aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNaveen Krishna Chatradhi <ch.naveen@samsung.com>2014-07-16 11:19:08 -0400
committerMark Brown <broonie@linaro.org>2014-07-17 14:37:49 -0400
commit306972cedfdedc662dd8e32a6397d0e29f2ac90e (patch)
tree06770f2712026f63843054f208dc720e5c41b1cc
parente2689b946a42acaad9ba94bf3a0bf4caa6509b9e (diff)
spi: s3c64xx: use the generic SPI "cs-gpios" property
The s3c64xx SPI driver uses a custom DT binding to specify the GPIO used to drive the chip select (CS) line instead of using the generic "cs-gpios" property already defined in: Documentation/devicetree/bindings/spi/spi-bus.txt. It's unfortunate that drivers are not using standard bindings and creating custom ones instead but in most cases this can't be changed without breaking Device Tree backward compatibility. But in the case of this driver, its DT binding has been broken for more than a year. Since after commit (dated June, 21 2013): 3146bee ("spi: s3c64xx: Added provision for dedicated cs pin") DT backward compatibility was broken and nobody noticed until now when the commit was reverted. So it seems to be safe to change the binding to use the standard SPI "cs-gpios" property instead of using a custom one just for this driver. This patch also allows boards that don't use a GPIO pin for the CS to work with the driver since the SPI core will take care of setting spi->cs_gpio to -ENOENT if a board wants to use the built in CS instead of a GPIO as explained in the SPI bus DT binding: Documentation/devicetree/bindings/spi/spi-bus.txt. For non-DT platforms, spi->cs_gpio will be set to -ENOENT as well unless they specify a GPIO pin in their platform data. So both native and GPIO chip select is also supported for legacy boards. The above use case was what motivated commit 3146bee which broke the DT binding backward compatibility in the first place. Signed-off-by: Naveen Krishna Chatradhi <ch.naveen@samsung.com> [javier.martinez@collabora.co.uk: split changes and improve commit message] 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>
-rw-r--r--drivers/spi/spi-s3c64xx.c49
1 files changed, 29 insertions, 20 deletions
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index b1e26f00cd05..1c36311935d7 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -773,14 +773,6 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
773 return ERR_PTR(-ENOMEM); 773 return ERR_PTR(-ENOMEM);
774 } 774 }
775 775
776 cs->line = of_get_named_gpio(data_np, "cs-gpio", 0);
777 if (!gpio_is_valid(cs->line)) {
778 dev_err(&spi->dev, "chip select gpio is not specified or invalid\n");
779 kfree(cs);
780 of_node_put(data_np);
781 return ERR_PTR(-EINVAL);
782 }
783
784 of_property_read_u32(data_np, "samsung,spi-feedback-delay", &fb_delay); 776 of_property_read_u32(data_np, "samsung,spi-feedback-delay", &fb_delay);
785 cs->fb_delay = fb_delay; 777 cs->fb_delay = fb_delay;
786 of_node_put(data_np); 778 of_node_put(data_np);
@@ -801,9 +793,16 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
801 int err; 793 int err;
802 794
803 sdd = spi_master_get_devdata(spi->master); 795 sdd = spi_master_get_devdata(spi->master);
804 if (!cs && spi->dev.of_node) { 796 if (spi->dev.of_node) {
805 cs = s3c64xx_get_slave_ctrldata(spi); 797 cs = s3c64xx_get_slave_ctrldata(spi);
806 spi->controller_data = cs; 798 spi->controller_data = cs;
799 } else if (cs) {
800 /* On non-DT platforms the SPI core will set spi->cs_gpio
801 * to -ENOENT. The GPIO pin used to drive the chip select
802 * is defined by using platform data so spi->cs_gpio value
803 * has to be override to have the proper GPIO pin number.
804 */
805 spi->cs_gpio = cs->line;
807 } 806 }
808 807
809 if (IS_ERR_OR_NULL(cs)) { 808 if (IS_ERR_OR_NULL(cs)) {
@@ -812,17 +811,17 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
812 } 811 }
813 812
814 if (!spi_get_ctldata(spi)) { 813 if (!spi_get_ctldata(spi)) {
815 err = gpio_request_one(cs->line, GPIOF_OUT_INIT_HIGH, 814 if (gpio_is_valid(spi->cs_gpio)) {
816 dev_name(&spi->dev)); 815 err = gpio_request_one(spi->cs_gpio, GPIOF_OUT_INIT_HIGH,
817 if (err) { 816 dev_name(&spi->dev));
818 dev_err(&spi->dev, 817 if (err) {
819 "Failed to get /CS gpio [%d]: %d\n", 818 dev_err(&spi->dev,
820 cs->line, err); 819 "Failed to get /CS gpio [%d]: %d\n",
821 goto err_gpio_req; 820 spi->cs_gpio, err);
821 goto err_gpio_req;
822 }
822 } 823 }
823 824
824 spi->cs_gpio = cs->line;
825
826 spi_set_ctldata(spi, cs); 825 spi_set_ctldata(spi, cs);
827 } 826 }
828 827
@@ -875,7 +874,8 @@ setup_exit:
875 /* setup() returns with device de-selected */ 874 /* setup() returns with device de-selected */
876 writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL); 875 writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
877 876
878 gpio_free(cs->line); 877 if (gpio_is_valid(spi->cs_gpio))
878 gpio_free(spi->cs_gpio);
879 spi_set_ctldata(spi, NULL); 879 spi_set_ctldata(spi, NULL);
880 880
881err_gpio_req: 881err_gpio_req:
@@ -889,11 +889,20 @@ static void s3c64xx_spi_cleanup(struct spi_device *spi)
889{ 889{
890 struct s3c64xx_spi_csinfo *cs = spi_get_ctldata(spi); 890 struct s3c64xx_spi_csinfo *cs = spi_get_ctldata(spi);
891 891
892 if (cs) { 892 if (gpio_is_valid(spi->cs_gpio)) {
893 gpio_free(spi->cs_gpio); 893 gpio_free(spi->cs_gpio);
894 if (spi->dev.of_node) 894 if (spi->dev.of_node)
895 kfree(cs); 895 kfree(cs);
896 else {
897 /* On non-DT platforms, the SPI core sets
898 * spi->cs_gpio to -ENOENT and .setup()
899 * overrides it with the GPIO pin value
900 * passed using platform data.
901 */
902 spi->cs_gpio = -ENOENT;
903 }
896 } 904 }
905
897 spi_set_ctldata(spi, NULL); 906 spi_set_ctldata(spi, NULL);
898} 907}
899 908