platform 设备
drivers/base/platform.c 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);
1. 前提
目前我们都用设备树,并解析设备树并创建设备贺电,这样子得到的 pdev->name 为设备节点名
pdev->driver_override 为 NULL
2. 5种匹配方式
2.1
pdev->driver_override
2.2
OF
2.3
ACPI
2.4
pdrv->id_table
platform_match_id(pdrv->id_table, pdev)
2.5
(strcmp(pdev->name, drv->name)
2.2 举例
static const struct of_device_id ids[] = {
{ .compatible = "chip-name"},
{ .compatible = "chip-name2"},
{ },
};
struct platform_driver pdr =
{
.driver=
{
.name = "somethingSUIBIAN_BUT_MUST_HAVE",
.of_match_table = ids,
}
.id_table = &p_id_table,
.probe = pdr_probe,
.remove = pdr_remove,
}
platform_driver_register(&pdr);
node-platform-node {
compatible = "vendor-name", "chip-name", "chip-name2","chip-name3";
}
2.4 举例
static const struct platform_device_id p_id_table = {
.name = "node-platform-node",
};
struct platform_driver pdr =
{
.driver=
{
.name = "somethingSUIBIAN_BUT_MUST_HAVE",
}
.id_table = &p_id_table,
.probe = pdr_probe,
.remove = pdr_remove,
}
platform_driver_register(&pdr);
node-platform-node {
compatible = "somethingSUIBIAN_BUT_MUST_HAVE";
}
2.5 举例
static const struct platform_device_id p_id_table = {
.name = "node-platform-node",
};
struct platform_driver pdr =
{
.driver=
{
.name = "node-platform-node",
}
.probe = pdr_probe,
.remove = pdr_remove,
}
platform_driver_register(&pdr);
node-platform-node {
compatible = "somethingSUIBIAN_BUT_MUST_HAVE";
}
chosen {
bootargs = "node-platform-file.num=100"
};
node-platform-file.c 文件中
static int num=10;
module_param(num,int,S_IRUGO);
kernel/params.c
parse_one
params[i].ops->set(val, ¶ms[i]);
driver 目录
/sys/bus/platform/drivers/xxx
/sys/devices/platform/yyy
sysfs_create_group(&pdev->dev.kobj, &sysfs_demo_attr_group)
从pdev 到 其他
int pdr_probe(struct platform_device * pdev);
获取 dev :pdev->dev
获取 设备树节点 : pdev->dev.of_node
获取驱动 : pdev->dev->driver
从 dev 到其他
struct platform_device *pdev = to_platform_device(dev);
从 drv 到其他
struct platform_driver *pdrv = to_platform_driver(drv);
int pdr_probe(struct platform_device * pdev);
name:node-platform-node
id:-1
id_auto:0
num_resources:1
resources:9f59f240
id_entry: (null)
driver_override: (null)
/sys/bus/platform/drivers/xxx #
--w------- 1 0 0 4096 Apr 20 10:30 bind
lrwxrwxrwx 1 0 0 0 Apr 20 10:30 yyy -> ../../../../devices/platform/yyy
--w------- 1 0 0 4096 Apr 20 10:30 uevent
--w------- 1 0 0 4096 Apr 20 10:30 unbind
/sys/devices/platform/yyy/:
total 0
lrwxrwxrwx 1 0 0 0 Apr 20 10:30 driver -> ../../../bus/platform/drivers/xxx
-rw-r--r-- 1 0 0 4096 Apr 20 10:30 driver_override
-r--r--r-- 1 0 0 4096 Apr 20 10:30 modalias
-rw-r--r-- 1 0 0 4096 Apr 20 10:30 node_one
-r--r--r-- 1 0 0 4096 Apr 20 10:30 node_two
drwxr-xr-x 2 0 0 0 Apr 20 10:30 power
lrwxrwxrwx 1 0 0 0 Apr 20 10:30 subsystem -> ../../../bus/platform
-rw-r--r-- 1 0 0 4096 Apr 20 10:30 uevent
/sys/devices/platform/yyy/power:
total 0
-rw-r--r-- 1 0 0 4096 Apr 20 10:31 autosuspend_delay_ms
-rw-r--r-- 1 0 0 4096 Apr 20 10:31 control
-r--r--r-- 1 0 0 4096 Apr 20 10:31 runtime_active_time
-r--r--r-- 1 0 0 4096 Apr 20 10:31 runtime_status
-r--r--r-- 1 0 0 4096 Apr 20 10:31 runtime_suspended_time
/sys/bus/platform/drivers/xxx 下面有 bind yyy unbind 表示已经匹配成功
可以通过 echo yyy > unbind 来卸载驱动
然后再 echo yyy > bind 来加载驱动
如果没有什么问题(不会有错误堆栈打出来,不会死机),基本上去初始化是ok的
s2mps11_clks->pdev = pdev;
struct platform_device * pdev = s2mps11_clks->pdev
---
platform_set_drvdata(pdev, s2mps11_clks);
struct s2mps11_clk *s2mps11_clks = platform_get_drvdata(pdev);