|
5 | 5 | * Copyright (C) 2022 Marek Vasut <[email protected]>
|
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>
|
|
13 | 14 | #include <linux/of.h>
|
14 | 15 | #include <linux/platform_device.h>
|
15 | 16 | #include <linux/pm_runtime.h>
|
| 17 | +#include <linux/slab.h> |
16 | 18 |
|
17 | 19 | #include <dt-bindings/clock/imx8mp-clock.h>
|
18 | 20 |
|
@@ -217,6 +219,63 @@ struct clk_imx8mp_audiomix_priv {
|
217 | 219 | struct clk_hw_onecell_data clk_data;
|
218 | 220 | };
|
219 | 221 |
|
| 222 | +#if IS_ENABLED(CONFIG_RESET_CONTROLLER) |
| 223 | + |
| 224 | +static void clk_imx8mp_audiomix_reset_unregister_adev(void *_adev) |
| 225 | +{ |
| 226 | + struct auxiliary_device *adev = _adev; |
| 227 | + |
| 228 | + auxiliary_device_delete(adev); |
| 229 | + auxiliary_device_uninit(adev); |
| 230 | +} |
| 231 | + |
| 232 | +static void clk_imx8mp_audiomix_reset_adev_release(struct device *dev) |
| 233 | +{ |
| 234 | + struct auxiliary_device *adev = to_auxiliary_dev(dev); |
| 235 | + |
| 236 | + kfree(adev); |
| 237 | +} |
| 238 | + |
| 239 | +static int clk_imx8mp_audiomix_reset_controller_register(struct device *dev, |
| 240 | + struct clk_imx8mp_audiomix_priv *priv) |
| 241 | +{ |
| 242 | + struct auxiliary_device *adev __free(kfree) = NULL; |
| 243 | + int ret; |
| 244 | + |
| 245 | + if (!of_property_present(dev->of_node, "#reset-cells")) |
| 246 | + return 0; |
| 247 | + |
| 248 | + adev = kzalloc(sizeof(*adev), GFP_KERNEL); |
| 249 | + if (!adev) |
| 250 | + return -ENOMEM; |
| 251 | + |
| 252 | + adev->name = "reset"; |
| 253 | + adev->dev.parent = dev; |
| 254 | + adev->dev.release = clk_imx8mp_audiomix_reset_adev_release; |
| 255 | + |
| 256 | + ret = auxiliary_device_init(adev); |
| 257 | + if (ret) |
| 258 | + return ret; |
| 259 | + |
| 260 | + ret = auxiliary_device_add(adev); |
| 261 | + if (ret) { |
| 262 | + auxiliary_device_uninit(adev); |
| 263 | + return ret; |
| 264 | + } |
| 265 | + |
| 266 | + return devm_add_action_or_reset(dev, clk_imx8mp_audiomix_reset_unregister_adev, |
| 267 | + no_free_ptr(adev)); |
| 268 | +} |
| 269 | + |
| 270 | +#else /* !CONFIG_RESET_CONTROLLER */ |
| 271 | + |
| 272 | +static int clk_imx8mp_audiomix_reset_controller_register(struct clk_imx8mp_audiomix_priv *priv) |
| 273 | +{ |
| 274 | + return 0; |
| 275 | +} |
| 276 | + |
| 277 | +#endif /* !CONFIG_RESET_CONTROLLER */ |
| 278 | + |
220 | 279 | static void clk_imx8mp_audiomix_save_restore(struct device *dev, bool save)
|
221 | 280 | {
|
222 | 281 | struct clk_imx8mp_audiomix_priv *priv = dev_get_drvdata(dev);
|
@@ -337,6 +396,10 @@ static int clk_imx8mp_audiomix_probe(struct platform_device *pdev)
|
337 | 396 | if (ret)
|
338 | 397 | goto err_clk_register;
|
339 | 398 |
|
| 399 | + ret = clk_imx8mp_audiomix_reset_controller_register(dev, priv); |
| 400 | + if (ret) |
| 401 | + goto err_clk_register; |
| 402 | + |
340 | 403 | pm_runtime_put_sync(dev);
|
341 | 404 | return 0;
|
342 | 405 |
|
|
0 commit comments