1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Broadcom Kona GPIO Driver |
4 | * |
5 | * Author: Broadcom Corporation <bcm-kernel-feedback-list@broadcom.com> |
6 | * Copyright (C) 2012-2014 Broadcom Corporation |
7 | */ |
8 | |
9 | #include <linux/bitops.h> |
10 | #include <linux/err.h> |
11 | #include <linux/gpio/driver.h> |
12 | #include <linux/init.h> |
13 | #include <linux/io.h> |
14 | #include <linux/irqdomain.h> |
15 | #include <linux/irqchip/chained_irq.h> |
16 | #include <linux/mod_devicetable.h> |
17 | #include <linux/platform_device.h> |
18 | #include <linux/property.h> |
19 | |
20 | #define BCM_GPIO_PASSWD 0x00a5a501 |
21 | #define GPIO_PER_BANK 32 |
22 | #define GPIO_MAX_BANK_NUM 8 |
23 | |
24 | #define GPIO_BANK(gpio) ((gpio) >> 5) |
25 | #define GPIO_BIT(gpio) ((gpio) & (GPIO_PER_BANK - 1)) |
26 | |
27 | /* There is a GPIO control register for each GPIO */ |
28 | #define GPIO_CONTROL(gpio) (0x00000100 + ((gpio) << 2)) |
29 | |
30 | /* The remaining registers are per GPIO bank */ |
31 | #define GPIO_OUT_STATUS(bank) (0x00000000 + ((bank) << 2)) |
32 | #define GPIO_IN_STATUS(bank) (0x00000020 + ((bank) << 2)) |
33 | #define GPIO_OUT_SET(bank) (0x00000040 + ((bank) << 2)) |
34 | #define GPIO_OUT_CLEAR(bank) (0x00000060 + ((bank) << 2)) |
35 | #define GPIO_INT_STATUS(bank) (0x00000080 + ((bank) << 2)) |
36 | #define GPIO_INT_MASK(bank) (0x000000a0 + ((bank) << 2)) |
37 | #define GPIO_INT_MSKCLR(bank) (0x000000c0 + ((bank) << 2)) |
38 | #define GPIO_PWD_STATUS(bank) (0x00000500 + ((bank) << 2)) |
39 | |
40 | #define GPIO_GPPWR_OFFSET 0x00000520 |
41 | |
42 | #define GPIO_GPCTR0_DBR_SHIFT 5 |
43 | #define GPIO_GPCTR0_DBR_MASK 0x000001e0 |
44 | |
45 | #define GPIO_GPCTR0_ITR_SHIFT 3 |
46 | #define GPIO_GPCTR0_ITR_MASK 0x00000018 |
47 | #define GPIO_GPCTR0_ITR_CMD_RISING_EDGE 0x00000001 |
48 | #define GPIO_GPCTR0_ITR_CMD_FALLING_EDGE 0x00000002 |
49 | #define GPIO_GPCTR0_ITR_CMD_BOTH_EDGE 0x00000003 |
50 | |
51 | #define GPIO_GPCTR0_IOTR_MASK 0x00000001 |
52 | #define GPIO_GPCTR0_IOTR_CMD_0UTPUT 0x00000000 |
53 | #define GPIO_GPCTR0_IOTR_CMD_INPUT 0x00000001 |
54 | |
55 | #define GPIO_GPCTR0_DB_ENABLE_MASK 0x00000100 |
56 | |
57 | #define LOCK_CODE 0xffffffff |
58 | #define UNLOCK_CODE 0x00000000 |
59 | |
60 | struct bcm_kona_gpio { |
61 | void __iomem *reg_base; |
62 | int num_bank; |
63 | raw_spinlock_t lock; |
64 | struct gpio_chip gpio_chip; |
65 | struct irq_domain *irq_domain; |
66 | struct bcm_kona_gpio_bank *banks; |
67 | }; |
68 | |
69 | struct bcm_kona_gpio_bank { |
70 | int id; |
71 | int irq; |
72 | /* Used in the interrupt handler */ |
73 | struct bcm_kona_gpio *kona_gpio; |
74 | }; |
75 | |
76 | static inline void bcm_kona_gpio_write_lock_regs(void __iomem *reg_base, |
77 | int bank_id, u32 lockcode) |
78 | { |
79 | writel(BCM_GPIO_PASSWD, addr: reg_base + GPIO_GPPWR_OFFSET); |
80 | writel(val: lockcode, addr: reg_base + GPIO_PWD_STATUS(bank_id)); |
81 | } |
82 | |
83 | static void bcm_kona_gpio_lock_gpio(struct bcm_kona_gpio *kona_gpio, |
84 | unsigned gpio) |
85 | { |
86 | u32 val; |
87 | unsigned long flags; |
88 | int bank_id = GPIO_BANK(gpio); |
89 | |
90 | raw_spin_lock_irqsave(&kona_gpio->lock, flags); |
91 | |
92 | val = readl(addr: kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id)); |
93 | val |= BIT(gpio); |
94 | bcm_kona_gpio_write_lock_regs(reg_base: kona_gpio->reg_base, bank_id, lockcode: val); |
95 | |
96 | raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); |
97 | } |
98 | |
99 | static void bcm_kona_gpio_unlock_gpio(struct bcm_kona_gpio *kona_gpio, |
100 | unsigned gpio) |
101 | { |
102 | u32 val; |
103 | unsigned long flags; |
104 | int bank_id = GPIO_BANK(gpio); |
105 | |
106 | raw_spin_lock_irqsave(&kona_gpio->lock, flags); |
107 | |
108 | val = readl(addr: kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id)); |
109 | val &= ~BIT(gpio); |
110 | bcm_kona_gpio_write_lock_regs(reg_base: kona_gpio->reg_base, bank_id, lockcode: val); |
111 | |
112 | raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); |
113 | } |
114 | |
115 | static int bcm_kona_gpio_get_dir(struct gpio_chip *chip, unsigned gpio) |
116 | { |
117 | struct bcm_kona_gpio *kona_gpio = gpiochip_get_data(gc: chip); |
118 | void __iomem *reg_base = kona_gpio->reg_base; |
119 | u32 val; |
120 | |
121 | val = readl(addr: reg_base + GPIO_CONTROL(gpio)) & GPIO_GPCTR0_IOTR_MASK; |
122 | return val ? GPIO_LINE_DIRECTION_IN : GPIO_LINE_DIRECTION_OUT; |
123 | } |
124 | |
125 | static void bcm_kona_gpio_set(struct gpio_chip *chip, unsigned gpio, int value) |
126 | { |
127 | struct bcm_kona_gpio *kona_gpio; |
128 | void __iomem *reg_base; |
129 | int bank_id = GPIO_BANK(gpio); |
130 | int bit = GPIO_BIT(gpio); |
131 | u32 val, reg_offset; |
132 | unsigned long flags; |
133 | |
134 | kona_gpio = gpiochip_get_data(gc: chip); |
135 | reg_base = kona_gpio->reg_base; |
136 | raw_spin_lock_irqsave(&kona_gpio->lock, flags); |
137 | |
138 | /* this function only applies to output pin */ |
139 | if (bcm_kona_gpio_get_dir(chip, gpio) == GPIO_LINE_DIRECTION_IN) |
140 | goto out; |
141 | |
142 | reg_offset = value ? GPIO_OUT_SET(bank_id) : GPIO_OUT_CLEAR(bank_id); |
143 | |
144 | val = readl(addr: reg_base + reg_offset); |
145 | val |= BIT(bit); |
146 | writel(val, addr: reg_base + reg_offset); |
147 | |
148 | out: |
149 | raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); |
150 | } |
151 | |
152 | static int bcm_kona_gpio_get(struct gpio_chip *chip, unsigned gpio) |
153 | { |
154 | struct bcm_kona_gpio *kona_gpio; |
155 | void __iomem *reg_base; |
156 | int bank_id = GPIO_BANK(gpio); |
157 | int bit = GPIO_BIT(gpio); |
158 | u32 val, reg_offset; |
159 | unsigned long flags; |
160 | |
161 | kona_gpio = gpiochip_get_data(gc: chip); |
162 | reg_base = kona_gpio->reg_base; |
163 | raw_spin_lock_irqsave(&kona_gpio->lock, flags); |
164 | |
165 | if (bcm_kona_gpio_get_dir(chip, gpio) == GPIO_LINE_DIRECTION_IN) |
166 | reg_offset = GPIO_IN_STATUS(bank_id); |
167 | else |
168 | reg_offset = GPIO_OUT_STATUS(bank_id); |
169 | |
170 | /* read the GPIO bank status */ |
171 | val = readl(addr: reg_base + reg_offset); |
172 | |
173 | raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); |
174 | |
175 | /* return the specified bit status */ |
176 | return !!(val & BIT(bit)); |
177 | } |
178 | |
179 | static int bcm_kona_gpio_request(struct gpio_chip *chip, unsigned gpio) |
180 | { |
181 | struct bcm_kona_gpio *kona_gpio = gpiochip_get_data(gc: chip); |
182 | |
183 | bcm_kona_gpio_unlock_gpio(kona_gpio, gpio); |
184 | return 0; |
185 | } |
186 | |
187 | static void bcm_kona_gpio_free(struct gpio_chip *chip, unsigned gpio) |
188 | { |
189 | struct bcm_kona_gpio *kona_gpio = gpiochip_get_data(gc: chip); |
190 | |
191 | bcm_kona_gpio_lock_gpio(kona_gpio, gpio); |
192 | } |
193 | |
194 | static int bcm_kona_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) |
195 | { |
196 | struct bcm_kona_gpio *kona_gpio; |
197 | void __iomem *reg_base; |
198 | u32 val; |
199 | unsigned long flags; |
200 | |
201 | kona_gpio = gpiochip_get_data(gc: chip); |
202 | reg_base = kona_gpio->reg_base; |
203 | raw_spin_lock_irqsave(&kona_gpio->lock, flags); |
204 | |
205 | val = readl(addr: reg_base + GPIO_CONTROL(gpio)); |
206 | val &= ~GPIO_GPCTR0_IOTR_MASK; |
207 | val |= GPIO_GPCTR0_IOTR_CMD_INPUT; |
208 | writel(val, addr: reg_base + GPIO_CONTROL(gpio)); |
209 | |
210 | raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); |
211 | |
212 | return 0; |
213 | } |
214 | |
215 | static int bcm_kona_gpio_direction_output(struct gpio_chip *chip, |
216 | unsigned gpio, int value) |
217 | { |
218 | struct bcm_kona_gpio *kona_gpio; |
219 | void __iomem *reg_base; |
220 | int bank_id = GPIO_BANK(gpio); |
221 | int bit = GPIO_BIT(gpio); |
222 | u32 val, reg_offset; |
223 | unsigned long flags; |
224 | |
225 | kona_gpio = gpiochip_get_data(gc: chip); |
226 | reg_base = kona_gpio->reg_base; |
227 | raw_spin_lock_irqsave(&kona_gpio->lock, flags); |
228 | |
229 | val = readl(addr: reg_base + GPIO_CONTROL(gpio)); |
230 | val &= ~GPIO_GPCTR0_IOTR_MASK; |
231 | val |= GPIO_GPCTR0_IOTR_CMD_0UTPUT; |
232 | writel(val, addr: reg_base + GPIO_CONTROL(gpio)); |
233 | reg_offset = value ? GPIO_OUT_SET(bank_id) : GPIO_OUT_CLEAR(bank_id); |
234 | |
235 | val = readl(addr: reg_base + reg_offset); |
236 | val |= BIT(bit); |
237 | writel(val, addr: reg_base + reg_offset); |
238 | |
239 | raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); |
240 | |
241 | return 0; |
242 | } |
243 | |
244 | static int bcm_kona_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) |
245 | { |
246 | struct bcm_kona_gpio *kona_gpio; |
247 | |
248 | kona_gpio = gpiochip_get_data(gc: chip); |
249 | if (gpio >= kona_gpio->gpio_chip.ngpio) |
250 | return -ENXIO; |
251 | return irq_create_mapping(host: kona_gpio->irq_domain, hwirq: gpio); |
252 | } |
253 | |
254 | static int bcm_kona_gpio_set_debounce(struct gpio_chip *chip, unsigned gpio, |
255 | unsigned debounce) |
256 | { |
257 | struct bcm_kona_gpio *kona_gpio; |
258 | void __iomem *reg_base; |
259 | u32 val, res; |
260 | unsigned long flags; |
261 | |
262 | kona_gpio = gpiochip_get_data(gc: chip); |
263 | reg_base = kona_gpio->reg_base; |
264 | /* debounce must be 1-128ms (or 0) */ |
265 | if ((debounce > 0 && debounce < 1000) || debounce > 128000) { |
266 | dev_err(chip->parent, "Debounce value %u not in range\n" , |
267 | debounce); |
268 | return -EINVAL; |
269 | } |
270 | |
271 | /* calculate debounce bit value */ |
272 | if (debounce != 0) { |
273 | /* Convert to ms */ |
274 | debounce /= 1000; |
275 | /* find the MSB */ |
276 | res = fls(x: debounce) - 1; |
277 | /* Check if MSB-1 is set (round up or down) */ |
278 | if (res > 0 && (debounce & BIT(res - 1))) |
279 | res++; |
280 | } |
281 | |
282 | /* spin lock for read-modify-write of the GPIO register */ |
283 | raw_spin_lock_irqsave(&kona_gpio->lock, flags); |
284 | |
285 | val = readl(addr: reg_base + GPIO_CONTROL(gpio)); |
286 | val &= ~GPIO_GPCTR0_DBR_MASK; |
287 | |
288 | if (debounce == 0) { |
289 | /* disable debounce */ |
290 | val &= ~GPIO_GPCTR0_DB_ENABLE_MASK; |
291 | } else { |
292 | val |= GPIO_GPCTR0_DB_ENABLE_MASK | |
293 | (res << GPIO_GPCTR0_DBR_SHIFT); |
294 | } |
295 | |
296 | writel(val, addr: reg_base + GPIO_CONTROL(gpio)); |
297 | |
298 | raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); |
299 | |
300 | return 0; |
301 | } |
302 | |
303 | static int bcm_kona_gpio_set_config(struct gpio_chip *chip, unsigned gpio, |
304 | unsigned long config) |
305 | { |
306 | u32 debounce; |
307 | |
308 | if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE) |
309 | return -ENOTSUPP; |
310 | |
311 | debounce = pinconf_to_config_argument(config); |
312 | return bcm_kona_gpio_set_debounce(chip, gpio, debounce); |
313 | } |
314 | |
315 | static const struct gpio_chip template_chip = { |
316 | .label = "bcm-kona-gpio" , |
317 | .owner = THIS_MODULE, |
318 | .request = bcm_kona_gpio_request, |
319 | .free = bcm_kona_gpio_free, |
320 | .get_direction = bcm_kona_gpio_get_dir, |
321 | .direction_input = bcm_kona_gpio_direction_input, |
322 | .get = bcm_kona_gpio_get, |
323 | .direction_output = bcm_kona_gpio_direction_output, |
324 | .set = bcm_kona_gpio_set, |
325 | .set_config = bcm_kona_gpio_set_config, |
326 | .to_irq = bcm_kona_gpio_to_irq, |
327 | .base = 0, |
328 | }; |
329 | |
330 | static void bcm_kona_gpio_irq_ack(struct irq_data *d) |
331 | { |
332 | struct bcm_kona_gpio *kona_gpio; |
333 | void __iomem *reg_base; |
334 | unsigned gpio = d->hwirq; |
335 | int bank_id = GPIO_BANK(gpio); |
336 | int bit = GPIO_BIT(gpio); |
337 | u32 val; |
338 | unsigned long flags; |
339 | |
340 | kona_gpio = irq_data_get_irq_chip_data(d); |
341 | reg_base = kona_gpio->reg_base; |
342 | raw_spin_lock_irqsave(&kona_gpio->lock, flags); |
343 | |
344 | val = readl(addr: reg_base + GPIO_INT_STATUS(bank_id)); |
345 | val |= BIT(bit); |
346 | writel(val, addr: reg_base + GPIO_INT_STATUS(bank_id)); |
347 | |
348 | raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); |
349 | } |
350 | |
351 | static void bcm_kona_gpio_irq_mask(struct irq_data *d) |
352 | { |
353 | struct bcm_kona_gpio *kona_gpio; |
354 | void __iomem *reg_base; |
355 | unsigned gpio = d->hwirq; |
356 | int bank_id = GPIO_BANK(gpio); |
357 | int bit = GPIO_BIT(gpio); |
358 | u32 val; |
359 | unsigned long flags; |
360 | |
361 | kona_gpio = irq_data_get_irq_chip_data(d); |
362 | reg_base = kona_gpio->reg_base; |
363 | raw_spin_lock_irqsave(&kona_gpio->lock, flags); |
364 | |
365 | val = readl(addr: reg_base + GPIO_INT_MASK(bank_id)); |
366 | val |= BIT(bit); |
367 | writel(val, addr: reg_base + GPIO_INT_MASK(bank_id)); |
368 | gpiochip_disable_irq(gc: &kona_gpio->gpio_chip, offset: gpio); |
369 | |
370 | raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); |
371 | } |
372 | |
373 | static void bcm_kona_gpio_irq_unmask(struct irq_data *d) |
374 | { |
375 | struct bcm_kona_gpio *kona_gpio; |
376 | void __iomem *reg_base; |
377 | unsigned gpio = d->hwirq; |
378 | int bank_id = GPIO_BANK(gpio); |
379 | int bit = GPIO_BIT(gpio); |
380 | u32 val; |
381 | unsigned long flags; |
382 | |
383 | kona_gpio = irq_data_get_irq_chip_data(d); |
384 | reg_base = kona_gpio->reg_base; |
385 | raw_spin_lock_irqsave(&kona_gpio->lock, flags); |
386 | |
387 | val = readl(addr: reg_base + GPIO_INT_MSKCLR(bank_id)); |
388 | val |= BIT(bit); |
389 | writel(val, addr: reg_base + GPIO_INT_MSKCLR(bank_id)); |
390 | gpiochip_enable_irq(gc: &kona_gpio->gpio_chip, offset: gpio); |
391 | |
392 | raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); |
393 | } |
394 | |
395 | static int bcm_kona_gpio_irq_set_type(struct irq_data *d, unsigned int type) |
396 | { |
397 | struct bcm_kona_gpio *kona_gpio; |
398 | void __iomem *reg_base; |
399 | unsigned gpio = d->hwirq; |
400 | u32 lvl_type; |
401 | u32 val; |
402 | unsigned long flags; |
403 | |
404 | kona_gpio = irq_data_get_irq_chip_data(d); |
405 | reg_base = kona_gpio->reg_base; |
406 | switch (type & IRQ_TYPE_SENSE_MASK) { |
407 | case IRQ_TYPE_EDGE_RISING: |
408 | lvl_type = GPIO_GPCTR0_ITR_CMD_RISING_EDGE; |
409 | break; |
410 | |
411 | case IRQ_TYPE_EDGE_FALLING: |
412 | lvl_type = GPIO_GPCTR0_ITR_CMD_FALLING_EDGE; |
413 | break; |
414 | |
415 | case IRQ_TYPE_EDGE_BOTH: |
416 | lvl_type = GPIO_GPCTR0_ITR_CMD_BOTH_EDGE; |
417 | break; |
418 | |
419 | case IRQ_TYPE_LEVEL_HIGH: |
420 | case IRQ_TYPE_LEVEL_LOW: |
421 | /* BCM GPIO doesn't support level triggering */ |
422 | default: |
423 | dev_err(kona_gpio->gpio_chip.parent, |
424 | "Invalid BCM GPIO irq type 0x%x\n" , type); |
425 | return -EINVAL; |
426 | } |
427 | |
428 | raw_spin_lock_irqsave(&kona_gpio->lock, flags); |
429 | |
430 | val = readl(addr: reg_base + GPIO_CONTROL(gpio)); |
431 | val &= ~GPIO_GPCTR0_ITR_MASK; |
432 | val |= lvl_type << GPIO_GPCTR0_ITR_SHIFT; |
433 | writel(val, addr: reg_base + GPIO_CONTROL(gpio)); |
434 | |
435 | raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); |
436 | |
437 | return 0; |
438 | } |
439 | |
440 | static void bcm_kona_gpio_irq_handler(struct irq_desc *desc) |
441 | { |
442 | void __iomem *reg_base; |
443 | int bit, bank_id; |
444 | unsigned long sta; |
445 | struct bcm_kona_gpio_bank *bank = irq_desc_get_handler_data(desc); |
446 | struct irq_chip *chip = irq_desc_get_chip(desc); |
447 | |
448 | chained_irq_enter(chip, desc); |
449 | |
450 | /* |
451 | * For bank interrupts, we can't use chip_data to store the kona_gpio |
452 | * pointer, since GIC needs it for its own purposes. Therefore, we get |
453 | * our pointer from the bank structure. |
454 | */ |
455 | reg_base = bank->kona_gpio->reg_base; |
456 | bank_id = bank->id; |
457 | |
458 | while ((sta = readl(addr: reg_base + GPIO_INT_STATUS(bank_id)) & |
459 | (~(readl(addr: reg_base + GPIO_INT_MASK(bank_id)))))) { |
460 | for_each_set_bit(bit, &sta, 32) { |
461 | int hwirq = GPIO_PER_BANK * bank_id + bit; |
462 | /* |
463 | * Clear interrupt before handler is called so we don't |
464 | * miss any interrupt occurred during executing them. |
465 | */ |
466 | writel(readl(addr: reg_base + GPIO_INT_STATUS(bank_id)) | |
467 | BIT(bit), addr: reg_base + GPIO_INT_STATUS(bank_id)); |
468 | /* Invoke interrupt handler */ |
469 | generic_handle_domain_irq(domain: bank->kona_gpio->irq_domain, |
470 | hwirq); |
471 | } |
472 | } |
473 | |
474 | chained_irq_exit(chip, desc); |
475 | } |
476 | |
477 | static int bcm_kona_gpio_irq_reqres(struct irq_data *d) |
478 | { |
479 | struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d); |
480 | |
481 | return gpiochip_reqres_irq(gc: &kona_gpio->gpio_chip, offset: d->hwirq); |
482 | } |
483 | |
484 | static void bcm_kona_gpio_irq_relres(struct irq_data *d) |
485 | { |
486 | struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d); |
487 | |
488 | gpiochip_relres_irq(gc: &kona_gpio->gpio_chip, offset: d->hwirq); |
489 | } |
490 | |
491 | static struct irq_chip bcm_gpio_irq_chip = { |
492 | .name = "bcm-kona-gpio" , |
493 | .irq_ack = bcm_kona_gpio_irq_ack, |
494 | .irq_mask = bcm_kona_gpio_irq_mask, |
495 | .irq_unmask = bcm_kona_gpio_irq_unmask, |
496 | .irq_set_type = bcm_kona_gpio_irq_set_type, |
497 | .irq_request_resources = bcm_kona_gpio_irq_reqres, |
498 | .irq_release_resources = bcm_kona_gpio_irq_relres, |
499 | }; |
500 | |
501 | static struct of_device_id const bcm_kona_gpio_of_match[] = { |
502 | { .compatible = "brcm,kona-gpio" }, |
503 | {} |
504 | }; |
505 | |
506 | /* |
507 | * This lock class tells lockdep that GPIO irqs are in a different |
508 | * category than their parents, so it won't report false recursion. |
509 | */ |
510 | static struct lock_class_key gpio_lock_class; |
511 | static struct lock_class_key gpio_request_class; |
512 | |
513 | static int bcm_kona_gpio_irq_map(struct irq_domain *d, unsigned int irq, |
514 | irq_hw_number_t hwirq) |
515 | { |
516 | int ret; |
517 | |
518 | ret = irq_set_chip_data(irq, data: d->host_data); |
519 | if (ret < 0) |
520 | return ret; |
521 | irq_set_lockdep_class(irq, lock_class: &gpio_lock_class, request_class: &gpio_request_class); |
522 | irq_set_chip_and_handler(irq, chip: &bcm_gpio_irq_chip, handle: handle_simple_irq); |
523 | irq_set_noprobe(irq); |
524 | |
525 | return 0; |
526 | } |
527 | |
528 | static void bcm_kona_gpio_irq_unmap(struct irq_domain *d, unsigned int irq) |
529 | { |
530 | irq_set_chip_and_handler(irq, NULL, NULL); |
531 | irq_set_chip_data(irq, NULL); |
532 | } |
533 | |
534 | static const struct irq_domain_ops bcm_kona_irq_ops = { |
535 | .map = bcm_kona_gpio_irq_map, |
536 | .unmap = bcm_kona_gpio_irq_unmap, |
537 | .xlate = irq_domain_xlate_twocell, |
538 | }; |
539 | |
540 | static void bcm_kona_gpio_reset(struct bcm_kona_gpio *kona_gpio) |
541 | { |
542 | void __iomem *reg_base; |
543 | int i; |
544 | |
545 | reg_base = kona_gpio->reg_base; |
546 | /* disable interrupts and clear status */ |
547 | for (i = 0; i < kona_gpio->num_bank; i++) { |
548 | /* Unlock the entire bank first */ |
549 | bcm_kona_gpio_write_lock_regs(reg_base, bank_id: i, UNLOCK_CODE); |
550 | writel(val: 0xffffffff, addr: reg_base + GPIO_INT_MASK(i)); |
551 | writel(val: 0xffffffff, addr: reg_base + GPIO_INT_STATUS(i)); |
552 | /* Now re-lock the bank */ |
553 | bcm_kona_gpio_write_lock_regs(reg_base, bank_id: i, LOCK_CODE); |
554 | } |
555 | } |
556 | |
557 | static int bcm_kona_gpio_probe(struct platform_device *pdev) |
558 | { |
559 | struct device *dev = &pdev->dev; |
560 | struct bcm_kona_gpio_bank *bank; |
561 | struct bcm_kona_gpio *kona_gpio; |
562 | struct gpio_chip *chip; |
563 | int ret; |
564 | int i; |
565 | |
566 | kona_gpio = devm_kzalloc(dev, size: sizeof(*kona_gpio), GFP_KERNEL); |
567 | if (!kona_gpio) |
568 | return -ENOMEM; |
569 | |
570 | kona_gpio->gpio_chip = template_chip; |
571 | chip = &kona_gpio->gpio_chip; |
572 | ret = platform_irq_count(pdev); |
573 | if (!ret) { |
574 | dev_err(dev, "Couldn't determine # GPIO banks\n" ); |
575 | return -ENOENT; |
576 | } else if (ret < 0) { |
577 | return dev_err_probe(dev, err: ret, fmt: "Couldn't determine GPIO banks\n" ); |
578 | } |
579 | kona_gpio->num_bank = ret; |
580 | |
581 | if (kona_gpio->num_bank > GPIO_MAX_BANK_NUM) { |
582 | dev_err(dev, "Too many GPIO banks configured (max=%d)\n" , |
583 | GPIO_MAX_BANK_NUM); |
584 | return -ENXIO; |
585 | } |
586 | kona_gpio->banks = devm_kcalloc(dev, |
587 | n: kona_gpio->num_bank, |
588 | size: sizeof(*kona_gpio->banks), |
589 | GFP_KERNEL); |
590 | if (!kona_gpio->banks) |
591 | return -ENOMEM; |
592 | |
593 | chip->parent = dev; |
594 | chip->ngpio = kona_gpio->num_bank * GPIO_PER_BANK; |
595 | |
596 | kona_gpio->irq_domain = irq_domain_create_linear(dev_fwnode(dev), |
597 | size: chip->ngpio, |
598 | ops: &bcm_kona_irq_ops, |
599 | host_data: kona_gpio); |
600 | if (!kona_gpio->irq_domain) { |
601 | dev_err(dev, "Couldn't allocate IRQ domain\n" ); |
602 | return -ENXIO; |
603 | } |
604 | |
605 | kona_gpio->reg_base = devm_platform_ioremap_resource(pdev, index: 0); |
606 | if (IS_ERR(ptr: kona_gpio->reg_base)) { |
607 | ret = PTR_ERR(ptr: kona_gpio->reg_base); |
608 | goto err_irq_domain; |
609 | } |
610 | |
611 | for (i = 0; i < kona_gpio->num_bank; i++) { |
612 | bank = &kona_gpio->banks[i]; |
613 | bank->id = i; |
614 | bank->irq = platform_get_irq(pdev, i); |
615 | bank->kona_gpio = kona_gpio; |
616 | if (bank->irq < 0) { |
617 | dev_err(dev, "Couldn't get IRQ for bank %d" , i); |
618 | ret = -ENOENT; |
619 | goto err_irq_domain; |
620 | } |
621 | } |
622 | |
623 | dev_info(&pdev->dev, "Setting up Kona GPIO\n" ); |
624 | |
625 | bcm_kona_gpio_reset(kona_gpio); |
626 | |
627 | ret = devm_gpiochip_add_data(dev, chip, kona_gpio); |
628 | if (ret < 0) { |
629 | dev_err(dev, "Couldn't add GPIO chip -- %d\n" , ret); |
630 | goto err_irq_domain; |
631 | } |
632 | for (i = 0; i < kona_gpio->num_bank; i++) { |
633 | bank = &kona_gpio->banks[i]; |
634 | irq_set_chained_handler_and_data(irq: bank->irq, |
635 | handle: bcm_kona_gpio_irq_handler, |
636 | data: bank); |
637 | } |
638 | |
639 | raw_spin_lock_init(&kona_gpio->lock); |
640 | |
641 | return 0; |
642 | |
643 | err_irq_domain: |
644 | irq_domain_remove(host: kona_gpio->irq_domain); |
645 | |
646 | return ret; |
647 | } |
648 | |
649 | static struct platform_driver bcm_kona_gpio_driver = { |
650 | .driver = { |
651 | .name = "bcm-kona-gpio" , |
652 | .of_match_table = bcm_kona_gpio_of_match, |
653 | }, |
654 | .probe = bcm_kona_gpio_probe, |
655 | }; |
656 | builtin_platform_driver(bcm_kona_gpio_driver); |
657 | |