aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c64xx-spi.h2
-rw-r--r--drivers/spi/spi-s3c64xx.c31
2 files changed, 26 insertions, 7 deletions
diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
index c818a7c18929..ceba18d23a5a 100644
--- a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
+++ b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
@@ -18,7 +18,6 @@ struct platform_device;
18 * @fb_delay: Slave specific feedback delay. 18 * @fb_delay: Slave specific feedback delay.
19 * Refer to FB_CLK_SEL register definition in SPI chapter. 19 * Refer to FB_CLK_SEL register definition in SPI chapter.
20 * @line: Custom 'identity' of the CS line. 20 * @line: Custom 'identity' of the CS line.
21 * @set_level: CS line control.
22 * 21 *
23 * This is per SPI-Slave Chipselect information. 22 * This is per SPI-Slave Chipselect information.
24 * Allocate and initialize one in machine init code and make the 23 * Allocate and initialize one in machine init code and make the
@@ -27,7 +26,6 @@ struct platform_device;
27struct s3c64xx_spi_csinfo { 26struct s3c64xx_spi_csinfo {
28 u8 fb_delay; 27 u8 fb_delay;
29 unsigned line; 28 unsigned line;
30 void (*set_level)(unsigned line_id, int lvl);
31}; 29};
32 30
33/** 31/**
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 0a9e43e635aa..e4182ea2f306 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -27,6 +27,7 @@
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/pm_runtime.h> 28#include <linux/pm_runtime.h>
29#include <linux/spi/spi.h> 29#include <linux/spi/spi.h>
30#include <linux/gpio.h>
30 31
31#include <mach/dma.h> 32#include <mach/dma.h>
32#include <plat/s3c64xx-spi.h> 33#include <plat/s3c64xx-spi.h>
@@ -411,14 +412,14 @@ static inline void enable_cs(struct s3c64xx_spi_driver_data *sdd,
411 if (sdd->tgl_spi != spi) { /* if last mssg on diff device */ 412 if (sdd->tgl_spi != spi) { /* if last mssg on diff device */
412 /* Deselect the last toggled device */ 413 /* Deselect the last toggled device */
413 cs = sdd->tgl_spi->controller_data; 414 cs = sdd->tgl_spi->controller_data;
414 cs->set_level(cs->line, 415 gpio_set_value(cs->line,
415 spi->mode & SPI_CS_HIGH ? 0 : 1); 416 spi->mode & SPI_CS_HIGH ? 0 : 1);
416 } 417 }
417 sdd->tgl_spi = NULL; 418 sdd->tgl_spi = NULL;
418 } 419 }
419 420
420 cs = spi->controller_data; 421 cs = spi->controller_data;
421 cs->set_level(cs->line, spi->mode & SPI_CS_HIGH ? 1 : 0); 422 gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 1 : 0);
422} 423}
423 424
424static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd, 425static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
@@ -504,7 +505,7 @@ static inline void disable_cs(struct s3c64xx_spi_driver_data *sdd,
504 if (sdd->tgl_spi == spi) 505 if (sdd->tgl_spi == spi)
505 sdd->tgl_spi = NULL; 506 sdd->tgl_spi = NULL;
506 507
507 cs->set_level(cs->line, spi->mode & SPI_CS_HIGH ? 0 : 1); 508 gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 0 : 1);
508} 509}
509 510
510static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) 511static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
@@ -833,11 +834,21 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
833 unsigned long flags; 834 unsigned long flags;
834 int err = 0; 835 int err = 0;
835 836
836 if (cs == NULL || cs->set_level == NULL) { 837 if (cs == NULL) {
837 dev_err(&spi->dev, "No CS for SPI(%d)\n", spi->chip_select); 838 dev_err(&spi->dev, "No CS for SPI(%d)\n", spi->chip_select);
838 return -ENODEV; 839 return -ENODEV;
839 } 840 }
840 841
842 if (!spi_get_ctldata(spi)) {
843 err = gpio_request(cs->line, dev_name(&spi->dev));
844 if (err) {
845 dev_err(&spi->dev, "request for slave select gpio "
846 "line [%d] failed\n", cs->line);
847 return -EBUSY;
848 }
849 spi_set_ctldata(spi, cs);
850 }
851
841 sdd = spi_master_get_devdata(spi->master); 852 sdd = spi_master_get_devdata(spi->master);
842 sci = sdd->cntrlr_info; 853 sci = sdd->cntrlr_info;
843 854
@@ -908,6 +919,15 @@ setup_exit:
908 return err; 919 return err;
909} 920}
910 921
922static void s3c64xx_spi_cleanup(struct spi_device *spi)
923{
924 struct s3c64xx_spi_csinfo *cs = spi_get_ctldata(spi);
925
926 if (cs)
927 gpio_free(cs->line);
928 spi_set_ctldata(spi, NULL);
929}
930
911static irqreturn_t s3c64xx_spi_irq(int irq, void *data) 931static irqreturn_t s3c64xx_spi_irq(int irq, void *data)
912{ 932{
913 struct s3c64xx_spi_driver_data *sdd = data; 933 struct s3c64xx_spi_driver_data *sdd = data;
@@ -1049,6 +1069,7 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
1049 1069
1050 master->bus_num = sdd->port_id; 1070 master->bus_num = sdd->port_id;
1051 master->setup = s3c64xx_spi_setup; 1071 master->setup = s3c64xx_spi_setup;
1072 master->cleanup = s3c64xx_spi_cleanup;
1052 master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer; 1073 master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer;
1053 master->transfer_one_message = s3c64xx_spi_transfer_one_message; 1074 master->transfer_one_message = s3c64xx_spi_transfer_one_message;
1054 master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer; 1075 master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer;