|
@@ -285,36 +285,38 @@ static inline void *ebus_alloc(size_t size)
|
|
|
|
|
|
static void __init ebus_ranges_init(struct linux_ebus *ebus)
|
|
|
{
|
|
|
- int success;
|
|
|
+ struct linux_prom_ebus_ranges *rngs;
|
|
|
+ int len;
|
|
|
|
|
|
ebus->num_ebus_ranges = 0;
|
|
|
- success = prom_getproperty(ebus->prom_node, "ranges",
|
|
|
- (char *)ebus->ebus_ranges,
|
|
|
- sizeof(ebus->ebus_ranges));
|
|
|
- if (success != -1)
|
|
|
- ebus->num_ebus_ranges = (success/sizeof(struct linux_prom_ebus_ranges));
|
|
|
+ rngs = of_get_property(ebus->prom_node, "ranges", &len);
|
|
|
+ if (rngs) {
|
|
|
+ memcpy(ebus->ebus_ranges, rngs, len);
|
|
|
+ ebus->num_ebus_ranges =
|
|
|
+ (len / sizeof(struct linux_prom_ebus_ranges));
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static void __init ebus_intmap_init(struct linux_ebus *ebus)
|
|
|
{
|
|
|
- int success;
|
|
|
+ struct linux_prom_ebus_intmap *imap;
|
|
|
+ struct linux_prom_ebus_intmask *imask;
|
|
|
+ int len;
|
|
|
|
|
|
ebus->num_ebus_intmap = 0;
|
|
|
- success = prom_getproperty(ebus->prom_node, "interrupt-map",
|
|
|
- (char *)ebus->ebus_intmap,
|
|
|
- sizeof(ebus->ebus_intmap));
|
|
|
- if (success == -1)
|
|
|
+ imap = of_get_property(ebus->prom_node, "interrupt-map", &len);
|
|
|
+ if (!imap)
|
|
|
return;
|
|
|
|
|
|
- ebus->num_ebus_intmap = (success/sizeof(struct linux_prom_ebus_intmap));
|
|
|
+ memcpy(ebus->ebus_intmap, imap, len);
|
|
|
+ ebus->num_ebus_intmap = (len / sizeof(struct linux_prom_ebus_intmap));
|
|
|
|
|
|
- success = prom_getproperty(ebus->prom_node, "interrupt-map-mask",
|
|
|
- (char *)&ebus->ebus_intmask,
|
|
|
- sizeof(ebus->ebus_intmask));
|
|
|
- if (success == -1) {
|
|
|
- prom_printf("%s: can't get interrupt-map-mask\n", __FUNCTION__);
|
|
|
+ imask = of_get_property(ebus->prom_node, "interrupt-map-mask", &len);
|
|
|
+ if (!imask) {
|
|
|
+ prom_printf("EBUS: can't get interrupt-map-mask\n");
|
|
|
prom_halt();
|
|
|
}
|
|
|
+ memcpy(&ebus->ebus_intmask, imask, sizeof(ebus->ebus_intmask));
|
|
|
}
|
|
|
|
|
|
int __init ebus_intmap_match(struct linux_ebus *ebus,
|
|
@@ -341,19 +343,23 @@ int __init ebus_intmap_match(struct linux_ebus *ebus,
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
-void __init fill_ebus_child(int node, struct linux_prom_registers *preg,
|
|
|
- struct linux_ebus_child *dev, int non_standard_regs)
|
|
|
+void __init fill_ebus_child(struct device_node *dp,
|
|
|
+ struct linux_prom_registers *preg,
|
|
|
+ struct linux_ebus_child *dev,
|
|
|
+ int non_standard_regs)
|
|
|
{
|
|
|
- int regs[PROMREG_MAX];
|
|
|
- int irqs[PROMREG_MAX];
|
|
|
+ int *regs;
|
|
|
+ int *irqs;
|
|
|
int i, len;
|
|
|
|
|
|
- dev->prom_node = node;
|
|
|
- prom_getstring(node, "name", dev->prom_name, sizeof(dev->prom_name));
|
|
|
- printk(" (%s)", dev->prom_name);
|
|
|
+ dev->prom_node = dp;
|
|
|
+ printk(" (%s)", dp->name);
|
|
|
|
|
|
- len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs));
|
|
|
- dev->num_addrs = len / sizeof(regs[0]);
|
|
|
+ regs = of_get_property(dp, "reg", &len);
|
|
|
+ if (!regs)
|
|
|
+ dev->num_addrs = 0;
|
|
|
+ else
|
|
|
+ dev->num_addrs = len / sizeof(regs[0]);
|
|
|
|
|
|
if (non_standard_regs) {
|
|
|
/* This is to handle reg properties which are not
|
|
@@ -370,21 +376,21 @@ void __init fill_ebus_child(int node, struct linux_prom_registers *preg,
|
|
|
int rnum = regs[i];
|
|
|
if (rnum >= dev->parent->num_addrs) {
|
|
|
prom_printf("UGH: property for %s was %d, need < %d\n",
|
|
|
- dev->prom_name, len, dev->parent->num_addrs);
|
|
|
- panic(__FUNCTION__);
|
|
|
+ dp->name, len, dev->parent->num_addrs);
|
|
|
+ prom_halt();
|
|
|
}
|
|
|
dev->resource[i].start = dev->parent->resource[i].start;
|
|
|
dev->resource[i].end = dev->parent->resource[i].end;
|
|
|
dev->resource[i].flags = IORESOURCE_MEM;
|
|
|
- dev->resource[i].name = dev->prom_name;
|
|
|
+ dev->resource[i].name = dp->name;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
for (i = 0; i < PROMINTR_MAX; i++)
|
|
|
dev->irqs[i] = PCI_IRQ_NONE;
|
|
|
|
|
|
- len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
|
|
|
- if ((len == -1) || (len == 0)) {
|
|
|
+ irqs = of_get_property(dp, "interrupts", &len);
|
|
|
+ if (!irqs) {
|
|
|
dev->num_irqs = 0;
|
|
|
/*
|
|
|
* Oh, well, some PROMs don't export interrupts
|
|
@@ -392,8 +398,8 @@ void __init fill_ebus_child(int node, struct linux_prom_registers *preg,
|
|
|
*
|
|
|
* Be smart about PS/2 keyboard and mouse.
|
|
|
*/
|
|
|
- if (!strcmp(dev->parent->prom_name, "8042")) {
|
|
|
- if (!strcmp(dev->prom_name, "kb_ps2")) {
|
|
|
+ if (!strcmp(dev->parent->prom_node->name, "8042")) {
|
|
|
+ if (!strcmp(dev->prom_node->name, "kb_ps2")) {
|
|
|
dev->num_irqs = 1;
|
|
|
dev->irqs[0] = dev->parent->irqs[0];
|
|
|
} else {
|
|
@@ -423,32 +429,32 @@ void __init fill_ebus_child(int node, struct linux_prom_registers *preg,
|
|
|
|
|
|
static int __init child_regs_nonstandard(struct linux_ebus_device *dev)
|
|
|
{
|
|
|
- if (!strcmp(dev->prom_name, "i2c") ||
|
|
|
- !strcmp(dev->prom_name, "SUNW,lombus"))
|
|
|
+ if (!strcmp(dev->prom_node->name, "i2c") ||
|
|
|
+ !strcmp(dev->prom_node->name, "SUNW,lombus"))
|
|
|
return 1;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-void __init fill_ebus_device(int node, struct linux_ebus_device *dev)
|
|
|
+void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev)
|
|
|
{
|
|
|
- struct linux_prom_registers regs[PROMREG_MAX];
|
|
|
+ struct linux_prom_registers *regs;
|
|
|
struct linux_ebus_child *child;
|
|
|
- int irqs[PROMINTR_MAX];
|
|
|
+ int *irqs;
|
|
|
int i, n, len;
|
|
|
|
|
|
- dev->prom_node = node;
|
|
|
- prom_getstring(node, "name", dev->prom_name, sizeof(dev->prom_name));
|
|
|
- printk(" [%s", dev->prom_name);
|
|
|
+ dev->prom_node = dp;
|
|
|
|
|
|
- len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs));
|
|
|
- if (len == -1) {
|
|
|
+ printk(" [%s", dp->name);
|
|
|
+
|
|
|
+ regs = of_get_property(dp, "reg", &len);
|
|
|
+ if (!regs) {
|
|
|
dev->num_addrs = 0;
|
|
|
goto probe_interrupts;
|
|
|
}
|
|
|
|
|
|
if (len % sizeof(struct linux_prom_registers)) {
|
|
|
prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
|
|
|
- dev->prom_name, len,
|
|
|
+ dev->prom_node->name, len,
|
|
|
(int)sizeof(struct linux_prom_registers));
|
|
|
prom_halt();
|
|
|
}
|
|
@@ -466,7 +472,7 @@ void __init fill_ebus_device(int node, struct linux_ebus_device *dev)
|
|
|
dev->resource[i].end =
|
|
|
(dev->resource[i].start + (unsigned long)regs[i].reg_size - 1UL);
|
|
|
dev->resource[i].flags = IORESOURCE_MEM;
|
|
|
- dev->resource[i].name = dev->prom_name;
|
|
|
+ dev->resource[i].name = dev->prom_node->name;
|
|
|
request_resource(&dev->bus->self->resource[n],
|
|
|
&dev->resource[i]);
|
|
|
}
|
|
@@ -475,8 +481,8 @@ probe_interrupts:
|
|
|
for (i = 0; i < PROMINTR_MAX; i++)
|
|
|
dev->irqs[i] = PCI_IRQ_NONE;
|
|
|
|
|
|
- len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
|
|
|
- if ((len == -1) || (len == 0)) {
|
|
|
+ irqs = of_get_property(dp, "interrupts", &len);
|
|
|
+ if (!irqs) {
|
|
|
dev->num_irqs = 0;
|
|
|
} else {
|
|
|
dev->num_irqs = len / sizeof(irqs[0]);
|
|
@@ -497,7 +503,8 @@ probe_interrupts:
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if ((node = prom_getchild(node))) {
|
|
|
+ dp = dp->child;
|
|
|
+ if (dp) {
|
|
|
printk(" ->");
|
|
|
dev->children = ebus_alloc(sizeof(struct linux_ebus_child));
|
|
|
|
|
@@ -505,18 +512,18 @@ probe_interrupts:
|
|
|
child->next = NULL;
|
|
|
child->parent = dev;
|
|
|
child->bus = dev->bus;
|
|
|
- fill_ebus_child(node, ®s[0],
|
|
|
- child, child_regs_nonstandard(dev));
|
|
|
+ fill_ebus_child(dp, regs, child,
|
|
|
+ child_regs_nonstandard(dev));
|
|
|
|
|
|
- while ((node = prom_getsibling(node)) != 0) {
|
|
|
+ while ((dp = dp->sibling) != NULL) {
|
|
|
child->next = ebus_alloc(sizeof(struct linux_ebus_child));
|
|
|
|
|
|
child = child->next;
|
|
|
child->next = NULL;
|
|
|
child->parent = dev;
|
|
|
child->bus = dev->bus;
|
|
|
- fill_ebus_child(node, ®s[0],
|
|
|
- child, child_regs_nonstandard(dev));
|
|
|
+ fill_ebus_child(dp, regs, child,
|
|
|
+ child_regs_nonstandard(dev));
|
|
|
}
|
|
|
}
|
|
|
printk("]");
|
|
@@ -543,7 +550,8 @@ void __init ebus_init(void)
|
|
|
struct linux_ebus *ebus;
|
|
|
struct pci_dev *pdev;
|
|
|
struct pcidev_cookie *cookie;
|
|
|
- int nd, ebusnd, is_rio;
|
|
|
+ struct device_node *dp;
|
|
|
+ int is_rio;
|
|
|
int num_ebus = 0;
|
|
|
|
|
|
pdev = find_next_ebus(NULL, &is_rio);
|
|
@@ -553,20 +561,22 @@ void __init ebus_init(void)
|
|
|
}
|
|
|
|
|
|
cookie = pdev->sysdata;
|
|
|
- ebusnd = cookie->prom_node->node;
|
|
|
+ dp = cookie->prom_node;
|
|
|
|
|
|
ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus));
|
|
|
ebus->next = NULL;
|
|
|
ebus->is_rio = is_rio;
|
|
|
|
|
|
- while (ebusnd) {
|
|
|
+ while (dp) {
|
|
|
+ struct device_node *child;
|
|
|
+
|
|
|
/* SUNW,pci-qfe uses four empty ebuses on it.
|
|
|
I think we should not consider them here,
|
|
|
as they have half of the properties this
|
|
|
code expects and once we do PCI hot-plug,
|
|
|
we'd have to tweak with the ebus_chain
|
|
|
in the runtime after initialization. -jj */
|
|
|
- if (!prom_getchild (ebusnd)) {
|
|
|
+ if (!dp->child) {
|
|
|
pdev = find_next_ebus(pdev, &is_rio);
|
|
|
if (!pdev) {
|
|
|
if (ebus == ebus_chain) {
|
|
@@ -578,22 +588,21 @@ void __init ebus_init(void)
|
|
|
}
|
|
|
ebus->is_rio = is_rio;
|
|
|
cookie = pdev->sysdata;
|
|
|
- ebusnd = cookie->prom_node->node;
|
|
|
+ dp = cookie->prom_node;
|
|
|
continue;
|
|
|
}
|
|
|
printk("ebus%d:", num_ebus);
|
|
|
|
|
|
- prom_getstring(ebusnd, "name", ebus->prom_name, sizeof(ebus->prom_name));
|
|
|
ebus->index = num_ebus;
|
|
|
- ebus->prom_node = ebusnd;
|
|
|
+ ebus->prom_node = dp;
|
|
|
ebus->self = pdev;
|
|
|
ebus->parent = pbm = cookie->pbm;
|
|
|
|
|
|
ebus_ranges_init(ebus);
|
|
|
ebus_intmap_init(ebus);
|
|
|
|
|
|
- nd = prom_getchild(ebusnd);
|
|
|
- if (!nd)
|
|
|
+ child = dp->child;
|
|
|
+ if (!child)
|
|
|
goto next_ebus;
|
|
|
|
|
|
ebus->devices = ebus_alloc(sizeof(struct linux_ebus_device));
|
|
@@ -602,16 +611,16 @@ void __init ebus_init(void)
|
|
|
dev->next = NULL;
|
|
|
dev->children = NULL;
|
|
|
dev->bus = ebus;
|
|
|
- fill_ebus_device(nd, dev);
|
|
|
+ fill_ebus_device(child, dev);
|
|
|
|
|
|
- while ((nd = prom_getsibling(nd)) != 0) {
|
|
|
+ while ((child = child->sibling) != NULL) {
|
|
|
dev->next = ebus_alloc(sizeof(struct linux_ebus_device));
|
|
|
|
|
|
dev = dev->next;
|
|
|
dev->next = NULL;
|
|
|
dev->children = NULL;
|
|
|
dev->bus = ebus;
|
|
|
- fill_ebus_device(nd, dev);
|
|
|
+ fill_ebus_device(child, dev);
|
|
|
}
|
|
|
|
|
|
next_ebus:
|
|
@@ -622,7 +631,7 @@ void __init ebus_init(void)
|
|
|
break;
|
|
|
|
|
|
cookie = pdev->sysdata;
|
|
|
- ebusnd = cookie->prom_node->node;
|
|
|
+ dp = cookie->prom_node;
|
|
|
|
|
|
ebus->next = ebus_alloc(sizeof(struct linux_ebus));
|
|
|
ebus = ebus->next;
|