diff options
author | Wolfram Sang <wsa+renesas@sang-engineering.com> | 2014-12-16 07:31:25 -0500 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2014-12-17 13:26:07 -0500 |
commit | e844a7997dfbce687c7afa9d40f8a3b278e08735 (patch) | |
tree | 10b94485c39112e0bdd4b81f1360bea1a281a2cc /drivers/i2c/busses | |
parent | 00d8689b85a7bb37cc57ba4c40bd46325f51ced4 (diff) |
i2c: sh_mobile: refactor DMA setup
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>
Diffstat (limited to 'drivers/i2c/busses')
-rw-r--r-- | drivers/i2c/busses/i2c-sh_mobile.c | 35 |
1 files changed, 16 insertions, 19 deletions
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index d7efaf44868b..b49e946b2940 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c | |||
@@ -548,7 +548,7 @@ static void sh_mobile_i2c_xfer_dma(struct sh_mobile_i2c_data *pd) | |||
548 | dma_addr_t dma_addr; | 548 | dma_addr_t dma_addr; |
549 | dma_cookie_t cookie; | 549 | dma_cookie_t cookie; |
550 | 550 | ||
551 | if (!chan) | 551 | if (IS_ERR(chan)) |
552 | return; | 552 | return; |
553 | 553 | ||
554 | dma_addr = dma_map_single(chan->device->dev, pd->msg->buf, pd->msg->len, dir); | 554 | dma_addr = dma_map_single(chan->device->dev, pd->msg->buf, pd->msg->len, dir); |
@@ -747,21 +747,18 @@ static const struct of_device_id sh_mobile_i2c_dt_ids[] = { | |||
747 | }; | 747 | }; |
748 | MODULE_DEVICE_TABLE(of, sh_mobile_i2c_dt_ids); | 748 | MODULE_DEVICE_TABLE(of, sh_mobile_i2c_dt_ids); |
749 | 749 | ||
750 | static int sh_mobile_i2c_request_dma_chan(struct device *dev, enum dma_transfer_direction dir, | 750 | static struct dma_chan *sh_mobile_i2c_request_dma_chan(struct device *dev, |
751 | dma_addr_t port_addr, struct dma_chan **chan_ptr) | 751 | enum dma_transfer_direction dir, dma_addr_t port_addr) |
752 | { | 752 | { |
753 | struct dma_chan *chan; | 753 | struct dma_chan *chan; |
754 | struct dma_slave_config cfg; | 754 | struct dma_slave_config cfg; |
755 | char *chan_name = dir == DMA_MEM_TO_DEV ? "tx" : "rx"; | 755 | char *chan_name = dir == DMA_MEM_TO_DEV ? "tx" : "rx"; |
756 | int ret; | 756 | int ret; |
757 | 757 | ||
758 | *chan_ptr = NULL; | ||
759 | |||
760 | chan = dma_request_slave_channel_reason(dev, chan_name); | 758 | chan = dma_request_slave_channel_reason(dev, chan_name); |
761 | if (IS_ERR(chan)) { | 759 | if (IS_ERR(chan)) { |
762 | ret = PTR_ERR(chan); | ||
763 | dev_dbg(dev, "request_channel failed for %s (%d)\n", chan_name, ret); | 760 | dev_dbg(dev, "request_channel failed for %s (%d)\n", chan_name, ret); |
764 | return ret; | 761 | return chan; |
765 | } | 762 | } |
766 | 763 | ||
767 | memset(&cfg, 0, sizeof(cfg)); | 764 | memset(&cfg, 0, sizeof(cfg)); |
@@ -778,25 +775,23 @@ static int sh_mobile_i2c_request_dma_chan(struct device *dev, enum dma_transfer_ | |||
778 | if (ret) { | 775 | if (ret) { |
779 | dev_dbg(dev, "slave_config failed for %s (%d)\n", chan_name, ret); | 776 | dev_dbg(dev, "slave_config failed for %s (%d)\n", chan_name, ret); |
780 | dma_release_channel(chan); | 777 | dma_release_channel(chan); |
781 | return ret; | 778 | return ERR_PTR(ret); |
782 | } | 779 | } |
783 | 780 | ||
784 | *chan_ptr = chan; | ||
785 | |||
786 | dev_dbg(dev, "got DMA channel for %s\n", chan_name); | 781 | dev_dbg(dev, "got DMA channel for %s\n", chan_name); |
787 | return 0; | 782 | return chan; |
788 | } | 783 | } |
789 | 784 | ||
790 | static void sh_mobile_i2c_release_dma(struct sh_mobile_i2c_data *pd) | 785 | static void sh_mobile_i2c_release_dma(struct sh_mobile_i2c_data *pd) |
791 | { | 786 | { |
792 | if (pd->dma_tx) { | 787 | if (!IS_ERR(pd->dma_tx)) { |
793 | dma_release_channel(pd->dma_tx); | 788 | dma_release_channel(pd->dma_tx); |
794 | pd->dma_tx = NULL; | 789 | pd->dma_tx = ERR_PTR(-EPROBE_DEFER); |
795 | } | 790 | } |
796 | 791 | ||
797 | if (pd->dma_rx) { | 792 | if (!IS_ERR(pd->dma_rx)) { |
798 | dma_release_channel(pd->dma_rx); | 793 | dma_release_channel(pd->dma_rx); |
799 | pd->dma_rx = NULL; | 794 | pd->dma_rx = ERR_PTR(-EPROBE_DEFER); |
800 | } | 795 | } |
801 | } | 796 | } |
802 | 797 | ||
@@ -889,13 +884,15 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) | |||
889 | /* Init DMA */ | 884 | /* Init DMA */ |
890 | sg_init_table(&pd->sg, 1); | 885 | sg_init_table(&pd->sg, 1); |
891 | pd->dma_direction = DMA_NONE; | 886 | pd->dma_direction = DMA_NONE; |
892 | ret = sh_mobile_i2c_request_dma_chan(pd->dev, DMA_DEV_TO_MEM, | 887 | pd->dma_rx = sh_mobile_i2c_request_dma_chan(pd->dev, DMA_DEV_TO_MEM, |
893 | res->start + ICDR, &pd->dma_rx); | 888 | res->start + ICDR); |
889 | ret = PTR_ERR(pd->dma_rx); | ||
894 | if (ret == -EPROBE_DEFER) | 890 | if (ret == -EPROBE_DEFER) |
895 | return ret; | 891 | return ret; |
896 | 892 | ||
897 | ret = sh_mobile_i2c_request_dma_chan(pd->dev, DMA_MEM_TO_DEV, | 893 | pd->dma_tx = sh_mobile_i2c_request_dma_chan(pd->dev, DMA_MEM_TO_DEV, |
898 | res->start + ICDR, &pd->dma_tx); | 894 | res->start + ICDR); |
895 | ret = PTR_ERR(pd->dma_tx); | ||
899 | if (ret == -EPROBE_DEFER) { | 896 | if (ret == -EPROBE_DEFER) { |
900 | sh_mobile_i2c_release_dma(pd); | 897 | sh_mobile_i2c_release_dma(pd); |
901 | return ret; | 898 | return ret; |