This is a retake of this set [1]. The patches are destined to 4.19.y and have been applied and compiled to 4.19.86. All the content in this set is already in 5.3.y.
Thanks, Mathieu
[1]. https://lkml.org/lkml/2019/11/15/1105
Alexandre Torgue (1): pinctrl: stm32: fix memory leak issue
Arnaud Pouliquen (1): mailbox: stm32_ipcc: add spinlock to fix channels concurrent access
Fabien Dessenne (1): mailbox: mailbox-test: fix null pointer if no mmio
Gabriel Fernandez (4): clk: stm32mp1: fix HSI divider flag clk: stm32mp1: fix mcu divider table clk: stm32mp1: add CLK_SET_RATE_NO_REPARENT to Kernel clocks clk: stm32mp1: parent clocks update
Hugues Fruchet (2): media: stm32-dcmi: fix DMA corruption when stopping streaming media: stm32-dcmi: fix check of pm_runtime_get_sync return value
Lionel Debieve (2): crypto: stm31/hash - Fix hmac issue more than 256 bytes hwrng: stm32 - fix unbalanced pm_runtime_enable
Loic Pallardy (1): remoteproc: fix rproc_da_to_va in case of unallocated carveout
Olivier Moysan (3): ASoC: stm32: i2s: fix dma configuration ASoC: stm32: i2s: fix 16 bit format support ASoC: stm32: i2s: fix IRQ clearing
Pierre-Yves MORDRET (1): dmaengine: stm32-dma: check whether length is aligned on FIFO threshold
Wen Yang (1): ASoC: stm32: sai: add missing put_device()
drivers/char/hw_random/stm32-rng.c | 8 +++++ drivers/clk/clk-stm32mp1.c | 28 +++++++++-------- drivers/crypto/stm32/stm32-hash.c | 2 +- drivers/dma/stm32-dma.c | 20 ++++-------- drivers/mailbox/mailbox-test.c | 14 +++++---- drivers/mailbox/stm32-ipcc.c | 37 +++++++++++++++++------ drivers/media/platform/stm32/stm32-dcmi.c | 23 ++++++++++++-- drivers/pinctrl/stm32/pinctrl-stm32.c | 26 ++++++++++------ drivers/remoteproc/remoteproc_core.c | 4 +++ sound/soc/stm/stm32_i2s.c | 29 +++++++++--------- sound/soc/stm/stm32_sai.c | 11 +++++-- 11 files changed, 127 insertions(+), 75 deletions(-)
From: Arnaud Pouliquen arnaud.pouliquen@st.com
commit dba9a3dfe912dc47c9dbc9ba1f5f65adbf9aea0f upstream
Add spinlock protection on IPCC register update to avoid race condition. Without this fix, stm32_ipcc_set_bits and stm32_ipcc_clr_bits can be called in parallel for different channels. This results in register corruptions.
Signed-off-by: Arnaud Pouliquen arnaud.pouliquen@st.com Reviewed-by: Fabien Dessenne fabien.dessenne@st.com Signed-off-by: Jassi Brar jaswinder.singh@linaro.org Cc: stable stable@vger.kernel.org # 4.19 Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- drivers/mailbox/stm32-ipcc.c | 37 ++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-)
diff --git a/drivers/mailbox/stm32-ipcc.c b/drivers/mailbox/stm32-ipcc.c index ca1f993c0de3..e31322225e93 100644 --- a/drivers/mailbox/stm32-ipcc.c +++ b/drivers/mailbox/stm32-ipcc.c @@ -50,6 +50,7 @@ struct stm32_ipcc { void __iomem *reg_base; void __iomem *reg_proc; struct clk *clk; + spinlock_t lock; /* protect access to IPCC registers */ int irqs[IPCC_IRQ_NUM]; int wkp; u32 proc_id; @@ -58,14 +59,24 @@ struct stm32_ipcc { u32 xmr; };
-static inline void stm32_ipcc_set_bits(void __iomem *reg, u32 mask) +static inline void stm32_ipcc_set_bits(spinlock_t *lock, void __iomem *reg, + u32 mask) { + unsigned long flags; + + spin_lock_irqsave(lock, flags); writel_relaxed(readl_relaxed(reg) | mask, reg); + spin_unlock_irqrestore(lock, flags); }
-static inline void stm32_ipcc_clr_bits(void __iomem *reg, u32 mask) +static inline void stm32_ipcc_clr_bits(spinlock_t *lock, void __iomem *reg, + u32 mask) { + unsigned long flags; + + spin_lock_irqsave(lock, flags); writel_relaxed(readl_relaxed(reg) & ~mask, reg); + spin_unlock_irqrestore(lock, flags); }
static irqreturn_t stm32_ipcc_rx_irq(int irq, void *data) @@ -92,7 +103,7 @@ static irqreturn_t stm32_ipcc_rx_irq(int irq, void *data)
mbox_chan_received_data(&ipcc->controller.chans[chan], NULL);
- stm32_ipcc_set_bits(ipcc->reg_proc + IPCC_XSCR, + stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XSCR, RX_BIT_CHAN(chan));
ret = IRQ_HANDLED; @@ -121,7 +132,7 @@ static irqreturn_t stm32_ipcc_tx_irq(int irq, void *data) dev_dbg(dev, "%s: chan:%d tx\n", __func__, chan);
/* mask 'tx channel free' interrupt */ - stm32_ipcc_set_bits(ipcc->reg_proc + IPCC_XMR, + stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XMR, TX_BIT_CHAN(chan));
mbox_chan_txdone(&ipcc->controller.chans[chan], 0); @@ -141,10 +152,12 @@ static int stm32_ipcc_send_data(struct mbox_chan *link, void *data) dev_dbg(ipcc->controller.dev, "%s: chan:%d\n", __func__, chan);
/* set channel n occupied */ - stm32_ipcc_set_bits(ipcc->reg_proc + IPCC_XSCR, TX_BIT_CHAN(chan)); + stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XSCR, + TX_BIT_CHAN(chan));
/* unmask 'tx channel free' interrupt */ - stm32_ipcc_clr_bits(ipcc->reg_proc + IPCC_XMR, TX_BIT_CHAN(chan)); + stm32_ipcc_clr_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XMR, + TX_BIT_CHAN(chan));
return 0; } @@ -163,7 +176,8 @@ static int stm32_ipcc_startup(struct mbox_chan *link) }
/* unmask 'rx channel occupied' interrupt */ - stm32_ipcc_clr_bits(ipcc->reg_proc + IPCC_XMR, RX_BIT_CHAN(chan)); + stm32_ipcc_clr_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XMR, + RX_BIT_CHAN(chan));
return 0; } @@ -175,7 +189,7 @@ static void stm32_ipcc_shutdown(struct mbox_chan *link) controller);
/* mask rx/tx interrupt */ - stm32_ipcc_set_bits(ipcc->reg_proc + IPCC_XMR, + stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XMR, RX_BIT_CHAN(chan) | TX_BIT_CHAN(chan));
clk_disable_unprepare(ipcc->clk); @@ -208,6 +222,8 @@ static int stm32_ipcc_probe(struct platform_device *pdev) if (!ipcc) return -ENOMEM;
+ spin_lock_init(&ipcc->lock); + /* proc_id */ if (of_property_read_u32(np, "st,proc-id", &ipcc->proc_id)) { dev_err(dev, "Missing st,proc-id\n"); @@ -259,9 +275,10 @@ static int stm32_ipcc_probe(struct platform_device *pdev) }
/* mask and enable rx/tx irq */ - stm32_ipcc_set_bits(ipcc->reg_proc + IPCC_XMR, + stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XMR, RX_BIT_MASK | TX_BIT_MASK); - stm32_ipcc_set_bits(ipcc->reg_proc + IPCC_XCR, XCR_RXOIE | XCR_TXOIE); + stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XCR, + XCR_RXOIE | XCR_TXOIE);
/* wakeup */ if (of_property_read_bool(np, "wakeup-source")) {
From: Lionel Debieve lionel.debieve@st.com
commit 0acabecebc912b3ba06289e4ef40476acc499a37 upstream
Correct condition for the second hmac loop. Key must be only set in the first loop. Initial condition was wrong, HMAC_KEY flag was not properly checked.
Signed-off-by: Lionel Debieve lionel.debieve@st.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Cc: stable stable@vger.kernel.org # 4.19 Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- drivers/crypto/stm32/stm32-hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/crypto/stm32/stm32-hash.c b/drivers/crypto/stm32/stm32-hash.c index 590d7352837e..641b11077f47 100644 --- a/drivers/crypto/stm32/stm32-hash.c +++ b/drivers/crypto/stm32/stm32-hash.c @@ -365,7 +365,7 @@ static int stm32_hash_xmit_cpu(struct stm32_hash_dev *hdev, return -ETIMEDOUT;
if ((hdev->flags & HASH_FLAGS_HMAC) && - (hdev->flags & ~HASH_FLAGS_HMAC_KEY)) { + (!(hdev->flags & HASH_FLAGS_HMAC_KEY))) { hdev->flags |= HASH_FLAGS_HMAC_KEY; stm32_hash_write_key(hdev); if (stm32_hash_wait_busy(hdev))
From: Hugues Fruchet hugues.fruchet@st.com
commit b3ce6f6ff3c260ee53b0f2236e5fd950d46957da upstream
Avoid call of dmaengine_terminate_all() between dmaengine_prep_slave_single() and dmaengine_submit() by locking the whole DMA submission sequence.
Signed-off-by: Hugues Fruchet hugues.fruchet@st.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Cc: stable stable@vger.kernel.org # 4.19 Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- drivers/media/platform/stm32/stm32-dcmi.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c index 1d9c028e52cb..d86944109cbf 100644 --- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c @@ -164,6 +164,9 @@ struct stm32_dcmi { int errors_count; int overrun_count; int buffers_count; + + /* Ensure DMA operations atomicity */ + struct mutex dma_lock; };
static inline struct stm32_dcmi *notifier_to_dcmi(struct v4l2_async_notifier *n) @@ -314,6 +317,13 @@ static int dcmi_start_dma(struct stm32_dcmi *dcmi, return ret; }
+ /* + * Avoid call of dmaengine_terminate_all() between + * dmaengine_prep_slave_single() and dmaengine_submit() + * by locking the whole DMA submission sequence + */ + mutex_lock(&dcmi->dma_lock); + /* Prepare a DMA transaction */ desc = dmaengine_prep_slave_single(dcmi->dma_chan, buf->paddr, buf->size, @@ -322,6 +332,7 @@ static int dcmi_start_dma(struct stm32_dcmi *dcmi, if (!desc) { dev_err(dcmi->dev, "%s: DMA dmaengine_prep_slave_single failed for buffer phy=%pad size=%zu\n", __func__, &buf->paddr, buf->size); + mutex_unlock(&dcmi->dma_lock); return -EINVAL; }
@@ -333,9 +344,12 @@ static int dcmi_start_dma(struct stm32_dcmi *dcmi, dcmi->dma_cookie = dmaengine_submit(desc); if (dma_submit_error(dcmi->dma_cookie)) { dev_err(dcmi->dev, "%s: DMA submission failed\n", __func__); + mutex_unlock(&dcmi->dma_lock); return -ENXIO; }
+ mutex_unlock(&dcmi->dma_lock); + dma_async_issue_pending(dcmi->dma_chan);
return 0; @@ -717,7 +731,9 @@ static void dcmi_stop_streaming(struct vb2_queue *vq) spin_unlock_irq(&dcmi->irqlock);
/* Stop all pending DMA operations */ + mutex_lock(&dcmi->dma_lock); dmaengine_terminate_all(dcmi->dma_chan); + mutex_unlock(&dcmi->dma_lock);
pm_runtime_put(dcmi->dev);
@@ -1719,6 +1735,7 @@ static int dcmi_probe(struct platform_device *pdev)
spin_lock_init(&dcmi->irqlock); mutex_init(&dcmi->lock); + mutex_init(&dcmi->dma_lock); init_completion(&dcmi->complete); INIT_LIST_HEAD(&dcmi->buffers);
From: Hugues Fruchet hugues.fruchet@st.com
commit ab41b99e7e55c85f29ff7b54718ccbbe051905e7 upstream
Start streaming was sometimes failing because of pm_runtime_get_sync() non-0 return value. In fact return value was not an error but a positive value (1), indicating that PM was already enabled. Fix this by going to error path only with negative return value.
Signed-off-by: Hugues Fruchet hugues.fruchet@st.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Cc: stable stable@vger.kernel.org # 4.19 Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- drivers/media/platform/stm32/stm32-dcmi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c index d86944109cbf..18d0b5641789 100644 --- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c @@ -584,9 +584,9 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) int ret;
ret = pm_runtime_get_sync(dcmi->dev); - if (ret) { - dev_err(dcmi->dev, "%s: Failed to start streaming, cannot get sync\n", - __func__); + if (ret < 0) { + dev_err(dcmi->dev, "%s: Failed to start streaming, cannot get sync (%d)\n", + __func__, ret); goto err_release_buffers; }
From: Lionel Debieve lionel.debieve@st.com
commit af0d4442dd6813de6e77309063beb064fa8e89ae upstream
No remove function implemented yet in the driver. Without remove function, the pm_runtime implementation complains when removing and probing again the driver.
Signed-off-by: Lionel Debieve lionel.debieve@st.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Cc: stable stable@vger.kernel.org # 4.19 Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- drivers/char/hw_random/stm32-rng.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/char/hw_random/stm32-rng.c b/drivers/char/hw_random/stm32-rng.c index 042860d97b15..37b338a76ba4 100644 --- a/drivers/char/hw_random/stm32-rng.c +++ b/drivers/char/hw_random/stm32-rng.c @@ -169,6 +169,13 @@ static int stm32_rng_probe(struct platform_device *ofdev) return devm_hwrng_register(dev, &priv->rng); }
+static int stm32_rng_remove(struct platform_device *ofdev) +{ + pm_runtime_disable(&ofdev->dev); + + return 0; +} + #ifdef CONFIG_PM static int stm32_rng_runtime_suspend(struct device *dev) { @@ -210,6 +217,7 @@ static struct platform_driver stm32_rng_driver = { .of_match_table = stm32_rng_match, }, .probe = stm32_rng_probe, + .remove = stm32_rng_remove, };
module_platform_driver(stm32_rng_driver);
From: Loic Pallardy loic.pallardy@st.com
commit 74457c40f97a98142bb13153395d304ad3c85cdd upstream
With introduction of rproc_alloc_registered_carveouts() which delays carveout allocation just before the start of the remote processor, rproc_da_to_va() could be called before all carveouts are allocated. This patch adds a check in rproc_da_to_va() to return NULL if carveout is not allocated.
Fixes: d7c51706d095 ("remoteproc: add alloc ops in rproc_mem_entry struct")
Signed-off-by: Loic Pallardy loic.pallardy@st.com Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Cc: stable stable@vger.kernel.org # 4.19 Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- drivers/remoteproc/remoteproc_core.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index aa6206706fe3..af9d443e7796 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -183,6 +183,10 @@ void *rproc_da_to_va(struct rproc *rproc, u64 da, int len) list_for_each_entry(carveout, &rproc->carveouts, node) { int offset = da - carveout->da;
+ /* Verify that carveout is allocated */ + if (!carveout->va) + continue; + /* try next carveout if da is too small */ if (offset < 0) continue;
On Thu, Nov 28, 2019 at 09:49:51AM -0700, Mathieu Poirier wrote:
From: Loic Pallardy loic.pallardy@st.com
commit 74457c40f97a98142bb13153395d304ad3c85cdd upstream
With introduction of rproc_alloc_registered_carveouts() which delays carveout allocation just before the start of the remote processor, rproc_da_to_va() could be called before all carveouts are allocated. This patch adds a check in rproc_da_to_va() to return NULL if carveout is not allocated.
Fixes: d7c51706d095 ("remoteproc: add alloc ops in rproc_mem_entry struct")
This commit only shows up in 4.20, not 4.19, so why is this patch relevant for 4.19?
thanks,
greg k-h
On Tue, 3 Dec 2019 at 12:43, Greg KH gregkh@linuxfoundation.org wrote:
On Thu, Nov 28, 2019 at 09:49:51AM -0700, Mathieu Poirier wrote:
From: Loic Pallardy loic.pallardy@st.com
commit 74457c40f97a98142bb13153395d304ad3c85cdd upstream
With introduction of rproc_alloc_registered_carveouts() which delays carveout allocation just before the start of the remote processor, rproc_da_to_va() could be called before all carveouts are allocated. This patch adds a check in rproc_da_to_va() to return NULL if carveout is not allocated.
Fixes: d7c51706d095 ("remoteproc: add alloc ops in rproc_mem_entry struct")
This commit only shows up in 4.20, not 4.19, so why is this patch relevant for 4.19?
Your scripts are better than mine...
thanks,
greg k-h
From: Gabriel Fernandez gabriel.fernandez@st.com
commit d3f2e33c875de5052e032a9eefa64c897a930ed1 upstream
The divider of HSI (clk-hsi-div) is power of two divider.
Fixes: 9bee94e7b7da ("clk: stm32mp1: Introduce STM32MP1 clock driver") Signed-off-by: Gabriel Fernandez gabriel.fernandez@st.com Signed-off-by: Stephen Boyd sboyd@kernel.org Cc: stable stable@vger.kernel.org # 4.19 Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- drivers/clk/clk-stm32mp1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c index a907555b2a3d..d602ae72eb81 100644 --- a/drivers/clk/clk-stm32mp1.c +++ b/drivers/clk/clk-stm32mp1.c @@ -1655,8 +1655,8 @@ static const struct stm32_mux_cfg ker_mux_cfg[M_LAST] = {
static const struct clock_config stm32mp1_clock_cfg[] = { /* Oscillator divider */ - DIV(NO_ID, "clk-hsi-div", "clk-hsi", 0, RCC_HSICFGR, 0, 2, - CLK_DIVIDER_READ_ONLY), + DIV(NO_ID, "clk-hsi-div", "clk-hsi", CLK_DIVIDER_POWER_OF_TWO, + RCC_HSICFGR, 0, 2, CLK_DIVIDER_READ_ONLY),
/* External / Internal Oscillators */ GATE_MP1(CK_HSE, "ck_hse", "clk-hse", 0, RCC_OCENSETR, 8, 0),
From: Gabriel Fernandez gabriel.fernandez@st.com
commit 140fc4e406fac420b978a0ef2ee1fe3c641a6ae4 upstream
index 8: ck_mcu is divided by 256 (not 512)
Fixes: e51d297e9a92 ("clk: stm32mp1: add Sub System clocks") Signed-off-by: Gabriel Fernandez gabriel.fernandez@st.com Signed-off-by: Stephen Boyd sboyd@kernel.org Cc: stable stable@vger.kernel.org # 4.19 Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- drivers/clk/clk-stm32mp1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c index d602ae72eb81..851fb4e9ac44 100644 --- a/drivers/clk/clk-stm32mp1.c +++ b/drivers/clk/clk-stm32mp1.c @@ -269,7 +269,7 @@ static const struct clk_div_table axi_div_table[] = { static const struct clk_div_table mcu_div_table[] = { { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 }, { 4, 16 }, { 5, 32 }, { 6, 64 }, { 7, 128 }, - { 8, 512 }, { 9, 512 }, { 10, 512}, { 11, 512 }, + { 8, 256 }, { 9, 512 }, { 10, 512}, { 11, 512 }, { 12, 512 }, { 13, 512 }, { 14, 512}, { 15, 512 }, { 0 }, };
From: Gabriel Fernandez gabriel.fernandez@st.com
commit 72cfd1ad1057f16fc614861b3c271597995e57ba upstream
STM32MP1 clock IP offers lots of Kernel clocks that are shared by multiple IP's at the same time. Then boot loader applies a clock tree that allows to use all IP's at same time and with the maximum of performance. Not change parents on a change rate on kernel clocks ensures the integrity of the system.
Signed-off-by: Gabriel Fernandez gabriel.fernandez@st.com Signed-off-by: Stephen Boyd sboyd@kernel.org Cc: stable stable@vger.kernel.org # 4.19 Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- drivers/clk/clk-stm32mp1.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c index 851fb4e9ac44..8e25ed62f67b 100644 --- a/drivers/clk/clk-stm32mp1.c +++ b/drivers/clk/clk-stm32mp1.c @@ -1286,10 +1286,11 @@ _clk_stm32_register_composite(struct device *dev, MGATE_MP1(_id, _name, _parent, _flags, _mgate)
#define KCLK(_id, _name, _parents, _flags, _mgate, _mmux)\ - COMPOSITE(_id, _name, _parents, CLK_OPS_PARENT_ENABLE | _flags,\ - _MGATE_MP1(_mgate),\ - _MMUX(_mmux),\ - _NO_DIV) + COMPOSITE(_id, _name, _parents, CLK_OPS_PARENT_ENABLE |\ + CLK_SET_RATE_NO_REPARENT | _flags,\ + _MGATE_MP1(_mgate),\ + _MMUX(_mmux),\ + _NO_DIV)
enum { G_SAI1, @@ -1952,7 +1953,8 @@ static const struct clock_config stm32mp1_clock_cfg[] = { MGATE_MP1(GPU_K, "gpu_k", "pll2_q", 0, G_GPU), MGATE_MP1(DAC12_K, "dac12_k", "ck_lsi", 0, G_DAC12),
- COMPOSITE(ETHPTP_K, "ethptp_k", eth_src, CLK_OPS_PARENT_ENABLE, + COMPOSITE(ETHPTP_K, "ethptp_k", eth_src, CLK_OPS_PARENT_ENABLE | + CLK_SET_RATE_NO_REPARENT, _NO_GATE, _MMUX(M_ETHCK), _DIV(RCC_ETHCKSELR, 4, 4, CLK_DIVIDER_ALLOW_ZERO, NULL)),
From: Gabriel Fernandez gabriel.fernandez@st.com
commit 749c9e553e1f063eb132a78d80225532cbfedb80 upstream
Fixes parent clock for axi, fdcan, sai and adc12 clocks.
Fixes: e51d297e9a92 ("clk: stm32mp1: add Sub System clocks") Signed-off-by: Gabriel Fernandez gabriel.fernandez@st.com Signed-off-by: Stephen Boyd sboyd@kernel.org Cc: stable stable@vger.kernel.org # 4.19 Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- drivers/clk/clk-stm32mp1.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c index 8e25ed62f67b..bf3b6a4c78d0 100644 --- a/drivers/clk/clk-stm32mp1.c +++ b/drivers/clk/clk-stm32mp1.c @@ -121,7 +121,7 @@ static const char * const cpu_src[] = { };
static const char * const axi_src[] = { - "ck_hsi", "ck_hse", "pll2_p", "pll3_p" + "ck_hsi", "ck_hse", "pll2_p" };
static const char * const per_src[] = { @@ -225,19 +225,19 @@ static const char * const usart6_src[] = { };
static const char * const fdcan_src[] = { - "ck_hse", "pll3_q", "pll4_q" + "ck_hse", "pll3_q", "pll4_q", "pll4_r" };
static const char * const sai_src[] = { - "pll4_q", "pll3_q", "i2s_ckin", "ck_per" + "pll4_q", "pll3_q", "i2s_ckin", "ck_per", "pll3_r" };
static const char * const sai2_src[] = { - "pll4_q", "pll3_q", "i2s_ckin", "ck_per", "spdif_ck_symb" + "pll4_q", "pll3_q", "i2s_ckin", "ck_per", "spdif_ck_symb", "pll3_r" };
static const char * const adc12_src[] = { - "pll4_q", "ck_per" + "pll4_r", "ck_per", "pll3_q" };
static const char * const dsi_src[] = {
From: Fabien Dessenne fabien.dessenne@st.com
commit 6899b4f7c99c72968e58e502f96084f74f6e5e86 upstream
Fix null pointer issue if resource_size is called with no ioresource.
Signed-off-by: Ludovic Barre ludovic.barre@st.com Signed-off-by: Fabien Dessenne fabien.dessenne@st.com Signed-off-by: Jassi Brar jaswinder.singh@linaro.org Cc: stable stable@vger.kernel.org # 4.19 Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- drivers/mailbox/mailbox-test.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c index 58bfafc34bc4..129b3656c453 100644 --- a/drivers/mailbox/mailbox-test.c +++ b/drivers/mailbox/mailbox-test.c @@ -363,22 +363,24 @@ static int mbox_test_probe(struct platform_device *pdev)
/* It's okay for MMIO to be NULL */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - size = resource_size(res); tdev->tx_mmio = devm_ioremap_resource(&pdev->dev, res); - if (PTR_ERR(tdev->tx_mmio) == -EBUSY) + if (PTR_ERR(tdev->tx_mmio) == -EBUSY) { /* if reserved area in SRAM, try just ioremap */ + size = resource_size(res); tdev->tx_mmio = devm_ioremap(&pdev->dev, res->start, size); - else if (IS_ERR(tdev->tx_mmio)) + } else if (IS_ERR(tdev->tx_mmio)) { tdev->tx_mmio = NULL; + }
/* If specified, second reg entry is Rx MMIO */ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - size = resource_size(res); tdev->rx_mmio = devm_ioremap_resource(&pdev->dev, res); - if (PTR_ERR(tdev->rx_mmio) == -EBUSY) + if (PTR_ERR(tdev->rx_mmio) == -EBUSY) { + size = resource_size(res); tdev->rx_mmio = devm_ioremap(&pdev->dev, res->start, size); - else if (IS_ERR(tdev->rx_mmio)) + } else if (IS_ERR(tdev->rx_mmio)) { tdev->rx_mmio = tdev->tx_mmio; + }
tdev->tx_channel = mbox_test_request_channel(pdev, "tx"); tdev->rx_channel = mbox_test_request_channel(pdev, "rx");
From: Alexandre Torgue alexandre.torgue@st.com
commit cd8c9b5a49576bf28990237715bc2cb2210ac80a upstream
configs is allocated by pinconf_generic_parse_dt_config(), pinctrl_utils_add_map_configs() duplicates configs so it can and has to be freed to prevent memory leaks.
Signed-off-by: Alexandre Torgue alexandre.torgue@st.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Cc: stable stable@vger.kernel.org # 4.19 Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- drivers/pinctrl/stm32/pinctrl-stm32.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index a9bec6e6fdd1..14dfbbd6c1c3 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -410,7 +410,7 @@ static int stm32_pctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, unsigned int num_configs; bool has_config = 0; unsigned reserve = 0; - int num_pins, num_funcs, maps_per_pin, i, err; + int num_pins, num_funcs, maps_per_pin, i, err = 0;
pctl = pinctrl_dev_get_drvdata(pctldev);
@@ -437,41 +437,45 @@ static int stm32_pctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, if (has_config && num_pins >= 1) maps_per_pin++;
- if (!num_pins || !maps_per_pin) - return -EINVAL; + if (!num_pins || !maps_per_pin) { + err = -EINVAL; + goto exit; + }
reserve = num_pins * maps_per_pin;
err = pinctrl_utils_reserve_map(pctldev, map, reserved_maps, num_maps, reserve); if (err) - return err; + goto exit;
for (i = 0; i < num_pins; i++) { err = of_property_read_u32_index(node, "pinmux", i, &pinfunc); if (err) - return err; + goto exit;
pin = STM32_GET_PIN_NO(pinfunc); func = STM32_GET_PIN_FUNC(pinfunc);
if (!stm32_pctrl_is_function_valid(pctl, pin, func)) { dev_err(pctl->dev, "invalid function.\n"); - return -EINVAL; + err = -EINVAL; + goto exit; }
grp = stm32_pctrl_find_group_by_pin(pctl, pin); if (!grp) { dev_err(pctl->dev, "unable to match pin %d to group\n", pin); - return -EINVAL; + err = -EINVAL; + goto exit; }
err = stm32_pctrl_dt_node_to_map_func(pctl, pin, func, grp, map, reserved_maps, num_maps); if (err) - return err; + goto exit;
if (has_config) { err = pinctrl_utils_add_map_configs(pctldev, map, @@ -479,11 +483,13 @@ static int stm32_pctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, configs, num_configs, PIN_MAP_TYPE_CONFIGS_GROUP); if (err) - return err; + goto exit; } }
- return 0; +exit: + kfree(configs); + return err; }
static int stm32_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
From: Olivier Moysan olivier.moysan@st.com
commit 1ac2bd16448997d9ec01922423486e1e85535eda upstream
DMA configuration is not balanced on start/stop. Move DMA configuration to trigger callback.
Signed-off-by: Olivier Moysan olivier.moysan@st.com Signed-off-by: Mark Brown broonie@kernel.org Cc: stable stable@vger.kernel.org # 4.19 Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- sound/soc/stm/stm32_i2s.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c index 6d0bf78d114d..449bb7049a28 100644 --- a/sound/soc/stm/stm32_i2s.c +++ b/sound/soc/stm/stm32_i2s.c @@ -488,7 +488,7 @@ static int stm32_i2s_configure(struct snd_soc_dai *cpu_dai, { struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai); int format = params_width(params); - u32 cfgr, cfgr_mask, cfg1, cfg1_mask; + u32 cfgr, cfgr_mask, cfg1; unsigned int fthlv; int ret;
@@ -529,15 +529,11 @@ static int stm32_i2s_configure(struct snd_soc_dai *cpu_dai, if (ret < 0) return ret;
- cfg1 = I2S_CFG1_RXDMAEN | I2S_CFG1_TXDMAEN; - cfg1_mask = cfg1; - fthlv = STM32_I2S_FIFO_SIZE * I2S_FIFO_TH_ONE_QUARTER / 4; - cfg1 |= I2S_CFG1_FTHVL_SET(fthlv - 1); - cfg1_mask |= I2S_CFG1_FTHVL_MASK; + cfg1 = I2S_CFG1_FTHVL_SET(fthlv - 1);
return regmap_update_bits(i2s->regmap, STM32_I2S_CFG1_REG, - cfg1_mask, cfg1); + I2S_CFG1_FTHVL_MASK, cfg1); }
static int stm32_i2s_startup(struct snd_pcm_substream *substream, @@ -589,6 +585,10 @@ static int stm32_i2s_trigger(struct snd_pcm_substream *substream, int cmd, /* Enable i2s */ dev_dbg(cpu_dai->dev, "start I2S\n");
+ cfg1_mask = I2S_CFG1_RXDMAEN | I2S_CFG1_TXDMAEN; + regmap_update_bits(i2s->regmap, STM32_I2S_CFG1_REG, + cfg1_mask, cfg1_mask); + ret = regmap_update_bits(i2s->regmap, STM32_I2S_CR1_REG, I2S_CR1_SPE, I2S_CR1_SPE); if (ret < 0) {
From: Olivier Moysan olivier.moysan@st.com
commit 0c4c68d6fa1bae74d450e50823c24fcc3cd0b171 upstream
I2S supports 16 bits data in 32 channel length. However the expected driver behavior, is to set channel length to 16 bits when data format is 16 bits.
Signed-off-by: Olivier Moysan olivier.moysan@st.com Signed-off-by: Mark Brown broonie@kernel.org Cc: stable stable@vger.kernel.org # 4.19 Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- sound/soc/stm/stm32_i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c index 449bb7049a28..004d83091505 100644 --- a/sound/soc/stm/stm32_i2s.c +++ b/sound/soc/stm/stm32_i2s.c @@ -501,7 +501,7 @@ static int stm32_i2s_configure(struct snd_soc_dai *cpu_dai, switch (format) { case 16: cfgr = I2S_CGFR_DATLEN_SET(I2S_I2SMOD_DATLEN_16); - cfgr_mask = I2S_CGFR_DATLEN_MASK; + cfgr_mask = I2S_CGFR_DATLEN_MASK | I2S_CGFR_CHLEN; break; case 32: cfgr = I2S_CGFR_DATLEN_SET(I2S_I2SMOD_DATLEN_32) |
From: Olivier Moysan olivier.moysan@st.com
commit 8ba3c5215d69c09f5c39783ff3b78347769822ad upstream
Because of regmap cache, interrupts may not be cleared as expected. Declare IFCR register as write only and make writings to IFCR register unconditional.
Signed-off-by: Olivier Moysan olivier.moysan@st.com Signed-off-by: Mark Brown broonie@kernel.org Cc: stable stable@vger.kernel.org # 4.19 Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- sound/soc/stm/stm32_i2s.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c index 004d83091505..aa2b1196171a 100644 --- a/sound/soc/stm/stm32_i2s.c +++ b/sound/soc/stm/stm32_i2s.c @@ -246,8 +246,8 @@ static irqreturn_t stm32_i2s_isr(int irq, void *devid) return IRQ_NONE; }
- regmap_update_bits(i2s->regmap, STM32_I2S_IFCR_REG, - I2S_IFCR_MASK, flags); + regmap_write_bits(i2s->regmap, STM32_I2S_IFCR_REG, + I2S_IFCR_MASK, flags);
if (flags & I2S_SR_OVR) { dev_dbg(&pdev->dev, "Overrun\n"); @@ -276,7 +276,6 @@ static bool stm32_i2s_readable_reg(struct device *dev, unsigned int reg) case STM32_I2S_CFG2_REG: case STM32_I2S_IER_REG: case STM32_I2S_SR_REG: - case STM32_I2S_IFCR_REG: case STM32_I2S_TXDR_REG: case STM32_I2S_RXDR_REG: case STM32_I2S_CGFR_REG: @@ -547,8 +546,8 @@ static int stm32_i2s_startup(struct snd_pcm_substream *substream, i2s->refcount++; spin_unlock(&i2s->lock_fd);
- return regmap_update_bits(i2s->regmap, STM32_I2S_IFCR_REG, - I2S_IFCR_MASK, I2S_IFCR_MASK); + return regmap_write_bits(i2s->regmap, STM32_I2S_IFCR_REG, + I2S_IFCR_MASK, I2S_IFCR_MASK); }
static int stm32_i2s_hw_params(struct snd_pcm_substream *substream, @@ -603,8 +602,8 @@ static int stm32_i2s_trigger(struct snd_pcm_substream *substream, int cmd, return ret; }
- regmap_update_bits(i2s->regmap, STM32_I2S_IFCR_REG, - I2S_IFCR_MASK, I2S_IFCR_MASK); + regmap_write_bits(i2s->regmap, STM32_I2S_IFCR_REG, + I2S_IFCR_MASK, I2S_IFCR_MASK);
if (playback_flg) { ier = I2S_IER_UDRIE;
From: Wen Yang yellowriver2010@hotmail.com
commit 1c3816a194870e7a6622345dab7fb56c7d708613 upstream
The of_find_device_by_node() takes a reference to the underlying device structure, we should release that reference.
Fixes: 7dd0d835582f ("ASoC: stm32: sai: simplify sync modes management") Signed-off-by: Wen Yang yellowriver2010@hotmail.com Acked-by: Olivier Moysan olivier.moysan@st.com Signed-off-by: Mark Brown broonie@kernel.org Cc: stable stable@vger.kernel.org # 4.19 Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- sound/soc/stm/stm32_sai.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/sound/soc/stm/stm32_sai.c b/sound/soc/stm/stm32_sai.c index f22654253c43..540c4a00405c 100644 --- a/sound/soc/stm/stm32_sai.c +++ b/sound/soc/stm/stm32_sai.c @@ -112,16 +112,21 @@ static int stm32_sai_set_sync(struct stm32_sai_data *sai_client, if (!sai_provider) { dev_err(&sai_client->pdev->dev, "SAI sync provider data not found\n"); - return -EINVAL; + ret = -EINVAL; + goto out_put_dev; }
/* Configure sync client */ ret = stm32_sai_sync_conf_client(sai_client, synci); if (ret < 0) - return ret; + goto out_put_dev;
/* Configure sync provider */ - return stm32_sai_sync_conf_provider(sai_provider, synco); + ret = stm32_sai_sync_conf_provider(sai_provider, synco); + +out_put_dev: + put_device(&pdev->dev); + return ret; }
static int stm32_sai_probe(struct platform_device *pdev)
From: Pierre-Yves MORDRET pierre-yves.mordret@st.com
commit cc832dc8e32785a730ba07c3a357e17c201a5df8 upstream
When a period length is not multiple of FIFO some data may be stuck within FIFO.
Burst/FIFO Threshold/Period or buffer length check has to be hardened
In any case DMA will grant any request from client but will degraded any parameters whether awkward.
Signed-off-by: Pierre-Yves MORDRET pierre-yves.mordret@st.com Signed-off-by: Vinod Koul vkoul@kernel.org Cc: stable stable@vger.kernel.org # 4.19 Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org --- drivers/dma/stm32-dma.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-)
diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c index 379e8d534e61..4903a408fc14 100644 --- a/drivers/dma/stm32-dma.c +++ b/drivers/dma/stm32-dma.c @@ -308,20 +308,12 @@ static bool stm32_dma_fifo_threshold_is_allowed(u32 burst, u32 threshold,
static bool stm32_dma_is_burst_possible(u32 buf_len, u32 threshold) { - switch (threshold) { - case STM32_DMA_FIFO_THRESHOLD_FULL: - if (buf_len >= STM32_DMA_MAX_BURST) - return true; - else - return false; - case STM32_DMA_FIFO_THRESHOLD_HALFFULL: - if (buf_len >= STM32_DMA_MAX_BURST / 2) - return true; - else - return false; - default: - return false; - } + /* + * Buffer or period length has to be aligned on FIFO depth. + * Otherwise bytes may be stuck within FIFO at buffer or period + * length. + */ + return ((buf_len % ((threshold + 1) * 4)) == 0); }
static u32 stm32_dma_get_best_burst(u32 buf_len, u32 max_burst, u32 threshold,
linux-stable-mirror@lists.linaro.org