Commit 3e13e3b2 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/gregkh/linux/driver-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents d829cefd 6214d5da
...@@ -703,6 +703,12 @@ M: jrv@vanzandt.mv.com ...@@ -703,6 +703,12 @@ M: jrv@vanzandt.mv.com
L: blinux-list@redhat.com L: blinux-list@redhat.com
S: Maintained 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 DRM DRIVERS
L: dri-devel@lists.sourceforge.net L: dri-devel@lists.sourceforge.net
S: Supported S: Supported
......
...@@ -36,12 +36,17 @@ ...@@ -36,12 +36,17 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/device.h>
#include <linux/cpu.h>
#include <linux/notifier.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/msr.h> #include <asm/msr.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/system.h> #include <asm/system.h>
static struct class_simple *cpuid_class;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
struct cpuid_command { struct cpuid_command {
...@@ -153,20 +158,84 @@ static struct file_operations cpuid_fops = { ...@@ -153,20 +158,84 @@ static struct file_operations cpuid_fops = {
.open = cpuid_open, .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 __init cpuid_init(void)
{ {
int i, err = 0;
i = 0;
if (register_chrdev(CPUID_MAJOR, "cpu/cpuid", &cpuid_fops)) { if (register_chrdev(CPUID_MAJOR, "cpu/cpuid", &cpuid_fops)) {
printk(KERN_ERR "cpuid: unable to get major %d for cpuid\n", printk(KERN_ERR "cpuid: unable to get major %d for cpuid\n",
CPUID_MAJOR); 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) 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_chrdev(CPUID_MAJOR, "cpu/cpuid");
unregister_cpu_notifier(&cpuid_class_cpu_notifier);
} }
module_init(cpuid_init); module_init(cpuid_init);
......
...@@ -35,12 +35,17 @@ ...@@ -35,12 +35,17 @@
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/major.h> #include <linux/major.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/device.h>
#include <linux/cpu.h>
#include <linux/notifier.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/msr.h> #include <asm/msr.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/system.h> #include <asm/system.h>
static struct class_simple *msr_class;
/* Note: "err" is handled in a funny way below. Otherwise one version /* Note: "err" is handled in a funny way below. Otherwise one version
of gcc or another breaks. */ of gcc or another breaks. */
...@@ -255,20 +260,82 @@ static struct file_operations msr_fops = { ...@@ -255,20 +260,82 @@ static struct file_operations msr_fops = {
.open = msr_open, .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 __init msr_init(void)
{ {
int i, err = 0;
i = 0;
if (register_chrdev(MSR_MAJOR, "cpu/msr", &msr_fops)) { if (register_chrdev(MSR_MAJOR, "cpu/msr", &msr_fops)) {
printk(KERN_ERR "msr: unable to get major %d for msr\n", printk(KERN_ERR "msr: unable to get major %d for msr\n",
MSR_MAJOR); 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) 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_chrdev(MSR_MAJOR, "cpu/msr");
unregister_cpu_notifier(&msr_class_cpu_notifier);
} }
module_init(msr_init); module_init(msr_init);
......
...@@ -6,12 +6,13 @@ extern void bus_remove_driver(struct device_driver *); ...@@ -6,12 +6,13 @@ extern void bus_remove_driver(struct device_driver *);
static inline struct class_device *to_class_dev(struct kobject *obj) 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 static inline
struct class_device_attribute *to_class_dev_attr(struct attribute *_attr) 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);
} }
...@@ -17,17 +17,17 @@ ...@@ -17,17 +17,17 @@
#include "base.h" #include "base.h"
#include "power/power.h" #include "power/power.h"
#define to_dev(node) container_of(node,struct device,bus_list) #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_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_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(obj) container_of(obj, struct bus_type, subsys.kset.kobj)
/* /*
* sysfs bindings for drivers * 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) #define to_driver(obj) container_of(obj, struct device_driver, kobj)
...@@ -39,7 +39,7 @@ drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) ...@@ -39,7 +39,7 @@ drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
ssize_t ret = 0; ssize_t ret = 0;
if (drv_attr->show) if (drv_attr->show)
ret = drv_attr->show(drv,buf); ret = drv_attr->show(drv, buf);
return ret; return ret;
} }
...@@ -52,7 +52,7 @@ drv_attr_store(struct kobject * kobj, struct attribute * attr, ...@@ -52,7 +52,7 @@ drv_attr_store(struct kobject * kobj, struct attribute * attr,
ssize_t ret = 0; ssize_t ret = 0;
if (drv_attr->store) if (drv_attr->store)
ret = drv_attr->store(drv,buf,count); ret = drv_attr->store(drv, buf, count);
return ret; return ret;
} }
...@@ -87,7 +87,7 @@ bus_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) ...@@ -87,7 +87,7 @@ bus_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
ssize_t ret = 0; ssize_t ret = 0;
if (bus_attr->show) if (bus_attr->show)
ret = bus_attr->show(bus,buf); ret = bus_attr->show(bus, buf);
return ret; return ret;
} }
...@@ -100,7 +100,7 @@ bus_attr_store(struct kobject * kobj, struct attribute * attr, ...@@ -100,7 +100,7 @@ bus_attr_store(struct kobject * kobj, struct attribute * attr,
ssize_t ret = 0; ssize_t ret = 0;
if (bus_attr->store) if (bus_attr->store)
ret = bus_attr->store(bus,buf,count); ret = bus_attr->store(bus, buf, count);
return ret; return ret;
} }
...@@ -113,7 +113,7 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr) ...@@ -113,7 +113,7 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
{ {
int error; int error;
if (get_bus(bus)) { 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); put_bus(bus);
} else } else
error = -EINVAL; error = -EINVAL;
...@@ -123,7 +123,7 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr) ...@@ -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) void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr)
{ {
if (get_bus(bus)) { 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); put_bus(bus);
} }
} }
...@@ -133,7 +133,7 @@ static struct kobj_type ktype_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. * bus_for_each_dev - device iterator.
...@@ -170,7 +170,7 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start, ...@@ -170,7 +170,7 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start,
down_read(&bus->subsys.rwsem); down_read(&bus->subsys.rwsem);
list_for_each_entry_continue(dev, head, bus_list) { list_for_each_entry_continue(dev, head, bus_list) {
get_device(dev); get_device(dev);
error = fn(dev,data); error = fn(dev, data);
put_device(dev); put_device(dev);
if (error) if (error)
break; break;
...@@ -216,7 +216,7 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, ...@@ -216,7 +216,7 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
down_read(&bus->subsys.rwsem); down_read(&bus->subsys.rwsem);
list_for_each_entry_continue(drv, head, kobj.entry) { list_for_each_entry_continue(drv, head, kobj.entry) {
get_driver(drv); get_driver(drv);
error = fn(drv,data); error = fn(drv, data);
put_driver(drv); put_driver(drv);
if(error) if(error)
break; break;
...@@ -242,9 +242,9 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, ...@@ -242,9 +242,9 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
void device_bind_driver(struct device * dev) void device_bind_driver(struct device * dev)
{ {
pr_debug("bound device '%s' to driver '%s'\n", pr_debug("bound device '%s' to driver '%s'\n",
dev->bus_id,dev->driver->name); dev->bus_id, dev->driver->name);
list_add_tail(&dev->driver_list,&dev->driver->devices); list_add_tail(&dev->driver_list, &dev->driver->devices);
sysfs_create_link(&dev->driver->kobj,&dev->kobj, sysfs_create_link(&dev->driver->kobj, &dev->kobj,
kobject_name(&dev->kobj)); kobject_name(&dev->kobj));
} }
...@@ -266,7 +266,7 @@ void device_bind_driver(struct device * dev) ...@@ -266,7 +266,7 @@ void device_bind_driver(struct device * dev)
static int bus_match(struct device * dev, struct device_driver * drv) static int bus_match(struct device * dev, struct device_driver * drv)
{ {
int error = -ENODEV; int error = -ENODEV;
if (dev->bus->match(dev,drv)) { if (dev->bus->match(dev, drv)) {
dev->driver = drv; dev->driver = drv;
if (drv->probe) { if (drv->probe) {
if ((error = drv->probe(dev))) { if ((error = drv->probe(dev))) {
...@@ -300,10 +300,10 @@ static int device_attach(struct device * dev) ...@@ -300,10 +300,10 @@ static int device_attach(struct device * dev)
} }
if (bus->match) { if (bus->match) {
list_for_each(entry,&bus->drivers.list) { list_for_each(entry, &bus->drivers.list) {
struct device_driver * drv = to_drv(entry); struct device_driver * drv = to_drv(entry);
error = bus_match(dev,drv); error = bus_match(dev, drv);
if (!error ) if (!error)
/* success, driver matched */ /* success, driver matched */
return 1; return 1;
if (error != -ENODEV) if (error != -ENODEV)
...@@ -339,10 +339,10 @@ void driver_attach(struct device_driver * drv) ...@@ -339,10 +339,10 @@ void driver_attach(struct device_driver * drv)
if (!bus->match) if (!bus->match)
return; return;
list_for_each(entry,&bus->devices.list) { list_for_each(entry, &bus->devices.list) {
struct device * dev = container_of(entry,struct device,bus_list); struct device * dev = container_of(entry, struct device, bus_list);
if (!dev->driver) { if (!dev->driver) {
error = bus_match(dev,drv); error = bus_match(dev, drv);
if (error && (error != -ENODEV)) if (error && (error != -ENODEV))
/* driver matched but the probe failed */ /* driver matched but the probe failed */
printk(KERN_WARNING printk(KERN_WARNING
...@@ -367,7 +367,7 @@ void device_release_driver(struct device * dev) ...@@ -367,7 +367,7 @@ void device_release_driver(struct device * dev)
{ {
struct device_driver * drv = dev->driver; struct device_driver * drv = dev->driver;
if (drv) { 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); list_del_init(&dev->driver_list);
device_detach_shutdown(dev); device_detach_shutdown(dev);
if (drv->remove) if (drv->remove)
...@@ -385,13 +385,44 @@ void device_release_driver(struct device * dev) ...@@ -385,13 +385,44 @@ void device_release_driver(struct device * dev)
static void driver_detach(struct device_driver * drv) static void driver_detach(struct device_driver * drv)
{ {
struct list_head * entry, * next; struct list_head * entry, * next;
list_for_each_safe(entry,next,&drv->devices) { list_for_each_safe(entry, next, &drv->devices) {
struct device * dev = container_of(entry,struct device,driver_list); struct device * dev = container_of(entry, struct device, driver_list);
device_release_driver(dev); 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 * bus_add_device - add device to bus
* @dev: device being added * @dev: device being added
...@@ -407,11 +438,12 @@ int bus_add_device(struct device * dev) ...@@ -407,11 +438,12 @@ int bus_add_device(struct device * dev)
if (bus) { if (bus) {
down_write(&dev->bus->subsys.rwsem); down_write(&dev->bus->subsys.rwsem);
pr_debug("bus %s: add device %s\n",bus->name,dev->bus_id); pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id);
list_add_tail(&dev->bus_list,&dev->bus->devices.list); list_add_tail(&dev->bus_list, &dev->bus->devices.list);
device_attach(dev); device_attach(dev);
up_write(&dev->bus->subsys.rwsem); 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; return error;
} }
...@@ -428,9 +460,10 @@ int bus_add_device(struct device * dev) ...@@ -428,9 +460,10 @@ int bus_add_device(struct device * dev)
void bus_remove_device(struct device * dev) void bus_remove_device(struct device * dev)
{ {
if (dev->bus) { 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); 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); device_release_driver(dev);
list_del_init(&dev->bus_list); list_del_init(&dev->bus_list);
up_write(&dev->bus->subsys.rwsem); up_write(&dev->bus->subsys.rwsem);
...@@ -450,8 +483,8 @@ int bus_add_driver(struct device_driver * drv) ...@@ -450,8 +483,8 @@ int bus_add_driver(struct device_driver * drv)
int error = 0; int error = 0;
if (bus) { if (bus) {
pr_debug("bus %s: add driver %s\n",bus->name,drv->name); pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
error = kobject_set_name(&drv->kobj,drv->name); error = kobject_set_name(&drv->kobj, drv->name);
if (error) { if (error) {
put_bus(bus); put_bus(bus);
return error; return error;
...@@ -484,7 +517,7 @@ void bus_remove_driver(struct device_driver * drv) ...@@ -484,7 +517,7 @@ void bus_remove_driver(struct device_driver * drv)
{ {
if (drv->bus) { if (drv->bus) {
down_write(&drv->bus->subsys.rwsem); 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); driver_detach(drv);
up_write(&drv->bus->subsys.rwsem); up_write(&drv->bus->subsys.rwsem);
kobject_unregister(&drv->kobj); kobject_unregister(&drv->kobj);
...@@ -526,7 +559,7 @@ int bus_rescan_devices(struct bus_type * bus) ...@@ -526,7 +559,7 @@ int bus_rescan_devices(struct bus_type * bus)
struct bus_type * get_bus(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) void put_bus(struct bus_type * bus)
...@@ -545,10 +578,45 @@ void put_bus(struct bus_type * bus) ...@@ -545,10 +578,45 @@ void put_bus(struct bus_type * bus)
struct bus_type * find_bus(char * name) 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; 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_register - register a bus with the system.
* @bus: bus. * @bus: bus.
...@@ -561,11 +629,11 @@ int bus_register(struct bus_type * bus) ...@@ -561,11 +629,11 @@ int bus_register(struct bus_type * bus)
{ {
int retval; int retval;
retval = kobject_set_name(&bus->subsys.kset.kobj,bus->name); retval = kobject_set_name(&bus->subsys.kset.kobj, bus->name);
if (retval) if (retval)
goto out; goto out;
subsys_set_kset(bus,bus_subsys); subsys_set_kset(bus, bus_subsys);
retval = subsystem_register(&bus->subsys); retval = subsystem_register(&bus->subsys);
if (retval) if (retval)
goto out; goto out;
...@@ -582,8 +650,9 @@ int bus_register(struct bus_type * bus) ...@@ -582,8 +650,9 @@ int bus_register(struct bus_type * bus)
retval = kset_register(&bus->drivers); retval = kset_register(&bus->drivers);
if (retval) if (retval)
goto bus_drivers_fail; 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; return 0;
bus_drivers_fail: bus_drivers_fail:
...@@ -604,7 +673,8 @@ int bus_register(struct bus_type * bus) ...@@ -604,7 +673,8 @@ int bus_register(struct bus_type * bus)
*/ */
void bus_unregister(struct bus_type * bus) 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->drivers);
kset_unregister(&bus->devices); kset_unregister(&bus->devices);
subsystem_unregister(&bus->subsys); subsystem_unregister(&bus->subsys);
......
...@@ -17,8 +17,8 @@ ...@@ -17,8 +17,8 @@
#include <linux/string.h> #include <linux/string.h>
#include "base.h" #include "base.h"
#define to_class_attr(_attr) container_of(_attr,struct class_attribute,attr) #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(obj) container_of(obj, struct class, subsys.kset.kobj)
static ssize_t static ssize_t
class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
...@@ -28,7 +28,7 @@ class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) ...@@ -28,7 +28,7 @@ class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
ssize_t ret = 0; ssize_t ret = 0;
if (class_attr->show) if (class_attr->show)
ret = class_attr->show(dc,buf); ret = class_attr->show(dc, buf);
return ret; return ret;
} }
...@@ -41,7 +41,7 @@ class_attr_store(struct kobject * kobj, struct attribute * attr, ...@@ -41,7 +41,7 @@ class_attr_store(struct kobject * kobj, struct attribute * attr,
ssize_t ret = 0; ssize_t ret = 0;
if (class_attr->store) if (class_attr->store)
ret = class_attr->store(dc,buf,count); ret = class_attr->store(dc, buf, count);
return ret; return ret;
} }
...@@ -69,14 +69,14 @@ static struct kobj_type ktype_class = { ...@@ -69,14 +69,14 @@ static struct kobj_type ktype_class = {
}; };
/* Hotplug events for classes go to the class_obj subsys */ /* 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 class_create_file(struct class * cls, const struct class_attribute * attr)
{ {
int error; int error;
if (cls) { if (cls) {
error = sysfs_create_file(&cls->subsys.kset.kobj,&attr->attr); error = sysfs_create_file(&cls->subsys.kset.kobj, &attr->attr);
} else } else
error = -EINVAL; error = -EINVAL;
return error; return error;
...@@ -85,13 +85,13 @@ int class_create_file(struct class * cls, const struct class_attribute * attr) ...@@ -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) void class_remove_file(struct class * cls, const struct class_attribute * attr)
{ {
if (cls) 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) struct class * class_get(struct class * cls)
{ {
if (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; return NULL;
} }
...@@ -100,33 +100,67 @@ void class_put(struct class * cls) ...@@ -100,33 +100,67 @@ void class_put(struct class * cls)
subsys_put(&cls->subsys); 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 class_register(struct class * cls)
{ {
int error; 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->children);
INIT_LIST_HEAD(&cls->interfaces); 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) if (error)
return error; return error;
subsys_set_kset(cls,class_subsys); subsys_set_kset(cls, class_subsys);
error = subsystem_register(&cls->subsys); error = subsystem_register(&cls->subsys);
if (error) if (!error) {
error = add_class_attrs(class_get(cls));
class_put(cls);
}
return error; return error;
return 0;
} }
void class_unregister(struct class * cls) 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); subsystem_unregister(&cls->subsys);
} }
/* Class Device Stuff */ /* Class Device Stuff */
int class_device_create_file(struct class_device * class_dev, int class_device_create_file(struct class_device * class_dev,
...@@ -181,7 +215,7 @@ class_device_attr_show(struct kobject * kobj, struct attribute * attr, ...@@ -181,7 +215,7 @@ class_device_attr_show(struct kobject * kobj, struct attribute * attr,
ssize_t ret = 0; ssize_t ret = 0;
if (class_dev_attr->show) if (class_dev_attr->show)
ret = class_dev_attr->show(cd,buf); ret = class_dev_attr->show(cd, buf);
return ret; return ret;
} }
...@@ -194,7 +228,7 @@ class_device_attr_store(struct kobject * kobj, struct attribute * attr, ...@@ -194,7 +228,7 @@ class_device_attr_store(struct kobject * kobj, struct attribute * attr,
ssize_t ret = 0; ssize_t ret = 0;
if (class_dev_attr->store) if (class_dev_attr->store)
ret = class_dev_attr->store(cd,buf,count); ret = class_dev_attr->store(cd, buf, count);
return ret; return ret;
} }
...@@ -208,7 +242,7 @@ static void class_dev_release(struct kobject * kobj) ...@@ -208,7 +242,7 @@ static void class_dev_release(struct kobject * kobj)
struct class_device *cd = to_class_dev(kobj); struct class_device *cd = to_class_dev(kobj);
struct class * cls = cd->class; 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) if (cls->release)
cls->release(cd); cls->release(cd);
...@@ -272,6 +306,40 @@ static struct kset_hotplug_ops class_hotplug_ops = { ...@@ -272,6 +306,40 @@ static struct kset_hotplug_ops class_hotplug_ops = {
static decl_subsys(class_obj, &ktype_class_device, &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) void class_device_initialize(struct class_device *class_dev)
{ {
kobj_set_kset_s(class_dev, class_obj_subsys); kobj_set_kset_s(class_dev, class_obj_subsys);
...@@ -311,7 +379,7 @@ int class_device_add(struct class_device *class_dev) ...@@ -311,7 +379,7 @@ int class_device_add(struct class_device *class_dev)
class_intf->add(class_dev); class_intf->add(class_dev);
up_write(&parent->subsys.rwsem); up_write(&parent->subsys.rwsem);
} }
class_device_add_attrs(class_dev);
class_device_dev_link(class_dev); class_device_dev_link(class_dev);
class_device_driver_link(class_dev); class_device_driver_link(class_dev);
...@@ -344,6 +412,7 @@ void class_device_del(struct class_device *class_dev) ...@@ -344,6 +412,7 @@ void class_device_del(struct class_device *class_dev)
class_device_dev_unlink(class_dev); class_device_dev_unlink(class_dev);
class_device_driver_unlink(class_dev); class_device_driver_unlink(class_dev);
class_device_remove_attrs(class_dev);
kobject_del(&class_dev->kobj); kobject_del(&class_dev->kobj);
......
...@@ -147,7 +147,7 @@ struct class_device *class_simple_device_add(struct class_simple *cs, dev_t dev, ...@@ -147,7 +147,7 @@ struct class_device *class_simple_device_add(struct class_simple *cs, dev_t dev,
s_dev->class_dev.dev = device; s_dev->class_dev.dev = device;
s_dev->class_dev.class = &cs->class; 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); vsnprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, fmt, args);
va_end(args); va_end(args);
retval = class_device_register(&s_dev->class_dev); retval = class_device_register(&s_dev->class_dev);
......
...@@ -28,8 +28,8 @@ int (*platform_notify_remove)(struct device * dev) = NULL; ...@@ -28,8 +28,8 @@ int (*platform_notify_remove)(struct device * dev) = NULL;
* sysfs bindings for devices. * sysfs bindings for devices.
*/ */
#define to_dev(obj) container_of(obj,struct device,kobj) #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_attr(_attr) container_of(_attr, struct device_attribute, attr)
extern struct attribute * dev_default_attrs[]; extern struct attribute * dev_default_attrs[];
...@@ -41,7 +41,7 @@ dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) ...@@ -41,7 +41,7 @@ dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
ssize_t ret = 0; ssize_t ret = 0;
if (dev_attr->show) if (dev_attr->show)
ret = dev_attr->show(dev,buf); ret = dev_attr->show(dev, buf);
return ret; return ret;
} }
...@@ -54,7 +54,7 @@ dev_attr_store(struct kobject * kobj, struct attribute * attr, ...@@ -54,7 +54,7 @@ dev_attr_store(struct kobject * kobj, struct attribute * attr,
ssize_t ret = 0; ssize_t ret = 0;
if (dev_attr->store) if (dev_attr->store)
ret = dev_attr->store(dev,buf,count); ret = dev_attr->store(dev, buf, count);
return ret; return ret;
} }
...@@ -153,7 +153,7 @@ int device_create_file(struct device * dev, struct device_attribute * attr) ...@@ -153,7 +153,7 @@ int device_create_file(struct device * dev, struct device_attribute * attr)
{ {
int error = 0; int error = 0;
if (get_device(dev)) { if (get_device(dev)) {
error = sysfs_create_file(&dev->kobj,&attr->attr); error = sysfs_create_file(&dev->kobj, &attr->attr);
put_device(dev); put_device(dev);
} }
return error; return error;
...@@ -168,7 +168,7 @@ int device_create_file(struct device * dev, struct device_attribute * attr) ...@@ -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) void device_remove_file(struct device * dev, struct device_attribute * attr)
{ {
if (get_device(dev)) { if (get_device(dev)) {
sysfs_remove_file(&dev->kobj,&attr->attr); sysfs_remove_file(&dev->kobj, &attr->attr);
put_device(dev); put_device(dev);
} }
} }
...@@ -187,7 +187,7 @@ void device_remove_file(struct device * dev, struct device_attribute * attr) ...@@ -187,7 +187,7 @@ void device_remove_file(struct device * dev, struct device_attribute * attr)
void device_initialize(struct device *dev) void device_initialize(struct device *dev)
{ {
kobj_set_kset_s(dev,devices_subsys); kobj_set_kset_s(dev, devices_subsys);
kobject_init(&dev->kobj); kobject_init(&dev->kobj);
INIT_LIST_HEAD(&dev->node); INIT_LIST_HEAD(&dev->node);
INIT_LIST_HEAD(&dev->children); INIT_LIST_HEAD(&dev->children);
...@@ -221,7 +221,7 @@ int device_add(struct device *dev) ...@@ -221,7 +221,7 @@ int device_add(struct device *dev)
pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id); pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id);
/* first, register with generic layer. */ /* first, register with generic layer. */
kobject_set_name(&dev->kobj,dev->bus_id); kobject_set_name(&dev->kobj, dev->bus_id);
if (parent) if (parent)
dev->kobj.parent = &parent->kobj; dev->kobj.parent = &parent->kobj;
...@@ -233,7 +233,7 @@ int device_add(struct device *dev) ...@@ -233,7 +233,7 @@ int device_add(struct device *dev)
goto BusError; goto BusError;
down_write(&devices_subsys.rwsem); down_write(&devices_subsys.rwsem);
if (parent) if (parent)
list_add_tail(&dev->node,&parent->children); list_add_tail(&dev->node, &parent->children);
up_write(&devices_subsys.rwsem); up_write(&devices_subsys.rwsem);
/* notify platform of device entry */ /* notify platform of device entry */
...@@ -245,7 +245,7 @@ int device_add(struct device *dev) ...@@ -245,7 +245,7 @@ int device_add(struct device *dev)
BusError: BusError:
device_pm_remove(dev); device_pm_remove(dev);
PMError: PMError:
kobject_unregister(&dev->kobj); kobject_del(&dev->kobj);
Error: Error:
if (parent) if (parent)
put_device(parent); put_device(parent);
...@@ -370,8 +370,8 @@ int device_for_each_child(struct device * dev, void * data, ...@@ -370,8 +370,8 @@ int device_for_each_child(struct device * dev, void * data,
int error = 0; int error = 0;
down_read(&devices_subsys.rwsem); down_read(&devices_subsys.rwsem);
list_for_each_entry(child,&dev->children,node) { list_for_each_entry(child, &dev->children, node) {
if((error = fn(child,data))) if((error = fn(child, data)))
break; break;
} }
up_read(&devices_subsys.rwsem); up_read(&devices_subsys.rwsem);
......
...@@ -15,8 +15,8 @@ ...@@ -15,8 +15,8 @@
#include <linux/string.h> #include <linux/string.h>
#include "base.h" #include "base.h"
#define to_dev(node) container_of(node,struct device,driver_list) #define to_dev(node) container_of(node, struct device, driver_list)
#define to_drv(obj) container_of(obj,struct device_driver,kobj) #define to_drv(obj) container_of(obj, struct device_driver, kobj)
/** /**
* driver_create_file - create sysfs file for driver. * driver_create_file - create sysfs file for driver.
...@@ -28,7 +28,7 @@ int driver_create_file(struct device_driver * drv, struct driver_attribute * att ...@@ -28,7 +28,7 @@ int driver_create_file(struct device_driver * drv, struct driver_attribute * att
{ {
int error; int error;
if (get_driver(drv)) { if (get_driver(drv)) {
error = sysfs_create_file(&drv->kobj,&attr->attr); error = sysfs_create_file(&drv->kobj, &attr->attr);
put_driver(drv); put_driver(drv);
} else } else
error = -EINVAL; error = -EINVAL;
...@@ -45,7 +45,7 @@ int driver_create_file(struct device_driver * drv, struct driver_attribute * att ...@@ -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) void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr)
{ {
if (get_driver(drv)) { if (get_driver(drv)) {
sysfs_remove_file(&drv->kobj,&attr->attr); sysfs_remove_file(&drv->kobj, &attr->attr);
put_driver(drv); put_driver(drv);
} }
} }
......
...@@ -12,11 +12,11 @@ ...@@ -12,11 +12,11 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
static decl_subsys(firmware,NULL,NULL); static decl_subsys(firmware, NULL, NULL);
int firmware_register(struct subsystem * s) int firmware_register(struct subsystem * s)
{ {
kset_set_kset_s(s,firmware_subsys); kset_set_kset_s(s, firmware_subsys);
return subsystem_register(s); return subsystem_register(s);
} }
......
...@@ -29,20 +29,20 @@ ...@@ -29,20 +29,20 @@
static ssize_t detach_show(struct device * dev, char * buf) 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) static ssize_t detach_store(struct device * dev, const char * buf, size_t n)
{ {
u32 state; u32 state;
state = simple_strtoul(buf,NULL,10); state = simple_strtoul(buf, NULL, 10);
if (state > 4) if (state > 4)
return -EINVAL; return -EINVAL;
dev->detach_state = state; dev->detach_state = state;
return n; 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[] = { struct attribute * dev_default_attrs[] = {
......
...@@ -29,7 +29,7 @@ static ssize_t node_read_cpumap(struct sys_device * dev, char * buf) ...@@ -29,7 +29,7 @@ static ssize_t node_read_cpumap(struct sys_device * dev, char * buf)
return len; 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. */ /* Can be overwritten by architecture specific code. */
int __attribute__((weak)) hugetlb_report_node_meminfo(int node, char *buf) 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) ...@@ -54,17 +54,17 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf)
"Node %d LowFree: %8lu kB\n", "Node %d LowFree: %8lu kB\n",
nid, K(i.totalram), nid, K(i.totalram),
nid, K(i.freeram), nid, K(i.freeram),
nid, K(i.totalram-i.freeram), nid, K(i.totalram - i.freeram),
nid, K(i.totalhigh), nid, K(i.totalhigh),
nid, K(i.freehigh), nid, K(i.freehigh),
nid, K(i.totalram-i.totalhigh), nid, K(i.totalram - i.totalhigh),
nid, K(i.freeram-i.freehigh)); nid, K(i.freeram - i.freehigh));
n += hugetlb_report_node_meminfo(nid, buf + n); n += hugetlb_report_node_meminfo(nid, buf + n);
return n; return n;
} }
#undef K #undef K
static SYSDEV_ATTR(meminfo,S_IRUGO,node_read_meminfo,NULL); static SYSDEV_ATTR(meminfo, S_IRUGO, node_read_meminfo, NULL);
static ssize_t node_read_numastat(struct sys_device * dev, char * buf) 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) ...@@ -104,7 +104,7 @@ static ssize_t node_read_numastat(struct sys_device * dev, char * buf)
local_node, local_node,
other_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. * register_node - Setup a driverfs device for a node.
......
...@@ -18,6 +18,63 @@ struct device platform_bus = { ...@@ -18,6 +18,63 @@ struct device platform_bus = {
.bus_id = "platform", .bus_id = "platform",
}; };
/**
* 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 * platform_device_register - add a platform-level device
* @dev: platform device we're adding * @dev: platform device we're adding
...@@ -25,6 +82,8 @@ struct device platform_bus = { ...@@ -25,6 +82,8 @@ struct device platform_bus = {
*/ */
int platform_device_register(struct platform_device * pdev) int platform_device_register(struct platform_device * pdev)
{ {
int i, ret = 0;
if (!pdev) if (!pdev)
return -EINVAL; return -EINVAL;
...@@ -33,17 +92,58 @@ int platform_device_register(struct platform_device * pdev) ...@@ -33,17 +92,58 @@ int platform_device_register(struct platform_device * pdev)
pdev->dev.bus = &platform_bus_type; 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", pr_debug("Registering platform device '%s'. Parent at %s\n",
pdev->dev.bus_id,pdev->dev.parent->bus_id); pdev->dev.bus_id, pdev->dev.parent->bus_id);
return device_register(&pdev->dev);
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) void platform_device_unregister(struct platform_device * pdev)
{ {
if (pdev) int i;
if (pdev) {
device_unregister(&pdev->dev); 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);
}
}
} }
...@@ -114,3 +214,5 @@ EXPORT_SYMBOL(platform_bus); ...@@ -114,3 +214,5 @@ EXPORT_SYMBOL(platform_bus);
EXPORT_SYMBOL(platform_bus_type); EXPORT_SYMBOL(platform_bus_type);
EXPORT_SYMBOL(platform_device_register); EXPORT_SYMBOL(platform_device_register);
EXPORT_SYMBOL(platform_device_unregister); EXPORT_SYMBOL(platform_device_unregister);
EXPORT_SYMBOL(platform_get_irq);
EXPORT_SYMBOL(platform_get_resource);
...@@ -74,10 +74,10 @@ int device_pm_add(struct device * dev) ...@@ -74,10 +74,10 @@ int device_pm_add(struct device * dev)
pr_debug("PM: Adding info for %s:%s\n", pr_debug("PM: Adding info for %s:%s\n",
dev->bus ? dev->bus->name : "No Bus", dev->kobj.name); 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); down(&dpm_sem);
list_add_tail(&dev->power.entry,&dpm_active); list_add_tail(&dev->power.entry, &dpm_active);
device_pm_set_parent(dev,dev->parent); device_pm_set_parent(dev, dev->parent);
if ((error = dpm_sysfs_add(dev))) if ((error = dpm_sysfs_add(dev)))
list_del(&dev->power.entry); list_del(&dev->power.entry);
up(&dpm_sem); up(&dpm_sem);
......
...@@ -37,12 +37,12 @@ extern struct list_head dpm_off_irq; ...@@ -37,12 +37,12 @@ extern struct list_head dpm_off_irq;
static inline struct dev_pm_info * to_pm_info(struct list_head * entry) 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) 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 *); extern int device_pm_add(struct device *);
......
...@@ -39,7 +39,7 @@ void dpm_resume(void) ...@@ -39,7 +39,7 @@ void dpm_resume(void)
if (!dev->power.prev_state) if (!dev->power.prev_state)
resume_device(dev); resume_device(dev);
list_add_tail(entry,&dpm_active); list_add_tail(entry, &dpm_active);
} }
} }
...@@ -78,7 +78,7 @@ void dpm_power_up(void) ...@@ -78,7 +78,7 @@ void dpm_power_up(void)
struct list_head * entry = dpm_off_irq.next; struct list_head * entry = dpm_off_irq.next;
list_del_init(entry); list_del_init(entry);
resume_device(to_device(entry)); resume_device(to_device(entry));
list_add_tail(entry,&dpm_active); list_add_tail(entry, &dpm_active);
} }
} }
......
...@@ -55,7 +55,7 @@ int dpm_runtime_suspend(struct device * dev, u32 state) ...@@ -55,7 +55,7 @@ int dpm_runtime_suspend(struct device * dev, u32 state)
if (dev->power.power_state) if (dev->power.power_state)
runtime_resume(dev); runtime_resume(dev);
if (!(error = suspend_device(dev,state))) if (!(error = suspend_device(dev, state)))
dev->power.power_state = state; dev->power.power_state = state;
Done: Done:
up(&dpm_sem); up(&dpm_sem);
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include "power.h" #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; extern struct subsystem devices_subsys;
...@@ -29,7 +29,7 @@ int device_detach_shutdown(struct device * dev) ...@@ -29,7 +29,7 @@ int device_detach_shutdown(struct device * dev)
dev->driver->shutdown(dev); dev->driver->shutdown(dev);
return 0; return 0;
} }
return dpm_runtime_suspend(dev,dev->detach_state); return dpm_runtime_suspend(dev, dev->detach_state);
} }
...@@ -52,8 +52,8 @@ void device_shutdown(void) ...@@ -52,8 +52,8 @@ void device_shutdown(void)
struct device * dev; struct device * dev;
down_write(&devices_subsys.rwsem); down_write(&devices_subsys.rwsem);
list_for_each_entry_reverse(dev,&devices_subsys.kset.list,kobj.entry) { list_for_each_entry_reverse(dev, &devices_subsys.kset.list, kobj.entry) {
pr_debug("shutting down %s: ",dev->bus_id); pr_debug("shutting down %s: ", dev->bus_id);
if (dev->driver && dev->driver->shutdown) { if (dev->driver && dev->driver->shutdown) {
pr_debug("Ok\n"); pr_debug("Ok\n");
dev->driver->shutdown(dev); dev->driver->shutdown(dev);
......
...@@ -44,7 +44,7 @@ int suspend_device(struct device * dev, u32 state) ...@@ -44,7 +44,7 @@ int suspend_device(struct device * dev, u32 state)
dev->power.prev_state = dev->power.power_state; dev->power.prev_state = dev->power.power_state;
if (dev->bus && dev->bus->suspend && !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; return error;
} }
...@@ -78,14 +78,14 @@ int device_suspend(u32 state) ...@@ -78,14 +78,14 @@ int device_suspend(u32 state)
while(!list_empty(&dpm_active)) { while(!list_empty(&dpm_active)) {
struct list_head * entry = dpm_active.prev; struct list_head * entry = dpm_active.prev;
struct device * dev = to_device(entry); struct device * dev = to_device(entry);
error = suspend_device(dev,state); error = suspend_device(dev, state);
if (!error) { if (!error) {
list_del(&dev->power.entry); list_del(&dev->power.entry);
list_add(&dev->power.entry,&dpm_off); list_add(&dev->power.entry, &dpm_off);
} else if (error == -EAGAIN) { } else if (error == -EAGAIN) {
list_del(&dev->power.entry); list_del(&dev->power.entry);
list_add(&dev->power.entry,&dpm_off_irq); list_add(&dev->power.entry, &dpm_off_irq);
} else { } else {
printk(KERN_ERR "Could not suspend device %s: " printk(KERN_ERR "Could not suspend device %s: "
"error %d\n", kobject_name(&dev->kobj), error); "error %d\n", kobject_name(&dev->kobj), error);
...@@ -117,8 +117,8 @@ int device_power_down(u32 state) ...@@ -117,8 +117,8 @@ int device_power_down(u32 state)
int error = 0; int error = 0;
struct device * dev; struct device * dev;
list_for_each_entry_reverse(dev,&dpm_off_irq,power.entry) { list_for_each_entry_reverse(dev, &dpm_off_irq, power.entry) {
if ((error = suspend_device(dev,state))) if ((error = suspend_device(dev, state)))
break; break;
} }
if (error) if (error)
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
static ssize_t state_show(struct device * dev, char * buf) 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) 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) ...@@ -35,17 +35,17 @@ static ssize_t state_store(struct device * dev, const char * buf, size_t n)
char * rest; char * rest;
int error = 0; int error = 0;
state = simple_strtoul(buf,&rest,10); state = simple_strtoul(buf, &rest, 10);
if (*rest) if (*rest)
return -EINVAL; return -EINVAL;
if (state) if (state)
error = dpm_runtime_suspend(dev,state); error = dpm_runtime_suspend(dev, state);
else else
dpm_runtime_resume(dev); dpm_runtime_resume(dev);
return error ? error : n; 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[] = { static struct attribute * power_attrs[] = {
...@@ -59,10 +59,10 @@ static struct attribute_group pm_attr_group = { ...@@ -59,10 +59,10 @@ static struct attribute_group pm_attr_group = {
int dpm_sysfs_add(struct device * dev) 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) void dpm_sysfs_remove(struct device * dev)
{ {
sysfs_remove_group(&dev->kobj,&pm_attr_group); sysfs_remove_group(&dev->kobj, &pm_attr_group);
} }
...@@ -24,8 +24,8 @@ ...@@ -24,8 +24,8 @@
extern struct subsystem devices_subsys; extern struct subsystem devices_subsys;
#define to_sysdev(k) container_of(k,struct sys_device,kobj) #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_attr(a) container_of(a, struct sysdev_attribute, attr)
static ssize_t static ssize_t
...@@ -35,7 +35,7 @@ sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer) ...@@ -35,7 +35,7 @@ sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer)
struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr); struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
if (sysdev_attr->show) if (sysdev_attr->show)
return sysdev_attr->show(sysdev,buffer); return sysdev_attr->show(sysdev, buffer);
return 0; return 0;
} }
...@@ -48,7 +48,7 @@ sysdev_store(struct kobject * kobj, struct attribute * attr, ...@@ -48,7 +48,7 @@ sysdev_store(struct kobject * kobj, struct attribute * attr,
struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr); struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
if (sysdev_attr->store) if (sysdev_attr->store)
return sysdev_attr->store(sysdev,buffer,count); return sysdev_attr->store(sysdev, buffer, count);
return 0; return 0;
} }
...@@ -64,13 +64,13 @@ static struct kobj_type ktype_sysdev = { ...@@ -64,13 +64,13 @@ static struct kobj_type ktype_sysdev = {
int sysdev_create_file(struct sys_device * s, struct sysdev_attribute * a) 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) 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_create_file);
...@@ -79,7 +79,7 @@ EXPORT_SYMBOL(sysdev_remove_file); ...@@ -79,7 +79,7 @@ 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) int sysdev_class_register(struct sysdev_class * cls)
{ {
...@@ -87,7 +87,7 @@ 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)); kobject_name(&cls->kset.kobj));
INIT_LIST_HEAD(&cls->drivers); INIT_LIST_HEAD(&cls->drivers);
cls->kset.subsys = &system_subsys; cls->kset.subsys = &system_subsys;
kset_set_kset_s(cls,system_subsys); kset_set_kset_s(cls, system_subsys);
return kset_register(&cls->kset); return kset_register(&cls->kset);
} }
...@@ -121,7 +121,7 @@ int sysdev_driver_register(struct sysdev_class * cls, ...@@ -121,7 +121,7 @@ int sysdev_driver_register(struct sysdev_class * cls,
{ {
down_write(&system_subsys.rwsem); down_write(&system_subsys.rwsem);
if (cls && kset_get(&cls->kset)) { 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 devices of this class already exist, tell the driver */
if (drv->add) { if (drv->add) {
...@@ -130,7 +130,7 @@ int sysdev_driver_register(struct sysdev_class * cls, ...@@ -130,7 +130,7 @@ int sysdev_driver_register(struct sysdev_class * cls,
drv->add(dev); drv->add(dev);
} }
} else } else
list_add_tail(&drv->entry,&global_drivers); list_add_tail(&drv->entry, &global_drivers);
up_write(&system_subsys.rwsem); up_write(&system_subsys.rwsem);
return 0; return 0;
} }
...@@ -180,12 +180,12 @@ int sysdev_register(struct sys_device * sysdev) ...@@ -180,12 +180,12 @@ int sysdev_register(struct sys_device * sysdev)
/* But make sure we point to the right type for sysfs translation */ /* But make sure we point to the right type for sysfs translation */
sysdev->kobj.ktype = &ktype_sysdev; sysdev->kobj.ktype = &ktype_sysdev;
error = kobject_set_name(&sysdev->kobj,"%s%d", error = kobject_set_name(&sysdev->kobj, "%s%d",
kobject_name(&cls->kset.kobj),sysdev->id); kobject_name(&cls->kset.kobj), sysdev->id);
if (error) if (error)
return 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 */ /* Register the object */
error = kobject_register(&sysdev->kobj); error = kobject_register(&sysdev->kobj);
...@@ -199,13 +199,13 @@ int sysdev_register(struct sys_device * sysdev) ...@@ -199,13 +199,13 @@ int sysdev_register(struct sys_device * sysdev)
*/ */
/* Notify global drivers */ /* Notify global drivers */
list_for_each_entry(drv,&global_drivers,entry) { list_for_each_entry(drv, &global_drivers, entry) {
if (drv->add) if (drv->add)
drv->add(sysdev); drv->add(sysdev);
} }
/* Notify class auxillary drivers */ /* Notify class auxillary drivers */
list_for_each_entry(drv,&cls->drivers,entry) { list_for_each_entry(drv, &cls->drivers, entry) {
if (drv->add) if (drv->add)
drv->add(sysdev); drv->add(sysdev);
} }
...@@ -219,12 +219,12 @@ void sysdev_unregister(struct sys_device * sysdev) ...@@ -219,12 +219,12 @@ void sysdev_unregister(struct sys_device * sysdev)
struct sysdev_driver * drv; struct sysdev_driver * drv;
down_write(&system_subsys.rwsem); down_write(&system_subsys.rwsem);
list_for_each_entry(drv,&global_drivers,entry) { list_for_each_entry(drv, &global_drivers, entry) {
if (drv->remove) if (drv->remove)
drv->remove(sysdev); drv->remove(sysdev);
} }
list_for_each_entry(drv,&sysdev->cls->drivers,entry) { list_for_each_entry(drv, &sysdev->cls->drivers, entry) {
if (drv->remove) if (drv->remove)
drv->remove(sysdev); drv->remove(sysdev);
} }
...@@ -256,25 +256,25 @@ void sysdev_shutdown(void) ...@@ -256,25 +256,25 @@ void sysdev_shutdown(void)
pr_debug("Shutting Down System Devices\n"); pr_debug("Shutting Down System Devices\n");
down_write(&system_subsys.rwsem); 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) { kset.kobj.entry) {
struct sys_device * sysdev; struct sys_device * sysdev;
pr_debug("Shutting down type '%s':\n", pr_debug("Shutting down type '%s':\n",
kobject_name(&cls->kset.kobj)); 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; struct sysdev_driver * drv;
pr_debug(" %s\n",kobject_name(&sysdev->kobj)); pr_debug(" %s\n", kobject_name(&sysdev->kobj));
/* Call global drivers first. */ /* Call global drivers first. */
list_for_each_entry(drv,&global_drivers,entry) { list_for_each_entry(drv, &global_drivers, entry) {
if (drv->shutdown) if (drv->shutdown)
drv->shutdown(sysdev); drv->shutdown(sysdev);
} }
/* Call auxillary drivers next. */ /* Call auxillary drivers next. */
list_for_each_entry(drv,&cls->drivers,entry) { list_for_each_entry(drv, &cls->drivers, entry) {
if (drv->shutdown) if (drv->shutdown)
drv->shutdown(sysdev); drv->shutdown(sysdev);
} }
...@@ -307,32 +307,32 @@ int sysdev_suspend(u32 state) ...@@ -307,32 +307,32 @@ int sysdev_suspend(u32 state)
pr_debug("Suspending System Devices\n"); 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) { kset.kobj.entry) {
struct sys_device * sysdev; struct sys_device * sysdev;
pr_debug("Suspending type '%s':\n", pr_debug("Suspending type '%s':\n",
kobject_name(&cls->kset.kobj)); 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; struct sysdev_driver * drv;
pr_debug(" %s\n",kobject_name(&sysdev->kobj)); pr_debug(" %s\n", kobject_name(&sysdev->kobj));
/* Call global drivers first. */ /* Call global drivers first. */
list_for_each_entry(drv,&global_drivers,entry) { list_for_each_entry(drv, &global_drivers, entry) {
if (drv->suspend) if (drv->suspend)
drv->suspend(sysdev,state); drv->suspend(sysdev, state);
} }
/* Call auxillary drivers next. */ /* Call auxillary drivers next. */
list_for_each_entry(drv,&cls->drivers,entry) { list_for_each_entry(drv, &cls->drivers, entry) {
if (drv->suspend) if (drv->suspend)
drv->suspend(sysdev,state); drv->suspend(sysdev, state);
} }
/* Now call the generic one */ /* Now call the generic one */
if (cls->suspend) if (cls->suspend)
cls->suspend(sysdev,state); cls->suspend(sysdev, state);
} }
} }
return 0; return 0;
...@@ -354,28 +354,28 @@ int sysdev_resume(void) ...@@ -354,28 +354,28 @@ int sysdev_resume(void)
pr_debug("Resuming System Devices\n"); 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; struct sys_device * sysdev;
pr_debug("Resuming type '%s':\n", pr_debug("Resuming type '%s':\n",
kobject_name(&cls->kset.kobj)); 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; 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 */ /* First, call the class-specific one */
if (cls->resume) if (cls->resume)
cls->resume(sysdev); cls->resume(sysdev);
/* Call auxillary drivers next. */ /* Call auxillary drivers next. */
list_for_each_entry(drv,&cls->drivers,entry) { list_for_each_entry(drv, &cls->drivers, entry) {
if (drv->resume) if (drv->resume)
drv->resume(sysdev); drv->resume(sysdev);
} }
/* Call global drivers. */ /* Call global drivers. */
list_for_each_entry(drv,&global_drivers,entry) { list_for_each_entry(drv, &global_drivers, entry) {
if (drv->resume) if (drv->resume)
drv->resume(sysdev); drv->resume(sysdev);
} }
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/capability.h> #include <linux/capability.h>
#include <linux/uio.h> #include <linux/uio.h>
#include <linux/cdev.h> #include <linux/cdev.h>
#include <linux/device.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -26,6 +27,7 @@ struct raw_device_data { ...@@ -26,6 +27,7 @@ struct raw_device_data {
int inuse; int inuse;
}; };
static struct class_simple *raw_class;
static struct raw_device_data raw_devices[MAX_RAW_MINORS]; static struct raw_device_data raw_devices[MAX_RAW_MINORS];
static DECLARE_MUTEX(raw_mutex); static DECLARE_MUTEX(raw_mutex);
static struct file_operations raw_ctl_fops; /* forward declaration */ static struct file_operations raw_ctl_fops; /* forward declaration */
...@@ -123,6 +125,13 @@ raw_ioctl(struct inode *inode, struct file *filp, ...@@ -123,6 +125,13 @@ raw_ioctl(struct inode *inode, struct file *filp,
return ioctl_by_bdev(bdev, command, arg); 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 * Deal with ioctls against the raw-device control interface, to bind
* and unbind other raw devices. * and unbind other raw devices.
...@@ -191,12 +200,15 @@ static int raw_ctl_ioctl(struct inode *inode, struct file *filp, ...@@ -191,12 +200,15 @@ static int raw_ctl_ioctl(struct inode *inode, struct file *filp,
if (rq.block_major == 0 && rq.block_minor == 0) { if (rq.block_major == 0 && rq.block_minor == 0) {
/* unbind */ /* unbind */
rawdev->binding = NULL; rawdev->binding = NULL;
class_simple_device_remove(MKDEV(RAW_MAJOR, rq.raw_minor));
} else { } else {
rawdev->binding = bdget(dev); rawdev->binding = bdget(dev);
if (rawdev->binding == NULL) if (rawdev->binding == NULL)
err = -ENOMEM; err = -ENOMEM;
else else {
__module_get(THIS_MODULE); __module_get(THIS_MODULE);
bind_device(rq);
}
} }
up(&raw_mutex); up(&raw_mutex);
} else { } else {
...@@ -287,6 +299,15 @@ static int __init raw_init(void) ...@@ -287,6 +299,15 @@ static int __init raw_init(void)
goto error; 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), devfs_mk_cdev(MKDEV(RAW_MAJOR, 0),
S_IFCHR | S_IRUGO | S_IWUGO, S_IFCHR | S_IRUGO | S_IWUGO,
"raw/rawctl"); "raw/rawctl");
...@@ -309,6 +330,8 @@ static void __exit raw_exit(void) ...@@ -309,6 +330,8 @@ static void __exit raw_exit(void)
devfs_remove("raw/raw%d", i); devfs_remove("raw/raw%d", i);
devfs_remove("raw/rawctl"); devfs_remove("raw/rawctl");
devfs_remove("raw"); devfs_remove("raw");
class_simple_device_remove(MKDEV(RAW_MAJOR, 0));
class_simple_destroy(raw_class);
cdev_del(&raw_cdev); cdev_del(&raw_cdev);
unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), MAX_RAW_MINORS); unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), MAX_RAW_MINORS);
} }
......
...@@ -138,7 +138,7 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, ...@@ -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)); 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 " dev_err(&PIIX4_dev->dev, "IBM Laptop detected; this module "
"may corrupt your serial eeprom! Refusing to load " "may corrupt your serial eeprom! Refusing to load "
"module!\n"); "module!\n");
......
...@@ -272,7 +272,7 @@ static ssize_t \ ...@@ -272,7 +272,7 @@ static ssize_t \
return show_in(dev, buf, 0x##offset); \ return show_in(dev, buf, 0x##offset); \
} \ } \
static DEVICE_ATTR(in##offset##_input, S_IRUGO, \ static DEVICE_ATTR(in##offset##_input, S_IRUGO, \
show_in##offset, NULL) \ show_in##offset, NULL); \
static ssize_t \ static ssize_t \
show_in##offset##_min (struct device *dev, char *buf) \ show_in##offset##_min (struct device *dev, char *buf) \
{ \ { \
...@@ -294,17 +294,17 @@ static ssize_t set_in##offset##_max (struct device *dev, \ ...@@ -294,17 +294,17 @@ static ssize_t set_in##offset##_max (struct device *dev, \
return set_in_max(dev, buf, count, 0x##offset); \ return set_in_max(dev, buf, count, 0x##offset); \
} \ } \
static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ 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, \ 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(0);
sysfs_in(1) sysfs_in(1);
sysfs_in(2) sysfs_in(2);
sysfs_in(3) sysfs_in(3);
sysfs_in(4) sysfs_in(4);
sysfs_in(5) sysfs_in(5);
sysfs_in(6) sysfs_in(6);
#define device_create_file_in(client, offset) do { \ #define device_create_file_in(client, offset) do { \
device_create_file(&client->dev, &dev_attr_in##offset##_input); \ 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, \ ...@@ -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); \ return set_fan_div(dev, buf, count, offset - 1); \
} \ } \
static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ 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, \ 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, \ 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(1);
sysfs_fan(2) sysfs_fan(2);
sysfs_fan(3) sysfs_fan(3);
#define device_create_file_fan(client, offset) do { \ #define device_create_file_fan(client, offset) do { \
device_create_file(&client->dev, &dev_attr_fan##offset##_input); \ 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) \ ...@@ -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); \ return sprintf_temp_from_reg(data->reg[nr], buf, nr); \
} }
show_temp_reg(temp) show_temp_reg(temp);
show_temp_reg(temp_max) show_temp_reg(temp_max);
show_temp_reg(temp_hyst) show_temp_reg(temp_hyst);
#define set_temp_reg(REG, reg) \ #define set_temp_reg(REG, reg) \
static ssize_t set_##reg(struct device *dev, const char *buf, \ 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, \ ...@@ -473,15 +473,15 @@ static ssize_t set_##reg(struct device *dev, const char *buf, \
return count; \ return count; \
} }
set_temp_reg(MAX, temp_max) set_temp_reg(MAX, temp_max);
set_temp_reg(HYST, temp_hyst) set_temp_reg(HYST, temp_hyst);
#define sysfs_temp(num) \ #define sysfs_temp(num) \
static ssize_t show_temp##num(struct device *dev, char *buf) \ static ssize_t show_temp##num(struct device *dev, char *buf) \
{ \ { \
return show_temp(dev, buf, num-1); \ 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) \ static ssize_t show_temp_max##num(struct device *dev, char *buf) \
{ \ { \
return show_temp_max(dev, buf, num-1); \ 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, \ ...@@ -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); \ return set_temp_max(dev, buf, count, num-1); \
} \ } \
static DEVICE_ATTR(temp##num##_max, S_IRUGO | S_IWUSR, \ 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) \ static ssize_t show_temp_hyst##num(struct device *dev, char *buf) \
{ \ { \
return show_temp_hyst(dev, buf, num-1); \ 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, \ ...@@ -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); \ return set_temp_hyst(dev, buf, count, num-1); \
} \ } \
static DEVICE_ATTR(temp##num##_max_hyst, S_IRUGO | S_IWUSR, \ 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(1);
sysfs_temp(2) sysfs_temp(2);
sysfs_temp(3) sysfs_temp(3);
sysfs_temp(4) sysfs_temp(4);
/* VID */ /* VID */
#define device_create_file_temp(client, num) do { \ #define device_create_file_temp(client, num) do { \
...@@ -523,7 +523,7 @@ static ssize_t show_vid(struct device *dev, char *buf) ...@@ -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)); 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) \ #define device_create_file_vid(client) \
device_create_file(&client->dev, &dev_attr_in0_ref) 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) ...@@ -544,7 +544,7 @@ static ssize_t set_vrm(struct device *dev, const char *buf, size_t count)
} }
/* Alarms */ /* 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) \ #define device_create_file_vrm(client) \
device_create_file(&client->dev, &dev_attr_vrm); device_create_file(&client->dev, &dev_attr_vrm);
...@@ -554,7 +554,7 @@ static ssize_t show_alarms(struct device *dev, char *buf) ...@@ -554,7 +554,7 @@ static ssize_t show_alarms(struct device *dev, char *buf)
return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->alarms)); 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) \ #define device_create_file_alarms(client) \
device_create_file(&client->dev, &dev_attr_alarms) device_create_file(&client->dev, &dev_attr_alarms)
...@@ -594,9 +594,9 @@ static ssize_t set_pwm_enable1(struct device *dev, const char *buf, ...@@ -594,9 +594,9 @@ static ssize_t set_pwm_enable1(struct device *dev, const char *buf,
return count; 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, 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 { \ #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); \
device_create_file(&new_client->dev, &dev_attr_fan1_pwm_enable); \ device_create_file(&new_client->dev, &dev_attr_fan1_pwm_enable); \
......
...@@ -128,15 +128,15 @@ static int reset; ...@@ -128,15 +128,15 @@ static int reset;
#define IT87_REG_FAN(nr) (0x0d + (nr)) #define IT87_REG_FAN(nr) (0x0d + (nr))
#define IT87_REG_FAN_MIN(nr) (0x10 + (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_VIN(nr) (0x20 + (nr))
#define IT87_REG_TEMP(nr) (0x29 + (nr)) #define IT87_REG_TEMP(nr) (0x29 + (nr))
#define IT87_REG_VIN_MAX(nr) (0x30 + (nr) * 2) #define IT87_REG_VIN_MAX(nr) (0x30 + (nr) * 2)
#define IT87_REG_VIN_MIN(nr) (0x31 + (nr) * 2) #define IT87_REG_VIN_MIN(nr) (0x31 + (nr) * 2)
#define IT87_REG_TEMP_HIGH(nr) (0x40 + ((nr) * 2)) #define IT87_REG_TEMP_HIGH(nr) (0x40 + (nr) * 2)
#define IT87_REG_TEMP_LOW(nr) (0x41 + ((nr) * 2)) #define IT87_REG_TEMP_LOW(nr) (0x41 + (nr) * 2)
#define IT87_REG_I2C_ADDR 0x48 #define IT87_REG_I2C_ADDR 0x48
...@@ -145,8 +145,8 @@ static int reset; ...@@ -145,8 +145,8 @@ static int reset;
#define IT87_REG_CHIPID 0x58 #define IT87_REG_CHIPID 0x58
#define IN_TO_REG(val) (SENSORS_LIMIT((((val) * 10 + 8)/16),0,255)) #define IN_TO_REG(val) (SENSORS_LIMIT((((val) + 8)/16),0,255))
#define IN_FROM_REG(val) (((val) * 16) / 10) #define IN_FROM_REG(val) ((val) * 16)
static inline u8 FAN_TO_REG(long rpm, int div) static inline u8 FAN_TO_REG(long rpm, int div)
{ {
...@@ -159,9 +159,9 @@ 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 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):\ #define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-500)/1000):\
((val)+5)/10),0,255)) ((val)+500)/1000),-128,127))
#define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*10) #define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*1000)
#define VID_FROM_REG(val) ((val)==0x1f?0:(val)>=0x10?510-(val)*10:\ #define VID_FROM_REG(val) ((val)==0x1f?0:(val)>=0x10?510-(val)*10:\
205-(val)*5) 205-(val)*5)
...@@ -170,7 +170,7 @@ static inline u8 FAN_TO_REG(long rpm, int div) ...@@ -170,7 +170,7 @@ static inline u8 FAN_TO_REG(long rpm, int div)
static int DIV_TO_REG(int val) static int DIV_TO_REG(int val)
{ {
int answer = 0; int answer = 0;
while ((val >>= 1)) while ((val >>= 1) != 0)
answer++; answer++;
return answer; return answer;
} }
...@@ -231,19 +231,19 @@ static int it87_id = 0; ...@@ -231,19 +231,19 @@ static int it87_id = 0;
static ssize_t show_in(struct device *dev, char *buf, int nr) static ssize_t show_in(struct device *dev, char *buf, int nr)
{ {
struct it87_data *data = it87_update_device(dev); 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) static ssize_t show_in_min(struct device *dev, char *buf, int nr)
{ {
struct it87_data *data = it87_update_device(dev); 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) static ssize_t show_in_max(struct device *dev, char *buf, int nr)
{ {
struct it87_data *data = it87_update_device(dev); 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, 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, ...@@ -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 i2c_client *client = to_i2c_client(dev);
struct it87_data *data = i2c_get_clientdata(client); 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); data->in_min[nr] = IN_TO_REG(val);
it87_write_value(client, IT87_REG_VIN_MIN(nr), it87_write_value(client, IT87_REG_VIN_MIN(nr),
data->in_min[nr]); data->in_min[nr]);
...@@ -262,7 +262,7 @@ static ssize_t set_in_max(struct device *dev, const char *buf, ...@@ -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 i2c_client *client = to_i2c_client(dev);
struct it87_data *data = i2c_get_clientdata(client); 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); data->in_max[nr] = IN_TO_REG(val);
it87_write_value(client, IT87_REG_VIN_MAX(nr), it87_write_value(client, IT87_REG_VIN_MAX(nr),
data->in_max[nr]); data->in_max[nr]);
...@@ -275,7 +275,7 @@ static ssize_t \ ...@@ -275,7 +275,7 @@ static ssize_t \
{ \ { \
return show_in(dev, buf, 0x##offset); \ 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) \ #define limit_in_offset(offset) \
static ssize_t \ static ssize_t \
...@@ -299,9 +299,9 @@ static ssize_t set_in##offset##_max (struct device *dev, \ ...@@ -299,9 +299,9 @@ static ssize_t set_in##offset##_max (struct device *dev, \
return set_in_max(dev, buf, count, 0x##offset); \ return set_in_max(dev, buf, count, 0x##offset); \
} \ } \
static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ 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, \ 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(0);
limit_in_offset(0); limit_in_offset(0);
...@@ -325,24 +325,24 @@ show_in_offset(8); ...@@ -325,24 +325,24 @@ show_in_offset(8);
static ssize_t show_temp(struct device *dev, char *buf, int nr) static ssize_t show_temp(struct device *dev, char *buf, int nr)
{ {
struct it87_data *data = it87_update_device(dev); 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) static ssize_t show_temp_max(struct device *dev, char *buf, int nr)
{ {
struct it87_data *data = it87_update_device(dev); 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) static ssize_t show_temp_min(struct device *dev, char *buf, int nr)
{ {
struct it87_data *data = it87_update_device(dev); 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, static ssize_t set_temp_max(struct device *dev, const char *buf,
size_t count, int nr) size_t count, int nr)
{ {
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
struct it87_data *data = i2c_get_clientdata(client); 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); data->temp_high[nr] = TEMP_TO_REG(val);
it87_write_value(client, IT87_REG_TEMP_HIGH(nr), data->temp_high[nr]); it87_write_value(client, IT87_REG_TEMP_HIGH(nr), data->temp_high[nr]);
return count; return count;
...@@ -352,7 +352,7 @@ static ssize_t set_temp_min(struct device *dev, const char *buf, ...@@ -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 i2c_client *client = to_i2c_client(dev);
struct it87_data *data = i2c_get_clientdata(client); 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); data->temp_low[nr] = TEMP_TO_REG(val);
it87_write_value(client, IT87_REG_TEMP_LOW(nr), data->temp_low[nr]); it87_write_value(client, IT87_REG_TEMP_LOW(nr), data->temp_low[nr]);
return count; return count;
...@@ -382,11 +382,11 @@ static ssize_t set_temp_##offset##_min (struct device *dev, \ ...@@ -382,11 +382,11 @@ static ssize_t set_temp_##offset##_min (struct device *dev, \
{ \ { \
return set_temp_min(dev, buf, count, 0x##offset - 1); \ 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, \ 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, \ 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(1);
show_temp_offset(2); show_temp_offset(2);
...@@ -431,7 +431,7 @@ static ssize_t set_sensor_##offset (struct device *dev, \ ...@@ -431,7 +431,7 @@ static ssize_t set_sensor_##offset (struct device *dev, \
return set_sensor(dev, buf, count, 0x##offset - 1); \ return set_sensor(dev, buf, count, 0x##offset - 1); \
} \ } \
static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, \ static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, \
show_sensor_##offset, set_sensor_##offset) show_sensor_##offset, set_sensor_##offset);
show_sensor_offset(1); show_sensor_offset(1);
show_sensor_offset(2); show_sensor_offset(2);
...@@ -525,11 +525,11 @@ static ssize_t set_fan_##offset##_div (struct device *dev, \ ...@@ -525,11 +525,11 @@ static ssize_t set_fan_##offset##_div (struct device *dev, \
{ \ { \
return set_fan_div(dev, buf, count, 0x##offset - 1); \ 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, \ 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, \ 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(1);
show_fan_offset(2); show_fan_offset(2);
...@@ -773,9 +773,7 @@ static int it87_detach_client(struct i2c_client *client) ...@@ -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 We don't want to lock the whole ISA bus, so we lock each client
separately. separately.
We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, 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. 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! */
static int it87_read_value(struct i2c_client *client, u8 reg) static int it87_read_value(struct i2c_client *client, u8 reg)
{ {
struct it87_data *data = i2c_get_clientdata(client); struct it87_data *data = i2c_get_clientdata(client);
...@@ -795,9 +793,7 @@ static int it87_read_value(struct i2c_client *client, u8 reg) ...@@ -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 We don't want to lock the whole ISA bus, so we lock each client
separately. separately.
We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, 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. 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! */
static int it87_write_value(struct i2c_client *client, u8 reg, u8 value) static int it87_write_value(struct i2c_client *client, u8 reg, u8 value)
{ {
struct it87_data *data = i2c_get_clientdata(client); 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) ...@@ -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 */ /* 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) { if ((tmp & 0x70) == 0) {
/* Enable all fan tachometers */ /* Enable all fan tachometers */
tmp = (tmp & 0x8f) | 0x70; 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 */ /* Start monitoring */
......
...@@ -281,7 +281,7 @@ static ssize_t \ ...@@ -281,7 +281,7 @@ static ssize_t \
return show_in(dev, buf, 0x##offset); \ return show_in(dev, buf, 0x##offset); \
} \ } \
static DEVICE_ATTR(in##offset##_input, S_IRUGO, \ static DEVICE_ATTR(in##offset##_input, S_IRUGO, \
show_in##offset, NULL) \ show_in##offset, NULL); \
static ssize_t \ static ssize_t \
show_in##offset##_min (struct device *dev, char *buf) \ show_in##offset##_min (struct device *dev, char *buf) \
{ \ { \
...@@ -303,9 +303,9 @@ static ssize_t set_in##offset##_max (struct device *dev, \ ...@@ -303,9 +303,9 @@ static ssize_t set_in##offset##_max (struct device *dev, \
return set_in_max(dev, buf, count, 0x##offset); \ return set_in_max(dev, buf, count, 0x##offset); \
} \ } \
static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ 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, \ 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(0);
show_in_offset(1); show_in_offset(1);
...@@ -354,11 +354,11 @@ static ssize_t set_temp_hyst(struct device *dev, const char *buf, size_t count) ...@@ -354,11 +354,11 @@ static ssize_t set_temp_hyst(struct device *dev, const char *buf, size_t count)
return 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, 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, static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
show_temp_hyst, set_temp_hyst) show_temp_hyst, set_temp_hyst);
/* 3 Fans */ /* 3 Fans */
static ssize_t show_fan(struct device *dev, char *buf, int nr) 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, \ ...@@ -439,9 +439,9 @@ static ssize_t set_fan_##offset##_min (struct device *dev, \
{ \ { \
return set_fan_min(dev, buf, count, 0x##offset - 1); \ 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, \ 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, static ssize_t set_fan_1_div(struct device *dev, const char *buf,
size_t count) size_t count)
...@@ -461,10 +461,10 @@ show_fan_offset(3); ...@@ -461,10 +461,10 @@ show_fan_offset(3);
/* Fan 3 divisor is locked in H/W */ /* Fan 3 divisor is locked in H/W */
static DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR, 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, static DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
show_fan_2_div, set_fan_2_div) show_fan_2_div, set_fan_2_div);
static DEVICE_ATTR(fan3_div, S_IRUGO, show_fan_3_div, NULL) static DEVICE_ATTR(fan3_div, S_IRUGO, show_fan_3_div, NULL);
/* VID */ /* VID */
static ssize_t show_vid(struct device *dev, char *buf) static ssize_t show_vid(struct device *dev, char *buf)
......
...@@ -451,9 +451,9 @@ static ssize_t set_fan_##offset##_min (struct device *dev, \ ...@@ -451,9 +451,9 @@ static ssize_t set_fan_##offset##_min (struct device *dev, \
{ \ { \
return set_fan_min(dev, buf, count, 0x##offset - 1); \ 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, \ 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(1);
show_fan_offset(2); show_fan_offset(2);
...@@ -468,7 +468,7 @@ static ssize_t show_vid_reg(struct device *dev, char *buf) ...@@ -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)); 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) 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) ...@@ -487,7 +487,7 @@ static ssize_t store_vrm_reg(struct device *dev, const char *buf, size_t count)
return 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) 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) ...@@ -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)); 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 */ /* pwm */
...@@ -542,8 +542,8 @@ static ssize_t show_pwm_enable##offset (struct device *dev, char *buf) \ ...@@ -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); \ return show_pwm_enable(dev, buf, 0x##offset - 1); \
} \ } \
static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, \ static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, \
show_pwm_##offset, set_pwm_##offset) \ show_pwm_##offset, set_pwm_##offset); \
static DEVICE_ATTR(fan##offset##_pwm_enable, S_IRUGO, show_pwm_enable##offset, NULL) static DEVICE_ATTR(fan##offset##_pwm_enable, S_IRUGO, show_pwm_enable##offset, NULL);
show_pwm_reg(1); show_pwm_reg(1);
show_pwm_reg(2); show_pwm_reg(2);
...@@ -617,11 +617,11 @@ static ssize_t set_in_##offset##_max (struct device *dev, \ ...@@ -617,11 +617,11 @@ static ssize_t set_in_##offset##_max (struct device *dev, \
{ \ { \
return set_in_max(dev, buf, count, 0x##offset); \ 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, \ 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, \ 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(0);
show_in_reg(1); show_in_reg(1);
...@@ -697,11 +697,11 @@ static ssize_t set_temp_##offset##_max (struct device *dev, \ ...@@ -697,11 +697,11 @@ static ssize_t set_temp_##offset##_max (struct device *dev, \
{ \ { \
return set_temp_max(dev, buf, count, 0x##offset - 1); \ 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, \ 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, \ 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(1);
show_temp_reg(2); show_temp_reg(2);
......
...@@ -405,11 +405,11 @@ static ssize_t set_in##offset##_max (struct device *dev, \ ...@@ -405,11 +405,11 @@ static ssize_t set_in##offset##_max (struct device *dev, \
{ \ { \
return set_in_max(dev, buf, count, 0x##offset); \ 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, \ 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, \ 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(0);
show_in_offset(1); show_in_offset(1);
...@@ -473,11 +473,11 @@ static ssize_t set_temp_##offset##_hyst (struct device *dev, \ ...@@ -473,11 +473,11 @@ static ssize_t set_temp_##offset##_hyst (struct device *dev, \
{ \ { \
return set_temp_hyst(dev, buf, count, 0x##offset - 1); \ 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, \ 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, \ 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(1);
show_temp_offset(2); show_temp_offset(2);
...@@ -542,11 +542,11 @@ static ssize_t set_fan_##offset##_div (struct device *dev, \ ...@@ -542,11 +542,11 @@ static ssize_t set_fan_##offset##_div (struct device *dev, \
{ \ { \
return set_fan_div(dev, buf, count, 0x##offset - 1); \ 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, \ 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, \ 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(1);
show_fan_offset(2); show_fan_offset(2);
......
...@@ -199,7 +199,7 @@ superio_exit(void) ...@@ -199,7 +199,7 @@ superio_exit(void)
#define W83627THF_REG_PWM2 0x03 /* 697HF and 637HF too */ #define W83627THF_REG_PWM2 0x03 /* 697HF and 637HF too */
#define W83627THF_REG_PWM3 0x11 /* 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_627hf[] = { W83627HF_REG_PWM1, W83627HF_REG_PWM2 };
static const u8 regpwm[] = { W83627THF_REG_PWM1, W83627THF_REG_PWM2, static const u8 regpwm[] = { W83627THF_REG_PWM1, W83627THF_REG_PWM2,
...@@ -222,7 +222,7 @@ static const u8 BIT_SCFG2[] = { 0x10, 0x20, 0x40 }; ...@@ -222,7 +222,7 @@ static const u8 BIT_SCFG2[] = { 0x10, 0x20, 0x40 };
these macros are called: arguments may be evaluated more than once. these macros are called: arguments may be evaluated more than once.
Fixing this is just not worth it. */ Fixing this is just not worth it. */
#define IN_TO_REG(val) (SENSORS_LIMIT((((val) + 8)/16),0,255)) #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) static inline u8 FAN_TO_REG(long rpm, int div)
{ {
...@@ -312,6 +312,7 @@ struct w83627hf_data { ...@@ -312,6 +312,7 @@ struct w83627hf_data {
Default = 3435. Default = 3435.
Other Betas unimplemented */ Other Betas unimplemented */
u8 vrm; u8 vrm;
u8 vrm_ovt; /* Register value, 627thf & 637hf only */
}; };
...@@ -370,7 +371,7 @@ show_regs_in_##offset (struct device *dev, char *buf) \ ...@@ -370,7 +371,7 @@ show_regs_in_##offset (struct device *dev, char *buf) \
{ \ { \
return show_in(dev, buf, 0x##offset); \ 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) \ #define sysfs_in_reg_offset(reg, offset) \
static ssize_t show_regs_in_##reg##offset (struct device *dev, char *buf) \ 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, \ ...@@ -384,22 +385,104 @@ store_regs_in_##reg##offset (struct device *dev, \
return store_in_##reg (dev, buf, count, 0x##offset); \ return store_in_##reg (dev, buf, count, 0x##offset); \
} \ } \
static DEVICE_ATTR(in##offset##_##reg, S_IRUGO| S_IWUSR, \ 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) \ #define sysfs_in_offsets(offset) \
sysfs_in_offset(offset) \ sysfs_in_offset(offset) \
sysfs_in_reg_offset(min, offset) \ sysfs_in_reg_offset(min, offset) \
sysfs_in_reg_offset(max, offset) sysfs_in_reg_offset(max, offset)
sysfs_in_offsets(0) sysfs_in_offsets(1);
sysfs_in_offsets(1) sysfs_in_offsets(2);
sysfs_in_offsets(2) sysfs_in_offsets(3);
sysfs_in_offsets(3) sysfs_in_offsets(4);
sysfs_in_offsets(4) sysfs_in_offsets(5);
sysfs_in_offsets(5) sysfs_in_offsets(6);
sysfs_in_offsets(6) sysfs_in_offsets(7);
sysfs_in_offsets(7) sysfs_in_offsets(8);
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) \ #define device_create_file_in(client, offset) \
do { \ do { \
...@@ -416,8 +499,8 @@ static ssize_t show_##reg (struct device *dev, char *buf, int nr) \ ...@@ -416,8 +499,8 @@ static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
FAN_FROM_REG(data->reg[nr-1], \ FAN_FROM_REG(data->reg[nr-1], \
(long)DIV_FROM_REG(data->fan_div[nr-1]))); \ (long)DIV_FROM_REG(data->fan_div[nr-1]))); \
} }
show_fan_reg(fan) show_fan_reg(fan);
show_fan_reg(fan_min) show_fan_reg(fan_min);
static ssize_t static ssize_t
store_fan_min(struct device *dev, const char *buf, size_t count, int nr) 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) \ ...@@ -440,7 +523,7 @@ static ssize_t show_regs_fan_##offset (struct device *dev, char *buf) \
{ \ { \
return show_fan(dev, buf, 0x##offset); \ 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) \ #define sysfs_fan_min_offset(offset) \
static ssize_t show_regs_fan_min##offset (struct device *dev, char *buf) \ 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) \ ...@@ -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); \ return store_fan_min(dev, buf, count, 0x##offset); \
} \ } \
static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ 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_offset(1);
sysfs_fan_min_offset(1) sysfs_fan_min_offset(1);
sysfs_fan_offset(2) sysfs_fan_offset(2);
sysfs_fan_min_offset(2) sysfs_fan_min_offset(2);
sysfs_fan_offset(3) sysfs_fan_offset(3);
sysfs_fan_min_offset(3) sysfs_fan_min_offset(3);
#define device_create_file_fan(client, offset) \ #define device_create_file_fan(client, offset) \
do { \ do { \
...@@ -479,9 +562,9 @@ static ssize_t show_##reg (struct device *dev, char *buf, int nr) \ ...@@ -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)); \ return sprintf(buf,"%ld\n", (long)TEMP_FROM_REG(data->reg)); \
} \ } \
} }
show_temp_reg(temp) show_temp_reg(temp);
show_temp_reg(temp_max) show_temp_reg(temp_max);
show_temp_reg(temp_max_hyst) show_temp_reg(temp_max_hyst);
#define store_temp_reg(REG, reg) \ #define store_temp_reg(REG, reg) \
static ssize_t \ static ssize_t \
...@@ -505,8 +588,8 @@ store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \ ...@@ -505,8 +588,8 @@ store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \
\ \
return count; \ return count; \
} }
store_temp_reg(OVER, max) store_temp_reg(OVER, max);
store_temp_reg(HYST, max_hyst) store_temp_reg(HYST, max_hyst);
#define sysfs_temp_offset(offset) \ #define sysfs_temp_offset(offset) \
static ssize_t \ static ssize_t \
...@@ -514,7 +597,7 @@ show_regs_temp_##offset (struct device *dev, char *buf) \ ...@@ -514,7 +597,7 @@ show_regs_temp_##offset (struct device *dev, char *buf) \
{ \ { \
return show_temp(dev, buf, 0x##offset); \ 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) \ #define sysfs_temp_reg_offset(reg, offset) \
static ssize_t show_regs_temp_##reg##offset (struct device *dev, char *buf) \ 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, \ ...@@ -528,16 +611,16 @@ store_regs_temp_##reg##offset (struct device *dev, \
return store_temp_##reg (dev, buf, count, 0x##offset); \ return store_temp_##reg (dev, buf, count, 0x##offset); \
} \ } \
static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, \ 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) \ #define sysfs_temp_offsets(offset) \
sysfs_temp_offset(offset) \ sysfs_temp_offset(offset) \
sysfs_temp_reg_offset(max, offset) \ sysfs_temp_reg_offset(max, offset) \
sysfs_temp_reg_offset(max_hyst, offset) sysfs_temp_reg_offset(max_hyst, offset)
sysfs_temp_offsets(1) sysfs_temp_offsets(1);
sysfs_temp_offsets(2) sysfs_temp_offsets(2);
sysfs_temp_offsets(3) sysfs_temp_offsets(3);
#define device_create_file_temp(client, offset) \ #define device_create_file_temp(client, offset) \
do { \ do { \
...@@ -552,7 +635,7 @@ show_vid_reg(struct device *dev, char *buf) ...@@ -552,7 +635,7 @@ show_vid_reg(struct device *dev, char *buf)
struct w83627hf_data *data = w83627hf_update_device(dev); struct w83627hf_data *data = w83627hf_update_device(dev);
return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm)); 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) \ #define device_create_file_vid(client) \
device_create_file(&client->dev, &dev_attr_in0_ref) 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) ...@@ -574,7 +657,7 @@ store_vrm_reg(struct device *dev, const char *buf, size_t count)
return 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) \ #define device_create_file_vrm(client) \
device_create_file(&client->dev, &dev_attr_vrm) device_create_file(&client->dev, &dev_attr_vrm)
...@@ -584,7 +667,7 @@ show_alarms_reg(struct device *dev, char *buf) ...@@ -584,7 +667,7 @@ show_alarms_reg(struct device *dev, char *buf)
struct w83627hf_data *data = w83627hf_update_device(dev); struct w83627hf_data *data = w83627hf_update_device(dev);
return sprintf(buf, "%ld\n", (long) data->alarms); 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) \ #define device_create_file_alarms(client) \
device_create_file(&client->dev, &dev_attr_alarms) 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) \ ...@@ -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); \ return store_beep_reg(dev, buf, count, BEEP_##REG); \
} \ } \
static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, \ 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(ENABLE, enable);
sysfs_beep(MASK, mask) sysfs_beep(MASK, mask);
#define device_create_file_beep(client) \ #define device_create_file_beep(client) \
do { \ do { \
...@@ -707,11 +790,11 @@ store_regs_fan_div_##offset (struct device *dev, \ ...@@ -707,11 +790,11 @@ store_regs_fan_div_##offset (struct device *dev, \
return store_fan_div_reg(dev, buf, count, offset - 1); \ return store_fan_div_reg(dev, buf, count, offset - 1); \
} \ } \
static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ 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(1);
sysfs_fan_div(2) sysfs_fan_div(2);
sysfs_fan_div(3) sysfs_fan_div(3);
#define device_create_file_fan_div(client, offset) \ #define device_create_file_fan_div(client, offset) \
do { \ do { \
...@@ -763,11 +846,11 @@ store_regs_pwm_##offset (struct device *dev, const char *buf, size_t count) \ ...@@ -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); \ return store_pwm_reg(dev, buf, count, offset); \
} \ } \
static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, \ 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(1);
sysfs_pwm(2) sysfs_pwm(2);
sysfs_pwm(3) sysfs_pwm(3);
#define device_create_file_pwm(client, offset) \ #define device_create_file_pwm(client, offset) \
do { \ do { \
...@@ -836,11 +919,11 @@ store_regs_sensor_##offset (struct device *dev, const char *buf, size_t count) \ ...@@ -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); \ return store_sensor_reg(dev, buf, count, offset); \
} \ } \
static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, \ 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(1);
sysfs_sensor(2) sysfs_sensor(2);
sysfs_sensor(3) sysfs_sensor(3);
#define device_create_file_sensor(client, offset) \ #define device_create_file_sensor(client, offset) \
do { \ do { \
...@@ -1157,7 +1240,7 @@ static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value) ...@@ -1157,7 +1240,7 @@ static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value)
static void w83627hf_init_client(struct i2c_client *client) static void w83627hf_init_client(struct i2c_client *client)
{ {
struct w83627hf_data *data = i2c_get_clientdata(client); struct w83627hf_data *data = i2c_get_clientdata(client);
int vid = 0, i; int i;
int type = data->type; int type = data->type;
u8 tmp; u8 tmp;
...@@ -1191,10 +1274,15 @@ static void w83627hf_init_client(struct i2c_client *client) ...@@ -1191,10 +1274,15 @@ static void w83627hf_init_client(struct i2c_client *client)
data->vid = w83627thf_read_gpio5(client) & 0x1f; data->vid = w83627thf_read_gpio5(client) & 0x1f;
} }
/* 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 */ /* Convert VID to voltage based on default VRM */
data->vrm = DEFAULT_VRM; data->vrm = DEFAULT_VRM;
if (type != w83697hf) }
vid = vid_from_reg(vid, data->vrm);
tmp = w83627hf_read_value(client, W83781D_REG_SCFG1); tmp = w83627hf_read_value(client, W83781D_REG_SCFG1);
for (i = 1; i <= 3; i++) { for (i = 1; i <= 3; i++) {
......
...@@ -320,7 +320,7 @@ show_regs_in_##offset (struct device *dev, char *buf) \ ...@@ -320,7 +320,7 @@ show_regs_in_##offset (struct device *dev, char *buf) \
{ \ { \
return show_in(dev, buf, 0x##offset); \ 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) \ #define sysfs_in_reg_offset(reg, offset) \
static ssize_t show_regs_in_##reg##offset (struct device *dev, char *buf) \ 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, ...@@ -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); \ 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) \ #define sysfs_in_offsets(offset) \
sysfs_in_offset(offset); \ sysfs_in_offset(offset); \
...@@ -386,7 +386,7 @@ static ssize_t show_regs_fan_##offset (struct device *dev, char *buf) \ ...@@ -386,7 +386,7 @@ static ssize_t show_regs_fan_##offset (struct device *dev, char *buf) \
{ \ { \
return show_fan(dev, buf, 0x##offset); \ 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) \ #define sysfs_fan_min_offset(offset) \
static ssize_t show_regs_fan_min##offset (struct device *dev, char *buf) \ 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, ...@@ -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); \ 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_offset(1);
sysfs_fan_min_offset(1); sysfs_fan_min_offset(1);
...@@ -466,7 +466,7 @@ show_regs_temp_##offset (struct device *dev, char *buf) \ ...@@ -466,7 +466,7 @@ show_regs_temp_##offset (struct device *dev, char *buf) \
{ \ { \
return show_temp(dev, buf, 0x##offset); \ 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) \ #define sysfs_temp_reg_offset(reg, offset) \
static ssize_t show_regs_temp_##reg##offset (struct device *dev, char *buf) \ 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 ...@@ -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); \ 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) \ #define sysfs_temp_offsets(offset) \
sysfs_temp_offset(offset); \ sysfs_temp_offset(offset); \
...@@ -503,7 +503,7 @@ show_vid_reg(struct device *dev, char *buf) ...@@ -503,7 +503,7 @@ show_vid_reg(struct device *dev, char *buf)
} }
static 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) \ #define device_create_file_vid(client) \
device_create_file(&client->dev, &dev_attr_in0_ref); device_create_file(&client->dev, &dev_attr_in0_ref);
static ssize_t static ssize_t
...@@ -527,7 +527,7 @@ store_vrm_reg(struct device *dev, const char *buf, size_t count) ...@@ -527,7 +527,7 @@ store_vrm_reg(struct device *dev, const char *buf, size_t count)
} }
static 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) \ #define device_create_file_vrm(client) \
device_create_file(&client->dev, &dev_attr_vrm); device_create_file(&client->dev, &dev_attr_vrm);
static ssize_t static ssize_t
...@@ -538,7 +538,7 @@ show_alarms_reg(struct device *dev, char *buf) ...@@ -538,7 +538,7 @@ show_alarms_reg(struct device *dev, char *buf)
} }
static 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) \ #define device_create_file_alarms(client) \
device_create_file(&client->dev, &dev_attr_alarms); device_create_file(&client->dev, &dev_attr_alarms);
static ssize_t show_beep_mask (struct device *dev, char *buf) 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_ ...@@ -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); \ 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(ENABLE, enable);
sysfs_beep(MASK, mask); sysfs_beep(MASK, mask);
...@@ -665,7 +665,7 @@ static ssize_t store_regs_fan_div_##offset (struct device *dev, const char *buf, ...@@ -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); \ 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(1);
sysfs_fan_div(2); sysfs_fan_div(2);
...@@ -744,7 +744,7 @@ static ssize_t store_regs_pwm_##offset (struct device *dev, const char *buf, siz ...@@ -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); \ 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) \ #define sysfs_pwmenable(offset) \
static ssize_t show_regs_pwmenable_##offset (struct device *dev, char *buf) \ 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 ...@@ -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); \ 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(1);
sysfs_pwm(2); sysfs_pwm(2);
...@@ -833,7 +833,7 @@ static ssize_t store_regs_sensor_##offset (struct device *dev, const char *buf, ...@@ -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); \ 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(1);
sysfs_sensor(2); sysfs_sensor(2);
...@@ -891,7 +891,7 @@ static ssize_t store_regs_rt_##offset (struct device *dev, const char *buf, size ...@@ -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); \ 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(1);
sysfs_rt(2); sysfs_rt(2);
...@@ -1491,7 +1491,7 @@ static void ...@@ -1491,7 +1491,7 @@ static void
w83781d_init_client(struct i2c_client *client) w83781d_init_client(struct i2c_client *client)
{ {
struct w83781d_data *data = i2c_get_clientdata(client); struct w83781d_data *data = i2c_get_clientdata(client);
int vid = 0, i, p; int i, p;
int type = data->type; int type = data->type;
u8 tmp; u8 tmp;
...@@ -1513,14 +1513,7 @@ w83781d_init_client(struct i2c_client *client) ...@@ -1513,14 +1513,7 @@ w83781d_init_client(struct i2c_client *client)
w83781d_write_value(client, W83781D_REG_BEEP_INTS2, 0); w83781d_write_value(client, W83781D_REG_BEEP_INTS2, 0);
} }
if (type != w83697hf) { data->vrm = 82;
vid = w83781d_read_value(client, W83781D_REG_VID_FANDIV) & 0x0f;
vid |=
(w83781d_read_value(client, W83781D_REG_CHIPID) & 0x01) <<
4;
data->vrm = DEFAULT_VRM;
vid = vid_from_reg(vid, data->vrm);
}
if ((type != w83781d) && (type != as99127f)) { if ((type != w83781d) && (type != as99127f)) {
tmp = w83781d_read_value(client, W83781D_REG_SCFG1); tmp = w83781d_read_value(client, W83781D_REG_SCFG1);
......
...@@ -137,8 +137,8 @@ static ssize_t show_temp_over(struct device *dev, char *buf) ...@@ -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)); 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_input, S_IRUGO, show_temp, NULL);
static DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_over, NULL) static DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_over, NULL);
/* /*
* Real code * Real code
......
...@@ -181,7 +181,7 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd, ...@@ -181,7 +181,7 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
struct i2c_smbus_ioctl_data data_arg; struct i2c_smbus_ioctl_data data_arg;
union i2c_smbus_data temp; union i2c_smbus_data temp;
struct i2c_msg *rdwr_pa; struct i2c_msg *rdwr_pa;
u8 **data_ptrs; u8 __user **data_ptrs;
int i,datasize,res; int i,datasize,res;
unsigned long funcs; unsigned long funcs;
...@@ -238,8 +238,7 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd, ...@@ -238,8 +238,7 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
return -EFAULT; return -EFAULT;
} }
data_ptrs = (u8 **) kmalloc(rdwr_arg.nmsgs * sizeof(u8 *), data_ptrs = kmalloc(rdwr_arg.nmsgs * sizeof(u8 __user *), GFP_KERNEL);
GFP_KERNEL);
if (data_ptrs == NULL) { if (data_ptrs == NULL) {
kfree(rdwr_pa); kfree(rdwr_pa);
return -ENOMEM; return -ENOMEM;
...@@ -252,7 +251,7 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd, ...@@ -252,7 +251,7 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
res = -EINVAL; res = -EINVAL;
break; 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); rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL);
if(rdwr_pa[i].buf == NULL) { if(rdwr_pa[i].buf == NULL) {
res = -ENOMEM; res = -ENOMEM;
......
...@@ -539,6 +539,7 @@ struct bus_type pci_bus_type = { ...@@ -539,6 +539,7 @@ struct bus_type pci_bus_type = {
.hotplug = pci_hotplug, .hotplug = pci_hotplug,
.suspend = pci_device_suspend, .suspend = pci_device_suspend,
.resume = pci_device_resume, .resume = pci_device_resume,
.dev_attrs = pci_dev_attrs,
}; };
static int __init pci_driver_init(void) static int __init pci_driver_init(void)
......
...@@ -23,14 +23,13 @@ ...@@ -23,14 +23,13 @@
/* show configuration fields */ /* show configuration fields */
#define pci_config_attr(field, format_string) \ #define pci_config_attr(field, format_string) \
static ssize_t \ static ssize_t \
show_##field (struct device *dev, char *buf) \ field##_show(struct device *dev, char *buf) \
{ \ { \
struct pci_dev *pdev; \ struct pci_dev *pdev; \
\ \
pdev = to_pci_dev (dev); \ pdev = to_pci_dev (dev); \
return sprintf (buf, format_string, pdev->field); \ 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(vendor, "0x%04x\n");
pci_config_attr(device, "0x%04x\n"); pci_config_attr(device, "0x%04x\n");
...@@ -41,7 +40,7 @@ pci_config_attr(irq, "%u\n"); ...@@ -41,7 +40,7 @@ pci_config_attr(irq, "%u\n");
/* show resources */ /* show resources */
static ssize_t 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); struct pci_dev * pci_dev = to_pci_dev(dev);
char * str = buf; char * str = buf;
...@@ -60,7 +59,16 @@ pci_show_resources(struct device * dev, char * buf) ...@@ -60,7 +59,16 @@ pci_show_resources(struct device * dev, char * buf)
return (str - 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 static ssize_t
pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count) 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 = { ...@@ -180,21 +188,10 @@ static struct bin_attribute pcie_config_attr = {
void pci_create_sysfs_dev_files (struct pci_dev *pdev) 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) 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 else
sysfs_create_bin_file(&dev->kobj, &pcie_config_attr); sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);
/* add platform-specific attributes */ /* add platform-specific attributes */
pcibios_add_platform_entries(pdev); pcibios_add_platform_entries(pdev);
......
...@@ -62,3 +62,4 @@ extern int pci_visit_dev(struct pci_visit *fn, ...@@ -62,3 +62,4 @@ extern int pci_visit_dev(struct pci_visit *fn,
extern spinlock_t pci_bus_lock; extern spinlock_t pci_bus_lock;
extern int pciehp_msi_quirk; extern int pciehp_msi_quirk;
extern struct device_attribute pci_dev_attrs[];
...@@ -1404,7 +1404,7 @@ static ssize_t sdebug_delay_store(struct device_driver * ddp, ...@@ -1404,7 +1404,7 @@ static ssize_t sdebug_delay_store(struct device_driver * ddp,
return -EINVAL; return -EINVAL;
} }
DRIVER_ATTR(delay, S_IRUGO | S_IWUSR, sdebug_delay_show, 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) static ssize_t sdebug_opts_show(struct device_driver * ddp, char * buf)
{ {
...@@ -1433,7 +1433,7 @@ static ssize_t sdebug_opts_store(struct device_driver * ddp, ...@@ -1433,7 +1433,7 @@ static ssize_t sdebug_opts_store(struct device_driver * ddp,
return count; return count;
} }
DRIVER_ATTR(opts, S_IRUGO | S_IWUSR, sdebug_opts_show, 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) static ssize_t sdebug_ptype_show(struct device_driver * ddp, char * buf)
{ {
...@@ -1450,7 +1450,7 @@ static ssize_t sdebug_ptype_store(struct device_driver * ddp, ...@@ -1450,7 +1450,7 @@ static ssize_t sdebug_ptype_store(struct device_driver * ddp,
} }
return -EINVAL; return -EINVAL;
} }
DRIVER_ATTR(ptype, S_IRUGO | S_IWUSR, sdebug_ptype_show, sdebug_ptype_store) DRIVER_ATTR(ptype, S_IRUGO | S_IWUSR, sdebug_ptype_show, sdebug_ptype_store);
static ssize_t sdebug_num_tgts_show(struct device_driver * ddp, char * buf) static ssize_t sdebug_num_tgts_show(struct device_driver * ddp, char * buf)
{ {
...@@ -1469,19 +1469,19 @@ static ssize_t sdebug_num_tgts_store(struct device_driver * ddp, ...@@ -1469,19 +1469,19 @@ static ssize_t sdebug_num_tgts_store(struct device_driver * ddp,
return -EINVAL; return -EINVAL;
} }
DRIVER_ATTR(num_tgts, S_IRUGO | S_IWUSR, sdebug_num_tgts_show, 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) 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); 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) static ssize_t sdebug_num_parts_show(struct device_driver * ddp, char * buf)
{ {
return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_num_parts); 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) 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, ...@@ -1500,7 +1500,7 @@ static ssize_t sdebug_every_nth_store(struct device_driver * ddp,
return -EINVAL; return -EINVAL;
} }
DRIVER_ATTR(every_nth, S_IRUGO | S_IWUSR, sdebug_every_nth_show, 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) 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, ...@@ -1519,13 +1519,13 @@ static ssize_t sdebug_max_luns_store(struct device_driver * ddp,
return -EINVAL; return -EINVAL;
} }
DRIVER_ATTR(max_luns, S_IRUGO | S_IWUSR, sdebug_max_luns_show, 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) static ssize_t sdebug_scsi_level_show(struct device_driver * ddp, char * buf)
{ {
return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_scsi_level); 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) 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, ...@@ -1562,7 +1562,7 @@ static ssize_t sdebug_add_host_store(struct device_driver * ddp,
return count; return count;
} }
DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show, 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) static void do_create_driverfs_files(void)
{ {
......
...@@ -99,7 +99,7 @@ show_##name (struct class_device *class_dev, char *buf) \ ...@@ -99,7 +99,7 @@ show_##name (struct class_device *class_dev, char *buf) \
*/ */
#define shost_rd_attr2(name, field, format_string) \ #define shost_rd_attr2(name, field, format_string) \
shost_show_function(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) \ #define shost_rd_attr(field, format_string) \
shost_rd_attr2(field, field, format_string) shost_rd_attr2(field, field, format_string)
...@@ -229,7 +229,7 @@ sdev_show_##field (struct device *dev, char *buf) \ ...@@ -229,7 +229,7 @@ sdev_show_##field (struct device *dev, char *buf) \
*/ */
#define sdev_rd_attr(field, format_string) \ #define sdev_rd_attr(field, format_string) \
sdev_show_function(field, format_string) \ sdev_show_function(field, format_string) \
static DEVICE_ATTR(field, S_IRUGO, sdev_show_##field, NULL) 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) \ ...@@ -247,7 +247,7 @@ sdev_store_##field (struct device *dev, const char *buf, size_t count) \
snscanf (buf, 20, format_string, &sdev->field); \ snscanf (buf, 20, format_string, &sdev->field); \
return count; \ 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, /* Currently we don't export bit fields, but we might in future,
* so leave this code in */ * so leave this code in */
...@@ -272,7 +272,7 @@ sdev_store_##field (struct device *dev, const char *buf, size_t count) \ ...@@ -272,7 +272,7 @@ sdev_store_##field (struct device *dev, const char *buf, size_t count) \
} \ } \
return ret; \ 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", * 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) ...@@ -320,7 +320,7 @@ sdev_store_timeout (struct device *dev, const char *buf, size_t count)
sdev->timeout = timeout * HZ; sdev->timeout = timeout * HZ;
return count; 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 static ssize_t
store_rescan_field (struct device *dev, const char *buf, size_t count) 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) ...@@ -328,7 +328,7 @@ store_rescan_field (struct device *dev, const char *buf, size_t count)
scsi_rescan_device(dev); scsi_rescan_device(dev);
return count; 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, static ssize_t sdev_store_delete(struct device *dev, const char *buf,
size_t count) size_t count)
......
...@@ -152,7 +152,7 @@ store_spi_transport_##field(struct class_device *cdev, const char *buf, \ ...@@ -152,7 +152,7 @@ store_spi_transport_##field(struct class_device *cdev, const char *buf, \
spi_transport_store_function(field, format_string) \ spi_transport_store_function(field, format_string) \
static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR, \ static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR, \
show_spi_transport_##field, \ show_spi_transport_##field, \
store_spi_transport_##field) store_spi_transport_##field);
/* The Parallel SCSI Tranport Attributes: */ /* The Parallel SCSI Tranport Attributes: */
spi_transport_rd_attr(offset, "%d\n"); spi_transport_rd_attr(offset, "%d\n");
......
...@@ -290,8 +290,11 @@ static void destroy_async (struct dev_state *ps, struct list_head *list) ...@@ -290,8 +290,11 @@ static void destroy_async (struct dev_state *ps, struct list_head *list)
spin_lock_irqsave(&ps->lock, flags); spin_lock_irqsave(&ps->lock, flags);
} }
spin_unlock_irqrestore(&ps->lock, flags); spin_unlock_irqrestore(&ps->lock, flags);
while ((as = async_getcompleted(ps))) as = async_getcompleted(ps);
while (as) {
free_async(as); free_async(as);
as = async_getcompleted(ps);
}
} }
static void destroy_async_on_interface (struct dev_state *ps, unsigned int ifnum) static void destroy_async_on_interface (struct dev_state *ps, unsigned int ifnum)
...@@ -968,29 +971,27 @@ static int proc_unlinkurb(struct dev_state *ps, void __user *arg) ...@@ -968,29 +971,27 @@ static int proc_unlinkurb(struct dev_state *ps, void __user *arg)
static int processcompl(struct async *as) static int processcompl(struct async *as)
{ {
struct urb *urb = as->urb; struct urb *urb = as->urb;
struct usbdevfs_urb __user *userurb = as->userurb;
unsigned int i; unsigned int i;
if (as->userbuffer) if (as->userbuffer)
if (copy_to_user(as->userbuffer, urb->transfer_buffer, urb->transfer_buffer_length)) if (copy_to_user(as->userbuffer, urb->transfer_buffer, urb->transfer_buffer_length))
return -EFAULT; return -EFAULT;
if (put_user(urb->status, if (put_user(urb->status, &userurb->status))
&((struct usbdevfs_urb *)as->userurb)->status))
return -EFAULT; return -EFAULT;
if (put_user(urb->actual_length, if (put_user(urb->actual_length, &userurb->actual_length))
&((struct usbdevfs_urb *)as->userurb)->actual_length))
return -EFAULT; return -EFAULT;
if (put_user(urb->error_count, if (put_user(urb->error_count, &userurb->error_count))
&((struct usbdevfs_urb *)as->userurb)->error_count))
return -EFAULT; return -EFAULT;
if (!(usb_pipeisoc(urb->pipe))) if (!(usb_pipeisoc(urb->pipe)))
return 0; return 0;
for (i = 0; i < urb->number_of_packets; i++) { for (i = 0; i < urb->number_of_packets; i++) {
if (put_user(urb->iso_frame_desc[i].actual_length, if (put_user(urb->iso_frame_desc[i].actual_length,
&((struct usbdevfs_urb *)as->userurb)->iso_frame_desc[i].actual_length)) &userurb->iso_frame_desc[i].actual_length))
return -EFAULT; return -EFAULT;
if (put_user(urb->iso_frame_desc[i].status, if (put_user(urb->iso_frame_desc[i].status,
&((struct usbdevfs_urb *)as->userurb)->iso_frame_desc[i].status)) &userurb->iso_frame_desc[i].status))
return -EFAULT; return -EFAULT;
} }
return 0; return 0;
......
...@@ -46,8 +46,13 @@ int sysfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *)) ...@@ -46,8 +46,13 @@ int sysfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *))
struct inode * inode = NULL; struct inode * inode = NULL;
if (dentry) { if (dentry) {
if (!dentry->d_inode) { 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; goto Proceed;
}
else else
error = -ENOMEM; error = -ENOMEM;
} else } else
......
...@@ -54,6 +54,9 @@ struct bus_type { ...@@ -54,6 +54,9 @@ struct bus_type {
struct kset drivers; struct kset drivers;
struct kset devices; struct kset devices;
struct bus_attribute * bus_attrs;
struct device_attribute * dev_attrs;
int (*match)(struct device * dev, struct device_driver * drv); int (*match)(struct device * dev, struct device_driver * drv);
struct device * (*add) (struct device * parent, char * bus_id); struct device * (*add) (struct device * parent, char * bus_id);
int (*hotplug) (struct device *dev, char **envp, int (*hotplug) (struct device *dev, char **envp,
...@@ -90,11 +93,7 @@ struct bus_attribute { ...@@ -90,11 +93,7 @@ struct bus_attribute {
}; };
#define BUS_ATTR(_name,_mode,_show,_store) \ #define BUS_ATTR(_name,_mode,_show,_store) \
struct bus_attribute bus_attr_##_name = { \ struct bus_attribute bus_attr_##_name = __ATTR(_name,_mode,_show,_store)
.attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
.show = _show, \
.store = _store, \
};
extern int bus_create_file(struct bus_type *, struct bus_attribute *); extern int bus_create_file(struct bus_type *, struct bus_attribute *);
extern void bus_remove_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 { ...@@ -131,11 +130,7 @@ struct driver_attribute {
}; };
#define DRIVER_ATTR(_name,_mode,_show,_store) \ #define DRIVER_ATTR(_name,_mode,_show,_store) \
struct driver_attribute driver_attr_##_name = { \ struct driver_attribute driver_attr_##_name = __ATTR(_name,_mode,_show,_store)
.attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
.show = _show, \
.store = _store, \
};
extern int driver_create_file(struct device_driver *, struct driver_attribute *); extern int driver_create_file(struct device_driver *, struct driver_attribute *);
extern void driver_remove_file(struct device_driver *, struct driver_attribute *); extern void driver_remove_file(struct device_driver *, struct driver_attribute *);
...@@ -151,6 +146,9 @@ struct class { ...@@ -151,6 +146,9 @@ struct class {
struct list_head children; struct list_head children;
struct list_head interfaces; 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 (*hotplug)(struct class_device *dev, char **envp,
int num_envp, char *buffer, int buffer_size); int num_envp, char *buffer, int buffer_size);
...@@ -172,11 +170,7 @@ struct class_attribute { ...@@ -172,11 +170,7 @@ struct class_attribute {
}; };
#define CLASS_ATTR(_name,_mode,_show,_store) \ #define CLASS_ATTR(_name,_mode,_show,_store) \
struct class_attribute class_attr_##_name = { \ struct class_attribute class_attr_##_name = __ATTR(_name,_mode,_show,_store)
.attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
.show = _show, \
.store = _store, \
};
extern int class_create_file(struct class *, const struct class_attribute *); extern int class_create_file(struct class *, const struct class_attribute *);
extern void class_remove_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 { ...@@ -224,11 +218,8 @@ struct class_device_attribute {
}; };
#define CLASS_DEVICE_ATTR(_name,_mode,_show,_store) \ #define CLASS_DEVICE_ATTR(_name,_mode,_show,_store) \
struct class_device_attribute class_device_attr_##_name = { \ struct class_device_attribute class_device_attr_##_name = \
.attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \ __ATTR(_name,_mode,_show,_store)
.show = _show, \
.store = _store, \
};
extern int class_device_create_file(struct class_device *, extern int class_device_create_file(struct class_device *,
const struct class_device_attribute *); const struct class_device_attribute *);
...@@ -342,11 +333,7 @@ struct device_attribute { ...@@ -342,11 +333,7 @@ struct device_attribute {
}; };
#define DEVICE_ATTR(_name,_mode,_show,_store) \ #define DEVICE_ATTR(_name,_mode,_show,_store) \
struct device_attribute dev_attr_##_name = { \ struct device_attribute dev_attr_##_name = __ATTR(_name,_mode,_show,_store)
.attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
.show = _show, \
.store = _store, \
};
extern int device_create_file(struct device *device, struct device_attribute * entry); extern int device_create_file(struct device *device, struct device_attribute * entry);
...@@ -390,6 +377,10 @@ extern void platform_device_unregister(struct platform_device *); ...@@ -390,6 +377,10 @@ extern void platform_device_unregister(struct platform_device *);
extern struct bus_type platform_bus_type; extern struct bus_type platform_bus_type;
extern struct device platform_bus; 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 */ /* drivers/base/power.c */
extern void device_shutdown(void); extern void device_shutdown(void);
......
...@@ -101,6 +101,14 @@ ...@@ -101,6 +101,14 @@
#define I2C_DRIVERID_UDA1342 53 /* UDA1342 audio codec */ #define I2C_DRIVERID_UDA1342 53 /* UDA1342 audio codec */
#define I2C_DRIVERID_ADV7170 54 /* video encoder */ #define I2C_DRIVERID_ADV7170 54 /* video encoder */
#define I2C_DRIVERID_RADEON 55 /* I2C bus on Radeon boards */ #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 */ #define I2C_DRIVERID_EXP0 0xF0 /* experimental use id's */
...@@ -264,6 +272,10 @@ ...@@ -264,6 +272,10 @@
#define I2C_HW_SMBUS_SCX200 0x0b #define I2C_HW_SMBUS_SCX200 0x0b
#define I2C_HW_SMBUS_NFORCE2 0x0c #define I2C_HW_SMBUS_NFORCE2 0x0c
#define I2C_HW_SMBUS_W9968CF 0x0d #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 */ /* --- ISA pseudo-adapter */
#define I2C_HW_ISA 0x00 #define I2C_HW_ISA 0x00
......
...@@ -225,6 +225,22 @@ struct module_kobject ...@@ -225,6 +225,22 @@ struct module_kobject
struct module_attribute attr[0]; 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 struct module
{ {
enum module_state state; enum module_state state;
...@@ -298,6 +314,9 @@ struct module ...@@ -298,6 +314,9 @@ struct module
Elf_Sym *symtab; Elf_Sym *symtab;
unsigned long num_symtab; unsigned long num_symtab;
char *strtab; char *strtab;
/* Section attributes */
struct module_sections *sect_attrs;
#endif #endif
/* Per-cpu data. */ /* Per-cpu data. */
......
...@@ -24,6 +24,27 @@ struct attribute_group { ...@@ -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 bin_attribute {
struct attribute attr; struct attribute attr;
size_t size; size_t size;
......
...@@ -980,6 +980,104 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs, ...@@ -980,6 +980,104 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
return ret; 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); #define to_module_attr(n) container_of(n, struct module_attribute, attr);
static ssize_t module_attr_show(struct kobject *kobj, static ssize_t module_attr_show(struct kobject *kobj,
...@@ -1098,6 +1196,7 @@ static void free_module(struct module *mod) ...@@ -1098,6 +1196,7 @@ static void free_module(struct module *mod)
list_del(&mod->list); list_del(&mod->list);
spin_unlock_irq(&modlist_lock); spin_unlock_irq(&modlist_lock);
remove_sect_attrs(mod);
mod_kobject_remove(mod); mod_kobject_remove(mod);
/* Arch-specific cleanup. */ /* Arch-specific cleanup. */
...@@ -1711,6 +1810,7 @@ static struct module *load_module(void __user *umod, ...@@ -1711,6 +1810,7 @@ static struct module *load_module(void __user *umod,
/ sizeof(struct kernel_param)); / sizeof(struct kernel_param));
if (err < 0) if (err < 0)
goto arch_cleanup; goto arch_cleanup;
add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
/* Get rid of temporary copy */ /* Get rid of temporary copy */
vfree(hdr); vfree(hdr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment