diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-12 14:50:33 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-12 14:50:33 -0500 |
commit | be23c9d20b341a58ad7107f9e9aa5735cea3da13 (patch) | |
tree | da5e5ede73ccba5e3464821fb0cfb67c027f796a | |
parent | 5d50ac70fe98518dbf620bfba8184254663125eb (diff) | |
parent | f57ab32a843690fe7431ebb3a2f461e689a2e3c7 (diff) |
Merge tag 'pm+acpi-4.4-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull more power management and ACPI updates from Rafael Wysocki:
"The only new feature in this batch is support for the ACPI _CCA device
configuration object, which it a pre-requisite for future ACPI PCI
support on ARM64, but should not affect the other architectures.
The rest is fixes and cleanups, mostly in cpufreq (including
intel_pstate), the Operating Performace Points (OPP) framework and
tools (cpupower and turbostat).
Specifics:
- Support for the ACPI _CCA configuration object intended to tell the
OS whether or not a bus master device supports hardware managed
cache coherency and a new set of functions to allow drivers to
check the cache coherency support for devices in a platform
firmware interface agnostic way (Suravee Suthikulpanit, Jeremy
Linton).
- ACPI backlight quirks for ESPRIMO Mobile M9410 and Dell XPS L421X
(Aaron Lu, Hans de Goede).
- Fixes for the arm_big_little and s5pv210-cpufreq cpufreq drivers
(Jon Medhurst, Nicolas Pitre).
- kfree()-related fixup for the recently introduced CPPC cpufreq
frontend (Markus Elfring).
- intel_pstate fix reducing kernel log noise on systems where
P-states are managed by hardware (Prarit Bhargava).
- intel_pstate maintainers information update (Srinivas Pandruvada).
- cpufreq core optimization related to the handling of delayed work
items used by governors (Viresh Kumar).
- Locking fixes and cleanups of the Operating Performance Points
(OPP) framework (Viresh Kumar).
- Generic power domains framework cleanups (Lina Iyer).
- cpupower tool updates (Jacob Tanenbaum, Sriram Raghunathan, Thomas
Renninger).
- turbostat tool updates (Len Brown)"
* tag 'pm+acpi-4.4-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (32 commits)
PCI: ACPI: Add support for PCI device DMA coherency
PCI: OF: Move of_pci_dma_configure() to pci_dma_configure()
of/pci: Fix pci_get_host_bridge_device leak
device property: ACPI: Remove unused DMA APIs
device property: ACPI: Make use of the new DMA Attribute APIs
device property: Adding DMA Attribute APIs for Generic Devices
ACPI: Adding DMA Attribute APIs for ACPI Device
device property: Introducing enum dev_dma_attr
ACPI: Honor ACPI _CCA attribute setting
cpufreq: CPPC: Delete an unnecessary check before the function call kfree()
PM / OPP: Add opp_rcu_lockdep_assert() to _find_device_opp()
PM / OPP: Hold dev_opp_list_lock for writers
PM / OPP: Protect updates to list_dev with mutex
PM / OPP: Propagate error properly from dev_pm_opp_set_sharing_cpus()
cpufreq: s5pv210-cpufreq: fix wrong do_div() usage
MAINTAINERS: update for intel P-state driver
Creating a common structure initialization pattern for struct option
cpupower: Enable disabled Cstates if they are below max latency
cpupower: Remove debug message when using cpupower idle-set -D switch
cpupower: cpupower monitor reports uninitialized values for offline cpus
...
35 files changed, 405 insertions, 209 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 35fe7ae0492e..8d941d6818cd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -5505,7 +5505,8 @@ S: Supported | |||
5505 | F: drivers/idle/intel_idle.c | 5505 | F: drivers/idle/intel_idle.c |
5506 | 5506 | ||
5507 | INTEL PSTATE DRIVER | 5507 | INTEL PSTATE DRIVER |
5508 | M: Kristen Carlson Accardi <kristen@linux.intel.com> | 5508 | M: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> |
5509 | M: Len Brown <lenb@kernel.org> | ||
5509 | L: linux-pm@vger.kernel.org | 5510 | L: linux-pm@vger.kernel.org |
5510 | S: Supported | 5511 | S: Supported |
5511 | F: drivers/cpufreq/intel_pstate.c | 5512 | F: drivers/cpufreq/intel_pstate.c |
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 06a67d5f2846..296b7a14893a 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c | |||
@@ -103,7 +103,12 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) | |||
103 | pdevinfo.res = resources; | 103 | pdevinfo.res = resources; |
104 | pdevinfo.num_res = count; | 104 | pdevinfo.num_res = count; |
105 | pdevinfo.fwnode = acpi_fwnode_handle(adev); | 105 | pdevinfo.fwnode = acpi_fwnode_handle(adev); |
106 | pdevinfo.dma_mask = acpi_check_dma(adev, NULL) ? DMA_BIT_MASK(32) : 0; | 106 | |
107 | if (acpi_dma_supported(adev)) | ||
108 | pdevinfo.dma_mask = DMA_BIT_MASK(32); | ||
109 | else | ||
110 | pdevinfo.dma_mask = 0; | ||
111 | |||
107 | pdev = platform_device_register_full(&pdevinfo); | 112 | pdev = platform_device_register_full(&pdevinfo); |
108 | if (IS_ERR(pdev)) | 113 | if (IS_ERR(pdev)) |
109 | dev_err(&adev->dev, "platform device creation failed: %ld\n", | 114 | dev_err(&adev->dev, "platform device creation failed: %ld\n", |
diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index 5778e8e4313a..3405f7a41e25 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c | |||
@@ -77,6 +77,12 @@ module_param(allow_duplicates, bool, 0644); | |||
77 | static int disable_backlight_sysfs_if = -1; | 77 | static int disable_backlight_sysfs_if = -1; |
78 | module_param(disable_backlight_sysfs_if, int, 0444); | 78 | module_param(disable_backlight_sysfs_if, int, 0444); |
79 | 79 | ||
80 | static bool device_id_scheme = false; | ||
81 | module_param(device_id_scheme, bool, 0444); | ||
82 | |||
83 | static bool only_lcd = false; | ||
84 | module_param(only_lcd, bool, 0444); | ||
85 | |||
80 | static int register_count; | 86 | static int register_count; |
81 | static DEFINE_MUTEX(register_count_mutex); | 87 | static DEFINE_MUTEX(register_count_mutex); |
82 | static struct mutex video_list_lock; | 88 | static struct mutex video_list_lock; |
@@ -394,6 +400,18 @@ static int video_disable_backlight_sysfs_if( | |||
394 | return 0; | 400 | return 0; |
395 | } | 401 | } |
396 | 402 | ||
403 | static int video_set_device_id_scheme(const struct dmi_system_id *d) | ||
404 | { | ||
405 | device_id_scheme = true; | ||
406 | return 0; | ||
407 | } | ||
408 | |||
409 | static int video_enable_only_lcd(const struct dmi_system_id *d) | ||
410 | { | ||
411 | only_lcd = true; | ||
412 | return 0; | ||
413 | } | ||
414 | |||
397 | static struct dmi_system_id video_dmi_table[] = { | 415 | static struct dmi_system_id video_dmi_table[] = { |
398 | /* | 416 | /* |
399 | * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121 | 417 | * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121 |
@@ -455,6 +473,33 @@ static struct dmi_system_id video_dmi_table[] = { | |||
455 | DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R830"), | 473 | DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R830"), |
456 | }, | 474 | }, |
457 | }, | 475 | }, |
476 | /* | ||
477 | * Some machine's _DOD IDs don't have bit 31(Device ID Scheme) set | ||
478 | * but the IDs actually follow the Device ID Scheme. | ||
479 | */ | ||
480 | { | ||
481 | /* https://bugzilla.kernel.org/show_bug.cgi?id=104121 */ | ||
482 | .callback = video_set_device_id_scheme, | ||
483 | .ident = "ESPRIMO Mobile M9410", | ||
484 | .matches = { | ||
485 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
486 | DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile M9410"), | ||
487 | }, | ||
488 | }, | ||
489 | /* | ||
490 | * Some machines have multiple video output devices, but only the one | ||
491 | * that is the type of LCD can do the backlight control so we should not | ||
492 | * register backlight interface for other video output devices. | ||
493 | */ | ||
494 | { | ||
495 | /* https://bugzilla.kernel.org/show_bug.cgi?id=104121 */ | ||
496 | .callback = video_enable_only_lcd, | ||
497 | .ident = "ESPRIMO Mobile M9410", | ||
498 | .matches = { | ||
499 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
500 | DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile M9410"), | ||
501 | }, | ||
502 | }, | ||
458 | {} | 503 | {} |
459 | }; | 504 | }; |
460 | 505 | ||
@@ -1003,7 +1048,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device, | |||
1003 | 1048 | ||
1004 | attribute = acpi_video_get_device_attr(video, device_id); | 1049 | attribute = acpi_video_get_device_attr(video, device_id); |
1005 | 1050 | ||
1006 | if (attribute && attribute->device_id_scheme) { | 1051 | if (attribute && (attribute->device_id_scheme || device_id_scheme)) { |
1007 | switch (attribute->display_type) { | 1052 | switch (attribute->display_type) { |
1008 | case ACPI_VIDEO_DISPLAY_CRT: | 1053 | case ACPI_VIDEO_DISPLAY_CRT: |
1009 | data->flags.crt = 1; | 1054 | data->flags.crt = 1; |
@@ -1568,15 +1613,6 @@ static void acpi_video_dev_register_backlight(struct acpi_video_device *device) | |||
1568 | static int count; | 1613 | static int count; |
1569 | char *name; | 1614 | char *name; |
1570 | 1615 | ||
1571 | /* | ||
1572 | * Do not create backlight device for video output | ||
1573 | * device that is not in the enumerated list. | ||
1574 | */ | ||
1575 | if (!acpi_video_device_in_dod(device)) { | ||
1576 | dev_dbg(&device->dev->dev, "not in _DOD list, ignore\n"); | ||
1577 | return; | ||
1578 | } | ||
1579 | |||
1580 | result = acpi_video_init_brightness(device); | 1616 | result = acpi_video_init_brightness(device); |
1581 | if (result) | 1617 | if (result) |
1582 | return; | 1618 | return; |
@@ -1657,6 +1693,22 @@ static void acpi_video_run_bcl_for_osi(struct acpi_video_bus *video) | |||
1657 | mutex_unlock(&video->device_list_lock); | 1693 | mutex_unlock(&video->device_list_lock); |
1658 | } | 1694 | } |
1659 | 1695 | ||
1696 | static bool acpi_video_should_register_backlight(struct acpi_video_device *dev) | ||
1697 | { | ||
1698 | /* | ||
1699 | * Do not create backlight device for video output | ||
1700 | * device that is not in the enumerated list. | ||
1701 | */ | ||
1702 | if (!acpi_video_device_in_dod(dev)) { | ||
1703 | dev_dbg(&dev->dev->dev, "not in _DOD list, ignore\n"); | ||
1704 | return false; | ||
1705 | } | ||
1706 | |||
1707 | if (only_lcd) | ||
1708 | return dev->flags.lcd; | ||
1709 | return true; | ||
1710 | } | ||
1711 | |||
1660 | static int acpi_video_bus_register_backlight(struct acpi_video_bus *video) | 1712 | static int acpi_video_bus_register_backlight(struct acpi_video_bus *video) |
1661 | { | 1713 | { |
1662 | struct acpi_video_device *dev; | 1714 | struct acpi_video_device *dev; |
@@ -1670,8 +1722,10 @@ static int acpi_video_bus_register_backlight(struct acpi_video_bus *video) | |||
1670 | return 0; | 1722 | return 0; |
1671 | 1723 | ||
1672 | mutex_lock(&video->device_list_lock); | 1724 | mutex_lock(&video->device_list_lock); |
1673 | list_for_each_entry(dev, &video->video_device_list, entry) | 1725 | list_for_each_entry(dev, &video->video_device_list, entry) { |
1674 | acpi_video_dev_register_backlight(dev); | 1726 | if (acpi_video_should_register_backlight(dev)) |
1727 | acpi_video_dev_register_backlight(dev); | ||
1728 | } | ||
1675 | mutex_unlock(&video->device_list_lock); | 1729 | mutex_unlock(&video->device_list_lock); |
1676 | 1730 | ||
1677 | video->backlight_registered = true; | 1731 | video->backlight_registered = true; |
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 1470ae4f98c0..5ea5dc219f56 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -168,7 +168,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev) | |||
168 | struct list_head *physnode_list; | 168 | struct list_head *physnode_list; |
169 | unsigned int node_id; | 169 | unsigned int node_id; |
170 | int retval = -EINVAL; | 170 | int retval = -EINVAL; |
171 | bool coherent; | 171 | enum dev_dma_attr attr; |
172 | 172 | ||
173 | if (has_acpi_companion(dev)) { | 173 | if (has_acpi_companion(dev)) { |
174 | if (acpi_dev) { | 174 | if (acpi_dev) { |
@@ -225,8 +225,10 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev) | |||
225 | if (!has_acpi_companion(dev)) | 225 | if (!has_acpi_companion(dev)) |
226 | ACPI_COMPANION_SET(dev, acpi_dev); | 226 | ACPI_COMPANION_SET(dev, acpi_dev); |
227 | 227 | ||
228 | if (acpi_check_dma(acpi_dev, &coherent)) | 228 | attr = acpi_get_dma_attr(acpi_dev); |
229 | arch_setup_dma_ops(dev, 0, 0, NULL, coherent); | 229 | if (attr != DEV_DMA_NOT_SUPPORTED) |
230 | arch_setup_dma_ops(dev, 0, 0, NULL, | ||
231 | attr == DEV_DMA_COHERENT); | ||
230 | 232 | ||
231 | acpi_physnode_link_name(physical_node_name, node_id); | 233 | acpi_physnode_link_name(physical_node_name, node_id); |
232 | retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, | 234 | retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index daf9fc8329e6..78d5f02a073b 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -1308,6 +1308,48 @@ void acpi_free_pnp_ids(struct acpi_device_pnp *pnp) | |||
1308 | kfree(pnp->unique_id); | 1308 | kfree(pnp->unique_id); |
1309 | } | 1309 | } |
1310 | 1310 | ||
1311 | /** | ||
1312 | * acpi_dma_supported - Check DMA support for the specified device. | ||
1313 | * @adev: The pointer to acpi device | ||
1314 | * | ||
1315 | * Return false if DMA is not supported. Otherwise, return true | ||
1316 | */ | ||
1317 | bool acpi_dma_supported(struct acpi_device *adev) | ||
1318 | { | ||
1319 | if (!adev) | ||
1320 | return false; | ||
1321 | |||
1322 | if (adev->flags.cca_seen) | ||
1323 | return true; | ||
1324 | |||
1325 | /* | ||
1326 | * Per ACPI 6.0 sec 6.2.17, assume devices can do cache-coherent | ||
1327 | * DMA on "Intel platforms". Presumably that includes all x86 and | ||
1328 | * ia64, and other arches will set CONFIG_ACPI_CCA_REQUIRED=y. | ||
1329 | */ | ||
1330 | if (!IS_ENABLED(CONFIG_ACPI_CCA_REQUIRED)) | ||
1331 | return true; | ||
1332 | |||
1333 | return false; | ||
1334 | } | ||
1335 | |||
1336 | /** | ||
1337 | * acpi_get_dma_attr - Check the supported DMA attr for the specified device. | ||
1338 | * @adev: The pointer to acpi device | ||
1339 | * | ||
1340 | * Return enum dev_dma_attr. | ||
1341 | */ | ||
1342 | enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev) | ||
1343 | { | ||
1344 | if (!acpi_dma_supported(adev)) | ||
1345 | return DEV_DMA_NOT_SUPPORTED; | ||
1346 | |||
1347 | if (adev->flags.coherent_dma) | ||
1348 | return DEV_DMA_COHERENT; | ||
1349 | else | ||
1350 | return DEV_DMA_NON_COHERENT; | ||
1351 | } | ||
1352 | |||
1311 | static void acpi_init_coherency(struct acpi_device *adev) | 1353 | static void acpi_init_coherency(struct acpi_device *adev) |
1312 | { | 1354 | { |
1313 | unsigned long long cca = 0; | 1355 | unsigned long long cca = 0; |
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 0d3a384b508a..daaf1c4e1e0f 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
@@ -233,6 +233,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = { | |||
233 | }, | 233 | }, |
234 | }, | 234 | }, |
235 | { | 235 | { |
236 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1272633 */ | ||
237 | .callback = video_detect_force_video, | ||
238 | .ident = "Dell XPS14 L421X", | ||
239 | .matches = { | ||
240 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
241 | DMI_MATCH(DMI_PRODUCT_NAME, "XPS L421X"), | ||
242 | }, | ||
243 | }, | ||
244 | { | ||
236 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1163574 */ | 245 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1163574 */ |
237 | .callback = video_detect_force_video, | 246 | .callback = video_detect_force_video, |
238 | .ident = "Dell XPS15 L521X", | 247 | .ident = "Dell XPS15 L521X", |
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 80e298870388..e03b1ad25a90 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
@@ -321,8 +321,7 @@ static int genpd_poweroff(struct generic_pm_domain *genpd, bool is_async) | |||
321 | if (stat > PM_QOS_FLAGS_NONE) | 321 | if (stat > PM_QOS_FLAGS_NONE) |
322 | return -EBUSY; | 322 | return -EBUSY; |
323 | 323 | ||
324 | if (pdd->dev->driver && (!pm_runtime_suspended(pdd->dev) | 324 | if (!pm_runtime_suspended(pdd->dev) || pdd->dev->power.irq_safe) |
325 | || pdd->dev->power.irq_safe)) | ||
326 | not_suspended++; | 325 | not_suspended++; |
327 | } | 326 | } |
328 | 327 | ||
@@ -1312,13 +1311,17 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd, | |||
1312 | int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, | 1311 | int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, |
1313 | struct generic_pm_domain *subdomain) | 1312 | struct generic_pm_domain *subdomain) |
1314 | { | 1313 | { |
1315 | struct gpd_link *link; | 1314 | struct gpd_link *link, *itr; |
1316 | int ret = 0; | 1315 | int ret = 0; |
1317 | 1316 | ||
1318 | if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain) | 1317 | if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain) |
1319 | || genpd == subdomain) | 1318 | || genpd == subdomain) |
1320 | return -EINVAL; | 1319 | return -EINVAL; |
1321 | 1320 | ||
1321 | link = kzalloc(sizeof(*link), GFP_KERNEL); | ||
1322 | if (!link) | ||
1323 | return -ENOMEM; | ||
1324 | |||
1322 | mutex_lock(&genpd->lock); | 1325 | mutex_lock(&genpd->lock); |
1323 | mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING); | 1326 | mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING); |
1324 | 1327 | ||
@@ -1328,18 +1331,13 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, | |||
1328 | goto out; | 1331 | goto out; |
1329 | } | 1332 | } |
1330 | 1333 | ||
1331 | list_for_each_entry(link, &genpd->master_links, master_node) { | 1334 | list_for_each_entry(itr, &genpd->master_links, master_node) { |
1332 | if (link->slave == subdomain && link->master == genpd) { | 1335 | if (itr->slave == subdomain && itr->master == genpd) { |
1333 | ret = -EINVAL; | 1336 | ret = -EINVAL; |
1334 | goto out; | 1337 | goto out; |
1335 | } | 1338 | } |
1336 | } | 1339 | } |
1337 | 1340 | ||
1338 | link = kzalloc(sizeof(*link), GFP_KERNEL); | ||
1339 | if (!link) { | ||
1340 | ret = -ENOMEM; | ||
1341 | goto out; | ||
1342 | } | ||
1343 | link->master = genpd; | 1341 | link->master = genpd; |
1344 | list_add_tail(&link->master_node, &genpd->master_links); | 1342 | list_add_tail(&link->master_node, &genpd->master_links); |
1345 | link->slave = subdomain; | 1343 | link->slave = subdomain; |
@@ -1350,7 +1348,8 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, | |||
1350 | out: | 1348 | out: |
1351 | mutex_unlock(&subdomain->lock); | 1349 | mutex_unlock(&subdomain->lock); |
1352 | mutex_unlock(&genpd->lock); | 1350 | mutex_unlock(&genpd->lock); |
1353 | 1351 | if (ret) | |
1352 | kfree(link); | ||
1354 | return ret; | 1353 | return ret; |
1355 | } | 1354 | } |
1356 | EXPORT_SYMBOL_GPL(pm_genpd_add_subdomain); | 1355 | EXPORT_SYMBOL_GPL(pm_genpd_add_subdomain); |
diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c index 270902007055..b8e76f75073b 100644 --- a/drivers/base/power/opp/core.c +++ b/drivers/base/power/opp/core.c | |||
@@ -11,6 +11,8 @@ | |||
11 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
15 | |||
14 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
15 | #include <linux/err.h> | 17 | #include <linux/err.h> |
16 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
@@ -27,7 +29,7 @@ | |||
27 | */ | 29 | */ |
28 | static LIST_HEAD(dev_opp_list); | 30 | static LIST_HEAD(dev_opp_list); |
29 | /* Lock to allow exclusive modification to the device and opp lists */ | 31 | /* Lock to allow exclusive modification to the device and opp lists */ |
30 | static DEFINE_MUTEX(dev_opp_list_lock); | 32 | DEFINE_MUTEX(dev_opp_list_lock); |
31 | 33 | ||
32 | #define opp_rcu_lockdep_assert() \ | 34 | #define opp_rcu_lockdep_assert() \ |
33 | do { \ | 35 | do { \ |
@@ -79,14 +81,18 @@ static struct device_opp *_managed_opp(const struct device_node *np) | |||
79 | * Return: pointer to 'struct device_opp' if found, otherwise -ENODEV or | 81 | * Return: pointer to 'struct device_opp' if found, otherwise -ENODEV or |
80 | * -EINVAL based on type of error. | 82 | * -EINVAL based on type of error. |
81 | * | 83 | * |
82 | * Locking: This function must be called under rcu_read_lock(). device_opp | 84 | * Locking: For readers, this function must be called under rcu_read_lock(). |
83 | * is a RCU protected pointer. This means that device_opp is valid as long | 85 | * device_opp is a RCU protected pointer, which means that device_opp is valid |
84 | * as we are under RCU lock. | 86 | * as long as we are under RCU lock. |
87 | * | ||
88 | * For Writers, this function must be called with dev_opp_list_lock held. | ||
85 | */ | 89 | */ |
86 | struct device_opp *_find_device_opp(struct device *dev) | 90 | struct device_opp *_find_device_opp(struct device *dev) |
87 | { | 91 | { |
88 | struct device_opp *dev_opp; | 92 | struct device_opp *dev_opp; |
89 | 93 | ||
94 | opp_rcu_lockdep_assert(); | ||
95 | |||
90 | if (IS_ERR_OR_NULL(dev)) { | 96 | if (IS_ERR_OR_NULL(dev)) { |
91 | pr_err("%s: Invalid parameters\n", __func__); | 97 | pr_err("%s: Invalid parameters\n", __func__); |
92 | return ERR_PTR(-EINVAL); | 98 | return ERR_PTR(-EINVAL); |
@@ -701,7 +707,7 @@ static int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, | |||
701 | } | 707 | } |
702 | 708 | ||
703 | /** | 709 | /** |
704 | * _opp_add_dynamic() - Allocate a dynamic OPP. | 710 | * _opp_add_v1() - Allocate a OPP based on v1 bindings. |
705 | * @dev: device for which we do this operation | 711 | * @dev: device for which we do this operation |
706 | * @freq: Frequency in Hz for this OPP | 712 | * @freq: Frequency in Hz for this OPP |
707 | * @u_volt: Voltage in uVolts for this OPP | 713 | * @u_volt: Voltage in uVolts for this OPP |
@@ -727,8 +733,8 @@ static int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, | |||
727 | * Duplicate OPPs (both freq and volt are same) and !opp->available | 733 | * Duplicate OPPs (both freq and volt are same) and !opp->available |
728 | * -ENOMEM Memory allocation failure | 734 | * -ENOMEM Memory allocation failure |
729 | */ | 735 | */ |
730 | static int _opp_add_dynamic(struct device *dev, unsigned long freq, | 736 | static int _opp_add_v1(struct device *dev, unsigned long freq, long u_volt, |
731 | long u_volt, bool dynamic) | 737 | bool dynamic) |
732 | { | 738 | { |
733 | struct device_opp *dev_opp; | 739 | struct device_opp *dev_opp; |
734 | struct dev_pm_opp *new_opp; | 740 | struct dev_pm_opp *new_opp; |
@@ -770,9 +776,10 @@ unlock: | |||
770 | } | 776 | } |
771 | 777 | ||
772 | /* TODO: Support multiple regulators */ | 778 | /* TODO: Support multiple regulators */ |
773 | static int opp_get_microvolt(struct dev_pm_opp *opp, struct device *dev) | 779 | static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev) |
774 | { | 780 | { |
775 | u32 microvolt[3] = {0}; | 781 | u32 microvolt[3] = {0}; |
782 | u32 val; | ||
776 | int count, ret; | 783 | int count, ret; |
777 | 784 | ||
778 | /* Missing property isn't a problem, but an invalid entry is */ | 785 | /* Missing property isn't a problem, but an invalid entry is */ |
@@ -805,6 +812,9 @@ static int opp_get_microvolt(struct dev_pm_opp *opp, struct device *dev) | |||
805 | opp->u_volt_min = microvolt[1]; | 812 | opp->u_volt_min = microvolt[1]; |
806 | opp->u_volt_max = microvolt[2]; | 813 | opp->u_volt_max = microvolt[2]; |
807 | 814 | ||
815 | if (!of_property_read_u32(opp->np, "opp-microamp", &val)) | ||
816 | opp->u_amp = val; | ||
817 | |||
808 | return 0; | 818 | return 0; |
809 | } | 819 | } |
810 | 820 | ||
@@ -869,13 +879,10 @@ static int _opp_add_static_v2(struct device *dev, struct device_node *np) | |||
869 | if (!of_property_read_u32(np, "clock-latency-ns", &val)) | 879 | if (!of_property_read_u32(np, "clock-latency-ns", &val)) |
870 | new_opp->clock_latency_ns = val; | 880 | new_opp->clock_latency_ns = val; |
871 | 881 | ||
872 | ret = opp_get_microvolt(new_opp, dev); | 882 | ret = opp_parse_supplies(new_opp, dev); |
873 | if (ret) | 883 | if (ret) |
874 | goto free_opp; | 884 | goto free_opp; |
875 | 885 | ||
876 | if (!of_property_read_u32(new_opp->np, "opp-microamp", &val)) | ||
877 | new_opp->u_amp = val; | ||
878 | |||
879 | ret = _opp_add(dev, new_opp, dev_opp); | 886 | ret = _opp_add(dev, new_opp, dev_opp); |
880 | if (ret) | 887 | if (ret) |
881 | goto free_opp; | 888 | goto free_opp; |
@@ -939,7 +946,7 @@ unlock: | |||
939 | */ | 946 | */ |
940 | int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt) | 947 | int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt) |
941 | { | 948 | { |
942 | return _opp_add_dynamic(dev, freq, u_volt, true); | 949 | return _opp_add_v1(dev, freq, u_volt, true); |
943 | } | 950 | } |
944 | EXPORT_SYMBOL_GPL(dev_pm_opp_add); | 951 | EXPORT_SYMBOL_GPL(dev_pm_opp_add); |
945 | 952 | ||
@@ -1172,13 +1179,17 @@ static int _of_add_opp_table_v2(struct device *dev, struct device_node *opp_np) | |||
1172 | struct device_opp *dev_opp; | 1179 | struct device_opp *dev_opp; |
1173 | int ret = 0, count = 0; | 1180 | int ret = 0, count = 0; |
1174 | 1181 | ||
1182 | mutex_lock(&dev_opp_list_lock); | ||
1183 | |||
1175 | dev_opp = _managed_opp(opp_np); | 1184 | dev_opp = _managed_opp(opp_np); |
1176 | if (dev_opp) { | 1185 | if (dev_opp) { |
1177 | /* OPPs are already managed */ | 1186 | /* OPPs are already managed */ |
1178 | if (!_add_list_dev(dev, dev_opp)) | 1187 | if (!_add_list_dev(dev, dev_opp)) |
1179 | ret = -ENOMEM; | 1188 | ret = -ENOMEM; |
1189 | mutex_unlock(&dev_opp_list_lock); | ||
1180 | return ret; | 1190 | return ret; |
1181 | } | 1191 | } |
1192 | mutex_unlock(&dev_opp_list_lock); | ||
1182 | 1193 | ||
1183 | /* We have opp-list node now, iterate over it and add OPPs */ | 1194 | /* We have opp-list node now, iterate over it and add OPPs */ |
1184 | for_each_available_child_of_node(opp_np, np) { | 1195 | for_each_available_child_of_node(opp_np, np) { |
@@ -1196,15 +1207,20 @@ static int _of_add_opp_table_v2(struct device *dev, struct device_node *opp_np) | |||
1196 | if (WARN_ON(!count)) | 1207 | if (WARN_ON(!count)) |
1197 | return -ENOENT; | 1208 | return -ENOENT; |
1198 | 1209 | ||
1210 | mutex_lock(&dev_opp_list_lock); | ||
1211 | |||
1199 | dev_opp = _find_device_opp(dev); | 1212 | dev_opp = _find_device_opp(dev); |
1200 | if (WARN_ON(IS_ERR(dev_opp))) { | 1213 | if (WARN_ON(IS_ERR(dev_opp))) { |
1201 | ret = PTR_ERR(dev_opp); | 1214 | ret = PTR_ERR(dev_opp); |
1215 | mutex_unlock(&dev_opp_list_lock); | ||
1202 | goto free_table; | 1216 | goto free_table; |
1203 | } | 1217 | } |
1204 | 1218 | ||
1205 | dev_opp->np = opp_np; | 1219 | dev_opp->np = opp_np; |
1206 | dev_opp->shared_opp = of_property_read_bool(opp_np, "opp-shared"); | 1220 | dev_opp->shared_opp = of_property_read_bool(opp_np, "opp-shared"); |
1207 | 1221 | ||
1222 | mutex_unlock(&dev_opp_list_lock); | ||
1223 | |||
1208 | return 0; | 1224 | return 0; |
1209 | 1225 | ||
1210 | free_table: | 1226 | free_table: |
@@ -1241,7 +1257,7 @@ static int _of_add_opp_table_v1(struct device *dev) | |||
1241 | unsigned long freq = be32_to_cpup(val++) * 1000; | 1257 | unsigned long freq = be32_to_cpup(val++) * 1000; |
1242 | unsigned long volt = be32_to_cpup(val++); | 1258 | unsigned long volt = be32_to_cpup(val++); |
1243 | 1259 | ||
1244 | if (_opp_add_dynamic(dev, freq, volt, false)) | 1260 | if (_opp_add_v1(dev, freq, volt, false)) |
1245 | dev_warn(dev, "%s: Failed to add OPP %ld\n", | 1261 | dev_warn(dev, "%s: Failed to add OPP %ld\n", |
1246 | __func__, freq); | 1262 | __func__, freq); |
1247 | nr -= 2; | 1263 | nr -= 2; |
diff --git a/drivers/base/power/opp/cpu.c b/drivers/base/power/opp/cpu.c index 7654c5606307..7b445e88a0d5 100644 --- a/drivers/base/power/opp/cpu.c +++ b/drivers/base/power/opp/cpu.c | |||
@@ -10,6 +10,9 @@ | |||
10 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
11 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
12 | */ | 12 | */ |
13 | |||
14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
15 | |||
13 | #include <linux/cpu.h> | 16 | #include <linux/cpu.h> |
14 | #include <linux/cpufreq.h> | 17 | #include <linux/cpufreq.h> |
15 | #include <linux/err.h> | 18 | #include <linux/err.h> |
@@ -124,12 +127,12 @@ int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, cpumask_var_t cpumask) | |||
124 | struct device *dev; | 127 | struct device *dev; |
125 | int cpu, ret = 0; | 128 | int cpu, ret = 0; |
126 | 129 | ||
127 | rcu_read_lock(); | 130 | mutex_lock(&dev_opp_list_lock); |
128 | 131 | ||
129 | dev_opp = _find_device_opp(cpu_dev); | 132 | dev_opp = _find_device_opp(cpu_dev); |
130 | if (IS_ERR(dev_opp)) { | 133 | if (IS_ERR(dev_opp)) { |
131 | ret = -EINVAL; | 134 | ret = -EINVAL; |
132 | goto out_rcu_read_unlock; | 135 | goto unlock; |
133 | } | 136 | } |
134 | 137 | ||
135 | for_each_cpu(cpu, cpumask) { | 138 | for_each_cpu(cpu, cpumask) { |
@@ -150,10 +153,10 @@ int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, cpumask_var_t cpumask) | |||
150 | continue; | 153 | continue; |
151 | } | 154 | } |
152 | } | 155 | } |
153 | out_rcu_read_unlock: | 156 | unlock: |
154 | rcu_read_unlock(); | 157 | mutex_unlock(&dev_opp_list_lock); |
155 | 158 | ||
156 | return 0; | 159 | return ret; |
157 | } | 160 | } |
158 | EXPORT_SYMBOL_GPL(dev_pm_opp_set_sharing_cpus); | 161 | EXPORT_SYMBOL_GPL(dev_pm_opp_set_sharing_cpus); |
159 | 162 | ||
diff --git a/drivers/base/power/opp/opp.h b/drivers/base/power/opp/opp.h index dcb38f78dae4..7366b2aa8997 100644 --- a/drivers/base/power/opp/opp.h +++ b/drivers/base/power/opp/opp.h | |||
@@ -21,6 +21,9 @@ | |||
21 | #include <linux/rculist.h> | 21 | #include <linux/rculist.h> |
22 | #include <linux/rcupdate.h> | 22 | #include <linux/rcupdate.h> |
23 | 23 | ||
24 | /* Lock to allow exclusive modification to the device and opp lists */ | ||
25 | extern struct mutex dev_opp_list_lock; | ||
26 | |||
24 | /* | 27 | /* |
25 | * Internal data structure organization with the OPP layer library is as | 28 | * Internal data structure organization with the OPP layer library is as |
26 | * follows: | 29 | * follows: |
diff --git a/drivers/base/property.c b/drivers/base/property.c index de40623bbd8a..1325ff225cc4 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c | |||
@@ -598,18 +598,34 @@ unsigned int device_get_child_node_count(struct device *dev) | |||
598 | } | 598 | } |
599 | EXPORT_SYMBOL_GPL(device_get_child_node_count); | 599 | EXPORT_SYMBOL_GPL(device_get_child_node_count); |
600 | 600 | ||
601 | bool device_dma_is_coherent(struct device *dev) | 601 | bool device_dma_supported(struct device *dev) |
602 | { | 602 | { |
603 | bool coherent = false; | 603 | /* For DT, this is always supported. |
604 | 604 | * For ACPI, this depends on CCA, which | |
605 | * is determined by the acpi_dma_supported(). | ||
606 | */ | ||
605 | if (IS_ENABLED(CONFIG_OF) && dev->of_node) | 607 | if (IS_ENABLED(CONFIG_OF) && dev->of_node) |
606 | coherent = of_dma_is_coherent(dev->of_node); | 608 | return true; |
607 | else | 609 | |
608 | acpi_check_dma(ACPI_COMPANION(dev), &coherent); | 610 | return acpi_dma_supported(ACPI_COMPANION(dev)); |
611 | } | ||
612 | EXPORT_SYMBOL_GPL(device_dma_supported); | ||
609 | 613 | ||
610 | return coherent; | 614 | enum dev_dma_attr device_get_dma_attr(struct device *dev) |
615 | { | ||
616 | enum dev_dma_attr attr = DEV_DMA_NOT_SUPPORTED; | ||
617 | |||
618 | if (IS_ENABLED(CONFIG_OF) && dev->of_node) { | ||
619 | if (of_dma_is_coherent(dev->of_node)) | ||
620 | attr = DEV_DMA_COHERENT; | ||
621 | else | ||
622 | attr = DEV_DMA_NON_COHERENT; | ||
623 | } else | ||
624 | attr = acpi_get_dma_attr(ACPI_COMPANION(dev)); | ||
625 | |||
626 | return attr; | ||
611 | } | 627 | } |
612 | EXPORT_SYMBOL_GPL(device_dma_is_coherent); | 628 | EXPORT_SYMBOL_GPL(device_get_dma_attr); |
613 | 629 | ||
614 | /** | 630 | /** |
615 | * device_get_phy_mode - Get phy mode for given device | 631 | * device_get_phy_mode - Get phy mode for given device |
diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index f1e42f8ce0fc..c5d256caa664 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c | |||
@@ -149,6 +149,19 @@ bL_cpufreq_set_rate(u32 cpu, u32 old_cluster, u32 new_cluster, u32 rate) | |||
149 | __func__, cpu, old_cluster, new_cluster, new_rate); | 149 | __func__, cpu, old_cluster, new_cluster, new_rate); |
150 | 150 | ||
151 | ret = clk_set_rate(clk[new_cluster], new_rate * 1000); | 151 | ret = clk_set_rate(clk[new_cluster], new_rate * 1000); |
152 | if (!ret) { | ||
153 | /* | ||
154 | * FIXME: clk_set_rate hasn't returned an error here however it | ||
155 | * may be that clk_change_rate failed due to hardware or | ||
156 | * firmware issues and wasn't able to report that due to the | ||
157 | * current design of the clk core layer. To work around this | ||
158 | * problem we will read back the clock rate and check it is | ||
159 | * correct. This needs to be removed once clk core is fixed. | ||
160 | */ | ||
161 | if (clk_get_rate(clk[new_cluster]) != new_rate * 1000) | ||
162 | ret = -EIO; | ||
163 | } | ||
164 | |||
152 | if (WARN_ON(ret)) { | 165 | if (WARN_ON(ret)) { |
153 | pr_err("clk_set_rate failed: %d, new cluster: %d\n", ret, | 166 | pr_err("clk_set_rate failed: %d, new cluster: %d\n", ret, |
154 | new_cluster); | 167 | new_cluster); |
@@ -189,15 +202,6 @@ bL_cpufreq_set_rate(u32 cpu, u32 old_cluster, u32 new_cluster, u32 rate) | |||
189 | mutex_unlock(&cluster_lock[old_cluster]); | 202 | mutex_unlock(&cluster_lock[old_cluster]); |
190 | } | 203 | } |
191 | 204 | ||
192 | /* | ||
193 | * FIXME: clk_set_rate has to handle the case where clk_change_rate | ||
194 | * can fail due to hardware or firmware issues. Until the clk core | ||
195 | * layer is fixed, we can check here. In most of the cases we will | ||
196 | * be reading only the cached value anyway. This needs to be removed | ||
197 | * once clk core is fixed. | ||
198 | */ | ||
199 | if (bL_cpufreq_get_rate(cpu) != new_rate) | ||
200 | return -EIO; | ||
201 | return 0; | 205 | return 0; |
202 | } | 206 | } |
203 | 207 | ||
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index 93c219fab850..e8cb334094b0 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c | |||
@@ -166,8 +166,7 @@ static int __init cppc_cpufreq_init(void) | |||
166 | 166 | ||
167 | out: | 167 | out: |
168 | for_each_possible_cpu(i) | 168 | for_each_possible_cpu(i) |
169 | if (all_cpu_data[i]) | 169 | kfree(all_cpu_data[i]); |
170 | kfree(all_cpu_data[i]); | ||
171 | 170 | ||
172 | kfree(all_cpu_data); | 171 | kfree(all_cpu_data); |
173 | return -ENODEV; | 172 | return -ENODEV; |
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index 11258c4c1b17..b260576ddb12 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c | |||
@@ -171,10 +171,6 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, | |||
171 | { | 171 | { |
172 | int i; | 172 | int i; |
173 | 173 | ||
174 | mutex_lock(&cpufreq_governor_lock); | ||
175 | if (!policy->governor_enabled) | ||
176 | goto out_unlock; | ||
177 | |||
178 | if (!all_cpus) { | 174 | if (!all_cpus) { |
179 | /* | 175 | /* |
180 | * Use raw_smp_processor_id() to avoid preemptible warnings. | 176 | * Use raw_smp_processor_id() to avoid preemptible warnings. |
@@ -188,9 +184,6 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, | |||
188 | for_each_cpu(i, policy->cpus) | 184 | for_each_cpu(i, policy->cpus) |
189 | __gov_queue_work(i, dbs_data, delay); | 185 | __gov_queue_work(i, dbs_data, delay); |
190 | } | 186 | } |
191 | |||
192 | out_unlock: | ||
193 | mutex_unlock(&cpufreq_governor_lock); | ||
194 | } | 187 | } |
195 | EXPORT_SYMBOL_GPL(gov_queue_work); | 188 | EXPORT_SYMBOL_GPL(gov_queue_work); |
196 | 189 | ||
@@ -229,13 +222,24 @@ static void dbs_timer(struct work_struct *work) | |||
229 | struct cpu_dbs_info *cdbs = container_of(work, struct cpu_dbs_info, | 222 | struct cpu_dbs_info *cdbs = container_of(work, struct cpu_dbs_info, |
230 | dwork.work); | 223 | dwork.work); |
231 | struct cpu_common_dbs_info *shared = cdbs->shared; | 224 | struct cpu_common_dbs_info *shared = cdbs->shared; |
232 | struct cpufreq_policy *policy = shared->policy; | 225 | struct cpufreq_policy *policy; |
233 | struct dbs_data *dbs_data = policy->governor_data; | 226 | struct dbs_data *dbs_data; |
234 | unsigned int sampling_rate, delay; | 227 | unsigned int sampling_rate, delay; |
235 | bool modify_all = true; | 228 | bool modify_all = true; |
236 | 229 | ||
237 | mutex_lock(&shared->timer_mutex); | 230 | mutex_lock(&shared->timer_mutex); |
238 | 231 | ||
232 | policy = shared->policy; | ||
233 | |||
234 | /* | ||
235 | * Governor might already be disabled and there is no point continuing | ||
236 | * with the work-handler. | ||
237 | */ | ||
238 | if (!policy) | ||
239 | goto unlock; | ||
240 | |||
241 | dbs_data = policy->governor_data; | ||
242 | |||
239 | if (dbs_data->cdata->governor == GOV_CONSERVATIVE) { | 243 | if (dbs_data->cdata->governor == GOV_CONSERVATIVE) { |
240 | struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; | 244 | struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; |
241 | 245 | ||
@@ -252,6 +256,7 @@ static void dbs_timer(struct work_struct *work) | |||
252 | delay = dbs_data->cdata->gov_dbs_timer(cdbs, dbs_data, modify_all); | 256 | delay = dbs_data->cdata->gov_dbs_timer(cdbs, dbs_data, modify_all); |
253 | gov_queue_work(dbs_data, policy, delay, modify_all); | 257 | gov_queue_work(dbs_data, policy, delay, modify_all); |
254 | 258 | ||
259 | unlock: | ||
255 | mutex_unlock(&shared->timer_mutex); | 260 | mutex_unlock(&shared->timer_mutex); |
256 | } | 261 | } |
257 | 262 | ||
@@ -478,9 +483,17 @@ static int cpufreq_governor_stop(struct cpufreq_policy *policy, | |||
478 | if (!shared || !shared->policy) | 483 | if (!shared || !shared->policy) |
479 | return -EBUSY; | 484 | return -EBUSY; |
480 | 485 | ||
486 | /* | ||
487 | * Work-handler must see this updated, as it should not proceed any | ||
488 | * further after governor is disabled. And so timer_mutex is taken while | ||
489 | * updating this value. | ||
490 | */ | ||
491 | mutex_lock(&shared->timer_mutex); | ||
492 | shared->policy = NULL; | ||
493 | mutex_unlock(&shared->timer_mutex); | ||
494 | |||
481 | gov_cancel_work(dbs_data, policy); | 495 | gov_cancel_work(dbs_data, policy); |
482 | 496 | ||
483 | shared->policy = NULL; | ||
484 | mutex_destroy(&shared->timer_mutex); | 497 | mutex_destroy(&shared->timer_mutex); |
485 | return 0; | 498 | return 0; |
486 | } | 499 | } |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 93a3c635ea27..2e31d097def6 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -684,8 +684,6 @@ static void __init intel_pstate_sysfs_expose_params(void) | |||
684 | 684 | ||
685 | static void intel_pstate_hwp_enable(struct cpudata *cpudata) | 685 | static void intel_pstate_hwp_enable(struct cpudata *cpudata) |
686 | { | 686 | { |
687 | pr_info("intel_pstate: HWP enabled\n"); | ||
688 | |||
689 | wrmsrl_on_cpu(cpudata->cpu, MSR_PM_ENABLE, 0x1); | 687 | wrmsrl_on_cpu(cpudata->cpu, MSR_PM_ENABLE, 0x1); |
690 | } | 688 | } |
691 | 689 | ||
@@ -1557,8 +1555,10 @@ static int __init intel_pstate_init(void) | |||
1557 | if (!all_cpu_data) | 1555 | if (!all_cpu_data) |
1558 | return -ENOMEM; | 1556 | return -ENOMEM; |
1559 | 1557 | ||
1560 | if (static_cpu_has_safe(X86_FEATURE_HWP) && !no_hwp) | 1558 | if (static_cpu_has_safe(X86_FEATURE_HWP) && !no_hwp) { |
1559 | pr_info("intel_pstate: HWP enabled\n"); | ||
1561 | hwp_active++; | 1560 | hwp_active++; |
1561 | } | ||
1562 | 1562 | ||
1563 | if (!hwp_active && hwp_only) | 1563 | if (!hwp_active && hwp_only) |
1564 | goto out; | 1564 | goto out; |
@@ -1593,8 +1593,10 @@ static int __init intel_pstate_setup(char *str) | |||
1593 | 1593 | ||
1594 | if (!strcmp(str, "disable")) | 1594 | if (!strcmp(str, "disable")) |
1595 | no_load = 1; | 1595 | no_load = 1; |
1596 | if (!strcmp(str, "no_hwp")) | 1596 | if (!strcmp(str, "no_hwp")) { |
1597 | pr_info("intel_pstate: HWP disabled\n"); | ||
1597 | no_hwp = 1; | 1598 | no_hwp = 1; |
1599 | } | ||
1598 | if (!strcmp(str, "force")) | 1600 | if (!strcmp(str, "force")) |
1599 | force_load = 1; | 1601 | force_load = 1; |
1600 | if (!strcmp(str, "hwp_only")) | 1602 | if (!strcmp(str, "hwp_only")) |
diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c index 9e231f52150c..051a8a8224cd 100644 --- a/drivers/cpufreq/s5pv210-cpufreq.c +++ b/drivers/cpufreq/s5pv210-cpufreq.c | |||
@@ -212,11 +212,11 @@ static void s5pv210_set_refresh(enum s5pv210_dmc_port ch, unsigned long freq) | |||
212 | /* Find current DRAM frequency */ | 212 | /* Find current DRAM frequency */ |
213 | tmp = s5pv210_dram_conf[ch].freq; | 213 | tmp = s5pv210_dram_conf[ch].freq; |
214 | 214 | ||
215 | do_div(tmp, freq); | 215 | tmp /= freq; |
216 | 216 | ||
217 | tmp1 = s5pv210_dram_conf[ch].refresh; | 217 | tmp1 = s5pv210_dram_conf[ch].refresh; |
218 | 218 | ||
219 | do_div(tmp1, tmp); | 219 | tmp1 /= tmp; |
220 | 220 | ||
221 | __raw_writel(tmp1, reg); | 221 | __raw_writel(tmp1, reg); |
222 | } | 222 | } |
diff --git a/drivers/crypto/ccp/ccp-platform.c b/drivers/crypto/ccp/ccp-platform.c index 8b923b7e9389..01b50cb4c982 100644 --- a/drivers/crypto/ccp/ccp-platform.c +++ b/drivers/crypto/ccp/ccp-platform.c | |||
@@ -94,6 +94,7 @@ static int ccp_platform_probe(struct platform_device *pdev) | |||
94 | struct ccp_device *ccp; | 94 | struct ccp_device *ccp; |
95 | struct ccp_platform *ccp_platform; | 95 | struct ccp_platform *ccp_platform; |
96 | struct device *dev = &pdev->dev; | 96 | struct device *dev = &pdev->dev; |
97 | enum dev_dma_attr attr; | ||
97 | struct resource *ior; | 98 | struct resource *ior; |
98 | int ret; | 99 | int ret; |
99 | 100 | ||
@@ -118,18 +119,24 @@ static int ccp_platform_probe(struct platform_device *pdev) | |||
118 | } | 119 | } |
119 | ccp->io_regs = ccp->io_map; | 120 | ccp->io_regs = ccp->io_map; |
120 | 121 | ||
121 | ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48)); | 122 | attr = device_get_dma_attr(dev); |
122 | if (ret) { | 123 | if (attr == DEV_DMA_NOT_SUPPORTED) { |
123 | dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n", ret); | 124 | dev_err(dev, "DMA is not supported"); |
124 | goto e_err; | 125 | goto e_err; |
125 | } | 126 | } |
126 | 127 | ||
127 | ccp_platform->coherent = device_dma_is_coherent(ccp->dev); | 128 | ccp_platform->coherent = (attr == DEV_DMA_COHERENT); |
128 | if (ccp_platform->coherent) | 129 | if (ccp_platform->coherent) |
129 | ccp->axcache = CACHE_WB_NO_ALLOC; | 130 | ccp->axcache = CACHE_WB_NO_ALLOC; |
130 | else | 131 | else |
131 | ccp->axcache = CACHE_NONE; | 132 | ccp->axcache = CACHE_NONE; |
132 | 133 | ||
134 | ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48)); | ||
135 | if (ret) { | ||
136 | dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n", ret); | ||
137 | goto e_err; | ||
138 | } | ||
139 | |||
133 | dev_set_drvdata(dev, ccp); | 140 | dev_set_drvdata(dev, ccp); |
134 | 141 | ||
135 | ret = ccp_init(ccp); | 142 | ret = ccp_init(ccp); |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c index 7dd893331785..618d952c2984 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c | |||
@@ -342,6 +342,7 @@ static int xgbe_probe(struct platform_device *pdev) | |||
342 | struct resource *res; | 342 | struct resource *res; |
343 | const char *phy_mode; | 343 | const char *phy_mode; |
344 | unsigned int i, phy_memnum, phy_irqnum; | 344 | unsigned int i, phy_memnum, phy_irqnum; |
345 | enum dev_dma_attr attr; | ||
345 | int ret; | 346 | int ret; |
346 | 347 | ||
347 | DBGPR("--> xgbe_probe\n"); | 348 | DBGPR("--> xgbe_probe\n"); |
@@ -609,7 +610,12 @@ static int xgbe_probe(struct platform_device *pdev) | |||
609 | goto err_io; | 610 | goto err_io; |
610 | 611 | ||
611 | /* Set the DMA coherency values */ | 612 | /* Set the DMA coherency values */ |
612 | pdata->coherent = device_dma_is_coherent(pdata->dev); | 613 | attr = device_get_dma_attr(dev); |
614 | if (attr == DEV_DMA_NOT_SUPPORTED) { | ||
615 | dev_err(dev, "DMA is not supported"); | ||
616 | goto err_io; | ||
617 | } | ||
618 | pdata->coherent = (attr == DEV_DMA_COHERENT); | ||
613 | if (pdata->coherent) { | 619 | if (pdata->coherent) { |
614 | pdata->axdomain = XGBE_DMA_OS_AXDOMAIN; | 620 | pdata->axdomain = XGBE_DMA_OS_AXDOMAIN; |
615 | pdata->arcache = XGBE_DMA_OS_ARCACHE; | 621 | pdata->arcache = XGBE_DMA_OS_ARCACHE; |
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c index ff27177f49ed..b1449f71601c 100644 --- a/drivers/of/of_pci.c +++ b/drivers/of/of_pci.c | |||
@@ -143,26 +143,6 @@ void of_pci_check_probe_only(void) | |||
143 | } | 143 | } |
144 | EXPORT_SYMBOL_GPL(of_pci_check_probe_only); | 144 | EXPORT_SYMBOL_GPL(of_pci_check_probe_only); |
145 | 145 | ||
146 | /** | ||
147 | * of_pci_dma_configure - Setup DMA configuration | ||
148 | * @dev: ptr to pci_dev struct of the PCI device | ||
149 | * | ||
150 | * Function to update PCI devices's DMA configuration using the same | ||
151 | * info from the OF node of host bridge's parent (if any). | ||
152 | */ | ||
153 | void of_pci_dma_configure(struct pci_dev *pci_dev) | ||
154 | { | ||
155 | struct device *dev = &pci_dev->dev; | ||
156 | struct device *bridge = pci_get_host_bridge_device(pci_dev); | ||
157 | |||
158 | if (!bridge->parent) | ||
159 | return; | ||
160 | |||
161 | of_dma_configure(dev, bridge->parent->of_node); | ||
162 | pci_put_host_bridge_device(bridge); | ||
163 | } | ||
164 | EXPORT_SYMBOL_GPL(of_pci_dma_configure); | ||
165 | |||
166 | #if defined(CONFIG_OF_ADDRESS) | 146 | #if defined(CONFIG_OF_ADDRESS) |
167 | /** | 147 | /** |
168 | * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT | 148 | * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index f53b8e85f137..e735c728e3b3 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/delay.h> | 6 | #include <linux/delay.h> |
7 | #include <linux/init.h> | 7 | #include <linux/init.h> |
8 | #include <linux/pci.h> | 8 | #include <linux/pci.h> |
9 | #include <linux/of_device.h> | ||
9 | #include <linux/of_pci.h> | 10 | #include <linux/of_pci.h> |
10 | #include <linux/pci_hotplug.h> | 11 | #include <linux/pci_hotplug.h> |
11 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
@@ -13,6 +14,7 @@ | |||
13 | #include <linux/cpumask.h> | 14 | #include <linux/cpumask.h> |
14 | #include <linux/pci-aspm.h> | 15 | #include <linux/pci-aspm.h> |
15 | #include <linux/aer.h> | 16 | #include <linux/aer.h> |
17 | #include <linux/acpi.h> | ||
16 | #include <asm-generic/pci-bridge.h> | 18 | #include <asm-generic/pci-bridge.h> |
17 | #include "pci.h" | 19 | #include "pci.h" |
18 | 20 | ||
@@ -1672,6 +1674,34 @@ static void pci_set_msi_domain(struct pci_dev *dev) | |||
1672 | dev_set_msi_domain(&dev->dev, d); | 1674 | dev_set_msi_domain(&dev->dev, d); |
1673 | } | 1675 | } |
1674 | 1676 | ||
1677 | /** | ||
1678 | * pci_dma_configure - Setup DMA configuration | ||
1679 | * @dev: ptr to pci_dev struct of the PCI device | ||
1680 | * | ||
1681 | * Function to update PCI devices's DMA configuration using the same | ||
1682 | * info from the OF node or ACPI node of host bridge's parent (if any). | ||
1683 | */ | ||
1684 | static void pci_dma_configure(struct pci_dev *dev) | ||
1685 | { | ||
1686 | struct device *bridge = pci_get_host_bridge_device(dev); | ||
1687 | |||
1688 | if (IS_ENABLED(CONFIG_OF) && dev->dev.of_node) { | ||
1689 | if (bridge->parent) | ||
1690 | of_dma_configure(&dev->dev, bridge->parent->of_node); | ||
1691 | } else if (has_acpi_companion(bridge)) { | ||
1692 | struct acpi_device *adev = to_acpi_device_node(bridge->fwnode); | ||
1693 | enum dev_dma_attr attr = acpi_get_dma_attr(adev); | ||
1694 | |||
1695 | if (attr == DEV_DMA_NOT_SUPPORTED) | ||
1696 | dev_warn(&dev->dev, "DMA not supported.\n"); | ||
1697 | else | ||
1698 | arch_setup_dma_ops(&dev->dev, 0, 0, NULL, | ||
1699 | attr == DEV_DMA_COHERENT); | ||
1700 | } | ||
1701 | |||
1702 | pci_put_host_bridge_device(bridge); | ||
1703 | } | ||
1704 | |||
1675 | void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) | 1705 | void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) |
1676 | { | 1706 | { |
1677 | int ret; | 1707 | int ret; |
@@ -1685,7 +1715,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) | |||
1685 | dev->dev.dma_mask = &dev->dma_mask; | 1715 | dev->dev.dma_mask = &dev->dma_mask; |
1686 | dev->dev.dma_parms = &dev->dma_parms; | 1716 | dev->dev.dma_parms = &dev->dma_parms; |
1687 | dev->dev.coherent_dma_mask = 0xffffffffull; | 1717 | dev->dev.coherent_dma_mask = 0xffffffffull; |
1688 | of_pci_dma_configure(dev); | 1718 | pci_dma_configure(dev); |
1689 | 1719 | ||
1690 | pci_set_dma_max_seg_size(dev, 65536); | 1720 | pci_set_dma_max_seg_size(dev, 65536); |
1691 | pci_set_dma_seg_boundary(dev, 0xffffffff); | 1721 | pci_set_dma_seg_boundary(dev, 0xffffffff); |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index d11eff8a4efe..ad0a5ff3d4cd 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -390,39 +390,6 @@ struct acpi_data_node { | |||
390 | struct completion kobj_done; | 390 | struct completion kobj_done; |
391 | }; | 391 | }; |
392 | 392 | ||
393 | static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent) | ||
394 | { | ||
395 | bool ret = false; | ||
396 | |||
397 | if (!adev) | ||
398 | return ret; | ||
399 | |||
400 | /** | ||
401 | * Currently, we only support _CCA=1 (i.e. coherent_dma=1) | ||
402 | * This should be equivalent to specifyig dma-coherent for | ||
403 | * a device in OF. | ||
404 | * | ||
405 | * For the case when _CCA=0 (i.e. coherent_dma=0 && cca_seen=1), | ||
406 | * There are two cases: | ||
407 | * case 1. Do not support and disable DMA. | ||
408 | * case 2. Support but rely on arch-specific cache maintenance for | ||
409 | * non-coherence DMA operations. | ||
410 | * Currently, we implement case 1 above. | ||
411 | * | ||
412 | * For the case when _CCA is missing (i.e. cca_seen=0) and | ||
413 | * platform specifies ACPI_CCA_REQUIRED, we do not support DMA, | ||
414 | * and fallback to arch-specific default handling. | ||
415 | * | ||
416 | * See acpi_init_coherency() for more info. | ||
417 | */ | ||
418 | if (adev->flags.coherent_dma) { | ||
419 | ret = true; | ||
420 | if (coherent) | ||
421 | *coherent = adev->flags.coherent_dma; | ||
422 | } | ||
423 | return ret; | ||
424 | } | ||
425 | |||
426 | static inline bool is_acpi_node(struct fwnode_handle *fwnode) | 393 | static inline bool is_acpi_node(struct fwnode_handle *fwnode) |
427 | { | 394 | { |
428 | return fwnode && (fwnode->type == FWNODE_ACPI | 395 | return fwnode && (fwnode->type == FWNODE_ACPI |
@@ -595,6 +562,9 @@ struct acpi_pci_root { | |||
595 | 562 | ||
596 | /* helper */ | 563 | /* helper */ |
597 | 564 | ||
565 | bool acpi_dma_supported(struct acpi_device *adev); | ||
566 | enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev); | ||
567 | |||
598 | struct acpi_device *acpi_find_child_device(struct acpi_device *parent, | 568 | struct acpi_device *acpi_find_child_device(struct acpi_device *parent, |
599 | u64 address, bool check_children); | 569 | u64 address, bool check_children); |
600 | int acpi_is_root_bridge(acpi_handle); | 570 | int acpi_is_root_bridge(acpi_handle); |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index ebfac2fe0c81..054833939995 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -601,11 +601,16 @@ static inline int acpi_device_modalias(struct device *dev, | |||
601 | return -ENODEV; | 601 | return -ENODEV; |
602 | } | 602 | } |
603 | 603 | ||
604 | static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent) | 604 | static inline bool acpi_dma_supported(struct acpi_device *adev) |
605 | { | 605 | { |
606 | return false; | 606 | return false; |
607 | } | 607 | } |
608 | 608 | ||
609 | static inline enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev) | ||
610 | { | ||
611 | return DEV_DMA_NOT_SUPPORTED; | ||
612 | } | ||
613 | |||
609 | #define ACPI_PTR(_ptr) (NULL) | 614 | #define ACPI_PTR(_ptr) (NULL) |
610 | 615 | ||
611 | #endif /* !CONFIG_ACPI */ | 616 | #endif /* !CONFIG_ACPI */ |
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h index 38c0533a3359..2c51ee78b1c0 100644 --- a/include/linux/of_pci.h +++ b/include/linux/of_pci.h | |||
@@ -16,7 +16,6 @@ int of_pci_get_devfn(struct device_node *np); | |||
16 | int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin); | 16 | int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin); |
17 | int of_pci_parse_bus_range(struct device_node *node, struct resource *res); | 17 | int of_pci_parse_bus_range(struct device_node *node, struct resource *res); |
18 | int of_get_pci_domain_nr(struct device_node *node); | 18 | int of_get_pci_domain_nr(struct device_node *node); |
19 | void of_pci_dma_configure(struct pci_dev *pci_dev); | ||
20 | void of_pci_check_probe_only(void); | 19 | void of_pci_check_probe_only(void); |
21 | #else | 20 | #else |
22 | static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq) | 21 | static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq) |
@@ -53,8 +52,6 @@ of_get_pci_domain_nr(struct device_node *node) | |||
53 | return -1; | 52 | return -1; |
54 | } | 53 | } |
55 | 54 | ||
56 | static inline void of_pci_dma_configure(struct pci_dev *pci_dev) { } | ||
57 | |||
58 | static inline void of_pci_check_probe_only(void) { } | 55 | static inline void of_pci_check_probe_only(void) { } |
59 | #endif | 56 | #endif |
60 | 57 | ||
diff --git a/include/linux/property.h b/include/linux/property.h index 463de52fe891..0a3705a7c9f2 100644 --- a/include/linux/property.h +++ b/include/linux/property.h | |||
@@ -27,6 +27,12 @@ enum dev_prop_type { | |||
27 | DEV_PROP_MAX, | 27 | DEV_PROP_MAX, |
28 | }; | 28 | }; |
29 | 29 | ||
30 | enum dev_dma_attr { | ||
31 | DEV_DMA_NOT_SUPPORTED, | ||
32 | DEV_DMA_NON_COHERENT, | ||
33 | DEV_DMA_COHERENT, | ||
34 | }; | ||
35 | |||
30 | bool device_property_present(struct device *dev, const char *propname); | 36 | bool device_property_present(struct device *dev, const char *propname); |
31 | int device_property_read_u8_array(struct device *dev, const char *propname, | 37 | int device_property_read_u8_array(struct device *dev, const char *propname, |
32 | u8 *val, size_t nval); | 38 | u8 *val, size_t nval); |
@@ -168,7 +174,9 @@ struct property_set { | |||
168 | 174 | ||
169 | void device_add_property_set(struct device *dev, struct property_set *pset); | 175 | void device_add_property_set(struct device *dev, struct property_set *pset); |
170 | 176 | ||
171 | bool device_dma_is_coherent(struct device *dev); | 177 | bool device_dma_supported(struct device *dev); |
178 | |||
179 | enum dev_dma_attr device_get_dma_attr(struct device *dev); | ||
172 | 180 | ||
173 | int device_get_phy_mode(struct device *dev); | 181 | int device_get_phy_mode(struct device *dev); |
174 | 182 | ||
diff --git a/tools/power/cpupower/debug/i386/dump_psb.c b/tools/power/cpupower/debug/i386/dump_psb.c index 8d6a47514253..2c768cf70128 100644 --- a/tools/power/cpupower/debug/i386/dump_psb.c +++ b/tools/power/cpupower/debug/i386/dump_psb.c | |||
@@ -134,7 +134,7 @@ next_one: | |||
134 | } | 134 | } |
135 | 135 | ||
136 | static struct option info_opts[] = { | 136 | static struct option info_opts[] = { |
137 | {.name = "numpst", .has_arg=no_argument, .flag=NULL, .val='n'}, | 137 | {"numpst", no_argument, NULL, 'n'}, |
138 | }; | 138 | }; |
139 | 139 | ||
140 | void print_help(void) | 140 | void print_help(void) |
diff --git a/tools/power/cpupower/man/cpupower-idle-set.1 b/tools/power/cpupower/man/cpupower-idle-set.1 index 3e6799d7a79f..580c4e3ea92a 100644 --- a/tools/power/cpupower/man/cpupower-idle-set.1 +++ b/tools/power/cpupower/man/cpupower-idle-set.1 | |||
@@ -20,7 +20,9 @@ Disable a specific processor sleep state. | |||
20 | Enable a specific processor sleep state. | 20 | Enable a specific processor sleep state. |
21 | .TP | 21 | .TP |
22 | \fB\-D\fR \fB\-\-disable-by-latency\fR <LATENCY> | 22 | \fB\-D\fR \fB\-\-disable-by-latency\fR <LATENCY> |
23 | Disable all idle states with a equal or higher latency than <LATENCY> | 23 | Disable all idle states with a equal or higher latency than <LATENCY>. |
24 | |||
25 | Enable all idle states with a latency lower than <LATENCY>. | ||
24 | .TP | 26 | .TP |
25 | \fB\-E\fR \fB\-\-enable-all\fR | 27 | \fB\-E\fR \fB\-\-enable-all\fR |
26 | Enable all idle states if not enabled already. | 28 | Enable all idle states if not enabled already. |
diff --git a/tools/power/cpupower/utils/cpufreq-info.c b/tools/power/cpupower/utils/cpufreq-info.c index b4b90a97662c..0e6764330241 100644 --- a/tools/power/cpupower/utils/cpufreq-info.c +++ b/tools/power/cpupower/utils/cpufreq-info.c | |||
@@ -536,21 +536,21 @@ static int get_latency(unsigned int cpu, unsigned int human) | |||
536 | } | 536 | } |
537 | 537 | ||
538 | static struct option info_opts[] = { | 538 | static struct option info_opts[] = { |
539 | { .name = "debug", .has_arg = no_argument, .flag = NULL, .val = 'e'}, | 539 | {"debug", no_argument, NULL, 'e'}, |
540 | { .name = "boost", .has_arg = no_argument, .flag = NULL, .val = 'b'}, | 540 | {"boost", no_argument, NULL, 'b'}, |
541 | { .name = "freq", .has_arg = no_argument, .flag = NULL, .val = 'f'}, | 541 | {"freq", no_argument, NULL, 'f'}, |
542 | { .name = "hwfreq", .has_arg = no_argument, .flag = NULL, .val = 'w'}, | 542 | {"hwfreq", no_argument, NULL, 'w'}, |
543 | { .name = "hwlimits", .has_arg = no_argument, .flag = NULL, .val = 'l'}, | 543 | {"hwlimits", no_argument, NULL, 'l'}, |
544 | { .name = "driver", .has_arg = no_argument, .flag = NULL, .val = 'd'}, | 544 | {"driver", no_argument, NULL, 'd'}, |
545 | { .name = "policy", .has_arg = no_argument, .flag = NULL, .val = 'p'}, | 545 | {"policy", no_argument, NULL, 'p'}, |
546 | { .name = "governors", .has_arg = no_argument, .flag = NULL, .val = 'g'}, | 546 | {"governors", no_argument, NULL, 'g'}, |
547 | { .name = "related-cpus", .has_arg = no_argument, .flag = NULL, .val = 'r'}, | 547 | {"related-cpus", no_argument, NULL, 'r'}, |
548 | { .name = "affected-cpus",.has_arg = no_argument, .flag = NULL, .val = 'a'}, | 548 | {"affected-cpus", no_argument, NULL, 'a'}, |
549 | { .name = "stats", .has_arg = no_argument, .flag = NULL, .val = 's'}, | 549 | {"stats", no_argument, NULL, 's'}, |
550 | { .name = "latency", .has_arg = no_argument, .flag = NULL, .val = 'y'}, | 550 | {"latency", no_argument, NULL, 'y'}, |
551 | { .name = "proc", .has_arg = no_argument, .flag = NULL, .val = 'o'}, | 551 | {"proc", no_argument, NULL, 'o'}, |
552 | { .name = "human", .has_arg = no_argument, .flag = NULL, .val = 'm'}, | 552 | {"human", no_argument, NULL, 'm'}, |
553 | { .name = "no-rounding", .has_arg = no_argument, .flag = NULL, .val = 'n'}, | 553 | {"no-rounding", no_argument, NULL, 'n'}, |
554 | { }, | 554 | { }, |
555 | }; | 555 | }; |
556 | 556 | ||
diff --git a/tools/power/cpupower/utils/cpufreq-set.c b/tools/power/cpupower/utils/cpufreq-set.c index 4e213576381e..0fbd1a22c0a9 100644 --- a/tools/power/cpupower/utils/cpufreq-set.c +++ b/tools/power/cpupower/utils/cpufreq-set.c | |||
@@ -22,11 +22,11 @@ | |||
22 | #define NORM_FREQ_LEN 32 | 22 | #define NORM_FREQ_LEN 32 |
23 | 23 | ||
24 | static struct option set_opts[] = { | 24 | static struct option set_opts[] = { |
25 | { .name = "min", .has_arg = required_argument, .flag = NULL, .val = 'd'}, | 25 | {"min", required_argument, NULL, 'd'}, |
26 | { .name = "max", .has_arg = required_argument, .flag = NULL, .val = 'u'}, | 26 | {"max", required_argument, NULL, 'u'}, |
27 | { .name = "governor", .has_arg = required_argument, .flag = NULL, .val = 'g'}, | 27 | {"governor", required_argument, NULL, 'g'}, |
28 | { .name = "freq", .has_arg = required_argument, .flag = NULL, .val = 'f'}, | 28 | {"freq", required_argument, NULL, 'f'}, |
29 | { .name = "related", .has_arg = no_argument, .flag = NULL, .val='r'}, | 29 | {"related", no_argument, NULL, 'r'}, |
30 | { }, | 30 | { }, |
31 | }; | 31 | }; |
32 | 32 | ||
diff --git a/tools/power/cpupower/utils/cpuidle-info.c b/tools/power/cpupower/utils/cpuidle-info.c index 75e66de7e7a7..750c1d82c3f7 100644 --- a/tools/power/cpupower/utils/cpuidle-info.c +++ b/tools/power/cpupower/utils/cpuidle-info.c | |||
@@ -126,8 +126,8 @@ static void proc_cpuidle_cpu_output(unsigned int cpu) | |||
126 | } | 126 | } |
127 | 127 | ||
128 | static struct option info_opts[] = { | 128 | static struct option info_opts[] = { |
129 | { .name = "silent", .has_arg = no_argument, .flag = NULL, .val = 's'}, | 129 | {"silent", no_argument, NULL, 's'}, |
130 | { .name = "proc", .has_arg = no_argument, .flag = NULL, .val = 'o'}, | 130 | {"proc", no_argument, NULL, 'o'}, |
131 | { }, | 131 | { }, |
132 | }; | 132 | }; |
133 | 133 | ||
diff --git a/tools/power/cpupower/utils/cpuidle-set.c b/tools/power/cpupower/utils/cpuidle-set.c index d45d8d775c02..d6b6ae44b8c2 100644 --- a/tools/power/cpupower/utils/cpuidle-set.c +++ b/tools/power/cpupower/utils/cpuidle-set.c | |||
@@ -13,15 +13,11 @@ | |||
13 | #include "helpers/sysfs.h" | 13 | #include "helpers/sysfs.h" |
14 | 14 | ||
15 | static struct option info_opts[] = { | 15 | static struct option info_opts[] = { |
16 | { .name = "disable", | 16 | {"disable", required_argument, NULL, 'd'}, |
17 | .has_arg = required_argument, .flag = NULL, .val = 'd'}, | 17 | {"enable", required_argument, NULL, 'e'}, |
18 | { .name = "enable", | 18 | {"disable-by-latency", required_argument, NULL, 'D'}, |
19 | .has_arg = required_argument, .flag = NULL, .val = 'e'}, | 19 | {"enable-all", no_argument, NULL, 'E'}, |
20 | { .name = "disable-by-latency", | 20 | { }, |
21 | .has_arg = required_argument, .flag = NULL, .val = 'D'}, | ||
22 | { .name = "enable-all", | ||
23 | .has_arg = no_argument, .flag = NULL, .val = 'E'}, | ||
24 | { }, | ||
25 | }; | 21 | }; |
26 | 22 | ||
27 | 23 | ||
@@ -148,14 +144,21 @@ int cmd_idle_set(int argc, char **argv) | |||
148 | (cpu, idlestate); | 144 | (cpu, idlestate); |
149 | state_latency = sysfs_get_idlestate_latency | 145 | state_latency = sysfs_get_idlestate_latency |
150 | (cpu, idlestate); | 146 | (cpu, idlestate); |
151 | printf("CPU: %u - idlestate %u - state_latency: %llu - latency: %llu\n", | 147 | if (disabled == 1) { |
152 | cpu, idlestate, state_latency, latency); | 148 | if (latency > state_latency){ |
153 | if (disabled == 1 || latency > state_latency) | 149 | ret = sysfs_idlestate_disable |
150 | (cpu, idlestate, 0); | ||
151 | if (ret == 0) | ||
152 | printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu); | ||
153 | } | ||
154 | continue; | 154 | continue; |
155 | ret = sysfs_idlestate_disable | 155 | } |
156 | (cpu, idlestate, 1); | 156 | if (latency <= state_latency){ |
157 | if (ret == 0) | 157 | ret = sysfs_idlestate_disable |
158 | (cpu, idlestate, 1); | ||
159 | if (ret == 0) | ||
158 | printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu); | 160 | printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu); |
161 | } | ||
159 | } | 162 | } |
160 | break; | 163 | break; |
161 | case 'E': | 164 | case 'E': |
diff --git a/tools/power/cpupower/utils/cpupower-info.c b/tools/power/cpupower/utils/cpupower-info.c index 136d979e9586..10299f2e9d2a 100644 --- a/tools/power/cpupower/utils/cpupower-info.c +++ b/tools/power/cpupower/utils/cpupower-info.c | |||
@@ -17,8 +17,8 @@ | |||
17 | #include "helpers/sysfs.h" | 17 | #include "helpers/sysfs.h" |
18 | 18 | ||
19 | static struct option set_opts[] = { | 19 | static struct option set_opts[] = { |
20 | { .name = "perf-bias", .has_arg = optional_argument, .flag = NULL, .val = 'b'}, | 20 | {"perf-bias", optional_argument, NULL, 'b'}, |
21 | { }, | 21 | { }, |
22 | }; | 22 | }; |
23 | 23 | ||
24 | static void print_wrong_arg_exit(void) | 24 | static void print_wrong_arg_exit(void) |
diff --git a/tools/power/cpupower/utils/cpupower-set.c b/tools/power/cpupower/utils/cpupower-set.c index 573c75f8e3f5..3e6f374f8dd7 100644 --- a/tools/power/cpupower/utils/cpupower-set.c +++ b/tools/power/cpupower/utils/cpupower-set.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include "helpers/bitmask.h" | 18 | #include "helpers/bitmask.h" |
19 | 19 | ||
20 | static struct option set_opts[] = { | 20 | static struct option set_opts[] = { |
21 | { .name = "perf-bias", .has_arg = required_argument, .flag = NULL, .val = 'b'}, | 21 | {"perf-bias", required_argument, NULL, 'b'}, |
22 | { }, | 22 | { }, |
23 | }; | 23 | }; |
24 | 24 | ||
diff --git a/tools/power/cpupower/utils/helpers/topology.c b/tools/power/cpupower/utils/helpers/topology.c index cea398c176e7..9cbb7fd75171 100644 --- a/tools/power/cpupower/utils/helpers/topology.c +++ b/tools/power/cpupower/utils/helpers/topology.c | |||
@@ -73,18 +73,22 @@ int get_cpu_topology(struct cpupower_topology *cpu_top) | |||
73 | for (cpu = 0; cpu < cpus; cpu++) { | 73 | for (cpu = 0; cpu < cpus; cpu++) { |
74 | cpu_top->core_info[cpu].cpu = cpu; | 74 | cpu_top->core_info[cpu].cpu = cpu; |
75 | cpu_top->core_info[cpu].is_online = sysfs_is_cpu_online(cpu); | 75 | cpu_top->core_info[cpu].is_online = sysfs_is_cpu_online(cpu); |
76 | if (!cpu_top->core_info[cpu].is_online) | ||
77 | continue; | ||
78 | if(sysfs_topology_read_file( | 76 | if(sysfs_topology_read_file( |
79 | cpu, | 77 | cpu, |
80 | "physical_package_id", | 78 | "physical_package_id", |
81 | &(cpu_top->core_info[cpu].pkg)) < 0) | 79 | &(cpu_top->core_info[cpu].pkg)) < 0) { |
82 | return -1; | 80 | cpu_top->core_info[cpu].pkg = -1; |
81 | cpu_top->core_info[cpu].core = -1; | ||
82 | continue; | ||
83 | } | ||
83 | if(sysfs_topology_read_file( | 84 | if(sysfs_topology_read_file( |
84 | cpu, | 85 | cpu, |
85 | "core_id", | 86 | "core_id", |
86 | &(cpu_top->core_info[cpu].core)) < 0) | 87 | &(cpu_top->core_info[cpu].core)) < 0) { |
87 | return -1; | 88 | cpu_top->core_info[cpu].pkg = -1; |
89 | cpu_top->core_info[cpu].core = -1; | ||
90 | continue; | ||
91 | } | ||
88 | } | 92 | } |
89 | 93 | ||
90 | qsort(cpu_top->core_info, cpus, sizeof(struct cpuid_core_info), | 94 | qsort(cpu_top->core_info, cpus, sizeof(struct cpuid_core_info), |
@@ -95,12 +99,15 @@ int get_cpu_topology(struct cpupower_topology *cpu_top) | |||
95 | done by pkg value. */ | 99 | done by pkg value. */ |
96 | last_pkg = cpu_top->core_info[0].pkg; | 100 | last_pkg = cpu_top->core_info[0].pkg; |
97 | for(cpu = 1; cpu < cpus; cpu++) { | 101 | for(cpu = 1; cpu < cpus; cpu++) { |
98 | if(cpu_top->core_info[cpu].pkg != last_pkg) { | 102 | if (cpu_top->core_info[cpu].pkg != last_pkg && |
103 | cpu_top->core_info[cpu].pkg != -1) { | ||
104 | |||
99 | last_pkg = cpu_top->core_info[cpu].pkg; | 105 | last_pkg = cpu_top->core_info[cpu].pkg; |
100 | cpu_top->pkgs++; | 106 | cpu_top->pkgs++; |
101 | } | 107 | } |
102 | } | 108 | } |
103 | cpu_top->pkgs++; | 109 | if (!cpu_top->core_info[0].pkg == -1) |
110 | cpu_top->pkgs++; | ||
104 | 111 | ||
105 | /* Intel's cores count is not consecutively numbered, there may | 112 | /* Intel's cores count is not consecutively numbered, there may |
106 | * be a core_id of 3, but none of 2. Assume there always is 0 | 113 | * be a core_id of 3, but none of 2. Assume there always is 0 |
diff --git a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c index c4bae9203a69..05f953f0f0a0 100644 --- a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c +++ b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c | |||
@@ -143,6 +143,9 @@ void print_results(int topology_depth, int cpu) | |||
143 | /* Be careful CPUs may got resorted for pkg value do not just use cpu */ | 143 | /* Be careful CPUs may got resorted for pkg value do not just use cpu */ |
144 | if (!bitmask_isbitset(cpus_chosen, cpu_top.core_info[cpu].cpu)) | 144 | if (!bitmask_isbitset(cpus_chosen, cpu_top.core_info[cpu].cpu)) |
145 | return; | 145 | return; |
146 | if (!cpu_top.core_info[cpu].is_online && | ||
147 | cpu_top.core_info[cpu].pkg == -1) | ||
148 | return; | ||
146 | 149 | ||
147 | if (topology_depth > 2) | 150 | if (topology_depth > 2) |
148 | printf("%4d|", cpu_top.core_info[cpu].pkg); | 151 | printf("%4d|", cpu_top.core_info[cpu].pkg); |
@@ -191,7 +194,8 @@ void print_results(int topology_depth, int cpu) | |||
191 | * It's up to the monitor plug-in to check .is_online, this one | 194 | * It's up to the monitor plug-in to check .is_online, this one |
192 | * is just for additional info. | 195 | * is just for additional info. |
193 | */ | 196 | */ |
194 | if (!cpu_top.core_info[cpu].is_online) { | 197 | if (!cpu_top.core_info[cpu].is_online && |
198 | cpu_top.core_info[cpu].pkg != -1) { | ||
195 | printf(_(" *is offline\n")); | 199 | printf(_(" *is offline\n")); |
196 | return; | 200 | return; |
197 | } else | 201 | } else |
@@ -388,6 +392,9 @@ int cmd_monitor(int argc, char **argv) | |||
388 | return EXIT_FAILURE; | 392 | return EXIT_FAILURE; |
389 | } | 393 | } |
390 | 394 | ||
395 | if (!cpu_top.core_info[0].is_online) | ||
396 | printf("WARNING: at least one cpu is offline\n"); | ||
397 | |||
391 | /* Default is: monitor all CPUs */ | 398 | /* Default is: monitor all CPUs */ |
392 | if (bitmask_isallclear(cpus_chosen)) | 399 | if (bitmask_isallclear(cpus_chosen)) |
393 | bitmask_setall(cpus_chosen); | 400 | bitmask_setall(cpus_chosen); |
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index bde0ef1a63df..d8e4b20b6d54 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
@@ -75,6 +75,7 @@ unsigned int aperf_mperf_multiplier = 1; | |||
75 | int do_smi; | 75 | int do_smi; |
76 | double bclk; | 76 | double bclk; |
77 | double base_hz; | 77 | double base_hz; |
78 | unsigned int has_base_hz; | ||
78 | double tsc_tweak = 1.0; | 79 | double tsc_tweak = 1.0; |
79 | unsigned int show_pkg; | 80 | unsigned int show_pkg; |
80 | unsigned int show_core; | 81 | unsigned int show_core; |
@@ -96,6 +97,7 @@ unsigned int do_ring_perf_limit_reasons; | |||
96 | unsigned int crystal_hz; | 97 | unsigned int crystal_hz; |
97 | unsigned long long tsc_hz; | 98 | unsigned long long tsc_hz; |
98 | int base_cpu; | 99 | int base_cpu; |
100 | double discover_bclk(unsigned int family, unsigned int model); | ||
99 | 101 | ||
100 | #define RAPL_PKG (1 << 0) | 102 | #define RAPL_PKG (1 << 0) |
101 | /* 0x610 MSR_PKG_POWER_LIMIT */ | 103 | /* 0x610 MSR_PKG_POWER_LIMIT */ |
@@ -511,9 +513,13 @@ int format_counters(struct thread_data *t, struct core_data *c, | |||
511 | } | 513 | } |
512 | 514 | ||
513 | /* Bzy_MHz */ | 515 | /* Bzy_MHz */ |
514 | if (has_aperf) | 516 | if (has_aperf) { |
515 | outp += sprintf(outp, "%8.0f", | 517 | if (has_base_hz) |
516 | 1.0 * t->tsc * tsc_tweak / units * t->aperf / t->mperf / interval_float); | 518 | outp += sprintf(outp, "%8.0f", base_hz / units * t->aperf / t->mperf); |
519 | else | ||
520 | outp += sprintf(outp, "%8.0f", | ||
521 | 1.0 * t->tsc / units * t->aperf / t->mperf / interval_float); | ||
522 | } | ||
517 | 523 | ||
518 | /* TSC_MHz */ | 524 | /* TSC_MHz */ |
519 | outp += sprintf(outp, "%8.0f", 1.0 * t->tsc/units/interval_float); | 525 | outp += sprintf(outp, "%8.0f", 1.0 * t->tsc/units/interval_float); |
@@ -1158,12 +1164,6 @@ int phi_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, | |||
1158 | static void | 1164 | static void |
1159 | calculate_tsc_tweak() | 1165 | calculate_tsc_tweak() |
1160 | { | 1166 | { |
1161 | unsigned long long msr; | ||
1162 | unsigned int base_ratio; | ||
1163 | |||
1164 | get_msr(base_cpu, MSR_NHM_PLATFORM_INFO, &msr); | ||
1165 | base_ratio = (msr >> 8) & 0xFF; | ||
1166 | base_hz = base_ratio * bclk * 1000000; | ||
1167 | tsc_tweak = base_hz / tsc_hz; | 1167 | tsc_tweak = base_hz / tsc_hz; |
1168 | } | 1168 | } |
1169 | 1169 | ||
@@ -1440,7 +1440,7 @@ dump_config_tdp(void) | |||
1440 | 1440 | ||
1441 | get_msr(base_cpu, MSR_TURBO_ACTIVATION_RATIO, &msr); | 1441 | get_msr(base_cpu, MSR_TURBO_ACTIVATION_RATIO, &msr); |
1442 | fprintf(stderr, "cpu%d: MSR_TURBO_ACTIVATION_RATIO: 0x%08llx (", base_cpu, msr); | 1442 | fprintf(stderr, "cpu%d: MSR_TURBO_ACTIVATION_RATIO: 0x%08llx (", base_cpu, msr); |
1443 | fprintf(stderr, "MAX_NON_TURBO_RATIO=%d", (unsigned int)(msr) & 0xEF); | 1443 | fprintf(stderr, "MAX_NON_TURBO_RATIO=%d", (unsigned int)(msr) & 0x7F); |
1444 | fprintf(stderr, " lock=%d", (unsigned int)(msr >> 31) & 1); | 1444 | fprintf(stderr, " lock=%d", (unsigned int)(msr >> 31) & 1); |
1445 | fprintf(stderr, ")\n"); | 1445 | fprintf(stderr, ")\n"); |
1446 | } | 1446 | } |
@@ -1821,6 +1821,7 @@ void check_permissions() | |||
1821 | int probe_nhm_msrs(unsigned int family, unsigned int model) | 1821 | int probe_nhm_msrs(unsigned int family, unsigned int model) |
1822 | { | 1822 | { |
1823 | unsigned long long msr; | 1823 | unsigned long long msr; |
1824 | unsigned int base_ratio; | ||
1824 | int *pkg_cstate_limits; | 1825 | int *pkg_cstate_limits; |
1825 | 1826 | ||
1826 | if (!genuine_intel) | 1827 | if (!genuine_intel) |
@@ -1829,6 +1830,8 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) | |||
1829 | if (family != 6) | 1830 | if (family != 6) |
1830 | return 0; | 1831 | return 0; |
1831 | 1832 | ||
1833 | bclk = discover_bclk(family, model); | ||
1834 | |||
1832 | switch (model) { | 1835 | switch (model) { |
1833 | case 0x1A: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */ | 1836 | case 0x1A: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */ |
1834 | case 0x1E: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */ | 1837 | case 0x1E: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */ |
@@ -1871,9 +1874,13 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) | |||
1871 | return 0; | 1874 | return 0; |
1872 | } | 1875 | } |
1873 | get_msr(base_cpu, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr); | 1876 | get_msr(base_cpu, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr); |
1874 | |||
1875 | pkg_cstate_limit = pkg_cstate_limits[msr & 0xF]; | 1877 | pkg_cstate_limit = pkg_cstate_limits[msr & 0xF]; |
1876 | 1878 | ||
1879 | get_msr(base_cpu, MSR_NHM_PLATFORM_INFO, &msr); | ||
1880 | base_ratio = (msr >> 8) & 0xFF; | ||
1881 | |||
1882 | base_hz = base_ratio * bclk * 1000000; | ||
1883 | has_base_hz = 1; | ||
1877 | return 1; | 1884 | return 1; |
1878 | } | 1885 | } |
1879 | int has_nhm_turbo_ratio_limit(unsigned int family, unsigned int model) | 1886 | int has_nhm_turbo_ratio_limit(unsigned int family, unsigned int model) |
@@ -2780,7 +2787,6 @@ void process_cpuid() | |||
2780 | do_skl_residency = has_skl_msrs(family, model); | 2787 | do_skl_residency = has_skl_msrs(family, model); |
2781 | do_slm_cstates = is_slm(family, model); | 2788 | do_slm_cstates = is_slm(family, model); |
2782 | do_knl_cstates = is_knl(family, model); | 2789 | do_knl_cstates = is_knl(family, model); |
2783 | bclk = discover_bclk(family, model); | ||
2784 | 2790 | ||
2785 | rapl_probe(family, model); | 2791 | rapl_probe(family, model); |
2786 | perf_limit_reasons_probe(family, model); | 2792 | perf_limit_reasons_probe(family, model); |