Skip to content

Commit 0e2d372

Browse files
committed
Merge tag 'reset-amlogic-aux' into clk-meson-next
Pull amlogic auxiliary reset support to continue removing reset drivers from amlogic clocks * tag 'reset-amlogic-aux': reset: amlogic: Fix small whitespace issue reset: amlogic: add auxiliary reset driver support reset: amlogic: split the device core and platform probe reset: amlogic: move drivers to a dedicated directory reset: amlogic: add reset status support reset: amlogic: use reset number instead of register count reset: amlogic: add driver parameters reset: amlogic: make parameters unsigned reset: amlogic: use generic data matching function reset: amlogic: convert driver to regmap
2 parents 0b2732b + 5f79c4b commit 0e2d372

File tree

11 files changed

+467
-175
lines changed

11 files changed

+467
-175
lines changed

drivers/reset/Kconfig

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -153,20 +153,6 @@ config RESET_MCHP_SPARX5
153153
help
154154
This driver supports switch core reset for the Microchip Sparx5 SoC.
155155

156-
config RESET_MESON
157-
tristate "Meson Reset Driver"
158-
depends on ARCH_MESON || COMPILE_TEST
159-
default ARCH_MESON
160-
help
161-
This enables the reset driver for Amlogic Meson SoCs.
162-
163-
config RESET_MESON_AUDIO_ARB
164-
tristate "Meson Audio Memory Arbiter Reset Driver"
165-
depends on ARCH_MESON || COMPILE_TEST
166-
help
167-
This enables the reset driver for Audio Memory Arbiter of
168-
Amlogic's A113 based SoCs
169-
170156
config RESET_NPCM
171157
bool "NPCM BMC Reset Driver" if COMPILE_TEST
172158
default ARCH_NPCM
@@ -356,6 +342,7 @@ config RESET_ZYNQMP
356342
help
357343
This enables the reset controller driver for Xilinx ZynqMP SoCs.
358344

345+
source "drivers/reset/amlogic/Kconfig"
359346
source "drivers/reset/starfive/Kconfig"
360347
source "drivers/reset/sti/Kconfig"
361348
source "drivers/reset/hisilicon/Kconfig"

drivers/reset/Makefile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# SPDX-License-Identifier: GPL-2.0
22
obj-y += core.o
3+
obj-y += amlogic/
34
obj-y += hisilicon/
45
obj-y += starfive/
56
obj-y += sti/
@@ -21,8 +22,6 @@ obj-$(CONFIG_RESET_K210) += reset-k210.o
2122
obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o
2223
obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
2324
obj-$(CONFIG_RESET_MCHP_SPARX5) += reset-microchip-sparx5.o
24-
obj-$(CONFIG_RESET_MESON) += reset-meson.o
25-
obj-$(CONFIG_RESET_MESON_AUDIO_ARB) += reset-meson-audio-arb.o
2625
obj-$(CONFIG_RESET_NPCM) += reset-npcm.o
2726
obj-$(CONFIG_RESET_NUVOTON_MA35D1) += reset-ma35d1.o
2827
obj-$(CONFIG_RESET_PISTACHIO) += reset-pistachio.o

drivers/reset/amlogic/Kconfig

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
config RESET_MESON_COMMON
2+
tristate
3+
select REGMAP
4+
5+
config RESET_MESON
6+
tristate "Meson Reset Driver"
7+
depends on ARCH_MESON || COMPILE_TEST
8+
default ARCH_MESON
9+
select REGMAP_MMIO
10+
select RESET_MESON_COMMON
11+
help
12+
This enables the reset driver for Amlogic SoCs.
13+
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+
22+
config RESET_MESON_AUDIO_ARB
23+
tristate "Meson Audio Memory Arbiter Reset Driver"
24+
depends on ARCH_MESON || COMPILE_TEST
25+
help
26+
This enables the reset driver for Audio Memory Arbiter of
27+
Amlogic's A113 based SoCs

drivers/reset/amlogic/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
obj-$(CONFIG_RESET_MESON) += reset-meson.o
2+
obj-$(CONFIG_RESET_MESON_AUX) += reset-meson-aux.o
3+
obj-$(CONFIG_RESET_MESON_COMMON) += reset-meson-common.o
4+
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 <[email protected]>
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 <[email protected]>");
135+
MODULE_LICENSE("Dual BSD/GPL");
136+
MODULE_IMPORT_NS(MESON_RESET);
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2+
/*
3+
* Amlogic Meson Reset core functions
4+
*
5+
* Copyright (c) 2016-2024 BayLibre, SAS.
6+
* Authors: Neil Armstrong <[email protected]>
7+
* Jerome Brunet <[email protected]>
8+
*/
9+
10+
#include <linux/device.h>
11+
#include <linux/module.h>
12+
#include <linux/regmap.h>
13+
#include <linux/reset-controller.h>
14+
15+
#include "reset-meson.h"
16+
17+
struct meson_reset {
18+
const struct meson_reset_param *param;
19+
struct reset_controller_dev rcdev;
20+
struct regmap *map;
21+
};
22+
23+
static void meson_reset_offset_and_bit(struct meson_reset *data,
24+
unsigned long id,
25+
unsigned int *offset,
26+
unsigned int *bit)
27+
{
28+
unsigned int stride = regmap_get_reg_stride(data->map);
29+
30+
*offset = (id / (stride * BITS_PER_BYTE)) * stride;
31+
*bit = id % (stride * BITS_PER_BYTE);
32+
}
33+
34+
static int meson_reset_reset(struct reset_controller_dev *rcdev,
35+
unsigned long id)
36+
{
37+
struct meson_reset *data =
38+
container_of(rcdev, struct meson_reset, rcdev);
39+
unsigned int offset, bit;
40+
41+
meson_reset_offset_and_bit(data, id, &offset, &bit);
42+
offset += data->param->reset_offset;
43+
44+
return regmap_write(data->map, offset, BIT(bit));
45+
}
46+
47+
static int meson_reset_level(struct reset_controller_dev *rcdev,
48+
unsigned long id, bool assert)
49+
{
50+
struct meson_reset *data =
51+
container_of(rcdev, struct meson_reset, rcdev);
52+
unsigned int offset, bit;
53+
54+
meson_reset_offset_and_bit(data, id, &offset, &bit);
55+
offset += data->param->level_offset;
56+
assert ^= data->param->level_low_reset;
57+
58+
return regmap_update_bits(data->map, offset,
59+
BIT(bit), assert ? BIT(bit) : 0);
60+
}
61+
62+
static int meson_reset_status(struct reset_controller_dev *rcdev,
63+
unsigned long id)
64+
{
65+
struct meson_reset *data =
66+
container_of(rcdev, struct meson_reset, rcdev);
67+
unsigned int val, offset, bit;
68+
69+
meson_reset_offset_and_bit(data, id, &offset, &bit);
70+
offset += data->param->level_offset;
71+
72+
regmap_read(data->map, offset, &val);
73+
val = !!(BIT(bit) & val);
74+
75+
return val ^ data->param->level_low_reset;
76+
}
77+
78+
static int meson_reset_assert(struct reset_controller_dev *rcdev,
79+
unsigned long id)
80+
{
81+
return meson_reset_level(rcdev, id, true);
82+
}
83+
84+
static int meson_reset_deassert(struct reset_controller_dev *rcdev,
85+
unsigned long id)
86+
{
87+
return meson_reset_level(rcdev, id, false);
88+
}
89+
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 = {
103+
.reset = meson_reset_reset,
104+
.assert = meson_reset_assert,
105+
.deassert = meson_reset_deassert,
106+
.status = meson_reset_status,
107+
};
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);
117+
118+
int meson_reset_controller_register(struct device *dev, struct regmap *map,
119+
const struct meson_reset_param *param)
120+
{
121+
struct meson_reset *data;
122+
123+
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
124+
if (!data)
125+
return -ENOMEM;
126+
127+
data->param = param;
128+
data->map = map;
129+
data->rcdev.owner = dev->driver->owner;
130+
data->rcdev.nr_resets = param->reset_num;
131+
data->rcdev.ops = data->param->reset_ops;
132+
data->rcdev.of_node = dev->of_node;
133+
134+
return devm_reset_controller_register(dev, &data->rcdev);
135+
}
136+
EXPORT_SYMBOL_NS_GPL(meson_reset_controller_register, MESON_RESET);
137+
138+
MODULE_DESCRIPTION("Amlogic Meson Reset Core function");
139+
MODULE_AUTHOR("Neil Armstrong <[email protected]>");
140+
MODULE_AUTHOR("Jerome Brunet <[email protected]>");
141+
MODULE_LICENSE("Dual BSD/GPL");
142+
MODULE_IMPORT_NS(MESON_RESET);

0 commit comments

Comments
 (0)