linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation
@ 2013-12-03  3:42 Felipe Balbi
  2013-12-03  3:42 ` [PATCH v2 02/15] mfd: menelaus: Switch over to module_i2c_driver Felipe Balbi
                   ` (17 more replies)
  0 siblings, 18 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-03  3:42 UTC (permalink / raw)
  To: linux-arm-kernel

we could build that as a driver.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index ad25bfa..975ff9e 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -1262,7 +1262,7 @@ fail:
 	return err;
 }
 
-static int __exit menelaus_remove(struct i2c_client *client)
+static int menelaus_remove(struct i2c_client *client)
 {
 	struct menelaus_chip	*menelaus = i2c_get_clientdata(client);
 
@@ -1283,7 +1283,7 @@ static struct i2c_driver menelaus_i2c_driver = {
 		.name		= DRIVER_NAME,
 	},
 	.probe		= menelaus_probe,
-	.remove		= __exit_p(menelaus_remove),
+	.remove		= menelaus_remove,
 	.id_table	= menelaus_id,
 };
 
-- 
1.8.4.GIT

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

* [PATCH v2 02/15] mfd: menelaus: Switch over to module_i2c_driver
  2013-12-03  3:42 [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Felipe Balbi
@ 2013-12-03  3:42 ` Felipe Balbi
  2013-12-03  3:42 ` [PATCH v2 03/15] mfd: menelaus: Convert to threaded irq Felipe Balbi
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-03  3:42 UTC (permalink / raw)
  To: linux-arm-kernel

just a macro to remove some boilerplate code,
no functional changes.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 23 +----------------------
 1 file changed, 1 insertion(+), 22 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 975ff9e..8bd97ca 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -1287,29 +1287,8 @@ static struct i2c_driver menelaus_i2c_driver = {
 	.id_table	= menelaus_id,
 };
 
-static int __init menelaus_init(void)
-{
-	int res;
-
-	res = i2c_add_driver(&menelaus_i2c_driver);
-	if (res < 0) {
-		pr_err(DRIVER_NAME ": driver registration failed\n");
-		return res;
-	}
-
-	return 0;
-}
-
-static void __exit menelaus_exit(void)
-{
-	i2c_del_driver(&menelaus_i2c_driver);
-
-	/* FIXME: Shutdown menelaus parts that can be shut down */
-}
+module_i2c_driver(menelaus_i2c_driver);
 
 MODULE_AUTHOR("Texas Instruments, Inc. (and others)");
 MODULE_DESCRIPTION("I2C interface for Menelaus.");
 MODULE_LICENSE("GPL");
-
-module_init(menelaus_init);
-module_exit(menelaus_exit);
-- 
1.8.4.GIT

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

* [PATCH v2 03/15] mfd: menelaus: Convert to threaded irq
  2013-12-03  3:42 [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Felipe Balbi
  2013-12-03  3:42 ` [PATCH v2 02/15] mfd: menelaus: Switch over to module_i2c_driver Felipe Balbi
@ 2013-12-03  3:42 ` Felipe Balbi
  2013-12-03  3:42 ` [PATCH v2 04/15] mfd: menelaus: Remove unnecessary loop Felipe Balbi
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-03  3:42 UTC (permalink / raw)
  To: linux-arm-kernel

we don't need that extra workqueue when we
have generic threaded irq handlers support.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 29 ++++-------------------------
 1 file changed, 4 insertions(+), 25 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 8bd97ca..11d7d81 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -36,7 +36,6 @@
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/mutex.h>
-#include <linux/workqueue.h>
 #include <linux/delay.h>
 #include <linux/rtc.h>
 #include <linux/bcd.h>
@@ -161,12 +160,9 @@
 #define MCT_PIN_ST_S1_CD_ST		(1 << 0)
 #define MCT_PIN_ST_S2_CD_ST		(1 << 1)
 
-static void menelaus_work(struct work_struct *_menelaus);
-
 struct menelaus_chip {
 	struct mutex		lock;
 	struct i2c_client	*client;
-	struct work_struct	work;
 #ifdef CONFIG_RTC_DRV_TWL92330
 	struct rtc_device	*rtc;
 	u8			rtc_control;
@@ -795,11 +791,9 @@ out:
 
 /*-----------------------------------------------------------------------*/
 
-/* Handles Menelaus interrupts. Does not run in interrupt context */
-static void menelaus_work(struct work_struct *_menelaus)
+static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 {
-	struct menelaus_chip *menelaus =
-			container_of(_menelaus, struct menelaus_chip, work);
+	struct menelaus_chip *menelaus = _menelaus;
 	void (*handler)(struct menelaus_chip *menelaus);
 
 	while (1) {
@@ -826,18 +820,6 @@ static void menelaus_work(struct work_struct *_menelaus)
 			mutex_unlock(&menelaus->lock);
 		}
 	}
-	enable_irq(menelaus->client->irq);
-}
-
-/*
- * We cannot use I2C in interrupt context, so we just schedule work.
- */
-static irqreturn_t menelaus_irq(int irq, void *_menelaus)
-{
-	struct menelaus_chip *menelaus = _menelaus;
-
-	disable_irq_nosync(irq);
-	(void)schedule_work(&menelaus->work);
 
 	return IRQ_HANDLED;
 }
@@ -1225,8 +1207,8 @@ static int menelaus_probe(struct i2c_client *client,
 	menelaus_write_reg(MENELAUS_MCT_CTRL1, 0x73);
 
 	if (client->irq > 0) {
-		err = request_irq(client->irq, menelaus_irq, 0,
-				  DRIVER_NAME, menelaus);
+		err = request_threaded_irq(client->irq, NULL, menelaus_irq,
+				IRQF_ONESHOT, DRIVER_NAME, menelaus);
 		if (err) {
 			dev_dbg(&client->dev,  "can't get IRQ %d, err %d\n",
 					client->irq, err);
@@ -1235,7 +1217,6 @@ static int menelaus_probe(struct i2c_client *client,
 	}
 
 	mutex_init(&menelaus->lock);
-	INIT_WORK(&menelaus->work, menelaus_work);
 
 	pr_info("Menelaus rev %d.%d\n", rev >> 4, rev & 0x0f);
 
@@ -1258,7 +1239,6 @@ static int menelaus_probe(struct i2c_client *client,
 	return 0;
 fail:
 	free_irq(client->irq, menelaus);
-	flush_work(&menelaus->work);
 	return err;
 }
 
@@ -1267,7 +1247,6 @@ static int menelaus_remove(struct i2c_client *client)
 	struct menelaus_chip	*menelaus = i2c_get_clientdata(client);
 
 	free_irq(client->irq, menelaus);
-	flush_work(&menelaus->work);
 	the_menelaus = NULL;
 	return 0;
 }
-- 
1.8.4.GIT

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

* [PATCH v2 04/15] mfd: menelaus: Remove unnecessary loop
  2013-12-03  3:42 [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Felipe Balbi
  2013-12-03  3:42 ` [PATCH v2 02/15] mfd: menelaus: Switch over to module_i2c_driver Felipe Balbi
  2013-12-03  3:42 ` [PATCH v2 03/15] mfd: menelaus: Convert to threaded irq Felipe Balbi
@ 2013-12-03  3:42 ` Felipe Balbi
  2013-12-03  3:42 ` [PATCH v2 05/15] mfd: menelaus: Use for_each_set_bit() Felipe Balbi
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-03  3:42 UTC (permalink / raw)
  To: linux-arm-kernel

we can let irqs refire and give the scheduler
a chance to choose when we should be scheduled.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 43 +++++++++++++++++++------------------------
 1 file changed, 19 insertions(+), 24 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 11d7d81..11dc4d3 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -795,30 +795,25 @@ static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 {
 	struct menelaus_chip *menelaus = _menelaus;
 	void (*handler)(struct menelaus_chip *menelaus);
-
-	while (1) {
-		unsigned isr;
-
-		isr = (menelaus_read_reg(MENELAUS_INT_STATUS2)
-				& ~menelaus->mask2) << 8;
-		isr |= menelaus_read_reg(MENELAUS_INT_STATUS1)
-				& ~menelaus->mask1;
-		if (!isr)
-			break;
-
-		while (isr) {
-			int irq = fls(isr) - 1;
-			isr &= ~(1 << irq);
-
-			mutex_lock(&menelaus->lock);
-			menelaus_disable_irq(irq);
-			menelaus_ack_irq(irq);
-			handler = menelaus->handlers[irq];
-			if (handler)
-				handler(menelaus);
-			menelaus_enable_irq(irq);
-			mutex_unlock(&menelaus->lock);
-		}
+	unsigned isr;
+
+	isr = (menelaus_read_reg(MENELAUS_INT_STATUS2)
+			& ~menelaus->mask2) << 8;
+	isr |= menelaus_read_reg(MENELAUS_INT_STATUS1)
+		& ~menelaus->mask1;
+
+	while (isr) {
+		int irq = fls(isr) - 1;
+		isr &= ~(1 << irq);
+
+		mutex_lock(&menelaus->lock);
+		menelaus_disable_irq(irq);
+		menelaus_ack_irq(irq);
+		handler = menelaus->handlers[irq];
+		if (handler)
+			handler(menelaus);
+		menelaus_enable_irq(irq);
+		mutex_unlock(&menelaus->lock);
 	}
 
 	return IRQ_HANDLED;
-- 
1.8.4.GIT

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

* [PATCH v2 05/15] mfd: menelaus: Use for_each_set_bit()
  2013-12-03  3:42 [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Felipe Balbi
                   ` (2 preceding siblings ...)
  2013-12-03  3:42 ` [PATCH v2 04/15] mfd: menelaus: Remove unnecessary loop Felipe Balbi
@ 2013-12-03  3:42 ` Felipe Balbi
  2013-12-03  3:42 ` [PATCH v2 06/15] mfd: menelaus: Pass menelaus pointer as argument to enable/disable irq Felipe Balbi
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-03  3:42 UTC (permalink / raw)
  To: linux-arm-kernel

that macro just helps removing some extra
line of code and hides ffs() calls.

while at that, also fix a variable shadowing
bug where 'int irq' was being redeclared inside
inner loop while it was also argument to interrupt
handler.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 11dc4d3..9ccbb79 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -795,24 +795,22 @@ static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 {
 	struct menelaus_chip *menelaus = _menelaus;
 	void (*handler)(struct menelaus_chip *menelaus);
-	unsigned isr;
+	unsigned long isr;
+	unsigned long i;
 
 	isr = (menelaus_read_reg(MENELAUS_INT_STATUS2)
 			& ~menelaus->mask2) << 8;
 	isr |= menelaus_read_reg(MENELAUS_INT_STATUS1)
 		& ~menelaus->mask1;
 
-	while (isr) {
-		int irq = fls(isr) - 1;
-		isr &= ~(1 << irq);
-
+	for_each_set_bit(i, &isr, 16) {
 		mutex_lock(&menelaus->lock);
-		menelaus_disable_irq(irq);
-		menelaus_ack_irq(irq);
-		handler = menelaus->handlers[irq];
+		menelaus_disable_irq(i);
+		menelaus_ack_irq(i);
+		handler = menelaus->handlers[i];
 		if (handler)
 			handler(menelaus);
-		menelaus_enable_irq(irq);
+		menelaus_enable_irq(i);
 		mutex_unlock(&menelaus->lock);
 	}
 
-- 
1.8.4.GIT

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

* [PATCH v2 06/15] mfd: menelaus: Pass menelaus pointer as argument to enable/disable irq
  2013-12-03  3:42 [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Felipe Balbi
                   ` (3 preceding siblings ...)
  2013-12-03  3:42 ` [PATCH v2 05/15] mfd: menelaus: Use for_each_set_bit() Felipe Balbi
@ 2013-12-03  3:42 ` Felipe Balbi
  2013-12-03  3:43 ` [PATCH v2 07/15] mfd: menelaus: Limit the usage of the_menelaus Felipe Balbi
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-03  3:42 UTC (permalink / raw)
  To: linux-arm-kernel

we want to, eventually, get rid of the global
the_menelaus pointer, so let's start passing
menelaus as argument to some function calls
and slowly phase out the_menelaus global pointer.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 48 ++++++++++++++++++++++++------------------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 9ccbb79..4c51e4b 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -199,35 +199,35 @@ static int menelaus_read_reg(int reg)
 	return val;
 }
 
-static int menelaus_enable_irq(int irq)
+static int menelaus_enable_irq(struct menelaus_chip *m, int irq)
 {
 	if (irq > 7) {
 		irq -= 8;
-		the_menelaus->mask2 &= ~(1 << irq);
+		m->mask2 &= ~(1 << irq);
 		return menelaus_write_reg(MENELAUS_INT_MASK2,
-				the_menelaus->mask2);
+				m->mask2);
 	} else {
-		the_menelaus->mask1 &= ~(1 << irq);
+		m->mask1 &= ~(1 << irq);
 		return menelaus_write_reg(MENELAUS_INT_MASK1,
-				the_menelaus->mask1);
+				m->mask1);
 	}
 }
 
-static int menelaus_disable_irq(int irq)
+static int menelaus_disable_irq(struct menelaus_chip *m, int irq)
 {
 	if (irq > 7) {
 		irq -= 8;
-		the_menelaus->mask2 |= (1 << irq);
+		m->mask2 |= (1 << irq);
 		return menelaus_write_reg(MENELAUS_INT_MASK2,
-				the_menelaus->mask2);
+				m->mask2);
 	} else {
-		the_menelaus->mask1 |= (1 << irq);
+		m->mask1 |= (1 << irq);
 		return menelaus_write_reg(MENELAUS_INT_MASK1,
-				the_menelaus->mask1);
+				m->mask1);
 	}
 }
 
-static int menelaus_ack_irq(int irq)
+static int menelaus_ack_irq(struct menelaus_chip *m, int irq)
 {
 	if (irq > 7)
 		return menelaus_write_reg(MENELAUS_INT_ACK2, 1 << (irq - 8));
@@ -243,7 +243,7 @@ static int menelaus_add_irq_work(int irq,
 
 	mutex_lock(&the_menelaus->lock);
 	the_menelaus->handlers[irq] = handler;
-	ret = menelaus_enable_irq(irq);
+	ret = menelaus_enable_irq(the_menelaus, irq);
 	mutex_unlock(&the_menelaus->lock);
 
 	return ret;
@@ -255,7 +255,7 @@ static int menelaus_remove_irq_work(int irq)
 	int ret = 0;
 
 	mutex_lock(&the_menelaus->lock);
-	ret = menelaus_disable_irq(irq);
+	ret = menelaus_disable_irq(the_menelaus, irq);
 	the_menelaus->handlers[irq] = NULL;
 	mutex_unlock(&the_menelaus->lock);
 
@@ -793,25 +793,25 @@ out:
 
 static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 {
-	struct menelaus_chip *menelaus = _menelaus;
-	void (*handler)(struct menelaus_chip *menelaus);
+	struct menelaus_chip *m = _menelaus;
+	void (*handler)(struct menelaus_chip *m);
 	unsigned long isr;
 	unsigned long i;
 
 	isr = (menelaus_read_reg(MENELAUS_INT_STATUS2)
-			& ~menelaus->mask2) << 8;
+			& ~m->mask2) << 8;
 	isr |= menelaus_read_reg(MENELAUS_INT_STATUS1)
-		& ~menelaus->mask1;
+		& ~m->mask1;
 
 	for_each_set_bit(i, &isr, 16) {
-		mutex_lock(&menelaus->lock);
-		menelaus_disable_irq(i);
-		menelaus_ack_irq(i);
-		handler = menelaus->handlers[i];
+		mutex_lock(&m->lock);
+		menelaus_disable_irq(m, i);
+		menelaus_ack_irq(m, i);
+		handler = m->handlers[i];
 		if (handler)
-			handler(menelaus);
-		menelaus_enable_irq(i);
-		mutex_unlock(&menelaus->lock);
+			handler(m);
+		menelaus_enable_irq(m, i);
+		mutex_unlock(&m->lock);
 	}
 
 	return IRQ_HANDLED;
-- 
1.8.4.GIT

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

* [PATCH v2 07/15] mfd: menelaus: Limit the usage of the_menelaus
  2013-12-03  3:42 [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Felipe Balbi
                   ` (4 preceding siblings ...)
  2013-12-03  3:42 ` [PATCH v2 06/15] mfd: menelaus: Pass menelaus pointer as argument to enable/disable irq Felipe Balbi
@ 2013-12-03  3:43 ` Felipe Balbi
  2013-12-03  3:43 ` [PATCH v2 08/15] mfd: menelaus: Pass menelaus_chip pointer to add/remove irq functions Felipe Balbi
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-03  3:43 UTC (permalink / raw)
  To: linux-arm-kernel

pass a menelaus_chip pointer as argument to most
functions so we can minimize the usage of the
global the_menelaus pointer.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 265 ++++++++++++++++++++++++++-----------------------
 1 file changed, 142 insertions(+), 123 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 4c51e4b..8796e5e 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -177,9 +177,9 @@ struct menelaus_chip {
 
 static struct menelaus_chip *the_menelaus;
 
-static int menelaus_write_reg(int reg, u8 value)
+static int menelaus_write_reg(struct menelaus_chip *m, int reg, u8 value)
 {
-	int val = i2c_smbus_write_byte_data(the_menelaus->client, reg, value);
+	int val = i2c_smbus_write_byte_data(m->client, reg, value);
 
 	if (val < 0) {
 		pr_err(DRIVER_NAME ": write error");
@@ -189,9 +189,9 @@ static int menelaus_write_reg(int reg, u8 value)
 	return 0;
 }
 
-static int menelaus_read_reg(int reg)
+static int menelaus_read_reg(struct menelaus_chip *m, int reg)
 {
-	int val = i2c_smbus_read_byte_data(the_menelaus->client, reg);
+	int val = i2c_smbus_read_byte_data(m->client, reg);
 
 	if (val < 0)
 		pr_err(DRIVER_NAME ": read error");
@@ -204,11 +204,11 @@ static int menelaus_enable_irq(struct menelaus_chip *m, int irq)
 	if (irq > 7) {
 		irq -= 8;
 		m->mask2 &= ~(1 << irq);
-		return menelaus_write_reg(MENELAUS_INT_MASK2,
+		return menelaus_write_reg(m, MENELAUS_INT_MASK2,
 				m->mask2);
 	} else {
 		m->mask1 &= ~(1 << irq);
-		return menelaus_write_reg(MENELAUS_INT_MASK1,
+		return menelaus_write_reg(m, MENELAUS_INT_MASK1,
 				m->mask1);
 	}
 }
@@ -218,11 +218,11 @@ static int menelaus_disable_irq(struct menelaus_chip *m, int irq)
 	if (irq > 7) {
 		irq -= 8;
 		m->mask2 |= (1 << irq);
-		return menelaus_write_reg(MENELAUS_INT_MASK2,
+		return menelaus_write_reg(m, MENELAUS_INT_MASK2,
 				m->mask2);
 	} else {
 		m->mask1 |= (1 << irq);
-		return menelaus_write_reg(MENELAUS_INT_MASK1,
+		return menelaus_write_reg(m, MENELAUS_INT_MASK1,
 				m->mask1);
 	}
 }
@@ -230,9 +230,9 @@ static int menelaus_disable_irq(struct menelaus_chip *m, int irq)
 static int menelaus_ack_irq(struct menelaus_chip *m, int irq)
 {
 	if (irq > 7)
-		return menelaus_write_reg(MENELAUS_INT_ACK2, 1 << (irq - 8));
+		return menelaus_write_reg(m, MENELAUS_INT_ACK2, 1 << (irq - 8));
 	else
-		return menelaus_write_reg(MENELAUS_INT_ACK1, 1 << irq);
+		return menelaus_write_reg(m, MENELAUS_INT_ACK1, 1 << irq);
 }
 
 /* Adds a handler for an interrupt. Does not run in interrupt context */
@@ -268,12 +268,12 @@ static int menelaus_remove_irq_work(int irq)
  * in each slot. In this case the cards are not seen by menelaus.
  * FIXME: Add handling for D1 too
  */
-static void menelaus_mmc_cd_work(struct menelaus_chip *menelaus_hw)
+static void menelaus_mmc_cd_work(struct menelaus_chip *m)
 {
 	int reg;
 	unsigned char card_mask = 0;
 
-	reg = menelaus_read_reg(MENELAUS_MCT_PIN_ST);
+	reg = menelaus_read_reg(m, MENELAUS_MCT_PIN_ST);
 	if (reg < 0)
 		return;
 
@@ -283,8 +283,8 @@ static void menelaus_mmc_cd_work(struct menelaus_chip *menelaus_hw)
 	if (!(reg & 0x2))
 		card_mask |= MCT_PIN_ST_S2_CD_ST;
 
-	if (menelaus_hw->mmc_callback)
-		menelaus_hw->mmc_callback(menelaus_hw->mmc_callback_data,
+	if (m->mmc_callback)
+		m->mmc_callback(m->mmc_callback_data,
 					  card_mask);
 }
 
@@ -293,14 +293,16 @@ static void menelaus_mmc_cd_work(struct menelaus_chip *menelaus_hw)
  */
 int menelaus_set_mmc_opendrain(int slot, int enable)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int ret, val;
 
 	if (slot != 1 && slot != 2)
 		return -EINVAL;
-	mutex_lock(&the_menelaus->lock);
-	ret = menelaus_read_reg(MENELAUS_MCT_CTRL1);
+
+	mutex_lock(&m->lock);
+	ret = menelaus_read_reg(m, MENELAUS_MCT_CTRL1);
 	if (ret < 0) {
-		mutex_unlock(&the_menelaus->lock);
+		mutex_unlock(&m->lock);
 		return ret;
 	}
 	val = ret;
@@ -315,8 +317,8 @@ int menelaus_set_mmc_opendrain(int slot, int enable)
 		else
 			val &= ~MCT_CTRL1_S2_CMD_OD;
 	}
-	ret = menelaus_write_reg(MENELAUS_MCT_CTRL1, val);
-	mutex_unlock(&the_menelaus->lock);
+	ret = menelaus_write_reg(m, MENELAUS_MCT_CTRL1, val);
+	mutex_unlock(&m->lock);
 
 	return ret;
 }
@@ -324,10 +326,12 @@ EXPORT_SYMBOL(menelaus_set_mmc_opendrain);
 
 int menelaus_set_slot_sel(int enable)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int ret;
 
-	mutex_lock(&the_menelaus->lock);
-	ret = menelaus_read_reg(MENELAUS_GPIO_CTRL);
+	mutex_lock(&m->lock);
+
+	ret = menelaus_read_reg(m, MENELAUS_GPIO_CTRL);
 	if (ret < 0)
 		goto out;
 	ret |= GPIO2_DIR_INPUT;
@@ -335,15 +339,16 @@ int menelaus_set_slot_sel(int enable)
 		ret |= GPIO_CTRL_SLOTSELEN;
 	else
 		ret &= ~GPIO_CTRL_SLOTSELEN;
-	ret = menelaus_write_reg(MENELAUS_GPIO_CTRL, ret);
+	ret = menelaus_write_reg(m, MENELAUS_GPIO_CTRL, ret);
 out:
-	mutex_unlock(&the_menelaus->lock);
+	mutex_unlock(&m->lock);
 	return ret;
 }
 EXPORT_SYMBOL(menelaus_set_slot_sel);
 
 int menelaus_set_mmc_slot(int slot, int enable, int power, int cd_en)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int ret, val;
 
 	if (slot != 1 && slot != 2)
@@ -351,9 +356,9 @@ int menelaus_set_mmc_slot(int slot, int enable, int power, int cd_en)
 	if (power >= 3)
 		return -EINVAL;
 
-	mutex_lock(&the_menelaus->lock);
+	mutex_lock(&m->lock);
 
-	ret = menelaus_read_reg(MENELAUS_MCT_CTRL2);
+	ret = menelaus_read_reg(m, MENELAUS_MCT_CTRL2);
 	if (ret < 0)
 		goto out;
 	val = ret;
@@ -368,11 +373,11 @@ int menelaus_set_mmc_slot(int slot, int enable, int power, int cd_en)
 		else
 			val &= ~(MCT_CTRL2_S2CD_BUFEN | MCT_CTRL2_S2CD_BEN);
 	}
-	ret = menelaus_write_reg(MENELAUS_MCT_CTRL2, val);
+	ret = menelaus_write_reg(m, MENELAUS_MCT_CTRL2, val);
 	if (ret < 0)
 		goto out;
 
-	ret = menelaus_read_reg(MENELAUS_MCT_CTRL3);
+	ret = menelaus_read_reg(m, MENELAUS_MCT_CTRL3);
 	if (ret < 0)
 		goto out;
 	val = ret;
@@ -388,18 +393,18 @@ int menelaus_set_mmc_slot(int slot, int enable, int power, int cd_en)
 			val |= MCT_CTRL3_SLOT2_EN;
 		else
 			val &= ~MCT_CTRL3_SLOT2_EN;
-		b = menelaus_read_reg(MENELAUS_MCT_CTRL2);
+		b = menelaus_read_reg(m, MENELAUS_MCT_CTRL2);
 		b &= ~(MCT_CTRL2_VS2_SEL_D0 | MCT_CTRL2_VS2_SEL_D1);
 		b |= power;
-		ret = menelaus_write_reg(MENELAUS_MCT_CTRL2, b);
+		ret = menelaus_write_reg(m, MENELAUS_MCT_CTRL2, b);
 		if (ret < 0)
 			goto out;
 	}
 	/* Disable autonomous shutdown */
 	val &= ~(MCT_CTRL3_S1_AUTO_EN | MCT_CTRL3_S2_AUTO_EN);
-	ret = menelaus_write_reg(MENELAUS_MCT_CTRL3, val);
+	ret = menelaus_write_reg(m, MENELAUS_MCT_CTRL3, val);
 out:
-	mutex_unlock(&the_menelaus->lock);
+	mutex_unlock(&m->lock);
 	return ret;
 }
 EXPORT_SYMBOL(menelaus_set_mmc_slot);
@@ -458,14 +463,15 @@ struct menelaus_vtg_value {
 static int menelaus_set_voltage(const struct menelaus_vtg *vtg, int mV,
 				int vtg_val, int mode)
 {
+	struct menelaus_chip *m = the_menelaus;
+	struct i2c_client *c = m->client;
 	int val, ret;
-	struct i2c_client *c = the_menelaus->client;
 
-	mutex_lock(&the_menelaus->lock);
+	mutex_lock(&m->lock);
 	if (!vtg)
 		goto set_voltage;
 
-	ret = menelaus_read_reg(vtg->vtg_reg);
+	ret = menelaus_read_reg(m, vtg->vtg_reg);
 	if (ret < 0)
 		goto out;
 	val = ret & ~(((1 << vtg->vtg_bits) - 1) << vtg->vtg_shift);
@@ -475,13 +481,13 @@ static int menelaus_set_voltage(const struct menelaus_vtg *vtg, int mV,
 			 "to %d mV (reg 0x%02x, val 0x%02x)\n",
 			vtg->name, mV, vtg->vtg_reg, val);
 
-	ret = menelaus_write_reg(vtg->vtg_reg, val);
+	ret = menelaus_write_reg(m, vtg->vtg_reg, val);
 	if (ret < 0)
 		goto out;
 set_voltage:
-	ret = menelaus_write_reg(vtg->mode_reg, mode);
+	ret = menelaus_write_reg(m, vtg->mode_reg, mode);
 out:
-	mutex_unlock(&the_menelaus->lock);
+	mutex_unlock(&m->lock);
 	if (ret == 0) {
 		/* Wait for voltage to stabilize */
 		msleep(1);
@@ -533,8 +539,9 @@ static const struct menelaus_vtg_value vcore_values[] = {
 
 int menelaus_set_vcore_sw(unsigned int mV)
 {
+	struct menelaus_chip *m = the_menelaus;
+	struct i2c_client *c = m->client;
 	int val, ret;
-	struct i2c_client *c = the_menelaus->client;
 
 	val = menelaus_get_vtg_value(mV, vcore_values,
 				     ARRAY_SIZE(vcore_values));
@@ -544,11 +551,11 @@ int menelaus_set_vcore_sw(unsigned int mV)
 	dev_dbg(&c->dev, "Setting VCORE to %d mV (val 0x%02x)\n", mV, val);
 
 	/* Set SW mode and the voltage in one go. */
-	mutex_lock(&the_menelaus->lock);
-	ret = menelaus_write_reg(MENELAUS_VCORE_CTRL1, val);
+	mutex_lock(&m->lock);
+	ret = menelaus_write_reg(m, MENELAUS_VCORE_CTRL1, val);
 	if (ret == 0)
-		the_menelaus->vcore_hw_mode = 0;
-	mutex_unlock(&the_menelaus->lock);
+		m->vcore_hw_mode = 0;
+	mutex_unlock(&m->lock);
 	msleep(1);
 
 	return ret;
@@ -556,8 +563,9 @@ int menelaus_set_vcore_sw(unsigned int mV)
 
 int menelaus_set_vcore_hw(unsigned int roof_mV, unsigned int floor_mV)
 {
+	struct menelaus_chip *m = the_menelaus;
+	struct i2c_client *c = m->client;
 	int fval, rval, val, ret;
-	struct i2c_client *c = the_menelaus->client;
 
 	rval = menelaus_get_vtg_value(roof_mV, vcore_values,
 				      ARRAY_SIZE(vcore_values));
@@ -571,23 +579,23 @@ int menelaus_set_vcore_hw(unsigned int roof_mV, unsigned int floor_mV)
 	dev_dbg(&c->dev, "Setting VCORE FLOOR to %d mV and ROOF to %d mV\n",
 	       floor_mV, roof_mV);
 
-	mutex_lock(&the_menelaus->lock);
-	ret = menelaus_write_reg(MENELAUS_VCORE_CTRL3, fval);
+	mutex_lock(&m->lock);
+	ret = menelaus_write_reg(m, MENELAUS_VCORE_CTRL3, fval);
 	if (ret < 0)
 		goto out;
-	ret = menelaus_write_reg(MENELAUS_VCORE_CTRL4, rval);
+	ret = menelaus_write_reg(m, MENELAUS_VCORE_CTRL4, rval);
 	if (ret < 0)
 		goto out;
-	if (!the_menelaus->vcore_hw_mode) {
-		val = menelaus_read_reg(MENELAUS_VCORE_CTRL1);
+	if (!m->vcore_hw_mode) {
+		val = menelaus_read_reg(m, MENELAUS_VCORE_CTRL1);
 		/* HW mode, turn OFF byte comparator */
 		val |= (VCORE_CTRL1_HW_NSW | VCORE_CTRL1_BYP_COMP);
-		ret = menelaus_write_reg(MENELAUS_VCORE_CTRL1, val);
-		the_menelaus->vcore_hw_mode = 1;
+		ret = menelaus_write_reg(m, MENELAUS_VCORE_CTRL1, val);
+		m->vcore_hw_mode = 1;
 	}
 	msleep(1);
 out:
-	mutex_unlock(&the_menelaus->lock);
+	mutex_unlock(&m->lock);
 	return ret;
 }
 
@@ -759,23 +767,26 @@ EXPORT_SYMBOL(menelaus_set_vaux);
 
 int menelaus_get_slot_pin_states(void)
 {
-	return menelaus_read_reg(MENELAUS_MCT_PIN_ST);
+	struct menelaus_chip *m = the_menelaus;
+
+	return menelaus_read_reg(m, MENELAUS_MCT_PIN_ST);
 }
 EXPORT_SYMBOL(menelaus_get_slot_pin_states);
 
 int menelaus_set_regulator_sleep(int enable, u32 val)
 {
+	struct menelaus_chip *m = the_menelaus;
+	struct i2c_client *c = m->client;
 	int t, ret;
-	struct i2c_client *c = the_menelaus->client;
 
-	mutex_lock(&the_menelaus->lock);
-	ret = menelaus_write_reg(MENELAUS_SLEEP_CTRL2, val);
+	mutex_lock(&m->lock);
+	ret = menelaus_write_reg(m, MENELAUS_SLEEP_CTRL2, val);
 	if (ret < 0)
 		goto out;
 
 	dev_dbg(&c->dev, "regulator sleep configuration: %02x\n", val);
 
-	ret = menelaus_read_reg(MENELAUS_GPIO_CTRL);
+	ret = menelaus_read_reg(m, MENELAUS_GPIO_CTRL);
 	if (ret < 0)
 		goto out;
 	t = (GPIO_CTRL_SLPCTLEN | GPIO3_DIR_INPUT);
@@ -783,9 +794,9 @@ int menelaus_set_regulator_sleep(int enable, u32 val)
 		ret |= t;
 	else
 		ret &= ~t;
-	ret = menelaus_write_reg(MENELAUS_GPIO_CTRL, ret);
+	ret = menelaus_write_reg(m, MENELAUS_GPIO_CTRL, ret);
 out:
-	mutex_unlock(&the_menelaus->lock);
+	mutex_unlock(&m->lock);
 	return ret;
 }
 
@@ -798,9 +809,9 @@ static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 	unsigned long isr;
 	unsigned long i;
 
-	isr = (menelaus_read_reg(MENELAUS_INT_STATUS2)
+	isr = (menelaus_read_reg(m, MENELAUS_INT_STATUS2)
 			& ~m->mask2) << 8;
-	isr |= menelaus_read_reg(MENELAUS_INT_STATUS1)
+	isr |= menelaus_read_reg(m, MENELAUS_INT_STATUS1)
 		& ~m->mask1;
 
 	for_each_set_bit(i, &isr, 16) {
@@ -841,9 +852,11 @@ static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 
 static void menelaus_to_time(char *regs, struct rtc_time *t)
 {
+	struct menelaus_chip *m = the_menelaus;
+
 	t->tm_sec = bcd2bin(regs[0]);
 	t->tm_min = bcd2bin(regs[1]);
-	if (the_menelaus->rtc_control & RTC_CTRL_MODE12) {
+	if (m->rtc_control & RTC_CTRL_MODE12) {
 		t->tm_hour = bcd2bin(regs[2] & 0x1f) - 1;
 		if (regs[2] & RTC_HR_PM)
 			t->tm_hour += 12;
@@ -856,17 +869,18 @@ static void menelaus_to_time(char *regs, struct rtc_time *t)
 
 static int time_to_menelaus(struct rtc_time *t, int regnum)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int	hour, status;
 
-	status = menelaus_write_reg(regnum++, bin2bcd(t->tm_sec));
+	status = menelaus_write_reg(m, regnum++, bin2bcd(t->tm_sec));
 	if (status < 0)
 		goto fail;
 
-	status = menelaus_write_reg(regnum++, bin2bcd(t->tm_min));
+	status = menelaus_write_reg(m, regnum++, bin2bcd(t->tm_min));
 	if (status < 0)
 		goto fail;
 
-	if (the_menelaus->rtc_control & RTC_CTRL_MODE12) {
+	if (m->rtc_control & RTC_CTRL_MODE12) {
 		hour = t->tm_hour + 1;
 		if (hour > 12)
 			hour = RTC_HR_PM | bin2bcd(hour - 12);
@@ -874,31 +888,32 @@ static int time_to_menelaus(struct rtc_time *t, int regnum)
 			hour = bin2bcd(hour);
 	} else
 		hour = bin2bcd(t->tm_hour);
-	status = menelaus_write_reg(regnum++, hour);
+	status = menelaus_write_reg(m, regnum++, hour);
 	if (status < 0)
 		goto fail;
 
-	status = menelaus_write_reg(regnum++, bin2bcd(t->tm_mday));
+	status = menelaus_write_reg(m, regnum++, bin2bcd(t->tm_mday));
 	if (status < 0)
 		goto fail;
 
-	status = menelaus_write_reg(regnum++, bin2bcd(t->tm_mon + 1));
+	status = menelaus_write_reg(m, regnum++, bin2bcd(t->tm_mon + 1));
 	if (status < 0)
 		goto fail;
 
-	status = menelaus_write_reg(regnum++, bin2bcd(t->tm_year - 100));
+	status = menelaus_write_reg(m, regnum++, bin2bcd(t->tm_year - 100));
 	if (status < 0)
 		goto fail;
 
 	return 0;
 fail:
-	dev_err(&the_menelaus->client->dev, "rtc write reg %02x, err %d\n",
+	dev_err(&m->client->dev, "rtc write reg %02x, err %d\n",
 			--regnum, status);
 	return status;
 }
 
 static int menelaus_read_time(struct device *dev, struct rtc_time *t)
 {
+	struct menelaus_chip *m = dev_get_drvdata(dev);
 	struct i2c_msg	msg[2];
 	char		regs[7];
 	int		status;
@@ -916,7 +931,7 @@ static int menelaus_read_time(struct device *dev, struct rtc_time *t)
 	msg[1].len = sizeof(regs);
 	msg[1].buf = regs;
 
-	status = i2c_transfer(the_menelaus->client->adapter, msg, 2);
+	status = i2c_transfer(m->client->adapter, msg, 2);
 	if (status != 2) {
 		dev_err(dev, "%s error %d\n", "read", status);
 		return -EIO;
@@ -930,23 +945,24 @@ static int menelaus_read_time(struct device *dev, struct rtc_time *t)
 
 static int menelaus_set_time(struct device *dev, struct rtc_time *t)
 {
+	struct menelaus_chip *m = dev_get_drvdata(dev);
 	int		status;
 
 	/* write date and time registers */
 	status = time_to_menelaus(t, MENELAUS_RTC_SEC);
 	if (status < 0)
 		return status;
-	status = menelaus_write_reg(MENELAUS_RTC_WKDAY, bin2bcd(t->tm_wday));
+	status = menelaus_write_reg(m, MENELAUS_RTC_WKDAY, bin2bcd(t->tm_wday));
 	if (status < 0) {
-		dev_err(&the_menelaus->client->dev, "rtc write reg %02x "
+		dev_err(&m->client->dev, "rtc write reg %02x "
 				"err %d\n", MENELAUS_RTC_WKDAY, status);
 		return status;
 	}
 
 	/* now commit the write */
-	status = menelaus_write_reg(MENELAUS_RTC_UPDATE, RTC_UPDATE_EVERY);
+	status = menelaus_write_reg(m, MENELAUS_RTC_UPDATE, RTC_UPDATE_EVERY);
 	if (status < 0)
-		dev_err(&the_menelaus->client->dev, "rtc commit time, err %d\n",
+		dev_err(&m->client->dev, "rtc commit time, err %d\n",
 				status);
 
 	return 0;
@@ -954,6 +970,7 @@ static int menelaus_set_time(struct device *dev, struct rtc_time *t)
 
 static int menelaus_read_alarm(struct device *dev, struct rtc_wkalrm *w)
 {
+	struct menelaus_chip *m = dev_get_drvdata(dev);
 	struct i2c_msg	msg[2];
 	char		regs[6];
 	int		status;
@@ -971,7 +988,7 @@ static int menelaus_read_alarm(struct device *dev, struct rtc_wkalrm *w)
 	msg[1].len = sizeof(regs);
 	msg[1].buf = regs;
 
-	status = i2c_transfer(the_menelaus->client->adapter, msg, 2);
+	status = i2c_transfer(m->client->adapter, msg, 2);
 	if (status != 2) {
 		dev_err(dev, "%s error %d\n", "alarm read", status);
 		return -EIO;
@@ -979,7 +996,7 @@ static int menelaus_read_alarm(struct device *dev, struct rtc_wkalrm *w)
 
 	menelaus_to_time(regs, &w->time);
 
-	w->enabled = !!(the_menelaus->rtc_control & RTC_CTRL_AL_EN);
+	w->enabled = !!(m->rtc_control & RTC_CTRL_AL_EN);
 
 	/* NOTE we *could* check if actually pending... */
 	w->pending = 0;
@@ -989,16 +1006,17 @@ static int menelaus_read_alarm(struct device *dev, struct rtc_wkalrm *w)
 
 static int menelaus_set_alarm(struct device *dev, struct rtc_wkalrm *w)
 {
+	struct menelaus_chip *m = dev_get_drvdata(dev);
 	int		status;
 
-	if (the_menelaus->client->irq <= 0 && w->enabled)
+	if (m->client->irq <= 0 && w->enabled)
 		return -ENODEV;
 
 	/* clear previous alarm enable */
-	if (the_menelaus->rtc_control & RTC_CTRL_AL_EN) {
-		the_menelaus->rtc_control &= ~RTC_CTRL_AL_EN;
-		status = menelaus_write_reg(MENELAUS_RTC_CTRL,
-				the_menelaus->rtc_control);
+	if (m->rtc_control & RTC_CTRL_AL_EN) {
+		m->rtc_control &= ~RTC_CTRL_AL_EN;
+		status = menelaus_write_reg(m, MENELAUS_RTC_CTRL,
+				m->rtc_control);
 		if (status < 0)
 			return status;
 	}
@@ -1010,9 +1028,9 @@ static int menelaus_set_alarm(struct device *dev, struct rtc_wkalrm *w)
 
 	/* enable alarm if requested */
 	if (w->enabled) {
-		the_menelaus->rtc_control |= RTC_CTRL_AL_EN;
-		status = menelaus_write_reg(MENELAUS_RTC_CTRL,
-				the_menelaus->rtc_control);
+		m->rtc_control |= RTC_CTRL_AL_EN;
+		status = menelaus_write_reg(m, MENELAUS_RTC_CTRL,
+				m->rtc_control);
 	}
 
 	return status;
@@ -1030,44 +1048,45 @@ static void menelaus_rtc_update_work(struct menelaus_chip *m)
 
 static int menelaus_ioctl(struct device *dev, unsigned cmd, unsigned long arg)
 {
+	struct menelaus_chip *m = dev_get_drvdata(dev);
 	int	status;
 
-	if (the_menelaus->client->irq <= 0)
+	if (m->client->irq <= 0)
 		return -ENOIOCTLCMD;
 
 	switch (cmd) {
 	/* alarm IRQ */
 	case RTC_AIE_ON:
-		if (the_menelaus->rtc_control & RTC_CTRL_AL_EN)
+		if (m->rtc_control & RTC_CTRL_AL_EN)
 			return 0;
-		the_menelaus->rtc_control |= RTC_CTRL_AL_EN;
+		m->rtc_control |= RTC_CTRL_AL_EN;
 		break;
 	case RTC_AIE_OFF:
-		if (!(the_menelaus->rtc_control & RTC_CTRL_AL_EN))
+		if (!(m->rtc_control & RTC_CTRL_AL_EN))
 			return 0;
-		the_menelaus->rtc_control &= ~RTC_CTRL_AL_EN;
+		m->rtc_control &= ~RTC_CTRL_AL_EN;
 		break;
 	/* 1/second "update" IRQ */
 	case RTC_UIE_ON:
-		if (the_menelaus->uie)
+		if (m->uie)
 			return 0;
 		status = menelaus_remove_irq_work(MENELAUS_RTCTMR_IRQ);
 		status = menelaus_add_irq_work(MENELAUS_RTCTMR_IRQ,
 				menelaus_rtc_update_work);
 		if (status == 0)
-			the_menelaus->uie = 1;
+			m->uie = 1;
 		return status;
 	case RTC_UIE_OFF:
-		if (!the_menelaus->uie)
+		if (!m->uie)
 			return 0;
 		status = menelaus_remove_irq_work(MENELAUS_RTCTMR_IRQ);
 		if (status == 0)
-			the_menelaus->uie = 0;
+			m->uie = 0;
 		return status;
 	default:
 		return -ENOIOCTLCMD;
 	}
-	return menelaus_write_reg(MENELAUS_RTC_CTRL, the_menelaus->rtc_control);
+	return menelaus_write_reg(m, MENELAUS_RTC_CTRL, m->rtc_control);
 }
 
 #else
@@ -1092,8 +1111,8 @@ static void menelaus_rtc_alarm_work(struct menelaus_chip *m)
 	local_irq_enable();
 
 	/* then disable it; alarms are oneshot */
-	the_menelaus->rtc_control &= ~RTC_CTRL_AL_EN;
-	menelaus_write_reg(MENELAUS_RTC_CTRL, the_menelaus->rtc_control);
+	m->rtc_control &= ~RTC_CTRL_AL_EN;
+	menelaus_write_reg(m, MENELAUS_RTC_CTRL, m->rtc_control);
 }
 
 static inline void menelaus_rtc_init(struct menelaus_chip *m)
@@ -1101,7 +1120,7 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 	int	alarm = (m->client->irq > 0);
 
 	/* assume 32KDETEN pin is pulled high */
-	if (!(menelaus_read_reg(MENELAUS_OSC_CTRL) & 0x80)) {
+	if (!(menelaus_read_reg(m, MENELAUS_OSC_CTRL) & 0x80)) {
 		dev_dbg(&m->client->dev, "no 32k oscillator\n");
 		return;
 	}
@@ -1117,7 +1136,7 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 	}
 
 	/* be sure RTC is enabled; allow 1/sec irqs; leave 12hr mode alone */
-	m->rtc_control = menelaus_read_reg(MENELAUS_RTC_CTRL);
+	m->rtc_control = menelaus_read_reg(m, MENELAUS_RTC_CTRL);
 	if (!(m->rtc_control & RTC_CTRL_RTC_EN)
 			|| (m->rtc_control & RTC_CTRL_AL_EN)
 			|| (m->rtc_control & RTC_CTRL_EVERY_MASK)) {
@@ -1127,7 +1146,7 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 		}
 		m->rtc_control &= ~RTC_CTRL_EVERY_MASK;
 		m->rtc_control &= ~RTC_CTRL_AL_EN;
-		menelaus_write_reg(MENELAUS_RTC_CTRL, m->rtc_control);
+		menelaus_write_reg(m, MENELAUS_RTC_CTRL, m->rtc_control);
 	}
 
 	m->rtc = rtc_device_register(DRIVER_NAME,
@@ -1140,7 +1159,7 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 		}
 		dev_err(&m->client->dev, "can't register RTC: %d\n",
 				(int) PTR_ERR(m->rtc));
-		the_menelaus->rtc = NULL;
+		m->rtc = NULL;
 	}
 }
 
@@ -1160,7 +1179,7 @@ static struct i2c_driver menelaus_i2c_driver;
 static int menelaus_probe(struct i2c_client *client,
 			  const struct i2c_device_id *id)
 {
-	struct menelaus_chip	*menelaus;
+	struct menelaus_chip	*m;
 	int			rev = 0, val;
 	int			err = 0;
 	struct menelaus_platform_data *menelaus_pdata =
@@ -1172,36 +1191,36 @@ static int menelaus_probe(struct i2c_client *client,
 		return -ENODEV;
 	}
 
-	menelaus = devm_kzalloc(&client->dev, sizeof(*menelaus), GFP_KERNEL);
-	if (!menelaus)
+	m = devm_kzalloc(&client->dev, sizeof(*m), GFP_KERNEL);
+	if (!m)
 		return -ENOMEM;
 
-	i2c_set_clientdata(client, menelaus);
+	i2c_set_clientdata(client, m);
 
-	the_menelaus = menelaus;
-	menelaus->client = client;
+	the_menelaus = m;
+	m->client = client;
 
 	/* If a true probe check the device */
-	rev = menelaus_read_reg(MENELAUS_REV);
+	rev = menelaus_read_reg(m, MENELAUS_REV);
 	if (rev < 0) {
 		pr_err(DRIVER_NAME ": device not found");
 		return -ENODEV;
 	}
 
 	/* Ack and disable all Menelaus interrupts */
-	menelaus_write_reg(MENELAUS_INT_ACK1, 0xff);
-	menelaus_write_reg(MENELAUS_INT_ACK2, 0xff);
-	menelaus_write_reg(MENELAUS_INT_MASK1, 0xff);
-	menelaus_write_reg(MENELAUS_INT_MASK2, 0xff);
-	menelaus->mask1 = 0xff;
-	menelaus->mask2 = 0xff;
+	menelaus_write_reg(m, MENELAUS_INT_ACK1, 0xff);
+	menelaus_write_reg(m, MENELAUS_INT_ACK2, 0xff);
+	menelaus_write_reg(m, MENELAUS_INT_MASK1, 0xff);
+	menelaus_write_reg(m, MENELAUS_INT_MASK2, 0xff);
+	m->mask1 = 0xff;
+	m->mask2 = 0xff;
 
 	/* Set output buffer strengths */
-	menelaus_write_reg(MENELAUS_MCT_CTRL1, 0x73);
+	menelaus_write_reg(m, MENELAUS_MCT_CTRL1, 0x73);
 
 	if (client->irq > 0) {
 		err = request_threaded_irq(client->irq, NULL, menelaus_irq,
-				IRQF_ONESHOT, DRIVER_NAME, menelaus);
+				IRQF_ONESHOT, DRIVER_NAME, m);
 		if (err) {
 			dev_dbg(&client->dev,  "can't get IRQ %d, err %d\n",
 					client->irq, err);
@@ -1209,17 +1228,17 @@ static int menelaus_probe(struct i2c_client *client,
 		}
 	}
 
-	mutex_init(&menelaus->lock);
+	mutex_init(&m->lock);
 
 	pr_info("Menelaus rev %d.%d\n", rev >> 4, rev & 0x0f);
 
-	val = menelaus_read_reg(MENELAUS_VCORE_CTRL1);
+	val = menelaus_read_reg(m, MENELAUS_VCORE_CTRL1);
 	if (val < 0)
 		goto fail;
 	if (val & (1 << 7))
-		menelaus->vcore_hw_mode = 1;
+		m->vcore_hw_mode = 1;
 	else
-		menelaus->vcore_hw_mode = 0;
+		m->vcore_hw_mode = 0;
 
 	if (menelaus_pdata != NULL && menelaus_pdata->late_init != NULL) {
 		err = menelaus_pdata->late_init(&client->dev);
@@ -1227,19 +1246,19 @@ static int menelaus_probe(struct i2c_client *client,
 			goto fail;
 	}
 
-	menelaus_rtc_init(menelaus);
+	menelaus_rtc_init(m);
 
 	return 0;
 fail:
-	free_irq(client->irq, menelaus);
+	free_irq(client->irq, m);
 	return err;
 }
 
 static int menelaus_remove(struct i2c_client *client)
 {
-	struct menelaus_chip	*menelaus = i2c_get_clientdata(client);
+	struct menelaus_chip	*m = i2c_get_clientdata(client);
 
-	free_irq(client->irq, menelaus);
+	free_irq(client->irq, m);
 	the_menelaus = NULL;
 	return 0;
 }
-- 
1.8.4.GIT

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

* [PATCH v2 08/15] mfd: menelaus: Pass menelaus_chip pointer to add/remove irq functions
  2013-12-03  3:42 [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Felipe Balbi
                   ` (5 preceding siblings ...)
  2013-12-03  3:43 ` [PATCH v2 07/15] mfd: menelaus: Limit the usage of the_menelaus Felipe Balbi
@ 2013-12-03  3:43 ` Felipe Balbi
  2013-12-03  3:43 ` [PATCH v2 09/15] mfd: menelaus: Pass menelaus_chip pointer to get/set voltage Felipe Balbi
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-03  3:43 UTC (permalink / raw)
  To: linux-arm-kernel

those functions are static and can receive a
menelaus_chip pointer very easily.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 57 ++++++++++++++++++++++++++------------------------
 1 file changed, 30 insertions(+), 27 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 8796e5e..8672d86 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -236,28 +236,28 @@ static int menelaus_ack_irq(struct menelaus_chip *m, int irq)
 }
 
 /* Adds a handler for an interrupt. Does not run in interrupt context */
-static int menelaus_add_irq_work(int irq,
+static int menelaus_add_irq_work(struct menelaus_chip *m, int irq,
 		void (*handler)(struct menelaus_chip *))
 {
 	int ret = 0;
 
-	mutex_lock(&the_menelaus->lock);
-	the_menelaus->handlers[irq] = handler;
-	ret = menelaus_enable_irq(the_menelaus, irq);
-	mutex_unlock(&the_menelaus->lock);
+	mutex_lock(&m->lock);
+	m->handlers[irq] = handler;
+	ret = menelaus_enable_irq(m, irq);
+	mutex_unlock(&m->lock);
 
 	return ret;
 }
 
 /* Removes handler for an interrupt */
-static int menelaus_remove_irq_work(int irq)
+static int menelaus_remove_irq_work(struct menelaus_chip *m, int irq)
 {
 	int ret = 0;
 
-	mutex_lock(&the_menelaus->lock);
-	ret = menelaus_disable_irq(the_menelaus, irq);
-	the_menelaus->handlers[irq] = NULL;
-	mutex_unlock(&the_menelaus->lock);
+	mutex_lock(&m->lock);
+	ret = menelaus_disable_irq(m, irq);
+	m->handlers[irq] = NULL;
+	mutex_unlock(&m->lock);
 
 	return ret;
 }
@@ -412,23 +412,24 @@ EXPORT_SYMBOL(menelaus_set_mmc_slot);
 int menelaus_register_mmc_callback(void (*callback)(void *data, u8 card_mask),
 				   void *data)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int ret = 0;
 
-	the_menelaus->mmc_callback_data = data;
-	the_menelaus->mmc_callback = callback;
-	ret = menelaus_add_irq_work(MENELAUS_MMC_S1CD_IRQ,
+	m->mmc_callback_data = data;
+	m->mmc_callback = callback;
+	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S1CD_IRQ,
 				    menelaus_mmc_cd_work);
 	if (ret < 0)
 		return ret;
-	ret = menelaus_add_irq_work(MENELAUS_MMC_S2CD_IRQ,
+	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S2CD_IRQ,
 				    menelaus_mmc_cd_work);
 	if (ret < 0)
 		return ret;
-	ret = menelaus_add_irq_work(MENELAUS_MMC_S1D1_IRQ,
+	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S1D1_IRQ,
 				    menelaus_mmc_cd_work);
 	if (ret < 0)
 		return ret;
-	ret = menelaus_add_irq_work(MENELAUS_MMC_S2D1_IRQ,
+	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S2D1_IRQ,
 				    menelaus_mmc_cd_work);
 
 	return ret;
@@ -437,13 +438,15 @@ EXPORT_SYMBOL(menelaus_register_mmc_callback);
 
 void menelaus_unregister_mmc_callback(void)
 {
-	menelaus_remove_irq_work(MENELAUS_MMC_S1CD_IRQ);
-	menelaus_remove_irq_work(MENELAUS_MMC_S2CD_IRQ);
-	menelaus_remove_irq_work(MENELAUS_MMC_S1D1_IRQ);
-	menelaus_remove_irq_work(MENELAUS_MMC_S2D1_IRQ);
+	struct menelaus_chip *m = the_menelaus;
+
+	menelaus_remove_irq_work(m, MENELAUS_MMC_S1CD_IRQ);
+	menelaus_remove_irq_work(m, MENELAUS_MMC_S2CD_IRQ);
+	menelaus_remove_irq_work(m, MENELAUS_MMC_S1D1_IRQ);
+	menelaus_remove_irq_work(m, MENELAUS_MMC_S2D1_IRQ);
 
-	the_menelaus->mmc_callback = NULL;
-	the_menelaus->mmc_callback_data = NULL;
+	m->mmc_callback = NULL;
+	m->mmc_callback_data = NULL;
 }
 EXPORT_SYMBOL(menelaus_unregister_mmc_callback);
 
@@ -1070,8 +1073,8 @@ static int menelaus_ioctl(struct device *dev, unsigned cmd, unsigned long arg)
 	case RTC_UIE_ON:
 		if (m->uie)
 			return 0;
-		status = menelaus_remove_irq_work(MENELAUS_RTCTMR_IRQ);
-		status = menelaus_add_irq_work(MENELAUS_RTCTMR_IRQ,
+		status = menelaus_remove_irq_work(m, MENELAUS_RTCTMR_IRQ);
+		status = menelaus_add_irq_work(m, MENELAUS_RTCTMR_IRQ,
 				menelaus_rtc_update_work);
 		if (status == 0)
 			m->uie = 1;
@@ -1079,7 +1082,7 @@ static int menelaus_ioctl(struct device *dev, unsigned cmd, unsigned long arg)
 	case RTC_UIE_OFF:
 		if (!m->uie)
 			return 0;
-		status = menelaus_remove_irq_work(MENELAUS_RTCTMR_IRQ);
+		status = menelaus_remove_irq_work(m, MENELAUS_RTCTMR_IRQ);
 		if (status == 0)
 			m->uie = 0;
 		return status;
@@ -1127,7 +1130,7 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 
 	/* support RTC alarm; it can issue wakeups */
 	if (alarm) {
-		if (menelaus_add_irq_work(MENELAUS_RTCALM_IRQ,
+		if (menelaus_add_irq_work(m, MENELAUS_RTCALM_IRQ,
 				menelaus_rtc_alarm_work) < 0) {
 			dev_err(&m->client->dev, "can't handle RTC alarm\n");
 			return;
@@ -1154,7 +1157,7 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 			&menelaus_rtc_ops, THIS_MODULE);
 	if (IS_ERR(m->rtc)) {
 		if (alarm) {
-			menelaus_remove_irq_work(MENELAUS_RTCALM_IRQ);
+			menelaus_remove_irq_work(m, MENELAUS_RTCALM_IRQ);
 			device_init_wakeup(&m->client->dev, 0);
 		}
 		dev_err(&m->client->dev, "can't register RTC: %d\n",
-- 
1.8.4.GIT

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

* [PATCH v2 09/15] mfd: menelaus: Pass menelaus_chip pointer to get/set voltage
  2013-12-03  3:42 [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Felipe Balbi
                   ` (6 preceding siblings ...)
  2013-12-03  3:43 ` [PATCH v2 08/15] mfd: menelaus: Pass menelaus_chip pointer to add/remove irq functions Felipe Balbi
@ 2013-12-03  3:43 ` Felipe Balbi
  2013-12-03  3:43 ` [PATCH v2 10/15] mfd: menelaus: Pass menelaus_chip argument to menelaus <-> time helpers Felipe Balbi
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-03  3:43 UTC (permalink / raw)
  To: linux-arm-kernel

those functions are static and can easily receive
a menelaus_chip pointer argument.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 50 +++++++++++++++++++++++++++-----------------------
 1 file changed, 27 insertions(+), 23 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 8672d86..13d1cb0 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -463,10 +463,9 @@ struct menelaus_vtg_value {
 	u16 val;
 };
 
-static int menelaus_set_voltage(const struct menelaus_vtg *vtg, int mV,
-				int vtg_val, int mode)
+static int menelaus_set_voltage(struct menelaus_chip *m,
+		const struct menelaus_vtg *vtg, int mV, int vtg_val, int mode)
 {
-	struct menelaus_chip *m = the_menelaus;
 	struct i2c_client *c = m->client;
 	int val, ret;
 
@@ -498,8 +497,8 @@ out:
 	return ret;
 }
 
-static int menelaus_get_vtg_value(int vtg, const struct menelaus_vtg_value *tbl,
-				  int n)
+static int menelaus_get_vtg_value(struct menelaus_chip *m,
+		int vtg, const struct menelaus_vtg_value *tbl, int n)
 {
 	int i;
 
@@ -546,7 +545,7 @@ int menelaus_set_vcore_sw(unsigned int mV)
 	struct i2c_client *c = m->client;
 	int val, ret;
 
-	val = menelaus_get_vtg_value(mV, vcore_values,
+	val = menelaus_get_vtg_value(m, mV, vcore_values,
 				     ARRAY_SIZE(vcore_values));
 	if (val < 0)
 		return -EINVAL;
@@ -570,11 +569,11 @@ int menelaus_set_vcore_hw(unsigned int roof_mV, unsigned int floor_mV)
 	struct i2c_client *c = m->client;
 	int fval, rval, val, ret;
 
-	rval = menelaus_get_vtg_value(roof_mV, vcore_values,
+	rval = menelaus_get_vtg_value(m, roof_mV, vcore_values,
 				      ARRAY_SIZE(vcore_values));
 	if (rval < 0)
 		return -EINVAL;
-	fval = menelaus_get_vtg_value(floor_mV, vcore_values,
+	fval = menelaus_get_vtg_value(m, floor_mV, vcore_values,
 				      ARRAY_SIZE(vcore_values));
 	if (fval < 0)
 		return -EINVAL;
@@ -619,15 +618,16 @@ static const struct menelaus_vtg_value vmem_values[] = {
 
 int menelaus_set_vmem(unsigned int mV)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int val;
 
 	if (mV == 0)
-		return menelaus_set_voltage(&vmem_vtg, 0, 0, 0);
+		return menelaus_set_voltage(m, &vmem_vtg, 0, 0, 0);
 
-	val = menelaus_get_vtg_value(mV, vmem_values, ARRAY_SIZE(vmem_values));
+	val = menelaus_get_vtg_value(m, mV, vmem_values, ARRAY_SIZE(vmem_values));
 	if (val < 0)
 		return -EINVAL;
-	return menelaus_set_voltage(&vmem_vtg, mV, val, 0x02);
+	return menelaus_set_voltage(m, &vmem_vtg, mV, val, 0x02);
 }
 EXPORT_SYMBOL(menelaus_set_vmem);
 
@@ -648,15 +648,16 @@ static const struct menelaus_vtg_value vio_values[] = {
 
 int menelaus_set_vio(unsigned int mV)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int val;
 
 	if (mV == 0)
-		return menelaus_set_voltage(&vio_vtg, 0, 0, 0);
+		return menelaus_set_voltage(m, &vio_vtg, 0, 0, 0);
 
-	val = menelaus_get_vtg_value(mV, vio_values, ARRAY_SIZE(vio_values));
+	val = menelaus_get_vtg_value(m, mV, vio_values, ARRAY_SIZE(vio_values));
 	if (val < 0)
 		return -EINVAL;
-	return menelaus_set_voltage(&vio_vtg, mV, val, 0x02);
+	return menelaus_set_voltage(m, &vio_vtg, mV, val, 0x02);
 }
 EXPORT_SYMBOL(menelaus_set_vio);
 
@@ -689,6 +690,7 @@ static const struct menelaus_vtg vdcdc3_vtg = {
 
 int menelaus_set_vdcdc(int dcdc, unsigned int mV)
 {
+	struct menelaus_chip *m = the_menelaus;
 	const struct menelaus_vtg *vtg;
 	int val;
 
@@ -700,13 +702,13 @@ int menelaus_set_vdcdc(int dcdc, unsigned int mV)
 		vtg = &vdcdc3_vtg;
 
 	if (mV == 0)
-		return menelaus_set_voltage(vtg, 0, 0, 0);
+		return menelaus_set_voltage(m, vtg, 0, 0, 0);
 
-	val = menelaus_get_vtg_value(mV, vdcdc_values,
+	val = menelaus_get_vtg_value(m, mV, vdcdc_values,
 				     ARRAY_SIZE(vdcdc_values));
 	if (val < 0)
 		return -EINVAL;
-	return menelaus_set_voltage(vtg, mV, val, 0x03);
+	return menelaus_set_voltage(m, vtg, mV, val, 0x03);
 }
 
 static const struct menelaus_vtg_value vmmc_values[] = {
@@ -726,15 +728,16 @@ static const struct menelaus_vtg vmmc_vtg = {
 
 int menelaus_set_vmmc(unsigned int mV)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int val;
 
 	if (mV == 0)
-		return menelaus_set_voltage(&vmmc_vtg, 0, 0, 0);
+		return menelaus_set_voltage(m, &vmmc_vtg, 0, 0, 0);
 
-	val = menelaus_get_vtg_value(mV, vmmc_values, ARRAY_SIZE(vmmc_values));
+	val = menelaus_get_vtg_value(m, mV, vmmc_values, ARRAY_SIZE(vmmc_values));
 	if (val < 0)
 		return -EINVAL;
-	return menelaus_set_voltage(&vmmc_vtg, mV, val, 0x02);
+	return menelaus_set_voltage(m, &vmmc_vtg, mV, val, 0x02);
 }
 EXPORT_SYMBOL(menelaus_set_vmmc);
 
@@ -756,15 +759,16 @@ static const struct menelaus_vtg vaux_vtg = {
 
 int menelaus_set_vaux(unsigned int mV)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int val;
 
 	if (mV == 0)
-		return menelaus_set_voltage(&vaux_vtg, 0, 0, 0);
+		return menelaus_set_voltage(m, &vaux_vtg, 0, 0, 0);
 
-	val = menelaus_get_vtg_value(mV, vaux_values, ARRAY_SIZE(vaux_values));
+	val = menelaus_get_vtg_value(m, mV, vaux_values, ARRAY_SIZE(vaux_values));
 	if (val < 0)
 		return -EINVAL;
-	return menelaus_set_voltage(&vaux_vtg, mV, val, 0x02);
+	return menelaus_set_voltage(m, &vaux_vtg, mV, val, 0x02);
 }
 EXPORT_SYMBOL(menelaus_set_vaux);
 
-- 
1.8.4.GIT

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

* [PATCH v2 10/15] mfd: menelaus: Pass menelaus_chip argument to menelaus <-> time helpers
  2013-12-03  3:42 [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Felipe Balbi
                   ` (7 preceding siblings ...)
  2013-12-03  3:43 ` [PATCH v2 09/15] mfd: menelaus: Pass menelaus_chip pointer to get/set voltage Felipe Balbi
@ 2013-12-03  3:43 ` Felipe Balbi
  2013-12-03  3:43 ` [PATCH v2 11/15] mfd: menelaus: Start to use irqdomain Felipe Balbi
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-03  3:43 UTC (permalink / raw)
  To: linux-arm-kernel

time_to_menelaus() and menelaus_to_time() are
static and can easily receive a struct menelaus_chip
pointer argument.

After this patch, the_menelaus is only used on
exported functions which are currently being
used by board-n8x0.c.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 13d1cb0..aa3c579 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -857,10 +857,9 @@ static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 
 #define RTC_HR_PM		(1 << 7)
 
-static void menelaus_to_time(char *regs, struct rtc_time *t)
+static void menelaus_to_time(struct menelaus_chip *m,
+		char *regs, struct rtc_time *t)
 {
-	struct menelaus_chip *m = the_menelaus;
-
 	t->tm_sec = bcd2bin(regs[0]);
 	t->tm_min = bcd2bin(regs[1]);
 	if (m->rtc_control & RTC_CTRL_MODE12) {
@@ -874,9 +873,9 @@ static void menelaus_to_time(char *regs, struct rtc_time *t)
 	t->tm_year = bcd2bin(regs[5]) + 100;
 }
 
-static int time_to_menelaus(struct rtc_time *t, int regnum)
+static int time_to_menelaus(struct menelaus_chip *m,
+		struct rtc_time *t, int regnum)
 {
-	struct menelaus_chip *m = the_menelaus;
 	int	hour, status;
 
 	status = menelaus_write_reg(m, regnum++, bin2bcd(t->tm_sec));
@@ -944,7 +943,7 @@ static int menelaus_read_time(struct device *dev, struct rtc_time *t)
 		return -EIO;
 	}
 
-	menelaus_to_time(regs, t);
+	menelaus_to_time(m, regs, t);
 	t->tm_wday = bcd2bin(regs[6]);
 
 	return 0;
@@ -956,7 +955,7 @@ static int menelaus_set_time(struct device *dev, struct rtc_time *t)
 	int		status;
 
 	/* write date and time registers */
-	status = time_to_menelaus(t, MENELAUS_RTC_SEC);
+	status = time_to_menelaus(m, t, MENELAUS_RTC_SEC);
 	if (status < 0)
 		return status;
 	status = menelaus_write_reg(m, MENELAUS_RTC_WKDAY, bin2bcd(t->tm_wday));
@@ -1001,7 +1000,7 @@ static int menelaus_read_alarm(struct device *dev, struct rtc_wkalrm *w)
 		return -EIO;
 	}
 
-	menelaus_to_time(regs, &w->time);
+	menelaus_to_time(m, regs, &w->time);
 
 	w->enabled = !!(m->rtc_control & RTC_CTRL_AL_EN);
 
@@ -1029,7 +1028,7 @@ static int menelaus_set_alarm(struct device *dev, struct rtc_wkalrm *w)
 	}
 
 	/* write alarm registers */
-	status = time_to_menelaus(&w->time, MENELAUS_RTC_AL_SEC);
+	status = time_to_menelaus(m, &w->time, MENELAUS_RTC_AL_SEC);
 	if (status < 0)
 		return status;
 
-- 
1.8.4.GIT

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

* [PATCH v2 11/15] mfd: menelaus: Start to use irqdomain
  2013-12-03  3:42 [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Felipe Balbi
                   ` (8 preceding siblings ...)
  2013-12-03  3:43 ` [PATCH v2 10/15] mfd: menelaus: Pass menelaus_chip argument to menelaus <-> time helpers Felipe Balbi
@ 2013-12-03  3:43 ` Felipe Balbi
  2013-12-03  3:43 ` [PATCH v2 12/15] mfd: menelaus: Switch all children to threaded_irq Felipe Balbi
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-03  3:43 UTC (permalink / raw)
  To: linux-arm-kernel

introduce an irq_chip and irq_domain for
menelaus driver. Following patches will
convert uses to traditional request_threaded_irq().

while at that, some better error handling had
to be added, so we could free irq descs we
allocated.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 120 insertions(+), 7 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index aa3c579..e4f33b7 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -34,6 +34,7 @@
 #include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
+#include <linux/irqdomain.h>
 #include <linux/sched.h>
 #include <linux/mutex.h>
 #include <linux/delay.h>
@@ -47,6 +48,7 @@
 #include <asm/gpio.h>
 
 #define DRIVER_NAME			"menelaus"
+#define MENELAUS_NR_IRQS		16
 
 #define MENELAUS_I2C_ADDRESS		0x72
 
@@ -168,11 +170,19 @@ struct menelaus_chip {
 	u8			rtc_control;
 	unsigned		uie:1;
 #endif
+	int			irq_base;
 	unsigned		vcore_hw_mode:1;
 	u8			mask1, mask2;
+	u8			ack1, ack2;
+
 	void			(*handlers[16])(struct menelaus_chip *);
 	void			(*mmc_callback)(void *data, u8 mask);
 	void			*mmc_callback_data;
+
+	unsigned		mask1_pending:1;
+	unsigned		mask2_pending:1;
+	unsigned		ack1_pending:1;
+	unsigned		ack2_pending:1;
 };
 
 static struct menelaus_chip *the_menelaus;
@@ -235,6 +245,83 @@ static int menelaus_ack_irq(struct menelaus_chip *m, int irq)
 		return menelaus_write_reg(m, MENELAUS_INT_ACK1, 1 << irq);
 }
 
+static void menelaus_irq_ack(struct irq_data *data)
+{
+	struct menelaus_chip *m = irq_data_get_irq_chip_data(data);
+	int irq = data->irq - m->irq_base;
+
+	if (irq > 7) {
+		m->ack2 |= BIT(irq);
+		m->ack2_pending = true;
+	} else {
+		m->ack1 |= BIT(irq);
+		m->ack1_pending = true;
+	}
+}
+
+static void menelaus_irq_mask(struct irq_data *data)
+{
+	struct menelaus_chip *m = irq_data_get_irq_chip_data(data);
+	int irq = data->irq - m->irq_base;
+
+	if (irq > 7) {
+		m->mask2 |= BIT(irq);
+		m->mask2_pending = true;
+	} else {
+		m->mask1 |= BIT(irq);
+		m->mask1_pending = true;
+	}
+}
+
+static void menelaus_irq_unmask(struct irq_data *data)
+{
+	struct menelaus_chip *m = irq_data_get_irq_chip_data(data);
+	int irq = data->irq - m->irq_base;
+
+	if (irq > 7) {
+		m->mask2 &= ~BIT(irq);
+		m->mask2_pending = true;
+	} else {
+		m->mask1 &= ~BIT(irq);
+		m->mask1_pending = true;
+	}
+}
+
+static void menelaus_irq_bus_lock(struct irq_data *data)
+{
+	struct menelaus_chip *m = irq_data_get_irq_chip_data(data);
+
+	mutex_lock(&m->lock);
+}
+
+static void menelaus_irq_bus_sync_unlock(struct irq_data *data)
+{
+	struct menelaus_chip *m = irq_data_get_irq_chip_data(data);
+
+	if (m->ack1_pending)
+		menelaus_write_reg(m, MENELAUS_INT_ACK1, m->ack1);
+
+	if (m->ack2_pending)
+		menelaus_write_reg(m, MENELAUS_INT_ACK2, m->ack2);
+
+	if (m->mask1_pending)
+		menelaus_write_reg(m, MENELAUS_INT_MASK1, m->mask1);
+
+	if (m->mask2_pending)
+		menelaus_write_reg(m, MENELAUS_INT_MASK2, m->mask2);
+
+	mutex_unlock(&m->lock);
+}
+
+static struct irq_chip menelaus_irq_chip = {
+	.name		= "menelaus",
+	.irq_ack	= menelaus_irq_ack,
+	.irq_mask	= menelaus_irq_mask,
+	.irq_unmask	= menelaus_irq_unmask,
+	.irq_bus_lock	= menelaus_irq_bus_lock,
+	.irq_bus_sync_unlock = menelaus_irq_bus_sync_unlock,
+};
+
 /* Adds a handler for an interrupt. Does not run in interrupt context */
 static int menelaus_add_irq_work(struct menelaus_chip *m, int irq,
 		void (*handler)(struct menelaus_chip *))
@@ -1186,8 +1273,11 @@ static int menelaus_probe(struct i2c_client *client,
 			  const struct i2c_device_id *id)
 {
 	struct menelaus_chip	*m;
+	struct device_node	*node = client->dev.of_node;
 	int			rev = 0, val;
 	int			err = 0;
+	int			irq_base;
+	int			i;
 	struct menelaus_platform_data *menelaus_pdata =
 					dev_get_platdata(&client->dev);
 
@@ -1205,12 +1295,32 @@ static int menelaus_probe(struct i2c_client *client,
 
 	the_menelaus = m;
 	m->client = client;
+	mutex_init(&m->lock);
+
+	irq_base = irq_alloc_descs(-1, 0, MENELAUS_NR_IRQS, 0);
+	if (irq_base < 0) {
+		dev_err(&client->dev, "failed to allocate irq descs\n");
+		return irq_base;
+	}
+
+	irq_domain_add_legacy(node, MENELAUS_NR_IRQS, irq_base, 0,
+			&irq_domain_simple_ops, m);
+
+	m->irq_base = irq_base;
+
+	for (i = irq_base; i < irq_base + MENELAUS_NR_IRQS; i++) {
+		irq_set_chip_data(i, m);
+		irq_set_chip_and_handler(i, &menelaus_irq_chip,
+				handle_simple_irq);
+		irq_set_nested_thread(i, 1);
+		set_irq_flags(i, IRQF_VALID);
+	}
 
 	/* If a true probe check the device */
 	rev = menelaus_read_reg(m, MENELAUS_REV);
 	if (rev < 0) {
 		pr_err(DRIVER_NAME ": device not found");
-		return -ENODEV;
+		goto fail_free_descs;
 	}
 
 	/* Ack and disable all Menelaus interrupts */
@@ -1230,17 +1340,15 @@ static int menelaus_probe(struct i2c_client *client,
 		if (err) {
 			dev_dbg(&client->dev,  "can't get IRQ %d, err %d\n",
 					client->irq, err);
-			return err;
+			goto fail_free_descs;
 		}
 	}
 
-	mutex_init(&m->lock);
-
 	pr_info("Menelaus rev %d.%d\n", rev >> 4, rev & 0x0f);
 
 	val = menelaus_read_reg(m, MENELAUS_VCORE_CTRL1);
 	if (val < 0)
-		goto fail;
+		goto fail_free_irq;
 	if (val & (1 << 7))
 		m->vcore_hw_mode = 1;
 	else
@@ -1249,14 +1357,18 @@ static int menelaus_probe(struct i2c_client *client,
 	if (menelaus_pdata != NULL && menelaus_pdata->late_init != NULL) {
 		err = menelaus_pdata->late_init(&client->dev);
 		if (err < 0)
-			goto fail;
+			goto fail_free_irq;
 	}
 
 	menelaus_rtc_init(m);
 
 	return 0;
-fail:
+fail_free_irq:
 	free_irq(client->irq, m);
+
+fail_free_descs:
+	irq_free_descs(irq_base, MENELAUS_NR_IRQS);
+
 	return err;
 }
 
@@ -1265,6 +1377,7 @@ static int menelaus_remove(struct i2c_client *client)
 	struct menelaus_chip	*m = i2c_get_clientdata(client);
 
 	free_irq(client->irq, m);
+	irq_free_descs(m->irq_base, MENELAUS_NR_IRQS);
 	the_menelaus = NULL;
 	return 0;
 }
-- 
1.8.4.GIT

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

* [PATCH v2 12/15] mfd: menelaus: Switch all children to threaded_irq
  2013-12-03  3:42 [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Felipe Balbi
                   ` (9 preceding siblings ...)
  2013-12-03  3:43 ` [PATCH v2 11/15] mfd: menelaus: Start to use irqdomain Felipe Balbi
@ 2013-12-03  3:43 ` Felipe Balbi
  2013-12-03  3:43 ` [PATCH v2 13/15] mfd: menelaus: Remove unnecessary definition Felipe Balbi
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-03  3:43 UTC (permalink / raw)
  To: linux-arm-kernel

now that we have our own irq_chip, all children
can use traditional request_threaded_irq().

While at that, also remove so functions which
became unused.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 161 +++++++++++++++----------------------------------
 1 file changed, 50 insertions(+), 111 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index e4f33b7..74eae19 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -175,7 +175,6 @@ struct menelaus_chip {
 	u8			mask1, mask2;
 	u8			ack1, ack2;
 
-	void			(*handlers[16])(struct menelaus_chip *);
 	void			(*mmc_callback)(void *data, u8 mask);
 	void			*mmc_callback_data;
 
@@ -209,42 +208,6 @@ static int menelaus_read_reg(struct menelaus_chip *m, int reg)
 	return val;
 }
 
-static int menelaus_enable_irq(struct menelaus_chip *m, int irq)
-{
-	if (irq > 7) {
-		irq -= 8;
-		m->mask2 &= ~(1 << irq);
-		return menelaus_write_reg(m, MENELAUS_INT_MASK2,
-				m->mask2);
-	} else {
-		m->mask1 &= ~(1 << irq);
-		return menelaus_write_reg(m, MENELAUS_INT_MASK1,
-				m->mask1);
-	}
-}
-
-static int menelaus_disable_irq(struct menelaus_chip *m, int irq)
-{
-	if (irq > 7) {
-		irq -= 8;
-		m->mask2 |= (1 << irq);
-		return menelaus_write_reg(m, MENELAUS_INT_MASK2,
-				m->mask2);
-	} else {
-		m->mask1 |= (1 << irq);
-		return menelaus_write_reg(m, MENELAUS_INT_MASK1,
-				m->mask1);
-	}
-}
-
-static int menelaus_ack_irq(struct menelaus_chip *m, int irq)
-{
-	if (irq > 7)
-		return menelaus_write_reg(m, MENELAUS_INT_ACK2, 1 << (irq - 8));
-	else
-		return menelaus_write_reg(m, MENELAUS_INT_ACK1, 1 << irq);
-}
-
 static void menelaus_irq_ack(struct irq_data *data)
 {
 	struct menelaus_chip *m = irq_data_get_irq_chip_data(data);
@@ -322,47 +285,15 @@ static struct irq_chip menelaus_irq_chip = {
 	.irq_bus_sync_unlock = menelaus_irq_bus_sync_unlock,
 };
 
-/* Adds a handler for an interrupt. Does not run in interrupt context */
-static int menelaus_add_irq_work(struct menelaus_chip *m, int irq,
-		void (*handler)(struct menelaus_chip *))
-{
-	int ret = 0;
-
-	mutex_lock(&m->lock);
-	m->handlers[irq] = handler;
-	ret = menelaus_enable_irq(m, irq);
-	mutex_unlock(&m->lock);
-
-	return ret;
-}
-
-/* Removes handler for an interrupt */
-static int menelaus_remove_irq_work(struct menelaus_chip *m, int irq)
-{
-	int ret = 0;
-
-	mutex_lock(&m->lock);
-	ret = menelaus_disable_irq(m, irq);
-	m->handlers[irq] = NULL;
-	mutex_unlock(&m->lock);
-
-	return ret;
-}
-
-/*
- * Gets scheduled when a card detect interrupt happens. Note that in some cases
- * this line is wired to card cover switch rather than the card detect switch
- * in each slot. In this case the cards are not seen by menelaus.
- * FIXME: Add handling for D1 too
- */
-static void menelaus_mmc_cd_work(struct menelaus_chip *m)
+static irqreturn_t menelaus_mmc_cd_irq(int irq, void *_m)
 {
-	int reg;
+	struct menelaus_chip *m = _m;
 	unsigned char card_mask = 0;
+	int reg;
 
 	reg = menelaus_read_reg(m, MENELAUS_MCT_PIN_ST);
 	if (reg < 0)
-		return;
+		return IRQ_NONE;
 
 	if (!(reg & 0x1))
 		card_mask |= MCT_PIN_ST_S1_CD_ST;
@@ -373,6 +304,8 @@ static void menelaus_mmc_cd_work(struct menelaus_chip *m)
 	if (m->mmc_callback)
 		m->mmc_callback(m->mmc_callback_data,
 					  card_mask);
+
+	return IRQ_HANDLED;
 }
 
 /*
@@ -504,20 +437,25 @@ int menelaus_register_mmc_callback(void (*callback)(void *data, u8 card_mask),
 
 	m->mmc_callback_data = data;
 	m->mmc_callback = callback;
-	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S1CD_IRQ,
-				    menelaus_mmc_cd_work);
+
+	ret = request_threaded_irq(MENELAUS_MMC_S1CD_IRQ + m->irq_base,
+			NULL, menelaus_mmc_cd_irq, IRQF_ONESHOT,
+			"mmc_s1cd", m);
 	if (ret < 0)
 		return ret;
-	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S2CD_IRQ,
-				    menelaus_mmc_cd_work);
+	ret = request_threaded_irq(MENELAUS_MMC_S2CD_IRQ + m->irq_base,
+			NULL, menelaus_mmc_cd_irq, IRQF_ONESHOT,
+			"mmc_s2cd", m);
 	if (ret < 0)
 		return ret;
-	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S1D1_IRQ,
-				    menelaus_mmc_cd_work);
+	ret = request_threaded_irq(MENELAUS_MMC_S1D1_IRQ + m->irq_base,
+			NULL, menelaus_mmc_cd_irq, IRQF_ONESHOT,
+			"mmc_s1d1", m);
 	if (ret < 0)
 		return ret;
-	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S2D1_IRQ,
-				    menelaus_mmc_cd_work);
+	ret = request_threaded_irq(MENELAUS_MMC_S2D1_IRQ + m->irq_base,
+			NULL, menelaus_mmc_cd_irq, IRQF_ONESHOT,
+			"mmc_s2d1", m);
 
 	return ret;
 }
@@ -527,10 +465,10 @@ void menelaus_unregister_mmc_callback(void)
 {
 	struct menelaus_chip *m = the_menelaus;
 
-	menelaus_remove_irq_work(m, MENELAUS_MMC_S1CD_IRQ);
-	menelaus_remove_irq_work(m, MENELAUS_MMC_S2CD_IRQ);
-	menelaus_remove_irq_work(m, MENELAUS_MMC_S1D1_IRQ);
-	menelaus_remove_irq_work(m, MENELAUS_MMC_S2D1_IRQ);
+	free_irq(MENELAUS_MMC_S1CD_IRQ + m->irq_base, m);
+	free_irq(MENELAUS_MMC_S2CD_IRQ + m->irq_base, m);
+	free_irq(MENELAUS_MMC_S1D1_IRQ + m->irq_base, m);
+	free_irq(MENELAUS_MMC_S2D1_IRQ + m->irq_base, m);
 
 	m->mmc_callback = NULL;
 	m->mmc_callback_data = NULL;
@@ -899,7 +837,6 @@ out:
 static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 {
 	struct menelaus_chip *m = _menelaus;
-	void (*handler)(struct menelaus_chip *m);
 	unsigned long isr;
 	unsigned long i;
 
@@ -909,14 +846,9 @@ static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 		& ~m->mask1;
 
 	for_each_set_bit(i, &isr, 16) {
-		mutex_lock(&m->lock);
-		menelaus_disable_irq(m, i);
-		menelaus_ack_irq(m, i);
-		handler = m->handlers[i];
-		if (handler)
-			handler(m);
-		menelaus_enable_irq(m, i);
-		mutex_unlock(&m->lock);
+		int irq = i + m->irq_base;
+
+		handle_nested_irq(irq);
 	}
 
 	return IRQ_HANDLED;
@@ -1131,18 +1063,19 @@ static int menelaus_set_alarm(struct device *dev, struct rtc_wkalrm *w)
 
 #ifdef CONFIG_RTC_INTF_DEV
 
-static void menelaus_rtc_update_work(struct menelaus_chip *m)
+static irqreturn_t menelaus_rtc_update_irq(int irq, void *_m)
 {
-	/* report 1/sec update */
-	local_irq_disable();
+	struct menelaus_chip *m = _m;
+
 	rtc_update_irq(m->rtc, 1, RTC_IRQF | RTC_UF);
-	local_irq_enable();
+
+	return IRQ_HANDLED;
 }
 
 static int menelaus_ioctl(struct device *dev, unsigned cmd, unsigned long arg)
 {
 	struct menelaus_chip *m = dev_get_drvdata(dev);
-	int	status;
+	int	status = 0;
 
 	if (m->client->irq <= 0)
 		return -ENOIOCTLCMD;
@@ -1163,18 +1096,18 @@ static int menelaus_ioctl(struct device *dev, unsigned cmd, unsigned long arg)
 	case RTC_UIE_ON:
 		if (m->uie)
 			return 0;
-		status = menelaus_remove_irq_work(m, MENELAUS_RTCTMR_IRQ);
-		status = menelaus_add_irq_work(m, MENELAUS_RTCTMR_IRQ,
-				menelaus_rtc_update_work);
+		free_irq(MENELAUS_RTCTMR_IRQ + m->irq_base, m);
+		status = request_threaded_irq(MENELAUS_RTCTMR_IRQ + m->irq_base,
+				NULL, menelaus_rtc_update_irq, IRQF_ONESHOT,
+				"rtc-timer", m);
 		if (status == 0)
 			m->uie = 1;
 		return status;
 	case RTC_UIE_OFF:
 		if (!m->uie)
 			return 0;
-		status = menelaus_remove_irq_work(m, MENELAUS_RTCTMR_IRQ);
-		if (status == 0)
-			m->uie = 0;
+		free_irq(MENELAUS_RTCTMR_IRQ + m->irq_base, m);
+		m->uie = 0;
 		return status;
 	default:
 		return -ENOIOCTLCMD;
@@ -1196,16 +1129,18 @@ static const struct rtc_class_ops menelaus_rtc_ops = {
 	.set_alarm		= menelaus_set_alarm,
 };
 
-static void menelaus_rtc_alarm_work(struct menelaus_chip *m)
+static irqreturn_t menelaus_rtc_alarm_irq(int irq, void *_m)
 {
+	struct menelaus_chip *m = _m;
+
 	/* report alarm */
-	local_irq_disable();
 	rtc_update_irq(m->rtc, 1, RTC_IRQF | RTC_AF);
-	local_irq_enable();
 
 	/* then disable it; alarms are oneshot */
 	m->rtc_control &= ~RTC_CTRL_AL_EN;
 	menelaus_write_reg(m, MENELAUS_RTC_CTRL, m->rtc_control);
+
+	return IRQ_HANDLED;
 }
 
 static inline void menelaus_rtc_init(struct menelaus_chip *m)
@@ -1220,8 +1155,12 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 
 	/* support RTC alarm; it can issue wakeups */
 	if (alarm) {
-		if (menelaus_add_irq_work(m, MENELAUS_RTCALM_IRQ,
-				menelaus_rtc_alarm_work) < 0) {
+		int ret;
+
+		ret = request_threaded_irq(MENELAUS_RTCALM_IRQ + m->irq_base,
+				NULL, menelaus_rtc_alarm_irq, IRQF_ONESHOT,
+				"rtc-alarm", m);
+		if (ret < 0) {
 			dev_err(&m->client->dev, "can't handle RTC alarm\n");
 			return;
 		}
@@ -1247,7 +1186,7 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 			&menelaus_rtc_ops, THIS_MODULE);
 	if (IS_ERR(m->rtc)) {
 		if (alarm) {
-			menelaus_remove_irq_work(m, MENELAUS_RTCALM_IRQ);
+			free_irq(MENELAUS_RTCALM_IRQ + m->irq_base, m);
 			device_init_wakeup(&m->client->dev, 0);
 		}
 		dev_err(&m->client->dev, "can't register RTC: %d\n",
-- 
1.8.4.GIT

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

* [PATCH v2 13/15] mfd: menelaus: Remove unnecessary definition
  2013-12-03  3:42 [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Felipe Balbi
                   ` (10 preceding siblings ...)
  2013-12-03  3:43 ` [PATCH v2 12/15] mfd: menelaus: Switch all children to threaded_irq Felipe Balbi
@ 2013-12-03  3:43 ` Felipe Balbi
  2013-12-03  3:43 ` [PATCH v2 14/15] mfd: menelaus: IRQ is a requirement Felipe Balbi
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-03  3:43 UTC (permalink / raw)
  To: linux-arm-kernel

menelaus_i2c_driver isn't referenced on probe,
just remove that unnecessary line. No functional
changes.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 74eae19..c0219b7 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -1206,8 +1206,6 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 
 /*-----------------------------------------------------------------------*/
 
-static struct i2c_driver menelaus_i2c_driver;
-
 static int menelaus_probe(struct i2c_client *client,
 			  const struct i2c_device_id *id)
 {
-- 
1.8.4.GIT

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

* [PATCH v2 14/15] mfd: menelaus: IRQ is a requirement
  2013-12-03  3:42 [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Felipe Balbi
                   ` (11 preceding siblings ...)
  2013-12-03  3:43 ` [PATCH v2 13/15] mfd: menelaus: Remove unnecessary definition Felipe Balbi
@ 2013-12-03  3:43 ` Felipe Balbi
  2013-12-03  3:43 ` [PATCH v2 15/15] mfd: menelaus: Use devm_request_threaded_irq() Felipe Balbi
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-03  3:43 UTC (permalink / raw)
  To: linux-arm-kernel

this driver needs IRQ to work, if client->irq
isn't set properly, we won't work. Remove
check around request_threaded_irq().

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index c0219b7..bffe978 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -1271,14 +1271,12 @@ static int menelaus_probe(struct i2c_client *client,
 	/* Set output buffer strengths */
 	menelaus_write_reg(m, MENELAUS_MCT_CTRL1, 0x73);
 
-	if (client->irq > 0) {
-		err = request_threaded_irq(client->irq, NULL, menelaus_irq,
-				IRQF_ONESHOT, DRIVER_NAME, m);
-		if (err) {
-			dev_dbg(&client->dev,  "can't get IRQ %d, err %d\n",
-					client->irq, err);
-			goto fail_free_descs;
-		}
+	err = request_threaded_irq(client->irq, NULL, menelaus_irq,
+			IRQF_ONESHOT, DRIVER_NAME, m);
+	if (err) {
+		dev_dbg(&client->dev,  "can't get IRQ %d, err %d\n",
+				client->irq, err);
+		goto fail_free_descs;
 	}
 
 	pr_info("Menelaus rev %d.%d\n", rev >> 4, rev & 0x0f);
-- 
1.8.4.GIT

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

* [PATCH v2 15/15] mfd: menelaus: Use devm_request_threaded_irq()
  2013-12-03  3:42 [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Felipe Balbi
                   ` (12 preceding siblings ...)
  2013-12-03  3:43 ` [PATCH v2 14/15] mfd: menelaus: IRQ is a requirement Felipe Balbi
@ 2013-12-03  3:43 ` Felipe Balbi
  2013-12-03  9:51 ` [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Lee Jones
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-03  3:43 UTC (permalink / raw)
  To: linux-arm-kernel

by using devm_request_threaded_irq() we can
drop a few extra lines of code and rely on
device managed resources layer to free our
IRQ for us.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index bffe978..b87c2bd 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -1271,8 +1271,8 @@ static int menelaus_probe(struct i2c_client *client,
 	/* Set output buffer strengths */
 	menelaus_write_reg(m, MENELAUS_MCT_CTRL1, 0x73);
 
-	err = request_threaded_irq(client->irq, NULL, menelaus_irq,
-			IRQF_ONESHOT, DRIVER_NAME, m);
+	err = devm_request_threaded_irq(&client->dev, client->irq,
+			NULL, menelaus_irq, IRQF_ONESHOT, DRIVER_NAME, m);
 	if (err) {
 		dev_dbg(&client->dev,  "can't get IRQ %d, err %d\n",
 				client->irq, err);
@@ -1283,7 +1283,7 @@ static int menelaus_probe(struct i2c_client *client,
 
 	val = menelaus_read_reg(m, MENELAUS_VCORE_CTRL1);
 	if (val < 0)
-		goto fail_free_irq;
+		goto fail_free_descs;
 	if (val & (1 << 7))
 		m->vcore_hw_mode = 1;
 	else
@@ -1292,14 +1292,12 @@ static int menelaus_probe(struct i2c_client *client,
 	if (menelaus_pdata != NULL && menelaus_pdata->late_init != NULL) {
 		err = menelaus_pdata->late_init(&client->dev);
 		if (err < 0)
-			goto fail_free_irq;
+			goto fail_free_descs;
 	}
 
 	menelaus_rtc_init(m);
 
 	return 0;
-fail_free_irq:
-	free_irq(client->irq, m);
 
 fail_free_descs:
 	irq_free_descs(irq_base, MENELAUS_NR_IRQS);
@@ -1311,7 +1309,6 @@ static int menelaus_remove(struct i2c_client *client)
 {
 	struct menelaus_chip	*m = i2c_get_clientdata(client);
 
-	free_irq(client->irq, m);
 	irq_free_descs(m->irq_base, MENELAUS_NR_IRQS);
 	the_menelaus = NULL;
 	return 0;
-- 
1.8.4.GIT

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

* [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation
  2013-12-03  3:42 [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Felipe Balbi
                   ` (13 preceding siblings ...)
  2013-12-03  3:43 ` [PATCH v2 15/15] mfd: menelaus: Use devm_request_threaded_irq() Felipe Balbi
@ 2013-12-03  9:51 ` Lee Jones
  2013-12-03  9:53   ` Lee Jones
  2013-12-08 19:07   ` Felipe Balbi
  2013-12-06 13:41 ` Aaro Koskinen
                   ` (2 subsequent siblings)
  17 siblings, 2 replies; 73+ messages in thread
From: Lee Jones @ 2013-12-03  9:51 UTC (permalink / raw)
  To: linux-arm-kernel

The code looks mostly fine, but the implementation of the commit logs
seems lazy. Please submit a v3 using coherent sentences with full
explanations and correct punctuation.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation
  2013-12-03  9:51 ` [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Lee Jones
@ 2013-12-03  9:53   ` Lee Jones
  2013-12-08 19:07   ` Felipe Balbi
  1 sibling, 0 replies; 73+ messages in thread
From: Lee Jones @ 2013-12-03  9:53 UTC (permalink / raw)
  To: linux-arm-kernel

> The code looks mostly fine, but the implementation of the commit logs
> seems lazy. Please submit a v3 using coherent sentences with full
> explanations and correct punctuation.

Also use the full length of the provided buffer, which I believe is 72
chars, but happy to be correct on that one. It's certainly not 40
chars however.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation
  2013-12-03  3:42 [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Felipe Balbi
                   ` (14 preceding siblings ...)
  2013-12-03  9:51 ` [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Lee Jones
@ 2013-12-06 13:41 ` Aaro Koskinen
  2013-12-11  9:44 ` Uwe Kleine-König
  2013-12-16 15:39 ` Lee Jones
  17 siblings, 0 replies; 73+ messages in thread
From: Aaro Koskinen @ 2013-12-06 13:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

For the whole series:

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>

A.

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

* [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation
  2013-12-03  9:51 ` [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Lee Jones
  2013-12-03  9:53   ` Lee Jones
@ 2013-12-08 19:07   ` Felipe Balbi
  2013-12-09  9:37     ` Lee Jones
  1 sibling, 1 reply; 73+ messages in thread
From: Felipe Balbi @ 2013-12-08 19:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Dec 03, 2013 at 09:51:36AM +0000, Lee Jones wrote:
> The code looks mostly fine, but the implementation of the commit logs
> seems lazy. Please submit a v3 using coherent sentences with full
> explanations and correct punctuation.

example ?

-- 
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/20131208/5a051299/attachment.sig>

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

* [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation
  2013-12-08 19:07   ` Felipe Balbi
@ 2013-12-09  9:37     ` Lee Jones
  2013-12-09 16:14       ` Felipe Balbi
  0 siblings, 1 reply; 73+ messages in thread
From: Lee Jones @ 2013-12-09  9:37 UTC (permalink / raw)
  To: linux-arm-kernel

> > The code looks mostly fine, but the implementation of the commit logs
> > seems lazy. Please submit a v3 using coherent sentences with full
> > explanations and correct punctuation.
> 
> example ?

All of your commit messages.

> that macro just helps removing some extra

  ^- Sentences start with an uppercase character.

> line of code and hides ffs() calls.
> 
> while at that, also fix a variable shadowing

  ^- Sentences start with an uppercase character.

> bug where 'int irq' was being redeclared inside
> inner loop while it was also argument to interrupt
> handler.

  < ---------------   50 chars   ----------------- >

Please use the full 72 char (or there abouts) width of the buffer.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation
  2013-12-09  9:37     ` Lee Jones
@ 2013-12-09 16:14       ` Felipe Balbi
  2013-12-09 16:21         ` [PATCH v3 " Felipe Balbi
  2013-12-10  8:50         ` [PATCH v2 " Lee Jones
  0 siblings, 2 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-09 16:14 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Mon, Dec 09, 2013 at 09:37:48AM +0000, Lee Jones wrote:
> > > The code looks mostly fine, but the implementation of the commit logs
> > > seems lazy. Please submit a v3 using coherent sentences with full
> > > explanations and correct punctuation.
> > 
> > example ?
> 
> All of your commit messages.
> 
> > that macro just helps removing some extra
> 
>   ^- Sentences start with an uppercase character.
> 
> > line of code and hides ffs() calls.
> > 
> > while at that, also fix a variable shadowing
> 
>   ^- Sentences start with an uppercase character.
> 
> > bug where 'int irq' was being redeclared inside
> > inner loop while it was also argument to interrupt
> > handler.
> 
>   < ---------------   50 chars   ----------------- >
> 
> Please use the full 72 char (or there abouts) width of the buffer.

I don't see any mention of punctuation problems, however. Also, you're
not complaining about the content at all, which tells me those sentences
aren't as incoherent as you claimed before. But fair enough, I'll fix
those up and add Aaro's Tested-by

-- 
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/20131209/3696edec/attachment.sig>

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

* [PATCH v3 01/15] mfd: menelaus: Drop __exit section annotation
  2013-12-09 16:14       ` Felipe Balbi
@ 2013-12-09 16:21         ` Felipe Balbi
  2013-12-09 16:21           ` [PATCH v3 02/15] mfd: menelaus: Switch over to module_i2c_driver Felipe Balbi
                             ` (14 more replies)
  2013-12-10  8:50         ` [PATCH v2 " Lee Jones
  1 sibling, 15 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-09 16:21 UTC (permalink / raw)
  To: linux-arm-kernel

We could build that driver as a dynamically-linked module.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index ad25bfa..975ff9e 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -1262,7 +1262,7 @@ fail:
 	return err;
 }
 
-static int __exit menelaus_remove(struct i2c_client *client)
+static int menelaus_remove(struct i2c_client *client)
 {
 	struct menelaus_chip	*menelaus = i2c_get_clientdata(client);
 
@@ -1283,7 +1283,7 @@ static struct i2c_driver menelaus_i2c_driver = {
 		.name		= DRIVER_NAME,
 	},
 	.probe		= menelaus_probe,
-	.remove		= __exit_p(menelaus_remove),
+	.remove		= menelaus_remove,
 	.id_table	= menelaus_id,
 };
 
-- 
1.8.4.GIT

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

* [PATCH v3 02/15] mfd: menelaus: Switch over to module_i2c_driver
  2013-12-09 16:21         ` [PATCH v3 " Felipe Balbi
@ 2013-12-09 16:21           ` Felipe Balbi
  2013-12-09 16:21           ` [PATCH v3 03/15] mfd: menelaus: Convert to threaded irq Felipe Balbi
                             ` (13 subsequent siblings)
  14 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-09 16:21 UTC (permalink / raw)
  To: linux-arm-kernel

Just a macro to remove some boilerplate code, no functional changes.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 23 +----------------------
 1 file changed, 1 insertion(+), 22 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 975ff9e..8bd97ca 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -1287,29 +1287,8 @@ static struct i2c_driver menelaus_i2c_driver = {
 	.id_table	= menelaus_id,
 };
 
-static int __init menelaus_init(void)
-{
-	int res;
-
-	res = i2c_add_driver(&menelaus_i2c_driver);
-	if (res < 0) {
-		pr_err(DRIVER_NAME ": driver registration failed\n");
-		return res;
-	}
-
-	return 0;
-}
-
-static void __exit menelaus_exit(void)
-{
-	i2c_del_driver(&menelaus_i2c_driver);
-
-	/* FIXME: Shutdown menelaus parts that can be shut down */
-}
+module_i2c_driver(menelaus_i2c_driver);
 
 MODULE_AUTHOR("Texas Instruments, Inc. (and others)");
 MODULE_DESCRIPTION("I2C interface for Menelaus.");
 MODULE_LICENSE("GPL");
-
-module_init(menelaus_init);
-module_exit(menelaus_exit);
-- 
1.8.4.GIT

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

* [PATCH v3 03/15] mfd: menelaus: Convert to threaded irq
  2013-12-09 16:21         ` [PATCH v3 " Felipe Balbi
  2013-12-09 16:21           ` [PATCH v3 02/15] mfd: menelaus: Switch over to module_i2c_driver Felipe Balbi
@ 2013-12-09 16:21           ` Felipe Balbi
  2013-12-10  9:32             ` Lee Jones
  2013-12-09 16:21           ` [PATCH v3 04/15] mfd: menelaus: Remove unnecessary loop Felipe Balbi
                             ` (12 subsequent siblings)
  14 siblings, 1 reply; 73+ messages in thread
From: Felipe Balbi @ 2013-12-09 16:21 UTC (permalink / raw)
  To: linux-arm-kernel

We don't need that extra workqueue when we have generic threaded irq
handlers support. This patch just moves over to threaded irqs and
deletes the unnecessary workqueue.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 29 ++++-------------------------
 1 file changed, 4 insertions(+), 25 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 8bd97ca..11d7d81 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -36,7 +36,6 @@
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/mutex.h>
-#include <linux/workqueue.h>
 #include <linux/delay.h>
 #include <linux/rtc.h>
 #include <linux/bcd.h>
@@ -161,12 +160,9 @@
 #define MCT_PIN_ST_S1_CD_ST		(1 << 0)
 #define MCT_PIN_ST_S2_CD_ST		(1 << 1)
 
-static void menelaus_work(struct work_struct *_menelaus);
-
 struct menelaus_chip {
 	struct mutex		lock;
 	struct i2c_client	*client;
-	struct work_struct	work;
 #ifdef CONFIG_RTC_DRV_TWL92330
 	struct rtc_device	*rtc;
 	u8			rtc_control;
@@ -795,11 +791,9 @@ out:
 
 /*-----------------------------------------------------------------------*/
 
-/* Handles Menelaus interrupts. Does not run in interrupt context */
-static void menelaus_work(struct work_struct *_menelaus)
+static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 {
-	struct menelaus_chip *menelaus =
-			container_of(_menelaus, struct menelaus_chip, work);
+	struct menelaus_chip *menelaus = _menelaus;
 	void (*handler)(struct menelaus_chip *menelaus);
 
 	while (1) {
@@ -826,18 +820,6 @@ static void menelaus_work(struct work_struct *_menelaus)
 			mutex_unlock(&menelaus->lock);
 		}
 	}
-	enable_irq(menelaus->client->irq);
-}
-
-/*
- * We cannot use I2C in interrupt context, so we just schedule work.
- */
-static irqreturn_t menelaus_irq(int irq, void *_menelaus)
-{
-	struct menelaus_chip *menelaus = _menelaus;
-
-	disable_irq_nosync(irq);
-	(void)schedule_work(&menelaus->work);
 
 	return IRQ_HANDLED;
 }
@@ -1225,8 +1207,8 @@ static int menelaus_probe(struct i2c_client *client,
 	menelaus_write_reg(MENELAUS_MCT_CTRL1, 0x73);
 
 	if (client->irq > 0) {
-		err = request_irq(client->irq, menelaus_irq, 0,
-				  DRIVER_NAME, menelaus);
+		err = request_threaded_irq(client->irq, NULL, menelaus_irq,
+				IRQF_ONESHOT, DRIVER_NAME, menelaus);
 		if (err) {
 			dev_dbg(&client->dev,  "can't get IRQ %d, err %d\n",
 					client->irq, err);
@@ -1235,7 +1217,6 @@ static int menelaus_probe(struct i2c_client *client,
 	}
 
 	mutex_init(&menelaus->lock);
-	INIT_WORK(&menelaus->work, menelaus_work);
 
 	pr_info("Menelaus rev %d.%d\n", rev >> 4, rev & 0x0f);
 
@@ -1258,7 +1239,6 @@ static int menelaus_probe(struct i2c_client *client,
 	return 0;
 fail:
 	free_irq(client->irq, menelaus);
-	flush_work(&menelaus->work);
 	return err;
 }
 
@@ -1267,7 +1247,6 @@ static int menelaus_remove(struct i2c_client *client)
 	struct menelaus_chip	*menelaus = i2c_get_clientdata(client);
 
 	free_irq(client->irq, menelaus);
-	flush_work(&menelaus->work);
 	the_menelaus = NULL;
 	return 0;
 }
-- 
1.8.4.GIT

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

* [PATCH v3 04/15] mfd: menelaus: Remove unnecessary loop
  2013-12-09 16:21         ` [PATCH v3 " Felipe Balbi
  2013-12-09 16:21           ` [PATCH v3 02/15] mfd: menelaus: Switch over to module_i2c_driver Felipe Balbi
  2013-12-09 16:21           ` [PATCH v3 03/15] mfd: menelaus: Convert to threaded irq Felipe Balbi
@ 2013-12-09 16:21           ` Felipe Balbi
  2013-12-09 16:21           ` [PATCH v3 05/15] mfd: menelaus: Use for_each_set_bit() Felipe Balbi
                             ` (11 subsequent siblings)
  14 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-09 16:21 UTC (permalink / raw)
  To: linux-arm-kernel

We can let irqs refire and give the scheduler a chance to choose when we
should be scheduled.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 43 +++++++++++++++++++------------------------
 1 file changed, 19 insertions(+), 24 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 11d7d81..11dc4d3 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -795,30 +795,25 @@ static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 {
 	struct menelaus_chip *menelaus = _menelaus;
 	void (*handler)(struct menelaus_chip *menelaus);
-
-	while (1) {
-		unsigned isr;
-
-		isr = (menelaus_read_reg(MENELAUS_INT_STATUS2)
-				& ~menelaus->mask2) << 8;
-		isr |= menelaus_read_reg(MENELAUS_INT_STATUS1)
-				& ~menelaus->mask1;
-		if (!isr)
-			break;
-
-		while (isr) {
-			int irq = fls(isr) - 1;
-			isr &= ~(1 << irq);
-
-			mutex_lock(&menelaus->lock);
-			menelaus_disable_irq(irq);
-			menelaus_ack_irq(irq);
-			handler = menelaus->handlers[irq];
-			if (handler)
-				handler(menelaus);
-			menelaus_enable_irq(irq);
-			mutex_unlock(&menelaus->lock);
-		}
+	unsigned isr;
+
+	isr = (menelaus_read_reg(MENELAUS_INT_STATUS2)
+			& ~menelaus->mask2) << 8;
+	isr |= menelaus_read_reg(MENELAUS_INT_STATUS1)
+		& ~menelaus->mask1;
+
+	while (isr) {
+		int irq = fls(isr) - 1;
+		isr &= ~(1 << irq);
+
+		mutex_lock(&menelaus->lock);
+		menelaus_disable_irq(irq);
+		menelaus_ack_irq(irq);
+		handler = menelaus->handlers[irq];
+		if (handler)
+			handler(menelaus);
+		menelaus_enable_irq(irq);
+		mutex_unlock(&menelaus->lock);
 	}
 
 	return IRQ_HANDLED;
-- 
1.8.4.GIT

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

* [PATCH v3 05/15] mfd: menelaus: Use for_each_set_bit()
  2013-12-09 16:21         ` [PATCH v3 " Felipe Balbi
                             ` (2 preceding siblings ...)
  2013-12-09 16:21           ` [PATCH v3 04/15] mfd: menelaus: Remove unnecessary loop Felipe Balbi
@ 2013-12-09 16:21           ` Felipe Balbi
  2013-12-09 16:21           ` [PATCH v3 06/15] mfd: menelaus: Pass menelaus pointer as argument to enable/disable irq Felipe Balbi
                             ` (10 subsequent siblings)
  14 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-09 16:21 UTC (permalink / raw)
  To: linux-arm-kernel

That macro just helps removing some extra line of code and hides ffs()
calls.

While at that, also fix a variable shadowing bug where 'int irq' was
being redeclared inside inner loop while it was also argument to
interrupt handler.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 11dc4d3..9ccbb79 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -795,24 +795,22 @@ static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 {
 	struct menelaus_chip *menelaus = _menelaus;
 	void (*handler)(struct menelaus_chip *menelaus);
-	unsigned isr;
+	unsigned long isr;
+	unsigned long i;
 
 	isr = (menelaus_read_reg(MENELAUS_INT_STATUS2)
 			& ~menelaus->mask2) << 8;
 	isr |= menelaus_read_reg(MENELAUS_INT_STATUS1)
 		& ~menelaus->mask1;
 
-	while (isr) {
-		int irq = fls(isr) - 1;
-		isr &= ~(1 << irq);
-
+	for_each_set_bit(i, &isr, 16) {
 		mutex_lock(&menelaus->lock);
-		menelaus_disable_irq(irq);
-		menelaus_ack_irq(irq);
-		handler = menelaus->handlers[irq];
+		menelaus_disable_irq(i);
+		menelaus_ack_irq(i);
+		handler = menelaus->handlers[i];
 		if (handler)
 			handler(menelaus);
-		menelaus_enable_irq(irq);
+		menelaus_enable_irq(i);
 		mutex_unlock(&menelaus->lock);
 	}
 
-- 
1.8.4.GIT

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

* [PATCH v3 06/15] mfd: menelaus: Pass menelaus pointer as argument to enable/disable irq
  2013-12-09 16:21         ` [PATCH v3 " Felipe Balbi
                             ` (3 preceding siblings ...)
  2013-12-09 16:21           ` [PATCH v3 05/15] mfd: menelaus: Use for_each_set_bit() Felipe Balbi
@ 2013-12-09 16:21           ` Felipe Balbi
  2013-12-09 16:21           ` [PATCH v3 07/15] mfd: menelaus: Limit the usage of the_menelaus Felipe Balbi
                             ` (9 subsequent siblings)
  14 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-09 16:21 UTC (permalink / raw)
  To: linux-arm-kernel

We want to, eventually, get rid of the global the_menelaus pointer, so
let's start passing menelaus as argument to some function calls and
slowly phase out the_menelaus global pointer.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 48 ++++++++++++++++++++++++------------------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 9ccbb79..4c51e4b 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -199,35 +199,35 @@ static int menelaus_read_reg(int reg)
 	return val;
 }
 
-static int menelaus_enable_irq(int irq)
+static int menelaus_enable_irq(struct menelaus_chip *m, int irq)
 {
 	if (irq > 7) {
 		irq -= 8;
-		the_menelaus->mask2 &= ~(1 << irq);
+		m->mask2 &= ~(1 << irq);
 		return menelaus_write_reg(MENELAUS_INT_MASK2,
-				the_menelaus->mask2);
+				m->mask2);
 	} else {
-		the_menelaus->mask1 &= ~(1 << irq);
+		m->mask1 &= ~(1 << irq);
 		return menelaus_write_reg(MENELAUS_INT_MASK1,
-				the_menelaus->mask1);
+				m->mask1);
 	}
 }
 
-static int menelaus_disable_irq(int irq)
+static int menelaus_disable_irq(struct menelaus_chip *m, int irq)
 {
 	if (irq > 7) {
 		irq -= 8;
-		the_menelaus->mask2 |= (1 << irq);
+		m->mask2 |= (1 << irq);
 		return menelaus_write_reg(MENELAUS_INT_MASK2,
-				the_menelaus->mask2);
+				m->mask2);
 	} else {
-		the_menelaus->mask1 |= (1 << irq);
+		m->mask1 |= (1 << irq);
 		return menelaus_write_reg(MENELAUS_INT_MASK1,
-				the_menelaus->mask1);
+				m->mask1);
 	}
 }
 
-static int menelaus_ack_irq(int irq)
+static int menelaus_ack_irq(struct menelaus_chip *m, int irq)
 {
 	if (irq > 7)
 		return menelaus_write_reg(MENELAUS_INT_ACK2, 1 << (irq - 8));
@@ -243,7 +243,7 @@ static int menelaus_add_irq_work(int irq,
 
 	mutex_lock(&the_menelaus->lock);
 	the_menelaus->handlers[irq] = handler;
-	ret = menelaus_enable_irq(irq);
+	ret = menelaus_enable_irq(the_menelaus, irq);
 	mutex_unlock(&the_menelaus->lock);
 
 	return ret;
@@ -255,7 +255,7 @@ static int menelaus_remove_irq_work(int irq)
 	int ret = 0;
 
 	mutex_lock(&the_menelaus->lock);
-	ret = menelaus_disable_irq(irq);
+	ret = menelaus_disable_irq(the_menelaus, irq);
 	the_menelaus->handlers[irq] = NULL;
 	mutex_unlock(&the_menelaus->lock);
 
@@ -793,25 +793,25 @@ out:
 
 static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 {
-	struct menelaus_chip *menelaus = _menelaus;
-	void (*handler)(struct menelaus_chip *menelaus);
+	struct menelaus_chip *m = _menelaus;
+	void (*handler)(struct menelaus_chip *m);
 	unsigned long isr;
 	unsigned long i;
 
 	isr = (menelaus_read_reg(MENELAUS_INT_STATUS2)
-			& ~menelaus->mask2) << 8;
+			& ~m->mask2) << 8;
 	isr |= menelaus_read_reg(MENELAUS_INT_STATUS1)
-		& ~menelaus->mask1;
+		& ~m->mask1;
 
 	for_each_set_bit(i, &isr, 16) {
-		mutex_lock(&menelaus->lock);
-		menelaus_disable_irq(i);
-		menelaus_ack_irq(i);
-		handler = menelaus->handlers[i];
+		mutex_lock(&m->lock);
+		menelaus_disable_irq(m, i);
+		menelaus_ack_irq(m, i);
+		handler = m->handlers[i];
 		if (handler)
-			handler(menelaus);
-		menelaus_enable_irq(i);
-		mutex_unlock(&menelaus->lock);
+			handler(m);
+		menelaus_enable_irq(m, i);
+		mutex_unlock(&m->lock);
 	}
 
 	return IRQ_HANDLED;
-- 
1.8.4.GIT

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

* [PATCH v3 07/15] mfd: menelaus: Limit the usage of the_menelaus
  2013-12-09 16:21         ` [PATCH v3 " Felipe Balbi
                             ` (4 preceding siblings ...)
  2013-12-09 16:21           ` [PATCH v3 06/15] mfd: menelaus: Pass menelaus pointer as argument to enable/disable irq Felipe Balbi
@ 2013-12-09 16:21           ` Felipe Balbi
  2013-12-10  8:57             ` Lee Jones
  2013-12-09 16:21           ` [PATCH v3 08/15] mfd: menelaus: Pass menelaus_chip pointer to add/remove irq functions Felipe Balbi
                             ` (8 subsequent siblings)
  14 siblings, 1 reply; 73+ messages in thread
From: Felipe Balbi @ 2013-12-09 16:21 UTC (permalink / raw)
  To: linux-arm-kernel

Pass a menelaus_chip pointer as argument to most functions so we can
minimize the usage of the global the_menelaus pointer.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 265 ++++++++++++++++++++++++++-----------------------
 1 file changed, 142 insertions(+), 123 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 4c51e4b..8796e5e 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -177,9 +177,9 @@ struct menelaus_chip {
 
 static struct menelaus_chip *the_menelaus;
 
-static int menelaus_write_reg(int reg, u8 value)
+static int menelaus_write_reg(struct menelaus_chip *m, int reg, u8 value)
 {
-	int val = i2c_smbus_write_byte_data(the_menelaus->client, reg, value);
+	int val = i2c_smbus_write_byte_data(m->client, reg, value);
 
 	if (val < 0) {
 		pr_err(DRIVER_NAME ": write error");
@@ -189,9 +189,9 @@ static int menelaus_write_reg(int reg, u8 value)
 	return 0;
 }
 
-static int menelaus_read_reg(int reg)
+static int menelaus_read_reg(struct menelaus_chip *m, int reg)
 {
-	int val = i2c_smbus_read_byte_data(the_menelaus->client, reg);
+	int val = i2c_smbus_read_byte_data(m->client, reg);
 
 	if (val < 0)
 		pr_err(DRIVER_NAME ": read error");
@@ -204,11 +204,11 @@ static int menelaus_enable_irq(struct menelaus_chip *m, int irq)
 	if (irq > 7) {
 		irq -= 8;
 		m->mask2 &= ~(1 << irq);
-		return menelaus_write_reg(MENELAUS_INT_MASK2,
+		return menelaus_write_reg(m, MENELAUS_INT_MASK2,
 				m->mask2);
 	} else {
 		m->mask1 &= ~(1 << irq);
-		return menelaus_write_reg(MENELAUS_INT_MASK1,
+		return menelaus_write_reg(m, MENELAUS_INT_MASK1,
 				m->mask1);
 	}
 }
@@ -218,11 +218,11 @@ static int menelaus_disable_irq(struct menelaus_chip *m, int irq)
 	if (irq > 7) {
 		irq -= 8;
 		m->mask2 |= (1 << irq);
-		return menelaus_write_reg(MENELAUS_INT_MASK2,
+		return menelaus_write_reg(m, MENELAUS_INT_MASK2,
 				m->mask2);
 	} else {
 		m->mask1 |= (1 << irq);
-		return menelaus_write_reg(MENELAUS_INT_MASK1,
+		return menelaus_write_reg(m, MENELAUS_INT_MASK1,
 				m->mask1);
 	}
 }
@@ -230,9 +230,9 @@ static int menelaus_disable_irq(struct menelaus_chip *m, int irq)
 static int menelaus_ack_irq(struct menelaus_chip *m, int irq)
 {
 	if (irq > 7)
-		return menelaus_write_reg(MENELAUS_INT_ACK2, 1 << (irq - 8));
+		return menelaus_write_reg(m, MENELAUS_INT_ACK2, 1 << (irq - 8));
 	else
-		return menelaus_write_reg(MENELAUS_INT_ACK1, 1 << irq);
+		return menelaus_write_reg(m, MENELAUS_INT_ACK1, 1 << irq);
 }
 
 /* Adds a handler for an interrupt. Does not run in interrupt context */
@@ -268,12 +268,12 @@ static int menelaus_remove_irq_work(int irq)
  * in each slot. In this case the cards are not seen by menelaus.
  * FIXME: Add handling for D1 too
  */
-static void menelaus_mmc_cd_work(struct menelaus_chip *menelaus_hw)
+static void menelaus_mmc_cd_work(struct menelaus_chip *m)
 {
 	int reg;
 	unsigned char card_mask = 0;
 
-	reg = menelaus_read_reg(MENELAUS_MCT_PIN_ST);
+	reg = menelaus_read_reg(m, MENELAUS_MCT_PIN_ST);
 	if (reg < 0)
 		return;
 
@@ -283,8 +283,8 @@ static void menelaus_mmc_cd_work(struct menelaus_chip *menelaus_hw)
 	if (!(reg & 0x2))
 		card_mask |= MCT_PIN_ST_S2_CD_ST;
 
-	if (menelaus_hw->mmc_callback)
-		menelaus_hw->mmc_callback(menelaus_hw->mmc_callback_data,
+	if (m->mmc_callback)
+		m->mmc_callback(m->mmc_callback_data,
 					  card_mask);
 }
 
@@ -293,14 +293,16 @@ static void menelaus_mmc_cd_work(struct menelaus_chip *menelaus_hw)
  */
 int menelaus_set_mmc_opendrain(int slot, int enable)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int ret, val;
 
 	if (slot != 1 && slot != 2)
 		return -EINVAL;
-	mutex_lock(&the_menelaus->lock);
-	ret = menelaus_read_reg(MENELAUS_MCT_CTRL1);
+
+	mutex_lock(&m->lock);
+	ret = menelaus_read_reg(m, MENELAUS_MCT_CTRL1);
 	if (ret < 0) {
-		mutex_unlock(&the_menelaus->lock);
+		mutex_unlock(&m->lock);
 		return ret;
 	}
 	val = ret;
@@ -315,8 +317,8 @@ int menelaus_set_mmc_opendrain(int slot, int enable)
 		else
 			val &= ~MCT_CTRL1_S2_CMD_OD;
 	}
-	ret = menelaus_write_reg(MENELAUS_MCT_CTRL1, val);
-	mutex_unlock(&the_menelaus->lock);
+	ret = menelaus_write_reg(m, MENELAUS_MCT_CTRL1, val);
+	mutex_unlock(&m->lock);
 
 	return ret;
 }
@@ -324,10 +326,12 @@ EXPORT_SYMBOL(menelaus_set_mmc_opendrain);
 
 int menelaus_set_slot_sel(int enable)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int ret;
 
-	mutex_lock(&the_menelaus->lock);
-	ret = menelaus_read_reg(MENELAUS_GPIO_CTRL);
+	mutex_lock(&m->lock);
+
+	ret = menelaus_read_reg(m, MENELAUS_GPIO_CTRL);
 	if (ret < 0)
 		goto out;
 	ret |= GPIO2_DIR_INPUT;
@@ -335,15 +339,16 @@ int menelaus_set_slot_sel(int enable)
 		ret |= GPIO_CTRL_SLOTSELEN;
 	else
 		ret &= ~GPIO_CTRL_SLOTSELEN;
-	ret = menelaus_write_reg(MENELAUS_GPIO_CTRL, ret);
+	ret = menelaus_write_reg(m, MENELAUS_GPIO_CTRL, ret);
 out:
-	mutex_unlock(&the_menelaus->lock);
+	mutex_unlock(&m->lock);
 	return ret;
 }
 EXPORT_SYMBOL(menelaus_set_slot_sel);
 
 int menelaus_set_mmc_slot(int slot, int enable, int power, int cd_en)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int ret, val;
 
 	if (slot != 1 && slot != 2)
@@ -351,9 +356,9 @@ int menelaus_set_mmc_slot(int slot, int enable, int power, int cd_en)
 	if (power >= 3)
 		return -EINVAL;
 
-	mutex_lock(&the_menelaus->lock);
+	mutex_lock(&m->lock);
 
-	ret = menelaus_read_reg(MENELAUS_MCT_CTRL2);
+	ret = menelaus_read_reg(m, MENELAUS_MCT_CTRL2);
 	if (ret < 0)
 		goto out;
 	val = ret;
@@ -368,11 +373,11 @@ int menelaus_set_mmc_slot(int slot, int enable, int power, int cd_en)
 		else
 			val &= ~(MCT_CTRL2_S2CD_BUFEN | MCT_CTRL2_S2CD_BEN);
 	}
-	ret = menelaus_write_reg(MENELAUS_MCT_CTRL2, val);
+	ret = menelaus_write_reg(m, MENELAUS_MCT_CTRL2, val);
 	if (ret < 0)
 		goto out;
 
-	ret = menelaus_read_reg(MENELAUS_MCT_CTRL3);
+	ret = menelaus_read_reg(m, MENELAUS_MCT_CTRL3);
 	if (ret < 0)
 		goto out;
 	val = ret;
@@ -388,18 +393,18 @@ int menelaus_set_mmc_slot(int slot, int enable, int power, int cd_en)
 			val |= MCT_CTRL3_SLOT2_EN;
 		else
 			val &= ~MCT_CTRL3_SLOT2_EN;
-		b = menelaus_read_reg(MENELAUS_MCT_CTRL2);
+		b = menelaus_read_reg(m, MENELAUS_MCT_CTRL2);
 		b &= ~(MCT_CTRL2_VS2_SEL_D0 | MCT_CTRL2_VS2_SEL_D1);
 		b |= power;
-		ret = menelaus_write_reg(MENELAUS_MCT_CTRL2, b);
+		ret = menelaus_write_reg(m, MENELAUS_MCT_CTRL2, b);
 		if (ret < 0)
 			goto out;
 	}
 	/* Disable autonomous shutdown */
 	val &= ~(MCT_CTRL3_S1_AUTO_EN | MCT_CTRL3_S2_AUTO_EN);
-	ret = menelaus_write_reg(MENELAUS_MCT_CTRL3, val);
+	ret = menelaus_write_reg(m, MENELAUS_MCT_CTRL3, val);
 out:
-	mutex_unlock(&the_menelaus->lock);
+	mutex_unlock(&m->lock);
 	return ret;
 }
 EXPORT_SYMBOL(menelaus_set_mmc_slot);
@@ -458,14 +463,15 @@ struct menelaus_vtg_value {
 static int menelaus_set_voltage(const struct menelaus_vtg *vtg, int mV,
 				int vtg_val, int mode)
 {
+	struct menelaus_chip *m = the_menelaus;
+	struct i2c_client *c = m->client;
 	int val, ret;
-	struct i2c_client *c = the_menelaus->client;
 
-	mutex_lock(&the_menelaus->lock);
+	mutex_lock(&m->lock);
 	if (!vtg)
 		goto set_voltage;
 
-	ret = menelaus_read_reg(vtg->vtg_reg);
+	ret = menelaus_read_reg(m, vtg->vtg_reg);
 	if (ret < 0)
 		goto out;
 	val = ret & ~(((1 << vtg->vtg_bits) - 1) << vtg->vtg_shift);
@@ -475,13 +481,13 @@ static int menelaus_set_voltage(const struct menelaus_vtg *vtg, int mV,
 			 "to %d mV (reg 0x%02x, val 0x%02x)\n",
 			vtg->name, mV, vtg->vtg_reg, val);
 
-	ret = menelaus_write_reg(vtg->vtg_reg, val);
+	ret = menelaus_write_reg(m, vtg->vtg_reg, val);
 	if (ret < 0)
 		goto out;
 set_voltage:
-	ret = menelaus_write_reg(vtg->mode_reg, mode);
+	ret = menelaus_write_reg(m, vtg->mode_reg, mode);
 out:
-	mutex_unlock(&the_menelaus->lock);
+	mutex_unlock(&m->lock);
 	if (ret == 0) {
 		/* Wait for voltage to stabilize */
 		msleep(1);
@@ -533,8 +539,9 @@ static const struct menelaus_vtg_value vcore_values[] = {
 
 int menelaus_set_vcore_sw(unsigned int mV)
 {
+	struct menelaus_chip *m = the_menelaus;
+	struct i2c_client *c = m->client;
 	int val, ret;
-	struct i2c_client *c = the_menelaus->client;
 
 	val = menelaus_get_vtg_value(mV, vcore_values,
 				     ARRAY_SIZE(vcore_values));
@@ -544,11 +551,11 @@ int menelaus_set_vcore_sw(unsigned int mV)
 	dev_dbg(&c->dev, "Setting VCORE to %d mV (val 0x%02x)\n", mV, val);
 
 	/* Set SW mode and the voltage in one go. */
-	mutex_lock(&the_menelaus->lock);
-	ret = menelaus_write_reg(MENELAUS_VCORE_CTRL1, val);
+	mutex_lock(&m->lock);
+	ret = menelaus_write_reg(m, MENELAUS_VCORE_CTRL1, val);
 	if (ret == 0)
-		the_menelaus->vcore_hw_mode = 0;
-	mutex_unlock(&the_menelaus->lock);
+		m->vcore_hw_mode = 0;
+	mutex_unlock(&m->lock);
 	msleep(1);
 
 	return ret;
@@ -556,8 +563,9 @@ int menelaus_set_vcore_sw(unsigned int mV)
 
 int menelaus_set_vcore_hw(unsigned int roof_mV, unsigned int floor_mV)
 {
+	struct menelaus_chip *m = the_menelaus;
+	struct i2c_client *c = m->client;
 	int fval, rval, val, ret;
-	struct i2c_client *c = the_menelaus->client;
 
 	rval = menelaus_get_vtg_value(roof_mV, vcore_values,
 				      ARRAY_SIZE(vcore_values));
@@ -571,23 +579,23 @@ int menelaus_set_vcore_hw(unsigned int roof_mV, unsigned int floor_mV)
 	dev_dbg(&c->dev, "Setting VCORE FLOOR to %d mV and ROOF to %d mV\n",
 	       floor_mV, roof_mV);
 
-	mutex_lock(&the_menelaus->lock);
-	ret = menelaus_write_reg(MENELAUS_VCORE_CTRL3, fval);
+	mutex_lock(&m->lock);
+	ret = menelaus_write_reg(m, MENELAUS_VCORE_CTRL3, fval);
 	if (ret < 0)
 		goto out;
-	ret = menelaus_write_reg(MENELAUS_VCORE_CTRL4, rval);
+	ret = menelaus_write_reg(m, MENELAUS_VCORE_CTRL4, rval);
 	if (ret < 0)
 		goto out;
-	if (!the_menelaus->vcore_hw_mode) {
-		val = menelaus_read_reg(MENELAUS_VCORE_CTRL1);
+	if (!m->vcore_hw_mode) {
+		val = menelaus_read_reg(m, MENELAUS_VCORE_CTRL1);
 		/* HW mode, turn OFF byte comparator */
 		val |= (VCORE_CTRL1_HW_NSW | VCORE_CTRL1_BYP_COMP);
-		ret = menelaus_write_reg(MENELAUS_VCORE_CTRL1, val);
-		the_menelaus->vcore_hw_mode = 1;
+		ret = menelaus_write_reg(m, MENELAUS_VCORE_CTRL1, val);
+		m->vcore_hw_mode = 1;
 	}
 	msleep(1);
 out:
-	mutex_unlock(&the_menelaus->lock);
+	mutex_unlock(&m->lock);
 	return ret;
 }
 
@@ -759,23 +767,26 @@ EXPORT_SYMBOL(menelaus_set_vaux);
 
 int menelaus_get_slot_pin_states(void)
 {
-	return menelaus_read_reg(MENELAUS_MCT_PIN_ST);
+	struct menelaus_chip *m = the_menelaus;
+
+	return menelaus_read_reg(m, MENELAUS_MCT_PIN_ST);
 }
 EXPORT_SYMBOL(menelaus_get_slot_pin_states);
 
 int menelaus_set_regulator_sleep(int enable, u32 val)
 {
+	struct menelaus_chip *m = the_menelaus;
+	struct i2c_client *c = m->client;
 	int t, ret;
-	struct i2c_client *c = the_menelaus->client;
 
-	mutex_lock(&the_menelaus->lock);
-	ret = menelaus_write_reg(MENELAUS_SLEEP_CTRL2, val);
+	mutex_lock(&m->lock);
+	ret = menelaus_write_reg(m, MENELAUS_SLEEP_CTRL2, val);
 	if (ret < 0)
 		goto out;
 
 	dev_dbg(&c->dev, "regulator sleep configuration: %02x\n", val);
 
-	ret = menelaus_read_reg(MENELAUS_GPIO_CTRL);
+	ret = menelaus_read_reg(m, MENELAUS_GPIO_CTRL);
 	if (ret < 0)
 		goto out;
 	t = (GPIO_CTRL_SLPCTLEN | GPIO3_DIR_INPUT);
@@ -783,9 +794,9 @@ int menelaus_set_regulator_sleep(int enable, u32 val)
 		ret |= t;
 	else
 		ret &= ~t;
-	ret = menelaus_write_reg(MENELAUS_GPIO_CTRL, ret);
+	ret = menelaus_write_reg(m, MENELAUS_GPIO_CTRL, ret);
 out:
-	mutex_unlock(&the_menelaus->lock);
+	mutex_unlock(&m->lock);
 	return ret;
 }
 
@@ -798,9 +809,9 @@ static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 	unsigned long isr;
 	unsigned long i;
 
-	isr = (menelaus_read_reg(MENELAUS_INT_STATUS2)
+	isr = (menelaus_read_reg(m, MENELAUS_INT_STATUS2)
 			& ~m->mask2) << 8;
-	isr |= menelaus_read_reg(MENELAUS_INT_STATUS1)
+	isr |= menelaus_read_reg(m, MENELAUS_INT_STATUS1)
 		& ~m->mask1;
 
 	for_each_set_bit(i, &isr, 16) {
@@ -841,9 +852,11 @@ static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 
 static void menelaus_to_time(char *regs, struct rtc_time *t)
 {
+	struct menelaus_chip *m = the_menelaus;
+
 	t->tm_sec = bcd2bin(regs[0]);
 	t->tm_min = bcd2bin(regs[1]);
-	if (the_menelaus->rtc_control & RTC_CTRL_MODE12) {
+	if (m->rtc_control & RTC_CTRL_MODE12) {
 		t->tm_hour = bcd2bin(regs[2] & 0x1f) - 1;
 		if (regs[2] & RTC_HR_PM)
 			t->tm_hour += 12;
@@ -856,17 +869,18 @@ static void menelaus_to_time(char *regs, struct rtc_time *t)
 
 static int time_to_menelaus(struct rtc_time *t, int regnum)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int	hour, status;
 
-	status = menelaus_write_reg(regnum++, bin2bcd(t->tm_sec));
+	status = menelaus_write_reg(m, regnum++, bin2bcd(t->tm_sec));
 	if (status < 0)
 		goto fail;
 
-	status = menelaus_write_reg(regnum++, bin2bcd(t->tm_min));
+	status = menelaus_write_reg(m, regnum++, bin2bcd(t->tm_min));
 	if (status < 0)
 		goto fail;
 
-	if (the_menelaus->rtc_control & RTC_CTRL_MODE12) {
+	if (m->rtc_control & RTC_CTRL_MODE12) {
 		hour = t->tm_hour + 1;
 		if (hour > 12)
 			hour = RTC_HR_PM | bin2bcd(hour - 12);
@@ -874,31 +888,32 @@ static int time_to_menelaus(struct rtc_time *t, int regnum)
 			hour = bin2bcd(hour);
 	} else
 		hour = bin2bcd(t->tm_hour);
-	status = menelaus_write_reg(regnum++, hour);
+	status = menelaus_write_reg(m, regnum++, hour);
 	if (status < 0)
 		goto fail;
 
-	status = menelaus_write_reg(regnum++, bin2bcd(t->tm_mday));
+	status = menelaus_write_reg(m, regnum++, bin2bcd(t->tm_mday));
 	if (status < 0)
 		goto fail;
 
-	status = menelaus_write_reg(regnum++, bin2bcd(t->tm_mon + 1));
+	status = menelaus_write_reg(m, regnum++, bin2bcd(t->tm_mon + 1));
 	if (status < 0)
 		goto fail;
 
-	status = menelaus_write_reg(regnum++, bin2bcd(t->tm_year - 100));
+	status = menelaus_write_reg(m, regnum++, bin2bcd(t->tm_year - 100));
 	if (status < 0)
 		goto fail;
 
 	return 0;
 fail:
-	dev_err(&the_menelaus->client->dev, "rtc write reg %02x, err %d\n",
+	dev_err(&m->client->dev, "rtc write reg %02x, err %d\n",
 			--regnum, status);
 	return status;
 }
 
 static int menelaus_read_time(struct device *dev, struct rtc_time *t)
 {
+	struct menelaus_chip *m = dev_get_drvdata(dev);
 	struct i2c_msg	msg[2];
 	char		regs[7];
 	int		status;
@@ -916,7 +931,7 @@ static int menelaus_read_time(struct device *dev, struct rtc_time *t)
 	msg[1].len = sizeof(regs);
 	msg[1].buf = regs;
 
-	status = i2c_transfer(the_menelaus->client->adapter, msg, 2);
+	status = i2c_transfer(m->client->adapter, msg, 2);
 	if (status != 2) {
 		dev_err(dev, "%s error %d\n", "read", status);
 		return -EIO;
@@ -930,23 +945,24 @@ static int menelaus_read_time(struct device *dev, struct rtc_time *t)
 
 static int menelaus_set_time(struct device *dev, struct rtc_time *t)
 {
+	struct menelaus_chip *m = dev_get_drvdata(dev);
 	int		status;
 
 	/* write date and time registers */
 	status = time_to_menelaus(t, MENELAUS_RTC_SEC);
 	if (status < 0)
 		return status;
-	status = menelaus_write_reg(MENELAUS_RTC_WKDAY, bin2bcd(t->tm_wday));
+	status = menelaus_write_reg(m, MENELAUS_RTC_WKDAY, bin2bcd(t->tm_wday));
 	if (status < 0) {
-		dev_err(&the_menelaus->client->dev, "rtc write reg %02x "
+		dev_err(&m->client->dev, "rtc write reg %02x "
 				"err %d\n", MENELAUS_RTC_WKDAY, status);
 		return status;
 	}
 
 	/* now commit the write */
-	status = menelaus_write_reg(MENELAUS_RTC_UPDATE, RTC_UPDATE_EVERY);
+	status = menelaus_write_reg(m, MENELAUS_RTC_UPDATE, RTC_UPDATE_EVERY);
 	if (status < 0)
-		dev_err(&the_menelaus->client->dev, "rtc commit time, err %d\n",
+		dev_err(&m->client->dev, "rtc commit time, err %d\n",
 				status);
 
 	return 0;
@@ -954,6 +970,7 @@ static int menelaus_set_time(struct device *dev, struct rtc_time *t)
 
 static int menelaus_read_alarm(struct device *dev, struct rtc_wkalrm *w)
 {
+	struct menelaus_chip *m = dev_get_drvdata(dev);
 	struct i2c_msg	msg[2];
 	char		regs[6];
 	int		status;
@@ -971,7 +988,7 @@ static int menelaus_read_alarm(struct device *dev, struct rtc_wkalrm *w)
 	msg[1].len = sizeof(regs);
 	msg[1].buf = regs;
 
-	status = i2c_transfer(the_menelaus->client->adapter, msg, 2);
+	status = i2c_transfer(m->client->adapter, msg, 2);
 	if (status != 2) {
 		dev_err(dev, "%s error %d\n", "alarm read", status);
 		return -EIO;
@@ -979,7 +996,7 @@ static int menelaus_read_alarm(struct device *dev, struct rtc_wkalrm *w)
 
 	menelaus_to_time(regs, &w->time);
 
-	w->enabled = !!(the_menelaus->rtc_control & RTC_CTRL_AL_EN);
+	w->enabled = !!(m->rtc_control & RTC_CTRL_AL_EN);
 
 	/* NOTE we *could* check if actually pending... */
 	w->pending = 0;
@@ -989,16 +1006,17 @@ static int menelaus_read_alarm(struct device *dev, struct rtc_wkalrm *w)
 
 static int menelaus_set_alarm(struct device *dev, struct rtc_wkalrm *w)
 {
+	struct menelaus_chip *m = dev_get_drvdata(dev);
 	int		status;
 
-	if (the_menelaus->client->irq <= 0 && w->enabled)
+	if (m->client->irq <= 0 && w->enabled)
 		return -ENODEV;
 
 	/* clear previous alarm enable */
-	if (the_menelaus->rtc_control & RTC_CTRL_AL_EN) {
-		the_menelaus->rtc_control &= ~RTC_CTRL_AL_EN;
-		status = menelaus_write_reg(MENELAUS_RTC_CTRL,
-				the_menelaus->rtc_control);
+	if (m->rtc_control & RTC_CTRL_AL_EN) {
+		m->rtc_control &= ~RTC_CTRL_AL_EN;
+		status = menelaus_write_reg(m, MENELAUS_RTC_CTRL,
+				m->rtc_control);
 		if (status < 0)
 			return status;
 	}
@@ -1010,9 +1028,9 @@ static int menelaus_set_alarm(struct device *dev, struct rtc_wkalrm *w)
 
 	/* enable alarm if requested */
 	if (w->enabled) {
-		the_menelaus->rtc_control |= RTC_CTRL_AL_EN;
-		status = menelaus_write_reg(MENELAUS_RTC_CTRL,
-				the_menelaus->rtc_control);
+		m->rtc_control |= RTC_CTRL_AL_EN;
+		status = menelaus_write_reg(m, MENELAUS_RTC_CTRL,
+				m->rtc_control);
 	}
 
 	return status;
@@ -1030,44 +1048,45 @@ static void menelaus_rtc_update_work(struct menelaus_chip *m)
 
 static int menelaus_ioctl(struct device *dev, unsigned cmd, unsigned long arg)
 {
+	struct menelaus_chip *m = dev_get_drvdata(dev);
 	int	status;
 
-	if (the_menelaus->client->irq <= 0)
+	if (m->client->irq <= 0)
 		return -ENOIOCTLCMD;
 
 	switch (cmd) {
 	/* alarm IRQ */
 	case RTC_AIE_ON:
-		if (the_menelaus->rtc_control & RTC_CTRL_AL_EN)
+		if (m->rtc_control & RTC_CTRL_AL_EN)
 			return 0;
-		the_menelaus->rtc_control |= RTC_CTRL_AL_EN;
+		m->rtc_control |= RTC_CTRL_AL_EN;
 		break;
 	case RTC_AIE_OFF:
-		if (!(the_menelaus->rtc_control & RTC_CTRL_AL_EN))
+		if (!(m->rtc_control & RTC_CTRL_AL_EN))
 			return 0;
-		the_menelaus->rtc_control &= ~RTC_CTRL_AL_EN;
+		m->rtc_control &= ~RTC_CTRL_AL_EN;
 		break;
 	/* 1/second "update" IRQ */
 	case RTC_UIE_ON:
-		if (the_menelaus->uie)
+		if (m->uie)
 			return 0;
 		status = menelaus_remove_irq_work(MENELAUS_RTCTMR_IRQ);
 		status = menelaus_add_irq_work(MENELAUS_RTCTMR_IRQ,
 				menelaus_rtc_update_work);
 		if (status == 0)
-			the_menelaus->uie = 1;
+			m->uie = 1;
 		return status;
 	case RTC_UIE_OFF:
-		if (!the_menelaus->uie)
+		if (!m->uie)
 			return 0;
 		status = menelaus_remove_irq_work(MENELAUS_RTCTMR_IRQ);
 		if (status == 0)
-			the_menelaus->uie = 0;
+			m->uie = 0;
 		return status;
 	default:
 		return -ENOIOCTLCMD;
 	}
-	return menelaus_write_reg(MENELAUS_RTC_CTRL, the_menelaus->rtc_control);
+	return menelaus_write_reg(m, MENELAUS_RTC_CTRL, m->rtc_control);
 }
 
 #else
@@ -1092,8 +1111,8 @@ static void menelaus_rtc_alarm_work(struct menelaus_chip *m)
 	local_irq_enable();
 
 	/* then disable it; alarms are oneshot */
-	the_menelaus->rtc_control &= ~RTC_CTRL_AL_EN;
-	menelaus_write_reg(MENELAUS_RTC_CTRL, the_menelaus->rtc_control);
+	m->rtc_control &= ~RTC_CTRL_AL_EN;
+	menelaus_write_reg(m, MENELAUS_RTC_CTRL, m->rtc_control);
 }
 
 static inline void menelaus_rtc_init(struct menelaus_chip *m)
@@ -1101,7 +1120,7 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 	int	alarm = (m->client->irq > 0);
 
 	/* assume 32KDETEN pin is pulled high */
-	if (!(menelaus_read_reg(MENELAUS_OSC_CTRL) & 0x80)) {
+	if (!(menelaus_read_reg(m, MENELAUS_OSC_CTRL) & 0x80)) {
 		dev_dbg(&m->client->dev, "no 32k oscillator\n");
 		return;
 	}
@@ -1117,7 +1136,7 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 	}
 
 	/* be sure RTC is enabled; allow 1/sec irqs; leave 12hr mode alone */
-	m->rtc_control = menelaus_read_reg(MENELAUS_RTC_CTRL);
+	m->rtc_control = menelaus_read_reg(m, MENELAUS_RTC_CTRL);
 	if (!(m->rtc_control & RTC_CTRL_RTC_EN)
 			|| (m->rtc_control & RTC_CTRL_AL_EN)
 			|| (m->rtc_control & RTC_CTRL_EVERY_MASK)) {
@@ -1127,7 +1146,7 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 		}
 		m->rtc_control &= ~RTC_CTRL_EVERY_MASK;
 		m->rtc_control &= ~RTC_CTRL_AL_EN;
-		menelaus_write_reg(MENELAUS_RTC_CTRL, m->rtc_control);
+		menelaus_write_reg(m, MENELAUS_RTC_CTRL, m->rtc_control);
 	}
 
 	m->rtc = rtc_device_register(DRIVER_NAME,
@@ -1140,7 +1159,7 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 		}
 		dev_err(&m->client->dev, "can't register RTC: %d\n",
 				(int) PTR_ERR(m->rtc));
-		the_menelaus->rtc = NULL;
+		m->rtc = NULL;
 	}
 }
 
@@ -1160,7 +1179,7 @@ static struct i2c_driver menelaus_i2c_driver;
 static int menelaus_probe(struct i2c_client *client,
 			  const struct i2c_device_id *id)
 {
-	struct menelaus_chip	*menelaus;
+	struct menelaus_chip	*m;
 	int			rev = 0, val;
 	int			err = 0;
 	struct menelaus_platform_data *menelaus_pdata =
@@ -1172,36 +1191,36 @@ static int menelaus_probe(struct i2c_client *client,
 		return -ENODEV;
 	}
 
-	menelaus = devm_kzalloc(&client->dev, sizeof(*menelaus), GFP_KERNEL);
-	if (!menelaus)
+	m = devm_kzalloc(&client->dev, sizeof(*m), GFP_KERNEL);
+	if (!m)
 		return -ENOMEM;
 
-	i2c_set_clientdata(client, menelaus);
+	i2c_set_clientdata(client, m);
 
-	the_menelaus = menelaus;
-	menelaus->client = client;
+	the_menelaus = m;
+	m->client = client;
 
 	/* If a true probe check the device */
-	rev = menelaus_read_reg(MENELAUS_REV);
+	rev = menelaus_read_reg(m, MENELAUS_REV);
 	if (rev < 0) {
 		pr_err(DRIVER_NAME ": device not found");
 		return -ENODEV;
 	}
 
 	/* Ack and disable all Menelaus interrupts */
-	menelaus_write_reg(MENELAUS_INT_ACK1, 0xff);
-	menelaus_write_reg(MENELAUS_INT_ACK2, 0xff);
-	menelaus_write_reg(MENELAUS_INT_MASK1, 0xff);
-	menelaus_write_reg(MENELAUS_INT_MASK2, 0xff);
-	menelaus->mask1 = 0xff;
-	menelaus->mask2 = 0xff;
+	menelaus_write_reg(m, MENELAUS_INT_ACK1, 0xff);
+	menelaus_write_reg(m, MENELAUS_INT_ACK2, 0xff);
+	menelaus_write_reg(m, MENELAUS_INT_MASK1, 0xff);
+	menelaus_write_reg(m, MENELAUS_INT_MASK2, 0xff);
+	m->mask1 = 0xff;
+	m->mask2 = 0xff;
 
 	/* Set output buffer strengths */
-	menelaus_write_reg(MENELAUS_MCT_CTRL1, 0x73);
+	menelaus_write_reg(m, MENELAUS_MCT_CTRL1, 0x73);
 
 	if (client->irq > 0) {
 		err = request_threaded_irq(client->irq, NULL, menelaus_irq,
-				IRQF_ONESHOT, DRIVER_NAME, menelaus);
+				IRQF_ONESHOT, DRIVER_NAME, m);
 		if (err) {
 			dev_dbg(&client->dev,  "can't get IRQ %d, err %d\n",
 					client->irq, err);
@@ -1209,17 +1228,17 @@ static int menelaus_probe(struct i2c_client *client,
 		}
 	}
 
-	mutex_init(&menelaus->lock);
+	mutex_init(&m->lock);
 
 	pr_info("Menelaus rev %d.%d\n", rev >> 4, rev & 0x0f);
 
-	val = menelaus_read_reg(MENELAUS_VCORE_CTRL1);
+	val = menelaus_read_reg(m, MENELAUS_VCORE_CTRL1);
 	if (val < 0)
 		goto fail;
 	if (val & (1 << 7))
-		menelaus->vcore_hw_mode = 1;
+		m->vcore_hw_mode = 1;
 	else
-		menelaus->vcore_hw_mode = 0;
+		m->vcore_hw_mode = 0;
 
 	if (menelaus_pdata != NULL && menelaus_pdata->late_init != NULL) {
 		err = menelaus_pdata->late_init(&client->dev);
@@ -1227,19 +1246,19 @@ static int menelaus_probe(struct i2c_client *client,
 			goto fail;
 	}
 
-	menelaus_rtc_init(menelaus);
+	menelaus_rtc_init(m);
 
 	return 0;
 fail:
-	free_irq(client->irq, menelaus);
+	free_irq(client->irq, m);
 	return err;
 }
 
 static int menelaus_remove(struct i2c_client *client)
 {
-	struct menelaus_chip	*menelaus = i2c_get_clientdata(client);
+	struct menelaus_chip	*m = i2c_get_clientdata(client);
 
-	free_irq(client->irq, menelaus);
+	free_irq(client->irq, m);
 	the_menelaus = NULL;
 	return 0;
 }
-- 
1.8.4.GIT

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

* [PATCH v3 08/15] mfd: menelaus: Pass menelaus_chip pointer to add/remove irq functions
  2013-12-09 16:21         ` [PATCH v3 " Felipe Balbi
                             ` (5 preceding siblings ...)
  2013-12-09 16:21           ` [PATCH v3 07/15] mfd: menelaus: Limit the usage of the_menelaus Felipe Balbi
@ 2013-12-09 16:21           ` Felipe Balbi
  2013-12-10  9:00             ` Lee Jones
  2013-12-09 16:21           ` [PATCH v3 09/15] mfd: menelaus: Pass menelaus_chip pointer to get/set voltage Felipe Balbi
                             ` (7 subsequent siblings)
  14 siblings, 1 reply; 73+ messages in thread
From: Felipe Balbi @ 2013-12-09 16:21 UTC (permalink / raw)
  To: linux-arm-kernel

Those functions are static and can receive a menelaus_chip pointer very
easily.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 57 ++++++++++++++++++++++++++------------------------
 1 file changed, 30 insertions(+), 27 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 8796e5e..8672d86 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -236,28 +236,28 @@ static int menelaus_ack_irq(struct menelaus_chip *m, int irq)
 }
 
 /* Adds a handler for an interrupt. Does not run in interrupt context */
-static int menelaus_add_irq_work(int irq,
+static int menelaus_add_irq_work(struct menelaus_chip *m, int irq,
 		void (*handler)(struct menelaus_chip *))
 {
 	int ret = 0;
 
-	mutex_lock(&the_menelaus->lock);
-	the_menelaus->handlers[irq] = handler;
-	ret = menelaus_enable_irq(the_menelaus, irq);
-	mutex_unlock(&the_menelaus->lock);
+	mutex_lock(&m->lock);
+	m->handlers[irq] = handler;
+	ret = menelaus_enable_irq(m, irq);
+	mutex_unlock(&m->lock);
 
 	return ret;
 }
 
 /* Removes handler for an interrupt */
-static int menelaus_remove_irq_work(int irq)
+static int menelaus_remove_irq_work(struct menelaus_chip *m, int irq)
 {
 	int ret = 0;
 
-	mutex_lock(&the_menelaus->lock);
-	ret = menelaus_disable_irq(the_menelaus, irq);
-	the_menelaus->handlers[irq] = NULL;
-	mutex_unlock(&the_menelaus->lock);
+	mutex_lock(&m->lock);
+	ret = menelaus_disable_irq(m, irq);
+	m->handlers[irq] = NULL;
+	mutex_unlock(&m->lock);
 
 	return ret;
 }
@@ -412,23 +412,24 @@ EXPORT_SYMBOL(menelaus_set_mmc_slot);
 int menelaus_register_mmc_callback(void (*callback)(void *data, u8 card_mask),
 				   void *data)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int ret = 0;
 
-	the_menelaus->mmc_callback_data = data;
-	the_menelaus->mmc_callback = callback;
-	ret = menelaus_add_irq_work(MENELAUS_MMC_S1CD_IRQ,
+	m->mmc_callback_data = data;
+	m->mmc_callback = callback;
+	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S1CD_IRQ,
 				    menelaus_mmc_cd_work);
 	if (ret < 0)
 		return ret;
-	ret = menelaus_add_irq_work(MENELAUS_MMC_S2CD_IRQ,
+	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S2CD_IRQ,
 				    menelaus_mmc_cd_work);
 	if (ret < 0)
 		return ret;
-	ret = menelaus_add_irq_work(MENELAUS_MMC_S1D1_IRQ,
+	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S1D1_IRQ,
 				    menelaus_mmc_cd_work);
 	if (ret < 0)
 		return ret;
-	ret = menelaus_add_irq_work(MENELAUS_MMC_S2D1_IRQ,
+	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S2D1_IRQ,
 				    menelaus_mmc_cd_work);
 
 	return ret;
@@ -437,13 +438,15 @@ EXPORT_SYMBOL(menelaus_register_mmc_callback);
 
 void menelaus_unregister_mmc_callback(void)
 {
-	menelaus_remove_irq_work(MENELAUS_MMC_S1CD_IRQ);
-	menelaus_remove_irq_work(MENELAUS_MMC_S2CD_IRQ);
-	menelaus_remove_irq_work(MENELAUS_MMC_S1D1_IRQ);
-	menelaus_remove_irq_work(MENELAUS_MMC_S2D1_IRQ);
+	struct menelaus_chip *m = the_menelaus;
+
+	menelaus_remove_irq_work(m, MENELAUS_MMC_S1CD_IRQ);
+	menelaus_remove_irq_work(m, MENELAUS_MMC_S2CD_IRQ);
+	menelaus_remove_irq_work(m, MENELAUS_MMC_S1D1_IRQ);
+	menelaus_remove_irq_work(m, MENELAUS_MMC_S2D1_IRQ);
 
-	the_menelaus->mmc_callback = NULL;
-	the_menelaus->mmc_callback_data = NULL;
+	m->mmc_callback = NULL;
+	m->mmc_callback_data = NULL;
 }
 EXPORT_SYMBOL(menelaus_unregister_mmc_callback);
 
@@ -1070,8 +1073,8 @@ static int menelaus_ioctl(struct device *dev, unsigned cmd, unsigned long arg)
 	case RTC_UIE_ON:
 		if (m->uie)
 			return 0;
-		status = menelaus_remove_irq_work(MENELAUS_RTCTMR_IRQ);
-		status = menelaus_add_irq_work(MENELAUS_RTCTMR_IRQ,
+		status = menelaus_remove_irq_work(m, MENELAUS_RTCTMR_IRQ);
+		status = menelaus_add_irq_work(m, MENELAUS_RTCTMR_IRQ,
 				menelaus_rtc_update_work);
 		if (status == 0)
 			m->uie = 1;
@@ -1079,7 +1082,7 @@ static int menelaus_ioctl(struct device *dev, unsigned cmd, unsigned long arg)
 	case RTC_UIE_OFF:
 		if (!m->uie)
 			return 0;
-		status = menelaus_remove_irq_work(MENELAUS_RTCTMR_IRQ);
+		status = menelaus_remove_irq_work(m, MENELAUS_RTCTMR_IRQ);
 		if (status == 0)
 			m->uie = 0;
 		return status;
@@ -1127,7 +1130,7 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 
 	/* support RTC alarm; it can issue wakeups */
 	if (alarm) {
-		if (menelaus_add_irq_work(MENELAUS_RTCALM_IRQ,
+		if (menelaus_add_irq_work(m, MENELAUS_RTCALM_IRQ,
 				menelaus_rtc_alarm_work) < 0) {
 			dev_err(&m->client->dev, "can't handle RTC alarm\n");
 			return;
@@ -1154,7 +1157,7 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 			&menelaus_rtc_ops, THIS_MODULE);
 	if (IS_ERR(m->rtc)) {
 		if (alarm) {
-			menelaus_remove_irq_work(MENELAUS_RTCALM_IRQ);
+			menelaus_remove_irq_work(m, MENELAUS_RTCALM_IRQ);
 			device_init_wakeup(&m->client->dev, 0);
 		}
 		dev_err(&m->client->dev, "can't register RTC: %d\n",
-- 
1.8.4.GIT

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

* [PATCH v3 09/15] mfd: menelaus: Pass menelaus_chip pointer to get/set voltage
  2013-12-09 16:21         ` [PATCH v3 " Felipe Balbi
                             ` (6 preceding siblings ...)
  2013-12-09 16:21           ` [PATCH v3 08/15] mfd: menelaus: Pass menelaus_chip pointer to add/remove irq functions Felipe Balbi
@ 2013-12-09 16:21           ` Felipe Balbi
  2013-12-10  9:01             ` Lee Jones
  2013-12-09 16:21           ` [PATCH v3 10/15] mfd: menelaus: Pass menelaus_chip argument to menelaus <-> time helpers Felipe Balbi
                             ` (6 subsequent siblings)
  14 siblings, 1 reply; 73+ messages in thread
From: Felipe Balbi @ 2013-12-09 16:21 UTC (permalink / raw)
  To: linux-arm-kernel

Those functions are static and can easily receive a menelaus_chip
pointer argument.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 50 +++++++++++++++++++++++++++-----------------------
 1 file changed, 27 insertions(+), 23 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 8672d86..13d1cb0 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -463,10 +463,9 @@ struct menelaus_vtg_value {
 	u16 val;
 };
 
-static int menelaus_set_voltage(const struct menelaus_vtg *vtg, int mV,
-				int vtg_val, int mode)
+static int menelaus_set_voltage(struct menelaus_chip *m,
+		const struct menelaus_vtg *vtg, int mV, int vtg_val, int mode)
 {
-	struct menelaus_chip *m = the_menelaus;
 	struct i2c_client *c = m->client;
 	int val, ret;
 
@@ -498,8 +497,8 @@ out:
 	return ret;
 }
 
-static int menelaus_get_vtg_value(int vtg, const struct menelaus_vtg_value *tbl,
-				  int n)
+static int menelaus_get_vtg_value(struct menelaus_chip *m,
+		int vtg, const struct menelaus_vtg_value *tbl, int n)
 {
 	int i;
 
@@ -546,7 +545,7 @@ int menelaus_set_vcore_sw(unsigned int mV)
 	struct i2c_client *c = m->client;
 	int val, ret;
 
-	val = menelaus_get_vtg_value(mV, vcore_values,
+	val = menelaus_get_vtg_value(m, mV, vcore_values,
 				     ARRAY_SIZE(vcore_values));
 	if (val < 0)
 		return -EINVAL;
@@ -570,11 +569,11 @@ int menelaus_set_vcore_hw(unsigned int roof_mV, unsigned int floor_mV)
 	struct i2c_client *c = m->client;
 	int fval, rval, val, ret;
 
-	rval = menelaus_get_vtg_value(roof_mV, vcore_values,
+	rval = menelaus_get_vtg_value(m, roof_mV, vcore_values,
 				      ARRAY_SIZE(vcore_values));
 	if (rval < 0)
 		return -EINVAL;
-	fval = menelaus_get_vtg_value(floor_mV, vcore_values,
+	fval = menelaus_get_vtg_value(m, floor_mV, vcore_values,
 				      ARRAY_SIZE(vcore_values));
 	if (fval < 0)
 		return -EINVAL;
@@ -619,15 +618,16 @@ static const struct menelaus_vtg_value vmem_values[] = {
 
 int menelaus_set_vmem(unsigned int mV)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int val;
 
 	if (mV == 0)
-		return menelaus_set_voltage(&vmem_vtg, 0, 0, 0);
+		return menelaus_set_voltage(m, &vmem_vtg, 0, 0, 0);
 
-	val = menelaus_get_vtg_value(mV, vmem_values, ARRAY_SIZE(vmem_values));
+	val = menelaus_get_vtg_value(m, mV, vmem_values, ARRAY_SIZE(vmem_values));
 	if (val < 0)
 		return -EINVAL;
-	return menelaus_set_voltage(&vmem_vtg, mV, val, 0x02);
+	return menelaus_set_voltage(m, &vmem_vtg, mV, val, 0x02);
 }
 EXPORT_SYMBOL(menelaus_set_vmem);
 
@@ -648,15 +648,16 @@ static const struct menelaus_vtg_value vio_values[] = {
 
 int menelaus_set_vio(unsigned int mV)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int val;
 
 	if (mV == 0)
-		return menelaus_set_voltage(&vio_vtg, 0, 0, 0);
+		return menelaus_set_voltage(m, &vio_vtg, 0, 0, 0);
 
-	val = menelaus_get_vtg_value(mV, vio_values, ARRAY_SIZE(vio_values));
+	val = menelaus_get_vtg_value(m, mV, vio_values, ARRAY_SIZE(vio_values));
 	if (val < 0)
 		return -EINVAL;
-	return menelaus_set_voltage(&vio_vtg, mV, val, 0x02);
+	return menelaus_set_voltage(m, &vio_vtg, mV, val, 0x02);
 }
 EXPORT_SYMBOL(menelaus_set_vio);
 
@@ -689,6 +690,7 @@ static const struct menelaus_vtg vdcdc3_vtg = {
 
 int menelaus_set_vdcdc(int dcdc, unsigned int mV)
 {
+	struct menelaus_chip *m = the_menelaus;
 	const struct menelaus_vtg *vtg;
 	int val;
 
@@ -700,13 +702,13 @@ int menelaus_set_vdcdc(int dcdc, unsigned int mV)
 		vtg = &vdcdc3_vtg;
 
 	if (mV == 0)
-		return menelaus_set_voltage(vtg, 0, 0, 0);
+		return menelaus_set_voltage(m, vtg, 0, 0, 0);
 
-	val = menelaus_get_vtg_value(mV, vdcdc_values,
+	val = menelaus_get_vtg_value(m, mV, vdcdc_values,
 				     ARRAY_SIZE(vdcdc_values));
 	if (val < 0)
 		return -EINVAL;
-	return menelaus_set_voltage(vtg, mV, val, 0x03);
+	return menelaus_set_voltage(m, vtg, mV, val, 0x03);
 }
 
 static const struct menelaus_vtg_value vmmc_values[] = {
@@ -726,15 +728,16 @@ static const struct menelaus_vtg vmmc_vtg = {
 
 int menelaus_set_vmmc(unsigned int mV)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int val;
 
 	if (mV == 0)
-		return menelaus_set_voltage(&vmmc_vtg, 0, 0, 0);
+		return menelaus_set_voltage(m, &vmmc_vtg, 0, 0, 0);
 
-	val = menelaus_get_vtg_value(mV, vmmc_values, ARRAY_SIZE(vmmc_values));
+	val = menelaus_get_vtg_value(m, mV, vmmc_values, ARRAY_SIZE(vmmc_values));
 	if (val < 0)
 		return -EINVAL;
-	return menelaus_set_voltage(&vmmc_vtg, mV, val, 0x02);
+	return menelaus_set_voltage(m, &vmmc_vtg, mV, val, 0x02);
 }
 EXPORT_SYMBOL(menelaus_set_vmmc);
 
@@ -756,15 +759,16 @@ static const struct menelaus_vtg vaux_vtg = {
 
 int menelaus_set_vaux(unsigned int mV)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int val;
 
 	if (mV == 0)
-		return menelaus_set_voltage(&vaux_vtg, 0, 0, 0);
+		return menelaus_set_voltage(m, &vaux_vtg, 0, 0, 0);
 
-	val = menelaus_get_vtg_value(mV, vaux_values, ARRAY_SIZE(vaux_values));
+	val = menelaus_get_vtg_value(m, mV, vaux_values, ARRAY_SIZE(vaux_values));
 	if (val < 0)
 		return -EINVAL;
-	return menelaus_set_voltage(&vaux_vtg, mV, val, 0x02);
+	return menelaus_set_voltage(m, &vaux_vtg, mV, val, 0x02);
 }
 EXPORT_SYMBOL(menelaus_set_vaux);
 
-- 
1.8.4.GIT

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

* [PATCH v3 10/15] mfd: menelaus: Pass menelaus_chip argument to menelaus <-> time helpers
  2013-12-09 16:21         ` [PATCH v3 " Felipe Balbi
                             ` (7 preceding siblings ...)
  2013-12-09 16:21           ` [PATCH v3 09/15] mfd: menelaus: Pass menelaus_chip pointer to get/set voltage Felipe Balbi
@ 2013-12-09 16:21           ` Felipe Balbi
  2013-12-10  9:02             ` Lee Jones
  2013-12-09 16:21           ` [PATCH v3 11/15] mfd: menelaus: Start to use irqdomain Felipe Balbi
                             ` (5 subsequent siblings)
  14 siblings, 1 reply; 73+ messages in thread
From: Felipe Balbi @ 2013-12-09 16:21 UTC (permalink / raw)
  To: linux-arm-kernel

time_to_menelaus() and menelaus_to_time() are static and can easily
receive a struct menelaus_chip pointer argument.

After this patch, the_menelaus is only used on exported functions which
are currently being used by board-n8x0.c.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 13d1cb0..aa3c579 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -857,10 +857,9 @@ static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 
 #define RTC_HR_PM		(1 << 7)
 
-static void menelaus_to_time(char *regs, struct rtc_time *t)
+static void menelaus_to_time(struct menelaus_chip *m,
+		char *regs, struct rtc_time *t)
 {
-	struct menelaus_chip *m = the_menelaus;
-
 	t->tm_sec = bcd2bin(regs[0]);
 	t->tm_min = bcd2bin(regs[1]);
 	if (m->rtc_control & RTC_CTRL_MODE12) {
@@ -874,9 +873,9 @@ static void menelaus_to_time(char *regs, struct rtc_time *t)
 	t->tm_year = bcd2bin(regs[5]) + 100;
 }
 
-static int time_to_menelaus(struct rtc_time *t, int regnum)
+static int time_to_menelaus(struct menelaus_chip *m,
+		struct rtc_time *t, int regnum)
 {
-	struct menelaus_chip *m = the_menelaus;
 	int	hour, status;
 
 	status = menelaus_write_reg(m, regnum++, bin2bcd(t->tm_sec));
@@ -944,7 +943,7 @@ static int menelaus_read_time(struct device *dev, struct rtc_time *t)
 		return -EIO;
 	}
 
-	menelaus_to_time(regs, t);
+	menelaus_to_time(m, regs, t);
 	t->tm_wday = bcd2bin(regs[6]);
 
 	return 0;
@@ -956,7 +955,7 @@ static int menelaus_set_time(struct device *dev, struct rtc_time *t)
 	int		status;
 
 	/* write date and time registers */
-	status = time_to_menelaus(t, MENELAUS_RTC_SEC);
+	status = time_to_menelaus(m, t, MENELAUS_RTC_SEC);
 	if (status < 0)
 		return status;
 	status = menelaus_write_reg(m, MENELAUS_RTC_WKDAY, bin2bcd(t->tm_wday));
@@ -1001,7 +1000,7 @@ static int menelaus_read_alarm(struct device *dev, struct rtc_wkalrm *w)
 		return -EIO;
 	}
 
-	menelaus_to_time(regs, &w->time);
+	menelaus_to_time(m, regs, &w->time);
 
 	w->enabled = !!(m->rtc_control & RTC_CTRL_AL_EN);
 
@@ -1029,7 +1028,7 @@ static int menelaus_set_alarm(struct device *dev, struct rtc_wkalrm *w)
 	}
 
 	/* write alarm registers */
-	status = time_to_menelaus(&w->time, MENELAUS_RTC_AL_SEC);
+	status = time_to_menelaus(m, &w->time, MENELAUS_RTC_AL_SEC);
 	if (status < 0)
 		return status;
 
-- 
1.8.4.GIT

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

* [PATCH v3 11/15] mfd: menelaus: Start to use irqdomain
  2013-12-09 16:21         ` [PATCH v3 " Felipe Balbi
                             ` (8 preceding siblings ...)
  2013-12-09 16:21           ` [PATCH v3 10/15] mfd: menelaus: Pass menelaus_chip argument to menelaus <-> time helpers Felipe Balbi
@ 2013-12-09 16:21           ` Felipe Balbi
  2013-12-10  9:20             ` Lee Jones
  2013-12-09 16:21           ` [PATCH v3 12/15] mfd: menelaus: Switch all children to threaded_irq Felipe Balbi
                             ` (4 subsequent siblings)
  14 siblings, 1 reply; 73+ messages in thread
From: Felipe Balbi @ 2013-12-09 16:21 UTC (permalink / raw)
  To: linux-arm-kernel

Introduce an irq_chip and irq_domain for menelaus driver. Following
patches will convert uses to traditional request_threaded_irq().

While at that, some better error handling had to be added, so we could
free irq descs we allocated.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 120 insertions(+), 7 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index aa3c579..e4f33b7 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -34,6 +34,7 @@
 #include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
+#include <linux/irqdomain.h>
 #include <linux/sched.h>
 #include <linux/mutex.h>
 #include <linux/delay.h>
@@ -47,6 +48,7 @@
 #include <asm/gpio.h>
 
 #define DRIVER_NAME			"menelaus"
+#define MENELAUS_NR_IRQS		16
 
 #define MENELAUS_I2C_ADDRESS		0x72
 
@@ -168,11 +170,19 @@ struct menelaus_chip {
 	u8			rtc_control;
 	unsigned		uie:1;
 #endif
+	int			irq_base;
 	unsigned		vcore_hw_mode:1;
 	u8			mask1, mask2;
+	u8			ack1, ack2;
+
 	void			(*handlers[16])(struct menelaus_chip *);
 	void			(*mmc_callback)(void *data, u8 mask);
 	void			*mmc_callback_data;
+
+	unsigned		mask1_pending:1;
+	unsigned		mask2_pending:1;
+	unsigned		ack1_pending:1;
+	unsigned		ack2_pending:1;
 };
 
 static struct menelaus_chip *the_menelaus;
@@ -235,6 +245,83 @@ static int menelaus_ack_irq(struct menelaus_chip *m, int irq)
 		return menelaus_write_reg(m, MENELAUS_INT_ACK1, 1 << irq);
 }
 
+static void menelaus_irq_ack(struct irq_data *data)
+{
+	struct menelaus_chip *m = irq_data_get_irq_chip_data(data);
+	int irq = data->irq - m->irq_base;
+
+	if (irq > 7) {
+		m->ack2 |= BIT(irq);
+		m->ack2_pending = true;
+	} else {
+		m->ack1 |= BIT(irq);
+		m->ack1_pending = true;
+	}
+}
+
+static void menelaus_irq_mask(struct irq_data *data)
+{
+	struct menelaus_chip *m = irq_data_get_irq_chip_data(data);
+	int irq = data->irq - m->irq_base;
+
+	if (irq > 7) {
+		m->mask2 |= BIT(irq);
+		m->mask2_pending = true;
+	} else {
+		m->mask1 |= BIT(irq);
+		m->mask1_pending = true;
+	}
+}
+
+static void menelaus_irq_unmask(struct irq_data *data)
+{
+	struct menelaus_chip *m = irq_data_get_irq_chip_data(data);
+	int irq = data->irq - m->irq_base;
+
+	if (irq > 7) {
+		m->mask2 &= ~BIT(irq);
+		m->mask2_pending = true;
+	} else {
+		m->mask1 &= ~BIT(irq);
+		m->mask1_pending = true;
+	}
+}
+
+static void menelaus_irq_bus_lock(struct irq_data *data)
+{
+	struct menelaus_chip *m = irq_data_get_irq_chip_data(data);
+
+	mutex_lock(&m->lock);
+}
+
+static void menelaus_irq_bus_sync_unlock(struct irq_data *data)
+{
+	struct menelaus_chip *m = irq_data_get_irq_chip_data(data);
+
+	if (m->ack1_pending)
+		menelaus_write_reg(m, MENELAUS_INT_ACK1, m->ack1);
+
+	if (m->ack2_pending)
+		menelaus_write_reg(m, MENELAUS_INT_ACK2, m->ack2);
+
+	if (m->mask1_pending)
+		menelaus_write_reg(m, MENELAUS_INT_MASK1, m->mask1);
+
+	if (m->mask2_pending)
+		menelaus_write_reg(m, MENELAUS_INT_MASK2, m->mask2);
+
+	mutex_unlock(&m->lock);
+}
+
+static struct irq_chip menelaus_irq_chip = {
+	.name		= "menelaus",
+	.irq_ack	= menelaus_irq_ack,
+	.irq_mask	= menelaus_irq_mask,
+	.irq_unmask	= menelaus_irq_unmask,
+	.irq_bus_lock	= menelaus_irq_bus_lock,
+	.irq_bus_sync_unlock = menelaus_irq_bus_sync_unlock,
+};
+
 /* Adds a handler for an interrupt. Does not run in interrupt context */
 static int menelaus_add_irq_work(struct menelaus_chip *m, int irq,
 		void (*handler)(struct menelaus_chip *))
@@ -1186,8 +1273,11 @@ static int menelaus_probe(struct i2c_client *client,
 			  const struct i2c_device_id *id)
 {
 	struct menelaus_chip	*m;
+	struct device_node	*node = client->dev.of_node;
 	int			rev = 0, val;
 	int			err = 0;
+	int			irq_base;
+	int			i;
 	struct menelaus_platform_data *menelaus_pdata =
 					dev_get_platdata(&client->dev);
 
@@ -1205,12 +1295,32 @@ static int menelaus_probe(struct i2c_client *client,
 
 	the_menelaus = m;
 	m->client = client;
+	mutex_init(&m->lock);
+
+	irq_base = irq_alloc_descs(-1, 0, MENELAUS_NR_IRQS, 0);
+	if (irq_base < 0) {
+		dev_err(&client->dev, "failed to allocate irq descs\n");
+		return irq_base;
+	}
+
+	irq_domain_add_legacy(node, MENELAUS_NR_IRQS, irq_base, 0,
+			&irq_domain_simple_ops, m);
+
+	m->irq_base = irq_base;
+
+	for (i = irq_base; i < irq_base + MENELAUS_NR_IRQS; i++) {
+		irq_set_chip_data(i, m);
+		irq_set_chip_and_handler(i, &menelaus_irq_chip,
+				handle_simple_irq);
+		irq_set_nested_thread(i, 1);
+		set_irq_flags(i, IRQF_VALID);
+	}
 
 	/* If a true probe check the device */
 	rev = menelaus_read_reg(m, MENELAUS_REV);
 	if (rev < 0) {
 		pr_err(DRIVER_NAME ": device not found");
-		return -ENODEV;
+		goto fail_free_descs;
 	}
 
 	/* Ack and disable all Menelaus interrupts */
@@ -1230,17 +1340,15 @@ static int menelaus_probe(struct i2c_client *client,
 		if (err) {
 			dev_dbg(&client->dev,  "can't get IRQ %d, err %d\n",
 					client->irq, err);
-			return err;
+			goto fail_free_descs;
 		}
 	}
 
-	mutex_init(&m->lock);
-
 	pr_info("Menelaus rev %d.%d\n", rev >> 4, rev & 0x0f);
 
 	val = menelaus_read_reg(m, MENELAUS_VCORE_CTRL1);
 	if (val < 0)
-		goto fail;
+		goto fail_free_irq;
 	if (val & (1 << 7))
 		m->vcore_hw_mode = 1;
 	else
@@ -1249,14 +1357,18 @@ static int menelaus_probe(struct i2c_client *client,
 	if (menelaus_pdata != NULL && menelaus_pdata->late_init != NULL) {
 		err = menelaus_pdata->late_init(&client->dev);
 		if (err < 0)
-			goto fail;
+			goto fail_free_irq;
 	}
 
 	menelaus_rtc_init(m);
 
 	return 0;
-fail:
+fail_free_irq:
 	free_irq(client->irq, m);
+
+fail_free_descs:
+	irq_free_descs(irq_base, MENELAUS_NR_IRQS);
+
 	return err;
 }
 
@@ -1265,6 +1377,7 @@ static int menelaus_remove(struct i2c_client *client)
 	struct menelaus_chip	*m = i2c_get_clientdata(client);
 
 	free_irq(client->irq, m);
+	irq_free_descs(m->irq_base, MENELAUS_NR_IRQS);
 	the_menelaus = NULL;
 	return 0;
 }
-- 
1.8.4.GIT

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

* [PATCH v3 12/15] mfd: menelaus: Switch all children to threaded_irq
  2013-12-09 16:21         ` [PATCH v3 " Felipe Balbi
                             ` (9 preceding siblings ...)
  2013-12-09 16:21           ` [PATCH v3 11/15] mfd: menelaus: Start to use irqdomain Felipe Balbi
@ 2013-12-09 16:21           ` Felipe Balbi
  2013-12-09 16:21           ` [PATCH v3 13/15] mfd: menelaus: Remove unnecessary definition Felipe Balbi
                             ` (3 subsequent siblings)
  14 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-09 16:21 UTC (permalink / raw)
  To: linux-arm-kernel

Now that we have our own irq_chip, all children can use traditional
request_threaded_irq().

While at that, also remove so functions which became unused.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 161 +++++++++++++++----------------------------------
 1 file changed, 50 insertions(+), 111 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index e4f33b7..74eae19 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -175,7 +175,6 @@ struct menelaus_chip {
 	u8			mask1, mask2;
 	u8			ack1, ack2;
 
-	void			(*handlers[16])(struct menelaus_chip *);
 	void			(*mmc_callback)(void *data, u8 mask);
 	void			*mmc_callback_data;
 
@@ -209,42 +208,6 @@ static int menelaus_read_reg(struct menelaus_chip *m, int reg)
 	return val;
 }
 
-static int menelaus_enable_irq(struct menelaus_chip *m, int irq)
-{
-	if (irq > 7) {
-		irq -= 8;
-		m->mask2 &= ~(1 << irq);
-		return menelaus_write_reg(m, MENELAUS_INT_MASK2,
-				m->mask2);
-	} else {
-		m->mask1 &= ~(1 << irq);
-		return menelaus_write_reg(m, MENELAUS_INT_MASK1,
-				m->mask1);
-	}
-}
-
-static int menelaus_disable_irq(struct menelaus_chip *m, int irq)
-{
-	if (irq > 7) {
-		irq -= 8;
-		m->mask2 |= (1 << irq);
-		return menelaus_write_reg(m, MENELAUS_INT_MASK2,
-				m->mask2);
-	} else {
-		m->mask1 |= (1 << irq);
-		return menelaus_write_reg(m, MENELAUS_INT_MASK1,
-				m->mask1);
-	}
-}
-
-static int menelaus_ack_irq(struct menelaus_chip *m, int irq)
-{
-	if (irq > 7)
-		return menelaus_write_reg(m, MENELAUS_INT_ACK2, 1 << (irq - 8));
-	else
-		return menelaus_write_reg(m, MENELAUS_INT_ACK1, 1 << irq);
-}
-
 static void menelaus_irq_ack(struct irq_data *data)
 {
 	struct menelaus_chip *m = irq_data_get_irq_chip_data(data);
@@ -322,47 +285,15 @@ static struct irq_chip menelaus_irq_chip = {
 	.irq_bus_sync_unlock = menelaus_irq_bus_sync_unlock,
 };
 
-/* Adds a handler for an interrupt. Does not run in interrupt context */
-static int menelaus_add_irq_work(struct menelaus_chip *m, int irq,
-		void (*handler)(struct menelaus_chip *))
-{
-	int ret = 0;
-
-	mutex_lock(&m->lock);
-	m->handlers[irq] = handler;
-	ret = menelaus_enable_irq(m, irq);
-	mutex_unlock(&m->lock);
-
-	return ret;
-}
-
-/* Removes handler for an interrupt */
-static int menelaus_remove_irq_work(struct menelaus_chip *m, int irq)
-{
-	int ret = 0;
-
-	mutex_lock(&m->lock);
-	ret = menelaus_disable_irq(m, irq);
-	m->handlers[irq] = NULL;
-	mutex_unlock(&m->lock);
-
-	return ret;
-}
-
-/*
- * Gets scheduled when a card detect interrupt happens. Note that in some cases
- * this line is wired to card cover switch rather than the card detect switch
- * in each slot. In this case the cards are not seen by menelaus.
- * FIXME: Add handling for D1 too
- */
-static void menelaus_mmc_cd_work(struct menelaus_chip *m)
+static irqreturn_t menelaus_mmc_cd_irq(int irq, void *_m)
 {
-	int reg;
+	struct menelaus_chip *m = _m;
 	unsigned char card_mask = 0;
+	int reg;
 
 	reg = menelaus_read_reg(m, MENELAUS_MCT_PIN_ST);
 	if (reg < 0)
-		return;
+		return IRQ_NONE;
 
 	if (!(reg & 0x1))
 		card_mask |= MCT_PIN_ST_S1_CD_ST;
@@ -373,6 +304,8 @@ static void menelaus_mmc_cd_work(struct menelaus_chip *m)
 	if (m->mmc_callback)
 		m->mmc_callback(m->mmc_callback_data,
 					  card_mask);
+
+	return IRQ_HANDLED;
 }
 
 /*
@@ -504,20 +437,25 @@ int menelaus_register_mmc_callback(void (*callback)(void *data, u8 card_mask),
 
 	m->mmc_callback_data = data;
 	m->mmc_callback = callback;
-	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S1CD_IRQ,
-				    menelaus_mmc_cd_work);
+
+	ret = request_threaded_irq(MENELAUS_MMC_S1CD_IRQ + m->irq_base,
+			NULL, menelaus_mmc_cd_irq, IRQF_ONESHOT,
+			"mmc_s1cd", m);
 	if (ret < 0)
 		return ret;
-	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S2CD_IRQ,
-				    menelaus_mmc_cd_work);
+	ret = request_threaded_irq(MENELAUS_MMC_S2CD_IRQ + m->irq_base,
+			NULL, menelaus_mmc_cd_irq, IRQF_ONESHOT,
+			"mmc_s2cd", m);
 	if (ret < 0)
 		return ret;
-	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S1D1_IRQ,
-				    menelaus_mmc_cd_work);
+	ret = request_threaded_irq(MENELAUS_MMC_S1D1_IRQ + m->irq_base,
+			NULL, menelaus_mmc_cd_irq, IRQF_ONESHOT,
+			"mmc_s1d1", m);
 	if (ret < 0)
 		return ret;
-	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S2D1_IRQ,
-				    menelaus_mmc_cd_work);
+	ret = request_threaded_irq(MENELAUS_MMC_S2D1_IRQ + m->irq_base,
+			NULL, menelaus_mmc_cd_irq, IRQF_ONESHOT,
+			"mmc_s2d1", m);
 
 	return ret;
 }
@@ -527,10 +465,10 @@ void menelaus_unregister_mmc_callback(void)
 {
 	struct menelaus_chip *m = the_menelaus;
 
-	menelaus_remove_irq_work(m, MENELAUS_MMC_S1CD_IRQ);
-	menelaus_remove_irq_work(m, MENELAUS_MMC_S2CD_IRQ);
-	menelaus_remove_irq_work(m, MENELAUS_MMC_S1D1_IRQ);
-	menelaus_remove_irq_work(m, MENELAUS_MMC_S2D1_IRQ);
+	free_irq(MENELAUS_MMC_S1CD_IRQ + m->irq_base, m);
+	free_irq(MENELAUS_MMC_S2CD_IRQ + m->irq_base, m);
+	free_irq(MENELAUS_MMC_S1D1_IRQ + m->irq_base, m);
+	free_irq(MENELAUS_MMC_S2D1_IRQ + m->irq_base, m);
 
 	m->mmc_callback = NULL;
 	m->mmc_callback_data = NULL;
@@ -899,7 +837,6 @@ out:
 static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 {
 	struct menelaus_chip *m = _menelaus;
-	void (*handler)(struct menelaus_chip *m);
 	unsigned long isr;
 	unsigned long i;
 
@@ -909,14 +846,9 @@ static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 		& ~m->mask1;
 
 	for_each_set_bit(i, &isr, 16) {
-		mutex_lock(&m->lock);
-		menelaus_disable_irq(m, i);
-		menelaus_ack_irq(m, i);
-		handler = m->handlers[i];
-		if (handler)
-			handler(m);
-		menelaus_enable_irq(m, i);
-		mutex_unlock(&m->lock);
+		int irq = i + m->irq_base;
+
+		handle_nested_irq(irq);
 	}
 
 	return IRQ_HANDLED;
@@ -1131,18 +1063,19 @@ static int menelaus_set_alarm(struct device *dev, struct rtc_wkalrm *w)
 
 #ifdef CONFIG_RTC_INTF_DEV
 
-static void menelaus_rtc_update_work(struct menelaus_chip *m)
+static irqreturn_t menelaus_rtc_update_irq(int irq, void *_m)
 {
-	/* report 1/sec update */
-	local_irq_disable();
+	struct menelaus_chip *m = _m;
+
 	rtc_update_irq(m->rtc, 1, RTC_IRQF | RTC_UF);
-	local_irq_enable();
+
+	return IRQ_HANDLED;
 }
 
 static int menelaus_ioctl(struct device *dev, unsigned cmd, unsigned long arg)
 {
 	struct menelaus_chip *m = dev_get_drvdata(dev);
-	int	status;
+	int	status = 0;
 
 	if (m->client->irq <= 0)
 		return -ENOIOCTLCMD;
@@ -1163,18 +1096,18 @@ static int menelaus_ioctl(struct device *dev, unsigned cmd, unsigned long arg)
 	case RTC_UIE_ON:
 		if (m->uie)
 			return 0;
-		status = menelaus_remove_irq_work(m, MENELAUS_RTCTMR_IRQ);
-		status = menelaus_add_irq_work(m, MENELAUS_RTCTMR_IRQ,
-				menelaus_rtc_update_work);
+		free_irq(MENELAUS_RTCTMR_IRQ + m->irq_base, m);
+		status = request_threaded_irq(MENELAUS_RTCTMR_IRQ + m->irq_base,
+				NULL, menelaus_rtc_update_irq, IRQF_ONESHOT,
+				"rtc-timer", m);
 		if (status == 0)
 			m->uie = 1;
 		return status;
 	case RTC_UIE_OFF:
 		if (!m->uie)
 			return 0;
-		status = menelaus_remove_irq_work(m, MENELAUS_RTCTMR_IRQ);
-		if (status == 0)
-			m->uie = 0;
+		free_irq(MENELAUS_RTCTMR_IRQ + m->irq_base, m);
+		m->uie = 0;
 		return status;
 	default:
 		return -ENOIOCTLCMD;
@@ -1196,16 +1129,18 @@ static const struct rtc_class_ops menelaus_rtc_ops = {
 	.set_alarm		= menelaus_set_alarm,
 };
 
-static void menelaus_rtc_alarm_work(struct menelaus_chip *m)
+static irqreturn_t menelaus_rtc_alarm_irq(int irq, void *_m)
 {
+	struct menelaus_chip *m = _m;
+
 	/* report alarm */
-	local_irq_disable();
 	rtc_update_irq(m->rtc, 1, RTC_IRQF | RTC_AF);
-	local_irq_enable();
 
 	/* then disable it; alarms are oneshot */
 	m->rtc_control &= ~RTC_CTRL_AL_EN;
 	menelaus_write_reg(m, MENELAUS_RTC_CTRL, m->rtc_control);
+
+	return IRQ_HANDLED;
 }
 
 static inline void menelaus_rtc_init(struct menelaus_chip *m)
@@ -1220,8 +1155,12 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 
 	/* support RTC alarm; it can issue wakeups */
 	if (alarm) {
-		if (menelaus_add_irq_work(m, MENELAUS_RTCALM_IRQ,
-				menelaus_rtc_alarm_work) < 0) {
+		int ret;
+
+		ret = request_threaded_irq(MENELAUS_RTCALM_IRQ + m->irq_base,
+				NULL, menelaus_rtc_alarm_irq, IRQF_ONESHOT,
+				"rtc-alarm", m);
+		if (ret < 0) {
 			dev_err(&m->client->dev, "can't handle RTC alarm\n");
 			return;
 		}
@@ -1247,7 +1186,7 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 			&menelaus_rtc_ops, THIS_MODULE);
 	if (IS_ERR(m->rtc)) {
 		if (alarm) {
-			menelaus_remove_irq_work(m, MENELAUS_RTCALM_IRQ);
+			free_irq(MENELAUS_RTCALM_IRQ + m->irq_base, m);
 			device_init_wakeup(&m->client->dev, 0);
 		}
 		dev_err(&m->client->dev, "can't register RTC: %d\n",
-- 
1.8.4.GIT

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

* [PATCH v3 13/15] mfd: menelaus: Remove unnecessary definition
  2013-12-09 16:21         ` [PATCH v3 " Felipe Balbi
                             ` (10 preceding siblings ...)
  2013-12-09 16:21           ` [PATCH v3 12/15] mfd: menelaus: Switch all children to threaded_irq Felipe Balbi
@ 2013-12-09 16:21           ` Felipe Balbi
  2013-12-09 16:21           ` [PATCH v3 14/15] mfd: menelaus: IRQ is a requirement Felipe Balbi
                             ` (2 subsequent siblings)
  14 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-09 16:21 UTC (permalink / raw)
  To: linux-arm-kernel

menelaus_i2c_driver isn't referenced on probe, just remove that
unnecessary line. No functional changes.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 74eae19..c0219b7 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -1206,8 +1206,6 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 
 /*-----------------------------------------------------------------------*/
 
-static struct i2c_driver menelaus_i2c_driver;
-
 static int menelaus_probe(struct i2c_client *client,
 			  const struct i2c_device_id *id)
 {
-- 
1.8.4.GIT

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

* [PATCH v3 14/15] mfd: menelaus: IRQ is a requirement
  2013-12-09 16:21         ` [PATCH v3 " Felipe Balbi
                             ` (11 preceding siblings ...)
  2013-12-09 16:21           ` [PATCH v3 13/15] mfd: menelaus: Remove unnecessary definition Felipe Balbi
@ 2013-12-09 16:21           ` Felipe Balbi
  2013-12-09 16:21           ` [PATCH v3 15/15] mfd: menelaus: Use devm_request_threaded_irq() Felipe Balbi
  2013-12-11  9:48           ` [PATCH v3 01/15] mfd: menelaus: Drop __exit section annotation Uwe Kleine-König
  14 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-09 16:21 UTC (permalink / raw)
  To: linux-arm-kernel

This driver needs IRQ to work, if client->irq isn't set properly, we
won't work. Remove check around request_threaded_irq().

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index c0219b7..bffe978 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -1271,14 +1271,12 @@ static int menelaus_probe(struct i2c_client *client,
 	/* Set output buffer strengths */
 	menelaus_write_reg(m, MENELAUS_MCT_CTRL1, 0x73);
 
-	if (client->irq > 0) {
-		err = request_threaded_irq(client->irq, NULL, menelaus_irq,
-				IRQF_ONESHOT, DRIVER_NAME, m);
-		if (err) {
-			dev_dbg(&client->dev,  "can't get IRQ %d, err %d\n",
-					client->irq, err);
-			goto fail_free_descs;
-		}
+	err = request_threaded_irq(client->irq, NULL, menelaus_irq,
+			IRQF_ONESHOT, DRIVER_NAME, m);
+	if (err) {
+		dev_dbg(&client->dev,  "can't get IRQ %d, err %d\n",
+				client->irq, err);
+		goto fail_free_descs;
 	}
 
 	pr_info("Menelaus rev %d.%d\n", rev >> 4, rev & 0x0f);
-- 
1.8.4.GIT

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

* [PATCH v3 15/15] mfd: menelaus: Use devm_request_threaded_irq()
  2013-12-09 16:21         ` [PATCH v3 " Felipe Balbi
                             ` (12 preceding siblings ...)
  2013-12-09 16:21           ` [PATCH v3 14/15] mfd: menelaus: IRQ is a requirement Felipe Balbi
@ 2013-12-09 16:21           ` Felipe Balbi
  2013-12-10  9:30             ` Lee Jones
  2013-12-11  9:48           ` [PATCH v3 01/15] mfd: menelaus: Drop __exit section annotation Uwe Kleine-König
  14 siblings, 1 reply; 73+ messages in thread
From: Felipe Balbi @ 2013-12-09 16:21 UTC (permalink / raw)
  To: linux-arm-kernel

By using devm_request_threaded_irq() we can drop a few extra lines of
code and rely on device managed resources layer to free our IRQ for us.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index bffe978..b87c2bd 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -1271,8 +1271,8 @@ static int menelaus_probe(struct i2c_client *client,
 	/* Set output buffer strengths */
 	menelaus_write_reg(m, MENELAUS_MCT_CTRL1, 0x73);
 
-	err = request_threaded_irq(client->irq, NULL, menelaus_irq,
-			IRQF_ONESHOT, DRIVER_NAME, m);
+	err = devm_request_threaded_irq(&client->dev, client->irq,
+			NULL, menelaus_irq, IRQF_ONESHOT, DRIVER_NAME, m);
 	if (err) {
 		dev_dbg(&client->dev,  "can't get IRQ %d, err %d\n",
 				client->irq, err);
@@ -1283,7 +1283,7 @@ static int menelaus_probe(struct i2c_client *client,
 
 	val = menelaus_read_reg(m, MENELAUS_VCORE_CTRL1);
 	if (val < 0)
-		goto fail_free_irq;
+		goto fail_free_descs;
 	if (val & (1 << 7))
 		m->vcore_hw_mode = 1;
 	else
@@ -1292,14 +1292,12 @@ static int menelaus_probe(struct i2c_client *client,
 	if (menelaus_pdata != NULL && menelaus_pdata->late_init != NULL) {
 		err = menelaus_pdata->late_init(&client->dev);
 		if (err < 0)
-			goto fail_free_irq;
+			goto fail_free_descs;
 	}
 
 	menelaus_rtc_init(m);
 
 	return 0;
-fail_free_irq:
-	free_irq(client->irq, m);
 
 fail_free_descs:
 	irq_free_descs(irq_base, MENELAUS_NR_IRQS);
@@ -1311,7 +1309,6 @@ static int menelaus_remove(struct i2c_client *client)
 {
 	struct menelaus_chip	*m = i2c_get_clientdata(client);
 
-	free_irq(client->irq, m);
 	irq_free_descs(m->irq_base, MENELAUS_NR_IRQS);
 	the_menelaus = NULL;
 	return 0;
-- 
1.8.4.GIT

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

* [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation
  2013-12-09 16:14       ` Felipe Balbi
  2013-12-09 16:21         ` [PATCH v3 " Felipe Balbi
@ 2013-12-10  8:50         ` Lee Jones
  2013-12-10 16:36           ` Felipe Balbi
  1 sibling, 1 reply; 73+ messages in thread
From: Lee Jones @ 2013-12-10  8:50 UTC (permalink / raw)
  To: linux-arm-kernel

> > > > The code looks mostly fine, but the implementation of the commit logs
> > > > seems lazy. Please submit a v3 using coherent sentences with full
> > > > explanations and correct punctuation.
> > > 
> > > example ?
> > 
> > All of your commit messages.
> > 
> > > that macro just helps removing some extra
> > 
> >   ^- Sentences start with an uppercase character.
> > 
> > > line of code and hides ffs() calls.
> > > 
> > > while at that, also fix a variable shadowing
> > 
> >   ^- Sentences start with an uppercase character.
> > 
> > > bug where 'int irq' was being redeclared inside
> > > inner loop while it was also argument to interrupt
> > > handler.
> > 
> >   < ---------------   50 chars   ----------------- >
> > 
> > Please use the full 72 char (or there abouts) width of the buffer.
> 
> I don't see any mention of punctuation problems, however. Also, you're
> not complaining about the content at all, which tells me those sentences
> aren't as incoherent as you claimed before.

I didn't read them in any detail. I traversed through the patches and
saw that the formatting looked obscure on all of them. As I have come
to expect more of your submissions, I provided a generic reply
detailing how I expected the commit logs to be. I wasn't insinuated
that you failed to meet all of the criteria, but they definitely fell
short of the mark.

> But fair enough, I'll fix those up and add Aaro's Tested-by

Thank you.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* [PATCH v3 07/15] mfd: menelaus: Limit the usage of the_menelaus
  2013-12-09 16:21           ` [PATCH v3 07/15] mfd: menelaus: Limit the usage of the_menelaus Felipe Balbi
@ 2013-12-10  8:57             ` Lee Jones
  2013-12-10 16:32               ` Felipe Balbi
  0 siblings, 1 reply; 73+ messages in thread
From: Lee Jones @ 2013-12-10  8:57 UTC (permalink / raw)
  To: linux-arm-kernel

> Pass a menelaus_chip pointer as argument to most functions so we can
> minimize the usage of the global the_menelaus pointer.
> 
> Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> Signed-off-by: Felipe Balbi <balbi@ti.com>
> ---
>  drivers/mfd/menelaus.c | 265 ++++++++++++++++++++++++++-----------------------
>  1 file changed, 142 insertions(+), 123 deletions(-)

How is this different from patch 6?

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* [PATCH v3 08/15] mfd: menelaus: Pass menelaus_chip pointer to add/remove irq functions
  2013-12-09 16:21           ` [PATCH v3 08/15] mfd: menelaus: Pass menelaus_chip pointer to add/remove irq functions Felipe Balbi
@ 2013-12-10  9:00             ` Lee Jones
  2013-12-10 16:32               ` Felipe Balbi
  0 siblings, 1 reply; 73+ messages in thread
From: Lee Jones @ 2013-12-10  9:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 09 Dec 2013, Felipe Balbi wrote:

> Those functions are static and can receive a menelaus_chip pointer very
> easily.
> 
> Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> Signed-off-by: Felipe Balbi <balbi@ti.com>
> ---
>  drivers/mfd/menelaus.c | 57 ++++++++++++++++++++++++++------------------------
>  1 file changed, 30 insertions(+), 27 deletions(-)

Same here. I think this should be done in one fell swoop.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* [PATCH v3 09/15] mfd: menelaus: Pass menelaus_chip pointer to get/set voltage
  2013-12-09 16:21           ` [PATCH v3 09/15] mfd: menelaus: Pass menelaus_chip pointer to get/set voltage Felipe Balbi
@ 2013-12-10  9:01             ` Lee Jones
  0 siblings, 0 replies; 73+ messages in thread
From: Lee Jones @ 2013-12-10  9:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 09 Dec 2013, Felipe Balbi wrote:

> Those functions are static and can easily receive a menelaus_chip
> pointer argument.
> 
> Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> Signed-off-by: Felipe Balbi <balbi@ti.com>
> ---
>  drivers/mfd/menelaus.c | 50 +++++++++++++++++++++++++++-----------------------
>  1 file changed, 27 insertions(+), 23 deletions(-)

I see a theme forming.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* [PATCH v3 10/15] mfd: menelaus: Pass menelaus_chip argument to menelaus <-> time helpers
  2013-12-09 16:21           ` [PATCH v3 10/15] mfd: menelaus: Pass menelaus_chip argument to menelaus <-> time helpers Felipe Balbi
@ 2013-12-10  9:02             ` Lee Jones
  0 siblings, 0 replies; 73+ messages in thread
From: Lee Jones @ 2013-12-10  9:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 09 Dec 2013, Felipe Balbi wrote:

> time_to_menelaus() and menelaus_to_time() are static and can easily
> receive a struct menelaus_chip pointer argument.
> 
> After this patch, the_menelaus is only used on exported functions which
> are currently being used by board-n8x0.c.
> 
> Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> Signed-off-by: Felipe Balbi <balbi@ti.com>
> ---
>  drivers/mfd/menelaus.c | 17 ++++++++---------
>  1 file changed, 8 insertions(+), 9 deletions(-)

Same.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* [PATCH v3 11/15] mfd: menelaus: Start to use irqdomain
  2013-12-09 16:21           ` [PATCH v3 11/15] mfd: menelaus: Start to use irqdomain Felipe Balbi
@ 2013-12-10  9:20             ` Lee Jones
  2013-12-10 16:34               ` Felipe Balbi
  0 siblings, 1 reply; 73+ messages in thread
From: Lee Jones @ 2013-12-10  9:20 UTC (permalink / raw)
  To: linux-arm-kernel

> Introduce an irq_chip and irq_domain for menelaus driver. Following
> patches will convert uses to traditional request_threaded_irq().
> 
> While at that, some better error handling had to be added, so we could
> free irq descs we allocated.
> 
> Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> Signed-off-by: Felipe Balbi <balbi@ti.com>
> ---
>  drivers/mfd/menelaus.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++---

<snip>

> +	irq_domain_add_legacy(node, MENELAUS_NR_IRQS, irq_base, 0,
> +			&irq_domain_simple_ops, m);

When will this driver become DT compliant?

I think you should use irq_domain_add_simple() to future proof
yourself a little.

> +	m->irq_base = irq_base;
> +
> +	for (i = irq_base; i < irq_base + MENELAUS_NR_IRQS; i++) {
> +		irq_set_chip_data(i, m);
> +		irq_set_chip_and_handler(i, &menelaus_irq_chip,
> +				handle_simple_irq);
> +		irq_set_nested_thread(i, 1);
> +		set_irq_flags(i, IRQF_VALID);

This assumes that this h/w only exists on ARM platforms. Is that true?

> +	}

This is usually completed in an *_irq_map() operation call-back.

I can't see where you reverse this process either (usually *_irq_unmap())

<snip>

> -	mutex_init(&m->lock);
> -

This doesn't belong in this patch.

It should have been removed with the final use of the lock was.

<snip>

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* [PATCH v3 15/15] mfd: menelaus: Use devm_request_threaded_irq()
  2013-12-09 16:21           ` [PATCH v3 15/15] mfd: menelaus: Use devm_request_threaded_irq() Felipe Balbi
@ 2013-12-10  9:30             ` Lee Jones
  2013-12-10 16:34               ` Felipe Balbi
  0 siblings, 1 reply; 73+ messages in thread
From: Lee Jones @ 2013-12-10  9:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 09 Dec 2013, Felipe Balbi wrote:

> By using devm_request_threaded_irq() we can drop a few extra lines of
> code and rely on device managed resources layer to free our IRQ for us.
> 
> Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> Signed-off-by: Felipe Balbi <balbi@ti.com>
> ---
>  drivers/mfd/menelaus.c | 11 ++++-------
>  1 file changed, 4 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
> index bffe978..b87c2bd 100644
> --- a/drivers/mfd/menelaus.c
> +++ b/drivers/mfd/menelaus.c
> @@ -1271,8 +1271,8 @@ static int menelaus_probe(struct i2c_client *client,
>  	/* Set output buffer strengths */
>  	menelaus_write_reg(m, MENELAUS_MCT_CTRL1, 0x73);
>  
> -	err = request_threaded_irq(client->irq, NULL, menelaus_irq,
> -			IRQF_ONESHOT, DRIVER_NAME, m);
> +	err = devm_request_threaded_irq(&client->dev, client->irq,
> +			NULL, menelaus_irq, IRQF_ONESHOT, DRIVER_NAME, m);

No need for a separate patch here. Convert straight from request_irq()
to devm_request_threaded_irq() in patch 3.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* [PATCH v3 03/15] mfd: menelaus: Convert to threaded irq
  2013-12-09 16:21           ` [PATCH v3 03/15] mfd: menelaus: Convert to threaded irq Felipe Balbi
@ 2013-12-10  9:32             ` Lee Jones
  2013-12-10 16:31               ` Felipe Balbi
  0 siblings, 1 reply; 73+ messages in thread
From: Lee Jones @ 2013-12-10  9:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 09 Dec 2013, Felipe Balbi wrote:

> We don't need that extra workqueue when we have generic threaded irq
> handlers support. This patch just moves over to threaded irqs and
> deletes the unnecessary workqueue.
> 
> Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> Signed-off-by: Felipe Balbi <balbi@ti.com>
> ---
>  drivers/mfd/menelaus.c | 29 ++++-------------------------
>  1 file changed, 4 insertions(+), 25 deletions(-)

<snip>

> -		err = request_irq(client->irq, menelaus_irq, 0,
> -				  DRIVER_NAME, menelaus);
> +		err = request_threaded_irq(client->irq, NULL, menelaus_irq,
> +				IRQF_ONESHOT, DRIVER_NAME, menelaus);

devm_* managed resources please.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* [PATCH v3 03/15] mfd: menelaus: Convert to threaded irq
  2013-12-10  9:32             ` Lee Jones
@ 2013-12-10 16:31               ` Felipe Balbi
  0 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-10 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Tue, Dec 10, 2013 at 09:32:13AM +0000, Lee Jones wrote:
> On Mon, 09 Dec 2013, Felipe Balbi wrote:
> 
> > We don't need that extra workqueue when we have generic threaded irq
> > handlers support. This patch just moves over to threaded irqs and
> > deletes the unnecessary workqueue.
> > 
> > Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> > Signed-off-by: Felipe Balbi <balbi@ti.com>
> > ---
> >  drivers/mfd/menelaus.c | 29 ++++-------------------------
> >  1 file changed, 4 insertions(+), 25 deletions(-)
> 
> <snip>
> 
> > -		err = request_irq(client->irq, menelaus_irq, 0,
> > -				  DRIVER_NAME, menelaus);
> > +		err = request_threaded_irq(client->irq, NULL, menelaus_irq,
> > +				IRQF_ONESHOT, DRIVER_NAME, menelaus);
> 
> devm_* managed resources please.

that would be subject to another patch. One that converts to devm_* on
the entire driver.

-- 
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/20131210/a7081e9e/attachment-0001.sig>

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

* [PATCH v3 07/15] mfd: menelaus: Limit the usage of the_menelaus
  2013-12-10  8:57             ` Lee Jones
@ 2013-12-10 16:32               ` Felipe Balbi
  2013-12-11  9:17                 ` Lee Jones
  0 siblings, 1 reply; 73+ messages in thread
From: Felipe Balbi @ 2013-12-10 16:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Dec 10, 2013 at 08:57:01AM +0000, Lee Jones wrote:
> > Pass a menelaus_chip pointer as argument to most functions so we can
> > minimize the usage of the global the_menelaus pointer.
> > 
> > Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> > Signed-off-by: Felipe Balbi <balbi@ti.com>
> > ---
> >  drivers/mfd/menelaus.c | 265 ++++++++++++++++++++++++++-----------------------
> >  1 file changed, 142 insertions(+), 123 deletions(-)
> 
> How is this different from patch 6?

have you read the patch ? patch 6 converts *only* enable/disable irq
functions.

-- 
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/20131210/07a67e99/attachment.sig>

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

* [PATCH v3 08/15] mfd: menelaus: Pass menelaus_chip pointer to add/remove irq functions
  2013-12-10  9:00             ` Lee Jones
@ 2013-12-10 16:32               ` Felipe Balbi
  2013-12-10 18:42                 ` Lee Jones
  0 siblings, 1 reply; 73+ messages in thread
From: Felipe Balbi @ 2013-12-10 16:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Dec 10, 2013 at 09:00:21AM +0000, Lee Jones wrote:
> On Mon, 09 Dec 2013, Felipe Balbi wrote:
> 
> > Those functions are static and can receive a menelaus_chip pointer very
> > easily.
> > 
> > Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> > Signed-off-by: Felipe Balbi <balbi@ti.com>
> > ---
> >  drivers/mfd/menelaus.c | 57 ++++++++++++++++++++++++++------------------------
> >  1 file changed, 30 insertions(+), 27 deletions(-)
> 
> Same here. I think this should be done in one fell swoop.

then it would become a much, much larger patch which would become a pain
to review.

-- 
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/20131210/7a409074/attachment.sig>

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

* [PATCH v3 11/15] mfd: menelaus: Start to use irqdomain
  2013-12-10  9:20             ` Lee Jones
@ 2013-12-10 16:34               ` Felipe Balbi
  2013-12-10 18:37                 ` Lee Jones
  0 siblings, 1 reply; 73+ messages in thread
From: Felipe Balbi @ 2013-12-10 16:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Dec 10, 2013 at 09:20:50AM +0000, Lee Jones wrote:
> > Introduce an irq_chip and irq_domain for menelaus driver. Following
> > patches will convert uses to traditional request_threaded_irq().
> > 
> > While at that, some better error handling had to be added, so we could
> > free irq descs we allocated.
> > 
> > Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> > Signed-off-by: Felipe Balbi <balbi@ti.com>
> > ---
> >  drivers/mfd/menelaus.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++---
> 
> <snip>
> 
> > +	irq_domain_add_legacy(node, MENELAUS_NR_IRQS, irq_base, 0,
> > +			&irq_domain_simple_ops, m);
> 
> When will this driver become DT compliant?

when OMAP2 becomes DT-compliant. It still boots with legacy board-file +
platform_data.

> > +	m->irq_base = irq_base;
> > +
> > +	for (i = irq_base; i < irq_base + MENELAUS_NR_IRQS; i++) {
> > +		irq_set_chip_data(i, m);
> > +		irq_set_chip_and_handler(i, &menelaus_irq_chip,
> > +				handle_simple_irq);
> > +		irq_set_nested_thread(i, 1);
> > +		set_irq_flags(i, IRQF_VALID);
> 
> This assumes that this h/w only exists on ARM platforms. Is that true?

it was made *only* for Nokia to use on their ARM-only internet tablets.

-- 
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/20131210/7980652b/attachment.sig>

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

* [PATCH v3 15/15] mfd: menelaus: Use devm_request_threaded_irq()
  2013-12-10  9:30             ` Lee Jones
@ 2013-12-10 16:34               ` Felipe Balbi
  2013-12-10 18:32                 ` Lee Jones
  0 siblings, 1 reply; 73+ messages in thread
From: Felipe Balbi @ 2013-12-10 16:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Dec 10, 2013 at 09:30:42AM +0000, Lee Jones wrote:
> On Mon, 09 Dec 2013, Felipe Balbi wrote:
> 
> > By using devm_request_threaded_irq() we can drop a few extra lines of
> > code and rely on device managed resources layer to free our IRQ for us.
> > 
> > Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> > Signed-off-by: Felipe Balbi <balbi@ti.com>
> > ---
> >  drivers/mfd/menelaus.c | 11 ++++-------
> >  1 file changed, 4 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
> > index bffe978..b87c2bd 100644
> > --- a/drivers/mfd/menelaus.c
> > +++ b/drivers/mfd/menelaus.c
> > @@ -1271,8 +1271,8 @@ static int menelaus_probe(struct i2c_client *client,
> >  	/* Set output buffer strengths */
> >  	menelaus_write_reg(m, MENELAUS_MCT_CTRL1, 0x73);
> >  
> > -	err = request_threaded_irq(client->irq, NULL, menelaus_irq,
> > -			IRQF_ONESHOT, DRIVER_NAME, m);
> > +	err = devm_request_threaded_irq(&client->dev, client->irq,
> > +			NULL, menelaus_irq, IRQF_ONESHOT, DRIVER_NAME, m);
> 
> No need for a separate patch here. Convert straight from request_irq()
> to devm_request_threaded_irq() in patch 3.

that would be 2 changes in a single patch.

-- 
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/20131210/97329829/attachment-0001.sig>

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

* [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation
  2013-12-10  8:50         ` [PATCH v2 " Lee Jones
@ 2013-12-10 16:36           ` Felipe Balbi
  0 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-10 16:36 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Tue, Dec 10, 2013 at 08:50:07AM +0000, Lee Jones wrote:
> > > > > The code looks mostly fine, but the implementation of the commit logs
> > > > > seems lazy. Please submit a v3 using coherent sentences with full
> > > > > explanations and correct punctuation.
> > > > 
> > > > example ?
> > > 
> > > All of your commit messages.
> > > 
> > > > that macro just helps removing some extra
> > > 
> > >   ^- Sentences start with an uppercase character.
> > > 
> > > > line of code and hides ffs() calls.
> > > > 
> > > > while at that, also fix a variable shadowing
> > > 
> > >   ^- Sentences start with an uppercase character.
> > > 
> > > > bug where 'int irq' was being redeclared inside
> > > > inner loop while it was also argument to interrupt
> > > > handler.
> > > 
> > >   < ---------------   50 chars   ----------------- >
> > > 
> > > Please use the full 72 char (or there abouts) width of the buffer.
> > 
> > I don't see any mention of punctuation problems, however. Also, you're
> > not complaining about the content at all, which tells me those sentences
> > aren't as incoherent as you claimed before.
> 
> I didn't read them in any detail. I traversed through the patches and

so you gave review comments without actually reviewing ? how rude...

> saw that the formatting looked obscure on all of them. As I have come
> to expect more of your submissions, I provided a generic reply
> detailing how I expected the commit logs to be. I wasn't insinuated
> that you failed to meet all of the criteria, but they definitely fell
> short of the mark.

in what way ?

-- 
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/20131210/79c22df9/attachment.sig>

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

* [PATCH v3 15/15] mfd: menelaus: Use devm_request_threaded_irq()
  2013-12-10 16:34               ` Felipe Balbi
@ 2013-12-10 18:32                 ` Lee Jones
  0 siblings, 0 replies; 73+ messages in thread
From: Lee Jones @ 2013-12-10 18:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 10 Dec 2013, Felipe Balbi wrote:

> On Tue, Dec 10, 2013 at 09:30:42AM +0000, Lee Jones wrote:
> > On Mon, 09 Dec 2013, Felipe Balbi wrote:
> > 
> > > By using devm_request_threaded_irq() we can drop a few extra lines of
> > > code and rely on device managed resources layer to free our IRQ for us.
> > > 
> > > Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> > > Signed-off-by: Felipe Balbi <balbi@ti.com>
> > > ---
> > >  drivers/mfd/menelaus.c | 11 ++++-------
> > >  1 file changed, 4 insertions(+), 7 deletions(-)
> > > 
> > > diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
> > > index bffe978..b87c2bd 100644
> > > --- a/drivers/mfd/menelaus.c
> > > +++ b/drivers/mfd/menelaus.c
> > > @@ -1271,8 +1271,8 @@ static int menelaus_probe(struct i2c_client *client,
> > >  	/* Set output buffer strengths */
> > >  	menelaus_write_reg(m, MENELAUS_MCT_CTRL1, 0x73);
> > >  
> > > -	err = request_threaded_irq(client->irq, NULL, menelaus_irq,
> > > -			IRQF_ONESHOT, DRIVER_NAME, m);
> > > +	err = devm_request_threaded_irq(&client->dev, client->irq,
> > > +			NULL, menelaus_irq, IRQF_ONESHOT, DRIVER_NAME, m);
> > 
> > No need for a separate patch here. Convert straight from request_irq()
> > to devm_request_threaded_irq() in patch 3.
> 
> that would be 2 changes in a single patch.

I think it's the right thing to do.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* [PATCH v3 11/15] mfd: menelaus: Start to use irqdomain
  2013-12-10 16:34               ` Felipe Balbi
@ 2013-12-10 18:37                 ` Lee Jones
  2013-12-10 18:46                   ` Tony Lindgren
  0 siblings, 1 reply; 73+ messages in thread
From: Lee Jones @ 2013-12-10 18:37 UTC (permalink / raw)
  To: linux-arm-kernel

> > > Introduce an irq_chip and irq_domain for menelaus driver. Following
> > > patches will convert uses to traditional request_threaded_irq().
> > > 
> > > While at that, some better error handling had to be added, so we could
> > > free irq descs we allocated.
> > > 
> > > Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> > > Signed-off-by: Felipe Balbi <balbi@ti.com>
> > > ---
> > >  drivers/mfd/menelaus.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++---
> > 
> > <snip>
> > 
> > > +	irq_domain_add_legacy(node, MENELAUS_NR_IRQS, irq_base, 0,
> > > +			&irq_domain_simple_ops, m);
> > 
> > When will this driver become DT compliant?
> 
> when OMAP2 becomes DT-compliant. It still boots with legacy board-file +
> platform_data.

Really? Tony, are there any plans to DT the platform?

Felipe, what did you think about using irq_domain_add_simple()?

> > > +	m->irq_base = irq_base;
> > > +
> > > +	for (i = irq_base; i < irq_base + MENELAUS_NR_IRQS; i++) {
> > > +		irq_set_chip_data(i, m);
> > > +		irq_set_chip_and_handler(i, &menelaus_irq_chip,
> > > +				handle_simple_irq);
> > > +		irq_set_nested_thread(i, 1);
> > > +		set_irq_flags(i, IRQF_VALID);
> > 
> > This assumes that this h/w only exists on ARM platforms. Is that true?
> 
> it was made *only* for Nokia to use on their ARM-only internet tablets.

If the IP is genuinely not reusable, them I'm fine with it.

I see that the Kconfig is setup in the correct way too, so we're good.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* [PATCH v3 08/15] mfd: menelaus: Pass menelaus_chip pointer to add/remove irq functions
  2013-12-10 16:32               ` Felipe Balbi
@ 2013-12-10 18:42                 ` Lee Jones
  0 siblings, 0 replies; 73+ messages in thread
From: Lee Jones @ 2013-12-10 18:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 10 Dec 2013, Felipe Balbi wrote:

> On Tue, Dec 10, 2013 at 09:00:21AM +0000, Lee Jones wrote:
> > On Mon, 09 Dec 2013, Felipe Balbi wrote:
> > 
> > > Those functions are static and can receive a menelaus_chip pointer very
> > > easily.
> > > 
> > > Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> > > Signed-off-by: Felipe Balbi <balbi@ti.com>
> > > ---
> > >  drivers/mfd/menelaus.c | 57 ++++++++++++++++++++++++++------------------------
> > >  1 file changed, 30 insertions(+), 27 deletions(-)
> > 
> > Same here. I think this should be done in one fell swoop.
> 
> then it would become a much, much larger patch which would become a pain
> to review.

If the patch was doing lots of different things then I'd be inclined
to agree, but although large, the changes here are pretty trivial.

I tend to break up patches based on; subsystem, file, device (for
platform/dts adaptions) and functionality. Rather than just because
the 'lines changed' count is large.

Please squash them and I'll review it.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* [PATCH v3 11/15] mfd: menelaus: Start to use irqdomain
  2013-12-10 18:37                 ` Lee Jones
@ 2013-12-10 18:46                   ` Tony Lindgren
  2013-12-11  9:06                     ` Lee Jones
  0 siblings, 1 reply; 73+ messages in thread
From: Tony Lindgren @ 2013-12-10 18:46 UTC (permalink / raw)
  To: linux-arm-kernel

* Lee Jones <lee.jones@linaro.org> [131210 10:39]:
> > > > Introduce an irq_chip and irq_domain for menelaus driver. Following
> > > > patches will convert uses to traditional request_threaded_irq().
> > > > 
> > > > While at that, some better error handling had to be added, so we could
> > > > free irq descs we allocated.
> > > > 
> > > > Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> > > > Signed-off-by: Felipe Balbi <balbi@ti.com>
> > > > ---
> > > >  drivers/mfd/menelaus.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++---
> > > 
> > > <snip>
> > > 
> > > > +	irq_domain_add_legacy(node, MENELAUS_NR_IRQS, irq_base, 0,
> > > > +			&irq_domain_simple_ops, m);
> > > 
> > > When will this driver become DT compliant?
> > 
> > when OMAP2 becomes DT-compliant. It still boots with legacy board-file +
> > platform_data.
> 
> Really? Tony, are there any plans to DT the platform?

Yeah and what Felipe is doing here is an important step towards that.
We'll be booting omap2 in DT only mode with v3.14, but we still need
to rely on some pdata quirks at least for the MMC because Menelaus
does not provide the needed regulator phandles for the .dts files for
the driver to use.

Regards,

Tony

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

* [PATCH v3 11/15] mfd: menelaus: Start to use irqdomain
  2013-12-10 18:46                   ` Tony Lindgren
@ 2013-12-11  9:06                     ` Lee Jones
  0 siblings, 0 replies; 73+ messages in thread
From: Lee Jones @ 2013-12-11  9:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 10 Dec 2013, Tony Lindgren wrote:

> * Lee Jones <lee.jones@linaro.org> [131210 10:39]:
> > > > > Introduce an irq_chip and irq_domain for menelaus driver. Following
> > > > > patches will convert uses to traditional request_threaded_irq().
> > > > > 
> > > > > While at that, some better error handling had to be added, so we could
> > > > > free irq descs we allocated.
> > > > > 
> > > > > Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> > > > > Signed-off-by: Felipe Balbi <balbi@ti.com>
> > > > > ---
> > > > >  drivers/mfd/menelaus.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++---
> > > > 
> > > > <snip>
> > > > 
> > > > > +	irq_domain_add_legacy(node, MENELAUS_NR_IRQS, irq_base, 0,
> > > > > +			&irq_domain_simple_ops, m);
> > > > 
> > > > When will this driver become DT compliant?
> > > 
> > > when OMAP2 becomes DT-compliant. It still boots with legacy board-file +
> > > platform_data.
> > 
> > Really? Tony, are there any plans to DT the platform?
> 
> Yeah and what Felipe is doing here is an important step towards that.
> We'll be booting omap2 in DT only mode with v3.14

Okay, sounds good. Thanks for the clarification.

> but we still need
> to rely on some pdata quirks at least for the MMC because Menelaus
> does not provide the needed regulator phandles for the .dts files for
> the driver to use.

I'll take your word for it. :)

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* [PATCH v3 07/15] mfd: menelaus: Limit the usage of the_menelaus
  2013-12-10 16:32               ` Felipe Balbi
@ 2013-12-11  9:17                 ` Lee Jones
  0 siblings, 0 replies; 73+ messages in thread
From: Lee Jones @ 2013-12-11  9:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 10 Dec 2013, Felipe Balbi wrote:

> On Tue, Dec 10, 2013 at 08:57:01AM +0000, Lee Jones wrote:
> > > Pass a menelaus_chip pointer as argument to most functions so we can
> > > minimize the usage of the global the_menelaus pointer.
> > > 
> > > Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> > > Signed-off-by: Felipe Balbi <balbi@ti.com>
> > > ---
> > >  drivers/mfd/menelaus.c | 265 ++++++++++++++++++++++++++-----------------------
> > >  1 file changed, 142 insertions(+), 123 deletions(-)
> > 
> > How is this different from patch 6?
> 
> have you read the patch ? patch 6 converts *only* enable/disable irq
> functions.

Well it actually converts menelaus_ack_irq() too, but that's not the
point I was making.

I can see that the 'code' is different, but the functionality of the
patch is the same i.e. converting functions to pass around the
menelaus_chip pointer for eradication of the_menelaus global pointer.

I'm not concerned about the 'lines changed' count. The change your
making is trivial, thus there is no requirement to split unnecessarily
over 5 patches. Please squash them into a single functionality patch.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation
  2013-12-03  3:42 [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Felipe Balbi
                   ` (15 preceding siblings ...)
  2013-12-06 13:41 ` Aaro Koskinen
@ 2013-12-11  9:44 ` Uwe Kleine-König
  2013-12-16 15:39 ` Lee Jones
  17 siblings, 0 replies; 73+ messages in thread
From: Uwe Kleine-König @ 2013-12-11  9:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Dec 02, 2013 at 09:42:54PM -0600, Felipe Balbi wrote:
> we could build that as a driver.
What is "that". How can it not be a driver? Do you mean modular? In that
case there is no problem, the only thing that doesn't work is unloading
the module.

Best regards
Uwe
 
> Signed-off-by: Felipe Balbi <balbi@ti.com>
> ---
>  drivers/mfd/menelaus.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
> index ad25bfa..975ff9e 100644
> --- a/drivers/mfd/menelaus.c
> +++ b/drivers/mfd/menelaus.c
> @@ -1262,7 +1262,7 @@ fail:
>  	return err;
>  }
>  
> -static int __exit menelaus_remove(struct i2c_client *client)
> +static int menelaus_remove(struct i2c_client *client)
>  {
>  	struct menelaus_chip	*menelaus = i2c_get_clientdata(client);
>  
> @@ -1283,7 +1283,7 @@ static struct i2c_driver menelaus_i2c_driver = {
>  		.name		= DRIVER_NAME,
>  	},
>  	.probe		= menelaus_probe,
> -	.remove		= __exit_p(menelaus_remove),
> +	.remove		= menelaus_remove,
>  	.id_table	= menelaus_id,
>  };
>  

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH v3 01/15] mfd: menelaus: Drop __exit section annotation
  2013-12-09 16:21         ` [PATCH v3 " Felipe Balbi
                             ` (13 preceding siblings ...)
  2013-12-09 16:21           ` [PATCH v3 15/15] mfd: menelaus: Use devm_request_threaded_irq() Felipe Balbi
@ 2013-12-11  9:48           ` Uwe Kleine-König
  14 siblings, 0 replies; 73+ messages in thread
From: Uwe Kleine-König @ 2013-12-11  9:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Dec 09, 2013 at 10:21:11AM -0600, Felipe Balbi wrote:
> We could build that driver as a dynamically-linked module.
ups, only saw now the v3 after I commented on v2. So you addressed a
part of my comment already. Still building that driver as a module also
works without this patch, right? So this is only about hotplugging
(which usually doesn't work on i2c, so only via /sys/bus/i2c) and driver
unloading.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation
  2013-12-03  3:42 [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Felipe Balbi
                   ` (16 preceding siblings ...)
  2013-12-11  9:44 ` Uwe Kleine-König
@ 2013-12-16 15:39 ` Lee Jones
  2013-12-17  0:08   ` [PATCH 01/10] " Felipe Balbi
  17 siblings, 1 reply; 73+ messages in thread
From: Lee Jones @ 2013-12-16 15:39 UTC (permalink / raw)
  To: linux-arm-kernel

Are you planning on re-submitting this patch-set anytime soon?

I thought Tony said it was important?

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* [PATCH 01/10] mfd: menelaus: Drop __exit section annotation
  2013-12-16 15:39 ` Lee Jones
@ 2013-12-17  0:08   ` Felipe Balbi
  2013-12-17  0:08     ` [PATCH 02/10] mfd: menelaus: Switch over to module_i2c_driver Felipe Balbi
                       ` (8 more replies)
  0 siblings, 9 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-17  0:08 UTC (permalink / raw)
  To: linux-arm-kernel

We could build that driver as a dynamically-linked module.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index ad25bfa..975ff9e 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -1262,7 +1262,7 @@ fail:
 	return err;
 }
 
-static int __exit menelaus_remove(struct i2c_client *client)
+static int menelaus_remove(struct i2c_client *client)
 {
 	struct menelaus_chip	*menelaus = i2c_get_clientdata(client);
 
@@ -1283,7 +1283,7 @@ static struct i2c_driver menelaus_i2c_driver = {
 		.name		= DRIVER_NAME,
 	},
 	.probe		= menelaus_probe,
-	.remove		= __exit_p(menelaus_remove),
+	.remove		= menelaus_remove,
 	.id_table	= menelaus_id,
 };
 
-- 
1.8.4.GIT

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

* [PATCH 02/10] mfd: menelaus: Switch over to module_i2c_driver
  2013-12-17  0:08   ` [PATCH 01/10] " Felipe Balbi
@ 2013-12-17  0:08     ` Felipe Balbi
  2013-12-17  0:08     ` [PATCH 03/10] mfd: menelaus: Convert to threaded irq Felipe Balbi
                       ` (7 subsequent siblings)
  8 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-17  0:08 UTC (permalink / raw)
  To: linux-arm-kernel

Just a macro to remove some boilerplate code, no functional changes.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 23 +----------------------
 1 file changed, 1 insertion(+), 22 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 975ff9e..8bd97ca 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -1287,29 +1287,8 @@ static struct i2c_driver menelaus_i2c_driver = {
 	.id_table	= menelaus_id,
 };
 
-static int __init menelaus_init(void)
-{
-	int res;
-
-	res = i2c_add_driver(&menelaus_i2c_driver);
-	if (res < 0) {
-		pr_err(DRIVER_NAME ": driver registration failed\n");
-		return res;
-	}
-
-	return 0;
-}
-
-static void __exit menelaus_exit(void)
-{
-	i2c_del_driver(&menelaus_i2c_driver);
-
-	/* FIXME: Shutdown menelaus parts that can be shut down */
-}
+module_i2c_driver(menelaus_i2c_driver);
 
 MODULE_AUTHOR("Texas Instruments, Inc. (and others)");
 MODULE_DESCRIPTION("I2C interface for Menelaus.");
 MODULE_LICENSE("GPL");
-
-module_init(menelaus_init);
-module_exit(menelaus_exit);
-- 
1.8.4.GIT

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

* [PATCH 03/10] mfd: menelaus: Convert to threaded irq
  2013-12-17  0:08   ` [PATCH 01/10] " Felipe Balbi
  2013-12-17  0:08     ` [PATCH 02/10] mfd: menelaus: Switch over to module_i2c_driver Felipe Balbi
@ 2013-12-17  0:08     ` Felipe Balbi
  2013-12-17  0:08     ` [PATCH 04/10] mfd: menelaus: Remove unnecessary loop Felipe Balbi
                       ` (6 subsequent siblings)
  8 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-17  0:08 UTC (permalink / raw)
  To: linux-arm-kernel

We don't need that extra workqueue when we have generic threaded irq
handlers support. This patch just moves over to threaded irqs and
deletes the unnecessary workqueue.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 34 +++++-----------------------------
 1 file changed, 5 insertions(+), 29 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 8bd97ca..268e39c 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -36,7 +36,6 @@
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/mutex.h>
-#include <linux/workqueue.h>
 #include <linux/delay.h>
 #include <linux/rtc.h>
 #include <linux/bcd.h>
@@ -161,12 +160,9 @@
 #define MCT_PIN_ST_S1_CD_ST		(1 << 0)
 #define MCT_PIN_ST_S2_CD_ST		(1 << 1)
 
-static void menelaus_work(struct work_struct *_menelaus);
-
 struct menelaus_chip {
 	struct mutex		lock;
 	struct i2c_client	*client;
-	struct work_struct	work;
 #ifdef CONFIG_RTC_DRV_TWL92330
 	struct rtc_device	*rtc;
 	u8			rtc_control;
@@ -795,11 +791,9 @@ out:
 
 /*-----------------------------------------------------------------------*/
 
-/* Handles Menelaus interrupts. Does not run in interrupt context */
-static void menelaus_work(struct work_struct *_menelaus)
+static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 {
-	struct menelaus_chip *menelaus =
-			container_of(_menelaus, struct menelaus_chip, work);
+	struct menelaus_chip *menelaus = _menelaus;
 	void (*handler)(struct menelaus_chip *menelaus);
 
 	while (1) {
@@ -826,18 +820,6 @@ static void menelaus_work(struct work_struct *_menelaus)
 			mutex_unlock(&menelaus->lock);
 		}
 	}
-	enable_irq(menelaus->client->irq);
-}
-
-/*
- * We cannot use I2C in interrupt context, so we just schedule work.
- */
-static irqreturn_t menelaus_irq(int irq, void *_menelaus)
-{
-	struct menelaus_chip *menelaus = _menelaus;
-
-	disable_irq_nosync(irq);
-	(void)schedule_work(&menelaus->work);
 
 	return IRQ_HANDLED;
 }
@@ -1225,8 +1207,9 @@ static int menelaus_probe(struct i2c_client *client,
 	menelaus_write_reg(MENELAUS_MCT_CTRL1, 0x73);
 
 	if (client->irq > 0) {
-		err = request_irq(client->irq, menelaus_irq, 0,
-				  DRIVER_NAME, menelaus);
+		err = devm_request_threaded_irq(&client->dev, client->irq, NULL,
+				menelaus_irq, IRQF_ONESHOT, DRIVER_NAME,
+				menelaus);
 		if (err) {
 			dev_dbg(&client->dev,  "can't get IRQ %d, err %d\n",
 					client->irq, err);
@@ -1235,7 +1218,6 @@ static int menelaus_probe(struct i2c_client *client,
 	}
 
 	mutex_init(&menelaus->lock);
-	INIT_WORK(&menelaus->work, menelaus_work);
 
 	pr_info("Menelaus rev %d.%d\n", rev >> 4, rev & 0x0f);
 
@@ -1257,17 +1239,11 @@ static int menelaus_probe(struct i2c_client *client,
 
 	return 0;
 fail:
-	free_irq(client->irq, menelaus);
-	flush_work(&menelaus->work);
 	return err;
 }
 
 static int menelaus_remove(struct i2c_client *client)
 {
-	struct menelaus_chip	*menelaus = i2c_get_clientdata(client);
-
-	free_irq(client->irq, menelaus);
-	flush_work(&menelaus->work);
 	the_menelaus = NULL;
 	return 0;
 }
-- 
1.8.4.GIT

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

* [PATCH 04/10] mfd: menelaus: Remove unnecessary loop
  2013-12-17  0:08   ` [PATCH 01/10] " Felipe Balbi
  2013-12-17  0:08     ` [PATCH 02/10] mfd: menelaus: Switch over to module_i2c_driver Felipe Balbi
  2013-12-17  0:08     ` [PATCH 03/10] mfd: menelaus: Convert to threaded irq Felipe Balbi
@ 2013-12-17  0:08     ` Felipe Balbi
  2013-12-17  0:08     ` [PATCH 05/10] mfd: menelaus: Use for_each_set_bit() Felipe Balbi
                       ` (5 subsequent siblings)
  8 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-17  0:08 UTC (permalink / raw)
  To: linux-arm-kernel

We can let irqs refire and give the scheduler a chance to choose when we
should be scheduled.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 43 +++++++++++++++++++------------------------
 1 file changed, 19 insertions(+), 24 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 268e39c..87d80a8 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -795,30 +795,25 @@ static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 {
 	struct menelaus_chip *menelaus = _menelaus;
 	void (*handler)(struct menelaus_chip *menelaus);
-
-	while (1) {
-		unsigned isr;
-
-		isr = (menelaus_read_reg(MENELAUS_INT_STATUS2)
-				& ~menelaus->mask2) << 8;
-		isr |= menelaus_read_reg(MENELAUS_INT_STATUS1)
-				& ~menelaus->mask1;
-		if (!isr)
-			break;
-
-		while (isr) {
-			int irq = fls(isr) - 1;
-			isr &= ~(1 << irq);
-
-			mutex_lock(&menelaus->lock);
-			menelaus_disable_irq(irq);
-			menelaus_ack_irq(irq);
-			handler = menelaus->handlers[irq];
-			if (handler)
-				handler(menelaus);
-			menelaus_enable_irq(irq);
-			mutex_unlock(&menelaus->lock);
-		}
+	unsigned isr;
+
+	isr = (menelaus_read_reg(MENELAUS_INT_STATUS2)
+			& ~menelaus->mask2) << 8;
+	isr |= menelaus_read_reg(MENELAUS_INT_STATUS1)
+		& ~menelaus->mask1;
+
+	while (isr) {
+		int irq = fls(isr) - 1;
+		isr &= ~(1 << irq);
+
+		mutex_lock(&menelaus->lock);
+		menelaus_disable_irq(irq);
+		menelaus_ack_irq(irq);
+		handler = menelaus->handlers[irq];
+		if (handler)
+			handler(menelaus);
+		menelaus_enable_irq(irq);
+		mutex_unlock(&menelaus->lock);
 	}
 
 	return IRQ_HANDLED;
-- 
1.8.4.GIT

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

* [PATCH 05/10] mfd: menelaus: Use for_each_set_bit()
  2013-12-17  0:08   ` [PATCH 01/10] " Felipe Balbi
                       ` (2 preceding siblings ...)
  2013-12-17  0:08     ` [PATCH 04/10] mfd: menelaus: Remove unnecessary loop Felipe Balbi
@ 2013-12-17  0:08     ` Felipe Balbi
  2013-12-17  0:17       ` Joe Perches
  2013-12-17  0:08     ` [PATCH 06/10] mfd: menelaus: Limit the usage of the_menelaus Felipe Balbi
                       ` (4 subsequent siblings)
  8 siblings, 1 reply; 73+ messages in thread
From: Felipe Balbi @ 2013-12-17  0:08 UTC (permalink / raw)
  To: linux-arm-kernel

That macro just helps removing some extra line of code and hides ffs()
calls.

While at that, also fix a variable shadowing bug where 'int irq' was
being redeclared inside inner loop while it was also argument to
interrupt handler.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 87d80a8..d3e3022 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -795,24 +795,22 @@ static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 {
 	struct menelaus_chip *menelaus = _menelaus;
 	void (*handler)(struct menelaus_chip *menelaus);
-	unsigned isr;
+	unsigned long isr;
+	unsigned long i;
 
 	isr = (menelaus_read_reg(MENELAUS_INT_STATUS2)
 			& ~menelaus->mask2) << 8;
 	isr |= menelaus_read_reg(MENELAUS_INT_STATUS1)
 		& ~menelaus->mask1;
 
-	while (isr) {
-		int irq = fls(isr) - 1;
-		isr &= ~(1 << irq);
-
+	for_each_set_bit(i, &isr, 16) {
 		mutex_lock(&menelaus->lock);
-		menelaus_disable_irq(irq);
-		menelaus_ack_irq(irq);
-		handler = menelaus->handlers[irq];
+		menelaus_disable_irq(i);
+		menelaus_ack_irq(i);
+		handler = menelaus->handlers[i];
 		if (handler)
 			handler(menelaus);
-		menelaus_enable_irq(irq);
+		menelaus_enable_irq(i);
 		mutex_unlock(&menelaus->lock);
 	}
 
-- 
1.8.4.GIT

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

* [PATCH 06/10] mfd: menelaus: Limit the usage of the_menelaus
  2013-12-17  0:08   ` [PATCH 01/10] " Felipe Balbi
                       ` (3 preceding siblings ...)
  2013-12-17  0:08     ` [PATCH 05/10] mfd: menelaus: Use for_each_set_bit() Felipe Balbi
@ 2013-12-17  0:08     ` Felipe Balbi
  2013-12-17  0:08     ` [PATCH 07/10] mfd: menelaus: Start to use irqdomain Felipe Balbi
                       ` (3 subsequent siblings)
  8 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-17  0:08 UTC (permalink / raw)
  To: linux-arm-kernel

Pass a menelaus_chip pointer as argument to most functions so we can
minimize the usage of the global the_menelaus pointer. This will
help later getting of the_menelaus altogether.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 420 ++++++++++++++++++++++++++-----------------------
 1 file changed, 222 insertions(+), 198 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index d3e3022..ae3209d 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -177,9 +177,9 @@ struct menelaus_chip {
 
 static struct menelaus_chip *the_menelaus;
 
-static int menelaus_write_reg(int reg, u8 value)
+static int menelaus_write_reg(struct menelaus_chip *m, int reg, u8 value)
 {
-	int val = i2c_smbus_write_byte_data(the_menelaus->client, reg, value);
+	int val = i2c_smbus_write_byte_data(m->client, reg, value);
 
 	if (val < 0) {
 		pr_err(DRIVER_NAME ": write error");
@@ -189,9 +189,9 @@ static int menelaus_write_reg(int reg, u8 value)
 	return 0;
 }
 
-static int menelaus_read_reg(int reg)
+static int menelaus_read_reg(struct menelaus_chip *m, int reg)
 {
-	int val = i2c_smbus_read_byte_data(the_menelaus->client, reg);
+	int val = i2c_smbus_read_byte_data(m->client, reg);
 
 	if (val < 0)
 		pr_err(DRIVER_NAME ": read error");
@@ -199,65 +199,65 @@ static int menelaus_read_reg(int reg)
 	return val;
 }
 
-static int menelaus_enable_irq(int irq)
+static int menelaus_enable_irq(struct menelaus_chip *m, int irq)
 {
 	if (irq > 7) {
 		irq -= 8;
-		the_menelaus->mask2 &= ~(1 << irq);
-		return menelaus_write_reg(MENELAUS_INT_MASK2,
-				the_menelaus->mask2);
+		m->mask2 &= ~(1 << irq);
+		return menelaus_write_reg(m, MENELAUS_INT_MASK2,
+				m->mask2);
 	} else {
-		the_menelaus->mask1 &= ~(1 << irq);
-		return menelaus_write_reg(MENELAUS_INT_MASK1,
-				the_menelaus->mask1);
+		m->mask1 &= ~(1 << irq);
+		return menelaus_write_reg(m, MENELAUS_INT_MASK1,
+				m->mask1);
 	}
 }
 
-static int menelaus_disable_irq(int irq)
+static int menelaus_disable_irq(struct menelaus_chip *m, int irq)
 {
 	if (irq > 7) {
 		irq -= 8;
-		the_menelaus->mask2 |= (1 << irq);
-		return menelaus_write_reg(MENELAUS_INT_MASK2,
-				the_menelaus->mask2);
+		m->mask2 |= (1 << irq);
+		return menelaus_write_reg(m, MENELAUS_INT_MASK2,
+				m->mask2);
 	} else {
-		the_menelaus->mask1 |= (1 << irq);
-		return menelaus_write_reg(MENELAUS_INT_MASK1,
-				the_menelaus->mask1);
+		m->mask1 |= (1 << irq);
+		return menelaus_write_reg(m, MENELAUS_INT_MASK1,
+				m->mask1);
 	}
 }
 
-static int menelaus_ack_irq(int irq)
+static int menelaus_ack_irq(struct menelaus_chip *m, int irq)
 {
 	if (irq > 7)
-		return menelaus_write_reg(MENELAUS_INT_ACK2, 1 << (irq - 8));
+		return menelaus_write_reg(m, MENELAUS_INT_ACK2, 1 << (irq - 8));
 	else
-		return menelaus_write_reg(MENELAUS_INT_ACK1, 1 << irq);
+		return menelaus_write_reg(m, MENELAUS_INT_ACK1, 1 << irq);
 }
 
 /* Adds a handler for an interrupt. Does not run in interrupt context */
-static int menelaus_add_irq_work(int irq,
+static int menelaus_add_irq_work(struct menelaus_chip *m, int irq,
 		void (*handler)(struct menelaus_chip *))
 {
 	int ret = 0;
 
-	mutex_lock(&the_menelaus->lock);
-	the_menelaus->handlers[irq] = handler;
-	ret = menelaus_enable_irq(irq);
-	mutex_unlock(&the_menelaus->lock);
+	mutex_lock(&m->lock);
+	m->handlers[irq] = handler;
+	ret = menelaus_enable_irq(m, irq);
+	mutex_unlock(&m->lock);
 
 	return ret;
 }
 
 /* Removes handler for an interrupt */
-static int menelaus_remove_irq_work(int irq)
+static int menelaus_remove_irq_work(struct menelaus_chip *m, int irq)
 {
 	int ret = 0;
 
-	mutex_lock(&the_menelaus->lock);
-	ret = menelaus_disable_irq(irq);
-	the_menelaus->handlers[irq] = NULL;
-	mutex_unlock(&the_menelaus->lock);
+	mutex_lock(&m->lock);
+	ret = menelaus_disable_irq(m, irq);
+	m->handlers[irq] = NULL;
+	mutex_unlock(&m->lock);
 
 	return ret;
 }
@@ -268,12 +268,12 @@ static int menelaus_remove_irq_work(int irq)
  * in each slot. In this case the cards are not seen by menelaus.
  * FIXME: Add handling for D1 too
  */
-static void menelaus_mmc_cd_work(struct menelaus_chip *menelaus_hw)
+static void menelaus_mmc_cd_work(struct menelaus_chip *m)
 {
 	int reg;
 	unsigned char card_mask = 0;
 
-	reg = menelaus_read_reg(MENELAUS_MCT_PIN_ST);
+	reg = menelaus_read_reg(m, MENELAUS_MCT_PIN_ST);
 	if (reg < 0)
 		return;
 
@@ -283,8 +283,8 @@ static void menelaus_mmc_cd_work(struct menelaus_chip *menelaus_hw)
 	if (!(reg & 0x2))
 		card_mask |= MCT_PIN_ST_S2_CD_ST;
 
-	if (menelaus_hw->mmc_callback)
-		menelaus_hw->mmc_callback(menelaus_hw->mmc_callback_data,
+	if (m->mmc_callback)
+		m->mmc_callback(m->mmc_callback_data,
 					  card_mask);
 }
 
@@ -293,14 +293,16 @@ static void menelaus_mmc_cd_work(struct menelaus_chip *menelaus_hw)
  */
 int menelaus_set_mmc_opendrain(int slot, int enable)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int ret, val;
 
 	if (slot != 1 && slot != 2)
 		return -EINVAL;
-	mutex_lock(&the_menelaus->lock);
-	ret = menelaus_read_reg(MENELAUS_MCT_CTRL1);
+
+	mutex_lock(&m->lock);
+	ret = menelaus_read_reg(m, MENELAUS_MCT_CTRL1);
 	if (ret < 0) {
-		mutex_unlock(&the_menelaus->lock);
+		mutex_unlock(&m->lock);
 		return ret;
 	}
 	val = ret;
@@ -315,8 +317,8 @@ int menelaus_set_mmc_opendrain(int slot, int enable)
 		else
 			val &= ~MCT_CTRL1_S2_CMD_OD;
 	}
-	ret = menelaus_write_reg(MENELAUS_MCT_CTRL1, val);
-	mutex_unlock(&the_menelaus->lock);
+	ret = menelaus_write_reg(m, MENELAUS_MCT_CTRL1, val);
+	mutex_unlock(&m->lock);
 
 	return ret;
 }
@@ -324,10 +326,12 @@ EXPORT_SYMBOL(menelaus_set_mmc_opendrain);
 
 int menelaus_set_slot_sel(int enable)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int ret;
 
-	mutex_lock(&the_menelaus->lock);
-	ret = menelaus_read_reg(MENELAUS_GPIO_CTRL);
+	mutex_lock(&m->lock);
+
+	ret = menelaus_read_reg(m, MENELAUS_GPIO_CTRL);
 	if (ret < 0)
 		goto out;
 	ret |= GPIO2_DIR_INPUT;
@@ -335,15 +339,16 @@ int menelaus_set_slot_sel(int enable)
 		ret |= GPIO_CTRL_SLOTSELEN;
 	else
 		ret &= ~GPIO_CTRL_SLOTSELEN;
-	ret = menelaus_write_reg(MENELAUS_GPIO_CTRL, ret);
+	ret = menelaus_write_reg(m, MENELAUS_GPIO_CTRL, ret);
 out:
-	mutex_unlock(&the_menelaus->lock);
+	mutex_unlock(&m->lock);
 	return ret;
 }
 EXPORT_SYMBOL(menelaus_set_slot_sel);
 
 int menelaus_set_mmc_slot(int slot, int enable, int power, int cd_en)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int ret, val;
 
 	if (slot != 1 && slot != 2)
@@ -351,9 +356,9 @@ int menelaus_set_mmc_slot(int slot, int enable, int power, int cd_en)
 	if (power >= 3)
 		return -EINVAL;
 
-	mutex_lock(&the_menelaus->lock);
+	mutex_lock(&m->lock);
 
-	ret = menelaus_read_reg(MENELAUS_MCT_CTRL2);
+	ret = menelaus_read_reg(m, MENELAUS_MCT_CTRL2);
 	if (ret < 0)
 		goto out;
 	val = ret;
@@ -368,11 +373,11 @@ int menelaus_set_mmc_slot(int slot, int enable, int power, int cd_en)
 		else
 			val &= ~(MCT_CTRL2_S2CD_BUFEN | MCT_CTRL2_S2CD_BEN);
 	}
-	ret = menelaus_write_reg(MENELAUS_MCT_CTRL2, val);
+	ret = menelaus_write_reg(m, MENELAUS_MCT_CTRL2, val);
 	if (ret < 0)
 		goto out;
 
-	ret = menelaus_read_reg(MENELAUS_MCT_CTRL3);
+	ret = menelaus_read_reg(m, MENELAUS_MCT_CTRL3);
 	if (ret < 0)
 		goto out;
 	val = ret;
@@ -388,18 +393,18 @@ int menelaus_set_mmc_slot(int slot, int enable, int power, int cd_en)
 			val |= MCT_CTRL3_SLOT2_EN;
 		else
 			val &= ~MCT_CTRL3_SLOT2_EN;
-		b = menelaus_read_reg(MENELAUS_MCT_CTRL2);
+		b = menelaus_read_reg(m, MENELAUS_MCT_CTRL2);
 		b &= ~(MCT_CTRL2_VS2_SEL_D0 | MCT_CTRL2_VS2_SEL_D1);
 		b |= power;
-		ret = menelaus_write_reg(MENELAUS_MCT_CTRL2, b);
+		ret = menelaus_write_reg(m, MENELAUS_MCT_CTRL2, b);
 		if (ret < 0)
 			goto out;
 	}
 	/* Disable autonomous shutdown */
 	val &= ~(MCT_CTRL3_S1_AUTO_EN | MCT_CTRL3_S2_AUTO_EN);
-	ret = menelaus_write_reg(MENELAUS_MCT_CTRL3, val);
+	ret = menelaus_write_reg(m, MENELAUS_MCT_CTRL3, val);
 out:
-	mutex_unlock(&the_menelaus->lock);
+	mutex_unlock(&m->lock);
 	return ret;
 }
 EXPORT_SYMBOL(menelaus_set_mmc_slot);
@@ -407,23 +412,24 @@ EXPORT_SYMBOL(menelaus_set_mmc_slot);
 int menelaus_register_mmc_callback(void (*callback)(void *data, u8 card_mask),
 				   void *data)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int ret = 0;
 
-	the_menelaus->mmc_callback_data = data;
-	the_menelaus->mmc_callback = callback;
-	ret = menelaus_add_irq_work(MENELAUS_MMC_S1CD_IRQ,
+	m->mmc_callback_data = data;
+	m->mmc_callback = callback;
+	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S1CD_IRQ,
 				    menelaus_mmc_cd_work);
 	if (ret < 0)
 		return ret;
-	ret = menelaus_add_irq_work(MENELAUS_MMC_S2CD_IRQ,
+	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S2CD_IRQ,
 				    menelaus_mmc_cd_work);
 	if (ret < 0)
 		return ret;
-	ret = menelaus_add_irq_work(MENELAUS_MMC_S1D1_IRQ,
+	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S1D1_IRQ,
 				    menelaus_mmc_cd_work);
 	if (ret < 0)
 		return ret;
-	ret = menelaus_add_irq_work(MENELAUS_MMC_S2D1_IRQ,
+	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S2D1_IRQ,
 				    menelaus_mmc_cd_work);
 
 	return ret;
@@ -432,13 +438,15 @@ EXPORT_SYMBOL(menelaus_register_mmc_callback);
 
 void menelaus_unregister_mmc_callback(void)
 {
-	menelaus_remove_irq_work(MENELAUS_MMC_S1CD_IRQ);
-	menelaus_remove_irq_work(MENELAUS_MMC_S2CD_IRQ);
-	menelaus_remove_irq_work(MENELAUS_MMC_S1D1_IRQ);
-	menelaus_remove_irq_work(MENELAUS_MMC_S2D1_IRQ);
+	struct menelaus_chip *m = the_menelaus;
+
+	menelaus_remove_irq_work(m, MENELAUS_MMC_S1CD_IRQ);
+	menelaus_remove_irq_work(m, MENELAUS_MMC_S2CD_IRQ);
+	menelaus_remove_irq_work(m, MENELAUS_MMC_S1D1_IRQ);
+	menelaus_remove_irq_work(m, MENELAUS_MMC_S2D1_IRQ);
 
-	the_menelaus->mmc_callback = NULL;
-	the_menelaus->mmc_callback_data = NULL;
+	m->mmc_callback = NULL;
+	m->mmc_callback_data = NULL;
 }
 EXPORT_SYMBOL(menelaus_unregister_mmc_callback);
 
@@ -455,17 +463,17 @@ struct menelaus_vtg_value {
 	u16 val;
 };
 
-static int menelaus_set_voltage(const struct menelaus_vtg *vtg, int mV,
-				int vtg_val, int mode)
+static int menelaus_set_voltage(struct menelaus_chip *m,
+		const struct menelaus_vtg *vtg, int mV, int vtg_val, int mode)
 {
+	struct i2c_client *c = m->client;
 	int val, ret;
-	struct i2c_client *c = the_menelaus->client;
 
-	mutex_lock(&the_menelaus->lock);
+	mutex_lock(&m->lock);
 	if (!vtg)
 		goto set_voltage;
 
-	ret = menelaus_read_reg(vtg->vtg_reg);
+	ret = menelaus_read_reg(m, vtg->vtg_reg);
 	if (ret < 0)
 		goto out;
 	val = ret & ~(((1 << vtg->vtg_bits) - 1) << vtg->vtg_shift);
@@ -475,13 +483,13 @@ static int menelaus_set_voltage(const struct menelaus_vtg *vtg, int mV,
 			 "to %d mV (reg 0x%02x, val 0x%02x)\n",
 			vtg->name, mV, vtg->vtg_reg, val);
 
-	ret = menelaus_write_reg(vtg->vtg_reg, val);
+	ret = menelaus_write_reg(m, vtg->vtg_reg, val);
 	if (ret < 0)
 		goto out;
 set_voltage:
-	ret = menelaus_write_reg(vtg->mode_reg, mode);
+	ret = menelaus_write_reg(m, vtg->mode_reg, mode);
 out:
-	mutex_unlock(&the_menelaus->lock);
+	mutex_unlock(&m->lock);
 	if (ret == 0) {
 		/* Wait for voltage to stabilize */
 		msleep(1);
@@ -489,8 +497,8 @@ out:
 	return ret;
 }
 
-static int menelaus_get_vtg_value(int vtg, const struct menelaus_vtg_value *tbl,
-				  int n)
+static int menelaus_get_vtg_value(struct menelaus_chip *m,
+		int vtg, const struct menelaus_vtg_value *tbl, int n)
 {
 	int i;
 
@@ -533,10 +541,11 @@ static const struct menelaus_vtg_value vcore_values[] = {
 
 int menelaus_set_vcore_sw(unsigned int mV)
 {
+	struct menelaus_chip *m = the_menelaus;
+	struct i2c_client *c = m->client;
 	int val, ret;
-	struct i2c_client *c = the_menelaus->client;
 
-	val = menelaus_get_vtg_value(mV, vcore_values,
+	val = menelaus_get_vtg_value(m, mV, vcore_values,
 				     ARRAY_SIZE(vcore_values));
 	if (val < 0)
 		return -EINVAL;
@@ -544,11 +553,11 @@ int menelaus_set_vcore_sw(unsigned int mV)
 	dev_dbg(&c->dev, "Setting VCORE to %d mV (val 0x%02x)\n", mV, val);
 
 	/* Set SW mode and the voltage in one go. */
-	mutex_lock(&the_menelaus->lock);
-	ret = menelaus_write_reg(MENELAUS_VCORE_CTRL1, val);
+	mutex_lock(&m->lock);
+	ret = menelaus_write_reg(m, MENELAUS_VCORE_CTRL1, val);
 	if (ret == 0)
-		the_menelaus->vcore_hw_mode = 0;
-	mutex_unlock(&the_menelaus->lock);
+		m->vcore_hw_mode = 0;
+	mutex_unlock(&m->lock);
 	msleep(1);
 
 	return ret;
@@ -556,14 +565,15 @@ int menelaus_set_vcore_sw(unsigned int mV)
 
 int menelaus_set_vcore_hw(unsigned int roof_mV, unsigned int floor_mV)
 {
+	struct menelaus_chip *m = the_menelaus;
+	struct i2c_client *c = m->client;
 	int fval, rval, val, ret;
-	struct i2c_client *c = the_menelaus->client;
 
-	rval = menelaus_get_vtg_value(roof_mV, vcore_values,
+	rval = menelaus_get_vtg_value(m, roof_mV, vcore_values,
 				      ARRAY_SIZE(vcore_values));
 	if (rval < 0)
 		return -EINVAL;
-	fval = menelaus_get_vtg_value(floor_mV, vcore_values,
+	fval = menelaus_get_vtg_value(m, floor_mV, vcore_values,
 				      ARRAY_SIZE(vcore_values));
 	if (fval < 0)
 		return -EINVAL;
@@ -571,23 +581,23 @@ int menelaus_set_vcore_hw(unsigned int roof_mV, unsigned int floor_mV)
 	dev_dbg(&c->dev, "Setting VCORE FLOOR to %d mV and ROOF to %d mV\n",
 	       floor_mV, roof_mV);
 
-	mutex_lock(&the_menelaus->lock);
-	ret = menelaus_write_reg(MENELAUS_VCORE_CTRL3, fval);
+	mutex_lock(&m->lock);
+	ret = menelaus_write_reg(m, MENELAUS_VCORE_CTRL3, fval);
 	if (ret < 0)
 		goto out;
-	ret = menelaus_write_reg(MENELAUS_VCORE_CTRL4, rval);
+	ret = menelaus_write_reg(m, MENELAUS_VCORE_CTRL4, rval);
 	if (ret < 0)
 		goto out;
-	if (!the_menelaus->vcore_hw_mode) {
-		val = menelaus_read_reg(MENELAUS_VCORE_CTRL1);
+	if (!m->vcore_hw_mode) {
+		val = menelaus_read_reg(m, MENELAUS_VCORE_CTRL1);
 		/* HW mode, turn OFF byte comparator */
 		val |= (VCORE_CTRL1_HW_NSW | VCORE_CTRL1_BYP_COMP);
-		ret = menelaus_write_reg(MENELAUS_VCORE_CTRL1, val);
-		the_menelaus->vcore_hw_mode = 1;
+		ret = menelaus_write_reg(m, MENELAUS_VCORE_CTRL1, val);
+		m->vcore_hw_mode = 1;
 	}
 	msleep(1);
 out:
-	mutex_unlock(&the_menelaus->lock);
+	mutex_unlock(&m->lock);
 	return ret;
 }
 
@@ -608,15 +618,16 @@ static const struct menelaus_vtg_value vmem_values[] = {
 
 int menelaus_set_vmem(unsigned int mV)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int val;
 
 	if (mV == 0)
-		return menelaus_set_voltage(&vmem_vtg, 0, 0, 0);
+		return menelaus_set_voltage(m, &vmem_vtg, 0, 0, 0);
 
-	val = menelaus_get_vtg_value(mV, vmem_values, ARRAY_SIZE(vmem_values));
+	val = menelaus_get_vtg_value(m, mV, vmem_values, ARRAY_SIZE(vmem_values));
 	if (val < 0)
 		return -EINVAL;
-	return menelaus_set_voltage(&vmem_vtg, mV, val, 0x02);
+	return menelaus_set_voltage(m, &vmem_vtg, mV, val, 0x02);
 }
 EXPORT_SYMBOL(menelaus_set_vmem);
 
@@ -637,15 +648,16 @@ static const struct menelaus_vtg_value vio_values[] = {
 
 int menelaus_set_vio(unsigned int mV)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int val;
 
 	if (mV == 0)
-		return menelaus_set_voltage(&vio_vtg, 0, 0, 0);
+		return menelaus_set_voltage(m, &vio_vtg, 0, 0, 0);
 
-	val = menelaus_get_vtg_value(mV, vio_values, ARRAY_SIZE(vio_values));
+	val = menelaus_get_vtg_value(m, mV, vio_values, ARRAY_SIZE(vio_values));
 	if (val < 0)
 		return -EINVAL;
-	return menelaus_set_voltage(&vio_vtg, mV, val, 0x02);
+	return menelaus_set_voltage(m, &vio_vtg, mV, val, 0x02);
 }
 EXPORT_SYMBOL(menelaus_set_vio);
 
@@ -678,6 +690,7 @@ static const struct menelaus_vtg vdcdc3_vtg = {
 
 int menelaus_set_vdcdc(int dcdc, unsigned int mV)
 {
+	struct menelaus_chip *m = the_menelaus;
 	const struct menelaus_vtg *vtg;
 	int val;
 
@@ -689,13 +702,13 @@ int menelaus_set_vdcdc(int dcdc, unsigned int mV)
 		vtg = &vdcdc3_vtg;
 
 	if (mV == 0)
-		return menelaus_set_voltage(vtg, 0, 0, 0);
+		return menelaus_set_voltage(m, vtg, 0, 0, 0);
 
-	val = menelaus_get_vtg_value(mV, vdcdc_values,
+	val = menelaus_get_vtg_value(m, mV, vdcdc_values,
 				     ARRAY_SIZE(vdcdc_values));
 	if (val < 0)
 		return -EINVAL;
-	return menelaus_set_voltage(vtg, mV, val, 0x03);
+	return menelaus_set_voltage(m, vtg, mV, val, 0x03);
 }
 
 static const struct menelaus_vtg_value vmmc_values[] = {
@@ -715,15 +728,16 @@ static const struct menelaus_vtg vmmc_vtg = {
 
 int menelaus_set_vmmc(unsigned int mV)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int val;
 
 	if (mV == 0)
-		return menelaus_set_voltage(&vmmc_vtg, 0, 0, 0);
+		return menelaus_set_voltage(m, &vmmc_vtg, 0, 0, 0);
 
-	val = menelaus_get_vtg_value(mV, vmmc_values, ARRAY_SIZE(vmmc_values));
+	val = menelaus_get_vtg_value(m, mV, vmmc_values, ARRAY_SIZE(vmmc_values));
 	if (val < 0)
 		return -EINVAL;
-	return menelaus_set_voltage(&vmmc_vtg, mV, val, 0x02);
+	return menelaus_set_voltage(m, &vmmc_vtg, mV, val, 0x02);
 }
 EXPORT_SYMBOL(menelaus_set_vmmc);
 
@@ -745,37 +759,41 @@ static const struct menelaus_vtg vaux_vtg = {
 
 int menelaus_set_vaux(unsigned int mV)
 {
+	struct menelaus_chip *m = the_menelaus;
 	int val;
 
 	if (mV == 0)
-		return menelaus_set_voltage(&vaux_vtg, 0, 0, 0);
+		return menelaus_set_voltage(m, &vaux_vtg, 0, 0, 0);
 
-	val = menelaus_get_vtg_value(mV, vaux_values, ARRAY_SIZE(vaux_values));
+	val = menelaus_get_vtg_value(m, mV, vaux_values, ARRAY_SIZE(vaux_values));
 	if (val < 0)
 		return -EINVAL;
-	return menelaus_set_voltage(&vaux_vtg, mV, val, 0x02);
+	return menelaus_set_voltage(m, &vaux_vtg, mV, val, 0x02);
 }
 EXPORT_SYMBOL(menelaus_set_vaux);
 
 int menelaus_get_slot_pin_states(void)
 {
-	return menelaus_read_reg(MENELAUS_MCT_PIN_ST);
+	struct menelaus_chip *m = the_menelaus;
+
+	return menelaus_read_reg(m, MENELAUS_MCT_PIN_ST);
 }
 EXPORT_SYMBOL(menelaus_get_slot_pin_states);
 
 int menelaus_set_regulator_sleep(int enable, u32 val)
 {
+	struct menelaus_chip *m = the_menelaus;
+	struct i2c_client *c = m->client;
 	int t, ret;
-	struct i2c_client *c = the_menelaus->client;
 
-	mutex_lock(&the_menelaus->lock);
-	ret = menelaus_write_reg(MENELAUS_SLEEP_CTRL2, val);
+	mutex_lock(&m->lock);
+	ret = menelaus_write_reg(m, MENELAUS_SLEEP_CTRL2, val);
 	if (ret < 0)
 		goto out;
 
 	dev_dbg(&c->dev, "regulator sleep configuration: %02x\n", val);
 
-	ret = menelaus_read_reg(MENELAUS_GPIO_CTRL);
+	ret = menelaus_read_reg(m, MENELAUS_GPIO_CTRL);
 	if (ret < 0)
 		goto out;
 	t = (GPIO_CTRL_SLPCTLEN | GPIO3_DIR_INPUT);
@@ -783,9 +801,9 @@ int menelaus_set_regulator_sleep(int enable, u32 val)
 		ret |= t;
 	else
 		ret &= ~t;
-	ret = menelaus_write_reg(MENELAUS_GPIO_CTRL, ret);
+	ret = menelaus_write_reg(m, MENELAUS_GPIO_CTRL, ret);
 out:
-	mutex_unlock(&the_menelaus->lock);
+	mutex_unlock(&m->lock);
 	return ret;
 }
 
@@ -793,25 +811,25 @@ out:
 
 static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 {
-	struct menelaus_chip *menelaus = _menelaus;
-	void (*handler)(struct menelaus_chip *menelaus);
+	struct menelaus_chip *m = _menelaus;
+	void (*handler)(struct menelaus_chip *m);
 	unsigned long isr;
 	unsigned long i;
 
-	isr = (menelaus_read_reg(MENELAUS_INT_STATUS2)
-			& ~menelaus->mask2) << 8;
-	isr |= menelaus_read_reg(MENELAUS_INT_STATUS1)
-		& ~menelaus->mask1;
+	isr = (menelaus_read_reg(m, MENELAUS_INT_STATUS2)
+			& ~m->mask2) << 8;
+	isr |= menelaus_read_reg(m, MENELAUS_INT_STATUS1)
+		& ~m->mask1;
 
 	for_each_set_bit(i, &isr, 16) {
-		mutex_lock(&menelaus->lock);
-		menelaus_disable_irq(i);
-		menelaus_ack_irq(i);
-		handler = menelaus->handlers[i];
+		mutex_lock(&m->lock);
+		menelaus_disable_irq(m, i);
+		menelaus_ack_irq(m, i);
+		handler = m->handlers[i];
 		if (handler)
-			handler(menelaus);
-		menelaus_enable_irq(i);
-		mutex_unlock(&menelaus->lock);
+			handler(m);
+		menelaus_enable_irq(m, i);
+		mutex_unlock(&m->lock);
 	}
 
 	return IRQ_HANDLED;
@@ -839,11 +857,12 @@ static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 
 #define RTC_HR_PM		(1 << 7)
 
-static void menelaus_to_time(char *regs, struct rtc_time *t)
+static void menelaus_to_time(struct menelaus_chip *m,
+		char *regs, struct rtc_time *t)
 {
 	t->tm_sec = bcd2bin(regs[0]);
 	t->tm_min = bcd2bin(regs[1]);
-	if (the_menelaus->rtc_control & RTC_CTRL_MODE12) {
+	if (m->rtc_control & RTC_CTRL_MODE12) {
 		t->tm_hour = bcd2bin(regs[2] & 0x1f) - 1;
 		if (regs[2] & RTC_HR_PM)
 			t->tm_hour += 12;
@@ -854,19 +873,20 @@ static void menelaus_to_time(char *regs, struct rtc_time *t)
 	t->tm_year = bcd2bin(regs[5]) + 100;
 }
 
-static int time_to_menelaus(struct rtc_time *t, int regnum)
+static int time_to_menelaus(struct menelaus_chip *m,
+		struct rtc_time *t, int regnum)
 {
 	int	hour, status;
 
-	status = menelaus_write_reg(regnum++, bin2bcd(t->tm_sec));
+	status = menelaus_write_reg(m, regnum++, bin2bcd(t->tm_sec));
 	if (status < 0)
 		goto fail;
 
-	status = menelaus_write_reg(regnum++, bin2bcd(t->tm_min));
+	status = menelaus_write_reg(m, regnum++, bin2bcd(t->tm_min));
 	if (status < 0)
 		goto fail;
 
-	if (the_menelaus->rtc_control & RTC_CTRL_MODE12) {
+	if (m->rtc_control & RTC_CTRL_MODE12) {
 		hour = t->tm_hour + 1;
 		if (hour > 12)
 			hour = RTC_HR_PM | bin2bcd(hour - 12);
@@ -874,31 +894,32 @@ static int time_to_menelaus(struct rtc_time *t, int regnum)
 			hour = bin2bcd(hour);
 	} else
 		hour = bin2bcd(t->tm_hour);
-	status = menelaus_write_reg(regnum++, hour);
+	status = menelaus_write_reg(m, regnum++, hour);
 	if (status < 0)
 		goto fail;
 
-	status = menelaus_write_reg(regnum++, bin2bcd(t->tm_mday));
+	status = menelaus_write_reg(m, regnum++, bin2bcd(t->tm_mday));
 	if (status < 0)
 		goto fail;
 
-	status = menelaus_write_reg(regnum++, bin2bcd(t->tm_mon + 1));
+	status = menelaus_write_reg(m, regnum++, bin2bcd(t->tm_mon + 1));
 	if (status < 0)
 		goto fail;
 
-	status = menelaus_write_reg(regnum++, bin2bcd(t->tm_year - 100));
+	status = menelaus_write_reg(m, regnum++, bin2bcd(t->tm_year - 100));
 	if (status < 0)
 		goto fail;
 
 	return 0;
 fail:
-	dev_err(&the_menelaus->client->dev, "rtc write reg %02x, err %d\n",
+	dev_err(&m->client->dev, "rtc write reg %02x, err %d\n",
 			--regnum, status);
 	return status;
 }
 
 static int menelaus_read_time(struct device *dev, struct rtc_time *t)
 {
+	struct menelaus_chip *m = dev_get_drvdata(dev);
 	struct i2c_msg	msg[2];
 	char		regs[7];
 	int		status;
@@ -916,13 +937,13 @@ static int menelaus_read_time(struct device *dev, struct rtc_time *t)
 	msg[1].len = sizeof(regs);
 	msg[1].buf = regs;
 
-	status = i2c_transfer(the_menelaus->client->adapter, msg, 2);
+	status = i2c_transfer(m->client->adapter, msg, 2);
 	if (status != 2) {
 		dev_err(dev, "%s error %d\n", "read", status);
 		return -EIO;
 	}
 
-	menelaus_to_time(regs, t);
+	menelaus_to_time(m, regs, t);
 	t->tm_wday = bcd2bin(regs[6]);
 
 	return 0;
@@ -930,23 +951,24 @@ static int menelaus_read_time(struct device *dev, struct rtc_time *t)
 
 static int menelaus_set_time(struct device *dev, struct rtc_time *t)
 {
+	struct menelaus_chip *m = dev_get_drvdata(dev);
 	int		status;
 
 	/* write date and time registers */
-	status = time_to_menelaus(t, MENELAUS_RTC_SEC);
+	status = time_to_menelaus(m, t, MENELAUS_RTC_SEC);
 	if (status < 0)
 		return status;
-	status = menelaus_write_reg(MENELAUS_RTC_WKDAY, bin2bcd(t->tm_wday));
+	status = menelaus_write_reg(m, MENELAUS_RTC_WKDAY, bin2bcd(t->tm_wday));
 	if (status < 0) {
-		dev_err(&the_menelaus->client->dev, "rtc write reg %02x "
+		dev_err(&m->client->dev, "rtc write reg %02x "
 				"err %d\n", MENELAUS_RTC_WKDAY, status);
 		return status;
 	}
 
 	/* now commit the write */
-	status = menelaus_write_reg(MENELAUS_RTC_UPDATE, RTC_UPDATE_EVERY);
+	status = menelaus_write_reg(m, MENELAUS_RTC_UPDATE, RTC_UPDATE_EVERY);
 	if (status < 0)
-		dev_err(&the_menelaus->client->dev, "rtc commit time, err %d\n",
+		dev_err(&m->client->dev, "rtc commit time, err %d\n",
 				status);
 
 	return 0;
@@ -954,6 +976,7 @@ static int menelaus_set_time(struct device *dev, struct rtc_time *t)
 
 static int menelaus_read_alarm(struct device *dev, struct rtc_wkalrm *w)
 {
+	struct menelaus_chip *m = dev_get_drvdata(dev);
 	struct i2c_msg	msg[2];
 	char		regs[6];
 	int		status;
@@ -971,15 +994,15 @@ static int menelaus_read_alarm(struct device *dev, struct rtc_wkalrm *w)
 	msg[1].len = sizeof(regs);
 	msg[1].buf = regs;
 
-	status = i2c_transfer(the_menelaus->client->adapter, msg, 2);
+	status = i2c_transfer(m->client->adapter, msg, 2);
 	if (status != 2) {
 		dev_err(dev, "%s error %d\n", "alarm read", status);
 		return -EIO;
 	}
 
-	menelaus_to_time(regs, &w->time);
+	menelaus_to_time(m, regs, &w->time);
 
-	w->enabled = !!(the_menelaus->rtc_control & RTC_CTRL_AL_EN);
+	w->enabled = !!(m->rtc_control & RTC_CTRL_AL_EN);
 
 	/* NOTE we *could* check if actually pending... */
 	w->pending = 0;
@@ -989,30 +1012,31 @@ static int menelaus_read_alarm(struct device *dev, struct rtc_wkalrm *w)
 
 static int menelaus_set_alarm(struct device *dev, struct rtc_wkalrm *w)
 {
+	struct menelaus_chip *m = dev_get_drvdata(dev);
 	int		status;
 
-	if (the_menelaus->client->irq <= 0 && w->enabled)
+	if (m->client->irq <= 0 && w->enabled)
 		return -ENODEV;
 
 	/* clear previous alarm enable */
-	if (the_menelaus->rtc_control & RTC_CTRL_AL_EN) {
-		the_menelaus->rtc_control &= ~RTC_CTRL_AL_EN;
-		status = menelaus_write_reg(MENELAUS_RTC_CTRL,
-				the_menelaus->rtc_control);
+	if (m->rtc_control & RTC_CTRL_AL_EN) {
+		m->rtc_control &= ~RTC_CTRL_AL_EN;
+		status = menelaus_write_reg(m, MENELAUS_RTC_CTRL,
+				m->rtc_control);
 		if (status < 0)
 			return status;
 	}
 
 	/* write alarm registers */
-	status = time_to_menelaus(&w->time, MENELAUS_RTC_AL_SEC);
+	status = time_to_menelaus(m, &w->time, MENELAUS_RTC_AL_SEC);
 	if (status < 0)
 		return status;
 
 	/* enable alarm if requested */
 	if (w->enabled) {
-		the_menelaus->rtc_control |= RTC_CTRL_AL_EN;
-		status = menelaus_write_reg(MENELAUS_RTC_CTRL,
-				the_menelaus->rtc_control);
+		m->rtc_control |= RTC_CTRL_AL_EN;
+		status = menelaus_write_reg(m, MENELAUS_RTC_CTRL,
+				m->rtc_control);
 	}
 
 	return status;
@@ -1030,44 +1054,45 @@ static void menelaus_rtc_update_work(struct menelaus_chip *m)
 
 static int menelaus_ioctl(struct device *dev, unsigned cmd, unsigned long arg)
 {
+	struct menelaus_chip *m = dev_get_drvdata(dev);
 	int	status;
 
-	if (the_menelaus->client->irq <= 0)
+	if (m->client->irq <= 0)
 		return -ENOIOCTLCMD;
 
 	switch (cmd) {
 	/* alarm IRQ */
 	case RTC_AIE_ON:
-		if (the_menelaus->rtc_control & RTC_CTRL_AL_EN)
+		if (m->rtc_control & RTC_CTRL_AL_EN)
 			return 0;
-		the_menelaus->rtc_control |= RTC_CTRL_AL_EN;
+		m->rtc_control |= RTC_CTRL_AL_EN;
 		break;
 	case RTC_AIE_OFF:
-		if (!(the_menelaus->rtc_control & RTC_CTRL_AL_EN))
+		if (!(m->rtc_control & RTC_CTRL_AL_EN))
 			return 0;
-		the_menelaus->rtc_control &= ~RTC_CTRL_AL_EN;
+		m->rtc_control &= ~RTC_CTRL_AL_EN;
 		break;
 	/* 1/second "update" IRQ */
 	case RTC_UIE_ON:
-		if (the_menelaus->uie)
+		if (m->uie)
 			return 0;
-		status = menelaus_remove_irq_work(MENELAUS_RTCTMR_IRQ);
-		status = menelaus_add_irq_work(MENELAUS_RTCTMR_IRQ,
+		status = menelaus_remove_irq_work(m, MENELAUS_RTCTMR_IRQ);
+		status = menelaus_add_irq_work(m, MENELAUS_RTCTMR_IRQ,
 				menelaus_rtc_update_work);
 		if (status == 0)
-			the_menelaus->uie = 1;
+			m->uie = 1;
 		return status;
 	case RTC_UIE_OFF:
-		if (!the_menelaus->uie)
+		if (!m->uie)
 			return 0;
-		status = menelaus_remove_irq_work(MENELAUS_RTCTMR_IRQ);
+		status = menelaus_remove_irq_work(m, MENELAUS_RTCTMR_IRQ);
 		if (status == 0)
-			the_menelaus->uie = 0;
+			m->uie = 0;
 		return status;
 	default:
 		return -ENOIOCTLCMD;
 	}
-	return menelaus_write_reg(MENELAUS_RTC_CTRL, the_menelaus->rtc_control);
+	return menelaus_write_reg(m, MENELAUS_RTC_CTRL, m->rtc_control);
 }
 
 #else
@@ -1092,8 +1117,8 @@ static void menelaus_rtc_alarm_work(struct menelaus_chip *m)
 	local_irq_enable();
 
 	/* then disable it; alarms are oneshot */
-	the_menelaus->rtc_control &= ~RTC_CTRL_AL_EN;
-	menelaus_write_reg(MENELAUS_RTC_CTRL, the_menelaus->rtc_control);
+	m->rtc_control &= ~RTC_CTRL_AL_EN;
+	menelaus_write_reg(m, MENELAUS_RTC_CTRL, m->rtc_control);
 }
 
 static inline void menelaus_rtc_init(struct menelaus_chip *m)
@@ -1101,14 +1126,14 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 	int	alarm = (m->client->irq > 0);
 
 	/* assume 32KDETEN pin is pulled high */
-	if (!(menelaus_read_reg(MENELAUS_OSC_CTRL) & 0x80)) {
+	if (!(menelaus_read_reg(m, MENELAUS_OSC_CTRL) & 0x80)) {
 		dev_dbg(&m->client->dev, "no 32k oscillator\n");
 		return;
 	}
 
 	/* support RTC alarm; it can issue wakeups */
 	if (alarm) {
-		if (menelaus_add_irq_work(MENELAUS_RTCALM_IRQ,
+		if (menelaus_add_irq_work(m, MENELAUS_RTCALM_IRQ,
 				menelaus_rtc_alarm_work) < 0) {
 			dev_err(&m->client->dev, "can't handle RTC alarm\n");
 			return;
@@ -1117,7 +1142,7 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 	}
 
 	/* be sure RTC is enabled; allow 1/sec irqs; leave 12hr mode alone */
-	m->rtc_control = menelaus_read_reg(MENELAUS_RTC_CTRL);
+	m->rtc_control = menelaus_read_reg(m, MENELAUS_RTC_CTRL);
 	if (!(m->rtc_control & RTC_CTRL_RTC_EN)
 			|| (m->rtc_control & RTC_CTRL_AL_EN)
 			|| (m->rtc_control & RTC_CTRL_EVERY_MASK)) {
@@ -1127,7 +1152,7 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 		}
 		m->rtc_control &= ~RTC_CTRL_EVERY_MASK;
 		m->rtc_control &= ~RTC_CTRL_AL_EN;
-		menelaus_write_reg(MENELAUS_RTC_CTRL, m->rtc_control);
+		menelaus_write_reg(m, MENELAUS_RTC_CTRL, m->rtc_control);
 	}
 
 	m->rtc = rtc_device_register(DRIVER_NAME,
@@ -1135,12 +1160,12 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 			&menelaus_rtc_ops, THIS_MODULE);
 	if (IS_ERR(m->rtc)) {
 		if (alarm) {
-			menelaus_remove_irq_work(MENELAUS_RTCALM_IRQ);
+			menelaus_remove_irq_work(m, MENELAUS_RTCALM_IRQ);
 			device_init_wakeup(&m->client->dev, 0);
 		}
 		dev_err(&m->client->dev, "can't register RTC: %d\n",
 				(int) PTR_ERR(m->rtc));
-		the_menelaus->rtc = NULL;
+		m->rtc = NULL;
 	}
 }
 
@@ -1160,7 +1185,7 @@ static struct i2c_driver menelaus_i2c_driver;
 static int menelaus_probe(struct i2c_client *client,
 			  const struct i2c_device_id *id)
 {
-	struct menelaus_chip	*menelaus;
+	struct menelaus_chip	*m;
 	int			rev = 0, val;
 	int			err = 0;
 	struct menelaus_platform_data *menelaus_pdata =
@@ -1172,37 +1197,36 @@ static int menelaus_probe(struct i2c_client *client,
 		return -ENODEV;
 	}
 
-	menelaus = devm_kzalloc(&client->dev, sizeof(*menelaus), GFP_KERNEL);
-	if (!menelaus)
+	m = devm_kzalloc(&client->dev, sizeof(*m), GFP_KERNEL);
+	if (!m)
 		return -ENOMEM;
 
-	i2c_set_clientdata(client, menelaus);
+	i2c_set_clientdata(client, m);
 
-	the_menelaus = menelaus;
-	menelaus->client = client;
+	the_menelaus = m;
+	m->client = client;
 
 	/* If a true probe check the device */
-	rev = menelaus_read_reg(MENELAUS_REV);
+	rev = menelaus_read_reg(m, MENELAUS_REV);
 	if (rev < 0) {
 		pr_err(DRIVER_NAME ": device not found");
 		return -ENODEV;
 	}
 
 	/* Ack and disable all Menelaus interrupts */
-	menelaus_write_reg(MENELAUS_INT_ACK1, 0xff);
-	menelaus_write_reg(MENELAUS_INT_ACK2, 0xff);
-	menelaus_write_reg(MENELAUS_INT_MASK1, 0xff);
-	menelaus_write_reg(MENELAUS_INT_MASK2, 0xff);
-	menelaus->mask1 = 0xff;
-	menelaus->mask2 = 0xff;
+	menelaus_write_reg(m, MENELAUS_INT_ACK1, 0xff);
+	menelaus_write_reg(m, MENELAUS_INT_ACK2, 0xff);
+	menelaus_write_reg(m, MENELAUS_INT_MASK1, 0xff);
+	menelaus_write_reg(m, MENELAUS_INT_MASK2, 0xff);
+	m->mask1 = 0xff;
+	m->mask2 = 0xff;
 
 	/* Set output buffer strengths */
-	menelaus_write_reg(MENELAUS_MCT_CTRL1, 0x73);
+	menelaus_write_reg(m, MENELAUS_MCT_CTRL1, 0x73);
 
 	if (client->irq > 0) {
 		err = devm_request_threaded_irq(&client->dev, client->irq, NULL,
-				menelaus_irq, IRQF_ONESHOT, DRIVER_NAME,
-				menelaus);
+				menelaus_irq, IRQF_ONESHOT, DRIVER_NAME, m);
 		if (err) {
 			dev_dbg(&client->dev,  "can't get IRQ %d, err %d\n",
 					client->irq, err);
@@ -1210,17 +1234,17 @@ static int menelaus_probe(struct i2c_client *client,
 		}
 	}
 
-	mutex_init(&menelaus->lock);
+	mutex_init(&m->lock);
 
 	pr_info("Menelaus rev %d.%d\n", rev >> 4, rev & 0x0f);
 
-	val = menelaus_read_reg(MENELAUS_VCORE_CTRL1);
+	val = menelaus_read_reg(m, MENELAUS_VCORE_CTRL1);
 	if (val < 0)
 		goto fail;
 	if (val & (1 << 7))
-		menelaus->vcore_hw_mode = 1;
+		m->vcore_hw_mode = 1;
 	else
-		menelaus->vcore_hw_mode = 0;
+		m->vcore_hw_mode = 0;
 
 	if (menelaus_pdata != NULL && menelaus_pdata->late_init != NULL) {
 		err = menelaus_pdata->late_init(&client->dev);
@@ -1228,7 +1252,7 @@ static int menelaus_probe(struct i2c_client *client,
 			goto fail;
 	}
 
-	menelaus_rtc_init(menelaus);
+	menelaus_rtc_init(m);
 
 	return 0;
 fail:
-- 
1.8.4.GIT

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

* [PATCH 07/10] mfd: menelaus: Start to use irqdomain
  2013-12-17  0:08   ` [PATCH 01/10] " Felipe Balbi
                       ` (4 preceding siblings ...)
  2013-12-17  0:08     ` [PATCH 06/10] mfd: menelaus: Limit the usage of the_menelaus Felipe Balbi
@ 2013-12-17  0:08     ` Felipe Balbi
  2013-12-17 10:32       ` Lee Jones
  2013-12-17  0:08     ` [PATCH 08/10] mfd: menelaus: Switch all children to threaded_irq Felipe Balbi
                       ` (2 subsequent siblings)
  8 siblings, 1 reply; 73+ messages in thread
From: Felipe Balbi @ 2013-12-17  0:08 UTC (permalink / raw)
  To: linux-arm-kernel

Introduce an irq_chip and irq_domain for menelaus driver. Following
patches will convert uses to traditional request_threaded_irq().

While at that, some better error handling had to be added, so we could
free irq descs we allocated.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 119 insertions(+), 4 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index ae3209d..838d6bf 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -34,6 +34,7 @@
 #include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
+#include <linux/irqdomain.h>
 #include <linux/sched.h>
 #include <linux/mutex.h>
 #include <linux/delay.h>
@@ -47,6 +48,7 @@
 #include <asm/gpio.h>
 
 #define DRIVER_NAME			"menelaus"
+#define MENELAUS_NR_IRQS		16
 
 #define MENELAUS_I2C_ADDRESS		0x72
 
@@ -168,11 +170,19 @@ struct menelaus_chip {
 	u8			rtc_control;
 	unsigned		uie:1;
 #endif
+	int			irq_base;
 	unsigned		vcore_hw_mode:1;
 	u8			mask1, mask2;
+	u8			ack1, ack2;
+
 	void			(*handlers[16])(struct menelaus_chip *);
 	void			(*mmc_callback)(void *data, u8 mask);
 	void			*mmc_callback_data;
+
+	unsigned		mask1_pending:1;
+	unsigned		mask2_pending:1;
+	unsigned		ack1_pending:1;
+	unsigned		ack2_pending:1;
 };
 
 static struct menelaus_chip *the_menelaus;
@@ -235,6 +245,83 @@ static int menelaus_ack_irq(struct menelaus_chip *m, int irq)
 		return menelaus_write_reg(m, MENELAUS_INT_ACK1, 1 << irq);
 }
 
+static void menelaus_irq_ack(struct irq_data *data)
+{
+	struct menelaus_chip *m = irq_data_get_irq_chip_data(data);
+	int irq = data->irq - m->irq_base;
+
+	if (irq > 7) {
+		m->ack2 |= BIT(irq);
+		m->ack2_pending = true;
+	} else {
+		m->ack1 |= BIT(irq);
+		m->ack1_pending = true;
+	}
+}
+
+static void menelaus_irq_mask(struct irq_data *data)
+{
+	struct menelaus_chip *m = irq_data_get_irq_chip_data(data);
+	int irq = data->irq - m->irq_base;
+
+	if (irq > 7) {
+		m->mask2 |= BIT(irq);
+		m->mask2_pending = true;
+	} else {
+		m->mask1 |= BIT(irq);
+		m->mask1_pending = true;
+	}
+}
+
+static void menelaus_irq_unmask(struct irq_data *data)
+{
+	struct menelaus_chip *m = irq_data_get_irq_chip_data(data);
+	int irq = data->irq - m->irq_base;
+
+	if (irq > 7) {
+		m->mask2 &= ~BIT(irq);
+		m->mask2_pending = true;
+	} else {
+		m->mask1 &= ~BIT(irq);
+		m->mask1_pending = true;
+	}
+}
+
+static void menelaus_irq_bus_lock(struct irq_data *data)
+{
+	struct menelaus_chip *m = irq_data_get_irq_chip_data(data);
+
+	mutex_lock(&m->lock);
+}
+
+static void menelaus_irq_bus_sync_unlock(struct irq_data *data)
+{
+	struct menelaus_chip *m = irq_data_get_irq_chip_data(data);
+
+	if (m->ack1_pending)
+		menelaus_write_reg(m, MENELAUS_INT_ACK1, m->ack1);
+
+	if (m->ack2_pending)
+		menelaus_write_reg(m, MENELAUS_INT_ACK2, m->ack2);
+
+	if (m->mask1_pending)
+		menelaus_write_reg(m, MENELAUS_INT_MASK1, m->mask1);
+
+	if (m->mask2_pending)
+		menelaus_write_reg(m, MENELAUS_INT_MASK2, m->mask2);
+
+	mutex_unlock(&m->lock);
+}
+
+static struct irq_chip menelaus_irq_chip = {
+	.name		= "menelaus",
+	.irq_ack	= menelaus_irq_ack,
+	.irq_mask	= menelaus_irq_mask,
+	.irq_unmask	= menelaus_irq_unmask,
+	.irq_bus_lock	= menelaus_irq_bus_lock,
+	.irq_bus_sync_unlock = menelaus_irq_bus_sync_unlock,
+};
+
 /* Adds a handler for an interrupt. Does not run in interrupt context */
 static int menelaus_add_irq_work(struct menelaus_chip *m, int irq,
 		void (*handler)(struct menelaus_chip *))
@@ -1186,8 +1273,11 @@ static int menelaus_probe(struct i2c_client *client,
 			  const struct i2c_device_id *id)
 {
 	struct menelaus_chip	*m;
+	struct device_node	*node = client->dev.of_node;
 	int			rev = 0, val;
 	int			err = 0;
+	int			irq_base;
+	int			i;
 	struct menelaus_platform_data *menelaus_pdata =
 					dev_get_platdata(&client->dev);
 
@@ -1205,12 +1295,32 @@ static int menelaus_probe(struct i2c_client *client,
 
 	the_menelaus = m;
 	m->client = client;
+	mutex_init(&m->lock);
+
+	irq_base = irq_alloc_descs(-1, 0, MENELAUS_NR_IRQS, 0);
+	if (irq_base < 0) {
+		dev_err(&client->dev, "failed to allocate irq descs\n");
+		return irq_base;
+	}
+
+	irq_domain_add_legacy(node, MENELAUS_NR_IRQS, irq_base, 0,
+			&irq_domain_simple_ops, m);
+
+	m->irq_base = irq_base;
+
+	for (i = irq_base; i < irq_base + MENELAUS_NR_IRQS; i++) {
+		irq_set_chip_data(i, m);
+		irq_set_chip_and_handler(i, &menelaus_irq_chip,
+				handle_simple_irq);
+		irq_set_nested_thread(i, 1);
+		set_irq_flags(i, IRQF_VALID);
+	}
 
 	/* If a true probe check the device */
 	rev = menelaus_read_reg(m, MENELAUS_REV);
 	if (rev < 0) {
 		pr_err(DRIVER_NAME ": device not found");
-		return -ENODEV;
+		goto fail;
 	}
 
 	/* Ack and disable all Menelaus interrupts */
@@ -1230,12 +1340,10 @@ static int menelaus_probe(struct i2c_client *client,
 		if (err) {
 			dev_dbg(&client->dev,  "can't get IRQ %d, err %d\n",
 					client->irq, err);
-			return err;
+			goto fail;
 		}
 	}
 
-	mutex_init(&m->lock);
-
 	pr_info("Menelaus rev %d.%d\n", rev >> 4, rev & 0x0f);
 
 	val = menelaus_read_reg(m, MENELAUS_VCORE_CTRL1);
@@ -1255,13 +1363,20 @@ static int menelaus_probe(struct i2c_client *client,
 	menelaus_rtc_init(m);
 
 	return 0;
+
 fail:
+	irq_free_descs(irq_base, MENELAUS_NR_IRQS);
+
 	return err;
 }
 
 static int menelaus_remove(struct i2c_client *client)
 {
+	struct menelaus_chip	*m = i2c_get_clientdata(client);
+
+	irq_free_descs(m->irq_base, MENELAUS_NR_IRQS);
 	the_menelaus = NULL;
+
 	return 0;
 }
 
-- 
1.8.4.GIT

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

* [PATCH 08/10] mfd: menelaus: Switch all children to threaded_irq
  2013-12-17  0:08   ` [PATCH 01/10] " Felipe Balbi
                       ` (5 preceding siblings ...)
  2013-12-17  0:08     ` [PATCH 07/10] mfd: menelaus: Start to use irqdomain Felipe Balbi
@ 2013-12-17  0:08     ` Felipe Balbi
  2013-12-17 10:35       ` Lee Jones
  2013-12-17  0:08     ` [PATCH 09/10] mfd: menelaus: Remove unnecessary definition Felipe Balbi
  2013-12-17  0:08     ` [PATCH 10/10] mfd: menelaus: IRQ is a requirement Felipe Balbi
  8 siblings, 1 reply; 73+ messages in thread
From: Felipe Balbi @ 2013-12-17  0:08 UTC (permalink / raw)
  To: linux-arm-kernel

Now that we have our own irq_chip, all children can use traditional
request_threaded_irq().

While at that, also remove so functions which became unused.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 161 +++++++++++++++----------------------------------
 1 file changed, 50 insertions(+), 111 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 838d6bf..232d037 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -175,7 +175,6 @@ struct menelaus_chip {
 	u8			mask1, mask2;
 	u8			ack1, ack2;
 
-	void			(*handlers[16])(struct menelaus_chip *);
 	void			(*mmc_callback)(void *data, u8 mask);
 	void			*mmc_callback_data;
 
@@ -209,42 +208,6 @@ static int menelaus_read_reg(struct menelaus_chip *m, int reg)
 	return val;
 }
 
-static int menelaus_enable_irq(struct menelaus_chip *m, int irq)
-{
-	if (irq > 7) {
-		irq -= 8;
-		m->mask2 &= ~(1 << irq);
-		return menelaus_write_reg(m, MENELAUS_INT_MASK2,
-				m->mask2);
-	} else {
-		m->mask1 &= ~(1 << irq);
-		return menelaus_write_reg(m, MENELAUS_INT_MASK1,
-				m->mask1);
-	}
-}
-
-static int menelaus_disable_irq(struct menelaus_chip *m, int irq)
-{
-	if (irq > 7) {
-		irq -= 8;
-		m->mask2 |= (1 << irq);
-		return menelaus_write_reg(m, MENELAUS_INT_MASK2,
-				m->mask2);
-	} else {
-		m->mask1 |= (1 << irq);
-		return menelaus_write_reg(m, MENELAUS_INT_MASK1,
-				m->mask1);
-	}
-}
-
-static int menelaus_ack_irq(struct menelaus_chip *m, int irq)
-{
-	if (irq > 7)
-		return menelaus_write_reg(m, MENELAUS_INT_ACK2, 1 << (irq - 8));
-	else
-		return menelaus_write_reg(m, MENELAUS_INT_ACK1, 1 << irq);
-}
-
 static void menelaus_irq_ack(struct irq_data *data)
 {
 	struct menelaus_chip *m = irq_data_get_irq_chip_data(data);
@@ -322,47 +285,15 @@ static struct irq_chip menelaus_irq_chip = {
 	.irq_bus_sync_unlock = menelaus_irq_bus_sync_unlock,
 };
 
-/* Adds a handler for an interrupt. Does not run in interrupt context */
-static int menelaus_add_irq_work(struct menelaus_chip *m, int irq,
-		void (*handler)(struct menelaus_chip *))
-{
-	int ret = 0;
-
-	mutex_lock(&m->lock);
-	m->handlers[irq] = handler;
-	ret = menelaus_enable_irq(m, irq);
-	mutex_unlock(&m->lock);
-
-	return ret;
-}
-
-/* Removes handler for an interrupt */
-static int menelaus_remove_irq_work(struct menelaus_chip *m, int irq)
-{
-	int ret = 0;
-
-	mutex_lock(&m->lock);
-	ret = menelaus_disable_irq(m, irq);
-	m->handlers[irq] = NULL;
-	mutex_unlock(&m->lock);
-
-	return ret;
-}
-
-/*
- * Gets scheduled when a card detect interrupt happens. Note that in some cases
- * this line is wired to card cover switch rather than the card detect switch
- * in each slot. In this case the cards are not seen by menelaus.
- * FIXME: Add handling for D1 too
- */
-static void menelaus_mmc_cd_work(struct menelaus_chip *m)
+static irqreturn_t menelaus_mmc_cd_irq(int irq, void *_m)
 {
-	int reg;
+	struct menelaus_chip *m = _m;
 	unsigned char card_mask = 0;
+	int reg;
 
 	reg = menelaus_read_reg(m, MENELAUS_MCT_PIN_ST);
 	if (reg < 0)
-		return;
+		return IRQ_NONE;
 
 	if (!(reg & 0x1))
 		card_mask |= MCT_PIN_ST_S1_CD_ST;
@@ -373,6 +304,8 @@ static void menelaus_mmc_cd_work(struct menelaus_chip *m)
 	if (m->mmc_callback)
 		m->mmc_callback(m->mmc_callback_data,
 					  card_mask);
+
+	return IRQ_HANDLED;
 }
 
 /*
@@ -504,20 +437,25 @@ int menelaus_register_mmc_callback(void (*callback)(void *data, u8 card_mask),
 
 	m->mmc_callback_data = data;
 	m->mmc_callback = callback;
-	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S1CD_IRQ,
-				    menelaus_mmc_cd_work);
+
+	ret = request_threaded_irq(MENELAUS_MMC_S1CD_IRQ + m->irq_base,
+			NULL, menelaus_mmc_cd_irq, IRQF_ONESHOT,
+			"mmc_s1cd", m);
 	if (ret < 0)
 		return ret;
-	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S2CD_IRQ,
-				    menelaus_mmc_cd_work);
+	ret = request_threaded_irq(MENELAUS_MMC_S2CD_IRQ + m->irq_base,
+			NULL, menelaus_mmc_cd_irq, IRQF_ONESHOT,
+			"mmc_s2cd", m);
 	if (ret < 0)
 		return ret;
-	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S1D1_IRQ,
-				    menelaus_mmc_cd_work);
+	ret = request_threaded_irq(MENELAUS_MMC_S1D1_IRQ + m->irq_base,
+			NULL, menelaus_mmc_cd_irq, IRQF_ONESHOT,
+			"mmc_s1d1", m);
 	if (ret < 0)
 		return ret;
-	ret = menelaus_add_irq_work(m, MENELAUS_MMC_S2D1_IRQ,
-				    menelaus_mmc_cd_work);
+	ret = request_threaded_irq(MENELAUS_MMC_S2D1_IRQ + m->irq_base,
+			NULL, menelaus_mmc_cd_irq, IRQF_ONESHOT,
+			"mmc_s2d1", m);
 
 	return ret;
 }
@@ -527,10 +465,10 @@ void menelaus_unregister_mmc_callback(void)
 {
 	struct menelaus_chip *m = the_menelaus;
 
-	menelaus_remove_irq_work(m, MENELAUS_MMC_S1CD_IRQ);
-	menelaus_remove_irq_work(m, MENELAUS_MMC_S2CD_IRQ);
-	menelaus_remove_irq_work(m, MENELAUS_MMC_S1D1_IRQ);
-	menelaus_remove_irq_work(m, MENELAUS_MMC_S2D1_IRQ);
+	free_irq(MENELAUS_MMC_S1CD_IRQ + m->irq_base, m);
+	free_irq(MENELAUS_MMC_S2CD_IRQ + m->irq_base, m);
+	free_irq(MENELAUS_MMC_S1D1_IRQ + m->irq_base, m);
+	free_irq(MENELAUS_MMC_S2D1_IRQ + m->irq_base, m);
 
 	m->mmc_callback = NULL;
 	m->mmc_callback_data = NULL;
@@ -899,7 +837,6 @@ out:
 static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 {
 	struct menelaus_chip *m = _menelaus;
-	void (*handler)(struct menelaus_chip *m);
 	unsigned long isr;
 	unsigned long i;
 
@@ -909,14 +846,9 @@ static irqreturn_t menelaus_irq(int irq, void *_menelaus)
 		& ~m->mask1;
 
 	for_each_set_bit(i, &isr, 16) {
-		mutex_lock(&m->lock);
-		menelaus_disable_irq(m, i);
-		menelaus_ack_irq(m, i);
-		handler = m->handlers[i];
-		if (handler)
-			handler(m);
-		menelaus_enable_irq(m, i);
-		mutex_unlock(&m->lock);
+		int irq = i + m->irq_base;
+
+		handle_nested_irq(irq);
 	}
 
 	return IRQ_HANDLED;
@@ -1131,18 +1063,19 @@ static int menelaus_set_alarm(struct device *dev, struct rtc_wkalrm *w)
 
 #ifdef CONFIG_RTC_INTF_DEV
 
-static void menelaus_rtc_update_work(struct menelaus_chip *m)
+static irqreturn_t menelaus_rtc_update_irq(int irq, void *_m)
 {
-	/* report 1/sec update */
-	local_irq_disable();
+	struct menelaus_chip *m = _m;
+
 	rtc_update_irq(m->rtc, 1, RTC_IRQF | RTC_UF);
-	local_irq_enable();
+
+	return IRQ_HANDLED;
 }
 
 static int menelaus_ioctl(struct device *dev, unsigned cmd, unsigned long arg)
 {
 	struct menelaus_chip *m = dev_get_drvdata(dev);
-	int	status;
+	int	status = 0;
 
 	if (m->client->irq <= 0)
 		return -ENOIOCTLCMD;
@@ -1163,18 +1096,18 @@ static int menelaus_ioctl(struct device *dev, unsigned cmd, unsigned long arg)
 	case RTC_UIE_ON:
 		if (m->uie)
 			return 0;
-		status = menelaus_remove_irq_work(m, MENELAUS_RTCTMR_IRQ);
-		status = menelaus_add_irq_work(m, MENELAUS_RTCTMR_IRQ,
-				menelaus_rtc_update_work);
+		free_irq(MENELAUS_RTCTMR_IRQ + m->irq_base, m);
+		status = request_threaded_irq(MENELAUS_RTCTMR_IRQ + m->irq_base,
+				NULL, menelaus_rtc_update_irq, IRQF_ONESHOT,
+				"rtc-timer", m);
 		if (status == 0)
 			m->uie = 1;
 		return status;
 	case RTC_UIE_OFF:
 		if (!m->uie)
 			return 0;
-		status = menelaus_remove_irq_work(m, MENELAUS_RTCTMR_IRQ);
-		if (status == 0)
-			m->uie = 0;
+		free_irq(MENELAUS_RTCTMR_IRQ + m->irq_base, m);
+		m->uie = 0;
 		return status;
 	default:
 		return -ENOIOCTLCMD;
@@ -1196,16 +1129,18 @@ static const struct rtc_class_ops menelaus_rtc_ops = {
 	.set_alarm		= menelaus_set_alarm,
 };
 
-static void menelaus_rtc_alarm_work(struct menelaus_chip *m)
+static irqreturn_t menelaus_rtc_alarm_irq(int irq, void *_m)
 {
+	struct menelaus_chip *m = _m;
+
 	/* report alarm */
-	local_irq_disable();
 	rtc_update_irq(m->rtc, 1, RTC_IRQF | RTC_AF);
-	local_irq_enable();
 
 	/* then disable it; alarms are oneshot */
 	m->rtc_control &= ~RTC_CTRL_AL_EN;
 	menelaus_write_reg(m, MENELAUS_RTC_CTRL, m->rtc_control);
+
+	return IRQ_HANDLED;
 }
 
 static inline void menelaus_rtc_init(struct menelaus_chip *m)
@@ -1220,8 +1155,12 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 
 	/* support RTC alarm; it can issue wakeups */
 	if (alarm) {
-		if (menelaus_add_irq_work(m, MENELAUS_RTCALM_IRQ,
-				menelaus_rtc_alarm_work) < 0) {
+		int ret;
+
+		ret = request_threaded_irq(MENELAUS_RTCALM_IRQ + m->irq_base,
+				NULL, menelaus_rtc_alarm_irq, IRQF_ONESHOT,
+				"rtc-alarm", m);
+		if (ret < 0) {
 			dev_err(&m->client->dev, "can't handle RTC alarm\n");
 			return;
 		}
@@ -1247,7 +1186,7 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 			&menelaus_rtc_ops, THIS_MODULE);
 	if (IS_ERR(m->rtc)) {
 		if (alarm) {
-			menelaus_remove_irq_work(m, MENELAUS_RTCALM_IRQ);
+			free_irq(MENELAUS_RTCALM_IRQ + m->irq_base, m);
 			device_init_wakeup(&m->client->dev, 0);
 		}
 		dev_err(&m->client->dev, "can't register RTC: %d\n",
-- 
1.8.4.GIT

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

* [PATCH 09/10] mfd: menelaus: Remove unnecessary definition
  2013-12-17  0:08   ` [PATCH 01/10] " Felipe Balbi
                       ` (6 preceding siblings ...)
  2013-12-17  0:08     ` [PATCH 08/10] mfd: menelaus: Switch all children to threaded_irq Felipe Balbi
@ 2013-12-17  0:08     ` Felipe Balbi
  2013-12-17  0:08     ` [PATCH 10/10] mfd: menelaus: IRQ is a requirement Felipe Balbi
  8 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-17  0:08 UTC (permalink / raw)
  To: linux-arm-kernel

menelaus_i2c_driver isn't referenced on probe, just remove that
unnecessary line. No functional changes.

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 232d037..5d106e4 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -1206,8 +1206,6 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 
 /*-----------------------------------------------------------------------*/
 
-static struct i2c_driver menelaus_i2c_driver;
-
 static int menelaus_probe(struct i2c_client *client,
 			  const struct i2c_device_id *id)
 {
-- 
1.8.4.GIT

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

* [PATCH 10/10] mfd: menelaus: IRQ is a requirement
  2013-12-17  0:08   ` [PATCH 01/10] " Felipe Balbi
                       ` (7 preceding siblings ...)
  2013-12-17  0:08     ` [PATCH 09/10] mfd: menelaus: Remove unnecessary definition Felipe Balbi
@ 2013-12-17  0:08     ` Felipe Balbi
  8 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-17  0:08 UTC (permalink / raw)
  To: linux-arm-kernel

This driver needs IRQ to work, if client->irq isn't set properly, we
won't work. Remove check around request_threaded_irq().

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/menelaus.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 5d106e4..b01588e 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -1271,14 +1271,12 @@ static int menelaus_probe(struct i2c_client *client,
 	/* Set output buffer strengths */
 	menelaus_write_reg(m, MENELAUS_MCT_CTRL1, 0x73);
 
-	if (client->irq > 0) {
-		err = devm_request_threaded_irq(&client->dev, client->irq, NULL,
-				menelaus_irq, IRQF_ONESHOT, DRIVER_NAME, m);
-		if (err) {
-			dev_dbg(&client->dev,  "can't get IRQ %d, err %d\n",
-					client->irq, err);
-			goto fail;
-		}
+	err = devm_request_threaded_irq(&client->dev, client->irq, NULL,
+			menelaus_irq, IRQF_ONESHOT, DRIVER_NAME, m);
+	if (err) {
+		dev_dbg(&client->dev,  "can't get IRQ %d, err %d\n",
+				client->irq, err);
+		goto fail;
 	}
 
 	pr_info("Menelaus rev %d.%d\n", rev >> 4, rev & 0x0f);
-- 
1.8.4.GIT

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

* [PATCH 05/10] mfd: menelaus: Use for_each_set_bit()
  2013-12-17  0:08     ` [PATCH 05/10] mfd: menelaus: Use for_each_set_bit() Felipe Balbi
@ 2013-12-17  0:17       ` Joe Perches
  2013-12-17  0:19         ` Felipe Balbi
  0 siblings, 1 reply; 73+ messages in thread
From: Joe Perches @ 2013-12-17  0:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 2013-12-16 at 18:08 -0600, Felipe Balbi wrote:
> That macro just helps removing some extra line of code and hides ffs()
> calls.
> 
> While at that, also fix a variable shadowing bug where 'int irq' was
> being redeclared inside inner loop while it was also argument to
> interrupt handler.
> 
> Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> Signed-off-by: Felipe Balbi <balbi@ti.com>
> ---
>  drivers/mfd/menelaus.c | 16 +++++++---------
>  1 file changed, 7 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
> index 87d80a8..d3e3022 100644
> --- a/drivers/mfd/menelaus.c
> +++ b/drivers/mfd/menelaus.c
> @@ -795,24 +795,22 @@ static irqreturn_t menelaus_irq(int irq, void *_menelaus)
>  {
>  	struct menelaus_chip *menelaus = _menelaus;
>  	void (*handler)(struct menelaus_chip *menelaus);
> -	unsigned isr;
> +	unsigned long isr;
> +	unsigned long i;
>  
>  	isr = (menelaus_read_reg(MENELAUS_INT_STATUS2)
>  			& ~menelaus->mask2) << 8;
>  	isr |= menelaus_read_reg(MENELAUS_INT_STATUS1)
>  		& ~menelaus->mask1;
>  
> -	while (isr) {
> -		int irq = fls(isr) - 1;
> -		isr &= ~(1 << irq);
> -
> +	for_each_set_bit(i, &isr, 16) {
>  		mutex_lock(&menelaus->lock);
> -		menelaus_disable_irq(irq);
> -		menelaus_ack_irq(irq);
> -		handler = menelaus->handlers[irq];
> +		menelaus_disable_irq(i);
> +		menelaus_ack_irq(i);
> +		handler = menelaus->handlers[i];
>  		if (handler)
>  			handler(menelaus);
> -		menelaus_enable_irq(irq);
> +		menelaus_enable_irq(i);
>  		mutex_unlock(&menelaus->lock);
>  	}
>  

This could handle the irqs in reverse order.
Does that matter?

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

* [PATCH 05/10] mfd: menelaus: Use for_each_set_bit()
  2013-12-17  0:17       ` Joe Perches
@ 2013-12-17  0:19         ` Felipe Balbi
  0 siblings, 0 replies; 73+ messages in thread
From: Felipe Balbi @ 2013-12-17  0:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Dec 16, 2013 at 04:17:35PM -0800, Joe Perches wrote:
> On Mon, 2013-12-16 at 18:08 -0600, Felipe Balbi wrote:
> > That macro just helps removing some extra line of code and hides ffs()
> > calls.
> > 
> > While at that, also fix a variable shadowing bug where 'int irq' was
> > being redeclared inside inner loop while it was also argument to
> > interrupt handler.
> > 
> > Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> > Signed-off-by: Felipe Balbi <balbi@ti.com>
> > ---
> >  drivers/mfd/menelaus.c | 16 +++++++---------
> >  1 file changed, 7 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
> > index 87d80a8..d3e3022 100644
> > --- a/drivers/mfd/menelaus.c
> > +++ b/drivers/mfd/menelaus.c
> > @@ -795,24 +795,22 @@ static irqreturn_t menelaus_irq(int irq, void *_menelaus)
> >  {
> >  	struct menelaus_chip *menelaus = _menelaus;
> >  	void (*handler)(struct menelaus_chip *menelaus);
> > -	unsigned isr;
> > +	unsigned long isr;
> > +	unsigned long i;
> >  
> >  	isr = (menelaus_read_reg(MENELAUS_INT_STATUS2)
> >  			& ~menelaus->mask2) << 8;
> >  	isr |= menelaus_read_reg(MENELAUS_INT_STATUS1)
> >  		& ~menelaus->mask1;
> >  
> > -	while (isr) {
> > -		int irq = fls(isr) - 1;
> > -		isr &= ~(1 << irq);
> > -
> > +	for_each_set_bit(i, &isr, 16) {
> >  		mutex_lock(&menelaus->lock);
> > -		menelaus_disable_irq(irq);
> > -		menelaus_ack_irq(irq);
> > -		handler = menelaus->handlers[irq];
> > +		menelaus_disable_irq(i);
> > +		menelaus_ack_irq(i);
> > +		handler = menelaus->handlers[i];
> >  		if (handler)
> >  			handler(menelaus);
> > -		menelaus_enable_irq(irq);
> > +		menelaus_enable_irq(i);
> >  		mutex_unlock(&menelaus->lock);
> >  	}
> >  
> 
> This could handle the irqs in reverse order.
> Does that matter?

order does not matter with this device.

-- 
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/20131216/1dc6fd72/attachment-0001.sig>

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

* [PATCH 07/10] mfd: menelaus: Start to use irqdomain
  2013-12-17  0:08     ` [PATCH 07/10] mfd: menelaus: Start to use irqdomain Felipe Balbi
@ 2013-12-17 10:32       ` Lee Jones
  0 siblings, 0 replies; 73+ messages in thread
From: Lee Jones @ 2013-12-17 10:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 16 Dec 2013, Felipe Balbi wrote:

> Introduce an irq_chip and irq_domain for menelaus driver. Following
> patches will convert uses to traditional request_threaded_irq().
> 
> While at that, some better error handling had to be added, so we could
> free irq descs we allocated.
> 
> Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> Signed-off-by: Felipe Balbi <balbi@ti.com>
> ---
>  drivers/mfd/menelaus.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 119 insertions(+), 4 deletions(-)
> 

<snip>

> +static void menelaus_irq_ack(struct irq_data *data)
> +{
> +	struct menelaus_chip *m = irq_data_get_irq_chip_data(data);
> +	int irq = data->irq - m->irq_base;

Shoudn't this now be?
  int irq = data->hwirq;

> +	if (irq > 7) {
> +		m->ack2 |= BIT(irq);
> +		m->ack2_pending = true;
> +	} else {
> +		m->ack1 |= BIT(irq);
> +		m->ack1_pending = true;
> +	}
> +}
> +
> +static void menelaus_irq_mask(struct irq_data *data)
> +{
> +	struct menelaus_chip *m = irq_data_get_irq_chip_data(data);
> +	int irq = data->irq - m->irq_base;

Same for here, and all the others.

<snip>

> +	irq_domain_add_legacy(node, MENELAUS_NR_IRQS, irq_base, 0,
> +			&irq_domain_simple_ops, m);

Please use irq_domain_add_simple() here.

> +	m->irq_base = irq_base;

I don't think you need this.

> +	for (i = irq_base; i < irq_base + MENELAUS_NR_IRQS; i++) {
> +		irq_set_chip_data(i, m);
> +		irq_set_chip_and_handler(i, &menelaus_irq_chip,
> +				handle_simple_irq);
> +		irq_set_nested_thread(i, 1);
> +		set_irq_flags(i, IRQF_VALID);
> +	}

You should put this in the .map() operation and the reverse in .unmap().

>  fail:
> +	irq_free_descs(irq_base, MENELAUS_NR_IRQS);

I don't think you need to do this.

>  
>  static int menelaus_remove(struct i2c_client *client)
>  {
> +	struct menelaus_chip	*m = i2c_get_clientdata(client);
> +
> +	irq_free_descs(m->irq_base, MENELAUS_NR_IRQS);

Nor here.

>  	the_menelaus = NULL;

Shouldn't this have been removed in patch 6?

>  	return 0;
>  }
>  

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* [PATCH 08/10] mfd: menelaus: Switch all children to threaded_irq
  2013-12-17  0:08     ` [PATCH 08/10] mfd: menelaus: Switch all children to threaded_irq Felipe Balbi
@ 2013-12-17 10:35       ` Lee Jones
  0 siblings, 0 replies; 73+ messages in thread
From: Lee Jones @ 2013-12-17 10:35 UTC (permalink / raw)
  To: linux-arm-kernel

> Now that we have our own irq_chip, all children can use traditional
> request_threaded_irq().

Is it possible to convert these to managed resources (*_devm)?

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

end of thread, other threads:[~2013-12-17 10:35 UTC | newest]

Thread overview: 73+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-03  3:42 [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Felipe Balbi
2013-12-03  3:42 ` [PATCH v2 02/15] mfd: menelaus: Switch over to module_i2c_driver Felipe Balbi
2013-12-03  3:42 ` [PATCH v2 03/15] mfd: menelaus: Convert to threaded irq Felipe Balbi
2013-12-03  3:42 ` [PATCH v2 04/15] mfd: menelaus: Remove unnecessary loop Felipe Balbi
2013-12-03  3:42 ` [PATCH v2 05/15] mfd: menelaus: Use for_each_set_bit() Felipe Balbi
2013-12-03  3:42 ` [PATCH v2 06/15] mfd: menelaus: Pass menelaus pointer as argument to enable/disable irq Felipe Balbi
2013-12-03  3:43 ` [PATCH v2 07/15] mfd: menelaus: Limit the usage of the_menelaus Felipe Balbi
2013-12-03  3:43 ` [PATCH v2 08/15] mfd: menelaus: Pass menelaus_chip pointer to add/remove irq functions Felipe Balbi
2013-12-03  3:43 ` [PATCH v2 09/15] mfd: menelaus: Pass menelaus_chip pointer to get/set voltage Felipe Balbi
2013-12-03  3:43 ` [PATCH v2 10/15] mfd: menelaus: Pass menelaus_chip argument to menelaus <-> time helpers Felipe Balbi
2013-12-03  3:43 ` [PATCH v2 11/15] mfd: menelaus: Start to use irqdomain Felipe Balbi
2013-12-03  3:43 ` [PATCH v2 12/15] mfd: menelaus: Switch all children to threaded_irq Felipe Balbi
2013-12-03  3:43 ` [PATCH v2 13/15] mfd: menelaus: Remove unnecessary definition Felipe Balbi
2013-12-03  3:43 ` [PATCH v2 14/15] mfd: menelaus: IRQ is a requirement Felipe Balbi
2013-12-03  3:43 ` [PATCH v2 15/15] mfd: menelaus: Use devm_request_threaded_irq() Felipe Balbi
2013-12-03  9:51 ` [PATCH v2 01/15] mfd: menelaus: Drop __exit section annotation Lee Jones
2013-12-03  9:53   ` Lee Jones
2013-12-08 19:07   ` Felipe Balbi
2013-12-09  9:37     ` Lee Jones
2013-12-09 16:14       ` Felipe Balbi
2013-12-09 16:21         ` [PATCH v3 " Felipe Balbi
2013-12-09 16:21           ` [PATCH v3 02/15] mfd: menelaus: Switch over to module_i2c_driver Felipe Balbi
2013-12-09 16:21           ` [PATCH v3 03/15] mfd: menelaus: Convert to threaded irq Felipe Balbi
2013-12-10  9:32             ` Lee Jones
2013-12-10 16:31               ` Felipe Balbi
2013-12-09 16:21           ` [PATCH v3 04/15] mfd: menelaus: Remove unnecessary loop Felipe Balbi
2013-12-09 16:21           ` [PATCH v3 05/15] mfd: menelaus: Use for_each_set_bit() Felipe Balbi
2013-12-09 16:21           ` [PATCH v3 06/15] mfd: menelaus: Pass menelaus pointer as argument to enable/disable irq Felipe Balbi
2013-12-09 16:21           ` [PATCH v3 07/15] mfd: menelaus: Limit the usage of the_menelaus Felipe Balbi
2013-12-10  8:57             ` Lee Jones
2013-12-10 16:32               ` Felipe Balbi
2013-12-11  9:17                 ` Lee Jones
2013-12-09 16:21           ` [PATCH v3 08/15] mfd: menelaus: Pass menelaus_chip pointer to add/remove irq functions Felipe Balbi
2013-12-10  9:00             ` Lee Jones
2013-12-10 16:32               ` Felipe Balbi
2013-12-10 18:42                 ` Lee Jones
2013-12-09 16:21           ` [PATCH v3 09/15] mfd: menelaus: Pass menelaus_chip pointer to get/set voltage Felipe Balbi
2013-12-10  9:01             ` Lee Jones
2013-12-09 16:21           ` [PATCH v3 10/15] mfd: menelaus: Pass menelaus_chip argument to menelaus <-> time helpers Felipe Balbi
2013-12-10  9:02             ` Lee Jones
2013-12-09 16:21           ` [PATCH v3 11/15] mfd: menelaus: Start to use irqdomain Felipe Balbi
2013-12-10  9:20             ` Lee Jones
2013-12-10 16:34               ` Felipe Balbi
2013-12-10 18:37                 ` Lee Jones
2013-12-10 18:46                   ` Tony Lindgren
2013-12-11  9:06                     ` Lee Jones
2013-12-09 16:21           ` [PATCH v3 12/15] mfd: menelaus: Switch all children to threaded_irq Felipe Balbi
2013-12-09 16:21           ` [PATCH v3 13/15] mfd: menelaus: Remove unnecessary definition Felipe Balbi
2013-12-09 16:21           ` [PATCH v3 14/15] mfd: menelaus: IRQ is a requirement Felipe Balbi
2013-12-09 16:21           ` [PATCH v3 15/15] mfd: menelaus: Use devm_request_threaded_irq() Felipe Balbi
2013-12-10  9:30             ` Lee Jones
2013-12-10 16:34               ` Felipe Balbi
2013-12-10 18:32                 ` Lee Jones
2013-12-11  9:48           ` [PATCH v3 01/15] mfd: menelaus: Drop __exit section annotation Uwe Kleine-König
2013-12-10  8:50         ` [PATCH v2 " Lee Jones
2013-12-10 16:36           ` Felipe Balbi
2013-12-06 13:41 ` Aaro Koskinen
2013-12-11  9:44 ` Uwe Kleine-König
2013-12-16 15:39 ` Lee Jones
2013-12-17  0:08   ` [PATCH 01/10] " Felipe Balbi
2013-12-17  0:08     ` [PATCH 02/10] mfd: menelaus: Switch over to module_i2c_driver Felipe Balbi
2013-12-17  0:08     ` [PATCH 03/10] mfd: menelaus: Convert to threaded irq Felipe Balbi
2013-12-17  0:08     ` [PATCH 04/10] mfd: menelaus: Remove unnecessary loop Felipe Balbi
2013-12-17  0:08     ` [PATCH 05/10] mfd: menelaus: Use for_each_set_bit() Felipe Balbi
2013-12-17  0:17       ` Joe Perches
2013-12-17  0:19         ` Felipe Balbi
2013-12-17  0:08     ` [PATCH 06/10] mfd: menelaus: Limit the usage of the_menelaus Felipe Balbi
2013-12-17  0:08     ` [PATCH 07/10] mfd: menelaus: Start to use irqdomain Felipe Balbi
2013-12-17 10:32       ` Lee Jones
2013-12-17  0:08     ` [PATCH 08/10] mfd: menelaus: Switch all children to threaded_irq Felipe Balbi
2013-12-17 10:35       ` Lee Jones
2013-12-17  0:08     ` [PATCH 09/10] mfd: menelaus: Remove unnecessary definition Felipe Balbi
2013-12-17  0:08     ` [PATCH 10/10] mfd: menelaus: IRQ is a requirement Felipe Balbi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).