#define IS_CENTRAL_FHC(__fhc) ((__fhc) == central_bus->child)
-static inline unsigned long long_align(unsigned long addr)
+static void central_probe_failure(int line)
{
- return ((addr + (sizeof(unsigned long) - 1)) &
- ~(sizeof(unsigned long) - 1));
+ prom_printf("CENTRAL: Critical device probe failure at central.c:%d\n",
+ line);
+ 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;
- success = prom_getproperty(central->prom_node, "ranges",
- (char *) central->central_ranges,
- sizeof (central->central_ranges));
- if (success != -1)
- central->num_central_ranges = (success/sizeof(struct linux_prom_ranges));
+ pval = of_get_property(dp, "ranges", &len);
+ if (pval) {
+ memcpy(central->central_ranges, pval, len);
+ central->num_central_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;
- success = prom_getproperty(fhc->prom_node, "ranges",
- (char *) fhc->fhc_ranges,
- sizeof (fhc->fhc_ranges));
- if (success != -1)
- fhc->num_fhc_ranges = (success/sizeof(struct linux_prom_ranges));
+ pval = of_get_property(dp, "ranges", &len);
+ if (pval) {
+ memcpy(fhc->fhc_ranges, pval, len);
+ fhc->num_fhc_ranges =
+ (len / sizeof(struct linux_prom_ranges));
+ }
}
/* Range application routines are exported to various drivers,
if (regp[regc].which_io == rangep[rngc].ot_child_space)
break; /* Fount it */
if (rngc == nranges) /* oops */
- prom_printf("adjust_regs: Could not find range with matching bus type...\n");
+ central_probe_failure(__LINE__);
regp[regc].which_io = rangep[rngc].ot_parent_space;
regp[regc].phys_addr -= rangep[rngc].ot_child_base;
regp[regc].phys_addr += rangep[rngc].ot_parent_base;
return ret;
}
+static unsigned long prom_reg_to_paddr(struct linux_prom_registers *r)
+{
+ unsigned long ret = ((unsigned long) r->which_io) << 32;
+
+ return ret | (unsigned long) r->phys_addr;
+}
+
static void probe_other_fhcs(void)
{
- struct linux_prom64_registers fpregs[6];
- char namebuf[128];
- int node;
-
- node = prom_getchild(prom_root_node);
- node = prom_searchsiblings(node, "fhc");
- if (node == 0) {
- prom_printf("FHC: Cannot find any toplevel firehose controllers.\n");
- prom_halt();
- }
- while (node) {
+ struct device_node *dp;
+ struct linux_prom64_registers *fpregs;
+
+ for_each_node_by_name(dp, "fhc") {
struct linux_fhc *fhc;
int board;
u32 tmp;
+ if (dp->parent &&
+ dp->parent->parent != NULL)
+ continue;
+
fhc = (struct linux_fhc *)
central_alloc_bootmem(sizeof(struct linux_fhc));
- if (fhc == NULL) {
- prom_printf("probe_other_fhcs: Cannot alloc fhc.\n");
- prom_halt();
- }
+ if (fhc == NULL)
+ central_probe_failure(__LINE__);
/* Link it into the FHC chain. */
fhc->next = fhc_list;
/* Toplevel FHCs have no parent. */
fhc->parent = NULL;
- fhc->prom_node = node;
- prom_getstring(node, "name", namebuf, sizeof(namebuf));
- strcpy(fhc->prom_name, namebuf);
- fhc_ranges_init(node, fhc);
+ fhc->prom_node = dp;
+ fhc_ranges_init(fhc);
/* Non-central FHC's have 64-bit OBP format registers. */
- if (prom_getproperty(node, "reg",
- (char *)&fpregs[0], sizeof(fpregs)) == -1) {
- prom_printf("FHC: Fatal error, cannot get fhc regs.\n");
- prom_halt();
- }
+ fpregs = of_get_property(dp, "reg", NULL);
+ if (!fpregs)
+ central_probe_failure(__LINE__);
/* Only central FHC needs special ranges applied. */
fhc->fhc_regs.pregs = fpregs[0].phys_addr;
fhc->fhc_regs.uregs = fpregs[4].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;
tmp = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_JCTRL);
tmp = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_CTRL);
tmp |= FHC_CONTROL_IXIST;
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,
struct linux_fhc *fhc,
- int cnode, int fnode)
+ struct device_node *fp)
{
- struct linux_prom_registers cregs[3];
- int clknode, nslots, tmp, nregs;
+ struct device_node *dp;
+ struct linux_prom_registers cregs[3], *pr;
+ int nslots, tmp, nregs;
- clknode = prom_searchsiblings(prom_getchild(fnode), "clock-board");
- if (clknode == 0 || clknode == -1) {
- prom_printf("Critical error, central lacks clock-board.\n");
- prom_halt();
- }
- nregs = prom_getproperty(clknode, "reg", (char *)&cregs[0], sizeof(cregs));
- if (nregs == -1) {
- prom_printf("CENTRAL: Fatal error, cannot map clock-board regs.\n");
- prom_halt();
+ dp = fp->child;
+ while (dp) {
+ if (!strcmp(dp->name, "clock-board"))
+ break;
+ dp = dp->sibling;
}
+ if (!dp)
+ central_probe_failure(__LINE__);
+
+ pr = of_get_property(dp, "reg", &nregs);
+ if (!pr)
+ central_probe_failure(__LINE__);
+
+ memcpy(cregs, pr, nregs);
nregs /= sizeof(struct linux_prom_registers);
+
apply_fhc_ranges(fhc, &cregs[0], nregs);
apply_central_ranges(central, &cregs[0], nregs);
- central->cfreg = ((((unsigned long)cregs[0].which_io) << 32UL) |
- ((unsigned long)cregs[0].phys_addr));
- central->clkregs = ((((unsigned long)cregs[1].which_io) << 32UL) |
- ((unsigned long)cregs[1].phys_addr));
+ central->cfreg = prom_reg_to_paddr(&cregs[0]);
+ central->clkregs = prom_reg_to_paddr(&cregs[1]);
if (nregs == 2)
central->clkver = 0UL;
else
- central->clkver = ((((unsigned long)cregs[2].which_io) << 32UL) |
- ((unsigned long)cregs[2].phys_addr));
+ central->clkver = prom_reg_to_paddr(&cregs[2]);
tmp = upa_readb(central->clkregs + CLOCK_STAT1);
tmp &= 0xc0;
(central->clkver ? upa_readb(central->clkver) : 0x00));
}
+static void ZAP(unsigned long iclr, unsigned long imap)
+{
+ u32 imap_tmp;
+
+ upa_writel(0, iclr);
+ upa_readl(iclr);
+ imap_tmp = upa_readl(imap);
+ imap_tmp &= ~(0x80000000);
+ upa_writel(imap_tmp, imap);
+ upa_readl(imap);
+}
+
static void init_all_fhc_hw(void)
{
struct linux_fhc *fhc;
/* Clear all of the interrupt mapping registers
* just in case OBP left them in a foul state.
*/
-#define ZAP(ICLR, IMAP) \
-do { u32 imap_tmp; \
- upa_writel(0, (ICLR)); \
- upa_readl(ICLR); \
- imap_tmp = upa_readl(IMAP); \
- imap_tmp &= ~(0x80000000); \
- upa_writel(imap_tmp, (IMAP)); \
- upa_readl(IMAP); \
-} while (0)
-
ZAP(fhc->fhc_regs.ffregs + FHC_FFREGS_ICLR,
fhc->fhc_regs.ffregs + FHC_FFREGS_IMAP);
ZAP(fhc->fhc_regs.sregs + FHC_SREGS_ICLR,
ZAP(fhc->fhc_regs.tregs + FHC_TREGS_ICLR,
fhc->fhc_regs.tregs + FHC_TREGS_IMAP);
-#undef ZAP
-
/* Setup FHC control register. */
tmp = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_CTRL);
/* For all FHCs, clear the firmware synchronization
* line and both low power mode enables.
*/
- tmp &= ~(FHC_CONTROL_AOFF | FHC_CONTROL_BOFF | FHC_CONTROL_SLINE);
+ tmp &= ~(FHC_CONTROL_AOFF | FHC_CONTROL_BOFF |
+ FHC_CONTROL_SLINE);
upa_writel(tmp, fhc->fhc_regs.pregs + FHC_PREGS_CTRL);
upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_CTRL);
void central_probe(void)
{
- struct linux_prom_registers fpregs[6];
+ struct linux_prom_registers fpregs[6], *pr;
struct linux_fhc *fhc;
- char namebuf[128];
- int cnode, fnode, err;
+ struct device_node *dp, *fp;
+ int err;
- cnode = prom_finddevice("/central");
- if (cnode == 0 || cnode == -1) {
+ dp = of_find_node_by_name(NULL, "central");
+ if (!dp) {
if (this_is_starfire)
starfire_cpu_setup();
return;
/* Ok we got one, grab some memory for software state. */
central_bus = (struct linux_central *)
central_alloc_bootmem(sizeof(struct linux_central));
- if (central_bus == NULL) {
- prom_printf("central_probe: Cannot alloc central_bus.\n");
- prom_halt();
- }
+ if (central_bus == NULL)
+ central_probe_failure(__LINE__);
fhc = (struct linux_fhc *)
central_alloc_bootmem(sizeof(struct linux_fhc));
- if (fhc == NULL) {
- prom_printf("central_probe: Cannot alloc central fhc.\n");
- prom_halt();
- }
+ if (fhc == NULL)
+ central_probe_failure(__LINE__);
/* First init central. */
central_bus->child = fhc;
- central_bus->prom_node = cnode;
-
- prom_getstring(cnode, "name", namebuf, sizeof(namebuf));
- strcpy(central_bus->prom_name, namebuf);
-
- central_ranges_init(cnode, central_bus);
+ central_bus->prom_node = dp;
+ central_ranges_init(central_bus);
/* And then central's FHC. */
fhc->next = fhc_list;
fhc_list = fhc;
fhc->parent = central_bus;
- fnode = prom_searchsiblings(prom_getchild(cnode), "fhc");
- if (fnode == 0 || fnode == -1) {
- prom_printf("Critical error, central board lacks fhc.\n");
- prom_halt();
+ fp = dp->child;
+ while (fp) {
+ if (!strcmp(fp->name, "fhc"))
+ break;
+ fp = fp->sibling;
}
- fhc->prom_node = fnode;
- prom_getstring(fnode, "name", namebuf, sizeof(namebuf));
- strcpy(fhc->prom_name, namebuf);
+ if (!fp)
+ central_probe_failure(__LINE__);
- fhc_ranges_init(fnode, fhc);
+ fhc->prom_node = fp;
+ fhc_ranges_init(fhc);
/* Now, map in FHC register set. */
- if (prom_getproperty(fnode, "reg", (char *)&fpregs[0], sizeof(fpregs)) == -1) {
- prom_printf("CENTRAL: Fatal error, cannot get fhc regs.\n");
- prom_halt();
- }
+ pr = of_get_property(fp, "reg", NULL);
+ if (!pr)
+ central_probe_failure(__LINE__);
+ memcpy(fpregs, pr, sizeof(fpregs));
+
apply_central_ranges(central_bus, &fpregs[0], 6);
- fhc->fhc_regs.pregs = ((((unsigned long)fpregs[0].which_io)<<32UL) |
- ((unsigned long)fpregs[0].phys_addr));
- fhc->fhc_regs.ireg = ((((unsigned long)fpregs[1].which_io)<<32UL) |
- ((unsigned long)fpregs[1].phys_addr));
- fhc->fhc_regs.ffregs = ((((unsigned long)fpregs[2].which_io)<<32UL) |
- ((unsigned long)fpregs[2].phys_addr));
- fhc->fhc_regs.sregs = ((((unsigned long)fpregs[3].which_io)<<32UL) |
- ((unsigned long)fpregs[3].phys_addr));
- fhc->fhc_regs.uregs = ((((unsigned long)fpregs[4].which_io)<<32UL) |
- ((unsigned long)fpregs[4].phys_addr));
- fhc->fhc_regs.tregs = ((((unsigned long)fpregs[5].which_io)<<32UL) |
- ((unsigned long)fpregs[5].phys_addr));
+ fhc->fhc_regs.pregs = prom_reg_to_paddr(&fpregs[0]);
+ fhc->fhc_regs.ireg = prom_reg_to_paddr(&fpregs[1]);
+ fhc->fhc_regs.ffregs = prom_reg_to_paddr(&fpregs[2]);
+ fhc->fhc_regs.sregs = prom_reg_to_paddr(&fpregs[3]);
+ fhc->fhc_regs.uregs = prom_reg_to_paddr(&fpregs[4]);
+ fhc->fhc_regs.tregs = prom_reg_to_paddr(&fpregs[5]);
/* Obtain board number from board status register, Central's
* FHC lacks "board#" property.
fhc->jtag_master = 0;
/* 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);
printk("FHC(board %d): Version[%x] PartID[%x] Manuf[%x] (CENTRAL)\n",