Merge branch 'driver-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core

* 'driver-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (73 commits)
  arm: fix up some samsung merge sysdev conversion problems
  firmware: Fix an oops on reading fw_priv->fw in sysfs loading file
  Drivers:hv: Fix a bug in vmbus_driver_unregister()
  driver core: remove __must_check from device_create_file
  debugfs: add missing #ifdef HAS_IOMEM
  arm: time.h: remove device.h #include
  driver-core: remove sysdev.h usage.
  clockevents: remove sysdev.h
  arm: convert sysdev_class to a regular subsystem
  arm: leds: convert sysdev_class to a regular subsystem
  kobject: remove kset_find_obj_hinted()
  m86k: gpio - convert sysdev_class to a regular subsystem
  mips: txx9_sram - convert sysdev_class to a regular subsystem
  mips: 7segled - convert sysdev_class to a regular subsystem
  sh: dma - convert sysdev_class to a regular subsystem
  sh: intc - convert sysdev_class to a regular subsystem
  power: suspend - convert sysdev_class to a regular subsystem
  power: qe_ic - convert sysdev_class to a regular subsystem
  power: cmm - convert sysdev_class to a regular subsystem
  s390: time - convert sysdev_class to a regular subsystem
  ...

Fix up conflicts with 'struct sysdev' removal from various platform
drivers that got changed:
 - arch/arm/mach-exynos/cpu.c
 - arch/arm/mach-exynos/irq-eint.c
 - arch/arm/mach-s3c64xx/common.c
 - arch/arm/mach-s3c64xx/cpu.c
 - arch/arm/mach-s5p64x0/cpu.c
 - arch/arm/mach-s5pv210/common.c
 - arch/arm/plat-samsung/include/plat/cpu.h
 - arch/powerpc/kernel/sysfs.c
and fix up cpu_is_hotpluggable() as per Greg in include/linux/cpu.h
This commit is contained in:
Linus Torvalds
2012-01-07 12:03:30 -08:00
517 changed files with 3168 additions and 6890 deletions
+2 -2
View File
@@ -3,7 +3,8 @@
obj-y := core.o sys.o bus.o dd.o syscore.o \
driver.o class.o platform.o \
cpu.o firmware.o init.o map.o devres.o \
attribute_container.o transport_class.o
attribute_container.o transport_class.o \
topology.o
obj-$(CONFIG_DEVTMPFS) += devtmpfs.o
obj-y += power/
obj-$(CONFIG_HAS_DMA) += dma-mapping.o
@@ -12,7 +13,6 @@ obj-$(CONFIG_ISA) += isa.o
obj-$(CONFIG_FW_LOADER) += firmware_class.o
obj-$(CONFIG_NUMA) += node.o
obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o
obj-$(CONFIG_SMP) += topology.o
ifeq ($(CONFIG_SYSFS),y)
obj-$(CONFIG_MODULES) += module.o
endif
+6 -6
View File
@@ -4,7 +4,9 @@
* struct subsys_private - structure to hold the private to the driver core portions of the bus_type/class structure.
*
* @subsys - the struct kset that defines this subsystem
* @devices_kset - the list of devices associated
* @devices_kset - the subsystem's 'devices' directory
* @interfaces - list of subsystem interfaces associated
* @mutex - protect the devices, and interfaces lists.
*
* @drivers_kset - the list of drivers associated
* @klist_devices - the klist to iterate over the @devices_kset
@@ -14,10 +16,8 @@
* @bus - pointer back to the struct bus_type that this structure is associated
* with.
*
* @class_interfaces - list of class_interfaces associated
* @glue_dirs - "glue" directory to put in-between the parent device to
* avoid namespace conflicts
* @class_mutex - mutex to protect the children, devices, and interfaces lists.
* @class - pointer back to the struct class that this structure is associated
* with.
*
@@ -28,6 +28,8 @@
struct subsys_private {
struct kset subsys;
struct kset *devices_kset;
struct list_head interfaces;
struct mutex mutex;
struct kset *drivers_kset;
struct klist klist_devices;
@@ -36,9 +38,7 @@ struct subsys_private {
unsigned int drivers_autoprobe:1;
struct bus_type *bus;
struct list_head class_interfaces;
struct kset glue_dirs;
struct mutex class_mutex;
struct class *class;
};
#define to_subsys_private(obj) container_of(obj, struct subsys_private, subsys.kobj)
@@ -94,7 +94,6 @@ extern int hypervisor_init(void);
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);
@@ -116,6 +115,7 @@ extern char *make_class_name(const char *name, struct kobject *kobj);
extern int devres_release_all(struct device *dev);
/* /sys/devices directory */
extern struct kset *devices_kset;
#if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS)
+273 -18
View File
@@ -16,9 +16,14 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/mutex.h>
#include "base.h"
#include "power/power.h"
/* /sys/devices/system */
/* FIXME: make static after drivers/base/sys.c is deleted */
struct kset *system_kset;
#define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr)
/*
@@ -360,6 +365,47 @@ struct device *bus_find_device_by_name(struct bus_type *bus,
}
EXPORT_SYMBOL_GPL(bus_find_device_by_name);
/**
* subsys_find_device_by_id - find a device with a specific enumeration number
* @subsys: subsystem
* @id: index 'id' in struct device
* @hint: device to check first
*
* Check the hint's next object and if it is a match return it directly,
* otherwise, fall back to a full list search. Either way a reference for
* the returned object is taken.
*/
struct device *subsys_find_device_by_id(struct bus_type *subsys, unsigned int id,
struct device *hint)
{
struct klist_iter i;
struct device *dev;
if (!subsys)
return NULL;
if (hint) {
klist_iter_init_node(&subsys->p->klist_devices, &i, &hint->p->knode_bus);
dev = next_device(&i);
if (dev && dev->id == id && get_device(dev)) {
klist_iter_exit(&i);
return dev;
}
klist_iter_exit(&i);
}
klist_iter_init_node(&subsys->p->klist_devices, &i, NULL);
while ((dev = next_device(&i))) {
if (dev->id == id && get_device(dev)) {
klist_iter_exit(&i);
return dev;
}
}
klist_iter_exit(&i);
return NULL;
}
EXPORT_SYMBOL_GPL(subsys_find_device_by_id);
static struct device_driver *next_driver(struct klist_iter *i)
{
struct klist_node *n = klist_next(i);
@@ -487,38 +533,59 @@ out_put:
void bus_probe_device(struct device *dev)
{
struct bus_type *bus = dev->bus;
struct subsys_interface *sif;
int ret;
if (bus && bus->p->drivers_autoprobe) {
if (!bus)
return;
if (bus->p->drivers_autoprobe) {
ret = device_attach(dev);
WARN_ON(ret < 0);
}
mutex_lock(&bus->p->mutex);
list_for_each_entry(sif, &bus->p->interfaces, node)
if (sif->add_dev)
sif->add_dev(dev, sif);
mutex_unlock(&bus->p->mutex);
}
/**
* bus_remove_device - remove device from bus
* @dev: device to be removed
*
* - Remove symlink from bus's directory.
* - Remove device from all interfaces.
* - Remove symlink from bus' 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");
sysfs_remove_link(&dev->bus->p->devices_kset->kobj,
dev_name(dev));
device_remove_attrs(dev->bus, dev);
if (klist_node_attached(&dev->p->knode_bus))
klist_del(&dev->p->knode_bus);
struct bus_type *bus = dev->bus;
struct subsys_interface *sif;
pr_debug("bus: '%s': remove device %s\n",
dev->bus->name, dev_name(dev));
device_release_driver(dev);
bus_put(dev->bus);
}
if (!bus)
return;
mutex_lock(&bus->p->mutex);
list_for_each_entry(sif, &bus->p->interfaces, node)
if (sif->remove_dev)
sif->remove_dev(dev, sif);
mutex_unlock(&bus->p->mutex);
sysfs_remove_link(&dev->kobj, "subsystem");
sysfs_remove_link(&dev->bus->p->devices_kset->kobj,
dev_name(dev));
device_remove_attrs(dev->bus, dev);
if (klist_node_attached(&dev->p->knode_bus))
klist_del(&dev->p->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)
@@ -847,14 +914,14 @@ static ssize_t bus_uevent_store(struct bus_type *bus,
static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store);
/**
* bus_register - register a bus with the system.
* __bus_register - register a driver-core subsystem
* @bus: bus.
*
* Once we have that, we registered the bus with the kobject
* infrastructure, then register the children subsystems it has:
* the devices and drivers that belong to the bus.
* the devices and drivers that belong to the subsystem.
*/
int bus_register(struct bus_type *bus)
int __bus_register(struct bus_type *bus, struct lock_class_key *key)
{
int retval;
struct subsys_private *priv;
@@ -898,6 +965,8 @@ int bus_register(struct bus_type *bus)
goto bus_drivers_fail;
}
INIT_LIST_HEAD(&priv->interfaces);
__mutex_init(&priv->mutex, "subsys mutex", key);
klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);
klist_init(&priv->klist_drivers, NULL, NULL);
@@ -927,7 +996,7 @@ out:
bus->p = NULL;
return retval;
}
EXPORT_SYMBOL_GPL(bus_register);
EXPORT_SYMBOL_GPL(__bus_register);
/**
* bus_unregister - remove a bus from the system
@@ -939,6 +1008,8 @@ EXPORT_SYMBOL_GPL(bus_register);
void bus_unregister(struct bus_type *bus)
{
pr_debug("bus: '%s': unregistering\n", bus->name);
if (bus->dev_root)
device_unregister(bus->dev_root);
bus_remove_attrs(bus);
remove_probe_files(bus);
kset_unregister(bus->p->drivers_kset);
@@ -1028,10 +1099,194 @@ void bus_sort_breadthfirst(struct bus_type *bus,
}
EXPORT_SYMBOL_GPL(bus_sort_breadthfirst);
/**
* subsys_dev_iter_init - initialize subsys device iterator
* @iter: subsys iterator to initialize
* @subsys: the subsys we wanna iterate over
* @start: the device to start iterating from, if any
* @type: device_type of the devices to iterate over, NULL for all
*
* Initialize subsys iterator @iter such that it iterates over devices
* of @subsys. If @start is set, the list iteration will start there,
* otherwise if it is NULL, the iteration starts at the beginning of
* the list.
*/
void subsys_dev_iter_init(struct subsys_dev_iter *iter, struct bus_type *subsys,
struct device *start, const struct device_type *type)
{
struct klist_node *start_knode = NULL;
if (start)
start_knode = &start->p->knode_bus;
klist_iter_init_node(&subsys->p->klist_devices, &iter->ki, start_knode);
iter->type = type;
}
EXPORT_SYMBOL_GPL(subsys_dev_iter_init);
/**
* subsys_dev_iter_next - iterate to the next device
* @iter: subsys iterator to proceed
*
* Proceed @iter to the next device and return it. Returns NULL if
* iteration is complete.
*
* The returned device is referenced and won't be released till
* iterator is proceed to the next device or exited. The caller is
* free to do whatever it wants to do with the device including
* calling back into subsys code.
*/
struct device *subsys_dev_iter_next(struct subsys_dev_iter *iter)
{
struct klist_node *knode;
struct device *dev;
for (;;) {
knode = klist_next(&iter->ki);
if (!knode)
return NULL;
dev = container_of(knode, struct device_private, knode_bus)->device;
if (!iter->type || iter->type == dev->type)
return dev;
}
}
EXPORT_SYMBOL_GPL(subsys_dev_iter_next);
/**
* subsys_dev_iter_exit - finish iteration
* @iter: subsys iterator to finish
*
* Finish an iteration. Always call this function after iteration is
* complete whether the iteration ran till the end or not.
*/
void subsys_dev_iter_exit(struct subsys_dev_iter *iter)
{
klist_iter_exit(&iter->ki);
}
EXPORT_SYMBOL_GPL(subsys_dev_iter_exit);
int subsys_interface_register(struct subsys_interface *sif)
{
struct bus_type *subsys;
struct subsys_dev_iter iter;
struct device *dev;
if (!sif || !sif->subsys)
return -ENODEV;
subsys = bus_get(sif->subsys);
if (!subsys)
return -EINVAL;
mutex_lock(&subsys->p->mutex);
list_add_tail(&sif->node, &subsys->p->interfaces);
if (sif->add_dev) {
subsys_dev_iter_init(&iter, subsys, NULL, NULL);
while ((dev = subsys_dev_iter_next(&iter)))
sif->add_dev(dev, sif);
subsys_dev_iter_exit(&iter);
}
mutex_unlock(&subsys->p->mutex);
return 0;
}
EXPORT_SYMBOL_GPL(subsys_interface_register);
void subsys_interface_unregister(struct subsys_interface *sif)
{
struct bus_type *subsys = sif->subsys;
struct subsys_dev_iter iter;
struct device *dev;
if (!sif)
return;
mutex_lock(&subsys->p->mutex);
list_del_init(&sif->node);
if (sif->remove_dev) {
subsys_dev_iter_init(&iter, subsys, NULL, NULL);
while ((dev = subsys_dev_iter_next(&iter)))
sif->remove_dev(dev, sif);
subsys_dev_iter_exit(&iter);
}
mutex_unlock(&subsys->p->mutex);
bus_put(subsys);
}
EXPORT_SYMBOL_GPL(subsys_interface_unregister);
static void system_root_device_release(struct device *dev)
{
kfree(dev);
}
/**
* subsys_system_register - register a subsystem at /sys/devices/system/
* @subsys - system subsystem
* @groups - default attributes for the root device
*
* All 'system' subsystems have a /sys/devices/system/<name> root device
* with the name of the subsystem. The root device can carry subsystem-
* wide attributes. All registered devices are below this single root
* device and are named after the subsystem with a simple enumeration
* number appended. The registered devices are not explicitely named;
* only 'id' in the device needs to be set.
*
* Do not use this interface for anything new, it exists for compatibility
* with bad ideas only. New subsystems should use plain subsystems; and
* add the subsystem-wide attributes should be added to the subsystem
* directory itself and not some create fake root-device placed in
* /sys/devices/system/<name>.
*/
int subsys_system_register(struct bus_type *subsys,
const struct attribute_group **groups)
{
struct device *dev;
int err;
err = bus_register(subsys);
if (err < 0)
return err;
dev = kzalloc(sizeof(struct device), GFP_KERNEL);
if (!dev) {
err = -ENOMEM;
goto err_dev;
}
err = dev_set_name(dev, "%s", subsys->name);
if (err < 0)
goto err_name;
dev->kobj.parent = &system_kset->kobj;
dev->groups = groups;
dev->release = system_root_device_release;
err = device_register(dev);
if (err < 0)
goto err_dev_reg;
subsys->dev_root = dev;
return 0;
err_dev_reg:
put_device(dev);
dev = NULL;
err_name:
kfree(dev);
err_dev:
bus_unregister(subsys);
return err;
}
EXPORT_SYMBOL_GPL(subsys_system_register);
int __init buses_init(void)
{
bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);
if (!bus_kset)
return -ENOMEM;
system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj);
if (!system_kset)
return -ENOMEM;
return 0;
}
+7 -7
View File
@@ -184,9 +184,9 @@ int __class_register(struct class *cls, struct lock_class_key *key)
if (!cp)
return -ENOMEM;
klist_init(&cp->klist_devices, klist_class_dev_get, klist_class_dev_put);
INIT_LIST_HEAD(&cp->class_interfaces);
INIT_LIST_HEAD(&cp->interfaces);
kset_init(&cp->glue_dirs);
__mutex_init(&cp->class_mutex, "struct class mutex", key);
__mutex_init(&cp->mutex, "subsys mutex", key);
error = kobject_set_name(&cp->subsys.kobj, "%s", cls->name);
if (error) {
kfree(cp);
@@ -460,15 +460,15 @@ int class_interface_register(struct class_interface *class_intf)
if (!parent)
return -EINVAL;
mutex_lock(&parent->p->class_mutex);
list_add_tail(&class_intf->node, &parent->p->class_interfaces);
mutex_lock(&parent->p->mutex);
list_add_tail(&class_intf->node, &parent->p->interfaces);
if (class_intf->add_dev) {
class_dev_iter_init(&iter, parent, NULL, NULL);
while ((dev = class_dev_iter_next(&iter)))
class_intf->add_dev(dev, class_intf);
class_dev_iter_exit(&iter);
}
mutex_unlock(&parent->p->class_mutex);
mutex_unlock(&parent->p->mutex);
return 0;
}
@@ -482,7 +482,7 @@ void class_interface_unregister(struct class_interface *class_intf)
if (!parent)
return;
mutex_lock(&parent->p->class_mutex);
mutex_lock(&parent->p->mutex);
list_del_init(&class_intf->node);
if (class_intf->remove_dev) {
class_dev_iter_init(&iter, parent, NULL, NULL);
@@ -490,7 +490,7 @@ void class_interface_unregister(struct class_interface *class_intf)
class_intf->remove_dev(dev, class_intf);
class_dev_iter_exit(&iter);
}
mutex_unlock(&parent->p->class_mutex);
mutex_unlock(&parent->p->mutex);
class_put(parent);
}
+69 -16
View File
@@ -118,6 +118,56 @@ static const struct sysfs_ops dev_sysfs_ops = {
.store = dev_attr_store,
};
#define to_ext_attr(x) container_of(x, struct dev_ext_attribute, attr)
ssize_t device_store_ulong(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t size)
{
struct dev_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(device_store_ulong);
ssize_t device_show_ulong(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct dev_ext_attribute *ea = to_ext_attr(attr);
return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var));
}
EXPORT_SYMBOL_GPL(device_show_ulong);
ssize_t device_store_int(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t size)
{
struct dev_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(device_store_int);
ssize_t device_show_int(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct dev_ext_attribute *ea = to_ext_attr(attr);
return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var));
}
EXPORT_SYMBOL_GPL(device_show_int);
/**
* device_release - free device structure.
@@ -464,7 +514,7 @@ static ssize_t show_dev(struct device *dev, struct device_attribute *attr,
static struct device_attribute devt_attr =
__ATTR(dev, S_IRUGO, show_dev, NULL);
/* kset to create /sys/devices/ */
/* /sys/devices/ */
struct kset *devices_kset;
/**
@@ -711,6 +761,10 @@ static struct kobject *get_device_parent(struct device *dev,
return k;
}
/* subsystems can specify a default root directory for their devices */
if (!parent && dev->bus && dev->bus->dev_root)
return &dev->bus->dev_root->kobj;
if (parent)
return &parent->kobj;
return NULL;
@@ -731,14 +785,6 @@ static void cleanup_device_parent(struct device *dev)
cleanup_glue_dir(dev, dev->kobj.parent);
}
static void setup_parent(struct device *dev, struct device *parent)
{
struct kobject *kobj;
kobj = get_device_parent(dev, parent);
if (kobj)
dev->kobj.parent = kobj;
}
static int device_add_class_symlinks(struct device *dev)
{
int error;
@@ -891,6 +937,7 @@ int device_private_init(struct device *dev)
int device_add(struct device *dev)
{
struct device *parent = NULL;
struct kobject *kobj;
struct class_interface *class_intf;
int error = -EINVAL;
@@ -914,6 +961,10 @@ int device_add(struct device *dev)
dev->init_name = NULL;
}
/* subsystems can specify simple device enumeration */
if (!dev_name(dev) && dev->bus && dev->bus->dev_name)
dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id);
if (!dev_name(dev)) {
error = -EINVAL;
goto name_error;
@@ -922,7 +973,9 @@ int device_add(struct device *dev)
pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
parent = get_device(dev->parent);
setup_parent(dev, parent);
kobj = get_device_parent(dev, parent);
if (kobj)
dev->kobj.parent = kobj;
/* use parent numa_node */
if (parent)
@@ -982,17 +1035,17 @@ int device_add(struct device *dev)
&parent->p->klist_children);
if (dev->class) {
mutex_lock(&dev->class->p->class_mutex);
mutex_lock(&dev->class->p->mutex);
/* tie the class to the device */
klist_add_tail(&dev->knode_class,
&dev->class->p->klist_devices);
/* notify any interfaces that the device is here */
list_for_each_entry(class_intf,
&dev->class->p->class_interfaces, node)
&dev->class->p->interfaces, node)
if (class_intf->add_dev)
class_intf->add_dev(dev, class_intf);
mutex_unlock(&dev->class->p->class_mutex);
mutex_unlock(&dev->class->p->mutex);
}
done:
put_device(dev);
@@ -1107,15 +1160,15 @@ void device_del(struct device *dev)
if (dev->class) {
device_remove_class_symlinks(dev);
mutex_lock(&dev->class->p->class_mutex);
mutex_lock(&dev->class->p->mutex);
/* notify any interfaces that the device is now gone */
list_for_each_entry(class_intf,
&dev->class->p->class_interfaces, node)
&dev->class->p->interfaces, node)
if (class_intf->remove_dev)
class_intf->remove_dev(dev, class_intf);
/* remove the device from the class list */
klist_del(&dev->knode_class);
mutex_unlock(&dev->class->p->class_mutex);
mutex_unlock(&dev->class->p->mutex);
}
device_remove_file(dev, &uevent_attr);
device_remove_attrs(dev);
+80 -72
View File
@@ -1,8 +1,7 @@
/*
* drivers/base/cpu.c - basic CPU class support
* CPU subsystem support
*/
#include <linux/sysdev.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
@@ -14,40 +13,40 @@
#include "base.h"
static struct sysdev_class_attribute *cpu_sysdev_class_attrs[];
struct sysdev_class cpu_sysdev_class = {
struct bus_type cpu_subsys = {
.name = "cpu",
.attrs = cpu_sysdev_class_attrs,
.dev_name = "cpu",
};
EXPORT_SYMBOL(cpu_sysdev_class);
EXPORT_SYMBOL_GPL(cpu_subsys);
static DEFINE_PER_CPU(struct sys_device *, cpu_sys_devices);
static DEFINE_PER_CPU(struct device *, cpu_sys_devices);
#ifdef CONFIG_HOTPLUG_CPU
static ssize_t show_online(struct sys_device *dev, struct sysdev_attribute *attr,
static ssize_t show_online(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct cpu *cpu = container_of(dev, struct cpu, sysdev);
struct cpu *cpu = container_of(dev, struct cpu, dev);
return sprintf(buf, "%u\n", !!cpu_online(cpu->sysdev.id));
return sprintf(buf, "%u\n", !!cpu_online(cpu->dev.id));
}
static ssize_t __ref store_online(struct sys_device *dev, struct sysdev_attribute *attr,
const char *buf, size_t count)
static ssize_t __ref store_online(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct cpu *cpu = container_of(dev, struct cpu, sysdev);
struct cpu *cpu = container_of(dev, struct cpu, dev);
ssize_t ret;
cpu_hotplug_driver_lock();
switch (buf[0]) {
case '0':
ret = cpu_down(cpu->sysdev.id);
ret = cpu_down(cpu->dev.id);
if (!ret)
kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
break;
case '1':
ret = cpu_up(cpu->sysdev.id);
ret = cpu_up(cpu->dev.id);
if (!ret)
kobject_uevent(&dev->kobj, KOBJ_ONLINE);
break;
@@ -60,44 +59,44 @@ static ssize_t __ref store_online(struct sys_device *dev, struct sysdev_attribut
ret = count;
return ret;
}
static SYSDEV_ATTR(online, 0644, show_online, store_online);
static DEVICE_ATTR(online, 0644, show_online, store_online);
static void __cpuinit register_cpu_control(struct cpu *cpu)
{
sysdev_create_file(&cpu->sysdev, &attr_online);
device_create_file(&cpu->dev, &dev_attr_online);
}
void unregister_cpu(struct cpu *cpu)
{
int logical_cpu = cpu->sysdev.id;
int logical_cpu = cpu->dev.id;
unregister_cpu_under_node(logical_cpu, cpu_to_node(logical_cpu));
sysdev_remove_file(&cpu->sysdev, &attr_online);
device_remove_file(&cpu->dev, &dev_attr_online);
sysdev_unregister(&cpu->sysdev);
device_unregister(&cpu->dev);
per_cpu(cpu_sys_devices, logical_cpu) = NULL;
return;
}
#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
static ssize_t cpu_probe_store(struct sysdev_class *class,
struct sysdev_class_attribute *attr,
static ssize_t cpu_probe_store(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t count)
{
return arch_cpu_probe(buf, count);
}
static ssize_t cpu_release_store(struct sysdev_class *class,
struct sysdev_class_attribute *attr,
static ssize_t cpu_release_store(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t count)
{
return arch_cpu_release(buf, count);
}
static SYSDEV_CLASS_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
static SYSDEV_CLASS_ATTR(release, S_IWUSR, NULL, cpu_release_store);
static DEVICE_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
static DEVICE_ATTR(release, S_IWUSR, NULL, cpu_release_store);
#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
#else /* ... !CONFIG_HOTPLUG_CPU */
@@ -109,15 +108,15 @@ static inline void register_cpu_control(struct cpu *cpu)
#ifdef CONFIG_KEXEC
#include <linux/kexec.h>
static ssize_t show_crash_notes(struct sys_device *dev, struct sysdev_attribute *attr,
static ssize_t show_crash_notes(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct cpu *cpu = container_of(dev, struct cpu, sysdev);
struct cpu *cpu = container_of(dev, struct cpu, dev);
ssize_t rc;
unsigned long long addr;
int cpunum;
cpunum = cpu->sysdev.id;
cpunum = cpu->dev.id;
/*
* Might be reading other cpu's data based on which cpu read thread
@@ -129,7 +128,7 @@ static ssize_t show_crash_notes(struct sys_device *dev, struct sysdev_attribute
rc = sprintf(buf, "%Lx\n", addr);
return rc;
}
static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL);
static DEVICE_ATTR(crash_notes, 0400, show_crash_notes, NULL);
#endif
/*
@@ -137,12 +136,12 @@ static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL);
*/
struct cpu_attr {
struct sysdev_class_attribute attr;
struct device_attribute attr;
const struct cpumask *const * const map;
};
static ssize_t show_cpus_attr(struct sysdev_class *class,
struct sysdev_class_attribute *attr,
static ssize_t show_cpus_attr(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct cpu_attr *ca = container_of(attr, struct cpu_attr, attr);
@@ -153,10 +152,10 @@ static ssize_t show_cpus_attr(struct sysdev_class *class,
return n;
}
#define _CPU_ATTR(name, map) \
{ _SYSDEV_CLASS_ATTR(name, 0444, show_cpus_attr, NULL), map }
#define _CPU_ATTR(name, map) \
{ __ATTR(name, 0444, show_cpus_attr, NULL), map }
/* Keep in sync with cpu_sysdev_class_attrs */
/* Keep in sync with cpu_subsys_attrs */
static struct cpu_attr cpu_attrs[] = {
_CPU_ATTR(online, &cpu_online_mask),
_CPU_ATTR(possible, &cpu_possible_mask),
@@ -166,19 +165,19 @@ static struct cpu_attr cpu_attrs[] = {
/*
* Print values for NR_CPUS and offlined cpus
*/
static ssize_t print_cpus_kernel_max(struct sysdev_class *class,
struct sysdev_class_attribute *attr, char *buf)
static ssize_t print_cpus_kernel_max(struct device *dev,
struct device_attribute *attr, 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);
static DEVICE_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,
struct sysdev_class_attribute *attr, char *buf)
static ssize_t print_cpus_offline(struct device *dev,
struct device_attribute *attr, char *buf)
{
int n = 0, len = PAGE_SIZE-2;
cpumask_var_t offline;
@@ -205,7 +204,7 @@ static ssize_t print_cpus_offline(struct sysdev_class *class,
n += snprintf(&buf[n], len - n, "\n");
return n;
}
static SYSDEV_CLASS_ATTR(offline, 0444, print_cpus_offline, NULL);
static DEVICE_ATTR(offline, 0444, print_cpus_offline, NULL);
/*
* register_cpu - Setup a sysfs device for a CPU.
@@ -218,39 +217,60 @@ static SYSDEV_CLASS_ATTR(offline, 0444, print_cpus_offline, NULL);
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);
cpu->dev.id = num;
cpu->dev.bus = &cpu_subsys;
error = device_register(&cpu->dev);
if (!error && cpu->hotpluggable)
register_cpu_control(cpu);
if (!error)
per_cpu(cpu_sys_devices, num) = &cpu->sysdev;
per_cpu(cpu_sys_devices, num) = &cpu->dev;
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);
error = device_create_file(&cpu->dev, &dev_attr_crash_notes);
#endif
return error;
}
struct sys_device *get_cpu_sysdev(unsigned cpu)
struct device *get_cpu_device(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);
EXPORT_SYMBOL_GPL(get_cpu_device);
static struct attribute *cpu_root_attrs[] = {
#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
&dev_attr_probe.attr,
&dev_attr_release.attr,
#endif
&cpu_attrs[0].attr.attr,
&cpu_attrs[1].attr.attr,
&cpu_attrs[2].attr.attr,
&dev_attr_kernel_max.attr,
&dev_attr_offline.attr,
NULL
};
static struct attribute_group cpu_root_attr_group = {
.attrs = cpu_root_attrs,
};
static const struct attribute_group *cpu_root_attr_groups[] = {
&cpu_root_attr_group,
NULL,
};
bool cpu_is_hotpluggable(unsigned cpu)
{
struct sys_device *dev = get_cpu_sysdev(cpu);
return dev && container_of(dev, struct cpu, sysdev)->hotpluggable;
struct device *dev = get_cpu_device(cpu);
return dev && container_of(dev, struct cpu, dev)->hotpluggable;
}
EXPORT_SYMBOL_GPL(cpu_is_hotpluggable);
@@ -258,24 +278,12 @@ int __init cpu_dev_init(void)
{
int err;
err = sysdev_class_register(&cpu_sysdev_class);
#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
if (!err)
err = sched_create_sysfs_power_savings_entries(&cpu_sysdev_class);
#endif
err = subsys_system_register(&cpu_subsys, cpu_root_attr_groups);
if (err)
return err;
#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
err = sched_create_sysfs_power_savings_entries(cpu_subsys.dev_root);
#endif
return err;
}
static struct sysdev_class_attribute *cpu_sysdev_class_attrs[] = {
#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
&attr_probe,
&attr_release,
#endif
&cpu_attrs[0].attr,
&cpu_attrs[1].attr,
&cpu_attrs[2].attr,
&attr_kernel_max,
&attr_offline,
NULL
};
+1 -2
View File
@@ -413,10 +413,9 @@ static int devtmpfsd(void *p)
}
spin_lock(&req_lock);
}
set_current_state(TASK_INTERRUPTIBLE);
__set_current_state(TASK_INTERRUPTIBLE);
spin_unlock(&req_lock);
schedule();
__set_current_state(TASK_RUNNING);
}
return 0;
out:
+7 -7
View File
@@ -226,13 +226,13 @@ static ssize_t firmware_loading_store(struct device *dev,
int loading = simple_strtol(buf, NULL, 10);
int i;
mutex_lock(&fw_lock);
if (!fw_priv->fw)
goto out;
switch (loading) {
case 1:
mutex_lock(&fw_lock);
if (!fw_priv->fw) {
mutex_unlock(&fw_lock);
break;
}
firmware_free_data(fw_priv->fw);
memset(fw_priv->fw, 0, sizeof(struct firmware));
/* If the pages are not owned by 'struct firmware' */
@@ -243,7 +243,6 @@ static ssize_t firmware_loading_store(struct device *dev,
fw_priv->page_array_size = 0;
fw_priv->nr_pages = 0;
set_bit(FW_STATUS_LOADING, &fw_priv->status);
mutex_unlock(&fw_lock);
break;
case 0:
if (test_bit(FW_STATUS_LOADING, &fw_priv->status)) {
@@ -274,7 +273,8 @@ static ssize_t firmware_loading_store(struct device *dev,
fw_load_abort(fw_priv);
break;
}
out:
mutex_unlock(&fw_lock);
return count;
}
-1
View File
@@ -31,7 +31,6 @@ void __init driver_init(void)
* core core pieces.
*/
platform_bus_init();
system_bus_init();
cpu_dev_init();
memory_dev_init();
}
+66 -94
View File
@@ -1,5 +1,5 @@
/*
* drivers/base/memory.c - basic Memory class support
* Memory subsystem support
*
* Written by Matt Tolentino <matthew.e.tolentino@intel.com>
* Dave Hansen <haveblue@us.ibm.com>
@@ -10,7 +10,6 @@
* SPARSEMEM should be contained here, or in mm/memory_hotplug.c.
*/
#include <linux/sysdev.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/topology.h>
@@ -38,26 +37,9 @@ static inline int base_memory_block_id(int section_nr)
return section_nr / sections_per_block;
}
static struct sysdev_class memory_sysdev_class = {
static struct bus_type memory_subsys = {
.name = MEMORY_CLASS_NAME,
};
static const char *memory_uevent_name(struct kset *kset, struct kobject *kobj)
{
return MEMORY_CLASS_NAME;
}
static int memory_uevent(struct kset *kset, struct kobject *obj,
struct kobj_uevent_env *env)
{
int retval = 0;
return retval;
}
static const struct kset_uevent_ops memory_uevent_ops = {
.name = memory_uevent_name,
.uevent = memory_uevent,
.dev_name = MEMORY_CLASS_NAME,
};
static BLOCKING_NOTIFIER_HEAD(memory_chain);
@@ -96,21 +78,21 @@ int register_memory(struct memory_block *memory)
{
int error;
memory->sysdev.cls = &memory_sysdev_class;
memory->sysdev.id = memory->start_section_nr / sections_per_block;
memory->dev.bus = &memory_subsys;
memory->dev.id = memory->start_section_nr / sections_per_block;
error = sysdev_register(&memory->sysdev);
error = device_register(&memory->dev);
return error;
}
static void
unregister_memory(struct memory_block *memory)
{
BUG_ON(memory->sysdev.cls != &memory_sysdev_class);
BUG_ON(memory->dev.bus != &memory_subsys);
/* drop the ref. we got in remove_memory_block() */
kobject_put(&memory->sysdev.kobj);
sysdev_unregister(&memory->sysdev);
kobject_put(&memory->dev.kobj);
device_unregister(&memory->dev);
}
unsigned long __weak memory_block_size_bytes(void)
@@ -138,22 +120,22 @@ static unsigned long get_memory_block_size(void)
* uses.
*/
static ssize_t show_mem_start_phys_index(struct sys_device *dev,
struct sysdev_attribute *attr, char *buf)
static ssize_t show_mem_start_phys_index(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct memory_block *mem =
container_of(dev, struct memory_block, sysdev);
container_of(dev, struct memory_block, dev);
unsigned long phys_index;
phys_index = mem->start_section_nr / sections_per_block;
return sprintf(buf, "%08lx\n", phys_index);
}
static ssize_t show_mem_end_phys_index(struct sys_device *dev,
struct sysdev_attribute *attr, char *buf)
static ssize_t show_mem_end_phys_index(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct memory_block *mem =
container_of(dev, struct memory_block, sysdev);
container_of(dev, struct memory_block, dev);
unsigned long phys_index;
phys_index = mem->end_section_nr / sections_per_block;
@@ -163,13 +145,13 @@ static ssize_t show_mem_end_phys_index(struct sys_device *dev,
/*
* Show whether the section of memory is likely to be hot-removable
*/
static ssize_t show_mem_removable(struct sys_device *dev,
struct sysdev_attribute *attr, char *buf)
static ssize_t show_mem_removable(struct device *dev,
struct device_attribute *attr, char *buf)
{
unsigned long i, pfn;
int ret = 1;
struct memory_block *mem =
container_of(dev, struct memory_block, sysdev);
container_of(dev, struct memory_block, dev);
for (i = 0; i < sections_per_block; i++) {
pfn = section_nr_to_pfn(mem->start_section_nr + i);
@@ -182,11 +164,11 @@ static ssize_t show_mem_removable(struct sys_device *dev,
/*
* online, offline, going offline, etc.
*/
static ssize_t show_mem_state(struct sys_device *dev,
struct sysdev_attribute *attr, char *buf)
static ssize_t show_mem_state(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct memory_block *mem =
container_of(dev, struct memory_block, sysdev);
container_of(dev, struct memory_block, dev);
ssize_t len = 0;
/*
@@ -324,13 +306,13 @@ out:
}
static ssize_t
store_mem_state(struct sys_device *dev,
struct sysdev_attribute *attr, const char *buf, size_t count)
store_mem_state(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct memory_block *mem;
int ret = -EINVAL;
mem = container_of(dev, struct memory_block, sysdev);
mem = container_of(dev, struct memory_block, dev);
if (!strncmp(buf, "online", min((int)count, 6)))
ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE);
@@ -351,41 +333,41 @@ store_mem_state(struct sys_device *dev,
* s.t. if I offline all of these sections I can then
* remove the physical device?
*/
static ssize_t show_phys_device(struct sys_device *dev,
struct sysdev_attribute *attr, char *buf)
static ssize_t show_phys_device(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct memory_block *mem =
container_of(dev, struct memory_block, sysdev);
container_of(dev, struct memory_block, dev);
return sprintf(buf, "%d\n", mem->phys_device);
}
static SYSDEV_ATTR(phys_index, 0444, show_mem_start_phys_index, NULL);
static SYSDEV_ATTR(end_phys_index, 0444, show_mem_end_phys_index, NULL);
static SYSDEV_ATTR(state, 0644, show_mem_state, store_mem_state);
static SYSDEV_ATTR(phys_device, 0444, show_phys_device, NULL);
static SYSDEV_ATTR(removable, 0444, show_mem_removable, NULL);
static DEVICE_ATTR(phys_index, 0444, show_mem_start_phys_index, NULL);
static DEVICE_ATTR(end_phys_index, 0444, show_mem_end_phys_index, NULL);
static DEVICE_ATTR(state, 0644, show_mem_state, store_mem_state);
static DEVICE_ATTR(phys_device, 0444, show_phys_device, NULL);
static DEVICE_ATTR(removable, 0444, show_mem_removable, NULL);
#define mem_create_simple_file(mem, attr_name) \
sysdev_create_file(&mem->sysdev, &attr_##attr_name)
device_create_file(&mem->dev, &dev_attr_##attr_name)
#define mem_remove_simple_file(mem, attr_name) \
sysdev_remove_file(&mem->sysdev, &attr_##attr_name)
device_remove_file(&mem->dev, &dev_attr_##attr_name)
/*
* Block size attribute stuff
*/
static ssize_t
print_block_size(struct sysdev_class *class, struct sysdev_class_attribute *attr,
print_block_size(struct device *dev, struct device_attribute *attr,
char *buf)
{
return sprintf(buf, "%lx\n", get_memory_block_size());
}
static SYSDEV_CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL);
static DEVICE_ATTR(block_size_bytes, 0444, print_block_size, NULL);
static int block_size_init(void)
{
return sysfs_create_file(&memory_sysdev_class.kset.kobj,
&attr_block_size_bytes.attr);
return device_create_file(memory_subsys.dev_root,
&dev_attr_block_size_bytes);
}
/*
@@ -396,7 +378,7 @@ static int block_size_init(void)
*/
#ifdef CONFIG_ARCH_MEMORY_PROBE
static ssize_t
memory_probe_store(struct class *class, struct class_attribute *attr,
memory_probe_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
u64 phys_addr;
@@ -423,12 +405,11 @@ memory_probe_store(struct class *class, struct class_attribute *attr,
out:
return ret;
}
static CLASS_ATTR(probe, S_IWUSR, NULL, memory_probe_store);
static DEVICE_ATTR(probe, S_IWUSR, NULL, memory_probe_store);
static int memory_probe_init(void)
{
return sysfs_create_file(&memory_sysdev_class.kset.kobj,
&class_attr_probe.attr);
return device_create_file(memory_subsys.dev_root, &dev_attr_probe);
}
#else
static inline int memory_probe_init(void)
@@ -444,8 +425,8 @@ static inline int memory_probe_init(void)
/* Soft offline a page */
static ssize_t
store_soft_offline_page(struct class *class,
struct class_attribute *attr,
store_soft_offline_page(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
int ret;
@@ -463,8 +444,8 @@ store_soft_offline_page(struct class *class,
/* Forcibly offline a page, including killing processes. */
static ssize_t
store_hard_offline_page(struct class *class,
struct class_attribute *attr,
store_hard_offline_page(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
int ret;
@@ -478,18 +459,18 @@ store_hard_offline_page(struct class *class,
return ret ? ret : count;
}
static CLASS_ATTR(soft_offline_page, 0644, NULL, store_soft_offline_page);
static CLASS_ATTR(hard_offline_page, 0644, NULL, store_hard_offline_page);
static DEVICE_ATTR(soft_offline_page, 0644, NULL, store_soft_offline_page);
static DEVICE_ATTR(hard_offline_page, 0644, NULL, store_hard_offline_page);
static __init int memory_fail_init(void)
{
int err;
err = sysfs_create_file(&memory_sysdev_class.kset.kobj,
&class_attr_soft_offline_page.attr);
err = device_create_file(memory_subsys.dev_root,
&dev_attr_soft_offline_page);
if (!err)
err = sysfs_create_file(&memory_sysdev_class.kset.kobj,
&class_attr_hard_offline_page.attr);
err = device_create_file(memory_subsys.dev_root,
&dev_attr_hard_offline_page);
return err;
}
#else
@@ -509,31 +490,23 @@ int __weak arch_get_memory_phys_device(unsigned long start_pfn)
return 0;
}
/*
* A reference for the returned object is held and the reference for the
* hinted object is released.
*/
struct memory_block *find_memory_block_hinted(struct mem_section *section,
struct memory_block *hint)
{
struct kobject *kobj;
struct sys_device *sysdev;
struct memory_block *mem;
char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1];
int block_id = base_memory_block_id(__section_nr(section));
struct device *hintdev = hint ? &hint->dev : NULL;
struct device *dev;
kobj = hint ? &hint->sysdev.kobj : NULL;
/*
* This only works because we know that section == sysdev->id
* slightly redundant with sysdev_register()
*/
sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, block_id);
kobj = kset_find_obj_hinted(&memory_sysdev_class.kset, name, kobj);
if (!kobj)
dev = subsys_find_device_by_id(&memory_subsys, block_id, hintdev);
if (hint)
put_device(&hint->dev);
if (!dev)
return NULL;
sysdev = container_of(kobj, struct sys_device, kobj);
mem = container_of(sysdev, struct memory_block, sysdev);
return mem;
return container_of(dev, struct memory_block, dev);
}
/*
@@ -542,7 +515,7 @@ struct memory_block *find_memory_block_hinted(struct mem_section *section,
* this gets to be a real problem, we can always use a radix
* tree or something here.
*
* This could be made generic for all sysdev classes.
* This could be made generic for all device subsystems.
*/
struct memory_block *find_memory_block(struct mem_section *section)
{
@@ -598,7 +571,7 @@ static int add_memory_section(int nid, struct mem_section *section,
mem = find_memory_block(section);
if (mem) {
mem->section_count++;
kobject_put(&mem->sysdev.kobj);
kobject_put(&mem->dev.kobj);
} else
ret = init_memory_block(&mem, section, state);
@@ -631,7 +604,7 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section,
unregister_memory(mem);
kfree(mem);
} else
kobject_put(&mem->sysdev.kobj);
kobject_put(&mem->dev.kobj);
mutex_unlock(&mem_sysfs_mutex);
return 0;
@@ -664,8 +637,7 @@ int __init memory_dev_init(void)
int err;
unsigned long block_sz;
memory_sysdev_class.kset.uevent_ops = &memory_uevent_ops;
ret = sysdev_class_register(&memory_sysdev_class);
ret = subsys_system_register(&memory_subsys, NULL);
if (ret)
goto out;
+80 -74
View File
@@ -1,8 +1,7 @@
/*
* drivers/base/node.c - basic Node class support
* Basic Node interface support
*/
#include <linux/sysdev.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
@@ -19,18 +18,16 @@
#include <linux/swap.h>
#include <linux/slab.h>
static struct sysdev_class_attribute *node_state_attrs[];
static struct sysdev_class node_class = {
static struct bus_type node_subsys = {
.name = "node",
.attrs = node_state_attrs,
.dev_name = "node",
};
static ssize_t node_read_cpumap(struct sys_device *dev, int type, char *buf)
static ssize_t node_read_cpumap(struct device *dev, int type, char *buf)
{
struct node *node_dev = to_node(dev);
const struct cpumask *mask = cpumask_of_node(node_dev->sysdev.id);
const struct cpumask *mask = cpumask_of_node(node_dev->dev.id);
int len;
/* 2008/04/07: buf currently PAGE_SIZE, need 9 chars per 32 bits. */
@@ -44,23 +41,23 @@ static ssize_t node_read_cpumap(struct sys_device *dev, int type, char *buf)
return len;
}
static inline ssize_t node_read_cpumask(struct sys_device *dev,
struct sysdev_attribute *attr, char *buf)
static inline ssize_t node_read_cpumask(struct device *dev,
struct device_attribute *attr, char *buf)
{
return node_read_cpumap(dev, 0, buf);
}
static inline ssize_t node_read_cpulist(struct sys_device *dev,
struct sysdev_attribute *attr, char *buf)
static inline ssize_t node_read_cpulist(struct device *dev,
struct device_attribute *attr, char *buf)
{
return node_read_cpumap(dev, 1, buf);
}
static SYSDEV_ATTR(cpumap, S_IRUGO, node_read_cpumask, NULL);
static SYSDEV_ATTR(cpulist, S_IRUGO, node_read_cpulist, NULL);
static DEVICE_ATTR(cpumap, S_IRUGO, node_read_cpumask, NULL);
static DEVICE_ATTR(cpulist, S_IRUGO, node_read_cpulist, NULL);
#define K(x) ((x) << (PAGE_SHIFT - 10))
static ssize_t node_read_meminfo(struct sys_device * dev,
struct sysdev_attribute *attr, char * buf)
static ssize_t node_read_meminfo(struct device *dev,
struct device_attribute *attr, char *buf)
{
int n;
int nid = dev->id;
@@ -157,10 +154,10 @@ static ssize_t node_read_meminfo(struct sys_device * dev,
}
#undef K
static SYSDEV_ATTR(meminfo, S_IRUGO, node_read_meminfo, NULL);
static DEVICE_ATTR(meminfo, S_IRUGO, node_read_meminfo, NULL);
static ssize_t node_read_numastat(struct sys_device * dev,
struct sysdev_attribute *attr, char * buf)
static ssize_t node_read_numastat(struct device *dev,
struct device_attribute *attr, char *buf)
{
return sprintf(buf,
"numa_hit %lu\n"
@@ -176,10 +173,10 @@ static ssize_t node_read_numastat(struct sys_device * dev,
node_page_state(dev->id, NUMA_LOCAL),
node_page_state(dev->id, NUMA_OTHER));
}
static SYSDEV_ATTR(numastat, S_IRUGO, node_read_numastat, NULL);
static DEVICE_ATTR(numastat, S_IRUGO, node_read_numastat, NULL);
static ssize_t node_read_vmstat(struct sys_device *dev,
struct sysdev_attribute *attr, char *buf)
static ssize_t node_read_vmstat(struct device *dev,
struct device_attribute *attr, char *buf)
{
int nid = dev->id;
int i;
@@ -191,10 +188,10 @@ static ssize_t node_read_vmstat(struct sys_device *dev,
return n;
}
static SYSDEV_ATTR(vmstat, S_IRUGO, node_read_vmstat, NULL);
static DEVICE_ATTR(vmstat, S_IRUGO, node_read_vmstat, NULL);
static ssize_t node_read_distance(struct sys_device * dev,
struct sysdev_attribute *attr, char * buf)
static ssize_t node_read_distance(struct device *dev,
struct device_attribute *attr, char * buf)
{
int nid = dev->id;
int len = 0;
@@ -212,7 +209,7 @@ static ssize_t node_read_distance(struct sys_device * dev,
len += sprintf(buf + len, "\n");
return len;
}
static SYSDEV_ATTR(distance, S_IRUGO, node_read_distance, NULL);
static DEVICE_ATTR(distance, S_IRUGO, node_read_distance, NULL);
#ifdef CONFIG_HUGETLBFS
/*
@@ -230,7 +227,7 @@ static node_registration_func_t __hugetlb_unregister_node;
static inline bool hugetlb_register_node(struct node *node)
{
if (__hugetlb_register_node &&
node_state(node->sysdev.id, N_HIGH_MEMORY)) {
node_state(node->dev.id, N_HIGH_MEMORY)) {
__hugetlb_register_node(node);
return true;
}
@@ -266,17 +263,17 @@ int register_node(struct node *node, int num, struct node *parent)
{
int error;
node->sysdev.id = num;
node->sysdev.cls = &node_class;
error = sysdev_register(&node->sysdev);
node->dev.id = num;
node->dev.bus = &node_subsys;
error = device_register(&node->dev);
if (!error){
sysdev_create_file(&node->sysdev, &attr_cpumap);
sysdev_create_file(&node->sysdev, &attr_cpulist);
sysdev_create_file(&node->sysdev, &attr_meminfo);
sysdev_create_file(&node->sysdev, &attr_numastat);
sysdev_create_file(&node->sysdev, &attr_distance);
sysdev_create_file(&node->sysdev, &attr_vmstat);
device_create_file(&node->dev, &dev_attr_cpumap);
device_create_file(&node->dev, &dev_attr_cpulist);
device_create_file(&node->dev, &dev_attr_meminfo);
device_create_file(&node->dev, &dev_attr_numastat);
device_create_file(&node->dev, &dev_attr_distance);
device_create_file(&node->dev, &dev_attr_vmstat);
scan_unevictable_register_node(node);
@@ -296,17 +293,17 @@ int register_node(struct node *node, int num, struct node *parent)
*/
void unregister_node(struct node *node)
{
sysdev_remove_file(&node->sysdev, &attr_cpumap);
sysdev_remove_file(&node->sysdev, &attr_cpulist);
sysdev_remove_file(&node->sysdev, &attr_meminfo);
sysdev_remove_file(&node->sysdev, &attr_numastat);
sysdev_remove_file(&node->sysdev, &attr_distance);
sysdev_remove_file(&node->sysdev, &attr_vmstat);
device_remove_file(&node->dev, &dev_attr_cpumap);
device_remove_file(&node->dev, &dev_attr_cpulist);
device_remove_file(&node->dev, &dev_attr_meminfo);
device_remove_file(&node->dev, &dev_attr_numastat);
device_remove_file(&node->dev, &dev_attr_distance);
device_remove_file(&node->dev, &dev_attr_vmstat);
scan_unevictable_unregister_node(node);
hugetlb_unregister_node(node); /* no-op, if memoryless node */
sysdev_unregister(&node->sysdev);
device_unregister(&node->dev);
}
struct node node_devices[MAX_NUMNODES];
@@ -317,41 +314,41 @@ struct node node_devices[MAX_NUMNODES];
int register_cpu_under_node(unsigned int cpu, unsigned int nid)
{
int ret;
struct sys_device *obj;
struct device *obj;
if (!node_online(nid))
return 0;
obj = get_cpu_sysdev(cpu);
obj = get_cpu_device(cpu);
if (!obj)
return 0;
ret = sysfs_create_link(&node_devices[nid].sysdev.kobj,
ret = sysfs_create_link(&node_devices[nid].dev.kobj,
&obj->kobj,
kobject_name(&obj->kobj));
if (ret)
return ret;
return sysfs_create_link(&obj->kobj,
&node_devices[nid].sysdev.kobj,
kobject_name(&node_devices[nid].sysdev.kobj));
&node_devices[nid].dev.kobj,
kobject_name(&node_devices[nid].dev.kobj));
}
int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
{
struct sys_device *obj;
struct device *obj;
if (!node_online(nid))
return 0;
obj = get_cpu_sysdev(cpu);
obj = get_cpu_device(cpu);
if (!obj)
return 0;
sysfs_remove_link(&node_devices[nid].sysdev.kobj,
sysfs_remove_link(&node_devices[nid].dev.kobj,
kobject_name(&obj->kobj));
sysfs_remove_link(&obj->kobj,
kobject_name(&node_devices[nid].sysdev.kobj));
kobject_name(&node_devices[nid].dev.kobj));
return 0;
}
@@ -393,15 +390,15 @@ int register_mem_sect_under_node(struct memory_block *mem_blk, int nid)
continue;
if (page_nid != nid)
continue;
ret = sysfs_create_link_nowarn(&node_devices[nid].sysdev.kobj,
&mem_blk->sysdev.kobj,
kobject_name(&mem_blk->sysdev.kobj));
ret = sysfs_create_link_nowarn(&node_devices[nid].dev.kobj,
&mem_blk->dev.kobj,
kobject_name(&mem_blk->dev.kobj));
if (ret)
return ret;
return sysfs_create_link_nowarn(&mem_blk->sysdev.kobj,
&node_devices[nid].sysdev.kobj,
kobject_name(&node_devices[nid].sysdev.kobj));
return sysfs_create_link_nowarn(&mem_blk->dev.kobj,
&node_devices[nid].dev.kobj,
kobject_name(&node_devices[nid].dev.kobj));
}
/* mem section does not span the specified node */
return 0;
@@ -434,10 +431,10 @@ int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
continue;
if (node_test_and_set(nid, *unlinked_nodes))
continue;
sysfs_remove_link(&node_devices[nid].sysdev.kobj,
kobject_name(&mem_blk->sysdev.kobj));
sysfs_remove_link(&mem_blk->sysdev.kobj,
kobject_name(&node_devices[nid].sysdev.kobj));
sysfs_remove_link(&node_devices[nid].dev.kobj,
kobject_name(&mem_blk->dev.kobj));
sysfs_remove_link(&mem_blk->dev.kobj,
kobject_name(&node_devices[nid].dev.kobj));
}
NODEMASK_FREE(unlinked_nodes);
return 0;
@@ -468,7 +465,7 @@ static int link_mem_sections(int nid)
}
if (mem_blk)
kobject_put(&mem_blk->sysdev.kobj);
kobject_put(&mem_blk->dev.kobj);
return err;
}
@@ -596,19 +593,19 @@ static ssize_t print_nodes_state(enum node_states state, char *buf)
}
struct node_attr {
struct sysdev_class_attribute attr;
struct device_attribute attr;
enum node_states state;
};
static ssize_t show_node_state(struct sysdev_class *class,
struct sysdev_class_attribute *attr, char *buf)
static ssize_t show_node_state(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct node_attr *na = container_of(attr, struct node_attr, attr);
return print_nodes_state(na->state, buf);
}
#define _NODE_ATTR(name, state) \
{ _SYSDEV_CLASS_ATTR(name, 0444, show_node_state, NULL), state }
{ __ATTR(name, 0444, show_node_state, NULL), state }
static struct node_attr node_state_attr[] = {
_NODE_ATTR(possible, N_POSSIBLE),
@@ -620,17 +617,26 @@ static struct node_attr node_state_attr[] = {
#endif
};
static struct sysdev_class_attribute *node_state_attrs[] = {
&node_state_attr[0].attr,
&node_state_attr[1].attr,
&node_state_attr[2].attr,
&node_state_attr[3].attr,
static struct attribute *node_state_attrs[] = {
&node_state_attr[0].attr.attr,
&node_state_attr[1].attr.attr,
&node_state_attr[2].attr.attr,
&node_state_attr[3].attr.attr,
#ifdef CONFIG_HIGHMEM
&node_state_attr[4].attr,
&node_state_attr[4].attr.attr,
#endif
NULL
};
static struct attribute_group memory_root_attr_group = {
.attrs = node_state_attrs,
};
static const struct attribute_group *cpu_root_attr_groups[] = {
&memory_root_attr_group,
NULL,
};
#define NODE_CALLBACK_PRI 2 /* lower than SLAB */
static int __init register_node_type(void)
{
@@ -639,7 +645,7 @@ static int __init register_node_type(void)
BUILD_BUG_ON(ARRAY_SIZE(node_state_attr) != NR_NODE_STATES);
BUILD_BUG_ON(ARRAY_SIZE(node_state_attrs)-1 != NR_NODE_STATES);
ret = sysdev_class_register(&node_class);
ret = subsys_system_register(&node_subsys, cpu_root_attr_groups);
if (!ret) {
hotplug_memory_notifier(node_memory_callback,
NODE_CALLBACK_PRI);
+1 -1
View File
@@ -383,7 +383,7 @@ EXPORT_SYMBOL_GPL(platform_device_unregister);
* Returns &struct platform_device pointer on success, or ERR_PTR() on error.
*/
struct platform_device *platform_device_register_full(
struct platform_device_info *pdevinfo)
const struct platform_device_info *pdevinfo)
{
int ret = -ENOMEM;
struct platform_device *pdev;
+1 -9
View File
@@ -126,7 +126,7 @@ void sysdev_class_remove_file(struct sysdev_class *c,
}
EXPORT_SYMBOL_GPL(sysdev_class_remove_file);
static struct kset *system_kset;
extern struct kset *system_kset;
int sysdev_class_register(struct sysdev_class *cls)
{
@@ -331,14 +331,6 @@ void sysdev_unregister(struct sys_device *sysdev)
EXPORT_SYMBOL_GPL(sysdev_register);
EXPORT_SYMBOL_GPL(sysdev_unregister);
int __init system_bus_init(void)
{
system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj);
if (!system_kset)
return -ENOMEM;
return 0;
}
#define to_ext_attr(x) container_of(x, struct sysdev_ext_attribute, attr)
ssize_t sysdev_store_ulong(struct sys_device *sysdev,
+25 -26
View File
@@ -23,7 +23,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <linux/sysdev.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/cpu.h>
@@ -32,14 +31,14 @@
#include <linux/topology.h>
#define define_one_ro_named(_name, _func) \
static SYSDEV_ATTR(_name, 0444, _func, NULL)
static DEVICE_ATTR(_name, 0444, _func, NULL)
#define define_one_ro(_name) \
static SYSDEV_ATTR(_name, 0444, show_##_name, NULL)
static DEVICE_ATTR(_name, 0444, show_##_name, NULL)
#define define_id_show_func(name) \
static ssize_t show_##name(struct sys_device *dev, \
struct sysdev_attribute *attr, char *buf) \
static ssize_t show_##name(struct device *dev, \
struct device_attribute *attr, char *buf) \
{ \
unsigned int cpu = dev->id; \
return sprintf(buf, "%d\n", topology_##name(cpu)); \
@@ -65,16 +64,16 @@ static ssize_t show_cpumap(int type, const struct cpumask *mask, char *buf)
#ifdef arch_provides_topology_pointers
#define define_siblings_show_map(name) \
static ssize_t show_##name(struct sys_device *dev, \
struct sysdev_attribute *attr, char *buf) \
static ssize_t show_##name(struct device *dev, \
struct device_attribute *attr, char *buf) \
{ \
unsigned int cpu = dev->id; \
return show_cpumap(0, topology_##name(cpu), buf); \
}
#define define_siblings_show_list(name) \
static ssize_t show_##name##_list(struct sys_device *dev, \
struct sysdev_attribute *attr, \
static ssize_t show_##name##_list(struct device *dev, \
struct device_attribute *attr, \
char *buf) \
{ \
unsigned int cpu = dev->id; \
@@ -83,15 +82,15 @@ static ssize_t show_##name##_list(struct sys_device *dev, \
#else
#define define_siblings_show_map(name) \
static ssize_t show_##name(struct sys_device *dev, \
struct sysdev_attribute *attr, char *buf) \
static ssize_t show_##name(struct device *dev, \
struct device_attribute *attr, char *buf) \
{ \
return show_cpumap(0, topology_##name(dev->id), buf); \
}
#define define_siblings_show_list(name) \
static ssize_t show_##name##_list(struct sys_device *dev, \
struct sysdev_attribute *attr, \
static ssize_t show_##name##_list(struct device *dev, \
struct device_attribute *attr, \
char *buf) \
{ \
return show_cpumap(1, topology_##name(dev->id), buf); \
@@ -124,16 +123,16 @@ define_one_ro_named(book_siblings_list, show_book_cpumask_list);
#endif
static struct attribute *default_attrs[] = {
&attr_physical_package_id.attr,
&attr_core_id.attr,
&attr_thread_siblings.attr,
&attr_thread_siblings_list.attr,
&attr_core_siblings.attr,
&attr_core_siblings_list.attr,
&dev_attr_physical_package_id.attr,
&dev_attr_core_id.attr,
&dev_attr_thread_siblings.attr,
&dev_attr_thread_siblings_list.attr,
&dev_attr_core_siblings.attr,
&dev_attr_core_siblings_list.attr,
#ifdef CONFIG_SCHED_BOOK
&attr_book_id.attr,
&attr_book_siblings.attr,
&attr_book_siblings_list.attr,
&dev_attr_book_id.attr,
&dev_attr_book_siblings.attr,
&dev_attr_book_siblings_list.attr,
#endif
NULL
};
@@ -146,16 +145,16 @@ static struct attribute_group topology_attr_group = {
/* Add/Remove cpu_topology interface for CPU device */
static int __cpuinit topology_add_dev(unsigned int cpu)
{
struct sys_device *sys_dev = get_cpu_sysdev(cpu);
struct device *dev = get_cpu_device(cpu);
return sysfs_create_group(&sys_dev->kobj, &topology_attr_group);
return sysfs_create_group(&dev->kobj, &topology_attr_group);
}
static void __cpuinit topology_remove_dev(unsigned int cpu)
{
struct sys_device *sys_dev = get_cpu_sysdev(cpu);
struct device *dev = get_cpu_device(cpu);
sysfs_remove_group(&sys_dev->kobj, &topology_attr_group);
sysfs_remove_group(&dev->kobj, &topology_attr_group);
}
static int __cpuinit topology_cpu_callback(struct notifier_block *nfb,