diff --git a/Documentation/devicetree/bindings/spi/spi-davinci.txt b/Documentation/devicetree/bindings/spi/spi-davinci.txt index 6d0ac8d0ad9b..f80887bca0d6 100644 --- a/Documentation/devicetree/bindings/spi/spi-davinci.txt +++ b/Documentation/devicetree/bindings/spi/spi-davinci.txt @@ -8,7 +8,8 @@ Required properties: - "ti,dm6441-spi" for SPI used similar to that on DM644x SoC family - "ti,da830-spi" for SPI used similar to that on DA8xx SoC family - reg: Offset and length of SPI controller register space -- num-cs: Number of chip selects +- num-cs: Number of chip selects. This includes internal as well as + GPIO chip selects. - ti,davinci-spi-intr-line: interrupt line used to connect the SPI IP to the interrupt controller within the SoC. Possible values are 0 and 1. Manual says one of the two possible interrupt @@ -17,6 +18,12 @@ Required properties: - interrupts: interrupt number mapped to CPU. - clocks: spi clk phandle +Optional: +- cs-gpios: gpio chip selects + For example to have 3 internal CS and 2 GPIO CS, user could define + cs-gpios = <0>, <0>, <0>, <&gpio1 30 0>, <&gpio1 31 0>; + where first three are internal CS and last two are GPIO CS. + Example of a NOR flash slave device (n25q032) connected to DaVinci SPI controller device over the SPI bus. 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-cadence.c b/drivers/spi/spi-cadence.c index 3312eccb18c1..562ff83debd9 100644 --- a/drivers/spi/spi-cadence.c +++ b/drivers/spi/spi-cadence.c @@ -664,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 #include #include +#include #include #include #include @@ -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; - 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); + flags |= (spi->mode & SPI_CS_HIGH) ? GPIOF_INIT_LOW : GPIOF_INIT_HIGH; + if (!(spi->mode & SPI_NO_CS)) { + 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-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-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-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;