Commit | Line | Data |
---|---|---|
e9a03add SZ |
1 | /* |
2 | * Pinctrl Driver for ADI GPIO2 controller | |
3 | * | |
4 | * Copyright 2007-2013 Analog Devices Inc. | |
5 | * | |
6 | * Licensed under the GPLv2 or later | |
7 | */ | |
8 | ||
9 | #include <linux/bitops.h> | |
10 | #include <linux/delay.h> | |
11 | #include <linux/module.h> | |
12 | #include <linux/err.h> | |
13 | #include <linux/debugfs.h> | |
14 | #include <linux/seq_file.h> | |
15 | #include <linux/irq.h> | |
16 | #include <linux/platform_data/pinctrl-adi2.h> | |
17 | #include <linux/irqdomain.h> | |
18 | #include <linux/irqchip/chained_irq.h> | |
19 | #include <linux/pinctrl/pinctrl.h> | |
20 | #include <linux/pinctrl/pinmux.h> | |
21 | #include <linux/pinctrl/consumer.h> | |
22 | #include <linux/pinctrl/machine.h> | |
23 | #include <linux/syscore_ops.h> | |
24 | #include <linux/gpio.h> | |
25 | #include <asm/portmux.h> | |
26 | #include "pinctrl-adi2.h" | |
27 | #include "core.h" | |
28 | ||
29 | /* | |
30 | According to the BF54x HRM, pint means "pin interrupt". | |
31 | http://www.analog.com/static/imported-files/processor_manuals/ADSP-BF54x_hwr_rev1.2.pdf | |
32 | ||
33 | ADSP-BF54x processor Blackfin processors have four SIC interrupt chan- | |
34 | nels dedicated to pin interrupt purposes. These channels are managed by | |
35 | four hardware blocks, called PINT0, PINT1, PINT2, and PINT3. Every PINTx | |
36 | block can sense to up to 32 pins. While PINT0 and PINT1 can sense the | |
37 | pins of port A and port B, PINT2 and PINT3 manage all the pins from port | |
38 | C to port J as shown in Figure 9-2. | |
39 | ||
40 | n BF54x HRM: | |
41 | The ten GPIO ports are subdivided into 8-bit half ports, resulting in lower and | |
42 | upper half 8-bit units. The PINTx_ASSIGN registers control the 8-bit multi- | |
43 | plexers shown in Figure 9-3. Lower half units of eight pins can be | |
44 | forwarded to either byte 0 or byte 2 of either associated PINTx block. | |
45 | Upper half units can be forwarded to either byte 1 or byte 3 of the pin | |
46 | interrupt blocks, without further restrictions. | |
47 | ||
48 | All MMR registers in the pin interrupt module are 32 bits wide. To simply the | |
49 | mapping logic, this driver only maps a 16-bit gpio port to the upper or lower | |
50 | 16 bits of a PINTx block. You can find the Figure 9-3 on page 583. | |
51 | ||
52 | Each IRQ domain is binding to a GPIO bank device. 2 GPIO bank devices can map | |
53 | to one PINT device. Two in "struct gpio_pint" are used to ease the PINT | |
54 | interrupt handler. | |
55 | ||
56 | The GPIO bank mapping to the lower 16 bits of the PINT device set its IRQ | |
57 | domain pointer in domain[0]. The IRQ domain pointer of the other bank is set | |
58 | to domain[1]. PINT interrupt handler adi_gpio_handle_pint_irq() finds out | |
59 | the current domain pointer according to whether the interrupt request mask | |
60 | is in lower 16 bits (domain[0]) or upper 16bits (domain[1]). | |
61 | ||
62 | A PINT device is not part of a GPIO port device in Blackfin. Multiple GPIO | |
63 | port devices can be mapped to the same PINT device. | |
64 | ||
65 | */ | |
66 | ||
67 | static LIST_HEAD(adi_pint_list); | |
68 | static LIST_HEAD(adi_gpio_port_list); | |
69 | ||
70 | #define DRIVER_NAME "pinctrl-adi2" | |
71 | ||
72 | #define PINT_HI_OFFSET 16 | |
73 | ||
74 | /** | |
75 | * struct gpio_port_saved - GPIO port registers that should be saved between | |
76 | * power suspend and resume operations. | |
77 | * | |
78 | * @fer: PORTx_FER register | |
79 | * @data: PORTx_DATA register | |
80 | * @dir: PORTx_DIR register | |
81 | * @inen: PORTx_INEN register | |
82 | * @mux: PORTx_MUX register | |
83 | */ | |
84 | struct gpio_port_saved { | |
85 | u16 fer; | |
86 | u16 data; | |
87 | u16 dir; | |
88 | u16 inen; | |
89 | u32 mux; | |
90 | }; | |
91 | ||
1e6f8e3c SZ |
92 | /* |
93 | * struct gpio_pint_saved - PINT registers saved in PM operations | |
94 | * | |
95 | * @assign: ASSIGN register | |
96 | * @edge_set: EDGE_SET register | |
97 | * @invert_set: INVERT_SET register | |
98 | */ | |
99 | struct gpio_pint_saved { | |
100 | u32 assign; | |
101 | u32 edge_set; | |
102 | u32 invert_set; | |
103 | }; | |
104 | ||
e9a03add SZ |
105 | /** |
106 | * struct gpio_pint - Pin interrupt controller device. Multiple ADI GPIO | |
107 | * banks can be mapped into one Pin interrupt controller. | |
108 | * | |
109 | * @node: All gpio_pint instances are added to a global list. | |
110 | * @base: PINT device register base address | |
111 | * @irq: IRQ of the PINT device, it is the parent IRQ of all | |
112 | * GPIO IRQs mapping to this device. | |
113 | * @domain: [0] irq domain of the gpio port, whose hardware interrupts are | |
114 | * mapping to the low 16-bit of the pint registers. | |
115 | * [1] irq domain of the gpio port, whose hardware interrupts are | |
116 | * mapping to the high 16-bit of the pint registers. | |
117 | * @regs: address pointer to the PINT device | |
118 | * @map_count: No more than 2 GPIO banks can be mapped to this PINT device. | |
119 | * @lock: This lock make sure the irq_chip operations to one PINT device | |
120 | * for different GPIO interrrupts are atomic. | |
121 | * @pint_map_port: Set up the mapping between one PINT device and | |
122 | * multiple GPIO banks. | |
123 | */ | |
124 | struct gpio_pint { | |
125 | struct list_head node; | |
126 | void __iomem *base; | |
127 | int irq; | |
128 | struct irq_domain *domain[2]; | |
129 | struct gpio_pint_regs *regs; | |
1e6f8e3c | 130 | struct gpio_pint_saved saved_data; |
e9a03add SZ |
131 | int map_count; |
132 | spinlock_t lock; | |
133 | ||
134 | int (*pint_map_port)(struct gpio_pint *pint, bool assign, | |
135 | u8 map, struct irq_domain *domain); | |
136 | }; | |
137 | ||
138 | /** | |
139 | * ADI pin controller | |
140 | * | |
141 | * @dev: a pointer back to containing device | |
142 | * @pctl: the pinctrl device | |
143 | * @soc: SoC data for this specific chip | |
144 | */ | |
145 | struct adi_pinctrl { | |
146 | struct device *dev; | |
147 | struct pinctrl_dev *pctl; | |
148 | const struct adi_pinctrl_soc_data *soc; | |
149 | }; | |
150 | ||
151 | /** | |
152 | * struct gpio_port - GPIO bank device. Multiple ADI GPIO banks can be mapped | |
153 | * into one pin interrupt controller. | |
154 | * | |
155 | * @node: All gpio_port instances are added to a list. | |
156 | * @base: GPIO bank device register base address | |
157 | * @irq_base: base IRQ of the GPIO bank device | |
158 | * @width: PIN number of the GPIO bank device | |
159 | * @regs: address pointer to the GPIO bank device | |
160 | * @saved_data: registers that should be saved between PM operations. | |
161 | * @dev: device structure of this GPIO bank | |
162 | * @pint: GPIO PINT device that this GPIO bank mapped to | |
163 | * @pint_map: GIOP bank mapping code in PINT device | |
164 | * @pint_assign: The 32-bit PINT registers can be divided into 2 parts. A | |
165 | * GPIO bank can be mapped into either low 16 bits[0] or high 16 | |
166 | * bits[1] of each PINT register. | |
167 | * @lock: This lock make sure the irq_chip operations to one PINT device | |
168 | * for different GPIO interrrupts are atomic. | |
169 | * @chip: abstract a GPIO controller | |
170 | * @domain: The irq domain owned by the GPIO port. | |
171 | * @rsvmap: Reservation map array for each pin in the GPIO bank | |
172 | */ | |
173 | struct gpio_port { | |
174 | struct list_head node; | |
175 | void __iomem *base; | |
b4eef7b2 | 176 | int irq_base; |
e9a03add SZ |
177 | unsigned int width; |
178 | struct gpio_port_t *regs; | |
179 | struct gpio_port_saved saved_data; | |
180 | struct device *dev; | |
181 | ||
182 | struct gpio_pint *pint; | |
183 | u8 pint_map; | |
184 | bool pint_assign; | |
185 | ||
186 | spinlock_t lock; | |
187 | struct gpio_chip chip; | |
188 | struct irq_domain *domain; | |
189 | }; | |
190 | ||
191 | static inline u8 pin_to_offset(struct pinctrl_gpio_range *range, unsigned pin) | |
192 | { | |
193 | return pin - range->pin_base; | |
194 | } | |
195 | ||
196 | static inline u32 hwirq_to_pintbit(struct gpio_port *port, int hwirq) | |
197 | { | |
198 | return port->pint_assign ? BIT(hwirq) << PINT_HI_OFFSET : BIT(hwirq); | |
199 | } | |
200 | ||
201 | static struct gpio_pint *find_gpio_pint(unsigned id) | |
202 | { | |
203 | struct gpio_pint *pint; | |
204 | int i = 0; | |
205 | ||
206 | list_for_each_entry(pint, &adi_pint_list, node) { | |
207 | if (id == i) | |
208 | return pint; | |
209 | i++; | |
210 | } | |
211 | ||
212 | return NULL; | |
213 | } | |
214 | ||
215 | static inline void port_setup(struct gpio_port *port, unsigned offset, | |
216 | bool use_for_gpio) | |
217 | { | |
218 | struct gpio_port_t *regs = port->regs; | |
219 | ||
220 | if (use_for_gpio) | |
221 | writew(readw(®s->port_fer) & ~BIT(offset), | |
222 | ®s->port_fer); | |
223 | else | |
224 | writew(readw(®s->port_fer) | BIT(offset), ®s->port_fer); | |
225 | } | |
226 | ||
227 | static inline void portmux_setup(struct gpio_port *port, unsigned offset, | |
228 | unsigned short function) | |
229 | { | |
230 | struct gpio_port_t *regs = port->regs; | |
231 | u32 pmux; | |
232 | ||
233 | pmux = readl(®s->port_mux); | |
234 | ||
235 | /* The function field of each pin has 2 consecutive bits in | |
236 | * the mux register. | |
237 | */ | |
238 | pmux &= ~(0x3 << (2 * offset)); | |
239 | pmux |= (function & 0x3) << (2 * offset); | |
240 | ||
241 | writel(pmux, ®s->port_mux); | |
242 | } | |
243 | ||
244 | static inline u16 get_portmux(struct gpio_port *port, unsigned offset) | |
245 | { | |
246 | struct gpio_port_t *regs = port->regs; | |
247 | u32 pmux = readl(®s->port_mux); | |
248 | ||
249 | /* The function field of each pin has 2 consecutive bits in | |
250 | * the mux register. | |
251 | */ | |
252 | return pmux >> (2 * offset) & 0x3; | |
253 | } | |
254 | ||
255 | static void adi_gpio_ack_irq(struct irq_data *d) | |
256 | { | |
257 | unsigned long flags; | |
258 | struct gpio_port *port = irq_data_get_irq_chip_data(d); | |
259 | struct gpio_pint_regs *regs = port->pint->regs; | |
260 | unsigned pintbit = hwirq_to_pintbit(port, d->hwirq); | |
261 | ||
262 | spin_lock_irqsave(&port->lock, flags); | |
010c51e1 | 263 | spin_lock(&port->pint->lock); |
e9a03add SZ |
264 | |
265 | if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) { | |
266 | if (readl(®s->invert_set) & pintbit) | |
267 | writel(pintbit, ®s->invert_clear); | |
268 | else | |
269 | writel(pintbit, ®s->invert_set); | |
270 | } | |
271 | ||
272 | writel(pintbit, ®s->request); | |
273 | ||
010c51e1 | 274 | spin_unlock(&port->pint->lock); |
e9a03add SZ |
275 | spin_unlock_irqrestore(&port->lock, flags); |
276 | } | |
277 | ||
278 | static void adi_gpio_mask_ack_irq(struct irq_data *d) | |
279 | { | |
280 | unsigned long flags; | |
281 | struct gpio_port *port = irq_data_get_irq_chip_data(d); | |
282 | struct gpio_pint_regs *regs = port->pint->regs; | |
283 | unsigned pintbit = hwirq_to_pintbit(port, d->hwirq); | |
284 | ||
285 | spin_lock_irqsave(&port->lock, flags); | |
010c51e1 | 286 | spin_lock(&port->pint->lock); |
e9a03add SZ |
287 | |
288 | if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) { | |
289 | if (readl(®s->invert_set) & pintbit) | |
290 | writel(pintbit, ®s->invert_clear); | |
291 | else | |
292 | writel(pintbit, ®s->invert_set); | |
293 | } | |
294 | ||
295 | writel(pintbit, ®s->request); | |
296 | writel(pintbit, ®s->mask_clear); | |
297 | ||
010c51e1 | 298 | spin_unlock(&port->pint->lock); |
e9a03add SZ |
299 | spin_unlock_irqrestore(&port->lock, flags); |
300 | } | |
301 | ||
302 | static void adi_gpio_mask_irq(struct irq_data *d) | |
303 | { | |
304 | unsigned long flags; | |
305 | struct gpio_port *port = irq_data_get_irq_chip_data(d); | |
306 | struct gpio_pint_regs *regs = port->pint->regs; | |
307 | ||
308 | spin_lock_irqsave(&port->lock, flags); | |
010c51e1 | 309 | spin_lock(&port->pint->lock); |
e9a03add SZ |
310 | |
311 | writel(hwirq_to_pintbit(port, d->hwirq), ®s->mask_clear); | |
312 | ||
010c51e1 | 313 | spin_unlock(&port->pint->lock); |
e9a03add SZ |
314 | spin_unlock_irqrestore(&port->lock, flags); |
315 | } | |
316 | ||
317 | static void adi_gpio_unmask_irq(struct irq_data *d) | |
318 | { | |
319 | unsigned long flags; | |
320 | struct gpio_port *port = irq_data_get_irq_chip_data(d); | |
321 | struct gpio_pint_regs *regs = port->pint->regs; | |
322 | ||
323 | spin_lock_irqsave(&port->lock, flags); | |
010c51e1 | 324 | spin_lock(&port->pint->lock); |
e9a03add SZ |
325 | |
326 | writel(hwirq_to_pintbit(port, d->hwirq), ®s->mask_set); | |
327 | ||
010c51e1 | 328 | spin_unlock(&port->pint->lock); |
e9a03add SZ |
329 | spin_unlock_irqrestore(&port->lock, flags); |
330 | } | |
331 | ||
332 | static unsigned int adi_gpio_irq_startup(struct irq_data *d) | |
333 | { | |
334 | unsigned long flags; | |
335 | struct gpio_port *port = irq_data_get_irq_chip_data(d); | |
010c51e1 | 336 | struct gpio_pint_regs *regs; |
e9a03add SZ |
337 | |
338 | if (!port) { | |
010c51e1 | 339 | pr_err("GPIO IRQ %d :Not exist\n", d->irq); |
57ef0428 | 340 | /* FIXME: negative return code will be ignored */ |
e9a03add SZ |
341 | return -ENODEV; |
342 | } | |
343 | ||
010c51e1 SZ |
344 | regs = port->pint->regs; |
345 | ||
e9a03add | 346 | spin_lock_irqsave(&port->lock, flags); |
010c51e1 | 347 | spin_lock(&port->pint->lock); |
e9a03add SZ |
348 | |
349 | port_setup(port, d->hwirq, true); | |
350 | writew(BIT(d->hwirq), &port->regs->dir_clear); | |
351 | writew(readw(&port->regs->inen) | BIT(d->hwirq), &port->regs->inen); | |
352 | ||
353 | writel(hwirq_to_pintbit(port, d->hwirq), ®s->mask_set); | |
354 | ||
010c51e1 | 355 | spin_unlock(&port->pint->lock); |
e9a03add SZ |
356 | spin_unlock_irqrestore(&port->lock, flags); |
357 | ||
358 | return 0; | |
359 | } | |
360 | ||
361 | static void adi_gpio_irq_shutdown(struct irq_data *d) | |
362 | { | |
363 | unsigned long flags; | |
364 | struct gpio_port *port = irq_data_get_irq_chip_data(d); | |
365 | struct gpio_pint_regs *regs = port->pint->regs; | |
366 | ||
367 | spin_lock_irqsave(&port->lock, flags); | |
010c51e1 | 368 | spin_lock(&port->pint->lock); |
e9a03add SZ |
369 | |
370 | writel(hwirq_to_pintbit(port, d->hwirq), ®s->mask_clear); | |
371 | ||
010c51e1 | 372 | spin_unlock(&port->pint->lock); |
e9a03add SZ |
373 | spin_unlock_irqrestore(&port->lock, flags); |
374 | } | |
375 | ||
376 | static int adi_gpio_irq_type(struct irq_data *d, unsigned int type) | |
377 | { | |
378 | unsigned long flags; | |
379 | struct gpio_port *port = irq_data_get_irq_chip_data(d); | |
010c51e1 | 380 | struct gpio_pint_regs *pint_regs; |
e9a03add SZ |
381 | unsigned pintmask; |
382 | unsigned int irq = d->irq; | |
383 | int ret = 0; | |
384 | char buf[16]; | |
385 | ||
386 | if (!port) { | |
010c51e1 | 387 | pr_err("GPIO IRQ %d :Not exist\n", d->irq); |
e9a03add SZ |
388 | return -ENODEV; |
389 | } | |
390 | ||
010c51e1 SZ |
391 | pint_regs = port->pint->regs; |
392 | ||
e9a03add SZ |
393 | pintmask = hwirq_to_pintbit(port, d->hwirq); |
394 | ||
395 | spin_lock_irqsave(&port->lock, flags); | |
010c51e1 | 396 | spin_lock(&port->pint->lock); |
e9a03add SZ |
397 | |
398 | /* In case of interrupt autodetect, set irq type to edge sensitive. */ | |
399 | if (type == IRQ_TYPE_PROBE) | |
400 | type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; | |
401 | ||
402 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | | |
403 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { | |
719e231b | 404 | snprintf(buf, 16, "gpio-irq%u", irq); |
e9a03add SZ |
405 | port_setup(port, d->hwirq, true); |
406 | } else | |
407 | goto out; | |
408 | ||
409 | /* The GPIO interrupt is triggered only when its input value | |
410 | * transfer from 0 to 1. So, invert the input value if the | |
411 | * irq type is low or falling | |
412 | */ | |
413 | if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW))) | |
414 | writel(pintmask, &pint_regs->invert_set); | |
415 | else | |
416 | writel(pintmask, &pint_regs->invert_clear); | |
417 | ||
418 | /* In edge sensitive case, if the input value of the requested irq | |
419 | * is already 1, invert it. | |
420 | */ | |
421 | if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) { | |
422 | if (gpio_get_value(port->chip.base + d->hwirq)) | |
423 | writel(pintmask, &pint_regs->invert_set); | |
424 | else | |
425 | writel(pintmask, &pint_regs->invert_clear); | |
426 | } | |
427 | ||
428 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { | |
429 | writel(pintmask, &pint_regs->edge_set); | |
430 | __irq_set_handler_locked(irq, handle_edge_irq); | |
431 | } else { | |
432 | writel(pintmask, &pint_regs->edge_clear); | |
433 | __irq_set_handler_locked(irq, handle_level_irq); | |
434 | } | |
435 | ||
436 | out: | |
010c51e1 | 437 | spin_unlock(&port->pint->lock); |
e9a03add SZ |
438 | spin_unlock_irqrestore(&port->lock, flags); |
439 | ||
440 | return ret; | |
441 | } | |
442 | ||
443 | #ifdef CONFIG_PM | |
444 | static int adi_gpio_set_wake(struct irq_data *d, unsigned int state) | |
445 | { | |
446 | struct gpio_port *port = irq_data_get_irq_chip_data(d); | |
447 | ||
448 | if (!port || !port->pint || port->pint->irq != d->irq) | |
449 | return -EINVAL; | |
450 | ||
451 | #ifndef SEC_GCTL | |
452 | adi_internal_set_wake(port->pint->irq, state); | |
453 | #endif | |
454 | ||
455 | return 0; | |
456 | } | |
457 | ||
458 | static int adi_pint_suspend(void) | |
459 | { | |
460 | struct gpio_pint *pint; | |
461 | ||
462 | list_for_each_entry(pint, &adi_pint_list, node) { | |
463 | writel(0xffffffff, &pint->regs->mask_clear); | |
464 | pint->saved_data.assign = readl(&pint->regs->assign); | |
465 | pint->saved_data.edge_set = readl(&pint->regs->edge_set); | |
466 | pint->saved_data.invert_set = readl(&pint->regs->invert_set); | |
467 | } | |
468 | ||
469 | return 0; | |
470 | } | |
471 | ||
472 | static void adi_pint_resume(void) | |
473 | { | |
474 | struct gpio_pint *pint; | |
475 | ||
476 | list_for_each_entry(pint, &adi_pint_list, node) { | |
477 | writel(pint->saved_data.assign, &pint->regs->assign); | |
478 | writel(pint->saved_data.edge_set, &pint->regs->edge_set); | |
479 | writel(pint->saved_data.invert_set, &pint->regs->invert_set); | |
480 | } | |
481 | } | |
482 | ||
483 | static int adi_gpio_suspend(void) | |
484 | { | |
485 | struct gpio_port *port; | |
486 | ||
487 | list_for_each_entry(port, &adi_gpio_port_list, node) { | |
488 | port->saved_data.fer = readw(&port->regs->port_fer); | |
489 | port->saved_data.mux = readl(&port->regs->port_mux); | |
490 | port->saved_data.data = readw(&port->regs->data); | |
491 | port->saved_data.inen = readw(&port->regs->inen); | |
492 | port->saved_data.dir = readw(&port->regs->dir_set); | |
493 | } | |
494 | ||
495 | return adi_pint_suspend(); | |
496 | } | |
497 | ||
498 | static void adi_gpio_resume(void) | |
499 | { | |
500 | struct gpio_port *port; | |
501 | ||
502 | adi_pint_resume(); | |
503 | ||
504 | list_for_each_entry(port, &adi_gpio_port_list, node) { | |
505 | writel(port->saved_data.mux, &port->regs->port_mux); | |
506 | writew(port->saved_data.fer, &port->regs->port_fer); | |
507 | writew(port->saved_data.inen, &port->regs->inen); | |
508 | writew(port->saved_data.data & port->saved_data.dir, | |
509 | &port->regs->data_set); | |
510 | writew(port->saved_data.dir, &port->regs->dir_set); | |
511 | } | |
512 | ||
513 | } | |
514 | ||
515 | static struct syscore_ops gpio_pm_syscore_ops = { | |
516 | .suspend = adi_gpio_suspend, | |
517 | .resume = adi_gpio_resume, | |
518 | }; | |
519 | #else /* CONFIG_PM */ | |
520 | #define adi_gpio_set_wake NULL | |
521 | #endif /* CONFIG_PM */ | |
522 | ||
523 | #ifdef CONFIG_IRQ_PREFLOW_FASTEOI | |
524 | static inline void preflow_handler(struct irq_desc *desc) | |
525 | { | |
526 | if (desc->preflow_handler) | |
527 | desc->preflow_handler(&desc->irq_data); | |
528 | } | |
529 | #else | |
530 | static inline void preflow_handler(struct irq_desc *desc) { } | |
531 | #endif | |
532 | ||
533 | static void adi_gpio_handle_pint_irq(unsigned int inta_irq, | |
534 | struct irq_desc *desc) | |
535 | { | |
536 | u32 request; | |
537 | u32 level_mask, hwirq; | |
538 | bool umask = false; | |
539 | struct gpio_pint *pint = irq_desc_get_handler_data(desc); | |
540 | struct irq_chip *chip = irq_desc_get_chip(desc); | |
541 | struct gpio_pint_regs *regs = pint->regs; | |
542 | struct irq_domain *domain; | |
543 | ||
544 | preflow_handler(desc); | |
545 | chained_irq_enter(chip, desc); | |
546 | ||
547 | request = readl(®s->request); | |
548 | level_mask = readl(®s->edge_set) & request; | |
549 | ||
550 | hwirq = 0; | |
551 | domain = pint->domain[0]; | |
552 | while (request) { | |
553 | /* domain pointer need to be changed only once at IRQ 16 when | |
554 | * we go through IRQ requests from bit 0 to bit 31. | |
555 | */ | |
556 | if (hwirq == PINT_HI_OFFSET) | |
557 | domain = pint->domain[1]; | |
558 | ||
559 | if (request & 1) { | |
560 | if (level_mask & BIT(hwirq)) { | |
561 | umask = true; | |
562 | chained_irq_exit(chip, desc); | |
563 | } | |
564 | generic_handle_irq(irq_find_mapping(domain, | |
565 | hwirq % PINT_HI_OFFSET)); | |
566 | } | |
567 | ||
568 | hwirq++; | |
569 | request >>= 1; | |
570 | } | |
571 | ||
572 | if (!umask) | |
573 | chained_irq_exit(chip, desc); | |
574 | } | |
575 | ||
576 | static struct irq_chip adi_gpio_irqchip = { | |
577 | .name = "GPIO", | |
578 | .irq_ack = adi_gpio_ack_irq, | |
579 | .irq_mask = adi_gpio_mask_irq, | |
580 | .irq_mask_ack = adi_gpio_mask_ack_irq, | |
581 | .irq_unmask = adi_gpio_unmask_irq, | |
582 | .irq_disable = adi_gpio_mask_irq, | |
583 | .irq_enable = adi_gpio_unmask_irq, | |
584 | .irq_set_type = adi_gpio_irq_type, | |
585 | .irq_startup = adi_gpio_irq_startup, | |
586 | .irq_shutdown = adi_gpio_irq_shutdown, | |
587 | .irq_set_wake = adi_gpio_set_wake, | |
588 | }; | |
589 | ||
590 | static int adi_get_groups_count(struct pinctrl_dev *pctldev) | |
591 | { | |
592 | struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev); | |
593 | ||
594 | return pinctrl->soc->ngroups; | |
595 | } | |
596 | ||
597 | static const char *adi_get_group_name(struct pinctrl_dev *pctldev, | |
598 | unsigned selector) | |
599 | { | |
600 | struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev); | |
601 | ||
602 | return pinctrl->soc->groups[selector].name; | |
603 | } | |
604 | ||
605 | static int adi_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, | |
606 | const unsigned **pins, | |
607 | unsigned *num_pins) | |
608 | { | |
609 | struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev); | |
610 | ||
611 | *pins = pinctrl->soc->groups[selector].pins; | |
612 | *num_pins = pinctrl->soc->groups[selector].num; | |
613 | return 0; | |
614 | } | |
615 | ||
616 | static struct pinctrl_ops adi_pctrl_ops = { | |
617 | .get_groups_count = adi_get_groups_count, | |
618 | .get_group_name = adi_get_group_name, | |
619 | .get_group_pins = adi_get_group_pins, | |
620 | }; | |
621 | ||
e3653749 SZ |
622 | static int adi_pinmux_enable(struct pinctrl_dev *pctldev, unsigned func_id, |
623 | unsigned group_id) | |
e9a03add SZ |
624 | { |
625 | struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev); | |
626 | struct gpio_port *port; | |
627 | struct pinctrl_gpio_range *range; | |
628 | unsigned long flags; | |
629 | unsigned short *mux, pin; | |
630 | ||
e3653749 | 631 | mux = (unsigned short *)pinctrl->soc->groups[group_id].mux; |
e9a03add SZ |
632 | |
633 | while (*mux) { | |
634 | pin = P_IDENT(*mux); | |
635 | ||
636 | range = pinctrl_find_gpio_range_from_pin(pctldev, pin); | |
637 | if (range == NULL) /* should not happen */ | |
638 | return -ENODEV; | |
639 | ||
640 | port = container_of(range->gc, struct gpio_port, chip); | |
641 | ||
642 | spin_lock_irqsave(&port->lock, flags); | |
643 | ||
644 | portmux_setup(port, pin_to_offset(range, pin), | |
b81e57e6 | 645 | P_FUNCT2MUX(*mux)); |
e9a03add SZ |
646 | port_setup(port, pin_to_offset(range, pin), false); |
647 | mux++; | |
648 | ||
649 | spin_unlock_irqrestore(&port->lock, flags); | |
650 | } | |
651 | ||
652 | return 0; | |
653 | } | |
654 | ||
e9a03add SZ |
655 | static int adi_pinmux_get_funcs_count(struct pinctrl_dev *pctldev) |
656 | { | |
657 | struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev); | |
658 | ||
659 | return pinctrl->soc->nfunctions; | |
660 | } | |
661 | ||
662 | static const char *adi_pinmux_get_func_name(struct pinctrl_dev *pctldev, | |
663 | unsigned selector) | |
664 | { | |
665 | struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev); | |
666 | ||
667 | return pinctrl->soc->functions[selector].name; | |
668 | } | |
669 | ||
670 | static int adi_pinmux_get_groups(struct pinctrl_dev *pctldev, unsigned selector, | |
671 | const char * const **groups, | |
672 | unsigned * const num_groups) | |
673 | { | |
674 | struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev); | |
675 | ||
676 | *groups = pinctrl->soc->functions[selector].groups; | |
677 | *num_groups = pinctrl->soc->functions[selector].num_groups; | |
678 | return 0; | |
679 | } | |
680 | ||
681 | static int adi_pinmux_request_gpio(struct pinctrl_dev *pctldev, | |
682 | struct pinctrl_gpio_range *range, unsigned pin) | |
683 | { | |
684 | struct gpio_port *port; | |
685 | unsigned long flags; | |
686 | u8 offset; | |
687 | ||
688 | port = container_of(range->gc, struct gpio_port, chip); | |
689 | offset = pin_to_offset(range, pin); | |
690 | ||
691 | spin_lock_irqsave(&port->lock, flags); | |
692 | ||
693 | port_setup(port, offset, true); | |
694 | ||
695 | spin_unlock_irqrestore(&port->lock, flags); | |
696 | ||
697 | return 0; | |
698 | } | |
699 | ||
700 | static struct pinmux_ops adi_pinmux_ops = { | |
701 | .enable = adi_pinmux_enable, | |
e9a03add SZ |
702 | .get_functions_count = adi_pinmux_get_funcs_count, |
703 | .get_function_name = adi_pinmux_get_func_name, | |
704 | .get_function_groups = adi_pinmux_get_groups, | |
705 | .gpio_request_enable = adi_pinmux_request_gpio, | |
706 | }; | |
707 | ||
708 | ||
709 | static struct pinctrl_desc adi_pinmux_desc = { | |
710 | .name = DRIVER_NAME, | |
711 | .pctlops = &adi_pctrl_ops, | |
712 | .pmxops = &adi_pinmux_ops, | |
713 | .owner = THIS_MODULE, | |
714 | }; | |
715 | ||
716 | static int adi_gpio_request(struct gpio_chip *chip, unsigned offset) | |
717 | { | |
718 | return pinctrl_request_gpio(chip->base + offset); | |
719 | } | |
720 | ||
721 | static void adi_gpio_free(struct gpio_chip *chip, unsigned offset) | |
722 | { | |
723 | pinctrl_free_gpio(chip->base + offset); | |
724 | } | |
725 | ||
726 | static int adi_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | |
727 | { | |
728 | struct gpio_port *port; | |
729 | unsigned long flags; | |
730 | ||
731 | port = container_of(chip, struct gpio_port, chip); | |
732 | ||
733 | spin_lock_irqsave(&port->lock, flags); | |
734 | ||
735 | writew(BIT(offset), &port->regs->dir_clear); | |
736 | writew(readw(&port->regs->inen) | BIT(offset), &port->regs->inen); | |
737 | ||
738 | spin_unlock_irqrestore(&port->lock, flags); | |
739 | ||
740 | return 0; | |
741 | } | |
742 | ||
743 | static void adi_gpio_set_value(struct gpio_chip *chip, unsigned offset, | |
744 | int value) | |
745 | { | |
746 | struct gpio_port *port = container_of(chip, struct gpio_port, chip); | |
747 | struct gpio_port_t *regs = port->regs; | |
748 | unsigned long flags; | |
749 | ||
750 | spin_lock_irqsave(&port->lock, flags); | |
751 | ||
752 | if (value) | |
d3224ed1 | 753 | writew(BIT(offset), ®s->data_set); |
e9a03add | 754 | else |
d3224ed1 | 755 | writew(BIT(offset), ®s->data_clear); |
e9a03add SZ |
756 | |
757 | spin_unlock_irqrestore(&port->lock, flags); | |
758 | } | |
759 | ||
760 | static int adi_gpio_direction_output(struct gpio_chip *chip, unsigned offset, | |
761 | int value) | |
762 | { | |
763 | struct gpio_port *port = container_of(chip, struct gpio_port, chip); | |
764 | struct gpio_port_t *regs = port->regs; | |
765 | unsigned long flags; | |
766 | ||
767 | spin_lock_irqsave(&port->lock, flags); | |
768 | ||
d3224ed1 SZ |
769 | writew(readw(®s->inen) & ~BIT(offset), ®s->inen); |
770 | if (value) | |
771 | writew(BIT(offset), ®s->data_set); | |
772 | else | |
773 | writew(BIT(offset), ®s->data_clear); | |
774 | writew(BIT(offset), ®s->dir_set); | |
e9a03add SZ |
775 | |
776 | spin_unlock_irqrestore(&port->lock, flags); | |
777 | ||
778 | return 0; | |
779 | } | |
780 | ||
781 | static int adi_gpio_get_value(struct gpio_chip *chip, unsigned offset) | |
782 | { | |
783 | struct gpio_port *port = container_of(chip, struct gpio_port, chip); | |
784 | struct gpio_port_t *regs = port->regs; | |
785 | unsigned long flags; | |
786 | int ret; | |
787 | ||
788 | spin_lock_irqsave(&port->lock, flags); | |
789 | ||
790 | ret = !!(readw(®s->data) & BIT(offset)); | |
791 | ||
792 | spin_unlock_irqrestore(&port->lock, flags); | |
793 | ||
794 | return ret; | |
795 | } | |
796 | ||
797 | static int adi_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | |
798 | { | |
799 | struct gpio_port *port = container_of(chip, struct gpio_port, chip); | |
800 | ||
801 | if (port->irq_base >= 0) | |
802 | return irq_find_mapping(port->domain, offset); | |
803 | else | |
804 | return irq_create_mapping(port->domain, offset); | |
805 | } | |
806 | ||
807 | static int adi_pint_map_port(struct gpio_pint *pint, bool assign, u8 map, | |
808 | struct irq_domain *domain) | |
809 | { | |
810 | struct gpio_pint_regs *regs = pint->regs; | |
811 | u32 map_mask; | |
812 | ||
813 | if (pint->map_count > 1) | |
814 | return -EINVAL; | |
815 | ||
816 | pint->map_count++; | |
817 | ||
818 | /* The map_mask of each gpio port is a 16-bit duplicate | |
819 | * of the 8-bit map. It can be set to either high 16 bits or low | |
820 | * 16 bits of the pint assignment register. | |
821 | */ | |
822 | map_mask = (map << 8) | map; | |
823 | if (assign) { | |
824 | map_mask <<= PINT_HI_OFFSET; | |
825 | writel((readl(®s->assign) & 0xFFFF) | map_mask, | |
826 | ®s->assign); | |
827 | } else | |
828 | writel((readl(®s->assign) & 0xFFFF0000) | map_mask, | |
829 | ®s->assign); | |
830 | ||
831 | pint->domain[assign] = domain; | |
832 | ||
833 | return 0; | |
834 | } | |
835 | ||
836 | static int adi_gpio_pint_probe(struct platform_device *pdev) | |
837 | { | |
838 | struct device *dev = &pdev->dev; | |
839 | struct resource *res; | |
840 | struct gpio_pint *pint; | |
841 | ||
842 | pint = devm_kzalloc(dev, sizeof(struct gpio_pint), GFP_KERNEL); | |
843 | if (!pint) { | |
844 | dev_err(dev, "Memory alloc failed\n"); | |
845 | return -ENOMEM; | |
846 | } | |
847 | ||
848 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
c8690d6d AL |
849 | pint->base = devm_ioremap_resource(dev, res); |
850 | if (IS_ERR(pint->base)) | |
851 | return PTR_ERR(pint->base); | |
e9a03add SZ |
852 | |
853 | pint->regs = (struct gpio_pint_regs *)pint->base; | |
854 | ||
855 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | |
856 | if (!res) { | |
857 | dev_err(dev, "Invalid IRQ resource\n"); | |
858 | return -ENODEV; | |
859 | } | |
860 | ||
861 | spin_lock_init(&pint->lock); | |
862 | ||
863 | pint->irq = res->start; | |
864 | pint->pint_map_port = adi_pint_map_port; | |
865 | platform_set_drvdata(pdev, pint); | |
866 | ||
867 | irq_set_chained_handler(pint->irq, adi_gpio_handle_pint_irq); | |
868 | irq_set_handler_data(pint->irq, pint); | |
869 | ||
870 | list_add_tail(&pint->node, &adi_pint_list); | |
871 | ||
872 | return 0; | |
873 | } | |
874 | ||
875 | static int adi_gpio_pint_remove(struct platform_device *pdev) | |
876 | { | |
877 | struct gpio_pint *pint = platform_get_drvdata(pdev); | |
878 | ||
879 | list_del(&pint->node); | |
880 | irq_set_handler(pint->irq, handle_simple_irq); | |
881 | ||
882 | return 0; | |
883 | } | |
884 | ||
885 | static int adi_gpio_irq_map(struct irq_domain *d, unsigned int irq, | |
886 | irq_hw_number_t hwirq) | |
887 | { | |
888 | struct gpio_port *port = d->host_data; | |
889 | ||
890 | if (!port) | |
891 | return -EINVAL; | |
892 | ||
893 | irq_set_chip_data(irq, port); | |
894 | irq_set_chip_and_handler(irq, &adi_gpio_irqchip, | |
895 | handle_level_irq); | |
896 | ||
897 | return 0; | |
898 | } | |
899 | ||
f77329d1 | 900 | static const struct irq_domain_ops adi_gpio_irq_domain_ops = { |
e9a03add SZ |
901 | .map = adi_gpio_irq_map, |
902 | .xlate = irq_domain_xlate_onecell, | |
903 | }; | |
904 | ||
905 | static int adi_gpio_init_int(struct gpio_port *port) | |
906 | { | |
907 | struct device_node *node = port->dev->of_node; | |
908 | struct gpio_pint *pint = port->pint; | |
909 | int ret; | |
910 | ||
911 | port->domain = irq_domain_add_linear(node, port->width, | |
912 | &adi_gpio_irq_domain_ops, port); | |
913 | if (!port->domain) { | |
914 | dev_err(port->dev, "Failed to create irqdomain\n"); | |
915 | return -ENOSYS; | |
916 | } | |
917 | ||
918 | /* According to BF54x and BF60x HRM, pin interrupt devices are not | |
919 | * part of the GPIO port device. in GPIO interrupt mode, the GPIO | |
920 | * pins of multiple port devices can be routed into one pin interrupt | |
921 | * device. The mapping can be configured by setting pint assignment | |
922 | * register with the mapping value of different GPIO port. This is | |
923 | * done via function pint_map_port(). | |
924 | */ | |
925 | ret = pint->pint_map_port(port->pint, port->pint_assign, | |
926 | port->pint_map, port->domain); | |
927 | if (ret) | |
928 | return ret; | |
929 | ||
930 | if (port->irq_base >= 0) { | |
931 | ret = irq_create_strict_mappings(port->domain, port->irq_base, | |
932 | 0, port->width); | |
933 | if (ret) { | |
934 | dev_err(port->dev, "Couldn't associate to domain\n"); | |
935 | return ret; | |
936 | } | |
937 | } | |
938 | ||
939 | return 0; | |
940 | } | |
941 | ||
942 | #define DEVNAME_SIZE 16 | |
943 | ||
944 | static int adi_gpio_probe(struct platform_device *pdev) | |
945 | { | |
946 | struct device *dev = &pdev->dev; | |
947 | const struct adi_pinctrl_gpio_platform_data *pdata; | |
948 | struct resource *res; | |
949 | struct gpio_port *port; | |
950 | char pinctrl_devname[DEVNAME_SIZE]; | |
951 | static int gpio; | |
b4e7c55d | 952 | int ret = 0; |
e9a03add SZ |
953 | |
954 | pdata = dev->platform_data; | |
955 | if (!pdata) | |
956 | return -EINVAL; | |
957 | ||
958 | port = devm_kzalloc(dev, sizeof(struct gpio_port), GFP_KERNEL); | |
959 | if (!port) { | |
960 | dev_err(dev, "Memory alloc failed\n"); | |
961 | return -ENOMEM; | |
962 | } | |
963 | ||
964 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
c8690d6d AL |
965 | port->base = devm_ioremap_resource(dev, res); |
966 | if (IS_ERR(port->base)) | |
967 | return PTR_ERR(port->base); | |
e9a03add SZ |
968 | |
969 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | |
970 | if (!res) | |
971 | port->irq_base = -1; | |
972 | else | |
973 | port->irq_base = res->start; | |
974 | ||
975 | port->width = pdata->port_width; | |
976 | port->dev = dev; | |
977 | port->regs = (struct gpio_port_t *)port->base; | |
978 | port->pint_assign = pdata->pint_assign; | |
979 | port->pint_map = pdata->pint_map; | |
980 | ||
981 | port->pint = find_gpio_pint(pdata->pint_id); | |
982 | if (port->pint) { | |
983 | ret = adi_gpio_init_int(port); | |
984 | if (ret) | |
985 | return ret; | |
986 | } | |
987 | ||
988 | spin_lock_init(&port->lock); | |
989 | ||
990 | platform_set_drvdata(pdev, port); | |
991 | ||
992 | port->chip.label = "adi-gpio"; | |
993 | port->chip.direction_input = adi_gpio_direction_input; | |
994 | port->chip.get = adi_gpio_get_value; | |
995 | port->chip.direction_output = adi_gpio_direction_output; | |
996 | port->chip.set = adi_gpio_set_value; | |
997 | port->chip.request = adi_gpio_request; | |
998 | port->chip.free = adi_gpio_free; | |
999 | port->chip.to_irq = adi_gpio_to_irq; | |
1000 | if (pdata->port_gpio_base > 0) | |
1001 | port->chip.base = pdata->port_gpio_base; | |
1002 | else | |
1003 | port->chip.base = gpio; | |
1004 | port->chip.ngpio = port->width; | |
1005 | gpio = port->chip.base + port->width; | |
1006 | ||
1007 | ret = gpiochip_add(&port->chip); | |
1008 | if (ret) { | |
1009 | dev_err(&pdev->dev, "Fail to add GPIO chip.\n"); | |
1010 | goto out_remove_domain; | |
1011 | } | |
1012 | ||
1013 | /* Add gpio pin range */ | |
1014 | snprintf(pinctrl_devname, DEVNAME_SIZE, "pinctrl-adi2.%d", | |
1015 | pdata->pinctrl_id); | |
1016 | pinctrl_devname[DEVNAME_SIZE - 1] = 0; | |
1017 | ret = gpiochip_add_pin_range(&port->chip, pinctrl_devname, | |
1018 | 0, pdata->port_pin_base, port->width); | |
1019 | if (ret) { | |
1020 | dev_err(&pdev->dev, "Fail to add pin range to %s.\n", | |
1021 | pinctrl_devname); | |
1022 | goto out_remove_gpiochip; | |
1023 | } | |
1024 | ||
1025 | list_add_tail(&port->node, &adi_gpio_port_list); | |
1026 | ||
1027 | return 0; | |
1028 | ||
1029 | out_remove_gpiochip: | |
b4e7c55d | 1030 | gpiochip_remove(&port->chip); |
e9a03add SZ |
1031 | out_remove_domain: |
1032 | if (port->pint) | |
1033 | irq_domain_remove(port->domain); | |
1034 | ||
1035 | return ret; | |
1036 | } | |
1037 | ||
1038 | static int adi_gpio_remove(struct platform_device *pdev) | |
1039 | { | |
1040 | struct gpio_port *port = platform_get_drvdata(pdev); | |
e9a03add SZ |
1041 | u8 offset; |
1042 | ||
1043 | list_del(&port->node); | |
1044 | gpiochip_remove_pin_ranges(&port->chip); | |
b4e7c55d | 1045 | gpiochip_remove(&port->chip); |
e9a03add SZ |
1046 | if (port->pint) { |
1047 | for (offset = 0; offset < port->width; offset++) | |
1048 | irq_dispose_mapping(irq_find_mapping(port->domain, | |
1049 | offset)); | |
1050 | irq_domain_remove(port->domain); | |
1051 | } | |
1052 | ||
b4e7c55d | 1053 | return 0; |
e9a03add SZ |
1054 | } |
1055 | ||
1056 | static int adi_pinctrl_probe(struct platform_device *pdev) | |
1057 | { | |
1058 | struct adi_pinctrl *pinctrl; | |
1059 | ||
1060 | pinctrl = devm_kzalloc(&pdev->dev, sizeof(*pinctrl), GFP_KERNEL); | |
1061 | if (!pinctrl) | |
1062 | return -ENOMEM; | |
1063 | ||
1064 | pinctrl->dev = &pdev->dev; | |
1065 | ||
1066 | adi_pinctrl_soc_init(&pinctrl->soc); | |
1067 | ||
1068 | adi_pinmux_desc.pins = pinctrl->soc->pins; | |
1069 | adi_pinmux_desc.npins = pinctrl->soc->npins; | |
1070 | ||
1071 | /* Now register the pin controller and all pins it handles */ | |
1072 | pinctrl->pctl = pinctrl_register(&adi_pinmux_desc, &pdev->dev, pinctrl); | |
1073 | if (!pinctrl->pctl) { | |
1074 | dev_err(&pdev->dev, "could not register pinctrl ADI2 driver\n"); | |
1075 | return -EINVAL; | |
1076 | } | |
1077 | ||
1078 | platform_set_drvdata(pdev, pinctrl); | |
1079 | ||
1080 | return 0; | |
1081 | } | |
1082 | ||
1083 | static int adi_pinctrl_remove(struct platform_device *pdev) | |
1084 | { | |
1085 | struct adi_pinctrl *pinctrl = platform_get_drvdata(pdev); | |
1086 | ||
1087 | pinctrl_unregister(pinctrl->pctl); | |
1088 | ||
1089 | return 0; | |
1090 | } | |
1091 | ||
1092 | static struct platform_driver adi_pinctrl_driver = { | |
1093 | .probe = adi_pinctrl_probe, | |
1094 | .remove = adi_pinctrl_remove, | |
1095 | .driver = { | |
1096 | .name = DRIVER_NAME, | |
1097 | }, | |
1098 | }; | |
1099 | ||
1100 | static struct platform_driver adi_gpio_pint_driver = { | |
1101 | .probe = adi_gpio_pint_probe, | |
1102 | .remove = adi_gpio_pint_remove, | |
1103 | .driver = { | |
1104 | .name = "adi-gpio-pint", | |
1105 | }, | |
1106 | }; | |
1107 | ||
1108 | static struct platform_driver adi_gpio_driver = { | |
1109 | .probe = adi_gpio_probe, | |
1110 | .remove = adi_gpio_remove, | |
1111 | .driver = { | |
1112 | .name = "adi-gpio", | |
1113 | }, | |
1114 | }; | |
1115 | ||
1116 | static int __init adi_pinctrl_setup(void) | |
1117 | { | |
1118 | int ret; | |
1119 | ||
1120 | ret = platform_driver_register(&adi_pinctrl_driver); | |
1121 | if (ret) | |
1122 | return ret; | |
1123 | ||
1124 | ret = platform_driver_register(&adi_gpio_pint_driver); | |
1125 | if (ret) | |
1126 | goto pint_error; | |
1127 | ||
1128 | ret = platform_driver_register(&adi_gpio_driver); | |
1129 | if (ret) | |
1130 | goto gpio_error; | |
1131 | ||
1132 | #ifdef CONFIG_PM | |
1133 | register_syscore_ops(&gpio_pm_syscore_ops); | |
1134 | #endif | |
1135 | return ret; | |
1136 | gpio_error: | |
1137 | platform_driver_unregister(&adi_gpio_pint_driver); | |
1138 | pint_error: | |
1139 | platform_driver_unregister(&adi_pinctrl_driver); | |
1140 | ||
1141 | return ret; | |
1142 | } | |
1143 | arch_initcall(adi_pinctrl_setup); | |
1144 | ||
1145 | MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>"); | |
1146 | MODULE_DESCRIPTION("ADI gpio2 pin control driver"); | |
1147 | MODULE_LICENSE("GPL"); |