Commit 8494206d authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge back power-related ACPI material for v4.12.

parents fe8c470a 6c4c9a9a
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -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)
+20 −2
Original line number Diff line number Diff line
@@ -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,8 +1359,10 @@ static int __init acpi_battery_init(void)
static void __exit acpi_battery_exit(void)
{
	async_synchronize_cookie(async_cookie + 1);
	if (battery_driver_registered)
		acpi_bus_unregister_driver(&acpi_battery_driver);
#ifdef CONFIG_ACPI_PROCFS_POWER
	if (acpi_battery_dir)
		acpi_unlock_battery_dir(acpi_battery_dir);
#endif
}
+66 −0
Original line number Diff line number Diff line
@@ -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.
+18 −10
Original line number Diff line number Diff line
@@ -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,11 +809,15 @@ 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 (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);
	mutex_init(&info->lock);
@@ -849,6 +855,7 @@ 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;
	if (info->otg.cable) {
		ret = devm_extcon_register_notifier(&pdev->dev, info->otg.cable,
					EXTCON_USB_HOST, &info->otg.id_nb);
		if (ret) {
@@ -856,6 +863,7 @@ static int axp288_charger_probe(struct platform_device *pdev)
			return ret;
		}
		schedule_work(&info->otg.work);
	}

	/* Register charger interrupts */
	for (i = 0; i < CHRG_INTR_END; i++) {
+1 −0
Original line number Diff line number Diff line
@@ -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

Loading