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

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

       …

}


 

 

你可能感兴趣的:(Linux 2.6下的新的驱动管理机制:Platform_device)