]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
hwmon: Request the I/O regions in platform drivers
authorJean Delvare <khali@linux-fr.org>
Tue, 8 May 2007 15:21:59 +0000 (17:21 +0200)
committerJean Delvare <khali@hyperion.delvare>
Tue, 8 May 2007 15:21:59 +0000 (17:21 +0200)
My understanding of the resource management in the Linux 2.6 device
driver model is that the devices should declare their resources, and
then when a driver attaches to a device, it should request the
resources it will be using, so as to mark them busy. This is how the
PCI and PNP subsystems work, you can clearly see the two levels of
resources (declaration and request) in /proc/ioports for these
devices.

So I believe that our platform hardware monitoring drivers should
follow the same logic. At the moment, we only declare the resources
but we do not request them. This patch adds the I/O region request
and release calls.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
Acked-by: Juerg Haefliger <juergh@gmail.com>
drivers/hwmon/f71805f.c
drivers/hwmon/pc87427.c
drivers/hwmon/vt1211.c

index 7c2973487122cd139b22081225cbcbefefa28bae..cdbe309b8fc41275a64ee5bd906504f2bb808220 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
+#include <linux/ioport.h>
 #include <asm/io.h>
 
 static struct platform_device *pdev;
@@ -1140,6 +1141,13 @@ static int __devinit f71805f_probe(struct platform_device *pdev)
        }
 
        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+       if (!request_region(res->start + ADDR_REG_OFFSET, 2, DRVNAME)) {
+               err = -EBUSY;
+               dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n",
+                       (unsigned long)(res->start + ADDR_REG_OFFSET),
+                       (unsigned long)(res->start + ADDR_REG_OFFSET + 1));
+               goto exit_free;
+       }
        data->addr = res->start;
        data->name = names[sio_data->kind];
        mutex_init(&data->update_lock);
@@ -1165,7 +1173,7 @@ static int __devinit f71805f_probe(struct platform_device *pdev)
 
        /* Register sysfs interface files */
        if ((err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group)))
-               goto exit_free;
+               goto exit_release_region;
        if (data->has_in & (1 << 4)) { /* in4 */
                if ((err = sysfs_create_group(&pdev->dev.kobj,
                                              &f71805f_group_optin[0])))
@@ -1219,6 +1227,8 @@ exit_remove_files:
        for (i = 0; i < 4; i++)
                sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]);
        sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq);
+exit_release_region:
+       release_region(res->start + ADDR_REG_OFFSET, 2);
 exit_free:
        platform_set_drvdata(pdev, NULL);
        kfree(data);
@@ -1229,6 +1239,7 @@ exit:
 static int __devexit f71805f_remove(struct platform_device *pdev)
 {
        struct f71805f_data *data = platform_get_drvdata(pdev);
+       struct resource *res;
        int i;
 
        platform_set_drvdata(pdev, NULL);
@@ -1239,6 +1250,9 @@ static int __devexit f71805f_remove(struct platform_device *pdev)
        sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq);
        kfree(data);
 
+       res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+       release_region(res->start + ADDR_REG_OFFSET, 2);
+
        return 0;
 }
 
index affa21a5ccfd2372cc1abfcb52caa75ecbae62bb..29354fa26f81e3578b7db2dd6b4cc188f4fafff8 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
+#include <linux/ioport.h>
 #include <asm/io.h>
 
 static struct platform_device *pdev;
@@ -429,6 +430,12 @@ static int __devinit pc87427_probe(struct platform_device *pdev)
        /* This will need to be revisited when we add support for
           temperature and voltage monitoring. */
        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+       if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) {
+               err = -EBUSY;
+               dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n",
+                       (unsigned long)res->start, (unsigned long)res->end);
+               goto exit_kfree;
+       }
        data->address[0] = res->start;
 
        mutex_init(&data->lock);
@@ -438,7 +445,7 @@ static int __devinit pc87427_probe(struct platform_device *pdev)
 
        /* Register sysfs hooks */
        if ((err = device_create_file(&pdev->dev, &dev_attr_name)))
-               goto exit_kfree;
+               goto exit_release_region;
        for (i = 0; i < 8; i++) {
                if (!(data->fan_enabled & (1 << i)))
                        continue;
@@ -462,6 +469,8 @@ exit_remove_files:
                        continue;
                sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]);
        }
+exit_release_region:
+       release_region(res->start, res->end - res->start + 1);
 exit_kfree:
        platform_set_drvdata(pdev, NULL);
        kfree(data);
@@ -472,6 +481,7 @@ exit:
 static int __devexit pc87427_remove(struct platform_device *pdev)
 {
        struct pc87427_data *data = platform_get_drvdata(pdev);
+       struct resource *res;
        int i;
 
        platform_set_drvdata(pdev, NULL);
@@ -484,6 +494,9 @@ static int __devexit pc87427_remove(struct platform_device *pdev)
        }
        kfree(data);
 
+       res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+       release_region(res->start, res->end - res->start + 1);
+
        return 0;
 }
 
index 89c23d6add7be174190cbc90f2cf2f1b25d2be10..9f3e332c5b7fe129f6ec9a62baa3201168ecf0c3 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/hwmon-vid.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/ioport.h>
 #include <asm/io.h>
 
 static int uch_config = -1;
@@ -1130,6 +1131,12 @@ static int __devinit vt1211_probe(struct platform_device *pdev)
        }
 
        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+       if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) {
+               err = -EBUSY;
+               dev_err(dev, "Failed to request region 0x%lx-0x%lx\n",
+                       (unsigned long)res->start, (unsigned long)res->end);
+               goto EXIT_KFREE;
+       }
        data->addr = res->start;
        data->name = DRVNAME;
        mutex_init(&data->update_lock);
@@ -1197,6 +1204,8 @@ EXIT_DEV_REMOVE:
        dev_err(dev, "Sysfs interface creation failed (%d)\n", err);
 EXIT_DEV_REMOVE_SILENT:
        vt1211_remove_sysfs(pdev);
+       release_region(res->start, res->end - res->start + 1);
+EXIT_KFREE:
        platform_set_drvdata(pdev, NULL);
        kfree(data);
 EXIT:
@@ -1206,12 +1215,16 @@ EXIT:
 static int __devexit vt1211_remove(struct platform_device *pdev)
 {
        struct vt1211_data *data = platform_get_drvdata(pdev);
+       struct resource *res;
 
        hwmon_device_unregister(data->class_dev);
        vt1211_remove_sysfs(pdev);
        platform_set_drvdata(pdev, NULL);
        kfree(data);
 
+       res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+       release_region(res->start, res->end - res->start + 1);
+
        return 0;
 }