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