Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  button.c - ACPI Button Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #define pr_fmt(fmt) "ACPI: button: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/dmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <acpi/button.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define PREFIX "ACPI: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define ACPI_BUTTON_CLASS		"button"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define ACPI_BUTTON_FILE_STATE		"state"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define ACPI_BUTTON_TYPE_UNKNOWN	0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define ACPI_BUTTON_NOTIFY_STATUS	0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define ACPI_BUTTON_SUBCLASS_POWER	"power"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define ACPI_BUTTON_DEVICE_NAME_POWER	"Power Button"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define ACPI_BUTTON_TYPE_POWER		0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define ACPI_BUTTON_SUBCLASS_SLEEP	"sleep"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define ACPI_BUTTON_DEVICE_NAME_SLEEP	"Sleep Button"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define ACPI_BUTTON_TYPE_SLEEP		0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define ACPI_BUTTON_SUBCLASS_LID	"lid"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define ACPI_BUTTON_DEVICE_NAME_LID	"Lid Switch"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define ACPI_BUTTON_TYPE_LID		0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	ACPI_BUTTON_LID_INIT_IGNORE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	ACPI_BUTTON_LID_INIT_OPEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	ACPI_BUTTON_LID_INIT_METHOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	ACPI_BUTTON_LID_INIT_DISABLED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) static const char * const lid_init_state_str[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	[ACPI_BUTTON_LID_INIT_IGNORE]		= "ignore",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	[ACPI_BUTTON_LID_INIT_OPEN]		= "open",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	[ACPI_BUTTON_LID_INIT_METHOD]		= "method",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	[ACPI_BUTTON_LID_INIT_DISABLED]		= "disabled",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define _COMPONENT		ACPI_BUTTON_COMPONENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) ACPI_MODULE_NAME("button");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) MODULE_AUTHOR("Paul Diefenbaugh");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) MODULE_DESCRIPTION("ACPI Button Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) static const struct acpi_device_id button_device_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	{ACPI_BUTTON_HID_LID,    0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	{ACPI_BUTTON_HID_SLEEP,  0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	{ACPI_BUTTON_HID_SLEEPF, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	{ACPI_BUTTON_HID_POWER,  0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	{ACPI_BUTTON_HID_POWERF, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	{"", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) MODULE_DEVICE_TABLE(acpi, button_device_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) /* Please keep this list sorted alphabetically by vendor and model */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) static const struct dmi_system_id dmi_lid_quirks[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		/* GP-electronic T701, _LID method points to a floating GPIO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		.matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 			DMI_MATCH(DMI_PRODUCT_NAME, "T701"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 			DMI_MATCH(DMI_BIOS_VERSION, "BYT70A.YNCHENG.WIN.007"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_DISABLED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		 * Medion Akoya E2215T, notification of the LID device only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		 * happens on close, not on open and _LID always returns closed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		.matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 			DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 			DMI_MATCH(DMI_PRODUCT_NAME, "E2215T"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		 * Medion Akoya E2228T, notification of the LID device only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		 * happens on close, not on open and _LID always returns closed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		.matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 			DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			DMI_MATCH(DMI_PRODUCT_NAME, "E2228T"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		 * Razer Blade Stealth 13 late 2019, notification of the LID device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		 * only happens on close, not on open and _LID always returns closed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		.matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			DMI_MATCH(DMI_SYS_VENDOR, "Razer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 			DMI_MATCH(DMI_PRODUCT_NAME, "Razer Blade Stealth 13 Late 2019"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	{}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static int acpi_button_add(struct acpi_device *device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static int acpi_button_remove(struct acpi_device *device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static void acpi_button_notify(struct acpi_device *device, u32 event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static int acpi_button_suspend(struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static int acpi_button_resume(struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define acpi_button_suspend NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define acpi_button_resume NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static SIMPLE_DEV_PM_OPS(acpi_button_pm, acpi_button_suspend, acpi_button_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static struct acpi_driver acpi_button_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	.name = "button",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	.class = ACPI_BUTTON_CLASS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	.ids = button_device_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	.ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		.add = acpi_button_add,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		.remove = acpi_button_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		.notify = acpi_button_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	.drv.pm = &acpi_button_pm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct acpi_button {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	unsigned int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	struct input_dev *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	char phys[32];			/* for input device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	unsigned long pushed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	int last_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	ktime_t last_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	bool suspended;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	bool lid_state_initialized;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static struct acpi_device *lid_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static long lid_init_state = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static unsigned long lid_report_interval __read_mostly = 500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) module_param(lid_report_interval, ulong, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) MODULE_PARM_DESC(lid_report_interval, "Interval (ms) between lid key events");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* --------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)                               FS Interface (/proc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)    -------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static struct proc_dir_entry *acpi_button_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static struct proc_dir_entry *acpi_lid_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static int acpi_lid_evaluate_state(struct acpi_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	unsigned long long lid_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	status = acpi_evaluate_integer(device->handle, "_LID", NULL, &lid_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	return lid_state ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static int acpi_lid_notify_state(struct acpi_device *device, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	struct acpi_button *button = acpi_driver_data(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	ktime_t next_report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	bool do_update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	 * In lid_init_state=ignore mode, if user opens/closes lid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	 * frequently with "open" missing, and "last_time" is also updated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	 * frequently, "close" cannot be delivered to the userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	 * So "last_time" is only updated after a timeout or an actual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	 * switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	if (lid_init_state != ACPI_BUTTON_LID_INIT_IGNORE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	    button->last_state != !!state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		do_update = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		do_update = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	next_report = ktime_add(button->last_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 				ms_to_ktime(lid_report_interval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	if (button->last_state == !!state &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	    ktime_after(ktime_get(), next_report)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		/* Complain the buggy firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		pr_warn_once("The lid device is not compliant to SW_LID.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		 * Send the unreliable complement switch event:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		 * On most platforms, the lid device is reliable. However
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		 * there are exceptions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		 * 1. Platforms returning initial lid state as "close" by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		 *    default after booting/resuming:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		 *     https://bugzilla.kernel.org/show_bug.cgi?id=89211
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		 *     https://bugzilla.kernel.org/show_bug.cgi?id=106151
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		 * 2. Platforms never reporting "open" events:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		 *     https://bugzilla.kernel.org/show_bug.cgi?id=106941
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		 * On these buggy platforms, the usage model of the ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		 * lid device actually is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		 * 1. The initial returning value of _LID may not be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		 *    reliable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		 * 2. The open event may not be reliable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		 * 3. The close event is reliable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		 * But SW_LID is typed as input switch event, the input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		 * layer checks if the event is redundant. Hence if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		 * state is not switched, the userspace cannot see this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		 * platform triggered reliable event. By inserting a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		 * complement switch event, it then is guaranteed that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		 * platform triggered reliable one can always be seen by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		 * the userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		if (lid_init_state == ACPI_BUTTON_LID_INIT_IGNORE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 			do_update = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			 * Do generate complement switch event for "close"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 			 * as "close" is reliable and wrong "open" won't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 			 * trigger unexpected behaviors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 			 * Do not generate complement switch event for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 			 * "open" as "open" is not reliable and wrong
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 			 * "close" will trigger unexpected behaviors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 			if (!state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 				input_report_switch(button->input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 						    SW_LID, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 				input_sync(button->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	/* Send the platform triggered reliable event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	if (do_update) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		acpi_handle_debug(device->handle, "ACPI LID %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 				  state ? "open" : "closed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		input_report_switch(button->input, SW_LID, !state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		input_sync(button->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		button->last_state = !!state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		button->last_time = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static int __maybe_unused acpi_button_state_seq_show(struct seq_file *seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 						     void *offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	struct acpi_device *device = seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	int state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	state = acpi_lid_evaluate_state(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	seq_printf(seq, "state:      %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		   state < 0 ? "unsupported" : (state ? "open" : "closed"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) static int acpi_button_add_fs(struct acpi_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	struct acpi_button *button = acpi_driver_data(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	struct proc_dir_entry *entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	/* procfs I/F for ACPI lid device only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	if (button->type != ACPI_BUTTON_TYPE_LID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	if (acpi_button_dir || acpi_lid_dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		printk(KERN_ERR PREFIX "More than one Lid device found!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	/* create /proc/acpi/button */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	if (!acpi_button_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	/* create /proc/acpi/button/lid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	acpi_lid_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	if (!acpi_lid_dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		goto remove_button_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	/* create /proc/acpi/button/lid/LID/ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), acpi_lid_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	if (!acpi_device_dir(device)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		goto remove_lid_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	/* create /proc/acpi/button/lid/LID/state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	entry = proc_create_single_data(ACPI_BUTTON_FILE_STATE, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 			acpi_device_dir(device), acpi_button_state_seq_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 			device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	if (!entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		goto remove_dev_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) remove_dev_dir:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	remove_proc_entry(acpi_device_bid(device),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 			  acpi_lid_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	acpi_device_dir(device) = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) remove_lid_dir:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	acpi_lid_dir = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) remove_button_dir:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	acpi_button_dir = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) static int acpi_button_remove_fs(struct acpi_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	struct acpi_button *button = acpi_driver_data(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	if (button->type != ACPI_BUTTON_TYPE_LID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	remove_proc_entry(ACPI_BUTTON_FILE_STATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 			  acpi_device_dir(device));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	remove_proc_entry(acpi_device_bid(device),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 			  acpi_lid_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	acpi_device_dir(device) = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	acpi_lid_dir = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	acpi_button_dir = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) /* --------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)                                 Driver Interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)    -------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) int acpi_lid_open(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	if (!lid_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	return acpi_lid_evaluate_state(lid_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) EXPORT_SYMBOL(acpi_lid_open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) static int acpi_lid_update_state(struct acpi_device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 				 bool signal_wakeup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	int state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	state = acpi_lid_evaluate_state(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	if (state < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		return state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	if (state && signal_wakeup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		acpi_pm_wakeup_event(&device->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	return acpi_lid_notify_state(device, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) static void acpi_lid_initialize_state(struct acpi_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	struct acpi_button *button = acpi_driver_data(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	switch (lid_init_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	case ACPI_BUTTON_LID_INIT_OPEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		(void)acpi_lid_notify_state(device, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	case ACPI_BUTTON_LID_INIT_METHOD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		(void)acpi_lid_update_state(device, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	case ACPI_BUTTON_LID_INIT_IGNORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	button->lid_state_initialized = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static void acpi_button_notify(struct acpi_device *device, u32 event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	struct acpi_button *button = acpi_driver_data(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	struct input_dev *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	switch (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	case ACPI_FIXED_HARDWARE_EVENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 		event = ACPI_BUTTON_NOTIFY_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	case ACPI_BUTTON_NOTIFY_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		input = button->input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		if (button->type == ACPI_BUTTON_TYPE_LID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 			if (button->lid_state_initialized)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 				acpi_lid_update_state(device, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 			int keycode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 			acpi_pm_wakeup_event(&device->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 			if (button->suspended)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 			keycode = test_bit(KEY_SLEEP, input->keybit) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 						KEY_SLEEP : KEY_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 			input_report_key(input, keycode, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 			input_sync(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 			input_report_key(input, keycode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 			input_sync(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 			acpi_bus_generate_netlink_event(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 					device->pnp.device_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 					dev_name(&device->dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 					event, ++button->pushed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 				  "Unsupported event [0x%x]\n", event));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) static int acpi_button_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	struct acpi_device *device = to_acpi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	struct acpi_button *button = acpi_driver_data(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	button->suspended = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static int acpi_button_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	struct acpi_device *device = to_acpi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	struct acpi_button *button = acpi_driver_data(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	button->suspended = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	if (button->type == ACPI_BUTTON_TYPE_LID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		button->last_state = !!acpi_lid_evaluate_state(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		button->last_time = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		acpi_lid_initialize_state(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) static int acpi_lid_input_open(struct input_dev *input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	struct acpi_device *device = input_get_drvdata(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	struct acpi_button *button = acpi_driver_data(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	button->last_state = !!acpi_lid_evaluate_state(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	button->last_time = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	acpi_lid_initialize_state(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) static int acpi_button_add(struct acpi_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	struct acpi_button *button;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	struct input_dev *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	const char *hid = acpi_device_hid(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	char *name, *class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	if (!strcmp(hid, ACPI_BUTTON_HID_LID) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	     lid_init_state == ACPI_BUTTON_LID_INIT_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	if (!button)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	device->driver_data = button;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	button->input = input = input_allocate_device();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	if (!input) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 		goto err_free_button;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	name = acpi_device_name(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	class = acpi_device_class(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	if (!strcmp(hid, ACPI_BUTTON_HID_POWER) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	    !strcmp(hid, ACPI_BUTTON_HID_POWERF)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 		button->type = ACPI_BUTTON_TYPE_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		strcpy(name, ACPI_BUTTON_DEVICE_NAME_POWER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		sprintf(class, "%s/%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	} else if (!strcmp(hid, ACPI_BUTTON_HID_SLEEP) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		   !strcmp(hid, ACPI_BUTTON_HID_SLEEPF)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		button->type = ACPI_BUTTON_TYPE_SLEEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		strcpy(name, ACPI_BUTTON_DEVICE_NAME_SLEEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		sprintf(class, "%s/%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	} else if (!strcmp(hid, ACPI_BUTTON_HID_LID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 		button->type = ACPI_BUTTON_TYPE_LID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		strcpy(name, ACPI_BUTTON_DEVICE_NAME_LID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 		sprintf(class, "%s/%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 		input->open = acpi_lid_input_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 		error = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		goto err_free_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	error = acpi_button_add_fs(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		goto err_free_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	snprintf(button->phys, sizeof(button->phys), "%s/button/input0", hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	input->name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	input->phys = button->phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	input->id.bustype = BUS_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	input->id.product = button->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	input->dev.parent = &device->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	switch (button->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	case ACPI_BUTTON_TYPE_POWER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		input_set_capability(input, EV_KEY, KEY_POWER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	case ACPI_BUTTON_TYPE_SLEEP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 		input_set_capability(input, EV_KEY, KEY_SLEEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	case ACPI_BUTTON_TYPE_LID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 		input_set_capability(input, EV_SW, SW_LID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	input_set_drvdata(input, device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	error = input_register_device(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		goto err_remove_fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	if (button->type == ACPI_BUTTON_TYPE_LID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 		 * This assumes there's only one lid device, or if there are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		 * more we only care about the last one...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 		lid_device = device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	device_init_wakeup(&device->dev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)  err_remove_fs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	acpi_button_remove_fs(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)  err_free_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	input_free_device(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)  err_free_button:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	kfree(button);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static int acpi_button_remove(struct acpi_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	struct acpi_button *button = acpi_driver_data(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	acpi_button_remove_fs(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	input_unregister_device(button->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	kfree(button);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static int param_set_lid_init_state(const char *val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 				    const struct kernel_param *kp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	i = sysfs_match_string(lid_init_state_str, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	if (i < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 		return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	lid_init_state = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	pr_info("Initial lid state set to '%s'\n", lid_init_state_str[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) static int param_get_lid_init_state(char *buf, const struct kernel_param *kp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	int i, c = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	for (i = 0; i < ARRAY_SIZE(lid_init_state_str); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 		if (i == lid_init_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 			c += sprintf(buf + c, "[%s] ", lid_init_state_str[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 			c += sprintf(buf + c, "%s ", lid_init_state_str[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	buf[c - 1] = '\n'; /* Replace the final space with a newline */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	return c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) module_param_call(lid_init_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 		  param_set_lid_init_state, param_get_lid_init_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 		  NULL, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) MODULE_PARM_DESC(lid_init_state, "Behavior for reporting LID initial state");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) static int acpi_button_register_driver(struct acpi_driver *driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	const struct dmi_system_id *dmi_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	if (lid_init_state == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 		dmi_id = dmi_first_match(dmi_lid_quirks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 		if (dmi_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 			lid_init_state = (long)dmi_id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 			lid_init_state = ACPI_BUTTON_LID_INIT_METHOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	 * Modules such as nouveau.ko and i915.ko have a link time dependency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	 * on acpi_lid_open(), and would therefore not be loadable on ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	 * capable kernels booted in non-ACPI mode if the return value of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	 * acpi_bus_register_driver() is returned from here with ACPI disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	 * when this driver is built as a module.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	if (acpi_disabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	return acpi_bus_register_driver(driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) static void acpi_button_unregister_driver(struct acpi_driver *driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	if (!acpi_disabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 		acpi_bus_unregister_driver(driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) module_driver(acpi_button_driver, acpi_button_register_driver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	       acpi_button_unregister_driver);