Merge branches 'acpi-x86', 'acpi-video', 'acpi-apei' and 'acpi-misc'
Merge x86-specific ACPI changes, an ACPI backlight driver change, ACPI APEI change and miscellaneous ACPI-related changes for 6.9-rc1: - Add DELL0501 handling to acpi_quirk_skip_serdev_enumeration() and make that function generic (Hans de Goede). - Make the ACPI backlight code handle fetching EDID that is longer than 256 bytes (Mario Limonciello). - Skip initialization of GHES_ASSIST structures for Machine Check Architecture in APEI (Avadhut Naik). - Convert several plaform drivers in the ACPI subsystem to using a remove callback that returns void (Uwe Kleine-König). - Drop the long-deprecated custom_method debugfs interface that is problematic from the security standpoint (Rafael Wysocki). - Use %pe in a couple of places in the ACPI code for easier error decoding (Onkarnath). * acpi-x86: ACPI: x86: Add DELL0501 handling to acpi_quirk_skip_serdev_enumeration() ACPI: x86: Move acpi_quirk_skip_serdev_enumeration() out of CONFIG_X86_ANDROID_TABLETS * acpi-video: ACPI: video: Handle fetching EDID that is longer than 256 bytes * acpi-apei: ACPI: APEI: Skip initialization of GHES_ASSIST structures for Machine Check Architecture ACPI: APEI: GHES: Convert to platform remove callback returning void * acpi-misc: ACPI: pfr_update: Convert to platform remove callback returning void ACPI: pfr_telemetry: Convert to platform remove callback returning void ACPI: fan: Convert to platform remove callback returning void ACPI: GED: Convert to platform remove callback returning void ACPI: DPTF: Convert to platform remove callback returning void ACPI: AGDI: Convert to platform remove callback returning void ACPI: TAD: Convert to platform remove callback returning void ACPI: Drop the custom_method debugfs interface ACPI: use %pe for better readability of errors while printing
This commit is contained in:
commit
817d2371e4
21 changed files with 138 additions and 280 deletions
|
@ -14,7 +14,6 @@ ACPI Support
|
|||
dsd/phy
|
||||
enumeration
|
||||
osi
|
||||
method-customizing
|
||||
method-tracing
|
||||
DSD-properties-rules
|
||||
debug
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
=======================================
|
||||
Linux ACPI Custom Control Method How To
|
||||
=======================================
|
||||
|
||||
:Author: Zhang Rui <rui.zhang@intel.com>
|
||||
|
||||
|
||||
Linux supports customizing ACPI control methods at runtime.
|
||||
|
||||
Users can use this to:
|
||||
|
||||
1. override an existing method which may not work correctly,
|
||||
or just for debugging purposes.
|
||||
2. insert a completely new method in order to create a missing
|
||||
method such as _OFF, _ON, _STA, _INI, etc.
|
||||
|
||||
For these cases, it is far simpler to dynamically install a single
|
||||
control method rather than override the entire DSDT, because kernel
|
||||
rebuild/reboot is not needed and test result can be got in minutes.
|
||||
|
||||
.. note::
|
||||
|
||||
- Only ACPI METHOD can be overridden, any other object types like
|
||||
"Device", "OperationRegion", are not recognized. Methods
|
||||
declared inside scope operators are also not supported.
|
||||
|
||||
- The same ACPI control method can be overridden for many times,
|
||||
and it's always the latest one that used by Linux/kernel.
|
||||
|
||||
- To get the ACPI debug object output (Store (AAAA, Debug)),
|
||||
please run::
|
||||
|
||||
echo 1 > /sys/module/acpi/parameters/aml_debug_output
|
||||
|
||||
|
||||
1. override an existing method
|
||||
==============================
|
||||
a) get the ACPI table via ACPI sysfs I/F. e.g. to get the DSDT,
|
||||
just run "cat /sys/firmware/acpi/tables/DSDT > /tmp/dsdt.dat"
|
||||
b) disassemble the table by running "iasl -d dsdt.dat".
|
||||
c) rewrite the ASL code of the method and save it in a new file,
|
||||
d) package the new file (psr.asl) to an ACPI table format.
|
||||
Here is an example of a customized \_SB._AC._PSR method::
|
||||
|
||||
DefinitionBlock ("", "SSDT", 1, "", "", 0x20080715)
|
||||
{
|
||||
Method (\_SB_.AC._PSR, 0, NotSerialized)
|
||||
{
|
||||
Store ("In AC _PSR", Debug)
|
||||
Return (ACON)
|
||||
}
|
||||
}
|
||||
|
||||
Note that the full pathname of the method in ACPI namespace
|
||||
should be used.
|
||||
e) assemble the file to generate the AML code of the method.
|
||||
e.g. "iasl -vw 6084 psr.asl" (psr.aml is generated as a result)
|
||||
If parameter "-vw 6084" is not supported by your iASL compiler,
|
||||
please try a newer version.
|
||||
f) mount debugfs by "mount -t debugfs none /sys/kernel/debug"
|
||||
g) override the old method via the debugfs by running
|
||||
"cat /tmp/psr.aml > /sys/kernel/debug/acpi/custom_method"
|
||||
|
||||
2. insert a new method
|
||||
======================
|
||||
This is easier than overriding an existing method.
|
||||
We just need to create the ASL code of the method we want to
|
||||
insert and then follow the step c) ~ g) in section 1.
|
||||
|
||||
3. undo your changes
|
||||
====================
|
||||
The "undo" operation is not supported for a new inserted method
|
||||
right now, i.e. we can not remove a method currently.
|
||||
For an overridden method, in order to undo your changes, please
|
||||
save a copy of the method original ASL code in step c) section 1,
|
||||
and redo step c) ~ g) to override the method with the original one.
|
||||
|
||||
|
||||
.. note:: We can use a kernel with multiple custom ACPI method running,
|
||||
But each individual write to debugfs can implement a SINGLE
|
||||
method override. i.e. if we want to insert/override multiple
|
||||
ACPI methods, we need to redo step c) ~ g) for multiple times.
|
||||
|
||||
.. note:: Be aware that root can mis-use this driver to modify arbitrary
|
||||
memory and gain additional rights, if root's privileges got
|
||||
restricted (for example if root is not allowed to load additional
|
||||
modules after boot).
|
|
@ -449,20 +449,6 @@ config ACPI_HED
|
|||
which is used to report some hardware errors notified via
|
||||
SCI, mainly the corrected errors.
|
||||
|
||||
config ACPI_CUSTOM_METHOD
|
||||
tristate "Allow ACPI methods to be inserted/replaced at run time"
|
||||
depends on DEBUG_FS
|
||||
help
|
||||
This debug facility allows ACPI AML methods to be inserted and/or
|
||||
replaced without rebooting the system. For details refer to:
|
||||
Documentation/firmware-guide/acpi/method-customizing.rst.
|
||||
|
||||
NOTE: This option is security sensitive, because it allows arbitrary
|
||||
kernel memory to be written to by root (uid=0) users, allowing them
|
||||
to bypass certain security measures (e.g. if root is not allowed to
|
||||
load additional kernel modules after boot, this feature may be used
|
||||
to override that restriction).
|
||||
|
||||
config ACPI_BGRT
|
||||
bool "Boottime Graphics Resource Table support"
|
||||
depends on EFI && (X86 || ARM64)
|
||||
|
|
|
@ -101,7 +101,6 @@ obj-$(CONFIG_ACPI_SBS) += sbshc.o
|
|||
obj-$(CONFIG_ACPI_SBS) += sbs.o
|
||||
obj-$(CONFIG_ACPI_HED) += hed.o
|
||||
obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o
|
||||
obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
|
||||
obj-$(CONFIG_ACPI_BGRT) += bgrt.o
|
||||
obj-$(CONFIG_ACPI_CPPC_LIB) += cppc_acpi.o
|
||||
obj-$(CONFIG_ACPI_SPCR_TABLE) += spcr.o
|
||||
|
|
|
@ -161,7 +161,7 @@ static void cpufreq_add_device(const char *name)
|
|||
|
||||
pdev = platform_device_register_simple(name, PLATFORM_DEVID_NONE, NULL, 0);
|
||||
if (IS_ERR(pdev))
|
||||
pr_info("%s device creation failed: %ld\n", name, PTR_ERR(pdev));
|
||||
pr_info("%s device creation failed: %pe\n", name, pdev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
|
|
|
@ -554,7 +554,7 @@ static int acpi_tad_disable_timer(struct device *dev, u32 timer_id)
|
|||
return acpi_tad_wake_set(dev, "_STV", timer_id, ACPI_TAD_WAKE_DISABLED);
|
||||
}
|
||||
|
||||
static int acpi_tad_remove(struct platform_device *pdev)
|
||||
static void acpi_tad_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
acpi_handle handle = ACPI_HANDLE(dev);
|
||||
|
@ -579,7 +579,6 @@ static int acpi_tad_remove(struct platform_device *pdev)
|
|||
pm_runtime_put_sync(dev);
|
||||
pm_runtime_disable(dev);
|
||||
acpi_remove_cmos_rtc_space_handler(handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_tad_probe(struct platform_device *pdev)
|
||||
|
@ -684,7 +683,7 @@ static struct platform_driver acpi_tad_driver = {
|
|||
.acpi_match_table = acpi_tad_ids,
|
||||
},
|
||||
.probe = acpi_tad_probe,
|
||||
.remove = acpi_tad_remove,
|
||||
.remove_new = acpi_tad_remove,
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, acpi_tad_ids);
|
||||
|
||||
|
|
|
@ -612,7 +612,7 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
|
|||
|
||||
static int
|
||||
acpi_video_device_EDID(struct acpi_video_device *device,
|
||||
union acpi_object **edid, ssize_t length)
|
||||
union acpi_object **edid, int length)
|
||||
{
|
||||
int status;
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
|
@ -625,13 +625,11 @@ acpi_video_device_EDID(struct acpi_video_device *device,
|
|||
|
||||
if (!device)
|
||||
return -ENODEV;
|
||||
if (length == 128)
|
||||
arg0.integer.value = 1;
|
||||
else if (length == 256)
|
||||
arg0.integer.value = 2;
|
||||
else
|
||||
if (!length || (length % 128))
|
||||
return -EINVAL;
|
||||
|
||||
arg0.integer.value = length / 128;
|
||||
|
||||
status = acpi_evaluate_object(device->dev->handle, "_DDC", &args, &buffer);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
|
@ -641,7 +639,8 @@ acpi_video_device_EDID(struct acpi_video_device *device,
|
|||
if (obj && obj->type == ACPI_TYPE_BUFFER)
|
||||
*edid = obj;
|
||||
else {
|
||||
acpi_handle_info(device->dev->handle, "Invalid _DDC data\n");
|
||||
acpi_handle_debug(device->dev->handle,
|
||||
"Invalid _DDC data for length %d\n", length);
|
||||
status = -EFAULT;
|
||||
kfree(obj);
|
||||
}
|
||||
|
@ -1447,7 +1446,6 @@ int acpi_video_get_edid(struct acpi_device *device, int type, int device_id,
|
|||
|
||||
for (i = 0; i < video->attached_count; i++) {
|
||||
video_device = video->attached_array[i].bind_info;
|
||||
length = 256;
|
||||
|
||||
if (!video_device)
|
||||
continue;
|
||||
|
@ -1478,18 +1476,14 @@ int acpi_video_get_edid(struct acpi_device *device, int type, int device_id,
|
|||
continue;
|
||||
}
|
||||
|
||||
status = acpi_video_device_EDID(video_device, &buffer, length);
|
||||
|
||||
if (ACPI_FAILURE(status) || !buffer ||
|
||||
buffer->type != ACPI_TYPE_BUFFER) {
|
||||
length = 128;
|
||||
for (length = 512; length > 0; length -= 128) {
|
||||
status = acpi_video_device_EDID(video_device, &buffer,
|
||||
length);
|
||||
if (ACPI_FAILURE(status) || !buffer ||
|
||||
buffer->type != ACPI_TYPE_BUFFER) {
|
||||
continue;
|
||||
}
|
||||
if (ACPI_SUCCESS(status))
|
||||
break;
|
||||
}
|
||||
if (!length)
|
||||
continue;
|
||||
|
||||
*edid = buffer->buffer.pointer;
|
||||
return length;
|
||||
|
|
|
@ -179,7 +179,7 @@ void __init acpi_watchdog_init(void)
|
|||
pdev = platform_device_register_simple("wdat_wdt", PLATFORM_DEVID_NONE,
|
||||
resources, nresources);
|
||||
if (IS_ERR(pdev))
|
||||
pr_err("Device creation failed: %ld\n", PTR_ERR(pdev));
|
||||
pr_err("Device creation failed: %pe\n", pdev);
|
||||
|
||||
kfree(resources);
|
||||
|
||||
|
|
|
@ -1455,7 +1455,7 @@ static int ghes_probe(struct platform_device *ghes_dev)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int ghes_remove(struct platform_device *ghes_dev)
|
||||
static void ghes_remove(struct platform_device *ghes_dev)
|
||||
{
|
||||
int rc;
|
||||
struct ghes *ghes;
|
||||
|
@ -1492,8 +1492,15 @@ static int ghes_remove(struct platform_device *ghes_dev)
|
|||
break;
|
||||
case ACPI_HEST_NOTIFY_SOFTWARE_DELEGATED:
|
||||
rc = apei_sdei_unregister_ghes(ghes);
|
||||
if (rc)
|
||||
return rc;
|
||||
if (rc) {
|
||||
/*
|
||||
* Returning early results in a resource leak, but we're
|
||||
* only here if stopping the hardware failed.
|
||||
*/
|
||||
dev_err(&ghes_dev->dev, "Failed to unregister ghes (%pe)\n",
|
||||
ERR_PTR(rc));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
|
@ -1507,8 +1514,6 @@ static int ghes_remove(struct platform_device *ghes_dev)
|
|||
mutex_unlock(&ghes_devs_mutex);
|
||||
|
||||
kfree(ghes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver ghes_platform_driver = {
|
||||
|
@ -1516,7 +1521,7 @@ static struct platform_driver ghes_platform_driver = {
|
|||
.name = "GHES",
|
||||
},
|
||||
.probe = ghes_probe,
|
||||
.remove = ghes_remove,
|
||||
.remove_new = ghes_remove,
|
||||
};
|
||||
|
||||
void __init acpi_ghes_init(void)
|
||||
|
|
|
@ -37,6 +37,20 @@ EXPORT_SYMBOL_GPL(hest_disable);
|
|||
|
||||
static struct acpi_table_hest *__read_mostly hest_tab;
|
||||
|
||||
/*
|
||||
* Since GHES_ASSIST is not supported, skip initialization of GHES_ASSIST
|
||||
* structures for MCA.
|
||||
* During HEST parsing, detected MCA error sources are cached from early
|
||||
* table entries so that the Flags and Source Id fields from these cached
|
||||
* values are then referred to in later table entries to determine if the
|
||||
* encountered GHES_ASSIST structure should be initialized.
|
||||
*/
|
||||
static struct {
|
||||
struct acpi_hest_ia_corrected *cmc;
|
||||
struct acpi_hest_ia_machine_check *mc;
|
||||
struct acpi_hest_ia_deferred_check *dmc;
|
||||
} mces;
|
||||
|
||||
static const int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = {
|
||||
[ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */
|
||||
[ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1,
|
||||
|
@ -70,22 +84,54 @@ static int hest_esrc_len(struct acpi_hest_header *hest_hdr)
|
|||
cmc = (struct acpi_hest_ia_corrected *)hest_hdr;
|
||||
len = sizeof(*cmc) + cmc->num_hardware_banks *
|
||||
sizeof(struct acpi_hest_ia_error_bank);
|
||||
mces.cmc = cmc;
|
||||
} else if (hest_type == ACPI_HEST_TYPE_IA32_CHECK) {
|
||||
struct acpi_hest_ia_machine_check *mc;
|
||||
mc = (struct acpi_hest_ia_machine_check *)hest_hdr;
|
||||
len = sizeof(*mc) + mc->num_hardware_banks *
|
||||
sizeof(struct acpi_hest_ia_error_bank);
|
||||
mces.mc = mc;
|
||||
} else if (hest_type == ACPI_HEST_TYPE_IA32_DEFERRED_CHECK) {
|
||||
struct acpi_hest_ia_deferred_check *mc;
|
||||
mc = (struct acpi_hest_ia_deferred_check *)hest_hdr;
|
||||
len = sizeof(*mc) + mc->num_hardware_banks *
|
||||
sizeof(struct acpi_hest_ia_error_bank);
|
||||
mces.dmc = mc;
|
||||
}
|
||||
BUG_ON(len == -1);
|
||||
|
||||
return len;
|
||||
};
|
||||
|
||||
/*
|
||||
* GHES and GHESv2 structures share the same format, starting from
|
||||
* Source Id and ending in Error Status Block Length (inclusive).
|
||||
*/
|
||||
static bool is_ghes_assist_struct(struct acpi_hest_header *hest_hdr)
|
||||
{
|
||||
struct acpi_hest_generic *ghes;
|
||||
u16 related_source_id;
|
||||
|
||||
if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR &&
|
||||
hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR_V2)
|
||||
return false;
|
||||
|
||||
ghes = (struct acpi_hest_generic *)hest_hdr;
|
||||
related_source_id = ghes->related_source_id;
|
||||
|
||||
if (mces.cmc && mces.cmc->flags & ACPI_HEST_GHES_ASSIST &&
|
||||
related_source_id == mces.cmc->header.source_id)
|
||||
return true;
|
||||
if (mces.mc && mces.mc->flags & ACPI_HEST_GHES_ASSIST &&
|
||||
related_source_id == mces.mc->header.source_id)
|
||||
return true;
|
||||
if (mces.dmc && mces.dmc->flags & ACPI_HEST_GHES_ASSIST &&
|
||||
related_source_id == mces.dmc->header.source_id)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef int (*apei_hest_func_t)(struct acpi_hest_header *hest_hdr, void *data);
|
||||
|
||||
static int apei_hest_parse(apei_hest_func_t func, void *data)
|
||||
|
@ -114,6 +160,11 @@ static int apei_hest_parse(apei_hest_func_t func, void *data)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (is_ghes_assist_struct(hest_hdr)) {
|
||||
hest_hdr = (void *)hest_hdr + len;
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = func(hest_hdr, data);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
|
|
@ -58,7 +58,7 @@ static int agdi_probe(struct platform_device *pdev)
|
|||
return agdi_sdei_probe(pdev, adata);
|
||||
}
|
||||
|
||||
static int agdi_remove(struct platform_device *pdev)
|
||||
static void agdi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct agdi_data *adata = dev_get_platdata(&pdev->dev);
|
||||
int err, i;
|
||||
|
@ -67,7 +67,7 @@ static int agdi_remove(struct platform_device *pdev)
|
|||
if (err) {
|
||||
dev_err(&pdev->dev, "Failed to disable sdei-event #%d (%pe)\n",
|
||||
adata->sdei_event, ERR_PTR(err));
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
|
@ -81,8 +81,6 @@ static int agdi_remove(struct platform_device *pdev)
|
|||
if (err)
|
||||
dev_err(&pdev->dev, "Failed to unregister sdei-event #%d (%pe)\n",
|
||||
adata->sdei_event, ERR_PTR(err));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver agdi_driver = {
|
||||
|
@ -90,7 +88,7 @@ static struct platform_driver agdi_driver = {
|
|||
.name = "agdi",
|
||||
},
|
||||
.probe = agdi_probe,
|
||||
.remove = agdi_remove,
|
||||
.remove_new = agdi_remove,
|
||||
};
|
||||
|
||||
void __init acpi_agdi_init(void)
|
||||
|
|
|
@ -1,103 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* custom_method.c - debugfs interface for customizing ACPI control method
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/security.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static struct dentry *cm_dentry;
|
||||
|
||||
/* /sys/kernel/debug/acpi/custom_method */
|
||||
|
||||
static ssize_t cm_write(struct file *file, const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
static char *buf;
|
||||
static u32 max_size;
|
||||
static u32 uncopied_bytes;
|
||||
|
||||
struct acpi_table_header table;
|
||||
acpi_status status;
|
||||
int ret;
|
||||
|
||||
ret = security_locked_down(LOCKDOWN_ACPI_TABLES);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!(*ppos)) {
|
||||
/* parse the table header to get the table length */
|
||||
if (count <= sizeof(struct acpi_table_header))
|
||||
return -EINVAL;
|
||||
if (copy_from_user(&table, user_buf,
|
||||
sizeof(struct acpi_table_header)))
|
||||
return -EFAULT;
|
||||
uncopied_bytes = max_size = table.length;
|
||||
/* make sure the buf is not allocated */
|
||||
kfree(buf);
|
||||
buf = kzalloc(max_size, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (buf == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if ((*ppos > max_size) ||
|
||||
(*ppos + count > max_size) ||
|
||||
(*ppos + count < count) ||
|
||||
(count > uncopied_bytes)) {
|
||||
kfree(buf);
|
||||
buf = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (copy_from_user(buf + (*ppos), user_buf, count)) {
|
||||
kfree(buf);
|
||||
buf = NULL;
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
uncopied_bytes -= count;
|
||||
*ppos += count;
|
||||
|
||||
if (!uncopied_bytes) {
|
||||
status = acpi_install_method(buf);
|
||||
kfree(buf);
|
||||
buf = NULL;
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EINVAL;
|
||||
add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations cm_fops = {
|
||||
.write = cm_write,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static int __init acpi_custom_method_init(void)
|
||||
{
|
||||
cm_dentry = debugfs_create_file("custom_method", S_IWUSR,
|
||||
acpi_debugfs_dir, NULL, &cm_fops);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit acpi_custom_method_exit(void)
|
||||
{
|
||||
debugfs_remove(cm_dentry);
|
||||
}
|
||||
|
||||
module_init(acpi_custom_method_init);
|
||||
module_exit(acpi_custom_method_exit);
|
|
@ -141,11 +141,9 @@ static int pch_fivr_add(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int pch_fivr_remove(struct platform_device *pdev)
|
||||
static void pch_fivr_remove(struct platform_device *pdev)
|
||||
{
|
||||
sysfs_remove_group(&pdev->dev.kobj, &pch_fivr_attribute_group);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct acpi_device_id pch_fivr_device_ids[] = {
|
||||
|
@ -159,7 +157,7 @@ MODULE_DEVICE_TABLE(acpi, pch_fivr_device_ids);
|
|||
|
||||
static struct platform_driver pch_fivr_driver = {
|
||||
.probe = pch_fivr_add,
|
||||
.remove = pch_fivr_remove,
|
||||
.remove_new = pch_fivr_remove,
|
||||
.driver = {
|
||||
.name = "dptf_pch_fivr",
|
||||
.acpi_match_table = pch_fivr_device_ids,
|
||||
|
|
|
@ -209,7 +209,7 @@ static int dptf_power_add(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int dptf_power_remove(struct platform_device *pdev)
|
||||
static void dptf_power_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct acpi_device *acpi_dev = platform_get_drvdata(pdev);
|
||||
|
||||
|
@ -221,8 +221,6 @@ static int dptf_power_remove(struct platform_device *pdev)
|
|||
sysfs_remove_group(&pdev->dev.kobj, &dptf_battery_attribute_group);
|
||||
else
|
||||
sysfs_remove_group(&pdev->dev.kobj, &dptf_power_attribute_group);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct acpi_device_id int3407_device_ids[] = {
|
||||
|
@ -242,7 +240,7 @@ MODULE_DEVICE_TABLE(acpi, int3407_device_ids);
|
|||
|
||||
static struct platform_driver dptf_power_driver = {
|
||||
.probe = dptf_power_add,
|
||||
.remove = dptf_power_remove,
|
||||
.remove_new = dptf_power_remove,
|
||||
.driver = {
|
||||
.name = "dptf_power",
|
||||
.acpi_match_table = int3407_device_ids,
|
||||
|
|
|
@ -173,10 +173,9 @@ static void ged_shutdown(struct platform_device *pdev)
|
|||
}
|
||||
}
|
||||
|
||||
static int ged_remove(struct platform_device *pdev)
|
||||
static void ged_remove(struct platform_device *pdev)
|
||||
{
|
||||
ged_shutdown(pdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct acpi_device_id ged_acpi_ids[] = {
|
||||
|
@ -186,7 +185,7 @@ static const struct acpi_device_id ged_acpi_ids[] = {
|
|||
|
||||
static struct platform_driver ged_driver = {
|
||||
.probe = ged_probe,
|
||||
.remove = ged_remove,
|
||||
.remove_new = ged_remove,
|
||||
.shutdown = ged_shutdown,
|
||||
.driver = {
|
||||
.name = MODULE_NAME,
|
||||
|
|
|
@ -387,7 +387,7 @@ static int acpi_fan_probe(struct platform_device *pdev)
|
|||
return result;
|
||||
}
|
||||
|
||||
static int acpi_fan_remove(struct platform_device *pdev)
|
||||
static void acpi_fan_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct acpi_fan *fan = platform_get_drvdata(pdev);
|
||||
|
||||
|
@ -399,8 +399,6 @@ static int acpi_fan_remove(struct platform_device *pdev)
|
|||
sysfs_remove_link(&pdev->dev.kobj, "thermal_cooling");
|
||||
sysfs_remove_link(&fan->cdev->device.kobj, "device");
|
||||
thermal_cooling_device_unregister(fan->cdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
@ -446,7 +444,7 @@ static const struct dev_pm_ops acpi_fan_pm = {
|
|||
|
||||
static struct platform_driver acpi_fan_driver = {
|
||||
.probe = acpi_fan_probe,
|
||||
.remove = acpi_fan_remove,
|
||||
.remove_new = acpi_fan_remove,
|
||||
.driver = {
|
||||
.name = "acpi-fan",
|
||||
.acpi_match_table = fan_device_ids,
|
||||
|
|
|
@ -111,7 +111,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
|
|||
snprintf(name, sizeof(name), "%llu", sun);
|
||||
pci_slot = pci_create_slot(pci_bus, device, name, NULL);
|
||||
if (IS_ERR(pci_slot)) {
|
||||
pr_err("pci_create_slot returned %ld\n", PTR_ERR(pci_slot));
|
||||
pr_err("pci_create_slot returned %pe\n", pci_slot);
|
||||
kfree(slot);
|
||||
return AE_OK;
|
||||
}
|
||||
|
|
|
@ -347,13 +347,11 @@ static const struct file_operations acpi_pfrt_log_fops = {
|
|||
.llseek = noop_llseek,
|
||||
};
|
||||
|
||||
static int acpi_pfrt_log_remove(struct platform_device *pdev)
|
||||
static void acpi_pfrt_log_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct pfrt_log_device *pfrt_log_dev = platform_get_drvdata(pdev);
|
||||
|
||||
misc_deregister(&pfrt_log_dev->miscdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pfrt_log_put_idx(void *data)
|
||||
|
@ -427,7 +425,7 @@ static struct platform_driver acpi_pfrt_log_driver = {
|
|||
.acpi_match_table = acpi_pfrt_log_ids,
|
||||
},
|
||||
.probe = acpi_pfrt_log_probe,
|
||||
.remove = acpi_pfrt_log_remove,
|
||||
.remove_new = acpi_pfrt_log_remove,
|
||||
};
|
||||
module_platform_driver(acpi_pfrt_log_driver);
|
||||
|
||||
|
|
|
@ -489,13 +489,11 @@ static const struct file_operations acpi_pfru_fops = {
|
|||
.llseek = noop_llseek,
|
||||
};
|
||||
|
||||
static int acpi_pfru_remove(struct platform_device *pdev)
|
||||
static void acpi_pfru_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct pfru_device *pfru_dev = platform_get_drvdata(pdev);
|
||||
|
||||
misc_deregister(&pfru_dev->miscdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pfru_put_idx(void *data)
|
||||
|
@ -567,7 +565,7 @@ static struct platform_driver acpi_pfru_driver = {
|
|||
.acpi_match_table = acpi_pfru_ids,
|
||||
},
|
||||
.probe = acpi_pfru_probe,
|
||||
.remove = acpi_pfru_remove,
|
||||
.remove_new = acpi_pfru_remove,
|
||||
};
|
||||
module_platform_driver(acpi_pfru_driver);
|
||||
|
||||
|
|
|
@ -428,7 +428,7 @@ bool acpi_quirk_skip_i2c_client_enumeration(struct acpi_device *adev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_quirk_skip_i2c_client_enumeration);
|
||||
|
||||
int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *skip)
|
||||
static int acpi_dmi_skip_serdev_enumeration(struct device *controller_parent, bool *skip)
|
||||
{
|
||||
struct acpi_device *adev = ACPI_COMPANION(controller_parent);
|
||||
const struct dmi_system_id *dmi_id;
|
||||
|
@ -436,8 +436,6 @@ int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *s
|
|||
u64 uid;
|
||||
int ret;
|
||||
|
||||
*skip = false;
|
||||
|
||||
ret = acpi_dev_uid_to_integer(adev, &uid);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
@ -463,7 +461,6 @@ int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *s
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_quirk_skip_serdev_enumeration);
|
||||
|
||||
bool acpi_quirk_skip_gpio_event_handlers(void)
|
||||
{
|
||||
|
@ -478,8 +475,41 @@ bool acpi_quirk_skip_gpio_event_handlers(void)
|
|||
return (quirks & ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_quirk_skip_gpio_event_handlers);
|
||||
#else
|
||||
static int acpi_dmi_skip_serdev_enumeration(struct device *controller_parent, bool *skip)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *skip)
|
||||
{
|
||||
struct acpi_device *adev = ACPI_COMPANION(controller_parent);
|
||||
|
||||
*skip = false;
|
||||
|
||||
/*
|
||||
* The DELL0501 ACPI HID represents an UART (CID is set to PNP0501) with
|
||||
* a backlight-controller attached. There is no separate ACPI device with
|
||||
* an UartSerialBusV2() resource to model the backlight-controller.
|
||||
* Set skip to true so that the tty core creates a serdev ctrl device.
|
||||
* The backlight driver will manually create the serdev client device.
|
||||
*/
|
||||
if (acpi_dev_hid_match(adev, "DELL0501")) {
|
||||
*skip = true;
|
||||
/*
|
||||
* Create a platform dev for dell-uart-backlight to bind to.
|
||||
* This is a static device, so no need to store the result.
|
||||
*/
|
||||
platform_device_register_simple("dell-uart-backlight", PLATFORM_DEVID_NONE,
|
||||
NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return acpi_dmi_skip_serdev_enumeration(controller_parent, skip);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_quirk_skip_serdev_enumeration);
|
||||
|
||||
/* Lists of PMIC ACPI HIDs with an (often better) native charger driver */
|
||||
static const struct {
|
||||
const char *hid;
|
||||
|
|
|
@ -749,6 +749,7 @@ bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *s
|
|||
bool acpi_quirk_skip_acpi_ac_and_battery(void);
|
||||
int acpi_install_cmos_rtc_space_handler(acpi_handle handle);
|
||||
void acpi_remove_cmos_rtc_space_handler(acpi_handle handle);
|
||||
int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *skip);
|
||||
#else
|
||||
static inline bool acpi_device_override_status(struct acpi_device *adev,
|
||||
unsigned long long *status)
|
||||
|
@ -766,23 +767,22 @@ static inline int acpi_install_cmos_rtc_space_handler(acpi_handle handle)
|
|||
static inline void acpi_remove_cmos_rtc_space_handler(acpi_handle handle)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_X86_ANDROID_TABLETS)
|
||||
bool acpi_quirk_skip_i2c_client_enumeration(struct acpi_device *adev);
|
||||
int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *skip);
|
||||
bool acpi_quirk_skip_gpio_event_handlers(void);
|
||||
#else
|
||||
static inline bool acpi_quirk_skip_i2c_client_enumeration(struct acpi_device *adev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline int
|
||||
acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *skip)
|
||||
{
|
||||
*skip = false;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_X86_ANDROID_TABLETS)
|
||||
bool acpi_quirk_skip_i2c_client_enumeration(struct acpi_device *adev);
|
||||
bool acpi_quirk_skip_gpio_event_handlers(void);
|
||||
#else
|
||||
static inline bool acpi_quirk_skip_i2c_client_enumeration(struct acpi_device *adev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline bool acpi_quirk_skip_gpio_event_handlers(void)
|
||||
{
|
||||
return false;
|
||||
|
|
Loading…
Reference in a new issue