Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dma: mxs-dma: move to generic device tree binding

Update mxs-dma driver to adopt generic DMA device tree binding. It
calls of_dma_controller_register() with mxs specific of_dma_xlate to
get the generic DMA device tree helper support. Then DMA clients only
need to call dma_request_slave_channel() for requesting a DMA channel
from dmaengine.

The existing way of requesting channel, clients directly call
dma_request_channel(), still work there, and will be removed after
all mxs-dma clients get converted to generic DMA device tree helper.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>

Shawn Guo d84f638b aaa20517

+66 -4
+66 -4
drivers/dma/mxs-dma.c
··· 27 27 #include <linux/stmp_device.h> 28 28 #include <linux/of.h> 29 29 #include <linux/of_device.h> 30 + #include <linux/of_dma.h> 30 31 31 32 #include <asm/irq.h> 32 33 ··· 140 139 struct dma_device dma_device; 141 140 struct device_dma_parameters dma_parms; 142 141 struct mxs_dma_chan mxs_chans[MXS_DMA_CHANNELS]; 142 + struct platform_device *pdev; 143 + unsigned int nr_channels; 143 144 }; 144 145 145 146 struct mxs_dma_type { ··· 353 350 struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma; 354 351 int ret; 355 352 356 - if (!data) 357 - return -EINVAL; 358 - 359 - mxs_chan->chan_irq = data->chan_irq; 353 + if (data) 354 + mxs_chan->chan_irq = data->chan_irq; 360 355 361 356 mxs_chan->ccw = dma_alloc_coherent(mxs_dma->dma_device.dev, 362 357 CCW_BLOCK_SIZE, &mxs_chan->ccw_phys, ··· 666 665 return ret; 667 666 } 668 667 668 + struct mxs_dma_filter_param { 669 + struct device_node *of_node; 670 + unsigned int chan_id; 671 + }; 672 + 673 + static bool mxs_dma_filter_fn(struct dma_chan *chan, void *fn_param) 674 + { 675 + struct mxs_dma_filter_param *param = fn_param; 676 + struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan); 677 + struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma; 678 + int chan_irq; 679 + 680 + if (mxs_dma->dma_device.dev->of_node != param->of_node) 681 + return false; 682 + 683 + if (chan->chan_id != param->chan_id) 684 + return false; 685 + 686 + chan_irq = platform_get_irq(mxs_dma->pdev, param->chan_id); 687 + if (chan_irq < 0) 688 + return false; 689 + 690 + mxs_chan->chan_irq = chan_irq; 691 + 692 + return true; 693 + } 694 + 695 + struct dma_chan *mxs_dma_xlate(struct of_phandle_args *dma_spec, 696 + struct of_dma *ofdma) 697 + { 698 + struct mxs_dma_engine *mxs_dma = ofdma->of_dma_data; 699 + dma_cap_mask_t mask = mxs_dma->dma_device.cap_mask; 700 + struct mxs_dma_filter_param param; 701 + 702 + if (dma_spec->args_count != 1) 703 + return NULL; 704 + 705 + param.of_node = ofdma->of_node; 706 + param.chan_id = dma_spec->args[0]; 707 + 708 + if (param.chan_id >= mxs_dma->nr_channels) 709 + return NULL; 710 + 711 + return dma_request_channel(mask, mxs_dma_filter_fn, &param); 712 + } 713 + 669 714 static int __init mxs_dma_probe(struct platform_device *pdev) 670 715 { 716 + struct device_node *np = pdev->dev.of_node; 671 717 const struct platform_device_id *id_entry; 672 718 const struct of_device_id *of_id; 673 719 const struct mxs_dma_type *dma_type; ··· 725 677 mxs_dma = devm_kzalloc(&pdev->dev, sizeof(*mxs_dma), GFP_KERNEL); 726 678 if (!mxs_dma) 727 679 return -ENOMEM; 680 + 681 + ret = of_property_read_u32(np, "dma-channels", &mxs_dma->nr_channels); 682 + if (ret) { 683 + dev_err(&pdev->dev, "failed to read dma-channels\n"); 684 + return ret; 685 + } 728 686 729 687 of_id = of_match_device(mxs_dma_dt_ids, &pdev->dev); 730 688 if (of_id) ··· 777 723 if (ret) 778 724 return ret; 779 725 726 + mxs_dma->pdev = pdev; 780 727 mxs_dma->dma_device.dev = &pdev->dev; 781 728 782 729 /* mxs_dma gets 65535 bytes maximum sg size */ ··· 796 741 if (ret) { 797 742 dev_err(mxs_dma->dma_device.dev, "unable to register\n"); 798 743 return ret; 744 + } 745 + 746 + ret = of_dma_controller_register(np, mxs_dma_xlate, mxs_dma); 747 + if (ret) { 748 + dev_err(mxs_dma->dma_device.dev, 749 + "failed to register controller\n"); 750 + dma_async_device_unregister(&mxs_dma->dma_device); 799 751 } 800 752 801 753 dev_info(mxs_dma->dma_device.dev, "initialized\n");