diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2013-07-27 22:07:53 +0000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2013-07-27 22:07:53 +0000 |
commit | 4fbe7358c7747a9165f776eb19addbb9baf7def2 (patch) | |
tree | bc7076b4f6d10c2cc2942539bb666e50f0b66954 /libdde_linux26/contrib/drivers | |
parent | 21adb5284111190057db245cfc2b54091920c373 (diff) |
rename libdde_linux26 into libdde-linux26 to make dpkg-source happy
Diffstat (limited to 'libdde_linux26/contrib/drivers')
20 files changed, 0 insertions, 7861 deletions
diff --git a/libdde_linux26/contrib/drivers/amba/bus.c b/libdde_linux26/contrib/drivers/amba/bus.c deleted file mode 100644 index 00c46e0b..00000000 --- a/libdde_linux26/contrib/drivers/amba/bus.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * linux/arch/arm/common/amba.c - * - * Copyright (C) 2003 Deep Blue Solutions Ltd, All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/module.h> -#include <linux/init.h> -#include <linux/device.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/io.h> -#include <linux/amba/bus.h> - -#include <asm/irq.h> -#include <asm/sizes.h> - -#define to_amba_device(d) container_of(d, struct amba_device, dev) -#define to_amba_driver(d) container_of(d, struct amba_driver, drv) - -static struct amba_id * -amba_lookup(struct amba_id *table, struct amba_device *dev) -{ - int ret = 0; - - while (table->mask) { - ret = (dev->periphid & table->mask) == table->id; - if (ret) - break; - table++; - } - - return ret ? table : NULL; -} - -static int amba_match(struct device *dev, struct device_driver *drv) -{ - struct amba_device *pcdev = to_amba_device(dev); - struct amba_driver *pcdrv = to_amba_driver(drv); - - return amba_lookup(pcdrv->id_table, pcdev) != NULL; -} - -#ifdef CONFIG_HOTPLUG -static int amba_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - struct amba_device *pcdev = to_amba_device(dev); - int retval = 0; - - retval = add_uevent_var(env, "AMBA_ID=%08x", pcdev->periphid); - return retval; -} -#else -#define amba_uevent NULL -#endif - -static int amba_suspend(struct device *dev, pm_message_t state) -{ - struct amba_driver *drv = to_amba_driver(dev->driver); - int ret = 0; - - if (dev->driver && drv->suspend) - ret = drv->suspend(to_amba_device(dev), state); - return ret; -} - -static int amba_resume(struct device *dev) -{ - struct amba_driver *drv = to_amba_driver(dev->driver); - int ret = 0; - - if (dev->driver && drv->resume) - ret = drv->resume(to_amba_device(dev)); - return ret; -} - -#define amba_attr_func(name,fmt,arg...) \ -static ssize_t name##_show(struct device *_dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - struct amba_device *dev = to_amba_device(_dev); \ - return sprintf(buf, fmt, arg); \ -} - -#define amba_attr(name,fmt,arg...) \ -amba_attr_func(name,fmt,arg) \ -static DEVICE_ATTR(name, S_IRUGO, name##_show, NULL) - -amba_attr_func(id, "%08x\n", dev->periphid); -amba_attr(irq0, "%u\n", dev->irq[0]); -amba_attr(irq1, "%u\n", dev->irq[1]); -amba_attr_func(resource, "\t%016llx\t%016llx\t%016lx\n", - (unsigned long long)dev->res.start, (unsigned long long)dev->res.end, - dev->res.flags); - -static struct device_attribute amba_dev_attrs[] = { - __ATTR_RO(id), - __ATTR_RO(resource), - __ATTR_NULL, -}; - -/* - * Primecells are part of the Advanced Microcontroller Bus Architecture, - * so we call the bus "amba". - */ -static struct bus_type amba_bustype = { - .name = "amba", - .dev_attrs = amba_dev_attrs, - .match = amba_match, - .uevent = amba_uevent, - .suspend = amba_suspend, - .resume = amba_resume, -}; - -static int __init amba_init(void) -{ - return bus_register(&amba_bustype); -} - -postcore_initcall(amba_init); - -/* - * These are the device model conversion veneers; they convert the - * device model structures to our more specific structures. - */ -static int amba_probe(struct device *dev) -{ - struct amba_device *pcdev = to_amba_device(dev); - struct amba_driver *pcdrv = to_amba_driver(dev->driver); - struct amba_id *id; - - id = amba_lookup(pcdrv->id_table, pcdev); - - return pcdrv->probe(pcdev, id); -} - -static int amba_remove(struct device *dev) -{ - struct amba_driver *drv = to_amba_driver(dev->driver); - return drv->remove(to_amba_device(dev)); -} - -static void amba_shutdown(struct device *dev) -{ - struct amba_driver *drv = to_amba_driver(dev->driver); - drv->shutdown(to_amba_device(dev)); -} - -/** - * amba_driver_register - register an AMBA device driver - * @drv: amba device driver structure - * - * Register an AMBA device driver with the Linux device model - * core. If devices pre-exist, the drivers probe function will - * be called. - */ -int amba_driver_register(struct amba_driver *drv) -{ - drv->drv.bus = &amba_bustype; - -#define SETFN(fn) if (drv->fn) drv->drv.fn = amba_##fn - SETFN(probe); - SETFN(remove); - SETFN(shutdown); - - return driver_register(&drv->drv); -} - -/** - * amba_driver_unregister - remove an AMBA device driver - * @drv: AMBA device driver structure to remove - * - * Unregister an AMBA device driver from the Linux device - * model. The device model will call the drivers remove function - * for each device the device driver is currently handling. - */ -void amba_driver_unregister(struct amba_driver *drv) -{ - driver_unregister(&drv->drv); -} - - -static void amba_device_release(struct device *dev) -{ - struct amba_device *d = to_amba_device(dev); - - if (d->res.parent) - release_resource(&d->res); - kfree(d); -} - -/** - * amba_device_register - register an AMBA device - * @dev: AMBA device to register - * @parent: parent memory resource - * - * Setup the AMBA device, reading the cell ID if present. - * Claim the resource, and register the AMBA device with - * the Linux device manager. - */ -int amba_device_register(struct amba_device *dev, struct resource *parent) -{ - u32 pid, cid; - void __iomem *tmp; - int i, ret; - - dev->dev.release = amba_device_release; - dev->dev.bus = &amba_bustype; - dev->dev.dma_mask = &dev->dma_mask; - dev->res.name = dev->dev.bus_id; - - if (!dev->dev.coherent_dma_mask && dev->dma_mask) - dev_warn(&dev->dev, "coherent dma mask is unset\n"); - - ret = request_resource(parent, &dev->res); - if (ret) - goto err_out; - - tmp = ioremap(dev->res.start, SZ_4K); - if (!tmp) { - ret = -ENOMEM; - goto err_release; - } - - for (pid = 0, i = 0; i < 4; i++) - pid |= (readl(tmp + 0xfe0 + 4 * i) & 255) << (i * 8); - for (cid = 0, i = 0; i < 4; i++) - cid |= (readl(tmp + 0xff0 + 4 * i) & 255) << (i * 8); - - iounmap(tmp); - - if (cid == 0xb105f00d) - dev->periphid = pid; - - if (!dev->periphid) { - ret = -ENODEV; - goto err_release; - } - - ret = device_register(&dev->dev); - if (ret) - goto err_release; - - if (dev->irq[0] != NO_IRQ) - ret = device_create_file(&dev->dev, &dev_attr_irq0); - if (ret == 0 && dev->irq[1] != NO_IRQ) - ret = device_create_file(&dev->dev, &dev_attr_irq1); - if (ret == 0) - return ret; - - device_unregister(&dev->dev); - - err_release: - release_resource(&dev->res); - err_out: - return ret; -} - -/** - * amba_device_unregister - unregister an AMBA device - * @dev: AMBA device to remove - * - * Remove the specified AMBA device from the Linux device - * manager. All files associated with this object will be - * destroyed, and device drivers notified that the device has - * been removed. The AMBA device's resources including - * the amba_device structure will be freed once all - * references to it have been dropped. - */ -void amba_device_unregister(struct amba_device *dev) -{ - device_unregister(&dev->dev); -} - - -struct find_data { - struct amba_device *dev; - struct device *parent; - const char *busid; - unsigned int id; - unsigned int mask; -}; - -static int amba_find_match(struct device *dev, void *data) -{ - struct find_data *d = data; - struct amba_device *pcdev = to_amba_device(dev); - int r; - - r = (pcdev->periphid & d->mask) == d->id; - if (d->parent) - r &= d->parent == dev->parent; - if (d->busid) - r &= strcmp(dev->bus_id, d->busid) == 0; - - if (r) { - get_device(dev); - d->dev = pcdev; - } - - return r; -} - -/** - * amba_find_device - locate an AMBA device given a bus id - * @busid: bus id for device (or NULL) - * @parent: parent device (or NULL) - * @id: peripheral ID (or 0) - * @mask: peripheral ID mask (or 0) - * - * Return the AMBA device corresponding to the supplied parameters. - * If no device matches, returns NULL. - * - * NOTE: When a valid device is found, its refcount is - * incremented, and must be decremented before the returned - * reference. - */ -struct amba_device * -amba_find_device(const char *busid, struct device *parent, unsigned int id, - unsigned int mask) -{ - struct find_data data; - - data.dev = NULL; - data.parent = parent; - data.busid = busid; - data.id = id; - data.mask = mask; - - bus_for_each_dev(&amba_bustype, NULL, &data, amba_find_match); - - return data.dev; -} - -/** - * amba_request_regions - request all mem regions associated with device - * @dev: amba_device structure for device - * @name: name, or NULL to use driver name - */ -int amba_request_regions(struct amba_device *dev, const char *name) -{ - int ret = 0; - - if (!name) - name = dev->dev.driver->name; - - if (!request_mem_region(dev->res.start, SZ_4K, name)) - ret = -EBUSY; - - return ret; -} - -/** - * amba_release_regions - release mem regions assoicated with device - * @dev: amba_device structure for device - * - * Release regions claimed by a successful call to amba_request_regions. - */ -void amba_release_regions(struct amba_device *dev) -{ - release_mem_region(dev->res.start, SZ_4K); -} - -EXPORT_SYMBOL(amba_driver_register); -EXPORT_SYMBOL(amba_driver_unregister); -EXPORT_SYMBOL(amba_device_register); -EXPORT_SYMBOL(amba_device_unregister); -EXPORT_SYMBOL(amba_find_device); -EXPORT_SYMBOL(amba_request_regions); -EXPORT_SYMBOL(amba_release_regions); 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); - diff --git a/libdde_linux26/contrib/drivers/net/mii.c b/libdde_linux26/contrib/drivers/net/mii.c deleted file mode 100644 index 92056051..00000000 --- a/libdde_linux26/contrib/drivers/net/mii.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - - mii.c: MII interface library - - Maintained by Jeff Garzik <jgarzik@pobox.com> - Copyright 2001,2002 Jeff Garzik - - Various code came from myson803.c and other files by - Donald Becker. Copyright: - - Written 1998-2002 by Donald Becker. - - This software may be used and distributed according - to the terms of the GNU General Public License (GPL), - incorporated herein by reference. Drivers based on - or derived from this code fall under the GPL and must - retain the authorship, copyright and license notice. - This file is not a complete program and may only be - used when the entire operating system is licensed - under the GPL. - - The author may be reached as becker@scyld.com, or C/O - Scyld Computing Corporation - 410 Severn Ave., Suite 210 - Annapolis MD 21403 - - - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/netdevice.h> -#include <linux/ethtool.h> -#include <linux/mii.h> - -/** - * mii_ethtool_gset - get settings that are specified in @ecmd - * @mii: MII interface - * @ecmd: requested ethtool_cmd - * - * Returns 0 for success, negative on error. - */ -int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd) -{ - struct net_device *dev = mii->dev; - u32 advert, bmcr, lpa, nego; - u32 advert2 = 0, bmcr2 = 0, lpa2 = 0; - - ecmd->supported = - (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | - SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII); - if (mii->supports_gmii) - ecmd->supported |= SUPPORTED_1000baseT_Half | - SUPPORTED_1000baseT_Full; - - /* only supports twisted-pair */ - ecmd->port = PORT_MII; - - /* only supports internal transceiver */ - ecmd->transceiver = XCVR_INTERNAL; - - /* this isn't fully supported at higher layers */ - ecmd->phy_address = mii->phy_id; - - ecmd->advertising = ADVERTISED_TP | ADVERTISED_MII; - advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE); - if (mii->supports_gmii) - advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000); - - if (advert & ADVERTISE_10HALF) - ecmd->advertising |= ADVERTISED_10baseT_Half; - if (advert & ADVERTISE_10FULL) - ecmd->advertising |= ADVERTISED_10baseT_Full; - if (advert & ADVERTISE_100HALF) - ecmd->advertising |= ADVERTISED_100baseT_Half; - if (advert & ADVERTISE_100FULL) - ecmd->advertising |= ADVERTISED_100baseT_Full; - if (advert2 & ADVERTISE_1000HALF) - ecmd->advertising |= ADVERTISED_1000baseT_Half; - if (advert2 & ADVERTISE_1000FULL) - ecmd->advertising |= ADVERTISED_1000baseT_Full; - - bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR); - lpa = mii->mdio_read(dev, mii->phy_id, MII_LPA); - if (mii->supports_gmii) { - bmcr2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000); - lpa2 = mii->mdio_read(dev, mii->phy_id, MII_STAT1000); - } - if (bmcr & BMCR_ANENABLE) { - ecmd->advertising |= ADVERTISED_Autoneg; - ecmd->autoneg = AUTONEG_ENABLE; - - nego = mii_nway_result(advert & lpa); - if ((bmcr2 & (ADVERTISE_1000HALF | ADVERTISE_1000FULL)) & - (lpa2 >> 2)) - ecmd->speed = SPEED_1000; - else if (nego == LPA_100FULL || nego == LPA_100HALF) - ecmd->speed = SPEED_100; - else - ecmd->speed = SPEED_10; - if ((lpa2 & LPA_1000FULL) || nego == LPA_100FULL || - nego == LPA_10FULL) { - ecmd->duplex = DUPLEX_FULL; - mii->full_duplex = 1; - } else { - ecmd->duplex = DUPLEX_HALF; - mii->full_duplex = 0; - } - } else { - ecmd->autoneg = AUTONEG_DISABLE; - - ecmd->speed = ((bmcr & BMCR_SPEED1000 && - (bmcr & BMCR_SPEED100) == 0) ? SPEED_1000 : - (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10); - ecmd->duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF; - } - - /* ignore maxtxpkt, maxrxpkt for now */ - - return 0; -} - -/** - * mii_ethtool_sset - set settings that are specified in @ecmd - * @mii: MII interface - * @ecmd: requested ethtool_cmd - * - * Returns 0 for success, negative on error. - */ -int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd) -{ - struct net_device *dev = mii->dev; - - if (ecmd->speed != SPEED_10 && - ecmd->speed != SPEED_100 && - ecmd->speed != SPEED_1000) - return -EINVAL; - if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL) - return -EINVAL; - if (ecmd->port != PORT_MII) - return -EINVAL; - if (ecmd->transceiver != XCVR_INTERNAL) - return -EINVAL; - if (ecmd->phy_address != mii->phy_id) - return -EINVAL; - if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE) - return -EINVAL; - if ((ecmd->speed == SPEED_1000) && (!mii->supports_gmii)) - return -EINVAL; - - /* ignore supported, maxtxpkt, maxrxpkt */ - - if (ecmd->autoneg == AUTONEG_ENABLE) { - u32 bmcr, advert, tmp; - u32 advert2 = 0, tmp2 = 0; - - if ((ecmd->advertising & (ADVERTISED_10baseT_Half | - ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | - ADVERTISED_100baseT_Full | - ADVERTISED_1000baseT_Half | - ADVERTISED_1000baseT_Full)) == 0) - return -EINVAL; - - /* advertise only what has been requested */ - advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE); - tmp = advert & ~(ADVERTISE_ALL | ADVERTISE_100BASE4); - if (mii->supports_gmii) { - advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000); - tmp2 = advert2 & ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL); - } - if (ecmd->advertising & ADVERTISED_10baseT_Half) - tmp |= ADVERTISE_10HALF; - if (ecmd->advertising & ADVERTISED_10baseT_Full) - tmp |= ADVERTISE_10FULL; - if (ecmd->advertising & ADVERTISED_100baseT_Half) - tmp |= ADVERTISE_100HALF; - if (ecmd->advertising & ADVERTISED_100baseT_Full) - tmp |= ADVERTISE_100FULL; - if (mii->supports_gmii) { - if (ecmd->advertising & ADVERTISED_1000baseT_Half) - tmp2 |= ADVERTISE_1000HALF; - if (ecmd->advertising & ADVERTISED_1000baseT_Full) - tmp2 |= ADVERTISE_1000FULL; - } - if (advert != tmp) { - mii->mdio_write(dev, mii->phy_id, MII_ADVERTISE, tmp); - mii->advertising = tmp; - } - if ((mii->supports_gmii) && (advert2 != tmp2)) - mii->mdio_write(dev, mii->phy_id, MII_CTRL1000, tmp2); - - /* turn on autonegotiation, and force a renegotiate */ - bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR); - bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); - mii->mdio_write(dev, mii->phy_id, MII_BMCR, bmcr); - - mii->force_media = 0; - } else { - u32 bmcr, tmp; - - /* turn off auto negotiation, set speed and duplexity */ - bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR); - tmp = bmcr & ~(BMCR_ANENABLE | BMCR_SPEED100 | - BMCR_SPEED1000 | BMCR_FULLDPLX); - if (ecmd->speed == SPEED_1000) - tmp |= BMCR_SPEED1000; - else if (ecmd->speed == SPEED_100) - tmp |= BMCR_SPEED100; - if (ecmd->duplex == DUPLEX_FULL) { - tmp |= BMCR_FULLDPLX; - mii->full_duplex = 1; - } else - mii->full_duplex = 0; - if (bmcr != tmp) - mii->mdio_write(dev, mii->phy_id, MII_BMCR, tmp); - - mii->force_media = 1; - } - return 0; -} - -/** - * mii_check_gmii_support - check if the MII supports Gb interfaces - * @mii: the MII interface - */ -int mii_check_gmii_support(struct mii_if_info *mii) -{ - int reg; - - reg = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR); - if (reg & BMSR_ESTATEN) { - reg = mii->mdio_read(mii->dev, mii->phy_id, MII_ESTATUS); - if (reg & (ESTATUS_1000_TFULL | ESTATUS_1000_THALF)) - return 1; - } - - return 0; -} - -/** - * mii_link_ok - is link status up/ok - * @mii: the MII interface - * - * Returns 1 if the MII reports link status up/ok, 0 otherwise. - */ -int mii_link_ok (struct mii_if_info *mii) -{ - /* first, a dummy read, needed to latch some MII phys */ - mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR); - if (mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR) & BMSR_LSTATUS) - return 1; - return 0; -} - -/** - * mii_nway_restart - restart NWay (autonegotiation) for this interface - * @mii: the MII interface - * - * Returns 0 on success, negative on error. - */ -int mii_nway_restart (struct mii_if_info *mii) -{ - int bmcr; - int r = -EINVAL; - - /* if autoneg is off, it's an error */ - bmcr = mii->mdio_read(mii->dev, mii->phy_id, MII_BMCR); - - if (bmcr & BMCR_ANENABLE) { - bmcr |= BMCR_ANRESTART; - mii->mdio_write(mii->dev, mii->phy_id, MII_BMCR, bmcr); - r = 0; - } - - return r; -} - -/** - * mii_check_link - check MII link status - * @mii: MII interface - * - * If the link status changed (previous != current), call - * netif_carrier_on() if current link status is Up or call - * netif_carrier_off() if current link status is Down. - */ -void mii_check_link (struct mii_if_info *mii) -{ - int cur_link = mii_link_ok(mii); - int prev_link = netif_carrier_ok(mii->dev); - - if (cur_link && !prev_link) - netif_carrier_on(mii->dev); - else if (prev_link && !cur_link) - netif_carrier_off(mii->dev); -} - -/** - * mii_check_media - check the MII interface for a duplex change - * @mii: the MII interface - * @ok_to_print: OK to print link up/down messages - * @init_media: OK to save duplex mode in @mii - * - * Returns 1 if the duplex mode changed, 0 if not. - * If the media type is forced, always returns 0. - */ -unsigned int mii_check_media (struct mii_if_info *mii, - unsigned int ok_to_print, - unsigned int init_media) -{ - unsigned int old_carrier, new_carrier; - int advertise, lpa, media, duplex; - int lpa2 = 0; - - /* if forced media, go no further */ - if (mii->force_media) - return 0; /* duplex did not change */ - - /* check current and old link status */ - old_carrier = netif_carrier_ok(mii->dev) ? 1 : 0; - new_carrier = (unsigned int) mii_link_ok(mii); - - /* if carrier state did not change, this is a "bounce", - * just exit as everything is already set correctly - */ - if ((!init_media) && (old_carrier == new_carrier)) - return 0; /* duplex did not change */ - - /* no carrier, nothing much to do */ - if (!new_carrier) { - netif_carrier_off(mii->dev); - if (ok_to_print) - printk(KERN_INFO "%s: link down\n", mii->dev->name); - return 0; /* duplex did not change */ - } - - /* - * we have carrier, see who's on the other end - */ - netif_carrier_on(mii->dev); - - /* get MII advertise and LPA values */ - if ((!init_media) && (mii->advertising)) - advertise = mii->advertising; - else { - advertise = mii->mdio_read(mii->dev, mii->phy_id, MII_ADVERTISE); - mii->advertising = advertise; - } - lpa = mii->mdio_read(mii->dev, mii->phy_id, MII_LPA); - if (mii->supports_gmii) - lpa2 = mii->mdio_read(mii->dev, mii->phy_id, MII_STAT1000); - - /* figure out media and duplex from advertise and LPA values */ - media = mii_nway_result(lpa & advertise); - duplex = (media & ADVERTISE_FULL) ? 1 : 0; - if (lpa2 & LPA_1000FULL) - duplex = 1; - - if (ok_to_print) - printk(KERN_INFO "%s: link up, %sMbps, %s-duplex, lpa 0x%04X\n", - mii->dev->name, - lpa2 & (LPA_1000FULL | LPA_1000HALF) ? "1000" : - media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? "100" : "10", - duplex ? "full" : "half", - lpa); - - if ((init_media) || (mii->full_duplex != duplex)) { - mii->full_duplex = duplex; - return 1; /* duplex changed */ - } - - return 0; /* duplex did not change */ -} - -/** - * generic_mii_ioctl - main MII ioctl interface - * @mii_if: the MII interface - * @mii_data: MII ioctl data structure - * @cmd: MII ioctl command - * @duplex_chg_out: pointer to @duplex_changed status if there was no - * ioctl error - * - * Returns 0 on success, negative on error. - */ -int generic_mii_ioctl(struct mii_if_info *mii_if, - struct mii_ioctl_data *mii_data, int cmd, - unsigned int *duplex_chg_out) -{ - int rc = 0; - unsigned int duplex_changed = 0; - - if (duplex_chg_out) - *duplex_chg_out = 0; - - mii_data->phy_id &= mii_if->phy_id_mask; - mii_data->reg_num &= mii_if->reg_num_mask; - - switch(cmd) { - case SIOCGMIIPHY: - mii_data->phy_id = mii_if->phy_id; - /* fall through */ - - case SIOCGMIIREG: - mii_data->val_out = - mii_if->mdio_read(mii_if->dev, mii_data->phy_id, - mii_data->reg_num); - break; - - case SIOCSMIIREG: { - u16 val = mii_data->val_in; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - if (mii_data->phy_id == mii_if->phy_id) { - switch(mii_data->reg_num) { - case MII_BMCR: { - unsigned int new_duplex = 0; - if (val & (BMCR_RESET|BMCR_ANENABLE)) - mii_if->force_media = 0; - else - mii_if->force_media = 1; - if (mii_if->force_media && - (val & BMCR_FULLDPLX)) - new_duplex = 1; - if (mii_if->full_duplex != new_duplex) { - duplex_changed = 1; - mii_if->full_duplex = new_duplex; - } - break; - } - case MII_ADVERTISE: - mii_if->advertising = val; - break; - default: - /* do nothing */ - break; - } - } - - mii_if->mdio_write(mii_if->dev, mii_data->phy_id, - mii_data->reg_num, val); - break; - } - - default: - rc = -EOPNOTSUPP; - break; - } - - if ((rc == 0) && (duplex_chg_out) && (duplex_changed)) - *duplex_chg_out = 1; - - return rc; -} - -MODULE_AUTHOR ("Jeff Garzik <jgarzik@pobox.com>"); -MODULE_DESCRIPTION ("MII hardware support library"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(mii_link_ok); -EXPORT_SYMBOL(mii_nway_restart); -EXPORT_SYMBOL(mii_ethtool_gset); -EXPORT_SYMBOL(mii_ethtool_sset); -EXPORT_SYMBOL(mii_check_link); -EXPORT_SYMBOL(mii_check_media); -EXPORT_SYMBOL(mii_check_gmii_support); -EXPORT_SYMBOL(generic_mii_ioctl); - diff --git a/libdde_linux26/contrib/drivers/pci/access.c b/libdde_linux26/contrib/drivers/pci/access.c deleted file mode 100644 index 9d05aea2..00000000 --- a/libdde_linux26/contrib/drivers/pci/access.c +++ /dev/null @@ -1,410 +0,0 @@ -#include <linux/delay.h> -#include <linux/pci.h> -#include <linux/module.h> -#include <linux/sched.h> -#include <linux/ioport.h> -#include <linux/wait.h> - -#include "pci.h" -#include <ddekit/timer.h> - -/* - * This interrupt-safe spinlock protects all accesses to PCI - * configuration space. - */ - -static DEFINE_SPINLOCK(pci_lock); - -/* - * Wrappers for all PCI configuration access functions. They just check - * alignment, do locking and call the low-level functions pointed to - * by pci_dev->ops. - */ - -#define PCI_byte_BAD 0 -#define PCI_word_BAD (pos & 1) -#define PCI_dword_BAD (pos & 3) - -#define PCI_OP_READ(size,type,len) \ -int pci_bus_read_config_##size \ - (struct pci_bus *bus, unsigned int devfn, int pos, type *value) \ -{ \ - int res; \ - unsigned long flags; \ - u32 data = 0; \ - if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ - spin_lock_irqsave(&pci_lock, flags); \ - res = bus->ops->read(bus, devfn, pos, len, &data); \ - *value = (type)data; \ - spin_unlock_irqrestore(&pci_lock, flags); \ - return res; \ -} - -#define PCI_OP_WRITE(size,type,len) \ -int pci_bus_write_config_##size \ - (struct pci_bus *bus, unsigned int devfn, int pos, type value) \ -{ \ - int res; \ - unsigned long flags; \ - if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ - spin_lock_irqsave(&pci_lock, flags); \ - res = bus->ops->write(bus, devfn, pos, len, value); \ - spin_unlock_irqrestore(&pci_lock, flags); \ - return res; \ -} - -PCI_OP_READ(byte, u8, 1) -PCI_OP_READ(word, u16, 2) -PCI_OP_READ(dword, u32, 4) -PCI_OP_WRITE(byte, u8, 1) -PCI_OP_WRITE(word, u16, 2) -PCI_OP_WRITE(dword, u32, 4) - -EXPORT_SYMBOL(pci_bus_read_config_byte); -EXPORT_SYMBOL(pci_bus_read_config_word); -EXPORT_SYMBOL(pci_bus_read_config_dword); -EXPORT_SYMBOL(pci_bus_write_config_byte); -EXPORT_SYMBOL(pci_bus_write_config_word); -EXPORT_SYMBOL(pci_bus_write_config_dword); - - -/** - * pci_read_vpd - Read one entry from Vital Product Data - * @dev: pci device struct - * @pos: offset in vpd space - * @count: number of bytes to read - * @buf: pointer to where to store result - * - */ -ssize_t pci_read_vpd(struct pci_dev *dev, loff_t pos, size_t count, void *buf) -{ - if (!dev->vpd || !dev->vpd->ops) - return -ENODEV; - return dev->vpd->ops->read(dev, pos, count, buf); -} -EXPORT_SYMBOL(pci_read_vpd); - -/** - * pci_write_vpd - Write entry to Vital Product Data - * @dev: pci device struct - * @pos: offset in vpd space - * @count: number of bytes to read - * @val: value to write - * - */ -ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void *buf) -{ - if (!dev->vpd || !dev->vpd->ops) - return -ENODEV; - return dev->vpd->ops->write(dev, pos, count, buf); -} -EXPORT_SYMBOL(pci_write_vpd); - -/* - * The following routines are to prevent the user from accessing PCI config - * space when it's unsafe to do so. Some devices require this during BIST and - * we're required to prevent it during D-state transitions. - * - * We have a bit per device to indicate it's blocked and a global wait queue - * for callers to sleep on until devices are unblocked. - */ -static DECLARE_WAIT_QUEUE_HEAD(pci_ucfg_wait); - -static noinline void pci_wait_ucfg(struct pci_dev *dev) -{ - DECLARE_WAITQUEUE(wait, current); - - __add_wait_queue(&pci_ucfg_wait, &wait); - do { - set_current_state(TASK_UNINTERRUPTIBLE); - spin_unlock_irq(&pci_lock); - schedule(); - spin_lock_irq(&pci_lock); - } while (dev->block_ucfg_access); - __remove_wait_queue(&pci_ucfg_wait, &wait); -} - -#define PCI_USER_READ_CONFIG(size,type) \ -int pci_user_read_config_##size \ - (struct pci_dev *dev, int pos, type *val) \ -{ \ - int ret = 0; \ - u32 data = -1; \ - if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ - spin_lock_irq(&pci_lock); \ - if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \ - ret = dev->bus->ops->read(dev->bus, dev->devfn, \ - pos, sizeof(type), &data); \ - spin_unlock_irq(&pci_lock); \ - *val = (type)data; \ - return ret; \ -} - -#define PCI_USER_WRITE_CONFIG(size,type) \ -int pci_user_write_config_##size \ - (struct pci_dev *dev, int pos, type val) \ -{ \ - int ret = -EIO; \ - if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ - spin_lock_irq(&pci_lock); \ - if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \ - ret = dev->bus->ops->write(dev->bus, dev->devfn, \ - pos, sizeof(type), val); \ - spin_unlock_irq(&pci_lock); \ - return ret; \ -} - -PCI_USER_READ_CONFIG(byte, u8) -PCI_USER_READ_CONFIG(word, u16) -PCI_USER_READ_CONFIG(dword, u32) -PCI_USER_WRITE_CONFIG(byte, u8) -PCI_USER_WRITE_CONFIG(word, u16) -PCI_USER_WRITE_CONFIG(dword, u32) - -/* VPD access through PCI 2.2+ VPD capability */ - -#define PCI_VPD_PCI22_SIZE (PCI_VPD_ADDR_MASK + 1) - -struct pci_vpd_pci22 { - struct pci_vpd base; - struct mutex lock; - u16 flag; - bool busy; - u8 cap; -}; - -/* - * Wait for last operation to complete. - * This code has to spin since there is no other notification from the PCI - * hardware. Since the VPD is often implemented by serial attachment to an - * EEPROM, it may take many milliseconds to complete. - */ -static int pci_vpd_pci22_wait(struct pci_dev *dev) -{ - struct pci_vpd_pci22 *vpd = - container_of(dev->vpd, struct pci_vpd_pci22, base); - unsigned long timeout = jiffies + HZ/20 + 2; - u16 status; - int ret; - - if (!vpd->busy) - return 0; - - for (;;) { - ret = pci_user_read_config_word(dev, vpd->cap + PCI_VPD_ADDR, - &status); - if (ret) - return ret; - - if ((status & PCI_VPD_ADDR_F) == vpd->flag) { - vpd->busy = false; - return 0; - } - - if (time_after(jiffies, timeout)) - return -ETIMEDOUT; - if (fatal_signal_pending(current)) - return -EINTR; - if (!cond_resched()) - udelay(10); - } -} - -static ssize_t pci_vpd_pci22_read(struct pci_dev *dev, loff_t pos, size_t count, - void *arg) -{ - struct pci_vpd_pci22 *vpd = - container_of(dev->vpd, struct pci_vpd_pci22, base); - int ret; - loff_t end = pos + count; - u8 *buf = arg; - - if (pos < 0 || pos > vpd->base.len || end > vpd->base.len) - return -EINVAL; - - if (mutex_lock_killable(&vpd->lock)) - return -EINTR; - - ret = pci_vpd_pci22_wait(dev); - if (ret < 0) - goto out; - - while (pos < end) { - u32 val; - unsigned int i, skip; - - ret = pci_user_write_config_word(dev, vpd->cap + PCI_VPD_ADDR, - pos & ~3); - if (ret < 0) - break; - vpd->busy = true; - vpd->flag = PCI_VPD_ADDR_F; - ret = pci_vpd_pci22_wait(dev); - if (ret < 0) - break; - - ret = pci_user_read_config_dword(dev, vpd->cap + PCI_VPD_DATA, &val); - if (ret < 0) - break; - - skip = pos & 3; - for (i = 0; i < sizeof(u32); i++) { - if (i >= skip) { - *buf++ = val; - if (++pos == end) - break; - } - val >>= 8; - } - } -out: - mutex_unlock(&vpd->lock); - return ret ? ret : count; -} - -static ssize_t pci_vpd_pci22_write(struct pci_dev *dev, loff_t pos, size_t count, - const void *arg) -{ - struct pci_vpd_pci22 *vpd = - container_of(dev->vpd, struct pci_vpd_pci22, base); - const u8 *buf = arg; - loff_t end = pos + count; - int ret = 0; - - if (pos < 0 || (pos & 3) || (count & 3) || end > vpd->base.len) - return -EINVAL; - - if (mutex_lock_killable(&vpd->lock)) - return -EINTR; - - ret = pci_vpd_pci22_wait(dev); - if (ret < 0) - goto out; - - while (pos < end) { - u32 val; - - val = *buf++; - val |= *buf++ << 8; - val |= *buf++ << 16; - val |= *buf++ << 24; - - ret = pci_user_write_config_dword(dev, vpd->cap + PCI_VPD_DATA, val); - if (ret < 0) - break; - ret = pci_user_write_config_word(dev, vpd->cap + PCI_VPD_ADDR, - pos | PCI_VPD_ADDR_F); - if (ret < 0) - break; - - vpd->busy = true; - vpd->flag = 0; - ret = pci_vpd_pci22_wait(dev); - - pos += sizeof(u32); - } -out: - mutex_unlock(&vpd->lock); - return ret ? ret : count; -} - -static void pci_vpd_pci22_release(struct pci_dev *dev) -{ - kfree(container_of(dev->vpd, struct pci_vpd_pci22, base)); -} - -static const struct pci_vpd_ops pci_vpd_pci22_ops = { - .read = pci_vpd_pci22_read, - .write = pci_vpd_pci22_write, - .release = pci_vpd_pci22_release, -}; - -int pci_vpd_pci22_init(struct pci_dev *dev) -{ - struct pci_vpd_pci22 *vpd; - u8 cap; - - cap = pci_find_capability(dev, PCI_CAP_ID_VPD); - if (!cap) - return -ENODEV; - vpd = kzalloc(sizeof(*vpd), GFP_ATOMIC); - if (!vpd) - return -ENOMEM; - - vpd->base.len = PCI_VPD_PCI22_SIZE; - vpd->base.ops = &pci_vpd_pci22_ops; - mutex_init(&vpd->lock); - vpd->cap = cap; - vpd->busy = false; - dev->vpd = &vpd->base; - return 0; -} - -/** - * pci_vpd_truncate - Set available Vital Product Data size - * @dev: pci device struct - * @size: available memory in bytes - * - * Adjust size of available VPD area. - */ -int pci_vpd_truncate(struct pci_dev *dev, size_t size) -{ - if (!dev->vpd) - return -EINVAL; - - /* limited by the access method */ - if (size > dev->vpd->len) - return -EINVAL; - - dev->vpd->len = size; - dev->vpd->attr->size = size; - - return 0; -} -EXPORT_SYMBOL(pci_vpd_truncate); - -/** - * pci_block_user_cfg_access - Block userspace PCI config reads/writes - * @dev: pci device struct - * - * When user access is blocked, any reads or writes to config space will - * sleep until access is unblocked again. We don't allow nesting of - * block/unblock calls. - */ -void pci_block_user_cfg_access(struct pci_dev *dev) -{ - unsigned long flags; - int was_blocked; - - spin_lock_irqsave(&pci_lock, flags); - was_blocked = dev->block_ucfg_access; - dev->block_ucfg_access = 1; - spin_unlock_irqrestore(&pci_lock, flags); - - /* If we BUG() inside the pci_lock, we're guaranteed to hose - * the machine */ - BUG_ON(was_blocked); -} -EXPORT_SYMBOL_GPL(pci_block_user_cfg_access); - -/** - * pci_unblock_user_cfg_access - Unblock userspace PCI config reads/writes - * @dev: pci device struct - * - * This function allows userspace PCI config accesses to resume. - */ -void pci_unblock_user_cfg_access(struct pci_dev *dev) -{ - unsigned long flags; - - spin_lock_irqsave(&pci_lock, flags); - - /* This indicates a problem in the caller, but we don't need - * to kill them, unlike a double-block above. */ - WARN_ON(!dev->block_ucfg_access); - - dev->block_ucfg_access = 0; - wake_up_all(&pci_ucfg_wait); - spin_unlock_irqrestore(&pci_lock, flags); -} -EXPORT_SYMBOL_GPL(pci_unblock_user_cfg_access); diff --git a/libdde_linux26/contrib/drivers/pci/bus.c b/libdde_linux26/contrib/drivers/pci/bus.c deleted file mode 100644 index 52b54f05..00000000 --- a/libdde_linux26/contrib/drivers/pci/bus.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * drivers/pci/bus.c - * - * From setup-res.c, by: - * Dave Rusling (david.rusling@reo.mts.dec.com) - * David Mosberger (davidm@cs.arizona.edu) - * David Miller (davem@redhat.com) - * Ivan Kokshaysky (ink@jurassic.park.msu.ru) - */ -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/pci.h> -#include <linux/errno.h> -#include <linux/ioport.h> -#include <linux/proc_fs.h> -#include <linux/init.h> - -#include "pci.h" - -/** - * pci_bus_alloc_resource - allocate a resource from a parent bus - * @bus: PCI bus - * @res: resource to allocate - * @size: size of resource to allocate - * @align: alignment of resource to allocate - * @min: minimum /proc/iomem address to allocate - * @type_mask: IORESOURCE_* type flags - * @alignf: resource alignment function - * @alignf_data: data argument for resource alignment function - * - * Given the PCI bus a device resides on, the size, minimum address, - * alignment and type, try to find an acceptable resource allocation - * for a specific device resource. - */ -int -pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, - resource_size_t size, resource_size_t align, - resource_size_t min, unsigned int type_mask, - void (*alignf)(void *, struct resource *, resource_size_t, - resource_size_t), - void *alignf_data) -{ - int i, ret = -ENOMEM; - - type_mask |= IORESOURCE_IO | IORESOURCE_MEM; - - for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { - struct resource *r = bus->resource[i]; - if (!r) - continue; - - /* type_mask must match */ - if ((res->flags ^ r->flags) & type_mask) - continue; - - /* We cannot allocate a non-prefetching resource - from a pre-fetching area */ - if ((r->flags & IORESOURCE_PREFETCH) && - !(res->flags & IORESOURCE_PREFETCH)) - continue; - - /* Ok, try it out.. */ - ret = allocate_resource(r, res, size, - r->start ? : min, - -1, align, - alignf, alignf_data); - if (ret == 0) - break; - } - return ret; -} - -/** - * pci_bus_add_device - add a single device - * @dev: device to add - * - * This adds a single pci device to the global - * device list and adds sysfs and procfs entries - */ -int pci_bus_add_device(struct pci_dev *dev) -{ - int retval; - retval = device_add(&dev->dev); - if (retval) - return retval; - - dev->is_added = 1; - pci_proc_attach_device(dev); - pci_create_sysfs_dev_files(dev); - return 0; -} - -/** - * pci_bus_add_child - add a child bus - * @bus: bus to add - * - * This adds sysfs entries for a single bus - */ -int pci_bus_add_child(struct pci_bus *bus) -{ - int retval; - - if (bus->bridge) - bus->dev.parent = bus->bridge; - - retval = device_register(&bus->dev); - if (retval) - return retval; - - bus->is_added = 1; - - retval = device_create_file(&bus->dev, &dev_attr_cpuaffinity); - if (retval) - return retval; - - retval = device_create_file(&bus->dev, &dev_attr_cpulistaffinity); - - /* Create legacy_io and legacy_mem files for this bus */ - pci_create_legacy_files(bus); - - return retval; -} - -/** - * pci_bus_add_devices - insert newly discovered PCI devices - * @bus: bus to check for new devices - * - * Add newly discovered PCI devices (which are on the bus->devices - * list) to the global PCI device list, add the sysfs and procfs - * entries. Where a bridge is found, add the discovered bus to - * the parents list of child buses, and recurse (breadth-first - * to be compatible with 2.4) - * - * Call hotplug for each new devices. - */ -void pci_bus_add_devices(struct pci_bus *bus) -{ - struct pci_dev *dev; - struct pci_bus *child; - int retval; - - list_for_each_entry(dev, &bus->devices, bus_list) { - /* Skip already-added devices */ - if (dev->is_added) - continue; - retval = pci_bus_add_device(dev); - if (retval) - dev_err(&dev->dev, "Error adding device, continuing\n"); - } - - list_for_each_entry(dev, &bus->devices, bus_list) { - BUG_ON(!dev->is_added); - - child = dev->subordinate; - /* - * If there is an unattached subordinate bus, attach - * it and then scan for unattached PCI devices. - */ - if (!child) - continue; - if (list_empty(&child->node)) { - down_write(&pci_bus_sem); - list_add_tail(&child->node, &dev->bus->children); - up_write(&pci_bus_sem); - } - pci_bus_add_devices(child); - - /* - * register the bus with sysfs as the parent is now - * properly registered. - */ - if (child->is_added) - continue; - retval = pci_bus_add_child(child); - if (retval) - dev_err(&dev->dev, "Error adding bus, continuing\n"); - } -} - -void pci_enable_bridges(struct pci_bus *bus) -{ - struct pci_dev *dev; - int retval; - - list_for_each_entry(dev, &bus->devices, bus_list) { - if (dev->subordinate) { - retval = pci_enable_device(dev); - pci_set_master(dev); - pci_enable_bridges(dev->subordinate); - } - } -} - -/** pci_walk_bus - walk devices on/under bus, calling callback. - * @top bus whose devices should be walked - * @cb callback to be called for each device found - * @userdata arbitrary pointer to be passed to callback. - * - * Walk the given bus, including any bridged devices - * on buses under this bus. Call the provided callback - * on each device found. - */ -void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *), - void *userdata) -{ - struct pci_dev *dev; - struct pci_bus *bus; - struct list_head *next; - - bus = top; - down_read(&pci_bus_sem); - next = top->devices.next; - for (;;) { - if (next == &bus->devices) { - /* end of this bus, go up or finish */ - if (bus == top) - break; - next = bus->self->bus_list.next; - bus = bus->self->bus; - continue; - } - dev = list_entry(next, struct pci_dev, bus_list); - if (dev->subordinate) { - /* this is a pci-pci bridge, do its devices next */ - next = dev->subordinate->devices.next; - bus = dev->subordinate; - } else - next = dev->bus_list.next; - - /* Run device routines with the device locked */ - down(&dev->dev.sem); - cb(dev, userdata); - up(&dev->dev.sem); - } - up_read(&pci_bus_sem); -} - -EXPORT_SYMBOL(pci_bus_alloc_resource); -EXPORT_SYMBOL_GPL(pci_bus_add_device); -EXPORT_SYMBOL(pci_bus_add_devices); -EXPORT_SYMBOL(pci_enable_bridges); diff --git a/libdde_linux26/contrib/drivers/pci/hotplug-pci.c b/libdde_linux26/contrib/drivers/pci/hotplug-pci.c deleted file mode 100644 index 4d4a6447..00000000 --- a/libdde_linux26/contrib/drivers/pci/hotplug-pci.c +++ /dev/null @@ -1,20 +0,0 @@ -/* Core PCI functionality used only by PCI hotplug */ - -#include <linux/pci.h> -#include "pci.h" - - -unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus) -{ - unsigned int max; - - max = pci_scan_child_bus(bus); - - /* - * Make the discovered devices available. - */ - pci_bus_add_devices(bus); - - return max; -} -EXPORT_SYMBOL(pci_do_scan_bus); diff --git a/libdde_linux26/contrib/drivers/pci/pci.h b/libdde_linux26/contrib/drivers/pci/pci.h deleted file mode 100644 index 07c0aa52..00000000 --- a/libdde_linux26/contrib/drivers/pci/pci.h +++ /dev/null @@ -1,198 +0,0 @@ -#ifndef DRIVERS_PCI_H -#define DRIVERS_PCI_H - -#define PCI_CFG_SPACE_SIZE 256 -#define PCI_CFG_SPACE_EXP_SIZE 4096 - -/* Functions internal to the PCI core code */ - -extern int pci_uevent(struct device *dev, struct kobj_uevent_env *env); -extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); -extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); -extern void pci_cleanup_rom(struct pci_dev *dev); -#ifdef HAVE_PCI_MMAP -extern int pci_mmap_fits(struct pci_dev *pdev, int resno, - struct vm_area_struct *vma); -#endif - -/** - * struct pci_platform_pm_ops - Firmware PM callbacks - * - * @is_manageable: returns 'true' if given device is power manageable by the - * platform firmware - * - * @set_state: invokes the platform firmware to set the device's power state - * - * @choose_state: returns PCI power state of given device preferred by the - * platform; to be used during system-wide transitions from a - * sleeping state to the working state and vice versa - * - * @can_wakeup: returns 'true' if given device is capable of waking up the - * system from a sleeping state - * - * @sleep_wake: enables/disables the system wake up capability of given device - * - * If given platform is generally capable of power managing PCI devices, all of - * these callbacks are mandatory. - */ -struct pci_platform_pm_ops { - bool (*is_manageable)(struct pci_dev *dev); - int (*set_state)(struct pci_dev *dev, pci_power_t state); - pci_power_t (*choose_state)(struct pci_dev *dev); - bool (*can_wakeup)(struct pci_dev *dev); - int (*sleep_wake)(struct pci_dev *dev, bool enable); -}; - -extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops); -extern void pci_update_current_state(struct pci_dev *dev, pci_power_t state); -extern void pci_disable_enabled_device(struct pci_dev *dev); -extern void pci_pm_init(struct pci_dev *dev); -extern void platform_pci_wakeup_init(struct pci_dev *dev); -extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); -extern int pci_restore_standard_config(struct pci_dev *dev); - -static inline bool pci_is_bridge(struct pci_dev *pci_dev) -{ - return !!(pci_dev->subordinate); -} - -extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val); -extern int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val); -extern int pci_user_read_config_dword(struct pci_dev *dev, int where, u32 *val); -extern int pci_user_write_config_byte(struct pci_dev *dev, int where, u8 val); -extern int pci_user_write_config_word(struct pci_dev *dev, int where, u16 val); -extern int pci_user_write_config_dword(struct pci_dev *dev, int where, u32 val); - -struct pci_vpd_ops { - ssize_t (*read)(struct pci_dev *dev, loff_t pos, size_t count, void *buf); - ssize_t (*write)(struct pci_dev *dev, loff_t pos, size_t count, const void *buf); - void (*release)(struct pci_dev *dev); -}; - -struct pci_vpd { - unsigned int len; - const struct pci_vpd_ops *ops; - struct bin_attribute *attr; /* descriptor for sysfs VPD entry */ -}; - -extern int pci_vpd_pci22_init(struct pci_dev *dev); -static inline void pci_vpd_release(struct pci_dev *dev) -{ - if (dev->vpd) - dev->vpd->ops->release(dev); -} - -/* PCI /proc functions */ -#ifdef CONFIG_PROC_FS -extern int pci_proc_attach_device(struct pci_dev *dev); -extern int pci_proc_detach_device(struct pci_dev *dev); -extern int pci_proc_detach_bus(struct pci_bus *bus); -#else -static inline int pci_proc_attach_device(struct pci_dev *dev) { return 0; } -static inline int pci_proc_detach_device(struct pci_dev *dev) { return 0; } -static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; } -#endif - -/* Functions for PCI Hotplug drivers to use */ -extern unsigned int pci_do_scan_bus(struct pci_bus *bus); - -#ifdef HAVE_PCI_LEGACY -extern void pci_create_legacy_files(struct pci_bus *bus); -extern void pci_remove_legacy_files(struct pci_bus *bus); -#else -static inline void pci_create_legacy_files(struct pci_bus *bus) { return; } -static inline void pci_remove_legacy_files(struct pci_bus *bus) { return; } -#endif - -/* Lock for read/write access to pci device and bus lists */ -extern struct rw_semaphore pci_bus_sem; - -extern unsigned int pci_pm_d3_delay; - -#ifdef CONFIG_PCI_MSI -void pci_no_msi(void); -extern void pci_msi_init_pci_dev(struct pci_dev *dev); -#else -static inline void pci_no_msi(void) { } -static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } -#endif - -#ifdef CONFIG_PCIEAER -void pci_no_aer(void); -#else -static inline void pci_no_aer(void) { } -#endif - -static inline int pci_no_d1d2(struct pci_dev *dev) -{ - unsigned int parent_dstates = 0; - - if (dev->bus->self) - parent_dstates = dev->bus->self->no_d1d2; - return (dev->no_d1d2 || parent_dstates); - -} -extern int pcie_mch_quirk; -extern struct device_attribute pci_dev_attrs[]; -extern struct device_attribute dev_attr_cpuaffinity; -extern struct device_attribute dev_attr_cpulistaffinity; - -/** - * pci_match_one_device - Tell if a PCI device structure has a matching - * PCI device id structure - * @id: single PCI device id structure to match - * @dev: the PCI device structure to match against - * - * Returns the matching pci_device_id structure or %NULL if there is no match. - */ -static inline const struct pci_device_id * -pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev) -{ - if ((id->vendor == PCI_ANY_ID || id->vendor == dev->vendor) && - (id->device == PCI_ANY_ID || id->device == dev->device) && - (id->subvendor == PCI_ANY_ID || id->subvendor == dev->subsystem_vendor) && - (id->subdevice == PCI_ANY_ID || id->subdevice == dev->subsystem_device) && - !((id->class ^ dev->class) & id->class_mask)) - return id; - return NULL; -} - -struct pci_dev *pci_find_upstream_pcie_bridge(struct pci_dev *pdev); - -/* PCI slot sysfs helper code */ -#define to_pci_slot(s) container_of(s, struct pci_slot, kobj) - -extern struct kset *pci_slots_kset; - -struct pci_slot_attribute { - struct attribute attr; - ssize_t (*show)(struct pci_slot *, char *); - ssize_t (*store)(struct pci_slot *, const char *, size_t); -}; -#define to_pci_slot_attr(s) container_of(s, struct pci_slot_attribute, attr) - -enum pci_bar_type { - pci_bar_unknown, /* Standard PCI BAR probe */ - pci_bar_io, /* An io port BAR */ - pci_bar_mem32, /* A 32-bit memory BAR */ - pci_bar_mem64, /* A 64-bit memory BAR */ -}; - -extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, - struct resource *res, unsigned int reg); -extern int pci_resource_bar(struct pci_dev *dev, int resno, - enum pci_bar_type *type); -extern int pci_bus_add_child(struct pci_bus *bus); -extern void pci_enable_ari(struct pci_dev *dev); -/** - * pci_ari_enabled - query ARI forwarding status - * @bus: the PCI bus - * - * Returns 1 if ARI forwarding is enabled, or 0 if not enabled; - */ -static inline int pci_ari_enabled(struct pci_bus *bus) -{ - return bus->self && bus->self->ari_enabled; -} - -#endif /* DRIVERS_PCI_H */ diff --git a/libdde_linux26/contrib/drivers/pci/search.c b/libdde_linux26/contrib/drivers/pci/search.c deleted file mode 100644 index 5af8bd53..00000000 --- a/libdde_linux26/contrib/drivers/pci/search.c +++ /dev/null @@ -1,419 +0,0 @@ -/* - * PCI searching functions. - * - * Copyright (C) 1993 -- 1997 Drew Eckhardt, Frederic Potter, - * David Mosberger-Tang - * Copyright (C) 1997 -- 2000 Martin Mares <mj@ucw.cz> - * Copyright (C) 2003 -- 2004 Greg Kroah-Hartman <greg@kroah.com> - */ - -#include <linux/init.h> -#include <linux/pci.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include "pci.h" - -DECLARE_RWSEM(pci_bus_sem); -/* - * find the upstream PCIE-to-PCI bridge of a PCI device - * if the device is PCIE, return NULL - * if the device isn't connected to a PCIE bridge (that is its parent is a - * legacy PCI bridge and the bridge is directly connected to bus 0), return its - * parent - */ -struct pci_dev * -pci_find_upstream_pcie_bridge(struct pci_dev *pdev) -{ - struct pci_dev *tmp = NULL; - - if (pdev->is_pcie) - return NULL; - while (1) { - if (!pdev->bus->self) - break; - pdev = pdev->bus->self; - /* a p2p bridge */ - if (!pdev->is_pcie) { - tmp = pdev; - continue; - } - /* PCI device should connect to a PCIE bridge */ - if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) { - /* Busted hardware? */ - WARN_ON_ONCE(1); - return NULL; - } - return pdev; - } - - return tmp; -} - -static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr) -{ - struct pci_bus* child; - struct list_head *tmp; - - if(bus->number == busnr) - return bus; - - list_for_each(tmp, &bus->children) { - child = pci_do_find_bus(pci_bus_b(tmp), busnr); - if(child) - return child; - } - return NULL; -} - -/** - * pci_find_bus - locate PCI bus from a given domain and bus number - * @domain: number of PCI domain to search - * @busnr: number of desired PCI bus - * - * Given a PCI bus number and domain number, the desired PCI bus is located - * in the global list of PCI buses. If the bus is found, a pointer to its - * data structure is returned. If no bus is found, %NULL is returned. - */ -struct pci_bus * pci_find_bus(int domain, int busnr) -{ - struct pci_bus *bus = NULL; - struct pci_bus *tmp_bus; - - while ((bus = pci_find_next_bus(bus)) != NULL) { - if (pci_domain_nr(bus) != domain) - continue; - tmp_bus = pci_do_find_bus(bus, busnr); - if (tmp_bus) - return tmp_bus; - } - return NULL; -} - -/** - * pci_find_next_bus - begin or continue searching for a PCI bus - * @from: Previous PCI bus found, or %NULL for new search. - * - * Iterates through the list of known PCI busses. A new search is - * initiated by passing %NULL as the @from argument. Otherwise if - * @from is not %NULL, searches continue from next device on the - * global list. - */ -struct pci_bus * -pci_find_next_bus(const struct pci_bus *from) -{ - struct list_head *n; - struct pci_bus *b = NULL; - - WARN_ON(in_interrupt()); - down_read(&pci_bus_sem); - n = from ? from->node.next : pci_root_buses.next; - if (n != &pci_root_buses) - b = pci_bus_b(n); - up_read(&pci_bus_sem); - return b; -} - -#ifdef CONFIG_PCI_LEGACY -/** - * pci_find_slot - locate PCI device from a given PCI slot - * @bus: number of PCI bus on which desired PCI device resides - * @devfn: encodes number of PCI slot in which the desired PCI - * device resides and the logical device number within that slot - * in case of multi-function devices. - * - * Given a PCI bus and slot/function number, the desired PCI device - * is located in system global list of PCI devices. If the device - * is found, a pointer to its data structure is returned. If no - * device is found, %NULL is returned. - * - * NOTE: Do not use this function any more; use pci_get_slot() instead, as - * the PCI device returned by this function can disappear at any moment in - * time. - */ -struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn) -{ - struct pci_dev *dev = NULL; - - while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - if (dev->bus->number == bus && dev->devfn == devfn) { - pci_dev_put(dev); - return dev; - } - } - return NULL; -} -EXPORT_SYMBOL(pci_find_slot); - -/** - * pci_find_device - begin or continue searching for a PCI device by vendor/device id - * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids - * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids - * @from: Previous PCI device found in search, or %NULL for new search. - * - * Iterates through the list of known PCI devices. If a PCI device is found - * with a matching @vendor and @device, a pointer to its device structure is - * returned. Otherwise, %NULL is returned. - * A new search is initiated by passing %NULL as the @from argument. - * Otherwise if @from is not %NULL, searches continue from next device - * on the global list. - * - * NOTE: Do not use this function any more; use pci_get_device() instead, as - * the PCI device returned by this function can disappear at any moment in - * time. - */ -struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device, - struct pci_dev *from) -{ - struct pci_dev *pdev; - - pci_dev_get(from); - pdev = pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from); - pci_dev_put(pdev); - return pdev; -} -EXPORT_SYMBOL(pci_find_device); -#endif /* CONFIG_PCI_LEGACY */ - -/** - * pci_get_slot - locate PCI device for a given PCI slot - * @bus: PCI bus on which desired PCI device resides - * @devfn: encodes number of PCI slot in which the desired PCI - * device resides and the logical device number within that slot - * in case of multi-function devices. - * - * Given a PCI bus and slot/function number, the desired PCI device - * is located in the list of PCI devices. - * If the device is found, its reference count is increased and this - * function returns a pointer to its data structure. The caller must - * decrement the reference count by calling pci_dev_put(). - * If no device is found, %NULL is returned. - */ -struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn) -{ - struct list_head *tmp; - struct pci_dev *dev; - - WARN_ON(in_interrupt()); - down_read(&pci_bus_sem); - - list_for_each(tmp, &bus->devices) { - dev = pci_dev_b(tmp); - if (dev->devfn == devfn) - goto out; - } - - dev = NULL; - out: - pci_dev_get(dev); - up_read(&pci_bus_sem); - return dev; -} - -/** - * pci_get_bus_and_slot - locate PCI device from a given PCI bus & slot - * @bus: number of PCI bus on which desired PCI device resides - * @devfn: encodes number of PCI slot in which the desired PCI - * device resides and the logical device number within that slot - * in case of multi-function devices. - * - * Note: the bus/slot search is limited to PCI domain (segment) 0. - * - * Given a PCI bus and slot/function number, the desired PCI device - * is located in system global list of PCI devices. If the device - * is found, a pointer to its data structure is returned. If no - * device is found, %NULL is returned. The returned device has its - * reference count bumped by one. - */ - -struct pci_dev * pci_get_bus_and_slot(unsigned int bus, unsigned int devfn) -{ - struct pci_dev *dev = NULL; - - while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - if (pci_domain_nr(dev->bus) == 0 && - (dev->bus->number == bus && dev->devfn == devfn)) - return dev; - } - return NULL; -} - -static int match_pci_dev_by_id(struct device *dev, void *data) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct pci_device_id *id = data; - - if (pci_match_one_device(id, pdev)) - return 1; - return 0; -} - -/* - * pci_get_dev_by_id - begin or continue searching for a PCI device by id - * @id: pointer to struct pci_device_id to match for the device - * @from: Previous PCI device found in search, or %NULL for new search. - * - * Iterates through the list of known PCI devices. If a PCI device is found - * with a matching id a pointer to its device structure is returned, and the - * reference count to the device is incremented. Otherwise, %NULL is returned. - * A new search is initiated by passing %NULL as the @from argument. Otherwise - * if @from is not %NULL, searches continue from next device on the global - * list. The reference count for @from is always decremented if it is not - * %NULL. - * - * This is an internal function for use by the other search functions in - * this file. - */ -static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id, - struct pci_dev *from) -{ - struct device *dev; - struct device *dev_start = NULL; - struct pci_dev *pdev = NULL; - - WARN_ON(in_interrupt()); - if (from) - dev_start = &from->dev; - dev = bus_find_device(&pci_bus_type, dev_start, (void *)id, - match_pci_dev_by_id); - if (dev) - pdev = to_pci_dev(dev); - if (from) - pci_dev_put(from); - return pdev; -} - -/** - * pci_get_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id - * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids - * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids - * @ss_vendor: PCI subsystem vendor id to match, or %PCI_ANY_ID to match all vendor ids - * @ss_device: PCI subsystem device id to match, or %PCI_ANY_ID to match all device ids - * @from: Previous PCI device found in search, or %NULL for new search. - * - * Iterates through the list of known PCI devices. If a PCI device is found - * with a matching @vendor, @device, @ss_vendor and @ss_device, a pointer to its - * device structure is returned, and the reference count to the device is - * incremented. Otherwise, %NULL is returned. A new search is initiated by - * passing %NULL as the @from argument. Otherwise if @from is not %NULL, - * searches continue from next device on the global list. - * The reference count for @from is always decremented if it is not %NULL. - */ -struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device, - unsigned int ss_vendor, unsigned int ss_device, - struct pci_dev *from) -{ - struct pci_dev *pdev; - struct pci_device_id *id; - - /* - * pci_find_subsys() can be called on the ide_setup() path, - * super-early in boot. But the down_read() will enable local - * interrupts, which can cause some machines to crash. So here we - * detect and flag that situation and bail out early. - */ - if (unlikely(no_pci_devices())) - return NULL; - - id = kzalloc(sizeof(*id), GFP_KERNEL); - if (!id) - return NULL; - id->vendor = vendor; - id->device = device; - id->subvendor = ss_vendor; - id->subdevice = ss_device; - - pdev = pci_get_dev_by_id(id, from); - kfree(id); - - return pdev; -} - -/** - * pci_get_device - begin or continue searching for a PCI device by vendor/device id - * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids - * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids - * @from: Previous PCI device found in search, or %NULL for new search. - * - * Iterates through the list of known PCI devices. If a PCI device is - * found with a matching @vendor and @device, the reference count to the - * device is incremented and a pointer to its device structure is returned. - * Otherwise, %NULL is returned. A new search is initiated by passing %NULL - * as the @from argument. Otherwise if @from is not %NULL, searches continue - * from next device on the global list. The reference count for @from is - * always decremented if it is not %NULL. - */ -struct pci_dev * -pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from) -{ - return pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from); -} - -/** - * pci_get_class - begin or continue searching for a PCI device by class - * @class: search for a PCI device with this class designation - * @from: Previous PCI device found in search, or %NULL for new search. - * - * Iterates through the list of known PCI devices. If a PCI device is - * found with a matching @class, the reference count to the device is - * incremented and a pointer to its device structure is returned. - * Otherwise, %NULL is returned. - * A new search is initiated by passing %NULL as the @from argument. - * Otherwise if @from is not %NULL, searches continue from next device - * on the global list. The reference count for @from is always decremented - * if it is not %NULL. - */ -struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from) -{ - struct pci_dev *dev; - struct pci_device_id *id; - - id = kzalloc(sizeof(*id), GFP_KERNEL); - if (!id) - return NULL; - id->vendor = id->device = id->subvendor = id->subdevice = PCI_ANY_ID; - id->class_mask = PCI_ANY_ID; - id->class = class; - - dev = pci_get_dev_by_id(id, from); - kfree(id); - return dev; -} - -/** - * pci_dev_present - Returns 1 if device matching the device list is present, 0 if not. - * @ids: A pointer to a null terminated list of struct pci_device_id structures - * that describe the type of PCI device the caller is trying to find. - * - * Obvious fact: You do not have a reference to any device that might be found - * by this function, so if that device is removed from the system right after - * this function is finished, the value will be stale. Use this function to - * find devices that are usually built into a system, or for a general hint as - * to if another device happens to be present at this specific moment in time. - */ -int pci_dev_present(const struct pci_device_id *ids) -{ - struct pci_dev *found = NULL; - - WARN_ON(in_interrupt()); - while (ids->vendor || ids->subvendor || ids->class_mask) { - found = pci_get_dev_by_id(ids, NULL); - if (found) - goto exit; - ids++; - } -exit: - if (found) - return 1; - return 0; -} -EXPORT_SYMBOL(pci_dev_present); - -/* For boot time work */ -EXPORT_SYMBOL(pci_find_bus); -EXPORT_SYMBOL(pci_find_next_bus); -/* For everyone */ -EXPORT_SYMBOL(pci_get_device); -EXPORT_SYMBOL(pci_get_subsys); -EXPORT_SYMBOL(pci_get_slot); -EXPORT_SYMBOL(pci_get_bus_and_slot); -EXPORT_SYMBOL(pci_get_class); diff --git a/libdde_linux26/contrib/drivers/pci/setup-bus.c b/libdde_linux26/contrib/drivers/pci/setup-bus.c deleted file mode 100644 index 70460894..00000000 --- a/libdde_linux26/contrib/drivers/pci/setup-bus.c +++ /dev/null @@ -1,581 +0,0 @@ -/* - * drivers/pci/setup-bus.c - * - * Extruded from code written by - * Dave Rusling (david.rusling@reo.mts.dec.com) - * David Mosberger (davidm@cs.arizona.edu) - * David Miller (davem@redhat.com) - * - * Support routines for initializing a PCI subsystem. - */ - -/* - * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru> - * PCI-PCI bridges cleanup, sorted resource allocation. - * Feb 2002, Ivan Kokshaysky <ink@jurassic.park.msu.ru> - * Converted to allocation in 3 passes, which gives - * tighter packing. Prefetchable range support. - */ - -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/errno.h> -#include <linux/ioport.h> -#include <linux/cache.h> -#include <linux/slab.h> - - -static void pbus_assign_resources_sorted(struct pci_bus *bus) -{ - struct pci_dev *dev; - struct resource *res; - struct resource_list head, *list, *tmp; - int idx; - - head.next = NULL; - list_for_each_entry(dev, &bus->devices, bus_list) { - u16 class = dev->class >> 8; - - /* Don't touch classless devices or host bridges or ioapics. */ - if (class == PCI_CLASS_NOT_DEFINED || - class == PCI_CLASS_BRIDGE_HOST) - continue; - - /* Don't touch ioapic devices already enabled by firmware */ - if (class == PCI_CLASS_SYSTEM_PIC) { - u16 command; - pci_read_config_word(dev, PCI_COMMAND, &command); - if (command & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) - continue; - } - - pdev_sort_resources(dev, &head); - } - - for (list = head.next; list;) { - res = list->res; - idx = res - &list->dev->resource[0]; - if (pci_assign_resource(list->dev, idx)) { - /* FIXME: get rid of this */ - res->start = 0; - res->end = 0; - res->flags = 0; - } - tmp = list; - list = list->next; - kfree(tmp); - } -} - -void pci_setup_cardbus(struct pci_bus *bus) -{ - struct pci_dev *bridge = bus->self; - struct pci_bus_region region; - - dev_info(&bridge->dev, "CardBus bridge, secondary bus %04x:%02x\n", - pci_domain_nr(bus), bus->number); - - pcibios_resource_to_bus(bridge, ®ion, bus->resource[0]); - if (bus->resource[0]->flags & IORESOURCE_IO) { - /* - * The IO resource is allocated a range twice as large as it - * would normally need. This allows us to set both IO regs. - */ - dev_info(&bridge->dev, " IO window: %#08lx-%#08lx\n", - (unsigned long)region.start, - (unsigned long)region.end); - pci_write_config_dword(bridge, PCI_CB_IO_BASE_0, - region.start); - pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0, - region.end); - } - - pcibios_resource_to_bus(bridge, ®ion, bus->resource[1]); - if (bus->resource[1]->flags & IORESOURCE_IO) { - dev_info(&bridge->dev, " IO window: %#08lx-%#08lx\n", - (unsigned long)region.start, - (unsigned long)region.end); - pci_write_config_dword(bridge, PCI_CB_IO_BASE_1, - region.start); - pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1, - region.end); - } - - pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]); - if (bus->resource[2]->flags & IORESOURCE_MEM) { - dev_info(&bridge->dev, " PREFETCH window: %#08lx-%#08lx\n", - (unsigned long)region.start, - (unsigned long)region.end); - pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0, - region.start); - pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0, - region.end); - } - - pcibios_resource_to_bus(bridge, ®ion, bus->resource[3]); - if (bus->resource[3]->flags & IORESOURCE_MEM) { - dev_info(&bridge->dev, " MEM window: %#08lx-%#08lx\n", - (unsigned long)region.start, - (unsigned long)region.end); - pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1, - region.start); - pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1, - region.end); - } -} -EXPORT_SYMBOL(pci_setup_cardbus); - -/* Initialize bridges with base/limit values we have collected. - PCI-to-PCI Bridge Architecture Specification rev. 1.1 (1998) - requires that if there is no I/O ports or memory behind the - bridge, corresponding range must be turned off by writing base - value greater than limit to the bridge's base/limit registers. - - Note: care must be taken when updating I/O base/limit registers - of bridges which support 32-bit I/O. This update requires two - config space writes, so it's quite possible that an I/O window of - the bridge will have some undesirable address (e.g. 0) after the - first write. Ditto 64-bit prefetchable MMIO. */ -static void pci_setup_bridge(struct pci_bus *bus) -{ - struct pci_dev *bridge = bus->self; - struct pci_bus_region region; - u32 l, bu, lu, io_upper16; - - dev_info(&bridge->dev, "PCI bridge, secondary bus %04x:%02x\n", - pci_domain_nr(bus), bus->number); - - /* Set up the top and bottom of the PCI I/O segment for this bus. */ - pcibios_resource_to_bus(bridge, ®ion, bus->resource[0]); - if (bus->resource[0]->flags & IORESOURCE_IO) { - pci_read_config_dword(bridge, PCI_IO_BASE, &l); - l &= 0xffff0000; - l |= (region.start >> 8) & 0x00f0; - l |= region.end & 0xf000; - /* Set up upper 16 bits of I/O base/limit. */ - io_upper16 = (region.end & 0xffff0000) | (region.start >> 16); - dev_info(&bridge->dev, " IO window: %#04lx-%#04lx\n", - (unsigned long)region.start, - (unsigned long)region.end); - } - else { - /* Clear upper 16 bits of I/O base/limit. */ - io_upper16 = 0; - l = 0x00f0; - dev_info(&bridge->dev, " IO window: disabled\n"); - } - /* Temporarily disable the I/O range before updating PCI_IO_BASE. */ - pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0x0000ffff); - /* Update lower 16 bits of I/O base/limit. */ - pci_write_config_dword(bridge, PCI_IO_BASE, l); - /* Update upper 16 bits of I/O base/limit. */ - pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, io_upper16); - - /* Set up the top and bottom of the PCI Memory segment - for this bus. */ - pcibios_resource_to_bus(bridge, ®ion, bus->resource[1]); - if (bus->resource[1]->flags & IORESOURCE_MEM) { - l = (region.start >> 16) & 0xfff0; - l |= region.end & 0xfff00000; - dev_info(&bridge->dev, " MEM window: %#08lx-%#08lx\n", - (unsigned long)region.start, - (unsigned long)region.end); - } - else { - l = 0x0000fff0; - dev_info(&bridge->dev, " MEM window: disabled\n"); - } - pci_write_config_dword(bridge, PCI_MEMORY_BASE, l); - - /* Clear out the upper 32 bits of PREF limit. - If PCI_PREF_BASE_UPPER32 was non-zero, this temporarily - disables PREF range, which is ok. */ - pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0); - - /* Set up PREF base/limit. */ - bu = lu = 0; - pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]); - if (bus->resource[2]->flags & IORESOURCE_PREFETCH) { - l = (region.start >> 16) & 0xfff0; - l |= region.end & 0xfff00000; - bu = upper_32_bits(region.start); - lu = upper_32_bits(region.end); - dev_info(&bridge->dev, " PREFETCH window: %#016llx-%#016llx\n", - (unsigned long long)region.start, - (unsigned long long)region.end); - } - else { - l = 0x0000fff0; - dev_info(&bridge->dev, " PREFETCH window: disabled\n"); - } - pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l); - - /* Set the upper 32 bits of PREF base & limit. */ - pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu); - pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu); - - pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); -} - -/* Check whether the bridge supports optional I/O and - prefetchable memory ranges. If not, the respective - base/limit registers must be read-only and read as 0. */ -static void pci_bridge_check_ranges(struct pci_bus *bus) -{ - u16 io; - u32 pmem; - struct pci_dev *bridge = bus->self; - struct resource *b_res; - - b_res = &bridge->resource[PCI_BRIDGE_RESOURCES]; - b_res[1].flags |= IORESOURCE_MEM; - - pci_read_config_word(bridge, PCI_IO_BASE, &io); - if (!io) { - pci_write_config_word(bridge, PCI_IO_BASE, 0xf0f0); - pci_read_config_word(bridge, PCI_IO_BASE, &io); - pci_write_config_word(bridge, PCI_IO_BASE, 0x0); - } - if (io) - b_res[0].flags |= IORESOURCE_IO; - /* DECchip 21050 pass 2 errata: the bridge may miss an address - disconnect boundary by one PCI data phase. - Workaround: do not use prefetching on this device. */ - if (bridge->vendor == PCI_VENDOR_ID_DEC && bridge->device == 0x0001) - return; - pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem); - if (!pmem) { - pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, - 0xfff0fff0); - pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem); - pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 0x0); - } - if (pmem) - b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH; -} - -/* Helper function for sizing routines: find first available - bus resource of a given type. Note: we intentionally skip - the bus resources which have already been assigned (that is, - have non-NULL parent resource). */ -static struct resource *find_free_bus_resource(struct pci_bus *bus, unsigned long type) -{ - int i; - struct resource *r; - unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | - IORESOURCE_PREFETCH; - - for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { - r = bus->resource[i]; - if (r == &ioport_resource || r == &iomem_resource) - continue; - if (r && (r->flags & type_mask) == type && !r->parent) - return r; - } - return NULL; -} - -/* Sizing the IO windows of the PCI-PCI bridge is trivial, - since these windows have 4K granularity and the IO ranges - of non-bridge PCI devices are limited to 256 bytes. - We must be careful with the ISA aliasing though. */ -static void pbus_size_io(struct pci_bus *bus) -{ - struct pci_dev *dev; - struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); - unsigned long size = 0, size1 = 0; - - if (!b_res) - return; - - list_for_each_entry(dev, &bus->devices, bus_list) { - int i; - - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - struct resource *r = &dev->resource[i]; - unsigned long r_size; - - if (r->parent || !(r->flags & IORESOURCE_IO)) - continue; - r_size = resource_size(r); - - if (r_size < 0x400) - /* Might be re-aligned for ISA */ - size += r_size; - else - size1 += r_size; - } - } -/* To be fixed in 2.5: we should have sort of HAVE_ISA - flag in the struct pci_bus. */ -#if defined(CONFIG_ISA) || defined(CONFIG_EISA) - size = (size & 0xff) + ((size & ~0xffUL) << 2); -#endif - size = ALIGN(size + size1, 4096); - if (!size) { - b_res->flags = 0; - return; - } - /* Alignment of the IO window is always 4K */ - b_res->start = 4096; - b_res->end = b_res->start + size - 1; - b_res->flags |= IORESOURCE_STARTALIGN; -} - -/* Calculate the size of the bus and minimal alignment which - guarantees that all child resources fit in this size. */ -static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type) -{ - struct pci_dev *dev; - resource_size_t min_align, align, size; - resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */ - int order, max_order; - struct resource *b_res = find_free_bus_resource(bus, type); - - if (!b_res) - return 0; - - memset(aligns, 0, sizeof(aligns)); - max_order = 0; - size = 0; - - list_for_each_entry(dev, &bus->devices, bus_list) { - int i; - - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - struct resource *r = &dev->resource[i]; - resource_size_t r_size; - - if (r->parent || (r->flags & mask) != type) - continue; - r_size = resource_size(r); - /* For bridges size != alignment */ - align = resource_alignment(r); - order = __ffs(align) - 20; - if (order > 11) { - dev_warn(&dev->dev, "BAR %d bad alignment %llx: " - "%pR\n", i, (unsigned long long)align, r); - r->flags = 0; - continue; - } - size += r_size; - if (order < 0) - order = 0; - /* Exclude ranges with size > align from - calculation of the alignment. */ - if (r_size == align) - aligns[order] += align; - if (order > max_order) - max_order = order; - } - } - - align = 0; - min_align = 0; - for (order = 0; order <= max_order; order++) { - resource_size_t align1 = 1; - - align1 <<= (order + 20); - - if (!align) - min_align = align1; - else if (ALIGN(align + min_align, min_align) < align1) - min_align = align1 >> 1; - align += aligns[order]; - } - size = ALIGN(size, min_align); - if (!size) { - b_res->flags = 0; - return 1; - } - b_res->start = min_align; - b_res->end = size + min_align - 1; - b_res->flags |= IORESOURCE_STARTALIGN; - return 1; -} - -static void pci_bus_size_cardbus(struct pci_bus *bus) -{ - struct pci_dev *bridge = bus->self; - struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES]; - u16 ctrl; - - /* - * Reserve some resources for CardBus. We reserve - * a fixed amount of bus space for CardBus bridges. - */ - b_res[0].start = 0; - b_res[0].end = pci_cardbus_io_size - 1; - b_res[0].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN; - - b_res[1].start = 0; - b_res[1].end = pci_cardbus_io_size - 1; - b_res[1].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN; - - /* - * Check whether prefetchable memory is supported - * by this bridge. - */ - pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); - if (!(ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0)) { - ctrl |= PCI_CB_BRIDGE_CTL_PREFETCH_MEM0; - pci_write_config_word(bridge, PCI_CB_BRIDGE_CONTROL, ctrl); - pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); - } - - /* - * If we have prefetchable memory support, allocate - * two regions. Otherwise, allocate one region of - * twice the size. - */ - if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) { - b_res[2].start = 0; - b_res[2].end = pci_cardbus_mem_size - 1; - b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_SIZEALIGN; - - b_res[3].start = 0; - b_res[3].end = pci_cardbus_mem_size - 1; - b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN; - } else { - b_res[3].start = 0; - b_res[3].end = pci_cardbus_mem_size * 2 - 1; - b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN; - } -} - -void __ref pci_bus_size_bridges(struct pci_bus *bus) -{ - struct pci_dev *dev; - unsigned long mask, prefmask; - - list_for_each_entry(dev, &bus->devices, bus_list) { - struct pci_bus *b = dev->subordinate; - if (!b) - continue; - - switch (dev->class >> 8) { - case PCI_CLASS_BRIDGE_CARDBUS: - pci_bus_size_cardbus(b); - break; - - case PCI_CLASS_BRIDGE_PCI: - default: - pci_bus_size_bridges(b); - break; - } - } - - /* The root bus? */ - if (!bus->self) - return; - - switch (bus->self->class >> 8) { - case PCI_CLASS_BRIDGE_CARDBUS: - /* don't size cardbuses yet. */ - break; - - case PCI_CLASS_BRIDGE_PCI: - pci_bridge_check_ranges(bus); - default: - pbus_size_io(bus); - /* If the bridge supports prefetchable range, size it - separately. If it doesn't, or its prefetchable window - has already been allocated by arch code, try - non-prefetchable range for both types of PCI memory - resources. */ - mask = IORESOURCE_MEM; - prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH; - if (pbus_size_mem(bus, prefmask, prefmask)) - mask = prefmask; /* Success, size non-prefetch only. */ - pbus_size_mem(bus, mask, IORESOURCE_MEM); - break; - } -} -EXPORT_SYMBOL(pci_bus_size_bridges); - -void __ref pci_bus_assign_resources(struct pci_bus *bus) -{ - struct pci_bus *b; - struct pci_dev *dev; - - pbus_assign_resources_sorted(bus); - - list_for_each_entry(dev, &bus->devices, bus_list) { - b = dev->subordinate; - if (!b) - continue; - - pci_bus_assign_resources(b); - - switch (dev->class >> 8) { - case PCI_CLASS_BRIDGE_PCI: - pci_setup_bridge(b); - break; - - case PCI_CLASS_BRIDGE_CARDBUS: - pci_setup_cardbus(b); - break; - - default: - dev_info(&dev->dev, "not setting up bridge for bus " - "%04x:%02x\n", pci_domain_nr(b), b->number); - break; - } - } -} -EXPORT_SYMBOL(pci_bus_assign_resources); - -static void pci_bus_dump_res(struct pci_bus *bus) -{ - int i; - - for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { - struct resource *res = bus->resource[i]; - if (!res) - continue; - - dev_printk(KERN_DEBUG, &bus->dev, "resource %d %s %pR\n", i, - (res->flags & IORESOURCE_IO) ? "io: " : "mem:", res); - } -} - -static void pci_bus_dump_resources(struct pci_bus *bus) -{ - struct pci_bus *b; - struct pci_dev *dev; - - - pci_bus_dump_res(bus); - - list_for_each_entry(dev, &bus->devices, bus_list) { - b = dev->subordinate; - if (!b) - continue; - - pci_bus_dump_resources(b); - } -} - -void __init -pci_assign_unassigned_resources(void) -{ - struct pci_bus *bus; - - /* Depth first, calculate sizes and alignments of all - subordinate buses. */ - list_for_each_entry(bus, &pci_root_buses, node) { - pci_bus_size_bridges(bus); - } - /* Depth last, allocate resources and update the hardware. */ - list_for_each_entry(bus, &pci_root_buses, node) { - pci_bus_assign_resources(bus); - pci_enable_bridges(bus); - } - - /* dump the resource on buses */ - list_for_each_entry(bus, &pci_root_buses, node) { - pci_bus_dump_resources(bus); - } -} diff --git a/libdde_linux26/contrib/drivers/pci/setup-res.c b/libdde_linux26/contrib/drivers/pci/setup-res.c deleted file mode 100644 index 32e8d88a..00000000 --- a/libdde_linux26/contrib/drivers/pci/setup-res.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * drivers/pci/setup-res.c - * - * Extruded from code written by - * Dave Rusling (david.rusling@reo.mts.dec.com) - * David Mosberger (davidm@cs.arizona.edu) - * David Miller (davem@redhat.com) - * - * Support routines for initializing a PCI subsystem. - */ - -/* fixed for multiple pci buses, 1999 Andrea Arcangeli <andrea@suse.de> */ - -/* - * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru> - * Resource sorting - */ - -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/pci.h> -#include <linux/errno.h> -#include <linux/ioport.h> -#include <linux/cache.h> -#include <linux/slab.h> -#include "pci.h" - - -void pci_update_resource(struct pci_dev *dev, int resno) -{ - struct pci_bus_region region; - u32 new, check, mask; - int reg; - enum pci_bar_type type; - struct resource *res = dev->resource + resno; - - /* - * Ignore resources for unimplemented BARs and unused resource slots - * for 64 bit BARs. - */ - if (!res->flags) - return; - - /* - * Ignore non-moveable resources. This might be legacy resources for - * which no functional BAR register exists or another important - * system resource we shouldn't move around. - */ - if (res->flags & IORESOURCE_PCI_FIXED) - return; - - pcibios_resource_to_bus(dev, ®ion, res); - - dev_dbg(&dev->dev, "BAR %d: got res %pR bus [%#llx-%#llx] " - "flags %#lx\n", resno, res, - (unsigned long long)region.start, - (unsigned long long)region.end, - (unsigned long)res->flags); - - new = region.start | (res->flags & PCI_REGION_FLAG_MASK); - if (res->flags & IORESOURCE_IO) - mask = (u32)PCI_BASE_ADDRESS_IO_MASK; - else - mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; - - reg = pci_resource_bar(dev, resno, &type); - if (!reg) - return; - if (type != pci_bar_unknown) { - if (!(res->flags & IORESOURCE_ROM_ENABLE)) - return; - new |= PCI_ROM_ADDRESS_ENABLE; - } - - pci_write_config_dword(dev, reg, new); - pci_read_config_dword(dev, reg, &check); - - if ((new ^ check) & mask) { - dev_err(&dev->dev, "BAR %d: error updating (%#08x != %#08x)\n", - resno, new, check); - } - - if ((new & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK)) == - (PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64)) { - new = region.start >> 16 >> 16; - pci_write_config_dword(dev, reg + 4, new); - pci_read_config_dword(dev, reg + 4, &check); - if (check != new) { - dev_err(&dev->dev, "BAR %d: error updating " - "(high %#08x != %#08x)\n", resno, new, check); - } - } - res->flags &= ~IORESOURCE_UNSET; - dev_dbg(&dev->dev, "BAR %d: moved to bus [%#llx-%#llx] flags %#lx\n", - resno, (unsigned long long)region.start, - (unsigned long long)region.end, res->flags); -} - -int pci_claim_resource(struct pci_dev *dev, int resource) -{ - struct resource *res = &dev->resource[resource]; - struct resource *root = NULL; - char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge"; - int err; - - root = pcibios_select_root(dev, res); - - err = -EINVAL; - if (root != NULL) - err = insert_resource(root, res); - - if (err) { - dev_err(&dev->dev, "BAR %d: %s of %s %pR\n", - resource, - root ? "address space collision on" : - "no parent found for", - dtype, res); - } - - return err; -} - -int pci_assign_resource(struct pci_dev *dev, int resno) -{ - struct pci_bus *bus = dev->bus; - struct resource *res = dev->resource + resno; - resource_size_t size, min, align; - int ret; - - size = resource_size(res); - min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; - - align = resource_alignment(res); - if (!align) { - dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus " - "alignment) %pR flags %#lx\n", - resno, res, res->flags); - return -EINVAL; - } - - /* First, try exact prefetching match.. */ - ret = pci_bus_alloc_resource(bus, res, size, align, min, - IORESOURCE_PREFETCH, - pcibios_align_resource, dev); - - if (ret < 0 && (res->flags & IORESOURCE_PREFETCH)) { - /* - * That failed. - * - * But a prefetching area can handle a non-prefetching - * window (it will just not perform as well). - */ - ret = pci_bus_alloc_resource(bus, res, size, align, min, 0, - pcibios_align_resource, dev); - } - - if (ret) { - dev_info(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", - resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res); - } else { - res->flags &= ~IORESOURCE_STARTALIGN; - if (resno < PCI_BRIDGE_RESOURCES) - pci_update_resource(dev, resno); - } - - return ret; -} - -#if 0 -int pci_assign_resource_fixed(struct pci_dev *dev, int resno) -{ - struct pci_bus *bus = dev->bus; - struct resource *res = dev->resource + resno; - unsigned int type_mask; - int i, ret = -EBUSY; - - type_mask = IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH; - - for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { - struct resource *r = bus->resource[i]; - if (!r) - continue; - - /* type_mask must match */ - if ((res->flags ^ r->flags) & type_mask) - continue; - - ret = request_resource(r, res); - - if (ret == 0) - break; - } - - if (ret) { - dev_err(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", - resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res); - } else if (resno < PCI_BRIDGE_RESOURCES) { - pci_update_resource(dev, resno); - } - - return ret; -} -EXPORT_SYMBOL_GPL(pci_assign_resource_fixed); -#endif - -/* Sort resources by alignment */ -void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) -{ - int i; - - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - struct resource *r; - struct resource_list *list, *tmp; - resource_size_t r_align; - - r = &dev->resource[i]; - - if (r->flags & IORESOURCE_PCI_FIXED) - continue; - - if (!(r->flags) || r->parent) - continue; - - r_align = resource_alignment(r); - if (!r_align) { - dev_warn(&dev->dev, "BAR %d: bogus alignment " - "%pR flags %#lx\n", - i, r, r->flags); - continue; - } - for (list = head; ; list = list->next) { - resource_size_t align = 0; - struct resource_list *ln = list->next; - - if (ln) - align = resource_alignment(ln->res); - - if (r_align > align) { - tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); - if (!tmp) - panic("pdev_sort_resources(): " - "kmalloc() failed!\n"); - tmp->next = ln; - tmp->res = r; - tmp->dev = dev; - list->next = tmp; - break; - } - } - } -} - -int pci_enable_resources(struct pci_dev *dev, int mask) -{ - u16 cmd, old_cmd; - int i; - struct resource *r; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; - - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - if (!(mask & (1 << i))) - continue; - - r = &dev->resource[i]; - - if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM))) - continue; - if ((i == PCI_ROM_RESOURCE) && - (!(r->flags & IORESOURCE_ROM_ENABLE))) - continue; - - if (!r->parent) { - dev_err(&dev->dev, "device not available because of " - "BAR %d %pR collisions\n", i, r); - return -EINVAL; - } - - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - - if (cmd != old_cmd) { - dev_info(&dev->dev, "enabling device (%04x -> %04x)\n", - old_cmd, cmd); - pci_write_config_word(dev, PCI_COMMAND, cmd); - } - return 0; -} |