diff options
-rw-r--r-- | arch/powerpc/platforms/ps3/device-init.c | 85 | ||||
-rw-r--r-- | arch/powerpc/platforms/ps3/system-bus.c | 5 | ||||
-rw-r--r-- | include/asm-powerpc/ps3.h | 8 |
3 files changed, 98 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c index 05c7c1c624dc..9d251d0ca8c6 100644 --- a/arch/powerpc/platforms/ps3/device-init.c +++ b/arch/powerpc/platforms/ps3/device-init.c | |||
@@ -31,6 +31,89 @@ | |||
31 | 31 | ||
32 | #include "platform.h" | 32 | #include "platform.h" |
33 | 33 | ||
34 | static int __init ps3_register_lpm_devices(void) | ||
35 | { | ||
36 | int result; | ||
37 | u64 tmp1; | ||
38 | u64 tmp2; | ||
39 | struct ps3_system_bus_device *dev; | ||
40 | |||
41 | pr_debug(" -> %s:%d\n", __func__, __LINE__); | ||
42 | |||
43 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
44 | if (!dev) | ||
45 | return -ENOMEM; | ||
46 | |||
47 | dev->match_id = PS3_MATCH_ID_LPM; | ||
48 | dev->dev_type = PS3_DEVICE_TYPE_LPM; | ||
49 | |||
50 | /* The current lpm driver only supports a single BE processor. */ | ||
51 | |||
52 | result = ps3_repository_read_be_node_id(0, &dev->lpm.node_id); | ||
53 | |||
54 | if (result) { | ||
55 | pr_debug("%s:%d: ps3_repository_read_be_node_id failed \n", | ||
56 | __func__, __LINE__); | ||
57 | goto fail_read_repo; | ||
58 | } | ||
59 | |||
60 | result = ps3_repository_read_lpm_privileges(dev->lpm.node_id, &tmp1, | ||
61 | &dev->lpm.rights); | ||
62 | |||
63 | if (result) { | ||
64 | pr_debug("%s:%d: ps3_repository_read_lpm_privleges failed \n", | ||
65 | __func__, __LINE__); | ||
66 | goto fail_read_repo; | ||
67 | } | ||
68 | |||
69 | lv1_get_logical_partition_id(&tmp2); | ||
70 | |||
71 | if (tmp1 != tmp2) { | ||
72 | pr_debug("%s:%d: wrong lpar\n", | ||
73 | __func__, __LINE__); | ||
74 | result = -ENODEV; | ||
75 | goto fail_rights; | ||
76 | } | ||
77 | |||
78 | if (!(dev->lpm.rights & PS3_LPM_RIGHTS_USE_LPM)) { | ||
79 | pr_debug("%s:%d: don't have rights to use lpm\n", | ||
80 | __func__, __LINE__); | ||
81 | result = -EPERM; | ||
82 | goto fail_rights; | ||
83 | } | ||
84 | |||
85 | pr_debug("%s:%d: pu_id %lu, rights %lu(%lxh)\n", | ||
86 | __func__, __LINE__, dev->lpm.pu_id, dev->lpm.rights, | ||
87 | dev->lpm.rights); | ||
88 | |||
89 | result = ps3_repository_read_pu_id(0, &dev->lpm.pu_id); | ||
90 | |||
91 | if (result) { | ||
92 | pr_debug("%s:%d: ps3_repository_read_pu_id failed \n", | ||
93 | __func__, __LINE__); | ||
94 | goto fail_read_repo; | ||
95 | } | ||
96 | |||
97 | result = ps3_system_bus_device_register(dev); | ||
98 | |||
99 | if (result) { | ||
100 | pr_debug("%s:%d ps3_system_bus_device_register failed\n", | ||
101 | __func__, __LINE__); | ||
102 | goto fail_register; | ||
103 | } | ||
104 | |||
105 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | ||
106 | return 0; | ||
107 | |||
108 | |||
109 | fail_register: | ||
110 | fail_rights: | ||
111 | fail_read_repo: | ||
112 | kfree(dev); | ||
113 | pr_debug(" <- %s:%d: failed\n", __func__, __LINE__); | ||
114 | return result; | ||
115 | } | ||
116 | |||
34 | /** | 117 | /** |
35 | * ps3_setup_gelic_device - Setup and register a gelic device instance. | 118 | * ps3_setup_gelic_device - Setup and register a gelic device instance. |
36 | * | 119 | * |
@@ -827,6 +910,8 @@ static int __init ps3_register_devices(void) | |||
827 | 910 | ||
828 | ps3_register_sound_devices(); | 911 | ps3_register_sound_devices(); |
829 | 912 | ||
913 | ps3_register_lpm_devices(); | ||
914 | |||
830 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 915 | pr_debug(" <- %s:%d\n", __func__, __LINE__); |
831 | return 0; | 916 | return 0; |
832 | } | 917 | } |
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index 872d68892ab1..43c493fca2d0 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c | |||
@@ -715,6 +715,7 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev) | |||
715 | static unsigned int dev_ioc0_count; | 715 | static unsigned int dev_ioc0_count; |
716 | static unsigned int dev_sb_count; | 716 | static unsigned int dev_sb_count; |
717 | static unsigned int dev_vuart_count; | 717 | static unsigned int dev_vuart_count; |
718 | static unsigned int dev_lpm_count; | ||
718 | 719 | ||
719 | if (!dev->core.parent) | 720 | if (!dev->core.parent) |
720 | dev->core.parent = &ps3_system_bus; | 721 | dev->core.parent = &ps3_system_bus; |
@@ -737,6 +738,10 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev) | |||
737 | snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), | 738 | snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), |
738 | "vuart_%02x", ++dev_vuart_count); | 739 | "vuart_%02x", ++dev_vuart_count); |
739 | break; | 740 | break; |
741 | case PS3_DEVICE_TYPE_LPM: | ||
742 | snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), | ||
743 | "lpm_%02x", ++dev_lpm_count); | ||
744 | break; | ||
740 | default: | 745 | default: |
741 | BUG(); | 746 | BUG(); |
742 | }; | 747 | }; |
diff --git a/include/asm-powerpc/ps3.h b/include/asm-powerpc/ps3.h index 4ff07dbe8169..001121b3eb1b 100644 --- a/include/asm-powerpc/ps3.h +++ b/include/asm-powerpc/ps3.h | |||
@@ -317,6 +317,7 @@ enum ps3_match_id { | |||
317 | PS3_MATCH_ID_STOR_FLASH = 8, | 317 | PS3_MATCH_ID_STOR_FLASH = 8, |
318 | PS3_MATCH_ID_SOUND = 9, | 318 | PS3_MATCH_ID_SOUND = 9, |
319 | PS3_MATCH_ID_GRAPHICS = 10, | 319 | PS3_MATCH_ID_GRAPHICS = 10, |
320 | PS3_MATCH_ID_LPM = 11, | ||
320 | }; | 321 | }; |
321 | 322 | ||
322 | #define PS3_MODULE_ALIAS_EHCI "ps3:1" | 323 | #define PS3_MODULE_ALIAS_EHCI "ps3:1" |
@@ -329,11 +330,13 @@ enum ps3_match_id { | |||
329 | #define PS3_MODULE_ALIAS_STOR_FLASH "ps3:8" | 330 | #define PS3_MODULE_ALIAS_STOR_FLASH "ps3:8" |
330 | #define PS3_MODULE_ALIAS_SOUND "ps3:9" | 331 | #define PS3_MODULE_ALIAS_SOUND "ps3:9" |
331 | #define PS3_MODULE_ALIAS_GRAPHICS "ps3:10" | 332 | #define PS3_MODULE_ALIAS_GRAPHICS "ps3:10" |
333 | #define PS3_MODULE_ALIAS_LPM "ps3:11" | ||
332 | 334 | ||
333 | enum ps3_system_bus_device_type { | 335 | enum ps3_system_bus_device_type { |
334 | PS3_DEVICE_TYPE_IOC0 = 1, | 336 | PS3_DEVICE_TYPE_IOC0 = 1, |
335 | PS3_DEVICE_TYPE_SB, | 337 | PS3_DEVICE_TYPE_SB, |
336 | PS3_DEVICE_TYPE_VUART, | 338 | PS3_DEVICE_TYPE_VUART, |
339 | PS3_DEVICE_TYPE_LPM, | ||
337 | }; | 340 | }; |
338 | 341 | ||
339 | /** | 342 | /** |
@@ -350,6 +353,11 @@ struct ps3_system_bus_device { | |||
350 | struct ps3_dma_region *d_region; /* SB, IOC0 */ | 353 | struct ps3_dma_region *d_region; /* SB, IOC0 */ |
351 | struct ps3_mmio_region *m_region; /* SB, IOC0*/ | 354 | struct ps3_mmio_region *m_region; /* SB, IOC0*/ |
352 | unsigned int port_number; /* VUART */ | 355 | unsigned int port_number; /* VUART */ |
356 | struct { /* LPM */ | ||
357 | u64 node_id; | ||
358 | u64 pu_id; | ||
359 | u64 rights; | ||
360 | } lpm; | ||
353 | 361 | ||
354 | /* struct iommu_table *iommu_table; -- waiting for BenH's cleanups */ | 362 | /* struct iommu_table *iommu_table; -- waiting for BenH's cleanups */ |
355 | struct device core; | 363 | struct device core; |