diff options
Diffstat (limited to 'drivers/base/memory.c')
| -rw-r--r-- | drivers/base/memory.c | 160 | 
1 files changed, 66 insertions, 94 deletions
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 8272d92d22c..f17e3ea041c 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -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;  |