[PATCH] hwmon: Request the I/O regions in platform drivers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Jean,

I get
Trying to free nonexistent resource <0000000000006000-000000000000607f>
when unloading the module.

After module load, the resources are properly allocated (cat /proc/ioports):
6000-607f : vt1211
  6000-607f : vt1211

I ran into this very same problem in the past where I get this warning
after releasing a previously requested io region. Never figured out
what's going on...

...juerg


On 2/21/07, Jean Delvare <khali at linux-fr.org> wrote:
> 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 regions request
> and release calls.
>
> It works fine with my Fintek F71805F chip. Juerg, can you please test
> this patch with your VIA VT1211 chip?
>
> Signed-off-by: Jean Delvare <khali at linux-fr.org>
> ---
>  drivers/hwmon/f71805f.c |   16 +++++++++++++++-
>  drivers/hwmon/pc87427.c |   15 ++++++++++++++-
>  drivers/hwmon/vt1211.c  |   13 +++++++++++++
>  3 files changed, 42 insertions(+), 2 deletions(-)
>
> --- linux-2.6.21-rc1.orig/drivers/hwmon/f71805f.c       2007-02-21 08:34:22.000000000 +0100
> +++ linux-2.6.21-rc1/drivers/hwmon/f71805f.c    2007-02-21 19:41:56.000000000 +0100
> @@ -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(struc
>         }
>
>         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(struc
>
>         /* 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(stru
>         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;
>  }
>
> --- linux-2.6.21-rc1.orig/drivers/hwmon/pc87427.c       2007-02-04 19:44:54.000000000 +0100
> +++ linux-2.6.21-rc1/drivers/hwmon/pc87427.c    2007-02-21 19:21:16.000000000 +0100
> @@ -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(struc
>         /* 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(struc
>
>         /* 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(stru
>         }
>         kfree(data);
>
> +       res = platform_get_resource(pdev, IORESOURCE_IO, 0);
> +       release_region(res->start, res->end - res->start + 1);
> +
>         return 0;
>  }
>
> --- linux-2.6.21-rc1.orig/drivers/hwmon/vt1211.c        2007-02-21 08:34:22.000000000 +0100
> +++ linux-2.6.21-rc1/drivers/hwmon/vt1211.c     2007-02-21 19:45:36.000000000 +0100
> @@ -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
>         }
>
>         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;
>  }
>
>
>
> --
> Jean Delvare
>




[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux