MIPS: lantiq: add reset-controller api support
authorJohn Crispin <blogic@openwrt.org>
Tue, 3 Sep 2013 11:18:12 +0000 (13:18 +0200)
committerRalf Baechle <ralf@linux-mips.org>
Mon, 24 Nov 2014 06:45:17 +0000 (07:45 +0100)
Add a reset-controller binding for the reset registers found on the lantiq
SoC.

Signed-off-by: John Crispin <blogic@openwrt.org>
Patchwork: http://patchwork.linux-mips.org/patch/8043/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/Kconfig
arch/mips/lantiq/xway/reset.c

index 97bbb3b09d4bd3eb8d7dff71533a46efee444687..9e8317e9b567c245bac97d619e10bb03441ec95f 100644 (file)
@@ -296,6 +296,8 @@ config LANTIQ
        select USE_OF
        select PINCTRL
        select PINCTRL_LANTIQ
+       select ARCH_HAS_RESET_CONTROLLER
+       select RESET_CONTROLLER
 
 config LASAT
        bool "LASAT Networks platforms"
index 1fa0f175357e86e462cd7a66ae045599d2a2c140..a1e06b78e15ae3a02b728a8adea867eed8cbc577 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/delay.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
+#include <linux/reset-controller.h>
 
 #include <asm/reboot.h>
 
@@ -113,6 +114,66 @@ void ltq_reset_once(unsigned int module, ulong u)
        ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ);
 }
 
+static int ltq_assert_device(struct reset_controller_dev *rcdev,
+                               unsigned long id)
+{
+       u32 val;
+
+       if (id < 8)
+               return -1;
+
+       val = ltq_rcu_r32(RCU_RST_REQ);
+       val |= BIT(id);
+       ltq_rcu_w32(val, RCU_RST_REQ);
+
+       return 0;
+}
+
+static int ltq_deassert_device(struct reset_controller_dev *rcdev,
+                                 unsigned long id)
+{
+       u32 val;
+
+       if (id < 8)
+               return -1;
+
+       val = ltq_rcu_r32(RCU_RST_REQ);
+       val &= ~BIT(id);
+       ltq_rcu_w32(val, RCU_RST_REQ);
+
+       return 0;
+}
+
+static int ltq_reset_device(struct reset_controller_dev *rcdev,
+                              unsigned long id)
+{
+       ltq_assert_device(rcdev, id);
+       return ltq_deassert_device(rcdev, id);
+}
+
+static struct reset_control_ops reset_ops = {
+       .reset = ltq_reset_device,
+       .assert = ltq_assert_device,
+       .deassert = ltq_deassert_device,
+};
+
+static struct reset_controller_dev reset_dev = {
+       .ops                    = &reset_ops,
+       .owner                  = THIS_MODULE,
+       .nr_resets              = 32,
+       .of_reset_n_cells       = 1,
+};
+
+void ltq_rst_init(void)
+{
+       reset_dev.of_node = of_find_compatible_node(NULL, NULL,
+                                               "lantiq,xway-reset");
+       if (!reset_dev.of_node)
+               pr_err("Failed to find reset controller node");
+       else
+               reset_controller_register(&reset_dev);
+}
+
 static void ltq_machine_restart(char *command)
 {
        local_irq_disable();