diff options
author | Sinan Kaya <okaya@codeaurora.org> | 2016-07-19 09:01:44 -0400 |
---|---|---|
committer | Alex Williamson <alex.williamson@redhat.com> | 2016-07-19 12:26:41 -0400 |
commit | a12a9368e192d56175e49d69360d861025a0f6f7 (patch) | |
tree | 79fc72bc9350f516664ebc434c2acdd11192c2ca | |
parent | dc5542fb115a9576493831160e31d355b58541d7 (diff) |
vfio: platform: add support for ACPI probe
The code is using the compatible DT string to associate a reset driver
with the actual device itself. The compatible string does not exist on
ACPI based systems. HID is the unique identifier for a device driver
instead.
Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
-rw-r--r-- | drivers/vfio/platform/vfio_platform_common.c | 64 | ||||
-rw-r--r-- | drivers/vfio/platform/vfio_platform_private.h | 1 |
2 files changed, 60 insertions, 5 deletions
diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c index 307d61d2aea2..716f421d1b01 100644 --- a/drivers/vfio/platform/vfio_platform_common.c +++ b/drivers/vfio/platform/vfio_platform_common.c | |||
@@ -13,6 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/device.h> | 15 | #include <linux/device.h> |
16 | #include <linux/acpi.h> | ||
16 | #include <linux/iommu.h> | 17 | #include <linux/iommu.h> |
17 | #include <linux/module.h> | 18 | #include <linux/module.h> |
18 | #include <linux/mutex.h> | 19 | #include <linux/mutex.h> |
@@ -49,6 +50,27 @@ static vfio_platform_reset_fn_t vfio_platform_lookup_reset(const char *compat, | |||
49 | return reset_fn; | 50 | return reset_fn; |
50 | } | 51 | } |
51 | 52 | ||
53 | static int vfio_platform_acpi_probe(struct vfio_platform_device *vdev, | ||
54 | struct device *dev) | ||
55 | { | ||
56 | struct acpi_device *adev; | ||
57 | |||
58 | if (acpi_disabled) | ||
59 | return -ENOENT; | ||
60 | |||
61 | adev = ACPI_COMPANION(dev); | ||
62 | if (!adev) { | ||
63 | pr_err("VFIO: ACPI companion device not found for %s\n", | ||
64 | vdev->name); | ||
65 | return -ENODEV; | ||
66 | } | ||
67 | |||
68 | #ifdef CONFIG_ACPI | ||
69 | vdev->acpihid = acpi_device_hid(adev); | ||
70 | #endif | ||
71 | return WARN_ON(!vdev->acpihid) ? -EINVAL : 0; | ||
72 | } | ||
73 | |||
52 | static bool vfio_platform_has_reset(struct vfio_platform_device *vdev) | 74 | static bool vfio_platform_has_reset(struct vfio_platform_device *vdev) |
53 | { | 75 | { |
54 | return vdev->of_reset ? true : false; | 76 | return vdev->of_reset ? true : false; |
@@ -547,6 +569,37 @@ static const struct vfio_device_ops vfio_platform_ops = { | |||
547 | .mmap = vfio_platform_mmap, | 569 | .mmap = vfio_platform_mmap, |
548 | }; | 570 | }; |
549 | 571 | ||
572 | int vfio_platform_of_probe(struct vfio_platform_device *vdev, | ||
573 | struct device *dev) | ||
574 | { | ||
575 | int ret; | ||
576 | |||
577 | ret = device_property_read_string(dev, "compatible", | ||
578 | &vdev->compat); | ||
579 | if (ret) | ||
580 | pr_err("VFIO: cannot retrieve compat for %s\n", | ||
581 | vdev->name); | ||
582 | |||
583 | return ret; | ||
584 | } | ||
585 | |||
586 | /* | ||
587 | * There can be two kernel build combinations. One build where | ||
588 | * ACPI is not selected in Kconfig and another one with the ACPI Kconfig. | ||
589 | * | ||
590 | * In the first case, vfio_platform_acpi_probe will return since | ||
591 | * acpi_disabled is 1. DT user will not see any kind of messages from | ||
592 | * ACPI. | ||
593 | * | ||
594 | * In the second case, both DT and ACPI is compiled in but the system is | ||
595 | * booting with any of these combinations. | ||
596 | * | ||
597 | * If the firmware is DT type, then acpi_disabled is 1. The ACPI probe routine | ||
598 | * terminates immediately without any messages. | ||
599 | * | ||
600 | * If the firmware is ACPI type, then acpi_disabled is 0. All other checks are | ||
601 | * valid checks. We cannot claim that this system is DT. | ||
602 | */ | ||
550 | int vfio_platform_probe_common(struct vfio_platform_device *vdev, | 603 | int vfio_platform_probe_common(struct vfio_platform_device *vdev, |
551 | struct device *dev) | 604 | struct device *dev) |
552 | { | 605 | { |
@@ -556,11 +609,12 @@ int vfio_platform_probe_common(struct vfio_platform_device *vdev, | |||
556 | if (!vdev) | 609 | if (!vdev) |
557 | return -EINVAL; | 610 | return -EINVAL; |
558 | 611 | ||
559 | ret = device_property_read_string(dev, "compatible", &vdev->compat); | 612 | ret = vfio_platform_acpi_probe(vdev, dev); |
560 | if (ret) { | 613 | if (ret) |
561 | pr_err("VFIO: cannot retrieve compat for %s\n", vdev->name); | 614 | ret = vfio_platform_of_probe(vdev, dev); |
562 | return -EINVAL; | 615 | |
563 | } | 616 | if (ret) |
617 | return ret; | ||
564 | 618 | ||
565 | vdev->device = dev; | 619 | vdev->device = dev; |
566 | 620 | ||
diff --git a/drivers/vfio/platform/vfio_platform_private.h b/drivers/vfio/platform/vfio_platform_private.h index 71ed7d1c1b7d..ba9e4f8b0746 100644 --- a/drivers/vfio/platform/vfio_platform_private.h +++ b/drivers/vfio/platform/vfio_platform_private.h | |||
@@ -58,6 +58,7 @@ struct vfio_platform_device { | |||
58 | struct mutex igate; | 58 | struct mutex igate; |
59 | struct module *parent_module; | 59 | struct module *parent_module; |
60 | const char *compat; | 60 | const char *compat; |
61 | const char *acpihid; | ||
61 | struct module *reset_module; | 62 | struct module *reset_module; |
62 | struct device *device; | 63 | struct device *device; |
63 | 64 | ||