gpio gpiochip0カーネルエラーとは何を意味し、どのように解決しますか?

gpio gpiochip0カーネルエラーとは何を意味し、どのように解決しますか?

ログでこれを見つけました。

kernel: gpio gpiochip0: (gpio_aaeon): tried to insert a GPIO chip with zero lines
kernel: gpiochip_add_data_with_key: GPIOs 0..-1 (gpio_aaeon) failed to register, -22
kernel: gpio-aaeon: probe of gpio-aaeon.0 failed with error -22

これは何を意味し、どのように解決すべきですか?

lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 21.04
Release:        21.04
Codename:       hirsute

ベストアンサー1

これらのメッセージはカーネル汎用I / Oコードによって生成され、明らかにこのパッチまたはより成熟したパッチ

簡潔なバージョン:

モジュールは探していたWMIプログラミングインターフェイスを見つけましたが、インターフェイスがハードウェアに制御可能なGPIOラインを報告していないことを無視しました。登録試行を中止し、-ENODEVエラーコードでモジュールのインストールを拒否する必要があります。モジュールをブラックリストに追加してメッセージを削除できます。たとえば、次の内容をgpio-aaeon含むファイルを作成します。/etc/modprobe.d/no-aaeon-gpio-here.conf

blacklist gpio-aaeon

このカーネルモジュールでバグが見つかりました。Linux GPIO開発者に報告。あなたのハードウェアは、gpio_aaeon開発者が明らかに考慮していないモジュールテストのための興味深い「最先端のケース」を提供するようです。モジュールはかなり新しいように見えるので、これは理解できます。上記のリンクされたパッチは今年5月末にリリースされました。


長いバージョン:

GPIOサブシステムは、gpio_aaeonモジュールが実際に制御する汎用I / Oラインがないチップを登録しようとしたため、そのようなチップをGPIOサブシステムに登録する意味がないと不平を言いました。

登録はモジュールのプローブ機能で発生します。

+static int __init aaeon_gpio_probe(struct platform_device *pdev)
+{
+   int err, i;
+   int dio_number = 0;
+   struct aaeon_gpio_data *data;
+   struct aaeon_gpio_bank *bank;
+
+   /* Prevent other drivers adding this platfom device */
+   if (!wmi_has_guid(AAEON_WMI_MGMT_GUID)) {
+       pr_debug("AAEON Management GUID not found\n");
+       return -ENODEV;
+   }
+
+   dio_number = aaeon_gpio_get_number();
+   if (dio_number < 0)
+       return -ENODEV;
+
+   data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+   if (!data)
+       return -ENOMEM;
+
+   data->nr_bank = ARRAY_SIZE(aaeon_gpio_bank);
+   data->bank = aaeon_gpio_bank;
+   platform_set_drvdata(pdev, data);
+   bank = &data->bank[0];
+   bank->chip.parent = &pdev->dev;
+   bank->chip.ngpio = dio_number;
+   bank->data = data;
+   err = devm_gpiochip_add_data(&pdev->dev, &bank->chip, bank);
+   if (err)
+       pr_debug("Failed to register gpiochip %d: %d\n", i, err);
+
+   return err;
+}

モジュールをロードしようとすると単にエラーで終わるわけではないので、-ENODEVシステムにはドライバが探しているWMI管理APIが明らかにあります。しかし、クエリを行うと、APIは実際に制御する項目がないと言います。

つまり、モジュールは引き続き呼び出しを実行しdio_number = aaeon_gpio_get_number();、最終的にWMIメソッドを呼び出して単一の整数を取得できます。これは明らかにこのAPIを介して制御できるGPIOラインの数です。 WMIメソッドはエラーを返しませんが、報告される行数は明らかにゼロです。

この関数は、いくつかのメモリを割り当て、制御のためにGPIOラインを登録するためにLinux GPIOサブシステムに必要な構造を構築し始めます。これが完了したら、devm_gpiochip_add_data()GPIOサブシステムの機能を呼び出して新しいGPIOチップを登録します。しかし、GPIOサブシステムはいくつかの健全性チェックを実行し、これらの構造が実際にラインを制御する必要があるチップにゼロ個のGPIOを割り当てることを理解しています。

~によるとElixir.bootlin.com Linuxカーネル相互参照は、最後の2つのパラメータがNULLの関数のみをdevm_gpiochip_add_data()呼び出すマクロです。devm_gpiochip_add_data_with_key()順番に、これは次のようにも知られています。gpiochip_add_data_with_key()機能、表示される最初のエラーメッセージが生成されます。628号線

関数呼び出しチェーンがデプロイされると、各関数は呼び出し元にエラーコードを返すため、追加のメッセージが続きます。

返された値がaaeon_gpio_get_number()実際にWMI APIが制御できるGPIO行の数である場合は、次をテストしてください。

+   if (dio_number < 0)
+       return -ENODEV;

実際には次のようになります。

+   if (dio_number < 1)
+       return -ENODEV;

しかし、WMI APIから返された数値が実際に「0から始まる最後の制御可能なGPIOライン番号」のように微妙に異なることを意味する場合はどうなりますか? 「はなし」を意味します)、dio_number値を使用するとbank->chip.ngpio1つずつエラーが発生し、モジュールはこのGPIO WMI APIを使用するすべてのシステムで最後に制御可能なGPIOラインを見逃します。

したがって、どちらにも対処すべきいくつかの点があります。

おすすめ記事