aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-06-22 22:53:24 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-06-24 02:15:32 -0400
commitcecc4e9222c4e2bca59834750e493eea6be97613 (patch)
tree9fd177ac904e4ef091c0322ae9f105210d42916d
parent9c10a58ed634d98114c5717e2da761d8a63f2cd4 (diff)
[SPARC64]: Convert central bus layer to in-kernel PROM device tree.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/sparc64/kernel/central.c127
-rw-r--r--arch/sparc64/kernel/time.c22
-rw-r--r--drivers/serial/sunzilog.c2
-rw-r--r--include/asm-sparc64/fhc.h7
4 files changed, 78 insertions, 80 deletions
diff --git a/arch/sparc64/kernel/central.c b/arch/sparc64/kernel/central.c
index 3d184a784968..b66336db00ee 100644
--- a/arch/sparc64/kernel/central.c
+++ b/arch/sparc64/kernel/central.c
@@ -29,28 +29,34 @@ static void central_probe_failure(int line)
29 prom_halt(); 29 prom_halt();
30} 30}
31 31
32static void central_ranges_init(int cnode, struct linux_central *central) 32static void central_ranges_init(struct linux_central *central)
33{ 33{
34 int success; 34 struct device_node *dp = central->prom_node;
35 void *pval;
36 int len;
35 37
36 central->num_central_ranges = 0; 38 central->num_central_ranges = 0;
37 success = prom_getproperty(central->prom_node, "ranges", 39 pval = of_get_property(dp, "ranges", &len);
38 (char *) central->central_ranges, 40 if (pval) {
39 sizeof (central->central_ranges)); 41 memcpy(central->central_ranges, pval, len);
40 if (success != -1) 42 central->num_central_ranges =
41 central->num_central_ranges = (success/sizeof(struct linux_prom_ranges)); 43 (len / sizeof(struct linux_prom_ranges));
44 }
42} 45}
43 46
44static void fhc_ranges_init(int fnode, struct linux_fhc *fhc) 47static void fhc_ranges_init(struct linux_fhc *fhc)
45{ 48{
46 int success; 49 struct device_node *dp = fhc->prom_node;
50 void *pval;
51 int len;
47 52
48 fhc->num_fhc_ranges = 0; 53 fhc->num_fhc_ranges = 0;
49 success = prom_getproperty(fhc->prom_node, "ranges", 54 pval = of_get_property(dp, "ranges", &len);
50 (char *) fhc->fhc_ranges, 55 if (pval) {
51 sizeof (fhc->fhc_ranges)); 56 memcpy(fhc->fhc_ranges, pval, len);
52 if (success != -1) 57 fhc->num_fhc_ranges =
53 fhc->num_fhc_ranges = (success/sizeof(struct linux_prom_ranges)); 58 (len / sizeof(struct linux_prom_ranges));
59 }
54} 60}
55 61
56/* Range application routines are exported to various drivers, 62/* Range application routines are exported to various drivers,
@@ -112,15 +118,10 @@ static unsigned long prom_reg_to_paddr(struct linux_prom_registers *r)
112 118
113static void probe_other_fhcs(void) 119static void probe_other_fhcs(void)
114{ 120{
115 struct linux_prom64_registers fpregs[6]; 121 struct device_node *dp;
116 char namebuf[128]; 122 struct linux_prom64_registers *fpregs;
117 int node;
118 123
119 node = prom_getchild(prom_root_node); 124 for_each_node_by_name(dp, "fhc") {
120 node = prom_searchsiblings(node, "fhc");
121 if (node == 0)
122 central_probe_failure(__LINE__);
123 while (node) {
124 struct linux_fhc *fhc; 125 struct linux_fhc *fhc;
125 int board; 126 int board;
126 u32 tmp; 127 u32 tmp;
@@ -137,14 +138,12 @@ static void probe_other_fhcs(void)
137 /* Toplevel FHCs have no parent. */ 138 /* Toplevel FHCs have no parent. */
138 fhc->parent = NULL; 139 fhc->parent = NULL;
139 140
140 fhc->prom_node = node; 141 fhc->prom_node = dp;
141 prom_getstring(node, "name", namebuf, sizeof(namebuf)); 142 fhc_ranges_init(fhc);
142 strcpy(fhc->prom_name, namebuf);
143 fhc_ranges_init(node, fhc);
144 143
145 /* Non-central FHC's have 64-bit OBP format registers. */ 144 /* Non-central FHC's have 64-bit OBP format registers. */
146 if (prom_getproperty(node, "reg", 145 fpregs = of_get_property(dp, "reg", NULL);
147 (char *)&fpregs[0], sizeof(fpregs)) == -1) 146 if (!fpregs)
148 central_probe_failure(__LINE__); 147 central_probe_failure(__LINE__);
149 148
150 /* Only central FHC needs special ranges applied. */ 149 /* Only central FHC needs special ranges applied. */
@@ -155,7 +154,7 @@ static void probe_other_fhcs(void)
155 fhc->fhc_regs.uregs = fpregs[4].phys_addr; 154 fhc->fhc_regs.uregs = fpregs[4].phys_addr;
156 fhc->fhc_regs.tregs = fpregs[5].phys_addr; 155 fhc->fhc_regs.tregs = fpregs[5].phys_addr;
157 156
158 board = prom_getintdefault(node, "board#", -1); 157 board = of_getintprop_default(dp, "board#", -1);
159 fhc->board = board; 158 fhc->board = board;
160 159
161 tmp = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_JCTRL); 160 tmp = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_JCTRL);
@@ -179,33 +178,33 @@ static void probe_other_fhcs(void)
179 tmp = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_CTRL); 178 tmp = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_CTRL);
180 tmp |= FHC_CONTROL_IXIST; 179 tmp |= FHC_CONTROL_IXIST;
181 upa_writel(tmp, fhc->fhc_regs.pregs + FHC_PREGS_CTRL); 180 upa_writel(tmp, fhc->fhc_regs.pregs + FHC_PREGS_CTRL);
182
183 /* Look for the next FHC. */
184 node = prom_getsibling(node);
185 if (node == 0)
186 break;
187 node = prom_searchsiblings(node, "fhc");
188 if (node == 0)
189 break;
190 } 181 }
191} 182}
192 183
193static void probe_clock_board(struct linux_central *central, 184static void probe_clock_board(struct linux_central *central,
194 struct linux_fhc *fhc, 185 struct linux_fhc *fhc,
195 int cnode, int fnode) 186 struct device_node *fp)
196{ 187{
197 struct linux_prom_registers cregs[3]; 188 struct device_node *dp;
198 int clknode, nslots, tmp, nregs; 189 struct linux_prom_registers cregs[3], *pr;
190 int nslots, tmp, nregs;
199 191
200 clknode = prom_searchsiblings(prom_getchild(fnode), "clock-board"); 192 dp = fp->child;
201 if (clknode == 0 || clknode == -1) 193 while (dp) {
194 if (!strcmp(dp->name, "clock-board"))
195 break;
196 dp = dp->sibling;
197 }
198 if (!dp)
202 central_probe_failure(__LINE__); 199 central_probe_failure(__LINE__);
203 200
204 nregs = prom_getproperty(clknode, "reg", (char *)&cregs[0], sizeof(cregs)); 201 pr = of_get_property(dp, "reg", &nregs);
205 if (nregs == -1) 202 if (!pr)
206 central_probe_failure(__LINE__); 203 central_probe_failure(__LINE__);
207 204
205 memcpy(cregs, pr, nregs);
208 nregs /= sizeof(struct linux_prom_registers); 206 nregs /= sizeof(struct linux_prom_registers);
207
209 apply_fhc_ranges(fhc, &cregs[0], nregs); 208 apply_fhc_ranges(fhc, &cregs[0], nregs);
210 apply_central_ranges(central, &cregs[0], nregs); 209 apply_central_ranges(central, &cregs[0], nregs);
211 central->cfreg = prom_reg_to_paddr(&cregs[0]); 210 central->cfreg = prom_reg_to_paddr(&cregs[0]);
@@ -296,13 +295,13 @@ static void init_all_fhc_hw(void)
296 295
297void central_probe(void) 296void central_probe(void)
298{ 297{
299 struct linux_prom_registers fpregs[6]; 298 struct linux_prom_registers fpregs[6], *pr;
300 struct linux_fhc *fhc; 299 struct linux_fhc *fhc;
301 char namebuf[128]; 300 struct device_node *dp, *fp;
302 int cnode, fnode, err; 301 int err;
303 302
304 cnode = prom_finddevice("/central"); 303 dp = of_find_node_by_name(NULL, "central");
305 if (cnode == 0 || cnode == -1) { 304 if (!dp) {
306 if (this_is_starfire) 305 if (this_is_starfire)
307 starfire_cpu_setup(); 306 starfire_cpu_setup();
308 return; 307 return;
@@ -321,31 +320,31 @@ void central_probe(void)
321 320
322 /* First init central. */ 321 /* First init central. */
323 central_bus->child = fhc; 322 central_bus->child = fhc;
324 central_bus->prom_node = cnode; 323 central_bus->prom_node = dp;
325 324 central_ranges_init(central_bus);
326 prom_getstring(cnode, "name", namebuf, sizeof(namebuf));
327 strcpy(central_bus->prom_name, namebuf);
328
329 central_ranges_init(cnode, central_bus);
330 325
331 /* And then central's FHC. */ 326 /* And then central's FHC. */
332 fhc->next = fhc_list; 327 fhc->next = fhc_list;
333 fhc_list = fhc; 328 fhc_list = fhc;
334 329
335 fhc->parent = central_bus; 330 fhc->parent = central_bus;
336 fnode = prom_searchsiblings(prom_getchild(cnode), "fhc"); 331 fp = dp->child;
337 if (fnode == 0 || fnode == -1) 332 while (fp) {
333 if (!strcmp(fp->name, "fhc"))
334 break;
335 fp = fp->sibling;
336 }
337 if (!fp)
338 central_probe_failure(__LINE__); 338 central_probe_failure(__LINE__);
339 339
340 fhc->prom_node = fnode; 340 fhc->prom_node = fp;
341 prom_getstring(fnode, "name", namebuf, sizeof(namebuf)); 341 fhc_ranges_init(fhc);
342 strcpy(fhc->prom_name, namebuf);
343
344 fhc_ranges_init(fnode, fhc);
345 342
346 /* Now, map in FHC register set. */ 343 /* Now, map in FHC register set. */
347 if (prom_getproperty(fnode, "reg", (char *)&fpregs[0], sizeof(fpregs)) == -1) 344 pr = of_get_property(fp, "reg", NULL);
345 if (!pr)
348 central_probe_failure(__LINE__); 346 central_probe_failure(__LINE__);
347 memcpy(fpregs, pr, sizeof(fpregs));
349 348
350 apply_central_ranges(central_bus, &fpregs[0], 6); 349 apply_central_ranges(central_bus, &fpregs[0], 6);
351 350
@@ -366,7 +365,7 @@ void central_probe(void)
366 fhc->jtag_master = 0; 365 fhc->jtag_master = 0;
367 366
368 /* Attach the clock board registers for CENTRAL. */ 367 /* Attach the clock board registers for CENTRAL. */
369 probe_clock_board(central_bus, fhc, cnode, fnode); 368 probe_clock_board(central_bus, fhc, fp);
370 369
371 err = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_ID); 370 err = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_ID);
372 printk("FHC(board %d): Version[%x] PartID[%x] Manuf[%x] (CENTRAL)\n", 371 printk("FHC(board %d): Version[%x] PartID[%x] Manuf[%x] (CENTRAL)\n",
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index d072b8632ccd..348b82035561 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -796,26 +796,26 @@ static void __init clock_assign_clk_reg(struct linux_prom_registers *clk_reg,
796 796
797static int __init clock_probe_central(void) 797static int __init clock_probe_central(void)
798{ 798{
799 struct linux_prom_registers clk_reg[2]; 799 struct linux_prom_registers clk_reg[2], *pr;
800 char model[64]; 800 struct device_node *dp;
801 int node; 801 char *model;
802 802
803 if (!central_bus) 803 if (!central_bus)
804 return 0; 804 return 0;
805 805
806 /* Get Central FHC's prom node. */ 806 /* Get Central FHC's prom node. */
807 node = central_bus->child->prom_node; 807 dp = central_bus->child->prom_node;
808 808
809 /* Then get the first child device below it. */ 809 /* Then get the first child device below it. */
810 node = prom_getchild(node); 810 dp = dp->child;
811 811
812 while (node) { 812 while (dp) {
813 prom_getstring(node, "model", model, sizeof(model)); 813 model = of_get_property(dp, "model", NULL);
814 if (!clock_model_matches(model)) 814 if (!model || !clock_model_matches(model))
815 goto next_sibling; 815 goto next_sibling;
816 816
817 prom_getproperty(node, "reg", (char *)clk_reg, 817 pr = of_get_property(dp, "reg", NULL);
818 sizeof(clk_reg)); 818 memcpy(clk_reg, pr, sizeof(clk_reg));
819 819
820 apply_fhc_ranges(central_bus->child, clk_reg, 1); 820 apply_fhc_ranges(central_bus->child, clk_reg, 1);
821 apply_central_ranges(central_bus, clk_reg, 1); 821 apply_central_ranges(central_bus, clk_reg, 1);
@@ -824,7 +824,7 @@ static int __init clock_probe_central(void)
824 return 1; 824 return 1;
825 825
826 next_sibling: 826 next_sibling:
827 node = prom_getsibling(node); 827 dp = dp->sibling;
828 } 828 }
829 829
830 return 0; 830 return 0;
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 5b6569728a9c..76c9bac9271f 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -1106,7 +1106,7 @@ static struct zilog_layout __iomem * __init get_zs_sun4u(int chip, int zsnode)
1106 + FHC_UREGS_ICLR; 1106 + FHC_UREGS_ICLR;
1107 imap = central_bus->child->fhc_regs.uregs 1107 imap = central_bus->child->fhc_regs.uregs
1108 + FHC_UREGS_IMAP; 1108 + FHC_UREGS_IMAP;
1109 zilog_irq = build_irq(12, 0, iclr, imap); 1109 zilog_irq = build_irq(0, iclr, imap);
1110 } else { 1110 } else {
1111 err = prom_getproperty(zsnode, "interrupts", 1111 err = prom_getproperty(zsnode, "interrupts",
1112 (char *) &sun4u_ino, 1112 (char *) &sun4u_ino,
diff --git a/include/asm-sparc64/fhc.h b/include/asm-sparc64/fhc.h
index f29eaa254055..9e7f1b0d78b9 100644
--- a/include/asm-sparc64/fhc.h
+++ b/include/asm-sparc64/fhc.h
@@ -10,6 +10,7 @@
10#include <linux/timer.h> 10#include <linux/timer.h>
11 11
12#include <asm/oplib.h> 12#include <asm/oplib.h>
13#include <asm/prom.h>
13#include <asm/upa.h> 14#include <asm/upa.h>
14 15
15struct linux_fhc; 16struct linux_fhc;
@@ -34,8 +35,7 @@ struct linux_central {
34 unsigned long clkregs; 35 unsigned long clkregs;
35 unsigned long clkver; 36 unsigned long clkver;
36 int slots; 37 int slots;
37 int prom_node; 38 struct device_node *prom_node;
38 char prom_name[64];
39 39
40 struct linux_prom_ranges central_ranges[PROMREG_MAX]; 40 struct linux_prom_ranges central_ranges[PROMREG_MAX];
41 int num_central_ranges; 41 int num_central_ranges;
@@ -112,8 +112,7 @@ struct linux_fhc {
112 struct fhc_regs fhc_regs; 112 struct fhc_regs fhc_regs;
113 int board; 113 int board;
114 int jtag_master; 114 int jtag_master;
115 int prom_node; 115 struct device_node *prom_node;
116 char prom_name[64];
117 116
118 struct linux_prom_ranges fhc_ranges[PROMREG_MAX]; 117 struct linux_prom_ranges fhc_ranges[PROMREG_MAX];
119 int num_fhc_ranges; 118 int num_fhc_ranges;