diff options
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi-s3c64xx.c | 31 |
1 files changed, 26 insertions, 5 deletions
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 @@ #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/spi/spi.h> +#include <linux/gpio.h> #include <mach/dma.h> #include <plat/s3c64xx-spi.h> @@ -411,14 +412,14 @@ static inline void enable_cs(struct s3c64xx_spi_driver_data *sdd, if (sdd->tgl_spi != spi) { /* if last mssg on diff device */ /* Deselect the last toggled device */ cs = sdd->tgl_spi->controller_data; - cs->set_level(cs->line, - spi->mode & SPI_CS_HIGH ? 0 : 1); + gpio_set_value(cs->line, + spi->mode & SPI_CS_HIGH ? 0 : 1); } sdd->tgl_spi = NULL; } cs = spi->controller_data; - cs->set_level(cs->line, spi->mode & SPI_CS_HIGH ? 1 : 0); + gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 1 : 0); } static 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, if (sdd->tgl_spi == spi) sdd->tgl_spi = NULL; - cs->set_level(cs->line, spi->mode & SPI_CS_HIGH ? 0 : 1); + gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 0 : 1); } static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) @@ -833,11 +834,21 @@ static int s3c64xx_spi_setup(struct spi_device *spi) unsigned long flags; int err = 0; - if (cs == NULL || cs->set_level == NULL) { + if (cs == NULL) { dev_err(&spi->dev, "No CS for SPI(%d)\n", spi->chip_select); return -ENODEV; } + if (!spi_get_ctldata(spi)) { + err = gpio_request(cs->line, dev_name(&spi->dev)); + if (err) { + dev_err(&spi->dev, "request for slave select gpio " + "line [%d] failed\n", cs->line); + return -EBUSY; + } + spi_set_ctldata(spi, cs); + } + sdd = spi_master_get_devdata(spi->master); sci = sdd->cntrlr_info; @@ -908,6 +919,15 @@ setup_exit: return err; } +static void s3c64xx_spi_cleanup(struct spi_device *spi) +{ + struct s3c64xx_spi_csinfo *cs = spi_get_ctldata(spi); + + if (cs) + gpio_free(cs->line); + spi_set_ctldata(spi, NULL); +} + static irqreturn_t s3c64xx_spi_irq(int irq, void *data) { struct s3c64xx_spi_driver_data *sdd = data; @@ -1049,6 +1069,7 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) master->bus_num = sdd->port_id; master->setup = s3c64xx_spi_setup; + master->cleanup = s3c64xx_spi_cleanup; master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer; master->transfer_one_message = s3c64xx_spi_transfer_one_message; master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer; |