Lines Matching +full:interrupt +full:- +full:affinity

1 // SPDX-License-Identifier: GPL-2.0
3 * platform.c - platform 'pseudo' bus for legacy devices
5 * Copyright (c) 2002-3 Patrick Mochel
6 * Copyright (c) 2002-3 Open Source Development Labs
8 * Please see Documentation/driver-api/driver-model/platform.rst for more
18 #include <linux/interrupt.h>
20 #include <linux/dma-mapping.h>
28 #include <linux/clk/clk-conf.h>
34 #include <linux/dma-map-ops.h>
48 * platform_get_resource - get a resource for a device
60 for (i = 0; i < dev->num_resources; i++) { in platform_get_resource()
61 struct resource *r = &dev->resource[i]; in platform_get_resource()
63 if (type == resource_type(r) && num-- == 0) in platform_get_resource()
75 for (i = 0; i < dev->num_resources; i++) { in platform_get_mem_or_io()
76 struct resource *r = &dev->resource[i]; in platform_get_mem_or_io()
78 if ((resource_type(r) & (IORESOURCE_MEM|IORESOURCE_IO)) && num-- == 0) in platform_get_mem_or_io()
87 * devm_platform_get_and_ioremap_resource - call devm_ioremap_resource() for a
107 return devm_ioremap_resource(&pdev->dev, r); in devm_platform_get_and_ioremap_resource()
112 * devm_platform_ioremap_resource - call devm_ioremap_resource() for a platform
130 * devm_platform_ioremap_resource_byname - call devm_ioremap_resource for
148 return devm_ioremap_resource(&pdev->dev, res); in devm_platform_ioremap_resource_byname()
158 struct fwnode_handle *fwnode = dev_fwnode(&dev->dev); in get_irq_affinity()
170 * platform_get_irq_affinity - get an optional IRQ and its affinity for a device
172 * @num: interrupt number index
173 * @affinity: optional cpumask pointer to get the affinity of a per-cpu interrupt
177 * the request_irq() APIs. Optional affinity information is provided in the
178 * affinity pointer if available, and NULL otherwise.
180 * Return: non-zero interrupt number on success, negative error number on failure.
183 const struct cpumask **affinity) in platform_get_irq_affinity() argument
188 if (!dev || num >= dev->archdata.num_irqs) in platform_get_irq_affinity()
190 ret = dev->archdata.irqs[num]; in platform_get_irq_affinity()
193 struct fwnode_handle *fwnode = dev_fwnode(&dev->dev); in platform_get_irq_affinity()
198 if (ret > 0 || ret == -EPROBE_DEFER) in platform_get_irq_affinity()
204 if (r && r->flags & IORESOURCE_DISABLED) { in platform_get_irq_affinity()
214 * IORESOURCE_BITS correspond 1-to-1 to the IRQF_TRIGGER* in platform_get_irq_affinity()
217 if (r && r->flags & IORESOURCE_BITS) { in platform_get_irq_affinity()
220 irqd = irq_get_irq_data(r->start); in platform_get_irq_affinity()
223 irqd_set_trigger_type(irqd, r->flags & IORESOURCE_BITS); in platform_get_irq_affinity()
227 ret = r->start; in platform_get_irq_affinity()
232 * For the index 0 interrupt, allow falling back to GpioInt in platform_get_irq_affinity()
233 * resources. While a device could have both Interrupt and GpioInt in platform_get_irq_affinity()
240 /* Our callers expect -ENXIO for missing IRQs. */ in platform_get_irq_affinity()
241 if (ret >= 0 || ret == -EPROBE_DEFER) in platform_get_irq_affinity()
247 ret = -ENXIO; in platform_get_irq_affinity()
250 return -EINVAL; in platform_get_irq_affinity()
252 if (ret > 0 && affinity) in platform_get_irq_affinity()
253 *affinity = get_irq_affinity(dev, num); in platform_get_irq_affinity()
260 * platform_get_irq_optional - get an optional interrupt for a device
262 * @num: interrupt number index
264 * Gets an interrupt for a platform device. Device drivers should check the
267 * that it does not print an error message if an interrupt can not be
276 * Return: non-zero interrupt number on success, negative error number on failure.
285 * platform_get_irq - get an IRQ for a device
299 * Return: non-zero IRQ number on success, negative error number on failure.
307 return dev_err_probe(&dev->dev, ret, in platform_get_irq()
315 * platform_irq_count - Count the number of IRQs a platform device uses
327 if (ret == -EPROBE_DEFER) in platform_irq_count()
354 for (i = 0; i < ptr->count; i++) { in devm_platform_get_irqs_affinity_release()
355 irq_dispose_mapping(ptr->irq[i]); in devm_platform_get_irqs_affinity_release()
363 * devm_platform_get_irqs_affinity - devm method to get a set of IRQs for a
364 * device using an interrupt affinity descriptor
366 * @affd: affinity descriptor
367 * @minvec: minimum count of interrupt vectors
368 * @maxvec: maximum count of interrupt vectors
372 * to the passed affinity descriptor
388 return -EPERM; in devm_platform_get_irqs_affinity()
391 return -ERANGE; in devm_platform_get_irqs_affinity()
398 return -ENOSPC; in devm_platform_get_irqs_affinity()
402 return -ENOSPC; in devm_platform_get_irqs_affinity()
411 return -ENOMEM; in devm_platform_get_irqs_affinity()
413 ptr->count = nvec; in devm_platform_get_irqs_affinity()
421 ptr->irq[i] = irq; in devm_platform_get_irqs_affinity()
426 ret = -ENOMEM; in devm_platform_get_irqs_affinity()
431 ret = irq_update_affinity_desc(ptr->irq[i], &desc[i]); in devm_platform_get_irqs_affinity()
433 dev_err(&dev->dev, "failed to update irq%d affinity descriptor (%d)\n", in devm_platform_get_irqs_affinity()
434 ptr->irq[i], ret); in devm_platform_get_irqs_affinity()
439 devres_add(&dev->dev, ptr); in devm_platform_get_irqs_affinity()
443 *irqs = ptr->irq; in devm_platform_get_irqs_affinity()
456 * platform_get_resource_byname - get a resource for a device by name
467 for (i = 0; i < dev->num_resources; i++) { in platform_get_resource_byname()
468 struct resource *r = &dev->resource[i]; in platform_get_resource_byname()
470 if (unlikely(!r->name)) in platform_get_resource_byname()
473 if (type == resource_type(r) && !strcmp(r->name, name)) in platform_get_resource_byname()
486 ret = fwnode_irq_get_byname(dev_fwnode(&dev->dev), name); in __platform_get_irq_byname()
487 if (ret > 0 || ret == -EPROBE_DEFER) in __platform_get_irq_byname()
492 if (WARN(!r->start, "0 is an invalid IRQ number\n")) in __platform_get_irq_byname()
493 return -EINVAL; in __platform_get_irq_byname()
494 return r->start; in __platform_get_irq_byname()
497 return -ENXIO; in __platform_get_irq_byname()
501 * platform_get_irq_byname - get an IRQ for a device by name
507 * Return: non-zero IRQ number on success, negative error number on failure.
515 return dev_err_probe(&dev->dev, ret, "IRQ %s not found\n", in platform_get_irq_byname()
522 * platform_get_irq_byname_optional - get an optional IRQ for a device by name
529 * Return: non-zero IRQ number on success, negative error number on failure.
539 * platform_add_devices - add a numbers of platform devices
552 while (--i >= 0) in platform_add_devices()
573 pdev->dev.dma_parms = &pdev->dma_parms; in setup_pdev_dma_masks()
575 if (!pdev->dev.coherent_dma_mask) in setup_pdev_dma_masks()
576 pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); in setup_pdev_dma_masks()
577 if (!pdev->dev.dma_mask) { in setup_pdev_dma_masks()
578 pdev->platform_dma_mask = DMA_BIT_MASK(32); in setup_pdev_dma_masks()
579 pdev->dev.dma_mask = &pdev->platform_dma_mask; in setup_pdev_dma_masks()
584 * platform_device_put - destroy a platform device
593 put_device(&pdev->dev); in platform_device_put()
602 of_node_put(pa->pdev.dev.of_node); in platform_device_release()
603 kfree(pa->pdev.dev.platform_data); in platform_device_release()
604 kfree(pa->pdev.mfd_cell); in platform_device_release()
605 kfree(pa->pdev.resource); in platform_device_release()
610 * platform_device_alloc - create a platform device
623 strcpy(pa->name, name); in platform_device_alloc()
624 pa->pdev.name = pa->name; in platform_device_alloc()
625 pa->pdev.id = id; in platform_device_alloc()
626 device_initialize(&pa->pdev.dev); in platform_device_alloc()
627 pa->pdev.dev.release = platform_device_release; in platform_device_alloc()
628 setup_pdev_dma_masks(&pa->pdev); in platform_device_alloc()
631 return pa ? &pa->pdev : NULL; in platform_device_alloc()
636 * platform_device_add_resources - add resources to a platform device
653 return -ENOMEM; in platform_device_add_resources()
656 kfree(pdev->resource); in platform_device_add_resources()
657 pdev->resource = r; in platform_device_add_resources()
658 pdev->num_resources = num; in platform_device_add_resources()
664 * platform_device_add_data - add platform-specific data to a platform device
681 return -ENOMEM; in platform_device_add_data()
684 kfree(pdev->dev.platform_data); in platform_device_add_data()
685 pdev->dev.platform_data = d; in platform_device_add_data()
691 * platform_device_add - add a platform device to device hierarchy
699 struct device *dev = &pdev->dev; in platform_device_add()
703 if (!dev->parent) in platform_device_add()
704 dev->parent = &platform_bus; in platform_device_add()
706 dev->bus = &platform_bus_type; in platform_device_add()
708 switch (pdev->id) { in platform_device_add()
710 dev_set_name(dev, "%s.%d", pdev->name, pdev->id); in platform_device_add()
713 dev_set_name(dev, "%s", pdev->name); in platform_device_add()
724 pdev->id = ret; in platform_device_add()
725 pdev->id_auto = true; in platform_device_add()
726 dev_set_name(dev, "%s.%d.auto", pdev->name, pdev->id); in platform_device_add()
730 for (i = 0; i < pdev->num_resources; i++) { in platform_device_add()
731 struct resource *p, *r = &pdev->resource[i]; in platform_device_add()
733 if (r->name == NULL) in platform_device_add()
734 r->name = dev_name(dev); in platform_device_add()
736 p = r->parent; in platform_device_add()
754 dev_name(dev->parent)); in platform_device_add()
763 if (pdev->id_auto) { in platform_device_add()
764 ida_free(&platform_devid_ida, pdev->id); in platform_device_add()
765 pdev->id = PLATFORM_DEVID_AUTO; in platform_device_add()
768 while (i--) { in platform_device_add()
769 struct resource *r = &pdev->resource[i]; in platform_device_add()
770 if (r->parent) in platform_device_add()
779 * platform_device_del - remove a platform-level device
782 * Note that this function will also release all memory- and port-based
783 * resources owned by the device (@dev->resource). This function must
791 device_del(&pdev->dev); in platform_device_del()
793 if (pdev->id_auto) { in platform_device_del()
794 ida_free(&platform_devid_ida, pdev->id); in platform_device_del()
795 pdev->id = PLATFORM_DEVID_AUTO; in platform_device_del()
798 for (i = 0; i < pdev->num_resources; i++) { in platform_device_del()
799 struct resource *r = &pdev->resource[i]; in platform_device_del()
800 if (r->parent) in platform_device_del()
808 * platform_device_register - add a platform-level device
817 device_initialize(&pdev->dev); in platform_device_register()
824 * platform_device_unregister - unregister a platform-level device
839 * platform_device_register_full - add a platform-level device with
840 * resources and platform-specific data
852 pdev = platform_device_alloc(pdevinfo->name, pdevinfo->id); in platform_device_register_full()
854 return ERR_PTR(-ENOMEM); in platform_device_register_full()
856 pdev->dev.parent = pdevinfo->parent; in platform_device_register_full()
857 pdev->dev.fwnode = pdevinfo->fwnode; in platform_device_register_full()
858 pdev->dev.of_node = of_node_get(to_of_node(pdev->dev.fwnode)); in platform_device_register_full()
859 pdev->dev.of_node_reused = pdevinfo->of_node_reused; in platform_device_register_full()
861 if (pdevinfo->dma_mask) { in platform_device_register_full()
862 pdev->platform_dma_mask = pdevinfo->dma_mask; in platform_device_register_full()
863 pdev->dev.dma_mask = &pdev->platform_dma_mask; in platform_device_register_full()
864 pdev->dev.coherent_dma_mask = pdevinfo->dma_mask; in platform_device_register_full()
868 pdevinfo->res, pdevinfo->num_res); in platform_device_register_full()
873 pdevinfo->data, pdevinfo->size_data); in platform_device_register_full()
877 if (pdevinfo->properties) { in platform_device_register_full()
878 ret = device_create_managed_software_node(&pdev->dev, in platform_device_register_full()
879 pdevinfo->properties, NULL); in platform_device_register_full()
887 ACPI_COMPANION_SET(&pdev->dev, NULL); in platform_device_register_full()
897 * __platform_driver_register - register a driver for platform-level devices
904 drv->driver.owner = owner; in __platform_driver_register()
905 drv->driver.bus = &platform_bus_type; in __platform_driver_register()
907 return driver_register(&drv->driver); in __platform_driver_register()
912 * platform_driver_unregister - unregister a driver for platform-level devices
917 driver_unregister(&drv->driver); in platform_driver_unregister()
923 return -ENXIO; in platform_probe_fail()
928 if (dev->driver == driver) in is_bound_to_driver()
934 * __platform_driver_probe - register driver for non-hotpluggable device
941 * remove its run-once probe() infrastructure from memory after the driver
945 * into system-on-chip processors, where the controller devices have been
958 if (drv->driver.probe_type == PROBE_PREFER_ASYNCHRONOUS) { in __platform_driver_probe()
960 drv->driver.name, __func__); in __platform_driver_probe()
961 return -EINVAL; in __platform_driver_probe()
969 drv->driver.probe_type = PROBE_FORCE_SYNCHRONOUS; in __platform_driver_probe()
975 drv->prevent_deferred_probe = true; in __platform_driver_probe()
978 drv->driver.suppress_bind_attrs = true; in __platform_driver_probe()
981 drv->probe = probe; in __platform_driver_probe()
987 drv->probe = platform_probe_fail; in __platform_driver_probe()
992 if (!bus_for_each_dev(&platform_bus_type, NULL, &drv->driver, is_bound_to_driver)) { in __platform_driver_probe()
993 retval = -ENODEV; in __platform_driver_probe()
1002 * __platform_create_bundle - register driver and create corresponding device
1011 * Use this in legacy-style modules that probe hardware directly and
1025 pdev = platform_device_alloc(driver->driver.name, PLATFORM_DEVID_NONE); in __platform_create_bundle()
1027 error = -ENOMEM; in __platform_create_bundle()
1059 * __platform_register_drivers - register an array of platform drivers
1091 while (i--) { in __platform_register_drivers()
1101 * platform_unregister_drivers - unregister an array of platform drivers
1112 while (count--) { in platform_unregister_drivers()
1123 while (id->name[0]) { in platform_match_id()
1124 if (strcmp(pdev->name, id->name) == 0) { in platform_match_id()
1125 pdev->id_entry = id; in platform_match_id()
1137 struct platform_driver *pdrv = to_platform_driver(dev->driver); in platform_legacy_suspend()
1141 if (dev->driver && pdrv->suspend) in platform_legacy_suspend()
1142 ret = pdrv->suspend(pdev, mesg); in platform_legacy_suspend()
1149 struct platform_driver *pdrv = to_platform_driver(dev->driver); in platform_legacy_resume()
1153 if (dev->driver && pdrv->resume) in platform_legacy_resume()
1154 ret = pdrv->resume(pdev); in platform_legacy_resume()
1165 const struct device_driver *drv = dev->driver; in platform_pm_suspend()
1171 if (drv->pm) { in platform_pm_suspend()
1172 if (drv->pm->suspend) in platform_pm_suspend()
1173 ret = drv->pm->suspend(dev); in platform_pm_suspend()
1183 const struct device_driver *drv = dev->driver; in platform_pm_resume()
1189 if (drv->pm) { in platform_pm_resume()
1190 if (drv->pm->resume) in platform_pm_resume()
1191 ret = drv->pm->resume(dev); in platform_pm_resume()
1205 const struct device_driver *drv = dev->driver; in platform_pm_freeze()
1211 if (drv->pm) { in platform_pm_freeze()
1212 if (drv->pm->freeze) in platform_pm_freeze()
1213 ret = drv->pm->freeze(dev); in platform_pm_freeze()
1223 const struct device_driver *drv = dev->driver; in platform_pm_thaw()
1229 if (drv->pm) { in platform_pm_thaw()
1230 if (drv->pm->thaw) in platform_pm_thaw()
1231 ret = drv->pm->thaw(dev); in platform_pm_thaw()
1241 const struct device_driver *drv = dev->driver; in platform_pm_poweroff()
1247 if (drv->pm) { in platform_pm_poweroff()
1248 if (drv->pm->poweroff) in platform_pm_poweroff()
1249 ret = drv->pm->poweroff(dev); in platform_pm_poweroff()
1259 const struct device_driver *drv = dev->driver; in platform_pm_restore()
1265 if (drv->pm) { in platform_pm_restore()
1266 if (drv->pm->restore) in platform_pm_restore()
1267 ret = drv->pm->restore(dev); in platform_pm_restore()
1277 /* modalias support enables more hands-off userspace setup:
1278 * (a) environment variable lets new-style hotplug events work once system is
1280 * (b) sysfs attribute lets new-style coldplug recover from hotplug events
1290 if (len != -ENODEV) in modalias_show()
1293 len = acpi_device_modalias(dev, buf, PAGE_SIZE - 1); in modalias_show()
1294 if (len != -ENODEV) in modalias_show()
1297 return sysfs_emit(buf, "platform:%s\n", pdev->name); in modalias_show()
1323 return a->mode; in platform_dev_attrs_visible()
1334 * platform_match - bind platform device to platform driver.
1366 if (pdrv->id_table) in platform_match()
1367 return platform_match_id(pdrv->id_table, pdev) != NULL; in platform_match()
1369 /* fall-back to driver name match */ in platform_match()
1370 return (strcmp(pdev->name, drv->name) == 0); in platform_match()
1378 /* Some devices have extra OF data and an OF-style MODALIAS */ in platform_uevent()
1380 if (rc != -ENODEV) in platform_uevent()
1384 if (rc != -ENODEV) in platform_uevent()
1388 pdev->name); in platform_uevent()
1394 struct platform_driver *drv = to_platform_driver(_dev->driver); in platform_probe()
1405 if (unlikely(drv->probe == platform_probe_fail)) in platform_probe()
1406 return -ENXIO; in platform_probe()
1408 ret = of_clk_set_defaults(_dev->of_node, false); in platform_probe()
1417 if (drv->probe) in platform_probe()
1418 ret = drv->probe(dev); in platform_probe()
1421 if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) { in platform_probe()
1423 ret = -ENXIO; in platform_probe()
1431 struct platform_driver *drv = to_platform_driver(_dev->driver); in platform_remove()
1434 if (drv->remove) in platform_remove()
1435 drv->remove(dev); in platform_remove()
1443 if (!_dev->driver) in platform_shutdown()
1446 drv = to_platform_driver(_dev->driver); in platform_shutdown()
1447 if (drv->shutdown) in platform_shutdown()
1448 drv->shutdown(dev); in platform_shutdown()
1453 struct device_driver *drv = READ_ONCE(dev->driver); in platform_dma_configure()
1464 /* @dev->driver may not be valid when we're called from the IOMMU layer */ in platform_dma_configure()
1465 if (ret || !drv || to_platform_driver(drv)->driver_managed_dma) in platform_dma_configure()
1477 struct platform_driver *drv = to_platform_driver(dev->driver); in platform_dma_cleanup()
1479 if (!drv->driver_managed_dma) in platform_dma_cleanup()
1509 * platform_find_device_by_driver - Find a platform device with a given