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.

clk: imx: clk-audiomix: Add reset controller

Audiomix block control can be a reset controller for
Enhanced Audio Return Channel (EARC), which is one of
modules in this audiomix subsystem.

The reset controller is supported by the auxiliary device
framework.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>
Link: https://lore.kernel.org/r/1718350923-21392-3-git-send-email-shengjiu.wang@nxp.com
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>

authored by

Shengjiu Wang and committed by
Abel Vesa
6f0e8171 d7d9ef1f

+64
+1
drivers/clk/imx/Kconfig
··· 81 81 tristate "IMX8MP CCM Clock Driver" 82 82 depends on ARCH_MXC || COMPILE_TEST 83 83 select MXC_CLK 84 + select AUXILIARY_BUS if RESET_CONTROLLER 84 85 help 85 86 Build the driver for i.MX8MP CCM Clock Driver 86 87
+63
drivers/clk/imx/clk-imx8mp-audiomix.c
··· 5 5 * Copyright (C) 2022 Marek Vasut <marex@denx.de> 6 6 */ 7 7 8 + #include <linux/auxiliary_bus.h> 8 9 #include <linux/clk-provider.h> 9 10 #include <linux/device.h> 10 11 #include <linux/io.h> ··· 14 13 #include <linux/of.h> 15 14 #include <linux/platform_device.h> 16 15 #include <linux/pm_runtime.h> 16 + #include <linux/slab.h> 17 17 18 18 #include <dt-bindings/clock/imx8mp-clock.h> 19 19 ··· 219 217 struct clk_hw_onecell_data clk_data; 220 218 }; 221 219 220 + #if IS_ENABLED(CONFIG_RESET_CONTROLLER) 221 + 222 + static void clk_imx8mp_audiomix_reset_unregister_adev(void *_adev) 223 + { 224 + struct auxiliary_device *adev = _adev; 225 + 226 + auxiliary_device_delete(adev); 227 + auxiliary_device_uninit(adev); 228 + } 229 + 230 + static void clk_imx8mp_audiomix_reset_adev_release(struct device *dev) 231 + { 232 + struct auxiliary_device *adev = to_auxiliary_dev(dev); 233 + 234 + kfree(adev); 235 + } 236 + 237 + static int clk_imx8mp_audiomix_reset_controller_register(struct device *dev, 238 + struct clk_imx8mp_audiomix_priv *priv) 239 + { 240 + struct auxiliary_device *adev __free(kfree) = NULL; 241 + int ret; 242 + 243 + if (!of_property_present(dev->of_node, "#reset-cells")) 244 + return 0; 245 + 246 + adev = kzalloc(sizeof(*adev), GFP_KERNEL); 247 + if (!adev) 248 + return -ENOMEM; 249 + 250 + adev->name = "reset"; 251 + adev->dev.parent = dev; 252 + adev->dev.release = clk_imx8mp_audiomix_reset_adev_release; 253 + 254 + ret = auxiliary_device_init(adev); 255 + if (ret) 256 + return ret; 257 + 258 + ret = auxiliary_device_add(adev); 259 + if (ret) { 260 + auxiliary_device_uninit(adev); 261 + return ret; 262 + } 263 + 264 + return devm_add_action_or_reset(dev, clk_imx8mp_audiomix_reset_unregister_adev, 265 + no_free_ptr(adev)); 266 + } 267 + 268 + #else /* !CONFIG_RESET_CONTROLLER */ 269 + 270 + static int clk_imx8mp_audiomix_reset_controller_register(struct clk_imx8mp_audiomix_priv *priv) 271 + { 272 + return 0; 273 + } 274 + 275 + #endif /* !CONFIG_RESET_CONTROLLER */ 276 + 222 277 static void clk_imx8mp_audiomix_save_restore(struct device *dev, bool save) 223 278 { 224 279 struct clk_imx8mp_audiomix_priv *priv = dev_get_drvdata(dev); ··· 393 334 394 335 ret = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_onecell_get, 395 336 clk_hw_data); 337 + if (ret) 338 + goto err_clk_register; 339 + 340 + ret = clk_imx8mp_audiomix_reset_controller_register(dev, priv); 396 341 if (ret) 397 342 goto err_clk_register; 398 343