diff options
-rwxr-xr-x | drivers/mxc/mlb/mxc_mlb150.c | 53 | ||||
-rw-r--r-- | include/linux/mxc_mlb.h | 2 | ||||
-rw-r--r-- | include/uapi/linux/mxc_mlb.h | 2 |
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 | ||
1699 | static irqreturn_t mlb_ahb_isr(int irq, void *dev_id) | 1698 | static 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; |
2382 | out: | 2388 | out: |
@@ -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 |