Merge branches 'acpi-power', 'acpi-blacklist', 'acpi-video' and 'acpi-doc'
* acpi-power: power: supply: axp288_charger: Only wait for INT3496 device if present ACPI / AC: Add a blacklist with PMIC ACPI HIDs with a native charger driver ACPI / battery: Add a blacklist with PMIC ACPI HIDs with a native battery driver ACPI / battery: Fix acpi_battery_exit on acpi_battery_init_async errors ACPI / utils: Add new acpi_dev_present helper * acpi-blacklist: ACPI / blacklist: add _REV quirk for Dell Inspiron 7537 * acpi-video: ACPI / video: add comments about subtle cases ACPI / video: get rid of magic numbers and use enum instead * acpi-doc: ACPI / doc: linuxized-acpica.txt: fix typos
This commit is contained in:
commit
52e70c8af7
9 changed files with 254 additions and 63 deletions
|
@ -24,7 +24,7 @@ upstream.
|
|||
The homepage of ACPICA project is: www.acpica.org, it is maintained and
|
||||
supported by Intel Corporation.
|
||||
|
||||
The following figure depicts the Linux ACPI subystem where the ACPICA
|
||||
The following figure depicts the Linux ACPI subsystem where the ACPICA
|
||||
adaptation is included:
|
||||
|
||||
+---------------------------------------------------------+
|
||||
|
@ -110,7 +110,7 @@ upstream.
|
|||
Linux patches. The patches generated by this process are referred to as
|
||||
"linuxized ACPICA patches". The release process is carried out on a local
|
||||
copy the ACPICA git repository. Each commit in the monthly release is
|
||||
converted into a linuxized ACPICA patch. Together, they form the montly
|
||||
converted into a linuxized ACPICA patch. Together, they form the monthly
|
||||
ACPICA release patchset for the Linux ACPI community. This process is
|
||||
illustrated in the following figure:
|
||||
|
||||
|
@ -165,7 +165,7 @@ upstream.
|
|||
<http://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git>.
|
||||
|
||||
Before the linuxized ACPICA patches are sent to the Linux ACPI community
|
||||
for review, there is a quality ensurance build test process to reduce
|
||||
for review, there is a quality assurance build test process to reduce
|
||||
porting issues. Currently this build process only takes care of the
|
||||
following kernel configuration options:
|
||||
CONFIG_ACPI/CONFIG_ACPI_DEBUG/CONFIG_ACPI_DEBUGGER
|
||||
|
@ -195,12 +195,12 @@ upstream.
|
|||
release utilities (please refer to Section 4 below for the details).
|
||||
3. Linux specific features - Sometimes it's impossible to use the
|
||||
current ACPICA APIs to implement features required by the Linux kernel,
|
||||
so Linux developers occasionaly have to change ACPICA code directly.
|
||||
so Linux developers occasionally have to change ACPICA code directly.
|
||||
Those changes may not be acceptable by ACPICA upstream and in such cases
|
||||
they are left as committed ACPICA divergences unless the ACPICA side can
|
||||
implement new mechanisms as replacements for them.
|
||||
4. ACPICA release fixups - ACPICA only tests commits using a set of the
|
||||
user space simulation utilies, thus the linuxized ACPICA patches may
|
||||
user space simulation utilities, thus the linuxized ACPICA patches may
|
||||
break the Linux kernel, leaving us build/boot failures. In order to
|
||||
avoid breaking Linux bisection, fixes are applied directly to the
|
||||
linuxized ACPICA patches during the release process. When the release
|
||||
|
|
|
@ -57,12 +57,23 @@ static int acpi_ac_add(struct acpi_device *device);
|
|||
static int acpi_ac_remove(struct acpi_device *device);
|
||||
static void acpi_ac_notify(struct acpi_device *device, u32 event);
|
||||
|
||||
struct acpi_ac_bl {
|
||||
const char *hid;
|
||||
int hrv;
|
||||
};
|
||||
|
||||
static const struct acpi_device_id ac_device_ids[] = {
|
||||
{"ACPI0003", 0},
|
||||
{"", 0},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, ac_device_ids);
|
||||
|
||||
/* Lists of PMIC ACPI HIDs with an (often better) native charger driver */
|
||||
static const struct acpi_ac_bl acpi_ac_blacklist[] = {
|
||||
{ "INT33F4", -1 }, /* X-Powers AXP288 PMIC */
|
||||
{ "INT34D3", 3 }, /* Intel Cherrytrail Whiskey Cove PMIC */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int acpi_ac_resume(struct device *dev);
|
||||
#endif
|
||||
|
@ -424,11 +435,20 @@ static int acpi_ac_remove(struct acpi_device *device)
|
|||
|
||||
static int __init acpi_ac_init(void)
|
||||
{
|
||||
unsigned int i;
|
||||
int result;
|
||||
|
||||
if (acpi_disabled)
|
||||
return -ENODEV;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(acpi_ac_blacklist); i++)
|
||||
if (acpi_dev_present(acpi_ac_blacklist[i].hid, "1",
|
||||
acpi_ac_blacklist[i].hrv)) {
|
||||
pr_info(PREFIX "AC: found native %s PMIC, not loading\n",
|
||||
acpi_ac_blacklist[i].hid);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_PROCFS_POWER
|
||||
acpi_ac_dir = acpi_lock_ac_dir();
|
||||
if (!acpi_ac_dir)
|
||||
|
|
|
@ -73,6 +73,10 @@ module_param(report_key_events, int, 0644);
|
|||
MODULE_PARM_DESC(report_key_events,
|
||||
"0: none, 1: output changes, 2: brightness changes, 3: all");
|
||||
|
||||
/*
|
||||
* Whether the struct acpi_video_device_attrib::device_id_scheme bit should be
|
||||
* assumed even if not actually set.
|
||||
*/
|
||||
static bool device_id_scheme = false;
|
||||
module_param(device_id_scheme, bool, 0444);
|
||||
|
||||
|
@ -88,6 +92,18 @@ static int acpi_video_bus_remove(struct acpi_device *device);
|
|||
static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
|
||||
void acpi_video_detect_exit(void);
|
||||
|
||||
/*
|
||||
* Indices in the _BCL method response: the first two items are special,
|
||||
* the rest are all supported levels.
|
||||
*
|
||||
* See page 575 of the ACPI spec 3.0
|
||||
*/
|
||||
enum acpi_video_level_idx {
|
||||
ACPI_VIDEO_AC_LEVEL, /* level when machine has full power */
|
||||
ACPI_VIDEO_BATTERY_LEVEL, /* level when machine is on batteries */
|
||||
ACPI_VIDEO_FIRST_LEVEL, /* actual supported levels begin here */
|
||||
};
|
||||
|
||||
static const struct acpi_device_id video_device_ids[] = {
|
||||
{ACPI_VIDEO_HID, 0},
|
||||
{"", 0},
|
||||
|
@ -132,7 +148,15 @@ struct acpi_video_device_attrib {
|
|||
the VGA device. */
|
||||
u32 pipe_id:3; /* For VGA multiple-head devices. */
|
||||
u32 reserved:10; /* Must be 0 */
|
||||
u32 device_id_scheme:1; /* Device ID Scheme */
|
||||
|
||||
/*
|
||||
* The device ID might not actually follow the scheme described by this
|
||||
* struct acpi_video_device_attrib. If it does, then this bit
|
||||
* device_id_scheme is set; otherwise, other fields should be ignored.
|
||||
*
|
||||
* (but also see the global flag device_id_scheme)
|
||||
*/
|
||||
u32 device_id_scheme:1;
|
||||
};
|
||||
|
||||
struct acpi_video_enumerated_device {
|
||||
|
@ -217,20 +241,16 @@ static int acpi_video_get_brightness(struct backlight_device *bd)
|
|||
|
||||
if (acpi_video_device_lcd_get_level_current(vd, &cur_level, false))
|
||||
return -EINVAL;
|
||||
for (i = 2; i < vd->brightness->count; i++) {
|
||||
for (i = ACPI_VIDEO_FIRST_LEVEL; i < vd->brightness->count; i++) {
|
||||
if (vd->brightness->levels[i] == cur_level)
|
||||
/*
|
||||
* The first two entries are special - see page 575
|
||||
* of the ACPI spec 3.0
|
||||
*/
|
||||
return i - 2;
|
||||
return i - ACPI_VIDEO_FIRST_LEVEL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_video_set_brightness(struct backlight_device *bd)
|
||||
{
|
||||
int request_level = bd->props.brightness + 2;
|
||||
int request_level = bd->props.brightness + ACPI_VIDEO_FIRST_LEVEL;
|
||||
struct acpi_video_device *vd = bl_get_data(bd);
|
||||
|
||||
cancel_delayed_work(&vd->switch_brightness_work);
|
||||
|
@ -244,18 +264,18 @@ static const struct backlight_ops acpi_backlight_ops = {
|
|||
};
|
||||
|
||||
/* thermal cooling device callbacks */
|
||||
static int video_get_max_state(struct thermal_cooling_device *cooling_dev, unsigned
|
||||
long *state)
|
||||
static int video_get_max_state(struct thermal_cooling_device *cooling_dev,
|
||||
unsigned long *state)
|
||||
{
|
||||
struct acpi_device *device = cooling_dev->devdata;
|
||||
struct acpi_video_device *video = acpi_driver_data(device);
|
||||
|
||||
*state = video->brightness->count - 3;
|
||||
*state = video->brightness->count - ACPI_VIDEO_FIRST_LEVEL - 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int video_get_cur_state(struct thermal_cooling_device *cooling_dev, unsigned
|
||||
long *state)
|
||||
static int video_get_cur_state(struct thermal_cooling_device *cooling_dev,
|
||||
unsigned long *state)
|
||||
{
|
||||
struct acpi_device *device = cooling_dev->devdata;
|
||||
struct acpi_video_device *video = acpi_driver_data(device);
|
||||
|
@ -264,7 +284,8 @@ static int video_get_cur_state(struct thermal_cooling_device *cooling_dev, unsig
|
|||
|
||||
if (acpi_video_device_lcd_get_level_current(video, &level, false))
|
||||
return -EINVAL;
|
||||
for (offset = 2; offset < video->brightness->count; offset++)
|
||||
for (offset = ACPI_VIDEO_FIRST_LEVEL; offset < video->brightness->count;
|
||||
offset++)
|
||||
if (level == video->brightness->levels[offset]) {
|
||||
*state = video->brightness->count - offset - 1;
|
||||
return 0;
|
||||
|
@ -280,7 +301,7 @@ video_set_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long st
|
|||
struct acpi_video_device *video = acpi_driver_data(device);
|
||||
int level;
|
||||
|
||||
if (state >= video->brightness->count - 2)
|
||||
if (state >= video->brightness->count - ACPI_VIDEO_FIRST_LEVEL)
|
||||
return -EINVAL;
|
||||
|
||||
state = video->brightness->count - state;
|
||||
|
@ -345,10 +366,12 @@ acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
|
|||
}
|
||||
|
||||
device->brightness->curr = level;
|
||||
for (state = 2; state < device->brightness->count; state++)
|
||||
for (state = ACPI_VIDEO_FIRST_LEVEL; state < device->brightness->count;
|
||||
state++)
|
||||
if (level == device->brightness->levels[state]) {
|
||||
if (device->backlight)
|
||||
device->backlight->props.brightness = state - 2;
|
||||
device->backlight->props.brightness =
|
||||
state - ACPI_VIDEO_FIRST_LEVEL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -530,14 +553,16 @@ acpi_video_bqc_value_to_level(struct acpi_video_device *device,
|
|||
|
||||
if (device->brightness->flags._BQC_use_index) {
|
||||
/*
|
||||
* _BQC returns an index that doesn't account for
|
||||
* the first 2 items with special meaning, so we need
|
||||
* to compensate for that by offsetting ourselves
|
||||
* _BQC returns an index that doesn't account for the first 2
|
||||
* items with special meaning (see enum acpi_video_level_idx),
|
||||
* so we need to compensate for that by offsetting ourselves
|
||||
*/
|
||||
if (device->brightness->flags._BCL_reversed)
|
||||
bqc_value = device->brightness->count - 3 - bqc_value;
|
||||
bqc_value = device->brightness->count -
|
||||
ACPI_VIDEO_FIRST_LEVEL - 1 - bqc_value;
|
||||
|
||||
level = device->brightness->levels[bqc_value + 2];
|
||||
level = device->brightness->levels[bqc_value +
|
||||
ACPI_VIDEO_FIRST_LEVEL];
|
||||
} else {
|
||||
level = bqc_value;
|
||||
}
|
||||
|
@ -571,7 +596,8 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
|
|||
|
||||
*level = acpi_video_bqc_value_to_level(device, *level);
|
||||
|
||||
for (i = 2; i < device->brightness->count; i++)
|
||||
for (i = ACPI_VIDEO_FIRST_LEVEL;
|
||||
i < device->brightness->count; i++)
|
||||
if (device->brightness->levels[i] == *level) {
|
||||
device->brightness->curr = *level;
|
||||
return 0;
|
||||
|
@ -714,9 +740,37 @@ static int acpi_video_bqc_quirk(struct acpi_video_device *device,
|
|||
|
||||
/*
|
||||
* Some systems always report current brightness level as maximum
|
||||
* through _BQC, we need to test another value for them.
|
||||
* through _BQC, we need to test another value for them. However,
|
||||
* there is a subtlety:
|
||||
*
|
||||
* If the _BCL package ordering is descending, the first level
|
||||
* (br->levels[2]) is likely to be 0, and if the number of levels
|
||||
* matches the number of steps, we might confuse a returned level to
|
||||
* mean the index.
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* current_level = max_level = 100
|
||||
* test_level = 0
|
||||
* returned level = 100
|
||||
*
|
||||
* In this case 100 means the level, not the index, and _BCM failed.
|
||||
* Still, if the _BCL package ordering is descending, the index of
|
||||
* level 0 is also 100, so we assume _BQC is indexed, when it's not.
|
||||
*
|
||||
* This causes all _BQC calls to return bogus values causing weird
|
||||
* behavior from the user's perspective. For example:
|
||||
*
|
||||
* xbacklight -set 10; xbacklight -set 20;
|
||||
*
|
||||
* would flash to 90% and then slowly down to the desired level (20).
|
||||
*
|
||||
* The solution is simple; test anything other than the first level
|
||||
* (e.g. 1).
|
||||
*/
|
||||
test_level = current_level == max_level ? br->levels[3] : max_level;
|
||||
test_level = current_level == max_level
|
||||
? br->levels[ACPI_VIDEO_FIRST_LEVEL + 1]
|
||||
: max_level;
|
||||
|
||||
result = acpi_video_device_lcd_set_level(device, test_level);
|
||||
if (result)
|
||||
|
@ -730,8 +784,8 @@ static int acpi_video_bqc_quirk(struct acpi_video_device *device,
|
|||
/* buggy _BQC found, need to find out if it uses index */
|
||||
if (level < br->count) {
|
||||
if (br->flags._BCL_reversed)
|
||||
level = br->count - 3 - level;
|
||||
if (br->levels[level + 2] == test_level)
|
||||
level = br->count - ACPI_VIDEO_FIRST_LEVEL - 1 - level;
|
||||
if (br->levels[level + ACPI_VIDEO_FIRST_LEVEL] == test_level)
|
||||
br->flags._BQC_use_index = 1;
|
||||
}
|
||||
|
||||
|
@ -761,7 +815,7 @@ int acpi_video_get_levels(struct acpi_device *device,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (obj->package.count < 2) {
|
||||
if (obj->package.count < ACPI_VIDEO_FIRST_LEVEL) {
|
||||
result = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
@ -773,8 +827,13 @@ int acpi_video_get_levels(struct acpi_device *device,
|
|||
goto out;
|
||||
}
|
||||
|
||||
br->levels = kmalloc((obj->package.count + 2) * sizeof *(br->levels),
|
||||
GFP_KERNEL);
|
||||
/*
|
||||
* Note that we have to reserve 2 extra items (ACPI_VIDEO_FIRST_LEVEL),
|
||||
* in order to account for buggy BIOS which don't export the first two
|
||||
* special levels (see below)
|
||||
*/
|
||||
br->levels = kmalloc((obj->package.count + ACPI_VIDEO_FIRST_LEVEL) *
|
||||
sizeof(*br->levels), GFP_KERNEL);
|
||||
if (!br->levels) {
|
||||
result = -ENOMEM;
|
||||
goto out_free;
|
||||
|
@ -788,7 +847,8 @@ int acpi_video_get_levels(struct acpi_device *device,
|
|||
}
|
||||
value = (u32) o->integer.value;
|
||||
/* Skip duplicate entries */
|
||||
if (count > 2 && br->levels[count - 1] == value)
|
||||
if (count > ACPI_VIDEO_FIRST_LEVEL
|
||||
&& br->levels[count - 1] == value)
|
||||
continue;
|
||||
|
||||
br->levels[count] = value;
|
||||
|
@ -804,27 +864,30 @@ int acpi_video_get_levels(struct acpi_device *device,
|
|||
* In this case, the first two elements in _BCL packages
|
||||
* are also supported brightness levels that OS should take care of.
|
||||
*/
|
||||
for (i = 2; i < count; i++) {
|
||||
if (br->levels[i] == br->levels[0])
|
||||
for (i = ACPI_VIDEO_FIRST_LEVEL; i < count; i++) {
|
||||
if (br->levels[i] == br->levels[ACPI_VIDEO_AC_LEVEL])
|
||||
level_ac_battery++;
|
||||
if (br->levels[i] == br->levels[1])
|
||||
if (br->levels[i] == br->levels[ACPI_VIDEO_BATTERY_LEVEL])
|
||||
level_ac_battery++;
|
||||
}
|
||||
|
||||
if (level_ac_battery < 2) {
|
||||
level_ac_battery = 2 - level_ac_battery;
|
||||
if (level_ac_battery < ACPI_VIDEO_FIRST_LEVEL) {
|
||||
level_ac_battery = ACPI_VIDEO_FIRST_LEVEL - level_ac_battery;
|
||||
br->flags._BCL_no_ac_battery_levels = 1;
|
||||
for (i = (count - 1 + level_ac_battery); i >= 2; i--)
|
||||
for (i = (count - 1 + level_ac_battery);
|
||||
i >= ACPI_VIDEO_FIRST_LEVEL; i--)
|
||||
br->levels[i] = br->levels[i - level_ac_battery];
|
||||
count += level_ac_battery;
|
||||
} else if (level_ac_battery > 2)
|
||||
} else if (level_ac_battery > ACPI_VIDEO_FIRST_LEVEL)
|
||||
ACPI_ERROR((AE_INFO, "Too many duplicates in _BCL package"));
|
||||
|
||||
/* Check if the _BCL package is in a reversed order */
|
||||
if (max_level == br->levels[2]) {
|
||||
if (max_level == br->levels[ACPI_VIDEO_FIRST_LEVEL]) {
|
||||
br->flags._BCL_reversed = 1;
|
||||
sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
|
||||
acpi_video_cmp_level, NULL);
|
||||
sort(&br->levels[ACPI_VIDEO_FIRST_LEVEL],
|
||||
count - ACPI_VIDEO_FIRST_LEVEL,
|
||||
sizeof(br->levels[ACPI_VIDEO_FIRST_LEVEL]),
|
||||
acpi_video_cmp_level, NULL);
|
||||
} else if (max_level != br->levels[count - 1])
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Found unordered _BCL package"));
|
||||
|
@ -894,7 +957,7 @@ acpi_video_init_brightness(struct acpi_video_device *device)
|
|||
* level_old is invalid (no matter whether it's a level
|
||||
* or an index). Set the backlight to max_level in this case.
|
||||
*/
|
||||
for (i = 2; i < br->count; i++)
|
||||
for (i = ACPI_VIDEO_FIRST_LEVEL; i < br->count; i++)
|
||||
if (level == br->levels[i])
|
||||
break;
|
||||
if (i == br->count || !level)
|
||||
|
@ -906,7 +969,8 @@ acpi_video_init_brightness(struct acpi_video_device *device)
|
|||
goto out_free_levels;
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"found %d brightness levels\n", br->count - 2));
|
||||
"found %d brightness levels\n",
|
||||
br->count - ACPI_VIDEO_FIRST_LEVEL));
|
||||
return 0;
|
||||
|
||||
out_free_levels:
|
||||
|
@ -1297,7 +1361,7 @@ acpi_video_get_next_level(struct acpi_video_device *device,
|
|||
max = max_below = 0;
|
||||
min = min_above = 255;
|
||||
/* Find closest level to level_current */
|
||||
for (i = 2; i < device->brightness->count; i++) {
|
||||
for (i = ACPI_VIDEO_FIRST_LEVEL; i < device->brightness->count; i++) {
|
||||
l = device->brightness->levels[i];
|
||||
if (abs(l - level_current) < abs(delta)) {
|
||||
delta = l - level_current;
|
||||
|
@ -1307,7 +1371,7 @@ acpi_video_get_next_level(struct acpi_video_device *device,
|
|||
}
|
||||
/* Ajust level_current to closest available level */
|
||||
level_current += delta;
|
||||
for (i = 2; i < device->brightness->count; i++) {
|
||||
for (i = ACPI_VIDEO_FIRST_LEVEL; i < device->brightness->count; i++) {
|
||||
l = device->brightness->levels[i];
|
||||
if (l < min)
|
||||
min = l;
|
||||
|
@ -1680,7 +1744,8 @@ static void acpi_video_dev_register_backlight(struct acpi_video_device *device)
|
|||
|
||||
memset(&props, 0, sizeof(struct backlight_properties));
|
||||
props.type = BACKLIGHT_FIRMWARE;
|
||||
props.max_brightness = device->brightness->count - 3;
|
||||
props.max_brightness =
|
||||
device->brightness->count - ACPI_VIDEO_FIRST_LEVEL - 1;
|
||||
device->backlight = backlight_device_register(name,
|
||||
parent,
|
||||
device,
|
||||
|
|
|
@ -67,6 +67,7 @@ MODULE_DESCRIPTION("ACPI Battery Driver");
|
|||
MODULE_LICENSE("GPL");
|
||||
|
||||
static async_cookie_t async_cookie;
|
||||
static bool battery_driver_registered;
|
||||
static int battery_bix_broken_package;
|
||||
static int battery_notification_delay_ms;
|
||||
static unsigned int cache_time = 1000;
|
||||
|
@ -93,6 +94,11 @@ static const struct acpi_device_id battery_device_ids[] = {
|
|||
|
||||
MODULE_DEVICE_TABLE(acpi, battery_device_ids);
|
||||
|
||||
/* Lists of PMIC ACPI HIDs with an (often better) native battery driver */
|
||||
static const char * const acpi_battery_blacklist[] = {
|
||||
"INT33F4", /* X-Powers AXP288 PMIC */
|
||||
};
|
||||
|
||||
enum {
|
||||
ACPI_BATTERY_ALARM_PRESENT,
|
||||
ACPI_BATTERY_XINFO_PRESENT,
|
||||
|
@ -1315,8 +1321,17 @@ static struct acpi_driver acpi_battery_driver = {
|
|||
|
||||
static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
|
||||
{
|
||||
unsigned int i;
|
||||
int result;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(acpi_battery_blacklist); i++)
|
||||
if (acpi_dev_present(acpi_battery_blacklist[i], "1", -1)) {
|
||||
pr_info(PREFIX ACPI_BATTERY_DEVICE_NAME
|
||||
": found native %s PMIC, not loading\n",
|
||||
acpi_battery_blacklist[i]);
|
||||
return;
|
||||
}
|
||||
|
||||
dmi_check_system(bat_dmi_table);
|
||||
|
||||
#ifdef CONFIG_ACPI_PROCFS_POWER
|
||||
|
@ -1329,6 +1344,7 @@ static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
|
|||
if (result < 0)
|
||||
acpi_unlock_battery_dir(acpi_battery_dir);
|
||||
#endif
|
||||
battery_driver_registered = (result == 0);
|
||||
}
|
||||
|
||||
static int __init acpi_battery_init(void)
|
||||
|
@ -1343,9 +1359,11 @@ static int __init acpi_battery_init(void)
|
|||
static void __exit acpi_battery_exit(void)
|
||||
{
|
||||
async_synchronize_cookie(async_cookie + 1);
|
||||
acpi_bus_unregister_driver(&acpi_battery_driver);
|
||||
if (battery_driver_registered)
|
||||
acpi_bus_unregister_driver(&acpi_battery_driver);
|
||||
#ifdef CONFIG_ACPI_PROCFS_POWER
|
||||
acpi_unlock_battery_dir(acpi_battery_dir);
|
||||
if (acpi_battery_dir)
|
||||
acpi_unlock_battery_dir(acpi_battery_dir);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -188,6 +188,14 @@ static struct dmi_system_id acpi_rev_dmi_table[] __initdata = {
|
|||
DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 3350"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = dmi_enable_rev_override,
|
||||
.ident = "DELL Inspiron 7537",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7537"),
|
||||
},
|
||||
},
|
||||
#endif
|
||||
{}
|
||||
};
|
||||
|
|
|
@ -736,6 +736,72 @@ bool acpi_dev_found(const char *hid)
|
|||
}
|
||||
EXPORT_SYMBOL(acpi_dev_found);
|
||||
|
||||
struct acpi_dev_present_info {
|
||||
struct acpi_device_id hid[2];
|
||||
const char *uid;
|
||||
s64 hrv;
|
||||
};
|
||||
|
||||
static int acpi_dev_present_cb(struct device *dev, void *data)
|
||||
{
|
||||
struct acpi_device *adev = to_acpi_device(dev);
|
||||
struct acpi_dev_present_info *match = data;
|
||||
unsigned long long hrv;
|
||||
acpi_status status;
|
||||
|
||||
if (acpi_match_device_ids(adev, match->hid))
|
||||
return 0;
|
||||
|
||||
if (match->uid && (!adev->pnp.unique_id ||
|
||||
strcmp(adev->pnp.unique_id, match->uid)))
|
||||
return 0;
|
||||
|
||||
if (match->hrv == -1)
|
||||
return 1;
|
||||
|
||||
status = acpi_evaluate_integer(adev->handle, "_HRV", NULL, &hrv);
|
||||
if (ACPI_FAILURE(status))
|
||||
return 0;
|
||||
|
||||
return hrv == match->hrv;
|
||||
}
|
||||
|
||||
/**
|
||||
* acpi_dev_present - Detect that a given ACPI device is present
|
||||
* @hid: Hardware ID of the device.
|
||||
* @uid: Unique ID of the device, pass NULL to not check _UID
|
||||
* @hrv: Hardware Revision of the device, pass -1 to not check _HRV
|
||||
*
|
||||
* Return %true if a matching device was present at the moment of invocation.
|
||||
* Note that if the device is pluggable, it may since have disappeared.
|
||||
*
|
||||
* Note that unlike acpi_dev_found() this function checks the status
|
||||
* of the device. So for devices which are present in the dsdt, but
|
||||
* which are disabled (their _STA callback returns 0) this function
|
||||
* will return false.
|
||||
*
|
||||
* For this function to work, acpi_bus_scan() must have been executed
|
||||
* which happens in the subsys_initcall() subsection. Hence, do not
|
||||
* call from a subsys_initcall() or earlier (use acpi_get_devices()
|
||||
* instead). Calling from module_init() is fine (which is synonymous
|
||||
* with device_initcall()).
|
||||
*/
|
||||
bool acpi_dev_present(const char *hid, const char *uid, s64 hrv)
|
||||
{
|
||||
struct acpi_dev_present_info match = {};
|
||||
struct device *dev;
|
||||
|
||||
strlcpy(match.hid[0].id, hid, sizeof(match.hid[0].id));
|
||||
match.uid = uid;
|
||||
match.hrv = hrv;
|
||||
|
||||
dev = bus_find_device(&acpi_bus_type, NULL, &match,
|
||||
acpi_dev_present_cb);
|
||||
|
||||
return !!dev;
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_dev_present);
|
||||
|
||||
/*
|
||||
* acpi_backlight= handling, this is done here rather then in video_detect.c
|
||||
* because __setup cannot be used in modules.
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
@ -113,7 +114,8 @@
|
|||
#define ILIM_3000MA 3000 /* 3000mA */
|
||||
|
||||
#define AXP288_EXTCON_DEV_NAME "axp288_extcon"
|
||||
#define USB_HOST_EXTCON_DEV_NAME "INT3496:00"
|
||||
#define USB_HOST_EXTCON_HID "INT3496"
|
||||
#define USB_HOST_EXTCON_NAME "INT3496:00"
|
||||
|
||||
static const unsigned int cable_ids[] =
|
||||
{ EXTCON_CHG_USB_SDP, EXTCON_CHG_USB_CDP, EXTCON_CHG_USB_DCP };
|
||||
|
@ -807,10 +809,14 @@ static int axp288_charger_probe(struct platform_device *pdev)
|
|||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
info->otg.cable = extcon_get_extcon_dev(USB_HOST_EXTCON_DEV_NAME);
|
||||
if (info->otg.cable == NULL) {
|
||||
dev_dbg(dev, "EXTCON_USB_HOST is not ready, probe deferred\n");
|
||||
return -EPROBE_DEFER;
|
||||
if (acpi_dev_present(USB_HOST_EXTCON_HID, NULL, -1)) {
|
||||
info->otg.cable = extcon_get_extcon_dev(USB_HOST_EXTCON_NAME);
|
||||
if (info->otg.cable == NULL) {
|
||||
dev_dbg(dev, "EXTCON_USB_HOST is not ready, probe deferred\n");
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
dev_info(&pdev->dev,
|
||||
"Using " USB_HOST_EXTCON_HID " extcon for usb-id\n");
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, info);
|
||||
|
@ -849,13 +855,15 @@ static int axp288_charger_probe(struct platform_device *pdev)
|
|||
/* Register for OTG notification */
|
||||
INIT_WORK(&info->otg.work, axp288_charger_otg_evt_worker);
|
||||
info->otg.id_nb.notifier_call = axp288_charger_handle_otg_evt;
|
||||
ret = devm_extcon_register_notifier(&pdev->dev, info->otg.cable,
|
||||
if (info->otg.cable) {
|
||||
ret = devm_extcon_register_notifier(&pdev->dev, info->otg.cable,
|
||||
EXTCON_USB_HOST, &info->otg.id_nb);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to register EXTCON_USB_HOST notifier\n");
|
||||
return ret;
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to register EXTCON_USB_HOST notifier\n");
|
||||
return ret;
|
||||
}
|
||||
schedule_work(&info->otg.work);
|
||||
}
|
||||
schedule_work(&info->otg.work);
|
||||
|
||||
/* Register charger interrupts */
|
||||
for (i = 0; i < CHRG_INTR_END; i++) {
|
||||
|
|
|
@ -88,6 +88,7 @@ acpi_evaluate_dsm_typed(acpi_handle handle, const u8 *uuid, u64 rev, u64 func,
|
|||
}
|
||||
|
||||
bool acpi_dev_found(const char *hid);
|
||||
bool acpi_dev_present(const char *hid, const char *uid, s64 hrv);
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
|
||||
|
|
|
@ -607,6 +607,11 @@ static inline bool acpi_dev_found(const char *hid)
|
|||
return false;
|
||||
}
|
||||
|
||||
static inline bool acpi_dev_present(const char *hid, const char *uid, s64 hrv)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool is_acpi_node(struct fwnode_handle *fwnode)
|
||||
{
|
||||
return false;
|
||||
|
|
Loading…
Reference in a new issue