diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 74fddcd3282b..f53f0c5e63da 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -23,8 +23,7 @@ #include #include -#include -#include +#include #include #include @@ -312,7 +311,7 @@ struct atmel_spi { /* Controller-specific per-slave state */ struct atmel_spi_device { - unsigned int npcs_pin; + struct gpio_desc *npcs_pin; u32 csr; }; @@ -355,7 +354,6 @@ static bool atmel_spi_is_v2(struct atmel_spi *as) static void cs_activate(struct atmel_spi *as, struct spi_device *spi) { struct atmel_spi_device *asd = spi->controller_state; - unsigned active = spi->mode & SPI_CS_HIGH; u32 mr; if (atmel_spi_is_v2(as)) { @@ -379,7 +377,7 @@ static void cs_activate(struct atmel_spi *as, struct spi_device *spi) mr = spi_readl(as, MR); if (as->use_cs_gpios) - gpio_set_value(asd->npcs_pin, active); + gpiod_set_value(asd->npcs_pin, 1); } else { u32 cpol = (spi->mode & SPI_CPOL) ? SPI_BIT(CPOL) : 0; int i; @@ -396,19 +394,16 @@ static void cs_activate(struct atmel_spi *as, struct spi_device *spi) mr = spi_readl(as, MR); mr = SPI_BFINS(PCS, ~(1 << spi->chip_select), mr); if (as->use_cs_gpios && spi->chip_select != 0) - gpio_set_value(asd->npcs_pin, active); + gpiod_set_value(asd->npcs_pin, 1); spi_writel(as, MR, mr); } - dev_dbg(&spi->dev, "activate %u%s, mr %08x\n", - asd->npcs_pin, active ? " (high)" : "", - mr); + dev_dbg(&spi->dev, "activate NPCS, mr %08x\n", mr); } static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi) { struct atmel_spi_device *asd = spi->controller_state; - unsigned active = spi->mode & SPI_CS_HIGH; u32 mr; /* only deactivate *this* device; sometimes transfers to @@ -420,14 +415,12 @@ static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi) spi_writel(as, MR, mr); } - dev_dbg(&spi->dev, "DEactivate %u%s, mr %08x\n", - asd->npcs_pin, active ? " (low)" : "", - mr); + dev_dbg(&spi->dev, "DEactivate NPCS, mr %08x\n", mr); if (!as->use_cs_gpios) spi_writel(as, CR, SPI_BIT(LASTXFER)); else if (atmel_spi_is_v2(as) || spi->chip_select != 0) - gpio_set_value(asd->npcs_pin, !active); + gpiod_set_value(asd->npcs_pin, 0); } static void atmel_spi_lock(struct atmel_spi *as) __acquires(&as->lock) @@ -1188,7 +1181,6 @@ static int atmel_spi_setup(struct spi_device *spi) struct atmel_spi_device *asd; u32 csr; unsigned int bits = spi->bits_per_word; - unsigned int npcs_pin; as = spi_master_get_devdata(spi->master); @@ -1217,25 +1209,27 @@ static int atmel_spi_setup(struct spi_device *spi) csr |= SPI_BF(DLYBS, 0); csr |= SPI_BF(DLYBCT, 0); - /* chipselect must have been muxed as GPIO (e.g. in board setup) */ - npcs_pin = (unsigned long)spi->controller_data; - - if (!as->use_cs_gpios) - npcs_pin = spi->chip_select; - else if (gpio_is_valid(spi->cs_gpio)) - npcs_pin = spi->cs_gpio; - asd = spi->controller_state; if (!asd) { asd = kzalloc(sizeof(struct atmel_spi_device), GFP_KERNEL); if (!asd) return -ENOMEM; - if (as->use_cs_gpios) - gpio_direction_output(npcs_pin, - !(spi->mode & SPI_CS_HIGH)); + /* + * If use_cs_gpios is true this means that we have "cs-gpios" + * defined in the device tree node so we should have + * gotten the GPIO lines from the device tree inside the + * SPI core. Warn if this is not the case but continue since + * CS GPIOs are after all optional. + */ + if (as->use_cs_gpios) { + if (!spi->cs_gpiod) { + dev_err(&spi->dev, + "host claims to use CS GPIOs but no CS found in DT by the SPI core\n"); + } + asd->npcs_pin = spi->cs_gpiod; + } - asd->npcs_pin = npcs_pin; spi->controller_state = asd; } @@ -1473,41 +1467,6 @@ static void atmel_get_caps(struct atmel_spi *as) as->caps.has_pdc_support = version < 0x212; } -/*-------------------------------------------------------------------------*/ -static int atmel_spi_gpio_cs(struct platform_device *pdev) -{ - struct spi_master *master = platform_get_drvdata(pdev); - struct atmel_spi *as = spi_master_get_devdata(master); - struct device_node *np = master->dev.of_node; - int i; - int ret = 0; - int nb = 0; - - if (!as->use_cs_gpios) - return 0; - - if (!np) - return 0; - - nb = of_gpio_named_count(np, "cs-gpios"); - for (i = 0; i < nb; i++) { - int cs_gpio = of_get_named_gpio(pdev->dev.of_node, - "cs-gpios", i); - - if (cs_gpio == -EPROBE_DEFER) - return cs_gpio; - - if (gpio_is_valid(cs_gpio)) { - ret = devm_gpio_request(&pdev->dev, cs_gpio, - dev_name(&pdev->dev)); - if (ret) - return ret; - } - } - - return 0; -} - static void atmel_spi_init(struct atmel_spi *as) { spi_writel(as, CR, SPI_BIT(SWRST)); @@ -1560,6 +1519,7 @@ static int atmel_spi_probe(struct platform_device *pdev) goto out_free; /* the spi->mode bits understood by this driver: */ + master->use_gpio_descriptors = true; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 16); master->dev.of_node = pdev->dev.of_node; @@ -1592,6 +1552,11 @@ static int atmel_spi_probe(struct platform_device *pdev) atmel_get_caps(as); + /* + * If there are chip selects in the device tree, those will be + * discovered by the SPI core when registering the SPI master + * and assigned to each SPI device. + */ as->use_cs_gpios = true; if (atmel_spi_is_v2(as) && pdev->dev.of_node && @@ -1600,10 +1565,6 @@ static int atmel_spi_probe(struct platform_device *pdev) master->num_chipselect = 4; } - ret = atmel_spi_gpio_cs(pdev); - if (ret) - goto out_unmap_regs; - as->use_dma = false; as->use_pdc = false; if (as->caps.has_dma_support) {