diff options
Diffstat (limited to 'arch/powerpc/platforms/cell/cbe_regs.c')
-rw-r--r-- | arch/powerpc/platforms/cell/cbe_regs.c | 71 |
1 files changed, 69 insertions, 2 deletions
diff --git a/arch/powerpc/platforms/cell/cbe_regs.c b/arch/powerpc/platforms/cell/cbe_regs.c index 2f194ba29899..9a0ee62691d5 100644 --- a/arch/powerpc/platforms/cell/cbe_regs.c +++ b/arch/powerpc/platforms/cell/cbe_regs.c | |||
@@ -8,6 +8,7 @@ | |||
8 | 8 | ||
9 | #include <linux/percpu.h> | 9 | #include <linux/percpu.h> |
10 | #include <linux/types.h> | 10 | #include <linux/types.h> |
11 | #include <linux/module.h> | ||
11 | 12 | ||
12 | #include <asm/io.h> | 13 | #include <asm/io.h> |
13 | #include <asm/pgtable.h> | 14 | #include <asm/pgtable.h> |
@@ -16,8 +17,6 @@ | |||
16 | 17 | ||
17 | #include "cbe_regs.h" | 18 | #include "cbe_regs.h" |
18 | 19 | ||
19 | #define MAX_CBE 2 | ||
20 | |||
21 | /* | 20 | /* |
22 | * Current implementation uses "cpu" nodes. We build our own mapping | 21 | * Current implementation uses "cpu" nodes. We build our own mapping |
23 | * array of cpu numbers to cpu nodes locally for now to allow interrupt | 22 | * array of cpu numbers to cpu nodes locally for now to allow interrupt |
@@ -30,6 +29,8 @@ static struct cbe_regs_map | |||
30 | struct device_node *cpu_node; | 29 | struct device_node *cpu_node; |
31 | struct cbe_pmd_regs __iomem *pmd_regs; | 30 | struct cbe_pmd_regs __iomem *pmd_regs; |
32 | struct cbe_iic_regs __iomem *iic_regs; | 31 | struct cbe_iic_regs __iomem *iic_regs; |
32 | struct cbe_mic_tm_regs __iomem *mic_tm_regs; | ||
33 | struct cbe_pmd_shadow_regs pmd_shadow_regs; | ||
33 | } cbe_regs_maps[MAX_CBE]; | 34 | } cbe_regs_maps[MAX_CBE]; |
34 | static int cbe_regs_map_count; | 35 | static int cbe_regs_map_count; |
35 | 36 | ||
@@ -42,6 +43,19 @@ static struct cbe_thread_map | |||
42 | static struct cbe_regs_map *cbe_find_map(struct device_node *np) | 43 | static struct cbe_regs_map *cbe_find_map(struct device_node *np) |
43 | { | 44 | { |
44 | int i; | 45 | int i; |
46 | struct device_node *tmp_np; | ||
47 | |||
48 | if (strcasecmp(np->type, "spe") == 0) { | ||
49 | if (np->data == NULL) { | ||
50 | /* walk up path until cpu node was found */ | ||
51 | tmp_np = np->parent; | ||
52 | while (tmp_np != NULL && strcasecmp(tmp_np->type, "cpu") != 0) | ||
53 | tmp_np = tmp_np->parent; | ||
54 | |||
55 | np->data = cbe_find_map(tmp_np); | ||
56 | } | ||
57 | return np->data; | ||
58 | } | ||
45 | 59 | ||
46 | for (i = 0; i < cbe_regs_map_count; i++) | 60 | for (i = 0; i < cbe_regs_map_count; i++) |
47 | if (cbe_regs_maps[i].cpu_node == np) | 61 | if (cbe_regs_maps[i].cpu_node == np) |
@@ -56,6 +70,7 @@ struct cbe_pmd_regs __iomem *cbe_get_pmd_regs(struct device_node *np) | |||
56 | return NULL; | 70 | return NULL; |
57 | return map->pmd_regs; | 71 | return map->pmd_regs; |
58 | } | 72 | } |
73 | EXPORT_SYMBOL_GPL(cbe_get_pmd_regs); | ||
59 | 74 | ||
60 | struct cbe_pmd_regs __iomem *cbe_get_cpu_pmd_regs(int cpu) | 75 | struct cbe_pmd_regs __iomem *cbe_get_cpu_pmd_regs(int cpu) |
61 | { | 76 | { |
@@ -64,7 +79,23 @@ struct cbe_pmd_regs __iomem *cbe_get_cpu_pmd_regs(int cpu) | |||
64 | return NULL; | 79 | return NULL; |
65 | return map->pmd_regs; | 80 | return map->pmd_regs; |
66 | } | 81 | } |
82 | EXPORT_SYMBOL_GPL(cbe_get_cpu_pmd_regs); | ||
67 | 83 | ||
84 | struct cbe_pmd_shadow_regs *cbe_get_pmd_shadow_regs(struct device_node *np) | ||
85 | { | ||
86 | struct cbe_regs_map *map = cbe_find_map(np); | ||
87 | if (map == NULL) | ||
88 | return NULL; | ||
89 | return &map->pmd_shadow_regs; | ||
90 | } | ||
91 | |||
92 | struct cbe_pmd_shadow_regs *cbe_get_cpu_pmd_shadow_regs(int cpu) | ||
93 | { | ||
94 | struct cbe_regs_map *map = cbe_thread_map[cpu].regs; | ||
95 | if (map == NULL) | ||
96 | return NULL; | ||
97 | return &map->pmd_shadow_regs; | ||
98 | } | ||
68 | 99 | ||
69 | struct cbe_iic_regs __iomem *cbe_get_iic_regs(struct device_node *np) | 100 | struct cbe_iic_regs __iomem *cbe_get_iic_regs(struct device_node *np) |
70 | { | 101 | { |
@@ -73,6 +104,7 @@ struct cbe_iic_regs __iomem *cbe_get_iic_regs(struct device_node *np) | |||
73 | return NULL; | 104 | return NULL; |
74 | return map->iic_regs; | 105 | return map->iic_regs; |
75 | } | 106 | } |
107 | |||
76 | struct cbe_iic_regs __iomem *cbe_get_cpu_iic_regs(int cpu) | 108 | struct cbe_iic_regs __iomem *cbe_get_cpu_iic_regs(int cpu) |
77 | { | 109 | { |
78 | struct cbe_regs_map *map = cbe_thread_map[cpu].regs; | 110 | struct cbe_regs_map *map = cbe_thread_map[cpu].regs; |
@@ -81,6 +113,36 @@ struct cbe_iic_regs __iomem *cbe_get_cpu_iic_regs(int cpu) | |||
81 | return map->iic_regs; | 113 | return map->iic_regs; |
82 | } | 114 | } |
83 | 115 | ||
116 | struct cbe_mic_tm_regs __iomem *cbe_get_mic_tm_regs(struct device_node *np) | ||
117 | { | ||
118 | struct cbe_regs_map *map = cbe_find_map(np); | ||
119 | if (map == NULL) | ||
120 | return NULL; | ||
121 | return map->mic_tm_regs; | ||
122 | } | ||
123 | |||
124 | struct cbe_mic_tm_regs __iomem *cbe_get_cpu_mic_tm_regs(int cpu) | ||
125 | { | ||
126 | struct cbe_regs_map *map = cbe_thread_map[cpu].regs; | ||
127 | if (map == NULL) | ||
128 | return NULL; | ||
129 | return map->mic_tm_regs; | ||
130 | } | ||
131 | EXPORT_SYMBOL_GPL(cbe_get_cpu_mic_tm_regs); | ||
132 | |||
133 | /* FIXME | ||
134 | * This is little more than a stub at the moment. It should be | ||
135 | * fleshed out so that it works for both SMT and non-SMT, no | ||
136 | * matter if the passed cpu is odd or even. | ||
137 | * For SMT enabled, returns 0 for even-numbered cpu; otherwise 1. | ||
138 | * For SMT disabled, returns 0 for all cpus. | ||
139 | */ | ||
140 | u32 cbe_get_hw_thread_id(int cpu) | ||
141 | { | ||
142 | return (cpu & 1); | ||
143 | } | ||
144 | EXPORT_SYMBOL_GPL(cbe_get_hw_thread_id); | ||
145 | |||
84 | void __init cbe_regs_init(void) | 146 | void __init cbe_regs_init(void) |
85 | { | 147 | { |
86 | int i; | 148 | int i; |
@@ -119,6 +181,11 @@ void __init cbe_regs_init(void) | |||
119 | prop = get_property(cpu, "iic", NULL); | 181 | prop = get_property(cpu, "iic", NULL); |
120 | if (prop != NULL) | 182 | if (prop != NULL) |
121 | map->iic_regs = ioremap(prop->address, prop->len); | 183 | map->iic_regs = ioremap(prop->address, prop->len); |
184 | |||
185 | prop = (struct address_prop *)get_property(cpu, "mic-tm", | ||
186 | NULL); | ||
187 | if (prop != NULL) | ||
188 | map->mic_tm_regs = ioremap(prop->address, prop->len); | ||
122 | } | 189 | } |
123 | } | 190 | } |
124 | 191 | ||