diff options
Diffstat (limited to 'drivers/base/memory.c')
-rw-r--r-- | drivers/base/memory.c | 143 |
1 files changed, 62 insertions, 81 deletions
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 14f8a6954da0..e315051cfeeb 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -77,22 +77,6 @@ static void memory_block_release(struct device *dev) | |||
77 | kfree(mem); | 77 | kfree(mem); |
78 | } | 78 | } |
79 | 79 | ||
80 | /* | ||
81 | * register_memory - Setup a sysfs device for a memory block | ||
82 | */ | ||
83 | static | ||
84 | int register_memory(struct memory_block *memory) | ||
85 | { | ||
86 | int error; | ||
87 | |||
88 | memory->dev.bus = &memory_subsys; | ||
89 | memory->dev.id = memory->start_section_nr / sections_per_block; | ||
90 | memory->dev.release = memory_block_release; | ||
91 | |||
92 | error = device_register(&memory->dev); | ||
93 | return error; | ||
94 | } | ||
95 | |||
96 | unsigned long __weak memory_block_size_bytes(void) | 80 | unsigned long __weak memory_block_size_bytes(void) |
97 | { | 81 | { |
98 | return MIN_MEMORY_BLOCK_SIZE; | 82 | return MIN_MEMORY_BLOCK_SIZE; |
@@ -371,11 +355,6 @@ static DEVICE_ATTR(state, 0644, show_mem_state, store_mem_state); | |||
371 | static DEVICE_ATTR(phys_device, 0444, show_phys_device, NULL); | 355 | static DEVICE_ATTR(phys_device, 0444, show_phys_device, NULL); |
372 | static DEVICE_ATTR(removable, 0444, show_mem_removable, NULL); | 356 | static DEVICE_ATTR(removable, 0444, show_mem_removable, NULL); |
373 | 357 | ||
374 | #define mem_create_simple_file(mem, attr_name) \ | ||
375 | device_create_file(&mem->dev, &dev_attr_##attr_name) | ||
376 | #define mem_remove_simple_file(mem, attr_name) \ | ||
377 | device_remove_file(&mem->dev, &dev_attr_##attr_name) | ||
378 | |||
379 | /* | 358 | /* |
380 | * Block size attribute stuff | 359 | * Block size attribute stuff |
381 | */ | 360 | */ |
@@ -388,12 +367,6 @@ print_block_size(struct device *dev, struct device_attribute *attr, | |||
388 | 367 | ||
389 | static DEVICE_ATTR(block_size_bytes, 0444, print_block_size, NULL); | 368 | static DEVICE_ATTR(block_size_bytes, 0444, print_block_size, NULL); |
390 | 369 | ||
391 | static int block_size_init(void) | ||
392 | { | ||
393 | return device_create_file(memory_subsys.dev_root, | ||
394 | &dev_attr_block_size_bytes); | ||
395 | } | ||
396 | |||
397 | /* | 370 | /* |
398 | * Some architectures will have custom drivers to do this, and | 371 | * Some architectures will have custom drivers to do this, and |
399 | * will not need to do it from userspace. The fake hot-add code | 372 | * will not need to do it from userspace. The fake hot-add code |
@@ -429,17 +402,8 @@ memory_probe_store(struct device *dev, struct device_attribute *attr, | |||
429 | out: | 402 | out: |
430 | return ret; | 403 | return ret; |
431 | } | 404 | } |
432 | static DEVICE_ATTR(probe, S_IWUSR, NULL, memory_probe_store); | ||
433 | 405 | ||
434 | static int memory_probe_init(void) | 406 | static DEVICE_ATTR(probe, S_IWUSR, NULL, memory_probe_store); |
435 | { | ||
436 | return device_create_file(memory_subsys.dev_root, &dev_attr_probe); | ||
437 | } | ||
438 | #else | ||
439 | static inline int memory_probe_init(void) | ||
440 | { | ||
441 | return 0; | ||
442 | } | ||
443 | #endif | 407 | #endif |
444 | 408 | ||
445 | #ifdef CONFIG_MEMORY_FAILURE | 409 | #ifdef CONFIG_MEMORY_FAILURE |
@@ -485,23 +449,6 @@ store_hard_offline_page(struct device *dev, | |||
485 | 449 | ||
486 | static DEVICE_ATTR(soft_offline_page, S_IWUSR, NULL, store_soft_offline_page); | 450 | static DEVICE_ATTR(soft_offline_page, S_IWUSR, NULL, store_soft_offline_page); |
487 | static DEVICE_ATTR(hard_offline_page, S_IWUSR, NULL, store_hard_offline_page); | 451 | static DEVICE_ATTR(hard_offline_page, S_IWUSR, NULL, store_hard_offline_page); |
488 | |||
489 | static __init int memory_fail_init(void) | ||
490 | { | ||
491 | int err; | ||
492 | |||
493 | err = device_create_file(memory_subsys.dev_root, | ||
494 | &dev_attr_soft_offline_page); | ||
495 | if (!err) | ||
496 | err = device_create_file(memory_subsys.dev_root, | ||
497 | &dev_attr_hard_offline_page); | ||
498 | return err; | ||
499 | } | ||
500 | #else | ||
501 | static inline int memory_fail_init(void) | ||
502 | { | ||
503 | return 0; | ||
504 | } | ||
505 | #endif | 452 | #endif |
506 | 453 | ||
507 | /* | 454 | /* |
@@ -546,6 +493,41 @@ struct memory_block *find_memory_block(struct mem_section *section) | |||
546 | return find_memory_block_hinted(section, NULL); | 493 | return find_memory_block_hinted(section, NULL); |
547 | } | 494 | } |
548 | 495 | ||
496 | static struct attribute *memory_memblk_attrs[] = { | ||
497 | &dev_attr_phys_index.attr, | ||
498 | &dev_attr_end_phys_index.attr, | ||
499 | &dev_attr_state.attr, | ||
500 | &dev_attr_phys_device.attr, | ||
501 | &dev_attr_removable.attr, | ||
502 | NULL | ||
503 | }; | ||
504 | |||
505 | static struct attribute_group memory_memblk_attr_group = { | ||
506 | .attrs = memory_memblk_attrs, | ||
507 | }; | ||
508 | |||
509 | static const struct attribute_group *memory_memblk_attr_groups[] = { | ||
510 | &memory_memblk_attr_group, | ||
511 | NULL, | ||
512 | }; | ||
513 | |||
514 | /* | ||
515 | * register_memory - Setup a sysfs device for a memory block | ||
516 | */ | ||
517 | static | ||
518 | int register_memory(struct memory_block *memory) | ||
519 | { | ||
520 | int error; | ||
521 | |||
522 | memory->dev.bus = &memory_subsys; | ||
523 | memory->dev.id = memory->start_section_nr / sections_per_block; | ||
524 | memory->dev.release = memory_block_release; | ||
525 | memory->dev.groups = memory_memblk_attr_groups; | ||
526 | |||
527 | error = device_register(&memory->dev); | ||
528 | return error; | ||
529 | } | ||
530 | |||
549 | static int init_memory_block(struct memory_block **memory, | 531 | static int init_memory_block(struct memory_block **memory, |
550 | struct mem_section *section, unsigned long state) | 532 | struct mem_section *section, unsigned long state) |
551 | { | 533 | { |
@@ -569,16 +551,6 @@ static int init_memory_block(struct memory_block **memory, | |||
569 | mem->phys_device = arch_get_memory_phys_device(start_pfn); | 551 | mem->phys_device = arch_get_memory_phys_device(start_pfn); |
570 | 552 | ||
571 | ret = register_memory(mem); | 553 | ret = register_memory(mem); |
572 | if (!ret) | ||
573 | ret = mem_create_simple_file(mem, phys_index); | ||
574 | if (!ret) | ||
575 | ret = mem_create_simple_file(mem, end_phys_index); | ||
576 | if (!ret) | ||
577 | ret = mem_create_simple_file(mem, state); | ||
578 | if (!ret) | ||
579 | ret = mem_create_simple_file(mem, phys_device); | ||
580 | if (!ret) | ||
581 | ret = mem_create_simple_file(mem, removable); | ||
582 | 554 | ||
583 | *memory = mem; | 555 | *memory = mem; |
584 | return ret; | 556 | return ret; |
@@ -656,14 +628,9 @@ static int remove_memory_block(unsigned long node_id, | |||
656 | unregister_mem_sect_under_nodes(mem, __section_nr(section)); | 628 | unregister_mem_sect_under_nodes(mem, __section_nr(section)); |
657 | 629 | ||
658 | mem->section_count--; | 630 | mem->section_count--; |
659 | if (mem->section_count == 0) { | 631 | if (mem->section_count == 0) |
660 | mem_remove_simple_file(mem, phys_index); | ||
661 | mem_remove_simple_file(mem, end_phys_index); | ||
662 | mem_remove_simple_file(mem, state); | ||
663 | mem_remove_simple_file(mem, phys_device); | ||
664 | mem_remove_simple_file(mem, removable); | ||
665 | unregister_memory(mem); | 632 | unregister_memory(mem); |
666 | } else | 633 | else |
667 | kobject_put(&mem->dev.kobj); | 634 | kobject_put(&mem->dev.kobj); |
668 | 635 | ||
669 | mutex_unlock(&mem_sysfs_mutex); | 636 | mutex_unlock(&mem_sysfs_mutex); |
@@ -700,6 +667,29 @@ bool is_memblock_offlined(struct memory_block *mem) | |||
700 | return mem->state == MEM_OFFLINE; | 667 | return mem->state == MEM_OFFLINE; |
701 | } | 668 | } |
702 | 669 | ||
670 | static struct attribute *memory_root_attrs[] = { | ||
671 | #ifdef CONFIG_ARCH_MEMORY_PROBE | ||
672 | &dev_attr_probe.attr, | ||
673 | #endif | ||
674 | |||
675 | #ifdef CONFIG_MEMORY_FAILURE | ||
676 | &dev_attr_soft_offline_page.attr, | ||
677 | &dev_attr_hard_offline_page.attr, | ||
678 | #endif | ||
679 | |||
680 | &dev_attr_block_size_bytes.attr, | ||
681 | NULL | ||
682 | }; | ||
683 | |||
684 | static struct attribute_group memory_root_attr_group = { | ||
685 | .attrs = memory_root_attrs, | ||
686 | }; | ||
687 | |||
688 | static const struct attribute_group *memory_root_attr_groups[] = { | ||
689 | &memory_root_attr_group, | ||
690 | NULL, | ||
691 | }; | ||
692 | |||
703 | /* | 693 | /* |
704 | * Initialize the sysfs support for memory devices... | 694 | * Initialize the sysfs support for memory devices... |
705 | */ | 695 | */ |
@@ -711,7 +701,7 @@ int __init memory_dev_init(void) | |||
711 | unsigned long block_sz; | 701 | unsigned long block_sz; |
712 | struct memory_block *mem = NULL; | 702 | struct memory_block *mem = NULL; |
713 | 703 | ||
714 | ret = subsys_system_register(&memory_subsys, NULL); | 704 | ret = subsys_system_register(&memory_subsys, memory_root_attr_groups); |
715 | if (ret) | 705 | if (ret) |
716 | goto out; | 706 | goto out; |
717 | 707 | ||
@@ -734,15 +724,6 @@ int __init memory_dev_init(void) | |||
734 | ret = err; | 724 | ret = err; |
735 | } | 725 | } |
736 | 726 | ||
737 | err = memory_probe_init(); | ||
738 | if (!ret) | ||
739 | ret = err; | ||
740 | err = memory_fail_init(); | ||
741 | if (!ret) | ||
742 | ret = err; | ||
743 | err = block_size_init(); | ||
744 | if (!ret) | ||
745 | ret = err; | ||
746 | out: | 727 | out: |
747 | if (ret) | 728 | if (ret) |
748 | printk(KERN_ERR "%s() failed: %d\n", __func__, ret); | 729 | printk(KERN_ERR "%s() failed: %d\n", __func__, ret); |