aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-05-14 17:14:24 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2012-05-20 11:27:07 -0400
commitcd99758ba3bde64347a8ece381cbae2fb5c745b2 (patch)
treece74c5150978f1cd29861e33e8847bc5dd667ed7 /drivers
parent4492c4c3ff7bbb5fd400f021532643a3493f0723 (diff)
mfd: Convert wm831x to irq_domain
The modern idiom is to use irq_domain to allocate interrupts. This is useful partly to allow further infrastructure to be based on the domains and partly because it makes it much easier to allocate virtual interrupts to devices as we don't need to allocate a contiguous range of interrupt numbers. Convert the wm831x driver over to this infrastructure, using a legacy IRQ mapping if an irq_base is specified in platform data and otherwise using a linear mapping, always registering the interrupts even if they won't ever be used. Only boards which need to use the GPIOs as interrupts should need to use an irq_base. This means that we can't use the MFD irq_base management since the unless we're using an explicit irq_base from platform data we can't rely on a linear mapping of interrupts. Instead we need to map things via the irq_domain - provide a conveniencem function wm831x_irq() to save a small amount of typing when doing so. Looking at this I couldn't clearly see anything the MFD core could do to make this nicer. Since we're not supporting device tree yet there's no meaningful advantage if we don't do this conversion in one, the fact that the interrupt resources are used for repeated IP blocks makes accessor functions for the irq_domain more trouble to do than they're worth. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpio/gpio-wm831x.c6
-rw-r--r--drivers/input/misc/wm831x-on.c2
-rw-r--r--drivers/input/touchscreen/wm831x-ts.c9
-rw-r--r--drivers/mfd/Kconfig2
-rw-r--r--drivers/mfd/wm831x-auxadc.c6
-rw-r--r--drivers/mfd/wm831x-core.c19
-rw-r--r--drivers/mfd/wm831x-irq.c101
-rw-r--r--drivers/power/wm831x_power.c21
-rw-r--r--drivers/regulator/wm831x-dcdc.c24
-rw-r--r--drivers/regulator/wm831x-isink.c4
-rw-r--r--drivers/regulator/wm831x-ldo.c10
-rw-r--r--drivers/rtc/rtc-wm831x.c2
12 files changed, 123 insertions, 83 deletions
diff --git a/drivers/gpio/gpio-wm831x.c b/drivers/gpio/gpio-wm831x.c
index deb949e75ec1..e56a2165641c 100644
--- a/drivers/gpio/gpio-wm831x.c
+++ b/drivers/gpio/gpio-wm831x.c
@@ -102,10 +102,8 @@ static int wm831x_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
102 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); 102 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
103 struct wm831x *wm831x = wm831x_gpio->wm831x; 103 struct wm831x *wm831x = wm831x_gpio->wm831x;
104 104
105 if (!wm831x->irq_base) 105 return irq_create_mapping(wm831x->irq_domain,
106 return -EINVAL; 106 WM831X_IRQ_GPIO_1 + offset);
107
108 return wm831x->irq_base + WM831X_IRQ_GPIO_1 + offset;
109} 107}
110 108
111static int wm831x_gpio_set_debounce(struct gpio_chip *chip, unsigned offset, 109static int wm831x_gpio_set_debounce(struct gpio_chip *chip, unsigned offset,
diff --git a/drivers/input/misc/wm831x-on.c b/drivers/input/misc/wm831x-on.c
index 47f18d6bce46..6790a812a1db 100644
--- a/drivers/input/misc/wm831x-on.c
+++ b/drivers/input/misc/wm831x-on.c
@@ -73,7 +73,7 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev)
73{ 73{
74 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); 74 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
75 struct wm831x_on *wm831x_on; 75 struct wm831x_on *wm831x_on;
76 int irq = platform_get_irq(pdev, 0); 76 int irq = wm831x_irq(wm831x, platform_get_irq(pdev, 0));
77 int ret; 77 int ret;
78 78
79 wm831x_on = kzalloc(sizeof(struct wm831x_on), GFP_KERNEL); 79 wm831x_on = kzalloc(sizeof(struct wm831x_on), GFP_KERNEL);
diff --git a/drivers/input/touchscreen/wm831x-ts.c b/drivers/input/touchscreen/wm831x-ts.c
index 4bc851a9dc3d..e83410721e38 100644
--- a/drivers/input/touchscreen/wm831x-ts.c
+++ b/drivers/input/touchscreen/wm831x-ts.c
@@ -260,15 +260,16 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev)
260 * If we have a direct IRQ use it, otherwise use the interrupt 260 * If we have a direct IRQ use it, otherwise use the interrupt
261 * from the WM831x IRQ controller. 261 * from the WM831x IRQ controller.
262 */ 262 */
263 wm831x_ts->data_irq = wm831x_irq(wm831x,
264 platform_get_irq_byname(pdev,
265 "TCHDATA"));
263 if (pdata && pdata->data_irq) 266 if (pdata && pdata->data_irq)
264 wm831x_ts->data_irq = pdata->data_irq; 267 wm831x_ts->data_irq = pdata->data_irq;
265 else
266 wm831x_ts->data_irq = platform_get_irq_byname(pdev, "TCHDATA");
267 268
269 wm831x_ts->pd_irq = wm831x_irq(wm831x,
270 platform_get_irq_byname(pdev, "TCHPD"));
268 if (pdata && pdata->pd_irq) 271 if (pdata && pdata->pd_irq)
269 wm831x_ts->pd_irq = pdata->pd_irq; 272 wm831x_ts->pd_irq = pdata->pd_irq;
270 else
271 wm831x_ts->pd_irq = platform_get_irq_byname(pdev, "TCHPD");
272 273
273 if (pdata) 274 if (pdata)
274 wm831x_ts->pressure = pdata->pressure; 275 wm831x_ts->pressure = pdata->pressure;
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index a0e1b834af61..8325c44c04c6 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -496,6 +496,7 @@ config MFD_WM831X_I2C
496 select MFD_CORE 496 select MFD_CORE
497 select MFD_WM831X 497 select MFD_WM831X
498 select REGMAP_I2C 498 select REGMAP_I2C
499 select IRQ_DOMAIN
499 depends on I2C=y && GENERIC_HARDIRQS 500 depends on I2C=y && GENERIC_HARDIRQS
500 help 501 help
501 Support for the Wolfson Microelecronics WM831x and WM832x PMICs 502 Support for the Wolfson Microelecronics WM831x and WM832x PMICs
@@ -508,6 +509,7 @@ config MFD_WM831X_SPI
508 select MFD_CORE 509 select MFD_CORE
509 select MFD_WM831X 510 select MFD_WM831X
510 select REGMAP_SPI 511 select REGMAP_SPI
512 select IRQ_DOMAIN
511 depends on SPI_MASTER && GENERIC_HARDIRQS 513 depends on SPI_MASTER && GENERIC_HARDIRQS
512 help 514 help
513 Support for the Wolfson Microelecronics WM831x and WM832x PMICs 515 Support for the Wolfson Microelecronics WM831x and WM832x PMICs
diff --git a/drivers/mfd/wm831x-auxadc.c b/drivers/mfd/wm831x-auxadc.c
index 87210954a066..6ee3018d8653 100644
--- a/drivers/mfd/wm831x-auxadc.c
+++ b/drivers/mfd/wm831x-auxadc.c
@@ -280,11 +280,11 @@ void wm831x_auxadc_init(struct wm831x *wm831x)
280 mutex_init(&wm831x->auxadc_lock); 280 mutex_init(&wm831x->auxadc_lock);
281 INIT_LIST_HEAD(&wm831x->auxadc_pending); 281 INIT_LIST_HEAD(&wm831x->auxadc_pending);
282 282
283 if (wm831x->irq && wm831x->irq_base) { 283 if (wm831x->irq) {
284 wm831x->auxadc_read = wm831x_auxadc_read_irq; 284 wm831x->auxadc_read = wm831x_auxadc_read_irq;
285 285
286 ret = request_threaded_irq(wm831x->irq_base + 286 ret = request_threaded_irq(wm831x_irq(wm831x,
287 WM831X_IRQ_AUXADC_DATA, 287 WM831X_IRQ_AUXADC_DATA),
288 NULL, wm831x_auxadc_irq, 0, 288 NULL, wm831x_auxadc_irq, 0,
289 "auxadc", wm831x); 289 "auxadc", wm831x);
290 if (ret < 0) { 290 if (ret < 0) {
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index 476e4d31a823..946698fd2dc6 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -1813,27 +1813,27 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
1813 case WM8310: 1813 case WM8310:
1814 ret = mfd_add_devices(wm831x->dev, wm831x_num, 1814 ret = mfd_add_devices(wm831x->dev, wm831x_num,
1815 wm8310_devs, ARRAY_SIZE(wm8310_devs), 1815 wm8310_devs, ARRAY_SIZE(wm8310_devs),
1816 NULL, wm831x->irq_base); 1816 NULL, 0);
1817 break; 1817 break;
1818 1818
1819 case WM8311: 1819 case WM8311:
1820 ret = mfd_add_devices(wm831x->dev, wm831x_num, 1820 ret = mfd_add_devices(wm831x->dev, wm831x_num,
1821 wm8311_devs, ARRAY_SIZE(wm8311_devs), 1821 wm8311_devs, ARRAY_SIZE(wm8311_devs),
1822 NULL, wm831x->irq_base); 1822 NULL, 0);
1823 if (!pdata || !pdata->disable_touch) 1823 if (!pdata || !pdata->disable_touch)
1824 mfd_add_devices(wm831x->dev, wm831x_num, 1824 mfd_add_devices(wm831x->dev, wm831x_num,
1825 touch_devs, ARRAY_SIZE(touch_devs), 1825 touch_devs, ARRAY_SIZE(touch_devs),
1826 NULL, wm831x->irq_base); 1826 NULL, 0);
1827 break; 1827 break;
1828 1828
1829 case WM8312: 1829 case WM8312:
1830 ret = mfd_add_devices(wm831x->dev, wm831x_num, 1830 ret = mfd_add_devices(wm831x->dev, wm831x_num,
1831 wm8312_devs, ARRAY_SIZE(wm8312_devs), 1831 wm8312_devs, ARRAY_SIZE(wm8312_devs),
1832 NULL, wm831x->irq_base); 1832 NULL, 0);
1833 if (!pdata || !pdata->disable_touch) 1833 if (!pdata || !pdata->disable_touch)
1834 mfd_add_devices(wm831x->dev, wm831x_num, 1834 mfd_add_devices(wm831x->dev, wm831x_num,
1835 touch_devs, ARRAY_SIZE(touch_devs), 1835 touch_devs, ARRAY_SIZE(touch_devs),
1836 NULL, wm831x->irq_base); 1836 NULL, 0);
1837 break; 1837 break;
1838 1838
1839 case WM8320: 1839 case WM8320:
@@ -1842,7 +1842,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
1842 case WM8326: 1842 case WM8326:
1843 ret = mfd_add_devices(wm831x->dev, wm831x_num, 1843 ret = mfd_add_devices(wm831x->dev, wm831x_num,
1844 wm8320_devs, ARRAY_SIZE(wm8320_devs), 1844 wm8320_devs, ARRAY_SIZE(wm8320_devs),
1845 NULL, wm831x->irq_base); 1845 NULL, 0);
1846 break; 1846 break;
1847 1847
1848 default: 1848 default:
@@ -1867,7 +1867,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
1867 if (ret & WM831X_XTAL_ENA) { 1867 if (ret & WM831X_XTAL_ENA) {
1868 ret = mfd_add_devices(wm831x->dev, wm831x_num, 1868 ret = mfd_add_devices(wm831x->dev, wm831x_num,
1869 rtc_devs, ARRAY_SIZE(rtc_devs), 1869 rtc_devs, ARRAY_SIZE(rtc_devs),
1870 NULL, wm831x->irq_base); 1870 NULL, 0);
1871 if (ret != 0) { 1871 if (ret != 0) {
1872 dev_err(wm831x->dev, "Failed to add RTC: %d\n", ret); 1872 dev_err(wm831x->dev, "Failed to add RTC: %d\n", ret);
1873 goto err_irq; 1873 goto err_irq;
@@ -1880,7 +1880,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
1880 /* Treat errors as non-critical */ 1880 /* Treat errors as non-critical */
1881 ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs, 1881 ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs,
1882 ARRAY_SIZE(backlight_devs), NULL, 1882 ARRAY_SIZE(backlight_devs), NULL,
1883 wm831x->irq_base); 1883 0);
1884 if (ret < 0) 1884 if (ret < 0)
1885 dev_err(wm831x->dev, "Failed to add backlight: %d\n", 1885 dev_err(wm831x->dev, "Failed to add backlight: %d\n",
1886 ret); 1886 ret);
@@ -1909,8 +1909,7 @@ void wm831x_device_exit(struct wm831x *wm831x)
1909{ 1909{
1910 wm831x_otp_exit(wm831x); 1910 wm831x_otp_exit(wm831x);
1911 mfd_remove_devices(wm831x->dev); 1911 mfd_remove_devices(wm831x->dev);
1912 if (wm831x->irq_base) 1912 free_irq(wm831x_irq(wm831x, WM831X_IRQ_AUXADC_DATA), wm831x);
1913 free_irq(wm831x->irq_base + WM831X_IRQ_AUXADC_DATA, wm831x);
1914 wm831x_irq_exit(wm831x); 1913 wm831x_irq_exit(wm831x);
1915} 1914}
1916 1915
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c
index 2be9628074bd..ecc9d6d62fad 100644
--- a/drivers/mfd/wm831x-irq.c
+++ b/drivers/mfd/wm831x-irq.c
@@ -18,6 +18,7 @@
18#include <linux/irq.h> 18#include <linux/irq.h>
19#include <linux/mfd/core.h> 19#include <linux/mfd/core.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/irqdomain.h>
21 22
22#include <linux/mfd/wm831x/core.h> 23#include <linux/mfd/wm831x/core.h>
23#include <linux/mfd/wm831x/pdata.h> 24#include <linux/mfd/wm831x/pdata.h>
@@ -328,7 +329,7 @@ static inline int irq_data_to_status_reg(struct wm831x_irq_data *irq_data)
328static inline struct wm831x_irq_data *irq_to_wm831x_irq(struct wm831x *wm831x, 329static inline struct wm831x_irq_data *irq_to_wm831x_irq(struct wm831x *wm831x,
329 int irq) 330 int irq)
330{ 331{
331 return &wm831x_irqs[irq - wm831x->irq_base]; 332 return &wm831x_irqs[irq];
332} 333}
333 334
334static void wm831x_irq_lock(struct irq_data *data) 335static void wm831x_irq_lock(struct irq_data *data)
@@ -374,7 +375,7 @@ static void wm831x_irq_enable(struct irq_data *data)
374{ 375{
375 struct wm831x *wm831x = irq_data_get_irq_chip_data(data); 376 struct wm831x *wm831x = irq_data_get_irq_chip_data(data);
376 struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, 377 struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x,
377 data->irq); 378 data->hwirq);
378 379
379 wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; 380 wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
380} 381}
@@ -383,7 +384,7 @@ static void wm831x_irq_disable(struct irq_data *data)
383{ 384{
384 struct wm831x *wm831x = irq_data_get_irq_chip_data(data); 385 struct wm831x *wm831x = irq_data_get_irq_chip_data(data);
385 struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, 386 struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x,
386 data->irq); 387 data->hwirq);
387 388
388 wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; 389 wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
389} 390}
@@ -393,7 +394,7 @@ static int wm831x_irq_set_type(struct irq_data *data, unsigned int type)
393 struct wm831x *wm831x = irq_data_get_irq_chip_data(data); 394 struct wm831x *wm831x = irq_data_get_irq_chip_data(data);
394 int irq; 395 int irq;
395 396
396 irq = data->irq - wm831x->irq_base; 397 irq = data->hwirq;
397 398
398 if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) { 399 if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) {
399 /* Ignore internal-only IRQs */ 400 /* Ignore internal-only IRQs */
@@ -469,9 +470,11 @@ static irqreturn_t wm831x_irq_thread(int irq, void *data)
469 * descriptors. 470 * descriptors.
470 */ 471 */
471 if (primary & WM831X_TCHPD_INT) 472 if (primary & WM831X_TCHPD_INT)
472 handle_nested_irq(wm831x->irq_base + WM831X_IRQ_TCHPD); 473 handle_nested_irq(irq_find_mapping(wm831x->irq_domain,
474 WM831X_IRQ_TCHPD));
473 if (primary & WM831X_TCHDATA_INT) 475 if (primary & WM831X_TCHDATA_INT)
474 handle_nested_irq(wm831x->irq_base + WM831X_IRQ_TCHDATA); 476 handle_nested_irq(irq_find_mapping(wm831x->irq_domain,
477 WM831X_IRQ_TCHDATA));
475 primary &= ~(WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT); 478 primary &= ~(WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT);
476 479
477 for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) { 480 for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) {
@@ -507,7 +510,8 @@ static irqreturn_t wm831x_irq_thread(int irq, void *data)
507 } 510 }
508 511
509 if (*status & wm831x_irqs[i].mask) 512 if (*status & wm831x_irqs[i].mask)
510 handle_nested_irq(wm831x->irq_base + i); 513 handle_nested_irq(irq_find_mapping(wm831x->irq_domain,
514 i));
511 515
512 /* Simulate an edge triggered IRQ by polling the input 516 /* Simulate an edge triggered IRQ by polling the input
513 * status. This is sucky but improves interoperability. 517 * status. This is sucky but improves interoperability.
@@ -516,7 +520,8 @@ static irqreturn_t wm831x_irq_thread(int irq, void *data)
516 wm831x->gpio_level[i - WM831X_IRQ_GPIO_1]) { 520 wm831x->gpio_level[i - WM831X_IRQ_GPIO_1]) {
517 ret = wm831x_reg_read(wm831x, WM831X_GPIO_LEVEL); 521 ret = wm831x_reg_read(wm831x, WM831X_GPIO_LEVEL);
518 while (ret & 1 << (i - WM831X_IRQ_GPIO_1)) { 522 while (ret & 1 << (i - WM831X_IRQ_GPIO_1)) {
519 handle_nested_irq(wm831x->irq_base + i); 523 handle_nested_irq(irq_find_mapping(wm831x->irq_domain,
524 i));
520 ret = wm831x_reg_read(wm831x, 525 ret = wm831x_reg_read(wm831x,
521 WM831X_GPIO_LEVEL); 526 WM831X_GPIO_LEVEL);
522 } 527 }
@@ -527,10 +532,34 @@ out:
527 return IRQ_HANDLED; 532 return IRQ_HANDLED;
528} 533}
529 534
535static int wm831x_irq_map(struct irq_domain *h, unsigned int virq,
536 irq_hw_number_t hw)
537{
538 irq_set_chip_data(virq, h->host_data);
539 irq_set_chip_and_handler(virq, &wm831x_irq_chip, handle_edge_irq);
540 irq_set_nested_thread(virq, 1);
541
542 /* ARM needs us to explicitly flag the IRQ as valid
543 * and will set them noprobe when we do so. */
544#ifdef CONFIG_ARM
545 set_irq_flags(virq, IRQF_VALID);
546#else
547 irq_set_noprobe(virq);
548#endif
549
550 return 0;
551}
552
553static struct irq_domain_ops wm831x_irq_domain_ops = {
554 .map = wm831x_irq_map,
555 .xlate = irq_domain_xlate_twocell,
556};
557
530int wm831x_irq_init(struct wm831x *wm831x, int irq) 558int wm831x_irq_init(struct wm831x *wm831x, int irq)
531{ 559{
532 struct wm831x_pdata *pdata = wm831x->dev->platform_data; 560 struct wm831x_pdata *pdata = wm831x->dev->platform_data;
533 int i, cur_irq, ret; 561 struct irq_domain *domain;
562 int i, ret, irq_base;
534 563
535 mutex_init(&wm831x->irq_lock); 564 mutex_init(&wm831x->irq_lock);
536 565
@@ -543,18 +572,33 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
543 } 572 }
544 573
545 /* Try to dynamically allocate IRQs if no base is specified */ 574 /* Try to dynamically allocate IRQs if no base is specified */
546 if (!pdata || !pdata->irq_base) 575 if (pdata && pdata->irq_base) {
547 wm831x->irq_base = -1; 576 irq_base = irq_alloc_descs(pdata->irq_base, 0,
577 WM831X_NUM_IRQS, 0);
578 if (irq_base < 0) {
579 dev_warn(wm831x->dev, "Failed to allocate IRQs: %d\n",
580 irq_base);
581 irq_base = 0;
582 }
583 } else {
584 irq_base = 0;
585 }
586
587 if (irq_base)
588 domain = irq_domain_add_legacy(wm831x->dev->of_node,
589 ARRAY_SIZE(wm831x_irqs),
590 irq_base, 0,
591 &wm831x_irq_domain_ops,
592 wm831x);
548 else 593 else
549 wm831x->irq_base = pdata->irq_base; 594 domain = irq_domain_add_linear(wm831x->dev->of_node,
595 ARRAY_SIZE(wm831x_irqs),
596 &wm831x_irq_domain_ops,
597 wm831x);
550 598
551 wm831x->irq_base = irq_alloc_descs(wm831x->irq_base, 0, 599 if (!domain) {
552 WM831X_NUM_IRQS, 0); 600 dev_warn(wm831x->dev, "Failed to allocate IRQ domain\n");
553 if (wm831x->irq_base < 0) { 601 return -EINVAL;
554 dev_warn(wm831x->dev, "Failed to allocate IRQs: %d\n",
555 wm831x->irq_base);
556 wm831x->irq_base = 0;
557 return 0;
558 } 602 }
559 603
560 if (pdata && pdata->irq_cmos) 604 if (pdata && pdata->irq_cmos)
@@ -566,24 +610,7 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
566 WM831X_IRQ_OD, i); 610 WM831X_IRQ_OD, i);
567 611
568 wm831x->irq = irq; 612 wm831x->irq = irq;
569 613 wm831x->irq_domain = domain;
570 /* Register them with genirq */
571 for (cur_irq = wm831x->irq_base;
572 cur_irq < ARRAY_SIZE(wm831x_irqs) + wm831x->irq_base;
573 cur_irq++) {
574 irq_set_chip_data(cur_irq, wm831x);
575 irq_set_chip_and_handler(cur_irq, &wm831x_irq_chip,
576 handle_edge_irq);
577 irq_set_nested_thread(cur_irq, 1);
578
579 /* ARM needs us to explicitly flag the IRQ as valid
580 * and will set them noprobe when we do so. */
581#ifdef CONFIG_ARM
582 set_irq_flags(cur_irq, IRQF_VALID);
583#else
584 irq_set_noprobe(cur_irq);
585#endif
586 }
587 614
588 if (irq) { 615 if (irq) {
589 /* Try to flag /IRQ as a wake source; there are a number of 616 /* Try to flag /IRQ as a wake source; there are a number of
diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c
index 987332b71d8d..fc1ad9551182 100644
--- a/drivers/power/wm831x_power.c
+++ b/drivers/power/wm831x_power.c
@@ -565,7 +565,7 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev)
565 goto err_usb; 565 goto err_usb;
566 } 566 }
567 567
568 irq = platform_get_irq_byname(pdev, "SYSLO"); 568 irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "SYSLO"));
569 ret = request_threaded_irq(irq, NULL, wm831x_syslo_irq, 569 ret = request_threaded_irq(irq, NULL, wm831x_syslo_irq,
570 IRQF_TRIGGER_RISING, "System power low", 570 IRQF_TRIGGER_RISING, "System power low",
571 power); 571 power);
@@ -575,7 +575,7 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev)
575 goto err_battery; 575 goto err_battery;
576 } 576 }
577 577
578 irq = platform_get_irq_byname(pdev, "PWR SRC"); 578 irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "PWR SRC"));
579 ret = request_threaded_irq(irq, NULL, wm831x_pwr_src_irq, 579 ret = request_threaded_irq(irq, NULL, wm831x_pwr_src_irq,
580 IRQF_TRIGGER_RISING, "Power source", 580 IRQF_TRIGGER_RISING, "Power source",
581 power); 581 power);
@@ -586,7 +586,9 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev)
586 } 586 }
587 587
588 for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) { 588 for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
589 irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]); 589 irq = wm831x_irq(wm831x,
590 platform_get_irq_byname(pdev,
591 wm831x_bat_irqs[i]));
590 ret = request_threaded_irq(irq, NULL, wm831x_bat_irq, 592 ret = request_threaded_irq(irq, NULL, wm831x_bat_irq,
591 IRQF_TRIGGER_RISING, 593 IRQF_TRIGGER_RISING,
592 wm831x_bat_irqs[i], 594 wm831x_bat_irqs[i],
@@ -606,10 +608,10 @@ err_bat_irq:
606 irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]); 608 irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]);
607 free_irq(irq, power); 609 free_irq(irq, power);
608 } 610 }
609 irq = platform_get_irq_byname(pdev, "PWR SRC"); 611 irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "PWR SRC"));
610 free_irq(irq, power); 612 free_irq(irq, power);
611err_syslo: 613err_syslo:
612 irq = platform_get_irq_byname(pdev, "SYSLO"); 614 irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "SYSLO"));
613 free_irq(irq, power); 615 free_irq(irq, power);
614err_battery: 616err_battery:
615 if (power->have_battery) 617 if (power->have_battery)
@@ -626,17 +628,20 @@ err_kmalloc:
626static __devexit int wm831x_power_remove(struct platform_device *pdev) 628static __devexit int wm831x_power_remove(struct platform_device *pdev)
627{ 629{
628 struct wm831x_power *wm831x_power = platform_get_drvdata(pdev); 630 struct wm831x_power *wm831x_power = platform_get_drvdata(pdev);
631 struct wm831x *wm831x = wm831x_power->wm831x;
629 int irq, i; 632 int irq, i;
630 633
631 for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) { 634 for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
632 irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]); 635 irq = wm831x_irq(wm831x,
636 platform_get_irq_byname(pdev,
637 wm831x_bat_irqs[i]));
633 free_irq(irq, wm831x_power); 638 free_irq(irq, wm831x_power);
634 } 639 }
635 640
636 irq = platform_get_irq_byname(pdev, "PWR SRC"); 641 irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "PWR SRC"));
637 free_irq(irq, wm831x_power); 642 free_irq(irq, wm831x_power);
638 643
639 irq = platform_get_irq_byname(pdev, "SYSLO"); 644 irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "SYSLO"));
640 free_irq(irq, wm831x_power); 645 free_irq(irq, wm831x_power);
641 646
642 if (wm831x_power->have_battery) 647 if (wm831x_power->have_battery)
diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c
index ff810e787eac..33b2f20a2932 100644
--- a/drivers/regulator/wm831x-dcdc.c
+++ b/drivers/regulator/wm831x-dcdc.c
@@ -565,7 +565,7 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
565 goto err; 565 goto err;
566 } 566 }
567 567
568 irq = platform_get_irq_byname(pdev, "UV"); 568 irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV"));
569 ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq, 569 ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq,
570 IRQF_TRIGGER_RISING, dcdc->name, dcdc); 570 IRQF_TRIGGER_RISING, dcdc->name, dcdc);
571 if (ret != 0) { 571 if (ret != 0) {
@@ -574,7 +574,7 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
574 goto err_regulator; 574 goto err_regulator;
575 } 575 }
576 576
577 irq = platform_get_irq_byname(pdev, "HC"); 577 irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "HC"));
578 ret = request_threaded_irq(irq, NULL, wm831x_dcdc_oc_irq, 578 ret = request_threaded_irq(irq, NULL, wm831x_dcdc_oc_irq,
579 IRQF_TRIGGER_RISING, dcdc->name, dcdc); 579 IRQF_TRIGGER_RISING, dcdc->name, dcdc);
580 if (ret != 0) { 580 if (ret != 0) {
@@ -588,7 +588,8 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
588 return 0; 588 return 0;
589 589
590err_uv: 590err_uv:
591 free_irq(platform_get_irq_byname(pdev, "UV"), dcdc); 591 free_irq(wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV")),
592 dcdc);
592err_regulator: 593err_regulator:
593 regulator_unregister(dcdc->regulator); 594 regulator_unregister(dcdc->regulator);
594err: 595err:
@@ -600,11 +601,14 @@ err:
600static __devexit int wm831x_buckv_remove(struct platform_device *pdev) 601static __devexit int wm831x_buckv_remove(struct platform_device *pdev)
601{ 602{
602 struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev); 603 struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
604 struct wm831x *wm831x = dcdc->wm831x;
603 605
604 platform_set_drvdata(pdev, NULL); 606 platform_set_drvdata(pdev, NULL);
605 607
606 free_irq(platform_get_irq_byname(pdev, "HC"), dcdc); 608 free_irq(wm831x_irq(wm831x, platform_get_irq_byname(pdev, "HC")),
607 free_irq(platform_get_irq_byname(pdev, "UV"), dcdc); 609 dcdc);
610 free_irq(wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV")),
611 dcdc);
608 regulator_unregister(dcdc->regulator); 612 regulator_unregister(dcdc->regulator);
609 if (dcdc->dvs_gpio) 613 if (dcdc->dvs_gpio)
610 gpio_free(dcdc->dvs_gpio); 614 gpio_free(dcdc->dvs_gpio);
@@ -758,7 +762,7 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
758 goto err; 762 goto err;
759 } 763 }
760 764
761 irq = platform_get_irq_byname(pdev, "UV"); 765 irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV"));
762 ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq, 766 ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq,
763 IRQF_TRIGGER_RISING, dcdc->name, dcdc); 767 IRQF_TRIGGER_RISING, dcdc->name, dcdc);
764 if (ret != 0) { 768 if (ret != 0) {
@@ -783,7 +787,8 @@ static __devexit int wm831x_buckp_remove(struct platform_device *pdev)
783 787
784 platform_set_drvdata(pdev, NULL); 788 platform_set_drvdata(pdev, NULL);
785 789
786 free_irq(platform_get_irq_byname(pdev, "UV"), dcdc); 790 free_irq(wm831x_irq(dcdc->wm831x, platform_get_irq_byname(pdev, "UV")),
791 dcdc);
787 regulator_unregister(dcdc->regulator); 792 regulator_unregister(dcdc->regulator);
788 793
789 return 0; 794 return 0;
@@ -883,7 +888,7 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev)
883 goto err; 888 goto err;
884 } 889 }
885 890
886 irq = platform_get_irq_byname(pdev, "UV"); 891 irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV"));
887 ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq, 892 ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq,
888 IRQF_TRIGGER_RISING, dcdc->name, 893 IRQF_TRIGGER_RISING, dcdc->name,
889 dcdc); 894 dcdc);
@@ -910,7 +915,8 @@ static __devexit int wm831x_boostp_remove(struct platform_device *pdev)
910 915
911 platform_set_drvdata(pdev, NULL); 916 platform_set_drvdata(pdev, NULL);
912 917
913 free_irq(platform_get_irq_byname(pdev, "UV"), dcdc); 918 free_irq(wm831x_irq(dcdc->wm831x, platform_get_irq_byname(pdev, "UV")),
919 dcdc);
914 regulator_unregister(dcdc->regulator); 920 regulator_unregister(dcdc->regulator);
915 kfree(dcdc); 921 kfree(dcdc);
916 922
diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c
index b414e09c5620..1596947f603f 100644
--- a/drivers/regulator/wm831x-isink.c
+++ b/drivers/regulator/wm831x-isink.c
@@ -198,7 +198,7 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev)
198 goto err; 198 goto err;
199 } 199 }
200 200
201 irq = platform_get_irq(pdev, 0); 201 irq = wm831x_irq(wm831x, platform_get_irq(pdev, 0));
202 ret = request_threaded_irq(irq, NULL, wm831x_isink_irq, 202 ret = request_threaded_irq(irq, NULL, wm831x_isink_irq,
203 IRQF_TRIGGER_RISING, isink->name, isink); 203 IRQF_TRIGGER_RISING, isink->name, isink);
204 if (ret != 0) { 204 if (ret != 0) {
@@ -223,7 +223,7 @@ static __devexit int wm831x_isink_remove(struct platform_device *pdev)
223 223
224 platform_set_drvdata(pdev, NULL); 224 platform_set_drvdata(pdev, NULL);
225 225
226 free_irq(platform_get_irq(pdev, 0), isink); 226 free_irq(wm831x_irq(isink->wm831x, platform_get_irq(pdev, 0)), isink);
227 227
228 regulator_unregister(isink->regulator); 228 regulator_unregister(isink->regulator);
229 229
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c
index 641e9f6499d1..b09ba05ada6d 100644
--- a/drivers/regulator/wm831x-ldo.c
+++ b/drivers/regulator/wm831x-ldo.c
@@ -359,7 +359,7 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev)
359 goto err; 359 goto err;
360 } 360 }
361 361
362 irq = platform_get_irq_byname(pdev, "UV"); 362 irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV"));
363 ret = request_threaded_irq(irq, NULL, wm831x_ldo_uv_irq, 363 ret = request_threaded_irq(irq, NULL, wm831x_ldo_uv_irq,
364 IRQF_TRIGGER_RISING, ldo->name, 364 IRQF_TRIGGER_RISING, ldo->name,
365 ldo); 365 ldo);
@@ -385,7 +385,8 @@ static __devexit int wm831x_gp_ldo_remove(struct platform_device *pdev)
385 385
386 platform_set_drvdata(pdev, NULL); 386 platform_set_drvdata(pdev, NULL);
387 387
388 free_irq(platform_get_irq_byname(pdev, "UV"), ldo); 388 free_irq(wm831x_irq(ldo->wm831x,
389 platform_get_irq_byname(pdev, "UV")), ldo);
389 regulator_unregister(ldo->regulator); 390 regulator_unregister(ldo->regulator);
390 391
391 return 0; 392 return 0;
@@ -624,7 +625,7 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev)
624 goto err; 625 goto err;
625 } 626 }
626 627
627 irq = platform_get_irq_byname(pdev, "UV"); 628 irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV"));
628 ret = request_threaded_irq(irq, NULL, wm831x_ldo_uv_irq, 629 ret = request_threaded_irq(irq, NULL, wm831x_ldo_uv_irq,
629 IRQF_TRIGGER_RISING, ldo->name, ldo); 630 IRQF_TRIGGER_RISING, ldo->name, ldo);
630 if (ret != 0) { 631 if (ret != 0) {
@@ -647,7 +648,8 @@ static __devexit int wm831x_aldo_remove(struct platform_device *pdev)
647{ 648{
648 struct wm831x_ldo *ldo = platform_get_drvdata(pdev); 649 struct wm831x_ldo *ldo = platform_get_drvdata(pdev);
649 650
650 free_irq(platform_get_irq_byname(pdev, "UV"), ldo); 651 free_irq(wm831x_irq(ldo->wm831x, platform_get_irq_byname(pdev, "UV")),
652 ldo);
651 regulator_unregister(ldo->regulator); 653 regulator_unregister(ldo->regulator);
652 654
653 return 0; 655 return 0;
diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c
index 3b6e6a67e765..59c6245e0421 100644
--- a/drivers/rtc/rtc-wm831x.c
+++ b/drivers/rtc/rtc-wm831x.c
@@ -396,7 +396,7 @@ static int wm831x_rtc_probe(struct platform_device *pdev)
396{ 396{
397 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); 397 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
398 struct wm831x_rtc *wm831x_rtc; 398 struct wm831x_rtc *wm831x_rtc;
399 int alm_irq = platform_get_irq_byname(pdev, "ALM"); 399 int alm_irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "ALM"));
400 int ret = 0; 400 int ret = 0;
401 401
402 wm831x_rtc = devm_kzalloc(&pdev->dev, sizeof(*wm831x_rtc), GFP_KERNEL); 402 wm831x_rtc = devm_kzalloc(&pdev->dev, sizeof(*wm831x_rtc), GFP_KERNEL);