[SPARC64]: Convert central bus layer to in-kernel PROM device tree.
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
9c10a58ed6
commit
cecc4e9222
|
@ -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)
|
||||||
|
|
||||||
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)
|
||||||
/* 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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
/* 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)
|
||||||
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,
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
+ 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 @@
|
||||||
#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 {
|
||||||
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 {
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue