提交 360782dd 编写于 作者: J Jean Delvare 提交者: Jean Delvare

hwmon: (w83781d) Stop abusing struct i2c_client for ISA devices

Upcoming changes to the I2C part of the w83781d driver will cause ISA
devices to no longer have a struct i2c_client at hand. So, we must
stop (ab)using it now.
Signed-off-by: NJean Delvare <khali@linux-fr.org>
Cc: Wolfgang Grandegger <wg@grandegger.com>
上级 443850ce
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
Copyright (c) 1998 - 2001 Frodo Looijaard <frodol@dds.nl>, Copyright (c) 1998 - 2001 Frodo Looijaard <frodol@dds.nl>,
Philip Edelbrock <phil@netroedge.com>, Philip Edelbrock <phil@netroedge.com>,
and Mark Studebaker <mdsxyz123@yahoo.com> and Mark Studebaker <mdsxyz123@yahoo.com>
Copyright (c) 2007 Jean Delvare <khali@linux-fr.org> Copyright (c) 2007 - 2008 Jean Delvare <khali@linux-fr.org>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -198,22 +198,16 @@ DIV_TO_REG(long val, enum chips type) ...@@ -198,22 +198,16 @@ DIV_TO_REG(long val, enum chips type)
return i; return i;
} }
/* There are some complications in a module like this. First off, W83781D chips
may be both present on the SMBus and the ISA bus, and we have to handle
those cases separately at some places. Second, there might be several
W83781D chips available (well, actually, that is probably never done; but
it is a clean illustration of how to handle a case like that). Finally,
a specific chip may be attached to *both* ISA and SMBus, and we would
not like to detect it double. */
/* For ISA chips, we abuse the i2c_client addr and name fields. We also use
the driver field to differentiate between I2C and ISA chips. */
struct w83781d_data { struct w83781d_data {
struct i2c_client client; struct i2c_client client;
struct device *hwmon_dev; struct device *hwmon_dev;
struct mutex lock; struct mutex lock;
enum chips type; enum chips type;
/* For ISA device only */
const char *name;
int isa_addr;
struct mutex update_lock; struct mutex update_lock;
char valid; /* !=0 if following fields are valid */ char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */ unsigned long last_updated; /* In jiffies */
...@@ -1625,7 +1619,7 @@ static ssize_t ...@@ -1625,7 +1619,7 @@ static ssize_t
show_name(struct device *dev, struct device_attribute *devattr, char *buf) show_name(struct device *dev, struct device_attribute *devattr, char *buf)
{ {
struct w83781d_data *data = dev_get_drvdata(dev); struct w83781d_data *data = dev_get_drvdata(dev);
return sprintf(buf, "%s\n", data->client.name); return sprintf(buf, "%s\n", data->name);
} }
static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
...@@ -1671,7 +1665,6 @@ static int w83781d_alias_detect(struct i2c_client *client, u8 chipid) ...@@ -1671,7 +1665,6 @@ static int w83781d_alias_detect(struct i2c_client *client, u8 chipid)
static int static int
w83781d_read_value_isa(struct w83781d_data *data, u16 reg) w83781d_read_value_isa(struct w83781d_data *data, u16 reg)
{ {
struct i2c_client *client = &data->client;
int word_sized, res; int word_sized, res;
word_sized = (((reg & 0xff00) == 0x100) word_sized = (((reg & 0xff00) == 0x100)
...@@ -1681,23 +1674,23 @@ w83781d_read_value_isa(struct w83781d_data *data, u16 reg) ...@@ -1681,23 +1674,23 @@ w83781d_read_value_isa(struct w83781d_data *data, u16 reg)
|| ((reg & 0x00ff) == 0x55)); || ((reg & 0x00ff) == 0x55));
if (reg & 0xff00) { if (reg & 0xff00) {
outb_p(W83781D_REG_BANK, outb_p(W83781D_REG_BANK,
client->addr + W83781D_ADDR_REG_OFFSET); data->isa_addr + W83781D_ADDR_REG_OFFSET);
outb_p(reg >> 8, outb_p(reg >> 8,
client->addr + W83781D_DATA_REG_OFFSET); data->isa_addr + W83781D_DATA_REG_OFFSET);
} }
outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET); outb_p(reg & 0xff, data->isa_addr + W83781D_ADDR_REG_OFFSET);
res = inb_p(client->addr + W83781D_DATA_REG_OFFSET); res = inb_p(data->isa_addr + W83781D_DATA_REG_OFFSET);
if (word_sized) { if (word_sized) {
outb_p((reg & 0xff) + 1, outb_p((reg & 0xff) + 1,
client->addr + W83781D_ADDR_REG_OFFSET); data->isa_addr + W83781D_ADDR_REG_OFFSET);
res = res =
(res << 8) + inb_p(client->addr + (res << 8) + inb_p(data->isa_addr +
W83781D_DATA_REG_OFFSET); W83781D_DATA_REG_OFFSET);
} }
if (reg & 0xff00) { if (reg & 0xff00) {
outb_p(W83781D_REG_BANK, outb_p(W83781D_REG_BANK,
client->addr + W83781D_ADDR_REG_OFFSET); data->isa_addr + W83781D_ADDR_REG_OFFSET);
outb_p(0, client->addr + W83781D_DATA_REG_OFFSET); outb_p(0, data->isa_addr + W83781D_DATA_REG_OFFSET);
} }
return res; return res;
} }
...@@ -1705,7 +1698,6 @@ w83781d_read_value_isa(struct w83781d_data *data, u16 reg) ...@@ -1705,7 +1698,6 @@ w83781d_read_value_isa(struct w83781d_data *data, u16 reg)
static void static void
w83781d_write_value_isa(struct w83781d_data *data, u16 reg, u16 value) w83781d_write_value_isa(struct w83781d_data *data, u16 reg, u16 value)
{ {
struct i2c_client *client = &data->client;
int word_sized; int word_sized;
word_sized = (((reg & 0xff00) == 0x100) word_sized = (((reg & 0xff00) == 0x100)
...@@ -1714,22 +1706,22 @@ w83781d_write_value_isa(struct w83781d_data *data, u16 reg, u16 value) ...@@ -1714,22 +1706,22 @@ w83781d_write_value_isa(struct w83781d_data *data, u16 reg, u16 value)
|| ((reg & 0x00ff) == 0x55)); || ((reg & 0x00ff) == 0x55));
if (reg & 0xff00) { if (reg & 0xff00) {
outb_p(W83781D_REG_BANK, outb_p(W83781D_REG_BANK,
client->addr + W83781D_ADDR_REG_OFFSET); data->isa_addr + W83781D_ADDR_REG_OFFSET);
outb_p(reg >> 8, outb_p(reg >> 8,
client->addr + W83781D_DATA_REG_OFFSET); data->isa_addr + W83781D_DATA_REG_OFFSET);
} }
outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET); outb_p(reg & 0xff, data->isa_addr + W83781D_ADDR_REG_OFFSET);
if (word_sized) { if (word_sized) {
outb_p(value >> 8, outb_p(value >> 8,
client->addr + W83781D_DATA_REG_OFFSET); data->isa_addr + W83781D_DATA_REG_OFFSET);
outb_p((reg & 0xff) + 1, outb_p((reg & 0xff) + 1,
client->addr + W83781D_ADDR_REG_OFFSET); data->isa_addr + W83781D_ADDR_REG_OFFSET);
} }
outb_p(value & 0xff, client->addr + W83781D_DATA_REG_OFFSET); outb_p(value & 0xff, data->isa_addr + W83781D_DATA_REG_OFFSET);
if (reg & 0xff00) { if (reg & 0xff00) {
outb_p(W83781D_REG_BANK, outb_p(W83781D_REG_BANK,
client->addr + W83781D_ADDR_REG_OFFSET); data->isa_addr + W83781D_ADDR_REG_OFFSET);
outb_p(0, client->addr + W83781D_DATA_REG_OFFSET); outb_p(0, data->isa_addr + W83781D_DATA_REG_OFFSET);
} }
} }
...@@ -1774,7 +1766,6 @@ w83781d_isa_probe(struct platform_device *pdev) ...@@ -1774,7 +1766,6 @@ w83781d_isa_probe(struct platform_device *pdev)
int err, reg; int err, reg;
struct w83781d_data *data; struct w83781d_data *data;
struct resource *res; struct resource *res;
const char *name;
/* Reserve the ISA region */ /* Reserve the ISA region */
res = platform_get_resource(pdev, IORESOURCE_IO, 0); res = platform_get_resource(pdev, IORESOURCE_IO, 0);
...@@ -1790,21 +1781,19 @@ w83781d_isa_probe(struct platform_device *pdev) ...@@ -1790,21 +1781,19 @@ w83781d_isa_probe(struct platform_device *pdev)
goto exit_release_region; goto exit_release_region;
} }
mutex_init(&data->lock); mutex_init(&data->lock);
data->client.addr = res->start; data->isa_addr = res->start;
i2c_set_clientdata(&data->client, data);
platform_set_drvdata(pdev, data); platform_set_drvdata(pdev, data);
reg = w83781d_read_value(data, W83781D_REG_WCHIPID); reg = w83781d_read_value(data, W83781D_REG_WCHIPID);
switch (reg) { switch (reg) {
case 0x30: case 0x30:
data->type = w83782d; data->type = w83782d;
name = "w83782d"; data->name = "w83782d";
break; break;
default: default:
data->type = w83781d; data->type = w83781d;
name = "w83781d"; data->name = "w83781d";
} }
strlcpy(data->client.name, name, I2C_NAME_SIZE);
/* Initialize the W83781D chip */ /* Initialize the W83781D chip */
w83781d_init_device(&pdev->dev); w83781d_init_device(&pdev->dev);
...@@ -1846,7 +1835,7 @@ w83781d_isa_remove(struct platform_device *pdev) ...@@ -1846,7 +1835,7 @@ w83781d_isa_remove(struct platform_device *pdev)
sysfs_remove_group(&pdev->dev.kobj, &w83781d_group); sysfs_remove_group(&pdev->dev.kobj, &w83781d_group);
sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt); sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt);
device_remove_file(&pdev->dev, &dev_attr_name); device_remove_file(&pdev->dev, &dev_attr_name);
release_region(data->client.addr + W83781D_ADDR_REG_OFFSET, 2); release_region(data->isa_addr + W83781D_ADDR_REG_OFFSET, 2);
kfree(data); kfree(data);
return 0; return 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册