^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * SiFive UART driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2018 Paul Walmsley <paul@pwsan.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2018-2019 SiFive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * it under the terms of the GNU General Public License as published by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * the Free Software Foundation; either version 2 of the License, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * (at your option) any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * This program is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Based partially on:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * - drivers/tty/serial/pxa.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * - drivers/tty/serial/amba-pl011.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * - drivers/tty/serial/uartlite.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * - drivers/tty/serial/omap-serial.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * - drivers/pwm/pwm-sifive.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * See the following sources for further documentation:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * - Chapter 19 "Universal Asynchronous Receiver/Transmitter (UART)" of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * SiFive FE310-G000 v2p3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * - The tree/master/src/main/scala/devices/uart directory of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * https://github.com/sifive/sifive-blocks/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * The SiFive UART design is not 8250-compatible. The following common
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * features are not supported:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * - Word lengths other than 8 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * - Break handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * - Parity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * - Flow control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * - Modem signals (DSR, RI, etc.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * On the other hand, the design is free from the baggage of the 8250
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * programming model.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <linux/serial_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <linux/serial_reg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * Register offsets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* TXDATA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define SIFIVE_SERIAL_TXDATA_OFFS 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define SIFIVE_SERIAL_TXDATA_FULL_SHIFT 31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define SIFIVE_SERIAL_TXDATA_FULL_MASK (1 << SIFIVE_SERIAL_TXDATA_FULL_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define SIFIVE_SERIAL_TXDATA_DATA_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define SIFIVE_SERIAL_TXDATA_DATA_MASK (0xff << SIFIVE_SERIAL_TXDATA_DATA_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* RXDATA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define SIFIVE_SERIAL_RXDATA_OFFS 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define SIFIVE_SERIAL_RXDATA_EMPTY_SHIFT 31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define SIFIVE_SERIAL_RXDATA_EMPTY_MASK (1 << SIFIVE_SERIAL_RXDATA_EMPTY_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define SIFIVE_SERIAL_RXDATA_DATA_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define SIFIVE_SERIAL_RXDATA_DATA_MASK (0xff << SIFIVE_SERIAL_RXDATA_DATA_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* TXCTRL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define SIFIVE_SERIAL_TXCTRL_OFFS 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define SIFIVE_SERIAL_TXCTRL_TXCNT_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define SIFIVE_SERIAL_TXCTRL_TXCNT_MASK (0x7 << SIFIVE_SERIAL_TXCTRL_TXCNT_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define SIFIVE_SERIAL_TXCTRL_NSTOP_SHIFT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define SIFIVE_SERIAL_TXCTRL_NSTOP_MASK (1 << SIFIVE_SERIAL_TXCTRL_NSTOP_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define SIFIVE_SERIAL_TXCTRL_TXEN_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define SIFIVE_SERIAL_TXCTRL_TXEN_MASK (1 << SIFIVE_SERIAL_TXCTRL_TXEN_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* RXCTRL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define SIFIVE_SERIAL_RXCTRL_OFFS 0xC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define SIFIVE_SERIAL_RXCTRL_RXCNT_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define SIFIVE_SERIAL_RXCTRL_RXCNT_MASK (0x7 << SIFIVE_SERIAL_TXCTRL_TXCNT_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define SIFIVE_SERIAL_RXCTRL_RXEN_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define SIFIVE_SERIAL_RXCTRL_RXEN_MASK (1 << SIFIVE_SERIAL_RXCTRL_RXEN_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /* IE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define SIFIVE_SERIAL_IE_OFFS 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define SIFIVE_SERIAL_IE_RXWM_SHIFT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define SIFIVE_SERIAL_IE_RXWM_MASK (1 << SIFIVE_SERIAL_IE_RXWM_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define SIFIVE_SERIAL_IE_TXWM_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define SIFIVE_SERIAL_IE_TXWM_MASK (1 << SIFIVE_SERIAL_IE_TXWM_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* IP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define SIFIVE_SERIAL_IP_OFFS 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define SIFIVE_SERIAL_IP_RXWM_SHIFT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define SIFIVE_SERIAL_IP_RXWM_MASK (1 << SIFIVE_SERIAL_IP_RXWM_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define SIFIVE_SERIAL_IP_TXWM_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define SIFIVE_SERIAL_IP_TXWM_MASK (1 << SIFIVE_SERIAL_IP_TXWM_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* DIV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define SIFIVE_SERIAL_DIV_OFFS 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define SIFIVE_SERIAL_DIV_DIV_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define SIFIVE_SERIAL_DIV_DIV_MASK (0xffff << SIFIVE_SERIAL_IP_DIV_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * Config macros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * SIFIVE_SERIAL_MAX_PORTS: maximum number of UARTs on a device that can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * host a serial console
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define SIFIVE_SERIAL_MAX_PORTS 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * SIFIVE_DEFAULT_BAUD_RATE: default baud rate that the driver should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * configure itself to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define SIFIVE_DEFAULT_BAUD_RATE 115200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* SIFIVE_SERIAL_NAME: our driver's name that we pass to the operating system */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define SIFIVE_SERIAL_NAME "sifive-serial"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* SIFIVE_TTY_PREFIX: tty name prefix for SiFive serial ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define SIFIVE_TTY_PREFIX "ttySIF"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* SIFIVE_TX_FIFO_DEPTH: depth of the TX FIFO (in bytes) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define SIFIVE_TX_FIFO_DEPTH 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* SIFIVE_RX_FIFO_DEPTH: depth of the TX FIFO (in bytes) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define SIFIVE_RX_FIFO_DEPTH 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #if (SIFIVE_TX_FIFO_DEPTH != SIFIVE_RX_FIFO_DEPTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #error Driver does not support configurations with different TX, RX FIFO sizes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * sifive_serial_port - driver-specific data extension to struct uart_port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * @port: struct uart_port embedded in this struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * @dev: struct device *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * @ier: shadowed copy of the interrupt enable register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * @clkin_rate: input clock to the UART IP block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * @baud_rate: UART serial line rate (e.g., 115200 baud)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * @clk_notifier: clock rate change notifier for upstream clock changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * Configuration data specific to this SiFive UART.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct sifive_serial_port {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct uart_port port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) unsigned char ier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) unsigned long clkin_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) unsigned long baud_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct notifier_block clk_notifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * Structure container-of macros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define port_to_sifive_serial_port(p) (container_of((p), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct sifive_serial_port, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #define notifier_to_sifive_serial_port(nb) (container_of((nb), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct sifive_serial_port, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) clk_notifier))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * Forward declarations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static void sifive_serial_stop_tx(struct uart_port *port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * Internal functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * __ssp_early_writel() - write to a SiFive serial port register (early)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * @port: pointer to a struct uart_port record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * @offs: register address offset from the IP block base address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * @v: value to write to the register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * Given a pointer @port to a struct uart_port record, write the value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * @v to the IP block register address offset @offs. This function is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * intended for early console use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * Context: Intended to be used only by the earlyconsole code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static void __ssp_early_writel(u32 v, u16 offs, struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) writel_relaxed(v, port->membase + offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * __ssp_early_readl() - read from a SiFive serial port register (early)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * @port: pointer to a struct uart_port record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * @offs: register address offset from the IP block base address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * Given a pointer @port to a struct uart_port record, read the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * contents of the IP block register located at offset @offs from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * IP block base and return it. This function is intended for early
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * console use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * Context: Intended to be called only by the earlyconsole code or by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * __ssp_readl() or __ssp_writel() (in this driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * Returns: the register value read from the UART.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static u32 __ssp_early_readl(struct uart_port *port, u16 offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return readl_relaxed(port->membase + offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * __ssp_writel() - write to a SiFive serial port register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * @v: value to write to the register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * @offs: register address offset from the IP block base address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * @ssp: pointer to a struct sifive_serial_port record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * Write the value @v to the IP block register located at offset @offs from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * IP block base, given a pointer @ssp to a struct sifive_serial_port record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * Context: Any context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static void __ssp_writel(u32 v, u16 offs, struct sifive_serial_port *ssp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) __ssp_early_writel(v, offs, &ssp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * __ssp_readl() - read from a SiFive serial port register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * @ssp: pointer to a struct sifive_serial_port record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * @offs: register address offset from the IP block base address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * Read the contents of the IP block register located at offset @offs from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * IP block base, given a pointer @ssp to a struct sifive_serial_port record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * Context: Any context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * Returns: the value of the UART register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static u32 __ssp_readl(struct sifive_serial_port *ssp, u16 offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return __ssp_early_readl(&ssp->port, offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * sifive_serial_is_txfifo_full() - is the TXFIFO full?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * @ssp: pointer to a struct sifive_serial_port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * Read the transmit FIFO "full" bit, returning a non-zero value if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * TX FIFO is full, or zero if space remains. Intended to be used to prevent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * writes to the TX FIFO when it's full.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * Returns: SIFIVE_SERIAL_TXDATA_FULL_MASK (non-zero) if the transmit FIFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * is full, or 0 if space remains.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static int sifive_serial_is_txfifo_full(struct sifive_serial_port *ssp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return __ssp_readl(ssp, SIFIVE_SERIAL_TXDATA_OFFS) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) SIFIVE_SERIAL_TXDATA_FULL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * __ssp_transmit_char() - enqueue a byte to transmit onto the TX FIFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * @ssp: pointer to a struct sifive_serial_port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * @ch: character to transmit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * Enqueue a byte @ch onto the transmit FIFO, given a pointer @ssp to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * struct sifive_serial_port * to transmit on. Caller should first check to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * ensure that the TXFIFO has space; see sifive_serial_is_txfifo_full().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * Context: Any context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static void __ssp_transmit_char(struct sifive_serial_port *ssp, int ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) __ssp_writel(ch, SIFIVE_SERIAL_TXDATA_OFFS, ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * __ssp_transmit_chars() - enqueue multiple bytes onto the TX FIFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * @ssp: pointer to a struct sifive_serial_port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * Transfer up to a TX FIFO size's worth of characters from the Linux serial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * transmit buffer to the SiFive UART TX FIFO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * Context: Any context. Expects @ssp->port.lock to be held by caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static void __ssp_transmit_chars(struct sifive_serial_port *ssp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct circ_buf *xmit = &ssp->port.state->xmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (ssp->port.x_char) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) __ssp_transmit_char(ssp, ssp->port.x_char);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) ssp->port.icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) ssp->port.x_char = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (uart_circ_empty(xmit) || uart_tx_stopped(&ssp->port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) sifive_serial_stop_tx(&ssp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) count = SIFIVE_TX_FIFO_DEPTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) __ssp_transmit_char(ssp, xmit->buf[xmit->tail]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) ssp->port.icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (uart_circ_empty(xmit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) } while (--count > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) uart_write_wakeup(&ssp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (uart_circ_empty(xmit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) sifive_serial_stop_tx(&ssp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) * __ssp_enable_txwm() - enable transmit watermark interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * @ssp: pointer to a struct sifive_serial_port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * Enable interrupt generation when the transmit FIFO watermark is reached
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * on the SiFive UART referred to by @ssp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static void __ssp_enable_txwm(struct sifive_serial_port *ssp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (ssp->ier & SIFIVE_SERIAL_IE_TXWM_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) ssp->ier |= SIFIVE_SERIAL_IE_TXWM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) __ssp_writel(ssp->ier, SIFIVE_SERIAL_IE_OFFS, ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * __ssp_enable_rxwm() - enable receive watermark interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * @ssp: pointer to a struct sifive_serial_port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * Enable interrupt generation when the receive FIFO watermark is reached
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * on the SiFive UART referred to by @ssp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static void __ssp_enable_rxwm(struct sifive_serial_port *ssp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (ssp->ier & SIFIVE_SERIAL_IE_RXWM_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) ssp->ier |= SIFIVE_SERIAL_IE_RXWM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) __ssp_writel(ssp->ier, SIFIVE_SERIAL_IE_OFFS, ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * __ssp_disable_txwm() - disable transmit watermark interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * @ssp: pointer to a struct sifive_serial_port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * Disable interrupt generation when the transmit FIFO watermark is reached
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * on the UART referred to by @ssp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static void __ssp_disable_txwm(struct sifive_serial_port *ssp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (!(ssp->ier & SIFIVE_SERIAL_IE_TXWM_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) ssp->ier &= ~SIFIVE_SERIAL_IE_TXWM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) __ssp_writel(ssp->ier, SIFIVE_SERIAL_IE_OFFS, ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * __ssp_disable_rxwm() - disable receive watermark interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) * @ssp: pointer to a struct sifive_serial_port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) * Disable interrupt generation when the receive FIFO watermark is reached
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * on the UART referred to by @ssp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) static void __ssp_disable_rxwm(struct sifive_serial_port *ssp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (!(ssp->ier & SIFIVE_SERIAL_IE_RXWM_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) ssp->ier &= ~SIFIVE_SERIAL_IE_RXWM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) __ssp_writel(ssp->ier, SIFIVE_SERIAL_IE_OFFS, ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * __ssp_receive_char() - receive a byte from the UART
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * @ssp: pointer to a struct sifive_serial_port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * @is_empty: char pointer to return whether the RX FIFO is empty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * Try to read a byte from the SiFive UART RX FIFO, referenced by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * @ssp, and to return it. Also returns the RX FIFO empty bit in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * the char pointed to by @ch. The caller must pass the byte back to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * Linux serial layer if needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * Returns: the byte read from the UART RX FIFO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static char __ssp_receive_char(struct sifive_serial_port *ssp, char *is_empty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) u32 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) u8 ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) v = __ssp_readl(ssp, SIFIVE_SERIAL_RXDATA_OFFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (!is_empty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) *is_empty = (v & SIFIVE_SERIAL_RXDATA_EMPTY_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) SIFIVE_SERIAL_RXDATA_EMPTY_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) ch = (v & SIFIVE_SERIAL_RXDATA_DATA_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) SIFIVE_SERIAL_RXDATA_DATA_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) * __ssp_receive_chars() - receive multiple bytes from the UART
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * @ssp: pointer to a struct sifive_serial_port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * Receive up to an RX FIFO's worth of bytes from the SiFive UART referred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * to by @ssp and pass them up to the Linux serial layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * Context: Expects ssp->port.lock to be held by caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) static void __ssp_receive_chars(struct sifive_serial_port *ssp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) unsigned char ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) char is_empty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) int c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) for (c = SIFIVE_RX_FIFO_DEPTH; c > 0; --c) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) ch = __ssp_receive_char(ssp, &is_empty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (is_empty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) ssp->port.icount.rx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) uart_insert_char(&ssp->port, 0, 0, ch, TTY_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) spin_unlock(&ssp->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) tty_flip_buffer_push(&ssp->port.state->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) spin_lock(&ssp->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * __ssp_update_div() - calculate the divisor setting by the line rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * @ssp: pointer to a struct sifive_serial_port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * Calculate the appropriate value of the clock divisor for the UART
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * and target line rate referred to by @ssp and write it into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) * hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) static void __ssp_update_div(struct sifive_serial_port *ssp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) u16 div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) div = DIV_ROUND_UP(ssp->clkin_rate, ssp->baud_rate) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) __ssp_writel(div, SIFIVE_SERIAL_DIV_OFFS, ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * __ssp_update_baud_rate() - set the UART "baud rate"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) * @ssp: pointer to a struct sifive_serial_port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * @rate: new target bit rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) * Calculate the UART divisor value for the target bit rate @rate for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * SiFive UART described by @ssp and program it into the UART. There may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * be some error between the target bit rate and the actual bit rate implemented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * by the UART due to clock ratio granularity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static void __ssp_update_baud_rate(struct sifive_serial_port *ssp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) unsigned int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (ssp->baud_rate == rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) ssp->baud_rate = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) __ssp_update_div(ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) * __ssp_set_stop_bits() - set the number of stop bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * @ssp: pointer to a struct sifive_serial_port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) * @nstop: 1 or 2 (stop bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) * Program the SiFive UART referred to by @ssp to use @nstop stop bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) static void __ssp_set_stop_bits(struct sifive_serial_port *ssp, char nstop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) u32 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (nstop < 1 || nstop > 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) v = __ssp_readl(ssp, SIFIVE_SERIAL_TXCTRL_OFFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) v &= ~SIFIVE_SERIAL_TXCTRL_NSTOP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) v |= (nstop - 1) << SIFIVE_SERIAL_TXCTRL_NSTOP_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) __ssp_writel(v, SIFIVE_SERIAL_TXCTRL_OFFS, ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * __ssp_wait_for_xmitr() - wait for an empty slot on the TX FIFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * @ssp: pointer to a struct sifive_serial_port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) * Delay while the UART TX FIFO referred to by @ssp is marked as full.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * Context: Any context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) static void __maybe_unused __ssp_wait_for_xmitr(struct sifive_serial_port *ssp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) while (sifive_serial_is_txfifo_full(ssp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) udelay(1); /* XXX Could probably be more intelligent here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) * Linux serial API functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) static void sifive_serial_stop_tx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct sifive_serial_port *ssp = port_to_sifive_serial_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) __ssp_disable_txwm(ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static void sifive_serial_stop_rx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct sifive_serial_port *ssp = port_to_sifive_serial_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) __ssp_disable_rxwm(ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) static void sifive_serial_start_tx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) struct sifive_serial_port *ssp = port_to_sifive_serial_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) __ssp_enable_txwm(ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) static irqreturn_t sifive_serial_irq(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) struct sifive_serial_port *ssp = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) u32 ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) spin_lock(&ssp->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) ip = __ssp_readl(ssp, SIFIVE_SERIAL_IP_OFFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (!ip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) spin_unlock(&ssp->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (ip & SIFIVE_SERIAL_IP_RXWM_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) __ssp_receive_chars(ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (ip & SIFIVE_SERIAL_IP_TXWM_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) __ssp_transmit_chars(ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) spin_unlock(&ssp->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static unsigned int sifive_serial_tx_empty(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) return TIOCSER_TEMT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) static unsigned int sifive_serial_get_mctrl(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static void sifive_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) /* IP block does not support these signals */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) static void sifive_serial_break_ctl(struct uart_port *port, int break_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) /* IP block does not support sending a break */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) static int sifive_serial_startup(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) struct sifive_serial_port *ssp = port_to_sifive_serial_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) __ssp_enable_rxwm(ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) static void sifive_serial_shutdown(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) struct sifive_serial_port *ssp = port_to_sifive_serial_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) __ssp_disable_rxwm(ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) __ssp_disable_txwm(ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * sifive_serial_clk_notifier() - clock post-rate-change notifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * @nb: pointer to the struct notifier_block, from the notifier code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * @event: event mask from the notifier code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * @data: pointer to the struct clk_notifier_data from the notifier code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * On the V0 SoC, the UART IP block is derived from the CPU clock source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * after a synchronous divide-by-two divider, so any CPU clock rate change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * requires the UART baud rate to be updated. This presumably corrupts any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * serial word currently being transmitted or received. In order to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * corrupting the output data stream, we drain the transmit queue before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) * allowing the clock's rate to be changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) static int sifive_serial_clk_notifier(struct notifier_block *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) unsigned long event, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) struct clk_notifier_data *cnd = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) struct sifive_serial_port *ssp = notifier_to_sifive_serial_port(nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (event == PRE_RATE_CHANGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) * The TX watermark is always set to 1 by this driver, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) * means that the TX busy bit will lower when there are 0 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) * left in the TX queue -- in other words, when the TX FIFO is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) * empty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) __ssp_wait_for_xmitr(ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) * On the cycle the TX FIFO goes empty there is still a full
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) * UART frame left to be transmitted in the shift register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) * The UART provides no way for software to directly determine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * when that last frame has been transmitted, so we just sleep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * here instead. As we're not tracking the number of stop bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * they're just worst cased here. The rest of the serial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * framing parameters aren't configurable by software.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) udelay(DIV_ROUND_UP(12 * 1000 * 1000, ssp->baud_rate));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (event == POST_RATE_CHANGE && ssp->clkin_rate != cnd->new_rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) ssp->clkin_rate = cnd->new_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) __ssp_update_div(ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) static void sifive_serial_set_termios(struct uart_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) struct ktermios *termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct ktermios *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct sifive_serial_port *ssp = port_to_sifive_serial_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) u32 v, old_v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) int rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) char nstop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if ((termios->c_cflag & CSIZE) != CS8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) dev_err_once(ssp->port.dev, "only 8-bit words supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (termios->c_iflag & (INPCK | PARMRK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) dev_err_once(ssp->port.dev, "parity checking not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (termios->c_iflag & BRKINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) dev_err_once(ssp->port.dev, "BREAK detection not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) /* Set number of stop bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) nstop = (termios->c_cflag & CSTOPB) ? 2 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) __ssp_set_stop_bits(ssp, nstop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) /* Set line rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) rate = uart_get_baud_rate(port, termios, old, 0, ssp->clkin_rate / 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) __ssp_update_baud_rate(ssp, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) spin_lock_irqsave(&ssp->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) /* Update the per-port timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) uart_update_timeout(port, termios->c_cflag, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) ssp->port.read_status_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) /* Ignore all characters if CREAD is not set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) v = __ssp_readl(ssp, SIFIVE_SERIAL_RXCTRL_OFFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) old_v = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if ((termios->c_cflag & CREAD) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) v &= SIFIVE_SERIAL_RXCTRL_RXEN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) v |= SIFIVE_SERIAL_RXCTRL_RXEN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (v != old_v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) __ssp_writel(v, SIFIVE_SERIAL_RXCTRL_OFFS, ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) spin_unlock_irqrestore(&ssp->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) static void sifive_serial_release_port(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) static int sifive_serial_request_port(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) static void sifive_serial_config_port(struct uart_port *port, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) struct sifive_serial_port *ssp = port_to_sifive_serial_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) ssp->port.type = PORT_SIFIVE_V0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) static int sifive_serial_verify_port(struct uart_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) struct serial_struct *ser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) static const char *sifive_serial_type(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return port->type == PORT_SIFIVE_V0 ? "SiFive UART v0" : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) #ifdef CONFIG_CONSOLE_POLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) static int sifive_serial_poll_get_char(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) struct sifive_serial_port *ssp = port_to_sifive_serial_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) char is_empty, ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) ch = __ssp_receive_char(ssp, &is_empty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (is_empty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return NO_POLL_CHAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) return ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) static void sifive_serial_poll_put_char(struct uart_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) unsigned char c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) struct sifive_serial_port *ssp = port_to_sifive_serial_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) __ssp_wait_for_xmitr(ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) __ssp_transmit_char(ssp, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) #endif /* CONFIG_CONSOLE_POLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) * Early console support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) #ifdef CONFIG_SERIAL_EARLYCON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) static void early_sifive_serial_putc(struct uart_port *port, int c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) while (__ssp_early_readl(port, SIFIVE_SERIAL_TXDATA_OFFS) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) SIFIVE_SERIAL_TXDATA_FULL_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) __ssp_early_writel(c, SIFIVE_SERIAL_TXDATA_OFFS, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) static void early_sifive_serial_write(struct console *con, const char *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) unsigned int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) struct earlycon_device *dev = con->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct uart_port *port = &dev->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) uart_console_write(port, s, n, early_sifive_serial_putc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) static int __init early_sifive_serial_setup(struct earlycon_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) const char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) struct uart_port *port = &dev->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (!port->membase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) dev->con->write = early_sifive_serial_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) OF_EARLYCON_DECLARE(sifive, "sifive,uart0", early_sifive_serial_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) OF_EARLYCON_DECLARE(sifive, "sifive,fu540-c000-uart0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) early_sifive_serial_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) #endif /* CONFIG_SERIAL_EARLYCON */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) * Linux console interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) #ifdef CONFIG_SERIAL_SIFIVE_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) static struct sifive_serial_port *sifive_serial_console_ports[SIFIVE_SERIAL_MAX_PORTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) static void sifive_serial_console_putchar(struct uart_port *port, int ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) struct sifive_serial_port *ssp = port_to_sifive_serial_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) __ssp_wait_for_xmitr(ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) __ssp_transmit_char(ssp, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) static void sifive_serial_console_write(struct console *co, const char *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) struct sifive_serial_port *ssp = sifive_serial_console_ports[co->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) unsigned int ier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) int locked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (!ssp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (ssp->port.sysrq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) locked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) else if (oops_in_progress)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) locked = spin_trylock(&ssp->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) spin_lock(&ssp->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) ier = __ssp_readl(ssp, SIFIVE_SERIAL_IE_OFFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) __ssp_writel(0, SIFIVE_SERIAL_IE_OFFS, ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) uart_console_write(&ssp->port, s, count, sifive_serial_console_putchar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) __ssp_writel(ier, SIFIVE_SERIAL_IE_OFFS, ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (locked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) spin_unlock(&ssp->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) static int __init sifive_serial_console_setup(struct console *co, char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) struct sifive_serial_port *ssp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) int baud = SIFIVE_DEFAULT_BAUD_RATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) int bits = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) int parity = 'n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) int flow = 'n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if (co->index < 0 || co->index >= SIFIVE_SERIAL_MAX_PORTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) ssp = sifive_serial_console_ports[co->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (!ssp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) uart_parse_options(options, &baud, &parity, &bits, &flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) return uart_set_options(&ssp->port, co, baud, parity, bits, flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) static struct uart_driver sifive_serial_uart_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) static struct console sifive_serial_console = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) .name = SIFIVE_TTY_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) .write = sifive_serial_console_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) .device = uart_console_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) .setup = sifive_serial_console_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) .flags = CON_PRINTBUFFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) .index = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) .data = &sifive_serial_uart_driver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) static int __init sifive_console_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) register_console(&sifive_serial_console);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) console_initcall(sifive_console_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) static void __ssp_add_console_port(struct sifive_serial_port *ssp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) sifive_serial_console_ports[ssp->port.line] = ssp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) static void __ssp_remove_console_port(struct sifive_serial_port *ssp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) sifive_serial_console_ports[ssp->port.line] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) #define SIFIVE_SERIAL_CONSOLE (&sifive_serial_console)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) #define SIFIVE_SERIAL_CONSOLE NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) static void __ssp_add_console_port(struct sifive_serial_port *ssp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) static void __ssp_remove_console_port(struct sifive_serial_port *ssp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) static const struct uart_ops sifive_serial_uops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) .tx_empty = sifive_serial_tx_empty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) .set_mctrl = sifive_serial_set_mctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) .get_mctrl = sifive_serial_get_mctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) .stop_tx = sifive_serial_stop_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) .start_tx = sifive_serial_start_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) .stop_rx = sifive_serial_stop_rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) .break_ctl = sifive_serial_break_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) .startup = sifive_serial_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) .shutdown = sifive_serial_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) .set_termios = sifive_serial_set_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) .type = sifive_serial_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) .release_port = sifive_serial_release_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) .request_port = sifive_serial_request_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) .config_port = sifive_serial_config_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) .verify_port = sifive_serial_verify_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) #ifdef CONFIG_CONSOLE_POLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) .poll_get_char = sifive_serial_poll_get_char,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) .poll_put_char = sifive_serial_poll_put_char,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) static struct uart_driver sifive_serial_uart_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) .driver_name = SIFIVE_SERIAL_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) .dev_name = SIFIVE_TTY_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) .nr = SIFIVE_SERIAL_MAX_PORTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) .cons = SIFIVE_SERIAL_CONSOLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) static int sifive_serial_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) struct sifive_serial_port *ssp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) struct resource *mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) int irq, id, r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) if (irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) return -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) base = devm_ioremap_resource(&pdev->dev, mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) if (IS_ERR(base)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) dev_err(&pdev->dev, "could not acquire device memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) return PTR_ERR(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) clk = devm_clk_get(&pdev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) dev_err(&pdev->dev, "unable to find controller clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) return PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) id = of_alias_get_id(pdev->dev.of_node, "serial");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) if (id < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) dev_err(&pdev->dev, "missing aliases entry\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) return id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) #ifdef CONFIG_SERIAL_SIFIVE_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (id > SIFIVE_SERIAL_MAX_PORTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) dev_err(&pdev->dev, "too many UARTs (%d)\n", id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) ssp = devm_kzalloc(&pdev->dev, sizeof(*ssp), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (!ssp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) ssp->port.dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) ssp->port.type = PORT_SIFIVE_V0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) ssp->port.iotype = UPIO_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) ssp->port.irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) ssp->port.fifosize = SIFIVE_TX_FIFO_DEPTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) ssp->port.ops = &sifive_serial_uops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) ssp->port.line = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) ssp->port.mapbase = mem->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) ssp->port.membase = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) ssp->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) ssp->clk = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) ssp->clk_notifier.notifier_call = sifive_serial_clk_notifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) r = clk_notifier_register(ssp->clk, &ssp->clk_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) dev_err(&pdev->dev, "could not register clock notifier: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) goto probe_out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) /* Set up clock divider */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) ssp->clkin_rate = clk_get_rate(ssp->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) ssp->baud_rate = SIFIVE_DEFAULT_BAUD_RATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) ssp->port.uartclk = ssp->baud_rate * 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) __ssp_update_div(ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) platform_set_drvdata(pdev, ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) /* Enable transmits and set the watermark level to 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) __ssp_writel((1 << SIFIVE_SERIAL_TXCTRL_TXCNT_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) SIFIVE_SERIAL_TXCTRL_TXEN_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) SIFIVE_SERIAL_TXCTRL_OFFS, ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) /* Enable receives and set the watermark level to 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) __ssp_writel((0 << SIFIVE_SERIAL_RXCTRL_RXCNT_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) SIFIVE_SERIAL_RXCTRL_RXEN_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) SIFIVE_SERIAL_RXCTRL_OFFS, ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) r = request_irq(ssp->port.irq, sifive_serial_irq, ssp->port.irqflags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) dev_name(&pdev->dev), ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) dev_err(&pdev->dev, "could not attach interrupt: %d\n", r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) goto probe_out2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) __ssp_add_console_port(ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) r = uart_add_one_port(&sifive_serial_uart_driver, &ssp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) if (r != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) dev_err(&pdev->dev, "could not add uart: %d\n", r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) goto probe_out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) probe_out3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) __ssp_remove_console_port(ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) free_irq(ssp->port.irq, ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) probe_out2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) clk_notifier_unregister(ssp->clk, &ssp->clk_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) probe_out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) static int sifive_serial_remove(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) struct sifive_serial_port *ssp = platform_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) __ssp_remove_console_port(ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) uart_remove_one_port(&sifive_serial_uart_driver, &ssp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) free_irq(ssp->port.irq, ssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) clk_notifier_unregister(ssp->clk, &ssp->clk_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) static const struct of_device_id sifive_serial_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) { .compatible = "sifive,fu540-c000-uart0" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) { .compatible = "sifive,uart0" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) MODULE_DEVICE_TABLE(of, sifive_serial_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) static struct platform_driver sifive_serial_platform_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) .probe = sifive_serial_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) .remove = sifive_serial_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) .name = SIFIVE_SERIAL_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) .of_match_table = of_match_ptr(sifive_serial_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) static int __init sifive_serial_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) r = uart_register_driver(&sifive_serial_uart_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) goto init_out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) r = platform_driver_register(&sifive_serial_platform_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) goto init_out2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) init_out2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) uart_unregister_driver(&sifive_serial_uart_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) init_out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) static void __exit sifive_serial_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) platform_driver_unregister(&sifive_serial_platform_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) uart_unregister_driver(&sifive_serial_uart_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) module_init(sifive_serial_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) module_exit(sifive_serial_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) MODULE_DESCRIPTION("SiFive UART serial driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) MODULE_AUTHOR("Paul Walmsley <paul@pwsan.com>");