로그에서 이것을 찾았습니다.
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 메서드는 오류를 반환하지 않지만 보고되는 행 수는 분명히 0입니다.
이 함수는 일부 메모리를 할당하고 제어를 위해 GPIO 라인을 등록하기 위해 Linux GPIO 하위 시스템에 필요한 구조를 구축하기 시작합니다. 이 작업이 완료되면 devm_gpiochip_add_data()
GPIO 하위 시스템의 기능을 호출하여 새 GPIO 칩을 등록합니다. 하지만 GPIO 하위 시스템은 일부 온전성 검사를 수행하고 이러한 구조가 실제로 라인을 제어해야 하는 칩에 0개의 GPIO를 지정한다는 사실을 알아냅니다.
~에 따르면Elixir.bootlin.com Linux 커널 상호 참조자는 마지막 두 매개변수가 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 라인 번호"와 같이 미묘하게 다른 것을 의미하는 경우에는 어떻게 될까요?(예: 값 0은 "GPIO 라인 #0이 하나만 있고 다른 라인은 없음"을 의미함) , dio_number
값을 사용하면 bank->chip.ngpio
1씩 오류가 발생하고 모듈은 이 GPIO WMI API를 사용하는 모든 시스템에서 마지막으로 제어 가능한 GPIO 라인을 놓치게 됩니다.
따라서 어느 쪽이든 해결해야 할 몇 가지 사항이 있습니다.
답변2
USB 스틱에서 Xubuntu 20.04를 설치하려고 할 때 이와 동일한 오류 메시지가 표시되었습니다. 저는 ASUS ROG STRIX R550-F 마더보드에서 Ryzen 5600X를 사용하고 있습니다. 문제는 nVidia 그래픽 카드에 있습니다. "안전한 그래픽" 옵션을 선택하면 실행되었습니다.