mirror of
https://github.com/torvalds/linux
synced 2024-09-24 05:17:36 +00:00
Merge branches 'bugzilla-15807', 'bugzilla-15979-v2' and 'bugzilla-19162' into release
This commit is contained in:
commit
38add9b4ba
|
@ -701,6 +701,7 @@ static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy)
|
||||||
per_cpu(acfreq_data, policy->cpu) = NULL;
|
per_cpu(acfreq_data, policy->cpu) = NULL;
|
||||||
acpi_processor_unregister_performance(data->acpi_data,
|
acpi_processor_unregister_performance(data->acpi_data,
|
||||||
policy->cpu);
|
policy->cpu);
|
||||||
|
kfree(data->freq_table);
|
||||||
kfree(data);
|
kfree(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,7 @@ enum {
|
||||||
* due to bad math.
|
* due to bad math.
|
||||||
*/
|
*/
|
||||||
ACPI_BATTERY_QUIRK_SIGNED16_CURRENT,
|
ACPI_BATTERY_QUIRK_SIGNED16_CURRENT,
|
||||||
|
ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct acpi_battery {
|
struct acpi_battery {
|
||||||
|
@ -405,6 +406,8 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
|
||||||
result = extract_package(battery, buffer.pointer,
|
result = extract_package(battery, buffer.pointer,
|
||||||
info_offsets, ARRAY_SIZE(info_offsets));
|
info_offsets, ARRAY_SIZE(info_offsets));
|
||||||
kfree(buffer.pointer);
|
kfree(buffer.pointer);
|
||||||
|
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
|
||||||
|
battery->full_charge_capacity = battery->design_capacity;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,6 +444,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
|
||||||
battery->rate_now != -1)
|
battery->rate_now != -1)
|
||||||
battery->rate_now = abs((s16)battery->rate_now);
|
battery->rate_now = abs((s16)battery->rate_now);
|
||||||
|
|
||||||
|
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
|
||||||
|
&& battery->capacity_now >= 0 && battery->capacity_now <= 100)
|
||||||
|
battery->capacity_now = (battery->capacity_now *
|
||||||
|
battery->full_charge_capacity) / 100;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -552,6 +559,33 @@ static void acpi_battery_quirks(struct acpi_battery *battery)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* According to the ACPI spec, some kinds of primary batteries can
|
||||||
|
* report percentage battery remaining capacity directly to OS.
|
||||||
|
* In this case, it reports the Last Full Charged Capacity == 100
|
||||||
|
* and BatteryPresentRate == 0xFFFFFFFF.
|
||||||
|
*
|
||||||
|
* Now we found some battery reports percentage remaining capacity
|
||||||
|
* even if it's rechargeable.
|
||||||
|
* https://bugzilla.kernel.org/show_bug.cgi?id=15979
|
||||||
|
*
|
||||||
|
* Handle this correctly so that they won't break userspace.
|
||||||
|
*/
|
||||||
|
static void acpi_battery_quirks2(struct acpi_battery *battery)
|
||||||
|
{
|
||||||
|
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
|
||||||
|
return ;
|
||||||
|
|
||||||
|
if (battery->full_charge_capacity == 100 &&
|
||||||
|
battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
|
||||||
|
battery->capacity_now >=0 && battery->capacity_now <= 100) {
|
||||||
|
set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags);
|
||||||
|
battery->full_charge_capacity = battery->design_capacity;
|
||||||
|
battery->capacity_now = (battery->capacity_now *
|
||||||
|
battery->full_charge_capacity) / 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int acpi_battery_update(struct acpi_battery *battery)
|
static int acpi_battery_update(struct acpi_battery *battery)
|
||||||
{
|
{
|
||||||
int result, old_present = acpi_battery_present(battery);
|
int result, old_present = acpi_battery_present(battery);
|
||||||
|
@ -573,7 +607,9 @@ static int acpi_battery_update(struct acpi_battery *battery)
|
||||||
}
|
}
|
||||||
if (!battery->bat.dev)
|
if (!battery->bat.dev)
|
||||||
sysfs_add_battery(battery);
|
sysfs_add_battery(battery);
|
||||||
return acpi_battery_get_state(battery);
|
result = acpi_battery_get_state(battery);
|
||||||
|
acpi_battery_quirks2(battery);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------
|
||||||
|
|
|
@ -338,7 +338,8 @@ static int acpi_button_add(struct acpi_device *device)
|
||||||
{
|
{
|
||||||
struct acpi_button *button;
|
struct acpi_button *button;
|
||||||
struct input_dev *input;
|
struct input_dev *input;
|
||||||
char *hid, *name, *class;
|
const char *hid = acpi_device_hid(device);
|
||||||
|
char *name, *class;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL);
|
button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL);
|
||||||
|
@ -353,7 +354,6 @@ static int acpi_button_add(struct acpi_device *device)
|
||||||
goto err_free_button;
|
goto err_free_button;
|
||||||
}
|
}
|
||||||
|
|
||||||
hid = acpi_device_hid(device);
|
|
||||||
name = acpi_device_name(device);
|
name = acpi_device_name(device);
|
||||||
class = acpi_device_class(device);
|
class = acpi_device_class(device);
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,8 @@ extern struct acpi_device *acpi_root;
|
||||||
|
|
||||||
#define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent)
|
#define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent)
|
||||||
|
|
||||||
|
static const char *dummy_hid = "device";
|
||||||
|
|
||||||
static LIST_HEAD(acpi_device_list);
|
static LIST_HEAD(acpi_device_list);
|
||||||
static LIST_HEAD(acpi_bus_id_list);
|
static LIST_HEAD(acpi_bus_id_list);
|
||||||
DEFINE_MUTEX(acpi_device_lock);
|
DEFINE_MUTEX(acpi_device_lock);
|
||||||
|
@ -49,6 +51,9 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
|
||||||
int count;
|
int count;
|
||||||
struct acpi_hardware_id *id;
|
struct acpi_hardware_id *id;
|
||||||
|
|
||||||
|
if (list_empty(&acpi_dev->pnp.ids))
|
||||||
|
return 0;
|
||||||
|
|
||||||
len = snprintf(modalias, size, "acpi:");
|
len = snprintf(modalias, size, "acpi:");
|
||||||
size -= len;
|
size -= len;
|
||||||
|
|
||||||
|
@ -202,13 +207,15 @@ static int acpi_device_setup_files(struct acpi_device *dev)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = device_create_file(&dev->dev, &dev_attr_hid);
|
if (!list_empty(&dev->pnp.ids)) {
|
||||||
if (result)
|
result = device_create_file(&dev->dev, &dev_attr_hid);
|
||||||
goto end;
|
if (result)
|
||||||
|
goto end;
|
||||||
|
|
||||||
result = device_create_file(&dev->dev, &dev_attr_modalias);
|
result = device_create_file(&dev->dev, &dev_attr_modalias);
|
||||||
if (result)
|
if (result)
|
||||||
goto end;
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If device has _EJ0, 'eject' file is created that is used to trigger
|
* If device has _EJ0, 'eject' file is created that is used to trigger
|
||||||
|
@ -316,6 +323,9 @@ static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||||
struct acpi_device *acpi_dev = to_acpi_device(dev);
|
struct acpi_device *acpi_dev = to_acpi_device(dev);
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
|
if (list_empty(&acpi_dev->pnp.ids))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (add_uevent_var(env, "MODALIAS="))
|
if (add_uevent_var(env, "MODALIAS="))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
len = create_modalias(acpi_dev, &env->buf[env->buflen - 1],
|
len = create_modalias(acpi_dev, &env->buf[env->buflen - 1],
|
||||||
|
@ -1010,10 +1020,13 @@ static int acpi_dock_match(struct acpi_device *device)
|
||||||
return acpi_get_handle(device->handle, "_DCK", &tmp);
|
return acpi_get_handle(device->handle, "_DCK", &tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *acpi_device_hid(struct acpi_device *device)
|
const char *acpi_device_hid(struct acpi_device *device)
|
||||||
{
|
{
|
||||||
struct acpi_hardware_id *hid;
|
struct acpi_hardware_id *hid;
|
||||||
|
|
||||||
|
if (list_empty(&device->pnp.ids))
|
||||||
|
return dummy_hid;
|
||||||
|
|
||||||
hid = list_first_entry(&device->pnp.ids, struct acpi_hardware_id, list);
|
hid = list_first_entry(&device->pnp.ids, struct acpi_hardware_id, list);
|
||||||
return hid->id;
|
return hid->id;
|
||||||
}
|
}
|
||||||
|
@ -1142,16 +1155,6 @@ static void acpi_device_set_id(struct acpi_device *device)
|
||||||
acpi_add_id(device, ACPI_BUTTON_HID_SLEEPF);
|
acpi_add_id(device, ACPI_BUTTON_HID_SLEEPF);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* We build acpi_devices for some objects that don't have _HID or _CID,
|
|
||||||
* e.g., PCI bridges and slots. Drivers can't bind to these objects,
|
|
||||||
* but we do use them indirectly by traversing the acpi_device tree.
|
|
||||||
* This generic ID isn't useful for driver binding, but it provides
|
|
||||||
* the useful property that "every acpi_device has an ID."
|
|
||||||
*/
|
|
||||||
if (list_empty(&device->pnp.ids))
|
|
||||||
acpi_add_id(device, "device");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int acpi_device_set_context(struct acpi_device *device)
|
static int acpi_device_set_context(struct acpi_device *device)
|
||||||
|
|
|
@ -12,11 +12,12 @@ void pnp_unregister_protocol(struct pnp_protocol *protocol);
|
||||||
|
|
||||||
#define PNP_EISA_ID_MASK 0x7fffffff
|
#define PNP_EISA_ID_MASK 0x7fffffff
|
||||||
void pnp_eisa_id_to_string(u32 id, char *str);
|
void pnp_eisa_id_to_string(u32 id, char *str);
|
||||||
struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *, int id, char *pnpid);
|
struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *, int id,
|
||||||
|
const char *pnpid);
|
||||||
struct pnp_card *pnp_alloc_card(struct pnp_protocol *, int id, char *pnpid);
|
struct pnp_card *pnp_alloc_card(struct pnp_protocol *, int id, char *pnpid);
|
||||||
|
|
||||||
int pnp_add_device(struct pnp_dev *dev);
|
int pnp_add_device(struct pnp_dev *dev);
|
||||||
struct pnp_id *pnp_add_id(struct pnp_dev *dev, char *id);
|
struct pnp_id *pnp_add_id(struct pnp_dev *dev, const char *id);
|
||||||
|
|
||||||
int pnp_add_card(struct pnp_card *card);
|
int pnp_add_card(struct pnp_card *card);
|
||||||
void pnp_remove_card(struct pnp_card *card);
|
void pnp_remove_card(struct pnp_card *card);
|
||||||
|
|
|
@ -124,7 +124,8 @@ static void pnp_release_device(struct device *dmdev)
|
||||||
kfree(dev);
|
kfree(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid)
|
struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id,
|
||||||
|
const char *pnpid)
|
||||||
{
|
{
|
||||||
struct pnp_dev *dev;
|
struct pnp_dev *dev;
|
||||||
struct pnp_id *dev_id;
|
struct pnp_id *dev_id;
|
||||||
|
|
|
@ -236,7 +236,7 @@ void pnp_unregister_driver(struct pnp_driver *drv)
|
||||||
* @dev: pointer to the desired device
|
* @dev: pointer to the desired device
|
||||||
* @id: pointer to an EISA id string
|
* @id: pointer to an EISA id string
|
||||||
*/
|
*/
|
||||||
struct pnp_id *pnp_add_id(struct pnp_dev *dev, char *id)
|
struct pnp_id *pnp_add_id(struct pnp_dev *dev, const char *id)
|
||||||
{
|
{
|
||||||
struct pnp_id *dev_id, *ptr;
|
struct pnp_id *dev_id, *ptr;
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ static inline int __init is_exclusive_device(struct acpi_device *dev)
|
||||||
#define TEST_ALPHA(c) \
|
#define TEST_ALPHA(c) \
|
||||||
if (!('@' <= (c) || (c) <= 'Z')) \
|
if (!('@' <= (c) || (c) <= 'Z')) \
|
||||||
return 0
|
return 0
|
||||||
static int __init ispnpidacpi(char *id)
|
static int __init ispnpidacpi(const char *id)
|
||||||
{
|
{
|
||||||
TEST_ALPHA(id[0]);
|
TEST_ALPHA(id[0]);
|
||||||
TEST_ALPHA(id[1]);
|
TEST_ALPHA(id[1]);
|
||||||
|
|
|
@ -184,7 +184,7 @@ struct acpi_device_pnp {
|
||||||
|
|
||||||
#define acpi_device_bid(d) ((d)->pnp.bus_id)
|
#define acpi_device_bid(d) ((d)->pnp.bus_id)
|
||||||
#define acpi_device_adr(d) ((d)->pnp.bus_address)
|
#define acpi_device_adr(d) ((d)->pnp.bus_address)
|
||||||
char *acpi_device_hid(struct acpi_device *device);
|
const char *acpi_device_hid(struct acpi_device *device);
|
||||||
#define acpi_device_name(d) ((d)->pnp.device_name)
|
#define acpi_device_name(d) ((d)->pnp.device_name)
|
||||||
#define acpi_device_class(d) ((d)->pnp.device_class)
|
#define acpi_device_class(d) ((d)->pnp.device_class)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue