mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 19:51:31 -04:00
Merge branches 'release' and 'dsdt-override' into release
This commit is contained in:
commit
81e242d0ef
9 changed files with 187 additions and 9 deletions
|
|
@ -276,8 +276,10 @@ config ACPI_CUSTOM_DSDT
|
|||
depends on !STANDALONE
|
||||
default n
|
||||
help
|
||||
This option is to load a custom ACPI DSDT
|
||||
If you don't know what that is, say N.
|
||||
This option supports a custom DSDT by linking it into the kernel.
|
||||
See Documentation/acpi/dsdt-override.txt
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config ACPI_CUSTOM_DSDT_FILE
|
||||
string "Custom DSDT Table file to include"
|
||||
|
|
@ -287,6 +289,17 @@ config ACPI_CUSTOM_DSDT_FILE
|
|||
Enter the full path name to the file which includes the AmlCode
|
||||
declaration.
|
||||
|
||||
config ACPI_CUSTOM_DSDT_INITRD
|
||||
bool "Read Custom DSDT from initramfs"
|
||||
depends on BLK_DEV_INITRD
|
||||
default n
|
||||
help
|
||||
This option supports a custom DSDT by optionally loading it from initrd.
|
||||
See Documentation/acpi/dsdt-override.txt
|
||||
|
||||
If you are not using this feature now, but may use it later,
|
||||
it is safe to say Y here.
|
||||
|
||||
config ACPI_BLACKLIST_YEAR
|
||||
int "Disable ACPI for systems before Jan 1st this year" if X86_32
|
||||
default 0
|
||||
|
|
|
|||
|
|
@ -91,6 +91,10 @@ static DEFINE_SPINLOCK(acpi_res_lock);
|
|||
#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
|
||||
static char osi_additional_string[OSI_STRING_LENGTH_MAX];
|
||||
|
||||
#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
|
||||
static int acpi_no_initrd_override;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* "Ode to _OSI(Linux)"
|
||||
*
|
||||
|
|
@ -329,6 +333,67 @@ acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
|
|||
return AE_OK;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
|
||||
struct acpi_table_header *acpi_find_dsdt_initrd(void)
|
||||
{
|
||||
struct file *firmware_file;
|
||||
mm_segment_t oldfs;
|
||||
unsigned long len, len2;
|
||||
struct acpi_table_header *dsdt_buffer, *ret = NULL;
|
||||
struct kstat stat;
|
||||
char *ramfs_dsdt_name = "/DSDT.aml";
|
||||
|
||||
printk(KERN_INFO PREFIX "Checking initramfs for custom DSDT");
|
||||
|
||||
/*
|
||||
* Never do this at home, only the user-space is allowed to open a file.
|
||||
* The clean way would be to use the firmware loader.
|
||||
* But this code must be run before there is any userspace available.
|
||||
* A static/init firmware infrastructure doesn't exist yet...
|
||||
*/
|
||||
if (vfs_stat(ramfs_dsdt_name, &stat) < 0)
|
||||
return ret;
|
||||
|
||||
len = stat.size;
|
||||
/* check especially against empty files */
|
||||
if (len <= 4) {
|
||||
printk(KERN_ERR PREFIX "Failed: DSDT only %lu bytes.\n", len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
firmware_file = filp_open(ramfs_dsdt_name, O_RDONLY, 0);
|
||||
if (IS_ERR(firmware_file)) {
|
||||
printk(KERN_ERR PREFIX "Failed to open %s.\n", ramfs_dsdt_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dsdt_buffer = kmalloc(len, GFP_ATOMIC);
|
||||
if (!dsdt_buffer) {
|
||||
printk(KERN_ERR PREFIX "Failed to allocate %lu bytes.\n", len);
|
||||
goto err;
|
||||
}
|
||||
|
||||
oldfs = get_fs();
|
||||
set_fs(KERNEL_DS);
|
||||
len2 = vfs_read(firmware_file, (char __user *)dsdt_buffer, len,
|
||||
&firmware_file->f_pos);
|
||||
set_fs(oldfs);
|
||||
if (len2 < len) {
|
||||
printk(KERN_ERR PREFIX "Failed to read %lu bytes from %s.\n",
|
||||
len, ramfs_dsdt_name);
|
||||
ACPI_FREE(dsdt_buffer);
|
||||
goto err;
|
||||
}
|
||||
|
||||
printk(KERN_INFO PREFIX "Found %lu byte DSDT in %s.\n",
|
||||
len, ramfs_dsdt_name);
|
||||
ret = dsdt_buffer;
|
||||
err:
|
||||
filp_close(firmware_file, NULL);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
acpi_status
|
||||
acpi_os_table_override(struct acpi_table_header * existing_table,
|
||||
struct acpi_table_header ** new_table)
|
||||
|
|
@ -336,17 +401,41 @@ acpi_os_table_override(struct acpi_table_header * existing_table,
|
|||
if (!existing_table || !new_table)
|
||||
return AE_BAD_PARAMETER;
|
||||
|
||||
*new_table = NULL;
|
||||
|
||||
#ifdef CONFIG_ACPI_CUSTOM_DSDT
|
||||
if (strncmp(existing_table->signature, "DSDT", 4) == 0)
|
||||
*new_table = (struct acpi_table_header *)AmlCode;
|
||||
else
|
||||
*new_table = NULL;
|
||||
#else
|
||||
*new_table = NULL;
|
||||
#endif
|
||||
#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
|
||||
if ((strncmp(existing_table->signature, "DSDT", 4) == 0) &&
|
||||
!acpi_no_initrd_override) {
|
||||
struct acpi_table_header *initrd_table;
|
||||
|
||||
initrd_table = acpi_find_dsdt_initrd();
|
||||
if (initrd_table)
|
||||
*new_table = initrd_table;
|
||||
}
|
||||
#endif
|
||||
if (*new_table != NULL) {
|
||||
printk(KERN_WARNING PREFIX "Override [%4.4s-%8.8s], "
|
||||
"this is unsafe: tainting kernel\n",
|
||||
existing_table->signature,
|
||||
existing_table->oem_table_id);
|
||||
add_taint(TAINT_OVERRIDDEN_ACPI_TABLE);
|
||||
}
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
|
||||
int __init acpi_no_initrd_override_setup(char *s)
|
||||
{
|
||||
acpi_no_initrd_override = 1;
|
||||
return 1;
|
||||
}
|
||||
__setup("acpi_no_initrd_override", acpi_no_initrd_override_setup);
|
||||
#endif
|
||||
|
||||
static irqreturn_t acpi_irq(int irq, void *dev_id)
|
||||
{
|
||||
u32 handled;
|
||||
|
|
|
|||
Loading…
Reference in a new issue