I am trying to shutdown the processor by driving a GPIO low as the final step in my kernel shutdown. I already have pm_power_off assigned to a custom function in my board file. (See my post here: http://e2e.ti.com/support/embedded/linux/f/354/p/138382/747621.aspx#747621) My problem is that no matter how I try, I cannot set the GPIO low. Below my pm_power_off code:
#define GPIO_PS_KEEPALIVE 28
static void iflextouch_power_off(void)
{
/* Driving GPIO 28 low will kill power to the AM3517*/
/* Try the eay way first */
gpio_set_value(GPIO_PS_KEEPALIVE, 0);
/* If we get this far, perhaps we haven't been configured properly
/* so we'll request it and enable as output with initial value of 0 */
int ret = gpio_request(GPIO_PS_KEEPALIVE, "ps_keepalive");
if(ret < 0){
printk(KERN_WARNING "failed to request GPIO#%d\n",GPIO_PS_KEEPALIVE);
} else {
ret = gpio_direction_output(GPIO_PS_KEEPALIVE, 0);
if (ret < 0){
printk(KERN_WARNING "PS_KEEPALIVE GPIO#%d cannot be configured as output\n", GPIO_PS_KEEPALIVE);
}
}
gpio_free(GPIO_PS_KEEPALIVE); //alas we have failed
/*** Now you've made me angry ***/
void __iomem *reg;
u32 l;
/* Set Value */
reg = 0x48310000; //OMAP34XX_GPIO1_BASE
l = 1 << GPIO_PS_KEEPALIVE;
__raw_writel(l, reg + 0x0090); //OMAP24XX_GPIO_CLEARDATAOUT
//u32 l = __raw_readl(reg + 0x003C); //OMAP24XX_GPIO_DATAOUT
//l &= ~(1 << GPIO_PS_KEEPALIVE);
//__raw_writel(l, reg);
/* Set Direction */
l = __raw_readl(reg + 0x0034); //OMAP24XX_GPIO_OE
l &= ~(1 << GPIO_PS_KEEPALIVE);
__raw_writel(l, reg);
printk(KERN_WARNING "Power Off Failed. System Halted\n");
while(1);
}
All three attempts at setting the GPIO will fail. And I will drop down to my error message and halt with the GPIO never being set. I confirmed that GPIO 28 is configured as an output gpio in my u-boot as well as being re-initialized in the kernel by calling omap_mux_init_gpio(GPIO_PS_KEEPALIVE, OMAP_PIN_OUTPUT); in my board initialization. Any suggestions for what would be causing me to not drive a gpio in this scenario?
Thanks,
Sean