diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-06 00:51:19 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-06 00:51:19 +0400 |
commit | dfc25e4503aef6b82a1de4a0fbe19aafa8648fbe (patch) | |
tree | 0a4f3a07e2286918298e635186e42726f4658cbd /arch/arm/mach-prima2/rstc.c | |
parent | 9f800363bb0ea459e15bef0928a72c88d374e489 (diff) | |
parent | 8f881c67368f82d0e20e1072b50b21132cc2440d (diff) | |
download | linux-dfc25e4503aef6b82a1de4a0fbe19aafa8648fbe.tar.xz |
Merge tag 'cleanup-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC cleanups from Arnd Bergmann:
"These cleanup patches are mainly move stuff around and should all be
harmless. They are mainly split out so that other branches can be
based on top to avoid conflicts.
Notable changes are:
- We finally remove all mach/timex.h, after CLOCK_TICK_RATE is no
longer used (Uwe Kleine-König)
- The Qualcomm MSM platform is split out into legacy mach-msm and
new-style mach-qcom, to allow easier maintainance of the new
hardware support without regressions (Kumar Gala)
- A rework of some of the Kconfig logic to simplify multiplatform
support (Rob Herring)
- Samsung Exynos gets closer to supporting multiplatform (Sachin
Kamat and others)
- mach-bcm3528 gets merged into mach-bcm (Stephen Warren)
- at91 gains some common clock framework support (Alexandre Belloni,
Jean-Jacques Hiblot and other French people)"
* tag 'cleanup-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (89 commits)
ARM: hisi: select HAVE_ARM_SCU only for SMP
ARM: efm32: allow uncompress debug output
ARM: prima2: build reset code standalone
ARM: at91: add PWM clock
ARM: at91: move sam9261 SoC to common clk
ARM: at91: prepare common clk transition for sam9261 SoC
ARM: at91: updated the at91_dt_defconfig with support for the ADS7846
ARM: at91: dt: sam9261: Device Tree support for the at91sam9261ek
ARM: at91: dt: defconfig: Added the sam9261 to the list of DT-enabled SOCs
ARM: at91: dt: Add at91sam9261 dt SoC support
ARM: at91: switch sam9rl to common clock framework
ARM: at91/dt: define main clk frequency of at91sam9rlek
ARM: at91/dt: define at91sam9rl clocks
ARM: at91: prepare common clk transition for sam9rl SoCs
ARM: at91: prepare sam9 dt boards transition to common clk
ARM: at91: dt: sam9rl: Device Tree for the at91sam9rlek
ARM: at91/defconfig: Add the sam9rl to the list of DT-enabled SOCs
ARM: at91: Add at91sam9rl DT SoC support
ARM: at91: prepare at91sam9rl DT transition
ARM: at91/defconfig: refresh at91sam9260_9g20_defconfig
...
Diffstat (limited to 'arch/arm/mach-prima2/rstc.c')
-rw-r--r-- | arch/arm/mach-prima2/rstc.c | 99 |
1 files changed, 64 insertions, 35 deletions
diff --git a/arch/arm/mach-prima2/rstc.c b/arch/arm/mach-prima2/rstc.c index ccb53391147a..4887a2a4c698 100644 --- a/arch/arm/mach-prima2/rstc.c +++ b/arch/arm/mach-prima2/rstc.c @@ -13,57 +13,38 @@ #include <linux/device.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/platform_device.h> #include <linux/reboot.h> +#include <linux/reset-controller.h> -void __iomem *sirfsoc_rstc_base; -static DEFINE_MUTEX(rstc_lock); - -static struct of_device_id rstc_ids[] = { - { .compatible = "sirf,prima2-rstc" }, - { .compatible = "sirf,marco-rstc" }, - {}, -}; +#include <asm/system_misc.h> -static int __init sirfsoc_of_rstc_init(void) -{ - struct device_node *np; +#define SIRFSOC_RSTBIT_NUM 64 - np = of_find_matching_node(NULL, rstc_ids); - if (!np) { - pr_err("unable to find compatible sirf rstc node in dtb\n"); - return -ENOENT; - } - - sirfsoc_rstc_base = of_iomap(np, 0); - if (!sirfsoc_rstc_base) - panic("unable to map rstc cpu registers\n"); - - of_node_put(np); - - return 0; -} -early_initcall(sirfsoc_of_rstc_init); +static void __iomem *sirfsoc_rstc_base; +static DEFINE_MUTEX(rstc_lock); -int sirfsoc_reset_device(struct device *dev) +static int sirfsoc_reset_module(struct reset_controller_dev *rcdev, + unsigned long sw_reset_idx) { - u32 reset_bit; + u32 reset_bit = sw_reset_idx; - if (of_property_read_u32(dev->of_node, "reset-bit", &reset_bit)) + if (reset_bit >= SIRFSOC_RSTBIT_NUM) return -EINVAL; mutex_lock(&rstc_lock); - if (of_device_is_compatible(dev->of_node, "sirf,prima2-rstc")) { + if (of_device_is_compatible(rcdev->of_node, "sirf,prima2-rstc")) { /* * Writing 1 to this bit resets corresponding block. Writing 0 to this * bit de-asserts reset signal of the corresponding block. * datasheet doesn't require explicit delay between the set and clear * of reset bit. it could be shorter if tests pass. */ - writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | reset_bit, + writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | (1 << reset_bit), sirfsoc_rstc_base + (reset_bit / 32) * 4); msleep(10); - writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~reset_bit, + writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~(1 << reset_bit), sirfsoc_rstc_base + (reset_bit / 32) * 4); } else { /* @@ -73,9 +54,9 @@ int sirfsoc_reset_device(struct device *dev) * datasheet doesn't require explicit delay between the set and clear * of reset bit. it could be shorter if tests pass. */ - writel(reset_bit, sirfsoc_rstc_base + (reset_bit / 32) * 8); + writel(1 << reset_bit, sirfsoc_rstc_base + (reset_bit / 32) * 8); msleep(10); - writel(reset_bit, sirfsoc_rstc_base + (reset_bit / 32) * 8 + 4); + writel(1 << reset_bit, sirfsoc_rstc_base + (reset_bit / 32) * 8 + 4); } mutex_unlock(&rstc_lock); @@ -83,9 +64,57 @@ int sirfsoc_reset_device(struct device *dev) return 0; } +static struct reset_control_ops sirfsoc_rstc_ops = { + .reset = sirfsoc_reset_module, +}; + +static struct reset_controller_dev sirfsoc_reset_controller = { + .ops = &sirfsoc_rstc_ops, + .nr_resets = SIRFSOC_RSTBIT_NUM, +}; + #define SIRFSOC_SYS_RST_BIT BIT(31) -void sirfsoc_restart(enum reboot_mode mode, const char *cmd) +static void sirfsoc_restart(enum reboot_mode mode, const char *cmd) { writel(SIRFSOC_SYS_RST_BIT, sirfsoc_rstc_base); } + +static int sirfsoc_rstc_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + sirfsoc_rstc_base = of_iomap(np, 0); + if (!sirfsoc_rstc_base) { + dev_err(&pdev->dev, "unable to map rstc cpu registers\n"); + return -ENOMEM; + } + + sirfsoc_reset_controller.of_node = np; + arm_pm_restart = sirfsoc_restart; + + if (IS_ENABLED(CONFIG_RESET_CONTROLLER)) + reset_controller_register(&sirfsoc_reset_controller); + + return 0; +} + +static const struct of_device_id rstc_ids[] = { + { .compatible = "sirf,prima2-rstc" }, + { .compatible = "sirf,marco-rstc" }, + {}, +}; + +static struct platform_driver sirfsoc_rstc_driver = { + .probe = sirfsoc_rstc_probe, + .driver = { + .name = "sirfsoc_rstc", + .owner = THIS_MODULE, + .of_match_table = rstc_ids, + }, +}; + +static int __init sirfsoc_rstc_init(void) +{ + return platform_driver_register(&sirfsoc_rstc_driver); +} +subsys_initcall(sirfsoc_rstc_init); |