diff options
Diffstat (limited to 'libdde_linux26/contrib/drivers/base')
-rw-r--r-- | libdde_linux26/contrib/drivers/base/attribute_container.c | 440 | ||||
-rw-r--r-- | libdde_linux26/contrib/drivers/base/base.h | 105 | ||||
-rw-r--r-- | libdde_linux26/contrib/drivers/base/bus.c | 1039 | ||||
-rw-r--r-- | libdde_linux26/contrib/drivers/base/cpu.c | 250 | ||||
-rw-r--r-- | libdde_linux26/contrib/drivers/base/dd.c | 383 | ||||
-rw-r--r-- | libdde_linux26/contrib/drivers/base/devres.c | 646 | ||||
-rw-r--r-- | libdde_linux26/contrib/drivers/base/driver.c | 277 | ||||
-rw-r--r-- | libdde_linux26/contrib/drivers/base/map.c | 155 | ||||
-rw-r--r-- | libdde_linux26/contrib/drivers/base/platform.c | 988 | ||||
-rw-r--r-- | libdde_linux26/contrib/drivers/base/power/power.h | 49 | ||||
-rw-r--r-- | libdde_linux26/contrib/drivers/base/sys.c | 525 |
11 files changed, 0 insertions, 4857 deletions
diff --git a/libdde_linux26/contrib/drivers/base/attribute_container.c b/libdde_linux26/contrib/drivers/base/attribute_container.c deleted file mode 100644 index b9cda053..00000000 --- a/libdde_linux26/contrib/drivers/base/attribute_container.c +++ /dev/null @@ -1,440 +0,0 @@ -/* - * attribute_container.c - implementation of a simple container for classes - * - * Copyright (c) 2005 - James Bottomley <James.Bottomley@steeleye.com> - * - * This file is licensed under GPLv2 - * - * The basic idea here is to enable a device to be attached to an - * aritrary numer of classes without having to allocate storage for them. - * Instead, the contained classes select the devices they need to attach - * to via a matching function. - */ - -#include <linux/attribute_container.h> -#include <linux/init.h> -#include <linux/device.h> -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/list.h> -#include <linux/module.h> -#include <linux/mutex.h> - -#include "base.h" - -/* This is a private structure used to tie the classdev and the - * container .. it should never be visible outside this file */ -struct internal_container { - struct klist_node node; - struct attribute_container *cont; - struct device classdev; -}; - -static void internal_container_klist_get(struct klist_node *n) -{ - struct internal_container *ic = - container_of(n, struct internal_container, node); - get_device(&ic->classdev); -} - -static void internal_container_klist_put(struct klist_node *n) -{ - struct internal_container *ic = - container_of(n, struct internal_container, node); - put_device(&ic->classdev); -} - - -/** - * attribute_container_classdev_to_container - given a classdev, return the container - * - * @classdev: the class device created by attribute_container_add_device. - * - * Returns the container associated with this classdev. - */ -struct attribute_container * -attribute_container_classdev_to_container(struct device *classdev) -{ - struct internal_container *ic = - container_of(classdev, struct internal_container, classdev); - return ic->cont; -} -EXPORT_SYMBOL_GPL(attribute_container_classdev_to_container); - -static LIST_HEAD(attribute_container_list); - -static DEFINE_MUTEX(attribute_container_mutex); - -/** - * attribute_container_register - register an attribute container - * - * @cont: The container to register. This must be allocated by the - * callee and should also be zeroed by it. - */ -int -attribute_container_register(struct attribute_container *cont) -{ - INIT_LIST_HEAD(&cont->node); - klist_init(&cont->containers,internal_container_klist_get, - internal_container_klist_put); - - mutex_lock(&attribute_container_mutex); - list_add_tail(&cont->node, &attribute_container_list); - mutex_unlock(&attribute_container_mutex); - - return 0; -} -EXPORT_SYMBOL_GPL(attribute_container_register); - -/** - * attribute_container_unregister - remove a container registration - * - * @cont: previously registered container to remove - */ -int -attribute_container_unregister(struct attribute_container *cont) -{ - int retval = -EBUSY; - 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); - mutex_unlock(&attribute_container_mutex); - return retval; - -} -EXPORT_SYMBOL_GPL(attribute_container_unregister); - -/* private function used as class release */ -static void attribute_container_release(struct device *classdev) -{ - struct internal_container *ic - = container_of(classdev, struct internal_container, classdev); - struct device *dev = classdev->parent; - - kfree(ic); - put_device(dev); -} - -/** - * attribute_container_add_device - see if any container is interested in dev - * - * @dev: device to add attributes to - * @fn: function to trigger addition of class device. - * - * This function allocates storage for the class device(s) to be - * attached to dev (one for each matching attribute_container). If no - * fn is provided, the code will simply register the class device via - * device_add. If a function is provided, it is expected to add - * the class device at the appropriate time. One of the things that - * might be necessary is to allocate and initialise the classdev and - * then add it a later time. To do this, call this routine for - * allocation and initialisation and then use - * attribute_container_device_trigger() to call device_add() on - * it. Note: after this, the class device contains a reference to dev - * which is not relinquished until the release of the classdev. - */ -void -attribute_container_add_device(struct device *dev, - int (*fn)(struct attribute_container *, - struct device *, - struct device *)) -{ - struct attribute_container *cont; - - mutex_lock(&attribute_container_mutex); - list_for_each_entry(cont, &attribute_container_list, node) { - struct internal_container *ic; - - if (attribute_container_no_classdevs(cont)) - continue; - - if (!cont->match(cont, dev)) - continue; - - ic = kzalloc(sizeof(*ic), GFP_KERNEL); - if (!ic) { - dev_printk(KERN_ERR, dev, "failed to allocate class container\n"); - continue; - } - - ic->cont = cont; - device_initialize(&ic->classdev); - ic->classdev.parent = get_device(dev); - ic->classdev.class = cont->class; - cont->class->dev_release = attribute_container_release; - dev_set_name(&ic->classdev, dev_name(dev)); - if (fn) - fn(cont, dev, &ic->classdev); - else - attribute_container_add_class_device(&ic->classdev); - klist_add_tail(&ic->node, &cont->containers); - } - mutex_unlock(&attribute_container_mutex); -} - -/* FIXME: can't break out of this unless klist_iter_exit is also - * called before doing the break - */ -#define klist_for_each_entry(pos, head, member, iter) \ - for (klist_iter_init(head, iter); (pos = ({ \ - struct klist_node *n = klist_next(iter); \ - n ? container_of(n, typeof(*pos), member) : \ - ({ klist_iter_exit(iter) ; NULL; }); \ - }) ) != NULL; ) - - -/** - * attribute_container_remove_device - make device eligible for removal. - * - * @dev: The generic device - * @fn: A function to call to remove the device - * - * This routine triggers device removal. If fn is NULL, then it is - * simply done via device_unregister (note that if something - * still has a reference to the classdev, then the memory occupied - * will not be freed until the classdev is released). If you want a - * two phase release: remove from visibility and then delete the - * device, then you should use this routine with a fn that calls - * device_del() and then use attribute_container_device_trigger() - * to do the final put on the classdev. - */ -void -attribute_container_remove_device(struct device *dev, - void (*fn)(struct attribute_container *, - struct device *, - struct device *)) -{ - struct attribute_container *cont; - - mutex_lock(&attribute_container_mutex); - list_for_each_entry(cont, &attribute_container_list, node) { - struct internal_container *ic; - struct klist_iter iter; - - if (attribute_container_no_classdevs(cont)) - continue; - - if (!cont->match(cont, dev)) - continue; - - klist_for_each_entry(ic, &cont->containers, node, &iter) { - if (dev != ic->classdev.parent) - continue; - klist_del(&ic->node); - if (fn) - fn(cont, dev, &ic->classdev); - else { - attribute_container_remove_attrs(&ic->classdev); - device_unregister(&ic->classdev); - } - } - } - mutex_unlock(&attribute_container_mutex); -} - -/** - * attribute_container_device_trigger - execute a trigger for each matching classdev - * - * @dev: The generic device to run the trigger for - * @fn the function to execute for each classdev. - * - * This funcion is for executing a trigger when you need to know both - * the container and the classdev. If you only care about the - * container, then use attribute_container_trigger() instead. - */ -void -attribute_container_device_trigger(struct device *dev, - int (*fn)(struct attribute_container *, - struct device *, - struct device *)) -{ - struct attribute_container *cont; - - mutex_lock(&attribute_container_mutex); - list_for_each_entry(cont, &attribute_container_list, node) { - struct internal_container *ic; - struct klist_iter iter; - - if (!cont->match(cont, dev)) - continue; - - if (attribute_container_no_classdevs(cont)) { - fn(cont, dev, NULL); - continue; - } - - klist_for_each_entry(ic, &cont->containers, node, &iter) { - if (dev == ic->classdev.parent) - fn(cont, dev, &ic->classdev); - } - } - mutex_unlock(&attribute_container_mutex); -} - -/** - * attribute_container_trigger - trigger a function for each matching container - * - * @dev: The generic device to activate the trigger for - * @fn: the function to trigger - * - * This routine triggers a function that only needs to know the - * matching containers (not the classdev) associated with a device. - * It is more lightweight than attribute_container_device_trigger, so - * should be used in preference unless the triggering function - * actually needs to know the classdev. - */ -void -attribute_container_trigger(struct device *dev, - int (*fn)(struct attribute_container *, - struct device *)) -{ - struct attribute_container *cont; - - mutex_lock(&attribute_container_mutex); - list_for_each_entry(cont, &attribute_container_list, node) { - if (cont->match(cont, dev)) - fn(cont, dev); - } - mutex_unlock(&attribute_container_mutex); -} - -/** - * attribute_container_add_attrs - add attributes - * - * @classdev: The class device - * - * This simply creates all the class device sysfs files from the - * attributes listed in the container - */ -int -attribute_container_add_attrs(struct device *classdev) -{ - struct attribute_container *cont = - attribute_container_classdev_to_container(classdev); - struct device_attribute **attrs = cont->attrs; - int i, error; - - BUG_ON(attrs && cont->grp); - - if (!attrs && !cont->grp) - return 0; - - if (cont->grp) - return sysfs_create_group(&classdev->kobj, cont->grp); - - for (i = 0; attrs[i]; i++) { - error = device_create_file(classdev, attrs[i]); - if (error) - return error; - } - - return 0; -} - -/** - * attribute_container_add_class_device - same function as device_add - * - * @classdev: the class device to add - * - * This performs essentially the same function as device_add except for - * attribute containers, namely add the classdev to the system and then - * create the attribute files - */ -int -attribute_container_add_class_device(struct device *classdev) -{ - int error = device_add(classdev); - if (error) - return error; - return attribute_container_add_attrs(classdev); -} - -/** - * attribute_container_add_class_device_adapter - simple adapter for triggers - * - * This function is identical to attribute_container_add_class_device except - * that it is designed to be called from the triggers - */ -int -attribute_container_add_class_device_adapter(struct attribute_container *cont, - struct device *dev, - struct device *classdev) -{ - return attribute_container_add_class_device(classdev); -} - -/** - * attribute_container_remove_attrs - remove any attribute files - * - * @classdev: The class device to remove the files from - * - */ -void -attribute_container_remove_attrs(struct device *classdev) -{ - struct attribute_container *cont = - attribute_container_classdev_to_container(classdev); - struct device_attribute **attrs = cont->attrs; - int i; - - if (!attrs && !cont->grp) - return; - - if (cont->grp) { - sysfs_remove_group(&classdev->kobj, cont->grp); - return ; - } - - for (i = 0; attrs[i]; i++) - device_remove_file(classdev, attrs[i]); -} - -/** - * attribute_container_class_device_del - equivalent of class_device_del - * - * @classdev: the class device - * - * This function simply removes all the attribute files and then calls - * device_del. - */ -void -attribute_container_class_device_del(struct device *classdev) -{ - attribute_container_remove_attrs(classdev); - device_del(classdev); -} - -/** - * attribute_container_find_class_device - find the corresponding class_device - * - * @cont: the container - * @dev: the generic device - * - * Looks up the device in the container's list of class devices and returns - * the corresponding class_device. - */ -struct device * -attribute_container_find_class_device(struct attribute_container *cont, - struct device *dev) -{ - struct device *cdev = NULL; - struct internal_container *ic; - struct klist_iter iter; - - klist_for_each_entry(ic, &cont->containers, node, &iter) { - if (ic->classdev.parent == dev) { - cdev = &ic->classdev; - /* FIXME: must exit iterator then break */ - klist_iter_exit(&iter); - break; - } - } - - return cdev; -} -EXPORT_SYMBOL_GPL(attribute_container_find_class_device); diff --git a/libdde_linux26/contrib/drivers/base/base.h b/libdde_linux26/contrib/drivers/base/base.h deleted file mode 100644 index 9f50f1b5..00000000 --- a/libdde_linux26/contrib/drivers/base/base.h +++ /dev/null @@ -1,105 +0,0 @@ - -/** - * struct bus_type_private - structure to hold the private to the driver core portions of the bus_type structure. - * - * @subsys - the struct kset that defines this bus. This is the main kobject - * @drivers_kset - the list of drivers associated with this bus - * @devices_kset - the list of devices associated with this bus - * @klist_devices - the klist to iterate over the @devices_kset - * @klist_drivers - the klist to iterate over the @drivers_kset - * @bus_notifier - the bus notifier list for anything that cares about things - * on this bus. - * @bus - pointer back to the struct bus_type that this structure is associated - * with. - * - * This structure is the one that is the actual kobject allowing struct - * bus_type to be statically allocated safely. Nothing outside of the driver - * core should ever touch these fields. - */ -struct bus_type_private { - struct kset subsys; - struct kset *drivers_kset; - struct kset *devices_kset; - struct klist klist_devices; - struct klist klist_drivers; - struct blocking_notifier_head bus_notifier; - unsigned int drivers_autoprobe:1; - struct bus_type *bus; -}; - -struct driver_private { - struct kobject kobj; - struct klist klist_devices; - struct klist_node knode_bus; - struct module_kobject *mkobj; - struct device_driver *driver; -}; -#define to_driver(obj) container_of(obj, struct driver_private, kobj) - - -/** - * struct class_private - structure to hold the private to the driver core portions of the class structure. - * - * @class_subsys - the struct kset that defines this class. This is the main kobject - * @class_devices - list of devices associated with this class - * @class_interfaces - list of class_interfaces associated with this class - * @class_dirs - "glue" directory for virtual devices associated with this class - * @class_mutex - mutex to protect the children, devices, and interfaces lists. - * @class - pointer back to the struct class that this structure is associated - * with. - * - * This structure is the one that is the actual kobject allowing struct - * class to be statically allocated safely. Nothing outside of the driver - * core should ever touch these fields. - */ -struct class_private { - struct kset class_subsys; - struct klist class_devices; - struct list_head class_interfaces; - struct kset class_dirs; - struct mutex class_mutex; - struct class *class; -}; -#define to_class(obj) \ - container_of(obj, struct class_private, class_subsys.kobj) - -/* initialisation functions */ -extern int devices_init(void); -extern int buses_init(void); -extern int classes_init(void); -extern int firmware_init(void); -#ifdef CONFIG_SYS_HYPERVISOR -extern int hypervisor_init(void); -#else -static inline int hypervisor_init(void) { return 0; } -#endif -extern int platform_bus_init(void); -extern int system_bus_init(void); -extern int cpu_dev_init(void); - -extern int bus_add_device(struct device *dev); -extern void bus_attach_device(struct device *dev); -extern void bus_remove_device(struct device *dev); - -extern int bus_add_driver(struct device_driver *drv); -extern void bus_remove_driver(struct device_driver *drv); - -extern void driver_detach(struct device_driver *drv); -extern int driver_probe_device(struct device_driver *drv, struct device *dev); - -extern void sysdev_shutdown(void); - -extern char *make_class_name(const char *name, struct kobject *kobj); - -extern int devres_release_all(struct device *dev); - -extern struct kset *devices_kset; - -#if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS) -extern void module_add_driver(struct module *mod, struct device_driver *drv); -extern void module_remove_driver(struct device_driver *drv); -#else -static inline void module_add_driver(struct module *mod, - struct device_driver *drv) { } -static inline void module_remove_driver(struct device_driver *drv) { } -#endif diff --git a/libdde_linux26/contrib/drivers/base/bus.c b/libdde_linux26/contrib/drivers/base/bus.c deleted file mode 100644 index 83f32b89..00000000 --- a/libdde_linux26/contrib/drivers/base/bus.c +++ /dev/null @@ -1,1039 +0,0 @@ -/* - * bus.c - bus driver management - * - * Copyright (c) 2002-3 Patrick Mochel - * Copyright (c) 2002-3 Open Source Development Labs - * Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de> - * Copyright (c) 2007 Novell Inc. - * - * This file is released under the GPLv2 - * - */ - -#include <linux/device.h> -#include <linux/module.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/string.h> -#include "base.h" -#include "power/power.h" - -#define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr) -#define to_bus(obj) container_of(obj, struct bus_type_private, subsys.kobj) - -/* - * sysfs bindings for drivers - */ - -#define to_drv_attr(_attr) container_of(_attr, struct driver_attribute, attr) - - -static int __must_check bus_rescan_devices_helper(struct device *dev, - void *data); - -static struct bus_type *bus_get(struct bus_type *bus) -{ - if (bus) { - kset_get(&bus->p->subsys); - return bus; - } - return NULL; -} - -static void bus_put(struct bus_type *bus) -{ - if (bus) - kset_put(&bus->p->subsys); -} - -static ssize_t drv_attr_show(struct kobject *kobj, struct attribute *attr, - char *buf) -{ - struct driver_attribute *drv_attr = to_drv_attr(attr); - struct driver_private *drv_priv = to_driver(kobj); - ssize_t ret = -EIO; - - if (drv_attr->show) - ret = drv_attr->show(drv_priv->driver, buf); - return ret; -} - -static ssize_t drv_attr_store(struct kobject *kobj, struct attribute *attr, - const char *buf, size_t count) -{ - struct driver_attribute *drv_attr = to_drv_attr(attr); - struct driver_private *drv_priv = to_driver(kobj); - ssize_t ret = -EIO; - - if (drv_attr->store) - ret = drv_attr->store(drv_priv->driver, buf, count); - return ret; -} - -static struct sysfs_ops driver_sysfs_ops = { - .show = drv_attr_show, - .store = drv_attr_store, -}; - -static void driver_release(struct kobject *kobj) -{ - struct driver_private *drv_priv = to_driver(kobj); - - pr_debug("driver: '%s': %s\n", kobject_name(kobj), __func__); - kfree(drv_priv); -} - -static struct kobj_type driver_ktype = { - .sysfs_ops = &driver_sysfs_ops, - .release = driver_release, -}; - -/* - * sysfs bindings for buses - */ -static ssize_t bus_attr_show(struct kobject *kobj, struct attribute *attr, - char *buf) -{ - struct bus_attribute *bus_attr = to_bus_attr(attr); - struct bus_type_private *bus_priv = to_bus(kobj); - ssize_t ret = 0; - - if (bus_attr->show) - ret = bus_attr->show(bus_priv->bus, buf); - return ret; -} - -static ssize_t bus_attr_store(struct kobject *kobj, struct attribute *attr, - const char *buf, size_t count) -{ - struct bus_attribute *bus_attr = to_bus_attr(attr); - struct bus_type_private *bus_priv = to_bus(kobj); - ssize_t ret = 0; - - if (bus_attr->store) - ret = bus_attr->store(bus_priv->bus, buf, count); - return ret; -} - -static struct sysfs_ops bus_sysfs_ops = { - .show = bus_attr_show, - .store = bus_attr_store, -}; - -int bus_create_file(struct bus_type *bus, struct bus_attribute *attr) -{ - int error; - if (bus_get(bus)) { - error = sysfs_create_file(&bus->p->subsys.kobj, &attr->attr); - bus_put(bus); - } else - error = -EINVAL; - return error; -} -EXPORT_SYMBOL_GPL(bus_create_file); - -void bus_remove_file(struct bus_type *bus, struct bus_attribute *attr) -{ - if (bus_get(bus)) { - sysfs_remove_file(&bus->p->subsys.kobj, &attr->attr); - bus_put(bus); - } -} -EXPORT_SYMBOL_GPL(bus_remove_file); - -static struct kobj_type bus_ktype = { - .sysfs_ops = &bus_sysfs_ops, -}; - -static int bus_uevent_filter(struct kset *kset, struct kobject *kobj) -{ - struct kobj_type *ktype = get_ktype(kobj); - - if (ktype == &bus_ktype) - return 1; - return 0; -} - -static struct kset_uevent_ops bus_uevent_ops = { - .filter = bus_uevent_filter, -}; - -static struct kset *bus_kset; - - -#ifdef CONFIG_HOTPLUG -/* Manually detach a device from its associated driver. */ -static ssize_t driver_unbind(struct device_driver *drv, - const char *buf, size_t count) -{ - struct bus_type *bus = bus_get(drv->bus); - struct device *dev; - int err = -ENODEV; - - dev = bus_find_device_by_name(bus, NULL, buf); - if (dev && dev->driver == drv) { - if (dev->parent) /* Needed for USB */ - down(&dev->parent->sem); - device_release_driver(dev); - if (dev->parent) - up(&dev->parent->sem); - err = count; - } - put_device(dev); - bus_put(bus); - return err; -} -static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind); - -/* - * Manually attach a device to a driver. - * Note: the driver must want to bind to the device, - * it is not possible to override the driver's id table. - */ -static ssize_t driver_bind(struct device_driver *drv, - const char *buf, size_t count) -{ - struct bus_type *bus = bus_get(drv->bus); - struct device *dev; - int err = -ENODEV; - - dev = bus_find_device_by_name(bus, NULL, buf); - if (dev && dev->driver == NULL) { - if (dev->parent) /* Needed for USB */ - down(&dev->parent->sem); - down(&dev->sem); - err = driver_probe_device(drv, dev); - up(&dev->sem); - if (dev->parent) - up(&dev->parent->sem); - - if (err > 0) { - /* success */ - err = count; - } else if (err == 0) { - /* driver didn't accept device */ - err = -ENODEV; - } - } - put_device(dev); - bus_put(bus); - return err; -} -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->p->drivers_autoprobe); -} - -static ssize_t store_drivers_autoprobe(struct bus_type *bus, - const char *buf, size_t count) -{ - if (buf[0] == '0') - bus->p->drivers_autoprobe = 0; - else - bus->p->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_by_name(bus, NULL, buf); - 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) -{ - struct klist_node *n = klist_next(i); - return n ? container_of(n, struct device, knode_bus) : NULL; -} - -/** - * bus_for_each_dev - device iterator. - * @bus: bus type. - * @start: device to start iterating from. - * @data: data for the callback. - * @fn: function to be called for each device. - * - * Iterate over @bus's list of devices, and call @fn for each, - * passing it @data. If @start is not NULL, we use that device to - * begin iterating from. - * - * We check the return of @fn each time. If it returns anything - * other than 0, we break out and return that value. - * - * 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 - * count in the supplied callback. - */ -int bus_for_each_dev(struct bus_type *bus, struct device *start, - void *data, int (*fn)(struct device *, void *)) -{ - struct klist_iter i; - struct device *dev; - int error = 0; - - if (!bus) - return -EINVAL; - - klist_iter_init_node(&bus->p->klist_devices, &i, - (start ? &start->knode_bus : NULL)); - while ((dev = next_device(&i)) && !error) - error = fn(dev, data); - klist_iter_exit(&i); - return error; -} -EXPORT_SYMBOL_GPL(bus_for_each_dev); - -/** - * bus_find_device - device iterator for locating a particular device. - * @bus: bus type - * @start: Device to begin with - * @data: Data to pass to match function - * @match: Callback function to check device - * - * This is similar to the bus_for_each_dev() function above, but it - * returns a reference to a device that is 'found' for later use, as - * determined by the @match callback. - * - * The callback should return 0 if the device doesn't match and non-zero - * if it does. If the callback returns non-zero, this function will - * return to the caller and not iterate over any more devices. - */ -struct device *bus_find_device(struct bus_type *bus, - struct device *start, void *data, - int (*match)(struct device *dev, void *data)) -{ - struct klist_iter i; - struct device *dev; - - if (!bus) - return NULL; - - klist_iter_init_node(&bus->p->klist_devices, &i, - (start ? &start->knode_bus : NULL)); - while ((dev = next_device(&i))) - if (match(dev, data) && get_device(dev)) - break; - klist_iter_exit(&i); - return dev; -} -EXPORT_SYMBOL_GPL(bus_find_device); - -static int match_name(struct device *dev, void *data) -{ - const char *name = data; - - return sysfs_streq(name, dev_name(dev)); -} - -/** - * bus_find_device_by_name - device iterator for locating a particular device of a specific name - * @bus: bus type - * @start: Device to begin with - * @name: name of the device to match - * - * This is similar to the bus_find_device() function above, but it handles - * searching by a name automatically, no need to write another strcmp matching - * function. - */ -struct device *bus_find_device_by_name(struct bus_type *bus, - struct device *start, const char *name) -{ - return bus_find_device(bus, start, (void *)name, match_name); -} -EXPORT_SYMBOL_GPL(bus_find_device_by_name); - -static struct device_driver *next_driver(struct klist_iter *i) -{ - struct klist_node *n = klist_next(i); - struct driver_private *drv_priv; - - if (n) { - drv_priv = container_of(n, struct driver_private, knode_bus); - return drv_priv->driver; - } - return NULL; -} - -/** - * bus_for_each_drv - driver iterator - * @bus: bus we're dealing with. - * @start: driver to start iterating on. - * @data: data to pass to the callback. - * @fn: function to call for each driver. - * - * This is nearly identical to the device iterator above. - * We iterate over each driver that belongs to @bus, and call - * @fn for each. If @fn returns anything but 0, we break out - * 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 - * 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 - * so it doesn't disappear before returning to the caller. - */ -int bus_for_each_drv(struct bus_type *bus, struct device_driver *start, - void *data, int (*fn)(struct device_driver *, void *)) -{ - struct klist_iter i; - struct device_driver *drv; - int error = 0; - - if (!bus) - return -EINVAL; - - klist_iter_init_node(&bus->p->klist_drivers, &i, - start ? &start->p->knode_bus : NULL); - while ((drv = next_driver(&i)) && !error) - error = fn(drv, data); - klist_iter_exit(&i); - return error; -} -EXPORT_SYMBOL_GPL(bus_for_each_drv); - -static int device_add_attrs(struct bus_type *bus, struct device *dev) -{ - int error = 0; - int i; - - if (!bus->dev_attrs) - return 0; - - for (i = 0; attr_name(bus->dev_attrs[i]); i++) { - error = device_create_file(dev, &bus->dev_attrs[i]); - if (error) { - while (--i >= 0) - device_remove_file(dev, &bus->dev_attrs[i]); - break; - } - } - return error; -} - -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]); - } -} - -#ifdef CONFIG_SYSFS_DEPRECATED -static int make_deprecated_bus_links(struct device *dev) -{ - return sysfs_create_link(&dev->kobj, - &dev->bus->p->subsys.kobj, "bus"); -} - -static void remove_deprecated_bus_links(struct device *dev) -{ - sysfs_remove_link(&dev->kobj, "bus"); -} -#else -static inline int make_deprecated_bus_links(struct device *dev) { return 0; } -static inline void remove_deprecated_bus_links(struct device *dev) { } -#endif - -/** - * bus_add_device - add device to bus - * @dev: device being added - * - * - Add the device to its bus's list of devices. - * - Create link to device's bus. - */ -int bus_add_device(struct device *dev) -{ - struct bus_type *bus = bus_get(dev->bus); - int error = 0; - - if (bus) { - pr_debug("bus: '%s': add device %s\n", bus->name, dev_name(dev)); - error = device_add_attrs(bus, dev); - if (error) - goto out_put; - error = sysfs_create_link(&bus->p->devices_kset->kobj, - &dev->kobj, dev_name(dev)); - if (error) - goto out_id; - error = sysfs_create_link(&dev->kobj, - &dev->bus->p->subsys.kobj, "subsystem"); - if (error) - goto out_subsys; - error = make_deprecated_bus_links(dev); - if (error) - goto out_deprecated; - } - return 0; - -out_deprecated: - sysfs_remove_link(&dev->kobj, "subsystem"); -out_subsys: - sysfs_remove_link(&bus->p->devices_kset->kobj, dev_name(dev)); -out_id: - device_remove_attrs(bus, dev); -out_put: - bus_put(dev->bus); - return error; -} - -/** - * bus_attach_device - add device to bus - * @dev: device tried to attach to a driver - * - * - Add device to bus's list of devices. - * - Try to attach to driver. - */ -void bus_attach_device(struct device *dev) -{ - struct bus_type *bus = dev->bus; - int ret = 0; - - if (bus) { - if (bus->p->drivers_autoprobe) - ret = device_attach(dev); - WARN_ON(ret < 0); - if (ret >= 0) - klist_add_tail(&dev->knode_bus, &bus->p->klist_devices); - } -} - -/** - * bus_remove_device - remove device from bus - * @dev: device to be removed - * - * - Remove symlink from bus's directory. - * - Delete device from bus's list. - * - Detach from its driver. - * - Drop reference taken in bus_add_device(). - */ -void bus_remove_device(struct device *dev) -{ - if (dev->bus) { - sysfs_remove_link(&dev->kobj, "subsystem"); - remove_deprecated_bus_links(dev); - sysfs_remove_link(&dev->bus->p->devices_kset->kobj, - dev_name(dev)); - device_remove_attrs(dev->bus, dev); - if (klist_node_attached(&dev->knode_bus)) - klist_del(&dev->knode_bus); - - pr_debug("bus: '%s': remove device %s\n", - dev->bus->name, dev_name(dev)); - device_release_driver(dev); - bus_put(dev->bus); - } -} - -static int driver_add_attrs(struct bus_type *bus, struct device_driver *drv) -{ - int error = 0; - int i; - - if (bus->drv_attrs) { - for (i = 0; attr_name(bus->drv_attrs[i]); i++) { - error = driver_create_file(drv, &bus->drv_attrs[i]); - if (error) - goto err; - } - } -done: - return error; -err: - while (--i >= 0) - driver_remove_file(drv, &bus->drv_attrs[i]); - goto done; -} - -static void driver_remove_attrs(struct bus_type *bus, - struct device_driver *drv) -{ - int i; - - if (bus->drv_attrs) { - for (i = 0; attr_name(bus->drv_attrs[i]); i++) - driver_remove_file(drv, &bus->drv_attrs[i]); - } -} - -#ifdef CONFIG_HOTPLUG -/* - * Thanks to drivers making their tables __devinit, we can't allow manual - * bind and unbind from userspace unless CONFIG_HOTPLUG is enabled. - */ -static int __must_check add_bind_files(struct device_driver *drv) -{ - int ret; - - ret = driver_create_file(drv, &driver_attr_unbind); - if (ret == 0) { - ret = driver_create_file(drv, &driver_attr_bind); - if (ret) - driver_remove_file(drv, &driver_attr_unbind); - } - return ret; -} - -static void remove_bind_files(struct device_driver *drv) -{ - driver_remove_file(drv, &driver_attr_bind); - driver_remove_file(drv, &driver_attr_unbind); -} - -static BUS_ATTR(drivers_probe, S_IWUSR, NULL, store_drivers_probe); -static BUS_ATTR(drivers_autoprobe, S_IWUSR | S_IRUGO, - show_drivers_autoprobe, store_drivers_autoprobe); - -static int add_probe_files(struct bus_type *bus) -{ - int retval; - - retval = bus_create_file(bus, &bus_attr_drivers_probe); - if (retval) - goto out; - - retval = bus_create_file(bus, &bus_attr_drivers_autoprobe); - if (retval) - bus_remove_file(bus, &bus_attr_drivers_probe); -out: - return retval; -} - -static void remove_probe_files(struct bus_type *bus) -{ - bus_remove_file(bus, &bus_attr_drivers_autoprobe); - bus_remove_file(bus, &bus_attr_drivers_probe); -} -#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 - -static ssize_t driver_uevent_store(struct device_driver *drv, - const char *buf, size_t count) -{ - enum kobject_action action; - - if (kobject_action_type(buf, count, &action) == 0) - kobject_uevent(&drv->p->kobj, action); - return count; -} -static DRIVER_ATTR(uevent, S_IWUSR, NULL, driver_uevent_store); - -/** - * bus_add_driver - Add a driver to the bus. - * @drv: driver. - */ -int bus_add_driver(struct device_driver *drv) -{ - struct bus_type *bus; - struct driver_private *priv; - int error = 0; - - bus = bus_get(drv->bus); - if (!bus) - return -EINVAL; - - pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name); - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) { - error = -ENOMEM; - goto out_put_bus; - } - klist_init(&priv->klist_devices, NULL, NULL); - priv->driver = drv; - drv->p = priv; - priv->kobj.kset = bus->p->drivers_kset; - error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL, - "%s", drv->name); - if (error) - goto out_unregister; - - if (drv->bus->p->drivers_autoprobe) { - error = driver_attach(drv); - if (error) - goto out_unregister; - } - klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers); - module_add_driver(drv->owner, drv); - - error = driver_create_file(drv, &driver_attr_uevent); - if (error) { - printk(KERN_ERR "%s: uevent attr (%s) failed\n", - __func__, drv->name); - } - error = driver_add_attrs(bus, drv); - if (error) { - /* How the hell do we get out of this pickle? Give up */ - printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", - __func__, drv->name); - } - error = add_bind_files(drv); - if (error) { - /* Ditto */ - printk(KERN_ERR "%s: add_bind_files(%s) failed\n", - __func__, drv->name); - } - - kobject_uevent(&priv->kobj, KOBJ_ADD); - return error; -out_unregister: - kobject_put(&priv->kobj); -out_put_bus: - bus_put(bus); - return error; -} - -/** - * bus_remove_driver - delete driver from bus's knowledge. - * @drv: driver. - * - * Detach the driver from the devices it controls, and remove - * it from its bus's list of drivers. Finally, we drop the reference - * to the bus we took in bus_add_driver(). - */ -void bus_remove_driver(struct device_driver *drv) -{ - if (!drv->bus) - return; - - remove_bind_files(drv); - driver_remove_attrs(drv->bus, drv); - driver_remove_file(drv, &driver_attr_uevent); - klist_remove(&drv->p->knode_bus); - pr_debug("bus: '%s': remove driver %s\n", drv->bus->name, drv->name); - driver_detach(drv); - module_remove_driver(drv); - kobject_put(&drv->p->kobj); - bus_put(drv->bus); -} - -/* Helper for bus_rescan_devices's iter */ -static int __must_check bus_rescan_devices_helper(struct device *dev, - void *data) -{ - int ret = 0; - - if (!dev->driver) { - if (dev->parent) /* Needed for USB */ - down(&dev->parent->sem); - ret = device_attach(dev); - if (dev->parent) - up(&dev->parent->sem); - } - return ret < 0 ? ret : 0; -} - -/** - * bus_rescan_devices - rescan devices on the bus for possible drivers - * @bus: the bus to scan. - * - * This function will look for devices on the bus with no driver - * attached and rescan it against existing drivers to see if it matches - * any by calling device_attach() for the unbound devices. - */ -int bus_rescan_devices(struct bus_type *bus) -{ - return bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper); -} -EXPORT_SYMBOL_GPL(bus_rescan_devices); - -/** - * device_reprobe - remove driver for a device and probe for a new driver - * @dev: the device to reprobe - * - * This function detaches the attached driver (if any) for the given - * device and restarts the driver probing process. It is intended - * to use if probing criteria changed during a devices lifetime and - * driver attachment should change accordingly. - */ -int device_reprobe(struct device *dev) -{ - if (dev->driver) { - if (dev->parent) /* Needed for USB */ - down(&dev->parent->sem); - device_release_driver(dev); - if (dev->parent) - up(&dev->parent->sem); - } - return bus_rescan_devices_helper(dev, NULL); -} -EXPORT_SYMBOL_GPL(device_reprobe); - -/** - * find_bus - locate bus by name. - * @name: name of bus. - * - * Call kset_find_obj() to iterate over list of buses to - * find a bus by name. Return bus if found. - * - * Note that kset_find_obj increments bus' reference count. - */ -#if 0 -struct bus_type *find_bus(char *name) -{ - struct kobject *k = kset_find_obj(bus_kset, name); - return k ? to_bus(k) : NULL; -} -#endif /* 0 */ - - -/** - * 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++) { - error = bus_create_file(bus, &bus->bus_attrs[i]); - if (error) - 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]); - } -} - -static void klist_devices_get(struct klist_node *n) -{ - struct device *dev = container_of(n, struct device, knode_bus); - - get_device(dev); -} - -static void klist_devices_put(struct klist_node *n) -{ - struct device *dev = container_of(n, struct device, knode_bus); - - put_device(dev); -} - -static ssize_t bus_uevent_store(struct bus_type *bus, - const char *buf, size_t count) -{ - enum kobject_action action; - - if (kobject_action_type(buf, count, &action) == 0) - kobject_uevent(&bus->p->subsys.kobj, action); - return count; -} -static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store); - -/** - * 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. - */ -int bus_register(struct bus_type *bus) -{ - int retval; - struct bus_type_private *priv; - - priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->bus = bus; - bus->p = priv; - - BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier); - - retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name); - if (retval) - goto out; - - priv->subsys.kobj.kset = bus_kset; - priv->subsys.kobj.ktype = &bus_ktype; - priv->drivers_autoprobe = 1; - - retval = kset_register(&priv->subsys); - if (retval) - goto out; - - retval = bus_create_file(bus, &bus_attr_uevent); - if (retval) - goto bus_uevent_fail; - - priv->devices_kset = kset_create_and_add("devices", NULL, - &priv->subsys.kobj); - if (!priv->devices_kset) { - retval = -ENOMEM; - goto bus_devices_fail; - } - - priv->drivers_kset = kset_create_and_add("drivers", NULL, - &priv->subsys.kobj); - if (!priv->drivers_kset) { - retval = -ENOMEM; - goto bus_drivers_fail; - } - - klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put); - klist_init(&priv->klist_drivers, NULL, NULL); - - retval = add_probe_files(bus); - if (retval) - goto bus_probe_files_fail; - - retval = bus_add_attrs(bus); - if (retval) - goto bus_attrs_fail; - - pr_debug("bus: '%s': registered\n", bus->name); - return 0; - -bus_attrs_fail: - remove_probe_files(bus); -bus_probe_files_fail: - kset_unregister(bus->p->drivers_kset); -bus_drivers_fail: - kset_unregister(bus->p->devices_kset); -bus_devices_fail: - bus_remove_file(bus, &bus_attr_uevent); -bus_uevent_fail: - kset_unregister(&bus->p->subsys); - kfree(bus->p); -out: - return retval; -} -EXPORT_SYMBOL_GPL(bus_register); - -/** - * bus_unregister - remove a bus from the system - * @bus: bus. - * - * Unregister the child subsystems and the bus itself. - * Finally, we call bus_put() to release the refcount - */ -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->p->drivers_kset); - kset_unregister(bus->p->devices_kset); - bus_remove_file(bus, &bus_attr_uevent); - kset_unregister(&bus->p->subsys); - kfree(bus->p); -} -EXPORT_SYMBOL_GPL(bus_unregister); - -int bus_register_notifier(struct bus_type *bus, struct notifier_block *nb) -{ - return blocking_notifier_chain_register(&bus->p->bus_notifier, nb); -} -EXPORT_SYMBOL_GPL(bus_register_notifier); - -int bus_unregister_notifier(struct bus_type *bus, struct notifier_block *nb) -{ - return blocking_notifier_chain_unregister(&bus->p->bus_notifier, nb); -} -EXPORT_SYMBOL_GPL(bus_unregister_notifier); - -struct kset *bus_get_kset(struct bus_type *bus) -{ - return &bus->p->subsys; -} -EXPORT_SYMBOL_GPL(bus_get_kset); - -struct klist *bus_get_device_klist(struct bus_type *bus) -{ - return &bus->p->klist_devices; -} -EXPORT_SYMBOL_GPL(bus_get_device_klist); - -/* - * Yes, this forcably breaks the klist abstraction temporarily. It - * just wants to sort the klist, not change reference counts and - * take/drop locks rapidly in the process. It does all this while - * holding the lock for the list, so objects can't otherwise be - * added/removed while we're swizzling. - */ -static void device_insertion_sort_klist(struct device *a, struct list_head *list, - int (*compare)(const struct device *a, - const struct device *b)) -{ - struct list_head *pos; - struct klist_node *n; - struct device *b; - - list_for_each(pos, list) { - n = container_of(pos, struct klist_node, n_node); - b = container_of(n, struct device, knode_bus); - if (compare(a, b) <= 0) { - list_move_tail(&a->knode_bus.n_node, - &b->knode_bus.n_node); - return; - } - } - list_move_tail(&a->knode_bus.n_node, list); -} - -void bus_sort_breadthfirst(struct bus_type *bus, - int (*compare)(const struct device *a, - const struct device *b)) -{ - LIST_HEAD(sorted_devices); - struct list_head *pos, *tmp; - struct klist_node *n; - struct device *dev; - struct klist *device_klist; - - device_klist = bus_get_device_klist(bus); - - spin_lock(&device_klist->k_lock); - list_for_each_safe(pos, tmp, &device_klist->k_list) { - n = container_of(pos, struct klist_node, n_node); - dev = container_of(n, struct device, knode_bus); - device_insertion_sort_klist(dev, &sorted_devices, compare); - } - list_splice(&sorted_devices, &device_klist->k_list); - spin_unlock(&device_klist->k_lock); -} -EXPORT_SYMBOL_GPL(bus_sort_breadthfirst); - -int __init buses_init(void) -{ - bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL); - if (!bus_kset) - return -ENOMEM; - return 0; -} diff --git a/libdde_linux26/contrib/drivers/base/cpu.c b/libdde_linux26/contrib/drivers/base/cpu.c deleted file mode 100644 index 719ee5c1..00000000 --- a/libdde_linux26/contrib/drivers/base/cpu.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * drivers/base/cpu.c - basic CPU class support - */ - -#include <linux/sysdev.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/cpu.h> -#include <linux/topology.h> -#include <linux/device.h> -#include <linux/node.h> - -#include "base.h" - -struct sysdev_class cpu_sysdev_class = { - .name = "cpu", -}; -EXPORT_SYMBOL(cpu_sysdev_class); - -static DEFINE_PER_CPU(struct sys_device *, cpu_sys_devices); - -#ifdef CONFIG_HOTPLUG_CPU -static ssize_t show_online(struct sys_device *dev, struct sysdev_attribute *attr, - char *buf) -{ - struct cpu *cpu = container_of(dev, struct cpu, sysdev); - - return sprintf(buf, "%u\n", !!cpu_online(cpu->sysdev.id)); -} - -static ssize_t __ref store_online(struct sys_device *dev, struct sysdev_attribute *attr, - const char *buf, size_t count) -{ - struct cpu *cpu = container_of(dev, struct cpu, sysdev); - ssize_t ret; - - switch (buf[0]) { - case '0': - ret = cpu_down(cpu->sysdev.id); - if (!ret) - kobject_uevent(&dev->kobj, KOBJ_OFFLINE); - break; - case '1': - ret = cpu_up(cpu->sysdev.id); - if (!ret) - kobject_uevent(&dev->kobj, KOBJ_ONLINE); - break; - default: - ret = -EINVAL; - } - - if (ret >= 0) - ret = count; - return ret; -} -static SYSDEV_ATTR(online, 0644, show_online, store_online); - -static void __cpuinit register_cpu_control(struct cpu *cpu) -{ - sysdev_create_file(&cpu->sysdev, &attr_online); -} -void unregister_cpu(struct cpu *cpu) -{ - int logical_cpu = cpu->sysdev.id; - - unregister_cpu_under_node(logical_cpu, cpu_to_node(logical_cpu)); - - sysdev_remove_file(&cpu->sysdev, &attr_online); - - sysdev_unregister(&cpu->sysdev); - per_cpu(cpu_sys_devices, logical_cpu) = NULL; - return; -} -#else /* ... !CONFIG_HOTPLUG_CPU */ -static inline void register_cpu_control(struct cpu *cpu) -{ -} -#endif /* CONFIG_HOTPLUG_CPU */ - -#ifdef CONFIG_KEXEC -#include <linux/kexec.h> - -static ssize_t show_crash_notes(struct sys_device *dev, struct sysdev_attribute *attr, - char *buf) -{ - struct cpu *cpu = container_of(dev, struct cpu, sysdev); - ssize_t rc; - unsigned long long addr; - int cpunum; - - cpunum = cpu->sysdev.id; - - /* - * Might be reading other cpu's data based on which cpu read thread - * has been scheduled. But cpu data (memory) is allocated once during - * boot up and this data does not change there after. Hence this - * operation should be safe. No locking required. - */ - addr = __pa(per_cpu_ptr(crash_notes, cpunum)); - rc = sprintf(buf, "%Lx\n", addr); - return rc; -} -static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL); -#endif - -/* - * Print cpu online, possible, present, and system maps - */ -static ssize_t print_cpus_map(char *buf, cpumask_t *map) -{ - int n = cpulist_scnprintf(buf, PAGE_SIZE-2, map); - - buf[n++] = '\n'; - buf[n] = '\0'; - return n; -} - -#define print_cpus_func(type) \ -static ssize_t print_cpus_##type(struct sysdev_class *class, char *buf) \ -{ \ - return print_cpus_map(buf, &cpu_##type##_map); \ -} \ -static struct sysdev_class_attribute attr_##type##_map = \ - _SYSDEV_CLASS_ATTR(type, 0444, print_cpus_##type, NULL) - -print_cpus_func(online); -print_cpus_func(possible); -print_cpus_func(present); - -/* - * Print values for NR_CPUS and offlined cpus - */ -static ssize_t print_cpus_kernel_max(struct sysdev_class *class, char *buf) -{ - int n = snprintf(buf, PAGE_SIZE-2, "%d\n", NR_CPUS - 1); - return n; -} -static SYSDEV_CLASS_ATTR(kernel_max, 0444, print_cpus_kernel_max, NULL); - -/* arch-optional setting to enable display of offline cpus >= nr_cpu_ids */ -unsigned int total_cpus; - -static ssize_t print_cpus_offline(struct sysdev_class *class, char *buf) -{ - int n = 0, len = PAGE_SIZE-2; - cpumask_var_t offline; - - /* display offline cpus < nr_cpu_ids */ - if (!alloc_cpumask_var(&offline, GFP_KERNEL)) - return -ENOMEM; - cpumask_complement(offline, cpu_online_mask); - n = cpulist_scnprintf(buf, len, offline); - free_cpumask_var(offline); - - /* display offline cpus >= nr_cpu_ids */ - if (total_cpus && nr_cpu_ids < total_cpus) { - if (n && n < len) - buf[n++] = ','; - - if (nr_cpu_ids == total_cpus-1) - n += snprintf(&buf[n], len - n, "%d", nr_cpu_ids); - else - n += snprintf(&buf[n], len - n, "%d-%d", - nr_cpu_ids, total_cpus-1); - } - - n += snprintf(&buf[n], len - n, "\n"); - return n; -} -static SYSDEV_CLASS_ATTR(offline, 0444, print_cpus_offline, NULL); - -static struct sysdev_class_attribute *cpu_state_attr[] = { - &attr_online_map, - &attr_possible_map, - &attr_present_map, - &attr_kernel_max, - &attr_offline, -}; - -static int cpu_states_init(void) -{ - int i; - int err = 0; - - for (i = 0; i < ARRAY_SIZE(cpu_state_attr); i++) { - int ret; - ret = sysdev_class_create_file(&cpu_sysdev_class, - cpu_state_attr[i]); - if (!err) - err = ret; - } - return err; -} - -/* - * register_cpu - Setup a sysfs device for a CPU. - * @cpu - cpu->hotpluggable field set to 1 will generate a control file in - * sysfs for this CPU. - * @num - CPU number to use when creating the device. - * - * Initialize and register the CPU device. - */ -int __cpuinit register_cpu(struct cpu *cpu, int num) -{ - int error; - cpu->node_id = cpu_to_node(num); - cpu->sysdev.id = num; - cpu->sysdev.cls = &cpu_sysdev_class; - - error = sysdev_register(&cpu->sysdev); - - if (!error && cpu->hotpluggable) - register_cpu_control(cpu); - if (!error) - per_cpu(cpu_sys_devices, num) = &cpu->sysdev; - if (!error) - register_cpu_under_node(num, cpu_to_node(num)); - -#ifdef CONFIG_KEXEC - if (!error) - error = sysdev_create_file(&cpu->sysdev, &attr_crash_notes); -#endif - return error; -} - -struct sys_device *get_cpu_sysdev(unsigned cpu) -{ - if (cpu < nr_cpu_ids && cpu_possible(cpu)) - return per_cpu(cpu_sys_devices, cpu); - else - return NULL; -} -EXPORT_SYMBOL_GPL(get_cpu_sysdev); - -int __init cpu_dev_init(void) -{ - int err; - - err = sysdev_class_register(&cpu_sysdev_class); - if (!err) - err = cpu_states_init(); - -#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT) - if (!err) - err = sched_create_sysfs_power_savings_entries(&cpu_sysdev_class); -#endif - - return err; -} diff --git a/libdde_linux26/contrib/drivers/base/dd.c b/libdde_linux26/contrib/drivers/base/dd.c deleted file mode 100644 index 13523123..00000000 --- a/libdde_linux26/contrib/drivers/base/dd.c +++ /dev/null @@ -1,383 +0,0 @@ -/* - * drivers/base/dd.c - The core device/driver interactions. - * - * This file contains the (sometimes tricky) code that controls the - * interactions between devices and drivers, which primarily includes - * driver binding and unbinding. - * - * All of this code used to exist in drivers/base/bus.c, but was - * relocated to here in the name of compartmentalization (since it wasn't - * strictly code just for the 'struct bus_type'. - * - * Copyright (c) 2002-5 Patrick Mochel - * Copyright (c) 2002-3 Open Source Development Labs - * Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de> - * Copyright (c) 2007 Novell Inc. - * - * This file is released under the GPLv2 - */ - -#include <linux/device.h> -#include <linux/delay.h> -#include <linux/module.h> -#include <linux/kthread.h> -#include <linux/wait.h> -#include <linux/async.h> - -#include "base.h" -#include "power/power.h" - - -static void driver_bound(struct device *dev) -{ - if (klist_node_attached(&dev->knode_driver)) { - printk(KERN_WARNING "%s: device %s already bound\n", - __func__, kobject_name(&dev->kobj)); - return; - } - - pr_debug("driver: '%s': %s: bound to device '%s'\n", dev_name(dev), - __func__, dev->driver->name); - - if (dev->bus) - blocking_notifier_call_chain(&dev->bus->p->bus_notifier, - BUS_NOTIFY_BOUND_DRIVER, dev); - - klist_add_tail(&dev->knode_driver, &dev->driver->p->klist_devices); -} - -static int driver_sysfs_add(struct device *dev) -{ - int ret; - - ret = sysfs_create_link(&dev->driver->p->kobj, &dev->kobj, - kobject_name(&dev->kobj)); - if (ret == 0) { - ret = sysfs_create_link(&dev->kobj, &dev->driver->p->kobj, - "driver"); - if (ret) - sysfs_remove_link(&dev->driver->p->kobj, - kobject_name(&dev->kobj)); - } - return ret; -} - -static void driver_sysfs_remove(struct device *dev) -{ - struct device_driver *drv = dev->driver; - - if (drv) { - sysfs_remove_link(&drv->p->kobj, kobject_name(&dev->kobj)); - sysfs_remove_link(&dev->kobj, "driver"); - } -} - -/** - * device_bind_driver - bind a driver to one device. - * @dev: device. - * - * Allow manual attachment of a driver to a device. - * 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 - * for before calling this. (It is ok to call with no other effort - * from a driver's probe() method.) - * - * This function must be called with @dev->sem held. - */ -int device_bind_driver(struct device *dev) -{ - int ret; - - ret = driver_sysfs_add(dev); - if (!ret) - driver_bound(dev); - return ret; -} -EXPORT_SYMBOL_GPL(device_bind_driver); - -static atomic_t probe_count = ATOMIC_INIT(0); -static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue); - -static int really_probe(struct device *dev, struct device_driver *drv) -{ - int ret = 0; - - atomic_inc(&probe_count); - pr_debug("bus: '%s': %s: probing driver %s with device %s\n", - drv->bus->name, __func__, drv->name, dev_name(dev)); - WARN_ON(!list_empty(&dev->devres_head)); - - dev->driver = drv; - if (driver_sysfs_add(dev)) { - printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n", - __func__, dev_name(dev)); - goto probe_failed; - } - - if (dev->bus->probe) { - ret = dev->bus->probe(dev); - if (ret) - goto probe_failed; - } else if (drv->probe) { - ret = drv->probe(dev); - if (ret) - goto probe_failed; - } - - driver_bound(dev); - ret = 1; - pr_debug("bus: '%s': %s: bound device %s to driver %s\n", - drv->bus->name, __func__, dev_name(dev), drv->name); - goto done; - -probe_failed: - devres_release_all(dev); - driver_sysfs_remove(dev); - dev->driver = NULL; - - if (ret != -ENODEV && ret != -ENXIO) { - /* driver matched but the probe failed */ - printk(KERN_WARNING - "%s: probe of %s failed with error %d\n", - drv->name, dev_name(dev), ret); - } - /* - * Ignore errors returned by ->probe so that the next driver can try - * its luck. - */ - ret = 0; -done: - atomic_dec(&probe_count); - wake_up(&probe_waitqueue); - return ret; -} - -/** - * driver_probe_done - * Determine if the probe sequence is finished or not. - * - * Should somehow figure out how to use a semaphore, not an atomic variable... - */ -int driver_probe_done(void) -{ - pr_debug("%s: probe_count = %d\n", __func__, - atomic_read(&probe_count)); - if (atomic_read(&probe_count)) - return -EBUSY; - return 0; -} - -/** - * wait_for_device_probe - * Wait for device probing to be completed. - * - * Note: this function polls at 100 msec intervals. - */ -int wait_for_device_probe(void) -{ - /* wait for the known devices to complete their probing */ - while (driver_probe_done() != 0) - msleep(100); - async_synchronize_full(); - return 0; -} - -/** - * driver_probe_device - attempt to bind device & driver together - * @drv: driver to bind a device to - * @dev: device to try to bind to the driver - * - * First, we call the bus's match function, if one present, 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 - * format of the ID structures, nor what is to be considered a match and - * what is not. - * - * This function returns 1 if a match is found, -ENODEV if the device is - * not registered, and 0 otherwise. - * - * This function must be called with @dev->sem held. When called for a - * USB interface, @dev->parent->sem must be held as well. - */ -int driver_probe_device(struct device_driver *drv, struct device *dev) -{ - int ret = 0; - - if (!device_is_registered(dev)) - return -ENODEV; - if (drv->bus->match && !drv->bus->match(dev, drv)) - goto done; - - pr_debug("bus: '%s': %s: matched device %s with driver %s\n", - drv->bus->name, __func__, dev_name(dev), drv->name); - - ret = really_probe(dev, drv); - -done: - return ret; -} - -static int __device_attach(struct device_driver *drv, void *data) -{ - struct device *dev = data; - return driver_probe_device(drv, dev); -} - -/** - * device_attach - try to attach device to a driver. - * @dev: device. - * - * Walk the list of drivers that the bus has and call - * driver_probe_device() for each pair. If a compatible - * pair is found, break out and return. - * - * Returns 1 if the device was bound to a driver; - * 0 if no matching device was found; - * -ENODEV if the device is not registered. - * - * When called for a USB interface, @dev->parent->sem must be held. - */ -int device_attach(struct device *dev) -{ - int ret = 0; - - down(&dev->sem); - if (dev->driver) { - ret = device_bind_driver(dev); - if (ret == 0) - ret = 1; - else { - dev->driver = NULL; - ret = 0; - } - } else { - ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); - } - up(&dev->sem); - return ret; -} -EXPORT_SYMBOL_GPL(device_attach); - -static int __driver_attach(struct device *dev, void *data) -{ - struct device_driver *drv = data; - - /* - * Lock device and try to bind to it. We drop the error - * here and always return 0, because we need to keep trying - * to bind to devices and some drivers will return an error - * simply if it didn't support the device. - * - * driver_probe_device() will spit a warning if there - * is an error. - */ - - if (drv->bus->match && !drv->bus->match(dev, drv)) - return 0; - - if (dev->parent) /* Needed for USB */ - down(&dev->parent->sem); - down(&dev->sem); - if (!dev->driver) - driver_probe_device(drv, dev); - up(&dev->sem); - if (dev->parent) - up(&dev->parent->sem); - - return 0; -} - -/** - * driver_attach - try to bind driver to devices. - * @drv: driver. - * - * Walk the list of devices that the bus has on it and try to - * match the driver with each one. If driver_probe_device() - * returns 0 and the @dev->driver is set, we've found a - * compatible pair. - */ -int driver_attach(struct device_driver *drv) -{ - return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach); -} -EXPORT_SYMBOL_GPL(driver_attach); - -/* - * __device_release_driver() must be called with @dev->sem held. - * When called for a USB interface, @dev->parent->sem must be held as well. - */ -static void __device_release_driver(struct device *dev) -{ - struct device_driver *drv; - - drv = dev->driver; - if (drv) { - driver_sysfs_remove(dev); - - if (dev->bus) - blocking_notifier_call_chain(&dev->bus->p->bus_notifier, - BUS_NOTIFY_UNBIND_DRIVER, - dev); - - if (dev->bus && dev->bus->remove) - dev->bus->remove(dev); - else if (drv->remove) - drv->remove(dev); - devres_release_all(dev); - dev->driver = NULL; - klist_remove(&dev->knode_driver); - } -} - -/** - * device_release_driver - manually detach device from driver. - * @dev: device. - * - * Manually detach device from driver. - * When called for a USB interface, @dev->parent->sem must be held. - */ -void device_release_driver(struct device *dev) -{ - /* - * If anyone calls device_release_driver() recursively from - * within their ->remove callback for the same device, they - * will deadlock right here. - */ - down(&dev->sem); - __device_release_driver(dev); - up(&dev->sem); -} -EXPORT_SYMBOL_GPL(device_release_driver); - -/** - * driver_detach - detach driver from all devices it controls. - * @drv: driver. - */ -void driver_detach(struct device_driver *drv) -{ - struct device *dev; - - for (;;) { - spin_lock(&drv->p->klist_devices.k_lock); - if (list_empty(&drv->p->klist_devices.k_list)) { - spin_unlock(&drv->p->klist_devices.k_lock); - break; - } - dev = list_entry(drv->p->klist_devices.k_list.prev, - struct device, knode_driver.n_node); - get_device(dev); - spin_unlock(&drv->p->klist_devices.k_lock); - - if (dev->parent) /* Needed for USB */ - down(&dev->parent->sem); - down(&dev->sem); - if (dev->driver == drv) - __device_release_driver(dev); - up(&dev->sem); - if (dev->parent) - up(&dev->parent->sem); - put_device(dev); - } -} diff --git a/libdde_linux26/contrib/drivers/base/devres.c b/libdde_linux26/contrib/drivers/base/devres.c deleted file mode 100644 index e8beb8e5..00000000 --- a/libdde_linux26/contrib/drivers/base/devres.c +++ /dev/null @@ -1,646 +0,0 @@ -/* - * drivers/base/devres.c - device resource management - * - * Copyright (c) 2006 SUSE Linux Products GmbH - * Copyright (c) 2006 Tejun Heo <teheo@suse.de> - * - * This file is released under the GPLv2. - */ - -#include <linux/device.h> -#include <linux/module.h> - -#include "base.h" - -struct devres_node { - struct list_head entry; - dr_release_t release; -#ifdef CONFIG_DEBUG_DEVRES - const char *name; - size_t size; -#endif -}; - -struct devres { - struct devres_node node; - /* -- 3 pointers */ - unsigned long long data[]; /* guarantee ull alignment */ -}; - -struct devres_group { - struct devres_node node[2]; - void *id; - int color; - /* -- 8 pointers */ -}; - -#ifdef CONFIG_DEBUG_DEVRES -static int log_devres = 0; -module_param_named(log, log_devres, int, S_IRUGO | S_IWUSR); - -static void set_node_dbginfo(struct devres_node *node, const char *name, - size_t size) -{ - node->name = name; - node->size = size; -} - -static void devres_log(struct device *dev, struct devres_node *node, - const char *op) -{ - if (unlikely(log_devres)) - dev_printk(KERN_ERR, dev, "DEVRES %3s %p %s (%lu bytes)\n", - op, node, node->name, (unsigned long)node->size); -} -#else /* CONFIG_DEBUG_DEVRES */ -#define set_node_dbginfo(node, n, s) do {} while (0) -#define devres_log(dev, node, op) do {} while (0) -#endif /* CONFIG_DEBUG_DEVRES */ - -/* - * Release functions for devres group. These callbacks are used only - * for identification. - */ -static void group_open_release(struct device *dev, void *res) -{ - /* noop */ -} - -static void group_close_release(struct device *dev, void *res) -{ - /* noop */ -} - -static struct devres_group * node_to_group(struct devres_node *node) -{ - if (node->release == &group_open_release) - return container_of(node, struct devres_group, node[0]); - if (node->release == &group_close_release) - return container_of(node, struct devres_group, node[1]); - return NULL; -} - -static __always_inline struct devres * alloc_dr(dr_release_t release, - size_t size, gfp_t gfp) -{ - size_t tot_size = sizeof(struct devres) + size; - struct devres *dr; - - dr = kmalloc_track_caller(tot_size, gfp); - if (unlikely(!dr)) - return NULL; - - memset(dr, 0, tot_size); - INIT_LIST_HEAD(&dr->node.entry); - dr->node.release = release; - return dr; -} - -static void add_dr(struct device *dev, struct devres_node *node) -{ - devres_log(dev, node, "ADD"); - BUG_ON(!list_empty(&node->entry)); - list_add_tail(&node->entry, &dev->devres_head); -} - -#ifdef CONFIG_DEBUG_DEVRES -void * __devres_alloc(dr_release_t release, size_t size, gfp_t gfp, - const char *name) -{ - struct devres *dr; - - dr = alloc_dr(release, size, gfp); - if (unlikely(!dr)) - return NULL; - set_node_dbginfo(&dr->node, name, size); - return dr->data; -} -EXPORT_SYMBOL_GPL(__devres_alloc); -#else -/** - * devres_alloc - Allocate device resource data - * @release: Release function devres will be associated with - * @size: Allocation size - * @gfp: Allocation flags - * - * Allocate devres of @size bytes. The allocated area is zeroed, then - * associated with @release. The returned pointer can be passed to - * other devres_*() functions. - * - * RETURNS: - * Pointer to allocated devres on success, NULL on failure. - */ -void * devres_alloc(dr_release_t release, size_t size, gfp_t gfp) -{ - struct devres *dr; - - dr = alloc_dr(release, size, gfp); - if (unlikely(!dr)) - return NULL; - return dr->data; -} -EXPORT_SYMBOL_GPL(devres_alloc); -#endif - -/** - * devres_free - Free device resource data - * @res: Pointer to devres data to free - * - * Free devres created with devres_alloc(). - */ -void devres_free(void *res) -{ - if (res) { - struct devres *dr = container_of(res, struct devres, data); - - BUG_ON(!list_empty(&dr->node.entry)); - kfree(dr); - } -} -EXPORT_SYMBOL_GPL(devres_free); - -/** - * devres_add - Register device resource - * @dev: Device to add resource to - * @res: Resource to register - * - * Register devres @res to @dev. @res should have been allocated - * using devres_alloc(). On driver detach, the associated release - * function will be invoked and devres will be freed automatically. - */ -void devres_add(struct device *dev, void *res) -{ - struct devres *dr = container_of(res, struct devres, data); - unsigned long flags; - - spin_lock_irqsave(&dev->devres_lock, flags); - add_dr(dev, &dr->node); - spin_unlock_irqrestore(&dev->devres_lock, flags); -} -EXPORT_SYMBOL_GPL(devres_add); - -static struct devres *find_dr(struct device *dev, dr_release_t release, - dr_match_t match, void *match_data) -{ - struct devres_node *node; - - list_for_each_entry_reverse(node, &dev->devres_head, entry) { - struct devres *dr = container_of(node, struct devres, node); - - if (node->release != release) - continue; - if (match && !match(dev, dr->data, match_data)) - continue; - return dr; - } - - return NULL; -} - -/** - * devres_find - Find device resource - * @dev: Device to lookup resource from - * @release: Look for resources associated with this release function - * @match: Match function (optional) - * @match_data: Data for the match function - * - * Find the latest devres of @dev which is associated with @release - * and for which @match returns 1. If @match is NULL, it's considered - * to match all. - * - * RETURNS: - * Pointer to found devres, NULL if not found. - */ -void * devres_find(struct device *dev, dr_release_t release, - dr_match_t match, void *match_data) -{ - struct devres *dr; - unsigned long flags; - - spin_lock_irqsave(&dev->devres_lock, flags); - dr = find_dr(dev, release, match, match_data); - spin_unlock_irqrestore(&dev->devres_lock, flags); - - if (dr) - return dr->data; - return NULL; -} -EXPORT_SYMBOL_GPL(devres_find); - -/** - * devres_get - Find devres, if non-existent, add one atomically - * @dev: Device to lookup or add devres for - * @new_res: Pointer to new initialized devres to add if not found - * @match: Match function (optional) - * @match_data: Data for the match function - * - * Find the latest devres of @dev which has the same release function - * as @new_res and for which @match return 1. If found, @new_res is - * freed; otherwise, @new_res is added atomically. - * - * RETURNS: - * Pointer to found or added devres. - */ -void * devres_get(struct device *dev, void *new_res, - dr_match_t match, void *match_data) -{ - struct devres *new_dr = container_of(new_res, struct devres, data); - struct devres *dr; - unsigned long flags; - - spin_lock_irqsave(&dev->devres_lock, flags); - dr = find_dr(dev, new_dr->node.release, match, match_data); - if (!dr) { - add_dr(dev, &new_dr->node); - dr = new_dr; - new_dr = NULL; - } - spin_unlock_irqrestore(&dev->devres_lock, flags); - devres_free(new_dr); - - return dr->data; -} -EXPORT_SYMBOL_GPL(devres_get); - -/** - * devres_remove - Find a device resource and remove it - * @dev: Device to find resource from - * @release: Look for resources associated with this release function - * @match: Match function (optional) - * @match_data: Data for the match function - * - * Find the latest devres of @dev associated with @release and for - * which @match returns 1. If @match is NULL, it's considered to - * match all. If found, the resource is removed atomically and - * returned. - * - * RETURNS: - * Pointer to removed devres on success, NULL if not found. - */ -void * devres_remove(struct device *dev, dr_release_t release, - dr_match_t match, void *match_data) -{ - struct devres *dr; - unsigned long flags; - - spin_lock_irqsave(&dev->devres_lock, flags); - dr = find_dr(dev, release, match, match_data); - if (dr) { - list_del_init(&dr->node.entry); - devres_log(dev, &dr->node, "REM"); - } - spin_unlock_irqrestore(&dev->devres_lock, flags); - - if (dr) - return dr->data; - return NULL; -} -EXPORT_SYMBOL_GPL(devres_remove); - -/** - * devres_destroy - Find a device resource and destroy it - * @dev: Device to find resource from - * @release: Look for resources associated with this release function - * @match: Match function (optional) - * @match_data: Data for the match function - * - * Find the latest devres of @dev associated with @release and for - * which @match returns 1. If @match is NULL, it's considered to - * match all. If found, the resource is removed atomically and freed. - * - * RETURNS: - * 0 if devres is found and freed, -ENOENT if not found. - */ -int devres_destroy(struct device *dev, dr_release_t release, - dr_match_t match, void *match_data) -{ - void *res; - - res = devres_remove(dev, release, match, match_data); - if (unlikely(!res)) - return -ENOENT; - - devres_free(res); - return 0; -} -EXPORT_SYMBOL_GPL(devres_destroy); - -static int remove_nodes(struct device *dev, - struct list_head *first, struct list_head *end, - struct list_head *todo) -{ - int cnt = 0, nr_groups = 0; - struct list_head *cur; - - /* First pass - move normal devres entries to @todo and clear - * devres_group colors. - */ - cur = first; - while (cur != end) { - struct devres_node *node; - struct devres_group *grp; - - node = list_entry(cur, struct devres_node, entry); - cur = cur->next; - - grp = node_to_group(node); - if (grp) { - /* clear color of group markers in the first pass */ - grp->color = 0; - nr_groups++; - } else { - /* regular devres entry */ - if (&node->entry == first) - first = first->next; - list_move_tail(&node->entry, todo); - cnt++; - } - } - - if (!nr_groups) - return cnt; - - /* Second pass - Scan groups and color them. A group gets - * color value of two iff the group is wholly contained in - * [cur, end). That is, for a closed group, both opening and - * closing markers should be in the range, while just the - * opening marker is enough for an open group. - */ - cur = first; - while (cur != end) { - struct devres_node *node; - struct devres_group *grp; - - node = list_entry(cur, struct devres_node, entry); - cur = cur->next; - - grp = node_to_group(node); - BUG_ON(!grp || list_empty(&grp->node[0].entry)); - - grp->color++; - if (list_empty(&grp->node[1].entry)) - grp->color++; - - BUG_ON(grp->color <= 0 || grp->color > 2); - if (grp->color == 2) { - /* No need to update cur or end. The removed - * nodes are always before both. - */ - list_move_tail(&grp->node[0].entry, todo); - list_del_init(&grp->node[1].entry); - } - } - - return cnt; -} - -static int release_nodes(struct device *dev, struct list_head *first, - struct list_head *end, unsigned long flags) -{ - LIST_HEAD(todo); - int cnt; - struct devres *dr, *tmp; - - cnt = remove_nodes(dev, first, end, &todo); - - spin_unlock_irqrestore(&dev->devres_lock, flags); - - /* Release. Note that both devres and devres_group are - * handled as devres in the following loop. This is safe. - */ - list_for_each_entry_safe_reverse(dr, tmp, &todo, node.entry) { - devres_log(dev, &dr->node, "REL"); - dr->node.release(dev, dr->data); - kfree(dr); - } - - return cnt; -} - -/** - * devres_release_all - Release all managed resources - * @dev: Device to release resources for - * - * Release all resources associated with @dev. This function is - * called on driver detach. - */ -int devres_release_all(struct device *dev) -{ - unsigned long flags; - - spin_lock_irqsave(&dev->devres_lock, flags); - return release_nodes(dev, dev->devres_head.next, &dev->devres_head, - flags); -} - -/** - * devres_open_group - Open a new devres group - * @dev: Device to open devres group for - * @id: Separator ID - * @gfp: Allocation flags - * - * Open a new devres group for @dev with @id. For @id, using a - * pointer to an object which won't be used for another group is - * recommended. If @id is NULL, address-wise unique ID is created. - * - * RETURNS: - * ID of the new group, NULL on failure. - */ -void * devres_open_group(struct device *dev, void *id, gfp_t gfp) -{ - struct devres_group *grp; - unsigned long flags; - - grp = kmalloc(sizeof(*grp), gfp); - if (unlikely(!grp)) - return NULL; - - grp->node[0].release = &group_open_release; - grp->node[1].release = &group_close_release; - INIT_LIST_HEAD(&grp->node[0].entry); - INIT_LIST_HEAD(&grp->node[1].entry); - set_node_dbginfo(&grp->node[0], "grp<", 0); - set_node_dbginfo(&grp->node[1], "grp>", 0); - grp->id = grp; - if (id) - grp->id = id; - - spin_lock_irqsave(&dev->devres_lock, flags); - add_dr(dev, &grp->node[0]); - spin_unlock_irqrestore(&dev->devres_lock, flags); - return grp->id; -} -EXPORT_SYMBOL_GPL(devres_open_group); - -/* Find devres group with ID @id. If @id is NULL, look for the latest. */ -static struct devres_group * find_group(struct device *dev, void *id) -{ - struct devres_node *node; - - list_for_each_entry_reverse(node, &dev->devres_head, entry) { - struct devres_group *grp; - - if (node->release != &group_open_release) - continue; - - grp = container_of(node, struct devres_group, node[0]); - - if (id) { - if (grp->id == id) - return grp; - } else if (list_empty(&grp->node[1].entry)) - return grp; - } - - return NULL; -} - -/** - * devres_close_group - Close a devres group - * @dev: Device to close devres group for - * @id: ID of target group, can be NULL - * - * Close the group identified by @id. If @id is NULL, the latest open - * group is selected. - */ -void devres_close_group(struct device *dev, void *id) -{ - struct devres_group *grp; - unsigned long flags; - - spin_lock_irqsave(&dev->devres_lock, flags); - - grp = find_group(dev, id); - if (grp) - add_dr(dev, &grp->node[1]); - else - WARN_ON(1); - - spin_unlock_irqrestore(&dev->devres_lock, flags); -} -EXPORT_SYMBOL_GPL(devres_close_group); - -/** - * devres_remove_group - Remove a devres group - * @dev: Device to remove group for - * @id: ID of target group, can be NULL - * - * Remove the group identified by @id. If @id is NULL, the latest - * open group is selected. Note that removing a group doesn't affect - * any other resources. - */ -void devres_remove_group(struct device *dev, void *id) -{ - struct devres_group *grp; - unsigned long flags; - - spin_lock_irqsave(&dev->devres_lock, flags); - - grp = find_group(dev, id); - if (grp) { - list_del_init(&grp->node[0].entry); - list_del_init(&grp->node[1].entry); - devres_log(dev, &grp->node[0], "REM"); - } else - WARN_ON(1); - - spin_unlock_irqrestore(&dev->devres_lock, flags); - - kfree(grp); -} -EXPORT_SYMBOL_GPL(devres_remove_group); - -/** - * devres_release_group - Release resources in a devres group - * @dev: Device to release group for - * @id: ID of target group, can be NULL - * - * Release all resources in the group identified by @id. If @id is - * NULL, the latest open group is selected. The selected group and - * groups properly nested inside the selected group are removed. - * - * RETURNS: - * The number of released non-group resources. - */ -int devres_release_group(struct device *dev, void *id) -{ - struct devres_group *grp; - unsigned long flags; - int cnt = 0; - - spin_lock_irqsave(&dev->devres_lock, flags); - - grp = find_group(dev, id); - if (grp) { - struct list_head *first = &grp->node[0].entry; - struct list_head *end = &dev->devres_head; - - if (!list_empty(&grp->node[1].entry)) - end = grp->node[1].entry.next; - - cnt = release_nodes(dev, first, end, flags); - } else { - WARN_ON(1); - spin_unlock_irqrestore(&dev->devres_lock, flags); - } - - return cnt; -} -EXPORT_SYMBOL_GPL(devres_release_group); - -/* - * Managed kzalloc/kfree - */ -static void devm_kzalloc_release(struct device *dev, void *res) -{ - /* noop */ -} - -static int devm_kzalloc_match(struct device *dev, void *res, void *data) -{ - return res == data; -} - -/** - * devm_kzalloc - Resource-managed kzalloc - * @dev: Device to allocate memory for - * @size: Allocation size - * @gfp: Allocation gfp flags - * - * Managed kzalloc. Memory allocated with this function is - * automatically freed on driver detach. Like all other devres - * resources, guaranteed alignment is unsigned long long. - * - * RETURNS: - * Pointer to allocated memory on success, NULL on failure. - */ -void * devm_kzalloc(struct device *dev, size_t size, gfp_t gfp) -{ - struct devres *dr; - - /* use raw alloc_dr for kmalloc caller tracing */ - dr = alloc_dr(devm_kzalloc_release, size, gfp); - if (unlikely(!dr)) - return NULL; - - set_node_dbginfo(&dr->node, "devm_kzalloc_release", size); - devres_add(dev, dr->data); - return dr->data; -} -EXPORT_SYMBOL_GPL(devm_kzalloc); - -/** - * devm_kfree - Resource-managed kfree - * @dev: Device this memory belongs to - * @p: Memory to free - * - * Free memory allocated with dev_kzalloc(). - */ -void devm_kfree(struct device *dev, void *p) -{ - int rc; - - rc = devres_destroy(dev, devm_kzalloc_release, devm_kzalloc_match, p); - WARN_ON(rc); -} -EXPORT_SYMBOL_GPL(devm_kfree); diff --git a/libdde_linux26/contrib/drivers/base/driver.c b/libdde_linux26/contrib/drivers/base/driver.c deleted file mode 100644 index 1e2bda78..00000000 --- a/libdde_linux26/contrib/drivers/base/driver.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * driver.c - centralized device driver management - * - * Copyright (c) 2002-3 Patrick Mochel - * Copyright (c) 2002-3 Open Source Development Labs - * Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de> - * Copyright (c) 2007 Novell Inc. - * - * This file is released under the GPLv2 - * - */ - -#include <linux/device.h> -#include <linux/module.h> -#include <linux/errno.h> -#include <linux/string.h> -#include "base.h" - -static struct device *next_device(struct klist_iter *i) -{ - struct klist_node *n = klist_next(i); - return n ? container_of(n, struct device, knode_driver) : NULL; -} - -/** - * driver_for_each_device - Iterator for devices bound to a driver. - * @drv: Driver we're iterating. - * @start: Device to begin with - * @data: Data to pass to the callback. - * @fn: Function to call for each device. - * - * Iterate over the @drv's list of devices calling @fn for each one. - */ -int driver_for_each_device(struct device_driver *drv, struct device *start, - void *data, int (*fn)(struct device *, void *)) -{ - struct klist_iter i; - struct device *dev; - int error = 0; - - if (!drv) - return -EINVAL; - - klist_iter_init_node(&drv->p->klist_devices, &i, - start ? &start->knode_driver : NULL); - while ((dev = next_device(&i)) && !error) - error = fn(dev, data); - klist_iter_exit(&i); - return error; -} -EXPORT_SYMBOL_GPL(driver_for_each_device); - -/** - * driver_find_device - device iterator for locating a particular device. - * @drv: The device's driver - * @start: Device to begin with - * @data: Data to pass to match function - * @match: Callback function to check device - * - * This is similar to the driver_for_each_device() function above, but - * it returns a reference to a device that is 'found' for later use, as - * determined by the @match callback. - * - * The callback should return 0 if the device doesn't match and non-zero - * if it does. If the callback returns non-zero, this function will - * return to the caller and not iterate over any more devices. - */ -struct device *driver_find_device(struct device_driver *drv, - struct device *start, void *data, - int (*match)(struct device *dev, void *data)) -{ - struct klist_iter i; - struct device *dev; - - if (!drv) - return NULL; - - klist_iter_init_node(&drv->p->klist_devices, &i, - (start ? &start->knode_driver : NULL)); - while ((dev = next_device(&i))) - if (match(dev, data) && get_device(dev)) - break; - klist_iter_exit(&i); - return dev; -} -EXPORT_SYMBOL_GPL(driver_find_device); - -/** - * driver_create_file - create sysfs file for driver. - * @drv: driver. - * @attr: driver attribute descriptor. - */ -int driver_create_file(struct device_driver *drv, - struct driver_attribute *attr) -{ - int error; - if (drv) - error = sysfs_create_file(&drv->p->kobj, &attr->attr); - else - error = -EINVAL; - return error; -} -EXPORT_SYMBOL_GPL(driver_create_file); - -/** - * driver_remove_file - remove sysfs file for driver. - * @drv: driver. - * @attr: driver attribute descriptor. - */ -void driver_remove_file(struct device_driver *drv, - struct driver_attribute *attr) -{ - if (drv) - sysfs_remove_file(&drv->p->kobj, &attr->attr); -} -EXPORT_SYMBOL_GPL(driver_remove_file); - -/** - * driver_add_kobj - add a kobject below the specified driver - * @drv: requesting device driver - * @kobj: kobject to add below this driver - * @fmt: format string that names the kobject - * - * You really don't want to do this, this is only here due to one looney - * iseries driver, go poke those developers if you are annoyed about - * this... - */ -int driver_add_kobj(struct device_driver *drv, struct kobject *kobj, - const char *fmt, ...) -{ - va_list args; - char *name; - int ret; - - va_start(args, fmt); - name = kvasprintf(GFP_KERNEL, fmt, args); - va_end(args); - - if (!name) - return -ENOMEM; - - ret = kobject_add(kobj, &drv->p->kobj, "%s", name); - kfree(name); - return ret; -} -EXPORT_SYMBOL_GPL(driver_add_kobj); - -/** - * get_driver - increment driver reference count. - * @drv: driver. - */ -struct device_driver *get_driver(struct device_driver *drv) -{ - if (drv) { - struct driver_private *priv; - struct kobject *kobj; - - kobj = kobject_get(&drv->p->kobj); - priv = to_driver(kobj); - return priv->driver; - } - return NULL; -} -EXPORT_SYMBOL_GPL(get_driver); - -/** - * put_driver - decrement driver's refcount. - * @drv: driver. - */ -void put_driver(struct device_driver *drv) -{ - kobject_put(&drv->p->kobj); -} -EXPORT_SYMBOL_GPL(put_driver); - -static int driver_add_groups(struct device_driver *drv, - struct attribute_group **groups) -{ - int error = 0; - int i; - - if (groups) { - for (i = 0; groups[i]; i++) { - error = sysfs_create_group(&drv->p->kobj, groups[i]); - if (error) { - while (--i >= 0) - sysfs_remove_group(&drv->p->kobj, - groups[i]); - break; - } - } - } - return error; -} - -static void driver_remove_groups(struct device_driver *drv, - struct attribute_group **groups) -{ - int i; - - if (groups) - for (i = 0; groups[i]; i++) - sysfs_remove_group(&drv->p->kobj, groups[i]); -} - -/** - * driver_register - register driver with bus - * @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 - * structures. - */ -int driver_register(struct device_driver *drv) -{ - int ret; - struct device_driver *other; - - if ((drv->bus->probe && drv->probe) || - (drv->bus->remove && drv->remove) || - (drv->bus->shutdown && drv->shutdown)) - printk(KERN_WARNING "Driver '%s' needs updating - please use " - "bus_type methods\n", drv->name); - - other = driver_find(drv->name, drv->bus); - if (other) { - put_driver(other); - printk(KERN_ERR "Error: Driver '%s' is already registered, " - "aborting...\n", drv->name); - return -EEXIST; - } - - ret = bus_add_driver(drv); - if (ret) - return ret; - ret = driver_add_groups(drv, drv->groups); - if (ret) - bus_remove_driver(drv); - return ret; -} -EXPORT_SYMBOL_GPL(driver_register); - -/** - * driver_unregister - remove driver from system. - * @drv: driver. - * - * Again, we pass off most of the work to the bus-level call. - */ -void driver_unregister(struct device_driver *drv) -{ - driver_remove_groups(drv, drv->groups); - bus_remove_driver(drv); -} -EXPORT_SYMBOL_GPL(driver_unregister); - -/** - * driver_find - locate driver on a bus by its name. - * @name: name of the driver. - * @bus: bus to scan for the driver. - * - * Call kset_find_obj() to iterate over list of drivers on - * a bus to find driver by name. Return driver if found. - * - * Note that kset_find_obj increments driver's reference count. - */ -struct device_driver *driver_find(const char *name, struct bus_type *bus) -{ - struct kobject *k = kset_find_obj(bus->p->drivers_kset, name); - struct driver_private *priv; - - if (k) { - priv = to_driver(k); - return priv->driver; - } - return NULL; -} -EXPORT_SYMBOL_GPL(driver_find); diff --git a/libdde_linux26/contrib/drivers/base/map.c b/libdde_linux26/contrib/drivers/base/map.c deleted file mode 100644 index e87017f3..00000000 --- a/libdde_linux26/contrib/drivers/base/map.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * linux/drivers/base/map.c - * - * (C) Copyright Al Viro 2002,2003 - * Released under GPL v2. - * - * NOTE: data structure needs to be changed. It works, but for large dev_t - * it will be too slow. It is isolated, though, so these changes will be - * local to that file. - */ - -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/mutex.h> -#include <linux/kdev_t.h> -#include <linux/kobject.h> -#include <linux/kobj_map.h> - -struct kobj_map { - struct probe { - struct probe *next; - dev_t dev; - unsigned long range; - struct module *owner; - kobj_probe_t *get; - int (*lock)(dev_t, void *); - void *data; - } *probes[255]; - struct mutex *lock; -}; - -int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range, - struct module *module, kobj_probe_t *probe, - int (*lock)(dev_t, void *), void *data) -{ - unsigned n = MAJOR(dev + range - 1) - MAJOR(dev) + 1; - unsigned index = MAJOR(dev); - unsigned i; - struct probe *p; - - if (n > 255) - n = 255; - - p = kmalloc(sizeof(struct probe) * n, GFP_KERNEL); - - if (p == NULL) - return -ENOMEM; - - for (i = 0; i < n; i++, p++) { - p->owner = module; - p->get = probe; - p->lock = lock; - p->dev = dev; - p->range = range; - p->data = data; - } - mutex_lock(domain->lock); - for (i = 0, p -= n; i < n; i++, p++, index++) { - struct probe **s = &domain->probes[index % 255]; - while (*s && (*s)->range < range) - s = &(*s)->next; - p->next = *s; - *s = p; - } - mutex_unlock(domain->lock); - return 0; -} - -void kobj_unmap(struct kobj_map *domain, dev_t dev, unsigned long range) -{ - unsigned n = MAJOR(dev + range - 1) - MAJOR(dev) + 1; - unsigned index = MAJOR(dev); - unsigned i; - struct probe *found = NULL; - - if (n > 255) - n = 255; - - mutex_lock(domain->lock); - for (i = 0; i < n; i++, index++) { - struct probe **s; - for (s = &domain->probes[index % 255]; *s; s = &(*s)->next) { - struct probe *p = *s; - if (p->dev == dev && p->range == range) { - *s = p->next; - if (!found) - found = p; - break; - } - } - } - mutex_unlock(domain->lock); - kfree(found); -} - -struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index) -{ - struct kobject *kobj; - struct probe *p; - unsigned long best = ~0UL; - -retry: - mutex_lock(domain->lock); - for (p = domain->probes[MAJOR(dev) % 255]; p; p = p->next) { - struct kobject *(*probe)(dev_t, int *, void *); - struct module *owner; - void *data; - - if (p->dev > dev || p->dev + p->range - 1 < dev) - continue; - if (p->range - 1 >= best) - break; - if (!try_module_get(p->owner)) - continue; - owner = p->owner; - data = p->data; - probe = p->get; - best = p->range - 1; - *index = dev - p->dev; - if (p->lock && p->lock(dev, data) < 0) { - module_put(owner); - continue; - } - mutex_unlock(domain->lock); - kobj = probe(dev, index, data); - /* Currently ->owner protects _only_ ->probe() itself. */ - module_put(owner); - if (kobj) - return kobj; - goto retry; - } - mutex_unlock(domain->lock); - return NULL; -} - -struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct mutex *lock) -{ - struct kobj_map *p = kmalloc(sizeof(struct kobj_map), GFP_KERNEL); - struct probe *base = kzalloc(sizeof(*base), GFP_KERNEL); - int i; - - if ((p == NULL) || (base == NULL)) { - kfree(p); - kfree(base); - return NULL; - } - - base->dev = 1; - base->range = ~0; - base->get = base_probe; - for (i = 0; i < 255; i++) - p->probes[i] = base; - p->lock = lock; - return p; -} diff --git a/libdde_linux26/contrib/drivers/base/platform.c b/libdde_linux26/contrib/drivers/base/platform.c deleted file mode 100644 index 349a1013..00000000 --- a/libdde_linux26/contrib/drivers/base/platform.c +++ /dev/null @@ -1,988 +0,0 @@ -/* - * platform.c - platform 'pseudo' bus for legacy devices - * - * 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 - * information. - */ - -#include <linux/platform_device.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/dma-mapping.h> -#include <linux/bootmem.h> -#include <linux/err.h> -#include <linux/slab.h> - -#include "base.h" - -#define to_platform_driver(drv) (container_of((drv), struct platform_driver, \ - driver)) - -struct device platform_bus = { - .init_name = "platform", -}; -EXPORT_SYMBOL_GPL(platform_bus); - -/** - * platform_get_resource - get a resource for a device - * @dev: platform device - * @type: resource type - * @num: resource index - */ -struct resource *platform_get_resource(struct platform_device *dev, - unsigned int type, unsigned int num) -{ - int i; - - for (i = 0; i < dev->num_resources; i++) { - struct resource *r = &dev->resource[i]; - - if (type == resource_type(r) && num-- == 0) - return r; - } - return NULL; -} -EXPORT_SYMBOL_GPL(platform_get_resource); - -/** - * 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 : -ENXIO; -} -EXPORT_SYMBOL_GPL(platform_get_irq); - -/** - * platform_get_resource_byname - get a resource for a device by name - * @dev: platform device - * @type: resource type - * @name: resource name - */ -struct resource *platform_get_resource_byname(struct platform_device *dev, - unsigned int type, char *name) -{ - int i; - - for (i = 0; i < dev->num_resources; i++) { - struct resource *r = &dev->resource[i]; - - if (type == resource_type(r) && !strcmp(r->name, name)) - return r; - } - return NULL; -} -EXPORT_SYMBOL_GPL(platform_get_resource_byname); - -/** - * platform_get_irq - get an IRQ for a device - * @dev: platform device - * @name: IRQ name - */ -int platform_get_irq_byname(struct platform_device *dev, char *name) -{ - struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, - name); - - return r ? r->start : -ENXIO; -} -EXPORT_SYMBOL_GPL(platform_get_irq_byname); - -/** - * 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; -} -EXPORT_SYMBOL_GPL(platform_add_devices); - -struct platform_object { - struct platform_device pdev; - char name[1]; -}; - -/** - * platform_device_put - * @pdev: platform device to free - * - * Free all memory associated with a platform device. This function must - * _only_ be externally called in error cases. All other usage is a bug. - */ -void platform_device_put(struct platform_device *pdev) -{ - if (pdev) - put_device(&pdev->dev); -} -EXPORT_SYMBOL_GPL(platform_device_put); - -static void platform_device_release(struct device *dev) -{ - struct platform_object *pa = container_of(dev, struct platform_object, - pdev.dev); - - kfree(pa->pdev.dev.platform_data); - kfree(pa->pdev.resource); - kfree(pa); -} - -/** - * platform_device_alloc - * @name: base name of the device we're adding - * @id: instance id - * - * Create a platform device object which can have other objects attached - * to it, and which will have attached objects freed when it is released. - */ -struct platform_device *platform_device_alloc(const char *name, int id) -{ - struct platform_object *pa; - - pa = kzalloc(sizeof(struct platform_object) + strlen(name), GFP_KERNEL); - if (pa) { - strcpy(pa->name, name); - pa->pdev.name = pa->name; - pa->pdev.id = id; - device_initialize(&pa->pdev.dev); - pa->pdev.dev.release = platform_device_release; - } - - return pa ? &pa->pdev : NULL; -} -EXPORT_SYMBOL_GPL(platform_device_alloc); - -/** - * platform_device_add_resources - * @pdev: platform device allocated by platform_device_alloc to add resources to - * @res: set of resources that needs to be allocated for the device - * @num: number of resources - * - * Add a copy of the resources to the platform device. The memory - * associated with the resources will be freed when the platform device is - * released. - */ -int platform_device_add_resources(struct platform_device *pdev, - struct resource *res, unsigned int num) -{ - struct resource *r; - - r = kmalloc(sizeof(struct resource) * num, GFP_KERNEL); - if (r) { - memcpy(r, res, sizeof(struct resource) * num); - pdev->resource = r; - pdev->num_resources = num; - } - return r ? 0 : -ENOMEM; -} -EXPORT_SYMBOL_GPL(platform_device_add_resources); - -/** - * platform_device_add_data - * @pdev: platform device allocated by platform_device_alloc to add resources to - * @data: platform specific data for this platform device - * @size: size of platform specific data - * - * Add a copy of platform specific data to the platform device's - * platform_data pointer. The memory associated with the platform data - * will be freed when the platform device is released. - */ -int platform_device_add_data(struct platform_device *pdev, const void *data, - size_t size) -{ - void *d; - - d = kmalloc(size, GFP_KERNEL); - if (d) { - memcpy(d, data, size); - pdev->dev.platform_data = d; - } - return d ? 0 : -ENOMEM; -} -EXPORT_SYMBOL_GPL(platform_device_add_data); - -/** - * platform_device_add - add a platform device to device hierarchy - * @pdev: platform device we're adding - * - * This is part 2 of platform_device_register(), though may be called - * separately _iff_ pdev was allocated by platform_device_alloc(). - */ -int platform_device_add(struct platform_device *pdev) -{ - int i, ret = 0; - - if (!pdev) - return -EINVAL; - - if (!pdev->dev.parent) - pdev->dev.parent = &platform_bus; - - pdev->dev.bus = &platform_bus_type; - - if (pdev->id != -1) - dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); - else - dev_set_name(&pdev->dev, pdev->name); - - for (i = 0; i < pdev->num_resources; i++) { - struct resource *p, *r = &pdev->resource[i]; - - if (r->name == NULL) - r->name = dev_name(&pdev->dev); - - p = r->parent; - if (!p) { - if (resource_type(r) == IORESOURCE_MEM) - p = &iomem_resource; - else if (resource_type(r) == IORESOURCE_IO) - p = &ioport_resource; - } - - if (p && insert_resource(p, r)) { - printk(KERN_ERR - "%s: failed to claim resource %d\n", - dev_name(&pdev->dev), i); - ret = -EBUSY; - goto failed; - } - } - - pr_debug("Registering platform device '%s'. Parent at %s\n", - dev_name(&pdev->dev), dev_name(pdev->dev.parent)); - - ret = device_add(&pdev->dev); - if (ret == 0) - return ret; - - failed: - while (--i >= 0) { - struct resource *r = &pdev->resource[i]; - unsigned long type = resource_type(r); - - if (type == IORESOURCE_MEM || type == IORESOURCE_IO) - release_resource(r); - } - - return ret; -} -EXPORT_SYMBOL_GPL(platform_device_add); - -/** - * platform_device_del - remove a platform-level device - * @pdev: platform device we're removing - * - * Note that this function will also release all memory- and port-based - * resources owned by the device (@dev->resource). This function must - * _only_ be externally called in error cases. All other usage is a bug. - */ -void platform_device_del(struct platform_device *pdev) -{ - int i; - - if (pdev) { - device_del(&pdev->dev); - - for (i = 0; i < pdev->num_resources; i++) { - struct resource *r = &pdev->resource[i]; - unsigned long type = resource_type(r); - - if (type == IORESOURCE_MEM || type == IORESOURCE_IO) - release_resource(r); - } - } -} -EXPORT_SYMBOL_GPL(platform_device_del); - -/** - * platform_device_register - add a platform-level device - * @pdev: platform device we're adding - */ -int platform_device_register(struct platform_device *pdev) -{ - device_initialize(&pdev->dev); - return platform_device_add(pdev); -} -EXPORT_SYMBOL_GPL(platform_device_register); - -/** - * platform_device_unregister - unregister a platform-level device - * @pdev: platform device we're unregistering - * - * Unregistration is done in 2 steps. First we release all resources - * and remove it from the subsystem, then we drop reference count by - * calling platform_device_put(). - */ -void platform_device_unregister(struct platform_device *pdev) -{ - platform_device_del(pdev); - platform_device_put(pdev); -} -EXPORT_SYMBOL_GPL(platform_device_unregister); - -/** - * platform_device_register_simple - * @name: base name of the device we're adding - * @id: instance id - * @res: set of resources that needs to be allocated for the device - * @num: number of resources - * - * This function creates a simple platform device that requires minimal - * resource and memory management. Canned release function freeing memory - * allocated for the device allows drivers using such devices to be - * unloaded without waiting for the last reference to the device to be - * dropped. - * - * This interface is primarily intended for use with legacy drivers which - * probe hardware directly. Because such drivers create sysfs device nodes - * themselves, rather than letting system infrastructure handle such device - * enumeration tasks, they don't fully conform to the Linux driver model. - * In particular, when such drivers are built as modules, they can't be - * "hotplugged". - */ -struct platform_device *platform_device_register_simple(const char *name, - int id, - struct resource *res, - unsigned int num) -{ - struct platform_device *pdev; - int retval; - - pdev = platform_device_alloc(name, id); - if (!pdev) { - retval = -ENOMEM; - goto error; - } - - if (num) { - retval = platform_device_add_resources(pdev, res, num); - if (retval) - goto error; - } - - retval = platform_device_add(pdev); - if (retval) - goto error; - - return pdev; - -error: - platform_device_put(pdev); - return ERR_PTR(retval); -} -EXPORT_SYMBOL_GPL(platform_device_register_simple); - -/** - * platform_device_register_data - * @parent: parent device for the device we're adding - * @name: base name of the device we're adding - * @id: instance id - * @data: platform specific data for this platform device - * @size: size of platform specific data - * - * This function creates a simple platform device that requires minimal - * resource and memory management. Canned release function freeing memory - * allocated for the device allows drivers using such devices to be - * unloaded without waiting for the last reference to the device to be - * dropped. - */ -struct platform_device *platform_device_register_data( - struct device *parent, - const char *name, int id, - const void *data, size_t size) -{ - struct platform_device *pdev; - int retval; - - pdev = platform_device_alloc(name, id); - if (!pdev) { - retval = -ENOMEM; - goto error; - } - - pdev->dev.parent = parent; - - if (size) { - retval = platform_device_add_data(pdev, data, size); - if (retval) - goto error; - } - - retval = platform_device_add(pdev); - if (retval) - goto error; - - return pdev; - -error: - platform_device_put(pdev); - return ERR_PTR(retval); -} - -static int platform_drv_probe(struct device *_dev) -{ - struct platform_driver *drv = to_platform_driver(_dev->driver); - struct platform_device *dev = to_platform_device(_dev); - - return drv->probe(dev); -} - -static int platform_drv_probe_fail(struct device *_dev) -{ - return -ENXIO; -} - -static int platform_drv_remove(struct device *_dev) -{ - struct platform_driver *drv = to_platform_driver(_dev->driver); - struct platform_device *dev = to_platform_device(_dev); - - return drv->remove(dev); -} - -static void platform_drv_shutdown(struct device *_dev) -{ - struct platform_driver *drv = to_platform_driver(_dev->driver); - struct platform_device *dev = to_platform_device(_dev); - - drv->shutdown(dev); -} - -static int platform_drv_suspend(struct device *_dev, pm_message_t state) -{ - struct platform_driver *drv = to_platform_driver(_dev->driver); - struct platform_device *dev = to_platform_device(_dev); - - return drv->suspend(dev, state); -} - -static int platform_drv_resume(struct device *_dev) -{ - struct platform_driver *drv = to_platform_driver(_dev->driver); - struct platform_device *dev = to_platform_device(_dev); - - return drv->resume(dev); -} - -/** - * platform_driver_register - * @drv: platform driver structure - */ -int platform_driver_register(struct platform_driver *drv) -{ - drv->driver.bus = &platform_bus_type; - if (drv->probe) - drv->driver.probe = platform_drv_probe; - if (drv->remove) - drv->driver.remove = platform_drv_remove; - if (drv->shutdown) - drv->driver.shutdown = platform_drv_shutdown; - if (drv->suspend) - drv->driver.suspend = platform_drv_suspend; - if (drv->resume) - drv->driver.resume = platform_drv_resume; - return driver_register(&drv->driver); -} -EXPORT_SYMBOL_GPL(platform_driver_register); - -/** - * platform_driver_unregister - * @drv: platform driver structure - */ -void platform_driver_unregister(struct platform_driver *drv) -{ - driver_unregister(&drv->driver); -} -EXPORT_SYMBOL_GPL(platform_driver_unregister); - -/** - * platform_driver_probe - register driver for non-hotpluggable device - * @drv: platform driver structure - * @probe: the driver probe routine, probably from an __init section - * - * Use this instead of platform_driver_register() when you know the device - * is not hotpluggable and has already been registered, and you want to - * remove its run-once probe() infrastructure from memory after the driver - * has bound to the device. - * - * One typical use for this would be with drivers for controllers integrated - * into system-on-chip processors, where the controller devices have been - * configured as part of board setup. - * - * Returns zero if the driver registered and bound to a device, else returns - * a negative error code and with the driver not registered. - */ -int __init_or_module platform_driver_probe(struct platform_driver *drv, - int (*probe)(struct platform_device *)) -{ - int retval, code; - - /* temporary section violation during probe() */ - drv->probe = probe; - retval = code = platform_driver_register(drv); - - /* Fixup that section violation, being paranoid about code scanning - * the list of drivers in order to probe new devices. Check to see - * if the probe was successful, and make sure any forced probes of - * new devices fail. - */ - spin_lock(&platform_bus_type.p->klist_drivers.k_lock); - drv->probe = NULL; - if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list)) - retval = -ENODEV; - drv->driver.probe = platform_drv_probe_fail; - spin_unlock(&platform_bus_type.p->klist_drivers.k_lock); - - if (code != retval) - platform_driver_unregister(drv); - return retval; -} -EXPORT_SYMBOL_GPL(platform_driver_probe); - -/* modalias support enables more hands-off userspace setup: - * (a) environment variable lets new-style hotplug events work once system is - * fully running: "modprobe $MODALIAS" - * (b) sysfs attribute lets new-style coldplug recover from hotplug events - * mishandled before system is fully running: "modprobe $(cat modalias)" - */ -static ssize_t modalias_show(struct device *dev, struct device_attribute *a, - char *buf) -{ - struct platform_device *pdev = to_platform_device(dev); - int len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name); - - return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; -} - -static struct device_attribute platform_dev_attrs[] = { - __ATTR_RO(modalias), - __ATTR_NULL, -}; - -static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - struct platform_device *pdev = to_platform_device(dev); - - add_uevent_var(env, "MODALIAS=platform:%s", pdev->name); - return 0; -} - -/** - * platform_match - bind platform device to platform driver. - * @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 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 they match - * or not. - */ -static int platform_match(struct device *dev, struct device_driver *drv) -{ - struct platform_device *pdev; - - pdev = container_of(dev, struct platform_device, dev); - return (strcmp(pdev->name, drv->name) == 0); -} - -#ifdef CONFIG_PM_SLEEP - -static int platform_legacy_suspend(struct device *dev, pm_message_t mesg) -{ - int ret = 0; - - if (dev->driver && dev->driver->suspend) - ret = dev->driver->suspend(dev, mesg); - - return ret; -} - -static int platform_legacy_suspend_late(struct device *dev, pm_message_t mesg) -{ - struct platform_driver *drv = to_platform_driver(dev->driver); - struct platform_device *pdev; - int ret = 0; - - pdev = container_of(dev, struct platform_device, dev); - if (dev->driver && drv->suspend_late) - ret = drv->suspend_late(pdev, mesg); - - return ret; -} - -static int platform_legacy_resume_early(struct device *dev) -{ - struct platform_driver *drv = to_platform_driver(dev->driver); - struct platform_device *pdev; - int ret = 0; - - pdev = container_of(dev, struct platform_device, dev); - if (dev->driver && drv->resume_early) - ret = drv->resume_early(pdev); - - return ret; -} - -static int platform_legacy_resume(struct device *dev) -{ - int ret = 0; - - if (dev->driver && dev->driver->resume) - ret = dev->driver->resume(dev); - - return ret; -} - -static int platform_pm_prepare(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (drv && drv->pm && drv->pm->prepare) - ret = drv->pm->prepare(dev); - - return ret; -} - -static void platform_pm_complete(struct device *dev) -{ - struct device_driver *drv = dev->driver; - - if (drv && drv->pm && drv->pm->complete) - drv->pm->complete(dev); -} - -#ifdef CONFIG_SUSPEND - -static int platform_pm_suspend(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->suspend) - ret = drv->pm->suspend(dev); - } else { - ret = platform_legacy_suspend(dev, PMSG_SUSPEND); - } - - return ret; -} - -static int platform_pm_suspend_noirq(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->suspend_noirq) - ret = drv->pm->suspend_noirq(dev); - } else { - ret = platform_legacy_suspend_late(dev, PMSG_SUSPEND); - } - - return ret; -} - -static int platform_pm_resume(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->resume) - ret = drv->pm->resume(dev); - } else { - ret = platform_legacy_resume(dev); - } - - return ret; -} - -static int platform_pm_resume_noirq(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->resume_noirq) - ret = drv->pm->resume_noirq(dev); - } else { - ret = platform_legacy_resume_early(dev); - } - - return ret; -} - -#else /* !CONFIG_SUSPEND */ - -#define platform_pm_suspend NULL -#define platform_pm_resume NULL -#define platform_pm_suspend_noirq NULL -#define platform_pm_resume_noirq NULL - -#endif /* !CONFIG_SUSPEND */ - -#ifdef CONFIG_HIBERNATION - -static int platform_pm_freeze(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->freeze) - ret = drv->pm->freeze(dev); - } else { - ret = platform_legacy_suspend(dev, PMSG_FREEZE); - } - - return ret; -} - -static int platform_pm_freeze_noirq(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->freeze_noirq) - ret = drv->pm->freeze_noirq(dev); - } else { - ret = platform_legacy_suspend_late(dev, PMSG_FREEZE); - } - - return ret; -} - -static int platform_pm_thaw(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->thaw) - ret = drv->pm->thaw(dev); - } else { - ret = platform_legacy_resume(dev); - } - - return ret; -} - -static int platform_pm_thaw_noirq(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->thaw_noirq) - ret = drv->pm->thaw_noirq(dev); - } else { - ret = platform_legacy_resume_early(dev); - } - - return ret; -} - -static int platform_pm_poweroff(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->poweroff) - ret = drv->pm->poweroff(dev); - } else { - ret = platform_legacy_suspend(dev, PMSG_HIBERNATE); - } - - return ret; -} - -static int platform_pm_poweroff_noirq(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->poweroff_noirq) - ret = drv->pm->poweroff_noirq(dev); - } else { - ret = platform_legacy_suspend_late(dev, PMSG_HIBERNATE); - } - - return ret; -} - -static int platform_pm_restore(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->restore) - ret = drv->pm->restore(dev); - } else { - ret = platform_legacy_resume(dev); - } - - return ret; -} - -static int platform_pm_restore_noirq(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->restore_noirq) - ret = drv->pm->restore_noirq(dev); - } else { - ret = platform_legacy_resume_early(dev); - } - - return ret; -} - -#else /* !CONFIG_HIBERNATION */ - -#define platform_pm_freeze NULL -#define platform_pm_thaw NULL -#define platform_pm_poweroff NULL -#define platform_pm_restore NULL -#define platform_pm_freeze_noirq NULL -#define platform_pm_thaw_noirq NULL -#define platform_pm_poweroff_noirq NULL -#define platform_pm_restore_noirq NULL - -#endif /* !CONFIG_HIBERNATION */ - -static struct dev_pm_ops platform_dev_pm_ops = { - .prepare = platform_pm_prepare, - .complete = platform_pm_complete, - .suspend = platform_pm_suspend, - .resume = platform_pm_resume, - .freeze = platform_pm_freeze, - .thaw = platform_pm_thaw, - .poweroff = platform_pm_poweroff, - .restore = platform_pm_restore, - .suspend_noirq = platform_pm_suspend_noirq, - .resume_noirq = platform_pm_resume_noirq, - .freeze_noirq = platform_pm_freeze_noirq, - .thaw_noirq = platform_pm_thaw_noirq, - .poweroff_noirq = platform_pm_poweroff_noirq, - .restore_noirq = platform_pm_restore_noirq, -}; - -#define PLATFORM_PM_OPS_PTR (&platform_dev_pm_ops) - -#else /* !CONFIG_PM_SLEEP */ - -#define PLATFORM_PM_OPS_PTR NULL - -#endif /* !CONFIG_PM_SLEEP */ - -struct bus_type platform_bus_type = { - .name = "platform", - .dev_attrs = platform_dev_attrs, - .match = platform_match, - .uevent = platform_uevent, - .pm = PLATFORM_PM_OPS_PTR, -}; -EXPORT_SYMBOL_GPL(platform_bus_type); - -int __init platform_bus_init(void) -{ - int error; - - error = device_register(&platform_bus); - if (error) - return error; - error = bus_register(&platform_bus_type); - if (error) - device_unregister(&platform_bus); - return error; -} - -#ifndef ARCH_HAS_DMA_GET_REQUIRED_MASK -u64 dma_get_required_mask(struct device *dev) -{ - u32 low_totalram = ((max_pfn - 1) << PAGE_SHIFT); - u32 high_totalram = ((max_pfn - 1) >> (32 - PAGE_SHIFT)); - u64 mask; - - if (!high_totalram) { - /* convert to mask just covering totalram */ - low_totalram = (1 << (fls(low_totalram) - 1)); - low_totalram += low_totalram - 1; - mask = low_totalram; - } else { - high_totalram = (1 << (fls(high_totalram) - 1)); - high_totalram += high_totalram - 1; - mask = (((u64)high_totalram) << 32) + 0xffffffff; - } - return mask; -} -EXPORT_SYMBOL_GPL(dma_get_required_mask); -#endif diff --git a/libdde_linux26/contrib/drivers/base/power/power.h b/libdde_linux26/contrib/drivers/base/power/power.h deleted file mode 100644 index 41f51fae..00000000 --- a/libdde_linux26/contrib/drivers/base/power/power.h +++ /dev/null @@ -1,49 +0,0 @@ -static inline void device_pm_init(struct device *dev) -{ - dev->power.status = DPM_ON; -} - -#ifdef CONFIG_PM_SLEEP - -/* - * main.c - */ - -extern struct list_head dpm_list; /* The active device list */ - -static inline struct device *to_device(struct list_head *entry) -{ - return container_of(entry, struct device, power.entry); -} - -extern void device_pm_add(struct device *); -extern void device_pm_remove(struct device *); - -#else /* CONFIG_PM_SLEEP */ - -static inline void device_pm_add(struct device *dev) {} -static inline void device_pm_remove(struct device *dev) {} - -#endif - -#ifdef CONFIG_PM - -/* - * sysfs.c - */ - -extern int dpm_sysfs_add(struct device *); -extern void dpm_sysfs_remove(struct device *); - -#else /* CONFIG_PM */ - -static inline int dpm_sysfs_add(struct device *dev) -{ - return 0; -} - -static inline void dpm_sysfs_remove(struct device *dev) -{ -} - -#endif diff --git a/libdde_linux26/contrib/drivers/base/sys.c b/libdde_linux26/contrib/drivers/base/sys.c deleted file mode 100644 index b428c8c4..00000000 --- a/libdde_linux26/contrib/drivers/base/sys.c +++ /dev/null @@ -1,525 +0,0 @@ -/* - * sys.c - pseudo-bus for system 'devices' (cpus, PICs, timers, etc) - * - * Copyright (c) 2002-3 Patrick Mochel - * 2002-3 Open Source Development Lab - * - * This file is released under the GPLv2 - * - * 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. - */ - -#include <linux/sysdev.h> -#include <linux/err.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/string.h> -#include <linux/pm.h> -#include <linux/device.h> -#include <linux/mutex.h> - -#include "base.h" - -#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 -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, sysdev_attr, buffer); - return -EIO; -} - - -static ssize_t -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, sysdev_attr, buffer, count); - return -EIO; -} - -static struct sysfs_ops sysfs_ops = { - .show = sysdev_show, - .store = sysdev_store, -}; - -static struct kobj_type ktype_sysdev = { - .sysfs_ops = &sysfs_ops, -}; - - -int sysdev_create_file(struct sys_device * s, struct sysdev_attribute * a) -{ - 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); -} - -EXPORT_SYMBOL_GPL(sysdev_create_file); -EXPORT_SYMBOL_GPL(sysdev_remove_file); - -#define to_sysdev_class(k) container_of(k, struct sysdev_class, kset.kobj) -#define to_sysdev_class_attr(a) container_of(a, \ - struct sysdev_class_attribute, attr) - -static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr, - char *buffer) -{ - struct sysdev_class * class = to_sysdev_class(kobj); - struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); - - if (class_attr->show) - return class_attr->show(class, buffer); - return -EIO; -} - -static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr, - const char *buffer, size_t count) -{ - struct sysdev_class * class = to_sysdev_class(kobj); - struct sysdev_class_attribute * class_attr = to_sysdev_class_attr(attr); - - if (class_attr->store) - return class_attr->store(class, buffer, count); - return -EIO; -} - -static struct sysfs_ops sysfs_class_ops = { - .show = sysdev_class_show, - .store = sysdev_class_store, -}; - -static struct kobj_type ktype_sysdev_class = { - .sysfs_ops = &sysfs_class_ops, -}; - -int sysdev_class_create_file(struct sysdev_class *c, - struct sysdev_class_attribute *a) -{ - return sysfs_create_file(&c->kset.kobj, &a->attr); -} -EXPORT_SYMBOL_GPL(sysdev_class_create_file); - -void sysdev_class_remove_file(struct sysdev_class *c, - struct sysdev_class_attribute *a) -{ - sysfs_remove_file(&c->kset.kobj, &a->attr); -} -EXPORT_SYMBOL_GPL(sysdev_class_remove_file); - -static struct kset *system_kset; - -int sysdev_class_register(struct sysdev_class * cls) -{ - pr_debug("Registering sysdev class '%s'\n", cls->name); - - INIT_LIST_HEAD(&cls->drivers); - memset(&cls->kset.kobj, 0x00, sizeof(struct kobject)); - cls->kset.kobj.parent = &system_kset->kobj; - cls->kset.kobj.ktype = &ktype_sysdev_class; - cls->kset.kobj.kset = system_kset; - kobject_set_name(&cls->kset.kobj, cls->name); - return kset_register(&cls->kset); -} - -void sysdev_class_unregister(struct sysdev_class * cls) -{ - pr_debug("Unregistering sysdev class '%s'\n", - kobject_name(&cls->kset.kobj)); - kset_unregister(&cls->kset); -} - -EXPORT_SYMBOL_GPL(sysdev_class_register); -EXPORT_SYMBOL_GPL(sysdev_class_unregister); - -static DEFINE_MUTEX(sysdev_drivers_lock); - -/** - * sysdev_driver_register - Register auxillary driver - * @cls: Device class driver belongs to. - * @drv: Driver. - * - * @drv is inserted into @cls->drivers to be - * called on each operation on devices of that class. The refcount - * of @cls is incremented. - */ - -int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv) -{ - int err = 0; - - if (!cls) { - WARN(1, KERN_WARNING "sysdev: invalid class passed to " - "sysdev_driver_register!\n"); - return -EINVAL; - } - - /* Check whether this driver has already been added to a class. */ - if (drv->entry.next && !list_empty(&drv->entry)) - WARN(1, KERN_WARNING "sysdev: class %s: driver (%p) has already" - " been registered to a class, something is wrong, but " - "will forge on!\n", cls->name, drv); - - mutex_lock(&sysdev_drivers_lock); - if (cls && kset_get(&cls->kset)) { - list_add_tail(&drv->entry, &cls->drivers); - - /* If devices of this class already exist, tell the driver */ - if (drv->add) { - struct sys_device *dev; - list_for_each_entry(dev, &cls->kset.list, kobj.entry) - drv->add(dev); - } - } else { - err = -EINVAL; - WARN(1, KERN_ERR "%s: invalid device class\n", __func__); - } - mutex_unlock(&sysdev_drivers_lock); - return err; -} - - -/** - * sysdev_driver_unregister - Remove an auxillary driver. - * @cls: Class driver belongs to. - * @drv: Driver. - */ -void sysdev_driver_unregister(struct sysdev_class * cls, - struct sysdev_driver * drv) -{ - mutex_lock(&sysdev_drivers_lock); - list_del_init(&drv->entry); - if (cls) { - if (drv->remove) { - struct sys_device *dev; - list_for_each_entry(dev, &cls->kset.list, kobj.entry) - drv->remove(dev); - } - kset_put(&cls->kset); - } - mutex_unlock(&sysdev_drivers_lock); -} - -EXPORT_SYMBOL_GPL(sysdev_driver_register); -EXPORT_SYMBOL_GPL(sysdev_driver_unregister); - - - -/** - * sysdev_register - add a system device to the tree - * @sysdev: device in question - * - */ -int sysdev_register(struct sys_device * sysdev) -{ - int error; - struct sysdev_class * cls = sysdev->cls; - - if (!cls) - return -EINVAL; - - pr_debug("Registering sys device of class '%s'\n", - kobject_name(&cls->kset.kobj)); - - /* initialize the kobject to 0, in case it had previously been used */ - memset(&sysdev->kobj, 0x00, sizeof(struct kobject)); - - /* Make sure the kset is set */ - sysdev->kobj.kset = &cls->kset; - - /* Register the object */ - error = kobject_init_and_add(&sysdev->kobj, &ktype_sysdev, NULL, - "%s%d", kobject_name(&cls->kset.kobj), - sysdev->id); - - if (!error) { - struct sysdev_driver * drv; - - pr_debug("Registering sys device '%s'\n", - kobject_name(&sysdev->kobj)); - - mutex_lock(&sysdev_drivers_lock); - /* Generic notification is implicit, because it's that - * code that should have called us. - */ - - /* Notify class auxillary drivers */ - list_for_each_entry(drv, &cls->drivers, entry) { - if (drv->add) - drv->add(sysdev); - } - mutex_unlock(&sysdev_drivers_lock); - } - - kobject_uevent(&sysdev->kobj, KOBJ_ADD); - return error; -} - -void sysdev_unregister(struct sys_device * sysdev) -{ - struct sysdev_driver * drv; - - mutex_lock(&sysdev_drivers_lock); - list_for_each_entry(drv, &sysdev->cls->drivers, entry) { - if (drv->remove) - drv->remove(sysdev); - } - mutex_unlock(&sysdev_drivers_lock); - - kobject_put(&sysdev->kobj); -} - - - -/** - * sysdev_shutdown - Shut down all system devices. - * - * 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 auxillaries, - * 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. - */ -void sysdev_shutdown(void) -{ - struct sysdev_class * cls; - - pr_debug("Shutting Down System Devices\n"); - - mutex_lock(&sysdev_drivers_lock); - list_for_each_entry_reverse(cls, &system_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) { - struct sysdev_driver * drv; - pr_debug(" %s\n", kobject_name(&sysdev->kobj)); - - /* Call auxillary drivers first */ - list_for_each_entry(drv, &cls->drivers, entry) { - if (drv->shutdown) - drv->shutdown(sysdev); - } - - /* Now call the generic one */ - if (cls->shutdown) - cls->shutdown(sysdev); - } - } - mutex_unlock(&sysdev_drivers_lock); -} - -static void __sysdev_resume(struct sys_device *dev) -{ - struct sysdev_class *cls = dev->cls; - struct sysdev_driver *drv; - - /* First, call the class-specific one */ - if (cls->resume) - cls->resume(dev); - - /* Call auxillary drivers next. */ - list_for_each_entry(drv, &cls->drivers, entry) { - if (drv->resume) - drv->resume(dev); - } -} - -/** - * sysdev_suspend - Suspend all system devices. - * @state: Power state to enter. - * - * We perform an almost identical operation as sysdev_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. - * - * This is only called by the device PM core, so we let them handle - * all synchronization. - */ -int sysdev_suspend(pm_message_t state) -{ - struct sysdev_class * cls; - struct sys_device *sysdev, *err_dev; - struct sysdev_driver *drv, *err_drv; - int ret; - - pr_debug("Suspending System Devices\n"); - - list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) { - pr_debug("Suspending type '%s':\n", - kobject_name(&cls->kset.kobj)); - - list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { - pr_debug(" %s\n", kobject_name(&sysdev->kobj)); - - /* Call auxillary drivers first */ - list_for_each_entry(drv, &cls->drivers, entry) { - if (drv->suspend) { - ret = drv->suspend(sysdev, state); - if (ret) - goto aux_driver; - } - } - - /* Now call the generic one */ - if (cls->suspend) { - ret = cls->suspend(sysdev, state); - if (ret) - goto cls_driver; - } - } - } - return 0; - /* resume current sysdev */ -cls_driver: - drv = NULL; - printk(KERN_ERR "Class suspend failed for %s\n", - kobject_name(&sysdev->kobj)); - -aux_driver: - if (drv) - printk(KERN_ERR "Class driver suspend failed for %s\n", - kobject_name(&sysdev->kobj)); - list_for_each_entry(err_drv, &cls->drivers, entry) { - if (err_drv == drv) - break; - if (err_drv->resume) - err_drv->resume(sysdev); - } - - /* resume other sysdevs in current class */ - list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) { - if (err_dev == sysdev) - break; - pr_debug(" %s\n", kobject_name(&err_dev->kobj)); - __sysdev_resume(err_dev); - } - - /* resume other classes */ - list_for_each_entry_continue(cls, &system_kset->list, kset.kobj.entry) { - list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) { - pr_debug(" %s\n", kobject_name(&err_dev->kobj)); - __sysdev_resume(err_dev); - } - } - return ret; -} -EXPORT_SYMBOL_GPL(sysdev_suspend); - -/** - * sysdev_resume - Bring system devices back to life. - * - * Similar to sysdev_suspend(), but we iterate the list forwards - * to guarantee that parent devices are resumed before their children. - * - * Note: Interrupts are disabled when called. - */ -int sysdev_resume(void) -{ - struct sysdev_class * cls; - - pr_debug("Resuming System Devices\n"); - - list_for_each_entry(cls, &system_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) { - pr_debug(" %s\n", kobject_name(&sysdev->kobj)); - - __sysdev_resume(sysdev); - } - } - return 0; -} -EXPORT_SYMBOL_GPL(sysdev_resume); - -int __init system_bus_init(void) -{ - system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj); - if (!system_kset) - return -ENOMEM; - return 0; -} - -EXPORT_SYMBOL_GPL(sysdev_register); -EXPORT_SYMBOL_GPL(sysdev_unregister); - -#define to_ext_attr(x) container_of(x, struct sysdev_ext_attribute, attr) - -ssize_t sysdev_store_ulong(struct sys_device *sysdev, - struct sysdev_attribute *attr, - const char *buf, size_t size) -{ - struct sysdev_ext_attribute *ea = to_ext_attr(attr); - char *end; - unsigned long new = simple_strtoul(buf, &end, 0); - if (end == buf) - return -EINVAL; - *(unsigned long *)(ea->var) = new; - /* Always return full write size even if we didn't consume all */ - return size; -} -EXPORT_SYMBOL_GPL(sysdev_store_ulong); - -ssize_t sysdev_show_ulong(struct sys_device *sysdev, - struct sysdev_attribute *attr, - char *buf) -{ - struct sysdev_ext_attribute *ea = to_ext_attr(attr); - return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var)); -} -EXPORT_SYMBOL_GPL(sysdev_show_ulong); - -ssize_t sysdev_store_int(struct sys_device *sysdev, - struct sysdev_attribute *attr, - const char *buf, size_t size) -{ - struct sysdev_ext_attribute *ea = to_ext_attr(attr); - char *end; - long new = simple_strtol(buf, &end, 0); - if (end == buf || new > INT_MAX || new < INT_MIN) - return -EINVAL; - *(int *)(ea->var) = new; - /* Always return full write size even if we didn't consume all */ - return size; -} -EXPORT_SYMBOL_GPL(sysdev_store_int); - -ssize_t sysdev_show_int(struct sys_device *sysdev, - struct sysdev_attribute *attr, - char *buf) -{ - struct sysdev_ext_attribute *ea = to_ext_attr(attr); - return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var)); -} -EXPORT_SYMBOL_GPL(sysdev_show_int); - |