Skip to content

Commit

Permalink
serial: 8250_fintek: UART dynamic clocksource on Fintek F81866
Browse files Browse the repository at this point in the history
The F81866 had 4 clocksource 1.8432/18.432/14.769/24MHz and baud rates can
be up to 1.5Mbits with 24MHz. We'll implements the dynamic clocksource in
fintek_8250_set_termios().

Signed-off-by: Ji-Ze Hong (Peter Hong) <hpeter+linux_kernel@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Ji-Ze Hong (Peter Hong) authored and Greg Kroah-Hartman committed Oct 3, 2017
1 parent 3b837fa commit 195638b
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions drivers/tty/serial/8250/8250_fintek.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,59 @@ static void fintek_8250_goto_highspeed(struct uart_8250_port *uart,
}
}

void fintek_8250_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old)
{
struct fintek_8250 *pdata = port->private_data;
unsigned int baud = tty_termios_baud_rate(termios);
int i;
static u32 baudrate_table[] = {115200, 921600, 1152000, 1500000};
static u8 clock_table[] = { F81866_UART_CLK_1_8432MHZ,
F81866_UART_CLK_14_769MHZ, F81866_UART_CLK_18_432MHZ,
F81866_UART_CLK_24MHZ };

for (i = 0; i < ARRAY_SIZE(baudrate_table); ++i) {
if (baud > baudrate_table[i] || baudrate_table[i] % baud != 0)
continue;

if (port->uartclk == baudrate_table[i] * 16)
break;

if (fintek_8250_enter_key(pdata->base_port, pdata->key))
continue;

port->uartclk = baudrate_table[i] * 16;

sio_write_reg(pdata, LDN, pdata->index);
sio_write_mask_reg(pdata, F81866_UART_CLK,
F81866_UART_CLK_MASK, clock_table[i]);

fintek_8250_exit_key(pdata->base_port);
break;
}

if (i == ARRAY_SIZE(baudrate_table)) {
baud = tty_termios_baud_rate(old);
tty_termios_encode_baud_rate(termios, baud, baud);
}

serial8250_do_set_termios(port, termios, old);
}

static void fintek_8250_set_termios_handler(struct uart_8250_port *uart)
{
struct fintek_8250 *pdata = uart->port.private_data;

switch (pdata->pid) {
case CHIP_ID_F81866:
uart->port.set_termios = fintek_8250_set_termios;
break;

default:
break;
}
}

static int probe_setup_port(struct fintek_8250 *pdata,
struct uart_8250_port *uart)
{
Expand Down Expand Up @@ -373,6 +426,7 @@ int fintek_8250_probe(struct uart_8250_port *uart)
memcpy(pdata, &probe_data, sizeof(probe_data));
uart->port.private_data = pdata;
fintek_8250_set_rs485_handler(uart);
fintek_8250_set_termios_handler(uart);

return 0;
}

0 comments on commit 195638b

Please sign in to comment.