Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 354792
b: refs/heads/master
c: 30046df
h: refs/heads/master
v: v3
  • Loading branch information
Heikki Krogerus authored and Greg Kroah-Hartman committed Jan 16, 2013
1 parent 40d6ad8 commit e53e45d
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a7260c8ce07d06da4cbb09120b4e9e8074d122cc
refs/heads/master: 30046df261875dfeaf92b44fe5cd6cde9716a561
57 changes: 53 additions & 4 deletions trunk/drivers/tty/serial/8250/8250_dw.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,28 @@
#include <linux/platform_device.h>
#include <linux/slab.h>

/* Offsets for the DesignWare specific registers */
#define DW_UART_USR 0x1f /* UART Status Register */
#define DW_UART_CPR 0xf4 /* Component Parameter Register */
#define DW_UART_UCV 0xf8 /* UART Component Version */

/* Component Parameter Register bits */
#define DW_UART_CPR_ABP_DATA_WIDTH (3 << 0)
#define DW_UART_CPR_AFCE_MODE (1 << 4)
#define DW_UART_CPR_THRE_MODE (1 << 5)
#define DW_UART_CPR_SIR_MODE (1 << 6)
#define DW_UART_CPR_SIR_LP_MODE (1 << 7)
#define DW_UART_CPR_ADDITIONAL_FEATURES (1 << 8)
#define DW_UART_CPR_FIFO_ACCESS (1 << 9)
#define DW_UART_CPR_FIFO_STAT (1 << 10)
#define DW_UART_CPR_SHADOW (1 << 11)
#define DW_UART_CPR_ENCODED_PARMS (1 << 12)
#define DW_UART_CPR_DMA_EXTRA (1 << 13)
#define DW_UART_CPR_FIFO_MODE (0xff << 16)
/* Helper for fifo size calculation */
#define DW_UART_CPR_FIFO_SIZE(a) (((a >> 16) & 0xff) * 16)


struct dw8250_data {
int last_lcr;
int line;
Expand Down Expand Up @@ -66,9 +88,6 @@ static unsigned int dw8250_serial_in32(struct uart_port *p, int offset)
return readl(p->membase + offset);
}

/* Offset for the DesignWare's UART Status Register. */
#define UART_USR 0x1f

static int dw8250_handle_irq(struct uart_port *p)
{
struct dw8250_data *d = p->private_data;
Expand All @@ -78,7 +97,7 @@ static int dw8250_handle_irq(struct uart_port *p)
return 1;
} else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
/* Clear the USR and write the LCR again. */
(void)p->serial_in(p, UART_USR);
(void)p->serial_in(p, DW_UART_USR);
p->serial_out(p, d->last_lcr, UART_LCR);

return 1;
Expand Down Expand Up @@ -119,6 +138,34 @@ static int dw8250_probe_of(struct uart_port *p)
return 0;
}

static void dw8250_setup_port(struct uart_8250_port *up)
{
struct uart_port *p = &up->port;
u32 reg = readl(p->membase + DW_UART_UCV);

/*
* If the Component Version Register returns zero, we know that
* ADDITIONAL_FEATURES are not enabled. No need to go any further.
*/
if (!reg)
return;

dev_dbg_ratelimited(p->dev, "Designware UART version %c.%c%c\n",
(reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff);

reg = readl(p->membase + DW_UART_CPR);
if (!reg)
return;

/* Select the type based on fifo */
if (reg & DW_UART_CPR_FIFO_MODE) {
p->type = PORT_16550A;
p->flags |= UPF_FIXED_TYPE;
p->fifosize = DW_UART_CPR_FIFO_SIZE(reg);
up->tx_loadsz = p->fifosize;
}
}

static int dw8250_probe(struct platform_device *pdev)
{
struct uart_8250_port uart = {};
Expand Down Expand Up @@ -156,6 +203,8 @@ static int dw8250_probe(struct platform_device *pdev)
return -ENODEV;
}

dw8250_setup_port(&uart);

data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
Expand Down

0 comments on commit e53e45d

Please sign in to comment.