[PATCH 26/25] twl4030 gpio cleanups

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

 



From: David Brownell <dbrownell@xxxxxxxxxxxxxxxxxxxxx>

Clean up the twl4030-gpio code a bit ... mostly by shrinkage.

Remove a bunch of macros that are just obfuscating what the
TWL4030 GPIO code is doing.  Some duplicated standard macros
like BIT(); others hid trivial math (mask/shift); others were
completely unused.

Use BIT() in several places to highlight the bitmasking and
make the code more compact.

Remove pointless locking calls, sanity checks, and parenthesis.
And needless irq_chip.

Signed-off-by: David Brownell <dbrownell@xxxxxxxxxxxxxxxxxxxxx>
---
I suggest just merging 'v5' plus this patch instead of issuing
"v6" series.  ;)

 drivers/gpio/twl4030-gpio.c |  189 ++++++++++--------------------------------
 1 file changed, 47 insertions(+), 142 deletions(-)

--- a/drivers/gpio/twl4030-gpio.c
+++ b/drivers/gpio/twl4030-gpio.c
@@ -41,6 +41,20 @@
 #include <linux/i2c/twl4030-gpio.h>
 
 
+/*
+ * The GPIO "subchip" supports 18 GPIOs which can be configured as
+ * inputs or outputs, with pullups or pulldowns on each pin.  Each
+ * GPIO can trigger interrupts on either or both edges.
+ *
+ * GPIO interrupts can be fed to either of two IRQ lines; this is
+ * intended to support multiple hosts.
+ *
+ * There are also two LED pins used sometimes as output-only GPIOs.
+ *
+ * FIXME code currently only handles the first IRQ line.
+ */
+
+
 static inline void activate_irq(int irq)
 {
 #ifdef CONFIG_ARM
@@ -65,83 +79,15 @@ static int twl4030_gpio_irq_end;
 #define is_module()	false
 #endif
 
-/* BitField Definitions */
-
-/* Data banks : 3 banks for 8 gpios each */
-#define DATA_BANK_MAX				8
-#define GET_GPIO_DATA_BANK(x)			((x)/DATA_BANK_MAX)
-#define GET_GPIO_DATA_OFF(x)			((x)%DATA_BANK_MAX)
-
-/* GPIODATADIR Fields each block 0-7 */
-#define BIT_GPIODATADIR_GPIOxDIR(x)		(x)
-#define MASK_GPIODATADIR_GPIOxDIR(x)		(0x01 << (x))
-
-/* GPIODATAIN Fields each block 0-7 */
-#define BIT_GPIODATAIN_GPIOxIN(x)		(x)
-#define MASK_GPIODATAIN_GPIOxIN(x)		(0x01 << (x))
-
-/* GPIODATAOUT Fields each block 0-7 */
-#define BIT_GPIODATAOUT_GPIOxOUT(x)		(x)
-#define MASK_GPIODATAOUT_GPIOxOUT(x)		(0x01 << (x))
-
-/* CLEARGPIODATAOUT Fields */
-#define BIT_CLEARGPIODATAOUT_GPIOxOUT(x)	(x)
-#define MASK_CLEARGPIODATAOUT_GPIOxOUT(x)	(0x01 << (x))
-
-/* SETGPIODATAOUT Fields */
-#define BIT_SETGPIODATAOUT_GPIOxOUT(x)		(x)
-#define MASK_SETGPIODATAOUT_GPIOxOUT(x)		(0x01 << (x))
-
-/* GPIO_DEBEN Fields */
-#define BIT_GPIO_DEBEN_GPIOxDEB(x)		(x)
-#define MASK_GPIO_DEBEN_GPIOxDEB(x)		(0x01 << (x))
-
-/* GPIO_ISR1A Fields */
-#define BIT_GPIO_ISR_GPIOxISR(x)		(x)
-#define MASK_GPIO_ISR_GPIOxISR(x)		(0x01 << (x))
-
-/* GPIO_IMR1A Fields */
-#define BIT_GPIO_IMR1A_GPIOxIMR(x)		(x)
-#define MASK_GPIO_IMR1A_GPIOxIMR(x)		(0x01 << (x))
-
-/* GPIO_SIR1 Fields */
-#define BIT_GPIO_SIR1_GPIOxSIR(x)		(x)
-#define MASK_GPIO_SIR1_GPIO0SIR			(0x01 << (x))
-
-
-/* Control banks : 5 banks for 4 gpios each */
-#define DATA_CTL_MAX			4
-#define GET_GPIO_CTL_BANK(x)		((x)/DATA_CTL_MAX)
-#define GET_GPIO_CTL_OFF(x)		((x)%DATA_CTL_MAX)
-#define GPIO_BANK_MAX			GET_GPIO_CTL_BANK(TWL4030_GPIO_MAX)
-
-/* GPIOPUPDCTRx Fields 5 banks of 4 gpios each */
-#define BIT_GPIOPUPDCTR1_GPIOxPD(x)	(2 * (x))
-#define MASK_GPIOPUPDCTR1_GPIOxPD(x)	(0x01 << (2 * (x)))
-#define BIT_GPIOPUPDCTR1_GPIOxPU(x)	((x) + 1)
-#define MASK_GPIOPUPDCTR1_GPIOxPU(x)	(0x01 << (((2 * (x)) + 1)))
-
-/* GPIO_EDR1 Fields */
-#define BIT_GPIO_EDR1_GPIOxFALLING(x)	(2 * (x))
-#define MASK_GPIO_EDR1_GPIOxFALLING(x)	(0x01 << (2 * (x)))
-#define BIT_GPIO_EDR1_GPIOxRISING(x)	((x) + 1)
-#define MASK_GPIO_EDR1_GPIOxRISING(x)	(0x01 << (((2 * (x)) + 1)))
-
 /* GPIO_SIH_CTRL Fields */
-#define BIT_GPIO_SIH_CTRL_EXCLEN	(0x000)
-#define MASK_GPIO_SIH_CTRL_EXCLEN	(0x00000001)
-#define BIT_GPIO_SIH_CTRL_PENDDIS	(0x001)
-#define MASK_GPIO_SIH_CTRL_PENDDIS	(0x00000002)
-#define BIT_GPIO_SIH_CTRL_COR		(0x002)
-#define MASK_GPIO_SIH_CTRL_COR		(0x00000004)
+#define MASK_GPIO_SIH_CTRL_EXCLEN	BIT(0)
+#define MASK_GPIO_SIH_CTRL_PENDDIS	BIT(1)
+#define MASK_GPIO_SIH_CTRL_COR		BIT(2)
 
 /* GPIO_CTRL Fields */
-#define BIT_GPIO_CTRL_GPIO0CD1		(0x000)
-#define MASK_GPIO_CTRL_GPIO0CD1		(0x00000001)
-#define BIT_GPIO_CTRL_GPIO1CD2		(0x001)
-#define MASK_GPIO_CTRL_GPIO1CD2		(0x00000002)
-#define BIT_GPIO_CTRL_GPIO_ON		(0x002)
-#define MASK_GPIO_CTRL_GPIO_ON		(0x00000004)
+#define MASK_GPIO_CTRL_GPIO0CD1		BIT(0)
+#define MASK_GPIO_CTRL_GPIO1CD2		BIT(1)
+#define MASK_GPIO_CTRL_GPIO_ON		BIT(2)
 
 /* Mask for GPIO registers when aggregated into a 32-bit integer */
 #define GPIO_32_MASK			0x0003ffff
@@ -298,29 +244,13 @@ static struct irq_chip twl4030_gpio_irq_
 	.set_type	= twl4030_gpio_irq_set_type,
 };
 
-/*
- * These are the irqchip methods for the TWL4030 PIH GPIO module interrupt.
- * The PIH module doesn't have interrupt masking capability, so these
- * methods are NULL.
- */
-static void twl4030_gpio_module_ack(unsigned int irq) {}
-static void twl4030_gpio_module_mask(unsigned int irq) {}
-static void twl4030_gpio_module_unmask(unsigned int irq) {}
-static struct irq_chip twl4030_gpio_module_irq_chip = {
-	.ack	= twl4030_gpio_module_ack,
-	.mask	= twl4030_gpio_module_mask,
-	.unmask	= twl4030_gpio_module_unmask,
-};
 
 /*
  * To configure TWL4030 GPIO module registers
  */
 static inline int gpio_twl4030_write(u8 address, u8 data)
 {
-	int ret = 0;
-
-	ret = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, data, address);
-	return ret;
+	return twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, data, address);
 }
 
 /*
@@ -332,9 +262,7 @@ static inline int gpio_twl4030_read(u8 a
 	int ret = 0;
 
 	ret = twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &data, address);
-	if (ret >= 0)
-		ret = data;
-	return ret;
+	return (ret < 0) ? ret : data;
 }
 
 /*
@@ -352,7 +280,7 @@ int twl4030_request_gpio(int gpio)
 		return ret;
 
 	mutex_lock(&gpio_lock);
-	if (gpio_usage_count & (0x1 << gpio)) {
+	if (gpio_usage_count & BIT(gpio)) {
 		ret = -EBUSY;
 	} else {
 		/* First time usage? - switch on GPIO module */
@@ -362,7 +290,7 @@ int twl4030_request_gpio(int gpio)
 			ret = gpio_twl4030_write(REG_GPIO_SIH_CTRL, 0x00);
 		}
 		if (!ret)
-			gpio_usage_count |= (0x1 << gpio);
+			gpio_usage_count |= BIT(gpio);
 		else
 			gpio_free(twl_gpiochip.base + gpio);
 	}
@@ -383,10 +311,10 @@ int twl4030_free_gpio(int gpio)
 
 	mutex_lock(&gpio_lock);
 
-	if ((gpio_usage_count & (0x1 << gpio)) == 0) {
+	if ((gpio_usage_count & BIT(gpio)) == 0) {
 		ret = -EPERM;
 	} else {
-		gpio_usage_count &= ~(0x1 << gpio);
+		gpio_usage_count &= ~BIT(gpio);
 		gpio_free(twl_gpiochip.base + gpio);
 	}
 
@@ -399,27 +327,21 @@ int twl4030_free_gpio(int gpio)
 }
 EXPORT_SYMBOL(twl4030_free_gpio);
 
-/*
- * Set direction for TWL4030 GPIO
- */
 static int twl4030_set_gpio_direction(int gpio, int is_input)
 {
-	u8 d_bnk = GET_GPIO_DATA_BANK(gpio);
-	u8 d_msk = MASK_GPIODATADIR_GPIOxDIR(GET_GPIO_DATA_OFF(gpio));
+	u8 d_bnk = gpio >> 3;
+	u8 d_msk = BIT(gpio & 0x7);
 	u8 reg = 0;
 	u8 base = REG_GPIODATADIR1 + d_bnk;
 	int ret = 0;
 
-	if (unlikely(!(gpio_usage_count & (0x1 << gpio))))
-		return -EPERM;
-
 	mutex_lock(&gpio_lock);
 	ret = gpio_twl4030_read(base);
 	if (ret >= 0) {
 		if (is_input)
-			reg = (u8) ((ret) & ~(d_msk));
+			reg = ret & ~d_msk;
 		else
-			reg = (u8) ((ret) | (d_msk));
+			reg = ret | d_msk;
 
 		ret = gpio_twl4030_write(base, reg);
 	}
@@ -427,48 +349,33 @@ static int twl4030_set_gpio_direction(in
 	return ret;
 }
 
-/*
- * To enable/disable GPIO pin on TWL4030
- */
 static int twl4030_set_gpio_dataout(int gpio, int enable)
 {
-	u8 d_bnk = GET_GPIO_DATA_BANK(gpio);
-	u8 d_msk = MASK_GPIODATAOUT_GPIOxOUT(GET_GPIO_DATA_OFF(gpio));
+	u8 d_bnk = gpio >> 3;
+	u8 d_msk = BIT(gpio & 0x7);
 	u8 base = 0;
-	int ret = 0;
-
-	if (unlikely(!(gpio_usage_count & (0x1 << gpio))))
-		return -EPERM;
 
 	if (enable)
 		base = REG_SETGPIODATAOUT1 + d_bnk;
 	else
 		base = REG_CLEARGPIODATAOUT1 + d_bnk;
 
-	mutex_lock(&gpio_lock);
-	ret = gpio_twl4030_write(base, d_msk);
-	mutex_unlock(&gpio_lock);
-	return ret;
+	return gpio_twl4030_write(base, d_msk);
 }
 
-/*
- * To get the status of a GPIO pin on TWL4030
- */
 int twl4030_get_gpio_datain(int gpio)
 {
-	u8 d_bnk = GET_GPIO_DATA_BANK(gpio);
-	u8 d_off = BIT_GPIODATAIN_GPIOxIN(GET_GPIO_DATA_OFF(gpio));
+	u8 d_bnk = gpio >> 3;
+	u8 d_off = gpio & 0x7;
 	u8 base = 0;
 	int ret = 0;
 
 	if (unlikely((gpio >= TWL4030_GPIO_MAX)
-		|| !(gpio_usage_count & (0x1 << gpio))))
+		|| !(gpio_usage_count & BIT(gpio))))
 		return -EPERM;
 
 	base = REG_GPIODATAIN1 + d_bnk;
-	mutex_lock(&gpio_lock);
 	ret = gpio_twl4030_read(base);
-	mutex_unlock(&gpio_lock);
 	if (ret > 0)
 		ret = (ret >> d_off) & 0x1;
 
@@ -478,8 +385,8 @@ EXPORT_SYMBOL(twl4030_get_gpio_datain);
 
 static int twl4030_set_gpio_edge_ctrl(int gpio, int edge)
 {
-	u8 c_bnk = GET_GPIO_CTL_BANK(gpio);
-	u8 c_off = GET_GPIO_CTL_OFF(gpio);
+	u8 c_bnk = gpio >> 2;
+	u8 c_off = (gpio & 0x3) * 2;
 	u8 c_msk = 0;
 	u8 reg = 0;
 	u8 base = 0;
@@ -488,17 +395,16 @@ static int twl4030_set_gpio_edge_ctrl(in
 	base = REG_GPIO_EDR1 + c_bnk;
 
 	if (edge & IRQ_TYPE_EDGE_RISING)
-		c_msk |= MASK_GPIO_EDR1_GPIOxRISING(c_off);
+		c_msk |= BIT(c_off + 1);
 	if (edge & IRQ_TYPE_EDGE_FALLING)
-		c_msk |= MASK_GPIO_EDR1_GPIOxFALLING(c_off);
+		c_msk |= BIT(c_off);
 
 	mutex_lock(&gpio_lock);
 	ret = gpio_twl4030_read(base);
 	if (ret >= 0) {
 		/* clear the previous rising/falling values */
 		reg = (u8) ret;
-		reg &= ~(MASK_GPIO_EDR1_GPIOxFALLING(c_off)
-			| MASK_GPIO_EDR1_GPIOxRISING(c_off));
+		reg &= ~(0x3 << c_off);
 		reg |= c_msk;
 		ret = gpio_twl4030_write(base, reg);
 	}
@@ -511,14 +417,14 @@ static int twl4030_set_gpio_edge_ctrl(in
  */
 int twl4030_set_gpio_debounce(int gpio, int enable)
 {
-	u8 d_bnk = GET_GPIO_DATA_BANK(gpio);
-	u8 d_msk = MASK_GPIO_DEBEN_GPIOxDEB(GET_GPIO_DATA_OFF(gpio));
+	u8 d_bnk = gpio >> 3;
+	u8 d_msk = BIT(gpio & 0x7);
 	u8 reg = 0;
 	u8 base = 0;
 	int ret = 0;
 
 	if (unlikely((gpio >= TWL4030_GPIO_MAX)
-		|| !(gpio_usage_count & (0x1 << gpio))))
+		|| !(gpio_usage_count & BIT(gpio))))
 		return -EPERM;
 
 	base = REG_GPIO_DEBEN1 + d_bnk;
@@ -526,9 +432,9 @@ int twl4030_set_gpio_debounce(int gpio, 
 	ret = gpio_twl4030_read(base);
 	if (ret >= 0) {
 		if (enable)
-			reg = (u8) ((ret) | (d_msk));
+			reg = ret | d_msk;
 		else
-			reg = (u8) ((ret) & ~(d_msk));
+			reg = ret & ~d_msk;
 
 		ret = gpio_twl4030_write(base, reg);
 	}
@@ -552,7 +458,7 @@ int twl4030_set_gpio_card_detect(int gpi
 
 	/* Only GPIO 0 or 1 can be used for CD feature.. */
 	if (unlikely((gpio >= TWL4030_GPIO_MAX)
-		|| !(gpio_usage_count & (0x1 << gpio))
+		|| !(gpio_usage_count & BIT(gpio))
 		|| (gpio >= TWL4030_GPIO_MAX_CD))) {
 		return -EPERM;
 	}
@@ -855,7 +761,6 @@ static int __devinit gpio_twl4030_probe(
 		 * Install an irq handler to demultiplex the gpio module
 		 * interrupt.
 		 */
-		set_irq_chip(irq, &twl4030_gpio_module_irq_chip);
 		set_irq_chained_handler(irq, do_twl4030_gpio_module_irq);
 		wake_up_process(gpio_unmask_thread);
 


--
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