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 >