Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0+
  2/*
  3 * Driver for the Surface ACPI Notify (SAN) interface/shim.
  4 *
  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.
 10 *
 11 * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
 12 */
 13
 14#include <asm/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>
 23
 24#include <linux/surface_aggregator/controller.h>
 25#include <linux/surface_acpi_notify.h>
 26
 27struct san_data {
 28	struct device *dev;
 29	struct ssam_controller *ctrl;
 30
 31	struct acpi_connection_info info;
 32
 33	struct ssam_event_notifier nf_bat;
 34	struct ssam_event_notifier nf_tmp;
 35};
 36
 37#define to_san_data(ptr, member) \
 38	container_of(ptr, struct san_data, member)
 39
 40
 41/* -- dGPU notifier interface. ---------------------------------------------- */
 42
 43struct san_rqsg_if {
 44	struct rw_semaphore lock;
 45	struct device *dev;
 46	struct blocking_notifier_head nh;
 47};
 48
 49static struct san_rqsg_if san_rqsg_if = {
 50	.lock = __RWSEM_INITIALIZER(san_rqsg_if.lock),
 51	.dev = NULL,
 52	.nh = BLOCKING_NOTIFIER_INIT(san_rqsg_if.nh),
 53};
 54
 55static int san_set_rqsg_interface_device(struct device *dev)
 56{
 57	int status = 0;
 58
 59	down_write(&san_rqsg_if.lock);
 60	if (!san_rqsg_if.dev && dev)
 61		san_rqsg_if.dev = dev;
 62	else
 63		status = -EBUSY;
 64	up_write(&san_rqsg_if.lock);
 65
 66	return status;
 67}
 68
 69/**
 70 * san_client_link() - Link client as consumer to SAN device.
 71 * @client: The client to link.
 72 *
 73 * Sets up a device link between the provided client device as consumer and
 74 * the SAN device as provider. This function can be used to ensure that the
 75 * SAN interface has been set up and will be set up for as long as the driver
 76 * of the client device is bound. This guarantees that, during that time, all
 77 * dGPU events will be received by any registered notifier.
 78 *
 79 * The link will be automatically removed once the client device's driver is
 80 * unbound.
 81 *
 82 * Return: Returns zero on success, %-ENXIO if the SAN interface has not been
 83 * set up yet, and %-ENOMEM if device link creation failed.
 84 */
 85int san_client_link(struct device *client)
 86{
 87	const u32 flags = DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_CONSUMER;
 88	struct device_link *link;
 89
 90	down_read(&san_rqsg_if.lock);
 91
 92	if (!san_rqsg_if.dev) {
 93		up_read(&san_rqsg_if.lock);
 94		return -ENXIO;
 95	}
 96
 97	link = device_link_add(client, san_rqsg_if.dev, flags);
 98	if (!link) {
 99		up_read(&san_rqsg_if.lock);
100		return -ENOMEM;
101	}
102
103	if (READ_ONCE(link->status) == DL_STATE_SUPPLIER_UNBIND) {
104		up_read(&san_rqsg_if.lock);
105		return -ENXIO;
106	}
107
108	up_read(&san_rqsg_if.lock);
109	return 0;
110}
111EXPORT_SYMBOL_GPL(san_client_link);
112
113/**
114 * san_dgpu_notifier_register() - Register a SAN dGPU notifier.
115 * @nb: The notifier-block to register.
116 *
117 * Registers a SAN dGPU notifier, receiving any new SAN dGPU events sent from
118 * ACPI. The registered notifier will be called with &struct san_dgpu_event
119 * as notifier data and the command ID of that event as notifier action.
120 */
121int san_dgpu_notifier_register(struct notifier_block *nb)
122{
123	return blocking_notifier_chain_register(&san_rqsg_if.nh, nb);
124}
125EXPORT_SYMBOL_GPL(san_dgpu_notifier_register);
126
127/**
128 * san_dgpu_notifier_unregister() - Unregister a SAN dGPU notifier.
129 * @nb: The notifier-block to unregister.
130 */
131int san_dgpu_notifier_unregister(struct notifier_block *nb)
132{
133	return blocking_notifier_chain_unregister(&san_rqsg_if.nh, nb);
134}
135EXPORT_SYMBOL_GPL(san_dgpu_notifier_unregister);
136
137static int san_dgpu_notifier_call(struct san_dgpu_event *evt)
138{
139	int ret;
140
141	ret = blocking_notifier_call_chain(&san_rqsg_if.nh, evt->command, evt);
142	return notifier_to_errno(ret);
143}
144
145
146/* -- ACPI _DSM event relay. ------------------------------------------------ */
147
148#define SAN_DSM_REVISION	0
149
150/* 93b666c5-70c6-469f-a215-3d487c91ab3c */
151static const guid_t SAN_DSM_UUID =
152	GUID_INIT(0x93b666c5, 0x70c6, 0x469f, 0xa2, 0x15, 0x3d,
153		  0x48, 0x7c, 0x91, 0xab, 0x3c);
154
155enum san_dsm_event_fn {
156	SAN_DSM_EVENT_FN_BAT1_STAT = 0x03,
157	SAN_DSM_EVENT_FN_BAT1_INFO = 0x04,
158	SAN_DSM_EVENT_FN_ADP1_STAT = 0x05,
159	SAN_DSM_EVENT_FN_ADP1_INFO = 0x06,
160	SAN_DSM_EVENT_FN_BAT2_STAT = 0x07,
161	SAN_DSM_EVENT_FN_BAT2_INFO = 0x08,
162	SAN_DSM_EVENT_FN_THERMAL   = 0x09,
163	SAN_DSM_EVENT_FN_DPTF      = 0x0a,
164};
165
166enum sam_event_cid_bat {
167	SAM_EVENT_CID_BAT_BIX  = 0x15,
168	SAM_EVENT_CID_BAT_BST  = 0x16,
169	SAM_EVENT_CID_BAT_ADP  = 0x17,
170	SAM_EVENT_CID_BAT_PROT = 0x18,
171	SAM_EVENT_CID_BAT_DPTF = 0x4f,
172};
173
174enum sam_event_cid_tmp {
175	SAM_EVENT_CID_TMP_TRIP = 0x0b,
176};
177
178struct san_event_work {
179	struct delayed_work work;
180	struct device *dev;
181	struct ssam_event event;	/* must be last */
182};
183
184static int san_acpi_notify_event(struct device *dev, u64 func,
185				 union acpi_object *param)
186{
187	acpi_handle san = ACPI_HANDLE(dev);
188	union acpi_object *obj;
189	int status = 0;
190
191	if (!acpi_check_dsm(san, &SAN_DSM_UUID, SAN_DSM_REVISION, BIT_ULL(func)))
192		return 0;
193
194	dev_dbg(dev, "notify event %#04llx\n", func);
195
196	obj = acpi_evaluate_dsm_typed(san, &SAN_DSM_UUID, SAN_DSM_REVISION,
197				      func, param, ACPI_TYPE_BUFFER);
198	if (!obj)
199		return -EFAULT;
200
201	if (obj->buffer.length != 1 || obj->buffer.pointer[0] != 0) {
202		dev_err(dev, "got unexpected result from _DSM\n");
203		status = -EPROTO;
204	}
205
206	ACPI_FREE(obj);
207	return status;
208}
209
210static int san_evt_bat_adp(struct device *dev, const struct ssam_event *event)
211{
212	int status;
213
214	status = san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_ADP1_STAT, NULL);
215	if (status)
216		return status;
217
218	/*
219	 * Ensure that the battery states get updated correctly. When the
220	 * battery is fully charged and an adapter is plugged in, it sometimes
221	 * is not updated correctly, instead showing it as charging.
222	 * Explicitly trigger battery updates to fix this.
223	 */
224
225	status = san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_BAT1_STAT, NULL);
226	if (status)
227		return status;
228
229	return san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_BAT2_STAT, NULL);
230}
231
232static int san_evt_bat_bix(struct device *dev, const struct ssam_event *event)
233{
234	enum san_dsm_event_fn fn;
235
236	if (event->instance_id == 0x02)
237		fn = SAN_DSM_EVENT_FN_BAT2_INFO;
238	else
239		fn = SAN_DSM_EVENT_FN_BAT1_INFO;
240
241	return san_acpi_notify_event(dev, fn, NULL);
242}
243
244static int san_evt_bat_bst(struct device *dev, const struct ssam_event *event)
245{
246	enum san_dsm_event_fn fn;
247
248	if (event->instance_id == 0x02)
249		fn = SAN_DSM_EVENT_FN_BAT2_STAT;
250	else
251		fn = SAN_DSM_EVENT_FN_BAT1_STAT;
252
253	return san_acpi_notify_event(dev, fn, NULL);
254}
255
256static int san_evt_bat_dptf(struct device *dev, const struct ssam_event *event)
257{
258	union acpi_object payload;
259
260	/*
261	 * The Surface ACPI expects a buffer and not a package. It specifically
262	 * checks for ObjectType (Arg3) == 0x03. This will cause a warning in
263	 * acpica/nsarguments.c, but that warning can be safely ignored.
264	 */
265	payload.type = ACPI_TYPE_BUFFER;
266	payload.buffer.length = event->length;
267	payload.buffer.pointer = (u8 *)&event->data[0];
268
269	return san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_DPTF, &payload);
270}
271
272static unsigned long san_evt_bat_delay(u8 cid)
273{
274	switch (cid) {
275	case SAM_EVENT_CID_BAT_ADP:
276		/*
277		 * Wait for battery state to update before signaling adapter
278		 * change.
279		 */
280		return msecs_to_jiffies(5000);
281
282	case SAM_EVENT_CID_BAT_BST:
283		/* Ensure we do not miss anything important due to caching. */
284		return msecs_to_jiffies(2000);
285
286	default:
287		return 0;
288	}
289}
290
291static bool san_evt_bat(const struct ssam_event *event, struct device *dev)
292{
293	int status;
294
295	switch (event->command_id) {
296	case SAM_EVENT_CID_BAT_BIX:
297		status = san_evt_bat_bix(dev, event);
298		break;
299
300	case SAM_EVENT_CID_BAT_BST:
301		status = san_evt_bat_bst(dev, event);
302		break;
303
304	case SAM_EVENT_CID_BAT_ADP:
305		status = san_evt_bat_adp(dev, event);
306		break;
307
308	case SAM_EVENT_CID_BAT_PROT:
309		/*
310		 * TODO: Implement support for battery protection status change
311		 *       event.
312		 */
313		return true;
314
315	case SAM_EVENT_CID_BAT_DPTF:
316		status = san_evt_bat_dptf(dev, event);
317		break;
318
319	default:
320		return false;
321	}
322
323	if (status) {
324		dev_err(dev, "error handling power event (cid = %#04x)\n",
325			event->command_id);
326	}
327
328	return true;
329}
330
331static void san_evt_bat_workfn(struct work_struct *work)
332{
333	struct san_event_work *ev;
334
335	ev = container_of(work, struct san_event_work, work.work);
336	san_evt_bat(&ev->event, ev->dev);
337	kfree(ev);
338}
339
340static u32 san_evt_bat_nf(struct ssam_event_notifier *nf,
341			  const struct ssam_event *event)
342{
343	struct san_data *d = to_san_data(nf, nf_bat);
344	struct san_event_work *work;
345	unsigned long delay = san_evt_bat_delay(event->command_id);
346
347	if (delay == 0)
348		return san_evt_bat(event, d->dev) ? SSAM_NOTIF_HANDLED : 0;
349
350	work = kzalloc(sizeof(*work) + event->length, GFP_KERNEL);
351	if (!work)
352		return ssam_notifier_from_errno(-ENOMEM);
353
354	INIT_DELAYED_WORK(&work->work, san_evt_bat_workfn);
355	work->dev = d->dev;
356
357	memcpy(&work->event, event, sizeof(struct ssam_event) + event->length);
358
359	schedule_delayed_work(&work->work, delay);
360	return SSAM_NOTIF_HANDLED;
361}
362
363static int san_evt_tmp_trip(struct device *dev, const struct ssam_event *event)
364{
365	union acpi_object param;
366
367	/*
368	 * The Surface ACPI expects an integer and not a package. This will
369	 * cause a warning in acpica/nsarguments.c, but that warning can be
370	 * safely ignored.
371	 */
372	param.type = ACPI_TYPE_INTEGER;
373	param.integer.value = event->instance_id;
374
375	return san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_THERMAL, &param);
376}
377
378static bool san_evt_tmp(const struct ssam_event *event, struct device *dev)
379{
380	int status;
381
382	switch (event->command_id) {
383	case SAM_EVENT_CID_TMP_TRIP:
384		status = san_evt_tmp_trip(dev, event);
385		break;
386
387	default:
388		return false;
389	}
390
391	if (status) {
392		dev_err(dev, "error handling thermal event (cid = %#04x)\n",
393			event->command_id);
394	}
395
396	return true;
397}
398
399static u32 san_evt_tmp_nf(struct ssam_event_notifier *nf,
400			  const struct ssam_event *event)
401{
402	struct san_data *d = to_san_data(nf, nf_tmp);
403
404	return san_evt_tmp(event, d->dev) ? SSAM_NOTIF_HANDLED : 0;
405}
406
407
408/* -- ACPI GSB OperationRegion handler -------------------------------------- */
409
410struct gsb_data_in {
411	u8 cv;
412} __packed;
413
414struct gsb_data_rqsx {
415	u8 cv;				/* Command value (san_gsb_request_cv). */
416	u8 tc;				/* Target category. */
417	u8 tid;				/* Target ID. */
418	u8 iid;				/* Instance ID. */
419	u8 snc;				/* Expect-response-flag. */
420	u8 cid;				/* Command ID. */
421	u16 cdl;			/* Payload length. */
422	u8 pld[];			/* Payload. */
423} __packed;
424
425struct gsb_data_etwl {
426	u8 cv;				/* Command value (should be 0x02). */
427	u8 etw3;			/* Unknown. */
428	u8 etw4;			/* Unknown. */
429	u8 msg[];			/* Error message (ASCIIZ). */
430} __packed;
431
432struct gsb_data_out {
433	u8 status;			/* _SSH communication status. */
434	u8 len;				/* _SSH payload length. */
435	u8 pld[];			/* _SSH payload. */
436} __packed;
437
438union gsb_buffer_data {
439	struct gsb_data_in   in;	/* Common input. */
440	struct gsb_data_rqsx rqsx;	/* RQSX input. */
441	struct gsb_data_etwl etwl;	/* ETWL input. */
442	struct gsb_data_out  out;	/* Output. */
443};
444
445struct gsb_buffer {
446	u8 status;			/* GSB AttribRawProcess status. */
447	u8 len;				/* GSB AttribRawProcess length. */
448	union gsb_buffer_data data;
449} __packed;
450
451#define SAN_GSB_MAX_RQSX_PAYLOAD  (U8_MAX - 2 - sizeof(struct gsb_data_rqsx))
452#define SAN_GSB_MAX_RESPONSE	  (U8_MAX - 2 - sizeof(struct gsb_data_out))
453
454#define SAN_GSB_COMMAND		0
455
456enum san_gsb_request_cv {
457	SAN_GSB_REQUEST_CV_RQST = 0x01,
458	SAN_GSB_REQUEST_CV_ETWL = 0x02,
459	SAN_GSB_REQUEST_CV_RQSG = 0x03,
460};
461
462#define SAN_REQUEST_NUM_TRIES	5
463
464static acpi_status san_etwl(struct san_data *d, struct gsb_buffer *b)
465{
466	struct gsb_data_etwl *etwl = &b->data.etwl;
467
468	if (b->len < sizeof(struct gsb_data_etwl)) {
469		dev_err(d->dev, "invalid ETWL package (len = %d)\n", b->len);
470		return AE_OK;
471	}
472
473	dev_err(d->dev, "ETWL(%#04x, %#04x): %.*s\n", etwl->etw3, etwl->etw4,
474		(unsigned int)(b->len - sizeof(struct gsb_data_etwl)),
475		(char *)etwl->msg);
476
477	/* Indicate success. */
478	b->status = 0x00;
479	b->len = 0x00;
480
481	return AE_OK;
482}
483
484static
485struct gsb_data_rqsx *san_validate_rqsx(struct device *dev, const char *type,
486					struct gsb_buffer *b)
487{
488	struct gsb_data_rqsx *rqsx = &b->data.rqsx;
489
490	if (b->len < sizeof(struct gsb_data_rqsx)) {
491		dev_err(dev, "invalid %s package (len = %d)\n", type, b->len);
492		return NULL;
493	}
494
495	if (get_unaligned(&rqsx->cdl) != b->len - sizeof(struct gsb_data_rqsx)) {
496		dev_err(dev, "bogus %s package (len = %d, cdl = %d)\n",
497			type, b->len, get_unaligned(&rqsx->cdl));
498		return NULL;
499	}
500
501	if (get_unaligned(&rqsx->cdl) > SAN_GSB_MAX_RQSX_PAYLOAD) {
502		dev_err(dev, "payload for %s package too large (cdl = %d)\n",
503			type, get_unaligned(&rqsx->cdl));
504		return NULL;
505	}
506
507	return rqsx;
508}
509
510static void gsb_rqsx_response_error(struct gsb_buffer *gsb, int status)
511{
512	gsb->status = 0x00;
513	gsb->len = 0x02;
514	gsb->data.out.status = (u8)(-status);
515	gsb->data.out.len = 0x00;
516}
517
518static void gsb_rqsx_response_success(struct gsb_buffer *gsb, u8 *ptr, size_t len)
519{
520	gsb->status = 0x00;
521	gsb->len = len + 2;
522	gsb->data.out.status = 0x00;
523	gsb->data.out.len = len;
524
525	if (len)
526		memcpy(&gsb->data.out.pld[0], ptr, len);
527}
528
529static acpi_status san_rqst_fixup_suspended(struct san_data *d,
530					    struct ssam_request *rqst,
531					    struct gsb_buffer *gsb)
532{
533	if (rqst->target_category == SSAM_SSH_TC_BAS && rqst->command_id == 0x0D) {
534		u8 base_state = 1;
535
536		/* Base state quirk:
537		 * The base state may be queried from ACPI when the EC is still
538		 * suspended. In this case it will return '-EPERM'. This query
539		 * will only be triggered from the ACPI lid GPE interrupt, thus
540		 * we are either in laptop or studio mode (base status 0x01 or
541		 * 0x02). Furthermore, we will only get here if the device (and
542		 * EC) have been suspended.
543		 *
544		 * We now assume that the device is in laptop mode (0x01). This
545		 * has the drawback that it will wake the device when unfolding
546		 * it in studio mode, but it also allows us to avoid actively
547		 * waiting for the EC to wake up, which may incur a notable
548		 * delay.
549		 */
550
551		dev_dbg(d->dev, "rqst: fixup: base-state quirk\n");
552
553		gsb_rqsx_response_success(gsb, &base_state, sizeof(base_state));
554		return AE_OK;
555	}
556
557	gsb_rqsx_response_error(gsb, -ENXIO);
558	return AE_OK;
559}
560
561static acpi_status san_rqst(struct san_data *d, struct gsb_buffer *buffer)
562{
563	u8 rspbuf[SAN_GSB_MAX_RESPONSE];
564	struct gsb_data_rqsx *gsb_rqst;
565	struct ssam_request rqst;
566	struct ssam_response rsp;
567	int status = 0;
568
569	gsb_rqst = san_validate_rqsx(d->dev, "RQST", buffer);
570	if (!gsb_rqst)
571		return AE_OK;
572
573	rqst.target_category = gsb_rqst->tc;
574	rqst.target_id = gsb_rqst->tid;
575	rqst.command_id = gsb_rqst->cid;
576	rqst.instance_id = gsb_rqst->iid;
577	rqst.flags = gsb_rqst->snc ? SSAM_REQUEST_HAS_RESPONSE : 0;
578	rqst.length = get_unaligned(&gsb_rqst->cdl);
579	rqst.payload = &gsb_rqst->pld[0];
580
581	rsp.capacity = ARRAY_SIZE(rspbuf);
582	rsp.length = 0;
583	rsp.pointer = &rspbuf[0];
584
585	/* Handle suspended device. */
586	if (d->dev->power.is_suspended) {
587		dev_warn(d->dev, "rqst: device is suspended, not executing\n");
588		return san_rqst_fixup_suspended(d, &rqst, buffer);
589	}
590
591	status = __ssam_retry(ssam_request_sync_onstack, SAN_REQUEST_NUM_TRIES,
592			      d->ctrl, &rqst, &rsp, SAN_GSB_MAX_RQSX_PAYLOAD);
593
594	if (!status) {
595		gsb_rqsx_response_success(buffer, rsp.pointer, rsp.length);
596	} else {
597		dev_err(d->dev, "rqst: failed with error %d\n", status);
598		gsb_rqsx_response_error(buffer, status);
599	}
600
601	return AE_OK;
602}
603
604static acpi_status san_rqsg(struct san_data *d, struct gsb_buffer *buffer)
605{
606	struct gsb_data_rqsx *gsb_rqsg;
607	struct san_dgpu_event evt;
608	int status;
609
610	gsb_rqsg = san_validate_rqsx(d->dev, "RQSG", buffer);
611	if (!gsb_rqsg)
612		return AE_OK;
613
614	evt.category = gsb_rqsg->tc;
615	evt.target = gsb_rqsg->tid;
616	evt.command = gsb_rqsg->cid;
617	evt.instance = gsb_rqsg->iid;
618	evt.length = get_unaligned(&gsb_rqsg->cdl);
619	evt.payload = &gsb_rqsg->pld[0];
620
621	status = san_dgpu_notifier_call(&evt);
622	if (!status) {
623		gsb_rqsx_response_success(buffer, NULL, 0);
624	} else {
625		dev_err(d->dev, "rqsg: failed with error %d\n", status);
626		gsb_rqsx_response_error(buffer, status);
627	}
628
629	return AE_OK;
630}
631
632static acpi_status san_opreg_handler(u32 function, acpi_physical_address command,
633				     u32 bits, u64 *value64, void *opreg_context,
634				     void *region_context)
635{
636	struct san_data *d = to_san_data(opreg_context, info);
637	struct gsb_buffer *buffer = (struct gsb_buffer *)value64;
638	int accessor_type = (function & 0xFFFF0000) >> 16;
639
640	if (command != SAN_GSB_COMMAND) {
641		dev_warn(d->dev, "unsupported command: %#04llx\n", command);
642		return AE_OK;
643	}
644
645	if (accessor_type != ACPI_GSB_ACCESS_ATTRIB_RAW_PROCESS) {
646		dev_err(d->dev, "invalid access type: %#04x\n", accessor_type);
647		return AE_OK;
648	}
649
650	/* Buffer must have at least contain the command-value. */
651	if (buffer->len == 0) {
652		dev_err(d->dev, "request-package too small\n");
653		return AE_OK;
654	}
655
656	switch (buffer->data.in.cv) {
657	case SAN_GSB_REQUEST_CV_RQST:
658		return san_rqst(d, buffer);
659
660	case SAN_GSB_REQUEST_CV_ETWL:
661		return san_etwl(d, buffer);
662
663	case SAN_GSB_REQUEST_CV_RQSG:
664		return san_rqsg(d, buffer);
665
666	default:
667		dev_warn(d->dev, "unsupported SAN0 request (cv: %#04x)\n",
668			 buffer->data.in.cv);
669		return AE_OK;
670	}
671}
672
673
674/* -- Driver setup. --------------------------------------------------------- */
675
676static int san_events_register(struct platform_device *pdev)
677{
678	struct san_data *d = platform_get_drvdata(pdev);
679	int status;
680
681	d->nf_bat.base.priority = 1;
682	d->nf_bat.base.fn = san_evt_bat_nf;
683	d->nf_bat.event.reg = SSAM_EVENT_REGISTRY_SAM;
684	d->nf_bat.event.id.target_category = SSAM_SSH_TC_BAT;
685	d->nf_bat.event.id.instance = 0;
686	d->nf_bat.event.mask = SSAM_EVENT_MASK_TARGET;
687	d->nf_bat.event.flags = SSAM_EVENT_SEQUENCED;
688
689	d->nf_tmp.base.priority = 1;
690	d->nf_tmp.base.fn = san_evt_tmp_nf;
691	d->nf_tmp.event.reg = SSAM_EVENT_REGISTRY_SAM;
692	d->nf_tmp.event.id.target_category = SSAM_SSH_TC_TMP;
693	d->nf_tmp.event.id.instance = 0;
694	d->nf_tmp.event.mask = SSAM_EVENT_MASK_TARGET;
695	d->nf_tmp.event.flags = SSAM_EVENT_SEQUENCED;
696
697	status = ssam_notifier_register(d->ctrl, &d->nf_bat);
698	if (status)
699		return status;
700
701	status = ssam_notifier_register(d->ctrl, &d->nf_tmp);
702	if (status)
703		ssam_notifier_unregister(d->ctrl, &d->nf_bat);
704
705	return status;
706}
707
708static void san_events_unregister(struct platform_device *pdev)
709{
710	struct san_data *d = platform_get_drvdata(pdev);
711
712	ssam_notifier_unregister(d->ctrl, &d->nf_bat);
713	ssam_notifier_unregister(d->ctrl, &d->nf_tmp);
714}
715
716#define san_consumer_printk(level, dev, handle, fmt, ...)			\
717do {										\
718	char *path = "<error getting consumer path>";				\
719	struct acpi_buffer buffer = {						\
720		.length = ACPI_ALLOCATE_BUFFER,					\
721		.pointer = NULL,						\
722	};									\
723										\
724	if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer)))	\
725		path = buffer.pointer;						\
726										\
727	dev_##level(dev, "[%s]: " fmt, path, ##__VA_ARGS__);			\
728	kfree(buffer.pointer);							\
729} while (0)
730
731#define san_consumer_dbg(dev, handle, fmt, ...) \
732	san_consumer_printk(dbg, dev, handle, fmt, ##__VA_ARGS__)
733
734#define san_consumer_warn(dev, handle, fmt, ...) \
735	san_consumer_printk(warn, dev, handle, fmt, ##__VA_ARGS__)
736
737static bool is_san_consumer(struct platform_device *pdev, acpi_handle handle)
738{
739	struct acpi_handle_list dep_devices;
740	acpi_handle supplier = ACPI_HANDLE(&pdev->dev);
741	acpi_status status;
742	int i;
743
744	if (!acpi_has_method(handle, "_DEP"))
745		return false;
746
747	status = acpi_evaluate_reference(handle, "_DEP", NULL, &dep_devices);
748	if (ACPI_FAILURE(status)) {
749		san_consumer_dbg(&pdev->dev, handle, "failed to evaluate _DEP\n");
750		return false;
751	}
752
753	for (i = 0; i < dep_devices.count; i++) {
754		if (dep_devices.handles[i] == supplier)
755			return true;
756	}
757
758	return false;
759}
760
761static acpi_status san_consumer_setup(acpi_handle handle, u32 lvl,
762				      void *context, void **rv)
763{
764	const u32 flags = DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER;
765	struct platform_device *pdev = context;
766	struct acpi_device *adev;
767	struct device_link *link;
768
769	if (!is_san_consumer(pdev, handle))
770		return AE_OK;
771
772	/* Ignore ACPI devices that are not present. */
773	if (acpi_bus_get_device(handle, &adev) != 0)
774		return AE_OK;
775
776	san_consumer_dbg(&pdev->dev, handle, "creating device link\n");
777
778	/* Try to set up device links, ignore but log errors. */
779	link = device_link_add(&adev->dev, &pdev->dev, flags);
780	if (!link) {
781		san_consumer_warn(&pdev->dev, handle, "failed to create device link\n");
782		return AE_OK;
783	}
784
785	return AE_OK;
786}
787
788static int san_consumer_links_setup(struct platform_device *pdev)
789{
790	acpi_status status;
791
792	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
793				     ACPI_UINT32_MAX, san_consumer_setup, NULL,
794				     pdev, NULL);
795
796	return status ? -EFAULT : 0;
797}
798
799static int san_probe(struct platform_device *pdev)
800{
801	struct acpi_device *san = ACPI_COMPANION(&pdev->dev);
802	struct ssam_controller *ctrl;
803	struct san_data *data;
804	acpi_status astatus;
805	int status;
806
807	ctrl = ssam_client_bind(&pdev->dev);
808	if (IS_ERR(ctrl))
809		return PTR_ERR(ctrl) == -ENODEV ? -EPROBE_DEFER : PTR_ERR(ctrl);
810
811	status = san_consumer_links_setup(pdev);
812	if (status)
813		return status;
814
815	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
816	if (!data)
817		return -ENOMEM;
818
819	data->dev = &pdev->dev;
820	data->ctrl = ctrl;
821
822	platform_set_drvdata(pdev, data);
823
824	astatus = acpi_install_address_space_handler(san->handle,
825						     ACPI_ADR_SPACE_GSBUS,
826						     &san_opreg_handler, NULL,
827						     &data->info);
828	if (ACPI_FAILURE(astatus))
829		return -ENXIO;
830
831	status = san_events_register(pdev);
832	if (status)
833		goto err_enable_events;
834
835	status = san_set_rqsg_interface_device(&pdev->dev);
836	if (status)
837		goto err_install_dev;
838
839	acpi_dev_clear_dependencies(san);
840	return 0;
841
842err_install_dev:
843	san_events_unregister(pdev);
844err_enable_events:
845	acpi_remove_address_space_handler(san, ACPI_ADR_SPACE_GSBUS,
846					  &san_opreg_handler);
847	return status;
848}
849
850static int san_remove(struct platform_device *pdev)
851{
852	acpi_handle san = ACPI_HANDLE(&pdev->dev);
853
854	san_set_rqsg_interface_device(NULL);
855	acpi_remove_address_space_handler(san, ACPI_ADR_SPACE_GSBUS,
856					  &san_opreg_handler);
857	san_events_unregister(pdev);
858
859	/*
860	 * We have unregistered our event sources. Now we need to ensure that
861	 * all delayed works they may have spawned are run to completion.
862	 */
863	flush_scheduled_work();
864
865	return 0;
866}
867
868static const struct acpi_device_id san_match[] = {
869	{ "MSHW0091" },
870	{ },
871};
872MODULE_DEVICE_TABLE(acpi, san_match);
873
874static struct platform_driver surface_acpi_notify = {
875	.probe = san_probe,
876	.remove = san_remove,
877	.driver = {
878		.name = "surface_acpi_notify",
879		.acpi_match_table = san_match,
880		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
881	},
882};
883module_platform_driver(surface_acpi_notify);
884
885MODULE_AUTHOR("Maximilian Luz <luzmaximilian@gmail.com>");
886MODULE_DESCRIPTION("Surface ACPI Notify driver for Surface System Aggregator Module");
887MODULE_LICENSE("GPL");