Esempio n. 1
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();
}
Esempio n. 2
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();
}
Esempio n. 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;
	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? */
}