Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'fixes' of http://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-2.6-arm

* 'fixes' of http://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-2.6-arm:
ARM: 7237/1: PL330: Fix driver freeze
ARM: 7197/1: errata: Remove SMP dependency for erratum 751472
ARM: 7196/1: errata: Remove SMP dependency for erratum 720789
ARM: 7220/1: mmc: mmci: Fixup error handling for dma
ARM: 7214/1: mmc: mmci: Fixup handling of MCI_STARTBITERR

+65 -75
+2 -2
arch/arm/Kconfig
··· 1246 1246 1247 1247 config ARM_ERRATA_720789 1248 1248 bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID" 1249 - depends on CPU_V7 && SMP 1249 + depends on CPU_V7 1250 1250 help 1251 1251 This option enables the workaround for the 720789 Cortex-A9 (prior to 1252 1252 r2p0) erratum. A faulty ASID can be sent to the other CPUs for the ··· 1282 1282 1283 1283 config ARM_ERRATA_751472 1284 1284 bool "ARM errata: Interrupted ICIALLUIS may prevent completion of broadcasted operation" 1285 - depends on CPU_V7 && SMP 1285 + depends on CPU_V7 1286 1286 help 1287 1287 This option enables the workaround for the 751472 Cortex-A9 (prior 1288 1288 to r3p0) erratum. An interrupted ICIALLUIS operation may prevent the
+49 -67
arch/arm/common/pl330.c
··· 221 221 */ 222 222 #define MCODE_BUFF_PER_REQ 256 223 223 224 - /* 225 - * Mark a _pl330_req as free. 226 - * We do it by writing DMAEND as the first instruction 227 - * because no valid request is going to have DMAEND as 228 - * its first instruction to execute. 229 - */ 230 - #define MARK_FREE(req) do { \ 231 - _emit_END(0, (req)->mc_cpu); \ 232 - (req)->mc_len = 0; \ 233 - } while (0) 234 - 235 224 /* If the _pl330_req is available to the client */ 236 225 #define IS_FREE(req) (*((u8 *)((req)->mc_cpu)) == CMD_DMAEND) 237 226 ··· 290 301 struct pl330_dmac *dmac; 291 302 /* Only two at a time */ 292 303 struct _pl330_req req[2]; 293 - /* Index of the last submitted request */ 304 + /* Index of the last enqueued request */ 294 305 unsigned lstenq; 306 + /* Index of the last submitted request or -1 if the DMA is stopped */ 307 + int req_running; 295 308 }; 296 309 297 310 enum pl330_dmac_state { ··· 769 778 writel(0, regs + DBGCMD); 770 779 } 771 780 781 + /* 782 + * Mark a _pl330_req as free. 783 + * We do it by writing DMAEND as the first instruction 784 + * because no valid request is going to have DMAEND as 785 + * its first instruction to execute. 786 + */ 787 + static void mark_free(struct pl330_thread *thrd, int idx) 788 + { 789 + struct _pl330_req *req = &thrd->req[idx]; 790 + 791 + _emit_END(0, req->mc_cpu); 792 + req->mc_len = 0; 793 + 794 + thrd->req_running = -1; 795 + } 796 + 772 797 static inline u32 _state(struct pl330_thread *thrd) 773 798 { 774 799 void __iomem *regs = thrd->dmac->pinfo->base; ··· 843 836 } 844 837 } 845 838 846 - /* If the request 'req' of thread 'thrd' is currently active */ 847 - static inline bool _req_active(struct pl330_thread *thrd, 848 - struct _pl330_req *req) 849 - { 850 - void __iomem *regs = thrd->dmac->pinfo->base; 851 - u32 buf = req->mc_bus, pc = readl(regs + CPC(thrd->id)); 852 - 853 - if (IS_FREE(req)) 854 - return false; 855 - 856 - return (pc >= buf && pc <= buf + req->mc_len) ? true : false; 857 - } 858 - 859 - /* Returns 0 if the thread is inactive, ID of active req + 1 otherwise */ 860 - static inline unsigned _thrd_active(struct pl330_thread *thrd) 861 - { 862 - if (_req_active(thrd, &thrd->req[0])) 863 - return 1; /* First req active */ 864 - 865 - if (_req_active(thrd, &thrd->req[1])) 866 - return 2; /* Second req active */ 867 - 868 - return 0; 869 - } 870 - 871 839 static void _stop(struct pl330_thread *thrd) 872 840 { 873 841 void __iomem *regs = thrd->dmac->pinfo->base; ··· 874 892 struct _arg_GO go; 875 893 unsigned ns; 876 894 u8 insn[6] = {0, 0, 0, 0, 0, 0}; 895 + int idx; 877 896 878 897 /* Return if already ACTIVE */ 879 898 if (_state(thrd) != PL330_STATE_STOPPED) 880 899 return true; 881 900 882 - if (!IS_FREE(&thrd->req[1 - thrd->lstenq])) 883 - req = &thrd->req[1 - thrd->lstenq]; 884 - else if (!IS_FREE(&thrd->req[thrd->lstenq])) 885 - req = &thrd->req[thrd->lstenq]; 886 - else 887 - req = NULL; 901 + idx = 1 - thrd->lstenq; 902 + if (!IS_FREE(&thrd->req[idx])) 903 + req = &thrd->req[idx]; 904 + else { 905 + idx = thrd->lstenq; 906 + if (!IS_FREE(&thrd->req[idx])) 907 + req = &thrd->req[idx]; 908 + else 909 + req = NULL; 910 + } 888 911 889 912 /* Return if no request */ 890 913 if (!req || !req->r) ··· 919 932 920 933 /* Only manager can execute GO */ 921 934 _execute_DBGINSN(thrd, insn, true); 935 + 936 + thrd->req_running = idx; 922 937 923 938 return true; 924 939 } ··· 1371 1382 1372 1383 thrd->req[0].r = NULL; 1373 1384 thrd->req[1].r = NULL; 1374 - MARK_FREE(&thrd->req[0]); 1375 - MARK_FREE(&thrd->req[1]); 1385 + mark_free(thrd, 0); 1386 + mark_free(thrd, 1); 1376 1387 1377 1388 /* Clear the reset flag */ 1378 1389 pl330->dmac_tbd.reset_chan &= ~(1 << i); ··· 1450 1461 1451 1462 thrd = &pl330->channels[id]; 1452 1463 1453 - active = _thrd_active(thrd); 1454 - if (!active) /* Aborted */ 1464 + active = thrd->req_running; 1465 + if (active == -1) /* Aborted */ 1455 1466 continue; 1456 1467 1457 - active -= 1; 1458 - 1459 1468 rqdone = &thrd->req[active]; 1460 - MARK_FREE(rqdone); 1469 + mark_free(thrd, active); 1461 1470 1462 1471 /* Get going again ASAP */ 1463 1472 _start(thrd); ··· 1496 1509 struct pl330_thread *thrd = ch_id; 1497 1510 struct pl330_dmac *pl330; 1498 1511 unsigned long flags; 1499 - int ret = 0, active; 1512 + int ret = 0, active = thrd->req_running; 1500 1513 1501 1514 if (!thrd || thrd->free || thrd->dmac->state == DYING) 1502 1515 return -EINVAL; ··· 1512 1525 1513 1526 thrd->req[0].r = NULL; 1514 1527 thrd->req[1].r = NULL; 1515 - MARK_FREE(&thrd->req[0]); 1516 - MARK_FREE(&thrd->req[1]); 1528 + mark_free(thrd, 0); 1529 + mark_free(thrd, 1); 1517 1530 break; 1518 1531 1519 1532 case PL330_OP_ABORT: 1520 - active = _thrd_active(thrd); 1521 - 1522 1533 /* Make sure the channel is stopped */ 1523 1534 _stop(thrd); 1524 1535 1525 1536 /* ABORT is only for the active req */ 1526 - if (!active) 1537 + if (active == -1) 1527 1538 break; 1528 1539 1529 - active--; 1530 - 1531 1540 thrd->req[active].r = NULL; 1532 - MARK_FREE(&thrd->req[active]); 1541 + mark_free(thrd, active); 1533 1542 1534 1543 /* Start the next */ 1535 1544 case PL330_OP_START: 1536 - if (!_thrd_active(thrd) && !_start(thrd)) 1545 + if ((active == -1) && !_start(thrd)) 1537 1546 ret = -EIO; 1538 1547 break; 1539 1548 ··· 1570 1587 else 1571 1588 pstatus->faulting = false; 1572 1589 1573 - active = _thrd_active(thrd); 1590 + active = thrd->req_running; 1574 1591 1575 - if (!active) { 1592 + if (active == -1) { 1576 1593 /* Indicate that the thread is not running */ 1577 1594 pstatus->top_req = NULL; 1578 1595 pstatus->wait_req = NULL; 1579 1596 } else { 1580 - active--; 1581 1597 pstatus->top_req = thrd->req[active].r; 1582 1598 pstatus->wait_req = !IS_FREE(&thrd->req[1 - active]) 1583 1599 ? thrd->req[1 - active].r : NULL; ··· 1641 1659 thrd->free = false; 1642 1660 thrd->lstenq = 1; 1643 1661 thrd->req[0].r = NULL; 1644 - MARK_FREE(&thrd->req[0]); 1662 + mark_free(thrd, 0); 1645 1663 thrd->req[1].r = NULL; 1646 - MARK_FREE(&thrd->req[1]); 1664 + mark_free(thrd, 1); 1647 1665 break; 1648 1666 } 1649 1667 } ··· 1749 1767 thrd->req[0].mc_bus = pl330->mcode_bus 1750 1768 + (thrd->id * pi->mcbufsz); 1751 1769 thrd->req[0].r = NULL; 1752 - MARK_FREE(&thrd->req[0]); 1770 + mark_free(thrd, 0); 1753 1771 1754 1772 thrd->req[1].mc_cpu = thrd->req[0].mc_cpu 1755 1773 + pi->mcbufsz / 2; 1756 1774 thrd->req[1].mc_bus = thrd->req[0].mc_bus 1757 1775 + pi->mcbufsz / 2; 1758 1776 thrd->req[1].r = NULL; 1759 - MARK_FREE(&thrd->req[1]); 1777 + mark_free(thrd, 1); 1760 1778 } 1761 1779 1762 1780 static int dmac_alloc_threads(struct pl330_dmac *pl330)
+4 -2
arch/arm/mm/proc-v7.S
··· 363 363 orreq r10, r10, #1 << 6 @ set bit #6 364 364 mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register 365 365 #endif 366 - #ifdef CONFIG_ARM_ERRATA_751472 367 - cmp r6, #0x30 @ present prior to r3p0 366 + #if defined(CONFIG_ARM_ERRATA_751472) && defined(CONFIG_SMP) 367 + ALT_SMP(cmp r6, #0x30) @ present prior to r3p0 368 + ALT_UP_B(1f) 368 369 mrclt p15, 0, r10, c15, c0, 1 @ read diagnostic register 369 370 orrlt r10, r10, #1 << 11 @ set bit #11 370 371 mcrlt p15, 0, r10, c15, c0, 1 @ write diagnostic register 372 + 1: 371 373 #endif 372 374 373 375 3: mov r10, #0
+10 -4
drivers/mmc/host/mmci.c
··· 675 675 unsigned int status) 676 676 { 677 677 /* First check for errors */ 678 - if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) { 678 + if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_STARTBITERR| 679 + MCI_TXUNDERRUN|MCI_RXOVERRUN)) { 679 680 u32 remain, success; 680 681 681 682 /* Terminate the DMA transfer */ ··· 755 754 } 756 755 757 756 if (!cmd->data || cmd->error) { 758 - if (host->data) 757 + if (host->data) { 758 + /* Terminate the DMA transfer */ 759 + if (dma_inprogress(host)) 760 + mmci_dma_data_error(host); 759 761 mmci_stop_data(host); 762 + } 760 763 mmci_request_end(host, cmd->mrq); 761 764 } else if (!(cmd->data->flags & MMC_DATA_READ)) { 762 765 mmci_start_data(host, cmd->data); ··· 960 955 dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); 961 956 962 957 data = host->data; 963 - if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN| 964 - MCI_RXOVERRUN|MCI_DATAEND|MCI_DATABLOCKEND) && data) 958 + if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_STARTBITERR| 959 + MCI_TXUNDERRUN|MCI_RXOVERRUN|MCI_DATAEND| 960 + MCI_DATABLOCKEND) && data) 965 961 mmci_data_irq(host, data, status); 966 962 967 963 cmd = host->cmd;