From 3f7e5e2423f6233f7665d54061ba7761ca90cf52 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 13 Jul 2011 07:59:48 +0000 Subject: clocksource: sh_cmt: wait for CMCNT on init V2 Add code to the CMT driver to wait for CMCNT V2. This to let the register value settle before starting the timer channel. Makes the driver more robust. Needed for CMT2 on sh7372 and certain CMT channels on sh73a0. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/clocksource/sh_cmt.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index dc7c033ef58..32a77becc09 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -150,13 +151,13 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start) static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate) { - int ret; + int k, ret; /* enable clock */ ret = clk_enable(p->clk); if (ret) { dev_err(&p->pdev->dev, "cannot enable clock\n"); - return ret; + goto err0; } /* make sure channel is disabled */ @@ -174,9 +175,38 @@ static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate) sh_cmt_write(p, CMCOR, 0xffffffff); sh_cmt_write(p, CMCNT, 0); + /* + * According to the sh73a0 user's manual, as CMCNT can be operated + * only by the RCLK (Pseudo 32 KHz), there's one restriction on + * modifying CMCNT register; two RCLK cycles are necessary before + * this register is either read or any modification of the value + * it holds is reflected in the LSI's actual operation. + * + * While at it, we're supposed to clear out the CMCNT as of this + * moment, so make sure it's processed properly here. This will + * take RCLKx2 at maximum. + */ + for (k = 0; k < 100; k++) { + if (!sh_cmt_read(p, CMCNT)) + break; + udelay(1); + } + + if (sh_cmt_read(p, CMCNT)) { + dev_err(&p->pdev->dev, "cannot clear CMCNT\n"); + ret = -ETIMEDOUT; + goto err1; + } + /* enable channel */ sh_cmt_start_stop_ch(p, 1); return 0; + err1: + /* stop clock */ + clk_disable(p->clk); + + err0: + return ret; } static void sh_cmt_disable(struct sh_cmt_priv *p) -- cgit v1.2.3-70-g09d2 From b4300b72cfc01ea75b8aaede574bdfb04545d691 Mon Sep 17 00:00:00 2001 From: David Engraf Date: Wed, 20 Jul 2011 13:03:39 +0000 Subject: shwdt: fix usage of mod_timer This patch fixes the usage of mod_timer and makes the driver usable. mod_timer must be called with an absolute timeout in jiffies, the old implementation used a relative timeout thus the hardware watchdog was never triggered. Signed-off-by: David Engraf Signed-off-by: Paul Mundt --- drivers/watchdog/shwdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index db84f2322d1..a267dc078da 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c @@ -64,7 +64,7 @@ * misses its deadline, the kernel timer will allow the WDT to overflow. */ static int clock_division_ratio = WTCSR_CKS_4096; -#define next_ping_period(cks) msecs_to_jiffies(cks - 4) +#define next_ping_period(cks) (jiffies + msecs_to_jiffies(cks - 4)) static const struct watchdog_info sh_wdt_info; static struct platform_device *sh_wdt_dev; -- cgit v1.2.3-70-g09d2 From 9a14a92c939aea1aaf27f5ad37b26b235acc2a65 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 15 Jul 2011 10:58:55 +0000 Subject: sh: intc: enable both edges GPIO interrupts on sh7372 IRQ-capable GPIOs on sh7372 can be configured to produce interrupts on both edges. Signed-off-by: Guennadi Liakhovetski Acked-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/sh/intc/chip.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/sh/intc/chip.c b/drivers/sh/intc/chip.c index f33e2dd9793..33b2ed451e0 100644 --- a/drivers/sh/intc/chip.c +++ b/drivers/sh/intc/chip.c @@ -186,6 +186,9 @@ static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = { !defined(CONFIG_CPU_SUBTYPE_SH7709) [IRQ_TYPE_LEVEL_HIGH] = VALID(3), #endif +#if defined(CONFIG_ARCH_SH7372) + [IRQ_TYPE_EDGE_BOTH] = VALID(4), +#endif }; static int intc_set_type(struct irq_data *data, unsigned int type) -- cgit v1.2.3-70-g09d2 From ad75b88ac3792ae6a541d9b9fa84e379bd0b29dd Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 3 Aug 2011 12:33:20 +0900 Subject: serial: sh-sci: Fix up default regtype probing. Presently the default regtype probing inadvertently bails out due to an inverted error check. This fixes it up, and gets platforms without explicit regtype specifications working again. Reported-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/tty/serial/sh-sci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index d0a56235c50..522f69d3c8a 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1889,7 +1889,7 @@ static int __devinit sci_init_single(struct platform_device *dev, if (p->regtype == SCIx_PROBE_REGTYPE) { ret = sci_probe_regmap(p); - if (unlikely(!ret)) + if (unlikely(ret != 0)) return ret; } -- cgit v1.2.3-70-g09d2 From 5beabc7fcd99856084e232b37d3280ce353eaf41 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 2 Aug 2011 09:42:54 +0000 Subject: serial: sh-sci: fix DMA build by including dma-mapping.h Include dma-mapping.h to fix build of the sh-sci driver on SH-Mobile ARM (sh73a0) when CONFIG_SERIAL_SH_SCI_DMA=y: drivers/tty/serial/sh-sci.c: In function 'sci_rx_dma_release': drivers/tty/serial/sh-sci.c:1182:3: error: implicit declaration of function 'dma_free_coherent' drivers/tty/serial/sh-sci.c: In function 'work_fn_tx': drivers/tty/serial/sh-sci.c:1333:2: error: implicit declaration of function 'dma_sync_sg_for_device' drivers/tty/serial/sh-sci.c: In function 'sci_request_dma': drivers/tty/serial/sh-sci.c:1498:3: error: implicit declaration of function 'dma_map_sg' drivers/tty/serial/sh-sci.c:1527:3: error: implicit declaration of function 'dma_alloc_coherent' drivers/tty/serial/sh-sci.c:1527:10: warning: assignment makes pointer from integer without a cast make[3]: *** [drivers/tty/serial/sh-sci.o] Error 1 make[2]: *** [drivers/tty/serial] Error 2 make[1]: *** [drivers/tty] Error 2 make: *** [drivers] Error 2 Signed-off-by: Magnus Damm Tested-by: Simon Horman Signed-off-by: Paul Mundt --- drivers/tty/serial/sh-sci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 522f69d3c8a..38a81ae9b7d 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3-70-g09d2 From 1ba762209491e2496e58baffa3fd65d661f54404 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 3 Aug 2011 03:47:36 +0000 Subject: serial: sh-sci: console Runtime PM support Add Runtime PM context save/restore support to the SCIF driver. Tested on the AP4EVB console. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/tty/serial/sh-sci.c | 68 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 38a81ae9b7d..ffcaceee021 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -96,6 +96,12 @@ struct sci_port { #endif struct notifier_block freq_transition; + +#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE + unsigned short saved_smr; + unsigned short saved_fcr; + unsigned char saved_brr; +#endif }; /* Function prototypes */ @@ -1634,11 +1640,25 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, return ((freq + 16 * bps) / (32 * bps) - 1); } +static void sci_reset(struct uart_port *port) +{ + unsigned int status; + + do { + status = sci_in(port, SCxSR); + } while (!(status & SCxSR_TEND(port))); + + sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ + + if (port->type != PORT_SCI) + sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST); +} + static void sci_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct sci_port *s = to_sci_port(port); - unsigned int status, baud, smr_val, max_baud; + unsigned int baud, smr_val, max_baud; int t = -1; u16 scfcr = 0; @@ -1658,14 +1678,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, sci_port_enable(s); - do { - status = sci_in(port, SCxSR); - } while (!(status & SCxSR_TEND(port))); - - sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ - - if (port->type != PORT_SCI) - sci_out(port, SCFCR, scfcr | SCFCR_RFRST | SCFCR_TFRST); + sci_reset(port); smr_val = sci_in(port, SCSMR) & 3; @@ -2037,7 +2050,8 @@ static int __devinit serial_console_setup(struct console *co, char *options) if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); - /* TODO: disable clock */ + sci_port_disable(sci_port); + return uart_set_options(port, co, baud, parity, bits, flow); } @@ -2080,6 +2094,36 @@ static int __devinit sci_probe_earlyprintk(struct platform_device *pdev) return 0; } +#define uart_console(port) ((port)->cons->index == (port)->line) + +static int sci_runtime_suspend(struct device *dev) +{ + struct sci_port *sci_port = dev_get_drvdata(dev); + struct uart_port *port = &sci_port->port; + + if (uart_console(port)) { + sci_port->saved_smr = sci_in(port, SCSMR); + sci_port->saved_brr = sci_in(port, SCBRR); + sci_port->saved_fcr = sci_in(port, SCFCR); + } + return 0; +} + +static int sci_runtime_resume(struct device *dev) +{ + struct sci_port *sci_port = dev_get_drvdata(dev); + struct uart_port *port = &sci_port->port; + + if (uart_console(port)) { + sci_reset(port); + sci_out(port, SCSMR, sci_port->saved_smr); + sci_out(port, SCBRR, sci_port->saved_brr); + sci_out(port, SCFCR, sci_port->saved_fcr); + sci_out(port, SCSCR, sci_port->cfg->scscr); + } + return 0; +} + #define SCI_CONSOLE (&serial_console) #else @@ -2089,6 +2133,8 @@ static inline int __devinit sci_probe_earlyprintk(struct platform_device *pdev) } #define SCI_CONSOLE NULL +#define sci_runtime_suspend NULL +#define sci_runtime_resume NULL #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ @@ -2204,6 +2250,8 @@ static int sci_resume(struct device *dev) } static const struct dev_pm_ops sci_dev_pm_ops = { + .runtime_suspend = sci_runtime_suspend, + .runtime_resume = sci_runtime_resume, .suspend = sci_suspend, .resume = sci_resume, }; -- cgit v1.2.3-70-g09d2 From 4480a688b2beaa82ecac269b6e21bf1a26251bf9 Mon Sep 17 00:00:00 2001 From: Yoshii Takashi Date: Tue, 23 Aug 2011 08:27:18 +0000 Subject: serial: sh-sci: report CTS as active for get_mctrl sh-sci.c sets hardware up and then let the HW do all flow controls. There is no software code, nor needs to get/set real CTS signal. But, when turning CRTSCTS on through termios, uart_set_termios() in serial_core.c checks CTS, and stops TX if it is inactive at the moment. Because sci_get_mctrl() returns a fixed value DTR|RTS|DSR but CTS, the sequence open -> set CRTSCTS -> write hit the case and stop working, no more outputs. This patch makes sci_get_mctrl() report CTS in addition. Signed-off-by: Takashi YOSHII Signed-off-by: Paul Mundt --- drivers/tty/serial/sh-sci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 18e6342af07..161e7001070 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1083,7 +1083,7 @@ static unsigned int sci_get_mctrl(struct uart_port *port) /* This routine is used for getting signals of: DTR, DCD, DSR, RI, and CTS/RTS */ - return TIOCM_DTR | TIOCM_RTS | TIOCM_DSR; + return TIOCM_DTR | TIOCM_RTS | TIOCM_CTS | TIOCM_DSR; } #ifdef CONFIG_SERIAL_SH_SCI_DMA -- cgit v1.2.3-70-g09d2