Commit 690c8fd3 authored by David S. Miller's avatar David S. Miller
Browse files

[SPARC64]: Use in-kernel PROM tree for EBUS and ISA.

parent de8d28b1
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -136,7 +136,7 @@ void __init auxio_probe(void)


		for_each_ebus(ebus) {
		for_each_ebus(ebus) {
			for_each_ebusdev(edev, ebus) {
			for_each_ebusdev(edev, ebus) {
				if (!strcmp(edev->prom_name, "auxio"))
				if (!strcmp(edev->prom_node->name, "auxio"))
					goto ebus_done;
					goto ebus_done;
			}
			}
		}
		}
+75 −66
Original line number Original line Diff line number Diff line
@@ -285,36 +285,38 @@ static inline void *ebus_alloc(size_t size)


static void __init ebus_ranges_init(struct linux_ebus *ebus)
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;
	ebus->num_ebus_ranges = 0;
	success = prom_getproperty(ebus->prom_node, "ranges",
	rngs = of_get_property(ebus->prom_node, "ranges", &len);
				   (char *)ebus->ebus_ranges,
	if (rngs) {
				   sizeof(ebus->ebus_ranges));
		memcpy(ebus->ebus_ranges, rngs, len);
	if (success != -1)
		ebus->num_ebus_ranges =
		ebus->num_ebus_ranges = (success/sizeof(struct linux_prom_ebus_ranges));
			(len / sizeof(struct linux_prom_ebus_ranges));
	}
}
}


static void __init ebus_intmap_init(struct linux_ebus *ebus)
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;
	ebus->num_ebus_intmap = 0;
	success = prom_getproperty(ebus->prom_node, "interrupt-map",
	imap = of_get_property(ebus->prom_node, "interrupt-map", &len);
				   (char *)ebus->ebus_intmap,
	if (!imap)
				   sizeof(ebus->ebus_intmap));
	if (success == -1)
		return;
		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",
	imask = of_get_property(ebus->prom_node, "interrupt-map-mask", &len);
				   (char *)&ebus->ebus_intmask,
	if (!imask) {
				   sizeof(ebus->ebus_intmask));
		prom_printf("EBUS: can't get interrupt-map-mask\n");
	if (success == -1) {
		prom_printf("%s: can't get interrupt-map-mask\n", __FUNCTION__);
		prom_halt();
		prom_halt();
	}
	}
	memcpy(&ebus->ebus_intmask, imask, sizeof(ebus->ebus_intmask));
}
}


int __init ebus_intmap_match(struct linux_ebus *ebus,
int __init ebus_intmap_match(struct linux_ebus *ebus,
@@ -341,18 +343,22 @@ int __init ebus_intmap_match(struct linux_ebus *ebus,
	return -1;
	return -1;
}
}


void __init fill_ebus_child(int node, struct linux_prom_registers *preg,
void __init fill_ebus_child(struct device_node *dp,
			    struct linux_ebus_child *dev, int non_standard_regs)
			    struct linux_prom_registers *preg,
			    struct linux_ebus_child *dev,
			    int non_standard_regs)
{
{
	int regs[PROMREG_MAX];
	int *regs;
	int irqs[PROMREG_MAX];
	int *irqs;
	int i, len;
	int i, len;


	dev->prom_node = node;
	dev->prom_node = dp;
	prom_getstring(node, "name", dev->prom_name, sizeof(dev->prom_name));
	printk(" (%s)", dp->name);
	printk(" (%s)", dev->prom_name);


	len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs));
	regs = of_get_property(dp, "reg", &len);
	if (!regs)
		dev->num_addrs = 0;
	else
		dev->num_addrs = len / sizeof(regs[0]);
		dev->num_addrs = len / sizeof(regs[0]);


	if (non_standard_regs) {
	if (non_standard_regs) {
@@ -370,21 +376,21 @@ void __init fill_ebus_child(int node, struct linux_prom_registers *preg,
			int rnum = regs[i];
			int rnum = regs[i];
			if (rnum >= dev->parent->num_addrs) {
			if (rnum >= dev->parent->num_addrs) {
				prom_printf("UGH: property for %s was %d, need < %d\n",
				prom_printf("UGH: property for %s was %d, need < %d\n",
					    dev->prom_name, len, dev->parent->num_addrs);
					    dp->name, len, dev->parent->num_addrs);
				panic(__FUNCTION__);
				prom_halt();
			}
			}
			dev->resource[i].start = dev->parent->resource[i].start;
			dev->resource[i].start = dev->parent->resource[i].start;
			dev->resource[i].end = dev->parent->resource[i].end;
			dev->resource[i].end = dev->parent->resource[i].end;
			dev->resource[i].flags = IORESOURCE_MEM;
			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++)
	for (i = 0; i < PROMINTR_MAX; i++)
		dev->irqs[i] = PCI_IRQ_NONE;
		dev->irqs[i] = PCI_IRQ_NONE;


	len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
	irqs = of_get_property(dp, "interrupts", &len);
	if ((len == -1) || (len == 0)) {
	if (!irqs) {
		dev->num_irqs = 0;
		dev->num_irqs = 0;
		/*
		/*
		 * Oh, well, some PROMs don't export interrupts
		 * 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.
		 * Be smart about PS/2 keyboard and mouse.
		 */
		 */
		if (!strcmp(dev->parent->prom_name, "8042")) {
		if (!strcmp(dev->parent->prom_node->name, "8042")) {
			if (!strcmp(dev->prom_name, "kb_ps2")) {
			if (!strcmp(dev->prom_node->name, "kb_ps2")) {
				dev->num_irqs = 1;
				dev->num_irqs = 1;
				dev->irqs[0] = dev->parent->irqs[0];
				dev->irqs[0] = dev->parent->irqs[0];
			} else {
			} 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)
static int __init child_regs_nonstandard(struct linux_ebus_device *dev)
{
{
	if (!strcmp(dev->prom_name, "i2c") ||
	if (!strcmp(dev->prom_node->name, "i2c") ||
	    !strcmp(dev->prom_name, "SUNW,lombus"))
	    !strcmp(dev->prom_node->name, "SUNW,lombus"))
		return 1;
		return 1;
	return 0;
	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;
	struct linux_ebus_child *child;
	int irqs[PROMINTR_MAX];
	int *irqs;
	int i, n, len;
	int i, n, len;


	dev->prom_node = node;
	dev->prom_node = dp;
	prom_getstring(node, "name", dev->prom_name, sizeof(dev->prom_name));

	printk(" [%s", dev->prom_name);
	printk(" [%s", dp->name);


	len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs));
	regs = of_get_property(dp, "reg", &len);
	if (len == -1) {
	if (!regs) {
		dev->num_addrs = 0;
		dev->num_addrs = 0;
		goto probe_interrupts;
		goto probe_interrupts;
	}
	}


	if (len % sizeof(struct linux_prom_registers)) {
	if (len % sizeof(struct linux_prom_registers)) {
		prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
		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));
			    (int)sizeof(struct linux_prom_registers));
		prom_halt();
		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].end    =
			(dev->resource[i].start + (unsigned long)regs[i].reg_size - 1UL);
			(dev->resource[i].start + (unsigned long)regs[i].reg_size - 1UL);
		dev->resource[i].flags  = IORESOURCE_MEM;
		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],
		request_resource(&dev->bus->self->resource[n],
				 &dev->resource[i]);
				 &dev->resource[i]);
	}
	}
@@ -475,8 +481,8 @@ void __init fill_ebus_device(int node, struct linux_ebus_device *dev)
	for (i = 0; i < PROMINTR_MAX; i++)
	for (i = 0; i < PROMINTR_MAX; i++)
		dev->irqs[i] = PCI_IRQ_NONE;
		dev->irqs[i] = PCI_IRQ_NONE;


	len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
	irqs = of_get_property(dp, "interrupts", &len);
	if ((len == -1) || (len == 0)) {
	if (!irqs) {
		dev->num_irqs = 0;
		dev->num_irqs = 0;
	} else {
	} else {
		dev->num_irqs = len / sizeof(irqs[0]);
		dev->num_irqs = len / sizeof(irqs[0]);
@@ -497,7 +503,8 @@ void __init fill_ebus_device(int node, struct linux_ebus_device *dev)
		}
		}
	}
	}


	if ((node = prom_getchild(node))) {
	dp = dp->child;
	if (dp) {
		printk(" ->");
		printk(" ->");
		dev->children = ebus_alloc(sizeof(struct linux_ebus_child));
		dev->children = ebus_alloc(sizeof(struct linux_ebus_child));


@@ -505,18 +512,18 @@ void __init fill_ebus_device(int node, struct linux_ebus_device *dev)
		child->next = NULL;
		child->next = NULL;
		child->parent = dev;
		child->parent = dev;
		child->bus = dev->bus;
		child->bus = dev->bus;
		fill_ebus_child(node, &regs[0],
		fill_ebus_child(dp, regs, child,
				child, child_regs_nonstandard(dev));
				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->next = ebus_alloc(sizeof(struct linux_ebus_child));


			child = child->next;
			child = child->next;
			child->next = NULL;
			child->next = NULL;
			child->parent = dev;
			child->parent = dev;
			child->bus = dev->bus;
			child->bus = dev->bus;
			fill_ebus_child(node, &regs[0],
			fill_ebus_child(dp, regs, child,
					child, child_regs_nonstandard(dev));
					child_regs_nonstandard(dev));
		}
		}
	}
	}
	printk("]");
	printk("]");
@@ -543,7 +550,8 @@ void __init ebus_init(void)
	struct linux_ebus *ebus;
	struct linux_ebus *ebus;
	struct pci_dev *pdev;
	struct pci_dev *pdev;
	struct pcidev_cookie *cookie;
	struct pcidev_cookie *cookie;
	int nd, ebusnd, is_rio;
	struct device_node *dp;
	int is_rio;
	int num_ebus = 0;
	int num_ebus = 0;


	pdev = find_next_ebus(NULL, &is_rio);
	pdev = find_next_ebus(NULL, &is_rio);
@@ -553,20 +561,22 @@ void __init ebus_init(void)
	}
	}


	cookie = pdev->sysdata;
	cookie = pdev->sysdata;
	ebusnd = cookie->prom_node->node;
	dp = cookie->prom_node;


	ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus));
	ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus));
	ebus->next = NULL;
	ebus->next = NULL;
	ebus->is_rio = is_rio;
	ebus->is_rio = is_rio;


	while (ebusnd) {
	while (dp) {
		struct device_node *child;

		/* SUNW,pci-qfe uses four empty ebuses on it.
		/* SUNW,pci-qfe uses four empty ebuses on it.
		   I think we should not consider them here,
		   I think we should not consider them here,
		   as they have half of the properties this
		   as they have half of the properties this
		   code expects and once we do PCI hot-plug,
		   code expects and once we do PCI hot-plug,
		   we'd have to tweak with the ebus_chain
		   we'd have to tweak with the ebus_chain
		   in the runtime after initialization. -jj */
		   in the runtime after initialization. -jj */
		if (!prom_getchild (ebusnd)) {
		if (!dp->child) {
			pdev = find_next_ebus(pdev, &is_rio);
			pdev = find_next_ebus(pdev, &is_rio);
			if (!pdev) {
			if (!pdev) {
				if (ebus == ebus_chain) {
				if (ebus == ebus_chain) {
@@ -578,22 +588,21 @@ void __init ebus_init(void)
			}
			}
			ebus->is_rio = is_rio;
			ebus->is_rio = is_rio;
			cookie = pdev->sysdata;
			cookie = pdev->sysdata;
			ebusnd = cookie->prom_node->node;
			dp = cookie->prom_node;
			continue;
			continue;
		}
		}
		printk("ebus%d:", num_ebus);
		printk("ebus%d:", num_ebus);


		prom_getstring(ebusnd, "name", ebus->prom_name, sizeof(ebus->prom_name));
		ebus->index = num_ebus;
		ebus->index = num_ebus;
		ebus->prom_node = ebusnd;
		ebus->prom_node = dp;
		ebus->self = pdev;
		ebus->self = pdev;
		ebus->parent = pbm = cookie->pbm;
		ebus->parent = pbm = cookie->pbm;


		ebus_ranges_init(ebus);
		ebus_ranges_init(ebus);
		ebus_intmap_init(ebus);
		ebus_intmap_init(ebus);


		nd = prom_getchild(ebusnd);
		child = dp->child;
		if (!nd)
		if (!child)
			goto next_ebus;
			goto next_ebus;


		ebus->devices = ebus_alloc(sizeof(struct linux_ebus_device));
		ebus->devices = ebus_alloc(sizeof(struct linux_ebus_device));
@@ -602,16 +611,16 @@ void __init ebus_init(void)
		dev->next = NULL;
		dev->next = NULL;
		dev->children = NULL;
		dev->children = NULL;
		dev->bus = ebus;
		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->next = ebus_alloc(sizeof(struct linux_ebus_device));


			dev = dev->next;
			dev = dev->next;
			dev->next = NULL;
			dev->next = NULL;
			dev->children = NULL;
			dev->children = NULL;
			dev->bus = ebus;
			dev->bus = ebus;
			fill_ebus_device(nd, dev);
			fill_ebus_device(child, dev);
		}
		}


	next_ebus:
	next_ebus:
@@ -622,7 +631,7 @@ void __init ebus_init(void)
			break;
			break;


		cookie = pdev->sysdata;
		cookie = pdev->sysdata;
		ebusnd = cookie->prom_node->node;
		dp = cookie->prom_node;


		ebus->next = ebus_alloc(sizeof(struct linux_ebus));
		ebus->next = ebus_alloc(sizeof(struct linux_ebus));
		ebus = ebus->next;
		ebus = ebus->next;
+57 −87
Original line number Original line Diff line number Diff line
@@ -15,23 +15,19 @@ static void __init fatal_err(const char *reason)
static void __init report_dev(struct sparc_isa_device *isa_dev, int child)
static void __init report_dev(struct sparc_isa_device *isa_dev, int child)
{
{
	if (child)
	if (child)
		printk(" (%s)", isa_dev->prom_name);
		printk(" (%s)", isa_dev->prom_node->name);
	else
	else
		printk(" [%s", isa_dev->prom_name);
		printk(" [%s", isa_dev->prom_node->name);
}
}


static void __init isa_dev_get_resource(struct sparc_isa_device *isa_dev,
static struct linux_prom_registers * __init
					struct linux_prom_registers *pregs,
isa_dev_get_resource(struct sparc_isa_device *isa_dev)
					int pregs_size)
{
{
	struct linux_prom_registers *pregs;
	unsigned long base, len;
	unsigned long base, len;
	int prop_len;
	int prop_len;


	prop_len = prom_getproperty(isa_dev->prom_node, "reg",
	pregs = of_get_property(isa_dev->prom_node, "reg", &prop_len);
				    (char *) pregs, pregs_size);

	if (prop_len <= 0)
		return;


	/* Only the first one is interesting. */
	/* Only the first one is interesting. */
	len = pregs[0].reg_size;
	len = pregs[0].reg_size;
@@ -42,10 +38,12 @@ static void __init isa_dev_get_resource(struct sparc_isa_device *isa_dev,
	isa_dev->resource.start = base;
	isa_dev->resource.start = base;
	isa_dev->resource.end   = (base + len - 1UL);
	isa_dev->resource.end   = (base + len - 1UL);
	isa_dev->resource.flags = IORESOURCE_IO;
	isa_dev->resource.flags = IORESOURCE_IO;
	isa_dev->resource.name  = isa_dev->prom_name;
	isa_dev->resource.name  = isa_dev->prom_node->name;


	request_resource(&isa_dev->bus->parent->io_space,
	request_resource(&isa_dev->bus->parent->io_space,
			 &isa_dev->resource);
			 &isa_dev->resource);

	return pregs;
}
}


/* I can't believe they didn't put a real INO in the isa device
/* I can't believe they didn't put a real INO in the isa device
@@ -98,7 +96,7 @@ static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev,
{
{
	int irq_prop;
	int irq_prop;


	irq_prop = prom_getintdefault(isa_dev->prom_node,
	irq_prop = of_getintprop_default(isa_dev->prom_node,
					 "interrupts", -1);
					 "interrupts", -1);
	if (irq_prop <= 0) {
	if (irq_prop <= 0) {
		goto no_irq;
		goto no_irq;
@@ -141,16 +139,15 @@ static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev,


static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev)
static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev)
{
{
	int node = prom_getchild(parent_isa_dev->prom_node);
	struct device_node *dp = parent_isa_dev->prom_node->child;


	if (node == 0)
	if (!dp)
		return;
		return;


	printk(" ->");
	printk(" ->");
	while (node != 0) {
	while (dp) {
		struct linux_prom_registers regs[PROMREG_MAX];
		struct linux_prom_registers *regs;
		struct sparc_isa_device *isa_dev;
		struct sparc_isa_device *isa_dev;
		int prop_len;


		isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
		isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
		if (!isa_dev) {
		if (!isa_dev) {
@@ -165,40 +162,24 @@ static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev)
		parent_isa_dev->child = isa_dev;
		parent_isa_dev->child = isa_dev;


		isa_dev->bus = parent_isa_dev->bus;
		isa_dev->bus = parent_isa_dev->bus;
		isa_dev->prom_node = node;
		isa_dev->prom_node = dp;
		prop_len = prom_getproperty(node, "name",
					    (char *) isa_dev->prom_name,
					    sizeof(isa_dev->prom_name));
		if (prop_len <= 0) {
			fatal_err("cannot get child isa_dev OBP node name");
			prom_halt();
		}

		prop_len = prom_getproperty(node, "compatible",
					    (char *) isa_dev->compatible,
					    sizeof(isa_dev->compatible));

		/* Not having this is OK. */
		if (prop_len <= 0)
			isa_dev->compatible[0] = '\0';


		isa_dev_get_resource(isa_dev, regs, sizeof(regs));
		regs = isa_dev_get_resource(isa_dev);
		isa_dev_get_irq(isa_dev, regs);
		isa_dev_get_irq(isa_dev, regs);


		report_dev(isa_dev, 1);
		report_dev(isa_dev, 1);


		node = prom_getsibling(node);
		dp = dp->sibling;
	}
	}
}
}


static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
{
{
	int node = prom_getchild(isa_br->prom_node);
	struct device_node *dp = isa_br->prom_node->child;


	while (node != 0) {
	while (dp) {
		struct linux_prom_registers regs[PROMREG_MAX];
		struct linux_prom_registers *regs;
		struct sparc_isa_device *isa_dev;
		struct sparc_isa_device *isa_dev;
		int prop_len;


		isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
		isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
		if (!isa_dev) {
		if (!isa_dev) {
@@ -222,24 +203,9 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
		}
		}


		isa_dev->bus = isa_br;
		isa_dev->bus = isa_br;
		isa_dev->prom_node = node;
		isa_dev->prom_node = dp;
		prop_len = prom_getproperty(node, "name",
					    (char *) isa_dev->prom_name,
					    sizeof(isa_dev->prom_name));
		if (prop_len <= 0) {
			fatal_err("cannot get isa_dev OBP node name");
			prom_halt();
		}

		prop_len = prom_getproperty(node, "compatible",
					    (char *) isa_dev->compatible,
					    sizeof(isa_dev->compatible));

		/* Not having this is OK. */
		if (prop_len <= 0)
			isa_dev->compatible[0] = '\0';


		isa_dev_get_resource(isa_dev, regs, sizeof(regs));
		regs = isa_dev_get_resource(isa_dev);
		isa_dev_get_irq(isa_dev, regs);
		isa_dev_get_irq(isa_dev, regs);


		report_dev(isa_dev, 0);
		report_dev(isa_dev, 0);
@@ -248,10 +214,40 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)


		printk("]");
		printk("]");


		node = prom_getsibling(node);
		dp = dp->sibling;
	}
	}
}
}


static void __init get_bridge_props(struct sparc_isa_bridge *isa_br)
{
	struct device_node *dp = isa_br->prom_node;
	void *pval;
	int len;

	pval = of_get_property(dp, "ranges", &len);
	if (pval) {
		memcpy(isa_br->isa_ranges, pval, len);
		isa_br->num_isa_ranges =
			len / sizeof(struct linux_prom_isa_ranges);
	} else {
		isa_br->num_isa_ranges = 0;
	}

	pval = of_get_property(dp, "interrupt-map", &len);
	if (pval) {
		memcpy(isa_br->isa_intmap, pval, len);
		isa_br->num_isa_intmap =
			(len / sizeof(struct linux_prom_isa_intmap));
	} else {
		isa_br->num_isa_intmap = 0;
	}

	pval = of_get_property(dp, "interrupt-map-mask", &len);
	if (pval)
		memcpy(&isa_br->isa_intmask, pval,
		       sizeof(isa_br->isa_intmask));
}

void __init isa_init(void)
void __init isa_init(void)
{
{
	struct pci_dev *pdev;
	struct pci_dev *pdev;
@@ -266,7 +262,6 @@ void __init isa_init(void)
		struct pcidev_cookie *pdev_cookie;
		struct pcidev_cookie *pdev_cookie;
		struct pci_pbm_info *pbm;
		struct pci_pbm_info *pbm;
		struct sparc_isa_bridge *isa_br;
		struct sparc_isa_bridge *isa_br;
		int prop_len;


		pdev_cookie = pdev->sysdata;
		pdev_cookie = pdev->sysdata;
		if (!pdev_cookie) {
		if (!pdev_cookie) {
@@ -291,34 +286,9 @@ void __init isa_init(void)
		isa_br->parent = pbm;
		isa_br->parent = pbm;
		isa_br->self = pdev;
		isa_br->self = pdev;
		isa_br->index = index++;
		isa_br->index = index++;
		isa_br->prom_node = pdev_cookie->prom_node->node;
		isa_br->prom_node = pdev_cookie->prom_node;
		strncpy(isa_br->prom_name, pdev_cookie->prom_node->name,
			sizeof(isa_br->prom_name));

		prop_len = prom_getproperty(isa_br->prom_node,
					    "ranges",
					    (char *) isa_br->isa_ranges,
					    sizeof(isa_br->isa_ranges));
		if (prop_len <= 0)
			isa_br->num_isa_ranges = 0;
		else
			isa_br->num_isa_ranges =
				(prop_len / sizeof(struct linux_prom_isa_ranges));


		prop_len = prom_getproperty(isa_br->prom_node,
		get_bridge_props(isa_br);
					    "interrupt-map",
					    (char *) isa_br->isa_intmap,
					    sizeof(isa_br->isa_intmap));
		if (prop_len <= 0)
			isa_br->num_isa_intmap = 0;
		else
			isa_br->num_isa_intmap =
				(prop_len / sizeof(struct linux_prom_isa_intmap));

		prop_len = prom_getproperty(isa_br->prom_node,
					    "interrupt-map-mask",
					    (char *) &(isa_br->isa_intmask),
					    sizeof(isa_br->isa_intmask));


		printk("isa%d:", isa_br->index);
		printk("isa%d:", isa_br->index);


+10 −10
Original line number Original line Diff line number Diff line
@@ -105,24 +105,24 @@ static int powerd(void *__unused)
	return 0;
	return 0;
}
}


static int __init has_button_interrupt(unsigned int irq, int prom_node)
static int __init has_button_interrupt(unsigned int irq, struct device_node *dp)
{
{
	if (irq == PCI_IRQ_NONE)
	if (irq == PCI_IRQ_NONE)
		return 0;
		return 0;
	if (!prom_node_has_property(prom_node, "button"))
	if (!of_find_property(dp, "button", NULL))
		return 0;
		return 0;


	return 1;
	return 1;
}
}


static int __init power_probe_ebus(struct resource **resp, unsigned int *irq_p, int *prom_node_p)
static int __init power_probe_ebus(struct resource **resp, unsigned int *irq_p, struct device_node **prom_node_p)
{
{
	struct linux_ebus *ebus;
	struct linux_ebus *ebus;
	struct linux_ebus_device *edev;
	struct linux_ebus_device *edev;


	for_each_ebus(ebus) {
	for_each_ebus(ebus) {
		for_each_ebusdev(edev, ebus) {
		for_each_ebusdev(edev, ebus) {
			if (!strcmp(edev->prom_name, "power")) {
			if (!strcmp(edev->prom_node->name, "power")) {
				*resp = &edev->resource[0];
				*resp = &edev->resource[0];
				*irq_p = edev->irqs[0];
				*irq_p = edev->irqs[0];
				*prom_node_p = edev->prom_node;
				*prom_node_p = edev->prom_node;
@@ -133,14 +133,14 @@ static int __init power_probe_ebus(struct resource **resp, unsigned int *irq_p,
	return -ENODEV;
	return -ENODEV;
}
}


static int __init power_probe_isa(struct resource **resp, unsigned int *irq_p, int *prom_node_p)
static int __init power_probe_isa(struct resource **resp, unsigned int *irq_p, struct device_node **prom_node_p)
{
{
	struct sparc_isa_bridge *isa_bus;
	struct sparc_isa_bridge *isa_bus;
	struct sparc_isa_device *isa_dev;
	struct sparc_isa_device *isa_dev;


	for_each_isa(isa_bus) {
	for_each_isa(isa_bus) {
		for_each_isadev(isa_dev, isa_bus) {
		for_each_isadev(isa_dev, isa_bus) {
			if (!strcmp(isa_dev->prom_name, "power")) {
			if (!strcmp(isa_dev->prom_node->name, "power")) {
				*resp = &isa_dev->resource;
				*resp = &isa_dev->resource;
				*irq_p = isa_dev->irq;
				*irq_p = isa_dev->irq;
				*prom_node_p = isa_dev->prom_node;
				*prom_node_p = isa_dev->prom_node;
@@ -155,17 +155,17 @@ void __init power_init(void)
{
{
	struct resource *res = NULL;
	struct resource *res = NULL;
	unsigned int irq;
	unsigned int irq;
	int prom_node;
	struct device_node *dp;
	static int invoked;
	static int invoked;


	if (invoked)
	if (invoked)
		return;
		return;
	invoked = 1;
	invoked = 1;


	if (!power_probe_ebus(&res, &irq, &prom_node))
	if (!power_probe_ebus(&res, &irq, &dp))
		goto found;
		goto found;


	if (!power_probe_isa(&res, &irq, &prom_node))
	if (!power_probe_isa(&res, &irq, &dp))
		goto found;
		goto found;


	return;
	return;
@@ -174,7 +174,7 @@ void __init power_init(void)
	power_reg = ioremap(res->start, 0x4);
	power_reg = ioremap(res->start, 0x4);
	printk("power: Control reg at %p ... ", power_reg);
	printk("power: Control reg at %p ... ", power_reg);
	poweroff_method = machine_halt;  /* able to use the standard halt */
	poweroff_method = machine_halt;  /* able to use the standard halt */
	if (has_button_interrupt(irq, prom_node)) {
	if (has_button_interrupt(irq, dp)) {
		if (kernel_thread(powerd, NULL, CLONE_FS) < 0) {
		if (kernel_thread(powerd, NULL, CLONE_FS) < 0) {
			printk("Failed to start power daemon.\n");
			printk("Failed to start power daemon.\n");
			return;
			return;
+1 −0
Original line number Original line Diff line number Diff line
@@ -63,6 +63,7 @@ struct device_node *of_find_node_by_path(const char *path)


	return np;
	return np;
}
}
EXPORT_SYMBOL(of_find_node_by_path);


struct device_node *of_find_node_by_phandle(phandle handle)
struct device_node *of_find_node_by_phandle(phandle handle)
{
{
Loading