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

Merge tag 'keystone-reset-driver' of git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone into next/drivers

Merge "Keystone Reset driver for 3.16" from Santosh Shilimkar:

* tag 'keystone-reset-driver' of git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone:
power: reset: keystone-reset: introduce keystone reset driver
Documentation: dt: add bindings for keystone pll control controller
Documentation: dt: add bindings for keystone reset driver

Signed-off-by: Olof Johansson <olof@lixom.net>

+262
+20
Documentation/devicetree/bindings/clock/ti-keystone-pllctrl.txt
··· 1 + * Device tree bindings for Texas Instruments keystone pll controller 2 + 3 + The main pll controller used to drive theC66x CorePacs, the switch fabric, 4 + and a majority of the peripheral clocks (all but the ARM CorePacs, DDR3 and 5 + the NETCP modules) requires a PLL Controller to manage the various clock 6 + divisions, gating, and synchronization. 7 + 8 + Required properties: 9 + 10 + - compatible: "ti,keystone-pllctrl", "syscon" 11 + 12 + - reg: contains offset/length value for pll controller 13 + registers space. 14 + 15 + Example: 16 + 17 + pllctrl: pll-controller@0x02310000 { 18 + compatible = "ti,keystone-pllctrl", "syscon"; 19 + reg = <0x02310000 0x200>; 20 + };
+67
Documentation/devicetree/bindings/power/reset/keystone-reset.txt
··· 1 + * Device tree bindings for Texas Instruments keystone reset 2 + 3 + This node is intended to allow SoC reset in case of software reset 4 + of selected watchdogs. 5 + 6 + The Keystone SoCs can contain up to 4 watchdog timers to reset 7 + SoC. Each watchdog timer event input is connected to the Reset Mux 8 + block. The Reset Mux block can be configured to cause reset or not. 9 + 10 + Additionally soft or hard reset can be configured. 11 + 12 + Required properties: 13 + 14 + - compatible: ti,keystone-reset 15 + 16 + - ti,syscon-pll: phandle/offset pair. The phandle to syscon used to 17 + access pll controller registers and the offset to use 18 + reset control registers. 19 + 20 + - ti,syscon-dev: phandle/offset pair. The phandle to syscon used to 21 + access device state control registers and the offset 22 + in order to use mux block registers for all watchdogs. 23 + 24 + Optional properties: 25 + 26 + - ti,soft-reset: Boolean option indicating soft reset. 27 + By default hard reset is used. 28 + 29 + - ti,wdt-list: WDT list that can cause SoC reset. It's not related 30 + to WDT driver, it's just needed to enable a SoC related 31 + reset that's triggered by one of WDTs. The list is 32 + in format: <0>, <2>; It can be in random order and 33 + begins from 0 to 3, as keystone can contain up to 4 SoC 34 + reset watchdogs and can be in random order. 35 + 36 + Example 1: 37 + Setup keystone reset so that in case software reset or 38 + WDT0 is triggered it issues hard reset for SoC. 39 + 40 + pllctrl: pll-controller@02310000 { 41 + compatible = "ti,keystone-pllctrl", "syscon"; 42 + reg = <0x02310000 0x200>; 43 + }; 44 + 45 + devctrl: device-state-control@02620000 { 46 + compatible = "ti,keystone-devctrl", "syscon"; 47 + reg = <0x02620000 0x1000>; 48 + }; 49 + 50 + rstctrl: reset-controller { 51 + compatible = "ti,keystone-reset"; 52 + ti,syscon-pll = <&pllctrl 0xe4>; 53 + ti,syscon-dev = <&devctrl 0x328>; 54 + ti,wdt-list = <0>; 55 + }; 56 + 57 + Example 2: 58 + Setup keystone reset so that in case of software reset or 59 + WDT0 or WDT2 is triggered it issues soft reset for SoC. 60 + 61 + rstctrl: reset-controller { 62 + compatible = "ti,keystone-reset"; 63 + ti,syscon-pll = <&pllctrl 0xe4>; 64 + ti,syscon-dev = <&devctrl 0x328>; 65 + ti,wdt-list = <0>, <2>; 66 + ti,soft-reset; 67 + };
+8
drivers/power/reset/Kconfig
··· 64 64 depends on POWER_RESET 65 65 help 66 66 Reboot support for the APM SoC X-Gene Eval boards. 67 + 68 + config POWER_RESET_KEYSTONE 69 + bool "Keystone reset driver" 70 + depends on ARCH_KEYSTONE 71 + select MFD_SYSCON 72 + help 73 + Reboot support for the KEYSTONE SoCs. 74 +
+1
drivers/power/reset/Makefile
··· 6 6 obj-$(CONFIG_POWER_RESET_SUN6I) += sun6i-reboot.o 7 7 obj-$(CONFIG_POWER_RESET_VEXPRESS) += vexpress-poweroff.o 8 8 obj-$(CONFIG_POWER_RESET_XGENE) += xgene-reboot.o 9 + obj-$(CONFIG_POWER_RESET_KEYSTONE) += keystone-reset.o
+166
drivers/power/reset/keystone-reset.c
··· 1 + /* 2 + * TI keystone reboot driver 3 + * 4 + * Copyright (C) 2014 Texas Instruments Incorporated. http://www.ti.com/ 5 + * 6 + * Author: Ivan Khoronzhuk <ivan.khoronzhuk@ti.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #include <linux/io.h> 14 + #include <linux/module.h> 15 + #include <linux/reboot.h> 16 + #include <linux/regmap.h> 17 + #include <asm/system_misc.h> 18 + #include <linux/mfd/syscon.h> 19 + #include <linux/of_platform.h> 20 + 21 + #define RSTYPE_RG 0x0 22 + #define RSCTRL_RG 0x4 23 + #define RSCFG_RG 0x8 24 + #define RSISO_RG 0xc 25 + 26 + #define RSCTRL_KEY_MASK 0x0000ffff 27 + #define RSCTRL_RESET_MASK BIT(16) 28 + #define RSCTRL_KEY 0x5a69 29 + 30 + #define RSMUX_OMODE_MASK 0xe 31 + #define RSMUX_OMODE_RESET_ON 0xa 32 + #define RSMUX_OMODE_RESET_OFF 0x0 33 + #define RSMUX_LOCK_MASK 0x1 34 + #define RSMUX_LOCK_SET 0x1 35 + 36 + #define RSCFG_RSTYPE_SOFT 0x300f 37 + #define RSCFG_RSTYPE_HARD 0x0 38 + 39 + #define WDT_MUX_NUMBER 0x4 40 + 41 + static int rspll_offset; 42 + static struct regmap *pllctrl_regs; 43 + 44 + /** 45 + * rsctrl_enable_rspll_write - enable access to RSCTRL, RSCFG 46 + * To be able to access to RSCTRL, RSCFG registers 47 + * we have to write a key before 48 + */ 49 + static inline int rsctrl_enable_rspll_write(void) 50 + { 51 + return regmap_update_bits(pllctrl_regs, rspll_offset + RSCTRL_RG, 52 + RSCTRL_KEY_MASK, RSCTRL_KEY); 53 + } 54 + 55 + static void rsctrl_restart(enum reboot_mode mode, const char *cmd) 56 + { 57 + /* enable write access to RSTCTRL */ 58 + rsctrl_enable_rspll_write(); 59 + 60 + /* reset the SOC */ 61 + regmap_update_bits(pllctrl_regs, rspll_offset + RSCTRL_RG, 62 + RSCTRL_RESET_MASK, 0); 63 + } 64 + 65 + static struct of_device_id rsctrl_of_match[] = { 66 + {.compatible = "ti,keystone-reset", }, 67 + {}, 68 + }; 69 + 70 + static int rsctrl_probe(struct platform_device *pdev) 71 + { 72 + int i; 73 + int ret; 74 + u32 val; 75 + unsigned int rg; 76 + u32 rsmux_offset; 77 + struct regmap *devctrl_regs; 78 + struct device *dev = &pdev->dev; 79 + struct device_node *np = dev->of_node; 80 + 81 + if (!np) 82 + return -ENODEV; 83 + 84 + /* get regmaps */ 85 + pllctrl_regs = syscon_regmap_lookup_by_phandle(np, "ti,syscon-pll"); 86 + if (IS_ERR(pllctrl_regs)) 87 + return PTR_ERR(pllctrl_regs); 88 + 89 + devctrl_regs = syscon_regmap_lookup_by_phandle(np, "ti,syscon-dev"); 90 + if (IS_ERR(devctrl_regs)) 91 + return PTR_ERR(devctrl_regs); 92 + 93 + ret = of_property_read_u32_index(np, "ti,syscon-pll", 1, &rspll_offset); 94 + if (ret) { 95 + dev_err(dev, "couldn't read the reset pll offset!\n"); 96 + return -EINVAL; 97 + } 98 + 99 + ret = of_property_read_u32_index(np, "ti,syscon-dev", 1, &rsmux_offset); 100 + if (ret) { 101 + dev_err(dev, "couldn't read the rsmux offset!\n"); 102 + return -EINVAL; 103 + } 104 + 105 + /* set soft/hard reset */ 106 + val = of_property_read_bool(np, "ti,soft-reset"); 107 + val = val ? RSCFG_RSTYPE_SOFT : RSCFG_RSTYPE_HARD; 108 + 109 + ret = rsctrl_enable_rspll_write(); 110 + if (ret) 111 + return ret; 112 + 113 + ret = regmap_write(pllctrl_regs, rspll_offset + RSCFG_RG, val); 114 + if (ret) 115 + return ret; 116 + 117 + arm_pm_restart = rsctrl_restart; 118 + 119 + /* disable a reset isolation for all module clocks */ 120 + ret = regmap_write(pllctrl_regs, rspll_offset + RSISO_RG, 0); 121 + if (ret) 122 + return ret; 123 + 124 + /* enable a reset for watchdogs from wdt-list */ 125 + for (i = 0; i < WDT_MUX_NUMBER; i++) { 126 + ret = of_property_read_u32_index(np, "ti,wdt-list", i, &val); 127 + if (ret == -EOVERFLOW && !i) { 128 + dev_err(dev, "ti,wdt-list property has to contain at" 129 + "least one entry\n"); 130 + return -EINVAL; 131 + } else if (ret) { 132 + break; 133 + } 134 + 135 + if (val >= WDT_MUX_NUMBER) { 136 + dev_err(dev, "ti,wdt-list property can contain" 137 + "only numbers < 4\n"); 138 + return -EINVAL; 139 + } 140 + 141 + rg = rsmux_offset + val * 4; 142 + 143 + ret = regmap_update_bits(devctrl_regs, rg, RSMUX_OMODE_MASK, 144 + RSMUX_OMODE_RESET_ON | 145 + RSMUX_LOCK_SET); 146 + if (ret) 147 + return ret; 148 + } 149 + 150 + return 0; 151 + } 152 + 153 + static struct platform_driver rsctrl_driver = { 154 + .probe = rsctrl_probe, 155 + .driver = { 156 + .owner = THIS_MODULE, 157 + .name = KBUILD_MODNAME, 158 + .of_match_table = rsctrl_of_match, 159 + }, 160 + }; 161 + module_platform_driver(rsctrl_driver); 162 + 163 + MODULE_AUTHOR("Ivan Khoronzhuk <ivan.khoronzhuk@ti.com>"); 164 + MODULE_DESCRIPTION("Texas Instruments keystone reset driver"); 165 + MODULE_LICENSE("GPL v2"); 166 + MODULE_ALIAS("platform:" KBUILD_MODNAME);