mirror of https://gitee.com/openkylin/linux.git
spi: Fixes for v4.3
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. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJWBDUFAAoJECTWi3JdVIfQir4H/RIAsfP5QqSzjQHmeZk1eHJv FIzUiHARK5Jy3ORXVCh3dh8JB67NF9Qa4p/fDcHhk0DFju+HTyvUHmChzGPwEw86 0lRv2PKhHu9e7vJG8IZXKbZKeBT9RtrVe8yQ7SLmQ+z0VxoVFaQwkWVKotzpL8wZ YCOYGAtmxXvqWDiGuhzqG7RVLKW6vj8xz2BFqm5Gf6O32RpV9wFiNp2EtF8Hu+On sMEqFWDqMbqIwUhcPKRI9+Zhj1TkzwNUawE+EgD4ydYVndYxSpqtn1veFc1Bv1xo 1FbntlDu/AzlPqtIFBzWLZNUxcwW+qKSjOCFlyCs+k1l6CEf+AoZAm1TsL+rVTw= =3QsX -----END PGP SIGNATURE----- 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()
This commit is contained in:
commit
d5fc4f555d
|
@ -15,17 +15,18 @@ Required properties:
|
|||
- interrupts: Should contain spi interrupt
|
||||
|
||||
- clocks: phandles to input clocks.
|
||||
The first should be <&topckgen CLK_TOP_SPI_SEL>.
|
||||
The second should be one of the following.
|
||||
The first should be one of the following. It's PLL.
|
||||
- <&clk26m>: specify parent clock 26MHZ.
|
||||
- <&topckgen CLK_TOP_SYSPLL3_D2>: specify parent clock 109MHZ.
|
||||
It's the default one.
|
||||
- <&topckgen CLK_TOP_SYSPLL4_D2>: specify parent clock 78MHZ.
|
||||
- <&topckgen CLK_TOP_UNIVPLL2_D4>: specify parent clock 104MHZ.
|
||||
- <&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
|
||||
"parent-clk" for the parent clock.
|
||||
- clock-names: shall be "parent-clk" for the parent clock, "sel-clk" for the
|
||||
muxes clock, and "spi-clk" for the clock gate.
|
||||
|
||||
Optional properties:
|
||||
- mediatek,pad-select: specify which pins group(ck/mi/mo/cs) spi
|
||||
|
@ -44,8 +45,11 @@ spi: spi@1100a000 {
|
|||
#size-cells = <0>;
|
||||
reg = <0 0x1100a000 0 0x1000>;
|
||||
interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
|
||||
clocks = <&topckgen CLK_TOP_SPI_SEL>, <&topckgen CLK_TOP_SYSPLL3_D2>;
|
||||
clock-names = "spi-clk", "parent-clk";
|
||||
clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
|
||||
<&topckgen CLK_TOP_SPI_SEL>,
|
||||
<&pericfg CLK_PERI_SPI0>;
|
||||
clock-names = "parent-clk", "sel-clk", "spi-clk";
|
||||
|
||||
mediatek,pad-select = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
|
|
@ -1720,6 +1720,7 @@ static int atmel_spi_runtime_resume(struct device *dev)
|
|||
return clk_prepare_enable(as->clk);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int atmel_spi_suspend(struct device *dev)
|
||||
{
|
||||
struct spi_master *master = dev_get_drvdata(dev);
|
||||
|
@ -1756,6 +1757,7 @@ static int atmel_spi_resume(struct device *dev)
|
|||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct dev_pm_ops atmel_spi_pm_ops = {
|
||||
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,
|
|||
/* otherwise we only allow transfers within the same page
|
||||
* 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,
|
||||
"Unaligned spi tx-transfer bridging page\n");
|
||||
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,
|
||||
"Unaligned spi tx-transfer bridging page\n");
|
||||
"Unaligned spi rx-transfer bridging page\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -444,6 +444,7 @@ static const struct of_device_id meson_spifc_dt_match[] = {
|
|||
{ .compatible = "amlogic,meson6-spifc", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, meson_spifc_dt_match);
|
||||
|
||||
static struct platform_driver meson_spifc_driver = {
|
||||
.probe = meson_spifc_probe,
|
||||
|
|
|
@ -85,7 +85,7 @@ struct mtk_spi {
|
|||
void __iomem *base;
|
||||
u32 state;
|
||||
u32 pad_sel;
|
||||
struct clk *spi_clk, *parent_clk;
|
||||
struct clk *parent_clk, *sel_clk, *spi_clk;
|
||||
struct spi_transfer *cur_transfer;
|
||||
u32 xfer_len;
|
||||
struct scatterlist *tx_sgl, *rx_sgl;
|
||||
|
@ -173,22 +173,6 @@ static void mtk_spi_config(struct mtk_spi *mdata,
|
|||
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,
|
||||
struct spi_message *msg)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
reg_val = readl(mdata->base + SPI_CMD_REG);
|
||||
if (!enable)
|
||||
if (!enable) {
|
||||
reg_val |= SPI_CMD_PAUSE_EN;
|
||||
else
|
||||
writel(reg_val, mdata->base + SPI_CMD_REG);
|
||||
} else {
|
||||
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,
|
||||
|
@ -509,7 +497,6 @@ static int mtk_spi_probe(struct platform_device *pdev)
|
|||
master->mode_bits = SPI_CPOL | SPI_CPHA;
|
||||
|
||||
master->set_cs = mtk_spi_set_cs;
|
||||
master->prepare_transfer_hardware = mtk_spi_prepare_hardware;
|
||||
master->prepare_message = mtk_spi_prepare_message;
|
||||
master->transfer_one = mtk_spi_transfer_one;
|
||||
master->can_dma = mtk_spi_can_dma;
|
||||
|
@ -576,13 +563,6 @@ static int mtk_spi_probe(struct platform_device *pdev)
|
|||
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");
|
||||
if (IS_ERR(mdata->parent_clk)) {
|
||||
ret = PTR_ERR(mdata->parent_clk);
|
||||
|
@ -590,13 +570,27 @@ static int mtk_spi_probe(struct platform_device *pdev)
|
|||
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);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to enable spi_clk (%d)\n", ret);
|
||||
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) {
|
||||
dev_err(&pdev->dev, "failed to clk_set_parent (%d)\n", ret);
|
||||
goto err_disable_clk;
|
||||
|
@ -630,7 +624,6 @@ static int mtk_spi_remove(struct platform_device *pdev)
|
|||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
mtk_spi_reset(mdata);
|
||||
clk_disable_unprepare(mdata->spi_clk);
|
||||
spi_master_put(master);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -654,6 +654,10 @@ static irqreturn_t ssp_int(int irq, void *dev_id)
|
|||
if (!(sccr1_reg & SSCR1_TIE))
|
||||
mask &= ~SSSR_TFS;
|
||||
|
||||
/* Ignore RX timeout interrupt if it is disabled */
|
||||
if (!(sccr1_reg & SSCR1_TINTE))
|
||||
mask &= ~SSSR_TINT;
|
||||
|
||||
if (!(status & mask))
|
||||
return IRQ_NONE;
|
||||
|
||||
|
|
|
@ -34,13 +34,13 @@ struct xtfpga_spi {
|
|||
static inline void xtfpga_spi_write32(const struct xtfpga_spi *spi,
|
||||
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,
|
||||
unsigned addr)
|
||||
{
|
||||
return ioread32(spi->regs + addr);
|
||||
return __raw_readl(spi->regs + addr);
|
||||
}
|
||||
|
||||
static inline void xtfpga_spi_wait_busy(struct xtfpga_spi *xspi)
|
||||
|
|
|
@ -1610,8 +1610,7 @@ static struct class spi_master_class = {
|
|||
*
|
||||
* The caller is responsible for assigning the bus number and initializing
|
||||
* 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
|
||||
* leak.
|
||||
* adding the device) calling spi_master_put() to prevent a memory leak.
|
||||
*/
|
||||
struct spi_master *spi_alloc_master(struct device *dev, unsigned size)
|
||||
{
|
||||
|
|
|
@ -651,7 +651,8 @@ static int spidev_release(struct inode *inode, struct file *filp)
|
|||
kfree(spidev->rx_buffer);
|
||||
spidev->rx_buffer = NULL;
|
||||
|
||||
spidev->speed_hz = spidev->spi->max_speed_hz;
|
||||
if (spidev->spi)
|
||||
spidev->speed_hz = spidev->spi->max_speed_hz;
|
||||
|
||||
/* ... after we unbound from the underlying device? */
|
||||
spin_lock_irq(&spidev->spi_lock);
|
||||
|
|
|
@ -34,7 +34,7 @@ extern struct bus_type spi_bus_type;
|
|||
|
||||
/**
|
||||
* struct spi_statistics - statistics for spi transfers
|
||||
* @clock: lock protecting this structure
|
||||
* @lock: lock protecting this structure
|
||||
*
|
||||
* @messages: number of spi-messages handled
|
||||
* @transfers: number of spi_transfers handled
|
||||
|
|
Loading…
Reference in New Issue