Commit 985f6ab9 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull spi fixes from Mark Brown:
 "A few small fixes.

  Mostly driver specific but there's one in the core which fixes a
  deadlock when adding devices on spi-mux that's triggered because
  spi-mux is a SPI device which is itself a SPI controller and so can
  instantiate devices when registered.

  We were using a global lock to protect against reusing chip selects
  but they're a per controller thing so moving the lock per controller
  resolves that"

* tag 'spi-fix-v5.15-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi-mux: Fix false-positive lockdep splats
  spi: Fix deadlock when adding SPI controllers on SPI buses
  spi: bcm-qspi: clear MSPI spifie interrupt during probe
  spi: spi-nxp-fspi: don't depend on a specific node name erratum workaround
  spi: mediatek: skip delays if they are 0
  spi: atmel: Fix PDC transfer setup bug
  spi: spidev: Add SPI ID table
  spi: Use 'flash' node name instead of 'spi-flash' in example
parents ccb6a666 16a8e2fb
...@@ -171,7 +171,7 @@ examples: ...@@ -171,7 +171,7 @@ examples:
cs-gpios = <&gpio0 13 0>, cs-gpios = <&gpio0 13 0>,
<&gpio0 14 0>; <&gpio0 14 0>;
rx-sample-delay-ns = <3>; rx-sample-delay-ns = <3>;
spi-flash@1 { flash@1 {
compatible = "spi-nand"; compatible = "spi-nand";
reg = <1>; reg = <1>;
rx-sample-delay-ns = <7>; rx-sample-delay-ns = <7>;
......
...@@ -1301,7 +1301,7 @@ static int atmel_spi_one_transfer(struct spi_master *master, ...@@ -1301,7 +1301,7 @@ static int atmel_spi_one_transfer(struct spi_master *master,
* DMA map early, for performance (empties dcache ASAP) and * DMA map early, for performance (empties dcache ASAP) and
* better fault reporting. * better fault reporting.
*/ */
if ((!master->cur_msg_mapped) if ((!master->cur_msg->is_dma_mapped)
&& as->use_pdc) { && as->use_pdc) {
if (atmel_spi_dma_map_xfer(as, xfer) < 0) if (atmel_spi_dma_map_xfer(as, xfer) < 0)
return -ENOMEM; return -ENOMEM;
...@@ -1381,7 +1381,7 @@ static int atmel_spi_one_transfer(struct spi_master *master, ...@@ -1381,7 +1381,7 @@ static int atmel_spi_one_transfer(struct spi_master *master,
} }
} }
if (!master->cur_msg_mapped if (!master->cur_msg->is_dma_mapped
&& as->use_pdc) && as->use_pdc)
atmel_spi_dma_unmap_xfer(master, xfer); atmel_spi_dma_unmap_xfer(master, xfer);
......
...@@ -1250,10 +1250,14 @@ static void bcm_qspi_hw_init(struct bcm_qspi *qspi) ...@@ -1250,10 +1250,14 @@ static void bcm_qspi_hw_init(struct bcm_qspi *qspi)
static void bcm_qspi_hw_uninit(struct bcm_qspi *qspi) static void bcm_qspi_hw_uninit(struct bcm_qspi *qspi)
{ {
u32 status = bcm_qspi_read(qspi, MSPI, MSPI_MSPI_STATUS);
bcm_qspi_write(qspi, MSPI, MSPI_SPCR2, 0); bcm_qspi_write(qspi, MSPI, MSPI_SPCR2, 0);
if (has_bspi(qspi)) if (has_bspi(qspi))
bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 0); bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 0);
/* clear interrupt */
bcm_qspi_write(qspi, MSPI, MSPI_MSPI_STATUS, status & ~1);
} }
static const struct spi_controller_mem_ops bcm_qspi_mem_ops = { static const struct spi_controller_mem_ops bcm_qspi_mem_ops = {
...@@ -1397,6 +1401,47 @@ int bcm_qspi_probe(struct platform_device *pdev, ...@@ -1397,6 +1401,47 @@ int bcm_qspi_probe(struct platform_device *pdev,
if (!qspi->dev_ids) if (!qspi->dev_ids)
return -ENOMEM; return -ENOMEM;
/*
* Some SoCs integrate spi controller (e.g., its interrupt bits)
* in specific ways
*/
if (soc_intc) {
qspi->soc_intc = soc_intc;
soc_intc->bcm_qspi_int_set(soc_intc, MSPI_DONE, true);
} else {
qspi->soc_intc = NULL;
}
if (qspi->clk) {
ret = clk_prepare_enable(qspi->clk);
if (ret) {
dev_err(dev, "failed to prepare clock\n");
goto qspi_probe_err;
}
qspi->base_clk = clk_get_rate(qspi->clk);
} else {
qspi->base_clk = MSPI_BASE_FREQ;
}
if (data->has_mspi_rev) {
rev = bcm_qspi_read(qspi, MSPI, MSPI_REV);
/* some older revs do not have a MSPI_REV register */
if ((rev & 0xff) == 0xff)
rev = 0;
}
qspi->mspi_maj_rev = (rev >> 4) & 0xf;
qspi->mspi_min_rev = rev & 0xf;
qspi->mspi_spcr3_sysclk = data->has_spcr3_sysclk;
qspi->max_speed_hz = qspi->base_clk / (bcm_qspi_spbr_min(qspi) * 2);
/*
* On SW resets it is possible to have the mask still enabled
* Need to disable the mask and clear the status while we init
*/
bcm_qspi_hw_uninit(qspi);
for (val = 0; val < num_irqs; val++) { for (val = 0; val < num_irqs; val++) {
irq = -1; irq = -1;
name = qspi_irq_tab[val].irq_name; name = qspi_irq_tab[val].irq_name;
...@@ -1433,38 +1478,6 @@ int bcm_qspi_probe(struct platform_device *pdev, ...@@ -1433,38 +1478,6 @@ int bcm_qspi_probe(struct platform_device *pdev,
goto qspi_probe_err; goto qspi_probe_err;
} }
/*
* Some SoCs integrate spi controller (e.g., its interrupt bits)
* in specific ways
*/
if (soc_intc) {
qspi->soc_intc = soc_intc;
soc_intc->bcm_qspi_int_set(soc_intc, MSPI_DONE, true);
} else {
qspi->soc_intc = NULL;
}
ret = clk_prepare_enable(qspi->clk);
if (ret) {
dev_err(dev, "failed to prepare clock\n");
goto qspi_probe_err;
}
qspi->base_clk = clk_get_rate(qspi->clk);
if (data->has_mspi_rev) {
rev = bcm_qspi_read(qspi, MSPI, MSPI_REV);
/* some older revs do not have a MSPI_REV register */
if ((rev & 0xff) == 0xff)
rev = 0;
}
qspi->mspi_maj_rev = (rev >> 4) & 0xf;
qspi->mspi_min_rev = rev & 0xf;
qspi->mspi_spcr3_sysclk = data->has_spcr3_sysclk;
qspi->max_speed_hz = qspi->base_clk / (bcm_qspi_spbr_min(qspi) * 2);
bcm_qspi_hw_init(qspi); bcm_qspi_hw_init(qspi);
init_completion(&qspi->mspi_done); init_completion(&qspi->mspi_done);
init_completion(&qspi->bspi_done); init_completion(&qspi->bspi_done);
......
...@@ -233,36 +233,44 @@ static int mtk_spi_set_hw_cs_timing(struct spi_device *spi) ...@@ -233,36 +233,44 @@ static int mtk_spi_set_hw_cs_timing(struct spi_device *spi)
return delay; return delay;
inactive = (delay * DIV_ROUND_UP(mdata->spi_clk_hz, 1000000)) / 1000; inactive = (delay * DIV_ROUND_UP(mdata->spi_clk_hz, 1000000)) / 1000;
setup = setup ? setup : 1; if (hold || setup) {
hold = hold ? hold : 1; reg_val = readl(mdata->base + SPI_CFG0_REG);
inactive = inactive ? inactive : 1; if (mdata->dev_comp->enhance_timing) {
if (hold) {
reg_val = readl(mdata->base + SPI_CFG0_REG); hold = min_t(u32, hold, 0x10000);
if (mdata->dev_comp->enhance_timing) { reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
hold = min_t(u32, hold, 0x10000); reg_val |= (((hold - 1) & 0xffff)
setup = min_t(u32, setup, 0x10000); << SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_HOLD_OFFSET); }
reg_val |= (((hold - 1) & 0xffff) if (setup) {
<< SPI_ADJUST_CFG0_CS_HOLD_OFFSET); setup = min_t(u32, setup, 0x10000);
reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_SETUP_OFFSET); reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
reg_val |= (((setup - 1) & 0xffff) reg_val |= (((setup - 1) & 0xffff)
<< SPI_ADJUST_CFG0_CS_SETUP_OFFSET); << SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
} else { }
hold = min_t(u32, hold, 0x100); } else {
setup = min_t(u32, setup, 0x100); if (hold) {
reg_val &= ~(0xff << SPI_CFG0_CS_HOLD_OFFSET); hold = min_t(u32, hold, 0x100);
reg_val |= (((hold - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET); reg_val &= ~(0xff << SPI_CFG0_CS_HOLD_OFFSET);
reg_val &= ~(0xff << SPI_CFG0_CS_SETUP_OFFSET); reg_val |= (((hold - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
reg_val |= (((setup - 1) & 0xff) }
<< SPI_CFG0_CS_SETUP_OFFSET); if (setup) {
setup = min_t(u32, setup, 0x100);
reg_val &= ~(0xff << SPI_CFG0_CS_SETUP_OFFSET);
reg_val |= (((setup - 1) & 0xff)
<< SPI_CFG0_CS_SETUP_OFFSET);
}
}
writel(reg_val, mdata->base + SPI_CFG0_REG);
} }
writel(reg_val, mdata->base + SPI_CFG0_REG);
inactive = min_t(u32, inactive, 0x100); if (inactive) {
reg_val = readl(mdata->base + SPI_CFG1_REG); inactive = min_t(u32, inactive, 0x100);
reg_val &= ~SPI_CFG1_CS_IDLE_MASK; reg_val = readl(mdata->base + SPI_CFG1_REG);
reg_val |= (((inactive - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET); reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
writel(reg_val, mdata->base + SPI_CFG1_REG); reg_val |= (((inactive - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET);
writel(reg_val, mdata->base + SPI_CFG1_REG);
}
return 0; return 0;
} }
......
...@@ -137,6 +137,13 @@ static int spi_mux_probe(struct spi_device *spi) ...@@ -137,6 +137,13 @@ static int spi_mux_probe(struct spi_device *spi)
priv = spi_controller_get_devdata(ctlr); priv = spi_controller_get_devdata(ctlr);
priv->spi = spi; priv->spi = spi;
/*
* Increase lockdep class as these lock are taken while the parent bus
* already holds their instance's lock.
*/
lockdep_set_subclass(&ctlr->io_mutex, 1);
lockdep_set_subclass(&ctlr->add_lock, 1);
priv->mux = devm_mux_control_get(&spi->dev, NULL); priv->mux = devm_mux_control_get(&spi->dev, NULL);
if (IS_ERR(priv->mux)) { if (IS_ERR(priv->mux)) {
ret = dev_err_probe(&spi->dev, PTR_ERR(priv->mux), ret = dev_err_probe(&spi->dev, PTR_ERR(priv->mux),
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/bitfield.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/delay.h> #include <linux/delay.h>
...@@ -315,6 +316,7 @@ ...@@ -315,6 +316,7 @@
#define NXP_FSPI_MIN_IOMAP SZ_4M #define NXP_FSPI_MIN_IOMAP SZ_4M
#define DCFG_RCWSR1 0x100 #define DCFG_RCWSR1 0x100
#define SYS_PLL_RAT GENMASK(6, 2)
/* Access flash memory using IP bus only */ /* Access flash memory using IP bus only */
#define FSPI_QUIRK_USE_IP_ONLY BIT(0) #define FSPI_QUIRK_USE_IP_ONLY BIT(0)
...@@ -926,9 +928,8 @@ static void erratum_err050568(struct nxp_fspi *f) ...@@ -926,9 +928,8 @@ static void erratum_err050568(struct nxp_fspi *f)
{ .family = "QorIQ LS1028A" }, { .family = "QorIQ LS1028A" },
{ /* sentinel */ } { /* sentinel */ }
}; };
struct device_node *np;
struct regmap *map; struct regmap *map;
u32 val = 0, sysclk = 0; u32 val, sys_pll_ratio;
int ret; int ret;
/* Check for LS1028A family */ /* Check for LS1028A family */
...@@ -937,7 +938,6 @@ static void erratum_err050568(struct nxp_fspi *f) ...@@ -937,7 +938,6 @@ static void erratum_err050568(struct nxp_fspi *f)
return; return;
} }
/* Compute system clock frequency multiplier ratio */
map = syscon_regmap_lookup_by_compatible("fsl,ls1028a-dcfg"); map = syscon_regmap_lookup_by_compatible("fsl,ls1028a-dcfg");
if (IS_ERR(map)) { if (IS_ERR(map)) {
dev_err(f->dev, "No syscon regmap\n"); dev_err(f->dev, "No syscon regmap\n");
...@@ -948,23 +948,11 @@ static void erratum_err050568(struct nxp_fspi *f) ...@@ -948,23 +948,11 @@ static void erratum_err050568(struct nxp_fspi *f)
if (ret < 0) if (ret < 0)
goto err; goto err;
/* Strap bits 6:2 define SYS_PLL_RAT i.e frequency multiplier ratio */ sys_pll_ratio = FIELD_GET(SYS_PLL_RAT, val);
val = (val >> 2) & 0x1F; dev_dbg(f->dev, "val: 0x%08x, sys_pll_ratio: %d\n", val, sys_pll_ratio);
WARN(val == 0, "Strapping is zero: Cannot determine ratio");
/* Compute system clock frequency */ /* Use IP bus only if platform clock is 300MHz */
np = of_find_node_by_name(NULL, "clock-sysclk"); if (sys_pll_ratio == 3)
if (!np)
goto err;
if (of_property_read_u32(np, "clock-frequency", &sysclk))
goto err;
sysclk = (sysclk * val) / 1000000; /* Convert sysclk to Mhz */
dev_dbg(f->dev, "val: 0x%08x, sysclk: %dMhz\n", val, sysclk);
/* Use IP bus only if PLL is 300MHz */
if (sysclk == 300)
f->devtype_data->quirks |= FSPI_QUIRK_USE_IP_ONLY; f->devtype_data->quirks |= FSPI_QUIRK_USE_IP_ONLY;
return; return;
......
...@@ -1182,8 +1182,7 @@ static int tegra_slink_resume(struct device *dev) ...@@ -1182,8 +1182,7 @@ static int tegra_slink_resume(struct device *dev)
} }
#endif #endif
#ifdef CONFIG_PM static int __maybe_unused tegra_slink_runtime_suspend(struct device *dev)
static int tegra_slink_runtime_suspend(struct device *dev)
{ {
struct spi_master *master = dev_get_drvdata(dev); struct spi_master *master = dev_get_drvdata(dev);
struct tegra_slink_data *tspi = spi_master_get_devdata(master); struct tegra_slink_data *tspi = spi_master_get_devdata(master);
...@@ -1208,7 +1207,6 @@ static int tegra_slink_runtime_resume(struct device *dev) ...@@ -1208,7 +1207,6 @@ static int tegra_slink_runtime_resume(struct device *dev)
} }
return 0; return 0;
} }
#endif /* CONFIG_PM */
static const struct dev_pm_ops slink_pm_ops = { static const struct dev_pm_ops slink_pm_ops = {
SET_RUNTIME_PM_OPS(tegra_slink_runtime_suspend, SET_RUNTIME_PM_OPS(tegra_slink_runtime_suspend,
......
...@@ -478,12 +478,6 @@ static LIST_HEAD(spi_controller_list); ...@@ -478,12 +478,6 @@ static LIST_HEAD(spi_controller_list);
*/ */
static DEFINE_MUTEX(board_lock); static DEFINE_MUTEX(board_lock);
/*
* Prevents addition of devices with same chip select and
* addition of devices below an unregistering controller.
*/
static DEFINE_MUTEX(spi_add_lock);
/** /**
* spi_alloc_device - Allocate a new SPI device * spi_alloc_device - Allocate a new SPI device
* @ctlr: Controller to which device is connected * @ctlr: Controller to which device is connected
...@@ -636,9 +630,9 @@ int spi_add_device(struct spi_device *spi) ...@@ -636,9 +630,9 @@ int spi_add_device(struct spi_device *spi)
* chipselect **BEFORE** we call setup(), else we'll trash * chipselect **BEFORE** we call setup(), else we'll trash
* its configuration. Lock against concurrent add() calls. * its configuration. Lock against concurrent add() calls.
*/ */
mutex_lock(&spi_add_lock); mutex_lock(&ctlr->add_lock);
status = __spi_add_device(spi); status = __spi_add_device(spi);
mutex_unlock(&spi_add_lock); mutex_unlock(&ctlr->add_lock);
return status; return status;
} }
EXPORT_SYMBOL_GPL(spi_add_device); EXPORT_SYMBOL_GPL(spi_add_device);
...@@ -658,7 +652,7 @@ static int spi_add_device_locked(struct spi_device *spi) ...@@ -658,7 +652,7 @@ static int spi_add_device_locked(struct spi_device *spi)
/* Set the bus ID string */ /* Set the bus ID string */
spi_dev_set_name(spi); spi_dev_set_name(spi);
WARN_ON(!mutex_is_locked(&spi_add_lock)); WARN_ON(!mutex_is_locked(&ctlr->add_lock));
return __spi_add_device(spi); return __spi_add_device(spi);
} }
...@@ -2553,6 +2547,12 @@ struct spi_controller *__spi_alloc_controller(struct device *dev, ...@@ -2553,6 +2547,12 @@ struct spi_controller *__spi_alloc_controller(struct device *dev,
return NULL; return NULL;
device_initialize(&ctlr->dev); device_initialize(&ctlr->dev);
INIT_LIST_HEAD(&ctlr->queue);
spin_lock_init(&ctlr->queue_lock);
spin_lock_init(&ctlr->bus_lock_spinlock);
mutex_init(&ctlr->bus_lock_mutex);
mutex_init(&ctlr->io_mutex);
mutex_init(&ctlr->add_lock);
ctlr->bus_num = -1; ctlr->bus_num = -1;
ctlr->num_chipselect = 1; ctlr->num_chipselect = 1;
ctlr->slave = slave; ctlr->slave = slave;
...@@ -2825,11 +2825,6 @@ int spi_register_controller(struct spi_controller *ctlr) ...@@ -2825,11 +2825,6 @@ int spi_register_controller(struct spi_controller *ctlr)
return id; return id;
ctlr->bus_num = id; ctlr->bus_num = id;
} }
INIT_LIST_HEAD(&ctlr->queue);
spin_lock_init(&ctlr->queue_lock);
spin_lock_init(&ctlr->bus_lock_spinlock);
mutex_init(&ctlr->bus_lock_mutex);
mutex_init(&ctlr->io_mutex);
ctlr->bus_lock_flag = 0; ctlr->bus_lock_flag = 0;
init_completion(&ctlr->xfer_completion); init_completion(&ctlr->xfer_completion);
if (!ctlr->max_dma_len) if (!ctlr->max_dma_len)
...@@ -2966,7 +2961,7 @@ void spi_unregister_controller(struct spi_controller *ctlr) ...@@ -2966,7 +2961,7 @@ void spi_unregister_controller(struct spi_controller *ctlr)
/* Prevent addition of new devices, unregister existing ones */ /* Prevent addition of new devices, unregister existing ones */
if (IS_ENABLED(CONFIG_SPI_DYNAMIC)) if (IS_ENABLED(CONFIG_SPI_DYNAMIC))
mutex_lock(&spi_add_lock); mutex_lock(&ctlr->add_lock);
device_for_each_child(&ctlr->dev, NULL, __unregister); device_for_each_child(&ctlr->dev, NULL, __unregister);
...@@ -2997,7 +2992,7 @@ void spi_unregister_controller(struct spi_controller *ctlr) ...@@ -2997,7 +2992,7 @@ void spi_unregister_controller(struct spi_controller *ctlr)
mutex_unlock(&board_lock); mutex_unlock(&board_lock);
if (IS_ENABLED(CONFIG_SPI_DYNAMIC)) if (IS_ENABLED(CONFIG_SPI_DYNAMIC))
mutex_unlock(&spi_add_lock); mutex_unlock(&ctlr->add_lock);
} }
EXPORT_SYMBOL_GPL(spi_unregister_controller); EXPORT_SYMBOL_GPL(spi_unregister_controller);
......
...@@ -673,6 +673,19 @@ static const struct file_operations spidev_fops = { ...@@ -673,6 +673,19 @@ static const struct file_operations spidev_fops = {
static struct class *spidev_class; static struct class *spidev_class;
static const struct spi_device_id spidev_spi_ids[] = {
{ .name = "dh2228fv" },
{ .name = "ltc2488" },
{ .name = "sx1301" },
{ .name = "bk4" },
{ .name = "dhcom-board" },
{ .name = "m53cpld" },
{ .name = "spi-petra" },
{ .name = "spi-authenta" },
{},
};
MODULE_DEVICE_TABLE(spi, spidev_spi_ids);
#ifdef CONFIG_OF #ifdef CONFIG_OF
static const struct of_device_id spidev_dt_ids[] = { static const struct of_device_id spidev_dt_ids[] = {
{ .compatible = "rohm,dh2228fv" }, { .compatible = "rohm,dh2228fv" },
...@@ -818,6 +831,7 @@ static struct spi_driver spidev_spi_driver = { ...@@ -818,6 +831,7 @@ static struct spi_driver spidev_spi_driver = {
}, },
.probe = spidev_probe, .probe = spidev_probe,
.remove = spidev_remove, .remove = spidev_remove,
.id_table = spidev_spi_ids,
/* NOTE: suspend/resume methods are not necessary here. /* NOTE: suspend/resume methods are not necessary here.
* We don't do anything except pass the requests to/from * We don't do anything except pass the requests to/from
......
...@@ -531,6 +531,9 @@ struct spi_controller { ...@@ -531,6 +531,9 @@ struct spi_controller {
/* I/O mutex */ /* I/O mutex */
struct mutex io_mutex; struct mutex io_mutex;
/* Used to avoid adding the same CS twice */
struct mutex add_lock;
/* lock and mutex for SPI bus locking */ /* lock and mutex for SPI bus locking */
spinlock_t bus_lock_spinlock; spinlock_t bus_lock_spinlock;
struct mutex bus_lock_mutex; struct mutex bus_lock_mutex;
......
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