aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/ec.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 97dc16155a55..987b967c7467 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -26,6 +26,9 @@
26 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 26 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27 */ 27 */
28 28
29/* Uncomment next line to get verbose print outs*/
30/* #define DEBUG */
31
29#include <linux/kernel.h> 32#include <linux/kernel.h>
30#include <linux/module.h> 33#include <linux/module.h>
31#include <linux/init.h> 34#include <linux/init.h>
@@ -47,9 +50,6 @@
47#undef PREFIX 50#undef PREFIX
48#define PREFIX "ACPI: EC: " 51#define PREFIX "ACPI: EC: "
49 52
50/* Uncomment next line to get verbose print outs*/
51/* #define DEBUG */
52
53/* EC status register */ 53/* EC status register */
54#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ 54#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */
55#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ 55#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */
@@ -82,6 +82,7 @@ enum {
82 EC_FLAGS_ADDRESS, /* Address is being written */ 82 EC_FLAGS_ADDRESS, /* Address is being written */
83 EC_FLAGS_NO_WDATA_GPE, /* Don't expect WDATA GPE event */ 83 EC_FLAGS_NO_WDATA_GPE, /* Don't expect WDATA GPE event */
84 EC_FLAGS_WDATA, /* Data is being written */ 84 EC_FLAGS_WDATA, /* Data is being written */
85 EC_FLAGS_NO_OBF1_GPE, /* Don't expect GPE before read */
85}; 86};
86 87
87static int acpi_ec_remove(struct acpi_device *device, int type); 88static int acpi_ec_remove(struct acpi_device *device, int type);
@@ -138,26 +139,26 @@ static struct acpi_ec {
138static inline u8 acpi_ec_read_status(struct acpi_ec *ec) 139static inline u8 acpi_ec_read_status(struct acpi_ec *ec)
139{ 140{
140 u8 x = inb(ec->command_addr); 141 u8 x = inb(ec->command_addr);
141 pr_debug(PREFIX "---> status = 0x%2x\n", x); 142 pr_debug(PREFIX "---> status = 0x%2.2x\n", x);
142 return x; 143 return x;
143} 144}
144 145
145static inline u8 acpi_ec_read_data(struct acpi_ec *ec) 146static inline u8 acpi_ec_read_data(struct acpi_ec *ec)
146{ 147{
147 u8 x = inb(ec->data_addr); 148 u8 x = inb(ec->data_addr);
148 pr_debug(PREFIX "---> data = 0x%2x\n", x); 149 pr_debug(PREFIX "---> data = 0x%2.2x\n", x);
149 return inb(ec->data_addr); 150 return inb(ec->data_addr);
150} 151}
151 152
152static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) 153static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command)
153{ 154{
154 pr_debug(PREFIX "<--- command = 0x%2x\n", command); 155 pr_debug(PREFIX "<--- command = 0x%2.2x\n", command);
155 outb(command, ec->command_addr); 156 outb(command, ec->command_addr);
156} 157}
157 158
158static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) 159static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
159{ 160{
160 pr_debug(PREFIX "<--- data = 0x%2x\n", data); 161 pr_debug(PREFIX "<--- data = 0x%2.2x\n", data);
161 outb(data, ec->data_addr); 162 outb(data, ec->data_addr);
162} 163}
163 164
@@ -179,6 +180,10 @@ static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event)
179static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) 180static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
180{ 181{
181 int ret = 0; 182 int ret = 0;
183
184 if (unlikely(event == ACPI_EC_EVENT_OBF_1 &&
185 test_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags)))
186 force_poll = 1;
182 if (unlikely(test_bit(EC_FLAGS_ADDRESS, &ec->flags) && 187 if (unlikely(test_bit(EC_FLAGS_ADDRESS, &ec->flags) &&
183 test_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags))) 188 test_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags)))
184 force_poll = 1; 189 force_poll = 1;
@@ -192,7 +197,12 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
192 goto end; 197 goto end;
193 clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); 198 clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
194 if (acpi_ec_check_status(ec, event)) { 199 if (acpi_ec_check_status(ec, event)) {
195 if (test_bit(EC_FLAGS_ADDRESS, &ec->flags)) { 200 if (event == ACPI_EC_EVENT_OBF_1) {
201 /* miss OBF_1 GPE, don't expect it */
202 pr_info(PREFIX "missing OBF confirmation, "
203 "don't expect it any longer.\n");
204 set_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags);
205 } else if (test_bit(EC_FLAGS_ADDRESS, &ec->flags)) {
196 /* miss address GPE, don't expect it anymore */ 206 /* miss address GPE, don't expect it anymore */
197 pr_info(PREFIX "missing address confirmation, " 207 pr_info(PREFIX "missing address confirmation, "
198 "don't expect it any longer.\n"); 208 "don't expect it any longer.\n");