diff options
Diffstat (limited to 'drivers/reset')
-rw-r--r-- | drivers/reset/Kconfig | 2 | ||||
-rw-r--r-- | drivers/reset/core.c | 15 | ||||
-rw-r--r-- | drivers/reset/reset-meson.c | 6 | ||||
-rw-r--r-- | drivers/reset/reset-rzg2l-usbphy-ctrl.c | 4 | ||||
-rw-r--r-- | drivers/reset/reset-simple.c | 1 | ||||
-rw-r--r-- | drivers/reset/reset-uniphier-glue.c | 75 | ||||
-rw-r--r-- | drivers/reset/tegra/reset-bpmp.c | 9 |
7 files changed, 67 insertions, 45 deletions
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index d6cb52a1dce7..93c8d07ee328 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -183,7 +183,7 @@ config RESET_RASPBERRYPI config RESET_RZG2L_USBPHY_CTRL tristate "Renesas RZ/G2L USBPHY control driver" - depends on ARCH_R9A07G044 || COMPILE_TEST + depends on ARCH_RZG2L || COMPILE_TEST help Support for USBPHY Control found on RZ/G2L family. It mainly controls reset and power down of the USB/PHY. diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 61e688882643..f0a076e94118 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -12,6 +12,7 @@ #include <linux/kref.h> #include <linux/module.h> #include <linux/of.h> +#include <linux/acpi.h> #include <linux/reset.h> #include <linux/reset-controller.h> #include <linux/slab.h> @@ -1100,13 +1101,25 @@ EXPORT_SYMBOL_GPL(__devm_reset_control_bulk_get); * * Convenience wrapper for __reset_control_get() and reset_control_reset(). * This is useful for the common case of devices with single, dedicated reset - * lines. + * lines. _RST firmware method will be called for devices with ACPI. */ int __device_reset(struct device *dev, bool optional) { struct reset_control *rstc; int ret; +#ifdef CONFIG_ACPI + acpi_handle handle = ACPI_HANDLE(dev); + + if (handle) { + if (!acpi_has_method(handle, "_RST")) + return optional ? 0 : -ENOENT; + if (ACPI_FAILURE(acpi_evaluate_object(handle, "_RST", NULL, + NULL))) + return -EIO; + } +#endif + rstc = __reset_control_get(dev, NULL, 0, 0, optional, true); if (IS_ERR(rstc)) return PTR_ERR(rstc); diff --git a/drivers/reset/reset-meson.c b/drivers/reset/reset-meson.c index c9bc325ad65a..26dc54778615 100644 --- a/drivers/reset/reset-meson.c +++ b/drivers/reset/reset-meson.c @@ -98,11 +98,17 @@ static const struct meson_reset_param meson_a1_param = { .level_offset = 0x40, }; +static const struct meson_reset_param meson_s4_param = { + .reg_count = 6, + .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}, { .compatible = "amlogic,meson-axg-reset", .data = &meson8b_param}, { .compatible = "amlogic,meson-a1-reset", .data = &meson_a1_param}, + { .compatible = "amlogic,meson-s4-reset", .data = &meson_s4_param}, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, meson_reset_dt_ids); diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c index 1e8315038850..a8dde4606360 100644 --- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c +++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c @@ -121,7 +121,9 @@ static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev) return dev_err_probe(dev, PTR_ERR(priv->rstc), "failed to get reset\n"); - reset_control_deassert(priv->rstc); + error = reset_control_deassert(priv->rstc); + if (error) + return error; priv->rcdev.ops = &rzg2l_usbphy_ctrl_reset_ops; priv->rcdev.of_reset_n_cells = 1; diff --git a/drivers/reset/reset-simple.c b/drivers/reset/reset-simple.c index 4dda0daf2c6f..361a68314265 100644 --- a/drivers/reset/reset-simple.c +++ b/drivers/reset/reset-simple.c @@ -144,6 +144,7 @@ static const struct of_device_id reset_simple_dt_ids[] = { .data = &reset_simple_active_low }, { .compatible = "aspeed,ast2400-lpc-reset" }, { .compatible = "aspeed,ast2500-lpc-reset" }, + { .compatible = "aspeed,ast2600-lpc-reset" }, { .compatible = "bitmain,bm1880-reset", .data = &reset_simple_active_low }, { .compatible = "brcm,bcm4908-misc-pcie-reset", diff --git a/drivers/reset/reset-uniphier-glue.c b/drivers/reset/reset-uniphier-glue.c index 908c1d5bc41e..146fd5d45e99 100644 --- a/drivers/reset/reset-uniphier-glue.c +++ b/drivers/reset/reset-uniphier-glue.c @@ -23,19 +23,32 @@ struct uniphier_glue_reset_soc_data { struct uniphier_glue_reset_priv { struct clk_bulk_data clk[MAX_CLKS]; - struct reset_control *rst[MAX_RSTS]; + struct reset_control_bulk_data rst[MAX_RSTS]; struct reset_simple_data rdata; const struct uniphier_glue_reset_soc_data *data; }; +static void uniphier_clk_disable(void *_priv) +{ + struct uniphier_glue_reset_priv *priv = _priv; + + clk_bulk_disable_unprepare(priv->data->nclks, priv->clk); +} + +static void uniphier_rst_assert(void *_priv) +{ + struct uniphier_glue_reset_priv *priv = _priv; + + reset_control_bulk_assert(priv->data->nrsts, priv->rst); +} + static int uniphier_glue_reset_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct uniphier_glue_reset_priv *priv; struct resource *res; resource_size_t size; - const char *name; - int i, ret, nr; + int i, ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -58,22 +71,28 @@ static int uniphier_glue_reset_probe(struct platform_device *pdev) if (ret) return ret; - for (i = 0; i < priv->data->nrsts; i++) { - name = priv->data->reset_names[i]; - priv->rst[i] = devm_reset_control_get_shared(dev, name); - if (IS_ERR(priv->rst[i])) - return PTR_ERR(priv->rst[i]); - } + for (i = 0; i < priv->data->nrsts; i++) + priv->rst[i].id = priv->data->reset_names[i]; + ret = devm_reset_control_bulk_get_shared(dev, priv->data->nrsts, + priv->rst); + if (ret) + return ret; ret = clk_bulk_prepare_enable(priv->data->nclks, priv->clk); if (ret) return ret; - for (nr = 0; nr < priv->data->nrsts; nr++) { - ret = reset_control_deassert(priv->rst[nr]); - if (ret) - goto out_rst_assert; - } + ret = devm_add_action_or_reset(dev, uniphier_clk_disable, priv); + if (ret) + return ret; + + ret = reset_control_bulk_deassert(priv->data->nrsts, priv->rst); + if (ret) + return ret; + + ret = devm_add_action_or_reset(dev, uniphier_rst_assert, priv); + if (ret) + return ret; spin_lock_init(&priv->rdata.lock); priv->rdata.rcdev.owner = THIS_MODULE; @@ -84,32 +103,7 @@ static int uniphier_glue_reset_probe(struct platform_device *pdev) platform_set_drvdata(pdev, priv); - ret = devm_reset_controller_register(dev, &priv->rdata.rcdev); - if (ret) - goto out_rst_assert; - - return 0; - -out_rst_assert: - while (nr--) - reset_control_assert(priv->rst[nr]); - - clk_bulk_disable_unprepare(priv->data->nclks, priv->clk); - - return ret; -} - -static int uniphier_glue_reset_remove(struct platform_device *pdev) -{ - struct uniphier_glue_reset_priv *priv = platform_get_drvdata(pdev); - int i; - - for (i = 0; i < priv->data->nrsts; i++) - reset_control_assert(priv->rst[i]); - - clk_bulk_disable_unprepare(priv->data->nclks, priv->clk); - - return 0; + return devm_reset_controller_register(dev, &priv->rdata.rcdev); } static const char * const uniphier_pro4_clock_reset_names[] = { @@ -177,7 +171,6 @@ MODULE_DEVICE_TABLE(of, uniphier_glue_reset_match); static struct platform_driver uniphier_glue_reset_driver = { .probe = uniphier_glue_reset_probe, - .remove = uniphier_glue_reset_remove, .driver = { .name = "uniphier-glue-reset", .of_match_table = uniphier_glue_reset_match, diff --git a/drivers/reset/tegra/reset-bpmp.c b/drivers/reset/tegra/reset-bpmp.c index 24d3395964cc..4c5bba52b105 100644 --- a/drivers/reset/tegra/reset-bpmp.c +++ b/drivers/reset/tegra/reset-bpmp.c @@ -20,6 +20,7 @@ static int tegra_bpmp_reset_common(struct reset_controller_dev *rstc, struct tegra_bpmp *bpmp = to_tegra_bpmp(rstc); struct mrq_reset_request request; struct tegra_bpmp_message msg; + int err; memset(&request, 0, sizeof(request)); request.cmd = command; @@ -30,7 +31,13 @@ static int tegra_bpmp_reset_common(struct reset_controller_dev *rstc, msg.tx.data = &request; msg.tx.size = sizeof(request); - return tegra_bpmp_transfer(bpmp, &msg); + err = tegra_bpmp_transfer(bpmp, &msg); + if (err) + return err; + if (msg.rx.ret) + return -EINVAL; + + return 0; } static int tegra_bpmp_reset_module(struct reset_controller_dev *rstc, |