Пример #1
0
static int __init ts102_uctrl_init(void)
{
	struct uctrl_driver *driver = &drv;
	int len, i;
	struct linux_prom_irqs tmp_irq[2];
        unsigned int vaddr[2] = { 0, 0 };
	int tmpnode, uctrlnode = prom_getchild(prom_root_node);

	tmpnode = prom_searchsiblings(uctrlnode, "obio");

	if (tmpnode)
	  uctrlnode = prom_getchild(tmpnode);

	uctrlnode = prom_searchsiblings(uctrlnode, "uctrl");

	if (!uctrlnode)
		return -ENODEV;

	/* the prom mapped it for us */
	len = prom_getproperty(uctrlnode, "address", (void *) vaddr,
			       sizeof(vaddr));
	driver->regs = (struct uctrl_regs *)vaddr[0];

	len = prom_getproperty(uctrlnode, "intr", (char *) tmp_irq,
			       sizeof(tmp_irq));

	/* Flush device */
	READUCTLDATA(len);

	if(!driver->irq) 
		driver->irq = tmp_irq[0].pri;

	request_irq(driver->irq, uctrl_interrupt, 0, 
		    "uctrl", driver);

	enable_irq(driver->irq);

	if (misc_register(&uctrl_dev)) {
		printk("%s: unable to get misc minor %d\n",
		       __FUNCTION__, uctrl_dev.minor);
		disable_irq(driver->irq);
		free_irq(driver->irq, driver);
		return -ENODEV;
	}

	driver->regs->uctrl_intr = UCTRL_INTR_RXNE_REQ|UCTRL_INTR_RXNE_MSK;
	printk("uctrl: 0x%x (irq %s)\n", driver->regs, __irq_itoa(driver->irq));
	uctrl_get_event_status();
	uctrl_get_external_status();
        return 0;
}
Пример #2
0
int
init_one_port(struct linux_ebus_device *dev)
{
    struct parport tmpport, *p;
    unsigned long base;
    unsigned long config;
    int irq, dma;

    /* Pointer to NS87303 Configuration Registers */
    config = dev->base_address[1];

    /* Setup temporary access to Device operations */
    tmpport.base = dev->base_address[0];
    tmpport.ops = &parport_ax_ops;

    /* Configure IRQ to Push Pull, Level Low */
    /* Enable ECP mode, set bit 2 of the CTR first */
    tmpport.ops->write_control(&tmpport, 0x04);
    ns87303_modify(config, PCR,
                   PCR_EPP_ENABLE | PCR_IRQ_ODRAIN,
                   PCR_ECP_ENABLE | PCR_ECP_CLK_ENA | PCR_IRQ_POLAR);

    /* LPT CTR bit 5 controls direction of parallel port */
    ns87303_modify(config, PTR, 0, PTR_LPT_REG_DIR);

    /*
     * Now continue initializing the port
     */
    base = dev->base_address[0];
    irq = dev->irqs[0];
    dma = PARPORT_DMA_AUTO;

    if (!(p = parport_register_port(base, irq, dma, &parport_ax_ops)))
        return 0;

    /* Save away pointer to our EBus DMA */
    p->private_data = (void *)dev->base_address[2];

    p->modes = PARPORT_MODE_PCSPP | parport_PS2_supported(p);
    if (!check_region(p->base + 0x400, 3)) {
        p->modes |= parport_ECR_present(p);
        p->modes |= parport_ECP_supported(p);
        p->modes |= parport_ECPPS2_supported(p);
    }
    p->size = 3;

    if (p->dma == PARPORT_DMA_AUTO)
        p->dma = (p->modes & PARPORT_MODE_PCECP) ? 0 : PARPORT_DMA_NONE;

    printk(KERN_INFO "%s: PC-style at 0x%lx", p->name, p->base);
    if (p->irq != PARPORT_IRQ_NONE)
        printk(", irq %s", __irq_itoa(p->irq));
    if (p->dma != PARPORT_DMA_NONE)
        printk(", dma %d", p->dma);
    printk(" [");
    {
        int f = 0;
        printmode(SPP);
        printmode(PS2);
        printmode(ECP);
        printmode(ECPPS2);
    }
    printk("]\n");
    parport_proc_register(p);
    p->flags |= PARPORT_FLAG_COMA;

    p->ops->write_control(p, 0x0c);
    p->ops->write_data(p, 0);

    if (parport_probe_hook)
        (*parport_probe_hook)(p);

    return 1;
}
Пример #3
0
__initfunc(void fill_ebus_child(int node, struct linux_prom_registers *preg,
                                struct linux_ebus_child *dev))
{
    int regs[PROMREG_MAX];
    int irqs[PROMREG_MAX];
    char lbuf[128];
    int i, 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));
    dev->num_addrs = len / sizeof(regs[0]);

    for (i = 0; i < dev->num_addrs; i++) {
        if (regs[i] >= 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__);
        }
        dev->base_address[i] = dev->parent->base_address[regs[i]];
    }

    len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
    if ((len == -1) || (len == 0)) {
        dev->num_irqs = 0;
        /*
         * Oh, well, some PROMs don't export interrupts
         * property to children of EBus devices...
         *
         * Be smart about PS/2 keyboard and mouse.
         */
        if (!strcmp(dev->parent->prom_name, "8042")) {
            if (!strcmp(dev->prom_name, "kb_ps2")) {
                dev->num_irqs = 1;
                dev->irqs[0] = dev->parent->irqs[0];
            } else {
                dev->num_irqs = 1;
                dev->irqs[0] = dev->parent->irqs[1];
            }
        }
    } else {
        dev->num_irqs = len / sizeof(irqs[0]);
        for (i = 0; i < dev->num_irqs; i++) {
            ebus_intmap_match(dev->bus, preg, &irqs[i]);
            dev->irqs[i] = psycho_irq_build(dev->bus->parent,
                                            dev->bus->self, irqs[i]);
        }
    }

#ifdef DEBUG_FILL_EBUS_DEV
    dprintf("child '%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
}
Пример #4
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);
        }
    }
}
Пример #5
0
/**
 * usb_hcd_pci_probe - initialize PCI-based HCDs
 * @dev: USB Host Controller being probed
 * @id: pci hotplug id connecting controller to HCD framework
 * Context: !in_interrupt()
 *
 * Allocates basic PCI resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 *
 * Store this function in the HCD's struct pci_driver as probe().
 */
int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
{
    struct hc_driver	*driver;
    unsigned long		resource, len;
    void __iomem		*base;
    struct usb_hcd		*hcd;
    int			retval, region;
    char			buf [8], *bufp = buf;

    if (usb_disabled())
        return -ENODEV;

    if (!id || !(driver = (struct hc_driver *) id->driver_data))
        return -EINVAL;

    if (pci_enable_device (dev) < 0)
        return -ENODEV;
    dev->current_state = 0;
    dev->dev.power.power_state = 0;

    if (!dev->irq) {
        dev_err (&dev->dev,
                 "Found HC with no IRQ.  Check BIOS/PCI %s setup!\n",
                 pci_name(dev));
        retval = -ENODEV;
        goto done;
    }

    if (driver->flags & HCD_MEMORY) {	// EHCI, OHCI
        region = 0;
        resource = pci_resource_start (dev, 0);
        len = pci_resource_len (dev, 0);
        if (!request_mem_region (resource, len, driver->description)) {
            dev_dbg (&dev->dev, "controller already in use\n");
            retval = -EBUSY;
            goto done;
        }
        base = ioremap_nocache (resource, len);
        if (base == NULL) {
            dev_dbg (&dev->dev, "error mapping memory\n");
            retval = -EFAULT;
clean_1:
            release_mem_region (resource, len);
            dev_err (&dev->dev, "init %s fail, %d\n",
                     pci_name(dev), retval);
            goto done;
        }

    } else { 				// UHCI
        resource = len = 0;
        for (region = 0; region < PCI_ROM_RESOURCE; region++) {
            if (!(pci_resource_flags (dev, region) & IORESOURCE_IO))
                continue;

            resource = pci_resource_start (dev, region);
            len = pci_resource_len (dev, region);
            if (request_region (resource, len,
                                driver->description))
                break;
        }
        if (region == PCI_ROM_RESOURCE) {
            dev_dbg (&dev->dev, "no i/o regions available\n");
            retval = -EBUSY;
            goto done;
        }
        base = (void __iomem *) resource;
    }

    // driver->reset(), later on, will transfer device from
    // control by SMM/BIOS to control by Linux (if needed)

    hcd = driver->hcd_alloc ();
    if (hcd == NULL) {
        dev_dbg (&dev->dev, "hcd alloc fail\n");
        retval = -ENOMEM;
clean_2:
        if (driver->flags & HCD_MEMORY) {
            iounmap (base);
            goto clean_1;
        } else {
            release_region (resource, len);
            dev_err (&dev->dev, "init %s fail, %d\n",
                     pci_name(dev), retval);
            goto done;
        }
    }
    // hcd zeroed everything
    hcd->regs = base;
    hcd->region = region;

    pci_set_drvdata (dev, hcd);
    hcd->driver = driver;
    hcd->description = driver->description;
    hcd->self.bus_name = pci_name(dev);
#ifdef CONFIG_PCI_NAMES
    hcd->product_desc = dev->pretty_name;
#else
    if (hcd->product_desc == NULL)
        hcd->product_desc = "USB Host Controller";
#endif
    hcd->self.controller = &dev->dev;

    if ((retval = hcd_buffer_create (hcd)) != 0) {
clean_3:
        kfree (hcd);
        goto clean_2;
    }

    dev_info (hcd->self.controller, "%s\n", hcd->product_desc);

    /* till now HC has been in an indeterminate state ... */
    if (driver->reset && (retval = driver->reset (hcd)) < 0) {
        dev_err (hcd->self.controller, "can't reset\n");
        goto clean_3;
    }
    hcd->state = USB_STATE_HALT;

    pci_set_master (dev);
#ifndef __sparc__
    sprintf (buf, "%d", dev->irq);
#else
    bufp = __irq_itoa(dev->irq);
#endif
    retval = request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ,
                          hcd->description, hcd);
    if (retval != 0) {
        dev_err (hcd->self.controller,
                 "request interrupt %s failed\n", bufp);
        goto clean_3;
    }
    hcd->irq = dev->irq;

    dev_info (hcd->self.controller, "irq %s, %s 0x%lx\n", bufp,
              (driver->flags & HCD_MEMORY) ? "pci mem" : "io base",
              resource);

    usb_bus_init (&hcd->self);
    hcd->self.op = &usb_hcd_operations;
    hcd->self.release = &usb_hcd_release;
    hcd->self.hcpriv = (void *) hcd;
    init_timer (&hcd->rh_timer);

    INIT_LIST_HEAD (&hcd->dev_list);

    usb_register_bus (&hcd->self);

    if ((retval = driver->start (hcd)) < 0) {
        dev_err (hcd->self.controller, "init error %d\n", retval);
        usb_hcd_pci_remove (dev);
    }

done:
    if (retval != 0)
        pci_disable_device (dev);
    return retval;
}
Пример #6
0
int usb_hcd_amba_probe (struct amba_device *dev, void *vid)
{
	int			retval = 0;
	char			buf [8], *bufp = buf;
	struct usb_bus		*bus = NULL;
	struct usb_hcd 		*hcd = NULL;
	void 			*device_base = NULL;
	struct amba_id *id 	= (struct amba_id *)vid;
	struct hc_driver	*driver = (struct hc_driver *)id->data;

#if defined (CONFIG_USB_EHCI_PNX0106) && defined (GPIO_USB_POWER_FAULT)
	init_timer (&timer_check_usb_power_fault);
	timer_check_usb_power_fault.function = check_usb_power_fault_func;
	timer_check_usb_power_fault.data = 0;
#endif
	proc_vbus_init();

	usb2ip_init (dev);

	if (driver->flags & HCD_MEMORY) {	// EHCI, OHCI
		/* map the address (already requested by amba_device) */
		device_base = ioremap_nocache( dev->res.start, dev->res.end - dev->res.start + 1 ) ;
		if ( !device_base ) {
			printk( KERN_ERR "%s: failed to remap the amba registers\n", __FUNCTION__) ;
			return -1 ;
		}
	} else {
		printk (KERN_ERR "%s: tried to allocate i/o memory for UHCI\n", __FUNCTION__);
	}


	hcd = driver->hcd_alloc ();
	if (hcd == NULL) {
		printk(KERN_DEBUG "%s: hcd alloc fail\n", __FUNCTION__);
		retval = -ENOMEM;
clean_1:
		if (driver->flags & HCD_MEMORY) {
			iounmap (device_base);
			device_base = 0;
		}
		printk(KERN_DEBUG "hcd-amba::init usb_amba fail, %d\n", retval);
		goto done;
	}
	// hcd zeroed everything
	hcd->regs = device_base;

	//amba_set_drvdata (dev, hcd);
	hcd->pdev = dev;
	hcd->driver = driver;
	hcd->description = driver->description;

	if (hcd->product_desc == NULL)
		hcd->product_desc = "USB EHCI 1.0 Host Controller (amba)";

	hcd->state = USB_STATE_HALT;

#ifndef __sparc__
	sprintf (buf, "%d", dev->irq[0]);
#else
	bufp = __irq_itoa(dev->irq[0]);
#endif

	/* request the irq (there should be one) */
	retval = request_irq (dev->irq[0], hcd_irq, 0/*SA_SHIRQ*/, "usb_ehci", hcd);
	if (retval) {
		printk(KERN_ERR	"hcd-amba.c :: request interrupt %s failed\n", bufp);
		retval = -EBUSY;
		goto clean_1;
	}
	hcd->irq = dev->irq[0];

	bus = usb_alloc_bus (&hcd_operations);
	if (bus == NULL) {
		printk(KERN_ERR "usb_alloc_bus fail\n");
		retval = -ENOMEM;
		free_irq (dev->irq, hcd);
		goto clean_1;
	}

	hcd->bus = bus;
	strcpy(dev->slot_name, "1");
	bus->bus_name = dev->slot_name;
	bus->hcpriv = (void *) hcd;

	INIT_LIST_HEAD (&hcd->dev_list);
	INIT_LIST_HEAD (&hcd->hcd_list);

	down (&hcd_list_lock);
	list_add (&hcd->hcd_list, &hcd_list);
	up (&hcd_list_lock);

	usb_register_bus (bus);

	if ((retval = driver->start (hcd)) < 0)
		usb_hcd_amba_remove (dev);

done:
	return retval;
}
Пример #7
0
/**
 * usb_hcd_pci_probe - initialize PCI-based HCDs
 * @dev: USB Host Controller being probed
 * @id: pci hotplug id connecting controller to HCD framework
 * Context: !in_interrupt()
 *
 * Allocates basic PCI resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 *
 * Store this function in the HCD's struct pci_driver as probe().
 */
int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
{
	struct hc_driver	*driver;
	unsigned long		resource, len;
	void			*base;
	struct usb_hcd		*hcd;
	int			retval, region;
	char			buf [8], *bufp = buf;

	if (usb_disabled())
		return -ENODEV;

	if (!id || !(driver = (struct hc_driver *) id->driver_data))
		return -EINVAL;

	if (pci_enable_device (dev) < 0)
		return -ENODEV;

        if (!dev->irq) {
        	err ("Found HC with no IRQ.  Check BIOS/PCI %s setup!",
			dev->slot_name);
   	        return -ENODEV;
        }

	if (driver->flags & HCD_MEMORY) {	// EHCI, OHCI
		region = 0;
		resource = pci_resource_start (dev, 0);
		len = pci_resource_len (dev, 0);
		if (!request_mem_region (resource, len, driver->description)) {
			dbg ("controller already in use");
			return -EBUSY;
		}
		base = ioremap_nocache (resource, len);
		if (base == NULL) {
			dbg ("error mapping memory");
			retval = -EFAULT;
clean_1:
			release_mem_region (resource, len);
			err ("init %s fail, %d", dev->slot_name, retval);
			return retval;
		}

	} else { 				// UHCI
		resource = len = 0;
		for (region = 0; region < PCI_ROM_RESOURCE; region++) {
			if (!(pci_resource_flags (dev, region) & IORESOURCE_IO))
				continue;

			resource = pci_resource_start (dev, region);
			len = pci_resource_len (dev, region);
			if (request_region (resource, len,
					driver->description))
				break;
		}
		if (region == PCI_ROM_RESOURCE) {
			dbg ("no i/o regions available");
			return -EBUSY;
		}
		base = (void *) resource;
	}

	// driver->start(), later on, will transfer device from
	// control by SMM/BIOS to control by Linux (if needed)

	pci_set_master (dev);

	hcd = driver->hcd_alloc ();
	if (hcd == NULL){
		dbg ("hcd alloc fail");
		retval = -ENOMEM;
clean_2:
		if (driver->flags & HCD_MEMORY) {
			iounmap (base);
			goto clean_1;
		} else {
			release_region (resource, len);
			err ("init %s fail, %d", dev->slot_name, retval);
			return retval;
		}
	}
	pci_set_drvdata (dev, hcd);
	hcd->driver = driver;
	hcd->description = driver->description;
	hcd->pdev = dev;
	hcd->self.bus_name = dev->slot_name;
	hcd->product_desc = dev->dev.name;
	hcd->self.controller = &dev->dev;
	hcd->controller = hcd->self.controller;

	if ((retval = hcd_buffer_create (hcd)) != 0) {
clean_3:
		driver->hcd_free (hcd);
		goto clean_2;
	}

	dev_info (hcd->controller, "%s\n", hcd->product_desc);

#ifndef __sparc__
	sprintf (buf, "%d", dev->irq);
#else
	bufp = __irq_itoa(dev->irq);
#endif
	if (request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ, hcd->description, hcd)
			!= 0) {
		dev_err (hcd->controller,
				"request interrupt %s failed\n", bufp);
		retval = -EBUSY;
		goto clean_3;
	}
	hcd->irq = dev->irq;

	hcd->regs = base;
	hcd->region = region;
	dev_info (hcd->controller, "irq %s, %s %p\n", bufp,
		(driver->flags & HCD_MEMORY) ? "pci mem" : "io base",
		base);

	usb_bus_init (&hcd->self);
	hcd->self.op = &usb_hcd_operations;
	hcd->self.hcpriv = (void *) hcd;

	INIT_LIST_HEAD (&hcd->dev_list);

	usb_register_bus (&hcd->self);

	if ((retval = driver->start (hcd)) < 0)
		usb_hcd_pci_remove (dev);

	return retval;
} 
Пример #8
0
static int __devinit
hc_found_ohci (struct pci_dev *dev, int irq,
	void *mem_base, const struct pci_device_id *id)
{
	ohci_t * ohci;
	char buf[8], *bufp = buf;
	int ret;

#ifndef __sparc__
	sprintf(buf, "%d", irq);
#else
	bufp = __irq_itoa(irq);
#endif
	printk(KERN_INFO __FILE__ ": USB OHCI at membase 0x%lx, IRQ %s\n",
		(unsigned long)	mem_base, bufp);
	printk(KERN_INFO __FILE__ ": usb-%s, %s\n", dev->slot_name, dev->name);
    
	ohci = hc_alloc_ohci (dev, mem_base);
	if (!ohci) {
		return -ENOMEM;
	}
	if ((ret = ohci_mem_init (ohci)) < 0) {
		hc_release_ohci (ohci);
		return ret;
	}
	ohci->flags = id->driver_data;

	/* Check for NSC87560. We have to look at the bridge (fn1) to identify
	   the USB (fn2). This quirk might apply to more or even all NSC stuff
	   I don't know.. */
	   
	if(dev->vendor == PCI_VENDOR_ID_NS)
	{
		struct pci_dev *fn1  = pci_find_slot(dev->bus->number, PCI_DEVFN(PCI_SLOT(dev->devfn), 1));
		if(fn1 && fn1->vendor == PCI_VENDOR_ID_NS && fn1->device == PCI_DEVICE_ID_NS_87560_LIO)
			ohci->flags |= OHCI_QUIRK_SUCKYIO;
		
	}
	
	if (ohci->flags & OHCI_QUIRK_SUCKYIO)
		printk (KERN_INFO __FILE__ ": Using NSC SuperIO setup\n");
	if (ohci->flags & OHCI_QUIRK_AMD756)
		printk (KERN_INFO __FILE__ ": AMD756 erratum 4 workaround\n");
	if (hc_reset (ohci) < 0) {
		hc_release_ohci (ohci);
		return -ENODEV;
	}

	/* FIXME this is a second HC reset; why?? */
	writel (ohci->hc_control = OHCI_USB_RESET, &ohci->regs->control);
	wait_ms (10);

	usb_register_bus (ohci->bus);
	
	if (request_irq (irq, hc_interrupt, SA_SHIRQ,
			ohci_pci_driver.name, ohci) != 0) {
		err ("request interrupt %s failed", bufp);
		hc_release_ohci (ohci);
		return -EBUSY;
	}
	ohci->irq = irq;     

	if (hc_start (ohci) < 0) {
		err ("can't start usb-%s", dev->slot_name);
		hc_release_ohci (ohci);
		return -EBUSY;
	}

#ifdef	DEBUG
	ohci_dump (ohci, 1);
#endif
	return 0;
}
Пример #9
0
__initfunc(static void
fill_sbus_device(int nd, struct linux_sbus_device *sbus_dev))
{
	int grrr, len;
	unsigned long dev_base_addr, base;

	sbus_dev->prom_node = nd;
	prom_getstring(nd, "name", lbuf, sizeof(lbuf));
	strcpy(sbus_dev->prom_name, lbuf);

	dev_base_addr = prom_getint(nd, "address");
	if(dev_base_addr != -1)
		sbus_dev->sbus_addr = dev_base_addr;

	len = prom_getproperty(nd, "reg", (void *) sbus_dev->reg_addrs,
			       sizeof(sbus_dev->reg_addrs));
	if(len == -1)
		goto no_regs;
	if(len%sizeof(struct linux_prom_registers)) {
		prom_printf("WHOOPS:  proplen for %s was %d, need multiple of %d\n",
		       sbus_dev->prom_name, len,
		       (int) sizeof(struct linux_prom_registers));
		panic("fill_sbus_device");
	}
	sbus_dev->num_registers = (len/sizeof(struct linux_prom_registers));
	sbus_dev->ranges_applied = 0;

	base = (unsigned long) sbus_dev->reg_addrs[0].phys_addr;
	if(base>=SUN_SBUS_BVADDR ||
	   (sparc_cpu_model != sun4c &&
	   sparc_cpu_model != sun4)) {
		/* Ahh, we can determine the slot and offset */
		if(sparc_cpu_model == sun4u) {
			/* A bit tricky on the SYSIO. */
			sbus_dev->slot = sbus_dev->reg_addrs[0].which_io;
			sbus_dev->offset = sbus_dev_offset(base);
		} else if (sparc_cpu_model == sun4d) {
			sbus_dev->slot = sbus_dev->reg_addrs[0].which_io;
			sbus_dev->offset = base;
		} else {
			sbus_dev->slot = sbus_dev_slot(base);
			sbus_dev->offset = sbus_dev_offset(base);
		}
	} else {   /* Grrr, gotta do calculations to fix things up */
		sbus_dev->slot = sbus_dev->reg_addrs[0].which_io;
		sbus_dev->offset = base;
		sbus_dev->reg_addrs[0].phys_addr = 
			sbus_devaddr(sbus_dev->slot, base);
		for(grrr=1; grrr<sbus_dev->num_registers; grrr++) {
			base = (unsigned long) sbus_dev->reg_addrs[grrr].phys_addr;
			sbus_dev->reg_addrs[grrr].phys_addr =
				sbus_devaddr(sbus_dev->slot, base);
		}
		/* That surely sucked */
	}
	sbus_dev->sbus_addr = (unsigned long) sbus_dev->reg_addrs[0].phys_addr;
	if(len>(sizeof(struct linux_prom_registers)*PROMREG_MAX)) {
		prom_printf("WHOOPS:  I got too many register addresses for %s  len=%d\n",
		       sbus_dev->prom_name, len);
		panic("sbus device register overflow");
	}

no_regs:
	len = prom_getproperty(nd, "address", (void *) sbus_dev->sbus_vaddrs,
			       sizeof(sbus_dev->sbus_vaddrs));
	if(len == -1) len=0;
	if(len&3) {
		prom_printf("Grrr, I didn't get a multiple of 4 proplen "
		       "for device %s got %d\n", sbus_dev->prom_name, len);
		len=0;
	}
	sbus_dev->num_vaddrs = (len/4);

#ifdef __sparc_v9__  
	len = prom_getproperty(nd, "interrupts", (void *)irqs, sizeof(irqs));
	if((len == -1) || (len == 0)) {
		sbus_dev->irqs[0] = 0;
		sbus_dev->num_irqs = 0;
	} else {
		sbus_dev->num_irqs = 1;
		if (irqs[0].pri < 0x20)
			sbus_dev->irqs[0] = sbus_build_irq(sbus_dev->my_bus, 
					irqs[0].pri + (sbus_dev->slot * 8));
		else
			sbus_dev->irqs[0] = sbus_build_irq(sbus_dev->my_bus, 
					irqs[0].pri);
	}
#else
	len = prom_getproperty(nd, "intr", (void *)irqs, sizeof(irqs));
	if (len == -1) len=0;
	if (len&7) {
		prom_printf("Grrr, I didn't get a multiple of 8 proplen for "
			    "device %s got %d\n", sbus_dev->prom_name, len);
		len=0;
	}
	if (len > 4 * 8) {
		prom_printf("Device %s has more than 4 interrupts\n", sbus_dev->prom_name);
		len = 4 * 8;
	}
	sbus_dev->num_irqs=(len/8);
	if(sbus_dev->num_irqs == 0)
		sbus_dev->irqs[0]=0;
	else if (sparc_cpu_model != sun4d)
		for (len = 0; len < sbus_dev->num_irqs; len++)
			sbus_dev->irqs[len] = irqs[len].pri;
	else {
		extern unsigned int sun4d_build_irq(struct linux_sbus_device *sdev, int irq);
		
		for (len = 0; len < sbus_dev->num_irqs; len++)
			sbus_dev->irqs[len] = sun4d_build_irq(sbus_dev, irqs[len].pri);
	}
#endif

#ifdef DEBUG_FILL
#ifdef __sparc_v9__
	prom_printf("Found %s at SBUS slot %x offset %016lx ",
	       sbus_dev->prom_name, sbus_dev->slot, sbus_dev->offset);
	if (sbus_dev->irqs[0])
		prom_printf("irq %s\n", __irq_itoa(sbus_dev->irqs[0]));
	else
		prom_printf("\n");
	prom_printf("Base address %016lx\n", sbus_dev->sbus_addr);
#else
	prom_printf("Found %s at SBUS slot %x offset %08lx irq-level %d\n",
	       sbus_dev->prom_name, sbus_dev->slot, sbus_dev->offset,
	       sbus_dev->irqs[0]);
	prom_printf("Base address %08lx\n", sbus_dev->sbus_addr);
#endif
	prom_printf("REGISTERS: Probed %d register(s)\n", sbus_dev->num_registers);
	for(len=0; len<sbus_dev->num_registers; len++)
#ifdef __sparc_v9__
		prom_printf("Regs<%d> at address<%08lx> IO-space<%d> size<%d "
		       "bytes, %d words>\n", (int) len,
		       (unsigned long) sbus_dev->reg_addrs[len].phys_addr,
		       sbus_dev->reg_addrs[len].which_io,
		       sbus_dev->reg_addrs[len].reg_size,
		       (sbus_dev->reg_addrs[len].reg_size/4));
#else
		prom_printf("Regs<%d> at address<%016lx> IO-space<%d> size<%d "
		       "bytes, %d words>\n", (int) len,
		       (unsigned long) sbus_dev->reg_addrs[len].phys_addr,
		       sbus_dev->reg_addrs[len].which_io,
		       sbus_dev->reg_addrs[len].reg_size,
		       (sbus_dev->reg_addrs[len].reg_size/4));
#endif
#endif
}