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: Jean Delvare <khali@linux-fr.org> Cc: Wolfgang Grandegger <wg@grandegger.com>
This commit is contained in:
parent
443850ce58
commit
360782dde0
|
@ -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)
|
||||||
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
|
||||||
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)
|
||||||
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)
|
||||||
|| ((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)
|
||||||
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)
|
||||||
|| ((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)
|
||||||
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)
|
||||||
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)
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue