Merge tag 'spi-fix-v5.5-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 17 Dec 2019 21:06:31 +0000 (13:06 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 17 Dec 2019 21:06:31 +0000 (13:06 -0800)
Pull spi fixes from Mark Brown:
 "A relatively large set of fixes here, the biggest part of it is for
  fallout from the GPIO descriptor rework that affected several of the
  devices with usable native chip select support. There's also some new
  PCI IDs for Intel Jasper Lake devices.

  The conversion to platform_get_irq() in the fsl driver is an
  incremental fix for build errors introduced on SPARC by the earlier
  fix for error handling in probe in that driver"

* tag 'spi-fix-v5.5-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi: fsl: use platform_get_irq() instead of of_irq_to_resource()
  spi: nxp-fspi: Ensure width is respected in spi-mem operations
  spi: spi-ti-qspi: Fix a bug when accessing non default CS
  spi: fsl: don't map irq during probe
  spi: spi-cavium-thunderx: Add missing pci_release_regions()
  spi: sprd: Fix the incorrect SPI register
  gpiolib: of: Make of_gpio_spi_cs_get_count static
  spi: fsl: Handle the single hardwired chipselect case
  gpio: Handle counting of Freescale chipselects
  spi: fsl: Fix GPIO descriptor support
  spi: dw: Correct handling of native chipselect
  spi: cadence: Correct handling of native chipselect
  spi: pxa2xx: Add support for Intel Jasper Lake

drivers/gpio/gpiolib-of.c
drivers/spi/spi-cadence.c
drivers/spi/spi-cavium-thunderx.c
drivers/spi/spi-dw.c
drivers/spi/spi-fsl-spi.c
drivers/spi/spi-nxp-fspi.c
drivers/spi/spi-pxa2xx.c
drivers/spi/spi-sprd.c
drivers/spi/spi-ti-qspi.c

index dc27b1a88e9343a8a029832cef5c6095a7be6238..b696e4598a240ea4237bacf42d90b22424320616 100644 (file)
 #include "gpiolib.h"
 #include "gpiolib-of.h"
 
+/**
+ * of_gpio_spi_cs_get_count() - special GPIO counting for SPI
+ * Some elder GPIO controllers need special quirks. Currently we handle
+ * the Freescale GPIO controller with bindings that doesn't use the
+ * established "cs-gpios" for chip selects but instead rely on
+ * "gpios" for the chip select lines. If we detect this, we redirect
+ * the counting of "cs-gpios" to count "gpios" transparent to the
+ * driver.
+ */
+static int of_gpio_spi_cs_get_count(struct device *dev, const char *con_id)
+{
+       struct device_node *np = dev->of_node;
+
+       if (!IS_ENABLED(CONFIG_SPI_MASTER))
+               return 0;
+       if (!con_id || strcmp(con_id, "cs"))
+               return 0;
+       if (!of_device_is_compatible(np, "fsl,spi") &&
+           !of_device_is_compatible(np, "aeroflexgaisler,spictrl"))
+               return 0;
+       return of_gpio_named_count(np, "gpios");
+}
+
 /*
  * This is used by external users of of_gpio_count() from <linux/of_gpio.h>
  *
@@ -35,6 +58,10 @@ int of_gpio_get_count(struct device *dev, const char *con_id)
        char propname[32];
        unsigned int i;
 
+       ret = of_gpio_spi_cs_get_count(dev, con_id);
+       if (ret > 0)
+               return ret;
+
        for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) {
                if (con_id)
                        snprintf(propname, sizeof(propname), "%s-%s",
index c36587b42e951eab806d4e9a12715db175619a8a..82a0ee09cbe148cf2407db213bae2cfec55312c1 100644 (file)
@@ -168,16 +168,16 @@ static void cdns_spi_init_hw(struct cdns_spi *xspi)
 /**
  * cdns_spi_chipselect - Select or deselect the chip select line
  * @spi:       Pointer to the spi_device structure
- * @enable:    Select (1) or deselect (0) the chip select line
+ * @is_high:   Select(0) or deselect (1) the chip select line
  */
-static void cdns_spi_chipselect(struct spi_device *spi, bool enable)
+static void cdns_spi_chipselect(struct spi_device *spi, bool is_high)
 {
        struct cdns_spi *xspi = spi_master_get_devdata(spi->master);
        u32 ctrl_reg;
 
        ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR);
 
-       if (!enable) {
+       if (is_high) {
                /* Deselect the slave */
                ctrl_reg |= CDNS_SPI_CR_SSCTRL;
        } else {
index d12e149f1a419ed72ef65dd788d409eb68c00cbf..fd6b9caffaf0c41ca36434a7ae90538b319560bd 100644 (file)
@@ -82,6 +82,7 @@ static int thunderx_spi_probe(struct pci_dev *pdev,
 
 error:
        clk_disable_unprepare(p->clk);
+       pci_release_regions(pdev);
        spi_master_put(master);
        return ret;
 }
@@ -96,6 +97,7 @@ static void thunderx_spi_remove(struct pci_dev *pdev)
                return;
 
        clk_disable_unprepare(p->clk);
+       pci_release_regions(pdev);
        /* Put everything in a known state. */
        writeq(0, p->register_base + OCTEON_SPI_CFG(p));
 }
index a92aa5cd4fbe8b1fd4433652e14ac9cef446af92..76d6b94a7597ff9b0686f3ac81c989f1fac711d2 100644 (file)
@@ -129,10 +129,11 @@ void dw_spi_set_cs(struct spi_device *spi, bool enable)
        struct dw_spi *dws = spi_controller_get_devdata(spi->controller);
        struct chip_data *chip = spi_get_ctldata(spi);
 
+       /* Chip select logic is inverted from spi_set_cs() */
        if (chip && chip->cs_control)
-               chip->cs_control(enable);
+               chip->cs_control(!enable);
 
-       if (enable)
+       if (!enable)
                dw_writel(dws, DW_SPI_SER, BIT(spi->chip_select));
        else if (dws->cs_override)
                dw_writel(dws, DW_SPI_SER, 0);
index 114801a32371c8f734362d3b550890d288943027..fb4159ad6bf6a8e5729f79baf27f0f68078eeff5 100644 (file)
@@ -611,6 +611,7 @@ static struct spi_master * fsl_spi_probe(struct device *dev,
        master->setup = fsl_spi_setup;
        master->cleanup = fsl_spi_cleanup;
        master->transfer_one_message = fsl_spi_do_one_msg;
+       master->use_gpio_descriptors = true;
 
        mpc8xxx_spi = spi_master_get_devdata(master);
        mpc8xxx_spi->max_bits_per_word = 32;
@@ -727,17 +728,27 @@ static int of_fsl_spi_probe(struct platform_device *ofdev)
                        }
                }
 #endif
-
-               pdata->cs_control = fsl_spi_cs_control;
+               /*
+                * Handle the case where we have one hardwired (always selected)
+                * device on the first "chipselect". Else we let the core code
+                * handle any GPIOs or native chip selects and assign the
+                * appropriate callback for dealing with the CS lines. This isn't
+                * supported on the GRLIB variant.
+                */
+               ret = gpiod_count(dev, "cs");
+               if (ret <= 0)
+                       pdata->max_chipselect = 1;
+               else
+                       pdata->cs_control = fsl_spi_cs_control;
        }
 
        ret = of_address_to_resource(np, 0, &mem);
        if (ret)
                goto err;
 
-       irq = irq_of_parse_and_map(np, 0);
-       if (!irq) {
-               ret = -EINVAL;
+       irq = platform_get_irq(ofdev, 0);
+       if (irq < 0) {
+               ret = irq;
                goto err;
        }
 
@@ -750,7 +761,6 @@ static int of_fsl_spi_probe(struct platform_device *ofdev)
        return 0;
 
 err:
-       irq_dispose_mapping(irq);
        return ret;
 }
 
index c36bb1bb464e60de23c466d700cff0c3ef1f02c6..8c5084a3a617b1a6839959a90f5691a3a2e45c41 100644 (file)
@@ -439,7 +439,7 @@ static bool nxp_fspi_supports_op(struct spi_mem *mem,
            op->data.nbytes > f->devtype_data->txfifo)
                return false;
 
-       return true;
+       return spi_mem_default_supports_op(mem, op);
 }
 
 /* Instead of busy looping invoke readl_poll_timeout functionality. */
index 16b6b2ad4e7c0aec2c3d58f6aa9ddac6f6d9dd32..9071333ebdd86fe290f441c21b4a1a37c7e40ff5 100644 (file)
@@ -1443,6 +1443,10 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = {
        { PCI_VDEVICE(INTEL, 0x4b2a), LPSS_BXT_SSP },
        { PCI_VDEVICE(INTEL, 0x4b2b), LPSS_BXT_SSP },
        { PCI_VDEVICE(INTEL, 0x4b37), LPSS_BXT_SSP },
+       /* JSL */
+       { PCI_VDEVICE(INTEL, 0x4daa), LPSS_CNL_SSP },
+       { PCI_VDEVICE(INTEL, 0x4dab), LPSS_CNL_SSP },
+       { PCI_VDEVICE(INTEL, 0x4dfb), LPSS_CNL_SSP },
        /* APL */
        { PCI_VDEVICE(INTEL, 0x5ac2), LPSS_BXT_SSP },
        { PCI_VDEVICE(INTEL, 0x5ac4), LPSS_BXT_SSP },
index 2ee1feb416812faf45b50b0e3e74dd9f1dde6891..6678f1cbc566078a7681a4aa047bc01a80cc4456 100644 (file)
@@ -678,7 +678,7 @@ static int sprd_spi_init_hw(struct sprd_spi *ss, struct spi_transfer *t)
        if (d->unit != SPI_DELAY_UNIT_SCK)
                return -EINVAL;
 
-       val = readl_relaxed(ss->base + SPRD_SPI_CTL7);
+       val = readl_relaxed(ss->base + SPRD_SPI_CTL0);
        val &= ~(SPRD_SPI_SCK_REV | SPRD_SPI_NG_TX | SPRD_SPI_NG_RX);
        /* Set default chip selection, clock phase and clock polarity */
        val |= ss->hw_mode & SPI_CPHA ? SPRD_SPI_NG_RX : SPRD_SPI_NG_TX;
index 3cb65371ae3bd45873f573fef70de052dfca373b..66dcb61285392523d9b8c08739026fb9fbcc5ee9 100644 (file)
@@ -62,6 +62,7 @@ struct ti_qspi {
        u32 dc;
 
        bool mmap_enabled;
+       int current_cs;
 };
 
 #define QSPI_PID                       (0x0)
@@ -487,6 +488,7 @@ static void ti_qspi_enable_memory_map(struct spi_device *spi)
                                   MEM_CS_EN(spi->chip_select));
        }
        qspi->mmap_enabled = true;
+       qspi->current_cs = spi->chip_select;
 }
 
 static void ti_qspi_disable_memory_map(struct spi_device *spi)
@@ -498,6 +500,7 @@ static void ti_qspi_disable_memory_map(struct spi_device *spi)
                regmap_update_bits(qspi->ctrl_base, qspi->ctrl_reg,
                                   MEM_CS_MASK, 0);
        qspi->mmap_enabled = false;
+       qspi->current_cs = -1;
 }
 
 static void ti_qspi_setup_mmap_read(struct spi_device *spi, u8 opcode,
@@ -543,7 +546,7 @@ static int ti_qspi_exec_mem_op(struct spi_mem *mem,
 
        mutex_lock(&qspi->list_lock);
 
-       if (!qspi->mmap_enabled)
+       if (!qspi->mmap_enabled || qspi->current_cs != mem->spi->chip_select)
                ti_qspi_enable_memory_map(mem->spi);
        ti_qspi_setup_mmap_read(mem->spi, op->cmd.opcode, op->data.buswidth,
                                op->addr.nbytes, op->dummy.nbytes);
@@ -799,6 +802,7 @@ no_dma:
                }
        }
        qspi->mmap_enabled = false;
+       qspi->current_cs = -1;
 
        ret = devm_spi_register_master(&pdev->dev, master);
        if (!ret)