diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-06-22 22:53:24 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-06-24 02:15:32 -0400 |
commit | cecc4e9222c4e2bca59834750e493eea6be97613 (patch) | |
tree | 9fd177ac904e4ef091c0322ae9f105210d42916d | |
parent | 9c10a58ed634d98114c5717e2da761d8a63f2cd4 (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.c | 127 | ||||
-rw-r--r-- | arch/sparc64/kernel/time.c | 22 | ||||
-rw-r--r-- | drivers/serial/sunzilog.c | 2 | ||||
-rw-r--r-- | include/asm-sparc64/fhc.h | 7 |
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 | ||
32 | static void central_ranges_init(int cnode, struct linux_central *central) | 32 | static 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 | ||
44 | static void fhc_ranges_init(int fnode, struct linux_fhc *fhc) | 47 | static 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 | ||
113 | static void probe_other_fhcs(void) | 119 | static 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 | ||
193 | static void probe_clock_board(struct linux_central *central, | 184 | static 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 | ||
297 | void central_probe(void) | 296 | void 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 | ||
797 | static int __init clock_probe_central(void) | 797 | static 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 | ||
15 | struct linux_fhc; | 16 | struct 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; |