Commit cecc4e92 authored by David S. Miller's avatar David S. Miller

[SPARC64]: Convert central bus layer to in-kernel PROM device tree.

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9c10a58e
...@@ -29,28 +29,34 @@ static void central_probe_failure(int line) ...@@ -29,28 +29,34 @@ static void central_probe_failure(int line)
prom_halt(); prom_halt();
} }
static void central_ranges_init(int cnode, struct linux_central *central) static void central_ranges_init(struct linux_central *central)
{ {
int success; struct device_node *dp = central->prom_node;
void *pval;
int len;
central->num_central_ranges = 0; central->num_central_ranges = 0;
success = prom_getproperty(central->prom_node, "ranges", pval = of_get_property(dp, "ranges", &len);
(char *) central->central_ranges, if (pval) {
sizeof (central->central_ranges)); memcpy(central->central_ranges, pval, len);
if (success != -1) central->num_central_ranges =
central->num_central_ranges = (success/sizeof(struct linux_prom_ranges)); (len / sizeof(struct linux_prom_ranges));
}
} }
static void fhc_ranges_init(int fnode, struct linux_fhc *fhc) static void fhc_ranges_init(struct linux_fhc *fhc)
{ {
int success; struct device_node *dp = fhc->prom_node;
void *pval;
int len;
fhc->num_fhc_ranges = 0; fhc->num_fhc_ranges = 0;
success = prom_getproperty(fhc->prom_node, "ranges", pval = of_get_property(dp, "ranges", &len);
(char *) fhc->fhc_ranges, if (pval) {
sizeof (fhc->fhc_ranges)); memcpy(fhc->fhc_ranges, pval, len);
if (success != -1) fhc->num_fhc_ranges =
fhc->num_fhc_ranges = (success/sizeof(struct linux_prom_ranges)); (len / sizeof(struct linux_prom_ranges));
}
} }
/* Range application routines are exported to various drivers, /* 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,15 +118,10 @@ static unsigned long prom_reg_to_paddr(struct linux_prom_registers *r)
static void probe_other_fhcs(void) static void probe_other_fhcs(void)
{ {
struct linux_prom64_registers fpregs[6]; struct device_node *dp;
char namebuf[128]; struct linux_prom64_registers *fpregs;
int node;
node = prom_getchild(prom_root_node); for_each_node_by_name(dp, "fhc") {
node = prom_searchsiblings(node, "fhc");
if (node == 0)
central_probe_failure(__LINE__);
while (node) {
struct linux_fhc *fhc; struct linux_fhc *fhc;
int board; int board;
u32 tmp; u32 tmp;
...@@ -137,14 +138,12 @@ static void probe_other_fhcs(void) ...@@ -137,14 +138,12 @@ static void probe_other_fhcs(void)
/* Toplevel FHCs have no parent. */ /* Toplevel FHCs have no parent. */
fhc->parent = NULL; fhc->parent = NULL;
fhc->prom_node = node; fhc->prom_node = dp;
prom_getstring(node, "name", namebuf, sizeof(namebuf)); fhc_ranges_init(fhc);
strcpy(fhc->prom_name, namebuf);
fhc_ranges_init(node, fhc);
/* Non-central FHC's have 64-bit OBP format registers. */ /* Non-central FHC's have 64-bit OBP format registers. */
if (prom_getproperty(node, "reg", fpregs = of_get_property(dp, "reg", NULL);
(char *)&fpregs[0], sizeof(fpregs)) == -1) if (!fpregs)
central_probe_failure(__LINE__); central_probe_failure(__LINE__);
/* Only central FHC needs special ranges applied. */ /* Only central FHC needs special ranges applied. */
...@@ -155,7 +154,7 @@ static void probe_other_fhcs(void) ...@@ -155,7 +154,7 @@ static void probe_other_fhcs(void)
fhc->fhc_regs.uregs = fpregs[4].phys_addr; fhc->fhc_regs.uregs = fpregs[4].phys_addr;
fhc->fhc_regs.tregs = fpregs[5].phys_addr; fhc->fhc_regs.tregs = fpregs[5].phys_addr;
board = prom_getintdefault(node, "board#", -1); board = of_getintprop_default(dp, "board#", -1);
fhc->board = board; fhc->board = board;
tmp = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_JCTRL); tmp = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_JCTRL);
...@@ -179,33 +178,33 @@ static void probe_other_fhcs(void) ...@@ -179,33 +178,33 @@ static void probe_other_fhcs(void)
tmp = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_CTRL); tmp = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_CTRL);
tmp |= FHC_CONTROL_IXIST; tmp |= FHC_CONTROL_IXIST;
upa_writel(tmp, fhc->fhc_regs.pregs + FHC_PREGS_CTRL); upa_writel(tmp, fhc->fhc_regs.pregs + FHC_PREGS_CTRL);
/* Look for the next FHC. */
node = prom_getsibling(node);
if (node == 0)
break;
node = prom_searchsiblings(node, "fhc");
if (node == 0)
break;
} }
} }
static void probe_clock_board(struct linux_central *central, static void probe_clock_board(struct linux_central *central,
struct linux_fhc *fhc, struct linux_fhc *fhc,
int cnode, int fnode) struct device_node *fp)
{ {
struct linux_prom_registers cregs[3]; struct device_node *dp;
int clknode, nslots, tmp, nregs; struct linux_prom_registers cregs[3], *pr;
int nslots, tmp, nregs;
clknode = prom_searchsiblings(prom_getchild(fnode), "clock-board"); dp = fp->child;
if (clknode == 0 || clknode == -1) while (dp) {
if (!strcmp(dp->name, "clock-board"))
break;
dp = dp->sibling;
}
if (!dp)
central_probe_failure(__LINE__); central_probe_failure(__LINE__);
nregs = prom_getproperty(clknode, "reg", (char *)&cregs[0], sizeof(cregs)); pr = of_get_property(dp, "reg", &nregs);
if (nregs == -1) if (!pr)
central_probe_failure(__LINE__); central_probe_failure(__LINE__);
memcpy(cregs, pr, nregs);
nregs /= sizeof(struct linux_prom_registers); nregs /= sizeof(struct linux_prom_registers);
apply_fhc_ranges(fhc, &cregs[0], nregs); apply_fhc_ranges(fhc, &cregs[0], nregs);
apply_central_ranges(central, &cregs[0], nregs); apply_central_ranges(central, &cregs[0], nregs);
central->cfreg = prom_reg_to_paddr(&cregs[0]); central->cfreg = prom_reg_to_paddr(&cregs[0]);
...@@ -296,13 +295,13 @@ static void init_all_fhc_hw(void) ...@@ -296,13 +295,13 @@ static void init_all_fhc_hw(void)
void central_probe(void) void central_probe(void)
{ {
struct linux_prom_registers fpregs[6]; struct linux_prom_registers fpregs[6], *pr;
struct linux_fhc *fhc; struct linux_fhc *fhc;
char namebuf[128]; struct device_node *dp, *fp;
int cnode, fnode, err; int err;
cnode = prom_finddevice("/central"); dp = of_find_node_by_name(NULL, "central");
if (cnode == 0 || cnode == -1) { if (!dp) {
if (this_is_starfire) if (this_is_starfire)
starfire_cpu_setup(); starfire_cpu_setup();
return; return;
...@@ -321,31 +320,31 @@ void central_probe(void) ...@@ -321,31 +320,31 @@ void central_probe(void)
/* First init central. */ /* First init central. */
central_bus->child = fhc; central_bus->child = fhc;
central_bus->prom_node = cnode; central_bus->prom_node = dp;
central_ranges_init(central_bus);
prom_getstring(cnode, "name", namebuf, sizeof(namebuf));
strcpy(central_bus->prom_name, namebuf);
central_ranges_init(cnode, central_bus);
/* And then central's FHC. */ /* And then central's FHC. */
fhc->next = fhc_list; fhc->next = fhc_list;
fhc_list = fhc; fhc_list = fhc;
fhc->parent = central_bus; fhc->parent = central_bus;
fnode = prom_searchsiblings(prom_getchild(cnode), "fhc"); fp = dp->child;
if (fnode == 0 || fnode == -1) while (fp) {
if (!strcmp(fp->name, "fhc"))
break;
fp = fp->sibling;
}
if (!fp)
central_probe_failure(__LINE__); central_probe_failure(__LINE__);
fhc->prom_node = fnode; fhc->prom_node = fp;
prom_getstring(fnode, "name", namebuf, sizeof(namebuf)); fhc_ranges_init(fhc);
strcpy(fhc->prom_name, namebuf);
fhc_ranges_init(fnode, fhc);
/* Now, map in FHC register set. */ /* Now, map in FHC register set. */
if (prom_getproperty(fnode, "reg", (char *)&fpregs[0], sizeof(fpregs)) == -1) pr = of_get_property(fp, "reg", NULL);
if (!pr)
central_probe_failure(__LINE__); central_probe_failure(__LINE__);
memcpy(fpregs, pr, sizeof(fpregs));
apply_central_ranges(central_bus, &fpregs[0], 6); apply_central_ranges(central_bus, &fpregs[0], 6);
...@@ -366,7 +365,7 @@ void central_probe(void) ...@@ -366,7 +365,7 @@ void central_probe(void)
fhc->jtag_master = 0; fhc->jtag_master = 0;
/* Attach the clock board registers for CENTRAL. */ /* Attach the clock board registers for CENTRAL. */
probe_clock_board(central_bus, fhc, cnode, fnode); probe_clock_board(central_bus, fhc, fp);
err = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_ID); err = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_ID);
printk("FHC(board %d): Version[%x] PartID[%x] Manuf[%x] (CENTRAL)\n", printk("FHC(board %d): Version[%x] PartID[%x] Manuf[%x] (CENTRAL)\n",
......
...@@ -796,26 +796,26 @@ static void __init clock_assign_clk_reg(struct linux_prom_registers *clk_reg, ...@@ -796,26 +796,26 @@ static void __init clock_assign_clk_reg(struct linux_prom_registers *clk_reg,
static int __init clock_probe_central(void) static int __init clock_probe_central(void)
{ {
struct linux_prom_registers clk_reg[2]; struct linux_prom_registers clk_reg[2], *pr;
char model[64]; struct device_node *dp;
int node; char *model;
if (!central_bus) if (!central_bus)
return 0; return 0;
/* Get Central FHC's prom node. */ /* Get Central FHC's prom node. */
node = central_bus->child->prom_node; dp = central_bus->child->prom_node;
/* Then get the first child device below it. */ /* Then get the first child device below it. */
node = prom_getchild(node); dp = dp->child;
while (node) { while (dp) {
prom_getstring(node, "model", model, sizeof(model)); model = of_get_property(dp, "model", NULL);
if (!clock_model_matches(model)) if (!model || !clock_model_matches(model))
goto next_sibling; goto next_sibling;
prom_getproperty(node, "reg", (char *)clk_reg, pr = of_get_property(dp, "reg", NULL);
sizeof(clk_reg)); memcpy(clk_reg, pr, sizeof(clk_reg));
apply_fhc_ranges(central_bus->child, clk_reg, 1); apply_fhc_ranges(central_bus->child, clk_reg, 1);
apply_central_ranges(central_bus, clk_reg, 1); apply_central_ranges(central_bus, clk_reg, 1);
...@@ -824,7 +824,7 @@ static int __init clock_probe_central(void) ...@@ -824,7 +824,7 @@ static int __init clock_probe_central(void)
return 1; return 1;
next_sibling: next_sibling:
node = prom_getsibling(node); dp = dp->sibling;
} }
return 0; return 0;
......
...@@ -1106,7 +1106,7 @@ static struct zilog_layout __iomem * __init get_zs_sun4u(int chip, int zsnode) ...@@ -1106,7 +1106,7 @@ static struct zilog_layout __iomem * __init get_zs_sun4u(int chip, int zsnode)
+ FHC_UREGS_ICLR; + FHC_UREGS_ICLR;
imap = central_bus->child->fhc_regs.uregs imap = central_bus->child->fhc_regs.uregs
+ FHC_UREGS_IMAP; + FHC_UREGS_IMAP;
zilog_irq = build_irq(12, 0, iclr, imap); zilog_irq = build_irq(0, iclr, imap);
} else { } else {
err = prom_getproperty(zsnode, "interrupts", err = prom_getproperty(zsnode, "interrupts",
(char *) &sun4u_ino, (char *) &sun4u_ino,
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/timer.h> #include <linux/timer.h>
#include <asm/oplib.h> #include <asm/oplib.h>
#include <asm/prom.h>
#include <asm/upa.h> #include <asm/upa.h>
struct linux_fhc; struct linux_fhc;
...@@ -34,8 +35,7 @@ struct linux_central { ...@@ -34,8 +35,7 @@ struct linux_central {
unsigned long clkregs; unsigned long clkregs;
unsigned long clkver; unsigned long clkver;
int slots; int slots;
int prom_node; struct device_node *prom_node;
char prom_name[64];
struct linux_prom_ranges central_ranges[PROMREG_MAX]; struct linux_prom_ranges central_ranges[PROMREG_MAX];
int num_central_ranges; int num_central_ranges;
...@@ -112,8 +112,7 @@ struct linux_fhc { ...@@ -112,8 +112,7 @@ struct linux_fhc {
struct fhc_regs fhc_regs; struct fhc_regs fhc_regs;
int board; int board;
int jtag_master; int jtag_master;
int prom_node; struct device_node *prom_node;
char prom_name[64];
struct linux_prom_ranges fhc_ranges[PROMREG_MAX]; struct linux_prom_ranges fhc_ranges[PROMREG_MAX];
int num_fhc_ranges; int num_fhc_ranges;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment