Merge branches 'acpi-processor', 'acpi-apei' and 'acpi-ec'
Merge ACPI processor driver changes, APEI changes and ACPI EC driver changes for v5.20-rc1: - Drop leftover acpi_processor_get_limit_info() declaration (Riwen Lu). - Split out thermal initialization from ACPI PSS (Riwen Lu). - Annotate more functions in the ACPI CPU idle driver to live in the cpuidle section (Guilherme G. Piccoli). - Fix _EINJ vs "special purpose" EFI memory regions (Dan Williams). - Implement a better fix to avoid spamming the console with old error logs (Tony Luck). - Fix typo in a comment in the APEI code (Xiang wangx). - Clean up the ACPI EC driver after previous changes in it (Hans de Goede). * acpi-processor: ACPI: processor: Drop leftover acpi_processor_get_limit_info() declaration ACPI: processor: Split out thermal initialization from ACPI PSS ACPI: processor/idle: Annotate more functions to live in cpuidle section * acpi-apei: ACPI: APEI: Fix _EINJ vs EFI_MEMORY_SP ACPI: APEI: Better fix to avoid spamming the console with old error logs ACPI: APEI: Fix double word in a comment * acpi-ec: ACPI: EC: Drop unused ident initializers from dmi_system_id tables ACPI: EC: Re-use boot_ec when possible even when EC_FLAGS_TRUST_DSDT_GPE is set ACPI: EC: Drop the EC_FLAGS_IGNORE_DSDT_GPE quirk ACPI: EC: Remove duplicate ThinkPad X1 Carbon 6th entry from DMI quirks
This commit is contained in:
commit
198c414ef2
|
@ -255,7 +255,6 @@ config ACPI_DOCK
|
|||
|
||||
config ACPI_CPU_FREQ_PSS
|
||||
bool
|
||||
select THERMAL
|
||||
|
||||
config ACPI_PROCESSOR_CSTATE
|
||||
def_bool y
|
||||
|
@ -287,6 +286,7 @@ config ACPI_PROCESSOR
|
|||
depends on X86 || IA64 || ARM64 || LOONGARCH
|
||||
select ACPI_PROCESSOR_IDLE
|
||||
select ACPI_CPU_FREQ_PSS if X86 || IA64 || LOONGARCH
|
||||
select THERMAL
|
||||
default y
|
||||
help
|
||||
This driver adds support for the ACPI Processor package. It is required
|
||||
|
|
|
@ -109,10 +109,9 @@ obj-$(CONFIG_ACPI_PPTT) += pptt.o
|
|||
obj-$(CONFIG_ACPI_PFRUT) += pfr_update.o pfr_telemetry.o
|
||||
|
||||
# processor has its own "processor." module_param namespace
|
||||
processor-y := processor_driver.o
|
||||
processor-y := processor_driver.o processor_thermal.o
|
||||
processor-$(CONFIG_ACPI_PROCESSOR_IDLE) += processor_idle.o
|
||||
processor-$(CONFIG_ACPI_CPU_FREQ_PSS) += processor_throttling.o \
|
||||
processor_thermal.o
|
||||
processor-$(CONFIG_ACPI_CPU_FREQ_PSS) += processor_throttling.o
|
||||
processor-$(CONFIG_CPU_FREQ) += processor_perflib.o
|
||||
|
||||
obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* apei-base.c - ACPI Platform Error Interface (APEI) supporting
|
||||
* infrastructure
|
||||
*
|
||||
* APEI allows to report errors (for example from the chipset) to the
|
||||
* APEI allows to report errors (for example from the chipset) to
|
||||
* the operating system. This improves NMI handling especially. In
|
||||
* addition it supports error serialization and error injection.
|
||||
*
|
||||
|
|
|
@ -29,16 +29,26 @@
|
|||
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) "BERT: " fmt
|
||||
|
||||
#define ACPI_BERT_PRINT_MAX_RECORDS 5
|
||||
#define ACPI_BERT_PRINT_MAX_LEN 1024
|
||||
|
||||
static int bert_disable;
|
||||
|
||||
/*
|
||||
* Print "all" the error records in the BERT table, but avoid huge spam to
|
||||
* the console if the BIOS included oversize records, or too many records.
|
||||
* Skipping some records here does not lose anything because the full
|
||||
* data is available to user tools in:
|
||||
* /sys/firmware/acpi/tables/data/BERT
|
||||
*/
|
||||
static void __init bert_print_all(struct acpi_bert_region *region,
|
||||
unsigned int region_len)
|
||||
{
|
||||
struct acpi_hest_generic_status *estatus =
|
||||
(struct acpi_hest_generic_status *)region;
|
||||
int remain = region_len;
|
||||
int printed = 0, skipped = 0;
|
||||
u32 estatus_len;
|
||||
|
||||
while (remain >= sizeof(struct acpi_bert_region)) {
|
||||
|
@ -46,24 +56,26 @@ static void __init bert_print_all(struct acpi_bert_region *region,
|
|||
if (remain < estatus_len) {
|
||||
pr_err(FW_BUG "Truncated status block (length: %u).\n",
|
||||
estatus_len);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
/* No more error records. */
|
||||
if (!estatus->block_status)
|
||||
return;
|
||||
break;
|
||||
|
||||
if (cper_estatus_check(estatus)) {
|
||||
pr_err(FW_BUG "Invalid error record.\n");
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
pr_info_once("Error records from previous boot:\n");
|
||||
if (region_len < ACPI_BERT_PRINT_MAX_LEN)
|
||||
if (estatus_len < ACPI_BERT_PRINT_MAX_LEN &&
|
||||
printed < ACPI_BERT_PRINT_MAX_RECORDS) {
|
||||
pr_info_once("Error records from previous boot:\n");
|
||||
cper_estatus_print(KERN_INFO HW_ERR, estatus);
|
||||
else
|
||||
pr_info_once("Max print length exceeded, table data is available at:\n"
|
||||
"/sys/firmware/acpi/tables/data/BERT");
|
||||
printed++;
|
||||
} else {
|
||||
skipped++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Because the boot error source is "one-time polled" type,
|
||||
|
@ -75,6 +87,9 @@ static void __init bert_print_all(struct acpi_bert_region *region,
|
|||
estatus = (void *)estatus + estatus_len;
|
||||
remain -= estatus_len;
|
||||
}
|
||||
|
||||
if (skipped)
|
||||
pr_info(HW_ERR "Skipped %d error records\n", skipped);
|
||||
}
|
||||
|
||||
static int __init setup_bert_disable(char *str)
|
||||
|
|
|
@ -546,6 +546,8 @@ static int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2,
|
|||
!= REGION_INTERSECTS) &&
|
||||
(region_intersects(base_addr, size, IORESOURCE_MEM, IORES_DESC_PERSISTENT_MEMORY)
|
||||
!= REGION_INTERSECTS) &&
|
||||
(region_intersects(base_addr, size, IORESOURCE_MEM, IORES_DESC_SOFT_RESERVED)
|
||||
!= REGION_INTERSECTS) &&
|
||||
!arch_is_platform_page(base_addr)))
|
||||
return -EINVAL;
|
||||
|
||||
|
|
|
@ -180,7 +180,6 @@ static struct workqueue_struct *ec_wq;
|
|||
static struct workqueue_struct *ec_query_wq;
|
||||
|
||||
static int EC_FLAGS_CORRECT_ECDT; /* Needs ECDT port address correction */
|
||||
static int EC_FLAGS_IGNORE_DSDT_GPE; /* Needs ECDT GPE as correction setting */
|
||||
static int EC_FLAGS_TRUST_DSDT_GPE; /* Needs DSDT GPE as correction setting */
|
||||
static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */
|
||||
|
||||
|
@ -1407,24 +1406,16 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
|
|||
if (ec->data_addr == 0 || ec->command_addr == 0)
|
||||
return AE_OK;
|
||||
|
||||
if (boot_ec && boot_ec_is_ecdt && EC_FLAGS_IGNORE_DSDT_GPE) {
|
||||
/*
|
||||
* Always inherit the GPE number setting from the ECDT
|
||||
* EC.
|
||||
*/
|
||||
ec->gpe = boot_ec->gpe;
|
||||
} else {
|
||||
/* Get GPE bit assignment (EC events). */
|
||||
/* TODO: Add support for _GPE returning a package */
|
||||
status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp);
|
||||
if (ACPI_SUCCESS(status))
|
||||
ec->gpe = tmp;
|
||||
/* Get GPE bit assignment (EC events). */
|
||||
/* TODO: Add support for _GPE returning a package */
|
||||
status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp);
|
||||
if (ACPI_SUCCESS(status))
|
||||
ec->gpe = tmp;
|
||||
/*
|
||||
* Errors are non-fatal, allowing for ACPI Reduced Hardware
|
||||
* platforms which use GpioInt instead of GPE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Errors are non-fatal, allowing for ACPI Reduced Hardware
|
||||
* platforms which use GpioInt instead of GPE.
|
||||
*/
|
||||
}
|
||||
/* Use the global lock for all EC transactions? */
|
||||
tmp = 0;
|
||||
acpi_evaluate_integer(handle, "_GLK", NULL, &tmp);
|
||||
|
@ -1626,15 +1617,18 @@ static int acpi_ec_add(struct acpi_device *device)
|
|||
}
|
||||
|
||||
if (boot_ec && ec->command_addr == boot_ec->command_addr &&
|
||||
ec->data_addr == boot_ec->data_addr &&
|
||||
!EC_FLAGS_TRUST_DSDT_GPE) {
|
||||
ec->data_addr == boot_ec->data_addr) {
|
||||
/*
|
||||
* Trust PNP0C09 namespace location rather than
|
||||
* ECDT ID. But trust ECDT GPE rather than _GPE
|
||||
* because of ASUS quirks, so do not change
|
||||
* boot_ec->gpe to ec->gpe.
|
||||
* Trust PNP0C09 namespace location rather than ECDT ID.
|
||||
* But trust ECDT GPE rather than _GPE because of ASUS
|
||||
* quirks. So do not change boot_ec->gpe to ec->gpe,
|
||||
* except when the TRUST_DSDT_GPE quirk is set.
|
||||
*/
|
||||
boot_ec->handle = ec->handle;
|
||||
|
||||
if (EC_FLAGS_TRUST_DSDT_GPE)
|
||||
boot_ec->gpe = ec->gpe;
|
||||
|
||||
acpi_handle_debug(ec->handle, "duplicated.\n");
|
||||
acpi_ec_free(ec);
|
||||
ec = boot_ec;
|
||||
|
@ -1862,68 +1856,40 @@ static int ec_honor_dsdt_gpe(const struct dmi_system_id *id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some DSDTs contain wrong GPE setting.
|
||||
* Asus FX502VD/VE, GL702VMK, X550VXK, X580VD
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=195651
|
||||
*/
|
||||
static int ec_honor_ecdt_gpe(const struct dmi_system_id *id)
|
||||
{
|
||||
pr_debug("Detected system needing ignore DSDT GPE setting.\n");
|
||||
EC_FLAGS_IGNORE_DSDT_GPE = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dmi_system_id ec_dmi_table[] __initconst = {
|
||||
{
|
||||
ec_correct_ecdt, "MSI MS-171F", {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "MS-171F"),}, NULL},
|
||||
/*
|
||||
* MSI MS-171F
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=12461
|
||||
*/
|
||||
.callback = ec_correct_ecdt,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "MS-171F"),
|
||||
},
|
||||
},
|
||||
{
|
||||
ec_honor_ecdt_gpe, "ASUS FX502VD", {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "FX502VD"),}, NULL},
|
||||
/*
|
||||
* HP Pavilion Gaming Laptop 15-cx0xxx
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=209989
|
||||
*/
|
||||
.callback = ec_honor_dsdt_gpe,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Gaming Laptop 15-cx0xxx"),
|
||||
},
|
||||
},
|
||||
{
|
||||
ec_honor_ecdt_gpe, "ASUS FX502VE", {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "FX502VE"),}, NULL},
|
||||
{
|
||||
ec_honor_ecdt_gpe, "ASUS GL702VMK", {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "GL702VMK"),}, NULL},
|
||||
{
|
||||
ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X505BA", {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "X505BA"),}, NULL},
|
||||
{
|
||||
ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X505BP", {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "X505BP"),}, NULL},
|
||||
{
|
||||
ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X542BA", {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "X542BA"),}, NULL},
|
||||
{
|
||||
ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X542BP", {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "X542BP"),}, NULL},
|
||||
{
|
||||
ec_honor_ecdt_gpe, "ASUS X550VXK", {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "X550VXK"),}, NULL},
|
||||
{
|
||||
ec_honor_ecdt_gpe, "ASUS X580VD", {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "X580VD"),}, NULL},
|
||||
{
|
||||
/* https://bugzilla.kernel.org/show_bug.cgi?id=209989 */
|
||||
ec_honor_dsdt_gpe, "HP Pavilion Gaming Laptop 15-cx0xxx", {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Gaming Laptop 15-cx0xxx"),}, NULL},
|
||||
{
|
||||
ec_clear_on_resume, "Samsung hardware", {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL},
|
||||
{},
|
||||
/*
|
||||
* Samsung hardware
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=44161
|
||||
*/
|
||||
.callback = ec_clear_on_resume,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
},
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
void __init acpi_ec_ecdt_probe(void)
|
||||
|
@ -2201,28 +2167,18 @@ static int acpi_ec_init_workqueues(void)
|
|||
|
||||
static const struct dmi_system_id acpi_ec_no_wakeup[] = {
|
||||
{
|
||||
.ident = "Thinkpad X1 Carbon 6th",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_FAMILY, "Thinkpad X1 Carbon 6th"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "ThinkPad X1 Carbon 6th",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Carbon 6th"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "ThinkPad X1 Yoga 3rd",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Yoga 3rd"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "HP ZHAN 66 Pro",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
|
||||
DMI_MATCH(DMI_PRODUCT_FAMILY, "103C_5336AN HP ZHAN 66 Pro"),
|
||||
|
|
|
@ -139,75 +139,17 @@ static int acpi_soft_cpu_dead(unsigned int cpu)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_CPU_FREQ_PSS
|
||||
static int acpi_pss_perf_init(struct acpi_processor *pr,
|
||||
struct acpi_device *device)
|
||||
static void acpi_pss_perf_init(struct acpi_processor *pr)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
acpi_processor_ppc_has_changed(pr, 0);
|
||||
|
||||
acpi_processor_get_throttling_info(pr);
|
||||
|
||||
if (pr->flags.throttling)
|
||||
pr->flags.limit = 1;
|
||||
|
||||
pr->cdev = thermal_cooling_device_register("Processor", device,
|
||||
&processor_cooling_ops);
|
||||
if (IS_ERR(pr->cdev)) {
|
||||
result = PTR_ERR(pr->cdev);
|
||||
return result;
|
||||
}
|
||||
|
||||
dev_dbg(&device->dev, "registered as cooling_device%d\n",
|
||||
pr->cdev->id);
|
||||
|
||||
result = sysfs_create_link(&device->dev.kobj,
|
||||
&pr->cdev->device.kobj,
|
||||
"thermal_cooling");
|
||||
if (result) {
|
||||
dev_err(&device->dev,
|
||||
"Failed to create sysfs link 'thermal_cooling'\n");
|
||||
goto err_thermal_unregister;
|
||||
}
|
||||
|
||||
result = sysfs_create_link(&pr->cdev->device.kobj,
|
||||
&device->dev.kobj,
|
||||
"device");
|
||||
if (result) {
|
||||
dev_err(&pr->cdev->device,
|
||||
"Failed to create sysfs link 'device'\n");
|
||||
goto err_remove_sysfs_thermal;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_remove_sysfs_thermal:
|
||||
sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
|
||||
err_thermal_unregister:
|
||||
thermal_cooling_device_unregister(pr->cdev);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void acpi_pss_perf_exit(struct acpi_processor *pr,
|
||||
struct acpi_device *device)
|
||||
{
|
||||
if (pr->cdev) {
|
||||
sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
|
||||
sysfs_remove_link(&pr->cdev->device.kobj, "device");
|
||||
thermal_cooling_device_unregister(pr->cdev);
|
||||
pr->cdev = NULL;
|
||||
}
|
||||
}
|
||||
#else
|
||||
static inline int acpi_pss_perf_init(struct acpi_processor *pr,
|
||||
struct acpi_device *device)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void acpi_pss_perf_exit(struct acpi_processor *pr,
|
||||
struct acpi_device *device) {}
|
||||
static inline void acpi_pss_perf_init(struct acpi_processor *pr) {}
|
||||
#endif /* CONFIG_ACPI_CPU_FREQ_PSS */
|
||||
|
||||
static int __acpi_processor_start(struct acpi_device *device)
|
||||
|
@ -229,7 +171,9 @@ static int __acpi_processor_start(struct acpi_device *device)
|
|||
if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
|
||||
acpi_processor_power_init(pr);
|
||||
|
||||
result = acpi_pss_perf_init(pr, device);
|
||||
acpi_pss_perf_init(pr);
|
||||
|
||||
result = acpi_processor_thermal_init(pr, device);
|
||||
if (result)
|
||||
goto err_power_exit;
|
||||
|
||||
|
@ -239,7 +183,7 @@ static int __acpi_processor_start(struct acpi_device *device)
|
|||
return 0;
|
||||
|
||||
result = -ENODEV;
|
||||
acpi_pss_perf_exit(pr, device);
|
||||
acpi_processor_thermal_exit(pr, device);
|
||||
|
||||
err_power_exit:
|
||||
acpi_processor_power_exit(pr);
|
||||
|
@ -277,10 +221,10 @@ static int acpi_processor_stop(struct device *dev)
|
|||
return 0;
|
||||
acpi_processor_power_exit(pr);
|
||||
|
||||
acpi_pss_perf_exit(pr, device);
|
||||
|
||||
acpi_cppc_processor_exit(pr);
|
||||
|
||||
acpi_processor_thermal_exit(pr, device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -607,7 +607,7 @@ static DEFINE_RAW_SPINLOCK(c3_lock);
|
|||
* @cx: Target state context
|
||||
* @index: index of target state
|
||||
*/
|
||||
static int acpi_idle_enter_bm(struct cpuidle_driver *drv,
|
||||
static int __cpuidle acpi_idle_enter_bm(struct cpuidle_driver *drv,
|
||||
struct acpi_processor *pr,
|
||||
struct acpi_processor_cx *cx,
|
||||
int index)
|
||||
|
@ -664,7 +664,7 @@ static int acpi_idle_enter_bm(struct cpuidle_driver *drv,
|
|||
return index;
|
||||
}
|
||||
|
||||
static int acpi_idle_enter(struct cpuidle_device *dev,
|
||||
static int __cpuidle acpi_idle_enter(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv, int index)
|
||||
{
|
||||
struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu);
|
||||
|
@ -693,7 +693,7 @@ static int acpi_idle_enter(struct cpuidle_device *dev,
|
|||
return index;
|
||||
}
|
||||
|
||||
static int acpi_idle_enter_s2idle(struct cpuidle_device *dev,
|
||||
static int __cpuidle acpi_idle_enter_s2idle(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv, int index)
|
||||
{
|
||||
struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu);
|
||||
|
|
|
@ -266,3 +266,57 @@ const struct thermal_cooling_device_ops processor_cooling_ops = {
|
|||
.get_cur_state = processor_get_cur_state,
|
||||
.set_cur_state = processor_set_cur_state,
|
||||
};
|
||||
|
||||
int acpi_processor_thermal_init(struct acpi_processor *pr,
|
||||
struct acpi_device *device)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
pr->cdev = thermal_cooling_device_register("Processor", device,
|
||||
&processor_cooling_ops);
|
||||
if (IS_ERR(pr->cdev)) {
|
||||
result = PTR_ERR(pr->cdev);
|
||||
return result;
|
||||
}
|
||||
|
||||
dev_dbg(&device->dev, "registered as cooling_device%d\n",
|
||||
pr->cdev->id);
|
||||
|
||||
result = sysfs_create_link(&device->dev.kobj,
|
||||
&pr->cdev->device.kobj,
|
||||
"thermal_cooling");
|
||||
if (result) {
|
||||
dev_err(&device->dev,
|
||||
"Failed to create sysfs link 'thermal_cooling'\n");
|
||||
goto err_thermal_unregister;
|
||||
}
|
||||
|
||||
result = sysfs_create_link(&pr->cdev->device.kobj,
|
||||
&device->dev.kobj,
|
||||
"device");
|
||||
if (result) {
|
||||
dev_err(&pr->cdev->device,
|
||||
"Failed to create sysfs link 'device'\n");
|
||||
goto err_remove_sysfs_thermal;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_remove_sysfs_thermal:
|
||||
sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
|
||||
err_thermal_unregister:
|
||||
thermal_cooling_device_unregister(pr->cdev);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void acpi_processor_thermal_exit(struct acpi_processor *pr,
|
||||
struct acpi_device *device)
|
||||
{
|
||||
if (pr->cdev) {
|
||||
sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
|
||||
sysfs_remove_link(&pr->cdev->device.kobj, "device");
|
||||
thermal_cooling_device_unregister(pr->cdev);
|
||||
pr->cdev = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -441,9 +441,12 @@ static inline int acpi_processor_hotplug(struct acpi_processor *pr)
|
|||
#endif /* CONFIG_ACPI_PROCESSOR_IDLE */
|
||||
|
||||
/* in processor_thermal.c */
|
||||
int acpi_processor_get_limit_info(struct acpi_processor *pr);
|
||||
int acpi_processor_thermal_init(struct acpi_processor *pr,
|
||||
struct acpi_device *device);
|
||||
void acpi_processor_thermal_exit(struct acpi_processor *pr,
|
||||
struct acpi_device *device);
|
||||
extern const struct thermal_cooling_device_ops processor_cooling_ops;
|
||||
#if defined(CONFIG_ACPI_CPU_FREQ_PSS) & defined(CONFIG_CPU_FREQ)
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
void acpi_thermal_cpufreq_init(struct cpufreq_policy *policy);
|
||||
void acpi_thermal_cpufreq_exit(struct cpufreq_policy *policy);
|
||||
#else
|
||||
|
@ -455,6 +458,6 @@ static inline void acpi_thermal_cpufreq_exit(struct cpufreq_policy *policy)
|
|||
{
|
||||
return;
|
||||
}
|
||||
#endif /* CONFIG_ACPI_CPU_FREQ_PSS */
|
||||
#endif /* CONFIG_CPU_FREQ */
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue