static int __devexit xilinx_iic_of_remove(struct platform_device *ofdev) { return xilinx_iic_remove(&ofdev->dev); }
static int __init xilinx_iic_probe(struct of_device *of_dev, const struct of_device_id *match) { XIic_Config xiic_cfg; struct xiic_data *dev; char *scan_results; struct resource mem; struct device_node *dev_node = of_dev->node; int error; const u32 *did; /* Allocate the dev and zero it out. */ dev = kzalloc(sizeof(struct xiic_data), SLAB_KERNEL); if (!dev) { dev_err(&of_dev->dev, "Cannot allocate struct xiic_data\n"); error = -ENOMEM; goto out2; } dev_set_drvdata(&of_dev->dev, dev); /* get resources from device tree */ dev->irq = irq_of_parse_and_map(dev_node, 0); if (dev->irq == 0 /* NOIRQ */ ) { error = -ENODEV; goto out; } if (of_address_to_resource(dev_node, 0, &mem)) { error = -ENODEV; goto out; } /* initialize fields to satisfy i2c */ strcpy(dev->adap.name, of_dev->dev.bus_id); did = of_get_property(dev_node, "index", NULL); if (did == NULL) { printk ("%s: Can not get device index from device tree, assume 0\n", __FUNCTION__); dev->index = 0; } else dev->index = *did; init_completion(&dev->complete); memset(&xiic_cfg, 0, sizeof(XIic_Config)); xiic_cfg.DeviceId = dev->index; /* Change the addresses to be virtual; save the old ones to restore. */ dev->base = mem.start; xiic_cfg.BaseAddress = (u32) ioremap(mem.start, mem.end - mem.start + 1); dev->remapped = 1; down(&cfg_sem); /* Tell the Xilinx code to bring this IIC interface up. */ if (XIic_CfgInitialize(&dev->Iic, &xiic_cfg, xiic_cfg.BaseAddress) != XST_SUCCESS) { up(&cfg_sem); dev_err(&of_dev->dev, "could not initialize device.\n"); error = -ENODEV; goto out; } up(&cfg_sem); XIic_SetRecvHandler(&dev->Iic, (void *)dev, RecvHandler); XIic_SetSendHandler(&dev->Iic, (void *)dev, SendHandler); XIic_SetStatusHandler(&dev->Iic, (void *)dev, StatusHandler); /* Grab the IRQ */ error = request_irq(dev->irq, xiic_interrupt, 0, dev->adap.name, dev); if (error) { dev_err(&of_dev->dev, "could not allocate interrupt %d.\n", dev->irq); goto out; } dev->reqirq = 1; if (XIic_Start(&dev->Iic) != XST_SUCCESS) { dev_err(&of_dev->dev, "could not start device\n"); error = -ENODEV; goto out; } dev->started = 1; /* Now tell the core I2C code about our new device. */ /* * SAATODO: Get a real ID (perhaps I2C_HW_XILINX) after * initial release. Will need to email [email protected] * per http://www2.lm-sensors.nu/~lm78/support.html */ dev->adap.id = I2C_DRIVERID_I2CDEV; dev->adap.algo = &xiic_algo; dev->adap.algo_data = NULL; dev->adap.timeout = XIIC_TIMEOUT; dev->adap.retries = XIIC_RETRY; error = i2c_add_adapter(&dev->adap); if (error) { dev_err(&of_dev->dev, "could not add i2c adapter\n"); goto out; } dev->added = 1; printk("%s #%d at 0x%08X mapped to 0x%08X, irq=%d\n", dev->adap.name, dev->index, dev->base, dev->Iic.BaseAddress, dev->irq); if (scan) { scan_results = xilinx_iic_do_scan(dev); if (scan_results) { printk(scan_results); kfree(scan_results); } } device_create_file(&of_dev->dev, &dev_attr_scan); out: if (error) xilinx_iic_remove(of_dev); out2: return error; }
/** Shared device initialization code */ static int __devinit xilinx_iic_setup( struct device *device, struct device_node *node, struct resource *r_mem, struct resource *r_irq, u32 ten_bit_addr, u32 gpo_width) { XIic_Config xiic_cfg; struct xiic_data *dev; char *scan_results; int error; /* Allocate the dev and zero it out. */ dev = kmalloc(sizeof(struct xiic_data), GFP_KERNEL); if (!dev) { dev_err(device, "Cannot allocate struct xiic_data\n"); error = -ENOMEM; goto out2; } memset(dev, 0, sizeof(struct xiic_data)); dev_set_drvdata(device, dev); dev->irq = r_irq->start; /* initialize fields to satisfy i2c */ dev->index = 0; init_completion(&dev->complete); memset(&xiic_cfg, 0, sizeof(XIic_Config)); xiic_cfg.DeviceId = 0; /* Change the addresses to be virtual; save the old ones to restore. */ dev->base = r_mem->start; xiic_cfg.BaseAddress = (u32) ioremap(r_mem->start, r_mem->end - r_mem->start + 1); dev->remapped = 1; down(&cfg_sem); xiic_cfg.Has10BitAddr = (int)ten_bit_addr; xiic_cfg.GpOutWidth = (u8)gpo_width; /* Tell the Xilinx code to bring this IIC interface up. */ if (XIic_CfgInitialize(&dev->Iic, &xiic_cfg, xiic_cfg.BaseAddress) != XST_SUCCESS) { up(&cfg_sem); dev_err(device, "could not initialize device.\n"); error = -ENODEV; goto out; } up(&cfg_sem); XIic_SetRecvHandler(&dev->Iic, (void *)dev, RecvHandler); XIic_SetSendHandler(&dev->Iic, (void *)dev, SendHandler); XIic_SetStatusHandler(&dev->Iic, (void *)dev, StatusHandler); /* Grab the IRQ */ error = request_irq(dev->irq, xiic_interrupt, 0, dev->adap.name, dev); if (error) { dev_err(device, "could not allocate interrupt %d.\n", dev->irq); goto out; } dev->reqirq = 1; if (XIic_Start(&dev->Iic) != XST_SUCCESS) { dev_err(device, "could not start device\n"); error = -ENODEV; goto out; } dev->started = 1; /* Now tell the core I2C code about our new device. */ strcpy(dev->adap.name, "xilinx-iic"); dev->adap.dev.of_node = node; dev->adap.algo = &xiic_algo; dev->adap.algo_data = NULL; dev->adap.timeout = XIIC_TIMEOUT; dev->adap.retries = XIIC_RETRY; error = i2c_add_adapter(&dev->adap); if (error) { dev_err(device, "could not add i2c adapter\n"); goto out; } dev->added = 1; printk("%s #%d at 0x%08X mapped to 0x%08X, irq=%d\n", dev->adap.name, dev->index, dev->base, (unsigned int)dev->Iic.BaseAddress, dev->irq); if (scan) { scan_results = xilinx_iic_do_scan(dev); if (scan_results) { printk(scan_results); kfree(scan_results); } } of_i2c_register_devices(&dev->adap); error = device_create_file(device, &dev_attr_scan); out: if (error) xilinx_iic_remove(device); out2: return error; }
static int __init xilinx_iic_probe(struct device *device) { XIic_Config xiic_cfg; struct platform_device *pdev = to_platform_device(device); struct xiic_data *dev; char *scan_results; struct resource *mem; int error; /* Allocate the dev and zero it out. */ dev = kzalloc(sizeof(struct xiic_data), SLAB_KERNEL); if (!dev) { dev_err(device, "Cannot allocate struct xiic_data\n"); error = -ENOMEM; goto out2; } dev_set_drvdata(device, dev); /* get resources from resource list of passed platform_device */ dev->irq = platform_get_irq(pdev, 0); if (dev->irq == 0 /* NOIRQ */ ) { error = -ENODEV; goto out; } mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { error = -ENODEV; goto out; } /* initialize fields to satisfy i2c */ strcpy(dev->adap.name, device->bus_id); dev->index = pdev->id; init_completion(&dev->complete); memset(&xiic_cfg, 0, sizeof(XIic_Config)); xiic_cfg.DeviceId = pdev->id; /* Change the addresses to be virtual; save the old ones to restore. */ dev->base = mem->start; xiic_cfg.BaseAddress = (u32) ioremap(mem->start, mem->end - mem->start + 1); dev->remapped = 1; down(&cfg_sem); /* Tell the Xilinx code to bring this IIC interface up. */ if (XIic_CfgInitialize(&dev->Iic, &xiic_cfg, xiic_cfg.BaseAddress) != XST_SUCCESS) { up(&cfg_sem); dev_err(device, "could not initialize device.\n"); error = -ENODEV; goto out; } up(&cfg_sem); XIic_SetRecvHandler(&dev->Iic, (void *)dev, RecvHandler); XIic_SetSendHandler(&dev->Iic, (void *)dev, SendHandler); XIic_SetStatusHandler(&dev->Iic, (void *)dev, StatusHandler); /* Grab the IRQ */ error = request_irq(dev->irq, xiic_interrupt, 0, dev->adap.name, dev); if (error) { dev_err(device, "could not allocate interrupt %d.\n", dev->irq); goto out; } dev->reqirq = 1; if (XIic_Start(&dev->Iic) != XST_SUCCESS) { dev_err(device, "could not start device\n"); error = -ENODEV; goto out; } dev->started = 1; /* Now tell the core I2C code about our new device. */ /* * SAATODO: Get a real ID (perhaps I2C_HW_XILINX) after * initial release. Will need to email [email protected] * per http://www2.lm-sensors.nu/~lm78/support.html */ dev->adap.id = xiic_algo.id | I2C_DRIVERID_EXP0; dev->adap.algo = &xiic_algo; dev->adap.algo_data = NULL; dev->adap.timeout = XIIC_TIMEOUT; dev->adap.retries = XIIC_RETRY; error = i2c_add_adapter(&dev->adap); if (error) { dev_err(device, "could not add i2c adapter\n"); goto out; } dev->added = 1; printk("%s #%d at 0x%08X mapped to 0x%08X, irq=%d\n", dev->adap.name, dev->index, dev->base, dev->Iic.BaseAddress, dev->irq); if (scan) { scan_results = xilinx_iic_do_scan(dev); if (scan_results) { printk(scan_results); kfree(scan_results); } } device_create_file(device, &dev_attr_scan); out: if (error) xilinx_iic_remove(device); out2: return error; }