Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e37aa63e authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'for-linus-20121212' of...

Merge tag 'for-linus-20121212' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-mn10300

Pull MN10300 changes from David Howells:
 "miscellaneous MN10300 arch patches.  I've based it on top of Al Viro's
  signal tree - so these patches should be pulled after that."

* tag 'for-linus-20121212' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-mn10300:
  MN10300: Use asm-generic/pci_iomap.h
  MN10300: Get rid of unused variable from ASB2305 PCI code
  MN10300: ASB2305 PCI code needs linux/irq.h
  mn10300/mm/fault.c: Port OOM changes to do_page_fault
  MN10300: Handle cacheable PCI regions in pci_iomap()
  MN10300: fix debug polling in ttySM driver
  MN10300: ttySM: clean up unnecessary casting
  MN10300: fix SMP synchronization between txdma and serial driver
  MN10300: fix serial port vdma irq setup for SMP
  MN10300: cleanup IRQ affinity setting
  MN10300: ttySM: Use memory barriers correctly in circular buffer logic
parents 9977d9b3 76583cff
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -14,6 +14,7 @@
#include <asm/page.h> /* I/O is all done through memory accesses */
#include <asm/page.h> /* I/O is all done through memory accesses */
#include <asm/cpu-regs.h>
#include <asm/cpu-regs.h>
#include <asm/cacheflush.h>
#include <asm/cacheflush.h>
#include <asm-generic/pci_iomap.h>


#define mmiowb() do {} while (0)
#define mmiowb() do {} while (0)


@@ -258,7 +259,7 @@ static inline void __iomem *__ioremap(unsigned long offset, unsigned long size,


static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
{
{
	return (void __iomem *) offset;
	return (void __iomem *)(offset & ~0x20000000);
}
}


/*
/*
+1 −1
Original line number Original line Diff line number Diff line
@@ -96,7 +96,7 @@ void foo(void)
	OFFSET(__rx_outp,		mn10300_serial_port, rx_outp);
	OFFSET(__rx_outp,		mn10300_serial_port, rx_outp);
	OFFSET(__uart_state,		mn10300_serial_port, uart.state);
	OFFSET(__uart_state,		mn10300_serial_port, uart.state);
	OFFSET(__tx_xchar,		mn10300_serial_port, tx_xchar);
	OFFSET(__tx_xchar,		mn10300_serial_port, tx_xchar);
	OFFSET(__tx_break,		mn10300_serial_port, tx_break);
	OFFSET(__tx_flags,		mn10300_serial_port, tx_flags);
	OFFSET(__intr_flags,		mn10300_serial_port, intr_flags);
	OFFSET(__intr_flags,		mn10300_serial_port, intr_flags);
	OFFSET(__rx_icr,		mn10300_serial_port, rx_icr);
	OFFSET(__rx_icr,		mn10300_serial_port, rx_icr);
	OFFSET(__tx_icr,		mn10300_serial_port, tx_icr);
	OFFSET(__tx_icr,		mn10300_serial_port, tx_icr);
+2 −48
Original line number Original line Diff line number Diff line
@@ -142,57 +142,11 @@ mn10300_cpupic_setaffinity(struct irq_data *d, const struct cpumask *mask,
			   bool force)
			   bool force)
{
{
	unsigned long flags;
	unsigned long flags;
	int err;


	flags = arch_local_cli_save();
	flags = arch_local_cli_save();

	/* check irq no */
	switch (d->irq) {
	case TMJCIRQ:
	case RESCHEDULE_IPI:
	case CALL_FUNC_SINGLE_IPI:
	case LOCAL_TIMER_IPI:
	case FLUSH_CACHE_IPI:
	case CALL_FUNCTION_NMI_IPI:
	case DEBUGGER_NMI_IPI:
#ifdef CONFIG_MN10300_TTYSM0
	case SC0RXIRQ:
	case SC0TXIRQ:
#ifdef CONFIG_MN10300_TTYSM0_TIMER8
	case TM8IRQ:
#elif CONFIG_MN10300_TTYSM0_TIMER2
	case TM2IRQ:
#endif /* CONFIG_MN10300_TTYSM0_TIMER8 */
#endif /* CONFIG_MN10300_TTYSM0 */

#ifdef CONFIG_MN10300_TTYSM1
	case SC1RXIRQ:
	case SC1TXIRQ:
#ifdef CONFIG_MN10300_TTYSM1_TIMER12
	case TM12IRQ:
#elif defined(CONFIG_MN10300_TTYSM1_TIMER9)
	case TM9IRQ:
#elif defined(CONFIG_MN10300_TTYSM1_TIMER3)
	case TM3IRQ:
#endif /* CONFIG_MN10300_TTYSM1_TIMER12 */
#endif /* CONFIG_MN10300_TTYSM1 */

#ifdef CONFIG_MN10300_TTYSM2
	case SC2RXIRQ:
	case SC2TXIRQ:
	case TM10IRQ:
#endif /* CONFIG_MN10300_TTYSM2 */
		err = -1;
		break;

	default:
	set_bit(d->irq, irq_affinity_request);
	set_bit(d->irq, irq_affinity_request);
		err = 0;
		break;
	}

	arch_local_irq_restore(flags);
	arch_local_irq_restore(flags);
	return err;
	return 0;
}
}
#endif /* CONFIG_SMP */
#endif /* CONFIG_SMP */


+6 −3
Original line number Original line Diff line number Diff line
@@ -118,8 +118,8 @@ ENTRY(mn10300_serial_vdma_tx_handler)
	movbu	d2,(e3)			# ACK the interrupt
	movbu	d2,(e3)			# ACK the interrupt
	movhu	(e3),d2			# flush
	movhu	(e3),d2			# flush


	btst	0x01,(__tx_break,a3)	# handle transmit break request
	btst	0xFF,(__tx_flags,a3)	# handle transmit flags
	bne	mnsc_vdma_tx_break
	bne	mnsc_vdma_tx_flags


	movbu	(SCxSTR,e2),d2		# don't try and transmit a char if the
	movbu	(SCxSTR,e2),d2		# don't try and transmit a char if the
					# buffer is not empty
					# buffer is not empty
@@ -171,10 +171,13 @@ mnsc_vdma_tx_empty:
	bset	MNSCx_TX_EMPTY,(__intr_flags,a3)
	bset	MNSCx_TX_EMPTY,(__intr_flags,a3)
	bra	mnsc_vdma_tx_done
	bra	mnsc_vdma_tx_done


mnsc_vdma_tx_break:
mnsc_vdma_tx_flags:
	btst	MNSCx_TX_STOP,(__tx_flags,a3)
	bne	mnsc_vdma_tx_stop
	movhu	(SCxCTR,e2),d2		# turn on break mode
	movhu	(SCxCTR,e2),d2		# turn on break mode
	or	SC01CTR_BKE,d2
	or	SC01CTR_BKE,d2
	movhu	d2,(SCxCTR,e2)
	movhu	d2,(SCxCTR,e2)
mnsc_vdma_tx_stop:
	mov	+(NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL)|GxICR_DETECT),d2
	mov	+(NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL)|GxICR_DETECT),d2
	movhu	d2,(e3)			# disable transmit interrupts on this
	movhu	d2,(e3)			# disable transmit interrupts on this
					# channel
					# channel
+145 −68
Original line number Original line Diff line number Diff line
@@ -408,6 +408,34 @@ static struct irq_chip mn10300_serial_pic = {
	.irq_unmask	= mn10300_serial_nop,
	.irq_unmask	= mn10300_serial_nop,
};
};


static void mn10300_serial_low_mask(struct irq_data *d)
{
	unsigned long flags;
	u16 tmp;

	flags = arch_local_cli_save();
	GxICR(d->irq) = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);
	tmp = GxICR(d->irq); /* flush write buffer */
	arch_local_irq_restore(flags);
}

static void mn10300_serial_low_unmask(struct irq_data *d)
{
	unsigned long flags;
	u16 tmp;

	flags = arch_local_cli_save();
	GxICR(d->irq) =
		NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL) | GxICR_ENABLE;
	tmp = GxICR(d->irq); /* flush write buffer */
	arch_local_irq_restore(flags);
}

static struct irq_chip mn10300_serial_low_pic = {
	.name		= "mnserial-low",
	.irq_mask	= mn10300_serial_low_mask,
	.irq_unmask	= mn10300_serial_low_unmask,
};


/*
/*
 * serial virtual DMA interrupt jump table
 * serial virtual DMA interrupt jump table
@@ -416,25 +444,53 @@ struct mn10300_serial_int mn10300_serial_int_tbl[NR_IRQS];


static void mn10300_serial_dis_tx_intr(struct mn10300_serial_port *port)
static void mn10300_serial_dis_tx_intr(struct mn10300_serial_port *port)
{
{
	unsigned long flags;
	int retries = 100;
	u16 x;
	u16 x;


	flags = arch_local_cli_save();
	/* nothing to do if irq isn't set up */
	*port->tx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);
	if (!mn10300_serial_int_tbl[port->tx_irq].port)
		return;

	port->tx_flags |= MNSCx_TX_STOP;
	mb();

	/*
	 * Here we wait for the irq to be disabled. Either it already is
	 * disabled or we wait some number of retries for the VDMA handler
	 * to disable it. The retries give the VDMA handler enough time to
	 * run to completion if it was already in progress. If the VDMA IRQ
	 * is enabled but the handler is not yet running when arrive here,
	 * the STOP flag will prevent the handler from conflicting with the
	 * driver code following this loop.
	 */
	while ((*port->tx_icr & GxICR_ENABLE) && retries-- > 0)
		;
	if (retries <= 0) {
		*port->tx_icr =
			NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);
		x = *port->tx_icr;
		x = *port->tx_icr;
	arch_local_irq_restore(flags);
	}
}
}


static void mn10300_serial_en_tx_intr(struct mn10300_serial_port *port)
static void mn10300_serial_en_tx_intr(struct mn10300_serial_port *port)
{
{
	unsigned long flags;
	u16 x;
	u16 x;


	flags = arch_local_cli_save();
	/* nothing to do if irq isn't set up */
	if (!mn10300_serial_int_tbl[port->tx_irq].port)
		return;

	/* stop vdma irq if not already stopped */
	if (!(port->tx_flags & MNSCx_TX_STOP))
		mn10300_serial_dis_tx_intr(port);

	port->tx_flags &= ~MNSCx_TX_STOP;
	mb();

	*port->tx_icr =
	*port->tx_icr =
		NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL) | GxICR_ENABLE;
		NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL) |
		GxICR_ENABLE | GxICR_REQUEST | GxICR_DETECT;
	x = *port->tx_icr;
	x = *port->tx_icr;
	arch_local_irq_restore(flags);
}
}


static void mn10300_serial_dis_rx_intr(struct mn10300_serial_port *port)
static void mn10300_serial_dis_rx_intr(struct mn10300_serial_port *port)
@@ -487,16 +543,17 @@ static void mn10300_serial_receive_interrupt(struct mn10300_serial_port *port)


try_again:
try_again:
	/* pull chars out of the hat */
	/* pull chars out of the hat */
	ix = port->rx_outp;
	ix = ACCESS_ONCE(port->rx_outp);
	if (ix == port->rx_inp) {
	if (CIRC_CNT(port->rx_inp, ix, MNSC_BUFFER_SIZE) == 0) {
		if (push && !tty->low_latency)
		if (push && !tty->low_latency)
			tty_flip_buffer_push(tty);
			tty_flip_buffer_push(tty);
		return;
		return;
	}
	}


	smp_read_barrier_depends();
	ch = port->rx_buffer[ix++];
	ch = port->rx_buffer[ix++];
	st = port->rx_buffer[ix++];
	st = port->rx_buffer[ix++];
	smp_rmb();
	smp_mb();
	port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1);
	port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1);
	port->uart.icount.rx++;
	port->uart.icount.rx++;


@@ -778,8 +835,6 @@ static void mn10300_serial_start_tx(struct uart_port *_port)
	struct mn10300_serial_port *port =
	struct mn10300_serial_port *port =
		container_of(_port, struct mn10300_serial_port, uart);
		container_of(_port, struct mn10300_serial_port, uart);


	u16 x;

	_enter("%s{%lu}",
	_enter("%s{%lu}",
	       port->name,
	       port->name,
	       CIRC_CNT(&port->uart.state->xmit.head,
	       CIRC_CNT(&port->uart.state->xmit.head,
@@ -787,14 +842,7 @@ static void mn10300_serial_start_tx(struct uart_port *_port)
			UART_XMIT_SIZE));
			UART_XMIT_SIZE));


	/* kick the virtual DMA controller */
	/* kick the virtual DMA controller */
	arch_local_cli();
	mn10300_serial_en_tx_intr(port);
	x = *port->tx_icr;
	x |= GxICR_ENABLE;

	if (*port->_status & SC01STR_TBF)
		x &= ~(GxICR_REQUEST | GxICR_DETECT);
	else
		x |= GxICR_REQUEST | GxICR_DETECT;


	_debug("CTR=%04hx ICR=%02hx STR=%04x TMD=%02hx TBR=%04hx ICR=%04hx",
	_debug("CTR=%04hx ICR=%02hx STR=%04x TMD=%02hx TBR=%04hx ICR=%04hx",
	       *port->_control, *port->_intr, *port->_status,
	       *port->_control, *port->_intr, *port->_status,
@@ -802,10 +850,6 @@ static void mn10300_serial_start_tx(struct uart_port *_port)
	       (port->div_timer == MNSCx_DIV_TIMER_8BIT) ?
	       (port->div_timer == MNSCx_DIV_TIMER_8BIT) ?
	           *(volatile u8 *)port->_tmxbr : *port->_tmxbr,
	           *(volatile u8 *)port->_tmxbr : *port->_tmxbr,
	       *port->tx_icr);
	       *port->tx_icr);

	*port->tx_icr = x;
	x = *port->tx_icr;
	arch_local_sti();
}
}


/*
/*
@@ -815,13 +859,17 @@ static void mn10300_serial_send_xchar(struct uart_port *_port, char ch)
{
{
	struct mn10300_serial_port *port =
	struct mn10300_serial_port *port =
		container_of(_port, struct mn10300_serial_port, uart);
		container_of(_port, struct mn10300_serial_port, uart);
	unsigned long flags;


	_enter("%s,%02x", port->name, ch);
	_enter("%s,%02x", port->name, ch);


	if (likely(port->gdbstub)) {
	if (likely(port->gdbstub)) {
		port->tx_xchar = ch;
		port->tx_xchar = ch;
		if (ch)
		if (ch) {
			spin_lock_irqsave(&port->uart.lock, flags);
			mn10300_serial_en_tx_intr(port);
			mn10300_serial_en_tx_intr(port);
			spin_unlock_irqrestore(&port->uart.lock, flags);
		}
	}
	}
}
}


@@ -882,18 +930,21 @@ static void mn10300_serial_break_ctl(struct uart_port *_port, int ctl)
{
{
	struct mn10300_serial_port *port =
	struct mn10300_serial_port *port =
		container_of(_port, struct mn10300_serial_port, uart);
		container_of(_port, struct mn10300_serial_port, uart);
	unsigned long flags;


	_enter("%s,%d", port->name, ctl);
	_enter("%s,%d", port->name, ctl);


	spin_lock_irqsave(&port->uart.lock, flags);
	if (ctl) {
	if (ctl) {
		/* tell the virtual DMA handler to assert BREAK */
		/* tell the virtual DMA handler to assert BREAK */
		port->tx_break = 1;
		port->tx_flags |= MNSCx_TX_BREAK;
		mn10300_serial_en_tx_intr(port);
		mn10300_serial_en_tx_intr(port);
	} else {
	} else {
		port->tx_break = 0;
		port->tx_flags &= ~MNSCx_TX_BREAK;
		*port->_control &= ~SC01CTR_BKE;
		*port->_control &= ~SC01CTR_BKE;
		mn10300_serial_en_tx_intr(port);
		mn10300_serial_en_tx_intr(port);
	}
	}
	spin_unlock_irqrestore(&port->uart.lock, flags);
}
}


/*
/*
@@ -916,6 +967,7 @@ static int mn10300_serial_startup(struct uart_port *_port)
		return -ENOMEM;
		return -ENOMEM;


	port->rx_inp = port->rx_outp = 0;
	port->rx_inp = port->rx_outp = 0;
	port->tx_flags = 0;


	/* finally, enable the device */
	/* finally, enable the device */
	*port->_intr = SC01ICR_TI;
	*port->_intr = SC01ICR_TI;
@@ -928,22 +980,23 @@ static int mn10300_serial_startup(struct uart_port *_port)
	pint->port = port;
	pint->port = port;
	pint->vdma = mn10300_serial_vdma_tx_handler;
	pint->vdma = mn10300_serial_vdma_tx_handler;


	set_intr_level(port->rx_irq,
	irq_set_chip(port->rx_irq, &mn10300_serial_low_pic);
		NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL));
	irq_set_chip(port->tx_irq, &mn10300_serial_low_pic);
	set_intr_level(port->tx_irq,
		NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL));
	irq_set_chip(port->tm_irq, &mn10300_serial_pic);
	irq_set_chip(port->tm_irq, &mn10300_serial_pic);


	if (request_irq(port->rx_irq, mn10300_serial_interrupt,
	if (request_irq(port->rx_irq, mn10300_serial_interrupt,
			IRQF_DISABLED, port->rx_name, port) < 0)
			IRQF_DISABLED | IRQF_NOBALANCING,
			port->rx_name, port) < 0)
		goto error;
		goto error;


	if (request_irq(port->tx_irq, mn10300_serial_interrupt,
	if (request_irq(port->tx_irq, mn10300_serial_interrupt,
			IRQF_DISABLED, port->tx_name, port) < 0)
			IRQF_DISABLED | IRQF_NOBALANCING,
			port->tx_name, port) < 0)
		goto error2;
		goto error2;


	if (request_irq(port->tm_irq, mn10300_serial_interrupt,
	if (request_irq(port->tm_irq, mn10300_serial_interrupt,
			IRQF_DISABLED, port->tm_name, port) < 0)
			IRQF_DISABLED | IRQF_NOBALANCING,
			port->tm_name, port) < 0)
		goto error3;
		goto error3;
	mn10300_serial_mask_ack(port->tm_irq);
	mn10300_serial_mask_ack(port->tm_irq);


@@ -964,14 +1017,22 @@ error:
 */
 */
static void mn10300_serial_shutdown(struct uart_port *_port)
static void mn10300_serial_shutdown(struct uart_port *_port)
{
{
	unsigned long flags;
	u16 x;
	u16 x;
	struct mn10300_serial_port *port =
	struct mn10300_serial_port *port =
		container_of(_port, struct mn10300_serial_port, uart);
		container_of(_port, struct mn10300_serial_port, uart);


	_enter("%s", port->name);
	_enter("%s", port->name);


	spin_lock_irqsave(&_port->lock, flags);
	mn10300_serial_dis_tx_intr(port);

	*port->rx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);
	x = *port->rx_icr;
	port->tx_flags = 0;
	spin_unlock_irqrestore(&_port->lock, flags);

	/* disable the serial port and its baud rate timer */
	/* disable the serial port and its baud rate timer */
	port->tx_break = 0;
	*port->_control &= ~(SC01CTR_TXE | SC01CTR_RXE | SC01CTR_BKE);
	*port->_control &= ~(SC01CTR_TXE | SC01CTR_RXE | SC01CTR_BKE);
	*port->_tmxmd = 0;
	*port->_tmxmd = 0;


@@ -986,12 +1047,8 @@ static void mn10300_serial_shutdown(struct uart_port *_port)
	free_irq(port->rx_irq, port);
	free_irq(port->rx_irq, port);
	free_irq(port->tx_irq, port);
	free_irq(port->tx_irq, port);


	arch_local_cli();
	mn10300_serial_int_tbl[port->tx_irq].port = NULL;
	*port->rx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);
	mn10300_serial_int_tbl[port->rx_irq].port = NULL;
	x = *port->rx_icr;
	*port->tx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);
	x = *port->tx_icr;
	arch_local_sti();
}
}


/*
/*
@@ -1317,7 +1374,8 @@ timer_okay:
	if ((new->c_cflag & CREAD) == 0)
	if ((new->c_cflag & CREAD) == 0)
		port->uart.ignore_status_mask |= (1 << TTY_NORMAL);
		port->uart.ignore_status_mask |= (1 << TTY_NORMAL);


	scxctr |= *port->_control & (SC01CTR_TXE | SC01CTR_RXE | SC01CTR_BKE);
	scxctr |= SC01CTR_TXE | SC01CTR_RXE;
	scxctr |= *port->_control & SC01CTR_BKE;
	*port->_control = scxctr;
	*port->_control = scxctr;


	spin_unlock_irqrestore(&port->uart.lock, flags);
	spin_unlock_irqrestore(&port->uart.lock, flags);
@@ -1519,17 +1577,24 @@ static void mn10300_serial_console_write(struct console *co,
{
{
	struct mn10300_serial_port *port;
	struct mn10300_serial_port *port;
	unsigned i;
	unsigned i;
	u16 scxctr, txicr, tmp;
	u16 scxctr;
	u8 tmxmd;
	u8 tmxmd;
	unsigned long flags;
	int locked = 1;


	port = mn10300_serial_ports[co->index];
	port = mn10300_serial_ports[co->index];


	local_irq_save(flags);
	if (port->uart.sysrq) {
		/* mn10300_serial_interrupt() already took the lock */
		locked = 0;
	} else if (oops_in_progress) {
		locked = spin_trylock(&port->uart.lock);
	} else
		spin_lock(&port->uart.lock);

	/* firstly hijack the serial port from the "virtual DMA" controller */
	/* firstly hijack the serial port from the "virtual DMA" controller */
	arch_local_cli();
	mn10300_serial_dis_tx_intr(port);
	txicr = *port->tx_icr;
	*port->tx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);
	tmp = *port->tx_icr;
	arch_local_sti();


	/* the transmitter may be disabled */
	/* the transmitter may be disabled */
	scxctr = *port->_control;
	scxctr = *port->_control;
@@ -1565,12 +1630,12 @@ static void mn10300_serial_console_write(struct console *co,


		while (*port->_status & SC01STR_TBF)
		while (*port->_status & SC01STR_TBF)
			continue;
			continue;
		*(u8 *) port->_txb = ch;
		*port->_txb = ch;


		if (ch == 0x0a) {
		if (ch == 0x0a) {
			while (*port->_status & SC01STR_TBF)
			while (*port->_status & SC01STR_TBF)
				continue;
				continue;
			*(u8 *) port->_txb = 0xd;
			*port->_txb = 0xd;
		}
		}
	}
	}


@@ -1583,10 +1648,11 @@ static void mn10300_serial_console_write(struct console *co,
	if (!(scxctr & SC01CTR_TXE))
	if (!(scxctr & SC01CTR_TXE))
		*port->_control = scxctr;
		*port->_control = scxctr;


	arch_local_cli();
	mn10300_serial_en_tx_intr(port);
	*port->tx_icr = txicr;

	tmp = *port->tx_icr;
	if (locked)
	arch_local_sti();
		spin_unlock(&port->uart.lock);
	local_irq_restore(flags);
}
}


/*
/*
@@ -1655,18 +1721,29 @@ static int mn10300_serial_poll_get_char(struct uart_port *_port)


	_enter("%s", port->name);
	_enter("%s", port->name);


	if (mn10300_serial_int_tbl[port->rx_irq].port != NULL) {
		do {
		do {
			/* pull chars out of the hat */
			/* pull chars out of the hat */
		ix = port->rx_outp;
			ix = ACCESS_ONCE(port->rx_outp);
		if (ix == port->rx_inp)
			if (CIRC_CNT(port->rx_inp, ix, MNSC_BUFFER_SIZE) == 0)
				return NO_POLL_CHAR;
				return NO_POLL_CHAR;


			smp_read_barrier_depends();
			ch = port->rx_buffer[ix++];
			ch = port->rx_buffer[ix++];
			st = port->rx_buffer[ix++];
			st = port->rx_buffer[ix++];
		smp_rmb();
			smp_mb();
			port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1);
			port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1);


		} while (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF));
		} while (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF));
	} else {
		do {
			st = *port->_status;
			if (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF))
				continue;
		} while (!(st & SC01STR_RBF));

		ch = *port->_rxb;
	}


	return ch;
	return ch;
}
}
@@ -1693,12 +1770,12 @@ static void mn10300_serial_poll_put_char(struct uart_port *_port,
	tmp = *port->_intr;
	tmp = *port->_intr;


	if (ch == 0x0a) {
	if (ch == 0x0a) {
		*(u8 *) port->_txb = 0x0d;
		*port->_txb = 0x0d;
		while (*port->_status & SC01STR_TBF)
		while (*port->_status & SC01STR_TBF)
			continue;
			continue;
	}
	}


	*(u8 *) port->_txb = ch;
	*port->_txb = ch;
	while (*port->_status & SC01STR_TBF)
	while (*port->_status & SC01STR_TBF)
		continue;
		continue;


Loading