2017-11-06 18:11:51 +01:00
// SPDX-License-Identifier: GPL-2.0
2006-12-06 20:35:17 -08:00
/*
* uartlite . c : Serial driver for Xilinx uartlite serial controller
*
2007-10-02 12:16:04 +10:00
* Copyright ( C ) 2006 Peter Korsgaard < jacmet @ sunsite . dk >
* Copyright ( C ) 2007 Secret Lab Technologies Ltd .
2006-12-06 20:35:17 -08:00
*/
# include <linux/platform_device.h>
# include <linux/module.h>
# include <linux/console.h>
# include <linux/serial.h>
# include <linux/serial_core.h>
# include <linux/tty.h>
2011-09-01 16:20:57 +02:00
# include <linux/tty_flip.h>
2006-12-06 20:35:17 -08:00
# include <linux/delay.h>
# include <linux/interrupt.h>
2008-01-09 06:35:05 +11:00
# include <linux/init.h>
2013-02-11 19:04:33 +01:00
# include <linux/io.h>
2008-01-09 06:35:05 +11:00
# include <linux/of.h>
2010-07-29 11:49:01 -06:00
# include <linux/of_address.h>
2007-10-02 12:16:04 +10:00
# include <linux/of_device.h>
# include <linux/of_platform.h>
2018-07-21 17:19:05 +05:30
# include <linux/clk.h>
2008-01-09 06:35:05 +11:00
2007-10-02 12:15:49 +10:00
# define ULITE_NAME "ttyUL"
2006-12-06 20:35:17 -08:00
# define ULITE_MAJOR 204
# define ULITE_MINOR 187
2017-03-15 20:43:24 -06:00
# define ULITE_NR_UARTS CONFIG_SERIAL_UARTLITE_NR_UARTS
2006-12-06 20:35:17 -08:00
2007-10-02 12:15:59 +10:00
/* ---------------------------------------------------------------------
* Register definitions
*
* For register details see datasheet :
2013-02-11 19:04:34 +01:00
* http : //www.xilinx.com/support/documentation/ip_documentation/opb_uartlite.pdf
2007-10-02 12:15:59 +10:00
*/
2006-12-06 20:35:17 -08:00
# define ULITE_RX 0x00
# define ULITE_TX 0x04
# define ULITE_STATUS 0x08
# define ULITE_CONTROL 0x0c
# define ULITE_REGION 16
# define ULITE_STATUS_RXVALID 0x01
# define ULITE_STATUS_RXFULL 0x02
# define ULITE_STATUS_TXEMPTY 0x04
# define ULITE_STATUS_TXFULL 0x08
# define ULITE_STATUS_IE 0x10
# define ULITE_STATUS_OVERRUN 0x20
# define ULITE_STATUS_FRAME 0x40
# define ULITE_STATUS_PARITY 0x80
# define ULITE_CONTROL_RST_TX 0x01
# define ULITE_CONTROL_RST_RX 0x02
# define ULITE_CONTROL_IE 0x10
2018-08-06 14:22:14 +05:30
/* Static pointer to console port */
# ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
static struct uart_port * console_port ;
# endif
2018-07-21 17:19:04 +05:30
struct uartlite_data {
const struct uartlite_reg_ops * reg_ops ;
2018-07-21 17:19:05 +05:30
struct clk * clk ;
2018-07-21 17:19:04 +05:30
} ;
2013-02-11 19:04:34 +01:00
struct uartlite_reg_ops {
u32 ( * in ) ( void __iomem * addr ) ;
void ( * out ) ( u32 val , void __iomem * addr ) ;
} ;
static u32 uartlite_inbe32 ( void __iomem * addr )
{
return ioread32be ( addr ) ;
}
static void uartlite_outbe32 ( u32 val , void __iomem * addr )
{
iowrite32be ( val , addr ) ;
}
2016-04-22 18:19:33 +02:00
static const struct uartlite_reg_ops uartlite_be = {
2013-02-11 19:04:34 +01:00
. in = uartlite_inbe32 ,
. out = uartlite_outbe32 ,
} ;
static u32 uartlite_inle32 ( void __iomem * addr )
{
return ioread32 ( addr ) ;
}
static void uartlite_outle32 ( u32 val , void __iomem * addr )
{
iowrite32 ( val , addr ) ;
}
2016-04-22 18:19:33 +02:00
static const struct uartlite_reg_ops uartlite_le = {
2013-02-11 19:04:34 +01:00
. in = uartlite_inle32 ,
. out = uartlite_outle32 ,
} ;
static inline u32 uart_in32 ( u32 offset , struct uart_port * port )
{
2018-07-21 17:19:04 +05:30
struct uartlite_data * pdata = port - > private_data ;
2013-02-11 19:04:34 +01:00
2018-07-21 17:19:04 +05:30
return pdata - > reg_ops - > in ( port - > membase + offset ) ;
2013-02-11 19:04:34 +01:00
}
static inline void uart_out32 ( u32 val , u32 offset , struct uart_port * port )
{
2018-07-21 17:19:04 +05:30
struct uartlite_data * pdata = port - > private_data ;
2013-02-11 19:04:34 +01:00
2018-07-21 17:19:04 +05:30
pdata - > reg_ops - > out ( val , port - > membase + offset ) ;
2013-02-11 19:04:34 +01:00
}
2006-12-06 20:35:17 -08:00
2007-10-02 12:15:44 +10:00
static struct uart_port ulite_ports [ ULITE_NR_UARTS ] ;
2006-12-06 20:35:17 -08:00
2007-10-02 12:15:59 +10:00
/* ---------------------------------------------------------------------
* Core UART driver operations
*/
2006-12-06 20:35:17 -08:00
static int ulite_receive ( struct uart_port * port , int stat )
{
2013-01-03 15:53:03 +01:00
struct tty_port * tport = & port - > state - > port ;
2006-12-06 20:35:17 -08:00
unsigned char ch = 0 ;
char flag = TTY_NORMAL ;
if ( ( stat & ( ULITE_STATUS_RXVALID | ULITE_STATUS_OVERRUN
| ULITE_STATUS_FRAME ) ) = = 0 )
return 0 ;
/* stats */
if ( stat & ULITE_STATUS_RXVALID ) {
port - > icount . rx + + ;
2013-02-11 19:04:34 +01:00
ch = uart_in32 ( ULITE_RX , port ) ;
2006-12-06 20:35:17 -08:00
if ( stat & ULITE_STATUS_PARITY )
port - > icount . parity + + ;
}
if ( stat & ULITE_STATUS_OVERRUN )
port - > icount . overrun + + ;
if ( stat & ULITE_STATUS_FRAME )
port - > icount . frame + + ;
/* drop byte with parity error if IGNPAR specificed */
if ( stat & port - > ignore_status_mask & ULITE_STATUS_PARITY )
stat & = ~ ULITE_STATUS_RXVALID ;
stat & = port - > read_status_mask ;
if ( stat & ULITE_STATUS_PARITY )
flag = TTY_PARITY ;
stat & = ~ port - > ignore_status_mask ;
if ( stat & ULITE_STATUS_RXVALID )
2013-01-03 15:53:03 +01:00
tty_insert_flip_char ( tport , ch , flag ) ;
2006-12-06 20:35:17 -08:00
if ( stat & ULITE_STATUS_FRAME )
2013-01-03 15:53:03 +01:00
tty_insert_flip_char ( tport , 0 , TTY_FRAME ) ;
2006-12-06 20:35:17 -08:00
if ( stat & ULITE_STATUS_OVERRUN )
2013-01-03 15:53:03 +01:00
tty_insert_flip_char ( tport , 0 , TTY_OVERRUN ) ;
2006-12-06 20:35:17 -08:00
return 1 ;
}
static int ulite_transmit ( struct uart_port * port , int stat )
{
2009-09-19 13:13:28 -07:00
struct circ_buf * xmit = & port - > state - > xmit ;
2006-12-06 20:35:17 -08:00
if ( stat & ULITE_STATUS_TXFULL )
return 0 ;
if ( port - > x_char ) {
2013-02-11 19:04:34 +01:00
uart_out32 ( port - > x_char , ULITE_TX , port ) ;
2006-12-06 20:35:17 -08:00
port - > x_char = 0 ;
port - > icount . tx + + ;
return 1 ;
}
if ( uart_circ_empty ( xmit ) | | uart_tx_stopped ( port ) )
return 0 ;
2013-02-11 19:04:34 +01:00
uart_out32 ( xmit - > buf [ xmit - > tail ] , ULITE_TX , port ) ;
2006-12-06 20:35:17 -08:00
xmit - > tail = ( xmit - > tail + 1 ) & ( UART_XMIT_SIZE - 1 ) ;
port - > icount . tx + + ;
/* wake up */
if ( uart_circ_chars_pending ( xmit ) < WAKEUP_CHARS )
uart_write_wakeup ( port ) ;
return 1 ;
}
static irqreturn_t ulite_isr ( int irq , void * dev_id )
{
2008-02-06 01:36:20 -08:00
struct uart_port * port = dev_id ;
2016-02-16 18:59:03 +01:00
int stat , busy , n = 0 ;
2016-01-08 15:33:50 -05:00
unsigned long flags ;
2006-12-06 20:35:17 -08:00
do {
2016-02-16 18:59:03 +01:00
spin_lock_irqsave ( & port - > lock , flags ) ;
stat = uart_in32 ( ULITE_STATUS , port ) ;
2006-12-06 20:35:17 -08:00
busy = ulite_receive ( port , stat ) ;
busy | = ulite_transmit ( port , stat ) ;
2016-02-16 18:59:03 +01:00
spin_unlock_irqrestore ( & port - > lock , flags ) ;
2009-09-09 16:54:04 +02:00
n + + ;
2006-12-06 20:35:17 -08:00
} while ( busy ) ;
2009-09-09 16:54:04 +02:00
/* work done? */
if ( n > 1 ) {
2013-01-03 15:53:06 +01:00
tty_flip_buffer_push ( & port - > state - > port ) ;
2009-09-09 16:54:04 +02:00
return IRQ_HANDLED ;
} else {
return IRQ_NONE ;
}
2006-12-06 20:35:17 -08:00
}
static unsigned int ulite_tx_empty ( struct uart_port * port )
{
unsigned long flags ;
unsigned int ret ;
spin_lock_irqsave ( & port - > lock , flags ) ;
2013-02-11 19:04:34 +01:00
ret = uart_in32 ( ULITE_STATUS , port ) ;
2006-12-06 20:35:17 -08:00
spin_unlock_irqrestore ( & port - > lock , flags ) ;
return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0 ;
}
static unsigned int ulite_get_mctrl ( struct uart_port * port )
{
return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR ;
}
static void ulite_set_mctrl ( struct uart_port * port , unsigned int mctrl )
{
/* N/A */
}
static void ulite_stop_tx ( struct uart_port * port )
{
/* N/A */
}
static void ulite_start_tx ( struct uart_port * port )
{
2013-02-11 19:04:34 +01:00
ulite_transmit ( port , uart_in32 ( ULITE_STATUS , port ) ) ;
2006-12-06 20:35:17 -08:00
}
static void ulite_stop_rx ( struct uart_port * port )
{
/* don't forward any more data (like !CREAD) */
port - > ignore_status_mask = ULITE_STATUS_RXVALID | ULITE_STATUS_PARITY
| ULITE_STATUS_FRAME | ULITE_STATUS_OVERRUN ;
}
static void ulite_break_ctl ( struct uart_port * port , int ctl )
{
/* N/A */
}
static int ulite_startup ( struct uart_port * port )
{
2018-07-21 17:19:05 +05:30
struct uartlite_data * pdata = port - > private_data ;
2006-12-06 20:35:17 -08:00
int ret ;
2018-07-21 17:19:05 +05:30
ret = clk_enable ( pdata - > clk ) ;
if ( ret ) {
dev_err ( port - > dev , " Failed to enable clock \n " ) ;
return ret ;
}
2016-02-16 18:59:04 +01:00
ret = request_irq ( port - > irq , ulite_isr , IRQF_SHARED | IRQF_TRIGGER_RISING ,
" uartlite " , port ) ;
2006-12-06 20:35:17 -08:00
if ( ret )
return ret ;
2013-02-11 19:04:34 +01:00
uart_out32 ( ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX ,
ULITE_CONTROL , port ) ;
uart_out32 ( ULITE_CONTROL_IE , ULITE_CONTROL , port ) ;
2006-12-06 20:35:17 -08:00
return 0 ;
}
static void ulite_shutdown ( struct uart_port * port )
{
2018-07-21 17:19:05 +05:30
struct uartlite_data * pdata = port - > private_data ;
2013-02-11 19:04:34 +01:00
uart_out32 ( 0 , ULITE_CONTROL , port ) ;
uart_in32 ( ULITE_CONTROL , port ) ; /* dummy */
2006-12-06 20:35:17 -08:00
free_irq ( port - > irq , port ) ;
2018-07-21 17:19:05 +05:30
clk_disable ( pdata - > clk ) ;
2006-12-06 20:35:17 -08:00
}
2006-12-08 02:38:45 -08:00
static void ulite_set_termios ( struct uart_port * port , struct ktermios * termios ,
struct ktermios * old )
2006-12-06 20:35:17 -08:00
{
unsigned long flags ;
unsigned int baud ;
spin_lock_irqsave ( & port - > lock , flags ) ;
port - > read_status_mask = ULITE_STATUS_RXVALID | ULITE_STATUS_OVERRUN
| ULITE_STATUS_TXFULL ;
if ( termios - > c_iflag & INPCK )
port - > read_status_mask | =
ULITE_STATUS_PARITY | ULITE_STATUS_FRAME ;
port - > ignore_status_mask = 0 ;
if ( termios - > c_iflag & IGNPAR )
port - > ignore_status_mask | = ULITE_STATUS_PARITY
| ULITE_STATUS_FRAME | ULITE_STATUS_OVERRUN ;
/* ignore all characters if CREAD is not set */
if ( ( termios - > c_cflag & CREAD ) = = 0 )
port - > ignore_status_mask | =
ULITE_STATUS_RXVALID | ULITE_STATUS_PARITY
| ULITE_STATUS_FRAME | ULITE_STATUS_OVERRUN ;
/* update timeout */
baud = uart_get_baud_rate ( port , termios , old , 0 , 460800 ) ;
uart_update_timeout ( port , termios - > c_cflag , baud ) ;
spin_unlock_irqrestore ( & port - > lock , flags ) ;
}
static const char * ulite_type ( struct uart_port * port )
{
return port - > type = = PORT_UARTLITE ? " uartlite " : NULL ;
}
static void ulite_release_port ( struct uart_port * port )
{
release_mem_region ( port - > mapbase , ULITE_REGION ) ;
iounmap ( port - > membase ) ;
2007-02-09 16:38:25 +00:00
port - > membase = NULL ;
2006-12-06 20:35:17 -08:00
}
static int ulite_request_port ( struct uart_port * port )
{
2018-07-21 17:19:04 +05:30
struct uartlite_data * pdata = port - > private_data ;
2013-02-11 19:04:34 +01:00
int ret ;
2008-11-14 09:59:48 -07:00
pr_debug ( " ulite console: port=%p; port->mapbase=%llx \n " ,
port , ( unsigned long long ) port - > mapbase ) ;
2008-01-09 06:35:05 +11:00
2006-12-06 20:35:17 -08:00
if ( ! request_mem_region ( port - > mapbase , ULITE_REGION , " uartlite " ) ) {
dev_err ( port - > dev , " Memory region busy \n " ) ;
return - EBUSY ;
}
port - > membase = ioremap ( port - > mapbase , ULITE_REGION ) ;
if ( ! port - > membase ) {
dev_err ( port - > dev , " Unable to map registers \n " ) ;
release_mem_region ( port - > mapbase , ULITE_REGION ) ;
return - EBUSY ;
}
2018-07-21 17:19:04 +05:30
pdata - > reg_ops = & uartlite_be ;
2013-02-11 19:04:34 +01:00
ret = uart_in32 ( ULITE_CONTROL , port ) ;
uart_out32 ( ULITE_CONTROL_RST_TX , ULITE_CONTROL , port ) ;
ret = uart_in32 ( ULITE_STATUS , port ) ;
/* Endianess detection */
if ( ( ret & ULITE_STATUS_TXEMPTY ) ! = ULITE_STATUS_TXEMPTY )
2018-07-21 17:19:04 +05:30
pdata - > reg_ops = & uartlite_le ;
2013-02-11 19:04:34 +01:00
2006-12-06 20:35:17 -08:00
return 0 ;
}
static void ulite_config_port ( struct uart_port * port , int flags )
{
2006-12-22 16:38:40 +01:00
if ( ! ulite_request_port ( port ) )
port - > type = PORT_UARTLITE ;
2006-12-06 20:35:17 -08:00
}
static int ulite_verify_port ( struct uart_port * port , struct serial_struct * ser )
{
/* we don't want the core code to modify any port params */
return - EINVAL ;
}
2018-07-21 17:19:05 +05:30
static void ulite_pm ( struct uart_port * port , unsigned int state ,
unsigned int oldstate )
{
2019-11-14 06:25:17 +08:00
struct uartlite_data * pdata = port - > private_data ;
if ( ! state )
clk_enable ( pdata - > clk ) ;
else
clk_disable ( pdata - > clk ) ;
2018-07-21 17:19:05 +05:30
}
2010-08-17 10:42:05 +02:00
# ifdef CONFIG_CONSOLE_POLL
static int ulite_get_poll_char ( struct uart_port * port )
{
2013-02-11 19:04:34 +01:00
if ( ! ( uart_in32 ( ULITE_STATUS , port ) & ULITE_STATUS_RXVALID ) )
2010-08-17 10:42:05 +02:00
return NO_POLL_CHAR ;
2013-02-11 19:04:34 +01:00
return uart_in32 ( ULITE_RX , port ) ;
2010-08-17 10:42:05 +02:00
}
static void ulite_put_poll_char ( struct uart_port * port , unsigned char ch )
{
2013-02-11 19:04:34 +01:00
while ( uart_in32 ( ULITE_STATUS , port ) & ULITE_STATUS_TXFULL )
2010-08-17 10:42:05 +02:00
cpu_relax ( ) ;
/* write char to device */
2013-02-11 19:04:34 +01:00
uart_out32 ( ch , ULITE_TX , port ) ;
2010-08-17 10:42:05 +02:00
}
# endif
2016-09-01 19:51:37 +02:00
static const struct uart_ops ulite_ops = {
2006-12-06 20:35:17 -08:00
. tx_empty = ulite_tx_empty ,
. set_mctrl = ulite_set_mctrl ,
. get_mctrl = ulite_get_mctrl ,
. stop_tx = ulite_stop_tx ,
. start_tx = ulite_start_tx ,
. stop_rx = ulite_stop_rx ,
. break_ctl = ulite_break_ctl ,
. startup = ulite_startup ,
. shutdown = ulite_shutdown ,
. set_termios = ulite_set_termios ,
. type = ulite_type ,
. release_port = ulite_release_port ,
. request_port = ulite_request_port ,
. config_port = ulite_config_port ,
2010-08-17 10:42:05 +02:00
. verify_port = ulite_verify_port ,
2018-07-21 17:19:05 +05:30
. pm = ulite_pm ,
2010-08-17 10:42:05 +02:00
# ifdef CONFIG_CONSOLE_POLL
. poll_get_char = ulite_get_poll_char ,
. poll_put_char = ulite_put_poll_char ,
# endif
2006-12-06 20:35:17 -08:00
} ;
2007-10-02 12:15:59 +10:00
/* ---------------------------------------------------------------------
* Console driver operations
*/
2006-12-06 20:35:17 -08:00
# ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
static void ulite_console_wait_tx ( struct uart_port * port )
{
2007-10-23 14:27:46 +10:00
u8 val ;
2014-05-06 06:46:15 +02:00
unsigned long timeout ;
/*
* Spin waiting for TX fifo to have space available .
* When using the Microblaze Debug Module this can take up to 1 s
*/
timeout = jiffies + msecs_to_jiffies ( 1000 ) ;
while ( 1 ) {
2013-02-11 19:04:34 +01:00
val = uart_in32 ( ULITE_STATUS , port ) ;
2007-10-23 14:27:46 +10:00
if ( ( val & ULITE_STATUS_TXFULL ) = = 0 )
2006-12-06 20:35:17 -08:00
break ;
2014-05-06 06:46:15 +02:00
if ( time_after ( jiffies , timeout ) ) {
dev_warn ( port - > dev ,
" timeout waiting for TX buffer empty \n " ) ;
break ;
}
2007-10-23 14:27:46 +10:00
cpu_relax ( ) ;
2006-12-06 20:35:17 -08:00
}
}
static void ulite_console_putchar ( struct uart_port * port , int ch )
{
ulite_console_wait_tx ( port ) ;
2013-02-11 19:04:34 +01:00
uart_out32 ( ch , ULITE_TX , port ) ;
2006-12-06 20:35:17 -08:00
}
static void ulite_console_write ( struct console * co , const char * s ,
unsigned int count )
{
2018-08-06 14:22:14 +05:30
struct uart_port * port = console_port ;
2006-12-06 20:35:17 -08:00
unsigned long flags ;
unsigned int ier ;
int locked = 1 ;
if ( oops_in_progress ) {
locked = spin_trylock_irqsave ( & port - > lock , flags ) ;
} else
spin_lock_irqsave ( & port - > lock , flags ) ;
/* save and disable interrupt */
2013-02-11 19:04:34 +01:00
ier = uart_in32 ( ULITE_STATUS , port ) & ULITE_STATUS_IE ;
uart_out32 ( 0 , ULITE_CONTROL , port ) ;
2006-12-06 20:35:17 -08:00
uart_console_write ( port , s , count , ulite_console_putchar ) ;
ulite_console_wait_tx ( port ) ;
/* restore interrupt state */
if ( ier )
2013-02-11 19:04:34 +01:00
uart_out32 ( ULITE_CONTROL_IE , ULITE_CONTROL , port ) ;
2006-12-06 20:35:17 -08:00
if ( locked )
spin_unlock_irqrestore ( & port - > lock , flags ) ;
}
2012-11-19 13:21:50 -05:00
static int ulite_console_setup ( struct console * co , char * options )
2006-12-06 20:35:17 -08:00
{
struct uart_port * port ;
int baud = 9600 ;
int bits = 8 ;
int parity = ' n ' ;
int flow = ' n ' ;
2018-08-06 14:22:14 +05:30
port = console_port ;
2006-12-06 20:35:17 -08:00
2008-02-06 10:23:41 -07:00
/* Has the device been initialized yet? */
2007-10-02 12:16:09 +10:00
if ( ! port - > mapbase ) {
pr_debug ( " console on ttyUL%i not present \n " , co - > index ) ;
return - ENODEV ;
}
2006-12-06 20:35:17 -08:00
/* not initialized yet? */
2007-10-02 12:16:04 +10:00
if ( ! port - > membase ) {
2007-10-02 12:16:09 +10:00
if ( ulite_request_port ( port ) )
return - ENODEV ;
2007-10-02 12:16:04 +10:00
}
2006-12-06 20:35:17 -08:00
if ( options )
uart_parse_options ( options , & baud , & parity , & bits , & flow ) ;
return uart_set_options ( port , co , baud , parity , bits , flow ) ;
}
static struct uart_driver ulite_uart_driver ;
static struct console ulite_console = {
2007-10-02 12:15:49 +10:00
. name = ULITE_NAME ,
2006-12-06 20:35:17 -08:00
. write = ulite_console_write ,
. device = uart_console_device ,
. setup = ulite_console_setup ,
. flags = CON_PRINTBUFFER ,
. index = - 1 , /* Specified on the cmdline (e.g. console=ttyUL0 ) */
. data = & ulite_uart_driver ,
} ;
2016-01-08 15:34:05 -05:00
static void early_uartlite_putc ( struct uart_port * port , int c )
{
/*
* Limit how many times we ' ll spin waiting for TX FIFO status .
* This will prevent lockups if the base address is incorrectly
* set , or any other issue on the UARTLITE .
* This limit is pretty arbitrary , unless we are at about 10 baud
* we ' ll never timeout on a working UART .
*/
unsigned retries = 1000000 ;
/* read status bit - 0x8 offset */
while ( - - retries & & ( readl ( port - > membase + 8 ) & ( 1 < < 3 ) ) )
;
/* Only attempt the iowrite if we didn't timeout */
/* write to TX_FIFO - 0x4 offset */
if ( retries )
writel ( c & 0xff , port - > membase + 4 ) ;
}
static void early_uartlite_write ( struct console * console ,
const char * s , unsigned n )
{
struct earlycon_device * device = console - > data ;
uart_console_write ( & device - > port , s , n , early_uartlite_putc ) ;
}
static int __init early_uartlite_setup ( struct earlycon_device * device ,
const char * options )
{
if ( ! device - > port . membase )
return - ENODEV ;
device - > con - > write = early_uartlite_write ;
return 0 ;
}
EARLYCON_DECLARE ( uartlite , early_uartlite_setup ) ;
OF_EARLYCON_DECLARE ( uartlite_b , " xlnx,opb-uartlite-1.00.b " , early_uartlite_setup ) ;
OF_EARLYCON_DECLARE ( uartlite_a , " xlnx,xps-uartlite-1.00.a " , early_uartlite_setup ) ;
2006-12-06 20:35:17 -08:00
# endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */
static struct uart_driver ulite_uart_driver = {
. owner = THIS_MODULE ,
. driver_name = " uartlite " ,
2007-10-02 12:15:49 +10:00
. dev_name = ULITE_NAME ,
2006-12-06 20:35:17 -08:00
. major = ULITE_MAJOR ,
. minor = ULITE_MINOR ,
. nr = ULITE_NR_UARTS ,
# ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
. cons = & ulite_console ,
# endif
} ;
2007-10-02 12:15:59 +10:00
/* ---------------------------------------------------------------------
* Port assignment functions ( mapping devices to uart_port structures )
*/
/** ulite_assign: register a uartlite device with the driver
*
* @ dev : pointer to device structure
* @ id : requested id number . Pass - 1 for automatic port assignment
* @ base : base address of uartlite registers
* @ irq : irq number for uartlite
2018-07-21 17:19:04 +05:30
* @ pdata : private data for uartlite
2007-10-02 12:15:59 +10:00
*
* Returns : 0 on success , < 0 otherwise
*/
2018-07-21 17:19:04 +05:30
static int ulite_assign ( struct device * dev , int id , u32 base , int irq ,
struct uartlite_data * pdata )
2006-12-06 20:35:17 -08:00
{
struct uart_port * port ;
2007-10-02 12:15:54 +10:00
int rc ;
2006-12-06 20:35:17 -08:00
2007-10-02 12:15:54 +10:00
/* if id = -1; then scan for a free id and use that */
if ( id < 0 ) {
for ( id = 0 ; id < ULITE_NR_UARTS ; id + + )
if ( ulite_ports [ id ] . mapbase = = 0 )
break ;
}
if ( id < 0 | | id > = ULITE_NR_UARTS ) {
dev_err ( dev , " %s%i too large \n " , ULITE_NAME , id ) ;
2006-12-06 20:35:17 -08:00
return - EINVAL ;
2007-10-02 12:15:54 +10:00
}
2006-12-06 20:35:17 -08:00
2007-10-02 12:16:09 +10:00
if ( ( ulite_ports [ id ] . mapbase ) & & ( ulite_ports [ id ] . mapbase ! = base ) ) {
2007-10-02 12:15:54 +10:00
dev_err ( dev , " cannot assign to %s%i; it is already in use \n " ,
ULITE_NAME , id ) ;
2006-12-06 20:35:17 -08:00
return - EBUSY ;
2007-10-02 12:15:54 +10:00
}
2006-12-06 20:35:17 -08:00
2007-10-02 12:15:54 +10:00
port = & ulite_ports [ id ] ;
2006-12-06 20:35:17 -08:00
2007-10-02 12:15:54 +10:00
spin_lock_init ( & port - > lock ) ;
port - > fifosize = 16 ;
port - > regshift = 2 ;
port - > iotype = UPIO_MEM ;
port - > iobase = 1 ; /* mark port in use */
port - > mapbase = base ;
port - > membase = NULL ;
port - > ops = & ulite_ops ;
port - > irq = irq ;
port - > flags = UPF_BOOT_AUTOCONF ;
port - > dev = dev ;
port - > type = PORT_UNKNOWN ;
port - > line = id ;
2018-07-21 17:19:04 +05:30
port - > private_data = pdata ;
2007-10-02 12:15:54 +10:00
dev_set_drvdata ( dev , port ) ;
2018-08-06 14:22:14 +05:30
# ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
/*
* If console hasn ' t been found yet try to assign this port
* because it is required to be assigned for console setup function .
* If register_console ( ) don ' t assign value , then console_port pointer
* is cleanup .
*/
2019-11-14 06:22:56 +08:00
if ( ulite_uart_driver . cons - > index = = - 1 )
2018-08-06 14:22:14 +05:30
console_port = port ;
# endif
2007-10-02 12:15:54 +10:00
/* Register the port */
2019-11-14 06:20:35 +08:00
rc = uart_add_one_port ( & ulite_uart_driver , port ) ;
2007-10-02 12:15:54 +10:00
if ( rc ) {
dev_err ( dev , " uart_add_one_port() failed; err=%i \n " , rc ) ;
port - > mapbase = 0 ;
dev_set_drvdata ( dev , NULL ) ;
return rc ;
}
2006-12-06 20:35:17 -08:00
2018-08-06 14:22:14 +05:30
# ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
/* This is not port which is used for console that's why clean it up */
2019-11-14 06:22:56 +08:00
if ( ulite_uart_driver . cons - > index = = - 1 )
2018-08-06 14:22:14 +05:30
console_port = NULL ;
# endif
2007-10-02 12:15:54 +10:00
return 0 ;
}
2006-12-06 20:35:17 -08:00
2007-10-02 12:15:59 +10:00
/** ulite_release: register a uartlite device with the driver
*
* @ dev : pointer to device structure
*/
2012-11-19 13:26:18 -05:00
static int ulite_release ( struct device * dev )
2007-10-02 12:15:54 +10:00
{
struct uart_port * port = dev_get_drvdata ( dev ) ;
int rc = 0 ;
2006-12-06 20:35:17 -08:00
2007-10-02 12:15:54 +10:00
if ( port ) {
2019-11-14 06:28:15 +08:00
rc = uart_remove_one_port ( & ulite_uart_driver , port ) ;
2007-10-02 12:15:54 +10:00
dev_set_drvdata ( dev , NULL ) ;
port - > mapbase = 0 ;
}
2006-12-06 20:35:17 -08:00
2007-10-02 12:15:54 +10:00
return rc ;
2006-12-06 20:35:17 -08:00
}
2018-07-21 17:19:06 +05:30
/**
* ulite_suspend - Stop the device .
*
* @ dev : handle to the device structure .
* Return : 0 always .
*/
static int __maybe_unused ulite_suspend ( struct device * dev )
{
struct uart_port * port = dev_get_drvdata ( dev ) ;
2019-11-14 06:28:15 +08:00
if ( port )
uart_suspend_port ( & ulite_uart_driver , port ) ;
2018-07-21 17:19:06 +05:30
return 0 ;
}
/**
* ulite_resume - Resume the device .
*
* @ dev : handle to the device structure .
* Return : 0 on success , errno otherwise .
*/
static int __maybe_unused ulite_resume ( struct device * dev )
{
struct uart_port * port = dev_get_drvdata ( dev ) ;
2019-11-14 06:28:15 +08:00
if ( port )
uart_resume_port ( & ulite_uart_driver , port ) ;
2018-07-21 17:19:06 +05:30
return 0 ;
}
2007-10-02 12:15:59 +10:00
/* ---------------------------------------------------------------------
* Platform bus binding
*/
2018-07-21 17:19:06 +05:30
2019-11-14 06:25:17 +08:00
static SIMPLE_DEV_PM_OPS ( ulite_pm_ops , ulite_suspend , ulite_resume ) ;
2018-07-21 17:19:06 +05:30
2011-02-22 20:16:13 -07:00
# if defined(CONFIG_OF)
/* Match table for of_platform binding */
2015-03-16 20:17:11 +01:00
static const struct of_device_id ulite_of_match [ ] = {
2011-02-22 20:16:13 -07:00
{ . compatible = " xlnx,opb-uartlite-1.00.b " , } ,
{ . compatible = " xlnx,xps-uartlite-1.00.a " , } ,
{ }
} ;
MODULE_DEVICE_TABLE ( of , ulite_of_match ) ;
# endif /* CONFIG_OF */
2012-11-19 13:21:50 -05:00
static int ulite_probe ( struct platform_device * pdev )
2006-12-06 20:35:17 -08:00
{
2015-04-13 16:34:21 +02:00
struct resource * res ;
2018-07-21 17:19:04 +05:30
struct uartlite_data * pdata ;
2018-07-21 17:19:05 +05:30
int irq , ret ;
2011-02-22 20:16:13 -07:00
int id = pdev - > id ;
# ifdef CONFIG_OF
const __be32 * prop ;
prop = of_get_property ( pdev - > dev . of_node , " port-number " , NULL ) ;
if ( prop )
id = be32_to_cpup ( prop ) ;
# endif
2018-07-21 17:19:04 +05:30
pdata = devm_kzalloc ( & pdev - > dev , sizeof ( struct uartlite_data ) ,
GFP_KERNEL ) ;
if ( ! pdata )
return - ENOMEM ;
2006-12-06 20:35:17 -08:00
2007-10-02 12:15:54 +10:00
res = platform_get_resource ( pdev , IORESOURCE_MEM , 0 ) ;
if ( ! res )
return - ENODEV ;
2006-12-06 20:35:17 -08:00
2015-04-13 16:34:21 +02:00
irq = platform_get_irq ( pdev , 0 ) ;
if ( irq < = 0 )
return - ENXIO ;
2006-12-06 20:35:17 -08:00
2018-07-21 17:19:05 +05:30
pdata - > clk = devm_clk_get ( & pdev - > dev , " s_axi_aclk " ) ;
if ( IS_ERR ( pdata - > clk ) ) {
if ( PTR_ERR ( pdata - > clk ) ! = - ENOENT )
return PTR_ERR ( pdata - > clk ) ;
/*
* Clock framework support is optional , continue on
* anyways if we don ' t find a matching clock .
*/
pdata - > clk = NULL ;
}
2018-08-06 14:22:11 +05:30
ret = clk_prepare_enable ( pdata - > clk ) ;
2018-07-21 17:19:05 +05:30
if ( ret ) {
dev_err ( & pdev - > dev , " Failed to prepare clock \n " ) ;
return ret ;
}
2019-11-14 06:29:08 +08:00
if ( ! ulite_uart_driver . state ) {
dev_dbg ( & pdev - > dev , " uartlite: calling uart_register_driver() \n " ) ;
ret = uart_register_driver ( & ulite_uart_driver ) ;
if ( ret < 0 ) {
dev_err ( & pdev - > dev , " Failed to register driver \n " ) ;
return ret ;
}
}
2018-08-06 14:22:11 +05:30
ret = ulite_assign ( & pdev - > dev , id , res - > start , irq , pdata ) ;
2019-11-14 06:25:17 +08:00
clk_disable ( pdata - > clk ) ;
2018-08-06 14:22:11 +05:30
return ret ;
2007-10-02 12:15:54 +10:00
}
2006-12-06 20:35:17 -08:00
2012-11-19 13:26:18 -05:00
static int ulite_remove ( struct platform_device * pdev )
2007-10-02 12:15:54 +10:00
{
2018-07-21 17:19:05 +05:30
struct uart_port * port = dev_get_drvdata ( & pdev - > dev ) ;
struct uartlite_data * pdata = port - > private_data ;
2019-11-01 16:54:33 +08:00
clk_disable_unprepare ( pdata - > clk ) ;
2019-11-14 06:25:17 +08:00
return ulite_release ( & pdev - > dev ) ;
2006-12-06 20:35:17 -08:00
}
2008-04-15 14:34:35 -07:00
/* work with hotplug and coldplug */
MODULE_ALIAS ( " platform:uartlite " ) ;
2006-12-06 20:35:17 -08:00
static struct platform_driver ulite_platform_driver = {
2011-02-22 20:16:13 -07:00
. probe = ulite_probe ,
2012-11-19 13:21:34 -05:00
. remove = ulite_remove ,
2007-10-02 12:16:04 +10:00
. driver = {
2011-02-22 20:16:13 -07:00
. name = " uartlite " ,
2011-08-03 10:11:43 +01:00
. of_match_table = of_match_ptr ( ulite_of_match ) ,
2018-07-21 17:19:06 +05:30
. pm = & ulite_pm_ops ,
2007-10-02 12:16:04 +10:00
} ,
} ;
2007-10-02 12:15:59 +10:00
/* ---------------------------------------------------------------------
* Module setup / teardown
*/
2013-02-11 19:04:33 +01:00
static int __init ulite_init ( void )
2006-12-06 20:35:17 -08:00
{
2007-10-02 12:16:04 +10:00
pr_debug ( " uartlite: calling platform_driver_register() \n " ) ;
2018-08-06 14:22:12 +05:30
return platform_driver_register ( & ulite_platform_driver ) ;
2006-12-06 20:35:17 -08:00
}
2013-02-11 19:04:33 +01:00
static void __exit ulite_exit ( void )
2006-12-06 20:35:17 -08:00
{
platform_driver_unregister ( & ulite_platform_driver ) ;
2019-09-16 16:12:23 -07:00
if ( ulite_uart_driver . state )
uart_unregister_driver ( & ulite_uart_driver ) ;
2006-12-06 20:35:17 -08:00
}
module_init ( ulite_init ) ;
module_exit ( ulite_exit ) ;
MODULE_AUTHOR ( " Peter Korsgaard <jacmet@sunsite.dk> " ) ;
MODULE_DESCRIPTION ( " Xilinx uartlite serial driver " ) ;
MODULE_LICENSE ( " GPL " ) ;