Skip to content

Commit 8f9eeb5

Browse files
Wenhua Lingregkh
authored andcommitted
serial: sprd: Add support for sc9632
Due to the platform's new project uart ip upgrade, the new project's timeout interrupt needs to use bit17 while other projects' timeout interrupt needs to use bit13, using private data to adapt and be compatible with all projects. Signed-off-by: Wenhua Lin <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent b3a882e commit 8f9eeb5

File tree

1 file changed

+36
-5
lines changed

1 file changed

+36
-5
lines changed

drivers/tty/serial/sprd_serial.c

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,12 @@
5353
#define SPRD_IEN_TX_EMPTY BIT(1)
5454
#define SPRD_IEN_BREAK_DETECT BIT(7)
5555
#define SPRD_IEN_TIMEOUT BIT(13)
56+
#define SPRD_IEN_DATA_TIMEOUT BIT(17)
5657

5758
/* interrupt clear register */
5859
#define SPRD_ICLR 0x0014
5960
#define SPRD_ICLR_TIMEOUT BIT(13)
61+
#define SPRD_ICLR_DATA_TIMEOUT BIT(17)
6062

6163
/* line control register */
6264
#define SPRD_LCR 0x0018
@@ -102,6 +104,7 @@
102104
#define SPRD_IMSR_TX_FIFO_EMPTY BIT(1)
103105
#define SPRD_IMSR_BREAK_DETECT BIT(7)
104106
#define SPRD_IMSR_TIMEOUT BIT(13)
107+
#define SPRD_IMSR_DATA_TIMEOUT BIT(17)
105108
#define SPRD_DEFAULT_SOURCE_CLK 26000000
106109

107110
#define SPRD_RX_DMA_STEP 1
@@ -118,6 +121,12 @@ struct sprd_uart_dma {
118121
bool enable;
119122
};
120123

124+
struct sprd_uart_data {
125+
unsigned int timeout_ien;
126+
unsigned int timeout_iclr;
127+
unsigned int timeout_imsr;
128+
};
129+
121130
struct sprd_uart_port {
122131
struct uart_port port;
123132
char name[16];
@@ -126,6 +135,7 @@ struct sprd_uart_port {
126135
struct sprd_uart_dma rx_dma;
127136
dma_addr_t pos;
128137
unsigned char *rx_buf_tail;
138+
const struct sprd_uart_data *pdata;
129139
};
130140

131141
static struct sprd_uart_port *sprd_port[UART_NR_MAX];
@@ -134,6 +144,18 @@ static int sprd_ports_num;
134144
static int sprd_start_dma_rx(struct uart_port *port);
135145
static int sprd_tx_dma_config(struct uart_port *port);
136146

147+
static const struct sprd_uart_data sc9836_data = {
148+
.timeout_ien = SPRD_IEN_TIMEOUT,
149+
.timeout_iclr = SPRD_ICLR_TIMEOUT,
150+
.timeout_imsr = SPRD_IMSR_TIMEOUT,
151+
};
152+
153+
static const struct sprd_uart_data sc9632_data = {
154+
.timeout_ien = SPRD_IEN_DATA_TIMEOUT,
155+
.timeout_iclr = SPRD_ICLR_DATA_TIMEOUT,
156+
.timeout_imsr = SPRD_IMSR_DATA_TIMEOUT,
157+
};
158+
137159
static inline unsigned int serial_in(struct uart_port *port,
138160
unsigned int offset)
139161
{
@@ -637,6 +659,8 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id)
637659
{
638660
struct uart_port *port = dev_id;
639661
unsigned int ims;
662+
struct sprd_uart_port *sp =
663+
container_of(port, struct sprd_uart_port, port);
640664

641665
uart_port_lock(port);
642666

@@ -647,14 +671,14 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id)
647671
return IRQ_NONE;
648672
}
649673

650-
if (ims & SPRD_IMSR_TIMEOUT)
651-
serial_out(port, SPRD_ICLR, SPRD_ICLR_TIMEOUT);
674+
if (ims & sp->pdata->timeout_imsr)
675+
serial_out(port, SPRD_ICLR, sp->pdata->timeout_iclr);
652676

653677
if (ims & SPRD_IMSR_BREAK_DETECT)
654678
serial_out(port, SPRD_ICLR, SPRD_IMSR_BREAK_DETECT);
655679

656680
if (ims & (SPRD_IMSR_RX_FIFO_FULL | SPRD_IMSR_BREAK_DETECT |
657-
SPRD_IMSR_TIMEOUT))
681+
sp->pdata->timeout_imsr))
658682
sprd_rx(port);
659683

660684
if (ims & SPRD_IMSR_TX_FIFO_EMPTY)
@@ -729,7 +753,7 @@ static int sprd_startup(struct uart_port *port)
729753
/* enable interrupt */
730754
uart_port_lock_irqsave(port, &flags);
731755
ien = serial_in(port, SPRD_IEN);
732-
ien |= SPRD_IEN_BREAK_DETECT | SPRD_IEN_TIMEOUT;
756+
ien |= SPRD_IEN_BREAK_DETECT | sp->pdata->timeout_ien;
733757
if (!sp->rx_dma.enable)
734758
ien |= SPRD_IEN_RX_FULL;
735759
serial_out(port, SPRD_IEN, ien);
@@ -1184,6 +1208,12 @@ static int sprd_probe(struct platform_device *pdev)
11841208

11851209
up->mapbase = res->start;
11861210

1211+
sport->pdata = of_device_get_match_data(&pdev->dev);
1212+
if (!sport->pdata) {
1213+
dev_err(&pdev->dev, "get match data failed!\n");
1214+
return -EINVAL;
1215+
}
1216+
11871217
irq = platform_get_irq(pdev, 0);
11881218
if (irq < 0)
11891219
return irq;
@@ -1248,7 +1278,8 @@ static int sprd_resume(struct device *dev)
12481278
static SIMPLE_DEV_PM_OPS(sprd_pm_ops, sprd_suspend, sprd_resume);
12491279

12501280
static const struct of_device_id serial_ids[] = {
1251-
{.compatible = "sprd,sc9836-uart",},
1281+
{.compatible = "sprd,sc9836-uart", .data = &sc9836_data},
1282+
{.compatible = "sprd,sc9632-uart", .data = &sc9632_data},
12521283
{}
12531284
};
12541285
MODULE_DEVICE_TABLE(of, serial_ids);

0 commit comments

Comments
 (0)