i2c: omap: few more patches
Subsystems (4)
cover i2c: omap: few more patches
Just a few extra patches on top of the earlier series I sent.
With these patches, we have threaded irq support and autosuspend support for i2c-omap driver.
All patches boot tested with pandaboard.
Felipe Balbi (4):
i2c: omap: always return IRQ_HANDLED
i2c: omap: switch to threaded IRQ support
i2c: omap: remove unnecessary pm_runtime_suspended check
i2c: omap: switch over to autosuspend API
drivers/i2c/busses/i2c-omap.c | 53 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 11 deletions(-)
Signature · 1 line
1.7.12.rc0
PATCH 1/4 i2c: omap: always return IRQ_HANDLED
even if our clocks are disabled, we still
handled the IRQ, so we should return IRQ_HANDLED.
--- drivers/i2c/busses/i2c-omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i2c/busses/i2c-omap.c +1 -1
@@ -862,7 +862,7 @@ omap_i2c_isr(int this_irq, void *dev_id)int err =0 , count =0 ;if (pm_runtime_suspended (dev->dev)) -return IRQ_NONE ; +return IRQ_HANDLED ; do { bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
Signature · 1 line
1.7.12.rc0
PATCH 2/4 i2c: omap: switch to threaded IRQ support
In reply to Felipe Balbifor OMAP2, we can easily switch over to threaded
IRQs on the I2C driver. This will allow us to
spend less time in hardirq context.
--- drivers/i2c/busses/i2c-omap.c | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-)
drivers/i2c/busses/i2c-omap.c +36 -6
@@ -176,6 +176,7 @@ enum {#define I2C_OMAP_ERRATA_I462 (1 << 1)struct omap_i2c_dev { +spinlock_t lock;/* IRQ synchronization */ struct device *dev;void __iomem *base;/* virtual */ int irq;
@@ -854,9 +855,30 @@ static int omap_i2c_transmit_data(struct omap_i2c_dev *dev, u8 num_bytes, }static irqreturn_t -omap_i2c_isr (int this_irq,void *dev_id) +omap_i2c_isr (int irq,void *dev_id) {struct omap_i2c_dev *dev = dev_id; +irqreturn_t ret =IRQ_HANDLED ; +u16 mask; +u16 stat; + +spin_lock (&dev->lock); + mask =omap_i2c_read_reg (dev,OMAP_I2C_IE_REG ); + stat =omap_i2c_read_reg (dev,OMAP_I2C_STAT_REG ); + +if (stat & mask) + ret =IRQ_WAKE_THREAD ; + +spin_unlock (&dev->lock); + +return ret; +} + +static irqreturn_t +omap_i2c_isr_thread (int this_irq,void *dev_id) +{ +struct omap_i2c_dev *dev = dev_id; +unsigned long flags;u16 bits;u16 stat;int err =0 , count =0 ;
@@ -864,6 +886,7 @@ omap_i2c_isr(int this_irq, void *dev_id)if (pm_runtime_suspended (dev->dev))return IRQ_HANDLED ; +spin_lock_irqsave (&dev->lock, flags); do { bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
@@ -877,6 +900,7 @@ omap_i2c_isr(int this_irq, void *dev_id)if (!stat) {/* my work here is done */ +spin_unlock_irqrestore (&dev->lock, flags);return IRQ_HANDLED ; }
@@ -985,6 +1009,8 @@ omap_i2c_isr(int this_irq, void *dev_id) out:omap_i2c_complete_cmd (dev, err); +spin_unlock_irqrestore (&dev->lock, flags); +return IRQ_HANDLED ; }
@@ -1028,7 +1054,6 @@ omap_i2c_probe(struct platform_device *pdev)struct omap_i2c_bus_platform_data *pdata = pdev->dev.platform_data;struct device_node *node = pdev->dev.of_node;const struct of_device_id *match; -irq_handler_t isr;int irq;int r;
@@ -1078,6 +1103,8 @@ omap_i2c_probe(struct platform_device *pdev) dev->dev = &pdev->dev; dev->irq = irq; +spin_lock_init (&dev->lock); +platform_set_drvdata (pdev, dev);init_completion (&dev->cmd_complete);
@@ -1130,10 +1157,13 @@ omap_i2c_probe(struct platform_device *pdev)/* reset ASAP, clearing any IRQs */ omap_i2c_init (dev); - isr = (dev->rev <OMAP_I2C_OMAP1_REV_2 ) ? omap_i2c_omap1_isr : - omap_i2c_isr; - r =devm_request_irq (&pdev->dev, dev->irq, isr,IRQF_NO_SUSPEND , - pdev->name, dev); +if (dev->rev <OMAP_I2C_OMAP1_REV_2 ) + r =devm_request_irq (&pdev->dev, dev->irq, omap_i2c_omap1_isr, +IRQF_NO_SUSPEND , pdev->name, dev); +else + r =devm_request_threaded_irq (&pdev->dev, dev->irq, omap_i2c_isr, + omap_i2c_isr_thread,IRQF_NO_SUSPEND |IRQF_ONESHOT , + pdev->name, dev);if (r) {dev_err (dev->dev,"failure requesting irq %i\n" , dev->irq);
Signature · 1 line
1.7.12.rc0
PATCH 3/4 i2c: omap: remove unnecessary pm_runtime_suspended check
In reply to Felipe Balbibefore starting any messages we call pm_runtime_get_sync() which will make sure that by the time we program a transfer and our IRQ handler gets called, we're not suspended anymore.
--- drivers/i2c/busses/i2c-omap.c | 3 --- 1 file changed, 3 deletions(-)
drivers/i2c/busses/i2c-omap.c +0 -3
@@ -883,9 +883,6 @@ omap_i2c_isr_thread(int this_irq, void *dev_id)u16 stat;int err =0 , count =0 ; -if (pm_runtime_suspended (dev->dev)) -return IRQ_HANDLED ; -spin_lock_irqsave (&dev->lock, flags); do { bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
Signature · 1 line
1.7.12.rc0
PATCH 4/4 i2c: omap: switch over to autosuspend API
In reply to Felipe Balbithis helps us reduce unnecessary pm transitions
in case we have another i2c message been started
soon.
--- drivers/i2c/busses/i2c-omap.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/i2c/busses/i2c-omap.c +6 -2
@@ -645,7 +645,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)omap_i2c_wait_for_bb (dev); out: -pm_runtime_put (dev->dev); +pm_runtime_mark_last_busy (dev->dev); +pm_runtime_put_autosuspend (dev->dev);return r; }
@@ -1113,6 +1114,9 @@ omap_i2c_probe(struct platform_device *pdev) dev->regs = (u8 *)reg_map_ip_v1;pm_runtime_enable (dev->dev); +pm_runtime_set_autosuspend_delay (dev->dev,1000 ); +pm_runtime_use_autosuspend (dev->dev); + r =pm_runtime_get_sync (dev->dev);if (IS_ERR_VALUE (r)) goto err_free_mem;
@@ -1189,7 +1193,7 @@ omap_i2c_probe(struct platform_device *pdev)of_i2c_register_devices (adap); -pm_runtime_put (dev->dev); +pm_runtime_put_autosuspend (dev->dev);return 0 ;
Signature · 1 line
1.7.12.rc0
PATCH 4/4 i2c: omap: switch over to autosuspend API
Hi Felipe,
Quoted 34 lines · Felipe Balbi
this helps us reduce unnecessary pm transitions
in case we have another i2c message been started
soon.Signed-off-by Felipe Balbi <[email protected]>--- drivers/i2c/busses/i2c-omap.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)drivers/i2c/busses/i2c-omap.c +5
-1@@ -645,7 +645,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)omap_i2c_wait_for_bb (dev); out: -pm_runtime_put (dev->dev); +pm_runtime_mark_last_busy (dev->dev); +pm_runtime_put_autosuspend (dev->dev);return r; }@@ -1113,6 +1114,9 @@ omap_i2c_probe(struct platform_device *pdev) dev->regs = (u8 *)reg_map_ip_v1;pm_runtime_enable (dev->dev); +pm_runtime_set_autosuspend_delay (dev->dev,1000 ); +pm_runtime_use_autosuspend (dev->dev); + r =pm_runtime_get_sync (dev->dev);if (IS_ERR_VALUE (r)) goto err_free_mem;
drivers/i2c/busses/i2c-omap.c omap_i2c_probe(struct platform_device *pdev) · line 1192
Quoted 4 lines
drivers/i2c/busses/i2c-omap.c +0
-1@@ -1189,7 +1193,7 @@ omap_i2c_probe(struct platform_device *pdev)of_i2c_register_devices (adap); -pm_runtime_put (dev->dev);
Should we mark it last busy stamp here here? Or it may not take effect till the first transaction.
Quoted 4 lines
drivers/i2c/busses/i2c-omap.c +1
-0+pm_runtime_put_autosuspend (dev->dev);return 0 ;
PATCH 4/4 i2c: omap: switch over to autosuspend API
In reply to Felipe BalbiHi,
Quoted 34 lines · Felipe Balbi
this helps us reduce unnecessary pm transitions
in case we have another i2c message been started
soon.Signed-off-by Felipe Balbi <[email protected]>--- drivers/i2c/busses/i2c-omap.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)drivers/i2c/busses/i2c-omap.c +5
-1@@ -645,7 +645,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)omap_i2c_wait_for_bb (dev); out: -pm_runtime_put (dev->dev); +pm_runtime_mark_last_busy (dev->dev); +pm_runtime_put_autosuspend (dev->dev);return r; }@@ -1113,6 +1114,9 @@ omap_i2c_probe(struct platform_device *pdev) dev->regs = (u8 *)reg_map_ip_v1;pm_runtime_enable (dev->dev); +pm_runtime_set_autosuspend_delay (dev->dev,1000 ); +pm_runtime_use_autosuspend (dev->dev); + r =pm_runtime_get_sync (dev->dev);if (IS_ERR_VALUE (r)) goto err_free_mem;
drivers/i2c/busses/i2c-omap.c omap_i2c_probe(struct platform_device *pdev) · line 1196
Quoted 5 lines
drivers/i2c/busses/i2c-omap.c +1
-1@@ -1189,7 +1193,7 @@ omap_i2c_probe(struct platform_device *pdev)of_i2c_register_devices (adap); -pm_runtime_put (dev->dev); +pm_runtime_put_autosuspend (dev->dev);
Probably... nice catch. Will send v2
Signature · 8 lines
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/20120807/c737c871/attachment.sig>
PATCH 1/1 i2c: omap: switch over to autosuspend API
this helps us reduce unnecessary pm transitions
in case we have another i2c message been started
soon.
--- drivers/i2c/busses/i2c-omap.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/i2c/busses/i2c-omap.c +7 -2
@@ -645,7 +645,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)omap_i2c_wait_for_bb (dev); out: -pm_runtime_put (dev->dev); +pm_runtime_mark_last_busy (dev->dev); +pm_runtime_put_autosuspend (dev->dev);return r; }
@@ -1113,6 +1114,9 @@ omap_i2c_probe(struct platform_device *pdev) dev->regs = (u8 *)reg_map_ip_v1;pm_runtime_enable (dev->dev); +pm_runtime_set_autosuspend_delay (dev->dev,1000 ); +pm_runtime_use_autosuspend (dev->dev); + r =pm_runtime_get_sync (dev->dev);if (IS_ERR_VALUE (r)) goto err_free_mem;
@@ -1189,7 +1193,8 @@ omap_i2c_probe(struct platform_device *pdev)of_i2c_register_devices (adap); -pm_runtime_put (dev->dev); +pm_runtime_mark_last_busy (dev->dev); +pm_runtime_put_autosuspend (dev->dev);return 0 ;
Signature · 1 line
1.7.12.rc0
PATCH 1/1 i2c: omap: switch over to autosuspend API
Quoted 4 lines · Felipe
this helps us reduce unnecessary pm transitions
in case we have another i2c message been started
soon.
s/been started/starting ?
Quoted 20 lines
Signed-off-by Felipe Balbi <[email protected]>--- drivers/i2c/busses/i2c-omap.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)drivers/i2c/busses/i2c-omap.c +2
-1@@ -645,7 +645,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)omap_i2c_wait_for_bb (dev); out: -pm_runtime_put (dev->dev); +pm_runtime_mark_last_busy (dev->dev); +pm_runtime_put_autosuspend (dev->dev);return r; }
drivers/i2c/busses/i2c-omap.c omap_i2c_probe(struct platform_device *pdev) · line 1117
Quoted 4 lines
drivers/i2c/busses/i2c-omap.c +1
-0@@ -1113,6 +1114,9 @@ omap_i2c_probe(struct platform_device *pdev) dev->regs = (u8 *)reg_map_ip_v1;pm_runtime_enable (dev->dev); +pm_runtime_set_autosuspend_delay (dev->dev,1000 );
I guess there will always be a debate around what's the right delay for autosuspend ;)
You can at least replace the magic number with a macro.
Quoted 24 lines
drivers/i2c/busses/i2c-omap.c +4
-1+pm_runtime_use_autosuspend (dev->dev); + r =pm_runtime_get_sync (dev->dev);if (IS_ERR_VALUE (r)) goto err_free_mem;@@ -1189,7 +1193,8 @@ omap_i2c_probe(struct platform_device *pdev)of_i2c_register_devices (adap); -pm_runtime_put (dev->dev); +pm_runtime_mark_last_busy (dev->dev); +pm_runtime_put_autosuspend (dev->dev);return 0 ;Signature · 7 lines
1.7.12.rc0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel at lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH v3 1/1 i2c: omap: switch over to autosuspend API
this helps us reduce unnecessary pm transitions in case we have another i2c message starting soon.
--- drivers/i2c/busses/i2c-omap.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/i2c/busses/i2c-omap.c +10 -2
@@ -55,6 +55,9 @@/* timeout waiting for the controller to respond */ #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000)) +/* timeout for pm runtime autosuspend */ +#define OMAP_I2C_PM_TIMEOUT 1000/* ms */ +/* For OMAP3 I2C_IV has changed to I2C_WE (wakeup enable) */ enum {OMAP_I2C_REV_REG =0 ,
@@ -645,7 +648,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)omap_i2c_wait_for_bb (dev); out: -pm_runtime_put (dev->dev); +pm_runtime_mark_last_busy (dev->dev); +pm_runtime_put_autosuspend (dev->dev);return r; }
@@ -1113,6 +1117,9 @@ omap_i2c_probe(struct platform_device *pdev) dev->regs = (u8 *)reg_map_ip_v1;pm_runtime_enable (dev->dev); +pm_runtime_set_autosuspend_delay (dev->dev,OMAP_I2C_PM_TIMEOUT ); +pm_runtime_use_autosuspend (dev->dev); + r =pm_runtime_get_sync (dev->dev);if (IS_ERR_VALUE (r)) goto err_free_mem;
@@ -1189,7 +1196,8 @@ omap_i2c_probe(struct platform_device *pdev)of_i2c_register_devices (adap); -pm_runtime_put (dev->dev); +pm_runtime_mark_last_busy (dev->dev); +pm_runtime_put_autosuspend (dev->dev);return 0 ;
Signature · 1 line
1.7.12.rc0
PATCH v3 1/1 i2c: omap: switch over to autosuspend API
Quoted 4 lines · Felipe
this helps us reduce unnecessary pm transitions in case we have another i2c message starting soon.
Signed-off-by Felipe Balbi <[email protected]>
FWIW, Acked-by: Vaibhav Bedia <[email protected]>
cover i2c: omap: few more patches
In reply to Felipe BalbiQuoted 4 lines · Felipe Balbi
Just a few extra patches on top of the earlier series I sent.
With these patches, we have threaded irq support and autosuspend support for i2c-omap driver.
Thanks for the patches.
Quoted 2 lines
All patches boot tested with pandaboard.
On omap4sdp and omap3sdp
also on omap3 did some basic power testing.
Quoted 9 lines
Felipe Balbi (4):
i2c: omap: always returnIRQ_HANDLED
i2c: omap: switch to threaded IRQ support
i2c: omap: remove unnecessarypm_runtime_suspendedcheck
i2c: omap: switch over to autosuspend APIdrivers/i2c/busses/i2c-omap.c | 53 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 11 deletions(-)