All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

Commit c42a2634 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'sh-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-3.x

* 'sh-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-3.x:
  sh: fix the compile error in setup-sh7757.c
  serial: sh-sci: report CTS as active for get_mctrl
  sh: Add unaligned memory access for PC relative intructions
  sh: Fix unaligned memory access for branches without delay slots
  sh: Fix up fallout from cpuidle changes.
  serial: sh-sci: console Runtime PM support
  sh: Fix conflicting definitions of ptrace_triggered
  serial: sh-sci: fix DMA build by including dma-mapping.h
  serial: sh-sci: Fix up default regtype probing.
  sh: intc: enable both edges GPIO interrupts on sh7372
  shwdt: fix usage of mod_timer
  clocksource: sh_cmt: wait for CMCNT on init V2
parents f9557a44 21d41f2b
......@@ -123,7 +123,7 @@ static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
struct perf_event;
struct perf_sample_data;
extern void ptrace_triggered(struct perf_event *bp, int nmi,
extern void ptrace_triggered(struct perf_event *bp,
struct perf_sample_data *data, struct pt_regs *regs);
#define task_pt_regs(task) \
......
......@@ -15,6 +15,7 @@
#include <linux/serial_sci.h>
#include <linux/io.h>
#include <linux/mm.h>
#include <linux/dma-mapping.h>
#include <linux/sh_timer.h>
#include <linux/sh_dma.h>
......
......@@ -22,7 +22,7 @@
#include <linux/atomic.h>
#include <asm/smp.h>
static void (*pm_idle)(void);
void (*pm_idle)(void);
static int hlt_counter;
......
......@@ -316,6 +316,35 @@ static int handle_unaligned_ins(insn_size_t instruction, struct pt_regs *regs,
break;
}
break;
case 9: /* mov.w @(disp,PC),Rn */
srcu = (unsigned char __user *)regs->pc;
srcu += 4;
srcu += (instruction & 0x00FF) << 1;
dst = (unsigned char *)rn;
*(unsigned long *)dst = 0;
#if !defined(__LITTLE_ENDIAN__)
dst += 2;
#endif
if (ma->from(dst, srcu, 2))
goto fetch_fault;
sign_extend(2, dst);
ret = 0;
break;
case 0xd: /* mov.l @(disp,PC),Rn */
srcu = (unsigned char __user *)(regs->pc & ~0x3);
srcu += 4;
srcu += (instruction & 0x00FF) << 2;
dst = (unsigned char *)rn;
*(unsigned long *)dst = 0;
if (ma->from(dst, srcu, 4))
goto fetch_fault;
ret = 0;
break;
}
return ret;
......@@ -466,6 +495,7 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
case 0x0500: /* mov.w @(disp,Rm),R0 */
goto simple;
case 0x0B00: /* bf lab - no delayslot*/
ret = 0;
break;
case 0x0F00: /* bf/s lab */
ret = handle_delayslot(regs, instruction, ma);
......@@ -479,6 +509,7 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
}
break;
case 0x0900: /* bt lab - no delayslot */
ret = 0;
break;
case 0x0D00: /* bt/s lab */
ret = handle_delayslot(regs, instruction, ma);
......@@ -494,6 +525,9 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
}
break;
case 0x9000: /* mov.w @(disp,Rm),Rn */
goto simple;
case 0xA000: /* bra label */
ret = handle_delayslot(regs, instruction, ma);
if (ret==0)
......@@ -507,6 +541,9 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
regs->pc += SH_PC_12BIT_OFFSET(instruction);
}
break;
case 0xD000: /* mov.l @(disp,Rm),Rn */
goto simple;
}
return ret;
......
......@@ -26,6 +26,7 @@
#include <linux/clk.h>
#include <linux/irq.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/sh_timer.h>
......@@ -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)
......
......@@ -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)
......
......@@ -47,6 +47,7 @@
#include <linux/ctype.h>
#include <linux/err.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
......@@ -95,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 */
......@@ -1076,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
......@@ -1633,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;
......@@ -1657,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 +2051,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 +2095,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 +2134,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 +2251,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,
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment