static int i2c_versatile_probe(struct platform_device *dev) { struct i2c_versatile *i2c; struct resource *r; int ret; r = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!r) { ret = -EINVAL; goto err_out; } if (!request_mem_region(r->start, resource_size(r), "versatile-i2c")) { ret = -EBUSY; goto err_out; } i2c = kzalloc(sizeof(struct i2c_versatile), GFP_KERNEL); if (!i2c) { ret = -ENOMEM; goto err_release; } i2c->base = ioremap(r->start, resource_size(r)); if (!i2c->base) { ret = -ENOMEM; goto err_free; } writel(SCL | SDA, i2c->base + I2C_CONTROLS); i2c->adap.owner = THIS_MODULE; strlcpy(i2c->adap.name, "Versatile I2C adapter", sizeof(i2c->adap.name)); i2c->adap.algo_data = &i2c->algo; i2c->adap.dev.parent = &dev->dev; i2c->adap.dev.of_node = dev->dev.of_node; i2c->algo = i2c_versatile_algo; i2c->algo.data = i2c; i2c->adap.nr = dev->id; ret = i2c_bit_add_numbered_bus(&i2c->adap); if (ret >= 0) { platform_set_drvdata(dev, i2c); of_i2c_register_devices(&i2c->adap); return 0; } iounmap(i2c->base); err_free: kfree(i2c); err_release: release_mem_region(r->start, resource_size(r)); err_out: return ret; }
/** 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 octeon_i2c_probe(struct platform_device *pdev) { int irq, result = 0; struct octeon_i2c *i2c; struct resource *res_mem; /* All adaptors have an irq. */ irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); if (!i2c) { dev_err(&pdev->dev, "kzalloc failed\n"); result = -ENOMEM; goto out; } i2c->dev = &pdev->dev; res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res_mem == NULL) { dev_err(i2c->dev, "found no memory resource\n"); result = -ENXIO; goto out; } i2c->twsi_phys = res_mem->start; i2c->regsize = resource_size(res_mem); /* * "clock-rate" is a legacy binding, the official binding is * "clock-frequency". Try the official one first and then * fall back if it doesn't exist. */ if (of_property_read_u32(pdev->dev.of_node, "clock-frequency", &i2c->twsi_freq) && of_property_read_u32(pdev->dev.of_node, "clock-rate", &i2c->twsi_freq)) { dev_err(i2c->dev, "no I2C 'clock-rate' or 'clock-frequency' property\n"); result = -ENXIO; goto out; } i2c->sys_freq = octeon_get_io_clock_rate(); if (!devm_request_mem_region(&pdev->dev, i2c->twsi_phys, i2c->regsize, res_mem->name)) { dev_err(i2c->dev, "request_mem_region failed\n"); goto out; } i2c->twsi_base = devm_ioremap(&pdev->dev, i2c->twsi_phys, i2c->regsize); init_waitqueue_head(&i2c->queue); i2c->irq = irq; result = devm_request_irq(&pdev->dev, i2c->irq, octeon_i2c_isr, 0, DRV_NAME, i2c); if (result < 0) { dev_err(i2c->dev, "failed to attach interrupt\n"); goto out; } result = octeon_i2c_initlowlevel(i2c); if (result) { dev_err(i2c->dev, "init low level failed\n"); goto out; } result = octeon_i2c_setclock(i2c); if (result) { dev_err(i2c->dev, "clock init failed\n"); goto out; } i2c->adap = octeon_i2c_ops; i2c->adap.dev.parent = &pdev->dev; i2c->adap.dev.of_node = pdev->dev.of_node; i2c_set_adapdata(&i2c->adap, i2c); platform_set_drvdata(pdev, i2c); result = i2c_add_adapter(&i2c->adap); if (result < 0) { dev_err(i2c->dev, "failed to add adapter\n"); goto fail_add; } dev_info(i2c->dev, "version %s\n", DRV_VERSION); of_i2c_register_devices(&i2c->adap); return 0; fail_add: platform_set_drvdata(pdev, NULL); out: return result; };
static int xiic_i2c_probe(struct platform_device *pdev) { struct xiic_i2c *i2c; struct xiic_i2c_platform_data *pdata; struct resource *res; int ret, irq; u8 i; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) goto resource_missing; irq = platform_get_irq(pdev, 0); if (irq < 0) goto resource_missing; pdata = (struct xiic_i2c_platform_data *) pdev->dev.platform_data; i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); if (!i2c) return -ENOMEM; if (!request_mem_region(res->start, resource_size(res), pdev->name)) { dev_err(&pdev->dev, "Memory region busy\n"); ret = -EBUSY; goto request_mem_failed; } i2c->base = ioremap(res->start, resource_size(res)); if (!i2c->base) { dev_err(&pdev->dev, "Unable to map registers\n"); ret = -EIO; goto map_failed; } /* hook up driver to tree */ platform_set_drvdata(pdev, i2c); i2c->adap = xiic_adapter; i2c_set_adapdata(&i2c->adap, i2c); i2c->adap.dev.parent = &pdev->dev; i2c->adap.dev.of_node = pdev->dev.of_node; xiic_reinit(i2c); spin_lock_init(&i2c->lock); init_waitqueue_head(&i2c->wait); ret = request_irq(irq, xiic_isr, 0, pdev->name, i2c); if (ret) { dev_err(&pdev->dev, "Cannot claim IRQ\n"); goto request_irq_failed; } /* add i2c adapter to i2c tree */ ret = i2c_add_adapter(&i2c->adap); if (ret) { dev_err(&pdev->dev, "Failed to add adapter\n"); goto add_adapter_failed; } if (pdata) { /* add in known devices to the bus */ for (i = 0; i < pdata->num_devices; i++) i2c_new_device(&i2c->adap, pdata->devices + i); } of_i2c_register_devices(&i2c->adap); return 0; add_adapter_failed: free_irq(irq, i2c); request_irq_failed: xiic_deinit(i2c); iounmap(i2c->base); map_failed: release_mem_region(res->start, resource_size(res)); request_mem_failed: kfree(i2c); return ret; resource_missing: dev_err(&pdev->dev, "IRQ or Memory resource is missing\n"); return -ENOENT; }
static int __devinit i2c_pnx_probe(struct platform_device *pdev) { unsigned long tmp; int ret = 0; struct i2c_pnx_algo_data *alg_data; unsigned long freq; struct resource *res; u32 speed = I2C_PNX_SPEED_KHZ_DEFAULT * 1000; alg_data = kzalloc(sizeof(*alg_data), GFP_KERNEL); if (!alg_data) { ret = -ENOMEM; goto err_kzalloc; } platform_set_drvdata(pdev, alg_data); alg_data->adapter.dev.parent = &pdev->dev; alg_data->adapter.algo = &pnx_algorithm; alg_data->adapter.algo_data = alg_data; alg_data->adapter.nr = pdev->id; alg_data->timeout = I2C_PNX_TIMEOUT_DEFAULT; #ifdef CONFIG_OF alg_data->adapter.dev.of_node = of_node_get(pdev->dev.of_node); if (pdev->dev.of_node) { of_property_read_u32(pdev->dev.of_node, "clock-frequency", &speed); /* * At this point, it is planned to add an OF timeout property. * As soon as there is a consensus about how to call and handle * this, sth. like the following can be put here: * * of_property_read_u32(pdev->dev.of_node, "timeout", * &alg_data->timeout); */ } #endif alg_data->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(alg_data->clk)) { ret = PTR_ERR(alg_data->clk); goto out_drvdata; } init_timer(&alg_data->mif.timer); alg_data->mif.timer.function = i2c_pnx_timeout; alg_data->mif.timer.data = (unsigned long)alg_data; snprintf(alg_data->adapter.name, sizeof(alg_data->adapter.name), "%s", pdev->name); /* Register I/O resource */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "Unable to get mem resource.\n"); ret = -EBUSY; goto out_clkget; } if (!request_mem_region(res->start, I2C_PNX_REGION_SIZE, pdev->name)) { dev_err(&pdev->dev, "I/O region 0x%08x for I2C already in use.\n", res->start); ret = -ENOMEM; goto out_clkget; } alg_data->base = res->start; alg_data->ioaddr = ioremap(res->start, I2C_PNX_REGION_SIZE); if (!alg_data->ioaddr) { dev_err(&pdev->dev, "Couldn't ioremap I2C I/O region\n"); ret = -ENOMEM; goto out_release; } ret = clk_enable(alg_data->clk); if (ret) goto out_unmap; freq = clk_get_rate(alg_data->clk); /* * Clock Divisor High This value is the number of system clocks * the serial clock (SCL) will be high. * For example, if the system clock period is 50 ns and the maximum * desired serial period is 10000 ns (100 kHz), then CLKHI would be * set to 0.5*(f_sys/f_i2c)-2=0.5*(20e6/100e3)-2=98. The actual value * programmed into CLKHI will vary from this slightly due to * variations in the output pad's rise and fall times as well as * the deglitching filter length. */ tmp = (freq / speed) / 2 - 2; if (tmp > 0x3FF) tmp = 0x3FF; iowrite32(tmp, I2C_REG_CKH(alg_data)); iowrite32(tmp, I2C_REG_CKL(alg_data)); iowrite32(mcntrl_reset, I2C_REG_CTL(alg_data)); if (wait_reset(alg_data)) { ret = -ENODEV; goto out_clock; } init_completion(&alg_data->mif.complete); alg_data->irq = platform_get_irq(pdev, 0); if (alg_data->irq < 0) { dev_err(&pdev->dev, "Failed to get IRQ from platform resource\n"); goto out_irq; } ret = request_irq(alg_data->irq, i2c_pnx_interrupt, 0, pdev->name, alg_data); if (ret) goto out_clock; /* Register this adapter with the I2C subsystem */ ret = i2c_add_numbered_adapter(&alg_data->adapter); if (ret < 0) { dev_err(&pdev->dev, "I2C: Failed to add bus\n"); goto out_irq; } of_i2c_register_devices(&alg_data->adapter); dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n", alg_data->adapter.name, res->start, alg_data->irq); return 0; out_irq: free_irq(alg_data->irq, alg_data); out_clock: clk_disable(alg_data->clk); out_unmap: iounmap(alg_data->ioaddr); out_release: release_mem_region(res->start, I2C_PNX_REGION_SIZE); out_clkget: clk_put(alg_data->clk); out_drvdata: kfree(alg_data); err_kzalloc: platform_set_drvdata(pdev, NULL); return ret; }