Linux 2.6下的新的驱动管理机制:Platform_device

来源:互联网 发布:麻将胡牌算法 百搭 编辑:程序博客网 时间:2024/05/17 23:25

 (1)       首先需要定义一个驱动设备的资源信息:

struct platform_device {  const char * name; u32  id; struct device dev; u32  num_resources; struct resource * resource; }; struct resource {       resource_size_t start;       resource_size_t end;       const char *name;       unsigned long flags;       struct resource *parent, *sibling, *child;}; 

 

例如定义at91网络设备:

static struct resource eth_resources[] = {       [0] = {              .start       = AT91SAM9260_BASE_EMAC,              .end = AT91SAM9260_BASE_EMAC + SZ_16K - 1,              .flags      = IORESOURCE_MEM,       },       [1] = {              .start       = AT91SAM9260_ID_EMAC,              .end = AT91SAM9260_ID_EMAC,              .flags      = IORESOURCE_IRQ,       },}; static struct platform_device at91sam9260_eth_device = {       .name             = "macb",       .id          = -1,       .dev        = {                            .dma_mask            = ð_dmamask,                            .coherent_dma_mask     = DMA_BIT_MASK(32),                            .platform_data              = ð_data,       },       .resource = eth_resources,       .num_resources      = ARRAY_SIZE(eth_resources),};

这里定义了IORESOURCE_MEM(IO地址范围)和IORESOURCE_IRQ(中断号)两个资源。这两个资源可以通过调用platform_get_resource和platform_get_irq获取,如:

/* Get I/O base address and IRQ */       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);//res是指向struct resource结构的指针。 irq = platform_get_irq(pdev, 0);//irq即是中断号。 //注:platform_get_resource和platform_get_irq的第二个参数是资源的序号。


(2)       添加Platform_device到驱动:

platform_device_register(&at91sam9260_eth_device);

 

(3)       定义Platform_driver

static struct platform_driver at91ether_driver = {       .probe            = at91ether_probe,       .remove          = __devexit_p(at91ether_remove),       .suspend  = at91ether_suspend,       .resume          = at91ether_resume,       .driver            = {              .name      = DRV_NAME,              .owner    = THIS_MODULE,       },};

这里指定的DRV_NAME必须和platform_device结构中的name一致,否则不能找到驱动。

(4)       注册platform_driver

static int __init at91ether_init(void){       return platform_driver_register(&at91ether_driver);} static void __exit at91ether_exit(void){       platform_driver_unregister(&at91ether_driver);} module_init(at91ether_init)module_exit(at91ether_exit)

platform_driver_register成功执行后将执行at91ether_probe。

 

(5)       在at91ether_probe中做驱动的初始化工作。如在at91的mac驱动中初始化一个net_device并调用register_netdev(dev):

static const struct net_device_ops at91ether_netdev_ops = {       .ndo_open             = at91ether_open,       .ndo_stop              = at91ether_close,       .ndo_start_xmit             = at91ether_start_xmit,       .ndo_get_stats        = at91ether_stats,       .ndo_set_multicast_list   = at91ether_set_multicast_list,       .ndo_set_mac_address    = set_mac_address,       .ndo_do_ioctl         = at91ether_ioctl,       .ndo_validate_addr = eth_validate_addr,       .ndo_change_mtu          = eth_change_mtu,#ifdef CONFIG_NET_POLL_CONTROLLER       .ndo_poll_controller      = at91ether_poll_controller,#endif};  static int __init at91ether_setup( …{       struct net_device *dev;       …       ether_setup(dev);       dev->netdev_ops = &at91ether_netdev_ops;              /* Register the network interface */       ret = register_netdev(dev);       …}


 

 

原创粉丝点击