* [PATCH 2/3] i2c: Convert all new-style drivers to use module aliasing
From: Jean Delvare @ 2008-01-21 10:41 UTC (permalink / raw)
To: Linux I2C; +Cc: David Brownell, linuxppc-dev
In-Reply-To: <20080121112517.6fe35a89@hyperion.delvare>
Based on earlier work by Jon Smirl.
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: 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 | 1
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 | 22 +++++-----
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/rtc/rtc-ds1307.c | 36 ++++++-----------
drivers/rtc/rtc-ds1374.c | 7 +++
drivers/rtc/rtc-m41t80.c | 78 +++++++++----------------------------
drivers/rtc/rtc-rs5c372.c | 14 ++++++
include/linux/i2c.h | 12 ++---
20 files changed, 120 insertions(+), 149 deletions(-)
--- linux-2.6.24-rc8.orig/arch/arm/mach-at91/board-csb337.c 2007-12-04 08:56:17.000000000 +0100
+++ linux-2.6.24-rc8/arch/arm/mach-at91/board-csb337.c 2008-01-20 18:08:16.000000000 +0100
@@ -85,8 +85,7 @@ static struct at91_udc_data __initdata c
static struct i2c_board_info __initdata csb337_i2c_devices[] = {
{
- I2C_BOARD_INFO("rtc-ds1307", 0x68),
- .type = "ds1307",
+ I2C_BOARD_INFO("ds1307", 0x68),
},
};
--- linux-2.6.24-rc8.orig/arch/arm/mach-at91/board-dk.c 2007-12-04 08:56:17.000000000 +0100
+++ linux-2.6.24-rc8/arch/arm/mach-at91/board-dk.c 2008-01-20 18:08:35.000000000 +0100
@@ -132,8 +132,7 @@ static struct i2c_board_info __initdata
I2C_BOARD_INFO("x9429", 0x28),
},
{
- I2C_BOARD_INFO("at24c", 0x50),
- .type = "24c1024",
+ I2C_BOARD_INFO("24c1024", 0x50),
}
};
--- linux-2.6.24-rc8.orig/arch/arm/mach-at91/board-eb9200.c 2007-12-04 08:56:17.000000000 +0100
+++ linux-2.6.24-rc8/arch/arm/mach-at91/board-eb9200.c 2008-01-20 18:08:05.000000000 +0100
@@ -93,8 +93,7 @@ static struct at91_mmc_data __initdata e
static struct i2c_board_info __initdata eb9200_i2c_devices[] = {
{
- I2C_BOARD_INFO("at24c", 0x50),
- .type = "24c512",
+ I2C_BOARD_INFO("24c512", 0x50),
},
};
--- linux-2.6.24-rc8.orig/arch/arm/mach-iop32x/em7210.c 2007-10-10 09:58:10.000000000 +0200
+++ linux-2.6.24-rc8/arch/arm/mach-iop32x/em7210.c 2008-01-20 18:07:15.000000000 +0100
@@ -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),
},
};
--- linux-2.6.24-rc8.orig/arch/arm/mach-iop32x/n2100.c 2007-11-17 10:26:25.000000000 +0100
+++ linux-2.6.24-rc8/arch/arm/mach-iop32x/n2100.c 2008-01-20 18:07:00.000000000 +0100
@@ -208,12 +208,10 @@ static struct f75375s_platform_data n210
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,
},
};
--- linux-2.6.24-rc8.orig/arch/arm/mach-omap1/board-h2.c 2008-01-19 12:16:45.000000000 +0100
+++ linux-2.6.24-rc8/arch/arm/mach-omap1/board-h2.c 2008-01-20 18:07:37.000000000 +0100
@@ -347,7 +347,6 @@ static struct platform_device *h2_device
static struct i2c_board_info __initdata h2_i2c_board_info[] = {
{
I2C_BOARD_INFO("tps65010", 0x48),
- .type = "tps65010",
.irq = OMAP_GPIO_IRQ(58),
},
/* TODO when driver support is ready:
--- linux-2.6.24-rc8.orig/arch/arm/mach-omap1/board-h3.c 2008-01-19 12:16:45.000000000 +0100
+++ linux-2.6.24-rc8/arch/arm/mach-omap1/board-h3.c 2008-01-20 18:07:43.000000000 +0100
@@ -459,8 +459,7 @@ static struct omap_board_config_kernel h
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(??), */
},
/* TODO when driver support is ready:
--- linux-2.6.24-rc8.orig/arch/arm/mach-omap1/board-osk.c 2008-01-19 12:16:45.000000000 +0100
+++ linux-2.6.24-rc8/arch/arm/mach-omap1/board-osk.c 2008-01-20 18:07:30.000000000 +0100
@@ -187,7 +187,6 @@ static struct platform_device *osk5912_d
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:
--- linux-2.6.24-rc8.orig/arch/powerpc/sysdev/fsl_soc.c 2008-01-20 17:28:17.000000000 +0100
+++ linux-2.6.24-rc8/arch/powerpc/sysdev/fsl_soc.c 2008-01-20 17:29:13.000000000 +0100
@@ -322,22 +322,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,
@@ -348,9 +347,7 @@ static int __init of_find_i2c_driver(str
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;
--- linux-2.6.24-rc8.orig/drivers/hwmon/f75375s.c 2008-01-20 14:43:34.000000000 +0100
+++ linux-2.6.24-rc8/drivers/hwmon/f75375s.c 2008-01-20 18:55:18.000000000 +0100
@@ -129,12 +129,20 @@ static struct i2c_driver f75375_legacy_d
.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)
@@ -646,15 +654,6 @@ static int f75375_probe(struct i2c_clien
data->client = client;
mutex_init(&data->update_lock);
- if (strcmp(client->name, "f75375") == 0)
- data->kind = f75375;
- else if (strcmp(client->name, "f75373") == 0)
- data->kind = f75373;
- else {
- dev_err(&client->dev, "Unsupported device: %s\n", client->name);
- return -ENODEV;
- }
-
if ((err = sysfs_create_group(&client->dev.kobj, &f75375_group)))
goto exit_free;
@@ -714,6 +713,7 @@ static int f75375_detect(struct i2c_adap
u8 version = 0;
int err = 0;
const char *name = "";
+ struct i2c_device_id id;
if (!(client = kzalloc(sizeof(*client), GFP_KERNEL))) {
err = -ENOMEM;
@@ -750,7 +750,9 @@ static int f75375_detect(struct i2c_adap
if ((err = i2c_attach_client(client)))
goto exit_free;
- if ((err = f75375_probe(client, NULL)) < 0)
+ strlcpy(id.name, name, I2C_NAME_SIZE);
+ id.driver_data = kind;
+ if ((err = f75375_probe(client, &id)) < 0)
goto exit_detach;
return 0;
--- linux-2.6.24-rc8.orig/drivers/i2c/busses/i2c-taos-evm.c 2007-10-10 09:58:24.000000000 +0200
+++ linux-2.6.24-rc8/drivers/i2c/busses/i2c-taos-evm.c 2008-01-20 19:38:20.000000000 +0100
@@ -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_instantia
{
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);
}
--- linux-2.6.24-rc8.orig/drivers/i2c/chips/ds1682.c 2008-01-20 14:41:23.000000000 +0100
+++ linux-2.6.24-rc8/drivers/i2c/chips/ds1682.c 2008-01-20 18:49:07.000000000 +0100
@@ -235,12 +235,19 @@ static int ds1682_remove(struct i2c_clie
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)
--- linux-2.6.24-rc8.orig/drivers/i2c/chips/menelaus.c 2008-01-20 14:49:40.000000000 +0100
+++ linux-2.6.24-rc8/drivers/i2c/chips/menelaus.c 2008-01-20 18:49:25.000000000 +0100
@@ -1243,12 +1243,19 @@ static int __exit menelaus_remove(struct
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)
--- linux-2.6.24-rc8.orig/drivers/i2c/chips/tps65010.c 2008-01-20 14:41:09.000000000 +0100
+++ linux-2.6.24-rc8/drivers/i2c/chips/tps65010.c 2008-01-20 18:49:34.000000000 +0100
@@ -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_cli
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_cli
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,
};
/*-------------------------------------------------------------------------*/
--- linux-2.6.24-rc8.orig/drivers/i2c/chips/tsl2550.c 2008-01-20 14:40:51.000000000 +0100
+++ linux-2.6.24-rc8/drivers/i2c/chips/tsl2550.c 2008-01-20 18:49:19.000000000 +0100
@@ -452,6 +452,12 @@ static int tsl2550_resume(struct i2c_cli
#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)
--- linux-2.6.24-rc8.orig/drivers/rtc/rtc-ds1307.c 2008-01-20 17:26:58.000000000 +0100
+++ linux-2.6.24-rc8/drivers/rtc/rtc-ds1307.c 2008-01-20 19:03:48.000000000 +0100
@@ -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
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
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:
@@ -538,6 +527,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)
--- linux-2.6.24-rc8.orig/drivers/rtc/rtc-ds1374.c 2008-01-20 17:26:58.000000000 +0100
+++ linux-2.6.24-rc8/drivers/rtc/rtc-ds1374.c 2008-01-20 19:04:10.000000000 +0100
@@ -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)
--- linux-2.6.24-rc8.orig/drivers/rtc/rtc-m41t80.c 2008-01-20 17:26:58.000000000 +0100
+++ linux-2.6.24-rc8/drivers/rtc/rtc-m41t80.c 2008-01-20 19:09:09.000000000 +0100
@@ -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
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_notifie
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_clien
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_clien
}
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_clien
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_clien
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_clie
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)
--- linux-2.6.24-rc8.orig/drivers/rtc/rtc-rs5c372.c 2008-01-20 17:26:58.000000000 +0100
+++ linux-2.6.24-rc8/drivers/rtc/rtc-rs5c372.c 2008-01-20 19:04:22.000000000 +0100
@@ -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_clie
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)
--- linux-2.6.24-rc8.orig/include/linux/i2c.h 2008-01-20 17:40:20.000000000 +0100
+++ linux-2.6.24-rc8/include/linux/i2c.h 2008-01-21 08:26:40.000000000 +0100
@@ -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
--
Jean Delvare
^ permalink raw reply
* [PATCH 1/3] i2c: Add support for device alias names
From: Jean Delvare @ 2008-01-21 10:39 UTC (permalink / raw)
To: Linux I2C; +Cc: David Brownell, linuxppc-dev
In-Reply-To: <20080121112517.6fe35a89@hyperion.delvare>
Based on earlier work by Jon Smirl.
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: Jean Delvare <khali@linux-fr.org>
Cc: Jon Smirl <jonsmirl@gmail.com>
---
drivers/hwmon/f75375s.c | 8 +++---
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 | 50 +++++++++++++++++++++++++++++++--------
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 ++++++++++
scripts/mod/file2alias.c | 13 ++++++++++
13 files changed, 90 insertions(+), 23 deletions(-)
--- linux-2.6.24-rc8.orig/drivers/hwmon/f75375s.c 2008-01-21 08:47:05.000000000 +0100
+++ linux-2.6.24-rc8/drivers/hwmon/f75375s.c 2008-01-21 09:12:25.000000000 +0100
@@ -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_clien
}
-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;
@@ -748,7 +750,7 @@ static int f75375_detect(struct i2c_adap
if ((err = i2c_attach_client(client)))
goto exit_free;
- if ((err = f75375_probe(client)) < 0)
+ if ((err = f75375_probe(client, NULL)) < 0)
goto exit_detach;
return 0;
--- linux-2.6.24-rc8.orig/drivers/i2c/chips/ds1682.c 2008-01-21 08:47:05.000000000 +0100
+++ linux-2.6.24-rc8/drivers/i2c/chips/ds1682.c 2008-01-21 09:12:25.000000000 +0100
@@ -200,7 +200,8 @@ static struct bin_attribute ds1682_eepro
/*
* 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;
--- linux-2.6.24-rc8.orig/drivers/i2c/chips/menelaus.c 2008-01-21 08:47:05.000000000 +0100
+++ linux-2.6.24-rc8/drivers/i2c/chips/menelaus.c 2008-01-21 09:12:25.000000000 +0100
@@ -1149,7 +1149,8 @@ static inline void menelaus_rtc_init(str
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;
--- linux-2.6.24-rc8.orig/drivers/i2c/chips/tps65010.c 2008-01-21 08:47:05.000000000 +0100
+++ linux-2.6.24-rc8/drivers/i2c/chips/tps65010.c 2008-01-21 09:12:25.000000000 +0100
@@ -465,7 +465,8 @@ static int __exit tps65010_remove(struct
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;
--- linux-2.6.24-rc8.orig/drivers/i2c/chips/tsl2550.c 2008-01-21 08:47:05.000000000 +0100
+++ linux-2.6.24-rc8/drivers/i2c/chips/tsl2550.c 2008-01-21 09:12:25.000000000 +0100
@@ -364,7 +364,8 @@ static int tsl2550_init_client(struct i2
*/
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;
--- linux-2.6.24-rc8.orig/drivers/i2c/i2c-core.c 2008-01-21 08:47:05.000000000 +0100
+++ linux-2.6.24-rc8/drivers/i2c/i2c-core.c 2008-01-21 09:12:25.000000000 +0100
@@ -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 devic
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 devi
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;
}
@@ -90,12 +111,18 @@ static int i2c_device_probe(struct devic
{
struct i2c_client *client = to_i2c_client(dev);
struct i2c_driver *driver = to_i2c_driver(dev->driver);
+ const struct i2c_device_id *id;
if (!driver->probe)
return -ENODEV;
client->driver = driver;
dev_dbg(dev, "probe\n");
- return driver->probe(client);
+
+ if (driver->id_table)
+ id = i2c_match_id(driver->id_table, client);
+ else
+ id = NULL;
+ return driver->probe(client, id);
}
static int i2c_device_remove(struct device *dev)
@@ -175,9 +202,9 @@ static ssize_t show_client_name(struct d
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[] = {
@@ -296,15 +323,20 @@ void i2c_unregister_device(struct i2c_cl
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,
};
/**
--- linux-2.6.24-rc8.orig/drivers/rtc/rtc-ds1307.c 2008-01-21 08:47:05.000000000 +0100
+++ linux-2.6.24-rc8/drivers/rtc/rtc-ds1307.c 2008-01-21 09:12:25.000000000 +0100
@@ -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;
--- linux-2.6.24-rc8.orig/drivers/rtc/rtc-ds1374.c 2008-01-21 08:47:05.000000000 +0100
+++ linux-2.6.24-rc8/drivers/rtc/rtc-ds1374.c 2008-01-21 09:12:25.000000000 +0100
@@ -355,7 +355,8 @@ static const struct rtc_class_ops ds1374
.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;
--- linux-2.6.24-rc8.orig/drivers/rtc/rtc-m41t80.c 2008-01-21 08:47:05.000000000 +0100
+++ linux-2.6.24-rc8/drivers/rtc/rtc-m41t80.c 2008-01-21 09:12:25.000000000 +0100
@@ -756,7 +756,8 @@ static struct notifier_block wdt_notifie
*
*****************************************************************************
*/
-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;
--- linux-2.6.24-rc8.orig/drivers/rtc/rtc-rs5c372.c 2008-01-21 08:47:05.000000000 +0100
+++ linux-2.6.24-rc8/drivers/rtc/rtc-rs5c372.c 2008-01-21 09:12:25.000000000 +0100
@@ -494,7 +494,8 @@ static void rs5c_sysfs_unregister(struct
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;
--- linux-2.6.24-rc8.orig/include/linux/i2c.h 2008-01-21 08:47:05.000000000 +0100
+++ linux-2.6.24-rc8/include/linux/i2c.h 2008-01-21 09:12:25.000000000 +0100
@@ -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;
--- linux-2.6.24-rc8.orig/include/linux/mod_devicetable.h 2008-01-21 08:47:05.000000000 +0100
+++ linux-2.6.24-rc8/include/linux/mod_devicetable.h 2008-01-21 09:12:25.000000000 +0100
@@ -367,4 +367,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 */
--- linux-2.6.24-rc8.orig/scripts/mod/file2alias.c 2008-01-21 08:47:05.000000000 +0100
+++ linux-2.6.24-rc8/scripts/mod/file2alias.c 2008-01-21 09:12:25.000000000 +0100
@@ -539,6 +539,15 @@ static int do_virtio_entry(const char *f
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)
{
@@ -669,6 +678,10 @@ void handle_moddevtable(struct module *m
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);
}
--
Jean Delvare
^ permalink raw reply
* [PATCH 0/3] i2c: Use the standard, alias-based device/driver matching scheme
From: Jean Delvare @ 2008-01-21 10:25 UTC (permalink / raw)
To: Linux I2C; +Cc: David Brownell, linuxppc-dev
Hi all,
Here comes a patch set, based on earlier work by Jon Smirl, that
updates the i2c subsystem to support and use the standard, alias-based
device/driver matching scheme that most other subsystems are using.
Contrary to Jon's patch set, this one only supports Linux names and not
OF names, although it might be added later (just not sure how exactly.)
Patch 1/3 adds support for this standard matching scheme, patch 2/3
converts all the in-tree drivers to make use of it, and patch 3/3
removes the old driver_name/type matching scheme that has no users left
at this point.
This new approach makes the i2c device drivers smaller in general
(because the name matching code moved to i2c-core), the exception being
drivers which support only one device, for which the device ID table
adds a small overhead (88 bytes on x86_64).
The key benefit compared to the original matching scheme is that
platform code no longer needs to know which driver supports which
device. This means that support for a given device can move from one
driver to another without changing the platform code.
Note: all the arm and powerpc stuff is untested.
--
Jean Delvare
^ permalink raw reply
* [PATCH] revert chrp_pci_fixup_vt8231_ata devinit to fix libata on pegasos
From: Olaf Hering @ 2008-01-21 9:39 UTC (permalink / raw)
To: linuxppc-dev
commit 6d98bda79bea0e1be26c0767d0e9923ad3b72f2e changed the init order
for chrp_pci_fixup_vt8231_ata()
It can not work anymore because either the irq is not yet set to 14 or
pci_get_device() returns nothing. At least the printk() in
chrp_pci_fixup_vt8231_ata() does not trigger anymore.
pata_via works again on Pegasos with the change below.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -354,7 +354,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_WI
* mode as well. The same fixup must be done to the class-code property in
* the IDE node /pci@80000000/ide@C,1
*/
-static void __devinit chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide)
+static void chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide)
{
u8 progif;
struct pci_dev *viaisa;
@@ -375,4 +375,4 @@ static void __devinit chrp_pci_fixup_vt8
pci_dev_put(viaisa);
}
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata);
^ permalink raw reply
* Re: [MPC5200] problem running FEC and ATA
From: Juergen Beisert @ 2008-01-21 8:57 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Mehlan, Markus (Ritter Elektronik)
In-Reply-To: <FACFFB02D783C64FB2CEF2D6825F6FC206EEF1BE@SRVEXC01.sts.saurer.vpn>
Markus,
On Monday 21 January 2008 08:10, Mehlan, Markus (Ritter Elektronik) wrote:
> i have the same problem with the fec driver. See my posting
> at
> http://ozlabs.org/pipermail/linuxppc-embedded/2008-January/029466.html
>
> Arnon, have you already fixed the FEC problem?
Can you check this?
http://ozlabs.org/pipermail/linuxppc-embedded/2007-May/027046.html
Regards,
Juergen
=2D-=20
Dipl.-Ing. Juergen Beisert | http://www.pengutronix.de
=A0Pengutronix - Linux Solutions for Science and Industry
=A0 Handelsregister: Amtsgericht Hildesheim, HRA 2686
=A0 =A0 =A0 Vertretung Sued/Muenchen, Germany
Phone: +49-8766-939 228 | Fax: +49-5121-206917-9
^ permalink raw reply
* RE: Xilinx XPS_LL_TEMAC vs PLB_TEMAC
From: Mohammad Sadegh Sadri @ 2008-01-21 8:54 UTC (permalink / raw)
To: David Baird, linuxppc-embedded
In-Reply-To: <440abda90801202354l5a0ce4caq382af5991e36f775@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1477 bytes --]
thanks for you reply david,
As far as I know the Linux driver for Xilinx PLB TEMAC was two parts : 1- adapter.c and 2- the rest of the driver files
Only adapter.c was really a linux related file and the rest of the files were Xilinx generic driver code for PLB TEMAC.
correct?
then now, I know EDK 9.2 generates the needed Linux support package and needed related files, so if this is the case can we use these files as the needed driver in our linux kernel?
by the way, i did never hear about this git repository before...can you describe us, where is it and how we can access it and which projects are now hosted by it?
thanks
> Date: Mon, 21 Jan 2008 00:54:30 -0700
> From: dhbaird@gmail.com
> To: mamsadegh@hotmail.com
> Subject: Re: Xilinx XPS_LL_TEMAC vs PLB_TEMAC
>
> On Jan 21, 2008 12:36 AM, Mohammad Sadegh Sadri <mamsadegh@hotmail.com> wrote:
> > As you know Xilinx PLB TEMAC is a module which connects Hard TEMAC in
> > Virtex-4 FX devices to PLB bus,
> > now, in the new release of EDK , EDK 9.2 Xilinx has added a new interface
> > core , which is called XPS_LL_TEMAC and has a different structure than
> > normal PLB TEMAC. spacially it has some additional data transfer buses.
> >
> > Now the question is,... is there any linux driver available for this new
> > core?
>
> Yes there is, but I had to use the git sources at:
>
> git.xilinx.com
_________________________________________________________________
[-- Attachment #2: Type: text/html, Size: 1790 bytes --]
^ permalink raw reply
* Re: Xilinx XPS_LL_TEMAC vs PLB_TEMAC
From: David Baird @ 2008-01-21 7:55 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <BAY115-W17ECE16AB6FA79B2D4DBBDB23D0@phx.gbl>
On Jan 21, 2008 12:36 AM, Mohammad Sadegh Sadri <mamsadegh@hotmail.com> wrote:
> As you know Xilinx PLB TEMAC is a module which connects Hard TEMAC in
> Virtex-4 FX devices to PLB bus,
> now, in the new release of EDK , EDK 9.2 Xilinx has added a new interface
> core , which is called XPS_LL_TEMAC and has a different structure than
> normal PLB TEMAC. spacially it has some additional data transfer buses.
>
> Now the question is,... is there any linux driver available for this new
> core?
Yes there is, but I had to use the git sources at:
git.xilinx.com
^ permalink raw reply
* Xilinx XPS_LL_TEMAC vs PLB_TEMAC
From: Mohammad Sadegh Sadri @ 2008-01-21 7:36 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 500 bytes --]
Hi All,
As you know Xilinx PLB TEMAC is a module which connects Hard TEMAC in Virtex-4 FX devices to PLB bus,
now, in the new release of EDK , EDK 9.2 Xilinx has added a new interface core , which is called XPS_LL_TEMAC and has a different structure than normal PLB TEMAC. spacially it has some additional data transfer buses.
Now the question is,... is there any linux driver available for this new core?
thanks
_________________________________________________________________
[-- Attachment #2: Type: text/html, Size: 679 bytes --]
^ permalink raw reply
* Re: [MPC5200] problem running FEC and ATA
From: Mehlan, Markus (Ritter Elektronik) @ 2008-01-21 7:10 UTC (permalink / raw)
To: linuxppc-dev
Hello all,
i have the same problem with the fec driver. See my posting
at
http://ozlabs.org/pipermail/linuxppc-embedded/2008-January/029466.html
Arnon, have you already fixed the FEC problem?
Thanks and regards,
Markus.
^ permalink raw reply
* Re: Endian problem when accessing internel regs on 8347
From: Bruce_Leonard @ 2008-01-21 7:21 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-embedded
In-Reply-To: <478FD442.8060902@freescale.com>
> >>> __asm__ __volatile__("lwz%U1%X1 %0,%1; twi 0,%0,0; isync" : "=r"
(ret)
> > :
> >>> "m" (*addr));
> >> They allow the compiler to use update and/or index mode for the
memory
> >> operand.
> >
> > Well that makes sense, U for update and X for index, but I'm not sure
> > they're applicable to this particular instruction and I'm not sure
that
> > the memory operand makes sense for PowerPC.
>
> Why not?
Okay, after much digging and experimenting, I'll agree that the memory
operand makes sense. When I first said that I was thinking of direct
manipulation of memory, which the PPC doesn't support. (Don't ask, my
brain sometimes goes off into la-la land without me :-> ) Also, update
mode is applicable and makes sense. But I do still have a problem with
the index mode, though it could be compiler magic. Here's why: the index
mode of the 'lwz' instruction requires three operands, i.e., 'lwzx
rD,rA,rB', and there's only place holders for two operands. Is the
compiler smart enough to add the third operand for the index mode? If so,
what does it put for the third operand?
Another question is how does the compiler know which mode to pick? And
what is the significance of the trailing number? Some places in the code
have %U1%X1 and others have %U2%X2? I've found documentation for the #
and ## tokens, but I can't find anything for the %U or %X tokens.
Now this has all been very interesting to learn but doesn't solve my
underlying problem which I've finally drilled down to. At first I thought
in_be32() might be broken because I wasn't getting back the value I knew
to be in the internal register. I knew I had the address and the mapping
to kernel space correct because I could use in_le32 and get the right
value though it was byte swapped. The value in the register was
0xFFFFFFE7 but what I was getting from in_be32 was 0xFFFFFFFF. Then I
started playing and here's what I found:
Register value in_be32 value
0x12345678 0x1234567
0xff345678 0xff345678
0xffff5678 0xffff5678
0xfffff678 0xfffff678
0xfffffe78 0xffffffff
0xffffff78 0xffffffff
This isn't an exhastive list but I tried about twenty values and pretty
much what I found was that if bits 0 through 22 are set to 1 then in_be32
reads 0xffffffff. I've also tried it at a variety of addresses and the
behaviour is the same. in_le32 works fine as does in_be16. I've got no
ideas as to what may be wrong. I don't want to just arbitrarily point to
that %U1%X1 parameter list, but I get compiler errors if I try to remove
them so I can't prove or disprove it and I can't find any documentation on
it I can't even form a theroy. Has anyone ever seen anything like this?
Can't anyone suggest anything I can try?
^ permalink raw reply
* [PATCH] Make IOMMU code safe for > 132 GB of memory
From: Michael Ellerman @ 2008-01-21 7:01 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Arnd Bergmann, Jeremy Kerr
Currently the IOMMU code allocates one page for the segment table, that
isn't safe if we have more than 132 GB of RAM.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/cell/iommu.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 7f45d59..eb2a94b 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -310,8 +310,8 @@ static void cell_iommu_setup_hardware(struct cbe_iommu *iommu, unsigned long siz
{
struct page *page;
int ret, i;
- unsigned long reg, segments, pages_per_segment, ptab_size, n_pte_pages;
- unsigned long xlate_base;
+ unsigned long reg, segments, pages_per_segment, ptab_size, stab_size,
+ n_pte_pages, xlate_base;
unsigned int virq;
if (cell_iommu_find_ioc(iommu->nid, &xlate_base))
@@ -328,7 +328,8 @@ static void cell_iommu_setup_hardware(struct cbe_iommu *iommu, unsigned long siz
__FUNCTION__, iommu->nid, segments, pages_per_segment);
/* set up the segment table */
- page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0);
+ stab_size = segments * sizeof(unsigned long);
+ page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(stab_size));
BUG_ON(!page);
iommu->stab = page_address(page);
clear_page(iommu->stab);
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* Re: [PATCH 7/7] Remove bogus comment in dma_direct_alloc_coherent()
From: Benjamin Herrenschmidt @ 2008-01-21 6:22 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, Arnd Bergmann, cbe-oss-dev
In-Reply-To: <f62c2a7477a956c09fe9286922c350465a60dacd.1200894155.git.michael@ellerman.id.au>
On Mon, 2008-01-21 at 16:42 +1100, Michael Ellerman wrote:
> Since commit c80d9133e99de1af607314107910a2a1645efb17 (Make direct DMA use
> node local allocations) went in this comment makes no sense.
>
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
> arch/powerpc/kernel/dma_64.c | 1 -
> 1 files changed, 0 insertions(+), 1 deletions(-)
>
> diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
> index 72fdc06..8423907 100644
> --- a/arch/powerpc/kernel/dma_64.c
> +++ b/arch/powerpc/kernel/dma_64.c
> @@ -130,7 +130,6 @@ static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
> void *ret;
> int node = dev->archdata.numa_node;
>
> - /* TODO: Maybe use the numa node here too ? */
> page = alloc_pages_node(node, flag, get_order(size));
> if (page == NULL)
> return NULL;
^ permalink raw reply
* Re: [PATCH 6/7] Remove the global dma_direct_offset
From: Benjamin Herrenschmidt @ 2008-01-21 6:21 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, Arnd Bergmann, cbe-oss-dev
In-Reply-To: <1e7b4eed15ca7723dd904b056d85b09873b70e8c.1200894155.git.michael@ellerman.id.au>
On Mon, 2008-01-21 at 16:42 +1100, Michael Ellerman wrote:
> We no longer need the global dma_direct_offset, update the comment to
> reflect the new reality.
>
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
> arch/powerpc/kernel/dma_64.c | 7 ++++---
> include/asm-powerpc/dma-mapping.h | 2 --
> 2 files changed, 4 insertions(+), 5 deletions(-)
>
> diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
> index a2d076d..72fdc06 100644
> --- a/arch/powerpc/kernel/dma_64.c
> +++ b/arch/powerpc/kernel/dma_64.c
> @@ -112,10 +112,11 @@ EXPORT_SYMBOL(dma_iommu_ops);
> /*
> * Generic direct DMA implementation
> *
> - * This implementation supports a global offset that can be applied if
> - * the address at which memory is visible to devices is not 0.
> + * This implementation supports a per-device offset that can be applied if
> + * the address at which memory is visible to devices is not 0. Platform code
> + * can set archdata.dma_data to an unsigned long holding the offset. By
> + * default the offset is zero.
> */
> -unsigned long dma_direct_offset;
>
> static unsigned long get_dma_direct_offset(struct device *dev)
> {
> diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
> index e974876..5eea6db 100644
> --- a/include/asm-powerpc/dma-mapping.h
> +++ b/include/asm-powerpc/dma-mapping.h
> @@ -189,8 +189,6 @@ static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
> extern struct dma_mapping_ops dma_iommu_ops;
> extern struct dma_mapping_ops dma_direct_ops;
>
> -extern unsigned long dma_direct_offset;
> -
> #else /* CONFIG_PPC64 */
>
> #define dma_supported(dev, mask) (1)
^ permalink raw reply
* Re: [PATCH 5/7] Have celleb use its own dma_direct_offset variable
From: Benjamin Herrenschmidt @ 2008-01-21 6:21 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, Arnd Bergmann, cbe-oss-dev
In-Reply-To: <e9ff0b0489aa17d36387d252811c2846976684fd.1200894155.git.michael@ellerman.id.au>
On Mon, 2008-01-21 at 16:42 +1100, Michael Ellerman wrote:
> Rather than using the global variable, have celleb use its own variable to
> store the direct DMA offset.
>
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
> arch/powerpc/platforms/celleb/iommu.c | 6 ++++--
> 1 files changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/platforms/celleb/iommu.c b/arch/powerpc/platforms/celleb/iommu.c
> index 843a66f..93b0efd 100644
> --- a/arch/powerpc/platforms/celleb/iommu.c
> +++ b/arch/powerpc/platforms/celleb/iommu.c
> @@ -52,6 +52,8 @@ static int __init find_dma_window(u64 *io_space_id, u64 *ioid,
> return 0;
> }
>
> +static unsigned long celleb_dma_direct_offset;
> +
> static void __init celleb_init_direct_mapping(void)
> {
> u64 lpar_addr, io_addr;
> @@ -69,13 +71,13 @@ static void __init celleb_init_direct_mapping(void)
> ioid, DMA_FLAGS);
> }
>
> - dma_direct_offset = dma_base;
> + celleb_dma_direct_offset = dma_base;
> }
>
> static void celleb_dma_dev_setup(struct device *dev)
> {
> dev->archdata.dma_ops = get_pci_dma_ops();
> - dev->archdata.dma_data = (void *)dma_direct_offset;
> + dev->archdata.dma_data = (void *)celleb_dma_direct_offset;
> }
>
> static void celleb_pci_dma_dev_setup(struct pci_dev *pdev)
^ permalink raw reply
* Re: [PATCH 4/7] Have cell use its own dma_direct_offset variable
From: Benjamin Herrenschmidt @ 2008-01-21 6:21 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, Arnd Bergmann, cbe-oss-dev
In-Reply-To: <0a87a8672c76341044ebb0231ff0c1fba4e82c36.1200894155.git.michael@ellerman.id.au>
On Mon, 2008-01-21 at 16:42 +1100, Michael Ellerman wrote:
> Rather than using the global variable, have cell use its own variable to
> store the direct DMA offset.
>
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
> arch/powerpc/platforms/cell/iommu.c | 12 +++++++-----
> 1 files changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
> index 9682b63..7f45d59 100644
> --- a/arch/powerpc/platforms/cell/iommu.c
> +++ b/arch/powerpc/platforms/cell/iommu.c
> @@ -490,6 +490,8 @@ static struct cbe_iommu *cell_iommu_for_node(int nid)
> return NULL;
> }
>
> +static unsigned long cell_dma_direct_offset;
> +
> static void cell_dma_dev_setup(struct device *dev)
> {
> struct iommu_window *window;
> @@ -497,7 +499,7 @@ static void cell_dma_dev_setup(struct device *dev)
> struct dev_archdata *archdata = &dev->archdata;
>
> if (get_pci_dma_ops() == &dma_direct_ops) {
> - archdata->dma_data = (void *)dma_direct_offset;
> + archdata->dma_data = (void *)cell_dma_direct_offset;
> return;
> }
>
> @@ -655,7 +657,7 @@ static int __init cell_iommu_init_disabled(void)
>
> /* If we have no Axon, we set up the spider DMA magic offset */
> if (of_find_node_by_name(NULL, "axon") == NULL)
> - dma_direct_offset = SPIDER_DMA_OFFSET;
> + cell_dma_direct_offset = SPIDER_DMA_OFFSET;
>
> /* Now we need to check to see where the memory is mapped
> * in PCI space. We assume that all busses use the same dma
> @@ -689,13 +691,13 @@ static int __init cell_iommu_init_disabled(void)
> return -ENODEV;
> }
>
> - dma_direct_offset += base;
> + cell_dma_direct_offset += base;
>
> - if (dma_direct_offset != 0)
> + if (cell_dma_direct_offset != 0)
> ppc_md.pci_dma_dev_setup = cell_pci_dma_dev_setup;
>
> printk("iommu: disabled, direct DMA offset is 0x%lx\n",
> - dma_direct_offset);
> + cell_dma_direct_offset);
>
> return 0;
> }
^ permalink raw reply
* Re: [PATCH 4/7] Have cell use its own dma_direct_offset variable
From: Benjamin Herrenschmidt @ 2008-01-21 6:21 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, Arnd Bergmann, cbe-oss-dev
In-Reply-To: <0a87a8672c76341044ebb0231ff0c1fba4e82c36.1200894155.git.michael@ellerman.id.au>
On Mon, 2008-01-21 at 16:42 +1100, Michael Ellerman wrote:
> Rather than using the global variable, have cell use its own variable to
> store the direct DMA offset.
>
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
> ---
> arch/powerpc/platforms/cell/iommu.c | 12 +++++++-----
> 1 files changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
> index 9682b63..7f45d59 100644
> --- a/arch/powerpc/platforms/cell/iommu.c
> +++ b/arch/powerpc/platforms/cell/iommu.c
> @@ -490,6 +490,8 @@ static struct cbe_iommu *cell_iommu_for_node(int nid)
> return NULL;
> }
>
> +static unsigned long cell_dma_direct_offset;
> +
> static void cell_dma_dev_setup(struct device *dev)
> {
> struct iommu_window *window;
> @@ -497,7 +499,7 @@ static void cell_dma_dev_setup(struct device *dev)
> struct dev_archdata *archdata = &dev->archdata;
>
> if (get_pci_dma_ops() == &dma_direct_ops) {
> - archdata->dma_data = (void *)dma_direct_offset;
> + archdata->dma_data = (void *)cell_dma_direct_offset;
> return;
> }
>
> @@ -655,7 +657,7 @@ static int __init cell_iommu_init_disabled(void)
>
> /* If we have no Axon, we set up the spider DMA magic offset */
> if (of_find_node_by_name(NULL, "axon") == NULL)
> - dma_direct_offset = SPIDER_DMA_OFFSET;
> + cell_dma_direct_offset = SPIDER_DMA_OFFSET;
>
> /* Now we need to check to see where the memory is mapped
> * in PCI space. We assume that all busses use the same dma
> @@ -689,13 +691,13 @@ static int __init cell_iommu_init_disabled(void)
> return -ENODEV;
> }
>
> - dma_direct_offset += base;
> + cell_dma_direct_offset += base;
>
> - if (dma_direct_offset != 0)
> + if (cell_dma_direct_offset != 0)
> ppc_md.pci_dma_dev_setup = cell_pci_dma_dev_setup;
>
> printk("iommu: disabled, direct DMA offset is 0x%lx\n",
> - dma_direct_offset);
> + cell_dma_direct_offset);
>
> return 0;
> }
^ permalink raw reply
* Re: [PATCH 3/7] Use archdata.dma_data in dma_direct_ops and add the offset
From: Benjamin Herrenschmidt @ 2008-01-21 6:21 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, Arnd Bergmann, cbe-oss-dev
In-Reply-To: <651e15968afb5bbd9eeafb0b66cd5b59eabcf8d9.1200894155.git.michael@ellerman.id.au>
On Mon, 2008-01-21 at 16:42 +1100, Michael Ellerman wrote:
> Now that all platforms using dma_direct_offset setup the archdata.dma_data
> correctly, we can change the dma_direct_ops to retrieve the offset from
> the dma_data, rather than directly from the global.
>
> While we're here, change the way the offset is used - instead of or'ing it
> into the value, add it. This should have no effect on current implementations
> where the offset is far larger than memory, however in future we may want
> to use smaller offsets.
>
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
> arch/powerpc/kernel/dma_64.c | 11 ++++++++---
> 1 files changed, 8 insertions(+), 3 deletions(-)
>
> diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
> index 14206e3..a2d076d 100644
> --- a/arch/powerpc/kernel/dma_64.c
> +++ b/arch/powerpc/kernel/dma_64.c
> @@ -117,6 +117,11 @@ EXPORT_SYMBOL(dma_iommu_ops);
> */
> unsigned long dma_direct_offset;
>
> +static unsigned long get_dma_direct_offset(struct device *dev)
> +{
> + return (unsigned long)dev->archdata.dma_data;
> +}
> +
> static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
> dma_addr_t *dma_handle, gfp_t flag)
> {
> @@ -130,7 +135,7 @@ static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
> return NULL;
> ret = page_address(page);
> memset(ret, 0, size);
> - *dma_handle = virt_to_abs(ret) | dma_direct_offset;
> + *dma_handle = virt_to_abs(ret) + get_dma_direct_offset(dev);
>
> return ret;
> }
> @@ -145,7 +150,7 @@ static dma_addr_t dma_direct_map_single(struct device *dev, void *ptr,
> size_t size,
> enum dma_data_direction direction)
> {
> - return virt_to_abs(ptr) | dma_direct_offset;
> + return virt_to_abs(ptr) + get_dma_direct_offset(dev);
> }
>
> static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr,
> @@ -161,7 +166,7 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
> int i;
>
> for_each_sg(sgl, sg, nents, i) {
> - sg->dma_address = sg_phys(sg) | dma_direct_offset;
> + sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev);
> sg->dma_length = sg->length;
> }
>
^ permalink raw reply
* Re: [PATCH 2/7] Add celleb_dma_dev_setup()
From: Benjamin Herrenschmidt @ 2008-01-21 6:20 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, Arnd Bergmann, cbe-oss-dev
In-Reply-To: <4bdf881cfc1386c5167495a5e64bdb9dc3ca90d5.1200894155.git.michael@ellerman.id.au>
On Mon, 2008-01-21 at 16:42 +1100, Michael Ellerman wrote:
> Celleb always uses dma_direct_ops, and sets dma_direct_offset, so it too
> should set dma_data to dma_direct_offset.
>
> Currently there's no pci_dma_dev_setup() routine for Celleb so add one.
>
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
> arch/powerpc/platforms/celleb/iommu.c | 14 +++++++++++++-
> 1 files changed, 13 insertions(+), 1 deletions(-)
>
> diff --git a/arch/powerpc/platforms/celleb/iommu.c b/arch/powerpc/platforms/celleb/iommu.c
> index 41e1e6f..843a66f 100644
> --- a/arch/powerpc/platforms/celleb/iommu.c
> +++ b/arch/powerpc/platforms/celleb/iommu.c
> @@ -72,6 +72,17 @@ static void __init celleb_init_direct_mapping(void)
> dma_direct_offset = dma_base;
> }
>
> +static void celleb_dma_dev_setup(struct device *dev)
> +{
> + dev->archdata.dma_ops = get_pci_dma_ops();
> + dev->archdata.dma_data = (void *)dma_direct_offset;
> +}
> +
> +static void celleb_pci_dma_dev_setup(struct pci_dev *pdev)
> +{
> + celleb_dma_dev_setup(&pdev->dev);
> +}
> +
> static int celleb_of_bus_notify(struct notifier_block *nb,
> unsigned long action, void *data)
> {
> @@ -81,7 +92,7 @@ static int celleb_of_bus_notify(struct notifier_block *nb,
> if (action != BUS_NOTIFY_ADD_DEVICE)
> return 0;
>
> - dev->archdata.dma_ops = get_pci_dma_ops();
> + celleb_dma_dev_setup(dev);
>
> return 0;
> }
> @@ -94,6 +105,7 @@ static int __init celleb_init_iommu(void)
> {
> celleb_init_direct_mapping();
> set_pci_dma_ops(&dma_direct_ops);
> + ppc_md.pci_dma_dev_setup = celleb_pci_dma_dev_setup;
> bus_register_notifier(&of_platform_bus_type, &celleb_of_bus_notifier);
>
> return 0;
^ permalink raw reply
* Re: [PATCH 1/7] Set archdata.dma_data for direct DMA in cell_dma_dev_setup()
From: Benjamin Herrenschmidt @ 2008-01-21 6:20 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, Arnd Bergmann, cbe-oss-dev
In-Reply-To: <2949748ba6ad7e14f0768ac3889267e42c050d7a.1200894155.git.michael@ellerman.id.au>
On Mon, 2008-01-21 at 16:42 +1100, Michael Ellerman wrote:
> Store the direct_dma_offset in each device's dma_data in the case
> where we're using the direct DMA ops.
>
> We need to make sure we setup the ppc_md.pci_dma_dev_setup() callback
> if we're using a non-zero offset.
>
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
> arch/powerpc/platforms/cell/iommu.c | 8 ++++++--
> 1 files changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
> index bceb5e1..9682b63 100644
> --- a/arch/powerpc/platforms/cell/iommu.c
> +++ b/arch/powerpc/platforms/cell/iommu.c
> @@ -496,9 +496,10 @@ static void cell_dma_dev_setup(struct device *dev)
> struct cbe_iommu *iommu;
> struct dev_archdata *archdata = &dev->archdata;
>
> - /* If we run without iommu, no need to do anything */
> - if (get_pci_dma_ops() == &dma_direct_ops)
> + if (get_pci_dma_ops() == &dma_direct_ops) {
> + archdata->dma_data = (void *)dma_direct_offset;
> return;
> + }
>
> /* Current implementation uses the first window available in that
> * node's iommu. We -might- do something smarter later though it may
> @@ -690,6 +691,9 @@ static int __init cell_iommu_init_disabled(void)
>
> dma_direct_offset += base;
>
> + if (dma_direct_offset != 0)
> + ppc_md.pci_dma_dev_setup = cell_pci_dma_dev_setup;
> +
> printk("iommu: disabled, direct DMA offset is 0x%lx\n",
> dma_direct_offset);
>
^ permalink raw reply
* [PATCH 7/7] Remove bogus comment in dma_direct_alloc_coherent()
From: Michael Ellerman @ 2008-01-21 5:42 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Arnd Bergmann, cbe-oss-dev
In-Reply-To: <2949748ba6ad7e14f0768ac3889267e42c050d7a.1200894155.git.michael@ellerman.id.au>
Since commit c80d9133e99de1af607314107910a2a1645efb17 (Make direct DMA use
node local allocations) went in this comment makes no sense.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/kernel/dma_64.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index 72fdc06..8423907 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -130,7 +130,6 @@ static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
void *ret;
int node = dev->archdata.numa_node;
- /* TODO: Maybe use the numa node here too ? */
page = alloc_pages_node(node, flag, get_order(size));
if (page == NULL)
return NULL;
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 6/7] Remove the global dma_direct_offset
From: Michael Ellerman @ 2008-01-21 5:42 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Arnd Bergmann, cbe-oss-dev
In-Reply-To: <2949748ba6ad7e14f0768ac3889267e42c050d7a.1200894155.git.michael@ellerman.id.au>
We no longer need the global dma_direct_offset, update the comment to
reflect the new reality.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/kernel/dma_64.c | 7 ++++---
include/asm-powerpc/dma-mapping.h | 2 --
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index a2d076d..72fdc06 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -112,10 +112,11 @@ EXPORT_SYMBOL(dma_iommu_ops);
/*
* Generic direct DMA implementation
*
- * This implementation supports a global offset that can be applied if
- * the address at which memory is visible to devices is not 0.
+ * This implementation supports a per-device offset that can be applied if
+ * the address at which memory is visible to devices is not 0. Platform code
+ * can set archdata.dma_data to an unsigned long holding the offset. By
+ * default the offset is zero.
*/
-unsigned long dma_direct_offset;
static unsigned long get_dma_direct_offset(struct device *dev)
{
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
index e974876..5eea6db 100644
--- a/include/asm-powerpc/dma-mapping.h
+++ b/include/asm-powerpc/dma-mapping.h
@@ -189,8 +189,6 @@ static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
extern struct dma_mapping_ops dma_iommu_ops;
extern struct dma_mapping_ops dma_direct_ops;
-extern unsigned long dma_direct_offset;
-
#else /* CONFIG_PPC64 */
#define dma_supported(dev, mask) (1)
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 5/7] Have celleb use its own dma_direct_offset variable
From: Michael Ellerman @ 2008-01-21 5:42 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Arnd Bergmann, cbe-oss-dev
In-Reply-To: <2949748ba6ad7e14f0768ac3889267e42c050d7a.1200894155.git.michael@ellerman.id.au>
Rather than using the global variable, have celleb use its own variable to
store the direct DMA offset.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/celleb/iommu.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/platforms/celleb/iommu.c b/arch/powerpc/platforms/celleb/iommu.c
index 843a66f..93b0efd 100644
--- a/arch/powerpc/platforms/celleb/iommu.c
+++ b/arch/powerpc/platforms/celleb/iommu.c
@@ -52,6 +52,8 @@ static int __init find_dma_window(u64 *io_space_id, u64 *ioid,
return 0;
}
+static unsigned long celleb_dma_direct_offset;
+
static void __init celleb_init_direct_mapping(void)
{
u64 lpar_addr, io_addr;
@@ -69,13 +71,13 @@ static void __init celleb_init_direct_mapping(void)
ioid, DMA_FLAGS);
}
- dma_direct_offset = dma_base;
+ celleb_dma_direct_offset = dma_base;
}
static void celleb_dma_dev_setup(struct device *dev)
{
dev->archdata.dma_ops = get_pci_dma_ops();
- dev->archdata.dma_data = (void *)dma_direct_offset;
+ dev->archdata.dma_data = (void *)celleb_dma_direct_offset;
}
static void celleb_pci_dma_dev_setup(struct pci_dev *pdev)
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 4/7] Have cell use its own dma_direct_offset variable
From: Michael Ellerman @ 2008-01-21 5:42 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Arnd Bergmann, cbe-oss-dev
In-Reply-To: <2949748ba6ad7e14f0768ac3889267e42c050d7a.1200894155.git.michael@ellerman.id.au>
Rather than using the global variable, have cell use its own variable to
store the direct DMA offset.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/cell/iommu.c | 12 +++++++-----
1 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 9682b63..7f45d59 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -490,6 +490,8 @@ static struct cbe_iommu *cell_iommu_for_node(int nid)
return NULL;
}
+static unsigned long cell_dma_direct_offset;
+
static void cell_dma_dev_setup(struct device *dev)
{
struct iommu_window *window;
@@ -497,7 +499,7 @@ static void cell_dma_dev_setup(struct device *dev)
struct dev_archdata *archdata = &dev->archdata;
if (get_pci_dma_ops() == &dma_direct_ops) {
- archdata->dma_data = (void *)dma_direct_offset;
+ archdata->dma_data = (void *)cell_dma_direct_offset;
return;
}
@@ -655,7 +657,7 @@ static int __init cell_iommu_init_disabled(void)
/* If we have no Axon, we set up the spider DMA magic offset */
if (of_find_node_by_name(NULL, "axon") == NULL)
- dma_direct_offset = SPIDER_DMA_OFFSET;
+ cell_dma_direct_offset = SPIDER_DMA_OFFSET;
/* Now we need to check to see where the memory is mapped
* in PCI space. We assume that all busses use the same dma
@@ -689,13 +691,13 @@ static int __init cell_iommu_init_disabled(void)
return -ENODEV;
}
- dma_direct_offset += base;
+ cell_dma_direct_offset += base;
- if (dma_direct_offset != 0)
+ if (cell_dma_direct_offset != 0)
ppc_md.pci_dma_dev_setup = cell_pci_dma_dev_setup;
printk("iommu: disabled, direct DMA offset is 0x%lx\n",
- dma_direct_offset);
+ cell_dma_direct_offset);
return 0;
}
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 3/7] Use archdata.dma_data in dma_direct_ops and add the offset
From: Michael Ellerman @ 2008-01-21 5:42 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Arnd Bergmann, cbe-oss-dev
In-Reply-To: <2949748ba6ad7e14f0768ac3889267e42c050d7a.1200894155.git.michael@ellerman.id.au>
Now that all platforms using dma_direct_offset setup the archdata.dma_data
correctly, we can change the dma_direct_ops to retrieve the offset from
the dma_data, rather than directly from the global.
While we're here, change the way the offset is used - instead of or'ing it
into the value, add it. This should have no effect on current implementations
where the offset is far larger than memory, however in future we may want
to use smaller offsets.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/kernel/dma_64.c | 11 ++++++++---
1 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index 14206e3..a2d076d 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -117,6 +117,11 @@ EXPORT_SYMBOL(dma_iommu_ops);
*/
unsigned long dma_direct_offset;
+static unsigned long get_dma_direct_offset(struct device *dev)
+{
+ return (unsigned long)dev->archdata.dma_data;
+}
+
static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag)
{
@@ -130,7 +135,7 @@ static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
return NULL;
ret = page_address(page);
memset(ret, 0, size);
- *dma_handle = virt_to_abs(ret) | dma_direct_offset;
+ *dma_handle = virt_to_abs(ret) + get_dma_direct_offset(dev);
return ret;
}
@@ -145,7 +150,7 @@ static dma_addr_t dma_direct_map_single(struct device *dev, void *ptr,
size_t size,
enum dma_data_direction direction)
{
- return virt_to_abs(ptr) | dma_direct_offset;
+ return virt_to_abs(ptr) + get_dma_direct_offset(dev);
}
static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr,
@@ -161,7 +166,7 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
int i;
for_each_sg(sgl, sg, nents, i) {
- sg->dma_address = sg_phys(sg) | dma_direct_offset;
+ sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev);
sg->dma_length = sg->length;
}
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 2/7] Add celleb_dma_dev_setup()
From: Michael Ellerman @ 2008-01-21 5:42 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Arnd Bergmann, cbe-oss-dev
In-Reply-To: <2949748ba6ad7e14f0768ac3889267e42c050d7a.1200894155.git.michael@ellerman.id.au>
Celleb always uses dma_direct_ops, and sets dma_direct_offset, so it too
should set dma_data to dma_direct_offset.
Currently there's no pci_dma_dev_setup() routine for Celleb so add one.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/celleb/iommu.c | 14 +++++++++++++-
1 files changed, 13 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/platforms/celleb/iommu.c b/arch/powerpc/platforms/celleb/iommu.c
index 41e1e6f..843a66f 100644
--- a/arch/powerpc/platforms/celleb/iommu.c
+++ b/arch/powerpc/platforms/celleb/iommu.c
@@ -72,6 +72,17 @@ static void __init celleb_init_direct_mapping(void)
dma_direct_offset = dma_base;
}
+static void celleb_dma_dev_setup(struct device *dev)
+{
+ dev->archdata.dma_ops = get_pci_dma_ops();
+ dev->archdata.dma_data = (void *)dma_direct_offset;
+}
+
+static void celleb_pci_dma_dev_setup(struct pci_dev *pdev)
+{
+ celleb_dma_dev_setup(&pdev->dev);
+}
+
static int celleb_of_bus_notify(struct notifier_block *nb,
unsigned long action, void *data)
{
@@ -81,7 +92,7 @@ static int celleb_of_bus_notify(struct notifier_block *nb,
if (action != BUS_NOTIFY_ADD_DEVICE)
return 0;
- dev->archdata.dma_ops = get_pci_dma_ops();
+ celleb_dma_dev_setup(dev);
return 0;
}
@@ -94,6 +105,7 @@ static int __init celleb_init_iommu(void)
{
celleb_init_direct_mapping();
set_pci_dma_ops(&dma_direct_ops);
+ ppc_md.pci_dma_dev_setup = celleb_pci_dma_dev_setup;
bus_register_notifier(&of_platform_bus_type, &celleb_of_bus_notifier);
return 0;
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox