Ejemplo n.º 1
0
static void max310x_port_irq(struct max310x_port *s, int portno)
{
	struct uart_port *port = &s->p[portno].port;

	do {
		unsigned int ists, lsr, rxlen;

		/* Read IRQ status & RX FIFO level */
		ists = max310x_port_read(port, MAX310X_IRQSTS_REG);
		rxlen = max310x_port_read(port, MAX310X_RXFIFOLVL_REG);
		if (!ists && !rxlen)
			break;

		if (ists & MAX310X_IRQ_CTS_BIT) {
			lsr = max310x_port_read(port, MAX310X_LSR_IRQSTS_REG);
			uart_handle_cts_change(port,
					       !!(lsr & MAX310X_LSR_CTS_BIT));
		}
		if (rxlen)
			max310x_handle_rx(port, rxlen);
		if (ists & MAX310X_IRQ_TXEMPTY_BIT) {
			mutex_lock(&s->mutex);
			max310x_handle_tx(port);
			mutex_unlock(&s->mutex);
		}
	} while (1);
}
Ejemplo n.º 2
0
static unsigned int max310x_tx_empty(struct uart_port *port)
{
	unsigned int lvl, sts;

	lvl = max310x_port_read(port, MAX310X_TXFIFOLVL_REG);
	sts = max310x_port_read(port, MAX310X_IRQSTS_REG);

	return ((sts & MAX310X_IRQ_TXEMPTY_BIT) && !lvl) ? TIOCSER_TEMT : 0;
}
Ejemplo n.º 3
0
static void max310x_handle_rx(struct uart_port *port, unsigned int rxlen)
{
	unsigned int sts, ch, flag;

	if (unlikely(rxlen >= port->fifosize)) {
		dev_warn_ratelimited(port->dev,
				     "Port %i: Possible RX FIFO overrun\n",
				     port->line);
		port->icount.buf_overrun++;
		/* Ensure sanity of RX level */
		rxlen = port->fifosize;
	}

	while (rxlen--) {
		ch = max310x_port_read(port, MAX310X_RHR_REG);
		sts = max310x_port_read(port, MAX310X_LSR_IRQSTS_REG);

		sts &= MAX310X_LSR_RXPAR_BIT | MAX310X_LSR_FRERR_BIT |
		       MAX310X_LSR_RXOVR_BIT | MAX310X_LSR_RXBRK_BIT;

		port->icount.rx++;
		flag = TTY_NORMAL;

		if (unlikely(sts)) {
			if (sts & MAX310X_LSR_RXBRK_BIT) {
				port->icount.brk++;
				if (uart_handle_break(port))
					continue;
			} else if (sts & MAX310X_LSR_RXPAR_BIT)
				port->icount.parity++;
			else if (sts & MAX310X_LSR_FRERR_BIT)
				port->icount.frame++;
			else if (sts & MAX310X_LSR_RXOVR_BIT)
				port->icount.overrun++;

			sts &= port->read_status_mask;
			if (sts & MAX310X_LSR_RXBRK_BIT)
				flag = TTY_BREAK;
			else if (sts & MAX310X_LSR_RXPAR_BIT)
				flag = TTY_PARITY;
			else if (sts & MAX310X_LSR_FRERR_BIT)
				flag = TTY_FRAME;
			else if (sts & MAX310X_LSR_RXOVR_BIT)
				flag = TTY_OVERRUN;
		}

		if (uart_handle_sysrq_char(port, ch))
			continue;

		if (sts & port->ignore_status_mask)
			continue;

		uart_insert_char(port, sts, MAX310X_LSR_RXOVR_BIT, ch, flag);
	}

	tty_flip_buffer_push(&port->state->port);
}
Ejemplo n.º 4
0
static int max310x_ioctl(struct uart_port *port, unsigned int cmd,
			 unsigned long arg)
{
#if defined(TIOCSRS485) && defined(TIOCGRS485)
	struct serial_rs485 rs485;
	unsigned int val;

	switch (cmd) {
	case TIOCSRS485:
		if (copy_from_user(&rs485, (void __user *)arg, sizeof(rs485)))
			return -EFAULT;
		if (rs485.delay_rts_before_send > 0x0f ||
		    rs485.delay_rts_after_send > 0x0f)
			return -ERANGE;
		val = (rs485.delay_rts_before_send << 4) |
		      rs485.delay_rts_after_send;
		max310x_port_write(port, MAX310X_HDPIXDELAY_REG, val);
		if (rs485.flags & SER_RS485_ENABLED) {
			max310x_port_update(port, MAX310X_MODE1_REG,
					    MAX310X_MODE1_TRNSCVCTRL_BIT,
					    MAX310X_MODE1_TRNSCVCTRL_BIT);
			max310x_port_update(port, MAX310X_MODE2_REG,
					    MAX310X_MODE2_ECHOSUPR_BIT,
					    MAX310X_MODE2_ECHOSUPR_BIT);
		} else {
			max310x_port_update(port, MAX310X_MODE1_REG,
					    MAX310X_MODE1_TRNSCVCTRL_BIT, 0);
			max310x_port_update(port, MAX310X_MODE2_REG,
					    MAX310X_MODE2_ECHOSUPR_BIT, 0);
		}
		return 0;
	case TIOCGRS485:
		memset(&rs485, 0, sizeof(rs485));
		val = max310x_port_read(port, MAX310X_MODE1_REG);
		rs485.flags = (val & MAX310X_MODE1_TRNSCVCTRL_BIT) ?
			      SER_RS485_ENABLED : 0;
		rs485.flags |= SER_RS485_RTS_ON_SEND;
		val = max310x_port_read(port, MAX310X_HDPIXDELAY_REG);
		rs485.delay_rts_before_send = val >> 4;
		rs485.delay_rts_after_send = val & 0x0f;
		if (copy_to_user((void __user *)arg, &rs485, sizeof(rs485)))
			return -EFAULT;
		return 0;
	default:
		break;
	}
#endif

	return -ENOIOCTLCMD;
}
Ejemplo n.º 5
0
static int max310x_startup(struct uart_port *port)
{
	struct max310x_port *s = dev_get_drvdata(port->dev);
	unsigned int val;

	s->devtype->power(port, 1);

	/* Configure MODE1 register */
	max310x_port_update(port, MAX310X_MODE1_REG,
			    MAX310X_MODE1_TRNSCVCTRL_BIT, 0);

	/* Configure MODE2 register & Reset FIFOs*/
	val = MAX310X_MODE2_RXEMPTINV_BIT | MAX310X_MODE2_FIFORST_BIT;
	max310x_port_write(port, MAX310X_MODE2_REG, val);
	max310x_port_update(port, MAX310X_MODE2_REG,
			    MAX310X_MODE2_FIFORST_BIT, 0);

	/* Configure flow control levels */
	/* Flow control halt level 96, resume level 48 */
	max310x_port_write(port, MAX310X_FLOWLVL_REG,
			   MAX310X_FLOWLVL_RES(48) | MAX310X_FLOWLVL_HALT(96));

	/* Clear IRQ status register */
	max310x_port_read(port, MAX310X_IRQSTS_REG);

	/* Enable RX, TX, CTS change interrupts */
	val = MAX310X_IRQ_RXEMPTY_BIT | MAX310X_IRQ_TXEMPTY_BIT;
	max310x_port_write(port, MAX310X_IRQEN_REG, val | MAX310X_IRQ_CTS_BIT);

	return 0;
}
Ejemplo n.º 6
0
static void max310x_handle_tx(struct uart_port *port)
{
	struct circ_buf *xmit = &port->state->xmit;
	unsigned int txlen, to_send;

	if (unlikely(port->x_char)) {
		max310x_port_write(port, MAX310X_THR_REG, port->x_char);
		port->icount.tx++;
		port->x_char = 0;
		return;
	}

	if (uart_circ_empty(xmit) || uart_tx_stopped(port))
		return;

	/* Get length of data pending in circular buffer */
	to_send = uart_circ_chars_pending(xmit);
	if (likely(to_send)) {
		/* Limit to size of TX FIFO */
		txlen = max310x_port_read(port, MAX310X_TXFIFOLVL_REG);
		txlen = port->fifosize - txlen;
		to_send = (to_send > txlen) ? txlen : to_send;

		/* Add data to send */
		port->icount.tx += to_send;
		while (to_send--) {
			max310x_port_write(port, MAX310X_THR_REG,
					   xmit->buf[xmit->tail]);
			xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		}
	}

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(port);
}
Ejemplo n.º 7
0
static int max310x_gpio_get(struct gpio_chip *chip, unsigned offset)
{
	unsigned int val;
	struct max310x_port *s = container_of(chip, struct max310x_port, gpio);
	struct uart_port *port = &s->p[offset / 4].port;

	val = max310x_port_read(port, MAX310X_GPIODATA_REG);

	return !!((val >> 4) & (1 << (offset % 4)));
}
Ejemplo n.º 8
0
static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
			 struct regmap *regmap, int irq, unsigned long flags)
{
	int i, ret, fmin, fmax, freq, uartclk;
	struct clk *clk_osc, *clk_xtal;
	struct max310x_port *s;
	bool xtal = false;

	if (IS_ERR(regmap))
		return PTR_ERR(regmap);

	/* Alloc port structure */
	s = devm_kzalloc(dev, sizeof(*s) +
			 sizeof(struct max310x_one) * devtype->nr, GFP_KERNEL);
	if (!s) {
		dev_err(dev, "Error allocating port structure\n");
		return -ENOMEM;
	}

	clk_osc = devm_clk_get(dev, "osc");
	clk_xtal = devm_clk_get(dev, "xtal");
	if (!IS_ERR(clk_osc)) {
		s->clk = clk_osc;
		fmin = 500000;
		fmax = 35000000;
	} else if (!IS_ERR(clk_xtal)) {
		s->clk = clk_xtal;
		fmin = 1000000;
		fmax = 4000000;
		xtal = true;
	} else if (PTR_ERR(clk_osc) == -EPROBE_DEFER ||
		   PTR_ERR(clk_xtal) == -EPROBE_DEFER) {
		return -EPROBE_DEFER;
	} else {
		dev_err(dev, "Cannot get clock\n");
		return -EINVAL;
	}

	ret = clk_prepare_enable(s->clk);
	if (ret)
		return ret;

	freq = clk_get_rate(s->clk);
	/* Check frequency limits */
	if (freq < fmin || freq > fmax) {
		ret = -ERANGE;
		goto out_clk;
	}

	s->regmap = regmap;
	s->devtype = devtype;
	dev_set_drvdata(dev, s);

	/* Check device to ensure we are talking to what we expect */
	ret = devtype->detect(dev);
	if (ret)
		goto out_clk;

	for (i = 0; i < devtype->nr; i++) {
		unsigned int offs = i << 5;

		/* Reset port */
		regmap_write(s->regmap, MAX310X_MODE2_REG + offs,
			     MAX310X_MODE2_RST_BIT);
		/* Clear port reset */
		regmap_write(s->regmap, MAX310X_MODE2_REG + offs, 0);

		/* Wait for port startup */
		do {
			regmap_read(s->regmap,
				    MAX310X_BRGDIVLSB_REG + offs, &ret);
		} while (ret != 0x01);

		regmap_update_bits(s->regmap, MAX310X_MODE1_REG + offs,
				   MAX310X_MODE1_AUTOSLEEP_BIT,
				   MAX310X_MODE1_AUTOSLEEP_BIT);
	}

	uartclk = max310x_set_ref_clk(s, freq, xtal);
	dev_dbg(dev, "Reference clock set to %i Hz\n", uartclk);

	/* Register UART driver */
	s->uart.owner		= THIS_MODULE;
	s->uart.dev_name	= "ttyMAX";
	s->uart.major		= MAX310X_MAJOR;
	s->uart.minor		= MAX310X_MINOR;
	s->uart.nr		= devtype->nr;
	ret = uart_register_driver(&s->uart);
	if (ret) {
		dev_err(dev, "Registering UART driver failed\n");
		goto out_clk;
	}

#ifdef CONFIG_GPIOLIB
	/* Setup GPIO cotroller */
	s->gpio.owner		= THIS_MODULE;
	s->gpio.dev		= dev;
	s->gpio.label		= dev_name(dev);
	s->gpio.direction_input	= max310x_gpio_direction_input;
	s->gpio.get		= max310x_gpio_get;
	s->gpio.direction_output= max310x_gpio_direction_output;
	s->gpio.set		= max310x_gpio_set;
	s->gpio.base		= -1;
	s->gpio.ngpio		= devtype->nr * 4;
	s->gpio.can_sleep	= 1;
	ret = gpiochip_add(&s->gpio);
	if (ret)
		goto out_uart;
#endif

	mutex_init(&s->mutex);

	for (i = 0; i < devtype->nr; i++) {
		/* Initialize port data */
		s->p[i].port.line	= i;
		s->p[i].port.dev	= dev;
		s->p[i].port.irq	= irq;
		s->p[i].port.type	= PORT_MAX310X;
		s->p[i].port.fifosize	= MAX310X_FIFO_SIZE;
		s->p[i].port.flags	= UPF_FIXED_TYPE | UPF_LOW_LATENCY;
		s->p[i].port.iotype	= UPIO_PORT;
		s->p[i].port.iobase	= i * 0x20;
		s->p[i].port.membase	= (void __iomem *)~0;
		s->p[i].port.uartclk	= uartclk;
		s->p[i].port.rs485_config = max310x_rs485_config;
		s->p[i].port.ops	= &max310x_ops;
		/* Disable all interrupts */
		max310x_port_write(&s->p[i].port, MAX310X_IRQEN_REG, 0);
		/* Clear IRQ status register */
		max310x_port_read(&s->p[i].port, MAX310X_IRQSTS_REG);
		/* Enable IRQ pin */
		max310x_port_update(&s->p[i].port, MAX310X_MODE1_REG,
				    MAX310X_MODE1_IRQSEL_BIT,
				    MAX310X_MODE1_IRQSEL_BIT);
		/* Initialize queue for start TX */
		INIT_WORK(&s->p[i].tx_work, max310x_wq_proc);
		/* Initialize queue for changing mode */
		INIT_WORK(&s->p[i].md_work, max310x_md_proc);
		/* Register port */
		uart_add_one_port(&s->uart, &s->p[i].port);
		/* Go to suspend mode */
		devtype->power(&s->p[i].port, 0);
	}

	/* Setup interrupt */
	ret = devm_request_threaded_irq(dev, irq, NULL, max310x_ist,
					IRQF_ONESHOT | flags, dev_name(dev), s);
	if (!ret)
		return 0;

	dev_err(dev, "Unable to reguest IRQ %i\n", irq);

	mutex_destroy(&s->mutex);

#ifdef CONFIG_GPIOLIB
	gpiochip_remove(&s->gpio);

out_uart:
#endif
	uart_unregister_driver(&s->uart);

out_clk:
	clk_disable_unprepare(s->clk);

	return ret;
}