All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] Pending Wolfson patches
@ 2011-06-02 18:18 Mark Brown
  2011-06-02 18:18 ` [PATCH 1/9] mfd: Fix bus lock interaction for WM831x IRQ set_type() operation Mark Brown
  2011-06-20 10:13 ` [PATCH 0/9] Pending Wolfson patches Samuel Ortiz
  0 siblings, 2 replies; 11+ messages in thread
From: Mark Brown @ 2011-06-02 18:18 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: linux-kernel, patches

Since there's quite a few Wolfson patches outstanding I thought it'd be
easiest to collect them all together into a single thread - there's also
a git branch in case that's helpful.  All these have been previously
posted, though some may have been revised and had me forget to post them.

The following changes since commit 55922c9d1b84b89cb946c777fddccb3247e7df2c:

  Linux 3.0-rc1 (2011-05-29 17:43:36 -0700)

are available in the git repository at:
  git://opensource.wolfsonmicro.com/linux-2.6-audioplus for-sameo

Mark Brown (8):
      mfd: Fix bus lock interaction for WM831x IRQ set_type() operation
      mfd: Implement support for multiple WM831x devices
      mfd: Allow touchscreen to be disabled on wm831x devices
      mfd: Only register wm831x RTC device if the 32.768kHz crystal is enabled
      mfd: Support dynamic allocation of IRQ range for wm831x
      mfd: Read wm831x AUXADC conversion results before acknowledging interrupt
      mfd: Refactor wm831x AUXADC handling into a separate file
      mfd: Restructure wm8994-core device revision handling

Sascha Hauer (1):
      mfd: Allocate wm835x irq descs dynamically

 drivers/mfd/Makefile             |    1 +
 drivers/mfd/wm831x-auxadc.c      |  199 +++++++++++++++++++++++++++++++
 drivers/mfd/wm831x-core.c        |  245 +++++++++-----------------------------
 drivers/mfd/wm831x-irq.c         |   42 +++++--
 drivers/mfd/wm8350-irq.c         |   18 ++-
 drivers/mfd/wm8994-core.c        |   13 ++-
 include/linux/mfd/wm831x/core.h  |    7 +-
 include/linux/mfd/wm831x/pdata.h |    3 +
 8 files changed, 319 insertions(+), 209 deletions(-)
 create mode 100644 drivers/mfd/wm831x-auxadc.c

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/9] mfd: Fix bus lock interaction for WM831x IRQ set_type() operation
  2011-06-02 18:18 [PATCH 0/9] Pending Wolfson patches Mark Brown
@ 2011-06-02 18:18 ` Mark Brown
  2011-06-02 18:18   ` [PATCH 2/9] mfd: Implement support for multiple WM831x devices Mark Brown
                     ` (7 more replies)
  2011-06-20 10:13 ` [PATCH 0/9] Pending Wolfson patches Samuel Ortiz
  1 sibling, 8 replies; 11+ messages in thread
From: Mark Brown @ 2011-06-02 18:18 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: patches, linux-kernel, Mark Brown

The WM831x IRQ set_type() operation is doing a direct register write when
called but since set_type() is called with the bus lock held this isn't
legal and could cause deadlocks in the IRQ core.

Fix this by posting the updates into an array and syncing in the
bus_sync_unlock() callback.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 drivers/mfd/wm831x-irq.c        |   24 ++++++++++++++++++------
 include/linux/mfd/wm831x/core.h |    4 ++++
 2 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c
index 42b928e..b23d8d5 100644
--- a/drivers/mfd/wm831x-irq.c
+++ b/drivers/mfd/wm831x-irq.c
@@ -348,6 +348,15 @@ static void wm831x_irq_sync_unlock(struct irq_data *data)
 	struct wm831x *wm831x = irq_data_get_irq_chip_data(data);
 	int i;
 
+	for (i = 0; i < ARRAY_SIZE(wm831x->gpio_update); i++) {
+		if (wm831x->gpio_update[i]) {
+			wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + i,
+					WM831X_GPN_INT_MODE | WM831X_GPN_POL,
+					wm831x->gpio_update[i]);
+			wm831x->gpio_update[i] = 0;
+		}
+	}
+
 	for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) {
 		/* If there's been a change in the mask write it back
 		 * to the hardware. */
@@ -387,7 +396,7 @@ static void wm831x_irq_disable(struct irq_data *data)
 static int wm831x_irq_set_type(struct irq_data *data, unsigned int type)
 {
 	struct wm831x *wm831x = irq_data_get_irq_chip_data(data);
-	int val, irq;
+	int irq;
 
 	irq = data->irq - wm831x->irq_base;
 
@@ -399,22 +408,25 @@ static int wm831x_irq_set_type(struct irq_data *data, unsigned int type)
 			return -EINVAL;
 	}
 
+	/* We set the high bit to flag that we need an update; don't
+	 * do the update here as we can be called with the bus lock
+	 * held.
+	 */
 	switch (type) {
 	case IRQ_TYPE_EDGE_BOTH:
-		val = WM831X_GPN_INT_MODE;
+		wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_INT_MODE;
 		break;
 	case IRQ_TYPE_EDGE_RISING:
-		val = WM831X_GPN_POL;
+		wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL;
 		break;
 	case IRQ_TYPE_EDGE_FALLING:
-		val = 0;
+		wm831x->gpio_update[irq] = 0x10000;
 		break;
 	default:
 		return -EINVAL;
 	}
 
-	return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + irq,
-			       WM831X_GPN_INT_MODE | WM831X_GPN_POL, val);
+	return 0;
 }
 
 static struct irq_chip wm831x_irq_chip = {
diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h
index 0d515ee..ebead1c 100644
--- a/include/linux/mfd/wm831x/core.h
+++ b/include/linux/mfd/wm831x/core.h
@@ -237,6 +237,7 @@
 struct regulator_dev;
 
 #define WM831X_NUM_IRQ_REGS 5
+#define WM831X_NUM_GPIO_REGS 16
 
 enum wm831x_parent {
 	WM8310 = 0x8310,
@@ -272,6 +273,9 @@ struct wm831x {
 
 	int num_gpio;
 
+	/* Used by the interrupt controller code to post writes */
+	int gpio_update[WM831X_NUM_GPIO_REGS];
+
 	struct mutex auxadc_lock;
 	struct completion auxadc_done;
 
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/9] mfd: Implement support for multiple WM831x devices
  2011-06-02 18:18 ` [PATCH 1/9] mfd: Fix bus lock interaction for WM831x IRQ set_type() operation Mark Brown
@ 2011-06-02 18:18   ` Mark Brown
  2011-06-02 18:18   ` [PATCH 3/9] mfd: Allow touchscreen to be disabled on wm831x devices Mark Brown
                     ` (6 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2011-06-02 18:18 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: patches, linux-kernel, Mark Brown

Systems using this functionality will be uncommon.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 drivers/mfd/wm831x-core.c |   18 ++++++++++++------
 1 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index 265f75f..04994b2 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -1440,7 +1440,7 @@ static struct mfd_cell backlight_devs[] = {
 int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
 {
 	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
-	int rev;
+	int rev, wm831x_num;
 	enum wm831x_parent parent;
 	int ret, i;
 
@@ -1592,6 +1592,12 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
 		}
 	}
 
+	/* Multiply by 10 as we have many subdevices of the same type */
+	if (pdata && pdata->wm831x_num)
+		wm831x_num = pdata->wm831x_num * 10;
+	else
+		wm831x_num = -1;
+
 	ret = wm831x_irq_init(wm831x, irq);
 	if (ret != 0)
 		goto err;
@@ -1609,19 +1615,19 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
 	/* The core device is up, instantiate the subdevices. */
 	switch (parent) {
 	case WM8310:
-		ret = mfd_add_devices(wm831x->dev, -1,
+		ret = mfd_add_devices(wm831x->dev, wm831x_num,
 				      wm8310_devs, ARRAY_SIZE(wm8310_devs),
 				      NULL, wm831x->irq_base);
 		break;
 
 	case WM8311:
-		ret = mfd_add_devices(wm831x->dev, -1,
+		ret = mfd_add_devices(wm831x->dev, wm831x_num,
 				      wm8311_devs, ARRAY_SIZE(wm8311_devs),
 				      NULL, wm831x->irq_base);
 		break;
 
 	case WM8312:
-		ret = mfd_add_devices(wm831x->dev, -1,
+		ret = mfd_add_devices(wm831x->dev, wm831x_num,
 				      wm8312_devs, ARRAY_SIZE(wm8312_devs),
 				      NULL, wm831x->irq_base);
 		break;
@@ -1630,7 +1636,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
 	case WM8321:
 	case WM8325:
 	case WM8326:
-		ret = mfd_add_devices(wm831x->dev, -1,
+		ret = mfd_add_devices(wm831x->dev, wm831x_num,
 				      wm8320_devs, ARRAY_SIZE(wm8320_devs),
 				      NULL, wm831x->irq_base);
 		break;
@@ -1647,7 +1653,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
 
 	if (pdata && pdata->backlight) {
 		/* Treat errors as non-critical */
-		ret = mfd_add_devices(wm831x->dev, -1, backlight_devs,
+		ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs,
 				      ARRAY_SIZE(backlight_devs), NULL,
 				      wm831x->irq_base);
 		if (ret < 0)
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/9] mfd: Allow touchscreen to be disabled on wm831x devices
  2011-06-02 18:18 ` [PATCH 1/9] mfd: Fix bus lock interaction for WM831x IRQ set_type() operation Mark Brown
  2011-06-02 18:18   ` [PATCH 2/9] mfd: Implement support for multiple WM831x devices Mark Brown
@ 2011-06-02 18:18   ` Mark Brown
  2011-06-02 18:18   ` [PATCH 4/9] mfd: Only register wm831x RTC device if the 32.768kHz crystal is enabled Mark Brown
                     ` (5 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2011-06-02 18:18 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: patches, linux-kernel, Mark Brown

Allow platform data to flag the touchscreen as disabled so that if the
touch driver is built in we don't end up causing lots of work by spuriously
detecting touchscreen activity on systems where it isn't in use.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 drivers/mfd/wm831x-core.c        |   27 +++++++++++++++++----------
 include/linux/mfd/wm831x/pdata.h |    3 +++
 2 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index 04994b2..ff57a16 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -1125,11 +1125,6 @@ static struct mfd_cell wm8311_devs[] = {
 		.resources = wm831x_status2_resources,
 	},
 	{
-		.name = "wm831x-touch",
-		.num_resources = ARRAY_SIZE(wm831x_touch_resources),
-		.resources = wm831x_touch_resources,
-	},
-	{
 		.name = "wm831x-watchdog",
 		.num_resources = ARRAY_SIZE(wm831x_wdt_resources),
 		.resources = wm831x_wdt_resources,
@@ -1286,11 +1281,6 @@ static struct mfd_cell wm8312_devs[] = {
 		.resources = wm831x_status2_resources,
 	},
 	{
-		.name = "wm831x-touch",
-		.num_resources = ARRAY_SIZE(wm831x_touch_resources),
-		.resources = wm831x_touch_resources,
-	},
-	{
 		.name = "wm831x-watchdog",
 		.num_resources = ARRAY_SIZE(wm831x_wdt_resources),
 		.resources = wm831x_wdt_resources,
@@ -1428,6 +1418,15 @@ static struct mfd_cell wm8320_devs[] = {
 	},
 };
 
+static struct mfd_cell touch_devs[] = {
+	{
+		.name = "wm831x-touch",
+		.num_resources = ARRAY_SIZE(wm831x_touch_resources),
+		.resources = wm831x_touch_resources,
+	},
+};
+
+
 static struct mfd_cell backlight_devs[] = {
 	{
 		.name = "wm831x-backlight",
@@ -1624,12 +1623,20 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
 		ret = mfd_add_devices(wm831x->dev, wm831x_num,
 				      wm8311_devs, ARRAY_SIZE(wm8311_devs),
 				      NULL, wm831x->irq_base);
+		if (!pdata || !pdata->disable_touch)
+			mfd_add_devices(wm831x->dev, wm831x_num,
+					touch_devs, ARRAY_SIZE(touch_devs),
+					NULL, wm831x->irq_base);
 		break;
 
 	case WM8312:
 		ret = mfd_add_devices(wm831x->dev, wm831x_num,
 				      wm8312_devs, ARRAY_SIZE(wm8312_devs),
 				      NULL, wm831x->irq_base);
+		if (!pdata || !pdata->disable_touch)
+			mfd_add_devices(wm831x->dev, wm831x_num,
+					touch_devs, ARRAY_SIZE(touch_devs),
+					NULL, wm831x->irq_base);
 		break;
 
 	case WM8320:
diff --git a/include/linux/mfd/wm831x/pdata.h b/include/linux/mfd/wm831x/pdata.h
index ff42d70..0ba2459 100644
--- a/include/linux/mfd/wm831x/pdata.h
+++ b/include/linux/mfd/wm831x/pdata.h
@@ -120,6 +120,9 @@ struct wm831x_pdata {
 	/** Put the /IRQ line into CMOS mode */
 	bool irq_cmos;
 
+	/** Disable the touchscreen */
+	bool disable_touch;
+
 	int irq_base;
 	int gpio_base;
 	int gpio_defaults[WM831X_GPIO_NUM];
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/9] mfd: Only register wm831x RTC device if the 32.768kHz crystal is enabled
  2011-06-02 18:18 ` [PATCH 1/9] mfd: Fix bus lock interaction for WM831x IRQ set_type() operation Mark Brown
  2011-06-02 18:18   ` [PATCH 2/9] mfd: Implement support for multiple WM831x devices Mark Brown
  2011-06-02 18:18   ` [PATCH 3/9] mfd: Allow touchscreen to be disabled on wm831x devices Mark Brown
@ 2011-06-02 18:18   ` Mark Brown
  2011-06-02 18:18   ` [PATCH 5/9] mfd: Support dynamic allocation of IRQ range for wm831x Mark Brown
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2011-06-02 18:18 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: patches, linux-kernel, Mark Brown

The RTC uses the 32.768kHz crystal so if it's not enabled (and it can only
be enabled via OTP or InstantConfig, not runtime software) the RTC can't
function.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 drivers/mfd/wm831x-core.c |   48 ++++++++++++++++++++++++++------------------
 1 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index ff57a16..58f033b 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -976,11 +976,6 @@ static struct mfd_cell wm8310_devs[] = {
 		.resources = wm831x_power_resources,
 	},
 	{
-		.name = "wm831x-rtc",
-		.num_resources = ARRAY_SIZE(wm831x_rtc_resources),
-		.resources = wm831x_rtc_resources,
-	},
-	{
 		.name = "wm831x-status",
 		.id = 1,
 		.num_resources = ARRAY_SIZE(wm831x_status1_resources),
@@ -1108,11 +1103,6 @@ static struct mfd_cell wm8311_devs[] = {
 		.resources = wm831x_power_resources,
 	},
 	{
-		.name = "wm831x-rtc",
-		.num_resources = ARRAY_SIZE(wm831x_rtc_resources),
-		.resources = wm831x_rtc_resources,
-	},
-	{
 		.name = "wm831x-status",
 		.id = 1,
 		.num_resources = ARRAY_SIZE(wm831x_status1_resources),
@@ -1264,11 +1254,6 @@ static struct mfd_cell wm8312_devs[] = {
 		.resources = wm831x_power_resources,
 	},
 	{
-		.name = "wm831x-rtc",
-		.num_resources = ARRAY_SIZE(wm831x_rtc_resources),
-		.resources = wm831x_rtc_resources,
-	},
-	{
 		.name = "wm831x-status",
 		.id = 1,
 		.num_resources = ARRAY_SIZE(wm831x_status1_resources),
@@ -1395,11 +1380,6 @@ static struct mfd_cell wm8320_devs[] = {
 		.resources = wm831x_on_resources,
 	},
 	{
-		.name = "wm831x-rtc",
-		.num_resources = ARRAY_SIZE(wm831x_rtc_resources),
-		.resources = wm831x_rtc_resources,
-	},
-	{
 		.name = "wm831x-status",
 		.id = 1,
 		.num_resources = ARRAY_SIZE(wm831x_status1_resources),
@@ -1426,6 +1406,13 @@ static struct mfd_cell touch_devs[] = {
 	},
 };
 
+static struct mfd_cell rtc_devs[] = {
+	{
+		.name = "wm831x-rtc",
+		.num_resources = ARRAY_SIZE(wm831x_rtc_resources),
+		.resources = wm831x_rtc_resources,
+	},
+};
 
 static struct mfd_cell backlight_devs[] = {
 	{
@@ -1658,6 +1645,27 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
 		goto err_irq;
 	}
 
+	/* The RTC can only be used if the 32.768kHz crystal is
+	 * enabled; this can't be controlled by software at runtime.
+	 */
+	ret = wm831x_reg_read(wm831x, WM831X_CLOCK_CONTROL_2);
+	if (ret < 0) {
+		dev_err(wm831x->dev, "Failed to read clock status: %d\n", ret);
+		goto err_irq;
+	}
+
+	if (ret & WM831X_XTAL_ENA) {
+		ret = mfd_add_devices(wm831x->dev, wm831x_num,
+				      rtc_devs, ARRAY_SIZE(rtc_devs),
+				      NULL, wm831x->irq_base);
+		if (ret != 0) {
+			dev_err(wm831x->dev, "Failed to add RTC: %d\n", ret);
+			goto err_irq;
+		}
+	} else {
+		dev_info(wm831x->dev, "32.768kHz clock disabled, no RTC\n");
+	}
+
 	if (pdata && pdata->backlight) {
 		/* Treat errors as non-critical */
 		ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs,
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 5/9] mfd: Support dynamic allocation of IRQ range for wm831x
  2011-06-02 18:18 ` [PATCH 1/9] mfd: Fix bus lock interaction for WM831x IRQ set_type() operation Mark Brown
                     ` (2 preceding siblings ...)
  2011-06-02 18:18   ` [PATCH 4/9] mfd: Only register wm831x RTC device if the 32.768kHz crystal is enabled Mark Brown
@ 2011-06-02 18:18   ` Mark Brown
  2011-06-02 18:18   ` [PATCH 6/9] mfd: Read wm831x AUXADC conversion results before acknowledging interrupt Mark Brown
                     ` (3 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2011-06-02 18:18 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: patches, linux-kernel, Mark Brown

Use irq_allocate_desc() to get the IRQ range, which turns into a noop on
non-sparse systems. Since all existing users are non-sparse there should
be no compatibility issues.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 drivers/mfd/wm831x-irq.c        |   18 +++++++++++++-----
 include/linux/mfd/wm831x/core.h |    2 +-
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c
index b23d8d5..1808deb 100644
--- a/drivers/mfd/wm831x-irq.c
+++ b/drivers/mfd/wm831x-irq.c
@@ -527,13 +527,22 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
 				 0xffff);
 	}
 
-	if (!pdata || !pdata->irq_base) {
-		dev_err(wm831x->dev,
-			"No interrupt base specified, no interrupts\n");
+	/* Try to dynamically allocate IRQs if no base is specified */
+	if (!pdata || !pdata->irq_base)
+		wm831x->irq_base = -1;
+	else
+		wm831x->irq_base = pdata->irq_base;
+
+	wm831x->irq_base = irq_alloc_descs(wm831x->irq_base, 0,
+					   WM831X_NUM_IRQS, 0);
+	if (wm831x->irq_base < 0) {
+		dev_warn(wm831x->dev, "Failed to allocate IRQs: %d\n",
+			 wm831x->irq_base);
+		wm831x->irq_base = 0;
 		return 0;
 	}
 
-	if (pdata->irq_cmos)
+	if (pdata && pdata->irq_cmos)
 		i = 0;
 	else
 		i = WM831X_IRQ_OD;
@@ -553,7 +562,6 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
 	}
 
 	wm831x->irq = irq;
-	wm831x->irq_base = pdata->irq_base;
 
 	/* Register them with genirq */
 	for (cur_irq = wm831x->irq_base;
diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h
index ebead1c..9564cf3 100644
--- a/include/linux/mfd/wm831x/core.h
+++ b/include/linux/mfd/wm831x/core.h
@@ -262,7 +262,7 @@ struct wm831x {
 
 	int irq;  /* Our chip IRQ */
 	struct mutex irq_lock;
-	unsigned int irq_base;
+	int irq_base;
 	int irq_masks_cur[WM831X_NUM_IRQ_REGS];   /* Currently active value */
 	int irq_masks_cache[WM831X_NUM_IRQ_REGS]; /* Cached hardware value */
 
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 6/9] mfd: Read wm831x AUXADC conversion results before acknowledging interrupt
  2011-06-02 18:18 ` [PATCH 1/9] mfd: Fix bus lock interaction for WM831x IRQ set_type() operation Mark Brown
                     ` (3 preceding siblings ...)
  2011-06-02 18:18   ` [PATCH 5/9] mfd: Support dynamic allocation of IRQ range for wm831x Mark Brown
@ 2011-06-02 18:18   ` Mark Brown
  2011-06-02 18:18   ` [PATCH 7/9] mfd: Refactor wm831x AUXADC handling into a separate file Mark Brown
                     ` (2 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2011-06-02 18:18 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: patches, linux-kernel, Mark Brown

Ensure that there's no possibility of loosing an AUXADC interrupt by reading
the conversion result in the IRQ handler when using interrupts. Otherwise
it's possible that under very heavy load a new conversion could be initiated
before the acknowledgement for a previous interrupt has happened.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 drivers/mfd/wm831x-core.c       |   47 +++++++++++++++++++++++++-------------
 include/linux/mfd/wm831x/core.h |    1 +
 2 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index 58f033b..480abc1 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -376,6 +376,16 @@ int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input)
 				goto disable;
 			}
 		}
+
+		ret = wm831x_reg_read(wm831x, WM831X_AUXADC_DATA);
+		if (ret < 0) {
+			dev_err(wm831x->dev,
+				"Failed to read AUXADC data: %d\n", ret);
+			goto disable;
+		}
+
+		wm831x->auxadc_data = ret;
+
 	} else {
 		/* If we are using interrupts then wait for the
 		 * interrupt to complete.  Use an extremely long
@@ -390,23 +400,18 @@ int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input)
 		}
 	}
 
-	ret = wm831x_reg_read(wm831x, WM831X_AUXADC_DATA);
-	if (ret < 0) {
-		dev_err(wm831x->dev, "Failed to read AUXADC data: %d\n", ret);
+	src = ((wm831x->auxadc_data & WM831X_AUX_DATA_SRC_MASK)
+	       >> WM831X_AUX_DATA_SRC_SHIFT) - 1;
+
+	if (src == 14)
+		src = WM831X_AUX_CAL;
+
+	if (src != input) {
+		dev_err(wm831x->dev, "Data from source %d not %d\n",
+			src, input);
+		ret = -EINVAL;
 	} else {
-		src = ((ret & WM831X_AUX_DATA_SRC_MASK)
-		       >> WM831X_AUX_DATA_SRC_SHIFT) - 1;
-
-		if (src == 14)
-			src = WM831X_AUX_CAL;
-
-		if (src != input) {
-			dev_err(wm831x->dev, "Data from source %d not %d\n",
-				src, input);
-			ret = -EINVAL;
-		} else {
-			ret &= WM831X_AUX_DATA_MASK;
-		}
+		ret = wm831x->auxadc_data & WM831X_AUX_DATA_MASK;
 	}
 
 disable:
@@ -420,6 +425,16 @@ EXPORT_SYMBOL_GPL(wm831x_auxadc_read);
 static irqreturn_t wm831x_auxadc_irq(int irq, void *irq_data)
 {
 	struct wm831x *wm831x = irq_data;
+	int ret;
+
+	ret = wm831x_reg_read(wm831x, WM831X_AUXADC_DATA);
+	if (ret < 0) {
+		dev_err(wm831x->dev,
+			"Failed to read AUXADC data: %d\n", ret);
+		wm831x->auxadc_data = 0xffff;
+	} else {
+		wm831x->auxadc_data = ret;
+	}
 
 	complete(&wm831x->auxadc_done);
 
diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h
index 9564cf3..592e4fd 100644
--- a/include/linux/mfd/wm831x/core.h
+++ b/include/linux/mfd/wm831x/core.h
@@ -278,6 +278,7 @@ struct wm831x {
 
 	struct mutex auxadc_lock;
 	struct completion auxadc_done;
+	u16 auxadc_data;
 
 	/* The WM831x has a security key blocking access to certain
 	 * registers.  The mutex is taken by the accessors for locking
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 7/9] mfd: Refactor wm831x AUXADC handling into a separate file
  2011-06-02 18:18 ` [PATCH 1/9] mfd: Fix bus lock interaction for WM831x IRQ set_type() operation Mark Brown
                     ` (4 preceding siblings ...)
  2011-06-02 18:18   ` [PATCH 6/9] mfd: Read wm831x AUXADC conversion results before acknowledging interrupt Mark Brown
@ 2011-06-02 18:18   ` Mark Brown
  2011-06-02 18:18   ` [PATCH 8/9] mfd: Allocate wm835x irq descs dynamically Mark Brown
  2011-06-02 18:18   ` [PATCH 9/9] mfd: Restructure wm8994-core device revision handling Mark Brown
  7 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2011-06-02 18:18 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: patches, linux-kernel, Mark Brown

In preparation for some additional work on the wm831x AUXADC code move the
support into a separate file. This is a simple code motion patch, there
should be no functional changes.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 drivers/mfd/Makefile        |    1 +
 drivers/mfd/wm831x-auxadc.c |  199 +++++++++++++++++++++++++++++++++++++++++++
 drivers/mfd/wm831x-core.c   |  167 +------------------------------------
 3 files changed, 201 insertions(+), 166 deletions(-)
 create mode 100644 drivers/mfd/wm831x-auxadc.c

diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index efe3cc3..9f41923 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_MFD_TC6393XB)	+= tc6393xb.o tmio_core.o
 
 obj-$(CONFIG_MFD_WM8400)	+= wm8400-core.o
 wm831x-objs			:= wm831x-core.o wm831x-irq.o wm831x-otp.o
+wm831x-objs			+= wm831x-auxadc.o
 obj-$(CONFIG_MFD_WM831X)	+= wm831x.o
 obj-$(CONFIG_MFD_WM831X_I2C)	+= wm831x-i2c.o
 obj-$(CONFIG_MFD_WM831X_SPI)	+= wm831x-spi.o
diff --git a/drivers/mfd/wm831x-auxadc.c b/drivers/mfd/wm831x-auxadc.c
new file mode 100644
index 0000000..2fc9531
--- /dev/null
+++ b/drivers/mfd/wm831x-auxadc.c
@@ -0,0 +1,199 @@
+/*
+ * wm831x-auxadc.c  --  AUXADC for Wolfson WM831x PMICs
+ *
+ * Copyright 2009-2011 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/mfd/core.h>
+#include <linux/slab.h>
+
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/pdata.h>
+#include <linux/mfd/wm831x/irq.h>
+#include <linux/mfd/wm831x/auxadc.h>
+#include <linux/mfd/wm831x/otp.h>
+#include <linux/mfd/wm831x/regulator.h>
+
+/**
+ * wm831x_auxadc_read: Read a value from the WM831x AUXADC
+ *
+ * @wm831x: Device to read from.
+ * @input: AUXADC input to read.
+ */
+int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input)
+{
+	int ret, src, irq_masked, timeout;
+
+	/* Are we using the interrupt? */
+	irq_masked = wm831x_reg_read(wm831x, WM831X_INTERRUPT_STATUS_1_MASK);
+	irq_masked &= WM831X_AUXADC_DATA_EINT;
+
+	mutex_lock(&wm831x->auxadc_lock);
+
+	ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL,
+			      WM831X_AUX_ENA, WM831X_AUX_ENA);
+	if (ret < 0) {
+		dev_err(wm831x->dev, "Failed to enable AUXADC: %d\n", ret);
+		goto out;
+	}
+
+	/* We force a single source at present */
+	src = input;
+	ret = wm831x_reg_write(wm831x, WM831X_AUXADC_SOURCE,
+			       1 << src);
+	if (ret < 0) {
+		dev_err(wm831x->dev, "Failed to set AUXADC source: %d\n", ret);
+		goto out;
+	}
+
+	/* Clear any notification from a very late arriving interrupt */
+	try_wait_for_completion(&wm831x->auxadc_done);
+
+	ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL,
+			      WM831X_AUX_CVT_ENA, WM831X_AUX_CVT_ENA);
+	if (ret < 0) {
+		dev_err(wm831x->dev, "Failed to start AUXADC: %d\n", ret);
+		goto disable;
+	}
+
+	if (irq_masked) {
+		/* If we're not using interrupts then poll the
+		 * interrupt status register */
+		timeout = 5;
+		while (timeout) {
+			msleep(1);
+
+			ret = wm831x_reg_read(wm831x,
+					      WM831X_INTERRUPT_STATUS_1);
+			if (ret < 0) {
+				dev_err(wm831x->dev,
+					"ISR 1 read failed: %d\n", ret);
+				goto disable;
+			}
+
+			/* Did it complete? */
+			if (ret & WM831X_AUXADC_DATA_EINT) {
+				wm831x_reg_write(wm831x,
+						 WM831X_INTERRUPT_STATUS_1,
+						 WM831X_AUXADC_DATA_EINT);
+				break;
+			} else {
+				dev_err(wm831x->dev,
+					"AUXADC conversion timeout\n");
+				ret = -EBUSY;
+				goto disable;
+			}
+		}
+
+		ret = wm831x_reg_read(wm831x, WM831X_AUXADC_DATA);
+		if (ret < 0) {
+			dev_err(wm831x->dev,
+				"Failed to read AUXADC data: %d\n", ret);
+			goto disable;
+		}
+
+		wm831x->auxadc_data = ret;
+
+	} else {
+		/* If we are using interrupts then wait for the
+		 * interrupt to complete.  Use an extremely long
+		 * timeout to handle situations with heavy load where
+		 * the notification of the interrupt may be delayed by
+		 * threaded IRQ handling. */
+		if (!wait_for_completion_timeout(&wm831x->auxadc_done,
+						 msecs_to_jiffies(500))) {
+			dev_err(wm831x->dev, "Timed out waiting for AUXADC\n");
+			ret = -EBUSY;
+			goto disable;
+		}
+	}
+
+	src = ((wm831x->auxadc_data & WM831X_AUX_DATA_SRC_MASK)
+	       >> WM831X_AUX_DATA_SRC_SHIFT) - 1;
+
+	if (src == 14)
+		src = WM831X_AUX_CAL;
+
+	if (src != input) {
+		dev_err(wm831x->dev, "Data from source %d not %d\n",
+			src, input);
+		ret = -EINVAL;
+	} else {
+		ret = wm831x->auxadc_data & WM831X_AUX_DATA_MASK;
+	}
+
+disable:
+	wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL, WM831X_AUX_ENA, 0);
+out:
+	mutex_unlock(&wm831x->auxadc_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(wm831x_auxadc_read);
+
+static irqreturn_t wm831x_auxadc_irq(int irq, void *irq_data)
+{
+	struct wm831x *wm831x = irq_data;
+	int ret;
+
+	ret = wm831x_reg_read(wm831x, WM831X_AUXADC_DATA);
+	if (ret < 0) {
+		dev_err(wm831x->dev,
+			"Failed to read AUXADC data: %d\n", ret);
+		wm831x->auxadc_data = 0xffff;
+	} else {
+		wm831x->auxadc_data = ret;
+	}
+
+	complete(&wm831x->auxadc_done);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * wm831x_auxadc_read_uv: Read a voltage from the WM831x AUXADC
+ *
+ * @wm831x: Device to read from.
+ * @input: AUXADC input to read.
+ */
+int wm831x_auxadc_read_uv(struct wm831x *wm831x, enum wm831x_auxadc input)
+{
+	int ret;
+
+	ret = wm831x_auxadc_read(wm831x, input);
+	if (ret < 0)
+		return ret;
+
+	ret *= 1465;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(wm831x_auxadc_read_uv);
+
+void wm831x_auxadc_init(struct wm831x *wm831x)
+{
+	int ret;
+
+	mutex_init(&wm831x->auxadc_lock);
+	init_completion(&wm831x->auxadc_done);
+
+	if (wm831x->irq_base) {
+		ret = request_threaded_irq(wm831x->irq_base +
+					   WM831X_IRQ_AUXADC_DATA,
+					   NULL, wm831x_auxadc_irq, 0,
+					   "auxadc", wm831x);
+		if (ret < 0)
+			dev_err(wm831x->dev, "AUXADC IRQ request failed: %d\n",
+				ret);
+	}
+}
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index 480abc1..772fe58 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -306,161 +306,6 @@ out:
 }
 EXPORT_SYMBOL_GPL(wm831x_set_bits);
 
-/**
- * wm831x_auxadc_read: Read a value from the WM831x AUXADC
- *
- * @wm831x: Device to read from.
- * @input: AUXADC input to read.
- */
-int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input)
-{
-	int ret, src, irq_masked, timeout;
-
-	/* Are we using the interrupt? */
-	irq_masked = wm831x_reg_read(wm831x, WM831X_INTERRUPT_STATUS_1_MASK);
-	irq_masked &= WM831X_AUXADC_DATA_EINT;
-
-	mutex_lock(&wm831x->auxadc_lock);
-
-	ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL,
-			      WM831X_AUX_ENA, WM831X_AUX_ENA);
-	if (ret < 0) {
-		dev_err(wm831x->dev, "Failed to enable AUXADC: %d\n", ret);
-		goto out;
-	}
-
-	/* We force a single source at present */
-	src = input;
-	ret = wm831x_reg_write(wm831x, WM831X_AUXADC_SOURCE,
-			       1 << src);
-	if (ret < 0) {
-		dev_err(wm831x->dev, "Failed to set AUXADC source: %d\n", ret);
-		goto out;
-	}
-
-	/* Clear any notification from a very late arriving interrupt */
-	try_wait_for_completion(&wm831x->auxadc_done);
-
-	ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL,
-			      WM831X_AUX_CVT_ENA, WM831X_AUX_CVT_ENA);
-	if (ret < 0) {
-		dev_err(wm831x->dev, "Failed to start AUXADC: %d\n", ret);
-		goto disable;
-	}
-
-	if (irq_masked) {
-		/* If we're not using interrupts then poll the
-		 * interrupt status register */
-		timeout = 5;
-		while (timeout) {
-			msleep(1);
-
-			ret = wm831x_reg_read(wm831x,
-					      WM831X_INTERRUPT_STATUS_1);
-			if (ret < 0) {
-				dev_err(wm831x->dev,
-					"ISR 1 read failed: %d\n", ret);
-				goto disable;
-			}
-
-			/* Did it complete? */
-			if (ret & WM831X_AUXADC_DATA_EINT) {
-				wm831x_reg_write(wm831x,
-						 WM831X_INTERRUPT_STATUS_1,
-						 WM831X_AUXADC_DATA_EINT);
-				break;
-			} else {
-				dev_err(wm831x->dev,
-					"AUXADC conversion timeout\n");
-				ret = -EBUSY;
-				goto disable;
-			}
-		}
-
-		ret = wm831x_reg_read(wm831x, WM831X_AUXADC_DATA);
-		if (ret < 0) {
-			dev_err(wm831x->dev,
-				"Failed to read AUXADC data: %d\n", ret);
-			goto disable;
-		}
-
-		wm831x->auxadc_data = ret;
-
-	} else {
-		/* If we are using interrupts then wait for the
-		 * interrupt to complete.  Use an extremely long
-		 * timeout to handle situations with heavy load where
-		 * the notification of the interrupt may be delayed by
-		 * threaded IRQ handling. */
-		if (!wait_for_completion_timeout(&wm831x->auxadc_done,
-						 msecs_to_jiffies(500))) {
-			dev_err(wm831x->dev, "Timed out waiting for AUXADC\n");
-			ret = -EBUSY;
-			goto disable;
-		}
-	}
-
-	src = ((wm831x->auxadc_data & WM831X_AUX_DATA_SRC_MASK)
-	       >> WM831X_AUX_DATA_SRC_SHIFT) - 1;
-
-	if (src == 14)
-		src = WM831X_AUX_CAL;
-
-	if (src != input) {
-		dev_err(wm831x->dev, "Data from source %d not %d\n",
-			src, input);
-		ret = -EINVAL;
-	} else {
-		ret = wm831x->auxadc_data & WM831X_AUX_DATA_MASK;
-	}
-
-disable:
-	wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL, WM831X_AUX_ENA, 0);
-out:
-	mutex_unlock(&wm831x->auxadc_lock);
-	return ret;
-}
-EXPORT_SYMBOL_GPL(wm831x_auxadc_read);
-
-static irqreturn_t wm831x_auxadc_irq(int irq, void *irq_data)
-{
-	struct wm831x *wm831x = irq_data;
-	int ret;
-
-	ret = wm831x_reg_read(wm831x, WM831X_AUXADC_DATA);
-	if (ret < 0) {
-		dev_err(wm831x->dev,
-			"Failed to read AUXADC data: %d\n", ret);
-		wm831x->auxadc_data = 0xffff;
-	} else {
-		wm831x->auxadc_data = ret;
-	}
-
-	complete(&wm831x->auxadc_done);
-
-	return IRQ_HANDLED;
-}
-
-/**
- * wm831x_auxadc_read_uv: Read a voltage from the WM831x AUXADC
- *
- * @wm831x: Device to read from.
- * @input: AUXADC input to read.
- */
-int wm831x_auxadc_read_uv(struct wm831x *wm831x, enum wm831x_auxadc input)
-{
-	int ret;
-
-	ret = wm831x_auxadc_read(wm831x, input);
-	if (ret < 0)
-		return ret;
-
-	ret *= 1465;
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(wm831x_auxadc_read_uv);
-
 static struct resource wm831x_dcdc1_resources[] = {
 	{
 		.start = WM831X_DC1_CONTROL_1,
@@ -1447,8 +1292,6 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
 
 	mutex_init(&wm831x->io_lock);
 	mutex_init(&wm831x->key_lock);
-	mutex_init(&wm831x->auxadc_lock);
-	init_completion(&wm831x->auxadc_done);
 	dev_set_drvdata(wm831x->dev, wm831x);
 
 	ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
@@ -1603,15 +1446,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
 	if (ret != 0)
 		goto err;
 
-	if (wm831x->irq_base) {
-		ret = request_threaded_irq(wm831x->irq_base +
-					   WM831X_IRQ_AUXADC_DATA,
-					   NULL, wm831x_auxadc_irq, 0,
-					   "auxadc", wm831x);
-		if (ret < 0)
-			dev_err(wm831x->dev, "AUXADC IRQ request failed: %d\n",
-				ret);
-	}
+	wm831x_auxadc_init(wm831x);
 
 	/* The core device is up, instantiate the subdevices. */
 	switch (parent) {
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 8/9] mfd: Allocate wm835x irq descs dynamically
  2011-06-02 18:18 ` [PATCH 1/9] mfd: Fix bus lock interaction for WM831x IRQ set_type() operation Mark Brown
                     ` (5 preceding siblings ...)
  2011-06-02 18:18   ` [PATCH 7/9] mfd: Refactor wm831x AUXADC handling into a separate file Mark Brown
@ 2011-06-02 18:18   ` Mark Brown
  2011-06-02 18:18   ` [PATCH 9/9] mfd: Restructure wm8994-core device revision handling Mark Brown
  7 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2011-06-02 18:18 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: patches, linux-kernel, Sascha Hauer, Mark Brown

From: Sascha Hauer <s.hauer@pengutronix.de>

This allows boards to leave the irq_base field unitialized and
prevents them having to reserve irqs in the platform.
pdata can be optional for irq support now. Without pdata the
driver allocates some free irq range. With pdata and irq_base > 0
the driver allocates exactly the specified irq.
Without pdata the irq defaults to IRQF_TRIGGER_LOW.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 drivers/mfd/wm8350-irq.c |   18 ++++++++++++------
 1 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/mfd/wm8350-irq.c b/drivers/mfd/wm8350-irq.c
index ed4b22a..8a1fafd 100644
--- a/drivers/mfd/wm8350-irq.c
+++ b/drivers/mfd/wm8350-irq.c
@@ -473,17 +473,13 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq,
 {
 	int ret, cur_irq, i;
 	int flags = IRQF_ONESHOT;
+	int irq_base = -1;
 
 	if (!irq) {
 		dev_warn(wm8350->dev, "No interrupt support, no core IRQ\n");
 		return 0;
 	}
 
-	if (!pdata || !pdata->irq_base) {
-		dev_warn(wm8350->dev, "No interrupt support, no IRQ base\n");
-		return 0;
-	}
-
 	/* Mask top level interrupts */
 	wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0xFFFF);
 
@@ -502,7 +498,17 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq,
 	wm8350->chip_irq = irq;
 	wm8350->irq_base = pdata->irq_base;
 
-	if (pdata->irq_high) {
+	if (pdata && pdata->irq_base > 0)
+		irq_base = pdata->irq_base;
+
+	wm8350->irq_base = irq_alloc_descs(irq_base, 0, ARRAY_SIZE(wm8350_irqs), 0);
+	if (wm8350->irq_base < 0) {
+		dev_warn(wm8350->dev, "Allocating irqs failed with %d\n",
+			wm8350->irq_base);
+		return 0;
+	}
+
+	if (pdata && pdata->irq_high) {
 		flags |= IRQF_TRIGGER_HIGH;
 
 		wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 9/9] mfd: Restructure wm8994-core device revision handling
  2011-06-02 18:18 ` [PATCH 1/9] mfd: Fix bus lock interaction for WM831x IRQ set_type() operation Mark Brown
                     ` (6 preceding siblings ...)
  2011-06-02 18:18   ` [PATCH 8/9] mfd: Allocate wm835x irq descs dynamically Mark Brown
@ 2011-06-02 18:18   ` Mark Brown
  7 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2011-06-02 18:18 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: patches, linux-kernel, Mark Brown

Switch on the device type before revision since anything we do here will
be device as well as revision specific.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 drivers/mfd/wm8994-core.c |   13 +++++++++----
 1 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index e198d40..18f19b7 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -476,13 +476,18 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
 		goto err_enable;
 	}
 
-	switch (ret) {
-	case 0:
-	case 1:
-		if (wm8994->type == WM8994)
+	switch (wm8994->type) {
+	case WM8994:
+		switch (ret) {
+		case 0:
+		case 1:
 			dev_warn(wm8994->dev,
 				 "revision %c not fully supported\n",
 				 'A' + ret);
+			break;
+		default:
+			break;
+		}
 		break;
 	default:
 		break;
-- 
1.7.5.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 0/9] Pending Wolfson patches
  2011-06-02 18:18 [PATCH 0/9] Pending Wolfson patches Mark Brown
  2011-06-02 18:18 ` [PATCH 1/9] mfd: Fix bus lock interaction for WM831x IRQ set_type() operation Mark Brown
@ 2011-06-20 10:13 ` Samuel Ortiz
  1 sibling, 0 replies; 11+ messages in thread
From: Samuel Ortiz @ 2011-06-20 10:13 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-kernel, patches

Hi Mark,

On Thu, Jun 02, 2011 at 07:18:08PM +0100, Mark Brown wrote:
> Since there's quite a few Wolfson patches outstanding I thought it'd be
> easiest to collect them all together into a single thread - there's also
> a git branch in case that's helpful. 
Thanks a lot, I appreciate. All patches applied to my for-next branch now.

Cheers,
Samuel.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2011-06-20 10:13 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-02 18:18 [PATCH 0/9] Pending Wolfson patches Mark Brown
2011-06-02 18:18 ` [PATCH 1/9] mfd: Fix bus lock interaction for WM831x IRQ set_type() operation Mark Brown
2011-06-02 18:18   ` [PATCH 2/9] mfd: Implement support for multiple WM831x devices Mark Brown
2011-06-02 18:18   ` [PATCH 3/9] mfd: Allow touchscreen to be disabled on wm831x devices Mark Brown
2011-06-02 18:18   ` [PATCH 4/9] mfd: Only register wm831x RTC device if the 32.768kHz crystal is enabled Mark Brown
2011-06-02 18:18   ` [PATCH 5/9] mfd: Support dynamic allocation of IRQ range for wm831x Mark Brown
2011-06-02 18:18   ` [PATCH 6/9] mfd: Read wm831x AUXADC conversion results before acknowledging interrupt Mark Brown
2011-06-02 18:18   ` [PATCH 7/9] mfd: Refactor wm831x AUXADC handling into a separate file Mark Brown
2011-06-02 18:18   ` [PATCH 8/9] mfd: Allocate wm835x irq descs dynamically Mark Brown
2011-06-02 18:18   ` [PATCH 9/9] mfd: Restructure wm8994-core device revision handling Mark Brown
2011-06-20 10:13 ` [PATCH 0/9] Pending Wolfson patches Samuel Ortiz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.