17d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown/*
27d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown * wm831x-irq.c  --  Interrupt controller support for Wolfson WM831x PMICs
37d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown *
47d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown * Copyright 2009 Wolfson Microelectronics PLC.
57d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown *
67d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
77d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown *
87d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown *  This program is free software; you can redistribute  it and/or modify it
97d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown *  under  the terms of  the GNU General  Public License as published by the
107d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown *  Free Software Foundation;  either version 2 of the  License, or (at your
117d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown *  option) any later version.
127d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown *
137d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown */
147d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
157d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown#include <linux/kernel.h>
167d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown#include <linux/module.h>
177d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown#include <linux/i2c.h>
185fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown#include <linux/irq.h>
197d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown#include <linux/mfd/core.h>
207d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown#include <linux/interrupt.h>
21cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown#include <linux/irqdomain.h>
227d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
237d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown#include <linux/mfd/wm831x/core.h>
247d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown#include <linux/mfd/wm831x/pdata.h>
25896060c76bdfd8a45eb33b3dd1a8307fe37f6c04Mark Brown#include <linux/mfd/wm831x/gpio.h>
267d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown#include <linux/mfd/wm831x/irq.h>
277d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
287d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown#include <linux/delay.h>
297d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
307d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brownstruct wm831x_irq_data {
317d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	int primary;
327d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	int reg;
337d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	int mask;
347d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown};
357d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
367d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brownstatic struct wm831x_irq_data wm831x_irqs[] = {
377d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_TEMP_THW] = {
387d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_TEMP_INT,
397d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 1,
407d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_TEMP_THW_EINT,
417d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
427d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_GPIO_1] = {
437d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_GP_INT,
447d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 5,
457d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_GP1_EINT,
467d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
477d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_GPIO_2] = {
487d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_GP_INT,
497d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 5,
507d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_GP2_EINT,
517d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
527d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_GPIO_3] = {
537d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_GP_INT,
547d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 5,
557d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_GP3_EINT,
567d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
577d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_GPIO_4] = {
587d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_GP_INT,
597d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 5,
607d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_GP4_EINT,
617d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
627d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_GPIO_5] = {
637d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_GP_INT,
647d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 5,
657d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_GP5_EINT,
667d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
677d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_GPIO_6] = {
687d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_GP_INT,
697d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 5,
707d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_GP6_EINT,
717d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
727d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_GPIO_7] = {
737d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_GP_INT,
747d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 5,
757d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_GP7_EINT,
767d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
777d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_GPIO_8] = {
787d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_GP_INT,
797d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 5,
807d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_GP8_EINT,
817d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
827d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_GPIO_9] = {
837d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_GP_INT,
847d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 5,
857d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_GP9_EINT,
867d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
877d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_GPIO_10] = {
887d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_GP_INT,
897d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 5,
907d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_GP10_EINT,
917d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
927d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_GPIO_11] = {
937d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_GP_INT,
947d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 5,
957d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_GP11_EINT,
967d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
977d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_GPIO_12] = {
987d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_GP_INT,
997d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 5,
1007d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_GP12_EINT,
1017d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
1027d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_GPIO_13] = {
1037d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_GP_INT,
1047d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 5,
1057d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_GP13_EINT,
1067d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
1077d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_GPIO_14] = {
1087d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_GP_INT,
1097d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 5,
1107d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_GP14_EINT,
1117d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
1127d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_GPIO_15] = {
1137d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_GP_INT,
1147d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 5,
1157d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_GP15_EINT,
1167d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
1177d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_GPIO_16] = {
1187d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_GP_INT,
1197d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 5,
1207d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_GP16_EINT,
1217d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
1227d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_ON] = {
1237d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_ON_PIN_INT,
1247d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 1,
1257d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_ON_PIN_EINT,
1267d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
1277d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_PPM_SYSLO] = {
1287d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_PPM_INT,
1297d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 1,
1307d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_PPM_SYSLO_EINT,
1317d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
1327d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_PPM_PWR_SRC] = {
1337d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_PPM_INT,
1347d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 1,
1357d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_PPM_PWR_SRC_EINT,
1367d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
1377d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_PPM_USB_CURR] = {
1387d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_PPM_INT,
1397d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 1,
1407d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_PPM_USB_CURR_EINT,
1417d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
1427d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_WDOG_TO] = {
1437d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_WDOG_INT,
1447d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 1,
1457d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_WDOG_TO_EINT,
1467d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
1477d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_RTC_PER] = {
1487d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_RTC_INT,
1497d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 1,
1507d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_RTC_PER_EINT,
1517d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
1527d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_RTC_ALM] = {
1537d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_RTC_INT,
1547d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 1,
1557d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_RTC_ALM_EINT,
1567d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
1577d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_CHG_BATT_HOT] = {
1587d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_CHG_INT,
1597d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 2,
1607d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_CHG_BATT_HOT_EINT,
1617d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
1627d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_CHG_BATT_COLD] = {
1637d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_CHG_INT,
1647d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 2,
1657d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_CHG_BATT_COLD_EINT,
1667d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
1677d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_CHG_BATT_FAIL] = {
1687d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_CHG_INT,
1697d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 2,
1707d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_CHG_BATT_FAIL_EINT,
1717d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
1727d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_CHG_OV] = {
1737d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_CHG_INT,
1747d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 2,
1757d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_CHG_OV_EINT,
1767d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
1777d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_CHG_END] = {
1787d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_CHG_INT,
1797d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 2,
1807d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_CHG_END_EINT,
1817d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
1827d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_CHG_TO] = {
1837d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_CHG_INT,
1847d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 2,
1857d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_CHG_TO_EINT,
1867d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
1877d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_CHG_MODE] = {
1887d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_CHG_INT,
1897d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 2,
1907d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_CHG_MODE_EINT,
1917d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
1927d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_CHG_START] = {
1937d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_CHG_INT,
1947d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 2,
1957d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_CHG_START_EINT,
1967d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
1977d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_TCHDATA] = {
1987d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_TCHDATA_INT,
1997d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 1,
2007d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_TCHDATA_EINT,
2017d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
2027d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_TCHPD] = {
2037d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_TCHPD_INT,
2047d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 1,
2057d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_TCHPD_EINT,
2067d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
2077d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_AUXADC_DATA] = {
2087d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_AUXADC_INT,
2097d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 1,
2107d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_AUXADC_DATA_EINT,
2117d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
2127d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_AUXADC_DCOMP1] = {
2137d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_AUXADC_INT,
2147d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 1,
2157d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_AUXADC_DCOMP1_EINT,
2167d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
2177d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_AUXADC_DCOMP2] = {
2187d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_AUXADC_INT,
2197d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 1,
2207d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_AUXADC_DCOMP2_EINT,
2217d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
2227d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_AUXADC_DCOMP3] = {
2237d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_AUXADC_INT,
2247d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 1,
2257d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_AUXADC_DCOMP3_EINT,
2267d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
2277d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_AUXADC_DCOMP4] = {
2287d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_AUXADC_INT,
2297d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 1,
2307d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_AUXADC_DCOMP4_EINT,
2317d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
2327d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_CS1] = {
2337d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_CS_INT,
2347d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 2,
2357d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_CS1_EINT,
2367d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
2377d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_CS2] = {
2387d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_CS_INT,
2397d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 2,
2407d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_CS2_EINT,
2417d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
2427d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_HC_DC1] = {
2437d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_HC_INT,
2447d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 4,
2457d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_HC_DC1_EINT,
2467d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
2477d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_HC_DC2] = {
2487d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_HC_INT,
2497d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 4,
2507d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_HC_DC2_EINT,
2517d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
2527d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_UV_LDO1] = {
2537d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_UV_INT,
2547d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 3,
2557d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_UV_LDO1_EINT,
2567d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
2577d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_UV_LDO2] = {
2587d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_UV_INT,
2597d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 3,
2607d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_UV_LDO2_EINT,
2617d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
2627d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_UV_LDO3] = {
2637d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_UV_INT,
2647d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 3,
2657d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_UV_LDO3_EINT,
2667d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
2677d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_UV_LDO4] = {
2687d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_UV_INT,
2697d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 3,
2707d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_UV_LDO4_EINT,
2717d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
2727d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_UV_LDO5] = {
2737d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_UV_INT,
2747d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 3,
2757d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_UV_LDO5_EINT,
2767d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
2777d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_UV_LDO6] = {
2787d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_UV_INT,
2797d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 3,
2807d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_UV_LDO6_EINT,
2817d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
2827d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_UV_LDO7] = {
2837d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_UV_INT,
2847d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 3,
2857d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_UV_LDO7_EINT,
2867d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
2877d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_UV_LDO8] = {
2887d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_UV_INT,
2897d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 3,
2907d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_UV_LDO8_EINT,
2917d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
2927d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_UV_LDO9] = {
2937d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_UV_INT,
2947d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 3,
2957d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_UV_LDO9_EINT,
2967d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
2977d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_UV_LDO10] = {
2987d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_UV_INT,
2997d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 3,
3007d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_UV_LDO10_EINT,
3017d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
3027d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_UV_DC1] = {
3037d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_UV_INT,
3047d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 4,
3057d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_UV_DC1_EINT,
3067d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
3077d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_UV_DC2] = {
3087d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_UV_INT,
3097d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 4,
3107d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_UV_DC2_EINT,
3117d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
3127d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_UV_DC3] = {
3137d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_UV_INT,
3147d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 4,
3157d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_UV_DC3_EINT,
3167d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
3177d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	[WM831X_IRQ_UV_DC4] = {
3187d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.primary = WM831X_UV_INT,
3197d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.reg = 4,
3207d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		.mask = WM831X_UV_DC4_EINT,
3217d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	},
3227d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown};
3237d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
3247d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brownstatic inline int irq_data_to_status_reg(struct wm831x_irq_data *irq_data)
3257d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown{
3267d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	return WM831X_INTERRUPT_STATUS_1 - 1 + irq_data->reg;
3277d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown}
3287d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
3295fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brownstatic inline struct wm831x_irq_data *irq_to_wm831x_irq(struct wm831x *wm831x,
3305fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown							int irq)
3317d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown{
332cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown	return &wm831x_irqs[irq];
3337d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown}
3347d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
335ba81cd393348b504ecc80d5fc363857f49410d5eMark Brownstatic void wm831x_irq_lock(struct irq_data *data)
3367d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown{
33725a947f805b4132b69f2561589e17a0fe45552b6Mark Brown	struct wm831x *wm831x = irq_data_get_irq_chip_data(data);
3387d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
3397d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	mutex_lock(&wm831x->irq_lock);
3407d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown}
3417d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
342ba81cd393348b504ecc80d5fc363857f49410d5eMark Brownstatic void wm831x_irq_sync_unlock(struct irq_data *data)
3437d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown{
34425a947f805b4132b69f2561589e17a0fe45552b6Mark Brown	struct wm831x *wm831x = irq_data_get_irq_chip_data(data);
3455fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown	int i;
3465fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown
347ca7a71824ac957b1b9d3322656c05aad38d7275cMark Brown	for (i = 0; i < ARRAY_SIZE(wm831x->gpio_update); i++) {
348ca7a71824ac957b1b9d3322656c05aad38d7275cMark Brown		if (wm831x->gpio_update[i]) {
349ca7a71824ac957b1b9d3322656c05aad38d7275cMark Brown			wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + i,
350ca7a71824ac957b1b9d3322656c05aad38d7275cMark Brown					WM831X_GPN_INT_MODE | WM831X_GPN_POL,
351ca7a71824ac957b1b9d3322656c05aad38d7275cMark Brown					wm831x->gpio_update[i]);
352ca7a71824ac957b1b9d3322656c05aad38d7275cMark Brown			wm831x->gpio_update[i] = 0;
353ca7a71824ac957b1b9d3322656c05aad38d7275cMark Brown		}
354ca7a71824ac957b1b9d3322656c05aad38d7275cMark Brown	}
355ca7a71824ac957b1b9d3322656c05aad38d7275cMark Brown
3565fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown	for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) {
3575fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown		/* If there's been a change in the mask write it back
3585fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown		 * to the hardware. */
3595fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown		if (wm831x->irq_masks_cur[i] != wm831x->irq_masks_cache[i]) {
360f624effb7354814d062f149c8a1e2c46a44acb1fMark Brown			dev_dbg(wm831x->dev, "IRQ mask sync: %x = %x\n",
361f624effb7354814d062f149c8a1e2c46a44acb1fMark Brown				WM831X_INTERRUPT_STATUS_1_MASK + i,
362f624effb7354814d062f149c8a1e2c46a44acb1fMark Brown				wm831x->irq_masks_cur[i]);
363f624effb7354814d062f149c8a1e2c46a44acb1fMark Brown
3645fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown			wm831x->irq_masks_cache[i] = wm831x->irq_masks_cur[i];
3655fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown			wm831x_reg_write(wm831x,
3665fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown					 WM831X_INTERRUPT_STATUS_1_MASK + i,
3675fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown					 wm831x->irq_masks_cur[i]);
3685fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown		}
3697d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	}
3707d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
3717d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	mutex_unlock(&wm831x->irq_lock);
3727d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown}
3737d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
374f624effb7354814d062f149c8a1e2c46a44acb1fMark Brownstatic void wm831x_irq_enable(struct irq_data *data)
3757d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown{
37625a947f805b4132b69f2561589e17a0fe45552b6Mark Brown	struct wm831x *wm831x = irq_data_get_irq_chip_data(data);
377ba81cd393348b504ecc80d5fc363857f49410d5eMark Brown	struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x,
378cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown							     data->hwirq);
3797d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
3805fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown	wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
3817d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown}
3827d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
383f624effb7354814d062f149c8a1e2c46a44acb1fMark Brownstatic void wm831x_irq_disable(struct irq_data *data)
3847d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown{
38525a947f805b4132b69f2561589e17a0fe45552b6Mark Brown	struct wm831x *wm831x = irq_data_get_irq_chip_data(data);
386ba81cd393348b504ecc80d5fc363857f49410d5eMark Brown	struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x,
387cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown							     data->hwirq);
3885fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown
3895fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown	wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
3907d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown}
3917d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
392ba81cd393348b504ecc80d5fc363857f49410d5eMark Brownstatic int wm831x_irq_set_type(struct irq_data *data, unsigned int type)
393896060c76bdfd8a45eb33b3dd1a8307fe37f6c04Mark Brown{
39425a947f805b4132b69f2561589e17a0fe45552b6Mark Brown	struct wm831x *wm831x = irq_data_get_irq_chip_data(data);
395ca7a71824ac957b1b9d3322656c05aad38d7275cMark Brown	int irq;
396896060c76bdfd8a45eb33b3dd1a8307fe37f6c04Mark Brown
397cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown	irq = data->hwirq;
398896060c76bdfd8a45eb33b3dd1a8307fe37f6c04Mark Brown
399c9d66d3515bbb0ad8062721487de7ade02d2b936Mark Brown	if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) {
400c9d66d3515bbb0ad8062721487de7ade02d2b936Mark Brown		/* Ignore internal-only IRQs */
401c9d66d3515bbb0ad8062721487de7ade02d2b936Mark Brown		if (irq >= 0 && irq < WM831X_NUM_IRQS)
402c9d66d3515bbb0ad8062721487de7ade02d2b936Mark Brown			return 0;
403c9d66d3515bbb0ad8062721487de7ade02d2b936Mark Brown		else
404c9d66d3515bbb0ad8062721487de7ade02d2b936Mark Brown			return -EINVAL;
405c9d66d3515bbb0ad8062721487de7ade02d2b936Mark Brown	}
406896060c76bdfd8a45eb33b3dd1a8307fe37f6c04Mark Brown
40708256712a2705f3ced3e54c3728932c9c39b58adDimitris Papastamos	/* Rebase the IRQ into the GPIO range so we've got a sensible array
40808256712a2705f3ced3e54c3728932c9c39b58adDimitris Papastamos	 * index.
40908256712a2705f3ced3e54c3728932c9c39b58adDimitris Papastamos	 */
41008256712a2705f3ced3e54c3728932c9c39b58adDimitris Papastamos	irq -= WM831X_IRQ_GPIO_1;
41108256712a2705f3ced3e54c3728932c9c39b58adDimitris Papastamos
412ca7a71824ac957b1b9d3322656c05aad38d7275cMark Brown	/* We set the high bit to flag that we need an update; don't
413ca7a71824ac957b1b9d3322656c05aad38d7275cMark Brown	 * do the update here as we can be called with the bus lock
414ca7a71824ac957b1b9d3322656c05aad38d7275cMark Brown	 * held.
415ca7a71824ac957b1b9d3322656c05aad38d7275cMark Brown	 */
4161fe17a24e2fe0a9554d19a4249eb2d80050ecb8cMark Brown	wm831x->gpio_level_low[irq] = false;
4171fe17a24e2fe0a9554d19a4249eb2d80050ecb8cMark Brown	wm831x->gpio_level_high[irq] = false;
418896060c76bdfd8a45eb33b3dd1a8307fe37f6c04Mark Brown	switch (type) {
419896060c76bdfd8a45eb33b3dd1a8307fe37f6c04Mark Brown	case IRQ_TYPE_EDGE_BOTH:
420ca7a71824ac957b1b9d3322656c05aad38d7275cMark Brown		wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_INT_MODE;
421896060c76bdfd8a45eb33b3dd1a8307fe37f6c04Mark Brown		break;
422896060c76bdfd8a45eb33b3dd1a8307fe37f6c04Mark Brown	case IRQ_TYPE_EDGE_RISING:
423ca7a71824ac957b1b9d3322656c05aad38d7275cMark Brown		wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL;
424896060c76bdfd8a45eb33b3dd1a8307fe37f6c04Mark Brown		break;
425896060c76bdfd8a45eb33b3dd1a8307fe37f6c04Mark Brown	case IRQ_TYPE_EDGE_FALLING:
426ca7a71824ac957b1b9d3322656c05aad38d7275cMark Brown		wm831x->gpio_update[irq] = 0x10000;
4277583a213ec3bde3082547ee37ad96214513bc1cbMark Brown		break;
4287583a213ec3bde3082547ee37ad96214513bc1cbMark Brown	case IRQ_TYPE_LEVEL_HIGH:
4297583a213ec3bde3082547ee37ad96214513bc1cbMark Brown		wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL;
4301fe17a24e2fe0a9554d19a4249eb2d80050ecb8cMark Brown		wm831x->gpio_level_high[irq] = true;
4311fe17a24e2fe0a9554d19a4249eb2d80050ecb8cMark Brown		break;
4321fe17a24e2fe0a9554d19a4249eb2d80050ecb8cMark Brown	case IRQ_TYPE_LEVEL_LOW:
4331fe17a24e2fe0a9554d19a4249eb2d80050ecb8cMark Brown		wm831x->gpio_update[irq] = 0x10000;
4341fe17a24e2fe0a9554d19a4249eb2d80050ecb8cMark Brown		wm831x->gpio_level_low[irq] = true;
435896060c76bdfd8a45eb33b3dd1a8307fe37f6c04Mark Brown		break;
436896060c76bdfd8a45eb33b3dd1a8307fe37f6c04Mark Brown	default:
437896060c76bdfd8a45eb33b3dd1a8307fe37f6c04Mark Brown		return -EINVAL;
438896060c76bdfd8a45eb33b3dd1a8307fe37f6c04Mark Brown	}
439896060c76bdfd8a45eb33b3dd1a8307fe37f6c04Mark Brown
440ca7a71824ac957b1b9d3322656c05aad38d7275cMark Brown	return 0;
441896060c76bdfd8a45eb33b3dd1a8307fe37f6c04Mark Brown}
442896060c76bdfd8a45eb33b3dd1a8307fe37f6c04Mark Brown
4435fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brownstatic struct irq_chip wm831x_irq_chip = {
444ba81cd393348b504ecc80d5fc363857f49410d5eMark Brown	.name			= "wm831x",
445ba81cd393348b504ecc80d5fc363857f49410d5eMark Brown	.irq_bus_lock		= wm831x_irq_lock,
446ba81cd393348b504ecc80d5fc363857f49410d5eMark Brown	.irq_bus_sync_unlock	= wm831x_irq_sync_unlock,
447f624effb7354814d062f149c8a1e2c46a44acb1fMark Brown	.irq_disable		= wm831x_irq_disable,
448f624effb7354814d062f149c8a1e2c46a44acb1fMark Brown	.irq_enable		= wm831x_irq_enable,
449ba81cd393348b504ecc80d5fc363857f49410d5eMark Brown	.irq_set_type		= wm831x_irq_set_type,
4505fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown};
4515fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown
4525fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown/* The processing of the primary interrupt occurs in a thread so that
4535fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown * we can interact with the device over I2C or SPI. */
4545fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brownstatic irqreturn_t wm831x_irq_thread(int irq, void *data)
4557d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown{
4565fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown	struct wm831x *wm831x = data;
4577d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	unsigned int i;
4587583a213ec3bde3082547ee37ad96214513bc1cbMark Brown	int primary, status_addr, ret;
4595fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown	int status_regs[WM831X_NUM_IRQ_REGS] = { 0 };
4605fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown	int read[WM831X_NUM_IRQ_REGS] = { 0 };
4617d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	int *status;
4627d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
4637d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	primary = wm831x_reg_read(wm831x, WM831X_SYSTEM_INTERRUPTS);
4647d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	if (primary < 0) {
4657d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		dev_err(wm831x->dev, "Failed to read system interrupt: %d\n",
4667d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown			primary);
4677d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		goto out;
4687d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	}
4697d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
4708546bd4af1251d17d16b0ef682d84fd23c8beacaMark Brown	/* The touch interrupts are visible in the primary register as
4718546bd4af1251d17d16b0ef682d84fd23c8beacaMark Brown	 * an optimisation; open code this to avoid complicating the
4728546bd4af1251d17d16b0ef682d84fd23c8beacaMark Brown	 * main handling loop and so we can also skip iterating the
4738546bd4af1251d17d16b0ef682d84fd23c8beacaMark Brown	 * descriptors.
4748546bd4af1251d17d16b0ef682d84fd23c8beacaMark Brown	 */
4758546bd4af1251d17d16b0ef682d84fd23c8beacaMark Brown	if (primary & WM831X_TCHPD_INT)
476cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown		handle_nested_irq(irq_find_mapping(wm831x->irq_domain,
477cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown						   WM831X_IRQ_TCHPD));
4788546bd4af1251d17d16b0ef682d84fd23c8beacaMark Brown	if (primary & WM831X_TCHDATA_INT)
479cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown		handle_nested_irq(irq_find_mapping(wm831x->irq_domain,
480cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown						   WM831X_IRQ_TCHDATA));
481953c7d025d97916e56fd6f1bd347e1c19fd7d5f5Mark Brown	primary &= ~(WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT);
4828546bd4af1251d17d16b0ef682d84fd23c8beacaMark Brown
4837d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) {
4847d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		int offset = wm831x_irqs[i].reg - 1;
4857d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
4867d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		if (!(primary & wm831x_irqs[i].primary))
4877d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown			continue;
4887d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
4897d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		status = &status_regs[offset];
4907d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
4917d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		/* Hopefully there should only be one register to read
4927d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		 * each time otherwise we ought to do a block read. */
4937d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		if (!read[offset]) {
49488c939770db375244b00ba92e901fa92677a7164Mark Brown			status_addr = irq_data_to_status_reg(&wm831x_irqs[i]);
49588c939770db375244b00ba92e901fa92677a7164Mark Brown
49688c939770db375244b00ba92e901fa92677a7164Mark Brown			*status = wm831x_reg_read(wm831x, status_addr);
4977d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown			if (*status < 0) {
4987d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown				dev_err(wm831x->dev,
4997d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown					"Failed to read IRQ status: %d\n",
5007d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown					*status);
5015fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown				goto out;
5027d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown			}
5037d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
5047d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown			read[offset] = 1;
50588c939770db375244b00ba92e901fa92677a7164Mark Brown
50688c939770db375244b00ba92e901fa92677a7164Mark Brown			/* Ignore any bits that we don't think are masked */
50788c939770db375244b00ba92e901fa92677a7164Mark Brown			*status &= ~wm831x->irq_masks_cur[offset];
50888c939770db375244b00ba92e901fa92677a7164Mark Brown
50988c939770db375244b00ba92e901fa92677a7164Mark Brown			/* Acknowledge now so we don't miss
51088c939770db375244b00ba92e901fa92677a7164Mark Brown			 * notifications while we handle.
51188c939770db375244b00ba92e901fa92677a7164Mark Brown			 */
51288c939770db375244b00ba92e901fa92677a7164Mark Brown			wm831x_reg_write(wm831x, status_addr, *status);
5137d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		}
5147d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
51588c939770db375244b00ba92e901fa92677a7164Mark Brown		if (*status & wm831x_irqs[i].mask)
516cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown			handle_nested_irq(irq_find_mapping(wm831x->irq_domain,
517cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown							   i));
5187583a213ec3bde3082547ee37ad96214513bc1cbMark Brown
5197583a213ec3bde3082547ee37ad96214513bc1cbMark Brown		/* Simulate an edge triggered IRQ by polling the input
5207583a213ec3bde3082547ee37ad96214513bc1cbMark Brown		 * status.  This is sucky but improves interoperability.
5217583a213ec3bde3082547ee37ad96214513bc1cbMark Brown		 */
5227583a213ec3bde3082547ee37ad96214513bc1cbMark Brown		if (primary == WM831X_GP_INT &&
5231fe17a24e2fe0a9554d19a4249eb2d80050ecb8cMark Brown		    wm831x->gpio_level_high[i - WM831X_IRQ_GPIO_1]) {
5247583a213ec3bde3082547ee37ad96214513bc1cbMark Brown			ret = wm831x_reg_read(wm831x, WM831X_GPIO_LEVEL);
5257583a213ec3bde3082547ee37ad96214513bc1cbMark Brown			while (ret & 1 << (i - WM831X_IRQ_GPIO_1)) {
5261fe17a24e2fe0a9554d19a4249eb2d80050ecb8cMark Brown				handle_nested_irq(irq_find_mapping(wm831x->irq_domain,
5271fe17a24e2fe0a9554d19a4249eb2d80050ecb8cMark Brown								   i));
5281fe17a24e2fe0a9554d19a4249eb2d80050ecb8cMark Brown				ret = wm831x_reg_read(wm831x,
5291fe17a24e2fe0a9554d19a4249eb2d80050ecb8cMark Brown						      WM831X_GPIO_LEVEL);
5301fe17a24e2fe0a9554d19a4249eb2d80050ecb8cMark Brown			}
5311fe17a24e2fe0a9554d19a4249eb2d80050ecb8cMark Brown		}
5321fe17a24e2fe0a9554d19a4249eb2d80050ecb8cMark Brown
5331fe17a24e2fe0a9554d19a4249eb2d80050ecb8cMark Brown		if (primary == WM831X_GP_INT &&
5341fe17a24e2fe0a9554d19a4249eb2d80050ecb8cMark Brown		    wm831x->gpio_level_low[i - WM831X_IRQ_GPIO_1]) {
5351fe17a24e2fe0a9554d19a4249eb2d80050ecb8cMark Brown			ret = wm831x_reg_read(wm831x, WM831X_GPIO_LEVEL);
5361fe17a24e2fe0a9554d19a4249eb2d80050ecb8cMark Brown			while (!(ret & 1 << (i - WM831X_IRQ_GPIO_1))) {
537cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown				handle_nested_irq(irq_find_mapping(wm831x->irq_domain,
538cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown								   i));
5397583a213ec3bde3082547ee37ad96214513bc1cbMark Brown				ret = wm831x_reg_read(wm831x,
5407583a213ec3bde3082547ee37ad96214513bc1cbMark Brown						      WM831X_GPIO_LEVEL);
5417583a213ec3bde3082547ee37ad96214513bc1cbMark Brown			}
5427583a213ec3bde3082547ee37ad96214513bc1cbMark Brown		}
5437d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	}
5447d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
5457d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brownout:
5467d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	return IRQ_HANDLED;
5477d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown}
5487d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
549cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brownstatic int wm831x_irq_map(struct irq_domain *h, unsigned int virq,
550cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown			  irq_hw_number_t hw)
551cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown{
552cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown	irq_set_chip_data(virq, h->host_data);
553cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown	irq_set_chip_and_handler(virq, &wm831x_irq_chip, handle_edge_irq);
554cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown	irq_set_nested_thread(virq, 1);
555cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown
556cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown	/* ARM needs us to explicitly flag the IRQ as valid
557cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown	 * and will set them noprobe when we do so. */
558cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown#ifdef CONFIG_ARM
559cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown	set_irq_flags(virq, IRQF_VALID);
560cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown#else
561cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown	irq_set_noprobe(virq);
562cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown#endif
563cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown
564cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown	return 0;
565cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown}
566cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown
567cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brownstatic struct irq_domain_ops wm831x_irq_domain_ops = {
568cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown	.map	= wm831x_irq_map,
569cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown	.xlate	= irq_domain_xlate_twocell,
570cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown};
571cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown
5727d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brownint wm831x_irq_init(struct wm831x *wm831x, int irq)
5737d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown{
574334a41ce9b753ec615e8c6c50ee07d6197190610Jingoo Han	struct wm831x_pdata *pdata = dev_get_platdata(wm831x->dev);
575cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown	struct irq_domain *domain;
576cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown	int i, ret, irq_base;
5777d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
57814f572fa38c55fbe369127b808a4a79b0bbec367Mark Brown	mutex_init(&wm831x->irq_lock);
57914f572fa38c55fbe369127b808a4a79b0bbec367Mark Brown
5800d7e0e399d7fcd5ddc3313a1aa2135fab3226d8fMark Brown	/* Mask the individual interrupt sources */
5810d7e0e399d7fcd5ddc3313a1aa2135fab3226d8fMark Brown	for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) {
5820d7e0e399d7fcd5ddc3313a1aa2135fab3226d8fMark Brown		wm831x->irq_masks_cur[i] = 0xffff;
5830d7e0e399d7fcd5ddc3313a1aa2135fab3226d8fMark Brown		wm831x->irq_masks_cache[i] = 0xffff;
5840d7e0e399d7fcd5ddc3313a1aa2135fab3226d8fMark Brown		wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1_MASK + i,
5850d7e0e399d7fcd5ddc3313a1aa2135fab3226d8fMark Brown				 0xffff);
5860d7e0e399d7fcd5ddc3313a1aa2135fab3226d8fMark Brown	}
5870d7e0e399d7fcd5ddc3313a1aa2135fab3226d8fMark Brown
5885c05a8d1f0105ada3cb04be5b70686fc6b272619Mark Brown	/* Try to dynamically allocate IRQs if no base is specified */
589cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown	if (pdata && pdata->irq_base) {
590cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown		irq_base = irq_alloc_descs(pdata->irq_base, 0,
591cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown					   WM831X_NUM_IRQS, 0);
592cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown		if (irq_base < 0) {
593cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown			dev_warn(wm831x->dev, "Failed to allocate IRQs: %d\n",
594cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown				 irq_base);
595cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown			irq_base = 0;
596cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown		}
597cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown	} else {
598cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown		irq_base = 0;
599cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown	}
600cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown
601cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown	if (irq_base)
602cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown		domain = irq_domain_add_legacy(wm831x->dev->of_node,
603cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown					       ARRAY_SIZE(wm831x_irqs),
604cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown					       irq_base, 0,
605cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown					       &wm831x_irq_domain_ops,
606cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown					       wm831x);
6075c05a8d1f0105ada3cb04be5b70686fc6b272619Mark Brown	else
608cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown		domain = irq_domain_add_linear(wm831x->dev->of_node,
609cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown					       ARRAY_SIZE(wm831x_irqs),
610cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown					       &wm831x_irq_domain_ops,
611cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown					       wm831x);
6125c05a8d1f0105ada3cb04be5b70686fc6b272619Mark Brown
613cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown	if (!domain) {
614cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown		dev_warn(wm831x->dev, "Failed to allocate IRQ domain\n");
615cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown		return -EINVAL;
6167d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	}
6177d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
6185c05a8d1f0105ada3cb04be5b70686fc6b272619Mark Brown	if (pdata && pdata->irq_cmos)
619b103e0b3c52e6edb4839ccc961cf335ca6b88918Mark Brown		i = 0;
620b103e0b3c52e6edb4839ccc961cf335ca6b88918Mark Brown	else
621b103e0b3c52e6edb4839ccc961cf335ca6b88918Mark Brown		i = WM831X_IRQ_OD;
622b103e0b3c52e6edb4839ccc961cf335ca6b88918Mark Brown
623b103e0b3c52e6edb4839ccc961cf335ca6b88918Mark Brown	wm831x_set_bits(wm831x, WM831X_IRQ_CONFIG,
624b103e0b3c52e6edb4839ccc961cf335ca6b88918Mark Brown			WM831X_IRQ_OD, i);
625b103e0b3c52e6edb4839ccc961cf335ca6b88918Mark Brown
6267d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	wm831x->irq = irq;
627cd99758ba3bde64347a8ece381cbae2fb5c745b2Mark Brown	wm831x->irq_domain = domain;
6287d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
629bc86fcee373f27bffc9ed0c0a734e40ec084aef5Mark Brown	if (irq) {
6304492c4c3ff7bbb5fd400f021532643a3493f0723Mark Brown		/* Try to flag /IRQ as a wake source; there are a number of
6314492c4c3ff7bbb5fd400f021532643a3493f0723Mark Brown		 * unconditional wake sources in the PMIC so this isn't
6324492c4c3ff7bbb5fd400f021532643a3493f0723Mark Brown		 * conditional but we don't actually care *too* much if it
6334492c4c3ff7bbb5fd400f021532643a3493f0723Mark Brown		 * fails.
6344492c4c3ff7bbb5fd400f021532643a3493f0723Mark Brown		 */
6354492c4c3ff7bbb5fd400f021532643a3493f0723Mark Brown		ret = enable_irq_wake(irq);
6364492c4c3ff7bbb5fd400f021532643a3493f0723Mark Brown		if (ret != 0) {
6374492c4c3ff7bbb5fd400f021532643a3493f0723Mark Brown			dev_warn(wm831x->dev,
6384492c4c3ff7bbb5fd400f021532643a3493f0723Mark Brown				 "Can't enable IRQ as wake source: %d\n",
6394492c4c3ff7bbb5fd400f021532643a3493f0723Mark Brown				 ret);
6404492c4c3ff7bbb5fd400f021532643a3493f0723Mark Brown		}
6414492c4c3ff7bbb5fd400f021532643a3493f0723Mark Brown
642bc86fcee373f27bffc9ed0c0a734e40ec084aef5Mark Brown		ret = request_threaded_irq(irq, NULL, wm831x_irq_thread,
643bc86fcee373f27bffc9ed0c0a734e40ec084aef5Mark Brown					   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
644bc86fcee373f27bffc9ed0c0a734e40ec084aef5Mark Brown					   "wm831x", wm831x);
645bc86fcee373f27bffc9ed0c0a734e40ec084aef5Mark Brown		if (ret != 0) {
646bc86fcee373f27bffc9ed0c0a734e40ec084aef5Mark Brown			dev_err(wm831x->dev, "Failed to request IRQ %d: %d\n",
647bc86fcee373f27bffc9ed0c0a734e40ec084aef5Mark Brown				irq, ret);
648bc86fcee373f27bffc9ed0c0a734e40ec084aef5Mark Brown			return ret;
649bc86fcee373f27bffc9ed0c0a734e40ec084aef5Mark Brown		}
650bc86fcee373f27bffc9ed0c0a734e40ec084aef5Mark Brown	} else {
651bc86fcee373f27bffc9ed0c0a734e40ec084aef5Mark Brown		dev_warn(wm831x->dev,
652bc86fcee373f27bffc9ed0c0a734e40ec084aef5Mark Brown			 "No interrupt specified - functionality limited\n");
6537d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	}
6547d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
6555fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown	/* Enable top level interrupts, we mask at secondary level */
6565fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown	wm831x_reg_write(wm831x, WM831X_SYSTEM_INTERRUPTS_MASK, 0);
6575fb4d38b19d95a5f980f0a10adba798f5b92128cMark Brown
6587d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	return 0;
6597d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown}
6607d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown
6617d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brownvoid wm831x_irq_exit(struct wm831x *wm831x)
6627d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown{
6637d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown	if (wm831x->irq)
6647d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown		free_irq(wm831x->irq, wm831x);
6657d4d0a3e7343e3190afaa17253073db58e3d9bffMark Brown}
666