All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3] i2c-eg20t: support new device OKI SEMICONDUCTOR ML7213 IOH
@ 2011-03-01  5:16 Tomoya MORINAGA
  2011-03-02  0:39   ` Ben Dooks
  0 siblings, 1 reply; 6+ messages in thread
From: Tomoya MORINAGA @ 2011-03-01  5:16 UTC (permalink / raw)
  To: Jean Delvare, Ben Dooks, Seth Heasley, Linus Walleij,
	Samuel Ortiz, linux-i2c, linux-kernel
  Cc: qi.wang, yong.y.wang, joel.clark, kok.howg.ewe, toshiharu-linux,
	Tomoya MORINAGA

Support new device OKI SEMICONDUCTOR ML7213 IOH.
The ML7213 which is for IVI(In-Vehicle Infotainment) is a companion
chip for the Atom E6xx series and compatible with the Intel EG20T
PCH.

Signed-off-by: Tomoya MORINAGA <tomoya-linux@dsn.okisemi.com>
---

v3 changes
Update Ben's comments.
  - Modify goto processing in probe.

 drivers/i2c/busses/Kconfig     |   15 ++--
 drivers/i2c/busses/i2c-eg20t.c |  161 ++++++++++++++++++++++++---------------
 2 files changed, 108 insertions(+), 68 deletions(-)

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 30f8dbd..61e3875 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -639,12 +639,15 @@ config I2C_XILINX
 	  will be called xilinx_i2c.
 
 config I2C_EG20T
-        tristate "PCH I2C of Intel EG20T"
-        depends on PCI
-        help
-          This driver is for PCH(Platform controller Hub) I2C of EG20T which
-          is an IOH(Input/Output Hub) for x86 embedded processor.
-          This driver can access PCH I2C bus device.
+	tristate "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH"
+	depends on PCI
+	help
+	  This driver is for PCH(Platform controller Hub) I2C of EG20T which
+	  is an IOH(Input/Output Hub) for x86 embedded processor.
+	  This driver can access PCH I2C bus device.
+
+	  This driver also supports the ML7213, a companion chip for the
+	  Atom E6xx series and compatible with the Intel EG20T PCH.
 
 comment "External I2C/SMBus adapter drivers"
 
diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c
index 2e067dd2..c57c837 100644
--- a/drivers/i2c/busses/i2c-eg20t.c
+++ b/drivers/i2c/busses/i2c-eg20t.c
@@ -131,6 +131,13 @@
 #define pch_pci_dbg(pdev, fmt, arg...)  \
 	dev_dbg(&pdev->dev, "%s :" fmt, __func__, ##arg)
 
+/*
+Set the number of I2C instance max
+Intel EG20T PCH :		1ch
+OKI SEMICONDUCTOR ML7213 IOH :	2ch
+*/
+#define PCH_I2C_MAX_DEV			2
+
 /**
  * struct i2c_algo_pch_data - for I2C driver functionalities
  * @pch_adapter:		stores the reference to i2c_adapter structure
@@ -155,12 +162,14 @@ struct i2c_algo_pch_data {
  * @pch_data:		stores a list of i2c_algo_pch_data
  * @pch_i2c_suspended:	specifies whether the system is suspended or not
  *			perhaps with more lines and words.
+ * @ch_num:		specifies the number of i2c instance
  *
  * pch_data has as many elements as maximum I2C channels
  */
 struct adapter_info {
-	struct i2c_algo_pch_data pch_data;
+	struct i2c_algo_pch_data pch_data[PCH_I2C_MAX_DEV];
 	bool pch_i2c_suspended;
+	int ch_num;
 };
 
 
@@ -169,8 +178,13 @@ static int pch_clk = 50000;	/* specifies I2C clock speed in KHz */
 static wait_queue_head_t pch_event;
 static DEFINE_MUTEX(pch_mutex);
 
+/* Definition for ML7213 by OKI SEMICONDUCTOR */
+#define PCI_VENDOR_ID_ROHM		0x10DB
+#define PCI_DEVICE_ID_ML7213_I2C	0x802D
+
 static struct pci_device_id __devinitdata pch_pcidev_id[] = {
-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PCH_I2C)},
+	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH_I2C),   1, },
+	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_I2C), 2, },
 	{0,}
 };
 
@@ -211,8 +225,7 @@ static void pch_i2c_init(struct i2c_algo_pch_data *adap)
 	/* Initialize I2C registers */
 	iowrite32(0x21, p + PCH_I2CNF);
 
-	pch_setbit(adap->pch_base_address, PCH_I2CCTL,
-			  PCH_I2CCTL_I2CMEN);
+	pch_setbit(adap->pch_base_address, PCH_I2CCTL, PCH_I2CCTL_I2CMEN);
 
 	if (pch_i2c_speed != 400)
 		pch_i2c_speed = 100;
@@ -254,7 +267,7 @@ static inline bool ktime_lt(const ktime_t cmp1, const ktime_t cmp2)
  * @timeout:	waiting time counter (us).
  */
 static s32 pch_i2c_wait_for_bus_idle(struct i2c_algo_pch_data *adap,
-				 s32 timeout)
+				     s32 timeout)
 {
 	void __iomem *p = adap->pch_base_address;
 
@@ -474,8 +487,8 @@ static void pch_i2c_sendnack(struct i2c_algo_pch_data *adap)
  * @last:	specifies whether last message or not.
  * @first:	specifies whether first message or not.
  */
-s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
-		  u32 last, u32 first)
+static s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
+			     u32 last, u32 first)
 {
 	struct i2c_algo_pch_data *adap = i2c_adap->algo_data;
 
@@ -568,10 +581,10 @@ s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
 }
 
 /**
- * pch_i2c_cb_ch0() - Interrupt handler Call back function
+ * pch_i2c_cb() - Interrupt handler Call back function
  * @adap:	Pointer to struct i2c_algo_pch_data.
  */
-static void pch_i2c_cb_ch0(struct i2c_algo_pch_data *adap)
+static void pch_i2c_cb(struct i2c_algo_pch_data *adap)
 {
 	u32 sts;
 	void __iomem *p = adap->pch_base_address;
@@ -599,24 +612,30 @@ static void pch_i2c_cb_ch0(struct i2c_algo_pch_data *adap)
  */
 static irqreturn_t pch_i2c_handler(int irq, void *pData)
 {
-	s32 reg_val;
-
-	struct i2c_algo_pch_data *adap_data = (struct i2c_algo_pch_data *)pData;
-	void __iomem *p = adap_data->pch_base_address;
-	u32 mode = ioread32(p + PCH_I2CMOD) & (BUFFER_MODE | EEPROM_SR_MODE);
-
-	if (mode != NORMAL_MODE) {
-		pch_err(adap_data, "I2C mode is not supported\n");
-		return IRQ_NONE;
+	u32 reg_val;
+	int flag;
+	int i;
+	struct adapter_info *adap_info = pData;
+	void __iomem *p;
+	u32 mode;
+
+	for (i = 0, flag = 0; i < adap_info->ch_num; i++) {
+		p = adap_info->pch_data[i].pch_base_address;
+		mode = ioread32(p + PCH_I2CMOD);
+		mode &= BUFFER_MODE | EEPROM_SR_MODE;
+		if (mode != NORMAL_MODE) {
+			pch_err(adap_info->pch_data,
+				"I2C-%d mode(%d) is not supported\n", mode, i);
+			continue;
+		}
+		reg_val = ioread32(p + PCH_I2CSR);
+		if (reg_val & (I2CMAL_BIT | I2CMCF_BIT | I2CMIF_BIT)) {
+			pch_i2c_cb(&adap_info->pch_data[i]);
+			flag = 1;
+		}
 	}
 
-	reg_val = ioread32(p + PCH_I2CSR);
-	if (reg_val & (I2CMAL_BIT | I2CMCF_BIT | I2CMIF_BIT))
-		pch_i2c_cb_ch0(adap_data);
-	else
-		return IRQ_NONE;
-
-	return IRQ_HANDLED;
+	return flag ? IRQ_HANDLED : IRQ_NONE;
 }
 
 /**
@@ -626,7 +645,7 @@ static irqreturn_t pch_i2c_handler(int irq, void *pData)
  * @num:	number of messages.
  */
 static s32 pch_i2c_xfer(struct i2c_adapter *i2c_adap,
-		    struct i2c_msg *msgs, s32 num)
+			struct i2c_msg *msgs, s32 num)
 {
 	struct i2c_msg *pmsg;
 	u32 i = 0;
@@ -709,11 +728,13 @@ static void pch_i2c_disbl_int(struct i2c_algo_pch_data *adap)
 }
 
 static int __devinit pch_i2c_probe(struct pci_dev *pdev,
-			       const struct pci_device_id *id)
+				   const struct pci_device_id *id)
 {
 	void __iomem *base_addr;
-	s32 ret;
+	int ret;
+	int i, j;
 	struct adapter_info *adap_info;
+	struct i2c_adapter *pch_adap;
 
 	pch_pci_dbg(pdev, "Entered.\n");
 
@@ -743,44 +764,48 @@ static int __devinit pch_i2c_probe(struct pci_dev *pdev,
 		goto err_pci_iomap;
 	}
 
-	adap_info->pch_i2c_suspended = false;
+	/* Set the number of I2C channel instance */
+	adap_info->ch_num = id->driver_data;
 
-	adap_info->pch_data.p_adapter_info = adap_info;
+	for (i = 0; i < adap_info->ch_num; i++) {
+		pch_adap = &adap_info->pch_data[i].pch_adapter;
+		adap_info->pch_i2c_suspended = false;
 
-	adap_info->pch_data.pch_adapter.owner = THIS_MODULE;
-	adap_info->pch_data.pch_adapter.class = I2C_CLASS_HWMON;
-	strcpy(adap_info->pch_data.pch_adapter.name, KBUILD_MODNAME);
-	adap_info->pch_data.pch_adapter.algo = &pch_algorithm;
-	adap_info->pch_data.pch_adapter.algo_data =
-						&adap_info->pch_data;
+		adap_info->pch_data[i].p_adapter_info = adap_info;
 
-	/* (i * 0x80) + base_addr; */
-	adap_info->pch_data.pch_base_address = base_addr;
+		pch_adap->owner = THIS_MODULE;
+		pch_adap->class = I2C_CLASS_HWMON;
+		strcpy(pch_adap->name, KBUILD_MODNAME);
+		pch_adap->algo = &pch_algorithm;
+		pch_adap->algo_data = &adap_info->pch_data[i];
 
-	adap_info->pch_data.pch_adapter.dev.parent = &pdev->dev;
+		/* base_addr + offset; */
+		adap_info->pch_data[i].pch_base_address = base_addr + 0x100 * i;
 
-	ret = i2c_add_adapter(&(adap_info->pch_data.pch_adapter));
+		pch_adap->dev.parent = &pdev->dev;
 
-	if (ret) {
-		pch_pci_err(pdev, "i2c_add_adapter FAILED\n");
-		goto err_i2c_add_adapter;
-	}
+		ret = i2c_add_adapter(pch_adap);
+		if (ret) {
+			pch_pci_err(pdev, "i2c_add_adapter[ch:%d] FAILED\n", i);
+			goto err_i2c_add_adapter;
+		}
 
-	pch_i2c_init(&adap_info->pch_data);
+		pch_i2c_init(&adap_info->pch_data[i]);
+	}
 	ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED,
-		  KBUILD_MODNAME, &adap_info->pch_data);
+		  KBUILD_MODNAME, adap_info);
 	if (ret) {
 		pch_pci_err(pdev, "request_irq FAILED\n");
-		goto err_request_irq;
+		goto err_i2c_add_adapter;
 	}
 
 	pci_set_drvdata(pdev, adap_info);
 	pch_pci_dbg(pdev, "returns %d.\n", ret);
 	return 0;
 
-err_request_irq:
-	i2c_del_adapter(&(adap_info->pch_data.pch_adapter));
 err_i2c_add_adapter:
+	for (j = 0; j < i; j++)
+		i2c_del_adapter(&adap_info->pch_data[j].pch_adapter);
 	pci_iounmap(pdev, base_addr);
 err_pci_iomap:
 	pci_release_regions(pdev);
@@ -793,17 +818,22 @@ err_pci_enable:
 
 static void __devexit pch_i2c_remove(struct pci_dev *pdev)
 {
+	int i;
 	struct adapter_info *adap_info = pci_get_drvdata(pdev);
 
-	pch_i2c_disbl_int(&adap_info->pch_data);
-	free_irq(pdev->irq, &adap_info->pch_data);
-	i2c_del_adapter(&(adap_info->pch_data.pch_adapter));
+	free_irq(pdev->irq, adap_info);
 
-	if (adap_info->pch_data.pch_base_address) {
-		pci_iounmap(pdev, adap_info->pch_data.pch_base_address);
-		adap_info->pch_data.pch_base_address = 0;
+	for (i = 0; i < adap_info->ch_num; i++) {
+		pch_i2c_disbl_int(&adap_info->pch_data[i]);
+		i2c_del_adapter(&adap_info->pch_data[i].pch_adapter);
 	}
 
+	if (adap_info->pch_data[0].pch_base_address)
+		pci_iounmap(pdev, adap_info->pch_data[0].pch_base_address);
+
+	for (i = 0; i < adap_info->ch_num; i++)
+		adap_info->pch_data[i].pch_base_address = 0;
+
 	pci_set_drvdata(pdev, NULL);
 
 	pci_release_regions(pdev);
@@ -816,17 +846,22 @@ static void __devexit pch_i2c_remove(struct pci_dev *pdev)
 static int pch_i2c_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	int ret;
+	int i;
 	struct adapter_info *adap_info = pci_get_drvdata(pdev);
-	void __iomem *p = adap_info->pch_data.pch_base_address;
+	void __iomem *p = adap_info->pch_data[0].pch_base_address;
 
 	adap_info->pch_i2c_suspended = true;
 
-	while ((adap_info->pch_data.pch_i2c_xfer_in_progress)) {
-		/* Wait until all channel transfers are completed */
-		msleep(20);
+	for (i = 0; i < adap_info->ch_num; i++) {
+		while ((adap_info->pch_data[i].pch_i2c_xfer_in_progress)) {
+			/* Wait until all channel transfers are completed */
+			msleep(20);
+		}
 	}
+
 	/* Disable the i2c interrupts */
-	pch_i2c_disbl_int(&adap_info->pch_data);
+	for (i = 0; i < adap_info->ch_num; i++)
+		pch_i2c_disbl_int(&adap_info->pch_data[i]);
 
 	pch_pci_dbg(pdev, "I2CSR = %x I2CBUFSTA = %x I2CESRSTA = %x "
 		"invoked function pch_i2c_disbl_int successfully\n",
@@ -849,6 +884,7 @@ static int pch_i2c_suspend(struct pci_dev *pdev, pm_message_t state)
 
 static int pch_i2c_resume(struct pci_dev *pdev)
 {
+	int i;
 	struct adapter_info *adap_info = pci_get_drvdata(pdev);
 
 	pci_set_power_state(pdev, PCI_D0);
@@ -861,7 +897,8 @@ static int pch_i2c_resume(struct pci_dev *pdev)
 
 	pci_enable_wake(pdev, PCI_D3hot, 0);
 
-	pch_i2c_init(&adap_info->pch_data);
+	for (i = 0; i < adap_info->ch_num; i++)
+		pch_i2c_init(&adap_info->pch_data[i]);
 
 	adap_info->pch_i2c_suspended = false;
 
@@ -893,7 +930,7 @@ static void __exit pch_pci_exit(void)
 }
 module_exit(pch_pci_exit);
 
-MODULE_DESCRIPTION("PCH I2C PCI Driver");
+MODULE_DESCRIPTION("Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH I2C Driver");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Tomoya MORINAGA. <tomoya-linux@dsn.okisemi.com>");
 module_param(pch_i2c_speed, int, (S_IRUSR | S_IWUSR));
-- 
1.7.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] i2c-eg20t: support new device OKI SEMICONDUCTOR ML7213 IOH
@ 2011-03-02  0:39   ` Ben Dooks
  0 siblings, 0 replies; 6+ messages in thread
From: Ben Dooks @ 2011-03-02  0:39 UTC (permalink / raw)
  To: Tomoya MORINAGA
  Cc: Jean Delvare, Ben Dooks, Seth Heasley, Linus Walleij,
	Samuel Ortiz, linux-i2c, linux-kernel, qi.wang, yong.y.wang,
	joel.clark, kok.howg.ewe, toshiharu-linux

On 01/03/11 05:16, Tomoya MORINAGA wrote:
> Support new device OKI SEMICONDUCTOR ML7213 IOH.
> The ML7213 which is for IVI(In-Vehicle Infotainment) is a companion
> chip for the Atom E6xx series and compatible with the Intel EG20T
> PCH.

Ok, will apply to i2c-next.

> Signed-off-by: Tomoya MORINAGA<tomoya-linux@dsn.okisemi.com>
> ---
>
> v3 changes
> Update Ben's comments.
>    - Modify goto processing in probe.
>
>   drivers/i2c/busses/Kconfig     |   15 ++--
>   drivers/i2c/busses/i2c-eg20t.c |  161 ++++++++++++++++++++++++---------------
>   2 files changed, 108 insertions(+), 68 deletions(-)
>
> diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
> index 30f8dbd..61e3875 100644
> --- a/drivers/i2c/busses/Kconfig
> +++ b/drivers/i2c/busses/Kconfig

snip

> diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c
> index 2e067dd2..c57c837 100644
> --- a/drivers/i2c/busses/i2c-eg20t.c
> +++ b/drivers/i2c/busses/i2c-eg20t.c
> @@ -131,6 +131,13 @@
>   #define pch_pci_dbg(pdev, fmt, arg...)  \
>   	dev_dbg(&pdev->dev, "%s :" fmt, __func__, ##arg)
>
> +/*
> +Set the number of I2C instance max
> +Intel EG20T PCH :		1ch
> +OKI SEMICONDUCTOR ML7213 IOH :	2ch
> +*/
> +#define PCH_I2C_MAX_DEV			2
> +
>   /**
>    * struct i2c_algo_pch_data - for I2C driver functionalities
>    * @pch_adapter:		stores the reference to i2c_adapter structure
> @@ -155,12 +162,14 @@ struct i2c_algo_pch_data {
>    * @pch_data:		stores a list of i2c_algo_pch_data
>    * @pch_i2c_suspended:	specifies whether the system is suspended or not
>    *			perhaps with more lines and words.
> + * @ch_num:		specifies the number of i2c instance
>    *
>    * pch_data has as many elements as maximum I2C channels
>    */
>   struct adapter_info {
> -	struct i2c_algo_pch_data pch_data;
> +	struct i2c_algo_pch_data pch_data[PCH_I2C_MAX_DEV];
>   	bool pch_i2c_suspended;
> +	int ch_num;
>   };
>
>
> @@ -169,8 +178,13 @@ static int pch_clk = 50000;	/* specifies I2C clock speed in KHz */
>   static wait_queue_head_t pch_event;
>   static DEFINE_MUTEX(pch_mutex);
>
> +/* Definition for ML7213 by OKI SEMICONDUCTOR */
> +#define PCI_VENDOR_ID_ROHM		0x10DB
> +#define PCI_DEVICE_ID_ML7213_I2C	0x802D

we should get this moved to a pci header file at somepoint.


>
> -	adap_info->pch_data.p_adapter_info = adap_info;
> +	for (i = 0; i<  adap_info->ch_num; i++) {
> +		pch_adap =&adap_info->pch_data[i].pch_adapter;
> +		adap_info->pch_i2c_suspended = false;
>
> -	adap_info->pch_data.pch_adapter.owner = THIS_MODULE;
> -	adap_info->pch_data.pch_adapter.class = I2C_CLASS_HWMON;
> -	strcpy(adap_info->pch_data.pch_adapter.name, KBUILD_MODNAME);
> -	adap_info->pch_data.pch_adapter.algo =&pch_algorithm;
> -	adap_info->pch_data.pch_adapter.algo_data =
> -						&adap_info->pch_data;
> +		adap_info->pch_data[i].p_adapter_info = adap_info;
>
> -	/* (i * 0x80) + base_addr; */
> -	adap_info->pch_data.pch_base_address = base_addr;
> +		pch_adap->owner = THIS_MODULE;
> +		pch_adap->class = I2C_CLASS_HWMON;
> +		strcpy(pch_adap->name, KBUILD_MODNAME);

really should be strlcpy() and ensure that the string length is used.

>
> -	pch_i2c_init(&adap_info->pch_data);
> +		pch_i2c_init(&adap_info->pch_data[i]);
> +	}
>   	ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED,
> -		  KBUILD_MODNAME,&adap_info->pch_data);
> +		  KBUILD_MODNAME, adap_info);

how about using dev_name() of the platform device to register
these things?

> +		}
>   	

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] i2c-eg20t: support new device OKI SEMICONDUCTOR ML7213 IOH
@ 2011-03-02  0:39   ` Ben Dooks
  0 siblings, 0 replies; 6+ messages in thread
From: Ben Dooks @ 2011-03-02  0:39 UTC (permalink / raw)
  To: Tomoya MORINAGA
  Cc: Jean Delvare, Ben Dooks, Seth Heasley, Linus Walleij,
	Samuel Ortiz, linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	qi.wang-ral2JQCrhuEAvxtiuMwx3w,
	yong.y.wang-ral2JQCrhuEAvxtiuMwx3w,
	joel.clark-ral2JQCrhuEAvxtiuMwx3w,
	kok.howg.ewe-ral2JQCrhuEAvxtiuMwx3w,
	toshiharu-linux-ECg8zkTtlr0C6LszWs/t0g

On 01/03/11 05:16, Tomoya MORINAGA wrote:
> Support new device OKI SEMICONDUCTOR ML7213 IOH.
> The ML7213 which is for IVI(In-Vehicle Infotainment) is a companion
> chip for the Atom E6xx series and compatible with the Intel EG20T
> PCH.

Ok, will apply to i2c-next.

> Signed-off-by: Tomoya MORINAGA<tomoya-linux-ECg8zkTtlr0C6LszWs/t0g@public.gmane.org>
> ---
>
> v3 changes
> Update Ben's comments.
>    - Modify goto processing in probe.
>
>   drivers/i2c/busses/Kconfig     |   15 ++--
>   drivers/i2c/busses/i2c-eg20t.c |  161 ++++++++++++++++++++++++---------------
>   2 files changed, 108 insertions(+), 68 deletions(-)
>
> diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
> index 30f8dbd..61e3875 100644
> --- a/drivers/i2c/busses/Kconfig
> +++ b/drivers/i2c/busses/Kconfig

snip

> diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c
> index 2e067dd2..c57c837 100644
> --- a/drivers/i2c/busses/i2c-eg20t.c
> +++ b/drivers/i2c/busses/i2c-eg20t.c
> @@ -131,6 +131,13 @@
>   #define pch_pci_dbg(pdev, fmt, arg...)  \
>   	dev_dbg(&pdev->dev, "%s :" fmt, __func__, ##arg)
>
> +/*
> +Set the number of I2C instance max
> +Intel EG20T PCH :		1ch
> +OKI SEMICONDUCTOR ML7213 IOH :	2ch
> +*/
> +#define PCH_I2C_MAX_DEV			2
> +
>   /**
>    * struct i2c_algo_pch_data - for I2C driver functionalities
>    * @pch_adapter:		stores the reference to i2c_adapter structure
> @@ -155,12 +162,14 @@ struct i2c_algo_pch_data {
>    * @pch_data:		stores a list of i2c_algo_pch_data
>    * @pch_i2c_suspended:	specifies whether the system is suspended or not
>    *			perhaps with more lines and words.
> + * @ch_num:		specifies the number of i2c instance
>    *
>    * pch_data has as many elements as maximum I2C channels
>    */
>   struct adapter_info {
> -	struct i2c_algo_pch_data pch_data;
> +	struct i2c_algo_pch_data pch_data[PCH_I2C_MAX_DEV];
>   	bool pch_i2c_suspended;
> +	int ch_num;
>   };
>
>
> @@ -169,8 +178,13 @@ static int pch_clk = 50000;	/* specifies I2C clock speed in KHz */
>   static wait_queue_head_t pch_event;
>   static DEFINE_MUTEX(pch_mutex);
>
> +/* Definition for ML7213 by OKI SEMICONDUCTOR */
> +#define PCI_VENDOR_ID_ROHM		0x10DB
> +#define PCI_DEVICE_ID_ML7213_I2C	0x802D

we should get this moved to a pci header file at somepoint.


>
> -	adap_info->pch_data.p_adapter_info = adap_info;
> +	for (i = 0; i<  adap_info->ch_num; i++) {
> +		pch_adap =&adap_info->pch_data[i].pch_adapter;
> +		adap_info->pch_i2c_suspended = false;
>
> -	adap_info->pch_data.pch_adapter.owner = THIS_MODULE;
> -	adap_info->pch_data.pch_adapter.class = I2C_CLASS_HWMON;
> -	strcpy(adap_info->pch_data.pch_adapter.name, KBUILD_MODNAME);
> -	adap_info->pch_data.pch_adapter.algo =&pch_algorithm;
> -	adap_info->pch_data.pch_adapter.algo_data =
> -						&adap_info->pch_data;
> +		adap_info->pch_data[i].p_adapter_info = adap_info;
>
> -	/* (i * 0x80) + base_addr; */
> -	adap_info->pch_data.pch_base_address = base_addr;
> +		pch_adap->owner = THIS_MODULE;
> +		pch_adap->class = I2C_CLASS_HWMON;
> +		strcpy(pch_adap->name, KBUILD_MODNAME);

really should be strlcpy() and ensure that the string length is used.

>
> -	pch_i2c_init(&adap_info->pch_data);
> +		pch_i2c_init(&adap_info->pch_data[i]);
> +	}
>   	ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED,
> -		  KBUILD_MODNAME,&adap_info->pch_data);
> +		  KBUILD_MODNAME, adap_info);

how about using dev_name() of the platform device to register
these things?

> +		}
>   	

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: [PATCH v3] i2c-eg20t: support new device OKI SEMICONDUCTOR ML7213 IOH
@ 2011-03-02  3:18     ` Tomoya MORINAGA
  0 siblings, 0 replies; 6+ messages in thread
From: Tomoya MORINAGA @ 2011-03-02  3:18 UTC (permalink / raw)
  To: 'Ben Dooks'
  Cc: 'Jean Delvare', 'Ben Dooks',
	'Seth Heasley', 'Linus Walleij',
	'Samuel Ortiz',
	linux-i2c, linux-kernel, qi.wang, yong.y.wang, joel.clark,
	kok.howg.ewe, toshiharu-linux

Hi Ben,

On Wednesday, March 02, 2011 9:39 AM, Ben Dooks wrote:
> Ok, will apply to i2c-next.
Thank you for your applying.

> > +/* Definition for ML7213 by OKI SEMICONDUCTOR */
> > +#define PCI_VENDOR_ID_ROHM		0x10DB
> > +#define PCI_DEVICE_ID_ML7213_I2C	0x802D
> 
> we should get this moved to a pci header file at somepoint.
Do you mean include/linux/pci_ids ?


> > +		strcpy(pch_adap->name, KBUILD_MODNAME);
> 
> really should be strlcpy() and ensure that the string length is used.
OK.
We will update in next update.


> > -	pch_i2c_init(&adap_info->pch_data);
> > +		pch_i2c_init(&adap_info->pch_data[i]);
> > +	}
> >   	ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED,
> > -		  KBUILD_MODNAME,&adap_info->pch_data);
> > +		  KBUILD_MODNAME, adap_info);
> 
> how about using dev_name() of the platform device to register 
> these things?
Sorry, I can't understand your saying.
Could you explain in more detail ? 

Thanks,
-----------------------------------------
Tomoya MORINAGA
OKI SEMICONDUCTOR CO., LTD.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: [PATCH v3] i2c-eg20t: support new device OKI SEMICONDUCTOR ML7213 IOH
@ 2011-03-02  3:18     ` Tomoya MORINAGA
  0 siblings, 0 replies; 6+ messages in thread
From: Tomoya MORINAGA @ 2011-03-02  3:18 UTC (permalink / raw)
  To: 'Ben Dooks'
  Cc: 'Jean Delvare', 'Ben Dooks',
	'Seth Heasley', 'Linus Walleij',
	'Samuel Ortiz',
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	qi.wang-ral2JQCrhuEAvxtiuMwx3w,
	yong.y.wang-ral2JQCrhuEAvxtiuMwx3w,
	joel.clark-ral2JQCrhuEAvxtiuMwx3w,
	kok.howg.ewe-ral2JQCrhuEAvxtiuMwx3w,
	toshiharu-linux-ECg8zkTtlr0C6LszWs/t0g

Hi Ben,

On Wednesday, March 02, 2011 9:39 AM, Ben Dooks wrote:
> Ok, will apply to i2c-next.
Thank you for your applying.

> > +/* Definition for ML7213 by OKI SEMICONDUCTOR */
> > +#define PCI_VENDOR_ID_ROHM		0x10DB
> > +#define PCI_DEVICE_ID_ML7213_I2C	0x802D
> 
> we should get this moved to a pci header file at somepoint.
Do you mean include/linux/pci_ids ?


> > +		strcpy(pch_adap->name, KBUILD_MODNAME);
> 
> really should be strlcpy() and ensure that the string length is used.
OK.
We will update in next update.


> > -	pch_i2c_init(&adap_info->pch_data);
> > +		pch_i2c_init(&adap_info->pch_data[i]);
> > +	}
> >   	ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED,
> > -		  KBUILD_MODNAME,&adap_info->pch_data);
> > +		  KBUILD_MODNAME, adap_info);
> 
> how about using dev_name() of the platform device to register 
> these things?
Sorry, I can't understand your saying.
Could you explain in more detail ? 

Thanks,
-----------------------------------------
Tomoya MORINAGA
OKI SEMICONDUCTOR CO., LTD.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v3] i2c-eg20t: support new device OKI SEMICONDUCTOR ML7213 IOH
@ 2011-03-01  5:16 Tomoya MORINAGA
  0 siblings, 0 replies; 6+ messages in thread
From: Tomoya MORINAGA @ 2011-03-01  5:16 UTC (permalink / raw)
  To: Jean Delvare, Ben Dooks, Seth Heasley, Linus Walleij, Samuel Ortiz
  Cc: qi.wang-ral2JQCrhuEAvxtiuMwx3w,
	yong.y.wang-ral2JQCrhuEAvxtiuMwx3w,
	joel.clark-ral2JQCrhuEAvxtiuMwx3w,
	kok.howg.ewe-ral2JQCrhuEAvxtiuMwx3w,
	toshiharu-linux-ECg8zkTtlr0C6LszWs/t0g, Tomoya MORINAGA

Support new device OKI SEMICONDUCTOR ML7213 IOH.
The ML7213 which is for IVI(In-Vehicle Infotainment) is a companion
chip for the Atom E6xx series and compatible with the Intel EG20T
PCH.

Signed-off-by: Tomoya MORINAGA <tomoya-linux-ECg8zkTtlr0C6LszWs/t0g@public.gmane.org>
---

v3 changes
Update Ben's comments.
  - Modify goto processing in probe.

 drivers/i2c/busses/Kconfig     |   15 ++--
 drivers/i2c/busses/i2c-eg20t.c |  161 ++++++++++++++++++++++++---------------
 2 files changed, 108 insertions(+), 68 deletions(-)

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 30f8dbd..61e3875 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -639,12 +639,15 @@ config I2C_XILINX
 	  will be called xilinx_i2c.
 
 config I2C_EG20T
-        tristate "PCH I2C of Intel EG20T"
-        depends on PCI
-        help
-          This driver is for PCH(Platform controller Hub) I2C of EG20T which
-          is an IOH(Input/Output Hub) for x86 embedded processor.
-          This driver can access PCH I2C bus device.
+	tristate "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH"
+	depends on PCI
+	help
+	  This driver is for PCH(Platform controller Hub) I2C of EG20T which
+	  is an IOH(Input/Output Hub) for x86 embedded processor.
+	  This driver can access PCH I2C bus device.
+
+	  This driver also supports the ML7213, a companion chip for the
+	  Atom E6xx series and compatible with the Intel EG20T PCH.
 
 comment "External I2C/SMBus adapter drivers"
 
diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c
index 2e067dd2..c57c837 100644
--- a/drivers/i2c/busses/i2c-eg20t.c
+++ b/drivers/i2c/busses/i2c-eg20t.c
@@ -131,6 +131,13 @@
 #define pch_pci_dbg(pdev, fmt, arg...)  \
 	dev_dbg(&pdev->dev, "%s :" fmt, __func__, ##arg)
 
+/*
+Set the number of I2C instance max
+Intel EG20T PCH :		1ch
+OKI SEMICONDUCTOR ML7213 IOH :	2ch
+*/
+#define PCH_I2C_MAX_DEV			2
+
 /**
  * struct i2c_algo_pch_data - for I2C driver functionalities
  * @pch_adapter:		stores the reference to i2c_adapter structure
@@ -155,12 +162,14 @@ struct i2c_algo_pch_data {
  * @pch_data:		stores a list of i2c_algo_pch_data
  * @pch_i2c_suspended:	specifies whether the system is suspended or not
  *			perhaps with more lines and words.
+ * @ch_num:		specifies the number of i2c instance
  *
  * pch_data has as many elements as maximum I2C channels
  */
 struct adapter_info {
-	struct i2c_algo_pch_data pch_data;
+	struct i2c_algo_pch_data pch_data[PCH_I2C_MAX_DEV];
 	bool pch_i2c_suspended;
+	int ch_num;
 };
 
 
@@ -169,8 +178,13 @@ static int pch_clk = 50000;	/* specifies I2C clock speed in KHz */
 static wait_queue_head_t pch_event;
 static DEFINE_MUTEX(pch_mutex);
 
+/* Definition for ML7213 by OKI SEMICONDUCTOR */
+#define PCI_VENDOR_ID_ROHM		0x10DB
+#define PCI_DEVICE_ID_ML7213_I2C	0x802D
+
 static struct pci_device_id __devinitdata pch_pcidev_id[] = {
-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PCH_I2C)},
+	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH_I2C),   1, },
+	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_I2C), 2, },
 	{0,}
 };
 
@@ -211,8 +225,7 @@ static void pch_i2c_init(struct i2c_algo_pch_data *adap)
 	/* Initialize I2C registers */
 	iowrite32(0x21, p + PCH_I2CNF);
 
-	pch_setbit(adap->pch_base_address, PCH_I2CCTL,
-			  PCH_I2CCTL_I2CMEN);
+	pch_setbit(adap->pch_base_address, PCH_I2CCTL, PCH_I2CCTL_I2CMEN);
 
 	if (pch_i2c_speed != 400)
 		pch_i2c_speed = 100;
@@ -254,7 +267,7 @@ static inline bool ktime_lt(const ktime_t cmp1, const ktime_t cmp2)
  * @timeout:	waiting time counter (us).
  */
 static s32 pch_i2c_wait_for_bus_idle(struct i2c_algo_pch_data *adap,
-				 s32 timeout)
+				     s32 timeout)
 {
 	void __iomem *p = adap->pch_base_address;
 
@@ -474,8 +487,8 @@ static void pch_i2c_sendnack(struct i2c_algo_pch_data *adap)
  * @last:	specifies whether last message or not.
  * @first:	specifies whether first message or not.
  */
-s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
-		  u32 last, u32 first)
+static s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
+			     u32 last, u32 first)
 {
 	struct i2c_algo_pch_data *adap = i2c_adap->algo_data;
 
@@ -568,10 +581,10 @@ s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
 }
 
 /**
- * pch_i2c_cb_ch0() - Interrupt handler Call back function
+ * pch_i2c_cb() - Interrupt handler Call back function
  * @adap:	Pointer to struct i2c_algo_pch_data.
  */
-static void pch_i2c_cb_ch0(struct i2c_algo_pch_data *adap)
+static void pch_i2c_cb(struct i2c_algo_pch_data *adap)
 {
 	u32 sts;
 	void __iomem *p = adap->pch_base_address;
@@ -599,24 +612,30 @@ static void pch_i2c_cb_ch0(struct i2c_algo_pch_data *adap)
  */
 static irqreturn_t pch_i2c_handler(int irq, void *pData)
 {
-	s32 reg_val;
-
-	struct i2c_algo_pch_data *adap_data = (struct i2c_algo_pch_data *)pData;
-	void __iomem *p = adap_data->pch_base_address;
-	u32 mode = ioread32(p + PCH_I2CMOD) & (BUFFER_MODE | EEPROM_SR_MODE);
-
-	if (mode != NORMAL_MODE) {
-		pch_err(adap_data, "I2C mode is not supported\n");
-		return IRQ_NONE;
+	u32 reg_val;
+	int flag;
+	int i;
+	struct adapter_info *adap_info = pData;
+	void __iomem *p;
+	u32 mode;
+
+	for (i = 0, flag = 0; i < adap_info->ch_num; i++) {
+		p = adap_info->pch_data[i].pch_base_address;
+		mode = ioread32(p + PCH_I2CMOD);
+		mode &= BUFFER_MODE | EEPROM_SR_MODE;
+		if (mode != NORMAL_MODE) {
+			pch_err(adap_info->pch_data,
+				"I2C-%d mode(%d) is not supported\n", mode, i);
+			continue;
+		}
+		reg_val = ioread32(p + PCH_I2CSR);
+		if (reg_val & (I2CMAL_BIT | I2CMCF_BIT | I2CMIF_BIT)) {
+			pch_i2c_cb(&adap_info->pch_data[i]);
+			flag = 1;
+		}
 	}
 
-	reg_val = ioread32(p + PCH_I2CSR);
-	if (reg_val & (I2CMAL_BIT | I2CMCF_BIT | I2CMIF_BIT))
-		pch_i2c_cb_ch0(adap_data);
-	else
-		return IRQ_NONE;
-
-	return IRQ_HANDLED;
+	return flag ? IRQ_HANDLED : IRQ_NONE;
 }
 
 /**
@@ -626,7 +645,7 @@ static irqreturn_t pch_i2c_handler(int irq, void *pData)
  * @num:	number of messages.
  */
 static s32 pch_i2c_xfer(struct i2c_adapter *i2c_adap,
-		    struct i2c_msg *msgs, s32 num)
+			struct i2c_msg *msgs, s32 num)
 {
 	struct i2c_msg *pmsg;
 	u32 i = 0;
@@ -709,11 +728,13 @@ static void pch_i2c_disbl_int(struct i2c_algo_pch_data *adap)
 }
 
 static int __devinit pch_i2c_probe(struct pci_dev *pdev,
-			       const struct pci_device_id *id)
+				   const struct pci_device_id *id)
 {
 	void __iomem *base_addr;
-	s32 ret;
+	int ret;
+	int i, j;
 	struct adapter_info *adap_info;
+	struct i2c_adapter *pch_adap;
 
 	pch_pci_dbg(pdev, "Entered.\n");
 
@@ -743,44 +764,48 @@ static int __devinit pch_i2c_probe(struct pci_dev *pdev,
 		goto err_pci_iomap;
 	}
 
-	adap_info->pch_i2c_suspended = false;
+	/* Set the number of I2C channel instance */
+	adap_info->ch_num = id->driver_data;
 
-	adap_info->pch_data.p_adapter_info = adap_info;
+	for (i = 0; i < adap_info->ch_num; i++) {
+		pch_adap = &adap_info->pch_data[i].pch_adapter;
+		adap_info->pch_i2c_suspended = false;
 
-	adap_info->pch_data.pch_adapter.owner = THIS_MODULE;
-	adap_info->pch_data.pch_adapter.class = I2C_CLASS_HWMON;
-	strcpy(adap_info->pch_data.pch_adapter.name, KBUILD_MODNAME);
-	adap_info->pch_data.pch_adapter.algo = &pch_algorithm;
-	adap_info->pch_data.pch_adapter.algo_data =
-						&adap_info->pch_data;
+		adap_info->pch_data[i].p_adapter_info = adap_info;
 
-	/* (i * 0x80) + base_addr; */
-	adap_info->pch_data.pch_base_address = base_addr;
+		pch_adap->owner = THIS_MODULE;
+		pch_adap->class = I2C_CLASS_HWMON;
+		strcpy(pch_adap->name, KBUILD_MODNAME);
+		pch_adap->algo = &pch_algorithm;
+		pch_adap->algo_data = &adap_info->pch_data[i];
 
-	adap_info->pch_data.pch_adapter.dev.parent = &pdev->dev;
+		/* base_addr + offset; */
+		adap_info->pch_data[i].pch_base_address = base_addr + 0x100 * i;
 
-	ret = i2c_add_adapter(&(adap_info->pch_data.pch_adapter));
+		pch_adap->dev.parent = &pdev->dev;
 
-	if (ret) {
-		pch_pci_err(pdev, "i2c_add_adapter FAILED\n");
-		goto err_i2c_add_adapter;
-	}
+		ret = i2c_add_adapter(pch_adap);
+		if (ret) {
+			pch_pci_err(pdev, "i2c_add_adapter[ch:%d] FAILED\n", i);
+			goto err_i2c_add_adapter;
+		}
 
-	pch_i2c_init(&adap_info->pch_data);
+		pch_i2c_init(&adap_info->pch_data[i]);
+	}
 	ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED,
-		  KBUILD_MODNAME, &adap_info->pch_data);
+		  KBUILD_MODNAME, adap_info);
 	if (ret) {
 		pch_pci_err(pdev, "request_irq FAILED\n");
-		goto err_request_irq;
+		goto err_i2c_add_adapter;
 	}
 
 	pci_set_drvdata(pdev, adap_info);
 	pch_pci_dbg(pdev, "returns %d.\n", ret);
 	return 0;
 
-err_request_irq:
-	i2c_del_adapter(&(adap_info->pch_data.pch_adapter));
 err_i2c_add_adapter:
+	for (j = 0; j < i; j++)
+		i2c_del_adapter(&adap_info->pch_data[j].pch_adapter);
 	pci_iounmap(pdev, base_addr);
 err_pci_iomap:
 	pci_release_regions(pdev);
@@ -793,17 +818,22 @@ err_pci_enable:
 
 static void __devexit pch_i2c_remove(struct pci_dev *pdev)
 {
+	int i;
 	struct adapter_info *adap_info = pci_get_drvdata(pdev);
 
-	pch_i2c_disbl_int(&adap_info->pch_data);
-	free_irq(pdev->irq, &adap_info->pch_data);
-	i2c_del_adapter(&(adap_info->pch_data.pch_adapter));
+	free_irq(pdev->irq, adap_info);
 
-	if (adap_info->pch_data.pch_base_address) {
-		pci_iounmap(pdev, adap_info->pch_data.pch_base_address);
-		adap_info->pch_data.pch_base_address = 0;
+	for (i = 0; i < adap_info->ch_num; i++) {
+		pch_i2c_disbl_int(&adap_info->pch_data[i]);
+		i2c_del_adapter(&adap_info->pch_data[i].pch_adapter);
 	}
 
+	if (adap_info->pch_data[0].pch_base_address)
+		pci_iounmap(pdev, adap_info->pch_data[0].pch_base_address);
+
+	for (i = 0; i < adap_info->ch_num; i++)
+		adap_info->pch_data[i].pch_base_address = 0;
+
 	pci_set_drvdata(pdev, NULL);
 
 	pci_release_regions(pdev);
@@ -816,17 +846,22 @@ static void __devexit pch_i2c_remove(struct pci_dev *pdev)
 static int pch_i2c_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	int ret;
+	int i;
 	struct adapter_info *adap_info = pci_get_drvdata(pdev);
-	void __iomem *p = adap_info->pch_data.pch_base_address;
+	void __iomem *p = adap_info->pch_data[0].pch_base_address;
 
 	adap_info->pch_i2c_suspended = true;
 
-	while ((adap_info->pch_data.pch_i2c_xfer_in_progress)) {
-		/* Wait until all channel transfers are completed */
-		msleep(20);
+	for (i = 0; i < adap_info->ch_num; i++) {
+		while ((adap_info->pch_data[i].pch_i2c_xfer_in_progress)) {
+			/* Wait until all channel transfers are completed */
+			msleep(20);
+		}
 	}
+
 	/* Disable the i2c interrupts */
-	pch_i2c_disbl_int(&adap_info->pch_data);
+	for (i = 0; i < adap_info->ch_num; i++)
+		pch_i2c_disbl_int(&adap_info->pch_data[i]);
 
 	pch_pci_dbg(pdev, "I2CSR = %x I2CBUFSTA = %x I2CESRSTA = %x "
 		"invoked function pch_i2c_disbl_int successfully\n",
@@ -849,6 +884,7 @@ static int pch_i2c_suspend(struct pci_dev *pdev, pm_message_t state)
 
 static int pch_i2c_resume(struct pci_dev *pdev)
 {
+	int i;
 	struct adapter_info *adap_info = pci_get_drvdata(pdev);
 
 	pci_set_power_state(pdev, PCI_D0);
@@ -861,7 +897,8 @@ static int pch_i2c_resume(struct pci_dev *pdev)
 
 	pci_enable_wake(pdev, PCI_D3hot, 0);
 
-	pch_i2c_init(&adap_info->pch_data);
+	for (i = 0; i < adap_info->ch_num; i++)
+		pch_i2c_init(&adap_info->pch_data[i]);
 
 	adap_info->pch_i2c_suspended = false;
 
@@ -893,7 +930,7 @@ static void __exit pch_pci_exit(void)
 }
 module_exit(pch_pci_exit);
 
-MODULE_DESCRIPTION("PCH I2C PCI Driver");
+MODULE_DESCRIPTION("Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH I2C Driver");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Tomoya MORINAGA. <tomoya-linux-ECg8zkTtlr0C6LszWs/t0g@public.gmane.org>");
 module_param(pch_i2c_speed, int, (S_IRUSR | S_IWUSR));
-- 
1.7.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-03-02  3:18 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-01  5:16 [PATCH v3] i2c-eg20t: support new device OKI SEMICONDUCTOR ML7213 IOH Tomoya MORINAGA
2011-03-02  0:39 ` Ben Dooks
2011-03-02  0:39   ` Ben Dooks
2011-03-02  3:18   ` Tomoya MORINAGA
2011-03-02  3:18     ` Tomoya MORINAGA
  -- strict thread matches above, loose matches on Subject: below --
2011-03-01  5:16 Tomoya MORINAGA

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.