Exemplo n.º 1
0
/**
*
* Initialize a specific XSysAce instance. The configuration information for
* the given device ID is found and the driver instance data is initialized
* appropriately.
*
* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
* @param DeviceId is the unique id of the device controlled by this XSysAce
*        instance.
*
* @return
*
* XST_SUCCESS if successful, or XST_DEVICE_NOT_FOUND if the device was not
* found in the configuration table in xsysace_g.c.
*
* @note
*
* We do not want to reset the configuration controller here since this could
* cause a reconfiguration of the JTAG target chain, depending on how the
* CFGMODEPIN of the device is wired.
*
******************************************************************************/
XStatus XSysAce_Initialize(XSysAce *InstancePtr, Xuint16 DeviceId)
{
    XSysAce_Config *ConfigPtr;

    XASSERT_NONVOID(InstancePtr != XNULL);

    InstancePtr->IsReady = 0;

    /*
     * Lookup configuration data in the device configuration table.
     * Use this configuration info down below when initializing this component.
     */
    ConfigPtr = XSysAce_LookupConfig(DeviceId);

    if (ConfigPtr == (XSysAce_Config *)XNULL)
    {
        return XST_DEVICE_NOT_FOUND;
    }

    return XSysAce_CfgInitialize(InstancePtr, ConfigPtr, ConfigPtr->BaseAddress);
}
Exemplo n.º 2
0
static int xsysace_probe(struct device *dev)
{
	XSysAce_Config xsysace_cfg;
	struct platform_device *pdev = to_platform_device(dev);
	struct resource *irq_res, *regs_res;
	unsigned long remap_size;
	XStatus stat;
	long size;
	XSysAce_CFParameters ident;
	int retval;

	if (!dev)
		return -EINVAL;

	/* Find irq number, map the control registers in */
	irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!regs_res || !irq_res) {
		printk(KERN_ERR "%s #%d: IO resource(s) not found\n",
		       DRIVER_NAME, pdev->id);
		retval = -EFAULT;
		goto failed1;
	}
	xsa_irq = irq_res->start;
	xsa_phys_addr = regs_res->start;
	remap_size = regs_res->end - regs_res->start + 1;
	if (!request_mem_region(regs_res->start, remap_size, DRIVER_NAME)) {
		printk(KERN_ERR
		       "%s #%d: Couldn't lock memory region at 0x%08lX\n",
		       DRIVER_NAME, pdev->id, regs_res->start);
		retval = -EBUSY;
		goto failed1;
	}

	/* Fill in cfg data and add them to the list */
	xsa_remap_size = remap_size;
	xsysace_cfg.DeviceId = pdev->id;
	xsysace_cfg.BaseAddress = (u32) ioremap(regs_res->start, remap_size);
	if (xsysace_cfg.BaseAddress == 0) {
		printk(KERN_ERR
		       "%s #%d: Couldn't ioremap memory at 0x%08lX\n",
		       DRIVER_NAME, pdev->id, regs_res->start);
		retval = -EFAULT;
		goto failed2;
	}

	/* Tell the Xilinx code to bring this SystemACE interface up. */
	down(&cfg_sem);
	if (XSysAce_CfgInitialize
	    (&SysAce, &xsysace_cfg, xsysace_cfg.BaseAddress) != XST_SUCCESS) {
		up(&cfg_sem);
		printk(KERN_ERR
		       "%s #%d: Could not initialize device.\n",
		       DRIVER_NAME, pdev->id);
		retval = -ENODEV;
		goto failed3;
	}
	up(&cfg_sem);

	retval = request_irq(xsa_irq, xsysace_interrupt, 0, DEVICE_NAME, NULL);
	if (retval) {
		printk(KERN_ERR
		       "%s #%d: Couldn't allocate interrupt %d.\n",
		       DRIVER_NAME, pdev->id, xsa_irq);
		goto failed3;
	}

	XSysAce_SetEventHandler(&SysAce, EventHandler, (void *)NULL);
	XSysAce_EnableInterrupt(&SysAce);

	/* Time to identify the drive. */
	while (XSysAce_Lock(&SysAce, 0) == XST_DEVICE_BUSY) ;
	while ((stat =
		XSysAce_IdentifyCF(&SysAce, &ident)) == XST_DEVICE_BUSY) ;
	XSysAce_Unlock(&SysAce);
	if (stat != XST_SUCCESS) {
		printk(KERN_ERR "%s: Could not send identify command.\n",
		       DEVICE_NAME);
		retval = -ENODEV;
		goto failed4;
	}

	/* Fill in what we learned. */
	heads = ident.NumHeads;
	sectors = ident.NumSectorsPerTrack;
	cylinders = ident.NumCylinders;
	size = (long)cylinders *(long)heads *(long)sectors;

	xsysace_queue = blk_init_queue(xsysace_do_request, &xsysace_lock);
	if (!xsysace_queue) {
		retval = -ENODEV;
		goto failed4;
	}

	if (register_blkdev(xsa_major, MAJOR_NAME)) {
		retval = -EBUSY;
		goto failed5;
	}

	xsa_gendisk = alloc_disk(16);
	if (!xsa_gendisk) {
		retval = -ENODEV;
		goto failed6;
	}

	strcpy(xsa_gendisk->disk_name, MAJOR_NAME);
	xsa_gendisk->fops = &xsysace_fops;
	xsa_gendisk->major = xsa_major;
	xsa_gendisk->first_minor = 0;
	xsa_gendisk->minors = 16;
	xsa_gendisk->queue = xsysace_queue;

	set_capacity(xsa_gendisk, size);

	printk(KERN_INFO
	       "%s at 0x%08X mapped to 0x%08X, irq=%d, %ldKB\n",
	       DEVICE_NAME, xsa_phys_addr, SysAce.BaseAddress, xsa_irq,
	       size / 2);

	/* Hook our reset function into system's restart code. */
	if (old_restart == NULL) {
		old_restart = ppc_md.restart;
		ppc_md.restart = xsysace_restart;
	}

	if (proc_init())
		printk(KERN_WARNING "%s: could not register /proc interface.\n",
		       DEVICE_NAME);

	add_disk(xsa_gendisk);

	return 0;		/* success */

      failed6:
	unregister_blkdev(xsa_major, MAJOR_NAME);

      failed5:
	blk_cleanup_queue(xsysace_queue);

      failed4:
	XSysAce_DisableInterrupt(&SysAce);
	free_irq(xsa_irq, NULL);

      failed3:
	iounmap((void *)(xsysace_cfg.BaseAddress));

      failed2:
	release_mem_region(regs_res->start, remap_size);

      failed1:
	return retval;
}