Lines 47-52
Link Here
|
47 |
#undef PREFIX |
47 |
#undef PREFIX |
48 |
#define PREFIX "ACPI: EC: " |
48 |
#define PREFIX "ACPI: EC: " |
49 |
|
49 |
|
|
|
50 |
/* Uncomment next line to get verbose print outs*/ |
51 |
#define DEBUG |
52 |
|
50 |
/* EC status register */ |
53 |
/* EC status register */ |
51 |
#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ |
54 |
#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ |
52 |
#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ |
55 |
#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ |
Lines 131-151
static struct acpi_ec {
Link Here
|
131 |
|
134 |
|
132 |
static inline u8 acpi_ec_read_status(struct acpi_ec *ec) |
135 |
static inline u8 acpi_ec_read_status(struct acpi_ec *ec) |
133 |
{ |
136 |
{ |
134 |
return inb(ec->command_addr); |
137 |
u8 x = inb(ec->command_addr); |
|
|
138 |
pr_debug(PREFIX "---> status = 0x%2x\n", x); |
139 |
return x; |
135 |
} |
140 |
} |
136 |
|
141 |
|
137 |
static inline u8 acpi_ec_read_data(struct acpi_ec *ec) |
142 |
static inline u8 acpi_ec_read_data(struct acpi_ec *ec) |
138 |
{ |
143 |
{ |
|
|
144 |
u8 x = inb(ec->data_addr); |
145 |
pr_debug(PREFIX "---> data = 0x%2x\n", x); |
139 |
return inb(ec->data_addr); |
146 |
return inb(ec->data_addr); |
140 |
} |
147 |
} |
141 |
|
148 |
|
142 |
static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) |
149 |
static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) |
143 |
{ |
150 |
{ |
|
|
151 |
pr_debug(PREFIX "<--- command = 0x%2x\n", command); |
144 |
outb(command, ec->command_addr); |
152 |
outb(command, ec->command_addr); |
145 |
} |
153 |
} |
146 |
|
154 |
|
147 |
static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) |
155 |
static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) |
148 |
{ |
156 |
{ |
|
|
157 |
pr_debug(PREFIX "<--- data = 0x%2x\n", data); |
149 |
outb(data, ec->data_addr); |
158 |
outb(data, ec->data_addr); |
150 |
} |
159 |
} |
151 |
|
160 |
|
Lines 175-186
static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
Link Here
|
175 |
if (acpi_ec_check_status(ec, event)) { |
184 |
if (acpi_ec_check_status(ec, event)) { |
176 |
if (event == ACPI_EC_EVENT_OBF_1) { |
185 |
if (event == ACPI_EC_EVENT_OBF_1) { |
177 |
/* miss OBF = 1 GPE, don't expect it anymore */ |
186 |
/* miss OBF = 1 GPE, don't expect it anymore */ |
178 |
printk(KERN_INFO PREFIX "missing OBF_1 confirmation," |
187 |
pr_info(PREFIX "missing OBF_1 confirmation," |
179 |
"switching to degraded mode.\n"); |
188 |
"switching to degraded mode.\n"); |
180 |
set_bit(EC_FLAGS_ONLY_IBF_GPE, &ec->flags); |
189 |
set_bit(EC_FLAGS_ONLY_IBF_GPE, &ec->flags); |
181 |
} else { |
190 |
} else { |
182 |
/* missing GPEs, switch back to poll mode */ |
191 |
/* missing GPEs, switch back to poll mode */ |
183 |
printk(KERN_INFO PREFIX "missing IBF_1 confirmations," |
192 |
pr_info(PREFIX "missing IBF_1 confirmations," |
184 |
"switch off interrupt mode.\n"); |
193 |
"switch off interrupt mode.\n"); |
185 |
clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); |
194 |
clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); |
186 |
} |
195 |
} |
Lines 194-200
static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
Link Here
|
194 |
return 0; |
203 |
return 0; |
195 |
} |
204 |
} |
196 |
} |
205 |
} |
197 |
printk(KERN_ERR PREFIX "acpi_ec_wait timeout," |
206 |
pr_err(PREFIX "acpi_ec_wait timeout," |
198 |
" status = %d, expect_event = %d\n", |
207 |
" status = %d, expect_event = %d\n", |
199 |
acpi_ec_read_status(ec), event); |
208 |
acpi_ec_read_status(ec), event); |
200 |
return -ETIME; |
209 |
return -ETIME; |
Lines 208-218
static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
Link Here
|
208 |
int result = 0; |
217 |
int result = 0; |
209 |
set_bit(EC_FLAGS_WAIT_GPE, &ec->flags); |
218 |
set_bit(EC_FLAGS_WAIT_GPE, &ec->flags); |
210 |
acpi_ec_write_cmd(ec, command); |
219 |
acpi_ec_write_cmd(ec, command); |
211 |
|
220 |
pr_debug(PREFIX "transaction start\n"); |
212 |
for (; wdata_len > 0; --wdata_len) { |
221 |
for (; wdata_len > 0; --wdata_len) { |
213 |
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll); |
222 |
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll); |
214 |
if (result) { |
223 |
if (result) { |
215 |
printk(KERN_ERR PREFIX |
224 |
pr_err(PREFIX |
216 |
"write_cmd timeout, command = %d\n", command); |
225 |
"write_cmd timeout, command = %d\n", command); |
217 |
goto end; |
226 |
goto end; |
218 |
} |
227 |
} |
Lines 223-229
static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
Link Here
|
223 |
if (!rdata_len) { |
232 |
if (!rdata_len) { |
224 |
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll); |
233 |
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll); |
225 |
if (result) { |
234 |
if (result) { |
226 |
printk(KERN_ERR PREFIX |
235 |
pr_err(PREFIX |
227 |
"finish-write timeout, command = %d\n", command); |
236 |
"finish-write timeout, command = %d\n", command); |
228 |
goto end; |
237 |
goto end; |
229 |
} |
238 |
} |
Lines 235-241
static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
Link Here
|
235 |
force_poll = 1; |
244 |
force_poll = 1; |
236 |
result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, force_poll); |
245 |
result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, force_poll); |
237 |
if (result) { |
246 |
if (result) { |
238 |
printk(KERN_ERR PREFIX "read timeout, command = %d\n", |
247 |
pr_err(PREFIX "read timeout, command = %d\n", |
239 |
command); |
248 |
command); |
240 |
goto end; |
249 |
goto end; |
241 |
} |
250 |
} |
Lines 245-250
static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
Link Here
|
245 |
*(rdata++) = acpi_ec_read_data(ec); |
254 |
*(rdata++) = acpi_ec_read_data(ec); |
246 |
} |
255 |
} |
247 |
end: |
256 |
end: |
|
|
257 |
pr_debug(PREFIX "transaction end\n"); |
248 |
return result; |
258 |
return result; |
249 |
} |
259 |
} |
250 |
|
260 |
|
Lines 273-279
static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
Link Here
|
273 |
|
283 |
|
274 |
status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0); |
284 |
status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0); |
275 |
if (status) { |
285 |
if (status) { |
276 |
printk(KERN_ERR PREFIX |
286 |
pr_err(PREFIX |
277 |
"input buffer is not empty, aborting transaction\n"); |
287 |
"input buffer is not empty, aborting transaction\n"); |
278 |
goto end; |
288 |
goto end; |
279 |
} |
289 |
} |
Lines 498-504
static u32 acpi_ec_gpe_handler(void *data)
Link Here
|
498 |
acpi_ec_gpe_query, ec); |
508 |
acpi_ec_gpe_query, ec); |
499 |
} else if (unlikely(!test_bit(EC_FLAGS_GPE_MODE, &ec->flags))) { |
509 |
} else if (unlikely(!test_bit(EC_FLAGS_GPE_MODE, &ec->flags))) { |
500 |
/* this is non-query, must be confirmation */ |
510 |
/* this is non-query, must be confirmation */ |
501 |
printk(KERN_INFO PREFIX "non-query interrupt received," |
511 |
pr_info(PREFIX "non-query interrupt received," |
502 |
" switching to interrupt mode\n"); |
512 |
" switching to interrupt mode\n"); |
503 |
set_bit(EC_FLAGS_GPE_MODE, &ec->flags); |
513 |
set_bit(EC_FLAGS_GPE_MODE, &ec->flags); |
504 |
} |
514 |
} |
Lines 701-710
static void ec_remove_handlers(struct acpi_ec *ec)
Link Here
|
701 |
{ |
711 |
{ |
702 |
if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, |
712 |
if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, |
703 |
ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) |
713 |
ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) |
704 |
printk(KERN_ERR PREFIX "failed to remove space handler\n"); |
714 |
pr_err(PREFIX "failed to remove space handler\n"); |
705 |
if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe, |
715 |
if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe, |
706 |
&acpi_ec_gpe_handler))) |
716 |
&acpi_ec_gpe_handler))) |
707 |
printk(KERN_ERR PREFIX "failed to remove gpe handler\n"); |
717 |
pr_err(PREFIX "failed to remove gpe handler\n"); |
708 |
ec->handlers_installed = 0; |
718 |
ec->handlers_installed = 0; |
709 |
} |
719 |
} |
710 |
|
720 |
|
Lines 747-755
static int acpi_ec_add(struct acpi_device *device)
Link Here
|
747 |
first_ec = ec; |
757 |
first_ec = ec; |
748 |
acpi_driver_data(device) = ec; |
758 |
acpi_driver_data(device) = ec; |
749 |
acpi_ec_add_fs(device); |
759 |
acpi_ec_add_fs(device); |
750 |
printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", |
760 |
pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", |
751 |
ec->gpe, ec->command_addr, ec->data_addr); |
761 |
ec->gpe, ec->command_addr, ec->data_addr); |
752 |
printk(KERN_INFO PREFIX "driver started in %s mode\n", |
762 |
pr_info(PREFIX "driver started in %s mode\n", |
753 |
(test_bit(EC_FLAGS_GPE_MODE, &ec->flags))?"interrupt":"poll"); |
763 |
(test_bit(EC_FLAGS_GPE_MODE, &ec->flags))?"interrupt":"poll"); |
754 |
return 0; |
764 |
return 0; |
755 |
} |
765 |
} |
Lines 875-881
int __init acpi_ec_ecdt_probe(void)
Link Here
|
875 |
status = acpi_get_table(ACPI_SIG_ECDT, 1, |
885 |
status = acpi_get_table(ACPI_SIG_ECDT, 1, |
876 |
(struct acpi_table_header **)&ecdt_ptr); |
886 |
(struct acpi_table_header **)&ecdt_ptr); |
877 |
if (ACPI_SUCCESS(status)) { |
887 |
if (ACPI_SUCCESS(status)) { |
878 |
printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n"); |
888 |
pr_info(PREFIX "EC description table is found, configuring boot EC\n"); |
879 |
boot_ec->command_addr = ecdt_ptr->control.address; |
889 |
boot_ec->command_addr = ecdt_ptr->control.address; |
880 |
boot_ec->data_addr = ecdt_ptr->data.address; |
890 |
boot_ec->data_addr = ecdt_ptr->data.address; |
881 |
boot_ec->gpe = ecdt_ptr->gpe; |
891 |
boot_ec->gpe = ecdt_ptr->gpe; |