diff options
author | Oleksandr Dmytryshyn <oleksandr.dmytryshyn@ti.com> | 2013-07-25 09:15:51 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2013-08-20 04:19:38 -0400 |
commit | 74d85e47ab8a7cdeffde6373cf1550bfbd2feaa6 (patch) | |
tree | 8b4321a40163b44f46786b112a5bdffa6dd7bed1 | |
parent | 0aa8c6853121a05bea297f21a6f72dda8e61949f (diff) |
mfd: twl6030-irq: Add interrupt mapping table for the twl6032
The TWL6032 PMIC has different IRQ status bits meaning.
Hence, add interrupt mapping table for the twl6032.
Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@ti.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Acked-by: Graeme Gregory <gg@slimlogic.co.uk>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r-- | drivers/mfd/twl6030-irq.c | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c index e3c54f80b9f0..517eda832f79 100644 --- a/drivers/mfd/twl6030-irq.c +++ b/drivers/mfd/twl6030-irq.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/suspend.h> | 41 | #include <linux/suspend.h> |
42 | #include <linux/of.h> | 42 | #include <linux/of.h> |
43 | #include <linux/irqdomain.h> | 43 | #include <linux/irqdomain.h> |
44 | #include <linux/of_device.h> | ||
44 | 45 | ||
45 | #include "twl-core.h" | 46 | #include "twl-core.h" |
46 | 47 | ||
@@ -84,6 +85,36 @@ static int twl6030_interrupt_mapping[24] = { | |||
84 | CHARGERFAULT_INTR_OFFSET, /* Bit 22 INT_CHRG */ | 85 | CHARGERFAULT_INTR_OFFSET, /* Bit 22 INT_CHRG */ |
85 | RSV_INTR_OFFSET, /* Bit 23 Reserved */ | 86 | RSV_INTR_OFFSET, /* Bit 23 Reserved */ |
86 | }; | 87 | }; |
88 | |||
89 | static int twl6032_interrupt_mapping[24] = { | ||
90 | PWR_INTR_OFFSET, /* Bit 0 PWRON */ | ||
91 | PWR_INTR_OFFSET, /* Bit 1 RPWRON */ | ||
92 | PWR_INTR_OFFSET, /* Bit 2 SYS_VLOW */ | ||
93 | RTC_INTR_OFFSET, /* Bit 3 RTC_ALARM */ | ||
94 | RTC_INTR_OFFSET, /* Bit 4 RTC_PERIOD */ | ||
95 | HOTDIE_INTR_OFFSET, /* Bit 5 HOT_DIE */ | ||
96 | SMPSLDO_INTR_OFFSET, /* Bit 6 VXXX_SHORT */ | ||
97 | PWR_INTR_OFFSET, /* Bit 7 SPDURATION */ | ||
98 | |||
99 | PWR_INTR_OFFSET, /* Bit 8 WATCHDOG */ | ||
100 | BATDETECT_INTR_OFFSET, /* Bit 9 BAT */ | ||
101 | SIMDETECT_INTR_OFFSET, /* Bit 10 SIM */ | ||
102 | MMCDETECT_INTR_OFFSET, /* Bit 11 MMC */ | ||
103 | MADC_INTR_OFFSET, /* Bit 12 GPADC_RT_EOC */ | ||
104 | MADC_INTR_OFFSET, /* Bit 13 GPADC_SW_EOC */ | ||
105 | GASGAUGE_INTR_OFFSET, /* Bit 14 CC_EOC */ | ||
106 | GASGAUGE_INTR_OFFSET, /* Bit 15 CC_AUTOCAL */ | ||
107 | |||
108 | USBOTG_INTR_OFFSET, /* Bit 16 ID_WKUP */ | ||
109 | USBOTG_INTR_OFFSET, /* Bit 17 VBUS_WKUP */ | ||
110 | USBOTG_INTR_OFFSET, /* Bit 18 ID */ | ||
111 | USB_PRES_INTR_OFFSET, /* Bit 19 VBUS */ | ||
112 | CHARGER_INTR_OFFSET, /* Bit 20 CHRG_CTRL */ | ||
113 | CHARGERFAULT_INTR_OFFSET, /* Bit 21 EXT_CHRG */ | ||
114 | CHARGERFAULT_INTR_OFFSET, /* Bit 22 INT_CHRG */ | ||
115 | RSV_INTR_OFFSET, /* Bit 23 Reserved */ | ||
116 | }; | ||
117 | |||
87 | /*----------------------------------------------------------------------*/ | 118 | /*----------------------------------------------------------------------*/ |
88 | 119 | ||
89 | struct twl6030_irq { | 120 | struct twl6030_irq { |
@@ -94,6 +125,7 @@ struct twl6030_irq { | |||
94 | struct notifier_block pm_nb; | 125 | struct notifier_block pm_nb; |
95 | struct irq_chip irq_chip; | 126 | struct irq_chip irq_chip; |
96 | struct irq_domain *irq_domain; | 127 | struct irq_domain *irq_domain; |
128 | const int *irq_mapping_tbl; | ||
97 | }; | 129 | }; |
98 | 130 | ||
99 | static struct twl6030_irq *twl6030_irq; | 131 | static struct twl6030_irq *twl6030_irq; |
@@ -168,7 +200,7 @@ static irqreturn_t twl6030_irq_thread(int irq, void *data) | |||
168 | if (sts.int_sts & 0x1) { | 200 | if (sts.int_sts & 0x1) { |
169 | int module_irq = | 201 | int module_irq = |
170 | irq_find_mapping(pdata->irq_domain, | 202 | irq_find_mapping(pdata->irq_domain, |
171 | twl6030_interrupt_mapping[i]); | 203 | pdata->irq_mapping_tbl[i]); |
172 | if (module_irq) | 204 | if (module_irq) |
173 | handle_nested_irq(module_irq); | 205 | handle_nested_irq(module_irq); |
174 | else | 206 | else |
@@ -347,12 +379,25 @@ static struct irq_domain_ops twl6030_irq_domain_ops = { | |||
347 | .xlate = irq_domain_xlate_onetwocell, | 379 | .xlate = irq_domain_xlate_onetwocell, |
348 | }; | 380 | }; |
349 | 381 | ||
382 | static const struct of_device_id twl6030_of_match[] = { | ||
383 | {.compatible = "ti,twl6030", &twl6030_interrupt_mapping}, | ||
384 | {.compatible = "ti,twl6032", &twl6032_interrupt_mapping}, | ||
385 | { }, | ||
386 | }; | ||
387 | |||
350 | int twl6030_init_irq(struct device *dev, int irq_num) | 388 | int twl6030_init_irq(struct device *dev, int irq_num) |
351 | { | 389 | { |
352 | struct device_node *node = dev->of_node; | 390 | struct device_node *node = dev->of_node; |
353 | int nr_irqs; | 391 | int nr_irqs; |
354 | int status; | 392 | int status; |
355 | u8 mask[3]; | 393 | u8 mask[3]; |
394 | const struct of_device_id *of_id; | ||
395 | |||
396 | of_id = of_match_device(twl6030_of_match, dev); | ||
397 | if (!of_id || !of_id->data) { | ||
398 | dev_err(dev, "Unknown TWL device model\n"); | ||
399 | return -EINVAL; | ||
400 | } | ||
356 | 401 | ||
357 | nr_irqs = TWL6030_NR_IRQS; | 402 | nr_irqs = TWL6030_NR_IRQS; |
358 | 403 | ||
@@ -389,6 +434,7 @@ int twl6030_init_irq(struct device *dev, int irq_num) | |||
389 | 434 | ||
390 | twl6030_irq->pm_nb.notifier_call = twl6030_irq_pm_notifier; | 435 | twl6030_irq->pm_nb.notifier_call = twl6030_irq_pm_notifier; |
391 | atomic_set(&twl6030_irq->wakeirqs, 0); | 436 | atomic_set(&twl6030_irq->wakeirqs, 0); |
437 | twl6030_irq->irq_mapping_tbl = of_id->data; | ||
392 | 438 | ||
393 | twl6030_irq->irq_domain = | 439 | twl6030_irq->irq_domain = |
394 | irq_domain_add_linear(node, nr_irqs, | 440 | irq_domain_add_linear(node, nr_irqs, |