aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/platforms/ps3/device-init.c85
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c5
-rw-r--r--include/asm-powerpc/ps3.h8
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
34static 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
109fail_register:
110fail_rights:
111fail_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
333enum ps3_system_bus_device_type { 335enum 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;