smmu学习笔记之device的platform_data和driver_data

device 这个结构体中有两个变量可以存储设备的私有数据
    void        *platform_data;    /* Platform specific data, device
                       core doesn't touch it */
    void        *driver_data;    /* Driver data, set and get with
                       dev_set/get_drvdata */

platform_data 一般存储Platform的私有数据。
static int arm_smmu_device_acpi_probe(struct platform_device *pdev,
                      struct arm_smmu_device *smmu,
                      bool *bypass)
{
    struct acpi_iort_smmu_v3 *iort_smmu;
    struct device *dev = smmu->dev;
    struct acpi_iort_node *node;

    node = *(struct acpi_iort_node **)dev_get_platdata(dev);

    /* Retrieve SMMUv3 specific data */
    iort_smmu = (struct acpi_iort_smmu_v3 *)node->node_data;

    if (iort_smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE)
        smmu->features |= ARM_SMMU_FEAT_COHERENCY;

    *bypass = false;

    return 0;
}
例如在arm_smmu_device_acpi_probe 中就可以通过dev_get_platdata(dev)来得到设备的私有数据。
得到私有数据acpi_iort_smmu_v3 *iort_smmu 后,再通过iort_smmu = (struct acpi_iort_smmu_v3 *)node->node_data;得到具体的数据,这部分和具体的driver没有什么关系,是和smmu spec相关的,例如这里决定smmu是否包含COHACC_OVERRIDE 这个feature.
而这个platform_data 是在iort_add_smmu_platform_device 中的platform_device_add_data 添加的.也就是bios传递过来的
int platform_device_add_data(struct platform_device *pdev, const void *data,
                 size_t size)
{
    void *d = NULL;

    if (data) {
        d = kmemdup(data, size, GFP_KERNEL);
        if (!d)
            return -ENOMEM;
    }

    kfree(pdev->dev.platform_data);
    pdev->dev.platform_data = d;
    return 0;
}


这个是针对platform 设备的,和具体的driver没有什么关系。
而driver_data 是提供给driver用来存储driver私有数据的
static int arm_smmu_device_probe(struct platform_device *pdev)
{
    int irq, ret;
    struct resource *res;
    struct arm_smmu_device *smmu;
    struct device *dev = &pdev->dev;
    bool bypass;

    smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL);
    if (!smmu) {
        dev_err(dev, "failed to allocate arm_smmu_device\n");
        return -ENOMEM;
    }
    smmu->dev = dev;
    /* Record our private device structure */
    platform_set_drvdata(pdev, smmu);
}
例如在arm_smmu_device_probe 中就是将arm_smmu_device 通过platform_set_drvdata(pdev, smmu);存到device的driver_data 中
static inline void platform_set_drvdata(struct platform_device *pdev,
                    void *data)
{
    dev_set_drvdata(&pdev->dev, data);
}
static inline void dev_set_drvdata(struct device *dev, void *data)
{
    dev->driver_data = data;
}
与之相对对应的是
static inline void *dev_get_drvdata(const struct device *dev)
{
    return dev->driver_data;
}

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值