diff options
author | John Crispin | 2013-09-04 00:16:59 +0200 |
---|---|---|
committer | Ralf Baechle | 2013-09-04 18:27:28 +0200 |
commit | 2a153f1c551e8b0012a2a901c5665fe4caf07a34 (patch) | |
tree | e23dc65c6f205bc21e4267171e93be0575ddd7d0 /arch/mips/ralink | |
parent | 9852ba6a914f95db65e86fed85d02d5309a301da (diff) |
MIPS: ralink: Add support for reset-controller API
Add a helper for reseting different devices on the SoC.
Signed-off-by: John Crispin <blogic@openwrt.org>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/5804/
Patchwork: https://patchwork.linux-mips.org/patch/5797/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/ralink')
-rw-r--r-- | arch/mips/ralink/common.h | 2 | ||||
-rw-r--r-- | arch/mips/ralink/of.c | 3 | ||||
-rw-r--r-- | arch/mips/ralink/reset.c | 62 |
3 files changed, 67 insertions, 0 deletions
diff --git a/arch/mips/ralink/common.h b/arch/mips/ralink/common.h index 83144c3fc5ac..42dfd6100a2d 100644 --- a/arch/mips/ralink/common.h +++ b/arch/mips/ralink/common.h @@ -46,6 +46,8 @@ extern void ralink_of_remap(void); extern void ralink_clk_init(void); extern void ralink_clk_add(const char *dev, unsigned long rate); +extern void ralink_rst_init(void); + extern void prom_soc_init(struct ralink_soc_info *soc_info); __iomem void *plat_of_remap_node(const char *node); diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c index f25ea5b45051..ce38d11f9da5 100644 --- a/arch/mips/ralink/of.c +++ b/arch/mips/ralink/of.c @@ -110,6 +110,9 @@ static int __init plat_of_setup(void) if (of_platform_populate(NULL, of_ids, NULL, NULL)) panic("failed to populate DT\n"); + /* make sure ithat the reset controller is setup early */ + ralink_rst_init(); + return 0; } diff --git a/arch/mips/ralink/reset.c b/arch/mips/ralink/reset.c index 22120e512e7e..55c7ec59df3c 100644 --- a/arch/mips/ralink/reset.c +++ b/arch/mips/ralink/reset.c @@ -10,6 +10,8 @@ #include <linux/pm.h> #include <linux/io.h> +#include <linux/of.h> +#include <linux/reset-controller.h> #include <asm/reboot.h> @@ -19,6 +21,66 @@ #define SYSC_REG_RESET_CTRL 0x034 #define RSTCTL_RESET_SYSTEM BIT(0) +static int ralink_assert_device(struct reset_controller_dev *rcdev, + unsigned long id) +{ + u32 val; + + if (id < 8) + return -1; + + val = rt_sysc_r32(SYSC_REG_RESET_CTRL); + val |= BIT(id); + rt_sysc_w32(val, SYSC_REG_RESET_CTRL); + + return 0; +} + +static int ralink_deassert_device(struct reset_controller_dev *rcdev, + unsigned long id) +{ + u32 val; + + if (id < 8) + return -1; + + val = rt_sysc_r32(SYSC_REG_RESET_CTRL); + val &= ~BIT(id); + rt_sysc_w32(val, SYSC_REG_RESET_CTRL); + + return 0; +} + +static int ralink_reset_device(struct reset_controller_dev *rcdev, + unsigned long id) +{ + ralink_assert_device(rcdev, id); + return ralink_deassert_device(rcdev, id); +} + +static struct reset_control_ops reset_ops = { + .reset = ralink_reset_device, + .assert = ralink_assert_device, + .deassert = ralink_deassert_device, +}; + +static struct reset_controller_dev reset_dev = { + .ops = &reset_ops, + .owner = THIS_MODULE, + .nr_resets = 32, + .of_reset_n_cells = 1, +}; + +void ralink_rst_init(void) +{ + reset_dev.of_node = of_find_compatible_node(NULL, NULL, + "ralink,rt2880-reset"); + if (!reset_dev.of_node) + pr_err("Failed to find reset controller node"); + else + reset_controller_register(&reset_dev); +} + static void ralink_restart(char *command) { local_irq_disable(); |