Re: [PATCH v2] i2c: add Renesas R-Car I2C driver

2012-09-28 Thread Shubhrajyoti Datta
On Fri, Sep 28, 2012 at 11:26 AM, Kuninori Morimoto
kuninori.morimoto...@renesas.com wrote:

 Dear Shubhrajyoti

 Thank you for your comment.

 Hi A few suggestions,

 On Tue, Aug 28, 2012 at 2:07 PM, Kuninori Morimoto
 kuninori.morimoto...@renesas.com wrote:
  R-Car I2C is similar with SH7760 I2C.
  But the SH7760 I2C driver had many workaround operations, since H/W had 
  bugs.
  Thus, it was pointless to keep compatible between SH7760 and R-Car I2C 
  drivers.
  This patch creates new Renesas R-Car I2C driver.
 
  Signed-off-by: Kuninori Morimoto kuninori.morimoto...@renesas.com
  ---
  v1 - v2
 
   - removed #if 0 function
   - add explanation on rcar_i2c_bus_barrier()
   - removed IGNORE_NAK support
   - rename rcar_i2c_soft_reset() - rcar_i2c_init()
   - removed devm_kfree/devm_iounmap
   - __raw_writel/readl = writel/readl
   - removed un-needed return from rcar_i2c_bus_phase()
   - tidyup calculation method on rcar_i2c_clock_calculate()
   - tidyup English type
   - tidyup comment to i2c device disabled
 
   drivers/i2c/busses/Kconfig|   10 +
   drivers/i2c/busses/Makefile   |1 +
   drivers/i2c/busses/i2c-rcar.c |  715 
  +
   include/linux/i2c/i2c-rcar.h  |   10 +
   4 files changed, 736 insertions(+), 0 deletions(-)
   create mode 100644 drivers/i2c/busses/i2c-rcar.c
   create mode 100644 include/linux/i2c/i2c-rcar.h
 
  diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
  index b4aaa1b..51baa08 100644
  --- a/drivers/i2c/busses/Kconfig
  +++ b/drivers/i2c/busses/Kconfig
  @@ -709,6 +709,16 @@ config I2C_XLR
This driver can also be built as a module.  If so, the module
will be called i2c-xlr.
 
  +config I2C_RCAR
  +   tristate Renesas R-Car I2C Controller
  +   depends on ARCH_SHMOBILE  I2C
  +   help
  + If you say yes to this option, support will be included for the
  + R-Car I2C controller.
  +
  + This driver can also be built as a module.  If so, the module
  + will be called i2c-rcar.
  +
   comment External I2C/SMBus adapter drivers
 
   config I2C_DIOLAN_U2C
  diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
  index ce3c2be..e98ff51 100644
  --- a/drivers/i2c/busses/Makefile
  +++ b/drivers/i2c/busses/Makefile
  @@ -70,6 +70,7 @@ obj-$(CONFIG_I2C_VERSATILE)   += i2c-versatile.o
   obj-$(CONFIG_I2C_OCTEON)   += i2c-octeon.o
   obj-$(CONFIG_I2C_XILINX)   += i2c-xiic.o
   obj-$(CONFIG_I2C_XLR)  += i2c-xlr.o
  +obj-$(CONFIG_I2C_RCAR) += i2c-rcar.o
 
   # External I2C/SMBus adapter drivers
   obj-$(CONFIG_I2C_DIOLAN_U2C)   += i2c-diolan-u2c.o
  diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
  new file mode 100644
  index 000..bd8fcf1
  --- /dev/null
  +++ b/drivers/i2c/busses/i2c-rcar.c
  @@ -0,0 +1,715 @@
  +/*
  + *  drivers/i2c/busses/i2c-rcar.c
  + *
  + * Copyright (C) 2012 Renesas Solutions Corp.
  + * Kuninori Morimoto kuninori.morimoto...@renesas.com
  + *
  + * This file is based on the drivers/i2c/busses/i2c-sh7760.c
  + * (c) 2005-2008 MSC Vertriebsges.m.b.H, Manuel Lauss m...@msc-ge.com
  + *
  + * This file used out-of-tree driver i2c-rcar.c
  + * Copyright (C) 2011-2012 Renesas Electronics Corporation
  + *
  + * This program is free software; you can redistribute it and/or modify
  + * it under the terms of the GNU General Public License as published by
  + * the Free Software Foundation; either version 2 of the License
  + *
  + * This program is distributed in the hope that it will be useful,
  + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  + * GNU General Public License for more details.
  + *
  + * You should have received a copy of the GNU General Public License
  + * along with this program; if not, write to the Free Software
  + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  
  USA
  + */
  +#include linux/clk.h
  +#include linux/delay.h
  +#include linux/err.h
  +#include linux/init.h
  +#include linux/interrupt.h
  +#include linux/io.h
  +#include linux/i2c.h
  +#include linux/i2c/i2c-rcar.h
  +#include linux/kernel.h
  +#include linux/module.h
  +#include linux/platform_device.h
  +#include linux/pm_runtime.h
  +#include linux/slab.h
  +#include linux/spinlock.h
  +
  +/* register offsets */
  +#define ICSCR  0x00/* slave ctrl */
  +#define ICMCR  0x04/* master ctrl */
  +#define ICSSR  0x08/* slave status */
  +#define ICMSR  0x0C/* master status */
  +#define ICSIER 0x10/* slave irq enable */
  +#define ICMIER 0x14/* master irq enable */
  +#define ICCCR  0x18/* clock dividers */
  +#define ICSAR  0x1C/* slave address */
  +#define ICMAR  0x20/* master address */
  +#define ICRXTX 0x24/* data port */
  +
  +/* ICMCR */
  +#define MDBS   (1  7)/* non-fifo mode switch */
  +#define FSCL   (1  6) 

[PATCH v3] i2c: add Renesas R-Car I2C driver

2012-09-28 Thread Kuninori Morimoto
R-Car I2C is similar with SH7760 I2C.
But the SH7760 I2C driver had many workaround operations, since H/W had bugs.
Thus, it was pointless to keep compatible between SH7760 and R-Car I2C drivers.
This patch creates new Renesas R-Car I2C driver.

Signed-off-by: Kuninori Morimoto kuninori.morimoto...@renesas.com
---
v2 - v3

 - used simple comment on rcar_i2c_irq_recv()
 - used LOOP_TIMEOUT
 - used pm_runtime_put()
 - used devm_request_irq()

 drivers/i2c/busses/Kconfig|   10 +
 drivers/i2c/busses/Makefile   |1 +
 drivers/i2c/busses/i2c-rcar.c |  709 +
 include/linux/i2c/i2c-rcar.h  |   10 +
 4 files changed, 730 insertions(+)
 create mode 100644 drivers/i2c/busses/i2c-rcar.c
 create mode 100644 include/linux/i2c/i2c-rcar.h

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index b4aaa1b..51baa08 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -709,6 +709,16 @@ config I2C_XLR
  This driver can also be built as a module.  If so, the module
  will be called i2c-xlr.
 
+config I2C_RCAR
+   tristate Renesas R-Car I2C Controller
+   depends on ARCH_SHMOBILE  I2C
+   help
+ If you say yes to this option, support will be included for the
+ R-Car I2C controller.
+
+ This driver can also be built as a module.  If so, the module
+ will be called i2c-rcar.
+
 comment External I2C/SMBus adapter drivers
 
 config I2C_DIOLAN_U2C
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index ce3c2be..e98ff51 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -70,6 +70,7 @@ obj-$(CONFIG_I2C_VERSATILE)   += i2c-versatile.o
 obj-$(CONFIG_I2C_OCTEON)   += i2c-octeon.o
 obj-$(CONFIG_I2C_XILINX)   += i2c-xiic.o
 obj-$(CONFIG_I2C_XLR)  += i2c-xlr.o
+obj-$(CONFIG_I2C_RCAR) += i2c-rcar.o
 
 # External I2C/SMBus adapter drivers
 obj-$(CONFIG_I2C_DIOLAN_U2C)   += i2c-diolan-u2c.o
diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
new file mode 100644
index 000..f9399d1
--- /dev/null
+++ b/drivers/i2c/busses/i2c-rcar.c
@@ -0,0 +1,709 @@
+/*
+ *  drivers/i2c/busses/i2c-rcar.c
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ * Kuninori Morimoto kuninori.morimoto...@renesas.com
+ *
+ * This file is based on the drivers/i2c/busses/i2c-sh7760.c
+ * (c) 2005-2008 MSC Vertriebsges.m.b.H, Manuel Lauss m...@msc-ge.com
+ *
+ * This file used out-of-tree driver i2c-rcar.c
+ * Copyright (C) 2011-2012 Renesas Electronics Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include linux/clk.h
+#include linux/delay.h
+#include linux/err.h
+#include linux/init.h
+#include linux/interrupt.h
+#include linux/io.h
+#include linux/i2c.h
+#include linux/i2c/i2c-rcar.h
+#include linux/kernel.h
+#include linux/module.h
+#include linux/platform_device.h
+#include linux/pm_runtime.h
+#include linux/slab.h
+#include linux/spinlock.h
+
+/* register offsets */
+#define ICSCR  0x00/* slave ctrl */
+#define ICMCR  0x04/* master ctrl */
+#define ICSSR  0x08/* slave status */
+#define ICMSR  0x0C/* master status */
+#define ICSIER 0x10/* slave irq enable */
+#define ICMIER 0x14/* master irq enable */
+#define ICCCR  0x18/* clock dividers */
+#define ICSAR  0x1C/* slave address */
+#define ICMAR  0x20/* master address */
+#define ICRXTX 0x24/* data port */
+
+/* ICMCR */
+#define MDBS   (1  7)/* non-fifo mode switch */
+#define FSCL   (1  6)/* override SCL pin */
+#define FSDA   (1  5)/* override SDA pin */
+#define OBPC   (1  4)/* override pins */
+#define MIE(1  3)/* master if enable */
+#define TSBE   (1  2)
+#define FSB(1  1)/* force stop bit */
+#define ESG(1  0)/* en startbit gen */
+
+/* ICMSR */
+#define MNR(1  6)/* nack received */
+#define MAL(1  5)/* arbitration lost */
+#define MST(1  4)/* sent a stop */
+#define MDE(1  3)
+#define MDT(1  2)
+#define MDR(1  1)
+#define MAT(1  0)/* slave addr xfer done */
+
+/* ICMIE */
+#define MNRE   (1  6)/* nack irq en */
+#define MALE   (1  5)/* arblos irq en */
+#define MSTE   (1  4)/* stop irq en */
+#define MDEE   (1  3)
+#define MDTE   (1 

Re: [PATCH V4 Resend 1/2] i2c/adapter: Add bus recovery infrastructure

2012-09-28 Thread Wolfram Sang
Hi,

 But before i send another version of this patchset, need some inputs from
 Wolfram.

I am trying to have another I2C weekend this weekend. And your patches
have been scheduled for that. The generic feeling is:

Very useful but the interface could probably be simplified. This is why
it takes me so long, working on interfaces needs more thought than the
average patch review :/

Thanks,

   Wolfram

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


signature.asc
Description: Digital signature


Re: [PATCH V4 Resend 1/2] i2c/adapter: Add bus recovery infrastructure

2012-09-28 Thread Viresh Kumar
On 28 September 2012 12:30, Wolfram Sang w.s...@pengutronix.de wrote:
 I am trying to have another I2C weekend this weekend. And your patches
 have been scheduled for that. The generic feeling is:

 Very useful but the interface could probably be simplified. This is why
 it takes me so long, working on interfaces needs more thought than the
 average patch review :/

Glad to hear that. Even i would like to make it better :)

Waiting for your comments.

--
Viresh
--
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 Resend 1/2] i2c/adapter: Add bus recovery infrastructure

2012-09-28 Thread Viresh Kumar
Hi Uwe,

On 28 September 2012 12:57, Uwe Kleine-König
u.kleine-koe...@pengutronix.de wrote:
 On Fri, Sep 28, 2012 at 09:11:34AM +0530, viresh kumar wrote:

 This was done, because few platforms may not have configuration bits to read
 status of sda line.. For them skip_sda_polling was required.

 Whereas, others would need this to see if we can return early.

 What is the upside of returning early? I'd say, just don't do it.

Save time. Why give additional clocks when you don't actually need them?
Can use likely/unlikely to make it more efficient for 9 clock pulse
scenario though.

  + * @put_gpio: called after recover_bus() to get padmux configured for 
  scl line
  + *   as scl. Only required if is_gpio_recovery == true.
  + * @scl_gpio: gpio number of the scl line. Only required if 
  is_gpio_recovery ==
  + *   true.
  + * @sda_gpio: gpio number of the sda line. Only required if 
  is_gpio_recovery ==
  + *   true and skip_sda_polling == false.
  + * @scl_gpio_flags: flag for gpio_request_one of scl_gpio. 0 implies
  + *   GPIOF_OUT_INIT_LOW.
  IMHO you should not make this configurable but use
 
  GPIOF_OUT_INIT_HIGH | GPIOF_OPEN_DRAIN

 Discussed here:
 http://www.spinics.net/lists/linux-i2c/msg07325.html

 Why do you default to GPIOF_OUT_INIT_LOW? The idle state of scl is high.
 Using low here introduces an additional clk pulse.

We aren't giving any clock pulses to scl line. Are you talking about sda?

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


[RFC PATCH 1/6] Introduce acpi_match_device_id().

2012-09-28 Thread Zhang Rui
From 72df5d1f51fb27a4ba7f70a3b07df759d32b8288 Mon Sep 17 00:00:00 2001
From: Zhang Rui rui.zh...@intel.com
Date: Thu, 27 Sep 2012 15:11:55 +0800
Subject: [RFC PATCH 1/6] Introduce acpi_match_device_id().

This API is used to check if a device id string is compatible
with an ACPI device,
either PNP id exported via _HID or compatible ids exported
via _CID control method.

Signed-off-by: Zhang Rui rui.zh...@intel.com
---
 drivers/acpi/scan.c |   22 ++
 include/acpi/acpi_bus.h |6 ++
 2 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index d1ecca2..936a7c9 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -312,6 +312,28 @@ int acpi_match_device_ids(struct acpi_device *device,
 }
 EXPORT_SYMBOL(acpi_match_device_ids);
 
+int acpi_match_device_id(const struct device *dev, const char *id)
+{
+   acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
+   struct acpi_device *device;
+   struct acpi_hardware_id *hwid;
+   acpi_status status;
+
+   if (!handle || !id)
+   return -ENODEV;
+
+   status = acpi_bus_get_device(handle, device);
+   if (ACPI_FAILURE(status))
+   return -ENODEV;
+
+   list_for_each_entry(hwid, device-pnp.ids, list)
+   if (!strcmp(id, hwid-id))
+   return 0;
+
+   return -ENODEV;
+}
+EXPORT_SYMBOL(acpi_match_device_id);
+
 static void acpi_free_ids(struct acpi_device *device)
 {
struct acpi_hardware_id *id, *tmp;
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index bde976e..8b5b124 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -378,6 +378,7 @@ int acpi_bus_start(struct acpi_device *device);
 acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd);
 int acpi_match_device_ids(struct acpi_device *device,
  const struct acpi_device_id *ids);
+int acpi_match_device_id(const struct device *, const char *);
 int acpi_create_dir(struct acpi_device *);
 void acpi_remove_dir(struct acpi_device *);
 
@@ -448,6 +449,11 @@ static inline int acpi_pm_device_sleep_wake(struct device 
*dev, bool enable)
 
 static inline int register_acpi_bus_type(void *bus) { return 0; }
 static inline int unregister_acpi_bus_type(void *bus) { return 0; }
+static inline int acpi_match_device_id(const struct device *device,
+   const char *name)
+{
+   return -ENODEV;
+}
 
 #endif /* CONFIG_ACPI */
 
-- 
1.7.7.6



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


[RFC PATCH 3/6] ACPI: introduce acpi_get_generic_resources

2012-09-28 Thread Zhang Rui
From 9a851d177794129a89f720c7122cb39fd163126b Mon Sep 17 00:00:00 2001
From: Zhang Rui rui.zh...@intel.com
Date: Fri, 28 Sep 2012 08:34:05 +0800
Subject: [RFC PATCH 3/6] ACPI: introduce acpi_get_generic_resources

Introduce acpi_get_generic_resources() to convert
ACPI style resources to struct resource.

Signed-off-by: Zhang Rui rui.zh...@intel.com
---
 drivers/acpi/Makefile   |1 +
 drivers/acpi/resource.c |  165 +++
 include/acpi/acpi_bus.h |1 +
 3 files changed, 167 insertions(+), 0 deletions(-)
 create mode 100644 drivers/acpi/resource.c

diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 6b1d535..4b65608 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -46,6 +46,7 @@ acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
 ifdef CONFIG_ACPI_VIDEO
 acpi-y += video_detect.o
 endif
+acpi-y += resource.o
 
 # These are (potentially) separate modules
 obj-$(CONFIG_ACPI_AC)  += ac.o
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
new file mode 100644
index 000..30a5204
--- /dev/null
+++ b/drivers/acpi/resource.c
@@ -0,0 +1,165 @@
+/*
+ * resource.c -- convert ACPI resource to generic resource
+ *
+ * Copyright (c) 2012 Zhang Rui rui.zh...@intel.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ */
+#include linux/kernel.h
+#include linux/export.h
+#include linux/acpi.h
+
+static int irq_flags(int triggering, int polarity, int sharable)
+{
+   int flags;
+
+   if (triggering == ACPI_LEVEL_SENSITIVE) {
+   if (polarity == ACPI_ACTIVE_LOW)
+   flags = IORESOURCE_IRQ_LOWLEVEL;
+   else
+   flags = IORESOURCE_IRQ_HIGHLEVEL;
+   } else {
+   if (polarity == ACPI_ACTIVE_LOW)
+   flags = IORESOURCE_IRQ_LOWEDGE;
+   else
+   flags = IORESOURCE_IRQ_HIGHEDGE;
+   }
+
+   if (sharable == ACPI_SHARED)
+   flags |= IORESOURCE_IRQ_SHAREABLE;
+
+   return flags;
+}
+
+static void acpi_get_irq_resource(struct acpi_resource *res,
+ struct resource *resource)
+{
+   struct acpi_resource_irq *irq = res-data.irq;
+   int t, p;
+
+   if (irq-interrupt_count == 0)
+   resource-flags = IORESOURCE_DISABLED;
+
+   if (!acpi_get_override_irq(irq-interrupts[0], t, p)) {
+   t = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
+   p = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
+
+   if (irq-triggering != t || irq-polarity != p) {
+   irq-triggering = t;
+   irq-polarity = p;
+   }
+   }
+
+   resource-flags =
+   irq_flags(irq-triggering, irq-polarity, irq-sharable);
+   resource-flags |= IORESOURCE_IRQ;
+   resource-start = irq-interrupts[0];
+   resource-end = irq-interrupts[0];
+}
+
+static void acpi_get_extended_irq_resource(struct acpi_resource *res,
+  struct resource *resource)
+{
+   struct acpi_resource_extended_irq *irq = res-data.extended_irq;
+   int t, p;
+
+   if (irq-interrupt_count == 0)
+   resource-flags = IORESOURCE_DISABLED;
+
+   if (!acpi_get_override_irq(irq-interrupts[0], t, p)) {
+   t = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
+   p = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
+
+   if (irq-triggering != t || irq-polarity != p) {
+   irq-triggering = t;
+   irq-polarity = p;
+   }
+   }
+
+   resource-flags =
+   irq_flags(irq-triggering, irq-polarity, irq-sharable);
+   resource-flags |= IORESOURCE_IRQ;
+   resource-start = irq-interrupts[0];
+   resource-end = irq-interrupts[0];
+}
+
+static void acpi_get_mem_resource(struct acpi_resource *res,
+ struct resource *resource)
+{
+   struct acpi_resource_fixed_memory32 *mem = res-data.fixed_memory32;
+
+   if (mem-address_length == 0)
+   resource-flags |= IORESOURCE_DISABLED;
+   if (mem-write_protect == ACPI_READ_WRITE_MEMORY)
+   resource-flags |= IORESOURCE_MEM_WRITEABLE;
+
+   resource-flags |= IORESOURCE_MEM;
+   resource-start = mem-address;
+   resource-end = mem-address + mem-address_length - 1;
+}
+
+int acpi_get_generic_resources(struct acpi_device *device,
+  struct resource 

[RFC PATCH 4/6] Change i2c_register_board_info from __init to __devinit

2012-09-28 Thread Zhang Rui
From 34aa38e12c04544d89af2eae46de284dc8a03b8d Mon Sep 17 00:00:00 2001
From: Zhang Rui rui.zh...@intel.com
Date: Thu, 27 Sep 2012 15:42:23 +0800
Subject: [RFC PATCH 4/6] Change i2c_register_board_info from __init to
 __devinit.

ACPI 5 supports enumerating I2C adapter and its slaves
via ACPI namespace, and this needs to be done at runtime,
after the ACPI I2C controller driver being loaded.

detailed usage of this API can be found in next patch.

Signed-off-by: Zhang Rui rui.zh...@intel.com
---
 drivers/i2c/i2c-boardinfo.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/i2c/i2c-boardinfo.c b/drivers/i2c/i2c-boardinfo.c
index f24cc64..1ecbbdc 100644
--- a/drivers/i2c/i2c-boardinfo.c
+++ b/drivers/i2c/i2c-boardinfo.c
@@ -61,7 +61,7 @@ EXPORT_SYMBOL_GPL(__i2c_first_dynamic_bus_num);
  * The board info passed can safely be __initdata, but be careful of embedded
  * pointers (for platform_data, functions, etc) since that won't be copied.
  */
-int __init
+int __devinit
 i2c_register_board_info(int busnum,
struct i2c_board_info const *info, unsigned len)
 {
-- 
1.7.7.6



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


[RFC PATCH 5/6] ACPI: Introduce ACPI I2C controller enumeration driver

2012-09-28 Thread Zhang Rui
From 6077a62f2865201ab6727ca7d628ee5e43aa57e1 Mon Sep 17 00:00:00 2001
From: Zhang Rui rui.zh...@intel.com
Date: Fri, 24 Aug 2012 15:18:25 +0800
Subject: [RFC PATCH 5/6] ACPI: Introduce ACPI I2C controller enumeration
 driver

This driver is able to
1) enumerate I2C controller via ACPI namespace
   and register it as a platform device.
2) enumerate I2C slave devices via ACPI namespace.

Signed-off-by: Zhang Rui rui.zh...@intel.com
---
 drivers/acpi/Makefile   |1 +
 drivers/acpi/i2c_root.c |  229 +++
 drivers/acpi/sysfs.c|1 +
 include/acpi/acpi_drivers.h |1 +
 4 files changed, 232 insertions(+), 0 deletions(-)
 create mode 100644 drivers/acpi/i2c_root.c

diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 4b65608..5b14f05 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -35,6 +35,7 @@ acpi-y+= scan.o
 acpi-y += processor_core.o
 acpi-y += ec.o
 acpi-y += gpio.o
+acpi-y += i2c_root.o
 acpi-$(CONFIG_ACPI_DOCK)   += dock.o
 acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
 acpi-y += power.o
diff --git a/drivers/acpi/i2c_root.c b/drivers/acpi/i2c_root.c
new file mode 100644
index 000..b9a042b
--- /dev/null
+++ b/drivers/acpi/i2c_root.c
@@ -0,0 +1,229 @@
+/*
+ *  i2c_root.c - ACPI I2C controller Driver ($Revision: 40 $)
+ *
+ *  Copyright (C) 2012 Intel Corp
+ *  Copyright (C) 2012 Zhang Rui rui.zh...@intel.com
+ *
+ * ~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~
+ */
+
+#include linux/kernel.h
+#include linux/module.h
+#include linux/init.h
+#include linux/types.h
+#include linux/spinlock.h
+#include linux/pm.h
+#include linux/pm_runtime.h
+#include linux/platform_device.h
+#include linux/i2c.h
+#include linux/acpi.h
+#include linux/slab.h
+#include acpi/acpi_bus.h
+#include acpi/acpi_drivers.h
+#include acpi/apei.h
+
+#define PREFIX ACPI: 
+
+#define _COMPONENT ACPI_SPB_COMPONENT
+ACPI_MODULE_NAME(i2c_root);
+#define ACPI_I2C_ROOT_CLASSi2c_root
+#define ACPI_I2C_ROOT_DEVICE_NAME  I2C Controller
+
+static int acpi_i2c_root_add(struct acpi_device *device);
+static int acpi_i2c_root_remove(struct acpi_device *device, int type);
+
+static const struct acpi_device_id root_device_ids[] = {
+   {INT33B1, 0},
+   {, 0},
+};
+
+MODULE_DEVICE_TABLE(acpi, root_device_ids);
+
+static struct acpi_driver acpi_i2c_root_driver = {
+   .name = i2c_root,
+   .class = ACPI_I2C_ROOT_CLASS,
+   .ids = root_device_ids,
+   .ops = {
+   .add = acpi_i2c_root_add,
+   .remove = acpi_i2c_root_remove,
+   },
+};
+
+struct acpi_i2c_root {
+   struct acpi_device *device;
+   struct platform_device *pdev;
+   int busnum;
+   int slaves;
+   struct i2c_board_info *info;
+};
+
+static int add_slave(struct acpi_i2c_root *root, struct i2c_board_info *info)
+{
+   struct i2c_board_info *p;
+
+   if (!info)
+   return 0;
+
+   p = kzalloc(sizeof(*p) * (root-slaves + 1), GFP_KERNEL);
+   if (!p)
+   return -ENOMEM;
+
+   memcpy(p, info, sizeof(*p));
+   if (root-info)
+   memcpy(p + 1, root-info, sizeof(*p) * root-slaves);
+
+   kfree(root-info);
+   root-info = p;
+   root-slaves++;
+   return 0;
+}
+
+static int register_slaves(struct acpi_i2c_root *root)
+{
+   return i2c_register_board_info(root-busnum, root-info, root-slaves);
+}
+
+/*
+ * The i2c info registering call back for each i2c slave device
+ */
+acpi_status __init i2c_enumerate_slave(acpi_handle handle, u32 level,
+  void *data, void **return_value)
+{
+   int result;
+   acpi_status status;
+   struct acpi_buffer buffer;
+   struct acpi_resource *resource;
+   struct acpi_resource_gpio *gpio;
+   struct acpi_resource_i2c_serialbus *i2c;
+   int i;
+   struct acpi_i2c_root *root = data;
+   struct i2c_board_info info;
+   struct acpi_device *device;
+
+   

[RFC PATCH 6/6] Introduce INT33B1 I2C controller driver

2012-09-28 Thread Zhang Rui
From 817d814ecae91862f42a0447f455dae7f74cba27 Mon Sep 17 00:00:00 2001
From: Zhang Rui rui.zh...@intel.com
Date: Fri, 24 Aug 2012 15:20:38 +0800
Subject: [RFC PATCH 6/6] Introduce INT33B1 I2C controller driver

This is a dummy platform device driver to illustrate my idea about
how a really I2C controller should work on ACPI 5 platforms. 
It just probes the INT33B1 I2C controller which is enumerated by ACPI.

Signed-off-by: Zhang Rui rui.zh...@intel.com
---
 drivers/i2c/busses/Kconfig|8 +++
 drivers/i2c/busses/Makefile   |1 +
 drivers/i2c/busses/i2c-33b1.c |  117 +
 3 files changed, 126 insertions(+), 0 deletions(-)
 create mode 100644 drivers/i2c/busses/i2c-33b1.c

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index b4aaa1b..536a19c 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -257,6 +257,14 @@ config I2C_SCMI
  To compile this driver as a module, choose M here:
  the module will be called i2c-scmi.
 
+config I2C_33B1
+   tristate INT33B1 I2C controller
+   help
+ This driver supports the ACPI enumerated INT33B1 I2C controller.
+
+ To compile this driver as a module, choose M here:
+ the module will be called i2c-scmi.
+
 endif # ACPI
 
 comment Mac SMBus host controller drivers
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index ce3c2be..8e478bd 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -4,6 +4,7 @@
 
 # ACPI drivers
 obj-$(CONFIG_I2C_SCMI) += i2c-scmi.o
+obj-$(CONFIG_I2C_33B1) += i2c-33b1.o
 
 # PC SMBus host controller drivers
 obj-$(CONFIG_I2C_ALI1535)  += i2c-ali1535.o
diff --git a/drivers/i2c/busses/i2c-33b1.c b/drivers/i2c/busses/i2c-33b1.c
new file mode 100644
index 000..152c3e4
--- /dev/null
+++ b/drivers/i2c/busses/i2c-33b1.c
@@ -0,0 +1,117 @@
+/*
+ *  i2c_33b1.c -INT33B1 i2c Controller Driver
+ *
+ *  Copyright (c) 2012 Intel Corp
+ *  Copyright (c) 2012 Zhang Rui rui.zh...@intel.com
+ *
+ * ~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ * ~~
+ */
+
+#include linux/kernel.h
+#include linux/module.h
+#include linux/slab.h
+#include linux/init.h
+#include linux/ioport.h
+#include linux/delay.h
+#include linux/errno.h
+#include linux/i2c.h
+#include linux/io.h
+#include linux/platform_device.h
+
+
+struct int33b1_i2c_private {
+struct i2c_adapter adap;
+void __iomem *iobase;
+};
+
+
+static int int33b1_i2c_xfer(struct i2c_adapter *adap,
+   struct i2c_msg *msgs, int num)
+{
+   return 0;
+}
+
+static u32 int33b1_func(struct i2c_adapter *adap)
+{
+   /* Emulate SMBUS over I2C */
+   return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm int33b1_i2c_algo = {
+   .master_xfer= int33b1_i2c_xfer,
+   .functionality  = int33b1_func,
+};
+
+static int __devinit int33b1_i2c_probe(struct platform_device *pdev)
+{
+   struct int33b1_i2c_private  *priv;
+   struct resource *res;
+   int ret;
+
+   priv = devm_kzalloc(pdev-dev, sizeof(*priv), GFP_KERNEL);
+   if (!priv)
+   return -ENOMEM;
+
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   priv-iobase = devm_request_and_ioremap(pdev-dev, res);
+   if (!priv-iobase) {
+   dev_err(pdev-dev, devm_request_and_ioremap failed\n);
+   return -EBUSY;
+   }
+
+   priv-adap.dev.parent = pdev-dev;
+   priv-adap.owner= THIS_MODULE;
+   priv-adap.algo_data= priv;
+   priv-adap.algo = int33b1_i2c_algo;
+   priv-adap.nr   = pdev-id;
+   priv-adap.class= I2C_CLASS_HWMON;
+   snprintf(priv-adap.name, sizeof(priv-adap.name), int33b1-i2c);
+
+   i2c_set_adapdata(priv-adap, priv);
+   ret = i2c_add_numbered_adapter(priv-adap);
+   if (ret  0) {
+   dev_err(priv-adap.dev, Failed to add i2c bus.\n);
+   return ret;
+   }
+
+   platform_set_drvdata(pdev, priv);
+   dev_info(priv-adap.dev, Added I2C Bus.\n);
+   return 0;
+}
+
+static int __devexit int33b1_i2c_remove(struct platform_device *pdev)
+{
+   struct int33b1_i2c_private *priv;
+
+   priv = platform_get_drvdata(pdev);
+   i2c_del_adapter(priv-adap);
+   platform_set_drvdata(pdev, NULL);
+   return 0;
+}
+
+static struct platform_driver 

Re: [PATCH V4 Resend 1/2] i2c/adapter: Add bus recovery infrastructure

2012-09-28 Thread Viresh Kumar
On 28 September 2012 12:57, Uwe Kleine-König
u.kleine-koe...@pengutronix.de wrote:
 Why do you default to GPIOF_OUT_INIT_LOW? The idle state of scl is high.
 Using low here introduces an additional clk pulse.

Went deep into the code i wrote ages ago to check why i did so :)

My initial idea was, because the idle state of scl is high, giving another high
initially  with gpio would be a waste. As the slave will not notice a change.

So, i will do it low and then following code will run with delay before setting
gpio again. This will ensure, the initial gpio-set is used as clock.

for (i = 0; i  bri-clock_cnt * 2; i++, val = !val) {
ndelay(delay);
gpio_set_value(bri-scl_gpio, val);

...
}

Yes, you are correct in saying that i have generated 9 *2 + 1 = 19
half-clocks...
or 9.5 clocks. Will fix it by making initial value of i as 1.

Also, will take care of this when user sends his own flags :)

--
viresh
--
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/adapter: Add bus recovery infrastructure

2012-09-28 Thread Viresh Kumar
From: Viresh Kumar viresh.ku...@st.com

Add i2c bus recovery infrastructure to i2c adapters as specified in the i2c
protocol Rev. 03 section 3.1.16 titled Bus clear.

http://www.nxp.com/documents/user_manual/UM10204.pdf

Sometimes during operation i2c bus hangs and we need to give dummy clocks to
slave device to start the transfer again. Now we may have capability in the bus
controller to generate these clocks or platform may have gpio pins which can be
toggled to generate dummy clocks. This patch supports both.

This patch also adds in generic bus recovery routines gpio or scl line based
which can be used by bus controller. In addition controller driver may provide
its own version of the bus recovery routine.

This doesn't support multi-master recovery for now.

Signed-off-by: Viresh Kumar viresh.ku...@st.com
---
V4-V5:
- section name corrected to 3.1.16
- merged gpio and non-gpio recovery routines to remove code redundancy
- Changed types of gpio and gpio-flags to unsigned and unsigned long
- Checking return value of get_gpio() now
- using DIV_ROUND_UP for calculating delay, to get more correct value

 drivers/i2c/i2c-core.c | 153 +
 include/linux/i2c.h|  52 +
 2 files changed, 205 insertions(+)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index a7edf98..bdc249a 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -27,7 +27,9 @@
 
 #include linux/module.h
 #include linux/kernel.h
+#include linux/delay.h
 #include linux/errno.h
+#include linux/gpio.h
 #include linux/slab.h
 #include linux/i2c.h
 #include linux/init.h
@@ -104,6 +106,116 @@ static int i2c_device_uevent(struct device *dev, struct 
kobj_uevent_env *env)
 #define i2c_device_uevent  NULL
 #endif /* CONFIG_HOTPLUG */
 
+/* i2c bus recovery routines */
+static inline void set_scl_value(struct i2c_adapter *adap, int val)
+{
+   struct i2c_bus_recovery_info *bri = adap-bus_recovery_info;
+
+   if (bri-is_gpio_recovery)
+   gpio_set_value(bri-scl_gpio, val);
+   else
+   bri-set_scl(adap, val);
+}
+
+static inline int get_sda_value(struct i2c_adapter *adap)
+{
+   struct i2c_bus_recovery_info *bri = adap-bus_recovery_info;
+
+   if (bri-is_gpio_recovery)
+   return gpio_get_value(bri-sda_gpio);
+   else
+   return bri-get_sda(adap);
+}
+
+static int i2c_get_gpios_for_recovery(struct i2c_adapter *adap)
+{
+   struct i2c_bus_recovery_info *bri = adap-bus_recovery_info;
+   struct device *dev = adap-dev;
+   int ret = 0;
+
+   if (bri-get_gpio) {
+   ret = bri-get_gpio(bri-scl_gpio);
+   if (ret) {
+   dev_warn(dev, scl get_gpio: %d\n, bri-scl_gpio);
+   return ret;
+   }
+   }
+
+   ret = gpio_request_one(bri-scl_gpio, bri-scl_gpio_flags, i2c-scl);
+   if (ret) {
+   dev_warn(dev, gpio request fail: %d\n, bri-scl_gpio);
+   goto scl_put_gpio;
+   }
+
+   if (!bri-skip_sda_polling) {
+   if (bri-get_gpio)
+   ret = bri-get_gpio(bri-sda_gpio);
+
+   if (unlikely(ret ||
+   gpio_request_one(bri-sda_gpio, bri-sda_gpio_flags,
+   i2c-sda))) {
+   /* work without sda polling */
+   dev_warn(dev, can't get sda: %d. Skip sda polling\n,
+   bri-sda_gpio);
+   bri-skip_sda_polling = true;
+   if (!ret  bri-put_gpio)
+   bri-put_gpio(bri-sda_gpio);
+
+   ret = 0;
+   }
+   }
+
+scl_put_gpio:
+   if (bri-put_gpio)
+   bri-put_gpio(bri-scl_gpio);
+
+   return ret;
+}
+
+static void i2c_put_gpios_for_recovery(struct i2c_adapter *adap)
+{
+   struct i2c_bus_recovery_info *bri = adap-bus_recovery_info;
+
+   gpio_free(bri-scl_gpio);
+
+   if (!bri-skip_sda_polling) {
+   gpio_free(bri-sda_gpio);
+
+   if (bri-put_gpio)
+   bri-put_gpio(bri-sda_gpio);
+   }
+}
+
+static int i2c_recover_bus(struct i2c_adapter *adap)
+{
+   struct i2c_bus_recovery_info *bri = adap-bus_recovery_info;
+   unsigned long delay = 100;
+   int i, ret, val = 1;
+
+   if (bri-is_gpio_recovery) {
+   ret = i2c_get_gpios_for_recovery(adap);
+   if (ret)
+   return ret;
+   }
+
+   delay = DIV_ROUND_UP(delay, bri-clock_rate_khz * 2);
+
+   for (i = 0; i  bri-clock_cnt * 2; i++, val = !val) {
+   set_scl_value(adap, val);
+   ndelay(delay);
+
+   /* break if sda got high, check only when scl line is high */
+   if (!bri-skip_sda_polling  val)
+   if (unlikely(get_sda_value(adap)))
+

[PATCH V5 2/2] i2c/designware: Provide i2c bus recovery support

2012-09-28 Thread Viresh Kumar
From: Viresh Kumar viresh.ku...@st.com

Add bus recovery support for designware_i2c controller. It uses generic gpio
based i2c_gpio_recover_bus() routine.

Signed-off-by: Vincenzo Frascino vincenzo.frasc...@st.com
Signed-off-by: Shiraz Hashim shiraz.has...@st.com
Signed-off-by: Viresh Kumar viresh.ku...@st.com
---
 drivers/i2c/busses/i2c-designware-core.c|  7 -
 drivers/i2c/busses/i2c-designware-platdrv.c | 40 +--
 include/linux/i2c/i2c-designware.h  | 49 +
 3 files changed, 93 insertions(+), 3 deletions(-)
 create mode 100644 include/linux/i2c/i2c-designware.h

diff --git a/drivers/i2c/busses/i2c-designware-core.c 
b/drivers/i2c/busses/i2c-designware-core.c
index 7b8ebbe..3073178 100644
--- a/drivers/i2c/busses/i2c-designware-core.c
+++ b/drivers/i2c/busses/i2c-designware-core.c
@@ -538,7 +538,12 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg 
msgs[], int num)
ret = wait_for_completion_interruptible_timeout(dev-cmd_complete, HZ);
if (ret == 0) {
dev_err(dev-dev, controller timed out\n);
-   i2c_dw_init(dev);
+   if (adap-bus_recovery_info 
+   adap-bus_recovery_info-recover_bus) {
+   dev_dbg(dev-dev, try i2c bus recovery\n);
+   adap-bus_recovery_info-recover_bus(adap);
+   }
+
ret = -ETIMEDOUT;
goto done;
} else if (ret  0)
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c 
b/drivers/i2c/busses/i2c-designware-platdrv.c
index 0506fef..9e8b7e3 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -29,6 +29,7 @@
 #include linux/module.h
 #include linux/delay.h
 #include linux/i2c.h
+#include linux/i2c/i2c-designware.h
 #include linux/clk.h
 #include linux/errno.h
 #include linux/sched.h
@@ -45,6 +46,7 @@ static struct i2c_algorithm i2c_dw_algo = {
.master_xfer= i2c_dw_xfer,
.functionality  = i2c_dw_func,
 };
+
 static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev)
 {
return clk_get_rate(dev-clk)/1000;
@@ -55,6 +57,8 @@ static int __devinit dw_i2c_probe(struct platform_device 
*pdev)
struct dw_i2c_dev *dev;
struct i2c_adapter *adap;
struct resource *mem, *ioarea;
+   struct i2c_dw_pdata *pdata;
+   struct i2c_bus_recovery_info *recovery_info = NULL;
int irq, r;
 
/* NOTE: driver uses the static register mapping */
@@ -141,17 +145,47 @@ static int __devinit dw_i2c_probe(struct platform_device 
*pdev)
adap-dev.parent = pdev-dev;
adap-dev.of_node = pdev-dev.of_node;
 
+   /* Bus recovery support */
+   pdata = dev_get_platdata(pdev-dev);
+   if (pdata) {
+   recovery_info = kzalloc(sizeof(*recovery_info), GFP_KERNEL);
+   if (!recovery_info) {
+   adap-bus_recovery_info = NULL;
+   dev_err(pdev-dev,
+   failure to allocate memory for bus 
recovery\n);
+   goto skip_recovery;
+   }
+
+   recovery_info-is_gpio_recovery = true;
+   recovery_info-get_gpio = pdata-get_gpio;
+   recovery_info-put_gpio = pdata-put_gpio;
+   recovery_info-scl_gpio = pdata-scl_gpio;
+   recovery_info-scl_gpio_flags = pdata-scl_gpio_flags;
+   recovery_info-clock_rate_khz = clk_get_rate(dev-clk) / 1000;
+
+   if (!pdata-skip_sda_polling) {
+   recovery_info-sda_gpio = pdata-sda_gpio;
+   recovery_info-sda_gpio_flags = pdata-sda_gpio_flags;
+   }
+
+   adap-bus_recovery_info = recovery_info;
+   } else {
+   adap-bus_recovery_info = NULL;
+   }
+
+skip_recovery:
adap-nr = pdev-id;
r = i2c_add_numbered_adapter(adap);
if (r) {
dev_err(pdev-dev, failure adding adapter\n);
-   goto err_free_irq;
+   goto err_free_recovery_info;
}
of_i2c_register_devices(adap);
 
return 0;
 
-err_free_irq:
+err_free_recovery_info:
+   kfree(recovery_info);
free_irq(dev-irq, dev);
 err_iounmap:
iounmap(dev-base);
@@ -174,6 +208,8 @@ static int __devexit dw_i2c_remove(struct platform_device 
*pdev)
struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
struct resource *mem;
 
+   kfree(dev-adapter.bus_recovery_info);
+
platform_set_drvdata(pdev, NULL);
i2c_del_adapter(dev-adapter);
put_device(pdev-dev);
diff --git a/include/linux/i2c/i2c-designware.h 
b/include/linux/i2c/i2c-designware.h
new file mode 100644
index 000..d60cb61c
--- /dev/null
+++ b/include/linux/i2c/i2c-designware.h
@@ -0,0 +1,49 @@
+/*
+ * Synopsys DesignWare I2C adapter driver's platform data
+ *
+ * Copyright (C) 2012 ST Microelectronics.
+ 

Re: [RFC PATCH 5/6] ACPI: Introduce ACPI I2C controller enumeration driver

2012-09-28 Thread Alan Cox
On Fri, 28 Sep 2012 15:40:32 +0800
Zhang Rui rui.zh...@intel.com wrote:

 From 6077a62f2865201ab6727ca7d628ee5e43aa57e1 Mon Sep 17 00:00:00 2001
 From: Zhang Rui rui.zh...@intel.com
 Date: Fri, 24 Aug 2012 15:18:25 +0800
 Subject: [RFC PATCH 5/6] ACPI: Introduce ACPI I2C controller enumeration
  driver
 
 This driver is able to
 1) enumerate I2C controller via ACPI namespace
and register it as a platform device.
 2) enumerate I2C slave devices via ACPI namespace.

Will this also trigger and work with the ACPI4 based devices that seem to
have I²C tables that Linux currently doesn't understand (eq some
GMA600/Oaktrail platforms) ?

--
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 v2] i2c: nomadik: adopt pinctrl support

2012-09-28 Thread Linus Walleij
From: Patrice Chotard patrice.chot...@stericsson.com

Amend the I2C nomadik pin controller to optionally take a pin control
handle and set the state of the pins to:

- default on boot, resume and before performing an i2c transfer
- idle after initial default, after resume default, and after each
   i2c xfer
- sleep on suspend()

This should make it possible to optimize energy usage for the pins
both for the suspend/resume cycle, and for runtime cases inbetween
I2C transfers.

Signed-off-by: Patrice Chotard patrice.chot...@stericsson.com
Signed-off-by: Linus Walleij linus.wall...@linaro.org
---
ChangeLog v1-v2:
- We used only two states initially: default and sleep. It turns
  out you can save some energy when idling (between transfers)
  and even more when suspending on our platform, so grab all
  three states and use them as applicable.
---
 drivers/i2c/busses/i2c-nomadik.c | 102 +++
 1 file changed, 102 insertions(+)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index 1b898b6..bd3da46 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -24,6 +24,7 @@
 #include linux/io.h
 #include linux/pm_runtime.h
 #include linux/platform_data/i2c-nomadik.h
+#include linux/pinctrl/consumer.h
 
 #define DRIVER_NAME nmk-i2c
 
@@ -145,6 +146,10 @@ struct i2c_nmk_client {
  * @stop: stop condition.
  * @xfer_complete: acknowledge completion for a I2C message.
  * @result: controller propogated result.
+ * @pinctrl: pinctrl handle.
+ * @pins_default: default state for the pins.
+ * @pins_idle: idle state for the pins.
+ * @pins_sleep: sleep state for the pins.
  * @busy: Busy doing transfer.
  */
 struct nmk_i2c_dev {
@@ -158,6 +163,11 @@ struct nmk_i2c_dev {
int stop;
struct completion   xfer_complete;
int result;
+   /* Three pin states - default, idle  sleep */
+   struct pinctrl  *pinctrl;
+   struct pinctrl_state*pins_default;
+   struct pinctrl_state*pins_idle;
+   struct pinctrl_state*pins_sleep;
boolbusy;
 };
 
@@ -642,6 +652,15 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
 
pm_runtime_get_sync(dev-adev-dev);
 
+   /* Optionaly enable pins to be muxed in and configured */
+   if (!IS_ERR(dev-pins_default)) {
+   status = pinctrl_select_state(dev-pinctrl,
+   dev-pins_default);
+   if (status)
+   dev_err(dev-adev-dev,
+   could not set default pins\n);
+   }
+
clk_enable(dev-clk);
 
status = init_hw(dev);
@@ -670,6 +689,16 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
 
 out:
clk_disable(dev-clk);
+
+   /* Optionally let pins go into idle state */
+   if (!IS_ERR(dev-pins_idle)) {
+   status = pinctrl_select_state(dev-pinctrl,
+   dev-pins_idle);
+   if (status)
+   dev_err(dev-adev-dev,
+   could not set pins to idle state\n);
+   }
+
pm_runtime_put_sync(dev-adev-dev);
 
dev-busy = false;
@@ -864,15 +893,44 @@ static int nmk_i2c_suspend(struct device *dev)
 {
struct amba_device *adev = to_amba_device(dev);
struct nmk_i2c_dev *nmk_i2c = amba_get_drvdata(adev);
+   int ret;
 
if (nmk_i2c-busy)
return -EBUSY;
 
+   if (!IS_ERR(nmk_i2c-pins_sleep)) {
+   ret = pinctrl_select_state(nmk_i2c-pinctrl,
+   nmk_i2c-pins_sleep);
+   if (ret)
+   dev_err(dev,
+   could not set pins to sleep state\n);
+   }
+
return 0;
 }
 
 static int nmk_i2c_resume(struct device *dev)
 {
+   struct amba_device *adev = to_amba_device(dev);
+   struct nmk_i2c_dev *nmk_i2c = amba_get_drvdata(adev);
+   int ret;
+
+   /* First go to the default state */
+   if (!IS_ERR(nmk_i2c-pins_default)) {
+   ret = pinctrl_select_state(nmk_i2c-pinctrl,
+   nmk_i2c-pins_default);
+   if (ret)
+   dev_err(dev,
+   could not set pins to default state\n);
+   }
+   /* Then let's idle the pins until the next transfer happens */
+   if (!IS_ERR(nmk_i2c-pins_idle)) {
+   ret = pinctrl_select_state(nmk_i2c-pinctrl,
+   nmk_i2c-pins_idle);
+   if (ret)
+   dev_err(dev,
+   could not set pins to idle state\n);
+   }
return 0;
 }
 #else
@@ -936,6 +994,40 @@ static int nmk_i2c_probe(struct amba_device *adev, const 
struct amba_id *id)
dev-adev = adev;

Re: [RFC PATCH 1/6] Introduce acpi_match_device_id().

2012-09-28 Thread Mika Westerberg
On Fri, Sep 28, 2012 at 03:38:30PM +0800, Zhang Rui wrote:
 From 72df5d1f51fb27a4ba7f70a3b07df759d32b8288 Mon Sep 17 00:00:00 2001
 From: Zhang Rui rui.zh...@intel.com
 Date: Thu, 27 Sep 2012 15:11:55 +0800
 Subject: [RFC PATCH 1/6] Introduce acpi_match_device_id().
 
 This API is used to check if a device id string is compatible
 with an ACPI device,
 either PNP id exported via _HID or compatible ids exported
 via _CID control method.
 
 Signed-off-by: Zhang Rui rui.zh...@intel.com
 ---
  drivers/acpi/scan.c |   22 ++
  include/acpi/acpi_bus.h |6 ++
  2 files changed, 28 insertions(+), 0 deletions(-)
 
 diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
 index d1ecca2..936a7c9 100644
 --- a/drivers/acpi/scan.c
 +++ b/drivers/acpi/scan.c
 @@ -312,6 +312,28 @@ int acpi_match_device_ids(struct acpi_device *device,
  }
  EXPORT_SYMBOL(acpi_match_device_ids);
  
 +int acpi_match_device_id(const struct device *dev, const char *id)

Would be good idea to implement this in terms of of_match_device() so that
it returns pointer to the matched id. This way drivers can get the
-driver_data pretty easily if needed.

 +{
 + acpi_handle handle = DEVICE_ACPI_HANDLE(dev);

If the device is not bound to an ACPI handle this will return NULL. And I
don't see you doing that in this series meaning that..

 + struct acpi_device *device;
 + struct acpi_hardware_id *hwid;
 + acpi_status status;
 +
 + if (!handle || !id)
 + return -ENODEV;

..you always return -ENODEV here, right?

 +
 + status = acpi_bus_get_device(handle, device);
 + if (ACPI_FAILURE(status))
 + return -ENODEV;
 +
 + list_for_each_entry(hwid, device-pnp.ids, list)
 + if (!strcmp(id, hwid-id))
 + return 0;
 +
 + return -ENODEV;
 +}
 +EXPORT_SYMBOL(acpi_match_device_id);
--
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