aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/lm78.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/lm78.c')
-rw-r--r--drivers/hwmon/lm78.c38
1 files changed, 16 insertions, 22 deletions
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
index f284ecbb9ca8..177eaddde321 100644
--- a/drivers/hwmon/lm78.c
+++ b/drivers/hwmon/lm78.c
@@ -114,22 +114,16 @@ static inline int TEMP_FROM_REG(s8 val)
114 114
115#define DIV_FROM_REG(val) (1 << (val)) 115#define DIV_FROM_REG(val) (1 << (val))
116 116
117/* There are some complications in a module like this. First off, LM78 chips
118 may be both present on the SMBus and the ISA bus, and we have to handle
119 those cases separately at some places. Second, there might be several
120 LM78 chips available (well, actually, that is probably never done; but
121 it is a clean illustration of how to handle a case like that). Finally,
122 a specific chip may be attached to *both* ISA and SMBus, and we would
123 not like to detect it double. */
124
125/* For ISA chips, we abuse the i2c_client addr and name fields. We also use
126 the driver field to differentiate between I2C and ISA chips. */
127struct lm78_data { 117struct lm78_data {
128 struct i2c_client client; 118 struct i2c_client client;
129 struct device *hwmon_dev; 119 struct device *hwmon_dev;
130 struct mutex lock; 120 struct mutex lock;
131 enum chips type; 121 enum chips type;
132 122
123 /* For ISA device only */
124 const char *name;
125 int isa_addr;
126
133 struct mutex update_lock; 127 struct mutex update_lock;
134 char valid; /* !=0 if following fields are valid */ 128 char valid; /* !=0 if following fields are valid */
135 unsigned long last_updated; /* In jiffies */ 129 unsigned long last_updated; /* In jiffies */
@@ -536,7 +530,7 @@ static ssize_t show_name(struct device *dev, struct device_attribute
536{ 530{
537 struct lm78_data *data = dev_get_drvdata(dev); 531 struct lm78_data *data = dev_get_drvdata(dev);
538 532
539 return sprintf(buf, "%s\n", data->client.name); 533 return sprintf(buf, "%s\n", data->name);
540} 534}
541static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); 535static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
542 536
@@ -707,7 +701,6 @@ static int __devinit lm78_isa_probe(struct platform_device *pdev)
707 int err; 701 int err;
708 struct lm78_data *data; 702 struct lm78_data *data;
709 struct resource *res; 703 struct resource *res;
710 const char *name;
711 704
712 /* Reserve the ISA region */ 705 /* Reserve the ISA region */
713 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 706 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
@@ -721,18 +714,16 @@ static int __devinit lm78_isa_probe(struct platform_device *pdev)
721 goto exit_release_region; 714 goto exit_release_region;
722 } 715 }
723 mutex_init(&data->lock); 716 mutex_init(&data->lock);
724 data->client.addr = res->start; 717 data->isa_addr = res->start;
725 i2c_set_clientdata(&data->client, data);
726 platform_set_drvdata(pdev, data); 718 platform_set_drvdata(pdev, data);
727 719
728 if (lm78_read_value(data, LM78_REG_CHIPID) & 0x80) { 720 if (lm78_read_value(data, LM78_REG_CHIPID) & 0x80) {
729 data->type = lm79; 721 data->type = lm79;
730 name = "lm79"; 722 data->name = "lm79";
731 } else { 723 } else {
732 data->type = lm78; 724 data->type = lm78;
733 name = "lm78"; 725 data->name = "lm78";
734 } 726 }
735 strlcpy(data->client.name, name, I2C_NAME_SIZE);
736 727
737 /* Initialize the LM78 chip */ 728 /* Initialize the LM78 chip */
738 lm78_init_device(data); 729 lm78_init_device(data);
@@ -763,13 +754,16 @@ static int __devinit lm78_isa_probe(struct platform_device *pdev)
763static int __devexit lm78_isa_remove(struct platform_device *pdev) 754static int __devexit lm78_isa_remove(struct platform_device *pdev)
764{ 755{
765 struct lm78_data *data = platform_get_drvdata(pdev); 756 struct lm78_data *data = platform_get_drvdata(pdev);
757 struct resource *res;
766 758
767 hwmon_device_unregister(data->hwmon_dev); 759 hwmon_device_unregister(data->hwmon_dev);
768 sysfs_remove_group(&pdev->dev.kobj, &lm78_group); 760 sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
769 device_remove_file(&pdev->dev, &dev_attr_name); 761 device_remove_file(&pdev->dev, &dev_attr_name);
770 release_region(data->client.addr + LM78_ADDR_REG_OFFSET, 2);
771 kfree(data); 762 kfree(data);
772 763
764 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
765 release_region(res->start + LM78_ADDR_REG_OFFSET, 2);
766
773 return 0; 767 return 0;
774} 768}
775 769
@@ -785,8 +779,8 @@ static int lm78_read_value(struct lm78_data *data, u8 reg)
785 if (!client->driver) { /* ISA device */ 779 if (!client->driver) { /* ISA device */
786 int res; 780 int res;
787 mutex_lock(&data->lock); 781 mutex_lock(&data->lock);
788 outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET); 782 outb_p(reg, data->isa_addr + LM78_ADDR_REG_OFFSET);
789 res = inb_p(client->addr + LM78_DATA_REG_OFFSET); 783 res = inb_p(data->isa_addr + LM78_DATA_REG_OFFSET);
790 mutex_unlock(&data->lock); 784 mutex_unlock(&data->lock);
791 return res; 785 return res;
792 } else 786 } else
@@ -806,8 +800,8 @@ static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value)
806 800
807 if (!client->driver) { /* ISA device */ 801 if (!client->driver) { /* ISA device */
808 mutex_lock(&data->lock); 802 mutex_lock(&data->lock);
809 outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET); 803 outb_p(reg, data->isa_addr + LM78_ADDR_REG_OFFSET);
810 outb_p(value, client->addr + LM78_DATA_REG_OFFSET); 804 outb_p(value, data->isa_addr + LM78_DATA_REG_OFFSET);
811 mutex_unlock(&data->lock); 805 mutex_unlock(&data->lock);
812 return 0; 806 return 0;
813 } else 807 } else