drivers/base/init.c から再度掘削着手。driver_init という手続きから platform_bus_init に向かって、というカンジです。
{% gist f10cad6ad9ed45e9f169 %}
なんとなくこれって /sys/bus/platform だったり /sys/drivers/platform だったりを、なのかどうか。device_register とか bus_register とかって名前てきにもそうであって欲しいなぁ。
リトライ
よくよく考えてみるに SoC なデバイスは platform_driver_regsiter 呼び出しときゃ OK なのかな、とも思いつつ掘削リトライ。
紆余曲折の挙句、以下な事が分かりました。おおよそ正しいはず。
- 起動時にどこかで platform_add_devices が呼び出される (はず)
- platform_device_register で bcm2708_gpio が登録
- 登録によって /sys/devices/platform/bcm2708_gpio ディレクトリが作成される
- device_add から kobject_add と device_create_file 呼び出し
- platform_driver_register 以降の処理で /sys/bus/platform/drivers/bcm2708_gpio ディレクトリが作成される
- driver_register -> bus_add_driver -> kobject_init_and_add
- こちらでは kobject_add ではなくて直接 create_dir している
- attribute に沿ってファイルも追加 (populate_dir 手続き)
- ここまでできてれば driver_attach 呼ばれても大丈夫
- driver_attach で相互リンクを作っている
- /sys/bus/platform/drivers/bcm2708_gpio/bcm2708_gpio
- /sys/devices/platform/bcm2708_gpio/driver
- probe で /sys/class/gpio/gpiochip0 を作っている (device_create の呼び出し)
あと、以下も確認をしておきたいと思います。
- /sys/class/gpio/{export, unexport} へのアクセスの記述確認
- そもそも /sys/class/gpio 配下のファイルはいつ作成されるのか
ということで確認してみます。まず、/sys/class 配下のファイルからですが gpiolib.c の gpiolib_sysfs_init 手続き確認します。gpio_class という変数を class_register という手続きに渡しています。
{% gist 0df8bc5c957e4664d6d0 %}
これ、/sys/class/gpio 配下の export と unexport なのが分かります。class_register から attribute に設定されてるのでファイルが作成されて手続きに紐が付くはず。
また、gpiolib_sysfs_init では struct gpio_chip なオブジェクトを gpiochip_export 手続きに渡しています。渡す struct gpio_chip オブジェクトは保持してるリストから順に取り出して、という形。
この手続きで /sys/class/gpio/gpiochip0 みたいなソレが作られるのか。ただ、ちょっと attr なファイルの根拠が分からない。
error = device_create_file(dev, &dev_attr_uevent);
ちょいここはスルーで。
export とか unexport とか
とりあえず export に番号を書き込んだ場合、export_store という手続きが呼びだされるはずです。gpiod_export という手続きが呼び出される模様。以下な手続き呼び出しな記述があります。
dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
desc, ioname ? ioname : "gpio%u",
desc_to_gpio(desc));
/sys/class/gpio/gpio0 みたいなディレクトリができて、その中に value とか direction とかなファイルが、というヤツですね。
渡している desc という変数は引数でして struct gpio_desc 型です。属性として struct gpio_chip 型ポインタの chip という属性を持っています。get とか set とか direction あたりを操作する手続きポインタを持っています。
おそらくは、なんですが device_create にこのオブジェクトを渡しているので driver core 方面から gpiod_export が呼び出される時にこれが渡されるのだろうなと。
で、device_create する時にこれを渡して value とか direction の操作に割り当てているのではないかと。
このあたり、詳細な部分を掘りきれていないので別途時間がある折に確認してみます。
つうか、そこが核心なのではないかとorz
それにしても gpiolib 凄いな。