[PATCH 9/9] TWL4030: convert early interrupt mask/clear funcs to use array

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Mask/clear TWL module IMRs/ISRs by iterating through arrays rather than
using a block of cut-and-pasted commands.  Removes 632 bytes of bloat.

Signed-off-by: Paul Walmsley <paul@xxxxxxxxx>
---

 drivers/i2c/chips/twl4030-core.c |  218 ++++++++++++++++++++++++--------------
 1 files changed, 137 insertions(+), 81 deletions(-)

diff --git a/drivers/i2c/chips/twl4030-core.c b/drivers/i2c/chips/twl4030-core.c
index 5855f5f..47d547d 100644
--- a/drivers/i2c/chips/twl4030-core.c
+++ b/drivers/i2c/chips/twl4030-core.c
@@ -153,6 +153,130 @@
 /* on I2C-1 for 2430SDP */
 #define CONFIG_I2C_TWL4030_ID		1
 
+/**
+ * struct twl4030_mod_iregs - TWL module IMR/ISR regs to mask/clear at init
+ * @mod_no: TWL4030 module number (e.g., TWL4030_MODULE_GPIO)
+ * @reg_cnt: number of IMR/ISR regs
+ * @imrs: pointer to array of TWL module interrupt mask register indices
+ * @isrs: pointer to array of TWL module interrupt status register indices
+ *
+ * Ties together TWL4030 modules and lists of IMR/ISR registers to mask/clear
+ * during twl_init_irq().
+ */
+struct twl4030_mod_iregs {
+	const u8 mod_no;
+	const u8 reg_cnt;
+	const u8 *imrs;
+	const u8 *isrs;
+};
+
+/* TWL4030 INT module interrupt mask registers */
+static const u8 __initconst twl4030_int_imr_regs[] = {
+	TWL4030_INT_PWR_IMR1,
+	TWL4030_INT_PWR_IMR2,
+};
+
+/* TWL4030 INT module interrupt status registers */
+static const u8 __initconst twl4030_int_isr_regs[] = {
+	TWL4030_INT_PWR_ISR1,
+	TWL4030_INT_PWR_ISR2,
+};
+
+/* TWL4030 INTERRUPTS module interrupt mask registers */
+static const u8 __initconst twl4030_interrupts_imr_regs[] = {
+	TWL4030_INTERRUPTS_BCIIMR1A,
+	TWL4030_INTERRUPTS_BCIIMR1B,
+	TWL4030_INTERRUPTS_BCIIMR2A,
+	TWL4030_INTERRUPTS_BCIIMR2B,
+};
+
+/* TWL4030 INTERRUPTS module interrupt status registers */
+static const u8 __initconst twl4030_interrupts_isr_regs[] = {
+	TWL4030_INTERRUPTS_BCIISR1A,
+	TWL4030_INTERRUPTS_BCIISR1B,
+	TWL4030_INTERRUPTS_BCIISR2A,
+	TWL4030_INTERRUPTS_BCIISR2B,
+};
+
+/* TWL4030 MADC module interrupt mask registers */
+static const u8 __initconst twl4030_madc_imr_regs[] = {
+	TWL4030_MADC_IMR1,
+	TWL4030_MADC_IMR2,
+};
+
+/* TWL4030 MADC module interrupt status registers */
+static const u8 __initconst twl4030_madc_isr_regs[] = {
+	TWL4030_MADC_ISR1,
+	TWL4030_MADC_ISR2,
+};
+
+/* TWL4030 keypad module interrupt mask registers */
+static const u8 __initconst twl4030_keypad_imr_regs[] = {
+	TWL4030_KEYPAD_KEYP_IMR1,
+	TWL4030_KEYPAD_KEYP_IMR2,
+};
+
+/* TWL4030 keypad module interrupt status registers */
+static const u8 __initconst twl4030_keypad_isr_regs[] = {
+	TWL4030_KEYPAD_KEYP_ISR1,
+	TWL4030_KEYPAD_KEYP_ISR2,
+};
+
+/* TWL4030 GPIO module interrupt mask registers */
+static const u8 __initconst twl4030_gpio_imr_regs[] = {
+	REG_GPIO_IMR1A,
+	REG_GPIO_IMR1B,
+	REG_GPIO_IMR2A,
+	REG_GPIO_IMR2B,
+	REG_GPIO_IMR3A,
+	REG_GPIO_IMR3B,
+};
+
+/* TWL4030 GPIO module interrupt status registers */
+static const u8 __initconst twl4030_gpio_isr_regs[] = {
+	REG_GPIO_ISR1A,
+	REG_GPIO_ISR1B,
+	REG_GPIO_ISR2A,
+	REG_GPIO_ISR2B,
+	REG_GPIO_ISR3A,
+	REG_GPIO_ISR3B,
+};
+
+/* TWL4030 modules that have IMR/ISR registers that must be masked/cleared */
+static const struct twl4030_mod_iregs __initconst twl4030_mod_regs[] = {
+	{
+		.mod_no = TWL4030_MODULE_INT,
+		.reg_cnt = ARRAY_SIZE(twl4030_int_imr_regs),
+		.imrs = twl4030_int_imr_regs,
+		.isrs = twl4030_int_isr_regs,
+	},
+	{
+		.mod_no = TWL4030_MODULE_INTERRUPTS,
+		.reg_cnt = ARRAY_SIZE(twl4030_interrupts_imr_regs),
+		.imrs = twl4030_interrupts_imr_regs,
+		.isrs = twl4030_interrupts_isr_regs,
+	},
+	{
+		.mod_no = TWL4030_MODULE_MADC,
+		.reg_cnt = ARRAY_SIZE(twl4030_madc_imr_regs),
+		.imrs = twl4030_madc_imr_regs,
+		.isrs = twl4030_madc_isr_regs,
+	},
+	{
+		.mod_no = TWL4030_MODULE_KEYPAD,
+		.reg_cnt = ARRAY_SIZE(twl4030_keypad_imr_regs),
+		.imrs = twl4030_keypad_imr_regs,
+		.isrs = twl4030_keypad_isr_regs,
+	},
+	{
+		.mod_no = TWL4030_MODULE_GPIO,
+		.reg_cnt = ARRAY_SIZE(twl4030_gpio_imr_regs),
+		.imrs = twl4030_gpio_imr_regs,
+		.isrs = twl4030_gpio_isr_regs,
+	},
+};
+
+
 /* Helper functions */
 static int
 twl4030_detect_client(struct i2c_adapter *adapter, unsigned char sid);
@@ -756,7 +880,7 @@ static int twl4030_i2c_clear_isr(u8 mod_no, u8 reg)
 
 static void twl_init_irq(void)
 {
-	int	i = 0;
+	int	i, j;
 	int	res = 0;
 	char	*msg = "Unable to register interrupt subsystem";
 	unsigned int irq_num;
@@ -767,86 +891,18 @@ static void twl_init_irq(void)
 	 * since we initially do not have any TWL4030 module interrupt
 	 * handlers present.
 	 */
-
-	/* Mask INT (PWR) interrupts at TWL4030 */
-	WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xff,
-				     TWL4030_INT_PWR_IMR1) < 0);
-	WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xff,
-				     TWL4030_INT_PWR_IMR2) < 0);
-	/* Clear TWL4030 INT (PWR) ISRs */
-	WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT,
-				      TWL4030_INT_PWR_ISR1) < 0);
-	WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT,
-				      TWL4030_INT_PWR_ISR2) < 0);
-
-	/* Slave address 0x4A */
-
-	/* Mask BCI interrupts at TWL4030 */
-	WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
-				     TWL4030_INTERRUPTS_BCIIMR1A) < 0);
-	WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
-				     TWL4030_INTERRUPTS_BCIIMR2A) < 0);
-	WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
-				     TWL4030_INTERRUPTS_BCIIMR1B) < 0);
-	WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
-				     TWL4030_INTERRUPTS_BCIIMR2B) < 0);
-	/* Clear TWL4030 BCI ISRs */
-	WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS,
-				      TWL4030_INTERRUPTS_BCIISR1A) < 0);
-	WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS,
-				      TWL4030_INTERRUPTS_BCIISR2A) < 0);
-	WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS,
-				      TWL4030_INTERRUPTS_BCIISR1B) < 0);
-	WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS,
-				      TWL4030_INTERRUPTS_BCIISR2B) < 0);
-
-	/* MAD C */
-	/* Mask MADC interrupts at TWL4030 */
-	WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xff,
-				     TWL4030_MADC_IMR1) < 0);
-	WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xff,
-				     TWL4030_MADC_IMR2) < 0);
-	/* Clear TWL4030 MADC ISRs */
-	WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC,
-				      TWL4030_MADC_ISR1) < 0);
-	WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC,
-				      TWL4030_MADC_ISR2) < 0);
-
-	/* key Pad */
-	/* Mask keypad interrupts at TWL4030 */
-	WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xff,
-				     TWL4030_KEYPAD_KEYP_IMR1) < 0);
-	WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xff,
-				     TWL4030_KEYPAD_KEYP_IMR2) < 0);
-	/* Clear TWL4030 keypad ISRs */
-	/* XXX does this still need to be done twice for some reason? */
-	WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD,
-				      TWL4030_KEYPAD_KEYP_ISR1) < 0);
-	WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD,
-				      TWL4030_KEYPAD_KEYP_ISR2) < 0);
-
-	/* Slave address 0x49 */
-	/* Mask GPIO interrupts at TWL4030 */
-	WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
-				     REG_GPIO_IMR1A) < 0);
-	WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
-				     REG_GPIO_IMR2A) < 0);
-	WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
-				     REG_GPIO_IMR3A) < 0);
-	WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
-				     REG_GPIO_IMR1B) < 0);
-	WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
-				     REG_GPIO_IMR2B) < 0);
-	WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
-				     REG_GPIO_IMR3B) < 0);
-
-	/* Clear TWL4030 GPIO ISRs */
-	WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR1A) < 0);
-	WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR2A) < 0);
-	WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR3A) < 0);
-	WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR1B) < 0);
-	WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR2B) < 0);
-	WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR3B) < 0);
+	for (i = 0; i < ARRAY_SIZE(twl4030_mod_regs); i++) {
+		const struct twl4030_mod_iregs tmr = twl4030_mod_regs[i];
+
+		for (j = 0; j < tmr.reg_cnt; j++) {
+			/* Mask interrupts at the TWL4030 */
+			WARN_ON(twl4030_i2c_write_u8(tmr.mod_no, 0xff,
+						     tmr.imrs[j]) < 0);
+			/* Clear TWL4030 ISRs */
+			WARN_ON(twl4030_i2c_clear_isr(tmr.mod_no,
+						      tmr.isrs[j]) < 0);
+		}
+	}
 
 	/* install an irq handler for each of the PIH modules */
 	for (i = TWL4030_IRQ_BASE; i < TWL4030_IRQ_END; i++) {


--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux