]> Git Repo - linux.git/blob - drivers/platform/surface/surface_acpi_notify.c
Linux 6.14-rc3
[linux.git] / drivers / platform / surface / surface_acpi_notify.c
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-2022 Maximilian Luz <[email protected]>
12  */
13
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>
23
24 #include <linux/surface_aggregator/controller.h>
25 #include <linux/surface_acpi_notify.h>
26
27 struct 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 static struct workqueue_struct *san_wq;
41
42 /* -- dGPU notifier interface. ---------------------------------------------- */
43
44 struct san_rqsg_if {
45         struct rw_semaphore lock;
46         struct device *dev;
47         struct blocking_notifier_head nh;
48 };
49
50 static struct san_rqsg_if san_rqsg_if = {
51         .lock = __RWSEM_INITIALIZER(san_rqsg_if.lock),
52         .dev = NULL,
53         .nh = BLOCKING_NOTIFIER_INIT(san_rqsg_if.nh),
54 };
55
56 static int san_set_rqsg_interface_device(struct device *dev)
57 {
58         int status = 0;
59
60         down_write(&san_rqsg_if.lock);
61         if (!san_rqsg_if.dev && dev)
62                 san_rqsg_if.dev = dev;
63         else
64                 status = -EBUSY;
65         up_write(&san_rqsg_if.lock);
66
67         return status;
68 }
69
70 /**
71  * san_client_link() - Link client as consumer to SAN device.
72  * @client: The client to link.
73  *
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.
79  *
80  * The link will be automatically removed once the client device's driver is
81  * unbound.
82  *
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.
85  */
86 int san_client_link(struct device *client)
87 {
88         const u32 flags = DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_CONSUMER;
89         struct device_link *link;
90
91         down_read(&san_rqsg_if.lock);
92
93         if (!san_rqsg_if.dev) {
94                 up_read(&san_rqsg_if.lock);
95                 return -ENXIO;
96         }
97
98         link = device_link_add(client, san_rqsg_if.dev, flags);
99         if (!link) {
100                 up_read(&san_rqsg_if.lock);
101                 return -ENOMEM;
102         }
103
104         if (READ_ONCE(link->status) == DL_STATE_SUPPLIER_UNBIND) {
105                 up_read(&san_rqsg_if.lock);
106                 return -ENXIO;
107         }
108
109         up_read(&san_rqsg_if.lock);
110         return 0;
111 }
112 EXPORT_SYMBOL_GPL(san_client_link);
113
114 /**
115  * san_dgpu_notifier_register() - Register a SAN dGPU notifier.
116  * @nb: The notifier-block to register.
117  *
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.
121  */
122 int san_dgpu_notifier_register(struct notifier_block *nb)
123 {
124         return blocking_notifier_chain_register(&san_rqsg_if.nh, nb);
125 }
126 EXPORT_SYMBOL_GPL(san_dgpu_notifier_register);
127
128 /**
129  * san_dgpu_notifier_unregister() - Unregister a SAN dGPU notifier.
130  * @nb: The notifier-block to unregister.
131  */
132 int san_dgpu_notifier_unregister(struct notifier_block *nb)
133 {
134         return blocking_notifier_chain_unregister(&san_rqsg_if.nh, nb);
135 }
136 EXPORT_SYMBOL_GPL(san_dgpu_notifier_unregister);
137
138 static int san_dgpu_notifier_call(struct san_dgpu_event *evt)
139 {
140         int ret;
141
142         ret = blocking_notifier_call_chain(&san_rqsg_if.nh, evt->command, evt);
143         return notifier_to_errno(ret);
144 }
145
146
147 /* -- ACPI _DSM event relay. ------------------------------------------------ */
148
149 #define SAN_DSM_REVISION        0
150
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);
155
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,
165 };
166
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,
173 };
174
175 enum sam_event_cid_tmp {
176         SAM_EVENT_CID_TMP_TRIP = 0x0b,
177 };
178
179 struct san_event_work {
180         struct delayed_work work;
181         struct device *dev;
182         struct ssam_event event;        /* must be last */
183 };
184
185 static int san_acpi_notify_event(struct device *dev, u64 func,
186                                  union acpi_object *param)
187 {
188         acpi_handle san = ACPI_HANDLE(dev);
189         union acpi_object *obj;
190         int status = 0;
191
192         if (!acpi_check_dsm(san, &SAN_DSM_UUID, SAN_DSM_REVISION, BIT_ULL(func)))
193                 return 0;
194
195         dev_dbg(dev, "notify event %#04llx\n", func);
196
197         obj = acpi_evaluate_dsm_typed(san, &SAN_DSM_UUID, SAN_DSM_REVISION,
198                                       func, param, ACPI_TYPE_BUFFER);
199         if (!obj)
200                 return -EFAULT;
201
202         if (obj->buffer.length != 1 || obj->buffer.pointer[0] != 0) {
203                 dev_err(dev, "got unexpected result from _DSM\n");
204                 status = -EPROTO;
205         }
206
207         ACPI_FREE(obj);
208         return status;
209 }
210
211 static int san_evt_bat_adp(struct device *dev, const struct ssam_event *event)
212 {
213         int status;
214
215         status = san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_ADP1_STAT, NULL);
216         if (status)
217                 return status;
218
219         /*
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.
224          */
225
226         status = san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_BAT1_STAT, NULL);
227         if (status)
228                 return status;
229
230         return san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_BAT2_STAT, NULL);
231 }
232
233 static int san_evt_bat_bix(struct device *dev, const struct ssam_event *event)
234 {
235         enum san_dsm_event_fn fn;
236
237         if (event->instance_id == 0x02)
238                 fn = SAN_DSM_EVENT_FN_BAT2_INFO;
239         else
240                 fn = SAN_DSM_EVENT_FN_BAT1_INFO;
241
242         return san_acpi_notify_event(dev, fn, NULL);
243 }
244
245 static int san_evt_bat_bst(struct device *dev, const struct ssam_event *event)
246 {
247         enum san_dsm_event_fn fn;
248
249         if (event->instance_id == 0x02)
250                 fn = SAN_DSM_EVENT_FN_BAT2_STAT;
251         else
252                 fn = SAN_DSM_EVENT_FN_BAT1_STAT;
253
254         return san_acpi_notify_event(dev, fn, NULL);
255 }
256
257 static int san_evt_bat_dptf(struct device *dev, const struct ssam_event *event)
258 {
259         union acpi_object payload;
260
261         /*
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.
265          */
266         payload.type = ACPI_TYPE_BUFFER;
267         payload.buffer.length = event->length;
268         payload.buffer.pointer = (u8 *)&event->data[0];
269
270         return san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_DPTF, &payload);
271 }
272
273 static unsigned long san_evt_bat_delay(u8 cid)
274 {
275         switch (cid) {
276         case SAM_EVENT_CID_BAT_ADP:
277                 /*
278                  * Wait for battery state to update before signaling adapter
279                  * change.
280                  */
281                 return msecs_to_jiffies(5000);
282
283         case SAM_EVENT_CID_BAT_BST:
284                 /* Ensure we do not miss anything important due to caching. */
285                 return msecs_to_jiffies(2000);
286
287         default:
288                 return 0;
289         }
290 }
291
292 static bool san_evt_bat(const struct ssam_event *event, struct device *dev)
293 {
294         int status;
295
296         switch (event->command_id) {
297         case SAM_EVENT_CID_BAT_BIX:
298                 status = san_evt_bat_bix(dev, event);
299                 break;
300
301         case SAM_EVENT_CID_BAT_BST:
302                 status = san_evt_bat_bst(dev, event);
303                 break;
304
305         case SAM_EVENT_CID_BAT_ADP:
306                 status = san_evt_bat_adp(dev, event);
307                 break;
308
309         case SAM_EVENT_CID_BAT_PROT:
310                 /*
311                  * TODO: Implement support for battery protection status change
312                  *       event.
313                  */
314                 return true;
315
316         case SAM_EVENT_CID_BAT_DPTF:
317                 status = san_evt_bat_dptf(dev, event);
318                 break;
319
320         default:
321                 return false;
322         }
323
324         if (status) {
325                 dev_err(dev, "error handling power event (cid = %#04x)\n",
326                         event->command_id);
327         }
328
329         return true;
330 }
331
332 static void san_evt_bat_workfn(struct work_struct *work)
333 {
334         struct san_event_work *ev;
335
336         ev = container_of(work, struct san_event_work, work.work);
337         san_evt_bat(&ev->event, ev->dev);
338         kfree(ev);
339 }
340
341 static u32 san_evt_bat_nf(struct ssam_event_notifier *nf,
342                           const struct ssam_event *event)
343 {
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);
347
348         if (delay == 0)
349                 return san_evt_bat(event, d->dev) ? SSAM_NOTIF_HANDLED : 0;
350
351         work = kzalloc(sizeof(*work) + event->length, GFP_KERNEL);
352         if (!work)
353                 return ssam_notifier_from_errno(-ENOMEM);
354
355         INIT_DELAYED_WORK(&work->work, san_evt_bat_workfn);
356         work->dev = d->dev;
357
358         work->event = *event;
359         memcpy(work->event.data, event->data, event->length);
360
361         queue_delayed_work(san_wq, &work->work, delay);
362         return SSAM_NOTIF_HANDLED;
363 }
364
365 static int san_evt_tmp_trip(struct device *dev, const struct ssam_event *event)
366 {
367         union acpi_object param;
368
369         /*
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
372          * safely ignored.
373          */
374         param.type = ACPI_TYPE_INTEGER;
375         param.integer.value = event->instance_id;
376
377         return san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_THERMAL, &param);
378 }
379
380 static bool san_evt_tmp(const struct ssam_event *event, struct device *dev)
381 {
382         int status;
383
384         switch (event->command_id) {
385         case SAM_EVENT_CID_TMP_TRIP:
386                 status = san_evt_tmp_trip(dev, event);
387                 break;
388
389         default:
390                 return false;
391         }
392
393         if (status) {
394                 dev_err(dev, "error handling thermal event (cid = %#04x)\n",
395                         event->command_id);
396         }
397
398         return true;
399 }
400
401 static u32 san_evt_tmp_nf(struct ssam_event_notifier *nf,
402                           const struct ssam_event *event)
403 {
404         struct san_data *d = to_san_data(nf, nf_tmp);
405
406         return san_evt_tmp(event, d->dev) ? SSAM_NOTIF_HANDLED : 0;
407 }
408
409
410 /* -- ACPI GSB OperationRegion handler -------------------------------------- */
411
412 struct gsb_data_in {
413         u8 cv;
414 } __packed;
415
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. */
425 } __packed;
426
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). */
432 } __packed;
433
434 struct gsb_data_out {
435         u8 status;                      /* _SSH communication status. */
436         u8 len;                         /* _SSH payload length. */
437         u8 pld[];                       /* _SSH payload. */
438 } __packed;
439
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. */
445 };
446
447 struct gsb_buffer {
448         u8 status;                      /* GSB AttribRawProcess status. */
449         u8 len;                         /* GSB AttribRawProcess length. */
450         union gsb_buffer_data data;
451 } __packed;
452
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))
455
456 #define SAN_GSB_COMMAND         0
457
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,
462 };
463
464 #define SAN_REQUEST_NUM_TRIES   5
465
466 static acpi_status san_etwl(struct san_data *d, struct gsb_buffer *b)
467 {
468         struct gsb_data_etwl *etwl = &b->data.etwl;
469
470         if (b->len < sizeof(struct gsb_data_etwl)) {
471                 dev_err(d->dev, "invalid ETWL package (len = %d)\n", b->len);
472                 return AE_OK;
473         }
474
475         dev_err(d->dev, "ETWL(%#04x, %#04x): %.*s\n", etwl->etw3, etwl->etw4,
476                 (unsigned int)(b->len - sizeof(struct gsb_data_etwl)),
477                 (char *)etwl->msg);
478
479         /* Indicate success. */
480         b->status = 0x00;
481         b->len = 0x00;
482
483         return AE_OK;
484 }
485
486 static
487 struct gsb_data_rqsx *san_validate_rqsx(struct device *dev, const char *type,
488                                         struct gsb_buffer *b)
489 {
490         struct gsb_data_rqsx *rqsx = &b->data.rqsx;
491
492         if (b->len < sizeof(struct gsb_data_rqsx)) {
493                 dev_err(dev, "invalid %s package (len = %d)\n", type, b->len);
494                 return NULL;
495         }
496
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));
500                 return NULL;
501         }
502
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));
506                 return NULL;
507         }
508
509         return rqsx;
510 }
511
512 static void gsb_rqsx_response_error(struct gsb_buffer *gsb, int status)
513 {
514         gsb->status = 0x00;
515         gsb->len = 0x02;
516         gsb->data.out.status = (u8)(-status);
517         gsb->data.out.len = 0x00;
518 }
519
520 static void gsb_rqsx_response_success(struct gsb_buffer *gsb, u8 *ptr, size_t len)
521 {
522         gsb->status = 0x00;
523         gsb->len = len + 2;
524         gsb->data.out.status = 0x00;
525         gsb->data.out.len = len;
526
527         if (len)
528                 memcpy(&gsb->data.out.pld[0], ptr, len);
529 }
530
531 static acpi_status san_rqst_fixup_suspended(struct san_data *d,
532                                             struct ssam_request *rqst,
533                                             struct gsb_buffer *gsb)
534 {
535         if (rqst->target_category == SSAM_SSH_TC_BAS && rqst->command_id == 0x0D) {
536                 u8 base_state = 1;
537
538                 /* Base state quirk:
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.
545                  *
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
550                  * delay.
551                  */
552
553                 dev_dbg(d->dev, "rqst: fixup: base-state quirk\n");
554
555                 gsb_rqsx_response_success(gsb, &base_state, sizeof(base_state));
556                 return AE_OK;
557         }
558
559         gsb_rqsx_response_error(gsb, -ENXIO);
560         return AE_OK;
561 }
562
563 static acpi_status san_rqst(struct san_data *d, struct gsb_buffer *buffer)
564 {
565         u8 rspbuf[SAN_GSB_MAX_RESPONSE];
566         struct gsb_data_rqsx *gsb_rqst;
567         struct ssam_request rqst;
568         struct ssam_response rsp;
569         int status = 0;
570
571         gsb_rqst = san_validate_rqsx(d->dev, "RQST", buffer);
572         if (!gsb_rqst)
573                 return AE_OK;
574
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];
582
583         rsp.capacity = ARRAY_SIZE(rspbuf);
584         rsp.length = 0;
585         rsp.pointer = &rspbuf[0];
586
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);
591         }
592
593         status = __ssam_retry(ssam_request_do_sync_onstack, SAN_REQUEST_NUM_TRIES,
594                               d->ctrl, &rqst, &rsp, SAN_GSB_MAX_RQSX_PAYLOAD);
595
596         if (!status) {
597                 gsb_rqsx_response_success(buffer, rsp.pointer, rsp.length);
598         } else {
599                 dev_err(d->dev, "rqst: failed with error %d\n", status);
600                 gsb_rqsx_response_error(buffer, status);
601         }
602
603         return AE_OK;
604 }
605
606 static acpi_status san_rqsg(struct san_data *d, struct gsb_buffer *buffer)
607 {
608         struct gsb_data_rqsx *gsb_rqsg;
609         struct san_dgpu_event evt;
610         int status;
611
612         gsb_rqsg = san_validate_rqsx(d->dev, "RQSG", buffer);
613         if (!gsb_rqsg)
614                 return AE_OK;
615
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];
622
623         status = san_dgpu_notifier_call(&evt);
624         if (!status) {
625                 gsb_rqsx_response_success(buffer, NULL, 0);
626         } else {
627                 dev_err(d->dev, "rqsg: failed with error %d\n", status);
628                 gsb_rqsx_response_error(buffer, status);
629         }
630
631         return AE_OK;
632 }
633
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)
637 {
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;
641
642         if (command != SAN_GSB_COMMAND) {
643                 dev_warn(d->dev, "unsupported command: %#04llx\n", command);
644                 return AE_OK;
645         }
646
647         if (accessor_type != ACPI_GSB_ACCESS_ATTRIB_RAW_PROCESS) {
648                 dev_err(d->dev, "invalid access type: %#04x\n", accessor_type);
649                 return AE_OK;
650         }
651
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");
655                 return AE_OK;
656         }
657
658         switch (buffer->data.in.cv) {
659         case SAN_GSB_REQUEST_CV_RQST:
660                 return san_rqst(d, buffer);
661
662         case SAN_GSB_REQUEST_CV_ETWL:
663                 return san_etwl(d, buffer);
664
665         case SAN_GSB_REQUEST_CV_RQSG:
666                 return san_rqsg(d, buffer);
667
668         default:
669                 dev_warn(d->dev, "unsupported SAN0 request (cv: %#04x)\n",
670                          buffer->data.in.cv);
671                 return AE_OK;
672         }
673 }
674
675
676 /* -- Driver setup. --------------------------------------------------------- */
677
678 static int san_events_register(struct platform_device *pdev)
679 {
680         struct san_data *d = platform_get_drvdata(pdev);
681         int status;
682
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;
690
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;
698
699         status = ssam_notifier_register(d->ctrl, &d->nf_bat);
700         if (status)
701                 return status;
702
703         status = ssam_notifier_register(d->ctrl, &d->nf_tmp);
704         if (status)
705                 ssam_notifier_unregister(d->ctrl, &d->nf_bat);
706
707         return status;
708 }
709
710 static void san_events_unregister(struct platform_device *pdev)
711 {
712         struct san_data *d = platform_get_drvdata(pdev);
713
714         ssam_notifier_unregister(d->ctrl, &d->nf_bat);
715         ssam_notifier_unregister(d->ctrl, &d->nf_tmp);
716 }
717
718 #define san_consumer_printk(level, dev, handle, fmt, ...)                       \
719 do {                                                                            \
720         char *path = "<error getting consumer path>";                           \
721         struct acpi_buffer buffer = {                                           \
722                 .length = ACPI_ALLOCATE_BUFFER,                                 \
723                 .pointer = NULL,                                                \
724         };                                                                      \
725                                                                                 \
726         if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer)))   \
727                 path = buffer.pointer;                                          \
728                                                                                 \
729         dev_##level(dev, "[%s]: " fmt, path, ##__VA_ARGS__);                    \
730         kfree(buffer.pointer);                                                  \
731 } while (0)
732
733 #define san_consumer_dbg(dev, handle, fmt, ...) \
734         san_consumer_printk(dbg, dev, handle, fmt, ##__VA_ARGS__)
735
736 #define san_consumer_warn(dev, handle, fmt, ...) \
737         san_consumer_printk(warn, dev, handle, fmt, ##__VA_ARGS__)
738
739 static acpi_status san_consumer_setup(acpi_handle handle, u32 lvl,
740                                       void *context, void **rv)
741 {
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;
746
747         if (!acpi_device_dep(handle, ACPI_HANDLE(&pdev->dev)))
748                 return AE_OK;
749
750         /* Ignore ACPI devices that are not present. */
751         adev = acpi_fetch_acpi_dev(handle);
752         if (!adev)
753                 return AE_OK;
754
755         san_consumer_dbg(&pdev->dev, handle, "creating device link\n");
756
757         /* Try to set up device links, ignore but log errors. */
758         link = device_link_add(&adev->dev, &pdev->dev, flags);
759         if (!link) {
760                 san_consumer_warn(&pdev->dev, handle, "failed to create device link\n");
761                 return AE_OK;
762         }
763
764         return AE_OK;
765 }
766
767 static int san_consumer_links_setup(struct platform_device *pdev)
768 {
769         acpi_status status;
770
771         status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
772                                      ACPI_UINT32_MAX, san_consumer_setup, NULL,
773                                      pdev, NULL);
774
775         return status ? -EFAULT : 0;
776 }
777
778 static int san_probe(struct platform_device *pdev)
779 {
780         struct acpi_device *san = ACPI_COMPANION(&pdev->dev);
781         struct ssam_controller *ctrl;
782         struct san_data *data;
783         acpi_status astatus;
784         int status;
785
786         ctrl = ssam_client_bind(&pdev->dev);
787         if (IS_ERR(ctrl))
788                 return PTR_ERR(ctrl) == -ENODEV ? -EPROBE_DEFER : PTR_ERR(ctrl);
789
790         status = san_consumer_links_setup(pdev);
791         if (status)
792                 return status;
793
794         data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
795         if (!data)
796                 return -ENOMEM;
797
798         data->dev = &pdev->dev;
799         data->ctrl = ctrl;
800
801         platform_set_drvdata(pdev, data);
802
803         astatus = acpi_install_address_space_handler(san->handle,
804                                                      ACPI_ADR_SPACE_GSBUS,
805                                                      &san_opreg_handler, NULL,
806                                                      &data->info);
807         if (ACPI_FAILURE(astatus))
808                 return -ENXIO;
809
810         status = san_events_register(pdev);
811         if (status)
812                 goto err_enable_events;
813
814         status = san_set_rqsg_interface_device(&pdev->dev);
815         if (status)
816                 goto err_install_dev;
817
818         acpi_dev_clear_dependencies(san);
819         return 0;
820
821 err_install_dev:
822         san_events_unregister(pdev);
823 err_enable_events:
824         acpi_remove_address_space_handler(san, ACPI_ADR_SPACE_GSBUS,
825                                           &san_opreg_handler);
826         return status;
827 }
828
829 static void san_remove(struct platform_device *pdev)
830 {
831         acpi_handle san = ACPI_HANDLE(&pdev->dev);
832
833         san_set_rqsg_interface_device(NULL);
834         acpi_remove_address_space_handler(san, ACPI_ADR_SPACE_GSBUS,
835                                           &san_opreg_handler);
836         san_events_unregister(pdev);
837
838         /*
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.
841          */
842         flush_workqueue(san_wq);
843 }
844
845 static const struct acpi_device_id san_match[] = {
846         { "MSHW0091" },
847         { },
848 };
849 MODULE_DEVICE_TABLE(acpi, san_match);
850
851 static struct platform_driver surface_acpi_notify = {
852         .probe = san_probe,
853         .remove = san_remove,
854         .driver = {
855                 .name = "surface_acpi_notify",
856                 .acpi_match_table = san_match,
857                 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
858         },
859 };
860
861 static int __init san_init(void)
862 {
863         int ret;
864
865         san_wq = alloc_workqueue("san_wq", 0, 0);
866         if (!san_wq)
867                 return -ENOMEM;
868         ret = platform_driver_register(&surface_acpi_notify);
869         if (ret)
870                 destroy_workqueue(san_wq);
871         return ret;
872 }
873 module_init(san_init);
874
875 static void __exit san_exit(void)
876 {
877         platform_driver_unregister(&surface_acpi_notify);
878         destroy_workqueue(san_wq);
879 }
880 module_exit(san_exit);
881
882 MODULE_AUTHOR("Maximilian Luz <[email protected]>");
883 MODULE_DESCRIPTION("Surface ACPI Notify driver for Surface System Aggregator Module");
884 MODULE_LICENSE("GPL");
This page took 0.081582 seconds and 4 git commands to generate.