* [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 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 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 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 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 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 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 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 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 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 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 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 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 " 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 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 " 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 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 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 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 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 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 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 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 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 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-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 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 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 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 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 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 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 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 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 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
* [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
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).