Example #1
0
/*
 * Initialize port. This is called from early_console stuff
 * so we have to be careful here !
 */
static int cpm_uart_request_port(struct uart_port *port)
{
	struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
	int ret;

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

	if (pinfo->flags & FLAG_CONSOLE)
		return 0;

	if (IS_SMC(pinfo)) {
		pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
		pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
	} else {
		pinfo->sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX);
		pinfo->sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
	}

	ret = cpm_uart_allocbuf(pinfo, 0);

	if (ret)
		return ret;

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

	return 0;
}
Example #2
0
/*
 * Start transmitter
 */
static void cpm_uart_start_tx(struct uart_port *port)
{
	struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
	volatile smc_t *smcp = pinfo->smcp;
	volatile scc_t *sccp = pinfo->sccp;

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

	if (IS_SMC(pinfo)) {
		if (smcp->smc_smcm & SMCM_TX)
			return;
	} else {
		if (sccp->scc_sccm & UART_SCCM_TX)
			return;
	}

	if (cpm_uart_tx_pump(port) != 0) {
		if (IS_SMC(pinfo)) {
			smcp->smc_smcm |= SMCM_TX;
			smcp->smc_smcmr |= SMCMR_TEN;
		} else {
			sccp->scc_sccm |= UART_SCCM_TX;
			pinfo->sccp->scc_gsmrl |= SCC_GSMRL_ENT;
		}
	}
}
Example #3
0
static int cpm_uart_startup(struct uart_port *port)
{
	int retval;
	struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;

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

	/* If the port is not the console, make sure rx is disabled. */
	if (!(pinfo->flags & FLAG_CONSOLE)) {
		/* Disable UART rx */
		if (IS_SMC(pinfo)) {
			clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN);
			clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX);
		} else {
			clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR);
			clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX);
		}
		cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX);
	}
	/* Install interrupt handler. */
	retval = request_irq(port->irq, cpm_uart_int, 0, "cpm_uart", port);
	if (retval)
		return retval;

	/* Startup rx-int */
	if (IS_SMC(pinfo)) {
		setbits8(&pinfo->smcp->smc_smcm, SMCM_RX);
		setbits16(&pinfo->smcp->smc_smcmr, (SMCMR_REN | SMCMR_TEN));
	} else {
		setbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX);
		setbits32(&pinfo->sccp->scc_gsmrl, (SCC_GSMRL_ENR | SCC_GSMRL_ENT));
	}

	return 0;
}
Example #4
0
/*
 * Setup console. Be careful is called early !
 */
static int __init cpm_uart_console_setup(struct console *co, char *options)
{
	struct uart_port *port;
	struct uart_cpm_port *pinfo;
	int baud = 38400;
	int bits = 8;
	int parity = 'n';
	int flow = 'n';
	int ret;

	port =
	    (struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]];
	pinfo = (struct uart_cpm_port *)port;

	pinfo->flags |= FLAG_CONSOLE;

	if (options) {
		uart_parse_options(options, &baud, &parity, &bits, &flow);
	} else {
		bd_t *bd = (bd_t *) __res;

		if (bd->bi_baudrate)
			baud = bd->bi_baudrate;
		else
			baud = 9600;
	}

	/*
	 * Setup any port IO, connect any baud rate generators,
	 * etc.  This is expected to be handled by board
	 * dependant code
	 */
	if (pinfo->set_lineif)
		pinfo->set_lineif(pinfo);

	if (IS_SMC(pinfo)) {
		pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
		pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
	} else {
		pinfo->sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX);
		pinfo->sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
	}

	ret = cpm_uart_allocbuf(pinfo, 1);

	if (ret)
		return ret;

	cpm_uart_initbd(pinfo);

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

	uart_set_options(port, co, baud, parity, bits, flow);

	return 0;
}
Example #5
0
int cpm_uart_early_setup(int index, int early)
{
	int ret;
	struct uart_port *port;
	struct uart_cpm_port *pinfo = &cpm_uart_ports[index];
	struct fs_uart_platform_info *pdata;
	struct platform_device* pdev = early_uart_get_pdev(index);
	int line = pinfo - cpm_uart_ports;

	BUG_ON(index>UART_NR);
	port =
		(struct uart_port *)&cpm_uart_ports[index];
	pinfo = (struct uart_cpm_port *)port;
	if (!pdev) {
		if (pinfo->set_lineif)
			pinfo->set_lineif(pinfo);
	} else {
		pdata = pdev->dev.platform_data;
		if (pdata)
			if (pdata->init_ioports)
    	                	pdata->init_ioports(pdata);

		cpm_uart_drv_get_platform_data(pdev, 1);
	}

	cpm_line_cr_cmd(line, CPM_CR_STOP_TX);

	if (IS_SMC(pinfo)) {
		pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
		pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
	} else {
		pinfo->sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX);
		pinfo->sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
	}
	ret = cpm_uart_allocbuf(pinfo, early);

	if (ret)
		return ret;

	cpm_uart_initbd(pinfo);

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

	return 0;
}
Example #6
0
/*
 * Asynchron mode interrupt handler
 */
static irqreturn_t cpm_uart_int(int irq, void *data)
{
	u8 events;
	struct uart_port *port = data;
	struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
	smc_t __iomem *smcp = pinfo->smcp;
	scc_t __iomem *sccp = pinfo->sccp;

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

	if (IS_SMC(pinfo)) {
		events = in_8(&smcp->smc_smce);
		out_8(&smcp->smc_smce, events);
		if (events & SMCM_BRKE)
			uart_handle_break(port);
		if (events & SMCM_RX)
			cpm_uart_int_rx(port);
		if (events & SMCM_TX)
			cpm_uart_int_tx(port);
	} else {
		events = in_be16(&sccp->scc_scce);
		out_be16(&sccp->scc_scce, events);
		if (events & UART_SCCM_BRKE)
			uart_handle_break(port);
		if (events & UART_SCCM_RX)
			cpm_uart_int_rx(port);
		if (events & UART_SCCM_TX)
			cpm_uart_int_tx(port);
	}
	return (events) ? IRQ_HANDLED : IRQ_NONE;
}
Example #7
0
/*
 * Asynchron mode interrupt handler
 */
static irqreturn_t cpm_uart_int(int irq, void *data)
{
	u8 events;
	struct uart_port *port = (struct uart_port *)data;
	struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
	volatile smc_t *smcp = pinfo->smcp;
	volatile scc_t *sccp = pinfo->sccp;

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

	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);
		if (events & SMCM_TX)
			cpm_uart_int_tx(port);
	} 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);
		if (events & UART_SCCM_TX)
			cpm_uart_int_tx(port);
	}
	return (events) ? IRQ_HANDLED : IRQ_NONE;
}
Example #8
0
/*
 *  Returns:
 *	0 on success, 1 on failure.
 */
static int kgdb_init(void)
{
	struct uart_port *port;
	struct uart_cpm_port *pinfo;

	int use_bootmem = 0; /* use dma by default */

	if(!cpm_uart_nr)
	{
		use_bootmem = 1;
		cpm_uart_init_portdesc();
	}
	port = (struct uart_port *)&cpm_uart_ports[KGDB_PINFO_INDEX];
	pinfo = (struct uart_cpm_port *)port;

	if (cpm_uart_early_setup(KGDB_PINFO_INDEX, use_bootmem))
		return 1;

	termios_set_options(KGDB_PINFO_INDEX, KGDB_BAUD,'n',8,'n');
        if (IS_SMC(pinfo))
                pinfo->smcp->smc_smcm |= SMCM_TX;
        else
                pinfo->sccp->scc_sccm |= UART_SCCM_TX;

	return 0;
}
Example #9
0
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);

	/* Install interrupt handler. */
	retval = request_irq(port->irq, cpm_uart_int, 0, "cpm_uart", port);
	if (retval)
		return retval;

	/* Startup rx-int */
	if (IS_SMC(pinfo)) {
		pinfo->smcp->smc_smcm |= SMCM_RX;
		pinfo->smcp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN);
	} else {
		pinfo->sccp->scc_sccm |= UART_SCCM_RX;
		pinfo->sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
	}

	if (!(pinfo->flags & FLAG_CONSOLE))
		cpm_line_cr_cmd(line,CPM_CR_INIT_TRX);
	return 0;
}
/*
 * Initialize port. This is called from early_console stuff
 * so we have to be careful here !
 */
static int cpm_uart_request_port(struct uart_port *port)
{
    struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
    int ret;

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

    if (pinfo->flags & FLAG_CONSOLE)
        return 0;

    /*
     * Setup any port IO, connect any baud rate generators,
     * etc.  This is expected to be handled by board
     * dependant code
     */
    if (pinfo->set_lineif)
        pinfo->set_lineif(pinfo);

    if (IS_SMC(pinfo)) {
        pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
        pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
    } else {
        pinfo->sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX);
        pinfo->sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
    }

    ret = cpm_uart_allocbuf(pinfo, 0);

    if (ret)
        return ret;

    cpm_uart_initbd(pinfo);

    return 0;
}
/*
 * Shutdown the uart
 */
static void cpm_uart_shutdown(struct uart_port *port)
{
    struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
    int line = pinfo - cpm_uart_ports;

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

    /* free interrupt handler */
    free_irq(port->irq, port);

    /* If the port is not the console, disable Rx and Tx. */
    if (!(pinfo->flags & FLAG_CONSOLE)) {
        /* Stop uarts */
        if (IS_SMC(pinfo)) {
            volatile smc_t *smcp = pinfo->smcp;
            smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
            smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
        } else {
            volatile scc_t *sccp = pinfo->sccp;
            sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
            sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX);
        }

        /* Shut them really down and reinit buffer descriptors */
        cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
        cpm_uart_initbd(pinfo);
    }
}
Example #12
0
/*
 * Shutdown the uart
 */
static void cpm_uart_shutdown(struct uart_port *port)
{
	struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;

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

	/* free interrupt handler */
	free_irq(port->irq, 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)) {
			set_current_state(TASK_UNINTERRUPTIBLE);
			schedule_timeout(2);
		}

		if (pinfo->wait_closing)
			cpm_uart_wait_until_send(pinfo);

		/* Stop uarts */
		if (IS_SMC(pinfo)) {
			smc_t __iomem *smcp = pinfo->smcp;
			clrbits16(&smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN);
			clrbits8(&smcp->smc_smcm, SMCM_RX | SMCM_TX);
		} else {
			scc_t __iomem *sccp = pinfo->sccp;
			clrbits32(&sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
			clrbits16(&sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
		}

		/* Shut them really down and reinit buffer descriptors */
		if (IS_SMC(pinfo)) {
			out_be16(&pinfo->smcup->smc_brkcr, 0);
			cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX);
		} else {
			out_be16(&pinfo->sccup->scc_brkcr, 0);
			cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX);
		}

		cpm_uart_initbd(pinfo);
	}
}
void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port,
				struct device_node *np)
{
	void __iomem *pram;
	unsigned long offset;
	struct resource res;
	unsigned long len;

	/* Don't remap parameter RAM if it has already been initialized
	 * during console setup.
	 */
	if (IS_SMC(port) && port->smcup)
		return port->smcup;
	else if (!IS_SMC(port) && port->sccup)
		return port->sccup;

	if (of_address_to_resource(np, 1, &res))
		return NULL;

	len = 1 + res.end - res.start;
	pram = ioremap(res.start, len);
	if (!pram)
		return NULL;

	if (!IS_SMC(port))
		return pram;

	if (len != 2) {
		printk(KERN_WARNING "cpm_uart[%d]: device tree references "
			"SMC pram, using boot loader/wrapper pram mapping. "
			"Please fix your device tree to reference the pram "
			"base register instead.\n",
			port->port.line);
		return pram;
	}

	offset = cpm_dpalloc(PROFF_SMC_SIZE, 64);
	out_be16(pram, offset);
	iounmap(pram);
	return cpm_muram_addr(offset);
}
Example #14
0
/*
 * Stop receiver
 */
static void cpm_uart_stop_rx(struct uart_port *port)
{
	struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
	smc_t __iomem *smcp = pinfo->smcp;
	scc_t __iomem *sccp = pinfo->sccp;

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

	if (IS_SMC(pinfo))
		clrbits8(&smcp->smc_smcm, SMCM_RX);
	else
		clrbits16(&sccp->scc_sccm, UART_SCCM_RX);
}
Example #15
0
/*
 * Stop receiver
 */
static void cpm_uart_stop_rx(struct uart_port *port)
{
	struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
	volatile smc_t *smcp = pinfo->smcp;
	volatile scc_t *sccp = pinfo->sccp;

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

	if (IS_SMC(pinfo))
		smcp->smc_smcm &= ~SMCM_RX;
	else
		sccp->scc_sccm &= ~UART_SCCM_RX;
}
/*
 * Start transmitter
 */
static void cpm_uart_start_tx(struct uart_port *port, unsigned int tty_start)
{
    struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
    volatile smc_t *smcp = pinfo->smcp;
    volatile scc_t *sccp = pinfo->sccp;

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

    if (IS_SMC(pinfo)) {
        if (smcp->smc_smcm & SMCM_TX)
            return;
    } else {
        if (sccp->scc_sccm & UART_SCCM_TX)
            return;
    }

    if (cpm_uart_tx_pump(port) != 0) {
        if (IS_SMC(pinfo))
            smcp->smc_smcm |= SMCM_TX;
        else
            sccp->scc_sccm |= UART_SCCM_TX;
    }
}
Example #17
0
/*
 * Start transmitter
 */
static void cpm_uart_start_tx(struct uart_port *port)
{
	struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
	smc_t __iomem *smcp = pinfo->smcp;
	scc_t __iomem *sccp = pinfo->sccp;

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

	if (IS_SMC(pinfo)) {
		if (in_8(&smcp->smc_smcm) & SMCM_TX)
			return;
	} else {
		if (in_be16(&sccp->scc_sccm) & UART_SCCM_TX)
			return;
	}

	if (cpm_uart_tx_pump(port) != 0) {
		if (IS_SMC(pinfo)) {
			setbits8(&smcp->smc_smcm, SMCM_TX);
		} else {
			setbits16(&sccp->scc_sccm, UART_SCCM_TX);
		}
	}
}
static int cpm_uart_startup(struct uart_port *port)
{
    int retval;
    struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;

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

    /* Install interrupt handler. */
    retval = request_irq(port->irq, cpm_uart_int, 0, "cpm_uart", port);
    if (retval)
        return retval;

    /* Startup rx-int */
    if (IS_SMC(pinfo)) {
        pinfo->smcp->smc_smcm |= SMCM_RX;
        pinfo->smcp->smc_smcmr |= SMCMR_REN;
    } else {
        pinfo->sccp->scc_sccm |= UART_SCCM_RX;
    }

    return 0;
}
void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram)
{
	if (!IS_SMC(port))
		iounmap(pram);
}
Example #20
0
/* unconditional independence tests. */
SEXP utest(SEXP x, SEXP y, SEXP data, SEXP test, SEXP B, SEXP alpha,
    SEXP learning) {

int ntests = length(x), nobs = 0;
double *pvalue = NULL, statistic = 0, df = NA_REAL;
const char *t = CHAR(STRING_ELT(test, 0));
test_e test_type = test_label(t);
SEXP xx, yy, result;

  /* allocate the return value, which has the same length as x. */
  PROTECT(result = allocVector(REALSXP, ntests));
  setAttrib(result, R_NamesSymbol, x);
  pvalue = REAL(result);
  /* set all elements to zero. */
  memset(pvalue, '\0', ntests * sizeof(double));

  /* extract the variables from the data. */
  PROTECT(xx = c_dataframe_column(data, x, FALSE, FALSE));
  PROTECT(yy = c_dataframe_column(data, y, TRUE, FALSE));
  nobs = length(yy);

  if (IS_DISCRETE_ASYMPTOTIC_TEST(test_type)) {

    /* parametric tests for discrete variables. */
    statistic = ut_discrete(xx, yy, nobs, ntests, pvalue, &df, test_type);

  }/*THEN*/
  else if ((test_type == COR) || (test_type == ZF) || (test_type == MI_G) ||
           (test_type == MI_G_SH)) {

    /* parametric tests for Gaussian variables. */
    statistic = ut_gaustests(xx, yy, nobs, ntests, pvalue, &df, test_type);

  }/*THEN*/
  else if (test_type == MI_CG) {

    /* conditional linear Gaussian mutual information test. */
    statistic = ut_micg(xx, yy, nobs, ntests, pvalue, &df);

  }/*THEN*/
  else if (IS_DISCRETE_PERMUTATION_TEST(test_type)) {

    statistic = ut_dperm(xx, yy, nobs, ntests, pvalue, &df, test_type, INT(B),
                  IS_SMC(test_type) ? NUM(alpha) : 1);

  }/*THEN*/
  else if (IS_CONTINUOUS_PERMUTATION_TEST(test_type)) {

    statistic = ut_gperm(xx, yy, nobs, ntests, pvalue, test_type, INT(B),
                  IS_SMC(test_type) ? NUM(alpha) : 1);

  }/*THEN*/

  UNPROTECT(3);

  /* catch-all for unknown tests (after deallocating memory.) */
  if (test_type == ENOTEST)
    error("unknown test statistic '%s'.", t);

  /* increase the test counter. */
  test_counter += ntests;

  if (isTRUE(learning))
    return result;
  else
    return c_create_htest(statistic, test, pvalue[ntests - 1], df, B);

}/*UTEST*/
Example #21
0
static void cpm_uart_set_termios(struct uart_port *port,
                                 struct ktermios *termios,
                                 struct ktermios *old)
{
	int baud;
	unsigned long flags;
	u16 cval, scval, prev_mode;
	int bits, sbits;
	struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
	volatile smc_t *smcp = pinfo->smcp;
	volatile scc_t *sccp = pinfo->sccp;

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

	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);

	/* Character length programmed into the mode register is the
	 * sum of: 1 start bit, number of data bits, 0 or 1 parity bit,
	 * 1 or 2 stop bits, minus 1.
	 * The value 'bits' counts this for us.
	 */
	cval = 0;
	scval = 0;

	/* byte size */
	switch (termios->c_cflag & CSIZE) {
	case CS5:
		bits = 5;
		break;
	case CS6:
		bits = 6;
		break;
	case CS7:
		bits = 7;
		break;
	case CS8:
		bits = 8;
		break;
		/* Never happens, but GCC is too dumb to figure it out */
	default:
		bits = 8;
		break;
	}
	sbits = bits - 5;

	if (termios->c_cflag & CSTOPB) {
		cval |= SMCMR_SL;	/* Two stops */
		scval |= SCU_PSMR_SL;
		bits++;
	}

	if (termios->c_cflag & PARENB) {
		cval |= SMCMR_PEN;
		scval |= SCU_PSMR_PEN;
		bits++;
		if (!(termios->c_cflag & PARODD)) {
			cval |= SMCMR_PM_EVEN;
			scval |= (SCU_PSMR_REVP | SCU_PSMR_TEVP);
		}
	}

	/*
	 * Set up parity check flag
	 */
#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))

	port->read_status_mask = (BD_SC_EMPTY | BD_SC_OV);
	if (termios->c_iflag & INPCK)
		port->read_status_mask |= BD_SC_FR | BD_SC_PR;
	if ((termios->c_iflag & BRKINT) || (termios->c_iflag & PARMRK))
		port->read_status_mask |= BD_SC_BR;

	/*
	 * Characters to ignore
	 */
	port->ignore_status_mask = 0;
	if (termios->c_iflag & IGNPAR)
		port->ignore_status_mask |= BD_SC_PR | BD_SC_FR;
	if (termios->c_iflag & IGNBRK) {
		port->ignore_status_mask |= BD_SC_BR;
		/*
		 * If we're ignore parity and break indicators, ignore
		 * overruns too.  (For real raw support).
		 */
		if (termios->c_iflag & IGNPAR)
			port->ignore_status_mask |= BD_SC_OV;
	}
	/*
	 * !!! ignore all characters if CREAD is not set
	 */
	if ((termios->c_cflag & CREAD) == 0)
		port->read_status_mask &= ~BD_SC_EMPTY;

	spin_lock_irqsave(&port->lock, flags);

	/* Start bit has not been added (so don't, because we would just
	 * subtract it later), and we need to add one for the number of
	 * stops bits (there is always at least one).
	 */
	bits++;
	if (IS_SMC(pinfo)) {
		/* Set the mode register.  We want to keep a copy of the
		 * enables, because we want to put them back if they were
		 * present.
		 */
		prev_mode = smcp->smc_smcmr;
		smcp->smc_smcmr = smcr_mk_clen(bits) | cval | SMCMR_SM_UART;
		smcp->smc_smcmr |= (prev_mode & (SMCMR_REN | SMCMR_TEN));
	} else {
		sccp->scc_psmr = (sbits << 12) | scval;
	}

	cpm_set_brg(pinfo->brg - 1, baud);
	spin_unlock_irqrestore(&port->lock, flags);

}
Example #22
0
static void cpm_uart_set_termios(struct uart_port *port,
                                 struct ktermios *termios,
                                 struct ktermios *old)
{
	int baud;
	unsigned long flags;
	u16 cval, scval, prev_mode;
	int bits, sbits;
	struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
	smc_t __iomem *smcp = pinfo->smcp;
	scc_t __iomem *sccp = pinfo->sccp;

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

	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
	if (baud <= HW_BUF_SPD_THRESHOLD ||
	    (pinfo->port.state && pinfo->port.state->port.tty->low_latency))
		pinfo->rx_fifosize = 1;
	else
		pinfo->rx_fifosize = RX_BUF_SIZE;

	/* Character length programmed into the mode register is the
	 * sum of: 1 start bit, number of data bits, 0 or 1 parity bit,
	 * 1 or 2 stop bits, minus 1.
	 * The value 'bits' counts this for us.
	 */
	cval = 0;
	scval = 0;

	/* byte size */
	switch (termios->c_cflag & CSIZE) {
	case CS5:
		bits = 5;
		break;
	case CS6:
		bits = 6;
		break;
	case CS7:
		bits = 7;
		break;
	case CS8:
		bits = 8;
		break;
		/* Never happens, but GCC is too dumb to figure it out */
	default:
		bits = 8;
		break;
	}
	sbits = bits - 5;

	if (termios->c_cflag & CSTOPB) {
		cval |= SMCMR_SL;	/* Two stops */
		scval |= SCU_PSMR_SL;
		bits++;
	}

	if (termios->c_cflag & PARENB) {
		cval |= SMCMR_PEN;
		scval |= SCU_PSMR_PEN;
		bits++;
		if (!(termios->c_cflag & PARODD)) {
			cval |= SMCMR_PM_EVEN;
			scval |= (SCU_PSMR_REVP | SCU_PSMR_TEVP);
		}
	}

	/*
	 * Update the timeout
	 */
	uart_update_timeout(port, termios->c_cflag, baud);

	/*
	 * Set up parity check flag
	 */
#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))

	port->read_status_mask = (BD_SC_EMPTY | BD_SC_OV);
	if (termios->c_iflag & INPCK)
		port->read_status_mask |= BD_SC_FR | BD_SC_PR;
	if ((termios->c_iflag & BRKINT) || (termios->c_iflag & PARMRK))
		port->read_status_mask |= BD_SC_BR;

	/*
	 * Characters to ignore
	 */
	port->ignore_status_mask = 0;
	if (termios->c_iflag & IGNPAR)
		port->ignore_status_mask |= BD_SC_PR | BD_SC_FR;
	if (termios->c_iflag & IGNBRK) {
		port->ignore_status_mask |= BD_SC_BR;
		/*
		 * If we're ignore parity and break indicators, ignore
		 * overruns too.  (For real raw support).
		 */
		if (termios->c_iflag & IGNPAR)
			port->ignore_status_mask |= BD_SC_OV;
	}
	/*
	 * !!! ignore all characters if CREAD is not set
	 */
	if ((termios->c_cflag & CREAD) == 0)
		port->read_status_mask &= ~BD_SC_EMPTY;

	spin_lock_irqsave(&port->lock, flags);

	/* Start bit has not been added (so don't, because we would just
	 * subtract it later), and we need to add one for the number of
	 * stops bits (there is always at least one).
	 */
	bits++;
	if (IS_SMC(pinfo)) {
		/*
		 * MRBLR can be changed while an SMC/SCC is operating only
		 * if it is done in a single bus cycle with one 16-bit move
		 * (not two 8-bit bus cycles back-to-back). This occurs when
		 * the cp shifts control to the next RxBD, so the change does
		 * not take effect immediately. To guarantee the exact RxBD
		 * on which the change occurs, change MRBLR only while the
		 * SMC/SCC receiver is disabled.
		 */
		out_be16(&pinfo->smcup->smc_mrblr, pinfo->rx_fifosize);

		/* Set the mode register.  We want to keep a copy of the
		 * enables, because we want to put them back if they were
		 * present.
		 */
		prev_mode = in_be16(&smcp->smc_smcmr) & (SMCMR_REN | SMCMR_TEN);
		/* Output in *one* operation, so we don't interrupt RX/TX if they
		 * were already enabled. */
		out_be16(&smcp->smc_smcmr, smcr_mk_clen(bits) | cval |
		    SMCMR_SM_UART | prev_mode);
	} else {
		out_be16(&pinfo->sccup->scc_genscc.scc_mrblr, pinfo->rx_fifosize);
		out_be16(&sccp->scc_psmr, (sbits << 12) | scval);
	}

	if (pinfo->clk)
		clk_set_rate(pinfo->clk, baud);
	else
		cpm_set_brg(pinfo->brg - 1, baud);
	spin_unlock_irqrestore(&port->lock, flags);
}
Example #23
0
static int __init cpm_uart_console_setup(struct console *co, char *options)
{
	int baud = 38400;
	int bits = 8;
	int parity = 'n';
	int flow = 'n';
	int ret;
	struct uart_cpm_port *pinfo;
	struct uart_port *port;

	struct device_node *np = NULL;
	int i = 0;

	if (co->index >= UART_NR) {
		printk(KERN_ERR "cpm_uart: console index %d too high\n",
		       co->index);
		return -ENODEV;
	}

	do {
		np = of_find_node_by_type(np, "serial");
		if (!np)
			return -ENODEV;

		if (!of_device_is_compatible(np, "fsl,cpm1-smc-uart") &&
		    !of_device_is_compatible(np, "fsl,cpm1-scc-uart") &&
		    !of_device_is_compatible(np, "fsl,cpm2-smc-uart") &&
		    !of_device_is_compatible(np, "fsl,cpm2-scc-uart"))
			i--;
	} while (i++ != co->index);

	pinfo = &cpm_uart_ports[co->index];

	pinfo->flags |= FLAG_CONSOLE;
	port = &pinfo->port;

	ret = cpm_uart_init_port(np, pinfo);
	of_node_put(np);
	if (ret)
		return ret;

	if (options) {
		uart_parse_options(options, &baud, &parity, &bits, &flow);
	} else {
		if ((baud = uart_baudrate()) == -1)
			baud = 9600;
	}

#ifdef CONFIG_PPC_EARLY_DEBUG_CPM
	udbg_putc = NULL;
#endif

	if (IS_SMC(pinfo)) {
		out_be16(&pinfo->smcup->smc_brkcr, 0);
		cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX);
		clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX);
		clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN);
	} else {
		out_be16(&pinfo->sccup->scc_brkcr, 0);
		cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX);
		clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
		clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
	}

	ret = cpm_uart_allocbuf(pinfo, 1);

	if (ret)
		return ret;

	cpm_uart_initbd(pinfo);

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

	uart_set_options(port, co, baud, parity, bits, flow);
	cpm_line_cr_cmd(pinfo, CPM_CR_RESTART_TX);

	return 0;
}
Example #24
0
static int __init cpm_uart_console_setup(struct console *co, char *options)
{
	struct uart_port *port;
	struct uart_cpm_port *pinfo;
	int baud = 38400;
	int bits = 8;
	int parity = 'n';
	int flow = 'n';
	int ret;

	struct fs_uart_platform_info *pdata;
	struct platform_device* pdev = early_uart_get_pdev(co->index);

	if (!pdev) {
		pr_info("cpm_uart: console: compat mode\n");
		/* compatibility - will be cleaned up */
		cpm_uart_init_portdesc();
	}

	port =
	    (struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]];
	pinfo = (struct uart_cpm_port *)port;
	if (!pdev) {
		if (pinfo->set_lineif)
			pinfo->set_lineif(pinfo);
	} else {
		pdata = pdev->dev.platform_data;
		if (pdata)
			if (pdata->init_ioports)
    	                	pdata->init_ioports(pdata);

		cpm_uart_drv_get_platform_data(pdev, 1);
	}

	pinfo->flags |= FLAG_CONSOLE;

	if (options) {
		uart_parse_options(options, &baud, &parity, &bits, &flow);
	} else {
		if ((baud = uart_baudrate()) == -1)
			baud = 9600;
	}

	if (IS_SMC(pinfo)) {
		pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
		pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
	} else {
		pinfo->sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX);
		pinfo->sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
	}

	ret = cpm_uart_allocbuf(pinfo, 1);

	if (ret)
		return ret;

	cpm_uart_initbd(pinfo);

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

	uart_set_options(port, co, baud, parity, bits, flow);

	return 0;
}