Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2601313
  • 博文数量: 333
  • 博客积分: 4817
  • 博客等级: 上校
  • 技术积分: 4413
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-28 10:51
文章分类

全部博文(333)

文章存档

2017年(20)

2016年(57)

2015年(27)

2014年(20)

2013年(21)

2012年(164)

2011年(24)

分类: LINUX

2012-03-16 08:14:05


struct device_driver {
    const char        *name;
    struct bus_type        *bus;

    struct module        *owner;
    const char        *mod_name;    /* used for built-in modules */

    bool suppress_bind_attrs;    /* disables bind/unbind via sysfs */

    int (*probe) (struct device *dev);
    int (*remove) (struct device *dev);
    void (*shutdown) (struct device *dev);
    int (*suspend) (struct device *dev, pm_message_t state);
    int (*resume) (struct device *dev);
    const struct attribute_group **groups;

    const struct dev_pm_ops *pm;

    struct driver_private *p;
};


struct driver_private {
    struct kobject kobj;
    struct klist klist_devices;
    struct klist_node knode_bus;
    struct module_kobject *mkobj;
    struct device_driver *driver;
};


struct platform_driver {           // 驱动程序结构的嵌入
    int (*probe)(struct platform_device *);
    int (*remove)(struct platform_device *);
    void (*shutdown)(struct platform_device *);
    int (*suspend)(struct platform_device *, pm_message_t state);
    int (*resume)(struct platform_device *);
    struct device_driver driver;
    struct platform_device_id *id_table;
};


static struct platform_driver dm9000_driver = {
    .driver    = {
        .name    = "dm9000",
        .owner     = THIS_MODULE,
        .pm     = &dm9000_drv_pm_ops,
    },
    .probe   = dm9000_probe,
    .remove  = __devexit_p(dm9000_drv_remove),
};


static int __init dm9000_init(void)
{
#if defined(CONFIG_ARCH_S3C2410)
    unsigned int oldval_bwscon = *(volatile unsigned int *)S3C2410_BWSCON;
    unsigned int oldval_bankcon4 = *(volatile unsigned int *)S3C2410_BANKCON4;
     *((volatile unsigned int *)S3C2410_BWSCON) =
       (oldval_bwscon & ~(3<<16)) | S3C2410_BWSCON_DW4_16 | S3C2410_BWSCON_WS4 | S3C2410_BWSCON_ST4;
     *((volatile unsigned int *)S3C2410_BANKCON4) = 0x1f7c;
#endif

    printk(KERN_INFO "%s Ethernet Driver, V%s\n", CARDNAME, DRV_VERSION);

    return platform_driver_register(&dm9000_driver);
}


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);// 注册device_driver
}
EXPORT_SYMBOL_GPL(platform_driver_register);


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


int driver_register(struct device_driver *drv)
{
    int ret;
    struct device_driver *other;

    BUG_ON(!drv->bus->p);

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

    other = driver_find(drv->name, drv->bus);
    if (other) {
        put_driver(other);
        printk(KERN_ERR "Error: Driver '%s' is already registered, "
            "aborting...\n", drv->name);
        return -EBUSY;
    }

    ret = bus_add_driver(drv);
    if (ret)
        return ret;
    ret = driver_add_groups(drv, drv->groups);
    if (ret)
        bus_remove_driver(drv);
    return ret;
}
EXPORT_SYMBOL_GPL(driver_register);





阅读(1314) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~