diff options
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/Kconfig | 2 | ||||
-rw-r--r-- | drivers/spi/spi-adi-v3.c | 5 | ||||
-rw-r--r-- | drivers/spi/spi-atmel.c | 22 | ||||
-rw-r--r-- | drivers/spi/spi-au1550.c | 6 | ||||
-rw-r--r-- | drivers/spi/spi-cadence.c | 37 | ||||
-rw-r--r-- | drivers/spi/spi-clps711x.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-davinci.c | 72 | ||||
-rw-r--r-- | drivers/spi/spi-dw-mmio.c | 19 | ||||
-rw-r--r-- | drivers/spi/spi-efm32.c | 8 | ||||
-rw-r--r-- | drivers/spi/spi-falcon.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-fsl-lib.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-fsl-spi.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-omap-100k.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-omap-uwire.c | 11 | ||||
-rw-r--r-- | drivers/spi/spi-omap2-mcspi.c | 14 | ||||
-rw-r--r-- | drivers/spi/spi-orion.c | 78 | ||||
-rw-r--r-- | drivers/spi/spi-pl022.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-pxa2xx-dma.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-pxa2xx.c | 8 | ||||
-rw-r--r-- | drivers/spi/spi-qup.c | 80 | ||||
-rw-r--r-- | drivers/spi/spi-rspi.c | 45 | ||||
-rw-r--r-- | drivers/spi/spi-s3c64xx.c | 54 | ||||
-rw-r--r-- | drivers/spi/spi-sh-hspi.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-sh-msiof.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-sh-sci.c | 4 | ||||
-rw-r--r-- | drivers/spi/spi-xilinx.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi.c | 12 |
27 files changed, 304 insertions, 193 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 79ace88030c4..20bd055ea2d1 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -396,7 +396,7 @@ config SPI_ROCKCHIP config SPI_RSPI tristate "Renesas RSPI/QSPI controller" - depends on (SUPERH && SH_DMAE_BASE) || ARCH_SHMOBILE + depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST help SPI driver for Renesas RSPI and QSPI blocks. diff --git a/drivers/spi/spi-adi-v3.c b/drivers/spi/spi-adi-v3.c index dcb2287c7f8a..19ea8fb78cc7 100644 --- a/drivers/spi/spi-adi-v3.c +++ b/drivers/spi/spi-adi-v3.c @@ -660,10 +660,9 @@ static int adi_spi_setup(struct spi_device *spi) struct adi_spi3_chip *chip_info = spi->controller_data; chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (!chip) { - dev_err(&spi->dev, "can not allocate chip data\n"); + if (!chip) return -ENOMEM; - } + if (chip_info) { if (chip_info->control & ~ctl_reg) { dev_err(&spi->dev, diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 92a6f0d93233..113c83f44b5c 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -597,21 +597,15 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master, goto err_exit; /* Send both scatterlists */ - rxdesc = rxchan->device->device_prep_slave_sg(rxchan, - &as->dma.sgrx, - 1, - DMA_FROM_DEVICE, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK, - NULL); + rxdesc = dmaengine_prep_slave_sg(rxchan, &as->dma.sgrx, 1, + DMA_FROM_DEVICE, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!rxdesc) goto err_dma; - txdesc = txchan->device->device_prep_slave_sg(txchan, - &as->dma.sgtx, - 1, - DMA_TO_DEVICE, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK, - NULL); + txdesc = dmaengine_prep_slave_sg(txchan, &as->dma.sgtx, 1, + DMA_TO_DEVICE, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!txdesc) goto err_dma; @@ -1018,7 +1012,7 @@ static int atmel_spi_setup(struct spi_device *spi) csr |= SPI_BF(DLYBCT, 0); /* chipselect must have been muxed as GPIO (e.g. in board setup) */ - npcs_pin = (unsigned int)spi->controller_data; + npcs_pin = (unsigned long)spi->controller_data; if (gpio_is_valid(spi->cs_gpio)) npcs_pin = spi->cs_gpio; @@ -1253,7 +1247,7 @@ msg_done: static void atmel_spi_cleanup(struct spi_device *spi) { struct atmel_spi_device *asd = spi->controller_state; - unsigned gpio = (unsigned) spi->controller_data; + unsigned gpio = (unsigned long) spi->controller_data; if (!asd) return; diff --git a/drivers/spi/spi-au1550.c b/drivers/spi/spi-au1550.c index 67375a11d4bd..fb61464348a1 100644 --- a/drivers/spi/spi-au1550.c +++ b/drivers/spi/spi-au1550.c @@ -925,8 +925,7 @@ err_no_txdma: iounmap((void __iomem *)hw->regs); err_ioremap: - release_resource(hw->ioarea); - kfree(hw->ioarea); + release_mem_region(r->start, sizeof(psc_spi_t)); err_no_iores: err_no_pdata: @@ -946,8 +945,7 @@ static int au1550_spi_remove(struct platform_device *pdev) spi_bitbang_stop(&hw->bitbang); free_irq(hw->irq, hw); iounmap((void __iomem *)hw->regs); - release_resource(hw->ioarea); - kfree(hw->ioarea); + release_mem_region(r->start, sizeof(psc_spi_t)); if (hw->usedma) { au1550_spi_dma_rxtmp_free(hw); diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c index bb758978465d..562ff83debd9 100644 --- a/drivers/spi/spi-cadence.c +++ b/drivers/spi/spi-cadence.c @@ -205,18 +205,30 @@ static void cdns_spi_chipselect(struct spi_device *spi, bool is_high) static void cdns_spi_config_clock_mode(struct spi_device *spi) { struct cdns_spi *xspi = spi_master_get_devdata(spi->master); - u32 ctrl_reg; + u32 ctrl_reg, new_ctrl_reg; - ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR_OFFSET); + new_ctrl_reg = ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR_OFFSET); /* Set the SPI clock phase and clock polarity */ - ctrl_reg &= ~(CDNS_SPI_CR_CPHA_MASK | CDNS_SPI_CR_CPOL_MASK); + new_ctrl_reg &= ~(CDNS_SPI_CR_CPHA_MASK | CDNS_SPI_CR_CPOL_MASK); if (spi->mode & SPI_CPHA) - ctrl_reg |= CDNS_SPI_CR_CPHA_MASK; + new_ctrl_reg |= CDNS_SPI_CR_CPHA_MASK; if (spi->mode & SPI_CPOL) - ctrl_reg |= CDNS_SPI_CR_CPOL_MASK; - - cdns_spi_write(xspi, CDNS_SPI_CR_OFFSET, ctrl_reg); + new_ctrl_reg |= CDNS_SPI_CR_CPOL_MASK; + + if (new_ctrl_reg != ctrl_reg) { + /* + * Just writing the CR register does not seem to apply the clock + * setting changes. This is problematic when changing the clock + * polarity as it will cause the SPI slave to see spurious clock + * transitions. To workaround the issue toggle the ER register. + */ + cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET, + CDNS_SPI_ER_DISABLE_MASK); + cdns_spi_write(xspi, CDNS_SPI_CR_OFFSET, new_ctrl_reg); + cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET, + CDNS_SPI_ER_ENABLE_MASK); + } } /** @@ -370,6 +382,12 @@ static irqreturn_t cdns_spi_irq(int irq, void *dev_id) return status; } +static int cdns_prepare_message(struct spi_master *master, + struct spi_message *msg) +{ + cdns_spi_config_clock_mode(msg->spi); + return 0; +} /** * cdns_transfer_one - Initiates the SPI transfer @@ -416,8 +434,6 @@ static int cdns_prepare_transfer_hardware(struct spi_master *master) { struct cdns_spi *xspi = spi_master_get_devdata(master); - cdns_spi_config_clock_mode(master->cur_msg->spi); - cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET, CDNS_SPI_ER_ENABLE_MASK); @@ -532,6 +548,7 @@ static int cdns_spi_probe(struct platform_device *pdev) xspi->is_decoded_cs = 0; master->prepare_transfer_hardware = cdns_prepare_transfer_hardware; + master->prepare_message = cdns_prepare_message; master->transfer_one = cdns_transfer_one; master->unprepare_transfer_hardware = cdns_unprepare_transfer_hardware; master->set_cs = cdns_spi_chipselect; @@ -647,7 +664,7 @@ static int __maybe_unused cdns_spi_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(cdns_spi_dev_pm_ops, cdns_spi_suspend, cdns_spi_resume); -static struct of_device_id cdns_spi_of_match[] = { +static const struct of_device_id cdns_spi_of_match[] = { { .compatible = "xlnx,zynq-spi-r1p6" }, { .compatible = "cdns,spi-r1p6" }, { /* end of table */ } diff --git a/drivers/spi/spi-clps711x.c b/drivers/spi/spi-clps711x.c index 4cd62f636547..ce538dad526b 100644 --- a/drivers/spi/spi-clps711x.c +++ b/drivers/spi/spi-clps711x.c @@ -184,8 +184,6 @@ static int spi_clps711x_probe(struct platform_device *pdev) } master->max_speed_hz = clk_get_rate(hw->spi_clk); - platform_set_drvdata(pdev, master); - hw->syscon = syscon_regmap_lookup_by_pdevname("syscon.3"); if (IS_ERR(hw->syscon)) { ret = PTR_ERR(hw->syscon); diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 50f750989258..276a3884fb3c 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -30,6 +30,7 @@ #include <linux/edma.h> #include <linux/of.h> #include <linux/of_device.h> +#include <linux/of_gpio.h> #include <linux/spi/spi.h> #include <linux/spi/spi_bitbang.h> #include <linux/slab.h> @@ -38,8 +39,6 @@ #define SPI_NO_RESOURCE ((resource_size_t)-1) -#define SPI_MAX_CHIPSELECT 2 - #define CS_DEFAULT 0xFF #define SPIFMT_PHASE_MASK BIT(16) @@ -142,7 +141,7 @@ struct davinci_spi { void (*get_rx)(u32 rx_data, struct davinci_spi *); u32 (*get_tx)(struct davinci_spi *); - u8 bytes_per_word[SPI_MAX_CHIPSELECT]; + u8 *bytes_per_word; }; static struct davinci_spi_config davinci_spi_default_cfg; @@ -213,13 +212,16 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value) u8 chip_sel = spi->chip_select; u16 spidat1 = CS_DEFAULT; bool gpio_chipsel = false; + int gpio; dspi = spi_master_get_devdata(spi->master); pdata = &dspi->pdata; - if (pdata->chip_sel && chip_sel < pdata->num_chipselect && - pdata->chip_sel[chip_sel] != SPI_INTERN_CS) + if (spi->cs_gpio >= 0) { + /* SPI core parse and update master->cs_gpio */ gpio_chipsel = true; + gpio = spi->cs_gpio; + } /* * Board specific chip select logic decides the polarity and cs @@ -227,9 +229,9 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value) */ if (gpio_chipsel) { if (value == BITBANG_CS_ACTIVE) - gpio_set_value(pdata->chip_sel[chip_sel], 0); + gpio_set_value(gpio, spi->mode & SPI_CS_HIGH); else - gpio_set_value(pdata->chip_sel[chip_sel], 1); + gpio_set_value(gpio, !(spi->mode & SPI_CS_HIGH)); } else { if (value == BITBANG_CS_ACTIVE) { spidat1 |= SPIDAT1_CSHOLD_MASK; @@ -392,17 +394,40 @@ static int davinci_spi_setup(struct spi_device *spi) int retval = 0; struct davinci_spi *dspi; struct davinci_spi_platform_data *pdata; + struct spi_master *master = spi->master; + struct device_node *np = spi->dev.of_node; + bool internal_cs = true; + unsigned long flags = GPIOF_DIR_OUT; dspi = spi_master_get_devdata(spi->master); pdata = &dspi->pdata; + flags |= (spi->mode & SPI_CS_HIGH) ? GPIOF_INIT_LOW : GPIOF_INIT_HIGH; + if (!(spi->mode & SPI_NO_CS)) { - if ((pdata->chip_sel == NULL) || - (pdata->chip_sel[spi->chip_select] == SPI_INTERN_CS)) - set_io_bits(dspi->base + SPIPC0, 1 << spi->chip_select); + if (np && (master->cs_gpios != NULL) && (spi->cs_gpio >= 0)) { + retval = gpio_request_one(spi->cs_gpio, + flags, dev_name(&spi->dev)); + internal_cs = false; + } else if (pdata->chip_sel && + spi->chip_select < pdata->num_chipselect && + pdata->chip_sel[spi->chip_select] != SPI_INTERN_CS) { + spi->cs_gpio = pdata->chip_sel[spi->chip_select]; + retval = gpio_request_one(spi->cs_gpio, + flags, dev_name(&spi->dev)); + internal_cs = false; + } + } + if (retval) { + dev_err(&spi->dev, "GPIO %d setup failed (%d)\n", + spi->cs_gpio, retval); + return retval; } + if (internal_cs) + set_io_bits(dspi->base + SPIPC0, 1 << spi->chip_select); + if (spi->mode & SPI_READY) set_io_bits(dspi->base + SPIPC0, SPIPC0_SPIENA_MASK); @@ -414,6 +439,12 @@ static int davinci_spi_setup(struct spi_device *spi) return retval; } +static void davinci_spi_cleanup(struct spi_device *spi) +{ + if (spi->cs_gpio >= 0) + gpio_free(spi->cs_gpio); +} + static int davinci_spi_check_error(struct davinci_spi *dspi, int int_status) { struct device *sdev = dspi->bitbang.master->dev.parent; @@ -812,6 +843,8 @@ static int spi_davinci_get_pdata(struct platform_device *pdev, /* * default num_cs is 1 and all chipsel are internal to the chip + * indicated by chip_sel being NULL or cs_gpios being NULL or + * set to -ENOENT. num-cs includes internal as well as gpios. * indicated by chip_sel being NULL. GPIO based CS is not * supported yet in DT bindings. */ @@ -850,7 +883,7 @@ static int davinci_spi_probe(struct platform_device *pdev) struct resource *r; resource_size_t dma_rx_chan = SPI_NO_RESOURCE; resource_size_t dma_tx_chan = SPI_NO_RESOURCE; - int i = 0, ret = 0; + int ret = 0; u32 spipc0; master = spi_alloc_master(&pdev->dev, sizeof(struct davinci_spi)); @@ -876,6 +909,14 @@ static int davinci_spi_probe(struct platform_device *pdev) /* pdata in dspi is now updated and point pdata to that */ pdata = &dspi->pdata; + dspi->bytes_per_word = devm_kzalloc(&pdev->dev, + sizeof(*dspi->bytes_per_word) * + pdata->num_chipselect, GFP_KERNEL); + if (dspi->bytes_per_word == NULL) { + ret = -ENOMEM; + goto free_master; + } + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (r == NULL) { ret = -ENOENT; @@ -915,6 +956,7 @@ static int davinci_spi_probe(struct platform_device *pdev) master->num_chipselect = pdata->num_chipselect; master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 16); master->setup = davinci_spi_setup; + master->cleanup = davinci_spi_cleanup; dspi->bitbang.chipselect = davinci_spi_chipselect; dspi->bitbang.setup_transfer = davinci_spi_setup_transfer; @@ -962,14 +1004,6 @@ static int davinci_spi_probe(struct platform_device *pdev) spipc0 = SPIPC0_DIFUN_MASK | SPIPC0_DOFUN_MASK | SPIPC0_CLKFUN_MASK; iowrite32(spipc0, dspi->base + SPIPC0); - /* initialize chip selects */ - if (pdata->chip_sel) { - for (i = 0; i < pdata->num_chipselect; i++) { - if (pdata->chip_sel[i] != SPI_INTERN_CS) - gpio_direction_output(pdata->chip_sel[i], 1); - } - } - if (pdata->intr_line) iowrite32(SPI_INTLVL_1, dspi->base + SPILVL); else diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c index a5cba14ac3d2..21ce0e36fa00 100644 --- a/drivers/spi/spi-dw-mmio.c +++ b/drivers/spi/spi-dw-mmio.c @@ -16,7 +16,9 @@ #include <linux/spi/spi.h> #include <linux/scatterlist.h> #include <linux/module.h> +#include <linux/of.h> #include <linux/of_gpio.h> +#include <linux/of_platform.h> #include "spi-dw.h" @@ -33,6 +35,7 @@ static int dw_spi_mmio_probe(struct platform_device *pdev) struct dw_spi *dws; struct resource *mem; int ret; + int num_cs; dwsmmio = devm_kzalloc(&pdev->dev, sizeof(struct dw_spi_mmio), GFP_KERNEL); @@ -68,9 +71,16 @@ static int dw_spi_mmio_probe(struct platform_device *pdev) return ret; dws->bus_num = pdev->id; - dws->num_cs = 4; + dws->max_freq = clk_get_rate(dwsmmio->clk); + num_cs = 4; + + if (pdev->dev.of_node) + of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs); + + dws->num_cs = num_cs; + if (pdev->dev.of_node) { int i; @@ -114,12 +124,19 @@ static int dw_spi_mmio_remove(struct platform_device *pdev) return 0; } +static const struct of_device_id dw_spi_mmio_of_match[] = { + { .compatible = "snps,dw-apb-ssi", }, + { /* end of table */} +}; +MODULE_DEVICE_TABLE(of, dw_spi_mmio_of_match); + static struct platform_driver dw_spi_mmio_driver = { .probe = dw_spi_mmio_probe, .remove = dw_spi_mmio_remove, .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, + .of_match_table = dw_spi_mmio_of_match, }, }; module_platform_driver(dw_spi_mmio_driver); diff --git a/drivers/spi/spi-efm32.c b/drivers/spi/spi-efm32.c index be44a3eeb5e8..6caeb1cac0f3 100644 --- a/drivers/spi/spi-efm32.c +++ b/drivers/spi/spi-efm32.c @@ -294,10 +294,16 @@ static void efm32_spi_probe_dt(struct platform_device *pdev, u32 location; int ret; - ret = of_property_read_u32(np, "efm32,location", &location); + ret = of_property_read_u32(np, "energymicro,location", &location); + + if (ret) + /* fall back to wrongly namespaced property */ + ret = of_property_read_u32(np, "efm32,location", &location); + if (ret) /* fall back to old and (wrongly) generic property "location" */ ret = of_property_read_u32(np, "location", &location); + if (!ret) { dev_dbg(&pdev->dev, "using location %u\n", location); } else { diff --git a/drivers/spi/spi-falcon.c b/drivers/spi/spi-falcon.c index ba441ad9a007..f73b3004d6d3 100644 --- a/drivers/spi/spi-falcon.c +++ b/drivers/spi/spi-falcon.c @@ -425,8 +425,6 @@ static int falcon_sflash_probe(struct platform_device *pdev) master->unprepare_transfer_hardware = falcon_sflash_unprepare_xfer; master->dev.of_node = pdev->dev.of_node; - platform_set_drvdata(pdev, priv); - ret = devm_spi_register_master(&pdev->dev, master); if (ret) spi_master_put(master); diff --git a/drivers/spi/spi-fsl-lib.c b/drivers/spi/spi-fsl-lib.c index 95212ea96c8d..e0b773fc29cb 100644 --- a/drivers/spi/spi-fsl-lib.c +++ b/drivers/spi/spi-fsl-lib.c @@ -196,7 +196,7 @@ int of_mpc8xxx_spi_probe(struct platform_device *ofdev) pinfo = devm_kzalloc(&ofdev->dev, sizeof(*pinfo), GFP_KERNEL); if (!pinfo) - return -ENOMEM; + return ret; pdata = &pinfo->pdata; dev->platform_data = pdata; diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index 98ccd231bf00..9452f6740997 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -58,7 +58,7 @@ static struct fsl_spi_match_data of_fsl_spi_grlib_config = { .type = TYPE_GRLIB, }; -static struct of_device_id of_fsl_spi_match[] = { +static const struct of_device_id of_fsl_spi_match[] = { { .compatible = "fsl,spi", .data = &of_fsl_spi_fsl_config, diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c index e7ffcded4e14..5e91858f6f01 100644 --- a/drivers/spi/spi-omap-100k.c +++ b/drivers/spi/spi-omap-100k.c @@ -420,8 +420,6 @@ static int omap1_spi100k_probe(struct platform_device *pdev) master->min_speed_hz = OMAP1_SPI100K_MAX_FREQ/(1<<16); master->max_speed_hz = OMAP1_SPI100K_MAX_FREQ; - platform_set_drvdata(pdev, master); - spi100k = spi_master_get_devdata(master); /* diff --git a/drivers/spi/spi-omap-uwire.c b/drivers/spi/spi-omap-uwire.c index 0f5a0aa3b871..8bca90a19dd1 100644 --- a/drivers/spi/spi-omap-uwire.c +++ b/drivers/spi/spi-omap-uwire.c @@ -41,14 +41,15 @@ #include <linux/err.h> #include <linux/clk.h> #include <linux/slab.h> +#include <linux/device.h> #include <linux/spi/spi.h> #include <linux/spi/spi_bitbang.h> #include <linux/module.h> +#include <linux/io.h> #include <asm/irq.h> #include <mach/hardware.h> -#include <asm/io.h> #include <asm/mach-types.h> #include <mach/mux.h> @@ -447,7 +448,6 @@ static void uwire_off(struct uwire_spi *uwire) { uwire_write_reg(UWIRE_SR3, 0); clk_disable(uwire->ck); - clk_put(uwire->ck); spi_master_put(uwire->bitbang.master); } @@ -463,7 +463,7 @@ static int uwire_probe(struct platform_device *pdev) uwire = spi_master_get_devdata(master); - uwire_base = ioremap(UWIRE_BASE_PHYS, UWIRE_IO_SIZE); + uwire_base = devm_ioremap(&pdev->dev, UWIRE_BASE_PHYS, UWIRE_IO_SIZE); if (!uwire_base) { dev_dbg(&pdev->dev, "can't ioremap UWIRE\n"); spi_master_put(master); @@ -472,12 +472,11 @@ static int uwire_probe(struct platform_device *pdev) platform_set_drvdata(pdev, uwire); - uwire->ck = clk_get(&pdev->dev, "fck"); + uwire->ck = devm_clk_get(&pdev->dev, "fck"); if (IS_ERR(uwire->ck)) { status = PTR_ERR(uwire->ck); dev_dbg(&pdev->dev, "no functional clock?\n"); spi_master_put(master); - iounmap(uwire_base); return status; } clk_enable(uwire->ck); @@ -507,7 +506,6 @@ static int uwire_probe(struct platform_device *pdev) status = spi_bitbang_start(&uwire->bitbang); if (status < 0) { uwire_off(uwire); - iounmap(uwire_base); } return status; } @@ -520,7 +518,6 @@ static int uwire_remove(struct platform_device *pdev) spi_bitbang_stop(&uwire->bitbang); uwire_off(uwire); - iounmap(uwire_base); return 0; } diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 4dc77df38864..68441fa448de 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -149,6 +149,7 @@ struct omap2_mcspi_cs { void __iomem *base; unsigned long phys; int word_len; + u16 mode; struct list_head node; /* Context save and restore shadow register */ u32 chconf0, chctrl0; @@ -926,6 +927,8 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, mcspi_write_chconf0(spi, l); + cs->mode = spi->mode; + dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n", speed_hz, (spi->mode & SPI_CPHA) ? "trailing" : "leading", @@ -998,6 +1001,7 @@ static int omap2_mcspi_setup(struct spi_device *spi) return -ENOMEM; cs->base = mcspi->base + spi->chip_select * 0x14; cs->phys = mcspi->phys + spi->chip_select * 0x14; + cs->mode = 0; cs->chconf0 = 0; cs->chctrl0 = 0; spi->controller_state = cs; @@ -1079,6 +1083,16 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) cs = spi->controller_state; cd = spi->controller_data; + /* + * The slave driver could have changed spi->mode in which case + * it will be different from cs->mode (the current hardware setup). + * If so, set par_override (even though its not a parity issue) so + * omap2_mcspi_setup_transfer will be called to configure the hardware + * with the correct mode on the first iteration of the loop below. + */ + if (spi->mode != cs->mode) + par_override = 1; + omap2_mcspi_set_enable(spi, 0); list_for_each_entry(t, &m->transfers, transfer_list) { if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) { diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index d018a4aac3a1..c4675fa8b645 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c @@ -16,6 +16,7 @@ #include <linux/io.h> #include <linux/spi/spi.h> #include <linux/module.h> +#include <linux/pm_runtime.h> #include <linux/of.h> #include <linux/clk.h> #include <linux/sizes.h> @@ -23,6 +24,9 @@ #define DRIVER_NAME "orion_spi" +/* Runtime PM autosuspend timeout: PM is fairly light on this driver */ +#define SPI_AUTOSUSPEND_TIMEOUT 200 + #define ORION_NUM_CHIPSELECTS 1 /* only one slave is supported*/ #define ORION_SPI_WAIT_RDY_MAX_LOOP 2000 /* in usec */ @@ -277,7 +281,6 @@ out: return xfer->len - count; } - static int orion_spi_transfer_one_message(struct spi_master *master, struct spi_message *m) { @@ -346,8 +349,6 @@ static int orion_spi_probe(struct platform_device *pdev) struct resource *r; unsigned long tclk_hz; int status = 0; - const u32 *iprop; - int size; master = spi_alloc_master(&pdev->dev, sizeof(*spi)); if (master == NULL) { @@ -358,10 +359,10 @@ static int orion_spi_probe(struct platform_device *pdev) if (pdev->id != -1) master->bus_num = pdev->id; if (pdev->dev.of_node) { - iprop = of_get_property(pdev->dev.of_node, "cell-index", - &size); - if (iprop && size == sizeof(*iprop)) - master->bus_num = *iprop; + u32 cell_index; + if (!of_property_read_u32(pdev->dev.of_node, "cell-index", + &cell_index)) + master->bus_num = cell_index; } /* we support only mode 0, and no options */ @@ -370,6 +371,7 @@ static int orion_spi_probe(struct platform_device *pdev) master->transfer_one_message = orion_spi_transfer_one_message; master->num_chipselect = ORION_NUM_CHIPSELECTS; master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16); + master->auto_runtime_pm = true; platform_set_drvdata(pdev, master); @@ -382,8 +384,10 @@ static int orion_spi_probe(struct platform_device *pdev) goto out; } - clk_prepare(spi->clk); - clk_enable(spi->clk); + status = clk_prepare_enable(spi->clk); + if (status) + goto out; + tclk_hz = clk_get_rate(spi->clk); master->max_speed_hz = DIV_ROUND_UP(tclk_hz, 4); master->min_speed_hz = DIV_ROUND_UP(tclk_hz, 30); @@ -395,16 +399,27 @@ static int orion_spi_probe(struct platform_device *pdev) goto out_rel_clk; } - if (orion_spi_reset(spi) < 0) - goto out_rel_clk; + pm_runtime_set_active(&pdev->dev); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT); + pm_runtime_enable(&pdev->dev); + + status = orion_spi_reset(spi); + if (status < 0) + goto out_rel_pm; + + pm_runtime_mark_last_busy(&pdev->dev); + pm_runtime_put_autosuspend(&pdev->dev); master->dev.of_node = pdev->dev.of_node; - status = devm_spi_register_master(&pdev->dev, master); + status = spi_register_master(master); if (status < 0) - goto out_rel_clk; + goto out_rel_pm; return status; +out_rel_pm: + pm_runtime_disable(&pdev->dev); out_rel_clk: clk_disable_unprepare(spi->clk); out: @@ -415,19 +430,45 @@ out: static int orion_spi_remove(struct platform_device *pdev) { - struct spi_master *master; - struct orion_spi *spi; - - master = platform_get_drvdata(pdev); - spi = spi_master_get_devdata(master); + struct spi_master *master = platform_get_drvdata(pdev); + struct orion_spi *spi = spi_master_get_devdata(master); + pm_runtime_get_sync(&pdev->dev); clk_disable_unprepare(spi->clk); + spi_unregister_master(master); + pm_runtime_disable(&pdev->dev); + return 0; } MODULE_ALIAS("platform:" DRIVER_NAME); +#ifdef CONFIG_PM_RUNTIME +static int orion_spi_runtime_suspend(struct device *dev) +{ + struct spi_master *master = dev_get_drvdata(dev); + struct orion_spi *spi = spi_master_get_devdata(master); + + clk_disable_unprepare(spi->clk); + return 0; +} + +static int orion_spi_runtime_resume(struct device *dev) +{ + struct spi_master *master = dev_get_drvdata(dev); + struct orion_spi *spi = spi_master_get_devdata(master); + + return clk_prepare_enable(spi->clk); +} +#endif + +static const struct dev_pm_ops orion_spi_pm_ops = { + SET_RUNTIME_PM_OPS(orion_spi_runtime_suspend, + orion_spi_runtime_resume, + NULL) +}; + static const struct of_device_id orion_spi_of_match_table[] = { { .compatible = "marvell,orion-spi", }, {} @@ -438,6 +479,7 @@ static struct platform_driver orion_spi_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, + .pm = &orion_spi_pm_ops, .of_match_table = of_match_ptr(orion_spi_of_match_table), }, .probe = orion_spi_probe, diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 66d2ae21e78e..1189cfd96477 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -1417,7 +1417,7 @@ static void do_interrupt_dma_transfer(struct pl022 *pl022) * Default is to enable all interrupts except RX - * this will be enabled once TX is complete */ - u32 irqflags = ENABLE_ALL_INTERRUPTS & ~SSP_IMSC_MASK_RXIM; + u32 irqflags = (u32)(ENABLE_ALL_INTERRUPTS & ~SSP_IMSC_MASK_RXIM); /* Enable target chip, if not already active */ if (!pl022->next_msg_cs_active) diff --git a/drivers/spi/spi-pxa2xx-dma.c b/drivers/spi/spi-pxa2xx-dma.c index f6759dc0153b..c41ff148a2b4 100644 --- a/drivers/spi/spi-pxa2xx-dma.c +++ b/drivers/spi/spi-pxa2xx-dma.c @@ -368,7 +368,7 @@ int pxa2xx_spi_set_dma_burst_and_threshold(struct chip_data *chip, * otherwise we use the default. Also we use the default FIFO * thresholds for now. */ - *burst_code = chip_info ? chip_info->dma_burst_size : 16; + *burst_code = chip_info ? chip_info->dma_burst_size : 1; *threshold = SSCR1_RxTresh(RX_THRESH_DFLT) | SSCR1_TxTresh(TX_THRESH_DFLT); diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index a98df7eeb42d..fe792106bdc5 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -118,6 +118,7 @@ static void lpss_ssp_setup(struct driver_data *drv_data) */ orig = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL); + /* Test SPI_CS_CONTROL_SW_MODE bit enabling */ value = orig | SPI_CS_CONTROL_SW_MODE; writel(value, drv_data->ioaddr + offset + SPI_CS_CONTROL); value = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL); @@ -126,10 +127,13 @@ static void lpss_ssp_setup(struct driver_data *drv_data) goto detection_done; } - value &= ~SPI_CS_CONTROL_SW_MODE; + orig = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL); + + /* Test SPI_CS_CONTROL_SW_MODE bit disabling */ + value = orig & ~SPI_CS_CONTROL_SW_MODE; writel(value, drv_data->ioaddr + offset + SPI_CS_CONTROL); value = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL); - if (value != orig) { + if (value != (orig & ~SPI_CS_CONTROL_SW_MODE)) { offset = 0x800; goto detection_done; } diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c index fc1de86d3c8a..9f83d2950748 100644 --- a/drivers/spi/spi-qup.c +++ b/drivers/spi/spi-qup.c @@ -142,6 +142,7 @@ struct spi_qup { int w_size; /* bytes per SPI word */ int tx_bytes; int rx_bytes; + int qup_v1; }; @@ -420,35 +421,12 @@ static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer) config |= QUP_CONFIG_SPI_MODE; writel_relaxed(config, controller->base + QUP_CONFIG); - writel_relaxed(0, controller->base + QUP_OPERATIONAL_MASK); + /* only write to OPERATIONAL_MASK when register is present */ + if (!controller->qup_v1) + writel_relaxed(0, controller->base + QUP_OPERATIONAL_MASK); return 0; } -static void spi_qup_set_cs(struct spi_device *spi, bool enable) -{ - struct spi_qup *controller = spi_master_get_devdata(spi->master); - - u32 iocontol, mask; - - iocontol = readl_relaxed(controller->base + SPI_IO_CONTROL); - - /* Disable auto CS toggle and use manual */ - iocontol &= ~SPI_IO_C_MX_CS_MODE; - iocontol |= SPI_IO_C_FORCE_CS; - - iocontol &= ~SPI_IO_C_CS_SELECT_MASK; - iocontol |= SPI_IO_C_CS_SELECT(spi->chip_select); - - mask = SPI_IO_C_CS_N_POLARITY_0 << spi->chip_select; - - if (enable) - iocontol |= mask; - else - iocontol &= ~mask; - - writel_relaxed(iocontol, controller->base + SPI_IO_CONTROL); -} - static int spi_qup_transfer_one(struct spi_master *master, struct spi_device *spi, struct spi_transfer *xfer) @@ -511,7 +489,7 @@ static int spi_qup_probe(struct platform_device *pdev) struct resource *res; struct device *dev; void __iomem *base; - u32 data, max_freq, iomode; + u32 max_freq, iomode; int ret, irq, size; dev = &pdev->dev; @@ -554,15 +532,6 @@ static int spi_qup_probe(struct platform_device *pdev) return ret; } - data = readl_relaxed(base + QUP_HW_VERSION); - - if (data < QUP_HW_VERSION_2_1_1) { - clk_disable_unprepare(cclk); - clk_disable_unprepare(iclk); - dev_err(dev, "v.%08x is not supported\n", data); - return -ENXIO; - } - master = spi_alloc_master(dev, sizeof(struct spi_qup)); if (!master) { clk_disable_unprepare(cclk); @@ -571,12 +540,16 @@ static int spi_qup_probe(struct platform_device *pdev) return -ENOMEM; } + /* use num-cs unless not present or out of range */ + if (of_property_read_u16(dev->of_node, "num-cs", + &master->num_chipselect) || + (master->num_chipselect > SPI_NUM_CHIPSELECTS)) + master->num_chipselect = SPI_NUM_CHIPSELECTS; + master->bus_num = pdev->id; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP; - master->num_chipselect = SPI_NUM_CHIPSELECTS; master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); master->max_speed_hz = max_freq; - master->set_cs = spi_qup_set_cs; master->transfer_one = spi_qup_transfer_one; master->dev.of_node = pdev->dev.of_node; master->auto_runtime_pm = true; @@ -591,6 +564,10 @@ static int spi_qup_probe(struct platform_device *pdev) controller->cclk = cclk; controller->irq = irq; + /* set v1 flag if device is version 1 */ + if (of_device_is_compatible(dev->of_node, "qcom,spi-qup-v1.1.1")) + controller->qup_v1 = 1; + spin_lock_init(&controller->lock); init_completion(&controller->done); @@ -614,8 +591,8 @@ static int spi_qup_probe(struct platform_device *pdev) size = QUP_IO_M_INPUT_FIFO_SIZE(iomode); controller->in_fifo_sz = controller->in_blk_sz * (2 << size); - dev_info(dev, "v.%08x IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n", - data, controller->in_blk_sz, controller->in_fifo_sz, + dev_info(dev, "IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n", + controller->in_blk_sz, controller->in_fifo_sz, controller->out_blk_sz, controller->out_fifo_sz); writel_relaxed(1, base + QUP_SW_RESET); @@ -628,10 +605,19 @@ static int spi_qup_probe(struct platform_device *pdev) writel_relaxed(0, base + QUP_OPERATIONAL); writel_relaxed(0, base + QUP_IO_M_MODES); - writel_relaxed(0, base + QUP_OPERATIONAL_MASK); + + if (!controller->qup_v1) + writel_relaxed(0, base + QUP_OPERATIONAL_MASK); + writel_relaxed(SPI_ERROR_CLK_UNDER_RUN | SPI_ERROR_CLK_OVER_RUN, base + SPI_ERROR_FLAGS_EN); + /* if earlier version of the QUP, disable INPUT_OVERRUN */ + if (controller->qup_v1) + writel_relaxed(QUP_ERROR_OUTPUT_OVER_RUN | + QUP_ERROR_INPUT_UNDER_RUN | QUP_ERROR_OUTPUT_UNDER_RUN, + base + QUP_ERROR_FLAGS_EN); + writel_relaxed(0, base + SPI_CONFIG); writel_relaxed(SPI_IO_C_NO_TRI_STATE, base + SPI_IO_CONTROL); @@ -640,16 +626,19 @@ static int spi_qup_probe(struct platform_device *pdev) if (ret) goto error; - ret = devm_spi_register_master(dev, master); - if (ret) - goto error; - pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC); pm_runtime_use_autosuspend(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); + + ret = devm_spi_register_master(dev, master); + if (ret) + goto disable_pm; + return 0; +disable_pm: + pm_runtime_disable(&pdev->dev); error: clk_disable_unprepare(cclk); clk_disable_unprepare(iclk); @@ -750,6 +739,7 @@ static int spi_qup_remove(struct platform_device *pdev) } static const struct of_device_id spi_qup_dt_match[] = { + { .compatible = "qcom,spi-qup-v1.1.1", }, { .compatible = "qcom,spi-qup-v2.1.1", }, { .compatible = "qcom,spi-qup-v2.2.1", }, { } diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 10112745bb17..c850dfdfa9e3 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -477,7 +477,7 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, tx->sgl, tx->nents, DMA_TO_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc_tx) - return -EIO; + goto no_dma; irq_mask |= SPCR_SPTIE; } @@ -486,7 +486,7 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, rx->sgl, rx->nents, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc_rx) - return -EIO; + goto no_dma; irq_mask |= SPCR_SPRIE; } @@ -540,6 +540,12 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, enable_irq(rspi->rx_irq); return ret; + +no_dma: + pr_warn_once("%s %s: DMA not available, falling back to PIO\n", + dev_driver_string(&rspi->master->dev), + dev_name(&rspi->master->dev)); + return -EAGAIN; } static void rspi_receive_init(const struct rspi_data *rspi) @@ -593,8 +599,10 @@ static int rspi_common_transfer(struct rspi_data *rspi, if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) { /* rx_buf can be NULL on RSPI on SH in TX-only Mode */ - return rspi_dma_transfer(rspi, &xfer->tx_sg, - xfer->rx_buf ? &xfer->rx_sg : NULL); + ret = rspi_dma_transfer(rspi, &xfer->tx_sg, + xfer->rx_buf ? &xfer->rx_sg : NULL); + if (ret != -EAGAIN) + return ret; } ret = rspi_pio_transfer(rspi, xfer->tx_buf, xfer->rx_buf, xfer->len); @@ -630,7 +638,6 @@ static int rspi_rz_transfer_one(struct spi_master *master, struct spi_transfer *xfer) { struct rspi_data *rspi = spi_master_get_devdata(master); - int ret; rspi_rz_receive_init(rspi); @@ -649,8 +656,11 @@ static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer) { int ret; - if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) - return rspi_dma_transfer(rspi, &xfer->tx_sg, NULL); + if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) { + ret = rspi_dma_transfer(rspi, &xfer->tx_sg, NULL); + if (ret != -EAGAIN) + return ret; + } ret = rspi_pio_transfer(rspi, xfer->tx_buf, NULL, xfer->len); if (ret < 0) @@ -664,8 +674,11 @@ static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer) static int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer) { - if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) - return rspi_dma_transfer(rspi, NULL, &xfer->rx_sg); + if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) { + int ret = rspi_dma_transfer(rspi, NULL, &xfer->rx_sg); + if (ret != -EAGAIN) + return ret; + } return rspi_pio_transfer(rspi, NULL, xfer->rx_buf, xfer->len); } @@ -927,19 +940,19 @@ static int rspi_request_dma(struct device *dev, struct spi_master *master, return 0; } -static void rspi_release_dma(struct rspi_data *rspi) +static void rspi_release_dma(struct spi_master *master) { - if (rspi->master->dma_tx) - dma_release_channel(rspi->master->dma_tx); - if (rspi->master->dma_rx) - dma_release_channel(rspi->master->dma_rx); + if (master->dma_tx) + dma_release_channel(master->dma_tx); + if (master->dma_rx) + dma_release_channel(master->dma_rx); } static int rspi_remove(struct platform_device *pdev) { struct rspi_data *rspi = platform_get_drvdata(pdev); - rspi_release_dma(rspi); + rspi_release_dma(rspi->master); pm_runtime_disable(&pdev->dev); return 0; @@ -1141,7 +1154,7 @@ static int rspi_probe(struct platform_device *pdev) return 0; error3: - rspi_release_dma(rspi); + rspi_release_dma(master); error2: pm_runtime_disable(&pdev->dev); error1: diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 75a56968b14c..1c36311935d7 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -197,7 +197,6 @@ struct s3c64xx_spi_driver_data { struct s3c64xx_spi_dma_data tx_dma; struct s3c64xx_spi_port_config *port_conf; unsigned int port_id; - bool cs_gpio; }; static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) @@ -754,10 +753,8 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata( { struct s3c64xx_spi_csinfo *cs; struct device_node *slave_np, *data_np = NULL; - struct s3c64xx_spi_driver_data *sdd; u32 fb_delay = 0; - sdd = spi_master_get_devdata(spi->master); slave_np = spi->dev.of_node; if (!slave_np) { dev_err(&spi->dev, "device node not found\n"); @@ -776,17 +773,6 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata( return ERR_PTR(-ENOMEM); } - /* The CS line is asserted/deasserted by the gpio pin */ - if (sdd->cs_gpio) - cs->line = of_get_named_gpio(data_np, "cs-gpio", 0); - - if (!gpio_is_valid(cs->line)) { - dev_err(&spi->dev, "chip select gpio is not specified or invalid\n"); - kfree(cs); - of_node_put(data_np); - return ERR_PTR(-EINVAL); - } - of_property_read_u32(data_np, "samsung,spi-feedback-delay", &fb_delay); cs->fb_delay = fb_delay; of_node_put(data_np); @@ -807,9 +793,16 @@ static int s3c64xx_spi_setup(struct spi_device *spi) int err; sdd = spi_master_get_devdata(spi->master); - if (!cs && spi->dev.of_node) { + if (spi->dev.of_node) { cs = s3c64xx_get_slave_ctrldata(spi); spi->controller_data = cs; + } else if (cs) { + /* On non-DT platforms the SPI core will set spi->cs_gpio + * to -ENOENT. The GPIO pin used to drive the chip select + * is defined by using platform data so spi->cs_gpio value + * has to be override to have the proper GPIO pin number. + */ + spi->cs_gpio = cs->line; } if (IS_ERR_OR_NULL(cs)) { @@ -818,18 +811,15 @@ static int s3c64xx_spi_setup(struct spi_device *spi) } if (!spi_get_ctldata(spi)) { - /* Request gpio only if cs line is asserted by gpio pins */ - if (sdd->cs_gpio) { - err = gpio_request_one(cs->line, GPIOF_OUT_INIT_HIGH, - dev_name(&spi->dev)); + if (gpio_is_valid(spi->cs_gpio)) { + err = gpio_request_one(spi->cs_gpio, GPIOF_OUT_INIT_HIGH, + dev_name(&spi->dev)); if (err) { dev_err(&spi->dev, "Failed to get /CS gpio [%d]: %d\n", - cs->line, err); + spi->cs_gpio, err); goto err_gpio_req; } - - spi->cs_gpio = cs->line; } spi_set_ctldata(spi, cs); @@ -884,7 +874,8 @@ setup_exit: /* setup() returns with device de-selected */ writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL); - gpio_free(cs->line); + if (gpio_is_valid(spi->cs_gpio)) + gpio_free(spi->cs_gpio); spi_set_ctldata(spi, NULL); err_gpio_req: @@ -897,14 +888,21 @@ err_gpio_req: static void s3c64xx_spi_cleanup(struct spi_device *spi) { struct s3c64xx_spi_csinfo *cs = spi_get_ctldata(spi); - struct s3c64xx_spi_driver_data *sdd; - sdd = spi_master_get_devdata(spi->master); - if (spi->cs_gpio) { + if (gpio_is_valid(spi->cs_gpio)) { gpio_free(spi->cs_gpio); if (spi->dev.of_node) kfree(cs); + else { + /* On non-DT platforms, the SPI core sets + * spi->cs_gpio to -ENOENT and .setup() + * overrides it with the GPIO pin value + * passed using platform data. + */ + spi->cs_gpio = -ENOENT; + } } + spi_set_ctldata(spi, NULL); } @@ -1075,11 +1073,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) sdd->cntrlr_info = sci; sdd->pdev = pdev; sdd->sfr_start = mem_res->start; - sdd->cs_gpio = true; if (pdev->dev.of_node) { - if (!of_find_property(pdev->dev.of_node, "cs-gpio", NULL)) - sdd->cs_gpio = false; - ret = of_alias_get_id(pdev->dev.of_node, "spi"); if (ret < 0) { dev_err(&pdev->dev, "failed to get alias id, errno %d\n", diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c index c8e795ef2e13..94b5faed21e2 100644 --- a/drivers/spi/spi-sh-hspi.c +++ b/drivers/spi/spi-sh-hspi.c @@ -304,7 +304,7 @@ static int hspi_remove(struct platform_device *pdev) return 0; } -static struct of_device_id hspi_of_match[] = { +static const struct of_device_id hspi_of_match[] = { { .compatible = "renesas,hspi", }, { /* sentinel */ } }; diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 45b09142afe2..83c43707f093 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -680,8 +680,6 @@ static int sh_msiof_spi_probe(struct platform_device *pdev) p = spi_master_get_devdata(master); - platform_set_drvdata(pdev, p); - of_id = of_match_device(sh_msiof_match, &pdev->dev); if (of_id) { p->chipdata = of_id->data; diff --git a/drivers/spi/spi-sh-sci.c b/drivers/spi/spi-sh-sci.c index 1f56ef651d1a..b83dd733684c 100644 --- a/drivers/spi/spi-sh-sci.c +++ b/drivers/spi/spi-sh-sci.c @@ -175,9 +175,9 @@ static int sh_sci_spi_remove(struct platform_device *dev) { struct sh_sci_spi *sp = platform_get_drvdata(dev); - iounmap(sp->membase); - setbits(sp, PIN_INIT, 0); spi_bitbang_stop(&sp->bitbang); + setbits(sp, PIN_INIT, 0); + iounmap(sp->membase); spi_master_put(sp->bitbang.master); return 0; } diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c index a3b0b9944bf0..4d8efb16573d 100644 --- a/drivers/spi/spi-xilinx.c +++ b/drivers/spi/spi-xilinx.c @@ -369,7 +369,7 @@ static int xilinx_spi_probe(struct platform_device *pdev) goto put_master; } - master->bus_num = pdev->dev.id; + master->bus_num = pdev->id; master->num_chipselect = num_cs; master->dev.of_node = pdev->dev.of_node; diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index d4f9670b51bc..e6f076d5ffd5 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -345,14 +345,12 @@ static DEFINE_MUTEX(board_lock); struct spi_device *spi_alloc_device(struct spi_master *master) { struct spi_device *spi; - struct device *dev = master->dev.parent; if (!spi_master_get(master)) return NULL; spi = kzalloc(sizeof(*spi), GFP_KERNEL); if (!spi) { - dev_err(dev, "cannot alloc spi_device\n"); spi_master_put(master); return NULL; } @@ -619,6 +617,8 @@ static int spi_map_buf(struct spi_master *master, struct device *dev, } ret = dma_map_sg(dev, sgt->sgl, sgt->nents, dir); + if (!ret) + ret = -ENOMEM; if (ret < 0) { sg_free_table(sgt); return ret; @@ -647,8 +647,8 @@ static int __spi_map_msg(struct spi_master *master, struct spi_message *msg) if (!master->can_dma) return 0; - tx_dev = &master->dma_tx->dev->device; - rx_dev = &master->dma_rx->dev->device; + tx_dev = master->dma_tx->device->dev; + rx_dev = master->dma_rx->device->dev; list_for_each_entry(xfer, &msg->transfers, transfer_list) { if (!master->can_dma(master, msg->spi, xfer)) @@ -687,8 +687,8 @@ static int spi_unmap_msg(struct spi_master *master, struct spi_message *msg) if (!master->cur_msg_mapped || !master->can_dma) return 0; - tx_dev = &master->dma_tx->dev->device; - rx_dev = &master->dma_rx->dev->device; + tx_dev = master->dma_tx->device->dev; + rx_dev = master->dma_rx->device->dev; list_for_each_entry(xfer, &msg->transfers, transfer_list) { if (!master->can_dma(master, msg->spi, xfer)) |