Commit ab69bcd6 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6: (28 commits)
  driver core: device_rename's new_name can be const
  sysfs: Remove owner field from sysfs struct attribute
  powerpc/pci: Remove owner field from attribute initialization in PCI bridge init
  regulator: Remove owner field from attribute initialization in regulator core driver
  leds: Remove owner field from attribute initialization in bd2802 driver
  scsi: Remove owner field from attribute initialization in ARCMSR driver
  scsi: Remove owner field from attribute initialization in LPFC driver
  cgroupfs: create /sys/fs/cgroup to mount cgroupfs on
  Driver core: Add BUS_NOTIFY_BIND_DRIVER
  driver core: fix memory leak on one error path in bus_register()
  debugfs: no longer needs to depend on SYSFS
  sysfs: Fix one more signature discrepancy between sysfs implementation and docs.
  sysfs: fix discrepancies between implementation and documentation
  dcdbas: remove a redundant smi_data_buf_free in dcdbas_exit
  dmi-id: fix a memory leak in dmi_id_init error path
  sysfs: sysfs_chmod_file's attr can be const
  firmware: Update hotplug script
  Driver core: move platform device creation helpers to .init.text (if MODULE=n)
  Driver core: reduce duplicated code for platform_device creation
  Driver core: use kmemdup in platform_device_add_resources
  ...
parents c513b67e 6937e8f8
...@@ -111,6 +111,7 @@ X!Edrivers/base/attribute_container.c ...@@ -111,6 +111,7 @@ X!Edrivers/base/attribute_container.c
<!-- <!--
X!Edrivers/base/interface.c X!Edrivers/base/interface.c
--> -->
!Iinclude/linux/platform_device.h
!Edrivers/base/platform.c !Edrivers/base/platform.c
!Edrivers/base/bus.c !Edrivers/base/bus.c
</sect1> </sect1>
......
...@@ -4,7 +4,7 @@ sysfs - _The_ filesystem for exporting kernel objects. ...@@ -4,7 +4,7 @@ sysfs - _The_ filesystem for exporting kernel objects.
Patrick Mochel <mochel@osdl.org> Patrick Mochel <mochel@osdl.org>
Mike Murphy <mamurph@cs.clemson.edu> Mike Murphy <mamurph@cs.clemson.edu>
Revised: 22 February 2009 Revised: 15 July 2010
Original: 10 January 2003 Original: 10 January 2003
...@@ -124,7 +124,7 @@ show and store methods of the attribute owners. ...@@ -124,7 +124,7 @@ show and store methods of the attribute owners.
struct sysfs_ops { struct sysfs_ops {
ssize_t (*show)(struct kobject *, struct attribute *, char *); ssize_t (*show)(struct kobject *, struct attribute *, char *);
ssize_t (*store)(struct kobject *, struct attribute *, const char *); ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t);
}; };
[ Subsystems should have already defined a struct kobj_type as a [ Subsystems should have already defined a struct kobj_type as a
...@@ -139,18 +139,22 @@ calls the associated methods. ...@@ -139,18 +139,22 @@ calls the associated methods.
To illustrate: To illustrate:
#define to_dev(obj) container_of(obj, struct device, kobj)
#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
#define to_dev(d) container_of(d, struct device, kobj)
static ssize_t static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr,
dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) char *buf)
{ {
struct device_attribute * dev_attr = to_dev_attr(attr); struct device_attribute *dev_attr = to_dev_attr(attr);
struct device * dev = to_dev(kobj); struct device *dev = to_dev(kobj);
ssize_t ret = 0; ssize_t ret = -EIO;
if (dev_attr->show) if (dev_attr->show)
ret = dev_attr->show(dev, buf); ret = dev_attr->show(dev, dev_attr, buf);
if (ret >= (ssize_t)PAGE_SIZE) {
print_symbol("dev_attr_show: %s returned bad count\n",
(unsigned long)dev_attr->show);
}
return ret; return ret;
} }
...@@ -163,10 +167,9 @@ To read or write attributes, show() or store() methods must be ...@@ -163,10 +167,9 @@ To read or write attributes, show() or store() methods must be
specified when declaring the attribute. The method types should be as specified when declaring the attribute. The method types should be as
simple as those defined for device attributes: simple as those defined for device attributes:
ssize_t (*show)(struct device * dev, struct device_attribute * attr, ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf);
char * buf); ssize_t (*store)(struct device *dev, struct device_attribute *attr,
ssize_t (*store)(struct device * dev, struct device_attribute * attr, const char *buf, size_t count);
const char * buf);
IOW, they should take only an object, an attribute, and a buffer as parameters. IOW, they should take only an object, an attribute, and a buffer as parameters.
...@@ -209,8 +212,8 @@ Other notes: ...@@ -209,8 +212,8 @@ Other notes:
- show() should always use snprintf(). - show() should always use snprintf().
- store() should return the number of bytes used from the buffer. This - store() should return the number of bytes used from the buffer. If the
can be done using strlen(). entire buffer has been used, just return the count argument.
- show() or store() can always return errors. If a bad value comes - show() or store() can always return errors. If a bad value comes
through, be sure to return an error. through, be sure to return an error.
...@@ -223,15 +226,18 @@ Other notes: ...@@ -223,15 +226,18 @@ Other notes:
A very simple (and naive) implementation of a device attribute is: A very simple (and naive) implementation of a device attribute is:
static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) static ssize_t show_name(struct device *dev, struct device_attribute *attr,
char *buf)
{ {
return snprintf(buf, PAGE_SIZE, "%s\n", dev->name); return snprintf(buf, PAGE_SIZE, "%s\n", dev->name);
} }
static ssize_t store_name(struct device * dev, const char * buf) static ssize_t store_name(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{ {
sscanf(buf, "%20s", dev->name); snprintf(dev->name, sizeof(dev->name), "%.*s",
return strnlen(buf, PAGE_SIZE); (int)min(count, sizeof(dev->name) - 1), buf);
return count;
} }
static DEVICE_ATTR(name, S_IRUGO, show_name, store_name); static DEVICE_ATTR(name, S_IRUGO, show_name, store_name);
...@@ -327,7 +333,7 @@ Structure: ...@@ -327,7 +333,7 @@ Structure:
struct bus_attribute { struct bus_attribute {
struct attribute attr; struct attribute attr;
ssize_t (*show)(struct bus_type *, char * buf); ssize_t (*show)(struct bus_type *, char * buf);
ssize_t (*store)(struct bus_type *, const char * buf); ssize_t (*store)(struct bus_type *, const char * buf, size_t count);
}; };
Declaring: Declaring:
......
...@@ -6,11 +6,12 @@ ...@@ -6,11 +6,12 @@
HOTPLUG_FW_DIR=/usr/lib/hotplug/firmware/ HOTPLUG_FW_DIR=/usr/lib/hotplug/firmware/
echo 1 > /sys/$DEVPATH/loading if [ "$SUBSYSTEM" == "firmware" -a "$ACTION" == "add" ]; then
cat $HOTPLUG_FW_DIR/$FIRMWARE > /sys/$DEVPATH/data if [ -f $HOTPLUG_FW_DIR/$FIRMWARE ]; then
echo 0 > /sys/$DEVPATH/loading echo 1 > /sys/$DEVPATH/loading
cat $HOTPLUG_FW_DIR/$FIRMWARE > /sys/$DEVPATH/data
# To cancel the load in case of error: echo 0 > /sys/$DEVPATH/loading
# else
# echo -1 > /sys/$DEVPATH/loading echo -1 > /sys/$DEVPATH/loading
# fi
fi
...@@ -73,7 +73,6 @@ static struct bin_attribute mv64x60_hs_reg_attr = { /* Hotswap register */ ...@@ -73,7 +73,6 @@ static struct bin_attribute mv64x60_hs_reg_attr = { /* Hotswap register */
.attr = { .attr = {
.name = "hs_reg", .name = "hs_reg",
.mode = S_IRUGO | S_IWUSR, .mode = S_IRUGO | S_IWUSR,
.owner = THIS_MODULE,
}, },
.size = MV64X60_VAL_LEN_MAX, .size = MV64X60_VAL_LEN_MAX,
.read = mv64x60_hs_reg_read, .read = mv64x60_hs_reg_read,
......
...@@ -945,8 +945,8 @@ int bus_register(struct bus_type *bus) ...@@ -945,8 +945,8 @@ int bus_register(struct bus_type *bus)
bus_remove_file(bus, &bus_attr_uevent); bus_remove_file(bus, &bus_attr_uevent);
bus_uevent_fail: bus_uevent_fail:
kset_unregister(&bus->p->subsys); kset_unregister(&bus->p->subsys);
kfree(bus->p);
out: out:
kfree(bus->p);
bus->p = NULL; bus->p = NULL;
return retval; return retval;
} }
......
...@@ -1599,7 +1599,7 @@ EXPORT_SYMBOL_GPL(device_destroy); ...@@ -1599,7 +1599,7 @@ EXPORT_SYMBOL_GPL(device_destroy);
* on the same device to ensure that new_name is valid and * on the same device to ensure that new_name is valid and
* won't conflict with other devices. * won't conflict with other devices.
*/ */
int device_rename(struct device *dev, char *new_name) int device_rename(struct device *dev, const char *new_name)
{ {
char *old_class_name = NULL; char *old_class_name = NULL;
char *new_class_name = NULL; char *new_class_name = NULL;
......
...@@ -51,6 +51,10 @@ static int driver_sysfs_add(struct device *dev) ...@@ -51,6 +51,10 @@ static int driver_sysfs_add(struct device *dev)
{ {
int ret; int ret;
if (dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
BUS_NOTIFY_BIND_DRIVER, dev);
ret = sysfs_create_link(&dev->driver->p->kobj, &dev->kobj, ret = sysfs_create_link(&dev->driver->p->kobj, &dev->kobj,
kobject_name(&dev->kobj)); kobject_name(&dev->kobj));
if (ret == 0) { if (ret == 0) {
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
struct dma_coherent_mem { struct dma_coherent_mem {
void *virt_base; void *virt_base;
u32 device_base; dma_addr_t device_base;
int size; int size;
int flags; int flags;
unsigned long *bitmap; unsigned long *bitmap;
......
This diff is collapsed.
...@@ -192,13 +192,13 @@ int platform_device_add_resources(struct platform_device *pdev, ...@@ -192,13 +192,13 @@ int platform_device_add_resources(struct platform_device *pdev,
{ {
struct resource *r; struct resource *r;
r = kmalloc(sizeof(struct resource) * num, GFP_KERNEL); r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL);
if (r) { if (r) {
memcpy(r, res, sizeof(struct resource) * num);
pdev->resource = r; pdev->resource = r;
pdev->num_resources = num; pdev->num_resources = num;
return 0;
} }
return r ? 0 : -ENOMEM; return -ENOMEM;
} }
EXPORT_SYMBOL_GPL(platform_device_add_resources); EXPORT_SYMBOL_GPL(platform_device_add_resources);
...@@ -345,108 +345,56 @@ void platform_device_unregister(struct platform_device *pdev) ...@@ -345,108 +345,56 @@ void platform_device_unregister(struct platform_device *pdev)
EXPORT_SYMBOL_GPL(platform_device_unregister); EXPORT_SYMBOL_GPL(platform_device_unregister);
/** /**
* platform_device_register_simple - add a platform-level device and its resources * platform_device_register_resndata - add a platform-level device with
* @name: base name of the device we're adding * resources and platform-specific data
* @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".
* *
* Returns &struct platform_device pointer on success, or ERR_PTR() on error.
*/
struct platform_device *platform_device_register_simple(const char *name,
int id,
const 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 - add a platform-level device with platform-specific data
* @parent: parent device for the device we're adding * @parent: parent device for the device we're adding
* @name: base name of the device we're adding * @name: base name of the device we're adding
* @id: instance id * @id: instance id
* @res: set of resources that needs to be allocated for the device
* @num: number of resources
* @data: platform specific data for this platform device * @data: platform specific data for this platform device
* @size: size of platform specific data * @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.
*
* Returns &struct platform_device pointer on success, or ERR_PTR() on error. * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
*/ */
struct platform_device *platform_device_register_data( struct platform_device *__init_or_module platform_device_register_resndata(
struct device *parent, struct device *parent,
const char *name, int id, const char *name, int id,
const struct resource *res, unsigned int num,
const void *data, size_t size) const void *data, size_t size)
{ {
int ret = -ENOMEM;
struct platform_device *pdev; struct platform_device *pdev;
int retval;
pdev = platform_device_alloc(name, id); pdev = platform_device_alloc(name, id);
if (!pdev) { if (!pdev)
retval = -ENOMEM; goto err;
goto error;
}
pdev->dev.parent = parent; pdev->dev.parent = parent;
if (size) { if (res) {
retval = platform_device_add_data(pdev, data, size); ret = platform_device_add_resources(pdev, res, num);
if (retval) if (ret)
goto error; goto err;
} }
retval = platform_device_add(pdev); if (data) {
if (retval) ret = platform_device_add_data(pdev, data, size);
goto error; if (ret)
goto err;
}
return pdev; ret = platform_device_add(pdev);
if (ret) {
err:
platform_device_put(pdev);
return ERR_PTR(ret);
}
error: return pdev;
platform_device_put(pdev);
return ERR_PTR(retval);
} }
EXPORT_SYMBOL_GPL(platform_device_register_data); EXPORT_SYMBOL_GPL(platform_device_register_resndata);
static int platform_drv_probe(struct device *_dev) static int platform_drv_probe(struct device *_dev)
{ {
......
...@@ -634,9 +634,6 @@ static void __exit dcdbas_exit(void) ...@@ -634,9 +634,6 @@ static void __exit dcdbas_exit(void)
* before platform_device_unregister * before platform_device_unregister
*/ */
unregister_reboot_notifier(&dcdbas_reboot_nb); unregister_reboot_notifier(&dcdbas_reboot_nb);
smi_data_buf_free();
platform_device_unregister(dcdbas_pdev);
platform_driver_unregister(&dcdbas_driver);
/* /*
* We have to free the buffer here instead of dcdbas_remove * We have to free the buffer here instead of dcdbas_remove
...@@ -645,6 +642,8 @@ static void __exit dcdbas_exit(void) ...@@ -645,6 +642,8 @@ static void __exit dcdbas_exit(void)
* released. * released.
*/ */
smi_data_buf_free(); smi_data_buf_free();
platform_device_unregister(dcdbas_pdev);
platform_driver_unregister(&dcdbas_driver);
} }
module_init(dcdbas_init); module_init(dcdbas_init);
......
...@@ -229,10 +229,12 @@ static int __init dmi_id_init(void) ...@@ -229,10 +229,12 @@ static int __init dmi_id_init(void)
ret = device_register(dmi_dev); ret = device_register(dmi_dev);
if (ret) if (ret)
goto fail_class_unregister; goto fail_free_dmi_dev;
return 0; return 0;
fail_free_dmi_dev:
kfree(dmi_dev);
fail_class_unregister: fail_class_unregister:
class_unregister(&dmi_class); class_unregister(&dmi_class);
......
...@@ -351,7 +351,7 @@ static ssize_t bd2802_store_reg##reg_addr(struct device *dev, \ ...@@ -351,7 +351,7 @@ static ssize_t bd2802_store_reg##reg_addr(struct device *dev, \
return count; \ return count; \
} \ } \
static struct device_attribute bd2802_reg##reg_addr##_attr = { \ static struct device_attribute bd2802_reg##reg_addr##_attr = { \
.attr = {.name = reg_name, .mode = 0644, .owner = THIS_MODULE}, \ .attr = {.name = reg_name, .mode = 0644}, \
.store = bd2802_store_reg##reg_addr, \ .store = bd2802_store_reg##reg_addr, \
}; };
...@@ -482,7 +482,6 @@ static struct device_attribute bd2802_adv_conf_attr = { ...@@ -482,7 +482,6 @@ static struct device_attribute bd2802_adv_conf_attr = {
.attr = { .attr = {
.name = "advanced_configuration", .name = "advanced_configuration",
.mode = 0644, .mode = 0644,
.owner = THIS_MODULE
}, },
.show = bd2802_show_adv_conf, .show = bd2802_show_adv_conf,
.store = bd2802_store_adv_conf, .store = bd2802_store_adv_conf,
...@@ -519,7 +518,6 @@ static struct device_attribute bd2802_##attr_name##_attr = { \ ...@@ -519,7 +518,6 @@ static struct device_attribute bd2802_##attr_name##_attr = { \
.attr = { \ .attr = { \
.name = name_str, \ .name = name_str, \
.mode = 0644, \ .mode = 0644, \
.owner = THIS_MODULE \
}, \ }, \
.show = bd2802_show_##attr_name, \ .show = bd2802_show_##attr_name, \
.store = bd2802_store_##attr_name, \ .store = bd2802_store_##attr_name, \
......
...@@ -1025,7 +1025,6 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, ...@@ -1025,7 +1025,6 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
if (regulator->dev_attr.attr.name == NULL) if (regulator->dev_attr.attr.name == NULL)
goto attr_name_err; goto attr_name_err;
regulator->dev_attr.attr.owner = THIS_MODULE;
regulator->dev_attr.attr.mode = 0444; regulator->dev_attr.attr.mode = 0444;
regulator->dev_attr.show = device_requested_uA_show; regulator->dev_attr.show = device_requested_uA_show;
err = device_create_file(dev, &regulator->dev_attr); err = device_create_file(dev, &regulator->dev_attr);
......
...@@ -192,7 +192,6 @@ static struct bin_attribute arcmsr_sysfs_message_read_attr = { ...@@ -192,7 +192,6 @@ static struct bin_attribute arcmsr_sysfs_message_read_attr = {
.attr = { .attr = {
.name = "mu_read", .name = "mu_read",
.mode = S_IRUSR , .mode = S_IRUSR ,
.owner = THIS_MODULE,
}, },
.size = 1032, .size = 1032,
.read = arcmsr_sysfs_iop_message_read, .read = arcmsr_sysfs_iop_message_read,
...@@ -202,7 +201,6 @@ static struct bin_attribute arcmsr_sysfs_message_write_attr = { ...@@ -202,7 +201,6 @@ static struct bin_attribute arcmsr_sysfs_message_write_attr = {
.attr = { .attr = {
.name = "mu_write", .name = "mu_write",
.mode = S_IWUSR, .mode = S_IWUSR,
.owner = THIS_MODULE,
}, },
.size = 1032, .size = 1032,
.write = arcmsr_sysfs_iop_message_write, .write = arcmsr_sysfs_iop_message_write,
...@@ -212,7 +210,6 @@ static struct bin_attribute arcmsr_sysfs_message_clear_attr = { ...@@ -212,7 +210,6 @@ static struct bin_attribute arcmsr_sysfs_message_clear_attr = {
.attr = { .attr = {
.name = "mu_clear", .name = "mu_clear",
.mode = S_IWUSR, .mode = S_IWUSR,
.owner = THIS_MODULE,
}, },
.size = 1, .size = 1,
.write = arcmsr_sysfs_iop_message_clear, .write = arcmsr_sysfs_iop_message_clear,
......
...@@ -2778,7 +2778,6 @@ static struct bin_attribute sysfs_drvr_stat_data_attr = { ...@@ -2778,7 +2778,6 @@ static struct bin_attribute sysfs_drvr_stat_data_attr = {
.attr = { .attr = {
.name = "lpfc_drvr_stat_data", .name = "lpfc_drvr_stat_data",
.mode = S_IRUSR, .mode = S_IRUSR,
.owner = THIS_MODULE,
}, },
.size = LPFC_MAX_TARGET * MAX_STAT_DATA_SIZE_PER_TARGET, .size = LPFC_MAX_TARGET * MAX_STAT_DATA_SIZE_PER_TARGET,
.read = sysfs_drvr_stat_data_read, .read = sysfs_drvr_stat_data_read,
......
...@@ -79,7 +79,7 @@ static int __devinit hilscher_pci_probe(struct pci_dev *dev, ...@@ -79,7 +79,7 @@ static int __devinit hilscher_pci_probe(struct pci_dev *dev,
} }
info->version = "0.0.1"; info->version = "0.0.1";
info->irq = dev->irq; info->irq = dev->irq;
info->irq_flags = IRQF_DISABLED | IRQF_SHARED; info->irq_flags = IRQF_SHARED;
info->handler = hilscher_handler; info->handler = hilscher_handler;
if (uio_register_device(&dev->dev, info)) if (uio_register_device(&dev->dev, info))
......
...@@ -155,7 +155,6 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev) ...@@ -155,7 +155,6 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
* Interrupt sharing is not supported. * Interrupt sharing is not supported.
*/ */
uioinfo->irq_flags |= IRQF_DISABLED;
uioinfo->handler = uio_pdrv_genirq_handler; uioinfo->handler = uio_pdrv_genirq_handler;
uioinfo->irqcontrol = uio_pdrv_genirq_irqcontrol; uioinfo->irqcontrol = uio_pdrv_genirq_irqcontrol;
uioinfo->open = uio_pdrv_genirq_open; uioinfo->open = uio_pdrv_genirq_open;
......
...@@ -154,7 +154,7 @@ static int __devinit sercos3_pci_probe(struct pci_dev *dev, ...@@ -154,7 +154,7 @@ static int __devinit sercos3_pci_probe(struct pci_dev *dev,
info->name = "Sercos_III_PCI"; info->name = "Sercos_III_PCI";
info->version = "0.0.1"; info->version = "0.0.1";
info->irq = dev->irq; info->irq = dev->irq;
info->irq_flags = IRQF_DISABLED | IRQF_SHARED; info->irq_flags = IRQF_SHARED;
info->handler = sercos3_handler; info->handler = sercos3_handler;
info->irqcontrol = sercos3_irqcontrol; info->irqcontrol = sercos3_irqcontrol;
......
...@@ -593,7 +593,8 @@ EXPORT_SYMBOL_GPL(sysfs_add_file_to_group); ...@@ -593,7 +593,8 @@ EXPORT_SYMBOL_GPL(sysfs_add_file_to_group);
* @mode: file permissions. * @mode: file permissions.
* *
*/ */
int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode) int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr,
mode_t mode)
{ {
struct sysfs_dirent *sd; struct sysfs_dirent *sd;
struct iattr newattrs; struct iattr newattrs;
......
...@@ -84,9 +84,8 @@ struct device *bus_find_device_by_name(struct bus_type *bus, ...@@ -84,9 +84,8 @@ struct device *bus_find_device_by_name(struct bus_type *bus,
struct device *start, struct device *start,
const char *name); const char *name);
int __must_check bus_for_each_drv(struct bus_type *bus, int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
struct device_driver *start, void *data, void *data, int (*fn)(struct device_driver *, void *));
int (*fn)(struct device_driver *, void *));
void bus_sort_breadthfirst(struct bus_type *bus, void bus_sort_breadthfirst(struct bus_type *bus,
int (*compare)(const struct device *a, int (*compare)(const struct device *a,
...@@ -110,10 +109,12 @@ extern int bus_unregister_notifier(struct bus_type *bus, ...@@ -110,10 +109,12 @@ extern int bus_unregister_notifier(struct bus_type *bus,
*/ */
#define BUS_NOTIFY_ADD_DEVICE 0x00000001 /* device added */ #define BUS_NOTIFY_ADD_DEVICE 0x00000001 /* device added */
#define BUS_NOTIFY_DEL_DEVICE 0x00000002 /* device removed */ #define BUS_NOTIFY_DEL_DEVICE 0x00000002 /* device removed */
#define BUS_NOTIFY_BOUND_DRIVER 0x00000003 /* driver bound to device */ #define BUS_NOTIFY_BIND_DRIVER 0x00000003 /* driver about to be
#define BUS_NOTIFY_UNBIND_DRIVER 0x00000004 /* driver about to be bound */
#define BUS_NOTIFY_BOUND_DRIVER 0x00000004 /* driver bound to device */
#define BUS_NOTIFY_UNBIND_DRIVER 0x00000005 /* driver about to be
unbound */ unbound */
#define BUS_NOTIFY_UNBOUND_DRIVER 0x00000005 /* driver is unbound #define BUS_NOTIFY_UNBOUND_DRIVER 0x00000006 /* driver is unbound
from the device */ from the device */
extern struct kset *bus_get_kset(struct bus_type *bus); extern struct kset *bus_get_kset(struct bus_type *bus);
...@@ -551,7 +552,7 @@ extern int device_for_each_child(struct device *dev, void *data, ...@@ -551,7 +552,7 @@ extern int device_for_each_child(struct device *dev, void *data,
int (*fn)(struct device *dev, void *data)); int (*fn)(struct device *dev, void *data));
extern struct device *device_find_child(struct device *dev, void *data, extern struct device *device_find_child(struct device *dev, void *data,
int (*match)(struct device *dev, void *data)); int (*match)(struct device *dev, void *data));
extern int device_rename(struct device *dev, char *new_name); extern int device_rename(struct device *dev, const char *new_name);
extern int device_move(struct device *dev, struct device *new_parent, extern int device_move(struct device *dev, struct device *new_parent,
enum dpm_order dpm_order); enum dpm_order dpm_order);
extern const char *device_get_devnode(struct device *dev, extern const char *device_get_devnode(struct device *dev,
......
...@@ -43,10 +43,64 @@ extern struct resource *platform_get_resource_byname(struct platform_device *, u ...@@ -43,10 +43,64 @@ extern struct resource *platform_get_resource_byname(struct platform_device *, u
extern int platform_get_irq_byname(struct platform_device *, const char *); extern int platform_get_irq_byname(struct platform_device *, const char *);
extern int platform_add_devices(struct platform_device **, int); extern int platform_add_devices(struct platform_device **, int);
extern struct platform_device *platform_device_register_simple(const char *, int id, extern struct platform_device *platform_device_register_resndata(
const struct resource *, unsigned int); struct device *parent, const char *name, int id,
extern struct platform_device *platform_device_register_data(struct device *, const struct resource *res, unsigned int num,
const char *, int, const void *, size_t); const void *data, size_t size);
/**
* platform_device_register_simple - add a platform-level device and its resources
* @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".
*
* Returns &struct platform_device pointer on success, or ERR_PTR() on error.
*/
static inline struct platform_device *platform_device_register_simple(
const char *name, int id,
const struct resource *res, unsigned int num)
{
return platform_device_register_resndata(NULL, name, id,
res, num, NULL, 0);
}
/**
* platform_device_register_data - add a platform-level device with platform-specific 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.
*
* Returns &struct platform_device pointer on success, or ERR_PTR() on error.
*/
static inline struct platform_device *platform_device_register_data(
struct device *parent, const char *name, int id,
const void *data, size_t size)
{
return platform_device_register_resndata(parent, name, id,
NULL, 0, data, size);
}
extern struct platform_device *platform_device_alloc(const char *name, int id); extern struct platform_device *platform_device_alloc(const char *name, int id);
extern int platform_device_add_resources(struct platform_device *pdev, extern int platform_device_add_resources(struct platform_device *pdev,
......
...@@ -22,14 +22,8 @@ struct kobject; ...@@ -22,14 +22,8 @@ struct kobject;
struct module; struct module;
enum kobj_ns_type; enum kobj_ns_type;
/* FIXME
* The *owner field is no longer used.
* x86 tree has been cleaned up. The owner
* attribute is still left for other arches.
*/
struct attribute { struct attribute {
const char *name; const char *name;
struct module *owner;
mode_t mode; mode_t mode;
#ifdef CONFIG_DEBUG_LOCK_ALLOC #ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lock_class_key *key; struct lock_class_key *key;
...@@ -136,8 +130,8 @@ int __must_check sysfs_create_file(struct kobject *kobj, ...@@ -136,8 +130,8 @@ int __must_check sysfs_create_file(struct kobject *kobj,
const struct attribute *attr); const struct attribute *attr);
int __must_check sysfs_create_files(struct kobject *kobj, int __must_check sysfs_create_files(struct kobject *kobj,
const struct attribute **attr); const struct attribute **attr);
int __must_check sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, int __must_check sysfs_chmod_file(struct kobject *kobj,
mode_t mode); const struct attribute *attr, mode_t mode);
void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr); void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr);
void sysfs_remove_files(struct kobject *kobj, const struct attribute **attr); void sysfs_remove_files(struct kobject *kobj, const struct attribute **attr);
...@@ -225,7 +219,7 @@ static inline int sysfs_create_files(struct kobject *kobj, ...@@ -225,7 +219,7 @@ static inline int sysfs_create_files(struct kobject *kobj,
} }
static inline int sysfs_chmod_file(struct kobject *kobj, static inline int sysfs_chmod_file(struct kobject *kobj,
struct attribute *attr, mode_t mode) const struct attribute *attr, mode_t mode)
{ {
return 0; return 0;
} }
......
...@@ -1623,6 +1623,8 @@ static struct file_system_type cgroup_fs_type = { ...@@ -1623,6 +1623,8 @@ static struct file_system_type cgroup_fs_type = {
.kill_sb = cgroup_kill_sb, .kill_sb = cgroup_kill_sb,
}; };
static struct kobject *cgroup_kobj;
static inline struct cgroup *__d_cgrp(struct dentry *dentry) static inline struct cgroup *__d_cgrp(struct dentry *dentry)
{ {
return dentry->d_fsdata; return dentry->d_fsdata;
...@@ -3894,9 +3896,18 @@ int __init cgroup_init(void) ...@@ -3894,9 +3896,18 @@ int __init cgroup_init(void)
hhead = css_set_hash(init_css_set.subsys); hhead = css_set_hash(init_css_set.subsys);
hlist_add_head(&init_css_set.hlist, hhead); hlist_add_head(&init_css_set.hlist, hhead);
BUG_ON(!init_root_id(&rootnode)); BUG_ON(!init_root_id(&rootnode));
cgroup_kobj = kobject_create_and_add("cgroup", fs_kobj);
if (!cgroup_kobj) {
err = -ENOMEM;
goto out;
}
err = register_filesystem(&cgroup_fs_type); err = register_filesystem(&cgroup_fs_type);
if (err < 0) if (err < 0) {
kobject_put(cgroup_kobj);
goto out; goto out;
}
proc_create("cgroups", 0, NULL, &proc_cgroupstats_operations); proc_create("cgroups", 0, NULL, &proc_cgroupstats_operations);
......
...@@ -566,7 +566,7 @@ static struct ctl_table kern_table[] = { ...@@ -566,7 +566,7 @@ static struct ctl_table kern_table[] = {
.extra2 = &one, .extra2 = &one,
}, },
#endif #endif
#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET) #ifdef CONFIG_HOTPLUG
{ {
.procname = "hotplug", .procname = "hotplug",
.data = &uevent_helper, .data = &uevent_helper,
......
...@@ -76,7 +76,6 @@ config UNUSED_SYMBOLS ...@@ -76,7 +76,6 @@ config UNUSED_SYMBOLS
config DEBUG_FS config DEBUG_FS
bool "Debug Filesystem" bool "Debug Filesystem"
depends on SYSFS
help help
debugfs is a virtual file system that kernel developers use to put debugfs is a virtual file system that kernel developers use to put
debugging files into. Enable this option to be able to read and debugging files into. Enable this option to be able to read and
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment