예제 #1
0
__initfunc(void ebus_init(void))
{
    struct linux_prom_pci_registers regs[PROMREG_MAX];
    struct linux_pbm_info *pbm;
    struct linux_ebus_device *dev;
    struct linux_ebus *ebus;
    struct pci_dev *pdev;
    struct pcidev_cookie *cookie;
    char lbuf[128];
    unsigned long addr, *base;
    unsigned short pci_command;
    int nd, len, ebusnd;
    int reg, rng, nreg;
    int num_ebus = 0;

    if (!pci_present())
        return;

    pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, 0);
    if (!pdev) {
        printk("ebus: No EBus's found.\n");
#ifdef PROM_DEBUG
        dprintf("ebus: No EBus's found.\n");
#endif
        return;
    }

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

    ebus_chain = ebus = (struct linux_ebus *)
                        ebus_alloc(sizeof(struct linux_ebus));
    ebus->next = 0;

    while (ebusnd) {
        printk("ebus%d:", num_ebus);
#ifdef PROM_DEBUG
        dprintf("ebus%d:", num_ebus);
#endif

        prom_getstring(ebusnd, "name", lbuf, sizeof(lbuf));
        ebus->prom_node = ebusnd;
        strcpy(ebus->prom_name, lbuf);

        ebus->self = pdev;
        ebus->parent = pbm = cookie->pbm;

        /* Enable BUS Master. */
        pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
        pci_command |= PCI_COMMAND_MASTER;
        pci_write_config_word(pdev, PCI_COMMAND, pci_command);

        len = prom_getproperty(ebusnd, "reg", (void *)regs,
                               sizeof(regs));
        if (len == 0 || len == -1) {
            prom_printf("%s: can't find reg property\n",
                        __FUNCTION__);
            prom_halt();
        }
        nreg = len / sizeof(struct linux_prom_pci_registers);

        base = &ebus->self->base_address[0];
        for (reg = 0; reg < nreg; reg++) {
            if (!(regs[reg].phys_hi & 0x03000000))
                continue;

            for (rng = 0; rng < pbm->num_pbm_ranges; rng++) {
                struct linux_prom_pci_ranges *rp =
                        &pbm->pbm_ranges[rng];

                if ((rp->child_phys_hi ^ regs[reg].phys_hi)
                        & 0x03000000)
                    continue;

                addr = (u64)regs[reg].phys_lo;
                addr += (u64)regs[reg].phys_mid << 32UL;
                addr += (u64)rp->parent_phys_lo;
                addr += (u64)rp->parent_phys_hi << 32UL;
                *base++ = (unsigned long)__va(addr);

                printk(" %lx[%x]", (unsigned long)__va(addr),
                       regs[reg].size_lo);
#ifdef PROM_DEBUG
                dprintf(" %lx[%x]", (unsigned long)__va(addr),
                        regs[reg].size_lo);
#endif
                break;
            }
        }
        printk("\n");
#ifdef PROM_DEBUG
        dprintf("\n");
#endif

        prom_ebus_ranges_init(ebus);
        prom_ebus_intmap_init(ebus);

        nd = prom_getchild(ebusnd);
        if (!nd)
            goto next_ebus;

        ebus->devices = (struct linux_ebus_device *)
                        ebus_alloc(sizeof(struct linux_ebus_device));

        dev = ebus->devices;
        dev->next = 0;
        dev->children = 0;
        dev->bus = ebus;
        fill_ebus_device(nd, dev);

        while ((nd = prom_getsibling(nd))) {
            dev->next = (struct linux_ebus_device *)
                        ebus_alloc(sizeof(struct linux_ebus_device));

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

next_ebus:
        pdev = pci_find_device(PCI_VENDOR_ID_SUN,
                               PCI_DEVICE_ID_SUN_EBUS, pdev);
        if (!pdev)
            break;

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

        ebus->next = (struct linux_ebus *)
                     ebus_alloc(sizeof(struct linux_ebus));
        ebus = ebus->next;
        ebus->next = 0;
        ++num_ebus;
    }

#ifdef CONFIG_SUN_OPENPROMIO
    openprom_init();
#endif
#ifdef CONFIG_SPARCAUDIO
    sparcaudio_init();
#endif
#ifdef CONFIG_SUN_BPP
    bpp_init();
#endif
#ifdef CONFIG_SUN_AUXIO
    auxio_probe();
#endif
#ifdef CONFIG_ENVCTRL
    envctrl_init();
#endif
#ifdef CONFIG_OBP_FLASH
    flash_init();
#endif
    clock_probe();
}
예제 #2
0
__initfunc(void fill_ebus_device(int node, struct linux_ebus_device *dev))
{
    struct linux_prom_registers regs[PROMREG_MAX];
    struct linux_ebus_child *child;
    int irqs[PROMINTR_MAX];
    char lbuf[128];
    int i, n, len;

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

    len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs));
    if (len % sizeof(struct linux_prom_registers)) {
        prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
                    dev->prom_name, len,
                    (int)sizeof(struct linux_prom_registers));
        panic(__FUNCTION__);
    }
    dev->num_addrs = len / sizeof(struct linux_prom_registers);

    for (i = 0; i < dev->num_addrs; i++) {
        n = (regs[i].which_io - 0x10) >> 2;

        dev->base_address[i] = dev->bus->self->base_address[n];
        dev->base_address[i] += (unsigned long)regs[i].phys_addr;
    }

    len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
    if ((len == -1) || (len == 0)) {
        dev->num_irqs = 0;
    } else {
        dev->num_irqs = len / sizeof(irqs[0]);
        for (i = 0; i < dev->num_irqs; i++) {
            ebus_intmap_match(dev->bus, &regs[0], &irqs[i]);
            dev->irqs[i] = psycho_irq_build(dev->bus->parent,
                                            dev->bus->self, irqs[i]);
        }
    }

#ifdef DEBUG_FILL_EBUS_DEV
    dprintf("'%s': address%s\n", dev->prom_name,
            dev->num_addrs > 1 ? "es" : "");
    for (i = 0; i < dev->num_addrs; i++)
        dprintf("  %016lx\n", dev->base_address[i]);
    if (dev->num_irqs) {
        dprintf("  IRQ%s", dev->num_irqs > 1 ? "s" : "");
        for (i = 0; i < dev->num_irqs; i++)
            dprintf(" %s", __irq_itoa(dev->irqs[i]));
        dprintf("\n");
    }
#endif
    if ((node = prom_getchild(node))) {
        dev->children = (struct linux_ebus_child *)
                        ebus_alloc(sizeof(struct linux_ebus_child));

        child = dev->children;
        child->next = 0;
        child->parent = dev;
        child->bus = dev->bus;
        fill_ebus_child(node, &regs[0], child);

        while ((node = prom_getsibling(node))) {
            child->next = (struct linux_ebus_child *)
                          ebus_alloc(sizeof(struct linux_ebus_child));

            child = child->next;
            child->next = 0;
            child->parent = dev;
            child->bus = dev->bus;
            fill_ebus_child(node, &regs[0], child);
        }
    }
}
예제 #3
0
void __init ebus_init(void)
{
	struct pci_pbm_info *pbm;
	struct linux_ebus_device *dev;
	struct linux_ebus *ebus;
	struct pci_dev *pdev;
	struct pcidev_cookie *cookie;
	int nd, ebusnd;
	int num_ebus = 0;

	if (!pci_present())
		return;

	pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, 0);
	if (!pdev) {
		printk("ebus: No EBus's found.\n");
		return;
	}

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

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

	while (ebusnd) {
		/* 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)) {
			pdev = pci_find_device(PCI_VENDOR_ID_SUN, 
					       PCI_DEVICE_ID_SUN_EBUS, pdev);
			if (!pdev) {
				if (ebus == ebus_chain) {
					ebus_chain = NULL;
					printk("ebus: No EBus's found.\n");
					return;
				}
				break;
			}
			
			cookie = pdev->sysdata;
			ebusnd = 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->self = pdev;
		ebus->parent = pbm = cookie->pbm;

		ebus_ranges_init(ebus);
		ebus_intmap_init(ebus);

		nd = prom_getchild(ebusnd);
		if (!nd)
			goto next_ebus;

		ebus->devices = ebus_alloc(sizeof(struct linux_ebus_device));

		dev = ebus->devices;
		dev->next = 0;
		dev->children = 0;
		dev->bus = ebus;
		fill_ebus_device(nd, dev);

		while ((nd = prom_getsibling(nd))) {
			dev->next = ebus_alloc(sizeof(struct linux_ebus_device));

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

	next_ebus:
		printk("\n");

		pdev = pci_find_device(PCI_VENDOR_ID_SUN,
				       PCI_DEVICE_ID_SUN_EBUS, pdev);
		if (!pdev)
			break;

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

		ebus->next = ebus_alloc(sizeof(struct linux_ebus));
		ebus = ebus->next;
		ebus->next = 0;
		++num_ebus;
	}

#ifdef CONFIG_SUN_AUXIO
	auxio_probe();
#endif
	clock_probe();
	power_init();
}
예제 #4
0
void __init fill_ebus_device(int node, struct linux_ebus_device *dev)
{
	struct linux_prom_registers regs[PROMREG_MAX];
	struct linux_ebus_child *child;
	int irqs[PROMINTR_MAX];
	int i, n, len;

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

	len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs));
	if (len % sizeof(struct linux_prom_registers)) {
		prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
			    dev->prom_name, len,
			    (int)sizeof(struct linux_prom_registers));
		prom_halt();
	}
	dev->num_addrs = len / sizeof(struct linux_prom_registers);

	for (i = 0; i < dev->num_addrs; i++) {
		n = (regs[i].which_io - 0x10) >> 2;

		dev->resource[i].start  = dev->bus->self->resource[n].start;
		dev->resource[i].start += (unsigned long)regs[i].phys_addr;
		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;
		request_resource(&dev->bus->self->resource[n],
				 &dev->resource[i]);
	}

	len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
	if ((len == -1) || (len == 0)) {
		dev->num_irqs = 0;
	} else {
		dev->num_irqs = len / sizeof(irqs[0]);
		for (i = 0; i < dev->num_irqs; i++) {
			struct pci_pbm_info *pbm = dev->bus->parent;
			struct pci_controller_info *p = pbm->parent;

			if (ebus_intmap_match(dev->bus, &regs[0], &irqs[i]) != -1) {
				dev->irqs[i] = p->irq_build(p,
							    dev->bus->self,
							    irqs[i]);
			} else {
				/* If we get a bogus interrupt property, just
				 * record the raw value instead of punting.
				 */
				dev->irqs[i] = irqs[i];
			}
		}
	}

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

		child = dev->children;
		child->next = 0;
		child->parent = dev;
		child->bus = dev->bus;
		fill_ebus_child(node, &regs[0],
				child, child_regs_nonstandard(dev));

		while ((node = prom_getsibling(node))) {
			child->next = ebus_alloc(sizeof(struct linux_ebus_child));

			child = child->next;
			child->next = 0;
			child->parent = dev;
			child->bus = dev->bus;
			fill_ebus_child(node, &regs[0],
					child, child_regs_nonstandard(dev));
		}
	}
	printk("]");
}
예제 #5
0
파일: ebus.c 프로젝트: JBTech/ralink_sdk
void __init ebus_init(void)
{
	struct pci_pbm_info *pbm;
	struct linux_ebus_device *dev;
	struct linux_ebus *ebus;
	struct pci_dev *pdev;
	struct pcidev_cookie *cookie;
	struct device_node *dp;
	int is_rio;
	int num_ebus = 0;

	pdev = find_next_ebus(NULL, &is_rio);
	if (!pdev) {
		printk("ebus: No EBus's found.\n");
		return;
	}

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

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

	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 (!dp->child) {
			pdev = find_next_ebus(pdev, &is_rio);
			if (!pdev) {
				if (ebus == ebus_chain) {
					ebus_chain = NULL;
					printk("ebus: No EBus's found.\n");
					return;
				}
				break;
			}
			ebus->is_rio = is_rio;
			cookie = pdev->sysdata;
			dp = cookie->prom_node;
			continue;
		}
		printk("ebus%d:", num_ebus);

		ebus->index = num_ebus;
		ebus->prom_node = dp;
		ebus->self = pdev;
		ebus->parent = pbm = cookie->pbm;

		ebus->ofdev.node = dp;
		ebus->ofdev.dev.parent = &pdev->dev;
		ebus->ofdev.dev.bus = &ebus_bus_type;
		sprintf(ebus->ofdev.dev.bus_id, "ebus%d", num_ebus);

		/* Register with core */
		if (of_device_register(&ebus->ofdev) != 0)
			printk(KERN_DEBUG "ebus: device registration error for %s!\n",
			       dp->path_component_name);


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

		ebus->devices = ebus_alloc(sizeof(struct linux_ebus_device));

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

		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(child, dev);
		}

	next_ebus:
		printk("\n");

		pdev = find_next_ebus(pdev, &is_rio);
		if (!pdev)
			break;

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

		ebus->next = ebus_alloc(sizeof(struct linux_ebus));
		ebus = ebus->next;
		ebus->next = NULL;
		ebus->is_rio = is_rio;
		++num_ebus;
	}
	pci_dev_put(pdev); /* XXX for the case, when ebusnd is 0, is it OK? */
}
예제 #6
0
파일: ebus.c 프로젝트: JBTech/ralink_sdk
static void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev)
{
	struct linux_ebus_child *child;
	struct of_device *op;
	int i, len;

	dev->prom_node = dp;

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

	op = of_find_device_by_node(dp);
	if (!op) {
		dev->num_addrs = 0;
		dev->num_irqs = 0;
	} else {
		(void) of_get_property(dp, "reg", &len);
		dev->num_addrs = len / sizeof(struct linux_prom_registers);

		for (i = 0; i < dev->num_addrs; i++)
			memcpy(&dev->resource[i],
			       &op->resource[i],
			       sizeof(struct resource));

		dev->num_irqs = op->num_irqs;
		for (i = 0; i < dev->num_irqs; i++)
			dev->irqs[i] = op->irqs[i];
	}

	dev->ofdev.node = dp;
	dev->ofdev.dev.parent = &dev->bus->ofdev.dev;
	dev->ofdev.dev.bus = &ebus_bus_type;
	sprintf(dev->ofdev.dev.bus_id, "ebus[%08x]", dp->node);

	/* Register with core */
	if (of_device_register(&dev->ofdev) != 0)
		printk(KERN_DEBUG "ebus: device registration error for %s!\n",
		       dp->path_component_name);

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

		child = dev->children;
		child->next = NULL;
		child->parent = dev;
		child->bus = dev->bus;
		fill_ebus_child(dp, child,
				child_regs_nonstandard(dev));

		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(dp, child,
					child_regs_nonstandard(dev));
		}
	}
	printk("]");
}