From 42a2478b789cb1b4335909e0fecc721c07be7d90 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 2 Oct 2009 12:48:47 +0200 Subject: microblaze: GPIO reset support Signed-off-by: Michal Simek --- arch/microblaze/kernel/reset.c | 138 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 arch/microblaze/kernel/reset.c (limited to 'arch/microblaze/kernel/reset.c') diff --git a/arch/microblaze/kernel/reset.c b/arch/microblaze/kernel/reset.c new file mode 100644 index 000000000000..ce74a6f436e3 --- /dev/null +++ b/arch/microblaze/kernel/reset.c @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2009 Michal Simek + * Copyright (C) 2009 PetaLogix + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include + +/* Trigger specific functions */ +#ifdef CONFIG_GPIOLIB + +#include + +static int handle; /* reset pin handle */ + +static int of_reset_gpio_handle(void) +{ + int ret; /* variable which stored handle reset gpio pin */ + struct device_node *root; /* root node */ + struct device_node *gpio; /* gpio node */ + struct of_gpio_chip *of_gc = NULL; + enum of_gpio_flags flags ; + const void *gpio_spec; + + /* find out root node */ + root = of_find_node_by_path("/"); + + /* give me handle for gpio node to be possible allocate pin */ + ret = of_parse_phandles_with_args(root, "hard-reset-gpios", + "#gpio-cells", 0, &gpio, &gpio_spec); + if (ret) { + pr_debug("%s: can't parse gpios property\n", __func__); + goto err0; + } + + of_gc = gpio->data; + if (!of_gc) { + pr_debug("%s: gpio controller %s isn't registered\n", + root->full_name, gpio->full_name); + ret = -ENODEV; + goto err1; + } + + ret = of_gc->xlate(of_gc, root, gpio_spec, &flags); + if (ret < 0) + goto err1; + + ret += of_gc->gc.base; +err1: + of_node_put(gpio); +err0: + pr_debug("%s exited with status %d\n", __func__, ret); + return ret; +} + +void of_platform_reset_gpio_probe(void) +{ + int ret; + handle = of_reset_gpio_handle(); + + if (!gpio_is_valid(handle)) { + printk(KERN_INFO "Skipping unavailable RESET gpio %d (%s)\n", + handle, "reset"); + } + + ret = gpio_request(handle, "reset"); + if (ret < 0) { + printk(KERN_INFO "GPIO pin is already allocated\n"); + return; + } + + /* get current setup value */ + ret = gpio_get_value(handle); + /* FIXME maybe worth to perform any action */ + pr_debug("Reset: Gpio output state: 0x%x\n", ret); + + /* Setup GPIO as output */ + ret = gpio_direction_output(handle, 0); + if (ret < 0) + goto err; + + /* Setup output direction */ + gpio_set_value(handle, 0); + + printk(KERN_INFO "Registered reset device: %d\n", handle); + return; +err: + gpio_free(handle); + return; +} + + +static void gpio_system_reset(void) +{ + gpio_set_value(handle, 1); +} +#else +#define gpio_system_reset() do {} while (0) +void of_platform_reset_gpio_probe(void) +{ + return; +} +#endif + +void machine_restart(char *cmd) +{ + printk(KERN_NOTICE "Machine restart...\n"); + gpio_system_reset(); + dump_stack(); + while (1) + ; +} + +void machine_shutdown(void) +{ + printk(KERN_NOTICE "Machine shutdown...\n"); + while (1) + ; +} + +void machine_halt(void) +{ + printk(KERN_NOTICE "Machine halt...\n"); + while (1) + ; +} + +void machine_power_off(void) +{ + printk(KERN_NOTICE "Machine power off...\n"); + while (1) + ; +} -- cgit v1.2.3 From 753758304019fc7c2ef3af674f52a193b1606d15 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 29 Oct 2009 08:58:15 +0100 Subject: microblaze: Fix announce message for reset gpio I had to change message for gpio-reset because I always not to see it. Prefix RESET is big and visible. Signed-off-by: Michal Simek --- arch/microblaze/kernel/reset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/microblaze/kernel/reset.c') diff --git a/arch/microblaze/kernel/reset.c b/arch/microblaze/kernel/reset.c index ce74a6f436e3..789af930d72c 100644 --- a/arch/microblaze/kernel/reset.c +++ b/arch/microblaze/kernel/reset.c @@ -87,7 +87,7 @@ void of_platform_reset_gpio_probe(void) /* Setup output direction */ gpio_set_value(handle, 0); - printk(KERN_INFO "Registered reset device: %d\n", handle); + printk(KERN_INFO "RESET: Registered gpio device: %d\n", handle); return; err: gpio_free(handle); -- cgit v1.2.3 From 67bf87665466c4ea93e2c54d66dfd4cdac011a4b Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 29 Oct 2009 10:12:59 +0100 Subject: microblaze: Support both levels for reset Till this patch reset always perform writen to 1. Now we can use negative logic and perform reset write to 0. It is opposite level than is currently read from that pin Signed-off-by: Michal Simek --- arch/microblaze/kernel/reset.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'arch/microblaze/kernel/reset.c') diff --git a/arch/microblaze/kernel/reset.c b/arch/microblaze/kernel/reset.c index 789af930d72c..a1721a33042e 100644 --- a/arch/microblaze/kernel/reset.c +++ b/arch/microblaze/kernel/reset.c @@ -17,6 +17,7 @@ #include static int handle; /* reset pin handle */ +static unsigned int reset_val; static int of_reset_gpio_handle(void) { @@ -75,9 +76,9 @@ void of_platform_reset_gpio_probe(void) } /* get current setup value */ - ret = gpio_get_value(handle); + reset_val = gpio_get_value(handle); /* FIXME maybe worth to perform any action */ - pr_debug("Reset: Gpio output state: 0x%x\n", ret); + pr_debug("Reset: Gpio output state: 0x%x\n", reset_val); /* Setup GPIO as output */ ret = gpio_direction_output(handle, 0); @@ -87,7 +88,8 @@ void of_platform_reset_gpio_probe(void) /* Setup output direction */ gpio_set_value(handle, 0); - printk(KERN_INFO "RESET: Registered gpio device: %d\n", handle); + printk(KERN_INFO "RESET: Registered gpio device: %d, current val: %d\n", + handle, reset_val); return; err: gpio_free(handle); @@ -97,7 +99,7 @@ err: static void gpio_system_reset(void) { - gpio_set_value(handle, 1); + gpio_set_value(handle, 1 - reset_val); } #else #define gpio_system_reset() do {} while (0) -- cgit v1.2.3