aboutsummaryrefslogtreecommitdiffstats
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)
1628{ 1628{
1629 struct mlb_ringbuf *rx_rbuf = &pdevinfo->rx_rbuf; 1629 struct mlb_ringbuf *rx_rbuf = &pdevinfo->rx_rbuf;
1630 s32 head, tail, adt_sts; 1630 s32 head, tail, adt_sts;
1631 unsigned long flags;
1632 u32 rx_buf_ptr; 1631 u32 rx_buf_ptr;
1633 1632
1634#ifdef DEBUG_RX 1633#ifdef DEBUG_RX
1635 pr_debug("mxc_mlb150: mlb_rx_isr\n"); 1634 pr_debug("mxc_mlb150: mlb_rx_isr\n");
1636#endif 1635#endif
1637 1636
1638 write_lock_irqsave(&rx_rbuf->rb_lock, flags); 1637 read_lock(&rx_rbuf->rb_lock);
1639 1638
1640 head = (rx_rbuf->head + 1) & (TRANS_RING_NODES - 1); 1639 head = (rx_rbuf->head + 1) & (TRANS_RING_NODES - 1);
1641 tail = ACCESS_ONCE(rx_rbuf->tail); 1640 tail = ACCESS_ONCE(rx_rbuf->tail);
1641 read_unlock(&rx_rbuf->rb_lock);
1642 1642
1643 if (CIRC_SPACE(head, tail, TRANS_RING_NODES) >= 1) { 1643 if (CIRC_SPACE(head, tail, TRANS_RING_NODES) >= 1) {
1644 rx_buf_ptr = rx_rbuf->phy_addrs[head]; 1644 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)
1646 /* commit the item before incrementing the head */ 1646 /* commit the item before incrementing the head */
1647 smp_wmb(); 1647 smp_wmb();
1648 1648
1649 write_lock(&rx_rbuf->rb_lock);
1649 rx_rbuf->head = head; 1650 rx_rbuf->head = head;
1650 1651 write_unlock(&rx_rbuf->rb_lock);
1651 write_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
1652 1652
1653 /* wake up the reader */ 1653 /* wake up the reader */
1654 wake_up_interruptible(&pdevinfo->rx_wq); 1654 wake_up_interruptible(&pdevinfo->rx_wq);
1655 } else { 1655 } else {
1656 rx_buf_ptr = rx_rbuf->phy_addrs[head]; 1656 rx_buf_ptr = rx_rbuf->phy_addrs[head];
1657 write_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
1658 pr_debug("drop RX package, due to no space, (%d,%d)\n", 1657 pr_debug("drop RX package, due to no space, (%d,%d)\n",
1659 head, tail); 1658 head, tail);
1660 } 1659 }
@@ -1669,14 +1668,17 @@ static void mlb_tx_isr(s32 ctype, u32 ahb_ch, struct mlb_dev_info *pdevinfo)
1669 struct mlb_ringbuf *tx_rbuf = &pdevinfo->tx_rbuf; 1668 struct mlb_ringbuf *tx_rbuf = &pdevinfo->tx_rbuf;
1670 s32 head, tail, adt_sts; 1669 s32 head, tail, adt_sts;
1671 u32 tx_buf_ptr; 1670 u32 tx_buf_ptr;
1672 unsigned long flags;
1673 1671
1674 write_lock_irqsave(&tx_rbuf->rb_lock, flags); 1672 read_lock(&tx_rbuf->rb_lock);
1675 1673
1676 head = ACCESS_ONCE(tx_rbuf->head); 1674 head = ACCESS_ONCE(tx_rbuf->head);
1677 tail = (tx_rbuf->tail + 1) & (TRANS_RING_NODES - 1); 1675 tail = (tx_rbuf->tail + 1) & (TRANS_RING_NODES - 1);
1676 read_unlock(&tx_rbuf->rb_lock);
1677
1678 smp_mb(); 1678 smp_mb();
1679 write_lock(&tx_rbuf->rb_lock);
1679 tx_rbuf->tail = tail; 1680 tx_rbuf->tail = tail;
1681 write_unlock(&tx_rbuf->rb_lock);
1680 1682
1681 /* check the current tx buffer is available or not */ 1683 /* check the current tx buffer is available or not */
1682 if (CIRC_CNT(head, tail, TRANS_RING_NODES) >= 1) { 1684 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)
1685 1687
1686 tx_buf_ptr = tx_rbuf->phy_addrs[tail]; 1688 tx_buf_ptr = tx_rbuf->phy_addrs[tail];
1687 1689
1688 write_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
1689
1690 wake_up_interruptible(&pdevinfo->tx_wq); 1690 wake_up_interruptible(&pdevinfo->tx_wq);
1691 1691
1692 adt_sts = mlb150_dev_get_adt_sts(ahb_ch); 1692 adt_sts = mlb150_dev_get_adt_sts(ahb_ch);
1693 /* Set ADT for TX */ 1693 /* Set ADT for TX */
1694 mlb150_dev_pipo_next(ahb_ch, ctype, adt_sts, tx_buf_ptr); 1694 mlb150_dev_pipo_next(ahb_ch, ctype, adt_sts, tx_buf_ptr);
1695 } else 1695 }
1696 write_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
1697} 1696}
1698 1697
1699static irqreturn_t mlb_ahb_isr(int irq, void *dev_id) 1698static irqreturn_t mlb_ahb_isr(int irq, void *dev_id)
@@ -2186,6 +2185,18 @@ static long mxc_mlb150_ioctl(struct file *filp,
2186 2185
2187 break; 2186 break;
2188 } 2187 }
2188
2189 case MLB_IRQ_DISABLE:
2190 {
2191 disable_irq(drvdata->irq_mlb);
2192 break;
2193 }
2194
2195 case MLB_IRQ_ENABLE:
2196 {
2197 enable_irq(drvdata->irq_mlb);
2198 break;
2199 }
2189 default: 2200 default:
2190 pr_info("mxc_mlb150: Invalid ioctl command\n"); 2201 pr_info("mxc_mlb150: Invalid ioctl command\n");
2191 return -EINVAL; 2202 return -EINVAL;
@@ -2214,9 +2225,10 @@ static ssize_t mxc_mlb150_read(struct file *filp, char __user *buf,
2214 head = ACCESS_ONCE(rx_rbuf->head); 2225 head = ACCESS_ONCE(rx_rbuf->head);
2215 tail = rx_rbuf->tail; 2226 tail = rx_rbuf->tail;
2216 2227
2228 read_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
2229
2217 /* check the current rx buffer is available or not */ 2230 /* check the current rx buffer is available or not */
2218 if (0 == CIRC_CNT(head, tail, TRANS_RING_NODES)) { 2231 if (0 == CIRC_CNT(head, tail, TRANS_RING_NODES)) {
2219 read_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
2220 2232
2221 if (filp->f_flags & O_NONBLOCK) 2233 if (filp->f_flags & O_NONBLOCK)
2222 return -EAGAIN; 2234 return -EAGAIN;
@@ -2246,9 +2258,7 @@ static ssize_t mxc_mlb150_read(struct file *filp, char __user *buf,
2246 } 2258 }
2247 finish_wait(&pdevinfo->rx_wq, &__wait); 2259 finish_wait(&pdevinfo->rx_wq, &__wait);
2248 } while (0); 2260 } while (0);
2249 read_lock_irqsave(&rx_rbuf->rb_lock, flags);
2250 } 2261 }
2251 read_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
2252 2262
2253 /* read index before reading contents at that index */ 2263 /* read index before reading contents at that index */
2254 smp_read_barrier_depends(); 2264 smp_read_barrier_depends();
@@ -2313,9 +2323,9 @@ static ssize_t mxc_mlb150_write(struct file *filp, const char __user *buf,
2313 2323
2314 head = tx_rbuf->head; 2324 head = tx_rbuf->head;
2315 tail = ACCESS_ONCE(tx_rbuf->tail); 2325 tail = ACCESS_ONCE(tx_rbuf->tail);
2326 read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
2316 2327
2317 if (0 == CIRC_SPACE(head, tail, TRANS_RING_NODES)) { 2328 if (0 == CIRC_SPACE(head, tail, TRANS_RING_NODES)) {
2318 read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
2319 if (filp->f_flags & O_NONBLOCK) 2329 if (filp->f_flags & O_NONBLOCK)
2320 return -EAGAIN; 2330 return -EAGAIN;
2321 do { 2331 do {
@@ -2352,13 +2362,11 @@ static ssize_t mxc_mlb150_write(struct file *filp, const char __user *buf,
2352 goto out; 2362 goto out;
2353 } 2363 }
2354 2364
2355 read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
2356 write_lock_irqsave(&tx_rbuf->rb_lock, flags); 2365 write_lock_irqsave(&tx_rbuf->rb_lock, flags);
2357 smp_wmb(); 2366 smp_wmb();
2358 tx_rbuf->head = (head + 1) & (TRANS_RING_NODES - 1); 2367 tx_rbuf->head = (head + 1) & (TRANS_RING_NODES - 1);
2359 write_unlock_irqrestore(&tx_rbuf->rb_lock, flags); 2368 write_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
2360 2369
2361 read_lock_irqsave(&tx_rbuf->rb_lock, flags);
2362 if (0 == CIRC_CNT(head, tail, TRANS_RING_NODES)) { 2370 if (0 == CIRC_CNT(head, tail, TRANS_RING_NODES)) {
2363 u32 tx_buf_ptr, ahb_ch; 2371 u32 tx_buf_ptr, ahb_ch;
2364 s32 adt_sts; 2372 s32 adt_sts;
@@ -2368,15 +2376,13 @@ static ssize_t mxc_mlb150_write(struct file *filp, const char __user *buf,
2368 smp_read_barrier_depends(); 2376 smp_read_barrier_depends();
2369 2377
2370 tx_buf_ptr = tx_rbuf->phy_addrs[tail]; 2378 tx_buf_ptr = tx_rbuf->phy_addrs[tail];
2371 read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
2372 2379
2373 ahb_ch = pdevinfo->channels[TX_CHANNEL].cl; 2380 ahb_ch = pdevinfo->channels[TX_CHANNEL].cl;
2374 adt_sts = mlb150_dev_get_adt_sts(ahb_ch); 2381 adt_sts = mlb150_dev_get_adt_sts(ahb_ch);
2375 2382
2376 /* Set ADT for TX */ 2383 /* Set ADT for TX */
2377 mlb150_dev_pipo_next(ahb_ch, ctype, adt_sts, tx_buf_ptr); 2384 mlb150_dev_pipo_next(ahb_ch, ctype, adt_sts, tx_buf_ptr);
2378 } else 2385 }
2379 read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
2380 2386
2381 ret = count; 2387 ret = count;
2382out: 2388out:
@@ -2402,26 +2408,23 @@ static unsigned int mxc_mlb150_poll(struct file *filp,
2402 poll_wait(filp, &pdevinfo->tx_wq, wait); 2408 poll_wait(filp, &pdevinfo->tx_wq, wait);
2403 2409
2404 read_lock_irqsave(&tx_rbuf->rb_lock, flags); 2410 read_lock_irqsave(&tx_rbuf->rb_lock, flags);
2405
2406 head = tx_rbuf->head; 2411 head = tx_rbuf->head;
2407 tail = tx_rbuf->tail; 2412 tail = tx_rbuf->tail;
2413 read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
2408 2414
2409 /* check the tx buffer is avaiable or not */ 2415 /* check the tx buffer is avaiable or not */
2410 if (CIRC_SPACE(head, tail, TRANS_RING_NODES) >= 1) 2416 if (CIRC_SPACE(head, tail, TRANS_RING_NODES) >= 1)
2411 ret |= POLLOUT | POLLWRNORM; 2417 ret |= POLLOUT | POLLWRNORM;
2412 2418
2413 read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
2414
2415 read_lock_irqsave(&rx_rbuf->rb_lock, flags); 2419 read_lock_irqsave(&rx_rbuf->rb_lock, flags);
2416
2417 head = rx_rbuf->head; 2420 head = rx_rbuf->head;
2418 tail = rx_rbuf->tail; 2421 tail = rx_rbuf->tail;
2422 read_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
2419 2423
2420 /* check the rx buffer filled or not */ 2424 /* check the rx buffer filled or not */
2421 if (CIRC_CNT(head, tail, TRANS_RING_NODES) >= 1) 2425 if (CIRC_CNT(head, tail, TRANS_RING_NODES) >= 1)
2422 ret |= POLLIN | POLLRDNORM; 2426 ret |= POLLIN | POLLRDNORM;
2423 2427
2424 read_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
2425 2428
2426 /* check the exception event */ 2429 /* check the exception event */
2427 if (pdevinfo->ex_event) 2430 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 @@
34#define MLB_SET_ISOC_BLKSIZE_188 _IO('S', 0x17) 34#define MLB_SET_ISOC_BLKSIZE_188 _IO('S', 0x17)
35#define MLB_SET_ISOC_BLKSIZE_196 _IO('S', 0x18) 35#define MLB_SET_ISOC_BLKSIZE_196 _IO('S', 0x18)
36#define MLB_SET_SYNC_QUAD _IOW('S', 0x19, unsigned int) 36#define MLB_SET_SYNC_QUAD _IOW('S', 0x19, unsigned int)
37#define MLB_IRQ_ENABLE _IO('S', 0x20)
38#define MLB_IRQ_DISABLE _IO('S', 0x21)
37 39
38/*! 40/*!
39 * MLB event define 41 * 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 @@
34#define MLB_SET_ISOC_BLKSIZE_188 _IO('S', 0x17) 34#define MLB_SET_ISOC_BLKSIZE_188 _IO('S', 0x17)
35#define MLB_SET_ISOC_BLKSIZE_196 _IO('S', 0x18) 35#define MLB_SET_ISOC_BLKSIZE_196 _IO('S', 0x18)
36#define MLB_SET_SYNC_QUAD _IOW('S', 0x19, unsigned int) 36#define MLB_SET_SYNC_QUAD _IOW('S', 0x19, unsigned int)
37#define MLB_IRQ_ENABLE _IO('S', 0x20)
38#define MLB_IRQ_DISABLE _IO('S', 0x21)
37 39
38/*! 40/*!
39 * MLB event define 41 * MLB event define