Skip to content

Commit fb4c315

Browse files
jbrun3tpH5
authored andcommitted
reset: amlogic: add auxiliary reset driver support
Add support for the reset controller present in the audio clock controller of the g12 and sm1 SoC families, using the auxiliary bus. This is expected to replace the driver currently present directly within the related clock driver. Signed-off-by: Jerome Brunet <jbrunet@baylibre.com> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Link: https://lore.kernel.org/r/20240910-meson-rst-aux-v5-9-60be62635d3e@baylibre.com Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
1 parent c38ae95 commit fb4c315

File tree

7 files changed

+198
-2
lines changed

7 files changed

+198
-2
lines changed

drivers/reset/amlogic/Kconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ config RESET_MESON
1111
help
1212
This enables the reset driver for Amlogic SoCs.
1313

14+
config RESET_MESON_AUX
15+
tristate "Meson Reset Auxiliary Driver"
16+
depends on ARCH_MESON || COMPILE_TEST
17+
select AUXILIARY_BUS
18+
select RESET_MESON_COMMON
19+
help
20+
This enables the reset auxiliary driver for Amlogic SoCs.
21+
1422
config RESET_MESON_AUDIO_ARB
1523
tristate "Meson Audio Memory Arbiter Reset Driver"
1624
depends on ARCH_MESON || COMPILE_TEST

drivers/reset/amlogic/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
obj-$(CONFIG_RESET_MESON) += reset-meson.o
2+
obj-$(CONFIG_RESET_MESON_AUX) += reset-meson-aux.o
23
obj-$(CONFIG_RESET_MESON_COMMON) += reset-meson-common.o
34
obj-$(CONFIG_RESET_MESON_AUDIO_ARB) += reset-meson-audio-arb.o
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2+
/*
3+
* Amlogic Meson Reset Auxiliary driver
4+
*
5+
* Copyright (c) 2024 BayLibre, SAS.
6+
* Author: Jerome Brunet <jbrunet@baylibre.com>
7+
*/
8+
9+
#include <linux/err.h>
10+
#include <linux/module.h>
11+
#include <linux/auxiliary_bus.h>
12+
#include <linux/regmap.h>
13+
#include <linux/reset-controller.h>
14+
#include <linux/slab.h>
15+
16+
#include "reset-meson.h"
17+
#include <soc/amlogic/reset-meson-aux.h>
18+
19+
static DEFINE_IDA(meson_rst_aux_ida);
20+
21+
struct meson_reset_adev {
22+
struct auxiliary_device adev;
23+
struct regmap *map;
24+
};
25+
26+
#define to_meson_reset_adev(_adev) \
27+
container_of((_adev), struct meson_reset_adev, adev)
28+
29+
static const struct meson_reset_param meson_g12a_audio_param = {
30+
.reset_ops = &meson_reset_toggle_ops,
31+
.reset_num = 26,
32+
.level_offset = 0x24,
33+
};
34+
35+
static const struct meson_reset_param meson_sm1_audio_param = {
36+
.reset_ops = &meson_reset_toggle_ops,
37+
.reset_num = 39,
38+
.level_offset = 0x28,
39+
};
40+
41+
static const struct auxiliary_device_id meson_reset_aux_ids[] = {
42+
{
43+
.name = "axg-audio-clkc.rst-g12a",
44+
.driver_data = (kernel_ulong_t)&meson_g12a_audio_param,
45+
}, {
46+
.name = "axg-audio-clkc.rst-sm1",
47+
.driver_data = (kernel_ulong_t)&meson_sm1_audio_param,
48+
}, {}
49+
};
50+
MODULE_DEVICE_TABLE(auxiliary, meson_reset_aux_ids);
51+
52+
static int meson_reset_aux_probe(struct auxiliary_device *adev,
53+
const struct auxiliary_device_id *id)
54+
{
55+
const struct meson_reset_param *param =
56+
(const struct meson_reset_param *)(id->driver_data);
57+
struct meson_reset_adev *raux =
58+
to_meson_reset_adev(adev);
59+
60+
return meson_reset_controller_register(&adev->dev, raux->map, param);
61+
}
62+
63+
static struct auxiliary_driver meson_reset_aux_driver = {
64+
.probe = meson_reset_aux_probe,
65+
.id_table = meson_reset_aux_ids,
66+
};
67+
module_auxiliary_driver(meson_reset_aux_driver);
68+
69+
static void meson_rst_aux_release(struct device *dev)
70+
{
71+
struct auxiliary_device *adev = to_auxiliary_dev(dev);
72+
struct meson_reset_adev *raux =
73+
to_meson_reset_adev(adev);
74+
75+
ida_free(&meson_rst_aux_ida, adev->id);
76+
kfree(raux);
77+
}
78+
79+
static void meson_rst_aux_unregister_adev(void *_adev)
80+
{
81+
struct auxiliary_device *adev = _adev;
82+
83+
auxiliary_device_delete(adev);
84+
auxiliary_device_uninit(adev);
85+
}
86+
87+
int devm_meson_rst_aux_register(struct device *dev,
88+
struct regmap *map,
89+
const char *adev_name)
90+
{
91+
struct meson_reset_adev *raux;
92+
struct auxiliary_device *adev;
93+
int ret;
94+
95+
raux = kzalloc(sizeof(*raux), GFP_KERNEL);
96+
if (!raux)
97+
return -ENOMEM;
98+
99+
ret = ida_alloc(&meson_rst_aux_ida, GFP_KERNEL);
100+
if (ret < 0)
101+
goto raux_free;
102+
103+
raux->map = map;
104+
105+
adev = &raux->adev;
106+
adev->id = ret;
107+
adev->name = adev_name;
108+
adev->dev.parent = dev;
109+
adev->dev.release = meson_rst_aux_release;
110+
device_set_of_node_from_dev(&adev->dev, dev);
111+
112+
ret = auxiliary_device_init(adev);
113+
if (ret)
114+
goto ida_free;
115+
116+
ret = __auxiliary_device_add(adev, dev->driver->name);
117+
if (ret) {
118+
auxiliary_device_uninit(adev);
119+
return ret;
120+
}
121+
122+
return devm_add_action_or_reset(dev, meson_rst_aux_unregister_adev,
123+
adev);
124+
125+
ida_free:
126+
ida_free(&meson_rst_aux_ida, adev->id);
127+
raux_free:
128+
kfree(raux);
129+
return ret;
130+
}
131+
EXPORT_SYMBOL_GPL(devm_meson_rst_aux_register);
132+
133+
MODULE_DESCRIPTION("Amlogic Meson Reset Auxiliary driver");
134+
MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
135+
MODULE_LICENSE("Dual BSD/GPL");
136+
MODULE_IMPORT_NS(MESON_RESET);

drivers/reset/amlogic/reset-meson-common.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,33 @@ static int meson_reset_deassert(struct reset_controller_dev *rcdev,
8787
return meson_reset_level(rcdev, id, false);
8888
}
8989

90-
static const struct reset_control_ops meson_reset_ops = {
90+
static int meson_reset_level_toggle(struct reset_controller_dev *rcdev,
91+
unsigned long id)
92+
{
93+
int ret;
94+
95+
ret = meson_reset_assert(rcdev, id);
96+
if (ret)
97+
return ret;
98+
99+
return meson_reset_deassert(rcdev, id);
100+
}
101+
102+
const struct reset_control_ops meson_reset_ops = {
91103
.reset = meson_reset_reset,
92104
.assert = meson_reset_assert,
93105
.deassert = meson_reset_deassert,
94106
.status = meson_reset_status,
95107
};
108+
EXPORT_SYMBOL_NS_GPL(meson_reset_ops, MESON_RESET);
109+
110+
const struct reset_control_ops meson_reset_toggle_ops = {
111+
.reset = meson_reset_level_toggle,
112+
.assert = meson_reset_assert,
113+
.deassert = meson_reset_deassert,
114+
.status = meson_reset_status,
115+
};
116+
EXPORT_SYMBOL_NS_GPL(meson_reset_toggle_ops, MESON_RESET);
96117

97118
int meson_reset_controller_register(struct device *dev, struct regmap *map,
98119
const struct meson_reset_param *param)
@@ -107,7 +128,7 @@ int meson_reset_controller_register(struct device *dev, struct regmap *map,
107128
data->map = map;
108129
data->rcdev.owner = dev->driver->owner;
109130
data->rcdev.nr_resets = param->reset_num;
110-
data->rcdev.ops = &meson_reset_ops;
131+
data->rcdev.ops = data->param->reset_ops;
111132
data->rcdev.of_node = dev->of_node;
112133

113134
return devm_reset_controller_register(dev, &data->rcdev);

drivers/reset/amlogic/reset-meson.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,23 @@
1818
#include "reset-meson.h"
1919

2020
static const struct meson_reset_param meson8b_param = {
21+
.reset_ops = &meson_reset_ops,
2122
.reset_num = 256,
2223
.reset_offset = 0x0,
2324
.level_offset = 0x7c,
2425
.level_low_reset = true,
2526
};
2627

2728
static const struct meson_reset_param meson_a1_param = {
29+
.reset_ops = &meson_reset_ops,
2830
.reset_num = 96,
2931
.reset_offset = 0x0,
3032
.level_offset = 0x40,
3133
.level_low_reset = true,
3234
};
3335

3436
static const struct meson_reset_param meson_s4_param = {
37+
.reset_ops = &meson_reset_ops,
3538
.reset_num = 192,
3639
.reset_offset = 0x0,
3740
.level_offset = 0x40,

drivers/reset/amlogic/reset-meson.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/reset-controller.h>
1313

1414
struct meson_reset_param {
15+
const struct reset_control_ops *reset_ops;
1516
unsigned int reset_num;
1617
unsigned int reset_offset;
1718
unsigned int level_offset;
@@ -21,4 +22,7 @@ struct meson_reset_param {
2122
int meson_reset_controller_register(struct device *dev, struct regmap *map,
2223
const struct meson_reset_param *param);
2324

25+
extern const struct reset_control_ops meson_reset_ops;
26+
extern const struct reset_control_ops meson_reset_toggle_ops;
27+
2428
#endif /* __MESON_RESET_H */

include/soc/amlogic/reset-meson-aux.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef __SOC_RESET_MESON_AUX_H
3+
#define __SOC_RESET_MESON_AUX_H
4+
5+
#include <linux/err.h>
6+
7+
struct device;
8+
struct regmap;
9+
10+
#if IS_ENABLED(CONFIG_RESET_MESON_AUX)
11+
int devm_meson_rst_aux_register(struct device *dev,
12+
struct regmap *map,
13+
const char *adev_name);
14+
#else
15+
static inline int devm_meson_rst_aux_register(struct device *dev,
16+
struct regmap *map,
17+
const char *adev_name)
18+
{
19+
return 0;
20+
}
21+
#endif
22+
23+
#endif /* __SOC_RESET_MESON_AUX_H */

0 commit comments

Comments
 (0)