嵌入式linux驱动开发--驱动设备注册资源(非设备树方式)

本章在以NUC972为平台的Linux3.10.1中添加设备驱动。
platform总线是linux中一种虚拟、抽象出来的总线,它将设备和驱动绑定。platform工作体系都定义在drivers/base/platform.c中,其有两个结构体:platform_device和platform_driver

platform_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 (*suspend_late)(struct platform_device *, pm_message_t state);
    int (*resume_early)(struct platform_device *);
    int (*resume)(struct platform_device *);//恢复函数,在开机时被调用
    struct device_driver driver;//设备驱动结构
};

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

    struct kobject      kobj;
    struct klist        klist_devices;
    struct klist_node   knode_bus;

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

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

platform_device

struct platform_device {
    const char  * name;//设备名称
    u32     id;//取-1
    struct device   dev;//设备结构      
    u32     num_resources;// resource结构个数   
    struct resource * resource;//设备资源
};

了解了上面两个结构体,然后开始修改dev.c文件,这里是基于nuc972平台,在目录linux-3.10.x/arch/arm/mach-nuc970下,这里以KSZ8851芯片为例:
首先这里定义KSZ8851的EBI总线的nCS4基地址(KSZ8851_16MLL_BASE_ADDR),[0] 和[1] 分别是读写数据和地址访问的访问地址,这里(.start = KSZ8851_16MLL_BASE_ADDR+4)为什么加4?因为ksz8851的CMD线接到了EBI总线的ADDR2上,当CMD为高为写命令,CMD为低为写数据,然后对总线写地址时候保证bit2(EBI的ADDR2地址线)为1,那么ADDR2地址线为高,此时写的是命令,bit2为0则ADDR2地址线为为低电平,此时写的是数据,因此bit2对应0x4。

每一个resource都有.start,.end和.flags ,用于表示该资源的起始地址,末地址和类型,struct platform_device中name用于和driver进行匹配,name需要和驱动层中name相同,当匹配后将执行probe函数。

#ifdef CONFIG_KS8851_MLL

#define KSZ8851_16MLL_BASE_ADDR			0x20100000		//512K cs4  adrress--data_access

static struct resource nuc970_ksz8851_resource[] = {
        [0] = {
                .start = KSZ8851_16MLL_BASE_ADDR,		//data_access
                .end   = KSZ8851_16MLL_BASE_ADDR+3,
                .flags = IORESOURCE_MEM,
        },
        [1] = {
                .start = KSZ8851_16MLL_BASE_ADDR+4,		//address_access
                .end   = KSZ8851_16MLL_BASE_ADDR+7,
                .flags = IORESOURCE_MEM,
        },
        [2] = {
                .start = IRQ_EXT7_H7,		//PH7-INT7
                .end   = IRQ_EXT7_H7,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
        },
};

struct platform_device nuc970_device_ksz8851 = {
        .name           = "ks8851_mll",
        .id             = -1,
        .num_resources  = ARRAY_SIZE(nuc970_ksz8851_resource),
        .resource       = nuc970_ksz8851_resource,
};
#endif

最后在static struct platform_device *nuc970_public_dev[] __initdata中注册设备

#ifdef CONFIG_KS8851_MLL
    &nuc970_device_ksz8851,
#endif

void __init nuc970_platform_init(struct platform_device **device, int size)函数会调用platform_add_devices(nuc970_public_dev, ARRAY_SIZE(nuc970_public_dev));来进行设备注册

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值