aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-sh_mobile.c
diff options
context:
space:
mode:
authorWolfram Sang <wsa+renesas@sang-engineering.com>2014-12-16 07:31:26 -0500
committerWolfram Sang <wsa@the-dreams.de>2014-12-17 13:26:08 -0500
commit55f5f9862a31e2ac9defea5f30e413d331d1f932 (patch)
treeccefc8ac5c8122a5afd37506d1a9d9817031eb1c /drivers/i2c/busses/i2c-sh_mobile.c
parente844a7997dfbce687c7afa9d40f8a3b278e08735 (diff)
i2c: sh_mobile: rework deferred probing
DMA is opt-in for this driver. So, we can't use deferred probing for requesting DMA channels in probe, because our driver would get endlessly deferred if DMA support is compiled in AND the DMA driver is missing. Because we can't know when the DMA driver might show up, we always try again when a DMA transfer would be possible. The downside is that there is more overhead for setting up PIO transfers under the above scenario. But well, having DMA enabled and the proper DMA driver missing looks like a broken or test config anyhow. Reported-by: Geert Uytterhoeven <geert+renesas@glider.be> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c/busses/i2c-sh_mobile.c')
-rw-r--r--drivers/i2c/busses/i2c-sh_mobile.c98
1 files changed, 48 insertions, 50 deletions
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
index b49e946b2940..a12297e7680a 100644
--- a/drivers/i2c/busses/i2c-sh_mobile.c
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
@@ -140,6 +140,7 @@ struct sh_mobile_i2c_data {
140 int sr; 140 int sr;
141 bool send_stop; 141 bool send_stop;
142 142
143 struct resource *res;
143 struct dma_chan *dma_tx; 144 struct dma_chan *dma_tx;
144 struct dma_chan *dma_rx; 145 struct dma_chan *dma_rx;
145 struct scatterlist sg; 146 struct scatterlist sg;
@@ -539,6 +540,41 @@ static void sh_mobile_i2c_dma_callback(void *data)
539 iic_set_clr(pd, ICIC, 0, ICIC_TDMAE | ICIC_RDMAE); 540 iic_set_clr(pd, ICIC, 0, ICIC_TDMAE | ICIC_RDMAE);
540} 541}
541 542
543static struct dma_chan *sh_mobile_i2c_request_dma_chan(struct device *dev,
544 enum dma_transfer_direction dir, dma_addr_t port_addr)
545{
546 struct dma_chan *chan;
547 struct dma_slave_config cfg;
548 char *chan_name = dir == DMA_MEM_TO_DEV ? "tx" : "rx";
549 int ret;
550
551 chan = dma_request_slave_channel_reason(dev, chan_name);
552 if (IS_ERR(chan)) {
553 dev_dbg(dev, "request_channel failed for %s (%d)\n", chan_name, ret);
554 return chan;
555 }
556
557 memset(&cfg, 0, sizeof(cfg));
558 cfg.direction = dir;
559 if (dir == DMA_MEM_TO_DEV) {
560 cfg.dst_addr = port_addr;
561 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
562 } else {
563 cfg.src_addr = port_addr;
564 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
565 }
566
567 ret = dmaengine_slave_config(chan, &cfg);
568 if (ret) {
569 dev_dbg(dev, "slave_config failed for %s (%d)\n", chan_name, ret);
570 dma_release_channel(chan);
571 return ERR_PTR(ret);
572 }
573
574 dev_dbg(dev, "got DMA channel for %s\n", chan_name);
575 return chan;
576}
577
542static void sh_mobile_i2c_xfer_dma(struct sh_mobile_i2c_data *pd) 578static void sh_mobile_i2c_xfer_dma(struct sh_mobile_i2c_data *pd)
543{ 579{
544 bool read = pd->msg->flags & I2C_M_RD; 580 bool read = pd->msg->flags & I2C_M_RD;
@@ -548,6 +584,15 @@ static void sh_mobile_i2c_xfer_dma(struct sh_mobile_i2c_data *pd)
548 dma_addr_t dma_addr; 584 dma_addr_t dma_addr;
549 dma_cookie_t cookie; 585 dma_cookie_t cookie;
550 586
587 if (PTR_ERR(chan) == -EPROBE_DEFER) {
588 if (read)
589 chan = pd->dma_rx = sh_mobile_i2c_request_dma_chan(pd->dev, DMA_DEV_TO_MEM,
590 pd->res->start + ICDR);
591 else
592 chan = pd->dma_tx = sh_mobile_i2c_request_dma_chan(pd->dev, DMA_MEM_TO_DEV,
593 pd->res->start + ICDR);
594 }
595
551 if (IS_ERR(chan)) 596 if (IS_ERR(chan))
552 return; 597 return;
553 598
@@ -747,41 +792,6 @@ static const struct of_device_id sh_mobile_i2c_dt_ids[] = {
747}; 792};
748MODULE_DEVICE_TABLE(of, sh_mobile_i2c_dt_ids); 793MODULE_DEVICE_TABLE(of, sh_mobile_i2c_dt_ids);
749 794
750static struct dma_chan *sh_mobile_i2c_request_dma_chan(struct device *dev,
751 enum dma_transfer_direction dir, dma_addr_t port_addr)
752{
753 struct dma_chan *chan;
754 struct dma_slave_config cfg;
755 char *chan_name = dir == DMA_MEM_TO_DEV ? "tx" : "rx";
756 int ret;
757
758 chan = dma_request_slave_channel_reason(dev, chan_name);
759 if (IS_ERR(chan)) {
760 dev_dbg(dev, "request_channel failed for %s (%d)\n", chan_name, ret);
761 return chan;
762 }
763
764 memset(&cfg, 0, sizeof(cfg));
765 cfg.direction = dir;
766 if (dir == DMA_MEM_TO_DEV) {
767 cfg.dst_addr = port_addr;
768 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
769 } else {
770 cfg.src_addr = port_addr;
771 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
772 }
773
774 ret = dmaengine_slave_config(chan, &cfg);
775 if (ret) {
776 dev_dbg(dev, "slave_config failed for %s (%d)\n", chan_name, ret);
777 dma_release_channel(chan);
778 return ERR_PTR(ret);
779 }
780
781 dev_dbg(dev, "got DMA channel for %s\n", chan_name);
782 return chan;
783}
784
785static void sh_mobile_i2c_release_dma(struct sh_mobile_i2c_data *pd) 795static void sh_mobile_i2c_release_dma(struct sh_mobile_i2c_data *pd)
786{ 796{
787 if (!IS_ERR(pd->dma_tx)) { 797 if (!IS_ERR(pd->dma_tx)) {
@@ -844,6 +854,7 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
844 854
845 res = platform_get_resource(dev, IORESOURCE_MEM, 0); 855 res = platform_get_resource(dev, IORESOURCE_MEM, 0);
846 856
857 pd->res = res;
847 pd->reg = devm_ioremap_resource(&dev->dev, res); 858 pd->reg = devm_ioremap_resource(&dev->dev, res);
848 if (IS_ERR(pd->reg)) 859 if (IS_ERR(pd->reg))
849 return PTR_ERR(pd->reg); 860 return PTR_ERR(pd->reg);
@@ -884,19 +895,7 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
884 /* Init DMA */ 895 /* Init DMA */
885 sg_init_table(&pd->sg, 1); 896 sg_init_table(&pd->sg, 1);
886 pd->dma_direction = DMA_NONE; 897 pd->dma_direction = DMA_NONE;
887 pd->dma_rx = sh_mobile_i2c_request_dma_chan(pd->dev, DMA_DEV_TO_MEM, 898 pd->dma_rx = pd->dma_tx = ERR_PTR(-EPROBE_DEFER);
888 res->start + ICDR);
889 ret = PTR_ERR(pd->dma_rx);
890 if (ret == -EPROBE_DEFER)
891 return ret;
892
893 pd->dma_tx = sh_mobile_i2c_request_dma_chan(pd->dev, DMA_MEM_TO_DEV,
894 res->start + ICDR);
895 ret = PTR_ERR(pd->dma_tx);
896 if (ret == -EPROBE_DEFER) {
897 sh_mobile_i2c_release_dma(pd);
898 return ret;
899 }
900 899
901 /* Enable Runtime PM for this device. 900 /* Enable Runtime PM for this device.
902 * 901 *
@@ -934,8 +933,7 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
934 return ret; 933 return ret;
935 } 934 }
936 935
937 dev_info(&dev->dev, "I2C adapter %d, bus speed %lu Hz, DMA=%c\n", 936 dev_info(&dev->dev, "I2C adapter %d, bus speed %lu Hz\n", adap->nr, pd->bus_speed);
938 adap->nr, pd->bus_speed, (pd->dma_rx || pd->dma_tx) ? 'y' : 'n');
939 937
940 return 0; 938 return 0;
941} 939}