summaryrefslogtreecommitdiffstats
path: root/drivers/acpi/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r--drivers/acpi/scan.c104
1 files changed, 93 insertions, 11 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 70fd5502c284..ac8a8a52ee4a 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -13,6 +13,7 @@
13#include <linux/dmi.h> 13#include <linux/dmi.h>
14#include <linux/nls.h> 14#include <linux/nls.h>
15#include <linux/dma-mapping.h> 15#include <linux/dma-mapping.h>
16#include <linux/platform_data/x86/apple.h>
16 17
17#include <asm/pgtable.h> 18#include <asm/pgtable.h>
18 19
@@ -1360,6 +1361,85 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
1360} 1361}
1361 1362
1362/** 1363/**
1364 * acpi_dma_get_range() - Get device DMA parameters.
1365 *
1366 * @dev: device to configure
1367 * @dma_addr: pointer device DMA address result
1368 * @offset: pointer to the DMA offset result
1369 * @size: pointer to DMA range size result
1370 *
1371 * Evaluate DMA regions and return respectively DMA region start, offset
1372 * and size in dma_addr, offset and size on parsing success; it does not
1373 * update the passed in values on failure.
1374 *
1375 * Return 0 on success, < 0 on failure.
1376 */
1377int acpi_dma_get_range(struct device *dev, u64 *dma_addr, u64 *offset,
1378 u64 *size)
1379{
1380 struct acpi_device *adev;
1381 LIST_HEAD(list);
1382 struct resource_entry *rentry;
1383 int ret;
1384 struct device *dma_dev = dev;
1385 u64 len, dma_start = U64_MAX, dma_end = 0, dma_offset = 0;
1386
1387 /*
1388 * Walk the device tree chasing an ACPI companion with a _DMA
1389 * object while we go. Stop if we find a device with an ACPI
1390 * companion containing a _DMA method.
1391 */
1392 do {
1393 adev = ACPI_COMPANION(dma_dev);
1394 if (adev && acpi_has_method(adev->handle, METHOD_NAME__DMA))
1395 break;
1396
1397 dma_dev = dma_dev->parent;
1398 } while (dma_dev);
1399
1400 if (!dma_dev)
1401 return -ENODEV;
1402
1403 if (!acpi_has_method(adev->handle, METHOD_NAME__CRS)) {
1404 acpi_handle_warn(adev->handle, "_DMA is valid only if _CRS is present\n");
1405 return -EINVAL;
1406 }
1407
1408 ret = acpi_dev_get_dma_resources(adev, &list);
1409 if (ret > 0) {
1410 list_for_each_entry(rentry, &list, node) {
1411 if (dma_offset && rentry->offset != dma_offset) {
1412 ret = -EINVAL;
1413 dev_warn(dma_dev, "Can't handle multiple windows with different offsets\n");
1414 goto out;
1415 }
1416 dma_offset = rentry->offset;
1417
1418 /* Take lower and upper limits */
1419 if (rentry->res->start < dma_start)
1420 dma_start = rentry->res->start;
1421 if (rentry->res->end > dma_end)
1422 dma_end = rentry->res->end;
1423 }
1424
1425 if (dma_start >= dma_end) {
1426 ret = -EINVAL;
1427 dev_dbg(dma_dev, "Invalid DMA regions configuration\n");
1428 goto out;
1429 }
1430
1431 *dma_addr = dma_start - dma_offset;
1432 len = dma_end - dma_start;
1433 *size = max(len, len + 1);
1434 *offset = dma_offset;
1435 }
1436 out:
1437 acpi_dev_free_resource_list(&list);
1438
1439 return ret >= 0 ? 0 : ret;
1440}
1441
1442/**
1363 * acpi_dma_configure - Set-up DMA configuration for the device. 1443 * acpi_dma_configure - Set-up DMA configuration for the device.
1364 * @dev: The pointer to the device 1444 * @dev: The pointer to the device
1365 * @attr: device dma attributes 1445 * @attr: device dma attributes
@@ -1367,20 +1447,16 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
1367int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr) 1447int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
1368{ 1448{
1369 const struct iommu_ops *iommu; 1449 const struct iommu_ops *iommu;
1370 u64 size; 1450 u64 dma_addr = 0, size = 0;
1371 1451
1372 iort_set_dma_mask(dev); 1452 iort_dma_setup(dev, &dma_addr, &size);
1373 1453
1374 iommu = iort_iommu_configure(dev); 1454 iommu = iort_iommu_configure(dev);
1375 if (IS_ERR(iommu) && PTR_ERR(iommu) == -EPROBE_DEFER) 1455 if (IS_ERR(iommu) && PTR_ERR(iommu) == -EPROBE_DEFER)
1376 return -EPROBE_DEFER; 1456 return -EPROBE_DEFER;
1377 1457
1378 size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1); 1458 arch_setup_dma_ops(dev, dma_addr, size,
1379 /* 1459 iommu, attr == DEV_DMA_COHERENT);
1380 * Assume dma valid range starts at 0 and covers the whole
1381 * coherent_dma_mask.
1382 */
1383 arch_setup_dma_ops(dev, 0, size, iommu, attr == DEV_DMA_COHERENT);
1384 1460
1385 return 0; 1461 return 0;
1386} 1462}
@@ -1452,6 +1528,12 @@ static bool acpi_is_spi_i2c_slave(struct acpi_device *device)
1452 struct list_head resource_list; 1528 struct list_head resource_list;
1453 bool is_spi_i2c_slave = false; 1529 bool is_spi_i2c_slave = false;
1454 1530
1531 /* Macs use device properties in lieu of _CRS resources */
1532 if (x86_apple_machine &&
1533 (fwnode_property_present(&device->fwnode, "spiSclkPeriod") ||
1534 fwnode_property_present(&device->fwnode, "i2cAddress")))
1535 return true;
1536
1455 INIT_LIST_HEAD(&resource_list); 1537 INIT_LIST_HEAD(&resource_list);
1456 acpi_dev_get_resources(device, &resource_list, acpi_check_spi_i2c_slave, 1538 acpi_dev_get_resources(device, &resource_list, acpi_check_spi_i2c_slave,
1457 &is_spi_i2c_slave); 1539 &is_spi_i2c_slave);
@@ -2058,6 +2140,9 @@ int __init acpi_scan_init(void)
2058 acpi_get_spcr_uart_addr(); 2140 acpi_get_spcr_uart_addr();
2059 } 2141 }
2060 2142
2143 acpi_gpe_apply_masked_gpes();
2144 acpi_update_all_gpes();
2145
2061 mutex_lock(&acpi_scan_lock); 2146 mutex_lock(&acpi_scan_lock);
2062 /* 2147 /*
2063 * Enumerate devices in the ACPI namespace. 2148 * Enumerate devices in the ACPI namespace.
@@ -2082,9 +2167,6 @@ int __init acpi_scan_init(void)
2082 } 2167 }
2083 } 2168 }
2084 2169
2085 acpi_gpe_apply_masked_gpes();
2086 acpi_update_all_gpes();
2087
2088 acpi_scan_initialized = true; 2170 acpi_scan_initialized = true;
2089 2171
2090 out: 2172 out: