Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Driver for the Surface ACPI Notify (SAN) interface/shim.
0004  *
0005  * Translates communication from ACPI to Surface System Aggregator Module
0006  * (SSAM/SAM) requests and back, specifically SAM-over-SSH. Translates SSAM
0007  * events back to ACPI notifications. Allows handling of discrete GPU
0008  * notifications sent from ACPI via the SAN interface by providing them to any
0009  * registered external driver.
0010  *
0011  * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com>
0012  */
0013 
0014 #include <asm/unaligned.h>
0015 #include <linux/acpi.h>
0016 #include <linux/delay.h>
0017 #include <linux/jiffies.h>
0018 #include <linux/kernel.h>
0019 #include <linux/module.h>
0020 #include <linux/notifier.h>
0021 #include <linux/platform_device.h>
0022 #include <linux/rwsem.h>
0023 
0024 #include <linux/surface_aggregator/controller.h>
0025 #include <linux/surface_acpi_notify.h>
0026 
0027 struct san_data {
0028     struct device *dev;
0029     struct ssam_controller *ctrl;
0030 
0031     struct acpi_connection_info info;
0032 
0033     struct ssam_event_notifier nf_bat;
0034     struct ssam_event_notifier nf_tmp;
0035 };
0036 
0037 #define to_san_data(ptr, member) \
0038     container_of(ptr, struct san_data, member)
0039 
0040 static struct workqueue_struct *san_wq;
0041 
0042 /* -- dGPU notifier interface. ---------------------------------------------- */
0043 
0044 struct san_rqsg_if {
0045     struct rw_semaphore lock;
0046     struct device *dev;
0047     struct blocking_notifier_head nh;
0048 };
0049 
0050 static struct san_rqsg_if san_rqsg_if = {
0051     .lock = __RWSEM_INITIALIZER(san_rqsg_if.lock),
0052     .dev = NULL,
0053     .nh = BLOCKING_NOTIFIER_INIT(san_rqsg_if.nh),
0054 };
0055 
0056 static int san_set_rqsg_interface_device(struct device *dev)
0057 {
0058     int status = 0;
0059 
0060     down_write(&san_rqsg_if.lock);
0061     if (!san_rqsg_if.dev && dev)
0062         san_rqsg_if.dev = dev;
0063     else
0064         status = -EBUSY;
0065     up_write(&san_rqsg_if.lock);
0066 
0067     return status;
0068 }
0069 
0070 /**
0071  * san_client_link() - Link client as consumer to SAN device.
0072  * @client: The client to link.
0073  *
0074  * Sets up a device link between the provided client device as consumer and
0075  * the SAN device as provider. This function can be used to ensure that the
0076  * SAN interface has been set up and will be set up for as long as the driver
0077  * of the client device is bound. This guarantees that, during that time, all
0078  * dGPU events will be received by any registered notifier.
0079  *
0080  * The link will be automatically removed once the client device's driver is
0081  * unbound.
0082  *
0083  * Return: Returns zero on success, %-ENXIO if the SAN interface has not been
0084  * set up yet, and %-ENOMEM if device link creation failed.
0085  */
0086 int san_client_link(struct device *client)
0087 {
0088     const u32 flags = DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_CONSUMER;
0089     struct device_link *link;
0090 
0091     down_read(&san_rqsg_if.lock);
0092 
0093     if (!san_rqsg_if.dev) {
0094         up_read(&san_rqsg_if.lock);
0095         return -ENXIO;
0096     }
0097 
0098     link = device_link_add(client, san_rqsg_if.dev, flags);
0099     if (!link) {
0100         up_read(&san_rqsg_if.lock);
0101         return -ENOMEM;
0102     }
0103 
0104     if (READ_ONCE(link->status) == DL_STATE_SUPPLIER_UNBIND) {
0105         up_read(&san_rqsg_if.lock);
0106         return -ENXIO;
0107     }
0108 
0109     up_read(&san_rqsg_if.lock);
0110     return 0;
0111 }
0112 EXPORT_SYMBOL_GPL(san_client_link);
0113 
0114 /**
0115  * san_dgpu_notifier_register() - Register a SAN dGPU notifier.
0116  * @nb: The notifier-block to register.
0117  *
0118  * Registers a SAN dGPU notifier, receiving any new SAN dGPU events sent from
0119  * ACPI. The registered notifier will be called with &struct san_dgpu_event
0120  * as notifier data and the command ID of that event as notifier action.
0121  */
0122 int san_dgpu_notifier_register(struct notifier_block *nb)
0123 {
0124     return blocking_notifier_chain_register(&san_rqsg_if.nh, nb);
0125 }
0126 EXPORT_SYMBOL_GPL(san_dgpu_notifier_register);
0127 
0128 /**
0129  * san_dgpu_notifier_unregister() - Unregister a SAN dGPU notifier.
0130  * @nb: The notifier-block to unregister.
0131  */
0132 int san_dgpu_notifier_unregister(struct notifier_block *nb)
0133 {
0134     return blocking_notifier_chain_unregister(&san_rqsg_if.nh, nb);
0135 }
0136 EXPORT_SYMBOL_GPL(san_dgpu_notifier_unregister);
0137 
0138 static int san_dgpu_notifier_call(struct san_dgpu_event *evt)
0139 {
0140     int ret;
0141 
0142     ret = blocking_notifier_call_chain(&san_rqsg_if.nh, evt->command, evt);
0143     return notifier_to_errno(ret);
0144 }
0145 
0146 
0147 /* -- ACPI _DSM event relay. ------------------------------------------------ */
0148 
0149 #define SAN_DSM_REVISION    0
0150 
0151 /* 93b666c5-70c6-469f-a215-3d487c91ab3c */
0152 static const guid_t SAN_DSM_UUID =
0153     GUID_INIT(0x93b666c5, 0x70c6, 0x469f, 0xa2, 0x15, 0x3d,
0154           0x48, 0x7c, 0x91, 0xab, 0x3c);
0155 
0156 enum san_dsm_event_fn {
0157     SAN_DSM_EVENT_FN_BAT1_STAT = 0x03,
0158     SAN_DSM_EVENT_FN_BAT1_INFO = 0x04,
0159     SAN_DSM_EVENT_FN_ADP1_STAT = 0x05,
0160     SAN_DSM_EVENT_FN_ADP1_INFO = 0x06,
0161     SAN_DSM_EVENT_FN_BAT2_STAT = 0x07,
0162     SAN_DSM_EVENT_FN_BAT2_INFO = 0x08,
0163     SAN_DSM_EVENT_FN_THERMAL   = 0x09,
0164     SAN_DSM_EVENT_FN_DPTF      = 0x0a,
0165 };
0166 
0167 enum sam_event_cid_bat {
0168     SAM_EVENT_CID_BAT_BIX  = 0x15,
0169     SAM_EVENT_CID_BAT_BST  = 0x16,
0170     SAM_EVENT_CID_BAT_ADP  = 0x17,
0171     SAM_EVENT_CID_BAT_PROT = 0x18,
0172     SAM_EVENT_CID_BAT_DPTF = 0x4f,
0173 };
0174 
0175 enum sam_event_cid_tmp {
0176     SAM_EVENT_CID_TMP_TRIP = 0x0b,
0177 };
0178 
0179 struct san_event_work {
0180     struct delayed_work work;
0181     struct device *dev;
0182     struct ssam_event event;    /* must be last */
0183 };
0184 
0185 static int san_acpi_notify_event(struct device *dev, u64 func,
0186                  union acpi_object *param)
0187 {
0188     acpi_handle san = ACPI_HANDLE(dev);
0189     union acpi_object *obj;
0190     int status = 0;
0191 
0192     if (!acpi_check_dsm(san, &SAN_DSM_UUID, SAN_DSM_REVISION, BIT_ULL(func)))
0193         return 0;
0194 
0195     dev_dbg(dev, "notify event %#04llx\n", func);
0196 
0197     obj = acpi_evaluate_dsm_typed(san, &SAN_DSM_UUID, SAN_DSM_REVISION,
0198                       func, param, ACPI_TYPE_BUFFER);
0199     if (!obj)
0200         return -EFAULT;
0201 
0202     if (obj->buffer.length != 1 || obj->buffer.pointer[0] != 0) {
0203         dev_err(dev, "got unexpected result from _DSM\n");
0204         status = -EPROTO;
0205     }
0206 
0207     ACPI_FREE(obj);
0208     return status;
0209 }
0210 
0211 static int san_evt_bat_adp(struct device *dev, const struct ssam_event *event)
0212 {
0213     int status;
0214 
0215     status = san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_ADP1_STAT, NULL);
0216     if (status)
0217         return status;
0218 
0219     /*
0220      * Ensure that the battery states get updated correctly. When the
0221      * battery is fully charged and an adapter is plugged in, it sometimes
0222      * is not updated correctly, instead showing it as charging.
0223      * Explicitly trigger battery updates to fix this.
0224      */
0225 
0226     status = san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_BAT1_STAT, NULL);
0227     if (status)
0228         return status;
0229 
0230     return san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_BAT2_STAT, NULL);
0231 }
0232 
0233 static int san_evt_bat_bix(struct device *dev, const struct ssam_event *event)
0234 {
0235     enum san_dsm_event_fn fn;
0236 
0237     if (event->instance_id == 0x02)
0238         fn = SAN_DSM_EVENT_FN_BAT2_INFO;
0239     else
0240         fn = SAN_DSM_EVENT_FN_BAT1_INFO;
0241 
0242     return san_acpi_notify_event(dev, fn, NULL);
0243 }
0244 
0245 static int san_evt_bat_bst(struct device *dev, const struct ssam_event *event)
0246 {
0247     enum san_dsm_event_fn fn;
0248 
0249     if (event->instance_id == 0x02)
0250         fn = SAN_DSM_EVENT_FN_BAT2_STAT;
0251     else
0252         fn = SAN_DSM_EVENT_FN_BAT1_STAT;
0253 
0254     return san_acpi_notify_event(dev, fn, NULL);
0255 }
0256 
0257 static int san_evt_bat_dptf(struct device *dev, const struct ssam_event *event)
0258 {
0259     union acpi_object payload;
0260 
0261     /*
0262      * The Surface ACPI expects a buffer and not a package. It specifically
0263      * checks for ObjectType (Arg3) == 0x03. This will cause a warning in
0264      * acpica/nsarguments.c, but that warning can be safely ignored.
0265      */
0266     payload.type = ACPI_TYPE_BUFFER;
0267     payload.buffer.length = event->length;
0268     payload.buffer.pointer = (u8 *)&event->data[0];
0269 
0270     return san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_DPTF, &payload);
0271 }
0272 
0273 static unsigned long san_evt_bat_delay(u8 cid)
0274 {
0275     switch (cid) {
0276     case SAM_EVENT_CID_BAT_ADP:
0277         /*
0278          * Wait for battery state to update before signaling adapter
0279          * change.
0280          */
0281         return msecs_to_jiffies(5000);
0282 
0283     case SAM_EVENT_CID_BAT_BST:
0284         /* Ensure we do not miss anything important due to caching. */
0285         return msecs_to_jiffies(2000);
0286 
0287     default:
0288         return 0;
0289     }
0290 }
0291 
0292 static bool san_evt_bat(const struct ssam_event *event, struct device *dev)
0293 {
0294     int status;
0295 
0296     switch (event->command_id) {
0297     case SAM_EVENT_CID_BAT_BIX:
0298         status = san_evt_bat_bix(dev, event);
0299         break;
0300 
0301     case SAM_EVENT_CID_BAT_BST:
0302         status = san_evt_bat_bst(dev, event);
0303         break;
0304 
0305     case SAM_EVENT_CID_BAT_ADP:
0306         status = san_evt_bat_adp(dev, event);
0307         break;
0308 
0309     case SAM_EVENT_CID_BAT_PROT:
0310         /*
0311          * TODO: Implement support for battery protection status change
0312          *       event.
0313          */
0314         return true;
0315 
0316     case SAM_EVENT_CID_BAT_DPTF:
0317         status = san_evt_bat_dptf(dev, event);
0318         break;
0319 
0320     default:
0321         return false;
0322     }
0323 
0324     if (status) {
0325         dev_err(dev, "error handling power event (cid = %#04x)\n",
0326             event->command_id);
0327     }
0328 
0329     return true;
0330 }
0331 
0332 static void san_evt_bat_workfn(struct work_struct *work)
0333 {
0334     struct san_event_work *ev;
0335 
0336     ev = container_of(work, struct san_event_work, work.work);
0337     san_evt_bat(&ev->event, ev->dev);
0338     kfree(ev);
0339 }
0340 
0341 static u32 san_evt_bat_nf(struct ssam_event_notifier *nf,
0342               const struct ssam_event *event)
0343 {
0344     struct san_data *d = to_san_data(nf, nf_bat);
0345     struct san_event_work *work;
0346     unsigned long delay = san_evt_bat_delay(event->command_id);
0347 
0348     if (delay == 0)
0349         return san_evt_bat(event, d->dev) ? SSAM_NOTIF_HANDLED : 0;
0350 
0351     work = kzalloc(sizeof(*work) + event->length, GFP_KERNEL);
0352     if (!work)
0353         return ssam_notifier_from_errno(-ENOMEM);
0354 
0355     INIT_DELAYED_WORK(&work->work, san_evt_bat_workfn);
0356     work->dev = d->dev;
0357 
0358     memcpy(&work->event, event, sizeof(struct ssam_event) + event->length);
0359 
0360     queue_delayed_work(san_wq, &work->work, delay);
0361     return SSAM_NOTIF_HANDLED;
0362 }
0363 
0364 static int san_evt_tmp_trip(struct device *dev, const struct ssam_event *event)
0365 {
0366     union acpi_object param;
0367 
0368     /*
0369      * The Surface ACPI expects an integer and not a package. This will
0370      * cause a warning in acpica/nsarguments.c, but that warning can be
0371      * safely ignored.
0372      */
0373     param.type = ACPI_TYPE_INTEGER;
0374     param.integer.value = event->instance_id;
0375 
0376     return san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_THERMAL, &param);
0377 }
0378 
0379 static bool san_evt_tmp(const struct ssam_event *event, struct device *dev)
0380 {
0381     int status;
0382 
0383     switch (event->command_id) {
0384     case SAM_EVENT_CID_TMP_TRIP:
0385         status = san_evt_tmp_trip(dev, event);
0386         break;
0387 
0388     default:
0389         return false;
0390     }
0391 
0392     if (status) {
0393         dev_err(dev, "error handling thermal event (cid = %#04x)\n",
0394             event->command_id);
0395     }
0396 
0397     return true;
0398 }
0399 
0400 static u32 san_evt_tmp_nf(struct ssam_event_notifier *nf,
0401               const struct ssam_event *event)
0402 {
0403     struct san_data *d = to_san_data(nf, nf_tmp);
0404 
0405     return san_evt_tmp(event, d->dev) ? SSAM_NOTIF_HANDLED : 0;
0406 }
0407 
0408 
0409 /* -- ACPI GSB OperationRegion handler -------------------------------------- */
0410 
0411 struct gsb_data_in {
0412     u8 cv;
0413 } __packed;
0414 
0415 struct gsb_data_rqsx {
0416     u8 cv;              /* Command value (san_gsb_request_cv). */
0417     u8 tc;              /* Target category. */
0418     u8 tid;             /* Target ID. */
0419     u8 iid;             /* Instance ID. */
0420     u8 snc;             /* Expect-response-flag. */
0421     u8 cid;             /* Command ID. */
0422     u16 cdl;            /* Payload length. */
0423     u8 pld[];           /* Payload. */
0424 } __packed;
0425 
0426 struct gsb_data_etwl {
0427     u8 cv;              /* Command value (should be 0x02). */
0428     u8 etw3;            /* Unknown. */
0429     u8 etw4;            /* Unknown. */
0430     u8 msg[];           /* Error message (ASCIIZ). */
0431 } __packed;
0432 
0433 struct gsb_data_out {
0434     u8 status;          /* _SSH communication status. */
0435     u8 len;             /* _SSH payload length. */
0436     u8 pld[];           /* _SSH payload. */
0437 } __packed;
0438 
0439 union gsb_buffer_data {
0440     struct gsb_data_in   in;    /* Common input. */
0441     struct gsb_data_rqsx rqsx;  /* RQSX input. */
0442     struct gsb_data_etwl etwl;  /* ETWL input. */
0443     struct gsb_data_out  out;   /* Output. */
0444 };
0445 
0446 struct gsb_buffer {
0447     u8 status;          /* GSB AttribRawProcess status. */
0448     u8 len;             /* GSB AttribRawProcess length. */
0449     union gsb_buffer_data data;
0450 } __packed;
0451 
0452 #define SAN_GSB_MAX_RQSX_PAYLOAD  (U8_MAX - 2 - sizeof(struct gsb_data_rqsx))
0453 #define SAN_GSB_MAX_RESPONSE      (U8_MAX - 2 - sizeof(struct gsb_data_out))
0454 
0455 #define SAN_GSB_COMMAND     0
0456 
0457 enum san_gsb_request_cv {
0458     SAN_GSB_REQUEST_CV_RQST = 0x01,
0459     SAN_GSB_REQUEST_CV_ETWL = 0x02,
0460     SAN_GSB_REQUEST_CV_RQSG = 0x03,
0461 };
0462 
0463 #define SAN_REQUEST_NUM_TRIES   5
0464 
0465 static acpi_status san_etwl(struct san_data *d, struct gsb_buffer *b)
0466 {
0467     struct gsb_data_etwl *etwl = &b->data.etwl;
0468 
0469     if (b->len < sizeof(struct gsb_data_etwl)) {
0470         dev_err(d->dev, "invalid ETWL package (len = %d)\n", b->len);
0471         return AE_OK;
0472     }
0473 
0474     dev_err(d->dev, "ETWL(%#04x, %#04x): %.*s\n", etwl->etw3, etwl->etw4,
0475         (unsigned int)(b->len - sizeof(struct gsb_data_etwl)),
0476         (char *)etwl->msg);
0477 
0478     /* Indicate success. */
0479     b->status = 0x00;
0480     b->len = 0x00;
0481 
0482     return AE_OK;
0483 }
0484 
0485 static
0486 struct gsb_data_rqsx *san_validate_rqsx(struct device *dev, const char *type,
0487                     struct gsb_buffer *b)
0488 {
0489     struct gsb_data_rqsx *rqsx = &b->data.rqsx;
0490 
0491     if (b->len < sizeof(struct gsb_data_rqsx)) {
0492         dev_err(dev, "invalid %s package (len = %d)\n", type, b->len);
0493         return NULL;
0494     }
0495 
0496     if (get_unaligned(&rqsx->cdl) != b->len - sizeof(struct gsb_data_rqsx)) {
0497         dev_err(dev, "bogus %s package (len = %d, cdl = %d)\n",
0498             type, b->len, get_unaligned(&rqsx->cdl));
0499         return NULL;
0500     }
0501 
0502     if (get_unaligned(&rqsx->cdl) > SAN_GSB_MAX_RQSX_PAYLOAD) {
0503         dev_err(dev, "payload for %s package too large (cdl = %d)\n",
0504             type, get_unaligned(&rqsx->cdl));
0505         return NULL;
0506     }
0507 
0508     return rqsx;
0509 }
0510 
0511 static void gsb_rqsx_response_error(struct gsb_buffer *gsb, int status)
0512 {
0513     gsb->status = 0x00;
0514     gsb->len = 0x02;
0515     gsb->data.out.status = (u8)(-status);
0516     gsb->data.out.len = 0x00;
0517 }
0518 
0519 static void gsb_rqsx_response_success(struct gsb_buffer *gsb, u8 *ptr, size_t len)
0520 {
0521     gsb->status = 0x00;
0522     gsb->len = len + 2;
0523     gsb->data.out.status = 0x00;
0524     gsb->data.out.len = len;
0525 
0526     if (len)
0527         memcpy(&gsb->data.out.pld[0], ptr, len);
0528 }
0529 
0530 static acpi_status san_rqst_fixup_suspended(struct san_data *d,
0531                         struct ssam_request *rqst,
0532                         struct gsb_buffer *gsb)
0533 {
0534     if (rqst->target_category == SSAM_SSH_TC_BAS && rqst->command_id == 0x0D) {
0535         u8 base_state = 1;
0536 
0537         /* Base state quirk:
0538          * The base state may be queried from ACPI when the EC is still
0539          * suspended. In this case it will return '-EPERM'. This query
0540          * will only be triggered from the ACPI lid GPE interrupt, thus
0541          * we are either in laptop or studio mode (base status 0x01 or
0542          * 0x02). Furthermore, we will only get here if the device (and
0543          * EC) have been suspended.
0544          *
0545          * We now assume that the device is in laptop mode (0x01). This
0546          * has the drawback that it will wake the device when unfolding
0547          * it in studio mode, but it also allows us to avoid actively
0548          * waiting for the EC to wake up, which may incur a notable
0549          * delay.
0550          */
0551 
0552         dev_dbg(d->dev, "rqst: fixup: base-state quirk\n");
0553 
0554         gsb_rqsx_response_success(gsb, &base_state, sizeof(base_state));
0555         return AE_OK;
0556     }
0557 
0558     gsb_rqsx_response_error(gsb, -ENXIO);
0559     return AE_OK;
0560 }
0561 
0562 static acpi_status san_rqst(struct san_data *d, struct gsb_buffer *buffer)
0563 {
0564     u8 rspbuf[SAN_GSB_MAX_RESPONSE];
0565     struct gsb_data_rqsx *gsb_rqst;
0566     struct ssam_request rqst;
0567     struct ssam_response rsp;
0568     int status = 0;
0569 
0570     gsb_rqst = san_validate_rqsx(d->dev, "RQST", buffer);
0571     if (!gsb_rqst)
0572         return AE_OK;
0573 
0574     rqst.target_category = gsb_rqst->tc;
0575     rqst.target_id = gsb_rqst->tid;
0576     rqst.command_id = gsb_rqst->cid;
0577     rqst.instance_id = gsb_rqst->iid;
0578     rqst.flags = gsb_rqst->snc ? SSAM_REQUEST_HAS_RESPONSE : 0;
0579     rqst.length = get_unaligned(&gsb_rqst->cdl);
0580     rqst.payload = &gsb_rqst->pld[0];
0581 
0582     rsp.capacity = ARRAY_SIZE(rspbuf);
0583     rsp.length = 0;
0584     rsp.pointer = &rspbuf[0];
0585 
0586     /* Handle suspended device. */
0587     if (d->dev->power.is_suspended) {
0588         dev_warn(d->dev, "rqst: device is suspended, not executing\n");
0589         return san_rqst_fixup_suspended(d, &rqst, buffer);
0590     }
0591 
0592     status = __ssam_retry(ssam_request_sync_onstack, SAN_REQUEST_NUM_TRIES,
0593                   d->ctrl, &rqst, &rsp, SAN_GSB_MAX_RQSX_PAYLOAD);
0594 
0595     if (!status) {
0596         gsb_rqsx_response_success(buffer, rsp.pointer, rsp.length);
0597     } else {
0598         dev_err(d->dev, "rqst: failed with error %d\n", status);
0599         gsb_rqsx_response_error(buffer, status);
0600     }
0601 
0602     return AE_OK;
0603 }
0604 
0605 static acpi_status san_rqsg(struct san_data *d, struct gsb_buffer *buffer)
0606 {
0607     struct gsb_data_rqsx *gsb_rqsg;
0608     struct san_dgpu_event evt;
0609     int status;
0610 
0611     gsb_rqsg = san_validate_rqsx(d->dev, "RQSG", buffer);
0612     if (!gsb_rqsg)
0613         return AE_OK;
0614 
0615     evt.category = gsb_rqsg->tc;
0616     evt.target = gsb_rqsg->tid;
0617     evt.command = gsb_rqsg->cid;
0618     evt.instance = gsb_rqsg->iid;
0619     evt.length = get_unaligned(&gsb_rqsg->cdl);
0620     evt.payload = &gsb_rqsg->pld[0];
0621 
0622     status = san_dgpu_notifier_call(&evt);
0623     if (!status) {
0624         gsb_rqsx_response_success(buffer, NULL, 0);
0625     } else {
0626         dev_err(d->dev, "rqsg: failed with error %d\n", status);
0627         gsb_rqsx_response_error(buffer, status);
0628     }
0629 
0630     return AE_OK;
0631 }
0632 
0633 static acpi_status san_opreg_handler(u32 function, acpi_physical_address command,
0634                      u32 bits, u64 *value64, void *opreg_context,
0635                      void *region_context)
0636 {
0637     struct san_data *d = to_san_data(opreg_context, info);
0638     struct gsb_buffer *buffer = (struct gsb_buffer *)value64;
0639     int accessor_type = (function & 0xFFFF0000) >> 16;
0640 
0641     if (command != SAN_GSB_COMMAND) {
0642         dev_warn(d->dev, "unsupported command: %#04llx\n", command);
0643         return AE_OK;
0644     }
0645 
0646     if (accessor_type != ACPI_GSB_ACCESS_ATTRIB_RAW_PROCESS) {
0647         dev_err(d->dev, "invalid access type: %#04x\n", accessor_type);
0648         return AE_OK;
0649     }
0650 
0651     /* Buffer must have at least contain the command-value. */
0652     if (buffer->len == 0) {
0653         dev_err(d->dev, "request-package too small\n");
0654         return AE_OK;
0655     }
0656 
0657     switch (buffer->data.in.cv) {
0658     case SAN_GSB_REQUEST_CV_RQST:
0659         return san_rqst(d, buffer);
0660 
0661     case SAN_GSB_REQUEST_CV_ETWL:
0662         return san_etwl(d, buffer);
0663 
0664     case SAN_GSB_REQUEST_CV_RQSG:
0665         return san_rqsg(d, buffer);
0666 
0667     default:
0668         dev_warn(d->dev, "unsupported SAN0 request (cv: %#04x)\n",
0669              buffer->data.in.cv);
0670         return AE_OK;
0671     }
0672 }
0673 
0674 
0675 /* -- Driver setup. --------------------------------------------------------- */
0676 
0677 static int san_events_register(struct platform_device *pdev)
0678 {
0679     struct san_data *d = platform_get_drvdata(pdev);
0680     int status;
0681 
0682     d->nf_bat.base.priority = 1;
0683     d->nf_bat.base.fn = san_evt_bat_nf;
0684     d->nf_bat.event.reg = SSAM_EVENT_REGISTRY_SAM;
0685     d->nf_bat.event.id.target_category = SSAM_SSH_TC_BAT;
0686     d->nf_bat.event.id.instance = 0;
0687     d->nf_bat.event.mask = SSAM_EVENT_MASK_TARGET;
0688     d->nf_bat.event.flags = SSAM_EVENT_SEQUENCED;
0689 
0690     d->nf_tmp.base.priority = 1;
0691     d->nf_tmp.base.fn = san_evt_tmp_nf;
0692     d->nf_tmp.event.reg = SSAM_EVENT_REGISTRY_SAM;
0693     d->nf_tmp.event.id.target_category = SSAM_SSH_TC_TMP;
0694     d->nf_tmp.event.id.instance = 0;
0695     d->nf_tmp.event.mask = SSAM_EVENT_MASK_TARGET;
0696     d->nf_tmp.event.flags = SSAM_EVENT_SEQUENCED;
0697 
0698     status = ssam_notifier_register(d->ctrl, &d->nf_bat);
0699     if (status)
0700         return status;
0701 
0702     status = ssam_notifier_register(d->ctrl, &d->nf_tmp);
0703     if (status)
0704         ssam_notifier_unregister(d->ctrl, &d->nf_bat);
0705 
0706     return status;
0707 }
0708 
0709 static void san_events_unregister(struct platform_device *pdev)
0710 {
0711     struct san_data *d = platform_get_drvdata(pdev);
0712 
0713     ssam_notifier_unregister(d->ctrl, &d->nf_bat);
0714     ssam_notifier_unregister(d->ctrl, &d->nf_tmp);
0715 }
0716 
0717 #define san_consumer_printk(level, dev, handle, fmt, ...)           \
0718 do {                                        \
0719     char *path = "<error getting consumer path>";               \
0720     struct acpi_buffer buffer = {                       \
0721         .length = ACPI_ALLOCATE_BUFFER,                 \
0722         .pointer = NULL,                        \
0723     };                                  \
0724                                         \
0725     if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer)))   \
0726         path = buffer.pointer;                      \
0727                                         \
0728     dev_##level(dev, "[%s]: " fmt, path, ##__VA_ARGS__);            \
0729     kfree(buffer.pointer);                          \
0730 } while (0)
0731 
0732 #define san_consumer_dbg(dev, handle, fmt, ...) \
0733     san_consumer_printk(dbg, dev, handle, fmt, ##__VA_ARGS__)
0734 
0735 #define san_consumer_warn(dev, handle, fmt, ...) \
0736     san_consumer_printk(warn, dev, handle, fmt, ##__VA_ARGS__)
0737 
0738 static bool is_san_consumer(struct platform_device *pdev, acpi_handle handle)
0739 {
0740     struct acpi_handle_list dep_devices;
0741     acpi_handle supplier = ACPI_HANDLE(&pdev->dev);
0742     acpi_status status;
0743     int i;
0744 
0745     if (!acpi_has_method(handle, "_DEP"))
0746         return false;
0747 
0748     status = acpi_evaluate_reference(handle, "_DEP", NULL, &dep_devices);
0749     if (ACPI_FAILURE(status)) {
0750         san_consumer_dbg(&pdev->dev, handle, "failed to evaluate _DEP\n");
0751         return false;
0752     }
0753 
0754     for (i = 0; i < dep_devices.count; i++) {
0755         if (dep_devices.handles[i] == supplier)
0756             return true;
0757     }
0758 
0759     return false;
0760 }
0761 
0762 static acpi_status san_consumer_setup(acpi_handle handle, u32 lvl,
0763                       void *context, void **rv)
0764 {
0765     const u32 flags = DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER;
0766     struct platform_device *pdev = context;
0767     struct acpi_device *adev;
0768     struct device_link *link;
0769 
0770     if (!is_san_consumer(pdev, handle))
0771         return AE_OK;
0772 
0773     /* Ignore ACPI devices that are not present. */
0774     adev = acpi_fetch_acpi_dev(handle);
0775     if (!adev)
0776         return AE_OK;
0777 
0778     san_consumer_dbg(&pdev->dev, handle, "creating device link\n");
0779 
0780     /* Try to set up device links, ignore but log errors. */
0781     link = device_link_add(&adev->dev, &pdev->dev, flags);
0782     if (!link) {
0783         san_consumer_warn(&pdev->dev, handle, "failed to create device link\n");
0784         return AE_OK;
0785     }
0786 
0787     return AE_OK;
0788 }
0789 
0790 static int san_consumer_links_setup(struct platform_device *pdev)
0791 {
0792     acpi_status status;
0793 
0794     status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
0795                      ACPI_UINT32_MAX, san_consumer_setup, NULL,
0796                      pdev, NULL);
0797 
0798     return status ? -EFAULT : 0;
0799 }
0800 
0801 static int san_probe(struct platform_device *pdev)
0802 {
0803     struct acpi_device *san = ACPI_COMPANION(&pdev->dev);
0804     struct ssam_controller *ctrl;
0805     struct san_data *data;
0806     acpi_status astatus;
0807     int status;
0808 
0809     ctrl = ssam_client_bind(&pdev->dev);
0810     if (IS_ERR(ctrl))
0811         return PTR_ERR(ctrl) == -ENODEV ? -EPROBE_DEFER : PTR_ERR(ctrl);
0812 
0813     status = san_consumer_links_setup(pdev);
0814     if (status)
0815         return status;
0816 
0817     data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
0818     if (!data)
0819         return -ENOMEM;
0820 
0821     data->dev = &pdev->dev;
0822     data->ctrl = ctrl;
0823 
0824     platform_set_drvdata(pdev, data);
0825 
0826     astatus = acpi_install_address_space_handler(san->handle,
0827                              ACPI_ADR_SPACE_GSBUS,
0828                              &san_opreg_handler, NULL,
0829                              &data->info);
0830     if (ACPI_FAILURE(astatus))
0831         return -ENXIO;
0832 
0833     status = san_events_register(pdev);
0834     if (status)
0835         goto err_enable_events;
0836 
0837     status = san_set_rqsg_interface_device(&pdev->dev);
0838     if (status)
0839         goto err_install_dev;
0840 
0841     acpi_dev_clear_dependencies(san);
0842     return 0;
0843 
0844 err_install_dev:
0845     san_events_unregister(pdev);
0846 err_enable_events:
0847     acpi_remove_address_space_handler(san, ACPI_ADR_SPACE_GSBUS,
0848                       &san_opreg_handler);
0849     return status;
0850 }
0851 
0852 static int san_remove(struct platform_device *pdev)
0853 {
0854     acpi_handle san = ACPI_HANDLE(&pdev->dev);
0855 
0856     san_set_rqsg_interface_device(NULL);
0857     acpi_remove_address_space_handler(san, ACPI_ADR_SPACE_GSBUS,
0858                       &san_opreg_handler);
0859     san_events_unregister(pdev);
0860 
0861     /*
0862      * We have unregistered our event sources. Now we need to ensure that
0863      * all delayed works they may have spawned are run to completion.
0864      */
0865     flush_workqueue(san_wq);
0866 
0867     return 0;
0868 }
0869 
0870 static const struct acpi_device_id san_match[] = {
0871     { "MSHW0091" },
0872     { },
0873 };
0874 MODULE_DEVICE_TABLE(acpi, san_match);
0875 
0876 static struct platform_driver surface_acpi_notify = {
0877     .probe = san_probe,
0878     .remove = san_remove,
0879     .driver = {
0880         .name = "surface_acpi_notify",
0881         .acpi_match_table = san_match,
0882         .probe_type = PROBE_PREFER_ASYNCHRONOUS,
0883     },
0884 };
0885 
0886 static int __init san_init(void)
0887 {
0888     int ret;
0889 
0890     san_wq = alloc_workqueue("san_wq", 0, 0);
0891     if (!san_wq)
0892         return -ENOMEM;
0893     ret = platform_driver_register(&surface_acpi_notify);
0894     if (ret)
0895         destroy_workqueue(san_wq);
0896     return ret;
0897 }
0898 module_init(san_init);
0899 
0900 static void __exit san_exit(void)
0901 {
0902     platform_driver_unregister(&surface_acpi_notify);
0903     destroy_workqueue(san_wq);
0904 }
0905 module_exit(san_exit);
0906 
0907 MODULE_AUTHOR("Maximilian Luz <luzmaximilian@gmail.com>");
0908 MODULE_DESCRIPTION("Surface ACPI Notify driver for Surface System Aggregator Module");
0909 MODULE_LICENSE("GPL");