diff options
Diffstat (limited to 'drivers/spi/au1550_spi.c')
-rw-r--r-- | drivers/spi/au1550_spi.c | 138 |
1 files changed, 74 insertions, 64 deletions
diff --git a/drivers/spi/au1550_spi.c b/drivers/spi/au1550_spi.c index 072c4a595334..3860dd2fa5d9 100644 --- a/drivers/spi/au1550_spi.c +++ b/drivers/spi/au1550_spi.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/errno.h> | 26 | #include <linux/errno.h> |
27 | #include <linux/device.h> | 27 | #include <linux/device.h> |
28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
29 | #include <linux/resource.h> | ||
29 | #include <linux/spi/spi.h> | 30 | #include <linux/spi/spi.h> |
30 | #include <linux/spi/spi_bitbang.h> | 31 | #include <linux/spi/spi_bitbang.h> |
31 | #include <linux/dma-mapping.h> | 32 | #include <linux/dma-mapping.h> |
@@ -81,6 +82,7 @@ struct au1550_spi { | |||
81 | struct spi_master *master; | 82 | struct spi_master *master; |
82 | struct device *dev; | 83 | struct device *dev; |
83 | struct au1550_spi_info *pdata; | 84 | struct au1550_spi_info *pdata; |
85 | struct resource *ioarea; | ||
84 | }; | 86 | }; |
85 | 87 | ||
86 | 88 | ||
@@ -96,6 +98,8 @@ static dbdev_tab_t au1550_spi_mem_dbdev = | |||
96 | .dev_intpolarity = 0 | 98 | .dev_intpolarity = 0 |
97 | }; | 99 | }; |
98 | 100 | ||
101 | static int ddma_memid; /* id to above mem dma device */ | ||
102 | |||
99 | static void au1550_spi_bits_handlers_set(struct au1550_spi *hw, int bpw); | 103 | static void au1550_spi_bits_handlers_set(struct au1550_spi *hw, int bpw); |
100 | 104 | ||
101 | 105 | ||
@@ -732,6 +736,7 @@ static int __init au1550_spi_probe(struct platform_device *pdev) | |||
732 | { | 736 | { |
733 | struct au1550_spi *hw; | 737 | struct au1550_spi *hw; |
734 | struct spi_master *master; | 738 | struct spi_master *master; |
739 | struct resource *r; | ||
735 | int err = 0; | 740 | int err = 0; |
736 | 741 | ||
737 | master = spi_alloc_master(&pdev->dev, sizeof(struct au1550_spi)); | 742 | master = spi_alloc_master(&pdev->dev, sizeof(struct au1550_spi)); |
@@ -753,76 +758,64 @@ static int __init au1550_spi_probe(struct platform_device *pdev) | |||
753 | goto err_no_pdata; | 758 | goto err_no_pdata; |
754 | } | 759 | } |
755 | 760 | ||
756 | platform_set_drvdata(pdev, hw); | 761 | r = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
757 | 762 | if (!r) { | |
758 | init_completion(&hw->master_done); | 763 | dev_err(&pdev->dev, "no IRQ\n"); |
759 | 764 | err = -ENODEV; | |
760 | hw->bitbang.master = hw->master; | 765 | goto err_no_iores; |
761 | hw->bitbang.setup_transfer = au1550_spi_setupxfer; | 766 | } |
762 | hw->bitbang.chipselect = au1550_spi_chipsel; | 767 | hw->irq = r->start; |
763 | hw->bitbang.master->setup = au1550_spi_setup; | 768 | |
764 | hw->bitbang.txrx_bufs = au1550_spi_txrx_bufs; | 769 | hw->usedma = 0; |
770 | r = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
771 | if (r) { | ||
772 | hw->dma_tx_id = r->start; | ||
773 | r = platform_get_resource(pdev, IORESOURCE_DMA, 1); | ||
774 | if (r) { | ||
775 | hw->dma_rx_id = r->start; | ||
776 | if (usedma && ddma_memid) { | ||
777 | if (pdev->dev.dma_mask == NULL) | ||
778 | dev_warn(&pdev->dev, "no dma mask\n"); | ||
779 | else | ||
780 | hw->usedma = 1; | ||
781 | } | ||
782 | } | ||
783 | } | ||
765 | 784 | ||
766 | switch (hw->pdata->bus_num) { | 785 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
767 | case 0: | 786 | if (!r) { |
768 | hw->irq = AU1550_PSC0_INT; | 787 | dev_err(&pdev->dev, "no mmio resource\n"); |
769 | hw->regs = (volatile psc_spi_t *)PSC0_BASE_ADDR; | 788 | err = -ENODEV; |
770 | hw->dma_rx_id = DSCR_CMD0_PSC0_RX; | 789 | goto err_no_iores; |
771 | hw->dma_tx_id = DSCR_CMD0_PSC0_TX; | ||
772 | break; | ||
773 | case 1: | ||
774 | hw->irq = AU1550_PSC1_INT; | ||
775 | hw->regs = (volatile psc_spi_t *)PSC1_BASE_ADDR; | ||
776 | hw->dma_rx_id = DSCR_CMD0_PSC1_RX; | ||
777 | hw->dma_tx_id = DSCR_CMD0_PSC1_TX; | ||
778 | break; | ||
779 | case 2: | ||
780 | hw->irq = AU1550_PSC2_INT; | ||
781 | hw->regs = (volatile psc_spi_t *)PSC2_BASE_ADDR; | ||
782 | hw->dma_rx_id = DSCR_CMD0_PSC2_RX; | ||
783 | hw->dma_tx_id = DSCR_CMD0_PSC2_TX; | ||
784 | break; | ||
785 | case 3: | ||
786 | hw->irq = AU1550_PSC3_INT; | ||
787 | hw->regs = (volatile psc_spi_t *)PSC3_BASE_ADDR; | ||
788 | hw->dma_rx_id = DSCR_CMD0_PSC3_RX; | ||
789 | hw->dma_tx_id = DSCR_CMD0_PSC3_TX; | ||
790 | break; | ||
791 | default: | ||
792 | dev_err(&pdev->dev, "Wrong bus_num of SPI\n"); | ||
793 | err = -ENOENT; | ||
794 | goto err_no_pdata; | ||
795 | } | 790 | } |
796 | 791 | ||
797 | if (request_mem_region((unsigned long)hw->regs, sizeof(psc_spi_t), | 792 | hw->ioarea = request_mem_region(r->start, sizeof(psc_spi_t), |
798 | pdev->name) == NULL) { | 793 | pdev->name); |
794 | if (!hw->ioarea) { | ||
799 | dev_err(&pdev->dev, "Cannot reserve iomem region\n"); | 795 | dev_err(&pdev->dev, "Cannot reserve iomem region\n"); |
800 | err = -ENXIO; | 796 | err = -ENXIO; |
801 | goto err_no_iores; | 797 | goto err_no_iores; |
802 | } | 798 | } |
803 | 799 | ||
804 | 800 | hw->regs = (psc_spi_t __iomem *)ioremap(r->start, sizeof(psc_spi_t)); | |
805 | if (usedma) { | 801 | if (!hw->regs) { |
806 | if (pdev->dev.dma_mask == NULL) | 802 | dev_err(&pdev->dev, "cannot ioremap\n"); |
807 | dev_warn(&pdev->dev, "no dma mask\n"); | 803 | err = -ENXIO; |
808 | else | 804 | goto err_ioremap; |
809 | hw->usedma = 1; | ||
810 | } | 805 | } |
811 | 806 | ||
812 | if (hw->usedma) { | 807 | platform_set_drvdata(pdev, hw); |
813 | /* | ||
814 | * create memory device with 8 bits dev_devwidth | ||
815 | * needed for proper byte ordering to spi fifo | ||
816 | */ | ||
817 | int memid = au1xxx_ddma_add_device(&au1550_spi_mem_dbdev); | ||
818 | if (!memid) { | ||
819 | dev_err(&pdev->dev, | ||
820 | "Cannot create dma 8 bit mem device\n"); | ||
821 | err = -ENXIO; | ||
822 | goto err_dma_add_dev; | ||
823 | } | ||
824 | 808 | ||
825 | hw->dma_tx_ch = au1xxx_dbdma_chan_alloc(memid, | 809 | init_completion(&hw->master_done); |
810 | |||
811 | hw->bitbang.master = hw->master; | ||
812 | hw->bitbang.setup_transfer = au1550_spi_setupxfer; | ||
813 | hw->bitbang.chipselect = au1550_spi_chipsel; | ||
814 | hw->bitbang.master->setup = au1550_spi_setup; | ||
815 | hw->bitbang.txrx_bufs = au1550_spi_txrx_bufs; | ||
816 | |||
817 | if (hw->usedma) { | ||
818 | hw->dma_tx_ch = au1xxx_dbdma_chan_alloc(ddma_memid, | ||
826 | hw->dma_tx_id, NULL, (void *)hw); | 819 | hw->dma_tx_id, NULL, (void *)hw); |
827 | if (hw->dma_tx_ch == 0) { | 820 | if (hw->dma_tx_ch == 0) { |
828 | dev_err(&pdev->dev, | 821 | dev_err(&pdev->dev, |
@@ -841,7 +834,7 @@ static int __init au1550_spi_probe(struct platform_device *pdev) | |||
841 | 834 | ||
842 | 835 | ||
843 | hw->dma_rx_ch = au1xxx_dbdma_chan_alloc(hw->dma_rx_id, | 836 | hw->dma_rx_ch = au1xxx_dbdma_chan_alloc(hw->dma_rx_id, |
844 | memid, NULL, (void *)hw); | 837 | ddma_memid, NULL, (void *)hw); |
845 | if (hw->dma_rx_ch == 0) { | 838 | if (hw->dma_rx_ch == 0) { |
846 | dev_err(&pdev->dev, | 839 | dev_err(&pdev->dev, |
847 | "Cannot allocate rx dma channel\n"); | 840 | "Cannot allocate rx dma channel\n"); |
@@ -874,7 +867,7 @@ static int __init au1550_spi_probe(struct platform_device *pdev) | |||
874 | goto err_no_irq; | 867 | goto err_no_irq; |
875 | } | 868 | } |
876 | 869 | ||
877 | master->bus_num = hw->pdata->bus_num; | 870 | master->bus_num = pdev->id; |
878 | master->num_chipselect = hw->pdata->num_chipselect; | 871 | master->num_chipselect = hw->pdata->num_chipselect; |
879 | 872 | ||
880 | /* | 873 | /* |
@@ -924,8 +917,11 @@ err_no_txdma_descr: | |||
924 | au1xxx_dbdma_chan_free(hw->dma_tx_ch); | 917 | au1xxx_dbdma_chan_free(hw->dma_tx_ch); |
925 | 918 | ||
926 | err_no_txdma: | 919 | err_no_txdma: |
927 | err_dma_add_dev: | 920 | iounmap((void __iomem *)hw->regs); |
928 | release_mem_region((unsigned long)hw->regs, sizeof(psc_spi_t)); | 921 | |
922 | err_ioremap: | ||
923 | release_resource(hw->ioarea); | ||
924 | kfree(hw->ioarea); | ||
929 | 925 | ||
930 | err_no_iores: | 926 | err_no_iores: |
931 | err_no_pdata: | 927 | err_no_pdata: |
@@ -944,7 +940,9 @@ static int __exit au1550_spi_remove(struct platform_device *pdev) | |||
944 | 940 | ||
945 | spi_bitbang_stop(&hw->bitbang); | 941 | spi_bitbang_stop(&hw->bitbang); |
946 | free_irq(hw->irq, hw); | 942 | free_irq(hw->irq, hw); |
947 | release_mem_region((unsigned long)hw->regs, sizeof(psc_spi_t)); | 943 | iounmap((void __iomem *)hw->regs); |
944 | release_resource(hw->ioarea); | ||
945 | kfree(hw->ioarea); | ||
948 | 946 | ||
949 | if (hw->usedma) { | 947 | if (hw->usedma) { |
950 | au1550_spi_dma_rxtmp_free(hw); | 948 | au1550_spi_dma_rxtmp_free(hw); |
@@ -971,12 +969,24 @@ static struct platform_driver au1550_spi_drv = { | |||
971 | 969 | ||
972 | static int __init au1550_spi_init(void) | 970 | static int __init au1550_spi_init(void) |
973 | { | 971 | { |
972 | /* | ||
973 | * create memory device with 8 bits dev_devwidth | ||
974 | * needed for proper byte ordering to spi fifo | ||
975 | */ | ||
976 | if (usedma) { | ||
977 | ddma_memid = au1xxx_ddma_add_device(&au1550_spi_mem_dbdev); | ||
978 | if (!ddma_memid) | ||
979 | printk(KERN_ERR "au1550-spi: cannot add memory" | ||
980 | "dbdma device\n"); | ||
981 | } | ||
974 | return platform_driver_probe(&au1550_spi_drv, au1550_spi_probe); | 982 | return platform_driver_probe(&au1550_spi_drv, au1550_spi_probe); |
975 | } | 983 | } |
976 | module_init(au1550_spi_init); | 984 | module_init(au1550_spi_init); |
977 | 985 | ||
978 | static void __exit au1550_spi_exit(void) | 986 | static void __exit au1550_spi_exit(void) |
979 | { | 987 | { |
988 | if (usedma && ddma_memid) | ||
989 | au1xxx_ddma_del_device(ddma_memid); | ||
980 | platform_driver_unregister(&au1550_spi_drv); | 990 | platform_driver_unregister(&au1550_spi_drv); |
981 | } | 991 | } |
982 | module_exit(au1550_spi_exit); | 992 | module_exit(au1550_spi_exit); |