Commit fee3c824 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'spi-fix-v5.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi

Pull spi fixes from Mark Brown:
 "This is a relatively large set of fixes, the bulk of it being a series
  from Lukas Wunner which fixes confusion with the lifetime of driver
  data allocated along with the SPI controller structure that's been
  created as part of the conversion to devm APIs.

  The simplest fix, explained in detail in Lukas' commit message, is to
  move to a devm_ function for allocation of the controller and hence
  driver data in order to push the free of that after anything tries to
  reference the driver data in the remove path. This results in a
  relatively large diff due to the addition of a new function but isn't
  particularly complex.

  There's also a fix from Sven van Asbroeck which fixes yet more fallout
  from the conflicts between the various different places one can
  configure the polarity of GPIOs in modern systems.

  Otherwise everything is fairly small and driver specific"

* tag 'spi-fix-v5.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi: npcm-fiu: Don't leak SPI master in probe error path
  spi: dw: Set transfer handler before unmasking the IRQs
  spi: cadence-quadspi: Fix error return code in cqspi_probe
  spi: bcm2835aux: Restore err assignment in bcm2835aux_spi_probe
  spi: lpspi: Fix use-after-free on unbind
  spi: bcm-qspi: Fix use-after-free on unbind
  spi: bcm2835aux: Fix use-after-free on unbind
  spi: bcm2835: Fix use-after-free on unbind
  spi: Introduce device-managed SPI controller allocation
  spi: fsi: Fix transfer returning without finalizing message
  spi: fix client driver breakages when using GPIO descriptors
parents d748287a 04a9cd51
...@@ -1327,7 +1327,7 @@ int bcm_qspi_probe(struct platform_device *pdev, ...@@ -1327,7 +1327,7 @@ int bcm_qspi_probe(struct platform_device *pdev,
data = of_id->data; data = of_id->data;
master = spi_alloc_master(dev, sizeof(struct bcm_qspi)); master = devm_spi_alloc_master(dev, sizeof(struct bcm_qspi));
if (!master) { if (!master) {
dev_err(dev, "error allocating spi_master\n"); dev_err(dev, "error allocating spi_master\n");
return -ENOMEM; return -ENOMEM;
...@@ -1367,21 +1367,17 @@ int bcm_qspi_probe(struct platform_device *pdev, ...@@ -1367,21 +1367,17 @@ int bcm_qspi_probe(struct platform_device *pdev,
if (res) { if (res) {
qspi->base[MSPI] = devm_ioremap_resource(dev, res); qspi->base[MSPI] = devm_ioremap_resource(dev, res);
if (IS_ERR(qspi->base[MSPI])) { if (IS_ERR(qspi->base[MSPI]))
ret = PTR_ERR(qspi->base[MSPI]); return PTR_ERR(qspi->base[MSPI]);
goto qspi_resource_err;
}
} else { } else {
goto qspi_resource_err; return 0;
} }
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bspi"); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bspi");
if (res) { if (res) {
qspi->base[BSPI] = devm_ioremap_resource(dev, res); qspi->base[BSPI] = devm_ioremap_resource(dev, res);
if (IS_ERR(qspi->base[BSPI])) { if (IS_ERR(qspi->base[BSPI]))
ret = PTR_ERR(qspi->base[BSPI]); return PTR_ERR(qspi->base[BSPI]);
goto qspi_resource_err;
}
qspi->bspi_mode = true; qspi->bspi_mode = true;
} else { } else {
qspi->bspi_mode = false; qspi->bspi_mode = false;
...@@ -1392,18 +1388,14 @@ int bcm_qspi_probe(struct platform_device *pdev, ...@@ -1392,18 +1388,14 @@ int bcm_qspi_probe(struct platform_device *pdev,
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cs_reg"); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cs_reg");
if (res) { if (res) {
qspi->base[CHIP_SELECT] = devm_ioremap_resource(dev, res); qspi->base[CHIP_SELECT] = devm_ioremap_resource(dev, res);
if (IS_ERR(qspi->base[CHIP_SELECT])) { if (IS_ERR(qspi->base[CHIP_SELECT]))
ret = PTR_ERR(qspi->base[CHIP_SELECT]); return PTR_ERR(qspi->base[CHIP_SELECT]);
goto qspi_resource_err;
}
} }
qspi->dev_ids = kcalloc(num_irqs, sizeof(struct bcm_qspi_dev_id), qspi->dev_ids = kcalloc(num_irqs, sizeof(struct bcm_qspi_dev_id),
GFP_KERNEL); GFP_KERNEL);
if (!qspi->dev_ids) { if (!qspi->dev_ids)
ret = -ENOMEM; return -ENOMEM;
goto qspi_resource_err;
}
for (val = 0; val < num_irqs; val++) { for (val = 0; val < num_irqs; val++) {
irq = -1; irq = -1;
...@@ -1484,7 +1476,7 @@ int bcm_qspi_probe(struct platform_device *pdev, ...@@ -1484,7 +1476,7 @@ int bcm_qspi_probe(struct platform_device *pdev,
qspi->xfer_mode.addrlen = -1; qspi->xfer_mode.addrlen = -1;
qspi->xfer_mode.hp = -1; qspi->xfer_mode.hp = -1;
ret = devm_spi_register_master(&pdev->dev, master); ret = spi_register_master(master);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "can't register master\n"); dev_err(dev, "can't register master\n");
goto qspi_reg_err; goto qspi_reg_err;
...@@ -1497,8 +1489,6 @@ int bcm_qspi_probe(struct platform_device *pdev, ...@@ -1497,8 +1489,6 @@ int bcm_qspi_probe(struct platform_device *pdev,
clk_disable_unprepare(qspi->clk); clk_disable_unprepare(qspi->clk);
qspi_probe_err: qspi_probe_err:
kfree(qspi->dev_ids); kfree(qspi->dev_ids);
qspi_resource_err:
spi_master_put(master);
return ret; return ret;
} }
/* probe function to be called by SoC specific platform driver probe */ /* probe function to be called by SoC specific platform driver probe */
...@@ -1508,10 +1498,10 @@ int bcm_qspi_remove(struct platform_device *pdev) ...@@ -1508,10 +1498,10 @@ int bcm_qspi_remove(struct platform_device *pdev)
{ {
struct bcm_qspi *qspi = platform_get_drvdata(pdev); struct bcm_qspi *qspi = platform_get_drvdata(pdev);
spi_unregister_master(qspi->master);
bcm_qspi_hw_uninit(qspi); bcm_qspi_hw_uninit(qspi);
clk_disable_unprepare(qspi->clk); clk_disable_unprepare(qspi->clk);
kfree(qspi->dev_ids); kfree(qspi->dev_ids);
spi_unregister_master(qspi->master);
return 0; return 0;
} }
......
...@@ -1278,7 +1278,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) ...@@ -1278,7 +1278,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
struct bcm2835_spi *bs; struct bcm2835_spi *bs;
int err; int err;
ctlr = spi_alloc_master(&pdev->dev, ALIGN(sizeof(*bs), ctlr = devm_spi_alloc_master(&pdev->dev, ALIGN(sizeof(*bs),
dma_get_cache_alignment())); dma_get_cache_alignment()));
if (!ctlr) if (!ctlr)
return -ENOMEM; return -ENOMEM;
...@@ -1299,23 +1299,17 @@ static int bcm2835_spi_probe(struct platform_device *pdev) ...@@ -1299,23 +1299,17 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
bs->ctlr = ctlr; bs->ctlr = ctlr;
bs->regs = devm_platform_ioremap_resource(pdev, 0); bs->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(bs->regs)) { if (IS_ERR(bs->regs))
err = PTR_ERR(bs->regs); return PTR_ERR(bs->regs);
goto out_controller_put;
}
bs->clk = devm_clk_get(&pdev->dev, NULL); bs->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(bs->clk)) { if (IS_ERR(bs->clk))
err = dev_err_probe(&pdev->dev, PTR_ERR(bs->clk), return dev_err_probe(&pdev->dev, PTR_ERR(bs->clk),
"could not get clk\n"); "could not get clk\n");
goto out_controller_put;
}
bs->irq = platform_get_irq(pdev, 0); bs->irq = platform_get_irq(pdev, 0);
if (bs->irq <= 0) { if (bs->irq <= 0)
err = bs->irq ? bs->irq : -ENODEV; return bs->irq ? bs->irq : -ENODEV;
goto out_controller_put;
}
clk_prepare_enable(bs->clk); clk_prepare_enable(bs->clk);
...@@ -1349,8 +1343,6 @@ static int bcm2835_spi_probe(struct platform_device *pdev) ...@@ -1349,8 +1343,6 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
bcm2835_dma_release(ctlr, bs); bcm2835_dma_release(ctlr, bs);
out_clk_disable: out_clk_disable:
clk_disable_unprepare(bs->clk); clk_disable_unprepare(bs->clk);
out_controller_put:
spi_controller_put(ctlr);
return err; return err;
} }
......
...@@ -494,7 +494,7 @@ static int bcm2835aux_spi_probe(struct platform_device *pdev) ...@@ -494,7 +494,7 @@ static int bcm2835aux_spi_probe(struct platform_device *pdev)
unsigned long clk_hz; unsigned long clk_hz;
int err; int err;
master = spi_alloc_master(&pdev->dev, sizeof(*bs)); master = devm_spi_alloc_master(&pdev->dev, sizeof(*bs));
if (!master) if (!master)
return -ENOMEM; return -ENOMEM;
...@@ -524,29 +524,25 @@ static int bcm2835aux_spi_probe(struct platform_device *pdev) ...@@ -524,29 +524,25 @@ static int bcm2835aux_spi_probe(struct platform_device *pdev)
/* the main area */ /* the main area */
bs->regs = devm_platform_ioremap_resource(pdev, 0); bs->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(bs->regs)) { if (IS_ERR(bs->regs))
err = PTR_ERR(bs->regs); return PTR_ERR(bs->regs);
goto out_master_put;
}
bs->clk = devm_clk_get(&pdev->dev, NULL); bs->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(bs->clk)) { if (IS_ERR(bs->clk)) {
err = PTR_ERR(bs->clk); err = PTR_ERR(bs->clk);
dev_err(&pdev->dev, "could not get clk: %d\n", err); dev_err(&pdev->dev, "could not get clk: %d\n", err);
goto out_master_put; return err;
} }
bs->irq = platform_get_irq(pdev, 0); bs->irq = platform_get_irq(pdev, 0);
if (bs->irq <= 0) { if (bs->irq <= 0)
err = bs->irq ? bs->irq : -ENODEV; return bs->irq ? bs->irq : -ENODEV;
goto out_master_put;
}
/* this also enables the HW block */ /* this also enables the HW block */
err = clk_prepare_enable(bs->clk); err = clk_prepare_enable(bs->clk);
if (err) { if (err) {
dev_err(&pdev->dev, "could not prepare clock: %d\n", err); dev_err(&pdev->dev, "could not prepare clock: %d\n", err);
goto out_master_put; return err;
} }
/* just checking if the clock returns a sane value */ /* just checking if the clock returns a sane value */
...@@ -581,8 +577,6 @@ static int bcm2835aux_spi_probe(struct platform_device *pdev) ...@@ -581,8 +577,6 @@ static int bcm2835aux_spi_probe(struct platform_device *pdev)
out_clk_disable: out_clk_disable:
clk_disable_unprepare(bs->clk); clk_disable_unprepare(bs->clk);
out_master_put:
spi_master_put(master);
return err; return err;
} }
......
...@@ -1260,12 +1260,14 @@ static int cqspi_probe(struct platform_device *pdev) ...@@ -1260,12 +1260,14 @@ static int cqspi_probe(struct platform_device *pdev)
/* Obtain QSPI reset control */ /* Obtain QSPI reset control */
rstc = devm_reset_control_get_optional_exclusive(dev, "qspi"); rstc = devm_reset_control_get_optional_exclusive(dev, "qspi");
if (IS_ERR(rstc)) { if (IS_ERR(rstc)) {
ret = PTR_ERR(rstc);
dev_err(dev, "Cannot get QSPI reset.\n"); dev_err(dev, "Cannot get QSPI reset.\n");
goto probe_reset_failed; goto probe_reset_failed;
} }
rstc_ocp = devm_reset_control_get_optional_exclusive(dev, "qspi-ocp"); rstc_ocp = devm_reset_control_get_optional_exclusive(dev, "qspi-ocp");
if (IS_ERR(rstc_ocp)) { if (IS_ERR(rstc_ocp)) {
ret = PTR_ERR(rstc_ocp);
dev_err(dev, "Cannot get QSPI OCP reset.\n"); dev_err(dev, "Cannot get QSPI OCP reset.\n");
goto probe_reset_failed; goto probe_reset_failed;
} }
......
...@@ -357,11 +357,11 @@ static void dw_spi_irq_setup(struct dw_spi *dws) ...@@ -357,11 +357,11 @@ static void dw_spi_irq_setup(struct dw_spi *dws)
dw_writel(dws, DW_SPI_TXFTLR, level); dw_writel(dws, DW_SPI_TXFTLR, level);
dw_writel(dws, DW_SPI_RXFTLR, level - 1); dw_writel(dws, DW_SPI_RXFTLR, level - 1);
dws->transfer_handler = dw_spi_transfer_handler;
imask = SPI_INT_TXEI | SPI_INT_TXOI | SPI_INT_RXUI | SPI_INT_RXOI | imask = SPI_INT_TXEI | SPI_INT_TXOI | SPI_INT_RXUI | SPI_INT_RXOI |
SPI_INT_RXFI; SPI_INT_RXFI;
spi_umask_intr(dws, imask); spi_umask_intr(dws, imask);
dws->transfer_handler = dw_spi_transfer_handler;
} }
/* /*
......
...@@ -477,7 +477,7 @@ static int fsi_spi_transfer_one_message(struct spi_controller *ctlr, ...@@ -477,7 +477,7 @@ static int fsi_spi_transfer_one_message(struct spi_controller *ctlr,
rc = fsi_spi_check_mux(ctx->fsi, ctx->dev); rc = fsi_spi_check_mux(ctx->fsi, ctx->dev);
if (rc) if (rc)
return rc; goto error;
list_for_each_entry(transfer, &mesg->transfers, transfer_list) { list_for_each_entry(transfer, &mesg->transfers, transfer_list) {
struct fsi_spi_sequence seq; struct fsi_spi_sequence seq;
......
...@@ -938,9 +938,6 @@ static int fsl_lpspi_remove(struct platform_device *pdev) ...@@ -938,9 +938,6 @@ static int fsl_lpspi_remove(struct platform_device *pdev)
spi_controller_get_devdata(controller); spi_controller_get_devdata(controller);
pm_runtime_disable(fsl_lpspi->dev); pm_runtime_disable(fsl_lpspi->dev);
spi_master_put(controller);
return 0; return 0;
} }
......
...@@ -679,7 +679,7 @@ static int npcm_fiu_probe(struct platform_device *pdev) ...@@ -679,7 +679,7 @@ static int npcm_fiu_probe(struct platform_device *pdev)
struct resource *res; struct resource *res;
int id; int id;
ctrl = spi_alloc_master(dev, sizeof(*fiu)); ctrl = devm_spi_alloc_master(dev, sizeof(*fiu));
if (!ctrl) if (!ctrl)
return -ENOMEM; return -ENOMEM;
......
...@@ -812,18 +812,16 @@ static void spi_set_cs(struct spi_device *spi, bool enable) ...@@ -812,18 +812,16 @@ static void spi_set_cs(struct spi_device *spi, bool enable)
enable = !enable; enable = !enable;
if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio)) { if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio)) {
/*
* Honour the SPI_NO_CS flag and invert the enable line, as
* active low is default for SPI. Execution paths that handle
* polarity inversion in gpiolib (such as device tree) will
* enforce active high using the SPI_CS_HIGH resulting in a
* double inversion through the code above.
*/
if (!(spi->mode & SPI_NO_CS)) { if (!(spi->mode & SPI_NO_CS)) {
if (spi->cs_gpiod) if (spi->cs_gpiod)
/* polarity handled by gpiolib */
gpiod_set_value_cansleep(spi->cs_gpiod, gpiod_set_value_cansleep(spi->cs_gpiod,
!enable); enable1);
else else
/*
* invert the enable line, as active low is
* default for SPI.
*/
gpio_set_value_cansleep(spi->cs_gpio, !enable); gpio_set_value_cansleep(spi->cs_gpio, !enable);
} }
/* Some SPI masters need both GPIO CS & slave_select */ /* Some SPI masters need both GPIO CS & slave_select */
...@@ -1992,15 +1990,6 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi, ...@@ -1992,15 +1990,6 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
} }
spi->chip_select = value; spi->chip_select = value;
/*
* For descriptors associated with the device, polarity inversion is
* handled in the gpiolib, so all gpio chip selects are "active high"
* in the logical sense, the gpiolib will invert the line if need be.
*/
if ((ctlr->use_gpio_descriptors) && ctlr->cs_gpiods &&
ctlr->cs_gpiods[spi->chip_select])
spi->mode |= SPI_CS_HIGH;
/* Device speed */ /* Device speed */
if (!of_property_read_u32(nc, "spi-max-frequency", &value)) if (!of_property_read_u32(nc, "spi-max-frequency", &value))
spi->max_speed_hz = value; spi->max_speed_hz = value;
...@@ -2453,6 +2442,49 @@ struct spi_controller *__spi_alloc_controller(struct device *dev, ...@@ -2453,6 +2442,49 @@ struct spi_controller *__spi_alloc_controller(struct device *dev,
} }
EXPORT_SYMBOL_GPL(__spi_alloc_controller); EXPORT_SYMBOL_GPL(__spi_alloc_controller);
static void devm_spi_release_controller(struct device *dev, void *ctlr)
{
spi_controller_put(*(struct spi_controller **)ctlr);
}
/**
* __devm_spi_alloc_controller - resource-managed __spi_alloc_controller()
* @dev: physical device of SPI controller
* @size: how much zeroed driver-private data to allocate
* @slave: whether to allocate an SPI master (false) or SPI slave (true)
* Context: can sleep
*
* Allocate an SPI controller and automatically release a reference on it
* when @dev is unbound from its driver. Drivers are thus relieved from
* having to call spi_controller_put().
*
* The arguments to this function are identical to __spi_alloc_controller().
*
* Return: the SPI controller structure on success, else NULL.
*/
struct spi_controller *__devm_spi_alloc_controller(struct device *dev,
unsigned int size,
bool slave)
{
struct spi_controller **ptr, *ctlr;
ptr = devres_alloc(devm_spi_release_controller, sizeof(*ptr),
GFP_KERNEL);
if (!ptr)
return NULL;
ctlr = __spi_alloc_controller(dev, size, slave);
if (ctlr) {
*ptr = ctlr;
devres_add(dev, ptr);
} else {
devres_free(ptr);
}
return ctlr;
}
EXPORT_SYMBOL_GPL(__devm_spi_alloc_controller);
#ifdef CONFIG_OF #ifdef CONFIG_OF
static int of_spi_get_gpio_numbers(struct spi_controller *ctlr) static int of_spi_get_gpio_numbers(struct spi_controller *ctlr)
{ {
...@@ -2789,6 +2821,11 @@ int devm_spi_register_controller(struct device *dev, ...@@ -2789,6 +2821,11 @@ int devm_spi_register_controller(struct device *dev,
} }
EXPORT_SYMBOL_GPL(devm_spi_register_controller); EXPORT_SYMBOL_GPL(devm_spi_register_controller);
static int devm_spi_match_controller(struct device *dev, void *res, void *ctlr)
{
return *(struct spi_controller **)res == ctlr;
}
static int __unregister(struct device *dev, void *null) static int __unregister(struct device *dev, void *null)
{ {
spi_unregister_device(to_spi_device(dev)); spi_unregister_device(to_spi_device(dev));
...@@ -2830,7 +2867,15 @@ void spi_unregister_controller(struct spi_controller *ctlr) ...@@ -2830,7 +2867,15 @@ void spi_unregister_controller(struct spi_controller *ctlr)
list_del(&ctlr->list); list_del(&ctlr->list);
mutex_unlock(&board_lock); mutex_unlock(&board_lock);
device_unregister(&ctlr->dev); device_del(&ctlr->dev);
/* Release the last reference on the controller if its driver
* has not yet been converted to devm_spi_alloc_master/slave().
*/
if (!devres_find(ctlr->dev.parent, devm_spi_release_controller,
devm_spi_match_controller, ctlr))
put_device(&ctlr->dev);
/* free bus id */ /* free bus id */
mutex_lock(&board_lock); mutex_lock(&board_lock);
if (found == ctlr) if (found == ctlr)
......
...@@ -734,6 +734,25 @@ static inline struct spi_controller *spi_alloc_slave(struct device *host, ...@@ -734,6 +734,25 @@ static inline struct spi_controller *spi_alloc_slave(struct device *host,
return __spi_alloc_controller(host, size, true); return __spi_alloc_controller(host, size, true);
} }
struct spi_controller *__devm_spi_alloc_controller(struct device *dev,
unsigned int size,
bool slave);
static inline struct spi_controller *devm_spi_alloc_master(struct device *dev,
unsigned int size)
{
return __devm_spi_alloc_controller(dev, size, false);
}
static inline struct spi_controller *devm_spi_alloc_slave(struct device *dev,
unsigned int size)
{
if (!IS_ENABLED(CONFIG_SPI_SLAVE))
return NULL;
return __devm_spi_alloc_controller(dev, size, true);
}
extern int spi_register_controller(struct spi_controller *ctlr); extern int spi_register_controller(struct spi_controller *ctlr);
extern int devm_spi_register_controller(struct device *dev, extern int devm_spi_register_controller(struct device *dev,
struct spi_controller *ctlr); struct spi_controller *ctlr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment