Skip to content

Commit

Permalink
hwmon: Request the I/O regions in platform drivers
Browse files Browse the repository at this point in the history
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 <[email protected]>
Acked-by: Juerg Haefliger <[email protected]>
  • Loading branch information
Jean Delvare authored and Jean Delvare committed May 8, 2007
1 parent 00cb473 commit ce7ee4e
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
16 changes: 15 additions & 1 deletion drivers/hwmon/f71805f.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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])))
Expand Down Expand Up @@ -1219,6 +1227,8 @@ static int __devinit f71805f_probe(struct platform_device *pdev)
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);
Expand All @@ -1229,6 +1239,7 @@ static int __devinit f71805f_probe(struct platform_device *pdev)
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);
Expand All @@ -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;
}

Expand Down
15 changes: 14 additions & 1 deletion drivers/hwmon/pc87427.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -462,6 +469,8 @@ static int __devinit pc87427_probe(struct platform_device *pdev)
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);
Expand All @@ -472,6 +481,7 @@ static int __devinit pc87427_probe(struct platform_device *pdev)
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);
Expand All @@ -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;
}

Expand Down
13 changes: 13 additions & 0 deletions drivers/hwmon/vt1211.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -1197,6 +1204,8 @@ static int __devinit vt1211_probe(struct platform_device *pdev)
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:
Expand All @@ -1206,12 +1215,16 @@ static int __devinit vt1211_probe(struct platform_device *pdev)
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;
}

Expand Down

0 comments on commit ce7ee4e

Please sign in to comment.