Commit 311ef883 authored by Arnd Bergmann's avatar Arnd Bergmann

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

Reset controller updates for v6.12

Use get_device()/put_device() to keep reset controller devices alive
while their reset controls are acquired.
Enable support for the Amlogic T7 SoC reset controller.
Remove unused EyeQ reset bindings and add a reset controller driver
to be instantiated as auxiliary device by the EyeQ clock driver.
Fix OF node leaks in the k210 and berlin probe() error paths.
Add some simplifications and cleanup in the core, lcp18xx driver, and
uniphier bindings.

* tag 'reset-for-v6.12' of git://git.pengutronix.de/pza/linux:
  reset: eyeq: add platform driver
  Revert "dt-bindings: reset: mobileye,eyeq5-reset: add bindings"
  reset: reset-meson: Add support for Amlogic T7 SoC reset controller
  dt-bindings: reset: Add Amlogic T7 reset controller
  reset: core: add get_device()/put_device on rcdev
  reset: lpc18xx: simplify with devm_clk_get_enabled()
  reset: lpc18xx: simplify with dev_err_probe()
  reset: simplify locking with guard()
  reset: k210: fix OF node leak in probe() error path
  reset: berlin: fix OF node leak in probe() error path
  dt-bindings: reset: socionext,uniphier-glue-reset: add top-level constraints

Link: https://lore.kernel.org/r/20240904103921.1479579-1-p.zabel@pengutronix.deSigned-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents 639d5f6d 487b1b32
......@@ -19,6 +19,7 @@ properties:
- amlogic,meson-a1-reset # Reset Controller on A1 and compatible SoCs
- amlogic,meson-s4-reset # Reset Controller on S4 and compatible SoCs
- amlogic,c3-reset # Reset Controller on C3 and compatible SoCs
- amlogic,t7-reset
reg:
maxItems: 1
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/reset/mobileye,eyeq5-reset.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Mobileye EyeQ5 reset controller
description:
The EyeQ5 reset driver handles three reset domains. Its registers live in a
shared region called OLB.
maintainers:
- Grégory Clement <gregory.clement@bootlin.com>
- Théo Lebrun <theo.lebrun@bootlin.com>
- Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
properties:
compatible:
const: mobileye,eyeq5-reset
reg:
maxItems: 3
reg-names:
items:
- const: d0
- const: d1
- const: d2
"#reset-cells":
const: 2
description:
The first cell is the domain (0 to 2 inclusive) and the second one is the
reset index inside that domain.
required:
- compatible
- reg
- reg-names
- "#reset-cells"
additionalProperties: false
......@@ -38,13 +38,17 @@ properties:
minItems: 1
maxItems: 2
clock-names: true
clock-names:
minItems: 1
maxItems: 2
resets:
minItems: 1
maxItems: 2
reset-names: true
reset-names:
minItems: 1
maxItems: 2
allOf:
- if:
......
......@@ -66,6 +66,19 @@ config RESET_BRCMSTB_RESCAL
This enables the RESCAL reset controller for SATA, PCIe0, or PCIe1 on
BCM7216.
config RESET_EYEQ
bool "Mobileye EyeQ reset controller"
depends on MACH_EYEQ5 || MACH_EYEQ6H || COMPILE_TEST
select AUXILIARY_BUS
default MACH_EYEQ5 || MACH_EYEQ6H
help
This enables the Mobileye EyeQ reset controller, used in EyeQ5, EyeQ6L
and EyeQ6H SoCs.
It has one or more domains, with a varying number of resets in each.
Registers are located in a shared register region called OLB. EyeQ6H
has multiple reset instances.
config RESET_GPIO
tristate "GPIO reset controller"
depends on GPIOLIB
......
......@@ -11,6 +11,7 @@ obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o
obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o
obj-$(CONFIG_RESET_BRCMSTB) += reset-brcmstb.o
obj-$(CONFIG_RESET_BRCMSTB_RESCAL) += reset-brcmstb-rescal.o
obj-$(CONFIG_RESET_EYEQ) += reset-eyeq.o
obj-$(CONFIG_RESET_GPIO) += reset-gpio.o
obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o
obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
......
......@@ -812,6 +812,7 @@ __reset_control_get_internal(struct reset_controller_dev *rcdev,
kref_init(&rstc->refcnt);
rstc->acquired = acquired;
rstc->shared = shared;
get_device(rcdev->dev);
return rstc;
}
......@@ -826,6 +827,7 @@ static void __reset_control_release(struct kref *kref)
module_put(rstc->rcdev->owner);
list_del(&rstc->list);
put_device(rstc->rcdev->dev);
kfree(rstc);
}
......@@ -916,20 +918,18 @@ static int __reset_add_reset_gpio_device(const struct of_phandle_args *args)
*/
lockdep_assert_not_held(&reset_list_mutex);
mutex_lock(&reset_gpio_lookup_mutex);
guard(mutex)(&reset_gpio_lookup_mutex);
list_for_each_entry(rgpio_dev, &reset_gpio_lookup_list, list) {
if (args->np == rgpio_dev->of_args.np) {
if (of_phandle_args_equal(args, &rgpio_dev->of_args))
goto out; /* Already on the list, done */
return 0; /* Already on the list, done */
}
}
id = ida_alloc(&reset_gpio_ida, GFP_KERNEL);
if (id < 0) {
ret = id;
goto err_unlock;
}
if (id < 0)
return id;
/* Not freed on success, because it is persisent subsystem data. */
rgpio_dev = kzalloc(sizeof(*rgpio_dev), GFP_KERNEL);
......@@ -959,9 +959,6 @@ static int __reset_add_reset_gpio_device(const struct of_phandle_args *args)
list_add(&rgpio_dev->list, &reset_gpio_lookup_list);
out:
mutex_unlock(&reset_gpio_lookup_mutex);
return 0;
err_put:
......@@ -970,8 +967,6 @@ static int __reset_add_reset_gpio_device(const struct of_phandle_args *args)
kfree(rgpio_dev);
err_ida_free:
ida_free(&reset_gpio_ida, id);
err_unlock:
mutex_unlock(&reset_gpio_lookup_mutex);
return ret;
}
......
......@@ -68,13 +68,14 @@ static int berlin_reset_xlate(struct reset_controller_dev *rcdev,
static int berlin2_reset_probe(struct platform_device *pdev)
{
struct device_node *parent_np = of_get_parent(pdev->dev.of_node);
struct device_node *parent_np;
struct berlin_reset_priv *priv;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
parent_np = of_get_parent(pdev->dev.of_node);
priv->regmap = syscon_node_to_regmap(parent_np);
of_node_put(parent_np);
if (IS_ERR(priv->regmap))
......
This diff is collapsed.
......@@ -90,7 +90,7 @@ static const struct reset_control_ops k210_rst_ops = {
static int k210_rst_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *parent_np = of_get_parent(dev->of_node);
struct device_node *parent_np;
struct k210_rst *ksr;
dev_info(dev, "K210 reset controller\n");
......@@ -99,6 +99,7 @@ static int k210_rst_probe(struct platform_device *pdev)
if (!ksr)
return -ENOMEM;
parent_np = of_get_parent(dev->of_node);
ksr->map = syscon_node_to_regmap(parent_np);
of_node_put(parent_np);
if (IS_ERR(ksr->map))
......
......@@ -150,29 +150,15 @@ static int lpc18xx_rgu_probe(struct platform_device *pdev)
if (IS_ERR(rc->base))
return PTR_ERR(rc->base);
rc->clk_reg = devm_clk_get(&pdev->dev, "reg");
if (IS_ERR(rc->clk_reg)) {
dev_err(&pdev->dev, "reg clock not found\n");
return PTR_ERR(rc->clk_reg);
}
rc->clk_delay = devm_clk_get(&pdev->dev, "delay");
if (IS_ERR(rc->clk_delay)) {
dev_err(&pdev->dev, "delay clock not found\n");
return PTR_ERR(rc->clk_delay);
}
ret = clk_prepare_enable(rc->clk_reg);
if (ret) {
dev_err(&pdev->dev, "unable to enable reg clock\n");
return ret;
}
rc->clk_reg = devm_clk_get_enabled(&pdev->dev, "reg");
if (IS_ERR(rc->clk_reg))
return dev_err_probe(&pdev->dev, PTR_ERR(rc->clk_reg),
"reg clock not found\n");
ret = clk_prepare_enable(rc->clk_delay);
if (ret) {
dev_err(&pdev->dev, "unable to enable delay clock\n");
goto dis_clk_reg;
}
rc->clk_delay = devm_clk_get_enabled(&pdev->dev, "delay");
if (IS_ERR(rc->clk_delay))
return dev_err_probe(&pdev->dev, PTR_ERR(rc->clk_delay),
"delay clock not found\n");
fcclk = clk_get_rate(rc->clk_reg) / USEC_PER_SEC;
firc = clk_get_rate(rc->clk_delay) / USEC_PER_SEC;
......@@ -189,10 +175,8 @@ static int lpc18xx_rgu_probe(struct platform_device *pdev)
rc->rcdev.of_node = pdev->dev.of_node;
ret = reset_controller_register(&rc->rcdev);
if (ret) {
dev_err(&pdev->dev, "unable to register device\n");
goto dis_clks;
}
if (ret)
return dev_err_probe(&pdev->dev, ret, "unable to register device\n");
rc->restart_nb.priority = 192,
rc->restart_nb.notifier_call = lpc18xx_rgu_restart,
......@@ -201,13 +185,6 @@ static int lpc18xx_rgu_probe(struct platform_device *pdev)
dev_warn(&pdev->dev, "failed to register restart handler\n");
return 0;
dis_clks:
clk_disable_unprepare(rc->clk_delay);
dis_clk_reg:
clk_disable_unprepare(rc->clk_reg);
return ret;
}
static const struct of_device_id lpc18xx_rgu_match[] = {
......
......@@ -102,6 +102,11 @@ static const struct meson_reset_param meson_s4_param = {
.level_offset = 0x40,
};
static const struct meson_reset_param t7_param = {
.reg_count = 7,
.level_offset = 0x40,
};
static const struct of_device_id meson_reset_dt_ids[] = {
{ .compatible = "amlogic,meson8b-reset", .data = &meson8b_param},
{ .compatible = "amlogic,meson-gxbb-reset", .data = &meson8b_param},
......@@ -109,6 +114,7 @@ static const struct of_device_id meson_reset_dt_ids[] = {
{ .compatible = "amlogic,meson-a1-reset", .data = &meson_a1_param},
{ .compatible = "amlogic,meson-s4-reset", .data = &meson_s4_param},
{ .compatible = "amlogic,c3-reset", .data = &meson_s4_param},
{ .compatible = "amlogic,t7-reset", .data = &t7_param},
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, meson_reset_dt_ids);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment