forked from Minki/linux
88bb4ea14c
s3c64xx and later SoC's include the interrupt mask and pending registers in the uart controller, unlike the s3c24xx SoC's which have these registers in the interrupt controller. When the mask and pending registers are part of the uart controller, a unified interrupt handler can handle the tx/rx interrupt. With this, the static reservation of interrupt numbers for the uart tx/rx/err interrupts in the linux irq space is not required and simplifies adding device tree support. Suggested-by: Grant Likely <grant.likely@secretlab.ca> CC: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org> Acked-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
102 lines
2.6 KiB
C
102 lines
2.6 KiB
C
/*
|
|
* Driver for Samsung SoC onboard UARTs.
|
|
*
|
|
* Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
|
|
* http://armlinux.simtec.co.uk/
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*/
|
|
|
|
struct s3c24xx_uart_info {
|
|
char *name;
|
|
unsigned int type;
|
|
unsigned int fifosize;
|
|
unsigned long rx_fifomask;
|
|
unsigned long rx_fifoshift;
|
|
unsigned long rx_fifofull;
|
|
unsigned long tx_fifomask;
|
|
unsigned long tx_fifoshift;
|
|
unsigned long tx_fifofull;
|
|
|
|
/* uart port features */
|
|
|
|
unsigned int has_divslot:1;
|
|
|
|
/* clock source control */
|
|
|
|
int (*get_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
|
|
int (*set_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
|
|
|
|
/* uart controls */
|
|
int (*reset_port)(struct uart_port *, struct s3c2410_uartcfg *);
|
|
};
|
|
|
|
struct s3c24xx_uart_port {
|
|
unsigned char rx_claimed;
|
|
unsigned char tx_claimed;
|
|
unsigned int pm_level;
|
|
unsigned long baudclk_rate;
|
|
|
|
unsigned int rx_irq;
|
|
unsigned int tx_irq;
|
|
|
|
struct s3c24xx_uart_info *info;
|
|
struct s3c24xx_uart_clksrc *clksrc;
|
|
struct clk *clk;
|
|
struct clk *baudclk;
|
|
struct uart_port port;
|
|
|
|
#ifdef CONFIG_CPU_FREQ
|
|
struct notifier_block freq_transition;
|
|
#endif
|
|
};
|
|
|
|
/* conversion functions */
|
|
|
|
#define s3c24xx_dev_to_port(__dev) (struct uart_port *)dev_get_drvdata(__dev)
|
|
#define s3c24xx_dev_to_cfg(__dev) (struct s3c2410_uartcfg *)((__dev)->platform_data)
|
|
|
|
/* register access controls */
|
|
|
|
#define portaddr(port, reg) ((port)->membase + (reg))
|
|
#define portaddrl(port, reg) ((unsigned long *)((port)->membase + (reg)))
|
|
|
|
#define rd_regb(port, reg) (__raw_readb(portaddr(port, reg)))
|
|
#define rd_regl(port, reg) (__raw_readl(portaddr(port, reg)))
|
|
|
|
#define wr_regb(port, reg, val) __raw_writeb(val, portaddr(port, reg))
|
|
#define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg))
|
|
|
|
extern int s3c24xx_serial_probe(struct platform_device *dev,
|
|
struct s3c24xx_uart_info *uart);
|
|
|
|
extern int __devexit s3c24xx_serial_remove(struct platform_device *dev);
|
|
|
|
extern int s3c24xx_serial_initconsole(struct platform_driver *drv,
|
|
struct s3c24xx_uart_info **uart);
|
|
|
|
extern int s3c24xx_serial_init(struct platform_driver *drv,
|
|
struct s3c24xx_uart_info *info);
|
|
|
|
#ifdef CONFIG_SERIAL_SAMSUNG_DEBUG
|
|
|
|
extern void printascii(const char *);
|
|
|
|
static void dbg(const char *fmt, ...)
|
|
{
|
|
va_list va;
|
|
char buff[256];
|
|
|
|
va_start(va, fmt);
|
|
vsprintf(buff, fmt, va);
|
|
va_end(va);
|
|
|
|
printascii(buff);
|
|
}
|
|
|
|
#else
|
|
#define dbg(x...) do { } while (0)
|
|
#endif
|