Skip to contentSkip to conversation

Pending Wolfson patches

PATCH In review Mark Brown 2 participants 11 messages Jun 2, 2011 – Jun 20, 2011

Subsystems (2)
lore
Share & tools
lore

Mark Brown

author
#0 lore raw

cover Pending Wolfson 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
author
#1 lore raw

PATCH 1/9 mfd: Fix bus lock interaction for WM831x IRQ set_type() operation

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.

---
 drivers/mfd/wm831x-irq.c        |   24 ++++++++++++++++++------
 include/linux/mfd/wm831x/core.h |    4 ++++
 2 files changed, 22 insertions(+), 6 deletions(-)
drivers/mfd/wm831x-irq.c +18 -6
index 42b928e..b23d8d5 100644
@@ -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 = {
include/linux/mfd/wm831x/core.h +4 -0
index 0d515ee..ebead1c 100644
@@ -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;
 
Signature · 1 line
1.7.5.3
author
#2 lore raw

PATCH 2/9 mfd: Implement support for multiple WM831x devices

Systems using this functionality will be uncommon.

---
 drivers/mfd/wm831x-core.c |   18 ++++++++++++------
 1 files changed, 12 insertions(+), 6 deletions(-)
drivers/mfd/wm831x-core.c +12 -6
index 265f75f..04994b2 100644
@@ -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)
Signature · 1 line
1.7.5.3
author
#3 lore raw

PATCH 3/9 mfd: Allow touchscreen to be disabled on wm831x devices

In reply to 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.

---
 drivers/mfd/wm831x-core.c        |   27 +++++++++++++++++----------
 include/linux/mfd/wm831x/pdata.h |    3 +++
 2 files changed, 20 insertions(+), 10 deletions(-)
drivers/mfd/wm831x-core.c +17 -10
index 04994b2..ff57a16 100644
@@ -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:
include/linux/mfd/wm831x/pdata.h +3 -0
index ff42d70..0ba2459 100644
@@ -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];
Signature · 1 line
1.7.5.3
author
#4 lore raw

PATCH 4/9 mfd: Only register wm831x RTC device if the 32.768kHz crystal is enabled

In reply to 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.

---
 drivers/mfd/wm831x-core.c |   48 ++++++++++++++++++++++++++------------------
 1 files changed, 28 insertions(+), 20 deletions(-)
drivers/mfd/wm831x-core.c +28 -20
index ff57a16..58f033b 100644
@@ -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,
Signature · 1 line
1.7.5.3
author
#5 lore raw

PATCH 5/9 mfd: Support dynamic allocation of IRQ range for wm831x

In reply to 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.

---
 drivers/mfd/wm831x-irq.c        |   18 +++++++++++++-----
 include/linux/mfd/wm831x/core.h |    2 +-
 2 files changed, 14 insertions(+), 6 deletions(-)
drivers/mfd/wm831x-irq.c +13 -5
index b23d8d5..1808deb 100644
@@ -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;
include/linux/mfd/wm831x/core.h +1 -1
index ebead1c..9564cf3 100644
@@ -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 */
 
Signature · 1 line
1.7.5.3
author
#6 lore raw

PATCH 6/9 mfd: Read wm831x AUXADC conversion results before acknowledging interrupt

In reply to 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.

---
 drivers/mfd/wm831x-core.c       |   47 +++++++++++++++++++++++++-------------
 include/linux/mfd/wm831x/core.h |    1 +
 2 files changed, 32 insertions(+), 16 deletions(-)
drivers/mfd/wm831x-core.c +31 -16
index 58f033b..480abc1 100644
@@ -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);
 
include/linux/mfd/wm831x/core.h +1 -0
index 9564cf3..592e4fd 100644
@@ -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
Signature · 1 line
1.7.5.3
author
#7 lore raw

PATCH 7/9 mfd: Refactor wm831x AUXADC handling into a separate file

In reply to 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.

---
 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
drivers/mfd/Makefile +1 -0
index efe3cc3..9f41923 100644
@@ -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
drivers/mfd/wm831x-auxadc.c new file +199 -0

199 lines not on this page · raw message

drivers/mfd/wm831x-core.c +1 -166

185 lines not on this page · raw message

Signature · 1 line
1.7.5.3
author
#8 lore raw

PATCH 8/9 mfd: Allocate wm835x irq descs dynamically

In reply to Mark Brown

From: Sascha Hauer <[email protected]>

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.

---
 drivers/mfd/wm8350-irq.c |   18 ++++++++++++------
 1 files changed, 12 insertions(+), 6 deletions(-)
drivers/mfd/wm8350-irq.c +12 -6
index ed4b22a..8a1fafd 100644
@@ -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,
Signature · 1 line
1.7.5.3
author
#9 lore raw

PATCH 9/9 mfd: Restructure wm8994-core device revision handling

In reply to Mark Brown

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

---
 drivers/mfd/wm8994-core.c |   13 +++++++++----
 1 files changed, 9 insertions(+), 4 deletions(-)
drivers/mfd/wm8994-core.c +9 -4
index e198d40..18f19b7 100644
@@ -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;
Signature · 1 line
1.7.5.3
#10 lore raw
In reply to Mark Brown

Hi Mark,

Quoted 3 lines · Mark Brown

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.