/*
 *  Copyright (C) 2002 - 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
 *  and                       Markus Demleitner <msdemlei@cl.uni-heidelberg.de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This driver adds basic cpufreq support for SMU & 970FX based G5 Macs,
 * that is iMac G5 and latest single CPU desktop.
 */

#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/cpufreq.h>
#include <linux/init.h>
#include <linux/completion.h>
#include <linux/mutex.h>
#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/irq.h>
#include <asm/sections.h>
#include <asm/cputable.h>
#include <asm/time.h>
#include <asm/smu.h>
#include <asm/pmac_pfunc.h>

#undef DEBUG

#ifdef DEBUG
#define DBG(fmt...) printk(fmt)
#else
#define DBG(fmt...)
#endif

/* see 970FX user manual */

#define SCOM_PCR 0x0aa001			/* PCR scom addr */

#define PCR_HILO_SELECT		0x80000000U	/* 1 = PCR, 0 = PCRH */
#define PCR_SPEED_FULL		0x00000000U	/* 1:1 speed value */
#define PCR_SPEED_HALF		0x00020000U	/* 1:2 speed value */
#define PCR_SPEED_QUARTER	0x00040000U	/* 1:4 speed value */
#define PCR_SPEED_MASK		0x000e0000U	/* speed mask */
#define PCR_SPEED_SHIFT		17
#define PCR_FREQ_REQ_VALID	0x00010000U	/* freq request valid */
#define PCR_VOLT_REQ_VALID	0x00008000U	/* volt request valid */
#define PCR_TARGET_TIME_MASK	0x00006000U	/* target time */
#define PCR_STATLAT_MASK	0x00001f00U	/* STATLAT value */
#define PCR_SNOOPLAT_MASK	0x000000f0U	/* SNOOPLAT value */
#define PCR_SNOOPACC_MASK	0x0000000fU	/* SNOOPACC value */

#define SCOM_PSR 0x408001			/* PSR scom addr */
/* warning: PSR is a 64 bits register */
#define PSR_CMD_RECEIVED	0x2000000000000000U   /* command received */
#define PSR_CMD_COMPLETED	0x1000000000000000U   /* command completed */
#define PSR_CUR_SPEED_MASK	0x0300000000000000U   /* current speed */
#define PSR_CUR_SPEED_SHIFT	(56)

/*
 * The G5 only supports two frequencies (Quarter speed is not supported)
 */
#define CPUFREQ_HIGH                  0
#define CPUFREQ_LOW                   1

static struct cpufreq_frequency_table g5_cpu_freqs[] = {
	{CPUFREQ_HIGH, 		0},
	{CPUFREQ_LOW,		0},
	{0,			CPUFREQ_TABLE_END},
};

static struct freq_attr* g5_cpu_freqs_attr[] = {
	&cpufreq_freq_attr_scaling_available_freqs,
	NULL,
};

/* Power mode data is an array of the 32 bits PCR values to use for
 * the various frequencies, retrieved from the device-tree
 */
static u32 *g5_pmode_data;
static int g5_pmode_max;
static int g5_pmode_cur;

static void (*g5_switch_volt)(int speed_mode);
static int (*g5_switch_freq)(int speed_mode);
static int (*g5_query_freq)(void);

static DEFINE_MUTEX(g5_switch_mutex);


static struct smu_sdbp_fvt *g5_fvt_table;	/* table of op. points */
static int g5_fvt_count;			/* number of op. points */
static int g5_fvt_cur;				/* current op. point */

/*
 * SMU based voltage switching for Neo2 platforms
 */

static void g5_smu_switch_volt(int speed_mode)
{
	struct smu_simple_cmd	cmd;

	DECLARE_COMPLETION(comp);
	smu_queue_simple(&cmd, SMU_CMD_POWER_COMMAND, 8, smu_done_complete,
			 &comp, 'V', 'S', 'L', 'E', 'W',
			 0xff, g5_fvt_cur+1, speed_mode);
	wait_for_completion(&comp);
}

/*
 * Platform function based voltage/vdnap switching for Neo2
 */

static struct pmf_function *pfunc_set_vdnap0;
static struct pmf_function *pfunc_vdnap0_complete;

static void g5_vdnap_switch_volt(int speed_mode)
{
	struct pmf_args args;
	u32 slew, done = 0;
	unsigned long timeout;

	slew = (speed_mode == CPUFREQ_LOW) ? 1 : 0;
	args.count = 1;
	args.u[0].p = &slew;

	pmf_call_one(pfunc_set_vdnap0, &args);

	/* It's an irq GPIO so we should be able to just block here,
	 * I'll do that later after I've properly tested the IRQ code for
	 * platform functions
	 */
	timeout = jiffies + HZ/10;
	while(!time_after(jiffies, timeout)) {
		args.count = 1;
		args.u[0].p = &done;
		pmf_call_one(pfunc_vdnap0_complete, &args);
		if (done)
			break;
		msleep(1);
	}
	if (done == 0)
		printk(KERN_WARNING "cpufreq: Timeout in clock slewing !\n");
}


/*
 * SCOM based frequency switching for 970FX rev3
 */
static int g5_scom_switch_freq(int speed_mode)
{
	unsigned long flags;
	int to;

	/* If frequency is going up, first ramp up the voltage */
	if (speed_mode < g5_pmode_cur)
		g5_switch_volt(speed_mode);

	local_irq_save(flags);

	/* Clear PCR high */
	scom970_write(SCOM_PCR, 0);
	/* Clear PCR low */
       	scom970_write(SCOM_PCR, PCR_HILO_SELECT | 0);
	/* Set PCR low */
	scom970_write(SCOM_PCR, PCR_HILO_SELECT |
		      g5_pmode_data[speed_mode]);

	/* Wait for completion */
	for (to = 0; to < 10; to++) {
		unsigned long psr = scom970_read(SCOM_PSR);

		if ((psr & PSR_CMD_RECEIVED) == 0 &&
		    (((psr >> PSR_CUR_SPEED_SHIFT) ^
		      (g5_pmode_data[speed_mode] >> PCR_SPEED_SHIFT)) & 0x3)
		    == 0)
			break;
		if (psr & PSR_CMD_COMPLETED)
			break;
		udelay(100);
	}

	local_irq_restore(flags);

	/* If frequency is going down, last ramp the voltage */
	if (speed_mode > g5_pmode_cur)
		g5_switch_volt(speed_mode);

	g5_pmode_cur = speed_mode;
	ppc_proc_freq = g5_cpu_freqs[speed_mode].frequency * 1000ul;

	return 0;
}

static int g5_scom_query_freq(void)
{
	unsigned long psr = scom970_read(SCOM_PSR);
	int i;

	for (i = 0; i <= g5_pmode_max; i++)
		if ((((psr >> PSR_CUR_SPEED_SHIFT) ^
		      (g5_pmode_data[i] >> PCR_SPEED_SHIFT)) & 0x3) == 0)
			break;
	return i;
}

/*
 * Platform function based voltage switching for PowerMac7,2 & 7,3
 */

static struct pmf_function *pfunc_cpu0_volt_high;
static struct pmf_function *pfunc_cpu0_volt_low;
static struct pmf_function *pfunc_cpu1_volt_high;
static struct pmf_function *pfunc_cpu1_volt_low;

static void g5_pfunc_switch_volt(int speed_mode)
{
	if (speed_mode == CPUFREQ_HIGH) {
		if (pfunc_cpu0_volt_high)
			pmf_call_one(pfunc_cpu0_volt_high, NULL);
		if (pfunc_cpu1_volt_high)
			pmf_call_one(pfunc_cpu1_volt_high, NULL);
	} else {
		if (pfunc_cpu0_volt_low)
			pmf_call_one(pfunc_cpu0_volt_low, NULL);
		if (pfunc_cpu1_volt_low)
			pmf_call_one(pfunc_cpu1_volt_low, NULL);
	}
	msleep(10); /* should be faster , to fix */
}

/*
 * Platform function based frequency switching for PowerMac7,2 & 7,3
 */

static struct pmf_function *pfunc_cpu_setfreq_high;
static struct pmf_function *pfunc_cpu_setfreq_low;
static struct pmf_function *pfunc_cpu_getfreq;
static struct pmf_function *pfunc_slewing_done;;

static int g5_pfunc_switch_freq(int speed_mode)
{
	struct pmf_args args;
	u32 done = 0;
	unsigned long timeout;

	/* If frequency is going up, first ramp up the voltage */
	if (speed_mode < g5_pmode_cur)
		g5_switch_volt(speed_mode);

	/* Do it */
	if (speed_mode == CPUFREQ_HIGH)
		pmf_call_one(pfunc_cpu_setfreq_high, NULL);
	else
		pmf_call_one(pfunc_cpu_setfreq_low, NULL);

	/* It's an irq GPIO so we should be able to just block here,
	 * I'll do that later after I've properly tested the IRQ code for
	 * platform functions
	 */
	timeout = jiffies + HZ/10;
	while(!time_after(jiffies, timeout)) {
		args.count = 1;
		args.u[0].p = &done;
		pmf_call_one(pfunc_slewing_done, &args);
		if (done)
			break;
		msleep(1);
	}
	if (done == 0)
		printk(KERN_WARNING "cpufreq: Timeout in clock slewing !\n");

	/* If frequency is going down, last ramp the voltage */
	if (speed_mode > g5_pmode_cur)
		g5_switch_volt(speed_mode);

	g5_pmode_cur = speed_mode;
	ppc_proc_freq = g5_cpu_freqs[speed_mode].frequency * 1000ul;

	return 0;
}

static int g5_pfunc_query_freq(void)
{
	struct pmf_args args;
	u32 val = 0;

	args.count = 1;
	args.u[0].p = &val;
	pmf_call_one(pfunc_cpu_getfreq, &args);
	return val ? CPUFREQ_HIGH : CPUFREQ_LOW;
}

/*
 * Fake voltage switching for platforms with missing support
 */

static void g5_dummy_switch_volt(int speed_mode)
{
}

/*
 * Common interface to the cpufreq core
 */

static int g5_cpufreq_verify(struct cpufreq_policy *policy)
{
	return cpufreq_frequency_table_verify(policy, g5_cpu_freqs);
}

static int g5_cpufreq_target(struct cpufreq_policy *policy,
	unsigned int target_freq, unsigned int relation)
{
	unsigned int newstate = 0;
	struct cpufreq_freqs freqs;
	int rc;

	if (cpufreq_frequency_table_target(policy, g5_cpu_freqs,
			target_freq, relation, &newstate))
		return -EINVAL;

	if (g5_pmode_cur == newstate)
		return 0;

	mutex_lock(&g5_switch_mutex);

	freqs.old = g5_cpu_freqs[g5_pmode_cur].frequency;
	freqs.new = g5_cpu_freqs[newstate].frequency;
	freqs.cpu = 0;

	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
	rc = g5_switch_freq(newstate);
	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);

	mutex_unlock(&g5_switch_mutex);

	return rc;
}

static unsigned int g5_cpufreq_get_speed(unsigned int cpu)
{
	return g5_cpu_freqs[g5_pmode_cur].frequency;
}

static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy)
{
	if (policy->cpu != 0)
		return -ENODEV;

	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
	policy->cur = g5_cpu_freqs[g5_query_freq()].frequency;
	policy->cpus = cpu_possible_map;
	cpufreq_frequency_table_get_attr(g5_cpu_freqs, policy->cpu);

	return cpufreq_frequency_table_cpuinfo(policy,
		g5_cpu_freqs);
}


static struct cpufreq_driver g5_cpufreq_driver = {
	.name		= "powermac",
	.owner		= THIS_MODULE,
	.flags		= CPUFREQ_CONST_LOOPS,
	.init		= g5_cpufreq_cpu_init,
	.verify		= g5_cpufreq_verify,
	.target		= g5_cpufreq_target,
	.get		= g5_cpufreq_get_speed,
	.attr 		= g5_cpu_freqs_attr,
};


static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
{
	struct device_node *cpunode;
	unsigned int psize, ssize;
	unsigned long max_freq;
	char *freq_method, *volt_method;
	u32 *valp, pvr_hi;
	int use_volts_vdnap = 0;
	int use_volts_smu = 0;
	int rc = -ENODEV;

	/* Check supported platforms */
	if (machine_is_compatible("PowerMac8,1") ||
	    machine_is_compatible("PowerMac8,2") ||
	    machine_is_compatible("PowerMac9,1"))
		use_volts_smu = 1;
	else if (machine_is_compatible("PowerMac11,2"))
		use_volts_vdnap = 1;
	else
		return -ENODEV;

	/* Get first CPU node */
	for (cpunode = NULL;
	     (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
		u32 *reg =
			(u32 *)get_property(cpunode, "reg", NULL);
		if (reg == NULL || (*reg) != 0)
			continue;
		if (!strcmp(cpunode->type, "cpu"))
			break;
	}
	if (cpunode == NULL) {
		printk(KERN_ERR "cpufreq: Can't find any CPU 0 node\n");
		return -ENODEV;
	}

	/* Check 970FX for now */
	valp = (u32 *)get_property(cpunode, "cpu-version", NULL);
	if (!valp) {
		DBG("No cpu-version property !\n");
		goto bail_noprops;
	}
	pvr_hi = (*valp) >> 16;
	if (pvr_hi != 0x3c && pvr_hi != 0x44) {
		printk(KERN_ERR "cpufreq: Unsupported CPU version\n");
		goto bail_noprops;
	}

	/* Look for the powertune data in the device-tree */
	g5_pmode_data = (u32 *)get_property(cpunode, "power-mode-data",&psize);
	if (!g5_pmode_data) {
		DBG("No power-mode-data !\n");
		goto bail_noprops;
	}
	g5_pmode_max = psize / sizeof(u32) - 1;

	if (use_volts_smu) {
		struct smu_sdbp_header *shdr;

		/* Look for the FVT table */
		shdr = smu_get_sdb_partition(SMU_SDB_FVT_ID, NULL);
		if (!shdr)
			goto bail_noprops;
		g5_fvt_table = (struct smu_sdbp_fvt *)&shdr[1];
		ssize = (shdr->len * sizeof(u32)) -
			sizeof(struct smu_sdbp_header);
		g5_fvt_count = ssize / sizeof(struct smu_sdbp_fvt);
		g5_fvt_cur = 0;

		/* Sanity checking */
		if (g5_fvt_count < 1 || g5_pmode_max < 1)
			goto bail_noprops;

		g5_switch_volt = g5_smu_switch_volt;
		volt_method = "SMU";
	} else if (use_volts_vdnap) {
		struct device_node *root;

		root = of_find_node_by_path("/");
		if (root == NULL) {
			printk(KERN_ERR "cpufreq: Can't find root of "
			       "device tree\n");
			goto bail_noprops;
		}
		pfunc_set_vdnap0 = pmf_find_function(root, "set-vdnap0");
		pfunc_vdnap0_complete =
			pmf_find_function(root, "slewing-done");
		if (pfunc_set_vdnap0 == NULL ||
		    pfunc_vdnap0_complete == NULL) {
			printk(KERN_ERR "cpufreq: Can't find required "
			       "platform function\n");
			goto bail_noprops;
		}

		g5_switch_volt = g5_vdnap_switch_volt;
		volt_method = "GPIO";
	} else {
		g5_switch_volt = g5_dummy_switch_volt;
		volt_method = "none";
	}

	/*
	 * From what I see, clock-frequency is always the maximal frequency.
	 * The current driver can not slew sysclk yet, so we really only deal
	 * with powertune steps for now. We also only implement full freq and
	 * half freq in this version. So far, I haven't yet seen a machine
	 * supporting anything else.
	 */
	valp = (u32 *)get_property(cpunode, "clock-frequency", NULL);
	if (!valp)
		return -ENODEV;
	max_freq = (*valp)/1000;
	g5_cpu_freqs[0].frequency = max_freq;
	g5_cpu_freqs[1].frequency = max_freq/2;

	/* Set callbacks */
	g5_switch_freq = g5_scom_switch_freq;
	g5_query_freq = g5_scom_query_freq;
	freq_method = "SCOM";

	/* Force apply current frequency to make sure everything is in
	 * sync (voltage is right for example). Firmware may leave us with
	 * a strange setting ...
	 */
	g5_switch_volt(CPUFREQ_HIGH);
	msleep(10);
	g5_pmode_cur = -1;
	g5_switch_freq(g5_query_freq());

	printk(KERN_INFO "Registering G5 CPU frequency driver\n");
	printk(KERN_INFO "Frequency method: %s, Voltage method: %s\n",
	       freq_method, volt_method);
	printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Cur: %d MHz\n",
		g5_cpu_freqs[1].frequency/1000,
		g5_cpu_freqs[0].frequency/1000,
		g5_cpu_freqs[g5_pmode_cur].frequency/1000);

	rc = cpufreq_register_driver(&g5_cpufreq_driver);

	/* We keep the CPU node on hold... hopefully, Apple G5 don't have
	 * hotplug CPU with a dynamic device-tree ...
	 */
	return rc;

 bail_noprops:
	of_node_put(cpunode);

	return rc;
}

static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
{
	struct device_node *cpuid = NULL, *hwclock = NULL, *cpunode = NULL;
	u8 *eeprom = NULL;
	u32 *valp;
	u64 max_freq, min_freq, ih, il;
	int has_volt = 1, rc = 0;

	/* Get first CPU node */
	for (cpunode = NULL;
	     (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
		if (!strcmp(cpunode->type, "cpu"))
			break;
	}
	if (cpunode == NULL) {
		printk(KERN_ERR "cpufreq: Can't find any CPU node\n");
		return -ENODEV;
	}

	/* Lookup the cpuid eeprom node */
        cpuid = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/cpuid@a0");
	if (cpuid != NULL)
		eeprom = (u8 *)get_property(cpuid, "cpuid", NULL);
	if (eeprom == NULL) {
		printk(KERN_ERR "cpufreq: Can't find cpuid EEPROM !\n");
		rc = -ENODEV;
		goto bail;
	}

	/* Lookup the i2c hwclock */
	for (hwclock = NULL;
	     (hwclock = of_find_node_by_name(hwclock, "i2c-hwclock")) != NULL;){
		char *loc = get_property(hwclock, "hwctrl-location", NULL);
		if (loc == NULL)
			continue;
		if (strcmp(loc, "CPU CLOCK"))
			continue;
		if (!get_property(hwclock, "platform-get-frequency", NULL))
			continue;
		break;
	}
	if (hwclock == NULL) {
		printk(KERN_ERR "cpufreq: Can't find i2c clock chip !\n");
		rc = -ENODEV;
		goto bail;
	}

	DBG("cpufreq: i2c clock chip found: %s\n", hwclock->full_name);

	/* Now get all the platform functions */
	pfunc_cpu_getfreq =
		pmf_find_function(hwclock, "get-frequency");
	pfunc_cpu_setfreq_high =
		pmf_find_function(hwclock, "set-frequency-high");
	pfunc_cpu_setfreq_low =
		pmf_find_function(hwclock, "set-frequency-low");
	pfunc_slewing_done =
		pmf_find_function(hwclock, "slewing-done");
	pfunc_cpu0_volt_high =
		pmf_find_function(hwclock, "set-voltage-high-0");
	pfunc_cpu0_volt_low =
		pmf_find_function(hwclock, "set-voltage-low-0");
	pfunc_cpu1_volt_high =
		pmf_find_function(hwclock, "set-voltage-high-1");
	pfunc_cpu1_volt_low =
		pmf_find_function(hwclock, "set-voltage-low-1");

	/* Check we have minimum requirements */
	if (pfunc_cpu_getfreq == NULL || pfunc_cpu_setfreq_high == NULL ||
	    pfunc_cpu_setfreq_low == NULL || pfunc_slewing_done == NULL) {
		printk(KERN_ERR "cpufreq: Can't find platform functions !\n");
		rc = -ENODEV;
		goto bail;
	}

	/* Check that we have complete sets */
	if (pfunc_cpu0_volt_high == NULL || pfunc_cpu0_volt_low == NULL) {
		pmf_put_function(pfunc_cpu0_volt_high);
		pmf_put_function(pfunc_cpu0_volt_low);
		pfunc_cpu0_volt_high = pfunc_cpu0_volt_low = NULL;
		has_volt = 0;
	}
	if (!has_volt ||
	    pfunc_cpu1_volt_high == NULL || pfunc_cpu1_volt_low == NULL) {
		pmf_put_function(pfunc_cpu1_volt_high);
		pmf_put_function(pfunc_cpu1_volt_low);
		pfunc_cpu1_volt_high = pfunc_cpu1_volt_low = NULL;
	}

	/* Note: The device tree also contains a "platform-set-values"
	 * function for which I haven't quite figured out the usage. It
	 * might have to be called on init and/or wakeup, I'm not too sure
	 * but things seem to work fine without it so far ...
	 */

	/* Get max frequency from device-tree */
	valp = (u32 *)get_property(cpunode, "clock-frequency", NULL);
	if (!valp) {
		printk(KERN_ERR "cpufreq: Can't find CPU frequency !\n");
		rc = -ENODEV;
		goto bail;
	}

	max_freq = (*valp)/1000;

	/* Now calculate reduced frequency by using the cpuid input freq
	 * ratio. This requires 64 bits math unless we are willing to lose
	 * some precision
	 */
	ih = *((u32 *)(eeprom + 0x10));
	il = *((u32 *)(eeprom + 0x20));
	min_freq = 0;
	if (ih != 0 && il != 0)
		min_freq = (max_freq * il) / ih;

	/* Sanity check */
	if (min_freq >= max_freq || min_freq < 1000) {
		printk(KERN_ERR "cpufreq: Can't calculate low frequency !\n");
		rc = -ENODEV;
		goto bail;
	}
	g5_cpu_freqs[0].frequency = max_freq;
	g5_cpu_freqs[1].frequency = min_freq;

	/* Set callbacks */
	g5_switch_volt = g5_pfunc_switch_volt;
	g5_switch_freq = g5_pfunc_switch_freq;
	g5_query_freq = g5_pfunc_query_freq;

	/* Force apply current frequency to make sure everything is in
	 * sync (voltage is right for example). Firmware may leave us with
	 * a strange setting ...
	 */
	g5_switch_volt(CPUFREQ_HIGH);
	msleep(10);
	g5_pmode_cur = -1;
	g5_switch_freq(g5_query_freq());

	printk(KERN_INFO "Registering G5 CPU frequency driver\n");
	printk(KERN_INFO "Frequency method: i2c/pfunc, "
	       "Voltage method: %s\n", has_volt ? "i2c/pfunc" : "none");
	printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Cur: %d MHz\n",
		g5_cpu_freqs[1].frequency/1000,
		g5_cpu_freqs[0].frequency/1000,
		g5_cpu_freqs[g5_pmode_cur].frequency/1000);

	rc = cpufreq_register_driver(&g5_cpufreq_driver);
 bail:
	if (rc != 0) {
		pmf_put_function(pfunc_cpu_getfreq);
		pmf_put_function(pfunc_cpu_setfreq_high);
		pmf_put_function(pfunc_cpu_setfreq_low);
		pmf_put_function(pfunc_slewing_done);
		pmf_put_function(pfunc_cpu0_volt_high);
		pmf_put_function(pfunc_cpu0_volt_low);
		pmf_put_function(pfunc_cpu1_volt_high);
		pmf_put_function(pfunc_cpu1_volt_low);
	}
	of_node_put(hwclock);
	of_node_put(cpuid);
	of_node_put(cpunode);

	return rc;
}

static int __init g5_rm31_cpufreq_init(struct device_node *cpus)
{
	/* NYI */
	return 0;
}

static int __init g5_cpufreq_init(void)
{
	struct device_node *cpus;
	int rc;

	cpus = of_find_node_by_path("/cpus");
	if (cpus == NULL) {
		DBG("No /cpus node !\n");
		return -ENODEV;
	}

	if (machine_is_compatible("PowerMac7,2") ||
	    machine_is_compatible("PowerMac7,3"))
		rc = g5_pm72_cpufreq_init(cpus);
	else if (machine_is_compatible("RackMac3,1"))
		rc = g5_rm31_cpufreq_init(cpus);
	else
		rc = g5_neo2_cpufreq_init(cpus);

	of_node_put(cpus);
	return rc;
}

module_init(g5_cpufreq_init);


MODULE_LICENSE("GPL");
