diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-07 14:06:17 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-07 14:06:17 -0400 |
commit | 38f56f33ca381751f9b8910f67e7a805ec0b68cb (patch) | |
tree | 202f2ce60f3f43a948607ec76c8cc48c1cf73a4b /drivers | |
parent | fcba914542082b272f31c8e4c40000b88ed3208d (diff) | |
parent | 4183bef2e093a2f0aab45f2d5fed82b0e02aeacf (diff) |
Merge tag 'dt-for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC device tree updates (part 2) from Arnd Bergmann:
"These are mostly new device tree bindings for existing drivers, as
well as changes to the device tree source files to add support for
those devices, and a couple of new boards, most notably Samsung's
Exynos5 based Chromebook.
The changes depend on earlier platform specific updates and touch the
usual platforms: omap, exynos, tegra, mxs, mvebu and davinci."
* tag 'dt-for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (169 commits)
ARM: exynos: dts: cros5250: add EC device
ARM: dts: Add sbs-battery for exynos5250-snow
ARM: dts: Add i2c-arbitrator bus for exynos5250-snow
ARM: dts: add mshc controller node for Exynos4x12 SoCs
ARM: dts: Add chip-id controller node on Exynos4/5 SoC
ARM: EXYNOS: Create virtual I/O mapping for Chip-ID controller using device tree
ARM: davinci: da850-evm: add SPI flash support
ARM: davinci: da850: override SPI DT node device name
ARM: davinci: da850: add SPI1 DT node
spi/davinci: add DT binding documentation
spi/davinci: no wildcards in DT compatible property
ARM: dts: mvebu: Convert mvebu device tree files to 64 bits
ARM: dts: mvebu: introduce internal-regs node
ARM: dts: mvebu: Convert all the mvebu files to use the range property
ARM: dts: mvebu: move all peripherals inside soc
ARM: dts: mvebu: fix cpus section indentation
ARM: davinci: da850: add EHRPWM & ECAP DT node
ARM/dts: OMAP3: fix pinctrl-single configuration
ARM: dts: Add OMAP3430 SDP NOR flash memory binding
ARM: dts: Add NOR flash bindings for OMAP2420 H4
...
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/dma/mxs-dma.c | 109 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-mxs.c | 40 | ||||
-rw-r--r-- | drivers/mmc/host/mxs-mmc.c | 48 | ||||
-rw-r--r-- | drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 51 | ||||
-rw-r--r-- | drivers/mtd/nand/gpmi-nand/gpmi-nand.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/fec.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/fec_main.c | 18 | ||||
-rw-r--r-- | drivers/spi/spi-davinci.c | 4 | ||||
-rw-r--r-- | drivers/spi/spi-mxs.c | 60 | ||||
-rw-r--r-- | drivers/tty/serial/mxs-auart.c | 52 | ||||
-rw-r--r-- | drivers/video/Kconfig | 2 | ||||
-rw-r--r-- | drivers/video/mxsfb.c | 260 |
12 files changed, 272 insertions, 376 deletions
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c index 8f6d30d37c45..b48a79c28845 100644 --- a/drivers/dma/mxs-dma.c +++ b/drivers/dma/mxs-dma.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/stmp_device.h> | 27 | #include <linux/stmp_device.h> |
28 | #include <linux/of.h> | 28 | #include <linux/of.h> |
29 | #include <linux/of_device.h> | 29 | #include <linux/of_device.h> |
30 | #include <linux/of_dma.h> | ||
30 | 31 | ||
31 | #include <asm/irq.h> | 32 | #include <asm/irq.h> |
32 | 33 | ||
@@ -139,6 +140,8 @@ struct mxs_dma_engine { | |||
139 | struct dma_device dma_device; | 140 | struct dma_device dma_device; |
140 | struct device_dma_parameters dma_parms; | 141 | struct device_dma_parameters dma_parms; |
141 | struct mxs_dma_chan mxs_chans[MXS_DMA_CHANNELS]; | 142 | struct mxs_dma_chan mxs_chans[MXS_DMA_CHANNELS]; |
143 | struct platform_device *pdev; | ||
144 | unsigned int nr_channels; | ||
142 | }; | 145 | }; |
143 | 146 | ||
144 | struct mxs_dma_type { | 147 | struct mxs_dma_type { |
@@ -350,10 +353,8 @@ static int mxs_dma_alloc_chan_resources(struct dma_chan *chan) | |||
350 | struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma; | 353 | struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma; |
351 | int ret; | 354 | int ret; |
352 | 355 | ||
353 | if (!data) | 356 | if (data) |
354 | return -EINVAL; | 357 | mxs_chan->chan_irq = data->chan_irq; |
355 | |||
356 | mxs_chan->chan_irq = data->chan_irq; | ||
357 | 358 | ||
358 | mxs_chan->ccw = dma_alloc_coherent(mxs_dma->dma_device.dev, | 359 | mxs_chan->ccw = dma_alloc_coherent(mxs_dma->dma_device.dev, |
359 | CCW_BLOCK_SIZE, &mxs_chan->ccw_phys, | 360 | CCW_BLOCK_SIZE, &mxs_chan->ccw_phys, |
@@ -665,8 +666,55 @@ err_out: | |||
665 | return ret; | 666 | return ret; |
666 | } | 667 | } |
667 | 668 | ||
669 | struct mxs_dma_filter_param { | ||
670 | struct device_node *of_node; | ||
671 | unsigned int chan_id; | ||
672 | }; | ||
673 | |||
674 | static bool mxs_dma_filter_fn(struct dma_chan *chan, void *fn_param) | ||
675 | { | ||
676 | struct mxs_dma_filter_param *param = fn_param; | ||
677 | struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan); | ||
678 | struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma; | ||
679 | int chan_irq; | ||
680 | |||
681 | if (mxs_dma->dma_device.dev->of_node != param->of_node) | ||
682 | return false; | ||
683 | |||
684 | if (chan->chan_id != param->chan_id) | ||
685 | return false; | ||
686 | |||
687 | chan_irq = platform_get_irq(mxs_dma->pdev, param->chan_id); | ||
688 | if (chan_irq < 0) | ||
689 | return false; | ||
690 | |||
691 | mxs_chan->chan_irq = chan_irq; | ||
692 | |||
693 | return true; | ||
694 | } | ||
695 | |||
696 | struct dma_chan *mxs_dma_xlate(struct of_phandle_args *dma_spec, | ||
697 | struct of_dma *ofdma) | ||
698 | { | ||
699 | struct mxs_dma_engine *mxs_dma = ofdma->of_dma_data; | ||
700 | dma_cap_mask_t mask = mxs_dma->dma_device.cap_mask; | ||
701 | struct mxs_dma_filter_param param; | ||
702 | |||
703 | if (dma_spec->args_count != 1) | ||
704 | return NULL; | ||
705 | |||
706 | param.of_node = ofdma->of_node; | ||
707 | param.chan_id = dma_spec->args[0]; | ||
708 | |||
709 | if (param.chan_id >= mxs_dma->nr_channels) | ||
710 | return NULL; | ||
711 | |||
712 | return dma_request_channel(mask, mxs_dma_filter_fn, ¶m); | ||
713 | } | ||
714 | |||
668 | static int __init mxs_dma_probe(struct platform_device *pdev) | 715 | static int __init mxs_dma_probe(struct platform_device *pdev) |
669 | { | 716 | { |
717 | struct device_node *np = pdev->dev.of_node; | ||
670 | const struct platform_device_id *id_entry; | 718 | const struct platform_device_id *id_entry; |
671 | const struct of_device_id *of_id; | 719 | const struct of_device_id *of_id; |
672 | const struct mxs_dma_type *dma_type; | 720 | const struct mxs_dma_type *dma_type; |
@@ -674,10 +722,16 @@ static int __init mxs_dma_probe(struct platform_device *pdev) | |||
674 | struct resource *iores; | 722 | struct resource *iores; |
675 | int ret, i; | 723 | int ret, i; |
676 | 724 | ||
677 | mxs_dma = kzalloc(sizeof(*mxs_dma), GFP_KERNEL); | 725 | mxs_dma = devm_kzalloc(&pdev->dev, sizeof(*mxs_dma), GFP_KERNEL); |
678 | if (!mxs_dma) | 726 | if (!mxs_dma) |
679 | return -ENOMEM; | 727 | return -ENOMEM; |
680 | 728 | ||
729 | ret = of_property_read_u32(np, "dma-channels", &mxs_dma->nr_channels); | ||
730 | if (ret) { | ||
731 | dev_err(&pdev->dev, "failed to read dma-channels\n"); | ||
732 | return ret; | ||
733 | } | ||
734 | |||
681 | of_id = of_match_device(mxs_dma_dt_ids, &pdev->dev); | 735 | of_id = of_match_device(mxs_dma_dt_ids, &pdev->dev); |
682 | if (of_id) | 736 | if (of_id) |
683 | id_entry = of_id->data; | 737 | id_entry = of_id->data; |
@@ -689,24 +743,13 @@ static int __init mxs_dma_probe(struct platform_device *pdev) | |||
689 | mxs_dma->dev_id = dma_type->id; | 743 | mxs_dma->dev_id = dma_type->id; |
690 | 744 | ||
691 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 745 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
746 | mxs_dma->base = devm_ioremap_resource(&pdev->dev, iores); | ||
747 | if (IS_ERR(mxs_dma->base)) | ||
748 | return PTR_ERR(mxs_dma->base); | ||
692 | 749 | ||
693 | if (!request_mem_region(iores->start, resource_size(iores), | 750 | mxs_dma->clk = devm_clk_get(&pdev->dev, NULL); |
694 | pdev->name)) { | 751 | if (IS_ERR(mxs_dma->clk)) |
695 | ret = -EBUSY; | 752 | return PTR_ERR(mxs_dma->clk); |
696 | goto err_request_region; | ||
697 | } | ||
698 | |||
699 | mxs_dma->base = ioremap(iores->start, resource_size(iores)); | ||
700 | if (!mxs_dma->base) { | ||
701 | ret = -ENOMEM; | ||
702 | goto err_ioremap; | ||
703 | } | ||
704 | |||
705 | mxs_dma->clk = clk_get(&pdev->dev, NULL); | ||
706 | if (IS_ERR(mxs_dma->clk)) { | ||
707 | ret = PTR_ERR(mxs_dma->clk); | ||
708 | goto err_clk; | ||
709 | } | ||
710 | 753 | ||
711 | dma_cap_set(DMA_SLAVE, mxs_dma->dma_device.cap_mask); | 754 | dma_cap_set(DMA_SLAVE, mxs_dma->dma_device.cap_mask); |
712 | dma_cap_set(DMA_CYCLIC, mxs_dma->dma_device.cap_mask); | 755 | dma_cap_set(DMA_CYCLIC, mxs_dma->dma_device.cap_mask); |
@@ -732,8 +775,9 @@ static int __init mxs_dma_probe(struct platform_device *pdev) | |||
732 | 775 | ||
733 | ret = mxs_dma_init(mxs_dma); | 776 | ret = mxs_dma_init(mxs_dma); |
734 | if (ret) | 777 | if (ret) |
735 | goto err_init; | 778 | return ret; |
736 | 779 | ||
780 | mxs_dma->pdev = pdev; | ||
737 | mxs_dma->dma_device.dev = &pdev->dev; | 781 | mxs_dma->dma_device.dev = &pdev->dev; |
738 | 782 | ||
739 | /* mxs_dma gets 65535 bytes maximum sg size */ | 783 | /* mxs_dma gets 65535 bytes maximum sg size */ |
@@ -751,22 +795,19 @@ static int __init mxs_dma_probe(struct platform_device *pdev) | |||
751 | ret = dma_async_device_register(&mxs_dma->dma_device); | 795 | ret = dma_async_device_register(&mxs_dma->dma_device); |
752 | if (ret) { | 796 | if (ret) { |
753 | dev_err(mxs_dma->dma_device.dev, "unable to register\n"); | 797 | dev_err(mxs_dma->dma_device.dev, "unable to register\n"); |
754 | goto err_init; | 798 | return ret; |
799 | } | ||
800 | |||
801 | ret = of_dma_controller_register(np, mxs_dma_xlate, mxs_dma); | ||
802 | if (ret) { | ||
803 | dev_err(mxs_dma->dma_device.dev, | ||
804 | "failed to register controller\n"); | ||
805 | dma_async_device_unregister(&mxs_dma->dma_device); | ||
755 | } | 806 | } |
756 | 807 | ||
757 | dev_info(mxs_dma->dma_device.dev, "initialized\n"); | 808 | dev_info(mxs_dma->dma_device.dev, "initialized\n"); |
758 | 809 | ||
759 | return 0; | 810 | return 0; |
760 | |||
761 | err_init: | ||
762 | clk_put(mxs_dma->clk); | ||
763 | err_clk: | ||
764 | iounmap(mxs_dma->base); | ||
765 | err_ioremap: | ||
766 | release_mem_region(iores->start, resource_size(iores)); | ||
767 | err_request_region: | ||
768 | kfree(mxs_dma); | ||
769 | return ret; | ||
770 | } | 811 | } |
771 | 812 | ||
772 | static struct platform_driver mxs_dma_driver = { | 813 | static struct platform_driver mxs_dma_driver = { |
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index c67d89fc6254..2039f230482d 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/of_i2c.h> | 31 | #include <linux/of_i2c.h> |
32 | #include <linux/dma-mapping.h> | 32 | #include <linux/dma-mapping.h> |
33 | #include <linux/dmaengine.h> | 33 | #include <linux/dmaengine.h> |
34 | #include <linux/fsl/mxs-dma.h> | ||
35 | 34 | ||
36 | #define DRIVER_NAME "mxs-i2c" | 35 | #define DRIVER_NAME "mxs-i2c" |
37 | 36 | ||
@@ -118,9 +117,7 @@ struct mxs_i2c_dev { | |||
118 | uint32_t timing1; | 117 | uint32_t timing1; |
119 | 118 | ||
120 | /* DMA support components */ | 119 | /* DMA support components */ |
121 | int dma_channel; | ||
122 | struct dma_chan *dmach; | 120 | struct dma_chan *dmach; |
123 | struct mxs_dma_data dma_data; | ||
124 | uint32_t pio_data[2]; | 121 | uint32_t pio_data[2]; |
125 | uint32_t addr_data; | 122 | uint32_t addr_data; |
126 | struct scatterlist sg_io[2]; | 123 | struct scatterlist sg_io[2]; |
@@ -581,21 +578,6 @@ static const struct i2c_algorithm mxs_i2c_algo = { | |||
581 | .functionality = mxs_i2c_func, | 578 | .functionality = mxs_i2c_func, |
582 | }; | 579 | }; |
583 | 580 | ||
584 | static bool mxs_i2c_dma_filter(struct dma_chan *chan, void *param) | ||
585 | { | ||
586 | struct mxs_i2c_dev *i2c = param; | ||
587 | |||
588 | if (!mxs_dma_is_apbx(chan)) | ||
589 | return false; | ||
590 | |||
591 | if (chan->chan_id != i2c->dma_channel) | ||
592 | return false; | ||
593 | |||
594 | chan->private = &i2c->dma_data; | ||
595 | |||
596 | return true; | ||
597 | } | ||
598 | |||
599 | static void mxs_i2c_derive_timing(struct mxs_i2c_dev *i2c, int speed) | 581 | static void mxs_i2c_derive_timing(struct mxs_i2c_dev *i2c, int speed) |
600 | { | 582 | { |
601 | /* The I2C block clock run at 24MHz */ | 583 | /* The I2C block clock run at 24MHz */ |
@@ -640,17 +622,6 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c) | |||
640 | struct device_node *node = dev->of_node; | 622 | struct device_node *node = dev->of_node; |
641 | int ret; | 623 | int ret; |
642 | 624 | ||
643 | /* | ||
644 | * TODO: This is a temporary solution and should be changed | ||
645 | * to use generic DMA binding later when the helpers get in. | ||
646 | */ | ||
647 | ret = of_property_read_u32(node, "fsl,i2c-dma-channel", | ||
648 | &i2c->dma_channel); | ||
649 | if (ret) { | ||
650 | dev_err(dev, "Failed to get DMA channel!\n"); | ||
651 | return -ENODEV; | ||
652 | } | ||
653 | |||
654 | ret = of_property_read_u32(node, "clock-frequency", &speed); | 625 | ret = of_property_read_u32(node, "clock-frequency", &speed); |
655 | if (ret) { | 626 | if (ret) { |
656 | dev_warn(dev, "No I2C speed selected, using 100kHz\n"); | 627 | dev_warn(dev, "No I2C speed selected, using 100kHz\n"); |
@@ -670,8 +641,7 @@ static int mxs_i2c_probe(struct platform_device *pdev) | |||
670 | struct pinctrl *pinctrl; | 641 | struct pinctrl *pinctrl; |
671 | struct resource *res; | 642 | struct resource *res; |
672 | resource_size_t res_size; | 643 | resource_size_t res_size; |
673 | int err, irq, dmairq; | 644 | int err, irq; |
674 | dma_cap_mask_t mask; | ||
675 | 645 | ||
676 | pinctrl = devm_pinctrl_get_select_default(dev); | 646 | pinctrl = devm_pinctrl_get_select_default(dev); |
677 | if (IS_ERR(pinctrl)) | 647 | if (IS_ERR(pinctrl)) |
@@ -683,9 +653,8 @@ static int mxs_i2c_probe(struct platform_device *pdev) | |||
683 | 653 | ||
684 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 654 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
685 | irq = platform_get_irq(pdev, 0); | 655 | irq = platform_get_irq(pdev, 0); |
686 | dmairq = platform_get_irq(pdev, 1); | ||
687 | 656 | ||
688 | if (!res || irq < 0 || dmairq < 0) | 657 | if (!res || irq < 0) |
689 | return -ENOENT; | 658 | return -ENOENT; |
690 | 659 | ||
691 | res_size = resource_size(res); | 660 | res_size = resource_size(res); |
@@ -711,10 +680,7 @@ static int mxs_i2c_probe(struct platform_device *pdev) | |||
711 | } | 680 | } |
712 | 681 | ||
713 | /* Setup the DMA */ | 682 | /* Setup the DMA */ |
714 | dma_cap_zero(mask); | 683 | i2c->dmach = dma_request_slave_channel(dev, "rx-tx"); |
715 | dma_cap_set(DMA_SLAVE, mask); | ||
716 | i2c->dma_data.chan_irq = dmairq; | ||
717 | i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c); | ||
718 | if (!i2c->dmach) { | 684 | if (!i2c->dmach) { |
719 | dev_err(dev, "Failed to request dma\n"); | 685 | dev_err(dev, "Failed to request dma\n"); |
720 | return -ENODEV; | 686 | return -ENODEV; |
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index 146a53bfab71..4278a1787d08 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c | |||
@@ -552,22 +552,6 @@ static const struct mmc_host_ops mxs_mmc_ops = { | |||
552 | .enable_sdio_irq = mxs_mmc_enable_sdio_irq, | 552 | .enable_sdio_irq = mxs_mmc_enable_sdio_irq, |
553 | }; | 553 | }; |
554 | 554 | ||
555 | static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param) | ||
556 | { | ||
557 | struct mxs_mmc_host *host = param; | ||
558 | struct mxs_ssp *ssp = &host->ssp; | ||
559 | |||
560 | if (!mxs_dma_is_apbh(chan)) | ||
561 | return false; | ||
562 | |||
563 | if (chan->chan_id != ssp->dma_channel) | ||
564 | return false; | ||
565 | |||
566 | chan->private = &ssp->dma_data; | ||
567 | |||
568 | return true; | ||
569 | } | ||
570 | |||
571 | static struct platform_device_id mxs_ssp_ids[] = { | 555 | static struct platform_device_id mxs_ssp_ids[] = { |
572 | { | 556 | { |
573 | .name = "imx23-mmc", | 557 | .name = "imx23-mmc", |
@@ -595,20 +579,17 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
595 | struct device_node *np = pdev->dev.of_node; | 579 | struct device_node *np = pdev->dev.of_node; |
596 | struct mxs_mmc_host *host; | 580 | struct mxs_mmc_host *host; |
597 | struct mmc_host *mmc; | 581 | struct mmc_host *mmc; |
598 | struct resource *iores, *dmares; | 582 | struct resource *iores; |
599 | struct pinctrl *pinctrl; | 583 | struct pinctrl *pinctrl; |
600 | int ret = 0, irq_err, irq_dma; | 584 | int ret = 0, irq_err; |
601 | dma_cap_mask_t mask; | ||
602 | struct regulator *reg_vmmc; | 585 | struct regulator *reg_vmmc; |
603 | enum of_gpio_flags flags; | 586 | enum of_gpio_flags flags; |
604 | struct mxs_ssp *ssp; | 587 | struct mxs_ssp *ssp; |
605 | u32 bus_width = 0; | 588 | u32 bus_width = 0; |
606 | 589 | ||
607 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 590 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
608 | dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
609 | irq_err = platform_get_irq(pdev, 0); | 591 | irq_err = platform_get_irq(pdev, 0); |
610 | irq_dma = platform_get_irq(pdev, 1); | 592 | if (!iores || irq_err < 0) |
611 | if (!iores || irq_err < 0 || irq_dma < 0) | ||
612 | return -EINVAL; | 593 | return -EINVAL; |
613 | 594 | ||
614 | mmc = mmc_alloc_host(sizeof(struct mxs_mmc_host), &pdev->dev); | 595 | mmc = mmc_alloc_host(sizeof(struct mxs_mmc_host), &pdev->dev); |
@@ -624,23 +605,7 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
624 | goto out_mmc_free; | 605 | goto out_mmc_free; |
625 | } | 606 | } |
626 | 607 | ||
627 | if (np) { | 608 | ssp->devid = (enum mxs_ssp_id) of_id->data; |
628 | ssp->devid = (enum mxs_ssp_id) of_id->data; | ||
629 | /* | ||
630 | * TODO: This is a temporary solution and should be changed | ||
631 | * to use generic DMA binding later when the helpers get in. | ||
632 | */ | ||
633 | ret = of_property_read_u32(np, "fsl,ssp-dma-channel", | ||
634 | &ssp->dma_channel); | ||
635 | if (ret) { | ||
636 | dev_err(mmc_dev(host->mmc), | ||
637 | "failed to get dma channel\n"); | ||
638 | goto out_mmc_free; | ||
639 | } | ||
640 | } else { | ||
641 | ssp->devid = pdev->id_entry->driver_data; | ||
642 | ssp->dma_channel = dmares->start; | ||
643 | } | ||
644 | 609 | ||
645 | host->mmc = mmc; | 610 | host->mmc = mmc; |
646 | host->sdio_irq_en = 0; | 611 | host->sdio_irq_en = 0; |
@@ -670,10 +635,7 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
670 | 635 | ||
671 | mxs_mmc_reset(host); | 636 | mxs_mmc_reset(host); |
672 | 637 | ||
673 | dma_cap_zero(mask); | 638 | ssp->dmach = dma_request_slave_channel(&pdev->dev, "rx-tx"); |
674 | dma_cap_set(DMA_SLAVE, mask); | ||
675 | ssp->dma_data.chan_irq = irq_dma; | ||
676 | ssp->dmach = dma_request_channel(mask, mxs_mmc_dma_filter, host); | ||
677 | if (!ssp->dmach) { | 639 | if (!ssp->dmach) { |
678 | dev_err(mmc_dev(host->mmc), | 640 | dev_err(mmc_dev(host->mmc), |
679 | "%s: failed to request dma\n", __func__); | 641 | "%s: failed to request dma\n", __func__); |
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 717881a3d1b8..25ecfa1822a8 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME "gpmi-nand" | 36 | #define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME "gpmi-nand" |
37 | #define GPMI_NAND_BCH_REGS_ADDR_RES_NAME "bch" | 37 | #define GPMI_NAND_BCH_REGS_ADDR_RES_NAME "bch" |
38 | #define GPMI_NAND_BCH_INTERRUPT_RES_NAME "bch" | 38 | #define GPMI_NAND_BCH_INTERRUPT_RES_NAME "bch" |
39 | #define GPMI_NAND_DMA_INTERRUPT_RES_NAME "gpmi-dma" | ||
40 | 39 | ||
41 | /* add our owner bbt descriptor */ | 40 | /* add our owner bbt descriptor */ |
42 | static uint8_t scan_ff_pattern[] = { 0xff }; | 41 | static uint8_t scan_ff_pattern[] = { 0xff }; |
@@ -420,28 +419,6 @@ static void release_bch_irq(struct gpmi_nand_data *this) | |||
420 | free_irq(i, this); | 419 | free_irq(i, this); |
421 | } | 420 | } |
422 | 421 | ||
423 | static bool gpmi_dma_filter(struct dma_chan *chan, void *param) | ||
424 | { | ||
425 | struct gpmi_nand_data *this = param; | ||
426 | int dma_channel = (int)this->private; | ||
427 | |||
428 | if (!mxs_dma_is_apbh(chan)) | ||
429 | return false; | ||
430 | /* | ||
431 | * only catch the GPMI dma channels : | ||
432 | * for mx23 : MX23_DMA_GPMI0 ~ MX23_DMA_GPMI3 | ||
433 | * (These four channels share the same IRQ!) | ||
434 | * | ||
435 | * for mx28 : MX28_DMA_GPMI0 ~ MX28_DMA_GPMI7 | ||
436 | * (These eight channels share the same IRQ!) | ||
437 | */ | ||
438 | if (dma_channel == chan->chan_id) { | ||
439 | chan->private = &this->dma_data; | ||
440 | return true; | ||
441 | } | ||
442 | return false; | ||
443 | } | ||
444 | |||
445 | static void release_dma_channels(struct gpmi_nand_data *this) | 422 | static void release_dma_channels(struct gpmi_nand_data *this) |
446 | { | 423 | { |
447 | unsigned int i; | 424 | unsigned int i; |
@@ -455,36 +432,10 @@ static void release_dma_channels(struct gpmi_nand_data *this) | |||
455 | static int acquire_dma_channels(struct gpmi_nand_data *this) | 432 | static int acquire_dma_channels(struct gpmi_nand_data *this) |
456 | { | 433 | { |
457 | struct platform_device *pdev = this->pdev; | 434 | struct platform_device *pdev = this->pdev; |
458 | struct resource *r_dma; | ||
459 | struct device_node *dn; | ||
460 | u32 dma_channel; | ||
461 | int ret; | ||
462 | struct dma_chan *dma_chan; | 435 | struct dma_chan *dma_chan; |
463 | dma_cap_mask_t mask; | ||
464 | |||
465 | /* dma channel, we only use the first one. */ | ||
466 | dn = pdev->dev.of_node; | ||
467 | ret = of_property_read_u32(dn, "fsl,gpmi-dma-channel", &dma_channel); | ||
468 | if (ret) { | ||
469 | pr_err("unable to get DMA channel from dt.\n"); | ||
470 | goto acquire_err; | ||
471 | } | ||
472 | this->private = (void *)dma_channel; | ||
473 | |||
474 | /* gpmi dma interrupt */ | ||
475 | r_dma = platform_get_resource_byname(pdev, IORESOURCE_IRQ, | ||
476 | GPMI_NAND_DMA_INTERRUPT_RES_NAME); | ||
477 | if (!r_dma) { | ||
478 | pr_err("Can't get resource for DMA\n"); | ||
479 | goto acquire_err; | ||
480 | } | ||
481 | this->dma_data.chan_irq = r_dma->start; | ||
482 | 436 | ||
483 | /* request dma channel */ | 437 | /* request dma channel */ |
484 | dma_cap_zero(mask); | 438 | dma_chan = dma_request_slave_channel(&pdev->dev, "rx-tx"); |
485 | dma_cap_set(DMA_SLAVE, mask); | ||
486 | |||
487 | dma_chan = dma_request_channel(mask, gpmi_dma_filter, this); | ||
488 | if (!dma_chan) { | 439 | if (!dma_chan) { |
489 | pr_err("Failed to request DMA channel.\n"); | 440 | pr_err("Failed to request DMA channel.\n"); |
490 | goto acquire_err; | 441 | goto acquire_err; |
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h index 072947731277..a7685e3a8748 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/mtd/nand.h> | 20 | #include <linux/mtd/nand.h> |
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/dma-mapping.h> | 22 | #include <linux/dma-mapping.h> |
23 | #include <linux/fsl/mxs-dma.h> | 23 | #include <linux/dmaengine.h> |
24 | 24 | ||
25 | #define GPMI_CLK_MAX 5 /* MX6Q needs five clocks */ | 25 | #define GPMI_CLK_MAX 5 /* MX6Q needs five clocks */ |
26 | struct resources { | 26 | struct resources { |
@@ -180,7 +180,6 @@ struct gpmi_nand_data { | |||
180 | /* DMA channels */ | 180 | /* DMA channels */ |
181 | #define DMA_CHANS 8 | 181 | #define DMA_CHANS 8 |
182 | struct dma_chan *dma_chans[DMA_CHANS]; | 182 | struct dma_chan *dma_chans[DMA_CHANS]; |
183 | struct mxs_dma_data dma_data; | ||
184 | enum dma_ops_type last_dma_type; | 183 | enum dma_ops_type last_dma_type; |
185 | enum dma_ops_type dma_type; | 184 | enum dma_ops_type dma_type; |
186 | struct completion dma_done; | 185 | struct completion dma_done; |
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index d44f65bac1d4..ceb4d43c132d 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h | |||
@@ -214,6 +214,7 @@ struct fec_enet_private { | |||
214 | 214 | ||
215 | struct clk *clk_ipg; | 215 | struct clk *clk_ipg; |
216 | struct clk *clk_ahb; | 216 | struct clk *clk_ahb; |
217 | struct clk *clk_enet_out; | ||
217 | struct clk *clk_ptp; | 218 | struct clk *clk_ptp; |
218 | 219 | ||
219 | /* The saved address of a sent-in-place packet/buffer, for skfree(). */ | 220 | /* The saved address of a sent-in-place packet/buffer, for skfree(). */ |
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index b9748f14ea78..e25bf832e6b3 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c | |||
@@ -1883,18 +1883,23 @@ fec_probe(struct platform_device *pdev) | |||
1883 | goto failed_clk; | 1883 | goto failed_clk; |
1884 | } | 1884 | } |
1885 | 1885 | ||
1886 | /* enet_out is optional, depends on board */ | ||
1887 | fep->clk_enet_out = devm_clk_get(&pdev->dev, "enet_out"); | ||
1888 | if (IS_ERR(fep->clk_enet_out)) | ||
1889 | fep->clk_enet_out = NULL; | ||
1890 | |||
1886 | fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp"); | 1891 | fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp"); |
1887 | fep->bufdesc_ex = | 1892 | fep->bufdesc_ex = |
1888 | pdev->id_entry->driver_data & FEC_QUIRK_HAS_BUFDESC_EX; | 1893 | pdev->id_entry->driver_data & FEC_QUIRK_HAS_BUFDESC_EX; |
1889 | if (IS_ERR(fep->clk_ptp)) { | 1894 | if (IS_ERR(fep->clk_ptp)) { |
1890 | ret = PTR_ERR(fep->clk_ptp); | 1895 | fep->clk_ptp = NULL; |
1891 | fep->bufdesc_ex = 0; | 1896 | fep->bufdesc_ex = 0; |
1892 | } | 1897 | } |
1893 | 1898 | ||
1894 | clk_prepare_enable(fep->clk_ahb); | 1899 | clk_prepare_enable(fep->clk_ahb); |
1895 | clk_prepare_enable(fep->clk_ipg); | 1900 | clk_prepare_enable(fep->clk_ipg); |
1896 | if (!IS_ERR(fep->clk_ptp)) | 1901 | clk_prepare_enable(fep->clk_enet_out); |
1897 | clk_prepare_enable(fep->clk_ptp); | 1902 | clk_prepare_enable(fep->clk_ptp); |
1898 | 1903 | ||
1899 | reg_phy = devm_regulator_get(&pdev->dev, "phy"); | 1904 | reg_phy = devm_regulator_get(&pdev->dev, "phy"); |
1900 | if (!IS_ERR(reg_phy)) { | 1905 | if (!IS_ERR(reg_phy)) { |
@@ -1962,8 +1967,8 @@ failed_irq: | |||
1962 | failed_regulator: | 1967 | failed_regulator: |
1963 | clk_disable_unprepare(fep->clk_ahb); | 1968 | clk_disable_unprepare(fep->clk_ahb); |
1964 | clk_disable_unprepare(fep->clk_ipg); | 1969 | clk_disable_unprepare(fep->clk_ipg); |
1965 | if (!IS_ERR(fep->clk_ptp)) | 1970 | clk_disable_unprepare(fep->clk_enet_out); |
1966 | clk_disable_unprepare(fep->clk_ptp); | 1971 | clk_disable_unprepare(fep->clk_ptp); |
1967 | failed_pin: | 1972 | failed_pin: |
1968 | failed_clk: | 1973 | failed_clk: |
1969 | failed_ioremap: | 1974 | failed_ioremap: |
@@ -1985,6 +1990,7 @@ fec_drv_remove(struct platform_device *pdev) | |||
1985 | clk_disable_unprepare(fep->clk_ptp); | 1990 | clk_disable_unprepare(fep->clk_ptp); |
1986 | if (fep->ptp_clock) | 1991 | if (fep->ptp_clock) |
1987 | ptp_clock_unregister(fep->ptp_clock); | 1992 | ptp_clock_unregister(fep->ptp_clock); |
1993 | clk_disable_unprepare(fep->clk_enet_out); | ||
1988 | clk_disable_unprepare(fep->clk_ahb); | 1994 | clk_disable_unprepare(fep->clk_ahb); |
1989 | clk_disable_unprepare(fep->clk_ipg); | 1995 | clk_disable_unprepare(fep->clk_ipg); |
1990 | for (i = 0; i < FEC_IRQ_NUM; i++) { | 1996 | for (i = 0; i < FEC_IRQ_NUM; i++) { |
@@ -2010,6 +2016,7 @@ fec_suspend(struct device *dev) | |||
2010 | fec_stop(ndev); | 2016 | fec_stop(ndev); |
2011 | netif_device_detach(ndev); | 2017 | netif_device_detach(ndev); |
2012 | } | 2018 | } |
2019 | clk_disable_unprepare(fep->clk_enet_out); | ||
2013 | clk_disable_unprepare(fep->clk_ahb); | 2020 | clk_disable_unprepare(fep->clk_ahb); |
2014 | clk_disable_unprepare(fep->clk_ipg); | 2021 | clk_disable_unprepare(fep->clk_ipg); |
2015 | 2022 | ||
@@ -2022,6 +2029,7 @@ fec_resume(struct device *dev) | |||
2022 | struct net_device *ndev = dev_get_drvdata(dev); | 2029 | struct net_device *ndev = dev_get_drvdata(dev); |
2023 | struct fec_enet_private *fep = netdev_priv(ndev); | 2030 | struct fec_enet_private *fep = netdev_priv(ndev); |
2024 | 2031 | ||
2032 | clk_prepare_enable(fep->clk_enet_out); | ||
2025 | clk_prepare_enable(fep->clk_ahb); | 2033 | clk_prepare_enable(fep->clk_ahb); |
2026 | clk_prepare_enable(fep->clk_ipg); | 2034 | clk_prepare_enable(fep->clk_ipg); |
2027 | if (netif_running(ndev)) { | 2035 | if (netif_running(ndev)) { |
diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 8234d2259722..2e8f24a1fb95 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c | |||
@@ -776,10 +776,10 @@ rx_dma_failed: | |||
776 | #if defined(CONFIG_OF) | 776 | #if defined(CONFIG_OF) |
777 | static const struct of_device_id davinci_spi_of_match[] = { | 777 | static const struct of_device_id davinci_spi_of_match[] = { |
778 | { | 778 | { |
779 | .compatible = "ti,dm644x-spi", | 779 | .compatible = "ti,dm6441-spi", |
780 | }, | 780 | }, |
781 | { | 781 | { |
782 | .compatible = "ti,da8xx-spi", | 782 | .compatible = "ti,da830-spi", |
783 | .data = (void *)SPI_VERSION_2, | 783 | .data = (void *)SPI_VERSION_2, |
784 | }, | 784 | }, |
785 | { }, | 785 | { }, |
diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c index a1d5778e2bbb..84982768cd10 100644 --- a/drivers/spi/spi-mxs.c +++ b/drivers/spi/spi-mxs.c | |||
@@ -490,21 +490,6 @@ static int mxs_spi_transfer_one(struct spi_master *master, | |||
490 | return status; | 490 | return status; |
491 | } | 491 | } |
492 | 492 | ||
493 | static bool mxs_ssp_dma_filter(struct dma_chan *chan, void *param) | ||
494 | { | ||
495 | struct mxs_ssp *ssp = param; | ||
496 | |||
497 | if (!mxs_dma_is_apbh(chan)) | ||
498 | return false; | ||
499 | |||
500 | if (chan->chan_id != ssp->dma_channel) | ||
501 | return false; | ||
502 | |||
503 | chan->private = &ssp->dma_data; | ||
504 | |||
505 | return true; | ||
506 | } | ||
507 | |||
508 | static const struct of_device_id mxs_spi_dt_ids[] = { | 493 | static const struct of_device_id mxs_spi_dt_ids[] = { |
509 | { .compatible = "fsl,imx23-spi", .data = (void *) IMX23_SSP, }, | 494 | { .compatible = "fsl,imx23-spi", .data = (void *) IMX23_SSP, }, |
510 | { .compatible = "fsl,imx28-spi", .data = (void *) IMX28_SSP, }, | 495 | { .compatible = "fsl,imx28-spi", .data = (void *) IMX28_SSP, }, |
@@ -520,13 +505,12 @@ static int mxs_spi_probe(struct platform_device *pdev) | |||
520 | struct spi_master *master; | 505 | struct spi_master *master; |
521 | struct mxs_spi *spi; | 506 | struct mxs_spi *spi; |
522 | struct mxs_ssp *ssp; | 507 | struct mxs_ssp *ssp; |
523 | struct resource *iores, *dmares; | 508 | struct resource *iores; |
524 | struct pinctrl *pinctrl; | 509 | struct pinctrl *pinctrl; |
525 | struct clk *clk; | 510 | struct clk *clk; |
526 | void __iomem *base; | 511 | void __iomem *base; |
527 | int devid, dma_channel, clk_freq; | 512 | int devid, clk_freq; |
528 | int ret = 0, irq_err, irq_dma; | 513 | int ret = 0, irq_err; |
529 | dma_cap_mask_t mask; | ||
530 | 514 | ||
531 | /* | 515 | /* |
532 | * Default clock speed for the SPI core. 160MHz seems to | 516 | * Default clock speed for the SPI core. 160MHz seems to |
@@ -537,8 +521,7 @@ static int mxs_spi_probe(struct platform_device *pdev) | |||
537 | 521 | ||
538 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 522 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
539 | irq_err = platform_get_irq(pdev, 0); | 523 | irq_err = platform_get_irq(pdev, 0); |
540 | irq_dma = platform_get_irq(pdev, 1); | 524 | if (!iores || irq_err < 0) |
541 | if (!iores || irq_err < 0 || irq_dma < 0) | ||
542 | return -EINVAL; | 525 | return -EINVAL; |
543 | 526 | ||
544 | base = devm_ioremap_resource(&pdev->dev, iores); | 527 | base = devm_ioremap_resource(&pdev->dev, iores); |
@@ -553,32 +536,11 @@ static int mxs_spi_probe(struct platform_device *pdev) | |||
553 | if (IS_ERR(clk)) | 536 | if (IS_ERR(clk)) |
554 | return PTR_ERR(clk); | 537 | return PTR_ERR(clk); |
555 | 538 | ||
556 | if (np) { | 539 | devid = (enum mxs_ssp_id) of_id->data; |
557 | devid = (enum mxs_ssp_id) of_id->data; | 540 | ret = of_property_read_u32(np, "clock-frequency", |
558 | /* | 541 | &clk_freq); |
559 | * TODO: This is a temporary solution and should be changed | 542 | if (ret) |
560 | * to use generic DMA binding later when the helpers get in. | ||
561 | */ | ||
562 | ret = of_property_read_u32(np, "fsl,ssp-dma-channel", | ||
563 | &dma_channel); | ||
564 | if (ret) { | ||
565 | dev_err(&pdev->dev, | ||
566 | "Failed to get DMA channel\n"); | ||
567 | return -EINVAL; | ||
568 | } | ||
569 | |||
570 | ret = of_property_read_u32(np, "clock-frequency", | ||
571 | &clk_freq); | ||
572 | if (ret) | ||
573 | clk_freq = clk_freq_default; | ||
574 | } else { | ||
575 | dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
576 | if (!dmares) | ||
577 | return -EINVAL; | ||
578 | devid = pdev->id_entry->driver_data; | ||
579 | dma_channel = dmares->start; | ||
580 | clk_freq = clk_freq_default; | 543 | clk_freq = clk_freq_default; |
581 | } | ||
582 | 544 | ||
583 | master = spi_alloc_master(&pdev->dev, sizeof(*spi)); | 545 | master = spi_alloc_master(&pdev->dev, sizeof(*spi)); |
584 | if (!master) | 546 | if (!master) |
@@ -597,7 +559,6 @@ static int mxs_spi_probe(struct platform_device *pdev) | |||
597 | ssp->clk = clk; | 559 | ssp->clk = clk; |
598 | ssp->base = base; | 560 | ssp->base = base; |
599 | ssp->devid = devid; | 561 | ssp->devid = devid; |
600 | ssp->dma_channel = dma_channel; | ||
601 | 562 | ||
602 | init_completion(&spi->c); | 563 | init_completion(&spi->c); |
603 | 564 | ||
@@ -606,10 +567,7 @@ static int mxs_spi_probe(struct platform_device *pdev) | |||
606 | if (ret) | 567 | if (ret) |
607 | goto out_master_free; | 568 | goto out_master_free; |
608 | 569 | ||
609 | dma_cap_zero(mask); | 570 | ssp->dmach = dma_request_slave_channel(&pdev->dev, "rx-tx"); |
610 | dma_cap_set(DMA_SLAVE, mask); | ||
611 | ssp->dma_data.chan_irq = irq_dma; | ||
612 | ssp->dmach = dma_request_channel(mask, mxs_ssp_dma_filter, ssp); | ||
613 | if (!ssp->dmach) { | 571 | if (!ssp->dmach) { |
614 | dev_err(ssp->dev, "Failed to request DMA\n"); | 572 | dev_err(ssp->dev, "Failed to request DMA\n"); |
615 | ret = -ENODEV; | 573 | ret = -ENODEV; |
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 62e7d3b015a1..4f5f161896a1 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <linux/pinctrl/consumer.h> | 35 | #include <linux/pinctrl/consumer.h> |
36 | #include <linux/of_device.h> | 36 | #include <linux/of_device.h> |
37 | #include <linux/dma-mapping.h> | 37 | #include <linux/dma-mapping.h> |
38 | #include <linux/fsl/mxs-dma.h> | 38 | #include <linux/dmaengine.h> |
39 | 39 | ||
40 | #include <asm/cacheflush.h> | 40 | #include <asm/cacheflush.h> |
41 | 41 | ||
@@ -148,11 +148,6 @@ struct mxs_auart_port { | |||
148 | struct device *dev; | 148 | struct device *dev; |
149 | 149 | ||
150 | /* for DMA */ | 150 | /* for DMA */ |
151 | struct mxs_dma_data dma_data; | ||
152 | int dma_channel_rx, dma_channel_tx; | ||
153 | int dma_irq_rx, dma_irq_tx; | ||
154 | int dma_channel; | ||
155 | |||
156 | struct scatterlist tx_sgl; | 151 | struct scatterlist tx_sgl; |
157 | struct dma_chan *tx_dma_chan; | 152 | struct dma_chan *tx_dma_chan; |
158 | void *tx_dma_buf; | 153 | void *tx_dma_buf; |
@@ -440,20 +435,6 @@ static u32 mxs_auart_get_mctrl(struct uart_port *u) | |||
440 | return mctrl; | 435 | return mctrl; |
441 | } | 436 | } |
442 | 437 | ||
443 | static bool mxs_auart_dma_filter(struct dma_chan *chan, void *param) | ||
444 | { | ||
445 | struct mxs_auart_port *s = param; | ||
446 | |||
447 | if (!mxs_dma_is_apbx(chan)) | ||
448 | return false; | ||
449 | |||
450 | if (s->dma_channel == chan->chan_id) { | ||
451 | chan->private = &s->dma_data; | ||
452 | return true; | ||
453 | } | ||
454 | return false; | ||
455 | } | ||
456 | |||
457 | static int mxs_auart_dma_prep_rx(struct mxs_auart_port *s); | 438 | static int mxs_auart_dma_prep_rx(struct mxs_auart_port *s); |
458 | static void dma_rx_callback(void *arg) | 439 | static void dma_rx_callback(void *arg) |
459 | { | 440 | { |
@@ -545,21 +526,11 @@ static void mxs_auart_dma_exit(struct mxs_auart_port *s) | |||
545 | 526 | ||
546 | static int mxs_auart_dma_init(struct mxs_auart_port *s) | 527 | static int mxs_auart_dma_init(struct mxs_auart_port *s) |
547 | { | 528 | { |
548 | dma_cap_mask_t mask; | ||
549 | |||
550 | if (auart_dma_enabled(s)) | 529 | if (auart_dma_enabled(s)) |
551 | return 0; | 530 | return 0; |
552 | 531 | ||
553 | /* We do not get the right DMA channels. */ | ||
554 | if (s->dma_channel_rx == -1 || s->dma_channel_tx == -1) | ||
555 | return -EINVAL; | ||
556 | |||
557 | /* init for RX */ | 532 | /* init for RX */ |
558 | dma_cap_zero(mask); | 533 | s->rx_dma_chan = dma_request_slave_channel(s->dev, "rx"); |
559 | dma_cap_set(DMA_SLAVE, mask); | ||
560 | s->dma_channel = s->dma_channel_rx; | ||
561 | s->dma_data.chan_irq = s->dma_irq_rx; | ||
562 | s->rx_dma_chan = dma_request_channel(mask, mxs_auart_dma_filter, s); | ||
563 | if (!s->rx_dma_chan) | 534 | if (!s->rx_dma_chan) |
564 | goto err_out; | 535 | goto err_out; |
565 | s->rx_dma_buf = kzalloc(UART_XMIT_SIZE, GFP_KERNEL | GFP_DMA); | 536 | s->rx_dma_buf = kzalloc(UART_XMIT_SIZE, GFP_KERNEL | GFP_DMA); |
@@ -567,9 +538,7 @@ static int mxs_auart_dma_init(struct mxs_auart_port *s) | |||
567 | goto err_out; | 538 | goto err_out; |
568 | 539 | ||
569 | /* init for TX */ | 540 | /* init for TX */ |
570 | s->dma_channel = s->dma_channel_tx; | 541 | s->tx_dma_chan = dma_request_slave_channel(s->dev, "tx"); |
571 | s->dma_data.chan_irq = s->dma_irq_tx; | ||
572 | s->tx_dma_chan = dma_request_channel(mask, mxs_auart_dma_filter, s); | ||
573 | if (!s->tx_dma_chan) | 542 | if (!s->tx_dma_chan) |
574 | goto err_out; | 543 | goto err_out; |
575 | s->tx_dma_buf = kzalloc(UART_XMIT_SIZE, GFP_KERNEL | GFP_DMA); | 544 | s->tx_dma_buf = kzalloc(UART_XMIT_SIZE, GFP_KERNEL | GFP_DMA); |
@@ -1020,7 +989,6 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s, | |||
1020 | struct platform_device *pdev) | 989 | struct platform_device *pdev) |
1021 | { | 990 | { |
1022 | struct device_node *np = pdev->dev.of_node; | 991 | struct device_node *np = pdev->dev.of_node; |
1023 | u32 dma_channel[2]; | ||
1024 | int ret; | 992 | int ret; |
1025 | 993 | ||
1026 | if (!np) | 994 | if (!np) |
@@ -1034,20 +1002,8 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s, | |||
1034 | } | 1002 | } |
1035 | s->port.line = ret; | 1003 | s->port.line = ret; |
1036 | 1004 | ||
1037 | s->dma_irq_rx = platform_get_irq(pdev, 1); | 1005 | s->flags |= MXS_AUART_DMA_CONFIG; |
1038 | s->dma_irq_tx = platform_get_irq(pdev, 2); | ||
1039 | 1006 | ||
1040 | ret = of_property_read_u32_array(np, "fsl,auart-dma-channel", | ||
1041 | dma_channel, 2); | ||
1042 | if (ret == 0) { | ||
1043 | s->dma_channel_rx = dma_channel[0]; | ||
1044 | s->dma_channel_tx = dma_channel[1]; | ||
1045 | |||
1046 | s->flags |= MXS_AUART_DMA_CONFIG; | ||
1047 | } else { | ||
1048 | s->dma_channel_rx = -1; | ||
1049 | s->dma_channel_tx = -1; | ||
1050 | } | ||
1051 | return 0; | 1007 | return 0; |
1052 | } | 1008 | } |
1053 | 1009 | ||
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index ab5ba3d49e14..c04ccdf60eaa 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -2428,6 +2428,8 @@ config FB_MXS | |||
2428 | select FB_CFB_FILLRECT | 2428 | select FB_CFB_FILLRECT |
2429 | select FB_CFB_COPYAREA | 2429 | select FB_CFB_COPYAREA |
2430 | select FB_CFB_IMAGEBLIT | 2430 | select FB_CFB_IMAGEBLIT |
2431 | select FB_MODE_HELPERS | ||
2432 | select OF_VIDEOMODE | ||
2431 | help | 2433 | help |
2432 | Framebuffer support for the MXS SoC. | 2434 | Framebuffer support for the MXS SoC. |
2433 | 2435 | ||
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c index 45169cbaba6e..1b2c26d1658c 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/mxsfb.c | |||
@@ -42,13 +42,15 @@ | |||
42 | #include <linux/module.h> | 42 | #include <linux/module.h> |
43 | #include <linux/kernel.h> | 43 | #include <linux/kernel.h> |
44 | #include <linux/of_device.h> | 44 | #include <linux/of_device.h> |
45 | #include <linux/of_gpio.h> | 45 | #include <video/of_display_timing.h> |
46 | #include <linux/platform_device.h> | 46 | #include <linux/platform_device.h> |
47 | #include <linux/clk.h> | 47 | #include <linux/clk.h> |
48 | #include <linux/dma-mapping.h> | 48 | #include <linux/dma-mapping.h> |
49 | #include <linux/io.h> | 49 | #include <linux/io.h> |
50 | #include <linux/pinctrl/consumer.h> | 50 | #include <linux/pinctrl/consumer.h> |
51 | #include <linux/mxsfb.h> | 51 | #include <linux/fb.h> |
52 | #include <linux/regulator/consumer.h> | ||
53 | #include <video/videomode.h> | ||
52 | 54 | ||
53 | #define REG_SET 4 | 55 | #define REG_SET 4 |
54 | #define REG_CLR 8 | 56 | #define REG_CLR 8 |
@@ -107,7 +109,7 @@ | |||
107 | #define VDCTRL0_ENABLE_PRESENT (1 << 28) | 109 | #define VDCTRL0_ENABLE_PRESENT (1 << 28) |
108 | #define VDCTRL0_VSYNC_ACT_HIGH (1 << 27) | 110 | #define VDCTRL0_VSYNC_ACT_HIGH (1 << 27) |
109 | #define VDCTRL0_HSYNC_ACT_HIGH (1 << 26) | 111 | #define VDCTRL0_HSYNC_ACT_HIGH (1 << 26) |
110 | #define VDCTRL0_DOTCLK_ACT_FAILING (1 << 25) | 112 | #define VDCTRL0_DOTCLK_ACT_FALLING (1 << 25) |
111 | #define VDCTRL0_ENABLE_ACT_HIGH (1 << 24) | 113 | #define VDCTRL0_ENABLE_ACT_HIGH (1 << 24) |
112 | #define VDCTRL0_VSYNC_PERIOD_UNIT (1 << 21) | 114 | #define VDCTRL0_VSYNC_PERIOD_UNIT (1 << 21) |
113 | #define VDCTRL0_VSYNC_PULSE_WIDTH_UNIT (1 << 20) | 115 | #define VDCTRL0_VSYNC_PULSE_WIDTH_UNIT (1 << 20) |
@@ -142,6 +144,14 @@ | |||
142 | #define BLUE 2 | 144 | #define BLUE 2 |
143 | #define TRANSP 3 | 145 | #define TRANSP 3 |
144 | 146 | ||
147 | #define STMLCDIF_8BIT 1 /** pixel data bus to the display is of 8 bit width */ | ||
148 | #define STMLCDIF_16BIT 0 /** pixel data bus to the display is of 16 bit width */ | ||
149 | #define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */ | ||
150 | #define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */ | ||
151 | |||
152 | #define MXSFB_SYNC_DATA_ENABLE_HIGH_ACT (1 << 6) | ||
153 | #define MXSFB_SYNC_DOTCLK_FALLING_ACT (1 << 7) /* negtive edge sampling */ | ||
154 | |||
145 | enum mxsfb_devtype { | 155 | enum mxsfb_devtype { |
146 | MXSFB_V3, | 156 | MXSFB_V3, |
147 | MXSFB_V4, | 157 | MXSFB_V4, |
@@ -168,8 +178,8 @@ struct mxsfb_info { | |||
168 | unsigned ld_intf_width; | 178 | unsigned ld_intf_width; |
169 | unsigned dotclk_delay; | 179 | unsigned dotclk_delay; |
170 | const struct mxsfb_devdata *devdata; | 180 | const struct mxsfb_devdata *devdata; |
171 | int mapped; | ||
172 | u32 sync; | 181 | u32 sync; |
182 | struct regulator *reg_lcd; | ||
173 | }; | 183 | }; |
174 | 184 | ||
175 | #define mxsfb_is_v3(host) (host->devdata->ipversion == 3) | 185 | #define mxsfb_is_v3(host) (host->devdata->ipversion == 3) |
@@ -329,9 +339,19 @@ static void mxsfb_enable_controller(struct fb_info *fb_info) | |||
329 | { | 339 | { |
330 | struct mxsfb_info *host = to_imxfb_host(fb_info); | 340 | struct mxsfb_info *host = to_imxfb_host(fb_info); |
331 | u32 reg; | 341 | u32 reg; |
342 | int ret; | ||
332 | 343 | ||
333 | dev_dbg(&host->pdev->dev, "%s\n", __func__); | 344 | dev_dbg(&host->pdev->dev, "%s\n", __func__); |
334 | 345 | ||
346 | if (host->reg_lcd) { | ||
347 | ret = regulator_enable(host->reg_lcd); | ||
348 | if (ret) { | ||
349 | dev_err(&host->pdev->dev, | ||
350 | "lcd regulator enable failed: %d\n", ret); | ||
351 | return; | ||
352 | } | ||
353 | } | ||
354 | |||
335 | clk_prepare_enable(host->clk); | 355 | clk_prepare_enable(host->clk); |
336 | clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U); | 356 | clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U); |
337 | 357 | ||
@@ -353,6 +373,7 @@ static void mxsfb_disable_controller(struct fb_info *fb_info) | |||
353 | struct mxsfb_info *host = to_imxfb_host(fb_info); | 373 | struct mxsfb_info *host = to_imxfb_host(fb_info); |
354 | unsigned loop; | 374 | unsigned loop; |
355 | u32 reg; | 375 | u32 reg; |
376 | int ret; | ||
356 | 377 | ||
357 | dev_dbg(&host->pdev->dev, "%s\n", __func__); | 378 | dev_dbg(&host->pdev->dev, "%s\n", __func__); |
358 | 379 | ||
@@ -376,6 +397,13 @@ static void mxsfb_disable_controller(struct fb_info *fb_info) | |||
376 | clk_disable_unprepare(host->clk); | 397 | clk_disable_unprepare(host->clk); |
377 | 398 | ||
378 | host->enabled = 0; | 399 | host->enabled = 0; |
400 | |||
401 | if (host->reg_lcd) { | ||
402 | ret = regulator_disable(host->reg_lcd); | ||
403 | if (ret) | ||
404 | dev_err(&host->pdev->dev, | ||
405 | "lcd regulator disable failed: %d\n", ret); | ||
406 | } | ||
379 | } | 407 | } |
380 | 408 | ||
381 | static int mxsfb_set_par(struct fb_info *fb_info) | 409 | static int mxsfb_set_par(struct fb_info *fb_info) |
@@ -459,8 +487,8 @@ static int mxsfb_set_par(struct fb_info *fb_info) | |||
459 | vdctrl0 |= VDCTRL0_VSYNC_ACT_HIGH; | 487 | vdctrl0 |= VDCTRL0_VSYNC_ACT_HIGH; |
460 | if (host->sync & MXSFB_SYNC_DATA_ENABLE_HIGH_ACT) | 488 | if (host->sync & MXSFB_SYNC_DATA_ENABLE_HIGH_ACT) |
461 | vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH; | 489 | vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH; |
462 | if (host->sync & MXSFB_SYNC_DOTCLK_FAILING_ACT) | 490 | if (host->sync & MXSFB_SYNC_DOTCLK_FALLING_ACT) |
463 | vdctrl0 |= VDCTRL0_DOTCLK_ACT_FAILING; | 491 | vdctrl0 |= VDCTRL0_DOTCLK_ACT_FALLING; |
464 | 492 | ||
465 | writel(vdctrl0, host->base + LCDC_VDCTRL0); | 493 | writel(vdctrl0, host->base + LCDC_VDCTRL0); |
466 | 494 | ||
@@ -679,14 +707,105 @@ static int mxsfb_restore_mode(struct mxsfb_info *host) | |||
679 | return 0; | 707 | return 0; |
680 | } | 708 | } |
681 | 709 | ||
710 | static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host) | ||
711 | { | ||
712 | struct fb_info *fb_info = &host->fb_info; | ||
713 | struct fb_var_screeninfo *var = &fb_info->var; | ||
714 | struct device *dev = &host->pdev->dev; | ||
715 | struct device_node *np = host->pdev->dev.of_node; | ||
716 | struct device_node *display_np; | ||
717 | struct device_node *timings_np; | ||
718 | struct display_timings *timings; | ||
719 | u32 width; | ||
720 | int i; | ||
721 | int ret = 0; | ||
722 | |||
723 | display_np = of_parse_phandle(np, "display", 0); | ||
724 | if (!display_np) { | ||
725 | dev_err(dev, "failed to find display phandle\n"); | ||
726 | return -ENOENT; | ||
727 | } | ||
728 | |||
729 | ret = of_property_read_u32(display_np, "bus-width", &width); | ||
730 | if (ret < 0) { | ||
731 | dev_err(dev, "failed to get property bus-width\n"); | ||
732 | goto put_display_node; | ||
733 | } | ||
734 | |||
735 | switch (width) { | ||
736 | case 8: | ||
737 | host->ld_intf_width = STMLCDIF_8BIT; | ||
738 | break; | ||
739 | case 16: | ||
740 | host->ld_intf_width = STMLCDIF_16BIT; | ||
741 | break; | ||
742 | case 18: | ||
743 | host->ld_intf_width = STMLCDIF_18BIT; | ||
744 | break; | ||
745 | case 24: | ||
746 | host->ld_intf_width = STMLCDIF_24BIT; | ||
747 | break; | ||
748 | default: | ||
749 | dev_err(dev, "invalid bus-width value\n"); | ||
750 | ret = -EINVAL; | ||
751 | goto put_display_node; | ||
752 | } | ||
753 | |||
754 | ret = of_property_read_u32(display_np, "bits-per-pixel", | ||
755 | &var->bits_per_pixel); | ||
756 | if (ret < 0) { | ||
757 | dev_err(dev, "failed to get property bits-per-pixel\n"); | ||
758 | goto put_display_node; | ||
759 | } | ||
760 | |||
761 | timings = of_get_display_timings(display_np); | ||
762 | if (!timings) { | ||
763 | dev_err(dev, "failed to get display timings\n"); | ||
764 | ret = -ENOENT; | ||
765 | goto put_display_node; | ||
766 | } | ||
767 | |||
768 | timings_np = of_find_node_by_name(display_np, | ||
769 | "display-timings"); | ||
770 | if (!timings_np) { | ||
771 | dev_err(dev, "failed to find display-timings node\n"); | ||
772 | ret = -ENOENT; | ||
773 | goto put_display_node; | ||
774 | } | ||
775 | |||
776 | for (i = 0; i < of_get_child_count(timings_np); i++) { | ||
777 | struct videomode vm; | ||
778 | struct fb_videomode fb_vm; | ||
779 | |||
780 | ret = videomode_from_timing(timings, &vm, i); | ||
781 | if (ret < 0) | ||
782 | goto put_timings_node; | ||
783 | ret = fb_videomode_from_videomode(&vm, &fb_vm); | ||
784 | if (ret < 0) | ||
785 | goto put_timings_node; | ||
786 | |||
787 | if (vm.data_flags & DISPLAY_FLAGS_DE_HIGH) | ||
788 | host->sync |= MXSFB_SYNC_DATA_ENABLE_HIGH_ACT; | ||
789 | if (vm.data_flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) | ||
790 | host->sync |= MXSFB_SYNC_DOTCLK_FALLING_ACT; | ||
791 | fb_add_videomode(&fb_vm, &fb_info->modelist); | ||
792 | } | ||
793 | |||
794 | put_timings_node: | ||
795 | of_node_put(timings_np); | ||
796 | put_display_node: | ||
797 | of_node_put(display_np); | ||
798 | return ret; | ||
799 | } | ||
800 | |||
682 | static int mxsfb_init_fbinfo(struct mxsfb_info *host) | 801 | static int mxsfb_init_fbinfo(struct mxsfb_info *host) |
683 | { | 802 | { |
684 | struct fb_info *fb_info = &host->fb_info; | 803 | struct fb_info *fb_info = &host->fb_info; |
685 | struct fb_var_screeninfo *var = &fb_info->var; | 804 | struct fb_var_screeninfo *var = &fb_info->var; |
686 | struct mxsfb_platform_data *pdata = host->pdev->dev.platform_data; | ||
687 | dma_addr_t fb_phys; | 805 | dma_addr_t fb_phys; |
688 | void *fb_virt; | 806 | void *fb_virt; |
689 | unsigned fb_size = pdata->fb_size; | 807 | unsigned fb_size; |
808 | int ret; | ||
690 | 809 | ||
691 | fb_info->fbops = &mxsfb_ops; | 810 | fb_info->fbops = &mxsfb_ops; |
692 | fb_info->flags = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST; | 811 | fb_info->flags = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST; |
@@ -696,40 +815,22 @@ static int mxsfb_init_fbinfo(struct mxsfb_info *host) | |||
696 | fb_info->fix.visual = FB_VISUAL_TRUECOLOR, | 815 | fb_info->fix.visual = FB_VISUAL_TRUECOLOR, |
697 | fb_info->fix.accel = FB_ACCEL_NONE; | 816 | fb_info->fix.accel = FB_ACCEL_NONE; |
698 | 817 | ||
699 | var->bits_per_pixel = pdata->default_bpp ? pdata->default_bpp : 16; | 818 | ret = mxsfb_init_fbinfo_dt(host); |
819 | if (ret) | ||
820 | return ret; | ||
821 | |||
700 | var->nonstd = 0; | 822 | var->nonstd = 0; |
701 | var->activate = FB_ACTIVATE_NOW; | 823 | var->activate = FB_ACTIVATE_NOW; |
702 | var->accel_flags = 0; | 824 | var->accel_flags = 0; |
703 | var->vmode = FB_VMODE_NONINTERLACED; | 825 | var->vmode = FB_VMODE_NONINTERLACED; |
704 | 826 | ||
705 | host->dotclk_delay = pdata->dotclk_delay; | ||
706 | host->ld_intf_width = pdata->ld_intf_width; | ||
707 | |||
708 | /* Memory allocation for framebuffer */ | 827 | /* Memory allocation for framebuffer */ |
709 | if (pdata->fb_phys) { | 828 | fb_size = SZ_2M; |
710 | if (!fb_size) | 829 | fb_virt = alloc_pages_exact(fb_size, GFP_DMA); |
711 | return -EINVAL; | 830 | if (!fb_virt) |
712 | 831 | return -ENOMEM; | |
713 | fb_phys = pdata->fb_phys; | ||
714 | |||
715 | if (!request_mem_region(fb_phys, fb_size, host->pdev->name)) | ||
716 | return -ENOMEM; | ||
717 | 832 | ||
718 | fb_virt = ioremap(fb_phys, fb_size); | 833 | fb_phys = virt_to_phys(fb_virt); |
719 | if (!fb_virt) { | ||
720 | release_mem_region(fb_phys, fb_size); | ||
721 | return -ENOMEM; | ||
722 | } | ||
723 | host->mapped = 1; | ||
724 | } else { | ||
725 | if (!fb_size) | ||
726 | fb_size = SZ_2M; /* default */ | ||
727 | fb_virt = alloc_pages_exact(fb_size, GFP_DMA); | ||
728 | if (!fb_virt) | ||
729 | return -ENOMEM; | ||
730 | |||
731 | fb_phys = virt_to_phys(fb_virt); | ||
732 | } | ||
733 | 834 | ||
734 | fb_info->fix.smem_start = fb_phys; | 835 | fb_info->fix.smem_start = fb_phys; |
735 | fb_info->screen_base = fb_virt; | 836 | fb_info->screen_base = fb_virt; |
@@ -745,13 +846,7 @@ static void mxsfb_free_videomem(struct mxsfb_info *host) | |||
745 | { | 846 | { |
746 | struct fb_info *fb_info = &host->fb_info; | 847 | struct fb_info *fb_info = &host->fb_info; |
747 | 848 | ||
748 | if (host->mapped) { | 849 | free_pages_exact(fb_info->screen_base, fb_info->fix.smem_len); |
749 | iounmap(fb_info->screen_base); | ||
750 | release_mem_region(fb_info->fix.smem_start, | ||
751 | fb_info->screen_size); | ||
752 | } else { | ||
753 | free_pages_exact(fb_info->screen_base, fb_info->fix.smem_len); | ||
754 | } | ||
755 | } | 850 | } |
756 | 851 | ||
757 | static struct platform_device_id mxsfb_devtype[] = { | 852 | static struct platform_device_id mxsfb_devtype[] = { |
@@ -778,47 +873,35 @@ static int mxsfb_probe(struct platform_device *pdev) | |||
778 | { | 873 | { |
779 | const struct of_device_id *of_id = | 874 | const struct of_device_id *of_id = |
780 | of_match_device(mxsfb_dt_ids, &pdev->dev); | 875 | of_match_device(mxsfb_dt_ids, &pdev->dev); |
781 | struct mxsfb_platform_data *pdata = pdev->dev.platform_data; | ||
782 | struct resource *res; | 876 | struct resource *res; |
783 | struct mxsfb_info *host; | 877 | struct mxsfb_info *host; |
784 | struct fb_info *fb_info; | 878 | struct fb_info *fb_info; |
785 | struct fb_modelist *modelist; | 879 | struct fb_modelist *modelist; |
786 | struct pinctrl *pinctrl; | 880 | struct pinctrl *pinctrl; |
787 | int panel_enable; | 881 | int ret; |
788 | enum of_gpio_flags flags; | ||
789 | int i, ret; | ||
790 | 882 | ||
791 | if (of_id) | 883 | if (of_id) |
792 | pdev->id_entry = of_id->data; | 884 | pdev->id_entry = of_id->data; |
793 | 885 | ||
794 | if (!pdata) { | ||
795 | dev_err(&pdev->dev, "No platformdata. Giving up\n"); | ||
796 | return -ENODEV; | ||
797 | } | ||
798 | |||
799 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 886 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
800 | if (!res) { | 887 | if (!res) { |
801 | dev_err(&pdev->dev, "Cannot get memory IO resource\n"); | 888 | dev_err(&pdev->dev, "Cannot get memory IO resource\n"); |
802 | return -ENODEV; | 889 | return -ENODEV; |
803 | } | 890 | } |
804 | 891 | ||
805 | if (!request_mem_region(res->start, resource_size(res), pdev->name)) | ||
806 | return -EBUSY; | ||
807 | |||
808 | fb_info = framebuffer_alloc(sizeof(struct mxsfb_info), &pdev->dev); | 892 | fb_info = framebuffer_alloc(sizeof(struct mxsfb_info), &pdev->dev); |
809 | if (!fb_info) { | 893 | if (!fb_info) { |
810 | dev_err(&pdev->dev, "Failed to allocate fbdev\n"); | 894 | dev_err(&pdev->dev, "Failed to allocate fbdev\n"); |
811 | ret = -ENOMEM; | 895 | return -ENOMEM; |
812 | goto error_alloc_info; | ||
813 | } | 896 | } |
814 | 897 | ||
815 | host = to_imxfb_host(fb_info); | 898 | host = to_imxfb_host(fb_info); |
816 | 899 | ||
817 | host->base = ioremap(res->start, resource_size(res)); | 900 | host->base = devm_ioremap_resource(&pdev->dev, res); |
818 | if (!host->base) { | 901 | if (IS_ERR(host->base)) { |
819 | dev_err(&pdev->dev, "ioremap failed\n"); | 902 | dev_err(&pdev->dev, "ioremap failed\n"); |
820 | ret = -ENOMEM; | 903 | ret = PTR_ERR(host->base); |
821 | goto error_ioremap; | 904 | goto fb_release; |
822 | } | 905 | } |
823 | 906 | ||
824 | host->pdev = pdev; | 907 | host->pdev = pdev; |
@@ -829,47 +912,31 @@ static int mxsfb_probe(struct platform_device *pdev) | |||
829 | pinctrl = devm_pinctrl_get_select_default(&pdev->dev); | 912 | pinctrl = devm_pinctrl_get_select_default(&pdev->dev); |
830 | if (IS_ERR(pinctrl)) { | 913 | if (IS_ERR(pinctrl)) { |
831 | ret = PTR_ERR(pinctrl); | 914 | ret = PTR_ERR(pinctrl); |
832 | goto error_getpin; | 915 | goto fb_release; |
833 | } | 916 | } |
834 | 917 | ||
835 | host->clk = clk_get(&host->pdev->dev, NULL); | 918 | host->clk = devm_clk_get(&host->pdev->dev, NULL); |
836 | if (IS_ERR(host->clk)) { | 919 | if (IS_ERR(host->clk)) { |
837 | ret = PTR_ERR(host->clk); | 920 | ret = PTR_ERR(host->clk); |
838 | goto error_getclock; | 921 | goto fb_release; |
839 | } | 922 | } |
840 | 923 | ||
841 | panel_enable = of_get_named_gpio_flags(pdev->dev.of_node, | 924 | host->reg_lcd = devm_regulator_get(&pdev->dev, "lcd"); |
842 | "panel-enable-gpios", 0, &flags); | 925 | if (IS_ERR(host->reg_lcd)) |
843 | if (gpio_is_valid(panel_enable)) { | 926 | host->reg_lcd = NULL; |
844 | unsigned long f = GPIOF_OUT_INIT_HIGH; | ||
845 | if (flags == OF_GPIO_ACTIVE_LOW) | ||
846 | f = GPIOF_OUT_INIT_LOW; | ||
847 | ret = devm_gpio_request_one(&pdev->dev, panel_enable, | ||
848 | f, "panel-enable"); | ||
849 | if (ret) { | ||
850 | dev_err(&pdev->dev, | ||
851 | "failed to request gpio %d: %d\n", | ||
852 | panel_enable, ret); | ||
853 | goto error_panel_enable; | ||
854 | } | ||
855 | } | ||
856 | 927 | ||
857 | fb_info->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL); | 928 | fb_info->pseudo_palette = devm_kzalloc(&pdev->dev, sizeof(u32) * 16, |
929 | GFP_KERNEL); | ||
858 | if (!fb_info->pseudo_palette) { | 930 | if (!fb_info->pseudo_palette) { |
859 | ret = -ENOMEM; | 931 | ret = -ENOMEM; |
860 | goto error_pseudo_pallette; | 932 | goto fb_release; |
861 | } | 933 | } |
862 | 934 | ||
863 | INIT_LIST_HEAD(&fb_info->modelist); | 935 | INIT_LIST_HEAD(&fb_info->modelist); |
864 | 936 | ||
865 | host->sync = pdata->sync; | ||
866 | |||
867 | ret = mxsfb_init_fbinfo(host); | 937 | ret = mxsfb_init_fbinfo(host); |
868 | if (ret != 0) | 938 | if (ret != 0) |
869 | goto error_init_fb; | 939 | goto fb_release; |
870 | |||
871 | for (i = 0; i < pdata->mode_count; i++) | ||
872 | fb_add_videomode(&pdata->mode_list[i], &fb_info->modelist); | ||
873 | 940 | ||
874 | modelist = list_first_entry(&fb_info->modelist, | 941 | modelist = list_first_entry(&fb_info->modelist, |
875 | struct fb_modelist, list); | 942 | struct fb_modelist, list); |
@@ -883,7 +950,7 @@ static int mxsfb_probe(struct platform_device *pdev) | |||
883 | ret = register_framebuffer(fb_info); | 950 | ret = register_framebuffer(fb_info); |
884 | if (ret != 0) { | 951 | if (ret != 0) { |
885 | dev_err(&pdev->dev,"Failed to register framebuffer\n"); | 952 | dev_err(&pdev->dev,"Failed to register framebuffer\n"); |
886 | goto error_register; | 953 | goto fb_destroy; |
887 | } | 954 | } |
888 | 955 | ||
889 | if (!host->enabled) { | 956 | if (!host->enabled) { |
@@ -896,22 +963,12 @@ static int mxsfb_probe(struct platform_device *pdev) | |||
896 | 963 | ||
897 | return 0; | 964 | return 0; |
898 | 965 | ||
899 | error_register: | 966 | fb_destroy: |
900 | if (host->enabled) | 967 | if (host->enabled) |
901 | clk_disable_unprepare(host->clk); | 968 | clk_disable_unprepare(host->clk); |
902 | fb_destroy_modelist(&fb_info->modelist); | 969 | fb_destroy_modelist(&fb_info->modelist); |
903 | error_init_fb: | 970 | fb_release: |
904 | kfree(fb_info->pseudo_palette); | ||
905 | error_pseudo_pallette: | ||
906 | error_panel_enable: | ||
907 | clk_put(host->clk); | ||
908 | error_getclock: | ||
909 | error_getpin: | ||
910 | iounmap(host->base); | ||
911 | error_ioremap: | ||
912 | framebuffer_release(fb_info); | 971 | framebuffer_release(fb_info); |
913 | error_alloc_info: | ||
914 | release_mem_region(res->start, resource_size(res)); | ||
915 | 972 | ||
916 | return ret; | 973 | return ret; |
917 | } | 974 | } |
@@ -920,19 +977,14 @@ static int mxsfb_remove(struct platform_device *pdev) | |||
920 | { | 977 | { |
921 | struct fb_info *fb_info = platform_get_drvdata(pdev); | 978 | struct fb_info *fb_info = platform_get_drvdata(pdev); |
922 | struct mxsfb_info *host = to_imxfb_host(fb_info); | 979 | struct mxsfb_info *host = to_imxfb_host(fb_info); |
923 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
924 | 980 | ||
925 | if (host->enabled) | 981 | if (host->enabled) |
926 | mxsfb_disable_controller(fb_info); | 982 | mxsfb_disable_controller(fb_info); |
927 | 983 | ||
928 | unregister_framebuffer(fb_info); | 984 | unregister_framebuffer(fb_info); |
929 | kfree(fb_info->pseudo_palette); | ||
930 | mxsfb_free_videomem(host); | 985 | mxsfb_free_videomem(host); |
931 | iounmap(host->base); | ||
932 | clk_put(host->clk); | ||
933 | 986 | ||
934 | framebuffer_release(fb_info); | 987 | framebuffer_release(fb_info); |
935 | release_mem_region(res->start, resource_size(res)); | ||
936 | 988 | ||
937 | platform_set_drvdata(pdev, NULL); | 989 | platform_set_drvdata(pdev, NULL); |
938 | 990 | ||