i 2 cサブシステムのplatform_driver初期化——i 2 c_adap_s3c_init()
完了platform_デバイスの追加後、i 2 cサブシステムはplatform_を行うdriverの登録プロセス.
platform_driverの登録は初期化関数i 2 cを呼び出すことによってadapter_s3c_义齿
数えて完成する.
i2c_adap_s3c_Init()関数体は次のとおりです.
s3c24xx_i2c_driverの仕事.s3c24xx_i2c_driverは以下の通りです.
platform_driverはplatformに登録しています.busバスの中で登録したplatformを試します.driver
platformに登録済みbus上のすべてのplatform_デバイスをペアリングします.
platform_busバスの関連操作は以下の通りです.
ペアリングプロセスは、バスを呼び出すmatchメソッド、すなわちplatform_によって実現される.match関数.次のようになります.
ここでplatfor_に基づいてデバイスとplatform_driverの名前でペアリングを実現します.でもplatform_driverにはいくつかの名前があります
選択可能、id_経由ペアを実現するためにtableを使用します.ここに実行され、platformに登録されています.busのplatform_device
型デバイスs 3 c_devicei 2 c 0とplatformに登録したばかりです.busバスのplatfor_drver型駆動s 3 c 24 xx_i2c_ドライブ将
ペアリングに成功しました.
ペアリングに成功したらprobeを試します
ドライバのprobe、すなわちplatform_を呼び出すdriver.drv->probe、platform_bus自体はprobeメソッドを初期化していません.
ここではドライバのprobeメソッドを呼び出し、ドライバのprobeは登録中に初期化されています.
このドライバを呼び出すprobeメソッド、すなわちs 3 c 24 xx_i2c_probe関数.
probe関数の機能は以下の通りです.
1.まずstruct s 3 c 24 xx_を作成するi2c *i2c.
i 2 c関連データの初期化はs 3 c 2_に由来するdevice_i2c0.dev.platdata.
2.i 2 c->adap.algo = &s3c24xx_i2c_algorithm;algoメソッドを初期化します.
writeシステム呼び出し時にs 3 c 24 x_に呼び出されますi2c_Algorithm関数.
3.init_waitqueue_head(&i2c->wait); 待機キューの初期化
4.s3c24xx_i2c_init (i2c);i 2 cコントローラを初期化し、主にs 3 c 24 xxに対するi 2 c制御
レジスタは、s 3 c 2440 i/o機能の構成、スレーブアドレスの設定、および
i 2 cクロック周波数などの関連動作を設定します.クロック周波数の設定については、ブログを参照してください.
5.request_irq(i2c->irq, s3c24xx_i2c_irq, IRQF_DISABLED, dev_name(&pdev->dev), i2c); 申請は中断して、カーネルの中のi 2 cの読み書きは中断することによって実現して、具体的には後で分析します
6.i2c_add_numbered_adapter(&i2c->adap);最後にi 2 c adapterをシステムに登録
ここでは第2、5、6点に注意する必要があります.
次に6点目を分析します.2、5時以降にat 24 c 02を読み書きするときに分析します.
platform_driverの登録は初期化関数i 2 cを呼び出すことによってadapter_s3c_义齿
数えて完成する.
i2c_adap_s3c_Init()関数体は次のとおりです.
static int __init i2c_adap_s3c_init(void)
{
return platform_driver_register(&s3c24xx_i2c_driver);
}
platform_driver_register(&s 3 c 24 xx_i 2 c_driver)、platform_への完了busバス登録platform_driverタイプドライバs3c24xx_i2c_driverの仕事.s3c24xx_i2c_driverは以下の通りです.
static struct platform_driver s3c24xx_i2c_driver = {
.probe = s3c24xx_i2c_probe,
.remove = s3c24xx_i2c_remove,
.id_table = s3c24xx_driver_ids,
.driver = {
.owner = THIS_MODULE,
.name = "s3c-i2c",
.pm = S3C24XX_DEV_PM_OPS,
},
};
id_tableはs 3 c 24 xx_に初期化されるdriver_ids: static struct platform_device_id s3c24xx_driver_ids[] = {
{
.name = "s3c2410-i2c",
.driver_data = TYPE_S3C2410,
}, {
.name = "s3c2440-i2c",
.driver_data = TYPE_S3C2440,
}, { },
};
platform_driverはplatformに登録しています.busバスの中で登録したplatformを試します.driver
platformに登録済みbus上のすべてのplatform_デバイスをペアリングします.
platform_busバスの関連操作は以下の通りです.
struct bus_type platform_bus_type = {
.name = "platform",
.dev_attrs = platform_dev_attrs,
.match = platform_match,
.uevent = platform_uevent,
.pm = &platform_dev_pm_ops,
};
ペアリングプロセスは、バスを呼び出すmatchメソッド、すなわちplatform_によって実現される.match関数.次のようになります.
static int platform_match(struct device *dev, struct device_driver *drv)
{
struct platform_device *pdev = to_platform_device(dev);
struct platform_driver *pdrv = to_platform_driver(drv);
/* Attempt an OF style match first */
if (of_driver_match_device(dev, drv))
return 1;
/* Then try to match against the id table */
if (pdrv->id_table)
return platform_match_id(pdrv->id_table, pdev) != NULL;
/* fall-back to driver name match */
return (strcmp(pdev->name, drv->name) == 0);
}
関数にif (pdrv->id_table)
return platform_match_id(pdrv->id_table, pdev) != NULL;
関連文.ここでplatfor_に基づいてデバイスとplatform_driverの名前でペアリングを実現します.でもplatform_driverにはいくつかの名前があります
選択可能、id_経由ペアを実現するためにtableを使用します.ここに実行され、platformに登録されています.busのplatform_device
型デバイスs 3 c_devicei 2 c 0とplatformに登録したばかりです.busバスのplatfor_drver型駆動s 3 c 24 xx_i2c_ドライブ将
ペアリングに成功しました.
ペアリングに成功したらprobeを試します
static int really_probe(struct device *dev, struct device_driver *drv)
{
。。。 。。。
if (dev->bus->probe) {
ret = dev->bus->probe(dev);
if (ret)
goto probe_failed;
} else if (drv->probe) {
ret = drv->probe(dev);
if (ret)
goto probe_failed;
}
。。。 。。。
}
上記のコードから分かるように、ペアリングに成功した後にまず呼び出されるのはバスのprobeであり、バスがprobeメソッドを初期化していない場合にのみ行われる.ドライバのprobe、すなわちplatform_を呼び出すdriver.drv->probe、platform_bus自体はprobeメソッドを初期化していません.
ここではドライバのprobeメソッドを呼び出し、ドライバのprobeは登録中に初期化されています.
int platform_driver_register(struct platform_driver *drv)
{
drv->driver.bus = &platform_bus_type;
if (drv->probe)
drv->driver.probe = platform_drv_probe;
if (drv->remove)
drv->driver.remove = platform_drv_remove;
if (drv->shutdown)
drv->driver.shutdown = platform_drv_shutdown;
return driver_register(&drv->driver);
}
直接呼び出し関数platform_drv_probe、関数は以下の通りです.static int platform_drv_probe(struct device *_dev)
{
struct platform_driver *drv = to_platform_driver(_dev->driver);
struct platform_device *dev = to_platform_device(_dev);
return drv->probe(dev);
}
関数の動作は簡単です.dev->driverそれを含むplatformを見つけます.driver型駆動、そしてこのドライバを呼び出すprobeメソッド、すなわちs 3 c 24 xx_i2c_probe関数.
probe関数の機能は以下の通りです.
1.まずstruct s 3 c 24 xx_を作成するi2c *i2c.
i 2 c関連データの初期化はs 3 c 2_に由来するdevice_i2c0.dev.platdata.
2.i 2 c->adap.algo = &s3c24xx_i2c_algorithm;algoメソッドを初期化します.
writeシステム呼び出し時にs 3 c 24 x_に呼び出されますi2c_Algorithm関数.
3.init_waitqueue_head(&i2c->wait); 待機キューの初期化
4.s3c24xx_i2c_init (i2c);i 2 cコントローラを初期化し、主にs 3 c 24 xxに対するi 2 c制御
レジスタは、s 3 c 2440 i/o機能の構成、スレーブアドレスの設定、および
i 2 cクロック周波数などの関連動作を設定します.クロック周波数の設定については、ブログを参照してください.
5.request_irq(i2c->irq, s3c24xx_i2c_irq, IRQF_DISABLED, dev_name(&pdev->dev), i2c); 申請は中断して、カーネルの中のi 2 cの読み書きは中断することによって実現して、具体的には後で分析します
6.i2c_add_numbered_adapter(&i2c->adap);最後にi 2 c adapterをシステムに登録
ここでは第2、5、6点に注意する必要があります.
次に6点目を分析します.2、5時以降にat 24 c 02を読み書きするときに分析します.