Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'reset-for-v6.11' of git://git.pengutronix.de/pza/linux into soc/drivers

Reset controller updates for v6.11

Move reset controller registration to the end in rzg2l-usbphy-ctrl, to
simplify the probe error path, add a new i.MX8MP AudioMix reset driver,
allow to build some drivers under COMPILE_TEST with fewer dependencies,
and use the devm_clk_get_enabled convenience wrapper in meson-audio-arb.

The latter causes a trivial merge conflict [1] with

b99e9c096148f ("reset: meson-audio-arb: Convert to platform remove callback returning void")

because I didn't manage to send that in last round. There is no overlap
though.

[1] https://lore.kernel.org/all/Znmufb9L78FCoSSS@sirena.org.uk/

* tag 'reset-for-v6.11' of git://git.pengutronix.de/pza/linux:
reset: RESET_IMX8MP_AUDIOMIX should depend on ARCH_MXC
reset: zynqmp: allow building under COMPILE_TEST
reset: imx8mp-audiomix: Add AudioMix Block Control reset driver
reset: meson-audio-arb: Use devm_clk_get_enabled()
reset: sti: allow building under COMPILE_TEST
reset: rzg2l-usbphy-ctrl: Move reset controller registration

Link: https://lore.kernel.org/r/20240626163258.61222-1-p.zabel@pengutronix.de
Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+167 -25
+14
drivers/reset/Kconfig
··· 91 91 help 92 92 This enables the reset controller driver for i.MX7 SoCs. 93 93 94 + config RESET_IMX8MP_AUDIOMIX 95 + tristate "i.MX8MP AudioMix Reset Driver" 96 + depends on ARCH_MXC || COMPILE_TEST 97 + select AUXILIARY_BUS 98 + default CLK_IMX8MP 99 + help 100 + This enables the reset controller driver for i.MX8MP AudioMix 101 + 94 102 config RESET_INTEL_GW 95 103 bool "Intel Reset Controller Driver" 96 104 depends on X86 || COMPILE_TEST ··· 335 327 default ARCH_ZYNQ 336 328 help 337 329 This enables the reset controller driver for Xilinx Zynq SoCs. 330 + 331 + config RESET_ZYNQMP 332 + bool "ZYNQMP Reset Driver" if COMPILE_TEST 333 + default ARCH_ZYNQMP 334 + help 335 + This enables the reset controller driver for Xilinx ZynqMP SoCs. 338 336 339 337 source "drivers/reset/starfive/Kconfig" 340 338 source "drivers/reset/sti/Kconfig"
+3 -2
drivers/reset/Makefile
··· 2 2 obj-y += core.o 3 3 obj-y += hisilicon/ 4 4 obj-y += starfive/ 5 - obj-$(CONFIG_ARCH_STI) += sti/ 5 + obj-y += sti/ 6 6 obj-$(CONFIG_ARCH_TEGRA) += tegra/ 7 7 obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o 8 8 obj-$(CONFIG_RESET_ATH79) += reset-ath79.o ··· 14 14 obj-$(CONFIG_RESET_GPIO) += reset-gpio.o 15 15 obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o 16 16 obj-$(CONFIG_RESET_IMX7) += reset-imx7.o 17 + obj-$(CONFIG_RESET_IMX8MP_AUDIOMIX) += reset-imx8mp-audiomix.o 17 18 obj-$(CONFIG_RESET_INTEL_GW) += reset-intel-gw.o 18 19 obj-$(CONFIG_RESET_K210) += reset-k210.o 19 20 obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o ··· 42 41 obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o 43 42 obj-$(CONFIG_RESET_UNIPHIER_GLUE) += reset-uniphier-glue.o 44 43 obj-$(CONFIG_RESET_ZYNQ) += reset-zynq.o 45 - obj-$(CONFIG_ARCH_ZYNQMP) += reset-zynqmp.o 44 + obj-$(CONFIG_RESET_ZYNQMP) += reset-zynqmp.o
+128
drivers/reset/reset-imx8mp-audiomix.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Copyright 2024 NXP 4 + */ 5 + 6 + #include <linux/auxiliary_bus.h> 7 + #include <linux/device.h> 8 + #include <linux/io.h> 9 + #include <linux/module.h> 10 + #include <linux/of.h> 11 + #include <linux/of_address.h> 12 + #include <linux/reset-controller.h> 13 + 14 + #define EARC 0x200 15 + #define EARC_RESET_MASK 0x3 16 + 17 + struct imx8mp_audiomix_reset { 18 + struct reset_controller_dev rcdev; 19 + spinlock_t lock; /* protect register read-modify-write cycle */ 20 + void __iomem *base; 21 + }; 22 + 23 + static struct imx8mp_audiomix_reset *to_imx8mp_audiomix_reset(struct reset_controller_dev *rcdev) 24 + { 25 + return container_of(rcdev, struct imx8mp_audiomix_reset, rcdev); 26 + } 27 + 28 + static int imx8mp_audiomix_reset_assert(struct reset_controller_dev *rcdev, 29 + unsigned long id) 30 + { 31 + struct imx8mp_audiomix_reset *priv = to_imx8mp_audiomix_reset(rcdev); 32 + void __iomem *reg_addr = priv->base; 33 + unsigned int mask, reg; 34 + unsigned long flags; 35 + 36 + mask = BIT(id); 37 + spin_lock_irqsave(&priv->lock, flags); 38 + reg = readl(reg_addr + EARC); 39 + writel(reg & ~mask, reg_addr + EARC); 40 + spin_unlock_irqrestore(&priv->lock, flags); 41 + 42 + return 0; 43 + } 44 + 45 + static int imx8mp_audiomix_reset_deassert(struct reset_controller_dev *rcdev, 46 + unsigned long id) 47 + { 48 + struct imx8mp_audiomix_reset *priv = to_imx8mp_audiomix_reset(rcdev); 49 + void __iomem *reg_addr = priv->base; 50 + unsigned int mask, reg; 51 + unsigned long flags; 52 + 53 + mask = BIT(id); 54 + spin_lock_irqsave(&priv->lock, flags); 55 + reg = readl(reg_addr + EARC); 56 + writel(reg | mask, reg_addr + EARC); 57 + spin_unlock_irqrestore(&priv->lock, flags); 58 + 59 + return 0; 60 + } 61 + 62 + static const struct reset_control_ops imx8mp_audiomix_reset_ops = { 63 + .assert = imx8mp_audiomix_reset_assert, 64 + .deassert = imx8mp_audiomix_reset_deassert, 65 + }; 66 + 67 + static int imx8mp_audiomix_reset_probe(struct auxiliary_device *adev, 68 + const struct auxiliary_device_id *id) 69 + { 70 + struct imx8mp_audiomix_reset *priv; 71 + struct device *dev = &adev->dev; 72 + int ret; 73 + 74 + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 75 + if (!priv) 76 + return -ENOMEM; 77 + 78 + spin_lock_init(&priv->lock); 79 + 80 + priv->rcdev.owner = THIS_MODULE; 81 + priv->rcdev.nr_resets = fls(EARC_RESET_MASK); 82 + priv->rcdev.ops = &imx8mp_audiomix_reset_ops; 83 + priv->rcdev.of_node = dev->parent->of_node; 84 + priv->rcdev.dev = dev; 85 + priv->rcdev.of_reset_n_cells = 1; 86 + priv->base = of_iomap(dev->parent->of_node, 0); 87 + if (!priv->base) 88 + return -ENOMEM; 89 + 90 + dev_set_drvdata(dev, priv); 91 + 92 + ret = devm_reset_controller_register(dev, &priv->rcdev); 93 + if (ret) 94 + goto out_unmap; 95 + 96 + return 0; 97 + 98 + out_unmap: 99 + iounmap(priv->base); 100 + return ret; 101 + } 102 + 103 + static void imx8mp_audiomix_reset_remove(struct auxiliary_device *adev) 104 + { 105 + struct imx8mp_audiomix_reset *priv = dev_get_drvdata(&adev->dev); 106 + 107 + iounmap(priv->base); 108 + } 109 + 110 + static const struct auxiliary_device_id imx8mp_audiomix_reset_ids[] = { 111 + { 112 + .name = "clk_imx8mp_audiomix.reset", 113 + }, 114 + { } 115 + }; 116 + MODULE_DEVICE_TABLE(auxiliary, imx8mp_audiomix_reset_ids); 117 + 118 + static struct auxiliary_driver imx8mp_audiomix_reset_driver = { 119 + .probe = imx8mp_audiomix_reset_probe, 120 + .remove = imx8mp_audiomix_reset_remove, 121 + .id_table = imx8mp_audiomix_reset_ids, 122 + }; 123 + 124 + module_auxiliary_driver(imx8mp_audiomix_reset_driver); 125 + 126 + MODULE_AUTHOR("Shengjiu Wang <shengjiu.wang@nxp.com>"); 127 + MODULE_DESCRIPTION("Freescale i.MX8MP Audio Block Controller reset driver"); 128 + MODULE_LICENSE("GPL");
+1 -8
drivers/reset/reset-meson-audio-arb.c
··· 129 129 writel(0, arb->regs); 130 130 spin_unlock(&arb->lock); 131 131 132 - clk_disable_unprepare(arb->clk); 133 - 134 132 return 0; 135 133 } 136 134 ··· 148 150 return -ENOMEM; 149 151 platform_set_drvdata(pdev, arb); 150 152 151 - arb->clk = devm_clk_get(dev, NULL); 153 + arb->clk = devm_clk_get_enabled(dev, NULL); 152 154 if (IS_ERR(arb->clk)) 153 155 return dev_err_probe(dev, PTR_ERR(arb->clk), "failed to get clock\n"); 154 156 ··· 168 170 * In the initial state, all memory interfaces are disabled 169 171 * and the general bit is on 170 172 */ 171 - ret = clk_prepare_enable(arb->clk); 172 - if (ret) { 173 - dev_err(dev, "failed to enable arb clock\n"); 174 - return ret; 175 - } 176 173 writel(BIT(ARB_GENERAL_BIT), arb->regs); 177 174 178 175 /* Register reset controller */
+19 -13
drivers/reset/reset-rzg2l-usbphy-ctrl.c
··· 125 125 if (error) 126 126 return error; 127 127 128 - priv->rcdev.ops = &rzg2l_usbphy_ctrl_reset_ops; 129 - priv->rcdev.of_reset_n_cells = 1; 130 - priv->rcdev.nr_resets = NUM_PORTS; 131 - priv->rcdev.of_node = dev->of_node; 132 - priv->rcdev.dev = dev; 133 - 134 - error = devm_reset_controller_register(dev, &priv->rcdev); 135 - if (error) 136 - return error; 137 - 138 128 spin_lock_init(&priv->lock); 139 129 dev_set_drvdata(dev, priv); 140 130 141 131 pm_runtime_enable(&pdev->dev); 142 132 error = pm_runtime_resume_and_get(&pdev->dev); 143 133 if (error < 0) { 144 - pm_runtime_disable(&pdev->dev); 145 - reset_control_assert(priv->rstc); 146 - return dev_err_probe(&pdev->dev, error, "pm_runtime_resume_and_get failed"); 134 + dev_err_probe(&pdev->dev, error, "pm_runtime_resume_and_get failed"); 135 + goto err_pm_disable_reset_deassert; 147 136 } 148 137 149 138 /* put pll and phy into reset state */ ··· 142 153 writel(val, priv->base + RESET); 143 154 spin_unlock_irqrestore(&priv->lock, flags); 144 155 156 + priv->rcdev.ops = &rzg2l_usbphy_ctrl_reset_ops; 157 + priv->rcdev.of_reset_n_cells = 1; 158 + priv->rcdev.nr_resets = NUM_PORTS; 159 + priv->rcdev.of_node = dev->of_node; 160 + priv->rcdev.dev = dev; 161 + 162 + error = devm_reset_controller_register(dev, &priv->rcdev); 163 + if (error) 164 + goto err_pm_runtime_put; 165 + 145 166 return 0; 167 + 168 + err_pm_runtime_put: 169 + pm_runtime_put(&pdev->dev); 170 + err_pm_disable_reset_deassert: 171 + pm_runtime_disable(&pdev->dev); 172 + reset_control_assert(priv->rstc); 173 + return error; 146 174 } 147 175 148 176 static int rzg2l_usbphy_ctrl_remove(struct platform_device *pdev)
+2 -2
drivers/reset/sti/Kconfig
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 - if ARCH_STI 2 + if ARCH_STI || COMPILE_TEST 3 3 4 4 config STIH407_RESET 5 - bool 5 + bool "STIH407 Reset Driver" if COMPILE_TEST 6 6 7 7 endif