ここに RasPI な GPIO のドライバがあると見て git clone してみました。ありますね。何故か driver 配下ではなくて arch/arm/mach-bcm2708/bcm2708_gpio.c な模様。
とり急ぎではありますが諸々確認を。
とりあえず、掘削起点のあたりなコードが以下らしい。
{% gist 7049fa8fe52a6138a4c8 %}
ドライバが insmod された時に呼び出されるのが bcm2708_gpio_init でデバイスが見つかった時に呼び出されるのが bcm2708_gpio_probe ということでこのあたりから掘削開始。
その前に、struct platform_driver 型から確認しといた方が良いのかどうか。定義は include/linux/platform_device.h で以下。
{% gist 773c8b6799b98173e4d6 %}
中の struct device_driver 型に簡単にアクセスできるマクロも定義されてますね。では掘っていきます。
- platform_driver_register はマクロで __platform_driver_register を呼び出す形に置き換え
- __platform_driver_register は drivers/base/platform.c で定義されてます
- register a driver for platform-level devices とのこと
で、_platform_driver_register ですが、probe, remove, shutdown に関数ポインタが設定されてる場合、driver 属性のそれぞれの属性に platform_drv* を設定して driver_register の戻りを戻す形になってます。
{% gist e6e24b0b5ff97479ab0f %}
とりあえず platform_drv_probe は確認してみます。定義は同じく driver/base/platform.c です。引用略。ACPI_HANDLE 云々は必要があれば別途確認の方向。struct platform_driver オブジェクトを取得してその probe を呼び出しています。
driver_register 手続き
細かい部分はスルーして
- driver_find 手続きで既に load 済みかどうかを確認
- bus_add_driver 手続き呼び出し
- driver_add_groups 手続き呼び出し
- kobject_uevent 手続き呼び出し
というカンジなのかどうか。と言いつつ詳細な確認は別途にした方が良いのかどうか。ざっくりは見とくべきなのかな。
と思ったら driver_add_groups で sysfs_create_groups を呼び出しているのを発見。もしかして bus_add_driver で drv->groups について何かをしてるのかな。
と、思ったら bus_add_driver から呼び出されている driver_add_groups からも sysfs_create_groups が呼び出されている模様。やっぱちゃんと見ないと駄目なのかorz
とりあえず driver_register 手続き呼び出しにより sysfs にかなり色々な形で影響が発生しているようですね。
と、言いつつ一旦このあたりスルーします。大丈夫かな。driver が登録された時点で sysfs に影響があるのは当たり前ですが、現時点でどうなるか、をきちんと理解できていないのでそのあたりの確認を踏まえて再度確認の方向ということで。
bcm2708_gpio_probe
かなり無理矢理ですが probe な実装をいきなり確認。その前に struct bcm2708_gpio 型の定義が以下ですね。
{% gist 57fb98b6ae5d3ca12257 %}
struct gpio_chip って何かな。GPIO コントローラの抽象型らしい。あ、ここに例の sysfs な i/f に関連する手続きポインタがありますね。成程。
手順としては
- struct bcm2708_gpio な領域確保
- platform_get_resource 手続き呼び出し
- platform_set_drvdata 手続き呼び出し
- struct bcm2708_gpio オブジェクトの初期設定
- bcm2708_gpio_irq_init 手続き呼び出し
- gpiochip_add 手続き呼び出し
となってます。
昨晩突発イベント発生により
今日はあまり何もできず。ここ継続で明日以降も掘削続けます。