Re: ACPI device using sub-resource of PCI device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Aug 16, 2016 at 2:15 AM, Mika Westerberg
<mika.westerberg@xxxxxxxxxxxxxxx> wrote:
> On Fri, Aug 12, 2016 at 11:45:30AM -0500, Aaron Durbin wrote:
>> Was anyone able to take a look into a solution for the current
>> problem?  Again, please feel free to ask if anyone would like help
>> testing potential solutions.
>
> Below is one proposal for fixing the issue. It is just a prototype and
> I'm not sure if it takes everything needed into account. Would you be
> able to try it out and let us know if it works for you?

Yes. I'll give it a go. I'm traveling this week so it won't likely be
til early next week. Thanks for the proposed fix. I'll report back on
my findings.

>
> diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
> index 159f7f19abce..72068415f806 100644
> --- a/drivers/acpi/acpi_platform.c
> +++ b/drivers/acpi/acpi_platform.c
> @@ -18,6 +18,7 @@
>  #include <linux/module.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/platform_device.h>
> +#include <linux/pci.h>
>
>  #include "internal.h"
>
> @@ -30,6 +31,35 @@ static const struct acpi_device_id forbidden_id_list[] = {
>         {"", 0},
>  };
>
> +static struct resource *acpi_find_parent_resource(struct acpi_device *adev,
> +                                                 struct resource *res)
> +{
> +       struct device *parent;
> +
> +       parent = acpi_get_first_physical_node(adev->parent);
> +       if (!parent)
> +               return NULL;
> +
> +#if IS_ENABLED(CONFIG_PCI)
> +       if (dev_is_pci(parent)) {
> +               struct pci_dev *pdev = to_pci_dev(parent);
> +
> +               if (!pci_is_bridge(pdev)) {
> +                       int i;
> +
> +                       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
> +                               struct resource *r = &pdev->resource[i];
> +
> +                               if (r->start && resource_contains(r, res))
> +                                       return r;
> +                       }
> +               }
> +       }
> +#endif
> +
> +       return NULL;
> +}
> +
>  /**
>   * acpi_create_platform_device - Create platform device for ACPI device node
>   * @adev: ACPI device node to create a platform device for.
> @@ -69,8 +99,17 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
>                         return ERR_PTR(-ENOMEM);
>                 }
>                 count = 0;
> -               list_for_each_entry(rentry, &resource_list, node)
> -                       resources[count++] = *rentry->res;
> +               list_for_each_entry(rentry, &resource_list, node) {
> +                       struct resource *res = &resources[count++];
> +
> +                       *res = *rentry->res;
> +                       /*
> +                        * If the device has parent we need to take its
> +                        * resources into account as well because this
> +                        * device might consume part of those.
> +                        */
> +                       res->parent = acpi_find_parent_resource(adev, res);
> +               }
>
>                 acpi_dev_free_resource_list(&resource_list);
>         }
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux