Merge branch 'tty-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6
* 'tty-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6: serial: bcm63xx_uart: fix irq storm after rx fifo overrun. amba pl011: platform data for reg lockup and glitch v2 amba pl011: workaround for uart registers lockup tty: n_gsm: improper skb_pull() use was leaking framed data tty: n_gsm: Fixed logic to decode break signal from modem status TTY: ntty, add one more sanity check TTY: ldisc, do not close until there are readers 8250: Fix capabilities when changing the port type 8250_pci: Fix missing const from merges ARM: SAMSUNG: serial: Fix on handling of one clock source for UART serial: ioremap warning fix for jsm driver. 8250_pci: add -ENODEV code for Intel EG20T PCH
This commit is contained in:
Коммит
04b905942b
|
@ -35,6 +35,7 @@ void __init exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
|
|||
tcfg->clocks = exynos4_serial_clocks;
|
||||
tcfg->clocks_size = ARRAY_SIZE(exynos4_serial_clocks);
|
||||
}
|
||||
tcfg->flags |= NO_NEED_CHECK_CLKSRC;
|
||||
}
|
||||
|
||||
s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no);
|
||||
|
|
|
@ -110,10 +110,18 @@ static pin_cfg_t mop500_pins_common[] = {
|
|||
GPIO168_KP_O0,
|
||||
|
||||
/* UART */
|
||||
GPIO0_U0_CTSn | PIN_INPUT_PULLUP,
|
||||
GPIO1_U0_RTSn | PIN_OUTPUT_HIGH,
|
||||
GPIO2_U0_RXD | PIN_INPUT_PULLUP,
|
||||
GPIO3_U0_TXD | PIN_OUTPUT_HIGH,
|
||||
/* uart-0 pins gpio configuration should be
|
||||
* kept intact to prevent glitch in tx line
|
||||
* when tty dev is opened. Later these pins
|
||||
* are configured to uart mop500_pins_uart0
|
||||
*
|
||||
* It will be replaced with uart configuration
|
||||
* once the issue is solved.
|
||||
*/
|
||||
GPIO0_GPIO | PIN_INPUT_PULLUP,
|
||||
GPIO1_GPIO | PIN_OUTPUT_HIGH,
|
||||
GPIO2_GPIO | PIN_INPUT_PULLUP,
|
||||
GPIO3_GPIO | PIN_OUTPUT_HIGH,
|
||||
|
||||
GPIO29_U2_RXD | PIN_INPUT_PULLUP,
|
||||
GPIO30_U2_TXD | PIN_OUTPUT_HIGH,
|
||||
|
|
|
@ -27,18 +27,21 @@
|
|||
#include <linux/leds-lp5521.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
#include <plat/i2c.h>
|
||||
#include <plat/ste_dma40.h>
|
||||
#include <plat/pincfg.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/setup.h>
|
||||
#include <mach/devices.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
#include "pins-db8500.h"
|
||||
#include "ste-dma40-db8500.h"
|
||||
#include "devices-db8500.h"
|
||||
#include "board-mop500.h"
|
||||
|
@ -393,12 +396,63 @@ static struct stedma40_chan_cfg uart2_dma_cfg_tx = {
|
|||
};
|
||||
#endif
|
||||
|
||||
|
||||
static pin_cfg_t mop500_pins_uart0[] = {
|
||||
GPIO0_U0_CTSn | PIN_INPUT_PULLUP,
|
||||
GPIO1_U0_RTSn | PIN_OUTPUT_HIGH,
|
||||
GPIO2_U0_RXD | PIN_INPUT_PULLUP,
|
||||
GPIO3_U0_TXD | PIN_OUTPUT_HIGH,
|
||||
};
|
||||
|
||||
#define PRCC_K_SOFTRST_SET 0x18
|
||||
#define PRCC_K_SOFTRST_CLEAR 0x1C
|
||||
static void ux500_uart0_reset(void)
|
||||
{
|
||||
void __iomem *prcc_rst_set, *prcc_rst_clr;
|
||||
|
||||
prcc_rst_set = (void __iomem *)IO_ADDRESS(U8500_CLKRST1_BASE +
|
||||
PRCC_K_SOFTRST_SET);
|
||||
prcc_rst_clr = (void __iomem *)IO_ADDRESS(U8500_CLKRST1_BASE +
|
||||
PRCC_K_SOFTRST_CLEAR);
|
||||
|
||||
/* Activate soft reset PRCC_K_SOFTRST_CLEAR */
|
||||
writel((readl(prcc_rst_clr) | 0x1), prcc_rst_clr);
|
||||
udelay(1);
|
||||
|
||||
/* Release soft reset PRCC_K_SOFTRST_SET */
|
||||
writel((readl(prcc_rst_set) | 0x1), prcc_rst_set);
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
static void ux500_uart0_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = nmk_config_pins(mop500_pins_uart0,
|
||||
ARRAY_SIZE(mop500_pins_uart0));
|
||||
if (ret < 0)
|
||||
pr_err("pl011: uart pins_enable failed\n");
|
||||
}
|
||||
|
||||
static void ux500_uart0_exit(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = nmk_config_pins_sleep(mop500_pins_uart0,
|
||||
ARRAY_SIZE(mop500_pins_uart0));
|
||||
if (ret < 0)
|
||||
pr_err("pl011: uart pins_disable failed\n");
|
||||
}
|
||||
|
||||
static struct amba_pl011_data uart0_plat = {
|
||||
#ifdef CONFIG_STE_DMA40
|
||||
.dma_filter = stedma40_filter,
|
||||
.dma_rx_param = &uart0_dma_cfg_rx,
|
||||
.dma_tx_param = &uart0_dma_cfg_tx,
|
||||
#endif
|
||||
.init = ux500_uart0_init,
|
||||
.exit = ux500_uart0_exit,
|
||||
.reset = ux500_uart0_reset,
|
||||
};
|
||||
|
||||
static struct amba_pl011_data uart1_plat = {
|
||||
|
|
|
@ -224,6 +224,8 @@
|
|||
#define S5PV210_UFSTAT_RXMASK (255<<0)
|
||||
#define S5PV210_UFSTAT_RXSHIFT (0)
|
||||
|
||||
#define NO_NEED_CHECK_CLKSRC 1
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* struct s3c24xx_uart_clksrc
|
||||
|
|
|
@ -875,7 +875,8 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm,
|
|||
*dp++ = last << 7 | first << 6 | 1; /* EA */
|
||||
len--;
|
||||
}
|
||||
memcpy(dp, skb_pull(dlci->skb, len), len);
|
||||
memcpy(dp, dlci->skb->data, len);
|
||||
skb_pull(dlci->skb, len);
|
||||
__gsm_data_queue(dlci, msg);
|
||||
if (last)
|
||||
dlci->skb = NULL;
|
||||
|
@ -984,10 +985,22 @@ static void gsm_control_reply(struct gsm_mux *gsm, int cmd, u8 *data,
|
|||
*/
|
||||
|
||||
static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci,
|
||||
u32 modem)
|
||||
u32 modem, int clen)
|
||||
{
|
||||
int mlines = 0;
|
||||
u8 brk = modem >> 6;
|
||||
u8 brk = 0;
|
||||
|
||||
/* The modem status command can either contain one octet (v.24 signals)
|
||||
or two octets (v.24 signals + break signals). The length field will
|
||||
either be 2 or 3 respectively. This is specified in section
|
||||
5.4.6.3.7 of the 27.010 mux spec. */
|
||||
|
||||
if (clen == 2)
|
||||
modem = modem & 0x7f;
|
||||
else {
|
||||
brk = modem & 0x7f;
|
||||
modem = (modem >> 7) & 0x7f;
|
||||
};
|
||||
|
||||
/* Flow control/ready to communicate */
|
||||
if (modem & MDM_FC) {
|
||||
|
@ -1061,7 +1074,7 @@ static void gsm_control_modem(struct gsm_mux *gsm, u8 *data, int clen)
|
|||
return;
|
||||
}
|
||||
tty = tty_port_tty_get(&dlci->port);
|
||||
gsm_process_modem(tty, dlci, modem);
|
||||
gsm_process_modem(tty, dlci, modem, clen);
|
||||
if (tty) {
|
||||
tty_wakeup(tty);
|
||||
tty_kref_put(tty);
|
||||
|
@ -1482,12 +1495,13 @@ static void gsm_dlci_begin_close(struct gsm_dlci *dlci)
|
|||
* open we shovel the bits down it, if not we drop them.
|
||||
*/
|
||||
|
||||
static void gsm_dlci_data(struct gsm_dlci *dlci, u8 *data, int len)
|
||||
static void gsm_dlci_data(struct gsm_dlci *dlci, u8 *data, int clen)
|
||||
{
|
||||
/* krefs .. */
|
||||
struct tty_port *port = &dlci->port;
|
||||
struct tty_struct *tty = tty_port_tty_get(port);
|
||||
unsigned int modem = 0;
|
||||
int len = clen;
|
||||
|
||||
if (debug & 16)
|
||||
pr_debug("%d bytes for tty %p\n", len, tty);
|
||||
|
@ -1507,7 +1521,7 @@ static void gsm_dlci_data(struct gsm_dlci *dlci, u8 *data, int len)
|
|||
if (len == 0)
|
||||
return;
|
||||
}
|
||||
gsm_process_modem(tty, dlci, modem);
|
||||
gsm_process_modem(tty, dlci, modem, clen);
|
||||
/* Line state will go via DLCI 0 controls only */
|
||||
case 1:
|
||||
default:
|
||||
|
|
|
@ -1815,6 +1815,7 @@ do_it_again:
|
|||
/* FIXME: does n_tty_set_room need locking ? */
|
||||
n_tty_set_room(tty);
|
||||
timeout = schedule_timeout(timeout);
|
||||
BUG_ON(!tty->read_buf);
|
||||
continue;
|
||||
}
|
||||
__set_current_state(TASK_RUNNING);
|
||||
|
|
|
@ -3318,6 +3318,7 @@ void serial8250_unregister_port(int line)
|
|||
uart->port.flags &= ~UPF_BOOT_AUTOCONF;
|
||||
uart->port.type = PORT_UNKNOWN;
|
||||
uart->port.dev = &serial8250_isa_devs->dev;
|
||||
uart->capabilities = uart_config[uart->port.type].flags;
|
||||
uart_add_one_port(&serial8250_reg, &uart->port);
|
||||
} else {
|
||||
uart->port.dev = NULL;
|
||||
|
|
|
@ -994,6 +994,15 @@ static int skip_tx_en_setup(struct serial_private *priv,
|
|||
return pci_default_setup(priv, board, port, idx);
|
||||
}
|
||||
|
||||
static int pci_eg20t_init(struct pci_dev *dev)
|
||||
{
|
||||
#if defined(CONFIG_SERIAL_PCH_UART) || defined(CONFIG_SERIAL_PCH_UART_MODULE)
|
||||
return -ENODEV;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This should be in linux/pci_ids.h */
|
||||
#define PCI_VENDOR_ID_SBSMODULARIO 0x124B
|
||||
#define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B
|
||||
|
@ -1446,6 +1455,56 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
|||
.init = pci_oxsemi_tornado_init,
|
||||
.setup = pci_default_setup,
|
||||
},
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_INTEL,
|
||||
.device = 0x8811,
|
||||
.init = pci_eg20t_init,
|
||||
},
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_INTEL,
|
||||
.device = 0x8812,
|
||||
.init = pci_eg20t_init,
|
||||
},
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_INTEL,
|
||||
.device = 0x8813,
|
||||
.init = pci_eg20t_init,
|
||||
},
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_INTEL,
|
||||
.device = 0x8814,
|
||||
.init = pci_eg20t_init,
|
||||
},
|
||||
{
|
||||
.vendor = 0x10DB,
|
||||
.device = 0x8027,
|
||||
.init = pci_eg20t_init,
|
||||
},
|
||||
{
|
||||
.vendor = 0x10DB,
|
||||
.device = 0x8028,
|
||||
.init = pci_eg20t_init,
|
||||
},
|
||||
{
|
||||
.vendor = 0x10DB,
|
||||
.device = 0x8029,
|
||||
.init = pci_eg20t_init,
|
||||
},
|
||||
{
|
||||
.vendor = 0x10DB,
|
||||
.device = 0x800C,
|
||||
.init = pci_eg20t_init,
|
||||
},
|
||||
{
|
||||
.vendor = 0x10DB,
|
||||
.device = 0x800D,
|
||||
.init = pci_eg20t_init,
|
||||
},
|
||||
{
|
||||
.vendor = 0x10DB,
|
||||
.device = 0x800D,
|
||||
.init = pci_eg20t_init,
|
||||
},
|
||||
/*
|
||||
* Cronyx Omega PCI (PLX-chip based)
|
||||
*/
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include <linux/dmaengine.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/sizes.h>
|
||||
|
@ -65,6 +66,30 @@
|
|||
#define UART_DR_ERROR (UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE)
|
||||
#define UART_DUMMY_DR_RX (1 << 16)
|
||||
|
||||
|
||||
#define UART_WA_SAVE_NR 14
|
||||
|
||||
static void pl011_lockup_wa(unsigned long data);
|
||||
static const u32 uart_wa_reg[UART_WA_SAVE_NR] = {
|
||||
ST_UART011_DMAWM,
|
||||
ST_UART011_TIMEOUT,
|
||||
ST_UART011_LCRH_RX,
|
||||
UART011_IBRD,
|
||||
UART011_FBRD,
|
||||
ST_UART011_LCRH_TX,
|
||||
UART011_IFLS,
|
||||
ST_UART011_XFCR,
|
||||
ST_UART011_XON1,
|
||||
ST_UART011_XON2,
|
||||
ST_UART011_XOFF1,
|
||||
ST_UART011_XOFF2,
|
||||
UART011_CR,
|
||||
UART011_IMSC
|
||||
};
|
||||
|
||||
static u32 uart_wa_regdata[UART_WA_SAVE_NR];
|
||||
static DECLARE_TASKLET(pl011_lockup_tlet, pl011_lockup_wa, 0);
|
||||
|
||||
/* There is by now at least one vendor with differing details, so handle it */
|
||||
struct vendor_data {
|
||||
unsigned int ifls;
|
||||
|
@ -72,6 +97,7 @@ struct vendor_data {
|
|||
unsigned int lcrh_tx;
|
||||
unsigned int lcrh_rx;
|
||||
bool oversampling;
|
||||
bool interrupt_may_hang; /* vendor-specific */
|
||||
bool dma_threshold;
|
||||
};
|
||||
|
||||
|
@ -90,9 +116,12 @@ static struct vendor_data vendor_st = {
|
|||
.lcrh_tx = ST_UART011_LCRH_TX,
|
||||
.lcrh_rx = ST_UART011_LCRH_RX,
|
||||
.oversampling = true,
|
||||
.interrupt_may_hang = true,
|
||||
.dma_threshold = true,
|
||||
};
|
||||
|
||||
static struct uart_amba_port *amba_ports[UART_NR];
|
||||
|
||||
/* Deals with DMA transactions */
|
||||
|
||||
struct pl011_sgbuf {
|
||||
|
@ -132,6 +161,7 @@ struct uart_amba_port {
|
|||
unsigned int lcrh_rx; /* vendor-specific */
|
||||
bool autorts;
|
||||
char type[12];
|
||||
bool interrupt_may_hang; /* vendor-specific */
|
||||
#ifdef CONFIG_DMA_ENGINE
|
||||
/* DMA stuff */
|
||||
bool using_tx_dma;
|
||||
|
@ -1008,6 +1038,68 @@ static inline bool pl011_dma_rx_running(struct uart_amba_port *uap)
|
|||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* pl011_lockup_wa
|
||||
* This workaround aims to break the deadlock situation
|
||||
* when after long transfer over uart in hardware flow
|
||||
* control, uart interrupt registers cannot be cleared.
|
||||
* Hence uart transfer gets blocked.
|
||||
*
|
||||
* It is seen that during such deadlock condition ICR
|
||||
* don't get cleared even on multiple write. This leads
|
||||
* pass_counter to decrease and finally reach zero. This
|
||||
* can be taken as trigger point to run this UART_BT_WA.
|
||||
*
|
||||
*/
|
||||
static void pl011_lockup_wa(unsigned long data)
|
||||
{
|
||||
struct uart_amba_port *uap = amba_ports[0];
|
||||
void __iomem *base = uap->port.membase;
|
||||
struct circ_buf *xmit = &uap->port.state->xmit;
|
||||
struct tty_struct *tty = uap->port.state->port.tty;
|
||||
int buf_empty_retries = 200;
|
||||
int loop;
|
||||
|
||||
/* Stop HCI layer from submitting data for tx */
|
||||
tty->hw_stopped = 1;
|
||||
while (!uart_circ_empty(xmit)) {
|
||||
if (buf_empty_retries-- == 0)
|
||||
break;
|
||||
udelay(100);
|
||||
}
|
||||
|
||||
/* Backup registers */
|
||||
for (loop = 0; loop < UART_WA_SAVE_NR; loop++)
|
||||
uart_wa_regdata[loop] = readl(base + uart_wa_reg[loop]);
|
||||
|
||||
/* Disable UART so that FIFO data is flushed out */
|
||||
writew(0x00, uap->port.membase + UART011_CR);
|
||||
|
||||
/* Soft reset UART module */
|
||||
if (uap->port.dev->platform_data) {
|
||||
struct amba_pl011_data *plat;
|
||||
|
||||
plat = uap->port.dev->platform_data;
|
||||
if (plat->reset)
|
||||
plat->reset();
|
||||
}
|
||||
|
||||
/* Restore registers */
|
||||
for (loop = 0; loop < UART_WA_SAVE_NR; loop++)
|
||||
writew(uart_wa_regdata[loop] ,
|
||||
uap->port.membase + uart_wa_reg[loop]);
|
||||
|
||||
/* Initialise the old status of the modem signals */
|
||||
uap->old_status = readw(uap->port.membase + UART01x_FR) &
|
||||
UART01x_FR_MODEM_ANY;
|
||||
|
||||
if (readl(base + UART011_MIS) & 0x2)
|
||||
printk(KERN_EMERG "UART_BT_WA: ***FAILED***\n");
|
||||
|
||||
/* Start Tx/Rx */
|
||||
tty->hw_stopped = 0;
|
||||
}
|
||||
|
||||
static void pl011_stop_tx(struct uart_port *port)
|
||||
{
|
||||
struct uart_amba_port *uap = (struct uart_amba_port *)port;
|
||||
|
@ -1158,8 +1250,11 @@ static irqreturn_t pl011_int(int irq, void *dev_id)
|
|||
if (status & UART011_TXIS)
|
||||
pl011_tx_chars(uap);
|
||||
|
||||
if (pass_counter-- == 0)
|
||||
if (pass_counter-- == 0) {
|
||||
if (uap->interrupt_may_hang)
|
||||
tasklet_schedule(&pl011_lockup_tlet);
|
||||
break;
|
||||
}
|
||||
|
||||
status = readw(uap->port.membase + UART011_MIS);
|
||||
} while (status != 0);
|
||||
|
@ -1339,6 +1434,14 @@ static int pl011_startup(struct uart_port *port)
|
|||
writew(uap->im, uap->port.membase + UART011_IMSC);
|
||||
spin_unlock_irq(&uap->port.lock);
|
||||
|
||||
if (uap->port.dev->platform_data) {
|
||||
struct amba_pl011_data *plat;
|
||||
|
||||
plat = uap->port.dev->platform_data;
|
||||
if (plat->init)
|
||||
plat->init();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
clk_dis:
|
||||
|
@ -1394,6 +1497,15 @@ static void pl011_shutdown(struct uart_port *port)
|
|||
* Shut down the clock producer
|
||||
*/
|
||||
clk_disable(uap->clk);
|
||||
|
||||
if (uap->port.dev->platform_data) {
|
||||
struct amba_pl011_data *plat;
|
||||
|
||||
plat = uap->port.dev->platform_data;
|
||||
if (plat->exit)
|
||||
plat->exit();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1700,6 +1812,14 @@ static int __init pl011_console_setup(struct console *co, char *options)
|
|||
if (!uap)
|
||||
return -ENODEV;
|
||||
|
||||
if (uap->port.dev->platform_data) {
|
||||
struct amba_pl011_data *plat;
|
||||
|
||||
plat = uap->port.dev->platform_data;
|
||||
if (plat->init)
|
||||
plat->init();
|
||||
}
|
||||
|
||||
uap->port.uartclk = clk_get_rate(uap->clk);
|
||||
|
||||
if (options)
|
||||
|
@ -1774,6 +1894,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
|
|||
uap->lcrh_rx = vendor->lcrh_rx;
|
||||
uap->lcrh_tx = vendor->lcrh_tx;
|
||||
uap->fifosize = vendor->fifosize;
|
||||
uap->interrupt_may_hang = vendor->interrupt_may_hang;
|
||||
uap->port.dev = &dev->dev;
|
||||
uap->port.mapbase = dev->res.start;
|
||||
uap->port.membase = base;
|
||||
|
|
|
@ -250,6 +250,20 @@ static void bcm_uart_do_rx(struct uart_port *port)
|
|||
/* get overrun/fifo empty information from ier
|
||||
* register */
|
||||
iestat = bcm_uart_readl(port, UART_IR_REG);
|
||||
|
||||
if (unlikely(iestat & UART_IR_STAT(UART_IR_RXOVER))) {
|
||||
unsigned int val;
|
||||
|
||||
/* fifo reset is required to clear
|
||||
* interrupt */
|
||||
val = bcm_uart_readl(port, UART_CTL_REG);
|
||||
val |= UART_CTL_RSTRXFIFO_MASK;
|
||||
bcm_uart_writel(port, val, UART_CTL_REG);
|
||||
|
||||
port->icount.overrun++;
|
||||
tty_insert_flip_char(tty, 0, TTY_OVERRUN);
|
||||
}
|
||||
|
||||
if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY)))
|
||||
break;
|
||||
|
||||
|
@ -284,10 +298,6 @@ static void bcm_uart_do_rx(struct uart_port *port)
|
|||
if (uart_handle_sysrq_char(port, c))
|
||||
continue;
|
||||
|
||||
if (unlikely(iestat & UART_IR_STAT(UART_IR_RXOVER))) {
|
||||
port->icount.overrun++;
|
||||
tty_insert_flip_char(tty, 0, TTY_OVERRUN);
|
||||
}
|
||||
|
||||
if ((cstat & port->ignore_status_mask) == 0)
|
||||
tty_insert_flip_char(tty, c, flag);
|
||||
|
|
|
@ -125,7 +125,7 @@ static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device
|
|||
brd->bd_uart_offset = 0x200;
|
||||
brd->bd_dividend = 921600;
|
||||
|
||||
brd->re_map_membase = ioremap(brd->membase, 0x1000);
|
||||
brd->re_map_membase = ioremap(brd->membase, pci_resource_len(pdev, 0));
|
||||
if (!brd->re_map_membase) {
|
||||
dev_err(&pdev->dev,
|
||||
"card has no PCI Memory resources, "
|
||||
|
|
|
@ -30,7 +30,7 @@ static int s5pv210_serial_setsource(struct uart_port *port,
|
|||
struct s3c2410_uartcfg *cfg = port->dev->platform_data;
|
||||
unsigned long ucon = rd_regl(port, S3C2410_UCON);
|
||||
|
||||
if ((cfg->clocks_size) == 1)
|
||||
if (cfg->flags & NO_NEED_CHECK_CLKSRC)
|
||||
return 0;
|
||||
|
||||
if (strcmp(clk->name, "pclk") == 0)
|
||||
|
@ -55,7 +55,7 @@ static int s5pv210_serial_getsource(struct uart_port *port,
|
|||
|
||||
clk->divisor = 1;
|
||||
|
||||
if ((cfg->clocks_size) == 1)
|
||||
if (cfg->flags & NO_NEED_CHECK_CLKSRC)
|
||||
return 0;
|
||||
|
||||
switch (ucon & S5PV210_UCON_CLKMASK) {
|
||||
|
|
|
@ -555,7 +555,7 @@ static void tty_ldisc_flush_works(struct tty_struct *tty)
|
|||
static int tty_ldisc_wait_idle(struct tty_struct *tty)
|
||||
{
|
||||
int ret;
|
||||
ret = wait_event_interruptible_timeout(tty_ldisc_idle,
|
||||
ret = wait_event_timeout(tty_ldisc_idle,
|
||||
atomic_read(&tty->ldisc->users) == 1, 5 * HZ);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -763,6 +763,8 @@ static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc)
|
|||
if (IS_ERR(ld))
|
||||
return -1;
|
||||
|
||||
WARN_ON_ONCE(tty_ldisc_wait_idle(tty));
|
||||
|
||||
tty_ldisc_close(tty, tty->ldisc);
|
||||
tty_ldisc_put(tty->ldisc);
|
||||
tty->ldisc = NULL;
|
||||
|
|
|
@ -201,6 +201,9 @@ struct amba_pl011_data {
|
|||
bool (*dma_filter)(struct dma_chan *chan, void *filter_param);
|
||||
void *dma_rx_param;
|
||||
void *dma_tx_param;
|
||||
void (*init) (void);
|
||||
void (*exit) (void);
|
||||
void (*reset) (void);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче