diff options
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/ehv_bytechan.c | 1 | ||||
-rw-r--r-- | drivers/tty/mxser.c | 11 | ||||
-rw-r--r-- | drivers/tty/n_tty.c | 8 | ||||
-rw-r--r-- | drivers/tty/rocket.c | 288 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_core.c | 14 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_dw.c | 7 | ||||
-rw-r--r-- | drivers/tty/serial/amba-pl011.c | 2 | ||||
-rw-r--r-- | drivers/tty/serial/imx.c | 2 | ||||
-rw-r--r-- | drivers/tty/serial/mcf.c | 4 | ||||
-rw-r--r-- | drivers/tty/serial/mpc52xx_uart.c | 11 | ||||
-rw-r--r-- | drivers/tty/serial/nwpserial.c | 2 | ||||
-rw-r--r-- | drivers/tty/serial/omap-serial.c | 23 | ||||
-rw-r--r-- | drivers/tty/serial/samsung.c | 18 | ||||
-rw-r--r-- | drivers/tty/serial/sh-sci.c | 104 | ||||
-rw-r--r-- | drivers/tty/vt/vt.c | 14 | ||||
-rw-r--r-- | drivers/tty/vt/vt_ioctl.c | 67 |
16 files changed, 351 insertions, 225 deletions
diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index 6d0c27cd03da..9bffcec5ad82 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c | |||
@@ -859,6 +859,7 @@ error: | |||
859 | */ | 859 | */ |
860 | static void __exit ehv_bc_exit(void) | 860 | static void __exit ehv_bc_exit(void) |
861 | { | 861 | { |
862 | platform_driver_unregister(&ehv_bc_tty_driver); | ||
862 | tty_unregister_driver(ehv_bc_driver); | 863 | tty_unregister_driver(ehv_bc_driver); |
863 | put_tty_driver(ehv_bc_driver); | 864 | put_tty_driver(ehv_bc_driver); |
864 | kfree(bcs); | 865 | kfree(bcs); |
diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 71d6eb2c93b1..4c4a23674569 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c | |||
@@ -1618,8 +1618,12 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1618 | if (ip->type == PORT_16550A) | 1618 | if (ip->type == PORT_16550A) |
1619 | me->fifo[p] = 1; | 1619 | me->fifo[p] = 1; |
1620 | 1620 | ||
1621 | opmode = inb(ip->opmode_ioaddr)>>((p % 4) * 2); | 1621 | if (ip->board->chip_flag == MOXA_MUST_MU860_HWID) { |
1622 | opmode &= OP_MODE_MASK; | 1622 | opmode = inb(ip->opmode_ioaddr)>>((p % 4) * 2); |
1623 | opmode &= OP_MODE_MASK; | ||
1624 | } else { | ||
1625 | opmode = RS232_MODE; | ||
1626 | } | ||
1623 | me->iftype[p] = opmode; | 1627 | me->iftype[p] = opmode; |
1624 | mutex_unlock(&port->mutex); | 1628 | mutex_unlock(&port->mutex); |
1625 | } | 1629 | } |
@@ -1676,6 +1680,9 @@ static int mxser_ioctl(struct tty_struct *tty, | |||
1676 | int shiftbit; | 1680 | int shiftbit; |
1677 | unsigned char val, mask; | 1681 | unsigned char val, mask; |
1678 | 1682 | ||
1683 | if (info->board->chip_flag != MOXA_MUST_MU860_HWID) | ||
1684 | return -EFAULT; | ||
1685 | |||
1679 | p = tty->index % 4; | 1686 | p = tty->index % 4; |
1680 | if (cmd == MOXA_SET_OP_MODE) { | 1687 | if (cmd == MOXA_SET_OP_MODE) { |
1681 | if (get_user(opmode, (int __user *) argp)) | 1688 | if (get_user(opmode, (int __user *) argp)) |
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index d655416087b7..6c7fe90ad72d 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
@@ -1573,6 +1573,14 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
1573 | ldata->real_raw = 0; | 1573 | ldata->real_raw = 0; |
1574 | } | 1574 | } |
1575 | n_tty_set_room(tty); | 1575 | n_tty_set_room(tty); |
1576 | /* | ||
1577 | * Fix tty hang when I_IXON(tty) is cleared, but the tty | ||
1578 | * been stopped by STOP_CHAR(tty) before it. | ||
1579 | */ | ||
1580 | if (!I_IXON(tty) && old && (old->c_iflag & IXON) && !tty->flow_stopped) { | ||
1581 | start_tty(tty); | ||
1582 | } | ||
1583 | |||
1576 | /* The termios change make the tty ready for I/O */ | 1584 | /* The termios change make the tty ready for I/O */ |
1577 | wake_up_interruptible(&tty->write_wait); | 1585 | wake_up_interruptible(&tty->write_wait); |
1578 | wake_up_interruptible(&tty->read_wait); | 1586 | wake_up_interruptible(&tty->read_wait); |
diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c index 82d35c5a58fd..354564ea47c5 100644 --- a/drivers/tty/rocket.c +++ b/drivers/tty/rocket.c | |||
@@ -150,12 +150,14 @@ static Word_t aiop_intr_bits[AIOP_CTL_SIZE] = { | |||
150 | AIOP_INTR_BIT_3 | 150 | AIOP_INTR_BIT_3 |
151 | }; | 151 | }; |
152 | 152 | ||
153 | #ifdef CONFIG_PCI | ||
153 | static Word_t upci_aiop_intr_bits[AIOP_CTL_SIZE] = { | 154 | static Word_t upci_aiop_intr_bits[AIOP_CTL_SIZE] = { |
154 | UPCI_AIOP_INTR_BIT_0, | 155 | UPCI_AIOP_INTR_BIT_0, |
155 | UPCI_AIOP_INTR_BIT_1, | 156 | UPCI_AIOP_INTR_BIT_1, |
156 | UPCI_AIOP_INTR_BIT_2, | 157 | UPCI_AIOP_INTR_BIT_2, |
157 | UPCI_AIOP_INTR_BIT_3 | 158 | UPCI_AIOP_INTR_BIT_3 |
158 | }; | 159 | }; |
160 | #endif | ||
159 | 161 | ||
160 | static Byte_t RData[RDATASIZE] = { | 162 | static Byte_t RData[RDATASIZE] = { |
161 | 0x00, 0x09, 0xf6, 0x82, | 163 | 0x00, 0x09, 0xf6, 0x82, |
@@ -227,7 +229,6 @@ static unsigned long nextLineNumber; | |||
227 | static int __init init_ISA(int i); | 229 | static int __init init_ISA(int i); |
228 | static void rp_wait_until_sent(struct tty_struct *tty, int timeout); | 230 | static void rp_wait_until_sent(struct tty_struct *tty, int timeout); |
229 | static void rp_flush_buffer(struct tty_struct *tty); | 231 | static void rp_flush_buffer(struct tty_struct *tty); |
230 | static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model); | ||
231 | static unsigned char GetLineNumber(int ctrl, int aiop, int ch); | 232 | static unsigned char GetLineNumber(int ctrl, int aiop, int ch); |
232 | static unsigned char SetLineNumber(int ctrl, int aiop, int ch); | 233 | static unsigned char SetLineNumber(int ctrl, int aiop, int ch); |
233 | static void rp_start(struct tty_struct *tty); | 234 | static void rp_start(struct tty_struct *tty); |
@@ -241,11 +242,6 @@ static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags); | |||
241 | static void sModemReset(CONTROLLER_T * CtlP, int chan, int on); | 242 | static void sModemReset(CONTROLLER_T * CtlP, int chan, int on); |
242 | static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on); | 243 | static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on); |
243 | static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data); | 244 | static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data); |
244 | static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum, | ||
245 | ByteIO_t * AiopIOList, int AiopIOListSize, | ||
246 | WordIO_t ConfigIO, int IRQNum, Byte_t Frequency, | ||
247 | int PeriodicOnly, int altChanRingIndicator, | ||
248 | int UPCIRingInd); | ||
249 | static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO, | 245 | static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO, |
250 | ByteIO_t * AiopIOList, int AiopIOListSize, | 246 | ByteIO_t * AiopIOList, int AiopIOListSize, |
251 | int IRQNum, Byte_t Frequency, int PeriodicOnly); | 247 | int IRQNum, Byte_t Frequency, int PeriodicOnly); |
@@ -1775,6 +1771,145 @@ static DEFINE_PCI_DEVICE_TABLE(rocket_pci_ids) = { | |||
1775 | }; | 1771 | }; |
1776 | MODULE_DEVICE_TABLE(pci, rocket_pci_ids); | 1772 | MODULE_DEVICE_TABLE(pci, rocket_pci_ids); |
1777 | 1773 | ||
1774 | /* Resets the speaker controller on RocketModem II and III devices */ | ||
1775 | static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model) | ||
1776 | { | ||
1777 | ByteIO_t addr; | ||
1778 | |||
1779 | /* RocketModem II speaker control is at the 8th port location of offset 0x40 */ | ||
1780 | if ((model == MODEL_RP4M) || (model == MODEL_RP6M)) { | ||
1781 | addr = CtlP->AiopIO[0] + 0x4F; | ||
1782 | sOutB(addr, 0); | ||
1783 | } | ||
1784 | |||
1785 | /* RocketModem III speaker control is at the 1st port location of offset 0x80 */ | ||
1786 | if ((model == MODEL_UPCI_RM3_8PORT) | ||
1787 | || (model == MODEL_UPCI_RM3_4PORT)) { | ||
1788 | addr = CtlP->AiopIO[0] + 0x88; | ||
1789 | sOutB(addr, 0); | ||
1790 | } | ||
1791 | } | ||
1792 | |||
1793 | /*************************************************************************** | ||
1794 | Function: sPCIInitController | ||
1795 | Purpose: Initialization of controller global registers and controller | ||
1796 | structure. | ||
1797 | Call: sPCIInitController(CtlP,CtlNum,AiopIOList,AiopIOListSize, | ||
1798 | IRQNum,Frequency,PeriodicOnly) | ||
1799 | CONTROLLER_T *CtlP; Ptr to controller structure | ||
1800 | int CtlNum; Controller number | ||
1801 | ByteIO_t *AiopIOList; List of I/O addresses for each AIOP. | ||
1802 | This list must be in the order the AIOPs will be found on the | ||
1803 | controller. Once an AIOP in the list is not found, it is | ||
1804 | assumed that there are no more AIOPs on the controller. | ||
1805 | int AiopIOListSize; Number of addresses in AiopIOList | ||
1806 | int IRQNum; Interrupt Request number. Can be any of the following: | ||
1807 | 0: Disable global interrupts | ||
1808 | 3: IRQ 3 | ||
1809 | 4: IRQ 4 | ||
1810 | 5: IRQ 5 | ||
1811 | 9: IRQ 9 | ||
1812 | 10: IRQ 10 | ||
1813 | 11: IRQ 11 | ||
1814 | 12: IRQ 12 | ||
1815 | 15: IRQ 15 | ||
1816 | Byte_t Frequency: A flag identifying the frequency | ||
1817 | of the periodic interrupt, can be any one of the following: | ||
1818 | FREQ_DIS - periodic interrupt disabled | ||
1819 | FREQ_137HZ - 137 Hertz | ||
1820 | FREQ_69HZ - 69 Hertz | ||
1821 | FREQ_34HZ - 34 Hertz | ||
1822 | FREQ_17HZ - 17 Hertz | ||
1823 | FREQ_9HZ - 9 Hertz | ||
1824 | FREQ_4HZ - 4 Hertz | ||
1825 | If IRQNum is set to 0 the Frequency parameter is | ||
1826 | overidden, it is forced to a value of FREQ_DIS. | ||
1827 | int PeriodicOnly: 1 if all interrupts except the periodic | ||
1828 | interrupt are to be blocked. | ||
1829 | 0 is both the periodic interrupt and | ||
1830 | other channel interrupts are allowed. | ||
1831 | If IRQNum is set to 0 the PeriodicOnly parameter is | ||
1832 | overidden, it is forced to a value of 0. | ||
1833 | Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller | ||
1834 | initialization failed. | ||
1835 | |||
1836 | Comments: | ||
1837 | If periodic interrupts are to be disabled but AIOP interrupts | ||
1838 | are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0. | ||
1839 | |||
1840 | If interrupts are to be completely disabled set IRQNum to 0. | ||
1841 | |||
1842 | Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an | ||
1843 | invalid combination. | ||
1844 | |||
1845 | This function performs initialization of global interrupt modes, | ||
1846 | but it does not actually enable global interrupts. To enable | ||
1847 | and disable global interrupts use functions sEnGlobalInt() and | ||
1848 | sDisGlobalInt(). Enabling of global interrupts is normally not | ||
1849 | done until all other initializations are complete. | ||
1850 | |||
1851 | Even if interrupts are globally enabled, they must also be | ||
1852 | individually enabled for each channel that is to generate | ||
1853 | interrupts. | ||
1854 | |||
1855 | Warnings: No range checking on any of the parameters is done. | ||
1856 | |||
1857 | No context switches are allowed while executing this function. | ||
1858 | |||
1859 | After this function all AIOPs on the controller are disabled, | ||
1860 | they can be enabled with sEnAiop(). | ||
1861 | */ | ||
1862 | static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum, | ||
1863 | ByteIO_t * AiopIOList, int AiopIOListSize, | ||
1864 | WordIO_t ConfigIO, int IRQNum, Byte_t Frequency, | ||
1865 | int PeriodicOnly, int altChanRingIndicator, | ||
1866 | int UPCIRingInd) | ||
1867 | { | ||
1868 | int i; | ||
1869 | ByteIO_t io; | ||
1870 | |||
1871 | CtlP->AltChanRingIndicator = altChanRingIndicator; | ||
1872 | CtlP->UPCIRingInd = UPCIRingInd; | ||
1873 | CtlP->CtlNum = CtlNum; | ||
1874 | CtlP->CtlID = CTLID_0001; /* controller release 1 */ | ||
1875 | CtlP->BusType = isPCI; /* controller release 1 */ | ||
1876 | |||
1877 | if (ConfigIO) { | ||
1878 | CtlP->isUPCI = 1; | ||
1879 | CtlP->PCIIO = ConfigIO + _PCI_9030_INT_CTRL; | ||
1880 | CtlP->PCIIO2 = ConfigIO + _PCI_9030_GPIO_CTRL; | ||
1881 | CtlP->AiopIntrBits = upci_aiop_intr_bits; | ||
1882 | } else { | ||
1883 | CtlP->isUPCI = 0; | ||
1884 | CtlP->PCIIO = | ||
1885 | (WordIO_t) ((ByteIO_t) AiopIOList[0] + _PCI_INT_FUNC); | ||
1886 | CtlP->AiopIntrBits = aiop_intr_bits; | ||
1887 | } | ||
1888 | |||
1889 | sPCIControllerEOI(CtlP); /* clear EOI if warm init */ | ||
1890 | /* Init AIOPs */ | ||
1891 | CtlP->NumAiop = 0; | ||
1892 | for (i = 0; i < AiopIOListSize; i++) { | ||
1893 | io = AiopIOList[i]; | ||
1894 | CtlP->AiopIO[i] = (WordIO_t) io; | ||
1895 | CtlP->AiopIntChanIO[i] = io + _INT_CHAN; | ||
1896 | |||
1897 | CtlP->AiopID[i] = sReadAiopID(io); /* read AIOP ID */ | ||
1898 | if (CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */ | ||
1899 | break; /* done looking for AIOPs */ | ||
1900 | |||
1901 | CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io); /* num channels in AIOP */ | ||
1902 | sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE); /* clock prescaler */ | ||
1903 | sOutB(io + _INDX_DATA, sClockPrescale); | ||
1904 | CtlP->NumAiop++; /* bump count of AIOPs */ | ||
1905 | } | ||
1906 | |||
1907 | if (CtlP->NumAiop == 0) | ||
1908 | return (-1); | ||
1909 | else | ||
1910 | return (CtlP->NumAiop); | ||
1911 | } | ||
1912 | |||
1778 | /* | 1913 | /* |
1779 | * Called when a PCI card is found. Retrieves and stores model information, | 1914 | * Called when a PCI card is found. Retrieves and stores model information, |
1780 | * init's aiopic and serial port hardware. | 1915 | * init's aiopic and serial port hardware. |
@@ -2519,147 +2654,6 @@ static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO, | |||
2519 | return (CtlP->NumAiop); | 2654 | return (CtlP->NumAiop); |
2520 | } | 2655 | } |
2521 | 2656 | ||
2522 | #ifdef CONFIG_PCI | ||
2523 | /*************************************************************************** | ||
2524 | Function: sPCIInitController | ||
2525 | Purpose: Initialization of controller global registers and controller | ||
2526 | structure. | ||
2527 | Call: sPCIInitController(CtlP,CtlNum,AiopIOList,AiopIOListSize, | ||
2528 | IRQNum,Frequency,PeriodicOnly) | ||
2529 | CONTROLLER_T *CtlP; Ptr to controller structure | ||
2530 | int CtlNum; Controller number | ||
2531 | ByteIO_t *AiopIOList; List of I/O addresses for each AIOP. | ||
2532 | This list must be in the order the AIOPs will be found on the | ||
2533 | controller. Once an AIOP in the list is not found, it is | ||
2534 | assumed that there are no more AIOPs on the controller. | ||
2535 | int AiopIOListSize; Number of addresses in AiopIOList | ||
2536 | int IRQNum; Interrupt Request number. Can be any of the following: | ||
2537 | 0: Disable global interrupts | ||
2538 | 3: IRQ 3 | ||
2539 | 4: IRQ 4 | ||
2540 | 5: IRQ 5 | ||
2541 | 9: IRQ 9 | ||
2542 | 10: IRQ 10 | ||
2543 | 11: IRQ 11 | ||
2544 | 12: IRQ 12 | ||
2545 | 15: IRQ 15 | ||
2546 | Byte_t Frequency: A flag identifying the frequency | ||
2547 | of the periodic interrupt, can be any one of the following: | ||
2548 | FREQ_DIS - periodic interrupt disabled | ||
2549 | FREQ_137HZ - 137 Hertz | ||
2550 | FREQ_69HZ - 69 Hertz | ||
2551 | FREQ_34HZ - 34 Hertz | ||
2552 | FREQ_17HZ - 17 Hertz | ||
2553 | FREQ_9HZ - 9 Hertz | ||
2554 | FREQ_4HZ - 4 Hertz | ||
2555 | If IRQNum is set to 0 the Frequency parameter is | ||
2556 | overidden, it is forced to a value of FREQ_DIS. | ||
2557 | int PeriodicOnly: 1 if all interrupts except the periodic | ||
2558 | interrupt are to be blocked. | ||
2559 | 0 is both the periodic interrupt and | ||
2560 | other channel interrupts are allowed. | ||
2561 | If IRQNum is set to 0 the PeriodicOnly parameter is | ||
2562 | overidden, it is forced to a value of 0. | ||
2563 | Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller | ||
2564 | initialization failed. | ||
2565 | |||
2566 | Comments: | ||
2567 | If periodic interrupts are to be disabled but AIOP interrupts | ||
2568 | are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0. | ||
2569 | |||
2570 | If interrupts are to be completely disabled set IRQNum to 0. | ||
2571 | |||
2572 | Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an | ||
2573 | invalid combination. | ||
2574 | |||
2575 | This function performs initialization of global interrupt modes, | ||
2576 | but it does not actually enable global interrupts. To enable | ||
2577 | and disable global interrupts use functions sEnGlobalInt() and | ||
2578 | sDisGlobalInt(). Enabling of global interrupts is normally not | ||
2579 | done until all other initializations are complete. | ||
2580 | |||
2581 | Even if interrupts are globally enabled, they must also be | ||
2582 | individually enabled for each channel that is to generate | ||
2583 | interrupts. | ||
2584 | |||
2585 | Warnings: No range checking on any of the parameters is done. | ||
2586 | |||
2587 | No context switches are allowed while executing this function. | ||
2588 | |||
2589 | After this function all AIOPs on the controller are disabled, | ||
2590 | they can be enabled with sEnAiop(). | ||
2591 | */ | ||
2592 | static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum, | ||
2593 | ByteIO_t * AiopIOList, int AiopIOListSize, | ||
2594 | WordIO_t ConfigIO, int IRQNum, Byte_t Frequency, | ||
2595 | int PeriodicOnly, int altChanRingIndicator, | ||
2596 | int UPCIRingInd) | ||
2597 | { | ||
2598 | int i; | ||
2599 | ByteIO_t io; | ||
2600 | |||
2601 | CtlP->AltChanRingIndicator = altChanRingIndicator; | ||
2602 | CtlP->UPCIRingInd = UPCIRingInd; | ||
2603 | CtlP->CtlNum = CtlNum; | ||
2604 | CtlP->CtlID = CTLID_0001; /* controller release 1 */ | ||
2605 | CtlP->BusType = isPCI; /* controller release 1 */ | ||
2606 | |||
2607 | if (ConfigIO) { | ||
2608 | CtlP->isUPCI = 1; | ||
2609 | CtlP->PCIIO = ConfigIO + _PCI_9030_INT_CTRL; | ||
2610 | CtlP->PCIIO2 = ConfigIO + _PCI_9030_GPIO_CTRL; | ||
2611 | CtlP->AiopIntrBits = upci_aiop_intr_bits; | ||
2612 | } else { | ||
2613 | CtlP->isUPCI = 0; | ||
2614 | CtlP->PCIIO = | ||
2615 | (WordIO_t) ((ByteIO_t) AiopIOList[0] + _PCI_INT_FUNC); | ||
2616 | CtlP->AiopIntrBits = aiop_intr_bits; | ||
2617 | } | ||
2618 | |||
2619 | sPCIControllerEOI(CtlP); /* clear EOI if warm init */ | ||
2620 | /* Init AIOPs */ | ||
2621 | CtlP->NumAiop = 0; | ||
2622 | for (i = 0; i < AiopIOListSize; i++) { | ||
2623 | io = AiopIOList[i]; | ||
2624 | CtlP->AiopIO[i] = (WordIO_t) io; | ||
2625 | CtlP->AiopIntChanIO[i] = io + _INT_CHAN; | ||
2626 | |||
2627 | CtlP->AiopID[i] = sReadAiopID(io); /* read AIOP ID */ | ||
2628 | if (CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */ | ||
2629 | break; /* done looking for AIOPs */ | ||
2630 | |||
2631 | CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io); /* num channels in AIOP */ | ||
2632 | sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE); /* clock prescaler */ | ||
2633 | sOutB(io + _INDX_DATA, sClockPrescale); | ||
2634 | CtlP->NumAiop++; /* bump count of AIOPs */ | ||
2635 | } | ||
2636 | |||
2637 | if (CtlP->NumAiop == 0) | ||
2638 | return (-1); | ||
2639 | else | ||
2640 | return (CtlP->NumAiop); | ||
2641 | } | ||
2642 | |||
2643 | /* Resets the speaker controller on RocketModem II and III devices */ | ||
2644 | static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model) | ||
2645 | { | ||
2646 | ByteIO_t addr; | ||
2647 | |||
2648 | /* RocketModem II speaker control is at the 8th port location of offset 0x40 */ | ||
2649 | if ((model == MODEL_RP4M) || (model == MODEL_RP6M)) { | ||
2650 | addr = CtlP->AiopIO[0] + 0x4F; | ||
2651 | sOutB(addr, 0); | ||
2652 | } | ||
2653 | |||
2654 | /* RocketModem III speaker control is at the 1st port location of offset 0x80 */ | ||
2655 | if ((model == MODEL_UPCI_RM3_8PORT) | ||
2656 | || (model == MODEL_UPCI_RM3_4PORT)) { | ||
2657 | addr = CtlP->AiopIO[0] + 0x88; | ||
2658 | sOutB(addr, 0); | ||
2659 | } | ||
2660 | } | ||
2661 | #endif | ||
2662 | |||
2663 | /*************************************************************************** | 2657 | /*************************************************************************** |
2664 | Function: sReadAiopID | 2658 | Function: sReadAiopID |
2665 | Purpose: Read the AIOP idenfication number directly from an AIOP. | 2659 | Purpose: Read the AIOP idenfication number directly from an AIOP. |
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 46528d57be72..86c00b1c5583 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c | |||
@@ -2755,7 +2755,7 @@ static void __init serial8250_isa_init_ports(void) | |||
2755 | if (nr_uarts > UART_NR) | 2755 | if (nr_uarts > UART_NR) |
2756 | nr_uarts = UART_NR; | 2756 | nr_uarts = UART_NR; |
2757 | 2757 | ||
2758 | for (i = 0; i < UART_NR; i++) { | 2758 | for (i = 0; i < nr_uarts; i++) { |
2759 | struct uart_8250_port *up = &serial8250_ports[i]; | 2759 | struct uart_8250_port *up = &serial8250_ports[i]; |
2760 | struct uart_port *port = &up->port; | 2760 | struct uart_port *port = &up->port; |
2761 | 2761 | ||
@@ -2916,7 +2916,7 @@ static int __init serial8250_console_setup(struct console *co, char *options) | |||
2916 | * if so, search for the first available port that does have | 2916 | * if so, search for the first available port that does have |
2917 | * console support. | 2917 | * console support. |
2918 | */ | 2918 | */ |
2919 | if (co->index >= UART_NR) | 2919 | if (co->index >= nr_uarts) |
2920 | co->index = 0; | 2920 | co->index = 0; |
2921 | port = &serial8250_ports[co->index].port; | 2921 | port = &serial8250_ports[co->index].port; |
2922 | if (!port->iobase && !port->membase) | 2922 | if (!port->iobase && !port->membase) |
@@ -2957,7 +2957,7 @@ int serial8250_find_port(struct uart_port *p) | |||
2957 | int line; | 2957 | int line; |
2958 | struct uart_port *port; | 2958 | struct uart_port *port; |
2959 | 2959 | ||
2960 | for (line = 0; line < UART_NR; line++) { | 2960 | for (line = 0; line < nr_uarts; line++) { |
2961 | port = &serial8250_ports[line].port; | 2961 | port = &serial8250_ports[line].port; |
2962 | if (uart_match_port(p, port)) | 2962 | if (uart_match_port(p, port)) |
2963 | return line; | 2963 | return line; |
@@ -3110,7 +3110,7 @@ static int serial8250_remove(struct platform_device *dev) | |||
3110 | { | 3110 | { |
3111 | int i; | 3111 | int i; |
3112 | 3112 | ||
3113 | for (i = 0; i < UART_NR; i++) { | 3113 | for (i = 0; i < nr_uarts; i++) { |
3114 | struct uart_8250_port *up = &serial8250_ports[i]; | 3114 | struct uart_8250_port *up = &serial8250_ports[i]; |
3115 | 3115 | ||
3116 | if (up->port.dev == &dev->dev) | 3116 | if (up->port.dev == &dev->dev) |
@@ -3178,7 +3178,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * | |||
3178 | /* | 3178 | /* |
3179 | * First, find a port entry which matches. | 3179 | * First, find a port entry which matches. |
3180 | */ | 3180 | */ |
3181 | for (i = 0; i < UART_NR; i++) | 3181 | for (i = 0; i < nr_uarts; i++) |
3182 | if (uart_match_port(&serial8250_ports[i].port, port)) | 3182 | if (uart_match_port(&serial8250_ports[i].port, port)) |
3183 | return &serial8250_ports[i]; | 3183 | return &serial8250_ports[i]; |
3184 | 3184 | ||
@@ -3187,7 +3187,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * | |||
3187 | * free entry. We look for one which hasn't been previously | 3187 | * free entry. We look for one which hasn't been previously |
3188 | * used (indicated by zero iobase). | 3188 | * used (indicated by zero iobase). |
3189 | */ | 3189 | */ |
3190 | for (i = 0; i < UART_NR; i++) | 3190 | for (i = 0; i < nr_uarts; i++) |
3191 | if (serial8250_ports[i].port.type == PORT_UNKNOWN && | 3191 | if (serial8250_ports[i].port.type == PORT_UNKNOWN && |
3192 | serial8250_ports[i].port.iobase == 0) | 3192 | serial8250_ports[i].port.iobase == 0) |
3193 | return &serial8250_ports[i]; | 3193 | return &serial8250_ports[i]; |
@@ -3196,7 +3196,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * | |||
3196 | * That also failed. Last resort is to find any entry which | 3196 | * That also failed. Last resort is to find any entry which |
3197 | * doesn't have a real port associated with it. | 3197 | * doesn't have a real port associated with it. |
3198 | */ | 3198 | */ |
3199 | for (i = 0; i < UART_NR; i++) | 3199 | for (i = 0; i < nr_uarts; i++) |
3200 | if (serial8250_ports[i].port.type == PORT_UNKNOWN) | 3200 | if (serial8250_ports[i].port.type == PORT_UNKNOWN) |
3201 | return &serial8250_ports[i]; | 3201 | return &serial8250_ports[i]; |
3202 | 3202 | ||
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index beaa283f5cc6..d07b6af3a937 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c | |||
@@ -338,7 +338,8 @@ static int dw8250_runtime_suspend(struct device *dev) | |||
338 | { | 338 | { |
339 | struct dw8250_data *data = dev_get_drvdata(dev); | 339 | struct dw8250_data *data = dev_get_drvdata(dev); |
340 | 340 | ||
341 | clk_disable_unprepare(data->clk); | 341 | if (!IS_ERR(data->clk)) |
342 | clk_disable_unprepare(data->clk); | ||
342 | 343 | ||
343 | return 0; | 344 | return 0; |
344 | } | 345 | } |
@@ -347,7 +348,8 @@ static int dw8250_runtime_resume(struct device *dev) | |||
347 | { | 348 | { |
348 | struct dw8250_data *data = dev_get_drvdata(dev); | 349 | struct dw8250_data *data = dev_get_drvdata(dev); |
349 | 350 | ||
350 | clk_prepare_enable(data->clk); | 351 | if (!IS_ERR(data->clk)) |
352 | clk_prepare_enable(data->clk); | ||
351 | 353 | ||
352 | return 0; | 354 | return 0; |
353 | } | 355 | } |
@@ -367,6 +369,7 @@ MODULE_DEVICE_TABLE(of, dw8250_of_match); | |||
367 | static const struct acpi_device_id dw8250_acpi_match[] = { | 369 | static const struct acpi_device_id dw8250_acpi_match[] = { |
368 | { "INT33C4", 0 }, | 370 | { "INT33C4", 0 }, |
369 | { "INT33C5", 0 }, | 371 | { "INT33C5", 0 }, |
372 | { "80860F0A", 0 }, | ||
370 | { }, | 373 | { }, |
371 | }; | 374 | }; |
372 | MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match); | 375 | MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match); |
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 8ab70a620919..e2774f9ecd59 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c | |||
@@ -332,7 +332,7 @@ static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port * | |||
332 | dmaengine_slave_config(chan, &rx_conf); | 332 | dmaengine_slave_config(chan, &rx_conf); |
333 | uap->dmarx.chan = chan; | 333 | uap->dmarx.chan = chan; |
334 | 334 | ||
335 | if (plat->dma_rx_poll_enable) { | 335 | if (plat && plat->dma_rx_poll_enable) { |
336 | /* Set poll rate if specified. */ | 336 | /* Set poll rate if specified. */ |
337 | if (plat->dma_rx_poll_rate) { | 337 | if (plat->dma_rx_poll_rate) { |
338 | uap->dmarx.auto_poll_rate = false; | 338 | uap->dmarx.auto_poll_rate = false; |
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 147c9e193595..8cdfbd365892 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
@@ -761,6 +761,8 @@ static int imx_startup(struct uart_port *port) | |||
761 | 761 | ||
762 | temp = readl(sport->port.membase + UCR2); | 762 | temp = readl(sport->port.membase + UCR2); |
763 | temp |= (UCR2_RXEN | UCR2_TXEN); | 763 | temp |= (UCR2_RXEN | UCR2_TXEN); |
764 | if (!sport->have_rtscts) | ||
765 | temp |= UCR2_IRTS; | ||
764 | writel(temp, sport->port.membase + UCR2); | 766 | writel(temp, sport->port.membase + UCR2); |
765 | 767 | ||
766 | if (USE_IRDA(sport)) { | 768 | if (USE_IRDA(sport)) { |
diff --git a/drivers/tty/serial/mcf.c b/drivers/tty/serial/mcf.c index e956377a38fe..65be0c00c4bf 100644 --- a/drivers/tty/serial/mcf.c +++ b/drivers/tty/serial/mcf.c | |||
@@ -707,8 +707,10 @@ static int __init mcf_init(void) | |||
707 | if (rc) | 707 | if (rc) |
708 | return rc; | 708 | return rc; |
709 | rc = platform_driver_register(&mcf_platform_driver); | 709 | rc = platform_driver_register(&mcf_platform_driver); |
710 | if (rc) | 710 | if (rc) { |
711 | uart_unregister_driver(&mcf_driver); | ||
711 | return rc; | 712 | return rc; |
713 | } | ||
712 | return 0; | 714 | return 0; |
713 | } | 715 | } |
714 | 716 | ||
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 018bad922554..f51b280f3bf2 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c | |||
@@ -1497,18 +1497,23 @@ mpc52xx_uart_init(void) | |||
1497 | if (psc_ops && psc_ops->fifoc_init) { | 1497 | if (psc_ops && psc_ops->fifoc_init) { |
1498 | ret = psc_ops->fifoc_init(); | 1498 | ret = psc_ops->fifoc_init(); |
1499 | if (ret) | 1499 | if (ret) |
1500 | return ret; | 1500 | goto err_init; |
1501 | } | 1501 | } |
1502 | 1502 | ||
1503 | ret = platform_driver_register(&mpc52xx_uart_of_driver); | 1503 | ret = platform_driver_register(&mpc52xx_uart_of_driver); |
1504 | if (ret) { | 1504 | if (ret) { |
1505 | printk(KERN_ERR "%s: platform_driver_register failed (%i)\n", | 1505 | printk(KERN_ERR "%s: platform_driver_register failed (%i)\n", |
1506 | __FILE__, ret); | 1506 | __FILE__, ret); |
1507 | uart_unregister_driver(&mpc52xx_uart_driver); | 1507 | goto err_reg; |
1508 | return ret; | ||
1509 | } | 1508 | } |
1510 | 1509 | ||
1511 | return 0; | 1510 | return 0; |
1511 | err_reg: | ||
1512 | if (psc_ops && psc_ops->fifoc_uninit) | ||
1513 | psc_ops->fifoc_uninit(); | ||
1514 | err_init: | ||
1515 | uart_unregister_driver(&mpc52xx_uart_driver); | ||
1516 | return ret; | ||
1512 | } | 1517 | } |
1513 | 1518 | ||
1514 | static void __exit | 1519 | static void __exit |
diff --git a/drivers/tty/serial/nwpserial.c b/drivers/tty/serial/nwpserial.c index 77287c54f331..549c70a2a63e 100644 --- a/drivers/tty/serial/nwpserial.c +++ b/drivers/tty/serial/nwpserial.c | |||
@@ -199,7 +199,7 @@ static void nwpserial_shutdown(struct uart_port *port) | |||
199 | dcr_write(up->dcr_host, UART_IER, up->ier); | 199 | dcr_write(up->dcr_host, UART_IER, up->ier); |
200 | 200 | ||
201 | /* free irq */ | 201 | /* free irq */ |
202 | free_irq(up->port.irq, port); | 202 | free_irq(up->port.irq, up); |
203 | } | 203 | } |
204 | 204 | ||
205 | static int nwpserial_verify_port(struct uart_port *port, | 205 | static int nwpserial_verify_port(struct uart_port *port, |
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 30d4f7a783cd..f0b9f6b52b32 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c | |||
@@ -202,26 +202,6 @@ static int serial_omap_get_context_loss_count(struct uart_omap_port *up) | |||
202 | return pdata->get_context_loss_count(up->dev); | 202 | return pdata->get_context_loss_count(up->dev); |
203 | } | 203 | } |
204 | 204 | ||
205 | static void serial_omap_set_forceidle(struct uart_omap_port *up) | ||
206 | { | ||
207 | struct omap_uart_port_info *pdata = up->dev->platform_data; | ||
208 | |||
209 | if (!pdata || !pdata->set_forceidle) | ||
210 | return; | ||
211 | |||
212 | pdata->set_forceidle(up->dev); | ||
213 | } | ||
214 | |||
215 | static void serial_omap_set_noidle(struct uart_omap_port *up) | ||
216 | { | ||
217 | struct omap_uart_port_info *pdata = up->dev->platform_data; | ||
218 | |||
219 | if (!pdata || !pdata->set_noidle) | ||
220 | return; | ||
221 | |||
222 | pdata->set_noidle(up->dev); | ||
223 | } | ||
224 | |||
225 | static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable) | 205 | static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable) |
226 | { | 206 | { |
227 | struct omap_uart_port_info *pdata = up->dev->platform_data; | 207 | struct omap_uart_port_info *pdata = up->dev->platform_data; |
@@ -298,8 +278,6 @@ static void serial_omap_stop_tx(struct uart_port *port) | |||
298 | serial_out(up, UART_IER, up->ier); | 278 | serial_out(up, UART_IER, up->ier); |
299 | } | 279 | } |
300 | 280 | ||
301 | serial_omap_set_forceidle(up); | ||
302 | |||
303 | pm_runtime_mark_last_busy(up->dev); | 281 | pm_runtime_mark_last_busy(up->dev); |
304 | pm_runtime_put_autosuspend(up->dev); | 282 | pm_runtime_put_autosuspend(up->dev); |
305 | } | 283 | } |
@@ -364,7 +342,6 @@ static void serial_omap_start_tx(struct uart_port *port) | |||
364 | 342 | ||
365 | pm_runtime_get_sync(up->dev); | 343 | pm_runtime_get_sync(up->dev); |
366 | serial_omap_enable_ier_thri(up); | 344 | serial_omap_enable_ier_thri(up); |
367 | serial_omap_set_noidle(up); | ||
368 | pm_runtime_mark_last_busy(up->dev); | 345 | pm_runtime_mark_last_busy(up->dev); |
369 | pm_runtime_put_autosuspend(up->dev); | 346 | pm_runtime_put_autosuspend(up->dev); |
370 | } | 347 | } |
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 074b9194144f..94a91c2b7ca0 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c | |||
@@ -1166,6 +1166,18 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, | |||
1166 | ourport->tx_irq = ret; | 1166 | ourport->tx_irq = ret; |
1167 | 1167 | ||
1168 | ourport->clk = clk_get(&platdev->dev, "uart"); | 1168 | ourport->clk = clk_get(&platdev->dev, "uart"); |
1169 | if (IS_ERR(ourport->clk)) { | ||
1170 | pr_err("%s: Controller clock not found\n", | ||
1171 | dev_name(&platdev->dev)); | ||
1172 | return PTR_ERR(ourport->clk); | ||
1173 | } | ||
1174 | |||
1175 | ret = clk_prepare_enable(ourport->clk); | ||
1176 | if (ret) { | ||
1177 | pr_err("uart: clock failed to prepare+enable: %d\n", ret); | ||
1178 | clk_put(ourport->clk); | ||
1179 | return ret; | ||
1180 | } | ||
1169 | 1181 | ||
1170 | /* Keep all interrupts masked and cleared */ | 1182 | /* Keep all interrupts masked and cleared */ |
1171 | if (s3c24xx_serial_has_interrupt_mask(port)) { | 1183 | if (s3c24xx_serial_has_interrupt_mask(port)) { |
@@ -1180,6 +1192,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, | |||
1180 | 1192 | ||
1181 | /* reset the fifos (and setup the uart) */ | 1193 | /* reset the fifos (and setup the uart) */ |
1182 | s3c24xx_serial_resetport(port, cfg); | 1194 | s3c24xx_serial_resetport(port, cfg); |
1195 | clk_disable_unprepare(ourport->clk); | ||
1183 | return 0; | 1196 | return 0; |
1184 | } | 1197 | } |
1185 | 1198 | ||
@@ -1700,9 +1713,7 @@ static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = { | |||
1700 | #define S5PV210_SERIAL_DRV_DATA (kernel_ulong_t)NULL | 1713 | #define S5PV210_SERIAL_DRV_DATA (kernel_ulong_t)NULL |
1701 | #endif | 1714 | #endif |
1702 | 1715 | ||
1703 | #if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212) || \ | 1716 | #if defined(CONFIG_ARCH_EXYNOS) |
1704 | defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) || \ | ||
1705 | defined(CONFIG_SOC_EXYNOS5440) | ||
1706 | static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = { | 1717 | static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = { |
1707 | .info = &(struct s3c24xx_uart_info) { | 1718 | .info = &(struct s3c24xx_uart_info) { |
1708 | .name = "Samsung Exynos4 UART", | 1719 | .name = "Samsung Exynos4 UART", |
@@ -1803,6 +1814,7 @@ static int __init s3c24xx_serial_modinit(void) | |||
1803 | 1814 | ||
1804 | static void __exit s3c24xx_serial_modexit(void) | 1815 | static void __exit s3c24xx_serial_modexit(void) |
1805 | { | 1816 | { |
1817 | platform_driver_unregister(&samsung_serial_driver); | ||
1806 | uart_unregister_driver(&s3c24xx_uart_drv); | 1818 | uart_unregister_driver(&s3c24xx_uart_drv); |
1807 | } | 1819 | } |
1808 | 1820 | ||
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 156418619949..7477e0ea5cdb 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
@@ -146,6 +146,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | |||
146 | [SCRFDR] = sci_reg_invalid, | 146 | [SCRFDR] = sci_reg_invalid, |
147 | [SCSPTR] = sci_reg_invalid, | 147 | [SCSPTR] = sci_reg_invalid, |
148 | [SCLSR] = sci_reg_invalid, | 148 | [SCLSR] = sci_reg_invalid, |
149 | [HSSRR] = sci_reg_invalid, | ||
149 | }, | 150 | }, |
150 | 151 | ||
151 | /* | 152 | /* |
@@ -165,6 +166,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | |||
165 | [SCRFDR] = sci_reg_invalid, | 166 | [SCRFDR] = sci_reg_invalid, |
166 | [SCSPTR] = sci_reg_invalid, | 167 | [SCSPTR] = sci_reg_invalid, |
167 | [SCLSR] = sci_reg_invalid, | 168 | [SCLSR] = sci_reg_invalid, |
169 | [HSSRR] = sci_reg_invalid, | ||
168 | }, | 170 | }, |
169 | 171 | ||
170 | /* | 172 | /* |
@@ -183,6 +185,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | |||
183 | [SCRFDR] = sci_reg_invalid, | 185 | [SCRFDR] = sci_reg_invalid, |
184 | [SCSPTR] = sci_reg_invalid, | 186 | [SCSPTR] = sci_reg_invalid, |
185 | [SCLSR] = sci_reg_invalid, | 187 | [SCLSR] = sci_reg_invalid, |
188 | [HSSRR] = sci_reg_invalid, | ||
186 | }, | 189 | }, |
187 | 190 | ||
188 | /* | 191 | /* |
@@ -201,6 +204,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | |||
201 | [SCRFDR] = { 0x3c, 16 }, | 204 | [SCRFDR] = { 0x3c, 16 }, |
202 | [SCSPTR] = sci_reg_invalid, | 205 | [SCSPTR] = sci_reg_invalid, |
203 | [SCLSR] = sci_reg_invalid, | 206 | [SCLSR] = sci_reg_invalid, |
207 | [HSSRR] = sci_reg_invalid, | ||
204 | }, | 208 | }, |
205 | 209 | ||
206 | /* | 210 | /* |
@@ -220,6 +224,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | |||
220 | [SCRFDR] = sci_reg_invalid, | 224 | [SCRFDR] = sci_reg_invalid, |
221 | [SCSPTR] = { 0x20, 16 }, | 225 | [SCSPTR] = { 0x20, 16 }, |
222 | [SCLSR] = { 0x24, 16 }, | 226 | [SCLSR] = { 0x24, 16 }, |
227 | [HSSRR] = sci_reg_invalid, | ||
223 | }, | 228 | }, |
224 | 229 | ||
225 | /* | 230 | /* |
@@ -238,6 +243,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | |||
238 | [SCRFDR] = sci_reg_invalid, | 243 | [SCRFDR] = sci_reg_invalid, |
239 | [SCSPTR] = sci_reg_invalid, | 244 | [SCSPTR] = sci_reg_invalid, |
240 | [SCLSR] = sci_reg_invalid, | 245 | [SCLSR] = sci_reg_invalid, |
246 | [HSSRR] = sci_reg_invalid, | ||
241 | }, | 247 | }, |
242 | 248 | ||
243 | /* | 249 | /* |
@@ -256,6 +262,26 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | |||
256 | [SCRFDR] = sci_reg_invalid, | 262 | [SCRFDR] = sci_reg_invalid, |
257 | [SCSPTR] = { 0x20, 16 }, | 263 | [SCSPTR] = { 0x20, 16 }, |
258 | [SCLSR] = { 0x24, 16 }, | 264 | [SCLSR] = { 0x24, 16 }, |
265 | [HSSRR] = sci_reg_invalid, | ||
266 | }, | ||
267 | |||
268 | /* | ||
269 | * Common HSCIF definitions. | ||
270 | */ | ||
271 | [SCIx_HSCIF_REGTYPE] = { | ||
272 | [SCSMR] = { 0x00, 16 }, | ||
273 | [SCBRR] = { 0x04, 8 }, | ||
274 | [SCSCR] = { 0x08, 16 }, | ||
275 | [SCxTDR] = { 0x0c, 8 }, | ||
276 | [SCxSR] = { 0x10, 16 }, | ||
277 | [SCxRDR] = { 0x14, 8 }, | ||
278 | [SCFCR] = { 0x18, 16 }, | ||
279 | [SCFDR] = { 0x1c, 16 }, | ||
280 | [SCTFDR] = sci_reg_invalid, | ||
281 | [SCRFDR] = sci_reg_invalid, | ||
282 | [SCSPTR] = { 0x20, 16 }, | ||
283 | [SCLSR] = { 0x24, 16 }, | ||
284 | [HSSRR] = { 0x40, 16 }, | ||
259 | }, | 285 | }, |
260 | 286 | ||
261 | /* | 287 | /* |
@@ -275,6 +301,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | |||
275 | [SCRFDR] = sci_reg_invalid, | 301 | [SCRFDR] = sci_reg_invalid, |
276 | [SCSPTR] = sci_reg_invalid, | 302 | [SCSPTR] = sci_reg_invalid, |
277 | [SCLSR] = { 0x24, 16 }, | 303 | [SCLSR] = { 0x24, 16 }, |
304 | [HSSRR] = sci_reg_invalid, | ||
278 | }, | 305 | }, |
279 | 306 | ||
280 | /* | 307 | /* |
@@ -294,6 +321,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | |||
294 | [SCRFDR] = { 0x20, 16 }, | 321 | [SCRFDR] = { 0x20, 16 }, |
295 | [SCSPTR] = { 0x24, 16 }, | 322 | [SCSPTR] = { 0x24, 16 }, |
296 | [SCLSR] = { 0x28, 16 }, | 323 | [SCLSR] = { 0x28, 16 }, |
324 | [HSSRR] = sci_reg_invalid, | ||
297 | }, | 325 | }, |
298 | 326 | ||
299 | /* | 327 | /* |
@@ -313,6 +341,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | |||
313 | [SCRFDR] = sci_reg_invalid, | 341 | [SCRFDR] = sci_reg_invalid, |
314 | [SCSPTR] = sci_reg_invalid, | 342 | [SCSPTR] = sci_reg_invalid, |
315 | [SCLSR] = sci_reg_invalid, | 343 | [SCLSR] = sci_reg_invalid, |
344 | [HSSRR] = sci_reg_invalid, | ||
316 | }, | 345 | }, |
317 | }; | 346 | }; |
318 | 347 | ||
@@ -374,6 +403,9 @@ static int sci_probe_regmap(struct plat_sci_port *cfg) | |||
374 | */ | 403 | */ |
375 | cfg->regtype = SCIx_SH4_SCIF_REGTYPE; | 404 | cfg->regtype = SCIx_SH4_SCIF_REGTYPE; |
376 | break; | 405 | break; |
406 | case PORT_HSCIF: | ||
407 | cfg->regtype = SCIx_HSCIF_REGTYPE; | ||
408 | break; | ||
377 | default: | 409 | default: |
378 | printk(KERN_ERR "Can't probe register map for given port\n"); | 410 | printk(KERN_ERR "Can't probe register map for given port\n"); |
379 | return -EINVAL; | 411 | return -EINVAL; |
@@ -1798,6 +1830,42 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, | |||
1798 | return ((freq + 16 * bps) / (32 * bps) - 1); | 1830 | return ((freq + 16 * bps) / (32 * bps) - 1); |
1799 | } | 1831 | } |
1800 | 1832 | ||
1833 | /* calculate sample rate, BRR, and clock select for HSCIF */ | ||
1834 | static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, | ||
1835 | int *brr, unsigned int *srr, | ||
1836 | unsigned int *cks) | ||
1837 | { | ||
1838 | int sr, c, br, err; | ||
1839 | int min_err = 1000; /* 100% */ | ||
1840 | |||
1841 | /* Find the combination of sample rate and clock select with the | ||
1842 | smallest deviation from the desired baud rate. */ | ||
1843 | for (sr = 8; sr <= 32; sr++) { | ||
1844 | for (c = 0; c <= 3; c++) { | ||
1845 | /* integerized formulas from HSCIF documentation */ | ||
1846 | br = freq / (sr * (1 << (2 * c + 1)) * bps) - 1; | ||
1847 | if (br < 0 || br > 255) | ||
1848 | continue; | ||
1849 | err = freq / ((br + 1) * bps * sr * | ||
1850 | (1 << (2 * c + 1)) / 1000) - 1000; | ||
1851 | if (min_err > err) { | ||
1852 | min_err = err; | ||
1853 | *brr = br; | ||
1854 | *srr = sr - 1; | ||
1855 | *cks = c; | ||
1856 | } | ||
1857 | } | ||
1858 | } | ||
1859 | |||
1860 | if (min_err == 1000) { | ||
1861 | WARN_ON(1); | ||
1862 | /* use defaults */ | ||
1863 | *brr = 255; | ||
1864 | *srr = 15; | ||
1865 | *cks = 0; | ||
1866 | } | ||
1867 | } | ||
1868 | |||
1801 | static void sci_reset(struct uart_port *port) | 1869 | static void sci_reset(struct uart_port *port) |
1802 | { | 1870 | { |
1803 | struct plat_sci_reg *reg; | 1871 | struct plat_sci_reg *reg; |
@@ -1819,8 +1887,9 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1819 | { | 1887 | { |
1820 | struct sci_port *s = to_sci_port(port); | 1888 | struct sci_port *s = to_sci_port(port); |
1821 | struct plat_sci_reg *reg; | 1889 | struct plat_sci_reg *reg; |
1822 | unsigned int baud, smr_val, max_baud, cks; | 1890 | unsigned int baud, smr_val, max_baud, cks = 0; |
1823 | int t = -1; | 1891 | int t = -1; |
1892 | unsigned int srr = 15; | ||
1824 | 1893 | ||
1825 | /* | 1894 | /* |
1826 | * earlyprintk comes here early on with port->uartclk set to zero. | 1895 | * earlyprintk comes here early on with port->uartclk set to zero. |
@@ -1833,8 +1902,17 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1833 | max_baud = port->uartclk ? port->uartclk / 16 : 115200; | 1902 | max_baud = port->uartclk ? port->uartclk / 16 : 115200; |
1834 | 1903 | ||
1835 | baud = uart_get_baud_rate(port, termios, old, 0, max_baud); | 1904 | baud = uart_get_baud_rate(port, termios, old, 0, max_baud); |
1836 | if (likely(baud && port->uartclk)) | 1905 | if (likely(baud && port->uartclk)) { |
1837 | t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, port->uartclk); | 1906 | if (s->cfg->scbrr_algo_id == SCBRR_ALGO_6) { |
1907 | sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, | ||
1908 | &cks); | ||
1909 | } else { | ||
1910 | t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, | ||
1911 | port->uartclk); | ||
1912 | for (cks = 0; t >= 256 && cks <= 3; cks++) | ||
1913 | t >>= 2; | ||
1914 | } | ||
1915 | } | ||
1838 | 1916 | ||
1839 | sci_port_enable(s); | 1917 | sci_port_enable(s); |
1840 | 1918 | ||
@@ -1853,15 +1931,15 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1853 | 1931 | ||
1854 | uart_update_timeout(port, termios->c_cflag, baud); | 1932 | uart_update_timeout(port, termios->c_cflag, baud); |
1855 | 1933 | ||
1856 | for (cks = 0; t >= 256 && cks <= 3; cks++) | ||
1857 | t >>= 2; | ||
1858 | |||
1859 | dev_dbg(port->dev, "%s: SMR %x, cks %x, t %x, SCSCR %x\n", | 1934 | dev_dbg(port->dev, "%s: SMR %x, cks %x, t %x, SCSCR %x\n", |
1860 | __func__, smr_val, cks, t, s->cfg->scscr); | 1935 | __func__, smr_val, cks, t, s->cfg->scscr); |
1861 | 1936 | ||
1862 | if (t >= 0) { | 1937 | if (t >= 0) { |
1863 | serial_port_out(port, SCSMR, (smr_val & ~3) | cks); | 1938 | serial_port_out(port, SCSMR, (smr_val & ~3) | cks); |
1864 | serial_port_out(port, SCBRR, t); | 1939 | serial_port_out(port, SCBRR, t); |
1940 | reg = sci_getreg(port, HSSRR); | ||
1941 | if (reg->size) | ||
1942 | serial_port_out(port, HSSRR, srr | HSCIF_SRE); | ||
1865 | udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ | 1943 | udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ |
1866 | } else | 1944 | } else |
1867 | serial_port_out(port, SCSMR, smr_val); | 1945 | serial_port_out(port, SCSMR, smr_val); |
@@ -1947,6 +2025,8 @@ static const char *sci_type(struct uart_port *port) | |||
1947 | return "scifa"; | 2025 | return "scifa"; |
1948 | case PORT_SCIFB: | 2026 | case PORT_SCIFB: |
1949 | return "scifb"; | 2027 | return "scifb"; |
2028 | case PORT_HSCIF: | ||
2029 | return "hscif"; | ||
1950 | } | 2030 | } |
1951 | 2031 | ||
1952 | return NULL; | 2032 | return NULL; |
@@ -1960,7 +2040,10 @@ static inline unsigned long sci_port_size(struct uart_port *port) | |||
1960 | * from platform resource data at such a time that ports begin to | 2040 | * from platform resource data at such a time that ports begin to |
1961 | * behave more erratically. | 2041 | * behave more erratically. |
1962 | */ | 2042 | */ |
1963 | return 64; | 2043 | if (port->type == PORT_HSCIF) |
2044 | return 96; | ||
2045 | else | ||
2046 | return 64; | ||
1964 | } | 2047 | } |
1965 | 2048 | ||
1966 | static int sci_remap_port(struct uart_port *port) | 2049 | static int sci_remap_port(struct uart_port *port) |
@@ -2085,6 +2168,9 @@ static int sci_init_single(struct platform_device *dev, | |||
2085 | case PORT_SCIFB: | 2168 | case PORT_SCIFB: |
2086 | port->fifosize = 256; | 2169 | port->fifosize = 256; |
2087 | break; | 2170 | break; |
2171 | case PORT_HSCIF: | ||
2172 | port->fifosize = 128; | ||
2173 | break; | ||
2088 | case PORT_SCIFA: | 2174 | case PORT_SCIFA: |
2089 | port->fifosize = 64; | 2175 | port->fifosize = 64; |
2090 | break; | 2176 | break; |
@@ -2325,7 +2411,7 @@ static inline int sci_probe_earlyprintk(struct platform_device *pdev) | |||
2325 | #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ | 2411 | #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ |
2326 | 2412 | ||
2327 | static char banner[] __initdata = | 2413 | static char banner[] __initdata = |
2328 | KERN_INFO "SuperH SCI(F) driver initialized\n"; | 2414 | KERN_INFO "SuperH (H)SCI(F) driver initialized\n"; |
2329 | 2415 | ||
2330 | static struct uart_driver sci_uart_driver = { | 2416 | static struct uart_driver sci_uart_driver = { |
2331 | .owner = THIS_MODULE, | 2417 | .owner = THIS_MODULE, |
@@ -2484,4 +2570,4 @@ module_exit(sci_exit); | |||
2484 | MODULE_LICENSE("GPL"); | 2570 | MODULE_LICENSE("GPL"); |
2485 | MODULE_ALIAS("platform:sh-sci"); | 2571 | MODULE_ALIAS("platform:sh-sci"); |
2486 | MODULE_AUTHOR("Paul Mundt"); | 2572 | MODULE_AUTHOR("Paul Mundt"); |
2487 | MODULE_DESCRIPTION("SuperH SCI(F) serial driver"); | 2573 | MODULE_DESCRIPTION("SuperH (H)SCI(F) serial driver"); |
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index fbd447b390f7..740202d8a5c4 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
@@ -779,7 +779,6 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */ | |||
779 | con_set_default_unimap(vc); | 779 | con_set_default_unimap(vc); |
780 | vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL); | 780 | vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL); |
781 | if (!vc->vc_screenbuf) { | 781 | if (!vc->vc_screenbuf) { |
782 | tty_port_destroy(&vc->port); | ||
783 | kfree(vc); | 782 | kfree(vc); |
784 | vc_cons[currcons].d = NULL; | 783 | vc_cons[currcons].d = NULL; |
785 | return -ENOMEM; | 784 | return -ENOMEM; |
@@ -986,26 +985,25 @@ static int vt_resize(struct tty_struct *tty, struct winsize *ws) | |||
986 | return ret; | 985 | return ret; |
987 | } | 986 | } |
988 | 987 | ||
989 | void vc_deallocate(unsigned int currcons) | 988 | struct vc_data *vc_deallocate(unsigned int currcons) |
990 | { | 989 | { |
990 | struct vc_data *vc = NULL; | ||
991 | |||
991 | WARN_CONSOLE_UNLOCKED(); | 992 | WARN_CONSOLE_UNLOCKED(); |
992 | 993 | ||
993 | if (vc_cons_allocated(currcons)) { | 994 | if (vc_cons_allocated(currcons)) { |
994 | struct vc_data *vc = vc_cons[currcons].d; | 995 | struct vt_notifier_param param; |
995 | struct vt_notifier_param param = { .vc = vc }; | ||
996 | 996 | ||
997 | param.vc = vc = vc_cons[currcons].d; | ||
997 | atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, ¶m); | 998 | atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, ¶m); |
998 | vcs_remove_sysfs(currcons); | 999 | vcs_remove_sysfs(currcons); |
999 | vc->vc_sw->con_deinit(vc); | 1000 | vc->vc_sw->con_deinit(vc); |
1000 | put_pid(vc->vt_pid); | 1001 | put_pid(vc->vt_pid); |
1001 | module_put(vc->vc_sw->owner); | 1002 | module_put(vc->vc_sw->owner); |
1002 | kfree(vc->vc_screenbuf); | 1003 | kfree(vc->vc_screenbuf); |
1003 | if (currcons >= MIN_NR_CONSOLES) { | ||
1004 | tty_port_destroy(&vc->port); | ||
1005 | kfree(vc); | ||
1006 | } | ||
1007 | vc_cons[currcons].d = NULL; | 1004 | vc_cons[currcons].d = NULL; |
1008 | } | 1005 | } |
1006 | return vc; | ||
1009 | } | 1007 | } |
1010 | 1008 | ||
1011 | /* | 1009 | /* |
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 98ff1735eafc..fc2c06c66e89 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c | |||
@@ -283,6 +283,51 @@ do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, struct vc_ | |||
283 | return 0; | 283 | return 0; |
284 | } | 284 | } |
285 | 285 | ||
286 | /* deallocate a single console, if possible (leave 0) */ | ||
287 | static int vt_disallocate(unsigned int vc_num) | ||
288 | { | ||
289 | struct vc_data *vc = NULL; | ||
290 | int ret = 0; | ||
291 | |||
292 | if (!vc_num) | ||
293 | return 0; | ||
294 | |||
295 | console_lock(); | ||
296 | if (VT_BUSY(vc_num)) | ||
297 | ret = -EBUSY; | ||
298 | else | ||
299 | vc = vc_deallocate(vc_num); | ||
300 | console_unlock(); | ||
301 | |||
302 | if (vc && vc_num >= MIN_NR_CONSOLES) { | ||
303 | tty_port_destroy(&vc->port); | ||
304 | kfree(vc); | ||
305 | } | ||
306 | |||
307 | return ret; | ||
308 | } | ||
309 | |||
310 | /* deallocate all unused consoles, but leave 0 */ | ||
311 | static void vt_disallocate_all(void) | ||
312 | { | ||
313 | struct vc_data *vc[MAX_NR_CONSOLES]; | ||
314 | int i; | ||
315 | |||
316 | console_lock(); | ||
317 | for (i = 1; i < MAX_NR_CONSOLES; i++) | ||
318 | if (!VT_BUSY(i)) | ||
319 | vc[i] = vc_deallocate(i); | ||
320 | else | ||
321 | vc[i] = NULL; | ||
322 | console_unlock(); | ||
323 | |||
324 | for (i = 1; i < MAX_NR_CONSOLES; i++) { | ||
325 | if (vc[i] && i >= MIN_NR_CONSOLES) { | ||
326 | tty_port_destroy(&vc[i]->port); | ||
327 | kfree(vc[i]); | ||
328 | } | ||
329 | } | ||
330 | } | ||
286 | 331 | ||
287 | 332 | ||
288 | /* | 333 | /* |
@@ -769,24 +814,10 @@ int vt_ioctl(struct tty_struct *tty, | |||
769 | ret = -ENXIO; | 814 | ret = -ENXIO; |
770 | break; | 815 | break; |
771 | } | 816 | } |
772 | if (arg == 0) { | 817 | if (arg == 0) |
773 | /* deallocate all unused consoles, but leave 0 */ | 818 | vt_disallocate_all(); |
774 | console_lock(); | 819 | else |
775 | for (i=1; i<MAX_NR_CONSOLES; i++) | 820 | ret = vt_disallocate(--arg); |
776 | if (! VT_BUSY(i)) | ||
777 | vc_deallocate(i); | ||
778 | console_unlock(); | ||
779 | } else { | ||
780 | /* deallocate a single console, if possible */ | ||
781 | arg--; | ||
782 | if (VT_BUSY(arg)) | ||
783 | ret = -EBUSY; | ||
784 | else if (arg) { /* leave 0 */ | ||
785 | console_lock(); | ||
786 | vc_deallocate(arg); | ||
787 | console_unlock(); | ||
788 | } | ||
789 | } | ||
790 | break; | 821 | break; |
791 | 822 | ||
792 | case VT_RESIZE: | 823 | case VT_RESIZE: |