* [PATCH 0/6] i2c: davinci updates for 2.6.35 @ 2010-04-06 17:42 Kevin Hilman [not found] ` <1270575738-22388-1-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> 2010-04-06 17:42 ` [PATCH 5/6] i2c: davinci: Add cpufreq support Kevin Hilman 0 siblings, 2 replies; 20+ messages in thread From: Kevin Hilman @ 2010-04-06 17:42 UTC (permalink / raw) To: linux-i2c-u79uwXL29TY76Z2rM5mHXA, Ben Dooks This series of davinci I2C driver updates and fixes is targetted for 2.6.35. It has been tested in davinci git on multiple davinci SoCs. Ben, since these changes are isolated to the davinci driver only, if you prefer I can merge them upstream along with my davinci changes for 2.6.35. This series is based on v2.6.34-rc3 Chaithrika U S (4): i2c: davinci: misc. cleanups: remove MOD_REG_BIT and IO_ADDRESS usage i2c: davinci: Add helper functions for power management i2c: davinci: Add suspend/resume support i2c: davinci: Add cpufreq support Dirk Behme (1): i2c: davinci: Fix smbus Oops with AIC33 usage Philby John (1): i2c: davinci: bus recovery procedure to clear the bus drivers/i2c/busses/i2c-davinci.c | 314 ++++++++++++++++++++++++++++++-------- 1 files changed, 251 insertions(+), 63 deletions(-) ^ permalink raw reply [flat|nested] 20+ messages in thread
[parent not found: <1270575738-22388-1-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org>]
* [PATCH 1/6] i2c: davinci: Fix smbus Oops with AIC33 usage [not found] ` <1270575738-22388-1-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> @ 2010-04-06 17:42 ` Kevin Hilman [not found] ` <1270575738-22388-2-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> 2010-04-06 17:42 ` [PATCH 2/6] i2c: davinci: misc. cleanups: remove MOD_REG_BIT and IO_ADDRESS usage Kevin Hilman ` (4 subsequent siblings) 5 siblings, 1 reply; 20+ messages in thread From: Kevin Hilman @ 2010-04-06 17:42 UTC (permalink / raw) To: linux-i2c-u79uwXL29TY76Z2rM5mHXA Cc: Dirk Behme, Sudhakar Rajashekhara, Alexander Vasiliev, Brad Griffis, Dirk Behme, Jean Delvare (PC drivers, core), Ben Dooks (embedded platforms), Kevin Hilman, Chaithrika U S, Philby John, Srinivasan, Nageswari, linux-kernel-u79uwXL29TY76Z2rM5mHXA From: Dirk Behme <dirk.behme-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> This fixes Oops at kernel startup while "scanning" for TLV320AIC23IDx addresses. Additional fix from Sudhakar Rajashekhara: I think 'first byte set' should come after the write because an I2C transaction is being carried out before configuring the I2C mode register (which has bits to configure Master, Start condition etc), which causes undefined behavior. Signed-off-by: Sudhakar Rajashekhara <sudhakar.raj-l0cyMroinI0@public.gmane.org> Signed-off-by: Alexander Vasiliev <alexvasiljev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> Signed-off-by: Brad Griffis <bgriffis-l0cyMroinI0@public.gmane.org> Signed-off-by: Dirk Behme <dirk.behme-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> Acked-by: Kevin Hilman <khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> --- drivers/i2c/busses/i2c-davinci.c | 31 +++++++++++++++++++++++++++---- 1 files changed, 27 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index c89687a..3b9ab23 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -112,6 +112,7 @@ struct davinci_i2c_dev { u8 *buf; size_t buf_len; int irq; + int stop; u8 terminate; struct i2c_adapter adapter; }; @@ -249,9 +250,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) u16 w; int r; - if (msg->len == 0) - return -EINVAL; - if (!pdata) pdata = &davinci_i2c_platform_data_default; /* Introduce a delay, required for some boards (e.g Davinci EVM) */ @@ -263,6 +261,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) dev->buf = msg->buf; dev->buf_len = msg->len; + dev->stop = stop; davinci_i2c_write_reg(dev, DAVINCI_I2C_CNT_REG, dev->buf_len); @@ -280,6 +279,10 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) flag |= DAVINCI_I2C_MDR_TRX; if (stop) flag |= DAVINCI_I2C_MDR_STP; + if (msg->len == 0) { + flag |= DAVINCI_I2C_MDR_RM; + flag &= ~DAVINCI_I2C_MDR_STP; + } /* Enable receive or transmit interrupts */ w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG); @@ -290,9 +293,21 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w); dev->terminate = 0; + /* write the data into mode register */ davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); + /* + * First byte should be set here, not after interrupt, + * because transmit-data-ready interrupt can come before + * NACK-interrupt during sending of previous message and + * ICDXR may have wrong data + */ + if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) { + davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++); + dev->buf_len--; + } + r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, dev->adapter.timeout); if (r == 0) { @@ -371,7 +386,7 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) static u32 i2c_davinci_func(struct i2c_adapter *adap) { - return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; } static void terminate_read(struct davinci_i2c_dev *dev) @@ -430,6 +445,14 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id) case DAVINCI_I2C_IVR_ARDY: davinci_i2c_write_reg(dev, DAVINCI_I2C_STR_REG, DAVINCI_I2C_STR_ARDY); + if (((dev->buf_len == 0) && (dev->stop != 0)) || + (dev->cmd_err & DAVINCI_I2C_STR_NACK)) { + w = davinci_i2c_read_reg(dev, + DAVINCI_I2C_MDR_REG); + w |= DAVINCI_I2C_MDR_STP; + davinci_i2c_write_reg(dev, + DAVINCI_I2C_MDR_REG, w); + } complete(&dev->cmd_complete); break; -- 1.7.0.2 ^ permalink raw reply related [flat|nested] 20+ messages in thread
[parent not found: <1270575738-22388-2-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org>]
* Re: [PATCH 1/6] i2c: davinci: Fix smbus Oops with AIC33 usage [not found] ` <1270575738-22388-2-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> @ 2010-04-20 0:05 ` Ben Dooks 0 siblings, 0 replies; 20+ messages in thread From: Ben Dooks @ 2010-04-20 0:05 UTC (permalink / raw) To: Kevin Hilman Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA, Ben Dooks, Dirk Behme, Sudhakar Rajashekhara, Alexander Vasiliev, Brad Griffis, Dirk Behme, Jean Delvare (PC drivers, core), Chaithrika U S, Philby John, Srinivasan, Nageswari, linux-kernel-u79uwXL29TY76Z2rM5mHXA On Tue, Apr 06, 2010 at 10:42:13AM -0700, Kevin Hilman wrote: > From: Dirk Behme <dirk.behme-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> > > This fixes Oops at kernel startup while "scanning" for TLV320AIC23IDx > addresses. this looks like it could be a candidate for -rc? > Additional fix from Sudhakar Rajashekhara: I think 'first byte set' > should come after the write because an I2C transaction is being > carried out before configuring the I2C mode register (which has bits > to configure Master, Start condition etc), which causes undefined > behavior. > > Signed-off-by: Sudhakar Rajashekhara <sudhakar.raj-l0cyMroinI0@public.gmane.org> > Signed-off-by: Alexander Vasiliev <alexvasiljev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > Signed-off-by: Brad Griffis <bgriffis-l0cyMroinI0@public.gmane.org> > Signed-off-by: Dirk Behme <dirk.behme-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > Acked-by: Kevin Hilman <khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> > --- > drivers/i2c/busses/i2c-davinci.c | 31 +++++++++++++++++++++++++++---- > 1 files changed, 27 insertions(+), 4 deletions(-) > > diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c > index c89687a..3b9ab23 100644 > --- a/drivers/i2c/busses/i2c-davinci.c > +++ b/drivers/i2c/busses/i2c-davinci.c > @@ -112,6 +112,7 @@ struct davinci_i2c_dev { > u8 *buf; > size_t buf_len; > int irq; > + int stop; > u8 terminate; > struct i2c_adapter adapter; > }; > @@ -249,9 +250,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) > u16 w; > int r; > > - if (msg->len == 0) > - return -EINVAL; > - > if (!pdata) > pdata = &davinci_i2c_platform_data_default; > /* Introduce a delay, required for some boards (e.g Davinci EVM) */ > @@ -263,6 +261,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) > > dev->buf = msg->buf; > dev->buf_len = msg->len; > + dev->stop = stop; > > davinci_i2c_write_reg(dev, DAVINCI_I2C_CNT_REG, dev->buf_len); > > @@ -280,6 +279,10 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) > flag |= DAVINCI_I2C_MDR_TRX; > if (stop) > flag |= DAVINCI_I2C_MDR_STP; > + if (msg->len == 0) { > + flag |= DAVINCI_I2C_MDR_RM; > + flag &= ~DAVINCI_I2C_MDR_STP; > + } > > /* Enable receive or transmit interrupts */ > w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG); > @@ -290,9 +293,21 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) > davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w); > > dev->terminate = 0; > + > /* write the data into mode register */ > davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); > > + /* > + * First byte should be set here, not after interrupt, > + * because transmit-data-ready interrupt can come before > + * NACK-interrupt during sending of previous message and > + * ICDXR may have wrong data > + */ > + if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) { > + davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++); > + dev->buf_len--; > + } > + > r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, > dev->adapter.timeout); > if (r == 0) { > @@ -371,7 +386,7 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) > > static u32 i2c_davinci_func(struct i2c_adapter *adap) > { > - return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); > + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; > } > > static void terminate_read(struct davinci_i2c_dev *dev) > @@ -430,6 +445,14 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id) > case DAVINCI_I2C_IVR_ARDY: > davinci_i2c_write_reg(dev, > DAVINCI_I2C_STR_REG, DAVINCI_I2C_STR_ARDY); > + if (((dev->buf_len == 0) && (dev->stop != 0)) || > + (dev->cmd_err & DAVINCI_I2C_STR_NACK)) { > + w = davinci_i2c_read_reg(dev, > + DAVINCI_I2C_MDR_REG); > + w |= DAVINCI_I2C_MDR_STP; > + davinci_i2c_write_reg(dev, > + DAVINCI_I2C_MDR_REG, w); > + } > complete(&dev->cmd_complete); > break; > > -- > 1.7.0.2 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-i2c" in > the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Ben (ben-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org, http://www.fluff.org/) 'a smiley only costs 4 bytes' ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 2/6] i2c: davinci: misc. cleanups: remove MOD_REG_BIT and IO_ADDRESS usage [not found] ` <1270575738-22388-1-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> 2010-04-06 17:42 ` [PATCH 1/6] i2c: davinci: Fix smbus Oops with AIC33 usage Kevin Hilman @ 2010-04-06 17:42 ` Kevin Hilman 2010-04-06 17:42 ` [PATCH 3/6] i2c: davinci: Add helper functions for power management Kevin Hilman ` (3 subsequent siblings) 5 siblings, 0 replies; 20+ messages in thread From: Kevin Hilman @ 2010-04-06 17:42 UTC (permalink / raw) To: linux-i2c-u79uwXL29TY76Z2rM5mHXA Cc: Chaithrika U S, Jean Delvare (PC drivers, core), Ben Dooks (embedded platforms), Kevin Hilman, Philby John, Srinivasan, Nageswari, linux-kernel-u79uwXL29TY76Z2rM5mHXA From: Chaithrika U S <chaithrika-l0cyMroinI0@public.gmane.org> Cleanup the DaVinci I2C driver. Remove MOD_REG_BIT macro. Also use ioremap instead of IO_ADDRESS macro. Signed-off-by: Chaithrika U S <chaithrika-l0cyMroinI0@public.gmane.org> Acked-by: Kevin Hilman <khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> --- drivers/i2c/busses/i2c-davinci.c | 77 +++++++++++++++++++------------------- 1 files changed, 38 insertions(+), 39 deletions(-) diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 3b9ab23..9327cc9 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -37,7 +37,6 @@ #include <linux/io.h> #include <mach/hardware.h> - #include <mach/i2c.h> /* ----- global defines ----------------------------------------------- */ @@ -71,37 +70,29 @@ #define DAVINCI_I2C_IVR_NACK 0x02 #define DAVINCI_I2C_IVR_AL 0x01 -#define DAVINCI_I2C_STR_BB (1 << 12) -#define DAVINCI_I2C_STR_RSFULL (1 << 11) -#define DAVINCI_I2C_STR_SCD (1 << 5) -#define DAVINCI_I2C_STR_ARDY (1 << 2) -#define DAVINCI_I2C_STR_NACK (1 << 1) -#define DAVINCI_I2C_STR_AL (1 << 0) - -#define DAVINCI_I2C_MDR_NACK (1 << 15) -#define DAVINCI_I2C_MDR_STT (1 << 13) -#define DAVINCI_I2C_MDR_STP (1 << 11) -#define DAVINCI_I2C_MDR_MST (1 << 10) -#define DAVINCI_I2C_MDR_TRX (1 << 9) -#define DAVINCI_I2C_MDR_XA (1 << 8) -#define DAVINCI_I2C_MDR_RM (1 << 7) -#define DAVINCI_I2C_MDR_IRS (1 << 5) - -#define DAVINCI_I2C_IMR_AAS (1 << 6) -#define DAVINCI_I2C_IMR_SCD (1 << 5) -#define DAVINCI_I2C_IMR_XRDY (1 << 4) -#define DAVINCI_I2C_IMR_RRDY (1 << 3) -#define DAVINCI_I2C_IMR_ARDY (1 << 2) -#define DAVINCI_I2C_IMR_NACK (1 << 1) -#define DAVINCI_I2C_IMR_AL (1 << 0) - -#define MOD_REG_BIT(val, mask, set) do { \ - if (set) { \ - val |= mask; \ - } else { \ - val &= ~mask; \ - } \ -} while (0) +#define DAVINCI_I2C_STR_BB BIT(12) +#define DAVINCI_I2C_STR_RSFULL BIT(11) +#define DAVINCI_I2C_STR_SCD BIT(5) +#define DAVINCI_I2C_STR_ARDY BIT(2) +#define DAVINCI_I2C_STR_NACK BIT(1) +#define DAVINCI_I2C_STR_AL BIT(0) + +#define DAVINCI_I2C_MDR_NACK BIT(15) +#define DAVINCI_I2C_MDR_STT BIT(13) +#define DAVINCI_I2C_MDR_STP BIT(11) +#define DAVINCI_I2C_MDR_MST BIT(10) +#define DAVINCI_I2C_MDR_TRX BIT(9) +#define DAVINCI_I2C_MDR_XA BIT(8) +#define DAVINCI_I2C_MDR_RM BIT(7) +#define DAVINCI_I2C_MDR_IRS BIT(5) + +#define DAVINCI_I2C_IMR_AAS BIT(6) +#define DAVINCI_I2C_IMR_SCD BIT(5) +#define DAVINCI_I2C_IMR_XRDY BIT(4) +#define DAVINCI_I2C_IMR_RRDY BIT(3) +#define DAVINCI_I2C_IMR_ARDY BIT(2) +#define DAVINCI_I2C_IMR_NACK BIT(1) +#define DAVINCI_I2C_IMR_AL BIT(0) struct davinci_i2c_dev { struct device *dev; @@ -155,7 +146,7 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) /* put I2C into reset */ w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); - MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, 0); + w &= ~DAVINCI_I2C_MDR_IRS; davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); /* NOTE: I2C Clock divider programming info @@ -205,7 +196,7 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) /* Take the I2C module out of reset: */ w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); - MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, 1); + w |= DAVINCI_I2C_MDR_IRS; davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); /* Enable interrupts */ @@ -287,9 +278,9 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) /* Enable receive or transmit interrupts */ w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG); if (msg->flags & I2C_M_RD) - MOD_REG_BIT(w, DAVINCI_I2C_IMR_RRDY, 1); + w |= DAVINCI_I2C_IMR_RRDY; else - MOD_REG_BIT(w, DAVINCI_I2C_IMR_XRDY, 1); + w |= DAVINCI_I2C_IMR_XRDY; davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w); dev->terminate = 0; @@ -348,7 +339,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) return msg->len; if (stop) { w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); - MOD_REG_BIT(w, DAVINCI_I2C_MDR_STP, 1); + w |= DAVINCI_I2C_MDR_STP; davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); } return -EREMOTEIO; @@ -484,7 +475,7 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id) w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG); - MOD_REG_BIT(w, DAVINCI_I2C_IMR_XRDY, 0); + w &= ~DAVINCI_I2C_IMR_XRDY; davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w); @@ -563,7 +554,12 @@ static int davinci_i2c_probe(struct platform_device *pdev) } clk_enable(dev->clk); - dev->base = (void __iomem *)IO_ADDRESS(mem->start); + dev->base = ioremap(mem->start, resource_size(mem)); + if (!dev->base) { + r = -EBUSY; + goto err_mem_ioremap; + } + i2c_davinci_init(dev); r = request_irq(dev->irq, i2c_davinci_isr, 0, pdev->name, dev); @@ -593,6 +589,8 @@ static int davinci_i2c_probe(struct platform_device *pdev) err_free_irq: free_irq(dev->irq, dev); err_unuse_clocks: + iounmap(dev->base); +err_mem_ioremap: clk_disable(dev->clk); clk_put(dev->clk); dev->clk = NULL; @@ -621,6 +619,7 @@ static int davinci_i2c_remove(struct platform_device *pdev) davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, 0); free_irq(IRQ_I2C, dev); + iounmap(dev->base); kfree(dev); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- 1.7.0.2 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 3/6] i2c: davinci: Add helper functions for power management [not found] ` <1270575738-22388-1-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> 2010-04-06 17:42 ` [PATCH 1/6] i2c: davinci: Fix smbus Oops with AIC33 usage Kevin Hilman 2010-04-06 17:42 ` [PATCH 2/6] i2c: davinci: misc. cleanups: remove MOD_REG_BIT and IO_ADDRESS usage Kevin Hilman @ 2010-04-06 17:42 ` Kevin Hilman 2010-04-06 17:42 ` [PATCH 4/6] i2c: davinci: Add suspend/resume support Kevin Hilman ` (2 subsequent siblings) 5 siblings, 0 replies; 20+ messages in thread From: Kevin Hilman @ 2010-04-06 17:42 UTC (permalink / raw) To: linux-i2c-u79uwXL29TY76Z2rM5mHXA Cc: Chaithrika U S, Jean Delvare (PC drivers, core), Ben Dooks (embedded platforms), Kevin Hilman, Philby John, Srinivasan, Nageswari, linux-kernel-u79uwXL29TY76Z2rM5mHXA From: Chaithrika U S <chaithrika-l0cyMroinI0@public.gmane.org> Add i2c reset control and clock divider calculation functions which will be useful for power management features. Signed-off-by: Chaithrika U S <chaithrika-l0cyMroinI0@public.gmane.org> Acked-by: Kevin Hilman <khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> --- drivers/i2c/busses/i2c-davinci.c | 56 +++++++++++++++++++++++++------------- 1 files changed, 37 insertions(+), 19 deletions(-) diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 9327cc9..9239d2b 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -125,12 +125,21 @@ static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg) return __raw_readw(i2c_dev->base + reg); } -/* - * This functions configures I2C and brings I2C out of reset. - * This function is called during I2C init function. This function - * also gets called if I2C encounters any errors. - */ -static int i2c_davinci_init(struct davinci_i2c_dev *dev) +static inline void davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev, + int val) +{ + u16 w; + + w = davinci_i2c_read_reg(i2c_dev, DAVINCI_I2C_MDR_REG); + if (!val) /* put I2C into reset */ + w &= ~DAVINCI_I2C_MDR_IRS; + else /* take I2C out of reset */ + w |= DAVINCI_I2C_MDR_IRS; + + davinci_i2c_write_reg(i2c_dev, DAVINCI_I2C_MDR_REG, w); +} + +static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev) { struct davinci_i2c_platform_data *pdata = dev->dev->platform_data; u16 psc; @@ -139,15 +148,6 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) u32 clkh; u32 clkl; u32 input_clock = clk_get_rate(dev->clk); - u16 w; - - if (!pdata) - pdata = &davinci_i2c_platform_data_default; - - /* put I2C into reset */ - w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); - w &= ~DAVINCI_I2C_MDR_IRS; - davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); /* NOTE: I2C Clock divider programming info * As per I2C specs the following formulas provide prescaler @@ -179,12 +179,32 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKH_REG, clkh); davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKL_REG, clkl); + dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk); +} + +/* + * This function configures I2C and brings I2C out of reset. + * This function is called during I2C init function. This function + * also gets called if I2C encounters any errors. + */ +static int i2c_davinci_init(struct davinci_i2c_dev *dev) +{ + struct davinci_i2c_platform_data *pdata = dev->dev->platform_data; + + if (!pdata) + pdata = &davinci_i2c_platform_data_default; + + /* put I2C into reset */ + davinci_i2c_reset_ctrl(dev, 0); + + /* compute clock dividers */ + i2c_davinci_calc_clk_dividers(dev); + /* Respond at reserved "SMBus Host" slave address" (and zero); * we seem to have no option to not respond... */ davinci_i2c_write_reg(dev, DAVINCI_I2C_OAR_REG, 0x08); - dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk); dev_dbg(dev->dev, "PSC = %d\n", davinci_i2c_read_reg(dev, DAVINCI_I2C_PSC_REG)); dev_dbg(dev->dev, "CLKL = %d\n", @@ -195,9 +215,7 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) pdata->bus_freq, pdata->bus_delay); /* Take the I2C module out of reset: */ - w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); - w |= DAVINCI_I2C_MDR_IRS; - davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); + davinci_i2c_reset_ctrl(dev, 1); /* Enable interrupts */ davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, I2C_DAVINCI_INTR_ALL); -- 1.7.0.2 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 4/6] i2c: davinci: Add suspend/resume support [not found] ` <1270575738-22388-1-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> ` (2 preceding siblings ...) 2010-04-06 17:42 ` [PATCH 3/6] i2c: davinci: Add helper functions for power management Kevin Hilman @ 2010-04-06 17:42 ` Kevin Hilman 2010-04-06 17:42 ` [PATCH 6/6] i2c: davinci: bus recovery procedure to clear the bus Kevin Hilman 2010-04-20 0:06 ` [PATCH 0/6] i2c: davinci updates for 2.6.35 Ben Dooks 5 siblings, 0 replies; 20+ messages in thread From: Kevin Hilman @ 2010-04-06 17:42 UTC (permalink / raw) To: linux-i2c-u79uwXL29TY76Z2rM5mHXA Cc: Chaithrika U S, Jean Delvare (PC drivers, core), Ben Dooks (embedded platforms), Kevin Hilman, Philby John, Srinivasan, Nageswari, linux-kernel-u79uwXL29TY76Z2rM5mHXA From: Chaithrika U S <chaithrika-l0cyMroinI0@public.gmane.org> Add suspend and resume callbacks to DaVinci I2C driver. This has been tested on DA850/OMAP-L138 EVM. Signed-off-by: Chaithrika U S <chaithrika-l0cyMroinI0@public.gmane.org> Acked-by: Kevin Hilman <khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> --- drivers/i2c/busses/i2c-davinci.c | 36 ++++++++++++++++++++++++++++++++++++ 1 files changed, 36 insertions(+), 0 deletions(-) diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 9239d2b..dfec296 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -645,6 +645,41 @@ static int davinci_i2c_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +static int davinci_i2c_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct davinci_i2c_dev *i2c_dev = platform_get_drvdata(pdev); + + /* put I2C into reset */ + davinci_i2c_reset_ctrl(i2c_dev, 0); + clk_disable(i2c_dev->clk); + + return 0; +} + +static int davinci_i2c_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct davinci_i2c_dev *i2c_dev = platform_get_drvdata(pdev); + + clk_enable(i2c_dev->clk); + /* take I2C out of reset */ + davinci_i2c_reset_ctrl(i2c_dev, 1); + + return 0; +} + +static const struct dev_pm_ops davinci_i2c_pm = { + .suspend = davinci_i2c_suspend, + .resume = davinci_i2c_resume, +}; + +#define davinci_i2c_pm_ops (&davinci_i2c_pm) +#else +#define davinci_i2c_pm_ops NULL +#endif + /* work with hotplug and coldplug */ MODULE_ALIAS("platform:i2c_davinci"); @@ -654,6 +689,7 @@ static struct platform_driver davinci_i2c_driver = { .driver = { .name = "i2c_davinci", .owner = THIS_MODULE, + .pm = davinci_i2c_pm_ops, }, }; -- 1.7.0.2 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 6/6] i2c: davinci: bus recovery procedure to clear the bus [not found] ` <1270575738-22388-1-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> ` (3 preceding siblings ...) 2010-04-06 17:42 ` [PATCH 4/6] i2c: davinci: Add suspend/resume support Kevin Hilman @ 2010-04-06 17:42 ` Kevin Hilman 2010-04-20 0:06 ` [PATCH 0/6] i2c: davinci updates for 2.6.35 Ben Dooks 5 siblings, 0 replies; 20+ messages in thread From: Kevin Hilman @ 2010-04-06 17:42 UTC (permalink / raw) To: linux-i2c-u79uwXL29TY76Z2rM5mHXA Cc: Philby John, Srinivasan, Nageswari, Jean Delvare (PC drivers, core), Ben Dooks (embedded platforms), Kevin Hilman, Chaithrika U S, linux-kernel-u79uwXL29TY76Z2rM5mHXA From: Philby John <pjohn-k0rHJ+Hhz/SB+jHODAdFcQ@public.gmane.org> Come out of i2c time out condition by following the bus recovery procedure outlined in the i2c protocol v3 spec. The kernel must be robust enough to gracefully recover from i2c bus failure without having to reset the machine. This is done by first NACKing the slave, pulsing the SCL line 9 times and then sending the stop command. This patch has been tested on a DM6446 and DM355 Signed-off-by: Philby John <pjohn-k0rHJ+Hhz/SB+jHODAdFcQ@public.gmane.org> Signed-off-by: Srinivasan, Nageswari <nageswari-l0cyMroinI0@public.gmane.org> Acked-by: Kevin Hilman <khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> --- drivers/i2c/busses/i2c-davinci.c | 57 +++++++++++++++++++++++++++++++++++-- 1 files changed, 53 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index fd7a155..0f71a7e 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -36,6 +36,7 @@ #include <linux/platform_device.h> #include <linux/io.h> #include <linux/cpufreq.h> +#include <linux/gpio.h> #include <mach/hardware.h> #include <mach/i2c.h> @@ -43,6 +44,7 @@ /* ----- global defines ----------------------------------------------- */ #define DAVINCI_I2C_TIMEOUT (1*HZ) +#define DAVINCI_I2C_MAX_TRIES 2 #define I2C_DAVINCI_INTR_ALL (DAVINCI_I2C_IMR_AAS | \ DAVINCI_I2C_IMR_SCD | \ DAVINCI_I2C_IMR_ARDY | \ @@ -130,6 +132,44 @@ static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg) return __raw_readw(i2c_dev->base + reg); } +/* Generate a pulse on the i2c clock pin. */ +static void generic_i2c_clock_pulse(unsigned int scl_pin) +{ + u16 i; + + if (scl_pin) { + /* Send high and low on the SCL line */ + for (i = 0; i < 9; i++) { + gpio_set_value(scl_pin, 0); + udelay(20); + gpio_set_value(scl_pin, 1); + udelay(20); + } + } +} + +/* This routine does i2c bus recovery as specified in the + * i2c protocol Rev. 03 section 3.16 titled "Bus clear" + */ +static void i2c_recover_bus(struct davinci_i2c_dev *dev) +{ + u32 flag = 0; + struct davinci_i2c_platform_data *pdata = dev->dev->platform_data; + + dev_err(dev->dev, "initiating i2c bus recovery\n"); + /* Send NACK to the slave */ + flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); + flag |= DAVINCI_I2C_MDR_NACK; + /* write the data into mode register */ + davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); + if (pdata) + generic_i2c_clock_pulse(pdata->scl_pin); + /* Send STOP */ + flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); + flag |= DAVINCI_I2C_MDR_STP; + davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); +} + static inline void davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev, int val) { @@ -235,14 +275,22 @@ static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev, char allow_sleep) { unsigned long timeout; + static u16 to_cnt; timeout = jiffies + dev->adapter.timeout; while (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG) & DAVINCI_I2C_STR_BB) { - if (time_after(jiffies, timeout)) { - dev_warn(dev->dev, - "timeout waiting for bus ready\n"); - return -ETIMEDOUT; + if (to_cnt <= DAVINCI_I2C_MAX_TRIES) { + if (time_after(jiffies, timeout)) { + dev_warn(dev->dev, + "timeout waiting for bus ready\n"); + to_cnt++; + return -ETIMEDOUT; + } else { + to_cnt = 0; + i2c_recover_bus(dev); + i2c_davinci_init(dev); + } } if (allow_sleep) schedule_timeout(1); @@ -326,6 +374,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) dev->adapter.timeout); if (r == 0) { dev_err(dev->dev, "controller timed out\n"); + i2c_recover_bus(dev); i2c_davinci_init(dev); dev->buf_len = 0; return -ETIMEDOUT; -- 1.7.0.2 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 0/6] i2c: davinci updates for 2.6.35 [not found] ` <1270575738-22388-1-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> ` (4 preceding siblings ...) 2010-04-06 17:42 ` [PATCH 6/6] i2c: davinci: bus recovery procedure to clear the bus Kevin Hilman @ 2010-04-20 0:06 ` Ben Dooks [not found] ` <20100420000621.GK32401-elnMNo+KYs3pIgCt6eIbzw@public.gmane.org> 5 siblings, 1 reply; 20+ messages in thread From: Ben Dooks @ 2010-04-20 0:06 UTC (permalink / raw) To: Kevin Hilman; +Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA, Ben Dooks On Tue, Apr 06, 2010 at 10:42:12AM -0700, Kevin Hilman wrote: > This series of davinci I2C driver updates and fixes is targetted for > 2.6.35. It has been tested in davinci git on multiple davinci SoCs. > > Ben, since these changes are isolated to the davinci driver only, if > you prefer I can merge them upstream along with my davinci changes for > 2.6.35. I'll get them into -next when I rebase it. The first in the series could be a -rc candidate as it looks like a useful bugfix? > This series is based on v2.6.34-rc3 > > Chaithrika U S (4): > i2c: davinci: misc. cleanups: remove MOD_REG_BIT and IO_ADDRESS usage > i2c: davinci: Add helper functions for power management > i2c: davinci: Add suspend/resume support > i2c: davinci: Add cpufreq support > > Dirk Behme (1): > i2c: davinci: Fix smbus Oops with AIC33 usage > > Philby John (1): > i2c: davinci: bus recovery procedure to clear the bus > > drivers/i2c/busses/i2c-davinci.c | 314 ++++++++++++++++++++++++++++++-------- > 1 files changed, 251 insertions(+), 63 deletions(-) > > -- > To unsubscribe from this list: send the line "unsubscribe linux-i2c" in > the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Ben (ben-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org, http://www.fluff.org/) 'a smiley only costs 4 bytes' ^ permalink raw reply [flat|nested] 20+ messages in thread
[parent not found: <20100420000621.GK32401-elnMNo+KYs3pIgCt6eIbzw@public.gmane.org>]
* Re: [PATCH 0/6] i2c: davinci updates for 2.6.35 [not found] ` <20100420000621.GK32401-elnMNo+KYs3pIgCt6eIbzw@public.gmane.org> @ 2010-04-20 13:55 ` Kevin Hilman 2010-06-21 20:16 ` Kevin Hilman 1 sibling, 0 replies; 20+ messages in thread From: Kevin Hilman @ 2010-04-20 13:55 UTC (permalink / raw) To: Ben Dooks; +Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA Ben Dooks <ben-linux-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org> writes: > On Tue, Apr 06, 2010 at 10:42:12AM -0700, Kevin Hilman wrote: >> This series of davinci I2C driver updates and fixes is targetted for >> 2.6.35. It has been tested in davinci git on multiple davinci SoCs. >> >> Ben, since these changes are isolated to the davinci driver only, if >> you prefer I can merge them upstream along with my davinci changes for >> 2.6.35. > > I'll get them into -next when I rebase it. The first in the series > could be a -rc candidate as it looks like a useful bugfix? Yeah, the first could be a bugfix, but at this point, I'd just prefer to keep them all together and get them merged for 2.6.35. Thanks, Kevin ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 0/6] i2c: davinci updates for 2.6.35 [not found] ` <20100420000621.GK32401-elnMNo+KYs3pIgCt6eIbzw@public.gmane.org> 2010-04-20 13:55 ` Kevin Hilman @ 2010-06-21 20:16 ` Kevin Hilman [not found] ` <AANLkTikJ6XDywcBA5O0mC85jQEIWxZ9NOALIQOjcGCDJ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 1 sibling, 1 reply; 20+ messages in thread From: Kevin Hilman @ 2010-06-21 20:16 UTC (permalink / raw) To: Ben Dooks; +Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA On Mon, Apr 19, 2010 at 5:06 PM, Ben Dooks <ben-linux-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org> wrote: > On Tue, Apr 06, 2010 at 10:42:12AM -0700, Kevin Hilman wrote: >> This series of davinci I2C driver updates and fixes is targetted for >> 2.6.35. It has been tested in davinci git on multiple davinci SoCs. >> >> Ben, since these changes are isolated to the davinci driver only, if >> you prefer I can merge them upstream along with my davinci changes for >> 2.6.35. > > I'll get them into -next when I rebase it. Ben, this series never made it in for 2.6.35. I've now rebased this against v2.6.35-rc3 and it's available here: git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci.git davinci-i2c Please pull for 2.6.36. Thanks. Kevin >> This series is based on v2.6.34-rc3 >> >> Chaithrika U S (4): >> i2c: davinci: misc. cleanups: remove MOD_REG_BIT and IO_ADDRESS usage >> i2c: davinci: Add helper functions for power management >> i2c: davinci: Add suspend/resume support >> i2c: davinci: Add cpufreq support >> >> Dirk Behme (1): >> i2c: davinci: Fix smbus Oops with AIC33 usage >> >> Philby John (1): >> i2c: davinci: bus recovery procedure to clear the bus >> >> drivers/i2c/busses/i2c-davinci.c | 314 ++++++++++++++++++++++++++++++-------- >> 1 files changed, 251 insertions(+), 63 deletions(-) >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-i2c" in >> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html > > -- > Ben (ben-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org, http://www.fluff.org/) > > 'a smiley only costs 4 bytes' > ^ permalink raw reply [flat|nested] 20+ messages in thread
[parent not found: <AANLkTikJ6XDywcBA5O0mC85jQEIWxZ9NOALIQOjcGCDJ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>]
* Re: [PATCH 0/6] i2c: davinci updates for 2.6.35 [not found] ` <AANLkTikJ6XDywcBA5O0mC85jQEIWxZ9NOALIQOjcGCDJ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> @ 2010-08-10 15:56 ` Kevin Hilman [not found] ` <AANLkTinNXxzCoH+b3=xA92sW8GCqqO4iY+_yVwBFLMqG-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 0 siblings, 1 reply; 20+ messages in thread From: Kevin Hilman @ 2010-08-10 15:56 UTC (permalink / raw) To: Ben Dooks Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r Ben, On Mon, Jun 21, 2010 at 1:16 PM, Kevin Hilman <khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> wrote: > On Mon, Apr 19, 2010 at 5:06 PM, Ben Dooks <ben-linux-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org> wrote: >> On Tue, Apr 06, 2010 at 10:42:12AM -0700, Kevin Hilman wrote: >>> This series of davinci I2C driver updates and fixes is targetted for >>> 2.6.35. It has been tested in davinci git on multiple davinci SoCs. >>> >>> Ben, since these changes are isolated to the davinci driver only, if >>> you prefer I can merge them upstream along with my davinci changes for >>> 2.6.35. >> >> I'll get them into -next when I rebase it. > > Ben, this series never made it in for 2.6.35. > > I've now rebased this against v2.6.35-rc3 and it's available here: > > git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci.git > davinci-i2c > > Please pull for 2.6.36. Thanks. OK, it's now been two merge windows that these have been ignored/forgotten. Can you let me know what is the plan for these? If you're too busy, I'd be happy to merge them via davinci git with your ack if that helps take some load off you. Either way, it would be nice to know what to do. If you want to pull, the branch has been rebased against v2.6.35 and is available here: git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci.git davinci-i2c Thanks, Kevin ^ permalink raw reply [flat|nested] 20+ messages in thread
[parent not found: <AANLkTinNXxzCoH+b3=xA92sW8GCqqO4iY+_yVwBFLMqG-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>]
* Re: [PATCH 0/6] i2c: davinci updates for 2.6.35 [not found] ` <AANLkTinNXxzCoH+b3=xA92sW8GCqqO4iY+_yVwBFLMqG-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> @ 2010-08-10 23:44 ` Ben Dooks 0 siblings, 0 replies; 20+ messages in thread From: Ben Dooks @ 2010-08-10 23:44 UTC (permalink / raw) To: Kevin Hilman Cc: Ben Dooks, linux-i2c-u79uwXL29TY76Z2rM5mHXA, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r On Tue, Aug 10, 2010 at 08:56:27AM -0700, Kevin Hilman wrote: > Ben, > > On Mon, Jun 21, 2010 at 1:16 PM, Kevin Hilman > <khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> wrote: > > On Mon, Apr 19, 2010 at 5:06 PM, Ben Dooks <ben-linux-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org> wrote: > >> On Tue, Apr 06, 2010 at 10:42:12AM -0700, Kevin Hilman wrote: > >>> This series of davinci I2C driver updates and fixes is targetted for > >>> 2.6.35. It has been tested in davinci git on multiple davinci SoCs. > >>> > >>> Ben, since these changes are isolated to the davinci driver only, if > >>> you prefer I can merge them upstream along with my davinci changes for > >>> 2.6.35. > >> > >> I'll get them into -next when I rebase it. > > > > Ben, this series never made it in for 2.6.35. > > > > I've now rebased this against v2.6.35-rc3 and it's available here: > > > > git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci.git > > davinci-i2c > > > > Please pull for 2.6.36. Thanks. > > OK, it's now been two merge windows that these have been > ignored/forgotten. Can you let me know what is the plan for these? pulled into current i2c-next, will send in the next day or so. -- Ben Q: What's a light-year? A: One-third less calories than a regular year. ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 5/6] i2c: davinci: Add cpufreq support 2010-04-06 17:42 [PATCH 0/6] i2c: davinci updates for 2.6.35 Kevin Hilman [not found] ` <1270575738-22388-1-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> @ 2010-04-06 17:42 ` Kevin Hilman 1 sibling, 0 replies; 20+ messages in thread From: Kevin Hilman @ 2010-04-06 17:42 UTC (permalink / raw) To: linux-i2c Cc: Chaithrika U S, Jean Delvare (PC drivers, core), Ben Dooks (embedded platforms), Kevin Hilman, Philby John, Srinivasan, Nageswari, linux-kernel From: Chaithrika U S <chaithrika@ti.com> Add cpufreq support for DaVinci I2C driver. Tested on DA850/OMAP-L138 EVM. Signed-off-by: Chaithrika U S <chaithrika@ti.com> Acked-by: Kevin Hilman <khilman@deeprootsystems.com> --- drivers/i2c/busses/i2c-davinci.c | 63 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 63 insertions(+), 0 deletions(-) diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index dfec296..fd7a155 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -35,6 +35,7 @@ #include <linux/interrupt.h> #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/cpufreq.h> #include <mach/hardware.h> #include <mach/i2c.h> @@ -106,6 +107,10 @@ struct davinci_i2c_dev { int stop; u8 terminate; struct i2c_adapter adapter; +#ifdef CONFIG_CPU_FREQ + struct completion xfr_complete; + struct notifier_block freq_transition; +#endif }; /* default platform data to use if not supplied in the platform_device */ @@ -390,6 +395,11 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) if (ret < 0) return ret; } + +#ifdef CONFIG_CPU_FREQ + complete(&dev->xfr_complete); +#endif + return num; } @@ -522,6 +532,48 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id) return count ? IRQ_HANDLED : IRQ_NONE; } +#ifdef CONFIG_CPU_FREQ +static int i2c_davinci_cpufreq_transition(struct notifier_block *nb, + unsigned long val, void *data) +{ + struct davinci_i2c_dev *dev; + + dev = container_of(nb, struct davinci_i2c_dev, freq_transition); + if (val == CPUFREQ_PRECHANGE) { + wait_for_completion(&dev->xfr_complete); + davinci_i2c_reset_ctrl(dev, 0); + } else if (val == CPUFREQ_POSTCHANGE) { + i2c_davinci_calc_clk_dividers(dev); + davinci_i2c_reset_ctrl(dev, 1); + } + + return 0; +} + +static inline int i2c_davinci_cpufreq_register(struct davinci_i2c_dev *dev) +{ + dev->freq_transition.notifier_call = i2c_davinci_cpufreq_transition; + + return cpufreq_register_notifier(&dev->freq_transition, + CPUFREQ_TRANSITION_NOTIFIER); +} + +static inline void i2c_davinci_cpufreq_deregister(struct davinci_i2c_dev *dev) +{ + cpufreq_unregister_notifier(&dev->freq_transition, + CPUFREQ_TRANSITION_NOTIFIER); +} +#else +static inline int i2c_davinci_cpufreq_register(struct davinci_i2c_dev *dev) +{ + return 0; +} + +static inline void i2c_davinci_cpufreq_deregister(struct davinci_i2c_dev *dev) +{ +} +#endif + static struct i2c_algorithm i2c_davinci_algo = { .master_xfer = i2c_davinci_xfer, .functionality = i2c_davinci_func, @@ -561,6 +613,9 @@ static int davinci_i2c_probe(struct platform_device *pdev) } init_completion(&dev->cmd_complete); +#ifdef CONFIG_CPU_FREQ + init_completion(&dev->xfr_complete); +#endif dev->dev = get_device(&pdev->dev); dev->irq = irq->start; platform_set_drvdata(pdev, dev); @@ -586,6 +641,12 @@ static int davinci_i2c_probe(struct platform_device *pdev) goto err_unuse_clocks; } + r = i2c_davinci_cpufreq_register(dev); + if (r) { + dev_err(&pdev->dev, "failed to register cpufreq\n"); + goto err_free_irq; + } + adap = &dev->adapter; i2c_set_adapdata(adap, dev); adap->owner = THIS_MODULE; @@ -627,6 +688,8 @@ static int davinci_i2c_remove(struct platform_device *pdev) struct davinci_i2c_dev *dev = platform_get_drvdata(pdev); struct resource *mem; + i2c_davinci_cpufreq_deregister(dev); + platform_set_drvdata(pdev, NULL); i2c_del_adapter(&dev->adapter); put_device(&pdev->dev); -- 1.7.0.2 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 0/6] davinci i2c updates for 2.6.34 @ 2010-01-26 23:41 Kevin Hilman [not found] ` <1264549293-25556-1-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> 0 siblings, 1 reply; 20+ messages in thread From: Kevin Hilman @ 2010-01-26 23:41 UTC (permalink / raw) To: Ben Dooks Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA, davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/ This series ia a set of proposed I2C updates for the DaVinci platform for 2.6.34. These have been tested and approved as part of the DaVinci tree. Note that patch 6 has a dependency on changes to the DaVinci core so is has been agreed to be merged it via davinci git. Ben, upon successful review, please let me know if you'd like me to merge the others via davinci git as well. Thanks, Kevin Chaithrika U S (4): i2c: davinci: Remove MOD_REG_BIT and IO_ADDRESS usage i2c: davinci: Add helper functions i2c: davinci: Add suspend/resume support i2c: davinci: Add cpufreq support Dirk Behme (1): i2c: davinci: Fix smbus Oops with AIC33 usage Philby John (1): i2c: davinci: bus recovery procedure to clear the bus drivers/i2c/busses/i2c-davinci.c | 312 ++++++++++++++++++++++++++++++-------- 1 files changed, 249 insertions(+), 63 deletions(-) ^ permalink raw reply [flat|nested] 20+ messages in thread
[parent not found: <1264549293-25556-1-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org>]
* [PATCH 1/6] i2c: davinci: Fix smbus Oops with AIC33 usage [not found] ` <1264549293-25556-1-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> @ 2010-01-26 23:41 ` Kevin Hilman [not found] ` <1264549293-25556-2-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> [not found] ` <026601ca9f54$17a18110$46e48330$@raj@ti.com> 0 siblings, 2 replies; 20+ messages in thread From: Kevin Hilman @ 2010-01-26 23:41 UTC (permalink / raw) To: Ben Dooks Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA, davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/, Dirk Behme, Alexander Vasiliev, Brad Griffis, Dirk Behme From: Dirk Behme <dirk.behme-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> This fixes Oops at kernel startup while "scanning" for TLV320AIC23IDx addresses. Signed-off-by: Alexander Vasiliev <alexvasiljev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> Signed-off-by: Brad Griffis <bgriffis-l0cyMroinI0@public.gmane.org> Signed-off-by: Dirk Behme <dirk.behme-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> Acked-by: Kevin Hilman <khilman-Igf4POYTYCDQT0dZR+AlfA@public.gmane.org> --- drivers/i2c/busses/i2c-davinci.c | 29 +++++++++++++++++++++++++---- 1 files changed, 25 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index c89687a..444a9f2 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -112,6 +112,7 @@ struct davinci_i2c_dev { u8 *buf; size_t buf_len; int irq; + int stop; u8 terminate; struct i2c_adapter adapter; }; @@ -249,9 +250,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) u16 w; int r; - if (msg->len == 0) - return -EINVAL; - if (!pdata) pdata = &davinci_i2c_platform_data_default; /* Introduce a delay, required for some boards (e.g Davinci EVM) */ @@ -263,6 +261,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) dev->buf = msg->buf; dev->buf_len = msg->len; + dev->stop = stop; davinci_i2c_write_reg(dev, DAVINCI_I2C_CNT_REG, dev->buf_len); @@ -280,6 +279,10 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) flag |= DAVINCI_I2C_MDR_TRX; if (stop) flag |= DAVINCI_I2C_MDR_STP; + if (msg->len == 0) { + flag |= DAVINCI_I2C_MDR_RM; + flag &= ~DAVINCI_I2C_MDR_STP; + } /* Enable receive or transmit interrupts */ w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG); @@ -290,6 +293,16 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w); dev->terminate = 0; + + /* First byte should be set here, not after interrupt, + * because transmit-data-ready interrupt can come before + * NACK-interrupt during sending of previous message and + * ICDXR may have wrong data */ + if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) { + davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++); + dev->buf_len--; + } + /* write the data into mode register */ davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); @@ -371,7 +384,7 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) static u32 i2c_davinci_func(struct i2c_adapter *adap) { - return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; } static void terminate_read(struct davinci_i2c_dev *dev) @@ -430,6 +443,14 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id) case DAVINCI_I2C_IVR_ARDY: davinci_i2c_write_reg(dev, DAVINCI_I2C_STR_REG, DAVINCI_I2C_STR_ARDY); + if (((dev->buf_len == 0) && (dev->stop != 0)) || + (dev->cmd_err & DAVINCI_I2C_STR_NACK)) { + w = davinci_i2c_read_reg(dev, + DAVINCI_I2C_MDR_REG); + w |= DAVINCI_I2C_MDR_STP; + davinci_i2c_write_reg(dev, + DAVINCI_I2C_MDR_REG, w); + } complete(&dev->cmd_complete); break; -- 1.6.6 ^ permalink raw reply related [flat|nested] 20+ messages in thread
[parent not found: <1264549293-25556-2-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org>]
* RE: [PATCH 1/6] i2c: davinci: Fix smbus Oops with AIC33 usage [not found] ` <1264549293-25556-2-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> @ 2010-01-27 13:24 ` Sudhakar Rajashekhara 2010-01-27 15:03 ` Ben Dooks 1 sibling, 0 replies; 20+ messages in thread From: Sudhakar Rajashekhara @ 2010-01-27 13:24 UTC (permalink / raw) To: 'Kevin Hilman', 'Ben Dooks' Cc: davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/, linux-i2c-u79uwXL29TY76Z2rM5mHXA, 'Dirk Behme', 'Alexander Vasiliev' Hi, On Wed, Jan 27, 2010 at 05:11:28, Kevin Hilman wrote: > From: Dirk Behme <dirk.behme-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> > > This fixes Oops at kernel startup while "scanning" for TLV320AIC23IDx > addresses. > > Signed-off-by: Alexander Vasiliev <alexvasiljev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > Signed-off-by: Brad Griffis <bgriffis-l0cyMroinI0@public.gmane.org> > Signed-off-by: Dirk Behme <dirk.behme-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > Acked-by: Kevin Hilman <khilman-Igf4POYTYCDQT0dZR+AlfA@public.gmane.org> > --- > drivers/i2c/busses/i2c-davinci.c | 29 +++++++++++++++++++++++++---- > 1 files changed, 25 insertions(+), 4 deletions(-) > > diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c > index c89687a..444a9f2 100644 > --- a/drivers/i2c/busses/i2c-davinci.c > +++ b/drivers/i2c/busses/i2c-davinci.c [...] > @@ -290,6 +293,16 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) > davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w); > > dev->terminate = 0; > + > + /* First byte should be set here, not after interrupt, > + * because transmit-data-ready interrupt can come before > + * NACK-interrupt during sending of previous message and > + * ICDXR may have wrong data */ > + if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) { > + davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++); > + dev->buf_len--; > + } > + I found an issue on DA850 while using this patch. I think the above code should come after the below lines because an I2C transaction is being carried out before configuring the I2C mode register (which has bits to configure Master, Start condition etc), which causes undefined behavior. > /* write the data into mode register */ > davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); > Regards, Sudhakar ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/6] i2c: davinci: Fix smbus Oops with AIC33 usage [not found] ` <1264549293-25556-2-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> 2010-01-27 13:24 ` Sudhakar Rajashekhara @ 2010-01-27 15:03 ` Ben Dooks 1 sibling, 0 replies; 20+ messages in thread From: Ben Dooks @ 2010-01-27 15:03 UTC (permalink / raw) To: Kevin Hilman Cc: Ben Dooks, linux-i2c-u79uwXL29TY76Z2rM5mHXA, davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/, Dirk Behme, Alexander Vasiliev, Brad Griffis, Dirk Behme On Tue, Jan 26, 2010 at 03:41:28PM -0800, Kevin Hilman wrote: > From: Dirk Behme <dirk.behme-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> > > This fixes Oops at kernel startup while "scanning" for TLV320AIC23IDx > addresses. > > Signed-off-by: Alexander Vasiliev <alexvasiljev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > Signed-off-by: Brad Griffis <bgriffis-l0cyMroinI0@public.gmane.org> > Signed-off-by: Dirk Behme <dirk.behme-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > Acked-by: Kevin Hilman <khilman-Igf4POYTYCDQT0dZR+AlfA@public.gmane.org> > --- > drivers/i2c/busses/i2c-davinci.c | 29 +++++++++++++++++++++++++---- > 1 files changed, 25 insertions(+), 4 deletions(-) > > diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c > index c89687a..444a9f2 100644 > --- a/drivers/i2c/busses/i2c-davinci.c > +++ b/drivers/i2c/busses/i2c-davinci.c > @@ -112,6 +112,7 @@ struct davinci_i2c_dev { > u8 *buf; > size_t buf_len; > int irq; > + int stop; > u8 terminate; > struct i2c_adapter adapter; > }; > @@ -249,9 +250,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) > u16 w; > int r; > > - if (msg->len == 0) > - return -EINVAL; > - > if (!pdata) > pdata = &davinci_i2c_platform_data_default; > /* Introduce a delay, required for some boards (e.g Davinci EVM) */ > @@ -263,6 +261,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) > > dev->buf = msg->buf; > dev->buf_len = msg->len; > + dev->stop = stop; > > davinci_i2c_write_reg(dev, DAVINCI_I2C_CNT_REG, dev->buf_len); > > @@ -280,6 +279,10 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) > flag |= DAVINCI_I2C_MDR_TRX; > if (stop) > flag |= DAVINCI_I2C_MDR_STP; > + if (msg->len == 0) { > + flag |= DAVINCI_I2C_MDR_RM; > + flag &= ~DAVINCI_I2C_MDR_STP; > + } > > /* Enable receive or transmit interrupts */ > w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG); > @@ -290,6 +293,16 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) > davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w); > > dev->terminate = 0; > + > + /* First byte should be set here, not after interrupt, > + * because transmit-data-ready interrupt can come before > + * NACK-interrupt during sending of previous message and > + * ICDXR may have wrong data */ > + if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) { > + davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++); > + dev->buf_len--; > + } > + > /* write the data into mode register */ > davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); > > @@ -371,7 +384,7 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) > > static u32 i2c_davinci_func(struct i2c_adapter *adap) > { > - return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); > + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; > } > > static void terminate_read(struct davinci_i2c_dev *dev) > @@ -430,6 +443,14 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id) > case DAVINCI_I2C_IVR_ARDY: > davinci_i2c_write_reg(dev, > DAVINCI_I2C_STR_REG, DAVINCI_I2C_STR_ARDY); > + if (((dev->buf_len == 0) && (dev->stop != 0)) || technically you don't need () around simple tests... > + (dev->cmd_err & DAVINCI_I2C_STR_NACK)) { > + w = davinci_i2c_read_reg(dev, > + DAVINCI_I2C_MDR_REG); > + w |= DAVINCI_I2C_MDR_STP; > + davinci_i2c_write_reg(dev, > + DAVINCI_I2C_MDR_REG, w); > + } > complete(&dev->cmd_complete); > break; > > -- > 1.6.6 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-i2c" in > the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Ben (ben-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org, http://www.fluff.org/) 'a smiley only costs 4 bytes' ^ permalink raw reply [flat|nested] 20+ messages in thread
[parent not found: <026601ca9f54$17a18110$46e48330$@raj@ti.com>]
[parent not found: <026601ca9f54$17a18110$46e48330$@raj-l0cyMroinI0@public.gmane.org>]
* Re: [PATCH 1/6] i2c: davinci: Fix smbus Oops with AIC33 usage [not found] ` <026601ca9f54$17a18110$46e48330$@raj-l0cyMroinI0@public.gmane.org> @ 2010-01-27 14:50 ` Kevin Hilman [not found] ` <87k4v3y53z.fsf-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> [not found] ` <02ee01ca9ff6$53cf0d90$fb6d28b0$@raj@ti.com> 0 siblings, 2 replies; 20+ messages in thread From: Kevin Hilman @ 2010-01-27 14:50 UTC (permalink / raw) To: Sudhakar Rajashekhara Cc: 'Ben Dooks', davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/, 'Dirk Behme', linux-i2c-u79uwXL29TY76Z2rM5mHXA, 'Alexander Vasiliev' "Sudhakar Rajashekhara" <sudhakar.raj-l0cyMroinI0@public.gmane.org> writes: > Hi, > > On Wed, Jan 27, 2010 at 05:11:28, Kevin Hilman wrote: >> From: Dirk Behme <dirk.behme-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> >> >> This fixes Oops at kernel startup while "scanning" for TLV320AIC23IDx >> addresses. >> >> Signed-off-by: Alexander Vasiliev <alexvasiljev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> >> Signed-off-by: Brad Griffis <bgriffis-l0cyMroinI0@public.gmane.org> >> Signed-off-by: Dirk Behme <dirk.behme-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> >> Acked-by: Kevin Hilman <khilman-Igf4POYTYCDQT0dZR+AlfA@public.gmane.org> >> --- >> drivers/i2c/busses/i2c-davinci.c | 29 +++++++++++++++++++++++++---- >> 1 files changed, 25 insertions(+), 4 deletions(-) >> >> diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c >> index c89687a..444a9f2 100644 >> --- a/drivers/i2c/busses/i2c-davinci.c >> +++ b/drivers/i2c/busses/i2c-davinci.c > > [...] > >> @@ -290,6 +293,16 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) >> davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w); >> >> dev->terminate = 0; >> + >> + /* First byte should be set here, not after interrupt, >> + * because transmit-data-ready interrupt can come before >> + * NACK-interrupt during sending of previous message and >> + * ICDXR may have wrong data */ >> + if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) { >> + davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++); >> + dev->buf_len--; >> + } >> + > > I found an issue on DA850 while using this patch. ok, I'll drop this one for 2.6.34 until we figure this out. > I think the above code should come after the > below lines because an I2C transaction is being carried out before configuring the I2C mode > register (which has bits to configure Master, Start condition etc), which causes undefined > behavior. hmm, are you seeing this behavior on davinci git too? This is the same patch that has been in davinci git for some time? Kevin > >> /* write the data into mode register */ >> davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); >> > > Regards, > Sudhakar ^ permalink raw reply [flat|nested] 20+ messages in thread
[parent not found: <87k4v3y53z.fsf-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org>]
* RE: [PATCH 1/6] i2c: davinci: Fix smbus Oops with AIC33 usage [not found] ` <87k4v3y53z.fsf-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> @ 2010-01-28 4:05 ` Sudhakar Rajashekhara 2010-01-28 8:46 ` Sudhakar Rajashekhara 1 sibling, 0 replies; 20+ messages in thread From: Sudhakar Rajashekhara @ 2010-01-28 4:05 UTC (permalink / raw) To: 'Kevin Hilman' Cc: 'Alexander Vasiliev', davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/, 'Dirk Behme', 'Ben Dooks', linux-i2c-u79uwXL29TY76Z2rM5mHXA On Wed, Jan 27, 2010 at 20:20:08, Kevin Hilman wrote: > "Sudhakar Rajashekhara" <sudhakar.raj-l0cyMroinI0@public.gmane.org> writes: > > > Hi, > > > > On Wed, Jan 27, 2010 at 05:11:28, Kevin Hilman wrote: > >> From: Dirk Behme <dirk.behme-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> > >> > >> This fixes Oops at kernel startup while "scanning" for TLV320AIC23IDx > >> addresses. > >> > >> Signed-off-by: Alexander Vasiliev <alexvasiljev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > >> Signed-off-by: Brad Griffis <bgriffis-l0cyMroinI0@public.gmane.org> > >> Signed-off-by: Dirk Behme <dirk.behme-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > >> Acked-by: Kevin Hilman <khilman-Igf4POYTYCDQT0dZR+AlfA@public.gmane.org> > >> --- > >> drivers/i2c/busses/i2c-davinci.c | 29 +++++++++++++++++++++++++---- > >> 1 files changed, 25 insertions(+), 4 deletions(-) > >> > >> diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c > >> index c89687a..444a9f2 100644 > >> --- a/drivers/i2c/busses/i2c-davinci.c > >> +++ b/drivers/i2c/busses/i2c-davinci.c > > > > [...] > > > >> @@ -290,6 +293,16 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) > >> davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w); > >> > >> dev->terminate = 0; > >> + > >> + /* First byte should be set here, not after interrupt, > >> + * because transmit-data-ready interrupt can come before > >> + * NACK-interrupt during sending of previous message and > >> + * ICDXR may have wrong data */ > >> + if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) { > >> + davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++); > >> + dev->buf_len--; > >> + } > >> + > > > > I found an issue on DA850 while using this patch. > > ok, I'll drop this one for 2.6.34 until we figure this out. > > > I think the above code should come after the > > below lines because an I2C transaction is being carried out before configuring the I2C mode > > register (which has bits to configure Master, Start condition etc), which causes undefined > > behavior. > > hmm, are you seeing this behavior on davinci git too? This is the same > patch that has been in davinci git for some time? > Yes, I am seeing this issue on davinci git. Regards, Sudhakar ^ permalink raw reply [flat|nested] 20+ messages in thread
* RE: [PATCH 1/6] i2c: davinci: Fix smbus Oops with AIC33 usage [not found] ` <87k4v3y53z.fsf-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> 2010-01-28 4:05 ` Sudhakar Rajashekhara @ 2010-01-28 8:46 ` Sudhakar Rajashekhara 1 sibling, 0 replies; 20+ messages in thread From: Sudhakar Rajashekhara @ 2010-01-28 8:46 UTC (permalink / raw) To: 'Kevin Hilman' Cc: 'Alexander Vasiliev', davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/, 'Dirk Behme', 'Ben Dooks', linux-i2c-u79uwXL29TY76Z2rM5mHXA Kevin, On Wed, Jan 27, 2010 at 20:20:08, Kevin Hilman wrote: > "Sudhakar Rajashekhara" <sudhakar.raj-l0cyMroinI0@public.gmane.org> writes: > > > Hi, > > > > On Wed, Jan 27, 2010 at 05:11:28, Kevin Hilman wrote: > >> From: Dirk Behme <dirk.behme-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> > >> > >> This fixes Oops at kernel startup while "scanning" for TLV320AIC23IDx > >> addresses. > >> > >> Signed-off-by: Alexander Vasiliev <alexvasiljev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > >> Signed-off-by: Brad Griffis <bgriffis-l0cyMroinI0@public.gmane.org> > >> Signed-off-by: Dirk Behme <dirk.behme-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > >> Acked-by: Kevin Hilman <khilman-Igf4POYTYCDQT0dZR+AlfA@public.gmane.org> > >> --- > >> drivers/i2c/busses/i2c-davinci.c | 29 +++++++++++++++++++++++++---- > >> 1 files changed, 25 insertions(+), 4 deletions(-) > >> > >> diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c > >> index c89687a..444a9f2 100644 > >> --- a/drivers/i2c/busses/i2c-davinci.c > >> +++ b/drivers/i2c/busses/i2c-davinci.c > > > > [...] > > > >> @@ -290,6 +293,16 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) > >> davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w); > >> > >> dev->terminate = 0; > >> + > >> + /* First byte should be set here, not after interrupt, > >> + * because transmit-data-ready interrupt can come before > >> + * NACK-interrupt during sending of previous message and > >> + * ICDXR may have wrong data */ > >> + if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) { > >> + davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++); > >> + dev->buf_len--; > >> + } > >> + > > > > I found an issue on DA850 while using this patch. > > ok, I'll drop this one for 2.6.34 until we figure this out. > > > I think the above code should come after the > > below lines because an I2C transaction is being carried out before configuring the I2C mode > > register (which has bits to configure Master, Start condition etc), which causes undefined > > behavior. > > hmm, are you seeing this behavior on davinci git too? This is the same > patch that has been in davinci git for some time? > The following patch fixes the issue I reported. I have tested it extensively on DA850/OMAP-L138. You can roll-in these changes into the current patch. Signed-off-by: Sudhakar Rajashekhara <sudhakar.raj-l0cyMroinI0@public.gmane.org> --- drivers/i2c/busses/i2c-davinci.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 35f9daa..8526bce 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -308,6 +308,9 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) dev->terminate = 0; + /* write the data into mode register */ + davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); + /* First byte should be set here, not after interrupt, * because transmit-data-ready interrupt can come before * NACK-interrupt during sending of previous message and @@ -317,9 +320,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) dev->buf_len--; } - /* write the data into mode register */ - davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); - r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, dev->adapter.timeout); if (r == 0) { -- Regards, Sudhakar ^ permalink raw reply related [flat|nested] 20+ messages in thread
[parent not found: <02ee01ca9ff6$53cf0d90$fb6d28b0$@raj@ti.com>]
[parent not found: <02ee01ca9ff6$53cf0d90$fb6d28b0$@raj-l0cyMroinI0@public.gmane.org>]
* Re: [PATCH 1/6] i2c: davinci: Fix smbus Oops with AIC33 usage [not found] ` <02ee01ca9ff6$53cf0d90$fb6d28b0$@raj-l0cyMroinI0@public.gmane.org> @ 2010-01-28 14:45 ` Kevin Hilman 0 siblings, 0 replies; 20+ messages in thread From: Kevin Hilman @ 2010-01-28 14:45 UTC (permalink / raw) To: Sudhakar Rajashekhara Cc: 'Alexander Vasiliev', davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/, 'Dirk Behme', 'Ben Dooks', linux-i2c-u79uwXL29TY76Z2rM5mHXA "Sudhakar Rajashekhara" <sudhakar.raj-l0cyMroinI0@public.gmane.org> writes: > Kevin, > > On Wed, Jan 27, 2010 at 20:20:08, Kevin Hilman wrote: >> "Sudhakar Rajashekhara" <sudhakar.raj-l0cyMroinI0@public.gmane.org> writes: >> >> > Hi, >> > >> > On Wed, Jan 27, 2010 at 05:11:28, Kevin Hilman wrote: >> >> From: Dirk Behme <dirk.behme-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> >> >> >> >> This fixes Oops at kernel startup while "scanning" for TLV320AIC23IDx >> >> addresses. >> >> >> >> Signed-off-by: Alexander Vasiliev <alexvasiljev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> >> >> Signed-off-by: Brad Griffis <bgriffis-l0cyMroinI0@public.gmane.org> >> >> Signed-off-by: Dirk Behme <dirk.behme-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> >> >> Acked-by: Kevin Hilman <khilman-Igf4POYTYCDQT0dZR+AlfA@public.gmane.org> >> >> --- >> >> drivers/i2c/busses/i2c-davinci.c | 29 +++++++++++++++++++++++++---- >> >> 1 files changed, 25 insertions(+), 4 deletions(-) >> >> >> >> diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c >> >> index c89687a..444a9f2 100644 >> >> --- a/drivers/i2c/busses/i2c-davinci.c >> >> +++ b/drivers/i2c/busses/i2c-davinci.c >> > >> > [...] >> > >> >> @@ -290,6 +293,16 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) >> >> davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w); >> >> >> >> dev->terminate = 0; >> >> + >> >> + /* First byte should be set here, not after interrupt, >> >> + * because transmit-data-ready interrupt can come before >> >> + * NACK-interrupt during sending of previous message and >> >> + * ICDXR may have wrong data */ >> >> + if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) { >> >> + davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++); >> >> + dev->buf_len--; >> >> + } >> >> + >> > >> > I found an issue on DA850 while using this patch. >> >> ok, I'll drop this one for 2.6.34 until we figure this out. >> >> > I think the above code should come after the >> > below lines because an I2C transaction is being carried out before configuring the I2C mode >> > register (which has bits to configure Master, Start condition etc), which causes undefined >> > behavior. >> >> hmm, are you seeing this behavior on davinci git too? This is the same >> patch that has been in davinci git for some time? >> > > The following patch fixes the issue I reported. I have tested it extensively on DA850/OMAP-L138. > You can roll-in these changes into the current patch. Thanks, I rolled it into the original, and updated the 'davinci-upstream-submitted' branch. Kevin > Signed-off-by: Sudhakar Rajashekhara <sudhakar.raj-l0cyMroinI0@public.gmane.org> > --- > drivers/i2c/busses/i2c-davinci.c | 6 +++--- > 1 files changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c > index 35f9daa..8526bce 100644 > --- a/drivers/i2c/busses/i2c-davinci.c > +++ b/drivers/i2c/busses/i2c-davinci.c > @@ -308,6 +308,9 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) > > dev->terminate = 0; > > + /* write the data into mode register */ > + davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); > + > /* First byte should be set here, not after interrupt, > * because transmit-data-ready interrupt can come before > * NACK-interrupt during sending of previous message and > @@ -317,9 +320,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) > dev->buf_len--; > } > > - /* write the data into mode register */ > - davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); > - > r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, > dev->adapter.timeout); > if (r == 0) { > -- > > Regards, > Sudhakar ^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2010-08-10 23:44 UTC | newest] Thread overview: 20+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-04-06 17:42 [PATCH 0/6] i2c: davinci updates for 2.6.35 Kevin Hilman [not found] ` <1270575738-22388-1-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> 2010-04-06 17:42 ` [PATCH 1/6] i2c: davinci: Fix smbus Oops with AIC33 usage Kevin Hilman [not found] ` <1270575738-22388-2-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> 2010-04-20 0:05 ` Ben Dooks 2010-04-06 17:42 ` [PATCH 2/6] i2c: davinci: misc. cleanups: remove MOD_REG_BIT and IO_ADDRESS usage Kevin Hilman 2010-04-06 17:42 ` [PATCH 3/6] i2c: davinci: Add helper functions for power management Kevin Hilman 2010-04-06 17:42 ` [PATCH 4/6] i2c: davinci: Add suspend/resume support Kevin Hilman 2010-04-06 17:42 ` [PATCH 6/6] i2c: davinci: bus recovery procedure to clear the bus Kevin Hilman 2010-04-20 0:06 ` [PATCH 0/6] i2c: davinci updates for 2.6.35 Ben Dooks [not found] ` <20100420000621.GK32401-elnMNo+KYs3pIgCt6eIbzw@public.gmane.org> 2010-04-20 13:55 ` Kevin Hilman 2010-06-21 20:16 ` Kevin Hilman [not found] ` <AANLkTikJ6XDywcBA5O0mC85jQEIWxZ9NOALIQOjcGCDJ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 2010-08-10 15:56 ` Kevin Hilman [not found] ` <AANLkTinNXxzCoH+b3=xA92sW8GCqqO4iY+_yVwBFLMqG-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 2010-08-10 23:44 ` Ben Dooks 2010-04-06 17:42 ` [PATCH 5/6] i2c: davinci: Add cpufreq support Kevin Hilman -- strict thread matches above, loose matches on Subject: below -- 2010-01-26 23:41 [PATCH 0/6] davinci i2c updates for 2.6.34 Kevin Hilman [not found] ` <1264549293-25556-1-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> 2010-01-26 23:41 ` [PATCH 1/6] i2c: davinci: Fix smbus Oops with AIC33 usage Kevin Hilman [not found] ` <1264549293-25556-2-git-send-email-khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> 2010-01-27 13:24 ` Sudhakar Rajashekhara 2010-01-27 15:03 ` Ben Dooks [not found] ` <026601ca9f54$17a18110$46e48330$@raj@ti.com> [not found] ` <026601ca9f54$17a18110$46e48330$@raj-l0cyMroinI0@public.gmane.org> 2010-01-27 14:50 ` Kevin Hilman [not found] ` <87k4v3y53z.fsf-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR@public.gmane.org> 2010-01-28 4:05 ` Sudhakar Rajashekhara 2010-01-28 8:46 ` Sudhakar Rajashekhara [not found] ` <02ee01ca9ff6$53cf0d90$fb6d28b0$@raj@ti.com> [not found] ` <02ee01ca9ff6$53cf0d90$fb6d28b0$@raj-l0cyMroinI0@public.gmane.org> 2010-01-28 14:45 ` Kevin Hilman
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).