diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-07-10 09:46:20 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-07-10 09:46:20 -0700 |
commit | 071e5aceebebf1d33b5c29ccfd2688ed39c60007 (patch) | |
tree | 8f1800a962fb22a857939e1f50d213968c8a2e11 /drivers/reset | |
parent | e083bbd6040f4efa5c13633fb4e460b919d69dae (diff) | |
parent | 2afd1c20e7547887f37f638d6b7953138d8c948e (diff) |
Merge tag 'arm-drivers-5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
Pull ARM driver updates from Olof Johansson:
- Reset controllers: Adding support for Microchip Sparx5 Switch.
- Memory controllers: ARM Primecell PL35x SMC memory controller driver
cleanups and improvements.
- i.MX SoC drivers: Power domain support for i.MX8MM and i.MX8MN.
- Rockchip: RK3568 power domains support + DT binding updates,
cleanups.
- Qualcomm SoC drivers: Amend socinfo with more SoC/PMIC details,
including support for MSM8226, MDM9607, SM6125 and SC8180X.
- ARM FFA driver: "Firmware Framework for ARMv8-A", defining management
interfaces and communication (including bus model) between partitions
both in Normal and Secure Worlds.
- Tegra Memory controller changes, including major rework to deal with
identity mappings at boot and integration with ARM SMMU pieces.
* tag 'arm-drivers-5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (120 commits)
firmware: turris-mox-rwtm: add marvell,armada-3700-rwtm-firmware compatible string
firmware: turris-mox-rwtm: show message about HWRNG registration
firmware: turris-mox-rwtm: fail probing when firmware does not support hwrng
firmware: turris-mox-rwtm: report failures better
firmware: turris-mox-rwtm: fix reply status decoding function
soc: imx: gpcv2: add support for i.MX8MN power domains
dt-bindings: add defines for i.MX8MN power domains
firmware: tegra: bpmp: Fix Tegra234-only builds
iommu/arm-smmu: Use Tegra implementation on Tegra186
iommu/arm-smmu: tegra: Implement SID override programming
iommu/arm-smmu: tegra: Detect number of instances at runtime
dt-bindings: arm-smmu: Add Tegra186 compatible string
firmware: qcom_scm: Add MDM9607 compatible
soc: qcom: rpmpd: Add MDM9607 RPM Power Domains
soc: renesas: Add support to read LSI DEVID register of RZ/G2{L,LC} SoC's
soc: renesas: Add ARCH_R9A07G044 for the new RZ/G2L SoC's
dt-bindings: soc: rockchip: drop unnecessary #phy-cells from grf.yaml
memory: emif: remove unused frequency and voltage notifiers
memory: fsl_ifc: fix leak of private memory on probe failure
memory: fsl_ifc: fix leak of IO mapping on probe failure
...
Diffstat (limited to 'drivers/reset')
-rw-r--r-- | drivers/reset/Kconfig | 17 | ||||
-rw-r--r-- | drivers/reset/Makefile | 1 | ||||
-rw-r--r-- | drivers/reset/core.c | 25 | ||||
-rw-r--r-- | drivers/reset/hisilicon/hi6220_reset.c | 2 | ||||
-rw-r--r-- | drivers/reset/reset-a10sr.c | 1 | ||||
-rw-r--r-- | drivers/reset/reset-bcm6345.c | 2 | ||||
-rw-r--r-- | drivers/reset/reset-berlin.c | 12 | ||||
-rw-r--r-- | drivers/reset/reset-brcmstb.c | 1 | ||||
-rw-r--r-- | drivers/reset/reset-lantiq.c | 2 | ||||
-rw-r--r-- | drivers/reset/reset-microchip-sparx5.c | 146 | ||||
-rw-r--r-- | drivers/reset/reset-oxnas.c | 2 | ||||
-rw-r--r-- | drivers/reset/reset-ti-syscon.c | 4 | ||||
-rw-r--r-- | drivers/reset/reset-uniphier.c | 2 | ||||
-rw-r--r-- | drivers/reset/reset-zynqmp.c | 4 | ||||
-rw-r--r-- | drivers/reset/sti/reset-syscfg.c | 2 |
15 files changed, 196 insertions, 27 deletions
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 29fb33c0e26d..328f70f633eb 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -43,8 +43,9 @@ config RESET_BCM6345 This enables the reset controller driver for BCM6345 SoCs. config RESET_BERLIN - bool "Berlin Reset Driver" if COMPILE_TEST - default ARCH_BERLIN + tristate "Berlin Reset Driver" + depends on ARCH_BERLIN || COMPILE_TEST + default m if ARCH_BERLIN help This enables the reset controller driver for Marvell Berlin SoCs. @@ -59,7 +60,8 @@ config RESET_BRCMSTB config RESET_BRCMSTB_RESCAL bool "Broadcom STB RESCAL reset controller" depends on HAS_IOMEM - default ARCH_BRCMSTB || COMPILE_TEST + depends on ARCH_BRCMSTB || COMPILE_TEST + default ARCH_BRCMSTB help This enables the RESCAL reset controller for SATA, PCIe0, or PCIe1 on BCM7216. @@ -82,6 +84,7 @@ config RESET_IMX7 config RESET_INTEL_GW bool "Intel Reset Controller Driver" + depends on X86 || COMPILE_TEST depends on OF && HAS_IOMEM select REGMAP_MMIO help @@ -111,6 +114,14 @@ config RESET_LPC18XX help This enables the reset controller driver for NXP LPC18xx/43xx SoCs. +config RESET_MCHP_SPARX5 + bool "Microchip Sparx5 reset driver" + depends on HAS_IOMEM || COMPILE_TEST + default y if SPARX5_SWITCH + select MFD_SYSCON + help + This driver supports switch core reset for the Microchip Sparx5 SoC. + config RESET_MESON tristate "Meson Reset Driver" depends on ARCH_MESON || COMPILE_TEST diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index ac3e612ad953..ea8b8d9ca565 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_RESET_INTEL_GW) += reset-intel-gw.o obj-$(CONFIG_RESET_K210) += reset-k210.o obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o +obj-$(CONFIG_RESET_MCHP_SPARX5) += reset-microchip-sparx5.o obj-$(CONFIG_RESET_MESON) += reset-meson.o obj-$(CONFIG_RESET_MESON_AUDIO_ARB) += reset-meson-audio-arb.o obj-$(CONFIG_RESET_NPCM) += reset-npcm.o diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 71c1c8264b2d..61e688882643 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -84,7 +84,7 @@ static const char *rcdev_name(struct reset_controller_dev *rcdev) * without gaps. */ static int of_reset_simple_xlate(struct reset_controller_dev *rcdev, - const struct of_phandle_args *reset_spec) + const struct of_phandle_args *reset_spec) { if (reset_spec->args[0] >= rcdev->nr_resets) return -EINVAL; @@ -744,9 +744,9 @@ void reset_control_bulk_release(int num_rstcs, } EXPORT_SYMBOL_GPL(reset_control_bulk_release); -static struct reset_control *__reset_control_get_internal( - struct reset_controller_dev *rcdev, - unsigned int index, bool shared, bool acquired) +static struct reset_control * +__reset_control_get_internal(struct reset_controller_dev *rcdev, + unsigned int index, bool shared, bool acquired) { struct reset_control *rstc; @@ -774,7 +774,10 @@ static struct reset_control *__reset_control_get_internal( if (!rstc) return ERR_PTR(-ENOMEM); - try_module_get(rcdev->owner); + if (!try_module_get(rcdev->owner)) { + kfree(rstc); + return ERR_PTR(-ENODEV); + } rstc->rcdev = rcdev; list_add(&rstc->list, &rcdev->reset_control_head); @@ -806,9 +809,9 @@ static void __reset_control_put_internal(struct reset_control *rstc) kref_put(&rstc->refcnt, __reset_control_release); } -struct reset_control *__of_reset_control_get(struct device_node *node, - const char *id, int index, bool shared, - bool optional, bool acquired) +struct reset_control * +__of_reset_control_get(struct device_node *node, const char *id, int index, + bool shared, bool optional, bool acquired) { struct reset_control *rstc; struct reset_controller_dev *r, *rcdev; @@ -1027,9 +1030,9 @@ static void devm_reset_control_release(struct device *dev, void *res) reset_control_put(*(struct reset_control **)res); } -struct reset_control *__devm_reset_control_get(struct device *dev, - const char *id, int index, bool shared, - bool optional, bool acquired) +struct reset_control * +__devm_reset_control_get(struct device *dev, const char *id, int index, + bool shared, bool optional, bool acquired) { struct reset_control **ptr, *rstc; diff --git a/drivers/reset/hisilicon/hi6220_reset.c b/drivers/reset/hisilicon/hi6220_reset.c index 19926506d033..5ca145b64e63 100644 --- a/drivers/reset/hisilicon/hi6220_reset.c +++ b/drivers/reset/hisilicon/hi6220_reset.c @@ -3,7 +3,7 @@ * Hisilicon Hi6220 reset controller driver * * Copyright (c) 2016 Linaro Limited. - * Copyright (c) 2015-2016 Hisilicon Limited. + * Copyright (c) 2015-2016 HiSilicon Limited. * * Author: Feng Chen <puck.chen@hisilicon.com> */ diff --git a/drivers/reset/reset-a10sr.c b/drivers/reset/reset-a10sr.c index 7eacc89382f8..99b3bc8382f3 100644 --- a/drivers/reset/reset-a10sr.c +++ b/drivers/reset/reset-a10sr.c @@ -118,6 +118,7 @@ static struct platform_driver a10sr_reset_driver = { .probe = a10sr_reset_probe, .driver = { .name = "altr_a10sr_reset", + .of_match_table = a10sr_reset_of_match, }, }; module_platform_driver(a10sr_reset_driver); diff --git a/drivers/reset/reset-bcm6345.c b/drivers/reset/reset-bcm6345.c index 737e4e81f6b7..ac6c7ad1deda 100644 --- a/drivers/reset/reset-bcm6345.c +++ b/drivers/reset/reset-bcm6345.c @@ -86,7 +86,7 @@ static int bcm6345_reset_status(struct reset_controller_dev *rcdev, return !(__raw_readl(bcm6345_reset->base) & BIT(id)); } -static struct reset_control_ops bcm6345_reset_ops = { +static const struct reset_control_ops bcm6345_reset_ops = { .assert = bcm6345_reset_assert, .deassert = bcm6345_reset_deassert, .reset = bcm6345_reset_reset, diff --git a/drivers/reset/reset-berlin.c b/drivers/reset/reset-berlin.c index 371197bbd055..2537ec05ecee 100644 --- a/drivers/reset/reset-berlin.c +++ b/drivers/reset/reset-berlin.c @@ -14,7 +14,7 @@ #include <linux/delay.h> #include <linux/io.h> #include <linux/mfd/syscon.h> -#include <linux/init.h> +#include <linux/module.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/platform_device.h> @@ -55,7 +55,7 @@ static const struct reset_control_ops berlin_reset_ops = { static int berlin_reset_xlate(struct reset_controller_dev *rcdev, const struct of_phandle_args *reset_spec) { - unsigned offset, bit; + unsigned int offset, bit; offset = reset_spec->args[0]; bit = reset_spec->args[1]; @@ -93,6 +93,7 @@ static const struct of_device_id berlin_reset_dt_match[] = { { .compatible = "marvell,berlin2-reset" }, { }, }; +MODULE_DEVICE_TABLE(of, berlin_reset_dt_match); static struct platform_driver berlin_reset_driver = { .probe = berlin2_reset_probe, @@ -101,4 +102,9 @@ static struct platform_driver berlin_reset_driver = { .of_match_table = berlin_reset_dt_match, }, }; -builtin_platform_driver(berlin_reset_driver); +module_platform_driver(berlin_reset_driver); + +MODULE_AUTHOR("Antoine Tenart <antoine.tenart@free-electrons.com>"); +MODULE_AUTHOR("Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>"); +MODULE_DESCRIPTION("Synaptics Berlin reset controller"); +MODULE_LICENSE("GPL"); diff --git a/drivers/reset/reset-brcmstb.c b/drivers/reset/reset-brcmstb.c index f213264c8567..42c9d5241c53 100644 --- a/drivers/reset/reset-brcmstb.c +++ b/drivers/reset/reset-brcmstb.c @@ -111,6 +111,7 @@ static const struct of_device_id brcmstb_reset_of_match[] = { { .compatible = "brcm,brcmstb-reset" }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, brcmstb_reset_of_match); static struct platform_driver brcmstb_reset_driver = { .probe = brcmstb_reset_probe, diff --git a/drivers/reset/reset-lantiq.c b/drivers/reset/reset-lantiq.c index ac41d093de13..b936cfe85641 100644 --- a/drivers/reset/reset-lantiq.c +++ b/drivers/reset/reset-lantiq.c @@ -186,7 +186,7 @@ static int lantiq_rcu_reset_probe(struct platform_device *pdev) priv->rcdev.of_xlate = lantiq_rcu_reset_xlate; priv->rcdev.of_reset_n_cells = 2; - return reset_controller_register(&priv->rcdev); + return devm_reset_controller_register(&pdev->dev, &priv->rcdev); } static const struct of_device_id lantiq_rcu_reset_dt_ids[] = { diff --git a/drivers/reset/reset-microchip-sparx5.c b/drivers/reset/reset-microchip-sparx5.c new file mode 100644 index 000000000000..f01e7db8e83b --- /dev/null +++ b/drivers/reset/reset-microchip-sparx5.c @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* Microchip Sparx5 Switch Reset driver + * + * Copyright (c) 2020 Microchip Technology Inc. and its subsidiaries. + * + * The Sparx5 Chip Register Model can be browsed at this location: + * https://github.com/microchip-ung/sparx-5_reginfo + */ +#include <linux/mfd/syscon.h> +#include <linux/of_device.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/reset-controller.h> + +#define PROTECT_REG 0x84 +#define PROTECT_BIT BIT(10) +#define SOFT_RESET_REG 0x00 +#define SOFT_RESET_BIT BIT(1) + +struct mchp_reset_context { + struct regmap *cpu_ctrl; + struct regmap *gcb_ctrl; + struct reset_controller_dev rcdev; +}; + +static struct regmap_config sparx5_reset_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, +}; + +static int sparx5_switch_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct mchp_reset_context *ctx = + container_of(rcdev, struct mchp_reset_context, rcdev); + u32 val; + + /* Make sure the core is PROTECTED from reset */ + regmap_update_bits(ctx->cpu_ctrl, PROTECT_REG, PROTECT_BIT, PROTECT_BIT); + + /* Start soft reset */ + regmap_write(ctx->gcb_ctrl, SOFT_RESET_REG, SOFT_RESET_BIT); + + /* Wait for soft reset done */ + return regmap_read_poll_timeout(ctx->gcb_ctrl, SOFT_RESET_REG, val, + (val & SOFT_RESET_BIT) == 0, + 1, 100); +} + +static const struct reset_control_ops sparx5_reset_ops = { + .reset = sparx5_switch_reset, +}; + +static int mchp_sparx5_map_syscon(struct platform_device *pdev, char *name, + struct regmap **target) +{ + struct device_node *syscon_np; + struct regmap *regmap; + int err; + + syscon_np = of_parse_phandle(pdev->dev.of_node, name, 0); + if (!syscon_np) + return -ENODEV; + regmap = syscon_node_to_regmap(syscon_np); + of_node_put(syscon_np); + if (IS_ERR(regmap)) { + err = PTR_ERR(regmap); + dev_err(&pdev->dev, "No '%s' map: %d\n", name, err); + return err; + } + *target = regmap; + return 0; +} + +static int mchp_sparx5_map_io(struct platform_device *pdev, int index, + struct regmap **target) +{ + struct resource *res; + struct regmap *map; + void __iomem *mem; + + mem = devm_platform_get_and_ioremap_resource(pdev, index, &res); + if (IS_ERR(mem)) { + dev_err(&pdev->dev, "Could not map resource %d\n", index); + return PTR_ERR(mem); + } + sparx5_reset_regmap_config.name = res->name; + map = devm_regmap_init_mmio(&pdev->dev, mem, &sparx5_reset_regmap_config); + if (IS_ERR(map)) + return PTR_ERR(map); + *target = map; + return 0; +} + +static int mchp_sparx5_reset_probe(struct platform_device *pdev) +{ + struct device_node *dn = pdev->dev.of_node; + struct mchp_reset_context *ctx; + int err; + + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + err = mchp_sparx5_map_syscon(pdev, "cpu-syscon", &ctx->cpu_ctrl); + if (err) + return err; + err = mchp_sparx5_map_io(pdev, 0, &ctx->gcb_ctrl); + if (err) + return err; + + ctx->rcdev.owner = THIS_MODULE; + ctx->rcdev.nr_resets = 1; + ctx->rcdev.ops = &sparx5_reset_ops; + ctx->rcdev.of_node = dn; + + return devm_reset_controller_register(&pdev->dev, &ctx->rcdev); +} + +static const struct of_device_id mchp_sparx5_reset_of_match[] = { + { + .compatible = "microchip,sparx5-switch-reset", + }, + { } +}; + +static struct platform_driver mchp_sparx5_reset_driver = { + .probe = mchp_sparx5_reset_probe, + .driver = { + .name = "sparx5-switch-reset", + .of_match_table = mchp_sparx5_reset_of_match, + }, +}; + +static int __init mchp_sparx5_reset_init(void) +{ + return platform_driver_register(&mchp_sparx5_reset_driver); +} + +postcore_initcall(mchp_sparx5_reset_init); + +MODULE_DESCRIPTION("Microchip Sparx5 switch reset driver"); +MODULE_AUTHOR("Steen Hegelund <steen.hegelund@microchip.com>"); +MODULE_LICENSE("Dual MIT/GPL"); diff --git a/drivers/reset/reset-oxnas.c b/drivers/reset/reset-oxnas.c index c4013165bdda..8209f922dc16 100644 --- a/drivers/reset/reset-oxnas.c +++ b/drivers/reset/reset-oxnas.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * drivers/reset/reset-oxnas.c + * Oxford Semiconductor Reset Controller driver * * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com> * Copyright (C) 2014 Ma Haijun <mahaijuns@gmail.com> diff --git a/drivers/reset/reset-ti-syscon.c b/drivers/reset/reset-ti-syscon.c index 218370faf37b..2b92775d58f0 100644 --- a/drivers/reset/reset-ti-syscon.c +++ b/drivers/reset/reset-ti-syscon.c @@ -58,8 +58,8 @@ struct ti_syscon_reset_data { unsigned int nr_controls; }; -#define to_ti_syscon_reset_data(rcdev) \ - container_of(rcdev, struct ti_syscon_reset_data, rcdev) +#define to_ti_syscon_reset_data(_rcdev) \ + container_of(_rcdev, struct ti_syscon_reset_data, rcdev) /** * ti_syscon_reset_assert() - assert device reset diff --git a/drivers/reset/reset-uniphier.c b/drivers/reset/reset-uniphier.c index 279e535bf5d8..5f75783f9397 100644 --- a/drivers/reset/reset-uniphier.c +++ b/drivers/reset/reset-uniphier.c @@ -20,7 +20,7 @@ struct uniphier_reset_data { #define UNIPHIER_RESET_ACTIVE_LOW BIT(0) }; -#define UNIPHIER_RESET_ID_END (unsigned int)(-1) +#define UNIPHIER_RESET_ID_END ((unsigned int)(-1)) #define UNIPHIER_RESET_END \ { .id = UNIPHIER_RESET_ID_END } diff --git a/drivers/reset/reset-zynqmp.c b/drivers/reset/reset-zynqmp.c index ebd433fa09dd..daa425e74c96 100644 --- a/drivers/reset/reset-zynqmp.c +++ b/drivers/reset/reset-zynqmp.c @@ -83,8 +83,8 @@ static const struct zynqmp_reset_soc_data zynqmp_reset_data = { }; static const struct zynqmp_reset_soc_data versal_reset_data = { - .reset_id = 0, - .num_resets = VERSAL_NR_RESETS, + .reset_id = 0, + .num_resets = VERSAL_NR_RESETS, }; static const struct reset_control_ops zynqmp_reset_ops = { diff --git a/drivers/reset/sti/reset-syscfg.c b/drivers/reset/sti/reset-syscfg.c index 99b63035fe72..b4b46e0f207e 100644 --- a/drivers/reset/sti/reset-syscfg.c +++ b/drivers/reset/sti/reset-syscfg.c @@ -153,7 +153,7 @@ static int syscfg_reset_controller_register(struct device *dev, if (!rc->channels) return -ENOMEM; - rc->rst.ops = &syscfg_reset_ops, + rc->rst.ops = &syscfg_reset_ops; rc->rst.of_node = dev->of_node; rc->rst.nr_resets = data->nr_channels; rc->active_low = data->active_low; |