^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) * Driver core for Samsung SoC onboard UARTs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * http://armlinux.simtec.co.uk/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) /* Note on 2410 error handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * The s3c2410 manual has a love/hate affair with the contents of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * UERSTAT register in the UART blocks, and keeps marking some of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * error bits as reserved. Having checked with the s3c2410x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * it copes with BREAKs properly, so I am happy to ignore the RESERVED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * feature from the latter versions of the manual.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * If it becomes aparrent that latter versions of the 2410 remove these
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * bits, then action will have to be taken to differentiate the versions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * and change the policy on BREAK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * BJD, 04-Nov-2004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/dmaengine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/sysrq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/serial_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/serial_s3c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/cpufreq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* UART name and device definitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define S3C24XX_SERIAL_NAME "ttySAC"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define S3C24XX_SERIAL_MAJOR 204
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define S3C24XX_SERIAL_MINOR 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define S3C24XX_TX_PIO 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define S3C24XX_TX_DMA 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define S3C24XX_RX_PIO 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define S3C24XX_RX_DMA 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* flag to ignore all characters coming in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define RXSTAT_DUMMY_READ (0x10000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct s3c24xx_uart_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) unsigned int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) unsigned int fifosize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) unsigned long rx_fifomask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) unsigned long rx_fifoshift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) unsigned long rx_fifofull;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) unsigned long tx_fifomask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) unsigned long tx_fifoshift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) unsigned long tx_fifofull;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned int def_clk_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) unsigned long num_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) unsigned long clksel_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) unsigned long clksel_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* uart port features */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) unsigned int has_divslot:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct s3c24xx_serial_drv_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct s3c24xx_uart_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct s3c2410_uartcfg *def_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) unsigned int fifosize[CONFIG_SERIAL_SAMSUNG_UARTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct s3c24xx_uart_dma {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) unsigned int rx_chan_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) unsigned int tx_chan_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct dma_slave_config rx_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct dma_slave_config tx_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct dma_chan *rx_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct dma_chan *tx_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) dma_addr_t rx_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) dma_addr_t tx_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) dma_cookie_t rx_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) dma_cookie_t tx_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) char *rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) dma_addr_t tx_transfer_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) size_t rx_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) size_t tx_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct dma_async_tx_descriptor *tx_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct dma_async_tx_descriptor *rx_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int tx_bytes_requested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int rx_bytes_requested;
^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) struct s3c24xx_uart_port {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) unsigned char rx_claimed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) unsigned char tx_claimed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) unsigned char rx_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) unsigned char tx_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) unsigned int pm_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) unsigned long baudclk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) unsigned int min_dma_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) unsigned int rx_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned int tx_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) unsigned int tx_in_progress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) unsigned int tx_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) unsigned int rx_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct s3c24xx_uart_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct clk *baudclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct uart_port port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct s3c24xx_serial_drv_data *drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* reference to platform data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct s3c2410_uartcfg *cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct s3c24xx_uart_dma *dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #ifdef CONFIG_ARM_S3C24XX_CPUFREQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct notifier_block freq_transition;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #endif
^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) /* conversion functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define s3c24xx_dev_to_port(__dev) dev_get_drvdata(__dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* register access controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define portaddr(port, reg) ((port)->membase + (reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define portaddrl(port, reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ((unsigned long *)(unsigned long)((port)->membase + (reg)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static u32 rd_reg(struct uart_port *port, u32 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) switch (port->iotype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) case UPIO_MEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return readb_relaxed(portaddr(port, reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) case UPIO_MEM32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return readl_relaxed(portaddr(port, reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define rd_regl(port, reg) (readl_relaxed(portaddr(port, reg)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static void wr_reg(struct uart_port *port, u32 reg, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) switch (port->iotype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) case UPIO_MEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) writeb_relaxed(val, portaddr(port, reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) case UPIO_MEM32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) writel_relaxed(val, portaddr(port, reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define wr_regl(port, reg, val) writel_relaxed(val, portaddr(port, reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /* Byte-order aware bit setting/clearing functions. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static inline void s3c24xx_set_bit(struct uart_port *port, int idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) val = rd_regl(port, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) val |= (1 << idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) wr_regl(port, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static inline void s3c24xx_clear_bit(struct uart_port *port, int idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) val = rd_regl(port, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) val &= ~(1 << idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) wr_regl(port, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static inline struct s3c24xx_uart_port *to_ourport(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return container_of(port, struct s3c24xx_uart_port, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /* translate a port to the device name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static inline const char *s3c24xx_serial_portname(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return to_platform_device(port->dev)->name;
^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) static int s3c24xx_serial_txempty_nofifo(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * s3c64xx and later SoC's include the interrupt mask and status registers in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * the controller itself, unlike the s3c24xx SoC's which have these registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * in the interrupt controller. Check if the port type is s3c64xx or higher.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static int s3c24xx_serial_has_interrupt_mask(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return to_ourport(port)->info->type == PORT_S3C6400;
^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) static void s3c24xx_serial_rx_enable(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct s3c24xx_uart_port *ourport = to_ourport(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) unsigned int ucon, ufcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) int count = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) while (--count && !s3c24xx_serial_txempty_nofifo(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ufcon = rd_regl(port, S3C2410_UFCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) ufcon |= S3C2410_UFCON_RESETRX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) wr_regl(port, S3C2410_UFCON, ufcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ucon = rd_regl(port, S3C2410_UCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) ucon |= S3C2410_UCON_RXIRQMODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) wr_regl(port, S3C2410_UCON, ucon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) ourport->rx_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static void s3c24xx_serial_rx_disable(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct s3c24xx_uart_port *ourport = to_ourport(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) unsigned int ucon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) ucon = rd_regl(port, S3C2410_UCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ucon &= ~S3C2410_UCON_RXIRQMODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) wr_regl(port, S3C2410_UCON, ucon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) ourport->rx_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static void s3c24xx_serial_stop_tx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct s3c24xx_uart_port *ourport = to_ourport(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) struct s3c24xx_uart_dma *dma = ourport->dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) struct circ_buf *xmit = &port->state->xmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct dma_tx_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (!ourport->tx_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (s3c24xx_serial_has_interrupt_mask(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) disable_irq_nosync(ourport->tx_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (dma && dma->tx_chan && ourport->tx_in_progress == S3C24XX_TX_DMA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) dmaengine_pause(dma->tx_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) dmaengine_tx_status(dma->tx_chan, dma->tx_cookie, &state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) dmaengine_terminate_all(dma->tx_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) dma_sync_single_for_cpu(ourport->port.dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) dma->tx_transfer_addr, dma->tx_size, DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) async_tx_ack(dma->tx_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) count = dma->tx_bytes_requested - state.residue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) port->icount.tx += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ourport->tx_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) ourport->tx_in_progress = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (port->flags & UPF_CONS_FLOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) s3c24xx_serial_rx_enable(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) ourport->tx_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static void s3c24xx_serial_start_next_tx(struct s3c24xx_uart_port *ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static void s3c24xx_serial_tx_dma_complete(void *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct s3c24xx_uart_port *ourport = args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) struct uart_port *port = &ourport->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct circ_buf *xmit = &port->state->xmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct s3c24xx_uart_dma *dma = ourport->dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct dma_tx_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) dmaengine_tx_status(dma->tx_chan, dma->tx_cookie, &state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) count = dma->tx_bytes_requested - state.residue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) async_tx_ack(dma->tx_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) dma_sync_single_for_cpu(ourport->port.dev, dma->tx_transfer_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) dma->tx_size, DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) port->icount.tx += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) ourport->tx_in_progress = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) uart_write_wakeup(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) s3c24xx_serial_start_next_tx(ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static void enable_tx_dma(struct s3c24xx_uart_port *ourport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) struct uart_port *port = &ourport->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) u32 ucon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* Mask Tx interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (s3c24xx_serial_has_interrupt_mask(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) disable_irq_nosync(ourport->tx_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /* Enable tx dma mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) ucon = rd_regl(port, S3C2410_UCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) ucon &= ~(S3C64XX_UCON_TXBURST_MASK | S3C64XX_UCON_TXMODE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) ucon |= (dma_get_cache_alignment() >= 16) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) S3C64XX_UCON_TXBURST_16 : S3C64XX_UCON_TXBURST_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) ucon |= S3C64XX_UCON_TXMODE_DMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) wr_regl(port, S3C2410_UCON, ucon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) ourport->tx_mode = S3C24XX_TX_DMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) static void enable_tx_pio(struct s3c24xx_uart_port *ourport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) struct uart_port *port = &ourport->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) u32 ucon, ufcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /* Set ufcon txtrig */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) ourport->tx_in_progress = S3C24XX_TX_PIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) ufcon = rd_regl(port, S3C2410_UFCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) wr_regl(port, S3C2410_UFCON, ufcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /* Enable tx pio mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) ucon = rd_regl(port, S3C2410_UCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) ucon &= ~(S3C64XX_UCON_TXMODE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) ucon |= S3C64XX_UCON_TXMODE_CPU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) wr_regl(port, S3C2410_UCON, ucon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /* Unmask Tx interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (s3c24xx_serial_has_interrupt_mask(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) s3c24xx_clear_bit(port, S3C64XX_UINTM_TXD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) S3C64XX_UINTM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) enable_irq(ourport->tx_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) ourport->tx_mode = S3C24XX_TX_PIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static void s3c24xx_serial_start_tx_pio(struct s3c24xx_uart_port *ourport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (ourport->tx_mode != S3C24XX_TX_PIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) enable_tx_pio(ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static int s3c24xx_serial_start_tx_dma(struct s3c24xx_uart_port *ourport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct uart_port *port = &ourport->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct circ_buf *xmit = &port->state->xmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) struct s3c24xx_uart_dma *dma = ourport->dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (ourport->tx_mode != S3C24XX_TX_DMA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) enable_tx_dma(ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) dma->tx_size = count & ~(dma_get_cache_alignment() - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) dma->tx_transfer_addr = dma->tx_addr + xmit->tail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) dma_sync_single_for_device(ourport->port.dev, dma->tx_transfer_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) dma->tx_size, DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) dma->tx_desc = dmaengine_prep_slave_single(dma->tx_chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) dma->tx_transfer_addr, dma->tx_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (!dma->tx_desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) dev_err(ourport->port.dev, "Unable to get desc for Tx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) dma->tx_desc->callback = s3c24xx_serial_tx_dma_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) dma->tx_desc->callback_param = ourport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) dma->tx_bytes_requested = dma->tx_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) ourport->tx_in_progress = S3C24XX_TX_DMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) dma->tx_cookie = dmaengine_submit(dma->tx_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) dma_async_issue_pending(dma->tx_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) static void s3c24xx_serial_start_next_tx(struct s3c24xx_uart_port *ourport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct uart_port *port = &ourport->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct circ_buf *xmit = &port->state->xmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) unsigned long count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) /* Get data size up to the end of buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (!count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) s3c24xx_serial_stop_tx(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (!ourport->dma || !ourport->dma->tx_chan ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) count < ourport->min_dma_size ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) xmit->tail & (dma_get_cache_alignment() - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) s3c24xx_serial_start_tx_pio(ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) s3c24xx_serial_start_tx_dma(ourport, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) static void s3c24xx_serial_start_tx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) struct s3c24xx_uart_port *ourport = to_ourport(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct circ_buf *xmit = &port->state->xmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (!ourport->tx_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (port->flags & UPF_CONS_FLOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) s3c24xx_serial_rx_disable(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) ourport->tx_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (!ourport->dma || !ourport->dma->tx_chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) s3c24xx_serial_start_tx_pio(ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (ourport->dma && ourport->dma->tx_chan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (!uart_circ_empty(xmit) && !ourport->tx_in_progress)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) s3c24xx_serial_start_next_tx(ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) static void s3c24xx_uart_copy_rx_to_tty(struct s3c24xx_uart_port *ourport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) struct tty_port *tty, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct s3c24xx_uart_dma *dma = ourport->dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) int copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (!count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) dma_sync_single_for_cpu(ourport->port.dev, dma->rx_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) dma->rx_size, DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ourport->port.icount.rx += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (!tty) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) dev_err(ourport->port.dev, "No tty port\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) copied = tty_insert_flip_string(tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) ((unsigned char *)(ourport->dma->rx_buf)), count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (copied != count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) dev_err(ourport->port.dev, "RxData copy to tty layer failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static void s3c24xx_serial_stop_rx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) struct s3c24xx_uart_port *ourport = to_ourport(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) struct s3c24xx_uart_dma *dma = ourport->dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) struct tty_port *t = &port->state->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) struct dma_tx_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) enum dma_status dma_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) unsigned int received;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (ourport->rx_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) dev_dbg(port->dev, "stopping rx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (s3c24xx_serial_has_interrupt_mask(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) s3c24xx_set_bit(port, S3C64XX_UINTM_RXD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) S3C64XX_UINTM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) disable_irq_nosync(ourport->rx_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) ourport->rx_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (dma && dma->rx_chan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) dmaengine_pause(dma->tx_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) dma_status = dmaengine_tx_status(dma->rx_chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) dma->rx_cookie, &state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (dma_status == DMA_IN_PROGRESS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) dma_status == DMA_PAUSED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) received = dma->rx_bytes_requested - state.residue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) dmaengine_terminate_all(dma->rx_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) s3c24xx_uart_copy_rx_to_tty(ourport, t, received);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static inline struct s3c24xx_uart_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) *s3c24xx_port_to_info(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return to_ourport(port)->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static inline struct s3c2410_uartcfg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) *s3c24xx_port_to_cfg(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) struct s3c24xx_uart_port *ourport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (port->dev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) ourport = container_of(port, struct s3c24xx_uart_port, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) return ourport->cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) unsigned long ufstat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) struct s3c24xx_uart_info *info = ourport->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (ufstat & info->rx_fifofull)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) return ourport->port.fifosize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return (ufstat & info->rx_fifomask) >> info->rx_fifoshift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) static void s3c64xx_start_rx_dma(struct s3c24xx_uart_port *ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) static void s3c24xx_serial_rx_dma_complete(void *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) struct s3c24xx_uart_port *ourport = args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) struct uart_port *port = &ourport->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) struct s3c24xx_uart_dma *dma = ourport->dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) struct tty_port *t = &port->state->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) struct tty_struct *tty = tty_port_tty_get(&ourport->port.state->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) struct dma_tx_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) int received;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) dmaengine_tx_status(dma->rx_chan, dma->rx_cookie, &state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) received = dma->rx_bytes_requested - state.residue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) async_tx_ack(dma->rx_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (received)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) s3c24xx_uart_copy_rx_to_tty(ourport, t, received);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (tty) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) tty_flip_buffer_push(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) s3c64xx_start_rx_dma(ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) static void s3c64xx_start_rx_dma(struct s3c24xx_uart_port *ourport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) struct s3c24xx_uart_dma *dma = ourport->dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) dma_sync_single_for_device(ourport->port.dev, dma->rx_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) dma->rx_size, DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) dma->rx_desc = dmaengine_prep_slave_single(dma->rx_chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) dma->rx_addr, dma->rx_size, DMA_DEV_TO_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) DMA_PREP_INTERRUPT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (!dma->rx_desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) dev_err(ourport->port.dev, "Unable to get desc for Rx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return;
^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) dma->rx_desc->callback = s3c24xx_serial_rx_dma_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) dma->rx_desc->callback_param = ourport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) dma->rx_bytes_requested = dma->rx_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) dma->rx_cookie = dmaengine_submit(dma->rx_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) dma_async_issue_pending(dma->rx_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) /* ? - where has parity gone?? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) #define S3C2410_UERSTAT_PARITY (0x1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) static void enable_rx_dma(struct s3c24xx_uart_port *ourport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) struct uart_port *port = &ourport->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) unsigned int ucon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) /* set Rx mode to DMA mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) ucon = rd_regl(port, S3C2410_UCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) ucon &= ~(S3C64XX_UCON_RXBURST_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) S3C64XX_UCON_TIMEOUT_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) S3C64XX_UCON_EMPTYINT_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) S3C64XX_UCON_DMASUS_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) S3C64XX_UCON_TIMEOUT_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) S3C64XX_UCON_RXMODE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) ucon |= S3C64XX_UCON_RXBURST_16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 0xf << S3C64XX_UCON_TIMEOUT_SHIFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) S3C64XX_UCON_EMPTYINT_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) S3C64XX_UCON_TIMEOUT_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) S3C64XX_UCON_RXMODE_DMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) wr_regl(port, S3C2410_UCON, ucon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) ourport->rx_mode = S3C24XX_RX_DMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) static void enable_rx_pio(struct s3c24xx_uart_port *ourport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) struct uart_port *port = &ourport->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) unsigned int ucon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) /* set Rx mode to DMA mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) ucon = rd_regl(port, S3C2410_UCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) ucon &= ~(S3C64XX_UCON_TIMEOUT_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) S3C64XX_UCON_EMPTYINT_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) S3C64XX_UCON_DMASUS_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) S3C64XX_UCON_TIMEOUT_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) S3C64XX_UCON_RXMODE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) ucon |= 0xf << S3C64XX_UCON_TIMEOUT_SHIFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) S3C64XX_UCON_TIMEOUT_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) S3C64XX_UCON_RXMODE_CPU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) wr_regl(port, S3C2410_UCON, ucon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) ourport->rx_mode = S3C24XX_RX_PIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) static void s3c24xx_serial_rx_drain_fifo(struct s3c24xx_uart_port *ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) static irqreturn_t s3c24xx_serial_rx_chars_dma(void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) unsigned int utrstat, received;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) struct s3c24xx_uart_port *ourport = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) struct uart_port *port = &ourport->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) struct s3c24xx_uart_dma *dma = ourport->dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) struct tty_struct *tty = tty_port_tty_get(&ourport->port.state->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) struct tty_port *t = &port->state->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) struct dma_tx_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) utrstat = rd_regl(port, S3C2410_UTRSTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) rd_regl(port, S3C2410_UFSTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (!(utrstat & S3C2410_UTRSTAT_TIMEOUT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) s3c64xx_start_rx_dma(ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (ourport->rx_mode == S3C24XX_RX_PIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) enable_rx_dma(ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) goto finish;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (ourport->rx_mode == S3C24XX_RX_DMA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) dmaengine_pause(dma->rx_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) dmaengine_tx_status(dma->rx_chan, dma->rx_cookie, &state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) dmaengine_terminate_all(dma->rx_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) received = dma->rx_bytes_requested - state.residue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) s3c24xx_uart_copy_rx_to_tty(ourport, t, received);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) enable_rx_pio(ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) s3c24xx_serial_rx_drain_fifo(ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (tty) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) tty_flip_buffer_push(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) tty_kref_put(tty);
^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) wr_regl(port, S3C2410_UTRSTAT, S3C2410_UTRSTAT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) finish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) static void s3c24xx_serial_rx_drain_fifo(struct s3c24xx_uart_port *ourport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) struct uart_port *port = &ourport->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) unsigned int ufcon, ch, flag, ufstat, uerstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) unsigned int fifocnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) int max_count = port->fifosize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) while (max_count-- > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) * Receive all characters known to be in FIFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) * before reading FIFO level again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (fifocnt == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) ufstat = rd_regl(port, S3C2410_UFSTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) fifocnt = s3c24xx_serial_rx_fifocnt(ourport, ufstat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (fifocnt == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) fifocnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) uerstat = rd_regl(port, S3C2410_UERSTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) ch = rd_reg(port, S3C2410_URXH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (port->flags & UPF_CONS_FLOW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) int txe = s3c24xx_serial_txempty_nofifo(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (ourport->rx_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if (!txe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) ourport->rx_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (txe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) ufcon = rd_regl(port, S3C2410_UFCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) ufcon |= S3C2410_UFCON_RESETRX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) wr_regl(port, S3C2410_UFCON, ufcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) ourport->rx_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) continue;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) /* insert the character into the buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) flag = TTY_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) port->icount.rx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (unlikely(uerstat & S3C2410_UERSTAT_ANY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) dev_dbg(port->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) "rxerr: port ch=0x%02x, rxs=0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) ch, uerstat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) /* check for break */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (uerstat & S3C2410_UERSTAT_BREAK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) dev_dbg(port->dev, "break!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) port->icount.brk++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (uart_handle_break(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) continue; /* Ignore character */
^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) if (uerstat & S3C2410_UERSTAT_FRAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) port->icount.frame++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (uerstat & S3C2410_UERSTAT_OVERRUN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) port->icount.overrun++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) uerstat &= port->read_status_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (uerstat & S3C2410_UERSTAT_BREAK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) flag = TTY_BREAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) else if (uerstat & S3C2410_UERSTAT_PARITY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) flag = TTY_PARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) else if (uerstat & (S3C2410_UERSTAT_FRAME |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) S3C2410_UERSTAT_OVERRUN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) flag = TTY_FRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (uart_handle_sysrq_char(port, ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) continue; /* Ignore character */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) uart_insert_char(port, uerstat, S3C2410_UERSTAT_OVERRUN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) ch, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) tty_flip_buffer_push(&port->state->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) static irqreturn_t s3c24xx_serial_rx_chars_pio(void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) struct s3c24xx_uart_port *ourport = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) struct uart_port *port = &ourport->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) s3c24xx_serial_rx_drain_fifo(ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) static irqreturn_t s3c24xx_serial_rx_chars(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) struct s3c24xx_uart_port *ourport = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (ourport->dma && ourport->dma->rx_chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) return s3c24xx_serial_rx_chars_dma(dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) return s3c24xx_serial_rx_chars_pio(dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) struct s3c24xx_uart_port *ourport = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) struct uart_port *port = &ourport->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) struct circ_buf *xmit = &port->state->xmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) int count, dma_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (ourport->dma && ourport->dma->tx_chan &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) count >= ourport->min_dma_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) int align = dma_get_cache_alignment() -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) (xmit->tail & (dma_get_cache_alignment() - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) if (count - align >= ourport->min_dma_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) dma_count = count - align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) count = align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (port->x_char) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) wr_reg(port, S3C2410_UTXH, port->x_char);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) port->icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) port->x_char = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) /* if there isn't anything more to transmit, or the uart is now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) * stopped, disable the uart and exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) s3c24xx_serial_stop_tx(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) goto out;
^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) /* try and drain the buffer... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (count > port->fifosize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) count = port->fifosize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) dma_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) while (!uart_circ_empty(xmit) && count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (rd_regl(port, S3C2410_UFSTAT) & ourport->info->tx_fifofull)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) wr_reg(port, S3C2410_UTXH, xmit->buf[xmit->tail]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) port->icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) if (!count && dma_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) s3c24xx_serial_start_tx_dma(ourport, dma_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) spin_unlock(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) uart_write_wakeup(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) spin_lock(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) if (uart_circ_empty(xmit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) s3c24xx_serial_stop_tx(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) /* interrupt handler for s3c64xx and later SoC's.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) struct s3c24xx_uart_port *ourport = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) struct uart_port *port = &ourport->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) unsigned int pend = rd_regl(port, S3C64XX_UINTP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) irqreturn_t ret = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (pend & S3C64XX_UINTM_RXD_MSK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) ret = s3c24xx_serial_rx_chars(irq, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_RXD_MSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) if (pend & S3C64XX_UINTM_TXD_MSK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) ret = s3c24xx_serial_tx_chars(irq, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_TXD_MSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) static unsigned int s3c24xx_serial_tx_empty(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) unsigned long ufstat = rd_regl(port, S3C2410_UFSTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) unsigned long ufcon = rd_regl(port, S3C2410_UFCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) if (ufcon & S3C2410_UFCON_FIFOMODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if ((ufstat & info->tx_fifomask) != 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) (ufstat & info->tx_fifofull))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) return s3c24xx_serial_txempty_nofifo(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) /* no modem control lines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) static unsigned int s3c24xx_serial_get_mctrl(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) unsigned int umstat = rd_reg(port, S3C2410_UMSTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (umstat & S3C2410_UMSTAT_CTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) return TIOCM_CAR | TIOCM_DSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) static void s3c24xx_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) unsigned int umcon = rd_regl(port, S3C2410_UMCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) if (mctrl & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) umcon |= S3C2410_UMCOM_RTS_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) umcon &= ~S3C2410_UMCOM_RTS_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) wr_regl(port, S3C2410_UMCON, umcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) unsigned int ucon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) ucon = rd_regl(port, S3C2410_UCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (break_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) ucon |= S3C2410_UCON_SBREAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) ucon &= ~S3C2410_UCON_SBREAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) wr_regl(port, S3C2410_UCON, ucon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) struct s3c24xx_uart_dma *dma = p->dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) struct dma_slave_caps dma_caps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) const char *reason = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) /* Default slave configuration parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) dma->rx_conf.direction = DMA_DEV_TO_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) dma->rx_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) dma->rx_conf.src_addr = p->port.mapbase + S3C2410_URXH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) dma->rx_conf.src_maxburst = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) dma->tx_conf.direction = DMA_MEM_TO_DEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) dma->tx_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) dma->tx_conf.dst_addr = p->port.mapbase + S3C2410_UTXH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) dma->tx_conf.dst_maxburst = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) dma->rx_chan = dma_request_chan(p->port.dev, "rx");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) if (IS_ERR(dma->rx_chan)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) reason = "DMA RX channel request failed";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) ret = PTR_ERR(dma->rx_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) goto err_warn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) ret = dma_get_slave_caps(dma->rx_chan, &dma_caps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (ret < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) dma_caps.residue_granularity < DMA_RESIDUE_GRANULARITY_BURST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) reason = "insufficient DMA RX engine capabilities";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) ret = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) goto err_release_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) dmaengine_slave_config(dma->rx_chan, &dma->rx_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) dma->tx_chan = dma_request_chan(p->port.dev, "tx");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (IS_ERR(dma->tx_chan)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) reason = "DMA TX channel request failed";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) ret = PTR_ERR(dma->tx_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) goto err_release_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) ret = dma_get_slave_caps(dma->tx_chan, &dma_caps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (ret < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) dma_caps.residue_granularity < DMA_RESIDUE_GRANULARITY_BURST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) reason = "insufficient DMA TX engine capabilities";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) ret = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) goto err_release_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) dmaengine_slave_config(dma->tx_chan, &dma->tx_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) /* RX buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) dma->rx_size = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) dma->rx_buf = kmalloc(dma->rx_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (!dma->rx_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) goto err_release_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) dma->rx_addr = dma_map_single(p->port.dev, dma->rx_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) dma->rx_size, DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) if (dma_mapping_error(p->port.dev, dma->rx_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) reason = "DMA mapping error for RX buffer";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) goto err_free_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) /* TX buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) dma->tx_addr = dma_map_single(p->port.dev, p->port.state->xmit.buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) UART_XMIT_SIZE, DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) if (dma_mapping_error(p->port.dev, dma->tx_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) reason = "DMA mapping error for TX buffer";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) goto err_unmap_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) err_unmap_rx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) dma_unmap_single(p->port.dev, dma->rx_addr, dma->rx_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) err_free_rx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) kfree(dma->rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) err_release_tx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) dma_release_channel(dma->tx_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) err_release_rx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) dma_release_channel(dma->rx_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) err_warn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) if (reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) dev_warn(p->port.dev, "%s, DMA will not be used\n", reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) static void s3c24xx_serial_release_dma(struct s3c24xx_uart_port *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) struct s3c24xx_uart_dma *dma = p->dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) if (dma->rx_chan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) dmaengine_terminate_all(dma->rx_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) dma_unmap_single(p->port.dev, dma->rx_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) dma->rx_size, DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) kfree(dma->rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) dma_release_channel(dma->rx_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) dma->rx_chan = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (dma->tx_chan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) dmaengine_terminate_all(dma->tx_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) dma_unmap_single(p->port.dev, dma->tx_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) UART_XMIT_SIZE, DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) dma_release_channel(dma->tx_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) dma->tx_chan = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) static void s3c24xx_serial_shutdown(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) struct s3c24xx_uart_port *ourport = to_ourport(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) if (ourport->tx_claimed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) if (!s3c24xx_serial_has_interrupt_mask(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) free_irq(ourport->tx_irq, ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) ourport->tx_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) ourport->tx_claimed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) ourport->tx_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) if (ourport->rx_claimed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (!s3c24xx_serial_has_interrupt_mask(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) free_irq(ourport->rx_irq, ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) ourport->rx_claimed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) ourport->rx_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) /* Clear pending interrupts and mask all interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) if (s3c24xx_serial_has_interrupt_mask(port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) free_irq(port->irq, ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) wr_regl(port, S3C64XX_UINTP, 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) wr_regl(port, S3C64XX_UINTM, 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) if (ourport->dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) s3c24xx_serial_release_dma(ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) ourport->tx_in_progress = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) static int s3c24xx_serial_startup(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) struct s3c24xx_uart_port *ourport = to_ourport(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) ourport->rx_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_chars, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) s3c24xx_serial_portname(port), ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) dev_err(port->dev, "cannot get irq %d\n", ourport->rx_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) ourport->rx_claimed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) dev_dbg(port->dev, "requesting tx irq...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) ourport->tx_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) ret = request_irq(ourport->tx_irq, s3c24xx_serial_tx_chars, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) s3c24xx_serial_portname(port), ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) dev_err(port->dev, "cannot get irq %d\n", ourport->tx_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) ourport->tx_claimed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) /* the port reset code should have done the correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) * register setup for the port controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) s3c24xx_serial_shutdown(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) static int s3c64xx_serial_startup(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) struct s3c24xx_uart_port *ourport = to_ourport(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) unsigned int ufcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) wr_regl(port, S3C64XX_UINTM, 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) if (ourport->dma) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) ret = s3c24xx_serial_request_dma(ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) devm_kfree(port->dev, ourport->dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) ourport->dma = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) ret = request_irq(port->irq, s3c64xx_serial_handle_irq, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) s3c24xx_serial_portname(port), ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) dev_err(port->dev, "cannot get irq %d\n", port->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) /* For compatibility with s3c24xx Soc's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) ourport->rx_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) ourport->rx_claimed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) ourport->tx_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) ourport->tx_claimed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) ufcon = rd_regl(port, S3C2410_UFCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) ufcon |= S3C2410_UFCON_RESETRX | S5PV210_UFCON_RXTRIG8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) if (!uart_console(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) ufcon |= S3C2410_UFCON_RESETTX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) wr_regl(port, S3C2410_UFCON, ufcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) enable_rx_pio(ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) /* Enable Rx Interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) s3c24xx_clear_bit(port, S3C64XX_UINTM_RXD, S3C64XX_UINTM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) /* power power management control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) unsigned int old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) struct s3c24xx_uart_port *ourport = to_ourport(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) int timeout = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) ourport->pm_level = level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) switch (level) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) while (--timeout && !s3c24xx_serial_txempty_nofifo(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) if (!IS_ERR(ourport->baudclk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) clk_disable_unprepare(ourport->baudclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) clk_disable_unprepare(ourport->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) clk_prepare_enable(ourport->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) if (!IS_ERR(ourport->baudclk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) clk_prepare_enable(ourport->baudclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) dev_err(port->dev, "s3c24xx_serial: unknown pm %d\n", level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) /* baud rate calculation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) * The UARTs on the S3C2410/S3C2440 can take their clocks from a number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) * of different sources, including the peripheral clock ("pclk") and an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) * external clock ("uclk"). The S3C2440 also adds the core clock ("fclk")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) * with a programmable extra divisor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) * The following code goes through the clock sources, and calculates the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) * baud clocks (and the resultant actual baud rates) and then tries to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) * pick the closest one and select that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) #define MAX_CLK_NAME_LENGTH 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) static inline int s3c24xx_serial_getsource(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) unsigned int ucon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) if (info->num_clks == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) ucon = rd_regl(port, S3C2410_UCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) ucon &= info->clksel_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) return ucon >> info->clksel_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) static void s3c24xx_serial_setsource(struct uart_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) unsigned int clk_sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) unsigned int ucon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) if (info->num_clks == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) ucon = rd_regl(port, S3C2410_UCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) if ((ucon & info->clksel_mask) >> info->clksel_shift == clk_sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) ucon &= ~info->clksel_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) ucon |= clk_sel << info->clksel_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) wr_regl(port, S3C2410_UCON, ucon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) static unsigned int s3c24xx_serial_getclk(struct s3c24xx_uart_port *ourport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) unsigned int req_baud, struct clk **best_clk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) unsigned int *clk_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) struct s3c24xx_uart_info *info = ourport->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) unsigned long rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) unsigned int cnt, baud, quot, best_quot = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) char clkname[MAX_CLK_NAME_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) int calc_deviation, deviation = (1 << 30) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) for (cnt = 0; cnt < info->num_clks; cnt++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) /* Keep selected clock if provided */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) if (ourport->cfg->clk_sel &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) !(ourport->cfg->clk_sel & (1 << cnt)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) sprintf(clkname, "clk_uart_baud%d", cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) clk = clk_get(ourport->port.dev, clkname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) rate = clk_get_rate(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) if (!rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) if (ourport->info->has_divslot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) unsigned long div = rate / req_baud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) /* The UDIVSLOT register on the newer UARTs allows us to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) * get a divisor adjustment of 1/16th on the baud clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) * We don't keep the UDIVSLOT value (the 16ths we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) * calculated by not multiplying the baud by 16) as it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) * is easy enough to recalculate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) quot = div / 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) baud = rate / div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) quot = (rate + (8 * req_baud)) / (16 * req_baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) baud = rate / (quot * 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) quot--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) calc_deviation = req_baud - baud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) if (calc_deviation < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) calc_deviation = -calc_deviation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) if (calc_deviation < deviation) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) *best_clk = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) best_quot = quot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) *clk_num = cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) deviation = calc_deviation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) return best_quot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) /* udivslot_table[]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) * This table takes the fractional value of the baud divisor and gives
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) * the recommended setting for the UDIVSLOT register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) static u16 udivslot_table[16] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) [0] = 0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) [1] = 0x0080,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) [2] = 0x0808,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) [3] = 0x0888,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) [4] = 0x2222,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) [5] = 0x4924,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) [6] = 0x4A52,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) [7] = 0x54AA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) [8] = 0x5555,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) [9] = 0xD555,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) [10] = 0xD5D5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) [11] = 0xDDD5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) [12] = 0xDDDD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) [13] = 0xDFDD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) [14] = 0xDFDF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) [15] = 0xFFDF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) static void s3c24xx_serial_set_termios(struct uart_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) struct ktermios *termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) struct ktermios *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) struct s3c24xx_uart_port *ourport = to_ourport(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) struct clk *clk = ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) unsigned int baud, quot, clk_sel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) unsigned int ulcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) unsigned int umcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) unsigned int udivslot = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) * We don't support modem control lines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) termios->c_cflag &= ~(HUPCL | CMSPAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) termios->c_cflag |= CLOCAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) * Ask the core to calculate the divisor for us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) baud = uart_get_baud_rate(port, termios, old, 0, 3000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) quot = s3c24xx_serial_getclk(ourport, baud, &clk, &clk_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) quot = port->custom_divisor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) /* check to see if we need to change clock source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) if (ourport->baudclk != clk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) clk_prepare_enable(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) s3c24xx_serial_setsource(port, clk_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) if (!IS_ERR(ourport->baudclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) clk_disable_unprepare(ourport->baudclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) ourport->baudclk = ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) ourport->baudclk = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) if (ourport->info->has_divslot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) unsigned int div = ourport->baudclk_rate / baud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) if (cfg->has_fracval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) udivslot = (div & 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) dev_dbg(port->dev, "fracval = %04x\n", udivslot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) udivslot = udivslot_table[div & 15];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) dev_dbg(port->dev, "udivslot = %04x (div %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) udivslot, div & 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) switch (termios->c_cflag & CSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) case CS5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) dev_dbg(port->dev, "config: 5bits/char\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) ulcon = S3C2410_LCON_CS5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) case CS6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) dev_dbg(port->dev, "config: 6bits/char\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) ulcon = S3C2410_LCON_CS6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) case CS7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) dev_dbg(port->dev, "config: 7bits/char\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) ulcon = S3C2410_LCON_CS7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) case CS8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) dev_dbg(port->dev, "config: 8bits/char\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) ulcon = S3C2410_LCON_CS8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) /* preserve original lcon IR settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) ulcon |= (cfg->ulcon & S3C2410_LCON_IRM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) if (termios->c_cflag & CSTOPB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) ulcon |= S3C2410_LCON_STOPB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) if (termios->c_cflag & PARENB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) if (termios->c_cflag & PARODD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) ulcon |= S3C2410_LCON_PODD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) ulcon |= S3C2410_LCON_PEVEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) ulcon |= S3C2410_LCON_PNONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) dev_dbg(port->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) "setting ulcon to %08x, brddiv to %d, udivslot %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) ulcon, quot, udivslot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) wr_regl(port, S3C2410_ULCON, ulcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) wr_regl(port, S3C2410_UBRDIV, quot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) port->status &= ~UPSTAT_AUTOCTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) umcon = rd_regl(port, S3C2410_UMCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) if (termios->c_cflag & CRTSCTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) umcon |= S3C2410_UMCOM_AFC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) /* Disable RTS when RX FIFO contains 63 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) umcon &= ~S3C2412_UMCON_AFC_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) port->status = UPSTAT_AUTOCTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) umcon &= ~S3C2410_UMCOM_AFC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) wr_regl(port, S3C2410_UMCON, umcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) if (ourport->info->has_divslot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) wr_regl(port, S3C2443_DIVSLOT, udivslot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) dev_dbg(port->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) "uart: ulcon = 0x%08x, ucon = 0x%08x, ufcon = 0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) rd_regl(port, S3C2410_ULCON),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) rd_regl(port, S3C2410_UCON),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) rd_regl(port, S3C2410_UFCON));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) * Update the per-port timeout.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) uart_update_timeout(port, termios->c_cflag, baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) * Which character status flags are we interested in?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) port->read_status_mask = S3C2410_UERSTAT_OVERRUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) if (termios->c_iflag & INPCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) port->read_status_mask |= S3C2410_UERSTAT_FRAME |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) S3C2410_UERSTAT_PARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) * Which character status flags should we ignore?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) port->ignore_status_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) if (termios->c_iflag & IGNPAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) port->ignore_status_mask |= S3C2410_UERSTAT_OVERRUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) if (termios->c_iflag & IGNBRK && termios->c_iflag & IGNPAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) port->ignore_status_mask |= S3C2410_UERSTAT_FRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) * Ignore all characters if CREAD is not set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) if ((termios->c_cflag & CREAD) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) port->ignore_status_mask |= RXSTAT_DUMMY_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) static const char *s3c24xx_serial_type(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) switch (port->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) case PORT_S3C2410:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) return "S3C2410";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) case PORT_S3C2440:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) return "S3C2440";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) case PORT_S3C2412:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) return "S3C2412";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) case PORT_S3C6400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) return "S3C6400/10";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) #define MAP_SIZE (0x100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) static void s3c24xx_serial_release_port(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) release_mem_region(port->mapbase, MAP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) static int s3c24xx_serial_request_port(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) const char *name = s3c24xx_serial_portname(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) return request_mem_region(port->mapbase, MAP_SIZE, name) ? 0 : -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) static void s3c24xx_serial_config_port(struct uart_port *port, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) if (flags & UART_CONFIG_TYPE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) s3c24xx_serial_request_port(port) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) port->type = info->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) * verify the new serial_struct (for TIOCSSERIAL).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) s3c24xx_serial_verify_port(struct uart_port *port, struct serial_struct *ser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) if (ser->type != PORT_UNKNOWN && ser->type != info->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) #ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) static struct console s3c24xx_serial_console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) static int __init s3c24xx_serial_console_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) register_console(&s3c24xx_serial_console);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) console_initcall(s3c24xx_serial_console_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) #define S3C24XX_SERIAL_CONSOLE &s3c24xx_serial_console
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) #define S3C24XX_SERIAL_CONSOLE NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) #if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_CONSOLE_POLL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) static int s3c24xx_serial_get_poll_char(struct uart_port *port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) static void s3c24xx_serial_put_poll_char(struct uart_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) unsigned char c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) static struct uart_ops s3c24xx_serial_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) .pm = s3c24xx_serial_pm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) .tx_empty = s3c24xx_serial_tx_empty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) .get_mctrl = s3c24xx_serial_get_mctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) .set_mctrl = s3c24xx_serial_set_mctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) .stop_tx = s3c24xx_serial_stop_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) .start_tx = s3c24xx_serial_start_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) .stop_rx = s3c24xx_serial_stop_rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) .break_ctl = s3c24xx_serial_break_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) .startup = s3c24xx_serial_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) .shutdown = s3c24xx_serial_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) .set_termios = s3c24xx_serial_set_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) .type = s3c24xx_serial_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) .release_port = s3c24xx_serial_release_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) .request_port = s3c24xx_serial_request_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) .config_port = s3c24xx_serial_config_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) .verify_port = s3c24xx_serial_verify_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) #if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_CONSOLE_POLL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) .poll_get_char = s3c24xx_serial_get_poll_char,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) .poll_put_char = s3c24xx_serial_put_poll_char,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) static struct uart_driver s3c24xx_uart_drv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) .driver_name = "s3c2410_serial",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) .nr = CONFIG_SERIAL_SAMSUNG_UARTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) .cons = S3C24XX_SERIAL_CONSOLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) .dev_name = S3C24XX_SERIAL_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) .major = S3C24XX_SERIAL_MAJOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) .minor = S3C24XX_SERIAL_MINOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) #define __PORT_LOCK_UNLOCKED(i) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[i].port.lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) static struct s3c24xx_uart_port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) [0] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) .port = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) .lock = __PORT_LOCK_UNLOCKED(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) .iotype = UPIO_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) .uartclk = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) .fifosize = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) .ops = &s3c24xx_serial_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) .flags = UPF_BOOT_AUTOCONF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) .line = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) [1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) .port = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) .lock = __PORT_LOCK_UNLOCKED(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) .iotype = UPIO_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) .uartclk = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) .fifosize = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) .ops = &s3c24xx_serial_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) .flags = UPF_BOOT_AUTOCONF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) .line = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) #if CONFIG_SERIAL_SAMSUNG_UARTS > 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) [2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) .port = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) .lock = __PORT_LOCK_UNLOCKED(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) .iotype = UPIO_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) .uartclk = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) .fifosize = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) .ops = &s3c24xx_serial_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) .flags = UPF_BOOT_AUTOCONF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) .line = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) #if CONFIG_SERIAL_SAMSUNG_UARTS > 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) [3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) .port = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) .lock = __PORT_LOCK_UNLOCKED(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) .iotype = UPIO_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) .uartclk = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) .fifosize = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) .ops = &s3c24xx_serial_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) .flags = UPF_BOOT_AUTOCONF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) .line = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) #undef __PORT_LOCK_UNLOCKED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) /* s3c24xx_serial_resetport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) * reset the fifos and other the settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) static void s3c24xx_serial_resetport(struct uart_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) struct s3c2410_uartcfg *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) unsigned long ucon = rd_regl(port, S3C2410_UCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) unsigned int ucon_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) ucon_mask = info->clksel_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) if (info->type == PORT_S3C2440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) ucon_mask |= S3C2440_UCON0_DIVMASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) ucon &= ucon_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) /* reset both fifos */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) wr_regl(port, S3C2410_UFCON, cfg->ufcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) /* some delay is required after fifo reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) #ifdef CONFIG_ARM_S3C24XX_CPUFREQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) unsigned long val, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) struct s3c24xx_uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) struct uart_port *uport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) port = container_of(nb, struct s3c24xx_uart_port, freq_transition);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) uport = &port->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) /* check to see if port is enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) if (port->pm_level != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) /* try and work out if the baudrate is changing, we can detect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) * a change in rate, but we do not have support for detecting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) * a disturbance in the clock-rate over the change.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) if (IS_ERR(port->baudclk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) if (port->baudclk_rate == clk_get_rate(port->baudclk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) if (val == CPUFREQ_PRECHANGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) /* we should really shut the port down whilst the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) * frequency change is in progress.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) } else if (val == CPUFREQ_POSTCHANGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) struct ktermios *termios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) struct tty_struct *tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) if (uport->state == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) tty = uport->state->port.tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) if (tty == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) termios = &tty->termios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) if (termios == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) dev_warn(uport->dev, "%s: no termios?\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) s3c24xx_serial_set_termios(uport, termios, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) port->freq_transition.notifier_call = s3c24xx_serial_cpufreq_transition;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) return cpufreq_register_notifier(&port->freq_transition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) CPUFREQ_TRANSITION_NOTIFIER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) cpufreq_unregister_notifier(&port->freq_transition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) CPUFREQ_TRANSITION_NOTIFIER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) static int s3c24xx_serial_enable_baudclk(struct s3c24xx_uart_port *ourport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) struct device *dev = ourport->port.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) struct s3c24xx_uart_info *info = ourport->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) char clk_name[MAX_CLK_NAME_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) unsigned int clk_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) int clk_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) clk_sel = ourport->cfg->clk_sel ? : info->def_clk_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) for (clk_num = 0; clk_num < info->num_clks; clk_num++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) if (!(clk_sel & (1 << clk_num)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) sprintf(clk_name, "clk_uart_baud%d", clk_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) clk = clk_get(dev, clk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) ret = clk_prepare_enable(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) clk_put(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) ourport->baudclk = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) ourport->baudclk_rate = clk_get_rate(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) s3c24xx_serial_setsource(&ourport->port, clk_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) /* s3c24xx_serial_init_port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) * initialise a single serial port from the platform device given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) struct platform_device *platdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) struct uart_port *port = &ourport->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) struct s3c2410_uartcfg *cfg = ourport->cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) if (platdev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) if (port->mapbase != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) /* setup info for port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) port->dev = &platdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) /* Startup sequence is different for s3c64xx and higher SoC's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) if (s3c24xx_serial_has_interrupt_mask(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) s3c24xx_serial_ops.startup = s3c64xx_serial_startup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) port->uartclk = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) if (cfg->uart_flags & UPF_CONS_FLOW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) dev_dbg(port->dev, "enabling flow control\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) port->flags |= UPF_CONS_FLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) /* sort our the physical and virtual addresses for each UART */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) res = platform_get_resource(platdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) if (res == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) dev_err(port->dev, "failed to find memory resource for uart\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) dev_dbg(port->dev, "resource %pR)\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) port->membase = devm_ioremap(port->dev, res->start, resource_size(res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) if (!port->membase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) dev_err(port->dev, "failed to remap controller address\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) port->mapbase = res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) ret = platform_get_irq(platdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) port->irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) port->irq = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) ourport->rx_irq = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) ourport->tx_irq = ret + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) if (!s3c24xx_serial_has_interrupt_mask(port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) ret = platform_get_irq(platdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) ourport->tx_irq = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) * DMA is currently supported only on DT platforms, if DMA properties
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) * are specified.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) if (platdev->dev.of_node && of_find_property(platdev->dev.of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) "dmas", NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) ourport->dma = devm_kzalloc(port->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) sizeof(*ourport->dma),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) if (!ourport->dma) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) ourport->clk = clk_get(&platdev->dev, "uart");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) if (IS_ERR(ourport->clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) pr_err("%s: Controller clock not found\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) dev_name(&platdev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) ret = PTR_ERR(ourport->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) ret = clk_prepare_enable(ourport->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) pr_err("uart: clock failed to prepare+enable: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) clk_put(ourport->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) ret = s3c24xx_serial_enable_baudclk(ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) pr_warn("uart: failed to enable baudclk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) /* Keep all interrupts masked and cleared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) if (s3c24xx_serial_has_interrupt_mask(port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) wr_regl(port, S3C64XX_UINTM, 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) wr_regl(port, S3C64XX_UINTP, 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) wr_regl(port, S3C64XX_UINTSP, 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) dev_dbg(port->dev, "port: map=%pa, mem=%p, irq=%d (%d,%d), clock=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) &port->mapbase, port->membase, port->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) ourport->rx_irq, ourport->tx_irq, port->uartclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) /* reset the fifos (and setup the uart) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) s3c24xx_serial_resetport(port, cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) port->mapbase = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) /* Device driver serial port probe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) static const struct of_device_id s3c24xx_uart_dt_match[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) static int probe_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) static inline struct s3c24xx_serial_drv_data *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) s3c24xx_get_driver_data(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) if (pdev->dev.of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) const struct of_device_id *match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) match = of_match_node(s3c24xx_uart_dt_match, pdev->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) return (struct s3c24xx_serial_drv_data *)match->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) return (struct s3c24xx_serial_drv_data *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) platform_get_device_id(pdev)->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) static int s3c24xx_serial_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) struct device_node *np = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) struct s3c24xx_uart_port *ourport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) int index = probe_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) int ret, prop = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) if (np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) ret = of_alias_get_id(np, "serial");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) index = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) if (index >= ARRAY_SIZE(s3c24xx_serial_ports)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) dev_err(&pdev->dev, "serial%d out of range\n", index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) ourport = &s3c24xx_serial_ports[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) ourport->drv_data = s3c24xx_get_driver_data(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) if (!ourport->drv_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) dev_err(&pdev->dev, "could not find driver data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) ourport->baudclk = ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) ourport->info = ourport->drv_data->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) ourport->cfg = (dev_get_platdata(&pdev->dev)) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) dev_get_platdata(&pdev->dev) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) ourport->drv_data->def_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) if (np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) of_property_read_u32(np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) "samsung,uart-fifosize", &ourport->port.fifosize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) switch (prop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) ourport->port.iotype = UPIO_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) ourport->port.iotype = UPIO_MEM32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) dev_warn(&pdev->dev, "unsupported reg-io-width (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) if (ourport->drv_data->fifosize[index])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) ourport->port.fifosize = ourport->drv_data->fifosize[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) else if (ourport->info->fifosize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) ourport->port.fifosize = ourport->info->fifosize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) ourport->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_SAMSUNG_CONSOLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) * DMA transfers must be aligned at least to cache line size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) * so find minimal transfer size suitable for DMA mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) ourport->min_dma_size = max_t(int, ourport->port.fifosize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) dma_get_cache_alignment());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) dev_dbg(&pdev->dev, "%s: initialising port %p...\n", __func__, ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) ret = s3c24xx_serial_init_port(ourport, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) if (!s3c24xx_uart_drv.state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) ret = uart_register_driver(&s3c24xx_uart_drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) pr_err("Failed to register Samsung UART driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) dev_dbg(&pdev->dev, "%s: adding port\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) uart_add_one_port(&s3c24xx_uart_drv, &ourport->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) platform_set_drvdata(pdev, &ourport->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) * Deactivate the clock enabled in s3c24xx_serial_init_port here,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) * so that a potential re-enablement through the pm-callback overlaps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) * and keeps the clock enabled in this case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) clk_disable_unprepare(ourport->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) if (!IS_ERR(ourport->baudclk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) clk_disable_unprepare(ourport->baudclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) ret = s3c24xx_serial_cpufreq_register(ourport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) dev_err(&pdev->dev, "failed to add cpufreq notifier\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) probe_index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) static int s3c24xx_serial_remove(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) if (port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) s3c24xx_serial_cpufreq_deregister(to_ourport(port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) uart_remove_one_port(&s3c24xx_uart_drv, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) uart_unregister_driver(&s3c24xx_uart_drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) /* UART power management code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) static int s3c24xx_serial_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) struct uart_port *port = s3c24xx_dev_to_port(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) if (port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) uart_suspend_port(&s3c24xx_uart_drv, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) static int s3c24xx_serial_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) struct uart_port *port = s3c24xx_dev_to_port(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) struct s3c24xx_uart_port *ourport = to_ourport(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) if (port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) clk_prepare_enable(ourport->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) if (!IS_ERR(ourport->baudclk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) clk_prepare_enable(ourport->baudclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) if (!IS_ERR(ourport->baudclk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) clk_disable_unprepare(ourport->baudclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) clk_disable_unprepare(ourport->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) uart_resume_port(&s3c24xx_uart_drv, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) static int s3c24xx_serial_resume_noirq(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) struct uart_port *port = s3c24xx_dev_to_port(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) struct s3c24xx_uart_port *ourport = to_ourport(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) if (port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) /* restore IRQ mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) if (s3c24xx_serial_has_interrupt_mask(port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) unsigned int uintm = 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) if (ourport->tx_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) uintm &= ~S3C64XX_UINTM_TXD_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) if (ourport->rx_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) uintm &= ~S3C64XX_UINTM_RXD_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) clk_prepare_enable(ourport->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) if (!IS_ERR(ourport->baudclk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) clk_prepare_enable(ourport->baudclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) wr_regl(port, S3C64XX_UINTM, uintm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) if (!IS_ERR(ourport->baudclk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) clk_disable_unprepare(ourport->baudclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) clk_disable_unprepare(ourport->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) static const struct dev_pm_ops s3c24xx_serial_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) .suspend = s3c24xx_serial_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) .resume = s3c24xx_serial_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) .resume_noirq = s3c24xx_serial_resume_noirq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) #define SERIAL_SAMSUNG_PM_OPS (&s3c24xx_serial_pm_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) #else /* !CONFIG_PM_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) #define SERIAL_SAMSUNG_PM_OPS NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) #endif /* CONFIG_PM_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) /* Console code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) #ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) static struct uart_port *cons_uart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) s3c24xx_serial_console_txrdy(struct uart_port *port, unsigned int ufcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) unsigned long ufstat, utrstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) if (ufcon & S3C2410_UFCON_FIFOMODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) /* fifo mode - check amount of data in fifo registers... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) ufstat = rd_regl(port, S3C2410_UFSTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) return (ufstat & info->tx_fifofull) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) /* in non-fifo mode, we go and use the tx buffer empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) utrstat = rd_regl(port, S3C2410_UTRSTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) return (utrstat & S3C2410_UTRSTAT_TXE) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) s3c24xx_port_configured(unsigned int ucon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) /* consider the serial port configured if the tx/rx mode set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) return (ucon & 0xf) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) #ifdef CONFIG_CONSOLE_POLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) * Console polling routines for writing and reading from the uart while
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) * in an interrupt or debug context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) static int s3c24xx_serial_get_poll_char(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) struct s3c24xx_uart_port *ourport = to_ourport(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) unsigned int ufstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) ufstat = rd_regl(port, S3C2410_UFSTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) return NO_POLL_CHAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) return rd_reg(port, S3C2410_URXH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) static void s3c24xx_serial_put_poll_char(struct uart_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) unsigned char c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) unsigned int ufcon = rd_regl(port, S3C2410_UFCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) unsigned int ucon = rd_regl(port, S3C2410_UCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) /* not possible to xmit on unconfigured port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) if (!s3c24xx_port_configured(ucon))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) while (!s3c24xx_serial_console_txrdy(port, ufcon))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) wr_reg(port, S3C2410_UTXH, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) #endif /* CONFIG_CONSOLE_POLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) s3c24xx_serial_console_putchar(struct uart_port *port, int ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) unsigned int ufcon = rd_regl(port, S3C2410_UFCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) while (!s3c24xx_serial_console_txrdy(port, ufcon))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) wr_reg(port, S3C2410_UTXH, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) s3c24xx_serial_console_write(struct console *co, const char *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) unsigned int ucon = rd_regl(cons_uart, S3C2410_UCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) /* not possible to xmit on unconfigured port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) if (!s3c24xx_port_configured(ucon))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) uart_console_write(cons_uart, s, count, s3c24xx_serial_console_putchar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) static void __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) s3c24xx_serial_get_options(struct uart_port *port, int *baud,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) int *parity, int *bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) unsigned int ulcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) unsigned int ucon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) unsigned int ubrdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) unsigned long rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) unsigned int clk_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) char clk_name[MAX_CLK_NAME_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) ulcon = rd_regl(port, S3C2410_ULCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) ucon = rd_regl(port, S3C2410_UCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) ubrdiv = rd_regl(port, S3C2410_UBRDIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) if (s3c24xx_port_configured(ucon)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) switch (ulcon & S3C2410_LCON_CSMASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) case S3C2410_LCON_CS5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) *bits = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) case S3C2410_LCON_CS6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) *bits = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) case S3C2410_LCON_CS7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) *bits = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) case S3C2410_LCON_CS8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) *bits = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) switch (ulcon & S3C2410_LCON_PMASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) case S3C2410_LCON_PEVEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) *parity = 'e';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) case S3C2410_LCON_PODD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) *parity = 'o';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) case S3C2410_LCON_PNONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) *parity = 'n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) /* now calculate the baud rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) clk_sel = s3c24xx_serial_getsource(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) sprintf(clk_name, "clk_uart_baud%d", clk_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) clk = clk_get(port->dev, clk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) if (!IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) rate = clk_get_rate(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) rate = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) *baud = rate / (16 * (ubrdiv + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) dev_dbg(port->dev, "calculated baud %d\n", *baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) s3c24xx_serial_console_setup(struct console *co, char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) struct uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) int baud = 9600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) int bits = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) int parity = 'n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) int flow = 'n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) /* is this a valid port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) if (co->index == -1 || co->index >= CONFIG_SERIAL_SAMSUNG_UARTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) co->index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) port = &s3c24xx_serial_ports[co->index].port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) /* is the port configured? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) if (port->mapbase == 0x0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) cons_uart = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) * Check whether an invalid uart number has been specified, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) * if so, search for the first available port that does have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) * console support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) if (options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) uart_parse_options(options, &baud, &parity, &bits, &flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) s3c24xx_serial_get_options(port, &baud, &parity, &bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) dev_dbg(port->dev, "baud %d\n", baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) return uart_set_options(port, co, baud, parity, bits, flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) static struct console s3c24xx_serial_console = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) .name = S3C24XX_SERIAL_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) .device = uart_console_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) .flags = CON_PRINTBUFFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) .index = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) .write = s3c24xx_serial_console_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) .setup = s3c24xx_serial_console_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) .data = &s3c24xx_uart_drv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) #endif /* CONFIG_SERIAL_SAMSUNG_CONSOLE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) #ifdef CONFIG_CPU_S3C2410
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) static struct s3c24xx_serial_drv_data s3c2410_serial_drv_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) .info = &(struct s3c24xx_uart_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) .name = "Samsung S3C2410 UART",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) .type = PORT_S3C2410,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) .fifosize = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) .rx_fifomask = S3C2410_UFSTAT_RXMASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) .rx_fifoshift = S3C2410_UFSTAT_RXSHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) .rx_fifofull = S3C2410_UFSTAT_RXFULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) .tx_fifofull = S3C2410_UFSTAT_TXFULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) .tx_fifomask = S3C2410_UFSTAT_TXMASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) .tx_fifoshift = S3C2410_UFSTAT_TXSHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) .def_clk_sel = S3C2410_UCON_CLKSEL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) .num_clks = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) .clksel_mask = S3C2410_UCON_CLKMASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) .clksel_shift = S3C2410_UCON_CLKSHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) .def_cfg = &(struct s3c2410_uartcfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) .ucon = S3C2410_UCON_DEFAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) .ufcon = S3C2410_UFCON_DEFAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) #define S3C2410_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2410_serial_drv_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) #define S3C2410_SERIAL_DRV_DATA (kernel_ulong_t)NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) #ifdef CONFIG_CPU_S3C2412
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) static struct s3c24xx_serial_drv_data s3c2412_serial_drv_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) .info = &(struct s3c24xx_uart_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) .name = "Samsung S3C2412 UART",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) .type = PORT_S3C2412,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) .fifosize = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) .has_divslot = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) .rx_fifomask = S3C2440_UFSTAT_RXMASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) .rx_fifofull = S3C2440_UFSTAT_RXFULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) .tx_fifofull = S3C2440_UFSTAT_TXFULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) .tx_fifomask = S3C2440_UFSTAT_TXMASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) .def_clk_sel = S3C2410_UCON_CLKSEL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) .num_clks = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) .clksel_mask = S3C2412_UCON_CLKMASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) .clksel_shift = S3C2412_UCON_CLKSHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) .def_cfg = &(struct s3c2410_uartcfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) .ucon = S3C2410_UCON_DEFAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) .ufcon = S3C2410_UFCON_DEFAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) #define S3C2412_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2412_serial_drv_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) #define S3C2412_SERIAL_DRV_DATA (kernel_ulong_t)NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) #if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2416) || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) .info = &(struct s3c24xx_uart_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) .name = "Samsung S3C2440 UART",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) .type = PORT_S3C2440,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) .fifosize = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) .has_divslot = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) .rx_fifomask = S3C2440_UFSTAT_RXMASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) .rx_fifofull = S3C2440_UFSTAT_RXFULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) .tx_fifofull = S3C2440_UFSTAT_TXFULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) .tx_fifomask = S3C2440_UFSTAT_TXMASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) .def_clk_sel = S3C2410_UCON_CLKSEL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) .num_clks = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) .clksel_mask = S3C2412_UCON_CLKMASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) .clksel_shift = S3C2412_UCON_CLKSHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) .def_cfg = &(struct s3c2410_uartcfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) .ucon = S3C2410_UCON_DEFAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) .ufcon = S3C2410_UFCON_DEFAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) #define S3C2440_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2440_serial_drv_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) #define S3C2440_SERIAL_DRV_DATA (kernel_ulong_t)NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) static struct s3c24xx_serial_drv_data s3c6400_serial_drv_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) .info = &(struct s3c24xx_uart_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) .name = "Samsung S3C6400 UART",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) .type = PORT_S3C6400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) .fifosize = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) .has_divslot = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) .rx_fifomask = S3C2440_UFSTAT_RXMASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) .rx_fifofull = S3C2440_UFSTAT_RXFULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) .tx_fifofull = S3C2440_UFSTAT_TXFULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) .tx_fifomask = S3C2440_UFSTAT_TXMASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) .def_clk_sel = S3C2410_UCON_CLKSEL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) .num_clks = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) .clksel_mask = S3C6400_UCON_CLKMASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) .clksel_shift = S3C6400_UCON_CLKSHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) .def_cfg = &(struct s3c2410_uartcfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) .ucon = S3C2410_UCON_DEFAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) .ufcon = S3C2410_UFCON_DEFAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) #define S3C6400_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c6400_serial_drv_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) #define S3C6400_SERIAL_DRV_DATA (kernel_ulong_t)NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) #ifdef CONFIG_CPU_S5PV210
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) .info = &(struct s3c24xx_uart_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) .name = "Samsung S5PV210 UART",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) .type = PORT_S3C6400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) .has_divslot = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) .rx_fifomask = S5PV210_UFSTAT_RXMASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) .rx_fifofull = S5PV210_UFSTAT_RXFULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) .tx_fifofull = S5PV210_UFSTAT_TXFULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) .tx_fifomask = S5PV210_UFSTAT_TXMASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) .def_clk_sel = S3C2410_UCON_CLKSEL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) .num_clks = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) .clksel_mask = S5PV210_UCON_CLKMASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) .clksel_shift = S5PV210_UCON_CLKSHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) .def_cfg = &(struct s3c2410_uartcfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) .ucon = S5PV210_UCON_DEFAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) .ufcon = S5PV210_UFCON_DEFAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) .fifosize = { 256, 64, 16, 16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) #define S5PV210_SERIAL_DRV_DATA ((kernel_ulong_t)&s5pv210_serial_drv_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) #define S5PV210_SERIAL_DRV_DATA (kernel_ulong_t)NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) #if defined(CONFIG_ARCH_EXYNOS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) #define EXYNOS_COMMON_SERIAL_DRV_DATA \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) .info = &(struct s3c24xx_uart_info) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) .name = "Samsung Exynos UART", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) .type = PORT_S3C6400, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) .has_divslot = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) .rx_fifomask = S5PV210_UFSTAT_RXMASK, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) .rx_fifofull = S5PV210_UFSTAT_RXFULL, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) .tx_fifofull = S5PV210_UFSTAT_TXFULL, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) .tx_fifomask = S5PV210_UFSTAT_TXMASK, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) .def_clk_sel = S3C2410_UCON_CLKSEL0, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) .num_clks = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) .clksel_mask = 0, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) .clksel_shift = 0, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) .def_cfg = &(struct s3c2410_uartcfg) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) .ucon = S5PV210_UCON_DEFAULT, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) .ufcon = S5PV210_UFCON_DEFAULT, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) .has_fracval = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) EXYNOS_COMMON_SERIAL_DRV_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) .fifosize = { 256, 64, 16, 16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) static struct s3c24xx_serial_drv_data exynos5433_serial_drv_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) EXYNOS_COMMON_SERIAL_DRV_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) .fifosize = { 64, 256, 16, 256 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) #define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos4210_serial_drv_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) #define EXYNOS5433_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos5433_serial_drv_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) #define EXYNOS4210_SERIAL_DRV_DATA (kernel_ulong_t)NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) #define EXYNOS5433_SERIAL_DRV_DATA (kernel_ulong_t)NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) static const struct platform_device_id s3c24xx_serial_driver_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) .name = "s3c2410-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) .driver_data = S3C2410_SERIAL_DRV_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) .name = "s3c2412-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) .driver_data = S3C2412_SERIAL_DRV_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) .name = "s3c2440-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) .driver_data = S3C2440_SERIAL_DRV_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) .name = "s3c6400-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) .driver_data = S3C6400_SERIAL_DRV_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) .name = "s5pv210-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) .driver_data = S5PV210_SERIAL_DRV_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) .name = "exynos4210-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) .driver_data = EXYNOS4210_SERIAL_DRV_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) .name = "exynos5433-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) .driver_data = EXYNOS5433_SERIAL_DRV_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) MODULE_DEVICE_TABLE(platform, s3c24xx_serial_driver_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) static const struct of_device_id s3c24xx_uart_dt_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) { .compatible = "samsung,s3c2410-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) .data = (void *)S3C2410_SERIAL_DRV_DATA },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) { .compatible = "samsung,s3c2412-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) .data = (void *)S3C2412_SERIAL_DRV_DATA },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) { .compatible = "samsung,s3c2440-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) .data = (void *)S3C2440_SERIAL_DRV_DATA },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) { .compatible = "samsung,s3c6400-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) .data = (void *)S3C6400_SERIAL_DRV_DATA },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) { .compatible = "samsung,s5pv210-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) .data = (void *)S5PV210_SERIAL_DRV_DATA },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) { .compatible = "samsung,exynos4210-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) .data = (void *)EXYNOS4210_SERIAL_DRV_DATA },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) { .compatible = "samsung,exynos5433-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) .data = (void *)EXYNOS5433_SERIAL_DRV_DATA },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) static struct platform_driver samsung_serial_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) .probe = s3c24xx_serial_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) .remove = s3c24xx_serial_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) .id_table = s3c24xx_serial_driver_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) .name = "samsung-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) .pm = SERIAL_SAMSUNG_PM_OPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) .of_match_table = of_match_ptr(s3c24xx_uart_dt_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) module_platform_driver(samsung_serial_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) #ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) * Early console.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) static void wr_reg_barrier(struct uart_port *port, u32 reg, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) switch (port->iotype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) case UPIO_MEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) writeb(val, portaddr(port, reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) case UPIO_MEM32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) writel(val, portaddr(port, reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) struct samsung_early_console_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) u32 txfull_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) static void samsung_early_busyuart(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) while (!(readl(port->membase + S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXFE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) static void samsung_early_busyuart_fifo(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) struct samsung_early_console_data *data = port->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) while (readl(port->membase + S3C2410_UFSTAT) & data->txfull_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) static void samsung_early_putc(struct uart_port *port, int c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) if (readl(port->membase + S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) samsung_early_busyuart_fifo(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) samsung_early_busyuart(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) wr_reg_barrier(port, S3C2410_UTXH, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) static void samsung_early_write(struct console *con, const char *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) unsigned int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) struct earlycon_device *dev = con->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) uart_console_write(&dev->port, s, n, samsung_early_putc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) static int __init samsung_early_console_setup(struct earlycon_device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) const char *opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) if (!device->port.membase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) device->con->write = samsung_early_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) /* S3C2410 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) static struct samsung_early_console_data s3c2410_early_console_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) .txfull_mask = S3C2410_UFSTAT_TXFULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) static int __init s3c2410_early_console_setup(struct earlycon_device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) const char *opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) device->port.private_data = &s3c2410_early_console_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) return samsung_early_console_setup(device, opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) OF_EARLYCON_DECLARE(s3c2410, "samsung,s3c2410-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) s3c2410_early_console_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) /* S3C2412, S3C2440, S3C64xx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) static struct samsung_early_console_data s3c2440_early_console_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) .txfull_mask = S3C2440_UFSTAT_TXFULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) static int __init s3c2440_early_console_setup(struct earlycon_device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) const char *opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) device->port.private_data = &s3c2440_early_console_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) return samsung_early_console_setup(device, opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) OF_EARLYCON_DECLARE(s3c2412, "samsung,s3c2412-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) s3c2440_early_console_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) OF_EARLYCON_DECLARE(s3c2440, "samsung,s3c2440-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) s3c2440_early_console_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) OF_EARLYCON_DECLARE(s3c6400, "samsung,s3c6400-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) s3c2440_early_console_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) /* S5PV210, Exynos */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) static struct samsung_early_console_data s5pv210_early_console_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) .txfull_mask = S5PV210_UFSTAT_TXFULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) static int __init s5pv210_early_console_setup(struct earlycon_device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) const char *opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) device->port.private_data = &s5pv210_early_console_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) return samsung_early_console_setup(device, opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) OF_EARLYCON_DECLARE(s5pv210, "samsung,s5pv210-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) s5pv210_early_console_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) OF_EARLYCON_DECLARE(exynos4210, "samsung,exynos4210-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) s5pv210_early_console_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) MODULE_ALIAS("platform:samsung-uart");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) MODULE_DESCRIPTION("Samsung SoC Serial port driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) MODULE_LICENSE("GPL v2");