142a2478bSMichal Simek /* 242a2478bSMichal Simek * Copyright (C) 2009 Michal Simek <[email protected]> 342a2478bSMichal Simek * Copyright (C) 2009 PetaLogix 442a2478bSMichal Simek * 542a2478bSMichal Simek * This file is subject to the terms and conditions of the GNU General Public 642a2478bSMichal Simek * License. See the file "COPYING" in the main directory of this archive 742a2478bSMichal Simek * for more details. 842a2478bSMichal Simek */ 942a2478bSMichal Simek 1042a2478bSMichal Simek #include <linux/init.h> 1142a2478bSMichal Simek #include <linux/of_platform.h> 1242a2478bSMichal Simek #include <asm/prom.h> 1342a2478bSMichal Simek 1442a2478bSMichal Simek /* Trigger specific functions */ 1542a2478bSMichal Simek #ifdef CONFIG_GPIOLIB 1642a2478bSMichal Simek 1742a2478bSMichal Simek #include <linux/of_gpio.h> 1842a2478bSMichal Simek 1942a2478bSMichal Simek static int handle; /* reset pin handle */ 20*67bf8766SMichal Simek static unsigned int reset_val; 2142a2478bSMichal Simek 2242a2478bSMichal Simek static int of_reset_gpio_handle(void) 2342a2478bSMichal Simek { 2442a2478bSMichal Simek int ret; /* variable which stored handle reset gpio pin */ 2542a2478bSMichal Simek struct device_node *root; /* root node */ 2642a2478bSMichal Simek struct device_node *gpio; /* gpio node */ 2742a2478bSMichal Simek struct of_gpio_chip *of_gc = NULL; 2842a2478bSMichal Simek enum of_gpio_flags flags ; 2942a2478bSMichal Simek const void *gpio_spec; 3042a2478bSMichal Simek 3142a2478bSMichal Simek /* find out root node */ 3242a2478bSMichal Simek root = of_find_node_by_path("/"); 3342a2478bSMichal Simek 3442a2478bSMichal Simek /* give me handle for gpio node to be possible allocate pin */ 3542a2478bSMichal Simek ret = of_parse_phandles_with_args(root, "hard-reset-gpios", 3642a2478bSMichal Simek "#gpio-cells", 0, &gpio, &gpio_spec); 3742a2478bSMichal Simek if (ret) { 3842a2478bSMichal Simek pr_debug("%s: can't parse gpios property\n", __func__); 3942a2478bSMichal Simek goto err0; 4042a2478bSMichal Simek } 4142a2478bSMichal Simek 4242a2478bSMichal Simek of_gc = gpio->data; 4342a2478bSMichal Simek if (!of_gc) { 4442a2478bSMichal Simek pr_debug("%s: gpio controller %s isn't registered\n", 4542a2478bSMichal Simek root->full_name, gpio->full_name); 4642a2478bSMichal Simek ret = -ENODEV; 4742a2478bSMichal Simek goto err1; 4842a2478bSMichal Simek } 4942a2478bSMichal Simek 5042a2478bSMichal Simek ret = of_gc->xlate(of_gc, root, gpio_spec, &flags); 5142a2478bSMichal Simek if (ret < 0) 5242a2478bSMichal Simek goto err1; 5342a2478bSMichal Simek 5442a2478bSMichal Simek ret += of_gc->gc.base; 5542a2478bSMichal Simek err1: 5642a2478bSMichal Simek of_node_put(gpio); 5742a2478bSMichal Simek err0: 5842a2478bSMichal Simek pr_debug("%s exited with status %d\n", __func__, ret); 5942a2478bSMichal Simek return ret; 6042a2478bSMichal Simek } 6142a2478bSMichal Simek 6242a2478bSMichal Simek void of_platform_reset_gpio_probe(void) 6342a2478bSMichal Simek { 6442a2478bSMichal Simek int ret; 6542a2478bSMichal Simek handle = of_reset_gpio_handle(); 6642a2478bSMichal Simek 6742a2478bSMichal Simek if (!gpio_is_valid(handle)) { 6842a2478bSMichal Simek printk(KERN_INFO "Skipping unavailable RESET gpio %d (%s)\n", 6942a2478bSMichal Simek handle, "reset"); 7042a2478bSMichal Simek } 7142a2478bSMichal Simek 7242a2478bSMichal Simek ret = gpio_request(handle, "reset"); 7342a2478bSMichal Simek if (ret < 0) { 7442a2478bSMichal Simek printk(KERN_INFO "GPIO pin is already allocated\n"); 7542a2478bSMichal Simek return; 7642a2478bSMichal Simek } 7742a2478bSMichal Simek 7842a2478bSMichal Simek /* get current setup value */ 79*67bf8766SMichal Simek reset_val = gpio_get_value(handle); 8042a2478bSMichal Simek /* FIXME maybe worth to perform any action */ 81*67bf8766SMichal Simek pr_debug("Reset: Gpio output state: 0x%x\n", reset_val); 8242a2478bSMichal Simek 8342a2478bSMichal Simek /* Setup GPIO as output */ 8442a2478bSMichal Simek ret = gpio_direction_output(handle, 0); 8542a2478bSMichal Simek if (ret < 0) 8642a2478bSMichal Simek goto err; 8742a2478bSMichal Simek 8842a2478bSMichal Simek /* Setup output direction */ 8942a2478bSMichal Simek gpio_set_value(handle, 0); 9042a2478bSMichal Simek 91*67bf8766SMichal Simek printk(KERN_INFO "RESET: Registered gpio device: %d, current val: %d\n", 92*67bf8766SMichal Simek handle, reset_val); 9342a2478bSMichal Simek return; 9442a2478bSMichal Simek err: 9542a2478bSMichal Simek gpio_free(handle); 9642a2478bSMichal Simek return; 9742a2478bSMichal Simek } 9842a2478bSMichal Simek 9942a2478bSMichal Simek 10042a2478bSMichal Simek static void gpio_system_reset(void) 10142a2478bSMichal Simek { 102*67bf8766SMichal Simek gpio_set_value(handle, 1 - reset_val); 10342a2478bSMichal Simek } 10442a2478bSMichal Simek #else 10542a2478bSMichal Simek #define gpio_system_reset() do {} while (0) 10642a2478bSMichal Simek void of_platform_reset_gpio_probe(void) 10742a2478bSMichal Simek { 10842a2478bSMichal Simek return; 10942a2478bSMichal Simek } 11042a2478bSMichal Simek #endif 11142a2478bSMichal Simek 11242a2478bSMichal Simek void machine_restart(char *cmd) 11342a2478bSMichal Simek { 11442a2478bSMichal Simek printk(KERN_NOTICE "Machine restart...\n"); 11542a2478bSMichal Simek gpio_system_reset(); 11642a2478bSMichal Simek dump_stack(); 11742a2478bSMichal Simek while (1) 11842a2478bSMichal Simek ; 11942a2478bSMichal Simek } 12042a2478bSMichal Simek 12142a2478bSMichal Simek void machine_shutdown(void) 12242a2478bSMichal Simek { 12342a2478bSMichal Simek printk(KERN_NOTICE "Machine shutdown...\n"); 12442a2478bSMichal Simek while (1) 12542a2478bSMichal Simek ; 12642a2478bSMichal Simek } 12742a2478bSMichal Simek 12842a2478bSMichal Simek void machine_halt(void) 12942a2478bSMichal Simek { 13042a2478bSMichal Simek printk(KERN_NOTICE "Machine halt...\n"); 13142a2478bSMichal Simek while (1) 13242a2478bSMichal Simek ; 13342a2478bSMichal Simek } 13442a2478bSMichal Simek 13542a2478bSMichal Simek void machine_power_off(void) 13642a2478bSMichal Simek { 13742a2478bSMichal Simek printk(KERN_NOTICE "Machine power off...\n"); 13842a2478bSMichal Simek while (1) 13942a2478bSMichal Simek ; 14042a2478bSMichal Simek } 141