X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fhwmon%2Fsmsc47b397.c;h=6f6d52b4fb64520f67581682acb3d63995343805;hb=3bb9db79235e19dbb18ba6f4a428a97c69115319;hp=09df56118e18e69fe6a0b5d0eac848d939cb5735;hpb=292fc1a5ff44d477ff335a343a48d2b67bbc70e3;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c index 09df561..6f6d52b 100644 --- a/drivers/hwmon/smsc47b397.c +++ b/drivers/hwmon/smsc47b397.c @@ -32,11 +32,17 @@ #include #include #include +#include #include #include #include +#include #include +static unsigned short force_id; +module_param(force_id, ushort, 0); +MODULE_PARM_DESC(force_id, "Override the detected device ID"); + static struct platform_device *pdev; #define DRVNAME "smsc47b397" @@ -93,7 +99,7 @@ static u8 smsc47b397_reg_temp[] = {0x25, 0x26, 0x27, 0x80}; struct smsc47b397_data { unsigned short addr; const char *name; - struct class_device *class_dev; + struct device *hwmon_dev; struct mutex lock; struct mutex update_lock; @@ -156,50 +162,39 @@ static int temp_from_reg(u8 reg) return (s8)reg * 1000; } -/* 0 <= nr <= 3 */ -static ssize_t show_temp(struct device *dev, char *buf, int nr) +static ssize_t show_temp(struct device *dev, struct device_attribute + *devattr, char *buf) { + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct smsc47b397_data *data = smsc47b397_update_device(dev); - return sprintf(buf, "%d\n", temp_from_reg(data->temp[nr])); + return sprintf(buf, "%d\n", temp_from_reg(data->temp[attr->index])); } -#define sysfs_temp(num) \ -static ssize_t show_temp##num(struct device *dev, struct device_attribute *attr, char *buf) \ -{ \ - return show_temp(dev, buf, num-1); \ -} \ -static DEVICE_ATTR(temp##num##_input, S_IRUGO, show_temp##num, NULL) - -sysfs_temp(1); -sysfs_temp(2); -sysfs_temp(3); -sysfs_temp(4); +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); +static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); +static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3); /* FAN: 1 RPM/bit REG: count of 90kHz pulses / revolution */ static int fan_from_reg(u16 reg) { + if (reg == 0 || reg == 0xffff) + return 0; return 90000 * 60 / reg; } -/* 0 <= nr <= 3 */ -static ssize_t show_fan(struct device *dev, char *buf, int nr) +static ssize_t show_fan(struct device *dev, struct device_attribute + *devattr, char *buf) { - struct smsc47b397_data *data = smsc47b397_update_device(dev); - return sprintf(buf, "%d\n", fan_from_reg(data->fan[nr])); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct smsc47b397_data *data = smsc47b397_update_device(dev); + return sprintf(buf, "%d\n", fan_from_reg(data->fan[attr->index])); } - -#define sysfs_fan(num) \ -static ssize_t show_fan##num(struct device *dev, struct device_attribute *attr, char *buf) \ -{ \ - return show_fan(dev, buf, num-1); \ -} \ -static DEVICE_ATTR(fan##num##_input, S_IRUGO, show_fan##num, NULL) - -sysfs_fan(1); -sysfs_fan(2); -sysfs_fan(3); -sysfs_fan(4); +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); +static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); +static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); +static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3); static ssize_t show_name(struct device *dev, struct device_attribute *devattr, char *buf) @@ -210,14 +205,14 @@ static ssize_t show_name(struct device *dev, struct device_attribute static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); static struct attribute *smsc47b397_attributes[] = { - &dev_attr_temp1_input.attr, - &dev_attr_temp2_input.attr, - &dev_attr_temp3_input.attr, - &dev_attr_temp4_input.attr, - &dev_attr_fan1_input.attr, - &dev_attr_fan2_input.attr, - &dev_attr_fan3_input.attr, - &dev_attr_fan4_input.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp4_input.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan3_input.dev_attr.attr, + &sensor_dev_attr_fan4_input.dev_attr.attr, &dev_attr_name.attr, NULL @@ -232,7 +227,7 @@ static int __devexit smsc47b397_remove(struct platform_device *pdev) struct smsc47b397_data *data = platform_get_drvdata(pdev); struct resource *res; - hwmon_device_unregister(data->class_dev); + hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&pdev->dev.kobj, &smsc47b397_group); res = platform_get_resource(pdev, IORESOURCE_IO, 0); release_region(res->start, SMSC_EXTENT); @@ -282,9 +277,9 @@ static int __devinit smsc47b397_probe(struct platform_device *pdev) if ((err = sysfs_create_group(&dev->kobj, &smsc47b397_group))) goto error_free; - data->class_dev = hwmon_device_register(dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); + data->hwmon_dev = hwmon_device_register(dev); + if (IS_ERR(data->hwmon_dev)) { + err = PTR_ERR(data->hwmon_dev); goto error_remove; } @@ -309,6 +304,10 @@ static int __init smsc47b397_device_add(unsigned short address) }; int err; + err = acpi_check_resource_conflict(&res); + if (err) + goto exit; + pdev = platform_device_alloc(DRVNAME, address); if (!pdev) { err = -ENOMEM; @@ -341,11 +340,23 @@ exit: static int __init smsc47b397_find(unsigned short *addr) { u8 id, rev; + char *name; superio_enter(); - id = superio_inb(SUPERIO_REG_DEVID); - - if ((id != 0x6f) && (id != 0x81)) { + id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID); + + switch(id) { + case 0x81: + name = "SCH5307-NS"; + break; + case 0x6f: + name = "LPC47B397-NC"; + break; + case 0x85: + case 0x8c: + name = "SCH5317"; + break; + default: superio_exit(); return -ENODEV; } @@ -358,7 +369,7 @@ static int __init smsc47b397_find(unsigned short *addr) printk(KERN_INFO DRVNAME ": found SMSC %s " "(base address 0x%04x, revision %u)\n", - id == 0x81 ? "SCH5307-NS" : "LPC47B397-NC", *addr, rev); + name, *addr, rev); superio_exit(); return 0;