diff options
| author | Doug Zobel <dzobel1@motorola.com> | 2014-02-26 17:44:29 -0600 | 
|---|---|---|
| committer | James Wylder <jwylder@motorola.com> | 2014-03-05 17:47:28 -0600 | 
| commit | 433f5cfd7ed53d216b1155cad2f7b364323a4372 (patch) | |
| tree | b7acb197896ab3ee9370178fa953b101c6bea186 | |
| parent | a4bc17668abc8c7ba0e6f2726f4bbd1efd457c19 (diff) | |
| download | olio-linux-3.10-433f5cfd7ed53d216b1155cad2f7b364323a4372.tar.xz olio-linux-3.10-433f5cfd7ed53d216b1155cad2f7b364323a4372.zip  | |
IKXCLOCK-338 minnow-poweroff: Drive sys_reset line low all the time
Support for the sys_reset line was added so that it can be driven low
all the time.  This line is only used in bootloader, but needs to be
driven low in the kernel to prevent random resets of the system.
Change-Id: I5c8976b578ee8cc8f7f960e34bcbe54ba45a780d
| -rw-r--r-- | drivers/power/reset/minnow-poweroff.c | 62 | 
1 files changed, 45 insertions, 17 deletions
diff --git a/drivers/power/reset/minnow-poweroff.c b/drivers/power/reset/minnow-poweroff.c index c79679b82ba..e2bfb1760f1 100644 --- a/drivers/power/reset/minnow-poweroff.c +++ b/drivers/power/reset/minnow-poweroff.c @@ -21,13 +21,14 @@  #include <linux/pinctrl/consumer.h>  #include <linux/usb.h> -#define NUM_GPIOS 1 +#define NUM_GPIOS 2  /*   * Hold configuration here, cannot be more than one instance of the driver   * since pm_power_off itself is global.   */  static int g_gpio_wdi = -1; +static int g_gpio_sys_resetb = -1;  static int g_usb_connected = -1;  static struct pinctrl_state *gp_outputstate;  static struct pinctrl_state *gp_tristate; @@ -83,9 +84,8 @@ static struct notifier_block pmic_usb_notifier = {  static int minnow_gpio_poweroff_probe(struct platform_device *pdev)  { -	int ret; +	int i, ret;  	struct device_node *np; -	enum of_gpio_flags flags;  	/* Lets register right away for usb notifications */  	usb_register_notify(&pmic_usb_notifier); @@ -108,49 +108,74 @@ static int minnow_gpio_poweroff_probe(struct platform_device *pdev)  		goto unregister_usb;  	} -	g_gpio_wdi = of_get_gpio_flags(np, 0, &flags); - -	ret = gpio_request_one(g_gpio_wdi, flags, -					"minnow_poweroff-gpio-wdi"); -	if (ret) { -		pr_err("%s: Can't request gpios err: %d\n", __func__, ret); +	/* Make sure number of GPIOs defined matches the supplied number of +	 * GPIO name strings. +	 */ +	if (of_property_count_strings(np, "gpio-names") != NUM_GPIOS) { +		dev_err(&pdev->dev, "GPIO info and name mismatch\n");  		goto unregister_usb;  	} +	for (i = 0; i < NUM_GPIOS; i++) { +		int gpio; +		enum of_gpio_flags flags; +		const char *label; + +		gpio = of_get_gpio_flags(np, i, &flags); +		of_property_read_string_index(np, "gpio-names", i, &label); +		ret = gpio_request_one(gpio, flags, label); +		if (ret) +			goto free_gpios; + +		if (!strcmp(label, "wdi")) +			g_gpio_wdi = gpio; +		else if (!strcmp(label, "sys_reset")) +			g_gpio_sys_resetb = gpio; +		else { +			dev_info(&pdev->dev, "Unknown gpio: %s (gpio-%d)\n", +				 label, gpio); +			goto free_gpios; +		} +		dev_info(&pdev->dev, "%s: gpio-%d  flags: 0x%x\n", +			 label, gpio, flags); +	} +  	gp_pctrl = devm_pinctrl_get(&(pdev->dev));  	if (IS_ERR(gp_pctrl)) {  		ret = PTR_ERR(gp_pctrl);  		pr_err("%s: no pinctrl handle\n", __func__); -		goto err; +		goto free_gpios;  	}  	gp_outputstate = pinctrl_lookup_state(gp_pctrl, "output");  	if (IS_ERR(gp_outputstate)) {  		ret = PTR_ERR(gp_outputstate);  		pr_err("%s: Can't obtain output pinctrl state\n", __func__); -		goto err; +		goto free_gpios;  	}  	gp_tristate = pinctrl_lookup_state(gp_pctrl, "tristate");  	if (IS_ERR(gp_tristate)) {  		ret = PTR_ERR(gp_tristate);  		pr_err("%s: Can't obtain tristate pinctrl state\n", __func__); -		goto err; +		goto free_gpios;  	}  	ret = pinctrl_select_state(gp_pctrl, gp_tristate);  	if (ret) {  		pr_err("%s: failed to set tristate\n", __func__); -		ret = -EINVAL; -		goto err; +		goto free_gpios;  	}  	pm_power_off = &minnow_gpio_poweroff_do_poweroff;  	return 0; -err: -	gpio_free(g_gpio_wdi); +free_gpios: +	if (gpio_is_valid(g_gpio_wdi)) +		gpio_free(g_gpio_wdi); +	if (gpio_is_valid(g_gpio_sys_resetb)) +		gpio_free(g_gpio_sys_resetb);  unregister_usb:  	usb_unregister_notify(&pmic_usb_notifier);  	return -ENODEV; @@ -158,7 +183,10 @@ unregister_usb:  static int minnow_gpio_poweroff_remove(struct platform_device *pdev)  { -	gpio_free(g_gpio_wdi); +	if (gpio_is_valid(g_gpio_wdi)) +		gpio_free(g_gpio_wdi); +	if (gpio_is_valid(g_gpio_sys_resetb)) +		gpio_free(g_gpio_sys_resetb);  	if (pm_power_off == &minnow_gpio_poweroff_do_poweroff)  		pm_power_off = NULL;  |