From 827e0920dbfb0d92416e56081d70745597403446 Mon Sep 17 00:00:00 2001 From: Benedikt Niedermayr Date: Fri, 9 Dec 2022 12:28:28 +0100 Subject: memory: omap-gpmc: fix wait pin validation This bug has been introduced after switching from -1 to UINT_MAX for GPMC_WAITPIN_INVALID. The bug leads to an error when the optional gpmc,wait-pin dt-property is not used: ... gpmc_cs_program_settings: invalid wait-pin (-1) ... Signed-off-by: Benedikt Niedermayr Fixes: 8dd7e4af5853 ("memory: omap-gpmc: fix coverity issue "Control flow issues"") Acked-by: Roger Quadros Tested-by: Tony Lindgren Link: https://lore.kernel.org/r/20221209112828.581491-1-benedikt.niedermayr@siemens.com Signed-off-by: Krzysztof Kozlowski --- drivers/memory/omap-gpmc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index 57d9f91fe89b..d78f73db37c8 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c @@ -1918,7 +1918,8 @@ int gpmc_cs_program_settings(int cs, struct gpmc_settings *p) } } - if (p->wait_pin > gpmc_nr_waitpins) { + if (p->wait_pin != GPMC_WAITPIN_INVALID && + p->wait_pin > gpmc_nr_waitpins) { pr_err("%s: invalid wait-pin (%d)\n", __func__, p->wait_pin); return -EINVAL; } -- cgit v1.2.3 From ef86b2c2807f41c045e5534d8513a8b83f63bc39 Mon Sep 17 00:00:00 2001 From: Ashish Mhetre Date: Fri, 25 Nov 2022 09:37:52 +0530 Subject: memory: tegra: Remove clients SID override programming On newer Tegra releases, early boot SID override programming and SID override programming during resume is handled by bootloader. In the function tegra186_mc_program_sid() which is getting removed, SID override register of all clients is written without checking if secure firmware has allowed write on it or not. If write is disabled by secure firmware then it can lead to errors coming from secure firmware and hang in kernel boot. Also, SID override is programmed on-demand during probe_finalize() call of IOMMU which is done in tegra186_mc_client_sid_override() in this same file. This function does it correctly by checking if write is permitted on SID override register. It also checks if SID override register is already written with correct value and skips re-writing it in that case. Fixes: 393d66fd2cac ("memory: tegra: Implement SID override programming") Signed-off-by: Ashish Mhetre Acked-by: Thierry Reding Link: https://lore.kernel.org/r/20221125040752.12627-1-amhetre@nvidia.com Signed-off-by: Krzysztof Kozlowski --- drivers/memory/tegra/tegra186.c | 36 ------------------------------------ 1 file changed, 36 deletions(-) (limited to 'drivers') diff --git a/drivers/memory/tegra/tegra186.c b/drivers/memory/tegra/tegra186.c index 62477e592bf5..7bb73f06fad3 100644 --- a/drivers/memory/tegra/tegra186.c +++ b/drivers/memory/tegra/tegra186.c @@ -22,32 +22,6 @@ #define MC_SID_STREAMID_SECURITY_WRITE_ACCESS_DISABLED BIT(16) #define MC_SID_STREAMID_SECURITY_OVERRIDE BIT(8) -static void tegra186_mc_program_sid(struct tegra_mc *mc) -{ - unsigned int i; - - for (i = 0; i < mc->soc->num_clients; i++) { - const struct tegra_mc_client *client = &mc->soc->clients[i]; - u32 override, security; - - override = readl(mc->regs + client->regs.sid.override); - security = readl(mc->regs + client->regs.sid.security); - - dev_dbg(mc->dev, "client %s: override: %x security: %x\n", - client->name, override, security); - - dev_dbg(mc->dev, "setting SID %u for %s\n", client->sid, - client->name); - writel(client->sid, mc->regs + client->regs.sid.override); - - override = readl(mc->regs + client->regs.sid.override); - security = readl(mc->regs + client->regs.sid.security); - - dev_dbg(mc->dev, "client %s: override: %x security: %x\n", - client->name, override, security); - } -} - static int tegra186_mc_probe(struct tegra_mc *mc) { struct platform_device *pdev = to_platform_device(mc->dev); @@ -85,8 +59,6 @@ populate: if (err < 0) return err; - tegra186_mc_program_sid(mc); - return 0; } @@ -95,13 +67,6 @@ static void tegra186_mc_remove(struct tegra_mc *mc) of_platform_depopulate(mc->dev); } -static int tegra186_mc_resume(struct tegra_mc *mc) -{ - tegra186_mc_program_sid(mc); - - return 0; -} - #if IS_ENABLED(CONFIG_IOMMU_API) static void tegra186_mc_client_sid_override(struct tegra_mc *mc, const struct tegra_mc_client *client, @@ -173,7 +138,6 @@ static int tegra186_mc_probe_device(struct tegra_mc *mc, struct device *dev) const struct tegra_mc_ops tegra186_mc_ops = { .probe = tegra186_mc_probe, .remove = tegra186_mc_remove, - .resume = tegra186_mc_resume, .probe_device = tegra186_mc_probe_device, .handle_irq = tegra30_mc_handle_irq, }; -- cgit v1.2.3 From 340cb392a038cf70540a4cdf2e98a247c66b6df4 Mon Sep 17 00:00:00 2001 From: Gaosheng Cui Date: Fri, 25 Nov 2022 15:37:57 +0800 Subject: memory: atmel-sdramc: Fix missing clk_disable_unprepare in atmel_ramc_probe() The clk_disable_unprepare() should be called in the error handling of caps->has_mpddr_clk, fix it by replacing devm_clk_get and clk_prepare_enable by devm_clk_get_enabled. Fixes: e81b6abebc87 ("memory: add a driver for atmel ram controllers") Signed-off-by: Gaosheng Cui Link: https://lore.kernel.org/r/20221125073757.3535219-1-cuigaosheng1@huawei.com Signed-off-by: Krzysztof Kozlowski --- drivers/memory/atmel-sdramc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/memory/atmel-sdramc.c b/drivers/memory/atmel-sdramc.c index 9c49d00c2a96..ea6e9e1eaf04 100644 --- a/drivers/memory/atmel-sdramc.c +++ b/drivers/memory/atmel-sdramc.c @@ -47,19 +47,17 @@ static int atmel_ramc_probe(struct platform_device *pdev) caps = of_device_get_match_data(&pdev->dev); if (caps->has_ddrck) { - clk = devm_clk_get(&pdev->dev, "ddrck"); + clk = devm_clk_get_enabled(&pdev->dev, "ddrck"); if (IS_ERR(clk)) return PTR_ERR(clk); - clk_prepare_enable(clk); } if (caps->has_mpddr_clk) { - clk = devm_clk_get(&pdev->dev, "mpddr"); + clk = devm_clk_get_enabled(&pdev->dev, "mpddr"); if (IS_ERR(clk)) { pr_err("AT91 RAMC: couldn't get mpddr clock\n"); return PTR_ERR(clk); } - clk_prepare_enable(clk); } return 0; -- cgit v1.2.3 From cb8fd6f75775165390ededea8799b60d93d9fe3e Mon Sep 17 00:00:00 2001 From: Gaosheng Cui Date: Sat, 26 Nov 2022 12:49:11 +0800 Subject: memory: mvebu-devbus: Fix missing clk_disable_unprepare in mvebu_devbus_probe() The clk_disable_unprepare() should be called in the error handling of devbus_get_timing_params() and of_platform_populate(), fix it by replacing devm_clk_get and clk_prepare_enable by devm_clk_get_enabled. Fixes: e81b6abebc87 ("memory: add a driver for atmel ram controllers") Signed-off-by: Gaosheng Cui Link: https://lore.kernel.org/r/20221126044911.7226-1-cuigaosheng1@huawei.com Signed-off-by: Krzysztof Kozlowski --- drivers/memory/mvebu-devbus.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/memory/mvebu-devbus.c b/drivers/memory/mvebu-devbus.c index 8450638e8670..efc6c08db2b7 100644 --- a/drivers/memory/mvebu-devbus.c +++ b/drivers/memory/mvebu-devbus.c @@ -280,10 +280,9 @@ static int mvebu_devbus_probe(struct platform_device *pdev) if (IS_ERR(devbus->base)) return PTR_ERR(devbus->base); - clk = devm_clk_get(&pdev->dev, NULL); + clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(clk)) return PTR_ERR(clk); - clk_prepare_enable(clk); /* * Obtain clock period in picoseconds, -- cgit v1.2.3 From b814eda949c324791580003303aa608761cfde3f Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Sat, 31 Dec 2022 13:40:25 +0800 Subject: soc: imx: imx8mp-blk-ctrl: enable global pixclk with HDMI_TX_PHY PD NXP internal information shows that the PHY refclk is gated by the GLOBAL_TX_PIX_CLK_EN bit, so to allow the PHY PLL to lock without the LCDIF being already active, tie this bit to the HDMI_TX_PHY power domain. Fixes: e3442022f543 ("soc: imx: add i.MX8MP HDMI blk-ctrl") Signed-off-by: Lucas Stach Signed-off-by: Shawn Guo --- drivers/soc/imx/imx8mp-blk-ctrl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/soc/imx/imx8mp-blk-ctrl.c b/drivers/soc/imx/imx8mp-blk-ctrl.c index 0e3b6ba22f94..9852714eb2a4 100644 --- a/drivers/soc/imx/imx8mp-blk-ctrl.c +++ b/drivers/soc/imx/imx8mp-blk-ctrl.c @@ -212,7 +212,7 @@ static void imx8mp_hdmi_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc, break; case IMX8MP_HDMIBLK_PD_LCDIF: regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL0, - BIT(7) | BIT(16) | BIT(17) | BIT(18) | + BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20)); regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(11)); regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, @@ -241,6 +241,7 @@ static void imx8mp_hdmi_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc, regmap_set_bits(bc->regmap, HDMI_TX_CONTROL0, BIT(1)); break; case IMX8MP_HDMIBLK_PD_HDMI_TX_PHY: + regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(7)); regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(22) | BIT(24)); regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(12)); regmap_clear_bits(bc->regmap, HDMI_TX_CONTROL0, BIT(3)); @@ -270,7 +271,7 @@ static void imx8mp_hdmi_blk_ctrl_power_off(struct imx8mp_blk_ctrl *bc, BIT(4) | BIT(5) | BIT(6)); regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(11)); regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL0, - BIT(7) | BIT(16) | BIT(17) | BIT(18) | + BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20)); break; case IMX8MP_HDMIBLK_PD_PAI: @@ -298,6 +299,7 @@ static void imx8mp_hdmi_blk_ctrl_power_off(struct imx8mp_blk_ctrl *bc, case IMX8MP_HDMIBLK_PD_HDMI_TX_PHY: regmap_set_bits(bc->regmap, HDMI_TX_CONTROL0, BIT(3)); regmap_clear_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(12)); + regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(7)); regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(22) | BIT(24)); break; case IMX8MP_HDMIBLK_PD_HDCP: -- cgit v1.2.3 From 21b84ebeee79d91e405f87f051e9489ef30ecad6 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 26 Aug 2022 21:13:03 +0200 Subject: soc: imx: imx8mp-blk-ctrl: don't set power device name Setting the device name after it has been registered confuses the sysfs cleanup paths. This has already been fixed for the imx8m-blk-ctrl driver in b64b46fbaa1d ("Revert "soc: imx: imx8m-blk-ctrl: set power device name""), but the same problem exists in imx8mp-blk-ctrl. Fixes: 556f5cf9568a ("soc: imx: add i.MX8MP HSIO blk-ctrl") Signed-off-by: Lucas Stach Reviewed-by: Peng Fan Signed-off-by: Shawn Guo --- drivers/soc/imx/imx8mp-blk-ctrl.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/soc/imx/imx8mp-blk-ctrl.c b/drivers/soc/imx/imx8mp-blk-ctrl.c index 9852714eb2a4..0f13853901df 100644 --- a/drivers/soc/imx/imx8mp-blk-ctrl.c +++ b/drivers/soc/imx/imx8mp-blk-ctrl.c @@ -592,7 +592,6 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev) ret = PTR_ERR(domain->power_dev); goto cleanup_pds; } - dev_set_name(domain->power_dev, "%s", data->name); domain->genpd.name = data->name; domain->genpd.power_on = imx8mp_blk_ctrl_power_on; -- cgit v1.2.3 From 490748874ebf1875420fc29b335bba2075dd1b5e Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Sat, 31 Dec 2022 13:58:48 +0400 Subject: soc: imx8m: Fix incorrect check for of_clk_get_by_name() of_clk_get_by_name() returns error pointers instead of NULL. Use IS_ERR() checks the return value to catch errors. Fixes: 836fb30949d9 ("soc: imx8m: Enable OCOTP clock before reading the register") Signed-off-by: Miaoqian Lin Signed-off-by: Shawn Guo --- drivers/soc/imx/soc-imx8m.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/soc/imx/soc-imx8m.c b/drivers/soc/imx/soc-imx8m.c index 28144c699b0c..32ed9dc88e45 100644 --- a/drivers/soc/imx/soc-imx8m.c +++ b/drivers/soc/imx/soc-imx8m.c @@ -66,8 +66,8 @@ static u32 __init imx8mq_soc_revision(void) ocotp_base = of_iomap(np, 0); WARN_ON(!ocotp_base); clk = of_clk_get_by_name(np, NULL); - if (!clk) { - WARN_ON(!clk); + if (IS_ERR(clk)) { + WARN_ON(IS_ERR(clk)); return 0; } -- cgit v1.2.3 From 13678f3feb3009b23aab424864fd0dac0765c83e Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 29 Oct 2022 22:56:36 -0700 Subject: reset: ti-sci: honor TI_SCI_PROTOCOL setting when not COMPILE_TEST There is a build error when COMPILE_TEST=y, TI_SCI_PROTOCOL=m, and RESET_TI_SCI=y: drivers/reset/reset-ti-sci.o: in function `ti_sci_reset_probe': reset-ti-sci.c:(.text+0x22c): undefined reference to `devm_ti_sci_get_handle' Fix this by making RESET_TI_SCI honor the Kconfig setting of TI_SCI_PROTOCOL when COMPILE_TEST is not set. When COMPILE_TEST is set, TI_SCI_PROTOCOL must be disabled (=n). Fixes: a6af504184c9 ("reset: ti-sci: Allow building under COMPILE_TEST") Signed-off-by: Randy Dunlap Reported-by: kernel test robot Cc: Nishanth Menon Cc: Tero Kristo Cc: Santosh Shilimkar Cc: linux-arm-kernel@lists.infradead.org Cc: Philipp Zabel Reviewed-by: Nishanth Menon Link: https://lore.kernel.org/r/20221030055636.3139-1-rdunlap@infradead.org Signed-off-by: Philipp Zabel --- drivers/reset/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index de176c2fbad9..2a52c990d4fe 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -257,7 +257,7 @@ config RESET_SUNXI config RESET_TI_SCI tristate "TI System Control Interface (TI-SCI) reset driver" - depends on TI_SCI_PROTOCOL || COMPILE_TEST + depends on TI_SCI_PROTOCOL || (COMPILE_TEST && TI_SCI_PROTOCOL=n) help This enables the reset driver support over TI System Control Interface available on some new TI's SoCs. If you wish to use reset resources -- cgit v1.2.3 From 3a2390c6777e3f6662980c6cfc25cafe9e4fef98 Mon Sep 17 00:00:00 2001 From: Hui Tang Date: Mon, 14 Nov 2022 08:49:58 +0800 Subject: reset: uniphier-glue: Fix possible null-ptr-deref It will cause null-ptr-deref when resource_size(res) invoked, if platform_get_resource() returns NULL. Fixes: 499fef09a323 ("reset: uniphier: add USB3 core reset control") Signed-off-by: Hui Tang Reviewed-by: Kunihiko Hayashi Link: https://lore.kernel.org/r/20221114004958.258513-1-tanghui20@huawei.com Signed-off-by: Philipp Zabel --- drivers/reset/reset-uniphier-glue.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/reset/reset-uniphier-glue.c b/drivers/reset/reset-uniphier-glue.c index 146fd5d45e99..15abac9fc72c 100644 --- a/drivers/reset/reset-uniphier-glue.c +++ b/drivers/reset/reset-uniphier-glue.c @@ -47,7 +47,6 @@ static int uniphier_glue_reset_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct uniphier_glue_reset_priv *priv; struct resource *res; - resource_size_t size; int i, ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -60,7 +59,6 @@ static int uniphier_glue_reset_probe(struct platform_device *pdev) return -EINVAL; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - size = resource_size(res); priv->rdata.membase = devm_ioremap_resource(dev, res); if (IS_ERR(priv->rdata.membase)) return PTR_ERR(priv->rdata.membase); @@ -96,7 +94,7 @@ static int uniphier_glue_reset_probe(struct platform_device *pdev) spin_lock_init(&priv->rdata.lock); priv->rdata.rcdev.owner = THIS_MODULE; - priv->rdata.rcdev.nr_resets = size * BITS_PER_BYTE; + priv->rdata.rcdev.nr_resets = resource_size(res) * BITS_PER_BYTE; priv->rdata.rcdev.ops = &reset_simple_ops; priv->rdata.rcdev.of_node = dev->of_node; priv->rdata.active_low = true; -- cgit v1.2.3 From f6ca5059dc0d6608dc46070f48e396d611f240d6 Mon Sep 17 00:00:00 2001 From: Cristian Marussi Date: Thu, 22 Dec 2022 18:38:19 +0000 Subject: firmware: arm_scmi: Clear stale xfer->hdr.status Stale error status reported from a previous message transaction must be cleared before starting a new transaction to avoid being confusingly reported in the following SCMI message dump traces. Signed-off-by: Cristian Marussi Link: https://lore.kernel.org/r/20221222183823.518856-2-cristian.marussi@arm.com Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scmi/driver.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index f818d00bb2c6..ffdad59ec81f 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -910,6 +910,8 @@ static int do_xfer(const struct scmi_protocol_handle *ph, xfer->hdr.protocol_id, xfer->hdr.seq, xfer->hdr.poll_completion); + /* Clear any stale status */ + xfer->hdr.status = SCMI_SUCCESS; xfer->state = SCMI_XFER_SENT_OK; /* * Even though spinlocking is not needed here since no race is possible -- cgit v1.2.3 From ad78b81a1077f7d956952cd8bdfe1e61504e3eb8 Mon Sep 17 00:00:00 2001 From: Cristian Marussi Date: Thu, 22 Dec 2022 18:38:20 +0000 Subject: firmware: arm_scmi: Harden shared memory access in fetch_response A misbheaving SCMI platform firmware could reply with out-of-spec messages, shorter than the mimimum size comprising a header and a status field. Harden shmem_fetch_response to properly truncate such a bad messages. Fixes: 5c8a47a5a91d ("firmware: arm_scmi: Make scmi core independent of the transport type") Signed-off-by: Cristian Marussi Link: https://lore.kernel.org/r/20221222183823.518856-3-cristian.marussi@arm.com Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scmi/shmem.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/arm_scmi/shmem.c b/drivers/firmware/arm_scmi/shmem.c index 1dfe534b8518..135f8718000f 100644 --- a/drivers/firmware/arm_scmi/shmem.c +++ b/drivers/firmware/arm_scmi/shmem.c @@ -81,10 +81,11 @@ u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem) void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem, struct scmi_xfer *xfer) { + size_t len = ioread32(&shmem->length); + xfer->hdr.status = ioread32(shmem->msg_payload); /* Skip the length of header and status in shmem area i.e 8 bytes */ - xfer->rx.len = min_t(size_t, xfer->rx.len, - ioread32(&shmem->length) - 8); + xfer->rx.len = min_t(size_t, xfer->rx.len, len > 8 ? len - 8 : 0); /* Take a copy to the rx buffer.. */ memcpy_fromio(xfer->rx.buf, shmem->msg_payload + 4, xfer->rx.len); -- cgit v1.2.3 From 9bae076cd4e3e3c3dc185cae829d80b2dddec86e Mon Sep 17 00:00:00 2001 From: Cristian Marussi Date: Thu, 22 Dec 2022 18:38:21 +0000 Subject: firmware: arm_scmi: Harden shared memory access in fetch_notification A misbheaving SCMI platform firmware could reply with out-of-spec notifications, shorter than the mimimum size comprising a header. Fixes: d5141f37c42e ("firmware: arm_scmi: Add notifications support in transport layer") Signed-off-by: Cristian Marussi Link: https://lore.kernel.org/r/20221222183823.518856-4-cristian.marussi@arm.com Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scmi/shmem.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/firmware/arm_scmi/shmem.c b/drivers/firmware/arm_scmi/shmem.c index 135f8718000f..87b4f4d35f06 100644 --- a/drivers/firmware/arm_scmi/shmem.c +++ b/drivers/firmware/arm_scmi/shmem.c @@ -94,8 +94,10 @@ void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem, void shmem_fetch_notification(struct scmi_shared_mem __iomem *shmem, size_t max_len, struct scmi_xfer *xfer) { + size_t len = ioread32(&shmem->length); + /* Skip only the length of header in shmem area i.e 4 bytes */ - xfer->rx.len = min_t(size_t, max_len, ioread32(&shmem->length) - 4); + xfer->rx.len = min_t(size_t, max_len, len > 4 ? len - 4 : 0); /* Take a copy to the rx buffer.. */ memcpy_fromio(xfer->rx.buf, shmem->msg_payload, xfer->rx.len); -- cgit v1.2.3 From e325285de2cd82fbdcc4df8898e4c6a597674816 Mon Sep 17 00:00:00 2001 From: Cristian Marussi Date: Thu, 22 Dec 2022 18:38:23 +0000 Subject: firmware: arm_scmi: Fix virtio channels cleanup on shutdown When unloading the SCMI core stack module, configured to use the virtio SCMI transport, LOCKDEP reports the splat down below about unsafe locks dependencies. In order to avoid this possible unsafe locking scenario call upfront virtio_break_device() before getting hold of vioch->lock. ===================================================== WARNING: HARDIRQ-safe -> HARDIRQ-unsafe lock order detected 6.1.0-00067-g6b934395ba07-dirty #4 Not tainted ----------------------------------------------------- rmmod/307 [HC0[0]:SC0[0]:HE0:SE1] is trying to acquire: ffff000080c510e0 (&dev->vqs_list_lock){+.+.}-{3:3}, at: virtio_break_device+0x28/0x68 and this task is already holding: ffff00008288ada0 (&channels[i].lock){-.-.}-{3:3}, at: virtio_chan_free+0x60/0x168 [scmi_module] which would create a new lock dependency: (&channels[i].lock){-.-.}-{3:3} -> (&dev->vqs_list_lock){+.+.}-{3:3} but this new dependency connects a HARDIRQ-irq-safe lock: (&channels[i].lock){-.-.}-{3:3} ... which became HARDIRQ-irq-safe at: lock_acquire+0x128/0x398 _raw_spin_lock_irqsave+0x78/0x140 scmi_vio_complete_cb+0xb4/0x3b8 [scmi_module] vring_interrupt+0x84/0x120 vm_interrupt+0x94/0xe8 __handle_irq_event_percpu+0xb4/0x3d8 handle_irq_event_percpu+0x20/0x68 handle_irq_event+0x50/0xb0 handle_fasteoi_irq+0xac/0x138 generic_handle_domain_irq+0x34/0x50 gic_handle_irq+0xa0/0xd8 call_on_irq_stack+0x2c/0x54 do_interrupt_handler+0x8c/0x90 el1_interrupt+0x40/0x78 el1h_64_irq_handler+0x18/0x28 el1h_64_irq+0x64/0x68 _raw_write_unlock_irq+0x48/0x80 ep_start_scan+0xf0/0x128 do_epoll_wait+0x390/0x858 do_compat_epoll_pwait.part.34+0x1c/0xb8 __arm64_sys_epoll_pwait+0x80/0xd0 invoke_syscall+0x4c/0x110 el0_svc_common.constprop.3+0x98/0x120 do_el0_svc+0x34/0xd0 el0_svc+0x40/0x98 el0t_64_sync_handler+0x98/0xc0 el0t_64_sync+0x170/0x174 to a HARDIRQ-irq-unsafe lock: (&dev->vqs_list_lock){+.+.}-{3:3} ... which became HARDIRQ-irq-unsafe at: ... lock_acquire+0x128/0x398 _raw_spin_lock+0x58/0x70 __vring_new_virtqueue+0x130/0x1c0 vring_create_virtqueue+0xc4/0x2b8 vm_find_vqs+0x20c/0x430 init_vq+0x308/0x390 virtblk_probe+0x114/0x9b0 virtio_dev_probe+0x1a4/0x248 really_probe+0xc8/0x3a8 __driver_probe_device+0x84/0x190 driver_probe_device+0x44/0x110 __driver_attach+0x104/0x1e8 bus_for_each_dev+0x7c/0xd0 driver_attach+0x2c/0x38 bus_add_driver+0x1e4/0x258 driver_register+0x6c/0x128 register_virtio_driver+0x2c/0x48 virtio_blk_init+0x70/0xac do_one_initcall+0x84/0x420 kernel_init_freeable+0x2d0/0x340 kernel_init+0x2c/0x138 ret_from_fork+0x10/0x20 other info that might help us debug this: Possible interrupt unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&dev->vqs_list_lock); local_irq_disable(); lock(&channels[i].lock); lock(&dev->vqs_list_lock); lock(&channels[i].lock); *** DEADLOCK *** ================ Fixes: 42e90eb53bf3f ("firmware: arm_scmi: Add a virtio channel refcount") Signed-off-by: Cristian Marussi Link: https://lore.kernel.org/r/20221222183823.518856-6-cristian.marussi@arm.com Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scmi/virtio.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/firmware/arm_scmi/virtio.c b/drivers/firmware/arm_scmi/virtio.c index 33c9b81a55cd..1db975c08896 100644 --- a/drivers/firmware/arm_scmi/virtio.c +++ b/drivers/firmware/arm_scmi/virtio.c @@ -160,7 +160,6 @@ static void scmi_vio_channel_cleanup_sync(struct scmi_vio_channel *vioch) } vioch->shutdown_done = &vioch_shutdown_done; - virtio_break_device(vioch->vqueue->vdev); if (!vioch->is_rx && vioch->deferred_tx_wq) /* Cannot be kicked anymore after this...*/ vioch->deferred_tx_wq = NULL; @@ -482,6 +481,12 @@ static int virtio_chan_free(int id, void *p, void *data) struct scmi_chan_info *cinfo = p; struct scmi_vio_channel *vioch = cinfo->transport_info; + /* + * Break device to inhibit further traffic flowing while shutting down + * the channels: doing it later holding vioch->lock creates unsafe + * locking dependency chains as reported by LOCKDEP. + */ + virtio_break_device(vioch->vqueue->vdev); scmi_vio_channel_cleanup_sync(vioch); scmi_free_channel(cinfo, data, id); -- cgit v1.2.3 From 599d41fb8ea8bd2a99ca9525dd69405020e43dda Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Thu, 29 Dec 2022 16:16:48 +0100 Subject: soc: qcom: apr: Make qcom,protection-domain optional again APR should not fail if the service device tree node does not have the qcom,protection-domain property, since this functionality does not exist on older platforms such as MSM8916 and MSM8996. Ignore -EINVAL (returned when the property does not exist) to fix a regression on 6.2-rc1 that prevents audio from working: qcom,apr remoteproc0:smd-edge.apr_audio_svc.-1.-1: Failed to read second value of qcom,protection-domain qcom,apr remoteproc0:smd-edge.apr_audio_svc.-1.-1: Failed to add apr 3 svc Fixes: 6d7860f5750d ("soc: qcom: apr: Add check for idr_alloc and of_property_read_string_index") Signed-off-by: Stephan Gerhold Reviewed-by: Bjorn Andersson Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20221229151648.19839-3-stephan@gerhold.net --- drivers/soc/qcom/apr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c index cd44f17dad3d..d51abb462ae5 100644 --- a/drivers/soc/qcom/apr.c +++ b/drivers/soc/qcom/apr.c @@ -461,9 +461,10 @@ static int apr_add_device(struct device *dev, struct device_node *np, goto out; } + /* Protection domain is optional, it does not exist on older platforms */ ret = of_property_read_string_index(np, "qcom,protection-domain", 1, &adev->service_path); - if (ret < 0) { + if (ret < 0 && ret != -EINVAL) { dev_err(dev, "Failed to read second value of qcom,protection-domain\n"); goto out; } -- cgit v1.2.3 From 6049aae52392539e505bfb8ccbcff3c26f1d2f0b Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sat, 17 Dec 2022 17:05:41 +0100 Subject: PM: AVS: qcom-cpr: Fix an error handling path in cpr_probe() If an error occurs after a successful pm_genpd_init() call, it should be undone by a corresponding pm_genpd_remove(). Add the missing call in the error handling path, as already done in the remove function. Fixes: bf6910abf548 ("power: avs: Add support for CPR (Core Power Reduction)") Signed-off-by: Christophe JAILLET Reviewed-by: Ulf Hansson Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/0f520597dbad89ab99c217c8986912fa53eaf5f9.1671293108.git.christophe.jaillet@wanadoo.fr --- drivers/soc/qcom/cpr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/soc/qcom/cpr.c b/drivers/soc/qcom/cpr.c index e9b854ed1bdf..144ea68e0920 100644 --- a/drivers/soc/qcom/cpr.c +++ b/drivers/soc/qcom/cpr.c @@ -1708,12 +1708,16 @@ static int cpr_probe(struct platform_device *pdev) ret = of_genpd_add_provider_simple(dev->of_node, &drv->pd); if (ret) - return ret; + goto err_remove_genpd; platform_set_drvdata(pdev, drv); cpr_debugfs_init(drv); return 0; + +err_remove_genpd: + pm_genpd_remove(&drv->pd); + return ret; } static int cpr_remove(struct platform_device *pdev) -- cgit v1.2.3