diff options
Diffstat (limited to 'arch/sh/kernel')
| -rw-r--r-- | arch/sh/kernel/Makefile | 1 | ||||
| -rw-r--r-- | arch/sh/kernel/cpu/shmobile/cpuidle.c | 101 | ||||
| -rw-r--r-- | arch/sh/kernel/cpu/shmobile/pm.c | 3 | ||||
| -rw-r--r-- | arch/sh/kernel/cpufreq.c | 201 | ||||
| -rw-r--r-- | arch/sh/kernel/dumpstack.c | 6 | ||||
| -rw-r--r-- | arch/sh/kernel/idle.c | 101 | ||||
| -rw-r--r-- | arch/sh/kernel/process_32.c | 6 | ||||
| -rw-r--r-- | arch/sh/kernel/process_64.c | 1 | ||||
| -rw-r--r-- | arch/sh/kernel/sh_bios.c | 4 | ||||
| -rw-r--r-- | arch/sh/kernel/smp.c | 2 | 
10 files changed, 59 insertions, 367 deletions
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index f259b37874e..261c8bfd75c 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile @@ -31,7 +31,6 @@ obj-$(CONFIG_VSYSCALL)		+= vsyscall/  obj-$(CONFIG_SMP)		+= smp.o  obj-$(CONFIG_SH_STANDARD_BIOS)	+= sh_bios.o  obj-$(CONFIG_KGDB)		+= kgdb.o -obj-$(CONFIG_SH_CPU_FREQ)	+= cpufreq.o  obj-$(CONFIG_MODULES)		+= sh_ksyms_$(BITS).o module.o  obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o  obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o diff --git a/arch/sh/kernel/cpu/shmobile/cpuidle.c b/arch/sh/kernel/cpu/shmobile/cpuidle.c index 1ddc876d3b2..d3062259211 100644 --- a/arch/sh/kernel/cpu/shmobile/cpuidle.c +++ b/arch/sh/kernel/cpu/shmobile/cpuidle.c @@ -51,70 +51,53 @@ static int cpuidle_sleep_enter(struct cpuidle_device *dev,  	return k;  } -static struct cpuidle_device cpuidle_dev;  static struct cpuidle_driver cpuidle_driver = { -	.name			= "sh_idle", -	.owner			= THIS_MODULE, -	.en_core_tk_irqen	= 1, +	.name   = "sh_idle", +	.owner  = THIS_MODULE, +	.states = { +		{ +			.exit_latency = 1, +			.target_residency = 1 * 2, +			.power_usage = 3, +			.flags = CPUIDLE_FLAG_TIME_VALID, +			.enter = cpuidle_sleep_enter, +			.name = "C1", +			.desc = "SuperH Sleep Mode", +		}, +		{ +			.exit_latency = 100, +			.target_residency = 1 * 2, +			.power_usage = 1, +			.flags = CPUIDLE_FLAG_TIME_VALID, +			.enter = cpuidle_sleep_enter, +			.name = "C2", +			.desc = "SuperH Sleep Mode [SF]", +			.disabled = true, +		}, +		{ +			.exit_latency = 2300, +			.target_residency = 1 * 2, +			.power_usage = 1, +			.flags = CPUIDLE_FLAG_TIME_VALID, +			.enter = cpuidle_sleep_enter, +			.name = "C3", +			.desc = "SuperH Mobile Standby Mode [SF]", +			.disabled = true, +		}, +	}, +	.safe_state_index = 0, +	.state_count = 3,  }; -void sh_mobile_setup_cpuidle(void) +int __init sh_mobile_setup_cpuidle(void)  { -	struct cpuidle_device *dev = &cpuidle_dev; -	struct cpuidle_driver *drv = &cpuidle_driver; -	struct cpuidle_state *state; -	int i; +	int ret; +	if (sh_mobile_sleep_supported & SUSP_SH_SF) +		cpuidle_driver.states[1].disabled = false; -	for (i = 0; i < CPUIDLE_STATE_MAX; i++) { -		drv->states[i].name[0] = '\0'; -		drv->states[i].desc[0] = '\0'; -	} +	if (sh_mobile_sleep_supported & SUSP_SH_STANDBY) +		cpuidle_driver.states[2].disabled = false; -	i = CPUIDLE_DRIVER_STATE_START; - -	state = &drv->states[i++]; -	snprintf(state->name, CPUIDLE_NAME_LEN, "C1"); -	strncpy(state->desc, "SuperH Sleep Mode", CPUIDLE_DESC_LEN); -	state->exit_latency = 1; -	state->target_residency = 1 * 2; -	state->power_usage = 3; -	state->flags = 0; -	state->flags |= CPUIDLE_FLAG_TIME_VALID; -	state->enter = cpuidle_sleep_enter; - -	drv->safe_state_index = i-1; - -	if (sh_mobile_sleep_supported & SUSP_SH_SF) { -		state = &drv->states[i++]; -		snprintf(state->name, CPUIDLE_NAME_LEN, "C2"); -		strncpy(state->desc, "SuperH Sleep Mode [SF]", -			CPUIDLE_DESC_LEN); -		state->exit_latency = 100; -		state->target_residency = 1 * 2; -		state->power_usage = 1; -		state->flags = 0; -		state->flags |= CPUIDLE_FLAG_TIME_VALID; -		state->enter = cpuidle_sleep_enter; -	} - -	if (sh_mobile_sleep_supported & SUSP_SH_STANDBY) { -		state = &drv->states[i++]; -		snprintf(state->name, CPUIDLE_NAME_LEN, "C3"); -		strncpy(state->desc, "SuperH Mobile Standby Mode [SF]", -			CPUIDLE_DESC_LEN); -		state->exit_latency = 2300; -		state->target_residency = 1 * 2; -		state->power_usage = 1; -		state->flags = 0; -		state->flags |= CPUIDLE_FLAG_TIME_VALID; -		state->enter = cpuidle_sleep_enter; -	} - -	drv->state_count = i; -	dev->state_count = i; - -	cpuidle_register_driver(&cpuidle_driver); - -	cpuidle_register_device(dev); +	return cpuidle_register(&cpuidle_driver);  } diff --git a/arch/sh/kernel/cpu/shmobile/pm.c b/arch/sh/kernel/cpu/shmobile/pm.c index 08d27fac8d0..ac37b7234f8 100644 --- a/arch/sh/kernel/cpu/shmobile/pm.c +++ b/arch/sh/kernel/cpu/shmobile/pm.c @@ -150,8 +150,7 @@ static const struct platform_suspend_ops sh_pm_ops = {  static int __init sh_pm_init(void)  {  	suspend_set_ops(&sh_pm_ops); -	sh_mobile_setup_cpuidle(); -	return 0; +	return sh_mobile_setup_cpuidle();  }  late_initcall(sh_pm_init); diff --git a/arch/sh/kernel/cpufreq.c b/arch/sh/kernel/cpufreq.c deleted file mode 100644 index e68b45b6f3f..00000000000 --- a/arch/sh/kernel/cpufreq.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * arch/sh/kernel/cpufreq.c - * - * cpufreq driver for the SuperH processors. - * - * Copyright (C) 2002 - 2012 Paul Mundt - * Copyright (C) 2002 M. R. Brown - * - * Clock framework bits from arch/avr32/mach-at32ap/cpufreq.c - * - *   Copyright (C) 2004-2007 Atmel Corporation - * - * This file is subject to the terms and conditions of the GNU General Public - * License.  See the file "COPYING" in the main directory of this archive - * for more details. - */ -#define pr_fmt(fmt) "cpufreq: " fmt - -#include <linux/types.h> -#include <linux/cpufreq.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/err.h> -#include <linux/cpumask.h> -#include <linux/cpu.h> -#include <linux/smp.h> -#include <linux/sched.h>	/* set_cpus_allowed() */ -#include <linux/clk.h> -#include <linux/percpu.h> -#include <linux/sh_clk.h> - -static DEFINE_PER_CPU(struct clk, sh_cpuclk); - -static unsigned int sh_cpufreq_get(unsigned int cpu) -{ -	return (clk_get_rate(&per_cpu(sh_cpuclk, cpu)) + 500) / 1000; -} - -/* - * Here we notify other drivers of the proposed change and the final change. - */ -static int sh_cpufreq_target(struct cpufreq_policy *policy, -			     unsigned int target_freq, -			     unsigned int relation) -{ -	unsigned int cpu = policy->cpu; -	struct clk *cpuclk = &per_cpu(sh_cpuclk, cpu); -	cpumask_t cpus_allowed; -	struct cpufreq_freqs freqs; -	struct device *dev; -	long freq; - -	if (!cpu_online(cpu)) -		return -ENODEV; - -	cpus_allowed = current->cpus_allowed; -	set_cpus_allowed_ptr(current, cpumask_of(cpu)); - -	BUG_ON(smp_processor_id() != cpu); - -	dev = get_cpu_device(cpu); - -	/* Convert target_freq from kHz to Hz */ -	freq = clk_round_rate(cpuclk, target_freq * 1000); - -	if (freq < (policy->min * 1000) || freq > (policy->max * 1000)) -		return -EINVAL; - -	dev_dbg(dev, "requested frequency %u Hz\n", target_freq * 1000); - -	freqs.cpu	= cpu; -	freqs.old	= sh_cpufreq_get(cpu); -	freqs.new	= (freq + 500) / 1000; -	freqs.flags	= 0; - -	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); -	set_cpus_allowed_ptr(current, &cpus_allowed); -	clk_set_rate(cpuclk, freq); -	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - -	dev_dbg(dev, "set frequency %lu Hz\n", freq); - -	return 0; -} - -static int sh_cpufreq_verify(struct cpufreq_policy *policy) -{ -	struct clk *cpuclk = &per_cpu(sh_cpuclk, policy->cpu); -	struct cpufreq_frequency_table *freq_table; - -	freq_table = cpuclk->nr_freqs ? cpuclk->freq_table : NULL; -	if (freq_table) -		return cpufreq_frequency_table_verify(policy, freq_table); - -	cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, -				     policy->cpuinfo.max_freq); - -	policy->min = (clk_round_rate(cpuclk, 1) + 500) / 1000; -	policy->max = (clk_round_rate(cpuclk, ~0UL) + 500) / 1000; - -	cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, -				     policy->cpuinfo.max_freq); - -	return 0; -} - -static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy) -{ -	unsigned int cpu = policy->cpu; -	struct clk *cpuclk = &per_cpu(sh_cpuclk, cpu); -	struct cpufreq_frequency_table *freq_table; -	struct device *dev; - -	if (!cpu_online(cpu)) -		return -ENODEV; - -	dev = get_cpu_device(cpu); - -	cpuclk = clk_get(dev, "cpu_clk"); -	if (IS_ERR(cpuclk)) { -		dev_err(dev, "couldn't get CPU clk\n"); -		return PTR_ERR(cpuclk); -	} - -	policy->cur = policy->min = policy->max = sh_cpufreq_get(cpu); - -	freq_table = cpuclk->nr_freqs ? cpuclk->freq_table : NULL; -	if (freq_table) { -		int result; - -		result = cpufreq_frequency_table_cpuinfo(policy, freq_table); -		if (!result) -			cpufreq_frequency_table_get_attr(freq_table, cpu); -	} else { -		dev_notice(dev, "no frequency table found, falling back " -			   "to rate rounding.\n"); - -		policy->cpuinfo.min_freq = -			(clk_round_rate(cpuclk, 1) + 500) / 1000; -		policy->cpuinfo.max_freq = -			(clk_round_rate(cpuclk, ~0UL) + 500) / 1000; -	} - -	policy->min = policy->cpuinfo.min_freq; -	policy->max = policy->cpuinfo.max_freq; - -	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; - -	dev_info(dev, "CPU Frequencies - Minimum %u.%03u MHz, " -	       "Maximum %u.%03u MHz.\n", -	       policy->min / 1000, policy->min % 1000, -	       policy->max / 1000, policy->max % 1000); - -	return 0; -} - -static int sh_cpufreq_cpu_exit(struct cpufreq_policy *policy) -{ -	unsigned int cpu = policy->cpu; -	struct clk *cpuclk = &per_cpu(sh_cpuclk, cpu); - -	cpufreq_frequency_table_put_attr(cpu); -	clk_put(cpuclk); - -	return 0; -} - -static struct freq_attr *sh_freq_attr[] = { -	&cpufreq_freq_attr_scaling_available_freqs, -	NULL, -}; - -static struct cpufreq_driver sh_cpufreq_driver = { -	.owner		= THIS_MODULE, -	.name		= "sh", -	.get		= sh_cpufreq_get, -	.target		= sh_cpufreq_target, -	.verify		= sh_cpufreq_verify, -	.init		= sh_cpufreq_cpu_init, -	.exit		= sh_cpufreq_cpu_exit, -	.attr		= sh_freq_attr, -}; - -static int __init sh_cpufreq_module_init(void) -{ -	pr_notice("SuperH CPU frequency driver.\n"); -	return cpufreq_register_driver(&sh_cpufreq_driver); -} - -static void __exit sh_cpufreq_module_exit(void) -{ -	cpufreq_unregister_driver(&sh_cpufreq_driver); -} - -module_init(sh_cpufreq_module_init); -module_exit(sh_cpufreq_module_exit); - -MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>"); -MODULE_DESCRIPTION("cpufreq driver for SuperH"); -MODULE_LICENSE("GPL"); diff --git a/arch/sh/kernel/dumpstack.c b/arch/sh/kernel/dumpstack.c index 7617dc4129a..b959f559260 100644 --- a/arch/sh/kernel/dumpstack.c +++ b/arch/sh/kernel/dumpstack.c @@ -158,9 +158,3 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)  		 (unsigned long)task_stack_page(tsk));  	show_trace(tsk, sp, NULL);  } - -void dump_stack(void) -{ -	show_stack(NULL, NULL); -} -EXPORT_SYMBOL(dump_stack); diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c index 3d5a1b387cc..2ea4483fd72 100644 --- a/arch/sh/kernel/idle.c +++ b/arch/sh/kernel/idle.c @@ -24,98 +24,24 @@  static void (*sh_idle)(void); -static int hlt_counter; - -static int __init nohlt_setup(char *__unused) -{ -	hlt_counter = 1; -	return 1; -} -__setup("nohlt", nohlt_setup); - -static int __init hlt_setup(char *__unused) -{ -	hlt_counter = 0; -	return 1; -} -__setup("hlt", hlt_setup); - -static inline int hlt_works(void) -{ -	return !hlt_counter; -} - -/* - * On SMP it's slightly faster (but much more power-consuming!) - * to poll the ->work.need_resched flag instead of waiting for the - * cross-CPU IPI to arrive. Use this option with caution. - */ -static void poll_idle(void) +void default_idle(void)  { +	set_bl_bit();  	local_irq_enable(); -	while (!need_resched()) -		cpu_relax(); +	/* Isn't this racy ? */ +	cpu_sleep(); +	clear_bl_bit();  } -void default_idle(void) +void arch_cpu_idle_dead(void)  { -	if (hlt_works()) { -		clear_thread_flag(TIF_POLLING_NRFLAG); -		smp_mb__after_clear_bit(); - -		set_bl_bit(); -		if (!need_resched()) { -			local_irq_enable(); -			cpu_sleep(); -		} else -			local_irq_enable(); - -		set_thread_flag(TIF_POLLING_NRFLAG); -		clear_bl_bit(); -	} else -		poll_idle(); +	play_dead();  } -/* - * The idle thread. There's no useful work to be done, so just try to conserve - * power and have a low exit latency (ie sit in a loop waiting for somebody to - * say that they'd like to reschedule) - */ -void cpu_idle(void) +void arch_cpu_idle(void)  { -	unsigned int cpu = smp_processor_id(); - -	set_thread_flag(TIF_POLLING_NRFLAG); - -	/* endless idle loop with no priority at all */ -	while (1) { -		tick_nohz_idle_enter(); -		rcu_idle_enter(); - -		while (!need_resched()) { -			check_pgt_cache(); -			rmb(); - -			if (cpu_is_offline(cpu)) -				play_dead(); - -			local_irq_disable(); -			/* Don't trace irqs off for idle */ -			stop_critical_timings(); -			if (cpuidle_idle_call()) -				sh_idle(); -			/* -			 * Sanity check to ensure that sh_idle() returns -			 * with IRQs enabled -			 */ -			WARN_ON(irqs_disabled()); -			start_critical_timings(); -		} - -		rcu_idle_exit(); -		tick_nohz_idle_exit(); -		schedule_preempt_disabled(); -	} +	if (cpuidle_idle_call()) +		sh_idle();  }  void __init select_idle_routine(void) @@ -123,13 +49,8 @@ void __init select_idle_routine(void)  	/*  	 * If a platform has set its own idle routine, leave it alone.  	 */ -	if (sh_idle) -		return; - -	if (hlt_works()) +	if (!sh_idle)  		sh_idle = default_idle; -	else -		sh_idle = poll_idle;  }  void stop_this_cpu(void *unused) diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c index 73eb66fc625..ebd3933005b 100644 --- a/arch/sh/kernel/process_32.c +++ b/arch/sh/kernel/process_32.c @@ -32,11 +32,7 @@  void show_regs(struct pt_regs * regs)  {  	printk("\n"); -	printk("Pid : %d, Comm: \t\t%s\n", task_pid_nr(current), current->comm); -	printk("CPU : %d        \t\t%s  (%s %.*s)\n\n", -	       smp_processor_id(), print_tainted(), init_utsname()->release, -	       (int)strcspn(init_utsname()->version, " "), -	       init_utsname()->version); +	show_regs_print_info(KERN_DEFAULT);  	print_symbol("PC is at %s\n", instruction_pointer(regs));  	print_symbol("PR is at %s\n", regs->pr); diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c index e611c85144b..174d124b419 100644 --- a/arch/sh/kernel/process_64.c +++ b/arch/sh/kernel/process_64.c @@ -40,6 +40,7 @@ void show_regs(struct pt_regs *regs)  	unsigned long long ah, al, bh, bl, ch, cl;  	printk("\n"); +	show_regs_print_info(KERN_DEFAULT);  	ah = (regs->pc) >> 32;  	al = (regs->pc) & 0xffffffff; diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c index 47475cca068..fe584e51696 100644 --- a/arch/sh/kernel/sh_bios.c +++ b/arch/sh/kernel/sh_bios.c @@ -104,6 +104,7 @@ void sh_bios_vbr_reload(void)  		);  } +#ifdef CONFIG_EARLY_PRINTK  /*   *	Print a string through the BIOS   */ @@ -144,8 +145,6 @@ static struct console bios_console = {  	.index		= -1,  }; -static struct console *early_console; -  static int __init setup_early_printk(char *buf)  {  	int keep_early = 0; @@ -170,3 +169,4 @@ static int __init setup_early_printk(char *buf)  	return 0;  }  early_param("earlyprintk", setup_early_printk); +#endif diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index 2062aa88af4..45696451f0e 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c @@ -203,7 +203,7 @@ asmlinkage void __cpuinit start_secondary(void)  	set_cpu_online(cpu, true);  	per_cpu(cpu_state, cpu) = CPU_ONLINE; -	cpu_idle(); +	cpu_startup_entry(CPUHP_ONLINE);  }  extern struct {  |