[PATCH 00/12] mfd: twl: Fix for irqdomain/next + SPARSE_IRQ + MMC card detect

STALE5254d

30 messages, 6 authors, 2012-03-13 · open the first message on its own page

[PATCH 00/12] mfd: twl: Fix for irqdomain/next + SPARSE_IRQ + MMC card detect

From: Benoit Cousson <hidden>
Date: 2012-03-02 16:50:12

Hi Samuel and Tony,

Here is a fix + cleanup + SPARSE_IRQ series for TWL4030 and TWL6030.

The first goal was to fix the current regression due to irqdomain
support inside twl-core for OMAP3 + twl4030.

The issue is that there is no quick and dirty fix for that, hence this
exhaustive series started by Felipe to add SPARSE_IRQ support for TWL
modules.

On top of that a bunch of code cleanup are done, and in order to make
the MMC card detect still operational, some fixes are needed in the
board file too.

Due to the modification in the SIH setup API, the twl4030-gpio driver
has to be updated as well.

It was then trivial to add some basic device tree support for the
twl4030-gpio driver.

Please note that this series does depend on the irqdomain/next series
from Grant.

These patches will be probably sent in separate pull request. The only
strong dependency is with the irqdomain series.

This series is available here for reference:
  git://git.kernel.org/pub/scm/linux/kernel/git/bcousson/linux-omap-dt.git for_3.4/twl_irq_gpio_cleanup

This is not for pull-request, becasue it is based on irqdomain + OMAP
IRQ DT series + OMAP twl DT series yet to be pushed.

Regards,
Benoit


Benoit Cousson (9):
  mfd: twl-core: Remove references already defined in header file
  mfd: twl-core: Move IRQ allocation into twl[4030|6030]-irq files
  mfd: twl4030-irq: Make SIH SPARSE_IRQ capable
  mfd: twl-*: Change from pr_XXX to dev_XXX macros and various cleanups
  gpio/twl: Allocate irq_desc dynamically for SPARSE_IRQ support
  gpio/twl: Add DT support to gpio-twl4030 driver
  arm/dts: twl4030: Add twl4030-gpio node
  mfd: twl4030-irq: Return twl6030_mmc_card_detect IRQ for board setup
  ARM: OMAP2+: board-omap4-*: Do not use anymore TWL6030_IRQ_BASE in board files

Felipe Balbi (3):
  mfd: twl-core: don't depend on pdata->irq_base/end
  mfd: twl-core: remove unneeded header
  mfd: twl4030-irq: micro-optimization on IRQ handler

 .../devicetree/bindings/gpio/gpio-twl4030.txt      |   23 ++++
 arch/arm/boot/dts/twl4030.dtsi                     |    8 ++
 arch/arm/mach-omap2/board-4430sdp.c                |   13 ++-
 arch/arm/mach-omap2/board-omap4panda.c             |   15 ++--
 drivers/gpio/gpio-twl4030.c                        |  111 ++++++++++++--------
 drivers/mfd/twl-core.c                             |   99 +++++++-----------
 drivers/mfd/twl-core.h                             |    4 +-
 drivers/mfd/twl4030-irq.c                          |   87 +++++++++-------
 drivers/mfd/twl6030-irq.c                          |   71 ++++++++-----
 include/linux/i2c/twl.h                            |    2 +-
 10 files changed, 247 insertions(+), 186 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-twl4030.txt

[PATCH 01/12] mfd: twl-core: don't depend on pdata->irq_base/end

From: Benoit Cousson <hidden>
Date: 2012-03-02 16:50:13

From: Felipe Balbi <redacted>

With sparse IRQs the driver shouldn't depend at all on
any IRQ values coming from board-file.

Remove every occurences of pdata->irq_base/end.

Signed-off-by: Felipe Balbi <redacted>
Signed-off-by: Benoit Cousson <redacted>
---
 drivers/mfd/twl-core.c |   49 ++++++++++++++++++++++++-----------------------
 1 files changed, 25 insertions(+), 24 deletions(-)
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 4970d43..f28a1dc 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -648,7 +648,8 @@ add_regulator(int num, struct regulator_init_data *pdata,
  */
 
 static int
-add_children(struct twl4030_platform_data *pdata, unsigned long features)
+add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
+		unsigned long features)
 {
 	struct device	*child;
 	unsigned sub_chip_id;
@@ -656,7 +657,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
 	if (twl_has_gpio() && pdata->gpio) {
 		child = add_child(SUB_CHIP_ID1, "twl4030_gpio",
 				pdata->gpio, sizeof(*pdata->gpio),
-				false, pdata->irq_base + GPIO_INTR_OFFSET, 0);
+				false, irq_base + GPIO_INTR_OFFSET, 0);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 	}
@@ -664,7 +665,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
 	if (twl_has_keypad() && pdata->keypad) {
 		child = add_child(SUB_CHIP_ID2, "twl4030_keypad",
 				pdata->keypad, sizeof(*pdata->keypad),
-				true, pdata->irq_base + KEYPAD_INTR_OFFSET, 0);
+				true, irq_base + KEYPAD_INTR_OFFSET, 0);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 	}
@@ -672,7 +673,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
 	if (twl_has_madc() && pdata->madc) {
 		child = add_child(2, "twl4030_madc",
 				pdata->madc, sizeof(*pdata->madc),
-				true, pdata->irq_base + MADC_INTR_OFFSET, 0);
+				true, irq_base + MADC_INTR_OFFSET, 0);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 	}
@@ -688,7 +689,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
 		sub_chip_id = twl_map[TWL_MODULE_RTC].sid;
 		child = add_child(sub_chip_id, "twl_rtc",
 				NULL, 0,
-				true, pdata->irq_base + RTC_INTR_OFFSET, 0);
+				true, irq_base + RTC_INTR_OFFSET, 0);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 	}
@@ -741,8 +742,8 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
 				pdata->usb, sizeof(*pdata->usb),
 				true,
 				/* irq0 = USB_PRES, irq1 = USB */
-				pdata->irq_base + USB_PRES_INTR_OFFSET,
-				pdata->irq_base + USB_INTR_OFFSET);
+				irq_base + USB_PRES_INTR_OFFSET,
+				irq_base + USB_INTR_OFFSET);
 
 		if (IS_ERR(child))
 			return PTR_ERR(child);
@@ -790,8 +791,8 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
 			pdata->usb, sizeof(*pdata->usb),
 			true,
 			/* irq1 = VBUS_PRES, irq0 = USB ID */
-			pdata->irq_base + USBOTG_INTR_OFFSET,
-			pdata->irq_base + USB_PRES_INTR_OFFSET);
+			irq_base + USBOTG_INTR_OFFSET,
+			irq_base + USB_PRES_INTR_OFFSET);
 
 		if (IS_ERR(child))
 			return PTR_ERR(child);
@@ -818,7 +819,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
 
 	if (twl_has_pwrbutton() && twl_class_is_4030()) {
 		child = add_child(1, "twl4030_pwrbutton",
-				NULL, 0, true, pdata->irq_base + 8 + 0, 0);
+				NULL, 0, true, irq_base + 8 + 0, 0);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 	}
@@ -1052,8 +1053,8 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
 		child = add_child(3, "twl4030_bci",
 				pdata->bci, sizeof(*pdata->bci), false,
 				/* irq0 = CHG_PRES, irq1 = BCI */
-				pdata->irq_base + BCI_PRES_INTR_OFFSET,
-				pdata->irq_base + BCI_INTR_OFFSET);
+				irq_base + BCI_PRES_INTR_OFFSET,
+				irq_base + BCI_INTR_OFFSET);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 	}
@@ -1187,6 +1188,8 @@ static int twl_remove(struct i2c_client *client)
 static int __devinit
 twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
+	int				irq_base;
+	int				irq_end;
 	int				status;
 	unsigned			i;
 	struct twl4030_platform_data	*pdata = client->dev.platform_data;
@@ -1215,15 +1218,15 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		return -EINVAL;
 	}
 
-	status = irq_alloc_descs(-1, pdata->irq_base, nr_irqs, 0);
+	status = irq_alloc_descs(-1, 0, nr_irqs, 0);
 	if (IS_ERR_VALUE(status)) {
 		dev_err(&client->dev, "Fail to allocate IRQ descs\n");
 		return status;
 	}
 
-	pdata->irq_base = status;
-	pdata->irq_end = pdata->irq_base + nr_irqs;
-	irq_domain_add_legacy(node, nr_irqs, pdata->irq_base, 0,
+	irq_base = status;
+	irq_end = irq_base + nr_irqs;
+	irq_domain_add_legacy(node, nr_irqs, irq_base, 0,
 			      &irq_domain_simple_ops, NULL);
 
 	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
@@ -1277,16 +1280,14 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		twl4030_power_init(pdata->power);
 
 	/* Maybe init the T2 Interrupt subsystem */
-	if (client->irq
-			&& pdata->irq_base
-			&& pdata->irq_end > pdata->irq_base) {
+	if (client->irq) {
 		if (twl_class_is_4030()) {
 			twl4030_init_chip_irq(id->name);
-			status = twl4030_init_irq(client->irq, pdata->irq_base,
-			pdata->irq_end);
+			status = twl4030_init_irq(client->irq, irq_base,
+			irq_end);
 		} else {
-			status = twl6030_init_irq(client->irq, pdata->irq_base,
-			pdata->irq_end);
+			status = twl6030_init_irq(client->irq, irq_base,
+			irq_end);
 		}
 
 		if (status < 0)
@@ -1309,7 +1310,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	if (node)
 		status = of_platform_populate(node, NULL, NULL, &client->dev);
 	if (status)
-		status = add_children(pdata, id->driver_data);
+		status = add_children(pdata, irq_base, id->driver_data);
 
 fail:
 	if (status < 0)
-- 
1.7.0.4

[PATCH 02/12] mfd: twl-core: remove unneeded header

From: Benoit Cousson <hidden>
Date: 2012-03-02 16:50:14

From: Felipe Balbi <redacted>

This driver doesn't really need <plat/cpu.h>, so remove it.

Signed-off-by: Felipe Balbi <redacted>
---
 drivers/mfd/twl-core.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index f28a1dc..e612678 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -45,10 +45,6 @@
 #include <linux/i2c.h>
 #include <linux/i2c/twl.h>
 
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-#include <plat/cpu.h>
-#endif
-
 /*
  * The TWL4030 "Triton 2" is one of a family of a multi-function "Power
  * Management and System Companion Device" chips originally designed for
-- 
1.7.0.4

[PATCH 03/12] mfd: twl-core: Remove references already defined in header file

From: Benoit Cousson <hidden>
Date: 2012-03-02 16:50:15

The twl-core exported functions are already declared in twl-core.h

Include the header file instead or re-declaring the functions.

Signed-off-by: Benoit Cousson <redacted>
Acked-by: Felipe Balbi <redacted>
---
 drivers/mfd/twl-core.c |    7 ++-----
 1 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index e612678..d0f08b0 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -45,6 +45,8 @@
 #include <linux/i2c.h>
 #include <linux/i2c/twl.h>
 
+#include "twl-core.h"
+
 /*
  * The TWL4030 "Triton 2" is one of a family of a multi-function "Power
  * Management and System Companion Device" chips originally designed for
@@ -1150,11 +1152,6 @@ static void clocks_init(struct device *dev,
 
 /*----------------------------------------------------------------------*/
 
-int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end);
-int twl4030_exit_irq(void);
-int twl4030_init_chip_irq(const char *chip);
-int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end);
-int twl6030_exit_irq(void);
 
 static int twl_remove(struct i2c_client *client)
 {
-- 
1.7.0.4

[PATCH 04/12] mfd: twl-core: Move IRQ allocation into twl[4030|6030]-irq files

From: Benoit Cousson <hidden>
Date: 2012-03-02 16:50:16

During DT adaptation, the irq_alloc_desc was added into twl-core, but
due to the rather different and weird IRQ management required by the twl4030,
it is much better to have a different approach for it.
The issue is that twl4030 uses a two level IRQ mechanism but handles all the
PWR interrupts as part of the twl-core interrupt range. It ends up with a
range of 16 interrupts total for CORE and PWR.

The other twl4030 functionalities already have a dedicated driver and thus
their IRQs and irqdomain can and should be defined localy.

twl6030 is using a single level IRQ controller and thus does not require any
trick.

Move the irq_alloc_desc and irq_domain_add_legacy in twl4030-irq and
twl6030-irq.

Allocate together CORE and PWR IRQs for twl4030-irq.

Signed-off-by: Benoit Cousson <redacted>
Acked-by: Felipe Balbi <redacted>
---
 drivers/mfd/twl-core.c    |   29 +++++------------------------
 drivers/mfd/twl-core.h    |    4 ++--
 drivers/mfd/twl4030-irq.c |   29 +++++++++++++++++++++++++++--
 drivers/mfd/twl6030-irq.c |   31 ++++++++++++++++++++++---------
 4 files changed, 56 insertions(+), 37 deletions(-)
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index d0f08b0..1c1b7d1 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -147,9 +147,6 @@
 
 #define TWL_MODULE_LAST TWL4030_MODULE_LAST
 
-#define TWL4030_NR_IRQS    34 /* core:8, power:8, gpio: 18 */
-#define TWL6030_NR_IRQS    20
-
 /* Base Address defns for twl4030_map[] */
 
 /* subchip/slave 0 - USB ID */
@@ -1182,17 +1179,12 @@ static int __devinit
 twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
 	int				irq_base;
-	int				irq_end;
 	int				status;
 	unsigned			i;
 	struct twl4030_platform_data	*pdata = client->dev.platform_data;
 	struct device_node		*node = client->dev.of_node;
 	u8 temp;
 	int ret = 0;
-	int nr_irqs = TWL4030_NR_IRQS;
-
-	if ((id->driver_data) & TWL6030_CLASS)
-		nr_irqs = TWL6030_NR_IRQS;
 
 	if (node && !pdata) {
 		/*
@@ -1211,17 +1203,6 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		return -EINVAL;
 	}
 
-	status = irq_alloc_descs(-1, 0, nr_irqs, 0);
-	if (IS_ERR_VALUE(status)) {
-		dev_err(&client->dev, "Fail to allocate IRQ descs\n");
-		return status;
-	}
-
-	irq_base = status;
-	irq_end = irq_base + nr_irqs;
-	irq_domain_add_legacy(node, nr_irqs, irq_base, 0,
-			      &irq_domain_simple_ops, NULL);
-
 	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
 		dev_dbg(&client->dev, "can't talk I2C?\n");
 		return -EIO;
@@ -1276,15 +1257,15 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	if (client->irq) {
 		if (twl_class_is_4030()) {
 			twl4030_init_chip_irq(id->name);
-			status = twl4030_init_irq(client->irq, irq_base,
-			irq_end);
+			irq_base = twl4030_init_irq(&client->dev, client->irq);
 		} else {
-			status = twl6030_init_irq(client->irq, irq_base,
-			irq_end);
+			irq_base = twl6030_init_irq(&client->dev, client->irq);
 		}
 
-		if (status < 0)
+		if (irq_base < 0) {
+			status = irq_base;
 			goto fail;
+		}
 	}
 
 	/* Disable TWL4030/TWL5030 I2C Pull-up on I2C1 and I2C4(SR) interface.
diff --git a/drivers/mfd/twl-core.h b/drivers/mfd/twl-core.h
index 8c50a55..6ff99dc 100644
--- a/drivers/mfd/twl-core.h
+++ b/drivers/mfd/twl-core.h
@@ -1,9 +1,9 @@
 #ifndef __TWL_CORE_H__
 #define __TWL_CORE_H__
 
-extern int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end);
+extern int twl6030_init_irq(struct device *dev, int irq_num);
 extern int twl6030_exit_irq(void);
-extern int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end);
+extern int twl4030_init_irq(struct device *dev, int irq_num);
 extern int twl4030_exit_irq(void);
 extern int twl4030_init_chip_irq(const char *chip);
 
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index b69bb51..3b34531 100644
--- a/drivers/mfd/twl4030-irq.c
+++ b/drivers/mfd/twl4030-irq.c
@@ -28,10 +28,13 @@
  */
 
 #include <linux/init.h>
+#include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/slab.h>
 
+#include <linux/of.h>
+#include <linux/irqdomain.h>
 #include <linux/i2c/twl.h>
 
 #include "twl-core.h"
@@ -53,6 +56,8 @@
  *	base + 8  .. base + 15	SIH for PWR_INT
  *	base + 16 .. base + 33	SIH for GPIO
  */
+#define TWL4030_CORE_NR_IRQS	8
+#define TWL4030_PWR_NR_IRQS	8
 
 /* PIH register offsets */
 #define REG_PIH_ISR_P1			0x01
@@ -694,14 +699,34 @@ int twl4030_sih_setup(int module)
 /* FIXME pass in which interrupt line we'll use ... */
 #define twl_irq_line	0
 
-int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
+int twl4030_init_irq(struct device *dev, int irq_num)
 {
 	static struct irq_chip	twl4030_irq_chip;
+	int			irq_base, irq_end, nr_irqs;
+	struct			device_node *node = dev->of_node;
 
 	int			status;
 	int			i;
 
 	/*
+	 * TWL core and pwr interrupts must be contiguous because
+	 * the hwirqs numbers are defined contiguously from 1 to 15.
+	 * Create only one domain for both.
+	 */
+	nr_irqs = TWL4030_PWR_NR_IRQS + TWL4030_CORE_NR_IRQS;
+
+	irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
+	if (IS_ERR_VALUE(irq_base)) {
+		dev_err(dev, "Fail to allocate IRQ descs\n");
+		return irq_base;
+	}
+
+	irq_domain_add_legacy(node, nr_irqs, irq_base, 0,
+			      &irq_domain_simple_ops, NULL);
+
+	irq_end = irq_base + TWL4030_CORE_NR_IRQS;
+
+	/*
 	 * Mask and clear all TWL4030 interrupts since initially we do
 	 * not have any TWL4030 module interrupt handlers present
 	 */
@@ -745,7 +770,7 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
 		goto fail_rqirq;
 	}
 
-	return status;
+	return irq_base;
 fail_rqirq:
 	/* clean up twl4030_sih_setup */
 fail:
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c
index c6b456a..b4d5e0e 100644
--- a/drivers/mfd/twl6030-irq.c
+++ b/drivers/mfd/twl6030-irq.c
@@ -39,6 +39,8 @@
 #include <linux/i2c/twl.h>
 #include <linux/platform_device.h>
 #include <linux/suspend.h>
+#include <linux/of.h>
+#include <linux/irqdomain.h>
 
 #include "twl-core.h"
 
@@ -53,6 +55,7 @@
  * specifies mapping between interrupt number and the associated module.
  *
  */
+#define TWL6030_NR_IRQS    20
 
 static int twl6030_interrupt_mapping[24] = {
 	PWR_INTR_OFFSET,	/* Bit 0	PWRON			*/
@@ -237,11 +240,6 @@ int twl6030_irq_set_wake(struct irq_data *d, unsigned int on)
 	return 0;
 }
 
-/*----------------------------------------------------------------------*/
-
-static unsigned twl6030_irq_next;
-
-/*----------------------------------------------------------------------*/
 int twl6030_interrupt_unmask(u8 bit_mask, u8 offset)
 {
 	int ret;
@@ -340,8 +338,10 @@ int twl6030_mmc_card_detect(struct device *dev, int slot)
 }
 EXPORT_SYMBOL(twl6030_mmc_card_detect);
 
-int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
+int twl6030_init_irq(struct device *dev, int irq_num)
 {
+	struct			device_node *node = dev->of_node;
+	int			nr_irqs, irq_base, irq_end;
 
 	int	status = 0;
 	int	i;
@@ -350,6 +350,20 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
 	u8 mask[4];
 
 	static struct irq_chip	twl6030_irq_chip;
+
+	nr_irqs = TWL6030_NR_IRQS;
+
+	irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
+	if (IS_ERR_VALUE(irq_base)) {
+		dev_err(dev, "Fail to allocate IRQ descs\n");
+		return irq_base;
+	}
+
+	irq_domain_add_legacy(node, nr_irqs, irq_base, 0,
+			      &irq_domain_simple_ops, NULL);
+
+	irq_end = irq_base + nr_irqs;
+
 	mask[1] = 0xFF;
 	mask[2] = 0xFF;
 	mask[3] = 0xFF;
@@ -377,9 +391,8 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
 		activate_irq(i);
 	}
 
-	twl6030_irq_next = i;
 	pr_info("twl6030: %s (irq %d) chaining IRQs %d..%d\n", "PIH",
-			irq_num, irq_base, twl6030_irq_next - 1);
+			irq_num, irq_base, irq_end);
 
 	/* install an irq handler to demultiplex the TWL6030 interrupt */
 	init_completion(&irq_event);
@@ -400,7 +413,7 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
 
 	twl_irq = irq_num;
 	register_pm_notifier(&twl6030_irq_pm_notifier_block);
-	return status;
+	return irq_base;
 
 fail_kthread:
 	free_irq(irq_num, &irq_event);
-- 
1.7.0.4

[PATCH 05/12] mfd: twl4030-irq: Make SIH SPARSE_IRQ capable

From: Benoit Cousson <hidden>
Date: 2012-03-02 16:50:17

twl4030 is using a two level irq controllers infrastruture.
So far, only the first level was using dynamic irq_desc allocation
to be able to have irq_domain support for device tree.
There is a need to allocate separate irq_descs for the SIH too to
avoid hacking the first level with interrupts from the second level.

Add an irq_base parameter to allow the caller to provide the base from
pdata or from dynamic allocation.

Affect TWL4030_NR_IRQS to the twl-core IRQs only.

Moreover that will allow the extraction of the of_node pointer for further
Device Tree conversion.

Signed-off-by: Felipe Balbi <redacted>
Signed-off-by: Benoit Cousson <redacted>
---
 drivers/gpio/gpio-twl4030.c |    3 ++-
 drivers/mfd/twl4030-irq.c   |   23 ++++++-----------------
 include/linux/i2c/twl.h     |    2 +-
 3 files changed, 9 insertions(+), 19 deletions(-)
diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c
index b8b4f22..697396c 100644
--- a/drivers/gpio/gpio-twl4030.c
+++ b/drivers/gpio/gpio-twl4030.c
@@ -404,7 +404,8 @@ static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
 				"can't dispatch IRQs from modules\n");
 			goto no_irqs;
 		}
-		ret = twl4030_sih_setup(TWL4030_MODULE_GPIO);
+		ret = twl4030_sih_setup(&pdev->dev, TWL4030_MODULE_GPIO,
+					pdata->irq_base);
 		if (ret < 0)
 			return ret;
 		WARN_ON(ret != pdata->irq_base);
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index 3b34531..faf3318 100644
--- a/drivers/mfd/twl4030-irq.c
+++ b/drivers/mfd/twl4030-irq.c
@@ -625,30 +625,23 @@ static irqreturn_t handle_twl4030_sih(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-static unsigned twl4030_irq_next;
-
 /* returns the first IRQ used by this SIH bank,
  * or negative errno
  */
-int twl4030_sih_setup(int module)
+int twl4030_sih_setup(struct device *dev, int module, int irq_base)
 {
 	int			sih_mod;
 	const struct sih	*sih = NULL;
 	struct sih_agent	*agent;
 	int			i, irq;
 	int			status = -EINVAL;
-	unsigned		irq_base = twl4030_irq_next;
 
 	/* only support modules with standard clear-on-read for now */
 	for (sih_mod = 0, sih = sih_modules;
 			sih_mod < nr_sih_modules;
 			sih_mod++, sih++) {
 		if (sih->module == module && sih->set_cor) {
-			if (!WARN((irq_base + sih->bits) > NR_IRQS,
-					"irq %d for %s too big\n",
-					irq_base + sih->bits,
-					sih->name))
-				status = 0;
+			status = 0;
 			break;
 		}
 	}
@@ -659,8 +652,6 @@ int twl4030_sih_setup(int module)
 	if (!agent)
 		return -ENOMEM;
 
-	status = 0;
-
 	agent->irq_base = irq_base;
 	agent->sih = sih;
 	agent->imr = ~0;
@@ -676,8 +667,6 @@ int twl4030_sih_setup(int module)
 		activate_irq(irq);
 	}
 
-	twl4030_irq_next += i;
-
 	/* replace generic PIH handler (handle_simple_irq) */
 	irq = sih_mod + twl4030_irq_base;
 	irq_set_handler_data(irq, agent);
@@ -686,7 +675,7 @@ int twl4030_sih_setup(int module)
 				      agent->irq_name ?: sih->name, NULL);
 
 	pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", sih->name,
-			irq, irq_base, twl4030_irq_next - 1);
+			irq, irq_base, irq_base + i - 1);
 
 	return status < 0 ? status : irq_base;
 }
@@ -750,12 +739,12 @@ int twl4030_init_irq(struct device *dev, int irq_num)
 		irq_set_nested_thread(i, 1);
 		activate_irq(i);
 	}
-	twl4030_irq_next = i;
+
 	pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", "PIH",
-			irq_num, irq_base, twl4030_irq_next - 1);
+			irq_num, irq_base, irq_end);
 
 	/* ... and the PWR_INT module ... */
-	status = twl4030_sih_setup(TWL4030_MODULE_INT);
+	status = twl4030_sih_setup(dev, TWL4030_MODULE_INT, irq_end);
 	if (status < 0) {
 		pr_err("twl4030: sih_setup PWR INT --> %d\n", status);
 		goto fail;
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index 78d3465..8b9904a 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -751,7 +751,7 @@ struct twl4030_platform_data {
 
 /*----------------------------------------------------------------------*/
 
-int twl4030_sih_setup(int module);
+int twl4030_sih_setup(struct device *dev, int module, int irq_base);
 
 /* Offsets to Power Registers */
 #define TWL4030_VDAC_DEV_GRP		0x3B
-- 
1.7.0.4

[PATCH 06/12] mfd: twl4030-irq: micro-optimization on IRQ handler

From: Benoit Cousson <hidden>
Date: 2012-03-02 16:50:18

From: Felipe Balbi <redacted>

__ffs() will be far faster than the for loop used.

Signed-off-by: Felipe Balbi <redacted>
---
 drivers/mfd/twl4030-irq.c |   14 +++++++-------
 1 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index faf3318..e6dc8f9 100644
--- a/drivers/mfd/twl4030-irq.c
+++ b/drivers/mfd/twl4030-irq.c
@@ -293,7 +293,6 @@ static unsigned twl4030_irq_base;
  */
 static irqreturn_t handle_twl4030_pih(int irq, void *devid)
 {
-	int		module_irq;
 	irqreturn_t	ret;
 	u8		pih_isr;
 
@@ -304,12 +303,13 @@ static irqreturn_t handle_twl4030_pih(int irq, void *devid)
 		return IRQ_NONE;
 	}
 
-	/* these handlers deal with the relevant SIH irq status */
-	for (module_irq = twl4030_irq_base;
-			pih_isr;
-			pih_isr >>= 1, module_irq++) {
-		if (pih_isr & 0x1)
-			handle_nested_irq(module_irq);
+	while (pih_isr) {
+		unsigned long	pending = __ffs(pih_isr);
+		unsigned int	irq;
+
+		pih_isr &= ~BIT(pending);
+		irq = pending + twl4030_irq_base;
+		handle_nested_irq(irq);
 	}
 
 	return IRQ_HANDLED;
-- 
1.7.0.4

[PATCH 07/12] mfd: twl-*: Change from pr_XXX to dev_XXX macros and various cleanups

From: Benoit Cousson <hidden>
Date: 2012-03-02 16:50:19

Since a structure device is available now, use the dev_ macros instead
of the pr_ ones.

Clean some badly formatted comments.
Remove some unused variables.
Move some variable to the place they belong.
Clean some badly wrapped lines.
Align variable definition
Add missing braces in if-then-else block.
Add blank line for better readability.
Move stuff here and there...

Signed-off-by: Benoit Cousson <redacted>
Cc: Felipe Balbi <redacted>
---
 drivers/mfd/twl-core.c    |   32 ++++++++++++++++++--------------
 drivers/mfd/twl4030-irq.c |   23 +++++++++++------------
 drivers/mfd/twl6030-irq.c |   39 +++++++++++++++++++--------------------
 3 files changed, 48 insertions(+), 46 deletions(-)
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 1c1b7d1..9bf14ef 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -1174,17 +1174,15 @@ static int twl_remove(struct i2c_client *client)
 	return 0;
 }
 
-/* NOTE:  this driver only handles a single twl4030/tps659x0 chip */
+/* NOTE: This driver only handles a single twl4030/tps659x0 chip */
 static int __devinit
 twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
-	int				irq_base;
-	int				status;
-	unsigned			i;
 	struct twl4030_platform_data	*pdata = client->dev.platform_data;
 	struct device_node		*node = client->dev.of_node;
-	u8 temp;
-	int ret = 0;
+	int				irq_base = 0;
+	int				status;
+	unsigned			i;
 
 	if (node && !pdata) {
 		/*
@@ -1214,12 +1212,12 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	}
 
 	for (i = 0; i < TWL_NUM_SLAVES; i++) {
-		struct twl_client	*twl = &twl_modules[i];
+		struct twl_client *twl = &twl_modules[i];
 
 		twl->address = client->addr + i;
-		if (i == 0)
+		if (i == 0) {
 			twl->client = client;
-		else {
+		} else {
 			twl->client = i2c_new_dummy(client->adapter,
 					twl->address);
 			if (!twl->client) {
@@ -1231,7 +1229,9 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		}
 		mutex_init(&twl->xfer_lock);
 	}
+
 	inuse = true;
+
 	if ((id->driver_data) & TWL6030_CLASS) {
 		twl_id = TWL6030_CLASS_ID;
 		twl_map = &twl6030_map[0];
@@ -1245,8 +1245,8 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 
 	/* read TWL IDCODE Register */
 	if (twl_id == TWL4030_CLASS_ID) {
-		ret = twl_read_idcode_register();
-		WARN(ret < 0, "Error: reading twl_idcode register value\n");
+		status = twl_read_idcode_register();
+		WARN(status < 0, "Error: reading twl_idcode register value\n");
 	}
 
 	/* load power event scripts */
@@ -1268,19 +1268,22 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		}
 	}
 
-	/* Disable TWL4030/TWL5030 I2C Pull-up on I2C1 and I2C4(SR) interface.
+	/*
+	 * Disable TWL4030/TWL5030 I2C Pull-up on I2C1 and I2C4(SR) interface.
 	 * Program I2C_SCL_CTRL_PU(bit 0)=0, I2C_SDA_CTRL_PU (bit 2)=0,
 	 * SR_I2C_SCL_CTRL_PU(bit 4)=0 and SR_I2C_SDA_CTRL_PU(bit 6)=0.
 	 */
-
 	if (twl_class_is_4030()) {
+		u8 temp;
+
 		twl_i2c_read_u8(TWL4030_MODULE_INTBR, &temp, REG_GPPUPDCTR1);
 		temp &= ~(SR_I2C_SDA_CTRL_PU | SR_I2C_SCL_CTRL_PU | \
-		I2C_SDA_CTRL_PU | I2C_SCL_CTRL_PU);
+			I2C_SDA_CTRL_PU | I2C_SCL_CTRL_PU);
 		twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1);
 	}
 
 	status = -ENODEV;
+
 	if (node)
 		status = of_platform_populate(node, NULL, NULL, &client->dev);
 	if (status)
@@ -1289,6 +1292,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 fail:
 	if (status < 0)
 		twl_remove(client);
+
 	return status;
 }
 
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index e6dc8f9..e523499 100644
--- a/drivers/mfd/twl4030-irq.c
+++ b/drivers/mfd/twl4030-irq.c
@@ -32,7 +32,6 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/slab.h>
-
 #include <linux/of.h>
 #include <linux/irqdomain.h>
 #include <linux/i2c/twl.h>
@@ -625,7 +624,8 @@ static irqreturn_t handle_twl4030_sih(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-/* returns the first IRQ used by this SIH bank,
+/*
+ * returns the first IRQ used by this SIH bank,
  * or negative errno
  */
 int twl4030_sih_setup(struct device *dev, int module, int irq_base)
@@ -637,14 +637,14 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base)
 	int			status = -EINVAL;
 
 	/* only support modules with standard clear-on-read for now */
-	for (sih_mod = 0, sih = sih_modules;
-			sih_mod < nr_sih_modules;
+	for (sih_mod = 0, sih = sih_modules; sih_mod < nr_sih_modules;
 			sih_mod++, sih++) {
 		if (sih->module == module && sih->set_cor) {
 			status = 0;
 			break;
 		}
 	}
+
 	if (status < 0)
 		return status;
 
@@ -674,7 +674,7 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base)
 	status = request_threaded_irq(irq, NULL, handle_twl4030_sih, 0,
 				      agent->irq_name ?: sih->name, NULL);
 
-	pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", sih->name,
+	dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", sih->name,
 			irq, irq_base, irq_base + i - 1);
 
 	return status < 0 ? status : irq_base;
@@ -691,12 +691,10 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base)
 int twl4030_init_irq(struct device *dev, int irq_num)
 {
 	static struct irq_chip	twl4030_irq_chip;
+	int			status, i;
 	int			irq_base, irq_end, nr_irqs;
 	struct			device_node *node = dev->of_node;
 
-	int			status;
-	int			i;
-
 	/*
 	 * TWL core and pwr interrupts must be contiguous because
 	 * the hwirqs numbers are defined contiguously from 1 to 15.
@@ -725,7 +723,8 @@ int twl4030_init_irq(struct device *dev, int irq_num)
 
 	twl4030_irq_base = irq_base;
 
-	/* install an irq handler for each of the SIH modules;
+	/*
+	 * Install an irq handler for each of the SIH modules;
 	 * clone dummy irq_chip since PIH can't *do* anything
 	 */
 	twl4030_irq_chip = dummy_irq_chip;
@@ -740,13 +739,13 @@ int twl4030_init_irq(struct device *dev, int irq_num)
 		activate_irq(i);
 	}
 
-	pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", "PIH",
+	dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", "PIH",
 			irq_num, irq_base, irq_end);
 
 	/* ... and the PWR_INT module ... */
 	status = twl4030_sih_setup(dev, TWL4030_MODULE_INT, irq_end);
 	if (status < 0) {
-		pr_err("twl4030: sih_setup PWR INT --> %d\n", status);
+		dev_err(dev, "sih_setup PWR INT --> %d\n", status);
 		goto fail;
 	}
 
@@ -755,7 +754,7 @@ int twl4030_init_irq(struct device *dev, int irq_num)
 				      IRQF_ONESHOT,
 				      "TWL4030-PIH", NULL);
 	if (status < 0) {
-		pr_err("twl4030: could not claim irq%d: %d\n", irq_num, status);
+		dev_err(dev, "could not claim irq%d: %d\n", irq_num, status);
 		goto fail_rqirq;
 	}
 
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c
index b4d5e0e..a1c7183 100644
--- a/drivers/mfd/twl6030-irq.c
+++ b/drivers/mfd/twl6030-irq.c
@@ -53,7 +53,6 @@
  *
  * We set up IRQs starting@a platform-specified base. An interrupt map table,
  * specifies mapping between interrupt number and the associated module.
- *
  */
 #define TWL6030_NR_IRQS    20
 
@@ -342,14 +341,11 @@ int twl6030_init_irq(struct device *dev, int irq_num)
 {
 	struct			device_node *node = dev->of_node;
 	int			nr_irqs, irq_base, irq_end;
-
-	int	status = 0;
-	int	i;
 	struct task_struct	*task;
-	int ret;
-	u8 mask[4];
-
-	static struct irq_chip	twl6030_irq_chip;
+	static struct irq_chip  twl6030_irq_chip;
+	int			status = 0;
+	int			i;
+	u8			mask[4];
 
 	nr_irqs = TWL6030_NR_IRQS;
 
@@ -367,16 +363,18 @@ int twl6030_init_irq(struct device *dev, int irq_num)
 	mask[1] = 0xFF;
 	mask[2] = 0xFF;
 	mask[3] = 0xFF;
-	ret = twl_i2c_write(TWL_MODULE_PIH, &mask[0],
-			REG_INT_MSK_LINE_A, 3); /* MASK ALL INT LINES */
-	ret = twl_i2c_write(TWL_MODULE_PIH, &mask[0],
-			REG_INT_MSK_STS_A, 3); /* MASK ALL INT STS */
-	ret = twl_i2c_write(TWL_MODULE_PIH, &mask[0],
-			REG_INT_STS_A, 3); /* clear INT_STS_A,B,C */
+
+	/* mask all int lines */
+	twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_LINE_A, 3);
+	/* mask all int sts */
+	twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_STS_A, 3);
+	/* clear INT_STS_A,B,C */
+	twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_STS_A, 3);
 
 	twl6030_irq_base = irq_base;
 
-	/* install an irq handler for each of the modules;
+	/*
+	 * install an irq handler for each of the modules;
 	 * clone dummy irq_chip since PIH can't *do* anything
 	 */
 	twl6030_irq_chip = dummy_irq_chip;
@@ -391,22 +389,22 @@ int twl6030_init_irq(struct device *dev, int irq_num)
 		activate_irq(i);
 	}
 
-	pr_info("twl6030: %s (irq %d) chaining IRQs %d..%d\n", "PIH",
+	dev_info(dev, "PIH (irq %d) chaining IRQs %d..%d\n",
 			irq_num, irq_base, irq_end);
 
 	/* install an irq handler to demultiplex the TWL6030 interrupt */
 	init_completion(&irq_event);
 
-	status = request_irq(irq_num, handle_twl6030_pih, 0,
-				"TWL6030-PIH", &irq_event);
+	status = request_irq(irq_num, handle_twl6030_pih, 0, "TWL6030-PIH",
+			     &irq_event);
 	if (status < 0) {
-		pr_err("twl6030: could not claim irq%d: %d\n", irq_num, status);
+		dev_err(dev, "could not claim irq %d: %d\n", irq_num, status);
 		goto fail_irq;
 	}
 
 	task = kthread_run(twl6030_irq_thread, (void *)irq_num, "twl6030-irq");
 	if (IS_ERR(task)) {
-		pr_err("twl6030: could not create irq %d thread!\n", irq_num);
+		dev_err(dev, "could not create irq %d thread!\n", irq_num);
 		status = PTR_ERR(task);
 		goto fail_kthread;
 	}
@@ -421,6 +419,7 @@ fail_kthread:
 fail_irq:
 	for (i = irq_base; i < irq_end; i++)
 		irq_set_chip_and_handler(i, NULL, NULL);
+
 	return status;
 }
 
-- 
1.7.0.4

[PATCH 08/12] gpio/twl: Allocate irq_desc dynamically for SPARSE_IRQ support

From: Benoit Cousson <hidden>
Date: 2012-03-02 16:50:20

Do not use the board pdata for irq_base, but allocate them dynamically
to allow a proper support of SPARSE_IRQ.

Fix an unneeded line wrap.

Signed-off-by: Benoit Cousson <redacted>
Acked-by: Felipe Balbi <redacted>
---
 drivers/gpio/gpio-twl4030.c |   33 +++++++++++++++++----------------
 1 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c
index 697396c..49e5c6e 100644
--- a/drivers/gpio/gpio-twl4030.c
+++ b/drivers/gpio/gpio-twl4030.c
@@ -395,23 +395,26 @@ static int gpio_twl4030_remove(struct platform_device *pdev);
 static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
 {
 	struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
-	int ret;
+	int ret, irq_base;
 
 	/* maybe setup IRQs */
-	if (pdata->irq_base) {
-		if (is_module()) {
-			dev_err(&pdev->dev,
-				"can't dispatch IRQs from modules\n");
-			goto no_irqs;
-		}
-		ret = twl4030_sih_setup(&pdev->dev, TWL4030_MODULE_GPIO,
-					pdata->irq_base);
-		if (ret < 0)
-			return ret;
-		WARN_ON(ret != pdata->irq_base);
-		twl4030_gpio_irq_base = ret;
+	if (is_module()) {
+		dev_err(&pdev->dev, "can't dispatch IRQs from modules\n");
+		goto no_irqs;
+	}
+
+	irq_base = irq_alloc_descs(-1, 0, TWL4030_GPIO_MAX, 0);
+	if (irq_base < 0) {
+		dev_err(&pdev->dev, "Failed to alloc irq_descs\n");
+		return irq_base;
 	}
 
+	ret = twl4030_sih_setup(&pdev->dev, TWL4030_MODULE_GPIO, irq_base);
+	if (ret < 0)
+		return ret;
+
+	twl4030_gpio_irq_base = irq_base;
+
 no_irqs:
 	/*
 	 * NOTE:  boards may waste power if they don't set pullups
@@ -443,9 +446,7 @@ no_irqs:
 
 	ret = gpiochip_add(&twl_gpiochip);
 	if (ret < 0) {
-		dev_err(&pdev->dev,
-				"could not register gpiochip, %d\n",
-				ret);
+		dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret);
 		twl_gpiochip.ngpio = 0;
 		gpio_twl4030_remove(pdev);
 	} else if (pdata->setup) {
-- 
1.7.0.4

[PATCH 08/12] gpio/twl: Allocate irq_desc dynamically for SPARSE_IRQ support

From: Cousson, Benoit <hidden>
Date: 2012-03-07 12:57:05

Hi Grant,

That fix is tightly coupled with the previous twl4030-irq change, so it 
will be good to pulled it with the twl series through MFD if you are OK 
with that?

Care to ack this one and the next one?

Thanks,
Benoit


On 3/2/2012 5:50 PM, Benoit Cousson wrote:
quoted hunk
Do not use the board pdata for irq_base, but allocate them dynamically
to allow a proper support of SPARSE_IRQ.

Fix an unneeded line wrap.

Signed-off-by: Benoit Cousson<redacted>
Acked-by: Felipe Balbi<redacted>
---
  drivers/gpio/gpio-twl4030.c |   33 +++++++++++++++++----------------
  1 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c
index 697396c..49e5c6e 100644
--- a/drivers/gpio/gpio-twl4030.c
+++ b/drivers/gpio/gpio-twl4030.c
@@ -395,23 +395,26 @@ static int gpio_twl4030_remove(struct platform_device *pdev);
  static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
  {
  	struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
-	int ret;
+	int ret, irq_base;

  	/* maybe setup IRQs */
-	if (pdata->irq_base) {
-		if (is_module()) {
-			dev_err(&pdev->dev,
-				"can't dispatch IRQs from modules\n");
-			goto no_irqs;
-		}
-		ret = twl4030_sih_setup(&pdev->dev, TWL4030_MODULE_GPIO,
-					pdata->irq_base);
-		if (ret<  0)
-			return ret;
-		WARN_ON(ret != pdata->irq_base);
-		twl4030_gpio_irq_base = ret;
+	if (is_module()) {
+		dev_err(&pdev->dev, "can't dispatch IRQs from modules\n");
+		goto no_irqs;
+	}
+
+	irq_base = irq_alloc_descs(-1, 0, TWL4030_GPIO_MAX, 0);
+	if (irq_base<  0) {
+		dev_err(&pdev->dev, "Failed to alloc irq_descs\n");
+		return irq_base;
  	}

+	ret = twl4030_sih_setup(&pdev->dev, TWL4030_MODULE_GPIO, irq_base);
+	if (ret<  0)
+		return ret;
+
+	twl4030_gpio_irq_base = irq_base;
+
  no_irqs:
  	/*
  	 * NOTE:  boards may waste power if they don't set pullups
@@ -443,9 +446,7 @@ no_irqs:

  	ret = gpiochip_add(&twl_gpiochip);
  	if (ret<  0) {
-		dev_err(&pdev->dev,
-				"could not register gpiochip, %d\n",
-				ret);
+		dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret);
  		twl_gpiochip.ngpio = 0;
  		gpio_twl4030_remove(pdev);
  	} else if (pdata->setup) {

[PATCH 08/12] gpio/twl: Allocate irq_desc dynamically for SPARSE_IRQ support

From: Cousson, Benoit <hidden>
Date: 2012-03-09 16:39:32

Hi Grant,

Gentle ping for these patches.

Thanks,
Benoit


On 3/7/2012 1:57 PM, Cousson, Benoit wrote:
Hi Grant,

That fix is tightly coupled with the previous twl4030-irq change, so it
will be good to pulled it with the twl series through MFD if you are OK
with that?

Care to ack this one and the next one?

Thanks,
Benoit


On 3/2/2012 5:50 PM, Benoit Cousson wrote:
quoted
Do not use the board pdata for irq_base, but allocate them dynamically
to allow a proper support of SPARSE_IRQ.

Fix an unneeded line wrap.

Signed-off-by: Benoit Cousson<redacted>
Acked-by: Felipe Balbi<redacted>
---
drivers/gpio/gpio-twl4030.c | 33 +++++++++++++++++----------------
1 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c
index 697396c..49e5c6e 100644
--- a/drivers/gpio/gpio-twl4030.c
+++ b/drivers/gpio/gpio-twl4030.c
@@ -395,23 +395,26 @@ static int gpio_twl4030_remove(struct
platform_device *pdev);
static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
{
struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
- int ret;
+ int ret, irq_base;

/* maybe setup IRQs */
- if (pdata->irq_base) {
- if (is_module()) {
- dev_err(&pdev->dev,
- "can't dispatch IRQs from modules\n");
- goto no_irqs;
- }
- ret = twl4030_sih_setup(&pdev->dev, TWL4030_MODULE_GPIO,
- pdata->irq_base);
- if (ret< 0)
- return ret;
- WARN_ON(ret != pdata->irq_base);
- twl4030_gpio_irq_base = ret;
+ if (is_module()) {
+ dev_err(&pdev->dev, "can't dispatch IRQs from modules\n");
+ goto no_irqs;
+ }
+
+ irq_base = irq_alloc_descs(-1, 0, TWL4030_GPIO_MAX, 0);
+ if (irq_base< 0) {
+ dev_err(&pdev->dev, "Failed to alloc irq_descs\n");
+ return irq_base;
}

+ ret = twl4030_sih_setup(&pdev->dev, TWL4030_MODULE_GPIO, irq_base);
+ if (ret< 0)
+ return ret;
+
+ twl4030_gpio_irq_base = irq_base;
+
no_irqs:
/*
* NOTE: boards may waste power if they don't set pullups
@@ -443,9 +446,7 @@ no_irqs:
ret = gpiochip_add(&twl_gpiochip);
if (ret< 0) {
- dev_err(&pdev->dev,
- "could not register gpiochip, %d\n",
- ret);
+ dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret);
twl_gpiochip.ngpio = 0;
gpio_twl4030_remove(pdev);
} else if (pdata->setup) {
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html

[PATCH 08/12] gpio/twl: Allocate irq_desc dynamically for SPARSE_IRQ support

From: Grant Likely <hidden>
Date: 2012-03-12 17:46:58

On Wed, 7 Mar 2012 13:57:05 +0100, "Cousson, Benoit" [off-list ref] wrote:
Hi Grant,

That fix is tightly coupled with the previous twl4030-irq change, so it 
will be good to pulled it with the twl series through MFD if you are OK 
with that?

Care to ack this one and the next one?

Thanks,
Benoit


On 3/2/2012 5:50 PM, Benoit Cousson wrote:
quoted
Do not use the board pdata for irq_base, but allocate them dynamically
to allow a proper support of SPARSE_IRQ.

Fix an unneeded line wrap.

Signed-off-by: Benoit Cousson<redacted>
Acked-by: Felipe Balbi<redacted>
Acked-by: Grant Likely <redacted>
quoted
---
  drivers/gpio/gpio-twl4030.c |   33 +++++++++++++++++----------------
  1 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c
index 697396c..49e5c6e 100644
--- a/drivers/gpio/gpio-twl4030.c
+++ b/drivers/gpio/gpio-twl4030.c
@@ -395,23 +395,26 @@ static int gpio_twl4030_remove(struct platform_device *pdev);
  static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
  {
  	struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
-	int ret;
+	int ret, irq_base;

  	/* maybe setup IRQs */
-	if (pdata->irq_base) {
-		if (is_module()) {
-			dev_err(&pdev->dev,
-				"can't dispatch IRQs from modules\n");
-			goto no_irqs;
-		}
-		ret = twl4030_sih_setup(&pdev->dev, TWL4030_MODULE_GPIO,
-					pdata->irq_base);
-		if (ret<  0)
-			return ret;
-		WARN_ON(ret != pdata->irq_base);
-		twl4030_gpio_irq_base = ret;
+	if (is_module()) {
+		dev_err(&pdev->dev, "can't dispatch IRQs from modules\n");
+		goto no_irqs;
+	}
+
+	irq_base = irq_alloc_descs(-1, 0, TWL4030_GPIO_MAX, 0);
+	if (irq_base<  0) {
+		dev_err(&pdev->dev, "Failed to alloc irq_descs\n");
+		return irq_base;
  	}

+	ret = twl4030_sih_setup(&pdev->dev, TWL4030_MODULE_GPIO, irq_base);
+	if (ret<  0)
+		return ret;
+
+	twl4030_gpio_irq_base = irq_base;
+
  no_irqs:
  	/*
  	 * NOTE:  boards may waste power if they don't set pullups
@@ -443,9 +446,7 @@ no_irqs:

  	ret = gpiochip_add(&twl_gpiochip);
  	if (ret<  0) {
-		dev_err(&pdev->dev,
-				"could not register gpiochip, %d\n",
-				ret);
+		dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret);
  		twl_gpiochip.ngpio = 0;
  		gpio_twl4030_remove(pdev);
  	} else if (pdata->setup) {
-- 
Grant Likely, B.Sc, P.Eng.
Secret Lab Technologies,Ltd.

[PATCH 09/12] gpio/twl: Add DT support to gpio-twl4030 driver

From: Benoit Cousson <hidden>
Date: 2012-03-02 16:50:21

Add the DT support for the I2C GPIO expander inside the twl4030.

Signed-off-by: Benoit Cousson <redacted>
Acked-by: Felipe Balbi <redacted>
---
 .../devicetree/bindings/gpio/gpio-twl4030.txt      |   23 ++++++
 drivers/gpio/gpio-twl4030.c                        |   79 ++++++++++++-------
 2 files changed, 73 insertions(+), 29 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-twl4030.txt
diff --git a/Documentation/devicetree/bindings/gpio/gpio-twl4030.txt b/Documentation/devicetree/bindings/gpio/gpio-twl4030.txt
new file mode 100644
index 0000000..16695d9
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-twl4030.txt
@@ -0,0 +1,23 @@
+twl4030 GPIO controller bindings
+
+Required properties:
+- compatible:
+  - "ti,twl4030-gpio" for twl4030 GPIO controller
+- #gpio-cells : Should be two.
+  - first cell is the pin number
+  - second cell is used to specify optional parameters (unused)
+- gpio-controller : Marks the device node as a GPIO controller.
+- #interrupt-cells : Should be 2.
+- interrupt-controller: Mark the device node as an interrupt controller
+  The first cell is the GPIO number.
+  The second cell is not used.
+
+Example:
+
+twl_gpio: gpio {
+    compatible = "ti,twl4030-gpio";
+    #gpio-cells = <2>;
+    gpio-controller;
+    #interrupt-cells = <2>;
+    interrupt-controller;
+};
diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c
index 49e5c6e..94256fe 100644
--- a/drivers/gpio/gpio-twl4030.c
+++ b/drivers/gpio/gpio-twl4030.c
@@ -32,6 +32,8 @@
 #include <linux/irq.h>
 #include <linux/gpio.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/irqdomain.h>
 
 #include <linux/i2c/twl.h>
 
@@ -256,7 +258,8 @@ static int twl_request(struct gpio_chip *chip, unsigned offset)
 		 * and vMMC2 power supplies based on card presence.
 		 */
 		pdata = chip->dev->platform_data;
-		value |= pdata->mmc_cd & 0x03;
+		if (pdata)
+			value |= pdata->mmc_cd & 0x03;
 
 		status = gpio_twl4030_write(REG_GPIO_CTRL, value);
 	}
@@ -395,6 +398,7 @@ static int gpio_twl4030_remove(struct platform_device *pdev);
 static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
 {
 	struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
+	struct device_node *node = pdev->dev.of_node;
 	int ret, irq_base;
 
 	/* maybe setup IRQs */
@@ -409,6 +413,9 @@ static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
 		return irq_base;
 	}
 
+	irq_domain_add_legacy(node, TWL4030_GPIO_MAX, irq_base, 0,
+			      &irq_domain_simple_ops, NULL);
+
 	ret = twl4030_sih_setup(&pdev->dev, TWL4030_MODULE_GPIO, irq_base);
 	if (ret < 0)
 		return ret;
@@ -416,40 +423,45 @@ static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
 	twl4030_gpio_irq_base = irq_base;
 
 no_irqs:
-	/*
-	 * NOTE:  boards may waste power if they don't set pullups
-	 * and pulldowns correctly ... default for non-ULPI pins is
-	 * pulldown, and some other pins may have external pullups
-	 * or pulldowns.  Careful!
-	 */
-	ret = gpio_twl4030_pulls(pdata->pullups, pdata->pulldowns);
-	if (ret)
-		dev_dbg(&pdev->dev, "pullups %.05x %.05x --> %d\n",
-				pdata->pullups, pdata->pulldowns,
-				ret);
-
-	ret = gpio_twl4030_debounce(pdata->debounce, pdata->mmc_cd);
-	if (ret)
-		dev_dbg(&pdev->dev, "debounce %.03x %.01x --> %d\n",
-				pdata->debounce, pdata->mmc_cd,
-				ret);
-
-	twl_gpiochip.base = pdata->gpio_base;
+	twl_gpiochip.base = -1;
 	twl_gpiochip.ngpio = TWL4030_GPIO_MAX;
 	twl_gpiochip.dev = &pdev->dev;
 
-	/* NOTE: we assume VIBRA_CTL.VIBRA_EN, in MODULE_AUDIO_VOICE,
-	 * is (still) clear if use_leds is set.
-	 */
-	if (pdata->use_leds)
-		twl_gpiochip.ngpio += 2;
+	if (pdata) {
+		twl_gpiochip.base = pdata->gpio_base;
+
+		/*
+		 * NOTE:  boards may waste power if they don't set pullups
+		 * and pulldowns correctly ... default for non-ULPI pins is
+		 * pulldown, and some other pins may have external pullups
+		 * or pulldowns.  Careful!
+		 */
+		ret = gpio_twl4030_pulls(pdata->pullups, pdata->pulldowns);
+		if (ret)
+			dev_dbg(&pdev->dev, "pullups %.05x %.05x --> %d\n",
+					pdata->pullups, pdata->pulldowns,
+					ret);
+
+		ret = gpio_twl4030_debounce(pdata->debounce, pdata->mmc_cd);
+		if (ret)
+			dev_dbg(&pdev->dev, "debounce %.03x %.01x --> %d\n",
+					pdata->debounce, pdata->mmc_cd,
+					ret);
+
+		/*
+		 * NOTE: we assume VIBRA_CTL.VIBRA_EN, in MODULE_AUDIO_VOICE,
+		 * is (still) clear if use_leds is set.
+		 */
+		if (pdata->use_leds)
+			twl_gpiochip.ngpio += 2;
+	}
 
 	ret = gpiochip_add(&twl_gpiochip);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret);
 		twl_gpiochip.ngpio = 0;
 		gpio_twl4030_remove(pdev);
-	} else if (pdata->setup) {
+	} else if (pdata && pdata->setup) {
 		int status;
 
 		status = pdata->setup(&pdev->dev,
@@ -467,7 +479,7 @@ static int gpio_twl4030_remove(struct platform_device *pdev)
 	struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
 	int status;
 
-	if (pdata->teardown) {
+	if (pdata && pdata->teardown) {
 		status = pdata->teardown(&pdev->dev,
 				pdata->gpio_base, TWL4030_GPIO_MAX);
 		if (status) {
@@ -488,12 +500,21 @@ static int gpio_twl4030_remove(struct platform_device *pdev)
 	return -EIO;
 }
 
+static const struct of_device_id twl_gpio_match[] = {
+	{ .compatible = "ti,twl4030-gpio", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, twl_gpio_match);
+
 /* Note:  this hardware lives inside an I2C-based multi-function device. */
 MODULE_ALIAS("platform:twl4030_gpio");
 
 static struct platform_driver gpio_twl4030_driver = {
-	.driver.name	= "twl4030_gpio",
-	.driver.owner	= THIS_MODULE,
+	.driver = {
+		.name	= "twl4030_gpio",
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(twl_gpio_match),
+	},
 	.probe		= gpio_twl4030_probe,
 	.remove		= gpio_twl4030_remove,
 };
-- 
1.7.0.4

[PATCH 09/12] gpio/twl: Add DT support to gpio-twl4030 driver

From: Grant Likely <hidden>
Date: 2012-03-12 17:48:12

On Fri, 2 Mar 2012 17:50:21 +0100, Benoit Cousson [off-list ref] wrote:
Add the DT support for the I2C GPIO expander inside the twl4030.

Signed-off-by: Benoit Cousson <redacted>
Acked-by: Felipe Balbi <redacted>
Acked-by: Grant Likely <redacted>
quoted hunk
---
 .../devicetree/bindings/gpio/gpio-twl4030.txt      |   23 ++++++
 drivers/gpio/gpio-twl4030.c                        |   79 ++++++++++++-------
 2 files changed, 73 insertions(+), 29 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-twl4030.txt
diff --git a/Documentation/devicetree/bindings/gpio/gpio-twl4030.txt b/Documentation/devicetree/bindings/gpio/gpio-twl4030.txt
new file mode 100644
index 0000000..16695d9
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-twl4030.txt
@@ -0,0 +1,23 @@
+twl4030 GPIO controller bindings
+
+Required properties:
+- compatible:
+  - "ti,twl4030-gpio" for twl4030 GPIO controller
+- #gpio-cells : Should be two.
+  - first cell is the pin number
+  - second cell is used to specify optional parameters (unused)
+- gpio-controller : Marks the device node as a GPIO controller.
+- #interrupt-cells : Should be 2.
+- interrupt-controller: Mark the device node as an interrupt controller
+  The first cell is the GPIO number.
+  The second cell is not used.
+
+Example:
+
+twl_gpio: gpio {
+    compatible = "ti,twl4030-gpio";
+    #gpio-cells = <2>;
+    gpio-controller;
+    #interrupt-cells = <2>;
+    interrupt-controller;
+};
diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c
index 49e5c6e..94256fe 100644
--- a/drivers/gpio/gpio-twl4030.c
+++ b/drivers/gpio/gpio-twl4030.c
@@ -32,6 +32,8 @@
 #include <linux/irq.h>
 #include <linux/gpio.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/irqdomain.h>
 
 #include <linux/i2c/twl.h>
 
@@ -256,7 +258,8 @@ static int twl_request(struct gpio_chip *chip, unsigned offset)
 		 * and vMMC2 power supplies based on card presence.
 		 */
 		pdata = chip->dev->platform_data;
-		value |= pdata->mmc_cd & 0x03;
+		if (pdata)
+			value |= pdata->mmc_cd & 0x03;
 
 		status = gpio_twl4030_write(REG_GPIO_CTRL, value);
 	}
@@ -395,6 +398,7 @@ static int gpio_twl4030_remove(struct platform_device *pdev);
 static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
 {
 	struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
+	struct device_node *node = pdev->dev.of_node;
 	int ret, irq_base;
 
 	/* maybe setup IRQs */
@@ -409,6 +413,9 @@ static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
 		return irq_base;
 	}
 
+	irq_domain_add_legacy(node, TWL4030_GPIO_MAX, irq_base, 0,
+			      &irq_domain_simple_ops, NULL);
+
 	ret = twl4030_sih_setup(&pdev->dev, TWL4030_MODULE_GPIO, irq_base);
 	if (ret < 0)
 		return ret;
@@ -416,40 +423,45 @@ static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
 	twl4030_gpio_irq_base = irq_base;
 
 no_irqs:
-	/*
-	 * NOTE:  boards may waste power if they don't set pullups
-	 * and pulldowns correctly ... default for non-ULPI pins is
-	 * pulldown, and some other pins may have external pullups
-	 * or pulldowns.  Careful!
-	 */
-	ret = gpio_twl4030_pulls(pdata->pullups, pdata->pulldowns);
-	if (ret)
-		dev_dbg(&pdev->dev, "pullups %.05x %.05x --> %d\n",
-				pdata->pullups, pdata->pulldowns,
-				ret);
-
-	ret = gpio_twl4030_debounce(pdata->debounce, pdata->mmc_cd);
-	if (ret)
-		dev_dbg(&pdev->dev, "debounce %.03x %.01x --> %d\n",
-				pdata->debounce, pdata->mmc_cd,
-				ret);
-
-	twl_gpiochip.base = pdata->gpio_base;
+	twl_gpiochip.base = -1;
 	twl_gpiochip.ngpio = TWL4030_GPIO_MAX;
 	twl_gpiochip.dev = &pdev->dev;
 
-	/* NOTE: we assume VIBRA_CTL.VIBRA_EN, in MODULE_AUDIO_VOICE,
-	 * is (still) clear if use_leds is set.
-	 */
-	if (pdata->use_leds)
-		twl_gpiochip.ngpio += 2;
+	if (pdata) {
+		twl_gpiochip.base = pdata->gpio_base;
+
+		/*
+		 * NOTE:  boards may waste power if they don't set pullups
+		 * and pulldowns correctly ... default for non-ULPI pins is
+		 * pulldown, and some other pins may have external pullups
+		 * or pulldowns.  Careful!
+		 */
+		ret = gpio_twl4030_pulls(pdata->pullups, pdata->pulldowns);
+		if (ret)
+			dev_dbg(&pdev->dev, "pullups %.05x %.05x --> %d\n",
+					pdata->pullups, pdata->pulldowns,
+					ret);
+
+		ret = gpio_twl4030_debounce(pdata->debounce, pdata->mmc_cd);
+		if (ret)
+			dev_dbg(&pdev->dev, "debounce %.03x %.01x --> %d\n",
+					pdata->debounce, pdata->mmc_cd,
+					ret);
+
+		/*
+		 * NOTE: we assume VIBRA_CTL.VIBRA_EN, in MODULE_AUDIO_VOICE,
+		 * is (still) clear if use_leds is set.
+		 */
+		if (pdata->use_leds)
+			twl_gpiochip.ngpio += 2;
+	}
 
 	ret = gpiochip_add(&twl_gpiochip);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret);
 		twl_gpiochip.ngpio = 0;
 		gpio_twl4030_remove(pdev);
-	} else if (pdata->setup) {
+	} else if (pdata && pdata->setup) {
 		int status;
 
 		status = pdata->setup(&pdev->dev,
@@ -467,7 +479,7 @@ static int gpio_twl4030_remove(struct platform_device *pdev)
 	struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
 	int status;
 
-	if (pdata->teardown) {
+	if (pdata && pdata->teardown) {
 		status = pdata->teardown(&pdev->dev,
 				pdata->gpio_base, TWL4030_GPIO_MAX);
 		if (status) {
@@ -488,12 +500,21 @@ static int gpio_twl4030_remove(struct platform_device *pdev)
 	return -EIO;
 }
 
+static const struct of_device_id twl_gpio_match[] = {
+	{ .compatible = "ti,twl4030-gpio", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, twl_gpio_match);
+
 /* Note:  this hardware lives inside an I2C-based multi-function device. */
 MODULE_ALIAS("platform:twl4030_gpio");
 
 static struct platform_driver gpio_twl4030_driver = {
-	.driver.name	= "twl4030_gpio",
-	.driver.owner	= THIS_MODULE,
+	.driver = {
+		.name	= "twl4030_gpio",
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(twl_gpio_match),
+	},
 	.probe		= gpio_twl4030_probe,
 	.remove		= gpio_twl4030_remove,
 };
-- 
1.7.0.4
-- 
Grant Likely, B.Sc, P.Eng.
Secret Lab Technologies,Ltd.

[PATCH 10/12] arm/dts: twl4030: Add twl4030-gpio node

From: Benoit Cousson <hidden>
Date: 2012-03-02 16:50:22

Add the twl-gpio node inside twl4030 definition.

Signed-off-by: Benoit Cousson <redacted>
Cc: Felipe Balbi <redacted>
---
 arch/arm/boot/dts/twl4030.dtsi |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/arch/arm/boot/dts/twl4030.dtsi b/arch/arm/boot/dts/twl4030.dtsi
index 8be5223..82a27f4 100644
--- a/arch/arm/boot/dts/twl4030.dtsi
+++ b/arch/arm/boot/dts/twl4030.dtsi
@@ -18,4 +18,12 @@
 		compatible = "ti,twl4030-rtc";
 		interrupts = <11>;
 	};
+
+	twl_gpio: gpio {
+		compatible = "ti,twl4030-gpio";
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
+	};
 };
-- 
1.7.0.4

[PATCH 11/12] mfd: twl4030-irq: Return twl6030_mmc_card_detect IRQ for board setup

From: Benoit Cousson <hidden>
Date: 2012-03-02 16:50:23

Card detect IRQ from the TWL6030 used to be provided to the MMC
controller code using a statically allocated IRQ scheme:

  card_detect_irq = TWL6030_IRQ_BASE + MMCDETECT_INTR_OFFSET;

This is no longer valid in a SPARSE_IRQ context since there is no more
pre-defined TWL6030_IRQ_BASE.

Return the proper card detect IRQ value in the twl6030_mmc_card_detect_config
that will be called from the MMC controller.

Signed-off-by: Benoit Cousson <redacted>
Cc: Felipe Balbi <redacted>
Cc: Tony Lindgren <tony@atomide.com>
Cc: Rajendra Nayak <redacted>
---
 drivers/mfd/twl6030-irq.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c
index a1c7183..4a63de2 100644
--- a/drivers/mfd/twl6030-irq.c
+++ b/drivers/mfd/twl6030-irq.c
@@ -308,7 +308,8 @@ int twl6030_mmc_card_detect_config(void)
 									ret);
 		return ret;
 	}
-	return 0;
+
+	return twl6030_irq_base + MMCDETECT_INTR_OFFSET;
 }
 EXPORT_SYMBOL(twl6030_mmc_card_detect_config);
 
-- 
1.7.0.4

[PATCH 11/12] mfd: twl4030-irq: Return twl6030_mmc_card_detect IRQ for board setup

From: Felipe Balbi <hidden>
Date: 2012-03-02 18:15:23

Hi,

On Fri, Mar 02, 2012 at 05:50:23PM +0100, Benoit Cousson wrote:
Card detect IRQ from the TWL6030 used to be provided to the MMC
controller code using a statically allocated IRQ scheme:

  card_detect_irq = TWL6030_IRQ_BASE + MMCDETECT_INTR_OFFSET;

This is no longer valid in a SPARSE_IRQ context since there is no more
pre-defined TWL6030_IRQ_BASE.

Return the proper card detect IRQ value in the twl6030_mmc_card_detect_config
that will be called from the MMC controller.

Signed-off-by: Benoit Cousson <redacted>
Cc: Felipe Balbi <redacted>
Cc: Tony Lindgren <tony@atomide.com>
Cc: Rajendra Nayak <redacted>
Reviewed-by: Felipe Balbi <redacted>
quoted hunk
---
 drivers/mfd/twl6030-irq.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c
index a1c7183..4a63de2 100644
--- a/drivers/mfd/twl6030-irq.c
+++ b/drivers/mfd/twl6030-irq.c
@@ -308,7 +308,8 @@ int twl6030_mmc_card_detect_config(void)
 									ret);
 		return ret;
 	}
-	return 0;
+
+	return twl6030_irq_base + MMCDETECT_INTR_OFFSET;
 }
 EXPORT_SYMBOL(twl6030_mmc_card_detect_config);
At some point this twl6030_mmc_card_detect_config() needs to vanish in
favor of a better mechanism. Maybe passing the GPIO number an requiring
the driver to request the GPIO, set its direction and use it as IRQ
line.

the only problem would arise if we end up hooking the Card Detect pin to
a real IRQ line, but then we can use a flag to differentiate.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120302/6c7941be/attachment.sig>

[PATCH 11/12] mfd: twl4030-irq: Return twl6030_mmc_card_detect IRQ for board setup

From: tony@atomide.com (Tony Lindgren)
Date: 2012-03-02 19:20:58

* Felipe Balbi [off-list ref] [120302 09:43]:
Hi,

On Fri, Mar 02, 2012 at 05:50:23PM +0100, Benoit Cousson wrote:
quoted
Card detect IRQ from the TWL6030 used to be provided to the MMC
controller code using a statically allocated IRQ scheme:

  card_detect_irq = TWL6030_IRQ_BASE + MMCDETECT_INTR_OFFSET;

This is no longer valid in a SPARSE_IRQ context since there is no more
pre-defined TWL6030_IRQ_BASE.

Return the proper card detect IRQ value in the twl6030_mmc_card_detect_config
that will be called from the MMC controller.

Signed-off-by: Benoit Cousson <redacted>
Cc: Felipe Balbi <redacted>
Cc: Tony Lindgren <tony@atomide.com>
Cc: Rajendra Nayak <redacted>
Reviewed-by: Felipe Balbi <redacted>
quoted
---
 drivers/mfd/twl6030-irq.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c
index a1c7183..4a63de2 100644
--- a/drivers/mfd/twl6030-irq.c
+++ b/drivers/mfd/twl6030-irq.c
@@ -308,7 +308,8 @@ int twl6030_mmc_card_detect_config(void)
 									ret);
 		return ret;
 	}
-	return 0;
+
+	return twl6030_irq_base + MMCDETECT_INTR_OFFSET;
 }
 EXPORT_SYMBOL(twl6030_mmc_card_detect_config);
At some point this twl6030_mmc_card_detect_config() needs to vanish in
favor of a better mechanism. Maybe passing the GPIO number an requiring
the driver to request the GPIO, set its direction and use it as IRQ
line.

the only problem would arise if we end up hooking the Card Detect pin to
a real IRQ line, but then we can use a flag to differentiate.
I'm trying to leave out the need for this callback to pdata..
See mmc: omap_hsmmc: Simplify init for twl6030 MMC card detect
that does pretty much the same as Benoit's patch plus removes
the need for the callback.

Tony

[PATCH 11/12] mfd: twl4030-irq: Return twl6030_mmc_card_detect IRQ for board setup

From: Cousson, Benoit <hidden>
Date: 2012-03-02 20:28:34

Hi Tony,

On 3/2/2012 8:20 PM, Tony Lindgren wrote:
* Felipe Balbi[off-list ref]  [120302 09:43]:
quoted
Hi,

On Fri, Mar 02, 2012 at 05:50:23PM +0100, Benoit Cousson wrote:
quoted
Card detect IRQ from the TWL6030 used to be provided to the MMC
controller code using a statically allocated IRQ scheme:

   card_detect_irq = TWL6030_IRQ_BASE + MMCDETECT_INTR_OFFSET;

This is no longer valid in a SPARSE_IRQ context since there is no more
pre-defined TWL6030_IRQ_BASE.

Return the proper card detect IRQ value in the twl6030_mmc_card_detect_config
that will be called from the MMC controller.

Signed-off-by: Benoit Cousson<redacted>
Cc: Felipe Balbi<redacted>
Cc: Tony Lindgren<tony@atomide.com>
Cc: Rajendra Nayak<redacted>
Reviewed-by: Felipe Balbi<redacted>
quoted
---
  drivers/mfd/twl6030-irq.c |    3 ++-
  1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c
index a1c7183..4a63de2 100644
--- a/drivers/mfd/twl6030-irq.c
+++ b/drivers/mfd/twl6030-irq.c
@@ -308,7 +308,8 @@ int twl6030_mmc_card_detect_config(void)
  									ret);
  		return ret;
  	}
-	return 0;
+
+	return twl6030_irq_base + MMCDETECT_INTR_OFFSET;
  }
  EXPORT_SYMBOL(twl6030_mmc_card_detect_config);
At some point this twl6030_mmc_card_detect_config() needs to vanish in
favor of a better mechanism. Maybe passing the GPIO number an requiring
the driver to request the GPIO, set its direction and use it as IRQ
line.

the only problem would arise if we end up hooking the Card Detect pin to
a real IRQ line, but then we can use a flag to differentiate.
I'm trying to leave out the need for this callback to pdata..
See mmc: omap_hsmmc: Simplify init for twl6030 MMC card detect
that does pretty much the same as Benoit's patch plus removes
the need for the callback.
That's cool. I did that patch to still have a working MMC after my TWL 
series, and I missed your MMC series.

The patch #4 "mmc: omap_hsmmc: Simplify init for twl6030 MMC card 
detect" is indeed simplifying a lot that IRQ mess.

I will check with that TWL series, but since you are already using the 
twl6030_irq_base it should work without any trouble.

Thanks,
Benoit

[PATCH 11/12] mfd: twl4030-irq: Return twl6030_mmc_card_detect IRQ for board setup

From: Cousson, Benoit <hidden>
Date: 2012-03-02 21:38:18

On 3/2/2012 9:28 PM, Cousson, Benoit wrote:
Hi Tony,

On 3/2/2012 8:20 PM, Tony Lindgren wrote:
quoted
* Felipe Balbi[off-list ref] [120302 09:43]:
quoted
Hi,

On Fri, Mar 02, 2012 at 05:50:23PM +0100, Benoit Cousson wrote:
quoted
Card detect IRQ from the TWL6030 used to be provided to the MMC
controller code using a statically allocated IRQ scheme:

card_detect_irq = TWL6030_IRQ_BASE + MMCDETECT_INTR_OFFSET;

This is no longer valid in a SPARSE_IRQ context since there is no more
pre-defined TWL6030_IRQ_BASE.

Return the proper card detect IRQ value in the
twl6030_mmc_card_detect_config
that will be called from the MMC controller.

Signed-off-by: Benoit Cousson<redacted>
Cc: Felipe Balbi<redacted>
Cc: Tony Lindgren<tony@atomide.com>
Cc: Rajendra Nayak<redacted>
Reviewed-by: Felipe Balbi<redacted>
quoted
---
drivers/mfd/twl6030-irq.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c
index a1c7183..4a63de2 100644
--- a/drivers/mfd/twl6030-irq.c
+++ b/drivers/mfd/twl6030-irq.c
@@ -308,7 +308,8 @@ int twl6030_mmc_card_detect_config(void)
ret);
return ret;
}
- return 0;
+
+ return twl6030_irq_base + MMCDETECT_INTR_OFFSET;
}
EXPORT_SYMBOL(twl6030_mmc_card_detect_config);
At some point this twl6030_mmc_card_detect_config() needs to vanish in
favor of a better mechanism. Maybe passing the GPIO number an requiring
the driver to request the GPIO, set its direction and use it as IRQ
line.

the only problem would arise if we end up hooking the Card Detect pin to
a real IRQ line, but then we can use a flag to differentiate.
I'm trying to leave out the need for this callback to pdata..
See mmc: omap_hsmmc: Simplify init for twl6030 MMC card detect
that does pretty much the same as Benoit's patch plus removes
the need for the callback.
That's cool. I did that patch to still have a working MMC after my TWL
series because I missed your MMC series :-(.

The patch #4 "mmc: omap_hsmmc: Simplify init for twl6030 MMC card
detect" is indeed simplifying a lot that IRQ mess.

I will check with that TWL series, but since you are already using the
twl6030_irq_base it should work without any trouble.
I created a for_3.4/twl_irq_gpio_fix branch based on irqdomain/next with 
all the TWL + GPIO patches except the DTS and without the MMC hacks.

And I merged it into your hsmmc-gpio branch. There is a small conflict 
in gpio-twl4030 but otherwise it works on the SDP4430.

I cannot test remotely with Panda or Beagle, the animals are already 
sleeping.

The branch is there if you want to check for OMAP3 as well.
git://git.kernel.org/pub/scm/linux/kernel/git/bcousson/linux-omap-dt.git 
for_3.4/twl_irq_gpio_fix

Regards,
Benoit

[PATCH 11/12] mfd: twl4030-irq: Return twl6030_mmc_card_detect IRQ for board setup

From: tony@atomide.com (Tony Lindgren)
Date: 2012-03-02 21:44:17

* Cousson, Benoit [off-list ref] [120302 13:06]:
I created a for_3.4/twl_irq_gpio_fix branch based on irqdomain/next
with all the TWL + GPIO patches except the DTS and without the MMC
hacks.

And I merged it into your hsmmc-gpio branch. There is a small
conflict in gpio-twl4030 but otherwise it works on the SDP4430.
OK cool.
 
I cannot test remotely with Panda or Beagle, the animals are already
sleeping.

The branch is there if you want to check for OMAP3 as well.
git://git.kernel.org/pub/scm/linux/kernel/git/bcousson/linux-omap-dt.git
for_3.4/twl_irq_gpio_fix
I'll give it a try at some point, looks like there's few more
hsmmc fixes needed first..

Tony

[PATCH 11/12] mfd: twl4030-irq: Return twl6030_mmc_card_detect IRQ for board setup

From: Rajendra Nayak <hidden>
Date: 2012-03-05 08:19:45

On Friday 02 March 2012 11:45 PM, Felipe Balbi wrote:
Hi,

On Fri, Mar 02, 2012 at 05:50:23PM +0100, Benoit Cousson wrote:
quoted
Card detect IRQ from the TWL6030 used to be provided to the MMC
controller code using a statically allocated IRQ scheme:

   card_detect_irq = TWL6030_IRQ_BASE + MMCDETECT_INTR_OFFSET;

This is no longer valid in a SPARSE_IRQ context since there is no more
pre-defined TWL6030_IRQ_BASE.

Return the proper card detect IRQ value in the twl6030_mmc_card_detect_config
that will be called from the MMC controller.

Signed-off-by: Benoit Cousson<redacted>
Cc: Felipe Balbi<redacted>
Cc: Tony Lindgren<tony@atomide.com>
Cc: Rajendra Nayak<redacted>
Reviewed-by: Felipe Balbi<redacted>
quoted
---
  drivers/mfd/twl6030-irq.c |    3 ++-
  1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c
index a1c7183..4a63de2 100644
--- a/drivers/mfd/twl6030-irq.c
+++ b/drivers/mfd/twl6030-irq.c
@@ -308,7 +308,8 @@ int twl6030_mmc_card_detect_config(void)
  									ret);
  		return ret;
  	}
-	return 0;
+
+	return twl6030_irq_base + MMCDETECT_INTR_OFFSET;
  }
  EXPORT_SYMBOL(twl6030_mmc_card_detect_config);
At some point this twl6030_mmc_card_detect_config() needs to vanish in
favor of a better mechanism. Maybe passing the GPIO number an requiring
the driver to request the GPIO, set its direction and use it as IRQ
line.

the only problem would arise if we end up hooking the Card Detect pin to
a real IRQ line, but then we can use a flag to differentiate.
Shouldn't this be hidden from the driver completely if the card detect
pin is a GPIO or connected to a real IRQ line? And the board/DT handle 
this instead of the driver knowing when to do a gpio_to_irq()?
But I see thats not the case with most mmc drivers, not just OMAP, I
wonder why.

[PATCH 11/12] mfd: twl4030-irq: Return twl6030_mmc_card_detect IRQ for board setup

From: Cousson, Benoit <hidden>
Date: 2012-03-05 08:58:37

On 3/5/2012 9:19 AM, Rajendra Nayak wrote:
On Friday 02 March 2012 11:45 PM, Felipe Balbi wrote:
quoted
Hi,

On Fri, Mar 02, 2012 at 05:50:23PM +0100, Benoit Cousson wrote:
quoted
Card detect IRQ from the TWL6030 used to be provided to the MMC
controller code using a statically allocated IRQ scheme:

card_detect_irq = TWL6030_IRQ_BASE + MMCDETECT_INTR_OFFSET;

This is no longer valid in a SPARSE_IRQ context since there is no more
pre-defined TWL6030_IRQ_BASE.

Return the proper card detect IRQ value in the
twl6030_mmc_card_detect_config
that will be called from the MMC controller.

Signed-off-by: Benoit Cousson<redacted>
Cc: Felipe Balbi<redacted>
Cc: Tony Lindgren<tony@atomide.com>
Cc: Rajendra Nayak<redacted>
Reviewed-by: Felipe Balbi<redacted>
quoted
---
drivers/mfd/twl6030-irq.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c
index a1c7183..4a63de2 100644
--- a/drivers/mfd/twl6030-irq.c
+++ b/drivers/mfd/twl6030-irq.c
@@ -308,7 +308,8 @@ int twl6030_mmc_card_detect_config(void)
ret);
return ret;
}
- return 0;
+
+ return twl6030_irq_base + MMCDETECT_INTR_OFFSET;
}
EXPORT_SYMBOL(twl6030_mmc_card_detect_config);
At some point this twl6030_mmc_card_detect_config() needs to vanish in
favor of a better mechanism. Maybe passing the GPIO number an requiring
the driver to request the GPIO, set its direction and use it as IRQ
line.

the only problem would arise if we end up hooking the Card Detect pin to
a real IRQ line, but then we can use a flag to differentiate.
Shouldn't this be hidden from the driver completely if the card detect
pin is a GPIO or connected to a real IRQ line? And the board/DT handle
this instead of the driver knowing when to do a gpio_to_irq()?
It work fine for a pure GPIO, but in this case, this is an IRQ handled 
by twl6030. So I'm not sure we have any API for the non-DT case.

DT will clearly help getting rid of such hacks.

Regards,
Benoit

[PATCH 11/12] mfd: twl4030-irq: Return twl6030_mmc_card_detect IRQ for board setup

From: Sergei Shtylyov <hidden>
Date: 2012-03-03 15:09:13

Hello.

On 02-03-2012 20:50, Benoit Cousson wrote:
Card detect IRQ from the TWL6030 used to be provided to the MMC
controller code using a statically allocated IRQ scheme:

   card_detect_irq = TWL6030_IRQ_BASE + MMCDETECT_INTR_OFFSET;

This is no longer valid in a SPARSE_IRQ context since there is no more
pre-defined TWL6030_IRQ_BASE.

Return the proper card detect IRQ value in the twl6030_mmc_card_detect_config
that will be called from the MMC controller.

Signed-off-by: Benoit Cousson<redacted>
Cc: Felipe Balbi<redacted>
Cc: Tony Lindgren<tony@atomide.com>
Cc: Rajendra Nayak<redacted>
---
  drivers/mfd/twl6030-irq.c |    3 ++-
     Subject talks about twl4030-irq.

WBR, Sergei

[PATCH 11/12] mfd: twl4030-irq: Return twl6030_mmc_card_detect IRQ for board setup

From: Cousson, Benoit <hidden>
Date: 2012-03-05 08:29:54

Hi Sergei,

On 3/3/2012 4:09 PM, Sergei Shtylyov wrote:
Hello.

On 02-03-2012 20:50, Benoit Cousson wrote:
quoted
Card detect IRQ from the TWL6030 used to be provided to the MMC
quoted
controller code using a statically allocated IRQ scheme:

card_detect_irq = TWL6030_IRQ_BASE + MMCDETECT_INTR_OFFSET;

This is no longer valid in a SPARSE_IRQ context since there is no more
pre-defined TWL6030_IRQ_BASE.

Return the proper card detect IRQ value in the
twl6030_mmc_card_detect_config
that will be called from the MMC controller.

Signed-off-by: Benoit Cousson<redacted>
Cc: Felipe Balbi<redacted>
Cc: Tony Lindgren<tony@atomide.com>
Cc: Rajendra Nayak<redacted>
---
drivers/mfd/twl6030-irq.c | 3 ++-
Subject talks about twl4030-irq.
Oops, good catch. thanks.

I guess that Tony's patch (mmc: omap_hsmmc: Simplify init for twl6030 
MMC card detect) will supersede that one.

Thanks,
Benoit

[PATCH 12/12] ARM: OMAP2+: board-omap4-*: Do not use anymore TWL6030_IRQ_BASE in board files

From: Benoit Cousson <hidden>
Date: 2012-03-02 16:50:24

With the introduction of dynamically allocated IRQ in the twl6030 driver,
the board files can no longer rely of static IRQ defines like before.

Retrieve the value dynamically allocated from the mmc -> twl6030 init
callback.

Note: The Panda board does not seems to use the card detect IRQ.

Signed-off-by: Benoit Cousson <redacted>
Cc: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap2/board-4430sdp.c    |   13 +++++++------
 arch/arm/mach-omap2/board-omap4panda.c |   15 ++++++++-------
 2 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 4e90715..79c4eba 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -457,21 +457,22 @@ static struct platform_device omap_vwlan_device = {
 
 static int omap4_twl6030_hsmmc_late_init(struct device *dev)
 {
-	int ret = 0;
+	int irq = 0;
 	struct platform_device *pdev = container_of(dev,
 				struct platform_device, dev);
 	struct omap_mmc_platform_data *pdata = dev->platform_data;
 
 	/* Setting MMC1 Card detect Irq */
 	if (pdev->id == 0) {
-		ret = twl6030_mmc_card_detect_config();
-		if (ret)
+		irq = twl6030_mmc_card_detect_config();
+		if (irq < 0) {
 			pr_err("Failed configuring MMC1 card detect\n");
-		pdata->slots[0].card_detect_irq = TWL6030_IRQ_BASE +
-						MMCDETECT_INTR_OFFSET;
+			return irq;
+		}
+		pdata->slots[0].card_detect_irq = irq;
 		pdata->slots[0].card_detect = twl6030_mmc_card_detect;
 	}
-	return ret;
+	return 0;
 }
 
 static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 28fc271..297f30b 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -206,7 +206,7 @@ struct wl12xx_platform_data omap_panda_wlan_data  __initdata = {
 
 static int omap4_twl6030_hsmmc_late_init(struct device *dev)
 {
-	int ret = 0;
+	int irq = 0;
 	struct platform_device *pdev = container_of(dev,
 				struct platform_device, dev);
 	struct omap_mmc_platform_data *pdata = dev->platform_data;
@@ -217,14 +217,15 @@ static int omap4_twl6030_hsmmc_late_init(struct device *dev)
 	}
 	/* Setting MMC1 Card detect Irq */
 	if (pdev->id == 0) {
-		ret = twl6030_mmc_card_detect_config();
-		 if (ret)
+		irq = twl6030_mmc_card_detect_config();
+		if (irq < 0) {
 			dev_err(dev, "%s: Error card detect config(%d)\n",
-				__func__, ret);
-		 else
-			pdata->slots[0].card_detect = twl6030_mmc_card_detect;
+				__func__, irq);
+			return irq;
+		}
+		pdata->slots[0].card_detect = twl6030_mmc_card_detect;
 	}
-	return ret;
+	return 0;
 }
 
 static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
-- 
1.7.0.4

[PATCH 12/12] ARM: OMAP2+: board-omap4-*: Do not use anymore TWL6030_IRQ_BASE in board files

From: tony@atomide.com (Tony Lindgren)
Date: 2012-03-13 17:07:57

* Benoit Cousson [off-list ref] [120302 08:19]:
With the introduction of dynamically allocated IRQ in the twl6030 driver,
the board files can no longer rely of static IRQ defines like before.

Retrieve the value dynamically allocated from the mmc -> twl6030 init
callback.

Note: The Panda board does not seems to use the card detect IRQ.
Looks like this one is safe to merge via MFD and does not seem to
cause any merge conflicts.

This one should be folded into patch 08/12 to avoid boot issues
for between patches 08 and 12 in this series. Other than that:

Acked-by: Tony Lindgren <tony@atomide.com>

[PATCH 12/12] ARM: OMAP2+: board-omap4-*: Do not use anymore TWL6030_IRQ_BASE in board files

From: Cousson, Benoit <hidden>
Date: 2012-03-13 21:35:22

On 3/13/2012 6:07 PM, Tony Lindgren wrote:
* Benoit Cousson[off-list ref]  [120302 08:19]:
quoted
With the introduction of dynamically allocated IRQ in the twl6030 driver,
the board files can no longer rely of static IRQ defines like before.

Retrieve the value dynamically allocated from the mmc ->  twl6030 init
callback.

Note: The Panda board does not seems to use the card detect IRQ.
Looks like this one is safe to merge via MFD and does not seem to
cause any merge conflicts.

This one should be folded into patch 08/12 to avoid boot issues
for between patches 08 and 12 in this series. Other than that:
In fact there is no need to merge them. They should just be at the 
beginning of the series.

The first patch...
  mfd: twl6030-irq: Return twl6030_mmc_card_detect IRQ for board setup

-       return 0;
+
+       return twl6030_irq_base + MMCDETECT_INTR_OFFSET;

...will just return the proper interrupt number instead of 0, but at 
that time, the board is still using the static TWL6030_IRQ_BASE + 
MMCDETECT_INTR_OFFSET value.

Only the next one...
  ARM: OMAP2+: board-omap4-*: Do not use anymore TWL6030_IRQ_BASE in 
board files
...will switch from the static to the value returned by 
twl6030_mmc_card_detect and then it keeps working.
Acked-by: Tony Lindgren<tony@atomide.com>
Cool, I'll send the pull request to Samuel ASAP.

Thanks,
Benoit

[PATCH 07/12] mfd: twl-*: Replace pr_ macros by the dev_ equivalent and do various cleanups

From: Benoit Cousson <hidden>
Date: 2012-03-02 20:33:44

Since a structure device is available now, use the dev_ macros instead
of the pr_ ones.

Clean some badly formatted comments.
Remove some unused variables.
Move some variable to the place they belong.
Clean some badly wrapped lines.
Align variable definition
Add missing braces in if-then-else block.
Add blank line for better readability.
Move stuff here and there...

Signed-off-by: Benoit Cousson <redacted>
Cc: Felipe Balbi <redacted>
---
 drivers/mfd/twl-core.c    |   32 ++++++++++++++++++--------------
 drivers/mfd/twl4030-irq.c |   23 +++++++++++------------
 drivers/mfd/twl6030-irq.c |   39 +++++++++++++++++++--------------------
 3 files changed, 48 insertions(+), 46 deletions(-)
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 1c1b7d1..9bf14ef 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -1174,17 +1174,15 @@ static int twl_remove(struct i2c_client *client)
 	return 0;
 }
 
-/* NOTE:  this driver only handles a single twl4030/tps659x0 chip */
+/* NOTE: This driver only handles a single twl4030/tps659x0 chip */
 static int __devinit
 twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
-	int				irq_base;
-	int				status;
-	unsigned			i;
 	struct twl4030_platform_data	*pdata = client->dev.platform_data;
 	struct device_node		*node = client->dev.of_node;
-	u8 temp;
-	int ret = 0;
+	int				irq_base = 0;
+	int				status;
+	unsigned			i;
 
 	if (node && !pdata) {
 		/*
@@ -1214,12 +1212,12 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	}
 
 	for (i = 0; i < TWL_NUM_SLAVES; i++) {
-		struct twl_client	*twl = &twl_modules[i];
+		struct twl_client *twl = &twl_modules[i];
 
 		twl->address = client->addr + i;
-		if (i == 0)
+		if (i == 0) {
 			twl->client = client;
-		else {
+		} else {
 			twl->client = i2c_new_dummy(client->adapter,
 					twl->address);
 			if (!twl->client) {
@@ -1231,7 +1229,9 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		}
 		mutex_init(&twl->xfer_lock);
 	}
+
 	inuse = true;
+
 	if ((id->driver_data) & TWL6030_CLASS) {
 		twl_id = TWL6030_CLASS_ID;
 		twl_map = &twl6030_map[0];
@@ -1245,8 +1245,8 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 
 	/* read TWL IDCODE Register */
 	if (twl_id == TWL4030_CLASS_ID) {
-		ret = twl_read_idcode_register();
-		WARN(ret < 0, "Error: reading twl_idcode register value\n");
+		status = twl_read_idcode_register();
+		WARN(status < 0, "Error: reading twl_idcode register value\n");
 	}
 
 	/* load power event scripts */
@@ -1268,19 +1268,22 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		}
 	}
 
-	/* Disable TWL4030/TWL5030 I2C Pull-up on I2C1 and I2C4(SR) interface.
+	/*
+	 * Disable TWL4030/TWL5030 I2C Pull-up on I2C1 and I2C4(SR) interface.
 	 * Program I2C_SCL_CTRL_PU(bit 0)=0, I2C_SDA_CTRL_PU (bit 2)=0,
 	 * SR_I2C_SCL_CTRL_PU(bit 4)=0 and SR_I2C_SDA_CTRL_PU(bit 6)=0.
 	 */
-
 	if (twl_class_is_4030()) {
+		u8 temp;
+
 		twl_i2c_read_u8(TWL4030_MODULE_INTBR, &temp, REG_GPPUPDCTR1);
 		temp &= ~(SR_I2C_SDA_CTRL_PU | SR_I2C_SCL_CTRL_PU | \
-		I2C_SDA_CTRL_PU | I2C_SCL_CTRL_PU);
+			I2C_SDA_CTRL_PU | I2C_SCL_CTRL_PU);
 		twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1);
 	}
 
 	status = -ENODEV;
+
 	if (node)
 		status = of_platform_populate(node, NULL, NULL, &client->dev);
 	if (status)
@@ -1289,6 +1292,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 fail:
 	if (status < 0)
 		twl_remove(client);
+
 	return status;
 }
 
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index e6dc8f9..e523499 100644
--- a/drivers/mfd/twl4030-irq.c
+++ b/drivers/mfd/twl4030-irq.c
@@ -32,7 +32,6 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/slab.h>
-
 #include <linux/of.h>
 #include <linux/irqdomain.h>
 #include <linux/i2c/twl.h>
@@ -625,7 +624,8 @@ static irqreturn_t handle_twl4030_sih(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-/* returns the first IRQ used by this SIH bank,
+/*
+ * returns the first IRQ used by this SIH bank,
  * or negative errno
  */
 int twl4030_sih_setup(struct device *dev, int module, int irq_base)
@@ -637,14 +637,14 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base)
 	int			status = -EINVAL;
 
 	/* only support modules with standard clear-on-read for now */
-	for (sih_mod = 0, sih = sih_modules;
-			sih_mod < nr_sih_modules;
+	for (sih_mod = 0, sih = sih_modules; sih_mod < nr_sih_modules;
 			sih_mod++, sih++) {
 		if (sih->module == module && sih->set_cor) {
 			status = 0;
 			break;
 		}
 	}
+
 	if (status < 0)
 		return status;
 
@@ -674,7 +674,7 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base)
 	status = request_threaded_irq(irq, NULL, handle_twl4030_sih, 0,
 				      agent->irq_name ?: sih->name, NULL);
 
-	pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", sih->name,
+	dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", sih->name,
 			irq, irq_base, irq_base + i - 1);
 
 	return status < 0 ? status : irq_base;
@@ -691,12 +691,10 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base)
 int twl4030_init_irq(struct device *dev, int irq_num)
 {
 	static struct irq_chip	twl4030_irq_chip;
+	int			status, i;
 	int			irq_base, irq_end, nr_irqs;
 	struct			device_node *node = dev->of_node;
 
-	int			status;
-	int			i;
-
 	/*
 	 * TWL core and pwr interrupts must be contiguous because
 	 * the hwirqs numbers are defined contiguously from 1 to 15.
@@ -725,7 +723,8 @@ int twl4030_init_irq(struct device *dev, int irq_num)
 
 	twl4030_irq_base = irq_base;
 
-	/* install an irq handler for each of the SIH modules;
+	/*
+	 * Install an irq handler for each of the SIH modules;
 	 * clone dummy irq_chip since PIH can't *do* anything
 	 */
 	twl4030_irq_chip = dummy_irq_chip;
@@ -740,13 +739,13 @@ int twl4030_init_irq(struct device *dev, int irq_num)
 		activate_irq(i);
 	}
 
-	pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", "PIH",
+	dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", "PIH",
 			irq_num, irq_base, irq_end);
 
 	/* ... and the PWR_INT module ... */
 	status = twl4030_sih_setup(dev, TWL4030_MODULE_INT, irq_end);
 	if (status < 0) {
-		pr_err("twl4030: sih_setup PWR INT --> %d\n", status);
+		dev_err(dev, "sih_setup PWR INT --> %d\n", status);
 		goto fail;
 	}
 
@@ -755,7 +754,7 @@ int twl4030_init_irq(struct device *dev, int irq_num)
 				      IRQF_ONESHOT,
 				      "TWL4030-PIH", NULL);
 	if (status < 0) {
-		pr_err("twl4030: could not claim irq%d: %d\n", irq_num, status);
+		dev_err(dev, "could not claim irq%d: %d\n", irq_num, status);
 		goto fail_rqirq;
 	}
 
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c
index b4d5e0e..a1c7183 100644
--- a/drivers/mfd/twl6030-irq.c
+++ b/drivers/mfd/twl6030-irq.c
@@ -53,7 +53,6 @@
  *
  * We set up IRQs starting@a platform-specified base. An interrupt map table,
  * specifies mapping between interrupt number and the associated module.
- *
  */
 #define TWL6030_NR_IRQS    20
 
@@ -342,14 +341,11 @@ int twl6030_init_irq(struct device *dev, int irq_num)
 {
 	struct			device_node *node = dev->of_node;
 	int			nr_irqs, irq_base, irq_end;
-
-	int	status = 0;
-	int	i;
 	struct task_struct	*task;
-	int ret;
-	u8 mask[4];
-
-	static struct irq_chip	twl6030_irq_chip;
+	static struct irq_chip  twl6030_irq_chip;
+	int			status = 0;
+	int			i;
+	u8			mask[4];
 
 	nr_irqs = TWL6030_NR_IRQS;
 
@@ -367,16 +363,18 @@ int twl6030_init_irq(struct device *dev, int irq_num)
 	mask[1] = 0xFF;
 	mask[2] = 0xFF;
 	mask[3] = 0xFF;
-	ret = twl_i2c_write(TWL_MODULE_PIH, &mask[0],
-			REG_INT_MSK_LINE_A, 3); /* MASK ALL INT LINES */
-	ret = twl_i2c_write(TWL_MODULE_PIH, &mask[0],
-			REG_INT_MSK_STS_A, 3); /* MASK ALL INT STS */
-	ret = twl_i2c_write(TWL_MODULE_PIH, &mask[0],
-			REG_INT_STS_A, 3); /* clear INT_STS_A,B,C */
+
+	/* mask all int lines */
+	twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_LINE_A, 3);
+	/* mask all int sts */
+	twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_STS_A, 3);
+	/* clear INT_STS_A,B,C */
+	twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_STS_A, 3);
 
 	twl6030_irq_base = irq_base;
 
-	/* install an irq handler for each of the modules;
+	/*
+	 * install an irq handler for each of the modules;
 	 * clone dummy irq_chip since PIH can't *do* anything
 	 */
 	twl6030_irq_chip = dummy_irq_chip;
@@ -391,22 +389,22 @@ int twl6030_init_irq(struct device *dev, int irq_num)
 		activate_irq(i);
 	}
 
-	pr_info("twl6030: %s (irq %d) chaining IRQs %d..%d\n", "PIH",
+	dev_info(dev, "PIH (irq %d) chaining IRQs %d..%d\n",
 			irq_num, irq_base, irq_end);
 
 	/* install an irq handler to demultiplex the TWL6030 interrupt */
 	init_completion(&irq_event);
 
-	status = request_irq(irq_num, handle_twl6030_pih, 0,
-				"TWL6030-PIH", &irq_event);
+	status = request_irq(irq_num, handle_twl6030_pih, 0, "TWL6030-PIH",
+			     &irq_event);
 	if (status < 0) {
-		pr_err("twl6030: could not claim irq%d: %d\n", irq_num, status);
+		dev_err(dev, "could not claim irq %d: %d\n", irq_num, status);
 		goto fail_irq;
 	}
 
 	task = kthread_run(twl6030_irq_thread, (void *)irq_num, "twl6030-irq");
 	if (IS_ERR(task)) {
-		pr_err("twl6030: could not create irq %d thread!\n", irq_num);
+		dev_err(dev, "could not create irq %d thread!\n", irq_num);
 		status = PTR_ERR(task);
 		goto fail_kthread;
 	}
@@ -421,6 +419,7 @@ fail_kthread:
 fail_irq:
 	for (i = irq_base; i < irq_end; i++)
 		irq_set_chip_and_handler(i, NULL, NULL);
+
 	return status;
 }
 
-- 
1.7.0.4

[PATCH 07/12] mfd: twl-*: Replace pr_ macros by the dev_ equivalent and do various cleanups

From: Cousson, Benoit <hidden>
Date: 2012-03-02 20:49:25

For people who were really impatient to get that patch #7, here is the 
reason it was rejected...

vger.kernel.org #<vger.kernel.org #5.7.1 SMTP; 550 5.7.1 Content-Policy 
reject msg: The capital Triple-X in subject is way too often associated 
with junk email, please rephrase. BF:<H 0>; S1758911Ab2CBQvf> #SMTP#

The original subject was indeed using a *double* Triple-X...
   mfd: twl-*: Change from pr_XXX to dev_XXX macros and various cleanups

Definitively too nasty for linux-omap mailing list...

I'm really glad vger.kernel.org is taking care of the ethics of the 
patches :-)

Regards,
Benoit


On 3/2/2012 9:33 PM, Benoit Cousson wrote:
quoted hunk
Since a structure device is available now, use the dev_ macros instead
of the pr_ ones.

Clean some badly formatted comments.
Remove some unused variables.
Move some variable to the place they belong.
Clean some badly wrapped lines.
Align variable definition
Add missing braces in if-then-else block.
Add blank line for better readability.
Move stuff here and there...

Signed-off-by: Benoit Cousson<redacted>
Cc: Felipe Balbi<redacted>
---
  drivers/mfd/twl-core.c    |   32 ++++++++++++++++++--------------
  drivers/mfd/twl4030-irq.c |   23 +++++++++++------------
  drivers/mfd/twl6030-irq.c |   39 +++++++++++++++++++--------------------
  3 files changed, 48 insertions(+), 46 deletions(-)
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 1c1b7d1..9bf14ef 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -1174,17 +1174,15 @@ static int twl_remove(struct i2c_client *client)
  	return 0;
  }

-/* NOTE:  this driver only handles a single twl4030/tps659x0 chip */
+/* NOTE: This driver only handles a single twl4030/tps659x0 chip */
  static int __devinit
  twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
  {
-	int				irq_base;
-	int				status;
-	unsigned			i;
  	struct twl4030_platform_data	*pdata = client->dev.platform_data;
  	struct device_node		*node = client->dev.of_node;
-	u8 temp;
-	int ret = 0;
+	int				irq_base = 0;
+	int				status;
+	unsigned			i;

  	if (node&&  !pdata) {
  		/*
@@ -1214,12 +1212,12 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
  	}

  	for (i = 0; i<  TWL_NUM_SLAVES; i++) {
-		struct twl_client	*twl =&twl_modules[i];
+		struct twl_client *twl =&twl_modules[i];

  		twl->address = client->addr + i;
-		if (i == 0)
+		if (i == 0) {
  			twl->client = client;
-		else {
+		} else {
  			twl->client = i2c_new_dummy(client->adapter,
  					twl->address);
  			if (!twl->client) {
@@ -1231,7 +1229,9 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
  		}
  		mutex_init(&twl->xfer_lock);
  	}
+
  	inuse = true;
+
  	if ((id->driver_data)&  TWL6030_CLASS) {
  		twl_id = TWL6030_CLASS_ID;
  		twl_map =&twl6030_map[0];
@@ -1245,8 +1245,8 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)

  	/* read TWL IDCODE Register */
  	if (twl_id == TWL4030_CLASS_ID) {
-		ret = twl_read_idcode_register();
-		WARN(ret<  0, "Error: reading twl_idcode register value\n");
+		status = twl_read_idcode_register();
+		WARN(status<  0, "Error: reading twl_idcode register value\n");
  	}

  	/* load power event scripts */
@@ -1268,19 +1268,22 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
  		}
  	}

-	/* Disable TWL4030/TWL5030 I2C Pull-up on I2C1 and I2C4(SR) interface.
+	/*
+	 * Disable TWL4030/TWL5030 I2C Pull-up on I2C1 and I2C4(SR) interface.
  	 * Program I2C_SCL_CTRL_PU(bit 0)=0, I2C_SDA_CTRL_PU (bit 2)=0,
  	 * SR_I2C_SCL_CTRL_PU(bit 4)=0 and SR_I2C_SDA_CTRL_PU(bit 6)=0.
  	 */
-
  	if (twl_class_is_4030()) {
+		u8 temp;
+
  		twl_i2c_read_u8(TWL4030_MODULE_INTBR,&temp, REG_GPPUPDCTR1);
  		temp&= ~(SR_I2C_SDA_CTRL_PU | SR_I2C_SCL_CTRL_PU | \
-		I2C_SDA_CTRL_PU | I2C_SCL_CTRL_PU);
+			I2C_SDA_CTRL_PU | I2C_SCL_CTRL_PU);
  		twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1);
  	}

  	status = -ENODEV;
+
  	if (node)
  		status = of_platform_populate(node, NULL, NULL,&client->dev);
  	if (status)
@@ -1289,6 +1292,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
  fail:
  	if (status<  0)
  		twl_remove(client);
+
  	return status;
  }
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index e6dc8f9..e523499 100644
--- a/drivers/mfd/twl4030-irq.c
+++ b/drivers/mfd/twl4030-irq.c
@@ -32,7 +32,6 @@
  #include<linux/interrupt.h>
  #include<linux/irq.h>
  #include<linux/slab.h>
-
  #include<linux/of.h>
  #include<linux/irqdomain.h>
  #include<linux/i2c/twl.h>
@@ -625,7 +624,8 @@ static irqreturn_t handle_twl4030_sih(int irq, void *data)
  	return IRQ_HANDLED;
  }

-/* returns the first IRQ used by this SIH bank,
+/*
+ * returns the first IRQ used by this SIH bank,
   * or negative errno
   */
  int twl4030_sih_setup(struct device *dev, int module, int irq_base)
@@ -637,14 +637,14 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base)
  	int			status = -EINVAL;

  	/* only support modules with standard clear-on-read for now */
-	for (sih_mod = 0, sih = sih_modules;
-			sih_mod<  nr_sih_modules;
+	for (sih_mod = 0, sih = sih_modules; sih_mod<  nr_sih_modules;
  			sih_mod++, sih++) {
  		if (sih->module == module&&  sih->set_cor) {
  			status = 0;
  			break;
  		}
  	}
+
  	if (status<  0)
  		return status;
@@ -674,7 +674,7 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base)
  	status = request_threaded_irq(irq, NULL, handle_twl4030_sih, 0,
  				      agent->irq_name ?: sih->name, NULL);

-	pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", sih->name,
+	dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", sih->name,
  			irq, irq_base, irq_base + i - 1);

  	return status<  0 ? status : irq_base;
@@ -691,12 +691,10 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base)
  int twl4030_init_irq(struct device *dev, int irq_num)
  {
  	static struct irq_chip	twl4030_irq_chip;
+	int			status, i;
  	int			irq_base, irq_end, nr_irqs;
  	struct			device_node *node = dev->of_node;

-	int			status;
-	int			i;
-
  	/*
  	 * TWL core and pwr interrupts must be contiguous because
  	 * the hwirqs numbers are defined contiguously from 1 to 15.
@@ -725,7 +723,8 @@ int twl4030_init_irq(struct device *dev, int irq_num)

  	twl4030_irq_base = irq_base;

-	/* install an irq handler for each of the SIH modules;
+	/*
+	 * Install an irq handler for each of the SIH modules;
  	 * clone dummy irq_chip since PIH can't *do* anything
  	 */
  	twl4030_irq_chip = dummy_irq_chip;
@@ -740,13 +739,13 @@ int twl4030_init_irq(struct device *dev, int irq_num)
  		activate_irq(i);
  	}

-	pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", "PIH",
+	dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", "PIH",
  			irq_num, irq_base, irq_end);

  	/* ... and the PWR_INT module ... */
  	status = twl4030_sih_setup(dev, TWL4030_MODULE_INT, irq_end);
  	if (status<  0) {
-		pr_err("twl4030: sih_setup PWR INT -->  %d\n", status);
+		dev_err(dev, "sih_setup PWR INT -->  %d\n", status);
  		goto fail;
  	}
@@ -755,7 +754,7 @@ int twl4030_init_irq(struct device *dev, int irq_num)
  				      IRQF_ONESHOT,
  				      "TWL4030-PIH", NULL);
  	if (status<  0) {
-		pr_err("twl4030: could not claim irq%d: %d\n", irq_num, status);
+		dev_err(dev, "could not claim irq%d: %d\n", irq_num, status);
  		goto fail_rqirq;
  	}
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c
index b4d5e0e..a1c7183 100644
--- a/drivers/mfd/twl6030-irq.c
+++ b/drivers/mfd/twl6030-irq.c
@@ -53,7 +53,6 @@
   *
   * We set up IRQs starting at a platform-specified base. An interrupt map table,
   * specifies mapping between interrupt number and the associated module.
- *
   */
  #define TWL6030_NR_IRQS    20
@@ -342,14 +341,11 @@ int twl6030_init_irq(struct device *dev, int irq_num)
  {
  	struct			device_node *node = dev->of_node;
  	int			nr_irqs, irq_base, irq_end;
-
-	int	status = 0;
-	int	i;
  	struct task_struct	*task;
-	int ret;
-	u8 mask[4];
-
-	static struct irq_chip	twl6030_irq_chip;
+	static struct irq_chip  twl6030_irq_chip;
+	int			status = 0;
+	int			i;
+	u8			mask[4];

  	nr_irqs = TWL6030_NR_IRQS;
@@ -367,16 +363,18 @@ int twl6030_init_irq(struct device *dev, int irq_num)
  	mask[1] = 0xFF;
  	mask[2] = 0xFF;
  	mask[3] = 0xFF;
-	ret = twl_i2c_write(TWL_MODULE_PIH,&mask[0],
-			REG_INT_MSK_LINE_A, 3); /* MASK ALL INT LINES */
-	ret = twl_i2c_write(TWL_MODULE_PIH,&mask[0],
-			REG_INT_MSK_STS_A, 3); /* MASK ALL INT STS */
-	ret = twl_i2c_write(TWL_MODULE_PIH,&mask[0],
-			REG_INT_STS_A, 3); /* clear INT_STS_A,B,C */
+
+	/* mask all int lines */
+	twl_i2c_write(TWL_MODULE_PIH,&mask[0], REG_INT_MSK_LINE_A, 3);
+	/* mask all int sts */
+	twl_i2c_write(TWL_MODULE_PIH,&mask[0], REG_INT_MSK_STS_A, 3);
+	/* clear INT_STS_A,B,C */
+	twl_i2c_write(TWL_MODULE_PIH,&mask[0], REG_INT_STS_A, 3);

  	twl6030_irq_base = irq_base;

-	/* install an irq handler for each of the modules;
+	/*
+	 * install an irq handler for each of the modules;
  	 * clone dummy irq_chip since PIH can't *do* anything
  	 */
  	twl6030_irq_chip = dummy_irq_chip;
@@ -391,22 +389,22 @@ int twl6030_init_irq(struct device *dev, int irq_num)
  		activate_irq(i);
  	}

-	pr_info("twl6030: %s (irq %d) chaining IRQs %d..%d\n", "PIH",
+	dev_info(dev, "PIH (irq %d) chaining IRQs %d..%d\n",
  			irq_num, irq_base, irq_end);

  	/* install an irq handler to demultiplex the TWL6030 interrupt */
  	init_completion(&irq_event);

-	status = request_irq(irq_num, handle_twl6030_pih, 0,
-				"TWL6030-PIH",&irq_event);
+	status = request_irq(irq_num, handle_twl6030_pih, 0, "TWL6030-PIH",
+			&irq_event);
  	if (status<  0) {
-		pr_err("twl6030: could not claim irq%d: %d\n", irq_num, status);
+		dev_err(dev, "could not claim irq %d: %d\n", irq_num, status);
  		goto fail_irq;
  	}

  	task = kthread_run(twl6030_irq_thread, (void *)irq_num, "twl6030-irq");
  	if (IS_ERR(task)) {
-		pr_err("twl6030: could not create irq %d thread!\n", irq_num);
+		dev_err(dev, "could not create irq %d thread!\n", irq_num);
  		status = PTR_ERR(task);
  		goto fail_kthread;
  	}
@@ -421,6 +419,7 @@ fail_kthread:
  fail_irq:
  	for (i = irq_base; i<  irq_end; i++)
  		irq_set_chip_and_handler(i, NULL, NULL);
+
  	return status;
  }
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help