platform 平臺匯流排驅動
阿新 • • 發佈:2019-02-10
platform平臺匯流排是為了將較為穩定的程式碼與具體的硬體 相關的會變得程式碼分開
其下有兩個部分platform_driver_register與platform_device_register
1.platform.c
int platform_driver_register(struct platform_driver *drv) { drv->driver.bus = &platform_bus_type; if (drv->probe) drv->driver.probe = platform_drv_probe; //將driver的probe函式賦給匯流排的probe函式 if (drv->remove) drv->driver.remove = platform_drv_remove; if (drv->shutdown) drv->driver.shutdown = platform_drv_shutdown; if (drv->suspend) drv->driver.suspend = platform_drv_suspend; if (drv->resume) drv->driver.resume = platform_drv_resume; return driver_register(&drv->driver); }
int driver_register(struct device_driver * drv) { if ((drv->bus->probe && drv->probe) || (drv->bus->remove && drv->remove) || (drv->bus->shutdown && drv->shutdown)) { printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods\n", drv->name); } klist_init(&drv->klist_devices, NULL, NULL); return bus_add_driver(drv); //bus匯流排裡,實現driver與device的匹配工作 }
int platform_device_register(struct platform_device * pdev)
{
device_initialize(&pdev->dev);
return platform_device_add(pdev);
}
2.device部分
static int led_dev_init(void)
{
platform_device_register(&led_dev);
return 0;
}
static struct platform_device led_dev = { .name = "myled", //driver中name與此相同時,則會相互匹配,呼叫driver中的probe函式 .id = -1, .num_resources = ARRAY_SIZE(led_resource), .resource = led_resource, //resource可以提供硬體的具體引數,handler可以根據此進行具體的硬體設定 .dev = { .release = led_release, }, };
static struct resource led_resource[] = {
[0] = {
.start = 0x56000050,
.end = 0x56000050 + 8 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 5,
.end = 5,
.flags = IORESOURCE_IRQ,
}
};
3.driver部分
static int led_drv_init(void)
{
platform_driver_register(&led_drv);
return 0;
}
struct platform_driver led_drv = {
.probe = led_probe, //有name相同的device出現時,呼叫probe函式
.remove = led_remove,
.driver = {
.name = "myled",
}
};
static int led_probe(struct platform_device *pdev)
{
struct resource *res;
/* 根據platform_device的資源進行ioremap */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
gpio_con = ioremap(res->start, res->end - res->start + 1);
gpio_dat = gpio_con + 1;
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
pin = res->start;
/* 註冊字元裝置驅動程式 */
printk("led_probe, found led\n");
major = register_chrdev(0, "myled", &led_fops);
cls = class_create(THIS_MODULE, "myled");
class_device_create(cls, NULL, MKDEV(major, 0), NULL, "led"); /* /dev/led */
return 0;
}