1. 程式人生 > >platform 平臺匯流排驅動

platform 平臺匯流排驅動

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;
}