Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // ISHTP interface for ChromeOS Embedded Controller
0003 //
0004 // Copyright (c) 2019, Intel Corporation.
0005 //
0006 // ISHTP client driver for talking to the Chrome OS EC firmware running
0007 // on Intel Integrated Sensor Hub (ISH) using the ISH Transport protocol
0008 // (ISH-TP).
0009 
0010 #include <linux/delay.h>
0011 #include <linux/module.h>
0012 #include <linux/pci.h>
0013 #include <linux/platform_data/cros_ec_commands.h>
0014 #include <linux/platform_data/cros_ec_proto.h>
0015 #include <linux/intel-ish-client-if.h>
0016 
0017 #include "cros_ec.h"
0018 
0019 /*
0020  * ISH TX/RX ring buffer pool size
0021  *
0022  * The AP->ISH messages and corresponding ISH->AP responses are
0023  * serialized. We need 1 TX and 1 RX buffer for these.
0024  *
0025  * The MKBP ISH->AP events are serialized. We need one additional RX
0026  * buffer for them.
0027  */
0028 #define CROS_ISH_CL_TX_RING_SIZE        8
0029 #define CROS_ISH_CL_RX_RING_SIZE        8
0030 
0031 /* ISH CrOS EC Host Commands */
0032 enum cros_ec_ish_channel {
0033     CROS_EC_COMMAND = 1,            /* AP->ISH message */
0034     CROS_MKBP_EVENT = 2,            /* ISH->AP events */
0035 };
0036 
0037 /*
0038  * ISH firmware timeout for 1 message send failure is 1Hz, and the
0039  * firmware will retry 2 times, so 3Hz is used for timeout.
0040  */
0041 #define ISHTP_SEND_TIMEOUT          (3 * HZ)
0042 
0043 /* ISH Transport CrOS EC ISH client unique GUID */
0044 static const struct ishtp_device_id cros_ec_ishtp_id_table[] = {
0045     { .guid = GUID_INIT(0x7b7154d0, 0x56f4, 0x4bdc,
0046           0xb0, 0xd8, 0x9e, 0x7c, 0xda, 0xe0, 0xd6, 0xa0), },
0047     { }
0048 };
0049 MODULE_DEVICE_TABLE(ishtp, cros_ec_ishtp_id_table);
0050 
0051 struct header {
0052     u8 channel;
0053     u8 status;
0054     u8 token;
0055     u8 reserved;
0056 } __packed;
0057 
0058 struct cros_ish_out_msg {
0059     struct header hdr;
0060     struct ec_host_request ec_request;
0061 } __packed;
0062 
0063 struct cros_ish_in_msg {
0064     struct header hdr;
0065     struct ec_host_response ec_response;
0066 } __packed;
0067 
0068 #define IN_MSG_EC_RESPONSE_PREAMBLE                 \
0069     offsetof(struct cros_ish_in_msg, ec_response)
0070 
0071 #define OUT_MSG_EC_REQUEST_PREAMBLE                 \
0072     offsetof(struct cros_ish_out_msg, ec_request)
0073 
0074 #define cl_data_to_dev(client_data) ishtp_device((client_data)->cl_device)
0075 
0076 /*
0077  * The Read-Write Semaphore is used to prevent message TX or RX while
0078  * the ishtp client is being initialized or undergoing reset.
0079  *
0080  * The readers are the kernel function calls responsible for IA->ISH
0081  * and ISH->AP messaging.
0082  *
0083  * The writers are .reset() and .probe() function.
0084  */
0085 static DECLARE_RWSEM(init_lock);
0086 
0087 /**
0088  * struct response_info - Encapsulate firmware response related
0089  * information for passing between function ish_send() and
0090  * process_recv() callback.
0091  *
0092  * @data: Copy the data received from firmware here.
0093  * @max_size: Max size allocated for the @data buffer. If the received
0094  * data exceeds this value, we log an error.
0095  * @size: Actual size of data received from firmware.
0096  * @error: 0 for success, negative error code for a failure in process_recv().
0097  * @token: Expected token for response that we are waiting on.
0098  * @received: Set to true on receiving a valid firmware response to host command
0099  * @wait_queue: Wait queue for host to wait for firmware response.
0100  */
0101 struct response_info {
0102     void *data;
0103     size_t max_size;
0104     size_t size;
0105     int error;
0106     u8 token;
0107     bool received;
0108     wait_queue_head_t wait_queue;
0109 };
0110 
0111 /**
0112  * struct ishtp_cl_data - Encapsulate per ISH TP Client.
0113  *
0114  * @cros_ish_cl: ISHTP firmware client instance.
0115  * @cl_device: ISHTP client device instance.
0116  * @response: Response info passing between ish_send() and process_recv().
0117  * @work_ishtp_reset: Work queue reset handling.
0118  * @work_ec_evt: Work queue for EC events.
0119  * @ec_dev: CrOS EC MFD device.
0120  *
0121  * This structure is used to store per client data.
0122  */
0123 struct ishtp_cl_data {
0124     struct ishtp_cl *cros_ish_cl;
0125     struct ishtp_cl_device *cl_device;
0126 
0127     /*
0128      * Used for passing firmware response information between
0129      * ish_send() and process_recv() callback.
0130      */
0131     struct response_info response;
0132 
0133     struct work_struct work_ishtp_reset;
0134     struct work_struct work_ec_evt;
0135     struct cros_ec_device *ec_dev;
0136 };
0137 
0138 /**
0139  * ish_evt_handler - ISH to AP event handler
0140  * @work: Work struct
0141  */
0142 static void ish_evt_handler(struct work_struct *work)
0143 {
0144     struct ishtp_cl_data *client_data =
0145         container_of(work, struct ishtp_cl_data, work_ec_evt);
0146 
0147     cros_ec_irq_thread(0, client_data->ec_dev);
0148 }
0149 
0150 /**
0151  * ish_send() - Send message from host to firmware
0152  *
0153  * @client_data: Client data instance
0154  * @out_msg: Message buffer to be sent to firmware
0155  * @out_size: Size of out going message
0156  * @in_msg: Message buffer where the incoming data is copied. This buffer
0157  * is allocated by calling
0158  * @in_size: Max size of incoming message
0159  *
0160  * Return: Number of bytes copied in the in_msg on success, negative
0161  * error code on failure.
0162  */
0163 static int ish_send(struct ishtp_cl_data *client_data,
0164             u8 *out_msg, size_t out_size,
0165             u8 *in_msg, size_t in_size)
0166 {
0167     static u8 next_token;
0168     int rv;
0169     struct header *out_hdr = (struct header *)out_msg;
0170     struct ishtp_cl *cros_ish_cl = client_data->cros_ish_cl;
0171 
0172     dev_dbg(cl_data_to_dev(client_data),
0173         "%s: channel=%02u status=%02u\n",
0174         __func__, out_hdr->channel, out_hdr->status);
0175 
0176     /* Setup for incoming response */
0177     client_data->response.data = in_msg;
0178     client_data->response.max_size = in_size;
0179     client_data->response.error = 0;
0180     client_data->response.token = next_token++;
0181     client_data->response.received = false;
0182 
0183     out_hdr->token = client_data->response.token;
0184 
0185     rv = ishtp_cl_send(cros_ish_cl, out_msg, out_size);
0186     if (rv) {
0187         dev_err(cl_data_to_dev(client_data),
0188             "ishtp_cl_send error %d\n", rv);
0189         return rv;
0190     }
0191 
0192     wait_event_interruptible_timeout(client_data->response.wait_queue,
0193                      client_data->response.received,
0194                      ISHTP_SEND_TIMEOUT);
0195     if (!client_data->response.received) {
0196         dev_err(cl_data_to_dev(client_data),
0197             "Timed out for response to host message\n");
0198         return -ETIMEDOUT;
0199     }
0200 
0201     if (client_data->response.error < 0)
0202         return client_data->response.error;
0203 
0204     return client_data->response.size;
0205 }
0206 
0207 /**
0208  * process_recv() - Received and parse incoming packet
0209  * @cros_ish_cl: Client instance to get stats
0210  * @rb_in_proc: Host interface message buffer
0211  * @timestamp: Timestamp of when parent callback started
0212  *
0213  * Parse the incoming packet. If it is a response packet then it will
0214  * update per instance flags and wake up the caller waiting to for the
0215  * response. If it is an event packet then it will schedule event work.
0216  */
0217 static void process_recv(struct ishtp_cl *cros_ish_cl,
0218              struct ishtp_cl_rb *rb_in_proc, ktime_t timestamp)
0219 {
0220     size_t data_len = rb_in_proc->buf_idx;
0221     struct ishtp_cl_data *client_data =
0222         ishtp_get_client_data(cros_ish_cl);
0223     struct device *dev = cl_data_to_dev(client_data);
0224     struct cros_ish_in_msg *in_msg =
0225         (struct cros_ish_in_msg *)rb_in_proc->buffer.data;
0226 
0227     /* Proceed only if reset or init is not in progress */
0228     if (!down_read_trylock(&init_lock)) {
0229         /* Free the buffer */
0230         ishtp_cl_io_rb_recycle(rb_in_proc);
0231         dev_warn(dev,
0232              "Host is not ready to receive incoming messages\n");
0233         return;
0234     }
0235 
0236     /*
0237      * All firmware messages contain a header. Check the buffer size
0238      * before accessing elements inside.
0239      */
0240     if (!rb_in_proc->buffer.data) {
0241         dev_warn(dev, "rb_in_proc->buffer.data returned null");
0242         client_data->response.error = -EBADMSG;
0243         goto end_error;
0244     }
0245 
0246     if (data_len < sizeof(struct header)) {
0247         dev_err(dev, "data size %zu is less than header %zu\n",
0248             data_len, sizeof(struct header));
0249         client_data->response.error = -EMSGSIZE;
0250         goto end_error;
0251     }
0252 
0253     dev_dbg(dev, "channel=%02u status=%02u\n",
0254         in_msg->hdr.channel, in_msg->hdr.status);
0255 
0256     switch (in_msg->hdr.channel) {
0257     case CROS_EC_COMMAND:
0258         if (client_data->response.received) {
0259             dev_err(dev,
0260                 "Previous firmware message not yet processed\n");
0261             goto end_error;
0262         }
0263 
0264         if (client_data->response.token != in_msg->hdr.token) {
0265             dev_err_ratelimited(dev,
0266                         "Dropping old response token %d\n",
0267                         in_msg->hdr.token);
0268             goto end_error;
0269         }
0270 
0271         /* Sanity check */
0272         if (!client_data->response.data) {
0273             dev_err(dev,
0274                 "Receiving buffer is null. Should be allocated by calling function\n");
0275             client_data->response.error = -EINVAL;
0276             goto error_wake_up;
0277         }
0278 
0279         if (data_len > client_data->response.max_size) {
0280             dev_err(dev,
0281                 "Received buffer size %zu is larger than allocated buffer %zu\n",
0282                 data_len, client_data->response.max_size);
0283             client_data->response.error = -EMSGSIZE;
0284             goto error_wake_up;
0285         }
0286 
0287         if (in_msg->hdr.status) {
0288             dev_err(dev, "firmware returned status %d\n",
0289                 in_msg->hdr.status);
0290             client_data->response.error = -EIO;
0291             goto error_wake_up;
0292         }
0293 
0294         /* Update the actual received buffer size */
0295         client_data->response.size = data_len;
0296 
0297         /*
0298          * Copy the buffer received in firmware response for the
0299          * calling thread.
0300          */
0301         memcpy(client_data->response.data,
0302                rb_in_proc->buffer.data, data_len);
0303 
0304 error_wake_up:
0305         /* Free the buffer since we copied data or didn't need it */
0306         ishtp_cl_io_rb_recycle(rb_in_proc);
0307         rb_in_proc = NULL;
0308 
0309         /* Set flag before waking up the caller */
0310         client_data->response.received = true;
0311 
0312         /* Wake the calling thread */
0313         wake_up_interruptible(&client_data->response.wait_queue);
0314 
0315         break;
0316 
0317     case CROS_MKBP_EVENT:
0318         /* Free the buffer. This is just an event without data */
0319         ishtp_cl_io_rb_recycle(rb_in_proc);
0320         rb_in_proc = NULL;
0321         /*
0322          * Set timestamp from beginning of function since we actually
0323          * got an incoming MKBP event
0324          */
0325         client_data->ec_dev->last_event_time = timestamp;
0326         schedule_work(&client_data->work_ec_evt);
0327 
0328         break;
0329 
0330     default:
0331         dev_err(dev, "Invalid channel=%02d\n", in_msg->hdr.channel);
0332     }
0333 
0334 end_error:
0335     /* Free the buffer if we already haven't */
0336     if (rb_in_proc)
0337         ishtp_cl_io_rb_recycle(rb_in_proc);
0338 
0339     up_read(&init_lock);
0340 }
0341 
0342 /**
0343  * ish_event_cb() - bus driver callback for incoming message
0344  * @cl_device: ISHTP client device for which this message is targeted.
0345  *
0346  * Remove the packet from the list and process the message by calling
0347  * process_recv.
0348  */
0349 static void ish_event_cb(struct ishtp_cl_device *cl_device)
0350 {
0351     struct ishtp_cl_rb *rb_in_proc;
0352     struct ishtp_cl *cros_ish_cl = ishtp_get_drvdata(cl_device);
0353     ktime_t timestamp;
0354 
0355     /*
0356      * Take timestamp as close to hardware interrupt as possible for sensor
0357      * timestamps.
0358      */
0359     timestamp = cros_ec_get_time_ns();
0360 
0361     while ((rb_in_proc = ishtp_cl_rx_get_rb(cros_ish_cl)) != NULL) {
0362         /* Decide what to do with received data */
0363         process_recv(cros_ish_cl, rb_in_proc, timestamp);
0364     }
0365 }
0366 
0367 /**
0368  * cros_ish_init() - Init function for ISHTP client
0369  * @cros_ish_cl: ISHTP client instance
0370  *
0371  * This function complete the initializtion of the client.
0372  *
0373  * Return: 0 for success, negative error code for failure.
0374  */
0375 static int cros_ish_init(struct ishtp_cl *cros_ish_cl)
0376 {
0377     int rv;
0378     struct ishtp_device *dev;
0379     struct ishtp_fw_client *fw_client;
0380     struct ishtp_cl_data *client_data = ishtp_get_client_data(cros_ish_cl);
0381 
0382     rv = ishtp_cl_link(cros_ish_cl);
0383     if (rv) {
0384         dev_err(cl_data_to_dev(client_data),
0385             "ishtp_cl_link failed\n");
0386         return rv;
0387     }
0388 
0389     dev = ishtp_get_ishtp_device(cros_ish_cl);
0390 
0391     /* Connect to firmware client */
0392     ishtp_set_tx_ring_size(cros_ish_cl, CROS_ISH_CL_TX_RING_SIZE);
0393     ishtp_set_rx_ring_size(cros_ish_cl, CROS_ISH_CL_RX_RING_SIZE);
0394 
0395     fw_client = ishtp_fw_cl_get_client(dev, &cros_ec_ishtp_id_table[0].guid);
0396     if (!fw_client) {
0397         dev_err(cl_data_to_dev(client_data),
0398             "ish client uuid not found\n");
0399         rv = -ENOENT;
0400         goto err_cl_unlink;
0401     }
0402 
0403     ishtp_cl_set_fw_client_id(cros_ish_cl,
0404                   ishtp_get_fw_client_id(fw_client));
0405     ishtp_set_connection_state(cros_ish_cl, ISHTP_CL_CONNECTING);
0406 
0407     rv = ishtp_cl_connect(cros_ish_cl);
0408     if (rv) {
0409         dev_err(cl_data_to_dev(client_data),
0410             "client connect fail\n");
0411         goto err_cl_unlink;
0412     }
0413 
0414     ishtp_register_event_cb(client_data->cl_device, ish_event_cb);
0415     return 0;
0416 
0417 err_cl_unlink:
0418     ishtp_cl_unlink(cros_ish_cl);
0419     return rv;
0420 }
0421 
0422 /**
0423  * cros_ish_deinit() - Deinit function for ISHTP client
0424  * @cros_ish_cl: ISHTP client instance
0425  *
0426  * Unlink and free cros_ec client
0427  */
0428 static void cros_ish_deinit(struct ishtp_cl *cros_ish_cl)
0429 {
0430     ishtp_set_connection_state(cros_ish_cl, ISHTP_CL_DISCONNECTING);
0431     ishtp_cl_disconnect(cros_ish_cl);
0432     ishtp_cl_unlink(cros_ish_cl);
0433     ishtp_cl_flush_queues(cros_ish_cl);
0434 
0435     /* Disband and free all Tx and Rx client-level rings */
0436     ishtp_cl_free(cros_ish_cl);
0437 }
0438 
0439 /**
0440  * prepare_cros_ec_rx() - Check & prepare receive buffer
0441  * @ec_dev: CrOS EC MFD device.
0442  * @in_msg: Incoming message buffer
0443  * @msg: cros_ec command used to send & receive data
0444  *
0445  * Return: 0 for success, negative error code for failure.
0446  *
0447  * Check the received buffer. Convert to cros_ec_command format.
0448  */
0449 static int prepare_cros_ec_rx(struct cros_ec_device *ec_dev,
0450                   const struct cros_ish_in_msg *in_msg,
0451                   struct cros_ec_command *msg)
0452 {
0453     u8 sum = 0;
0454     int i, rv, offset;
0455 
0456     /* Check response error code */
0457     msg->result = in_msg->ec_response.result;
0458     rv = cros_ec_check_result(ec_dev, msg);
0459     if (rv < 0)
0460         return rv;
0461 
0462     if (in_msg->ec_response.data_len > msg->insize) {
0463         dev_err(ec_dev->dev, "Packet too long (%d bytes, expected %d)",
0464             in_msg->ec_response.data_len, msg->insize);
0465         return -ENOSPC;
0466     }
0467 
0468     /* Copy response packet payload and compute checksum */
0469     for (i = 0; i < sizeof(struct ec_host_response); i++)
0470         sum += ((u8 *)in_msg)[IN_MSG_EC_RESPONSE_PREAMBLE + i];
0471 
0472     offset = sizeof(struct cros_ish_in_msg);
0473     for (i = 0; i < in_msg->ec_response.data_len; i++)
0474         sum += msg->data[i] = ((u8 *)in_msg)[offset + i];
0475 
0476     if (sum) {
0477         dev_dbg(ec_dev->dev, "Bad received packet checksum %d\n", sum);
0478         return -EBADMSG;
0479     }
0480 
0481     return 0;
0482 }
0483 
0484 static int cros_ec_pkt_xfer_ish(struct cros_ec_device *ec_dev,
0485                 struct cros_ec_command *msg)
0486 {
0487     int rv;
0488     struct ishtp_cl *cros_ish_cl = ec_dev->priv;
0489     struct ishtp_cl_data *client_data = ishtp_get_client_data(cros_ish_cl);
0490     struct device *dev = cl_data_to_dev(client_data);
0491     struct cros_ish_in_msg *in_msg = (struct cros_ish_in_msg *)ec_dev->din;
0492     struct cros_ish_out_msg *out_msg =
0493         (struct cros_ish_out_msg *)ec_dev->dout;
0494     size_t in_size = sizeof(struct cros_ish_in_msg) + msg->insize;
0495     size_t out_size = sizeof(struct cros_ish_out_msg) + msg->outsize;
0496 
0497     /* Sanity checks */
0498     if (in_size > ec_dev->din_size) {
0499         dev_err(dev,
0500             "Incoming payload size %zu is too large for ec_dev->din_size %d\n",
0501             in_size, ec_dev->din_size);
0502         return -EMSGSIZE;
0503     }
0504 
0505     if (out_size > ec_dev->dout_size) {
0506         dev_err(dev,
0507             "Outgoing payload size %zu is too large for ec_dev->dout_size %d\n",
0508             out_size, ec_dev->dout_size);
0509         return -EMSGSIZE;
0510     }
0511 
0512     /* Proceed only if reset-init is not in progress */
0513     if (!down_read_trylock(&init_lock)) {
0514         dev_warn(dev,
0515              "Host is not ready to send messages to ISH. Try again\n");
0516         return -EAGAIN;
0517     }
0518 
0519     /* Prepare the package to be sent over ISH TP */
0520     out_msg->hdr.channel = CROS_EC_COMMAND;
0521     out_msg->hdr.status = 0;
0522 
0523     ec_dev->dout += OUT_MSG_EC_REQUEST_PREAMBLE;
0524     rv = cros_ec_prepare_tx(ec_dev, msg);
0525     if (rv < 0)
0526         goto end_error;
0527     ec_dev->dout -= OUT_MSG_EC_REQUEST_PREAMBLE;
0528 
0529     dev_dbg(dev,
0530         "out_msg: struct_ver=0x%x checksum=0x%x command=0x%x command_ver=0x%x data_len=0x%x\n",
0531         out_msg->ec_request.struct_version,
0532         out_msg->ec_request.checksum,
0533         out_msg->ec_request.command,
0534         out_msg->ec_request.command_version,
0535         out_msg->ec_request.data_len);
0536 
0537     /* Send command to ISH EC firmware and read response */
0538     rv = ish_send(client_data,
0539               (u8 *)out_msg, out_size,
0540               (u8 *)in_msg, in_size);
0541     if (rv < 0)
0542         goto end_error;
0543 
0544     rv = prepare_cros_ec_rx(ec_dev, in_msg, msg);
0545     if (rv)
0546         goto end_error;
0547 
0548     rv = in_msg->ec_response.data_len;
0549 
0550     dev_dbg(dev,
0551         "in_msg: struct_ver=0x%x checksum=0x%x result=0x%x data_len=0x%x\n",
0552         in_msg->ec_response.struct_version,
0553         in_msg->ec_response.checksum,
0554         in_msg->ec_response.result,
0555         in_msg->ec_response.data_len);
0556 
0557 end_error:
0558     if (msg->command == EC_CMD_REBOOT_EC)
0559         msleep(EC_REBOOT_DELAY_MS);
0560 
0561     up_read(&init_lock);
0562 
0563     return rv;
0564 }
0565 
0566 static int cros_ec_dev_init(struct ishtp_cl_data *client_data)
0567 {
0568     struct cros_ec_device *ec_dev;
0569     struct device *dev = cl_data_to_dev(client_data);
0570 
0571     ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);
0572     if (!ec_dev)
0573         return -ENOMEM;
0574 
0575     client_data->ec_dev = ec_dev;
0576     dev->driver_data = ec_dev;
0577 
0578     ec_dev->dev = dev;
0579     ec_dev->priv = client_data->cros_ish_cl;
0580     ec_dev->cmd_xfer = NULL;
0581     ec_dev->pkt_xfer = cros_ec_pkt_xfer_ish;
0582     ec_dev->phys_name = dev_name(dev);
0583     ec_dev->din_size = sizeof(struct cros_ish_in_msg) +
0584                sizeof(struct ec_response_get_protocol_info);
0585     ec_dev->dout_size = sizeof(struct cros_ish_out_msg);
0586 
0587     return cros_ec_register(ec_dev);
0588 }
0589 
0590 static void reset_handler(struct work_struct *work)
0591 {
0592     int rv;
0593     struct device *dev;
0594     struct ishtp_cl *cros_ish_cl;
0595     struct ishtp_cl_device *cl_device;
0596     struct ishtp_cl_data *client_data =
0597         container_of(work, struct ishtp_cl_data, work_ishtp_reset);
0598 
0599     /* Lock for reset to complete */
0600     down_write(&init_lock);
0601 
0602     cros_ish_cl = client_data->cros_ish_cl;
0603     cl_device = client_data->cl_device;
0604 
0605     /* Unlink, flush queues & start again */
0606     ishtp_cl_unlink(cros_ish_cl);
0607     ishtp_cl_flush_queues(cros_ish_cl);
0608     ishtp_cl_free(cros_ish_cl);
0609 
0610     cros_ish_cl = ishtp_cl_allocate(cl_device);
0611     if (!cros_ish_cl) {
0612         up_write(&init_lock);
0613         return;
0614     }
0615 
0616     ishtp_set_drvdata(cl_device, cros_ish_cl);
0617     ishtp_set_client_data(cros_ish_cl, client_data);
0618     client_data->cros_ish_cl = cros_ish_cl;
0619 
0620     rv = cros_ish_init(cros_ish_cl);
0621     if (rv) {
0622         ishtp_cl_free(cros_ish_cl);
0623         dev_err(cl_data_to_dev(client_data), "Reset Failed\n");
0624         up_write(&init_lock);
0625         return;
0626     }
0627 
0628     /* Refresh ec_dev device pointers */
0629     client_data->ec_dev->priv = client_data->cros_ish_cl;
0630     dev = cl_data_to_dev(client_data);
0631     dev->driver_data = client_data->ec_dev;
0632 
0633     dev_info(cl_data_to_dev(client_data), "Chrome EC ISH reset done\n");
0634 
0635     up_write(&init_lock);
0636 }
0637 
0638 /**
0639  * cros_ec_ishtp_probe() - ISHTP client driver probe callback
0640  * @cl_device: ISHTP client device instance
0641  *
0642  * Return: 0 for success, negative error code for failure.
0643  */
0644 static int cros_ec_ishtp_probe(struct ishtp_cl_device *cl_device)
0645 {
0646     int rv;
0647     struct ishtp_cl *cros_ish_cl;
0648     struct ishtp_cl_data *client_data =
0649         devm_kzalloc(ishtp_device(cl_device),
0650                  sizeof(*client_data), GFP_KERNEL);
0651     if (!client_data)
0652         return -ENOMEM;
0653 
0654     /* Lock for initialization to complete */
0655     down_write(&init_lock);
0656 
0657     cros_ish_cl = ishtp_cl_allocate(cl_device);
0658     if (!cros_ish_cl) {
0659         rv = -ENOMEM;
0660         goto end_ishtp_cl_alloc_error;
0661     }
0662 
0663     ishtp_set_drvdata(cl_device, cros_ish_cl);
0664     ishtp_set_client_data(cros_ish_cl, client_data);
0665     client_data->cros_ish_cl = cros_ish_cl;
0666     client_data->cl_device = cl_device;
0667 
0668     init_waitqueue_head(&client_data->response.wait_queue);
0669 
0670     INIT_WORK(&client_data->work_ishtp_reset,
0671           reset_handler);
0672     INIT_WORK(&client_data->work_ec_evt,
0673           ish_evt_handler);
0674 
0675     rv = cros_ish_init(cros_ish_cl);
0676     if (rv)
0677         goto end_ishtp_cl_init_error;
0678 
0679     ishtp_get_device(cl_device);
0680 
0681     up_write(&init_lock);
0682 
0683     /* Register croc_ec_dev mfd */
0684     rv = cros_ec_dev_init(client_data);
0685     if (rv) {
0686         down_write(&init_lock);
0687         goto end_cros_ec_dev_init_error;
0688     }
0689 
0690     return 0;
0691 
0692 end_cros_ec_dev_init_error:
0693     ishtp_set_connection_state(cros_ish_cl, ISHTP_CL_DISCONNECTING);
0694     ishtp_cl_disconnect(cros_ish_cl);
0695     ishtp_cl_unlink(cros_ish_cl);
0696     ishtp_cl_flush_queues(cros_ish_cl);
0697     ishtp_put_device(cl_device);
0698 end_ishtp_cl_init_error:
0699     ishtp_cl_free(cros_ish_cl);
0700 end_ishtp_cl_alloc_error:
0701     up_write(&init_lock);
0702     return rv;
0703 }
0704 
0705 /**
0706  * cros_ec_ishtp_remove() - ISHTP client driver remove callback
0707  * @cl_device: ISHTP client device instance
0708  *
0709  * Return: 0
0710  */
0711 static void cros_ec_ishtp_remove(struct ishtp_cl_device *cl_device)
0712 {
0713     struct ishtp_cl *cros_ish_cl = ishtp_get_drvdata(cl_device);
0714     struct ishtp_cl_data *client_data = ishtp_get_client_data(cros_ish_cl);
0715 
0716     cancel_work_sync(&client_data->work_ishtp_reset);
0717     cancel_work_sync(&client_data->work_ec_evt);
0718     cros_ish_deinit(cros_ish_cl);
0719     ishtp_put_device(cl_device);
0720 }
0721 
0722 /**
0723  * cros_ec_ishtp_reset() - ISHTP client driver reset callback
0724  * @cl_device: ISHTP client device instance
0725  *
0726  * Return: 0
0727  */
0728 static int cros_ec_ishtp_reset(struct ishtp_cl_device *cl_device)
0729 {
0730     struct ishtp_cl *cros_ish_cl = ishtp_get_drvdata(cl_device);
0731     struct ishtp_cl_data *client_data = ishtp_get_client_data(cros_ish_cl);
0732 
0733     schedule_work(&client_data->work_ishtp_reset);
0734 
0735     return 0;
0736 }
0737 
0738 /**
0739  * cros_ec_ishtp_suspend() - ISHTP client driver suspend callback
0740  * @device: device instance
0741  *
0742  * Return: 0 for success, negative error code for failure.
0743  */
0744 static int __maybe_unused cros_ec_ishtp_suspend(struct device *device)
0745 {
0746     struct ishtp_cl_device *cl_device = ishtp_dev_to_cl_device(device);
0747     struct ishtp_cl *cros_ish_cl = ishtp_get_drvdata(cl_device);
0748     struct ishtp_cl_data *client_data = ishtp_get_client_data(cros_ish_cl);
0749 
0750     return cros_ec_suspend(client_data->ec_dev);
0751 }
0752 
0753 /**
0754  * cros_ec_ishtp_resume() - ISHTP client driver resume callback
0755  * @device: device instance
0756  *
0757  * Return: 0 for success, negative error code for failure.
0758  */
0759 static int __maybe_unused cros_ec_ishtp_resume(struct device *device)
0760 {
0761     struct ishtp_cl_device *cl_device = ishtp_dev_to_cl_device(device);
0762     struct ishtp_cl *cros_ish_cl = ishtp_get_drvdata(cl_device);
0763     struct ishtp_cl_data *client_data = ishtp_get_client_data(cros_ish_cl);
0764 
0765     return cros_ec_resume(client_data->ec_dev);
0766 }
0767 
0768 static SIMPLE_DEV_PM_OPS(cros_ec_ishtp_pm_ops, cros_ec_ishtp_suspend,
0769              cros_ec_ishtp_resume);
0770 
0771 static struct ishtp_cl_driver   cros_ec_ishtp_driver = {
0772     .name = "cros_ec_ishtp",
0773     .id = cros_ec_ishtp_id_table,
0774     .probe = cros_ec_ishtp_probe,
0775     .remove = cros_ec_ishtp_remove,
0776     .reset = cros_ec_ishtp_reset,
0777     .driver = {
0778         .pm = &cros_ec_ishtp_pm_ops,
0779     },
0780 };
0781 
0782 static int __init cros_ec_ishtp_mod_init(void)
0783 {
0784     return ishtp_cl_driver_register(&cros_ec_ishtp_driver, THIS_MODULE);
0785 }
0786 
0787 static void __exit cros_ec_ishtp_mod_exit(void)
0788 {
0789     ishtp_cl_driver_unregister(&cros_ec_ishtp_driver);
0790 }
0791 
0792 module_init(cros_ec_ishtp_mod_init);
0793 module_exit(cros_ec_ishtp_mod_exit);
0794 
0795 MODULE_DESCRIPTION("ChromeOS EC ISHTP Client Driver");
0796 MODULE_AUTHOR("Rushikesh S Kadam <rushikesh.s.kadam@intel.com>");
0797 
0798 MODULE_LICENSE("GPL v2");