in busses/i2c-pxa.c [1362:1485]
static int i2c_pxa_probe(struct platform_device *dev)
{
struct i2c_pxa_platform_data *plat = dev_get_platdata(&dev->dev);
enum pxa_i2c_types i2c_type;
struct pxa_i2c *i2c;
struct resource *res = NULL;
int ret, irq;
i2c = devm_kzalloc(&dev->dev, sizeof(struct pxa_i2c), GFP_KERNEL);
if (!i2c)
return -ENOMEM;
/* Default adapter num to device id; i2c_pxa_probe_dt can override. */
i2c->adap.nr = dev->id;
i2c->adap.owner = THIS_MODULE;
i2c->adap.retries = 5;
i2c->adap.algo_data = i2c;
i2c->adap.dev.parent = &dev->dev;
#ifdef CONFIG_OF
i2c->adap.dev.of_node = dev->dev.of_node;
#endif
res = platform_get_resource(dev, IORESOURCE_MEM, 0);
i2c->reg_base = devm_ioremap_resource(&dev->dev, res);
if (IS_ERR(i2c->reg_base))
return PTR_ERR(i2c->reg_base);
irq = platform_get_irq(dev, 0);
if (irq < 0)
return irq;
ret = i2c_pxa_init_recovery(i2c);
if (ret)
return ret;
ret = i2c_pxa_probe_dt(dev, i2c, &i2c_type);
if (ret > 0)
ret = i2c_pxa_probe_pdata(dev, i2c, &i2c_type);
if (ret < 0)
return ret;
spin_lock_init(&i2c->lock);
init_waitqueue_head(&i2c->wait);
strlcpy(i2c->adap.name, "pxa_i2c-i2c", sizeof(i2c->adap.name));
i2c->clk = devm_clk_get(&dev->dev, NULL);
if (IS_ERR(i2c->clk)) {
dev_err(&dev->dev, "failed to get the clk: %ld\n", PTR_ERR(i2c->clk));
return PTR_ERR(i2c->clk);
}
i2c->reg_ibmr = i2c->reg_base + pxa_reg_layout[i2c_type].ibmr;
i2c->reg_idbr = i2c->reg_base + pxa_reg_layout[i2c_type].idbr;
i2c->reg_icr = i2c->reg_base + pxa_reg_layout[i2c_type].icr;
i2c->reg_isr = i2c->reg_base + pxa_reg_layout[i2c_type].isr;
i2c->fm_mask = pxa_reg_layout[i2c_type].fm;
i2c->hs_mask = pxa_reg_layout[i2c_type].hs;
if (i2c_type != REGS_CE4100)
i2c->reg_isar = i2c->reg_base + pxa_reg_layout[i2c_type].isar;
if (i2c_type == REGS_PXA910) {
i2c->reg_ilcr = i2c->reg_base + pxa_reg_layout[i2c_type].ilcr;
i2c->reg_iwcr = i2c->reg_base + pxa_reg_layout[i2c_type].iwcr;
}
i2c->iobase = res->start;
i2c->iosize = resource_size(res);
i2c->irq = irq;
i2c->slave_addr = I2C_PXA_SLAVE_ADDR;
i2c->highmode_enter = false;
if (plat) {
i2c->adap.class = plat->class;
}
if (i2c->high_mode) {
if (i2c->rate) {
clk_set_rate(i2c->clk, i2c->rate);
pr_info("i2c: <%s> set rate to %ld\n",
i2c->adap.name, clk_get_rate(i2c->clk));
} else
pr_warn("i2c: <%s> clock rate not set\n",
i2c->adap.name);
}
clk_prepare_enable(i2c->clk);
if (i2c->use_pio) {
i2c->adap.algo = &i2c_pxa_pio_algorithm;
} else {
i2c->adap.algo = &i2c_pxa_algorithm;
ret = devm_request_irq(&dev->dev, irq, i2c_pxa_handler,
IRQF_SHARED | IRQF_NO_SUSPEND,
dev_name(&dev->dev), i2c);
if (ret) {
dev_err(&dev->dev, "failed to request irq: %d\n", ret);
goto ereqirq;
}
}
i2c_pxa_reset(i2c);
ret = i2c_add_numbered_adapter(&i2c->adap);
if (ret < 0)
goto ereqirq;
platform_set_drvdata(dev, i2c);
#ifdef CONFIG_I2C_PXA_SLAVE
dev_info(&i2c->adap.dev, " PXA I2C adapter, slave address %d\n",
i2c->slave_addr);
#else
dev_info(&i2c->adap.dev, " PXA I2C adapter\n");
#endif
return 0;
ereqirq:
clk_disable_unprepare(i2c->clk);
return ret;
}