Re: [PATCH 2/2] i2c: i2c-ocores: Add support for the GRLIB port of the controller and custom getreg and setreg functions
> "Andreas" == Andreas Larsson writes: Andreas> The registers in the GRLIB port of the controller are 32-bit Andreas> and in big endian byte order. The PRELOW and PREHIGH registers Andreas> are merged into one register. The subsequent registers have Andreas> their offset decreased accordingly. Hence the register access Andreas> needs to be handled in a non-standard manner using custom Andreas> getreg and Andreas> setreg functions. Andreas> Signed-off-by: Andreas Larsson Andreas> --- Andreas> drivers/i2c/busses/i2c-ocores.c | 57 +- Andreas> 1 files changed, 55 insertions(+), 2 deletions(-) Andreas> diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c Andreas> index 1eb8a65..e3df62f 100644 Andreas> --- a/drivers/i2c/busses/i2c-ocores.c Andreas> +++ b/drivers/i2c/busses/i2c-ocores.c Andreas> @@ -4,6 +4,9 @@ Andreas> * Andreas> * Peter Korsgaard Andreas> * Andreas> + * Support for the GRLIB port of the controller by Andreas> + * Andreas Larsson Andreas> + * Andreas> * This file is licensed under the terms of the GNU General Public License Andreas> * version 2. This program is licensed "as is" without any warranty of any Andreas> * kind, whether express or implied. Andreas> @@ -38,6 +41,8 @@ struct ocores_i2c { Andreas> int nmsgs; Andreas> int state; /* see STATE_ */ Andreas> int clock_khz; Andreas> + void (*setreg)(struct ocores_i2c *i2c, int reg, u8 value); Andreas> + u8 (*getreg)(struct ocores_i2c *i2c, int reg); Andreas> }; Andreas> /* registers */ Andreas> @@ -73,7 +78,9 @@ struct ocores_i2c { Andreas> static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value) Andreas> { Andreas> - if (i2c->reg_io_width == 4) Andreas> + if (i2c->setreg) Andreas> + i2c->setreg(i2c, reg, value); Andreas> + else if (i2c->reg_io_width == 4) Andreas> iowrite32(value, i2c->base + (reg << i2c->reg_shift)); Andreas> else if (i2c->reg_io_width == 2) Andreas> iowrite16(value, i2c->base + (reg << i2c->reg_shift)); Andreas> @@ -83,7 +90,9 @@ static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value) Andreas> static inline u8 oc_getreg(struct ocores_i2c *i2c, int reg) Andreas> { Andreas> - if (i2c->reg_io_width == 4) Andreas> + if (i2c->getreg) Andreas> + return i2c->getreg(i2c, reg); Andreas> + else if (i2c->reg_io_width == 4) Andreas> return ioread32(i2c->base + (reg << i2c->reg_shift)); Andreas> else if (i2c->reg_io_width == 2) Andreas> return ioread16(i2c->base + (reg << i2c->reg_shift)); Andreas> @@ -91,6 +100,40 @@ static inline u8 oc_getreg(struct ocores_i2c *i2c, int reg) Andreas> return ioread8(i2c->base + (reg << i2c->reg_shift)); Andreas> } Andreas> +/* Read and write functions for the GRLIB port of the controller. Registers are Andreas> + * 32-bit big endian and the PRELOW and PREHIGH registers are merged into one Andreas> + * register. The subsequent registers has their offset decreased accordingly. */ Andreas> +static u8 oc_getreg_grlib(struct ocores_i2c *i2c, int reg) Andreas> +{ Andreas> + u32 rd; Andreas> + int rreg = reg; Andreas> + if (reg != OCI2C_PRELOW) Andreas> + rreg--; Andreas> + rd = ioread32be(i2c->base + (rreg << i2c->reg_shift)); Andreas> + if (reg == OCI2C_PREHIGH) Andreas> + return (u8)rd >> 8; Andreas> + else Andreas> + return (u8)rd; Andreas> +} Andreas> + Andreas> +static void oc_setreg_grlib(struct ocores_i2c *i2c, int reg, u8 value) Andreas> +{ Andreas> + u32 curr, wr; Andreas> + int rreg = reg; Andreas> + if (reg != OCI2C_PRELOW) Andreas> + rreg--; Andreas> + if (reg == OCI2C_PRELOW || reg == OCI2C_PREHIGH) { Andreas> + curr = ioread32be(i2c->base + (rreg << i2c->reg_shift)); Andreas> + if (reg == OCI2C_PRELOW) Andreas> + wr = (curr & 0xff00) | value; Andreas> + else Andreas> + wr = (((u32)value) << 8) | (curr & 0xff); Andreas> + } else { Andreas> + wr = value; Andreas> + } Andreas> + iowrite32be(wr, i2c->base + (rreg << i2c->reg_shift)); Are all platforms using i2c-ocores guaranteed to provide ioread32be / iowrite32be or should we stick an #ifdef CONFIG_SPARC around it? -- Bye, Peter Korsgaard -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] i2c: i2c-ocores: Add irq support for sparc
> "Andreas" == Andreas Larsson writes: Andreas> There are no platform resources of type IORESOURCE_IRQ on Andreas> sparc, so the irq number is acquired in a different manner for Andreas> sparc. The general case uses platform_get_irq, that internally Andreas> still uses platform_get_resource. I have no idea why sparc is being odd in this regard, but assuming this is how it's done, I'm fine with this change. A quick grep doesn't find any other drivers doing this though: git grep -l archdata.irqs drivers | xargs grep platform_get_irq Acked-by: Peter Korsgaard Andreas> Signed-off-by: Andreas Larsson Andreas> --- Andreas> drivers/i2c/busses/i2c-ocores.c | 13 + Andreas> 1 files changed, 9 insertions(+), 4 deletions(-) Andreas> diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c Andreas> index bffd550..1eb8a65 100644 Andreas> --- a/drivers/i2c/busses/i2c-ocores.c Andreas> +++ b/drivers/i2c/busses/i2c-ocores.c Andreas> @@ -267,16 +267,21 @@ static int __devinit ocores_i2c_probe(struct platform_device *pdev) Andreas> { Andreas> struct ocores_i2c *i2c; Andreas> struct ocores_i2c_platform_data *pdata; Andreas> - struct resource *res, *res2; Andreas> + struct resource *res; Andreas> int ret; Andreas> int i; Andreas> + int irq; Andreas> res = platform_get_resource(pdev, IORESOURCE_MEM, 0); Andreas> if (!res) Andreas> return -ENODEV; Andreas> - res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); Andreas> - if (!res2) Andreas> +#ifdef CONFIG_SPARC Andreas> + irq = pdev->archdata.irqs[0]; Andreas> +#else Andreas> + irq = platform_get_irq(pdev, 0); Andreas> +#endif Andreas> + if (irq < 0) Andreas> return -ENODEV; Andreas> i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); Andreas> @@ -313,7 +318,7 @@ static int __devinit ocores_i2c_probe(struct platform_device *pdev) Andreas> ocores_init(i2c); Andreas> init_waitqueue_head(&i2c->wait); Andreas> - ret = devm_request_irq(&pdev->dev, res2->start, ocores_isr, 0, Andreas> + ret = devm_request_irq(&pdev->dev, irq, ocores_isr, 0, pdev-> name, i2c); Andreas> if (ret) { Andreas> dev_err(&pdev->dev, "Cannot claim IRQ\n"); Andreas> -- Andreas> 1.7.0.4 Andreas> -- Andreas> To unsubscribe from this list: send the line "unsubscribe linux-i2c" in Andreas> the body of a message to majord...@vger.kernel.org Andreas> More majordomo info at http://vger.kernel.org/majordomo-info.html -- Bye, Peter Korsgaard -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] i2c: mux: Add dt support to i2c-mux-gpio driver
> "MR" == Maxime Ripard writes: Hi Maxime, I'm fine with the idea, but a few comments: MR> Allow the i2c-mux-gpio to be used by a device tree enabled device. The MR> bindings are inspired by the one found in the i2c-mux-pinctrl driver. MR> Signed-off-by: Maxime Ripard MR> --- MR> .../devicetree/bindings/i2c/i2c-mux-gpio.txt | 81 ++ MR> drivers/i2c/muxes/i2c-mux-gpio.c | 169 +++- MR> 2 files changed, 211 insertions(+), 39 deletions(-) MR> create mode 100644 Documentation/devicetree/bindings/i2c/i2c-mux-gpio.txt MR> diff --git a/Documentation/devicetree/bindings/i2c/i2c-mux-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-mux-gpio.txt MR> new file mode 100644 MR> index 000..335fc4e MR> --- /dev/null MR> +++ b/Documentation/devicetree/bindings/i2c/i2c-mux-gpio.txt MR> @@ -0,0 +1,81 @@ MR> +GPIO-based I2C Bus Mux MR> + MR> +This binding describes an I2C bus multiplexer that uses GPIOs to MR> +route the I2C signals. MR> + MR> + +-+ +-+ MR> + | dev | | dev | MR> ++++-+ +-+ MR> +| SoC| || MR> +|| /++ MR> +| +--+ | +--+child bus A, on GPIO value set to 0 MR> +| | I2C |-|--| Mux | MR> +| +--+ | +--+---+child bus B, on GPIO value set to 1 MR> +|| |\--+++ MR> +| +--+ | | ||| MR> +| | GPIO |-|-++-+ +-+ +-+ MR> +| +--+ | | dev | | dev | | dev | MR> +++ +-+ +-+ +-+ MR> + MR> +Required properties: MR> +- compatible: i2c-mux-gpio MR> +- i2c-parent: The phandle of the I2C bus that this multiplexer's master-side MR> + port is connected to. MR> +- mux-gpios: list of gpios to use to control the muxer s/to use to/used to/ MR> +* Standard I2C mux properties. See mux.txt in this directory. MR> +* I2C child bus nodes. See mux.txt in this directory. MR> + MR> +Optional properties: MR> +- idle-state: value to set to the muxer when idle. When no value is How about 'bitmask defining mux state when idle' instead? MR> + given, it defaults to the last value used. MR> + MR> +For each i2c child node, an I2C child bus will be created. They will MR> +be numbered based on the reg property of each node. As far as I can see they are dynamically assigned numbers in the order they are listed in the dt. MR> + MR> +Whenever an access is made to a device on a child bus, the value set MR> +in the revelant node's reg property will be output using the list of MR> +GPIOs, the first in the list holding the most-significant value. Isn't it the other way around, E.G. first gpio in mux-gpios controlled by LSB of reg property, next gpio by lsb+1, ..? MR> + MR> +If an idle state is defined, using the idle-state (optional) property, MR> +whenever an access is not being made to a device on a child bus, the MR> +idle value will be programmed into the GPIOs. s/idle value will be programmed into the GPIOS/GPIOS set according to the idle value bitmask/ MR> + MR> +If an idle state is not defined, the most recently used value will be MR> +left programmed into hardware whenever no access is being made of a s/of a/to a/ MR> +device on a child bus. MR> + MR> +Example: MR> + i2cmux { MR> + compatible = "i2c-mux-gpio"; MR> + #address-cells = <1>; MR> + #size-cells = <0>; MR> + mux-gpios = <&gpio1 22 0 &gpio1 23 0>; MR> + i2c-parent = <&i2c1>; MR> + MR> + i2c@1 { MR> + reg = <1>; MR> + #address-cells = <1>; MR> + #size-cells = <0>; MR> + MR> + ssd1307: oled@3c { MR> + compatible = "solomon,ssd1307fb-i2c"; MR> + reg = <0x3c>; MR> + pwms = <&pwm 4 3000>; MR> + reset-gpios = <&gpio2 7 1>; MR> + reset-active-low; MR> + }; MR> + }; MR> + MR> + i2c@3 { MR> + reg = <3>; MR> + #address-cells = <1>; MR> + #size-cells = <0>; MR> + MR> + pca9555: pca9555@20 { MR> + compatible = "nxp,pca9555"; MR> + gpio-controller; MR> + #gpio-cells = <2>; MR> + reg = <0x20>; MR> + }; MR> + }; MR> + }; MR> diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c MR> index 566a675..7ebef01 100644 MR> --- a/drivers/i2c/muxes/i2c-mux-gpio.c MR> +++ b/drivers/i2c/muxes/i2c-mux-gpio.c MR> @@ -16,11 +16,13 @@ MR> #include MR> #include MR> #includ
Re: [PATCH] i2c: omap: re-factor omap_i2c_init function
Hi, On Tue, Oct 23, 2012 at 08:57:19PM +0530, Shubhrajyoti D wrote: > re-factor omap_i2c_init() so that we can re-use it for resume. > While at it also remove the bufstate variable as we write it > in omap_i2c_resize_fifo for every transfer. > > Signed-off-by: Shubhrajyoti D > --- > Applies on Felipe's series > http://www.spinics.net/lists/linux-omap/msg79995.html > > Tested with Terro sys fix + Felipe's stop sched_clock() during suspend > on omap3636 beagle both idle and suspend. > > Functional testing on omap4sdp. > > drivers/i2c/busses/i2c-omap.c | 68 > + > 1 files changed, 28 insertions(+), 40 deletions(-) > > diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c > index 5e5cefb..338cee7 100644 > --- a/drivers/i2c/busses/i2c-omap.c > +++ b/drivers/i2c/busses/i2c-omap.c > @@ -209,7 +209,6 @@ struct omap_i2c_dev { > u16 pscstate; > u16 scllstate; > u16 sclhstate; > - u16 bufstate; > u16 syscstate; > u16 westate; > u16 errata; > @@ -285,9 +284,26 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev > *i2c_dev, int reg) > } > } > > +static void __omap_i2c_init(struct omap_i2c_dev *dev) > +{ > + > + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); > + /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ > + omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate); > + > + /* SCL low and high time values */ > + omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate); > + omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate); > + if (dev->rev >= OMAP_I2C_REV_ON_3430_3530) > + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate); > + /* Take the I2C module out of reset: */ > + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); > + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate); > + > +} > static int omap_i2c_init(struct omap_i2c_dev *dev) > { > - u16 psc = 0, scll = 0, sclh = 0, buf = 0; > + u16 psc = 0, scll = 0, sclh = 0; > u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; > unsigned long fclk_rate = 1200; > unsigned long timeout; > @@ -337,11 +353,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) >* REVISIT: Some wkup sources might not be needed. >*/ > dev->westate = OMAP_I2C_WE_ALL; > - omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, > - dev->westate); > } > } > - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); > > if (dev->flags & OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) { > /* > @@ -426,28 +439,18 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > sclh = fclk_rate / (dev->speed * 2) - 7 + psc; > } > > - /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ > - omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, psc); > - > - /* SCL low and high time values */ > - omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll); > - omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh); > - > - /* Take the I2C module out of reset: */ > - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); > - > /* Enable interrupts */ > dev->iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY | > OMAP_I2C_IE_NACK | OMAP_I2C_IE_AL) | > ((dev->fifo_size) ? (OMAP_I2C_IE_RDR | > OMAP_I2C_IE_XDR) : 0); > - omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate); > - if (dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { > - dev->pscstate = psc; > - dev->scllstate = scll; > - dev->sclhstate = sclh; > - dev->bufstate = buf; > - } > + > + dev->pscstate = psc; > + dev->scllstate = scll; > + dev->sclhstate = sclh; > + > + __omap_i2c_init(dev); > + > return 0; > } > > @@ -1136,7 +1139,7 @@ omap_i2c_probe(struct platform_device *pdev) > if (IS_ERR_VALUE(r)) > goto err_free_mem; > > - dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; > + dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; > > dev->errata = 0; > > @@ -1268,23 +1271,8 @@ static int omap_i2c_runtime_resume(struct device *dev) > { > struct omap_i2c_dev *_dev = dev_get_drvdata(dev); > > - if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { > - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0); > - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate); > - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate); > - omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate); >
Re: [PATCH] i2c: omap: re-factor omap_i2c_init function
On Tue, Oct 23, 2012 at 11:27 PM, Felipe Balbi wrote: > Hi, > > On Tue, Oct 23, 2012 at 11:26:15PM +0530, Shubhrajyoti Datta wrote: >> >> @@ -1268,23 +1271,8 @@ static int omap_i2c_runtime_resume(struct device >> >> *dev) >> >> { >> >> struct omap_i2c_dev *_dev = dev_get_drvdata(dev); >> >> >> >> - if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { >> >> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0); >> >> - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate); >> >> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, >> >> _dev->scllstate); >> >> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, >> >> _dev->sclhstate); >> >> - omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate); >> >> - omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, >> >> _dev->syscstate); >> >> - omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate); >> >> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); >> >> - } >> >> - >> >> - /* >> >> - * Don't write to this register if the IE state is 0 as it can >> >> - * cause deadlock. >> >> - */ >> >> - if (_dev->iestate) >> >> - omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate); >> > >> > this part is not on __omap_i2c_init() so you're potentially causing a >> > regression here. >> >> iestate is set at init so cannot be zero. so the check was removed. > > so you never read it back ? Then you need to add a note for that in > changelog, since this is a behavior change ;-) Indeed will do. > > > -- > balbi -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] i2c: omap: re-factor omap_i2c_init function
Hi, On Tue, Oct 23, 2012 at 11:26:15PM +0530, Shubhrajyoti Datta wrote: > >> @@ -1268,23 +1271,8 @@ static int omap_i2c_runtime_resume(struct device > >> *dev) > >> { > >> struct omap_i2c_dev *_dev = dev_get_drvdata(dev); > >> > >> - if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { > >> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0); > >> - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate); > >> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate); > >> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate); > >> - omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate); > >> - omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate); > >> - omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate); > >> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); > >> - } > >> - > >> - /* > >> - * Don't write to this register if the IE state is 0 as it can > >> - * cause deadlock. > >> - */ > >> - if (_dev->iestate) > >> - omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate); > > > > this part is not on __omap_i2c_init() so you're potentially causing a > > regression here. > > iestate is set at init so cannot be zero. so the check was removed. so you never read it back ? Then you need to add a note for that in changelog, since this is a behavior change ;-) -- balbi signature.asc Description: Digital signature
Re: [PATCH] i2c: omap: re-factor omap_i2c_init function
On Tue, Oct 23, 2012 at 10:48 PM, Felipe Balbi wrote: > Hi, > > On Tue, Oct 23, 2012 at 08:57:19PM +0530, Shubhrajyoti D wrote: >> re-factor omap_i2c_init() so that we can re-use it for resume. >> While at it also remove the bufstate variable as we write it >> in omap_i2c_resize_fifo for every transfer. >> >> Signed-off-by: Shubhrajyoti D >> --- >> Applies on Felipe's series >> http://www.spinics.net/lists/linux-omap/msg79995.html >> >> Tested with Terro sys fix + Felipe's stop sched_clock() during suspend >> on omap3636 beagle both idle and suspend. >> >> Functional testing on omap4sdp. >> >> drivers/i2c/busses/i2c-omap.c | 68 >> + >> 1 files changed, 28 insertions(+), 40 deletions(-) >> >> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c >> index 5e5cefb..338cee7 100644 >> --- a/drivers/i2c/busses/i2c-omap.c >> +++ b/drivers/i2c/busses/i2c-omap.c >> @@ -209,7 +209,6 @@ struct omap_i2c_dev { >> u16 pscstate; >> u16 scllstate; >> u16 sclhstate; >> - u16 bufstate; >> u16 syscstate; >> u16 westate; >> u16 errata; >> @@ -285,9 +284,26 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev >> *i2c_dev, int reg) >> } >> } >> >> +static void __omap_i2c_init(struct omap_i2c_dev *dev) >> +{ >> + >> + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); >> + /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ >> + omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate); >> + >> + /* SCL low and high time values */ >> + omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate); >> + omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate); >> + if (dev->rev >= OMAP_I2C_REV_ON_3430_3530) >> + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate); >> + /* Take the I2C module out of reset: */ >> + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); >> + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate); >> + >> +} >> static int omap_i2c_init(struct omap_i2c_dev *dev) >> { >> - u16 psc = 0, scll = 0, sclh = 0, buf = 0; >> + u16 psc = 0, scll = 0, sclh = 0; >> u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; >> unsigned long fclk_rate = 1200; >> unsigned long timeout; >> @@ -337,11 +353,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) >>* REVISIT: Some wkup sources might not be needed. >>*/ >> dev->westate = OMAP_I2C_WE_ALL; >> - omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, >> - dev->westate); >> } >> } >> - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); >> >> if (dev->flags & OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) { >> /* >> @@ -426,28 +439,18 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) >> sclh = fclk_rate / (dev->speed * 2) - 7 + psc; >> } >> >> - /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ >> - omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, psc); >> - >> - /* SCL low and high time values */ >> - omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll); >> - omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh); >> - >> - /* Take the I2C module out of reset: */ >> - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); >> - >> /* Enable interrupts */ >> dev->iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY | >> OMAP_I2C_IE_NACK | OMAP_I2C_IE_AL) | >> ((dev->fifo_size) ? (OMAP_I2C_IE_RDR | >> OMAP_I2C_IE_XDR) : 0); >> - omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate); >> - if (dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { >> - dev->pscstate = psc; >> - dev->scllstate = scll; >> - dev->sclhstate = sclh; >> - dev->bufstate = buf; >> - } >> + >> + dev->pscstate = psc; >> + dev->scllstate = scll; >> + dev->sclhstate = sclh; >> + >> + __omap_i2c_init(dev); >> + >> return 0; >> } >> >> @@ -1136,7 +1139,7 @@ omap_i2c_probe(struct platform_device *pdev) >> if (IS_ERR_VALUE(r)) >> goto err_free_mem; >> >> - dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; >> + dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; > > trailing change. not part of $SUBJECT my mistake will remove. > >> dev->errata = 0; >> >> @@ -1268,23 +1271,8 @@ static int omap_i2c_runtime_resume(struct device *dev) >> { >> struct omap_i2c_dev *_dev = dev_get_drvdata(dev); >> >> - if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { >> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0); >> -
Re: [PATCH] i2c: omap: re-factor omap_i2c_init function
Hi, On Tue, Oct 23, 2012 at 08:57:19PM +0530, Shubhrajyoti D wrote: > re-factor omap_i2c_init() so that we can re-use it for resume. > While at it also remove the bufstate variable as we write it > in omap_i2c_resize_fifo for every transfer. > > Signed-off-by: Shubhrajyoti D > --- > Applies on Felipe's series > http://www.spinics.net/lists/linux-omap/msg79995.html > > Tested with Terro sys fix + Felipe's stop sched_clock() during suspend > on omap3636 beagle both idle and suspend. > > Functional testing on omap4sdp. > > drivers/i2c/busses/i2c-omap.c | 68 > + > 1 files changed, 28 insertions(+), 40 deletions(-) > > diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c > index 5e5cefb..338cee7 100644 > --- a/drivers/i2c/busses/i2c-omap.c > +++ b/drivers/i2c/busses/i2c-omap.c > @@ -209,7 +209,6 @@ struct omap_i2c_dev { > u16 pscstate; > u16 scllstate; > u16 sclhstate; > - u16 bufstate; > u16 syscstate; > u16 westate; > u16 errata; > @@ -285,9 +284,26 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev > *i2c_dev, int reg) > } > } > > +static void __omap_i2c_init(struct omap_i2c_dev *dev) > +{ > + > + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); > + /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ > + omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate); > + > + /* SCL low and high time values */ > + omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate); > + omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate); > + if (dev->rev >= OMAP_I2C_REV_ON_3430_3530) > + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate); > + /* Take the I2C module out of reset: */ > + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); > + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate); > + > +} > static int omap_i2c_init(struct omap_i2c_dev *dev) > { > - u16 psc = 0, scll = 0, sclh = 0, buf = 0; > + u16 psc = 0, scll = 0, sclh = 0; > u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; > unsigned long fclk_rate = 1200; > unsigned long timeout; > @@ -337,11 +353,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) >* REVISIT: Some wkup sources might not be needed. >*/ > dev->westate = OMAP_I2C_WE_ALL; > - omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, > - dev->westate); > } > } > - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); > > if (dev->flags & OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) { > /* > @@ -426,28 +439,18 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > sclh = fclk_rate / (dev->speed * 2) - 7 + psc; > } > > - /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ > - omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, psc); > - > - /* SCL low and high time values */ > - omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll); > - omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh); > - > - /* Take the I2C module out of reset: */ > - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); > - > /* Enable interrupts */ > dev->iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY | > OMAP_I2C_IE_NACK | OMAP_I2C_IE_AL) | > ((dev->fifo_size) ? (OMAP_I2C_IE_RDR | > OMAP_I2C_IE_XDR) : 0); > - omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate); > - if (dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { > - dev->pscstate = psc; > - dev->scllstate = scll; > - dev->sclhstate = sclh; > - dev->bufstate = buf; > - } > + > + dev->pscstate = psc; > + dev->scllstate = scll; > + dev->sclhstate = sclh; > + > + __omap_i2c_init(dev); > + > return 0; > } > > @@ -1136,7 +1139,7 @@ omap_i2c_probe(struct platform_device *pdev) > if (IS_ERR_VALUE(r)) > goto err_free_mem; > > - dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; > + dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; trailing change. not part of $SUBJECT > dev->errata = 0; > > @@ -1268,23 +1271,8 @@ static int omap_i2c_runtime_resume(struct device *dev) > { > struct omap_i2c_dev *_dev = dev_get_drvdata(dev); > > - if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { > - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0); > - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate); > - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate); > - omap_i2c_write_reg(_dev, OM
[PATCH] i2c: omap: re-factor omap_i2c_init function
re-factor omap_i2c_init() so that we can re-use it for resume. While at it also remove the bufstate variable as we write it in omap_i2c_resize_fifo for every transfer. Signed-off-by: Shubhrajyoti D --- Applies on Felipe's series http://www.spinics.net/lists/linux-omap/msg79995.html Tested with Terro sys fix + Felipe's stop sched_clock() during suspend on omap3636 beagle both idle and suspend. Functional testing on omap4sdp. drivers/i2c/busses/i2c-omap.c | 68 + 1 files changed, 28 insertions(+), 40 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 5e5cefb..338cee7 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -209,7 +209,6 @@ struct omap_i2c_dev { u16 pscstate; u16 scllstate; u16 sclhstate; - u16 bufstate; u16 syscstate; u16 westate; u16 errata; @@ -285,9 +284,26 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg) } } +static void __omap_i2c_init(struct omap_i2c_dev *dev) +{ + + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); + /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ + omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate); + + /* SCL low and high time values */ + omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate); + omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate); + if (dev->rev >= OMAP_I2C_REV_ON_3430_3530) + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate); + /* Take the I2C module out of reset: */ + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate); + +} static int omap_i2c_init(struct omap_i2c_dev *dev) { - u16 psc = 0, scll = 0, sclh = 0, buf = 0; + u16 psc = 0, scll = 0, sclh = 0; u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; unsigned long fclk_rate = 1200; unsigned long timeout; @@ -337,11 +353,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) * REVISIT: Some wkup sources might not be needed. */ dev->westate = OMAP_I2C_WE_ALL; - omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, - dev->westate); } } - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); if (dev->flags & OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) { /* @@ -426,28 +439,18 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) sclh = fclk_rate / (dev->speed * 2) - 7 + psc; } - /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ - omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, psc); - - /* SCL low and high time values */ - omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll); - omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh); - - /* Take the I2C module out of reset: */ - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); - /* Enable interrupts */ dev->iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY | OMAP_I2C_IE_NACK | OMAP_I2C_IE_AL) | ((dev->fifo_size) ? (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0); - omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate); - if (dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { - dev->pscstate = psc; - dev->scllstate = scll; - dev->sclhstate = sclh; - dev->bufstate = buf; - } + + dev->pscstate = psc; + dev->scllstate = scll; + dev->sclhstate = sclh; + + __omap_i2c_init(dev); + return 0; } @@ -1136,7 +1139,7 @@ omap_i2c_probe(struct platform_device *pdev) if (IS_ERR_VALUE(r)) goto err_free_mem; - dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; + dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; dev->errata = 0; @@ -1268,23 +1271,8 @@ static int omap_i2c_runtime_resume(struct device *dev) { struct omap_i2c_dev *_dev = dev_get_drvdata(dev); - if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0); - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate); - omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate); - omap_i2c_
[PATCH 2/2] i2c: i2c-ocores: Add support for the GRLIB port of the controller and custom getreg and setreg functions
The registers in the GRLIB port of the controller are 32-bit and in big endian byte order. The PRELOW and PREHIGH registers are merged into one register. The subsequent registers have their offset decreased accordingly. Hence the register access needs to be handled in a non-standard manner using custom getreg and setreg functions. Signed-off-by: Andreas Larsson --- drivers/i2c/busses/i2c-ocores.c | 57 +- 1 files changed, 55 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index 1eb8a65..e3df62f 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c @@ -4,6 +4,9 @@ * * Peter Korsgaard * + * Support for the GRLIB port of the controller by + * Andreas Larsson + * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any * kind, whether express or implied. @@ -38,6 +41,8 @@ struct ocores_i2c { int nmsgs; int state; /* see STATE_ */ int clock_khz; + void (*setreg)(struct ocores_i2c *i2c, int reg, u8 value); + u8 (*getreg)(struct ocores_i2c *i2c, int reg); }; /* registers */ @@ -73,7 +78,9 @@ struct ocores_i2c { static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value) { - if (i2c->reg_io_width == 4) + if (i2c->setreg) + i2c->setreg(i2c, reg, value); + else if (i2c->reg_io_width == 4) iowrite32(value, i2c->base + (reg << i2c->reg_shift)); else if (i2c->reg_io_width == 2) iowrite16(value, i2c->base + (reg << i2c->reg_shift)); @@ -83,7 +90,9 @@ static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value) static inline u8 oc_getreg(struct ocores_i2c *i2c, int reg) { - if (i2c->reg_io_width == 4) + if (i2c->getreg) + return i2c->getreg(i2c, reg); + else if (i2c->reg_io_width == 4) return ioread32(i2c->base + (reg << i2c->reg_shift)); else if (i2c->reg_io_width == 2) return ioread16(i2c->base + (reg << i2c->reg_shift)); @@ -91,6 +100,40 @@ static inline u8 oc_getreg(struct ocores_i2c *i2c, int reg) return ioread8(i2c->base + (reg << i2c->reg_shift)); } +/* Read and write functions for the GRLIB port of the controller. Registers are + * 32-bit big endian and the PRELOW and PREHIGH registers are merged into one + * register. The subsequent registers has their offset decreased accordingly. */ +static u8 oc_getreg_grlib(struct ocores_i2c *i2c, int reg) +{ + u32 rd; + int rreg = reg; + if (reg != OCI2C_PRELOW) + rreg--; + rd = ioread32be(i2c->base + (rreg << i2c->reg_shift)); + if (reg == OCI2C_PREHIGH) + return (u8)rd >> 8; + else + return (u8)rd; +} + +static void oc_setreg_grlib(struct ocores_i2c *i2c, int reg, u8 value) +{ + u32 curr, wr; + int rreg = reg; + if (reg != OCI2C_PRELOW) + rreg--; + if (reg == OCI2C_PRELOW || reg == OCI2C_PREHIGH) { + curr = ioread32be(i2c->base + (rreg << i2c->reg_shift)); + if (reg == OCI2C_PRELOW) + wr = (curr & 0xff00) | value; + else + wr = (((u32)value) << 8) | (curr & 0xff); + } else { + wr = value; + } + iowrite32be(wr, i2c->base + (rreg << i2c->reg_shift)); +} + static void ocores_process(struct ocores_i2c *i2c) { struct i2c_msg *msg = i2c->msg; @@ -233,6 +276,7 @@ static int ocores_i2c_of_probe(struct platform_device *pdev, { struct device_node *np = pdev->dev.of_node; u32 val; + const char *name; if (of_property_read_u32(np, "reg-shift", &i2c->reg_shift)) { /* no 'reg-shift', check for deprecated 'regstep' */ @@ -257,6 +301,15 @@ static int ocores_i2c_of_probe(struct platform_device *pdev, of_property_read_u32(pdev->dev.of_node, "reg-io-width", &i2c->reg_io_width); + + name = of_get_property(pdev->dev.of_node, "name", NULL); + if (name && (!strcmp(name, "GAISLER_I2CMST") || +!strcmp(name, "01_028"))) { + dev_dbg(&pdev->dev, "GRLIB variant of i2c-ocores\n"); + i2c->setreg = oc_setreg_grlib; + i2c->getreg = oc_getreg_grlib; + } + return 0; } #else -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/2] i2c: i2c-ocores: Add support for sparc, custom set and get functions, and the GRLIB port of the controller
On sparc, irqs are not present as an IORESOURCE in the struct platform_device representation. Therefore, for sparc the irq needs to be fetched in a different manner. The GRLIB port of the ocores i2c controller needs custom getreg and setreg functions to allow for big endian register access and to deal with the fact that the PRELOW and PREHIGH registers have been merged into one register. Signed-off-by: Andreas Larsson Andreas Larsson (2): i2c: i2c-ocores: Add irq support for sparc i2c: i2c-ocores: Add support for the GRLIB port of the controller and custom getreg and setreg functions drivers/i2c/busses/i2c-ocores.c | 70 +++--- 1 files changed, 64 insertions(+), 6 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] i2c: i2c-ocores: Add irq support for sparc
There are no platform resources of type IORESOURCE_IRQ on sparc, so the irq number is acquired in a different manner for sparc. The general case uses platform_get_irq, that internally still uses platform_get_resource. Signed-off-by: Andreas Larsson --- drivers/i2c/busses/i2c-ocores.c | 13 + 1 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index bffd550..1eb8a65 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c @@ -267,16 +267,21 @@ static int __devinit ocores_i2c_probe(struct platform_device *pdev) { struct ocores_i2c *i2c; struct ocores_i2c_platform_data *pdata; - struct resource *res, *res2; + struct resource *res; int ret; int i; + int irq; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENODEV; - res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res2) +#ifdef CONFIG_SPARC + irq = pdev->archdata.irqs[0]; +#else + irq = platform_get_irq(pdev, 0); +#endif + if (irq < 0) return -ENODEV; i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); @@ -313,7 +318,7 @@ static int __devinit ocores_i2c_probe(struct platform_device *pdev) ocores_init(i2c); init_waitqueue_head(&i2c->wait); - ret = devm_request_irq(&pdev->dev, res2->start, ocores_isr, 0, + ret = devm_request_irq(&pdev->dev, irq, ocores_isr, 0, pdev->name, i2c); if (ret) { dev_err(&pdev->dev, "Cannot claim IRQ\n"); -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: RT throttling and suspend/resume (was Re: [PATCH] i2c: omap: revert "i2c: omap: switch to threaded IRQ support")
On Mon, Oct 22, 2012 at 09:47:06AM -0700, Kevin Hilman wrote: > Peter Zijlstra writes: > > > On Fri, 2012-10-19 at 16:54 -0700, Kevin Hilman wrote: > > > >> So I did the same thing for my ARM SoC, and it definitley stops the RT > >> throttling. > >> > >> However, it has the undesriable (IMO) side effect of making timed printk > >> output rather unhelpful for debugging suspend/resume since printk time > >> stays constant throughout suspend/resume no matter how long you > >> sleep. :( > >> > >> So does that mean we have to choose between useful printk times during > >> suspend/resume or functioning IRQ threads during suspend/resume ? > > > > Urgh.. this was not something I considered. This being primarily the > > sched_clock infrastructure and such. > > > > So what exactly is the problem with the suspend resume thing (its not > > something I've ever debugged), is all you need a clean break between pre > > and post suspend, or do you need the actual time the machine was gone? > > I think it's more a question of what people are used to. I think folks > used to debugging suspend/resume (at least on ARM) are used to having > the printk timestamps reflect the amount of time the machine was gone. > > With a sched_clock() that counts during suspend, that feature doesn't > work anymore. I'm not sure that this feature is a deal breaker, but it > has been convenient. IMHO, this isn't a deal breaker, it's nothing more than cosmetic issue. The big hint about the sched_clock() behaviour is partly in the name, and the behaviour you get from the scheduler if you don't give it what it wants. The scheduler sets the requirements for sched_clock(), not printk, so if we have to fix sched_clock() to get correct behaviour from the scheduler, that's what we have to do irrespective of cosmetic printk issues. And there are many other ways to measure time off in suspend... we have at least three other functions which return time, and which will return updated time after a resume event. -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH v1] Support Elan Touchscreen eKTF product.
Hi Dmitry: This driver is not related to Tom's driver. This driver is ELAN standard I2C driver for touch panel and its packets is defined by ELAN own format and not related to HID over I2C. Thanks, Scott > -Original Message- > From: Jian-Jhong Ding [mailto:jj_d...@emc.com.tw] > Sent: Tuesday, October 23, 2012 10:15 AM > To: Dmitry Torokhov > Cc: Scott Liu; linux-in...@vger.kernel.org; linux-i2c@vger.kernel.org; > linux-ker...@vger.kernel.org; Benjamin Tissoires; Jesse; Vincent Wang; Paul > Subject: Re: [PATCH v1] Support Elan Touchscreen eKTF product. > > Dmitry Torokhov writes: > > On Mon, Oct 22, 2012 at 11:47:42AM +0800, Jian-Jhong Ding wrote: > >> With Benjamin's i2c-hid implimentation, is it possible to make > >> hid-multitouch not depend on USBHID and reuse it to drive this device? > > > > Exactly. Before looking any further - is this the same part that Tom Lin > > posted a driver for earlier this summer? > > No. Tom's driver was only for trackpads, this is probably for some > touch panel. The controller ICs may have some similarities, but the > firmware is developed independently, though both somewhat conform to the > HID over I2C protocol. > > Thanks, > -JJ > > Thanks. > > > > -- > > Dmitry -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html