1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright (C) 2017 Broadcom |
4 | */ |
5 | |
6 | #include <linux/gpio/driver.h> |
7 | #include <linux/init.h> |
8 | #include <linux/interrupt.h> |
9 | #include <linux/io.h> |
10 | #include <linux/irq.h> |
11 | #include <linux/kernel.h> |
12 | #include <linux/module.h> |
13 | #include <linux/platform_device.h> |
14 | #include <linux/seq_file.h> |
15 | #include <linux/spinlock.h> |
16 | |
17 | #define IPROC_CCA_INT_F_GPIOINT BIT(0) |
18 | #define IPROC_CCA_INT_STS 0x20 |
19 | #define IPROC_CCA_INT_MASK 0x24 |
20 | |
21 | #define IPROC_GPIO_CCA_DIN 0x0 |
22 | #define IPROC_GPIO_CCA_DOUT 0x4 |
23 | #define IPROC_GPIO_CCA_OUT_EN 0x8 |
24 | #define IPROC_GPIO_CCA_INT_LEVEL 0x10 |
25 | #define IPROC_GPIO_CCA_INT_LEVEL_MASK 0x14 |
26 | #define IPROC_GPIO_CCA_INT_EVENT 0x18 |
27 | #define IPROC_GPIO_CCA_INT_EVENT_MASK 0x1C |
28 | #define IPROC_GPIO_CCA_INT_EDGE 0x24 |
29 | |
30 | struct iproc_gpio_chip { |
31 | struct gpio_chip gc; |
32 | spinlock_t lock; |
33 | struct device *dev; |
34 | void __iomem *base; |
35 | void __iomem *intr; |
36 | }; |
37 | |
38 | static inline struct iproc_gpio_chip * |
39 | to_iproc_gpio(struct gpio_chip *gc) |
40 | { |
41 | return container_of(gc, struct iproc_gpio_chip, gc); |
42 | } |
43 | |
44 | static void iproc_gpio_irq_ack(struct irq_data *d) |
45 | { |
46 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
47 | struct iproc_gpio_chip *chip = to_iproc_gpio(gc); |
48 | int pin = d->hwirq; |
49 | unsigned long flags; |
50 | u32 irq = d->irq; |
51 | u32 irq_type, event_status = 0; |
52 | |
53 | spin_lock_irqsave(&chip->lock, flags); |
54 | irq_type = irq_get_trigger_type(irq); |
55 | if (irq_type & IRQ_TYPE_EDGE_BOTH) { |
56 | event_status |= BIT(pin); |
57 | writel_relaxed(event_status, |
58 | chip->base + IPROC_GPIO_CCA_INT_EVENT); |
59 | } |
60 | spin_unlock_irqrestore(lock: &chip->lock, flags); |
61 | } |
62 | |
63 | static void iproc_gpio_irq_unmask(struct irq_data *d) |
64 | { |
65 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
66 | struct iproc_gpio_chip *chip = to_iproc_gpio(gc); |
67 | int pin = d->hwirq; |
68 | unsigned long flags; |
69 | u32 irq = d->irq; |
70 | u32 int_mask, irq_type, event_mask; |
71 | |
72 | gpiochip_enable_irq(gc, offset: pin); |
73 | spin_lock_irqsave(&chip->lock, flags); |
74 | irq_type = irq_get_trigger_type(irq); |
75 | event_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK); |
76 | int_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK); |
77 | |
78 | if (irq_type & IRQ_TYPE_EDGE_BOTH) { |
79 | event_mask |= 1 << pin; |
80 | writel_relaxed(event_mask, |
81 | chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK); |
82 | } else { |
83 | int_mask |= 1 << pin; |
84 | writel_relaxed(int_mask, |
85 | chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK); |
86 | } |
87 | spin_unlock_irqrestore(lock: &chip->lock, flags); |
88 | } |
89 | |
90 | static void iproc_gpio_irq_mask(struct irq_data *d) |
91 | { |
92 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
93 | struct iproc_gpio_chip *chip = to_iproc_gpio(gc); |
94 | int pin = d->hwirq; |
95 | unsigned long flags; |
96 | u32 irq = d->irq; |
97 | u32 irq_type, int_mask, event_mask; |
98 | |
99 | spin_lock_irqsave(&chip->lock, flags); |
100 | irq_type = irq_get_trigger_type(irq); |
101 | event_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK); |
102 | int_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK); |
103 | |
104 | if (irq_type & IRQ_TYPE_EDGE_BOTH) { |
105 | event_mask &= ~BIT(pin); |
106 | writel_relaxed(event_mask, |
107 | chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK); |
108 | } else { |
109 | int_mask &= ~BIT(pin); |
110 | writel_relaxed(int_mask, |
111 | chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK); |
112 | } |
113 | spin_unlock_irqrestore(lock: &chip->lock, flags); |
114 | gpiochip_disable_irq(gc, offset: pin); |
115 | } |
116 | |
117 | static int iproc_gpio_irq_set_type(struct irq_data *d, u32 type) |
118 | { |
119 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
120 | struct iproc_gpio_chip *chip = to_iproc_gpio(gc); |
121 | int pin = d->hwirq; |
122 | unsigned long flags; |
123 | u32 irq = d->irq; |
124 | u32 event_pol, int_pol; |
125 | int ret = 0; |
126 | |
127 | spin_lock_irqsave(&chip->lock, flags); |
128 | switch (type & IRQ_TYPE_SENSE_MASK) { |
129 | case IRQ_TYPE_EDGE_RISING: |
130 | event_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EDGE); |
131 | event_pol &= ~BIT(pin); |
132 | writel_relaxed(event_pol, chip->base + IPROC_GPIO_CCA_INT_EDGE); |
133 | break; |
134 | case IRQ_TYPE_EDGE_FALLING: |
135 | event_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EDGE); |
136 | event_pol |= BIT(pin); |
137 | writel_relaxed(event_pol, chip->base + IPROC_GPIO_CCA_INT_EDGE); |
138 | break; |
139 | case IRQ_TYPE_LEVEL_HIGH: |
140 | int_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL); |
141 | int_pol &= ~BIT(pin); |
142 | writel_relaxed(int_pol, chip->base + IPROC_GPIO_CCA_INT_LEVEL); |
143 | break; |
144 | case IRQ_TYPE_LEVEL_LOW: |
145 | int_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL); |
146 | int_pol |= BIT(pin); |
147 | writel_relaxed(int_pol, chip->base + IPROC_GPIO_CCA_INT_LEVEL); |
148 | break; |
149 | default: |
150 | /* should not come here */ |
151 | ret = -EINVAL; |
152 | goto out_unlock; |
153 | } |
154 | |
155 | if (type & IRQ_TYPE_LEVEL_MASK) |
156 | irq_set_handler_locked(data: irq_get_irq_data(irq), handler: handle_level_irq); |
157 | else if (type & IRQ_TYPE_EDGE_BOTH) |
158 | irq_set_handler_locked(data: irq_get_irq_data(irq), handler: handle_edge_irq); |
159 | |
160 | out_unlock: |
161 | spin_unlock_irqrestore(lock: &chip->lock, flags); |
162 | |
163 | return ret; |
164 | } |
165 | |
166 | static irqreturn_t iproc_gpio_irq_handler(int irq, void *data) |
167 | { |
168 | struct gpio_chip *gc = (struct gpio_chip *)data; |
169 | struct iproc_gpio_chip *chip = to_iproc_gpio(gc); |
170 | int bit; |
171 | unsigned long int_bits = 0; |
172 | u32 int_status; |
173 | |
174 | /* go through the entire GPIOs and handle all interrupts */ |
175 | int_status = readl_relaxed(chip->intr + IPROC_CCA_INT_STS); |
176 | if (int_status & IPROC_CCA_INT_F_GPIOINT) { |
177 | u32 event, level; |
178 | |
179 | /* Get level and edge interrupts */ |
180 | event = |
181 | readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK); |
182 | event &= readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT); |
183 | level = readl_relaxed(chip->base + IPROC_GPIO_CCA_DIN); |
184 | level ^= readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL); |
185 | level &= |
186 | readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK); |
187 | int_bits = level | event; |
188 | |
189 | for_each_set_bit(bit, &int_bits, gc->ngpio) |
190 | generic_handle_domain_irq(domain: gc->irq.domain, hwirq: bit); |
191 | } |
192 | |
193 | return int_bits ? IRQ_HANDLED : IRQ_NONE; |
194 | } |
195 | |
196 | static void iproc_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p) |
197 | { |
198 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
199 | struct iproc_gpio_chip *chip = to_iproc_gpio(gc); |
200 | |
201 | seq_printf(m: p, fmt: dev_name(dev: chip->dev)); |
202 | } |
203 | |
204 | static const struct irq_chip iproc_gpio_irq_chip = { |
205 | .irq_ack = iproc_gpio_irq_ack, |
206 | .irq_mask = iproc_gpio_irq_mask, |
207 | .irq_unmask = iproc_gpio_irq_unmask, |
208 | .irq_set_type = iproc_gpio_irq_set_type, |
209 | .irq_print_chip = iproc_gpio_irq_print_chip, |
210 | .flags = IRQCHIP_IMMUTABLE, |
211 | GPIOCHIP_IRQ_RESOURCE_HELPERS, |
212 | }; |
213 | |
214 | static int iproc_gpio_probe(struct platform_device *pdev) |
215 | { |
216 | struct device *dev = &pdev->dev; |
217 | struct device_node *dn = pdev->dev.of_node; |
218 | struct iproc_gpio_chip *chip; |
219 | u32 num_gpios; |
220 | int irq, ret; |
221 | |
222 | chip = devm_kzalloc(dev, size: sizeof(*chip), GFP_KERNEL); |
223 | if (!chip) |
224 | return -ENOMEM; |
225 | |
226 | chip->dev = dev; |
227 | platform_set_drvdata(pdev, data: chip); |
228 | spin_lock_init(&chip->lock); |
229 | |
230 | chip->base = devm_platform_ioremap_resource(pdev, index: 0); |
231 | if (IS_ERR(ptr: chip->base)) |
232 | return PTR_ERR(ptr: chip->base); |
233 | |
234 | ret = bgpio_init(gc: &chip->gc, dev, sz: 4, |
235 | dat: chip->base + IPROC_GPIO_CCA_DIN, |
236 | set: chip->base + IPROC_GPIO_CCA_DOUT, |
237 | NULL, |
238 | dirout: chip->base + IPROC_GPIO_CCA_OUT_EN, |
239 | NULL, |
240 | flags: 0); |
241 | if (ret) { |
242 | dev_err(dev, "unable to init GPIO chip\n" ); |
243 | return ret; |
244 | } |
245 | |
246 | chip->gc.label = dev_name(dev); |
247 | if (!of_property_read_u32(np: dn, propname: "ngpios" , out_value: &num_gpios)) |
248 | chip->gc.ngpio = num_gpios; |
249 | |
250 | irq = platform_get_irq(pdev, 0); |
251 | if (irq > 0) { |
252 | struct gpio_irq_chip *girq; |
253 | u32 val; |
254 | |
255 | chip->intr = devm_platform_ioremap_resource(pdev, index: 1); |
256 | if (IS_ERR(ptr: chip->intr)) |
257 | return PTR_ERR(ptr: chip->intr); |
258 | |
259 | /* Enable GPIO interrupts for CCA GPIO */ |
260 | val = readl_relaxed(chip->intr + IPROC_CCA_INT_MASK); |
261 | val |= IPROC_CCA_INT_F_GPIOINT; |
262 | writel_relaxed(val, chip->intr + IPROC_CCA_INT_MASK); |
263 | |
264 | /* |
265 | * Directly request the irq here instead of passing |
266 | * a flow-handler because the irq is shared. |
267 | */ |
268 | ret = devm_request_irq(dev, irq, handler: iproc_gpio_irq_handler, |
269 | IRQF_SHARED, devname: chip->gc.label, dev_id: &chip->gc); |
270 | if (ret) { |
271 | dev_err(dev, "Fail to request IRQ%d: %d\n" , irq, ret); |
272 | return ret; |
273 | } |
274 | |
275 | girq = &chip->gc.irq; |
276 | gpio_irq_chip_set_chip(girq, chip: &iproc_gpio_irq_chip); |
277 | /* This will let us handle the parent IRQ in the driver */ |
278 | girq->parent_handler = NULL; |
279 | girq->num_parents = 0; |
280 | girq->parents = NULL; |
281 | girq->default_type = IRQ_TYPE_NONE; |
282 | girq->handler = handle_simple_irq; |
283 | } |
284 | |
285 | ret = devm_gpiochip_add_data(dev, &chip->gc, chip); |
286 | if (ret) { |
287 | dev_err(dev, "unable to add GPIO chip\n" ); |
288 | return ret; |
289 | } |
290 | |
291 | return 0; |
292 | } |
293 | |
294 | static void iproc_gpio_remove(struct platform_device *pdev) |
295 | { |
296 | struct iproc_gpio_chip *chip = platform_get_drvdata(pdev); |
297 | |
298 | if (chip->intr) { |
299 | u32 val; |
300 | |
301 | val = readl_relaxed(chip->intr + IPROC_CCA_INT_MASK); |
302 | val &= ~IPROC_CCA_INT_F_GPIOINT; |
303 | writel_relaxed(val, chip->intr + IPROC_CCA_INT_MASK); |
304 | } |
305 | } |
306 | |
307 | static const struct of_device_id bcm_iproc_gpio_of_match[] = { |
308 | { .compatible = "brcm,iproc-gpio-cca" }, |
309 | {} |
310 | }; |
311 | MODULE_DEVICE_TABLE(of, bcm_iproc_gpio_of_match); |
312 | |
313 | static struct platform_driver bcm_iproc_gpio_driver = { |
314 | .driver = { |
315 | .name = "iproc-xgs-gpio" , |
316 | .of_match_table = bcm_iproc_gpio_of_match, |
317 | }, |
318 | .probe = iproc_gpio_probe, |
319 | .remove_new = iproc_gpio_remove, |
320 | }; |
321 | |
322 | module_platform_driver(bcm_iproc_gpio_driver); |
323 | |
324 | MODULE_DESCRIPTION("XGS IPROC GPIO driver" ); |
325 | MODULE_LICENSE("GPL v2" ); |
326 | |