openbmc大多數設備的dts中,gpio的名字都在gpio-line-names中命名
如aspeed-bmc-opp-romulus.dts中
&gpio {
gpio-line-names =
/*A0-A7*/ "","cfam-reset","","","","","fsi-mux","",
/*B0-B7*/ "","","","","","","","",
/*C0-C7*/ "","","","","","","","",
/*D0-D7*/ "fsi-enable","","","nic_func_mode0","nic_func_mode1","","","",
/*E0-E7*/ "","","","","","","","",
/*F0-F7*/ "","","","","","","","",
/*G0-G7*/ "","","","","","","","",
/*H0-H7*/ "","","","","","","","",
/*I0-I7*/ "","","","power-button","","","","",
/*J0-J7*/ "","","checkstop","","","","","",
/*K0-K7*/ "","","","","","","","",
/*L0-L7*/ "","","","","","","","",
/*M0-M7*/ "","","","","","","","",
/*N0-N7*/ "","","led-fault","",
"led-identify","","","",
/*O0-O7*/ "","","","","","","","",
/*P0-P7*/ "","","","","","","","",
/*Q0-Q7*/ "","","","","","","","id-button",
/*R0-R7*/ "","","fsi-trans","","","led-power","","",
/*S0-S7*/ "","","","","","","","seq_cont",
/*T0-T7*/ "","","","","","","","",
/*U0-U7*/ "","","","","","","","",
/*V0-V7*/ "","","","","","","","",
/*W0-W7*/ "","","","","","","","",
/*X0-X7*/ "","","","","","","","",
/*Y0-Y7*/ "","","","","","","","",
/*Z0-Z7*/ "","","","","","","","",
/*AA0-AA7*/ "fsi-clock","","fsi-data","","","","","",
/*AB0-AB7*/ "","","","","","","","",
/*AC0-AC7*/ "","","","","","","","";
...
};
而aspeed-bmc-lenovo-hr630.dts中,出現了在subnode中用line-name這個property命名的方式
&gpio {
pin_gpio_a1 {
gpio-hog;
gpios = <ASPEED_GPIO(A, 1) GPIO_ACTIVE_LOW>;
output-high;
line-name = "BMC_EMMC_RST_N";
};
...
};
兩種命名方式有何區別呢?
以下是代碼層面創建gpio設備的代碼調用棧:
aspeed_gpio_probe
gpiochip_add_data
devm_gpiochip_add_data_with_key
gpiochip_add_data_with_key
of_gpiochip_add
devprop_gpiochip_set_names
fwnode_property_read_string_array(fwnode, "gpio-line-names", NULL, 0)
gdev->descs[i].name =
of_gpiochip_scan_gpios
of_gpiochip_add_hog
of_parse_own_gpio
of_property_read_string(np, "line-name", name)
gpiod_hog
gpiochip_request_own_desc
gpiod_request_commit
desc_set_label
gdev->descs[i].label =
可見屬性gpio-line-names最終賦值給了desc的name變量
而line-name最終賦值給了desc的label變量
那最終應用有何區別呢?
應用中對於gpio的操作基本是基於libgpiod這個庫
閱讀庫源碼可以得知驅動中的name變量在libgpiod的gpio信息結構中仍然叫做name,而驅動中的label在libgpiod中被命名為consumer
對於擁有gpio-hog屬性的gpio,在libgpiod讀取gpio信息時,內核會標記其flag為GPIOLINE_FLAG_KERNEL
在調用gpioinfo的時候,會顯示label,否則顯示為unused
后續用gpioset等其他操作時,底層會再次調用gpiod_request_commit
如果gpio被配置為gpio-hog,由於內核之前已經執行過gpiod_request_commit了,那么應用中再次請求就會失敗,返回EBUSY
static int gpiod_request_commit(struct gpio_desc *desc, const char *label)
{
……
if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
desc_set_label(desc, label ? : "?");
ret = 0;
} else {
kfree_const(label);
ret = -EBUSY;
goto done;
}
……
}
由此可見gpio驅動中的label屬性,實際就是用來標記當前gpio的擁有者是誰
總上所述,gpio-line-names和line-name雖然都包含name,但是其用途是不一樣的
gpio-line-names是真正用來表示名字的
而line-name是用於記錄gpio的控制者
如果希望gpio在應用層能夠控制,就不能配置gpio-hog屬性,而沒有gpio-hog屬性的話,line-name也就沒有意義了
看來gpio-hog是為了安全性而提供的一種機制,將需要動態配置的gpio在內核態寫死
完