linux-i2c.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Guenter Roeck <guenter.roeck@ericsson.com>
To: Jean Delvare <khali@linux-fr.org>, Ben Dooks <ben-linux@fluff.org>
Cc: Randy Dunlap <rdunlap@xenotime.net>,
	linux-i2c@vger.kernel.org, linux-usb@vger.kernel.org,
	linux-doc@vger.kernel.org,
	Guenter Roeck <guenter.roeck@ericsson.com>
Subject: [PATCH] i2c/busses: Driver for Devantech USB-ISS I2C adapter
Date: Tue, 22 Mar 2011 20:43:47 -0700	[thread overview]
Message-ID: <1300851827-13627-1-git-send-email-guenter.roeck@ericsson.com> (raw)

This patch adds support for the I2C interface of the Devantech USB-ISS
Multifunction adapter.

Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
---
The driver has one problem: It competes with the cdc_acm driver for device
access. Copying the usb mailing list in the hope that someone can tell me
if there is a way to prevent this from happening.

 Documentation/i2c/busses/i2c-devantech-iss |   31 ++
 drivers/i2c/busses/Kconfig                 |   10 +
 drivers/i2c/busses/Makefile                |    1 +
 drivers/i2c/busses/i2c-devantech-iss.c     |  495 ++++++++++++++++++++++++++++
 4 files changed, 537 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/i2c/busses/i2c-devantech-iss
 create mode 100644 drivers/i2c/busses/i2c-devantech-iss.c

diff --git a/Documentation/i2c/busses/i2c-devantech-iss b/Documentation/i2c/busses/i2c-devantech-iss
new file mode 100644
index 0000000..f8199fd
--- /dev/null
+++ b/Documentation/i2c/busses/i2c-devantech-iss
@@ -0,0 +1,31 @@
+Kernel driver i2c-devantech-iss
+
+Supported adapters:
+  * Devantech USB-ISS Multifunction USB Communications Module
+    Documentation:
+        http://www.robot-electronics.co.uk/htm/usb_iss_tech.htm
+
+Author: Guenter Roeck <guenter.roeck@ericsson.com>
+
+
+Description
+-----------
+
+This is the driver for the Devantech USB-ISS Multifunction USB Communications
+Module.
+
+The USB-ISS Multifunction USB Communications Module provides an interface
+to I2C, SPI, Serial port, and general purpose Analogue Input or Digital I/O.
+The module is powered from USB.
+
+The driver only supports the I2C interface of USB-ISS. The driver does not use
+interrupts.
+
+Clock stretching is supported for bus frequencies of 100,000 Hz and above.
+
+
+Module parameters
+-----------------
+
+* frequency: I2C bus frequency in Hz
+  Supported frequencies are 20,000, 50,000, 100,000, 400,000, and 1,000,000 Hz.
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 230601e..0bffacd 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -676,6 +676,16 @@ config I2C_EG20T
 
 comment "External I2C/SMBus adapter drivers"
 
+config I2C_DEVANTECH
+	tristate "Devantech USB-ISS"
+	select I2C_SMBUS
+	help
+	  This supports the I2C interface of the Devantech USB-ISS Multifunction
+	  Communications Module.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-devantech-iss.
+
 config I2C_PARPORT
 	tristate "Parallel port adapter"
 	depends on PARPORT
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 3878c95..5ecec28 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_I2C_XILINX)	+= i2c-xiic.o
 obj-$(CONFIG_I2C_EG20T)         += i2c-eg20t.o
 
 # External I2C/SMBus adapter drivers
+obj-$(CONFIG_I2C_DEVANTECH)	+= i2c-devantech-iss.o
 obj-$(CONFIG_I2C_PARPORT)	+= i2c-parport.o
 obj-$(CONFIG_I2C_PARPORT_LIGHT)	+= i2c-parport-light.o
 obj-$(CONFIG_I2C_TAOS_EVM)	+= i2c-taos-evm.o
diff --git a/drivers/i2c/busses/i2c-devantech-iss.c b/drivers/i2c/busses/i2c-devantech-iss.c
new file mode 100644
index 0000000..b14daa6
--- /dev/null
+++ b/drivers/i2c/busses/i2c-devantech-iss.c
@@ -0,0 +1,495 @@
+/*
+ * Driver for the Devantech USB-ISS Multifunction Communications Module
+ *
+ * Copyright (c) 2011 Ericsson AB
+ *
+ * Derived from:
+ *  i2c-diolan-u2c.c
+ *  Copyright (c) 2010-2011 Ericsson AB
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/i2c.h>
+
+#define DRIVER_NAME		"i2c-devantech-iss"
+
+#define USB_VENDOR_ID_DEVANTECH	0x04d8
+#define USB_DEVICE_ID_ISS	0xffee
+
+/* commands */
+#define ISS_CMD_I2C_DIRECT	0x57	/* Custom I2C sequence */
+#define ISS_CMD_I2C_INTERNAL	0x5a	/* internal commands */
+
+/* direct commands */
+#define ISS_I2C_START		0x01
+#define ISS_I2C_RESTART		0x02
+#define ISS_I2C_STOP		0x03
+#define ISS_I2C_NACK		0x04
+#define ISS_I2C_READ(n)		(0x20 + (n) - 1)
+#define ISS_I2C_WRITE(n)	(0x30 + (n) - 1)
+
+/* internal commands */
+#define ISS_GET_VERSION		0x01
+#define ISS_MODE		0x02
+#define ISS_GET_SERIAL		0x03
+
+/* modes */
+#define ISS_MODE_I2C_S_20KHZ	0x20	/* I2C, SW (bitbang), 20 kHz clock */
+#define ISS_MODE_I2C_S_50KHZ	0x30	/* I2C, SW (bitbang), 50 kHz clock */
+#define ISS_MODE_I2C_S_100KHZ	0x40	/* I2C, SW (bitbang), 100 kHz clock */
+#define ISS_MODE_I2C_S_400KHZ	0x50	/* I2C, SW (bitbang), 400 kHz clock */
+#define ISS_MODE_I2C_H_100KHZ	0x60	/* I2C, HW (PIC), 100 kHz clock */
+#define ISS_MODE_I2C_H_400KHZ	0x70	/* I2C, HW (PIC), 400 kHz clock */
+#define ISS_MODE_I2C_H_1000KHZ	0x80	/* I2C, HW (PIC), 1000 kHz clock */
+
+/* response codes */
+
+#define ISS_RESP_ACK		0xff
+#define ISS_RESP_NACK		0x00
+
+#define ISS_RESP_OK		0x00
+#define ISS_RESP_DEV_ERROR	0x01
+#define ISS_RESP_OVERFLOW	0x02
+#define ISS_RESP_UNDERFLOW	0x03
+#define ISS_RESP_UNKNOWN_CMD	0x04
+
+#define ISS_USB_TIMEOUT		100	/* in ms */
+
+#define ISS_MAX_TRANSFER_LEN	60
+
+/* Structure to hold all of our device specific stuff */
+struct i2c_devantech_iss {
+	u8 buffer[ISS_MAX_TRANSFER_LEN];/* rx and tx buffer */
+	struct usb_interface *usb_if;	/* device data interface */
+	struct usb_interface *interface;/* device control interface */
+	struct usb_device *usb_dev;	/* the usb device for this interface */
+	struct i2c_adapter adapter;	/* i2c related things */
+	int ep_out, ep_in;
+};
+
+static uint frequency = 100000;	/* I2C clock frequency in Hz */
+module_param(frequency, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(frequency, "I2C clock frequency in hertz");
+
+static struct usb_driver devantech_iss_driver;
+
+/* usb layer */
+
+/* Send command to device, and get response. */
+static int devantech_usb_transfer(struct i2c_devantech_iss *dev, int len)
+{
+	int ret, actual;
+
+	if (len <= 0 || len > ISS_MAX_TRANSFER_LEN)
+		return -EINVAL;
+
+	ret = usb_bulk_msg(dev->usb_dev,
+			   usb_sndbulkpipe(dev->usb_dev, dev->ep_out),
+			   dev->buffer, len, &actual,
+			   ISS_USB_TIMEOUT);
+
+	if (!ret) {
+		ret = usb_bulk_msg(dev->usb_dev,
+				   usb_rcvbulkpipe(dev->usb_dev, dev->ep_in),
+				   dev->buffer, sizeof(dev->buffer),
+				   &actual, ISS_USB_TIMEOUT);
+		if (!ret && actual > 0)
+			ret = actual;
+	}
+	return ret;
+}
+
+static int devantech_set_speed(struct i2c_devantech_iss *dev, int speed)
+{
+	int ret;
+
+	dev->buffer[0] = ISS_CMD_I2C_INTERNAL;
+	dev->buffer[1] = ISS_MODE;
+	dev->buffer[2] = speed;
+	dev->buffer[3] = 0x04;
+
+	ret = devantech_usb_transfer(dev, 4);
+	if (ret < 0)
+		return ret;
+	if (!dev->buffer[0])
+		return -EINVAL;
+	return 0;
+}
+
+static void devantech_fw_version(struct i2c_devantech_iss *dev)
+{
+	int ret;
+
+	dev->buffer[0] = ISS_CMD_I2C_INTERNAL;
+	dev->buffer[1] = ISS_GET_VERSION;
+
+	ret = devantech_usb_transfer(dev, 2);
+	if (ret >= 3)
+		dev_info(&dev->interface->dev,
+			 "Devantech USB-ISS firmware version %u.%u\n",
+			 dev->buffer[0], dev->buffer[1]);
+	else
+		dev_err(&dev->interface->dev,
+			"Failed to get firmware version, error %d\n", ret);
+}
+
+static void devantech_get_serial(struct i2c_devantech_iss *dev)
+{
+	int ret;
+
+	dev->buffer[0] = ISS_CMD_I2C_INTERNAL;
+	dev->buffer[1] = ISS_GET_SERIAL;
+
+	ret = devantech_usb_transfer(dev, 2);
+	if (ret >= 8) {
+		dev->buffer[ret] = '\0';
+		dev_info(&dev->interface->dev,
+			 "Devantech USS-ISS serial number %s\n", dev->buffer);
+	} else {
+		dev_err(&dev->interface->dev,
+			"Failed to get serial number, error %d\n", ret);
+	}
+}
+
+static int devantech_init(struct i2c_devantech_iss *dev)
+{
+	int speed;
+
+	/*
+	 * Software (bit-bang) I2C implementation does not support I2C clock
+	 * stretching, at least not with firmware version 7.2. The PIC hardware
+	 * implementation supports it, so select the hardware protocol if
+	 * available for a given bus speed.
+	 * If the bus speed is not configured or set to 0, select 100kHz.
+	 */
+	if (frequency >= 1000000) {
+		speed = ISS_MODE_I2C_H_1000KHZ;
+		frequency = 1000000;
+	} else if (frequency >= 400000) {
+		speed = ISS_MODE_I2C_H_400KHZ;
+		frequency = 400000;
+	} else if (frequency >= 100000 || frequency == 0) {
+		speed = ISS_MODE_I2C_H_100KHZ;
+		frequency = 100000;
+	} else if (frequency >= 50000) {
+		speed = ISS_MODE_I2C_S_50KHZ;
+		frequency = 50000;
+	} else {
+		speed = ISS_MODE_I2C_S_20KHZ;
+		frequency = 20000;
+	}
+
+	dev_info(&dev->interface->dev,
+		 "Devantech USB-ISS at USB bus %03d address %03d speed %d Hz\n",
+		 dev->usb_dev->bus->busnum, dev->usb_dev->devnum, frequency);
+
+	devantech_fw_version(dev);
+	devantech_get_serial(dev);
+
+	return devantech_set_speed(dev, speed);
+}
+
+/* i2c layer */
+
+static int devantech_usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
+			      int num)
+{
+	struct i2c_devantech_iss *dev = i2c_get_adapdata(adapter);
+	struct i2c_msg *pmsg = NULL;
+	int i, j, len, rlen;
+	int ret;
+
+	len = 0;
+	dev->buffer[len++] = ISS_CMD_I2C_DIRECT;
+	dev->buffer[len++] = ISS_I2C_START;
+
+	for (i = 0; i < num; i++) {
+		pmsg = &msgs[i];
+		if (i)
+			dev->buffer[len++] = ISS_I2C_RESTART;
+
+		if (pmsg->flags & I2C_M_RD) {
+			dev->buffer[len++] = ISS_I2C_WRITE(1);
+			dev->buffer[len++] = (pmsg->addr << 1) | 1;
+			if (pmsg->flags & I2C_M_RECV_LEN) {
+				/*
+				 * Block read returns receive length in 1st
+				 * byte. We must read up to 33 bytes of data
+				 * (len + 32) to avoid adapter hangup.
+				 */
+				dev->buffer[len++] = ISS_I2C_READ(16);
+				dev->buffer[len++] = ISS_I2C_READ(16);
+				dev->buffer[len++] = ISS_I2C_NACK;
+				dev->buffer[len++] = ISS_I2C_READ(1);
+			} else {
+				rlen = pmsg->len;
+				/*
+				 * repeat read sequence until done or out of
+				 * buffer
+				 */
+				if (rlen > ISS_MAX_TRANSFER_LEN - 8)
+					rlen = ISS_MAX_TRANSFER_LEN - 8;
+				while (rlen > 16) {
+					dev->buffer[len++] = ISS_I2C_READ(16);
+					rlen -= 16;
+				}
+				if (rlen > 1)
+					dev->buffer[len++]
+					  = ISS_I2C_READ(rlen - 1);
+				dev->buffer[len++] = ISS_I2C_NACK;
+				dev->buffer[len++] = ISS_I2C_READ(1);
+			}
+		} else {
+			dev->buffer[len++] = ISS_I2C_WRITE(1);
+			dev->buffer[len++] = pmsg->addr << 1;
+			/* Repeat write sequence until done */
+			for (rlen = 0; rlen < pmsg->len; rlen += 16) {
+				int clen = min(pmsg->len - rlen, 16);
+				/*
+				 * Make sure we have enough buffer space. We
+				 * need two additional bytes, one for the write
+				 * command itself and one for the STOP command.
+				 */
+				if (len + clen > ISS_MAX_TRANSFER_LEN - 2) {
+					ret = -EINVAL;
+					goto error;
+				}
+				dev->buffer[len++] = ISS_I2C_WRITE(clen);
+				for (j = 0; j < clen; j++)
+					dev->buffer[len++]
+					  = pmsg->buf[rlen + j];
+			}
+		}
+	}
+	dev->buffer[len++] = ISS_I2C_STOP;
+
+	ret = devantech_usb_transfer(dev, len);
+	if (ret < 0)
+		goto error;
+
+	if (ret < 2) {
+		ret = -EIO;
+		goto error;
+	}
+
+	if (dev->buffer[0] == ISS_RESP_NACK) {
+		ret = dev->buffer[1] == ISS_RESP_DEV_ERROR ? -ENXIO : -EIO;
+		goto error;
+	}
+
+	/*
+	 * Copy received data back into receive buffer. pmsg points to it.
+	 */
+	if (pmsg->flags & I2C_M_RD) {
+		if (pmsg->flags & I2C_M_RECV_LEN) {
+			rlen = dev->buffer[2];
+			if (rlen == 0 || rlen > I2C_SMBUS_BLOCK_MAX ||
+			    rlen > ret - 2) {
+				ret = -EPROTO;
+				goto error;
+			}
+			pmsg->len += rlen;
+			len = pmsg->len;
+		} else {
+			len = ret - 2;
+		}
+		for (i = 0; i < len; i++)
+			pmsg->buf[i] = dev->buffer[i + 2];
+	}
+	ret = 0;
+error:
+	return ret;
+}
+
+/*
+ * Return list of supported functionality.
+ */
+static u32 devantech_usb_func(struct i2c_adapter *a)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
+	       I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_FUNC_SMBUS_BLOCK_PROC_CALL;
+}
+
+static const struct i2c_algorithm devantech_usb_algorithm = {
+	.master_xfer = devantech_usb_xfer,
+	.functionality = devantech_usb_func,
+};
+
+/* device layer */
+
+static const struct usb_device_id devantech_iss_table[] = {
+	{ USB_DEVICE(USB_VENDOR_ID_DEVANTECH, USB_DEVICE_ID_ISS) },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(usb, devantech_iss_table);
+
+static void devantech_iss_free(struct i2c_devantech_iss *dev)
+{
+	usb_put_dev(dev->usb_dev);
+	kfree(dev);
+}
+
+static int devantech_iss_probe(struct usb_interface *interface,
+			       const struct usb_device_id *id)
+{
+	struct i2c_devantech_iss *dev;
+	int ret;
+	struct usb_interface *usb_if;
+	struct usb_host_endpoint *ep_out, *ep_in;
+
+	/* allocate memory for our device state and initialize it */
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (dev == NULL) {
+		dev_err(&interface->dev, "no memory for device state\n");
+		ret = -ENOMEM;
+		goto error;
+	}
+
+	dev->usb_dev = usb_get_dev(interface_to_usbdev(interface));
+	dev->interface = interface;
+
+	/* setup i2c adapter description */
+	dev->adapter.owner = THIS_MODULE;
+	dev->adapter.class = I2C_CLASS_HWMON;
+	dev->adapter.algo = &devantech_usb_algorithm;
+	i2c_set_adapdata(&dev->adapter, dev);
+
+	snprintf(dev->adapter.name, sizeof(dev->adapter.name),
+		 DRIVER_NAME " at bus %03d device %03d",
+		 dev->usb_dev->bus->busnum, dev->usb_dev->devnum);
+
+	dev->adapter.dev.parent = &dev->interface->dev;
+
+	/* Only accept probe on control interface */
+	usb_if = usb_ifnum_to_if(dev->usb_dev, 0);
+	if (usb_if != interface) {
+		dev_err(&interface->dev, "not on control interface\n");
+		ret = -ENODEV;
+		goto error_free;
+	}
+
+	usb_if = usb_ifnum_to_if(dev->usb_dev, 1);
+	if (!usb_if) {
+		dev_err(&interface->dev, "no USB interface\n");
+		ret = -ENODEV;
+		goto error_free;
+	}
+	if (usb_interface_claimed(usb_if)) {
+		dev_err(&interface->dev, "USB interface busy\n");
+		ret = -EBUSY;
+		goto error_free;
+	}
+	if (usb_if->cur_altsetting->desc.bNumEndpoints < 2) {
+		dev_err(&interface->dev,
+			"insufficient number of USB endpoints\n");
+		ret = -EINVAL;
+		goto error_free;
+	}
+
+	ep_out = &usb_if->cur_altsetting->endpoint[0];
+	ep_in = &usb_if->cur_altsetting->endpoint[1];
+	if (!ep_out || !ep_in) {
+		dev_err(&interface->dev, "missing USB endpoints\n");
+		ret = -EINVAL;
+		goto error_free;
+	}
+	dev->ep_out = ep_out->desc.bEndpointAddress;
+	dev->ep_in = ep_in->desc.bEndpointAddress;
+	dev->usb_if = usb_get_intf(usb_if);
+
+	/*
+	 * We need to claim the data interface to prevent other drivers
+	 * from accessing and registering it.
+	 */
+	ret = usb_driver_claim_interface(&devantech_iss_driver,
+					 dev->usb_if, dev);
+	if (ret < 0) {
+		dev_err(&usb_if->dev, "failed to claim interface\n");
+		goto error_put;
+	}
+
+	/* save our data pointer in this interface device */
+	usb_set_intfdata(interface, dev);
+
+	/* initialize devantech i2c interface */
+	ret = devantech_init(dev);
+	if (ret < 0) {
+		dev_err(&interface->dev, "failed to initialize adapter\n");
+		goto error_release;
+	}
+
+	/* and finally attach to i2c layer */
+	ret = i2c_add_adapter(&dev->adapter);
+	if (ret < 0) {
+		dev_err(&interface->dev, "failed to add I2C adapter\n");
+		goto error_release;
+	}
+
+	dev_info(&interface->dev, "connected\n");
+	return 0;
+
+error_release:
+	usb_set_intfdata(interface, NULL);
+	usb_set_intfdata(dev->usb_if, NULL);
+	usb_driver_release_interface(&devantech_iss_driver, dev->usb_if);
+error_put:
+	usb_put_intf(dev->usb_if);
+error_free:
+	devantech_iss_free(dev);
+error:
+	return ret;
+}
+
+static void devantech_iss_disconnect(struct usb_interface *interface)
+{
+	struct i2c_devantech_iss *dev = usb_get_intfdata(interface);
+	struct usb_host_interface *alt = interface->cur_altsetting;
+
+	if (alt->desc.bInterfaceNumber)
+		return;
+
+	i2c_del_adapter(&dev->adapter);
+	usb_set_intfdata(interface, NULL);
+	usb_set_intfdata(dev->usb_if, NULL);
+	usb_driver_release_interface(&devantech_iss_driver, dev->usb_if);
+	usb_put_intf(dev->usb_if);
+	devantech_iss_free(dev);
+
+	dev_info(&interface->dev, "disconnected\n");
+}
+
+static struct usb_driver devantech_iss_driver = {
+	.name = DRIVER_NAME,
+	.probe = devantech_iss_probe,
+	.disconnect = devantech_iss_disconnect,
+	.id_table = devantech_iss_table,
+};
+
+static int __init devantech_iss_init(void)
+{
+	/* register this driver with the USB subsystem */
+	return usb_register(&devantech_iss_driver);
+}
+
+static void __exit devantech_iss_exit(void)
+{
+	/* deregister this driver with the USB subsystem */
+	usb_deregister(&devantech_iss_driver);
+}
+
+module_init(devantech_iss_init);
+module_exit(devantech_iss_exit);
+
+MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>");
+MODULE_DESCRIPTION(DRIVER_NAME " driver");
+MODULE_LICENSE("GPL");
-- 
1.7.3.1


             reply	other threads:[~2011-03-23  3:43 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-23  3:43 Guenter Roeck [this message]
     [not found] ` <1300851827-13627-1-git-send-email-guenter.roeck-IzeFyvvaP7pWk0Htik3J/w@public.gmane.org>
2011-03-23  3:45   ` [PATCH] i2c/busses: Driver for Devantech USB-ISS I2C adapter Greg KH
     [not found]     ` <20110323034524.GA11675-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
2011-03-23  4:25       ` Guenter Roeck
2011-03-23  4:50         ` Greg KH
     [not found]           ` <20110323045058.GA13606-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
2011-03-23  5:41             ` Bernhard Walle
2011-03-23  6:07               ` Guenter Roeck
     [not found]                 ` <20110323060746.GA9673-IzeFyvvaP7pWk0Htik3J/w@public.gmane.org>
2011-03-23 15:00                   ` Greg KH
     [not found]                     ` <20110323150014.GB6284-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
2011-03-23 15:10                       ` Alan Cox
     [not found]                         ` <20110323151021.53e187bb-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org>
2011-03-23 15:31                           ` Greg KH
2011-03-23 15:42                             ` Mark Brown
2011-03-24  4:31                             ` Guenter Roeck
     [not found]                               ` <20110324043157.GD15395-IzeFyvvaP7pWk0Htik3J/w@public.gmane.org>
2011-03-24 16:41                                 ` Greg KH
2011-03-23  7:17               ` Oliver Neukum
2011-03-23  9:28   ` Alan Cox
     [not found]     ` <20110323092829.25d42e27-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org>
2011-03-23 13:46       ` Guenter Roeck
     [not found]         ` <20110323134650.GA11492-IzeFyvvaP7pWk0Htik3J/w@public.gmane.org>
2011-03-23 13:52           ` Alan Cox
     [not found]             ` <20110323135244.202cc9bd-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org>
2011-03-23 13:57               ` Guenter Roeck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1300851827-13627-1-git-send-email-guenter.roeck@ericsson.com \
    --to=guenter.roeck@ericsson.com \
    --cc=ben-linux@fluff.org \
    --cc=khali@linux-fr.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=rdunlap@xenotime.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).