Lines Matching +full:autosuspend +full:- +full:delay

1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2003-2022, Intel Corporation. All rights reserved.
9 #include <linux/delay.h>
12 #include <linux/dma-mapping.h>
21 * mei_me_cl_init - initialize me client
27 INIT_LIST_HEAD(&me_cl->list); in mei_me_cl_init()
28 kref_init(&me_cl->refcnt); in mei_me_cl_init()
32 * mei_me_cl_get - increases me client refcount
36 * Locking: called under "dev->device_lock" lock
42 if (me_cl && kref_get_unless_zero(&me_cl->refcnt)) in mei_me_cl_get()
49 * mei_me_cl_release - free me client
53 * Locking: called under "dev->device_lock" lock
64 * mei_me_cl_put - decrease me client refcount and free client if necessary
68 * Locking: called under "dev->device_lock" lock
73 kref_put(&me_cl->refcnt, mei_me_cl_release); in mei_me_cl_put()
77 * __mei_me_cl_del - delete me client from the list and decrease
83 * Locking: dev->me_clients_rwsem
90 list_del_init(&me_cl->list); in __mei_me_cl_del()
95 * mei_me_cl_del - delete me client from the list and decrease
103 down_write(&dev->me_clients_rwsem); in mei_me_cl_del()
105 up_write(&dev->me_clients_rwsem); in mei_me_cl_del()
109 * mei_me_cl_add - add me client to the list
116 down_write(&dev->me_clients_rwsem); in mei_me_cl_add()
117 list_add(&me_cl->list, &dev->me_clients); in mei_me_cl_add()
118 up_write(&dev->me_clients_rwsem); in mei_me_cl_add()
122 * __mei_me_cl_by_uuid - locate me client by uuid
130 * Locking: dev->me_clients_rwsem
138 WARN_ON(!rwsem_is_locked(&dev->me_clients_rwsem)); in __mei_me_cl_by_uuid()
140 list_for_each_entry(me_cl, &dev->me_clients, list) { in __mei_me_cl_by_uuid()
141 pn = &me_cl->props.protocol_name; in __mei_me_cl_by_uuid()
150 * mei_me_cl_by_uuid - locate me client by uuid
158 * Locking: dev->me_clients_rwsem
165 down_read(&dev->me_clients_rwsem); in mei_me_cl_by_uuid()
167 up_read(&dev->me_clients_rwsem); in mei_me_cl_by_uuid()
173 * mei_me_cl_by_id - locate me client by client id
181 * Locking: dev->me_clients_rwsem
188 down_read(&dev->me_clients_rwsem); in mei_me_cl_by_id()
189 list_for_each_entry(__me_cl, &dev->me_clients, list) { in mei_me_cl_by_id()
190 if (__me_cl->client_id == client_id) { in mei_me_cl_by_id()
195 up_read(&dev->me_clients_rwsem); in mei_me_cl_by_id()
201 * __mei_me_cl_by_uuid_id - locate me client by client id and uuid
210 * Locking: dev->me_clients_rwsem
218 WARN_ON(!rwsem_is_locked(&dev->me_clients_rwsem)); in __mei_me_cl_by_uuid_id()
220 list_for_each_entry(me_cl, &dev->me_clients, list) { in __mei_me_cl_by_uuid_id()
221 pn = &me_cl->props.protocol_name; in __mei_me_cl_by_uuid_id()
223 me_cl->client_id == client_id) in __mei_me_cl_by_uuid_id()
232 * mei_me_cl_by_uuid_id - locate me client by client id and uuid
246 down_read(&dev->me_clients_rwsem); in mei_me_cl_by_uuid_id()
248 up_read(&dev->me_clients_rwsem); in mei_me_cl_by_uuid_id()
254 * mei_me_cl_rm_by_uuid - remove all me clients matching uuid
259 * Locking: called under "dev->device_lock" lock
265 dev_dbg(dev->dev, "remove %pUl\n", uuid); in mei_me_cl_rm_by_uuid()
267 down_write(&dev->me_clients_rwsem); in mei_me_cl_rm_by_uuid()
271 up_write(&dev->me_clients_rwsem); in mei_me_cl_rm_by_uuid()
275 * mei_me_cl_rm_by_uuid_id - remove all me clients matching client id
281 * Locking: called under "dev->device_lock" lock
287 dev_dbg(dev->dev, "remove %pUl %d\n", uuid, id); in mei_me_cl_rm_by_uuid_id()
289 down_write(&dev->me_clients_rwsem); in mei_me_cl_rm_by_uuid_id()
293 up_write(&dev->me_clients_rwsem); in mei_me_cl_rm_by_uuid_id()
297 * mei_me_cl_rm_all - remove all me clients
301 * Locking: called under "dev->device_lock" lock
307 down_write(&dev->me_clients_rwsem); in mei_me_cl_rm_all()
308 list_for_each_entry_safe(me_cl, next, &dev->me_clients, list) in mei_me_cl_rm_all()
310 up_write(&dev->me_clients_rwsem); in mei_me_cl_rm_all()
314 * mei_io_cb_free - free mei_cb_private related memory
323 list_del(&cb->list); in mei_io_cb_free()
324 kvfree(cb->buf.data); in mei_io_cb_free()
325 kfree(cb->ext_hdr); in mei_io_cb_free()
330 * mei_tx_cb_enqueue - queue tx callback
335 * Locking: called under "dev->device_lock" lock
340 list_add_tail(&cb->list, head); in mei_tx_cb_enqueue()
341 cb->cl->tx_cb_queued++; in mei_tx_cb_enqueue()
345 * mei_tx_cb_dequeue - dequeue tx callback
349 * Locking: called under "dev->device_lock" lock
353 if (!WARN_ON(cb->cl->tx_cb_queued == 0)) in mei_tx_cb_dequeue()
354 cb->cl->tx_cb_queued--; in mei_tx_cb_dequeue()
360 * mei_cl_set_read_by_fp - set pending_read flag to vtag struct for given fp
365 * Locking: called under "dev->device_lock" lock
372 list_for_each_entry(cl_vtag, &cl->vtag_map, list) { in mei_cl_set_read_by_fp()
373 if (cl_vtag->fp == fp) { in mei_cl_set_read_by_fp()
374 cl_vtag->pending_read = true; in mei_cl_set_read_by_fp()
381 * mei_io_cb_init - allocate and initialize io callback
399 INIT_LIST_HEAD(&cb->list); in mei_io_cb_init()
400 cb->fp = fp; in mei_io_cb_init()
401 cb->cl = cl; in mei_io_cb_init()
402 cb->buf_idx = 0; in mei_io_cb_init()
403 cb->fop_type = type; in mei_io_cb_init()
404 cb->vtag = 0; in mei_io_cb_init()
405 cb->ext_hdr = NULL; in mei_io_cb_init()
411 * mei_io_list_flush_cl - removes cbs belonging to the cl.
422 if (cl == cb->cl) { in mei_io_list_flush_cl()
423 list_del_init(&cb->list); in mei_io_list_flush_cl()
424 if (cb->fop_type == MEI_FOP_READ) in mei_io_list_flush_cl()
431 * mei_io_tx_list_free_cl - removes cb belonging to the cl and free them
444 if (cl == cb->cl && (!fp || fp == cb->fp)) in mei_io_tx_list_free_cl()
450 * mei_io_list_free_fp - free cb from a list that matches file pointer
460 if (!fp || fp == cb->fp) in mei_io_list_free_fp()
465 * mei_cl_free_pending - free pending cb
473 cb = list_first_entry_or_null(&cl->rd_pending, struct mei_cl_cb, list); in mei_cl_free_pending()
478 * mei_cl_alloc_cb - a convenient wrapper for allocating read cb
500 cb->buf.data = kvmalloc(roundup(length, MEI_SLOT_SIZE), GFP_KERNEL); in mei_cl_alloc_cb()
501 if (!cb->buf.data) { in mei_cl_alloc_cb()
505 cb->buf.size = length; in mei_cl_alloc_cb()
511 * mei_cl_enqueue_ctrl_wr_cb - a convenient wrapper for allocating
520 * Locking: called under "dev->device_lock" lock
536 list_add_tail(&cb->list, &cl->dev->ctrl_wr_list); in mei_cl_enqueue_ctrl_wr_cb()
541 * mei_cl_read_cb - find this cl's callback in the read list
554 spin_lock(&cl->rd_completed_lock); in mei_cl_read_cb()
555 list_for_each_entry(cb, &cl->rd_completed, list) in mei_cl_read_cb()
556 if (!fp || fp == cb->fp) { in mei_cl_read_cb()
560 spin_unlock(&cl->rd_completed_lock); in mei_cl_read_cb()
565 * mei_cl_flush_queues - flushes queue lists belonging to cl.
570 * Return: 0 on success, -EINVAL if cl or cl->dev is NULL.
576 if (WARN_ON(!cl || !cl->dev)) in mei_cl_flush_queues()
577 return -EINVAL; in mei_cl_flush_queues()
579 dev = cl->dev; in mei_cl_flush_queues()
582 mei_io_tx_list_free_cl(&cl->dev->write_list, cl, fp); in mei_cl_flush_queues()
583 mei_io_tx_list_free_cl(&cl->dev->write_waiting_list, cl, fp); in mei_cl_flush_queues()
586 mei_io_list_flush_cl(&cl->dev->ctrl_wr_list, cl); in mei_cl_flush_queues()
587 mei_io_list_flush_cl(&cl->dev->ctrl_rd_list, cl); in mei_cl_flush_queues()
590 spin_lock(&cl->rd_completed_lock); in mei_cl_flush_queues()
591 mei_io_list_free_fp(&cl->rd_completed, fp); in mei_cl_flush_queues()
592 spin_unlock(&cl->rd_completed_lock); in mei_cl_flush_queues()
598 * mei_cl_init - initializes cl.
606 init_waitqueue_head(&cl->wait); in mei_cl_init()
607 init_waitqueue_head(&cl->rx_wait); in mei_cl_init()
608 init_waitqueue_head(&cl->tx_wait); in mei_cl_init()
609 init_waitqueue_head(&cl->ev_wait); in mei_cl_init()
610 INIT_LIST_HEAD(&cl->vtag_map); in mei_cl_init()
611 spin_lock_init(&cl->rd_completed_lock); in mei_cl_init()
612 INIT_LIST_HEAD(&cl->rd_completed); in mei_cl_init()
613 INIT_LIST_HEAD(&cl->rd_pending); in mei_cl_init()
614 INIT_LIST_HEAD(&cl->link); in mei_cl_init()
615 cl->writing_state = MEI_IDLE; in mei_cl_init()
616 cl->state = MEI_FILE_UNINITIALIZED; in mei_cl_init()
617 cl->dev = dev; in mei_cl_init()
621 * mei_cl_allocate - allocates cl structure and sets it up.
640 * mei_cl_link - allocate host id in the host map
645 * -EINVAL on incorrect values
646 * -EMFILE if open count exceeded.
653 if (WARN_ON(!cl || !cl->dev)) in mei_cl_link()
654 return -EINVAL; in mei_cl_link()
656 dev = cl->dev; in mei_cl_link()
658 id = find_first_zero_bit(dev->host_clients_map, MEI_CLIENTS_MAX); in mei_cl_link()
660 dev_err(dev->dev, "id exceeded %d", MEI_CLIENTS_MAX); in mei_cl_link()
661 return -EMFILE; in mei_cl_link()
664 if (dev->open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT) { in mei_cl_link()
665 dev_err(dev->dev, "open_handle_count exceeded %d", in mei_cl_link()
667 return -EMFILE; in mei_cl_link()
670 dev->open_handle_count++; in mei_cl_link()
672 cl->host_client_id = id; in mei_cl_link()
673 list_add_tail(&cl->link, &dev->file_list); in mei_cl_link()
675 set_bit(id, dev->host_clients_map); in mei_cl_link()
677 cl->state = MEI_FILE_INITIALIZING; in mei_cl_link()
684 * mei_cl_unlink - remove host client from the list
698 if (WARN_ON(!cl->dev)) in mei_cl_unlink()
701 dev = cl->dev; in mei_cl_unlink()
705 if (cl->state == MEI_FILE_UNINITIALIZED) in mei_cl_unlink()
708 if (dev->open_handle_count > 0) in mei_cl_unlink()
709 dev->open_handle_count--; in mei_cl_unlink()
712 if (cl->host_client_id) in mei_cl_unlink()
713 clear_bit(cl->host_client_id, dev->host_clients_map); in mei_cl_unlink()
715 list_del_init(&cl->link); in mei_cl_unlink()
717 cl->state = MEI_FILE_UNINITIALIZED; in mei_cl_unlink()
718 cl->writing_state = MEI_IDLE; in mei_cl_unlink()
720 WARN_ON(!list_empty(&cl->rd_completed) || in mei_cl_unlink()
721 !list_empty(&cl->rd_pending) || in mei_cl_unlink()
722 !list_empty(&cl->link)); in mei_cl_unlink()
730 dev->reset_count = 0; in mei_host_client_init()
732 schedule_work(&dev->bus_rescan_work); in mei_host_client_init()
734 pm_runtime_mark_last_busy(dev->dev); in mei_host_client_init()
735 dev_dbg(dev->dev, "rpm: autosuspend\n"); in mei_host_client_init()
736 pm_request_autosuspend(dev->dev); in mei_host_client_init()
740 * mei_hbuf_acquire - try to acquire host buffer
749 dev_dbg(dev->dev, "device is in pg\n"); in mei_hbuf_acquire()
753 if (!dev->hbuf_is_ready) { in mei_hbuf_acquire()
754 dev_dbg(dev->dev, "hbuf is not ready\n"); in mei_hbuf_acquire()
758 dev->hbuf_is_ready = false; in mei_hbuf_acquire()
764 * mei_cl_wake_all - wake up readers, writers and event waiters so
771 struct mei_device *dev = cl->dev; in mei_cl_wake_all()
774 if (waitqueue_active(&cl->rx_wait)) { in mei_cl_wake_all()
776 wake_up_interruptible(&cl->rx_wait); in mei_cl_wake_all()
779 if (waitqueue_active(&cl->tx_wait)) { in mei_cl_wake_all()
781 wake_up_interruptible(&cl->tx_wait); in mei_cl_wake_all()
784 if (waitqueue_active(&cl->ev_wait)) { in mei_cl_wake_all()
786 wake_up_interruptible(&cl->ev_wait); in mei_cl_wake_all()
789 if (waitqueue_active(&cl->wait)) { in mei_cl_wake_all()
791 wake_up(&cl->wait); in mei_cl_wake_all()
796 * mei_cl_set_disconnected - set disconnected state and clear
803 struct mei_device *dev = cl->dev; in mei_cl_set_disconnected()
805 if (cl->state == MEI_FILE_DISCONNECTED || in mei_cl_set_disconnected()
806 cl->state <= MEI_FILE_INITIALIZING) in mei_cl_set_disconnected()
809 cl->state = MEI_FILE_DISCONNECTED; in mei_cl_set_disconnected()
810 mei_io_tx_list_free_cl(&dev->write_list, cl, NULL); in mei_cl_set_disconnected()
811 mei_io_tx_list_free_cl(&dev->write_waiting_list, cl, NULL); in mei_cl_set_disconnected()
812 mei_io_list_flush_cl(&dev->ctrl_rd_list, cl); in mei_cl_set_disconnected()
813 mei_io_list_flush_cl(&dev->ctrl_wr_list, cl); in mei_cl_set_disconnected()
815 cl->rx_flow_ctrl_creds = 0; in mei_cl_set_disconnected()
816 cl->tx_flow_ctrl_creds = 0; in mei_cl_set_disconnected()
817 cl->timer_count = 0; in mei_cl_set_disconnected()
819 if (!cl->me_cl) in mei_cl_set_disconnected()
822 if (!WARN_ON(cl->me_cl->connect_count == 0)) in mei_cl_set_disconnected()
823 cl->me_cl->connect_count--; in mei_cl_set_disconnected()
825 if (cl->me_cl->connect_count == 0) in mei_cl_set_disconnected()
826 cl->me_cl->tx_flow_ctrl_creds = 0; in mei_cl_set_disconnected()
828 mei_me_cl_put(cl->me_cl); in mei_cl_set_disconnected()
829 cl->me_cl = NULL; in mei_cl_set_disconnected()
835 return -ENOENT; in mei_cl_set_connecting()
838 if (me_cl->props.fixed_address) { in mei_cl_set_connecting()
839 if (me_cl->connect_count) { in mei_cl_set_connecting()
841 return -EBUSY; in mei_cl_set_connecting()
845 cl->me_cl = me_cl; in mei_cl_set_connecting()
846 cl->state = MEI_FILE_CONNECTING; in mei_cl_set_connecting()
847 cl->me_cl->connect_count++; in mei_cl_set_connecting()
853 * mei_cl_send_disconnect - send disconnect request
865 dev = cl->dev; in mei_cl_send_disconnect()
868 cl->status = ret; in mei_cl_send_disconnect()
870 cl->state = MEI_FILE_DISCONNECT_REPLY; in mei_cl_send_disconnect()
874 list_move_tail(&cb->list, &dev->ctrl_rd_list); in mei_cl_send_disconnect()
875 cl->timer_count = dev->timeouts.connect; in mei_cl_send_disconnect()
882 * mei_cl_irq_disconnect - processes close related operation from
883 * interrupt thread context - send disconnect request
894 struct mei_device *dev = cl->dev; in mei_cl_irq_disconnect()
902 return -EOVERFLOW; in mei_cl_irq_disconnect()
905 return -EMSGSIZE; in mei_cl_irq_disconnect()
909 list_move_tail(&cb->list, cmpl_list); in mei_cl_irq_disconnect()
915 * __mei_cl_disconnect - disconnect host client from the me one
928 dev = cl->dev; in __mei_cl_disconnect()
930 cl->state = MEI_FILE_DISCONNECTING; in __mei_cl_disconnect()
934 rets = -ENOMEM; in __mei_cl_disconnect()
946 mutex_unlock(&dev->device_lock); in __mei_cl_disconnect()
947 wait_event_timeout(cl->wait, in __mei_cl_disconnect()
948 cl->state == MEI_FILE_DISCONNECT_REPLY || in __mei_cl_disconnect()
949 cl->state == MEI_FILE_DISCONNECTED, in __mei_cl_disconnect()
950 dev->timeouts.cl_connect); in __mei_cl_disconnect()
951 mutex_lock(&dev->device_lock); in __mei_cl_disconnect()
953 rets = cl->status; in __mei_cl_disconnect()
954 if (cl->state != MEI_FILE_DISCONNECT_REPLY && in __mei_cl_disconnect()
955 cl->state != MEI_FILE_DISCONNECTED) { in __mei_cl_disconnect()
957 rets = -ETIME; in __mei_cl_disconnect()
971 * mei_cl_disconnect - disconnect host client from the me one
975 * Locking: called under "dev->device_lock" lock
984 if (WARN_ON(!cl || !cl->dev)) in mei_cl_disconnect()
985 return -ENODEV; in mei_cl_disconnect()
987 dev = cl->dev; in mei_cl_disconnect()
999 if (dev->dev_state == MEI_DEV_POWERING_DOWN || in mei_cl_disconnect()
1000 dev->dev_state == MEI_DEV_POWER_DOWN) { in mei_cl_disconnect()
1006 rets = pm_runtime_get(dev->dev); in mei_cl_disconnect()
1007 if (rets < 0 && rets != -EINPROGRESS) { in mei_cl_disconnect()
1008 pm_runtime_put_noidle(dev->dev); in mei_cl_disconnect()
1015 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_disconnect()
1016 pm_runtime_mark_last_busy(dev->dev); in mei_cl_disconnect()
1017 pm_runtime_put_autosuspend(dev->dev); in mei_cl_disconnect()
1024 * mei_cl_is_other_connecting - checks if other
1029 * Return: true if other client is connected, false - otherwise.
1036 dev = cl->dev; in mei_cl_is_other_connecting()
1038 list_for_each_entry(cb, &dev->ctrl_rd_list, list) { in mei_cl_is_other_connecting()
1039 if (cb->fop_type == MEI_FOP_CONNECT && in mei_cl_is_other_connecting()
1040 mei_cl_me_id(cl) == mei_cl_me_id(cb->cl)) in mei_cl_is_other_connecting()
1048 * mei_cl_send_connect - send connect request
1060 dev = cl->dev; in mei_cl_send_connect()
1063 cl->status = ret; in mei_cl_send_connect()
1065 cl->state = MEI_FILE_DISCONNECT_REPLY; in mei_cl_send_connect()
1069 list_move_tail(&cb->list, &dev->ctrl_rd_list); in mei_cl_send_connect()
1070 cl->timer_count = dev->timeouts.connect; in mei_cl_send_connect()
1076 * mei_cl_irq_connect - send connect request in irq_thread context
1087 struct mei_device *dev = cl->dev; in mei_cl_irq_connect()
1098 return -EOVERFLOW; in mei_cl_irq_connect()
1101 return -EMSGSIZE; in mei_cl_irq_connect()
1105 list_move_tail(&cb->list, cmpl_list); in mei_cl_irq_connect()
1111 * mei_cl_connect - connect host client to the me one
1117 * Locking: called under "dev->device_lock" lock
1128 if (WARN_ON(!cl || !cl->dev || !me_cl)) in mei_cl_connect()
1129 return -ENODEV; in mei_cl_connect()
1131 dev = cl->dev; in mei_cl_connect()
1138 cl->state = MEI_FILE_CONNECTED; in mei_cl_connect()
1143 rets = pm_runtime_get(dev->dev); in mei_cl_connect()
1144 if (rets < 0 && rets != -EINPROGRESS) { in mei_cl_connect()
1145 pm_runtime_put_noidle(dev->dev); in mei_cl_connect()
1152 rets = -ENOMEM; in mei_cl_connect()
1163 mutex_unlock(&dev->device_lock); in mei_cl_connect()
1164 wait_event_timeout(cl->wait, in mei_cl_connect()
1165 (cl->state == MEI_FILE_CONNECTED || in mei_cl_connect()
1166 cl->state == MEI_FILE_DISCONNECTED || in mei_cl_connect()
1167 cl->state == MEI_FILE_DISCONNECT_REQUIRED || in mei_cl_connect()
1168 cl->state == MEI_FILE_DISCONNECT_REPLY), in mei_cl_connect()
1169 dev->timeouts.cl_connect); in mei_cl_connect()
1170 mutex_lock(&dev->device_lock); in mei_cl_connect()
1173 if (cl->state == MEI_FILE_DISCONNECT_REQUIRED) { in mei_cl_connect()
1174 mei_io_list_flush_cl(&dev->ctrl_rd_list, cl); in mei_cl_connect()
1175 mei_io_list_flush_cl(&dev->ctrl_wr_list, cl); in mei_cl_connect()
1180 rets = -EFAULT; in mei_cl_connect()
1185 if (!cl->status) in mei_cl_connect()
1186 cl->status = -EFAULT; in mei_cl_connect()
1189 rets = cl->status; in mei_cl_connect()
1191 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_connect()
1192 pm_runtime_mark_last_busy(dev->dev); in mei_cl_connect()
1193 pm_runtime_put_autosuspend(dev->dev); in mei_cl_connect()
1205 * mei_cl_alloc_linked - allocate and link host client
1218 ret = -ENOMEM; in mei_cl_alloc_linked()
1233 * mei_cl_tx_flow_ctrl_creds - checks flow_control credits for cl.
1237 * Return: 1 if tx_flow_ctrl_creds >0, 0 - otherwise.
1241 if (WARN_ON(!cl || !cl->me_cl)) in mei_cl_tx_flow_ctrl_creds()
1242 return -EINVAL; in mei_cl_tx_flow_ctrl_creds()
1244 if (cl->tx_flow_ctrl_creds > 0) in mei_cl_tx_flow_ctrl_creds()
1251 if (cl->me_cl->tx_flow_ctrl_creds > 0) in mei_cl_tx_flow_ctrl_creds()
1258 * mei_cl_tx_flow_ctrl_creds_reduce - reduces transmit flow control credits
1265 * -EINVAL when ctrl credits are <= 0
1269 if (WARN_ON(!cl || !cl->me_cl)) in mei_cl_tx_flow_ctrl_creds_reduce()
1270 return -EINVAL; in mei_cl_tx_flow_ctrl_creds_reduce()
1276 if (WARN_ON(cl->me_cl->tx_flow_ctrl_creds <= 0)) in mei_cl_tx_flow_ctrl_creds_reduce()
1277 return -EINVAL; in mei_cl_tx_flow_ctrl_creds_reduce()
1278 cl->me_cl->tx_flow_ctrl_creds--; in mei_cl_tx_flow_ctrl_creds_reduce()
1280 if (WARN_ON(cl->tx_flow_ctrl_creds <= 0)) in mei_cl_tx_flow_ctrl_creds_reduce()
1281 return -EINVAL; in mei_cl_tx_flow_ctrl_creds_reduce()
1282 cl->tx_flow_ctrl_creds--; in mei_cl_tx_flow_ctrl_creds_reduce()
1288 * mei_cl_vtag_alloc - allocate and fill the vtag structure
1294 * * Pointer to allocated struct - on success
1295 * * ERR_PTR(-ENOMEM) on memory allocation failure
1303 return ERR_PTR(-ENOMEM); in mei_cl_vtag_alloc()
1305 INIT_LIST_HEAD(&cl_vtag->list); in mei_cl_vtag_alloc()
1306 cl_vtag->vtag = vtag; in mei_cl_vtag_alloc()
1307 cl_vtag->fp = fp; in mei_cl_vtag_alloc()
1313 * mei_cl_fp_by_vtag - obtain the file pointer by vtag
1319 * * A file pointer - on success
1320 * * ERR_PTR(-ENOENT) if vtag is not found in the client vtag list
1326 list_for_each_entry(vtag_l, &cl->vtag_map, list) in mei_cl_fp_by_vtag()
1328 if ((cl->cldev && mei_cldev_enabled(cl->cldev)) || in mei_cl_fp_by_vtag()
1329 vtag_l->vtag == vtag) in mei_cl_fp_by_vtag()
1330 return vtag_l->fp; in mei_cl_fp_by_vtag()
1332 return ERR_PTR(-ENOENT); in mei_cl_fp_by_vtag()
1336 * mei_cl_reset_read_by_vtag - reset pending_read flag by given vtag
1345 list_for_each_entry(vtag_l, &cl->vtag_map, list) { in mei_cl_reset_read_by_vtag()
1347 if ((cl->cldev && mei_cldev_enabled(cl->cldev)) || in mei_cl_reset_read_by_vtag()
1348 vtag_l->vtag == vtag) { in mei_cl_reset_read_by_vtag()
1349 vtag_l->pending_read = false; in mei_cl_reset_read_by_vtag()
1356 * mei_cl_read_vtag_add_fc - add flow control for next pending reader
1365 list_for_each_entry(cl_vtag, &cl->vtag_map, list) { in mei_cl_read_vtag_add_fc()
1366 if (cl_vtag->pending_read) { in mei_cl_read_vtag_add_fc()
1370 cl_vtag->fp)) in mei_cl_read_vtag_add_fc()
1371 cl->rx_flow_ctrl_creds++; in mei_cl_read_vtag_add_fc()
1378 * mei_cl_vt_support_check - check if client support vtags
1383 * * 0 - supported, or not connected at all
1384 * * -EOPNOTSUPP - vtags are not supported by client
1388 struct mei_device *dev = cl->dev; in mei_cl_vt_support_check()
1390 if (!dev->hbm_f_vt_supported) in mei_cl_vt_support_check()
1391 return -EOPNOTSUPP; in mei_cl_vt_support_check()
1393 if (!cl->me_cl) in mei_cl_vt_support_check()
1396 return cl->me_cl->props.vt_supported ? 0 : -EOPNOTSUPP; in mei_cl_vt_support_check()
1400 * mei_cl_add_rd_completed - add read completed callback to list with lock
1412 fp = mei_cl_fp_by_vtag(cl, cb->vtag); in mei_cl_add_rd_completed()
1418 cb->fp = fp; in mei_cl_add_rd_completed()
1419 mei_cl_reset_read_by_vtag(cl, cb->vtag); in mei_cl_add_rd_completed()
1423 spin_lock(&cl->rd_completed_lock); in mei_cl_add_rd_completed()
1424 list_add_tail(&cb->list, &cl->rd_completed); in mei_cl_add_rd_completed()
1425 spin_unlock(&cl->rd_completed_lock); in mei_cl_add_rd_completed()
1429 * mei_cl_del_rd_completed - free read completed callback with lock
1437 spin_lock(&cl->rd_completed_lock); in mei_cl_del_rd_completed()
1439 spin_unlock(&cl->rd_completed_lock); in mei_cl_del_rd_completed()
1443 * mei_cl_notify_fop2req - convert fop to proper request
1458 * mei_cl_notify_req2fop - convert notification request top file operation type
1473 * mei_cl_irq_notify - send notification request in irq_thread context
1484 struct mei_device *dev = cl->dev; in mei_cl_irq_notify()
1493 return -EOVERFLOW; in mei_cl_irq_notify()
1496 return -EMSGSIZE; in mei_cl_irq_notify()
1498 request = mei_cl_notify_fop2req(cb->fop_type); in mei_cl_irq_notify()
1501 cl->status = ret; in mei_cl_irq_notify()
1502 list_move_tail(&cb->list, cmpl_list); in mei_cl_irq_notify()
1506 list_move_tail(&cb->list, &dev->ctrl_rd_list); in mei_cl_irq_notify()
1511 * mei_cl_notify_request - send notification stop/start request
1517 * Locking: called under "dev->device_lock" lock
1529 if (WARN_ON(!cl || !cl->dev)) in mei_cl_notify_request()
1530 return -ENODEV; in mei_cl_notify_request()
1532 dev = cl->dev; in mei_cl_notify_request()
1534 if (!dev->hbm_f_ev_supported) { in mei_cl_notify_request()
1536 return -EOPNOTSUPP; in mei_cl_notify_request()
1540 return -ENODEV; in mei_cl_notify_request()
1542 rets = pm_runtime_get(dev->dev); in mei_cl_notify_request()
1543 if (rets < 0 && rets != -EINPROGRESS) { in mei_cl_notify_request()
1544 pm_runtime_put_noidle(dev->dev); in mei_cl_notify_request()
1552 rets = -ENOMEM; in mei_cl_notify_request()
1558 rets = -ENODEV; in mei_cl_notify_request()
1561 list_move_tail(&cb->list, &dev->ctrl_rd_list); in mei_cl_notify_request()
1564 mutex_unlock(&dev->device_lock); in mei_cl_notify_request()
1565 wait_event_timeout(cl->wait, in mei_cl_notify_request()
1566 cl->notify_en == request || in mei_cl_notify_request()
1567 cl->status || in mei_cl_notify_request()
1569 dev->timeouts.cl_connect); in mei_cl_notify_request()
1570 mutex_lock(&dev->device_lock); in mei_cl_notify_request()
1572 if (cl->notify_en != request && !cl->status) in mei_cl_notify_request()
1573 cl->status = -EFAULT; in mei_cl_notify_request()
1575 rets = cl->status; in mei_cl_notify_request()
1578 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_notify_request()
1579 pm_runtime_mark_last_busy(dev->dev); in mei_cl_notify_request()
1580 pm_runtime_put_autosuspend(dev->dev); in mei_cl_notify_request()
1587 * mei_cl_notify - raise notification
1591 * Locking: called under "dev->device_lock" lock
1597 if (!cl || !cl->dev) in mei_cl_notify()
1600 dev = cl->dev; in mei_cl_notify()
1602 if (!cl->notify_en) in mei_cl_notify()
1606 cl->notify_ev = true; in mei_cl_notify()
1608 wake_up_interruptible(&cl->ev_wait); in mei_cl_notify()
1610 if (cl->ev_async) in mei_cl_notify()
1611 kill_fasync(&cl->ev_async, SIGIO, POLL_PRI); in mei_cl_notify()
1616 * mei_cl_notify_get - get or wait for notification event
1622 * Locking: called under "dev->device_lock" lock
1633 if (WARN_ON(!cl || !cl->dev)) in mei_cl_notify_get()
1634 return -ENODEV; in mei_cl_notify_get()
1636 dev = cl->dev; in mei_cl_notify_get()
1638 if (!dev->hbm_f_ev_supported) { in mei_cl_notify_get()
1640 return -EOPNOTSUPP; in mei_cl_notify_get()
1644 return -ENODEV; in mei_cl_notify_get()
1646 if (cl->notify_ev) in mei_cl_notify_get()
1650 return -EAGAIN; in mei_cl_notify_get()
1652 mutex_unlock(&dev->device_lock); in mei_cl_notify_get()
1653 rets = wait_event_interruptible(cl->ev_wait, cl->notify_ev); in mei_cl_notify_get()
1654 mutex_lock(&dev->device_lock); in mei_cl_notify_get()
1660 *notify_ev = cl->notify_ev; in mei_cl_notify_get()
1661 cl->notify_ev = false; in mei_cl_notify_get()
1666 * mei_cl_read_start - the start read client message function.
1680 if (WARN_ON(!cl || !cl->dev)) in mei_cl_read_start()
1681 return -ENODEV; in mei_cl_read_start()
1683 dev = cl->dev; in mei_cl_read_start()
1686 return -ENODEV; in mei_cl_read_start()
1688 if (!mei_me_cl_is_active(cl->me_cl)) { in mei_cl_read_start()
1690 return -ENOTTY; in mei_cl_read_start()
1697 if (cl->rx_flow_ctrl_creds) { in mei_cl_read_start()
1699 return -EBUSY; in mei_cl_read_start()
1704 return -ENOMEM; in mei_cl_read_start()
1708 rets = pm_runtime_get(dev->dev); in mei_cl_read_start()
1709 if (rets < 0 && rets != -EINPROGRESS) { in mei_cl_read_start()
1710 pm_runtime_put_noidle(dev->dev); in mei_cl_read_start()
1721 list_move_tail(&cb->list, &cl->rd_pending); in mei_cl_read_start()
1723 cl->rx_flow_ctrl_creds++; in mei_cl_read_start()
1726 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_read_start()
1727 pm_runtime_mark_last_busy(dev->dev); in mei_cl_read_start()
1728 pm_runtime_put_autosuspend(dev->dev); in mei_cl_read_start()
1740 vtag_hdr->hdr.type = MEI_EXT_HDR_VTAG; in mei_ext_hdr_set_vtag()
1741 vtag_hdr->hdr.length = mei_data2slots(sizeof(*vtag_hdr)); in mei_ext_hdr_set_vtag()
1742 vtag_hdr->vtag = vtag; in mei_ext_hdr_set_vtag()
1743 vtag_hdr->reserved = 0; in mei_ext_hdr_set_vtag()
1744 return vtag_hdr->hdr.length; in mei_ext_hdr_set_vtag()
1749 return ext && ext->type == MEI_EXT_HDR_GSC; in mei_ext_hdr_is_gsc()
1755 return ext->length; in mei_ext_hdr_set_gsc()
1759 * mei_msg_hdr_init - allocate and initialize mei message header
1774 return ERR_PTR(-EINVAL); in mei_msg_hdr_init()
1777 is_vtag = (cb->vtag && cb->buf_idx == 0); in mei_msg_hdr_init()
1778 is_hbm = cb->cl->me_cl->client_id == 0; in mei_msg_hdr_init()
1779 is_gsc = ((!is_hbm) && cb->cl->dev->hbm_f_gsc_supported && mei_ext_hdr_is_gsc(cb->ext_hdr)); in mei_msg_hdr_init()
1793 hdr_len += mei_ext_hdr_len(cb->ext_hdr); in mei_msg_hdr_init()
1798 return ERR_PTR(-ENOMEM); in mei_msg_hdr_init()
1800 mei_hdr->host_addr = mei_cl_host_addr(cb->cl); in mei_msg_hdr_init()
1801 mei_hdr->me_addr = mei_cl_me_id(cb->cl); in mei_msg_hdr_init()
1802 mei_hdr->internal = cb->internal; in mei_msg_hdr_init()
1803 mei_hdr->extended = is_ext; in mei_msg_hdr_init()
1808 meta = (struct mei_ext_meta_hdr *)mei_hdr->extension; in mei_msg_hdr_init()
1809 meta->size = 0; in mei_msg_hdr_init()
1810 next_ext = (struct mei_ext_hdr *)meta->hdrs; in mei_msg_hdr_init()
1812 meta->count++; in mei_msg_hdr_init()
1813 meta->size += mei_ext_hdr_set_vtag(next_ext, cb->vtag); in mei_msg_hdr_init()
1818 meta->count++; in mei_msg_hdr_init()
1819 meta->size += mei_ext_hdr_set_gsc(next_ext, cb->ext_hdr); in mei_msg_hdr_init()
1824 mei_hdr->length = hdr_len - sizeof(*mei_hdr); in mei_msg_hdr_init()
1829 * mei_cl_irq_write - write a message to device
1855 if (WARN_ON(!cl || !cl->dev)) in mei_cl_irq_write()
1856 return -ENODEV; in mei_cl_irq_write()
1858 dev = cl->dev; in mei_cl_irq_write()
1860 buf = &cb->buf; in mei_cl_irq_write()
1862 first_chunk = cb->buf_idx == 0; in mei_cl_irq_write()
1873 if (buf->data) { in mei_cl_irq_write()
1874 buf_len = buf->size - cb->buf_idx; in mei_cl_irq_write()
1875 data = buf->data + cb->buf_idx; in mei_cl_irq_write()
1879 rets = -EOVERFLOW; in mei_cl_irq_write()
1894 hdr_len = sizeof(*mei_hdr) + mei_hdr->length; in mei_cl_irq_write()
1902 mei_hdr->msg_complete = 1; in mei_cl_irq_write()
1904 mei_hdr->dma_ring = 1; in mei_cl_irq_write()
1908 mei_hdr->msg_complete = 1; in mei_cl_irq_write()
1914 buf_len = hbuf_len - hdr_len; in mei_cl_irq_write()
1920 mei_hdr->length += data_len; in mei_cl_irq_write()
1922 if (mei_hdr->dma_ring && buf->data) in mei_cl_irq_write()
1923 mei_dma_ring_write(dev, buf->data + cb->buf_idx, buf_len); in mei_cl_irq_write()
1929 cl->status = 0; in mei_cl_irq_write()
1930 cl->writing_state = MEI_WRITING; in mei_cl_irq_write()
1931 cb->buf_idx += buf_len; in mei_cl_irq_write()
1935 rets = -EIO; in mei_cl_irq_write()
1940 if (mei_hdr->msg_complete) in mei_cl_irq_write()
1941 list_move_tail(&cb->list, &dev->write_waiting_list); in mei_cl_irq_write()
1948 cl->status = rets; in mei_cl_irq_write()
1949 list_move_tail(&cb->list, cmpl_list); in mei_cl_irq_write()
1954 * mei_cl_write - submit a write cb to mei device
1960 * effective only for blocking writes: the cb->blocking is set.
1981 if (WARN_ON(!cl || !cl->dev)) in mei_cl_write()
1982 return -ENODEV; in mei_cl_write()
1985 return -EINVAL; in mei_cl_write()
1987 dev = cl->dev; in mei_cl_write()
1989 buf = &cb->buf; in mei_cl_write()
1990 buf_len = buf->size; in mei_cl_write()
1994 blocking = cb->blocking; in mei_cl_write()
1995 data = buf->data; in mei_cl_write()
1997 rets = pm_runtime_get(dev->dev); in mei_cl_write()
1998 if (rets < 0 && rets != -EINPROGRESS) { in mei_cl_write()
1999 pm_runtime_put_noidle(dev->dev); in mei_cl_write()
2004 cb->buf_idx = 0; in mei_cl_write()
2005 cl->writing_state = MEI_IDLE; in mei_cl_write()
2019 hdr_len = sizeof(*mei_hdr) + mei_hdr->length; in mei_cl_write()
2035 buf_len = -EOVERFLOW; in mei_cl_write()
2045 mei_hdr->msg_complete = 1; in mei_cl_write()
2047 mei_hdr->dma_ring = 1; in mei_cl_write()
2051 mei_hdr->msg_complete = 1; in mei_cl_write()
2057 buf_len = hbuf_len - hdr_len; in mei_cl_write()
2061 mei_hdr->length += data_len; in mei_cl_write()
2063 if (mei_hdr->dma_ring && buf->data) in mei_cl_write()
2064 mei_dma_ring_write(dev, buf->data, buf_len); in mei_cl_write()
2074 cl->writing_state = MEI_WRITING; in mei_cl_write()
2075 cb->buf_idx = buf_len; in mei_cl_write()
2077 buf_len = buf->size; in mei_cl_write()
2080 if (mei_hdr->msg_complete) in mei_cl_write()
2081 mei_tx_cb_enqueue(cb, &dev->write_waiting_list); in mei_cl_write()
2083 mei_tx_cb_enqueue(cb, &dev->write_list); in mei_cl_write()
2086 if (blocking && cl->writing_state != MEI_WRITE_COMPLETE) { in mei_cl_write()
2088 mutex_unlock(&dev->device_lock); in mei_cl_write()
2089 rets = wait_event_interruptible_timeout(cl->tx_wait, in mei_cl_write()
2090 cl->writing_state == MEI_WRITE_COMPLETE || in mei_cl_write()
2093 mutex_lock(&dev->device_lock); in mei_cl_write()
2096 rets = -ETIME; in mei_cl_write()
2097 mei_io_tx_list_free_cl(&dev->write_list, cl, NULL); in mei_cl_write()
2098 mei_io_tx_list_free_cl(&dev->write_waiting_list, cl, NULL); in mei_cl_write()
2100 /* wait_event_interruptible returns -ERESTARTSYS */ in mei_cl_write()
2105 rets = -EINTR; in mei_cl_write()
2108 if (cl->writing_state != MEI_WRITE_COMPLETE) { in mei_cl_write()
2109 rets = -EFAULT; in mei_cl_write()
2116 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_write()
2117 pm_runtime_mark_last_busy(dev->dev); in mei_cl_write()
2118 pm_runtime_put_autosuspend(dev->dev); in mei_cl_write()
2128 * mei_cl_complete - processes completed operation for a client
2135 struct mei_device *dev = cl->dev; in mei_cl_complete()
2137 switch (cb->fop_type) { in mei_cl_complete()
2140 cl->writing_state = MEI_WRITE_COMPLETE; in mei_cl_complete()
2141 if (waitqueue_active(&cl->tx_wait)) { in mei_cl_complete()
2142 wake_up_interruptible(&cl->tx_wait); in mei_cl_complete()
2144 pm_runtime_mark_last_busy(dev->dev); in mei_cl_complete()
2145 pm_request_autosuspend(dev->dev); in mei_cl_complete()
2152 !WARN_ON(!cl->rx_flow_ctrl_creds)) in mei_cl_complete()
2153 cl->rx_flow_ctrl_creds--; in mei_cl_complete()
2155 wake_up_interruptible(&cl->rx_wait); in mei_cl_complete()
2164 if (waitqueue_active(&cl->wait)) in mei_cl_complete()
2165 wake_up(&cl->wait); in mei_cl_complete()
2179 * mei_cl_all_disconnect - disconnect forcefully all connected clients
2187 list_for_each_entry(cl, &dev->file_list, link) in mei_cl_all_disconnect()
2196 list_for_each_entry(cl, &dev->file_list, link) in mei_cl_dma_map_find()
2197 if (cl->dma.buffer_id == buffer_id) in mei_cl_dma_map_find()
2203 * mei_cl_irq_dma_map - send client dma map request in irq_thread context
2214 struct mei_device *dev = cl->dev; in mei_cl_irq_dma_map()
2222 return -EOVERFLOW; in mei_cl_irq_dma_map()
2225 return -EMSGSIZE; in mei_cl_irq_dma_map()
2229 cl->status = ret; in mei_cl_irq_dma_map()
2230 list_move_tail(&cb->list, cmpl_list); in mei_cl_irq_dma_map()
2234 list_move_tail(&cb->list, &dev->ctrl_rd_list); in mei_cl_irq_dma_map()
2239 * mei_cl_irq_dma_unmap - send client dma unmap request in irq_thread context
2250 struct mei_device *dev = cl->dev; in mei_cl_irq_dma_unmap()
2258 return -EOVERFLOW; in mei_cl_irq_dma_unmap()
2261 return -EMSGSIZE; in mei_cl_irq_dma_unmap()
2265 cl->status = ret; in mei_cl_irq_dma_unmap()
2266 list_move_tail(&cb->list, cmpl_list); in mei_cl_irq_dma_unmap()
2270 list_move_tail(&cb->list, &dev->ctrl_rd_list); in mei_cl_irq_dma_unmap()
2276 cl->dma.vaddr = dmam_alloc_coherent(cl->dev->dev, size, in mei_cl_dma_alloc()
2277 &cl->dma.daddr, GFP_KERNEL); in mei_cl_dma_alloc()
2278 if (!cl->dma.vaddr) in mei_cl_dma_alloc()
2279 return -ENOMEM; in mei_cl_dma_alloc()
2281 cl->dma.buffer_id = buf_id; in mei_cl_dma_alloc()
2282 cl->dma.size = size; in mei_cl_dma_alloc()
2289 cl->dma.buffer_id = 0; in mei_cl_dma_free()
2290 dmam_free_coherent(cl->dev->dev, in mei_cl_dma_free()
2291 cl->dma.size, cl->dma.vaddr, cl->dma.daddr); in mei_cl_dma_free()
2292 cl->dma.size = 0; in mei_cl_dma_free()
2293 cl->dma.vaddr = NULL; in mei_cl_dma_free()
2294 cl->dma.daddr = 0; in mei_cl_dma_free()
2298 * mei_cl_dma_alloc_and_map - send client dma map request
2305 * Locking: called under "dev->device_lock" lock
2308 * * -ENODEV
2309 * * -EINVAL
2310 * * -EOPNOTSUPP
2311 * * -EPROTO
2312 * * -ENOMEM;
2321 if (WARN_ON(!cl || !cl->dev)) in mei_cl_dma_alloc_and_map()
2322 return -ENODEV; in mei_cl_dma_alloc_and_map()
2324 dev = cl->dev; in mei_cl_dma_alloc_and_map()
2326 if (!dev->hbm_f_cd_supported) { in mei_cl_dma_alloc_and_map()
2328 return -EOPNOTSUPP; in mei_cl_dma_alloc_and_map()
2332 return -EINVAL; in mei_cl_dma_alloc_and_map()
2335 return -EPROTO; in mei_cl_dma_alloc_and_map()
2337 if (cl->dma_mapped) in mei_cl_dma_alloc_and_map()
2338 return -EPROTO; in mei_cl_dma_alloc_and_map()
2342 cl->dma.buffer_id); in mei_cl_dma_alloc_and_map()
2343 return -EPROTO; in mei_cl_dma_alloc_and_map()
2346 rets = pm_runtime_get(dev->dev); in mei_cl_dma_alloc_and_map()
2347 if (rets < 0 && rets != -EINPROGRESS) { in mei_cl_dma_alloc_and_map()
2348 pm_runtime_put_noidle(dev->dev); in mei_cl_dma_alloc_and_map()
2355 pm_runtime_put_noidle(dev->dev); in mei_cl_dma_alloc_and_map()
2361 rets = -ENOMEM; in mei_cl_dma_alloc_and_map()
2367 rets = -ENODEV; in mei_cl_dma_alloc_and_map()
2370 list_move_tail(&cb->list, &dev->ctrl_rd_list); in mei_cl_dma_alloc_and_map()
2373 cl->status = 0; in mei_cl_dma_alloc_and_map()
2375 mutex_unlock(&dev->device_lock); in mei_cl_dma_alloc_and_map()
2376 wait_event_timeout(cl->wait, in mei_cl_dma_alloc_and_map()
2377 cl->dma_mapped || cl->status, in mei_cl_dma_alloc_and_map()
2378 dev->timeouts.cl_connect); in mei_cl_dma_alloc_and_map()
2379 mutex_lock(&dev->device_lock); in mei_cl_dma_alloc_and_map()
2381 if (!cl->dma_mapped && !cl->status) in mei_cl_dma_alloc_and_map()
2382 cl->status = -EFAULT; in mei_cl_dma_alloc_and_map()
2384 rets = cl->status; in mei_cl_dma_alloc_and_map()
2390 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_dma_alloc_and_map()
2391 pm_runtime_mark_last_busy(dev->dev); in mei_cl_dma_alloc_and_map()
2392 pm_runtime_put_autosuspend(dev->dev); in mei_cl_dma_alloc_and_map()
2399 * mei_cl_dma_unmap - send client dma unmap request
2404 * Locking: called under "dev->device_lock" lock
2414 if (WARN_ON(!cl || !cl->dev)) in mei_cl_dma_unmap()
2415 return -ENODEV; in mei_cl_dma_unmap()
2417 dev = cl->dev; in mei_cl_dma_unmap()
2419 if (!dev->hbm_f_cd_supported) { in mei_cl_dma_unmap()
2421 return -EOPNOTSUPP; in mei_cl_dma_unmap()
2426 return -EPROTO; in mei_cl_dma_unmap()
2428 if (!cl->dma_mapped) in mei_cl_dma_unmap()
2429 return -EPROTO; in mei_cl_dma_unmap()
2431 rets = pm_runtime_get(dev->dev); in mei_cl_dma_unmap()
2432 if (rets < 0 && rets != -EINPROGRESS) { in mei_cl_dma_unmap()
2433 pm_runtime_put_noidle(dev->dev); in mei_cl_dma_unmap()
2440 rets = -ENOMEM; in mei_cl_dma_unmap()
2446 rets = -ENODEV; in mei_cl_dma_unmap()
2449 list_move_tail(&cb->list, &dev->ctrl_rd_list); in mei_cl_dma_unmap()
2452 cl->status = 0; in mei_cl_dma_unmap()
2454 mutex_unlock(&dev->device_lock); in mei_cl_dma_unmap()
2455 wait_event_timeout(cl->wait, in mei_cl_dma_unmap()
2456 !cl->dma_mapped || cl->status, in mei_cl_dma_unmap()
2457 dev->timeouts.cl_connect); in mei_cl_dma_unmap()
2458 mutex_lock(&dev->device_lock); in mei_cl_dma_unmap()
2460 if (cl->dma_mapped && !cl->status) in mei_cl_dma_unmap()
2461 cl->status = -EFAULT; in mei_cl_dma_unmap()
2463 rets = cl->status; in mei_cl_dma_unmap()
2468 cl_dbg(dev, cl, "rpm: autosuspend\n"); in mei_cl_dma_unmap()
2469 pm_runtime_mark_last_busy(dev->dev); in mei_cl_dma_unmap()
2470 pm_runtime_put_autosuspend(dev->dev); in mei_cl_dma_unmap()