Re: [PATCH 2/2] i2c: i2c-ocores: Add support for the GRLIB port of the controller and custom getreg and setreg functions

2012-10-23 Thread Peter Korsgaard
> "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

2012-10-23 Thread Peter Korsgaard
> "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

2012-10-23 Thread Peter Korsgaard
> "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

2012-10-23 Thread Felipe Balbi
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

2012-10-23 Thread Shubhrajyoti Datta
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

2012-10-23 Thread Felipe Balbi
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

2012-10-23 Thread Shubhrajyoti Datta
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

2012-10-23 Thread Felipe Balbi
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

2012-10-23 Thread Shubhrajyoti D
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

2012-10-23 Thread Andreas Larsson
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

2012-10-23 Thread Andreas Larsson
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

2012-10-23 Thread Andreas Larsson
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")

2012-10-23 Thread Russell King - ARM Linux
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.

2012-10-23 Thread 劉嘉駿
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