1 // SPDX-License-Identifier: GPL-2.0-only
3 * Intel ECLite opregion driver for talking to ECLite firmware running on
4 * Intel Integrated Sensor Hub (ISH) using ISH Transport Protocol (ISHTP)
6 * Copyright (c) 2021, Intel Corporation.
9 #include <linux/acpi.h>
10 #include <linux/bitops.h>
11 #include <linux/device.h>
12 #include <linux/errno.h>
13 #include <linux/intel-ish-client-if.h>
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/mutex.h>
17 #include <linux/slab.h>
18 #include <linux/suspend.h>
19 #include <linux/types.h>
20 #include <linux/uuid.h>
21 #include <linux/uaccess.h>
23 #define ECLITE_DATA_OPREGION_ID 0x9E
24 #define ECLITE_CMD_OPREGION_ID 0x9F
26 #define ECL_MSG_DATA 0x1
27 #define ECL_MSG_EVENT 0x2
29 #define ECL_ISH_READ 0x1
30 #define ECL_ISH_WRITE 0x2
31 #define ECL_ISH_HEADER_VERSION 0
33 #define ECL_CL_RX_RING_SIZE 16
34 #define ECL_CL_TX_RING_SIZE 8
36 #define ECL_DATA_OPR_BUFLEN 384
37 #define ECL_EVENTS_NOTIFY 333
39 #define cmd_opr_offsetof(element) offsetof(struct opregion_cmd, element)
40 #define cl_data_to_dev(opr_dev) ishtp_device((opr_dev)->cl_device)
43 #define BITS_TO_BYTES(x) ((x) / 8)
50 unsigned int event_id
;
53 struct opregion_data
{
54 char data
[ECL_DATA_OPR_BUFLEN
];
57 struct opregion_context
{
58 struct opregion_cmd cmd_area
;
59 struct opregion_data data_area
;
62 struct ecl_message_header
{
63 unsigned int version
:2;
64 unsigned int data_type
:2;
65 unsigned int request_type
:2;
66 unsigned int offset
:9;
67 unsigned int data_len
:9;
72 struct ecl_message_header header
;
73 char payload
[ECL_DATA_OPR_BUFLEN
];
76 struct ishtp_opregion_dev
{
77 struct opregion_context opr_context
;
78 struct ishtp_cl
*ecl_ishtp_cl
;
79 struct ishtp_cl_device
*cl_device
;
80 struct ishtp_fw_client
*fw_client
;
81 struct ishtp_cl_rb
*rb
;
82 struct acpi_device
*adev
;
83 unsigned int dsm_event_id
;
84 unsigned int ish_link_ready
;
85 unsigned int ish_read_done
;
86 unsigned int acpi_init_done
;
87 wait_queue_head_t read_wait
;
88 struct work_struct event_work
;
89 struct work_struct reset_work
;
90 /* lock for opregion context */
95 /* eclite ishtp client UUID: 6a19cc4b-d760-4de3-b14d-f25ebd0fbcd9 */
96 static const struct ishtp_device_id ecl_ishtp_id_table
[] = {
97 { .guid
= GUID_INIT(0x6a19cc4b, 0xd760, 0x4de3,
98 0xb1, 0x4d, 0xf2, 0x5e, 0xbd, 0xf, 0xbc, 0xd9), },
101 MODULE_DEVICE_TABLE(ishtp
, ecl_ishtp_id_table
);
103 /* ACPI DSM UUID: 91d936a7-1f01-49c6-a6b4-72f00ad8d8a5 */
104 static const guid_t ecl_acpi_guid
=
105 GUID_INIT(0x91d936a7, 0x1f01, 0x49c6, 0xa6,
106 0xb4, 0x72, 0xf0, 0x0a, 0xd8, 0xd8, 0xa5);
109 * ecl_ish_cl_read() - Read data from eclite FW
111 * @opr_dev: pointer to opregion device
113 * This function issues a read request to eclite FW and waits until it
114 * receives a response. When response is received the read data is copied to
117 static int ecl_ish_cl_read(struct ishtp_opregion_dev
*opr_dev
)
119 struct ecl_message_header header
;
122 if (!opr_dev
->ish_link_ready
)
125 if ((opr_dev
->opr_context
.cmd_area
.offset
+
126 opr_dev
->opr_context
.cmd_area
.length
) > ECL_DATA_OPR_BUFLEN
) {
130 header
.version
= ECL_ISH_HEADER_VERSION
;
131 header
.data_type
= ECL_MSG_DATA
;
132 header
.request_type
= ECL_ISH_READ
;
133 header
.offset
= opr_dev
->opr_context
.cmd_area
.offset
;
134 header
.data_len
= opr_dev
->opr_context
.cmd_area
.length
;
135 header
.event
= opr_dev
->opr_context
.cmd_area
.event_id
;
136 len
= sizeof(header
);
138 opr_dev
->ish_read_done
= false;
139 rv
= ishtp_cl_send(opr_dev
->ecl_ishtp_cl
, (uint8_t *)&header
, len
);
141 dev_err(cl_data_to_dev(opr_dev
), "ish-read : send failed\n");
145 dev_dbg(cl_data_to_dev(opr_dev
),
146 "[ish_rd] Req: off : %x, len : %x\n",
150 rv
= wait_event_interruptible_timeout(opr_dev
->read_wait
,
151 opr_dev
->ish_read_done
,
154 dev_err(cl_data_to_dev(opr_dev
),
155 "[ish_rd] No response from firmware\n");
163 * ecl_ish_cl_write() - This function writes data to eclite FW.
165 * @opr_dev: pointer to opregion device
167 * This function writes data to eclite FW.
169 static int ecl_ish_cl_write(struct ishtp_opregion_dev
*opr_dev
)
171 struct ecl_message message
;
174 if (!opr_dev
->ish_link_ready
)
177 if ((opr_dev
->opr_context
.cmd_area
.offset
+
178 opr_dev
->opr_context
.cmd_area
.length
) > ECL_DATA_OPR_BUFLEN
) {
182 message
.header
.version
= ECL_ISH_HEADER_VERSION
;
183 message
.header
.data_type
= ECL_MSG_DATA
;
184 message
.header
.request_type
= ECL_ISH_WRITE
;
185 message
.header
.offset
= opr_dev
->opr_context
.cmd_area
.offset
;
186 message
.header
.data_len
= opr_dev
->opr_context
.cmd_area
.length
;
187 message
.header
.event
= opr_dev
->opr_context
.cmd_area
.event_id
;
188 len
= sizeof(struct ecl_message_header
) + message
.header
.data_len
;
190 memcpy(message
.payload
,
191 opr_dev
->opr_context
.data_area
.data
+ message
.header
.offset
,
192 message
.header
.data_len
);
194 dev_dbg(cl_data_to_dev(opr_dev
),
195 "[ish_wr] off : %x, len : %x\n",
196 message
.header
.offset
,
197 message
.header
.data_len
);
199 return ishtp_cl_send(opr_dev
->ecl_ishtp_cl
, (uint8_t *)&message
, len
);
203 ecl_opregion_cmd_handler(u32 function
, acpi_physical_address address
,
204 u32 bits
, u64
*value64
,
205 void *handler_context
, void *region_context
)
207 struct ishtp_opregion_dev
*opr_dev
;
208 struct opregion_cmd
*cmd
;
209 acpi_status status
= AE_OK
;
211 if (!region_context
|| !value64
)
212 return AE_BAD_PARAMETER
;
214 if (function
== ACPI_READ
)
217 opr_dev
= (struct ishtp_opregion_dev
*)region_context
;
219 mutex_lock(&opr_dev
->lock
);
221 cmd
= &opr_dev
->opr_context
.cmd_area
;
224 case cmd_opr_offsetof(command
):
225 cmd
->command
= (u32
)*value64
;
227 if (cmd
->command
== ECL_ISH_READ
)
228 status
= ecl_ish_cl_read(opr_dev
);
229 else if (cmd
->command
== ECL_ISH_WRITE
)
230 status
= ecl_ish_cl_write(opr_dev
);
234 case cmd_opr_offsetof(offset
):
235 cmd
->offset
= (u32
)*value64
;
237 case cmd_opr_offsetof(length
):
238 cmd
->length
= (u32
)*value64
;
240 case cmd_opr_offsetof(event_id
):
241 cmd
->event_id
= (u32
)*value64
;
247 mutex_unlock(&opr_dev
->lock
);
253 ecl_opregion_data_handler(u32 function
, acpi_physical_address address
,
254 u32 bits
, u64
*value64
,
255 void *handler_context
, void *region_context
)
257 struct ishtp_opregion_dev
*opr_dev
;
258 unsigned int bytes
= BITS_TO_BYTES(bits
);
261 if (!region_context
|| !value64
)
262 return AE_BAD_PARAMETER
;
264 if (address
+ bytes
> ECL_DATA_OPR_BUFLEN
)
265 return AE_BAD_PARAMETER
;
267 opr_dev
= (struct ishtp_opregion_dev
*)region_context
;
269 mutex_lock(&opr_dev
->lock
);
271 data_addr
= &opr_dev
->opr_context
.data_area
.data
[address
];
273 if (function
== ACPI_READ
) {
274 memcpy(value64
, data_addr
, bytes
);
275 } else if (function
== ACPI_WRITE
) {
276 memcpy(data_addr
, value64
, bytes
);
278 mutex_unlock(&opr_dev
->lock
);
279 return AE_BAD_PARAMETER
;
282 mutex_unlock(&opr_dev
->lock
);
287 static int acpi_find_eclite_device(struct ishtp_opregion_dev
*opr_dev
)
289 struct acpi_device
*adev
;
291 /* Find ECLite device and save reference */
292 adev
= acpi_dev_get_first_match_dev("INTC1035", NULL
, -1);
294 dev_err(cl_data_to_dev(opr_dev
), "eclite ACPI device not found\n");
298 opr_dev
->adev
= adev
;
303 static int acpi_opregion_init(struct ishtp_opregion_dev
*opr_dev
)
307 status
= acpi_install_address_space_handler(opr_dev
->adev
->handle
,
308 ECLITE_CMD_OPREGION_ID
,
309 ecl_opregion_cmd_handler
,
311 if (ACPI_FAILURE(status
)) {
312 dev_err(cl_data_to_dev(opr_dev
),
313 "cmd space handler install failed\n");
317 status
= acpi_install_address_space_handler(opr_dev
->adev
->handle
,
318 ECLITE_DATA_OPREGION_ID
,
319 ecl_opregion_data_handler
,
321 if (ACPI_FAILURE(status
)) {
322 dev_err(cl_data_to_dev(opr_dev
),
323 "data space handler install failed\n");
325 acpi_remove_address_space_handler(opr_dev
->adev
->handle
,
326 ECLITE_CMD_OPREGION_ID
,
327 ecl_opregion_cmd_handler
);
330 opr_dev
->acpi_init_done
= true;
332 dev_dbg(cl_data_to_dev(opr_dev
), "Opregion handlers are installed\n");
337 static void acpi_opregion_deinit(struct ishtp_opregion_dev
*opr_dev
)
339 acpi_remove_address_space_handler(opr_dev
->adev
->handle
,
340 ECLITE_CMD_OPREGION_ID
,
341 ecl_opregion_cmd_handler
);
343 acpi_remove_address_space_handler(opr_dev
->adev
->handle
,
344 ECLITE_DATA_OPREGION_ID
,
345 ecl_opregion_data_handler
);
346 opr_dev
->acpi_init_done
= false;
349 static void ecl_acpi_invoke_dsm(struct work_struct
*work
)
351 struct ishtp_opregion_dev
*opr_dev
;
352 union acpi_object
*obj
;
354 opr_dev
= container_of(work
, struct ishtp_opregion_dev
, event_work
);
355 if (!opr_dev
->acpi_init_done
)
358 obj
= acpi_evaluate_dsm(opr_dev
->adev
->handle
, &ecl_acpi_guid
, 0,
359 opr_dev
->dsm_event_id
, NULL
);
361 dev_warn(cl_data_to_dev(opr_dev
), "_DSM fn call failed\n");
365 dev_dbg(cl_data_to_dev(opr_dev
), "Exec DSM function code: %d success\n",
366 opr_dev
->dsm_event_id
);
371 static void ecl_ish_process_rx_data(struct ishtp_opregion_dev
*opr_dev
)
373 struct ecl_message
*message
=
374 (struct ecl_message
*)opr_dev
->rb
->buffer
.data
;
376 dev_dbg(cl_data_to_dev(opr_dev
),
377 "[ish_rd] Resp: off : %x, len : %x\n",
378 message
->header
.offset
,
379 message
->header
.data_len
);
381 if ((message
->header
.offset
+ message
->header
.data_len
) >
382 ECL_DATA_OPR_BUFLEN
) {
386 memcpy(opr_dev
->opr_context
.data_area
.data
+ message
->header
.offset
,
387 message
->payload
, message
->header
.data_len
);
389 opr_dev
->ish_read_done
= true;
390 wake_up_interruptible(&opr_dev
->read_wait
);
393 static void ecl_ish_process_rx_event(struct ishtp_opregion_dev
*opr_dev
)
395 struct ecl_message_header
*header
=
396 (struct ecl_message_header
*)opr_dev
->rb
->buffer
.data
;
398 dev_dbg(cl_data_to_dev(opr_dev
),
399 "[ish_ev] Evt received: %8x\n", header
->event
);
401 opr_dev
->dsm_event_id
= header
->event
;
402 schedule_work(&opr_dev
->event_work
);
405 static int ecl_ish_cl_enable_events(struct ishtp_opregion_dev
*opr_dev
,
408 struct ecl_message message
;
411 message
.header
.version
= ECL_ISH_HEADER_VERSION
;
412 message
.header
.data_type
= ECL_MSG_DATA
;
413 message
.header
.request_type
= ECL_ISH_WRITE
;
414 message
.header
.offset
= ECL_EVENTS_NOTIFY
;
415 message
.header
.data_len
= 1;
416 message
.payload
[0] = config_enable
;
418 len
= sizeof(struct ecl_message_header
) + message
.header
.data_len
;
420 return ishtp_cl_send(opr_dev
->ecl_ishtp_cl
, (uint8_t *)&message
, len
);
423 static void ecl_ishtp_cl_event_cb(struct ishtp_cl_device
*cl_device
)
425 struct ishtp_cl
*ecl_ishtp_cl
= ishtp_get_drvdata(cl_device
);
426 struct ishtp_opregion_dev
*opr_dev
;
427 struct ecl_message_header
*header
;
428 struct ishtp_cl_rb
*rb
;
430 opr_dev
= ishtp_get_client_data(ecl_ishtp_cl
);
431 while ((rb
= ishtp_cl_rx_get_rb(opr_dev
->ecl_ishtp_cl
)) != NULL
) {
433 header
= (struct ecl_message_header
*)rb
->buffer
.data
;
435 if (header
->data_type
== ECL_MSG_DATA
)
436 ecl_ish_process_rx_data(opr_dev
);
437 else if (header
->data_type
== ECL_MSG_EVENT
)
438 ecl_ish_process_rx_event(opr_dev
);
440 /* Got an event with wrong data_type, ignore it */
441 dev_err(cl_data_to_dev(opr_dev
),
442 "[ish_cb] Received wrong data_type\n");
444 ishtp_cl_io_rb_recycle(rb
);
448 static int ecl_ishtp_cl_init(struct ishtp_cl
*ecl_ishtp_cl
)
450 struct ishtp_opregion_dev
*opr_dev
=
451 ishtp_get_client_data(ecl_ishtp_cl
);
452 struct ishtp_fw_client
*fw_client
;
453 struct ishtp_device
*dev
;
456 rv
= ishtp_cl_link(ecl_ishtp_cl
);
458 dev_err(cl_data_to_dev(opr_dev
), "ishtp_cl_link failed\n");
462 dev
= ishtp_get_ishtp_device(ecl_ishtp_cl
);
464 /* Connect to FW client */
465 ishtp_set_tx_ring_size(ecl_ishtp_cl
, ECL_CL_TX_RING_SIZE
);
466 ishtp_set_rx_ring_size(ecl_ishtp_cl
, ECL_CL_RX_RING_SIZE
);
468 fw_client
= ishtp_fw_cl_get_client(dev
, &ecl_ishtp_id_table
[0].guid
);
470 dev_err(cl_data_to_dev(opr_dev
), "fw client not found\n");
474 ishtp_cl_set_fw_client_id(ecl_ishtp_cl
,
475 ishtp_get_fw_client_id(fw_client
));
477 ishtp_set_connection_state(ecl_ishtp_cl
, ISHTP_CL_CONNECTING
);
479 rv
= ishtp_cl_connect(ecl_ishtp_cl
);
481 dev_err(cl_data_to_dev(opr_dev
), "client connect failed\n");
483 ishtp_cl_unlink(ecl_ishtp_cl
);
487 dev_dbg(cl_data_to_dev(opr_dev
), "Host connected to fw client\n");
492 static void ecl_ishtp_cl_deinit(struct ishtp_cl
*ecl_ishtp_cl
)
494 ishtp_cl_unlink(ecl_ishtp_cl
);
495 ishtp_cl_flush_queues(ecl_ishtp_cl
);
496 ishtp_cl_free(ecl_ishtp_cl
);
499 static void ecl_ishtp_cl_reset_handler(struct work_struct
*work
)
501 struct ishtp_opregion_dev
*opr_dev
;
502 struct ishtp_cl_device
*cl_device
;
503 struct ishtp_cl
*ecl_ishtp_cl
;
507 opr_dev
= container_of(work
, struct ishtp_opregion_dev
, reset_work
);
509 opr_dev
->ish_link_ready
= false;
511 cl_device
= opr_dev
->cl_device
;
512 ecl_ishtp_cl
= opr_dev
->ecl_ishtp_cl
;
514 ecl_ishtp_cl_deinit(ecl_ishtp_cl
);
516 ecl_ishtp_cl
= ishtp_cl_allocate(cl_device
);
520 ishtp_set_drvdata(cl_device
, ecl_ishtp_cl
);
521 ishtp_set_client_data(ecl_ishtp_cl
, opr_dev
);
523 opr_dev
->ecl_ishtp_cl
= ecl_ishtp_cl
;
525 for (retry
= 0; retry
< 3; ++retry
) {
526 rv
= ecl_ishtp_cl_init(ecl_ishtp_cl
);
531 ishtp_cl_free(ecl_ishtp_cl
);
532 opr_dev
->ecl_ishtp_cl
= NULL
;
533 dev_err(cl_data_to_dev(opr_dev
),
534 "[ish_rst] Reset failed. Link not ready.\n");
538 ishtp_register_event_cb(cl_device
, ecl_ishtp_cl_event_cb
);
539 dev_info(cl_data_to_dev(opr_dev
),
540 "[ish_rst] Reset Success. Link ready.\n");
542 opr_dev
->ish_link_ready
= true;
544 if (opr_dev
->acpi_init_done
)
547 rv
= acpi_opregion_init(opr_dev
);
549 dev_err(cl_data_to_dev(opr_dev
),
550 "ACPI opregion init failed\n");
554 static int ecl_ishtp_cl_probe(struct ishtp_cl_device
*cl_device
)
556 struct ishtp_cl
*ecl_ishtp_cl
;
557 struct ishtp_opregion_dev
*opr_dev
;
560 opr_dev
= devm_kzalloc(ishtp_device(cl_device
), sizeof(*opr_dev
),
565 ecl_ishtp_cl
= ishtp_cl_allocate(cl_device
);
569 ishtp_set_drvdata(cl_device
, ecl_ishtp_cl
);
570 ishtp_set_client_data(ecl_ishtp_cl
, opr_dev
);
571 opr_dev
->ecl_ishtp_cl
= ecl_ishtp_cl
;
572 opr_dev
->cl_device
= cl_device
;
574 init_waitqueue_head(&opr_dev
->read_wait
);
575 INIT_WORK(&opr_dev
->event_work
, ecl_acpi_invoke_dsm
);
576 INIT_WORK(&opr_dev
->reset_work
, ecl_ishtp_cl_reset_handler
);
578 /* Initialize ish client device */
579 rv
= ecl_ishtp_cl_init(ecl_ishtp_cl
);
581 dev_err(cl_data_to_dev(opr_dev
), "Client init failed\n");
585 dev_dbg(cl_data_to_dev(opr_dev
), "eclite-ishtp client initialised\n");
587 opr_dev
->ish_link_ready
= true;
588 mutex_init(&opr_dev
->lock
);
590 rv
= acpi_find_eclite_device(opr_dev
);
592 dev_err(cl_data_to_dev(opr_dev
), "ECLite ACPI ID not found\n");
596 /* Register a handler for eclite fw events */
597 ishtp_register_event_cb(cl_device
, ecl_ishtp_cl_event_cb
);
599 /* Now init opregion handlers */
600 rv
= acpi_opregion_init(opr_dev
);
602 dev_err(cl_data_to_dev(opr_dev
), "ACPI opregion init failed\n");
606 /* Reprobe devices depending on ECLite - battery, fan, etc. */
607 acpi_dev_clear_dependencies(opr_dev
->adev
);
611 ishtp_set_connection_state(ecl_ishtp_cl
, ISHTP_CL_DISCONNECTING
);
612 ishtp_cl_disconnect(ecl_ishtp_cl
);
613 ecl_ishtp_cl_deinit(ecl_ishtp_cl
);
618 static void ecl_ishtp_cl_remove(struct ishtp_cl_device
*cl_device
)
620 struct ishtp_cl
*ecl_ishtp_cl
= ishtp_get_drvdata(cl_device
);
621 struct ishtp_opregion_dev
*opr_dev
=
622 ishtp_get_client_data(ecl_ishtp_cl
);
624 if (opr_dev
->acpi_init_done
)
625 acpi_opregion_deinit(opr_dev
);
627 acpi_dev_put(opr_dev
->adev
);
629 ishtp_set_connection_state(ecl_ishtp_cl
, ISHTP_CL_DISCONNECTING
);
630 ishtp_cl_disconnect(ecl_ishtp_cl
);
631 ecl_ishtp_cl_deinit(ecl_ishtp_cl
);
633 cancel_work_sync(&opr_dev
->reset_work
);
634 cancel_work_sync(&opr_dev
->event_work
);
637 static int ecl_ishtp_cl_reset(struct ishtp_cl_device
*cl_device
)
639 struct ishtp_cl
*ecl_ishtp_cl
= ishtp_get_drvdata(cl_device
);
640 struct ishtp_opregion_dev
*opr_dev
=
641 ishtp_get_client_data(ecl_ishtp_cl
);
643 schedule_work(&opr_dev
->reset_work
);
648 static int ecl_ishtp_cl_suspend(struct device
*device
)
650 struct ishtp_cl_device
*cl_device
= ishtp_dev_to_cl_device(device
);
651 struct ishtp_cl
*ecl_ishtp_cl
= ishtp_get_drvdata(cl_device
);
652 struct ishtp_opregion_dev
*opr_dev
=
653 ishtp_get_client_data(ecl_ishtp_cl
);
655 if (acpi_target_system_state() == ACPI_STATE_S0
)
658 acpi_opregion_deinit(opr_dev
);
659 ecl_ish_cl_enable_events(opr_dev
, false);
664 static int ecl_ishtp_cl_resume(struct device
*device
)
666 /* A reset is expected to call after an Sx. At this point
667 * we are not sure if the link is up or not to restore anything,
668 * so do nothing in resume path
673 static const struct dev_pm_ops ecl_ishtp_pm_ops
= {
674 .suspend
= ecl_ishtp_cl_suspend
,
675 .resume
= ecl_ishtp_cl_resume
,
678 static struct ishtp_cl_driver ecl_ishtp_cl_driver
= {
679 .name
= "ishtp-eclite",
680 .id
= ecl_ishtp_id_table
,
681 .probe
= ecl_ishtp_cl_probe
,
682 .remove
= ecl_ishtp_cl_remove
,
683 .reset
= ecl_ishtp_cl_reset
,
684 .driver
.pm
= &ecl_ishtp_pm_ops
,
687 static int __init
ecl_ishtp_init(void)
689 return ishtp_cl_driver_register(&ecl_ishtp_cl_driver
, THIS_MODULE
);
692 static void __exit
ecl_ishtp_exit(void)
694 return ishtp_cl_driver_unregister(&ecl_ishtp_cl_driver
);
697 late_initcall(ecl_ishtp_init
);
698 module_exit(ecl_ishtp_exit
);
700 MODULE_DESCRIPTION("ISH ISHTP eclite client opregion driver");
701 MODULE_AUTHOR("K Naduvalath, Sumesh <sumesh.k.naduvalath@intel.com>");
703 MODULE_LICENSE("GPL v2");