设备驱动中的platform(kernel-4.7)

platform驱动模型搭建

platform核心层:为设备层和驱动层提供注册接口、为设备层和驱动层的匹配提供标准。
内核是这样描述它们的(Documentation/driver-model/platform.txt):

Platform devices are devices that typically appear as autonomous
entities in the system. This includes legacy port-based devices and
host bridges to peripheral buses, and most controllers integrated
into system-on-chip platforms.  What they usually have in common
is direct addressing from a CPU bus.  Rarely, a platform_device will
be connected through a segment of some other kind of bus; but its
registers will still be directly addressable. 

概括来说,Platform设备包括:基于端口的设备(已不推荐使用,保留下来只为兼容旧设备,legacy);连接物理总线的桥设备;集成在SOC平台上面的控制器;连接在其它bus上的设备(很少见)。等等。
这些设备有一个基本的特征:可以通过CPU bus直接寻址(例如在嵌入式系统常见的“寄存器”)。因此,由于这个共性,内核在设备模型的基础上(devicedevice_driver),对这些设备进行了更进一步的封装,抽象出paltform bus、platform device和platform driver,以便驱动开发人员可以方便的开发这类设备的驱动。 paltform设备对Linux驱动工程师是非常重要的,因为编写的大多数设备驱动,都是为了驱动plaftom设备。

Platform模块的软件架构

内核中Platform设备有关的实现位于include/linux/platform_device.h和drivers/base/platform.c两个文件中,它的软件架构如下:
这里写图片描述

由图片可知,Platform设备在内核中的实现主要包括三个部分:
Platform Bus,基于底层bus模块,抽象出一个虚拟的Platform bus,用于挂载Platform设备;
Platform Device,基于底层device模块,抽象出Platform Device,用于表示Platform设备;
Platform Driver,基于底层device_driver模块,抽象出Platform Driver,用于驱动Platform设备。

其中Platform Device和Platform Driver会会其它Driver提供封装好的API。

①搭建总线框架:
总线类结构体:
在include/linux/device.h中定义的bus_type:



/**
 * struct bus_type - The bus type of the device
 *
 * @name:   The name of the bus.
 * @dev_name:   Used for subsystems to enumerate devices like ("foo%u", dev->id).
 * @dev_root:   Default device to use as the parent.
 * @dev_attrs:  Default attributes of the devices on the bus.
 * @bus_groups: Default attributes of the bus.
 * @dev_groups: Default attributes of the devices on the bus.
 * @drv_groups: Default attributes of the device drivers on the bus.
 * @match:  Called, perhaps multiple times, whenever a new device or driver
 *      is added for this bus. It should return a positive value if the
 *      given device can be handled by the given driver and zero
 *      otherwise. It may also return error code if determining that
 *      the driver supports the device is not possible. In case of
 *      -EPROBE_DEFER it will queue the device for deferred probing.
 * @uevent: Called when a device is added, removed, or a few other things
 *      that generate uevents to add the environment variables.
 * @probe:  Called when a new device or driver add to this bus, and callback
 *      the specific driver's probe to initial the matched device.
 * @remove: Called when a device removed from this bus.
 * @shutdown:   Called at shut-down time to quiesce the device.
 *
 * @online: Called to put the device back online (after offlining it).
 * @offline:    Called to put the device offline for hot-removal. May fail.
 *
 * @suspend:    Called when a device on this bus wants to go to sleep mode.
 * @resume: Called to bring a device on this bus out of sleep mode.
 * @pm:     Power management operations of this bus, callback the specific
 *      device driver's pm-ops.
 * @iommu_ops:  IOMMU specific operations for this bus, used to attach IOMMU
 *              driver implementations to a bus and allow the driver to do
 *              bus-specific setup
 * @p:      The private data of the driver core, only the driver core can
 *      touch this.
 * @lock_key:   Lock class key for use by the lock validator
 *
 * A bus is a channel between the processor and one or more devices. For the
 * purposes of the device model, all devices are connected via a bus, even if
 * it is an internal, virtual, "platform" bus. Buses can plug into each other.
 * A USB controller is usually a PCI device, for example. The device model
 * represents the actual connections between buses and the devices they control.
 * A bus is represented by the bus_type structure. It contains the name, the
 * default attributes, the bus' methods, PM operations, and the driver core's
 * private data.
 */
struct bus_type {
    const char      *name;
    const char      *dev_name;
    struct device       *dev_root;
    struct device_attribute *dev_attrs; /* use dev_groups instead */
    const struct attribute_group **bus_groups;
    const struct attribute_group **dev_groups;
    const struct attribute_group **drv_groups;

    int (*match)(struct device *dev, struct device_driver *drv);
    int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
    int (*probe)(struct device *dev);
    int (*remove)(struct device *dev); void (*shutdown)(struct device *dev); int (*online)(struct device *dev); int (*offline)(struct device *dev); int (*suspend)(struct device *dev, pm_message_t state); int (*resume)(struct device *dev); const struct dev_pm_ops *pm; const struct iommu_ops *iommu_ops; struct subsys_private *p; struct lock_class_key lock_key; }; 

总线类实例化:platform总线 :
在driver/base/platform.c中:


struct bus_type platform_bus_type = {
    .name       = "platform",
    .dev_groups = platform_dev_groups,
    .match      = platform_match,
    .uevent     = platform_uevent,
    .pm     = &platform_dev_pm_ops,
};

注册platform总线过程:
在driver/base/platform.c中:


int __init platform_bus_init(void)
{
    int error;

    early_platform_cleanup();

    error = device_register(&platform_bus);
    if (error)
        return error;
    error =  bus_register(&platform_bus_type); 
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值