|
@@ -152,6 +152,7 @@ struct sci_port {
|
|
int rx_trigger;
|
|
int rx_trigger;
|
|
struct timer_list rx_fifo_timer;
|
|
struct timer_list rx_fifo_timer;
|
|
int rx_fifo_timeout;
|
|
int rx_fifo_timeout;
|
|
|
|
+ u16 hscif_tot;
|
|
|
|
|
|
bool has_rtscts;
|
|
bool has_rtscts;
|
|
bool autorts;
|
|
bool autorts;
|
|
@@ -1107,8 +1108,14 @@ static ssize_t rx_fifo_timeout_show(struct device *dev,
|
|
{
|
|
{
|
|
struct uart_port *port = dev_get_drvdata(dev);
|
|
struct uart_port *port = dev_get_drvdata(dev);
|
|
struct sci_port *sci = to_sci_port(port);
|
|
struct sci_port *sci = to_sci_port(port);
|
|
|
|
+ int v;
|
|
|
|
|
|
- return sprintf(buf, "%d\n", sci->rx_fifo_timeout);
|
|
|
|
|
|
+ if (port->type == PORT_HSCIF)
|
|
|
|
+ v = sci->hscif_tot >> HSSCR_TOT_SHIFT;
|
|
|
|
+ else
|
|
|
|
+ v = sci->rx_fifo_timeout;
|
|
|
|
+
|
|
|
|
+ return sprintf(buf, "%d\n", v);
|
|
}
|
|
}
|
|
|
|
|
|
static ssize_t rx_fifo_timeout_store(struct device *dev,
|
|
static ssize_t rx_fifo_timeout_store(struct device *dev,
|
|
@@ -1124,11 +1131,19 @@ static ssize_t rx_fifo_timeout_store(struct device *dev,
|
|
ret = kstrtol(buf, 0, &r);
|
|
ret = kstrtol(buf, 0, &r);
|
|
if (ret)
|
|
if (ret)
|
|
return ret;
|
|
return ret;
|
|
- sci->rx_fifo_timeout = r;
|
|
|
|
- scif_set_rtrg(port, 1);
|
|
|
|
- if (r > 0)
|
|
|
|
- setup_timer(&sci->rx_fifo_timer, rx_fifo_timer_fn,
|
|
|
|
- (unsigned long)sci);
|
|
|
|
|
|
+
|
|
|
|
+ if (port->type == PORT_HSCIF) {
|
|
|
|
+ if (r < 0 || r > 3)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ sci->hscif_tot = r << HSSCR_TOT_SHIFT;
|
|
|
|
+ } else {
|
|
|
|
+ sci->rx_fifo_timeout = r;
|
|
|
|
+ scif_set_rtrg(port, 1);
|
|
|
|
+ if (r > 0)
|
|
|
|
+ setup_timer(&sci->rx_fifo_timer, rx_fifo_timer_fn,
|
|
|
|
+ (unsigned long)sci);
|
|
|
|
+ }
|
|
|
|
+
|
|
return count;
|
|
return count;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2037,9 +2052,13 @@ static void sci_shutdown(struct uart_port *port)
|
|
spin_lock_irqsave(&port->lock, flags);
|
|
spin_lock_irqsave(&port->lock, flags);
|
|
sci_stop_rx(port);
|
|
sci_stop_rx(port);
|
|
sci_stop_tx(port);
|
|
sci_stop_tx(port);
|
|
- /* Stop RX and TX, disable related interrupts, keep clock source */
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Stop RX and TX, disable related interrupts, keep clock source
|
|
|
|
+ * and HSCIF TOT bits
|
|
|
|
+ */
|
|
scr = serial_port_in(port, SCSCR);
|
|
scr = serial_port_in(port, SCSCR);
|
|
- serial_port_out(port, SCSCR, scr & (SCSCR_CKE1 | SCSCR_CKE0));
|
|
|
|
|
|
+ serial_port_out(port, SCSCR, scr &
|
|
|
|
+ (SCSCR_CKE1 | SCSCR_CKE0 | s->hscif_tot));
|
|
spin_unlock_irqrestore(&port->lock, flags);
|
|
spin_unlock_irqrestore(&port->lock, flags);
|
|
|
|
|
|
#ifdef CONFIG_SERIAL_SH_SCI_DMA
|
|
#ifdef CONFIG_SERIAL_SH_SCI_DMA
|
|
@@ -2186,7 +2205,7 @@ static void sci_reset(struct uart_port *port)
|
|
unsigned int status;
|
|
unsigned int status;
|
|
struct sci_port *s = to_sci_port(port);
|
|
struct sci_port *s = to_sci_port(port);
|
|
|
|
|
|
- serial_port_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */
|
|
|
|
|
|
+ serial_port_out(port, SCSCR, s->hscif_tot); /* TE=0, RE=0, CKE1=0 */
|
|
|
|
|
|
reg = sci_getreg(port, SCFCR);
|
|
reg = sci_getreg(port, SCFCR);
|
|
if (reg->size)
|
|
if (reg->size)
|
|
@@ -2356,7 +2375,7 @@ done:
|
|
dev_dbg(port->dev,
|
|
dev_dbg(port->dev,
|
|
"SCR 0x%x SMR 0x%x BRR %u CKS 0x%x DL %u SRR %u\n",
|
|
"SCR 0x%x SMR 0x%x BRR %u CKS 0x%x DL %u SRR %u\n",
|
|
scr_val, smr_val, brr, sccks, dl, srr);
|
|
scr_val, smr_val, brr, sccks, dl, srr);
|
|
- serial_port_out(port, SCSCR, scr_val);
|
|
|
|
|
|
+ serial_port_out(port, SCSCR, scr_val | s->hscif_tot);
|
|
serial_port_out(port, SCSMR, smr_val);
|
|
serial_port_out(port, SCSMR, smr_val);
|
|
serial_port_out(port, SCBRR, brr);
|
|
serial_port_out(port, SCBRR, brr);
|
|
if (sci_getreg(port, HSSRR)->size)
|
|
if (sci_getreg(port, HSSRR)->size)
|
|
@@ -2370,7 +2389,7 @@ done:
|
|
smr_val |= serial_port_in(port, SCSMR) &
|
|
smr_val |= serial_port_in(port, SCSMR) &
|
|
(SCSMR_CKEDG | SCSMR_SRC_MASK | SCSMR_CKS);
|
|
(SCSMR_CKEDG | SCSMR_SRC_MASK | SCSMR_CKS);
|
|
dev_dbg(port->dev, "SCR 0x%x SMR 0x%x\n", scr_val, smr_val);
|
|
dev_dbg(port->dev, "SCR 0x%x SMR 0x%x\n", scr_val, smr_val);
|
|
- serial_port_out(port, SCSCR, scr_val);
|
|
|
|
|
|
+ serial_port_out(port, SCSCR, scr_val | s->hscif_tot);
|
|
serial_port_out(port, SCSMR, smr_val);
|
|
serial_port_out(port, SCSMR, smr_val);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2407,7 +2426,7 @@ done:
|
|
scr_val |= SCSCR_RE | SCSCR_TE |
|
|
scr_val |= SCSCR_RE | SCSCR_TE |
|
|
(s->cfg->scscr & ~(SCSCR_CKE1 | SCSCR_CKE0));
|
|
(s->cfg->scscr & ~(SCSCR_CKE1 | SCSCR_CKE0));
|
|
dev_dbg(port->dev, "SCSCR 0x%x\n", scr_val);
|
|
dev_dbg(port->dev, "SCSCR 0x%x\n", scr_val);
|
|
- serial_port_out(port, SCSCR, scr_val);
|
|
|
|
|
|
+ serial_port_out(port, SCSCR, scr_val | s->hscif_tot);
|
|
if ((srr + 1 == 5) &&
|
|
if ((srr + 1 == 5) &&
|
|
(port->type == PORT_SCIFA || port->type == PORT_SCIFB)) {
|
|
(port->type == PORT_SCIFA || port->type == PORT_SCIFB)) {
|
|
/*
|
|
/*
|
|
@@ -2773,6 +2792,7 @@ static int sci_init_single(struct platform_device *dev,
|
|
}
|
|
}
|
|
|
|
|
|
sci_port->rx_fifo_timeout = 0;
|
|
sci_port->rx_fifo_timeout = 0;
|
|
|
|
+ sci_port->hscif_tot = 0;
|
|
|
|
|
|
/* SCIFA on sh7723 and sh7724 need a custom sampling rate that doesn't
|
|
/* SCIFA on sh7723 and sh7724 need a custom sampling rate that doesn't
|
|
* match the SoC datasheet, this should be investigated. Let platform
|
|
* match the SoC datasheet, this should be investigated. Let platform
|
|
@@ -2860,7 +2880,7 @@ static void serial_console_write(struct console *co, const char *s,
|
|
ctrl_temp = SCSCR_RE | SCSCR_TE |
|
|
ctrl_temp = SCSCR_RE | SCSCR_TE |
|
|
(sci_port->cfg->scscr & ~(SCSCR_CKE1 | SCSCR_CKE0)) |
|
|
(sci_port->cfg->scscr & ~(SCSCR_CKE1 | SCSCR_CKE0)) |
|
|
(ctrl & (SCSCR_CKE1 | SCSCR_CKE0));
|
|
(ctrl & (SCSCR_CKE1 | SCSCR_CKE0));
|
|
- serial_port_out(port, SCSCR, ctrl_temp);
|
|
|
|
|
|
+ serial_port_out(port, SCSCR, ctrl_temp | sci_port->hscif_tot);
|
|
|
|
|
|
uart_console_write(port, s, count, serial_console_putchar);
|
|
uart_console_write(port, s, count, serial_console_putchar);
|
|
|
|
|
|
@@ -2988,7 +3008,8 @@ static int sci_remove(struct platform_device *dev)
|
|
sysfs_remove_file(&dev->dev.kobj,
|
|
sysfs_remove_file(&dev->dev.kobj,
|
|
&dev_attr_rx_fifo_trigger.attr);
|
|
&dev_attr_rx_fifo_trigger.attr);
|
|
}
|
|
}
|
|
- if (port->port.type == PORT_SCIFA || port->port.type == PORT_SCIFB) {
|
|
|
|
|
|
+ if (port->port.type == PORT_SCIFA || port->port.type == PORT_SCIFB ||
|
|
|
|
+ port->port.type == PORT_HSCIF) {
|
|
sysfs_remove_file(&dev->dev.kobj,
|
|
sysfs_remove_file(&dev->dev.kobj,
|
|
&dev_attr_rx_fifo_timeout.attr);
|
|
&dev_attr_rx_fifo_timeout.attr);
|
|
}
|
|
}
|
|
@@ -3173,7 +3194,8 @@ static int sci_probe(struct platform_device *dev)
|
|
if (ret)
|
|
if (ret)
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
- if (sp->port.type == PORT_SCIFA || sp->port.type == PORT_SCIFB) {
|
|
|
|
|
|
+ if (sp->port.type == PORT_SCIFA || sp->port.type == PORT_SCIFB ||
|
|
|
|
+ sp->port.type == PORT_HSCIF) {
|
|
ret = sysfs_create_file(&dev->dev.kobj,
|
|
ret = sysfs_create_file(&dev->dev.kobj,
|
|
&dev_attr_rx_fifo_timeout.attr);
|
|
&dev_attr_rx_fifo_timeout.attr);
|
|
if (ret) {
|
|
if (ret) {
|