summaryrefslogtreecommitdiff
path: root/drivers/reset
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-04-21 08:33:26 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-04-21 08:33:26 -0700
commit4ee64205ffaa587e8114d84a67ac721399ccb369 (patch)
tree2ea560af94683235e16bb8943efa08c8ba6d2d01 /drivers/reset
parenta85d6ff99411eb21536a750ad02205e8a97894c6 (diff)
parent6b701fde9b31f085f39fc2a371cb33212fab6f68 (diff)
downloadlinux-4ee64205ffaa587e8114d84a67ac721399ccb369.tar.gz
linux-4ee64205ffaa587e8114d84a67ac721399ccb369.zip
Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
Pull clk updates from Stephen Boyd: "We've finally gotten rid of the struct clk_ops::round_rate() code after months of effort from Brian Masney. Now the only option is to use determine_rate(), which is good because that takes a struct argument instead of just a couple unsigned longs, allowing us to easily modify the way we determine and set rates in the clk tree. Beyond that core framework change we've got the typical pile of new SoC clk driver additions, fixes for clk data and/or adding missing clks because the consumer driver using those clks wasn't ready, etc. The usual suspects are all here: Qualcomm, Samsung, Mediatek, and Rockchip along with some newcomers making RISC-V SoCs like ESWIN's eic700 and Tenstorrent's Atlantis. The clk driver side of this looks pretty normal. Core: - Remove the round_rate() clk op (yay!) New Drivers: - ESWIN eic700 SoC clk support - Econet EN751221 SoC clock/reset support - Global TCSR, RPMh, and display clock controller support for the Qualcomm Eliza platform - TCSR, the multiple global, and the RPMh clock controller support for the Qualcomm Nord platform - GPU clock controller support for Qualcomm SM8750 - Video and GPU clock controller support for Qualcomm Glymur - Global clock controller support for Qualcomm IPQ5210 - Axis ARTPEC-9: Add new PLL clocks and new drivers for eight clock controllers on the SoC - ExynosAutov920: Add G3D (GPU) clock controller - Clock driver for the Rockchip RV1103B SoC - Initial support for the Renesas RZ/G3L (R9A08G046) SoC - Clock and reset controllers (e.g. PRCM) in the Tenstorrent Atlantis SoC" * tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (132 commits) clk: visconti: pll: initialize clk_init_data to zero clk: fsl-sai: Add MCLK generation support clk: fsl-sai: Extract clock setup into fsl_sai_clk_register() dt-bindings: clock: fsl-sai: Document clock-cells = <1> support clk: fsl-sai: Add i.MX8M support with 8 byte register offset clk: fsl-sai: Sort the headers dt-bindings: clock: fsl-sai: Document i.MX8M support clk: qcom: gcc: Add multiple global clock controller driver for Nord SoC clk: qcom: rpmh: Add support for Nord rpmh clocks clk: qcom: Add TCSR clock driver for Nord SoC dt-bindings: clock: qcom: Add Nord Global Clock Controller dt-bindings: clock: qcom-rpmhcc: Add support for Nord SoCs dt-bindings: clock: qcom: Document the Nord SoC TCSR Clock Controller clk: qcom: gcc-x1e80100: Keep GCC USB QTB clock always ON clk: qcom: Constify list of critical CBCR registers clk: qcom: Constify qcom_cc_driver_data clk: qcom: videocc-glymur: Constify qcom_cc_desc clk: qcom: Add a driver for SM8750 GPU clocks dt-bindings: clock: qcom: Add SM8750 GPU clocks clk: qcom: ipq-cmn-pll: Add IPQ8074 SoC support ...
Diffstat (limited to 'drivers/reset')
-rw-r--r--drivers/reset/Kconfig11
-rw-r--r--drivers/reset/Makefile1
-rw-r--r--drivers/reset/reset-tenstorrent-atlantis.c173
3 files changed, 185 insertions, 0 deletions
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 7140bff0b883..d009eb0849a3 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -324,6 +324,17 @@ config RESET_SUNXI
help
This enables the reset driver for Allwinner SoCs.
+config RESET_TENSTORRENT_ATLANTIS
+ tristate "Tenstorrent atlantis reset driver"
+ depends on ARCH_TENSTORRENT || COMPILE_TEST
+ select AUXILIARY_BUS
+ default ARCH_TENSTORRENT
+ help
+ This enables the driver for the reset controller
+ present in the Tenstorrent Atlantis SoC.
+ Enable this option to be able to use hardware
+ resets on Atalantis based systems.
+
config RESET_TH1520
tristate "T-HEAD TH1520 reset controller"
depends on ARCH_THEAD || COMPILE_TEST
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index d1b8c66e5086..3e52569bd276 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_RESET_SKY1) += reset-sky1.o
obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
obj-$(CONFIG_RESET_SUNPLUS) += reset-sunplus.o
obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
+obj-$(CONFIG_RESET_TENSTORRENT_ATLANTIS) += reset-tenstorrent-atlantis.o
obj-$(CONFIG_RESET_TH1520) += reset-th1520.o
obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
obj-$(CONFIG_RESET_TI_SYSCON) += reset-ti-syscon.o
diff --git a/drivers/reset/reset-tenstorrent-atlantis.c b/drivers/reset/reset-tenstorrent-atlantis.c
new file mode 100644
index 000000000000..ab8be52fdd5e
--- /dev/null
+++ b/drivers/reset/reset-tenstorrent-atlantis.c
@@ -0,0 +1,173 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Tenstorrent Atlantis PRCM Reset Driver
+ *
+ * Copyright (c) 2026 Tenstorrent
+ */
+
+#include <dt-bindings/clock/tenstorrent,atlantis-prcm-rcpu.h>
+#include <linux/auxiliary_bus.h>
+#include <linux/reset-controller.h>
+#include <linux/regmap.h>
+
+/* RCPU Reset Register Offsets */
+#define RCPU_BLK_RST_REG 0x001c
+#define LSIO_BLK_RST_REG 0x0020
+#define HSIO_BLK_RST_REG 0x000c
+#define PCIE_SUBS_RST_REG 0x0000
+#define MM_RSTN_REG 0x0014
+
+struct atlantis_reset_data {
+ u8 bit;
+ u16 reg;
+ bool active_low;
+};
+
+struct atlantis_reset_controller_data {
+ const struct atlantis_reset_data *reset_data;
+ size_t count;
+};
+
+struct atlantis_reset_controller {
+ struct reset_controller_dev rcdev;
+ const struct atlantis_reset_controller_data *data;
+ struct regmap *regmap;
+};
+
+static inline struct atlantis_reset_controller *
+to_atlantis_reset_controller(struct reset_controller_dev *rcdev)
+{
+ return container_of(rcdev, struct atlantis_reset_controller, rcdev);
+}
+
+#define RESET_DATA(_reg, _bit, _active_low) \
+ { \
+ .bit = _bit, .reg = _reg, .active_low = _active_low, \
+ }
+
+static const struct atlantis_reset_data atlantis_rcpu_resets[] = {
+ [RST_SMNDMA0] = RESET_DATA(RCPU_BLK_RST_REG, 0, true),
+ [RST_SMNDMA1] = RESET_DATA(RCPU_BLK_RST_REG, 1, true),
+ [RST_WDT0] = RESET_DATA(RCPU_BLK_RST_REG, 2, true),
+ [RST_WDT1] = RESET_DATA(RCPU_BLK_RST_REG, 3, true),
+ [RST_TMR] = RESET_DATA(RCPU_BLK_RST_REG, 4, true),
+ [RST_PVTC] = RESET_DATA(RCPU_BLK_RST_REG, 12, true),
+ [RST_PMU] = RESET_DATA(RCPU_BLK_RST_REG, 13, true),
+ [RST_MAILBOX] = RESET_DATA(RCPU_BLK_RST_REG, 14, true),
+ [RST_SPACC] = RESET_DATA(RCPU_BLK_RST_REG, 26, true),
+ [RST_OTP] = RESET_DATA(RCPU_BLK_RST_REG, 28, true),
+ [RST_TRNG] = RESET_DATA(RCPU_BLK_RST_REG, 29, true),
+ [RST_CRC] = RESET_DATA(RCPU_BLK_RST_REG, 30, true),
+ [RST_QSPI] = RESET_DATA(LSIO_BLK_RST_REG, 0, true),
+ [RST_I2C0] = RESET_DATA(LSIO_BLK_RST_REG, 1, true),
+ [RST_I2C1] = RESET_DATA(LSIO_BLK_RST_REG, 2, true),
+ [RST_I2C2] = RESET_DATA(LSIO_BLK_RST_REG, 3, true),
+ [RST_I2C3] = RESET_DATA(LSIO_BLK_RST_REG, 4, true),
+ [RST_I2C4] = RESET_DATA(LSIO_BLK_RST_REG, 5, true),
+ [RST_UART0] = RESET_DATA(LSIO_BLK_RST_REG, 6, true),
+ [RST_UART1] = RESET_DATA(LSIO_BLK_RST_REG, 7, true),
+ [RST_UART2] = RESET_DATA(LSIO_BLK_RST_REG, 8, true),
+ [RST_UART3] = RESET_DATA(LSIO_BLK_RST_REG, 9, true),
+ [RST_UART4] = RESET_DATA(LSIO_BLK_RST_REG, 10, true),
+ [RST_SPI0] = RESET_DATA(LSIO_BLK_RST_REG, 11, true),
+ [RST_SPI1] = RESET_DATA(LSIO_BLK_RST_REG, 12, true),
+ [RST_SPI2] = RESET_DATA(LSIO_BLK_RST_REG, 13, true),
+ [RST_SPI3] = RESET_DATA(LSIO_BLK_RST_REG, 14, true),
+ [RST_GPIO] = RESET_DATA(LSIO_BLK_RST_REG, 15, true),
+ [RST_CAN0] = RESET_DATA(LSIO_BLK_RST_REG, 17, true),
+ [RST_CAN1] = RESET_DATA(LSIO_BLK_RST_REG, 18, true),
+ [RST_I2S0] = RESET_DATA(LSIO_BLK_RST_REG, 19, true),
+ [RST_I2S1] = RESET_DATA(LSIO_BLK_RST_REG, 20, true),
+
+};
+
+static const struct atlantis_reset_controller_data atlantis_rcpu_reset_data = {
+ .reset_data = atlantis_rcpu_resets,
+ .count = ARRAY_SIZE(atlantis_rcpu_resets),
+};
+
+static int atlantis_reset_update(struct reset_controller_dev *rcdev,
+ unsigned long id, bool assert)
+{
+ unsigned int val;
+ struct atlantis_reset_controller *rst =
+ to_atlantis_reset_controller(rcdev);
+ const struct atlantis_reset_data *data = &rst->data->reset_data[id];
+ unsigned int mask = BIT(data->bit);
+ struct regmap *regmap = rst->regmap;
+
+ if (data->active_low ^ assert)
+ val = mask;
+ else
+ val = 0;
+
+ return regmap_update_bits(regmap, data->reg, mask, val);
+}
+
+static int atlantis_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ return atlantis_reset_update(rcdev, id, true);
+}
+
+static int atlantis_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ return atlantis_reset_update(rcdev, id, false);
+}
+
+static const struct reset_control_ops atlantis_reset_control_ops = {
+ .assert = atlantis_reset_assert,
+ .deassert = atlantis_reset_deassert,
+};
+
+static int
+atlantis_reset_controller_register(struct device *dev,
+ struct atlantis_reset_controller *controller)
+{
+ struct reset_controller_dev *rcdev = &controller->rcdev;
+
+ rcdev->ops = &atlantis_reset_control_ops;
+ rcdev->owner = THIS_MODULE;
+ rcdev->of_node = dev->of_node;
+ rcdev->nr_resets = controller->data->count;
+
+ return devm_reset_controller_register(dev, &controller->rcdev);
+}
+static int atlantis_reset_probe(struct auxiliary_device *adev,
+ const struct auxiliary_device_id *id)
+{
+ struct atlantis_reset_controller *controller;
+ struct device *dev = &adev->dev;
+ struct regmap *regmap;
+
+ regmap = dev_get_regmap(dev->parent, NULL);
+ if (!regmap)
+ return -ENODEV;
+
+ controller = devm_kzalloc(dev, sizeof(*controller), GFP_KERNEL);
+ if (!controller)
+ return -ENOMEM;
+ controller->data =
+ (const struct atlantis_reset_controller_data *)id->driver_data;
+ controller->regmap = regmap;
+
+ return atlantis_reset_controller_register(dev, controller);
+}
+
+static const struct auxiliary_device_id atlantis_reset_ids[] = {
+ { .name = "atlantis_prcm.rcpu-reset",
+ .driver_data = (kernel_ulong_t)&atlantis_rcpu_reset_data },
+ {},
+};
+MODULE_DEVICE_TABLE(auxiliary, atlantis_reset_ids);
+
+static struct auxiliary_driver atlantis_reset_driver = {
+ .probe = atlantis_reset_probe,
+ .id_table = atlantis_reset_ids,
+};
+module_auxiliary_driver(atlantis_reset_driver);
+
+MODULE_AUTHOR("Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>");
+MODULE_DESCRIPTION("Atlantis PRCM reset controller driver");
+MODULE_LICENSE("GPL");