diff options
| author | Jeremy Kerr <jk@ozlabs.org> | 2006-06-19 14:33:19 -0400 |
|---|---|---|
| committer | Paul Mackerras <paulus@samba.org> | 2006-06-21 01:01:29 -0400 |
| commit | 1d64093f6627a7eef1ed0fe005463f0a5ea25a5f (patch) | |
| tree | faa57ae7e34dd45b843161c233a59a15fe6ddaf1 /arch/powerpc | |
| parent | 0f0f90c304b42d8ce7fc5958de894bdcff3a0ca1 (diff) | |
[POWERPC] cell: register SPUs as sysdevs
SPUs are registered as system devices, exposing attributes through
sysfs. Since the sysdev includes a kref, we can remove the one in
struct spu (it isn't used at the moment anyway).
Currently only the interrupt source and numa node attributes are added.
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc')
| -rw-r--r-- | arch/powerpc/platforms/cell/spu_base.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index ad141fe8d52d..d5877aacc3b6 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c | |||
| @@ -649,6 +649,46 @@ out: | |||
| 649 | return ret; | 649 | return ret; |
| 650 | } | 650 | } |
| 651 | 651 | ||
| 652 | struct sysdev_class spu_sysdev_class = { | ||
| 653 | set_kset_name("spu") | ||
| 654 | }; | ||
| 655 | |||
| 656 | static ssize_t spu_show_isrc(struct sys_device *sysdev, char *buf) | ||
| 657 | { | ||
| 658 | struct spu *spu = container_of(sysdev, struct spu, sysdev); | ||
| 659 | return sprintf(buf, "%d\n", spu->isrc); | ||
| 660 | |||
| 661 | } | ||
| 662 | static SYSDEV_ATTR(isrc, 0400, spu_show_isrc, NULL); | ||
| 663 | |||
| 664 | extern int attach_sysdev_to_node(struct sys_device *dev, int nid); | ||
| 665 | |||
| 666 | static int spu_create_sysdev(struct spu *spu) | ||
| 667 | { | ||
| 668 | int ret; | ||
| 669 | |||
| 670 | spu->sysdev.id = spu->number; | ||
| 671 | spu->sysdev.cls = &spu_sysdev_class; | ||
| 672 | ret = sysdev_register(&spu->sysdev); | ||
| 673 | if (ret) { | ||
| 674 | printk(KERN_ERR "Can't register SPU %d with sysfs\n", | ||
| 675 | spu->number); | ||
| 676 | return ret; | ||
| 677 | } | ||
| 678 | |||
| 679 | sysdev_create_file(&spu->sysdev, &attr_isrc); | ||
| 680 | sysfs_add_device_to_node(&spu->sysdev, spu->nid); | ||
| 681 | |||
| 682 | return 0; | ||
| 683 | } | ||
| 684 | |||
| 685 | static void spu_destroy_sysdev(struct spu *spu) | ||
| 686 | { | ||
| 687 | sysdev_remove_file(&spu->sysdev, &attr_isrc); | ||
| 688 | sysfs_remove_device_from_node(&spu->sysdev, spu->nid); | ||
| 689 | sysdev_unregister(&spu->sysdev); | ||
| 690 | } | ||
| 691 | |||
| 652 | static int __init create_spu(struct device_node *spe) | 692 | static int __init create_spu(struct device_node *spe) |
| 653 | { | 693 | { |
| 654 | struct spu *spu; | 694 | struct spu *spu; |
| @@ -695,6 +735,10 @@ static int __init create_spu(struct device_node *spe) | |||
| 695 | if (ret) | 735 | if (ret) |
| 696 | goto out_unmap; | 736 | goto out_unmap; |
| 697 | 737 | ||
| 738 | ret = spu_create_sysdev(spu); | ||
| 739 | if (ret) | ||
| 740 | goto out_free_irqs; | ||
| 741 | |||
| 698 | list_add(&spu->list, &spu_list); | 742 | list_add(&spu->list, &spu_list); |
| 699 | mutex_unlock(&spu_mutex); | 743 | mutex_unlock(&spu_mutex); |
| 700 | 744 | ||
| @@ -703,6 +747,9 @@ static int __init create_spu(struct device_node *spe) | |||
| 703 | spu->problem, spu->priv1, spu->priv2, spu->number); | 747 | spu->problem, spu->priv1, spu->priv2, spu->number); |
| 704 | goto out; | 748 | goto out; |
| 705 | 749 | ||
| 750 | out_free_irqs: | ||
| 751 | spu_free_irqs(spu); | ||
| 752 | |||
| 706 | out_unmap: | 753 | out_unmap: |
| 707 | mutex_unlock(&spu_mutex); | 754 | mutex_unlock(&spu_mutex); |
| 708 | spu_unmap(spu); | 755 | spu_unmap(spu); |
| @@ -716,6 +763,7 @@ static void destroy_spu(struct spu *spu) | |||
| 716 | { | 763 | { |
| 717 | list_del_init(&spu->list); | 764 | list_del_init(&spu->list); |
| 718 | 765 | ||
| 766 | spu_destroy_sysdev(spu); | ||
| 719 | spu_free_irqs(spu); | 767 | spu_free_irqs(spu); |
| 720 | spu_unmap(spu); | 768 | spu_unmap(spu); |
| 721 | kfree(spu); | 769 | kfree(spu); |
| @@ -728,6 +776,7 @@ static void cleanup_spu_base(void) | |||
| 728 | list_for_each_entry_safe(spu, tmp, &spu_list, list) | 776 | list_for_each_entry_safe(spu, tmp, &spu_list, list) |
| 729 | destroy_spu(spu); | 777 | destroy_spu(spu); |
| 730 | mutex_unlock(&spu_mutex); | 778 | mutex_unlock(&spu_mutex); |
| 779 | sysdev_class_unregister(&spu_sysdev_class); | ||
| 731 | } | 780 | } |
| 732 | module_exit(cleanup_spu_base); | 781 | module_exit(cleanup_spu_base); |
| 733 | 782 | ||
| @@ -736,6 +785,11 @@ static int __init init_spu_base(void) | |||
| 736 | struct device_node *node; | 785 | struct device_node *node; |
| 737 | int ret; | 786 | int ret; |
| 738 | 787 | ||
| 788 | /* create sysdev class for spus */ | ||
| 789 | ret = sysdev_class_register(&spu_sysdev_class); | ||
| 790 | if (ret) | ||
| 791 | return ret; | ||
| 792 | |||
| 739 | ret = -ENODEV; | 793 | ret = -ENODEV; |
| 740 | for (node = of_find_node_by_type(NULL, "spe"); | 794 | for (node = of_find_node_by_type(NULL, "spe"); |
| 741 | node; node = of_find_node_by_type(node, "spe")) { | 795 | node; node = of_find_node_by_type(node, "spe")) { |
