2390 lines · 61.4 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-or-later/* *  ec.c - ACPI Embedded Controller Driver (v3) * *  Copyright (C) 2001-2015 Intel Corporation *    Author: 2014, 2015 Lv Zheng <lv.zheng@intel.com> *            2006, 2007 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> *            2006       Denis Sadykov <denis.m.sadykov@intel.com> *            2004       Luming Yu <luming.yu@intel.com> *            2001, 2002 Andy Grover <andrew.grover@intel.com> *            2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> *  Copyright (C) 2008      Alexey Starikovskiy <astarikovskiy@suse.de> */ /* Uncomment next line to get verbose printout *//* #define DEBUG */#define pr_fmt(fmt) "ACPI: EC: " fmt #include <linux/kernel.h>#include <linux/module.h>#include <linux/init.h>#include <linux/types.h>#include <linux/delay.h>#include <linux/interrupt.h>#include <linux/list.h>#include <linux/platform_device.h>#include <linux/printk.h>#include <linux/spinlock.h>#include <linux/slab.h>#include <linux/string.h>#include <linux/suspend.h>#include <linux/acpi.h>#include <linux/dmi.h>#include <asm/io.h> #include "internal.h" /* EC status register */#define ACPI_EC_FLAG_OBF	0x01	/* Output buffer full */#define ACPI_EC_FLAG_IBF	0x02	/* Input buffer full */#define ACPI_EC_FLAG_CMD	0x08	/* Input buffer contains a command */#define ACPI_EC_FLAG_BURST	0x10	/* burst mode */#define ACPI_EC_FLAG_SCI	0x20	/* EC-SCI occurred */ /* * The SCI_EVT clearing timing is not defined by the ACPI specification. * This leads to lots of practical timing issues for the host EC driver. * The following variations are defined (from the target EC firmware's * perspective): * STATUS: After indicating SCI_EVT edge triggered IRQ to the host, the *         target can clear SCI_EVT at any time so long as the host can see *         the indication by reading the status register (EC_SC). So the *         host should re-check SCI_EVT after the first time the SCI_EVT *         indication is seen, which is the same time the query request *         (QR_EC) is written to the command register (EC_CMD). SCI_EVT set *         at any later time could indicate another event. Normally such *         kind of EC firmware has implemented an event queue and will *         return 0x00 to indicate "no outstanding event". * QUERY: After seeing the query request (QR_EC) written to the command *        register (EC_CMD) by the host and having prepared the responding *        event value in the data register (EC_DATA), the target can safely *        clear SCI_EVT because the target can confirm that the current *        event is being handled by the host. The host then should check *        SCI_EVT right after reading the event response from the data *        register (EC_DATA). * EVENT: After seeing the event response read from the data register *        (EC_DATA) by the host, the target can clear SCI_EVT. As the *        target requires time to notice the change in the data register *        (EC_DATA), the host may be required to wait additional guarding *        time before checking the SCI_EVT again. Such guarding may not be *        necessary if the host is notified via another IRQ. */#define ACPI_EC_EVT_TIMING_STATUS	0x00#define ACPI_EC_EVT_TIMING_QUERY	0x01#define ACPI_EC_EVT_TIMING_EVENT	0x02 /* EC commands */enum ec_command {	ACPI_EC_COMMAND_READ = 0x80,	ACPI_EC_COMMAND_WRITE = 0x81,	ACPI_EC_BURST_ENABLE = 0x82,	ACPI_EC_BURST_DISABLE = 0x83,	ACPI_EC_COMMAND_QUERY = 0x84,}; #define ACPI_EC_DELAY		500	/* Wait 500ms max. during EC ops */#define ACPI_EC_UDELAY_GLK	1000	/* Wait 1ms max. to get global lock */#define ACPI_EC_UDELAY_POLL	550	/* Wait 1ms for EC transaction polling */#define ACPI_EC_CLEAR_MAX	100	/* Maximum number of events to query					 * when trying to clear the EC */#define ACPI_EC_MAX_QUERIES	16	/* Maximum number of parallel queries */ enum {	EC_FLAGS_QUERY_ENABLED,		/* Query is enabled */	EC_FLAGS_EVENT_HANDLER_INSTALLED,	/* Event handler installed */	EC_FLAGS_EC_HANDLER_INSTALLED,	/* OpReg handler installed */	EC_FLAGS_EC_REG_CALLED,		/* OpReg ACPI _REG method called */	EC_FLAGS_QUERY_METHODS_INSTALLED, /* _Qxx handlers installed */	EC_FLAGS_STARTED,		/* Driver is started */	EC_FLAGS_STOPPED,		/* Driver is stopped */	EC_FLAGS_EVENTS_MASKED,		/* Events masked */}; #define ACPI_EC_COMMAND_POLL		0x01 /* Available for command byte */#define ACPI_EC_COMMAND_COMPLETE	0x02 /* Completed last byte */ /* ec.c is compiled in acpi namespace so this shows up as acpi.ec_delay param */static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY;module_param(ec_delay, uint, 0644);MODULE_PARM_DESC(ec_delay, "Timeout(ms) waited until an EC command completes"); static unsigned int ec_max_queries __read_mostly = ACPI_EC_MAX_QUERIES;module_param(ec_max_queries, uint, 0644);MODULE_PARM_DESC(ec_max_queries, "Maximum parallel _Qxx evaluations"); static bool ec_busy_polling __read_mostly;module_param(ec_busy_polling, bool, 0644);MODULE_PARM_DESC(ec_busy_polling, "Use busy polling to advance EC transaction"); static unsigned int ec_polling_guard __read_mostly = ACPI_EC_UDELAY_POLL;module_param(ec_polling_guard, uint, 0644);MODULE_PARM_DESC(ec_polling_guard, "Guard time(us) between EC accesses in polling modes"); static unsigned int ec_event_clearing __read_mostly = ACPI_EC_EVT_TIMING_QUERY; /* * If the number of false interrupts per one transaction exceeds * this threshold, will think there is a GPE storm happened and * will disable the GPE for normal transaction. */static unsigned int ec_storm_threshold  __read_mostly = 8;module_param(ec_storm_threshold, uint, 0644);MODULE_PARM_DESC(ec_storm_threshold, "Maxim false GPE numbers not considered as GPE storm"); static bool ec_freeze_events __read_mostly;module_param(ec_freeze_events, bool, 0644);MODULE_PARM_DESC(ec_freeze_events, "Disabling event handling during suspend/resume"); static bool ec_no_wakeup __read_mostly;module_param(ec_no_wakeup, bool, 0644);MODULE_PARM_DESC(ec_no_wakeup, "Do not wake up from suspend-to-idle"); struct acpi_ec_query_handler {	struct list_head node;	acpi_ec_query_func func;	acpi_handle handle;	void *data;	u8 query_bit;	struct kref kref;}; struct transaction {	const u8 *wdata;	u8 *rdata;	unsigned short irq_count;	u8 command;	u8 wi;	u8 ri;	u8 wlen;	u8 rlen;	u8 flags;}; struct acpi_ec_query {	struct transaction transaction;	struct work_struct work;	struct acpi_ec_query_handler *handler;	struct acpi_ec *ec;}; static int acpi_ec_submit_query(struct acpi_ec *ec);static void advance_transaction(struct acpi_ec *ec, bool interrupt);static void acpi_ec_event_handler(struct work_struct *work); struct acpi_ec *first_ec;EXPORT_SYMBOL(first_ec); static struct acpi_ec *boot_ec;static bool boot_ec_is_ecdt;static struct workqueue_struct *ec_wq;static struct workqueue_struct *ec_query_wq; static int EC_FLAGS_CORRECT_ECDT; /* Needs ECDT port address correction */static int EC_FLAGS_TRUST_DSDT_GPE; /* Needs DSDT GPE as correction setting */static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */ /* -------------------------------------------------------------------------- *                           Logging/Debugging * -------------------------------------------------------------------------- */ /* * Splitters used by the developers to track the boundary of the EC * handling processes. */#ifdef DEBUG#define EC_DBG_SEP	" "#define EC_DBG_DRV	"+++++"#define EC_DBG_STM	"====="#define EC_DBG_REQ	"*****"#define EC_DBG_EVT	"#####"#else#define EC_DBG_SEP	""#define EC_DBG_DRV#define EC_DBG_STM#define EC_DBG_REQ#define EC_DBG_EVT#endif #define ec_log_raw(fmt, ...) \	pr_info(fmt "\n", ##__VA_ARGS__)#define ec_dbg_raw(fmt, ...) \	pr_debug(fmt "\n", ##__VA_ARGS__)#define ec_log(filter, fmt, ...) \	ec_log_raw(filter EC_DBG_SEP fmt EC_DBG_SEP filter, ##__VA_ARGS__)#define ec_dbg(filter, fmt, ...) \	ec_dbg_raw(filter EC_DBG_SEP fmt EC_DBG_SEP filter, ##__VA_ARGS__) #define ec_log_drv(fmt, ...) \	ec_log(EC_DBG_DRV, fmt, ##__VA_ARGS__)#define ec_dbg_drv(fmt, ...) \	ec_dbg(EC_DBG_DRV, fmt, ##__VA_ARGS__)#define ec_dbg_stm(fmt, ...) \	ec_dbg(EC_DBG_STM, fmt, ##__VA_ARGS__)#define ec_dbg_req(fmt, ...) \	ec_dbg(EC_DBG_REQ, fmt, ##__VA_ARGS__)#define ec_dbg_evt(fmt, ...) \	ec_dbg(EC_DBG_EVT, fmt, ##__VA_ARGS__)#define ec_dbg_ref(ec, fmt, ...) \	ec_dbg_raw("%lu: " fmt, ec->reference_count, ## __VA_ARGS__) /* -------------------------------------------------------------------------- *                           Device Flags * -------------------------------------------------------------------------- */ static bool acpi_ec_started(struct acpi_ec *ec){	return test_bit(EC_FLAGS_STARTED, &ec->flags) &&	       !test_bit(EC_FLAGS_STOPPED, &ec->flags);} static bool acpi_ec_event_enabled(struct acpi_ec *ec){	/*	 * There is an OSPM early stage logic. During the early stages	 * (boot/resume), OSPMs shouldn't enable the event handling, only	 * the EC transactions are allowed to be performed.	 */	if (!test_bit(EC_FLAGS_QUERY_ENABLED, &ec->flags))		return false;	/*	 * However, disabling the event handling is experimental for late	 * stage (suspend), and is controlled by the boot parameter of	 * "ec_freeze_events":	 * 1. true:  The EC event handling is disabled before entering	 *           the noirq stage.	 * 2. false: The EC event handling is automatically disabled as	 *           soon as the EC driver is stopped.	 */	if (ec_freeze_events)		return acpi_ec_started(ec);	else		return test_bit(EC_FLAGS_STARTED, &ec->flags);} static bool acpi_ec_flushed(struct acpi_ec *ec){	return ec->reference_count == 1;} /* -------------------------------------------------------------------------- *                           EC Registers * -------------------------------------------------------------------------- */ static inline u8 acpi_ec_read_status(struct acpi_ec *ec){	u8 x = inb(ec->command_addr); 	ec_dbg_raw("EC_SC(R) = 0x%2.2x "		   "SCI_EVT=%d BURST=%d CMD=%d IBF=%d OBF=%d",		   x,		   !!(x & ACPI_EC_FLAG_SCI),		   !!(x & ACPI_EC_FLAG_BURST),		   !!(x & ACPI_EC_FLAG_CMD),		   !!(x & ACPI_EC_FLAG_IBF),		   !!(x & ACPI_EC_FLAG_OBF));	return x;} static inline u8 acpi_ec_read_data(struct acpi_ec *ec){	u8 x = inb(ec->data_addr); 	ec->timestamp = jiffies;	ec_dbg_raw("EC_DATA(R) = 0x%2.2x", x);	return x;} static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command){	ec_dbg_raw("EC_SC(W) = 0x%2.2x", command);	outb(command, ec->command_addr);	ec->timestamp = jiffies;} static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data){	ec_dbg_raw("EC_DATA(W) = 0x%2.2x", data);	outb(data, ec->data_addr);	ec->timestamp = jiffies;} #if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)static const char *acpi_ec_cmd_string(u8 cmd){	switch (cmd) {	case 0x80:		return "RD_EC";	case 0x81:		return "WR_EC";	case 0x82:		return "BE_EC";	case 0x83:		return "BD_EC";	case 0x84:		return "QR_EC";	}	return "UNKNOWN";}#else#define acpi_ec_cmd_string(cmd)		"UNDEF"#endif /* -------------------------------------------------------------------------- *                           GPE Registers * -------------------------------------------------------------------------- */ static inline bool acpi_ec_gpe_status_set(struct acpi_ec *ec){	acpi_event_status gpe_status = 0; 	(void)acpi_get_gpe_status(NULL, ec->gpe, &gpe_status);	return !!(gpe_status & ACPI_EVENT_FLAG_STATUS_SET);} static inline void acpi_ec_enable_gpe(struct acpi_ec *ec, bool open){	if (open)		acpi_enable_gpe(NULL, ec->gpe);	else {		BUG_ON(ec->reference_count < 1);		acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE);	}	if (acpi_ec_gpe_status_set(ec)) {		/*		 * On some platforms, EN=1 writes cannot trigger GPE. So		 * software need to manually trigger a pseudo GPE event on		 * EN=1 writes.		 */		ec_dbg_raw("Polling quirk");		advance_transaction(ec, false);	}} static inline void acpi_ec_disable_gpe(struct acpi_ec *ec, bool close){	if (close)		acpi_disable_gpe(NULL, ec->gpe);	else {		BUG_ON(ec->reference_count < 1);		acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE);	}} /* -------------------------------------------------------------------------- *                           Transaction Management * -------------------------------------------------------------------------- */ static void acpi_ec_submit_request(struct acpi_ec *ec){	ec->reference_count++;	if (test_bit(EC_FLAGS_EVENT_HANDLER_INSTALLED, &ec->flags) &&	    ec->gpe >= 0 && ec->reference_count == 1)		acpi_ec_enable_gpe(ec, true);} static void acpi_ec_complete_request(struct acpi_ec *ec){	bool flushed = false; 	ec->reference_count--;	if (test_bit(EC_FLAGS_EVENT_HANDLER_INSTALLED, &ec->flags) &&	    ec->gpe >= 0 && ec->reference_count == 0)		acpi_ec_disable_gpe(ec, true);	flushed = acpi_ec_flushed(ec);	if (flushed)		wake_up(&ec->wait);} static void acpi_ec_mask_events(struct acpi_ec *ec){	if (!test_bit(EC_FLAGS_EVENTS_MASKED, &ec->flags)) {		if (ec->gpe >= 0)			acpi_ec_disable_gpe(ec, false);		else			disable_irq_nosync(ec->irq); 		ec_dbg_drv("Polling enabled");		set_bit(EC_FLAGS_EVENTS_MASKED, &ec->flags);	}} static void acpi_ec_unmask_events(struct acpi_ec *ec){	if (test_bit(EC_FLAGS_EVENTS_MASKED, &ec->flags)) {		clear_bit(EC_FLAGS_EVENTS_MASKED, &ec->flags);		if (ec->gpe >= 0)			acpi_ec_enable_gpe(ec, false);		else			enable_irq(ec->irq); 		ec_dbg_drv("Polling disabled");	}} /* * acpi_ec_submit_flushable_request() - Increase the reference count unless *                                      the flush operation is not in *                                      progress * @ec: the EC device * * This function must be used before taking a new action that should hold * the reference count.  If this function returns false, then the action * must be discarded or it will prevent the flush operation from being * completed. */static bool acpi_ec_submit_flushable_request(struct acpi_ec *ec){	if (!acpi_ec_started(ec))		return false;	acpi_ec_submit_request(ec);	return true;} static void acpi_ec_submit_event(struct acpi_ec *ec){	/*	 * It is safe to mask the events here, because acpi_ec_close_event()	 * will run at least once after this.	 */	acpi_ec_mask_events(ec);	if (!acpi_ec_event_enabled(ec))		return; 	if (ec->event_state != EC_EVENT_READY)		return; 	ec_dbg_evt("Command(%s) submitted/blocked",		   acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY)); 	ec->event_state = EC_EVENT_IN_PROGRESS;	/*	 * If events_to_process is greater than 0 at this point, the while ()	 * loop in acpi_ec_event_handler() is still running and incrementing	 * events_to_process will cause it to invoke acpi_ec_submit_query() once	 * more, so it is not necessary to queue up the event work to start the	 * same loop again.	 */	if (ec->events_to_process++ > 0)		return; 	ec->events_in_progress++;	queue_work(ec_wq, &ec->work);} static void acpi_ec_complete_event(struct acpi_ec *ec){	if (ec->event_state == EC_EVENT_IN_PROGRESS)		ec->event_state = EC_EVENT_COMPLETE;} static void acpi_ec_close_event(struct acpi_ec *ec){	if (ec->event_state != EC_EVENT_READY)		ec_dbg_evt("Command(%s) unblocked",			   acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY)); 	ec->event_state = EC_EVENT_READY;	acpi_ec_unmask_events(ec);} static inline void __acpi_ec_enable_event(struct acpi_ec *ec){	if (!test_and_set_bit(EC_FLAGS_QUERY_ENABLED, &ec->flags))		ec_log_drv("event unblocked");	/*	 * Unconditionally invoke this once after enabling the event	 * handling mechanism to detect the pending events.	 */	advance_transaction(ec, false);}

Lines 1–500 of 2390.