使用regulator_get時的一個小注意事項

bigfish99發表於2021-06-12

Linux kernel 使用 regulator 框架來管理電源,比如 PMIC 晶片上常見的LDO。使用 regulator 的常規流程如以下程式碼所示:

void set_vbus_voltage(struct device *dev)
{
  struct regulator *vbus;
​
  vbus = regulator_get(dev, "vbus");
  if (IS_ERR(vbus)) {
    ret = PTR_ERR(vbus);
    goto reg_put;
  }
​
  regulator_set_voltage(vbus, 5000000, 5000000);
  regulator_enable(vbus);
  
reg_put: 
  regulator_put(vbus);
}

 

IS_ERR巨集用來判斷 regulator_get 的返回值是否有錯誤,如果沒有錯誤,表示成功 get 到這個 regulator,那麼就可以進行後續的 set 和 enable 操作了。這個設計符合我們的思維習慣。

那麼對於上例,當 IS_ERR(vbus) 返回假時,也就是成功 get 到了名為 vbus 的 regulator,是否代表 vbus 這個 regulator 一定會起作用,輸出 5V 呢?答案是不一定。

假設我們並沒有在裝置樹中定義或者程式碼中建立“vbus”這個 regulator,比如我們一不小心搞錯了regulator的名字,這個 regulator 的正確名字應該是 “vusbhost”,而不是 “vbus”,那麼IS_ERR巨集能判定出來嗎?按我們的思維習慣應該是會返回真,也就是判定 get regulator 出錯了;但是實際情況恰恰相反,IS_ERR巨集仍然返回假,也就是判定 get regulator 成功。為什麼會發生這種情況呢,這就需要看一下 regulator_get 函式的具體實現。

 

如上圖,regulator_get 最終會呼叫到 _regulator_get。結合紅色箭頭1和2所指向的程式碼,可以看出程式碼邏輯是:如果找不到對應名字的 regulator,那麼就返回 dummy regulator,並且在 kernel log 中輸出相關 warning 資訊。比如上例中如果找不到 “vbus”,則會輸出如下 warning:

supply vbus not found, using dummy regulator

同時作者還在註釋中給出了理由:“假設某個 regulator 是物理硬體上存在並已經使能了的,如果軟體中找不到,那麼就提供一個 dummy regulator 裝置”。

 

所以當我們在除錯驅動時,如果發現某個 regulator 沒有按預期輸出,且跟蹤程式碼流程也沒有發現中途出錯返回,那麼不妨考慮一下上述情況,仔細看看 kernel log 中有沒有相關的 warning。

 


 作者:bigfish99

部落格:https://www.cnblogs.com/bigfish0506/

公眾號:大魚嵌入式

相關文章