Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0
2 : : /*
3 : : * platform.c - platform 'pseudo' bus for legacy devices
4 : : *
5 : : * Copyright (c) 2002-3 Patrick Mochel
6 : : * Copyright (c) 2002-3 Open Source Development Labs
7 : : *
8 : : * Please see Documentation/driver-api/driver-model/platform.rst for more
9 : : * information.
10 : : */
11 : :
12 : : #include <linux/string.h>
13 : : #include <linux/platform_device.h>
14 : : #include <linux/of_device.h>
15 : : #include <linux/of_irq.h>
16 : : #include <linux/module.h>
17 : : #include <linux/init.h>
18 : : #include <linux/dma-mapping.h>
19 : : #include <linux/memblock.h>
20 : : #include <linux/err.h>
21 : : #include <linux/slab.h>
22 : : #include <linux/pm_runtime.h>
23 : : #include <linux/pm_domain.h>
24 : : #include <linux/idr.h>
25 : : #include <linux/acpi.h>
26 : : #include <linux/clk/clk-conf.h>
27 : : #include <linux/limits.h>
28 : : #include <linux/property.h>
29 : : #include <linux/kmemleak.h>
30 : : #include <linux/types.h>
31 : :
32 : : #include "base.h"
33 : : #include "power/power.h"
34 : :
35 : : /* For automatically allocated device IDs */
36 : : static DEFINE_IDA(platform_devid_ida);
37 : :
38 : : struct device platform_bus = {
39 : : .init_name = "platform",
40 : : };
41 : : EXPORT_SYMBOL_GPL(platform_bus);
42 : :
43 : : /**
44 : : * platform_get_resource - get a resource for a device
45 : : * @dev: platform device
46 : : * @type: resource type
47 : : * @num: resource index
48 : : */
49 : 0 : struct resource *platform_get_resource(struct platform_device *dev,
50 : : unsigned int type, unsigned int num)
51 : : {
52 : 0 : u32 i;
53 : :
54 [ # # # # : 0 : for (i = 0; i < dev->num_resources; i++) {
# # # # ]
55 : 0 : struct resource *r = &dev->resource[i];
56 : :
57 [ # # # # : 0 : if (type == resource_type(r) && num-- == 0)
# # # # #
# # # # #
# # ]
58 : 0 : return r;
59 : : }
60 : : return NULL;
61 : : }
62 : : EXPORT_SYMBOL_GPL(platform_get_resource);
63 : :
64 : : #ifdef CONFIG_HAS_IOMEM
65 : : /**
66 : : * devm_platform_ioremap_resource - call devm_ioremap_resource() for a platform
67 : : * device
68 : : *
69 : : * @pdev: platform device to use both for memory resource lookup as well as
70 : : * resource management
71 : : * @index: resource index
72 : : */
73 : 0 : void __iomem *devm_platform_ioremap_resource(struct platform_device *pdev,
74 : : unsigned int index)
75 : : {
76 : 0 : struct resource *res;
77 : :
78 : 0 : res = platform_get_resource(pdev, IORESOURCE_MEM, index);
79 : 0 : return devm_ioremap_resource(&pdev->dev, res);
80 : : }
81 : : EXPORT_SYMBOL_GPL(devm_platform_ioremap_resource);
82 : :
83 : : /**
84 : : * devm_platform_ioremap_resource_wc - write-combined variant of
85 : : * devm_platform_ioremap_resource()
86 : : *
87 : : * @pdev: platform device to use both for memory resource lookup as well as
88 : : * resource management
89 : : * @index: resource index
90 : : */
91 : 0 : void __iomem *devm_platform_ioremap_resource_wc(struct platform_device *pdev,
92 : : unsigned int index)
93 : : {
94 : 0 : struct resource *res;
95 : :
96 : 0 : res = platform_get_resource(pdev, IORESOURCE_MEM, index);
97 : 0 : return devm_ioremap_resource_wc(&pdev->dev, res);
98 : : }
99 : :
100 : : /**
101 : : * devm_platform_ioremap_resource_byname - call devm_ioremap_resource for
102 : : * a platform device, retrieve the
103 : : * resource by name
104 : : *
105 : : * @pdev: platform device to use both for memory resource lookup as well as
106 : : * resource management
107 : : * @name: name of the resource
108 : : */
109 : : void __iomem *
110 : 0 : devm_platform_ioremap_resource_byname(struct platform_device *pdev,
111 : : const char *name)
112 : : {
113 : 0 : struct resource *res;
114 : :
115 : 0 : res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
116 : 0 : return devm_ioremap_resource(&pdev->dev, res);
117 : : }
118 : : EXPORT_SYMBOL_GPL(devm_platform_ioremap_resource_byname);
119 : : #endif /* CONFIG_HAS_IOMEM */
120 : :
121 : : /**
122 : : * platform_get_irq_optional - get an optional IRQ for a device
123 : : * @dev: platform device
124 : : * @num: IRQ number index
125 : : *
126 : : * Gets an IRQ for a platform device. Device drivers should check the return
127 : : * value for errors so as to not pass a negative integer value to the
128 : : * request_irq() APIs. This is the same as platform_get_irq(), except that it
129 : : * does not print an error message if an IRQ can not be obtained.
130 : : *
131 : : * Example:
132 : : * int irq = platform_get_irq_optional(pdev, 0);
133 : : * if (irq < 0)
134 : : * return irq;
135 : : *
136 : : * Return: IRQ number on success, negative error number on failure.
137 : : */
138 : 0 : int platform_get_irq_optional(struct platform_device *dev, unsigned int num)
139 : : {
140 : : #ifdef CONFIG_SPARC
141 : : /* sparc does not have irqs represented as IORESOURCE_IRQ resources */
142 : : if (!dev || num >= dev->archdata.num_irqs)
143 : : return -ENXIO;
144 : : return dev->archdata.irqs[num];
145 : : #else
146 : 0 : struct resource *r;
147 : 0 : int ret;
148 : :
149 : 0 : if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) {
150 : : ret = of_irq_get(dev->dev.of_node, num);
151 : : if (ret > 0 || ret == -EPROBE_DEFER)
152 : : return ret;
153 : : }
154 : :
155 : 0 : r = platform_get_resource(dev, IORESOURCE_IRQ, num);
156 [ # # ]: 0 : if (has_acpi_companion(&dev->dev)) {
157 [ # # # # ]: 0 : if (r && r->flags & IORESOURCE_DISABLED) {
158 : 0 : ret = acpi_irq_get(ACPI_HANDLE(&dev->dev), num, r);
159 : 0 : if (ret)
160 : 0 : return ret;
161 : : }
162 : : }
163 : :
164 : : /*
165 : : * The resources may pass trigger flags to the irqs that need
166 : : * to be set up. It so happens that the trigger flags for
167 : : * IORESOURCE_BITS correspond 1-to-1 to the IRQF_TRIGGER*
168 : : * settings.
169 : : */
170 [ # # # # ]: 0 : if (r && r->flags & IORESOURCE_BITS) {
171 : 0 : struct irq_data *irqd;
172 : :
173 : 0 : irqd = irq_get_irq_data(r->start);
174 [ # # ]: 0 : if (!irqd)
175 : : return -ENXIO;
176 : 0 : irqd_set_trigger_type(irqd, r->flags & IORESOURCE_BITS);
177 : : }
178 : :
179 [ # # ]: 0 : if (r)
180 : 0 : return r->start;
181 : :
182 : : /*
183 : : * For the index 0 interrupt, allow falling back to GpioInt
184 : : * resources. While a device could have both Interrupt and GpioInt
185 : : * resources, making this fallback ambiguous, in many common cases
186 : : * the device will only expose one IRQ, and this fallback
187 : : * allows a common code path across either kind of resource.
188 : : */
189 [ # # # # ]: 0 : if (num == 0 && has_acpi_companion(&dev->dev)) {
190 : 0 : ret = acpi_dev_gpio_irq_get(ACPI_COMPANION(&dev->dev), num);
191 : : /* Our callers expect -ENXIO for missing IRQs. */
192 : : if (ret >= 0 || ret == -EPROBE_DEFER)
193 : : return ret;
194 : : }
195 : :
196 : : return -ENXIO;
197 : : #endif
198 : : }
199 : : EXPORT_SYMBOL_GPL(platform_get_irq_optional);
200 : :
201 : : /**
202 : : * platform_get_irq - get an IRQ for a device
203 : : * @dev: platform device
204 : : * @num: IRQ number index
205 : : *
206 : : * Gets an IRQ for a platform device and prints an error message if finding the
207 : : * IRQ fails. Device drivers should check the return value for errors so as to
208 : : * not pass a negative integer value to the request_irq() APIs.
209 : : *
210 : : * Example:
211 : : * int irq = platform_get_irq(pdev, 0);
212 : : * if (irq < 0)
213 : : * return irq;
214 : : *
215 : : * Return: IRQ number on success, negative error number on failure.
216 : : */
217 : 0 : int platform_get_irq(struct platform_device *dev, unsigned int num)
218 : : {
219 : 0 : int ret;
220 : :
221 : 0 : ret = platform_get_irq_optional(dev, num);
222 [ # # ]: 0 : if (ret < 0 && ret != -EPROBE_DEFER)
223 : 0 : dev_err(&dev->dev, "IRQ index %u not found\n", num);
224 : :
225 : 0 : return ret;
226 : : }
227 : : EXPORT_SYMBOL_GPL(platform_get_irq);
228 : :
229 : : /**
230 : : * platform_irq_count - Count the number of IRQs a platform device uses
231 : : * @dev: platform device
232 : : *
233 : : * Return: Number of IRQs a platform device uses or EPROBE_DEFER
234 : : */
235 : 0 : int platform_irq_count(struct platform_device *dev)
236 : : {
237 : 0 : int ret, nr = 0;
238 : :
239 [ # # ]: 0 : while ((ret = platform_get_irq_optional(dev, nr)) >= 0)
240 : 0 : nr++;
241 : :
242 [ # # ]: 0 : if (ret == -EPROBE_DEFER)
243 : 0 : return ret;
244 : :
245 : : return nr;
246 : : }
247 : : EXPORT_SYMBOL_GPL(platform_irq_count);
248 : :
249 : : /**
250 : : * platform_get_resource_byname - get a resource for a device by name
251 : : * @dev: platform device
252 : : * @type: resource type
253 : : * @name: resource name
254 : : */
255 : 0 : struct resource *platform_get_resource_byname(struct platform_device *dev,
256 : : unsigned int type,
257 : : const char *name)
258 : : {
259 : 0 : u32 i;
260 : :
261 [ # # ]: 0 : for (i = 0; i < dev->num_resources; i++) {
262 : 0 : struct resource *r = &dev->resource[i];
263 : :
264 [ # # ]: 0 : if (unlikely(!r->name))
265 : 0 : continue;
266 : :
267 [ # # # # ]: 0 : if (type == resource_type(r) && !strcmp(r->name, name))
268 : 0 : return r;
269 : : }
270 : : return NULL;
271 : : }
272 : : EXPORT_SYMBOL_GPL(platform_get_resource_byname);
273 : :
274 : 0 : static int __platform_get_irq_byname(struct platform_device *dev,
275 : : const char *name)
276 : : {
277 : 0 : struct resource *r;
278 : 0 : int ret;
279 : :
280 : 0 : if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) {
281 : : ret = of_irq_get_byname(dev->dev.of_node, name);
282 : : if (ret > 0 || ret == -EPROBE_DEFER)
283 : : return ret;
284 : : }
285 : :
286 : 0 : r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name);
287 [ # # # # ]: 0 : if (r)
288 : 0 : return r->start;
289 : :
290 : : return -ENXIO;
291 : : }
292 : :
293 : : /**
294 : : * platform_get_irq_byname - get an IRQ for a device by name
295 : : * @dev: platform device
296 : : * @name: IRQ name
297 : : *
298 : : * Get an IRQ like platform_get_irq(), but then by name rather then by index.
299 : : *
300 : : * Return: IRQ number on success, negative error number on failure.
301 : : */
302 : 0 : int platform_get_irq_byname(struct platform_device *dev, const char *name)
303 : : {
304 : 0 : int ret;
305 : :
306 : 0 : ret = __platform_get_irq_byname(dev, name);
307 [ # # ]: 0 : if (ret < 0 && ret != -EPROBE_DEFER)
308 : 0 : dev_err(&dev->dev, "IRQ %s not found\n", name);
309 : :
310 : 0 : return ret;
311 : : }
312 : : EXPORT_SYMBOL_GPL(platform_get_irq_byname);
313 : :
314 : : /**
315 : : * platform_get_irq_byname_optional - get an optional IRQ for a device by name
316 : : * @dev: platform device
317 : : * @name: IRQ name
318 : : *
319 : : * Get an optional IRQ by name like platform_get_irq_byname(). Except that it
320 : : * does not print an error message if an IRQ can not be obtained.
321 : : *
322 : : * Return: IRQ number on success, negative error number on failure.
323 : : */
324 : 0 : int platform_get_irq_byname_optional(struct platform_device *dev,
325 : : const char *name)
326 : : {
327 : 0 : return __platform_get_irq_byname(dev, name);
328 : : }
329 : : EXPORT_SYMBOL_GPL(platform_get_irq_byname_optional);
330 : :
331 : : /**
332 : : * platform_add_devices - add a numbers of platform devices
333 : : * @devs: array of platform devices to add
334 : : * @num: number of platform devices in array
335 : : */
336 : 0 : int platform_add_devices(struct platform_device **devs, int num)
337 : : {
338 : 0 : int i, ret = 0;
339 : :
340 [ # # ]: 0 : for (i = 0; i < num; i++) {
341 : 0 : ret = platform_device_register(devs[i]);
342 [ # # ]: 0 : if (ret) {
343 [ # # ]: 0 : while (--i >= 0)
344 : 0 : platform_device_unregister(devs[i]);
345 : : break;
346 : : }
347 : : }
348 : :
349 : 0 : return ret;
350 : : }
351 : : EXPORT_SYMBOL_GPL(platform_add_devices);
352 : :
353 : : struct platform_object {
354 : : struct platform_device pdev;
355 : : char name[];
356 : : };
357 : :
358 : : /*
359 : : * Set up default DMA mask for platform devices if the they weren't
360 : : * previously set by the architecture / DT.
361 : : */
362 : 224 : static void setup_pdev_dma_masks(struct platform_device *pdev)
363 : : {
364 : 224 : if (!pdev->dev.coherent_dma_mask)
365 : 224 : pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
366 [ - - + - ]: 224 : if (!pdev->dev.dma_mask) {
367 : 224 : pdev->platform_dma_mask = DMA_BIT_MASK(32);
368 : 224 : pdev->dev.dma_mask = &pdev->platform_dma_mask;
369 : : }
370 : : };
371 : :
372 : : /**
373 : : * platform_device_put - destroy a platform device
374 : : * @pdev: platform device to free
375 : : *
376 : : * Free all memory associated with a platform device. This function must
377 : : * _only_ be externally called in error cases. All other usage is a bug.
378 : : */
379 : 28 : void platform_device_put(struct platform_device *pdev)
380 : : {
381 [ - - - - : 28 : if (!IS_ERR_OR_NULL(pdev))
- + - - -
- ]
382 : 0 : put_device(&pdev->dev);
383 : 0 : }
384 : : EXPORT_SYMBOL_GPL(platform_device_put);
385 : :
386 : 0 : static void platform_device_release(struct device *dev)
387 : : {
388 : 0 : struct platform_object *pa = container_of(dev, struct platform_object,
389 : : pdev.dev);
390 : :
391 : 0 : of_device_node_put(&pa->pdev.dev);
392 : 0 : kfree(pa->pdev.dev.platform_data);
393 : 0 : kfree(pa->pdev.mfd_cell);
394 : 0 : kfree(pa->pdev.resource);
395 : 0 : kfree(pa->pdev.driver_override);
396 : 0 : kfree(pa);
397 : 0 : }
398 : :
399 : : /**
400 : : * platform_device_alloc - create a platform device
401 : : * @name: base name of the device we're adding
402 : : * @id: instance id
403 : : *
404 : : * Create a platform device object which can have other objects attached
405 : : * to it, and which will have attached objects freed when it is released.
406 : : */
407 : 224 : struct platform_device *platform_device_alloc(const char *name, int id)
408 : : {
409 : 224 : struct platform_object *pa;
410 : :
411 : 224 : pa = kzalloc(sizeof(*pa) + strlen(name) + 1, GFP_KERNEL);
412 [ + - ]: 224 : if (pa) {
413 : 224 : strcpy(pa->name, name);
414 : 224 : pa->pdev.name = pa->name;
415 : 224 : pa->pdev.id = id;
416 : 224 : device_initialize(&pa->pdev.dev);
417 : 224 : pa->pdev.dev.release = platform_device_release;
418 [ + - ]: 224 : setup_pdev_dma_masks(&pa->pdev);
419 : : }
420 : :
421 [ + - ]: 224 : return pa ? &pa->pdev : NULL;
422 : : }
423 : : EXPORT_SYMBOL_GPL(platform_device_alloc);
424 : :
425 : : /**
426 : : * platform_device_add_resources - add resources to a platform device
427 : : * @pdev: platform device allocated by platform_device_alloc to add resources to
428 : : * @res: set of resources that needs to be allocated for the device
429 : : * @num: number of resources
430 : : *
431 : : * Add a copy of the resources to the platform device. The memory
432 : : * associated with the resources will be freed when the platform device is
433 : : * released.
434 : : */
435 : 196 : int platform_device_add_resources(struct platform_device *pdev,
436 : : const struct resource *res, unsigned int num)
437 : : {
438 : 196 : struct resource *r = NULL;
439 : :
440 [ + + ]: 196 : if (res) {
441 : 56 : r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL);
442 [ + - ]: 56 : if (!r)
443 : : return -ENOMEM;
444 : : }
445 : :
446 : 196 : kfree(pdev->resource);
447 : 196 : pdev->resource = r;
448 : 196 : pdev->num_resources = num;
449 : 196 : return 0;
450 : : }
451 : : EXPORT_SYMBOL_GPL(platform_device_add_resources);
452 : :
453 : : /**
454 : : * platform_device_add_data - add platform-specific data to a platform device
455 : : * @pdev: platform device allocated by platform_device_alloc to add resources to
456 : : * @data: platform specific data for this platform device
457 : : * @size: size of platform specific data
458 : : *
459 : : * Add a copy of platform specific data to the platform device's
460 : : * platform_data pointer. The memory associated with the platform data
461 : : * will be freed when the platform device is released.
462 : : */
463 : 196 : int platform_device_add_data(struct platform_device *pdev, const void *data,
464 : : size_t size)
465 : : {
466 : 196 : void *d = NULL;
467 : :
468 [ + + ]: 196 : if (data) {
469 : 28 : d = kmemdup(data, size, GFP_KERNEL);
470 [ + - ]: 28 : if (!d)
471 : : return -ENOMEM;
472 : : }
473 : :
474 : 196 : kfree(pdev->dev.platform_data);
475 : 196 : pdev->dev.platform_data = d;
476 : 196 : return 0;
477 : : }
478 : : EXPORT_SYMBOL_GPL(platform_device_add_data);
479 : :
480 : : /**
481 : : * platform_device_add_properties - add built-in properties to a platform device
482 : : * @pdev: platform device to add properties to
483 : : * @properties: null terminated array of properties to add
484 : : *
485 : : * The function will take deep copy of @properties and attach the copy to the
486 : : * platform device. The memory associated with properties will be freed when the
487 : : * platform device is released.
488 : : */
489 : 0 : int platform_device_add_properties(struct platform_device *pdev,
490 : : const struct property_entry *properties)
491 : : {
492 : 0 : return device_add_properties(&pdev->dev, properties);
493 : : }
494 : : EXPORT_SYMBOL_GPL(platform_device_add_properties);
495 : :
496 : : /**
497 : : * platform_device_add - add a platform device to device hierarchy
498 : : * @pdev: platform device we're adding
499 : : *
500 : : * This is part 2 of platform_device_register(), though may be called
501 : : * separately _iff_ pdev was allocated by platform_device_alloc().
502 : : */
503 : 224 : int platform_device_add(struct platform_device *pdev)
504 : : {
505 : 224 : u32 i;
506 : 224 : int ret;
507 : :
508 [ + - ]: 224 : if (!pdev)
509 : : return -EINVAL;
510 : :
511 [ + + ]: 224 : if (!pdev->dev.parent)
512 : 168 : pdev->dev.parent = &platform_bus;
513 : :
514 : 224 : pdev->dev.bus = &platform_bus_type;
515 : :
516 [ + + + ]: 224 : switch (pdev->id) {
517 : 56 : default:
518 : 56 : dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
519 : 56 : break;
520 : 140 : case PLATFORM_DEVID_NONE:
521 : 140 : dev_set_name(&pdev->dev, "%s", pdev->name);
522 : 140 : break;
523 : 28 : case PLATFORM_DEVID_AUTO:
524 : : /*
525 : : * Automatically allocated device ID. We mark it as such so
526 : : * that we remember it must be freed, and we append a suffix
527 : : * to avoid namespace collision with explicit IDs.
528 : : */
529 : 28 : ret = ida_simple_get(&platform_devid_ida, 0, 0, GFP_KERNEL);
530 [ - + ]: 28 : if (ret < 0)
531 : 0 : goto err_out;
532 : 28 : pdev->id = ret;
533 : 28 : pdev->id_auto = true;
534 : 28 : dev_set_name(&pdev->dev, "%s.%d.auto", pdev->name, pdev->id);
535 : 28 : break;
536 : : }
537 : :
538 [ + + ]: 280 : for (i = 0; i < pdev->num_resources; i++) {
539 : 56 : struct resource *p, *r = &pdev->resource[i];
540 : :
541 [ + - ]: 56 : if (r->name == NULL)
542 [ + - ]: 112 : r->name = dev_name(&pdev->dev);
543 : :
544 : 56 : p = r->parent;
545 [ + - ]: 56 : if (!p) {
546 [ + + ]: 56 : if (resource_type(r) == IORESOURCE_MEM)
547 : : p = &iomem_resource;
548 [ + - ]: 28 : else if (resource_type(r) == IORESOURCE_IO)
549 : 28 : p = &ioport_resource;
550 : : }
551 : :
552 [ + - ]: 56 : if (p) {
553 : 56 : ret = insert_resource(p, r);
554 [ - + ]: 56 : if (ret) {
555 : 0 : dev_err(&pdev->dev, "failed to claim resource %d: %pR\n", i, r);
556 : 0 : goto failed;
557 : : }
558 : : }
559 : : }
560 : :
561 : 224 : pr_debug("Registering platform device '%s'. Parent at %s\n",
562 : : dev_name(&pdev->dev), dev_name(pdev->dev.parent));
563 : :
564 : 224 : ret = device_add(&pdev->dev);
565 [ - + ]: 224 : if (ret == 0)
566 : : return ret;
567 : :
568 : 0 : failed:
569 [ # # ]: 0 : if (pdev->id_auto) {
570 : 0 : ida_simple_remove(&platform_devid_ida, pdev->id);
571 : 0 : pdev->id = PLATFORM_DEVID_AUTO;
572 : : }
573 : :
574 [ # # ]: 0 : while (i--) {
575 : 0 : struct resource *r = &pdev->resource[i];
576 [ # # ]: 0 : if (r->parent)
577 : 0 : release_resource(r);
578 : : }
579 : :
580 : 0 : err_out:
581 : : return ret;
582 : : }
583 : : EXPORT_SYMBOL_GPL(platform_device_add);
584 : :
585 : : /**
586 : : * platform_device_del - remove a platform-level device
587 : : * @pdev: platform device we're removing
588 : : *
589 : : * Note that this function will also release all memory- and port-based
590 : : * resources owned by the device (@dev->resource). This function must
591 : : * _only_ be externally called in error cases. All other usage is a bug.
592 : : */
593 : 28 : void platform_device_del(struct platform_device *pdev)
594 : : {
595 : 28 : u32 i;
596 : :
597 [ - + - + ]: 28 : if (!IS_ERR_OR_NULL(pdev)) {
598 : 0 : device_del(&pdev->dev);
599 : :
600 [ # # ]: 0 : if (pdev->id_auto) {
601 : 0 : ida_simple_remove(&platform_devid_ida, pdev->id);
602 : 0 : pdev->id = PLATFORM_DEVID_AUTO;
603 : : }
604 : :
605 [ # # ]: 0 : for (i = 0; i < pdev->num_resources; i++) {
606 : 0 : struct resource *r = &pdev->resource[i];
607 [ # # ]: 0 : if (r->parent)
608 : 0 : release_resource(r);
609 : : }
610 : : }
611 : 28 : }
612 : : EXPORT_SYMBOL_GPL(platform_device_del);
613 : :
614 : : /**
615 : : * platform_device_register - add a platform-level device
616 : : * @pdev: platform device we're adding
617 : : */
618 : 0 : int platform_device_register(struct platform_device *pdev)
619 : : {
620 : 0 : device_initialize(&pdev->dev);
621 [ # # ]: 0 : setup_pdev_dma_masks(pdev);
622 : 0 : return platform_device_add(pdev);
623 : : }
624 : : EXPORT_SYMBOL_GPL(platform_device_register);
625 : :
626 : : /**
627 : : * platform_device_unregister - unregister a platform-level device
628 : : * @pdev: platform device we're unregistering
629 : : *
630 : : * Unregistration is done in 2 steps. First we release all resources
631 : : * and remove it from the subsystem, then we drop reference count by
632 : : * calling platform_device_put().
633 : : */
634 : 28 : void platform_device_unregister(struct platform_device *pdev)
635 : : {
636 : 28 : platform_device_del(pdev);
637 [ - + ]: 28 : platform_device_put(pdev);
638 : 28 : }
639 : : EXPORT_SYMBOL_GPL(platform_device_unregister);
640 : :
641 : : /**
642 : : * platform_device_register_full - add a platform-level device with
643 : : * resources and platform-specific data
644 : : *
645 : : * @pdevinfo: data used to create device
646 : : *
647 : : * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
648 : : */
649 : 168 : struct platform_device *platform_device_register_full(
650 : : const struct platform_device_info *pdevinfo)
651 : : {
652 : 168 : int ret = -ENOMEM;
653 : 168 : struct platform_device *pdev;
654 : :
655 : 168 : pdev = platform_device_alloc(pdevinfo->name, pdevinfo->id);
656 [ + - ]: 168 : if (!pdev)
657 : : return ERR_PTR(-ENOMEM);
658 : :
659 : 168 : pdev->dev.parent = pdevinfo->parent;
660 : 168 : pdev->dev.fwnode = pdevinfo->fwnode;
661 [ + + ]: 168 : pdev->dev.of_node = of_node_get(to_of_node(pdev->dev.fwnode));
662 : 168 : pdev->dev.of_node_reused = pdevinfo->of_node_reused;
663 : :
664 [ + + ]: 168 : if (pdevinfo->dma_mask) {
665 : 56 : pdev->platform_dma_mask = pdevinfo->dma_mask;
666 : 56 : pdev->dev.dma_mask = &pdev->platform_dma_mask;
667 : 56 : pdev->dev.coherent_dma_mask = pdevinfo->dma_mask;
668 : : }
669 : :
670 : 168 : ret = platform_device_add_resources(pdev,
671 : : pdevinfo->res, pdevinfo->num_res);
672 [ - + ]: 168 : if (ret)
673 : 0 : goto err;
674 : :
675 : 168 : ret = platform_device_add_data(pdev,
676 : : pdevinfo->data, pdevinfo->size_data);
677 [ - + ]: 168 : if (ret)
678 : 0 : goto err;
679 : :
680 [ - + ]: 168 : if (pdevinfo->properties) {
681 : 0 : ret = platform_device_add_properties(pdev,
682 : : pdevinfo->properties);
683 [ # # ]: 0 : if (ret)
684 : 0 : goto err;
685 : : }
686 : :
687 : 168 : ret = platform_device_add(pdev);
688 [ - + ]: 168 : if (ret) {
689 : 0 : err:
690 : 0 : ACPI_COMPANION_SET(&pdev->dev, NULL);
691 [ # # ]: 0 : platform_device_put(pdev);
692 : 0 : return ERR_PTR(ret);
693 : : }
694 : :
695 : : return pdev;
696 : : }
697 : : EXPORT_SYMBOL_GPL(platform_device_register_full);
698 : :
699 : 84 : static int platform_drv_probe(struct device *_dev)
700 : : {
701 : 84 : struct platform_driver *drv = to_platform_driver(_dev->driver);
702 : 84 : struct platform_device *dev = to_platform_device(_dev);
703 : 84 : int ret;
704 : :
705 : 84 : ret = of_clk_set_defaults(_dev->of_node, false);
706 : 84 : if (ret < 0)
707 : : return ret;
708 : :
709 : 84 : ret = dev_pm_domain_attach(_dev, true);
710 [ - + ]: 84 : if (ret)
711 : 0 : goto out;
712 : :
713 [ + + ]: 84 : if (drv->probe) {
714 : 56 : ret = drv->probe(dev);
715 [ + - ]: 56 : if (ret)
716 : 0 : dev_pm_domain_detach(_dev, true);
717 : : }
718 : :
719 : 84 : out:
720 [ + + - + ]: 84 : if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) {
721 : 0 : dev_warn(_dev, "probe deferral not supported\n");
722 : 0 : ret = -ENXIO;
723 : : }
724 : :
725 : 84 : return ret;
726 : : }
727 : :
728 : 0 : static int platform_drv_probe_fail(struct device *_dev)
729 : : {
730 : 0 : return -ENXIO;
731 : : }
732 : :
733 : 0 : static int platform_drv_remove(struct device *_dev)
734 : : {
735 : 0 : struct platform_driver *drv = to_platform_driver(_dev->driver);
736 : 0 : struct platform_device *dev = to_platform_device(_dev);
737 : 0 : int ret = 0;
738 : :
739 [ # # ]: 0 : if (drv->remove)
740 : 0 : ret = drv->remove(dev);
741 : 0 : dev_pm_domain_detach(_dev, true);
742 : :
743 : 0 : return ret;
744 : : }
745 : :
746 : 0 : static void platform_drv_shutdown(struct device *_dev)
747 : : {
748 : 0 : struct platform_driver *drv = to_platform_driver(_dev->driver);
749 : 0 : struct platform_device *dev = to_platform_device(_dev);
750 : :
751 [ # # ]: 0 : if (drv->shutdown)
752 : 0 : drv->shutdown(dev);
753 : 0 : }
754 : :
755 : : /**
756 : : * __platform_driver_register - register a driver for platform-level devices
757 : : * @drv: platform driver structure
758 : : * @owner: owning module/driver
759 : : */
760 : 308 : int __platform_driver_register(struct platform_driver *drv,
761 : : struct module *owner)
762 : : {
763 : 308 : drv->driver.owner = owner;
764 : 308 : drv->driver.bus = &platform_bus_type;
765 : 308 : drv->driver.probe = platform_drv_probe;
766 : 308 : drv->driver.remove = platform_drv_remove;
767 : 308 : drv->driver.shutdown = platform_drv_shutdown;
768 : :
769 : 280 : return driver_register(&drv->driver);
770 : : }
771 : : EXPORT_SYMBOL_GPL(__platform_driver_register);
772 : :
773 : : /**
774 : : * platform_driver_unregister - unregister a driver for platform-level devices
775 : : * @drv: platform driver structure
776 : : */
777 : 28 : void platform_driver_unregister(struct platform_driver *drv)
778 : : {
779 : 28 : driver_unregister(&drv->driver);
780 : 0 : }
781 : : EXPORT_SYMBOL_GPL(platform_driver_unregister);
782 : :
783 : : /**
784 : : * __platform_driver_probe - register driver for non-hotpluggable device
785 : : * @drv: platform driver structure
786 : : * @probe: the driver probe routine, probably from an __init section
787 : : * @module: module which will be the owner of the driver
788 : : *
789 : : * Use this instead of platform_driver_register() when you know the device
790 : : * is not hotpluggable and has already been registered, and you want to
791 : : * remove its run-once probe() infrastructure from memory after the driver
792 : : * has bound to the device.
793 : : *
794 : : * One typical use for this would be with drivers for controllers integrated
795 : : * into system-on-chip processors, where the controller devices have been
796 : : * configured as part of board setup.
797 : : *
798 : : * Note that this is incompatible with deferred probing.
799 : : *
800 : : * Returns zero if the driver registered and bound to a device, else returns
801 : : * a negative error code and with the driver not registered.
802 : : */
803 : 28 : int __init_or_module __platform_driver_probe(struct platform_driver *drv,
804 : : int (*probe)(struct platform_device *), struct module *module)
805 : : {
806 : 28 : int retval, code;
807 : :
808 [ - + ]: 28 : if (drv->driver.probe_type == PROBE_PREFER_ASYNCHRONOUS) {
809 : 0 : pr_err("%s: drivers registered with %s can not be probed asynchronously\n",
810 : : drv->driver.name, __func__);
811 : 0 : return -EINVAL;
812 : : }
813 : :
814 : : /*
815 : : * We have to run our probes synchronously because we check if
816 : : * we find any devices to bind to and exit with error if there
817 : : * are any.
818 : : */
819 : 28 : drv->driver.probe_type = PROBE_FORCE_SYNCHRONOUS;
820 : :
821 : : /*
822 : : * Prevent driver from requesting probe deferral to avoid further
823 : : * futile probe attempts.
824 : : */
825 : 28 : drv->prevent_deferred_probe = true;
826 : :
827 : : /* make sure driver won't have bind/unbind attributes */
828 : 28 : drv->driver.suppress_bind_attrs = true;
829 : :
830 : : /* temporary section violation during probe() */
831 : 28 : drv->probe = probe;
832 : 28 : retval = code = __platform_driver_register(drv, module);
833 : :
834 : : /*
835 : : * Fixup that section violation, being paranoid about code scanning
836 : : * the list of drivers in order to probe new devices. Check to see
837 : : * if the probe was successful, and make sure any forced probes of
838 : : * new devices fail.
839 : : */
840 : 28 : spin_lock(&drv->driver.bus->p->klist_drivers.k_lock);
841 : 28 : drv->probe = NULL;
842 [ + - - + ]: 28 : if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list))
843 : 0 : retval = -ENODEV;
844 : 28 : drv->driver.probe = platform_drv_probe_fail;
845 : 28 : spin_unlock(&drv->driver.bus->p->klist_drivers.k_lock);
846 : :
847 [ - + ]: 28 : if (code != retval)
848 : 0 : platform_driver_unregister(drv);
849 : : return retval;
850 : : }
851 : : EXPORT_SYMBOL_GPL(__platform_driver_probe);
852 : :
853 : : /**
854 : : * __platform_create_bundle - register driver and create corresponding device
855 : : * @driver: platform driver structure
856 : : * @probe: the driver probe routine, probably from an __init section
857 : : * @res: set of resources that needs to be allocated for the device
858 : : * @n_res: number of resources
859 : : * @data: platform specific data for this platform device
860 : : * @size: size of platform specific data
861 : : * @module: module which will be the owner of the driver
862 : : *
863 : : * Use this in legacy-style modules that probe hardware directly and
864 : : * register a single platform device and corresponding platform driver.
865 : : *
866 : : * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
867 : : */
868 : 28 : struct platform_device * __init_or_module __platform_create_bundle(
869 : : struct platform_driver *driver,
870 : : int (*probe)(struct platform_device *),
871 : : struct resource *res, unsigned int n_res,
872 : : const void *data, size_t size, struct module *module)
873 : : {
874 : 28 : struct platform_device *pdev;
875 : 28 : int error;
876 : :
877 : 28 : pdev = platform_device_alloc(driver->driver.name, -1);
878 [ - + ]: 28 : if (!pdev) {
879 : 0 : error = -ENOMEM;
880 : 0 : goto err_out;
881 : : }
882 : :
883 : 28 : error = platform_device_add_resources(pdev, res, n_res);
884 [ - + ]: 28 : if (error)
885 : 0 : goto err_pdev_put;
886 : :
887 : 28 : error = platform_device_add_data(pdev, data, size);
888 [ - + ]: 28 : if (error)
889 : 0 : goto err_pdev_put;
890 : :
891 : 28 : error = platform_device_add(pdev);
892 [ - + ]: 28 : if (error)
893 : 0 : goto err_pdev_put;
894 : :
895 : 28 : error = __platform_driver_probe(driver, probe, module);
896 [ - + ]: 28 : if (error)
897 : 0 : goto err_pdev_del;
898 : :
899 : : return pdev;
900 : :
901 : : err_pdev_del:
902 : 0 : platform_device_del(pdev);
903 : 0 : err_pdev_put:
904 [ # # ]: 0 : platform_device_put(pdev);
905 : 0 : err_out:
906 : 0 : return ERR_PTR(error);
907 : : }
908 : : EXPORT_SYMBOL_GPL(__platform_create_bundle);
909 : :
910 : : /**
911 : : * __platform_register_drivers - register an array of platform drivers
912 : : * @drivers: an array of drivers to register
913 : : * @count: the number of drivers to register
914 : : * @owner: module owning the drivers
915 : : *
916 : : * Registers platform drivers specified by an array. On failure to register a
917 : : * driver, all previously registered drivers will be unregistered. Callers of
918 : : * this API should use platform_unregister_drivers() to unregister drivers in
919 : : * the reverse order.
920 : : *
921 : : * Returns: 0 on success or a negative error code on failure.
922 : : */
923 : 0 : int __platform_register_drivers(struct platform_driver * const *drivers,
924 : : unsigned int count, struct module *owner)
925 : : {
926 : 0 : unsigned int i;
927 : 0 : int err;
928 : :
929 [ # # ]: 0 : for (i = 0; i < count; i++) {
930 : 0 : pr_debug("registering platform driver %ps\n", drivers[i]);
931 : :
932 : 0 : err = __platform_driver_register(drivers[i], owner);
933 [ # # ]: 0 : if (err < 0) {
934 : 0 : pr_err("failed to register platform driver %ps: %d\n",
935 : : drivers[i], err);
936 : 0 : goto error;
937 : : }
938 : : }
939 : :
940 : : return 0;
941 : :
942 : : error:
943 [ # # ]: 0 : while (i--) {
944 : 0 : pr_debug("unregistering platform driver %ps\n", drivers[i]);
945 : 0 : platform_driver_unregister(drivers[i]);
946 : : }
947 : :
948 : : return err;
949 : : }
950 : : EXPORT_SYMBOL_GPL(__platform_register_drivers);
951 : :
952 : : /**
953 : : * platform_unregister_drivers - unregister an array of platform drivers
954 : : * @drivers: an array of drivers to unregister
955 : : * @count: the number of drivers to unregister
956 : : *
957 : : * Unegisters platform drivers specified by an array. This is typically used
958 : : * to complement an earlier call to platform_register_drivers(). Drivers are
959 : : * unregistered in the reverse order in which they were registered.
960 : : */
961 : 0 : void platform_unregister_drivers(struct platform_driver * const *drivers,
962 : : unsigned int count)
963 : : {
964 [ # # ]: 0 : while (count--) {
965 : 0 : pr_debug("unregistering platform driver %ps\n", drivers[count]);
966 : 0 : platform_driver_unregister(drivers[count]);
967 : : }
968 : 0 : }
969 : : EXPORT_SYMBOL_GPL(platform_unregister_drivers);
970 : :
971 : : /* modalias support enables more hands-off userspace setup:
972 : : * (a) environment variable lets new-style hotplug events work once system is
973 : : * fully running: "modprobe $MODALIAS"
974 : : * (b) sysfs attribute lets new-style coldplug recover from hotplug events
975 : : * mishandled before system is fully running: "modprobe $(cat modalias)"
976 : : */
977 : 28 : static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
978 : : char *buf)
979 : : {
980 : 28 : struct platform_device *pdev = to_platform_device(dev);
981 : 28 : int len;
982 : :
983 : 28 : len = of_device_modalias(dev, buf, PAGE_SIZE);
984 : 28 : if (len != -ENODEV)
985 : : return len;
986 : :
987 : 28 : len = acpi_device_modalias(dev, buf, PAGE_SIZE -1);
988 [ + - ]: 28 : if (len != -ENODEV)
989 : 28 : return len;
990 : :
991 : 0 : len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name);
992 : :
993 [ # # ]: 0 : return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
994 : : }
995 : : static DEVICE_ATTR_RO(modalias);
996 : :
997 : 0 : static ssize_t driver_override_store(struct device *dev,
998 : : struct device_attribute *attr,
999 : : const char *buf, size_t count)
1000 : : {
1001 : 0 : struct platform_device *pdev = to_platform_device(dev);
1002 : 0 : char *driver_override, *old, *cp;
1003 : :
1004 : : /* We need to keep extra room for a newline */
1005 [ # # ]: 0 : if (count >= (PAGE_SIZE - 1))
1006 : : return -EINVAL;
1007 : :
1008 : 0 : driver_override = kstrndup(buf, count, GFP_KERNEL);
1009 [ # # ]: 0 : if (!driver_override)
1010 : : return -ENOMEM;
1011 : :
1012 : 0 : cp = strchr(driver_override, '\n');
1013 [ # # ]: 0 : if (cp)
1014 : 0 : *cp = '\0';
1015 : :
1016 : 0 : device_lock(dev);
1017 : 0 : old = pdev->driver_override;
1018 [ # # ]: 0 : if (strlen(driver_override)) {
1019 : 0 : pdev->driver_override = driver_override;
1020 : : } else {
1021 : 0 : kfree(driver_override);
1022 : 0 : pdev->driver_override = NULL;
1023 : : }
1024 : 0 : device_unlock(dev);
1025 : :
1026 : 0 : kfree(old);
1027 : :
1028 : 0 : return count;
1029 : : }
1030 : :
1031 : 0 : static ssize_t driver_override_show(struct device *dev,
1032 : : struct device_attribute *attr, char *buf)
1033 : : {
1034 : 0 : struct platform_device *pdev = to_platform_device(dev);
1035 : 0 : ssize_t len;
1036 : :
1037 : 0 : device_lock(dev);
1038 : 0 : len = sprintf(buf, "%s\n", pdev->driver_override);
1039 : 0 : device_unlock(dev);
1040 : 0 : return len;
1041 : : }
1042 : : static DEVICE_ATTR_RW(driver_override);
1043 : :
1044 : :
1045 : : static struct attribute *platform_dev_attrs[] = {
1046 : : &dev_attr_modalias.attr,
1047 : : &dev_attr_driver_override.attr,
1048 : : NULL,
1049 : : };
1050 : : ATTRIBUTE_GROUPS(platform_dev);
1051 : :
1052 : 1260 : static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
1053 : : {
1054 : 1260 : struct platform_device *pdev = to_platform_device(dev);
1055 : 1260 : int rc;
1056 : :
1057 : : /* Some devices have extra OF data and an OF-style MODALIAS */
1058 : 1260 : rc = of_device_uevent_modalias(dev, env);
1059 : 1260 : if (rc != -ENODEV)
1060 : : return rc;
1061 : :
1062 : 1260 : rc = acpi_device_uevent_modalias(dev, env);
1063 [ + + ]: 1260 : if (rc != -ENODEV)
1064 : : return rc;
1065 : :
1066 : 1036 : add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX,
1067 : : pdev->name);
1068 : 1036 : return 0;
1069 : : }
1070 : :
1071 : : static const struct platform_device_id *platform_match_id(
1072 : : const struct platform_device_id *id,
1073 : : struct platform_device *pdev)
1074 : : {
1075 [ + + ]: 448 : while (id->name[0]) {
1076 [ - + ]: 224 : if (strcmp(pdev->name, id->name) == 0) {
1077 : 0 : pdev->id_entry = id;
1078 : 0 : return id;
1079 : : }
1080 : 224 : id++;
1081 : : }
1082 : : return NULL;
1083 : : }
1084 : :
1085 : : /**
1086 : : * platform_match - bind platform device to platform driver.
1087 : : * @dev: device.
1088 : : * @drv: driver.
1089 : : *
1090 : : * Platform device IDs are assumed to be encoded like this:
1091 : : * "<name><instance>", where <name> is a short description of the type of
1092 : : * device, like "pci" or "floppy", and <instance> is the enumerated
1093 : : * instance of the device, like '0' or '42'. Driver IDs are simply
1094 : : * "<name>". So, extract the <name> from the platform_device structure,
1095 : : * and compare it against the name of the driver. Return whether they match
1096 : : * or not.
1097 : : */
1098 : 2240 : static int platform_match(struct device *dev, struct device_driver *drv)
1099 : : {
1100 : 2240 : struct platform_device *pdev = to_platform_device(dev);
1101 : 2240 : struct platform_driver *pdrv = to_platform_driver(drv);
1102 : :
1103 : : /* When driver_override is set, only bind to the matching driver */
1104 [ - + ]: 2240 : if (pdev->driver_override)
1105 : 0 : return !strcmp(pdev->driver_override, drv->name);
1106 : :
1107 : : /* Attempt an OF style match first */
1108 : 2240 : if (of_driver_match_device(dev, drv))
1109 : : return 1;
1110 : :
1111 : : /* Then try ACPI style match */
1112 [ + - ]: 2240 : if (acpi_driver_match_device(dev, drv))
1113 : : return 1;
1114 : :
1115 : : /* Then try to match against the id table */
1116 [ + + ]: 2240 : if (pdrv->id_table)
1117 : 224 : return platform_match_id(pdrv->id_table, pdev) != NULL;
1118 : :
1119 : : /* fall-back to driver name match */
1120 : 2016 : return (strcmp(pdev->name, drv->name) == 0);
1121 : : }
1122 : :
1123 : : #ifdef CONFIG_PM_SLEEP
1124 : :
1125 : 0 : static int platform_legacy_suspend(struct device *dev, pm_message_t mesg)
1126 : : {
1127 : 0 : struct platform_driver *pdrv = to_platform_driver(dev->driver);
1128 : 0 : struct platform_device *pdev = to_platform_device(dev);
1129 : 0 : int ret = 0;
1130 : :
1131 : 0 : if (dev->driver && pdrv->suspend)
1132 : 0 : ret = pdrv->suspend(pdev, mesg);
1133 : :
1134 : 0 : return ret;
1135 : : }
1136 : :
1137 : 0 : static int platform_legacy_resume(struct device *dev)
1138 : : {
1139 : 0 : struct platform_driver *pdrv = to_platform_driver(dev->driver);
1140 : 0 : struct platform_device *pdev = to_platform_device(dev);
1141 : 0 : int ret = 0;
1142 : :
1143 : 0 : if (dev->driver && pdrv->resume)
1144 : 0 : ret = pdrv->resume(pdev);
1145 : :
1146 : : return ret;
1147 : : }
1148 : :
1149 : : #endif /* CONFIG_PM_SLEEP */
1150 : :
1151 : : #ifdef CONFIG_SUSPEND
1152 : :
1153 : 0 : int platform_pm_suspend(struct device *dev)
1154 : : {
1155 : 0 : struct device_driver *drv = dev->driver;
1156 : 0 : int ret = 0;
1157 : :
1158 [ # # ]: 0 : if (!drv)
1159 : : return 0;
1160 : :
1161 [ # # ]: 0 : if (drv->pm) {
1162 [ # # ]: 0 : if (drv->pm->suspend)
1163 : 0 : ret = drv->pm->suspend(dev);
1164 : : } else {
1165 [ # # ]: 0 : ret = platform_legacy_suspend(dev, PMSG_SUSPEND);
1166 : : }
1167 : :
1168 : : return ret;
1169 : : }
1170 : :
1171 : 0 : int platform_pm_resume(struct device *dev)
1172 : : {
1173 : 0 : struct device_driver *drv = dev->driver;
1174 : 0 : int ret = 0;
1175 : :
1176 [ # # ]: 0 : if (!drv)
1177 : : return 0;
1178 : :
1179 [ # # ]: 0 : if (drv->pm) {
1180 [ # # ]: 0 : if (drv->pm->resume)
1181 : 0 : ret = drv->pm->resume(dev);
1182 : : } else {
1183 [ # # ]: 0 : ret = platform_legacy_resume(dev);
1184 : : }
1185 : :
1186 : : return ret;
1187 : : }
1188 : :
1189 : : #endif /* CONFIG_SUSPEND */
1190 : :
1191 : : #ifdef CONFIG_HIBERNATE_CALLBACKS
1192 : :
1193 : 0 : int platform_pm_freeze(struct device *dev)
1194 : : {
1195 : 0 : struct device_driver *drv = dev->driver;
1196 : 0 : int ret = 0;
1197 : :
1198 [ # # ]: 0 : if (!drv)
1199 : : return 0;
1200 : :
1201 [ # # ]: 0 : if (drv->pm) {
1202 [ # # ]: 0 : if (drv->pm->freeze)
1203 : 0 : ret = drv->pm->freeze(dev);
1204 : : } else {
1205 [ # # ]: 0 : ret = platform_legacy_suspend(dev, PMSG_FREEZE);
1206 : : }
1207 : :
1208 : : return ret;
1209 : : }
1210 : :
1211 : 0 : int platform_pm_thaw(struct device *dev)
1212 : : {
1213 : 0 : struct device_driver *drv = dev->driver;
1214 : 0 : int ret = 0;
1215 : :
1216 [ # # ]: 0 : if (!drv)
1217 : : return 0;
1218 : :
1219 [ # # ]: 0 : if (drv->pm) {
1220 [ # # ]: 0 : if (drv->pm->thaw)
1221 : 0 : ret = drv->pm->thaw(dev);
1222 : : } else {
1223 [ # # ]: 0 : ret = platform_legacy_resume(dev);
1224 : : }
1225 : :
1226 : : return ret;
1227 : : }
1228 : :
1229 : 0 : int platform_pm_poweroff(struct device *dev)
1230 : : {
1231 : 0 : struct device_driver *drv = dev->driver;
1232 : 0 : int ret = 0;
1233 : :
1234 [ # # ]: 0 : if (!drv)
1235 : : return 0;
1236 : :
1237 [ # # ]: 0 : if (drv->pm) {
1238 [ # # ]: 0 : if (drv->pm->poweroff)
1239 : 0 : ret = drv->pm->poweroff(dev);
1240 : : } else {
1241 [ # # ]: 0 : ret = platform_legacy_suspend(dev, PMSG_HIBERNATE);
1242 : : }
1243 : :
1244 : : return ret;
1245 : : }
1246 : :
1247 : 0 : int platform_pm_restore(struct device *dev)
1248 : : {
1249 : 0 : struct device_driver *drv = dev->driver;
1250 : 0 : int ret = 0;
1251 : :
1252 [ # # ]: 0 : if (!drv)
1253 : : return 0;
1254 : :
1255 [ # # ]: 0 : if (drv->pm) {
1256 [ # # ]: 0 : if (drv->pm->restore)
1257 : 0 : ret = drv->pm->restore(dev);
1258 : : } else {
1259 [ # # ]: 0 : ret = platform_legacy_resume(dev);
1260 : : }
1261 : :
1262 : : return ret;
1263 : : }
1264 : :
1265 : : #endif /* CONFIG_HIBERNATE_CALLBACKS */
1266 : :
1267 : 84 : int platform_dma_configure(struct device *dev)
1268 : : {
1269 : 84 : enum dev_dma_attr attr;
1270 : 84 : int ret = 0;
1271 : :
1272 [ + - ]: 84 : if (dev->of_node) {
1273 : : ret = of_dma_configure(dev, dev->of_node, true);
1274 [ - + ]: 84 : } else if (has_acpi_companion(dev)) {
1275 [ # # ]: 0 : attr = acpi_get_dma_attr(to_acpi_device_node(dev->fwnode));
1276 : 0 : ret = acpi_dma_configure(dev, attr);
1277 : : }
1278 : :
1279 : 84 : return ret;
1280 : : }
1281 : :
1282 : : static const struct dev_pm_ops platform_dev_pm_ops = {
1283 : : .runtime_suspend = pm_generic_runtime_suspend,
1284 : : .runtime_resume = pm_generic_runtime_resume,
1285 : : USE_PLATFORM_PM_SLEEP_OPS
1286 : : };
1287 : :
1288 : : struct bus_type platform_bus_type = {
1289 : : .name = "platform",
1290 : : .dev_groups = platform_dev_groups,
1291 : : .match = platform_match,
1292 : : .uevent = platform_uevent,
1293 : : .dma_configure = platform_dma_configure,
1294 : : .pm = &platform_dev_pm_ops,
1295 : : };
1296 : : EXPORT_SYMBOL_GPL(platform_bus_type);
1297 : :
1298 : 0 : static inline int __platform_match(struct device *dev, const void *drv)
1299 : : {
1300 : 0 : return platform_match(dev, (struct device_driver *)drv);
1301 : : }
1302 : :
1303 : : /**
1304 : : * platform_find_device_by_driver - Find a platform device with a given
1305 : : * driver.
1306 : : * @start: The device to start the search from.
1307 : : * @drv: The device driver to look for.
1308 : : */
1309 : 0 : struct device *platform_find_device_by_driver(struct device *start,
1310 : : const struct device_driver *drv)
1311 : : {
1312 : 0 : return bus_find_device(&platform_bus_type, start, drv,
1313 : : __platform_match);
1314 : : }
1315 : : EXPORT_SYMBOL_GPL(platform_find_device_by_driver);
1316 : :
1317 : 28 : void __weak __init early_platform_cleanup(void) { }
1318 : :
1319 : 28 : int __init platform_bus_init(void)
1320 : : {
1321 : 28 : int error;
1322 : :
1323 : 28 : early_platform_cleanup();
1324 : :
1325 : 28 : error = device_register(&platform_bus);
1326 [ - + ]: 28 : if (error) {
1327 : 0 : put_device(&platform_bus);
1328 : 0 : return error;
1329 : : }
1330 : 28 : error = bus_register(&platform_bus_type);
1331 [ - + ]: 28 : if (error)
1332 : 0 : device_unregister(&platform_bus);
1333 : : of_platform_register_reconfig_notifier();
1334 : : return error;
1335 : : }
|