[PATCH] i2c: Add support for device-tree based chip initialization

2012-11-15 Thread Guenter Roeck
Some I2C devices are not or not correctly initialized by the firmware.
Configuration would be possible via platform data, but that would require
per-driver platform data and a lot of code, and changing it would not be
possible without re-compiling the kernel. It is more elegant to do it
generically via devicetree properties.

Add a generic I2C devicetree property named "reg-init". This property provides
a sequence of device initialization commands to be executed prior to calling
the probe function for a given device.

Signed-off-by: Guenter Roeck 
---
 .../devicetree/bindings/i2c/trivial-devices.txt|   24 +++
 drivers/i2c/i2c-core.c |   68 
 2 files changed, 92 insertions(+)

diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt 
b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
index 2f5322b..33b694e 100644
--- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
+++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
@@ -2,6 +2,30 @@ This is a list of trivial i2c devices that have simple device 
tree
 bindings, consisting only of a compatible field, an address and
 possibly an interrupt line.
 
+Device initialization is supported with an optional reg-init property.
+This property contains a sequence of commands to be written into the chip.
+Each command consists of four values: Register, command type, mask, and data.
+   Register:
+   Register or command address
+   Command type:
+   0: SMBus write byte
+   1: SMBus write byte data
+   2: SMBus write word data
+   Mask:
+   If set, the register is read and masked with this value.
+   Data:
+   Data to be written (or with original data and mask if set)
+
+Example:
+   max6696@1a {
+   compatible = "maxim,max6696";
+   reg = <0x1a>;
+   reg-init = <
+   0x09 1 0x00 0x24
+   0x21 1 0x00 0x05
+   >;
+   };
+
 If a device needs more specific bindings, such as properties to
 describe some aspect of it, there needs to be a specific binding
 document for it just like any other devices.
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index a7edf98..49f8b74 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -104,6 +104,69 @@ static int i2c_device_uevent(struct device *dev, struct 
kobj_uevent_env *env)
 #define i2c_device_uevent  NULL
 #endif /* CONFIG_HOTPLUG */
 
+static int i2c_dev_of_init(struct i2c_client *client, struct device *dev)
+{
+   const u32 *reg_init;
+   int rlen;
+   int val;
+   u32 reg, access, mask, data;
+
+   reg_init = of_get_property(dev->of_node, "reg-init", &rlen);
+   if (!reg_init)
+   return 0;
+
+   if (!rlen || rlen % 4)
+   return -EINVAL;
+
+   while (rlen >= 4) {
+   reg = reg_init[0];
+   access = reg_init[1];
+   mask = reg_init[2];
+   data = reg_init[3];
+
+   if (reg > 0xff)
+   return -EINVAL;
+
+   switch (access) {
+   default:
+   return -EINVAL;
+   case 0:
+   val = 0;
+   break;
+   case 1:
+   val = mask ? i2c_smbus_read_byte_data(client, reg) : 0;
+   break;
+   case 2:
+   val = mask ? i2c_smbus_read_word_data(client, reg) : 0;
+   break;
+   }
+   if (val < 0)
+   return val;
+
+   val &= mask;
+   val |= data;
+
+   switch (access) {
+   default:
+   case 0:
+   val = i2c_smbus_write_byte(client, reg);
+   break;
+   case 1:
+   val = i2c_smbus_write_byte_data(client, reg, val);
+   break;
+   case 2:
+   val = i2c_smbus_write_word_data(client, reg, val);
+   break;
+   }
+   if (val < 0)
+   return val;
+
+   reg_init += 4;
+   rlen -= 4 * sizeof(u32);
+   }
+   return 0;
+}
+
 static int i2c_device_probe(struct device *dev)
 {
struct i2c_client   *client = i2c_verify_client(dev);
@@ -122,7 +185,12 @@ static int i2c_device_probe(struct device *dev)
client->flags & I2C_CLIENT_WAKE);
dev_dbg(dev, "probe\n");
 
+   status = i2c_dev_of_init(client, dev);
+   if (status)
+   goto error;
+
status = driver->probe(client, i2c_match_id(driver->id_table, client));
+error:
if (status) {
client->driver = NULL;
i2c_set_clientdata(client, NULL)

Re: [PATCH 3/3] i2c: at91: add dma support

2012-11-15 Thread Nicolas Ferre
On 11/14/2012 05:44 PM, ludovic.desroc...@atmel.com :
> From: Ludovic Desroches 
> 
> Add dma support for Atmel TWI which is available on sam9x5 and later.
> 
> When using dma for reception, you have to read only n-2 bytes. The last
> two bytes are read manually. Don't doing this should cause to send the
> STOP command too late and then to get extra data in the receive
> register.
> 
> Signed-off-by: Ludovic Desroches 

Even nicer ;-)

Acked-by: Nicolas Ferre 


> ---
>  drivers/i2c/busses/i2c-at91.c | 306 
> --
>  1 file changed, 298 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
> index 2c437df..ceef40f 100644
> --- a/drivers/i2c/busses/i2c-at91.c
> +++ b/drivers/i2c/busses/i2c-at91.c
> @@ -19,6 +19,8 @@
>  
>  #include 
>  #include 
> +#include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -29,9 +31,11 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #define TWI_CLK_HZ   10  /* max 400 Kbits/s */
>  #define AT91_I2C_TIMEOUT msecs_to_jiffies(100)   /* transfer timeout */
> +#define AT91_I2C_DMA_THRESHOLD   8   /* enable DMA 
> if transfer size is bigger than this threshold */
>  
>  /* AT91 TWI register definitions */
>  #define  AT91_TWI_CR 0x  /* Control Register */
> @@ -69,6 +73,18 @@ struct at91_twi_pdata {
>   unsigned clk_max_div;
>   unsigned clk_offset;
>   bool has_unre_flag;
> + bool has_dma_support;
> + struct at_dma_slave dma_slave;
> +};
> +
> +struct at91_twi_dma {
> + struct dma_chan *chan_rx;
> + struct dma_chan *chan_tx;
> + struct scatterlist sg;
> + struct dma_async_tx_descriptor *data_desc;
> + enum dma_data_direction direction;
> + bool buf_mapped;
> + bool xfer_in_progress;
>  };
>  
>  struct at91_twi_dev {
> @@ -80,10 +96,13 @@ struct at91_twi_dev {
>   size_t buf_len;
>   struct i2c_msg *msg;
>   int irq;
> + unsigned imr;
>   unsigned transfer_status;
>   struct i2c_adapter adapter;
>   unsigned twi_cwgr_reg;
>   struct at91_twi_pdata *pdata;
> + bool use_dma;
> + struct at91_twi_dma dma;
>  };
>  
>  static unsigned at91_twi_read(struct at91_twi_dev *dev, unsigned reg)
> @@ -102,6 +121,17 @@ static void at91_disable_twi_interrupts(struct 
> at91_twi_dev *dev)
>  AT91_TWI_TXCOMP | AT91_TWI_RXRDY | AT91_TWI_TXRDY);
>  }
>  
> +static void at91_twi_irq_save(struct at91_twi_dev *dev)
> +{
> + dev->imr = at91_twi_read(dev, AT91_TWI_IMR) & 0x7;
> + at91_disable_twi_interrupts(dev);
> +}
> +
> +static void at91_twi_irq_restore(struct at91_twi_dev *dev)
> +{
> + at91_twi_write(dev, AT91_TWI_IER, dev->imr);
> +}
> +
>  static void at91_init_twi_bus(struct at91_twi_dev *dev)
>  {
>   at91_disable_twi_interrupts(dev);
> @@ -138,6 +168,28 @@ static void __devinit at91_calc_twi_clock(struct 
> at91_twi_dev *dev, int twi_clk)
>   dev_dbg(dev->dev, "cdiv %d ckdiv %d\n", cdiv, ckdiv);
>  }
>  
> +static void at91_twi_dma_cleanup(struct at91_twi_dev *dev)
> +{
> + struct at91_twi_dma *dma = &dev->dma;
> +
> + at91_twi_irq_save(dev);
> +
> + if (dma->xfer_in_progress) {
> + if (dma->direction == DMA_FROM_DEVICE)
> + dmaengine_terminate_all(dma->chan_rx);
> + else
> + dmaengine_terminate_all(dma->chan_tx);
> + dma->xfer_in_progress = false;
> + }
> + if (dma->buf_mapped) {
> + dma_unmap_single(dev->dev, sg_dma_address(&dma->sg),
> +  dev->buf_len, dma->direction);
> + dma->buf_mapped = false;
> + }
> +
> + at91_twi_irq_restore(dev);
> +}
> +
>  static void at91_twi_write_next_byte(struct at91_twi_dev *dev)
>  {
>   if (dev->buf_len <= 0)
> @@ -154,6 +206,60 @@ static void at91_twi_write_next_byte(struct at91_twi_dev 
> *dev)
>   ++dev->buf;
>  }
>  
> +static void at91_twi_write_data_dma_callback(void *data)
> +{
> + struct at91_twi_dev *dev = (struct at91_twi_dev *)data;
> +
> + dma_unmap_single(dev->dev, sg_dma_address(&dev->dma.sg),
> +  dev->buf_len, DMA_MEM_TO_DEV);
> +
> + at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_STOP);
> +}
> +
> +static void at91_twi_write_data_dma(struct at91_twi_dev *dev)
> +{
> + dma_addr_t dma_addr;
> + struct dma_async_tx_descriptor *txdesc;
> + struct at91_twi_dma *dma = &dev->dma;
> + struct dma_chan *chan_tx = dma->chan_tx;
> +
> + if (dev->buf_len <= 0)
> + return;
> +
> + dma->direction = DMA_TO_DEVICE;
> +
> + at91_twi_irq_save(dev);
> + dma_addr = dma_map_single(dev->dev, dev->buf, dev->buf_len,
> +   DMA_TO_DEVICE);
> + if (dma_mapping_error(dev->dev, dma_addr)) {
> + dev_err(dev->dev, "dma map failed\n");
> + return;
> + }
> + dma->

Re: [PATCH 2/3] i2c: at91: change struct members indentation

2012-11-15 Thread Nicolas Ferre
On 11/14/2012 05:44 PM, ludovic.desroc...@atmel.com :
> From: Ludovic Desroches 
> 
> Replace tabs for struct members indentation by space to minimise line changes
> when adding new members which would require extra tabs to keep alignment.

Lol, you followed Wolfram's advice... You know my preferences ;-)

> Signed-off-by: Ludovic Desroches 

Ok, then:

Acked-by: Nicolas Ferre 

> ---
>  drivers/i2c/busses/i2c-at91.c | 30 +++---
>  1 file changed, 15 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
> index dc8cb22..2c437df 100644
> --- a/drivers/i2c/busses/i2c-at91.c
> +++ b/drivers/i2c/busses/i2c-at91.c
> @@ -66,24 +66,24 @@
>  #define  AT91_TWI_THR0x0034  /* Transmit Holding Register */
>  
>  struct at91_twi_pdata {
> - unsignedclk_max_div;
> - unsignedclk_offset;
> - boolhas_unre_flag;
> + unsigned clk_max_div;
> + unsigned clk_offset;
> + bool has_unre_flag;
>  };
>  
>  struct at91_twi_dev {
> - struct device   *dev;
> - void __iomem*base;
> - struct completion   cmd_complete;
> - struct clk  *clk;
> - u8  *buf;
> - size_t  buf_len;
> - struct i2c_msg  *msg;
> - int irq;
> - unsignedtransfer_status;
> - struct i2c_adapter  adapter;
> - unsignedtwi_cwgr_reg;
> - struct at91_twi_pdata   *pdata;
> + struct device *dev;
> + void __iomem *base;
> + struct completion cmd_complete;
> + struct clk *clk;
> + u8 *buf;
> + size_t buf_len;
> + struct i2c_msg *msg;
> + int irq;
> + unsigned transfer_status;
> + struct i2c_adapter adapter;
> + unsigned twi_cwgr_reg;
> + struct at91_twi_pdata *pdata;
>  };
>  
>  static unsigned at91_twi_read(struct at91_twi_dev *dev, unsigned reg)
> 


-- 
Nicolas Ferre
--
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/3] i2c: at91: fix compilation warning

2012-11-15 Thread Nicolas Ferre
On 11/14/2012 05:44 PM, ludovic.desroc...@atmel.com :
> From: Ludovic Desroches 
> 
> Signed-off-by: Ludovic Desroches 

Acked-by: Nicolas Ferre 

Maybe tell Wolfram to remove this one from the series and add it to his
3.7 tree...

Bye,

> ---
>  drivers/i2c/busses/i2c-at91.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
> index a6670eb..dc8cb22 100644
> --- a/drivers/i2c/busses/i2c-at91.c
> +++ b/drivers/i2c/busses/i2c-at91.c
> @@ -412,7 +412,7 @@ static struct at91_twi_pdata * __devinit 
> at91_twi_get_driver_data(
>   match = of_match_node(atmel_twi_dt_ids, pdev->dev.of_node);
>   if (!match)
>   return NULL;
> - return match->data;
> + return (struct at91_twi_pdata *) match->data;
>   }
>   return (struct at91_twi_pdata *) 
> platform_get_device_id(pdev)->driver_data;
>  }
> 


-- 
Nicolas Ferre
--
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 v6 2/2] i2c: i2c-ocores: Add support for the GRLIB port of the controller and use function pointers for getreg and setreg functions

2012-11-15 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 setreg functions.

 Andreas> Add setreg and getreg functions for different register widths
 Andreas> and let oc_setreg and oc_getreg use function pointers to call
 Andreas> the appropriate functions.

 Andreas> A type is added as the data of the of match table entries. A
 Andreas> new entry with a different compatible string is added to the
 Andreas> table. The type of that entry triggers usage of the custom
 Andreas> grlib functions by setting the setreg and getreg function
 Andreas> pointers.

 Andreas> Signed-off-by: Andreas Larsson 

Acked-by: Peter Korsgaard 

Thanks!

-- 
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] bindings: i2c: use consistent naming for i2c binding descriptions

2012-11-15 Thread Grant Likely
On Tue, 13 Nov 2012 18:16:43 +0100, Wolfram Sang  wrote:
> Filenames of devictree binding documentation seems to be arbitrary and
> for me it is unneeded hazzle to find the corresponding documentation for
> a specific driver.
> 
> Naming the description the same as the driver is a lot easier and makes
> sense to me since the driver defines the binding it understands.
> 
> Also, remove a reference in one source to the binding documentation, since 
> path
> information easily gets stale.
> 
> Signed-off-by: Wolfram Sang 
> Cc: Rob Herring 
> Cc: Grant Likely 

Applied, thanks.

g.

--
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 v6 1/2] i2c: i2c-ocores: Add irq support for sparc

2012-11-15 Thread Andreas Larsson
Add sparc support by using platform_get_irq instead of platform_get_resource.
There are no platform resources of type IORESOURCE_IRQ for sparc, but
platform_get_irq works for sparc. In the non-sparc case platform_get_irq
internally uses platform_get_resource.

Signed-off-by: Andreas Larsson 
Acked-by: Peter Korsgaard 
---
 Changes since v5:
 - None

 drivers/i2c/busses/i2c-ocores.c |   11 ++-
 1 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
index bffd550..1d204cb 100644
--- a/drivers/i2c/busses/i2c-ocores.c
+++ b/drivers/i2c/busses/i2c-ocores.c
@@ -267,7 +267,8 @@ 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 irq;
int ret;
int i;
 
@@ -275,9 +276,9 @@ static int __devinit ocores_i2c_probe(struct 
platform_device *pdev)
if (!res)
return -ENODEV;
 
-   res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-   if (!res2)
-   return -ENODEV;
+   irq = platform_get_irq(pdev, 0);
+   if (irq < 0)
+   return irq;
 
i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
if (!i2c)
@@ -313,7 +314,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


[PATCH v6 2/2] i2c: i2c-ocores: Add support for the GRLIB port of the controller and use function pointers for getreg and setreg functions

2012-11-15 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.

Add setreg and getreg functions for different register widths and let oc_setreg
and oc_getreg use function pointers to call the appropriate functions.

A type is added as the data of the of match table entries. A new entry with a
different compatible string is added to the table. The type of that entry
triggers usage of the custom grlib functions by setting the setreg and getreg
function pointers.

Signed-off-by: Andreas Larsson 
---
 Changes since v5:
 - Function pointers for different widths are set together
 - oc_setreg and oc_getreg are kept as wrappers

 .../devicetree/bindings/i2c/i2c-ocores.txt |2 +-
 drivers/i2c/busses/i2c-ocores.c|  138 +---
 2 files changed, 121 insertions(+), 19 deletions(-)

diff --git a/Documentation/devicetree/bindings/i2c/i2c-ocores.txt 
b/Documentation/devicetree/bindings/i2c/i2c-ocores.txt
index c15781f..1637c29 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-ocores.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-ocores.txt
@@ -1,7 +1,7 @@
 Device tree configuration for i2c-ocores
 
 Required properties:
-- compatible  : "opencores,i2c-ocores"
+- compatible  : "opencores,i2c-ocores" or "aeroflexgaisler,i2cmst"
 - reg : bus address start and address range size of device
 - interrupts  : interrupt number
 - clock-frequency : frequency of bus clock in Hz
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
index 1d204cb..2ef318b 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 */
@@ -71,24 +76,81 @@ struct ocores_i2c {
 #define STATE_READ 3
 #define STATE_ERROR4
 
+#define TYPE_OCORES0
+#define TYPE_GRLIB 1
+
+static void oc_setreg_8(struct ocores_i2c *i2c, int reg, u8 value)
+{
+   iowrite8(value, i2c->base + (reg << i2c->reg_shift));
+}
+
+static void oc_setreg_16(struct ocores_i2c *i2c, int reg, u8 value)
+{
+   iowrite16(value, i2c->base + (reg << i2c->reg_shift));
+}
+
+static void oc_setreg_32(struct ocores_i2c *i2c, int reg, u8 value)
+{
+   iowrite32(value, i2c->base + (reg << i2c->reg_shift));
+}
+
+static inline u8 oc_getreg_8(struct ocores_i2c *i2c, int reg)
+{
+   return ioread8(i2c->base + (reg << i2c->reg_shift));
+}
+
+static inline u8 oc_getreg_16(struct ocores_i2c *i2c, int reg)
+{
+   return ioread16(i2c->base + (reg << i2c->reg_shift));
+}
+
+static inline u8 oc_getreg_32(struct ocores_i2c *i2c, int reg)
+{
+   return ioread32(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 inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value)
 {
-   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));
-   else
-

[PATCH v6 0/2] i2c: i2c-ocores: Add support for sparc, custom set and get functions, and the GRLIB port of the controller

2012-11-15 Thread Andreas Larsson
On sparc, irqs are not present as an IORESOURCE in the struct platform_device
representation. By using platform_get_irq instead of platform_get_resource the
driver works for sparc.

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 

Changes since v5:
- Function pointers for different widths are set together
- oc_setreg and oc_getreg are kept as wrappers

Andreas Larsson (2):
  i2c: i2c-ocores: Add irq support for sparc
  i2c: i2c-ocores: Add support for the GRLIB port of the controller and
use function pointers for getreg and setreg functions

 .../devicetree/bindings/i2c/i2c-ocores.txt |2 +-
 drivers/i2c/busses/i2c-ocores.c|  149 +---
 2 files changed, 127 insertions(+), 24 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


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

2012-11-15 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 setreg functions.

 Andreas> The single oc_getreg and one oc_setreg functions, that
 Andreas> branches and call different ioread and iowrite functions, are
 Andreas> replaced by specific functions that uses the appropriate
 Andreas> ioread and iowrite functions and function pointers are
 Andreas> initiated and used to call the approproate functions.

 Andreas> A type is added as the data of the of match table entries. A
 Andreas> new entry with a different compatible string is added to the
 Andreas> table. The type of that entry triggers usage of the custom
 Andreas> grlib functions by setting the new getreg and setreg function
 Andreas> pointers to these functions.

Sorry to keep on requesting changes, but see below for a bit more:

 
 Andreas>  static void ocores_process(struct ocores_i2c *i2c)
 Andreas>  {
 Andreas>   struct i2c_msg *msg = i2c->msg;
 Andreas> - u8 stat = oc_getreg(i2c, OCI2C_STATUS);
 Andreas> + u8 stat = i2c->getreg(i2c, OCI2C_STATUS);

The patch would have been quite a bit smaller/easier to read if you had
kept oc_getreg / oc_setreg as wrappers.

 
 Andreas>  #ifdef CONFIG_OF
 Andreas>  static int ocores_i2c_of_probe(struct platform_device *pdev,
 Andreas>   struct ocores_i2c *i2c)
 Andreas>  {
 Andreas>   struct device_node *np = pdev->dev.of_node;
 Andreas> + const struct of_device_id *match;
 Andreas>   u32 val;
 
 Andreas>   if (of_property_read_u32(np, "reg-shift", &i2c->reg_shift)) {
 Andreas> @@ -257,6 +324,14 @@ static int ocores_i2c_of_probe(struct 
platform_device *pdev,
 
 Andreas>   of_property_read_u32(pdev->dev.of_node, "reg-io-width",
 Andreas>   &i2c->reg_io_width);
 Andreas> +
 Andreas> + match = of_match_node(ocores_i2c_match, pdev->dev.of_node);
 Andreas> + if (match && (int)match->data == TYPE_GRLIB) {
 Andreas> + dev_dbg(&pdev->dev, "GRLIB variant of i2c-ocores\n");
 Andreas> + i2c->setreg = oc_setreg_grlib;
 Andreas> + i2c->getreg = oc_getreg_grlib;
 Andreas> + }
 Andreas> +  
 Andreas>   return 0;
 Andreas>  }
 Andreas>  #else
 Andreas> @@ -311,6 +386,23 @@ static int __devinit ocores_i2c_probe(struct 
platform_device *pdev)
 Andreas>   if (i2c->reg_io_width == 0)
 i2c-> reg_io_width = 1; /* Set to default value */
 
 Andreas> + if (!i2c->getreg) {
 Andreas> + if (i2c->reg_io_width == 4)
 Andreas> + i2c->getreg = oc_getreg_32;
 Andreas> + else if (i2c->reg_io_width == 2)
 Andreas> + i2c->getreg = oc_getreg_16;
 Andreas> + else
 Andreas> + i2c->getreg = oc_getreg_8;
 Andreas> + }
 Andreas> + if (!i2c->setreg) {
 Andreas> + if (i2c->reg_io_width == 4)
 Andreas> + i2c->setreg = oc_setreg_32;
 Andreas> + else if (i2c->reg_io_width == 2)
 Andreas> + i2c->setreg = oc_setreg_16;
 Andreas> + else
 Andreas> + i2c->setreg = oc_setreg_8;
 Andreas> + }
 Andreas> +

These are always set together (could even move to a single ops
structure), so it would be shorter to assign them at the same time:

if (!i2c->setreg || !i2c->getreg) {
   switch (i2c->reg_io_width) {
   case 1:
i2c->setreg = oc_setreg_8;
i2c->getreg = oc_getreg_8;
break;

   case 2:
i2c->setreg = oc_setreg_16;
...

   default:
dev_err(&pdev->dev "Unsupported I/O width (%d)\n", i2c->reg_io_width);
return -EINVAL;
   }
}

-- 
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


[PATCH v5 1/2] i2c: i2c-ocores: Add irq support for sparc

2012-11-15 Thread Andreas Larsson
Add sparc support by using platform_get_irq instead of platform_get_resource.
There are no platform resources of type IORESOURCE_IRQ for sparc, but
platform_get_irq works for sparc. In the non-sparc case platform_get_irq
internally uses platform_get_resource.

Signed-off-by: Andreas Larsson 
Acked-by: Peter Korsgaard 
---
 Changes since v4:
 - None

 drivers/i2c/busses/i2c-ocores.c |   11 ++-
 1 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
index bffd550..1d204cb 100644
--- a/drivers/i2c/busses/i2c-ocores.c
+++ b/drivers/i2c/busses/i2c-ocores.c
@@ -267,7 +267,8 @@ 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 irq;
int ret;
int i;
 
@@ -275,9 +276,9 @@ static int __devinit ocores_i2c_probe(struct 
platform_device *pdev)
if (!res)
return -ENODEV;
 
-   res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-   if (!res2)
-   return -ENODEV;
+   irq = platform_get_irq(pdev, 0);
+   if (irq < 0)
+   return irq;
 
i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
if (!i2c)
@@ -313,7 +314,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


[PATCH v5 2/2] i2c: i2c-ocores: Add support for the GRLIB port of the controller and use function pointers for getreg and setreg functions

2012-11-15 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.

The single oc_getreg and one oc_setreg functions, that branches and call
different ioread and iowrite functions, are replaced by specific functions that
uses the appropriate ioread and iowrite functions and function pointers are
initiated and used to call the approproate functions.

A type is added as the data of the of match table entries. A new entry with a
different compatible string is added to the table. The type of that entry
triggers usage of the custom grlib functions by setting the new getreg and
setreg function pointers to these functions.

Signed-off-by: Andreas Larsson 
---
 Changes since v4:
 - Replace the ocores_get_type function with inline code in the probe function
 - Replace the oc_(get|set)reg functions with oc_(get|set)reg_(8|16|32)
   functions and always use the function pointers to call them.

 .../devicetree/bindings/i2c/i2c-ocores.txt |2 +-
 drivers/i2c/busses/i2c-ocores.c|  176 +++-
 2 files changed, 132 insertions(+), 46 deletions(-)

diff --git a/Documentation/devicetree/bindings/i2c/i2c-ocores.txt 
b/Documentation/devicetree/bindings/i2c/i2c-ocores.txt
index c15781f..1637c29 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-ocores.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-ocores.txt
@@ -1,7 +1,7 @@
 Device tree configuration for i2c-ocores
 
 Required properties:
-- compatible  : "opencores,i2c-ocores"
+- compatible  : "opencores,i2c-ocores" or "aeroflexgaisler,i2cmst"
 - reg : bus address start and address range size of device
 - interrupts  : interrupt number
 - clock-frequency : frequency of bus clock in Hz
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
index 1d204cb..566193d 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 */
@@ -71,34 +76,82 @@ struct ocores_i2c {
 #define STATE_READ 3
 #define STATE_ERROR4
 
-static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value)
+#define TYPE_OCORES0
+#define TYPE_GRLIB 1
+
+static void oc_setreg_8(struct ocores_i2c *i2c, int reg, u8 value)
 {
-   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));
-   else
-   iowrite8(value, i2c->base + (reg << i2c->reg_shift));
+   iowrite8(value, i2c->base + (reg << i2c->reg_shift));
+}
+
+static void oc_setreg_16(struct ocores_i2c *i2c, int reg, u8 value)
+{
+   iowrite16(value, i2c->base + (reg << i2c->reg_shift));
 }
 
-static inline u8 oc_getreg(struct ocores_i2c *i2c, int reg)
+static void oc_setreg_32(struct ocores_i2c *i2c, int reg, u8 value)
 {
-   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));
+   iowrite32(value, i2c->base + (reg << i2c->reg_shift));
+}
+
+static inline u8 oc_getreg_8(struct ocores_i2c *i2c, int reg)
+{
+   return ioread8(i2c->base + (reg << i2c->reg_shift));
+}
+
+static inline u8 oc_getreg_16(struct ocores_i2c *i2c, int reg)
+{
+   return ioread16(i2c->base + (reg << i2c->reg_shift));
+}
+
+static inline u8 oc_getreg_32(struct ocores_i2c *i2c, int reg)
+{
+   return ioread32(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 ioread8(i2c->base + (reg <<

[PATCH v5 0/2] i2c: i2c-ocores: Add support for sparc, custom set and get functions, and the GRLIB port of the controller

2012-11-15 Thread Andreas Larsson
On sparc, irqs are not present as an IORESOURCE in the struct platform_device
representation. By using platform_get_irq instead of platform_get_resource the
driver works for sparc.

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 

Changes since v4:
- Replace the ocores_get_type function with inline code in the probe function
- Replace the oc_(get|set)reg functions with oc_(get|set)reg_(8|16|32)
  functions and always use the function pointers to call them.

Andreas Larsson (2):
  i2c: i2c-ocores: Add irq support for sparc
  i2c: i2c-ocores: Add support for the GRLIB port of the controller and
use function pointers for getreg and setreg functions

 .../devicetree/bindings/i2c/i2c-ocores.txt |2 +-
 drivers/i2c/busses/i2c-ocores.c|  187 ++--
 2 files changed, 138 insertions(+), 51 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


Re: [PATCH v3] i2c-hid: introduce HID over i2c specification implementation

2012-11-15 Thread Benjamin Tissoires
On Thu, Nov 15, 2012 at 2:51 PM, Jiri Kosina  wrote:
> On Mon, 12 Nov 2012, Benjamin Tissoires wrote:
>
>> Microsoft published the protocol specification of HID over i2c:
>> http://msdn.microsoft.com/en-us/library/windows/hardware/hh852380.aspx
>>
>> This patch introduces an implementation of this protocol.
>>
>> This implementation does not includes the ACPI part of the specification.
>> This will come when ACPI 5.0 devices enumeration will be available.
>>
>> Once the ACPI part is done, OEM will not have to declare HID over I2C
>> devices in their platform specific driver.
>>
>> Signed-off-by: Benjamin Tissoires 
>
> Out of curiosity -- has this been tested on a real device (is there any
> such device available anyway?), or is that just the implementation of the
> defined protocol?

It has been tested on an ELAN microelectronics device (a prototype),
on an odroid-x board. That's how we figure out the bug in the
set_report command.
I think we manage to test all main features of the protocol
(get_report, irqs, hid descriptor, report descriptors, set_report).

I'm currently waiting for a Synaptics touchpad to check if it's also
working with their devices.

The thing is that HID over i2c for x86 platform will presumably
require the Haswell platform from Intel (we need ACPI 5 for
enumeration), but it would be very nice to get this in the kernel just
before hardware arrive on the market :)
However, I won't be surprise if android OEMs also start using this
specification because it won't force them to write kernel drivers...

Cheers,
Benjamin

>
> Thanks,
>
> --
> Jiri Kosina
> SUSE Labs
--
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 v3] i2c-hid: introduce HID over i2c specification implementation

2012-11-15 Thread Jiri Kosina
On Mon, 12 Nov 2012, Benjamin Tissoires wrote:

> Microsoft published the protocol specification of HID over i2c:
> http://msdn.microsoft.com/en-us/library/windows/hardware/hh852380.aspx
> 
> This patch introduces an implementation of this protocol.
> 
> This implementation does not includes the ACPI part of the specification.
> This will come when ACPI 5.0 devices enumeration will be available.
> 
> Once the ACPI part is done, OEM will not have to declare HID over I2C
> devices in their platform specific driver.
> 
> Signed-off-by: Benjamin Tissoires 

Out of curiosity -- has this been tested on a real device (is there any 
such device available anyway?), or is that just the implementation of the 
defined protocol?

Thanks,

-- 
Jiri Kosina
SUSE Labs
--
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: don't save a value only needed for read-clearing

2012-11-15 Thread Felipe Balbi
Hi,

On Thu, Nov 15, 2012 at 03:34:10PM +0530, Shubhrajyoti Datta wrote:
> On Thu, Nov 15, 2012 at 12:20 AM, Wolfram Sang  wrote:
> >
> >> > This makes one of my code analyzers happy and makes me a part of the
> >>
> >> anything open source which we could all be using ? :-)
> >
> > 'my' as in 'one of those I am using'. It was cppcheck which found that
> > flaw. Its use for kernel code is limited, but it does find one or the
> > other thing.
> 
> sparse did not complain though.
> So it seems it helps to run multiple static tools:-)

or sending a patch to sparse ;-)

-- 
balbi


signature.asc
Description: Digital signature


[PATCH 7/7] decode-dimms: Strip former manufacturer name in side-by-side mode

2012-11-15 Thread Jean Delvare
Strip former manufacturer name in side-by-side output mode, to avoid
overly large columns.
---
 eeprom/decode-dimms |1 +
 1 file changed, 1 insertion(+)

--- i2c-tools.orig/eeprom/decode-dimms  2012-11-15 11:47:17.878976012 +0100
+++ i2c-tools/eeprom/decode-dimms   2012-11-15 11:47:19.684976039 +0100
@@ -342,6 +342,7 @@ sub manufacturer_ddr3($$)
return "Invalid" if parity($code) != 1;
return "Unknown" if ($code & 0x7F) - 1 > $vendors[$count & 0x7F];
$manufacturer = $vendors[$count & 0x7F][($code & 0x7F) - 1];
+   $manufacturer =~ s/ \(former .*\)$// if $opt_side_by_side;
$manufacturer .= "? (Invalid parity)" if parity($count) != 1;
return $manufacturer;
 }

-- 
Jean Delvare
--
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 6/7] decode-dimms: Bad manufacturer page count parity is not fatal

2012-11-15 Thread Jean Delvare
If DDR3 manufacturer page count parity is wrong, still print the
manufacturer name (if valid) but add a question mark.
---
 eeprom/decode-dimms |9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

--- i2c-tools.orig/eeprom/decode-dimms  2012-11-15 11:45:52.020974740 +0100
+++ i2c-tools/eeprom/decode-dimms   2012-11-15 11:47:17.878976012 +0100
@@ -337,10 +337,13 @@ sub parity($)
 sub manufacturer_ddr3($$)
 {
my ($count, $code) = @_;
-   return "Invalid" if parity($count) != 1;
+   my $manufacturer;
+
return "Invalid" if parity($code) != 1;
-   return (($code & 0x7F) - 1 > $vendors[$count & 0x7F]) ? "Unknown" :
-   $vendors[$count & 0x7F][($code & 0x7F) - 1];
+   return "Unknown" if ($code & 0x7F) - 1 > $vendors[$count & 0x7F];
+   $manufacturer = $vendors[$count & 0x7F][($code & 0x7F) - 1];
+   $manufacturer .= "? (Invalid parity)" if parity($count) != 1;
+   return $manufacturer;
 }
 
 sub manufacturer(@)

-- 
Jean Delvare
--
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 4/4] i2c-s3c2410: do not special case HDMIPHY stuck bus detection

2012-11-15 Thread Naveen Krishna Chatradhi
From: Daniel Kurtz 

Commit "i2c-s3c2410: Add HDMIPHY quirk for S3C2440" added support for
HDMIPHY with some special handling in s3c24xx_i2c_set_master:

"due to unknown reason (probably HW bug in HDMIPHY and/or the controller)
a transfer fails to finish. The controller hangs after sending the last
byte, the workaround for this bug is resetting the controller after each
transfer"

The "unknown reason" was that the proper sequence for generating a STOP
condition wasn't being followed as per the datasheet. Since this is fixed
by "PATCH: i2c-s3c2410: do not generate STOP for QUIRK_HDMIPHY buses",
remove the special handling.

Signed-off-by: Daniel Kurtz 
Cc: Daniel Kurtz 
Signed-off-by: Naveen Krishna Chatradhi 
---
 drivers/i2c/busses/i2c-s3c2410.c |   16 
 1 file changed, 16 deletions(-)

diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 362a307..c76ca7c 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -531,13 +531,6 @@ static int s3c24xx_i2c_set_master(struct s3c24xx_i2c *i2c)
unsigned long iicstat;
int timeout = 400;
 
-   /* the timeout for HDMIPHY is reduced to 10 ms because
-* the hangup is expected to happen, so waiting 400 ms
-* causes only unnecessary system hangup
-*/
-   if (i2c->quirks & QUIRK_HDMIPHY)
-   timeout = 10;
-
while (timeout-- > 0) {
iicstat = readl(i2c->regs + S3C2410_IICSTAT);
 
@@ -547,15 +540,6 @@ static int s3c24xx_i2c_set_master(struct s3c24xx_i2c *i2c)
msleep(1);
}
 
-   /* hang-up of bus dedicated for HDMIPHY occurred, resetting */
-   if (i2c->quirks & QUIRK_HDMIPHY) {
-   writel(0, i2c->regs + S3C2410_IICCON);
-   writel(0, i2c->regs + S3C2410_IICSTAT);
-   writel(0, i2c->regs + S3C2410_IICDS);
-
-   return 0;
-   }
-
return -ETIMEDOUT;
 }
 
-- 
1.7.9.5

--
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 3/4] i2c-s3c2410: use exponential back off while polling for bus idle

2012-11-15 Thread Naveen Krishna Chatradhi
From: Daniel Kurtz 

Usually, the i2c controller has finished emitting the i2c STOP before the
driver reaches the bus idle polling loop.  Optimize for this most common
case by reading IICSTAT first and potentially skipping the loop.

If the cpu is faster than the hardware, we wait for bus idle in a polling
loop.  However, since the duration of one iteration of the loop is
dependent on cpu freq, and this i2c IP is used on many different systems,
use a time based loop timeout (5 ms).

We would like very low latencies to detect bus idle for the normal
'fast' case.  However, if a device is slow to release the bus for some
reason, it could hold off the STOP generation for up to several
milliseconds.  Rapidly polling for bus idle would seriously load the CPU
while waiting for it to release the bus.  So, use a partial exponential
backoff as a compromise between idle detection latency and cpu load.

Signed-off-by: Daniel Kurtz 
Cc: Olof Johansson 
Cc: Benson Leung 
Cc: Doug Anderson 
Cc: Daniel Kurtz 
Signed-off-by: Naveen Krishna Chatradhi 
---
 drivers/i2c/busses/i2c-s3c2410.c |   67 ++
 1 file changed, 47 insertions(+), 20 deletions(-)

diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index fc4bf35..362a307 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -49,6 +49,9 @@
 #define QUIRK_HDMIPHY  (1 << 1)
 #define QUIRK_NO_GPIO  (1 << 2)
 
+/* Max time to wait for bus to become idle after a xfer (in us) */
+#define S3C2410_IDLE_TIMEOUT   5000
+
 /* i2c controller state */
 enum s3c24xx_i2c_state {
STATE_IDLE,
@@ -556,6 +559,48 @@ static int s3c24xx_i2c_set_master(struct s3c24xx_i2c *i2c)
return -ETIMEDOUT;
 }
 
+/* s3c24xx_i2c_wait_idle
+ *
+ * wait for the i2c bus to become idle.
+*/
+
+static void s3c24xx_i2c_wait_idle(struct s3c24xx_i2c *i2c)
+{
+   unsigned long iicstat;
+   ktime_t start, now;
+   unsigned long delay;
+
+   /* ensure the stop has been through the bus */
+
+   dev_dbg(i2c->dev, "waiting for bus idle\n");
+
+   start = now = ktime_get();
+
+   /*
+* Most of the time, the bus is already idle within a few usec of the
+* end of a transaction.  However, really slow i2c devices can stretch
+* the clock, delaying STOP generation.
+*
+* As a compromise between idle detection latency for the normal, fast
+* case, and system load in the slow device case, use an exponential
+* back off in the polling loop, up to 1/10th of the total timeout,
+* then continue to poll at a constant rate up to the timeout.
+*/
+   iicstat = readl(i2c->regs + S3C2410_IICSTAT);
+   delay = 1;
+   while ((iicstat & S3C2410_IICSTAT_START) &&
+  ktime_us_delta(now, start) < S3C2410_IDLE_TIMEOUT) {
+   usleep_range(delay, 2 * delay);
+   if (delay < S3C2410_IDLE_TIMEOUT / 10)
+   delay <<= 1;
+   now = ktime_get();
+   iicstat = readl(i2c->regs + S3C2410_IICSTAT);
+   }
+
+   if (iicstat & S3C2410_IICSTAT_START)
+   dev_warn(i2c->dev, "timeout waiting for bus idle\n");
+}
+
 /* s3c24xx_i2c_doxfer
  *
  * this starts an i2c transfer
@@ -564,8 +609,7 @@ static int s3c24xx_i2c_set_master(struct s3c24xx_i2c *i2c)
 static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
  struct i2c_msg *msgs, int num)
 {
-   unsigned long iicstat, timeout;
-   int spins = 20;
+   unsigned long timeout;
int ret;
 
if (i2c->suspended)
@@ -603,24 +647,7 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
if (i2c->quirks & QUIRK_HDMIPHY)
goto out;
 
-   /* ensure the stop has been through the bus */
-
-   dev_dbg(i2c->dev, "waiting for bus idle\n");
-
-   /* first, try busy waiting briefly */
-   do {
-   cpu_relax();
-   iicstat = readl(i2c->regs + S3C2410_IICSTAT);
-   } while ((iicstat & S3C2410_IICSTAT_START) && --spins);
-
-   /* if that timed out sleep */
-   if (!spins) {
-   msleep(1);
-   iicstat = readl(i2c->regs + S3C2410_IICSTAT);
-   }
-
-   if (iicstat & S3C2410_IICSTAT_START)
-   dev_warn(i2c->dev, "timeout waiting for bus idle\n");
+   s3c24xx_i2c_wait_idle(i2c);
 
  out:
return ret;
-- 
1.7.9.5

--
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 2/4] i2c-s3c2410: do not generate STOP for QUIRK_HDMIPHY

2012-11-15 Thread Naveen Krishna Chatradhi
From: Daniel Kurtz 

buses

The datasheet says that the STOP sequence should be:
 1) I2CSTAT.5 = 0   - Clear BUSY (or 'generate STOP')
 2) I2CCON.4 = 0- Clear IRQPEND
 3) Wait until the stop condition takes effect.
 4*) I2CSTAT.4 = 0  - Clear TXRXEN

Where, step "4*" is only for buses with the "HDMIPHY" quirk.

However, after much experimentation, it appears that:
 a) normal buses automatically clear BUSY and transition from
Master->Slave when they complete generating a STOP condition.
Therefore, step (3) can be done in doxfer() by polling I2CCON.4
after starting the STOP generation here.
 b) HDMIPHY bus does neither, so there is no way to do step 3.
There is no indication when this bus has finished generating STOP.

In fact, we have found that as soon as the IRQPEND bit is cleared in
step 2, the HDMIPHY bus generates the STOP condition, and then immediately
starts transferring another data byte, even though the bus is supposedly
stopped.  This is presumably because the bus is still in "Master" mode,
and its BUSY bit is still set.

To avoid these extra post-STOP transactions on HDMI phy devices, we just
disable Serial Output on the bus (I2CSTAT.4 = 0) directly, instead of
first generating a proper STOP condition.  This should float SDA & SCK
terminating the transfer.  Subsequent transfers start with a proper START
condition, and proceed normally.

The HDMIPHY bus is an internal bus that always has exactly two devices,
the host as Master and the HDMIPHY device as the slave. Skipping the STOP
condition has been tested on this bus and works.

Also, since we disable the bus directly from the isr, we can skip the bus
idle polling loop at the end of doxfer().

Signed-off-by: Daniel Kurtz 
Cc: Doug Anderson 
Cc: Daniel Kurtz 
Signed-off-by: Naveen Krishna Chatradhi 
---
 drivers/i2c/busses/i2c-s3c2410.c |   47 --
 1 file changed, 45 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 155cb04..fc4bf35 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -234,8 +234,47 @@ static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c 
*i2c, int ret)
 
dev_dbg(i2c->dev, "STOP\n");
 
-   /* stop the transfer */
-   iicstat &= ~S3C2410_IICSTAT_START;
+   /*
+* The datasheet says that the STOP sequence should be:
+*  1) I2CSTAT.5 = 0- Clear BUSY (or 'generate STOP')
+*  2) I2CCON.4 = 0 - Clear IRQPEND
+*  3) Wait until the stop condition takes effect.
+*  4*) I2CSTAT.4 = 0   - Clear TXRXEN
+*
+* Where, step "4*" is only for buses with the "HDMIPHY" quirk.
+*
+* However, after much experimentation, it appears that:
+* a) normal buses automatically clear BUSY and transition from
+*Master->Slave when they complete generating a STOP condition.
+*Therefore, step (3) can be done in doxfer() by polling I2CCON.4
+*after starting the STOP generation here.
+* b) HDMIPHY bus does neither, so there is no way to do step 3.
+*There is no indication when this bus has finished generating
+*STOP.
+*
+* In fact, we have found that as soon as the IRQPEND bit is cleared in
+* step 2, the HDMIPHY bus generates the STOP condition, and then
+* immediately starts transferring another data byte, even though the
+* bus is supposedly stopped.  This is presumably because the bus is
+* still in "Master" mode, and its BUSY bit is still set.
+*
+* To avoid these extra post-STOP transactions on HDMI phy devices, we
+* just disable Serial Output on the bus (I2CSTAT.4 = 0) directly,
+* instead of first generating a proper STOP condition.  This should
+* float SDA & SCK terminating the transfer.  Subsequent transfers
+*  start with a proper START condition, and proceed normally.
+*
+* The HDMIPHY bus is an internal bus that always has exactly two
+* devices, the host as Master and the HDMIPHY device as the slave.
+* Skipping the STOP condition has been tested on this bus and works.
+*/
+   if (i2c->quirks & QUIRK_HDMIPHY) {
+   /* Stop driving the I2C pins */
+   iicstat &= ~S3C2410_IICSTAT_TXRXEN;
+   } else {
+   /* stop the transfer */
+   iicstat &= ~S3C2410_IICSTAT_START;
+   }
writel(iicstat, i2c->regs + S3C2410_IICSTAT);
 
i2c->state = STATE_STOP;
@@ -560,6 +599,10 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
else if (ret != num)
dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret);
 
+   /* For QUIRK_HDMIPHY, bus is already disabled */
+   if (i2c->quirks & QUIRK_HDMIPHY)
+   goto out;
+
/* ensure the stop has been through the bus */
 
dev

[PATCH 1/4] i2c-s3c2410: grab adapter lock while changing i2c clock

2012-11-15 Thread Naveen Krishna Chatradhi
From: Daniel Kurtz 

We probably don't want to change I2C frequency while a transfer is in
progress.  The current implementation grabs a spinlock, but that only
protected the writes to IICCON when starting a message, it didn't protect
against clock changes in the middle of a transaction.

Note: The i2c-core already grabs the adapter lock before calling
s3c24xx_i2c_doxfer(), which ensures that only one caller is issuing a
xfer at a time. This means it is not necessary to disable interrupts
(spin_lock_irqsave) when changing frequencies, since there won't be
any i2c interrupts if there is no on-going xfer.

Lastly, i2c_lock_adapter() may cause the cpufreq_transition to sleep if
if a xfer is in progress, but this is ok since cpufreq notifiers are
called in a kernel thread, and there are already cases where it could
sleep, such as when using i2c to update the output of a voltage
regulator.

Note: the cpufreq part of this change has no functional affect on
exynos, where the i2c clock is independent of the cpufreq.
But, there is a slight perfomance boost since we no longer need to
lock/unlock an additional spinlock.

Signed-off-by: Daniel Kurtz 
Cc: Olof Johansson 
Cc: Doug Anderson 
Cc: Daniel Kurtz 
Signed-off-by: Naveen Krishna Chatradhi 
---
 drivers/i2c/busses/i2c-s3c2410.c |   10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 3e0335f..155cb04 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -59,7 +59,6 @@ enum s3c24xx_i2c_state {
 };
 
 struct s3c24xx_i2c {
-   spinlock_t  lock;
wait_queue_head_t   wait;
unsigned intquirks;
unsigned intsuspended:1;
@@ -540,8 +539,6 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
goto out;
}
 
-   spin_lock_irq(&i2c->lock);
-
i2c->msg = msgs;
i2c->msg_num = num;
i2c->msg_ptr = 0;
@@ -550,7 +547,6 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
 
s3c24xx_i2c_enable_irq(i2c);
s3c24xx_i2c_message_start(i2c, msgs);
-   spin_unlock_irq(&i2c->lock);
 
timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
 
@@ -740,7 +736,6 @@ static int s3c24xx_i2c_cpufreq_transition(struct 
notifier_block *nb,
  unsigned long val, void *data)
 {
struct s3c24xx_i2c *i2c = freq_to_i2c(nb);
-   unsigned long flags;
unsigned int got;
int delta_f;
int ret;
@@ -754,9 +749,9 @@ static int s3c24xx_i2c_cpufreq_transition(struct 
notifier_block *nb,
 
if ((val == CPUFREQ_POSTCHANGE && delta_f < 0) ||
(val == CPUFREQ_PRECHANGE && delta_f > 0)) {
-   spin_lock_irqsave(&i2c->lock, flags);
+   i2c_lock_adapter(&i2c->adap);
ret = s3c24xx_i2c_clockrate(i2c, &got);
-   spin_unlock_irqrestore(&i2c->lock, flags);
+   i2c_unlock_adapter(&i2c->adap);
 
if (ret < 0)
dev_err(i2c->dev, "cannot find frequency\n");
@@ -962,7 +957,6 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
i2c->adap.class   = I2C_CLASS_HWMON | I2C_CLASS_SPD;
i2c->tx_setup = 50;
 
-   spin_lock_init(&i2c->lock);
init_waitqueue_head(&i2c->wait);
 
/* find the clock and enable it */
-- 
1.7.9.5

--
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/4] i2c-s3c2410: Fix a bug and optimize code

2012-11-15 Thread Naveen Krishna Chatradhi
The following set of patches fixes a bug in i2c-s3c2410 driver
with respect to the functioning of dedicated HDMIPHY channel.
1. Removing unwanted spinlock
2. Correcting the Stop sequence
3. Optimizing the wait loop for bus idle.
4. Removing unnecessary HDMI special cases
Respectively.

Daniel Kurtz (4):
  i2c-s3c2410: grab adapter lock while changing i2c clock
  i2c-s3c2410: do not generate STOP for QUIRK_HDMIPHY
  i2c-s3c2410: use exponential back off while polling for bus idle
  i2c-s3c2410: do not special case HDMIPHY stuck bus detection

 drivers/i2c/busses/i2c-s3c2410.c |  134 ++
 1 file changed, 91 insertions(+), 43 deletions(-)

-- 
1.7.9.5

--
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 5/7] decode-dimms: Manufacturer names from Jedec JEP106AJ

2012-11-15 Thread Jean Delvare
Add manufacturer names from Jedec document JEP106AJ.
---
 eeprom/decode-dimms |8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

--- i2c-tools.orig/eeprom/decode-dimms  2012-11-15 11:11:22.0 +0100
+++ i2c-tools/eeprom/decode-dimms   2012-11-15 11:45:52.020974740 +0100
@@ -64,7 +64,7 @@ $revision =~ s/ \([^()]*\)//;
  "Lattice Semi.", "NCR", "Wafer Scale Integration", "IBM",
  "Tristar", "Visic", "Intl. CMOS Technology", "SSSI",
  "MicrochipTechnology", "Ricoh Ltd.", "VLSI", "Micron Technology",
- "Hynix Semiconductor Inc. (former Hyundai Electronics)", "OKI Semiconductor", 
"ACTEL", "Sharp",
+ "SK Hynix (former Hyundai Electronics)", "OKI Semiconductor", "ACTEL", 
"Sharp",
  "Catalyst", "Panasonic", "IDT", "Cypress",
  "DEC", "LSI Logic", "Zarlink (former Plessey)", "UTMC",
  "Thinking Machine", "Thomson CSF", "Integrated CMOS (Vertex)", "Honeywell",
@@ -293,7 +293,11 @@ $revision =~ s/ \([^()]*\)//;
  "Accord Software & Systems Pvt. Ltd.", "Active-Semi Inc.", "Denso 
Corporation", "TLSI Inc.",
  "Shenzhen Daling Electronic Co. Ltd.", "Mustang", "Orca Systems", "Passif 
Semiconductor",
  "GigaDevice Semiconductor (Beijing) Inc.", "Memphis Electronic", "Beckhoff 
Automation GmbH",
- "Harmony Semiconductor Corp (former ProPlus Design Solutions)", "Air 
Computers SRL", "TMT Memory"]
+ "Harmony Semiconductor Corp (former ProPlus Design Solutions)", "Air 
Computers SRL", "TMT Memory",
+ "Eorex Corporation", "Xingtera", "Netsol", "Bestdon Technology Co. Ltd.", 
"Baysand Inc.",
+ "Uroad Technology Co. Ltd. (former Triple Grow Industrial Ltd.)", "Wilk 
Elektronik S.A.",
+ "AAI", "Harman", "Berg Microelectronics Inc.", "ASSIA, Inc.", "Visiontek 
Products LLC",
+ "OCMEMORY", "Welink Solution Inc."]
 );
 
 $use_sysfs = -d '/sys/bus';

-- 
Jean Delvare
--
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 4/7] decode-dimms: Introduce helper function as_ddr

2012-11-15 Thread Jean Delvare
Introduce helper function as_ddr(), hopefully this makes the code a
little more readable. 
---
 eeprom/decode-dimms |   24 
 1 file changed, 16 insertions(+), 8 deletions(-)

--- i2c-tools.orig/eeprom/decode-dimms  2012-11-15 10:52:06.0 +0100
+++ i2c-tools/eeprom/decode-dimms   2012-11-15 10:57:57.171530598 +0100
@@ -830,6 +830,14 @@ sub decode_sdr_sdram($)
(($bytes->[35] >> 7) ? -$temp : $temp) . " ns");
 }
 
+sub as_ddr($$)
+{
+   my ($gen, $ctime) = @_;
+
+   return " as DDR" . ($gen == 1 ? "" : $gen) . "-" .
+  int(2000 / $ctime);
+}
+
 sub ddr_core_timings($)
 {
my ($cas, $ctime, $trcd, $trp, $tras) = @_;
@@ -931,7 +939,7 @@ sub decode_ddr_sdram($)
 
if (exists $cas{$highestCAS}) {
$core_timings = ddr_core_timings($highestCAS, $ctime,
-   $trcd, $trp, $tras) . " as DDR-" . int(2000 / $ctime);
+   $trcd, $trp, $tras) . as_ddr(1, $ctime);
 
$cycle_time = "$ctime ns at CAS $highestCAS";
$access_time = (($bytes->[10] >> 4) * 0.1 + ($bytes->[10] & 
0xf) * 0.01)
@@ -941,7 +949,7 @@ sub decode_ddr_sdram($)
if (exists $cas{$highestCAS-0.5} && spd_written(@$bytes[23..24])) {
$ctime1 = ($bytes->[23] >> 4) + ($bytes->[23] & 0xf) * 0.1;
$core_timings .= "\n".ddr_core_timings($highestCAS-0.5, $ctime1,
-   $trcd, $trp, $tras) . " as DDR-" . int(2000 / $ctime1);
+   $trcd, $trp, $tras) . as_ddr(1, $ctime1);
 
$cycle_time .= "\n$ctime1 ns at CAS ".($highestCAS-0.5);
$access_time .= "\n".(($bytes->[24] >> 4) * 0.1 + ($bytes->[24] 
& 0xf) * 0.01)
@@ -951,7 +959,7 @@ sub decode_ddr_sdram($)
if (exists $cas{$highestCAS-1} && spd_written(@$bytes[25..26])) {
$ctime2 = ($bytes->[25] >> 4) + ($bytes->[25] & 0xf) * 0.1,
$core_timings .= "\n".ddr_core_timings($highestCAS-1, $ctime2,
-   $trcd, $trp, $tras) . " as DDR-" . int(2000 / $ctime2);
+   $trcd, $trp, $tras) . as_ddr(1, $ctime2);
 
$cycle_time .= "\n$ctime2 ns at CAS ".($highestCAS-1);
$access_time .= "\n".(($bytes->[26] >> 4) * 0.1 + ($bytes->[26] 
& 0xf) * 0.01)
@@ -984,7 +992,7 @@ sub decode_ddr_sdram($)
}
 
printl_cond($ctime >= $ctime_min && ($ctime_max < 1 || $ctime 
<= $ctime_max),
-   "tCL-tRCD-tRP-tRAS as DDR-".int(2000 / $ctime),
+   "tCL-tRCD-tRP-tRAS" . as_ddr(1, $ctime),
ddr_core_timings($best_cas, $ctime,
 $trcd, $trp, $tras));
}
@@ -1182,7 +1190,7 @@ sub decode_ddr2_sdram($)
 
if (exists $cas{$highestCAS}) {
$core_timings = ddr_core_timings($highestCAS, $ctime,
-   $trcd, $trp, $tras) . " as DDR2-" . int(2000 / $ctime);
+   $trcd, $trp, $tras) . as_ddr(2, $ctime);
 
$cycle_time = tns($ctime) . " at CAS $highestCAS (tCK min)";
$access_time = tns(ddr2_sdram_atime($bytes->[10]))
@@ -1192,7 +1200,7 @@ sub decode_ddr2_sdram($)
if (exists $cas{$highestCAS-1} && spd_written(@$bytes[23..24])) {
$ctime1 = ddr2_sdram_ctime($bytes->[23]);
$core_timings .= "\n".ddr_core_timings($highestCAS-1, $ctime1,
-   $trcd, $trp, $tras) . " as DDR2-" . int(2000 / $ctime1);
+   $trcd, $trp, $tras) . as_ddr(2, $ctime1);
 
$cycle_time .= "\n".tns($ctime1)
 . " at CAS ".($highestCAS-1);
@@ -1203,7 +1211,7 @@ sub decode_ddr2_sdram($)
if (exists $cas{$highestCAS-2} && spd_written(@$bytes[25..26])) {
$ctime2 = ddr2_sdram_ctime($bytes->[25]);
$core_timings .= "\n".ddr_core_timings($highestCAS-2, $ctime2,
-   $trcd, $trp, $tras) . " as DDR2-" . int(2000 / $ctime2);
+   $trcd, $trp, $tras) . as_ddr(2, $ctime2);
 
$cycle_time .= "\n".tns($ctime2)
 . " at CAS ".($highestCAS-2);
@@ -1236,7 +1244,7 @@ sub decode_ddr2_sdram($)
}
 
printl_cond($ctime >= $ctime_min && $ctime <= $ctime_max,
-   "tCL-tRCD-tRP-tRAS as DDR2-".int(2000 / $ctime),
+   "tCL-tRCD-tRP-tRAS" . as_ddr(2,$ctime),
ddr_core_timings($best_cas, $ctime,
 $trcd, $trp, $tras));
}

-- 
Jean Delvare
--
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 3/7] decode-dimms: Delete ddr2_core_timings

2012-11-15 Thread Jean Delvare
ddr2_core_timings is now the exact same function as ddr_core_timings
so delete the former and user the latter everywhere.
---
 eeprom/decode-dimms |   18 +-
 1 file changed, 5 insertions(+), 13 deletions(-)

--- i2c-tools.orig/eeprom/decode-dimms  2012-11-15 09:59:02.0 +0100
+++ i2c-tools/eeprom/decode-dimms   2012-11-15 09:59:33.500544032 +0100
@@ -1091,14 +1091,6 @@ sub ddr2_refresh_rate($)
   ($byte & 0x80 ? " - Self Refresh" : "");
 }
 
-sub ddr2_core_timings($)
-{
-   my ($cas, $ctime, $trcd, $trp, $tras) = @_;
-
-   return $cas . "-" . ceil($trcd/$ctime) . "-" . ceil($trp/$ctime) .
-   "-" . ceil($tras/$ctime);
-}
-
 # Parameter: EEPROM bytes 0-127 (using 3-62)
 sub decode_ddr2_sdram($)
 {
@@ -1189,7 +1181,7 @@ sub decode_ddr2_sdram($)
my ($cycle_time, $access_time, $core_timings);
 
if (exists $cas{$highestCAS}) {
-   $core_timings = ddr2_core_timings($highestCAS, $ctime,
+   $core_timings = ddr_core_timings($highestCAS, $ctime,
$trcd, $trp, $tras) . " as DDR2-" . int(2000 / $ctime);
 
$cycle_time = tns($ctime) . " at CAS $highestCAS (tCK min)";
@@ -1199,7 +1191,7 @@ sub decode_ddr2_sdram($)
 
if (exists $cas{$highestCAS-1} && spd_written(@$bytes[23..24])) {
$ctime1 = ddr2_sdram_ctime($bytes->[23]);
-   $core_timings .= "\n".ddr2_core_timings($highestCAS-1, $ctime1,
+   $core_timings .= "\n".ddr_core_timings($highestCAS-1, $ctime1,
$trcd, $trp, $tras) . " as DDR2-" . int(2000 / $ctime1);
 
$cycle_time .= "\n".tns($ctime1)
@@ -1210,7 +1202,7 @@ sub decode_ddr2_sdram($)
 
if (exists $cas{$highestCAS-2} && spd_written(@$bytes[25..26])) {
$ctime2 = ddr2_sdram_ctime($bytes->[25]);
-   $core_timings .= "\n".ddr2_core_timings($highestCAS-2, $ctime2,
+   $core_timings .= "\n".ddr_core_timings($highestCAS-2, $ctime2,
$trcd, $trp, $tras) . " as DDR2-" . int(2000 / $ctime2);
 
$cycle_time .= "\n".tns($ctime2)
@@ -1245,8 +1237,8 @@ sub decode_ddr2_sdram($)
 
printl_cond($ctime >= $ctime_min && $ctime <= $ctime_max,
"tCL-tRCD-tRP-tRAS as DDR2-".int(2000 / $ctime),
-   ddr2_core_timings($best_cas, $ctime,
- $trcd, $trp, $tras));
+   ddr_core_timings($best_cas, $ctime,
+$trcd, $trp, $tras));
}
 
 # more timing information


-- 
Jean Delvare
--
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 2/7] decode-dimms: Print timings at standard DDR speeds

2012-11-15 Thread Jean Delvare
Print timings at standard DDR speeds. The minimum cycle times for the
3 supported CAS latency values do not necessarily match standard
speeds, and even if they do, they may not cover all standard speeds.
Display the timings at all standard supported speeds. This makes it
easier to figure out which memory modules will work well together
without tinkering with BIOS options.
---
 eeprom/decode-dimms |   46 ++
 1 file changed, 34 insertions(+), 12 deletions(-)

--- i2c-tools.orig/eeprom/decode-dimms  2012-11-15 09:37:36.0 +0100
+++ i2c-tools/eeprom/decode-dimms   2012-11-15 10:40:13.765625180 +0100
@@ -835,7 +835,7 @@ sub ddr_core_timings($)
my ($cas, $ctime, $trcd, $trp, $tras) = @_;
 
return $cas . "-" . ceil($trcd/$ctime) . "-" . ceil($trp/$ctime) .
-   "-" . ceil($tras/$ctime) . " as DDR-" . int(2000 / $ctime);
+   "-" . ceil($tras/$ctime);
 }
 
 # Parameter: EEPROM bytes 0-127 (using 3-62)
@@ -843,6 +843,7 @@ sub decode_ddr_sdram($)
 {
my $bytes = shift;
my $temp;
+   my ($ctime, $ctime1, $ctime2, $ctime_min, $ctime_max);
 
 # SPD revision
printl_cond($bytes->[62] != 0xff, "SPD Revision",
@@ -851,7 +852,7 @@ sub decode_ddr_sdram($)
 # speed
prints("Memory Characteristics");
 
-   my $ctime = ($bytes->[9] >> 4) + ($bytes->[9] & 0xf) * 0.1;
+   $ctime_min = $ctime = ($bytes->[9] >> 4) + ($bytes->[9] & 0xf) * 0.1;
my $ddrclk = 2 * (1000 / $ctime);
my $tbits = ($bytes->[7] * 256) + $bytes->[6];
if (($bytes->[11] == 2) || ($bytes->[11] == 1)) { $tbits = $tbits - 8; }
@@ -930,7 +931,7 @@ sub decode_ddr_sdram($)
 
if (exists $cas{$highestCAS}) {
$core_timings = ddr_core_timings($highestCAS, $ctime,
-   $trcd, $trp, $tras);
+   $trcd, $trp, $tras) . " as DDR-" . int(2000 / $ctime);
 
$cycle_time = "$ctime ns at CAS $highestCAS";
$access_time = (($bytes->[10] >> 4) * 0.1 + ($bytes->[10] & 
0xf) * 0.01)
@@ -938,25 +939,27 @@ sub decode_ddr_sdram($)
}
 
if (exists $cas{$highestCAS-0.5} && spd_written(@$bytes[23..24])) {
-   $ctime = ($bytes->[23] >> 4) + ($bytes->[23] & 0xf) * 0.1;
-   $core_timings .= "\n".ddr_core_timings($highestCAS-0.5, $ctime,
-   $trcd, $trp, $tras);
+   $ctime1 = ($bytes->[23] >> 4) + ($bytes->[23] & 0xf) * 0.1;
+   $core_timings .= "\n".ddr_core_timings($highestCAS-0.5, $ctime1,
+   $trcd, $trp, $tras) . " as DDR-" . int(2000 / $ctime1);
 
-   $cycle_time .= "\n$ctime ns at CAS ".($highestCAS-0.5);
+   $cycle_time .= "\n$ctime1 ns at CAS ".($highestCAS-0.5);
$access_time .= "\n".(($bytes->[24] >> 4) * 0.1 + ($bytes->[24] 
& 0xf) * 0.01)
  . " ns at CAS ".($highestCAS-0.5);
}
 
if (exists $cas{$highestCAS-1} && spd_written(@$bytes[25..26])) {
-   $ctime = ($bytes->[25] >> 4) + ($bytes->[25] & 0xf) * 0.1,
-   $core_timings .= "\n".ddr_core_timings($highestCAS-1, $ctime,
-   $trcd, $trp, $tras);
+   $ctime2 = ($bytes->[25] >> 4) + ($bytes->[25] & 0xf) * 0.1,
+   $core_timings .= "\n".ddr_core_timings($highestCAS-1, $ctime2,
+   $trcd, $trp, $tras) . " as DDR-" . int(2000 / $ctime2);
 
-   $cycle_time .= "\n$ctime ns at CAS ".($highestCAS-1);
+   $cycle_time .= "\n$ctime2 ns at CAS ".($highestCAS-1);
$access_time .= "\n".(($bytes->[26] >> 4) * 0.1 + ($bytes->[26] 
& 0xf) * 0.01)
  . " ns at CAS ".($highestCAS-1);
}
 
+   $ctime_max = $bytes->[43] == 0xff ? 0 : $bytes->[43]/4;
+
printl_cond(defined $core_timings, "tCL-tRCD-tRP-tRAS", $core_timings);
printl_cond(defined $cycle_time, "Minimum Cycle Time", $cycle_time);
printl_cond(defined $access_time, "Maximum Access Time", $access_time);
@@ -964,8 +967,27 @@ sub decode_ddr_sdram($)
"Maximum Cycle Time (tCK max)",
$bytes->[43] == 0xff ? "No minimum frequency" :
$bytes->[43] == 0 ? "" : # Wouldn't be displayed, prevent 
div by 0
-   tns1($bytes->[43]/4)." (DDR-".int(8000 / $bytes->[43]).")");
+   tns1($ctime_max)." (DDR-".int(8000 / $bytes->[43]).")");
+
+# standard DDR speeds
+   prints("Timings at Standard Speeds");
+   foreach $ctime (5, 6, 7.5, 10) {
+   my $best_cas;
 
+   # Find min CAS latency at this speed
+   if (defined $ctime2 && $ctime >= $ctime2) {
+   $best_cas = $highestCAS-1;
+   } elsif (defined $ctime1 && $ctime >= $ctime1) {
+   $best_cas = $highestCAS-0.5;
+   } else {
+   $best_ca

Re: [PATCH 1/2] i2c: Add possibility for user-defined (i2c-)devices for bus-drivers.

2012-11-15 Thread Alexander Holler

Hello,

Am 15.11.2012 12:04, schrieb Till Harbaum:


There's actually one thing you can do: You device doesn't seem to expose
the i2c bus, anyway. What you have is an rtc connected via usb. So why not
move all the i2c intelligence into the device? Do pure usb-rtc's exist?
Could you perhaps even make your device compatible to one of these?
Then a driver for this would imho have good chances to find their way into
the kernel.


Sorry, but I'm satisfied with what I've done and I didn't do it just to 
get "something" into the kernel. I don't need my patches to become part 
of in the kernel, I can handle them by myself. And my free resources to 
submit patches just became exhausted (again). Maybe in some weeks or 
month ..., I don't know.


Regards,

Alexander
--
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: Fwd: [PATCH 1/7] I2c-nomadik: Fix the usage of wait_for_completion_timeout

2012-11-15 Thread Srinidhi Kasagar
On Thu, Nov 15, 2012 at 11:18:20 +0100, Wolfram Sang wrote:
> On Thu, Nov 15, 2012 at 03:27:42PM +0530, Srinidhi Kasagar wrote:
> > On Thu, Nov 15, 2012 at 10:29:53 +0100, Wolfram Sang wrote:
> > > 
> > > > > -   if (timeout < 0) {
> > > > > -   dev_err(&dev->adev->dev,
> > > > > -   "wait_for_completion_timeout "
> > > > > -   "returned %d waiting for event\n", timeout);
> > > > > -   status = timeout;
> > > > > -   }
> > > > > -
> > > > No, it is wrong. You need to update the status variable in the case of 
> > > > timeout.
> > > 
> > > Looking at the patch context, such code comes later.
> > But it causes regressions; without looking at the "later" code, we can't 
> > afford merging
> > this code now.
> 
> Later as in "a few lines later" not "some time later". Or am I missing
> something else?
I was too fast in reading emails after my short vacation...Sorry.

Acked-by: srinidhi kasagar 

regards/srinidhi
--
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/7] sensors-detect: Print timings at standard DDR2 speeds

2012-11-15 Thread Jean Delvare
Print timings at standard DDR2 speeds. The minimum cycle times for the
3 supported CAS latency values do not necessarily match standard
speeds, and even if they do, they may not cover all standard speeds.
Display the timings at all standard supported speeds. This makes it
easier to figure out which memory modules will work well together
without tinkering with BIOS options.
---
 eeprom/decode-dimms |   51 ---
 1 file changed, 36 insertions(+), 15 deletions(-)

--- i2c-tools.orig/eeprom/decode-dimms  2012-10-25 14:02:21.0 +0200
+++ i2c-tools/eeprom/decode-dimms   2012-11-15 09:37:36.686924305 +0100
@@ -1074,7 +1074,7 @@ sub ddr2_core_timings($)
my ($cas, $ctime, $trcd, $trp, $tras) = @_;
 
return $cas . "-" . ceil($trcd/$ctime) . "-" . ceil($trp/$ctime) .
-   "-" . ceil($tras/$ctime) . " as DDR2-" . int(2000 / $ctime);
+   "-" . ceil($tras/$ctime);
 }
 
 # Parameter: EEPROM bytes 0-127 (using 3-62)
@@ -1082,7 +1082,7 @@ sub decode_ddr2_sdram($)
 {
my $bytes = shift;
my $temp;
-   my $ctime;
+   my ($ctime, $ctime1, $ctime2, $ctime_min, $ctime_max);
 
 # SPD revision
printl_cond($bytes->[62] != 0xff, "SPD Revision",
@@ -1091,7 +1091,7 @@ sub decode_ddr2_sdram($)
 # speed
prints("Memory Characteristics");
 
-   $ctime = ddr2_sdram_ctime($bytes->[9]);
+   $ctime_min = $ctime = ddr2_sdram_ctime($bytes->[9]);
my $ddrclk = 2 * (1000 / $ctime);
my $tbits = ($bytes->[7] * 256) + $bytes->[6];
if ($bytes->[11] & 0x03) { $tbits = $tbits - 8; }
@@ -1168,7 +1168,7 @@ sub decode_ddr2_sdram($)
 
if (exists $cas{$highestCAS}) {
$core_timings = ddr2_core_timings($highestCAS, $ctime,
-   $trcd, $trp, $tras);
+   $trcd, $trp, $tras) . " as DDR2-" . int(2000 / $ctime);
 
$cycle_time = tns($ctime) . " at CAS $highestCAS (tCK min)";
$access_time = tns(ddr2_sdram_atime($bytes->[10]))
@@ -1176,35 +1176,56 @@ sub decode_ddr2_sdram($)
}
 
if (exists $cas{$highestCAS-1} && spd_written(@$bytes[23..24])) {
-   $ctime = ddr2_sdram_ctime($bytes->[23]);
-   $core_timings .= "\n".ddr2_core_timings($highestCAS-1, $ctime,
-   $trcd, $trp, $tras);
+   $ctime1 = ddr2_sdram_ctime($bytes->[23]);
+   $core_timings .= "\n".ddr2_core_timings($highestCAS-1, $ctime1,
+   $trcd, $trp, $tras) . " as DDR2-" . int(2000 / $ctime1);
 
-   $cycle_time .= "\n".tns($ctime)
+   $cycle_time .= "\n".tns($ctime1)
 . " at CAS ".($highestCAS-1);
$access_time .= "\n".tns(ddr2_sdram_atime($bytes->[24]))
  . " at CAS ".($highestCAS-1);
}
 
if (exists $cas{$highestCAS-2} && spd_written(@$bytes[25..26])) {
-   $ctime = ddr2_sdram_ctime($bytes->[25]);
-   $core_timings .= "\n".ddr2_core_timings($highestCAS-2, $ctime,
-   $trcd, $trp, $tras);
+   $ctime2 = ddr2_sdram_ctime($bytes->[25]);
+   $core_timings .= "\n".ddr2_core_timings($highestCAS-2, $ctime2,
+   $trcd, $trp, $tras) . " as DDR2-" . int(2000 / $ctime2);
 
-   $cycle_time .= "\n".tns($ctime)
+   $cycle_time .= "\n".tns($ctime2)
 . " at CAS ".($highestCAS-2);
$access_time .= "\n".tns(ddr2_sdram_atime($bytes->[26]))
  . " at CAS ".($highestCAS-2);
}
 
+   $ctime_max = ddr2_sdram_ctime($bytes->[43]);
+
printl_cond(defined $core_timings, "tCL-tRCD-tRP-tRAS", $core_timings);
printl_cond(defined $cycle_time, "Minimum Cycle Time", $cycle_time);
printl_cond(defined $access_time, "Maximum Access Time", $access_time);
-   $temp = ddr2_sdram_ctime($bytes->[43]);
printl_cond(($bytes->[43] & 0xf0) && $bytes->[43] != 0xff,
"Maximum Cycle Time (tCK max)",
-   $temp == 0 ? "" : # Wouldn't be displayed, prevent div by 0
-   tns($temp)." (DDR2-".int(2000 / $temp).")");
+   $ctime_max == 0 ? "" : # Wouldn't be displayed, prevent div 
by 0
+   tns($ctime_max)." (DDR2-".int(2000 / $ctime_max).")");
+
+# standard DDR2 speeds
+   prints("Timings at Standard Speeds");
+   foreach $ctime (1.875, 2.5, 3, 3.75, 5) {
+   my $best_cas;
+
+   # Find min CAS latency at this speed
+   if (defined $ctime2 && $ctime >= $ctime2) {
+   $best_cas = $highestCAS-2;
+   } elsif (defined $ctime1 && $ctime >= $ctime1) {
+   $best_cas = $highestCAS-1;
+   } else {
+   $best_cas = $highestCAS;
+   }
+
+   printl_cond($

[PATCH 0/7] Improvements to decode-dimms

2012-11-15 Thread Jean Delvare
Here is a patch series improving decode-dimms:
* Show timings at all standard DDR and DDR2 speeds.
* Code refactoring.
* New manufacturer names from JEP106AJ.
* Smarter decoding of manufacturer names.

-- 
Jean Delvare
--
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 v4 2/2] i2c: i2c-ocores: Add support for the GRLIB port of the controller and custom getreg and setreg functions

2012-11-15 Thread Peter Korsgaard
> "Andreas" == Andreas Larsson  writes:

Hi,

 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 setreg functions.

 Andreas> A type is added as the data of the of match table entries. A
 Andreas> new entry with a different compatible string is added to the
 Andreas> table. The type of that entry triggers usage of the grlib
 Andreas> functions.

 Andreas> Signed-off-by: Andreas Larsson 
 Andreas> ---
 Andreas>  Changes since v3:
 Andreas>  - Use a separate entry in the of match table for the grlib
 Andreas>  variant and trigger grlib function usage on type put in the
 Andreas>  data field of that table entry

Thanks. A few more comments:


 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));

It would have been nice to add oc_getreg_8/16/32 functions and always
use the function pointers - But ok, that can be done later.

 
 Andreas>  #ifdef CONFIG_OF
 Andreas> +static int ocores_i2c_get_type(struct platform_device *pdev);
 Andreas> +

Why not just move the implementation up here instead of the forward
declaration?

 
 Andreas> +static int ocores_i2c_get_type(struct platform_device *pdev)
 Andreas> +{
 Andreas> + const struct of_device_id *match;
 Andreas> +
 Andreas> + match = of_match_node(ocores_i2c_match, pdev->dev.of_node);
 Andreas> + if (match)
 Andreas> + return (int)match->data;

Can this ever fail? If not, you might as well do the of_match_node
inline in the probe instead of this helper.

Other than that it looks good.

-- 
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


[PATCH v4 0/2] i2c: i2c-ocores: Add support for sparc, custom set and get functions, and the GRLIB port of the controller

2012-11-15 Thread Andreas Larsson
On sparc, irqs are not present as an IORESOURCE in the struct platform_device
representation. By using platform_get_irq instead of platform_get_resource the
driver works for sparc.

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 

 Changes since v3:
 - Use a separate entry in the of match table for the grlib variant and trigger
   grlib function usage on type put in the data field of that table entry

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

 .../devicetree/bindings/i2c/i2c-ocores.txt |2 +-
 drivers/i2c/busses/i2c-ocores.c|   90 ++--
 2 files changed, 83 insertions(+), 9 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 v4 1/2] i2c: i2c-ocores: Add irq support for sparc

2012-11-15 Thread Andreas Larsson
Add sparc support by using platform_get_irq instead of platform_get_resource.
There are no platform resources of type IORESOURCE_IRQ for sparc, but
platform_get_irq works for sparc. In the non-sparc case platform_get_irq
internally uses platform_get_resource.

Signed-off-by: Andreas Larsson 
Acked-by: Peter Korsgaard 
---
 Changes since v3:
 - None

 drivers/i2c/busses/i2c-ocores.c |   11 ++-
 1 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
index bffd550..1d204cb 100644
--- a/drivers/i2c/busses/i2c-ocores.c
+++ b/drivers/i2c/busses/i2c-ocores.c
@@ -267,7 +267,8 @@ 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 irq;
int ret;
int i;
 
@@ -275,9 +276,9 @@ static int __devinit ocores_i2c_probe(struct 
platform_device *pdev)
if (!res)
return -ENODEV;
 
-   res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-   if (!res2)
-   return -ENODEV;
+   irq = platform_get_irq(pdev, 0);
+   if (irq < 0)
+   return irq;
 
i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
if (!i2c)
@@ -313,7 +314,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


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

2012-11-15 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.

A type is added as the data of the of match table entries. A new entry with a
different compatible string is added to the table. The type of that entry
triggers usage of the grlib functions.

Signed-off-by: Andreas Larsson 
---
 Changes since v3:
 - Use a separate entry in the of match table for the grlib variant and trigger
   grlib function usage on type put in the data field of that table entry

 .../devicetree/bindings/i2c/i2c-ocores.txt |2 +-
 drivers/i2c/busses/i2c-ocores.c|   79 +++-
 2 files changed, 77 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/i2c/i2c-ocores.txt 
b/Documentation/devicetree/bindings/i2c/i2c-ocores.txt
index c15781f..1637c29 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-ocores.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-ocores.txt
@@ -1,7 +1,7 @@
 Device tree configuration for i2c-ocores
 
 Required properties:
-- compatible  : "opencores,i2c-ocores"
+- compatible  : "opencores,i2c-ocores" or "aeroflexgaisler,i2cmst"
 - reg : bus address start and address range size of device
 - interrupts  : interrupt number
 - clock-frequency : frequency of bus clock in Hz
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
index 1d204cb..fc6e6e7 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 */
@@ -71,9 +76,14 @@ struct ocores_i2c {
 #define STATE_READ 3
 #define STATE_ERROR4
 
+#define TYPE_OCORES0
+#define TYPE_GRLIB 1
+
 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 +93,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 +103,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;
@@ -228,6 +274,8 @@ static struct i2c_adapter ocores_adapter = {
 };
 
 #ifdef CONFIG_OF
+static int ocores_i2c_get_type(struct platform_device *pdev);
+
 stat

Re: Fwd: [PATCH 1/7] I2c-nomadik: Fix the usage of wait_for_completion_timeout

2012-11-15 Thread Wolfram Sang
On Thu, Nov 15, 2012 at 03:27:42PM +0530, Srinidhi Kasagar wrote:
> On Thu, Nov 15, 2012 at 10:29:53 +0100, Wolfram Sang wrote:
> > 
> > > > -   if (timeout < 0) {
> > > > -   dev_err(&dev->adev->dev,
> > > > -   "wait_for_completion_timeout "
> > > > -   "returned %d waiting for event\n", timeout);
> > > > -   status = timeout;
> > > > -   }
> > > > -
> > > No, it is wrong. You need to update the status variable in the case of 
> > > timeout.
> > 
> > Looking at the patch context, such code comes later.
> But it causes regressions; without looking at the "later" code, we can't 
> afford merging
> this code now.

Later as in "a few lines later" not "some time later". Or am I missing
something else?

-- 
Pengutronix e.K.   | Wolfram Sang|
Industrial Linux Solutions | http://www.pengutronix.de/  |


signature.asc
Description: Digital signature


Re: [PATCH] i2c: omap: don't save a value only needed for read-clearing

2012-11-15 Thread Shubhrajyoti Datta
On Thu, Nov 15, 2012 at 12:20 AM, Wolfram Sang  wrote:
>
>> > This makes one of my code analyzers happy and makes me a part of the
>>
>> anything open source which we could all be using ? :-)
>
> 'my' as in 'one of those I am using'. It was cppcheck which found that
> flaw. Its use for kernel code is limited, but it does find one or the
> other thing.

sparse did not complain though.
So it seems it helps to run multiple static tools:-)

>
> --
> Pengutronix e.K.   | Wolfram Sang|
> Industrial Linux Solutions | http://www.pengutronix.de/  |
--
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: Fwd: [PATCH 1/7] I2c-nomadik: Fix the usage of wait_for_completion_timeout

2012-11-15 Thread Srinidhi Kasagar
On Thu, Nov 15, 2012 at 10:29:53 +0100, Wolfram Sang wrote:
> 
> > > -   if (timeout < 0) {
> > > -   dev_err(&dev->adev->dev,
> > > -   "wait_for_completion_timeout "
> > > -   "returned %d waiting for event\n", timeout);
> > > -   status = timeout;
> > > -   }
> > > -
> > No, it is wrong. You need to update the status variable in the case of 
> > timeout.
> 
> Looking at the patch context, such code comes later.
But it causes regressions; without looking at the "later" code, we can't afford 
merging
this code now.

regards/srinidhi
--
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: Fwd: [PATCH 1/7] I2c-nomadik: Fix the usage of wait_for_completion_timeout

2012-11-15 Thread Wolfram Sang

> > -   if (timeout < 0) {
> > -   dev_err(&dev->adev->dev,
> > -   "wait_for_completion_timeout "
> > -   "returned %d waiting for event\n", timeout);
> > -   status = timeout;
> > -   }
> > -
> No, it is wrong. You need to update the status variable in the case of 
> timeout.

Looking at the patch context, such code comes later.

-- 
Pengutronix e.K.   | Wolfram Sang|
Industrial Linux Solutions | http://www.pengutronix.de/  |


signature.asc
Description: Digital signature


Re: Fwd: [PATCH 1/7] I2c-nomadik: Fix the usage of wait_for_completion_timeout

2012-11-15 Thread Srinidhi Kasagar
[...]

> From: Chuansheng Liu 
> Date: Tue, Nov 6, 2012 at 6:18 PM
> Subject: [PATCH 1/7] I2c-nomadik: Fix the usage of wait_for_completion_timeout
> To: linus.wall...@linaro.org, w.s...@pengutronix.de
> Cc: linux-arm-ker...@lists.infradead.org,
> linux-ker...@vger.kernel.org, chuansheng@intel.com
> 
> 
> 
> The return value of wait_for_completion_timeout() is always
> >= 0 with unsigned int type.
> 
> So the condition "ret < 0" or "ret >= 0" is pointless.
> 
> Signed-off-by: liu chuansheng 
> ---
>  drivers/i2c/busses/i2c-nomadik.c |   14 --
>  1 files changed, 0 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-nomadik.c 
> b/drivers/i2c/busses/i2c-nomadik.c
> index 02c3115..8b2ffcf 100644
> --- a/drivers/i2c/busses/i2c-nomadik.c
> +++ b/drivers/i2c/busses/i2c-nomadik.c
> @@ -435,13 +435,6 @@ static int read_i2c(struct nmk_i2c_dev *dev, u16 flags)
> timeout = wait_for_completion_timeout(
> &dev->xfer_complete, dev->adap.timeout);
> 
> -   if (timeout < 0) {
> -   dev_err(&dev->adev->dev,
> -   "wait_for_completion_timeout "
> -   "returned %d waiting for event\n", timeout);
> -   status = timeout;
> -   }
> -
No, it is wrong. You need to update the status variable in the case of timeout.
It is used further in nmk_i2c_xfer_one. You could perhaps use

if (timeout == 0) {
 ...and the rest of the code as is
}

regards/srinidhi
--
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 v3 2/2] i2c: i2c-ocores: Add support for the GRLIB port of the controller and custom getreg and setreg functions

2012-11-15 Thread Peter Korsgaard
> "Andreas" == Andreas Larsson  writes:

Hi,

 >> Adding a type define (TYPE_OCORES / TYPE_GRLIB) and a 2nd
 >> of_device_id entry with .data = TYPE_GRLIB, and then using that in
 >> the probe routine would be nicer. Have a look at i2c-at91.c for an
 >> example of a driver doing something like that.

 Andreas> Yes, that is a good idea. Do you think casting to and from
 Andreas> void * in the following solution is too ugly and rather have a
 Andreas> struct pointed to, or do you think that would be unnecessary?

I find the casting OK.

Thanks.

-- 
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: [PATCHv2] i2c: omap: Move the remove constraint

2012-11-15 Thread Jean Pihet
On Thu, Nov 15, 2012 at 9:51 AM, Shubhrajyoti Datta
 wrote:
> On Thu, Nov 15, 2012 at 1:46 PM, Jean Pihet  wrote:
>> Hi Shubhrajyoti,
>>
>> On Thu, Nov 15, 2012 at 8:34 AM, Shubhrajyoti D  wrote:
>>> Currently we just queue the transfer and release the
>>> qos constraints, however we donot wait for the transfer
>> Typo: donot
> Just fixed and resent.
>
>>
>>> to complete to release the constraint. Move the remove
>>> constraint after the bus busy as we are sure that the
>>> transfers are completed by then.
>>>
>>> Signed-off-by: Shubhrajyoti D 
>> Looks good!
>> Acked-by: Jean Pihet 
>
> Thanks for review.

Thanks!

Regards,
Jean

>
>>
>> Regards,
>> Jean
>>
--
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: [PATCHv2] i2c: omap: Move the remove constraint

2012-11-15 Thread Shubhrajyoti Datta
On Thu, Nov 15, 2012 at 1:46 PM, Jean Pihet  wrote:
> Hi Shubhrajyoti,
>
> On Thu, Nov 15, 2012 at 8:34 AM, Shubhrajyoti D  wrote:
>> Currently we just queue the transfer and release the
>> qos constraints, however we donot wait for the transfer
> Typo: donot
Just fixed and resent.

>
>> to complete to release the constraint. Move the remove
>> constraint after the bus busy as we are sure that the
>> transfers are completed by then.
>>
>> Signed-off-by: Shubhrajyoti D 
> Looks good!
> Acked-by: Jean Pihet 

Thanks for review.

>
> Regards,
> Jean
>
--
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


[PATCHv3] i2c: omap: Move the remove constraint

2012-11-15 Thread Shubhrajyoti D
Currently we just queue the transfer and release the
qos constraints, however we do not wait for the transfer
to complete to release the constraint. Move the remove
constraint after the bus busy as we are sure that the
transfers are completed by then.

Acked-by: Jean Pihet 
Signed-off-by: Shubhrajyoti D 
---
v2: rebase to the for-next branch
v3: Fix a typo

 drivers/i2c/busses/i2c-omap.c |7 ---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 482c63d..fabcbe1 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -654,13 +654,14 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg 
msgs[], int num)
break;
}
 
-   if (dev->set_mpu_wkup_lat != NULL)
-   dev->set_mpu_wkup_lat(dev->dev, -1);
-
if (r == 0)
r = num;
 
omap_i2c_wait_for_bb(dev);
+
+   if (dev->set_mpu_wkup_lat != NULL)
+   dev->set_mpu_wkup_lat(dev->dev, -1);
+
 out:
pm_runtime_mark_last_busy(dev->dev);
pm_runtime_put_autosuspend(dev->dev);
-- 
1.7.5.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: [PATCH v3 2/2] i2c: i2c-ocores: Add support for the GRLIB port of the controller and custom getreg and setreg functions

2012-11-15 Thread Andreas Larsson

On 2012-11-13 23:45, Peter Korsgaard wrote:

"Andreas" == Andreas Larsson  writes:


Hi,

  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 setreg functions.

  Andreas> @@ -257,6 +300,14 @@ static int ocores_i2c_of_probe(struct 
platform_device *pdev,

  Andreas>   of_property_read_u32(pdev->dev.of_node, "reg-io-width",
  Andreas>   &i2c->reg_io_width);
  Andreas> +
  Andreas> + if (of_device_is_compatible(pdev->dev.of_node,
  Andreas> + "aeroflexgaisler,i2cmst")) {
  Andreas> + dev_dbg(&pdev->dev, "GRLIB variant of i2c-ocores\n");
  Andreas> + i2c->setreg = oc_setreg_grlib;
  Andreas> + i2c->getreg = oc_getreg_grlib;
  Andreas> + }
  Andreas> +

Please also update the bindings documentation under
Documentation/devicetree/bindings/i2c.


Sure!



With this core you need to add both aeroflexgaisler,i2cmst and
opencores,i2c-ocores to the compatible property, but the grlib variant
is NOT compatible with i2c-ocores, so that's not really nice.

Adding a type define (TYPE_OCORES / TYPE_GRLIB) and a 2nd of_device_id
entry with .data = TYPE_GRLIB, and then using that in the probe routine
would be nicer. Have a look at i2c-at91.c for an example of a driver
doing something like that.


Yes, that is a good idea. Do you think casting to and from void * in the 
following solution is too ugly and rather have a struct pointed to, or do you 
think that would be unnecessary?


static struct of_device_id ocores_i2c_match[] = {
{
.compatible = "opencores,i2c-ocores",
.data = (void *)TYPE_OCORES,
},
{
.compatible = "aeroflexgaisler,i2cmst",
.data = (void *)TYPE_GRLIB,
},
{},
};
MODULE_DEVICE_TABLE(of, ocores_i2c_match);

static int ocores_i2c_get_type(struct platform_device *pdev)
{
const struct of_device_id *match;

match = of_match_node(ocores_i2c_match, pdev->dev.of_node);
if (match)
return (int)match->data;
else
return TYPE_OCORES;
}

Cheers,
Andreas

--
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: [PATCHv2] i2c: omap: Move the remove constraint

2012-11-15 Thread Jean Pihet
Hi Shubhrajyoti,

On Thu, Nov 15, 2012 at 8:34 AM, Shubhrajyoti D  wrote:
> Currently we just queue the transfer and release the
> qos constraints, however we donot wait for the transfer
Typo: donot

> to complete to release the constraint. Move the remove
> constraint after the bus busy as we are sure that the
> transfers are completed by then.
>
> Signed-off-by: Shubhrajyoti D 
Looks good!
Acked-by: Jean Pihet 

Regards,
Jean

> ---
> v2: rebase to the for-next branch
>
>  drivers/i2c/busses/i2c-omap.c |7 ---
>  1 files changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index 482c63d..fabcbe1 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -654,13 +654,14 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg 
> msgs[], int num)
> break;
> }
>
> -   if (dev->set_mpu_wkup_lat != NULL)
> -   dev->set_mpu_wkup_lat(dev->dev, -1);
> -
> if (r == 0)
> r = num;
>
> omap_i2c_wait_for_bb(dev);
> +
> +   if (dev->set_mpu_wkup_lat != NULL)
> +   dev->set_mpu_wkup_lat(dev->dev, -1);
> +
>  out:
> pm_runtime_mark_last_busy(dev->dev);
> pm_runtime_put_autosuspend(dev->dev);
> --
> 1.7.5.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
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