Blame view

drivers/gpio/gpio-davinci.c 11.9 KB
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
1
2
3
  /*
   * TI DaVinci GPIO Support
   *
dce1115bc   David Brownell   ARM: DaVinci: SOC...
4
   * Copyright (c) 2006-2007 David Brownell
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
5
6
7
8
9
10
11
   * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   */
2f8163baa   Russell King   ARM: gpio: conver...
12
  #include <linux/gpio.h>
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
13
14
  #include <linux/errno.h>
  #include <linux/kernel.h>
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
15
16
17
  #include <linux/clk.h>
  #include <linux/err.h>
  #include <linux/io.h>
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
18

3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
19
  #include <asm/mach/irq.h>
c12f415a9   Cyril Chemparathy   Davinci: gpio - r...
20
21
22
23
24
25
26
27
28
29
30
31
  struct davinci_gpio_regs {
  	u32	dir;
  	u32	out_data;
  	u32	set_data;
  	u32	clr_data;
  	u32	in_data;
  	u32	set_rising;
  	u32	clr_rising;
  	u32	set_falling;
  	u32	clr_falling;
  	u32	intstat;
  };
ba4a984e8   Cyril Chemparathy   Davinci: gpio - m...
32
  #define chip2controller(chip)	\
99e9e52de   Cyril Chemparathy   Davinci: gpio - s...
33
  	container_of(chip, struct davinci_gpio_controller, chip)
ba4a984e8   Cyril Chemparathy   Davinci: gpio - m...
34

99e9e52de   Cyril Chemparathy   Davinci: gpio - s...
35
  static struct davinci_gpio_controller chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];
b8d442939   Cyril Chemparathy   Davinci: gpio - u...
36
  static void __iomem *gpio_base;
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
37

99e9e52de   Cyril Chemparathy   Davinci: gpio - s...
38
  static struct davinci_gpio_regs __iomem __init *gpio2regs(unsigned gpio)
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
39
  {
c12f415a9   Cyril Chemparathy   Davinci: gpio - r...
40
  	void __iomem *ptr;
c12f415a9   Cyril Chemparathy   Davinci: gpio - r...
41
42
  
  	if (gpio < 32 * 1)
b8d442939   Cyril Chemparathy   Davinci: gpio - u...
43
  		ptr = gpio_base + 0x10;
c12f415a9   Cyril Chemparathy   Davinci: gpio - r...
44
  	else if (gpio < 32 * 2)
b8d442939   Cyril Chemparathy   Davinci: gpio - u...
45
  		ptr = gpio_base + 0x38;
c12f415a9   Cyril Chemparathy   Davinci: gpio - r...
46
  	else if (gpio < 32 * 3)
b8d442939   Cyril Chemparathy   Davinci: gpio - u...
47
  		ptr = gpio_base + 0x60;
c12f415a9   Cyril Chemparathy   Davinci: gpio - r...
48
  	else if (gpio < 32 * 4)
b8d442939   Cyril Chemparathy   Davinci: gpio - u...
49
  		ptr = gpio_base + 0x88;
c12f415a9   Cyril Chemparathy   Davinci: gpio - r...
50
  	else if (gpio < 32 * 5)
b8d442939   Cyril Chemparathy   Davinci: gpio - u...
51
  		ptr = gpio_base + 0xb0;
c12f415a9   Cyril Chemparathy   Davinci: gpio - r...
52
53
54
  	else
  		ptr = NULL;
  	return ptr;
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
55
  }
99e9e52de   Cyril Chemparathy   Davinci: gpio - s...
56
  static inline struct davinci_gpio_regs __iomem *irq2regs(int irq)
21ce873d2   Kevin Hilman   davinci: sparse: ...
57
  {
99e9e52de   Cyril Chemparathy   Davinci: gpio - s...
58
  	struct davinci_gpio_regs __iomem *g;
21ce873d2   Kevin Hilman   davinci: sparse: ...
59

6845664a6   Thomas Gleixner   arm: Cleanup the ...
60
  	g = (__force struct davinci_gpio_regs __iomem *)irq_get_chip_data(irq);
21ce873d2   Kevin Hilman   davinci: sparse: ...
61
62
63
  
  	return g;
  }
dc7560262   Kevin Hilman   davinci: fixups f...
64
  static int __init davinci_gpio_irq_setup(void);
dce1115bc   David Brownell   ARM: DaVinci: SOC...
65
66
  
  /*--------------------------------------------------------------------------*/
5b3a05ca9   Cyril Chemparathy   Davinci: eliminat...
67
  /* board setup code *MUST* setup pinmux and enable the GPIO clock. */
ba4a984e8   Cyril Chemparathy   Davinci: gpio - m...
68
69
  static inline int __davinci_direction(struct gpio_chip *chip,
  			unsigned offset, bool out, int value)
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
70
  {
99e9e52de   Cyril Chemparathy   Davinci: gpio - s...
71
72
  	struct davinci_gpio_controller *d = chip2controller(chip);
  	struct davinci_gpio_regs __iomem *g = d->regs;
b27b6d03f   Cyril Chemparathy   Davinci: gpio - f...
73
  	unsigned long flags;
dce1115bc   David Brownell   ARM: DaVinci: SOC...
74
  	u32 temp;
ba4a984e8   Cyril Chemparathy   Davinci: gpio - m...
75
  	u32 mask = 1 << offset;
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
76

b27b6d03f   Cyril Chemparathy   Davinci: gpio - f...
77
  	spin_lock_irqsave(&d->lock, flags);
dce1115bc   David Brownell   ARM: DaVinci: SOC...
78
  	temp = __raw_readl(&g->dir);
ba4a984e8   Cyril Chemparathy   Davinci: gpio - m...
79
80
81
82
83
84
  	if (out) {
  		temp &= ~mask;
  		__raw_writel(mask, value ? &g->set_data : &g->clr_data);
  	} else {
  		temp |= mask;
  	}
dce1115bc   David Brownell   ARM: DaVinci: SOC...
85
  	__raw_writel(temp, &g->dir);
b27b6d03f   Cyril Chemparathy   Davinci: gpio - f...
86
  	spin_unlock_irqrestore(&d->lock, flags);
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
87

dce1115bc   David Brownell   ARM: DaVinci: SOC...
88
89
  	return 0;
  }
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
90

ba4a984e8   Cyril Chemparathy   Davinci: gpio - m...
91
92
93
94
95
96
97
98
99
100
  static int davinci_direction_in(struct gpio_chip *chip, unsigned offset)
  {
  	return __davinci_direction(chip, offset, false, 0);
  }
  
  static int
  davinci_direction_out(struct gpio_chip *chip, unsigned offset, int value)
  {
  	return __davinci_direction(chip, offset, true, value);
  }
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
101
102
103
104
105
106
107
  /*
   * Read the pin's value (works even if it's set up as output);
   * returns zero/nonzero.
   *
   * Note that changes are synched to the GPIO clock, so reading values back
   * right after you've set them may give old values.
   */
dce1115bc   David Brownell   ARM: DaVinci: SOC...
108
  static int davinci_gpio_get(struct gpio_chip *chip, unsigned offset)
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
109
  {
99e9e52de   Cyril Chemparathy   Davinci: gpio - s...
110
111
  	struct davinci_gpio_controller *d = chip2controller(chip);
  	struct davinci_gpio_regs __iomem *g = d->regs;
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
112

dce1115bc   David Brownell   ARM: DaVinci: SOC...
113
  	return (1 << offset) & __raw_readl(&g->in_data);
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
114
  }
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
115

dce1115bc   David Brownell   ARM: DaVinci: SOC...
116
117
118
119
120
  /*
   * Assuming the pin is muxed as a gpio output, set its output value.
   */
  static void
  davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
121
  {
99e9e52de   Cyril Chemparathy   Davinci: gpio - s...
122
123
  	struct davinci_gpio_controller *d = chip2controller(chip);
  	struct davinci_gpio_regs __iomem *g = d->regs;
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
124

dce1115bc   David Brownell   ARM: DaVinci: SOC...
125
126
127
128
129
130
  	__raw_writel((1 << offset), value ? &g->set_data : &g->clr_data);
  }
  
  static int __init davinci_gpio_setup(void)
  {
  	int i, base;
a994955cc   Mark A. Greer   davinci: Make GPI...
131
132
  	unsigned ngpio;
  	struct davinci_soc_info *soc_info = &davinci_soc_info;
c12f415a9   Cyril Chemparathy   Davinci: gpio - r...
133
  	struct davinci_gpio_regs *regs;
dce1115bc   David Brownell   ARM: DaVinci: SOC...
134

686b634a0   Cyril Chemparathy   Davinci: gpio - c...
135
136
  	if (soc_info->gpio_type != GPIO_TYPE_DAVINCI)
  		return 0;
a994955cc   Mark A. Greer   davinci: Make GPI...
137
138
  	/*
  	 * The gpio banks conceptually expose a segmented bitmap,
474dad54b   David Brownell   davinci: gpio bug...
139
140
141
  	 * and "ngpio" is one more than the largest zero-based
  	 * bit index that's valid.
  	 */
a994955cc   Mark A. Greer   davinci: Make GPI...
142
143
  	ngpio = soc_info->gpio_num;
  	if (ngpio == 0) {
474dad54b   David Brownell   davinci: gpio bug...
144
145
146
147
148
149
150
  		pr_err("GPIO setup:  how many GPIOs?
  ");
  		return -EINVAL;
  	}
  
  	if (WARN_ON(DAVINCI_N_GPIO < ngpio))
  		ngpio = DAVINCI_N_GPIO;
b8d442939   Cyril Chemparathy   Davinci: gpio - u...
151
152
153
  	gpio_base = ioremap(soc_info->gpio_base, SZ_4K);
  	if (WARN_ON(!gpio_base))
  		return -ENOMEM;
474dad54b   David Brownell   davinci: gpio bug...
154
  	for (i = 0, base = 0; base < ngpio; i++, base += 32) {
dce1115bc   David Brownell   ARM: DaVinci: SOC...
155
156
157
158
159
160
161
162
  		chips[i].chip.label = "DaVinci";
  
  		chips[i].chip.direction_input = davinci_direction_in;
  		chips[i].chip.get = davinci_gpio_get;
  		chips[i].chip.direction_output = davinci_direction_out;
  		chips[i].chip.set = davinci_gpio_set;
  
  		chips[i].chip.base = base;
474dad54b   David Brownell   davinci: gpio bug...
163
  		chips[i].chip.ngpio = ngpio - base;
dce1115bc   David Brownell   ARM: DaVinci: SOC...
164
165
  		if (chips[i].chip.ngpio > 32)
  			chips[i].chip.ngpio = 32;
b27b6d03f   Cyril Chemparathy   Davinci: gpio - f...
166
  		spin_lock_init(&chips[i].lock);
c12f415a9   Cyril Chemparathy   Davinci: gpio - r...
167
168
169
170
171
  		regs = gpio2regs(base);
  		chips[i].regs = regs;
  		chips[i].set_data = &regs->set_data;
  		chips[i].clr_data = &regs->clr_data;
  		chips[i].in_data = &regs->in_data;
dce1115bc   David Brownell   ARM: DaVinci: SOC...
172
173
174
  
  		gpiochip_add(&chips[i].chip);
  	}
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
175

c12f415a9   Cyril Chemparathy   Davinci: gpio - r...
176
177
  	soc_info->gpio_ctlrs = chips;
  	soc_info->gpio_ctlrs_num = DIV_ROUND_UP(ngpio, 32);
dc7560262   Kevin Hilman   davinci: fixups f...
178
  	davinci_gpio_irq_setup();
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
179
180
  	return 0;
  }
dce1115bc   David Brownell   ARM: DaVinci: SOC...
181
  pure_initcall(davinci_gpio_setup);
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
182

dce1115bc   David Brownell   ARM: DaVinci: SOC...
183
  /*--------------------------------------------------------------------------*/
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
184
185
186
187
  /*
   * We expect irqs will normally be set up as input pins, but they can also be
   * used as output pins ... which is convenient for testing.
   *
474dad54b   David Brownell   davinci: gpio bug...
188
   * NOTE:  The first few GPIOs also have direct INTC hookups in addition
7a36071e7   David Brownell   davinci: dm365 gp...
189
   * to their GPIOBNK0 irq, with a bit less overhead.
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
190
   *
474dad54b   David Brownell   davinci: gpio bug...
191
   * All those INTC hookups (direct, plus several IRQ banks) can also
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
192
193
   * serve as EDMA event triggers.
   */
23265442b   Lennert Buytenhek   ARM: davinci: irq...
194
  static void gpio_irq_disable(struct irq_data *d)
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
195
  {
23265442b   Lennert Buytenhek   ARM: davinci: irq...
196
  	struct davinci_gpio_regs __iomem *g = irq2regs(d->irq);
6845664a6   Thomas Gleixner   arm: Cleanup the ...
197
  	u32 mask = (u32) irq_data_get_irq_handler_data(d);
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
198
199
200
201
  
  	__raw_writel(mask, &g->clr_falling);
  	__raw_writel(mask, &g->clr_rising);
  }
23265442b   Lennert Buytenhek   ARM: davinci: irq...
202
  static void gpio_irq_enable(struct irq_data *d)
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
203
  {
23265442b   Lennert Buytenhek   ARM: davinci: irq...
204
  	struct davinci_gpio_regs __iomem *g = irq2regs(d->irq);
6845664a6   Thomas Gleixner   arm: Cleanup the ...
205
  	u32 mask = (u32) irq_data_get_irq_handler_data(d);
5093aec87   Thomas Gleixner   arm: davinci: Cle...
206
  	unsigned status = irqd_get_trigger_type(d);
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
207

df4aab46a   David Brownell   davinci: gpio irq...
208
209
210
211
212
  	status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
  	if (!status)
  		status = IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
  
  	if (status & IRQ_TYPE_EDGE_FALLING)
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
213
  		__raw_writel(mask, &g->set_falling);
df4aab46a   David Brownell   davinci: gpio irq...
214
  	if (status & IRQ_TYPE_EDGE_RISING)
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
215
216
  		__raw_writel(mask, &g->set_rising);
  }
23265442b   Lennert Buytenhek   ARM: davinci: irq...
217
  static int gpio_irq_type(struct irq_data *d, unsigned trigger)
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
218
  {
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
219
220
  	if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
  		return -EINVAL;
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
221
222
223
224
225
  	return 0;
  }
  
  static struct irq_chip gpio_irqchip = {
  	.name		= "GPIO",
23265442b   Lennert Buytenhek   ARM: davinci: irq...
226
227
228
  	.irq_enable	= gpio_irq_enable,
  	.irq_disable	= gpio_irq_disable,
  	.irq_set_type	= gpio_irq_type,
5093aec87   Thomas Gleixner   arm: davinci: Cle...
229
  	.flags		= IRQCHIP_SET_TYPE_MASKED,
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
230
231
232
233
234
  };
  
  static void
  gpio_irq_handler(unsigned irq, struct irq_desc *desc)
  {
741640166   Thomas Gleixner   arm: davinci: Fix...
235
  	struct davinci_gpio_regs __iomem *g;
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
236
  	u32 mask = 0xffff;
f299bb952   Ido Yariv   arm: davinci: Fix...
237
  	struct davinci_gpio_controller *d;
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
238

f299bb952   Ido Yariv   arm: davinci: Fix...
239
240
  	d = (struct davinci_gpio_controller *)irq_desc_get_handler_data(desc);
  	g = (struct davinci_gpio_regs __iomem *)d->regs;
741640166   Thomas Gleixner   arm: davinci: Fix...
241

3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
242
243
244
245
246
  	/* we only care about one bank */
  	if (irq & 1)
  		mask <<= 16;
  
  	/* temporarily mask (level sensitive) parent IRQ */
23265442b   Lennert Buytenhek   ARM: davinci: irq...
247
248
  	desc->irq_data.chip->irq_mask(&desc->irq_data);
  	desc->irq_data.chip->irq_ack(&desc->irq_data);
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
249
250
  	while (1) {
  		u32		status;
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
251
252
253
254
255
256
257
258
  		int		n;
  		int		res;
  
  		/* ack any irqs */
  		status = __raw_readl(&g->intstat) & mask;
  		if (!status)
  			break;
  		__raw_writel(status, &g->intstat);
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
259
260
  
  		/* now demux them to the right lowlevel handler */
f299bb952   Ido Yariv   arm: davinci: Fix...
261
262
263
264
265
  		n = d->irq_base;
  		if (irq & 1) {
  			n += 16;
  			status >>= 16;
  		}
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
266
267
268
  		while (status) {
  			res = ffs(status);
  			n += res;
d8aa0251f   Dmitry Eremin-Solenikov   [ARM] 5298/1: Dro...
269
  			generic_handle_irq(n - 1);
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
270
271
272
  			status >>= res;
  		}
  	}
23265442b   Lennert Buytenhek   ARM: davinci: irq...
273
  	desc->irq_data.chip->irq_unmask(&desc->irq_data);
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
274
275
  	/* now it may re-trigger */
  }
7a36071e7   David Brownell   davinci: dm365 gp...
276
277
  static int gpio_to_irq_banked(struct gpio_chip *chip, unsigned offset)
  {
99e9e52de   Cyril Chemparathy   Davinci: gpio - s...
278
  	struct davinci_gpio_controller *d = chip2controller(chip);
7a36071e7   David Brownell   davinci: dm365 gp...
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
  
  	if (d->irq_base >= 0)
  		return d->irq_base + offset;
  	else
  		return -ENODEV;
  }
  
  static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset)
  {
  	struct davinci_soc_info *soc_info = &davinci_soc_info;
  
  	/* NOTE:  we assume for now that only irqs in the first gpio_chip
  	 * can provide direct-mapped IRQs to AINTC (up to 32 GPIOs).
  	 */
  	if (offset < soc_info->gpio_unbanked)
  		return soc_info->gpio_irq + offset;
  	else
  		return -ENODEV;
  }
23265442b   Lennert Buytenhek   ARM: davinci: irq...
298
  static int gpio_irq_type_unbanked(struct irq_data *d, unsigned trigger)
7a36071e7   David Brownell   davinci: dm365 gp...
299
  {
23265442b   Lennert Buytenhek   ARM: davinci: irq...
300
  	struct davinci_gpio_regs __iomem *g = irq2regs(d->irq);
6845664a6   Thomas Gleixner   arm: Cleanup the ...
301
  	u32 mask = (u32) irq_data_get_irq_handler_data(d);
7a36071e7   David Brownell   davinci: dm365 gp...
302
303
304
305
306
307
308
309
310
311
312
  
  	if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
  		return -EINVAL;
  
  	__raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
  		     ? &g->set_falling : &g->clr_falling);
  	__raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING)
  		     ? &g->set_rising : &g->clr_rising);
  
  	return 0;
  }
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
313
  /*
474dad54b   David Brownell   davinci: gpio bug...
314
315
   * NOTE:  for suspend/resume, probably best to make a platform_device with
   * suspend_late/resume_resume calls hooking into results of the set_wake()
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
316
317
   * calls ... so if no gpios are wakeup events the clock can be disabled,
   * with outputs left at previously set levels, and so that VDD3P3V.IOPWDN0
474dad54b   David Brownell   davinci: gpio bug...
318
   * (dm6446) can be set appropriately for GPIOV33 pins.
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
319
320
321
322
323
324
   */
  
  static int __init davinci_gpio_irq_setup(void)
  {
  	unsigned	gpio, irq, bank;
  	struct clk	*clk;
474dad54b   David Brownell   davinci: gpio bug...
325
  	u32		binten = 0;
a994955cc   Mark A. Greer   davinci: Make GPI...
326
327
  	unsigned	ngpio, bank_irq;
  	struct davinci_soc_info *soc_info = &davinci_soc_info;
99e9e52de   Cyril Chemparathy   Davinci: gpio - s...
328
  	struct davinci_gpio_regs	__iomem *g;
a994955cc   Mark A. Greer   davinci: Make GPI...
329
330
  
  	ngpio = soc_info->gpio_num;
474dad54b   David Brownell   davinci: gpio bug...
331

a994955cc   Mark A. Greer   davinci: Make GPI...
332
333
  	bank_irq = soc_info->gpio_irq;
  	if (bank_irq == 0) {
474dad54b   David Brownell   davinci: gpio bug...
334
335
336
337
  		printk(KERN_ERR "Don't know first GPIO bank IRQ.
  ");
  		return -EINVAL;
  	}
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
338
339
340
341
342
343
  
  	clk = clk_get(NULL, "gpio");
  	if (IS_ERR(clk)) {
  		printk(KERN_ERR "Error %ld getting gpio clock?
  ",
  		       PTR_ERR(clk));
474dad54b   David Brownell   davinci: gpio bug...
344
  		return PTR_ERR(clk);
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
345
  	}
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
346
  	clk_enable(clk);
7a36071e7   David Brownell   davinci: dm365 gp...
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
  	/* Arrange gpio_to_irq() support, handling either direct IRQs or
  	 * banked IRQs.  Having GPIOs in the first GPIO bank use direct
  	 * IRQs, while the others use banked IRQs, would need some setup
  	 * tweaks to recognize hardware which can do that.
  	 */
  	for (gpio = 0, bank = 0; gpio < ngpio; bank++, gpio += 32) {
  		chips[bank].chip.to_irq = gpio_to_irq_banked;
  		chips[bank].irq_base = soc_info->gpio_unbanked
  			? -EINVAL
  			: (soc_info->intc_irq_num + gpio);
  	}
  
  	/*
  	 * AINTC can handle direct/unbanked IRQs for GPIOs, with the GPIO
  	 * controller only handling trigger modes.  We currently assume no
  	 * IRQ mux conflicts; gpio_irq_type_unbanked() is only for GPIOs.
  	 */
  	if (soc_info->gpio_unbanked) {
  		static struct irq_chip gpio_irqchip_unbanked;
  
  		/* pass "bank 0" GPIO IRQs to AINTC */
  		chips[0].chip.to_irq = gpio_to_irq_unbanked;
  		binten = BIT(0);
  
  		/* AINTC handles mask/unmask; GPIO handles triggering */
  		irq = bank_irq;
5093aec87   Thomas Gleixner   arm: davinci: Cle...
373
  		gpio_irqchip_unbanked = *irq_get_chip(irq);
7a36071e7   David Brownell   davinci: dm365 gp...
374
  		gpio_irqchip_unbanked.name = "GPIO-AINTC";
23265442b   Lennert Buytenhek   ARM: davinci: irq...
375
  		gpio_irqchip_unbanked.irq_set_type = gpio_irq_type_unbanked;
7a36071e7   David Brownell   davinci: dm365 gp...
376
377
  
  		/* default trigger: both edges */
99e9e52de   Cyril Chemparathy   Davinci: gpio - s...
378
  		g = gpio2regs(0);
7a36071e7   David Brownell   davinci: dm365 gp...
379
380
381
382
383
  		__raw_writel(~0, &g->set_falling);
  		__raw_writel(~0, &g->set_rising);
  
  		/* set the direct IRQs up to use that irqchip */
  		for (gpio = 0; gpio < soc_info->gpio_unbanked; gpio++, irq++) {
6845664a6   Thomas Gleixner   arm: Cleanup the ...
384
385
386
  			irq_set_chip(irq, &gpio_irqchip_unbanked);
  			irq_set_handler_data(irq, (void *)__gpio_mask(gpio));
  			irq_set_chip_data(irq, (__force void *)g);
5093aec87   Thomas Gleixner   arm: davinci: Cle...
387
  			irq_set_status_flags(irq, IRQ_TYPE_EDGE_BOTH);
7a36071e7   David Brownell   davinci: dm365 gp...
388
389
390
391
392
393
394
395
396
  		}
  
  		goto done;
  	}
  
  	/*
  	 * Or, AINTC can handle IRQs for banks of 16 GPIO IRQs, which we
  	 * then chain through our own handler.
  	 */
474dad54b   David Brownell   davinci: gpio bug...
397
398
399
  	for (gpio = 0, irq = gpio_to_irq(0), bank = 0;
  			gpio < ngpio;
  			bank++, bank_irq++) {
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
400
  		unsigned		i;
7a36071e7   David Brownell   davinci: dm365 gp...
401
  		/* disabled by default, enabled only as needed */
99e9e52de   Cyril Chemparathy   Davinci: gpio - s...
402
  		g = gpio2regs(gpio);
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
403
404
405
406
  		__raw_writel(~0, &g->clr_falling);
  		__raw_writel(~0, &g->clr_rising);
  
  		/* set up all irqs in this bank */
6845664a6   Thomas Gleixner   arm: Cleanup the ...
407
  		irq_set_chained_handler(bank_irq, gpio_irq_handler);
f299bb952   Ido Yariv   arm: davinci: Fix...
408
409
410
411
412
413
414
  
  		/*
  		 * Each chip handles 32 gpios, and each irq bank consists of 16
  		 * gpio irqs. Pass the irq bank's corresponding controller to
  		 * the chained irq handler.
  		 */
  		irq_set_handler_data(bank_irq, &chips[gpio / 32]);
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
415

474dad54b   David Brownell   davinci: gpio bug...
416
  		for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) {
6845664a6   Thomas Gleixner   arm: Cleanup the ...
417
418
419
420
  			irq_set_chip(irq, &gpio_irqchip);
  			irq_set_chip_data(irq, (__force void *)g);
  			irq_set_handler_data(irq, (void *)__gpio_mask(gpio));
  			irq_set_handler(irq, handle_simple_irq);
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
421
422
  			set_irq_flags(irq, IRQF_VALID);
  		}
474dad54b   David Brownell   davinci: gpio bug...
423
424
  
  		binten |= BIT(bank);
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
425
  	}
7a36071e7   David Brownell   davinci: dm365 gp...
426
  done:
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
427
428
429
  	/* BINTEN -- per-bank interrupt enable. genirq would also let these
  	 * bits be set/cleared dynamically.
  	 */
b8d442939   Cyril Chemparathy   Davinci: gpio - u...
430
  	__raw_writel(binten, gpio_base + 0x08);
3d9edf09d   Vladimir Barinov   [ARM] 4457/2: dav...
431
432
433
434
435
436
  
  	printk(KERN_INFO "DaVinci: %d gpio irqs
  ", irq - gpio_to_irq(0));
  
  	return 0;
  }