Commit c2a905a6 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'spi-fix-v6.11-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi

Pull spi fixes from Mark Brown:
 "A small collection of fixes here, all driver specific and none of them
  too serious. For whatever reason runtime PM seems to have been causing
  a bunch of issues recently"

* tag 'spi-fix-v6.11-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi: pxa2xx: Move PM runtime handling to the glue drivers
  spi: pxa2xx: Do not override dev->platform_data on probe
  spi: spi-fsl-lpspi: limit PRESCALE bit in TCR register
  spi: spi-cadence-quadspi: Fix OSPI NOR failures during system resume
  spi: zynqmp-gqspi: Scale timeout by data size
parents 3d5f968a e17465f7
......@@ -2000,13 +2000,25 @@ static int cqspi_runtime_resume(struct device *dev)
static int cqspi_suspend(struct device *dev)
{
struct cqspi_st *cqspi = dev_get_drvdata(dev);
int ret;
return spi_controller_suspend(cqspi->host);
ret = spi_controller_suspend(cqspi->host);
if (ret)
return ret;
return pm_runtime_force_suspend(dev);
}
static int cqspi_resume(struct device *dev)
{
struct cqspi_st *cqspi = dev_get_drvdata(dev);
int ret;
ret = pm_runtime_force_resume(dev);
if (ret) {
dev_err(dev, "pm_runtime_force_resume failed on resume\n");
return ret;
}
return spi_controller_resume(cqspi->host);
}
......
......@@ -82,6 +82,10 @@
#define TCR_RXMSK BIT(19)
#define TCR_TXMSK BIT(18)
struct fsl_lpspi_devtype_data {
u8 prescale_max;
};
struct lpspi_config {
u8 bpw;
u8 chip_select;
......@@ -119,10 +123,25 @@ struct fsl_lpspi_data {
bool usedma;
struct completion dma_rx_completion;
struct completion dma_tx_completion;
const struct fsl_lpspi_devtype_data *devtype_data;
};
/*
* ERR051608 fixed or not:
* https://www.nxp.com/docs/en/errata/i.MX93_1P87f.pdf
*/
static struct fsl_lpspi_devtype_data imx93_lpspi_devtype_data = {
.prescale_max = 1,
};
static struct fsl_lpspi_devtype_data imx7ulp_lpspi_devtype_data = {
.prescale_max = 8,
};
static const struct of_device_id fsl_lpspi_dt_ids[] = {
{ .compatible = "fsl,imx7ulp-spi", },
{ .compatible = "fsl,imx7ulp-spi", .data = &imx7ulp_lpspi_devtype_data,},
{ .compatible = "fsl,imx93-spi", .data = &imx93_lpspi_devtype_data,},
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, fsl_lpspi_dt_ids);
......@@ -297,9 +316,11 @@ static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi)
{
struct lpspi_config config = fsl_lpspi->config;
unsigned int perclk_rate, scldiv, div;
u8 prescale_max;
u8 prescale;
perclk_rate = clk_get_rate(fsl_lpspi->clk_per);
prescale_max = fsl_lpspi->devtype_data->prescale_max;
if (!config.speed_hz) {
dev_err(fsl_lpspi->dev,
......@@ -315,7 +336,7 @@ static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi)
div = DIV_ROUND_UP(perclk_rate, config.speed_hz);
for (prescale = 0; prescale < 8; prescale++) {
for (prescale = 0; prescale < prescale_max; prescale++) {
scldiv = div / (1 << prescale) - 2;
if (scldiv < 256) {
fsl_lpspi->config.prescale = prescale;
......@@ -822,6 +843,7 @@ static int fsl_lpspi_init_rpm(struct fsl_lpspi_data *fsl_lpspi)
static int fsl_lpspi_probe(struct platform_device *pdev)
{
const struct fsl_lpspi_devtype_data *devtype_data;
struct fsl_lpspi_data *fsl_lpspi;
struct spi_controller *controller;
struct resource *res;
......@@ -830,6 +852,10 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
u32 temp;
bool is_target;
devtype_data = of_device_get_match_data(&pdev->dev);
if (!devtype_data)
return -ENODEV;
is_target = of_property_read_bool((&pdev->dev)->of_node, "spi-slave");
if (is_target)
controller = devm_spi_alloc_target(&pdev->dev,
......@@ -848,6 +874,7 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
fsl_lpspi->is_target = is_target;
fsl_lpspi->is_only_cs1 = of_property_read_bool((&pdev->dev)->of_node,
"fsl,spi-only-use-cs1-sel");
fsl_lpspi->devtype_data = devtype_data;
init_completion(&fsl_lpspi->xfer_done);
......
......@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/sprintf.h>
#include <linux/string.h>
#include <linux/types.h>
......@@ -297,11 +298,23 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev,
return ret;
ssp->irq = pci_irq_vector(dev, 0);
return pxa2xx_spi_probe(&dev->dev, ssp);
ret = pxa2xx_spi_probe(&dev->dev, ssp, pdata);
if (ret)
return ret;
pm_runtime_set_autosuspend_delay(&dev->dev, 50);
pm_runtime_use_autosuspend(&dev->dev);
pm_runtime_put_autosuspend(&dev->dev);
pm_runtime_allow(&dev->dev);
return 0;
}
static void pxa2xx_spi_pci_remove(struct pci_dev *dev)
{
pm_runtime_forbid(&dev->dev);
pm_runtime_get_noresume(&dev->dev);
pxa2xx_spi_remove(&dev->dev);
}
......
......@@ -7,6 +7,7 @@
#include <linux/init.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include <linux/types.h>
......@@ -63,7 +64,7 @@ static struct ssp_device *pxa2xx_spi_ssp_request(struct platform_device *pdev)
ssp = pxa_ssp_request(pdev->id, pdev->name);
if (!ssp)
return ssp;
return NULL;
status = devm_add_action_or_reset(&pdev->dev, pxa2xx_spi_ssp_release, ssp);
if (status)
......@@ -142,14 +143,13 @@ static int pxa2xx_spi_platform_probe(struct platform_device *pdev)
struct pxa2xx_spi_controller *platform_info;
struct device *dev = &pdev->dev;
struct ssp_device *ssp;
int ret;
platform_info = dev_get_platdata(dev);
if (!platform_info) {
platform_info = pxa2xx_spi_init_pdata(pdev);
if (IS_ERR(platform_info))
return dev_err_probe(dev, PTR_ERR(platform_info), "missing platform data\n");
dev->platform_data = platform_info;
}
ssp = pxa2xx_spi_ssp_request(pdev);
......@@ -158,12 +158,28 @@ static int pxa2xx_spi_platform_probe(struct platform_device *pdev)
if (!ssp)
ssp = &platform_info->ssp;
return pxa2xx_spi_probe(dev, ssp);
pm_runtime_set_autosuspend_delay(dev, 50);
pm_runtime_use_autosuspend(dev);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
ret = pxa2xx_spi_probe(dev, ssp, platform_info);
if (ret)
pm_runtime_disable(dev);
return ret;
}
static void pxa2xx_spi_platform_remove(struct platform_device *pdev)
{
pxa2xx_spi_remove(&pdev->dev);
struct device *dev = &pdev->dev;
pm_runtime_get_sync(dev);
pxa2xx_spi_remove(dev);
pm_runtime_put_noidle(dev);
pm_runtime_disable(dev);
}
static const struct acpi_device_id pxa2xx_spi_acpi_match[] = {
......
......@@ -1277,16 +1277,15 @@ static size_t pxa2xx_spi_max_dma_transfer_size(struct spi_device *spi)
return MAX_DMA_LEN;
}
int pxa2xx_spi_probe(struct device *dev, struct ssp_device *ssp)
int pxa2xx_spi_probe(struct device *dev, struct ssp_device *ssp,
struct pxa2xx_spi_controller *platform_info)
{
struct pxa2xx_spi_controller *platform_info;
struct spi_controller *controller;
struct driver_data *drv_data;
const struct lpss_config *config;
int status;
u32 tmp;
platform_info = dev_get_platdata(dev);
if (platform_info->is_target)
controller = devm_spi_alloc_target(dev, sizeof(*drv_data));
else
......@@ -1450,24 +1449,16 @@ int pxa2xx_spi_probe(struct device *dev, struct ssp_device *ssp)
}
}
pm_runtime_set_autosuspend_delay(dev, 50);
pm_runtime_use_autosuspend(dev);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
/* Register with the SPI framework */
dev_set_drvdata(dev, drv_data);
status = spi_register_controller(controller);
if (status) {
dev_err_probe(dev, status, "problem registering SPI controller\n");
goto out_error_pm_runtime_enabled;
goto out_error_clock_enabled;
}
return status;
out_error_pm_runtime_enabled:
pm_runtime_disable(dev);
out_error_clock_enabled:
clk_disable_unprepare(ssp->clk);
......@@ -1484,8 +1475,6 @@ void pxa2xx_spi_remove(struct device *dev)
struct driver_data *drv_data = dev_get_drvdata(dev);
struct ssp_device *ssp = drv_data->ssp;
pm_runtime_get_sync(dev);
spi_unregister_controller(drv_data->controller);
/* Disable the SSP at the peripheral and SOC level */
......@@ -1496,9 +1485,6 @@ void pxa2xx_spi_remove(struct device *dev)
if (drv_data->controller_info->enable_dma)
pxa2xx_spi_dma_release(drv_data);
pm_runtime_put_noidle(dev);
pm_runtime_disable(dev);
/* Release IRQ */
free_irq(ssp->irq, drv_data);
}
......
......@@ -132,7 +132,8 @@ extern void pxa2xx_spi_dma_stop(struct driver_data *drv_data);
extern int pxa2xx_spi_dma_setup(struct driver_data *drv_data);
extern void pxa2xx_spi_dma_release(struct driver_data *drv_data);
int pxa2xx_spi_probe(struct device *dev, struct ssp_device *ssp);
int pxa2xx_spi_probe(struct device *dev, struct ssp_device *ssp,
struct pxa2xx_spi_controller *platform_info);
void pxa2xx_spi_remove(struct device *dev);
extern const struct dev_pm_ops pxa2xx_spi_pm_ops;
......
......@@ -1033,6 +1033,18 @@ static int __maybe_unused zynqmp_runtime_resume(struct device *dev)
return 0;
}
static unsigned long zynqmp_qspi_timeout(struct zynqmp_qspi *xqspi, u8 bits,
unsigned long bytes)
{
unsigned long timeout;
/* Assume we are at most 2x slower than the nominal bus speed */
timeout = mult_frac(bytes, 2 * 8 * MSEC_PER_SEC,
bits * xqspi->speed_hz);
/* And add 100 ms for scheduling delays */
return msecs_to_jiffies(timeout + 100);
}
/**
* zynqmp_qspi_exec_op() - Initiates the QSPI transfer
* @mem: The SPI memory
......@@ -1049,6 +1061,7 @@ static int zynqmp_qspi_exec_op(struct spi_mem *mem,
{
struct zynqmp_qspi *xqspi = spi_controller_get_devdata
(mem->spi->controller);
unsigned long timeout;
int err = 0, i;
u32 genfifoentry = 0;
u16 opcode = op->cmd.opcode;
......@@ -1077,8 +1090,10 @@ static int zynqmp_qspi_exec_op(struct spi_mem *mem,
zynqmp_gqspi_write(xqspi, GQSPI_IER_OFST,
GQSPI_IER_GENFIFOEMPTY_MASK |
GQSPI_IER_TXNOT_FULL_MASK);
if (!wait_for_completion_timeout
(&xqspi->data_completion, msecs_to_jiffies(1000))) {
timeout = zynqmp_qspi_timeout(xqspi, op->cmd.buswidth,
op->cmd.nbytes);
if (!wait_for_completion_timeout(&xqspi->data_completion,
timeout)) {
err = -ETIMEDOUT;
goto return_err;
}
......@@ -1104,8 +1119,10 @@ static int zynqmp_qspi_exec_op(struct spi_mem *mem,
GQSPI_IER_TXEMPTY_MASK |
GQSPI_IER_GENFIFOEMPTY_MASK |
GQSPI_IER_TXNOT_FULL_MASK);
if (!wait_for_completion_timeout
(&xqspi->data_completion, msecs_to_jiffies(1000))) {
timeout = zynqmp_qspi_timeout(xqspi, op->addr.buswidth,
op->addr.nbytes);
if (!wait_for_completion_timeout(&xqspi->data_completion,
timeout)) {
err = -ETIMEDOUT;
goto return_err;
}
......@@ -1173,8 +1190,9 @@ static int zynqmp_qspi_exec_op(struct spi_mem *mem,
GQSPI_IER_RXEMPTY_MASK);
}
}
if (!wait_for_completion_timeout
(&xqspi->data_completion, msecs_to_jiffies(1000)))
timeout = zynqmp_qspi_timeout(xqspi, op->data.buswidth,
op->data.nbytes);
if (!wait_for_completion_timeout(&xqspi->data_completion, timeout))
err = -ETIMEDOUT;
}
......
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