diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-30 15:21:02 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-30 15:21:02 -0700 | 
| commit | 3ed1c478eff8db80e234d5446cb378b503135888 (patch) | |
| tree | e1c8e0f488ca49c49b5a31fe59add4254381dd4b /arch/sparc | |
| parent | 151173e8ce9b95bbbbd7eedb9035cfaffbdb7cb2 (diff) | |
| parent | 371deb9500831ad1afbf9ea00e373f650deaed2f (diff) | |
| download | linux-3ed1c478eff8db80e234d5446cb378b503135888.tar.bz2 | |
Merge tag 'pm+acpi-3.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management and ACPI updates from Rafael J Wysocki:
 - ARM big.LITTLE cpufreq driver from Viresh Kumar.
 - exynos5440 cpufreq driver from Amit Daniel Kachhap.
 - cpufreq core cleanup and code consolidation from Viresh Kumar and
   Stratos Karafotis.
 - cpufreq scalability improvement from Nathan Zimmer.
 - AMD "frequency sensitivity feedback" powersave bias for the ondemand
   cpufreq governor from Jacob Shin.
 - cpuidle code consolidation and cleanups from Daniel Lezcano.
 - ARM OMAP cpuidle fixes from Santosh Shilimkar and Daniel Lezcano.
 - ACPICA fixes and other improvements from Bob Moore, Jung-uk Kim, Lv
   Zheng, Yinghai Lu, Tang Chen, Colin Ian King, and Linn Crosetto.
 - ACPI core updates related to hotplug from Toshi Kani, Paul Bolle,
   Yasuaki Ishimatsu, and Rafael J Wysocki.
 - Intel Lynxpoint LPSS (Low-Power Subsystem) support improvements from
   Rafael J Wysocki and Andy Shevchenko.
* tag 'pm+acpi-3.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (192 commits)
  cpufreq: Revert incorrect commit 5800043
  cpufreq: MAINTAINERS: Add co-maintainer
  cpuidle: add maintainer entry
  ACPI / thermal: do not always return THERMAL_TREND_RAISING for active trip points
  ARM: s3c64xx: cpuidle: use init/exit common routine
  cpufreq: pxa2xx: initialize variables
  ACPI: video: correct acpi_video_bus_add error processing
  SH: cpuidle: use init/exit common routine
  ARM: S5pv210: compiling issue, ARM_S5PV210_CPUFREQ needs CONFIG_CPU_FREQ_TABLE=y
  ACPI: Fix wrong parameter passed to memblock_reserve
  cpuidle: fix comment format
  pnp: use %*phC to dump small buffers
  isapnp: remove debug leftovers
  ARM: imx: cpuidle: use init/exit common routine
  ARM: davinci: cpuidle: use init/exit common routine
  ARM: kirkwood: cpuidle: use init/exit common routine
  ARM: calxeda: cpuidle: use init/exit common routine
  ARM: tegra: cpuidle: use init/exit common routine for tegra3
  ARM: tegra: cpuidle: use init/exit common routine for tegra2
  ARM: OMAP4: cpuidle: use init/exit common routine
  ...
Diffstat (limited to 'arch/sparc')
| -rw-r--r-- | arch/sparc/Kconfig | 23 | ||||
| -rw-r--r-- | arch/sparc/kernel/Makefile | 3 | ||||
| -rw-r--r-- | arch/sparc/kernel/us2e_cpufreq.c | 413 | ||||
| -rw-r--r-- | arch/sparc/kernel/us3_cpufreq.c | 274 | 
4 files changed, 0 insertions, 713 deletions
| diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 66dc562950ae..e5641157464f 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -254,29 +254,6 @@ config HOTPLUG_CPU  if SPARC64  source "drivers/cpufreq/Kconfig" - -config US3_FREQ -	tristate "UltraSPARC-III CPU Frequency driver" -	depends on CPU_FREQ -	select CPU_FREQ_TABLE -	help -	  This adds the CPUFreq driver for UltraSPARC-III processors. - -	  For details, take a look at <file:Documentation/cpu-freq>. - -	  If in doubt, say N. - -config US2E_FREQ -	tristate "UltraSPARC-IIe CPU Frequency driver" -	depends on CPU_FREQ -	select CPU_FREQ_TABLE -	help -	  This adds the CPUFreq driver for UltraSPARC-IIe processors. - -	  For details, take a look at <file:Documentation/cpu-freq>. - -	  If in doubt, say N. -  endif  config US3_MC diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index 6cf591b7e1c6..5276fd4e9d03 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -102,9 +102,6 @@ obj-$(CONFIG_PCI_MSI)        += pci_msi.o  obj-$(CONFIG_COMPAT)         += sys32.o sys_sparc32.o signal32.o -# sparc64 cpufreq -obj-$(CONFIG_US3_FREQ)  += us3_cpufreq.o -obj-$(CONFIG_US2E_FREQ) += us2e_cpufreq.o  obj-$(CONFIG_US3_MC)    += chmc.o  obj-$(CONFIG_KPROBES)   += kprobes.o diff --git a/arch/sparc/kernel/us2e_cpufreq.c b/arch/sparc/kernel/us2e_cpufreq.c deleted file mode 100644 index 489fc15f3194..000000000000 --- a/arch/sparc/kernel/us2e_cpufreq.c +++ /dev/null @@ -1,413 +0,0 @@ -/* us2e_cpufreq.c: UltraSPARC-IIe cpu frequency support - * - * Copyright (C) 2003 David S. Miller (davem@redhat.com) - * - * Many thanks to Dominik Brodowski for fixing up the cpufreq - * infrastructure in order to make this driver easier to implement. - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/sched.h> -#include <linux/smp.h> -#include <linux/cpufreq.h> -#include <linux/threads.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/init.h> - -#include <asm/asi.h> -#include <asm/timer.h> - -static struct cpufreq_driver *cpufreq_us2e_driver; - -struct us2e_freq_percpu_info { -	struct cpufreq_frequency_table table[6]; -}; - -/* Indexed by cpu number. */ -static struct us2e_freq_percpu_info *us2e_freq_table; - -#define HBIRD_MEM_CNTL0_ADDR	0x1fe0000f010UL -#define HBIRD_ESTAR_MODE_ADDR	0x1fe0000f080UL - -/* UltraSPARC-IIe has five dividers: 1, 2, 4, 6, and 8.  These are controlled - * in the ESTAR mode control register. - */ -#define ESTAR_MODE_DIV_1	0x0000000000000000UL -#define ESTAR_MODE_DIV_2	0x0000000000000001UL -#define ESTAR_MODE_DIV_4	0x0000000000000003UL -#define ESTAR_MODE_DIV_6	0x0000000000000002UL -#define ESTAR_MODE_DIV_8	0x0000000000000004UL -#define ESTAR_MODE_DIV_MASK	0x0000000000000007UL - -#define MCTRL0_SREFRESH_ENAB	0x0000000000010000UL -#define MCTRL0_REFR_COUNT_MASK	0x0000000000007f00UL -#define MCTRL0_REFR_COUNT_SHIFT	8 -#define MCTRL0_REFR_INTERVAL	7800 -#define MCTRL0_REFR_CLKS_P_CNT	64 - -static unsigned long read_hbreg(unsigned long addr) -{ -	unsigned long ret; - -	__asm__ __volatile__("ldxa	[%1] %2, %0" -			     : "=&r" (ret) -			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); -	return ret; -} - -static void write_hbreg(unsigned long addr, unsigned long val) -{ -	__asm__ __volatile__("stxa	%0, [%1] %2\n\t" -			     "membar	#Sync" -			     : /* no outputs */ -			     : "r" (val), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E) -			     : "memory"); -	if (addr == HBIRD_ESTAR_MODE_ADDR) { -		/* Need to wait 16 clock cycles for the PLL to lock.  */ -		udelay(1); -	} -} - -static void self_refresh_ctl(int enable) -{ -	unsigned long mctrl = read_hbreg(HBIRD_MEM_CNTL0_ADDR); - -	if (enable) -		mctrl |= MCTRL0_SREFRESH_ENAB; -	else -		mctrl &= ~MCTRL0_SREFRESH_ENAB; -	write_hbreg(HBIRD_MEM_CNTL0_ADDR, mctrl); -	(void) read_hbreg(HBIRD_MEM_CNTL0_ADDR); -} - -static void frob_mem_refresh(int cpu_slowing_down, -			     unsigned long clock_tick, -			     unsigned long old_divisor, unsigned long divisor) -{ -	unsigned long old_refr_count, refr_count, mctrl; - -	refr_count  = (clock_tick * MCTRL0_REFR_INTERVAL); -	refr_count /= (MCTRL0_REFR_CLKS_P_CNT * divisor * 1000000000UL); - -	mctrl = read_hbreg(HBIRD_MEM_CNTL0_ADDR); -	old_refr_count = (mctrl & MCTRL0_REFR_COUNT_MASK) -		>> MCTRL0_REFR_COUNT_SHIFT; - -	mctrl &= ~MCTRL0_REFR_COUNT_MASK; -	mctrl |= refr_count << MCTRL0_REFR_COUNT_SHIFT; -	write_hbreg(HBIRD_MEM_CNTL0_ADDR, mctrl); -	mctrl = read_hbreg(HBIRD_MEM_CNTL0_ADDR); - -	if (cpu_slowing_down && !(mctrl & MCTRL0_SREFRESH_ENAB)) { -		unsigned long usecs; - -		/* We have to wait for both refresh counts (old -		 * and new) to go to zero. -		 */ -		usecs = (MCTRL0_REFR_CLKS_P_CNT * -			 (refr_count + old_refr_count) * -			 1000000UL * -			 old_divisor) / clock_tick; -		udelay(usecs + 1UL); -	} -} - -static void us2e_transition(unsigned long estar, unsigned long new_bits, -			    unsigned long clock_tick, -			    unsigned long old_divisor, unsigned long divisor) -{ -	unsigned long flags; - -	local_irq_save(flags); - -	estar &= ~ESTAR_MODE_DIV_MASK; - -	/* This is based upon the state transition diagram in the IIe manual.  */ -	if (old_divisor == 2 && divisor == 1) { -		self_refresh_ctl(0); -		write_hbreg(HBIRD_ESTAR_MODE_ADDR, estar | new_bits); -		frob_mem_refresh(0, clock_tick, old_divisor, divisor); -	} else if (old_divisor == 1 && divisor == 2) { -		frob_mem_refresh(1, clock_tick, old_divisor, divisor); -		write_hbreg(HBIRD_ESTAR_MODE_ADDR, estar | new_bits); -		self_refresh_ctl(1); -	} else if (old_divisor == 1 && divisor > 2) { -		us2e_transition(estar, ESTAR_MODE_DIV_2, clock_tick, -				1, 2); -		us2e_transition(estar, new_bits, clock_tick, -				2, divisor); -	} else if (old_divisor > 2 && divisor == 1) { -		us2e_transition(estar, ESTAR_MODE_DIV_2, clock_tick, -				old_divisor, 2); -		us2e_transition(estar, new_bits, clock_tick, -				2, divisor); -	} else if (old_divisor < divisor) { -		frob_mem_refresh(0, clock_tick, old_divisor, divisor); -		write_hbreg(HBIRD_ESTAR_MODE_ADDR, estar | new_bits); -	} else if (old_divisor > divisor) { -		write_hbreg(HBIRD_ESTAR_MODE_ADDR, estar | new_bits); -		frob_mem_refresh(1, clock_tick, old_divisor, divisor); -	} else { -		BUG(); -	} - -	local_irq_restore(flags); -} - -static unsigned long index_to_estar_mode(unsigned int index) -{ -	switch (index) { -	case 0: -		return ESTAR_MODE_DIV_1; - -	case 1: -		return ESTAR_MODE_DIV_2; - -	case 2: -		return ESTAR_MODE_DIV_4; - -	case 3: -		return ESTAR_MODE_DIV_6; - -	case 4: -		return ESTAR_MODE_DIV_8; - -	default: -		BUG(); -	} -} - -static unsigned long index_to_divisor(unsigned int index) -{ -	switch (index) { -	case 0: -		return 1; - -	case 1: -		return 2; - -	case 2: -		return 4; - -	case 3: -		return 6; - -	case 4: -		return 8; - -	default: -		BUG(); -	} -} - -static unsigned long estar_to_divisor(unsigned long estar) -{ -	unsigned long ret; - -	switch (estar & ESTAR_MODE_DIV_MASK) { -	case ESTAR_MODE_DIV_1: -		ret = 1; -		break; -	case ESTAR_MODE_DIV_2: -		ret = 2; -		break; -	case ESTAR_MODE_DIV_4: -		ret = 4; -		break; -	case ESTAR_MODE_DIV_6: -		ret = 6; -		break; -	case ESTAR_MODE_DIV_8: -		ret = 8; -		break; -	default: -		BUG(); -	} - -	return ret; -} - -static unsigned int us2e_freq_get(unsigned int cpu) -{ -	cpumask_t cpus_allowed; -	unsigned long clock_tick, estar; - -	if (!cpu_online(cpu)) -		return 0; - -	cpumask_copy(&cpus_allowed, tsk_cpus_allowed(current)); -	set_cpus_allowed_ptr(current, cpumask_of(cpu)); - -	clock_tick = sparc64_get_clock_tick(cpu) / 1000; -	estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR); - -	set_cpus_allowed_ptr(current, &cpus_allowed); - -	return clock_tick / estar_to_divisor(estar); -} - -static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index) -{ -	unsigned long new_bits, new_freq; -	unsigned long clock_tick, divisor, old_divisor, estar; -	cpumask_t cpus_allowed; -	struct cpufreq_freqs freqs; - -	if (!cpu_online(cpu)) -		return; - -	cpumask_copy(&cpus_allowed, tsk_cpus_allowed(current)); -	set_cpus_allowed_ptr(current, cpumask_of(cpu)); - -	new_freq = clock_tick = sparc64_get_clock_tick(cpu) / 1000; -	new_bits = index_to_estar_mode(index); -	divisor = index_to_divisor(index); -	new_freq /= divisor; - -	estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR); - -	old_divisor = estar_to_divisor(estar); - -	freqs.old = clock_tick / old_divisor; -	freqs.new = new_freq; -	freqs.cpu = cpu; -	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - -	if (old_divisor != divisor) -		us2e_transition(estar, new_bits, clock_tick * 1000, -				old_divisor, divisor); - -	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - -	set_cpus_allowed_ptr(current, &cpus_allowed); -} - -static int us2e_freq_target(struct cpufreq_policy *policy, -			  unsigned int target_freq, -			  unsigned int relation) -{ -	unsigned int new_index = 0; - -	if (cpufreq_frequency_table_target(policy, -					   &us2e_freq_table[policy->cpu].table[0], -					   target_freq, relation, &new_index)) -		return -EINVAL; - -	us2e_set_cpu_divider_index(policy->cpu, new_index); - -	return 0; -} - -static int us2e_freq_verify(struct cpufreq_policy *policy) -{ -	return cpufreq_frequency_table_verify(policy, -					      &us2e_freq_table[policy->cpu].table[0]); -} - -static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy) -{ -	unsigned int cpu = policy->cpu; -	unsigned long clock_tick = sparc64_get_clock_tick(cpu) / 1000; -	struct cpufreq_frequency_table *table = -		&us2e_freq_table[cpu].table[0]; - -	table[0].index = 0; -	table[0].frequency = clock_tick / 1; -	table[1].index = 1; -	table[1].frequency = clock_tick / 2; -	table[2].index = 2; -	table[2].frequency = clock_tick / 4; -	table[2].index = 3; -	table[2].frequency = clock_tick / 6; -	table[2].index = 4; -	table[2].frequency = clock_tick / 8; -	table[2].index = 5; -	table[3].frequency = CPUFREQ_TABLE_END; - -	policy->cpuinfo.transition_latency = 0; -	policy->cur = clock_tick; - -	return cpufreq_frequency_table_cpuinfo(policy, table); -} - -static int us2e_freq_cpu_exit(struct cpufreq_policy *policy) -{ -	if (cpufreq_us2e_driver) -		us2e_set_cpu_divider_index(policy->cpu, 0); - -	return 0; -} - -static int __init us2e_freq_init(void) -{ -	unsigned long manuf, impl, ver; -	int ret; - -	if (tlb_type != spitfire) -		return -ENODEV; - -	__asm__("rdpr %%ver, %0" : "=r" (ver)); -	manuf = ((ver >> 48) & 0xffff); -	impl  = ((ver >> 32) & 0xffff); - -	if (manuf == 0x17 && impl == 0x13) { -		struct cpufreq_driver *driver; - -		ret = -ENOMEM; -		driver = kzalloc(sizeof(struct cpufreq_driver), GFP_KERNEL); -		if (!driver) -			goto err_out; - -		us2e_freq_table = kzalloc( -			(NR_CPUS * sizeof(struct us2e_freq_percpu_info)), -			GFP_KERNEL); -		if (!us2e_freq_table) -			goto err_out; - -		driver->init = us2e_freq_cpu_init; -		driver->verify = us2e_freq_verify; -		driver->target = us2e_freq_target; -		driver->get = us2e_freq_get; -		driver->exit = us2e_freq_cpu_exit; -		driver->owner = THIS_MODULE, -		strcpy(driver->name, "UltraSPARC-IIe"); - -		cpufreq_us2e_driver = driver; -		ret = cpufreq_register_driver(driver); -		if (ret) -			goto err_out; - -		return 0; - -err_out: -		if (driver) { -			kfree(driver); -			cpufreq_us2e_driver = NULL; -		} -		kfree(us2e_freq_table); -		us2e_freq_table = NULL; -		return ret; -	} - -	return -ENODEV; -} - -static void __exit us2e_freq_exit(void) -{ -	if (cpufreq_us2e_driver) { -		cpufreq_unregister_driver(cpufreq_us2e_driver); -		kfree(cpufreq_us2e_driver); -		cpufreq_us2e_driver = NULL; -		kfree(us2e_freq_table); -		us2e_freq_table = NULL; -	} -} - -MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); -MODULE_DESCRIPTION("cpufreq driver for UltraSPARC-IIe"); -MODULE_LICENSE("GPL"); - -module_init(us2e_freq_init); -module_exit(us2e_freq_exit); diff --git a/arch/sparc/kernel/us3_cpufreq.c b/arch/sparc/kernel/us3_cpufreq.c deleted file mode 100644 index eb1624b931d9..000000000000 --- a/arch/sparc/kernel/us3_cpufreq.c +++ /dev/null @@ -1,274 +0,0 @@ -/* us3_cpufreq.c: UltraSPARC-III cpu frequency support - * - * Copyright (C) 2003 David S. Miller (davem@redhat.com) - * - * Many thanks to Dominik Brodowski for fixing up the cpufreq - * infrastructure in order to make this driver easier to implement. - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/sched.h> -#include <linux/smp.h> -#include <linux/cpufreq.h> -#include <linux/threads.h> -#include <linux/slab.h> -#include <linux/init.h> - -#include <asm/head.h> -#include <asm/timer.h> - -static struct cpufreq_driver *cpufreq_us3_driver; - -struct us3_freq_percpu_info { -	struct cpufreq_frequency_table table[4]; -}; - -/* Indexed by cpu number. */ -static struct us3_freq_percpu_info *us3_freq_table; - -/* UltraSPARC-III has three dividers: 1, 2, and 32.  These are controlled - * in the Safari config register. - */ -#define SAFARI_CFG_DIV_1	0x0000000000000000UL -#define SAFARI_CFG_DIV_2	0x0000000040000000UL -#define SAFARI_CFG_DIV_32	0x0000000080000000UL -#define SAFARI_CFG_DIV_MASK	0x00000000C0000000UL - -static unsigned long read_safari_cfg(void) -{ -	unsigned long ret; - -	__asm__ __volatile__("ldxa	[%%g0] %1, %0" -			     : "=&r" (ret) -			     : "i" (ASI_SAFARI_CONFIG)); -	return ret; -} - -static void write_safari_cfg(unsigned long val) -{ -	__asm__ __volatile__("stxa	%0, [%%g0] %1\n\t" -			     "membar	#Sync" -			     : /* no outputs */ -			     : "r" (val), "i" (ASI_SAFARI_CONFIG) -			     : "memory"); -} - -static unsigned long get_current_freq(unsigned int cpu, unsigned long safari_cfg) -{ -	unsigned long clock_tick = sparc64_get_clock_tick(cpu) / 1000; -	unsigned long ret; - -	switch (safari_cfg & SAFARI_CFG_DIV_MASK) { -	case SAFARI_CFG_DIV_1: -		ret = clock_tick / 1; -		break; -	case SAFARI_CFG_DIV_2: -		ret = clock_tick / 2; -		break; -	case SAFARI_CFG_DIV_32: -		ret = clock_tick / 32; -		break; -	default: -		BUG(); -	} - -	return ret; -} - -static unsigned int us3_freq_get(unsigned int cpu) -{ -	cpumask_t cpus_allowed; -	unsigned long reg; -	unsigned int ret; - -	if (!cpu_online(cpu)) -		return 0; - -	cpumask_copy(&cpus_allowed, tsk_cpus_allowed(current)); -	set_cpus_allowed_ptr(current, cpumask_of(cpu)); - -	reg = read_safari_cfg(); -	ret = get_current_freq(cpu, reg); - -	set_cpus_allowed_ptr(current, &cpus_allowed); - -	return ret; -} - -static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index) -{ -	unsigned long new_bits, new_freq, reg; -	cpumask_t cpus_allowed; -	struct cpufreq_freqs freqs; - -	if (!cpu_online(cpu)) -		return; - -	cpumask_copy(&cpus_allowed, tsk_cpus_allowed(current)); -	set_cpus_allowed_ptr(current, cpumask_of(cpu)); - -	new_freq = sparc64_get_clock_tick(cpu) / 1000; -	switch (index) { -	case 0: -		new_bits = SAFARI_CFG_DIV_1; -		new_freq /= 1; -		break; -	case 1: -		new_bits = SAFARI_CFG_DIV_2; -		new_freq /= 2; -		break; -	case 2: -		new_bits = SAFARI_CFG_DIV_32; -		new_freq /= 32; -		break; - -	default: -		BUG(); -	} - -	reg = read_safari_cfg(); - -	freqs.old = get_current_freq(cpu, reg); -	freqs.new = new_freq; -	freqs.cpu = cpu; -	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - -	reg &= ~SAFARI_CFG_DIV_MASK; -	reg |= new_bits; -	write_safari_cfg(reg); - -	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - -	set_cpus_allowed_ptr(current, &cpus_allowed); -} - -static int us3_freq_target(struct cpufreq_policy *policy, -			  unsigned int target_freq, -			  unsigned int relation) -{ -	unsigned int new_index = 0; - -	if (cpufreq_frequency_table_target(policy, -					   &us3_freq_table[policy->cpu].table[0], -					   target_freq, -					   relation, -					   &new_index)) -		return -EINVAL; - -	us3_set_cpu_divider_index(policy->cpu, new_index); - -	return 0; -} - -static int us3_freq_verify(struct cpufreq_policy *policy) -{ -	return cpufreq_frequency_table_verify(policy, -					      &us3_freq_table[policy->cpu].table[0]); -} - -static int __init us3_freq_cpu_init(struct cpufreq_policy *policy) -{ -	unsigned int cpu = policy->cpu; -	unsigned long clock_tick = sparc64_get_clock_tick(cpu) / 1000; -	struct cpufreq_frequency_table *table = -		&us3_freq_table[cpu].table[0]; - -	table[0].index = 0; -	table[0].frequency = clock_tick / 1; -	table[1].index = 1; -	table[1].frequency = clock_tick / 2; -	table[2].index = 2; -	table[2].frequency = clock_tick / 32; -	table[3].index = 0; -	table[3].frequency = CPUFREQ_TABLE_END; - -	policy->cpuinfo.transition_latency = 0; -	policy->cur = clock_tick; - -	return cpufreq_frequency_table_cpuinfo(policy, table); -} - -static int us3_freq_cpu_exit(struct cpufreq_policy *policy) -{ -	if (cpufreq_us3_driver) -		us3_set_cpu_divider_index(policy->cpu, 0); - -	return 0; -} - -static int __init us3_freq_init(void) -{ -	unsigned long manuf, impl, ver; -	int ret; - -	if (tlb_type != cheetah && tlb_type != cheetah_plus) -		return -ENODEV; - -	__asm__("rdpr %%ver, %0" : "=r" (ver)); -	manuf = ((ver >> 48) & 0xffff); -	impl  = ((ver >> 32) & 0xffff); - -	if (manuf == CHEETAH_MANUF && -	    (impl == CHEETAH_IMPL || -	     impl == CHEETAH_PLUS_IMPL || -	     impl == JAGUAR_IMPL || -	     impl == PANTHER_IMPL)) { -		struct cpufreq_driver *driver; - -		ret = -ENOMEM; -		driver = kzalloc(sizeof(struct cpufreq_driver), GFP_KERNEL); -		if (!driver) -			goto err_out; - -		us3_freq_table = kzalloc( -			(NR_CPUS * sizeof(struct us3_freq_percpu_info)), -			GFP_KERNEL); -		if (!us3_freq_table) -			goto err_out; - -		driver->init = us3_freq_cpu_init; -		driver->verify = us3_freq_verify; -		driver->target = us3_freq_target; -		driver->get = us3_freq_get; -		driver->exit = us3_freq_cpu_exit; -		driver->owner = THIS_MODULE, -		strcpy(driver->name, "UltraSPARC-III"); - -		cpufreq_us3_driver = driver; -		ret = cpufreq_register_driver(driver); -		if (ret) -			goto err_out; - -		return 0; - -err_out: -		if (driver) { -			kfree(driver); -			cpufreq_us3_driver = NULL; -		} -		kfree(us3_freq_table); -		us3_freq_table = NULL; -		return ret; -	} - -	return -ENODEV; -} - -static void __exit us3_freq_exit(void) -{ -	if (cpufreq_us3_driver) { -		cpufreq_unregister_driver(cpufreq_us3_driver); -		kfree(cpufreq_us3_driver); -		cpufreq_us3_driver = NULL; -		kfree(us3_freq_table); -		us3_freq_table = NULL; -	} -} - -MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); -MODULE_DESCRIPTION("cpufreq driver for UltraSPARC-III"); -MODULE_LICENSE("GPL"); - -module_init(us3_freq_init); -module_exit(us3_freq_exit); |