diff options
author | Murali Karicheri <m-karicheri2@ti.com> | 2012-12-11 16:20:39 -0500 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2013-02-05 07:26:57 -0500 |
commit | aae7147dfc522062b3448f67f5517d32fbdab1fb (patch) | |
tree | cbaca876f97b552e6ee1a9a984fb51af97a3ccd4 /drivers/spi/spi-davinci.c | |
parent | 830379e04858098d65c59f07f68be3d73244ae54 (diff) |
spi/davinci: add OF support for the spi controller
This adds OF support to DaVinci SPI controller to configure platform
data through device bindings. Also replaces clk_enable() with
of clk_prepare_enable() as well as clk_disable() with
clk_disable_unprepare().
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/spi/spi-davinci.c')
-rw-r--r-- | drivers/spi/spi-davinci.c | 102 |
1 files changed, 88 insertions, 14 deletions
diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 13661e129d96..50bd2cdc52de 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <linux/dmaengine.h> | 28 | #include <linux/dmaengine.h> |
29 | #include <linux/dma-mapping.h> | 29 | #include <linux/dma-mapping.h> |
30 | #include <linux/edma.h> | 30 | #include <linux/edma.h> |
31 | #include <linux/of.h> | ||
32 | #include <linux/of_device.h> | ||
31 | #include <linux/spi/spi.h> | 33 | #include <linux/spi/spi.h> |
32 | #include <linux/spi/spi_bitbang.h> | 34 | #include <linux/spi/spi_bitbang.h> |
33 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
@@ -135,7 +137,7 @@ struct davinci_spi { | |||
135 | int dma_rx_chnum; | 137 | int dma_rx_chnum; |
136 | int dma_tx_chnum; | 138 | int dma_tx_chnum; |
137 | 139 | ||
138 | struct davinci_spi_platform_data *pdata; | 140 | struct davinci_spi_platform_data pdata; |
139 | 141 | ||
140 | void (*get_rx)(u32 rx_data, struct davinci_spi *); | 142 | void (*get_rx)(u32 rx_data, struct davinci_spi *); |
141 | u32 (*get_tx)(struct davinci_spi *); | 143 | u32 (*get_tx)(struct davinci_spi *); |
@@ -213,7 +215,7 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value) | |||
213 | bool gpio_chipsel = false; | 215 | bool gpio_chipsel = false; |
214 | 216 | ||
215 | dspi = spi_master_get_devdata(spi->master); | 217 | dspi = spi_master_get_devdata(spi->master); |
216 | pdata = dspi->pdata; | 218 | pdata = &dspi->pdata; |
217 | 219 | ||
218 | if (pdata->chip_sel && chip_sel < pdata->num_chipselect && | 220 | if (pdata->chip_sel && chip_sel < pdata->num_chipselect && |
219 | pdata->chip_sel[chip_sel] != SPI_INTERN_CS) | 221 | pdata->chip_sel[chip_sel] != SPI_INTERN_CS) |
@@ -392,7 +394,7 @@ static int davinci_spi_setup(struct spi_device *spi) | |||
392 | struct davinci_spi_platform_data *pdata; | 394 | struct davinci_spi_platform_data *pdata; |
393 | 395 | ||
394 | dspi = spi_master_get_devdata(spi->master); | 396 | dspi = spi_master_get_devdata(spi->master); |
395 | pdata = dspi->pdata; | 397 | pdata = &dspi->pdata; |
396 | 398 | ||
397 | /* if bits per word length is zero then set it default 8 */ | 399 | /* if bits per word length is zero then set it default 8 */ |
398 | if (!spi->bits_per_word) | 400 | if (!spi->bits_per_word) |
@@ -534,7 +536,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
534 | struct scatterlist sg_rx, sg_tx; | 536 | struct scatterlist sg_rx, sg_tx; |
535 | 537 | ||
536 | dspi = spi_master_get_devdata(spi->master); | 538 | dspi = spi_master_get_devdata(spi->master); |
537 | pdata = dspi->pdata; | 539 | pdata = &dspi->pdata; |
538 | spicfg = (struct davinci_spi_config *)spi->controller_data; | 540 | spicfg = (struct davinci_spi_config *)spi->controller_data; |
539 | if (!spicfg) | 541 | if (!spicfg) |
540 | spicfg = &davinci_spi_default_cfg; | 542 | spicfg = &davinci_spi_default_cfg; |
@@ -758,6 +760,70 @@ rx_dma_failed: | |||
758 | return r; | 760 | return r; |
759 | } | 761 | } |
760 | 762 | ||
763 | #if defined(CONFIG_OF) | ||
764 | static const struct of_device_id davinci_spi_of_match[] = { | ||
765 | { | ||
766 | .compatible = "ti,dm644x-spi", | ||
767 | }, | ||
768 | { | ||
769 | .compatible = "ti,da8xx-spi", | ||
770 | .data = (void *)SPI_VERSION_2, | ||
771 | }, | ||
772 | { }, | ||
773 | }; | ||
774 | MODULE_DEVICE_TABLE(of, davini_spi_of_match); | ||
775 | |||
776 | /** | ||
777 | * spi_davinci_get_pdata - Get platform data from DTS binding | ||
778 | * @pdev: ptr to platform data | ||
779 | * @dspi: ptr to driver data | ||
780 | * | ||
781 | * Parses and populates pdata in dspi from device tree bindings. | ||
782 | * | ||
783 | * NOTE: Not all platform data params are supported currently. | ||
784 | */ | ||
785 | static int spi_davinci_get_pdata(struct platform_device *pdev, | ||
786 | struct davinci_spi *dspi) | ||
787 | { | ||
788 | struct device_node *node = pdev->dev.of_node; | ||
789 | struct davinci_spi_platform_data *pdata; | ||
790 | unsigned int num_cs, intr_line = 0; | ||
791 | const struct of_device_id *match; | ||
792 | |||
793 | pdata = &dspi->pdata; | ||
794 | |||
795 | pdata->version = SPI_VERSION_1; | ||
796 | match = of_match_device(of_match_ptr(davinci_spi_of_match), | ||
797 | &pdev->dev); | ||
798 | if (!match) | ||
799 | return -ENODEV; | ||
800 | |||
801 | /* match data has the SPI version number for SPI_VERSION_2 */ | ||
802 | if (match->data == (void *)SPI_VERSION_2) | ||
803 | pdata->version = SPI_VERSION_2; | ||
804 | |||
805 | /* | ||
806 | * default num_cs is 1 and all chipsel are internal to the chip | ||
807 | * indicated by chip_sel being NULL. GPIO based CS is not | ||
808 | * supported yet in DT bindings. | ||
809 | */ | ||
810 | num_cs = 1; | ||
811 | of_property_read_u32(node, "num-cs", &num_cs); | ||
812 | pdata->num_chipselect = num_cs; | ||
813 | of_property_read_u32(node, "ti,davinci-spi-intr-line", &intr_line); | ||
814 | pdata->intr_line = intr_line; | ||
815 | return 0; | ||
816 | } | ||
817 | #else | ||
818 | #define davinci_spi_of_match NULL | ||
819 | static struct davinci_spi_platform_data | ||
820 | *spi_davinci_get_pdata(struct platform_device *pdev, | ||
821 | struct davinci_spi *dspi) | ||
822 | { | ||
823 | return -ENODEV; | ||
824 | } | ||
825 | #endif | ||
826 | |||
761 | /** | 827 | /** |
762 | * davinci_spi_probe - probe function for SPI Master Controller | 828 | * davinci_spi_probe - probe function for SPI Master Controller |
763 | * @pdev: platform_device structure which contains plateform specific data | 829 | * @pdev: platform_device structure which contains plateform specific data |
@@ -780,12 +846,6 @@ static int davinci_spi_probe(struct platform_device *pdev) | |||
780 | int i = 0, ret = 0; | 846 | int i = 0, ret = 0; |
781 | u32 spipc0; | 847 | u32 spipc0; |
782 | 848 | ||
783 | pdata = pdev->dev.platform_data; | ||
784 | if (pdata == NULL) { | ||
785 | ret = -ENODEV; | ||
786 | goto err; | ||
787 | } | ||
788 | |||
789 | master = spi_alloc_master(&pdev->dev, sizeof(struct davinci_spi)); | 849 | master = spi_alloc_master(&pdev->dev, sizeof(struct davinci_spi)); |
790 | if (master == NULL) { | 850 | if (master == NULL) { |
791 | ret = -ENOMEM; | 851 | ret = -ENOMEM; |
@@ -800,6 +860,19 @@ static int davinci_spi_probe(struct platform_device *pdev) | |||
800 | goto free_master; | 860 | goto free_master; |
801 | } | 861 | } |
802 | 862 | ||
863 | if (pdev->dev.platform_data) { | ||
864 | pdata = pdev->dev.platform_data; | ||
865 | dspi->pdata = *pdata; | ||
866 | } else { | ||
867 | /* update dspi pdata with that from the DT */ | ||
868 | ret = spi_davinci_get_pdata(pdev, dspi); | ||
869 | if (ret < 0) | ||
870 | goto free_master; | ||
871 | } | ||
872 | |||
873 | /* pdata in dspi is now updated and point pdata to that */ | ||
874 | pdata = &dspi->pdata; | ||
875 | |||
803 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 876 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
804 | if (r == NULL) { | 877 | if (r == NULL) { |
805 | ret = -ENOENT; | 878 | ret = -ENOENT; |
@@ -807,7 +880,6 @@ static int davinci_spi_probe(struct platform_device *pdev) | |||
807 | } | 880 | } |
808 | 881 | ||
809 | dspi->pbase = r->start; | 882 | dspi->pbase = r->start; |
810 | dspi->pdata = pdata; | ||
811 | 883 | ||
812 | mem = request_mem_region(r->start, resource_size(r), pdev->name); | 884 | mem = request_mem_region(r->start, resource_size(r), pdev->name); |
813 | if (mem == NULL) { | 885 | if (mem == NULL) { |
@@ -843,8 +915,9 @@ static int davinci_spi_probe(struct platform_device *pdev) | |||
843 | ret = -ENODEV; | 915 | ret = -ENODEV; |
844 | goto put_master; | 916 | goto put_master; |
845 | } | 917 | } |
846 | clk_enable(dspi->clk); | 918 | clk_prepare_enable(dspi->clk); |
847 | 919 | ||
920 | master->dev.of_node = pdev->dev.of_node; | ||
848 | master->bus_num = pdev->id; | 921 | master->bus_num = pdev->id; |
849 | master->num_chipselect = pdata->num_chipselect; | 922 | master->num_chipselect = pdata->num_chipselect; |
850 | master->setup = davinci_spi_setup; | 923 | master->setup = davinci_spi_setup; |
@@ -927,7 +1000,7 @@ free_dma: | |||
927 | dma_release_channel(dspi->dma_rx); | 1000 | dma_release_channel(dspi->dma_rx); |
928 | dma_release_channel(dspi->dma_tx); | 1001 | dma_release_channel(dspi->dma_tx); |
929 | free_clk: | 1002 | free_clk: |
930 | clk_disable(dspi->clk); | 1003 | clk_disable_unprepare(dspi->clk); |
931 | clk_put(dspi->clk); | 1004 | clk_put(dspi->clk); |
932 | put_master: | 1005 | put_master: |
933 | spi_master_put(master); | 1006 | spi_master_put(master); |
@@ -963,7 +1036,7 @@ static int davinci_spi_remove(struct platform_device *pdev) | |||
963 | 1036 | ||
964 | spi_bitbang_stop(&dspi->bitbang); | 1037 | spi_bitbang_stop(&dspi->bitbang); |
965 | 1038 | ||
966 | clk_disable(dspi->clk); | 1039 | clk_disable_unprepare(dspi->clk); |
967 | clk_put(dspi->clk); | 1040 | clk_put(dspi->clk); |
968 | spi_master_put(master); | 1041 | spi_master_put(master); |
969 | free_irq(dspi->irq, dspi); | 1042 | free_irq(dspi->irq, dspi); |
@@ -978,6 +1051,7 @@ static struct platform_driver davinci_spi_driver = { | |||
978 | .driver = { | 1051 | .driver = { |
979 | .name = "spi_davinci", | 1052 | .name = "spi_davinci", |
980 | .owner = THIS_MODULE, | 1053 | .owner = THIS_MODULE, |
1054 | .of_match_table = davinci_spi_of_match, | ||
981 | }, | 1055 | }, |
982 | .probe = davinci_spi_probe, | 1056 | .probe = davinci_spi_probe, |
983 | .remove = davinci_spi_remove, | 1057 | .remove = davinci_spi_remove, |