Documentation/driver-api/driver-model/platform.rst GitHub 원문 ↗

Linux 6.18.37 · Driver API

Platform Devices and Drivers

platform_device/driver 등록, enumeration, binding과 early platform 6단계를 설명합니다.

Source pathDocumentation/driver-api/driver-model/platform.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약과 해설

platform.rst:1-247

platform bus는 SoC와 legacy device를 name/id·resource로 표현하고 enumeration과 driver를 분리합니다. 일반 등록·array rollback·legacy 제한·automatic binding을 제공하며 early platform interface로 command line parsing 전후의 매우 이른 console 같은 device도 안전하게 probe합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 ============================
2 Platform Devices and Drivers
3 ============================
4
5 See <linux/platform_device.h> for the driver model interface to the
6 platform bus: platform_device, and platform_driver. This pseudo-bus
7 is used to connect devices on buses with minimal infrastructure,
8 like those used to integrate peripherals on many system-on-chip
9 processors, or some "legacy" PC interconnects; as opposed to large
10 formally specified ones like PCI or USB.
11
12
13 Platform devices
14 ~~~~~~~~~~~~~~~~
15 Platform devices are devices that typically appear as autonomous
16 entities in the system. This includes legacy port-based devices and
17 host bridges to peripheral buses, and most controllers integrated
18 into system-on-chip platforms. What they usually have in common
19 is direct addressing from a CPU bus. Rarely, a platform_device will
20 be connected through a segment of some other kind of bus; but its
21 registers will still be directly addressable.
22
23 Platform devices are given a name, used in driver binding, and a
24 list of resources such as addresses and IRQs::
25
26 struct platform_device {
27 const char *name;
28 u32 id;
29 struct device dev;
30 u32 num_resources;
31 struct resource *resource;
32 };
33
34
35 Platform drivers
36 ~~~~~~~~~~~~~~~~
37 Platform drivers follow the standard driver model convention, where
38 discovery/enumeration is handled outside the drivers, and drivers
39 provide probe() and remove() methods. They support power management
40 and shutdown notifications using the standard conventions::
41
42 struct platform_driver {
43 int (*probe)(struct platform_device *);
44 void (*remove)(struct platform_device *);
45 void (*shutdown)(struct platform_device *);
46 int (*suspend)(struct platform_device *, pm_message_t state);
47 int (*resume)(struct platform_device *);
48 struct device_driver driver;
49 const struct platform_device_id *id_table;
50 bool prevent_deferred_probe;
51 bool driver_managed_dma;
52 };
53
54 Note that probe() should in general verify that the specified device hardware
55 actually exists; sometimes platform setup code can't be sure. The probing
56 can use device resources, including clocks, and device platform_data.
57
58 Platform drivers register themselves the normal way::
59
60 int platform_driver_register(struct platform_driver *drv);
61
62 Or, in common situations where the device is known not to be hot-pluggable,
63 the probe() routine can live in an init section to reduce the driver's
64 runtime memory footprint::
65
66 int platform_driver_probe(struct platform_driver *drv,
67 int (*probe)(struct platform_device *))
68
69 Kernel modules can be composed of several platform drivers. The platform core
70 provides helpers to register and unregister an array of drivers::
71
72 int __platform_register_drivers(struct platform_driver * const *drivers,
73 unsigned int count, struct module *owner);
74 void platform_unregister_drivers(struct platform_driver * const *drivers,
75 unsigned int count);
76
77 If one of the drivers fails to register, all drivers registered up to that
78 point will be unregistered in reverse order. Note that there is a convenience
79 macro that passes THIS_MODULE as owner parameter::
80
81 #define platform_register_drivers(drivers, count)
82
83
84 Device Enumeration
85 ~~~~~~~~~~~~~~~~~~
86 As a rule, platform specific (and often board-specific) setup code will
87 register platform devices::
88
89 int platform_device_register(struct platform_device *pdev);
90
91 int platform_add_devices(struct platform_device **pdevs, int ndev);
92
93 The general rule is to register only those devices that actually exist,
94 but in some cases extra devices might be registered. For example, a kernel
95 might be configured to work with an external network adapter that might not
96 be populated on all boards, or likewise to work with an integrated controller
97 that some boards might not hook up to any peripherals.
98
99 In some cases, boot firmware will export tables describing the devices
100 that are populated on a given board. Without such tables, often the
101 only way for system setup code to set up the correct devices is to build
102 a kernel for a specific target board. Such board-specific kernels are
103 common with embedded and custom systems development.
104
105 In many cases, the memory and IRQ resources associated with the platform
106 device are not enough to let the device's driver work. Board setup code
107 will often provide additional information using the device's platform_data
108 field to hold additional information.
109
110 Embedded systems frequently need one or more clocks for platform devices,
111 which are normally kept off until they're actively needed (to save power).
112 System setup also associates those clocks with the device, so that
113 calls to clk_get(&pdev->dev, clock_name) return them as needed.
114
115
116 Legacy Drivers: Device Probing
117 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
118 Some drivers are not fully converted to the driver model, because they take
119 on a non-driver role: the driver registers its platform device, rather than
120 leaving that for system infrastructure. Such drivers can't be hotplugged
121 or coldplugged, since those mechanisms require device creation to be in a
122 different system component than the driver.
123
124 The only "good" reason for this is to handle older system designs which, like
125 original IBM PCs, rely on error-prone "probe-the-hardware" models for hardware
126 configuration. Newer systems have largely abandoned that model, in favor of
127 bus-level support for dynamic configuration (PCI, USB), or device tables
128 provided by the boot firmware (e.g. PNPACPI on x86). There are too many
129 conflicting options about what might be where, and even educated guesses by
130 an operating system will be wrong often enough to make trouble.
131
132 This style of driver is discouraged. If you're updating such a driver,
133 please try to move the device enumeration to a more appropriate location,
134 outside the driver. This will usually be cleanup, since such drivers
135 tend to already have "normal" modes, such as ones using device nodes that
136 were created by PNP or by platform device setup.
137
138 None the less, there are some APIs to support such legacy drivers. Avoid
139 using these calls except with such hotplug-deficient drivers::
140
141 struct platform_device *platform_device_alloc(
142 const char *name, int id);
143
144 You can use platform_device_alloc() to dynamically allocate a device, which
145 you will then initialize with resources and platform_device_register().
146 A better solution is usually::
147
148 struct platform_device *platform_device_register_simple(
149 const char *name, int id,
150 struct resource *res, unsigned int nres);
151
152 You can use platform_device_register_simple() as a one-step call to allocate
153 and register a device.
154
155
156 Device Naming and Driver Binding
157 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
158 The platform_device.dev.bus_id is the canonical name for the devices.
159 It's built from two components:
160
161 * platform_device.name ... which is also used to for driver matching.
162
163 * platform_device.id ... the device instance number, or else "-1"
164 to indicate there's only one.
165
166 These are concatenated, so name/id "serial"/0 indicates bus_id "serial.0", and
167 "serial/3" indicates bus_id "serial.3"; both would use the platform_driver
168 named "serial". While "my_rtc"/-1 would be bus_id "my_rtc" (no instance id)
169 and use the platform_driver called "my_rtc".
170
171 Driver binding is performed automatically by the driver core, invoking
172 driver probe() after finding a match between device and driver. If the
173 probe() succeeds, the driver and device are bound as usual. There are
174 three different ways to find such a match:
175
176 - Whenever a device is registered, the drivers for that bus are
177 checked for matches. Platform devices should be registered very
178 early during system boot.
179
180 - When a driver is registered using platform_driver_register(), all
181 unbound devices on that bus are checked for matches. Drivers
182 usually register later during booting, or by module loading.
183
184 - Registering a driver using platform_driver_probe() works just like
185 using platform_driver_register(), except that the driver won't
186 be probed later if another device registers. (Which is OK, since
187 this interface is only for use with non-hotpluggable devices.)
188
189
190 Early Platform Devices and Drivers
191 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
192 The early platform interfaces provide platform data to platform device
193 drivers early on during the system boot. The code is built on top of the
194 early_param() command line parsing and can be executed very early on.
195
196 Example: "earlyprintk" class early serial console in 6 steps
197
198 1. Registering early platform device data
199 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
200 The architecture code registers platform device data using the function
201 early_platform_add_devices(). In the case of early serial console this
202 should be hardware configuration for the serial port. Devices registered
203 at this point will later on be matched against early platform drivers.
204
205 2. Parsing kernel command line
206 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
207 The architecture code calls parse_early_param() to parse the kernel
208 command line. This will execute all matching early_param() callbacks.
209 User specified early platform devices will be registered at this point.
210 For the early serial console case the user can specify port on the
211 kernel command line as "earlyprintk=serial.0" where "earlyprintk" is
212 the class string, "serial" is the name of the platform driver and
213 0 is the platform device id. If the id is -1 then the dot and the
214 id can be omitted.
215
216 3. Installing early platform drivers belonging to a certain class
217 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
218 The architecture code may optionally force registration of all early
219 platform drivers belonging to a certain class using the function
220 early_platform_driver_register_all(). User specified devices from
221 step 2 have priority over these. This step is omitted by the serial
222 driver example since the early serial driver code should be disabled
223 unless the user has specified port on the kernel command line.
224
225 4. Early platform driver registration
226 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
227 Compiled-in platform drivers making use of early_platform_init() are
228 automatically registered during step 2 or 3. The serial driver example
229 should use early_platform_init("earlyprintk", &platform_driver).
230
231 5. Probing of early platform drivers belonging to a certain class
232 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
233 The architecture code calls early_platform_driver_probe() to match
234 registered early platform devices associated with a certain class with
235 registered early platform drivers. Matched devices will get probed().
236 This step can be executed at any point during the early boot. As soon
237 as possible may be good for the serial port case.
238
239 6. Inside the early platform driver probe()
240 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
241 The driver code needs to take special care during early boot, especially
242 when it comes to memory allocation and interrupt registration. The code
243 in the probe() function can use is_early_platform_device() to check if
244 it is called at early platform device or at the regular platform device
245 time. The early serial driver performs register_console() at this point.
246
247 For further information, see <linux/platform_device.h>.
248

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

Platform bus 소개

1-12

platform bus의 driver model interface인 `platform_device`와 `platform_driver`는 `<linux/platform_device.h>`에 있습니다. 이 pseudo-bus는 PCI·USB처럼 큰 정식 specification이 있는 bus와 달리, 많은 SoC peripheral이나 일부 legacy PC interconnect처럼 infrastructure가 최소인 bus의 device를 연결합니다.

Platform device

13-34

platform device는 보통 system에서 autonomous entity로 나타납니다. legacy port-based device, peripheral bus host bridge, 대부분의 SoC integrated controller가 포함됩니다. 공통점은 CPU bus에서 직접 address할 수 있다는 것입니다. 드물게 다른 bus segment를 거쳐도 register는 여전히 직접 address할 수 있습니다.

driver binding에 사용하는 name과 address·IRQ 같은 resource 목록을 가집니다.

struct platform_device {
      const char        *name;
      u32                id;
      struct device        dev;
      u32                num_resources;
      struct resource        *resource;
};
platform_device 핵심 field
FieldRole
nameDriver matching name
idInstance number
devEmbedded struct device
num_resourcesResource count
resourceAddress/IRQ resource array

identity, generic core object와 resource를 구분했습니다.

Platform driver와 등록 helper

35-83

platform driver는 discovery/enumeration을 driver 밖에서 처리하고 driver가 `probe()`와 `remove()`를 제공하는 standard driver model convention을 따릅니다. standard convention으로 power management와 shutdown notification도 지원합니다.

struct platform_driver {
      int (*probe)(struct platform_device *);
      void (*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;
      bool driver_managed_dma;
};

`probe()`는 지정 hardware가 실제로 존재하는지 보통 확인해야 합니다. platform setup code가 확신하지 못할 수 있기 때문입니다. probing에는 clock을 포함한 device resource와 `platform_data`를 사용할 수 있습니다.

일반 등록 함수는 다음과 같습니다.

int platform_driver_register(struct platform_driver *drv);

hot-plug되지 않는 것이 확실한 흔한 경우에는 `probe()`를 init section에 두어 runtime memory footprint를 줄일 수 있습니다.

int platform_driver_probe(struct platform_driver *drv,
                  int (*probe)(struct platform_device *))

kernel module 하나가 여러 platform driver로 구성될 수 있어 core는 driver array 등록·해제 helper를 제공합니다.

int __platform_register_drivers(struct platform_driver * const *drivers,
                              unsigned int count, struct module *owner);
void platform_unregister_drivers(struct platform_driver * const *drivers,
                                 unsigned int count);

driver 하나의 등록이 실패하면 앞서 등록된 모든 driver를 reverse order로 unregister합니다. owner로 `THIS_MODULE`을 넘기는 convenience macro도 있습니다.

#define platform_register_drivers(drivers, count)
platform driver array registration
register drivers[0..n]one registration failsstop forward registrationunregister prior drivers in reverse orderreturn failure

부분 실패 시 rollback 순서를 나타냅니다.

Device enumeration과 board data

84-115

일반적으로 platform-specific, 흔히 board-specific setup code가 platform device를 등록합니다.

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

실제로 존재하는 device만 등록하는 것이 원칙이지만, 모든 board에 장착되지 않은 external network adapter나 peripheral에 연결되지 않은 integrated controller를 지원하려고 extra device를 등록할 수도 있습니다.

boot firmware가 board에 장착된 device table을 export하기도 합니다. table이 없으면 target board 전용 kernel을 build하는 것이 올바른 setup의 유일한 방법일 수 있으며 embedded·custom system에서 흔합니다.

memory와 IRQ resource만으로 부족하면 board setup code가 `platform_data` field에 추가 정보를 제공합니다. embedded system의 platform device는 power 절약을 위해 필요할 때만 켜는 clock이 흔하며 system setup이 clock을 device와 연결해 `clk_get(&pdev->dev, clock_name)`으로 얻도록 합니다.

Legacy probe-the-hardware driver

116-155

일부 driver는 system infrastructure 대신 자신이 platform device를 등록하는 non-driver role까지 맡아 driver model로 완전히 전환되지 않았습니다. device creation과 driver가 분리되지 않으므로 hotplug·coldplug할 수 없습니다.

정당한 이유는 original IBM PC처럼 오류가 잦은 `probe-the-hardware` model에 의존하는 오래된 system을 처리하는 경우뿐입니다. 새 system은 PCI·USB dynamic configuration이나 PNPACPI 같은 boot firmware device table을 사용합니다. 가능한 위치 조합이 너무 많아 OS의 educated guess도 문제를 일으킬 만큼 자주 틀립니다.

이 style은 권장하지 않습니다. 수정할 때 device enumeration을 driver 밖의 적절한 위치로 옮겨야 합니다. PNP나 platform setup이 만든 device node를 쓰는 normal mode가 이미 있는 경우가 많아 보통 cleanup이 됩니다. 그래도 legacy 지원 API는 존재하며 hotplug가 불가능한 driver 외에는 피해야 합니다.

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

`platform_device_alloc()`으로 device를 동적 할당한 뒤 resource를 초기화하고 `platform_device_register()`로 등록할 수 있지만 보통 다음 one-step call이 더 낫습니다.

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

`platform_device_register_simple()`은 device allocation과 registration을 한 번에 수행합니다.

Device naming과 automatic binding

156-189

`platform_device.dev.bus_id`는 canonical device name이며 driver matching에도 쓰는 `platform_device.name`과 instance number인 `platform_device.id`를 결합합니다. instance가 하나뿐이면 id `-1`을 사용합니다.

name/id `serial`/0과 `serial`/3은 각각 `serial.0`, `serial.3`이 되고 둘 다 `serial` platform_driver를 사용합니다. `my_rtc`/-1은 instance suffix 없이 `my_rtc`가 되고 같은 이름의 driver를 사용합니다.

driver core는 device와 driver match를 찾은 뒤 `probe()`를 호출해 자동 binding합니다. device 등록 시 bus driver를 검사하므로 platform device는 boot 초기에 등록해야 합니다. `platform_driver_register()` 시 bus의 unbound device를 모두 검사하며 driver는 보통 boot 후반이나 module load 때 등록됩니다. `platform_driver_probe()`도 비슷하지만 이후 새 device가 등록되어도 다시 probe하지 않으므로 non-hotpluggable device에만 적합합니다.

Platform matching trigger
TriggerCandidates checkedFuture devices
platform_device registerDrivers on platform busNormal matching
platform_driver_registerAll unbound devicesCan match later devices
platform_driver_probeAll current unbound devicesNo later probing

세 binding 시점과 hotplug 특성을 비교했습니다.

Early platform interface 개요

190-197

early platform interface는 boot 초기에 platform device driver에 platform data를 제공합니다. `early_param()` command-line parsing 위에 구현되어 매우 이르게 실행할 수 있습니다. 문서는 `earlyprintk` class early serial console을 6단계로 설명합니다.

Early platform 6단계
1 add device data2 parse early command line3 optionally install class drivers4 early driver registration5 class matching and probe6 early-safe probe work

data 등록에서 early probe까지의 전체 순서입니다.

1. Early device data 등록

198-204

architecture code는 `early_platform_add_devices()`로 platform device data를 등록합니다. early serial console이라면 serial port hardware configuration입니다. 이때 등록한 device는 나중에 early platform driver와 match됩니다.

2. Kernel command line parsing

205-215

architecture code가 `parse_early_param()`을 호출해 command line을 parse하고 일치하는 모든 `early_param()` callback을 실행합니다. user가 지정한 early platform device도 여기서 등록됩니다. serial console은 `earlyprintk=serial.0`처럼 class string, platform driver name, device id를 지정하며 id가 -1이면 dot과 id를 생략할 수 있습니다.

3. Class driver 강제 등록

216-224

architecture code는 선택적으로 `early_platform_driver_register_all()`로 특정 class의 early platform driver를 모두 강제 등록할 수 있습니다. 2단계의 user-specified device가 우선합니다. early serial driver는 user가 command line에서 port를 지정하지 않으면 disable되어야 하므로 이 단계를 생략합니다.

4. Early driver registration

225-230

`early_platform_init()`을 사용하는 built-in platform driver는 2단계나 3단계 중 자동 등록됩니다. serial 예제는 `early_platform_init("earlyprintk", &platform_driver)`를 사용해야 합니다.

5. Early driver probing

231-238

architecture code가 `early_platform_driver_probe()`를 호출해 특정 class의 등록 device와 driver를 match하고 일치한 device를 `probe()`합니다. early boot 중 어느 때든 실행할 수 있으며 serial port는 가능한 한 이른 시점이 좋습니다.

6. Early probe 내부 주의점

239-247

driver code는 early boot에서 memory allocation과 interrupt registration에 특별히 주의해야 합니다. `probe()`는 `is_early_platform_device()`로 early device 시점인지 regular platform device 시점인지 확인할 수 있습니다. early serial driver는 여기서 `register_console()`을 수행합니다. 자세한 내용은 `<linux/platform_device.h>`를 참고합니다.