diff options
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/acpi_apd.c | 4 | ||||
-rw-r--r-- | drivers/acpi/acpi_lpss.c | 14 | ||||
-rw-r--r-- | drivers/acpi/acpi_watchdog.c | 7 | ||||
-rw-r--r-- | drivers/acpi/arm64/iort.c | 140 |
4 files changed, 109 insertions, 56 deletions
diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c index fc6c416f8724..d5999eb41c00 100644 --- a/drivers/acpi/acpi_apd.c +++ b/drivers/acpi/acpi_apd.c @@ -180,8 +180,8 @@ static const struct acpi_device_id acpi_apd_device_ids[] = { { "APMC0D0F", APD_ADDR(xgene_i2c_desc) }, { "BRCM900D", APD_ADDR(vulcan_spi_desc) }, { "CAV900D", APD_ADDR(vulcan_spi_desc) }, - { "HISI0A21", APD_ADDR(hip07_i2c_desc) }, - { "HISI0A22", APD_ADDR(hip08_i2c_desc) }, + { "HISI02A1", APD_ADDR(hip07_i2c_desc) }, + { "HISI02A2", APD_ADDR(hip08_i2c_desc) }, #endif { } }; diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index e51a1e98e62f..f88caf5aab76 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -85,6 +85,7 @@ static const struct lpss_device_desc lpss_dma_desc = { }; struct lpss_private_data { + struct acpi_device *adev; void __iomem *mmio_base; resource_size_t mmio_size; unsigned int fixed_clk_rate; @@ -155,6 +156,12 @@ static struct pwm_lookup byt_pwm_lookup[] = { static void byt_pwm_setup(struct lpss_private_data *pdata) { + struct acpi_device *adev = pdata->adev; + + /* Only call pwm_add_table for the first PWM controller */ + if (!adev->pnp.unique_id || strcmp(adev->pnp.unique_id, "1")) + return; + if (!acpi_dev_present("INT33FD", NULL, -1)) pwm_add_table(byt_pwm_lookup, ARRAY_SIZE(byt_pwm_lookup)); } @@ -180,6 +187,12 @@ static struct pwm_lookup bsw_pwm_lookup[] = { static void bsw_pwm_setup(struct lpss_private_data *pdata) { + struct acpi_device *adev = pdata->adev; + + /* Only call pwm_add_table for the first PWM controller */ + if (!adev->pnp.unique_id || strcmp(adev->pnp.unique_id, "1")) + return; + pwm_add_table(bsw_pwm_lookup, ARRAY_SIZE(bsw_pwm_lookup)); } @@ -456,6 +469,7 @@ static int acpi_lpss_create_device(struct acpi_device *adev, goto err_out; } + pdata->adev = adev; pdata->dev_desc = dev_desc; if (dev_desc->setup) diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c index 8c4e0a18460a..bf22c29d2517 100644 --- a/drivers/acpi/acpi_watchdog.c +++ b/drivers/acpi/acpi_watchdog.c @@ -86,7 +86,12 @@ void __init acpi_watchdog_init(void) found = false; resource_list_for_each_entry(rentry, &resource_list) { - if (resource_contains(rentry->res, &res)) { + if (rentry->res->flags == res.flags && + resource_overlaps(rentry->res, &res)) { + if (res.start < rentry->res->start) + rentry->res->start = res.start; + if (res.end > rentry->res->end) + rentry->res->end = res.end; found = true; break; } diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index a3215ee671c1..736783c67ea0 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -588,7 +588,8 @@ void acpi_configure_pmsi_domain(struct device *dev) dev_set_msi_domain(dev, msi_domain); } -static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data) +static int __maybe_unused __get_pci_rid(struct pci_dev *pdev, u16 alias, + void *data) { u32 *rid = data; @@ -633,8 +634,7 @@ int iort_add_device_replay(const struct iommu_ops *ops, struct device *dev) { int err = 0; - if (!IS_ERR_OR_NULL(ops) && ops->add_device && dev->bus && - !dev->iommu_group) + if (ops->add_device && dev->bus && !dev->iommu_group) err = ops->add_device(dev); return err; @@ -648,36 +648,49 @@ int iort_add_device_replay(const struct iommu_ops *ops, struct device *dev) { return 0; } #endif -static const struct iommu_ops *iort_iommu_xlate(struct device *dev, - struct acpi_iort_node *node, - u32 streamid) +static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node, + u32 streamid) { - const struct iommu_ops *ops = NULL; - int ret = -ENODEV; + const struct iommu_ops *ops; struct fwnode_handle *iort_fwnode; - if (node) { - iort_fwnode = iort_get_fwnode(node); - if (!iort_fwnode) - return NULL; + if (!node) + return -ENODEV; - ops = iommu_ops_from_fwnode(iort_fwnode); - /* - * If the ops look-up fails, this means that either - * the SMMU drivers have not been probed yet or that - * the SMMU drivers are not built in the kernel; - * Depending on whether the SMMU drivers are built-in - * in the kernel or not, defer the IOMMU configuration - * or just abort it. - */ - if (!ops) - return iort_iommu_driver_enabled(node->type) ? - ERR_PTR(-EPROBE_DEFER) : NULL; + iort_fwnode = iort_get_fwnode(node); + if (!iort_fwnode) + return -ENODEV; - ret = arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops); - } + /* + * If the ops look-up fails, this means that either + * the SMMU drivers have not been probed yet or that + * the SMMU drivers are not built in the kernel; + * Depending on whether the SMMU drivers are built-in + * in the kernel or not, defer the IOMMU configuration + * or just abort it. + */ + ops = iommu_ops_from_fwnode(iort_fwnode); + if (!ops) + return iort_iommu_driver_enabled(node->type) ? + -EPROBE_DEFER : -ENODEV; - return ret ? NULL : ops; + return arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops); +} + +struct iort_pci_alias_info { + struct device *dev; + struct acpi_iort_node *node; +}; + +static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) +{ + struct iort_pci_alias_info *info = data; + struct acpi_iort_node *parent; + u32 streamid; + + parent = iort_node_map_id(info->node, alias, &streamid, + IORT_IOMMU_TYPE); + return iort_iommu_xlate(info->dev, parent, streamid); } /** @@ -713,9 +726,9 @@ void iort_set_dma_mask(struct device *dev) const struct iommu_ops *iort_iommu_configure(struct device *dev) { struct acpi_iort_node *node, *parent; - const struct iommu_ops *ops = NULL; + const struct iommu_ops *ops; u32 streamid = 0; - int err; + int err = -ENODEV; /* * If we already translated the fwspec there @@ -727,21 +740,16 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev) if (dev_is_pci(dev)) { struct pci_bus *bus = to_pci_dev(dev)->bus; - u32 rid; - - pci_for_each_dma_alias(to_pci_dev(dev), __get_pci_rid, - &rid); + struct iort_pci_alias_info info = { .dev = dev }; node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX, iort_match_node_callback, &bus->dev); if (!node) return NULL; - parent = iort_node_map_id(node, rid, &streamid, - IORT_IOMMU_TYPE); - - ops = iort_iommu_xlate(dev, parent, streamid); - + info.node = node; + err = pci_for_each_dma_alias(to_pci_dev(dev), + iort_pci_iommu_init, &info); } else { int i = 0; @@ -750,31 +758,30 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev) if (!node) return NULL; - parent = iort_node_map_platform_id(node, &streamid, - IORT_IOMMU_TYPE, i++); - - while (parent) { - ops = iort_iommu_xlate(dev, parent, streamid); - if (IS_ERR_OR_NULL(ops)) - return ops; - + do { parent = iort_node_map_platform_id(node, &streamid, IORT_IOMMU_TYPE, i++); - } + + if (parent) + err = iort_iommu_xlate(dev, parent, streamid); + } while (parent && !err); } /* * If we have reason to believe the IOMMU driver missed the initial * add_device callback for dev, replay it to get things in order. */ - err = iort_add_device_replay(ops, dev); - if (err) - ops = ERR_PTR(err); + if (!err) { + ops = iort_fwspec_iommu_ops(dev->iommu_fwspec); + err = iort_add_device_replay(ops, dev); + } /* Ignore all other errors apart from EPROBE_DEFER */ - if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) { - dev_dbg(dev, "Adding to IOMMU failed: %ld\n", PTR_ERR(ops)); + if (err == -EPROBE_DEFER) { + ops = ERR_PTR(err); + } else if (err) { + dev_dbg(dev, "Adding to IOMMU failed: %d\n", err); ops = NULL; } @@ -908,6 +915,27 @@ static bool __init arm_smmu_v3_is_coherent(struct acpi_iort_node *node) return smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE; } +#if defined(CONFIG_ACPI_NUMA) && defined(ACPI_IORT_SMMU_V3_PXM_VALID) +/* + * set numa proximity domain for smmuv3 device + */ +static void __init arm_smmu_v3_set_proximity(struct device *dev, + struct acpi_iort_node *node) +{ + struct acpi_iort_smmu_v3 *smmu; + + smmu = (struct acpi_iort_smmu_v3 *)node->node_data; + if (smmu->flags & ACPI_IORT_SMMU_V3_PXM_VALID) { + set_dev_node(dev, acpi_map_pxm_to_node(smmu->pxm)); + pr_info("SMMU-v3[%llx] Mapped to Proximity domain %d\n", + smmu->base_address, + smmu->pxm); + } +} +#else +#define arm_smmu_v3_set_proximity NULL +#endif + static int __init arm_smmu_count_resources(struct acpi_iort_node *node) { struct acpi_iort_smmu *smmu; @@ -977,13 +1005,16 @@ struct iort_iommu_config { int (*iommu_count_resources)(struct acpi_iort_node *node); void (*iommu_init_resources)(struct resource *res, struct acpi_iort_node *node); + void (*iommu_set_proximity)(struct device *dev, + struct acpi_iort_node *node); }; static const struct iort_iommu_config iort_arm_smmu_v3_cfg __initconst = { .name = "arm-smmu-v3", .iommu_is_coherent = arm_smmu_v3_is_coherent, .iommu_count_resources = arm_smmu_v3_count_resources, - .iommu_init_resources = arm_smmu_v3_init_resources + .iommu_init_resources = arm_smmu_v3_init_resources, + .iommu_set_proximity = arm_smmu_v3_set_proximity, }; static const struct iort_iommu_config iort_arm_smmu_cfg __initconst = { @@ -1028,6 +1059,9 @@ static int __init iort_add_smmu_platform_device(struct acpi_iort_node *node) if (!pdev) return -ENOMEM; + if (ops->iommu_set_proximity) + ops->iommu_set_proximity(&pdev->dev, node); + count = ops->iommu_count_resources(node); r = kcalloc(count, sizeof(*r), GFP_KERNEL); |