Skip to content

Commit

Permalink
i2c: sh_mobile: refactor DMA setup
Browse files Browse the repository at this point in the history
Refactor DMA setup to keep the errno so we can implement better
deferred probe support in the next step.

Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
  • Loading branch information
Wolfram Sang authored and Wolfram Sang committed Dec 17, 2014
1 parent 00d8689 commit e844a79
Showing 1 changed file with 16 additions and 19 deletions.
35 changes: 16 additions & 19 deletions drivers/i2c/busses/i2c-sh_mobile.c
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ static void sh_mobile_i2c_xfer_dma(struct sh_mobile_i2c_data *pd)
dma_addr_t dma_addr;
dma_cookie_t cookie;

if (!chan)
if (IS_ERR(chan))
return;

dma_addr = dma_map_single(chan->device->dev, pd->msg->buf, pd->msg->len, dir);
Expand Down Expand Up @@ -747,21 +747,18 @@ static const struct of_device_id sh_mobile_i2c_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, sh_mobile_i2c_dt_ids);

static int sh_mobile_i2c_request_dma_chan(struct device *dev, enum dma_transfer_direction dir,
dma_addr_t port_addr, struct dma_chan **chan_ptr)
static struct dma_chan *sh_mobile_i2c_request_dma_chan(struct device *dev,
enum dma_transfer_direction dir, dma_addr_t port_addr)
{
struct dma_chan *chan;
struct dma_slave_config cfg;
char *chan_name = dir == DMA_MEM_TO_DEV ? "tx" : "rx";
int ret;

*chan_ptr = NULL;

chan = dma_request_slave_channel_reason(dev, chan_name);
if (IS_ERR(chan)) {
ret = PTR_ERR(chan);
dev_dbg(dev, "request_channel failed for %s (%d)\n", chan_name, ret);
return ret;
return chan;
}

memset(&cfg, 0, sizeof(cfg));
Expand All @@ -778,25 +775,23 @@ static int sh_mobile_i2c_request_dma_chan(struct device *dev, enum dma_transfer_
if (ret) {
dev_dbg(dev, "slave_config failed for %s (%d)\n", chan_name, ret);
dma_release_channel(chan);
return ret;
return ERR_PTR(ret);
}

*chan_ptr = chan;

dev_dbg(dev, "got DMA channel for %s\n", chan_name);
return 0;
return chan;
}

static void sh_mobile_i2c_release_dma(struct sh_mobile_i2c_data *pd)
{
if (pd->dma_tx) {
if (!IS_ERR(pd->dma_tx)) {
dma_release_channel(pd->dma_tx);
pd->dma_tx = NULL;
pd->dma_tx = ERR_PTR(-EPROBE_DEFER);
}

if (pd->dma_rx) {
if (!IS_ERR(pd->dma_rx)) {
dma_release_channel(pd->dma_rx);
pd->dma_rx = NULL;
pd->dma_rx = ERR_PTR(-EPROBE_DEFER);
}
}

Expand Down Expand Up @@ -889,13 +884,15 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
/* Init DMA */
sg_init_table(&pd->sg, 1);
pd->dma_direction = DMA_NONE;
ret = sh_mobile_i2c_request_dma_chan(pd->dev, DMA_DEV_TO_MEM,
res->start + ICDR, &pd->dma_rx);
pd->dma_rx = sh_mobile_i2c_request_dma_chan(pd->dev, DMA_DEV_TO_MEM,
res->start + ICDR);
ret = PTR_ERR(pd->dma_rx);
if (ret == -EPROBE_DEFER)
return ret;

ret = sh_mobile_i2c_request_dma_chan(pd->dev, DMA_MEM_TO_DEV,
res->start + ICDR, &pd->dma_tx);
pd->dma_tx = sh_mobile_i2c_request_dma_chan(pd->dev, DMA_MEM_TO_DEV,
res->start + ICDR);
ret = PTR_ERR(pd->dma_tx);
if (ret == -EPROBE_DEFER) {
sh_mobile_i2c_release_dma(pd);
return ret;
Expand Down

0 comments on commit e844a79

Please sign in to comment.