diff options
Diffstat (limited to 'drivers/dma/cppi41.c')
-rw-r--r-- | drivers/dma/cppi41.c | 94 |
1 files changed, 62 insertions, 32 deletions
diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c index 7c82b92f9b16..167c0223ae9e 100644 --- a/drivers/dma/cppi41.c +++ b/drivers/dma/cppi41.c | |||
@@ -674,14 +674,14 @@ static void cleanup_chans(struct cppi41_dd *cdd) | |||
674 | } | 674 | } |
675 | } | 675 | } |
676 | 676 | ||
677 | static int cppi41_add_chans(struct platform_device *pdev, struct cppi41_dd *cdd) | 677 | static int cppi41_add_chans(struct device *dev, struct cppi41_dd *cdd) |
678 | { | 678 | { |
679 | struct cppi41_channel *cchan; | 679 | struct cppi41_channel *cchan; |
680 | int i; | 680 | int i; |
681 | int ret; | 681 | int ret; |
682 | u32 n_chans; | 682 | u32 n_chans; |
683 | 683 | ||
684 | ret = of_property_read_u32(pdev->dev.of_node, "#dma-channels", | 684 | ret = of_property_read_u32(dev->of_node, "#dma-channels", |
685 | &n_chans); | 685 | &n_chans); |
686 | if (ret) | 686 | if (ret) |
687 | return ret; | 687 | return ret; |
@@ -719,7 +719,7 @@ err: | |||
719 | return -ENOMEM; | 719 | return -ENOMEM; |
720 | } | 720 | } |
721 | 721 | ||
722 | static void purge_descs(struct platform_device *pdev, struct cppi41_dd *cdd) | 722 | static void purge_descs(struct device *dev, struct cppi41_dd *cdd) |
723 | { | 723 | { |
724 | unsigned int mem_decs; | 724 | unsigned int mem_decs; |
725 | int i; | 725 | int i; |
@@ -731,7 +731,7 @@ static void purge_descs(struct platform_device *pdev, struct cppi41_dd *cdd) | |||
731 | cppi_writel(0, cdd->qmgr_mem + QMGR_MEMBASE(i)); | 731 | cppi_writel(0, cdd->qmgr_mem + QMGR_MEMBASE(i)); |
732 | cppi_writel(0, cdd->qmgr_mem + QMGR_MEMCTRL(i)); | 732 | cppi_writel(0, cdd->qmgr_mem + QMGR_MEMCTRL(i)); |
733 | 733 | ||
734 | dma_free_coherent(&pdev->dev, mem_decs, cdd->cd, | 734 | dma_free_coherent(dev, mem_decs, cdd->cd, |
735 | cdd->descs_phys); | 735 | cdd->descs_phys); |
736 | } | 736 | } |
737 | } | 737 | } |
@@ -741,19 +741,19 @@ static void disable_sched(struct cppi41_dd *cdd) | |||
741 | cppi_writel(0, cdd->sched_mem + DMA_SCHED_CTRL); | 741 | cppi_writel(0, cdd->sched_mem + DMA_SCHED_CTRL); |
742 | } | 742 | } |
743 | 743 | ||
744 | static void deinit_cpii41(struct platform_device *pdev, struct cppi41_dd *cdd) | 744 | static void deinit_cppi41(struct device *dev, struct cppi41_dd *cdd) |
745 | { | 745 | { |
746 | disable_sched(cdd); | 746 | disable_sched(cdd); |
747 | 747 | ||
748 | purge_descs(pdev, cdd); | 748 | purge_descs(dev, cdd); |
749 | 749 | ||
750 | cppi_writel(0, cdd->qmgr_mem + QMGR_LRAM0_BASE); | 750 | cppi_writel(0, cdd->qmgr_mem + QMGR_LRAM0_BASE); |
751 | cppi_writel(0, cdd->qmgr_mem + QMGR_LRAM0_BASE); | 751 | cppi_writel(0, cdd->qmgr_mem + QMGR_LRAM0_BASE); |
752 | dma_free_coherent(&pdev->dev, QMGR_SCRATCH_SIZE, cdd->qmgr_scratch, | 752 | dma_free_coherent(dev, QMGR_SCRATCH_SIZE, cdd->qmgr_scratch, |
753 | cdd->scratch_phys); | 753 | cdd->scratch_phys); |
754 | } | 754 | } |
755 | 755 | ||
756 | static int init_descs(struct platform_device *pdev, struct cppi41_dd *cdd) | 756 | static int init_descs(struct device *dev, struct cppi41_dd *cdd) |
757 | { | 757 | { |
758 | unsigned int desc_size; | 758 | unsigned int desc_size; |
759 | unsigned int mem_decs; | 759 | unsigned int mem_decs; |
@@ -777,7 +777,7 @@ static int init_descs(struct platform_device *pdev, struct cppi41_dd *cdd) | |||
777 | reg |= ilog2(ALLOC_DECS_NUM) - 5; | 777 | reg |= ilog2(ALLOC_DECS_NUM) - 5; |
778 | 778 | ||
779 | BUILD_BUG_ON(DESCS_AREAS != 1); | 779 | BUILD_BUG_ON(DESCS_AREAS != 1); |
780 | cdd->cd = dma_alloc_coherent(&pdev->dev, mem_decs, | 780 | cdd->cd = dma_alloc_coherent(dev, mem_decs, |
781 | &cdd->descs_phys, GFP_KERNEL); | 781 | &cdd->descs_phys, GFP_KERNEL); |
782 | if (!cdd->cd) | 782 | if (!cdd->cd) |
783 | return -ENOMEM; | 783 | return -ENOMEM; |
@@ -813,12 +813,12 @@ static void init_sched(struct cppi41_dd *cdd) | |||
813 | cppi_writel(reg, cdd->sched_mem + DMA_SCHED_CTRL); | 813 | cppi_writel(reg, cdd->sched_mem + DMA_SCHED_CTRL); |
814 | } | 814 | } |
815 | 815 | ||
816 | static int init_cppi41(struct platform_device *pdev, struct cppi41_dd *cdd) | 816 | static int init_cppi41(struct device *dev, struct cppi41_dd *cdd) |
817 | { | 817 | { |
818 | int ret; | 818 | int ret; |
819 | 819 | ||
820 | BUILD_BUG_ON(QMGR_SCRATCH_SIZE > ((1 << 14) - 1)); | 820 | BUILD_BUG_ON(QMGR_SCRATCH_SIZE > ((1 << 14) - 1)); |
821 | cdd->qmgr_scratch = dma_alloc_coherent(&pdev->dev, QMGR_SCRATCH_SIZE, | 821 | cdd->qmgr_scratch = dma_alloc_coherent(dev, QMGR_SCRATCH_SIZE, |
822 | &cdd->scratch_phys, GFP_KERNEL); | 822 | &cdd->scratch_phys, GFP_KERNEL); |
823 | if (!cdd->qmgr_scratch) | 823 | if (!cdd->qmgr_scratch) |
824 | return -ENOMEM; | 824 | return -ENOMEM; |
@@ -827,7 +827,7 @@ static int init_cppi41(struct platform_device *pdev, struct cppi41_dd *cdd) | |||
827 | cppi_writel(QMGR_SCRATCH_SIZE, cdd->qmgr_mem + QMGR_LRAM_SIZE); | 827 | cppi_writel(QMGR_SCRATCH_SIZE, cdd->qmgr_mem + QMGR_LRAM_SIZE); |
828 | cppi_writel(0, cdd->qmgr_mem + QMGR_LRAM1_BASE); | 828 | cppi_writel(0, cdd->qmgr_mem + QMGR_LRAM1_BASE); |
829 | 829 | ||
830 | ret = init_descs(pdev, cdd); | 830 | ret = init_descs(dev, cdd); |
831 | if (ret) | 831 | if (ret) |
832 | goto err_td; | 832 | goto err_td; |
833 | 833 | ||
@@ -835,7 +835,7 @@ static int init_cppi41(struct platform_device *pdev, struct cppi41_dd *cdd) | |||
835 | init_sched(cdd); | 835 | init_sched(cdd); |
836 | return 0; | 836 | return 0; |
837 | err_td: | 837 | err_td: |
838 | deinit_cpii41(pdev, cdd); | 838 | deinit_cppi41(dev, cdd); |
839 | return ret; | 839 | return ret; |
840 | } | 840 | } |
841 | 841 | ||
@@ -914,11 +914,11 @@ static const struct of_device_id cppi41_dma_ids[] = { | |||
914 | }; | 914 | }; |
915 | MODULE_DEVICE_TABLE(of, cppi41_dma_ids); | 915 | MODULE_DEVICE_TABLE(of, cppi41_dma_ids); |
916 | 916 | ||
917 | static const struct cppi_glue_infos *get_glue_info(struct platform_device *pdev) | 917 | static const struct cppi_glue_infos *get_glue_info(struct device *dev) |
918 | { | 918 | { |
919 | const struct of_device_id *of_id; | 919 | const struct of_device_id *of_id; |
920 | 920 | ||
921 | of_id = of_match_node(cppi41_dma_ids, pdev->dev.of_node); | 921 | of_id = of_match_node(cppi41_dma_ids, dev->of_node); |
922 | if (!of_id) | 922 | if (!of_id) |
923 | return NULL; | 923 | return NULL; |
924 | return of_id->data; | 924 | return of_id->data; |
@@ -927,11 +927,12 @@ static const struct cppi_glue_infos *get_glue_info(struct platform_device *pdev) | |||
927 | static int cppi41_dma_probe(struct platform_device *pdev) | 927 | static int cppi41_dma_probe(struct platform_device *pdev) |
928 | { | 928 | { |
929 | struct cppi41_dd *cdd; | 929 | struct cppi41_dd *cdd; |
930 | struct device *dev = &pdev->dev; | ||
930 | const struct cppi_glue_infos *glue_info; | 931 | const struct cppi_glue_infos *glue_info; |
931 | int irq; | 932 | int irq; |
932 | int ret; | 933 | int ret; |
933 | 934 | ||
934 | glue_info = get_glue_info(pdev); | 935 | glue_info = get_glue_info(dev); |
935 | if (!glue_info) | 936 | if (!glue_info) |
936 | return -EINVAL; | 937 | return -EINVAL; |
937 | 938 | ||
@@ -946,14 +947,14 @@ static int cppi41_dma_probe(struct platform_device *pdev) | |||
946 | cdd->ddev.device_issue_pending = cppi41_dma_issue_pending; | 947 | cdd->ddev.device_issue_pending = cppi41_dma_issue_pending; |
947 | cdd->ddev.device_prep_slave_sg = cppi41_dma_prep_slave_sg; | 948 | cdd->ddev.device_prep_slave_sg = cppi41_dma_prep_slave_sg; |
948 | cdd->ddev.device_control = cppi41_dma_control; | 949 | cdd->ddev.device_control = cppi41_dma_control; |
949 | cdd->ddev.dev = &pdev->dev; | 950 | cdd->ddev.dev = dev; |
950 | INIT_LIST_HEAD(&cdd->ddev.channels); | 951 | INIT_LIST_HEAD(&cdd->ddev.channels); |
951 | cpp41_dma_info.dma_cap = cdd->ddev.cap_mask; | 952 | cpp41_dma_info.dma_cap = cdd->ddev.cap_mask; |
952 | 953 | ||
953 | cdd->usbss_mem = of_iomap(pdev->dev.of_node, 0); | 954 | cdd->usbss_mem = of_iomap(dev->of_node, 0); |
954 | cdd->ctrl_mem = of_iomap(pdev->dev.of_node, 1); | 955 | cdd->ctrl_mem = of_iomap(dev->of_node, 1); |
955 | cdd->sched_mem = of_iomap(pdev->dev.of_node, 2); | 956 | cdd->sched_mem = of_iomap(dev->of_node, 2); |
956 | cdd->qmgr_mem = of_iomap(pdev->dev.of_node, 3); | 957 | cdd->qmgr_mem = of_iomap(dev->of_node, 3); |
957 | 958 | ||
958 | if (!cdd->usbss_mem || !cdd->ctrl_mem || !cdd->sched_mem || | 959 | if (!cdd->usbss_mem || !cdd->ctrl_mem || !cdd->sched_mem || |
959 | !cdd->qmgr_mem) { | 960 | !cdd->qmgr_mem) { |
@@ -961,8 +962,8 @@ static int cppi41_dma_probe(struct platform_device *pdev) | |||
961 | goto err_remap; | 962 | goto err_remap; |
962 | } | 963 | } |
963 | 964 | ||
964 | pm_runtime_enable(&pdev->dev); | 965 | pm_runtime_enable(dev); |
965 | ret = pm_runtime_get_sync(&pdev->dev); | 966 | ret = pm_runtime_get_sync(dev); |
966 | if (ret) | 967 | if (ret) |
967 | goto err_get_sync; | 968 | goto err_get_sync; |
968 | 969 | ||
@@ -970,22 +971,22 @@ static int cppi41_dma_probe(struct platform_device *pdev) | |||
970 | cdd->queues_tx = glue_info->queues_tx; | 971 | cdd->queues_tx = glue_info->queues_tx; |
971 | cdd->td_queue = glue_info->td_queue; | 972 | cdd->td_queue = glue_info->td_queue; |
972 | 973 | ||
973 | ret = init_cppi41(pdev, cdd); | 974 | ret = init_cppi41(dev, cdd); |
974 | if (ret) | 975 | if (ret) |
975 | goto err_init_cppi; | 976 | goto err_init_cppi; |
976 | 977 | ||
977 | ret = cppi41_add_chans(pdev, cdd); | 978 | ret = cppi41_add_chans(dev, cdd); |
978 | if (ret) | 979 | if (ret) |
979 | goto err_chans; | 980 | goto err_chans; |
980 | 981 | ||
981 | irq = irq_of_parse_and_map(pdev->dev.of_node, 0); | 982 | irq = irq_of_parse_and_map(dev->of_node, 0); |
982 | if (!irq) | 983 | if (!irq) |
983 | goto err_irq; | 984 | goto err_irq; |
984 | 985 | ||
985 | cppi_writel(USBSS_IRQ_PD_COMP, cdd->usbss_mem + USBSS_IRQ_ENABLER); | 986 | cppi_writel(USBSS_IRQ_PD_COMP, cdd->usbss_mem + USBSS_IRQ_ENABLER); |
986 | 987 | ||
987 | ret = request_irq(irq, glue_info->isr, IRQF_SHARED, | 988 | ret = request_irq(irq, glue_info->isr, IRQF_SHARED, |
988 | dev_name(&pdev->dev), cdd); | 989 | dev_name(dev), cdd); |
989 | if (ret) | 990 | if (ret) |
990 | goto err_irq; | 991 | goto err_irq; |
991 | cdd->irq = irq; | 992 | cdd->irq = irq; |
@@ -994,7 +995,7 @@ static int cppi41_dma_probe(struct platform_device *pdev) | |||
994 | if (ret) | 995 | if (ret) |
995 | goto err_dma_reg; | 996 | goto err_dma_reg; |
996 | 997 | ||
997 | ret = of_dma_controller_register(pdev->dev.of_node, | 998 | ret = of_dma_controller_register(dev->of_node, |
998 | cppi41_dma_xlate, &cpp41_dma_info); | 999 | cppi41_dma_xlate, &cpp41_dma_info); |
999 | if (ret) | 1000 | if (ret) |
1000 | goto err_of; | 1001 | goto err_of; |
@@ -1009,11 +1010,11 @@ err_irq: | |||
1009 | cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); | 1010 | cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); |
1010 | cleanup_chans(cdd); | 1011 | cleanup_chans(cdd); |
1011 | err_chans: | 1012 | err_chans: |
1012 | deinit_cpii41(pdev, cdd); | 1013 | deinit_cppi41(dev, cdd); |
1013 | err_init_cppi: | 1014 | err_init_cppi: |
1014 | pm_runtime_put(&pdev->dev); | 1015 | pm_runtime_put(dev); |
1015 | err_get_sync: | 1016 | err_get_sync: |
1016 | pm_runtime_disable(&pdev->dev); | 1017 | pm_runtime_disable(dev); |
1017 | iounmap(cdd->usbss_mem); | 1018 | iounmap(cdd->usbss_mem); |
1018 | iounmap(cdd->ctrl_mem); | 1019 | iounmap(cdd->ctrl_mem); |
1019 | iounmap(cdd->sched_mem); | 1020 | iounmap(cdd->sched_mem); |
@@ -1033,7 +1034,7 @@ static int cppi41_dma_remove(struct platform_device *pdev) | |||
1033 | cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); | 1034 | cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); |
1034 | free_irq(cdd->irq, cdd); | 1035 | free_irq(cdd->irq, cdd); |
1035 | cleanup_chans(cdd); | 1036 | cleanup_chans(cdd); |
1036 | deinit_cpii41(pdev, cdd); | 1037 | deinit_cppi41(&pdev->dev, cdd); |
1037 | iounmap(cdd->usbss_mem); | 1038 | iounmap(cdd->usbss_mem); |
1038 | iounmap(cdd->ctrl_mem); | 1039 | iounmap(cdd->ctrl_mem); |
1039 | iounmap(cdd->sched_mem); | 1040 | iounmap(cdd->sched_mem); |
@@ -1044,12 +1045,41 @@ static int cppi41_dma_remove(struct platform_device *pdev) | |||
1044 | return 0; | 1045 | return 0; |
1045 | } | 1046 | } |
1046 | 1047 | ||
1048 | #ifdef CONFIG_PM_SLEEP | ||
1049 | static int cppi41_suspend(struct device *dev) | ||
1050 | { | ||
1051 | struct cppi41_dd *cdd = dev_get_drvdata(dev); | ||
1052 | |||
1053 | cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); | ||
1054 | disable_sched(cdd); | ||
1055 | |||
1056 | return 0; | ||
1057 | } | ||
1058 | |||
1059 | static int cppi41_resume(struct device *dev) | ||
1060 | { | ||
1061 | struct cppi41_dd *cdd = dev_get_drvdata(dev); | ||
1062 | int i; | ||
1063 | |||
1064 | for (i = 0; i < DESCS_AREAS; i++) | ||
1065 | cppi_writel(cdd->descs_phys, cdd->qmgr_mem + QMGR_MEMBASE(i)); | ||
1066 | |||
1067 | init_sched(cdd); | ||
1068 | cppi_writel(USBSS_IRQ_PD_COMP, cdd->usbss_mem + USBSS_IRQ_ENABLER); | ||
1069 | |||
1070 | return 0; | ||
1071 | } | ||
1072 | #endif | ||
1073 | |||
1074 | static SIMPLE_DEV_PM_OPS(cppi41_pm_ops, cppi41_suspend, cppi41_resume); | ||
1075 | |||
1047 | static struct platform_driver cpp41_dma_driver = { | 1076 | static struct platform_driver cpp41_dma_driver = { |
1048 | .probe = cppi41_dma_probe, | 1077 | .probe = cppi41_dma_probe, |
1049 | .remove = cppi41_dma_remove, | 1078 | .remove = cppi41_dma_remove, |
1050 | .driver = { | 1079 | .driver = { |
1051 | .name = "cppi41-dma-engine", | 1080 | .name = "cppi41-dma-engine", |
1052 | .owner = THIS_MODULE, | 1081 | .owner = THIS_MODULE, |
1082 | .pm = &cppi41_pm_ops, | ||
1053 | .of_match_table = of_match_ptr(cppi41_dma_ids), | 1083 | .of_match_table = of_match_ptr(cppi41_dma_ids), |
1054 | }, | 1084 | }, |
1055 | }; | 1085 | }; |