forked from mirrors/linux
		
	gpio/omap: force restore if context loss is not detectable
When booting with device-tree the function pointer for detecting context loss is not populated. Ideally, the pm_runtime framework should be enhanced to allow a means for reporting context/state loss and we could avoid populating such function pointers altogether. In the interim until a generic non-device specific solution is in place, force a restore of the gpio bank when enabling the gpio controller. Adds a new device-tree property for the OMAP GPIO controller to indicate if the GPIO controller is located in a power-domain that never loses power and hence will always maintain its logic state. Signed-off-by: Jon Hunter <jon-hunter@ti.com> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Reviewed-by: Kevin Hilman <khilman@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
		
							parent
							
								
									3513cdeccc
								
							
						
					
					
						commit
						a2797beadf
					
				
					 2 changed files with 22 additions and 10 deletions
				
			
		|  | @ -20,8 +20,11 @@ Required properties: | ||||||
|       8 = active low level-sensitive. |       8 = active low level-sensitive. | ||||||
| 
 | 
 | ||||||
| OMAP specific properties: | OMAP specific properties: | ||||||
| - ti,hwmods: Name of the hwmod associated to the GPIO: | - ti,hwmods:		Name of the hwmod associated to the GPIO: | ||||||
|   "gpio<X>", <X> being the 1-based instance number from the HW spec | 			"gpio<X>", <X> being the 1-based instance number | ||||||
|  | 			from the HW spec. | ||||||
|  | - ti,gpio-always-on: 	Indicates if a GPIO bank is always powered and | ||||||
|  | 			so will never lose its logic state. | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| Example: | Example: | ||||||
|  |  | ||||||
|  | @ -1120,11 +1120,17 @@ static int omap_gpio_probe(struct platform_device *pdev) | ||||||
| 	bank->width = pdata->bank_width; | 	bank->width = pdata->bank_width; | ||||||
| 	bank->is_mpuio = pdata->is_mpuio; | 	bank->is_mpuio = pdata->is_mpuio; | ||||||
| 	bank->non_wakeup_gpios = pdata->non_wakeup_gpios; | 	bank->non_wakeup_gpios = pdata->non_wakeup_gpios; | ||||||
| 	bank->loses_context = pdata->loses_context; |  | ||||||
| 	bank->regs = pdata->regs; | 	bank->regs = pdata->regs; | ||||||
| #ifdef CONFIG_OF_GPIO | #ifdef CONFIG_OF_GPIO | ||||||
| 	bank->chip.of_node = of_node_get(node); | 	bank->chip.of_node = of_node_get(node); | ||||||
| #endif | #endif | ||||||
|  | 	if (node) { | ||||||
|  | 		if (!of_property_read_bool(node, "ti,gpio-always-on")) | ||||||
|  | 			bank->loses_context = true; | ||||||
|  | 	} else { | ||||||
|  | 		bank->loses_context = pdata->loses_context; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| 	bank->domain = irq_domain_add_linear(node, bank->width, | 	bank->domain = irq_domain_add_linear(node, bank->width, | ||||||
| 					     &irq_domain_simple_ops, NULL); | 					     &irq_domain_simple_ops, NULL); | ||||||
|  | @ -1258,9 +1264,9 @@ static int omap_gpio_runtime_resume(struct device *dev) | ||||||
| { | { | ||||||
| 	struct platform_device *pdev = to_platform_device(dev); | 	struct platform_device *pdev = to_platform_device(dev); | ||||||
| 	struct gpio_bank *bank = platform_get_drvdata(pdev); | 	struct gpio_bank *bank = platform_get_drvdata(pdev); | ||||||
| 	int context_lost_cnt_after; |  | ||||||
| 	u32 l = 0, gen, gen0, gen1; | 	u32 l = 0, gen, gen0, gen1; | ||||||
| 	unsigned long flags; | 	unsigned long flags; | ||||||
|  | 	int c; | ||||||
| 
 | 
 | ||||||
| 	spin_lock_irqsave(&bank->lock, flags); | 	spin_lock_irqsave(&bank->lock, flags); | ||||||
| 	_gpio_dbck_enable(bank); | 	_gpio_dbck_enable(bank); | ||||||
|  | @ -1276,14 +1282,17 @@ static int omap_gpio_runtime_resume(struct device *dev) | ||||||
| 	__raw_writel(bank->context.risingdetect, | 	__raw_writel(bank->context.risingdetect, | ||||||
| 		     bank->base + bank->regs->risingdetect); | 		     bank->base + bank->regs->risingdetect); | ||||||
| 
 | 
 | ||||||
| 	if (bank->get_context_loss_count) { | 	if (bank->loses_context) { | ||||||
| 		context_lost_cnt_after = | 		if (!bank->get_context_loss_count) { | ||||||
| 			bank->get_context_loss_count(bank->dev); |  | ||||||
| 		if (context_lost_cnt_after != bank->context_loss_count) { |  | ||||||
| 			omap_gpio_restore_context(bank); | 			omap_gpio_restore_context(bank); | ||||||
| 		} else { | 		} else { | ||||||
| 			spin_unlock_irqrestore(&bank->lock, flags); | 			c = bank->get_context_loss_count(bank->dev); | ||||||
| 			return 0; | 			if (c != bank->context_loss_count) { | ||||||
|  | 				omap_gpio_restore_context(bank); | ||||||
|  | 			} else { | ||||||
|  | 				spin_unlock_irqrestore(&bank->lock, flags); | ||||||
|  | 				return 0; | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Jon Hunter
						Jon Hunter