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

1  2 
drivers/gpio/gpiolib-of.c
drivers/spi/spi-dw.c
drivers/spi/spi-pxa2xx.c

index dc27b1a88e9343a8a029832cef5c6095a7be6238,f90a161ca97a9d106b4eec04aba7d238132f3f4d..b696e4598a240ea4237bacf42d90b22424320616
  #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>
   *
   * FIXME: get rid of those external users by converting them to GPIO
 - * descriptors and let them all use gpiod_get_count()
 + * descriptors and let them all use gpiod_count()
   */
  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",
@@@ -84,9 -111,8 +111,9 @@@ static struct gpio_desc *of_xlate_and_g
  /**
   * of_gpio_need_valid_mask() - figure out if the OF GPIO driver needs
   * to set the .valid_mask
 - * @dev: the device for the GPIO provider
 - * @return: true if the valid mask needs to be set
 + * @gc: the target gpio_chip
 + *
 + * Return: true if the valid mask needs to be set
   */
  bool of_gpio_need_valid_mask(const struct gpio_chip *gc)
  {
@@@ -135,20 -161,18 +162,20 @@@ static void of_gpio_flags_quirks(struc
             (!(strcmp(propname, "enable-gpio") &&
                strcmp(propname, "enable-gpios")) &&
              of_device_is_compatible(np, "regulator-gpio")))) {
 +              bool active_low = !of_property_read_bool(np,
 +                                                       "enable-active-high");
                /*
                 * The regulator GPIO handles are specified such that the
                 * presence or absence of "enable-active-high" solely controls
                 * the polarity of the GPIO line. Any phandle flags must
                 * be actively ignored.
                 */
 -              if (*flags & OF_GPIO_ACTIVE_LOW) {
 +              if ((*flags & OF_GPIO_ACTIVE_LOW) && !active_low) {
                        pr_warn("%s GPIO handle specifies active low - ignored\n",
                                of_node_full_name(np));
                        *flags &= ~OF_GPIO_ACTIVE_LOW;
                }
 -              if (!of_property_read_bool(np, "enable-active-high"))
 +              if (active_low)
                        *flags |= OF_GPIO_ACTIVE_LOW;
        }
        /*
@@@ -320,7 -344,7 +347,7 @@@ struct gpio_desc *gpiod_get_from_of_nod
        transitory = flags & OF_GPIO_TRANSITORY;
  
        ret = gpiod_request(desc, label);
 -      if (ret == -EBUSY && (flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE))
 +      if (ret == -EBUSY && (dflags & GPIOD_FLAGS_BIT_NONEXCLUSIVE))
                return desc;
        if (ret)
                return ERR_PTR(ret);
@@@ -885,13 -909,16 +912,13 @@@ int of_gpiochip_add(struct gpio_chip *c
        of_node_get(chip->of_node);
  
        ret = of_gpiochip_scan_gpios(chip);
 -      if (ret) {
 +      if (ret)
                of_node_put(chip->of_node);
 -              gpiochip_remove_pin_ranges(chip);
 -      }
  
        return ret;
  }
  
  void of_gpiochip_remove(struct gpio_chip *chip)
  {
 -      gpiochip_remove_pin_ranges(chip);
        of_node_put(chip->of_node);
  }
diff --combined drivers/spi/spi-dw.c
index a92aa5cd4fbe8b1fd4433652e14ac9cef446af92,9387f60eb496e30de76533f69f69d73890c01cfc..76d6b94a7597ff9b0686f3ac81c989f1fac711d2
@@@ -129,10 -129,11 +129,11 @@@ void dw_spi_set_cs(struct spi_device *s
        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);
@@@ -308,8 -309,7 +309,8 @@@ static int dw_spi_transfer_one(struct s
        cr0 = (transfer->bits_per_word - 1)
                | (chip->type << SPI_FRF_OFFSET)
                | ((((spi->mode & SPI_CPOL) ? 1 : 0) << SPI_SCOL_OFFSET) |
 -                      (((spi->mode & SPI_CPHA) ? 1 : 0) << SPI_SCPH_OFFSET))
 +                      (((spi->mode & SPI_CPHA) ? 1 : 0) << SPI_SCPH_OFFSET) |
 +                      (((spi->mode & SPI_LOOP) ? 1 : 0) << SPI_SRL_OFFSET))
                | (chip->tmode << SPI_TMOD_OFFSET);
  
        /*
diff --combined drivers/spi/spi-pxa2xx.c
index 16b6b2ad4e7c0aec2c3d58f6aa9ddac6f6d9dd32,d58791d92c7336c46d85fee1fc298d3fbcf8b0d5..9071333ebdd86fe290f441c21b4a1a37c7e40ff5
@@@ -1443,6 -1443,10 +1443,10 @@@ static const struct pci_device_id pxa2x
        { 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 },
        { PCI_VDEVICE(INTEL, 0x02aa), LPSS_CNL_SSP },
        { PCI_VDEVICE(INTEL, 0x02ab), LPSS_CNL_SSP },
        { PCI_VDEVICE(INTEL, 0x02fb), LPSS_CNL_SSP },
 +      /* CML-H */
 +      { PCI_VDEVICE(INTEL, 0x06aa), LPSS_CNL_SSP },
 +      { PCI_VDEVICE(INTEL, 0x06ab), LPSS_CNL_SSP },
 +      { PCI_VDEVICE(INTEL, 0x06fb), LPSS_CNL_SSP },
        /* TGL-LP */
        { PCI_VDEVICE(INTEL, 0xa0aa), LPSS_CNL_SSP },
        { PCI_VDEVICE(INTEL, 0xa0ab), LPSS_CNL_SSP },
@@@ -1541,15 -1541,17 +1545,15 @@@ pxa2xx_spi_init_pdata(struct platform_d
        if (!pdata)
                return NULL;
  
 -      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 -      if (!res)
 -              return NULL;
 -
        ssp = &pdata->ssp;
  
 -      ssp->phys_base = res->start;
 +      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        ssp->mmio_base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(ssp->mmio_base))
                return NULL;
  
 +      ssp->phys_base = res->start;
 +
  #ifdef CONFIG_PCI
        if (pcidev_id) {
                pdata->tx_param = parent;
@@@ -1602,11 -1604,6 +1606,11 @@@ static int pxa2xx_spi_fw_translate_cs(s
        return cs;
  }
  
 +static size_t pxa2xx_spi_max_dma_transfer_size(struct spi_device *spi)
 +{
 +      return MAX_DMA_LEN;
 +}
 +
  static int pxa2xx_spi_probe(struct platform_device *pdev)
  {
        struct device *dev = &pdev->dev;
                } else {
                        controller->can_dma = pxa2xx_spi_can_dma;
                        controller->max_dma_len = MAX_DMA_LEN;
 +                      controller->max_transfer_size =
 +                              pxa2xx_spi_max_dma_transfer_size;
                }
        }