summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <greg@kroah.com>2004-06-21 01:14:21 -0700
committerGreg Kroah-Hartman <greg@kroah.com>2004-06-21 01:14:21 -0700
commit269986dcf4017c4bd44aa1f81d3b94349ca93296 (patch)
tree96a0a74ae12f39af1a7f5e2062dea3e8987f28ee
parent9a85e04ec3e527234d8a2210e6ba04d7af9a4298 (diff)
parentc4a9c8212b8e954da29dc2e9002842729c0ba6d1 (diff)
merge
-rw-r--r--MAINTAINERS6
-rw-r--r--arch/i386/kernel/cpuid.c73
-rw-r--r--arch/i386/kernel/msr.c71
-rw-r--r--drivers/base/base.h5
-rw-r--r--drivers/base/bus.c194
-rw-r--r--drivers/base/class.c117
-rw-r--r--drivers/base/class_simple.c12
-rw-r--r--drivers/base/core.c48
-rw-r--r--drivers/base/driver.c16
-rw-r--r--drivers/base/firmware.c6
-rw-r--r--drivers/base/firmware_class.c10
-rw-r--r--drivers/base/init.c4
-rw-r--r--drivers/base/interface.c18
-rw-r--r--drivers/base/node.c14
-rw-r--r--drivers/base/platform.c126
-rw-r--r--drivers/base/power/main.c14
-rw-r--r--drivers/base/power/power.h8
-rw-r--r--drivers/base/power/resume.c12
-rw-r--r--drivers/base/power/runtime.c8
-rw-r--r--drivers/base/power/shutdown.c18
-rw-r--r--drivers/base/power/suspend.c42
-rw-r--r--drivers/base/power/sysfs.c18
-rw-r--r--drivers/base/sys.c102
-rw-r--r--drivers/char/raw.c25
-rw-r--r--drivers/i2c/busses/i2c-piix4.c2
-rw-r--r--drivers/i2c/chips/asb100.c66
-rw-r--r--drivers/i2c/chips/it87.c72
-rw-r--r--drivers/i2c/chips/lm78.c22
-rw-r--r--drivers/i2c/chips/lm85.c26
-rw-r--r--drivers/i2c/chips/via686a.c18
-rw-r--r--drivers/i2c/chips/w83627hf.c197
-rw-r--r--drivers/i2c/chips/w83781d.c30
-rw-r--r--drivers/i2c/chips/w83l785ts.c4
-rw-r--r--drivers/i2c/i2c-dev.c7
-rw-r--r--drivers/pci/pci-driver.c1
-rw-r--r--drivers/pci/pci-sysfs.c33
-rw-r--r--drivers/pci/pci.h1
-rw-r--r--drivers/scsi/scsi_debug.c18
-rw-r--r--drivers/scsi/scsi_sysfs.c14
-rw-r--r--drivers/scsi/scsi_transport_spi.c2
-rw-r--r--fs/sysfs/inode.c7
-rw-r--r--include/linux/device.h41
-rw-r--r--include/linux/i2c-id.h12
-rw-r--r--include/linux/module.h19
-rw-r--r--include/linux/sysfs.h21
-rw-r--r--kernel/module.c100
46 files changed, 1160 insertions, 520 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 1b254cd76b4b..9d6c1955bd14 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -703,6 +703,12 @@ M: jrv@vanzandt.mv.com
L: blinux-list@redhat.com
S: Maintained
+DRIVER CORE, KOBJECTS, AND SYSFS
+P: Greg Kroah-Hartman
+M: greg@kroah.com
+L: linux-kernel@vger.kernel.org
+S: Supported
+
DRM DRIVERS
L: dri-devel@lists.sourceforge.net
S: Supported
diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c
index 5a997a3716fc..32a0984318f6 100644
--- a/arch/i386/kernel/cpuid.c
+++ b/arch/i386/kernel/cpuid.c
@@ -36,12 +36,17 @@
#include <linux/fs.h>
#include <linux/smp_lock.h>
#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/cpu.h>
+#include <linux/notifier.h>
#include <asm/processor.h>
#include <asm/msr.h>
#include <asm/uaccess.h>
#include <asm/system.h>
+static struct class_simple *cpuid_class;
+
#ifdef CONFIG_SMP
struct cpuid_command {
@@ -153,20 +158,84 @@ static struct file_operations cpuid_fops = {
.open = cpuid_open,
};
+static int cpuid_class_simple_device_add(int i)
+{
+ int err = 0;
+ struct class_device *class_err;
+
+ class_err = class_simple_device_add(cpuid_class, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i);
+ if (IS_ERR(class_err))
+ err = PTR_ERR(class_err);
+ return err;
+}
+
+static int __devinit cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned long)hcpu;
+
+ switch (action) {
+ case CPU_ONLINE:
+ cpuid_class_simple_device_add(cpu);
+ break;
+ case CPU_DEAD:
+ class_simple_device_remove(MKDEV(CPUID_MAJOR, cpu));
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block cpuid_class_cpu_notifier =
+{
+ .notifier_call = cpuid_class_cpu_callback,
+};
+
int __init cpuid_init(void)
{
+ int i, err = 0;
+ i = 0;
+
if (register_chrdev(CPUID_MAJOR, "cpu/cpuid", &cpuid_fops)) {
printk(KERN_ERR "cpuid: unable to get major %d for cpuid\n",
CPUID_MAJOR);
- return -EBUSY;
+ err = -EBUSY;
+ goto out;
+ }
+ cpuid_class = class_simple_create(THIS_MODULE, "cpuid");
+ if (IS_ERR(cpuid_class)) {
+ err = PTR_ERR(cpuid_class);
+ goto out_chrdev;
}
+ for_each_online_cpu(i) {
+ err = cpuid_class_simple_device_add(i);
+ if (err != 0)
+ goto out_class;
+ }
+ register_cpu_notifier(&cpuid_class_cpu_notifier);
- return 0;
+ err = 0;
+ goto out;
+
+out_class:
+ i = 0;
+ for_each_online_cpu(i) {
+ class_simple_device_remove(MKDEV(CPUID_MAJOR, i));
+ }
+ class_simple_destroy(cpuid_class);
+out_chrdev:
+ unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
+out:
+ return err;
}
void __exit cpuid_exit(void)
{
+ int cpu = 0;
+
+ for_each_online_cpu(cpu)
+ class_simple_device_remove(MKDEV(CPUID_MAJOR, cpu));
+ class_simple_destroy(cpuid_class);
unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
+ unregister_cpu_notifier(&cpuid_class_cpu_notifier);
}
module_init(cpuid_init);
diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c
index 1a1093e4a4c2..670a71efafb3 100644
--- a/arch/i386/kernel/msr.c
+++ b/arch/i386/kernel/msr.c
@@ -35,12 +35,17 @@
#include <linux/smp_lock.h>
#include <linux/major.h>
#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/cpu.h>
+#include <linux/notifier.h>
#include <asm/processor.h>
#include <asm/msr.h>
#include <asm/uaccess.h>
#include <asm/system.h>
+static struct class_simple *msr_class;
+
/* Note: "err" is handled in a funny way below. Otherwise one version
of gcc or another breaks. */
@@ -255,20 +260,82 @@ static struct file_operations msr_fops = {
.open = msr_open,
};
+static int msr_class_simple_device_add(int i)
+{
+ int err = 0;
+ struct class_device *class_err;
+
+ class_err = class_simple_device_add(msr_class, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i);
+ if (IS_ERR(class_err))
+ err = PTR_ERR(class_err);
+ return err;
+}
+
+static int __devinit msr_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned long)hcpu;
+
+ switch (action) {
+ case CPU_ONLINE:
+ msr_class_simple_device_add(cpu);
+ break;
+ case CPU_DEAD:
+ class_simple_device_remove(MKDEV(MSR_MAJOR, cpu));
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block msr_class_cpu_notifier =
+{
+ .notifier_call = msr_class_cpu_callback,
+};
+
int __init msr_init(void)
{
+ int i, err = 0;
+ i = 0;
+
if (register_chrdev(MSR_MAJOR, "cpu/msr", &msr_fops)) {
printk(KERN_ERR "msr: unable to get major %d for msr\n",
MSR_MAJOR);
- return -EBUSY;
+ err = -EBUSY;
+ goto out;
+ }
+ msr_class = class_simple_create(THIS_MODULE, "msr");
+ if (IS_ERR(msr_class)) {
+ err = PTR_ERR(msr_class);
+ goto out_chrdev;
}
+ for_each_online_cpu(i) {
+ err = msr_class_simple_device_add(i);
+ if (err != 0)
+ goto out_class;
+ }
+ register_cpu_notifier(&msr_class_cpu_notifier);
- return 0;
+ err = 0;
+ goto out;
+
+out_class:
+ i = 0;
+ for_each_online_cpu(i)
+ class_simple_device_remove(MKDEV(MSR_MAJOR, i));
+ class_simple_destroy(msr_class);
+out_chrdev:
+ unregister_chrdev(MSR_MAJOR, "cpu/msr");
+out:
+ return err;
}
void __exit msr_exit(void)
{
+ int cpu = 0;
+ for_each_online_cpu(cpu)
+ class_simple_device_remove(MKDEV(MSR_MAJOR, cpu));
+ class_simple_destroy(msr_class);
unregister_chrdev(MSR_MAJOR, "cpu/msr");
+ unregister_cpu_notifier(&msr_class_cpu_notifier);
}
module_init(msr_init);
diff --git a/drivers/base/base.h b/drivers/base/base.h
index da16cc5c9e30..8d1e8bd48632 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -6,12 +6,13 @@ extern void bus_remove_driver(struct device_driver *);
static inline struct class_device *to_class_dev(struct kobject *obj)
{
- return container_of(obj,struct class_device,kobj);
+ return container_of(obj, struct class_device, kobj);
}
+
static inline
struct class_device_attribute *to_class_dev_attr(struct attribute *_attr)
{
- return container_of(_attr,struct class_device_attribute,attr);
+ return container_of(_attr, struct class_device_attribute, attr);
}
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index b40af6a72afe..02ff97df6dee 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
- *
+ *
* This file is released under the GPLv2
*
*/
@@ -17,17 +17,17 @@
#include "base.h"
#include "power/power.h"
-#define to_dev(node) container_of(node,struct device,bus_list)
-#define to_drv(node) container_of(node,struct device_driver,kobj.entry)
+#define to_dev(node) container_of(node, struct device, bus_list)
+#define to_drv(node) container_of(node, struct device_driver, kobj.entry)
-#define to_bus_attr(_attr) container_of(_attr,struct bus_attribute,attr)
-#define to_bus(obj) container_of(obj,struct bus_type,subsys.kset.kobj)
+#define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr)
+#define to_bus(obj) container_of(obj, struct bus_type, subsys.kset.kobj)
/*
* sysfs bindings for drivers
*/
-#define to_drv_attr(_attr) container_of(_attr,struct driver_attribute,attr)
+#define to_drv_attr(_attr) container_of(_attr, struct driver_attribute, attr)
#define to_driver(obj) container_of(obj, struct device_driver, kobj)
@@ -39,12 +39,12 @@ drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
ssize_t ret = 0;
if (drv_attr->show)
- ret = drv_attr->show(drv,buf);
+ ret = drv_attr->show(drv, buf);
return ret;
}
static ssize_t
-drv_attr_store(struct kobject * kobj, struct attribute * attr,
+drv_attr_store(struct kobject * kobj, struct attribute * attr,
const char * buf, size_t count)
{
struct driver_attribute * drv_attr = to_drv_attr(attr);
@@ -52,7 +52,7 @@ drv_attr_store(struct kobject * kobj, struct attribute * attr,
ssize_t ret = 0;
if (drv_attr->store)
- ret = drv_attr->store(drv,buf,count);
+ ret = drv_attr->store(drv, buf, count);
return ret;
}
@@ -87,12 +87,12 @@ bus_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
ssize_t ret = 0;
if (bus_attr->show)
- ret = bus_attr->show(bus,buf);
+ ret = bus_attr->show(bus, buf);
return ret;
}
static ssize_t
-bus_attr_store(struct kobject * kobj, struct attribute * attr,
+bus_attr_store(struct kobject * kobj, struct attribute * attr,
const char * buf, size_t count)
{
struct bus_attribute * bus_attr = to_bus_attr(attr);
@@ -100,7 +100,7 @@ bus_attr_store(struct kobject * kobj, struct attribute * attr,
ssize_t ret = 0;
if (bus_attr->store)
- ret = bus_attr->store(bus,buf,count);
+ ret = bus_attr->store(bus, buf, count);
return ret;
}
@@ -113,7 +113,7 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
{
int error;
if (get_bus(bus)) {
- error = sysfs_create_file(&bus->subsys.kset.kobj,&attr->attr);
+ error = sysfs_create_file(&bus->subsys.kset.kobj, &attr->attr);
put_bus(bus);
} else
error = -EINVAL;
@@ -123,7 +123,7 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr)
{
if (get_bus(bus)) {
- sysfs_remove_file(&bus->subsys.kset.kobj,&attr->attr);
+ sysfs_remove_file(&bus->subsys.kset.kobj, &attr->attr);
put_bus(bus);
}
}
@@ -133,7 +133,7 @@ static struct kobj_type ktype_bus = {
};
-decl_subsys(bus,&ktype_bus,NULL);
+decl_subsys(bus, &ktype_bus, NULL);
/**
* bus_for_each_dev - device iterator.
@@ -151,10 +151,10 @@ decl_subsys(bus,&ktype_bus,NULL);
*
* NOTE: The device that returns a non-zero value is not retained
* in any way, nor is its refcount incremented. If the caller needs
- * to retain this data, it should do, and increment the reference
+ * to retain this data, it should do, and increment the reference
* count in the supplied callback.
*/
-int bus_for_each_dev(struct bus_type * bus, struct device * start,
+int bus_for_each_dev(struct bus_type * bus, struct device * start,
void * data, int (*fn)(struct device *, void *))
{
struct device *dev;
@@ -170,7 +170,7 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start,
down_read(&bus->subsys.rwsem);
list_for_each_entry_continue(dev, head, bus_list) {
get_device(dev);
- error = fn(dev,data);
+ error = fn(dev, data);
put_device(dev);
if (error)
break;
@@ -193,7 +193,7 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start,
* and return it. If @start is not NULL, we use it as the head
* of the list.
*
- * NOTE: we don't return the driver that returns a non-zero
+ * NOTE: we don't return the driver that returns a non-zero
* value, nor do we leave the reference count incremented for that
* driver. If the caller needs to know that info, it must set it
* in the callback. It must also be sure to increment the refcount
@@ -216,7 +216,7 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
down_read(&bus->subsys.rwsem);
list_for_each_entry_continue(drv, head, kobj.entry) {
get_driver(drv);
- error = fn(drv,data);
+ error = fn(drv, data);
put_driver(drv);
if(error)
break;
@@ -233,8 +233,8 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
* Allow manual attachment of a driver to a deivce.
* Caller must have already set @dev->driver.
*
- * Note that this does not modify the bus reference count
- * nor take the bus's rwsem. Please verify those are accounted
+ * Note that this does not modify the bus reference count
+ * nor take the bus's rwsem. Please verify those are accounted
* for before calling this. (It is ok to call with no other effort
* from a driver's probe() method.)
*/
@@ -242,9 +242,9 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
void device_bind_driver(struct device * dev)
{
pr_debug("bound device '%s' to driver '%s'\n",
- dev->bus_id,dev->driver->name);
- list_add_tail(&dev->driver_list,&dev->driver->devices);
- sysfs_create_link(&dev->driver->kobj,&dev->kobj,
+ dev->bus_id, dev->driver->name);
+ list_add_tail(&dev->driver_list, &dev->driver->devices);
+ sysfs_create_link(&dev->driver->kobj, &dev->kobj,
kobject_name(&dev->kobj));
}
@@ -255,18 +255,18 @@ void device_bind_driver(struct device * dev)
* @drv: driver.
*
* First, we call the bus's match function, which should compare
- * the device IDs the driver supports with the device IDs of the
- * device. Note we don't do this ourselves because we don't know
+ * the device IDs the driver supports with the device IDs of the
+ * device. Note we don't do this ourselves because we don't know
* the format of the ID structures, nor what is to be considered
* a match and what is not.
- *
- * If we find a match, we call @drv->probe(@dev) if it exists, and
+ *
+ * If we find a match, we call @drv->probe(@dev) if it exists, and
* call attach() above.
*/
static int bus_match(struct device * dev, struct device_driver * drv)
{
int error = -ENODEV;
- if (dev->bus->match(dev,drv)) {
+ if (dev->bus->match(dev, drv)) {
dev->driver = drv;
if (drv->probe) {
if ((error = drv->probe(dev))) {
@@ -285,7 +285,7 @@ static int bus_match(struct device * dev, struct device_driver * drv)
* device_attach - try to attach device to a driver.
* @dev: device.
*
- * Walk the list of drivers that the bus has and call bus_match()
+ * Walk the list of drivers that the bus has and call bus_match()
* for each pair. If a compatible pair is found, break out and return.
*/
static int device_attach(struct device * dev)
@@ -300,15 +300,15 @@ static int device_attach(struct device * dev)
}
if (bus->match) {
- list_for_each(entry,&bus->drivers.list) {
+ list_for_each(entry, &bus->drivers.list) {
struct device_driver * drv = to_drv(entry);
- error = bus_match(dev,drv);
- if (!error )
+ error = bus_match(dev, drv);
+ if (!error)
/* success, driver matched */
- return 1;
- if (error != -ENODEV)
+ return 1;
+ if (error != -ENODEV)
/* driver matched but the probe failed */
- printk(KERN_WARNING
+ printk(KERN_WARNING
"%s: probe of %s failed with error %d\n",
drv->name, dev->bus_id, error);
}
@@ -327,7 +327,7 @@ static int device_attach(struct device * dev)
* If bus_match() returns 0 and the @dev->driver is set, we've found
* a compatible pair.
*
- * Note that we ignore the -ENODEV error from bus_match(), since it's
+ * Note that we ignore the -ENODEV error from bus_match(), since it's
* perfectly valid for a driver not to bind to any devices.
*/
void driver_attach(struct device_driver * drv)
@@ -339,13 +339,13 @@ void driver_attach(struct device_driver * drv)
if (!bus->match)
return;
- list_for_each(entry,&bus->devices.list) {
- struct device * dev = container_of(entry,struct device,bus_list);
+ list_for_each(entry, &bus->devices.list) {
+ struct device * dev = container_of(entry, struct device, bus_list);
if (!dev->driver) {
- error = bus_match(dev,drv);
+ error = bus_match(dev, drv);
if (error && (error != -ENODEV))
/* driver matched but the probe failed */
- printk(KERN_WARNING
+ printk(KERN_WARNING
"%s: probe of %s failed with error %d\n",
drv->name, dev->bus_id, error);
}
@@ -367,7 +367,7 @@ void device_release_driver(struct device * dev)
{
struct device_driver * drv = dev->driver;
if (drv) {
- sysfs_remove_link(&drv->kobj,kobject_name(&dev->kobj));
+ sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj));
list_del_init(&dev->driver_list);
device_detach_shutdown(dev);
if (drv->remove)
@@ -385,13 +385,44 @@ void device_release_driver(struct device * dev)
static void driver_detach(struct device_driver * drv)
{
struct list_head * entry, * next;
- list_for_each_safe(entry,next,&drv->devices) {
- struct device * dev = container_of(entry,struct device,driver_list);
+ list_for_each_safe(entry, next, &drv->devices) {
+ struct device * dev = container_of(entry, struct device, driver_list);
device_release_driver(dev);
}
+}
+
+static int device_add_attrs(struct bus_type * bus, struct device * dev)
+{
+ int error = 0;
+ int i;
+
+ if (bus->dev_attrs) {
+ for (i = 0; attr_name(bus->dev_attrs[i]); i++) {
+ error = device_create_file(dev,&bus->dev_attrs[i]);
+ if (error)
+ goto Err;
+ }
+ }
+ Done:
+ return error;
+ Err:
+ while (--i >= 0)
+ device_remove_file(dev,&bus->dev_attrs[i]);
+ goto Done;
+}
+
+
+static void device_remove_attrs(struct bus_type * bus, struct device * dev)
+{
+ int i;
+ if (bus->dev_attrs) {
+ for (i = 0; attr_name(bus->dev_attrs[i]); i++)
+ device_remove_file(dev,&bus->dev_attrs[i]);
+ }
}
+
/**
* bus_add_device - add device to bus
* @dev: device being added
@@ -407,11 +438,12 @@ int bus_add_device(struct device * dev)
if (bus) {
down_write(&dev->bus->subsys.rwsem);
- pr_debug("bus %s: add device %s\n",bus->name,dev->bus_id);
- list_add_tail(&dev->bus_list,&dev->bus->devices.list);
+ pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id);
+ list_add_tail(&dev->bus_list, &dev->bus->devices.list);
device_attach(dev);
up_write(&dev->bus->subsys.rwsem);
- sysfs_create_link(&bus->devices.kobj,&dev->kobj,dev->bus_id);
+ device_add_attrs(bus, dev);
+ sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id);
}
return error;
}
@@ -428,9 +460,10 @@ int bus_add_device(struct device * dev)
void bus_remove_device(struct device * dev)
{
if (dev->bus) {
- sysfs_remove_link(&dev->bus->devices.kobj,dev->bus_id);
+ sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id);
+ device_remove_attrs(dev->bus, dev);
down_write(&dev->bus->subsys.rwsem);
- pr_debug("bus %s: remove device %s\n",dev->bus->name,dev->bus_id);
+ pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id);
device_release_driver(dev);
list_del_init(&dev->bus_list);
up_write(&dev->bus->subsys.rwsem);
@@ -450,8 +483,8 @@ int bus_add_driver(struct device_driver * drv)
int error = 0;
if (bus) {
- pr_debug("bus %s: add driver %s\n",bus->name,drv->name);
- error = kobject_set_name(&drv->kobj,drv->name);
+ pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
+ error = kobject_set_name(&drv->kobj, drv->name);
if (error) {
put_bus(bus);
return error;
@@ -484,7 +517,7 @@ void bus_remove_driver(struct device_driver * drv)
{
if (drv->bus) {
down_write(&drv->bus->subsys.rwsem);
- pr_debug("bus %s: remove driver %s\n",drv->bus->name,drv->name);
+ pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
driver_detach(drv);
up_write(&drv->bus->subsys.rwsem);
kobject_unregister(&drv->kobj);
@@ -526,7 +559,7 @@ int bus_rescan_devices(struct bus_type * bus)
struct bus_type * get_bus(struct bus_type * bus)
{
- return bus ? container_of(subsys_get(&bus->subsys),struct bus_type,subsys) : NULL;
+ return bus ? container_of(subsys_get(&bus->subsys), struct bus_type, subsys) : NULL;
}
void put_bus(struct bus_type * bus)
@@ -545,29 +578,64 @@ void put_bus(struct bus_type * bus)
struct bus_type * find_bus(char * name)
{
- struct kobject * k = kset_find_obj(&bus_subsys.kset,name);
+ struct kobject * k = kset_find_obj(&bus_subsys.kset, name);
return k ? to_bus(k) : NULL;
}
+
+/**
+ * bus_add_attrs - Add default attributes for this bus.
+ * @bus: Bus that has just been registered.
+ */
+
+static int bus_add_attrs(struct bus_type * bus)
+{
+ int error = 0;
+ int i;
+
+ if (bus->bus_attrs) {
+ for (i = 0; attr_name(bus->bus_attrs[i]); i++) {
+ if ((error = bus_create_file(bus,&bus->bus_attrs[i])))
+ goto Err;
+ }
+ }
+ Done:
+ return error;
+ Err:
+ while (--i >= 0)
+ bus_remove_file(bus,&bus->bus_attrs[i]);
+ goto Done;
+}
+
+static void bus_remove_attrs(struct bus_type * bus)
+{
+ int i;
+
+ if (bus->bus_attrs) {
+ for (i = 0; attr_name(bus->bus_attrs[i]); i++)
+ bus_remove_file(bus,&bus->bus_attrs[i]);
+ }
+}
+
/**
* bus_register - register a bus with the system.
* @bus: bus.
*
* Once we have that, we registered the bus with the kobject
* infrastructure, then register the children subsystems it has:
- * the devices and drivers that belong to the bus.
+ * the devices and drivers that belong to the bus.
*/
int bus_register(struct bus_type * bus)
{
int retval;
- retval = kobject_set_name(&bus->subsys.kset.kobj,bus->name);
+ retval = kobject_set_name(&bus->subsys.kset.kobj, bus->name);
if (retval)
goto out;
- subsys_set_kset(bus,bus_subsys);
+ subsys_set_kset(bus, bus_subsys);
retval = subsystem_register(&bus->subsys);
- if (retval)
+ if (retval)
goto out;
kobject_set_name(&bus->devices.kobj, "devices");
@@ -582,8 +650,9 @@ int bus_register(struct bus_type * bus)
retval = kset_register(&bus->drivers);
if (retval)
goto bus_drivers_fail;
+ bus_add_attrs(bus);
- pr_debug("bus type '%s' registered\n",bus->name);
+ pr_debug("bus type '%s' registered\n", bus->name);
return 0;
bus_drivers_fail:
@@ -596,7 +665,7 @@ out:
/**
- * bus_unregister - remove a bus from the system
+ * bus_unregister - remove a bus from the system
* @bus: bus.
*
* Unregister the child subsystems and the bus itself.
@@ -604,7 +673,8 @@ out:
*/
void bus_unregister(struct bus_type * bus)
{
- pr_debug("bus %s: unregistering\n",bus->name);
+ pr_debug("bus %s: unregistering\n", bus->name);
+ bus_remove_attrs(bus);
kset_unregister(&bus->drivers);
kset_unregister(&bus->devices);
subsystem_unregister(&bus->subsys);
diff --git a/drivers/base/class.c b/drivers/base/class.c
index ed13d9de0d1d..2693bb5455f4 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -5,7 +5,7 @@
* Copyright (c) 2002-3 Open Source Development Labs
* Copyright (c) 2003-2004 Greg Kroah-Hartman
* Copyright (c) 2003-2004 IBM Corp.
- *
+ *
* This file is released under the GPLv2
*
*/
@@ -17,8 +17,8 @@
#include <linux/string.h>
#include "base.h"
-#define to_class_attr(_attr) container_of(_attr,struct class_attribute,attr)
-#define to_class(obj) container_of(obj,struct class,subsys.kset.kobj)
+#define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
+#define to_class(obj) container_of(obj, struct class, subsys.kset.kobj)
static ssize_t
class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
@@ -28,12 +28,12 @@ class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
ssize_t ret = 0;
if (class_attr->show)
- ret = class_attr->show(dc,buf);
+ ret = class_attr->show(dc, buf);
return ret;
}
static ssize_t
-class_attr_store(struct kobject * kobj, struct attribute * attr,
+class_attr_store(struct kobject * kobj, struct attribute * attr,
const char * buf, size_t count)
{
struct class_attribute * class_attr = to_class_attr(attr);
@@ -41,7 +41,7 @@ class_attr_store(struct kobject * kobj, struct attribute * attr,
ssize_t ret = 0;
if (class_attr->store)
- ret = class_attr->store(dc,buf,count);
+ ret = class_attr->store(dc, buf, count);
return ret;
}
@@ -69,14 +69,14 @@ static struct kobj_type ktype_class = {
};
/* Hotplug events for classes go to the class_obj subsys */
-static decl_subsys(class,&ktype_class,NULL);
+static decl_subsys(class, &ktype_class, NULL);
int class_create_file(struct class * cls, const struct class_attribute * attr)
{
int error;
if (cls) {
- error = sysfs_create_file(&cls->subsys.kset.kobj,&attr->attr);
+ error = sysfs_create_file(&cls->subsys.kset.kobj, &attr->attr);
} else
error = -EINVAL;
return error;
@@ -85,13 +85,13 @@ int class_create_file(struct class * cls, const struct class_attribute * attr)
void class_remove_file(struct class * cls, const struct class_attribute * attr)
{
if (cls)
- sysfs_remove_file(&cls->subsys.kset.kobj,&attr->attr);
+ sysfs_remove_file(&cls->subsys.kset.kobj, &attr->attr);
}
struct class * class_get(struct class * cls)
{
if (cls)
- return container_of(subsys_get(&cls->subsys),struct class,subsys);
+ return container_of(subsys_get(&cls->subsys), struct class, subsys);
return NULL;
}
@@ -100,33 +100,67 @@ void class_put(struct class * cls)
subsys_put(&cls->subsys);
}
+
+static int add_class_attrs(struct class * cls)
+{
+ int i;
+ int error = 0;
+
+ if (cls->class_attrs) {
+ for (i = 0; attr_name(cls->class_attrs[i]); i++) {
+ error = class_create_file(cls,&cls->class_attrs[i]);
+ if (error)
+ goto Err;
+ }
+ }
+ Done:
+ return error;
+ Err:
+ while (--i >= 0)
+ class_remove_file(cls,&cls->class_attrs[i]);
+ goto Done;
+}
+
+static void remove_class_attrs(struct class * cls)
+{
+ int i;
+
+ if (cls->class_attrs) {
+ for (i = 0; attr_name(cls->class_attrs[i]); i++)
+ class_remove_file(cls,&cls->class_attrs[i]);
+ }
+}
+
int class_register(struct class * cls)
{
int error;
- pr_debug("device class '%s': registering\n",cls->name);
+ pr_debug("device class '%s': registering\n", cls->name);
INIT_LIST_HEAD(&cls->children);
INIT_LIST_HEAD(&cls->interfaces);
- error = kobject_set_name(&cls->subsys.kset.kobj,cls->name);
+ error = kobject_set_name(&cls->subsys.kset.kobj, cls->name);
if (error)
return error;
- subsys_set_kset(cls,class_subsys);
+ subsys_set_kset(cls, class_subsys);
error = subsystem_register(&cls->subsys);
- if (error)
- return error;
-
- return 0;
+ if (!error) {
+ error = add_class_attrs(class_get(cls));
+ class_put(cls);
+ }
+ return error;
}
void class_unregister(struct class * cls)
{
- pr_debug("device class '%s': unregistering\n",cls->name);
+ pr_debug("device class '%s': unregistering\n", cls->name);
+ remove_class_attrs(cls);
subsystem_unregister(&cls->subsys);
}
+
/* Class Device Stuff */
int class_device_create_file(struct class_device * class_dev,
@@ -181,12 +215,12 @@ class_device_attr_show(struct kobject * kobj, struct attribute * attr,
ssize_t ret = 0;
if (class_dev_attr->show)
- ret = class_dev_attr->show(cd,buf);
+ ret = class_dev_attr->show(cd, buf);
return ret;
}
static ssize_t
-class_device_attr_store(struct kobject * kobj, struct attribute * attr,
+class_device_attr_store(struct kobject * kobj, struct attribute * attr,
const char * buf, size_t count)
{
struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr);
@@ -194,7 +228,7 @@ class_device_attr_store(struct kobject * kobj, struct attribute * attr,
ssize_t ret = 0;
if (class_dev_attr->store)
- ret = class_dev_attr->store(cd,buf,count);
+ ret = class_dev_attr->store(cd, buf, count);
return ret;
}
@@ -208,7 +242,7 @@ static void class_dev_release(struct kobject * kobj)
struct class_device *cd = to_class_dev(kobj);
struct class * cls = cd->class;
- pr_debug("device class '%s': release.\n",cd->class_id);
+ pr_debug("device class '%s': release.\n", cd->class_id);
if (cls->release)
cls->release(cd);
@@ -272,6 +306,40 @@ static struct kset_hotplug_ops class_hotplug_ops = {
static decl_subsys(class_obj, &ktype_class_device, &class_hotplug_ops);
+
+static int class_device_add_attrs(struct class_device * cd)
+{
+ int i;
+ int error = 0;
+ struct class * cls = cd->class;
+
+ if (cls->class_dev_attrs) {
+ for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) {
+ error = class_device_create_file(cd,
+ &cls->class_dev_attrs[i]);
+ if (error)
+ goto Err;
+ }
+ }
+ Done:
+ return error;
+ Err:
+ while (--i >= 0)
+ class_device_remove_file(cd,&cls->class_dev_attrs[i]);
+ goto Done;
+}
+
+static void class_device_remove_attrs(struct class_device * cd)
+{
+ int i;
+ struct class * cls = cd->class;
+
+ if (cls->class_dev_attrs) {
+ for (i = 0; attr_name(cls->class_dev_attrs[i]); i++)
+ class_device_remove_file(cd,&cls->class_dev_attrs[i]);
+ }
+}
+
void class_device_initialize(struct class_device *class_dev)
{
kobj_set_kset_s(class_dev, class_obj_subsys);
@@ -311,7 +379,7 @@ int class_device_add(struct class_device *class_dev)
class_intf->add(class_dev);
up_write(&parent->subsys.rwsem);
}
-
+ class_device_add_attrs(class_dev);
class_device_dev_link(class_dev);
class_device_driver_link(class_dev);
@@ -344,7 +412,8 @@ void class_device_del(struct class_device *class_dev)
class_device_dev_unlink(class_dev);
class_device_driver_unlink(class_dev);
-
+ class_device_remove_attrs(class_dev);
+
kobject_del(&class_dev->kobj);
if (parent)
diff --git a/drivers/base/class_simple.c b/drivers/base/class_simple.c
index 20707be0dcd7..3410636de0a5 100644
--- a/drivers/base/class_simple.c
+++ b/drivers/base/class_simple.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2003-2004 Greg Kroah-Hartman <greg@kroah.com>
* Copyright (c) 2003-2004 IBM Corp.
- *
+ *
* This file is released under the GPLv2
*
*/
@@ -111,7 +111,7 @@ EXPORT_SYMBOL(class_simple_destroy);
/**
* class_simple_device_add - adds a class device to sysfs for a character driver
- * @cs: pointer to the struct class_simple that this device should be registered to.
+ * @cs: pointer to the struct class_simple that this device should be registered to.
* @dev: the dev_t for the device to be added.
* @device: a pointer to a struct device that is assiociated with this class device.
* @fmt: string for the class device's name
@@ -146,8 +146,8 @@ struct class_device *class_simple_device_add(struct class_simple *cs, dev_t dev,
s_dev->dev = dev;
s_dev->class_dev.dev = device;
s_dev->class_dev.class = &cs->class;
-
- va_start(args,fmt);
+
+ va_start(args, fmt);
vsnprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, fmt, args);
va_end(args);
retval = class_device_register(&s_dev->class_dev);
@@ -173,10 +173,10 @@ EXPORT_SYMBOL(class_simple_device_add);
* @cs: pointer to the struct class_simple to hold the pointer
* @hotplug: function pointer to the hotplug function
*
- * Implement and set a hotplug function to add environment variables specific to this
+ * Implement and set a hotplug function to add environment variables specific to this
* class on the hotplug event.
*/
-int class_simple_set_hotplug(struct class_simple *cs,
+int class_simple_set_hotplug(struct class_simple *cs,
int (*hotplug)(struct class_device *dev, char **envp, int num_envp, char *buffer, int buffer_size))
{
if ((cs == NULL) || (IS_ERR(cs)))
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 0eaa2c003e69..3325810c42ab 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
- *
+ *
* This file is released under the GPLv2
*
*/
@@ -28,8 +28,8 @@ int (*platform_notify_remove)(struct device * dev) = NULL;
* sysfs bindings for devices.
*/
-#define to_dev(obj) container_of(obj,struct device,kobj)
-#define to_dev_attr(_attr) container_of(_attr,struct device_attribute,attr)
+#define to_dev(obj) container_of(obj, struct device, kobj)
+#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
extern struct attribute * dev_default_attrs[];
@@ -41,12 +41,12 @@ dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
ssize_t ret = 0;
if (dev_attr->show)
- ret = dev_attr->show(dev,buf);
+ ret = dev_attr->show(dev, buf);
return ret;
}
static ssize_t
-dev_attr_store(struct kobject * kobj, struct attribute * attr,
+dev_attr_store(struct kobject * kobj, struct attribute * attr,
const char * buf, size_t count)
{
struct device_attribute * dev_attr = to_dev_attr(attr);
@@ -54,7 +54,7 @@ dev_attr_store(struct kobject * kobj, struct attribute * attr,
ssize_t ret = 0;
if (dev_attr->store)
- ret = dev_attr->store(dev,buf,count);
+ ret = dev_attr->store(dev, buf, count);
return ret;
}
@@ -153,7 +153,7 @@ int device_create_file(struct device * dev, struct device_attribute * attr)
{
int error = 0;
if (get_device(dev)) {
- error = sysfs_create_file(&dev->kobj,&attr->attr);
+ error = sysfs_create_file(&dev->kobj, &attr->attr);
put_device(dev);
}
return error;
@@ -168,7 +168,7 @@ int device_create_file(struct device * dev, struct device_attribute * attr)
void device_remove_file(struct device * dev, struct device_attribute * attr)
{
if (get_device(dev)) {
- sysfs_remove_file(&dev->kobj,&attr->attr);
+ sysfs_remove_file(&dev->kobj, &attr->attr);
put_device(dev);
}
}
@@ -179,7 +179,7 @@ void device_remove_file(struct device * dev, struct device_attribute * attr)
* @dev: device.
*
* This prepares the device for use by other layers,
- * including adding it to the device hierarchy.
+ * including adding it to the device hierarchy.
* It is the first half of device_register(), if called by
* that, though it can also be called separately, so one
* may use @dev's fields (e.g. the refcount).
@@ -187,7 +187,7 @@ void device_remove_file(struct device * dev, struct device_attribute * attr)
void device_initialize(struct device *dev)
{
- kobj_set_kset_s(dev,devices_subsys);
+ kobj_set_kset_s(dev, devices_subsys);
kobject_init(&dev->kobj);
INIT_LIST_HEAD(&dev->node);
INIT_LIST_HEAD(&dev->children);
@@ -200,7 +200,7 @@ void device_initialize(struct device *dev)
* device_add - add device to device hierarchy.
* @dev: device.
*
- * This is part 2 of device_register(), though may be called
+ * This is part 2 of device_register(), though may be called
* separately _iff_ device_initialize() has been called separately.
*
* This adds it to the kobject hierarchy via kobject_add(), adds it
@@ -221,7 +221,7 @@ int device_add(struct device *dev)
pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id);
/* first, register with generic layer. */
- kobject_set_name(&dev->kobj,dev->bus_id);
+ kobject_set_name(&dev->kobj, dev->bus_id);
if (parent)
dev->kobj.parent = &parent->kobj;
@@ -233,7 +233,7 @@ int device_add(struct device *dev)
goto BusError;
down_write(&devices_subsys.rwsem);
if (parent)
- list_add_tail(&dev->node,&parent->children);
+ list_add_tail(&dev->node, &parent->children);
up_write(&devices_subsys.rwsem);
/* notify platform of device entry */
@@ -245,7 +245,7 @@ int device_add(struct device *dev)
BusError:
device_pm_remove(dev);
PMError:
- kobject_unregister(&dev->kobj);
+ kobject_del(&dev->kobj);
Error:
if (parent)
put_device(parent);
@@ -258,9 +258,9 @@ int device_add(struct device *dev)
* @dev: pointer to the device structure
*
* This happens in two clean steps - initialize the device
- * and add it to the system. The two steps can be called
- * separately, but this is the easiest and most common.
- * I.e. you should only call the two helpers separately if
+ * and add it to the system. The two steps can be called
+ * separately, but this is the easiest and most common.
+ * I.e. you should only call the two helpers separately if
* have a clearly defined need to use and refcount the device
* before it is added to the hierarchy.
*/
@@ -301,13 +301,13 @@ void put_device(struct device * dev)
* device_del - delete device from system.
* @dev: device.
*
- * This is the first part of the device unregistration
+ * This is the first part of the device unregistration
* sequence. This removes the device from the lists we control
- * from here, has it removed from the other driver model
+ * from here, has it removed from the other driver model
* subsystems it was added to in device_add(), and removes it
* from the kobject hierarchy.
*
- * NOTE: this should be called manually _iff_ device_add() was
+ * NOTE: this should be called manually _iff_ device_add() was
* also called manually.
*/
@@ -340,7 +340,7 @@ void device_del(struct device * dev)
* we remove it from all the subsystems with device_del(), then
* we decrement the reference count via put_device(). If that
* is the final reference count, the device will be cleaned up
- * via device_release() above. Otherwise, the structure will
+ * via device_release() above. Otherwise, the structure will
* stick around until the final reference to the device is dropped.
*/
void device_unregister(struct device * dev)
@@ -358,7 +358,7 @@ void device_unregister(struct device * dev)
* @fn: function to be called for each device.
*
* Iterate over @dev's child devices, and call @fn for each,
- * passing it @data.
+ * passing it @data.
*
* We check the return of @fn each time. If it returns anything
* other than 0, we break out and return that value.
@@ -370,8 +370,8 @@ int device_for_each_child(struct device * dev, void * data,
int error = 0;
down_read(&devices_subsys.rwsem);
- list_for_each_entry(child,&dev->children,node) {
- if((error = fn(child,data)))
+ list_for_each_entry(child, &dev->children, node) {
+ if((error = fn(child, data)))
break;
}
up_read(&devices_subsys.rwsem);
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 0236ba33542b..0604b2b20e6f 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
- *
+ *
* This file is released under the GPLv2
*
*/
@@ -15,8 +15,8 @@
#include <linux/string.h>
#include "base.h"
-#define to_dev(node) container_of(node,struct device,driver_list)
-#define to_drv(obj) container_of(obj,struct device_driver,kobj)
+#define to_dev(node) container_of(node, struct device, driver_list)
+#define to_drv(obj) container_of(obj, struct device_driver, kobj)
/**
* driver_create_file - create sysfs file for driver.
@@ -28,7 +28,7 @@ int driver_create_file(struct device_driver * drv, struct driver_attribute * att
{
int error;
if (get_driver(drv)) {
- error = sysfs_create_file(&drv->kobj,&attr->attr);
+ error = sysfs_create_file(&drv->kobj, &attr->attr);
put_driver(drv);
} else
error = -EINVAL;
@@ -45,7 +45,7 @@ int driver_create_file(struct device_driver * drv, struct driver_attribute * att
void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr)
{
if (get_driver(drv)) {
- sysfs_remove_file(&drv->kobj,&attr->attr);
+ sysfs_remove_file(&drv->kobj, &attr->attr);
put_driver(drv);
}
}
@@ -76,7 +76,7 @@ void put_driver(struct device_driver * drv)
* @drv: driver to register
*
* We pass off most of the work to the bus_add_driver() call,
- * since most of the things we have to do deal with the bus
+ * since most of the things we have to do deal with the bus
* structures.
*
* The one interesting aspect is that we initialize @drv->unload_sem
@@ -99,8 +99,8 @@ int driver_register(struct device_driver * drv)
*
* Though, once that is done, we attempt to take @drv->unload_sem.
* This will block until the driver refcount reaches 0, and it is
- * released. Only modular drivers will call this function, and we
- * have to guarantee that it won't complete, letting the driver
+ * released. Only modular drivers will call this function, and we
+ * have to guarantee that it won't complete, letting the driver
* unload until all references are gone.
*/
diff --git a/drivers/base/firmware.c b/drivers/base/firmware.c
index 886d4961498b..0cff0498ea8b 100644
--- a/drivers/base/firmware.c
+++ b/drivers/base/firmware.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
- *
+ *
* This file is released under the GPLv2
*
*/
@@ -12,11 +12,11 @@
#include <linux/module.h>
#include <linux/init.h>
-static decl_subsys(firmware,NULL,NULL);
+static decl_subsys(firmware, NULL, NULL);
int firmware_register(struct subsystem * s)
{
- kset_set_kset_s(s,firmware_subsys);
+ kset_set_kset_s(s, firmware_subsys);
return subsystem_register(s);
}
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 8ff239f146cf..a57ba84eb2c6 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -68,7 +68,7 @@ firmware_timeout_show(struct class *class, char *buf)
* firmware will be provided.
*
* Note: zero means 'wait for ever'
- *
+ *
**/
static ssize_t
firmware_timeout_store(struct class *class, const char *buf, size_t count)
@@ -121,7 +121,7 @@ firmware_loading_show(struct class_device *class_dev, char *buf)
/**
* firmware_loading_store: - loading control file
* Description:
- * The relevant values are:
+ * The relevant values are:
*
* 1: Start a load, discarding any previous partial load.
* 0: Conclude the load and handle the data to the driver code.
@@ -376,7 +376,7 @@ out:
return retval;
}
-/**
+/**
* request_firmware: - request firmware to hotplug and wait for it
* Description:
* @firmware will be used to return a firmware image by the name
@@ -457,7 +457,7 @@ release_firmware(const struct firmware *fw)
/**
* register_firmware: - provide a firmware image for later usage
- *
+ *
* Description:
* Make sure that @data will be available by requesting firmware @name.
*
@@ -541,7 +541,7 @@ request_firmware_nowait(
ret = kernel_thread(request_firmware_work_func, fw_work,
CLONE_FS | CLONE_FILES);
-
+
if (ret < 0) {
fw_work->cont(NULL, fw_work->context);
return ret;
diff --git a/drivers/base/init.c b/drivers/base/init.c
index fd53f364b1ed..7b86c409c648 100644
--- a/drivers/base/init.c
+++ b/drivers/base/init.c
@@ -2,7 +2,7 @@
*
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
- *
+ *
* This file is released under the GPLv2
*
*/
@@ -33,7 +33,7 @@ void __init driver_init(void)
classes_init();
firmware_init();
- /* These are also core pieces, but must come after the
+ /* These are also core pieces, but must come after the
* core core pieces.
*/
platform_bus_init();
diff --git a/drivers/base/interface.c b/drivers/base/interface.c
index 1e2d4c328ed5..bd515843a0cb 100644
--- a/drivers/base/interface.c
+++ b/drivers/base/interface.c
@@ -1,10 +1,10 @@
/*
- * drivers/base/interface.c - common driverfs interface that's exported to
+ * drivers/base/interface.c - common driverfs interface that's exported to
* the world for all devices.
*
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
- *
+ *
* This file is released under the GPLv2
*
*/
@@ -16,33 +16,33 @@
/**
* detach_state - control the default power state for the device.
- *
- * This is the state the device enters when it's driver module is
+ *
+ * This is the state the device enters when it's driver module is
* unloaded. The value is an unsigned integer, in the range of 0-4.
* '0' indicates 'On', so no action will be taken when the driver is
* unloaded. This is the default behavior.
* '4' indicates 'Off', meaning the driver core will call the driver's
* shutdown method to quiesce the device.
- * 1-3 indicate a low-power state for the device to enter via the
- * driver's suspend method.
+ * 1-3 indicate a low-power state for the device to enter via the
+ * driver's suspend method.
*/
static ssize_t detach_show(struct device * dev, char * buf)
{
- return sprintf(buf,"%u\n",dev->detach_state);
+ return sprintf(buf, "%u\n", dev->detach_state);
}
static ssize_t detach_store(struct device * dev, const char * buf, size_t n)
{
u32 state;
- state = simple_strtoul(buf,NULL,10);
+ state = simple_strtoul(buf, NULL, 10);
if (state > 4)
return -EINVAL;
dev->detach_state = state;
return n;
}
-static DEVICE_ATTR(detach_state,0644,detach_show,detach_store);
+static DEVICE_ATTR(detach_state, 0644, detach_show, detach_store);
struct attribute * dev_default_attrs[] = {
diff --git a/drivers/base/node.c b/drivers/base/node.c
index b5aa9dc6cdb7..fa06de092972 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -29,7 +29,7 @@ static ssize_t node_read_cpumap(struct sys_device * dev, char * buf)
return len;
}
-static SYSDEV_ATTR(cpumap,S_IRUGO,node_read_cpumap,NULL);
+static SYSDEV_ATTR(cpumap, S_IRUGO, node_read_cpumap, NULL);
/* Can be overwritten by architecture specific code. */
int __attribute__((weak)) hugetlb_report_node_meminfo(int node, char *buf)
@@ -54,17 +54,17 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf)
"Node %d LowFree: %8lu kB\n",
nid, K(i.totalram),
nid, K(i.freeram),
- nid, K(i.totalram-i.freeram),
+ nid, K(i.totalram - i.freeram),
nid, K(i.totalhigh),
nid, K(i.freehigh),
- nid, K(i.totalram-i.totalhigh),
- nid, K(i.freeram-i.freehigh));
+ nid, K(i.totalram - i.totalhigh),
+ nid, K(i.freeram - i.freehigh));
n += hugetlb_report_node_meminfo(nid, buf + n);
return n;
}
-#undef K
-static SYSDEV_ATTR(meminfo,S_IRUGO,node_read_meminfo,NULL);
+#undef K
+static SYSDEV_ATTR(meminfo, S_IRUGO, node_read_meminfo, NULL);
static ssize_t node_read_numastat(struct sys_device * dev, char * buf)
{
@@ -104,7 +104,7 @@ static ssize_t node_read_numastat(struct sys_device * dev, char * buf)
local_node,
other_node);
}
-static SYSDEV_ATTR(numastat,S_IRUGO,node_read_numastat,NULL);
+static SYSDEV_ATTR(numastat, S_IRUGO, node_read_numastat, NULL);
/*
* register_node - Setup a driverfs device for a node.
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 0d75909a4538..dcb875e487d2 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
- *
+ *
* This file is released under the GPLv2
*
* Please see Documentation/driver-model/platform.txt for more
@@ -19,12 +19,71 @@ struct device platform_bus = {
};
/**
+ * platform_get_resource - get a resource for a device
+ * @dev: platform device
+ * @type: resource type
+ * @num: resource index
+ */
+struct resource *
+platform_get_resource(struct platform_device *dev, unsigned int type,
+ unsigned int num)
+{
+ int i;
+
+ for (i = 0; i < dev->num_resources; i++) {
+ struct resource *r = &dev->resource[i];
+
+ if ((r->flags & (IORESOURCE_IO|IORESOURCE_MEM|
+ IORESOURCE_IRQ|IORESOURCE_DMA))
+ == type)
+ if (num-- == 0)
+ return r;
+ }
+ return NULL;
+}
+
+/**
+ * platform_get_irq - get an IRQ for a device
+ * @dev: platform device
+ * @num: IRQ number index
+ */
+int platform_get_irq(struct platform_device *dev, unsigned int num)
+{
+ struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num);
+
+ return r ? r->start : 0;
+}
+
+/**
+ * platform_add_devices - add a numbers of platform devices
+ * @devs: array of platform devices to add
+ * @num: number of platform devices in array
+ */
+int platform_add_devices(struct platform_device **devs, int num)
+{
+ int i, ret = 0;
+
+ for (i = 0; i < num; i++) {
+ ret = platform_device_register(devs[i]);
+ if (ret) {
+ while (--i >= 0)
+ platform_device_unregister(devs[i]);
+ break;
+ }
+ }
+
+ return ret;
+}
+
+/**
* platform_device_register - add a platform-level device
* @dev: platform device we're adding
*
*/
int platform_device_register(struct platform_device * pdev)
{
+ int i, ret = 0;
+
if (!pdev)
return -EINVAL;
@@ -32,18 +91,59 @@ int platform_device_register(struct platform_device * pdev)
pdev->dev.parent = &platform_bus;
pdev->dev.bus = &platform_bus_type;
-
- snprintf(pdev->dev.bus_id,BUS_ID_SIZE,"%s%u",pdev->name,pdev->id);
+
+ if (pdev->id != -1)
+ snprintf(pdev->dev.bus_id, BUS_ID_SIZE, "%s%u", pdev->name, pdev->id);
+ else
+ strlcpy(pdev->dev.bus_id, pdev->name, BUS_ID_SIZE);
+
+ for (i = 0; i < pdev->num_resources; i++) {
+ struct resource *p, *r = &pdev->resource[i];
+
+ r->name = pdev->dev.bus_id;
+
+ p = NULL;
+ if (r->flags & IORESOURCE_MEM)
+ p = &iomem_resource;
+ else if (r->flags & IORESOURCE_IO)
+ p = &ioport_resource;
+
+ if (p && request_resource(p, r)) {
+ printk(KERN_ERR
+ "%s: failed to claim resource %d\n",
+ pdev->dev.bus_id, i);
+ ret = -EBUSY;
+ goto failed;
+ }
+ }
pr_debug("Registering platform device '%s'. Parent at %s\n",
- pdev->dev.bus_id,pdev->dev.parent->bus_id);
- return device_register(&pdev->dev);
+ pdev->dev.bus_id, pdev->dev.parent->bus_id);
+
+ ret = device_register(&pdev->dev);
+ if (ret == 0)
+ return ret;
+
+ failed:
+ while (--i >= 0)
+ if (pdev->resource[i].flags & (IORESOURCE_MEM|IORESOURCE_IO))
+ release_resource(&pdev->resource[i]);
+ return ret;
}
void platform_device_unregister(struct platform_device * pdev)
{
- if (pdev)
+ int i;
+
+ if (pdev) {
device_unregister(&pdev->dev);
+
+ for (i = 0; i < pdev->num_resources; i++) {
+ struct resource *r = &pdev->resource[i];
+ if (r->flags & (IORESOURCE_MEM|IORESOURCE_IO))
+ release_resource(r);
+ }
+ }
}
@@ -52,13 +152,13 @@ void platform_device_unregister(struct platform_device * pdev)
* @dev: device.
* @drv: driver.
*
- * Platform device IDs are assumed to be encoded like this:
- * "<name><instance>", where <name> is a short description of the
- * type of device, like "pci" or "floppy", and <instance> is the
+ * Platform device IDs are assumed to be encoded like this:
+ * "<name><instance>", where <name> is a short description of the
+ * type of device, like "pci" or "floppy", and <instance> is the
* enumerated instance of the device, like '0' or '42'.
- * Driver IDs are simply "<name>".
- * So, extract the <name> from the platform_device structure,
- * and compare it against the name of the driver. Return whether
+ * Driver IDs are simply "<name>".
+ * So, extract the <name> from the platform_device structure,
+ * and compare it against the name of the driver. Return whether
* they match or not.
*/
@@ -114,3 +214,5 @@ EXPORT_SYMBOL(platform_bus);
EXPORT_SYMBOL(platform_bus_type);
EXPORT_SYMBOL(platform_device_register);
EXPORT_SYMBOL(platform_device_unregister);
+EXPORT_SYMBOL(platform_get_irq);
+EXPORT_SYMBOL(platform_get_resource);
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 634c98f5c437..635ea200132e 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -12,10 +12,10 @@
* and add it to the list of power-controlled devices. sysfs entries for
* controlling device power management will also be added.
*
- * A different set of lists than the global subsystem list are used to
- * keep track of power info because we use different lists to hold
- * devices based on what stage of the power management process they
- * are in. The power domain dependencies may also differ from the
+ * A different set of lists than the global subsystem list are used to
+ * keep track of power info because we use different lists to hold
+ * devices based on what stage of the power management process they
+ * are in. The power domain dependencies may also differ from the
* ancestral dependencies that the subsystem list maintains.
*/
@@ -74,10 +74,10 @@ int device_pm_add(struct device * dev)
pr_debug("PM: Adding info for %s:%s\n",
dev->bus ? dev->bus->name : "No Bus", dev->kobj.name);
- atomic_set(&dev->power.pm_users,0);
+ atomic_set(&dev->power.pm_users, 0);
down(&dpm_sem);
- list_add_tail(&dev->power.entry,&dpm_active);
- device_pm_set_parent(dev,dev->parent);
+ list_add_tail(&dev->power.entry, &dpm_active);
+ device_pm_set_parent(dev, dev->parent);
if ((error = dpm_sysfs_add(dev)))
list_del(&dev->power.entry);
up(&dpm_sem);
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index b930ccef5785..6971cc667b17 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -27,7 +27,7 @@ extern void device_shutdown(void);
*/
extern struct semaphore dpm_sem;
-/*
+/*
* The PM lists.
*/
extern struct list_head dpm_active;
@@ -37,12 +37,12 @@ extern struct list_head dpm_off_irq;
static inline struct dev_pm_info * to_pm_info(struct list_head * entry)
{
- return container_of(entry,struct dev_pm_info,entry);
+ return container_of(entry, struct dev_pm_info, entry);
}
static inline struct device * to_device(struct list_head * entry)
{
- return container_of(to_pm_info(entry),struct device,power);
+ return container_of(to_pm_info(entry), struct device, power);
}
extern int device_pm_add(struct device *);
@@ -56,7 +56,7 @@ extern int dpm_sysfs_add(struct device *);
extern void dpm_sysfs_remove(struct device *);
/*
- * resume.c
+ * resume.c
*/
extern void dpm_resume(void);
diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c
index 21d4b56debe0..1d830be4c9bc 100644
--- a/drivers/base/power/resume.c
+++ b/drivers/base/power/resume.c
@@ -39,7 +39,7 @@ void dpm_resume(void)
if (!dev->power.prev_state)
resume_device(dev);
- list_add_tail(entry,&dpm_active);
+ list_add_tail(entry, &dpm_active);
}
}
@@ -48,7 +48,7 @@ void dpm_resume(void)
* device_resume - Restore state of each device in system.
*
* Walk the dpm_off list, remove each entry, resume the device,
- * then add it to the dpm_active list.
+ * then add it to the dpm_active list.
*/
void device_resume(void)
@@ -62,14 +62,14 @@ EXPORT_SYMBOL(device_resume);
/**
- * device_power_up_irq - Power on some devices.
+ * device_power_up_irq - Power on some devices.
*
- * Walk the dpm_off_irq list and power each device up. This
+ * Walk the dpm_off_irq list and power each device up. This
* is used for devices that required they be powered down with
* interrupts disabled. As devices are powered on, they are moved to
* the dpm_suspended list.
*
- * Interrupts must be disabled when calling this.
+ * Interrupts must be disabled when calling this.
*/
void dpm_power_up(void)
@@ -78,7 +78,7 @@ void dpm_power_up(void)
struct list_head * entry = dpm_off_irq.next;
list_del_init(entry);
resume_device(to_device(entry));
- list_add_tail(entry,&dpm_active);
+ list_add_tail(entry, &dpm_active);
}
}
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 4ff5340e90fb..5e58f68363af 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -24,9 +24,9 @@ static void runtime_resume(struct device * dev)
* dpm_runtime_resume - Power one device back on.
* @dev: Device.
*
- * Bring one device back to the on state by first powering it
+ * Bring one device back to the on state by first powering it
* on, then restoring state. We only operate on devices that aren't
- * already on.
+ * already on.
* FIXME: We need to handle devices that are in an unknown state.
*/
@@ -55,7 +55,7 @@ int dpm_runtime_suspend(struct device * dev, u32 state)
if (dev->power.power_state)
runtime_resume(dev);
- if (!(error = suspend_device(dev,state)))
+ if (!(error = suspend_device(dev, state)))
dev->power.power_state = state;
Done:
up(&dpm_sem);
@@ -70,7 +70,7 @@ int dpm_runtime_suspend(struct device * dev, u32 state)
*
* This is an update mechanism for drivers to notify the core
* what power state a device is in. Device probing code may not
- * always be able to tell, but we need accurate information to
+ * always be able to tell, but we need accurate information to
* work reliably.
*/
void dpm_set_power_state(struct device * dev, u32 state)
diff --git a/drivers/base/power/shutdown.c b/drivers/base/power/shutdown.c
index 6725ffacb518..d1e023fbe169 100644
--- a/drivers/base/power/shutdown.c
+++ b/drivers/base/power/shutdown.c
@@ -1,9 +1,9 @@
/*
* shutdown.c - power management functions for the device tree.
- *
+ *
* Copyright (c) 2002-3 Patrick Mochel
* 2002-3 Open Source Development Lab
- *
+ *
* This file is released under the GPLv2
*
*/
@@ -14,7 +14,7 @@
#include "power.h"
-#define to_dev(node) container_of(node,struct device,kobj.entry)
+#define to_dev(node) container_of(node, struct device, kobj.entry)
extern struct subsystem devices_subsys;
@@ -29,7 +29,7 @@ int device_detach_shutdown(struct device * dev)
dev->driver->shutdown(dev);
return 0;
}
- return dpm_runtime_suspend(dev,dev->detach_state);
+ return dpm_runtime_suspend(dev, dev->detach_state);
}
@@ -38,8 +38,8 @@ int device_detach_shutdown(struct device * dev)
* down last and resume them first. That way, we don't do anything stupid like
* shutting down the interrupt controller before any devices..
*
- * Note that there are not different stages for power management calls -
- * they only get one called once when interrupts are disabled.
+ * Note that there are not different stages for power management calls -
+ * they only get one called once when interrupts are disabled.
*/
extern int sysdev_shutdown(void);
@@ -50,10 +50,10 @@ extern int sysdev_shutdown(void);
void device_shutdown(void)
{
struct device * dev;
-
+
down_write(&devices_subsys.rwsem);
- list_for_each_entry_reverse(dev,&devices_subsys.kset.list,kobj.entry) {
- pr_debug("shutting down %s: ",dev->bus_id);
+ list_for_each_entry_reverse(dev, &devices_subsys.kset.list, kobj.entry) {
+ pr_debug("shutting down %s: ", dev->bus_id);
if (dev->driver && dev->driver->shutdown) {
pr_debug("Ok\n");
dev->driver->shutdown(dev);
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
index a2bc41cc9a38..86f9e6ec05a8 100644
--- a/drivers/base/power/suspend.c
+++ b/drivers/base/power/suspend.c
@@ -1,5 +1,5 @@
/*
- * suspend.c - Functions for putting devices to sleep.
+ * suspend.c - Functions for putting devices to sleep.
*
* Copyright (c) 2003 Patrick Mochel
* Copyright (c) 2003 Open Source Development Labs
@@ -10,18 +10,18 @@
#include <linux/device.h>
#include "power.h"
-
+
extern int sysdev_suspend(u32 state);
/*
* The entries in the dpm_active list are in a depth first order, simply
- * because children are guaranteed to be discovered after parents, and
- * are inserted at the back of the list on discovery.
- *
+ * because children are guaranteed to be discovered after parents, and
+ * are inserted at the back of the list on discovery.
+ *
* All list on the suspend path are done in reverse order, so we operate
* on the leaves of the device tree (or forests, depending on how you want
- * to look at it ;) first. As nodes are removed from the back of the list,
- * they are inserted into the front of their destintation lists.
+ * to look at it ;) first. As nodes are removed from the back of the list,
+ * they are inserted into the front of their destintation lists.
*
* Things are the reverse on the resume path - iterations are done in
* forward order, and nodes are inserted at the back of their destination
@@ -44,7 +44,7 @@ int suspend_device(struct device * dev, u32 state)
dev->power.prev_state = dev->power.power_state;
if (dev->bus && dev->bus->suspend && !dev->power.power_state)
- error = dev->bus->suspend(dev,state);
+ error = dev->bus->suspend(dev, state);
return error;
}
@@ -52,16 +52,16 @@ int suspend_device(struct device * dev, u32 state)
/**
* device_suspend - Save state and stop all devices in system.
- * @state: Power state to put each device in.
+ * @state: Power state to put each device in.
*
* Walk the dpm_active list, call ->suspend() for each device, and move
- * it to dpm_off.
+ * it to dpm_off.
* Check the return value for each. If it returns 0, then we move the
- * the device to the dpm_off list. If it returns -EAGAIN, we move it to
- * the dpm_off_irq list. If we get a different error, try and back out.
+ * the device to the dpm_off list. If it returns -EAGAIN, we move it to
+ * the dpm_off_irq list. If we get a different error, try and back out.
*
* If we hit a failure with any of the devices, call device_resume()
- * above to bring the suspended devices back to life.
+ * above to bring the suspended devices back to life.
*
* Note this function leaves dpm_sem held to
* a) block other devices from registering.
@@ -78,14 +78,14 @@ int device_suspend(u32 state)
while(!list_empty(&dpm_active)) {
struct list_head * entry = dpm_active.prev;
struct device * dev = to_device(entry);
- error = suspend_device(dev,state);
+ error = suspend_device(dev, state);
if (!error) {
list_del(&dev->power.entry);
- list_add(&dev->power.entry,&dpm_off);
+ list_add(&dev->power.entry, &dpm_off);
} else if (error == -EAGAIN) {
list_del(&dev->power.entry);
- list_add(&dev->power.entry,&dpm_off_irq);
+ list_add(&dev->power.entry, &dpm_off_irq);
} else {
printk(KERN_ERR "Could not suspend device %s: "
"error %d\n", kobject_name(&dev->kobj), error);
@@ -108,8 +108,8 @@ EXPORT_SYMBOL(device_suspend);
* @state: Power state to enter.
*
* Walk the dpm_off_irq list, calling ->power_down() for each device that
- * couldn't power down the device with interrupts enabled. When we're
- * done, power down system devices.
+ * couldn't power down the device with interrupts enabled. When we're
+ * done, power down system devices.
*/
int device_power_down(u32 state)
@@ -117,10 +117,10 @@ int device_power_down(u32 state)
int error = 0;
struct device * dev;
- list_for_each_entry_reverse(dev,&dpm_off_irq,power.entry) {
- if ((error = suspend_device(dev,state)))
+ list_for_each_entry_reverse(dev, &dpm_off_irq, power.entry) {
+ if ((error = suspend_device(dev, state)))
break;
- }
+ }
if (error)
goto Error;
if ((error = sysdev_suspend(state)))
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index 683dd59b0bff..6ac96349a8e8 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -11,10 +11,10 @@
*
* show() returns the current power state of the device. '0' indicates
* the device is on. Other values (1-3) indicate the device is in a low
- * power state.
+ * power state.
*
- * store() sets the current power state, which is an integer value
- * between 0-3. If the device is on ('0'), and the value written is
+ * store() sets the current power state, which is an integer value
+ * between 0-3. If the device is on ('0'), and the value written is
* greater than 0, then the device is placed directly into the low-power
* state (via its driver's ->suspend() method).
* If the device is currently in a low-power state, and the value is 0,
@@ -26,7 +26,7 @@
static ssize_t state_show(struct device * dev, char * buf)
{
- return sprintf(buf,"%u\n",dev->power.power_state);
+ return sprintf(buf, "%u\n", dev->power.power_state);
}
static ssize_t state_store(struct device * dev, const char * buf, size_t n)
@@ -35,17 +35,17 @@ static ssize_t state_store(struct device * dev, const char * buf, size_t n)
char * rest;
int error = 0;
- state = simple_strtoul(buf,&rest,10);
+ state = simple_strtoul(buf, &rest, 10);
if (*rest)
return -EINVAL;
if (state)
- error = dpm_runtime_suspend(dev,state);
+ error = dpm_runtime_suspend(dev, state);
else
dpm_runtime_resume(dev);
return error ? error : n;
}
-static DEVICE_ATTR(state,0644,state_show,state_store);
+static DEVICE_ATTR(state, 0644, state_show, state_store);
static struct attribute * power_attrs[] = {
@@ -59,10 +59,10 @@ static struct attribute_group pm_attr_group = {
int dpm_sysfs_add(struct device * dev)
{
- return sysfs_create_group(&dev->kobj,&pm_attr_group);
+ return sysfs_create_group(&dev->kobj, &pm_attr_group);
}
void dpm_sysfs_remove(struct device * dev)
{
- sysfs_remove_group(&dev->kobj,&pm_attr_group);
+ sysfs_remove_group(&dev->kobj, &pm_attr_group);
}
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index b0d55a930855..9d10500cd961 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -5,8 +5,8 @@
* 2002-3 Open Source Development Lab
*
* This file is released under the GPLv2
- *
- * This exports a 'system' bus type.
+ *
+ * This exports a 'system' bus type.
* By default, a 'sys' bus gets added to the root of the system. There will
* always be core system devices. Devices can use sysdev_register() to
* add themselves as children of the system bus.
@@ -24,31 +24,31 @@
extern struct subsystem devices_subsys;
-#define to_sysdev(k) container_of(k,struct sys_device,kobj)
-#define to_sysdev_attr(a) container_of(a,struct sysdev_attribute,attr)
+#define to_sysdev(k) container_of(k, struct sys_device, kobj)
+#define to_sysdev_attr(a) container_of(a, struct sysdev_attribute, attr)
-static ssize_t
+static ssize_t
sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer)
{
struct sys_device * sysdev = to_sysdev(kobj);
struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
if (sysdev_attr->show)
- return sysdev_attr->show(sysdev,buffer);
+ return sysdev_attr->show(sysdev, buffer);
return 0;
}
static ssize_t
-sysdev_store(struct kobject * kobj, struct attribute * attr,
+sysdev_store(struct kobject * kobj, struct attribute * attr,
const char * buffer, size_t count)
{
struct sys_device * sysdev = to_sysdev(kobj);
struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
if (sysdev_attr->store)
- return sysdev_attr->store(sysdev,buffer,count);
+ return sysdev_attr->store(sysdev, buffer, count);
return 0;
}
@@ -64,22 +64,22 @@ static struct kobj_type ktype_sysdev = {
int sysdev_create_file(struct sys_device * s, struct sysdev_attribute * a)
{
- return sysfs_create_file(&s->kobj,&a->attr);
+ return sysfs_create_file(&s->kobj, &a->attr);
}
void sysdev_remove_file(struct sys_device * s, struct sysdev_attribute * a)
{
- sysfs_remove_file(&s->kobj,&a->attr);
+ sysfs_remove_file(&s->kobj, &a->attr);
}
EXPORT_SYMBOL(sysdev_create_file);
EXPORT_SYMBOL(sysdev_remove_file);
-/*
- * declare system_subsys
+/*
+ * declare system_subsys
*/
-decl_subsys(system,&ktype_sysdev,NULL);
+decl_subsys(system, &ktype_sysdev, NULL);
int sysdev_class_register(struct sysdev_class * cls)
{
@@ -87,7 +87,7 @@ int sysdev_class_register(struct sysdev_class * cls)
kobject_name(&cls->kset.kobj));
INIT_LIST_HEAD(&cls->drivers);
cls->kset.subsys = &system_subsys;
- kset_set_kset_s(cls,system_subsys);
+ kset_set_kset_s(cls, system_subsys);
return kset_register(&cls->kset);
}
@@ -109,19 +109,19 @@ static LIST_HEAD(global_drivers);
* @cls: Device class driver belongs to.
* @drv: Driver.
*
- * If @cls is valid, then @drv is inserted into @cls->drivers to be
+ * If @cls is valid, then @drv is inserted into @cls->drivers to be
* called on each operation on devices of that class. The refcount
- * of @cls is incremented.
- * Otherwise, @drv is inserted into global_drivers, and called for
+ * of @cls is incremented.
+ * Otherwise, @drv is inserted into global_drivers, and called for
* each device.
*/
-int sysdev_driver_register(struct sysdev_class * cls,
+int sysdev_driver_register(struct sysdev_class * cls,
struct sysdev_driver * drv)
{
down_write(&system_subsys.rwsem);
if (cls && kset_get(&cls->kset)) {
- list_add_tail(&drv->entry,&cls->drivers);
+ list_add_tail(&drv->entry, &cls->drivers);
/* If devices of this class already exist, tell the driver */
if (drv->add) {
@@ -130,7 +130,7 @@ int sysdev_driver_register(struct sysdev_class * cls,
drv->add(dev);
}
} else
- list_add_tail(&drv->entry,&global_drivers);
+ list_add_tail(&drv->entry, &global_drivers);
up_write(&system_subsys.rwsem);
return 0;
}
@@ -180,12 +180,12 @@ int sysdev_register(struct sys_device * sysdev)
/* But make sure we point to the right type for sysfs translation */
sysdev->kobj.ktype = &ktype_sysdev;
- error = kobject_set_name(&sysdev->kobj,"%s%d",
- kobject_name(&cls->kset.kobj),sysdev->id);
+ error = kobject_set_name(&sysdev->kobj, "%s%d",
+ kobject_name(&cls->kset.kobj), sysdev->id);
if (error)
return error;
- pr_debug("Registering sys device '%s'\n",kobject_name(&sysdev->kobj));
+ pr_debug("Registering sys device '%s'\n", kobject_name(&sysdev->kobj));
/* Register the object */
error = kobject_register(&sysdev->kobj);
@@ -194,18 +194,18 @@ int sysdev_register(struct sys_device * sysdev)
struct sysdev_driver * drv;
down_write(&system_subsys.rwsem);
- /* Generic notification is implicit, because it's that
- * code that should have called us.
+ /* Generic notification is implicit, because it's that
+ * code that should have called us.
*/
/* Notify global drivers */
- list_for_each_entry(drv,&global_drivers,entry) {
+ list_for_each_entry(drv, &global_drivers, entry) {
if (drv->add)
drv->add(sysdev);
}
/* Notify class auxillary drivers */
- list_for_each_entry(drv,&cls->drivers,entry) {
+ list_for_each_entry(drv, &cls->drivers, entry) {
if (drv->add)
drv->add(sysdev);
}
@@ -219,12 +219,12 @@ void sysdev_unregister(struct sys_device * sysdev)
struct sysdev_driver * drv;
down_write(&system_subsys.rwsem);
- list_for_each_entry(drv,&global_drivers,entry) {
+ list_for_each_entry(drv, &global_drivers, entry) {
if (drv->remove)
drv->remove(sysdev);
}
- list_for_each_entry(drv,&sysdev->cls->drivers,entry) {
+ list_for_each_entry(drv, &sysdev->cls->drivers, entry) {
if (drv->remove)
drv->remove(sysdev);
}
@@ -241,12 +241,12 @@ void sysdev_unregister(struct sys_device * sysdev)
* Loop over each class of system devices, and the devices in each
* of those classes. For each device, we call the shutdown method for
* each driver registered for the device - the globals, the auxillaries,
- * and the class driver.
+ * and the class driver.
*
* Note: The list is iterated in reverse order, so that we shut down
* child devices before we shut down thier parents. The list ordering
* is guaranteed by virtue of the fact that child devices are registered
- * after their parents.
+ * after their parents.
*/
void sysdev_shutdown(void)
@@ -256,25 +256,25 @@ void sysdev_shutdown(void)
pr_debug("Shutting Down System Devices\n");
down_write(&system_subsys.rwsem);
- list_for_each_entry_reverse(cls,&system_subsys.kset.list,
+ list_for_each_entry_reverse(cls, &system_subsys.kset.list,
kset.kobj.entry) {
struct sys_device * sysdev;
pr_debug("Shutting down type '%s':\n",
kobject_name(&cls->kset.kobj));
- list_for_each_entry(sysdev,&cls->kset.list,kobj.entry) {
+ list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
struct sysdev_driver * drv;
- pr_debug(" %s\n",kobject_name(&sysdev->kobj));
+ pr_debug(" %s\n", kobject_name(&sysdev->kobj));
/* Call global drivers first. */
- list_for_each_entry(drv,&global_drivers,entry) {
+ list_for_each_entry(drv, &global_drivers, entry) {
if (drv->shutdown)
drv->shutdown(sysdev);
}
/* Call auxillary drivers next. */
- list_for_each_entry(drv,&cls->drivers,entry) {
+ list_for_each_entry(drv, &cls->drivers, entry) {
if (drv->shutdown)
drv->shutdown(sysdev);
}
@@ -295,7 +295,7 @@ void sysdev_shutdown(void)
* We perform an almost identical operation as sys_device_shutdown()
* above, though calling ->suspend() instead. Interrupts are disabled
* when this called. Devices are responsible for both saving state and
- * quiescing or powering down the device.
+ * quiescing or powering down the device.
*
* This is only called by the device PM core, so we let them handle
* all synchronization.
@@ -307,32 +307,32 @@ int sysdev_suspend(u32 state)
pr_debug("Suspending System Devices\n");
- list_for_each_entry_reverse(cls,&system_subsys.kset.list,
+ list_for_each_entry_reverse(cls, &system_subsys.kset.list,
kset.kobj.entry) {
struct sys_device * sysdev;
pr_debug("Suspending type '%s':\n",
kobject_name(&cls->kset.kobj));
- list_for_each_entry(sysdev,&cls->kset.list,kobj.entry) {
+ list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
struct sysdev_driver * drv;
- pr_debug(" %s\n",kobject_name(&sysdev->kobj));
+ pr_debug(" %s\n", kobject_name(&sysdev->kobj));
/* Call global drivers first. */
- list_for_each_entry(drv,&global_drivers,entry) {
+ list_for_each_entry(drv, &global_drivers, entry) {
if (drv->suspend)
- drv->suspend(sysdev,state);
+ drv->suspend(sysdev, state);
}
/* Call auxillary drivers next. */
- list_for_each_entry(drv,&cls->drivers,entry) {
+ list_for_each_entry(drv, &cls->drivers, entry) {
if (drv->suspend)
- drv->suspend(sysdev,state);
+ drv->suspend(sysdev, state);
}
/* Now call the generic one */
if (cls->suspend)
- cls->suspend(sysdev,state);
+ cls->suspend(sysdev, state);
}
}
return 0;
@@ -345,7 +345,7 @@ int sysdev_suspend(u32 state)
* Similar to sys_device_suspend(), but we iterate the list forwards
* to guarantee that parent devices are resumed before their children.
*
- * Note: Interrupts are disabled when called.
+ * Note: Interrupts are disabled when called.
*/
int sysdev_resume(void)
@@ -354,28 +354,28 @@ int sysdev_resume(void)
pr_debug("Resuming System Devices\n");
- list_for_each_entry(cls,&system_subsys.kset.list,kset.kobj.entry) {
+ list_for_each_entry(cls, &system_subsys.kset.list, kset.kobj.entry) {
struct sys_device * sysdev;
pr_debug("Resuming type '%s':\n",
kobject_name(&cls->kset.kobj));
- list_for_each_entry(sysdev,&cls->kset.list,kobj.entry) {
+ list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
struct sysdev_driver * drv;
- pr_debug(" %s\n",kobject_name(&sysdev->kobj));
+ pr_debug(" %s\n", kobject_name(&sysdev->kobj));
/* First, call the class-specific one */
if (cls->resume)
cls->resume(sysdev);
/* Call auxillary drivers next. */
- list_for_each_entry(drv,&cls->drivers,entry) {
+ list_for_each_entry(drv, &cls->drivers, entry) {
if (drv->resume)
drv->resume(sysdev);
}
/* Call global drivers. */
- list_for_each_entry(drv,&global_drivers,entry) {
+ list_for_each_entry(drv, &global_drivers, entry) {
if (drv->resume)
drv->resume(sysdev);
}
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 9c19dbc8eb19..b416bdf57080 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -18,6 +18,7 @@
#include <linux/capability.h>
#include <linux/uio.h>
#include <linux/cdev.h>
+#include <linux/device.h>
#include <asm/uaccess.h>
@@ -26,6 +27,7 @@ struct raw_device_data {
int inuse;
};
+static struct class_simple *raw_class;
static struct raw_device_data raw_devices[MAX_RAW_MINORS];
static DECLARE_MUTEX(raw_mutex);
static struct file_operations raw_ctl_fops; /* forward declaration */
@@ -123,6 +125,13 @@ raw_ioctl(struct inode *inode, struct file *filp,
return ioctl_by_bdev(bdev, command, arg);
}
+static void bind_device(struct raw_config_request rq)
+{
+ class_simple_device_remove(MKDEV(RAW_MAJOR, rq.raw_minor));
+ class_simple_device_add(raw_class, MKDEV(RAW_MAJOR, rq.raw_minor),
+ NULL, "raw%d", rq.raw_minor);
+}
+
/*
* Deal with ioctls against the raw-device control interface, to bind
* and unbind other raw devices.
@@ -191,12 +200,15 @@ static int raw_ctl_ioctl(struct inode *inode, struct file *filp,
if (rq.block_major == 0 && rq.block_minor == 0) {
/* unbind */
rawdev->binding = NULL;
+ class_simple_device_remove(MKDEV(RAW_MAJOR, rq.raw_minor));
} else {
rawdev->binding = bdget(dev);
if (rawdev->binding == NULL)
err = -ENOMEM;
- else
+ else {
__module_get(THIS_MODULE);
+ bind_device(rq);
+ }
}
up(&raw_mutex);
} else {
@@ -287,6 +299,15 @@ static int __init raw_init(void)
goto error;
}
+ raw_class = class_simple_create(THIS_MODULE, "raw");
+ if (IS_ERR(raw_class)) {
+ printk(KERN_ERR "Error creating raw class.\n");
+ cdev_del(&raw_cdev);
+ unregister_chrdev_region(dev, MAX_RAW_MINORS);
+ goto error;
+ }
+ class_simple_device_add(raw_class, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
+
devfs_mk_cdev(MKDEV(RAW_MAJOR, 0),
S_IFCHR | S_IRUGO | S_IWUGO,
"raw/rawctl");
@@ -309,6 +330,8 @@ static void __exit raw_exit(void)
devfs_remove("raw/raw%d", i);
devfs_remove("raw/rawctl");
devfs_remove("raw");
+ class_simple_device_remove(MKDEV(RAW_MAJOR, 0));
+ class_simple_destroy(raw_class);
cdev_del(&raw_cdev);
unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), MAX_RAW_MINORS);
}
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 31ee54341952..6e22814a7f40 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -138,7 +138,7 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev));
- if(ibm_dmi_probe()) {
+ if(ibm_dmi_probe() && PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) {
dev_err(&PIIX4_dev->dev, "IBM Laptop detected; this module "
"may corrupt your serial eeprom! Refusing to load "
"module!\n");
diff --git a/drivers/i2c/chips/asb100.c b/drivers/i2c/chips/asb100.c
index f93b6f67696e..a416e4ee560e 100644
--- a/drivers/i2c/chips/asb100.c
+++ b/drivers/i2c/chips/asb100.c
@@ -272,7 +272,7 @@ static ssize_t \
return show_in(dev, buf, 0x##offset); \
} \
static DEVICE_ATTR(in##offset##_input, S_IRUGO, \
- show_in##offset, NULL) \
+ show_in##offset, NULL); \
static ssize_t \
show_in##offset##_min (struct device *dev, char *buf) \
{ \
@@ -294,17 +294,17 @@ static ssize_t set_in##offset##_max (struct device *dev, \
return set_in_max(dev, buf, count, 0x##offset); \
} \
static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
- show_in##offset##_min, set_in##offset##_min) \
+ show_in##offset##_min, set_in##offset##_min); \
static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
- show_in##offset##_max, set_in##offset##_max)
+ show_in##offset##_max, set_in##offset##_max);
-sysfs_in(0)
-sysfs_in(1)
-sysfs_in(2)
-sysfs_in(3)
-sysfs_in(4)
-sysfs_in(5)
-sysfs_in(6)
+sysfs_in(0);
+sysfs_in(1);
+sysfs_in(2);
+sysfs_in(3);
+sysfs_in(4);
+sysfs_in(5);
+sysfs_in(6);
#define device_create_file_in(client, offset) do { \
device_create_file(&client->dev, &dev_attr_in##offset##_input); \
@@ -410,15 +410,15 @@ static ssize_t set_fan##offset##_div(struct device *dev, const char *buf, \
return set_fan_div(dev, buf, count, offset - 1); \
} \
static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
- show_fan##offset, NULL) \
+ show_fan##offset, NULL); \
static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
- show_fan##offset##_min, set_fan##offset##_min) \
+ show_fan##offset##_min, set_fan##offset##_min); \
static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
- show_fan##offset##_div, set_fan##offset##_div)
+ show_fan##offset##_div, set_fan##offset##_div);
-sysfs_fan(1)
-sysfs_fan(2)
-sysfs_fan(3)
+sysfs_fan(1);
+sysfs_fan(2);
+sysfs_fan(3);
#define device_create_file_fan(client, offset) do { \
device_create_file(&client->dev, &dev_attr_fan##offset##_input); \
@@ -449,9 +449,9 @@ static ssize_t show_##reg(struct device *dev, char *buf, int nr) \
return sprintf_temp_from_reg(data->reg[nr], buf, nr); \
}
-show_temp_reg(temp)
-show_temp_reg(temp_max)
-show_temp_reg(temp_hyst)
+show_temp_reg(temp);
+show_temp_reg(temp_max);
+show_temp_reg(temp_hyst);
#define set_temp_reg(REG, reg) \
static ssize_t set_##reg(struct device *dev, const char *buf, \
@@ -473,15 +473,15 @@ static ssize_t set_##reg(struct device *dev, const char *buf, \
return count; \
}
-set_temp_reg(MAX, temp_max)
-set_temp_reg(HYST, temp_hyst)
+set_temp_reg(MAX, temp_max);
+set_temp_reg(HYST, temp_hyst);
#define sysfs_temp(num) \
static ssize_t show_temp##num(struct device *dev, char *buf) \
{ \
return show_temp(dev, buf, num-1); \
} \
-static DEVICE_ATTR(temp##num##_input, S_IRUGO, show_temp##num, NULL) \
+static DEVICE_ATTR(temp##num##_input, S_IRUGO, show_temp##num, NULL); \
static ssize_t show_temp_max##num(struct device *dev, char *buf) \
{ \
return show_temp_max(dev, buf, num-1); \
@@ -492,7 +492,7 @@ static ssize_t set_temp_max##num(struct device *dev, const char *buf, \
return set_temp_max(dev, buf, count, num-1); \
} \
static DEVICE_ATTR(temp##num##_max, S_IRUGO | S_IWUSR, \
- show_temp_max##num, set_temp_max##num) \
+ show_temp_max##num, set_temp_max##num); \
static ssize_t show_temp_hyst##num(struct device *dev, char *buf) \
{ \
return show_temp_hyst(dev, buf, num-1); \
@@ -503,12 +503,12 @@ static ssize_t set_temp_hyst##num(struct device *dev, const char *buf, \
return set_temp_hyst(dev, buf, count, num-1); \
} \
static DEVICE_ATTR(temp##num##_max_hyst, S_IRUGO | S_IWUSR, \
- show_temp_hyst##num, set_temp_hyst##num)
+ show_temp_hyst##num, set_temp_hyst##num);
-sysfs_temp(1)
-sysfs_temp(2)
-sysfs_temp(3)
-sysfs_temp(4)
+sysfs_temp(1);
+sysfs_temp(2);
+sysfs_temp(3);
+sysfs_temp(4);
/* VID */
#define device_create_file_temp(client, num) do { \
@@ -523,7 +523,7 @@ static ssize_t show_vid(struct device *dev, char *buf)
return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
}
-static DEVICE_ATTR(in0_ref, S_IRUGO, show_vid, NULL)
+static DEVICE_ATTR(in0_ref, S_IRUGO, show_vid, NULL);
#define device_create_file_vid(client) \
device_create_file(&client->dev, &dev_attr_in0_ref)
@@ -544,7 +544,7 @@ static ssize_t set_vrm(struct device *dev, const char *buf, size_t count)
}
/* Alarms */
-static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm)
+static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
#define device_create_file_vrm(client) \
device_create_file(&client->dev, &dev_attr_vrm);
@@ -554,7 +554,7 @@ static ssize_t show_alarms(struct device *dev, char *buf)
return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->alarms));
}
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL)
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
#define device_create_file_alarms(client) \
device_create_file(&client->dev, &dev_attr_alarms)
@@ -594,9 +594,9 @@ static ssize_t set_pwm_enable1(struct device *dev, const char *buf,
return count;
}
-static DEVICE_ATTR(fan1_pwm, S_IRUGO | S_IWUSR, show_pwm1, set_pwm1)
+static DEVICE_ATTR(fan1_pwm, S_IRUGO | S_IWUSR, show_pwm1, set_pwm1);
static DEVICE_ATTR(fan1_pwm_enable, S_IRUGO | S_IWUSR,
- show_pwm_enable1, set_pwm_enable1)
+ show_pwm_enable1, set_pwm_enable1);
#define device_create_file_pwm1(client) do { \
device_create_file(&new_client->dev, &dev_attr_fan1_pwm); \
device_create_file(&new_client->dev, &dev_attr_fan1_pwm_enable); \
diff --git a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c
index 061a0b8009b5..ef656298779a 100644
--- a/drivers/i2c/chips/it87.c
+++ b/drivers/i2c/chips/it87.c
@@ -128,15 +128,15 @@ static int reset;
#define IT87_REG_FAN(nr) (0x0d + (nr))
#define IT87_REG_FAN_MIN(nr) (0x10 + (nr))
-#define IT87_REG_FAN_CTRL 0x13
+#define IT87_REG_FAN_MAIN_CTRL 0x13
#define IT87_REG_VIN(nr) (0x20 + (nr))
#define IT87_REG_TEMP(nr) (0x29 + (nr))
#define IT87_REG_VIN_MAX(nr) (0x30 + (nr) * 2)
#define IT87_REG_VIN_MIN(nr) (0x31 + (nr) * 2)
-#define IT87_REG_TEMP_HIGH(nr) (0x40 + ((nr) * 2))
-#define IT87_REG_TEMP_LOW(nr) (0x41 + ((nr) * 2))
+#define IT87_REG_TEMP_HIGH(nr) (0x40 + (nr) * 2)
+#define IT87_REG_TEMP_LOW(nr) (0x41 + (nr) * 2)
#define IT87_REG_I2C_ADDR 0x48
@@ -145,8 +145,8 @@ static int reset;
#define IT87_REG_CHIPID 0x58
-#define IN_TO_REG(val) (SENSORS_LIMIT((((val) * 10 + 8)/16),0,255))
-#define IN_FROM_REG(val) (((val) * 16) / 10)
+#define IN_TO_REG(val) (SENSORS_LIMIT((((val) + 8)/16),0,255))
+#define IN_FROM_REG(val) ((val) * 16)
static inline u8 FAN_TO_REG(long rpm, int div)
{
@@ -159,9 +159,9 @@ static inline u8 FAN_TO_REG(long rpm, int div)
#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div)))
-#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-5)/10):\
- ((val)+5)/10),0,255))
-#define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*10)
+#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-500)/1000):\
+ ((val)+500)/1000),-128,127))
+#define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*1000)
#define VID_FROM_REG(val) ((val)==0x1f?0:(val)>=0x10?510-(val)*10:\
205-(val)*5)
@@ -170,7 +170,7 @@ static inline u8 FAN_TO_REG(long rpm, int div)
static int DIV_TO_REG(int val)
{
int answer = 0;
- while ((val >>= 1))
+ while ((val >>= 1) != 0)
answer++;
return answer;
}
@@ -231,19 +231,19 @@ static int it87_id = 0;
static ssize_t show_in(struct device *dev, char *buf, int nr)
{
struct it87_data *data = it87_update_device(dev);
- return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr])*10 );
+ return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr]));
}
static ssize_t show_in_min(struct device *dev, char *buf, int nr)
{
struct it87_data *data = it87_update_device(dev);
- return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr])*10 );
+ return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr]));
}
static ssize_t show_in_max(struct device *dev, char *buf, int nr)
{
struct it87_data *data = it87_update_device(dev);
- return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr])*10 );
+ return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr]));
}
static ssize_t set_in_min(struct device *dev, const char *buf,
@@ -251,7 +251,7 @@ static ssize_t set_in_min(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct it87_data *data = i2c_get_clientdata(client);
- unsigned long val = simple_strtoul(buf, NULL, 10)/10;
+ unsigned long val = simple_strtoul(buf, NULL, 10);
data->in_min[nr] = IN_TO_REG(val);
it87_write_value(client, IT87_REG_VIN_MIN(nr),
data->in_min[nr]);
@@ -262,7 +262,7 @@ static ssize_t set_in_max(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct it87_data *data = i2c_get_clientdata(client);
- unsigned long val = simple_strtoul(buf, NULL, 10)/10;
+ unsigned long val = simple_strtoul(buf, NULL, 10);
data->in_max[nr] = IN_TO_REG(val);
it87_write_value(client, IT87_REG_VIN_MAX(nr),
data->in_max[nr]);
@@ -275,7 +275,7 @@ static ssize_t \
{ \
return show_in(dev, buf, 0x##offset); \
} \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL)
+static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL);
#define limit_in_offset(offset) \
static ssize_t \
@@ -299,9 +299,9 @@ static ssize_t set_in##offset##_max (struct device *dev, \
return set_in_max(dev, buf, count, 0x##offset); \
} \
static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
- show_in##offset##_min, set_in##offset##_min) \
+ show_in##offset##_min, set_in##offset##_min); \
static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
- show_in##offset##_max, set_in##offset##_max)
+ show_in##offset##_max, set_in##offset##_max);
show_in_offset(0);
limit_in_offset(0);
@@ -325,24 +325,24 @@ show_in_offset(8);
static ssize_t show_temp(struct device *dev, char *buf, int nr)
{
struct it87_data *data = it87_update_device(dev);
- return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr])*100 );
+ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr]));
}
static ssize_t show_temp_max(struct device *dev, char *buf, int nr)
{
struct it87_data *data = it87_update_device(dev);
- return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_high[nr])*100);
+ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_high[nr]));
}
static ssize_t show_temp_min(struct device *dev, char *buf, int nr)
{
struct it87_data *data = it87_update_device(dev);
- return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_low[nr])*100);
+ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_low[nr]));
}
static ssize_t set_temp_max(struct device *dev, const char *buf,
size_t count, int nr)
{
struct i2c_client *client = to_i2c_client(dev);
struct it87_data *data = i2c_get_clientdata(client);
- int val = simple_strtol(buf, NULL, 10)/100;
+ int val = simple_strtol(buf, NULL, 10);
data->temp_high[nr] = TEMP_TO_REG(val);
it87_write_value(client, IT87_REG_TEMP_HIGH(nr), data->temp_high[nr]);
return count;
@@ -352,7 +352,7 @@ static ssize_t set_temp_min(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct it87_data *data = i2c_get_clientdata(client);
- int val = simple_strtol(buf, NULL, 10)/100;
+ int val = simple_strtol(buf, NULL, 10);
data->temp_low[nr] = TEMP_TO_REG(val);
it87_write_value(client, IT87_REG_TEMP_LOW(nr), data->temp_low[nr]);
return count;
@@ -382,11 +382,11 @@ static ssize_t set_temp_##offset##_min (struct device *dev, \
{ \
return set_temp_min(dev, buf, count, 0x##offset - 1); \
} \
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL) \
+static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL); \
static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
- show_temp_##offset##_max, set_temp_##offset##_max) \
+ show_temp_##offset##_max, set_temp_##offset##_max); \
static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \
- show_temp_##offset##_min, set_temp_##offset##_min)
+ show_temp_##offset##_min, set_temp_##offset##_min);
show_temp_offset(1);
show_temp_offset(2);
@@ -430,8 +430,8 @@ static ssize_t set_sensor_##offset (struct device *dev, \
{ \
return set_sensor(dev, buf, count, 0x##offset - 1); \
} \
-static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, \
- show_sensor_##offset, set_sensor_##offset)
+static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, \
+ show_sensor_##offset, set_sensor_##offset);
show_sensor_offset(1);
show_sensor_offset(2);
@@ -525,11 +525,11 @@ static ssize_t set_fan_##offset##_div (struct device *dev, \
{ \
return set_fan_div(dev, buf, count, 0x##offset - 1); \
} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL) \
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL); \
static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
- show_fan_##offset##_min, set_fan_##offset##_min) \
+ show_fan_##offset##_min, set_fan_##offset##_min); \
static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
- show_fan_##offset##_div, set_fan_##offset##_div)
+ show_fan_##offset##_div, set_fan_##offset##_div);
show_fan_offset(1);
show_fan_offset(2);
@@ -773,9 +773,7 @@ static int it87_detach_client(struct i2c_client *client)
We don't want to lock the whole ISA bus, so we lock each client
separately.
We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
- would slow down the IT87 access and should not be necessary.
- There are some ugly typecasts here, but the good new is - they should
- nowhere else be necessary! */
+ would slow down the IT87 access and should not be necessary. */
static int it87_read_value(struct i2c_client *client, u8 reg)
{
struct it87_data *data = i2c_get_clientdata(client);
@@ -795,9 +793,7 @@ static int it87_read_value(struct i2c_client *client, u8 reg)
We don't want to lock the whole ISA bus, so we lock each client
separately.
We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
- would slow down the IT87 access and should not be necessary.
- There are some ugly typecasts here, but the good new is - they should
- nowhere else be necessary! */
+ would slow down the IT87 access and should not be necessary. */
static int it87_write_value(struct i2c_client *client, u8 reg, u8 value)
{
struct it87_data *data = i2c_get_clientdata(client);
@@ -840,11 +836,11 @@ static void it87_init_client(struct i2c_client *client, struct it87_data *data)
}
/* Check if tachometers are reset manually or by some reason */
- tmp = it87_read_value(client, IT87_REG_FAN_CTRL);
+ tmp = it87_read_value(client, IT87_REG_FAN_MAIN_CTRL);
if ((tmp & 0x70) == 0) {
/* Enable all fan tachometers */
tmp = (tmp & 0x8f) | 0x70;
- it87_write_value(client, IT87_REG_FAN_CTRL, tmp);
+ it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, tmp);
}
/* Start monitoring */
diff --git a/drivers/i2c/chips/lm78.c b/drivers/i2c/chips/lm78.c
index 74a1ca76cc04..b9ffad6c36e4 100644
--- a/drivers/i2c/chips/lm78.c
+++ b/drivers/i2c/chips/lm78.c
@@ -281,7 +281,7 @@ static ssize_t \
return show_in(dev, buf, 0x##offset); \
} \
static DEVICE_ATTR(in##offset##_input, S_IRUGO, \
- show_in##offset, NULL) \
+ show_in##offset, NULL); \
static ssize_t \
show_in##offset##_min (struct device *dev, char *buf) \
{ \
@@ -303,9 +303,9 @@ static ssize_t set_in##offset##_max (struct device *dev, \
return set_in_max(dev, buf, count, 0x##offset); \
} \
static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
- show_in##offset##_min, set_in##offset##_min) \
+ show_in##offset##_min, set_in##offset##_min); \
static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
- show_in##offset##_max, set_in##offset##_max)
+ show_in##offset##_max, set_in##offset##_max);
show_in_offset(0);
show_in_offset(1);
@@ -354,11 +354,11 @@ static ssize_t set_temp_hyst(struct device *dev, const char *buf, size_t count)
return count;
}
-static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL)
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL);
static DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR,
- show_temp_over, set_temp_over)
+ show_temp_over, set_temp_over);
static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
- show_temp_hyst, set_temp_hyst)
+ show_temp_hyst, set_temp_hyst);
/* 3 Fans */
static ssize_t show_fan(struct device *dev, char *buf, int nr)
@@ -439,9 +439,9 @@ static ssize_t set_fan_##offset##_min (struct device *dev, \
{ \
return set_fan_min(dev, buf, count, 0x##offset - 1); \
} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL) \
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\
static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
- show_fan_##offset##_min, set_fan_##offset##_min)
+ show_fan_##offset##_min, set_fan_##offset##_min);
static ssize_t set_fan_1_div(struct device *dev, const char *buf,
size_t count)
@@ -461,10 +461,10 @@ show_fan_offset(3);
/* Fan 3 divisor is locked in H/W */
static DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR,
- show_fan_1_div, set_fan_1_div)
+ show_fan_1_div, set_fan_1_div);
static DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
- show_fan_2_div, set_fan_2_div)
-static DEVICE_ATTR(fan3_div, S_IRUGO, show_fan_3_div, NULL)
+ show_fan_2_div, set_fan_2_div);
+static DEVICE_ATTR(fan3_div, S_IRUGO, show_fan_3_div, NULL);
/* VID */
static ssize_t show_vid(struct device *dev, char *buf)
diff --git a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c
index 795852aa6719..11f85043153b 100644
--- a/drivers/i2c/chips/lm85.c
+++ b/drivers/i2c/chips/lm85.c
@@ -451,9 +451,9 @@ static ssize_t set_fan_##offset##_min (struct device *dev, \
{ \
return set_fan_min(dev, buf, count, 0x##offset - 1); \
} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL) \
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\
static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
- show_fan_##offset##_min, set_fan_##offset##_min)
+ show_fan_##offset##_min, set_fan_##offset##_min);
show_fan_offset(1);
show_fan_offset(2);
@@ -468,7 +468,7 @@ static ssize_t show_vid_reg(struct device *dev, char *buf)
return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
}
-static DEVICE_ATTR(in0_ref, S_IRUGO, show_vid_reg, NULL)
+static DEVICE_ATTR(in0_ref, S_IRUGO, show_vid_reg, NULL);
static ssize_t show_vrm_reg(struct device *dev, char *buf)
{
@@ -487,7 +487,7 @@ static ssize_t store_vrm_reg(struct device *dev, const char *buf, size_t count)
return count;
}
-static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg)
+static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
static ssize_t show_alarms_reg(struct device *dev, char *buf)
{
@@ -495,7 +495,7 @@ static ssize_t show_alarms_reg(struct device *dev, char *buf)
return sprintf(buf, "%ld\n", (long) ALARMS_FROM_REG(data->alarms));
}
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL)
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
/* pwm */
@@ -542,8 +542,8 @@ static ssize_t show_pwm_enable##offset (struct device *dev, char *buf) \
return show_pwm_enable(dev, buf, 0x##offset - 1); \
} \
static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, \
- show_pwm_##offset, set_pwm_##offset) \
-static DEVICE_ATTR(fan##offset##_pwm_enable, S_IRUGO, show_pwm_enable##offset, NULL)
+ show_pwm_##offset, set_pwm_##offset); \
+static DEVICE_ATTR(fan##offset##_pwm_enable, S_IRUGO, show_pwm_enable##offset, NULL);
show_pwm_reg(1);
show_pwm_reg(2);
@@ -617,11 +617,11 @@ static ssize_t set_in_##offset##_max (struct device *dev, \
{ \
return set_in_max(dev, buf, count, 0x##offset); \
} \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in_##offset, NULL) \
+static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in_##offset, NULL); \
static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
- show_in_##offset##_min, set_in_##offset##_min) \
+ show_in_##offset##_min, set_in_##offset##_min); \
static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
- show_in_##offset##_max, set_in_##offset##_max)
+ show_in_##offset##_max, set_in_##offset##_max);
show_in_reg(0);
show_in_reg(1);
@@ -697,11 +697,11 @@ static ssize_t set_temp_##offset##_max (struct device *dev, \
{ \
return set_temp_max(dev, buf, count, 0x##offset - 1); \
} \
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL) \
+static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL); \
static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \
- show_temp_##offset##_min, set_temp_##offset##_min) \
+ show_temp_##offset##_min, set_temp_##offset##_min); \
static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
- show_temp_##offset##_max, set_temp_##offset##_max)
+ show_temp_##offset##_max, set_temp_##offset##_max);
show_temp_reg(1);
show_temp_reg(2);
diff --git a/drivers/i2c/chips/via686a.c b/drivers/i2c/chips/via686a.c
index a5ec359b0f6f..3aa334583b89 100644
--- a/drivers/i2c/chips/via686a.c
+++ b/drivers/i2c/chips/via686a.c
@@ -405,11 +405,11 @@ static ssize_t set_in##offset##_max (struct device *dev, \
{ \
return set_in_max(dev, buf, count, 0x##offset); \
} \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL) \
+static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL);\
static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
- show_in##offset##_min, set_in##offset##_min) \
+ show_in##offset##_min, set_in##offset##_min); \
static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
- show_in##offset##_max, set_in##offset##_max)
+ show_in##offset##_max, set_in##offset##_max);
show_in_offset(0);
show_in_offset(1);
@@ -473,11 +473,11 @@ static ssize_t set_temp_##offset##_hyst (struct device *dev, \
{ \
return set_temp_hyst(dev, buf, count, 0x##offset - 1); \
} \
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL) \
+static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL);\
static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
- show_temp_##offset##_over, set_temp_##offset##_over) \
+ show_temp_##offset##_over, set_temp_##offset##_over); \
static DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \
- show_temp_##offset##_hyst, set_temp_##offset##_hyst)
+ show_temp_##offset##_hyst, set_temp_##offset##_hyst);
show_temp_offset(1);
show_temp_offset(2);
@@ -542,11 +542,11 @@ static ssize_t set_fan_##offset##_div (struct device *dev, \
{ \
return set_fan_div(dev, buf, count, 0x##offset - 1); \
} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL) \
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\
static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
- show_fan_##offset##_min, set_fan_##offset##_min) \
+ show_fan_##offset##_min, set_fan_##offset##_min); \
static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
- show_fan_##offset##_div, set_fan_##offset##_div)
+ show_fan_##offset##_div, set_fan_##offset##_div);
show_fan_offset(1);
show_fan_offset(2);
diff --git a/drivers/i2c/chips/w83627hf.c b/drivers/i2c/chips/w83627hf.c
index c38a7f9712b6..649bf80203bd 100644
--- a/drivers/i2c/chips/w83627hf.c
+++ b/drivers/i2c/chips/w83627hf.c
@@ -199,7 +199,7 @@ superio_exit(void)
#define W83627THF_REG_PWM2 0x03 /* 697HF and 637HF too */
#define W83627THF_REG_PWM3 0x11 /* 637HF too */
-#define W83627THF_REG_VRM_OVT_CFG 0x18 /* 637HF too, unused yet */
+#define W83627THF_REG_VRM_OVT_CFG 0x18 /* 637HF too */
static const u8 regpwm_627hf[] = { W83627HF_REG_PWM1, W83627HF_REG_PWM2 };
static const u8 regpwm[] = { W83627THF_REG_PWM1, W83627THF_REG_PWM2,
@@ -222,7 +222,7 @@ static const u8 BIT_SCFG2[] = { 0x10, 0x20, 0x40 };
these macros are called: arguments may be evaluated more than once.
Fixing this is just not worth it. */
#define IN_TO_REG(val) (SENSORS_LIMIT((((val) + 8)/16),0,255))
-#define IN_FROM_REG(val) ((val) * 16 + 5)
+#define IN_FROM_REG(val) ((val) * 16)
static inline u8 FAN_TO_REG(long rpm, int div)
{
@@ -312,6 +312,7 @@ struct w83627hf_data {
Default = 3435.
Other Betas unimplemented */
u8 vrm;
+ u8 vrm_ovt; /* Register value, 627thf & 637hf only */
};
@@ -370,7 +371,7 @@ show_regs_in_##offset (struct device *dev, char *buf) \
{ \
return show_in(dev, buf, 0x##offset); \
} \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL)
+static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL);
#define sysfs_in_reg_offset(reg, offset) \
static ssize_t show_regs_in_##reg##offset (struct device *dev, char *buf) \
@@ -384,22 +385,104 @@ store_regs_in_##reg##offset (struct device *dev, \
return store_in_##reg (dev, buf, count, 0x##offset); \
} \
static DEVICE_ATTR(in##offset##_##reg, S_IRUGO| S_IWUSR, \
- show_regs_in_##reg##offset, store_regs_in_##reg##offset)
+ show_regs_in_##reg##offset, store_regs_in_##reg##offset);
#define sysfs_in_offsets(offset) \
sysfs_in_offset(offset) \
sysfs_in_reg_offset(min, offset) \
sysfs_in_reg_offset(max, offset)
-sysfs_in_offsets(0)
-sysfs_in_offsets(1)
-sysfs_in_offsets(2)
-sysfs_in_offsets(3)
-sysfs_in_offsets(4)
-sysfs_in_offsets(5)
-sysfs_in_offsets(6)
-sysfs_in_offsets(7)
-sysfs_in_offsets(8)
+sysfs_in_offsets(1);
+sysfs_in_offsets(2);
+sysfs_in_offsets(3);
+sysfs_in_offsets(4);
+sysfs_in_offsets(5);
+sysfs_in_offsets(6);
+sysfs_in_offsets(7);
+sysfs_in_offsets(8);
+
+/* use a different set of functions for in0 */
+static ssize_t show_in_0(struct w83627hf_data *data, char *buf, u8 reg)
+{
+ long in0;
+
+ if ((data->vrm_ovt & 0x01) &&
+ (w83627thf == data->type || w83637hf == data->type))
+
+ /* use VRM9 calculation */
+ in0 = (long)((reg * 488 + 70000 + 50) / 100);
+ else
+ /* use VRM8 (standard) calculation */
+ in0 = (long)IN_FROM_REG(reg);
+
+ return sprintf(buf,"%ld\n", in0);
+}
+
+static ssize_t show_regs_in_0(struct device *dev, char *buf)
+{
+ struct w83627hf_data *data = w83627hf_update_device(dev);
+ return show_in_0(data, buf, data->in[0]);
+}
+
+static ssize_t show_regs_in_min0(struct device *dev, char *buf)
+{
+ struct w83627hf_data *data = w83627hf_update_device(dev);
+ return show_in_0(data, buf, data->in_min[0]);
+}
+
+static ssize_t show_regs_in_max0(struct device *dev, char *buf)
+{
+ struct w83627hf_data *data = w83627hf_update_device(dev);
+ return show_in_0(data, buf, data->in_max[0]);
+}
+
+static ssize_t store_regs_in_min0(struct device *dev,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83627hf_data *data = i2c_get_clientdata(client);
+ u32 val;
+
+ val = simple_strtoul(buf, NULL, 10);
+ if ((data->vrm_ovt & 0x01) &&
+ (w83627thf == data->type || w83637hf == data->type))
+
+ /* use VRM9 calculation */
+ data->in_min[0] = (u8)(((val * 100) - 70000 + 244) / 488);
+ else
+ /* use VRM8 (standard) calculation */
+ data->in_min[0] = IN_TO_REG(val);
+
+ w83627hf_write_value(client, W83781D_REG_IN_MIN(0), data->in_min[0]);
+ return count;
+}
+
+static ssize_t store_regs_in_max0(struct device *dev,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83627hf_data *data = i2c_get_clientdata(client);
+ u32 val;
+
+ val = simple_strtoul(buf, NULL, 10);
+ if ((data->vrm_ovt & 0x01) &&
+ (w83627thf == data->type || w83637hf == data->type))
+
+ /* use VRM9 calculation */
+ data->in_max[0] = (u8)(((val * 100) - 70000 + 244) / 488);
+ else
+ /* use VRM8 (standard) calculation */
+ data->in_max[0] = IN_TO_REG(val);
+
+ w83627hf_write_value(client, W83781D_REG_IN_MAX(0), data->in_max[0]);
+ return count;
+}
+
+static DEVICE_ATTR(in0_input, S_IRUGO, show_regs_in_0, NULL);
+static DEVICE_ATTR(in0_min, S_IRUGO | S_IWUSR,
+ show_regs_in_min0, store_regs_in_min0);
+static DEVICE_ATTR(in0_max, S_IRUGO | S_IWUSR,
+ show_regs_in_max0, store_regs_in_max0);
#define device_create_file_in(client, offset) \
do { \
@@ -416,8 +499,8 @@ static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
FAN_FROM_REG(data->reg[nr-1], \
(long)DIV_FROM_REG(data->fan_div[nr-1]))); \
}
-show_fan_reg(fan)
-show_fan_reg(fan_min)
+show_fan_reg(fan);
+show_fan_reg(fan_min);
static ssize_t
store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
@@ -440,7 +523,7 @@ static ssize_t show_regs_fan_##offset (struct device *dev, char *buf) \
{ \
return show_fan(dev, buf, 0x##offset); \
} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL)
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL);
#define sysfs_fan_min_offset(offset) \
static ssize_t show_regs_fan_min##offset (struct device *dev, char *buf) \
@@ -453,14 +536,14 @@ store_regs_fan_min##offset (struct device *dev, const char *buf, size_t count) \
return store_fan_min(dev, buf, count, 0x##offset); \
} \
static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
- show_regs_fan_min##offset, store_regs_fan_min##offset)
+ show_regs_fan_min##offset, store_regs_fan_min##offset);
-sysfs_fan_offset(1)
-sysfs_fan_min_offset(1)
-sysfs_fan_offset(2)
-sysfs_fan_min_offset(2)
-sysfs_fan_offset(3)
-sysfs_fan_min_offset(3)
+sysfs_fan_offset(1);
+sysfs_fan_min_offset(1);
+sysfs_fan_offset(2);
+sysfs_fan_min_offset(2);
+sysfs_fan_offset(3);
+sysfs_fan_min_offset(3);
#define device_create_file_fan(client, offset) \
do { \
@@ -479,9 +562,9 @@ static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
return sprintf(buf,"%ld\n", (long)TEMP_FROM_REG(data->reg)); \
} \
}
-show_temp_reg(temp)
-show_temp_reg(temp_max)
-show_temp_reg(temp_max_hyst)
+show_temp_reg(temp);
+show_temp_reg(temp_max);
+show_temp_reg(temp_max_hyst);
#define store_temp_reg(REG, reg) \
static ssize_t \
@@ -505,8 +588,8 @@ store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \
\
return count; \
}
-store_temp_reg(OVER, max)
-store_temp_reg(HYST, max_hyst)
+store_temp_reg(OVER, max);
+store_temp_reg(HYST, max_hyst);
#define sysfs_temp_offset(offset) \
static ssize_t \
@@ -514,7 +597,7 @@ show_regs_temp_##offset (struct device *dev, char *buf) \
{ \
return show_temp(dev, buf, 0x##offset); \
} \
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL)
+static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL);
#define sysfs_temp_reg_offset(reg, offset) \
static ssize_t show_regs_temp_##reg##offset (struct device *dev, char *buf) \
@@ -528,16 +611,16 @@ store_regs_temp_##reg##offset (struct device *dev, \
return store_temp_##reg (dev, buf, count, 0x##offset); \
} \
static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, \
- show_regs_temp_##reg##offset, store_regs_temp_##reg##offset)
+ show_regs_temp_##reg##offset, store_regs_temp_##reg##offset);
#define sysfs_temp_offsets(offset) \
sysfs_temp_offset(offset) \
sysfs_temp_reg_offset(max, offset) \
sysfs_temp_reg_offset(max_hyst, offset)
-sysfs_temp_offsets(1)
-sysfs_temp_offsets(2)
-sysfs_temp_offsets(3)
+sysfs_temp_offsets(1);
+sysfs_temp_offsets(2);
+sysfs_temp_offsets(3);
#define device_create_file_temp(client, offset) \
do { \
@@ -552,7 +635,7 @@ show_vid_reg(struct device *dev, char *buf)
struct w83627hf_data *data = w83627hf_update_device(dev);
return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
}
-static DEVICE_ATTR(in0_ref, S_IRUGO, show_vid_reg, NULL)
+static DEVICE_ATTR(in0_ref, S_IRUGO, show_vid_reg, NULL);
#define device_create_file_vid(client) \
device_create_file(&client->dev, &dev_attr_in0_ref)
@@ -574,7 +657,7 @@ store_vrm_reg(struct device *dev, const char *buf, size_t count)
return count;
}
-static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg)
+static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
#define device_create_file_vrm(client) \
device_create_file(&client->dev, &dev_attr_vrm)
@@ -584,7 +667,7 @@ show_alarms_reg(struct device *dev, char *buf)
struct w83627hf_data *data = w83627hf_update_device(dev);
return sprintf(buf, "%ld\n", (long) data->alarms);
}
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL)
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
#define device_create_file_alarms(client) \
device_create_file(&client->dev, &dev_attr_alarms)
@@ -641,10 +724,10 @@ store_regs_beep_##reg (struct device *dev, const char *buf, size_t count) \
return store_beep_reg(dev, buf, count, BEEP_##REG); \
} \
static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, \
- show_regs_beep_##reg, store_regs_beep_##reg)
+ show_regs_beep_##reg, store_regs_beep_##reg);
-sysfs_beep(ENABLE, enable)
-sysfs_beep(MASK, mask)
+sysfs_beep(ENABLE, enable);
+sysfs_beep(MASK, mask);
#define device_create_file_beep(client) \
do { \
@@ -707,11 +790,11 @@ store_regs_fan_div_##offset (struct device *dev, \
return store_fan_div_reg(dev, buf, count, offset - 1); \
} \
static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
- show_regs_fan_div_##offset, store_regs_fan_div_##offset)
+ show_regs_fan_div_##offset, store_regs_fan_div_##offset);
-sysfs_fan_div(1)
-sysfs_fan_div(2)
-sysfs_fan_div(3)
+sysfs_fan_div(1);
+sysfs_fan_div(2);
+sysfs_fan_div(3);
#define device_create_file_fan_div(client, offset) \
do { \
@@ -763,11 +846,11 @@ store_regs_pwm_##offset (struct device *dev, const char *buf, size_t count) \
return store_pwm_reg(dev, buf, count, offset); \
} \
static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, \
- show_regs_pwm_##offset, store_regs_pwm_##offset)
+ show_regs_pwm_##offset, store_regs_pwm_##offset);
-sysfs_pwm(1)
-sysfs_pwm(2)
-sysfs_pwm(3)
+sysfs_pwm(1);
+sysfs_pwm(2);
+sysfs_pwm(3);
#define device_create_file_pwm(client, offset) \
do { \
@@ -836,11 +919,11 @@ store_regs_sensor_##offset (struct device *dev, const char *buf, size_t count) \
return store_sensor_reg(dev, buf, count, offset); \
} \
static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, \
- show_regs_sensor_##offset, store_regs_sensor_##offset)
+ show_regs_sensor_##offset, store_regs_sensor_##offset);
-sysfs_sensor(1)
-sysfs_sensor(2)
-sysfs_sensor(3)
+sysfs_sensor(1);
+sysfs_sensor(2);
+sysfs_sensor(3);
#define device_create_file_sensor(client, offset) \
do { \
@@ -1191,8 +1274,16 @@ static void w83627hf_init_client(struct i2c_client *client)
data->vid = w83627thf_read_gpio5(client) & 0x1f;
}
- /* Convert VID to voltage based on default VRM */
- data->vrm = DEFAULT_VRM;
+ /* Read VRM & OVT Config only once */
+ if (w83627thf == data->type || w83637hf == data->type) {
+ data->vrm_ovt =
+ w83627hf_read_value(client, W83627THF_REG_VRM_OVT_CFG);
+ data->vrm = (data->vrm_ovt & 0x01) ? 90 : 82;
+ } else {
+ /* Convert VID to voltage based on default VRM */
+ data->vrm = DEFAULT_VRM;
+ }
+
if (type != w83697hf)
vid = vid_from_reg(vid, data->vrm);
diff --git a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c
index ac378b54b1cd..df30ca18602a 100644
--- a/drivers/i2c/chips/w83781d.c
+++ b/drivers/i2c/chips/w83781d.c
@@ -320,7 +320,7 @@ show_regs_in_##offset (struct device *dev, char *buf) \
{ \
return show_in(dev, buf, 0x##offset); \
} \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL)
+static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL);
#define sysfs_in_reg_offset(reg, offset) \
static ssize_t show_regs_in_##reg##offset (struct device *dev, char *buf) \
@@ -331,7 +331,7 @@ static ssize_t store_regs_in_##reg##offset (struct device *dev, const char *buf,
{ \
return store_in_##reg (dev, buf, count, 0x##offset); \
} \
-static DEVICE_ATTR(in##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_in_##reg##offset, store_regs_in_##reg##offset)
+static DEVICE_ATTR(in##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_in_##reg##offset, store_regs_in_##reg##offset);
#define sysfs_in_offsets(offset) \
sysfs_in_offset(offset); \
@@ -386,7 +386,7 @@ static ssize_t show_regs_fan_##offset (struct device *dev, char *buf) \
{ \
return show_fan(dev, buf, 0x##offset); \
} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL)
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL);
#define sysfs_fan_min_offset(offset) \
static ssize_t show_regs_fan_min##offset (struct device *dev, char *buf) \
@@ -397,7 +397,7 @@ static ssize_t store_regs_fan_min##offset (struct device *dev, const char *buf,
{ \
return store_fan_min(dev, buf, count, 0x##offset); \
} \
-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, show_regs_fan_min##offset, store_regs_fan_min##offset)
+static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, show_regs_fan_min##offset, store_regs_fan_min##offset);
sysfs_fan_offset(1);
sysfs_fan_min_offset(1);
@@ -466,7 +466,7 @@ show_regs_temp_##offset (struct device *dev, char *buf) \
{ \
return show_temp(dev, buf, 0x##offset); \
} \
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL)
+static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL);
#define sysfs_temp_reg_offset(reg, offset) \
static ssize_t show_regs_temp_##reg##offset (struct device *dev, char *buf) \
@@ -477,7 +477,7 @@ static ssize_t store_regs_temp_##reg##offset (struct device *dev, const char *bu
{ \
return store_temp_##reg (dev, buf, count, 0x##offset); \
} \
-static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_temp_##reg##offset, store_regs_temp_##reg##offset)
+static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_temp_##reg##offset, store_regs_temp_##reg##offset);
#define sysfs_temp_offsets(offset) \
sysfs_temp_offset(offset); \
@@ -503,7 +503,7 @@ show_vid_reg(struct device *dev, char *buf)
}
static
-DEVICE_ATTR(in0_ref, S_IRUGO, show_vid_reg, NULL)
+DEVICE_ATTR(in0_ref, S_IRUGO, show_vid_reg, NULL);
#define device_create_file_vid(client) \
device_create_file(&client->dev, &dev_attr_in0_ref);
static ssize_t
@@ -527,7 +527,7 @@ store_vrm_reg(struct device *dev, const char *buf, size_t count)
}
static
-DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg)
+DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
#define device_create_file_vrm(client) \
device_create_file(&client->dev, &dev_attr_vrm);
static ssize_t
@@ -538,7 +538,7 @@ show_alarms_reg(struct device *dev, char *buf)
}
static
-DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL)
+DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
#define device_create_file_alarms(client) \
device_create_file(&client->dev, &dev_attr_alarms);
static ssize_t show_beep_mask (struct device *dev, char *buf)
@@ -598,7 +598,7 @@ static ssize_t store_regs_beep_##reg (struct device *dev, const char *buf, size_
{ \
return store_beep_reg(dev, buf, count, BEEP_##REG); \
} \
-static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, show_regs_beep_##reg, store_regs_beep_##reg)
+static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, show_regs_beep_##reg, store_regs_beep_##reg);
sysfs_beep(ENABLE, enable);
sysfs_beep(MASK, mask);
@@ -665,7 +665,7 @@ static ssize_t store_regs_fan_div_##offset (struct device *dev, const char *buf,
{ \
return store_fan_div_reg(dev, buf, count, offset - 1); \
} \
-static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, show_regs_fan_div_##offset, store_regs_fan_div_##offset)
+static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, show_regs_fan_div_##offset, store_regs_fan_div_##offset);
sysfs_fan_div(1);
sysfs_fan_div(2);
@@ -744,7 +744,7 @@ static ssize_t store_regs_pwm_##offset (struct device *dev, const char *buf, siz
{ \
return store_pwm_reg(dev, buf, count, offset); \
} \
-static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, show_regs_pwm_##offset, store_regs_pwm_##offset)
+static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, show_regs_pwm_##offset, store_regs_pwm_##offset);
#define sysfs_pwmenable(offset) \
static ssize_t show_regs_pwmenable_##offset (struct device *dev, char *buf) \
@@ -755,7 +755,7 @@ static ssize_t store_regs_pwmenable_##offset (struct device *dev, const char *bu
{ \
return store_pwmenable_reg(dev, buf, count, offset); \
} \
-static DEVICE_ATTR(fan##offset##_pwm_enable, S_IRUGO | S_IWUSR, show_regs_pwmenable_##offset, store_regs_pwmenable_##offset)
+static DEVICE_ATTR(fan##offset##_pwm_enable, S_IRUGO | S_IWUSR, show_regs_pwmenable_##offset, store_regs_pwmenable_##offset);
sysfs_pwm(1);
sysfs_pwm(2);
@@ -833,7 +833,7 @@ static ssize_t store_regs_sensor_##offset (struct device *dev, const char *buf,
{ \
return store_sensor_reg(dev, buf, count, offset); \
} \
-static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, show_regs_sensor_##offset, store_regs_sensor_##offset)
+static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, show_regs_sensor_##offset, store_regs_sensor_##offset);
sysfs_sensor(1);
sysfs_sensor(2);
@@ -891,7 +891,7 @@ static ssize_t store_regs_rt_##offset (struct device *dev, const char *buf, size
{ \
return store_rt_reg(dev, buf, count, offset); \
} \
-static DEVICE_ATTR(rt##offset, S_IRUGO | S_IWUSR, show_regs_rt_##offset, store_regs_rt_##offset)
+static DEVICE_ATTR(rt##offset, S_IRUGO | S_IWUSR, show_regs_rt_##offset, store_regs_rt_##offset);
sysfs_rt(1);
sysfs_rt(2);
diff --git a/drivers/i2c/chips/w83l785ts.c b/drivers/i2c/chips/w83l785ts.c
index 52118f9bf11f..58575861fc78 100644
--- a/drivers/i2c/chips/w83l785ts.c
+++ b/drivers/i2c/chips/w83l785ts.c
@@ -137,8 +137,8 @@ static ssize_t show_temp_over(struct device *dev, char *buf)
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over));
}
-static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL)
-static DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_over, NULL)
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL);
+static DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_over, NULL);
/*
* Real code
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index a0a4aa15aa97..4e5a3671d6e3 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -181,7 +181,7 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
struct i2c_smbus_ioctl_data data_arg;
union i2c_smbus_data temp;
struct i2c_msg *rdwr_pa;
- u8 **data_ptrs;
+ u8 __user **data_ptrs;
int i,datasize,res;
unsigned long funcs;
@@ -238,8 +238,7 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
return -EFAULT;
}
- data_ptrs = (u8 **) kmalloc(rdwr_arg.nmsgs * sizeof(u8 *),
- GFP_KERNEL);
+ data_ptrs = kmalloc(rdwr_arg.nmsgs * sizeof(u8 __user *), GFP_KERNEL);
if (data_ptrs == NULL) {
kfree(rdwr_pa);
return -ENOMEM;
@@ -252,7 +251,7 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
res = -EINVAL;
break;
}
- data_ptrs[i] = rdwr_pa[i].buf;
+ data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf;
rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL);
if(rdwr_pa[i].buf == NULL) {
res = -ENOMEM;
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 0dea6b1ddd52..9936879eb719 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -539,6 +539,7 @@ struct bus_type pci_bus_type = {
.hotplug = pci_hotplug,
.suspend = pci_device_suspend,
.resume = pci_device_resume,
+ .dev_attrs = pci_dev_attrs,
};
static int __init pci_driver_init(void)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 34161c9f88ff..120a441a88d6 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -23,14 +23,13 @@
/* show configuration fields */
#define pci_config_attr(field, format_string) \
static ssize_t \
-show_##field (struct device *dev, char *buf) \
+field##_show(struct device *dev, char *buf) \
{ \
struct pci_dev *pdev; \
\
pdev = to_pci_dev (dev); \
return sprintf (buf, format_string, pdev->field); \
-} \
-static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
+}
pci_config_attr(vendor, "0x%04x\n");
pci_config_attr(device, "0x%04x\n");
@@ -41,7 +40,7 @@ pci_config_attr(irq, "%u\n");
/* show resources */
static ssize_t
-pci_show_resources(struct device * dev, char * buf)
+resource_show(struct device * dev, char * buf)
{
struct pci_dev * pci_dev = to_pci_dev(dev);
char * str = buf;
@@ -60,7 +59,16 @@ pci_show_resources(struct device * dev, char * buf)
return (str - buf);
}
-static DEVICE_ATTR(resource,S_IRUGO,pci_show_resources,NULL);
+struct device_attribute pci_dev_attrs[] = {
+ __ATTR_RO(resource),
+ __ATTR_RO(vendor),
+ __ATTR_RO(device),
+ __ATTR_RO(subsystem_vendor),
+ __ATTR_RO(subsystem_device),
+ __ATTR_RO(class),
+ __ATTR_RO(irq),
+ __ATTR_NULL,
+};
static ssize_t
pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
@@ -180,21 +188,10 @@ static struct bin_attribute pcie_config_attr = {
void pci_create_sysfs_dev_files (struct pci_dev *pdev)
{
- struct device *dev = &pdev->dev;
-
- /* current configuration's attributes */
- device_create_file (dev, &dev_attr_vendor);
- device_create_file (dev, &dev_attr_device);
- device_create_file (dev, &dev_attr_subsystem_vendor);
- device_create_file (dev, &dev_attr_subsystem_device);
- device_create_file (dev, &dev_attr_class);
- device_create_file (dev, &dev_attr_irq);
- device_create_file (dev, &dev_attr_resource);
-
if (pdev->cfg_size < 4096)
- sysfs_create_bin_file(&dev->kobj, &pci_config_attr);
+ sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr);
else
- sysfs_create_bin_file(&dev->kobj, &pcie_config_attr);
+ sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);
/* add platform-specific attributes */
pcibios_add_platform_entries(pdev);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index e1985b618fc9..a9b243770580 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -62,3 +62,4 @@ extern int pci_visit_dev(struct pci_visit *fn,
extern spinlock_t pci_bus_lock;
extern int pciehp_msi_quirk;
+extern struct device_attribute pci_dev_attrs[];
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index d291d68cd1b0..f20e5a787e9f 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -1404,7 +1404,7 @@ static ssize_t sdebug_delay_store(struct device_driver * ddp,
return -EINVAL;
}
DRIVER_ATTR(delay, S_IRUGO | S_IWUSR, sdebug_delay_show,
- sdebug_delay_store)
+ sdebug_delay_store);
static ssize_t sdebug_opts_show(struct device_driver * ddp, char * buf)
{
@@ -1433,7 +1433,7 @@ opts_done:
return count;
}
DRIVER_ATTR(opts, S_IRUGO | S_IWUSR, sdebug_opts_show,
- sdebug_opts_store)
+ sdebug_opts_store);
static ssize_t sdebug_ptype_show(struct device_driver * ddp, char * buf)
{
@@ -1469,19 +1469,19 @@ static ssize_t sdebug_num_tgts_store(struct device_driver * ddp,
return -EINVAL;
}
DRIVER_ATTR(num_tgts, S_IRUGO | S_IWUSR, sdebug_num_tgts_show,
- sdebug_num_tgts_store)
+ sdebug_num_tgts_store);
static ssize_t sdebug_dev_size_mb_show(struct device_driver * ddp, char * buf)
{
return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_dev_size_mb);
}
-DRIVER_ATTR(dev_size_mb, S_IRUGO, sdebug_dev_size_mb_show, NULL)
+DRIVER_ATTR(dev_size_mb, S_IRUGO, sdebug_dev_size_mb_show, NULL);
static ssize_t sdebug_num_parts_show(struct device_driver * ddp, char * buf)
{
return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_num_parts);
}
-DRIVER_ATTR(num_parts, S_IRUGO, sdebug_num_parts_show, NULL)
+DRIVER_ATTR(num_parts, S_IRUGO, sdebug_num_parts_show, NULL);
static ssize_t sdebug_every_nth_show(struct device_driver * ddp, char * buf)
{
@@ -1500,7 +1500,7 @@ static ssize_t sdebug_every_nth_store(struct device_driver * ddp,
return -EINVAL;
}
DRIVER_ATTR(every_nth, S_IRUGO | S_IWUSR, sdebug_every_nth_show,
- sdebug_every_nth_store)
+ sdebug_every_nth_store);
static ssize_t sdebug_max_luns_show(struct device_driver * ddp, char * buf)
{
@@ -1519,13 +1519,13 @@ static ssize_t sdebug_max_luns_store(struct device_driver * ddp,
return -EINVAL;
}
DRIVER_ATTR(max_luns, S_IRUGO | S_IWUSR, sdebug_max_luns_show,
- sdebug_max_luns_store)
+ sdebug_max_luns_store);
static ssize_t sdebug_scsi_level_show(struct device_driver * ddp, char * buf)
{
return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_scsi_level);
}
-DRIVER_ATTR(scsi_level, S_IRUGO, sdebug_scsi_level_show, NULL)
+DRIVER_ATTR(scsi_level, S_IRUGO, sdebug_scsi_level_show, NULL);
static ssize_t sdebug_add_host_show(struct device_driver * ddp, char * buf)
{
@@ -1562,7 +1562,7 @@ static ssize_t sdebug_add_host_store(struct device_driver * ddp,
return count;
}
DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show,
- sdebug_add_host_store)
+ sdebug_add_host_store);
static void do_create_driverfs_files(void)
{
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index fceb6f9a1be1..a9ff002bb0a5 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -99,7 +99,7 @@ show_##name (struct class_device *class_dev, char *buf) \
*/
#define shost_rd_attr2(name, field, format_string) \
shost_show_function(name, field, format_string) \
-static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
+static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
#define shost_rd_attr(field, format_string) \
shost_rd_attr2(field, field, format_string)
@@ -228,8 +228,8 @@ sdev_show_##field (struct device *dev, char *buf) \
* read only field.
*/
#define sdev_rd_attr(field, format_string) \
- sdev_show_function(field, format_string) \
-static DEVICE_ATTR(field, S_IRUGO, sdev_show_##field, NULL)
+ sdev_show_function(field, format_string) \
+static DEVICE_ATTR(field, S_IRUGO, sdev_show_##field, NULL);
/*
@@ -247,7 +247,7 @@ sdev_store_##field (struct device *dev, const char *buf, size_t count) \
snscanf (buf, 20, format_string, &sdev->field); \
return count; \
} \
-static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, sdev_show_##field, sdev_store_##field)
+static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, sdev_show_##field, sdev_store_##field);
/* Currently we don't export bit fields, but we might in future,
* so leave this code in */
@@ -272,7 +272,7 @@ sdev_store_##field (struct device *dev, const char *buf, size_t count) \
} \
return ret; \
} \
-static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, sdev_show_##field, sdev_store_##field)
+static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, sdev_show_##field, sdev_store_##field);
/*
* scsi_sdev_check_buf_bit: return 0 if buf is "0", return 1 if buf is "1",
@@ -320,7 +320,7 @@ sdev_store_timeout (struct device *dev, const char *buf, size_t count)
sdev->timeout = timeout * HZ;
return count;
}
-static DEVICE_ATTR(timeout, S_IRUGO | S_IWUSR, sdev_show_timeout, sdev_store_timeout)
+static DEVICE_ATTR(timeout, S_IRUGO | S_IWUSR, sdev_show_timeout, sdev_store_timeout);
static ssize_t
store_rescan_field (struct device *dev, const char *buf, size_t count)
@@ -328,7 +328,7 @@ store_rescan_field (struct device *dev, const char *buf, size_t count)
scsi_rescan_device(dev);
return count;
}
-static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field)
+static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field);
static ssize_t sdev_store_delete(struct device *dev, const char *buf,
size_t count)
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index 3b30baff2000..9c41eefb9640 100644
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -152,7 +152,7 @@ store_spi_transport_##field(struct class_device *cdev, const char *buf, \
spi_transport_store_function(field, format_string) \
static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR, \
show_spi_transport_##field, \
- store_spi_transport_##field)
+ store_spi_transport_##field);
/* The Parallel SCSI Tranport Attributes: */
spi_transport_rd_attr(offset, "%d\n");
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index ac5c0b962ba9..d0030a4b151a 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -46,8 +46,13 @@ int sysfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *))
struct inode * inode = NULL;
if (dentry) {
if (!dentry->d_inode) {
- if ((inode = sysfs_new_inode(mode)))
+ if ((inode = sysfs_new_inode(mode))) {
+ if (dentry->d_parent && dentry->d_parent->d_inode) {
+ struct inode *p_inode = dentry->d_parent->d_inode;
+ p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME;
+ }
goto Proceed;
+ }
else
error = -ENOMEM;
} else
diff --git a/include/linux/device.h b/include/linux/device.h
index 2b8b3d636889..3f6e14c099e2 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -54,6 +54,9 @@ struct bus_type {
struct kset drivers;
struct kset devices;
+ struct bus_attribute * bus_attrs;
+ struct device_attribute * dev_attrs;
+
int (*match)(struct device * dev, struct device_driver * drv);
struct device * (*add) (struct device * parent, char * bus_id);
int (*hotplug) (struct device *dev, char **envp,
@@ -90,11 +93,7 @@ struct bus_attribute {
};
#define BUS_ATTR(_name,_mode,_show,_store) \
-struct bus_attribute bus_attr_##_name = { \
- .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
- .show = _show, \
- .store = _store, \
-};
+struct bus_attribute bus_attr_##_name = __ATTR(_name,_mode,_show,_store)
extern int bus_create_file(struct bus_type *, struct bus_attribute *);
extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
@@ -131,11 +130,7 @@ struct driver_attribute {
};
#define DRIVER_ATTR(_name,_mode,_show,_store) \
-struct driver_attribute driver_attr_##_name = { \
- .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
- .show = _show, \
- .store = _store, \
-};
+struct driver_attribute driver_attr_##_name = __ATTR(_name,_mode,_show,_store)
extern int driver_create_file(struct device_driver *, struct driver_attribute *);
extern void driver_remove_file(struct device_driver *, struct driver_attribute *);
@@ -151,6 +146,9 @@ struct class {
struct list_head children;
struct list_head interfaces;
+ struct class_attribute * class_attrs;
+ struct class_device_attribute * class_dev_attrs;
+
int (*hotplug)(struct class_device *dev, char **envp,
int num_envp, char *buffer, int buffer_size);
@@ -172,11 +170,7 @@ struct class_attribute {
};
#define CLASS_ATTR(_name,_mode,_show,_store) \
-struct class_attribute class_attr_##_name = { \
- .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
- .show = _show, \
- .store = _store, \
-};
+struct class_attribute class_attr_##_name = __ATTR(_name,_mode,_show,_store)
extern int class_create_file(struct class *, const struct class_attribute *);
extern void class_remove_file(struct class *, const struct class_attribute *);
@@ -224,11 +218,8 @@ struct class_device_attribute {
};
#define CLASS_DEVICE_ATTR(_name,_mode,_show,_store) \
-struct class_device_attribute class_device_attr_##_name = { \
- .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
- .show = _show, \
- .store = _store, \
-};
+struct class_device_attribute class_device_attr_##_name = \
+ __ATTR(_name,_mode,_show,_store)
extern int class_device_create_file(struct class_device *,
const struct class_device_attribute *);
@@ -342,11 +333,7 @@ struct device_attribute {
};
#define DEVICE_ATTR(_name,_mode,_show,_store) \
-struct device_attribute dev_attr_##_name = { \
- .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
- .show = _show, \
- .store = _store, \
-};
+struct device_attribute dev_attr_##_name = __ATTR(_name,_mode,_show,_store)
extern int device_create_file(struct device *device, struct device_attribute * entry);
@@ -390,6 +377,10 @@ extern void platform_device_unregister(struct platform_device *);
extern struct bus_type platform_bus_type;
extern struct device platform_bus;
+extern struct resource *platform_get_resource(struct platform_device *, unsigned int, unsigned int);
+extern int platform_get_irq(struct platform_device *, unsigned int);
+extern int platform_add_devices(struct platform_device **, int);
+
/* drivers/base/power.c */
extern void device_shutdown(void);
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
index 591e7ad68d30..520fe7220cd3 100644
--- a/include/linux/i2c-id.h
+++ b/include/linux/i2c-id.h
@@ -101,6 +101,14 @@
#define I2C_DRIVERID_UDA1342 53 /* UDA1342 audio codec */
#define I2C_DRIVERID_ADV7170 54 /* video encoder */
#define I2C_DRIVERID_RADEON 55 /* I2C bus on Radeon boards */
+#define I2C_DRIVERID_MAX1617 56 /* temp sensor */
+#define I2C_DRIVERID_SAA7191 57 /* video encoder */
+#define I2C_DRIVERID_INDYCAM 58 /* SGI IndyCam */
+#define I2C_DRIVERID_BT832 59 /* CMOS camera video processor */
+#define I2C_DRIVERID_TDA9887 60 /* TDA988x IF-PLL demodulator */
+#define I2C_DRIVERID_OVCAMCHIP 61 /* OmniVision CMOS image sens. */
+#define I2C_DRIVERID_TDA7313 62 /* TDA7313 audio processor */
+#define I2C_DRIVERID_MAX6900 63 /* MAX6900 real-time clock */
#define I2C_DRIVERID_EXP0 0xF0 /* experimental use id's */
@@ -264,6 +272,10 @@
#define I2C_HW_SMBUS_SCX200 0x0b
#define I2C_HW_SMBUS_NFORCE2 0x0c
#define I2C_HW_SMBUS_W9968CF 0x0d
+#define I2C_HW_SMBUS_OV511 0x0e /* OV511(+) USB 1.1 webcam ICs */
+#define I2C_HW_SMBUS_OV518 0x0f /* OV518(+) USB 1.1 webcam ICs */
+#define I2C_HW_SMBUS_OV519 0x10 /* OV519 USB 1.1 webcam IC */
+#define I2C_HW_SMBUS_OVFX2 0x11 /* Cypress/OmniVision FX2 webcam */
/* --- ISA pseudo-adapter */
#define I2C_HW_ISA 0x00
diff --git a/include/linux/module.h b/include/linux/module.h
index 2709330e8684..2ad187c3bda1 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -225,6 +225,22 @@ struct module_kobject
struct module_attribute attr[0];
};
+/* Similar stuff for section attributes. */
+#define MODULE_SECT_NAME_LEN 32
+struct module_sect_attr
+{
+ struct attribute attr;
+ char name[MODULE_SECT_NAME_LEN];
+ unsigned long address;
+};
+
+struct module_sections
+{
+ struct kobject kobj;
+ struct module_sect_attr attrs[0];
+};
+
+
struct module
{
enum module_state state;
@@ -298,6 +314,9 @@ struct module
Elf_Sym *symtab;
unsigned long num_symtab;
char *strtab;
+
+ /* Section attributes */
+ struct module_sections *sect_attrs;
#endif
/* Per-cpu data. */
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 4cb54379e85a..f94c7ac77c48 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -24,6 +24,27 @@ struct attribute_group {
};
+
+/**
+ * Use these macros to make defining attributes easier. See include/linux/device.h
+ * for examples..
+ */
+
+#define __ATTR(_name,_mode,_show,_store) { \
+ .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
+ .show = _show, \
+ .store = _store, \
+}
+
+#define __ATTR_RO(_name) { \
+ .attr = { .name = __stringify(_name), .mode = 0444, .owner = THIS_MODULE }, \
+ .show = _name##_show, \
+}
+
+#define __ATTR_NULL { .attr = { .name = NULL } }
+
+#define attr_name(_attr) (_attr).attr.name
+
struct bin_attribute {
struct attribute attr;
size_t size;
diff --git a/kernel/module.c b/kernel/module.c
index b96b1397422b..71a0944bddb1 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -980,6 +980,104 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
return ret;
}
+
+/*
+ * /sys/module/foo/sections stuff
+ * J. Corbet <corbet@lwn.net>
+ */
+#ifdef CONFIG_KALLSYMS
+static void module_sect_attrs_release(struct kobject *kobj)
+{
+ kfree(container_of(kobj, struct module_sections, kobj));
+}
+
+static ssize_t module_sect_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct module_sect_attr *sattr =
+ container_of(attr, struct module_sect_attr, attr);
+ return sprintf(buf, "0x%lx\n", sattr->address);
+}
+
+static struct sysfs_ops module_sect_ops = {
+ .show = module_sect_show,
+};
+
+static struct kobj_type module_sect_ktype = {
+ .sysfs_ops = &module_sect_ops,
+ .release = module_sect_attrs_release,
+};
+
+static void add_sect_attrs(struct module *mod, unsigned int nsect,
+ char *secstrings, Elf_Shdr *sechdrs)
+{
+ unsigned int nloaded = 0, i;
+ struct module_sect_attr *sattr;
+
+ if (!mod->mkobj)
+ return;
+
+ /* Count loaded sections and allocate structures */
+ for (i = 0; i < nsect; i++)
+ if (sechdrs[i].sh_flags & SHF_ALLOC)
+ nloaded++;
+ mod->sect_attrs = kmalloc(sizeof(struct module_sections) +
+ nloaded*sizeof(mod->sect_attrs->attrs[0]), GFP_KERNEL);
+ if (! mod->sect_attrs)
+ return;
+
+ /* sections entry setup */
+ memset(mod->sect_attrs, 0, sizeof(struct module_sections));
+ if (kobject_set_name(&mod->sect_attrs->kobj, "sections"))
+ goto out;
+ mod->sect_attrs->kobj.parent = &mod->mkobj->kobj;
+ mod->sect_attrs->kobj.ktype = &module_sect_ktype;
+ if (kobject_register(&mod->sect_attrs->kobj))
+ goto out;
+
+ /* And the section attributes. */
+ sattr = &mod->sect_attrs->attrs[0];
+ for (i = 0; i < nsect; i++) {
+ if (! (sechdrs[i].sh_flags & SHF_ALLOC))
+ continue;
+ sattr->address = sechdrs[i].sh_addr;
+ strlcpy(sattr->name, secstrings + sechdrs[i].sh_name,
+ MODULE_SECT_NAME_LEN);
+ sattr->attr.name = sattr->name;
+ sattr->attr.owner = mod;
+ sattr->attr.mode = S_IRUGO;
+ (void) sysfs_create_file(&mod->sect_attrs->kobj, &sattr->attr);
+ sattr++;
+ }
+ return;
+ out:
+ kfree(mod->sect_attrs);
+ mod->sect_attrs = NULL;
+}
+
+static void remove_sect_attrs(struct module *mod)
+{
+ if (mod->sect_attrs) {
+ kobject_unregister(&mod->sect_attrs->kobj);
+ mod->sect_attrs = NULL;
+ }
+}
+
+
+#else
+static inline void add_sect_attrs(struct module *mod, unsigned int nsect,
+ char *sectstrings, Elf_Shdr *sechdrs)
+{
+}
+
+static inline void remove_sect_attrs(struct module *mod)
+{
+}
+#endif /* CONFIG_KALLSYMS */
+
+
+
+
#define to_module_attr(n) container_of(n, struct module_attribute, attr);
static ssize_t module_attr_show(struct kobject *kobj,
@@ -1098,6 +1196,7 @@ static void free_module(struct module *mod)
list_del(&mod->list);
spin_unlock_irq(&modlist_lock);
+ remove_sect_attrs(mod);
mod_kobject_remove(mod);
/* Arch-specific cleanup. */
@@ -1711,6 +1810,7 @@ static struct module *load_module(void __user *umod,
/ sizeof(struct kernel_param));
if (err < 0)
goto arch_cleanup;
+ add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
/* Get rid of temporary copy */
vfree(hdr);