summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xdrivers/mxc/mlb/mxc_mlb150.c53
-rw-r--r--include/linux/mxc_mlb.h2
-rw-r--r--include/uapi/linux/mxc_mlb.h2
3 files changed, 32 insertions, 25 deletions
diff --git a/drivers/mxc/mlb/mxc_mlb150.c b/drivers/mxc/mlb/mxc_mlb150.c
index 79aeeb50fb0d..f0701e52693d 100755
--- a/drivers/mxc/mlb/mxc_mlb150.c
+++ b/drivers/mxc/mlb/mxc_mlb150.c
@@ -1628,17 +1628,17 @@ static void mlb_rx_isr(s32 ctype, u32 ahb_ch, struct mlb_dev_info *pdevinfo)
{
struct mlb_ringbuf *rx_rbuf = &pdevinfo->rx_rbuf;
s32 head, tail, adt_sts;
- unsigned long flags;
u32 rx_buf_ptr;
#ifdef DEBUG_RX
pr_debug("mxc_mlb150: mlb_rx_isr\n");
#endif
- write_lock_irqsave(&rx_rbuf->rb_lock, flags);
+ read_lock(&rx_rbuf->rb_lock);
head = (rx_rbuf->head + 1) & (TRANS_RING_NODES - 1);
tail = ACCESS_ONCE(rx_rbuf->tail);
+ read_unlock(&rx_rbuf->rb_lock);
if (CIRC_SPACE(head, tail, TRANS_RING_NODES) >= 1) {
rx_buf_ptr = rx_rbuf->phy_addrs[head];
@@ -1646,15 +1646,14 @@ static void mlb_rx_isr(s32 ctype, u32 ahb_ch, struct mlb_dev_info *pdevinfo)
/* commit the item before incrementing the head */
smp_wmb();
+ write_lock(&rx_rbuf->rb_lock);
rx_rbuf->head = head;
-
- write_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
+ write_unlock(&rx_rbuf->rb_lock);
/* wake up the reader */
wake_up_interruptible(&pdevinfo->rx_wq);
} else {
rx_buf_ptr = rx_rbuf->phy_addrs[head];
- write_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
pr_debug("drop RX package, due to no space, (%d,%d)\n",
head, tail);
}
@@ -1669,14 +1668,17 @@ static void mlb_tx_isr(s32 ctype, u32 ahb_ch, struct mlb_dev_info *pdevinfo)
struct mlb_ringbuf *tx_rbuf = &pdevinfo->tx_rbuf;
s32 head, tail, adt_sts;
u32 tx_buf_ptr;
- unsigned long flags;
- write_lock_irqsave(&tx_rbuf->rb_lock, flags);
+ read_lock(&tx_rbuf->rb_lock);
head = ACCESS_ONCE(tx_rbuf->head);
tail = (tx_rbuf->tail + 1) & (TRANS_RING_NODES - 1);
+ read_unlock(&tx_rbuf->rb_lock);
+
smp_mb();
+ write_lock(&tx_rbuf->rb_lock);
tx_rbuf->tail = tail;
+ write_unlock(&tx_rbuf->rb_lock);
/* check the current tx buffer is available or not */
if (CIRC_CNT(head, tail, TRANS_RING_NODES) >= 1) {
@@ -1685,15 +1687,12 @@ static void mlb_tx_isr(s32 ctype, u32 ahb_ch, struct mlb_dev_info *pdevinfo)
tx_buf_ptr = tx_rbuf->phy_addrs[tail];
- write_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
-
wake_up_interruptible(&pdevinfo->tx_wq);
adt_sts = mlb150_dev_get_adt_sts(ahb_ch);
/* Set ADT for TX */
mlb150_dev_pipo_next(ahb_ch, ctype, adt_sts, tx_buf_ptr);
- } else
- write_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
+ }
}
static irqreturn_t mlb_ahb_isr(int irq, void *dev_id)
@@ -2186,6 +2185,18 @@ static long mxc_mlb150_ioctl(struct file *filp,
break;
}
+
+ case MLB_IRQ_DISABLE:
+ {
+ disable_irq(drvdata->irq_mlb);
+ break;
+ }
+
+ case MLB_IRQ_ENABLE:
+ {
+ enable_irq(drvdata->irq_mlb);
+ break;
+ }
default:
pr_info("mxc_mlb150: Invalid ioctl command\n");
return -EINVAL;
@@ -2214,9 +2225,10 @@ static ssize_t mxc_mlb150_read(struct file *filp, char __user *buf,
head = ACCESS_ONCE(rx_rbuf->head);
tail = rx_rbuf->tail;
+ read_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
+
/* check the current rx buffer is available or not */
if (0 == CIRC_CNT(head, tail, TRANS_RING_NODES)) {
- read_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
@@ -2246,9 +2258,7 @@ static ssize_t mxc_mlb150_read(struct file *filp, char __user *buf,
}
finish_wait(&pdevinfo->rx_wq, &__wait);
} while (0);
- read_lock_irqsave(&rx_rbuf->rb_lock, flags);
}
- read_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
/* read index before reading contents at that index */
smp_read_barrier_depends();
@@ -2313,9 +2323,9 @@ static ssize_t mxc_mlb150_write(struct file *filp, const char __user *buf,
head = tx_rbuf->head;
tail = ACCESS_ONCE(tx_rbuf->tail);
+ read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
if (0 == CIRC_SPACE(head, tail, TRANS_RING_NODES)) {
- read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
do {
@@ -2352,13 +2362,11 @@ static ssize_t mxc_mlb150_write(struct file *filp, const char __user *buf,
goto out;
}
- read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
write_lock_irqsave(&tx_rbuf->rb_lock, flags);
smp_wmb();
tx_rbuf->head = (head + 1) & (TRANS_RING_NODES - 1);
write_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
- read_lock_irqsave(&tx_rbuf->rb_lock, flags);
if (0 == CIRC_CNT(head, tail, TRANS_RING_NODES)) {
u32 tx_buf_ptr, ahb_ch;
s32 adt_sts;
@@ -2368,15 +2376,13 @@ static ssize_t mxc_mlb150_write(struct file *filp, const char __user *buf,
smp_read_barrier_depends();
tx_buf_ptr = tx_rbuf->phy_addrs[tail];
- read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
ahb_ch = pdevinfo->channels[TX_CHANNEL].cl;
adt_sts = mlb150_dev_get_adt_sts(ahb_ch);
/* Set ADT for TX */
mlb150_dev_pipo_next(ahb_ch, ctype, adt_sts, tx_buf_ptr);
- } else
- read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
+ }
ret = count;
out:
@@ -2402,26 +2408,23 @@ static unsigned int mxc_mlb150_poll(struct file *filp,
poll_wait(filp, &pdevinfo->tx_wq, wait);
read_lock_irqsave(&tx_rbuf->rb_lock, flags);
-
head = tx_rbuf->head;
tail = tx_rbuf->tail;
+ read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
/* check the tx buffer is avaiable or not */
if (CIRC_SPACE(head, tail, TRANS_RING_NODES) >= 1)
ret |= POLLOUT | POLLWRNORM;
- read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
-
read_lock_irqsave(&rx_rbuf->rb_lock, flags);
-
head = rx_rbuf->head;
tail = rx_rbuf->tail;
+ read_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
/* check the rx buffer filled or not */
if (CIRC_CNT(head, tail, TRANS_RING_NODES) >= 1)
ret |= POLLIN | POLLRDNORM;
- read_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
/* check the exception event */
if (pdevinfo->ex_event)
diff --git a/include/linux/mxc_mlb.h b/include/linux/mxc_mlb.h
index 147f64329972..d7c792a2bee4 100644
--- a/include/linux/mxc_mlb.h
+++ b/include/linux/mxc_mlb.h
@@ -34,6 +34,8 @@
#define MLB_SET_ISOC_BLKSIZE_188 _IO('S', 0x17)
#define MLB_SET_ISOC_BLKSIZE_196 _IO('S', 0x18)
#define MLB_SET_SYNC_QUAD _IOW('S', 0x19, unsigned int)
+#define MLB_IRQ_ENABLE _IO('S', 0x20)
+#define MLB_IRQ_DISABLE _IO('S', 0x21)
/*!
* MLB event define
diff --git a/include/uapi/linux/mxc_mlb.h b/include/uapi/linux/mxc_mlb.h
index 90c94daf8e9c..20ba5240ea51 100644
--- a/include/uapi/linux/mxc_mlb.h
+++ b/include/uapi/linux/mxc_mlb.h
@@ -34,6 +34,8 @@
#define MLB_SET_ISOC_BLKSIZE_188 _IO('S', 0x17)
#define MLB_SET_ISOC_BLKSIZE_196 _IO('S', 0x18)
#define MLB_SET_SYNC_QUAD _IOW('S', 0x19, unsigned int)
+#define MLB_IRQ_ENABLE _IO('S', 0x20)
+#define MLB_IRQ_DISABLE _IO('S', 0x21)
/*!
* MLB event define