636 (LK) 驱动模型实例

/* 
 * my_platform_device.c
 */ 
#include <linux/module.h> 
#include <linux/platform_device.h>

#define DEV_NAME    "my_pltdev"
#define DVR_NAME    "my_pltdev"

static const char *mydata = "ldm";
static struct platform_device *mypltdev;

static int mypltdev_probe(struct platform_device *pdev)
{
    if (pdev->dev.platform_data)
        pr_info("in mypltdev-%d probe, private platform data is %s\n",
                pdev->dev.id, *(const char **)pdev->dev.platform_data);
    return 0;
}

static struct platform_driver mypltdev_driver = { 
    .driver = { 
        .name   = DVR_NAME,
        .owner  = THIS_MODULE,
    },  
    .probe = mypltdev_probe,
};

static void set_private_data(struct platform_device *pdev)
{
    pdev->dev.platform_data = &mydata;
}

static int __init mymodule_init(void) 
{
    int ret;
    pr_info("mymodule init\n"); 
    mypltdev = platform_device_alloc(DEV_NAME, 0); 
    if (mypltdev == NULL) {
        pr_info("Failed to alloc device\n");
        goto err;
    }   
    ret = platform_device_add(mypltdev);
    if (ret != 0) {
        pr_info("Failed to add device\n");
        goto err;
    }
    set_private_data(mypltdev);
    ret = platform_driver_register(&mypltdev_driver);
    if (ret != 0) {
        pr_info("Failed to register %s\n", DVR_NAME);
        goto err_del_dev;
    }
    pr_info("mypltdev at %p(%lu), assert to be less than %lu\n",
            (void *)mypltdev, (unsigned long)(void *)mypltdev, (unsigned long)-4095);
    return 0;

err_del_dev:
    platform_device_del(mypltdev);
err:
    pr_info("mymodule init failed\n");
    return -1;
}

static void __exit mymodule_exit(void)
{
    pr_info("mymodule exit\n");
    platform_driver_unregister(&mypltdev_driver);
    platform_device_del(mypltdev);
}

module_init(mymodule_init);
module_exit(mymodule_exit);

MODULE_LICENSE("GPL");