加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

Linux内核-平台设备-platform

发布时间:2020-12-14 01:46:53 所属栏目:Linux 来源:网络整理
导读:一、注册一个平台设备 方法1:platform_device_register 核心数据结构: 1 struct platform_device { 2 const char * name; 3 int id; 4 bool id_auto; 5 struct device dev; 6 u32 num_resources; 7 struct resource * resource; 8 9 const struct platform

一、注册一个平台设备

  方法1:platform_device_register

  核心数据结构:

 1 struct platform_device {
 2     const char    *name;
 3     int        id;
 4     bool        id_auto;
 5     struct device    dev;
 6     u32        num_resources;
 7     struct resource    *resource;
 8 
 9     const struct platform_device_id    *id_entry;
10     char *driver_override; /* Driver name to force a match */
11 
12     /* MFD cell pointer */
13     struct mfd_cell *mfd_cell;
14 
15     /* arch specific additions */
16     struct pdev_archdata    archdata;
17 };
View Code

  核心接口

1 extern int platform_device_register(struct platform_device *);
View Code

  代码示例

static struct resource my_resoure1[]={
    {
        .start     = 0x00,.end    = 0x10,.name    = "resource1 MEM",.flags    = IORESOURCE_MEM,},{
        .start     = 0x11,.end    = 0x20,.name    = "resource2 MEM",{
        .start     = 5,.end    = 9,.name    = "resource3 IRQ",.flags    = IORESOURCE_IRQ,{
        .start     = 10,.end    = 15,.name    = "resource4 IRQ",};
static struct platform_device my_device1 = {
    .name           = "xym-test-platform-device-1",.id                = -1,.num_resources     = ARRAY_SIZE(my_resoure1),.resource         = my_resoure1,.dev = {
        .release = my_platform_device_release,//不注册此接口,卸载驱动时会报警告
        .platform_data = &platform_data_1,};
struct platform_device * p_device_1 = &my_device1;

//device 1
ret = platform_device_register(&my_device1);
if (ret) 
{
    printk(KERN_INFO"Unable to device 1 register(%d)n",ret);
    return ret;
}
View Code

  方法2:platform_device_register_full

  核心数据结构

 1 struct platform_device_info {
 2         struct device *parent;
 3         struct fwnode_handle *fwnode;
 4 
 5         const char *name;
 6         int id;
 7 
 8         const struct resource *res;
 9         unsigned int num_res;
10 
11         const void *data;
12         size_t size_data;
13         u64 dma_mask;
14 };
View Code

  核心接口

 1 extern struct platform_device *platform_device_register_full(const struct platform_device_info *pdevinfo);
 2 
 3 static inline struct platform_device *platform_device_register_simple(
 4         const char *name,int id, 5         const struct resource *res,unsigned int num)
 6 
 7 static inline struct platform_device *platform_device_register_resndata(
 8         struct device *parent,const char *name, 9         const struct resource *res,unsigned int num,10         const void *data,size_t size)
View Code

  代码示例

static struct resource my_resoure2[]={
    {
        .start     = 0x21,.end    = 0x30,{
        .start     = 0x31,.end    = 0x40,{
        .start     = 20,.end    = 30,{
        .start     = 40,.end    = 50,};

static struct platform_device_info my_device_2 = {
    .name           = "xym-test-platform-device-2",.num_res         = ARRAY_SIZE(my_resoure2),.res             = my_resoure2,.data            = &platform_data_2,.size_data        = sizeof(platform_data_2),};
struct platform_device * p_device_2;

//device 2
p_device_2 = platform_device_register_full(&my_device_2);
if (!p_device_2) 
{
    printk(KERN_INFO"Unable to device 2 registern");
    return ret;
}
View Code

static struct resource my_resoure3[]={
    {
        .start     = 0x41,.end    = 0x50,{
        .start     = 0x51,.end    = 0x60,{
        .start     = 60,.end    = 70,{
        .start     = 80,.end    = 90,};

struct platform_device * p_device_3;

p_device_3 = platform_device_register_resndata(NULL,"xym-test-platform-device-3",-1,my_resoure3,ARRAY_SIZE(my_resoure3),&platform_data_3,sizeof(platform_data_3));    
    if (!p_device_3) 
    {
        printk(KERN_INFO"Unable to device 3 registern");
        return ret;
    }
View Code

static struct resource my_resoure4[]={
    {
        .start     = 0x61,.end    = 0x70,{
        .start     = 0x71,.end    = 0x80,{
        .start     = 100,.end    = 110,{
        .start     = 120,.end    = 130,};
struct platform_device * p_device_4;

//device 4
p_device_4 = platform_device_register_simple("xym-test-platform-device-4",-1,my_resoure4,ARRAY_SIZE(my_resoure4));
    if (!p_device_4) 
    {
        printk(KERN_INFO"Unable to device 4 registern");
        return ret;
    }
View Code

  方法3、DTS注册

/ {
        platform_device_test,test{

        compatible = "dts_test";
        #address-cells = <1>;
        #size-cells = <1>;
        reg = <0x500 0x32>,<0x200 0x32>;
        reg-names = "test mem1","resource2 MEM";

        interrupt-parent = <&vic0>;
        interrupts = <IRQ_TIMER0>,<IRQ_TIMER1>;
        interrupt-names = "test irq1","resource4 IRQ";
        };
};    
View Code

二、获取平台设备资源

  核心接口

1 extern struct resource *platform_get_resource(struct platform_device *unsigned int,unsigned int);
2 extern int platform_get_irq(struct platform_device *,unsigned int);
3 extern struct resource *platform_get_resource_byname(struct platform_device *,unsigned int,const char *);
4 extern int platform_get_irq_byname(struct platform_device *,const char *);
View Code

  代码示例

struct resource *presource;

    int irq = 0;
    
    printk(KERN_INFO"---------------------------n");
    printk(KERN_INFO"%sn",__func__);
    printk(KERN_INFO"%sn",pdev->name);
    if(pdev->dev.platform_data)
    {
        printk(KERN_INFO"platform_data is %dn",*((int*)pdev->dev.platform_data));
    }
    
    presource = platform_get_resource(pdev,IORESOURCE_MEM,0);
    if(!presource)
    {
        printk(KERN_INFO"get mem1 resource failedn");
        return -1;
    }
    printk(KERN_INFO"resoure1 name %sn",presource->name);
    printk(KERN_INFO"resoure1 start 0x%08Xn",presource->start);
    printk(KERN_INFO"resoure1 end 0x%08Xn",presource->end);
    
    presource = NULL;
    presource = platform_get_resource_byname(pdev,"resource2 MEM");
    if(!presource)
    {
        printk(KERN_INFO"get mem2 resource failedn");
        return -1;
    }
    printk(KERN_INFO"resoure1 name %sn",presource->end);


    irq = platform_get_irq(pdev,0);

    if(irq < 0)
    {
        printk(KERN_INFO"get irq1 resource failedn");
        return -1;        
    }
    printk(KERN_INFO"irq1 value is %dn",irq);
    irq = 0;

    irq = platform_get_irq_byname(pdev,"resource4 IRQ");
    if(irq < 0)
    {
        printk(KERN_INFO"get irq2 resource failedn");
        return -1;        
    }
    printk(KERN_INFO"irq2 value is %dn",irq);
    printk(KERN_INFO"---------------------------nnn");
View Code

三、销毁设备

1 platform_device_unregister(&my_device);
2 platform_device_unregister(p_device_2);
View Code

?四、注册平台设备驱动

核心数据结构

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;
    const struct platform_device_id *id_table;
    bool prevent_deferred_probe;
};
View Code

核心接口

platform_driver_register
View Code

代码示例

static struct platform_driver my_driver1 = {
    
    .driver = {
        .name     =  "xym-test-platform-device-1",.probe        = my_platform_probe,.remove        = my_platform_remove,.shutdown    = my_platform_shutdown,.suspend    = my_platform_suspend,.resume        = my_platform_resume,};

ret = platform_driver_register(&my_driver1);
if (ret) 
{
    printk(KERN_INFO"Unable to driver 1 register(%d)n",ret);
    return ret;
}
View Code

其中,driver中的 ”.name“ 字段和device中的?”.name“ 相同,即可完成驱动和设备的匹配,即进入probe阶段。

结果输出

  

  

  

  

完整代码如下:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/ioport.h>


static struct resource my_resoure1[]={
    {
        .start     = 0x00,};
static struct resource my_resoure2[]={
    {
        .start     = 0x21,};

static struct resource my_resoure3[]={
    {
        .start     = 0x41,};

static struct resource my_resoure4[]={
    {
        .start     = 0x61,};

static int platform_data_1 = 1;
static int platform_data_2 = 2;
static int platform_data_3 = 3;
static int platform_data_4 = 4;

static int my_platform_probe(struct platform_device * pdev)
{
    struct resource *presource;

    int irq = 0;
    
    printk(KERN_INFO"---------------------------n");
    printk(KERN_INFO"%sn",irq);
    printk(KERN_INFO"---------------------------nnn");

    return 0;
}
static int my_platform_remove(struct platform_device * pdev)
{
    printk(KERN_INFO"%sn",__func__);
    return 0;
}
static void my_platform_shutdown(struct platform_device *pdev)
{
    printk(KERN_INFO"%sn",__func__);
}
static int my_platform_suspend(struct platform_device * pdev,pm_message_t state)
{
    printk(KERN_INFO"%sn",__func__);
    return 0;
}
static int my_platform_resume(struct platform_device * pdev)
{
    printk(KERN_INFO"%sn",__func__);
    return 0;
}

static void my_platform_device_release(struct device *dev)
{
    printk(KERN_INFO"%sn",__func__);
}


static struct platform_device my_device1 = {
    .name           = "xym-test-platform-device-1",};
struct platform_device * p_device_1 = &my_device1;

static struct platform_driver my_driver1 = {
    
    .driver = {
        .name     =  "xym-test-platform-device-1",};



static struct platform_device_info my_device_2 = {
    .name           = "xym-test-platform-device-2",};
struct platform_device * p_device_2;
        
static struct platform_driver my_driver2 = {
    
    .driver = {
        .name    =  "xym-test-platform-device-2",.remove     = my_platform_remove,.resume     = my_platform_resume,};


struct platform_device * p_device_3;
        
static struct platform_driver my_driver3 = {
    
    .driver = {
        .name    =  "xym-test-platform-device-3",};

struct platform_device * p_device_4;
        
static struct platform_driver my_driver4 = {
    
    .driver = {
        .name    =  "xym-test-platform-device-4",};

static struct of_device_id oz1c007_match_table[] = {
    { .compatible = "dts_test"},};

static struct platform_driver my_driver5 = {
    
    .driver = {
        .name    =  "xym-test-platform-device-5",.of_match_table = oz1c007_match_table,.owner        = THIS_MODULE,};

static int  platform_device_init(void)
{
    int ret = 0;

    
    printk(KERN_INFO"%sn",__func__);
    
    //device 1
    ret = platform_device_register(&my_device1);
    if (ret) 
    {
        printk(KERN_INFO"Unable to device 1 register(%d)n",ret);
        return ret;
    }
    ret = platform_driver_register(&my_driver1);
    if (ret) {
        printk(KERN_INFO"Unable to driver 1 register(%d)n",ret);
        return ret;
    }

    //device 2
    p_device_2 = platform_device_register_full(&my_device_2);
    if (!p_device_2) 
    {
        printk(KERN_INFO"Unable to device 2 registern");
        return ret;
    }
    ret = platform_driver_register(&my_driver2);
    if (ret) {
        printk(KERN_INFO"Unable to driver 2 register(%d)n",ret);
        return ret;
    }

    //device 3
    p_device_3 = platform_device_register_resndata(NULL,sizeof(platform_data_3));    
    if (!p_device_3) 
    {
        printk(KERN_INFO"Unable to device 3 registern");
        return ret;
    }
    ret = platform_driver_register(&my_driver3);
    if (ret) 
    {
        printk(KERN_INFO"Unable to driver 4 register(%d)n",ret);
        return ret;
    }
    
    //device 4
    p_device_4 = platform_device_register_simple("xym-test-platform-device-4",ARRAY_SIZE(my_resoure4));
    if (!p_device_4) 
    {
        printk(KERN_INFO"Unable to device 4 registern");
        return ret;
    }
    platform_device_add_data(p_device_4,&platform_data_4,sizeof(platform_data_4));
    ret = platform_driver_register(&my_driver4);
    if (ret) 
    {
        printk(KERN_INFO"Unable to driver 4 register(%d)n",ret);
        return ret;
    }
    
    //device 5 dts
    ret = platform_driver_register(&my_driver5);
    if (ret) {
        printk(KERN_INFO"Unable to driver 5 register(%d)n",ret);
        return ret;
    }

    printk(KERN_INFO"---------------------------nnn");
    return ret;
}


static void platform_device_destory(void)
{
    printk(KERN_INFO"%sn",__func__);

    platform_device_unregister(p_device_1);
    platform_device_unregister(p_device_2);
    platform_device_unregister(p_device_3);
    platform_device_unregister(p_device_4);
    
    platform_driver_unregister(&my_driver1);
    platform_driver_unregister(&my_driver2);
    platform_driver_unregister(&my_driver3);
    platform_driver_unregister(&my_driver4);
    
    platform_driver_unregister(&my_driver5);

}


static int __init platform_test_init(void)
{
    printk(KERN_INFO"Enter platform testnn");
    platform_device_init();
    return 0;
}

static void __exit platform_test_exit(void)
{
    printk(KERN_INFO"Exit platform testn");
    platform_device_destory();
    
}

module_init(platform_test_init);
module_exit(platform_test_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Marvin.xin");
MODULE_DESCRIPTION("A Test Module for Platform driver");
View Code

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读