Skip to content

Commit

Permalink
convert 'memory' sysdev_class to a regular subsystem
Browse files Browse the repository at this point in the history
This moves the 'memory sysdev_class' over to a regular 'memory' subsystem
and converts the devices to regular devices. The sysdev drivers are
implemented as subsystem interfaces now.

After all sysdev classes are ported to regular driver core entities, the
sysdev implementation will be entirely removed from the kernel.

Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Kay Sievers authored and Greg Kroah-Hartman committed Dec 21, 2011
1 parent 8a25a2f commit 10fbcf4
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 200 deletions.
4 changes: 2 additions & 2 deletions arch/powerpc/kernel/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -592,15 +592,15 @@ static void register_nodes(void)
int sysfs_add_device_to_node(struct device *dev, int nid)
{
struct node *node = &node_devices[nid];
return sysfs_create_link(&node->sysdev.kobj, &dev->kobj,
return sysfs_create_link(&node->dev.kobj, &dev->kobj,
kobject_name(&dev->kobj));
}
EXPORT_SYMBOL_GPL(sysfs_add_device_to_node);

void sysfs_remove_device_from_node(struct device *dev, int nid)
{
struct node *node = &node_devices[nid];
sysfs_remove_link(&node->sysdev.kobj, kobject_name(&dev->kobj));
sysfs_remove_link(&node->dev.kobj, kobject_name(&dev->kobj));
}
EXPORT_SYMBOL_GPL(sysfs_remove_device_from_node);

Expand Down
160 changes: 66 additions & 94 deletions drivers/base/memory.c
Original file line number Diff line number Diff line change
@@ -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>
Expand All @@ -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>
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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;

/*
Expand Down Expand Up @@ -324,13 +306,13 @@ static int memory_block_change_state(struct memory_block *mem,
}

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);
Expand All @@ -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);
}

/*
Expand All @@ -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;
Expand All @@ -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)
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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
Expand All @@ -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);
}

/*
Expand All @@ -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)
{
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down
Loading

0 comments on commit 10fbcf4

Please sign in to comment.