aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/spi/spi-s3c64xx.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 70b221355400..067f442de2d4 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -208,6 +208,7 @@ struct s3c64xx_spi_driver_data {
208 struct s3c64xx_spi_port_config *port_conf; 208 struct s3c64xx_spi_port_config *port_conf;
209 unsigned int port_id; 209 unsigned int port_id;
210 unsigned long gpios[4]; 210 unsigned long gpios[4];
211 bool cs_gpio;
211}; 212};
212 213
213static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) 214static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
@@ -570,14 +571,16 @@ static inline void enable_cs(struct s3c64xx_spi_driver_data *sdd,
570 if (sdd->tgl_spi != spi) { /* if last mssg on diff device */ 571 if (sdd->tgl_spi != spi) { /* if last mssg on diff device */
571 /* Deselect the last toggled device */ 572 /* Deselect the last toggled device */
572 cs = sdd->tgl_spi->controller_data; 573 cs = sdd->tgl_spi->controller_data;
573 gpio_set_value(cs->line, 574 if (sdd->cs_gpio)
574 spi->mode & SPI_CS_HIGH ? 0 : 1); 575 gpio_set_value(cs->line,
576 spi->mode & SPI_CS_HIGH ? 0 : 1);
575 } 577 }
576 sdd->tgl_spi = NULL; 578 sdd->tgl_spi = NULL;
577 } 579 }
578 580
579 cs = spi->controller_data; 581 cs = spi->controller_data;
580 gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 1 : 0); 582 if (sdd->cs_gpio)
583 gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 1 : 0);
581 584
582 /* Start the signals */ 585 /* Start the signals */
583 writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL); 586 writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
@@ -710,7 +713,8 @@ static inline void disable_cs(struct s3c64xx_spi_driver_data *sdd,
710 if (sdd->tgl_spi == spi) 713 if (sdd->tgl_spi == spi)
711 sdd->tgl_spi = NULL; 714 sdd->tgl_spi = NULL;
712 715
713 gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 0 : 1); 716 if (sdd->cs_gpio)
717 gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 0 : 1);
714 718
715 /* Quiese the signals */ 719 /* Quiese the signals */
716 writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL); 720 writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
@@ -998,8 +1002,10 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
998{ 1002{
999 struct s3c64xx_spi_csinfo *cs; 1003 struct s3c64xx_spi_csinfo *cs;
1000 struct device_node *slave_np, *data_np = NULL; 1004 struct device_node *slave_np, *data_np = NULL;
1005 struct s3c64xx_spi_driver_data *sdd;
1001 u32 fb_delay = 0; 1006 u32 fb_delay = 0;
1002 1007
1008 sdd = spi_master_get_devdata(spi->master);
1003 slave_np = spi->dev.of_node; 1009 slave_np = spi->dev.of_node;
1004 if (!slave_np) { 1010 if (!slave_np) {
1005 dev_err(&spi->dev, "device node not found\n"); 1011 dev_err(&spi->dev, "device node not found\n");
@@ -1019,7 +1025,10 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
1019 return ERR_PTR(-ENOMEM); 1025 return ERR_PTR(-ENOMEM);
1020 } 1026 }
1021 1027
1022 cs->line = of_get_named_gpio(data_np, "cs-gpio", 0); 1028 /* The CS line is asserted/deasserted by the gpio pin */
1029 if (sdd->cs_gpio)
1030 cs->line = of_get_named_gpio(data_np, "cs-gpio", 0);
1031
1023 if (!gpio_is_valid(cs->line)) { 1032 if (!gpio_is_valid(cs->line)) {
1024 dev_err(&spi->dev, "chip select gpio is not specified or invalid\n"); 1033 dev_err(&spi->dev, "chip select gpio is not specified or invalid\n");
1025 kfree(cs); 1034 kfree(cs);
@@ -1059,7 +1068,8 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
1059 return -ENODEV; 1068 return -ENODEV;
1060 } 1069 }
1061 1070
1062 if (!spi_get_ctldata(spi)) { 1071 /* Request gpio only if cs line is asserted by gpio pins */
1072 if (sdd->cs_gpio) {
1063 err = gpio_request_one(cs->line, GPIOF_OUT_INIT_HIGH, 1073 err = gpio_request_one(cs->line, GPIOF_OUT_INIT_HIGH,
1064 dev_name(&spi->dev)); 1074 dev_name(&spi->dev));
1065 if (err) { 1075 if (err) {
@@ -1068,9 +1078,11 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
1068 cs->line, err); 1078 cs->line, err);
1069 goto err_gpio_req; 1079 goto err_gpio_req;
1070 } 1080 }
1071 spi_set_ctldata(spi, cs);
1072 } 1081 }
1073 1082
1083 if (!spi_get_ctldata(spi))
1084 spi_set_ctldata(spi, cs);
1085
1074 sci = sdd->cntrlr_info; 1086 sci = sdd->cntrlr_info;
1075 1087
1076 spin_lock_irqsave(&sdd->lock, flags); 1088 spin_lock_irqsave(&sdd->lock, flags);
@@ -1148,8 +1160,10 @@ err_gpio_req:
1148static void s3c64xx_spi_cleanup(struct spi_device *spi) 1160static void s3c64xx_spi_cleanup(struct spi_device *spi)
1149{ 1161{
1150 struct s3c64xx_spi_csinfo *cs = spi_get_ctldata(spi); 1162 struct s3c64xx_spi_csinfo *cs = spi_get_ctldata(spi);
1163 struct s3c64xx_spi_driver_data *sdd;
1151 1164
1152 if (cs) { 1165 sdd = spi_master_get_devdata(spi->master);
1166 if (cs && sdd->cs_gpio) {
1153 gpio_free(cs->line); 1167 gpio_free(cs->line);
1154 if (spi->dev.of_node) 1168 if (spi->dev.of_node)
1155 kfree(cs); 1169 kfree(cs);
@@ -1326,7 +1340,11 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
1326 sdd->cntrlr_info = sci; 1340 sdd->cntrlr_info = sci;
1327 sdd->pdev = pdev; 1341 sdd->pdev = pdev;
1328 sdd->sfr_start = mem_res->start; 1342 sdd->sfr_start = mem_res->start;
1343 sdd->cs_gpio = true;
1329 if (pdev->dev.of_node) { 1344 if (pdev->dev.of_node) {
1345 if (!of_find_property(pdev->dev.of_node, "cs-gpio", NULL))
1346 sdd->cs_gpio = false;
1347
1330 ret = of_alias_get_id(pdev->dev.of_node, "spi"); 1348 ret = of_alias_get_id(pdev->dev.of_node, "spi");
1331 if (ret < 0) { 1349 if (ret < 0) {
1332 dev_err(&pdev->dev, "failed to get alias id, errno %d\n", 1350 dev_err(&pdev->dev, "failed to get alias id, errno %d\n",