Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'reset-for-5.6' of git://git.pengutronix.de/pza/linux into arm/drivers

Reset controller updates for v5.6

This tag adds support for the Nuvoton NPCM, Intel Gatway SoC, and
Broadcom BCM7216 RESCAL reset controllers, adds missing SCSSI reset
controls for newer Uniphier SoCs, aligns the program flow in the
devm_reset_controller_register, __devm_reset_control_get, and
devm_reset_control_array_get functions for better consistency,
and allows to build the Qcom AOSS reset driver as a module.

This is based on v5.5-rc3 because the core patch depends on commit
db23808615e2 ("reset: Do not register resource data for missing
resets").

* tag 'reset-for-5.6' of git://git.pengutronix.de/pza/linux:
reset: qcom-aoss: Allow CONFIG_RESET_QCOM_AOSS to be a tristate
reset: Add Broadcom STB RESCAL reset controller
dt-bindings: reset: Document BCM7216 RESCAL reset controller
reset: intel: Add system reset controller driver
dt-bindings: reset: Add YAML schemas for the Intel Reset controller
reset: uniphier: Add SCSSI reset control for each channel
reset: Align logic and flow in managed helpers
reset: npcm: add NPCM reset controller driver
dt-bindings: reset: Add binding constants for NPCM7xx reset controller
dt-bindings: reset: add NPCM reset controller documentation

Link: https://lore.kernel.org/r/dbbb2ca7490a0146d9ba632fd4d9f38063e03e9f.camel@pengutronix.de
Signed-off-by: Olof Johansson <olof@lixom.net>

+937 -23
+37
Documentation/devicetree/bindings/reset/brcm,bcm7216-pcie-sata-rescal.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + # Copyright 2020 Broadcom 3 + %YAML 1.2 4 + --- 5 + $id: "http://devicetree.org/schemas/reset/brcm,bcm7216-pcie-sata-rescal.yaml#" 6 + $schema: "http://devicetree.org/meta-schemas/core.yaml#" 7 + 8 + title: BCM7216 RESCAL reset controller 9 + 10 + description: This document describes the BCM7216 RESCAL reset controller which is responsible for controlling the reset of the SATA and PCIe0/1 instances on BCM7216. 11 + 12 + maintainers: 13 + - Florian Fainelli <f.fainelli@gmail.com> 14 + - Jim Quinlan <jim2101024@gmail.com> 15 + 16 + properties: 17 + compatible: 18 + const: brcm,bcm7216-pcie-sata-rescal 19 + 20 + reg: 21 + maxItems: 1 22 + 23 + "#reset-cells": 24 + const: 0 25 + 26 + required: 27 + - compatible 28 + - reg 29 + - "#reset-cells" 30 + 31 + examples: 32 + - | 33 + reset-controller@8b2c800 { 34 + compatible = "brcm,bcm7216-pcie-sata-rescal"; 35 + reg = <0x8b2c800 0x10>; 36 + #reset-cells = <0>; 37 + };
+63
Documentation/devicetree/bindings/reset/intel,rcu-gw.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/reset/intel,rcu-gw.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: System Reset Controller on Intel Gateway SoCs 8 + 9 + maintainers: 10 + - Dilip Kota <eswara.kota@linux.intel.com> 11 + 12 + properties: 13 + compatible: 14 + enum: 15 + - intel,rcu-lgm 16 + - intel,rcu-xrx200 17 + 18 + reg: 19 + description: Reset controller registers. 20 + maxItems: 1 21 + 22 + intel,global-reset: 23 + description: Global reset register offset and bit offset. 24 + allOf: 25 + - $ref: /schemas/types.yaml#/definitions/uint32-array 26 + - maxItems: 2 27 + 28 + "#reset-cells": 29 + minimum: 2 30 + maximum: 3 31 + description: | 32 + First cell is reset request register offset. 33 + Second cell is bit offset in reset request register. 34 + Third cell is bit offset in reset status register. 35 + For LGM SoC, reset cell count is 2 as bit offset in 36 + reset request and reset status registers is same. Whereas 37 + 3 for legacy SoCs as bit offset differs. 38 + 39 + required: 40 + - compatible 41 + - reg 42 + - intel,global-reset 43 + - "#reset-cells" 44 + 45 + additionalProperties: false 46 + 47 + examples: 48 + - | 49 + rcu0: reset-controller@e0000000 { 50 + compatible = "intel,rcu-lgm"; 51 + reg = <0xe0000000 0x20000>; 52 + intel,global-reset = <0x10 30>; 53 + #reset-cells = <2>; 54 + }; 55 + 56 + pwm: pwm@e0d00000 { 57 + status = "disabled"; 58 + compatible = "intel,lgm-pwm"; 59 + reg = <0xe0d00000 0x30>; 60 + clocks = <&cgu0 1>; 61 + #pwm-cells = <2>; 62 + resets = <&rcu0 0x30 21>; 63 + };
+32
Documentation/devicetree/bindings/reset/nuvoton,npcm-reset.txt
··· 1 + Nuvoton NPCM Reset controller 2 + 3 + Required properties: 4 + - compatible : "nuvoton,npcm750-reset" for NPCM7XX BMC 5 + - reg : specifies physical base address and size of the register. 6 + - #reset-cells: must be set to 2 7 + 8 + Optional property: 9 + - nuvoton,sw-reset-number - Contains the software reset number to restart the SoC. 10 + NPCM7xx contain four software reset that represent numbers 1 to 4. 11 + 12 + If 'nuvoton,sw-reset-number' is not specfied software reset is disabled. 13 + 14 + Example: 15 + rstc: rstc@f0801000 { 16 + compatible = "nuvoton,npcm750-reset"; 17 + reg = <0xf0801000 0x70>; 18 + #reset-cells = <2>; 19 + nuvoton,sw-reset-number = <2>; 20 + }; 21 + 22 + Specifying reset lines connected to IP NPCM7XX modules 23 + ====================================================== 24 + example: 25 + 26 + spi0: spi@..... { 27 + ... 28 + resets = <&rstc NPCM7XX_RESET_IPSRST2 NPCM7XX_RESET_PSPI1>; 29 + ... 30 + }; 31 + 32 + The index could be found in <dt-bindings/reset/nuvoton,npcm7xx-reset.h>.
+24 -1
drivers/reset/Kconfig
··· 49 49 This enables the reset controller driver for Broadcom STB SoCs using 50 50 a SUN_TOP_CTRL_SW_INIT style controller. 51 51 52 + config RESET_BRCMSTB_RESCAL 53 + bool "Broadcom STB RESCAL reset controller" 54 + default ARCH_BRCMSTB || COMPILE_TEST 55 + help 56 + This enables the RESCAL reset controller for SATA, PCIe0, or PCIe1 on 57 + BCM7216. 58 + 52 59 config RESET_HSDK 53 60 bool "Synopsys HSDK Reset Driver" 54 61 depends on HAS_IOMEM ··· 70 63 select MFD_SYSCON 71 64 help 72 65 This enables the reset controller driver for i.MX7 SoCs. 66 + 67 + config RESET_INTEL_GW 68 + bool "Intel Reset Controller Driver" 69 + depends on OF 70 + select REGMAP_MMIO 71 + help 72 + This enables the reset controller driver for Intel Gateway SoCs. 73 + Say Y to control the reset signals provided by reset controller. 74 + Otherwise, say N. 73 75 74 76 config RESET_LANTIQ 75 77 bool "Lantiq XWAY Reset Driver" if COMPILE_TEST ··· 105 89 This enables the reset driver for Audio Memory Arbiter of 106 90 Amlogic's A113 based SoCs 107 91 92 + config RESET_NPCM 93 + bool "NPCM BMC Reset Driver" if COMPILE_TEST 94 + default ARCH_NPCM 95 + help 96 + This enables the reset controller driver for Nuvoton NPCM 97 + BMC SoCs. 98 + 108 99 config RESET_OXNAS 109 100 bool 110 101 ··· 122 99 This enables the reset driver for ImgTec Pistachio SoCs. 123 100 124 101 config RESET_QCOM_AOSS 125 - bool "Qcom AOSS Reset Driver" 102 + tristate "Qcom AOSS Reset Driver" 126 103 depends on ARCH_QCOM || COMPILE_TEST 127 104 help 128 105 This enables the AOSS (always on subsystem) reset driver
+3
drivers/reset/Makefile
··· 8 8 obj-$(CONFIG_RESET_AXS10X) += reset-axs10x.o 9 9 obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o 10 10 obj-$(CONFIG_RESET_BRCMSTB) += reset-brcmstb.o 11 + obj-$(CONFIG_RESET_BRCMSTB_RESCAL) += reset-brcmstb-rescal.o 11 12 obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o 12 13 obj-$(CONFIG_RESET_IMX7) += reset-imx7.o 14 + obj-$(CONFIG_RESET_INTEL_GW) += reset-intel-gw.o 13 15 obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o 14 16 obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o 15 17 obj-$(CONFIG_RESET_MESON) += reset-meson.o 16 18 obj-$(CONFIG_RESET_MESON_AUDIO_ARB) += reset-meson-audio-arb.o 19 + obj-$(CONFIG_RESET_NPCM) += reset-npcm.o 17 20 obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o 18 21 obj-$(CONFIG_RESET_PISTACHIO) += reset-pistachio.o 19 22 obj-$(CONFIG_RESET_QCOM_AOSS) += reset-qcom-aoss.o
+17 -16
drivers/reset/core.c
··· 150 150 return -ENOMEM; 151 151 152 152 ret = reset_controller_register(rcdev); 153 - if (!ret) { 154 - *rcdevp = rcdev; 155 - devres_add(dev, rcdevp); 156 - } else { 153 + if (ret) { 157 154 devres_free(rcdevp); 155 + return ret; 158 156 } 157 + 158 + *rcdevp = rcdev; 159 + devres_add(dev, rcdevp); 159 160 160 161 return ret; 161 162 } ··· 788 787 return ERR_PTR(-ENOMEM); 789 788 790 789 rstc = __reset_control_get(dev, id, index, shared, optional, acquired); 791 - if (!IS_ERR_OR_NULL(rstc)) { 792 - *ptr = rstc; 793 - devres_add(dev, ptr); 794 - } else { 790 + if (IS_ERR_OR_NULL(rstc)) { 795 791 devres_free(ptr); 792 + return rstc; 796 793 } 794 + 795 + *ptr = rstc; 796 + devres_add(dev, ptr); 797 797 798 798 return rstc; 799 799 } ··· 921 919 struct reset_control * 922 920 devm_reset_control_array_get(struct device *dev, bool shared, bool optional) 923 921 { 924 - struct reset_control **devres; 925 - struct reset_control *rstc; 922 + struct reset_control **ptr, *rstc; 926 923 927 - devres = devres_alloc(devm_reset_control_release, sizeof(*devres), 928 - GFP_KERNEL); 929 - if (!devres) 924 + ptr = devres_alloc(devm_reset_control_release, sizeof(*ptr), 925 + GFP_KERNEL); 926 + if (!ptr) 930 927 return ERR_PTR(-ENOMEM); 931 928 932 929 rstc = of_reset_control_array_get(dev->of_node, shared, optional, true); 933 930 if (IS_ERR_OR_NULL(rstc)) { 934 - devres_free(devres); 931 + devres_free(ptr); 935 932 return rstc; 936 933 } 937 934 938 - *devres = rstc; 939 - devres_add(dev, devres); 935 + *ptr = rstc; 936 + devres_add(dev, ptr); 940 937 941 938 return rstc; 942 939 }
+107
drivers/reset/reset-brcmstb-rescal.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (C) 2018-2020 Broadcom */ 3 + 4 + #include <linux/device.h> 5 + #include <linux/iopoll.h> 6 + #include <linux/module.h> 7 + #include <linux/of.h> 8 + #include <linux/platform_device.h> 9 + #include <linux/reset-controller.h> 10 + 11 + #define BRCM_RESCAL_START 0x0 12 + #define BRCM_RESCAL_START_BIT BIT(0) 13 + #define BRCM_RESCAL_CTRL 0x4 14 + #define BRCM_RESCAL_STATUS 0x8 15 + #define BRCM_RESCAL_STATUS_BIT BIT(0) 16 + 17 + struct brcm_rescal_reset { 18 + void __iomem *base; 19 + struct device *dev; 20 + struct reset_controller_dev rcdev; 21 + }; 22 + 23 + static int brcm_rescal_reset_set(struct reset_controller_dev *rcdev, 24 + unsigned long id) 25 + { 26 + struct brcm_rescal_reset *data = 27 + container_of(rcdev, struct brcm_rescal_reset, rcdev); 28 + void __iomem *base = data->base; 29 + u32 reg; 30 + int ret; 31 + 32 + reg = readl(base + BRCM_RESCAL_START); 33 + writel(reg | BRCM_RESCAL_START_BIT, base + BRCM_RESCAL_START); 34 + reg = readl(base + BRCM_RESCAL_START); 35 + if (!(reg & BRCM_RESCAL_START_BIT)) { 36 + dev_err(data->dev, "failed to start SATA/PCIe rescal\n"); 37 + return -EIO; 38 + } 39 + 40 + ret = readl_poll_timeout(base + BRCM_RESCAL_STATUS, reg, 41 + !(reg & BRCM_RESCAL_STATUS_BIT), 100, 1000); 42 + if (ret) { 43 + dev_err(data->dev, "time out on SATA/PCIe rescal\n"); 44 + return ret; 45 + } 46 + 47 + reg = readl(base + BRCM_RESCAL_START); 48 + writel(reg & ~BRCM_RESCAL_START_BIT, base + BRCM_RESCAL_START); 49 + 50 + dev_dbg(data->dev, "SATA/PCIe rescal success\n"); 51 + 52 + return 0; 53 + } 54 + 55 + static int brcm_rescal_reset_xlate(struct reset_controller_dev *rcdev, 56 + const struct of_phandle_args *reset_spec) 57 + { 58 + /* This is needed if #reset-cells == 0. */ 59 + return 0; 60 + } 61 + 62 + static const struct reset_control_ops brcm_rescal_reset_ops = { 63 + .reset = brcm_rescal_reset_set, 64 + }; 65 + 66 + static int brcm_rescal_reset_probe(struct platform_device *pdev) 67 + { 68 + struct brcm_rescal_reset *data; 69 + struct resource *res; 70 + 71 + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 72 + if (!data) 73 + return -ENOMEM; 74 + 75 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 76 + data->base = devm_ioremap_resource(&pdev->dev, res); 77 + if (IS_ERR(data->base)) 78 + return PTR_ERR(data->base); 79 + 80 + data->rcdev.owner = THIS_MODULE; 81 + data->rcdev.nr_resets = 1; 82 + data->rcdev.ops = &brcm_rescal_reset_ops; 83 + data->rcdev.of_node = pdev->dev.of_node; 84 + data->rcdev.of_xlate = brcm_rescal_reset_xlate; 85 + data->dev = &pdev->dev; 86 + 87 + return devm_reset_controller_register(&pdev->dev, &data->rcdev); 88 + } 89 + 90 + static const struct of_device_id brcm_rescal_reset_of_match[] = { 91 + { .compatible = "brcm,bcm7216-pcie-sata-rescal" }, 92 + { }, 93 + }; 94 + MODULE_DEVICE_TABLE(of, brcm_rescal_reset_of_match); 95 + 96 + static struct platform_driver brcm_rescal_reset_driver = { 97 + .probe = brcm_rescal_reset_probe, 98 + .driver = { 99 + .name = "brcm-rescal-reset", 100 + .of_match_table = brcm_rescal_reset_of_match, 101 + } 102 + }; 103 + module_platform_driver(brcm_rescal_reset_driver); 104 + 105 + MODULE_AUTHOR("Broadcom"); 106 + MODULE_DESCRIPTION("Broadcom SATA/PCIe rescal reset controller"); 107 + MODULE_LICENSE("GPL v2");
+262
drivers/reset/reset-intel-gw.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2019 Intel Corporation. 4 + * Lei Chuanhua <Chuanhua.lei@intel.com> 5 + */ 6 + 7 + #include <linux/bitfield.h> 8 + #include <linux/init.h> 9 + #include <linux/of_device.h> 10 + #include <linux/platform_device.h> 11 + #include <linux/reboot.h> 12 + #include <linux/regmap.h> 13 + #include <linux/reset-controller.h> 14 + 15 + #define RCU_RST_STAT 0x0024 16 + #define RCU_RST_REQ 0x0048 17 + 18 + #define REG_OFFSET GENMASK(31, 16) 19 + #define BIT_OFFSET GENMASK(15, 8) 20 + #define STAT_BIT_OFFSET GENMASK(7, 0) 21 + 22 + #define to_reset_data(x) container_of(x, struct intel_reset_data, rcdev) 23 + 24 + struct intel_reset_soc { 25 + bool legacy; 26 + u32 reset_cell_count; 27 + }; 28 + 29 + struct intel_reset_data { 30 + struct reset_controller_dev rcdev; 31 + struct notifier_block restart_nb; 32 + const struct intel_reset_soc *soc_data; 33 + struct regmap *regmap; 34 + struct device *dev; 35 + u32 reboot_id; 36 + }; 37 + 38 + static const struct regmap_config intel_rcu_regmap_config = { 39 + .name = "intel-reset", 40 + .reg_bits = 32, 41 + .reg_stride = 4, 42 + .val_bits = 32, 43 + .fast_io = true, 44 + }; 45 + 46 + /* 47 + * Reset status register offset relative to 48 + * the reset control register(X) is X + 4 49 + */ 50 + static u32 id_to_reg_and_bit_offsets(struct intel_reset_data *data, 51 + unsigned long id, u32 *rst_req, 52 + u32 *req_bit, u32 *stat_bit) 53 + { 54 + *rst_req = FIELD_GET(REG_OFFSET, id); 55 + *req_bit = FIELD_GET(BIT_OFFSET, id); 56 + 57 + if (data->soc_data->legacy) 58 + *stat_bit = FIELD_GET(STAT_BIT_OFFSET, id); 59 + else 60 + *stat_bit = *req_bit; 61 + 62 + if (data->soc_data->legacy && *rst_req == RCU_RST_REQ) 63 + return RCU_RST_STAT; 64 + else 65 + return *rst_req + 0x4; 66 + } 67 + 68 + static int intel_set_clr_bits(struct intel_reset_data *data, unsigned long id, 69 + bool set) 70 + { 71 + u32 rst_req, req_bit, rst_stat, stat_bit, val; 72 + int ret; 73 + 74 + rst_stat = id_to_reg_and_bit_offsets(data, id, &rst_req, 75 + &req_bit, &stat_bit); 76 + 77 + val = set ? BIT(req_bit) : 0; 78 + ret = regmap_update_bits(data->regmap, rst_req, BIT(req_bit), val); 79 + if (ret) 80 + return ret; 81 + 82 + return regmap_read_poll_timeout(data->regmap, rst_stat, val, 83 + set == !!(val & BIT(stat_bit)), 20, 84 + 200); 85 + } 86 + 87 + static int intel_assert_device(struct reset_controller_dev *rcdev, 88 + unsigned long id) 89 + { 90 + struct intel_reset_data *data = to_reset_data(rcdev); 91 + int ret; 92 + 93 + ret = intel_set_clr_bits(data, id, true); 94 + if (ret) 95 + dev_err(data->dev, "Reset assert failed %d\n", ret); 96 + 97 + return ret; 98 + } 99 + 100 + static int intel_deassert_device(struct reset_controller_dev *rcdev, 101 + unsigned long id) 102 + { 103 + struct intel_reset_data *data = to_reset_data(rcdev); 104 + int ret; 105 + 106 + ret = intel_set_clr_bits(data, id, false); 107 + if (ret) 108 + dev_err(data->dev, "Reset deassert failed %d\n", ret); 109 + 110 + return ret; 111 + } 112 + 113 + static int intel_reset_status(struct reset_controller_dev *rcdev, 114 + unsigned long id) 115 + { 116 + struct intel_reset_data *data = to_reset_data(rcdev); 117 + u32 rst_req, req_bit, rst_stat, stat_bit, val; 118 + int ret; 119 + 120 + rst_stat = id_to_reg_and_bit_offsets(data, id, &rst_req, 121 + &req_bit, &stat_bit); 122 + ret = regmap_read(data->regmap, rst_stat, &val); 123 + if (ret) 124 + return ret; 125 + 126 + return !!(val & BIT(stat_bit)); 127 + } 128 + 129 + static const struct reset_control_ops intel_reset_ops = { 130 + .assert = intel_assert_device, 131 + .deassert = intel_deassert_device, 132 + .status = intel_reset_status, 133 + }; 134 + 135 + static int intel_reset_xlate(struct reset_controller_dev *rcdev, 136 + const struct of_phandle_args *spec) 137 + { 138 + struct intel_reset_data *data = to_reset_data(rcdev); 139 + u32 id; 140 + 141 + if (spec->args[1] > 31) 142 + return -EINVAL; 143 + 144 + id = FIELD_PREP(REG_OFFSET, spec->args[0]); 145 + id |= FIELD_PREP(BIT_OFFSET, spec->args[1]); 146 + 147 + if (data->soc_data->legacy) { 148 + if (spec->args[2] > 31) 149 + return -EINVAL; 150 + 151 + id |= FIELD_PREP(STAT_BIT_OFFSET, spec->args[2]); 152 + } 153 + 154 + return id; 155 + } 156 + 157 + static int intel_reset_restart_handler(struct notifier_block *nb, 158 + unsigned long action, void *data) 159 + { 160 + struct intel_reset_data *reset_data; 161 + 162 + reset_data = container_of(nb, struct intel_reset_data, restart_nb); 163 + intel_assert_device(&reset_data->rcdev, reset_data->reboot_id); 164 + 165 + return NOTIFY_DONE; 166 + } 167 + 168 + static int intel_reset_probe(struct platform_device *pdev) 169 + { 170 + struct device_node *np = pdev->dev.of_node; 171 + struct device *dev = &pdev->dev; 172 + struct intel_reset_data *data; 173 + void __iomem *base; 174 + u32 rb_id[3]; 175 + int ret; 176 + 177 + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 178 + if (!data) 179 + return -ENOMEM; 180 + 181 + data->soc_data = of_device_get_match_data(dev); 182 + if (!data->soc_data) 183 + return -ENODEV; 184 + 185 + base = devm_platform_ioremap_resource(pdev, 0); 186 + if (IS_ERR(base)) 187 + return PTR_ERR(base); 188 + 189 + data->regmap = devm_regmap_init_mmio(dev, base, 190 + &intel_rcu_regmap_config); 191 + if (IS_ERR(data->regmap)) { 192 + dev_err(dev, "regmap initialization failed\n"); 193 + return PTR_ERR(data->regmap); 194 + } 195 + 196 + ret = device_property_read_u32_array(dev, "intel,global-reset", rb_id, 197 + data->soc_data->reset_cell_count); 198 + if (ret) { 199 + dev_err(dev, "Failed to get global reset offset!\n"); 200 + return ret; 201 + } 202 + 203 + data->dev = dev; 204 + data->rcdev.of_node = np; 205 + data->rcdev.owner = dev->driver->owner; 206 + data->rcdev.ops = &intel_reset_ops; 207 + data->rcdev.of_xlate = intel_reset_xlate; 208 + data->rcdev.of_reset_n_cells = data->soc_data->reset_cell_count; 209 + ret = devm_reset_controller_register(&pdev->dev, &data->rcdev); 210 + if (ret) 211 + return ret; 212 + 213 + data->reboot_id = FIELD_PREP(REG_OFFSET, rb_id[0]); 214 + data->reboot_id |= FIELD_PREP(BIT_OFFSET, rb_id[1]); 215 + 216 + if (data->soc_data->legacy) 217 + data->reboot_id |= FIELD_PREP(STAT_BIT_OFFSET, rb_id[2]); 218 + 219 + data->restart_nb.notifier_call = intel_reset_restart_handler; 220 + data->restart_nb.priority = 128; 221 + register_restart_handler(&data->restart_nb); 222 + 223 + return 0; 224 + } 225 + 226 + static const struct intel_reset_soc xrx200_data = { 227 + .legacy = true, 228 + .reset_cell_count = 3, 229 + }; 230 + 231 + static const struct intel_reset_soc lgm_data = { 232 + .legacy = false, 233 + .reset_cell_count = 2, 234 + }; 235 + 236 + static const struct of_device_id intel_reset_match[] = { 237 + { .compatible = "intel,rcu-lgm", .data = &lgm_data }, 238 + { .compatible = "intel,rcu-xrx200", .data = &xrx200_data }, 239 + {} 240 + }; 241 + 242 + static struct platform_driver intel_reset_driver = { 243 + .probe = intel_reset_probe, 244 + .driver = { 245 + .name = "intel-reset", 246 + .of_match_table = intel_reset_match, 247 + }, 248 + }; 249 + 250 + static int __init intel_reset_init(void) 251 + { 252 + return platform_driver_register(&intel_reset_driver); 253 + } 254 + 255 + /* 256 + * RCU is system core entity which is in Always On Domain whose clocks 257 + * or resource initialization happens in system core initialization. 258 + * Also, it is required for most of the platform or architecture 259 + * specific devices to perform reset operation as part of initialization. 260 + * So perform RCU as post core initialization. 261 + */ 262 + postcore_initcall(intel_reset_init);
+291
drivers/reset/reset-npcm.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright (c) 2019 Nuvoton Technology corporation. 3 + 4 + #include <linux/delay.h> 5 + #include <linux/err.h> 6 + #include <linux/io.h> 7 + #include <linux/init.h> 8 + #include <linux/of.h> 9 + #include <linux/of_device.h> 10 + #include <linux/platform_device.h> 11 + #include <linux/reboot.h> 12 + #include <linux/reset-controller.h> 13 + #include <linux/spinlock.h> 14 + #include <linux/mfd/syscon.h> 15 + #include <linux/regmap.h> 16 + #include <linux/of_address.h> 17 + 18 + /* NPCM7xx GCR registers */ 19 + #define NPCM_MDLR_OFFSET 0x7C 20 + #define NPCM_MDLR_USBD0 BIT(9) 21 + #define NPCM_MDLR_USBD1 BIT(8) 22 + #define NPCM_MDLR_USBD2_4 BIT(21) 23 + #define NPCM_MDLR_USBD5_9 BIT(22) 24 + 25 + #define NPCM_USB1PHYCTL_OFFSET 0x140 26 + #define NPCM_USB2PHYCTL_OFFSET 0x144 27 + #define NPCM_USBXPHYCTL_RS BIT(28) 28 + 29 + /* NPCM7xx Reset registers */ 30 + #define NPCM_SWRSTR 0x14 31 + #define NPCM_SWRST BIT(2) 32 + 33 + #define NPCM_IPSRST1 0x20 34 + #define NPCM_IPSRST1_USBD1 BIT(5) 35 + #define NPCM_IPSRST1_USBD2 BIT(8) 36 + #define NPCM_IPSRST1_USBD3 BIT(25) 37 + #define NPCM_IPSRST1_USBD4 BIT(22) 38 + #define NPCM_IPSRST1_USBD5 BIT(23) 39 + #define NPCM_IPSRST1_USBD6 BIT(24) 40 + 41 + #define NPCM_IPSRST2 0x24 42 + #define NPCM_IPSRST2_USB_HOST BIT(26) 43 + 44 + #define NPCM_IPSRST3 0x34 45 + #define NPCM_IPSRST3_USBD0 BIT(4) 46 + #define NPCM_IPSRST3_USBD7 BIT(5) 47 + #define NPCM_IPSRST3_USBD8 BIT(6) 48 + #define NPCM_IPSRST3_USBD9 BIT(7) 49 + #define NPCM_IPSRST3_USBPHY1 BIT(24) 50 + #define NPCM_IPSRST3_USBPHY2 BIT(25) 51 + 52 + #define NPCM_RC_RESETS_PER_REG 32 53 + #define NPCM_MASK_RESETS GENMASK(4, 0) 54 + 55 + struct npcm_rc_data { 56 + struct reset_controller_dev rcdev; 57 + struct notifier_block restart_nb; 58 + u32 sw_reset_number; 59 + void __iomem *base; 60 + spinlock_t lock; 61 + }; 62 + 63 + #define to_rc_data(p) container_of(p, struct npcm_rc_data, rcdev) 64 + 65 + static int npcm_rc_restart(struct notifier_block *nb, unsigned long mode, 66 + void *cmd) 67 + { 68 + struct npcm_rc_data *rc = container_of(nb, struct npcm_rc_data, 69 + restart_nb); 70 + 71 + writel(NPCM_SWRST << rc->sw_reset_number, rc->base + NPCM_SWRSTR); 72 + mdelay(1000); 73 + 74 + pr_emerg("%s: unable to restart system\n", __func__); 75 + 76 + return NOTIFY_DONE; 77 + } 78 + 79 + static int npcm_rc_setclear_reset(struct reset_controller_dev *rcdev, 80 + unsigned long id, bool set) 81 + { 82 + struct npcm_rc_data *rc = to_rc_data(rcdev); 83 + unsigned int rst_bit = BIT(id & NPCM_MASK_RESETS); 84 + unsigned int ctrl_offset = id >> 8; 85 + unsigned long flags; 86 + u32 stat; 87 + 88 + spin_lock_irqsave(&rc->lock, flags); 89 + stat = readl(rc->base + ctrl_offset); 90 + if (set) 91 + writel(stat | rst_bit, rc->base + ctrl_offset); 92 + else 93 + writel(stat & ~rst_bit, rc->base + ctrl_offset); 94 + spin_unlock_irqrestore(&rc->lock, flags); 95 + 96 + return 0; 97 + } 98 + 99 + static int npcm_rc_assert(struct reset_controller_dev *rcdev, unsigned long id) 100 + { 101 + return npcm_rc_setclear_reset(rcdev, id, true); 102 + } 103 + 104 + static int npcm_rc_deassert(struct reset_controller_dev *rcdev, 105 + unsigned long id) 106 + { 107 + return npcm_rc_setclear_reset(rcdev, id, false); 108 + } 109 + 110 + static int npcm_rc_status(struct reset_controller_dev *rcdev, 111 + unsigned long id) 112 + { 113 + struct npcm_rc_data *rc = to_rc_data(rcdev); 114 + unsigned int rst_bit = BIT(id & NPCM_MASK_RESETS); 115 + unsigned int ctrl_offset = id >> 8; 116 + 117 + return (readl(rc->base + ctrl_offset) & rst_bit); 118 + } 119 + 120 + static int npcm_reset_xlate(struct reset_controller_dev *rcdev, 121 + const struct of_phandle_args *reset_spec) 122 + { 123 + unsigned int offset, bit; 124 + 125 + offset = reset_spec->args[0]; 126 + if (offset != NPCM_IPSRST1 && offset != NPCM_IPSRST2 && 127 + offset != NPCM_IPSRST3) { 128 + dev_err(rcdev->dev, "Error reset register (0x%x)\n", offset); 129 + return -EINVAL; 130 + } 131 + bit = reset_spec->args[1]; 132 + if (bit >= NPCM_RC_RESETS_PER_REG) { 133 + dev_err(rcdev->dev, "Error reset number (%d)\n", bit); 134 + return -EINVAL; 135 + } 136 + 137 + return (offset << 8) | bit; 138 + } 139 + 140 + static const struct of_device_id npcm_rc_match[] = { 141 + { .compatible = "nuvoton,npcm750-reset", 142 + .data = (void *)"nuvoton,npcm750-gcr" }, 143 + { } 144 + }; 145 + 146 + /* 147 + * The following procedure should be observed in USB PHY, USB device and 148 + * USB host initialization at BMC boot 149 + */ 150 + static int npcm_usb_reset(struct platform_device *pdev, struct npcm_rc_data *rc) 151 + { 152 + u32 mdlr, iprst1, iprst2, iprst3; 153 + struct device *dev = &pdev->dev; 154 + struct regmap *gcr_regmap; 155 + u32 ipsrst1_bits = 0; 156 + u32 ipsrst2_bits = NPCM_IPSRST2_USB_HOST; 157 + u32 ipsrst3_bits = 0; 158 + const char *gcr_dt; 159 + 160 + gcr_dt = (const char *) 161 + of_match_device(dev->driver->of_match_table, dev)->data; 162 + 163 + gcr_regmap = syscon_regmap_lookup_by_compatible(gcr_dt); 164 + if (IS_ERR(gcr_regmap)) { 165 + dev_err(&pdev->dev, "Failed to find %s\n", gcr_dt); 166 + return PTR_ERR(gcr_regmap); 167 + } 168 + 169 + /* checking which USB device is enabled */ 170 + regmap_read(gcr_regmap, NPCM_MDLR_OFFSET, &mdlr); 171 + if (!(mdlr & NPCM_MDLR_USBD0)) 172 + ipsrst3_bits |= NPCM_IPSRST3_USBD0; 173 + if (!(mdlr & NPCM_MDLR_USBD1)) 174 + ipsrst1_bits |= NPCM_IPSRST1_USBD1; 175 + if (!(mdlr & NPCM_MDLR_USBD2_4)) 176 + ipsrst1_bits |= (NPCM_IPSRST1_USBD2 | 177 + NPCM_IPSRST1_USBD3 | 178 + NPCM_IPSRST1_USBD4); 179 + if (!(mdlr & NPCM_MDLR_USBD0)) { 180 + ipsrst1_bits |= (NPCM_IPSRST1_USBD5 | 181 + NPCM_IPSRST1_USBD6); 182 + ipsrst3_bits |= (NPCM_IPSRST3_USBD7 | 183 + NPCM_IPSRST3_USBD8 | 184 + NPCM_IPSRST3_USBD9); 185 + } 186 + 187 + /* assert reset USB PHY and USB devices */ 188 + iprst1 = readl(rc->base + NPCM_IPSRST1); 189 + iprst2 = readl(rc->base + NPCM_IPSRST2); 190 + iprst3 = readl(rc->base + NPCM_IPSRST3); 191 + 192 + iprst1 |= ipsrst1_bits; 193 + iprst2 |= ipsrst2_bits; 194 + iprst3 |= (ipsrst3_bits | NPCM_IPSRST3_USBPHY1 | 195 + NPCM_IPSRST3_USBPHY2); 196 + 197 + writel(iprst1, rc->base + NPCM_IPSRST1); 198 + writel(iprst2, rc->base + NPCM_IPSRST2); 199 + writel(iprst3, rc->base + NPCM_IPSRST3); 200 + 201 + /* clear USB PHY RS bit */ 202 + regmap_update_bits(gcr_regmap, NPCM_USB1PHYCTL_OFFSET, 203 + NPCM_USBXPHYCTL_RS, 0); 204 + regmap_update_bits(gcr_regmap, NPCM_USB2PHYCTL_OFFSET, 205 + NPCM_USBXPHYCTL_RS, 0); 206 + 207 + /* deassert reset USB PHY */ 208 + iprst3 &= ~(NPCM_IPSRST3_USBPHY1 | NPCM_IPSRST3_USBPHY2); 209 + writel(iprst3, rc->base + NPCM_IPSRST3); 210 + 211 + udelay(50); 212 + 213 + /* set USB PHY RS bit */ 214 + regmap_update_bits(gcr_regmap, NPCM_USB1PHYCTL_OFFSET, 215 + NPCM_USBXPHYCTL_RS, NPCM_USBXPHYCTL_RS); 216 + regmap_update_bits(gcr_regmap, NPCM_USB2PHYCTL_OFFSET, 217 + NPCM_USBXPHYCTL_RS, NPCM_USBXPHYCTL_RS); 218 + 219 + /* deassert reset USB devices*/ 220 + iprst1 &= ~ipsrst1_bits; 221 + iprst2 &= ~ipsrst2_bits; 222 + iprst3 &= ~ipsrst3_bits; 223 + 224 + writel(iprst1, rc->base + NPCM_IPSRST1); 225 + writel(iprst2, rc->base + NPCM_IPSRST2); 226 + writel(iprst3, rc->base + NPCM_IPSRST3); 227 + 228 + return 0; 229 + } 230 + 231 + static const struct reset_control_ops npcm_rc_ops = { 232 + .assert = npcm_rc_assert, 233 + .deassert = npcm_rc_deassert, 234 + .status = npcm_rc_status, 235 + }; 236 + 237 + static int npcm_rc_probe(struct platform_device *pdev) 238 + { 239 + struct npcm_rc_data *rc; 240 + int ret; 241 + 242 + rc = devm_kzalloc(&pdev->dev, sizeof(*rc), GFP_KERNEL); 243 + if (!rc) 244 + return -ENOMEM; 245 + 246 + rc->base = devm_platform_ioremap_resource(pdev, 0); 247 + if (IS_ERR(rc->base)) 248 + return PTR_ERR(rc->base); 249 + 250 + spin_lock_init(&rc->lock); 251 + 252 + rc->rcdev.owner = THIS_MODULE; 253 + rc->rcdev.ops = &npcm_rc_ops; 254 + rc->rcdev.of_node = pdev->dev.of_node; 255 + rc->rcdev.of_reset_n_cells = 2; 256 + rc->rcdev.of_xlate = npcm_reset_xlate; 257 + 258 + platform_set_drvdata(pdev, rc); 259 + 260 + ret = devm_reset_controller_register(&pdev->dev, &rc->rcdev); 261 + if (ret) { 262 + dev_err(&pdev->dev, "unable to register device\n"); 263 + return ret; 264 + } 265 + 266 + if (npcm_usb_reset(pdev, rc)) 267 + dev_warn(&pdev->dev, "NPCM USB reset failed, can cause issues with UDC and USB host\n"); 268 + 269 + if (!of_property_read_u32(pdev->dev.of_node, "nuvoton,sw-reset-number", 270 + &rc->sw_reset_number)) { 271 + if (rc->sw_reset_number && rc->sw_reset_number < 5) { 272 + rc->restart_nb.priority = 192, 273 + rc->restart_nb.notifier_call = npcm_rc_restart, 274 + ret = register_restart_handler(&rc->restart_nb); 275 + if (ret) 276 + dev_warn(&pdev->dev, "failed to register restart handler\n"); 277 + } 278 + } 279 + 280 + return ret; 281 + } 282 + 283 + static struct platform_driver npcm_rc_driver = { 284 + .probe = npcm_rc_probe, 285 + .driver = { 286 + .name = "npcm-reset", 287 + .of_match_table = npcm_rc_match, 288 + .suppress_bind_attrs = true, 289 + }, 290 + }; 291 + builtin_platform_driver(npcm_rc_driver);
+2 -1
drivers/reset/reset-qcom-aoss.c
··· 118 118 { .compatible = "qcom,sdm845-aoss-cc", .data = &sdm845_aoss_desc }, 119 119 {} 120 120 }; 121 + MODULE_DEVICE_TABLE(of, qcom_aoss_reset_of_match); 121 122 122 123 static struct platform_driver qcom_aoss_reset_driver = { 123 124 .probe = qcom_aoss_reset_probe, ··· 128 127 }, 129 128 }; 130 129 131 - builtin_platform_driver(qcom_aoss_reset_driver); 130 + module_platform_driver(qcom_aoss_reset_driver); 132 131 133 132 MODULE_DESCRIPTION("Qualcomm AOSS Reset Driver"); 134 133 MODULE_LICENSE("GPL v2");
+8 -5
drivers/reset/reset-uniphier.c
··· 193 193 #define UNIPHIER_PERI_RESET_FI2C(id, ch) \ 194 194 UNIPHIER_RESETX((id), 0x114, 24 + (ch)) 195 195 196 - #define UNIPHIER_PERI_RESET_SCSSI(id) \ 197 - UNIPHIER_RESETX((id), 0x110, 17) 196 + #define UNIPHIER_PERI_RESET_SCSSI(id, ch) \ 197 + UNIPHIER_RESETX((id), 0x110, 17 + (ch)) 198 198 199 199 #define UNIPHIER_PERI_RESET_MCSSI(id) \ 200 200 UNIPHIER_RESETX((id), 0x114, 14) ··· 209 209 UNIPHIER_PERI_RESET_I2C(6, 2), 210 210 UNIPHIER_PERI_RESET_I2C(7, 3), 211 211 UNIPHIER_PERI_RESET_I2C(8, 4), 212 - UNIPHIER_PERI_RESET_SCSSI(11), 212 + UNIPHIER_PERI_RESET_SCSSI(11, 0), 213 213 UNIPHIER_RESET_END, 214 214 }; 215 215 ··· 225 225 UNIPHIER_PERI_RESET_FI2C(8, 4), 226 226 UNIPHIER_PERI_RESET_FI2C(9, 5), 227 227 UNIPHIER_PERI_RESET_FI2C(10, 6), 228 - UNIPHIER_PERI_RESET_SCSSI(11), 229 - UNIPHIER_PERI_RESET_MCSSI(12), 228 + UNIPHIER_PERI_RESET_SCSSI(11, 0), 229 + UNIPHIER_PERI_RESET_SCSSI(12, 1), 230 + UNIPHIER_PERI_RESET_SCSSI(13, 2), 231 + UNIPHIER_PERI_RESET_SCSSI(14, 3), 232 + UNIPHIER_PERI_RESET_MCSSI(15), 230 233 UNIPHIER_RESET_END, 231 234 }; 232 235
+91
include/dt-bindings/reset/nuvoton,npcm7xx-reset.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + // Copyright (c) 2019 Nuvoton Technology corporation. 3 + 4 + #ifndef _DT_BINDINGS_NPCM7XX_RESET_H 5 + #define _DT_BINDINGS_NPCM7XX_RESET_H 6 + 7 + #define NPCM7XX_RESET_IPSRST1 0x20 8 + #define NPCM7XX_RESET_IPSRST2 0x24 9 + #define NPCM7XX_RESET_IPSRST3 0x34 10 + 11 + /* Reset lines on IP1 reset module (NPCM7XX_RESET_IPSRST1) */ 12 + #define NPCM7XX_RESET_FIU3 1 13 + #define NPCM7XX_RESET_UDC1 5 14 + #define NPCM7XX_RESET_EMC1 6 15 + #define NPCM7XX_RESET_UART_2_3 7 16 + #define NPCM7XX_RESET_UDC2 8 17 + #define NPCM7XX_RESET_PECI 9 18 + #define NPCM7XX_RESET_AES 10 19 + #define NPCM7XX_RESET_UART_0_1 11 20 + #define NPCM7XX_RESET_MC 12 21 + #define NPCM7XX_RESET_SMB2 13 22 + #define NPCM7XX_RESET_SMB3 14 23 + #define NPCM7XX_RESET_SMB4 15 24 + #define NPCM7XX_RESET_SMB5 16 25 + #define NPCM7XX_RESET_PWM_M0 18 26 + #define NPCM7XX_RESET_TIMER_0_4 19 27 + #define NPCM7XX_RESET_TIMER_5_9 20 28 + #define NPCM7XX_RESET_EMC2 21 29 + #define NPCM7XX_RESET_UDC4 22 30 + #define NPCM7XX_RESET_UDC5 23 31 + #define NPCM7XX_RESET_UDC6 24 32 + #define NPCM7XX_RESET_UDC3 25 33 + #define NPCM7XX_RESET_ADC 27 34 + #define NPCM7XX_RESET_SMB6 28 35 + #define NPCM7XX_RESET_SMB7 29 36 + #define NPCM7XX_RESET_SMB0 30 37 + #define NPCM7XX_RESET_SMB1 31 38 + 39 + /* Reset lines on IP2 reset module (NPCM7XX_RESET_IPSRST2) */ 40 + #define NPCM7XX_RESET_MFT0 0 41 + #define NPCM7XX_RESET_MFT1 1 42 + #define NPCM7XX_RESET_MFT2 2 43 + #define NPCM7XX_RESET_MFT3 3 44 + #define NPCM7XX_RESET_MFT4 4 45 + #define NPCM7XX_RESET_MFT5 5 46 + #define NPCM7XX_RESET_MFT6 6 47 + #define NPCM7XX_RESET_MFT7 7 48 + #define NPCM7XX_RESET_MMC 8 49 + #define NPCM7XX_RESET_SDHC 9 50 + #define NPCM7XX_RESET_GFX_SYS 10 51 + #define NPCM7XX_RESET_AHB_PCIBRG 11 52 + #define NPCM7XX_RESET_VDMA 12 53 + #define NPCM7XX_RESET_ECE 13 54 + #define NPCM7XX_RESET_VCD 14 55 + #define NPCM7XX_RESET_OTP 16 56 + #define NPCM7XX_RESET_SIOX1 18 57 + #define NPCM7XX_RESET_SIOX2 19 58 + #define NPCM7XX_RESET_3DES 21 59 + #define NPCM7XX_RESET_PSPI1 22 60 + #define NPCM7XX_RESET_PSPI2 23 61 + #define NPCM7XX_RESET_GMAC2 25 62 + #define NPCM7XX_RESET_USB_HOST 26 63 + #define NPCM7XX_RESET_GMAC1 28 64 + #define NPCM7XX_RESET_CP 31 65 + 66 + /* Reset lines on IP3 reset module (NPCM7XX_RESET_IPSRST3) */ 67 + #define NPCM7XX_RESET_PWM_M1 0 68 + #define NPCM7XX_RESET_SMB12 1 69 + #define NPCM7XX_RESET_SPIX 2 70 + #define NPCM7XX_RESET_SMB13 3 71 + #define NPCM7XX_RESET_UDC0 4 72 + #define NPCM7XX_RESET_UDC7 5 73 + #define NPCM7XX_RESET_UDC8 6 74 + #define NPCM7XX_RESET_UDC9 7 75 + #define NPCM7XX_RESET_PCI_MAILBOX 9 76 + #define NPCM7XX_RESET_SMB14 12 77 + #define NPCM7XX_RESET_SHA 13 78 + #define NPCM7XX_RESET_SEC_ECC 14 79 + #define NPCM7XX_RESET_PCIE_RC 15 80 + #define NPCM7XX_RESET_TIMER_10_14 16 81 + #define NPCM7XX_RESET_RNG 17 82 + #define NPCM7XX_RESET_SMB15 18 83 + #define NPCM7XX_RESET_SMB8 19 84 + #define NPCM7XX_RESET_SMB9 20 85 + #define NPCM7XX_RESET_SMB10 21 86 + #define NPCM7XX_RESET_SMB11 22 87 + #define NPCM7XX_RESET_ESPI 23 88 + #define NPCM7XX_RESET_USB_PHY_1 24 89 + #define NPCM7XX_RESET_USB_PHY_2 25 90 + 91 + #endif