.. | .. |
---|
5 | 5 | * Copyright (c) 2002-3 Patrick Mochel |
---|
6 | 6 | * Copyright (c) 2002-3 Open Source Development Labs |
---|
7 | 7 | * |
---|
8 | | - * Please see Documentation/driver-model/platform.txt for more |
---|
| 8 | + * Please see Documentation/driver-api/driver-model/platform.rst for more |
---|
9 | 9 | * information. |
---|
10 | 10 | */ |
---|
11 | 11 | |
---|
.. | .. |
---|
16 | 16 | #include <linux/module.h> |
---|
17 | 17 | #include <linux/init.h> |
---|
18 | 18 | #include <linux/dma-mapping.h> |
---|
19 | | -#include <linux/bootmem.h> |
---|
| 19 | +#include <linux/memblock.h> |
---|
20 | 20 | #include <linux/err.h> |
---|
21 | 21 | #include <linux/slab.h> |
---|
22 | 22 | #include <linux/pm_runtime.h> |
---|
.. | .. |
---|
41 | 41 | EXPORT_SYMBOL_GPL(platform_bus); |
---|
42 | 42 | |
---|
43 | 43 | /** |
---|
44 | | - * arch_setup_pdev_archdata - Allow manipulation of archdata before its used |
---|
45 | | - * @pdev: platform device |
---|
46 | | - * |
---|
47 | | - * This is called before platform_device_add() such that any pdev_archdata may |
---|
48 | | - * be setup before the platform_notifier is called. So if a user needs to |
---|
49 | | - * manipulate any relevant information in the pdev_archdata they can do: |
---|
50 | | - * |
---|
51 | | - * platform_device_alloc() |
---|
52 | | - * ... manipulate ... |
---|
53 | | - * platform_device_add() |
---|
54 | | - * |
---|
55 | | - * And if they don't care they can just call platform_device_register() and |
---|
56 | | - * everything will just work out. |
---|
57 | | - */ |
---|
58 | | -void __weak arch_setup_pdev_archdata(struct platform_device *pdev) |
---|
59 | | -{ |
---|
60 | | -} |
---|
61 | | - |
---|
62 | | -/** |
---|
63 | 44 | * platform_get_resource - get a resource for a device |
---|
64 | 45 | * @dev: platform device |
---|
65 | 46 | * @type: resource type |
---|
66 | 47 | * @num: resource index |
---|
| 48 | + * |
---|
| 49 | + * Return: a pointer to the resource or NULL on failure. |
---|
67 | 50 | */ |
---|
68 | 51 | struct resource *platform_get_resource(struct platform_device *dev, |
---|
69 | 52 | unsigned int type, unsigned int num) |
---|
.. | .. |
---|
80 | 63 | } |
---|
81 | 64 | EXPORT_SYMBOL_GPL(platform_get_resource); |
---|
82 | 65 | |
---|
| 66 | +#ifdef CONFIG_HAS_IOMEM |
---|
83 | 67 | /** |
---|
84 | 68 | * devm_platform_get_and_ioremap_resource - call devm_ioremap_resource() for a |
---|
85 | 69 | * platform device and get resource |
---|
.. | .. |
---|
88 | 72 | * resource management |
---|
89 | 73 | * @index: resource index |
---|
90 | 74 | * @res: optional output parameter to store a pointer to the obtained resource. |
---|
| 75 | + * |
---|
| 76 | + * Return: a pointer to the remapped memory or an ERR_PTR() encoded error code |
---|
| 77 | + * on failure. |
---|
91 | 78 | */ |
---|
92 | 79 | void __iomem * |
---|
93 | 80 | devm_platform_get_and_ioremap_resource(struct platform_device *pdev, |
---|
.. | .. |
---|
107 | 94 | * device |
---|
108 | 95 | * |
---|
109 | 96 | * @pdev: platform device to use both for memory resource lookup as well as |
---|
110 | | - * resource managemend |
---|
| 97 | + * resource management |
---|
111 | 98 | * @index: resource index |
---|
| 99 | + * |
---|
| 100 | + * Return: a pointer to the remapped memory or an ERR_PTR() encoded error code |
---|
| 101 | + * on failure. |
---|
112 | 102 | */ |
---|
113 | 103 | void __iomem *devm_platform_ioremap_resource(struct platform_device *pdev, |
---|
114 | 104 | unsigned int index) |
---|
115 | 105 | { |
---|
116 | | - struct resource *res; |
---|
117 | | - |
---|
118 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, index); |
---|
119 | | - return devm_ioremap_resource(&pdev->dev, res); |
---|
| 106 | + return devm_platform_get_and_ioremap_resource(pdev, index, NULL); |
---|
120 | 107 | } |
---|
121 | 108 | EXPORT_SYMBOL_GPL(devm_platform_ioremap_resource); |
---|
122 | 109 | |
---|
123 | 110 | /** |
---|
124 | | - * platform_get_irq - get an IRQ for a device |
---|
| 111 | + * devm_platform_ioremap_resource_wc - write-combined variant of |
---|
| 112 | + * devm_platform_ioremap_resource() |
---|
| 113 | + * |
---|
| 114 | + * @pdev: platform device to use both for memory resource lookup as well as |
---|
| 115 | + * resource management |
---|
| 116 | + * @index: resource index |
---|
| 117 | + * |
---|
| 118 | + * Return: a pointer to the remapped memory or an ERR_PTR() encoded error code |
---|
| 119 | + * on failure. |
---|
| 120 | + */ |
---|
| 121 | +void __iomem *devm_platform_ioremap_resource_wc(struct platform_device *pdev, |
---|
| 122 | + unsigned int index) |
---|
| 123 | +{ |
---|
| 124 | + struct resource *res; |
---|
| 125 | + |
---|
| 126 | + res = platform_get_resource(pdev, IORESOURCE_MEM, index); |
---|
| 127 | + return devm_ioremap_resource_wc(&pdev->dev, res); |
---|
| 128 | +} |
---|
| 129 | + |
---|
| 130 | +/** |
---|
| 131 | + * devm_platform_ioremap_resource_byname - call devm_ioremap_resource for |
---|
| 132 | + * a platform device, retrieve the |
---|
| 133 | + * resource by name |
---|
| 134 | + * |
---|
| 135 | + * @pdev: platform device to use both for memory resource lookup as well as |
---|
| 136 | + * resource management |
---|
| 137 | + * @name: name of the resource |
---|
| 138 | + * |
---|
| 139 | + * Return: a pointer to the remapped memory or an ERR_PTR() encoded error code |
---|
| 140 | + * on failure. |
---|
| 141 | + */ |
---|
| 142 | +void __iomem * |
---|
| 143 | +devm_platform_ioremap_resource_byname(struct platform_device *pdev, |
---|
| 144 | + const char *name) |
---|
| 145 | +{ |
---|
| 146 | + struct resource *res; |
---|
| 147 | + |
---|
| 148 | + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); |
---|
| 149 | + return devm_ioremap_resource(&pdev->dev, res); |
---|
| 150 | +} |
---|
| 151 | +EXPORT_SYMBOL_GPL(devm_platform_ioremap_resource_byname); |
---|
| 152 | +#endif /* CONFIG_HAS_IOMEM */ |
---|
| 153 | + |
---|
| 154 | +/** |
---|
| 155 | + * platform_get_irq_optional - get an optional IRQ for a device |
---|
125 | 156 | * @dev: platform device |
---|
126 | 157 | * @num: IRQ number index |
---|
| 158 | + * |
---|
| 159 | + * Gets an IRQ for a platform device. Device drivers should check the return |
---|
| 160 | + * value for errors so as to not pass a negative integer value to the |
---|
| 161 | + * request_irq() APIs. This is the same as platform_get_irq(), except that it |
---|
| 162 | + * does not print an error message if an IRQ can not be obtained. |
---|
| 163 | + * |
---|
| 164 | + * For example:: |
---|
| 165 | + * |
---|
| 166 | + * int irq = platform_get_irq_optional(pdev, 0); |
---|
| 167 | + * if (irq < 0) |
---|
| 168 | + * return irq; |
---|
| 169 | + * |
---|
| 170 | + * Return: non-zero IRQ number on success, negative error number on failure. |
---|
127 | 171 | */ |
---|
128 | | -int platform_get_irq(struct platform_device *dev, unsigned int num) |
---|
| 172 | +int platform_get_irq_optional(struct platform_device *dev, unsigned int num) |
---|
129 | 173 | { |
---|
| 174 | + int ret; |
---|
130 | 175 | #ifdef CONFIG_SPARC |
---|
131 | 176 | /* sparc does not have irqs represented as IORESOURCE_IRQ resources */ |
---|
132 | 177 | if (!dev || num >= dev->archdata.num_irqs) |
---|
133 | 178 | return -ENXIO; |
---|
134 | | - return dev->archdata.irqs[num]; |
---|
| 179 | + ret = dev->archdata.irqs[num]; |
---|
| 180 | + goto out; |
---|
135 | 181 | #else |
---|
136 | 182 | struct resource *r; |
---|
137 | | - if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) { |
---|
138 | | - int ret; |
---|
139 | 183 | |
---|
| 184 | + if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) { |
---|
140 | 185 | ret = of_irq_get(dev->dev.of_node, num); |
---|
141 | 186 | if (ret > 0 || ret == -EPROBE_DEFER) |
---|
142 | | - return ret; |
---|
| 187 | + goto out; |
---|
143 | 188 | } |
---|
144 | 189 | |
---|
145 | 190 | r = platform_get_resource(dev, IORESOURCE_IRQ, num); |
---|
146 | 191 | if (has_acpi_companion(&dev->dev)) { |
---|
147 | 192 | if (r && r->flags & IORESOURCE_DISABLED) { |
---|
148 | | - int ret; |
---|
149 | | - |
---|
150 | 193 | ret = acpi_irq_get(ACPI_HANDLE(&dev->dev), num, r); |
---|
151 | 194 | if (ret) |
---|
152 | | - return ret; |
---|
| 195 | + goto out; |
---|
153 | 196 | } |
---|
154 | 197 | } |
---|
155 | 198 | |
---|
.. | .. |
---|
163 | 206 | struct irq_data *irqd; |
---|
164 | 207 | |
---|
165 | 208 | irqd = irq_get_irq_data(r->start); |
---|
166 | | - if (!irqd) |
---|
167 | | - return -ENXIO; |
---|
| 209 | + if (!irqd) { |
---|
| 210 | + ret = -ENXIO; |
---|
| 211 | + goto out; |
---|
| 212 | + } |
---|
168 | 213 | irqd_set_trigger_type(irqd, r->flags & IORESOURCE_BITS); |
---|
169 | 214 | } |
---|
170 | 215 | |
---|
171 | | - return r ? r->start : -ENXIO; |
---|
| 216 | + if (r) { |
---|
| 217 | + ret = r->start; |
---|
| 218 | + goto out; |
---|
| 219 | + } |
---|
| 220 | + |
---|
| 221 | + /* |
---|
| 222 | + * For the index 0 interrupt, allow falling back to GpioInt |
---|
| 223 | + * resources. While a device could have both Interrupt and GpioInt |
---|
| 224 | + * resources, making this fallback ambiguous, in many common cases |
---|
| 225 | + * the device will only expose one IRQ, and this fallback |
---|
| 226 | + * allows a common code path across either kind of resource. |
---|
| 227 | + */ |
---|
| 228 | + if (num == 0 && has_acpi_companion(&dev->dev)) { |
---|
| 229 | + ret = acpi_dev_gpio_irq_get(ACPI_COMPANION(&dev->dev), num); |
---|
| 230 | + /* Our callers expect -ENXIO for missing IRQs. */ |
---|
| 231 | + if (ret >= 0 || ret == -EPROBE_DEFER) |
---|
| 232 | + goto out; |
---|
| 233 | + } |
---|
| 234 | + |
---|
| 235 | + ret = -ENXIO; |
---|
172 | 236 | #endif |
---|
| 237 | +out: |
---|
| 238 | + WARN(ret == 0, "0 is an invalid IRQ number\n"); |
---|
| 239 | + return ret; |
---|
| 240 | +} |
---|
| 241 | +EXPORT_SYMBOL_GPL(platform_get_irq_optional); |
---|
| 242 | + |
---|
| 243 | +/** |
---|
| 244 | + * platform_get_irq - get an IRQ for a device |
---|
| 245 | + * @dev: platform device |
---|
| 246 | + * @num: IRQ number index |
---|
| 247 | + * |
---|
| 248 | + * Gets an IRQ for a platform device and prints an error message if finding the |
---|
| 249 | + * IRQ fails. Device drivers should check the return value for errors so as to |
---|
| 250 | + * not pass a negative integer value to the request_irq() APIs. |
---|
| 251 | + * |
---|
| 252 | + * For example:: |
---|
| 253 | + * |
---|
| 254 | + * int irq = platform_get_irq(pdev, 0); |
---|
| 255 | + * if (irq < 0) |
---|
| 256 | + * return irq; |
---|
| 257 | + * |
---|
| 258 | + * Return: non-zero IRQ number on success, negative error number on failure. |
---|
| 259 | + */ |
---|
| 260 | +int platform_get_irq(struct platform_device *dev, unsigned int num) |
---|
| 261 | +{ |
---|
| 262 | + int ret; |
---|
| 263 | + |
---|
| 264 | + ret = platform_get_irq_optional(dev, num); |
---|
| 265 | + if (ret < 0 && ret != -EPROBE_DEFER) |
---|
| 266 | + dev_err(&dev->dev, "IRQ index %u not found\n", num); |
---|
| 267 | + |
---|
| 268 | + return ret; |
---|
173 | 269 | } |
---|
174 | 270 | EXPORT_SYMBOL_GPL(platform_get_irq); |
---|
175 | 271 | |
---|
.. | .. |
---|
183 | 279 | { |
---|
184 | 280 | int ret, nr = 0; |
---|
185 | 281 | |
---|
186 | | - while ((ret = platform_get_irq(dev, nr)) >= 0) |
---|
| 282 | + while ((ret = platform_get_irq_optional(dev, nr)) >= 0) |
---|
187 | 283 | nr++; |
---|
188 | 284 | |
---|
189 | 285 | if (ret == -EPROBE_DEFER) |
---|
.. | .. |
---|
218 | 314 | } |
---|
219 | 315 | EXPORT_SYMBOL_GPL(platform_get_resource_byname); |
---|
220 | 316 | |
---|
221 | | -/** |
---|
222 | | - * platform_get_irq_byname - get an IRQ for a device by name |
---|
223 | | - * @dev: platform device |
---|
224 | | - * @name: IRQ name |
---|
225 | | - */ |
---|
226 | | -int platform_get_irq_byname(struct platform_device *dev, const char *name) |
---|
| 317 | +static int __platform_get_irq_byname(struct platform_device *dev, |
---|
| 318 | + const char *name) |
---|
227 | 319 | { |
---|
228 | 320 | struct resource *r; |
---|
| 321 | + int ret; |
---|
229 | 322 | |
---|
230 | 323 | if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) { |
---|
231 | | - int ret; |
---|
232 | | - |
---|
233 | 324 | ret = of_irq_get_byname(dev->dev.of_node, name); |
---|
234 | 325 | if (ret > 0 || ret == -EPROBE_DEFER) |
---|
235 | 326 | return ret; |
---|
236 | 327 | } |
---|
237 | 328 | |
---|
238 | 329 | r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name); |
---|
239 | | - return r ? r->start : -ENXIO; |
---|
| 330 | + if (r) { |
---|
| 331 | + WARN(r->start == 0, "0 is an invalid IRQ number\n"); |
---|
| 332 | + return r->start; |
---|
| 333 | + } |
---|
| 334 | + |
---|
| 335 | + return -ENXIO; |
---|
| 336 | +} |
---|
| 337 | + |
---|
| 338 | +/** |
---|
| 339 | + * platform_get_irq_byname - get an IRQ for a device by name |
---|
| 340 | + * @dev: platform device |
---|
| 341 | + * @name: IRQ name |
---|
| 342 | + * |
---|
| 343 | + * Get an IRQ like platform_get_irq(), but then by name rather then by index. |
---|
| 344 | + * |
---|
| 345 | + * Return: non-zero IRQ number on success, negative error number on failure. |
---|
| 346 | + */ |
---|
| 347 | +int platform_get_irq_byname(struct platform_device *dev, const char *name) |
---|
| 348 | +{ |
---|
| 349 | + int ret; |
---|
| 350 | + |
---|
| 351 | + ret = __platform_get_irq_byname(dev, name); |
---|
| 352 | + if (ret < 0 && ret != -EPROBE_DEFER) |
---|
| 353 | + dev_err(&dev->dev, "IRQ %s not found\n", name); |
---|
| 354 | + |
---|
| 355 | + return ret; |
---|
240 | 356 | } |
---|
241 | 357 | EXPORT_SYMBOL_GPL(platform_get_irq_byname); |
---|
| 358 | + |
---|
| 359 | +/** |
---|
| 360 | + * platform_get_irq_byname_optional - get an optional IRQ for a device by name |
---|
| 361 | + * @dev: platform device |
---|
| 362 | + * @name: IRQ name |
---|
| 363 | + * |
---|
| 364 | + * Get an optional IRQ by name like platform_get_irq_byname(). Except that it |
---|
| 365 | + * does not print an error message if an IRQ can not be obtained. |
---|
| 366 | + * |
---|
| 367 | + * Return: non-zero IRQ number on success, negative error number on failure. |
---|
| 368 | + */ |
---|
| 369 | +int platform_get_irq_byname_optional(struct platform_device *dev, |
---|
| 370 | + const char *name) |
---|
| 371 | +{ |
---|
| 372 | + return __platform_get_irq_byname(dev, name); |
---|
| 373 | +} |
---|
| 374 | +EXPORT_SYMBOL_GPL(platform_get_irq_byname_optional); |
---|
242 | 375 | |
---|
243 | 376 | /** |
---|
244 | 377 | * platform_add_devices - add a numbers of platform devices |
---|
.. | .. |
---|
267 | 400 | char name[]; |
---|
268 | 401 | }; |
---|
269 | 402 | |
---|
| 403 | +/* |
---|
| 404 | + * Set up default DMA mask for platform devices if the they weren't |
---|
| 405 | + * previously set by the architecture / DT. |
---|
| 406 | + */ |
---|
| 407 | +static void setup_pdev_dma_masks(struct platform_device *pdev) |
---|
| 408 | +{ |
---|
| 409 | + pdev->dev.dma_parms = &pdev->dma_parms; |
---|
| 410 | + |
---|
| 411 | + if (!pdev->dev.coherent_dma_mask) |
---|
| 412 | + pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); |
---|
| 413 | + if (!pdev->dev.dma_mask) { |
---|
| 414 | + pdev->platform_dma_mask = DMA_BIT_MASK(32); |
---|
| 415 | + pdev->dev.dma_mask = &pdev->platform_dma_mask; |
---|
| 416 | + } |
---|
| 417 | +}; |
---|
| 418 | + |
---|
270 | 419 | /** |
---|
271 | 420 | * platform_device_put - destroy a platform device |
---|
272 | 421 | * @pdev: platform device to free |
---|
.. | .. |
---|
276 | 425 | */ |
---|
277 | 426 | void platform_device_put(struct platform_device *pdev) |
---|
278 | 427 | { |
---|
279 | | - if (pdev) |
---|
| 428 | + if (!IS_ERR_OR_NULL(pdev)) |
---|
280 | 429 | put_device(&pdev->dev); |
---|
281 | 430 | } |
---|
282 | 431 | EXPORT_SYMBOL_GPL(platform_device_put); |
---|
.. | .. |
---|
313 | 462 | pa->pdev.id = id; |
---|
314 | 463 | device_initialize(&pa->pdev.dev); |
---|
315 | 464 | pa->pdev.dev.release = platform_device_release; |
---|
316 | | - arch_setup_pdev_archdata(&pa->pdev); |
---|
| 465 | + setup_pdev_dma_masks(&pa->pdev); |
---|
317 | 466 | } |
---|
318 | 467 | |
---|
319 | 468 | return pa ? &pa->pdev : NULL; |
---|
.. | .. |
---|
424 | 573 | * that we remember it must be freed, and we append a suffix |
---|
425 | 574 | * to avoid namespace collision with explicit IDs. |
---|
426 | 575 | */ |
---|
427 | | - ret = ida_simple_get(&platform_devid_ida, 0, 0, GFP_KERNEL); |
---|
| 576 | + ret = ida_alloc(&platform_devid_ida, GFP_KERNEL); |
---|
428 | 577 | if (ret < 0) |
---|
429 | 578 | goto err_out; |
---|
430 | 579 | pdev->id = ret; |
---|
.. | .. |
---|
447 | 596 | p = &ioport_resource; |
---|
448 | 597 | } |
---|
449 | 598 | |
---|
450 | | - if (p && insert_resource(p, r)) { |
---|
451 | | - dev_err(&pdev->dev, "failed to claim resource %d: %pR\n", i, r); |
---|
452 | | - ret = -EBUSY; |
---|
453 | | - goto failed; |
---|
| 599 | + if (p) { |
---|
| 600 | + ret = insert_resource(p, r); |
---|
| 601 | + if (ret) { |
---|
| 602 | + dev_err(&pdev->dev, "failed to claim resource %d: %pR\n", i, r); |
---|
| 603 | + goto failed; |
---|
| 604 | + } |
---|
454 | 605 | } |
---|
455 | 606 | } |
---|
456 | 607 | |
---|
.. | .. |
---|
463 | 614 | |
---|
464 | 615 | failed: |
---|
465 | 616 | if (pdev->id_auto) { |
---|
466 | | - ida_simple_remove(&platform_devid_ida, pdev->id); |
---|
| 617 | + ida_free(&platform_devid_ida, pdev->id); |
---|
467 | 618 | pdev->id = PLATFORM_DEVID_AUTO; |
---|
468 | 619 | } |
---|
469 | 620 | |
---|
.. | .. |
---|
490 | 641 | { |
---|
491 | 642 | u32 i; |
---|
492 | 643 | |
---|
493 | | - if (pdev) { |
---|
494 | | - device_remove_properties(&pdev->dev); |
---|
| 644 | + if (!IS_ERR_OR_NULL(pdev)) { |
---|
495 | 645 | device_del(&pdev->dev); |
---|
496 | 646 | |
---|
497 | 647 | if (pdev->id_auto) { |
---|
498 | | - ida_simple_remove(&platform_devid_ida, pdev->id); |
---|
| 648 | + ida_free(&platform_devid_ida, pdev->id); |
---|
499 | 649 | pdev->id = PLATFORM_DEVID_AUTO; |
---|
500 | 650 | } |
---|
501 | 651 | |
---|
.. | .. |
---|
515 | 665 | int platform_device_register(struct platform_device *pdev) |
---|
516 | 666 | { |
---|
517 | 667 | device_initialize(&pdev->dev); |
---|
518 | | - arch_setup_pdev_archdata(pdev); |
---|
| 668 | + setup_pdev_dma_masks(pdev); |
---|
519 | 669 | return platform_device_add(pdev); |
---|
520 | 670 | } |
---|
521 | 671 | EXPORT_SYMBOL_GPL(platform_device_register); |
---|
.. | .. |
---|
546 | 696 | struct platform_device *platform_device_register_full( |
---|
547 | 697 | const struct platform_device_info *pdevinfo) |
---|
548 | 698 | { |
---|
549 | | - int ret = -ENOMEM; |
---|
| 699 | + int ret; |
---|
550 | 700 | struct platform_device *pdev; |
---|
551 | 701 | |
---|
552 | 702 | pdev = platform_device_alloc(pdevinfo->name, pdevinfo->id); |
---|
553 | 703 | if (!pdev) |
---|
554 | | - goto err_alloc; |
---|
| 704 | + return ERR_PTR(-ENOMEM); |
---|
555 | 705 | |
---|
556 | 706 | pdev->dev.parent = pdevinfo->parent; |
---|
557 | 707 | pdev->dev.fwnode = pdevinfo->fwnode; |
---|
| 708 | + pdev->dev.of_node = of_node_get(to_of_node(pdev->dev.fwnode)); |
---|
| 709 | + pdev->dev.of_node_reused = pdevinfo->of_node_reused; |
---|
558 | 710 | |
---|
559 | 711 | if (pdevinfo->dma_mask) { |
---|
560 | | - /* |
---|
561 | | - * This memory isn't freed when the device is put, |
---|
562 | | - * I don't have a nice idea for that though. Conceptually |
---|
563 | | - * dma_mask in struct device should not be a pointer. |
---|
564 | | - * See http://thread.gmane.org/gmane.linux.kernel.pci/9081 |
---|
565 | | - */ |
---|
566 | | - pdev->dev.dma_mask = |
---|
567 | | - kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL); |
---|
568 | | - if (!pdev->dev.dma_mask) |
---|
569 | | - goto err; |
---|
570 | | - |
---|
571 | | - kmemleak_ignore(pdev->dev.dma_mask); |
---|
572 | | - |
---|
573 | | - *pdev->dev.dma_mask = pdevinfo->dma_mask; |
---|
| 712 | + pdev->platform_dma_mask = pdevinfo->dma_mask; |
---|
| 713 | + pdev->dev.dma_mask = &pdev->platform_dma_mask; |
---|
574 | 714 | pdev->dev.coherent_dma_mask = pdevinfo->dma_mask; |
---|
575 | 715 | } |
---|
576 | 716 | |
---|
.. | .. |
---|
595 | 735 | if (ret) { |
---|
596 | 736 | err: |
---|
597 | 737 | ACPI_COMPANION_SET(&pdev->dev, NULL); |
---|
598 | | - kfree(pdev->dev.dma_mask); |
---|
599 | | - |
---|
600 | | -err_alloc: |
---|
601 | 738 | platform_device_put(pdev); |
---|
602 | 739 | return ERR_PTR(ret); |
---|
603 | 740 | } |
---|
.. | .. |
---|
866 | 1003 | * @drivers: an array of drivers to unregister |
---|
867 | 1004 | * @count: the number of drivers to unregister |
---|
868 | 1005 | * |
---|
869 | | - * Unegisters platform drivers specified by an array. This is typically used |
---|
| 1006 | + * Unregisters platform drivers specified by an array. This is typically used |
---|
870 | 1007 | * to complement an earlier call to platform_register_drivers(). Drivers are |
---|
871 | 1008 | * unregistered in the reverse order in which they were registered. |
---|
872 | 1009 | */ |
---|
.. | .. |
---|
886 | 1023 | * (b) sysfs attribute lets new-style coldplug recover from hotplug events |
---|
887 | 1024 | * mishandled before system is fully running: "modprobe $(cat modalias)" |
---|
888 | 1025 | */ |
---|
889 | | -static ssize_t modalias_show(struct device *dev, struct device_attribute *a, |
---|
890 | | - char *buf) |
---|
| 1026 | +static ssize_t modalias_show(struct device *dev, |
---|
| 1027 | + struct device_attribute *attr, char *buf) |
---|
891 | 1028 | { |
---|
892 | | - struct platform_device *pdev = to_platform_device(dev); |
---|
| 1029 | + struct platform_device *pdev = to_platform_device(dev); |
---|
893 | 1030 | int len; |
---|
894 | 1031 | |
---|
895 | 1032 | len = of_device_modalias(dev, buf, PAGE_SIZE); |
---|
896 | 1033 | if (len != -ENODEV) |
---|
897 | 1034 | return len; |
---|
898 | 1035 | |
---|
899 | | - len = acpi_device_modalias(dev, buf, PAGE_SIZE -1); |
---|
| 1036 | + len = acpi_device_modalias(dev, buf, PAGE_SIZE - 1); |
---|
900 | 1037 | if (len != -ENODEV) |
---|
901 | 1038 | return len; |
---|
902 | 1039 | |
---|
903 | | - len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name); |
---|
904 | | - |
---|
905 | | - return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; |
---|
| 1040 | + return sysfs_emit(buf, "platform:%s\n", pdev->name); |
---|
906 | 1041 | } |
---|
907 | 1042 | static DEVICE_ATTR_RO(modalias); |
---|
908 | 1043 | |
---|
.. | .. |
---|
947 | 1082 | ssize_t len; |
---|
948 | 1083 | |
---|
949 | 1084 | device_lock(dev); |
---|
950 | | - len = sprintf(buf, "%s\n", pdev->driver_override); |
---|
| 1085 | + len = sysfs_emit(buf, "%s\n", pdev->driver_override); |
---|
951 | 1086 | device_unlock(dev); |
---|
| 1087 | + |
---|
952 | 1088 | return len; |
---|
953 | 1089 | } |
---|
954 | 1090 | static DEVICE_ATTR_RW(driver_override); |
---|
955 | 1091 | |
---|
| 1092 | +static ssize_t numa_node_show(struct device *dev, |
---|
| 1093 | + struct device_attribute *attr, char *buf) |
---|
| 1094 | +{ |
---|
| 1095 | + return sysfs_emit(buf, "%d\n", dev_to_node(dev)); |
---|
| 1096 | +} |
---|
| 1097 | +static DEVICE_ATTR_RO(numa_node); |
---|
| 1098 | + |
---|
| 1099 | +static umode_t platform_dev_attrs_visible(struct kobject *kobj, struct attribute *a, |
---|
| 1100 | + int n) |
---|
| 1101 | +{ |
---|
| 1102 | + struct device *dev = container_of(kobj, typeof(*dev), kobj); |
---|
| 1103 | + |
---|
| 1104 | + if (a == &dev_attr_numa_node.attr && |
---|
| 1105 | + dev_to_node(dev) == NUMA_NO_NODE) |
---|
| 1106 | + return 0; |
---|
| 1107 | + |
---|
| 1108 | + return a->mode; |
---|
| 1109 | +} |
---|
956 | 1110 | |
---|
957 | 1111 | static struct attribute *platform_dev_attrs[] = { |
---|
958 | 1112 | &dev_attr_modalias.attr, |
---|
| 1113 | + &dev_attr_numa_node.attr, |
---|
959 | 1114 | &dev_attr_driver_override.attr, |
---|
960 | 1115 | NULL, |
---|
961 | 1116 | }; |
---|
962 | | -ATTRIBUTE_GROUPS(platform_dev); |
---|
| 1117 | + |
---|
| 1118 | +static struct attribute_group platform_dev_group = { |
---|
| 1119 | + .attrs = platform_dev_attrs, |
---|
| 1120 | + .is_visible = platform_dev_attrs_visible, |
---|
| 1121 | +}; |
---|
| 1122 | +__ATTRIBUTE_GROUPS(platform_dev); |
---|
963 | 1123 | |
---|
964 | 1124 | static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) |
---|
965 | 1125 | { |
---|
.. | .. |
---|
1185 | 1345 | ret = of_dma_configure(dev, dev->of_node, true); |
---|
1186 | 1346 | } else if (has_acpi_companion(dev)) { |
---|
1187 | 1347 | attr = acpi_get_dma_attr(to_acpi_device_node(dev->fwnode)); |
---|
1188 | | - if (attr != DEV_DMA_NOT_SUPPORTED) |
---|
1189 | | - ret = acpi_dma_configure(dev, attr); |
---|
| 1348 | + ret = acpi_dma_configure(dev, attr); |
---|
1190 | 1349 | } |
---|
1191 | 1350 | |
---|
1192 | 1351 | return ret; |
---|
.. | .. |
---|
1208 | 1367 | }; |
---|
1209 | 1368 | EXPORT_SYMBOL_GPL(platform_bus_type); |
---|
1210 | 1369 | |
---|
| 1370 | +static inline int __platform_match(struct device *dev, const void *drv) |
---|
| 1371 | +{ |
---|
| 1372 | + return platform_match(dev, (struct device_driver *)drv); |
---|
| 1373 | +} |
---|
| 1374 | + |
---|
| 1375 | +/** |
---|
| 1376 | + * platform_find_device_by_driver - Find a platform device with a given |
---|
| 1377 | + * driver. |
---|
| 1378 | + * @start: The device to start the search from. |
---|
| 1379 | + * @drv: The device driver to look for. |
---|
| 1380 | + */ |
---|
| 1381 | +struct device *platform_find_device_by_driver(struct device *start, |
---|
| 1382 | + const struct device_driver *drv) |
---|
| 1383 | +{ |
---|
| 1384 | + return bus_find_device(&platform_bus_type, start, drv, |
---|
| 1385 | + __platform_match); |
---|
| 1386 | +} |
---|
| 1387 | +EXPORT_SYMBOL_GPL(platform_find_device_by_driver); |
---|
| 1388 | + |
---|
| 1389 | +void __weak __init early_platform_cleanup(void) { } |
---|
| 1390 | + |
---|
1211 | 1391 | int __init platform_bus_init(void) |
---|
1212 | 1392 | { |
---|
1213 | 1393 | int error; |
---|
.. | .. |
---|
1225 | 1405 | of_platform_register_reconfig_notifier(); |
---|
1226 | 1406 | return error; |
---|
1227 | 1407 | } |
---|
1228 | | - |
---|
1229 | | -#ifndef ARCH_HAS_DMA_GET_REQUIRED_MASK |
---|
1230 | | -u64 dma_get_required_mask(struct device *dev) |
---|
1231 | | -{ |
---|
1232 | | - u32 low_totalram = ((max_pfn - 1) << PAGE_SHIFT); |
---|
1233 | | - u32 high_totalram = ((max_pfn - 1) >> (32 - PAGE_SHIFT)); |
---|
1234 | | - u64 mask; |
---|
1235 | | - |
---|
1236 | | - if (!high_totalram) { |
---|
1237 | | - /* convert to mask just covering totalram */ |
---|
1238 | | - low_totalram = (1 << (fls(low_totalram) - 1)); |
---|
1239 | | - low_totalram += low_totalram - 1; |
---|
1240 | | - mask = low_totalram; |
---|
1241 | | - } else { |
---|
1242 | | - high_totalram = (1 << (fls(high_totalram) - 1)); |
---|
1243 | | - high_totalram += high_totalram - 1; |
---|
1244 | | - mask = (((u64)high_totalram) << 32) + 0xffffffff; |
---|
1245 | | - } |
---|
1246 | | - return mask; |
---|
1247 | | -} |
---|
1248 | | -EXPORT_SYMBOL_GPL(dma_get_required_mask); |
---|
1249 | | -#endif |
---|
1250 | | - |
---|
1251 | | -static __initdata LIST_HEAD(early_platform_driver_list); |
---|
1252 | | -static __initdata LIST_HEAD(early_platform_device_list); |
---|
1253 | | - |
---|
1254 | | -/** |
---|
1255 | | - * early_platform_driver_register - register early platform driver |
---|
1256 | | - * @epdrv: early_platform driver structure |
---|
1257 | | - * @buf: string passed from early_param() |
---|
1258 | | - * |
---|
1259 | | - * Helper function for early_platform_init() / early_platform_init_buffer() |
---|
1260 | | - */ |
---|
1261 | | -int __init early_platform_driver_register(struct early_platform_driver *epdrv, |
---|
1262 | | - char *buf) |
---|
1263 | | -{ |
---|
1264 | | - char *tmp; |
---|
1265 | | - int n; |
---|
1266 | | - |
---|
1267 | | - /* Simply add the driver to the end of the global list. |
---|
1268 | | - * Drivers will by default be put on the list in compiled-in order. |
---|
1269 | | - */ |
---|
1270 | | - if (!epdrv->list.next) { |
---|
1271 | | - INIT_LIST_HEAD(&epdrv->list); |
---|
1272 | | - list_add_tail(&epdrv->list, &early_platform_driver_list); |
---|
1273 | | - } |
---|
1274 | | - |
---|
1275 | | - /* If the user has specified device then make sure the driver |
---|
1276 | | - * gets prioritized. The driver of the last device specified on |
---|
1277 | | - * command line will be put first on the list. |
---|
1278 | | - */ |
---|
1279 | | - n = strlen(epdrv->pdrv->driver.name); |
---|
1280 | | - if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) { |
---|
1281 | | - list_move(&epdrv->list, &early_platform_driver_list); |
---|
1282 | | - |
---|
1283 | | - /* Allow passing parameters after device name */ |
---|
1284 | | - if (buf[n] == '\0' || buf[n] == ',') |
---|
1285 | | - epdrv->requested_id = -1; |
---|
1286 | | - else { |
---|
1287 | | - epdrv->requested_id = simple_strtoul(&buf[n + 1], |
---|
1288 | | - &tmp, 10); |
---|
1289 | | - |
---|
1290 | | - if (buf[n] != '.' || (tmp == &buf[n + 1])) { |
---|
1291 | | - epdrv->requested_id = EARLY_PLATFORM_ID_ERROR; |
---|
1292 | | - n = 0; |
---|
1293 | | - } else |
---|
1294 | | - n += strcspn(&buf[n + 1], ",") + 1; |
---|
1295 | | - } |
---|
1296 | | - |
---|
1297 | | - if (buf[n] == ',') |
---|
1298 | | - n++; |
---|
1299 | | - |
---|
1300 | | - if (epdrv->bufsize) { |
---|
1301 | | - memcpy(epdrv->buffer, &buf[n], |
---|
1302 | | - min_t(int, epdrv->bufsize, strlen(&buf[n]) + 1)); |
---|
1303 | | - epdrv->buffer[epdrv->bufsize - 1] = '\0'; |
---|
1304 | | - } |
---|
1305 | | - } |
---|
1306 | | - |
---|
1307 | | - return 0; |
---|
1308 | | -} |
---|
1309 | | - |
---|
1310 | | -/** |
---|
1311 | | - * early_platform_add_devices - adds a number of early platform devices |
---|
1312 | | - * @devs: array of early platform devices to add |
---|
1313 | | - * @num: number of early platform devices in array |
---|
1314 | | - * |
---|
1315 | | - * Used by early architecture code to register early platform devices and |
---|
1316 | | - * their platform data. |
---|
1317 | | - */ |
---|
1318 | | -void __init early_platform_add_devices(struct platform_device **devs, int num) |
---|
1319 | | -{ |
---|
1320 | | - struct device *dev; |
---|
1321 | | - int i; |
---|
1322 | | - |
---|
1323 | | - /* simply add the devices to list */ |
---|
1324 | | - for (i = 0; i < num; i++) { |
---|
1325 | | - dev = &devs[i]->dev; |
---|
1326 | | - |
---|
1327 | | - if (!dev->devres_head.next) { |
---|
1328 | | - pm_runtime_early_init(dev); |
---|
1329 | | - INIT_LIST_HEAD(&dev->devres_head); |
---|
1330 | | - list_add_tail(&dev->devres_head, |
---|
1331 | | - &early_platform_device_list); |
---|
1332 | | - } |
---|
1333 | | - } |
---|
1334 | | -} |
---|
1335 | | - |
---|
1336 | | -/** |
---|
1337 | | - * early_platform_driver_register_all - register early platform drivers |
---|
1338 | | - * @class_str: string to identify early platform driver class |
---|
1339 | | - * |
---|
1340 | | - * Used by architecture code to register all early platform drivers |
---|
1341 | | - * for a certain class. If omitted then only early platform drivers |
---|
1342 | | - * with matching kernel command line class parameters will be registered. |
---|
1343 | | - */ |
---|
1344 | | -void __init early_platform_driver_register_all(char *class_str) |
---|
1345 | | -{ |
---|
1346 | | - /* The "class_str" parameter may or may not be present on the kernel |
---|
1347 | | - * command line. If it is present then there may be more than one |
---|
1348 | | - * matching parameter. |
---|
1349 | | - * |
---|
1350 | | - * Since we register our early platform drivers using early_param() |
---|
1351 | | - * we need to make sure that they also get registered in the case |
---|
1352 | | - * when the parameter is missing from the kernel command line. |
---|
1353 | | - * |
---|
1354 | | - * We use parse_early_options() to make sure the early_param() gets |
---|
1355 | | - * called at least once. The early_param() may be called more than |
---|
1356 | | - * once since the name of the preferred device may be specified on |
---|
1357 | | - * the kernel command line. early_platform_driver_register() handles |
---|
1358 | | - * this case for us. |
---|
1359 | | - */ |
---|
1360 | | - parse_early_options(class_str); |
---|
1361 | | -} |
---|
1362 | | - |
---|
1363 | | -/** |
---|
1364 | | - * early_platform_match - find early platform device matching driver |
---|
1365 | | - * @epdrv: early platform driver structure |
---|
1366 | | - * @id: id to match against |
---|
1367 | | - */ |
---|
1368 | | -static struct platform_device * __init |
---|
1369 | | -early_platform_match(struct early_platform_driver *epdrv, int id) |
---|
1370 | | -{ |
---|
1371 | | - struct platform_device *pd; |
---|
1372 | | - |
---|
1373 | | - list_for_each_entry(pd, &early_platform_device_list, dev.devres_head) |
---|
1374 | | - if (platform_match(&pd->dev, &epdrv->pdrv->driver)) |
---|
1375 | | - if (pd->id == id) |
---|
1376 | | - return pd; |
---|
1377 | | - |
---|
1378 | | - return NULL; |
---|
1379 | | -} |
---|
1380 | | - |
---|
1381 | | -/** |
---|
1382 | | - * early_platform_left - check if early platform driver has matching devices |
---|
1383 | | - * @epdrv: early platform driver structure |
---|
1384 | | - * @id: return true if id or above exists |
---|
1385 | | - */ |
---|
1386 | | -static int __init early_platform_left(struct early_platform_driver *epdrv, |
---|
1387 | | - int id) |
---|
1388 | | -{ |
---|
1389 | | - struct platform_device *pd; |
---|
1390 | | - |
---|
1391 | | - list_for_each_entry(pd, &early_platform_device_list, dev.devres_head) |
---|
1392 | | - if (platform_match(&pd->dev, &epdrv->pdrv->driver)) |
---|
1393 | | - if (pd->id >= id) |
---|
1394 | | - return 1; |
---|
1395 | | - |
---|
1396 | | - return 0; |
---|
1397 | | -} |
---|
1398 | | - |
---|
1399 | | -/** |
---|
1400 | | - * early_platform_driver_probe_id - probe drivers matching class_str and id |
---|
1401 | | - * @class_str: string to identify early platform driver class |
---|
1402 | | - * @id: id to match against |
---|
1403 | | - * @nr_probe: number of platform devices to successfully probe before exiting |
---|
1404 | | - */ |
---|
1405 | | -static int __init early_platform_driver_probe_id(char *class_str, |
---|
1406 | | - int id, |
---|
1407 | | - int nr_probe) |
---|
1408 | | -{ |
---|
1409 | | - struct early_platform_driver *epdrv; |
---|
1410 | | - struct platform_device *match; |
---|
1411 | | - int match_id; |
---|
1412 | | - int n = 0; |
---|
1413 | | - int left = 0; |
---|
1414 | | - |
---|
1415 | | - list_for_each_entry(epdrv, &early_platform_driver_list, list) { |
---|
1416 | | - /* only use drivers matching our class_str */ |
---|
1417 | | - if (strcmp(class_str, epdrv->class_str)) |
---|
1418 | | - continue; |
---|
1419 | | - |
---|
1420 | | - if (id == -2) { |
---|
1421 | | - match_id = epdrv->requested_id; |
---|
1422 | | - left = 1; |
---|
1423 | | - |
---|
1424 | | - } else { |
---|
1425 | | - match_id = id; |
---|
1426 | | - left += early_platform_left(epdrv, id); |
---|
1427 | | - |
---|
1428 | | - /* skip requested id */ |
---|
1429 | | - switch (epdrv->requested_id) { |
---|
1430 | | - case EARLY_PLATFORM_ID_ERROR: |
---|
1431 | | - case EARLY_PLATFORM_ID_UNSET: |
---|
1432 | | - break; |
---|
1433 | | - default: |
---|
1434 | | - if (epdrv->requested_id == id) |
---|
1435 | | - match_id = EARLY_PLATFORM_ID_UNSET; |
---|
1436 | | - } |
---|
1437 | | - } |
---|
1438 | | - |
---|
1439 | | - switch (match_id) { |
---|
1440 | | - case EARLY_PLATFORM_ID_ERROR: |
---|
1441 | | - pr_warn("%s: unable to parse %s parameter\n", |
---|
1442 | | - class_str, epdrv->pdrv->driver.name); |
---|
1443 | | - /* fall-through */ |
---|
1444 | | - case EARLY_PLATFORM_ID_UNSET: |
---|
1445 | | - match = NULL; |
---|
1446 | | - break; |
---|
1447 | | - default: |
---|
1448 | | - match = early_platform_match(epdrv, match_id); |
---|
1449 | | - } |
---|
1450 | | - |
---|
1451 | | - if (match) { |
---|
1452 | | - /* |
---|
1453 | | - * Set up a sensible init_name to enable |
---|
1454 | | - * dev_name() and others to be used before the |
---|
1455 | | - * rest of the driver core is initialized. |
---|
1456 | | - */ |
---|
1457 | | - if (!match->dev.init_name && slab_is_available()) { |
---|
1458 | | - if (match->id != -1) |
---|
1459 | | - match->dev.init_name = |
---|
1460 | | - kasprintf(GFP_KERNEL, "%s.%d", |
---|
1461 | | - match->name, |
---|
1462 | | - match->id); |
---|
1463 | | - else |
---|
1464 | | - match->dev.init_name = |
---|
1465 | | - kasprintf(GFP_KERNEL, "%s", |
---|
1466 | | - match->name); |
---|
1467 | | - |
---|
1468 | | - if (!match->dev.init_name) |
---|
1469 | | - return -ENOMEM; |
---|
1470 | | - } |
---|
1471 | | - |
---|
1472 | | - if (epdrv->pdrv->probe(match)) |
---|
1473 | | - pr_warn("%s: unable to probe %s early.\n", |
---|
1474 | | - class_str, match->name); |
---|
1475 | | - else |
---|
1476 | | - n++; |
---|
1477 | | - } |
---|
1478 | | - |
---|
1479 | | - if (n >= nr_probe) |
---|
1480 | | - break; |
---|
1481 | | - } |
---|
1482 | | - |
---|
1483 | | - if (left) |
---|
1484 | | - return n; |
---|
1485 | | - else |
---|
1486 | | - return -ENODEV; |
---|
1487 | | -} |
---|
1488 | | - |
---|
1489 | | -/** |
---|
1490 | | - * early_platform_driver_probe - probe a class of registered drivers |
---|
1491 | | - * @class_str: string to identify early platform driver class |
---|
1492 | | - * @nr_probe: number of platform devices to successfully probe before exiting |
---|
1493 | | - * @user_only: only probe user specified early platform devices |
---|
1494 | | - * |
---|
1495 | | - * Used by architecture code to probe registered early platform drivers |
---|
1496 | | - * within a certain class. For probe to happen a registered early platform |
---|
1497 | | - * device matching a registered early platform driver is needed. |
---|
1498 | | - */ |
---|
1499 | | -int __init early_platform_driver_probe(char *class_str, |
---|
1500 | | - int nr_probe, |
---|
1501 | | - int user_only) |
---|
1502 | | -{ |
---|
1503 | | - int k, n, i; |
---|
1504 | | - |
---|
1505 | | - n = 0; |
---|
1506 | | - for (i = -2; n < nr_probe; i++) { |
---|
1507 | | - k = early_platform_driver_probe_id(class_str, i, nr_probe - n); |
---|
1508 | | - |
---|
1509 | | - if (k < 0) |
---|
1510 | | - break; |
---|
1511 | | - |
---|
1512 | | - n += k; |
---|
1513 | | - |
---|
1514 | | - if (user_only) |
---|
1515 | | - break; |
---|
1516 | | - } |
---|
1517 | | - |
---|
1518 | | - return n; |
---|
1519 | | -} |
---|
1520 | | - |
---|
1521 | | -/** |
---|
1522 | | - * early_platform_cleanup - clean up early platform code |
---|
1523 | | - */ |
---|
1524 | | -void __init early_platform_cleanup(void) |
---|
1525 | | -{ |
---|
1526 | | - struct platform_device *pd, *pd2; |
---|
1527 | | - |
---|
1528 | | - /* clean up the devres list used to chain devices */ |
---|
1529 | | - list_for_each_entry_safe(pd, pd2, &early_platform_device_list, |
---|
1530 | | - dev.devres_head) { |
---|
1531 | | - list_del(&pd->dev.devres_head); |
---|
1532 | | - memset(&pd->dev.devres_head, 0, sizeof(pd->dev.devres_head)); |
---|
1533 | | - } |
---|
1534 | | -} |
---|
1535 | | - |
---|