cregit-Linux how code gets into the kernel

Release 4.14 drivers/cpufreq/pasemi-cpufreq.c

Directory: drivers/cpufreq
/*
 * Copyright (C) 2007 PA Semi, Inc
 *
 * Authors: Egor Martovetsky <egor@pasemi.com>
 *          Olof Johansson <olof@lixom.net>
 *
 * Maintained by: Olof Johansson <olof@lixom.net>
 *
 * Based on arch/powerpc/platforms/cell/cbe_cpufreq.c:
 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <linux/cpufreq.h>
#include <linux/timer.h>
#include <linux/module.h>
#include <linux/of_address.h>

#include <asm/hw_irq.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/time.h>
#include <asm/smp.h>


#define SDCASR_REG		0x0100

#define SDCASR_REG_STRIDE	0x1000

#define SDCPWR_CFGA0_REG	0x0100

#define SDCPWR_PWST0_REG	0x0000

#define SDCPWR_GIZTIME_REG	0x0440

/* SDCPWR_GIZTIME_REG fields */

#define SDCPWR_GIZTIME_GR	0x80000000

#define SDCPWR_GIZTIME_LONGLOCK	0x000000ff

/* Offset of ASR registers from SDC base */

#define SDCASR_OFFSET		0x120000


static void __iomem *sdcpwr_mapbase;

static void __iomem *sdcasr_mapbase;

/* Current astate, is used when waking up from power savings on
 * one core, in case the other core has switched states during
 * the idle time.
 */

static int current_astate;

/* We support 5(A0-A4) power states excluding turbo(A5-A6) modes */

static struct cpufreq_frequency_table pas_freqs[] = {
	{0, 0,	0},
	{0, 1,	0},
	{0, 2,	0},
	{0, 3,	0},
	{0, 4,	0},
	{0, 0,	CPUFREQ_TABLE_END},
};

/*
 * hardware specific functions
 */


static int get_astate_freq(int astate) { u32 ret; ret = in_le32(sdcpwr_mapbase + SDCPWR_CFGA0_REG + (astate * 0x10)); return ret & 0x3f; }

Contributors

PersonTokensPropCommitsCommitProp
Olof Johansson32100.00%1100.00%
Total32100.00%1100.00%


static int get_cur_astate(int cpu) { u32 ret; ret = in_le32(sdcpwr_mapbase + SDCPWR_PWST0_REG); ret = (ret >> (cpu * 4)) & 0x7; return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Olof Johansson38100.00%1100.00%
Total38100.00%1100.00%


static int get_gizmo_latency(void) { u32 giztime, ret; giztime = in_le32(sdcpwr_mapbase + SDCPWR_GIZTIME_REG); /* just provide the upper bound */ if (giztime & SDCPWR_GIZTIME_GR) ret = (giztime & SDCPWR_GIZTIME_LONGLOCK) * 128000; else ret = (giztime & SDCPWR_GIZTIME_LONGLOCK) * 1000; return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Olof Johansson53100.00%1100.00%
Total53100.00%1100.00%


static void set_astate(int cpu, unsigned int astate) { unsigned long flags; /* Return if called before init has run */ if (unlikely(!sdcasr_mapbase)) return; local_irq_save(flags); out_le32(sdcasr_mapbase + SDCASR_REG + SDCASR_REG_STRIDE*cpu, astate); local_irq_restore(flags); }

Contributors

PersonTokensPropCommitsCommitProp
Olof Johansson4896.00%150.00%
Ingo Molnar24.00%150.00%
Total50100.00%2100.00%


int check_astate(void) { return get_cur_astate(hard_smp_processor_id()); }

Contributors

PersonTokensPropCommitsCommitProp
Olof Johansson14100.00%1100.00%
Total14100.00%1100.00%


void restore_astate(int cpu) { set_astate(cpu, current_astate); }

Contributors

PersonTokensPropCommitsCommitProp
Olof Johansson15100.00%1100.00%
Total15100.00%1100.00%

/* * cpufreq functions */
static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy) { struct cpufreq_frequency_table *pos; const u32 *max_freqp; u32 max_freq; int cur_astate; struct resource res; struct device_node *cpu, *dn; int err = -ENODEV; cpu = of_get_cpu_node(policy->cpu, NULL); if (!cpu) goto out; dn = of_find_compatible_node(NULL, NULL, "1682m-sdc"); if (!dn) dn = of_find_compatible_node(NULL, NULL, "pasemi,pwrficient-sdc"); if (!dn) goto out; err = of_address_to_resource(dn, 0, &res); of_node_put(dn); if (err) goto out; sdcasr_mapbase = ioremap(res.start + SDCASR_OFFSET, 0x2000); if (!sdcasr_mapbase) { err = -EINVAL; goto out; } dn = of_find_compatible_node(NULL, NULL, "1682m-gizmo"); if (!dn) dn = of_find_compatible_node(NULL, NULL, "pasemi,pwrficient-gizmo"); if (!dn) { err = -ENODEV; goto out_unmap_sdcasr; } err = of_address_to_resource(dn, 0, &res); of_node_put(dn); if (err) goto out_unmap_sdcasr; sdcpwr_mapbase = ioremap(res.start, 0x1000); if (!sdcpwr_mapbase) { err = -EINVAL; goto out_unmap_sdcasr; } pr_debug("init cpufreq on CPU %d\n", policy->cpu); max_freqp = of_get_property(cpu, "clock-frequency", NULL); if (!max_freqp) { err = -EINVAL; goto out_unmap_sdcpwr; } /* we need the freq in kHz */ max_freq = *max_freqp / 1000; pr_debug("max clock-frequency is at %u kHz\n", max_freq); pr_debug("initializing frequency table\n"); /* initialize frequency table */ cpufreq_for_each_entry(pos, pas_freqs) { pos->frequency = get_astate_freq(pos->driver_data) * 100000; pr_debug("%d: %d\n", (int)(pos - pas_freqs), pos->frequency); } cur_astate = get_cur_astate(policy->cpu); pr_debug("current astate is at %d\n",cur_astate); policy->cur = pas_freqs[cur_astate].frequency; ppc_proc_freq = policy->cur * 1000ul; return cpufreq_generic_init(policy, pas_freqs, get_gizmo_latency()); out_unmap_sdcpwr: iounmap(sdcpwr_mapbase); out_unmap_sdcasr: iounmap(sdcasr_mapbase); out: return err; }

Contributors

PersonTokensPropCommitsCommitProp
Olof Johansson36289.83%342.86%
Stratos Karafotis256.20%114.29%
Stephen Rothwell112.73%114.29%
Viresh Kumar51.24%228.57%
Total403100.00%7100.00%


static int pas_cpufreq_cpu_exit(struct cpufreq_policy *policy) { /* * We don't support CPU hotplug. Don't unmap after the system * has already made it to a running state. */ if (system_state >= SYSTEM_RUNNING) return 0; if (sdcasr_mapbase) iounmap(sdcasr_mapbase); if (sdcpwr_mapbase) iounmap(sdcpwr_mapbase); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Olof Johansson3276.19%133.33%
Steven Rostedt819.05%133.33%
Thomas Gleixner24.76%133.33%
Total42100.00%3100.00%


static int pas_cpufreq_target(struct cpufreq_policy *policy, unsigned int pas_astate_new) { int i; pr_debug("setting frequency for cpu %d to %d kHz, 1/%d of max frequency\n", policy->cpu, pas_freqs[pas_astate_new].frequency, pas_freqs[pas_astate_new].driver_data); current_astate = pas_astate_new; for_each_online_cpu(i) set_astate(i, pas_astate_new); ppc_proc_freq = pas_freqs[pas_astate_new].frequency * 1000ul; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Olof Johansson6390.00%240.00%
Viresh Kumar710.00%360.00%
Total70100.00%5100.00%

static struct cpufreq_driver pas_cpufreq_driver = { .name = "pas-cpufreq", .flags = CPUFREQ_CONST_LOOPS, .init = pas_cpufreq_cpu_init, .exit = pas_cpufreq_cpu_exit, .verify = cpufreq_generic_frequency_table_verify, .target_index = pas_cpufreq_target, .attr = cpufreq_generic_attr, }; /* * module init and destoy */
static int __init pas_cpufreq_init(void) { if (!of_machine_is_compatible("PA6T-1682M") && !of_machine_is_compatible("pasemi,pwrficient")) return -ENODEV; return cpufreq_register_driver(&pas_cpufreq_driver); }

Contributors

PersonTokensPropCommitsCommitProp
Olof Johansson3294.12%266.67%
Grant C. Likely25.88%133.33%
Total34100.00%3100.00%


static void __exit pas_cpufreq_exit(void) { cpufreq_unregister_driver(&pas_cpufreq_driver); }

Contributors

PersonTokensPropCommitsCommitProp
Olof Johansson15100.00%1100.00%
Total15100.00%1100.00%

module_init(pas_cpufreq_init); module_exit(pas_cpufreq_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Egor Martovetsky <egor@pasemi.com>, Olof Johansson <olof@lixom.net>");

Overall Contributors

PersonTokensPropCommitsCommitProp
Olof Johansson88491.42%422.22%
Viresh Kumar272.79%633.33%
Stratos Karafotis252.59%15.56%
Stephen Rothwell111.14%15.56%
Steven Rostedt80.83%15.56%
Rob Herring30.31%15.56%
Paul Gortmaker30.31%15.56%
Grant C. Likely20.21%15.56%
Ingo Molnar20.21%15.56%
Thomas Gleixner20.21%15.56%
Total967100.00%18100.00%
Directory: drivers/cpufreq
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.