如何将platform_device的通用资源/数据转发给驱动程序

时间:2013-09-04 11:08:50

标签: c linux linux-kernel linux-device-driver device-driver

我有一个platform_device实例,我想传递一个函数指针,我想知道什么是最干净,最通用的方法。

最好的事情是,如果我在内核中有一些misc资源,我可以为我想要的任何内容传递void*,但这些是唯一可用的资源:

 31 #define IORESOURCE_TYPE_BITS    0x00001f00      /* Resource type */
 32 #define IORESOURCE_IO           0x00000100      /* PCI/ISA I/O ports */
 33 #define IORESOURCE_MEM          0x00000200
 34 #define IORESOURCE_REG          0x00000300      /* Register offsets */
 35 #define IORESOURCE_IRQ          0x00000400
 36 #define IORESOURCE_DMA          0x00000800
 37 #define IORESOURCE_BUS          0x00001000

实际上我有一个平台设备容器,但它在探测功能中动态分配和初始化。

我的问题是如何将通用指针作为资源传递给设备?或者我怎样才能以最干净的方式做到这一点?

1 个答案:

答案 0 :(得分:3)

使用platform_data,如您在问题中链接的LWN文章底部所述。在您的情况下,您的数据结构将如下所示。这显然是未经测试的,但你明白了。您的platform_data结构将保存函数指针,您可以在定义设备详细信息的同时设置它。

int sleep_function_chip1(struct platform_device *pdev)
{
    // Go to sleep
    return 0;
}
int resume_function_chip1(struct platform_device *pdev)
{
    // Resume
    return 0;
}

struct my_platform_data {
    int (*sleep_function)(struct platform_device *);
    int (*resume_function)(struct platform_device *);
};

// Instance of my_platform_data for a particular hardware (called chip1 for now)
static struct my_platform_data my_platform_data_chip1 = {
    .sleep_function  = &sleep_function_chip1,
    .resume_function = &resume_function_chip1,
};

// Second instance of my_platform_data for a different hardware (called chip2 for now)
static struct my_platform_data my_platform_data_chip2 = {
    .sleep_function  = &sleep_function_chip2,
    .resume_function = &resume_function_chip2,
};

// Now include that data when you create the descriptor for
// your platform
static struct platform_device my_platform_device_chip1 = {
    .name       = "my_device",
    .id     = 0,
    .dev = {
        .platform_data = &my_platform_data_chip1,
    }
};

int some_driver_function() {
    struct platform_device *pdev;
    pdev = // wherever you store this

    // Any time you need that data, extract the platform_data pointer
    struct my_platform_data *pd = (struct my_platform_data*)pdev->dev.platform_data;

    // Call the function pointer
    pd->sleep_function(pdev);
}