1 // SPDX-License-Identifier: GPL-2.0+
3 * Driver for the Surface ACPI Notify (SAN) interface/shim.
5 * Translates communication from ACPI to Surface System Aggregator Module
6 * (SSAM/SAM) requests and back, specifically SAM-over-SSH. Translates SSAM
7 * events back to ACPI notifications. Allows handling of discrete GPU
8 * notifications sent from ACPI via the SAN interface by providing them to any
9 * registered external driver.
11 * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com>
14 #include <linux/unaligned.h>
15 #include <linux/acpi.h>
16 #include <linux/delay.h>
17 #include <linux/jiffies.h>
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/notifier.h>
21 #include <linux/platform_device.h>
22 #include <linux/rwsem.h>
24 #include <linux/surface_aggregator/controller.h>
25 #include <linux/surface_acpi_notify.h>
29 struct ssam_controller
*ctrl
;
31 struct acpi_connection_info info
;
33 struct ssam_event_notifier nf_bat
;
34 struct ssam_event_notifier nf_tmp
;
37 #define to_san_data(ptr, member) \
38 container_of(ptr, struct san_data, member)
40 static struct workqueue_struct
*san_wq
;
42 /* -- dGPU notifier interface. ---------------------------------------------- */
45 struct rw_semaphore lock
;
47 struct blocking_notifier_head nh
;
50 static struct san_rqsg_if san_rqsg_if
= {
51 .lock
= __RWSEM_INITIALIZER(san_rqsg_if
.lock
),
53 .nh
= BLOCKING_NOTIFIER_INIT(san_rqsg_if
.nh
),
56 static int san_set_rqsg_interface_device(struct device
*dev
)
60 down_write(&san_rqsg_if
.lock
);
61 if (!san_rqsg_if
.dev
&& dev
)
62 san_rqsg_if
.dev
= dev
;
65 up_write(&san_rqsg_if
.lock
);
71 * san_client_link() - Link client as consumer to SAN device.
72 * @client: The client to link.
74 * Sets up a device link between the provided client device as consumer and
75 * the SAN device as provider. This function can be used to ensure that the
76 * SAN interface has been set up and will be set up for as long as the driver
77 * of the client device is bound. This guarantees that, during that time, all
78 * dGPU events will be received by any registered notifier.
80 * The link will be automatically removed once the client device's driver is
83 * Return: Returns zero on success, %-ENXIO if the SAN interface has not been
84 * set up yet, and %-ENOMEM if device link creation failed.
86 int san_client_link(struct device
*client
)
88 const u32 flags
= DL_FLAG_PM_RUNTIME
| DL_FLAG_AUTOREMOVE_CONSUMER
;
89 struct device_link
*link
;
91 down_read(&san_rqsg_if
.lock
);
93 if (!san_rqsg_if
.dev
) {
94 up_read(&san_rqsg_if
.lock
);
98 link
= device_link_add(client
, san_rqsg_if
.dev
, flags
);
100 up_read(&san_rqsg_if
.lock
);
104 if (READ_ONCE(link
->status
) == DL_STATE_SUPPLIER_UNBIND
) {
105 up_read(&san_rqsg_if
.lock
);
109 up_read(&san_rqsg_if
.lock
);
112 EXPORT_SYMBOL_GPL(san_client_link
);
115 * san_dgpu_notifier_register() - Register a SAN dGPU notifier.
116 * @nb: The notifier-block to register.
118 * Registers a SAN dGPU notifier, receiving any new SAN dGPU events sent from
119 * ACPI. The registered notifier will be called with &struct san_dgpu_event
120 * as notifier data and the command ID of that event as notifier action.
122 int san_dgpu_notifier_register(struct notifier_block
*nb
)
124 return blocking_notifier_chain_register(&san_rqsg_if
.nh
, nb
);
126 EXPORT_SYMBOL_GPL(san_dgpu_notifier_register
);
129 * san_dgpu_notifier_unregister() - Unregister a SAN dGPU notifier.
130 * @nb: The notifier-block to unregister.
132 int san_dgpu_notifier_unregister(struct notifier_block
*nb
)
134 return blocking_notifier_chain_unregister(&san_rqsg_if
.nh
, nb
);
136 EXPORT_SYMBOL_GPL(san_dgpu_notifier_unregister
);
138 static int san_dgpu_notifier_call(struct san_dgpu_event
*evt
)
142 ret
= blocking_notifier_call_chain(&san_rqsg_if
.nh
, evt
->command
, evt
);
143 return notifier_to_errno(ret
);
147 /* -- ACPI _DSM event relay. ------------------------------------------------ */
149 #define SAN_DSM_REVISION 0
151 /* 93b666c5-70c6-469f-a215-3d487c91ab3c */
152 static const guid_t SAN_DSM_UUID
=
153 GUID_INIT(0x93b666c5, 0x70c6, 0x469f, 0xa2, 0x15, 0x3d,
154 0x48, 0x7c, 0x91, 0xab, 0x3c);
156 enum san_dsm_event_fn
{
157 SAN_DSM_EVENT_FN_BAT1_STAT
= 0x03,
158 SAN_DSM_EVENT_FN_BAT1_INFO
= 0x04,
159 SAN_DSM_EVENT_FN_ADP1_STAT
= 0x05,
160 SAN_DSM_EVENT_FN_ADP1_INFO
= 0x06,
161 SAN_DSM_EVENT_FN_BAT2_STAT
= 0x07,
162 SAN_DSM_EVENT_FN_BAT2_INFO
= 0x08,
163 SAN_DSM_EVENT_FN_THERMAL
= 0x09,
164 SAN_DSM_EVENT_FN_DPTF
= 0x0a,
167 enum sam_event_cid_bat
{
168 SAM_EVENT_CID_BAT_BIX
= 0x15,
169 SAM_EVENT_CID_BAT_BST
= 0x16,
170 SAM_EVENT_CID_BAT_ADP
= 0x17,
171 SAM_EVENT_CID_BAT_PROT
= 0x18,
172 SAM_EVENT_CID_BAT_DPTF
= 0x4f,
175 enum sam_event_cid_tmp
{
176 SAM_EVENT_CID_TMP_TRIP
= 0x0b,
179 struct san_event_work
{
180 struct delayed_work work
;
182 struct ssam_event event
; /* must be last */
185 static int san_acpi_notify_event(struct device
*dev
, u64 func
,
186 union acpi_object
*param
)
188 acpi_handle san
= ACPI_HANDLE(dev
);
189 union acpi_object
*obj
;
192 if (!acpi_check_dsm(san
, &SAN_DSM_UUID
, SAN_DSM_REVISION
, BIT_ULL(func
)))
195 dev_dbg(dev
, "notify event %#04llx\n", func
);
197 obj
= acpi_evaluate_dsm_typed(san
, &SAN_DSM_UUID
, SAN_DSM_REVISION
,
198 func
, param
, ACPI_TYPE_BUFFER
);
202 if (obj
->buffer
.length
!= 1 || obj
->buffer
.pointer
[0] != 0) {
203 dev_err(dev
, "got unexpected result from _DSM\n");
211 static int san_evt_bat_adp(struct device
*dev
, const struct ssam_event
*event
)
215 status
= san_acpi_notify_event(dev
, SAN_DSM_EVENT_FN_ADP1_STAT
, NULL
);
220 * Ensure that the battery states get updated correctly. When the
221 * battery is fully charged and an adapter is plugged in, it sometimes
222 * is not updated correctly, instead showing it as charging.
223 * Explicitly trigger battery updates to fix this.
226 status
= san_acpi_notify_event(dev
, SAN_DSM_EVENT_FN_BAT1_STAT
, NULL
);
230 return san_acpi_notify_event(dev
, SAN_DSM_EVENT_FN_BAT2_STAT
, NULL
);
233 static int san_evt_bat_bix(struct device
*dev
, const struct ssam_event
*event
)
235 enum san_dsm_event_fn fn
;
237 if (event
->instance_id
== 0x02)
238 fn
= SAN_DSM_EVENT_FN_BAT2_INFO
;
240 fn
= SAN_DSM_EVENT_FN_BAT1_INFO
;
242 return san_acpi_notify_event(dev
, fn
, NULL
);
245 static int san_evt_bat_bst(struct device
*dev
, const struct ssam_event
*event
)
247 enum san_dsm_event_fn fn
;
249 if (event
->instance_id
== 0x02)
250 fn
= SAN_DSM_EVENT_FN_BAT2_STAT
;
252 fn
= SAN_DSM_EVENT_FN_BAT1_STAT
;
254 return san_acpi_notify_event(dev
, fn
, NULL
);
257 static int san_evt_bat_dptf(struct device
*dev
, const struct ssam_event
*event
)
259 union acpi_object payload
;
262 * The Surface ACPI expects a buffer and not a package. It specifically
263 * checks for ObjectType (Arg3) == 0x03. This will cause a warning in
264 * acpica/nsarguments.c, but that warning can be safely ignored.
266 payload
.type
= ACPI_TYPE_BUFFER
;
267 payload
.buffer
.length
= event
->length
;
268 payload
.buffer
.pointer
= (u8
*)&event
->data
[0];
270 return san_acpi_notify_event(dev
, SAN_DSM_EVENT_FN_DPTF
, &payload
);
273 static unsigned long san_evt_bat_delay(u8 cid
)
276 case SAM_EVENT_CID_BAT_ADP
:
278 * Wait for battery state to update before signaling adapter
281 return msecs_to_jiffies(5000);
283 case SAM_EVENT_CID_BAT_BST
:
284 /* Ensure we do not miss anything important due to caching. */
285 return msecs_to_jiffies(2000);
292 static bool san_evt_bat(const struct ssam_event
*event
, struct device
*dev
)
296 switch (event
->command_id
) {
297 case SAM_EVENT_CID_BAT_BIX
:
298 status
= san_evt_bat_bix(dev
, event
);
301 case SAM_EVENT_CID_BAT_BST
:
302 status
= san_evt_bat_bst(dev
, event
);
305 case SAM_EVENT_CID_BAT_ADP
:
306 status
= san_evt_bat_adp(dev
, event
);
309 case SAM_EVENT_CID_BAT_PROT
:
311 * TODO: Implement support for battery protection status change
316 case SAM_EVENT_CID_BAT_DPTF
:
317 status
= san_evt_bat_dptf(dev
, event
);
325 dev_err(dev
, "error handling power event (cid = %#04x)\n",
332 static void san_evt_bat_workfn(struct work_struct
*work
)
334 struct san_event_work
*ev
;
336 ev
= container_of(work
, struct san_event_work
, work
.work
);
337 san_evt_bat(&ev
->event
, ev
->dev
);
341 static u32
san_evt_bat_nf(struct ssam_event_notifier
*nf
,
342 const struct ssam_event
*event
)
344 struct san_data
*d
= to_san_data(nf
, nf_bat
);
345 struct san_event_work
*work
;
346 unsigned long delay
= san_evt_bat_delay(event
->command_id
);
349 return san_evt_bat(event
, d
->dev
) ? SSAM_NOTIF_HANDLED
: 0;
351 work
= kzalloc(sizeof(*work
) + event
->length
, GFP_KERNEL
);
353 return ssam_notifier_from_errno(-ENOMEM
);
355 INIT_DELAYED_WORK(&work
->work
, san_evt_bat_workfn
);
358 work
->event
= *event
;
359 memcpy(work
->event
.data
, event
->data
, event
->length
);
361 queue_delayed_work(san_wq
, &work
->work
, delay
);
362 return SSAM_NOTIF_HANDLED
;
365 static int san_evt_tmp_trip(struct device
*dev
, const struct ssam_event
*event
)
367 union acpi_object param
;
370 * The Surface ACPI expects an integer and not a package. This will
371 * cause a warning in acpica/nsarguments.c, but that warning can be
374 param
.type
= ACPI_TYPE_INTEGER
;
375 param
.integer
.value
= event
->instance_id
;
377 return san_acpi_notify_event(dev
, SAN_DSM_EVENT_FN_THERMAL
, ¶m
);
380 static bool san_evt_tmp(const struct ssam_event
*event
, struct device
*dev
)
384 switch (event
->command_id
) {
385 case SAM_EVENT_CID_TMP_TRIP
:
386 status
= san_evt_tmp_trip(dev
, event
);
394 dev_err(dev
, "error handling thermal event (cid = %#04x)\n",
401 static u32
san_evt_tmp_nf(struct ssam_event_notifier
*nf
,
402 const struct ssam_event
*event
)
404 struct san_data
*d
= to_san_data(nf
, nf_tmp
);
406 return san_evt_tmp(event
, d
->dev
) ? SSAM_NOTIF_HANDLED
: 0;
410 /* -- ACPI GSB OperationRegion handler -------------------------------------- */
416 struct gsb_data_rqsx
{
417 u8 cv
; /* Command value (san_gsb_request_cv). */
418 u8 tc
; /* Target category. */
419 u8 tid
; /* Target ID. */
420 u8 iid
; /* Instance ID. */
421 u8 snc
; /* Expect-response-flag. */
422 u8 cid
; /* Command ID. */
423 u16 cdl
; /* Payload length. */
424 u8 pld
[]; /* Payload. */
427 struct gsb_data_etwl
{
428 u8 cv
; /* Command value (should be 0x02). */
429 u8 etw3
; /* Unknown. */
430 u8 etw4
; /* Unknown. */
431 u8 msg
[]; /* Error message (ASCIIZ). */
434 struct gsb_data_out
{
435 u8 status
; /* _SSH communication status. */
436 u8 len
; /* _SSH payload length. */
437 u8 pld
[]; /* _SSH payload. */
440 union gsb_buffer_data
{
441 struct gsb_data_in in
; /* Common input. */
442 struct gsb_data_rqsx rqsx
; /* RQSX input. */
443 struct gsb_data_etwl etwl
; /* ETWL input. */
444 struct gsb_data_out out
; /* Output. */
448 u8 status
; /* GSB AttribRawProcess status. */
449 u8 len
; /* GSB AttribRawProcess length. */
450 union gsb_buffer_data data
;
453 #define SAN_GSB_MAX_RQSX_PAYLOAD (U8_MAX - 2 - sizeof(struct gsb_data_rqsx))
454 #define SAN_GSB_MAX_RESPONSE (U8_MAX - 2 - sizeof(struct gsb_data_out))
456 #define SAN_GSB_COMMAND 0
458 enum san_gsb_request_cv
{
459 SAN_GSB_REQUEST_CV_RQST
= 0x01,
460 SAN_GSB_REQUEST_CV_ETWL
= 0x02,
461 SAN_GSB_REQUEST_CV_RQSG
= 0x03,
464 #define SAN_REQUEST_NUM_TRIES 5
466 static acpi_status
san_etwl(struct san_data
*d
, struct gsb_buffer
*b
)
468 struct gsb_data_etwl
*etwl
= &b
->data
.etwl
;
470 if (b
->len
< sizeof(struct gsb_data_etwl
)) {
471 dev_err(d
->dev
, "invalid ETWL package (len = %d)\n", b
->len
);
475 dev_err(d
->dev
, "ETWL(%#04x, %#04x): %.*s\n", etwl
->etw3
, etwl
->etw4
,
476 (unsigned int)(b
->len
- sizeof(struct gsb_data_etwl
)),
479 /* Indicate success. */
487 struct gsb_data_rqsx
*san_validate_rqsx(struct device
*dev
, const char *type
,
488 struct gsb_buffer
*b
)
490 struct gsb_data_rqsx
*rqsx
= &b
->data
.rqsx
;
492 if (b
->len
< sizeof(struct gsb_data_rqsx
)) {
493 dev_err(dev
, "invalid %s package (len = %d)\n", type
, b
->len
);
497 if (get_unaligned(&rqsx
->cdl
) != b
->len
- sizeof(struct gsb_data_rqsx
)) {
498 dev_err(dev
, "bogus %s package (len = %d, cdl = %d)\n",
499 type
, b
->len
, get_unaligned(&rqsx
->cdl
));
503 if (get_unaligned(&rqsx
->cdl
) > SAN_GSB_MAX_RQSX_PAYLOAD
) {
504 dev_err(dev
, "payload for %s package too large (cdl = %d)\n",
505 type
, get_unaligned(&rqsx
->cdl
));
512 static void gsb_rqsx_response_error(struct gsb_buffer
*gsb
, int status
)
516 gsb
->data
.out
.status
= (u8
)(-status
);
517 gsb
->data
.out
.len
= 0x00;
520 static void gsb_rqsx_response_success(struct gsb_buffer
*gsb
, u8
*ptr
, size_t len
)
524 gsb
->data
.out
.status
= 0x00;
525 gsb
->data
.out
.len
= len
;
528 memcpy(&gsb
->data
.out
.pld
[0], ptr
, len
);
531 static acpi_status
san_rqst_fixup_suspended(struct san_data
*d
,
532 struct ssam_request
*rqst
,
533 struct gsb_buffer
*gsb
)
535 if (rqst
->target_category
== SSAM_SSH_TC_BAS
&& rqst
->command_id
== 0x0D) {
539 * The base state may be queried from ACPI when the EC is still
540 * suspended. In this case it will return '-EPERM'. This query
541 * will only be triggered from the ACPI lid GPE interrupt, thus
542 * we are either in laptop or studio mode (base status 0x01 or
543 * 0x02). Furthermore, we will only get here if the device (and
544 * EC) have been suspended.
546 * We now assume that the device is in laptop mode (0x01). This
547 * has the drawback that it will wake the device when unfolding
548 * it in studio mode, but it also allows us to avoid actively
549 * waiting for the EC to wake up, which may incur a notable
553 dev_dbg(d
->dev
, "rqst: fixup: base-state quirk\n");
555 gsb_rqsx_response_success(gsb
, &base_state
, sizeof(base_state
));
559 gsb_rqsx_response_error(gsb
, -ENXIO
);
563 static acpi_status
san_rqst(struct san_data
*d
, struct gsb_buffer
*buffer
)
565 u8 rspbuf
[SAN_GSB_MAX_RESPONSE
];
566 struct gsb_data_rqsx
*gsb_rqst
;
567 struct ssam_request rqst
;
568 struct ssam_response rsp
;
571 gsb_rqst
= san_validate_rqsx(d
->dev
, "RQST", buffer
);
575 rqst
.target_category
= gsb_rqst
->tc
;
576 rqst
.target_id
= gsb_rqst
->tid
;
577 rqst
.command_id
= gsb_rqst
->cid
;
578 rqst
.instance_id
= gsb_rqst
->iid
;
579 rqst
.flags
= gsb_rqst
->snc
? SSAM_REQUEST_HAS_RESPONSE
: 0;
580 rqst
.length
= get_unaligned(&gsb_rqst
->cdl
);
581 rqst
.payload
= &gsb_rqst
->pld
[0];
583 rsp
.capacity
= ARRAY_SIZE(rspbuf
);
585 rsp
.pointer
= &rspbuf
[0];
587 /* Handle suspended device. */
588 if (d
->dev
->power
.is_suspended
) {
589 dev_warn(d
->dev
, "rqst: device is suspended, not executing\n");
590 return san_rqst_fixup_suspended(d
, &rqst
, buffer
);
593 status
= __ssam_retry(ssam_request_do_sync_onstack
, SAN_REQUEST_NUM_TRIES
,
594 d
->ctrl
, &rqst
, &rsp
, SAN_GSB_MAX_RQSX_PAYLOAD
);
597 gsb_rqsx_response_success(buffer
, rsp
.pointer
, rsp
.length
);
599 dev_err(d
->dev
, "rqst: failed with error %d\n", status
);
600 gsb_rqsx_response_error(buffer
, status
);
606 static acpi_status
san_rqsg(struct san_data
*d
, struct gsb_buffer
*buffer
)
608 struct gsb_data_rqsx
*gsb_rqsg
;
609 struct san_dgpu_event evt
;
612 gsb_rqsg
= san_validate_rqsx(d
->dev
, "RQSG", buffer
);
616 evt
.category
= gsb_rqsg
->tc
;
617 evt
.target
= gsb_rqsg
->tid
;
618 evt
.command
= gsb_rqsg
->cid
;
619 evt
.instance
= gsb_rqsg
->iid
;
620 evt
.length
= get_unaligned(&gsb_rqsg
->cdl
);
621 evt
.payload
= &gsb_rqsg
->pld
[0];
623 status
= san_dgpu_notifier_call(&evt
);
625 gsb_rqsx_response_success(buffer
, NULL
, 0);
627 dev_err(d
->dev
, "rqsg: failed with error %d\n", status
);
628 gsb_rqsx_response_error(buffer
, status
);
634 static acpi_status
san_opreg_handler(u32 function
, acpi_physical_address command
,
635 u32 bits
, u64
*value64
, void *opreg_context
,
636 void *region_context
)
638 struct san_data
*d
= to_san_data(opreg_context
, info
);
639 struct gsb_buffer
*buffer
= (struct gsb_buffer
*)value64
;
640 int accessor_type
= (function
& 0xFFFF0000) >> 16;
642 if (command
!= SAN_GSB_COMMAND
) {
643 dev_warn(d
->dev
, "unsupported command: %#04llx\n", command
);
647 if (accessor_type
!= ACPI_GSB_ACCESS_ATTRIB_RAW_PROCESS
) {
648 dev_err(d
->dev
, "invalid access type: %#04x\n", accessor_type
);
652 /* Buffer must have at least contain the command-value. */
653 if (buffer
->len
== 0) {
654 dev_err(d
->dev
, "request-package too small\n");
658 switch (buffer
->data
.in
.cv
) {
659 case SAN_GSB_REQUEST_CV_RQST
:
660 return san_rqst(d
, buffer
);
662 case SAN_GSB_REQUEST_CV_ETWL
:
663 return san_etwl(d
, buffer
);
665 case SAN_GSB_REQUEST_CV_RQSG
:
666 return san_rqsg(d
, buffer
);
669 dev_warn(d
->dev
, "unsupported SAN0 request (cv: %#04x)\n",
676 /* -- Driver setup. --------------------------------------------------------- */
678 static int san_events_register(struct platform_device
*pdev
)
680 struct san_data
*d
= platform_get_drvdata(pdev
);
683 d
->nf_bat
.base
.priority
= 1;
684 d
->nf_bat
.base
.fn
= san_evt_bat_nf
;
685 d
->nf_bat
.event
.reg
= SSAM_EVENT_REGISTRY_SAM
;
686 d
->nf_bat
.event
.id
.target_category
= SSAM_SSH_TC_BAT
;
687 d
->nf_bat
.event
.id
.instance
= 0;
688 d
->nf_bat
.event
.mask
= SSAM_EVENT_MASK_TARGET
;
689 d
->nf_bat
.event
.flags
= SSAM_EVENT_SEQUENCED
;
691 d
->nf_tmp
.base
.priority
= 1;
692 d
->nf_tmp
.base
.fn
= san_evt_tmp_nf
;
693 d
->nf_tmp
.event
.reg
= SSAM_EVENT_REGISTRY_SAM
;
694 d
->nf_tmp
.event
.id
.target_category
= SSAM_SSH_TC_TMP
;
695 d
->nf_tmp
.event
.id
.instance
= 0;
696 d
->nf_tmp
.event
.mask
= SSAM_EVENT_MASK_TARGET
;
697 d
->nf_tmp
.event
.flags
= SSAM_EVENT_SEQUENCED
;
699 status
= ssam_notifier_register(d
->ctrl
, &d
->nf_bat
);
703 status
= ssam_notifier_register(d
->ctrl
, &d
->nf_tmp
);
705 ssam_notifier_unregister(d
->ctrl
, &d
->nf_bat
);
710 static void san_events_unregister(struct platform_device
*pdev
)
712 struct san_data
*d
= platform_get_drvdata(pdev
);
714 ssam_notifier_unregister(d
->ctrl
, &d
->nf_bat
);
715 ssam_notifier_unregister(d
->ctrl
, &d
->nf_tmp
);
718 #define san_consumer_printk(level, dev, handle, fmt, ...) \
720 char *path = "<error getting consumer path>"; \
721 struct acpi_buffer buffer = { \
722 .length = ACPI_ALLOCATE_BUFFER, \
726 if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer))) \
727 path = buffer.pointer; \
729 dev_##level(dev, "[%s]: " fmt, path, ##__VA_ARGS__); \
730 kfree(buffer.pointer); \
733 #define san_consumer_dbg(dev, handle, fmt, ...) \
734 san_consumer_printk(dbg, dev, handle, fmt, ##__VA_ARGS__)
736 #define san_consumer_warn(dev, handle, fmt, ...) \
737 san_consumer_printk(warn, dev, handle, fmt, ##__VA_ARGS__)
739 static acpi_status
san_consumer_setup(acpi_handle handle
, u32 lvl
,
740 void *context
, void **rv
)
742 const u32 flags
= DL_FLAG_PM_RUNTIME
| DL_FLAG_AUTOREMOVE_SUPPLIER
;
743 struct platform_device
*pdev
= context
;
744 struct acpi_device
*adev
;
745 struct device_link
*link
;
747 if (!acpi_device_dep(handle
, ACPI_HANDLE(&pdev
->dev
)))
750 /* Ignore ACPI devices that are not present. */
751 adev
= acpi_fetch_acpi_dev(handle
);
755 san_consumer_dbg(&pdev
->dev
, handle
, "creating device link\n");
757 /* Try to set up device links, ignore but log errors. */
758 link
= device_link_add(&adev
->dev
, &pdev
->dev
, flags
);
760 san_consumer_warn(&pdev
->dev
, handle
, "failed to create device link\n");
767 static int san_consumer_links_setup(struct platform_device
*pdev
)
771 status
= acpi_walk_namespace(ACPI_TYPE_DEVICE
, ACPI_ROOT_OBJECT
,
772 ACPI_UINT32_MAX
, san_consumer_setup
, NULL
,
775 return status
? -EFAULT
: 0;
778 static int san_probe(struct platform_device
*pdev
)
780 struct acpi_device
*san
= ACPI_COMPANION(&pdev
->dev
);
781 struct ssam_controller
*ctrl
;
782 struct san_data
*data
;
786 ctrl
= ssam_client_bind(&pdev
->dev
);
788 return PTR_ERR(ctrl
) == -ENODEV
? -EPROBE_DEFER
: PTR_ERR(ctrl
);
790 status
= san_consumer_links_setup(pdev
);
794 data
= devm_kzalloc(&pdev
->dev
, sizeof(*data
), GFP_KERNEL
);
798 data
->dev
= &pdev
->dev
;
801 platform_set_drvdata(pdev
, data
);
803 astatus
= acpi_install_address_space_handler(san
->handle
,
804 ACPI_ADR_SPACE_GSBUS
,
805 &san_opreg_handler
, NULL
,
807 if (ACPI_FAILURE(astatus
))
810 status
= san_events_register(pdev
);
812 goto err_enable_events
;
814 status
= san_set_rqsg_interface_device(&pdev
->dev
);
816 goto err_install_dev
;
818 acpi_dev_clear_dependencies(san
);
822 san_events_unregister(pdev
);
824 acpi_remove_address_space_handler(san
, ACPI_ADR_SPACE_GSBUS
,
829 static void san_remove(struct platform_device
*pdev
)
831 acpi_handle san
= ACPI_HANDLE(&pdev
->dev
);
833 san_set_rqsg_interface_device(NULL
);
834 acpi_remove_address_space_handler(san
, ACPI_ADR_SPACE_GSBUS
,
836 san_events_unregister(pdev
);
839 * We have unregistered our event sources. Now we need to ensure that
840 * all delayed works they may have spawned are run to completion.
842 flush_workqueue(san_wq
);
845 static const struct acpi_device_id san_match
[] = {
849 MODULE_DEVICE_TABLE(acpi
, san_match
);
851 static struct platform_driver surface_acpi_notify
= {
853 .remove
= san_remove
,
855 .name
= "surface_acpi_notify",
856 .acpi_match_table
= san_match
,
857 .probe_type
= PROBE_PREFER_ASYNCHRONOUS
,
861 static int __init
san_init(void)
865 san_wq
= alloc_workqueue("san_wq", 0, 0);
868 ret
= platform_driver_register(&surface_acpi_notify
);
870 destroy_workqueue(san_wq
);
873 module_init(san_init
);
875 static void __exit
san_exit(void)
877 platform_driver_unregister(&surface_acpi_notify
);
878 destroy_workqueue(san_wq
);
880 module_exit(san_exit
);
882 MODULE_AUTHOR("Maximilian Luz <luzmaximilian@gmail.com>");
883 MODULE_DESCRIPTION("Surface ACPI Notify driver for Surface System Aggregator Module");
884 MODULE_LICENSE("GPL");