aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/memory.c
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2011-12-21 17:48:43 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2011-12-21 17:48:43 -0500
commit10fbcf4c6cb122005cdf36fc24d7683da92c7a27 (patch)
tree1a2ad572b421d576e14dbf006ecb321a53063f0c /drivers/base/memory.c
parent8a25a2fd126c621f44f3aeaef80d51f00fc11639 (diff)
convert 'memory' sysdev_class to a regular subsystem
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>
Diffstat (limited to 'drivers/base/memory.c')
-rw-r--r--drivers/base/memory.c160
1 files changed, 66 insertions, 94 deletions
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 8272d92d22c0..f17e3ea041c0 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * drivers/base/memory.c - basic Memory class support 2 * Memory subsystem support
3 * 3 *
4 * Written by Matt Tolentino <matthew.e.tolentino@intel.com> 4 * Written by Matt Tolentino <matthew.e.tolentino@intel.com>
5 * Dave Hansen <haveblue@us.ibm.com> 5 * Dave Hansen <haveblue@us.ibm.com>
@@ -10,7 +10,6 @@
10 * SPARSEMEM should be contained here, or in mm/memory_hotplug.c. 10 * SPARSEMEM should be contained here, or in mm/memory_hotplug.c.
11 */ 11 */
12 12
13#include <linux/sysdev.h>
14#include <linux/module.h> 13#include <linux/module.h>
15#include <linux/init.h> 14#include <linux/init.h>
16#include <linux/topology.h> 15#include <linux/topology.h>
@@ -38,26 +37,9 @@ static inline int base_memory_block_id(int section_nr)
38 return section_nr / sections_per_block; 37 return section_nr / sections_per_block;
39} 38}
40 39
41static struct sysdev_class memory_sysdev_class = { 40static struct bus_type memory_subsys = {
42 .name = MEMORY_CLASS_NAME, 41 .name = MEMORY_CLASS_NAME,
43}; 42 .dev_name = MEMORY_CLASS_NAME,
44
45static const char *memory_uevent_name(struct kset *kset, struct kobject *kobj)
46{
47 return MEMORY_CLASS_NAME;
48}
49
50static int memory_uevent(struct kset *kset, struct kobject *obj,
51 struct kobj_uevent_env *env)
52{
53 int retval = 0;
54
55 return retval;
56}
57
58static const struct kset_uevent_ops memory_uevent_ops = {
59 .name = memory_uevent_name,
60 .uevent = memory_uevent,
61}; 43};
62 44
63static BLOCKING_NOTIFIER_HEAD(memory_chain); 45static BLOCKING_NOTIFIER_HEAD(memory_chain);
@@ -96,21 +78,21 @@ int register_memory(struct memory_block *memory)
96{ 78{
97 int error; 79 int error;
98 80
99 memory->sysdev.cls = &memory_sysdev_class; 81 memory->dev.bus = &memory_subsys;
100 memory->sysdev.id = memory->start_section_nr / sections_per_block; 82 memory->dev.id = memory->start_section_nr / sections_per_block;
101 83
102 error = sysdev_register(&memory->sysdev); 84 error = device_register(&memory->dev);
103 return error; 85 return error;
104} 86}
105 87
106static void 88static void
107unregister_memory(struct memory_block *memory) 89unregister_memory(struct memory_block *memory)
108{ 90{
109 BUG_ON(memory->sysdev.cls != &memory_sysdev_class); 91 BUG_ON(memory->dev.bus != &memory_subsys);
110 92
111 /* drop the ref. we got in remove_memory_block() */ 93 /* drop the ref. we got in remove_memory_block() */
112 kobject_put(&memory->sysdev.kobj); 94 kobject_put(&memory->dev.kobj);
113 sysdev_unregister(&memory->sysdev); 95 device_unregister(&memory->dev);
114} 96}
115 97
116unsigned long __weak memory_block_size_bytes(void) 98unsigned long __weak memory_block_size_bytes(void)
@@ -138,22 +120,22 @@ static unsigned long get_memory_block_size(void)
138 * uses. 120 * uses.
139 */ 121 */
140 122
141static ssize_t show_mem_start_phys_index(struct sys_device *dev, 123static ssize_t show_mem_start_phys_index(struct device *dev,
142 struct sysdev_attribute *attr, char *buf) 124 struct device_attribute *attr, char *buf)
143{ 125{
144 struct memory_block *mem = 126 struct memory_block *mem =
145 container_of(dev, struct memory_block, sysdev); 127 container_of(dev, struct memory_block, dev);
146 unsigned long phys_index; 128 unsigned long phys_index;
147 129
148 phys_index = mem->start_section_nr / sections_per_block; 130 phys_index = mem->start_section_nr / sections_per_block;
149 return sprintf(buf, "%08lx\n", phys_index); 131 return sprintf(buf, "%08lx\n", phys_index);
150} 132}
151 133
152static ssize_t show_mem_end_phys_index(struct sys_device *dev, 134static ssize_t show_mem_end_phys_index(struct device *dev,
153 struct sysdev_attribute *attr, char *buf) 135 struct device_attribute *attr, char *buf)
154{ 136{
155 struct memory_block *mem = 137 struct memory_block *mem =
156 container_of(dev, struct memory_block, sysdev); 138 container_of(dev, struct memory_block, dev);
157 unsigned long phys_index; 139 unsigned long phys_index;
158 140
159 phys_index = mem->end_section_nr / sections_per_block; 141 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,
163/* 145/*
164 * Show whether the section of memory is likely to be hot-removable 146 * Show whether the section of memory is likely to be hot-removable
165 */ 147 */
166static ssize_t show_mem_removable(struct sys_device *dev, 148static ssize_t show_mem_removable(struct device *dev,
167 struct sysdev_attribute *attr, char *buf) 149 struct device_attribute *attr, char *buf)
168{ 150{
169 unsigned long i, pfn; 151 unsigned long i, pfn;
170 int ret = 1; 152 int ret = 1;
171 struct memory_block *mem = 153 struct memory_block *mem =
172 container_of(dev, struct memory_block, sysdev); 154 container_of(dev, struct memory_block, dev);
173 155
174 for (i = 0; i < sections_per_block; i++) { 156 for (i = 0; i < sections_per_block; i++) {
175 pfn = section_nr_to_pfn(mem->start_section_nr + i); 157 pfn = section_nr_to_pfn(mem->start_section_nr + i);
@@ -182,11 +164,11 @@ static ssize_t show_mem_removable(struct sys_device *dev,
182/* 164/*
183 * online, offline, going offline, etc. 165 * online, offline, going offline, etc.
184 */ 166 */
185static ssize_t show_mem_state(struct sys_device *dev, 167static ssize_t show_mem_state(struct device *dev,
186 struct sysdev_attribute *attr, char *buf) 168 struct device_attribute *attr, char *buf)
187{ 169{
188 struct memory_block *mem = 170 struct memory_block *mem =
189 container_of(dev, struct memory_block, sysdev); 171 container_of(dev, struct memory_block, dev);
190 ssize_t len = 0; 172 ssize_t len = 0;
191 173
192 /* 174 /*
@@ -324,13 +306,13 @@ out:
324} 306}
325 307
326static ssize_t 308static ssize_t
327store_mem_state(struct sys_device *dev, 309store_mem_state(struct device *dev,
328 struct sysdev_attribute *attr, const char *buf, size_t count) 310 struct device_attribute *attr, const char *buf, size_t count)
329{ 311{
330 struct memory_block *mem; 312 struct memory_block *mem;
331 int ret = -EINVAL; 313 int ret = -EINVAL;
332 314
333 mem = container_of(dev, struct memory_block, sysdev); 315 mem = container_of(dev, struct memory_block, dev);
334 316
335 if (!strncmp(buf, "online", min((int)count, 6))) 317 if (!strncmp(buf, "online", min((int)count, 6)))
336 ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE); 318 ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE);
@@ -351,41 +333,41 @@ store_mem_state(struct sys_device *dev,
351 * s.t. if I offline all of these sections I can then 333 * s.t. if I offline all of these sections I can then
352 * remove the physical device? 334 * remove the physical device?
353 */ 335 */
354static ssize_t show_phys_device(struct sys_device *dev, 336static ssize_t show_phys_device(struct device *dev,
355 struct sysdev_attribute *attr, char *buf) 337 struct device_attribute *attr, char *buf)
356{ 338{
357 struct memory_block *mem = 339 struct memory_block *mem =
358 container_of(dev, struct memory_block, sysdev); 340 container_of(dev, struct memory_block, dev);
359 return sprintf(buf, "%d\n", mem->phys_device); 341 return sprintf(buf, "%d\n", mem->phys_device);
360} 342}
361 343
362static SYSDEV_ATTR(phys_index, 0444, show_mem_start_phys_index, NULL); 344static DEVICE_ATTR(phys_index, 0444, show_mem_start_phys_index, NULL);
363static SYSDEV_ATTR(end_phys_index, 0444, show_mem_end_phys_index, NULL); 345static DEVICE_ATTR(end_phys_index, 0444, show_mem_end_phys_index, NULL);
364static SYSDEV_ATTR(state, 0644, show_mem_state, store_mem_state); 346static DEVICE_ATTR(state, 0644, show_mem_state, store_mem_state);
365static SYSDEV_ATTR(phys_device, 0444, show_phys_device, NULL); 347static DEVICE_ATTR(phys_device, 0444, show_phys_device, NULL);
366static SYSDEV_ATTR(removable, 0444, show_mem_removable, NULL); 348static DEVICE_ATTR(removable, 0444, show_mem_removable, NULL);
367 349
368#define mem_create_simple_file(mem, attr_name) \ 350#define mem_create_simple_file(mem, attr_name) \
369 sysdev_create_file(&mem->sysdev, &attr_##attr_name) 351 device_create_file(&mem->dev, &dev_attr_##attr_name)
370#define mem_remove_simple_file(mem, attr_name) \ 352#define mem_remove_simple_file(mem, attr_name) \
371 sysdev_remove_file(&mem->sysdev, &attr_##attr_name) 353 device_remove_file(&mem->dev, &dev_attr_##attr_name)
372 354
373/* 355/*
374 * Block size attribute stuff 356 * Block size attribute stuff
375 */ 357 */
376static ssize_t 358static ssize_t
377print_block_size(struct sysdev_class *class, struct sysdev_class_attribute *attr, 359print_block_size(struct device *dev, struct device_attribute *attr,
378 char *buf) 360 char *buf)
379{ 361{
380 return sprintf(buf, "%lx\n", get_memory_block_size()); 362 return sprintf(buf, "%lx\n", get_memory_block_size());
381} 363}
382 364
383static SYSDEV_CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL); 365static DEVICE_ATTR(block_size_bytes, 0444, print_block_size, NULL);
384 366
385static int block_size_init(void) 367static int block_size_init(void)
386{ 368{
387 return sysfs_create_file(&memory_sysdev_class.kset.kobj, 369 return device_create_file(memory_subsys.dev_root,
388 &attr_block_size_bytes.attr); 370 &dev_attr_block_size_bytes);
389} 371}
390 372
391/* 373/*
@@ -396,7 +378,7 @@ static int block_size_init(void)
396 */ 378 */
397#ifdef CONFIG_ARCH_MEMORY_PROBE 379#ifdef CONFIG_ARCH_MEMORY_PROBE
398static ssize_t 380static ssize_t
399memory_probe_store(struct class *class, struct class_attribute *attr, 381memory_probe_store(struct device *dev, struct device_attribute *attr,
400 const char *buf, size_t count) 382 const char *buf, size_t count)
401{ 383{
402 u64 phys_addr; 384 u64 phys_addr;
@@ -423,12 +405,11 @@ memory_probe_store(struct class *class, struct class_attribute *attr,
423out: 405out:
424 return ret; 406 return ret;
425} 407}
426static CLASS_ATTR(probe, S_IWUSR, NULL, memory_probe_store); 408static DEVICE_ATTR(probe, S_IWUSR, NULL, memory_probe_store);
427 409
428static int memory_probe_init(void) 410static int memory_probe_init(void)
429{ 411{
430 return sysfs_create_file(&memory_sysdev_class.kset.kobj, 412 return device_create_file(memory_subsys.dev_root, &dev_attr_probe);
431 &class_attr_probe.attr);
432} 413}
433#else 414#else
434static inline int memory_probe_init(void) 415static inline int memory_probe_init(void)
@@ -444,8 +425,8 @@ static inline int memory_probe_init(void)
444 425
445/* Soft offline a page */ 426/* Soft offline a page */
446static ssize_t 427static ssize_t
447store_soft_offline_page(struct class *class, 428store_soft_offline_page(struct device *dev,
448 struct class_attribute *attr, 429 struct device_attribute *attr,
449 const char *buf, size_t count) 430 const char *buf, size_t count)
450{ 431{
451 int ret; 432 int ret;
@@ -463,8 +444,8 @@ store_soft_offline_page(struct class *class,
463 444
464/* Forcibly offline a page, including killing processes. */ 445/* Forcibly offline a page, including killing processes. */
465static ssize_t 446static ssize_t
466store_hard_offline_page(struct class *class, 447store_hard_offline_page(struct device *dev,
467 struct class_attribute *attr, 448 struct device_attribute *attr,
468 const char *buf, size_t count) 449 const char *buf, size_t count)
469{ 450{
470 int ret; 451 int ret;
@@ -478,18 +459,18 @@ store_hard_offline_page(struct class *class,
478 return ret ? ret : count; 459 return ret ? ret : count;
479} 460}
480 461
481static CLASS_ATTR(soft_offline_page, 0644, NULL, store_soft_offline_page); 462static DEVICE_ATTR(soft_offline_page, 0644, NULL, store_soft_offline_page);
482static CLASS_ATTR(hard_offline_page, 0644, NULL, store_hard_offline_page); 463static DEVICE_ATTR(hard_offline_page, 0644, NULL, store_hard_offline_page);
483 464
484static __init int memory_fail_init(void) 465static __init int memory_fail_init(void)
485{ 466{
486 int err; 467 int err;
487 468
488 err = sysfs_create_file(&memory_sysdev_class.kset.kobj, 469 err = device_create_file(memory_subsys.dev_root,
489 &class_attr_soft_offline_page.attr); 470 &dev_attr_soft_offline_page);
490 if (!err) 471 if (!err)
491 err = sysfs_create_file(&memory_sysdev_class.kset.kobj, 472 err = device_create_file(memory_subsys.dev_root,
492 &class_attr_hard_offline_page.attr); 473 &dev_attr_hard_offline_page);
493 return err; 474 return err;
494} 475}
495#else 476#else
@@ -509,31 +490,23 @@ int __weak arch_get_memory_phys_device(unsigned long start_pfn)
509 return 0; 490 return 0;
510} 491}
511 492
493/*
494 * A reference for the returned object is held and the reference for the
495 * hinted object is released.
496 */
512struct memory_block *find_memory_block_hinted(struct mem_section *section, 497struct memory_block *find_memory_block_hinted(struct mem_section *section,
513 struct memory_block *hint) 498 struct memory_block *hint)
514{ 499{
515 struct kobject *kobj;
516 struct sys_device *sysdev;
517 struct memory_block *mem;
518 char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1];
519 int block_id = base_memory_block_id(__section_nr(section)); 500 int block_id = base_memory_block_id(__section_nr(section));
501 struct device *hintdev = hint ? &hint->dev : NULL;
502 struct device *dev;
520 503
521 kobj = hint ? &hint->sysdev.kobj : NULL; 504 dev = subsys_find_device_by_id(&memory_subsys, block_id, hintdev);
522 505 if (hint)
523 /* 506 put_device(&hint->dev);
524 * This only works because we know that section == sysdev->id 507 if (!dev)
525 * slightly redundant with sysdev_register()
526 */
527 sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, block_id);
528
529 kobj = kset_find_obj_hinted(&memory_sysdev_class.kset, name, kobj);
530 if (!kobj)
531 return NULL; 508 return NULL;
532 509 return container_of(dev, struct memory_block, dev);
533 sysdev = container_of(kobj, struct sys_device, kobj);
534 mem = container_of(sysdev, struct memory_block, sysdev);
535
536 return mem;
537} 510}
538 511
539/* 512/*
@@ -542,7 +515,7 @@ struct memory_block *find_memory_block_hinted(struct mem_section *section,
542 * this gets to be a real problem, we can always use a radix 515 * this gets to be a real problem, we can always use a radix
543 * tree or something here. 516 * tree or something here.
544 * 517 *
545 * This could be made generic for all sysdev classes. 518 * This could be made generic for all device subsystems.
546 */ 519 */
547struct memory_block *find_memory_block(struct mem_section *section) 520struct memory_block *find_memory_block(struct mem_section *section)
548{ 521{
@@ -598,7 +571,7 @@ static int add_memory_section(int nid, struct mem_section *section,
598 mem = find_memory_block(section); 571 mem = find_memory_block(section);
599 if (mem) { 572 if (mem) {
600 mem->section_count++; 573 mem->section_count++;
601 kobject_put(&mem->sysdev.kobj); 574 kobject_put(&mem->dev.kobj);
602 } else 575 } else
603 ret = init_memory_block(&mem, section, state); 576 ret = init_memory_block(&mem, section, state);
604 577
@@ -631,7 +604,7 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section,
631 unregister_memory(mem); 604 unregister_memory(mem);
632 kfree(mem); 605 kfree(mem);
633 } else 606 } else
634 kobject_put(&mem->sysdev.kobj); 607 kobject_put(&mem->dev.kobj);
635 608
636 mutex_unlock(&mem_sysfs_mutex); 609 mutex_unlock(&mem_sysfs_mutex);
637 return 0; 610 return 0;
@@ -664,8 +637,7 @@ int __init memory_dev_init(void)
664 int err; 637 int err;
665 unsigned long block_sz; 638 unsigned long block_sz;
666 639
667 memory_sysdev_class.kset.uevent_ops = &memory_uevent_ops; 640 ret = subsys_system_register(&memory_subsys, NULL);
668 ret = sysdev_class_register(&memory_sysdev_class);
669 if (ret) 641 if (ret)
670 goto out; 642 goto out;
671 643