Skip to content

Commit

Permalink
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6
Browse files Browse the repository at this point in the history
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6: (46 commits)
  dev_dbg: check dev_dbg() arguments
  drivers/base/attribute_container.c: use mutex instead of binary semaphore
  mod_sysfs_setup() doesn't return errno when kobject_add_dir() failure occurs
  s2ram: add arch irq disable/enable hooks
  define platform wakeup hook, use in pci_enable_wake()
  security: prevent permission checking of file removal via sysfs_remove_group()
  device_schedule_callback() needs a module reference
  s390: cio: Delay uevents for subchannels
  sysfs: bin.c printk fix
  Driver core: use mutex instead of semaphore in DMA pool handler
  driver core: bus_add_driver should return an error if no bus
  debugfs: Add debugfs_create_u64()
  the overdue removal of the mount/umount uevents
  kobject: Comment and warning fixes to kobject.c
  Driver core: warn when userspace writes to the uevent file in a non-supported way
  Driver core: make uevent-environment available in uevent-file
  kobject core: remove rwsem from struct subsystem
  qeth: Remove usage of subsys.rwsem
  PHY: remove rwsem use from phy core
  IEEE1394: remove rwsem use from ieee1394 core
  ...
  • Loading branch information
Linus Torvalds committed Apr 27, 2007
2 parents a205752 + 404d5b1 commit d868772
Show file tree
Hide file tree
Showing 56 changed files with 854 additions and 544 deletions.
9 changes: 0 additions & 9 deletions Documentation/feature-removal-schedule.txt
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,6 @@ Who: Arjan van de Ven <arjan@linux.intel.com>

---------------------------

What: mount/umount uevents
When: February 2007
Why: These events are not correct, and do not properly let userspace know
when a file system has been mounted or unmounted. Userspace should
poll the /proc/mounts file instead to detect this properly.
Who: Greg Kroah-Hartman <gregkh@suse.de>

---------------------------

What: USB driver API moves to EXPORT_SYMBOL_GPL
When: February 2008
Files: include/linux/usb.h, drivers/usb/core/driver.c
Expand Down
3 changes: 0 additions & 3 deletions arch/powerpc/kernel/of_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,9 +475,6 @@ static struct of_platform_driver of_pci_phb_driver = {
.name = "of-pci",
.match_table = of_pci_phb_ids,
.probe = of_pci_phb_probe,
.driver = {
.multithread_probe = 1,
},
};

static __init int of_pci_phb_init(void)
Expand Down
13 changes: 6 additions & 7 deletions drivers/amba/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,13 @@ static int amba_match(struct device *dev, struct device_driver *drv)
static int amba_uevent(struct device *dev, char **envp, int nr_env, char *buf, int bufsz)
{
struct amba_device *pcdev = to_amba_device(dev);
int retval = 0, i = 0, len = 0;

if (nr_env < 2)
return -ENOMEM;

snprintf(buf, bufsz, "AMBA_ID=%08x", pcdev->periphid);
*envp++ = buf;
*envp++ = NULL;
return 0;
retval = add_uevent_var(envp, nr_env, &i,
buf, bufsz, &len,
"AMBA_ID=%08x", pcdev->periphid);
envp[i] = NULL;
return retval;
}
#else
#define amba_uevent NULL
Expand Down
26 changes: 13 additions & 13 deletions drivers/base/attribute_container.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ EXPORT_SYMBOL_GPL(attribute_container_classdev_to_container);

static struct list_head attribute_container_list;

static DECLARE_MUTEX(attribute_container_mutex);
static DEFINE_MUTEX(attribute_container_mutex);

/**
* attribute_container_register - register an attribute container
Expand All @@ -77,9 +77,9 @@ attribute_container_register(struct attribute_container *cont)
klist_init(&cont->containers,internal_container_klist_get,
internal_container_klist_put);

down(&attribute_container_mutex);
mutex_lock(&attribute_container_mutex);
list_add_tail(&cont->node, &attribute_container_list);
up(&attribute_container_mutex);
mutex_unlock(&attribute_container_mutex);

return 0;
}
Expand All @@ -94,15 +94,15 @@ int
attribute_container_unregister(struct attribute_container *cont)
{
int retval = -EBUSY;
down(&attribute_container_mutex);
mutex_lock(&attribute_container_mutex);
spin_lock(&cont->containers.k_lock);
if (!list_empty(&cont->containers.k_list))
goto out;
retval = 0;
list_del(&cont->node);
out:
spin_unlock(&cont->containers.k_lock);
up(&attribute_container_mutex);
mutex_unlock(&attribute_container_mutex);
return retval;

}
Expand Down Expand Up @@ -145,7 +145,7 @@ attribute_container_add_device(struct device *dev,
{
struct attribute_container *cont;

down(&attribute_container_mutex);
mutex_lock(&attribute_container_mutex);
list_for_each_entry(cont, &attribute_container_list, node) {
struct internal_container *ic;

Expand Down Expand Up @@ -173,7 +173,7 @@ attribute_container_add_device(struct device *dev,
attribute_container_add_class_device(&ic->classdev);
klist_add_tail(&ic->node, &cont->containers);
}
up(&attribute_container_mutex);
mutex_unlock(&attribute_container_mutex);
}

/* FIXME: can't break out of this unless klist_iter_exit is also
Expand Down Expand Up @@ -211,7 +211,7 @@ attribute_container_remove_device(struct device *dev,
{
struct attribute_container *cont;

down(&attribute_container_mutex);
mutex_lock(&attribute_container_mutex);
list_for_each_entry(cont, &attribute_container_list, node) {
struct internal_container *ic;
struct klist_iter iter;
Expand All @@ -234,7 +234,7 @@ attribute_container_remove_device(struct device *dev,
}
}
}
up(&attribute_container_mutex);
mutex_unlock(&attribute_container_mutex);
}

/**
Expand All @@ -255,7 +255,7 @@ attribute_container_device_trigger(struct device *dev,
{
struct attribute_container *cont;

down(&attribute_container_mutex);
mutex_lock(&attribute_container_mutex);
list_for_each_entry(cont, &attribute_container_list, node) {
struct internal_container *ic;
struct klist_iter iter;
Expand All @@ -273,7 +273,7 @@ attribute_container_device_trigger(struct device *dev,
fn(cont, dev, &ic->classdev);
}
}
up(&attribute_container_mutex);
mutex_unlock(&attribute_container_mutex);
}

/**
Expand All @@ -295,12 +295,12 @@ attribute_container_trigger(struct device *dev,
{
struct attribute_container *cont;

down(&attribute_container_mutex);
mutex_lock(&attribute_container_mutex);
list_for_each_entry(cont, &attribute_container_list, node) {
if (cont->match(cont, dev))
fn(cont, dev);
}
up(&attribute_container_mutex);
mutex_unlock(&attribute_container_mutex);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion drivers/base/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ extern int cpu_dev_init(void);
extern int attribute_container_init(void);

extern int bus_add_device(struct device * dev);
extern int bus_attach_device(struct device * dev);
extern void bus_attach_device(struct device * dev);
extern void bus_remove_device(struct device * dev);
extern struct bus_type *get_bus(struct bus_type * bus);
extern void put_bus(struct bus_type * bus);
Expand Down
112 changes: 96 additions & 16 deletions drivers/base/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
#define to_driver(obj) container_of(obj, struct device_driver, kobj)


static int __must_check bus_rescan_devices_helper(struct device *dev,
void *data);

static ssize_t
drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
{
Expand Down Expand Up @@ -60,8 +63,19 @@ static struct sysfs_ops driver_sysfs_ops = {

static void driver_release(struct kobject * kobj)
{
struct device_driver * drv = to_driver(kobj);
complete(&drv->unloaded);
/*
* Yes this is an empty release function, it is this way because struct
* device is always a static object, not a dynamic one. Yes, this is
* not nice and bad, but remember, drivers are code, reference counted
* by the module count, not a device, which is really data. And yes,
* in the future I do want to have all drivers be created dynamically,
* and am working toward that goal, but it will take a bit longer...
*
* But do not let this example give _anyone_ the idea that they can
* create a release function without any code in it at all, to do that
* is almost always wrong. If you have any questions about this,
* please send an email to <greg@kroah.com>
*/
}

static struct kobj_type ktype_driver = {
Expand Down Expand Up @@ -133,7 +147,6 @@ static decl_subsys(bus, &ktype_bus, NULL);


#ifdef CONFIG_HOTPLUG

/* Manually detach a device from its associated driver. */
static int driver_helper(struct device *dev, void *data)
{
Expand Down Expand Up @@ -199,6 +212,33 @@ static ssize_t driver_bind(struct device_driver *drv,
}
static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind);

static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf)
{
return sprintf(buf, "%d\n", bus->drivers_autoprobe);
}

static ssize_t store_drivers_autoprobe(struct bus_type *bus,
const char *buf, size_t count)
{
if (buf[0] == '0')
bus->drivers_autoprobe = 0;
else
bus->drivers_autoprobe = 1;
return count;
}

static ssize_t store_drivers_probe(struct bus_type *bus,
const char *buf, size_t count)
{
struct device *dev;

dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
if (!dev)
return -ENODEV;
if (bus_rescan_devices_helper(dev, NULL) != 0)
return -EINVAL;
return count;
}
#endif

static struct device * next_device(struct klist_iter * i)
Expand Down Expand Up @@ -418,21 +458,21 @@ int bus_add_device(struct device * dev)
* - Add device to bus's list of devices.
* - Try to attach to driver.
*/
int bus_attach_device(struct device * dev)
void bus_attach_device(struct device * dev)
{
struct bus_type *bus = dev->bus;
int ret = 0;

if (bus) {
dev->is_registered = 1;
ret = device_attach(dev);
if (ret >= 0) {
if (bus->drivers_autoprobe)
ret = device_attach(dev);
WARN_ON(ret < 0);
if (ret >= 0)
klist_add_tail(&dev->knode_bus, &bus->klist_devices);
ret = 0;
} else
else
dev->is_registered = 0;
}
return ret;
}

/**
Expand Down Expand Up @@ -515,9 +555,41 @@ static void remove_bind_files(struct device_driver *drv)
driver_remove_file(drv, &driver_attr_bind);
driver_remove_file(drv, &driver_attr_unbind);
}

static int add_probe_files(struct bus_type *bus)
{
int retval;

bus->drivers_probe_attr.attr.name = "drivers_probe";
bus->drivers_probe_attr.attr.mode = S_IWUSR;
bus->drivers_probe_attr.attr.owner = bus->owner;
bus->drivers_probe_attr.store = store_drivers_probe;
retval = bus_create_file(bus, &bus->drivers_probe_attr);
if (retval)
goto out;

bus->drivers_autoprobe_attr.attr.name = "drivers_autoprobe";
bus->drivers_autoprobe_attr.attr.mode = S_IWUSR | S_IRUGO;
bus->drivers_autoprobe_attr.attr.owner = bus->owner;
bus->drivers_autoprobe_attr.show = show_drivers_autoprobe;
bus->drivers_autoprobe_attr.store = store_drivers_autoprobe;
retval = bus_create_file(bus, &bus->drivers_autoprobe_attr);
if (retval)
bus_remove_file(bus, &bus->drivers_probe_attr);
out:
return retval;
}

static void remove_probe_files(struct bus_type *bus)
{
bus_remove_file(bus, &bus->drivers_autoprobe_attr);
bus_remove_file(bus, &bus->drivers_probe_attr);
}
#else
static inline int add_bind_files(struct device_driver *drv) { return 0; }
static inline void remove_bind_files(struct device_driver *drv) {}
static inline int add_probe_files(struct bus_type *bus) { return 0; }
static inline void remove_probe_files(struct bus_type *bus) {}
#endif

/**
Expand All @@ -531,7 +603,7 @@ int bus_add_driver(struct device_driver *drv)
int error = 0;

if (!bus)
return 0;
return -EINVAL;

pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
error = kobject_set_name(&drv->kobj, "%s", drv->name);
Expand All @@ -541,9 +613,11 @@ int bus_add_driver(struct device_driver *drv)
if ((error = kobject_register(&drv->kobj)))
goto out_put_bus;

error = driver_attach(drv);
if (error)
goto out_unregister;
if (drv->bus->drivers_autoprobe) {
error = driver_attach(drv);
if (error)
goto out_unregister;
}
klist_add_tail(&drv->knode_bus, &bus->klist_drivers);
module_add_driver(drv->owner, drv);

Expand Down Expand Up @@ -605,8 +679,6 @@ static int __must_check bus_rescan_devices_helper(struct device *dev,
ret = device_attach(dev);
if (dev->parent)
up(&dev->parent->sem);
if (ret > 0)
ret = 0;
}
return ret < 0 ? ret : 0;
}
Expand Down Expand Up @@ -762,6 +834,12 @@ int bus_register(struct bus_type * bus)

klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put);
klist_init(&bus->klist_drivers, NULL, NULL);

bus->drivers_autoprobe = 1;
retval = add_probe_files(bus);
if (retval)
goto bus_probe_files_fail;

retval = bus_add_attrs(bus);
if (retval)
goto bus_attrs_fail;
Expand All @@ -770,6 +848,8 @@ int bus_register(struct bus_type * bus)
return 0;

bus_attrs_fail:
remove_probe_files(bus);
bus_probe_files_fail:
kset_unregister(&bus->drivers);
bus_drivers_fail:
kset_unregister(&bus->devices);
Expand All @@ -779,7 +859,6 @@ int bus_register(struct bus_type * bus)
return retval;
}


/**
* bus_unregister - remove a bus from the system
* @bus: bus.
Expand All @@ -791,6 +870,7 @@ void bus_unregister(struct bus_type * bus)
{
pr_debug("bus %s: unregistering\n", bus->name);
bus_remove_attrs(bus);
remove_probe_files(bus);
kset_unregister(&bus->drivers);
kset_unregister(&bus->devices);
subsystem_unregister(&bus->subsys);
Expand Down
2 changes: 1 addition & 1 deletion drivers/base/class.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ int class_register(struct class * cls)
INIT_LIST_HEAD(&cls->children);
INIT_LIST_HEAD(&cls->devices);
INIT_LIST_HEAD(&cls->interfaces);
kset_init(&cls->class_dirs);
init_MUTEX(&cls->sem);
error = kobject_set_name(&cls->subsys.kset.kobj, "%s", cls->name);
if (error)
Expand All @@ -163,7 +164,6 @@ int class_register(struct class * cls)
void class_unregister(struct class * cls)
{
pr_debug("device class '%s': unregistering\n", cls->name);
kobject_unregister(cls->virtual_dir);
remove_class_attrs(cls);
subsystem_unregister(&cls->subsys);
}
Expand Down
Loading

0 comments on commit d868772

Please sign in to comment.