aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-s3c64xx.c
diff options
context:
space:
mode:
authorJavier Martinez Canillas <javier.martinez@collabora.co.uk>2014-07-16 11:19:07 -0400
committerMark Brown <broonie@linaro.org>2014-07-17 14:37:41 -0400
commite2689b946a42acaad9ba94bf3a0bf4caa6509b9e (patch)
tree2b2af8e08ea2150a4e5e92cdcba00ea0e6170768 /drivers/spi/spi-s3c64xx.c
parent7171511eaec5bf23fb06078f59784a3a0626b38f (diff)
spi: s3c64xx: Revert "spi: s3c64xx: Added provision for dedicated cs pin"
This reverts commit 3146beec21b64f4551fcf0ac148381d54dc41b1b. This commit resulted in a DT backward compatibility breakage. Some devices use the native chip select (CS) instead of a GPIO pin to drive the CS line. But the SPI driver made it mandatory to specify a GPIO pin in the SPI device node controller-data. So, using the built-in CS was not possible with the driver. Commit 3146bee tried to fix that by adding a "cs-gpio" property which could be defined in the SPI device node to make the driver request the GPIO from the controller-data node. Unfortunately that changed the old DT binding semantics since now it's mandatory to have the "cs-gpio" property defined in the SPI device node in order to use a GPIO pin to drive the CS. As an example, a SPI device was defined before the commit with: spi@12d20000 { slave-node@0 { controller-data { cs-gpio = <&gpb1 2 0>; } } } and after the commit, the following DTS snippet must be used: spi@12d20000 { cs-gpio; slave-node@0 { controller-data { cs-gpio = <&gpb1 2 0>; } } } So, after commit 3146bee the driver does not look for the GPIO by default and it only looks for it if the top level "cs-gpio" property is defined while the default used to be the opposite. To always request the GPIO defined in the controller-data node. This means that old FDT that of course didn't have this added "cs-gpio" DT property in the SPI node broke after this change. The offending commit can't be reverted cleanly since more than a year have passed and other changes were made in the meantime but this patch partially reverts the driver to it's original state so old FDT can work again. This patch will break Device Trees that were relying on the new behavior of course but the patch should be reverted because: a) There aren't DTS in mainline that use this new property. b) They were relying on a behavior that broke DT compatibility. c) The new binding is awkard, needing two properties with the same name (cs-gpio) on different nodes is confusing at least. d) The new property was not added to the DT binding doc: Documentation/devicetree/bindings/spi/spi-samsung.txt Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk> Reviewed-by: Tomasz Figa <t.figa@samsung.com> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/spi/spi-s3c64xx.c')
-rw-r--r--drivers/spi/spi-s3c64xx.c37
1 files changed, 11 insertions, 26 deletions
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 75a56968b14c..b1e26f00cd05 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -197,7 +197,6 @@ struct s3c64xx_spi_driver_data {
197 struct s3c64xx_spi_dma_data tx_dma; 197 struct s3c64xx_spi_dma_data tx_dma;
198 struct s3c64xx_spi_port_config *port_conf; 198 struct s3c64xx_spi_port_config *port_conf;
199 unsigned int port_id; 199 unsigned int port_id;
200 bool cs_gpio;
201}; 200};
202 201
203static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) 202static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
@@ -754,10 +753,8 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
754{ 753{
755 struct s3c64xx_spi_csinfo *cs; 754 struct s3c64xx_spi_csinfo *cs;
756 struct device_node *slave_np, *data_np = NULL; 755 struct device_node *slave_np, *data_np = NULL;
757 struct s3c64xx_spi_driver_data *sdd;
758 u32 fb_delay = 0; 756 u32 fb_delay = 0;
759 757
760 sdd = spi_master_get_devdata(spi->master);
761 slave_np = spi->dev.of_node; 758 slave_np = spi->dev.of_node;
762 if (!slave_np) { 759 if (!slave_np) {
763 dev_err(&spi->dev, "device node not found\n"); 760 dev_err(&spi->dev, "device node not found\n");
@@ -776,10 +773,7 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
776 return ERR_PTR(-ENOMEM); 773 return ERR_PTR(-ENOMEM);
777 } 774 }
778 775
779 /* The CS line is asserted/deasserted by the gpio pin */ 776 cs->line = of_get_named_gpio(data_np, "cs-gpio", 0);
780 if (sdd->cs_gpio)
781 cs->line = of_get_named_gpio(data_np, "cs-gpio", 0);
782
783 if (!gpio_is_valid(cs->line)) { 777 if (!gpio_is_valid(cs->line)) {
784 dev_err(&spi->dev, "chip select gpio is not specified or invalid\n"); 778 dev_err(&spi->dev, "chip select gpio is not specified or invalid\n");
785 kfree(cs); 779 kfree(cs);
@@ -818,20 +812,17 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
818 } 812 }
819 813
820 if (!spi_get_ctldata(spi)) { 814 if (!spi_get_ctldata(spi)) {
821 /* Request gpio only if cs line is asserted by gpio pins */ 815 err = gpio_request_one(cs->line, GPIOF_OUT_INIT_HIGH,
822 if (sdd->cs_gpio) { 816 dev_name(&spi->dev));
823 err = gpio_request_one(cs->line, GPIOF_OUT_INIT_HIGH, 817 if (err) {
824 dev_name(&spi->dev)); 818 dev_err(&spi->dev,
825 if (err) { 819 "Failed to get /CS gpio [%d]: %d\n",
826 dev_err(&spi->dev, 820 cs->line, err);
827 "Failed to get /CS gpio [%d]: %d\n", 821 goto err_gpio_req;
828 cs->line, err);
829 goto err_gpio_req;
830 }
831
832 spi->cs_gpio = cs->line;
833 } 822 }
834 823
824 spi->cs_gpio = cs->line;
825
835 spi_set_ctldata(spi, cs); 826 spi_set_ctldata(spi, cs);
836 } 827 }
837 828
@@ -897,10 +888,8 @@ err_gpio_req:
897static void s3c64xx_spi_cleanup(struct spi_device *spi) 888static void s3c64xx_spi_cleanup(struct spi_device *spi)
898{ 889{
899 struct s3c64xx_spi_csinfo *cs = spi_get_ctldata(spi); 890 struct s3c64xx_spi_csinfo *cs = spi_get_ctldata(spi);
900 struct s3c64xx_spi_driver_data *sdd;
901 891
902 sdd = spi_master_get_devdata(spi->master); 892 if (cs) {
903 if (spi->cs_gpio) {
904 gpio_free(spi->cs_gpio); 893 gpio_free(spi->cs_gpio);
905 if (spi->dev.of_node) 894 if (spi->dev.of_node)
906 kfree(cs); 895 kfree(cs);
@@ -1075,11 +1064,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
1075 sdd->cntrlr_info = sci; 1064 sdd->cntrlr_info = sci;
1076 sdd->pdev = pdev; 1065 sdd->pdev = pdev;
1077 sdd->sfr_start = mem_res->start; 1066 sdd->sfr_start = mem_res->start;
1078 sdd->cs_gpio = true;
1079 if (pdev->dev.of_node) { 1067 if (pdev->dev.of_node) {
1080 if (!of_find_property(pdev->dev.of_node, "cs-gpio", NULL))
1081 sdd->cs_gpio = false;
1082
1083 ret = of_alias_get_id(pdev->dev.of_node, "spi"); 1068 ret = of_alias_get_id(pdev->dev.of_node, "spi");
1084 if (ret < 0) { 1069 if (ret < 0) {
1085 dev_err(&pdev->dev, "failed to get alias id, errno %d\n", 1070 dev_err(&pdev->dev, "failed to get alias id, errno %d\n",