aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/misc/mei/hw-txe.c
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2014-02-19 17:35:48 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-02-28 15:15:57 -0800
commit9d098192c3d45ab6dd90ae87d649950a9ef70ccb (patch)
treea0f48fbc9a60e411cd499a22ac013f85fbb0aeeb /drivers/misc/mei/hw-txe.c
parentmei: add mei_hbuf_acquire wrapper (diff)
downloadwireguard-linux-9d098192c3d45ab6dd90ae87d649950a9ef70ccb.tar.xz
wireguard-linux-9d098192c3d45ab6dd90ae87d649950a9ef70ccb.zip
mei: revamp writing slot counting
Since txe use doorbell and not circular buffer we have to cheat in write slot counting, txe always consume all the slots upon write. In order for it to work we need to track slots using mei_hbuf_empty_slots() instead of tracking it in mei layer Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei/hw-txe.c')
-rw-r--r--drivers/misc/mei/hw-txe.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c
index 8f5e4be9ebc2..f60182a52f96 100644
--- a/drivers/misc/mei/hw-txe.c
+++ b/drivers/misc/mei/hw-txe.c
@@ -566,7 +566,9 @@ static int mei_txe_write(struct mei_device *dev,
struct mei_txe_hw *hw = to_txe_hw(dev);
unsigned long rem;
unsigned long length;
+ int slots = dev->hbuf_depth;
u32 *reg_buf = (u32 *)buf;
+ u32 dw_cnt;
int i;
if (WARN_ON(!header || !buf))
@@ -576,11 +578,9 @@ static int mei_txe_write(struct mei_device *dev,
dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(header));
- if ((length + sizeof(struct mei_msg_hdr)) > PAYLOAD_SIZE) {
- dev_err(&dev->pdev->dev, "write length exceeded = %ld > %d\n",
- length + sizeof(struct mei_msg_hdr), PAYLOAD_SIZE);
- return -ERANGE;
- }
+ dw_cnt = mei_data2slots(length);
+ if (dw_cnt > slots)
+ return -EMSGSIZE;
if (WARN(!hw->aliveness, "txe write: aliveness not asserted\n"))
return -EAGAIN;
@@ -605,6 +605,9 @@ static int mei_txe_write(struct mei_device *dev,
mei_txe_input_payload_write(dev, i + 1, reg);
}
+ /* after each write the whole buffer is consumed */
+ hw->slots = 0;
+
/* Set Input-Doorbell */
mei_txe_input_doorbell_set(hw);
@@ -632,7 +635,8 @@ static size_t mei_txe_hbuf_max_len(const struct mei_device *dev)
*/
static int mei_txe_hbuf_empty_slots(struct mei_device *dev)
{
- return dev->hbuf_depth;
+ struct mei_txe_hw *hw = to_txe_hw(dev);
+ return hw->slots;
}
/**
@@ -978,11 +982,12 @@ irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id)
}
}
/* Input Ready: Detection if host can write to SeC */
- if (test_and_clear_bit(TXE_INTR_IN_READY_BIT, &hw->intr_cause))
+ if (test_and_clear_bit(TXE_INTR_IN_READY_BIT, &hw->intr_cause)) {
dev->hbuf_is_ready = true;
+ hw->slots = dev->hbuf_depth;
+ }
if (hw->aliveness && dev->hbuf_is_ready) {
-
/* get the real register value */
dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
rets = mei_irq_write_handler(dev, &complete_list);