Commit d5fc4f55 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'spi-fix-v4.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi

Pull spi fixes from Mark Brown:
 "A disappointingly large collection of fixes for SPI issues, though
  almost all in drivers (and there mainly the newly added Mediatek
  driver) and the core fixes are documentation and error handling.

  The driver fixes are all of the usual 'important if you see them'
  variety"

* tag 'spi-fix-v4.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi: xtensa-xtfpga: fix register endianness
  spi: meson: Fix module autoload for OF platform driver
  spi: mediatek: fix wrong error return value on probe
  spi: fix kernel-doc warnings in spi.h
  spi: spidev: fix possible NULL dereference
  spi: atmel: remove warning when !CONFIG_PM_SLEEP
  spi: bcm2835: BUG: fix wrong use of PAGE_MASK
  spi: mediatek: fix spi cs polarity error
  spi: Fix documentation of spi_alloc_master()
  spi: spi-pxa2xx: Check status register to determine if SSSR_TINT is disabled
  spi: Mediatek: Document devicetree bindings update for spi bus
  spi: mediatek: fix spi clock usage error
  spi: mediatek: remove clk_disable_unprepare()
parents bbad8220 711e020c
...@@ -15,17 +15,18 @@ Required properties: ...@@ -15,17 +15,18 @@ Required properties:
- interrupts: Should contain spi interrupt - interrupts: Should contain spi interrupt
- clocks: phandles to input clocks. - clocks: phandles to input clocks.
The first should be <&topckgen CLK_TOP_SPI_SEL>. The first should be one of the following. It's PLL.
The second should be one of the following.
- <&clk26m>: specify parent clock 26MHZ. - <&clk26m>: specify parent clock 26MHZ.
- <&topckgen CLK_TOP_SYSPLL3_D2>: specify parent clock 109MHZ. - <&topckgen CLK_TOP_SYSPLL3_D2>: specify parent clock 109MHZ.
It's the default one. It's the default one.
- <&topckgen CLK_TOP_SYSPLL4_D2>: specify parent clock 78MHZ. - <&topckgen CLK_TOP_SYSPLL4_D2>: specify parent clock 78MHZ.
- <&topckgen CLK_TOP_UNIVPLL2_D4>: specify parent clock 104MHZ. - <&topckgen CLK_TOP_UNIVPLL2_D4>: specify parent clock 104MHZ.
- <&topckgen CLK_TOP_UNIVPLL1_D8>: specify parent clock 78MHZ. - <&topckgen CLK_TOP_UNIVPLL1_D8>: specify parent clock 78MHZ.
The second should be <&topckgen CLK_TOP_SPI_SEL>. It's clock mux.
The third is <&pericfg CLK_PERI_SPI0>. It's clock gate.
- clock-names: shall be "spi-clk" for the controller clock, and - clock-names: shall be "parent-clk" for the parent clock, "sel-clk" for the
"parent-clk" for the parent clock. muxes clock, and "spi-clk" for the clock gate.
Optional properties: Optional properties:
- mediatek,pad-select: specify which pins group(ck/mi/mo/cs) spi - mediatek,pad-select: specify which pins group(ck/mi/mo/cs) spi
...@@ -44,8 +45,11 @@ spi: spi@1100a000 { ...@@ -44,8 +45,11 @@ spi: spi@1100a000 {
#size-cells = <0>; #size-cells = <0>;
reg = <0 0x1100a000 0 0x1000>; reg = <0 0x1100a000 0 0x1000>;
interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>; interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
clocks = <&topckgen CLK_TOP_SPI_SEL>, <&topckgen CLK_TOP_SYSPLL3_D2>; clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
clock-names = "spi-clk", "parent-clk"; <&topckgen CLK_TOP_SPI_SEL>,
<&pericfg CLK_PERI_SPI0>;
clock-names = "parent-clk", "sel-clk", "spi-clk";
mediatek,pad-select = <0>; mediatek,pad-select = <0>;
status = "disabled"; status = "disabled";
}; };
...@@ -1720,6 +1720,7 @@ static int atmel_spi_runtime_resume(struct device *dev) ...@@ -1720,6 +1720,7 @@ static int atmel_spi_runtime_resume(struct device *dev)
return clk_prepare_enable(as->clk); return clk_prepare_enable(as->clk);
} }
#ifdef CONFIG_PM_SLEEP
static int atmel_spi_suspend(struct device *dev) static int atmel_spi_suspend(struct device *dev)
{ {
struct spi_master *master = dev_get_drvdata(dev); struct spi_master *master = dev_get_drvdata(dev);
...@@ -1756,6 +1757,7 @@ static int atmel_spi_resume(struct device *dev) ...@@ -1756,6 +1757,7 @@ static int atmel_spi_resume(struct device *dev)
return ret; return ret;
} }
#endif
static const struct dev_pm_ops atmel_spi_pm_ops = { static const struct dev_pm_ops atmel_spi_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(atmel_spi_suspend, atmel_spi_resume) SET_SYSTEM_SLEEP_PM_OPS(atmel_spi_suspend, atmel_spi_resume)
......
...@@ -386,14 +386,14 @@ static bool bcm2835_spi_can_dma(struct spi_master *master, ...@@ -386,14 +386,14 @@ static bool bcm2835_spi_can_dma(struct spi_master *master,
/* otherwise we only allow transfers within the same page /* otherwise we only allow transfers within the same page
* to avoid wasting time on dma_mapping when it is not practical * to avoid wasting time on dma_mapping when it is not practical
*/ */
if (((size_t)tfr->tx_buf & PAGE_MASK) + tfr->len > PAGE_SIZE) { if (((size_t)tfr->tx_buf & (PAGE_SIZE - 1)) + tfr->len > PAGE_SIZE) {
dev_warn_once(&spi->dev, dev_warn_once(&spi->dev,
"Unaligned spi tx-transfer bridging page\n"); "Unaligned spi tx-transfer bridging page\n");
return false; return false;
} }
if (((size_t)tfr->rx_buf & PAGE_MASK) + tfr->len > PAGE_SIZE) { if (((size_t)tfr->rx_buf & (PAGE_SIZE - 1)) + tfr->len > PAGE_SIZE) {
dev_warn_once(&spi->dev, dev_warn_once(&spi->dev,
"Unaligned spi tx-transfer bridging page\n"); "Unaligned spi rx-transfer bridging page\n");
return false; return false;
} }
......
...@@ -444,6 +444,7 @@ static const struct of_device_id meson_spifc_dt_match[] = { ...@@ -444,6 +444,7 @@ static const struct of_device_id meson_spifc_dt_match[] = {
{ .compatible = "amlogic,meson6-spifc", }, { .compatible = "amlogic,meson6-spifc", },
{ }, { },
}; };
MODULE_DEVICE_TABLE(of, meson_spifc_dt_match);
static struct platform_driver meson_spifc_driver = { static struct platform_driver meson_spifc_driver = {
.probe = meson_spifc_probe, .probe = meson_spifc_probe,
......
...@@ -85,7 +85,7 @@ struct mtk_spi { ...@@ -85,7 +85,7 @@ struct mtk_spi {
void __iomem *base; void __iomem *base;
u32 state; u32 state;
u32 pad_sel; u32 pad_sel;
struct clk *spi_clk, *parent_clk; struct clk *parent_clk, *sel_clk, *spi_clk;
struct spi_transfer *cur_transfer; struct spi_transfer *cur_transfer;
u32 xfer_len; u32 xfer_len;
struct scatterlist *tx_sgl, *rx_sgl; struct scatterlist *tx_sgl, *rx_sgl;
...@@ -173,22 +173,6 @@ static void mtk_spi_config(struct mtk_spi *mdata, ...@@ -173,22 +173,6 @@ static void mtk_spi_config(struct mtk_spi *mdata,
writel(mdata->pad_sel, mdata->base + SPI_PAD_SEL_REG); writel(mdata->pad_sel, mdata->base + SPI_PAD_SEL_REG);
} }
static int mtk_spi_prepare_hardware(struct spi_master *master)
{
struct spi_transfer *trans;
struct mtk_spi *mdata = spi_master_get_devdata(master);
struct spi_message *msg = master->cur_msg;
trans = list_first_entry(&msg->transfers, struct spi_transfer,
transfer_list);
if (!trans->cs_change) {
mdata->state = MTK_SPI_IDLE;
mtk_spi_reset(mdata);
}
return 0;
}
static int mtk_spi_prepare_message(struct spi_master *master, static int mtk_spi_prepare_message(struct spi_master *master,
struct spi_message *msg) struct spi_message *msg)
{ {
...@@ -228,11 +212,15 @@ static void mtk_spi_set_cs(struct spi_device *spi, bool enable) ...@@ -228,11 +212,15 @@ static void mtk_spi_set_cs(struct spi_device *spi, bool enable)
struct mtk_spi *mdata = spi_master_get_devdata(spi->master); struct mtk_spi *mdata = spi_master_get_devdata(spi->master);
reg_val = readl(mdata->base + SPI_CMD_REG); reg_val = readl(mdata->base + SPI_CMD_REG);
if (!enable) if (!enable) {
reg_val |= SPI_CMD_PAUSE_EN; reg_val |= SPI_CMD_PAUSE_EN;
else writel(reg_val, mdata->base + SPI_CMD_REG);
} else {
reg_val &= ~SPI_CMD_PAUSE_EN; reg_val &= ~SPI_CMD_PAUSE_EN;
writel(reg_val, mdata->base + SPI_CMD_REG); writel(reg_val, mdata->base + SPI_CMD_REG);
mdata->state = MTK_SPI_IDLE;
mtk_spi_reset(mdata);
}
} }
static void mtk_spi_prepare_transfer(struct spi_master *master, static void mtk_spi_prepare_transfer(struct spi_master *master,
...@@ -509,7 +497,6 @@ static int mtk_spi_probe(struct platform_device *pdev) ...@@ -509,7 +497,6 @@ static int mtk_spi_probe(struct platform_device *pdev)
master->mode_bits = SPI_CPOL | SPI_CPHA; master->mode_bits = SPI_CPOL | SPI_CPHA;
master->set_cs = mtk_spi_set_cs; master->set_cs = mtk_spi_set_cs;
master->prepare_transfer_hardware = mtk_spi_prepare_hardware;
master->prepare_message = mtk_spi_prepare_message; master->prepare_message = mtk_spi_prepare_message;
master->transfer_one = mtk_spi_transfer_one; master->transfer_one = mtk_spi_transfer_one;
master->can_dma = mtk_spi_can_dma; master->can_dma = mtk_spi_can_dma;
...@@ -576,13 +563,6 @@ static int mtk_spi_probe(struct platform_device *pdev) ...@@ -576,13 +563,6 @@ static int mtk_spi_probe(struct platform_device *pdev)
goto err_put_master; goto err_put_master;
} }
mdata->spi_clk = devm_clk_get(&pdev->dev, "spi-clk");
if (IS_ERR(mdata->spi_clk)) {
ret = PTR_ERR(mdata->spi_clk);
dev_err(&pdev->dev, "failed to get spi-clk: %d\n", ret);
goto err_put_master;
}
mdata->parent_clk = devm_clk_get(&pdev->dev, "parent-clk"); mdata->parent_clk = devm_clk_get(&pdev->dev, "parent-clk");
if (IS_ERR(mdata->parent_clk)) { if (IS_ERR(mdata->parent_clk)) {
ret = PTR_ERR(mdata->parent_clk); ret = PTR_ERR(mdata->parent_clk);
...@@ -590,13 +570,27 @@ static int mtk_spi_probe(struct platform_device *pdev) ...@@ -590,13 +570,27 @@ static int mtk_spi_probe(struct platform_device *pdev)
goto err_put_master; goto err_put_master;
} }
mdata->sel_clk = devm_clk_get(&pdev->dev, "sel-clk");
if (IS_ERR(mdata->sel_clk)) {
ret = PTR_ERR(mdata->sel_clk);
dev_err(&pdev->dev, "failed to get sel-clk: %d\n", ret);
goto err_put_master;
}
mdata->spi_clk = devm_clk_get(&pdev->dev, "spi-clk");
if (IS_ERR(mdata->spi_clk)) {
ret = PTR_ERR(mdata->spi_clk);
dev_err(&pdev->dev, "failed to get spi-clk: %d\n", ret);
goto err_put_master;
}
ret = clk_prepare_enable(mdata->spi_clk); ret = clk_prepare_enable(mdata->spi_clk);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "failed to enable spi_clk (%d)\n", ret); dev_err(&pdev->dev, "failed to enable spi_clk (%d)\n", ret);
goto err_put_master; goto err_put_master;
} }
ret = clk_set_parent(mdata->spi_clk, mdata->parent_clk); ret = clk_set_parent(mdata->sel_clk, mdata->parent_clk);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "failed to clk_set_parent (%d)\n", ret); dev_err(&pdev->dev, "failed to clk_set_parent (%d)\n", ret);
goto err_disable_clk; goto err_disable_clk;
...@@ -630,7 +624,6 @@ static int mtk_spi_remove(struct platform_device *pdev) ...@@ -630,7 +624,6 @@ static int mtk_spi_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
mtk_spi_reset(mdata); mtk_spi_reset(mdata);
clk_disable_unprepare(mdata->spi_clk);
spi_master_put(master); spi_master_put(master);
return 0; return 0;
......
...@@ -654,6 +654,10 @@ static irqreturn_t ssp_int(int irq, void *dev_id) ...@@ -654,6 +654,10 @@ static irqreturn_t ssp_int(int irq, void *dev_id)
if (!(sccr1_reg & SSCR1_TIE)) if (!(sccr1_reg & SSCR1_TIE))
mask &= ~SSSR_TFS; mask &= ~SSSR_TFS;
/* Ignore RX timeout interrupt if it is disabled */
if (!(sccr1_reg & SSCR1_TINTE))
mask &= ~SSSR_TINT;
if (!(status & mask)) if (!(status & mask))
return IRQ_NONE; return IRQ_NONE;
......
...@@ -34,13 +34,13 @@ struct xtfpga_spi { ...@@ -34,13 +34,13 @@ struct xtfpga_spi {
static inline void xtfpga_spi_write32(const struct xtfpga_spi *spi, static inline void xtfpga_spi_write32(const struct xtfpga_spi *spi,
unsigned addr, u32 val) unsigned addr, u32 val)
{ {
iowrite32(val, spi->regs + addr); __raw_writel(val, spi->regs + addr);
} }
static inline unsigned int xtfpga_spi_read32(const struct xtfpga_spi *spi, static inline unsigned int xtfpga_spi_read32(const struct xtfpga_spi *spi,
unsigned addr) unsigned addr)
{ {
return ioread32(spi->regs + addr); return __raw_readl(spi->regs + addr);
} }
static inline void xtfpga_spi_wait_busy(struct xtfpga_spi *xspi) static inline void xtfpga_spi_wait_busy(struct xtfpga_spi *xspi)
......
...@@ -1610,8 +1610,7 @@ static struct class spi_master_class = { ...@@ -1610,8 +1610,7 @@ static struct class spi_master_class = {
* *
* The caller is responsible for assigning the bus number and initializing * The caller is responsible for assigning the bus number and initializing
* the master's methods before calling spi_register_master(); and (after errors * the master's methods before calling spi_register_master(); and (after errors
* adding the device) calling spi_master_put() and kfree() to prevent a memory * adding the device) calling spi_master_put() to prevent a memory leak.
* leak.
*/ */
struct spi_master *spi_alloc_master(struct device *dev, unsigned size) struct spi_master *spi_alloc_master(struct device *dev, unsigned size)
{ {
......
...@@ -651,6 +651,7 @@ static int spidev_release(struct inode *inode, struct file *filp) ...@@ -651,6 +651,7 @@ static int spidev_release(struct inode *inode, struct file *filp)
kfree(spidev->rx_buffer); kfree(spidev->rx_buffer);
spidev->rx_buffer = NULL; spidev->rx_buffer = NULL;
if (spidev->spi)
spidev->speed_hz = spidev->spi->max_speed_hz; spidev->speed_hz = spidev->spi->max_speed_hz;
/* ... after we unbound from the underlying device? */ /* ... after we unbound from the underlying device? */
......
...@@ -34,7 +34,7 @@ extern struct bus_type spi_bus_type; ...@@ -34,7 +34,7 @@ extern struct bus_type spi_bus_type;
/** /**
* struct spi_statistics - statistics for spi transfers * struct spi_statistics - statistics for spi transfers
* @clock: lock protecting this structure * @lock: lock protecting this structure
* *
* @messages: number of spi-messages handled * @messages: number of spi-messages handled
* @transfers: number of spi_transfers handled * @transfers: number of spi_transfers handled
......
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