aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/heci/heci_init.c4
-rw-r--r--drivers/staging/heci/heci_interface.c17
-rw-r--r--drivers/staging/heci/heci_interface.h1
-rw-r--r--drivers/staging/heci/interrupt.c6
4 files changed, 24 insertions, 4 deletions
diff --git a/drivers/staging/heci/heci_init.c b/drivers/staging/heci/heci_init.c
index 06ea1967e0e..427f55d7b26 100644
--- a/drivers/staging/heci/heci_init.c
+++ b/drivers/staging/heci/heci_init.c
@@ -249,7 +249,7 @@ int heci_hw_init(struct iamt_heci_device *dev)
if ((dev->host_hw_state & H_IS) == H_IS) {
/* acknowledge interrupt and stop interupts */
- heci_set_csr_register(dev);
+ heci_csr_clear_his(dev);
}
dev->recvd_msg = 0;
DBG("reset in start the heci device.\n");
@@ -354,7 +354,7 @@ void heci_reset(struct iamt_heci_device *dev, int interrupts)
dev->host_hw_state &= ~H_RST;
dev->host_hw_state |= H_IG;
- write_heci_register(dev, H_CSR, dev->host_hw_state);
+ heci_set_csr_register(dev);
DBG("currently saved host_hw_state = 0x%08x.\n",
dev->host_hw_state);
diff --git a/drivers/staging/heci/heci_interface.c b/drivers/staging/heci/heci_interface.c
index c5f51a7ddf2..03e1df1a88a 100644
--- a/drivers/staging/heci/heci_interface.c
+++ b/drivers/staging/heci/heci_interface.c
@@ -44,12 +44,15 @@
/**
- * heci_set_csr_register - write H_CSR register to the heci device
+ * heci_set_csr_register - write H_CSR register to the heci device,
+ * and ignore the H_IS bit for it is write-one-to-zero.
*
* @dev: device object for our driver
*/
void heci_set_csr_register(struct iamt_heci_device *dev)
{
+ if ((dev->host_hw_state & H_IS) == H_IS)
+ dev->host_hw_state &= ~H_IS;
write_heci_register(dev, H_CSR, dev->host_hw_state);
dev->host_hw_state = read_heci_register(dev, H_CSR);
}
@@ -76,6 +79,16 @@ void heci_csr_disable_interrupts(struct iamt_heci_device *dev)
heci_set_csr_register(dev);
}
+/**
+ * heci_csr_clear_his - clear H_IS bit in H_CSR
+ *
+ * @dev: device object for our driver
+ */
+void heci_csr_clear_his(struct iamt_heci_device *dev)
+{
+ write_heci_register(dev, H_CSR, dev->host_hw_state);
+ dev->host_hw_state = read_heci_register(dev, H_CSR);
+}
/**
* _host_get_filled_slots - get number of device filled buffer slots
@@ -185,7 +198,7 @@ int heci_write_message(struct iamt_heci_device *dev,
}
dev->host_hw_state |= H_IG;
- write_heci_register(dev, H_CSR, dev->host_hw_state);
+ heci_set_csr_register(dev);
dev->me_hw_state = read_heci_register(dev, ME_CSR_HA);
if ((dev->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA)
return 0;
diff --git a/drivers/staging/heci/heci_interface.h b/drivers/staging/heci/heci_interface.h
index d9193cf6d9e..34db7e52b8e 100644
--- a/drivers/staging/heci/heci_interface.h
+++ b/drivers/staging/heci/heci_interface.h
@@ -133,6 +133,7 @@ enum client_disconnect_status_types{
void heci_set_csr_register(struct iamt_heci_device *dev);
void heci_csr_enable_interrupts(struct iamt_heci_device *dev);
void heci_csr_disable_interrupts(struct iamt_heci_device *dev);
+void heci_csr_clear_his(struct iamt_heci_device *dev);
void heci_read_slots(struct iamt_heci_device *dev,
unsigned char *buffer, unsigned long buffer_length);
diff --git a/drivers/staging/heci/interrupt.c b/drivers/staging/heci/interrupt.c
index b7ce73be826..3a510ed3a3d 100644
--- a/drivers/staging/heci/interrupt.c
+++ b/drivers/staging/heci/interrupt.c
@@ -92,6 +92,9 @@ irqreturn_t heci_isr_interrupt(int irq, void *dev_id)
/* disable interrupts */
heci_csr_disable_interrupts(dev);
+ /* clear H_IS bit in H_CSR */
+ heci_csr_clear_his(dev);
+
/*
* Our device interrupted, schedule work the heci_bh_handler
* to handle the interrupt processing. This needs to be a
@@ -251,6 +254,9 @@ end:
/* acknowledge interrupt and disable interrupts */
heci_csr_disable_interrupts(dev);
+ /* clear H_IS bit in H_CSR */
+ heci_csr_clear_his(dev);
+
PREPARE_WORK(&dev->work, heci_bh_handler);
DBG("schedule work the heci_bh_handler.\n");
rets = schedule_work(&dev->work);