Merge branch 'acpi-assorted'
* acpi-assorted: ACPI / EC: Add HP Folio 13 to ec_dmi_table in order to skip DSDT scan ACPI: Add CMOS RTC Operation Region handler support ACPI: Remove unused flags in acpi_device_flags ACPI: Remove useless initializers ACPI / battery: Make sure all spaces are in correct places ACPI: add _STA evaluation at do_acpi_find_child() ACPI / EC: access user space with get_user()/put_user()
This commit is contained in:
Коммит
bdc8f09685
|
@ -44,6 +44,7 @@ acpi-y += acpi_platform.o
|
||||||
acpi-y += power.o
|
acpi-y += power.o
|
||||||
acpi-y += event.o
|
acpi-y += event.o
|
||||||
acpi-y += sysfs.o
|
acpi-y += sysfs.o
|
||||||
|
acpi-$(CONFIG_X86) += acpi_cmos_rtc.o
|
||||||
acpi-$(CONFIG_DEBUG_FS) += debugfs.o
|
acpi-$(CONFIG_DEBUG_FS) += debugfs.o
|
||||||
acpi-$(CONFIG_ACPI_NUMA) += numa.o
|
acpi-$(CONFIG_ACPI_NUMA) += numa.o
|
||||||
acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
|
acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
* ACPI support for CMOS RTC Address Space access
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013, Intel Corporation
|
||||||
|
* Authors: Lan Tianyu <tianyu.lan@intel.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/acpi.h>
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <asm-generic/rtc.h>
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#define PREFIX "ACPI: "
|
||||||
|
|
||||||
|
ACPI_MODULE_NAME("cmos rtc");
|
||||||
|
|
||||||
|
static const struct acpi_device_id acpi_cmos_rtc_ids[] = {
|
||||||
|
{ "PNP0B00" },
|
||||||
|
{ "PNP0B01" },
|
||||||
|
{ "PNP0B02" },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static acpi_status
|
||||||
|
acpi_cmos_rtc_space_handler(u32 function, acpi_physical_address address,
|
||||||
|
u32 bits, u64 *value64,
|
||||||
|
void *handler_context, void *region_context)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
u8 *value = (u8 *)&value64;
|
||||||
|
|
||||||
|
if (address > 0xff || !value64)
|
||||||
|
return AE_BAD_PARAMETER;
|
||||||
|
|
||||||
|
if (function != ACPI_WRITE && function != ACPI_READ)
|
||||||
|
return AE_BAD_PARAMETER;
|
||||||
|
|
||||||
|
spin_lock_irq(&rtc_lock);
|
||||||
|
|
||||||
|
for (i = 0; i < DIV_ROUND_UP(bits, 8); ++i, ++address, ++value)
|
||||||
|
if (function == ACPI_READ)
|
||||||
|
*value = CMOS_READ(address);
|
||||||
|
else
|
||||||
|
CMOS_WRITE(*value, address);
|
||||||
|
|
||||||
|
spin_unlock_irq(&rtc_lock);
|
||||||
|
|
||||||
|
return AE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int acpi_install_cmos_rtc_space_handler(struct acpi_device *adev,
|
||||||
|
const struct acpi_device_id *id)
|
||||||
|
{
|
||||||
|
acpi_status status;
|
||||||
|
|
||||||
|
status = acpi_install_address_space_handler(adev->handle,
|
||||||
|
ACPI_ADR_SPACE_CMOS,
|
||||||
|
&acpi_cmos_rtc_space_handler,
|
||||||
|
NULL, NULL);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
pr_err(PREFIX "Error installing CMOS-RTC region handler\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void acpi_remove_cmos_rtc_space_handler(struct acpi_device *adev)
|
||||||
|
{
|
||||||
|
if (ACPI_FAILURE(acpi_remove_address_space_handler(adev->handle,
|
||||||
|
ACPI_ADR_SPACE_CMOS, &acpi_cmos_rtc_space_handler)))
|
||||||
|
pr_err(PREFIX "Error removing CMOS-RTC region handler\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct acpi_scan_handler cmos_rtc_handler = {
|
||||||
|
.ids = acpi_cmos_rtc_ids,
|
||||||
|
.attach = acpi_install_cmos_rtc_space_handler,
|
||||||
|
.detach = acpi_remove_cmos_rtc_space_handler,
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init acpi_cmos_rtc_init(void)
|
||||||
|
{
|
||||||
|
acpi_scan_add_handler(&cmos_rtc_handler);
|
||||||
|
}
|
|
@ -425,7 +425,7 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
|
||||||
{
|
{
|
||||||
int result = -EFAULT;
|
int result = -EFAULT;
|
||||||
acpi_status status = 0;
|
acpi_status status = 0;
|
||||||
char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags)?
|
char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags) ?
|
||||||
"_BIX" : "_BIF";
|
"_BIX" : "_BIF";
|
||||||
|
|
||||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||||
|
@ -661,11 +661,11 @@ static void find_battery(const struct dmi_header *dm, void *private)
|
||||||
static void acpi_battery_quirks(struct acpi_battery *battery)
|
static void acpi_battery_quirks(struct acpi_battery *battery)
|
||||||
{
|
{
|
||||||
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
|
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
|
||||||
return ;
|
return;
|
||||||
|
|
||||||
if (battery->full_charge_capacity == 100 &&
|
if (battery->full_charge_capacity == 100 &&
|
||||||
battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
|
battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
|
||||||
battery->capacity_now >=0 && battery->capacity_now <= 100) {
|
battery->capacity_now >= 0 && battery->capacity_now <= 100) {
|
||||||
set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags);
|
set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags);
|
||||||
battery->full_charge_capacity = battery->design_capacity;
|
battery->full_charge_capacity = battery->design_capacity;
|
||||||
battery->capacity_now = (battery->capacity_now *
|
battery->capacity_now = (battery->capacity_now *
|
||||||
|
@ -673,7 +673,7 @@ static void acpi_battery_quirks(struct acpi_battery *battery)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags))
|
if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags))
|
||||||
return ;
|
return;
|
||||||
|
|
||||||
if (battery->power_unit && dmi_name_in_vendors("LENOVO")) {
|
if (battery->power_unit && dmi_name_in_vendors("LENOVO")) {
|
||||||
const char *s;
|
const char *s;
|
||||||
|
@ -761,7 +761,7 @@ static int acpi_battery_print_info(struct seq_file *seq, int result)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
seq_printf(seq, "present: %s\n",
|
seq_printf(seq, "present: %s\n",
|
||||||
acpi_battery_present(battery)?"yes":"no");
|
acpi_battery_present(battery) ? "yes" : "no");
|
||||||
if (!acpi_battery_present(battery))
|
if (!acpi_battery_present(battery))
|
||||||
goto end;
|
goto end;
|
||||||
if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
|
if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
|
||||||
|
@ -817,12 +817,12 @@ static int acpi_battery_print_state(struct seq_file *seq, int result)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
seq_printf(seq, "present: %s\n",
|
seq_printf(seq, "present: %s\n",
|
||||||
acpi_battery_present(battery)?"yes":"no");
|
acpi_battery_present(battery) ? "yes" : "no");
|
||||||
if (!acpi_battery_present(battery))
|
if (!acpi_battery_present(battery))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
seq_printf(seq, "capacity state: %s\n",
|
seq_printf(seq, "capacity state: %s\n",
|
||||||
(battery->state & 0x04)?"critical":"ok");
|
(battery->state & 0x04) ? "critical" : "ok");
|
||||||
if ((battery->state & 0x01) && (battery->state & 0x02))
|
if ((battery->state & 0x01) && (battery->state & 0x02))
|
||||||
seq_printf(seq,
|
seq_printf(seq,
|
||||||
"charging state: charging/discharging\n");
|
"charging state: charging/discharging\n");
|
||||||
|
|
|
@ -91,8 +91,7 @@ static struct dmi_system_id dsdt_dmi_table[] __initdata = {
|
||||||
|
|
||||||
int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device)
|
int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device)
|
||||||
{
|
{
|
||||||
acpi_status status = AE_OK;
|
acpi_status status;
|
||||||
|
|
||||||
|
|
||||||
if (!device)
|
if (!device)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -162,7 +161,7 @@ EXPORT_SYMBOL(acpi_bus_private_data_handler);
|
||||||
|
|
||||||
int acpi_bus_get_private_data(acpi_handle handle, void **data)
|
int acpi_bus_get_private_data(acpi_handle handle, void **data)
|
||||||
{
|
{
|
||||||
acpi_status status = AE_OK;
|
acpi_status status;
|
||||||
|
|
||||||
if (!*data)
|
if (!*data)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -361,7 +360,7 @@ extern int event_is_open;
|
||||||
int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id, u8 type, int data)
|
int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id, u8 type, int data)
|
||||||
{
|
{
|
||||||
struct acpi_bus_event *event;
|
struct acpi_bus_event *event;
|
||||||
unsigned long flags = 0;
|
unsigned long flags;
|
||||||
|
|
||||||
/* drop event on the floor if no one's listening */
|
/* drop event on the floor if no one's listening */
|
||||||
if (!event_is_open)
|
if (!event_is_open)
|
||||||
|
@ -400,7 +399,7 @@ EXPORT_SYMBOL(acpi_bus_generate_proc_event);
|
||||||
|
|
||||||
int acpi_bus_receive_event(struct acpi_bus_event *event)
|
int acpi_bus_receive_event(struct acpi_bus_event *event)
|
||||||
{
|
{
|
||||||
unsigned long flags = 0;
|
unsigned long flags;
|
||||||
struct acpi_bus_event *entry = NULL;
|
struct acpi_bus_event *entry = NULL;
|
||||||
|
|
||||||
DECLARE_WAITQUEUE(wait, current);
|
DECLARE_WAITQUEUE(wait, current);
|
||||||
|
@ -593,7 +592,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
|
||||||
|
|
||||||
static int __init acpi_bus_init_irq(void)
|
static int __init acpi_bus_init_irq(void)
|
||||||
{
|
{
|
||||||
acpi_status status = AE_OK;
|
acpi_status status;
|
||||||
union acpi_object arg = { ACPI_TYPE_INTEGER };
|
union acpi_object arg = { ACPI_TYPE_INTEGER };
|
||||||
struct acpi_object_list arg_list = { 1, &arg };
|
struct acpi_object_list arg_list = { 1, &arg };
|
||||||
char *message = NULL;
|
char *message = NULL;
|
||||||
|
@ -640,7 +639,7 @@ u8 acpi_gbl_permanent_mmap;
|
||||||
|
|
||||||
void __init acpi_early_init(void)
|
void __init acpi_early_init(void)
|
||||||
{
|
{
|
||||||
acpi_status status = AE_OK;
|
acpi_status status;
|
||||||
|
|
||||||
if (acpi_disabled)
|
if (acpi_disabled)
|
||||||
return;
|
return;
|
||||||
|
@ -714,8 +713,8 @@ void __init acpi_early_init(void)
|
||||||
|
|
||||||
static int __init acpi_bus_init(void)
|
static int __init acpi_bus_init(void)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result;
|
||||||
acpi_status status = AE_OK;
|
acpi_status status;
|
||||||
extern acpi_status acpi_os_initialize1(void);
|
extern acpi_status acpi_os_initialize1(void);
|
||||||
|
|
||||||
acpi_os_initialize1();
|
acpi_os_initialize1();
|
||||||
|
|
|
@ -983,6 +983,10 @@ static struct dmi_system_id __initdata ec_dmi_table[] = {
|
||||||
ec_enlarge_storm_threshold, "CLEVO hardware", {
|
ec_enlarge_storm_threshold, "CLEVO hardware", {
|
||||||
DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."),
|
DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."),
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "M720T/M730T"),}, NULL},
|
DMI_MATCH(DMI_PRODUCT_NAME, "M720T/M730T"),}, NULL},
|
||||||
|
{
|
||||||
|
ec_skip_dsdt_scan, "HP Folio 13", {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13"),}, NULL},
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <linux/acpi.h>
|
#include <linux/acpi.h>
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/uaccess.h>
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>");
|
MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>");
|
||||||
|
@ -34,7 +35,6 @@ static ssize_t acpi_ec_read_io(struct file *f, char __user *buf,
|
||||||
* struct acpi_ec *ec = ((struct seq_file *)f->private_data)->private;
|
* struct acpi_ec *ec = ((struct seq_file *)f->private_data)->private;
|
||||||
*/
|
*/
|
||||||
unsigned int size = EC_SPACE_SIZE;
|
unsigned int size = EC_SPACE_SIZE;
|
||||||
u8 *data = (u8 *) buf;
|
|
||||||
loff_t init_off = *off;
|
loff_t init_off = *off;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
|
@ -47,9 +47,15 @@ static ssize_t acpi_ec_read_io(struct file *f, char __user *buf,
|
||||||
size = count;
|
size = count;
|
||||||
|
|
||||||
while (size) {
|
while (size) {
|
||||||
err = ec_read(*off, &data[*off - init_off]);
|
u8 byte_read;
|
||||||
|
err = ec_read(*off, &byte_read);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
if (put_user(byte_read, buf + *off - init_off)) {
|
||||||
|
if (*off - init_off)
|
||||||
|
return *off - init_off; /* partial read */
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
*off += 1;
|
*off += 1;
|
||||||
size--;
|
size--;
|
||||||
}
|
}
|
||||||
|
@ -65,7 +71,6 @@ static ssize_t acpi_ec_write_io(struct file *f, const char __user *buf,
|
||||||
|
|
||||||
unsigned int size = count;
|
unsigned int size = count;
|
||||||
loff_t init_off = *off;
|
loff_t init_off = *off;
|
||||||
u8 *data = (u8 *) buf;
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (*off >= EC_SPACE_SIZE)
|
if (*off >= EC_SPACE_SIZE)
|
||||||
|
@ -76,7 +81,12 @@ static ssize_t acpi_ec_write_io(struct file *f, const char __user *buf,
|
||||||
}
|
}
|
||||||
|
|
||||||
while (size) {
|
while (size) {
|
||||||
u8 byte_write = data[*off - init_off];
|
u8 byte_write;
|
||||||
|
if (get_user(byte_write, buf + *off - init_off)) {
|
||||||
|
if (*off - init_off)
|
||||||
|
return *off - init_off; /* partial write */
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
err = ec_write(*off, byte_write);
|
err = ec_write(*off, byte_write);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -81,13 +81,15 @@ static struct acpi_bus_type *acpi_get_bus_type(struct device *dev)
|
||||||
static acpi_status do_acpi_find_child(acpi_handle handle, u32 lvl_not_used,
|
static acpi_status do_acpi_find_child(acpi_handle handle, u32 lvl_not_used,
|
||||||
void *addr_p, void **ret_p)
|
void *addr_p, void **ret_p)
|
||||||
{
|
{
|
||||||
unsigned long long addr;
|
unsigned long long addr, sta;
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
|
|
||||||
status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr);
|
status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr);
|
||||||
if (ACPI_SUCCESS(status) && addr == *((u64 *)addr_p)) {
|
if (ACPI_SUCCESS(status) && addr == *((u64 *)addr_p)) {
|
||||||
*ret_p = handle;
|
*ret_p = handle;
|
||||||
return AE_CTRL_TERMINATE;
|
status = acpi_bus_get_status_handle(handle, &sta);
|
||||||
|
if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_ENABLED))
|
||||||
|
return AE_CTRL_TERMINATE;
|
||||||
}
|
}
|
||||||
return AE_OK;
|
return AE_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,11 @@ void acpi_memory_hotplug_init(void);
|
||||||
#else
|
#else
|
||||||
static inline void acpi_memory_hotplug_init(void) {}
|
static inline void acpi_memory_hotplug_init(void) {}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_X86
|
||||||
|
void acpi_cmos_rtc_init(void);
|
||||||
|
#else
|
||||||
|
static inline void acpi_cmos_rtc_init(void) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
extern bool acpi_force_hot_remove;
|
extern bool acpi_force_hot_remove;
|
||||||
|
|
||||||
|
|
|
@ -2132,6 +2132,7 @@ int __init acpi_scan_init(void)
|
||||||
acpi_processor_init();
|
acpi_processor_init();
|
||||||
acpi_platform_init();
|
acpi_platform_init();
|
||||||
acpi_lpss_init();
|
acpi_lpss_init();
|
||||||
|
acpi_cmos_rtc_init();
|
||||||
acpi_container_init();
|
acpi_container_init();
|
||||||
acpi_memory_hotplug_init();
|
acpi_memory_hotplug_init();
|
||||||
acpi_dock_init();
|
acpi_dock_init();
|
||||||
|
|
|
@ -156,12 +156,10 @@ struct acpi_device_flags {
|
||||||
u32 dynamic_status:1;
|
u32 dynamic_status:1;
|
||||||
u32 removable:1;
|
u32 removable:1;
|
||||||
u32 ejectable:1;
|
u32 ejectable:1;
|
||||||
u32 suprise_removal_ok:1;
|
|
||||||
u32 power_manageable:1;
|
u32 power_manageable:1;
|
||||||
u32 performance_manageable:1;
|
|
||||||
u32 eject_pending:1;
|
u32 eject_pending:1;
|
||||||
u32 match_driver:1;
|
u32 match_driver:1;
|
||||||
u32 reserved:24;
|
u32 reserved:26;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* File System */
|
/* File System */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче