LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH3/7] i2c: OF helpers for the i2c API
From: Jochen Friedrich @ 2008-04-11 14:09 UTC (permalink / raw)
  To: Kumar Gala
  Cc: linuxppc-dev list, Kernel, Linux, Scott Wood, Jean Delvare,
	Linux I2C

This patch implements various helpers to support OF bindings for
the i2c API.

Signed-off-by: Jochen Friedrich <jochen@scram.de>
---
 drivers/of/Kconfig     |    6 +++
 drivers/of/Makefile    |    1 +
 drivers/of/i2c.c       |  115 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of_i2c.h |   24 ++++++++++
 4 files changed, 146 insertions(+), 0 deletions(-)
 create mode 100644 drivers/of/i2c.c
 create mode 100644 include/linux/of_i2c.h

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index c03072b..3cff449 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -1,3 +1,9 @@
 config OF_DEVICE
 	def_bool y
 	depends on OF && (SPARC || PPC_OF)
+
+config OF_I2C
+	def_bool y
+	depends on OF && PPC_OF && I2C
+	help
+	  OpenFirmware I2C accessors
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index ab9be5d..655b982 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -1,2 +1,3 @@
 obj-y = base.o
 obj-$(CONFIG_OF_DEVICE) += device.o platform.o
+obj-$(CONFIG_OF_I2C)	+= i2c.o
diff --git a/drivers/of/i2c.c b/drivers/of/i2c.c
new file mode 100644
index 0000000..6316891
--- /dev/null
+++ b/drivers/of/i2c.c
@@ -0,0 +1,115 @@
+/*
+ * OF helpers for the I2C API
+ *
+ * Copyright (c) 2008 Jochen Friedrich <jochen@scram.de>
+ *
+ * Based on a previous patch from Jon Smirl <jonsmirl@gmail.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 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/i2c.h>
+#include <linux/of.h>
+
+struct i2c_driver_device {
+	char    *of_device;
+	char    *i2c_type;
+};
+
+static struct i2c_driver_device i2c_devices[] = {
+	{ "dallas,ds1374", "rtc-ds1374" },
+};
+
+static int of_find_i2c_driver(struct device_node *node,
+			      struct i2c_board_info *info)
+{
+	int i, cplen;
+	const char *compatible;
+	const char *p;
+
+	/* 1. search for exception list entry */
+	for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) {
+		if (!of_device_is_compatible(node, i2c_devices[i].of_device))
+			continue;
+		if (strlcpy(info->type, i2c_devices[i].i2c_type,
+			    I2C_NAME_SIZE) >= I2C_NAME_SIZE)
+			return -ENOMEM;
+
+		return 0;
+	}
+
+	compatible = of_get_property(node, "compatible", &cplen);
+	if (!compatible)
+		return -ENODEV;
+
+	/* 2. search for linux,<i2c-type> entry */
+	p = compatible;
+	while (cplen > 0) {
+		if (!strncmp(p, "linux,", 6)) {
+			p += 6;
+			if (strlcpy(info->type, p,
+				    I2C_NAME_SIZE) >= I2C_NAME_SIZE)
+				return -ENOMEM;
+			return 0;
+		}
+
+		i = strlen(p) + 1;
+		p += i;
+		cplen -= i;
+	}
+
+	/* 3. take fist compatible entry and strip manufacturer */
+	p = strchr(compatible, ',');
+	if (!p)
+		return -ENODEV;
+	p++;
+	if (strlcpy(info->type, p, I2C_NAME_SIZE) >= I2C_NAME_SIZE)
+		return -ENOMEM;
+	return 0;
+}
+
+void of_register_i2c_devices(struct i2c_adapter *adap,
+			     struct device_node *adap_node)
+{
+	void *result;
+	struct device_node *node;
+
+	for_each_child_of_node(adap_node, node) {
+		struct i2c_board_info info = {};
+		const u32 *addr;
+		int len;
+
+		addr = of_get_property(node, "reg", &len);
+		if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) {
+			printk(KERN_ERR
+			       "of-i2c: invalid i2c device entry\n");
+			continue;
+		}
+
+		info.irq = irq_of_parse_and_map(node, 0);
+		if (info.irq == NO_IRQ)
+			info.irq = -1;
+
+		if (of_find_i2c_driver(node, &info) < 0) {
+			irq_dispose_mapping(info.irq);
+			continue;
+		}
+
+		info.addr = *addr;
+
+		request_module(info.type);
+
+		result = i2c_new_device(adap, &info);
+		if (result == NULL) {
+			printk(KERN_ERR
+			       "of-i2c: Failed to load driver for %s\n",
+			       info.type);
+			irq_dispose_mapping(info.irq);
+			continue;
+		}
+	}
+}
+EXPORT_SYMBOL(of_register_i2c_devices);
diff --git a/include/linux/of_i2c.h b/include/linux/of_i2c.h
new file mode 100644
index 0000000..2e5a967
--- /dev/null
+++ b/include/linux/of_i2c.h
@@ -0,0 +1,24 @@
+/*
+ * Generic I2C API implementation for PowerPC.
+ *
+ * Copyright (c) 2008 Jochen Friedrich <jochen@scram.de>
+ *
+ * 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, or
+ * (at your option) any later version.
+ */
+
+#ifndef __LINUX_OF_I2C_H
+#define __LINUX_OF_I2C_H
+
+#include <linux/i2c.h>
+
+#ifdef CONFIG_OF_I2C
+
+void of_register_i2c_devices(struct i2c_adapter *adap,
+			     struct device_node *adap_node);
+
+#endif /* CONFIG_OF_I2C */
+
+#endif /* __LINUX_OF_I2C_H */
-- 
1.5.4.5

^ permalink raw reply related

* [PATCH2/7] i2c: Convert all new-style drivers to use module aliasing
From: Jochen Friedrich @ 2008-04-11 14:08 UTC (permalink / raw)
  To: Kumar Gala
  Cc: linuxppc-dev list, Kernel, Linux, Scott Wood, Jean Delvare,
	Linux I2C

Based on earlier work by Jon Smirl and Jean Delvare.

Update all the new-style i2c drivers to use standard module aliasing
instead of the old driver_name/type driver matching scheme.

Signed-off-by: Jochen Friedrich <jochen@scram.de>
Cc: Jean Delvare <khali@linux-fr.org>
Cc: Jon Smirl <jonsmirl@gmail.com>
---
 arch/arm/mach-at91/board-csb337.c          |    3 +-
 arch/arm/mach-at91/board-dk.c              |    3 +-
 arch/arm/mach-at91/board-eb9200.c          |    3 +-
 arch/arm/mach-iop32x/em7210.c              |    3 +-
 arch/arm/mach-iop32x/n2100.c               |    4 +-
 arch/arm/mach-omap1/board-h2.c             |    2 -
 arch/arm/mach-omap1/board-h3.c             |    3 +-
 arch/arm/mach-omap1/board-osk.c            |    1 -
 arch/powerpc/sysdev/fsl_soc.c              |   27 ++++-----
 drivers/hwmon/f75375s.c                    |   12 ++++
 drivers/i2c/busses/i2c-taos-evm.c          |    3 +-
 drivers/i2c/chips/ds1682.c                 |    7 +++
 drivers/i2c/chips/menelaus.c               |    7 +++
 drivers/i2c/chips/tps65010.c               |   28 ++++------
 drivers/i2c/chips/tsl2550.c                |    7 +++
 drivers/media/video/cs5345.c               |    7 +++
 drivers/media/video/cs53l32a.c             |    7 +++
 drivers/media/video/cx25840/cx25840-core.c |    7 +++
 drivers/media/video/m52790.c               |    7 +++
 drivers/media/video/msp3400-driver.c       |    7 +++
 drivers/media/video/saa7115.c              |    7 +++
 drivers/media/video/saa7127.c              |   10 ++++
 drivers/media/video/tlv320aic23b.c         |    6 ++
 drivers/media/video/tuner-core.c           |   22 ++++++++
 drivers/media/video/tvaudio.c              |   13 +++++
 drivers/media/video/upd64031a.c            |    6 ++
 drivers/media/video/upd64083.c             |    6 ++
 drivers/media/video/vp27smpx.c             |    7 +++
 drivers/media/video/wm8739.c               |    7 +++
 drivers/media/video/wm8775.c               |    7 +++
 drivers/rtc/rtc-ds1307.c                   |   36 +++++--------
 drivers/rtc/rtc-ds1374.c                   |    7 +++
 drivers/rtc/rtc-m41t80.c                   |   78 +++++++---------------------
 drivers/rtc/rtc-rs5c372.c                  |   14 +++++-
 drivers/rtc/rtc-s35390a.c                  |    7 +++
 include/linux/i2c.h                        |   12 ++--
 include/media/v4l2-i2c-drv-legacy.h        |    2 +
 include/media/v4l2-i2c-drv.h               |    2 +
 38 files changed, 257 insertions(+), 140 deletions(-)

diff --git a/arch/arm/mach-at91/board-csb337.c b/arch/arm/mach-at91/board-csb337.c
index 0e2a11f..63e4cb6 100644
--- a/arch/arm/mach-at91/board-csb337.c
+++ b/arch/arm/mach-at91/board-csb337.c
@@ -87,8 +87,7 @@ static struct at91_udc_data __initdata csb337_udc_data = {
 
 static struct i2c_board_info __initdata csb337_i2c_devices[] = {
 	{
-		I2C_BOARD_INFO("rtc-ds1307", 0x68),
-		.type	= "ds1307",
+		I2C_BOARD_INFO("ds1307", 0x68),
 	},
 };
 
diff --git a/arch/arm/mach-at91/board-dk.c b/arch/arm/mach-at91/board-dk.c
index 0a897ef..c1a813c 100644
--- a/arch/arm/mach-at91/board-dk.c
+++ b/arch/arm/mach-at91/board-dk.c
@@ -132,8 +132,7 @@ static struct i2c_board_info __initdata dk_i2c_devices[] = {
 		I2C_BOARD_INFO("x9429", 0x28),
 	},
 	{
-		I2C_BOARD_INFO("at24c", 0x50),
-		.type	= "24c1024",
+		I2C_BOARD_INFO("24c1024", 0x50),
 	}
 };
 
diff --git a/arch/arm/mach-at91/board-eb9200.c b/arch/arm/mach-at91/board-eb9200.c
index b7b79bb..af1a1d8 100644
--- a/arch/arm/mach-at91/board-eb9200.c
+++ b/arch/arm/mach-at91/board-eb9200.c
@@ -93,8 +93,7 @@ static struct at91_mmc_data __initdata eb9200_mmc_data = {
 
 static struct i2c_board_info __initdata eb9200_i2c_devices[] = {
 	{
-		I2C_BOARD_INFO("at24c", 0x50),
-		.type	= "24c512",
+		I2C_BOARD_INFO("24c512", 0x50),
 	},
 };
 
diff --git a/arch/arm/mach-iop32x/em7210.c b/arch/arm/mach-iop32x/em7210.c
index c947152..4877597 100644
--- a/arch/arm/mach-iop32x/em7210.c
+++ b/arch/arm/mach-iop32x/em7210.c
@@ -50,8 +50,7 @@ static struct sys_timer em7210_timer = {
  */
 static struct i2c_board_info __initdata em7210_i2c_devices[] = {
 	{
-		I2C_BOARD_INFO("rtc-rs5c372", 0x32),
-		.type = "rs5c372a",
+		I2C_BOARD_INFO("rs5c372a", 0x32),
 	},
 };
 
diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c
index bc91d6e..2741063 100644
--- a/arch/arm/mach-iop32x/n2100.c
+++ b/arch/arm/mach-iop32x/n2100.c
@@ -208,12 +208,10 @@ static struct f75375s_platform_data n2100_f75375s = {
 
 static struct i2c_board_info __initdata n2100_i2c_devices[] = {
 	{
-		I2C_BOARD_INFO("rtc-rs5c372", 0x32),
-		.type = "rs5c372b",
+		I2C_BOARD_INFO("rs5c372b", 0x32),
 	},
 	{
 		I2C_BOARD_INFO("f75375", 0x2e),
-		.type = "f75375",
 		.platform_data = &n2100_f75375s,
 	},
 };
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index 5079877..4b444fd 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -351,11 +351,9 @@ static void __init h2_init_smc91x(void)
 static struct i2c_board_info __initdata h2_i2c_board_info[] = {
 	{
 		I2C_BOARD_INFO("tps65010", 0x48),
-		.type           = "tps65010",
 		.irq            = OMAP_GPIO_IRQ(58),
 	}, {
 		I2C_BOARD_INFO("isp1301_omap", 0x2d),
-		.type		= "isp1301_omap",
 		.irq		= OMAP_GPIO_IRQ(2),
 	},
 };
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index c3ef1ee..7fbaa8d 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -473,8 +473,7 @@ static struct omap_board_config_kernel h3_config[] __initdata = {
 
 static struct i2c_board_info __initdata h3_i2c_board_info[] = {
        {
-               I2C_BOARD_INFO("tps65010", 0x48),
-               .type           = "tps65013",
+		I2C_BOARD_INFO("tps65013", 0x48),
                /* .irq         = OMAP_GPIO_IRQ(??), */
        },
 };
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index 5279e35..70c77e5 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -186,7 +186,6 @@ static struct platform_device *osk5912_devices[] __initdata = {
 static struct i2c_board_info __initdata osk_i2c_board_info[] = {
 	{
 		I2C_BOARD_INFO("tps65010", 0x48),
-		.type		= "tps65010",
 		.irq		= OMAP_GPIO_IRQ(OMAP_MPUIO(1)),
 	},
 	/* TODO when driver support is ready:
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 2c5388c..2cd4ef9 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -390,22 +390,21 @@ arch_initcall(gfar_of_init);
 #include <linux/i2c.h>
 struct i2c_driver_device {
 	char	*of_device;
-	char	*i2c_driver;
 	char	*i2c_type;
 };
 
 static struct i2c_driver_device i2c_devices[] __initdata = {
-	{"ricoh,rs5c372a", "rtc-rs5c372", "rs5c372a",},
-	{"ricoh,rs5c372b", "rtc-rs5c372", "rs5c372b",},
-	{"ricoh,rv5c386",  "rtc-rs5c372", "rv5c386",},
-	{"ricoh,rv5c387a", "rtc-rs5c372", "rv5c387a",},
-	{"dallas,ds1307",  "rtc-ds1307",  "ds1307",},
-	{"dallas,ds1337",  "rtc-ds1307",  "ds1337",},
-	{"dallas,ds1338",  "rtc-ds1307",  "ds1338",},
-	{"dallas,ds1339",  "rtc-ds1307",  "ds1339",},
-	{"dallas,ds1340",  "rtc-ds1307",  "ds1340",},
-	{"stm,m41t00",     "rtc-ds1307",  "m41t00"},
-	{"dallas,ds1374",  "rtc-ds1374",  "rtc-ds1374",},
+	{"ricoh,rs5c372a", "rs5c372a",},
+	{"ricoh,rs5c372b", "rs5c372b",},
+	{"ricoh,rv5c386",  "rv5c386",},
+	{"ricoh,rv5c387a", "rv5c387a",},
+	{"dallas,ds1307",  "ds1307",},
+	{"dallas,ds1337",  "ds1337",},
+	{"dallas,ds1338",  "ds1338",},
+	{"dallas,ds1339",  "ds1339",},
+	{"dallas,ds1340",  "ds1340",},
+	{"stm,m41t00",     "m41t00"},
+	{"dallas,ds1374",  "rtc-ds1374",},
 };
 
 static int __init of_find_i2c_driver(struct device_node *node,
@@ -416,9 +415,7 @@ static int __init of_find_i2c_driver(struct device_node *node,
 	for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) {
 		if (!of_device_is_compatible(node, i2c_devices[i].of_device))
 			continue;
-		if (strlcpy(info->driver_name, i2c_devices[i].i2c_driver,
-			    KOBJ_NAME_LEN) >= KOBJ_NAME_LEN ||
-		    strlcpy(info->type, i2c_devices[i].i2c_type,
+		if (strlcpy(info->type, i2c_devices[i].i2c_type,
 			    I2C_NAME_SIZE) >= I2C_NAME_SIZE)
 			return -ENOMEM;
 		return 0;
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index 3ec9123..1fabcae 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -129,12 +129,20 @@ static struct i2c_driver f75375_legacy_driver = {
 	.detach_client = f75375_detach_client,
 };
 
+static const struct i2c_device_id f75375_id[] = {
+	{ "f75373", f75373 },
+	{ "f75375", f75375 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, f75375_id);
+
 static struct i2c_driver f75375_driver = {
 	.driver = {
 		.name = "f75375",
 	},
 	.probe = f75375_probe,
 	.remove = f75375_remove,
+	.id_table = f75375_id,
 };
 
 static inline int f75375_read8(struct i2c_client *client, u8 reg)
@@ -716,6 +724,7 @@ static int f75375_detect(struct i2c_adapter *adapter, int address, int kind)
 	u8 version = 0;
 	int err = 0;
 	const char *name = "";
+	struct i2c_device_id id;
 
 	client = kzalloc(sizeof(*client), GFP_KERNEL);
 	if (!client) {
@@ -754,6 +763,9 @@ static int f75375_detect(struct i2c_adapter *adapter, int address, int kind)
 	if (err)
 		goto exit_free;
 
+	strlcpy(id.name, name, I2C_NAME_SIZE);
+	id.driver_data = kind;
+
 	err = f75375_probe(client, NULL);
 	if (err < 0)
 		goto exit_detach;
diff --git a/drivers/i2c/busses/i2c-taos-evm.c b/drivers/i2c/busses/i2c-taos-evm.c
index 1b0cfd5..de9db49 100644
--- a/drivers/i2c/busses/i2c-taos-evm.c
+++ b/drivers/i2c/busses/i2c-taos-evm.c
@@ -51,7 +51,6 @@ struct taos_data {
 /* TAOS TSL2550 EVM */
 static struct i2c_board_info tsl2550_info = {
 	I2C_BOARD_INFO("tsl2550", 0x39),
-	.type	= "tsl2550",
 };
 
 /* Instantiate i2c devices based on the adapter name */
@@ -59,7 +58,7 @@ static struct i2c_client *taos_instantiate_device(struct i2c_adapter *adapter)
 {
 	if (!strncmp(adapter->name, "TAOS TSL2550 EVM", 16)) {
 		dev_info(&adapter->dev, "Instantiating device %s at 0x%02x\n",
-			tsl2550_info.driver_name, tsl2550_info.addr);
+			tsl2550_info.type, tsl2550_info.addr);
 		return i2c_new_device(adapter, &tsl2550_info);
 	}
 
diff --git a/drivers/i2c/chips/ds1682.c b/drivers/i2c/chips/ds1682.c
index 3070821..51ff518 100644
--- a/drivers/i2c/chips/ds1682.c
+++ b/drivers/i2c/chips/ds1682.c
@@ -235,12 +235,19 @@ static int ds1682_remove(struct i2c_client *client)
 	return 0;
 }
 
+static const struct i2c_device_id ds1682_id[] = {
+	{ "ds1682", 0 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, ds1682_id);
+
 static struct i2c_driver ds1682_driver = {
 	.driver = {
 		.name = "ds1682",
 	},
 	.probe = ds1682_probe,
 	.remove = ds1682_remove,
+	.id_table = ds1682_id,
 };
 
 static int __init ds1682_init(void)
diff --git a/drivers/i2c/chips/menelaus.c b/drivers/i2c/chips/menelaus.c
index 3b8ba7e..1f9ac5e 100644
--- a/drivers/i2c/chips/menelaus.c
+++ b/drivers/i2c/chips/menelaus.c
@@ -1243,12 +1243,19 @@ static int __exit menelaus_remove(struct i2c_client *client)
 	return 0;
 }
 
+static const struct i2c_device_id menelaus_id[] = {
+	{ "menelaus", 0 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, menelaus_id);
+
 static struct i2c_driver menelaus_i2c_driver = {
 	.driver = {
 		.name		= DRIVER_NAME,
 	},
 	.probe		= menelaus_probe,
 	.remove		= __exit_p(menelaus_remove),
+	.id_table	= menelaus_id,
 };
 
 static int __init menelaus_init(void)
diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c
index 3ce43f8..e07274d 100644
--- a/drivers/i2c/chips/tps65010.c
+++ b/drivers/i2c/chips/tps65010.c
@@ -60,7 +60,6 @@ static struct i2c_driver tps65010_driver;
  * as part of board setup by a bootloader.
  */
 enum tps_model {
-	TPS_UNKNOWN = 0,
 	TPS65010,
 	TPS65011,
 	TPS65012,
@@ -487,20 +486,6 @@ static int tps65010_probe(struct i2c_client *client,
 	INIT_DELAYED_WORK(&tps->work, tps65010_work);
 	tps->client = client;
 
-	if (strcmp(client->name, "tps65010") == 0)
-		tps->model = TPS65010;
-	else if (strcmp(client->name, "tps65011") == 0)
-		tps->model = TPS65011;
-	else if (strcmp(client->name, "tps65012") == 0)
-		tps->model = TPS65012;
-	else if (strcmp(client->name, "tps65013") == 0)
-		tps->model = TPS65013;
-	else {
-		dev_warn(&client->dev, "unknown chip '%s'\n", client->name);
-		status = -ENODEV;
-		goto fail1;
-	}
-
 	/* the IRQ is active low, but many gpio lines can't support that
 	 * so this driver uses falling-edge triggers instead.
 	 */
@@ -528,9 +513,6 @@ static int tps65010_probe(struct i2c_client *client,
 	case TPS65012:
 		tps->por = 1;
 		break;
-	case TPS_UNKNOWN:
-		printk(KERN_WARNING "%s: unknown TPS chip\n", DRIVER_NAME);
-		break;
 	/* else CHGCONFIG.POR is replaced by AUA, enabling a WAIT mode */
 	}
 	tps->chgconf = i2c_smbus_read_byte_data(client, TPS_CHGCONFIG);
@@ -584,12 +566,22 @@ fail1:
 	return status;
 }
 
+static const struct i2c_device_id tps65010_id[] = {
+	{ "tps65010", TPS65010 },
+	{ "tps65011", TPS65011 },
+	{ "tps65012", TPS65012 },
+	{ "tps65013", TPS65013 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, tps65010_id);
+
 static struct i2c_driver tps65010_driver = {
 	.driver = {
 		.name	= "tps65010",
 	},
 	.probe	= tps65010_probe,
 	.remove	= __exit_p(tps65010_remove),
+	.id_table = tps65010_id,
 };
 
 /*-------------------------------------------------------------------------*/
diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/i2c/chips/tsl2550.c
index 59c2c66..2add8be 100644
--- a/drivers/i2c/chips/tsl2550.c
+++ b/drivers/i2c/chips/tsl2550.c
@@ -452,6 +452,12 @@ static int tsl2550_resume(struct i2c_client *client)
 
 #endif /* CONFIG_PM */
 
+static const struct i2c_device_id tsl2550_id[] = {
+	{ "tsl2550", 0 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, tsl2550_id);
+
 static struct i2c_driver tsl2550_driver = {
 	.driver = {
 		.name	= TSL2550_DRV_NAME,
@@ -461,6 +467,7 @@ static struct i2c_driver tsl2550_driver = {
 	.resume	= tsl2550_resume,
 	.probe	= tsl2550_probe,
 	.remove	= __devexit_p(tsl2550_remove),
+	.id_table = tsl2550_id,
 };
 
 static int __init tsl2550_init(void)
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c
index 2a429f9..69aeb3d 100644
--- a/drivers/media/video/cs5345.c
+++ b/drivers/media/video/cs5345.c
@@ -160,9 +160,16 @@ static int cs5345_probe(struct i2c_client *client,
 
 /* ----------------------------------------------------------------------- */
 
+static const struct i2c_device_id cs5345_id[] = {
+	{ "cs5345", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, cs5345_id);
+
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "cs5345",
 	.driverid = I2C_DRIVERID_CS5345,
+	.id_table = cs5345_id,
 	.command = cs5345_command,
 	.probe = cs5345_probe,
 };
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
index 2dfd0af..f3749fb 100644
--- a/drivers/media/video/cs53l32a.c
+++ b/drivers/media/video/cs53l32a.c
@@ -175,9 +175,16 @@ static int cs53l32a_probe(struct i2c_client *client,
 	return 0;
 }
 
+static const struct i2c_device_id cs53l32a_id[] = {
+	{ "cs53l32a", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, cs53l32a_id);
+
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "cs53l32a",
 	.driverid = I2C_DRIVERID_CS53L32A,
+	.id_table = cs53l32a_id,
 	.command = cs53l32a_command,
 	.probe = cs53l32a_probe,
 };
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 6f16186..7df9dc1 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -1301,9 +1301,16 @@ static int cx25840_remove(struct i2c_client *client)
 	return 0;
 }
 
+static const struct i2c_device_id cx25840_id[] = {
+	{ "cx25840", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, cx25840_id);
+
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "cx25840",
 	.driverid = I2C_DRIVERID_CX25840,
+	.id_table = cx25840_id,
 	.command = cx25840_command,
 	.probe = cx25840_probe,
 	.remove = cx25840_remove,
diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c
index 5b9dfa2..acf9075 100644
--- a/drivers/media/video/m52790.c
+++ b/drivers/media/video/m52790.c
@@ -159,9 +159,16 @@ static int m52790_remove(struct i2c_client *client)
 
 /* ----------------------------------------------------------------------- */
 
+static const struct i2c_device_id m52790_id[] = {
+	{ "m52790", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, m52790_id);
+
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "m52790",
 	.driverid = I2C_DRIVERID_M52790,
+	.id_table = m52790_id,
 	.command = m52790_command,
 	.probe = m52790_probe,
 	.remove = m52790_remove,
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index 3f97737..1e5f256 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -988,9 +988,16 @@ static int msp_remove(struct i2c_client *client)
 
 /* ----------------------------------------------------------------------- */
 
+static const struct i2c_device_id msp_id[] = {
+	{ "msp3400", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, msp_id);
+
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "msp3400",
 	.driverid = I2C_DRIVERID_MSP3400,
+	.id_table = msp_id,
 	.command = msp_command,
 	.probe = msp_probe,
 	.remove = msp_remove,
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 7882e29..ea9a9c4 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -1553,9 +1553,16 @@ static int saa7115_remove(struct i2c_client *client)
 	return 0;
 }
 
+static const struct i2c_device_id saa7115_id[] = {
+	{ "saa7115", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, saa7115_id);
+
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "saa7115",
 	.driverid = I2C_DRIVERID_SAA711X,
+	.id_table = saa7115_id,
 	.command = saa7115_command,
 	.probe = saa7115_probe,
 	.remove = saa7115_remove,
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index e750cd6..9520041 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -741,8 +741,18 @@ static int saa7127_remove(struct i2c_client *client)
 
 /* ----------------------------------------------------------------------- */
 
+static struct i2c_device_id saa7127_id[] = {
+	{ "saa7126", 0 },
+	{ "saa7127", 0 },
+	{ "saa7128", 0 },
+	{ "saa7129", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, saa7127_id);
+
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "saa7127",
+	.id_table = saa7127_id,
 	.driverid = I2C_DRIVERID_SAA7127,
 	.command = saa7127_command,
 	.probe = saa7127_probe,
diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c
index f1db542..87e538f 100644
--- a/drivers/media/video/tlv320aic23b.c
+++ b/drivers/media/video/tlv320aic23b.c
@@ -168,10 +168,16 @@ static int tlv320aic23b_remove(struct i2c_client *client)
 
 /* ----------------------------------------------------------------------- */
 
+static const struct i2c_device_id tlv320aic23b_id[] = {
+	{ "tlv320aic23b", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, tlv320aic23b_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "tlv320aic23b",
 	.driverid = I2C_DRIVERID_TLV320AIC23B,
+	.id_table = tlv320aic23b_id,
 	.command = tlv320aic23b_command,
 	.probe = tlv320aic23b_probe,
 	.remove = tlv320aic23b_remove,
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index edd451e..205c9d0 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -1247,9 +1247,31 @@ static int tuner_remove(struct i2c_client *client)
 
 /* ----------------------------------------------------------------------- */
 
+static const struct i2c_device_id tuner_id[] = {
+	{ "dtt761x", 0 },
+	{ "fcv1236", 0 },
+	{ "fi1216mk", 0 },
+	{ "fm1216me", 0 },
+	{ "fm1236", 0 },
+	{ "fm1256", 0 },
+	{ "fmd1216me", 0 },
+	{ "h06xf", 0 },
+	{ "j180at", 0 },
+	{ "mt4042fi5", 0 },
+	{ "mt4049fm5", 0 },
+	{ "tlc2002n", 0 },
+	{ "tnf8831", 0 },
+	{ "tnf9533", 0 },
+	{ "tvf5533mf", 0 },
+	{ "vp27s", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, tuner_id);
+
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "tuner",
 	.driverid = I2C_DRIVERID_TUNER,
+	.id_table = tuner_id,
 	.command = tuner_command,
 	.probe = tuner_probe,
 	.remove = tuner_remove,
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 1fa1552..3545daf 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -1831,9 +1831,22 @@ static int chip_legacy_probe(struct i2c_adapter *adap)
 	return 0;
 }
 
+static const struct i2c_device_id chip_id[] = {
+	{ "tda8425", 0 },
+	{ "tea6300", 0 },
+	{ "tea6420", 0 },
+	{ "tda9840", 0 },
+	{ "tda985x", 0 },
+	{ "tda9874", 0 },
+	{ "pic16c54", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, chip_id);
+
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "tvaudio",
 	.driverid = I2C_DRIVERID_TVAUDIO,
+	.id_table = chip_id,
 	.command = chip_command,
 	.probe = chip_probe,
 	.remove = chip_remove,
diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c
index 93bfd19..f69f9b9 100644
--- a/drivers/media/video/upd64031a.c
+++ b/drivers/media/video/upd64031a.c
@@ -228,10 +228,16 @@ static int upd64031a_remove(struct i2c_client *client)
 
 /* ----------------------------------------------------------------------- */
 
+static const struct i2c_device_id upd64031a_id[] = {
+	{ "upd64031a", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, upd64031a_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "upd64031a",
 	.driverid = I2C_DRIVERID_UPD64031A,
+	.id_table = upd64031a_id,
 	.command = upd64031a_command,
 	.probe = upd64031a_probe,
 	.remove = upd64031a_remove,
diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c
index 9ab712a..d39849f 100644
--- a/drivers/media/video/upd64083.c
+++ b/drivers/media/video/upd64083.c
@@ -205,10 +205,16 @@ static int upd64083_remove(struct i2c_client *client)
 
 /* ----------------------------------------------------------------------- */
 
+static const struct i2c_device_id upd64083_id[] = {
+	{ "upd64083", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, upd64083_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "upd64083",
 	.driverid = I2C_DRIVERID_UPD64083,
+	.id_table = upd64083_id,
 	.command = upd64083_command,
 	.probe = upd64083_probe,
 	.remove = upd64083_remove,
diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c
index fac0deb..fc91cfa 100644
--- a/drivers/media/video/vp27smpx.c
+++ b/drivers/media/video/vp27smpx.c
@@ -154,9 +154,16 @@ static int vp27smpx_remove(struct i2c_client *client)
 
 /* ----------------------------------------------------------------------- */
 
+static const struct i2c_device_id vp27smpx_id[] = {
+	{ "vp27smpx", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, vp27smpx_id);
+
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "vp27smpx",
 	.driverid = I2C_DRIVERID_VP27SMPX,
+	.id_table = vp27smpx_id,
 	.command = vp27smpx_command,
 	.probe = vp27smpx_probe,
 	.remove = vp27smpx_remove,
diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c
index 0f8ed84..cf180a5 100644
--- a/drivers/media/video/wm8739.c
+++ b/drivers/media/video/wm8739.c
@@ -313,9 +313,16 @@ static int wm8739_remove(struct i2c_client *client)
 	return 0;
 }
 
+static const struct i2c_device_id wm8739_id[] = {
+	{ "wm8739", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, wm8739_id);
+
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "wm8739",
 	.driverid = I2C_DRIVERID_WM8739,
+	.id_table = wm8739_id,
 	.command = wm8739_command,
 	.probe = wm8739_probe,
 	.remove = wm8739_remove,
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index 67a409e..b1653c5 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -216,9 +216,16 @@ static int wm8775_remove(struct i2c_client *client)
 	return 0;
 }
 
+static const struct i2c_device_id wm8775_id[] = {
+	{ "wm8775", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, wm8775_id);
+
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "wm8775",
 	.driverid = I2C_DRIVERID_WM8775,
+	.id_table = wm8775_id,
 	.command = wm8775_command,
 	.probe = wm8775_probe,
 	.remove = wm8775_remove,
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 67ba8ae..93fdced 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -102,42 +102,36 @@ struct chip_desc {
 	char			name[9];
 	unsigned		nvram56:1;
 	unsigned		alarm:1;
-	enum ds_type		type;
 };
 
 static const struct chip_desc chips[] = { {
 	.name		= "ds1307",
-	.type		= ds_1307,
 	.nvram56	= 1,
 }, {
 	.name		= "ds1337",
-	.type		= ds_1337,
 	.alarm		= 1,
 }, {
 	.name		= "ds1338",
-	.type		= ds_1338,
 	.nvram56	= 1,
 }, {
 	.name		= "ds1339",
-	.type		= ds_1339,
 	.alarm		= 1,
 }, {
 	.name		= "ds1340",
-	.type		= ds_1340,
 }, {
 	.name		= "m41t00",
-	.type		= m41t00,
 }, };
 
-static inline const struct chip_desc *find_chip(const char *s)
-{
-	unsigned i;
-
-	for (i = 0; i < ARRAY_SIZE(chips); i++)
-		if (strnicmp(s, chips[i].name, sizeof chips[i].name) == 0)
-			return &chips[i];
-	return NULL;
-}
+static const struct i2c_device_id ds1307_id[] = {
+	{ "ds1307", ds_1307 },
+	{ "ds1337", ds_1337 },
+	{ "ds1338", ds_1338 },
+	{ "ds1339", ds_1339 },
+	{ "ds1340", ds_1340 },
+	{ "m41t00", m41t00 },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, ds1307_id);
 
 static int ds1307_get_time(struct device *dev, struct rtc_time *t)
 {
@@ -335,12 +329,7 @@ static int __devinit ds1307_probe(struct i2c_client *client,
 	const struct chip_desc	*chip;
 	struct i2c_adapter	*adapter = to_i2c_adapter(client->dev.parent);
 
-	chip = find_chip(client->name);
-	if (!chip) {
-		dev_err(&client->dev, "unknown chip type '%s'\n",
-				client->name);
-		return -ENODEV;
-	}
+	chip = &chips[id->driver_data];
 
 	if (!i2c_check_functionality(adapter,
 			I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
@@ -362,7 +351,7 @@ static int __devinit ds1307_probe(struct i2c_client *client,
 	ds1307->msg[1].len = sizeof(ds1307->regs);
 	ds1307->msg[1].buf = ds1307->regs;
 
-	ds1307->type = chip->type;
+	ds1307->type = id->driver_data;
 
 	switch (ds1307->type) {
 	case ds_1337:
@@ -551,6 +540,7 @@ static struct i2c_driver ds1307_driver = {
 	},
 	.probe		= ds1307_probe,
 	.remove		= __devexit_p(ds1307_remove),
+	.id_table	= ds1307_id,
 };
 
 static int __init ds1307_init(void)
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index 104dcfd..376ceeb 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -41,6 +41,12 @@
 #define DS1374_REG_SR_AF	0x01 /* Alarm Flag */
 #define DS1374_REG_TCR		0x09 /* Trickle Charge */
 
+static const struct i2c_device_id ds1374_id[] = {
+	{ "ds1374", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, ds1374_id);
+
 struct ds1374 {
 	struct i2c_client *client;
 	struct rtc_device *rtc;
@@ -430,6 +436,7 @@ static struct i2c_driver ds1374_driver = {
 	},
 	.probe = ds1374_probe,
 	.remove = __devexit_p(ds1374_remove),
+	.id_table = ds1374_id,
 };
 
 static int __init ds1374_init(void)
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 2ee0d07..c672557 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -60,48 +60,21 @@
 
 #define DRV_VERSION "0.05"
 
-struct m41t80_chip_info {
-	const char *name;
-	u8 features;
-};
-
-static const struct m41t80_chip_info m41t80_chip_info_tbl[] = {
-	{
-		.name		= "m41t80",
-		.features	= 0,
-	},
-	{
-		.name		= "m41t81",
-		.features	= M41T80_FEATURE_HT,
-	},
-	{
-		.name		= "m41t81s",
-		.features	= M41T80_FEATURE_HT | M41T80_FEATURE_BL,
-	},
-	{
-		.name		= "m41t82",
-		.features	= M41T80_FEATURE_HT | M41T80_FEATURE_BL,
-	},
-	{
-		.name		= "m41t83",
-		.features	= M41T80_FEATURE_HT | M41T80_FEATURE_BL,
-	},
-	{
-		.name		= "m41st84",
-		.features	= M41T80_FEATURE_HT | M41T80_FEATURE_BL,
-	},
-	{
-		.name		= "m41st85",
-		.features	= M41T80_FEATURE_HT | M41T80_FEATURE_BL,
-	},
-	{
-		.name		= "m41st87",
-		.features	= M41T80_FEATURE_HT | M41T80_FEATURE_BL,
-	},
+static const struct i2c_device_id m41t80_id[] = {
+	{ "m41t80", 0 },
+	{ "m41t81", M41T80_FEATURE_HT },
+	{ "m41t81s", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
+	{ "m41t82", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
+	{ "m41t83", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
+	{ "m41st84", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
+	{ "m41st85", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
+	{ "m41st87", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
+	{},
 };
+MODULE_DEVICE_TABLE(i2c, m41t80_id);
 
 struct m41t80_data {
-	const struct m41t80_chip_info *chip;
+	u8 features;
 	struct rtc_device *rtc;
 };
 
@@ -208,7 +181,7 @@ static int m41t80_rtc_proc(struct device *dev, struct seq_file *seq)
 	struct m41t80_data *clientdata = i2c_get_clientdata(client);
 	u8 reg;
 
-	if (clientdata->chip->features & M41T80_FEATURE_BL) {
+	if (clientdata->features & M41T80_FEATURE_BL) {
 		reg = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
 		seq_printf(seq, "battery\t\t: %s\n",
 			   (reg & M41T80_FLAGS_BATT_LOW) ? "exhausted" : "ok");
@@ -759,10 +732,9 @@ static struct notifier_block wdt_notifier = {
 static int m41t80_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
-	int i, rc = 0;
+	int rc = 0;
 	struct rtc_device *rtc = NULL;
 	struct rtc_time tm;
-	const struct m41t80_chip_info *chip;
 	struct m41t80_data *clientdata = NULL;
 
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C
@@ -774,19 +746,6 @@ static int m41t80_probe(struct i2c_client *client,
 	dev_info(&client->dev,
 		 "chip found, driver version " DRV_VERSION "\n");
 
-	chip = NULL;
-	for (i = 0; i < ARRAY_SIZE(m41t80_chip_info_tbl); i++) {
-		if (!strcmp(m41t80_chip_info_tbl[i].name, client->name)) {
-			chip = &m41t80_chip_info_tbl[i];
-			break;
-		}
-	}
-	if (!chip) {
-		dev_err(&client->dev, "%s is not supported\n", client->name);
-		rc = -ENODEV;
-		goto exit;
-	}
-
 	clientdata = kzalloc(sizeof(*clientdata), GFP_KERNEL);
 	if (!clientdata) {
 		rc = -ENOMEM;
@@ -802,7 +761,7 @@ static int m41t80_probe(struct i2c_client *client,
 	}
 
 	clientdata->rtc = rtc;
-	clientdata->chip = chip;
+	clientdata->features = id->driver_data;
 	i2c_set_clientdata(client, clientdata);
 
 	/* Make sure HT (Halt Update) bit is cleared */
@@ -811,7 +770,7 @@ static int m41t80_probe(struct i2c_client *client,
 		goto ht_err;
 
 	if (rc & M41T80_ALHOUR_HT) {
-		if (chip->features & M41T80_FEATURE_HT) {
+		if (clientdata->features & M41T80_FEATURE_HT) {
 			m41t80_get_datetime(client, &tm);
 			dev_info(&client->dev, "HT bit was set!\n");
 			dev_info(&client->dev,
@@ -843,7 +802,7 @@ static int m41t80_probe(struct i2c_client *client,
 		goto exit;
 
 #ifdef CONFIG_RTC_DRV_M41T80_WDT
-	if (chip->features & M41T80_FEATURE_HT) {
+	if (clientdata->features & M41T80_FEATURE_HT) {
 		rc = misc_register(&wdt_dev);
 		if (rc)
 			goto exit;
@@ -879,7 +838,7 @@ static int m41t80_remove(struct i2c_client *client)
 	struct rtc_device *rtc = clientdata->rtc;
 
 #ifdef CONFIG_RTC_DRV_M41T80_WDT
-	if (clientdata->chip->features & M41T80_FEATURE_HT) {
+	if (clientdata->features & M41T80_FEATURE_HT) {
 		misc_deregister(&wdt_dev);
 		unregister_reboot_notifier(&wdt_notifier);
 	}
@@ -897,6 +856,7 @@ static struct i2c_driver m41t80_driver = {
 	},
 	.probe = m41t80_probe,
 	.remove = m41t80_remove,
+	.id_table = m41t80_id,
 };
 
 static int __init m41t80_rtc_init(void)
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index ebdbad9..a3e4f8d 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -69,6 +69,15 @@ enum rtc_type {
 	rtc_rv5c387a,
 };
 
+static const struct i2c_device_id rs5c372_id[] = {
+	{ "rs5c372a", rtc_rs5c372a },
+	{ "rs5c372b", rtc_rs5c372b },
+	{ "rv5c386", rtc_rv5c386 },
+	{ "rv5c387a", rtc_rv5c387a },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, rs5c372_id);
+
 /* REVISIT:  this assumes that:
  *  - we're in the 21st century, so it's safe to ignore the century
  *    bit for rv5c38[67] (REG_MONTH bit 7);
@@ -523,7 +532,9 @@ static int rs5c372_probe(struct i2c_client *client,
 	if (err < 0)
 		goto exit_kfree;
 
-	if (strcmp(client->name, "rs5c372a") == 0)
+	if (id)
+		rs5c372->type = id->driver_data;
+	else if (strcmp(client->name, "rs5c372a") == 0)
 		rs5c372->type = rtc_rs5c372a;
 	else if (strcmp(client->name, "rs5c372b") == 0)
 		rs5c372->type = rtc_rs5c372b;
@@ -652,6 +663,7 @@ static struct i2c_driver rs5c372_driver = {
 	},
 	.probe		= rs5c372_probe,
 	.remove		= rs5c372_remove,
+	.id_table	= rs5c372_id,
 };
 
 static __init int rs5c372_init(void)
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c
index e8abc90..c55b9ea 100644
--- a/drivers/rtc/rtc-s35390a.c
+++ b/drivers/rtc/rtc-s35390a.c
@@ -34,6 +34,12 @@
 #define S35390A_FLAG_RESET	0x80
 #define S35390A_FLAG_TEST	0x01
 
+static const struct i2c_device_id s35390a_id[] = {
+	{ "s35390a", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, s35390a_id);
+
 struct s35390a {
 	struct i2c_client *client[8];
 	struct rtc_device *rtc;
@@ -296,6 +302,7 @@ static struct i2c_driver s35390a_driver = {
 	},
 	.probe		= s35390a_probe,
 	.remove		= s35390a_remove,
+	.id_table	= s35390a_id,
 };
 
 static int __init s35390a_rtc_init(void)
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 92c8ecf..01ad5db 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -229,17 +229,17 @@ struct i2c_board_info {
 };
 
 /**
- * I2C_BOARD_INFO - macro used to list an i2c device and its driver
- * @driver: identifies the driver to use with the device
+ * I2C_BOARD_INFO - macro used to list an i2c device and its address
+ * @dev_type: identifies the device type
  * @dev_addr: the device's address on the bus.
  *
  * This macro initializes essential fields of a struct i2c_board_info,
  * declaring what has been provided on a particular board.  Optional
- * fields (such as the chip type, its associated irq, or device-specific
- * platform_data) are provided using conventional syntax.
+ * fields (such as associated irq, or device-specific platform_data)
+ * are provided using conventional syntax.
  */
-#define I2C_BOARD_INFO(driver,dev_addr) \
-	.driver_name = (driver), .addr = (dev_addr)
+#define I2C_BOARD_INFO(dev_type,dev_addr) \
+	.type = (dev_type), .addr = (dev_addr)
 
 
 /* Add-on boards should register/unregister their devices; e.g. a board
diff --git a/include/media/v4l2-i2c-drv-legacy.h b/include/media/v4l2-i2c-drv-legacy.h
index 347b6f8..8785622 100644
--- a/include/media/v4l2-i2c-drv-legacy.h
+++ b/include/media/v4l2-i2c-drv-legacy.h
@@ -31,6 +31,7 @@ struct v4l2_i2c_driver_data {
 	int (*resume)(struct i2c_client *client);
 	int (*legacy_probe)(struct i2c_adapter *adapter);
 	int legacy_class;
+	const struct i2c_device_id *id_table;
 };
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data;
@@ -124,6 +125,7 @@ static int __init v4l2_i2c_drv_init(void)
 	v4l2_i2c_driver.command = v4l2_i2c_data.command;
 	v4l2_i2c_driver.probe = v4l2_i2c_data.probe;
 	v4l2_i2c_driver.remove = v4l2_i2c_data.remove;
+	v4l2_i2c_driver.id_table = v4l2_i2c_data.id_table;
 	err = i2c_add_driver(&v4l2_i2c_driver);
 	if (err)
 		i2c_del_driver(&v4l2_i2c_driver_legacy);
diff --git a/include/media/v4l2-i2c-drv.h b/include/media/v4l2-i2c-drv.h
index 7b6f06b..40ecef2 100644
--- a/include/media/v4l2-i2c-drv.h
+++ b/include/media/v4l2-i2c-drv.h
@@ -36,6 +36,7 @@ struct v4l2_i2c_driver_data {
 	int (*resume)(struct i2c_client *client);
 	int (*legacy_probe)(struct i2c_adapter *adapter);
 	int legacy_class;
+	const struct i2c_device_id *id_table;
 };
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data;
@@ -53,6 +54,7 @@ static int __init v4l2_i2c_drv_init(void)
 	v4l2_i2c_driver.remove = v4l2_i2c_data.remove;
 	v4l2_i2c_driver.suspend = v4l2_i2c_data.suspend;
 	v4l2_i2c_driver.resume = v4l2_i2c_data.resume;
+	v4l2_i2c_driver.id_table = v4l2_i2c_data.id_table;
 	return i2c_add_driver(&v4l2_i2c_driver);
 }
 
-- 
1.5.4.5

^ permalink raw reply related

* [PATCH1/7] i2c: Add support for device alias names
From: Jochen Friedrich @ 2008-04-11 14:07 UTC (permalink / raw)
  To: Kumar Gala
  Cc: linuxppc-dev list, Kernel, Linux, Scott Wood, Jean Delvare,
	Linux I2C

Based on earlier work by Jon Smirl and Jean Delvare.

This patch allows new-style i2c chip drivers to have alias names using
the official kernel aliasing system and MODULE_DEVICE_TABLE(). At this
point, the old i2c driver binding scheme (driver_name/type) is still
supported.

Signed-off-by: Jochen Friedrich <jochen@scram.de>
Cc: Jean Delvare <khali@linux-fr.org>
Cc: Jon Smirl <jonsmirl@gmail.com>
---
 drivers/hwmon/f75375s.c                    |   21 ++++++++----
 drivers/i2c/chips/ds1682.c                 |    3 +-
 drivers/i2c/chips/menelaus.c               |    3 +-
 drivers/i2c/chips/tps65010.c               |    3 +-
 drivers/i2c/chips/tsl2550.c                |    3 +-
 drivers/i2c/i2c-core.c                     |   51 +++++++++++++++++++++++-----
 drivers/media/video/cs5345.c               |    3 +-
 drivers/media/video/cs53l32a.c             |    3 +-
 drivers/media/video/cx25840/cx25840-core.c |    3 +-
 drivers/media/video/ivtv/ivtv-i2c.c        |    2 +-
 drivers/media/video/m52790.c               |    3 +-
 drivers/media/video/msp3400-driver.c       |    3 +-
 drivers/media/video/saa7115.c              |    3 +-
 drivers/media/video/saa7127.c              |    3 +-
 drivers/media/video/tlv320aic23b.c         |    3 +-
 drivers/media/video/tuner-core.c           |    3 +-
 drivers/media/video/tvaudio.c              |    3 +-
 drivers/media/video/upd64031a.c            |    3 +-
 drivers/media/video/upd64083.c             |    3 +-
 drivers/media/video/v4l2-common.c          |    5 ++-
 drivers/media/video/vp27smpx.c             |    3 +-
 drivers/media/video/wm8739.c               |    3 +-
 drivers/media/video/wm8775.c               |    3 +-
 drivers/rtc/rtc-ds1307.c                   |    3 +-
 drivers/rtc/rtc-ds1374.c                   |    3 +-
 drivers/rtc/rtc-m41t80.c                   |    3 +-
 drivers/rtc/rtc-rs5c372.c                  |    3 +-
 include/linux/i2c.h                        |    5 +--
 include/linux/mod_devicetable.h            |   13 +++++++
 include/media/v4l2-common.h                |    4 ++-
 include/media/v4l2-i2c-drv-legacy.h        |    2 +-
 include/media/v4l2-i2c-drv.h               |    2 +-
 scripts/mod/file2alias.c                   |   13 +++++++
 33 files changed, 139 insertions(+), 48 deletions(-)

diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index 1464338..3ec9123 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -117,7 +117,8 @@ struct f75375_data {
 static int f75375_attach_adapter(struct i2c_adapter *adapter);
 static int f75375_detect(struct i2c_adapter *adapter, int address, int kind);
 static int f75375_detach_client(struct i2c_client *client);
-static int f75375_probe(struct i2c_client *client);
+static int f75375_probe(struct i2c_client *client,
+			const struct i2c_device_id *id);
 static int f75375_remove(struct i2c_client *client);
 
 static struct i2c_driver f75375_legacy_driver = {
@@ -628,7 +629,8 @@ static void f75375_init(struct i2c_client *client, struct f75375_data *data,
 
 }
 
-static int f75375_probe(struct i2c_client *client)
+static int f75375_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
 {
 	struct f75375_data *data = i2c_get_clientdata(client);
 	struct f75375s_platform_data *f75375s_pdata = client->dev.platform_data;
@@ -637,7 +639,8 @@ static int f75375_probe(struct i2c_client *client)
 	if (!i2c_check_functionality(client->adapter,
 				I2C_FUNC_SMBUS_BYTE_DATA))
 		return -EIO;
-	if (!(data = kzalloc(sizeof(struct f75375_data), GFP_KERNEL)))
+	data = kzalloc(sizeof(struct f75375_data), GFP_KERNEL);
+	if (!data)
 		return -ENOMEM;
 
 	i2c_set_clientdata(client, data);
@@ -653,7 +656,8 @@ static int f75375_probe(struct i2c_client *client)
 		return -ENODEV;
 	}
 
-	if ((err = sysfs_create_group(&client->dev.kobj, &f75375_group)))
+	err = sysfs_create_group(&client->dev.kobj, &f75375_group);
+	if (err)
 		goto exit_free;
 
 	if (data->kind == f75375) {
@@ -713,7 +717,8 @@ static int f75375_detect(struct i2c_adapter *adapter, int address, int kind)
 	int err = 0;
 	const char *name = "";
 
-	if (!(client = kzalloc(sizeof(*client), GFP_KERNEL))) {
+	client = kzalloc(sizeof(*client), GFP_KERNEL);
+	if (!client) {
 		err = -ENOMEM;
 		goto exit;
 	}
@@ -745,10 +750,12 @@ static int f75375_detect(struct i2c_adapter *adapter, int address, int kind)
 	dev_info(&adapter->dev, "found %s version: %02X\n", name, version);
 	strlcpy(client->name, name, I2C_NAME_SIZE);
 
-	if ((err = i2c_attach_client(client)))
+	err = i2c_attach_client(client);
+	if (err)
 		goto exit_free;
 
-	if ((err = f75375_probe(client)) < 0)
+	err = f75375_probe(client, NULL);
+	if (err < 0)
 		goto exit_detach;
 
 	return 0;
diff --git a/drivers/i2c/chips/ds1682.c b/drivers/i2c/chips/ds1682.c
index 9e94542..3070821 100644
--- a/drivers/i2c/chips/ds1682.c
+++ b/drivers/i2c/chips/ds1682.c
@@ -200,7 +200,8 @@ static struct bin_attribute ds1682_eeprom_attr = {
 /*
  * Called when a ds1682 device is matched with this driver
  */
-static int ds1682_probe(struct i2c_client *client)
+static int ds1682_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
 {
 	int rc;
 
diff --git a/drivers/i2c/chips/menelaus.c b/drivers/i2c/chips/menelaus.c
index 2dea012..3b8ba7e 100644
--- a/drivers/i2c/chips/menelaus.c
+++ b/drivers/i2c/chips/menelaus.c
@@ -1149,7 +1149,8 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
 
 static struct i2c_driver menelaus_i2c_driver;
 
-static int menelaus_probe(struct i2c_client *client)
+static int menelaus_probe(struct i2c_client *client,
+			  const struct i2c_device_id *id)
 {
 	struct menelaus_chip	*menelaus;
 	int			rev = 0, val;
diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c
index 4154a91..3ce43f8 100644
--- a/drivers/i2c/chips/tps65010.c
+++ b/drivers/i2c/chips/tps65010.c
@@ -465,7 +465,8 @@ static int __exit tps65010_remove(struct i2c_client *client)
 	return 0;
 }
 
-static int tps65010_probe(struct i2c_client *client)
+static int tps65010_probe(struct i2c_client *client,
+			  const struct i2c_device_id *id)
 {
 	struct tps65010		*tps;
 	int			status;
diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/i2c/chips/tsl2550.c
index a10fd27..59c2c66 100644
--- a/drivers/i2c/chips/tsl2550.c
+++ b/drivers/i2c/chips/tsl2550.c
@@ -364,7 +364,8 @@ static int tsl2550_init_client(struct i2c_client *client)
  */
 
 static struct i2c_driver tsl2550_driver;
-static int __devinit tsl2550_probe(struct i2c_client *client)
+static int __devinit tsl2550_probe(struct i2c_client *client,
+				   const struct i2c_device_id *id)
 {
 	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
 	struct tsl2550_data *data;
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 8b645c6..8879acb 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -48,6 +48,17 @@ static DEFINE_IDR(i2c_adapter_idr);
 
 /* ------------------------------------------------------------------------- */
 
+static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
+						const struct i2c_client *client)
+{
+	while (id->name[0]) {
+		if (strcmp(client->name, id->name) == 0)
+			return id;
+		id++;
+	}
+	return NULL;
+}
+
 static int i2c_device_match(struct device *dev, struct device_driver *drv)
 {
 	struct i2c_client	*client = to_i2c_client(dev);
@@ -59,6 +70,10 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
 	if (!is_newstyle_driver(driver))
 		return 0;
 
+	/* match on an id table if there is one */
+	if (driver->id_table)
+		return i2c_match_id(driver->id_table, client) != NULL;
+
 	/* new style drivers use the same kind of driver matching policy
 	 * as platform devices or SPI:  compare device and driver IDs.
 	 */
@@ -73,11 +88,17 @@ static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
 	struct i2c_client	*client = to_i2c_client(dev);
 
 	/* by definition, legacy drivers can't hotplug */
-	if (dev->driver || !client->driver_name)
+	if (dev->driver)
 		return 0;
 
-	if (add_uevent_var(env, "MODALIAS=%s", client->driver_name))
-		return -ENOMEM;
+	if (client->driver_name[0]) {
+		if (add_uevent_var(env, "MODALIAS=%s", client->driver_name))
+			return -ENOMEM;
+	} else {
+		if (add_uevent_var(env, "MODALIAS=%s%s",
+				   I2C_MODULE_PREFIX, client->name))
+			return -ENOMEM;
+	}
 	dev_dbg(dev, "uevent\n");
 	return 0;
 }
@@ -91,12 +112,18 @@ static int i2c_device_probe(struct device *dev)
 	struct i2c_client	*client = to_i2c_client(dev);
 	struct i2c_driver	*driver = to_i2c_driver(dev->driver);
 	int status;
+	const struct i2c_device_id *id;
 
 	if (!driver->probe)
 		return -ENODEV;
 	client->driver = driver;
 	dev_dbg(dev, "probe\n");
-	status = driver->probe(client);
+
+	if (driver->id_table)
+		id = i2c_match_id(driver->id_table, client);
+	else
+		id = NULL;
+	status = driver->probe(client, id);
 	if (status)
 		client->driver = NULL;
 	return status;
@@ -179,9 +206,9 @@ static ssize_t show_client_name(struct device *dev, struct device_attribute *att
 static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct i2c_client *client = to_i2c_client(dev);
-	return client->driver_name
+	return client->driver_name[0]
 		? sprintf(buf, "%s\n", client->driver_name)
-		: 0;
+		: sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name);
 }
 
 static struct device_attribute i2c_dev_attrs[] = {
@@ -300,15 +327,21 @@ void i2c_unregister_device(struct i2c_client *client)
 EXPORT_SYMBOL_GPL(i2c_unregister_device);
 
 
-static int dummy_nop(struct i2c_client *client)
+static int dummy_probe(struct i2c_client *client,
+		       const struct i2c_device_id *id)
+{
+	return 0;
+}
+
+static int dummy_remove(struct i2c_client *client)
 {
 	return 0;
 }
 
 static struct i2c_driver dummy_driver = {
 	.driver.name	= "dummy",
-	.probe		= dummy_nop,
-	.remove		= dummy_nop,
+	.probe		= dummy_probe,
+	.remove		= dummy_remove,
 };
 
 /**
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c
index fae469c..2a429f9 100644
--- a/drivers/media/video/cs5345.c
+++ b/drivers/media/video/cs5345.c
@@ -142,7 +142,8 @@ static int cs5345_command(struct i2c_client *client, unsigned cmd, void *arg)
 
 /* ----------------------------------------------------------------------- */
 
-static int cs5345_probe(struct i2c_client *client)
+static int cs5345_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
 {
 	/* Check if the adapter supports the needed features */
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
index f41bfde..2dfd0af 100644
--- a/drivers/media/video/cs53l32a.c
+++ b/drivers/media/video/cs53l32a.c
@@ -135,7 +135,8 @@ static int cs53l32a_command(struct i2c_client *client, unsigned cmd, void *arg)
  * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
  */
 
-static int cs53l32a_probe(struct i2c_client *client)
+static int cs53l32a_probe(struct i2c_client *client,
+			  const struct i2c_device_id *id)
 {
 	int i;
 
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 756a1ee..6f16186 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -1232,7 +1232,8 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
 
 /* ----------------------------------------------------------------------- */
 
-static int cx25840_probe(struct i2c_client *client)
+static int cx25840_probe(struct i2c_client *client,
+			 const struct i2c_device_id *did)
 {
 	struct cx25840_state *state;
 	u32 id;
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index fa5ab1e..37b0fd6 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -167,7 +167,7 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
 		return -1;
 	id = hw_driverids[idx];
 	memset(&info, 0, sizeof(info));
-	strcpy(info.driver_name, hw_drivernames[idx]);
+	strcpy(info.type, hw_drivernames[idx]);
 	info.addr = hw_addrs[idx];
 	for (i = 0; itv->i2c_clients[i] && i < I2C_CLIENTS_MAX; i++) {}
 
diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c
index d4bf14c..5b9dfa2 100644
--- a/drivers/media/video/m52790.c
+++ b/drivers/media/video/m52790.c
@@ -126,7 +126,8 @@ static int m52790_command(struct i2c_client *client, unsigned int cmd,
 
 /* i2c implementation */
 
-static int m52790_probe(struct i2c_client *client)
+static int m52790_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
 {
 	struct m52790_state *state;
 
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index 7a11f31..3f97737 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -805,7 +805,8 @@ static int msp_resume(struct i2c_client *client)
 
 /* ----------------------------------------------------------------------- */
 
-static int msp_probe(struct i2c_client *client)
+static int msp_probe(struct i2c_client *client,
+		     const struct i2c_device_id *id)
 {
 	struct msp_state *state;
 	int (*thread_func)(void *data) = NULL;
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 41e5e51..7882e29 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -1450,7 +1450,8 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
 
 /* ----------------------------------------------------------------------- */
 
-static int saa7115_probe(struct i2c_client *client)
+static int saa7115_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
 {
 	struct saa711x_state *state;
 	int	i;
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index 06c88db..e750cd6 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -661,7 +661,8 @@ static int saa7127_command(struct i2c_client *client,
 
 /* ----------------------------------------------------------------------- */
 
-static int saa7127_probe(struct i2c_client *client)
+static int saa7127_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
 {
 	struct saa7127_state *state;
 	struct v4l2_sliced_vbi_data vbi = { 0, 0, 0, 0 };  /* set to disabled */
diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c
index dc7b9c2..f1db542 100644
--- a/drivers/media/video/tlv320aic23b.c
+++ b/drivers/media/video/tlv320aic23b.c
@@ -125,7 +125,8 @@ static int tlv320aic23b_command(struct i2c_client *client,
  * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
  */
 
-static int tlv320aic23b_probe(struct i2c_client *client)
+static int tlv320aic23b_probe(struct i2c_client *client,
+			      const struct i2c_device_id *id)
 {
 	struct tlv320aic23b_state *state;
 
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 78a09a2..edd451e 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -1074,7 +1074,8 @@ static void tuner_lookup(struct i2c_adapter *adap,
 /* During client attach, set_type is called by adapter's attach_inform callback.
    set_type must then be completed by tuner_probe.
  */
-static int tuner_probe(struct i2c_client *client)
+static int tuner_probe(struct i2c_client *client,
+		       const struct i2c_device_id *id)
 {
 	struct tuner *t;
 	struct tuner *radio;
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 01ebcec..1fa1552 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -1461,7 +1461,8 @@ static struct CHIPDESC chiplist[] = {
 /* ---------------------------------------------------------------------- */
 /* i2c registration                                                       */
 
-static int chip_probe(struct i2c_client *client)
+static int chip_probe(struct i2c_client *client,
+		      const struct i2c_device_id *id)
 {
 	struct CHIPSTATE *chip;
 	struct CHIPDESC  *desc;
diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c
index bd20139..93bfd19 100644
--- a/drivers/media/video/upd64031a.c
+++ b/drivers/media/video/upd64031a.c
@@ -195,7 +195,8 @@ static int upd64031a_command(struct i2c_client *client, unsigned cmd, void *arg)
 
 /* i2c implementation */
 
-static int upd64031a_probe(struct i2c_client *client)
+static int upd64031a_probe(struct i2c_client *client,
+			   const struct i2c_device_id *id)
 {
 	struct upd64031a_state *state;
 	int i;
diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c
index 2d9a88f..9ab712a 100644
--- a/drivers/media/video/upd64083.c
+++ b/drivers/media/video/upd64083.c
@@ -172,7 +172,8 @@ static int upd64083_command(struct i2c_client *client, unsigned cmd, void *arg)
 
 /* i2c implementation */
 
-static int upd64083_probe(struct i2c_client *client)
+static int upd64083_probe(struct i2c_client *client,
+			  const struct i2c_device_id *id)
 {
 	struct upd64083_state *state;
 	int i;
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 34deb68..afacf75 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -710,7 +710,8 @@ EXPORT_SYMBOL(v4l2_chip_ident_i2c_client);
 /* Helper function for I2C legacy drivers */
 
 int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver *driver,
-		const char *name, int (*probe)(struct i2c_client *))
+		const char *name, int (*probe)(struct i2c_client *,
+					       const struct i2c_device_id *id))
 {
 	struct i2c_client *client;
 	int err;
@@ -724,7 +725,7 @@ int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver
 	client->driver = driver;
 	strlcpy(client->name, name, sizeof(client->name));
 
-	err = probe(client);
+	err = probe(client, NULL);
 	if (err == 0) {
 		i2c_attach_client(client);
 	} else {
diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c
index 282c814..fac0deb 100644
--- a/drivers/media/video/vp27smpx.c
+++ b/drivers/media/video/vp27smpx.c
@@ -121,7 +121,8 @@ static int vp27smpx_command(struct i2c_client *client, unsigned cmd, void *arg)
  * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
  */
 
-static int vp27smpx_probe(struct i2c_client *client)
+static int vp27smpx_probe(struct i2c_client *client,
+			  const struct i2c_device_id *id)
 {
 	struct vp27smpx_state *state;
 
diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c
index 31795b4..0f8ed84 100644
--- a/drivers/media/video/wm8739.c
+++ b/drivers/media/video/wm8739.c
@@ -261,7 +261,8 @@ static int wm8739_command(struct i2c_client *client, unsigned cmd, void *arg)
 
 /* i2c implementation */
 
-static int wm8739_probe(struct i2c_client *client)
+static int wm8739_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
 {
 	struct wm8739_state *state;
 
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index 869f9e7..67a409e 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -159,7 +159,8 @@ static int wm8775_command(struct i2c_client *client, unsigned cmd, void *arg)
  * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
  */
 
-static int wm8775_probe(struct i2c_client *client)
+static int wm8775_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
 {
 	struct wm8775_state *state;
 
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index f389a28..67ba8ae 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -326,7 +326,8 @@ static struct bin_attribute nvram = {
 
 static struct i2c_driver ds1307_driver;
 
-static int __devinit ds1307_probe(struct i2c_client *client)
+static int __devinit ds1307_probe(struct i2c_client *client,
+				  const struct i2c_device_id *id)
 {
 	struct ds1307		*ds1307;
 	int			err = -ENODEV;
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index 45bda18..104dcfd 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -355,7 +355,8 @@ static const struct rtc_class_ops ds1374_rtc_ops = {
 	.ioctl = ds1374_ioctl,
 };
 
-static int ds1374_probe(struct i2c_client *client)
+static int ds1374_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
 {
 	struct ds1374 *ds1374;
 	int ret;
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 1cb33ca..2ee0d07 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -756,7 +756,8 @@ static struct notifier_block wdt_notifier = {
  *
  *****************************************************************************
  */
-static int m41t80_probe(struct i2c_client *client)
+static int m41t80_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
 {
 	int i, rc = 0;
 	struct rtc_device *rtc = NULL;
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index 6b67b50..ebdbad9 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -494,7 +494,8 @@ static void rs5c_sysfs_unregister(struct device *dev)
 
 static struct i2c_driver rs5c372_driver;
 
-static int rs5c372_probe(struct i2c_client *client)
+static int rs5c372_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
 {
 	int err = 0;
 	struct rs5c372 *rs5c372;
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 365e0df..92c8ecf 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -126,7 +126,7 @@ struct i2c_driver {
 	 * With the driver model, device enumeration is NEVER done by drivers;
 	 * it's done by infrastructure.  (NEW STYLE DRIVERS ONLY)
 	 */
-	int (*probe)(struct i2c_client *);
+	int (*probe)(struct i2c_client *, const struct i2c_device_id *id);
 	int (*remove)(struct i2c_client *);
 
 	/* driver model interfaces that don't relate to enumeration  */
@@ -140,11 +140,10 @@ struct i2c_driver {
 	int (*command)(struct i2c_client *client,unsigned int cmd, void *arg);
 
 	struct device_driver driver;
+	const struct i2c_device_id *id_table;
 };
 #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)
 
-#define I2C_NAME_SIZE	20
-
 /**
  * struct i2c_client - represent an I2C slave device
  * @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address;
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 139d49d..696c07b 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -368,4 +368,17 @@ struct virtio_device_id {
 };
 #define VIRTIO_DEV_ANY_ID	0xffffffff
 
+/* i2c */
+
+/* These defines are used to separate PowerPC open firmware
+ * drivers into their own namespace */
+#define I2C_NAME_SIZE	20
+#define I2C_MODULE_PREFIX "i2c:"
+
+struct i2c_device_id {
+	char name[I2C_NAME_SIZE];
+	kernel_ulong_t driver_data;	/* Data private to the driver */
+};
+
+
 #endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 316a584..9c4b906 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -107,9 +107,11 @@ int v4l2_chip_match_host(u32 id_type, u32 chip_id);
 struct i2c_driver;
 struct i2c_adapter;
 struct i2c_client;
+struct i2c_device_id;
 
 int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver *driver,
-		const char *name, int (*probe)(struct i2c_client *));
+		const char *name, int (*probe)(struct i2c_client *,
+					       const struct i2c_device_id *id));
 
 /* ------------------------------------------------------------------------- */
 
diff --git a/include/media/v4l2-i2c-drv-legacy.h b/include/media/v4l2-i2c-drv-legacy.h
index e764557..347b6f8 100644
--- a/include/media/v4l2-i2c-drv-legacy.h
+++ b/include/media/v4l2-i2c-drv-legacy.h
@@ -25,7 +25,7 @@ struct v4l2_i2c_driver_data {
 	const char * const name;
 	int driverid;
 	int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
-	int (*probe)(struct i2c_client *client);
+	int (*probe)(struct i2c_client *client, const struct i2c_device_id *id);
 	int (*remove)(struct i2c_client *client);
 	int (*suspend)(struct i2c_client *client, pm_message_t state);
 	int (*resume)(struct i2c_client *client);
diff --git a/include/media/v4l2-i2c-drv.h b/include/media/v4l2-i2c-drv.h
index 9e4bab2..7b6f06b 100644
--- a/include/media/v4l2-i2c-drv.h
+++ b/include/media/v4l2-i2c-drv.h
@@ -30,7 +30,7 @@ struct v4l2_i2c_driver_data {
 	const char * const name;
 	int driverid;
 	int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
-	int (*probe)(struct i2c_client *client);
+	int (*probe)(struct i2c_client *client, const struct i2c_device_id *id);
 	int (*remove)(struct i2c_client *client);
 	int (*suspend)(struct i2c_client *client, pm_message_t state);
 	int (*resume)(struct i2c_client *client);
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 348d868..0d9e179 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -543,6 +543,15 @@ static int do_virtio_entry(const char *filename, struct virtio_device_id *id,
 	return 1;
 }
 
+/* Looks like: i2c:S */
+static int do_i2c_entry(const char *filename, struct i2c_device_id *id,
+			char *alias)
+{
+	sprintf(alias, I2C_MODULE_PREFIX "%s", id->name);
+
+	return 1;
+}
+
 /* Ignore any prefix, eg. v850 prepends _ */
 static inline int sym_is(const char *symbol, const char *name)
 {
@@ -673,6 +682,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
 		do_table(symval, sym->st_size,
 			 sizeof(struct virtio_device_id), "virtio",
 			 do_virtio_entry, mod);
+	else if (sym_is(symname, "__mod_i2c_device_table"))
+		do_table(symval, sym->st_size,
+			 sizeof(struct i2c_device_id), "i2c",
+			 do_i2c_entry, mod);
 	free(zeros);
 }
 
-- 
1.5.4.5

^ permalink raw reply related

* Re: [PATCH 1/8] [POWERPC] fsl_elbc_nand: factor out localbus defines
From: Kumar Gala @ 2008-04-11 14:06 UTC (permalink / raw)
  To: David Woodhouse; +Cc: Scott Wood, linuxppc-dev@ozlabs.org list, linux-mtd
In-Reply-To: <20080311172328.GA7727@localhost.localdomain>


On Mar 11, 2008, at 12:23 PM, Anton Vorontsov wrote:
> This is needed to support other localbus peripherals, such as
> NAND on FSL UPM.
>
> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
> ---
>
> Would be great if someone from the MTD community will ack this patch
> to go through powerpc trees.
>
> Thanks,

David, can you ack this.  It looks good to me but want a MTD  
maintainer ack before having it go through the powerpc tree.

- k

>
>
> drivers/mtd/nand/fsl_elbc_nand.c |  219 + 
> +-----------------------------------
> include/asm-powerpc/fsl_lbc.h    |  223 +++++++++++++++++++++++++++++ 
> +++++++++
> 2 files changed, 235 insertions(+), 207 deletions(-)
> create mode 100644 include/asm-powerpc/fsl_lbc.h
>
> diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/ 
> fsl_elbc_nand.c
> index b025dfe..378b7aa 100644
> --- a/drivers/mtd/nand/fsl_elbc_nand.c
> +++ b/drivers/mtd/nand/fsl_elbc_nand.c
> @@ -36,207 +36,12 @@
> #include <linux/mtd/partitions.h>
>
> #include <asm/io.h>
> -
> +#include <asm/fsl_lbc.h>
>
> #define MAX_BANKS 8
> #define ERR_BYTE 0xFF /* Value returned for read bytes when read  
> failed */
> #define FCM_TIMEOUT_MSECS 500 /* Maximum number of mSecs to wait for  
> FCM */
>
> -struct elbc_bank {
> -	__be32 br;             /**< Base Register  */
> -#define BR_BA           0xFFFF8000
> -#define BR_BA_SHIFT             15
> -#define BR_PS           0x00001800
> -#define BR_PS_SHIFT             11
> -#define BR_PS_8         0x00000800  /* Port Size 8 bit */
> -#define BR_PS_16        0x00001000  /* Port Size 16 bit */
> -#define BR_PS_32        0x00001800  /* Port Size 32 bit */
> -#define BR_DECC         0x00000600
> -#define BR_DECC_SHIFT            9
> -#define BR_DECC_OFF     0x00000000  /* HW ECC checking and  
> generation off */
> -#define BR_DECC_CHK     0x00000200  /* HW ECC checking on,  
> generation off */
> -#define BR_DECC_CHK_GEN 0x00000400  /* HW ECC checking and  
> generation on */
> -#define BR_WP           0x00000100
> -#define BR_WP_SHIFT              8
> -#define BR_MSEL         0x000000E0
> -#define BR_MSEL_SHIFT            5
> -#define BR_MS_GPCM      0x00000000  /* GPCM */
> -#define BR_MS_FCM       0x00000020  /* FCM */
> -#define BR_MS_SDRAM     0x00000060  /* SDRAM */
> -#define BR_MS_UPMA      0x00000080  /* UPMA */
> -#define BR_MS_UPMB      0x000000A0  /* UPMB */
> -#define BR_MS_UPMC      0x000000C0  /* UPMC */
> -#define BR_V            0x00000001
> -#define BR_V_SHIFT               0
> -#define BR_RES          ~(BR_BA|BR_PS|BR_DECC|BR_WP|BR_MSEL|BR_V)
> -
> -	__be32 or;             /**< Base Register  */
> -#define OR0 0x5004
> -#define OR1 0x500C
> -#define OR2 0x5014
> -#define OR3 0x501C
> -#define OR4 0x5024
> -#define OR5 0x502C
> -#define OR6 0x5034
> -#define OR7 0x503C
> -
> -#define OR_FCM_AM               0xFFFF8000
> -#define OR_FCM_AM_SHIFT                 15
> -#define OR_FCM_BCTLD            0x00001000
> -#define OR_FCM_BCTLD_SHIFT              12
> -#define OR_FCM_PGS              0x00000400
> -#define OR_FCM_PGS_SHIFT                10
> -#define OR_FCM_CSCT             0x00000200
> -#define OR_FCM_CSCT_SHIFT                9
> -#define OR_FCM_CST              0x00000100
> -#define OR_FCM_CST_SHIFT                 8
> -#define OR_FCM_CHT              0x00000080
> -#define OR_FCM_CHT_SHIFT                 7
> -#define OR_FCM_SCY              0x00000070
> -#define OR_FCM_SCY_SHIFT                 4
> -#define OR_FCM_SCY_1            0x00000010
> -#define OR_FCM_SCY_2            0x00000020
> -#define OR_FCM_SCY_3            0x00000030
> -#define OR_FCM_SCY_4            0x00000040
> -#define OR_FCM_SCY_5            0x00000050
> -#define OR_FCM_SCY_6            0x00000060
> -#define OR_FCM_SCY_7            0x00000070
> -#define OR_FCM_RST              0x00000008
> -#define OR_FCM_RST_SHIFT                 3
> -#define OR_FCM_TRLX             0x00000004
> -#define OR_FCM_TRLX_SHIFT                2
> -#define OR_FCM_EHTR             0x00000002
> -#define OR_FCM_EHTR_SHIFT                1
> -};
> -
> -struct elbc_regs {
> -	struct elbc_bank bank[8];
> -	u8 res0[0x28];
> -	__be32 mar;             /**< UPM Address Register */
> -	u8 res1[0x4];
> -	__be32 mamr;            /**< UPMA Mode Register */
> -	__be32 mbmr;            /**< UPMB Mode Register */
> -	__be32 mcmr;            /**< UPMC Mode Register */
> -	u8 res2[0x8];
> -	__be32 mrtpr;           /**< Memory Refresh Timer Prescaler  
> Register */
> -	__be32 mdr;             /**< UPM Data Register */
> -	u8 res3[0x4];
> -	__be32 lsor;            /**< Special Operation Initiation Register  
> */
> -	__be32 lsdmr;           /**< SDRAM Mode Register */
> -	u8 res4[0x8];
> -	__be32 lurt;            /**< UPM Refresh Timer */
> -	__be32 lsrt;            /**< SDRAM Refresh Timer */
> -	u8 res5[0x8];
> -	__be32 ltesr;           /**< Transfer Error Status Register */
> -#define LTESR_BM   0x80000000
> -#define LTESR_FCT  0x40000000
> -#define LTESR_PAR  0x20000000
> -#define LTESR_WP   0x04000000
> -#define LTESR_ATMW 0x00800000
> -#define LTESR_ATMR 0x00400000
> -#define LTESR_CS   0x00080000
> -#define LTESR_CC   0x00000001
> -#define LTESR_NAND_MASK (LTESR_FCT | LTESR_PAR | LTESR_CC)
> -	__be32 ltedr;           /**< Transfer Error Disable Register */
> -	__be32 lteir;           /**< Transfer Error Interrupt Register */
> -	__be32 lteatr;          /**< Transfer Error Attributes Register */
> -	__be32 ltear;           /**< Transfer Error Address Register */
> -	u8 res6[0xC];
> -	__be32 lbcr;            /**< Configuration Register */
> -#define LBCR_LDIS  0x80000000
> -#define LBCR_LDIS_SHIFT    31
> -#define LBCR_BCTLC 0x00C00000
> -#define LBCR_BCTLC_SHIFT   22
> -#define LBCR_AHD   0x00200000
> -#define LBCR_LPBSE 0x00020000
> -#define LBCR_LPBSE_SHIFT   17
> -#define LBCR_EPAR  0x00010000
> -#define LBCR_EPAR_SHIFT    16
> -#define LBCR_BMT   0x0000FF00
> -#define LBCR_BMT_SHIFT      8
> -#define LBCR_INIT  0x00040000
> -	__be32 lcrr;            /**< Clock Ratio Register */
> -#define LCRR_DBYP    0x80000000
> -#define LCRR_DBYP_SHIFT      31
> -#define LCRR_BUFCMDC 0x30000000
> -#define LCRR_BUFCMDC_SHIFT   28
> -#define LCRR_ECL     0x03000000
> -#define LCRR_ECL_SHIFT       24
> -#define LCRR_EADC    0x00030000
> -#define LCRR_EADC_SHIFT      16
> -#define LCRR_CLKDIV  0x0000000F
> -#define LCRR_CLKDIV_SHIFT     0
> -	u8 res7[0x8];
> -	__be32 fmr;             /**< Flash Mode Register */
> -#define FMR_CWTO     0x0000F000
> -#define FMR_CWTO_SHIFT       12
> -#define FMR_BOOT     0x00000800
> -#define FMR_ECCM     0x00000100
> -#define FMR_AL       0x00000030
> -#define FMR_AL_SHIFT          4
> -#define FMR_OP       0x00000003
> -#define FMR_OP_SHIFT          0
> -	__be32 fir;             /**< Flash Instruction Register */
> -#define FIR_OP0      0xF0000000
> -#define FIR_OP0_SHIFT        28
> -#define FIR_OP1      0x0F000000
> -#define FIR_OP1_SHIFT        24
> -#define FIR_OP2      0x00F00000
> -#define FIR_OP2_SHIFT        20
> -#define FIR_OP3      0x000F0000
> -#define FIR_OP3_SHIFT        16
> -#define FIR_OP4      0x0000F000
> -#define FIR_OP4_SHIFT        12
> -#define FIR_OP5      0x00000F00
> -#define FIR_OP5_SHIFT         8
> -#define FIR_OP6      0x000000F0
> -#define FIR_OP6_SHIFT         4
> -#define FIR_OP7      0x0000000F
> -#define FIR_OP7_SHIFT         0
> -#define FIR_OP_NOP   0x0	/* No operation and end of sequence */
> -#define FIR_OP_CA    0x1        /* Issue current column address */
> -#define FIR_OP_PA    0x2        /* Issue current block+page address  
> */
> -#define FIR_OP_UA    0x3        /* Issue user defined address */
> -#define FIR_OP_CM0   0x4        /* Issue command from FCR[CMD0] */
> -#define FIR_OP_CM1   0x5        /* Issue command from FCR[CMD1] */
> -#define FIR_OP_CM2   0x6        /* Issue command from FCR[CMD2] */
> -#define FIR_OP_CM3   0x7        /* Issue command from FCR[CMD3] */
> -#define FIR_OP_WB    0x8        /* Write FBCR bytes from FCM buffer  
> */
> -#define FIR_OP_WS    0x9        /* Write 1 or 2 bytes from MDR[AS] */
> -#define FIR_OP_RB    0xA        /* Read FBCR bytes to FCM buffer */
> -#define FIR_OP_RS    0xB        /* Read 1 or 2 bytes to MDR[AS] */
> -#define FIR_OP_CW0   0xC        /* Wait then issue FCR[CMD0] */
> -#define FIR_OP_CW1   0xD        /* Wait then issue FCR[CMD1] */
> -#define FIR_OP_RBW   0xE        /* Wait then read FBCR bytes */
> -#define FIR_OP_RSW   0xE        /* Wait then read 1 or 2 bytes */
> -	__be32 fcr;             /**< Flash Command Register */
> -#define FCR_CMD0     0xFF000000
> -#define FCR_CMD0_SHIFT       24
> -#define FCR_CMD1     0x00FF0000
> -#define FCR_CMD1_SHIFT       16
> -#define FCR_CMD2     0x0000FF00
> -#define FCR_CMD2_SHIFT        8
> -#define FCR_CMD3     0x000000FF
> -#define FCR_CMD3_SHIFT        0
> -	__be32 fbar;            /**< Flash Block Address Register */
> -#define FBAR_BLK     0x00FFFFFF
> -	__be32 fpar;            /**< Flash Page Address Register */
> -#define FPAR_SP_PI   0x00007C00
> -#define FPAR_SP_PI_SHIFT     10
> -#define FPAR_SP_MS   0x00000200
> -#define FPAR_SP_CI   0x000001FF
> -#define FPAR_SP_CI_SHIFT      0
> -#define FPAR_LP_PI   0x0003F000
> -#define FPAR_LP_PI_SHIFT     12
> -#define FPAR_LP_MS   0x00000800
> -#define FPAR_LP_CI   0x000007FF
> -#define FPAR_LP_CI_SHIFT      0
> -	__be32 fbcr;            /**< Flash Byte Count Register */
> -#define FBCR_BC      0x00000FFF
> -	u8 res11[0x8];
> -	u8 res8[0xF00];
> -};
> -
> struct fsl_elbc_ctrl;
>
> /* mtd information per set */
> @@ -261,7 +66,7 @@ struct fsl_elbc_ctrl {
>
> 	/* device info */
> 	struct device *dev;
> -	struct elbc_regs __iomem *regs;
> +	struct fsl_lbc_regs __iomem *regs;
> 	int irq;
> 	wait_queue_head_t irq_wait;
> 	unsigned int irq_status; /* status read from LTESR by irq handler */
> @@ -322,7 +127,7 @@ static void set_addr(struct mtd_info *mtd, int  
> column, int page_addr, int oob)
> 	struct nand_chip *chip = mtd->priv;
> 	struct fsl_elbc_mtd *priv = chip->priv;
> 	struct fsl_elbc_ctrl *ctrl = priv->ctrl;
> -	struct elbc_regs __iomem *lbc = ctrl->regs;
> +	struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
> 	int buf_num;
>
> 	ctrl->page = page_addr;
> @@ -363,7 +168,7 @@ static int fsl_elbc_run_command(struct mtd_info  
> *mtd)
> 	struct nand_chip *chip = mtd->priv;
> 	struct fsl_elbc_mtd *priv = chip->priv;
> 	struct fsl_elbc_ctrl *ctrl = priv->ctrl;
> -	struct elbc_regs __iomem *lbc = ctrl->regs;
> +	struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
>
> 	/* Setup the FMR[OP] to execute without write protection */
> 	out_be32(&lbc->fmr, priv->fmr | 3);
> @@ -406,7 +211,7 @@ static void fsl_elbc_do_read(struct nand_chip  
> *chip, int oob)
> {
> 	struct fsl_elbc_mtd *priv = chip->priv;
> 	struct fsl_elbc_ctrl *ctrl = priv->ctrl;
> -	struct elbc_regs __iomem *lbc = ctrl->regs;
> +	struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
>
> 	if (priv->page_size) {
> 		out_be32(&lbc->fir,
> @@ -439,7 +244,7 @@ static void fsl_elbc_cmdfunc(struct mtd_info  
> *mtd, unsigned int command,
> 	struct nand_chip *chip = mtd->priv;
> 	struct fsl_elbc_mtd *priv = chip->priv;
> 	struct fsl_elbc_ctrl *ctrl = priv->ctrl;
> -	struct elbc_regs __iomem *lbc = ctrl->regs;
> +	struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
>
> 	ctrl->use_mdr = 0;
>
> @@ -775,7 +580,7 @@ static int fsl_elbc_wait(struct mtd_info *mtd,  
> struct nand_chip *chip)
> {
> 	struct fsl_elbc_mtd *priv = chip->priv;
> 	struct fsl_elbc_ctrl *ctrl = priv->ctrl;
> -	struct elbc_regs __iomem *lbc = ctrl->regs;
> +	struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
>
> 	if (ctrl->status != LTESR_CC)
> 		return NAND_STATUS_FAIL;
> @@ -807,7 +612,7 @@ static int fsl_elbc_chip_init_tail(struct  
> mtd_info *mtd)
> 	struct nand_chip *chip = mtd->priv;
> 	struct fsl_elbc_mtd *priv = chip->priv;
> 	struct fsl_elbc_ctrl *ctrl = priv->ctrl;
> -	struct elbc_regs __iomem *lbc = ctrl->regs;
> +	struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
> 	unsigned int al;
>
> 	/* calculate FMR Address Length field */
> @@ -922,7 +727,7 @@ static void fsl_elbc_write_page(struct mtd_info  
> *mtd,
> static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
> {
> 	struct fsl_elbc_ctrl *ctrl = priv->ctrl;
> -	struct elbc_regs __iomem *lbc = ctrl->regs;
> +	struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
> 	struct nand_chip *chip = &priv->chip;
>
> 	dev_dbg(priv->dev, "eLBC Set Information for bank %d\n", priv->bank);
> @@ -986,7 +791,7 @@ static int fsl_elbc_chip_remove(struct  
> fsl_elbc_mtd *priv)
> static int fsl_elbc_chip_probe(struct fsl_elbc_ctrl *ctrl,
>                                struct device_node *node)
> {
> -	struct elbc_regs __iomem *lbc = ctrl->regs;
> +	struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
> 	struct fsl_elbc_mtd *priv;
> 	struct resource res;
> #ifdef CONFIG_MTD_PARTITIONS
> @@ -1083,7 +888,7 @@ err:
>
> static int __devinit fsl_elbc_ctrl_init(struct fsl_elbc_ctrl *ctrl)
> {
> -	struct elbc_regs __iomem *lbc = ctrl->regs;
> +	struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
>
> 	/* clear event registers */
> 	setbits32(&lbc->ltesr, LTESR_NAND_MASK);
> @@ -1128,7 +933,7 @@ static int __devexit  
> fsl_elbc_ctrl_remove(struct of_device *ofdev)
> static irqreturn_t fsl_elbc_ctrl_irq(int irqno, void *data)
> {
> 	struct fsl_elbc_ctrl *ctrl = data;
> -	struct elbc_regs __iomem *lbc = ctrl->regs;
> +	struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
> 	__be32 status = in_be32(&lbc->ltesr) & LTESR_NAND_MASK;
>
> 	if (status) {
> diff --git a/include/asm-powerpc/fsl_lbc.h b/include/asm-powerpc/ 
> fsl_lbc.h
> new file mode 100644
> index 0000000..13a3c28
> --- /dev/null
> +++ b/include/asm-powerpc/fsl_lbc.h
> @@ -0,0 +1,223 @@
> +/* Freescale Local Bus Controller
> + *
> + * Copyright (c) 2006-2007 Freescale Semiconductor
> + *
> + * Authors: Nick Spence <nick.spence@freescale.com>,
> + *          Scott Wood <scottwood@freescale.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 of the License, or
> + * (at your option) any later version.
> + *
> + * 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
> + */
> +
> +#ifndef __ASM_FSL_LBC_H
> +#define __ASM_FSL_LBC_H
> +
> +#include <linux/types.h>
> +
> +struct fsl_lbc_bank {
> +	__be32 br;             /**< Base Register  */
> +#define BR_BA           0xFFFF8000
> +#define BR_BA_SHIFT             15
> +#define BR_PS           0x00001800
> +#define BR_PS_SHIFT             11
> +#define BR_PS_8         0x00000800  /* Port Size 8 bit */
> +#define BR_PS_16        0x00001000  /* Port Size 16 bit */
> +#define BR_PS_32        0x00001800  /* Port Size 32 bit */
> +#define BR_DECC         0x00000600
> +#define BR_DECC_SHIFT            9
> +#define BR_DECC_OFF     0x00000000  /* HW ECC checking and  
> generation off */
> +#define BR_DECC_CHK     0x00000200  /* HW ECC checking on,  
> generation off */
> +#define BR_DECC_CHK_GEN 0x00000400  /* HW ECC checking and  
> generation on */
> +#define BR_WP           0x00000100
> +#define BR_WP_SHIFT              8
> +#define BR_MSEL         0x000000E0
> +#define BR_MSEL_SHIFT            5
> +#define BR_MS_GPCM      0x00000000  /* GPCM */
> +#define BR_MS_FCM       0x00000020  /* FCM */
> +#define BR_MS_SDRAM     0x00000060  /* SDRAM */
> +#define BR_MS_UPMA      0x00000080  /* UPMA */
> +#define BR_MS_UPMB      0x000000A0  /* UPMB */
> +#define BR_MS_UPMC      0x000000C0  /* UPMC */
> +#define BR_V            0x00000001
> +#define BR_V_SHIFT               0
> +#define BR_RES          ~(BR_BA|BR_PS|BR_DECC|BR_WP|BR_MSEL|BR_V)
> +
> +	__be32 or;             /**< Base Register  */
> +#define OR0 0x5004
> +#define OR1 0x500C
> +#define OR2 0x5014
> +#define OR3 0x501C
> +#define OR4 0x5024
> +#define OR5 0x502C
> +#define OR6 0x5034
> +#define OR7 0x503C
> +
> +#define OR_FCM_AM               0xFFFF8000
> +#define OR_FCM_AM_SHIFT                 15
> +#define OR_FCM_BCTLD            0x00001000
> +#define OR_FCM_BCTLD_SHIFT              12
> +#define OR_FCM_PGS              0x00000400
> +#define OR_FCM_PGS_SHIFT                10
> +#define OR_FCM_CSCT             0x00000200
> +#define OR_FCM_CSCT_SHIFT                9
> +#define OR_FCM_CST              0x00000100
> +#define OR_FCM_CST_SHIFT                 8
> +#define OR_FCM_CHT              0x00000080
> +#define OR_FCM_CHT_SHIFT                 7
> +#define OR_FCM_SCY              0x00000070
> +#define OR_FCM_SCY_SHIFT                 4
> +#define OR_FCM_SCY_1            0x00000010
> +#define OR_FCM_SCY_2            0x00000020
> +#define OR_FCM_SCY_3            0x00000030
> +#define OR_FCM_SCY_4            0x00000040
> +#define OR_FCM_SCY_5            0x00000050
> +#define OR_FCM_SCY_6            0x00000060
> +#define OR_FCM_SCY_7            0x00000070
> +#define OR_FCM_RST              0x00000008
> +#define OR_FCM_RST_SHIFT                 3
> +#define OR_FCM_TRLX             0x00000004
> +#define OR_FCM_TRLX_SHIFT                2
> +#define OR_FCM_EHTR             0x00000002
> +#define OR_FCM_EHTR_SHIFT                1
> +};
> +
> +struct fsl_lbc_regs {
> +	struct fsl_lbc_bank bank[8];
> +	u8 res0[0x28];
> +	__be32 mar;             /**< UPM Address Register */
> +	u8 res1[0x4];
> +	__be32 mamr;            /**< UPMA Mode Register */
> +	__be32 mbmr;            /**< UPMB Mode Register */
> +	__be32 mcmr;            /**< UPMC Mode Register */
> +	u8 res2[0x8];
> +	__be32 mrtpr;           /**< Memory Refresh Timer Prescaler  
> Register */
> +	__be32 mdr;             /**< UPM Data Register */
> +	u8 res3[0x4];
> +	__be32 lsor;            /**< Special Operation Initiation Register  
> */
> +	__be32 lsdmr;           /**< SDRAM Mode Register */
> +	u8 res4[0x8];
> +	__be32 lurt;            /**< UPM Refresh Timer */
> +	__be32 lsrt;            /**< SDRAM Refresh Timer */
> +	u8 res5[0x8];
> +	__be32 ltesr;           /**< Transfer Error Status Register */
> +#define LTESR_BM   0x80000000
> +#define LTESR_FCT  0x40000000
> +#define LTESR_PAR  0x20000000
> +#define LTESR_WP   0x04000000
> +#define LTESR_ATMW 0x00800000
> +#define LTESR_ATMR 0x00400000
> +#define LTESR_CS   0x00080000
> +#define LTESR_CC   0x00000001
> +#define LTESR_NAND_MASK (LTESR_FCT | LTESR_PAR | LTESR_CC)
> +	__be32 ltedr;           /**< Transfer Error Disable Register */
> +	__be32 lteir;           /**< Transfer Error Interrupt Register */
> +	__be32 lteatr;          /**< Transfer Error Attributes Register */
> +	__be32 ltear;           /**< Transfer Error Address Register */
> +	u8 res6[0xC];
> +	__be32 lbcr;            /**< Configuration Register */
> +#define LBCR_LDIS  0x80000000
> +#define LBCR_LDIS_SHIFT    31
> +#define LBCR_BCTLC 0x00C00000
> +#define LBCR_BCTLC_SHIFT   22
> +#define LBCR_AHD   0x00200000
> +#define LBCR_LPBSE 0x00020000
> +#define LBCR_LPBSE_SHIFT   17
> +#define LBCR_EPAR  0x00010000
> +#define LBCR_EPAR_SHIFT    16
> +#define LBCR_BMT   0x0000FF00
> +#define LBCR_BMT_SHIFT      8
> +#define LBCR_INIT  0x00040000
> +	__be32 lcrr;            /**< Clock Ratio Register */
> +#define LCRR_DBYP    0x80000000
> +#define LCRR_DBYP_SHIFT      31
> +#define LCRR_BUFCMDC 0x30000000
> +#define LCRR_BUFCMDC_SHIFT   28
> +#define LCRR_ECL     0x03000000
> +#define LCRR_ECL_SHIFT       24
> +#define LCRR_EADC    0x00030000
> +#define LCRR_EADC_SHIFT      16
> +#define LCRR_CLKDIV  0x0000000F
> +#define LCRR_CLKDIV_SHIFT     0
> +	u8 res7[0x8];
> +	__be32 fmr;             /**< Flash Mode Register */
> +#define FMR_CWTO     0x0000F000
> +#define FMR_CWTO_SHIFT       12
> +#define FMR_BOOT     0x00000800
> +#define FMR_ECCM     0x00000100
> +#define FMR_AL       0x00000030
> +#define FMR_AL_SHIFT          4
> +#define FMR_OP       0x00000003
> +#define FMR_OP_SHIFT          0
> +	__be32 fir;             /**< Flash Instruction Register */
> +#define FIR_OP0      0xF0000000
> +#define FIR_OP0_SHIFT        28
> +#define FIR_OP1      0x0F000000
> +#define FIR_OP1_SHIFT        24
> +#define FIR_OP2      0x00F00000
> +#define FIR_OP2_SHIFT        20
> +#define FIR_OP3      0x000F0000
> +#define FIR_OP3_SHIFT        16
> +#define FIR_OP4      0x0000F000
> +#define FIR_OP4_SHIFT        12
> +#define FIR_OP5      0x00000F00
> +#define FIR_OP5_SHIFT         8
> +#define FIR_OP6      0x000000F0
> +#define FIR_OP6_SHIFT         4
> +#define FIR_OP7      0x0000000F
> +#define FIR_OP7_SHIFT         0
> +#define FIR_OP_NOP   0x0	/* No operation and end of sequence */
> +#define FIR_OP_CA    0x1        /* Issue current column address */
> +#define FIR_OP_PA    0x2        /* Issue current block+page address  
> */
> +#define FIR_OP_UA    0x3        /* Issue user defined address */
> +#define FIR_OP_CM0   0x4        /* Issue command from FCR[CMD0] */
> +#define FIR_OP_CM1   0x5        /* Issue command from FCR[CMD1] */
> +#define FIR_OP_CM2   0x6        /* Issue command from FCR[CMD2] */
> +#define FIR_OP_CM3   0x7        /* Issue command from FCR[CMD3] */
> +#define FIR_OP_WB    0x8        /* Write FBCR bytes from FCM buffer  
> */
> +#define FIR_OP_WS    0x9        /* Write 1 or 2 bytes from MDR[AS] */
> +#define FIR_OP_RB    0xA        /* Read FBCR bytes to FCM buffer */
> +#define FIR_OP_RS    0xB        /* Read 1 or 2 bytes to MDR[AS] */
> +#define FIR_OP_CW0   0xC        /* Wait then issue FCR[CMD0] */
> +#define FIR_OP_CW1   0xD        /* Wait then issue FCR[CMD1] */
> +#define FIR_OP_RBW   0xE        /* Wait then read FBCR bytes */
> +#define FIR_OP_RSW   0xE        /* Wait then read 1 or 2 bytes */
> +	__be32 fcr;             /**< Flash Command Register */
> +#define FCR_CMD0     0xFF000000
> +#define FCR_CMD0_SHIFT       24
> +#define FCR_CMD1     0x00FF0000
> +#define FCR_CMD1_SHIFT       16
> +#define FCR_CMD2     0x0000FF00
> +#define FCR_CMD2_SHIFT        8
> +#define FCR_CMD3     0x000000FF
> +#define FCR_CMD3_SHIFT        0
> +	__be32 fbar;            /**< Flash Block Address Register */
> +#define FBAR_BLK     0x00FFFFFF
> +	__be32 fpar;            /**< Flash Page Address Register */
> +#define FPAR_SP_PI   0x00007C00
> +#define FPAR_SP_PI_SHIFT     10
> +#define FPAR_SP_MS   0x00000200
> +#define FPAR_SP_CI   0x000001FF
> +#define FPAR_SP_CI_SHIFT      0
> +#define FPAR_LP_PI   0x0003F000
> +#define FPAR_LP_PI_SHIFT     12
> +#define FPAR_LP_MS   0x00000800
> +#define FPAR_LP_CI   0x000007FF
> +#define FPAR_LP_CI_SHIFT      0
> +	__be32 fbcr;            /**< Flash Byte Count Register */
> +#define FBCR_BC      0x00000FFF
> +	u8 res11[0x8];
> +	u8 res8[0xF00];
> +};
> +
> +#endif /* __ASM_FSL_LBC_H */
> -- 
> 1.5.2.2
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* [PATCH0/7] OF support for i2c bus drivers
From: Jochen Friedrich @ 2008-04-11 14:06 UTC (permalink / raw)
  To: Kumar Gala
  Cc: linuxppc-dev list, Kernel, Linux, Scott Wood, Jean Delvare,
	Linux I2C

This series of patches implements the framework needed by of_platform_driver i2c bus drivers.
i2c-mpc is then converted to an of_platform_driver and i2c-cpm is added as new driver.

This is based on earlier work by Jon Smirl and Jean Delvare.

[PATCH1/7] i2c: Add support for device alias names
[PATCH2/7] i2c: Convert all new-style drivers to use module aliasing
[PATCH3/7] i2c: OF helpers for the i2c API
[PATCH4/7] i2c: Convert PowerPC MPC i2c to of_platform_driver from platform_driver
[PATCH5/7] i2c: Kill the old driver matching scheme
[PATCH6/7] i2c: adds support for i2c bus on Freescale CPM1/CPM2 controllers
[PATCH7/7] [POWERPC] Add i2c pins to dts and board setup

Thanks,
Jochen

^ permalink raw reply

* Re: zImage.embedded
From: Grant Likely @ 2008-04-11 13:55 UTC (permalink / raw)
  To: Guillaume Dargaud; +Cc: linuxppc-dev
In-Reply-To: <014701c89bda$09380060$ad289e86@LPSC0173W>

On Fri, Apr 11, 2008 at 7:43 AM, Guillaume Dargaud
<dargaud@lpsc.in2p3.fr> wrote:
> Hello all,
>
>  I'm not sure what kind of error this is. I'm trying to generate a kernel
> image suitable for network boot and it seems to fail at the very end (wrong
> target ?)
>
>  $ make ARCH=ppc CROSS_COMPILE=powerpc-linux-uclibc-  znetboot
>
>  powerpc-linux-uclibc-objcopy -O elf32-powerpc arch/ppc/boot/simple/zvmlinux
> arch/ppc/boot/simple/zvmlinux -R .comment -R .stab \
>                -R .stabstr -R .ramdisk
>  cp -f arch/ppc/boot/simple/zvmlinux arch/ppc/boot/images/zImage.elf
>  rm -f arch/ppc/boot/simple/zvmlinux
>  cp arch/ppc/boot/images/zImage.embedded /tftpboot/zImage.embedded
>  cp: cannot stat `arch/ppc/boot/images/zImage.embedded': No such file or
> directory
>  make[2]: *** [znetboot] Error 1
>  make[1]: *** [simple] Error 2
>  make: *** [znetboot] Error 2
>
>  is the file zImage.elf my proper network image ?

What bootloader is on your board?  zImage.elf *might* be the proper
image.  If you're using u-boot, then you want to build a uImage
instead.

Cheers,
g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply

* Re: [PATCH 1/5] phylib: don't create a phydev for ID-less PHYs.
From: Grant Likely @ 2008-04-11 13:54 UTC (permalink / raw)
  To: joakim.tjernlund
  Cc: scottwood, linuxppc-dev, Stefan Roese, Paul Gortmaker, linux-net
In-Reply-To: <1207910826.9544.26.camel@gentoo-jocke.transmode.se>

On Fri, Apr 11, 2008 at 4:47 AM, Joakim Tjernlund
<joakim.tjernlund@transmode.se> wrote:
>
>  On Fri, 2008-04-11 at 10:06 +0200, Stefan Roese wrote:
>  > On Friday 11 April 2008, Joakim Tjernlund wrote:
>  > > PHY ID 0x0 isn't an invalid id, I got a Broadcom PHY that has
>  > > PHY ID=0. Maybe I am misunderstanding something?
>  >
>  > IIRC, address 0 is the PHY broadcast address, but can be used without problem
>  > with some PHY's. I remember some designs were we had the PHY at address 0.
>
>  Ouh, if that is so, I guess we need a CONFIG option or a new mdio bus
>  property to select if PHY ID 0 is valid id or not.

Or, don't probe for phys by default.  Rather, use the data in the
device tree to determine what PHY ids are valid.

Cheers,
g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply

* Re: State of the MPC5200 PSC AC97 driver
From: Grant Likely @ 2008-04-11 13:50 UTC (permalink / raw)
  To: Marian Balakowicz; +Cc: Sven Luther, spitzauer_77, linuxppc-dev
In-Reply-To: <47FF2DFA.2060003@semihalf.com>

On Fri, Apr 11, 2008 at 3:23 AM, Marian Balakowicz <m8@semihalf.com> wrote:
>
>  All,
>
>  Thanks for the input and comments.
>
>  I am also having a look at the I2S driver. There were attempts some
>  time ago and I found few pieces of code floating on net but couldn't
>  find anything cleaned up. Did anyone tried to put the results of those
>  attempts together?

I'm actually working on the I2S driver now and I'll probably have
something to post about a month from now.  This is funded development,
so I'll actually have lots of time to spend on it when I get back from
ELC.

Cheers,
g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply

* zImage.embedded
From: Guillaume Dargaud @ 2008-04-11 13:43 UTC (permalink / raw)
  To: linuxppc-dev

Hello all,

I'm not sure what kind of error this is. I'm trying to generate a kernel 
image suitable for network boot and it seems to fail at the very end (wrong 
target ?)

$ make ARCH=ppc CROSS_COMPILE=powerpc-linux-uclibc-  znetboot

powerpc-linux-uclibc-objcopy -O elf32-powerpc arch/ppc/boot/simple/zvmlinux 
arch/ppc/boot/simple/zvmlinux -R .comment -R .stab \
                -R .stabstr -R .ramdisk
cp -f arch/ppc/boot/simple/zvmlinux arch/ppc/boot/images/zImage.elf
rm -f arch/ppc/boot/simple/zvmlinux
cp arch/ppc/boot/images/zImage.embedded /tftpboot/zImage.embedded
cp: cannot stat `arch/ppc/boot/images/zImage.embedded': No such file or 
directory
make[2]: *** [znetboot] Error 1
make[1]: *** [simple] Error 2
make: *** [znetboot] Error 2

is the file zImage.elf my proper network image ?
-- 
Guillaume Dargaud
http://www.gdargaud.net/

^ permalink raw reply

* [PATCH 1/2] OF helpers for the GPIO API
From: Anton Vorontsov @ 2008-04-11 13:06 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, David Miller
In-Reply-To: <20080411130537.GA10608@polina.dev.rtsoft.ru>

This patch implements various helpers to support OF bindings for
the GPIO LIB API.

Previously this was PowerPC specific, but it seems this code
isn't arch-dependent anyhow, so let's place it into of/.

SPARC will not see this addition yet, real hardware seem to not use
GPIOs at all. But this might change:

   http://www.leox.org/docs/faq_MLleon.html

"16-bit I/O port" sounds promising. :-)

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 drivers/of/Kconfig      |    6 +
 drivers/of/Makefile     |    1 +
 drivers/of/gpio.c       |  242 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of_gpio.h |   69 +++++++++++++
 4 files changed, 318 insertions(+), 0 deletions(-)
 create mode 100644 drivers/of/gpio.c
 create mode 100644 include/linux/of_gpio.h

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index c03072b..3354ad7 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -1,3 +1,9 @@
 config OF_DEVICE
 	def_bool y
 	depends on OF && (SPARC || PPC_OF)
+
+config OF_GPIO
+	def_bool y
+	depends on OF && PPC_OF && HAVE_GPIO_LIB
+	help
+	  OpenFirmware GPIO accessors
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index ab9be5d..5a61f70 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -1,2 +1,3 @@
 obj-y = base.o
 obj-$(CONFIG_OF_DEVICE) += device.o platform.o
+obj-$(CONFIG_OF_GPIO)   += gpio.o
diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c
new file mode 100644
index 0000000..000681e
--- /dev/null
+++ b/drivers/of/gpio.c
@@ -0,0 +1,242 @@
+/*
+ * OF helpers for the GPIO API
+ *
+ * Copyright (c) 2007-2008  MontaVista Software, Inc.
+ *
+ * Author: Anton Vorontsov <avorontsov@ru.mvista.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 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <asm/prom.h>
+
+/**
+ * of_get_gpio - Get a GPIO number from the device tree to use with GPIO API
+ * @np:		device node to get GPIO from
+ * @index:	index of the GPIO
+ *
+ * Returns GPIO number to use with Linux generic GPIO API, or one of the errno
+ * value on the error condition.
+ */
+int of_get_gpio(struct device_node *np, int index)
+{
+	int ret = -EINVAL;
+	struct device_node *gc;
+	struct of_gpio_chip *of_gc = NULL;
+	int size;
+	const u32 *gpios;
+	u32 nr_cells;
+	int i;
+	const void *gpio_spec;
+	const u32 *gpio_cells;
+	int gpio_index = 0;
+
+	gpios = of_get_property(np, "gpios", &size);
+	if (!gpios) {
+		ret = -ENOENT;
+		goto err0;
+	}
+	nr_cells = size / sizeof(u32);
+
+	for (i = 0; i < nr_cells; gpio_index++) {
+		const phandle *gpio_phandle;
+
+		gpio_phandle = gpios + i;
+		gpio_spec = gpio_phandle + 1;
+
+		/* one cell hole in the gpios = <>; */
+		if (!*gpio_phandle) {
+			if (gpio_index == index)
+				return -ENOENT;
+			i++;
+			continue;
+		}
+
+		gc = of_find_node_by_phandle(*gpio_phandle);
+		if (!gc) {
+			pr_debug("%s: could not find phandle for gpios\n",
+				 np->full_name);
+			goto err0;
+		}
+
+		of_gc = gc->data;
+		if (!of_gc) {
+			pr_debug("%s: gpio controller %s isn't registered\n",
+				 np->full_name, gc->full_name);
+			goto err1;
+		}
+
+		gpio_cells = of_get_property(gc, "#gpio-cells", &size);
+		if (!gpio_cells || size != sizeof(*gpio_cells) ||
+				*gpio_cells != of_gc->gpio_cells) {
+			pr_debug("%s: wrong #gpio-cells for %s\n",
+				 np->full_name, gc->full_name);
+			goto err1;
+		}
+
+		/* Next phandle is at phandle cells + #gpio-cells */
+		i += sizeof(*gpio_phandle) / sizeof(u32) + *gpio_cells;
+		if (i >= nr_cells + 1) {
+			pr_debug("%s: insufficient gpio-spec length\n",
+				 np->full_name);
+			goto err1;
+		}
+
+		if (gpio_index == index)
+			break;
+
+		of_gc = NULL;
+		of_node_put(gc);
+	}
+
+	if (!of_gc) {
+		ret = -ENOENT;
+		goto err0;
+	}
+
+	ret = of_gc->xlate(of_gc, np, gpio_spec);
+	if (ret < 0)
+		goto err1;
+
+	ret += of_gc->gc.base;
+err1:
+	of_node_put(gc);
+err0:
+	pr_debug("%s exited with status %d\n", __func__, ret);
+	return ret;
+}
+EXPORT_SYMBOL(of_get_gpio);
+
+/**
+ * of_gpio_simple_xlate - translate gpio_spec to the GPIO number
+ * @of_gc:	pointer to the of_gpio_chip structure
+ * @np:		device node of the GPIO chip
+ * @gpio_spec:	gpio specifier as found in the device tree
+ *
+ * This is simple translation function, suitable for the most 1:1 mapped
+ * gpio chips. This function performs only one sanity check: whether gpio
+ * is less than ngpios (that is specified in the gpio_chip).
+ */
+int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, struct device_node *np,
+			 const void *gpio_spec)
+{
+	const u32 *gpio = gpio_spec;
+
+	if (*gpio > of_gc->gc.ngpio)
+		return -EINVAL;
+
+	return *gpio;
+}
+EXPORT_SYMBOL(of_gpio_simple_xlate);
+
+/* Should be sufficient for now, later we'll use dynamic bases. */
+#if defined(CONFIG_PPC32) || defined(CONFIG_SPARC32)
+#define GPIOS_PER_CHIP 32
+#else
+#define GPIOS_PER_CHIP 64
+#endif
+
+static int of_get_gpiochip_base(struct device_node *np)
+{
+	struct device_node *gc = NULL;
+	int gpiochip_base = 0;
+
+	while ((gc = of_find_all_nodes(gc))) {
+		if (!of_get_property(gc, "gpio-controller", NULL))
+			continue;
+
+		if (gc != np) {
+			gpiochip_base += GPIOS_PER_CHIP;
+			continue;
+		}
+
+		of_node_put(gc);
+
+		if (gpiochip_base >= ARCH_NR_GPIOS)
+			return -ENOSPC;
+
+		return gpiochip_base;
+	}
+
+	return -ENOENT;
+}
+
+/**
+ * of_mm_gpiochip_add - Add memory mapped GPIO chip (bank)
+ * @np:		device node of the GPIO chip
+ * @mm_gc:	pointer to the of_mm_gpio_chip allocated structure
+ *
+ * To use this function you should allocate and fill mm_gc with:
+ *
+ * 1) In the gpio_chip structure:
+ *    - all the callbacks
+ *
+ * 2) In the of_gpio_chip structure:
+ *    - gpio_cells
+ *    - xlate callback (optional)
+ *
+ * 3) In the of_mm_gpio_chip structure:
+ *    - save_regs callback (optional)
+ *
+ * If succeeded, this function will map bank's memory and will
+ * do all necessary work for you. Then you'll able to use .regs
+ * to manage GPIOs from the callbacks.
+ */
+int of_mm_gpiochip_add(struct device_node *np,
+		       struct of_mm_gpio_chip *mm_gc)
+{
+	int ret = -ENOMEM;
+	struct of_gpio_chip *of_gc = &mm_gc->of_gc;
+	struct gpio_chip *gc = &of_gc->gc;
+
+	gc->label = kstrdup(np->full_name, GFP_KERNEL);
+	if (!gc->label)
+		goto err0;
+
+	mm_gc->regs = of_iomap(np, 0);
+	if (!mm_gc->regs)
+		goto err1;
+
+	gc->base = of_get_gpiochip_base(np);
+	if (gc->base < 0) {
+		ret = gc->base;
+		goto err1;
+	}
+
+	if (!of_gc->xlate)
+		of_gc->xlate = of_gpio_simple_xlate;
+
+	if (mm_gc->save_regs)
+		mm_gc->save_regs(mm_gc);
+
+	np->data = of_gc;
+
+	ret = gpiochip_add(gc);
+	if (ret)
+		goto err2;
+
+	/* We don't want to lose the node and its ->data */
+	of_node_get(np);
+
+	pr_debug("%s: registered as generic GPIO chip, base is %d\n",
+		 np->full_name, gc->base);
+	return 0;
+err2:
+	np->data = NULL;
+	iounmap(mm_gc->regs);
+err1:
+	kfree(gc->label);
+err0:
+	pr_err("%s: GPIO chip registration failed with status %d\n",
+	       np->full_name, ret);
+	return ret;
+}
+EXPORT_SYMBOL(of_mm_gpiochip_add);
diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h
new file mode 100644
index 0000000..2ee97e9
--- /dev/null
+++ b/include/linux/of_gpio.h
@@ -0,0 +1,69 @@
+/*
+ * OF helpers for the GPIO API
+ *
+ * Copyright (c) 2007-2008  MontaVista Software, Inc.
+ *
+ * Author: Anton Vorontsov <avorontsov@ru.mvista.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 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __LINUX_OF_GPIO_H
+#define __LINUX_OF_GPIO_H
+
+#include <linux/errno.h>
+#include <asm/gpio.h>
+
+#ifdef CONFIG_OF_GPIO
+
+/*
+ * Generic OF GPIO chip
+ */
+struct of_gpio_chip {
+	struct gpio_chip gc;
+	int gpio_cells;
+	int (*xlate)(struct of_gpio_chip *of_gc, struct device_node *np,
+		     const void *gpio_spec);
+};
+
+static inline struct of_gpio_chip *to_of_gpio_chip(struct gpio_chip *gc)
+{
+	return container_of(gc, struct of_gpio_chip, gc);
+}
+
+/*
+ * OF GPIO chip for memory mapped banks
+ */
+struct of_mm_gpio_chip {
+	struct of_gpio_chip of_gc;
+	void (*save_regs)(struct of_mm_gpio_chip *mm_gc);
+	void __iomem *regs;
+};
+
+static inline struct of_mm_gpio_chip *to_of_mm_gpio_chip(struct gpio_chip *gc)
+{
+	struct of_gpio_chip *of_gc = to_of_gpio_chip(gc);
+
+	return container_of(of_gc, struct of_mm_gpio_chip, of_gc);
+}
+
+extern int of_get_gpio(struct device_node *np, int index);
+extern int of_mm_gpiochip_add(struct device_node *np,
+			      struct of_mm_gpio_chip *mm_gc);
+extern int of_gpio_simple_xlate(struct of_gpio_chip *of_gc,
+				struct device_node *np,
+				const void *gpio_spec);
+#else
+
+/* Drivers may not strictly depend on the GPIO support, so let them link. */
+static inline int of_get_gpio(struct device_node *np, int index)
+{
+	return -ENOSYS;
+}
+
+#endif /* CONFIG_OF_GPIO */
+
+#endif /* __LINUX_OF_GPIO_H */
-- 
1.5.4.5

^ permalink raw reply related

* [PATCH 2/2] [POWERPC] Implement support for the GPIO LIB API
From: Anton Vorontsov @ 2008-04-11 13:06 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, David Miller
In-Reply-To: <20080411130537.GA10608@polina.dev.rtsoft.ru>

This patch implements support for the GPIO LIB API. Two calls
unimplemented though: irq_to_gpio and gpio_to_irq.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 Documentation/powerpc/booting-without-of.txt |   52 ++++++++++++++++++++++++
 arch/powerpc/Kconfig                         |    5 ++
 include/asm-powerpc/gpio.h                   |   56 ++++++++++++++++++++++++++
 3 files changed, 113 insertions(+), 0 deletions(-)
 create mode 100644 include/asm-powerpc/gpio.h

diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index b506245..e9e0c2f 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -66,6 +66,10 @@ Table of Contents
     3) OpenPIC Interrupt Controllers
     4) ISA Interrupt Controllers
 
+  VIII - Specifying GPIO information for devices
+    1) gpios property
+    2) gpio-controller nodes
+
   Appendix A - Sample SOC node for MPC8540
 
 
@@ -2925,6 +2929,54 @@ encodings listed below:
 	2 =  high to low edge sensitive type enabled
 	3 =  low to high edge sensitive type enabled
 
+VIII - Specifying GPIO information for devices
+==============================================
+
+1) gpios property
+-----------------
+
+Nodes that makes use of GPIOs should define them using `gpios' property,
+format of which is: <&gpio-controller1-phandle gpio1-specifier
+		     &gpio-controller2-phandle gpio2-specifier
+		     0 /* holes are permitted, means no GPIO 3 */
+		     &gpio-controller4-phandle gpio4-specifier
+		     ...>;
+
+Note that gpio-specifier length is controller dependent.
+
+gpio-specifier may encode: bank, pin position inside the bank,
+whether pin is open-drain and whether pin is logically inverted.
+
+Example of the node using GPIOs:
+
+	node {
+		gpios = <&qe_pio_e 18 0>;
+	};
+
+In this example gpio-specifier is "18 0" and encodes GPIO pin number,
+and empty GPIO flags as accepted by the "qe_pio_e" gpio-controller.
+
+2) gpio-controller nodes
+------------------------
+
+Every GPIO controller node must have #gpio-cells property defined,
+this information will be used to translate gpio-specifiers.
+
+Example of two SOC GPIO banks defined as gpio-controller nodes:
+
+	qe_pio_a: gpio-controller@1400 {
+		#gpio-cells = <2>;
+		compatible = "fsl,qe-pario-bank-a", "fsl,qe-pario-bank";
+		reg = <0x1400 0x18>;
+		gpio-controller;
+	};
+
+	qe_pio_e: gpio-controller@1460 {
+		#gpio-cells = <2>;
+		compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank";
+		reg = <0x1460 0x18>;
+		gpio-controller;
+	};
 
 Appendix A - Sample SOC node for MPC8540
 ========================================
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 0b27cbd..f328509 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -81,6 +81,11 @@ config GENERIC_FIND_NEXT_BIT
 	bool
 	default y
 
+config GENERIC_GPIO
+	bool
+	help
+	  Generic GPIO API support
+
 config ARCH_NO_VIRT_TO_BUS
 	def_bool PPC64
 
diff --git a/include/asm-powerpc/gpio.h b/include/asm-powerpc/gpio.h
new file mode 100644
index 0000000..77ad3a8
--- /dev/null
+++ b/include/asm-powerpc/gpio.h
@@ -0,0 +1,56 @@
+/*
+ * Generic GPIO API implementation for PowerPC.
+ *
+ * Copyright (c) 2007-2008  MontaVista Software, Inc.
+ *
+ * Author: Anton Vorontsov <avorontsov@ru.mvista.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 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __ASM_POWERPC_GPIO_H
+#define __ASM_POWERPC_GPIO_H
+
+#include <linux/errno.h>
+#include <asm-generic/gpio.h>
+
+#ifdef CONFIG_HAVE_GPIO_LIB
+
+/*
+ * We don't (yet) implement inlined/rapid versions for on-chip gpios.
+ * Just call gpiolib.
+ */
+static inline int gpio_get_value(unsigned int gpio)
+{
+	return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned int gpio, int value)
+{
+	__gpio_set_value(gpio, value);
+}
+
+static inline int gpio_cansleep(unsigned int gpio)
+{
+	return __gpio_cansleep(gpio);
+}
+
+/*
+ * Not implemented, yet.
+ */
+static inline int gpio_to_irq(unsigned int gpio)
+{
+	return -ENOSYS;
+}
+
+static inline int irq_to_gpio(unsigned int irq)
+{
+	return -EINVAL;
+}
+
+#endif /* CONFIG_HAVE_GPIO_LIB */
+
+#endif /* __ASM_POWERPC_GPIO_H */
-- 
1.5.4.5

^ permalink raw reply related

* [PATCH 0/2] Notorious OF GPIO API support
From: Anton Vorontsov @ 2008-04-11 13:05 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, David Miller

Hello Paul,

Please consider applying these patches for the 2.6.26. Pretty much of
new drivers depend on this support, including some of my patches and
patches from Jochen Friedrich and Laurent Pinchart.

My plan is to submit MPC83xx/MPC85xx specific parts to Kumar after these
two applied. Then I'll submit pending USB/I2C/MTD/... drivers to the
appropriate subsystem maintainers.

For those who didn't follow these patches, here is recall of the
previous discussions:
http://ozlabs.org/pipermail/linuxppc-dev/2007-December/047948.html
http://ozlabs.org/pipermail/linuxppc-dev/2007-December/048788.html
http://ozlabs.org/pipermail/linuxppc-dev/2008-January/049414.html
http://ozlabs.org/pipermail/linuxppc-dev/2008-March/052881.html

Since January I resent these patches about two or three times just with
some cosmetic changes because of no further comments on the design, so I
believe that interested parties are more or less satisfied with it now.

Thanks,

-- 
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2

^ permalink raw reply

* [PATCH] fs_enet: Don't call NAPI functions when NAPI is not used.
From: Laurent Pinchart @ 2008-04-11 12:05 UTC (permalink / raw)
  To: netdev; +Cc: linuxppc-dev, Jeff Garzik

fs_enet_close() calls napi_disable() unconditionally. This patch skips the
call when use_napi isn't set.

Signed-off-by: Laurent Pinchart <laurentp@cse-semaphore.com>
---
 drivers/net/fs_enet/fs_enet-main.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index c83bd65..1801ce3 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -835,7 +835,8 @@ static int fs_enet_close(struct net_device *dev)
 
 	netif_stop_queue(dev);
 	netif_carrier_off(dev);
-	napi_disable(&fep->napi);
+	if (fep->fpi->use_napi)
+		napi_disable(&fep->napi);
 	phy_stop(fep->phydev);
 
 	spin_lock_irqsave(&fep->lock, flags);
-- 
1.5.0

This is a bugfix and should probably go in 2.6.25.

-- 
Laurent Pinchart
CSE Semaphore Belgium

Chaussee de Bruxelles, 732A
B-1410 Waterloo
Belgium

T +32 (2) 387 42 59
F +32 (2) 387 42 75

^ permalink raw reply related

* Re: patches for 2.6.26
From: Anton Vorontsov @ 2008-04-11 11:45 UTC (permalink / raw)
  To: Kumar Gala; +Cc: ppc-dev list
In-Reply-To: <D9A4BB4A-970C-4E9E-9174-BA8C0191CCA2@kernel.crashing.org>

Hello Kumar,

On Thu, Apr 10, 2008 at 09:21:34AM -0500, Kumar Gala wrote:
> Guy's
>
> if you have work you want in 2.6.26 related to Freescale PPC's let me  
> know.  Ideally you can provide links to the patches in 
> http://patchwork.ozlabs.org/linuxppc/

Please take a look at these:

[POWERPC] mpc8315: fix USB UTMI Host setup
http://patchwork.ozlabs.org/linuxppc/patch?id=17782

[POWERPC] qe_lib and ucc_geth: switch to the cpm_muram implementation
http://patchwork.ozlabs.org/linuxppc/patch?id=17441
^ Scott and Timur say that patch looks fine.

[POWERPC] 83xx: mpc837x_rdb: add simple-bus compatible matching
http://patchwork.ozlabs.org/linuxppc/patch?id=17405

[POWERPC] 83xx: MPC837xRDB's VSC7385 ethernet switch isn't on the MDIO bus
http://patchwork.ozlabs.org/linuxppc/patch?id=17389

[POWERPC] fsl_soc: add support for "fsl, soc" compatible matching
http://patchwork.ozlabs.org/linuxppc/patch?id=17289

[POWERPC] UCC nodes cleanup
http://patchwork.ozlabs.org/linuxppc/patch?id=17290

UPM Patches
http://patchwork.ozlabs.org/linuxppc/patch?id=17291
http://patchwork.ozlabs.org/linuxppc/patch?id=17292
^ Needed to be in-tree so I can ask to merge FSL UPM NAND driver just after
OF GPIO API merge.


Thanks,

-- 
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2

^ permalink raw reply

* Re: [PATCH 1/5] phylib: don't create a phydev for ID-less PHYs.
From: Joakim Tjernlund @ 2008-04-11 10:47 UTC (permalink / raw)
  To: Stefan Roese; +Cc: scottwood, linuxppc-dev, linux-net, Paul Gortmaker
In-Reply-To: <200804111006.04708.sr@denx.de>


On Fri, 2008-04-11 at 10:06 +0200, Stefan Roese wrote:
> On Friday 11 April 2008, Joakim Tjernlund wrote:
> > On Thu, 2008-04-10 at 13:51 -0400, Paul Gortmaker wrote:
> > > In addition to marking 0x0 as an invalid PHY ID, I've also
> > > changed the existing somewhat useless printk to actually
> > > list the bus IDs where it found a PHY so we get a basic
> > > bus summary.
> >
> > PHY ID 0x0 isn't an invalid id, I got a Broadcom PHY that has
> > PHY ID=0. Maybe I am misunderstanding something?
> 
> IIRC, address 0 is the PHY broadcast address, but can be used without problem 
> with some PHY's. I remember some designs were we had the PHY at address 0.

Ouh, if that is so, I guess we need a CONFIG option or a new mdio bus
property to select if PHY ID 0 is valid id or not.

 Jocke

^ permalink raw reply

* Re: State of the MPC5200 PSC AC97 driver
From: Marian Balakowicz @ 2008-04-11  9:23 UTC (permalink / raw)
  To: Sylvain Munaut; +Cc: Sven Luther, spitzauer_77, linuxppc-dev
In-Reply-To: <47FDEF9B.5000506@semihalf.com>


All,

Thanks for the input and comments.

I am also having a look at the I2S driver. There were attempts some
time ago and I found few pieces of code floating on net but couldn't
find anything cleaned up. Did anyone tried to put the results of those
attempts together?

Cheers,
m.

^ permalink raw reply

* Re: [PATCH 1/5] phylib: don't create a phydev for ID-less PHYs.
From: Stefan Roese @ 2008-04-11  8:06 UTC (permalink / raw)
  To: linuxppc-dev, joakim.tjernlund; +Cc: scottwood, Paul Gortmaker, linux-net
In-Reply-To: <1207897589.9544.13.camel@gentoo-jocke.transmode.se>

On Friday 11 April 2008, Joakim Tjernlund wrote:
> On Thu, 2008-04-10 at 13:51 -0400, Paul Gortmaker wrote:
> > In addition to marking 0x0 as an invalid PHY ID, I've also
> > changed the existing somewhat useless printk to actually
> > list the bus IDs where it found a PHY so we get a basic
> > bus summary.
>
> PHY ID 0x0 isn't an invalid id, I got a Broadcom PHY that has
> PHY ID=0. Maybe I am misunderstanding something?

IIRC, address 0 is the PHY broadcast address, but can be used without problem 
with some PHY's. I remember some designs were we had the PHY at address 0.

Best regards,
Stefan

^ permalink raw reply

* Re: State of the MPC5200 PSC AC97 driver
From: Sven Luther @ 2008-04-11  7:34 UTC (permalink / raw)
  To: Robert Schwebel
  Cc: Sylvain Munaut, linuxppc-dev, spitzauer_77, sven,
	Marian Balakowicz
In-Reply-To: <20080411065100.GQ13814@pengutronix.de>

On Fri, Apr 11, 2008 at 08:51:00AM +0200, Robert Schwebel wrote:
> Hi Matt,
> 
> On Thu, Apr 10, 2008 at 04:25:20PM +0100, Matt Sealey wrote:
> > I have a copy of the driver I hacked to work with the new PSC
> > framework but it doesn't "work" anymore - I have no idea why.
> >
> > Mail me privately if you want it, I have no time to make patches or
> > look for a good reason for the breakages, but it compiles at least.
> > The Efika hack should be gone now (irrelevant since we released a
> > firmware that obseletes it) and the other fixmes should be by the
> > wayside considering the fscking thing doesn't play sound anymore...
> 
> I'd be interested as well; do I read your mail right that you have
> already managed to hear sound coming out of the MPC5200B PSC AC97
> interface? You would be the first one I've heared of, so it would
> definitely be interesting to see your code. 

Indeed, sound was known to work on the efika plateform, altough it is
the last patch which not merged upstream, and needs some work.

I leave matt send it to you, as he has been more in touch with this
lately.

Friendly,

Sven Luther

^ permalink raw reply

* Re: State of the MPC5200 PSC AC97 driver
From: Sylvain Munaut @ 2008-04-11  7:29 UTC (permalink / raw)
  To: Marian Balakowicz; +Cc: spitzauer_77, linuxppc-dev
In-Reply-To: <47FDEF9B.5000506@semihalf.com>


> Last year you have posted a MPC5200 PSC AC97 driver patch
> "[PATCH 9/9] sound: Add support for Freescale MPC5200 AC97 interface."
> with the following comment:
>
>   
>> Not quite a clean driver, but it get things done (well, mostly).
>> Only included to be able to test functionalityi/usage of
>> the BestComm driver.
>>     
Yes ... and it still applies.
>
> There are various FIXMEs and commented out code here and there.
> Could you elaborate a bit on the overall state of the driver's
> functionality,
> which areas need improvement and attention?
>   
It's a minimum boiler plate.
I filled the function at the minimum to get some sound output and being
able to hear music coming out of it :)
I also completely skipped the 5200 (not B) support ...

At first there was no DMA at all (full software copy). I added some
simple DMA later just to prove it could work and how to use the API.

I just wrote it to get some sound, prove the interface could work under
linux and to show how to use DMA. I had hoped someone else would finish
it ... (yeah, I know ... big mistake).
> Seems that you mainly tested BestComm with this driver, what was the
> overall
> BestComm performance, any issues here? Did you use any specific test setup
> involving some dedicated application, etc.?
>   
My test was listening to Gorrillaz "Feel Good inc" using mplayer ...

> Did anyone else tried it and/or has a updated version or can share
> experience?
>   
At the time several other people tried it and it worked ... unless you
did lots of harddrive IO and then it crumbled ...



Sylvain

^ permalink raw reply

* Re: [PATCH 1/5] phylib: don't create a phydev for ID-less PHYs.
From: Joakim Tjernlund @ 2008-04-11  7:06 UTC (permalink / raw)
  To: Paul Gortmaker; +Cc: scottwood, linuxppc-dev, linux-net
In-Reply-To: <4764055962e0a42ce083783bbb897a62090ad90b.1207846542.git.paul.gortmaker@windriver.com>


On Thu, 2008-04-10 at 13:51 -0400, Paul Gortmaker wrote:
> I've tested on 8360, 8540 and 8641D and in all cases, the PHY
> ID returned for bus addr 0x1f is all zeros, and not all 0xf.
> This means we've been allocating a phydev for this "ghost".
> 
> In addition to marking 0x0 as an invalid PHY ID, I've also
> changed the existing somewhat useless printk to actually
> list the bus IDs where it found a PHY so we get a basic
> bus summary.
 
PHY ID 0x0 isn't an invalid id, I got a Broadcom PHY that has
PHY ID=0. Maybe I am misunderstanding something?

 Jocke

^ permalink raw reply

* Re: State of the MPC5200 PSC AC97 driver
From: Robert Schwebel @ 2008-04-11  6:51 UTC (permalink / raw)
  To: Matt Sealey; +Cc: linuxppc-dev, Sylvain Munaut, spitzauer_77, Marian Balakowicz
In-Reply-To: <47FE3160.2060907@genesi-usa.com>

Hi Matt,

On Thu, Apr 10, 2008 at 04:25:20PM +0100, Matt Sealey wrote:
> I have a copy of the driver I hacked to work with the new PSC
> framework but it doesn't "work" anymore - I have no idea why.
>
> Mail me privately if you want it, I have no time to make patches or
> look for a good reason for the breakages, but it compiles at least.
> The Efika hack should be gone now (irrelevant since we released a
> firmware that obseletes it) and the other fixmes should be by the
> wayside considering the fscking thing doesn't play sound anymore...

I'd be interested as well; do I read your mail right that you have
already managed to hear sound coming out of the MPC5200B PSC AC97
interface? You would be the first one I've heared of, so it would
definitely be interesting to see your code. 

Robert
-- 
 Dipl.-Ing. Robert Schwebel | http://www.pengutronix.de
 Pengutronix - Linux Solutions for Science and Industry
   Handelsregister:  Amtsgericht Hildesheim, HRA 2686
     Hannoversche Str. 2, 31134 Hildesheim, Germany
   Phone: +49-5121-206917-0 |  Fax: +49-5121-206917-9

^ permalink raw reply

* Re: [PATCH] [v5] Add idle wait support for 44x platforms
From: Olof Johansson @ 2008-04-11  5:31 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: kvm-ppc-devel, linuxppc-dev
In-Reply-To: <200804110218.23912.arnd@arndb.de>

On Fri, Apr 11, 2008 at 02:18:22AM +0200, Arnd Bergmann wrote:
> On Thursday 10 April 2008, Jerone Young wrote:
> > Well it could be this simple. But the current code leaves a lot more
> > room to add different type waits or spins if need be (if they are ever
> > needed ... though none off the top of my head at the moment)...but it
> > does allow you to create another wait state for whatever reason a lot
> > easier.
> > 
> > So I really don't think this needs to change. Unless everyone really
> > feels that it just has to be.
> 
> No, it doesn't need to change, the current patch is entirely correct,
> just a little bit more complicated than it needs to be, and I try
> not to have code in anticipation of something getting more complicated
> in the future, you can always add the complexity at the point where you
> need it.

That piece of code came across from the platforms/pasemi version,
where we for a while had more than two kinds of idle loops
(doze/nap/sleep/rvwinkle). Turns out doze does well enough that the
others weren't really needed so I never submitted support for the deeper
sleep modes.


-Olof

^ permalink raw reply

* Re: [PATCH 0/5] dynamic detection of gianfar TPIPA
From: Paul Gortmaker @ 2008-04-11  3:34 UTC (permalink / raw)
  To: Andy Fleming; +Cc: scottwood, linuxppc-dev, netdev
In-Reply-To: <3F8109F5-F512-48CD-AD93-2C6B4164E5AA@freescale.com>

In message: Re: [PATCH 0/5] dynamic detection of gianfar TPIPA
on 10/04/2008 Andy Fleming wrote:

>
> I may be missing something, but I don't think this quite right.
>
> If you have a PHY at 0x1f, this patchset will cause no PHY device to be 
> allocated for that address, and you'll actually end up assigning TBIPA to 
> be 0x1f again, since there's no PHY there.  Right?  Were you able to use 
> this code with a PHY at 0x1f?

I tested on several "normal" boards and on a board with the PHY @ 0x1f,
and it did what I expected it to do.  It was when I was testing on the
normal boards (8540MDS, 8360MDS, HPCN) that I observed we were showing
a PHY ID of 0x0 at 0x1f during the routine PHY scan, because the
autodetect code was skipping 0x1f even on those boards.  I backed out
all my patches and the situation was the same, hence why I decided to
skip IDs of either 0xffff or 0x0.


> I like the idea of passing around priv->mii_bus instead of regs, but I  
> think it won't work without becoming unnecessarily unwieldy.  The  
> problem is that the TBI PHY is not necessarily accessed through the same 
> bus as the PHY.  Each controller has its own TBI PHY, and that PHY can 
> only be accessed from *that* controller's MDIO bus.  So if you want to 
> configure TSEC2's TBI PHY, you use TSEC2's MDIO regs.  That's what 
> gfar_local_mdio_* allowed; they write the *local* controller's MDIO regs. 
>  It looks like this code sets up priv->mii_bus to point at the bus which 
> holds the PHY, but only TSEC0's bus (on most SoCs) is connected to actual 
> PHYs.  So you will only ever be able to configure the TBI PHY on TSEC0, 
> which will not allow any of the other TSECs to use an SGMII PHY.  Were 
> you able to use other TSECs to connect to an SGMII PHY?

Okay -- that explanation helps me understand the role of the *_local_*
variants -- it wasn't obvious to me that they were being used to jump
the device --> bus association and go right at MDIO bus of tsec0.  I
think this can still be handled sanely though -- we'd have to simply
say that if you wanted the bus of the TBI of the controller, you would
go at dev->priv->mii_bus, and if you wanted the bus of the PHY of the
controller, you'd go at dev->priv->phydev->bus.  I'd have to think a bit
to see if that would afford the same or similar cleanups, but the
distinction at least seems clearer to me now.

> We could still pass around an mii_bus reference, but this would require 
> creating an mii_bus instance for every single TSEC, which is a little 
> heavyweight when we just want to configure the TBI PHY once on startup.

Yep.  Is there any boards out there with more than 4 tsec?  I'd have
to go look at the size of mii_bus to see what the per bus cost is.

>
> After some thinking, I went ahead and implemented a patch which isn't  
> ideal, but should solve the problems your patches set out to solve.   
> I've sent it in a separate message.  If you have some systems with SGMII 
> and/or a PHY at 0x1f, please test this patch on them.  I don't currently 
> have either.

I'll go have a look.  I've only got the SBC8641D with the PHY @ 0x1f to
be the oddball guniea pig.

Paul.

>
> Andy
>

^ permalink raw reply

* Re: [PATCH 6/13] devres: implement managed iomap interface
From: Tejun Heo @ 2008-04-11  2:08 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev, gregkh, linux-kernel, linux-ide, jgarzik, alan
In-Reply-To: <A567023C-17FC-402D-9394-29DFFA816891@kernel.crashing.org>

Kumar Gala wrote:
>>> but there is no reason not to make it work properly.  For example I  
>>> believe libata uses devm_* and the fsl SATA driver (non-PCI) will 
>>> need  to work in cases similar to the 44x.
>>
>>   Well, as for sata_fsl, it calls of_iomap() which does The Right Thing.
> 
> Fair, but I don't see why we should introduce new APIs that are already 
> "broken".  We went through a lot of effort to clean up and introduce 
> resource_t (and clearly still have some bugs) for the >32-bit physical 
> address problem.

Yes, please go ahead.  In case it wasn't clear, I wasn't objecting to 
the fix at all.  I was just curious what could actually happen on x86.

-- 
tejun

^ permalink raw reply

* Re: [PATCH] powerpc TLF_RESTORE_SIGMASK
From: Andrew Morton @ 2008-04-11  1:50 UTC (permalink / raw)
  To: Roland McGrath; +Cc: linuxppc-dev, Paul Mackerras, linux-kernel
In-Reply-To: <20080411013635.1F4B126F992@magilla.localdomain>

On Thu, 10 Apr 2008 18:36:35 -0700 (PDT) Roland McGrath <roland@redhat.com> wrote:

> > This crashes my powerpc mac g5.
> 
> It worked fine on mine.
> 
> > It happens after the boot, during the first login-over-ssh.
> 
> Mine did lots of stuff fine.
> 
> > This is with most of the rest of the -mm poopile applied.  i386 and x86_64
> > seem OK.
> 
> I had only tested with Linus's tree plus the small handful of post-2.6.25
> cleanup patches I've posted in the last few weeks.  To be precise it was
> 9597362d354f8655ece324b01d0c640a0e99c077 plus several of my cleanup patches
> (that are probably all in -mm, but I'm not sure off hand).
> 
> I'd rebased my tree today to 783e391b7b5b273cd20856d8f6f4878da8ec31b3
> anyway.  I just tried the new kernel with the sigmask cleanups and only 
> a few other patches, and have no problems.
> 
> The details of your crash make it look pretty unrelated to this code.
> Off hand I would guess that it's some other bug from other -mm patches
> that just happens only to bite you on powerpc.  If the crash is not
> intermittent and you bisected it to this one change, then I am at a
> loss to see what might be happening.  I'd have to leave it to Paul et
> al to figure out if there is some strange powerpc juju going on.

It's 100% repeatable and I bisected it to this change.

I expect you could repeat it by applying it to
http://userweb.kernel.org/~akpm/mmotm/ (or to -rc6-mm2, if I ever manage to
get it to boot on something) and using
http://userweb.kernel.org/~akpm/config-g5.txt

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox