static int serial_m3110_startup(struct uart_port *port) { struct uart_max3110 *max = container_of(port, struct uart_max3110, port); u16 config = 0; int ret = 0; if (port->line != 0) { pr_err(PR_FMT "uart port startup failed\n"); return -1; } /* Disable all IRQ and config it to 115200, 8n1 */ config = WC_TAG | WC_FIFO_ENABLE | WC_1_STOPBITS | WC_8BIT_WORD | WC_BAUD_DR2; /* as we use thread to handle tx/rx, need set low latency */ port->state->port.tty->low_latency = 1; if (max->irq) { max->read_thread = NULL; ret = request_irq(max->irq, serial_m3110_irq, IRQ_TYPE_EDGE_FALLING, "max3110", max); if (ret) { max->irq = 0; pr_err(PR_FMT "unable to allocate IRQ, polling\n"); } else { /* Enable RX IRQ only */ config |= WC_RXA_IRQ_ENABLE; } } if (max->irq == 0) { /* If IRQ is disabled, start a read thread for input data */ max->read_thread = kthread_run(max3110_read_thread, max, "max3110_read"); if (IS_ERR(max->read_thread)) { ret = PTR_ERR(max->read_thread); max->read_thread = NULL; pr_err(PR_FMT "Can't create read thread!\n"); return ret; } } ret = max3110_out(max, config); if (ret) { if (max->irq) free_irq(max->irq, max); if (max->read_thread) kthread_stop(max->read_thread); max->read_thread = NULL; return ret; } max->cur_conf = config; max->opened = true; return 0; }
static int serial_m3110_resume(struct spi_device *spi) { struct uart_max3110 *max = spi_get_drvdata(spi); max3110_out(max, max->cur_conf); uart_resume_port(&serial_m3110_reg, &max->port); enable_irq(max->irq); return 0; }
static int serial_m3110_suspend(struct spi_device *spi, pm_message_t state) { struct uart_max3110 *max = spi_get_drvdata(spi); disable_irq(max->irq); uart_suspend_port(&serial_m3110_reg, &max->port); max3110_out(max, max->cur_conf | WC_SW_SHDI); return 0; }
static int serial_m3110_suspend(struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct uart_max3110 *max = spi_get_drvdata(spi); if (max->irq > 0) disable_irq(max->irq); uart_suspend_port(&serial_m3110_reg, &max->port); max3110_out(max, max->cur_conf | WC_SW_SHDI); return 0; }
static int serial_m3110_resume(struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct uart_max3110 *max = spi_get_drvdata(spi); /* Enable IRQ before max3110 write */ if (max->irq > 0) enable_irq(max->irq); max3110_out(max, max->cur_conf); uart_resume_port(&serial_m3110_reg, &max->port); return 0; }
static int serial_m3110_startup(struct uart_port *port) { struct uart_max3110 *max = container_of(port, struct uart_max3110, port); u16 config = 0; int ret = 0; if (port->line != 0) pr_err(PR_FMT "uart port startup failed\n"); /* firstly disable all IRQ and config it to 115200, 8n1 */ config = WC_TAG | WC_FIFO_ENABLE | WC_1_STOPBITS | WC_8BIT_WORD | WC_BAUD_DR2; ret = max3110_out(max, config); /* as we use thread to handle tx/rx, need set low latency */ port->state->port.tty->low_latency = 1; #ifdef CONFIG_MRST_MAX3110_IRQ ret = request_irq(max->irq, serial_m3110_irq, IRQ_TYPE_EDGE_FALLING, "max3110", max); if (ret) return ret; /* enable RX IRQ only */ config |= WC_RXA_IRQ_ENABLE; max3110_out(max, config); #else /* if IRQ is disabled, start a read thread for input data */ max->read_thread = kthread_run(max3110_read_thread, max, "max3110_read"); #endif max->cur_conf = config; return 0; }
static void serial_m3110_shutdown(struct uart_port *port) { struct uart_max3110 *max = container_of(port, struct uart_max3110, port); u16 config; if (max->read_thread) { kthread_stop(max->read_thread); max->read_thread = NULL; } /* Disable interrupts from this port */ config = WC_TAG | WC_SW_SHDI; max3110_out(max, config); }
static void serial_m3110_shutdown(struct uart_port *port) { struct uart_max3110 *max = container_of(port, struct uart_max3110, port); u16 config; if (max->read_thread) { kthread_stop(max->read_thread); max->read_thread = NULL; } #ifdef CONFIG_MRST_MAX3110_IRQ free_irq(max->irq, max); #endif /* Disable interrupts from this port */ config = WC_TAG | WC_SW_SHDI; max3110_out(max, config); }
static void serial_m3110_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct uart_max3110 *max = container_of(port, struct uart_max3110, port); unsigned char cval; unsigned int baud, parity = 0; int clk_div = -1; u16 new_conf = max->cur_conf; switch (termios->c_cflag & CSIZE) { case CS7: cval = UART_LCR_WLEN7; new_conf |= WC_7BIT_WORD; break; default: case CS8: cval = UART_LCR_WLEN8; new_conf |= WC_8BIT_WORD; break; } baud = uart_get_baud_rate(port, termios, old, 0, 230400); /* first calc the div for 1.8MHZ clock case */ switch (baud) { case 300: clk_div = WC_BAUD_DR384; break; case 600: clk_div = WC_BAUD_DR192; break; case 1200: clk_div = WC_BAUD_DR96; break; case 2400: clk_div = WC_BAUD_DR48; break; case 4800: clk_div = WC_BAUD_DR24; break; case 9600: clk_div = WC_BAUD_DR12; break; case 19200: clk_div = WC_BAUD_DR6; break; case 38400: clk_div = WC_BAUD_DR3; break; case 57600: clk_div = WC_BAUD_DR2; break; case 115200: clk_div = WC_BAUD_DR1; break; case 230400: if (max->clock & MAX3110_HIGH_CLK) break; default: /* pick the previous baud rate */ baud = max->baud; clk_div = max->cur_conf & WC_BAUD_DIV_MASK; tty_termios_encode_baud_rate(termios, baud, baud); } if (max->clock & MAX3110_HIGH_CLK) { clk_div += 1; /* high clk version max3110 doesn't support B300 */ if (baud == 300) baud = 600; if (baud == 230400) clk_div = WC_BAUD_DR1; tty_termios_encode_baud_rate(termios, baud, baud); } new_conf = (new_conf & ~WC_BAUD_DIV_MASK) | clk_div; if (termios->c_cflag & CSTOPB) new_conf |= WC_2_STOPBITS; else new_conf &= ~WC_2_STOPBITS; if (termios->c_cflag & PARENB) { new_conf |= WC_PARITY_ENABLE; parity |= UART_LCR_PARITY; } else new_conf &= ~WC_PARITY_ENABLE; if (!(termios->c_cflag & PARODD)) parity |= UART_LCR_EPAR; max->parity = parity; uart_update_timeout(port, termios->c_cflag, baud); new_conf |= WC_TAG; if (new_conf != max->cur_conf) { max3110_out(max, new_conf); max->cur_conf = new_conf; max->baud = baud; } }