spi: Fixes for v5.5
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. -----BEGIN PGP SIGNATURE----- iQFHBAABCgAxFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAl34xt8THGJyb29uaWVA a2VybmVsLm9yZwAKCRAk1otyXVSH0D64B/91GGhGgNybvExhls79YKQx9STnv8Vl sIVgbnVxnTHrAa+s/5ML0T8LzH9W5KcBUuL+KCd0oMdaE9QZSCKGdraEqDJz7Ie4 iHbBSAtwL0tegbyM+J4oKC3wen3Lg1u1iwn4Plo2fVKEah7zG6gdneQcf454EnEF om2Sj2K7tqoqN1jIl0j/FGQtlDXvhzp3m+CyGakjzsBvINmSGixrO5Lit/dx3qSf xkhLDWZqUk3UatusPXhpJJVxWPuVvT5NQkvUYDte1rHxrVdolYQctwBRPN/uZ2hq FcLzUbWVFx7p3cDqvuQ6XTptpue4njnaPOT/LW6tud4BexlaV1q83XYs =gPXn -----END PGP SIGNATURE----- Merge tag 'spi-fix-v5.5-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi 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
This commit is contained in:
commit
a922f1a9ae
@ -23,6 +23,29 @@
|
||||
#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",
|
||||
|
@ -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 {
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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 },
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user