/** * * 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); }
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; }