From c530781c93a55a937d2847efeda744b4e099dfef Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 3 Sep 2013 13:18:12 +0200 Subject: [PATCH] MIPS: lantiq: add reset-controller api support Add a reset-controller binding for the reset registers found on the lantiq SoC. Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8043/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 2 ++ arch/mips/lantiq/xway/reset.c | 61 +++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 97bbb3b09d4b..9e8317e9b567 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -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" diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c index 1fa0f175357e..a1e06b78e15a 100644 --- a/arch/mips/lantiq/xway/reset.c +++ b/arch/mips/lantiq/xway/reset.c @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -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();