summaryrefslogtreecommitdiff
path: root/drivers/misc/mei/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/mei/client.c')
-rw-r--r--drivers/misc/mei/client.c132
1 files changed, 51 insertions, 81 deletions
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 9ddb854b8155..5dc665515263 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -48,9 +48,9 @@ struct mei_me_client *mei_me_cl_get(struct mei_me_client *me_cl)
/**
* mei_me_cl_release - free me client
*
- * Locking: called under "dev->device_lock" lock
- *
* @ref: me_client refcount
+ *
+ * Locking: called under "dev->device_lock" lock
*/
static void mei_me_cl_release(struct kref *ref)
{
@@ -63,9 +63,9 @@ static void mei_me_cl_release(struct kref *ref)
/**
* mei_me_cl_put - decrease me client refcount and free client if necessary
*
- * Locking: called under "dev->device_lock" lock
- *
* @me_cl: me client
+ *
+ * Locking: called under "dev->device_lock" lock
*/
void mei_me_cl_put(struct mei_me_client *me_cl)
{
@@ -262,7 +262,7 @@ void mei_me_cl_rm_by_uuid(struct mei_device *dev, const uuid_le *uuid)
{
struct mei_me_client *me_cl;
- dev_dbg(dev->dev, "remove %pUl\n", uuid);
+ dev_dbg(&dev->dev, "remove %pUl\n", uuid);
down_write(&dev->me_clients_rwsem);
me_cl = __mei_me_cl_by_uuid(dev, uuid);
@@ -272,28 +272,6 @@ void mei_me_cl_rm_by_uuid(struct mei_device *dev, const uuid_le *uuid)
}
/**
- * mei_me_cl_rm_by_uuid_id - remove all me clients matching client id
- *
- * @dev: the device structure
- * @uuid: me client uuid
- * @id: me client id
- *
- * Locking: called under "dev->device_lock" lock
- */
-void mei_me_cl_rm_by_uuid_id(struct mei_device *dev, const uuid_le *uuid, u8 id)
-{
- struct mei_me_client *me_cl;
-
- dev_dbg(dev->dev, "remove %pUl %d\n", uuid, id);
-
- down_write(&dev->me_clients_rwsem);
- me_cl = __mei_me_cl_by_uuid_id(dev, uuid, id);
- __mei_me_cl_del(dev, me_cl);
- mei_me_cl_put(me_cl);
- up_write(&dev->me_clients_rwsem);
-}
-
-/**
* mei_me_cl_rm_all - remove all me clients
*
* @dev: the device structure
@@ -321,7 +299,7 @@ void mei_io_cb_free(struct mei_cl_cb *cb)
return;
list_del(&cb->list);
- kfree(cb->buf.data);
+ kvfree(cb->buf.data);
kfree(cb->ext_hdr);
kfree(cb);
}
@@ -329,10 +307,10 @@ void mei_io_cb_free(struct mei_cl_cb *cb)
/**
* mei_tx_cb_enqueue - queue tx callback
*
- * Locking: called under "dev->device_lock" lock
- *
* @cb: mei callback struct
* @head: an instance of list to queue on
+ *
+ * Locking: called under "dev->device_lock" lock
*/
static inline void mei_tx_cb_enqueue(struct mei_cl_cb *cb,
struct list_head *head)
@@ -344,9 +322,9 @@ static inline void mei_tx_cb_enqueue(struct mei_cl_cb *cb,
/**
* mei_tx_cb_dequeue - dequeue tx callback
*
- * Locking: called under "dev->device_lock" lock
- *
* @cb: mei callback struct to dequeue and free
+ *
+ * Locking: called under "dev->device_lock" lock
*/
static inline void mei_tx_cb_dequeue(struct mei_cl_cb *cb)
{
@@ -359,10 +337,10 @@ static inline void mei_tx_cb_dequeue(struct mei_cl_cb *cb)
/**
* mei_cl_set_read_by_fp - set pending_read flag to vtag struct for given fp
*
- * Locking: called under "dev->device_lock" lock
- *
* @cl: mei client
* @fp: pointer to file structure
+ *
+ * Locking: called under "dev->device_lock" lock
*/
static void mei_cl_set_read_by_fp(const struct mei_cl *cl,
const struct file *fp)
@@ -497,7 +475,7 @@ struct mei_cl_cb *mei_cl_alloc_cb(struct mei_cl *cl, size_t length,
if (length == 0)
return cb;
- cb->buf.data = kmalloc(roundup(length, MEI_SLOT_SIZE), GFP_KERNEL);
+ cb->buf.data = kvmalloc(roundup(length, MEI_SLOT_SIZE), GFP_KERNEL);
if (!cb->buf.data) {
mei_io_cb_free(cb);
return NULL;
@@ -657,12 +635,12 @@ int mei_cl_link(struct mei_cl *cl)
id = find_first_zero_bit(dev->host_clients_map, MEI_CLIENTS_MAX);
if (id >= MEI_CLIENTS_MAX) {
- dev_err(dev->dev, "id exceeded %d", MEI_CLIENTS_MAX);
+ dev_err(&dev->dev, "id exceeded %d", MEI_CLIENTS_MAX);
return -EMFILE;
}
if (dev->open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT) {
- dev_err(dev->dev, "open_handle_count exceeded %d",
+ dev_err(&dev->dev, "open_handle_count exceeded %d",
MEI_MAX_OPEN_HANDLE_COUNT);
return -EMFILE;
}
@@ -731,9 +709,8 @@ void mei_host_client_init(struct mei_device *dev)
schedule_work(&dev->bus_rescan_work);
- pm_runtime_mark_last_busy(dev->dev);
- dev_dbg(dev->dev, "rpm: autosuspend\n");
- pm_request_autosuspend(dev->dev);
+ dev_dbg(&dev->dev, "rpm: autosuspend\n");
+ pm_request_autosuspend(dev->parent);
}
/**
@@ -746,12 +723,12 @@ bool mei_hbuf_acquire(struct mei_device *dev)
{
if (mei_pg_state(dev) == MEI_PG_ON ||
mei_pg_in_transition(dev)) {
- dev_dbg(dev->dev, "device is in pg\n");
+ dev_dbg(&dev->dev, "device is in pg\n");
return false;
}
if (!dev->hbuf_is_ready) {
- dev_dbg(dev->dev, "hbuf is not ready\n");
+ dev_dbg(&dev->dev, "hbuf is not ready\n");
return false;
}
@@ -1003,9 +980,9 @@ int mei_cl_disconnect(struct mei_cl *cl)
return 0;
}
- rets = pm_runtime_get(dev->dev);
+ rets = pm_runtime_get(dev->parent);
if (rets < 0 && rets != -EINPROGRESS) {
- pm_runtime_put_noidle(dev->dev);
+ pm_runtime_put_noidle(dev->parent);
cl_err(dev, cl, "rpm: get failed %d\n", rets);
return rets;
}
@@ -1013,8 +990,7 @@ int mei_cl_disconnect(struct mei_cl *cl)
rets = __mei_cl_disconnect(cl);
cl_dbg(dev, cl, "rpm: autosuspend\n");
- pm_runtime_mark_last_busy(dev->dev);
- pm_runtime_put_autosuspend(dev->dev);
+ pm_runtime_put_autosuspend(dev->parent);
return rets;
}
@@ -1140,9 +1116,9 @@ int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl,
goto nortpm;
}
- rets = pm_runtime_get(dev->dev);
+ rets = pm_runtime_get(dev->parent);
if (rets < 0 && rets != -EINPROGRESS) {
- pm_runtime_put_noidle(dev->dev);
+ pm_runtime_put_noidle(dev->parent);
cl_err(dev, cl, "rpm: get failed %d\n", rets);
goto nortpm;
}
@@ -1189,8 +1165,7 @@ int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl,
rets = cl->status;
out:
cl_dbg(dev, cl, "rpm: autosuspend\n");
- pm_runtime_mark_last_busy(dev->dev);
- pm_runtime_put_autosuspend(dev->dev);
+ pm_runtime_put_autosuspend(dev->parent);
mei_io_cb_free(cb);
@@ -1343,7 +1318,9 @@ static void mei_cl_reset_read_by_vtag(const struct mei_cl *cl, u8 vtag)
struct mei_cl_vtag *vtag_l;
list_for_each_entry(vtag_l, &cl->vtag_map, list) {
- if (vtag_l->vtag == vtag) {
+ /* The client on bus has one fixed vtag map */
+ if ((cl->cldev && mei_cldev_enabled(cl->cldev)) ||
+ vtag_l->vtag == vtag) {
vtag_l->pending_read = false;
break;
}
@@ -1537,9 +1514,9 @@ int mei_cl_notify_request(struct mei_cl *cl,
if (!mei_cl_is_connected(cl))
return -ENODEV;
- rets = pm_runtime_get(dev->dev);
+ rets = pm_runtime_get(dev->parent);
if (rets < 0 && rets != -EINPROGRESS) {
- pm_runtime_put_noidle(dev->dev);
+ pm_runtime_put_noidle(dev->parent);
cl_err(dev, cl, "rpm: get failed %d\n", rets);
return rets;
}
@@ -1574,8 +1551,7 @@ int mei_cl_notify_request(struct mei_cl *cl,
out:
cl_dbg(dev, cl, "rpm: autosuspend\n");
- pm_runtime_mark_last_busy(dev->dev);
- pm_runtime_put_autosuspend(dev->dev);
+ pm_runtime_put_autosuspend(dev->parent);
mei_io_cb_free(cb);
return rets;
@@ -1703,9 +1679,9 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length, const struct file *fp)
mei_cl_set_read_by_fp(cl, fp);
- rets = pm_runtime_get(dev->dev);
+ rets = pm_runtime_get(dev->parent);
if (rets < 0 && rets != -EINPROGRESS) {
- pm_runtime_put_noidle(dev->dev);
+ pm_runtime_put_noidle(dev->parent);
cl_err(dev, cl, "rpm: get failed %d\n", rets);
goto nortpm;
}
@@ -1722,8 +1698,7 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length, const struct file *fp)
out:
cl_dbg(dev, cl, "rpm: autosuspend\n");
- pm_runtime_mark_last_busy(dev->dev);
- pm_runtime_put_autosuspend(dev->dev);
+ pm_runtime_put_autosuspend(dev->parent);
nortpm:
if (rets)
mei_io_cb_free(cb);
@@ -1992,9 +1967,9 @@ ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, unsigned long time
blocking = cb->blocking;
data = buf->data;
- rets = pm_runtime_get(dev->dev);
+ rets = pm_runtime_get(dev->parent);
if (rets < 0 && rets != -EINPROGRESS) {
- pm_runtime_put_noidle(dev->dev);
+ pm_runtime_put_noidle(dev->parent);
cl_err(dev, cl, "rpm: get failed %zd\n", rets);
goto free;
}
@@ -2009,7 +1984,7 @@ ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, unsigned long time
mei_hdr = mei_msg_hdr_init(cb);
if (IS_ERR(mei_hdr)) {
- rets = -PTR_ERR(mei_hdr);
+ rets = PTR_ERR(mei_hdr);
mei_hdr = NULL;
goto err;
}
@@ -2030,7 +2005,7 @@ ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, unsigned long time
hbuf_slots = mei_hbuf_empty_slots(dev);
if (hbuf_slots < 0) {
- rets = -EOVERFLOW;
+ buf_len = -EOVERFLOW;
goto out;
}
@@ -2112,8 +2087,7 @@ out:
rets = buf_len;
err:
cl_dbg(dev, cl, "rpm: autosuspend\n");
- pm_runtime_mark_last_busy(dev->dev);
- pm_runtime_put_autosuspend(dev->dev);
+ pm_runtime_put_autosuspend(dev->parent);
free:
mei_io_cb_free(cb);
@@ -2136,12 +2110,10 @@ void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb)
case MEI_FOP_WRITE:
mei_tx_cb_dequeue(cb);
cl->writing_state = MEI_WRITE_COMPLETE;
- if (waitqueue_active(&cl->tx_wait)) {
+ if (waitqueue_active(&cl->tx_wait))
wake_up_interruptible(&cl->tx_wait);
- } else {
- pm_runtime_mark_last_busy(dev->dev);
- pm_request_autosuspend(dev->dev);
- }
+ else
+ pm_request_autosuspend(dev->parent);
break;
case MEI_FOP_READ:
@@ -2271,7 +2243,7 @@ int mei_cl_irq_dma_unmap(struct mei_cl *cl, struct mei_cl_cb *cb,
static int mei_cl_dma_alloc(struct mei_cl *cl, u8 buf_id, size_t size)
{
- cl->dma.vaddr = dmam_alloc_coherent(cl->dev->dev, size,
+ cl->dma.vaddr = dmam_alloc_coherent(&cl->dev->dev, size,
&cl->dma.daddr, GFP_KERNEL);
if (!cl->dma.vaddr)
return -ENOMEM;
@@ -2285,7 +2257,7 @@ static int mei_cl_dma_alloc(struct mei_cl *cl, u8 buf_id, size_t size)
static void mei_cl_dma_free(struct mei_cl *cl)
{
cl->dma.buffer_id = 0;
- dmam_free_coherent(cl->dev->dev,
+ dmam_free_coherent(&cl->dev->dev,
cl->dma.size, cl->dma.vaddr, cl->dma.daddr);
cl->dma.size = 0;
cl->dma.vaddr = NULL;
@@ -2341,16 +2313,16 @@ int mei_cl_dma_alloc_and_map(struct mei_cl *cl, const struct file *fp,
return -EPROTO;
}
- rets = pm_runtime_get(dev->dev);
+ rets = pm_runtime_get(dev->parent);
if (rets < 0 && rets != -EINPROGRESS) {
- pm_runtime_put_noidle(dev->dev);
+ pm_runtime_put_noidle(dev->parent);
cl_err(dev, cl, "rpm: get failed %d\n", rets);
return rets;
}
rets = mei_cl_dma_alloc(cl, buffer_id, size);
if (rets) {
- pm_runtime_put_noidle(dev->dev);
+ pm_runtime_put_noidle(dev->parent);
return rets;
}
@@ -2386,8 +2358,7 @@ out:
mei_cl_dma_free(cl);
cl_dbg(dev, cl, "rpm: autosuspend\n");
- pm_runtime_mark_last_busy(dev->dev);
- pm_runtime_put_autosuspend(dev->dev);
+ pm_runtime_put_autosuspend(dev->parent);
mei_io_cb_free(cb);
return rets;
@@ -2426,9 +2397,9 @@ int mei_cl_dma_unmap(struct mei_cl *cl, const struct file *fp)
if (!cl->dma_mapped)
return -EPROTO;
- rets = pm_runtime_get(dev->dev);
+ rets = pm_runtime_get(dev->parent);
if (rets < 0 && rets != -EINPROGRESS) {
- pm_runtime_put_noidle(dev->dev);
+ pm_runtime_put_noidle(dev->parent);
cl_err(dev, cl, "rpm: get failed %d\n", rets);
return rets;
}
@@ -2464,8 +2435,7 @@ int mei_cl_dma_unmap(struct mei_cl *cl, const struct file *fp)
mei_cl_dma_free(cl);
out:
cl_dbg(dev, cl, "rpm: autosuspend\n");
- pm_runtime_mark_last_busy(dev->dev);
- pm_runtime_put_autosuspend(dev->dev);
+ pm_runtime_put_autosuspend(dev->parent);
mei_io_cb_free(cb);
return rets;