1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Renesas R-Car GPIO Support |
4 | * |
5 | * Copyright (C) 2014 Renesas Electronics Corporation |
6 | * Copyright (C) 2013 Magnus Damm |
7 | */ |
8 | |
9 | #include <linux/err.h> |
10 | #include <linux/gpio/driver.h> |
11 | #include <linux/init.h> |
12 | #include <linux/interrupt.h> |
13 | #include <linux/io.h> |
14 | #include <linux/ioport.h> |
15 | #include <linux/irq.h> |
16 | #include <linux/module.h> |
17 | #include <linux/of.h> |
18 | #include <linux/pinctrl/consumer.h> |
19 | #include <linux/platform_device.h> |
20 | #include <linux/pm_runtime.h> |
21 | #include <linux/spinlock.h> |
22 | #include <linux/slab.h> |
23 | |
24 | struct gpio_rcar_bank_info { |
25 | u32 iointsel; |
26 | u32 inoutsel; |
27 | u32 outdt; |
28 | u32 posneg; |
29 | u32 edglevel; |
30 | u32 bothedge; |
31 | u32 intmsk; |
32 | }; |
33 | |
34 | struct gpio_rcar_info { |
35 | bool has_outdtsel; |
36 | bool has_both_edge_trigger; |
37 | bool has_always_in; |
38 | bool has_inen; |
39 | }; |
40 | |
41 | struct gpio_rcar_priv { |
42 | void __iomem *base; |
43 | spinlock_t lock; |
44 | struct device *dev; |
45 | struct gpio_chip gpio_chip; |
46 | unsigned int irq_parent; |
47 | atomic_t wakeup_path; |
48 | struct gpio_rcar_info info; |
49 | struct gpio_rcar_bank_info bank_info; |
50 | }; |
51 | |
52 | #define IOINTSEL 0x00 /* General IO/Interrupt Switching Register */ |
53 | #define INOUTSEL 0x04 /* General Input/Output Switching Register */ |
54 | #define OUTDT 0x08 /* General Output Register */ |
55 | #define INDT 0x0c /* General Input Register */ |
56 | #define INTDT 0x10 /* Interrupt Display Register */ |
57 | #define INTCLR 0x14 /* Interrupt Clear Register */ |
58 | #define INTMSK 0x18 /* Interrupt Mask Register */ |
59 | #define MSKCLR 0x1c /* Interrupt Mask Clear Register */ |
60 | #define POSNEG 0x20 /* Positive/Negative Logic Select Register */ |
61 | #define EDGLEVEL 0x24 /* Edge/level Select Register */ |
62 | #define FILONOFF 0x28 /* Chattering Prevention On/Off Register */ |
63 | #define OUTDTSEL 0x40 /* Output Data Select Register */ |
64 | #define BOTHEDGE 0x4c /* One Edge/Both Edge Select Register */ |
65 | #define INEN 0x50 /* General Input Enable Register */ |
66 | |
67 | #define RCAR_MAX_GPIO_PER_BANK 32 |
68 | |
69 | static inline u32 gpio_rcar_read(struct gpio_rcar_priv *p, int offs) |
70 | { |
71 | return ioread32(p->base + offs); |
72 | } |
73 | |
74 | static inline void gpio_rcar_write(struct gpio_rcar_priv *p, int offs, |
75 | u32 value) |
76 | { |
77 | iowrite32(value, p->base + offs); |
78 | } |
79 | |
80 | static void gpio_rcar_modify_bit(struct gpio_rcar_priv *p, int offs, |
81 | int bit, bool value) |
82 | { |
83 | u32 tmp = gpio_rcar_read(p, offs); |
84 | |
85 | if (value) |
86 | tmp |= BIT(bit); |
87 | else |
88 | tmp &= ~BIT(bit); |
89 | |
90 | gpio_rcar_write(p, offs, value: tmp); |
91 | } |
92 | |
93 | static void gpio_rcar_irq_disable(struct irq_data *d) |
94 | { |
95 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
96 | struct gpio_rcar_priv *p = gpiochip_get_data(gc); |
97 | irq_hw_number_t hwirq = irqd_to_hwirq(d); |
98 | |
99 | gpio_rcar_write(p, INTMSK, value: ~BIT(hwirq)); |
100 | gpiochip_disable_irq(gc, offset: hwirq); |
101 | } |
102 | |
103 | static void gpio_rcar_irq_enable(struct irq_data *d) |
104 | { |
105 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
106 | struct gpio_rcar_priv *p = gpiochip_get_data(gc); |
107 | irq_hw_number_t hwirq = irqd_to_hwirq(d); |
108 | |
109 | gpiochip_enable_irq(gc, offset: hwirq); |
110 | gpio_rcar_write(p, MSKCLR, BIT(hwirq)); |
111 | } |
112 | |
113 | static void gpio_rcar_config_interrupt_input_mode(struct gpio_rcar_priv *p, |
114 | unsigned int hwirq, |
115 | bool active_high_rising_edge, |
116 | bool level_trigger, |
117 | bool both) |
118 | { |
119 | unsigned long flags; |
120 | |
121 | /* follow steps in the GPIO documentation for |
122 | * "Setting Edge-Sensitive Interrupt Input Mode" and |
123 | * "Setting Level-Sensitive Interrupt Input Mode" |
124 | */ |
125 | |
126 | spin_lock_irqsave(&p->lock, flags); |
127 | |
128 | /* Configure positive or negative logic in POSNEG */ |
129 | gpio_rcar_modify_bit(p, POSNEG, bit: hwirq, value: !active_high_rising_edge); |
130 | |
131 | /* Configure edge or level trigger in EDGLEVEL */ |
132 | gpio_rcar_modify_bit(p, EDGLEVEL, bit: hwirq, value: !level_trigger); |
133 | |
134 | /* Select one edge or both edges in BOTHEDGE */ |
135 | if (p->info.has_both_edge_trigger) |
136 | gpio_rcar_modify_bit(p, BOTHEDGE, bit: hwirq, value: both); |
137 | |
138 | /* Select "Interrupt Input Mode" in IOINTSEL */ |
139 | gpio_rcar_modify_bit(p, IOINTSEL, bit: hwirq, value: true); |
140 | |
141 | /* Write INTCLR in case of edge trigger */ |
142 | if (!level_trigger) |
143 | gpio_rcar_write(p, INTCLR, BIT(hwirq)); |
144 | |
145 | spin_unlock_irqrestore(lock: &p->lock, flags); |
146 | } |
147 | |
148 | static int gpio_rcar_irq_set_type(struct irq_data *d, unsigned int type) |
149 | { |
150 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
151 | struct gpio_rcar_priv *p = gpiochip_get_data(gc); |
152 | unsigned int hwirq = irqd_to_hwirq(d); |
153 | |
154 | dev_dbg(p->dev, "sense irq = %d, type = %d\n" , hwirq, type); |
155 | |
156 | switch (type & IRQ_TYPE_SENSE_MASK) { |
157 | case IRQ_TYPE_LEVEL_HIGH: |
158 | gpio_rcar_config_interrupt_input_mode(p, hwirq, active_high_rising_edge: true, level_trigger: true, |
159 | both: false); |
160 | break; |
161 | case IRQ_TYPE_LEVEL_LOW: |
162 | gpio_rcar_config_interrupt_input_mode(p, hwirq, active_high_rising_edge: false, level_trigger: true, |
163 | both: false); |
164 | break; |
165 | case IRQ_TYPE_EDGE_RISING: |
166 | gpio_rcar_config_interrupt_input_mode(p, hwirq, active_high_rising_edge: true, level_trigger: false, |
167 | both: false); |
168 | break; |
169 | case IRQ_TYPE_EDGE_FALLING: |
170 | gpio_rcar_config_interrupt_input_mode(p, hwirq, active_high_rising_edge: false, level_trigger: false, |
171 | both: false); |
172 | break; |
173 | case IRQ_TYPE_EDGE_BOTH: |
174 | if (!p->info.has_both_edge_trigger) |
175 | return -EINVAL; |
176 | gpio_rcar_config_interrupt_input_mode(p, hwirq, active_high_rising_edge: true, level_trigger: false, |
177 | both: true); |
178 | break; |
179 | default: |
180 | return -EINVAL; |
181 | } |
182 | return 0; |
183 | } |
184 | |
185 | static int gpio_rcar_irq_set_wake(struct irq_data *d, unsigned int on) |
186 | { |
187 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
188 | struct gpio_rcar_priv *p = gpiochip_get_data(gc); |
189 | int error; |
190 | |
191 | if (p->irq_parent) { |
192 | error = irq_set_irq_wake(irq: p->irq_parent, on); |
193 | if (error) { |
194 | dev_dbg(p->dev, "irq %u doesn't support irq_set_wake\n" , |
195 | p->irq_parent); |
196 | p->irq_parent = 0; |
197 | } |
198 | } |
199 | |
200 | if (on) |
201 | atomic_inc(v: &p->wakeup_path); |
202 | else |
203 | atomic_dec(v: &p->wakeup_path); |
204 | |
205 | return 0; |
206 | } |
207 | |
208 | static const struct irq_chip gpio_rcar_irq_chip = { |
209 | .name = "gpio-rcar" , |
210 | .irq_mask = gpio_rcar_irq_disable, |
211 | .irq_unmask = gpio_rcar_irq_enable, |
212 | .irq_set_type = gpio_rcar_irq_set_type, |
213 | .irq_set_wake = gpio_rcar_irq_set_wake, |
214 | .flags = IRQCHIP_IMMUTABLE | IRQCHIP_SET_TYPE_MASKED | |
215 | IRQCHIP_MASK_ON_SUSPEND, |
216 | GPIOCHIP_IRQ_RESOURCE_HELPERS, |
217 | }; |
218 | |
219 | static irqreturn_t gpio_rcar_irq_handler(int irq, void *dev_id) |
220 | { |
221 | struct gpio_rcar_priv *p = dev_id; |
222 | u32 pending; |
223 | unsigned int offset, irqs_handled = 0; |
224 | |
225 | while ((pending = gpio_rcar_read(p, INTDT) & |
226 | gpio_rcar_read(p, INTMSK))) { |
227 | offset = __ffs(pending); |
228 | gpio_rcar_write(p, INTCLR, BIT(offset)); |
229 | generic_handle_domain_irq(domain: p->gpio_chip.irq.domain, |
230 | hwirq: offset); |
231 | irqs_handled++; |
232 | } |
233 | |
234 | return irqs_handled ? IRQ_HANDLED : IRQ_NONE; |
235 | } |
236 | |
237 | static void gpio_rcar_config_general_input_output_mode(struct gpio_chip *chip, |
238 | unsigned int gpio, |
239 | bool output) |
240 | { |
241 | struct gpio_rcar_priv *p = gpiochip_get_data(gc: chip); |
242 | unsigned long flags; |
243 | |
244 | /* follow steps in the GPIO documentation for |
245 | * "Setting General Output Mode" and |
246 | * "Setting General Input Mode" |
247 | */ |
248 | |
249 | spin_lock_irqsave(&p->lock, flags); |
250 | |
251 | /* Configure positive logic in POSNEG */ |
252 | gpio_rcar_modify_bit(p, POSNEG, bit: gpio, value: false); |
253 | |
254 | /* Select "General Input/Output Mode" in IOINTSEL */ |
255 | gpio_rcar_modify_bit(p, IOINTSEL, bit: gpio, value: false); |
256 | |
257 | /* Select Input Mode or Output Mode in INOUTSEL */ |
258 | gpio_rcar_modify_bit(p, INOUTSEL, bit: gpio, value: output); |
259 | |
260 | /* Select General Output Register to output data in OUTDTSEL */ |
261 | if (p->info.has_outdtsel && output) |
262 | gpio_rcar_modify_bit(p, OUTDTSEL, bit: gpio, value: false); |
263 | |
264 | spin_unlock_irqrestore(lock: &p->lock, flags); |
265 | } |
266 | |
267 | static int gpio_rcar_request(struct gpio_chip *chip, unsigned offset) |
268 | { |
269 | struct gpio_rcar_priv *p = gpiochip_get_data(gc: chip); |
270 | int error; |
271 | |
272 | error = pm_runtime_get_sync(dev: p->dev); |
273 | if (error < 0) { |
274 | pm_runtime_put(dev: p->dev); |
275 | return error; |
276 | } |
277 | |
278 | error = pinctrl_gpio_request(gc: chip, offset); |
279 | if (error) |
280 | pm_runtime_put(dev: p->dev); |
281 | |
282 | return error; |
283 | } |
284 | |
285 | static void gpio_rcar_free(struct gpio_chip *chip, unsigned offset) |
286 | { |
287 | struct gpio_rcar_priv *p = gpiochip_get_data(gc: chip); |
288 | |
289 | pinctrl_gpio_free(gc: chip, offset); |
290 | |
291 | /* |
292 | * Set the GPIO as an input to ensure that the next GPIO request won't |
293 | * drive the GPIO pin as an output. |
294 | */ |
295 | gpio_rcar_config_general_input_output_mode(chip, gpio: offset, output: false); |
296 | |
297 | pm_runtime_put(dev: p->dev); |
298 | } |
299 | |
300 | static int gpio_rcar_get_direction(struct gpio_chip *chip, unsigned int offset) |
301 | { |
302 | struct gpio_rcar_priv *p = gpiochip_get_data(gc: chip); |
303 | |
304 | if (gpio_rcar_read(p, INOUTSEL) & BIT(offset)) |
305 | return GPIO_LINE_DIRECTION_OUT; |
306 | |
307 | return GPIO_LINE_DIRECTION_IN; |
308 | } |
309 | |
310 | static int gpio_rcar_direction_input(struct gpio_chip *chip, unsigned offset) |
311 | { |
312 | gpio_rcar_config_general_input_output_mode(chip, gpio: offset, output: false); |
313 | return 0; |
314 | } |
315 | |
316 | static int gpio_rcar_get(struct gpio_chip *chip, unsigned offset) |
317 | { |
318 | struct gpio_rcar_priv *p = gpiochip_get_data(gc: chip); |
319 | u32 bit = BIT(offset); |
320 | |
321 | /* |
322 | * Before R-Car Gen3, INDT does not show correct pin state when |
323 | * configured as output, so use OUTDT in case of output pins |
324 | */ |
325 | if (!p->info.has_always_in && (gpio_rcar_read(p, INOUTSEL) & bit)) |
326 | return !!(gpio_rcar_read(p, OUTDT) & bit); |
327 | else |
328 | return !!(gpio_rcar_read(p, INDT) & bit); |
329 | } |
330 | |
331 | static int gpio_rcar_get_multiple(struct gpio_chip *chip, unsigned long *mask, |
332 | unsigned long *bits) |
333 | { |
334 | struct gpio_rcar_priv *p = gpiochip_get_data(gc: chip); |
335 | u32 bankmask, outputs, m, val = 0; |
336 | unsigned long flags; |
337 | |
338 | bankmask = mask[0] & GENMASK(chip->ngpio - 1, 0); |
339 | if (chip->valid_mask) |
340 | bankmask &= chip->valid_mask[0]; |
341 | |
342 | if (!bankmask) |
343 | return 0; |
344 | |
345 | if (p->info.has_always_in) { |
346 | bits[0] = gpio_rcar_read(p, INDT) & bankmask; |
347 | return 0; |
348 | } |
349 | |
350 | spin_lock_irqsave(&p->lock, flags); |
351 | outputs = gpio_rcar_read(p, INOUTSEL); |
352 | m = outputs & bankmask; |
353 | if (m) |
354 | val |= gpio_rcar_read(p, OUTDT) & m; |
355 | |
356 | m = ~outputs & bankmask; |
357 | if (m) |
358 | val |= gpio_rcar_read(p, INDT) & m; |
359 | spin_unlock_irqrestore(lock: &p->lock, flags); |
360 | |
361 | bits[0] = val; |
362 | return 0; |
363 | } |
364 | |
365 | static void gpio_rcar_set(struct gpio_chip *chip, unsigned offset, int value) |
366 | { |
367 | struct gpio_rcar_priv *p = gpiochip_get_data(gc: chip); |
368 | unsigned long flags; |
369 | |
370 | spin_lock_irqsave(&p->lock, flags); |
371 | gpio_rcar_modify_bit(p, OUTDT, bit: offset, value); |
372 | spin_unlock_irqrestore(lock: &p->lock, flags); |
373 | } |
374 | |
375 | static void gpio_rcar_set_multiple(struct gpio_chip *chip, unsigned long *mask, |
376 | unsigned long *bits) |
377 | { |
378 | struct gpio_rcar_priv *p = gpiochip_get_data(gc: chip); |
379 | unsigned long flags; |
380 | u32 val, bankmask; |
381 | |
382 | bankmask = mask[0] & GENMASK(chip->ngpio - 1, 0); |
383 | if (chip->valid_mask) |
384 | bankmask &= chip->valid_mask[0]; |
385 | |
386 | if (!bankmask) |
387 | return; |
388 | |
389 | spin_lock_irqsave(&p->lock, flags); |
390 | val = gpio_rcar_read(p, OUTDT); |
391 | val &= ~bankmask; |
392 | val |= (bankmask & bits[0]); |
393 | gpio_rcar_write(p, OUTDT, value: val); |
394 | spin_unlock_irqrestore(lock: &p->lock, flags); |
395 | } |
396 | |
397 | static int gpio_rcar_direction_output(struct gpio_chip *chip, unsigned offset, |
398 | int value) |
399 | { |
400 | /* write GPIO value to output before selecting output mode of pin */ |
401 | gpio_rcar_set(chip, offset, value); |
402 | gpio_rcar_config_general_input_output_mode(chip, gpio: offset, output: true); |
403 | return 0; |
404 | } |
405 | |
406 | static const struct gpio_rcar_info gpio_rcar_info_gen1 = { |
407 | .has_outdtsel = false, |
408 | .has_both_edge_trigger = false, |
409 | .has_always_in = false, |
410 | .has_inen = false, |
411 | }; |
412 | |
413 | static const struct gpio_rcar_info gpio_rcar_info_gen2 = { |
414 | .has_outdtsel = true, |
415 | .has_both_edge_trigger = true, |
416 | .has_always_in = false, |
417 | .has_inen = false, |
418 | }; |
419 | |
420 | static const struct gpio_rcar_info gpio_rcar_info_gen3 = { |
421 | .has_outdtsel = true, |
422 | .has_both_edge_trigger = true, |
423 | .has_always_in = true, |
424 | .has_inen = false, |
425 | }; |
426 | |
427 | static const struct gpio_rcar_info gpio_rcar_info_gen4 = { |
428 | .has_outdtsel = true, |
429 | .has_both_edge_trigger = true, |
430 | .has_always_in = true, |
431 | .has_inen = true, |
432 | }; |
433 | |
434 | static const struct of_device_id gpio_rcar_of_table[] = { |
435 | { |
436 | .compatible = "renesas,gpio-r8a779a0" , |
437 | .data = &gpio_rcar_info_gen4, |
438 | }, { |
439 | .compatible = "renesas,rcar-gen1-gpio" , |
440 | .data = &gpio_rcar_info_gen1, |
441 | }, { |
442 | .compatible = "renesas,rcar-gen2-gpio" , |
443 | .data = &gpio_rcar_info_gen2, |
444 | }, { |
445 | .compatible = "renesas,rcar-gen3-gpio" , |
446 | .data = &gpio_rcar_info_gen3, |
447 | }, { |
448 | .compatible = "renesas,rcar-gen4-gpio" , |
449 | .data = &gpio_rcar_info_gen4, |
450 | }, { |
451 | .compatible = "renesas,gpio-rcar" , |
452 | .data = &gpio_rcar_info_gen1, |
453 | }, { |
454 | /* Terminator */ |
455 | }, |
456 | }; |
457 | |
458 | MODULE_DEVICE_TABLE(of, gpio_rcar_of_table); |
459 | |
460 | static int gpio_rcar_parse_dt(struct gpio_rcar_priv *p, unsigned int *npins) |
461 | { |
462 | struct device_node *np = p->dev->of_node; |
463 | const struct gpio_rcar_info *info; |
464 | struct of_phandle_args args; |
465 | int ret; |
466 | |
467 | info = of_device_get_match_data(dev: p->dev); |
468 | p->info = *info; |
469 | |
470 | ret = of_parse_phandle_with_fixed_args(np, list_name: "gpio-ranges" , cell_count: 3, index: 0, out_args: &args); |
471 | *npins = ret == 0 ? args.args[2] : RCAR_MAX_GPIO_PER_BANK; |
472 | |
473 | if (*npins == 0 || *npins > RCAR_MAX_GPIO_PER_BANK) { |
474 | dev_warn(p->dev, "Invalid number of gpio lines %u, using %u\n" , |
475 | *npins, RCAR_MAX_GPIO_PER_BANK); |
476 | *npins = RCAR_MAX_GPIO_PER_BANK; |
477 | } |
478 | |
479 | return 0; |
480 | } |
481 | |
482 | static void gpio_rcar_enable_inputs(struct gpio_rcar_priv *p) |
483 | { |
484 | u32 mask = GENMASK(p->gpio_chip.ngpio - 1, 0); |
485 | |
486 | /* Select "Input Enable" in INEN */ |
487 | if (p->gpio_chip.valid_mask) |
488 | mask &= p->gpio_chip.valid_mask[0]; |
489 | if (mask) |
490 | gpio_rcar_write(p, INEN, value: gpio_rcar_read(p, INEN) | mask); |
491 | } |
492 | |
493 | static int gpio_rcar_probe(struct platform_device *pdev) |
494 | { |
495 | struct gpio_rcar_priv *p; |
496 | struct gpio_chip *gpio_chip; |
497 | struct gpio_irq_chip *girq; |
498 | struct device *dev = &pdev->dev; |
499 | const char *name = dev_name(dev); |
500 | unsigned int npins; |
501 | int ret; |
502 | |
503 | p = devm_kzalloc(dev, size: sizeof(*p), GFP_KERNEL); |
504 | if (!p) |
505 | return -ENOMEM; |
506 | |
507 | p->dev = dev; |
508 | spin_lock_init(&p->lock); |
509 | |
510 | /* Get device configuration from DT node */ |
511 | ret = gpio_rcar_parse_dt(p, npins: &npins); |
512 | if (ret < 0) |
513 | return ret; |
514 | |
515 | platform_set_drvdata(pdev, data: p); |
516 | |
517 | pm_runtime_enable(dev); |
518 | |
519 | ret = platform_get_irq(pdev, 0); |
520 | if (ret < 0) |
521 | goto err0; |
522 | p->irq_parent = ret; |
523 | |
524 | p->base = devm_platform_ioremap_resource(pdev, index: 0); |
525 | if (IS_ERR(ptr: p->base)) { |
526 | ret = PTR_ERR(ptr: p->base); |
527 | goto err0; |
528 | } |
529 | |
530 | gpio_chip = &p->gpio_chip; |
531 | gpio_chip->request = gpio_rcar_request; |
532 | gpio_chip->free = gpio_rcar_free; |
533 | gpio_chip->get_direction = gpio_rcar_get_direction; |
534 | gpio_chip->direction_input = gpio_rcar_direction_input; |
535 | gpio_chip->get = gpio_rcar_get; |
536 | gpio_chip->get_multiple = gpio_rcar_get_multiple; |
537 | gpio_chip->direction_output = gpio_rcar_direction_output; |
538 | gpio_chip->set = gpio_rcar_set; |
539 | gpio_chip->set_multiple = gpio_rcar_set_multiple; |
540 | gpio_chip->label = name; |
541 | gpio_chip->parent = dev; |
542 | gpio_chip->owner = THIS_MODULE; |
543 | gpio_chip->base = -1; |
544 | gpio_chip->ngpio = npins; |
545 | |
546 | girq = &gpio_chip->irq; |
547 | gpio_irq_chip_set_chip(girq, chip: &gpio_rcar_irq_chip); |
548 | /* This will let us handle the parent IRQ in the driver */ |
549 | girq->parent_handler = NULL; |
550 | girq->num_parents = 0; |
551 | girq->parents = NULL; |
552 | girq->default_type = IRQ_TYPE_NONE; |
553 | girq->handler = handle_level_irq; |
554 | |
555 | ret = gpiochip_add_data(gpio_chip, p); |
556 | if (ret) { |
557 | dev_err(dev, "failed to add GPIO controller\n" ); |
558 | goto err0; |
559 | } |
560 | |
561 | irq_domain_set_pm_device(d: gpio_chip->irq.domain, dev); |
562 | ret = devm_request_irq(dev, irq: p->irq_parent, handler: gpio_rcar_irq_handler, |
563 | IRQF_SHARED, devname: name, dev_id: p); |
564 | if (ret) { |
565 | dev_err(dev, "failed to request IRQ\n" ); |
566 | goto err1; |
567 | } |
568 | |
569 | if (p->info.has_inen) { |
570 | pm_runtime_get_sync(dev); |
571 | gpio_rcar_enable_inputs(p); |
572 | pm_runtime_put(dev); |
573 | } |
574 | |
575 | dev_info(dev, "driving %d GPIOs\n" , npins); |
576 | |
577 | return 0; |
578 | |
579 | err1: |
580 | gpiochip_remove(gc: gpio_chip); |
581 | err0: |
582 | pm_runtime_disable(dev); |
583 | return ret; |
584 | } |
585 | |
586 | static void gpio_rcar_remove(struct platform_device *pdev) |
587 | { |
588 | struct gpio_rcar_priv *p = platform_get_drvdata(pdev); |
589 | |
590 | gpiochip_remove(gc: &p->gpio_chip); |
591 | |
592 | pm_runtime_disable(dev: &pdev->dev); |
593 | } |
594 | |
595 | #ifdef CONFIG_PM_SLEEP |
596 | static int gpio_rcar_suspend(struct device *dev) |
597 | { |
598 | struct gpio_rcar_priv *p = dev_get_drvdata(dev); |
599 | |
600 | p->bank_info.iointsel = gpio_rcar_read(p, IOINTSEL); |
601 | p->bank_info.inoutsel = gpio_rcar_read(p, INOUTSEL); |
602 | p->bank_info.outdt = gpio_rcar_read(p, OUTDT); |
603 | p->bank_info.intmsk = gpio_rcar_read(p, INTMSK); |
604 | p->bank_info.posneg = gpio_rcar_read(p, POSNEG); |
605 | p->bank_info.edglevel = gpio_rcar_read(p, EDGLEVEL); |
606 | if (p->info.has_both_edge_trigger) |
607 | p->bank_info.bothedge = gpio_rcar_read(p, BOTHEDGE); |
608 | |
609 | if (atomic_read(v: &p->wakeup_path)) |
610 | device_set_wakeup_path(dev); |
611 | |
612 | return 0; |
613 | } |
614 | |
615 | static int gpio_rcar_resume(struct device *dev) |
616 | { |
617 | struct gpio_rcar_priv *p = dev_get_drvdata(dev); |
618 | unsigned int offset; |
619 | u32 mask; |
620 | |
621 | for (offset = 0; offset < p->gpio_chip.ngpio; offset++) { |
622 | if (!gpiochip_line_is_valid(gc: &p->gpio_chip, offset)) |
623 | continue; |
624 | |
625 | mask = BIT(offset); |
626 | /* I/O pin */ |
627 | if (!(p->bank_info.iointsel & mask)) { |
628 | if (p->bank_info.inoutsel & mask) |
629 | gpio_rcar_direction_output( |
630 | chip: &p->gpio_chip, offset, |
631 | value: !!(p->bank_info.outdt & mask)); |
632 | else |
633 | gpio_rcar_direction_input(chip: &p->gpio_chip, |
634 | offset); |
635 | } else { |
636 | /* Interrupt pin */ |
637 | gpio_rcar_config_interrupt_input_mode( |
638 | p, |
639 | hwirq: offset, |
640 | active_high_rising_edge: !(p->bank_info.posneg & mask), |
641 | level_trigger: !(p->bank_info.edglevel & mask), |
642 | both: !!(p->bank_info.bothedge & mask)); |
643 | |
644 | if (p->bank_info.intmsk & mask) |
645 | gpio_rcar_write(p, MSKCLR, value: mask); |
646 | } |
647 | } |
648 | |
649 | if (p->info.has_inen) |
650 | gpio_rcar_enable_inputs(p); |
651 | |
652 | return 0; |
653 | } |
654 | #endif /* CONFIG_PM_SLEEP*/ |
655 | |
656 | static SIMPLE_DEV_PM_OPS(gpio_rcar_pm_ops, gpio_rcar_suspend, gpio_rcar_resume); |
657 | |
658 | static struct platform_driver gpio_rcar_device_driver = { |
659 | .probe = gpio_rcar_probe, |
660 | .remove_new = gpio_rcar_remove, |
661 | .driver = { |
662 | .name = "gpio_rcar" , |
663 | .pm = &gpio_rcar_pm_ops, |
664 | .of_match_table = gpio_rcar_of_table, |
665 | } |
666 | }; |
667 | |
668 | module_platform_driver(gpio_rcar_device_driver); |
669 | |
670 | MODULE_AUTHOR("Magnus Damm" ); |
671 | MODULE_DESCRIPTION("Renesas R-Car GPIO Driver" ); |
672 | MODULE_LICENSE("GPL v2" ); |
673 | |