記一次gpio喚醒調試

使用TP的IRQ腳做手勢喚醒。雙擊屏幕後,從log看cpu已經被喚醒了,但很快又睡下去,通過log分析,發現沒有進入中斷處理函數。這裏使用的電平中斷。以前已分析過電平/邊沿喚醒cpu流程https://blog.csdn.net/mike8825/article/details/98473014,打印發現handle_level_irq只跑了一遍,第二次的handle_level_irq沒有過來導致無法進入中斷函數。一開始懷疑是低電平的持續時間不夠,導致沒有第二次中斷過來。修改TP的固件,讓TP的IRQ拉低到500ms,也是一樣的情況,也用示波器確認信號確實拉低了500ms。跟cpu廠商那邊溝通,說該cpu支持邊沿喚醒,也支持電平喚醒,建議用邊沿喚醒測試。修過代碼後,邊沿喚醒的確有效,但電平喚醒爲什麼不會進入中斷。fae加了一些打印信息,也發現什麼異常。

查看cpu手冊,gpio支持dbc和level模式,再看下gpio代碼,只有dbc模式纔會設置電平模式,所以設置電平中斷沒有成功,導致還是邊沿的電平觸發方式,所以中斷只會過來一次,第二次中斷沒有過來,導致沒有進入中斷模式,也就是平臺代碼的BUG。

static int sprd_gpio_plus_irq_set_type(struct irq_data *data,unsigned int flow_type)
{
    case IRQ_TYPE_LEVEL_LOW:
		mode = sprd_gpio_plus_read(chip, channel, REG_INT_CRL,
			BIT_INT_MODE, INT_MODE_WIDTH);
		dbnc = sprd_gpio_plus_read(chip, channel, REG_INT_CRL,
			BIT_DBC_CYCLE, DBC_CYCLE_WIDTH);
		if ((mode == GPIO_INT_DBC_MODE) && (dbnc == 0)) {
			sprd_gpio_plus_write(chip, channel, REG_INT_CRL,
			BIT_INT_MODE, INT_MODE_WIDTH, GPIO_INT_LEVEL_MODE);
		}
		sprd_gpio_plus_write(chip, channel, REG_INT_CRL,
			BIT_INT_LEVEL, 1, 0);
		irq_set_handler_locked(data, handle_level_irq);
		break;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章