现在的位置: 首页 > 综合 > 正文

Platform Devices and Drivers

2013年11月05日 ⁄ 综合 ⁄ 共 7089字 ⁄ 字号 评论关闭

Platform Devices and Drivers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
See
<linux/platform_device.h> for the driver model interface to the
platform
bus:  platform_device, and platform_driver.  This pseudo-bus
is used
to connect devices on busses with minimal infrastructure,
like those
used to integrate peripherals on many system-on-chip
processors, or
some "legacy" PC interconnects; as opposed to large
formally
specified on

es like PCI or USB.
作为与正式且看得见模得着的如PCI或者USB相对,这个虚拟的
bus用来在bus上以最小的基础构建去连接设备,类似的使用如,在SOC上集成外围设备、早期的计算机互联。

Platform
devices
~~~~~~~~~~~~~~~~
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.

型的平台设备作为一个独立自主的实体在系统中出现。这包含兼容的基于端口的设备和主机与外围总线的连接设备(南北桥),以及诸多集成于SOC的控制器,

此,他们通常具有的共性就是通过CPU bus的直接地址访问。极少数情况下,平台设备会被连接到其他类型总线上,这种情况下他依然被注册为直接地址访问
Platform
devices are given a name, used in driver binding, and a
list of
resources such as addresses and IRQs.

struct platform_device {
  
 const char    *name;
    u32        id;
    struct device  
 dev;
    u32        num_resources;
    struct resource  
 *resource;
};

Platform drivers
~~~~~~~~~~~~~~~~
Platform
drivers follow the standard driver model convention, where
discovery/enumeration
is handled outside the drivers, and drivers
provide probe() and
remove() methods.  They support power management
and shutdown
notifications通告 using the standard conventions协议.

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 (*suspend_late)(struct platform_device
*, pm_message_t state);
    int (*resume_early)(struct
platform_device *);
    int (*resume)(struct platform_device *);
  
 struct device_driver driver;
};

Note that probe() should
general verify验证 that the specified device hardware
actually exists;
sometimes platform setup code can't be sure.  The probing
can
use device resources, including clocks, and device platform_data.

Platform
drivers register themselves the normal way:

    int
platform_driver_register(struct platform_driver *drv);

Or, in
common situations where the device is known not to be hot-pluggable,
the
probe() routine can live in an init section to reduce the driver's
runtime
memory footprint:
通常情况下,当设备不支持热插拔的时候,probe()例程会处于一个初始化段中,以减少驱动的运行时内存
交换
    int platform_driver_probe(struct platform_driver *drv,
  
           int (*probe)(struct platform_device *))

Device
Enumeration列举
~~~~~~~~~~~~~~~~~~
As a rule, platform specific (and
often board-specific) setup code will
register platform
devices:
作为一个规则,平台专用setup code 会注册平台设备
    int
platform_device_register(struct platform_device *pdev);

    int
platform_add_devices(struct platform_device **pdevs, int ndev);

The
general rule is to register only those devices that actually
exist,
but in some cases extra devices might be registered.  For
example, a kernel
might be configured to work with an external
network adapter that might not没有被移植到所有的板子上
be populated on all
boards, or likewise同样地 to work with an integrated controller
that
some boards might not hook up与..衔接 to any peripherals.外设

In some
cases, boot firmware will export tables describing the devices
that
are populated on a given board.   Without such tables, often the
only
way for system setup code to set up the correct devices is to
build
a kernel for a specific target board.  Such board-specific
kernels are
common with embedded and custom systems development.

某些情况下,启动固件会输出一个用于描述所有被移植到该板子的设备。如果没有这个表,通常唯一让系统
设置代码去设置一个正确的设备的方法就是为目
标板专门编译一个kernel,这样的专用kernel经常出现在
嵌入式开发和用户定制系统的开发。
In many cases,
the memory and IRQ resources associated关联结合 with the platform
device
are not enough to let the device's driver work.  Board setup code
will
often provide additional information using the device's platform_data
field
to hold additional information.

Embedded systems frequently need
one or more clocks for platform devices,
which are normally
kept off until they're actively needed (to save power).
System setup
also associates those clocks with the device, so that that
calls to
clk_get(&pdev->dev, clock_name) return them as needed.

Legacy
Drivers:  Device Probing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Some
drivers are not fully converted to the driver model, because they take
on
a non-driver role:  the driver registers its platform device, rather
than
leaving that for system infrastructure基础结构.  Such drivers can't
be hotplugged
or coldplugged, since those mechanisms require device
creation to be in a
different system component than the driver.
有一
些驱动并不能完全转换成上述的驱动模式,那是因为他们扮演了一个没有驱动的角色:由驱动亲自去注册自己的平
台设备,比留给系统基础结构去作这件事
更好!这些驱动不支持热插拔,诚然这些机制使得设备被创建成不同的系统组件比驱动要好!
The only "good" reason
for this is to handle older system designs which, like
original IBM
PCs, rely on error-prone "probe-the-hardware" models for hardware
configuration. 
Newer systems have largely abandoned放弃 that model, in favor of有利于
bus-level
support for dynamic configuration (PCI, USB), or device tables
provided
by the boot firmware (e.g. PNPACPI on x86).  There are too many
conflicting
冲突 options about what might be where, and even educated guesses by
an
operating system will be wrong often enough to make trouble.
如此,唯一的好
的理由就是能够保持(兼容)早期的系统设计,比如早先的IBM-PC。
This style of driver is
discouraged反对.  If you're updating such a driver,
please try to move
the device enumeration to a more appropriate适当的 location,
outside the
driver.  This will usually be cleanup, since such drivers
tend
to有..的趋势 already have "normal" modes, such as ones using device
nodes that
were created by PNP or by platform device setup.

None
the less, there are some APIs to support such legacy drivers.  Avoid避免
using
these calls except with such hotplug-deficient drivers.

  
 struct platform_device *platform_device_alloc(
            const
char *name, int id);

You can use platform_device_alloc() to
dynamically allocate a device, which
you will then initialize with
resources and platform_device_register().
A better solution is
usually:

    struct platform_device
*platform_device_register_simple(
            const char *name, int
id,
            struct resource *res, unsigned int nres);

You
can use platform_device_register_simple() as a one-step call to
allocate
and register a device.

Device Naming and Driver
Binding
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The
platform_device.dev.bus_id is the canonical典型的 name for the devices.
It's
built from two components:

    * platform_device.name ... which
is also used to for driver matching匹配.

    * platform_device.id
... the device instance number设备实例号,即这是相同设备里的第几个, or else "-1"
     
to indicate there's only one.

These are concatenated,
so name/id "serial"/0 indicates bus_id "serial.0", and
"serial/3"
indicates bus_id "serial.3"; both would use the platform_driver
named
"serial".  While "my_rtc"/-1 would be bus_id "my_rtc" (no instance id)
and
use the platform_driver called "my_rtc".

Driver binding is
performed automatically by the driver core, invoking调用
driver probe()
after finding a match between device and driver.  If the
probe()
succeeds, the driver and device are bound as usual.  There are
three
different ways to find such a match:

    - Whenever a device is
registered, the drivers for that bus are
      checked for matches. 
Platform devices should be registered very
      early during system
boot.

    - When a driver is registered using
platform_driver_register(), all
      unbound devices on that bus are
checked for matches.  Drivers
      usually register later during
booting, or by module loading.

    - Registering a driver using
platform_driver_probe() works just like
      using
platform_driver_register(), except that the driver won't
      be
probed later if another device registers.  (Which is OK, since
     
this interface is only for use with non-hotpluggable devices.)

抱歉!评论已关闭.