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

Commit 311c4627 authored by Kumar Gala's avatar Kumar Gala Committed by Linus Torvalds
Browse files

[PATCH] cpm_uart: Fix dpram allocation and non-console uarts



* Makes dpram allocations work
* Makes non-console UART work on both 8xx and 82xx
* Fixed whitespace in files that were touched

Signed-off-by: default avatarVitaly Bordug <vbordug@ru.mvista.com>
Signed-off-by: default avatarPantelis Antoniou <panto@intracom.gr>
Signed-off-by: default avatarKumar Gala <kumar.gala@freescale.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 3077a260
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@
#define TX_NUM_FIFO	4
#define TX_BUF_SIZE	32

#define SCC_WAIT_CLOSING 100

struct uart_cpm_port {
	struct uart_port	port;
	u16			rx_nrfifos;
@@ -67,6 +69,8 @@ struct uart_cpm_port {
	int			 bits;
	/* Keep track of 'odd' SMC2 wirings */
	int			is_portb;
	/* wait on close if needed */
	int 			wait_closing;
};

extern int cpm_uart_port_map[UART_NR];
+80 −38
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
 *
 *  Copyright (C) 2004 Freescale Semiconductor, Inc.
 *            (C) 2004 Intracom, S.A.
 *            (C) 2005 MontaVista Software, Inc. by Vitaly Bordug <vbordug@ru.mvista.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
@@ -70,6 +71,20 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo);

/**************************************************************/

static inline unsigned long cpu2cpm_addr(void *addr)
{
	if ((unsigned long)addr >= CPM_ADDR)
		return (unsigned long)addr;
	return virt_to_bus(addr);
}

static inline void *cpm2cpu_addr(unsigned long addr)
{
	if (addr >= CPM_ADDR)
		return (void *)addr;
	return bus_to_virt(addr);
}

/*
 * Check, if transmit buffers are processed
*/
@@ -143,10 +158,13 @@ static void cpm_uart_start_tx(struct uart_port *port, unsigned int tty_start)
	}

	if (cpm_uart_tx_pump(port) != 0) {
		if (IS_SMC(pinfo))
		if (IS_SMC(pinfo)) {
			smcp->smc_smcm |= SMCM_TX;
		else
			smcp->smc_smcmr |= SMCMR_TEN;
		} else {
			sccp->scc_sccm |= UART_SCCM_TX;
			pinfo->sccp->scc_gsmrl |= SCC_GSMRL_ENT;
		}
	}
}

@@ -243,7 +261,7 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs)
		}

		/* get pointer */
		cp = (unsigned char *)bus_to_virt(bdp->cbd_bufaddr);
		cp = cpm2cpu_addr(bdp->cbd_bufaddr);

		/* loop through the buffer */
		while (i-- > 0) {
@@ -265,13 +283,14 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs)
		}		/* End while (i--) */

		/* This BD is ready to be used again. Clear status. get next */
		bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV);
		bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV | BD_SC_ID);
		bdp->cbd_sc |= BD_SC_EMPTY;

		if (bdp->cbd_sc & BD_SC_WRAP)
			bdp = pinfo->rx_bd_base;
		else
			bdp++;

	} /* End for (;;) */

	/* Write back buffer pointer */
@@ -336,22 +355,22 @@ static irqreturn_t cpm_uart_int(int irq, void *data, struct pt_regs *regs)

	if (IS_SMC(pinfo)) {
		events = smcp->smc_smce;
		smcp->smc_smce = events;
		if (events & SMCM_BRKE)
			uart_handle_break(port);
		if (events & SMCM_RX)
			cpm_uart_int_rx(port, regs);
		if (events & SMCM_TX)
			cpm_uart_int_tx(port, regs);
		smcp->smc_smce = events;
	} else {
		events = sccp->scc_scce;
		sccp->scc_scce = events;
		if (events & UART_SCCM_BRKE)
			uart_handle_break(port);
		if (events & UART_SCCM_RX)
			cpm_uart_int_rx(port, regs);
		if (events & UART_SCCM_TX)
			cpm_uart_int_tx(port, regs);
		sccp->scc_scce = events;
	}
	return (events) ? IRQ_HANDLED : IRQ_NONE;
}
@@ -360,6 +379,7 @@ static int cpm_uart_startup(struct uart_port *port)
{
	int retval;
	struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
	int line = pinfo - cpm_uart_ports;

	pr_debug("CPM uart[%d]:startup\n", port->line);

@@ -376,9 +396,19 @@ static int cpm_uart_startup(struct uart_port *port)
		pinfo->sccp->scc_sccm |= UART_SCCM_RX;
	}

	if (!(pinfo->flags & FLAG_CONSOLE))
		cpm_line_cr_cmd(line,CPM_CR_INIT_TRX);
	return 0;
}

inline void cpm_uart_wait_until_send(struct uart_cpm_port *pinfo)
{
	unsigned long target_jiffies = jiffies + pinfo->wait_closing;

	while (!time_after(jiffies, target_jiffies))
   		schedule();
}

/*
 * Shutdown the uart
 */
@@ -394,6 +424,12 @@ static void cpm_uart_shutdown(struct uart_port *port)

	/* If the port is not the console, disable Rx and Tx. */
	if (!(pinfo->flags & FLAG_CONSOLE)) {
		/* Wait for all the BDs marked sent */
		while(!cpm_uart_tx_empty(port))
			schedule_timeout(2);
		if(pinfo->wait_closing)
			cpm_uart_wait_until_send(pinfo);

		/* Stop uarts */
		if (IS_SMC(pinfo)) {
			volatile smc_t *smcp = pinfo->smcp;
@@ -569,7 +605,8 @@ static int cpm_uart_tx_pump(struct uart_port *port)
		/* Pick next descriptor and fill from buffer */
		bdp = pinfo->tx_cur;

		p = bus_to_virt(bdp->cbd_bufaddr);
		p = cpm2cpu_addr(bdp->cbd_bufaddr);

		*p++ = xmit->buf[xmit->tail];
		bdp->cbd_datlen = 1;
		bdp->cbd_sc |= BD_SC_READY;
@@ -595,7 +632,7 @@ static int cpm_uart_tx_pump(struct uart_port *port)

	while (!(bdp->cbd_sc & BD_SC_READY) && (xmit->tail != xmit->head)) {
		count = 0;
		p = bus_to_virt(bdp->cbd_bufaddr);
		p = cpm2cpu_addr(bdp->cbd_bufaddr);
		while (count < pinfo->tx_fifosize) {
			*p++ = xmit->buf[xmit->tail];
			xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
@@ -606,6 +643,7 @@ static int cpm_uart_tx_pump(struct uart_port *port)
		}
		bdp->cbd_datlen = count;
		bdp->cbd_sc |= BD_SC_READY;
		__asm__("eieio");
		/* Get next BD. */
		if (bdp->cbd_sc & BD_SC_WRAP)
			bdp = pinfo->tx_bd_base;
@@ -643,12 +681,12 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo)
	mem_addr = pinfo->mem_addr;
	bdp = pinfo->rx_cur = pinfo->rx_bd_base;
	for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) {
		bdp->cbd_bufaddr = virt_to_bus(mem_addr);
		bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
		bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT;
		mem_addr += pinfo->rx_fifosize;
	}

	bdp->cbd_bufaddr = virt_to_bus(mem_addr);
	bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
	bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;

	/* Set the physical address of the host memory
@@ -658,12 +696,12 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo)
	mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize);
	bdp = pinfo->tx_cur = pinfo->tx_bd_base;
	for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) {
		bdp->cbd_bufaddr = virt_to_bus(mem_addr);
		bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
		bdp->cbd_sc = BD_SC_INTRPT;
		mem_addr += pinfo->tx_fifosize;
	}

	bdp->cbd_bufaddr = virt_to_bus(mem_addr);
	bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
	bdp->cbd_sc = BD_SC_WRAP | BD_SC_INTRPT;
}

@@ -763,6 +801,8 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo)
	/* Using idle charater time requires some additional tuning.  */
	up->smc_mrblr = pinfo->rx_fifosize;
	up->smc_maxidl = pinfo->rx_fifosize;
	up->smc_brklen = 0;
	up->smc_brkec = 0;
	up->smc_brkcr = 1;

	cpm_line_cr_cmd(line, CPM_CR_INIT_TRX);
@@ -815,6 +855,10 @@ static int cpm_uart_request_port(struct uart_port *port)
		return ret;

	cpm_uart_initbd(pinfo);
	if (IS_SMC(pinfo))
		cpm_uart_init_smc(pinfo);
	else
		cpm_uart_init_scc(pinfo);

	return 0;
}
@@ -902,6 +946,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
		.rx_nrfifos = RX_NUM_FIFO,
		.rx_fifosize = RX_BUF_SIZE,
		.set_lineif = scc1_lineif,
		.wait_closing = SCC_WAIT_CLOSING,
	},
	[UART_SCC2] = {
		.port = {
@@ -915,6 +960,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
		.rx_nrfifos = RX_NUM_FIFO,
		.rx_fifosize = RX_BUF_SIZE,
		.set_lineif = scc2_lineif,
		.wait_closing = SCC_WAIT_CLOSING,
	},
	[UART_SCC3] = {
		.port = {
@@ -928,6 +974,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
		.rx_nrfifos = RX_NUM_FIFO,
		.rx_fifosize = RX_BUF_SIZE,
		.set_lineif = scc3_lineif,
		.wait_closing = SCC_WAIT_CLOSING,
	},
	[UART_SCC4] = {
		.port = {
@@ -941,6 +988,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
		.rx_nrfifos = RX_NUM_FIFO,
		.rx_fifosize = RX_BUF_SIZE,
		.set_lineif = scc4_lineif,
		.wait_closing = SCC_WAIT_CLOSING,
	},
};

@@ -983,10 +1031,7 @@ static void cpm_uart_console_write(struct console *co, const char *s,
		 * If the buffer address is in the CPM DPRAM, don't
		 * convert it.
		 */
		if ((uint) (bdp->cbd_bufaddr) > (uint) CPM_ADDR)
			cp = (unsigned char *) (bdp->cbd_bufaddr);
		else
			cp = bus_to_virt(bdp->cbd_bufaddr);
		cp = cpm2cpu_addr(bdp->cbd_bufaddr);

		*cp = *s;

@@ -1003,10 +1048,7 @@ static void cpm_uart_console_write(struct console *co, const char *s,
			while ((bdp->cbd_sc & BD_SC_READY) != 0)
				;

			if ((uint) (bdp->cbd_bufaddr) > (uint) CPM_ADDR)
				cp = (unsigned char *) (bdp->cbd_bufaddr);
			else
				cp = bus_to_virt(bdp->cbd_bufaddr);
			cp = cpm2cpu_addr(bdp->cbd_bufaddr);

			*cp = 13;
			bdp->cbd_datlen = 1;
+29 −24
Original line number Diff line number Diff line
@@ -82,6 +82,17 @@ void cpm_line_cr_cmd(int line, int cmd)
void smc1_lineif(struct uart_cpm_port *pinfo)
{
	volatile cpm8xx_t *cp = cpmp;

	(void)cp;	/* fix warning */
#if defined (CONFIG_MPC885ADS)
	/* Enable SMC1 transceivers */
	{
		cp->cp_pepar |= 0x000000c0;
		cp->cp_pedir &= ~0x000000c0;
		cp->cp_peso &= ~0x00000040;
		cp->cp_peso |= 0x00000080;
	}
#elif defined (CONFIG_MPC86XADS)
	unsigned int iobits = 0x000000c0;

	if (!pinfo->is_portb) {
@@ -93,41 +104,33 @@ void smc1_lineif(struct uart_cpm_port *pinfo)
		((immap_t *)IMAP_ADDR)->im_ioport.iop_padir &= ~iobits;
		((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits;
	}

#ifdef CONFIG_MPC885ADS
	/* Enable SMC1 transceivers */
	{
		volatile uint __iomem *bcsr1 = ioremap(BCSR1, 4);
		uint tmp;

		tmp = in_be32(bcsr1);
		tmp &= ~BCSR1_RS232EN_1;
		out_be32(bcsr1, tmp);
		iounmap(bcsr1);
	}
#endif

	pinfo->brg = 1;
}

void smc2_lineif(struct uart_cpm_port *pinfo)
{
#ifdef CONFIG_MPC885ADS
	volatile cpm8xx_t *cp = cpmp;
	volatile uint __iomem *bcsr1;
	uint tmp;

	(void)cp;	/* fix warning */
#if defined (CONFIG_MPC885ADS)
	cp->cp_pepar |= 0x00000c00;
	cp->cp_pedir &= ~0x00000c00;
	cp->cp_peso &= ~0x00000400;
	cp->cp_peso |= 0x00000800;
#elif defined (CONFIG_MPC86XADS)
	unsigned int iobits = 0x00000c00;

	if (!pinfo->is_portb) {
		cp->cp_pbpar |= iobits;
		cp->cp_pbdir &= ~iobits;
		cp->cp_pbodr &= ~iobits;
	} else {
		((immap_t *)IMAP_ADDR)->im_ioport.iop_papar |= iobits;
		((immap_t *)IMAP_ADDR)->im_ioport.iop_padir &= ~iobits;
		((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits;
	}

	/* Enable SMC2 transceivers */
	bcsr1 = ioremap(BCSR1, 4);
	tmp = in_be32(bcsr1);
	tmp &= ~BCSR1_RS232EN_2;
	out_be32(bcsr1, tmp);
	iounmap(bcsr1);
#endif

	pinfo->brg = 2;
@@ -185,6 +188,8 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
	memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) +
	    L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize);
	if (is_con) {
		/* was hostalloc but changed cause it blows away the */
		/* large tlb mapping when pinning the kernel area    */
		mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8));
		dma_addr = 0;
	} else