diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-at91.c')
| -rw-r--r-- | drivers/i2c/busses/i2c-at91.c | 101 |
1 files changed, 54 insertions, 47 deletions
diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index 2bfc04d0a1b..e95f9ba9679 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c @@ -28,12 +28,11 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> -#include <linux/of_i2c.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/platform_data/dma-atmel.h> -#define TWI_CLK_HZ 100000 /* max 400 Kbits/s */ +#define DEFAULT_TWI_CLK_HZ 100000 /* max 400 Kbits/s */ #define AT91_I2C_TIMEOUT msecs_to_jiffies(100) /* transfer timeout */ #define AT91_I2C_DMA_THRESHOLD 8 /* enable DMA if transfer size is bigger than this threshold */ @@ -372,7 +371,7 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev) dev_dbg(dev->dev, "transfer: %s %d bytes.\n", (dev->msg->flags & I2C_M_RD) ? "read" : "write", dev->buf_len); - INIT_COMPLETION(dev->cmd_complete); + reinit_completion(&dev->cmd_complete); dev->transfer_status = 0; if (!dev->buf_len) { @@ -553,13 +552,6 @@ static struct at91_twi_pdata at91sam9g10_config = { .has_dma_support = false, }; -static struct at91_twi_pdata at91sam9x5_config = { - .clk_max_div = 7, - .clk_offset = 4, - .has_unre_flag = false, - .has_dma_support = true, -}; - static const struct platform_device_id at91_twi_devtypes[] = { { .name = "i2c-at91rm9200", @@ -582,11 +574,24 @@ static const struct platform_device_id at91_twi_devtypes[] = { }; #if defined(CONFIG_OF) +static struct at91_twi_pdata at91sam9x5_config = { + .clk_max_div = 7, + .clk_offset = 4, + .has_unre_flag = false, + .has_dma_support = true, +}; + static const struct of_device_id atmel_twi_dt_ids[] = { { + .compatible = "atmel,at91rm9200-i2c", + .data = &at91rm9200_config, + } , { .compatible = "atmel,at91sam9260-i2c", .data = &at91sam9260_config, } , { + .compatible = "atmel,at91sam9261-i2c", + .data = &at91sam9261_config, + } , { .compatible = "atmel,at91sam9g20-i2c", .data = &at91sam9g20_config, } , { @@ -600,15 +605,18 @@ static const struct of_device_id atmel_twi_dt_ids[] = { } }; MODULE_DEVICE_TABLE(of, atmel_twi_dt_ids); -#else -#define atmel_twi_dt_ids NULL #endif -static bool filter(struct dma_chan *chan, void *slave) +static bool filter(struct dma_chan *chan, void *pdata) { - struct at_dma_slave *sl = slave; + struct at91_twi_pdata *sl_pdata = pdata; + struct at_dma_slave *sl; + + if (!sl_pdata) + return false; - if (sl->dma_dev == chan->device->dev) { + sl = &sl_pdata->dma_slave; + if (sl && (sl->dma_dev == chan->device->dev)) { chan->private = sl; return true; } else { @@ -619,11 +627,10 @@ static bool filter(struct dma_chan *chan, void *slave) static int at91_twi_configure_dma(struct at91_twi_dev *dev, u32 phy_addr) { int ret = 0; - struct at_dma_slave *sdata; + struct at91_twi_pdata *pdata = dev->pdata; struct dma_slave_config slave_config; struct at91_twi_dma *dma = &dev->dma; - - sdata = &dev->pdata->dma_slave; + dma_cap_mask_t mask; memset(&slave_config, 0, sizeof(slave_config)); slave_config.src_addr = (dma_addr_t)phy_addr + AT91_TWI_RHR; @@ -634,25 +641,22 @@ static int at91_twi_configure_dma(struct at91_twi_dev *dev, u32 phy_addr) slave_config.dst_maxburst = 1; slave_config.device_fc = false; - if (sdata && sdata->dma_dev) { - dma_cap_mask_t mask; + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - dma->chan_tx = dma_request_channel(mask, filter, sdata); - if (!dma->chan_tx) { - dev_err(dev->dev, "no DMA channel available for tx\n"); - ret = -EBUSY; - goto error; - } - dma->chan_rx = dma_request_channel(mask, filter, sdata); - if (!dma->chan_rx) { - dev_err(dev->dev, "no DMA channel available for rx\n"); - ret = -EBUSY; - goto error; - } - } else { - ret = -EINVAL; + dma->chan_tx = dma_request_slave_channel_compat(mask, filter, pdata, + dev->dev, "tx"); + if (!dma->chan_tx) { + dev_err(dev->dev, "can't get a DMA channel for tx\n"); + ret = -EBUSY; + goto error; + } + + dma->chan_rx = dma_request_slave_channel_compat(mask, filter, pdata, + dev->dev, "rx"); + if (!dma->chan_rx) { + dev_err(dev->dev, "can't get a DMA channel for rx\n"); + ret = -EBUSY; goto error; } @@ -707,6 +711,7 @@ static int at91_twi_probe(struct platform_device *pdev) struct resource *mem; int rc; u32 phy_addr; + u32 bus_clk_rate; dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); if (!dev) @@ -723,9 +728,9 @@ static int at91_twi_probe(struct platform_device *pdev) if (!dev->pdata) return -ENODEV; - dev->base = devm_request_and_ioremap(&pdev->dev, mem); - if (!dev->base) - return -EBUSY; + dev->base = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(dev->base)) + return PTR_ERR(dev->base); dev->irq = platform_get_irq(pdev, 0); if (dev->irq < 0) @@ -752,13 +757,18 @@ static int at91_twi_probe(struct platform_device *pdev) dev->use_dma = true; } - at91_calc_twi_clock(dev, TWI_CLK_HZ); + rc = of_property_read_u32(dev->dev->of_node, "clock-frequency", + &bus_clk_rate); + if (rc) + bus_clk_rate = DEFAULT_TWI_CLK_HZ; + + at91_calc_twi_clock(dev, bus_clk_rate); at91_init_twi_bus(dev); snprintf(dev->adapter.name, sizeof(dev->adapter.name), "AT91"); i2c_set_adapdata(&dev->adapter, dev); dev->adapter.owner = THIS_MODULE; - dev->adapter.class = I2C_CLASS_HWMON; + dev->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_DEPRECATED; dev->adapter.algo = &at91_twi_algorithm; dev->adapter.dev.parent = dev->dev; dev->adapter.nr = pdev->id; @@ -773,8 +783,6 @@ static int at91_twi_probe(struct platform_device *pdev) return rc; } - of_i2c_register_devices(&dev->adapter); - dev_info(dev->dev, "AT91 i2c bus driver.\n"); return 0; } @@ -782,12 +790,11 @@ static int at91_twi_probe(struct platform_device *pdev) static int at91_twi_remove(struct platform_device *pdev) { struct at91_twi_dev *dev = platform_get_drvdata(pdev); - int rc; - rc = i2c_del_adapter(&dev->adapter); + i2c_del_adapter(&dev->adapter); clk_disable_unprepare(dev->clk); - return rc; + return 0; } #ifdef CONFIG_PM @@ -825,7 +832,7 @@ static struct platform_driver at91_twi_driver = { .driver = { .name = "at91_i2c", .owner = THIS_MODULE, - .of_match_table = atmel_twi_dt_ids, + .of_match_table = of_match_ptr(atmel_twi_dt_ids), .pm = at91_twi_pm_ops, }, }; |
