/* ----------------------------------------------------------------------- *
 *   
 *   Copyright 2000 H. Peter Anvin - All Rights Reserved
 *
 *   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, Inc., 675 Mass Ave, Cambridge MA 02139,
 *   USA; either version 2 of the License, or (at your option) any later
 *   version; incorporated herein by reference.
 *
 * ----------------------------------------------------------------------- */

/*
 * cpuid.c
 *
 * x86 CPUID access device
 *
 * This device is accessed by lseek() to the appropriate CPUID level
 * and then read in chunks of 16 bytes.  A larger size means multiple
 * reads of consecutive levels.
 *
 * This driver uses /dev/cpu/%d/cpuid where %d is the minor number, and on
 * an SMP box will direct the access to CPU %d.
 */

#include <linux/module.h>

#include <linux/types.h>
#include <linux/errno.h>
#include <linux/fcntl.h>
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/smp.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/cpu.h>
#include <linux/notifier.h>

#include <asm/processor.h>
#include <asm/msr.h>
#include <asm/uaccess.h>
#include <asm/system.h>

static struct class *cpuid_class;

#ifdef CONFIG_SMP

struct cpuid_command {
	int cpu;
	u32 reg;
	u32 *data;
};

static void cpuid_smp_cpuid(void *cmd_block)
{
	struct cpuid_command *cmd = (struct cpuid_command *)cmd_block;

	if (cmd->cpu == smp_processor_id())
		cpuid(cmd->reg, &cmd->data[0], &cmd->data[1], &cmd->data[2],
		      &cmd->data[3]);
}

static inline void do_cpuid(int cpu, u32 reg, u32 * data)
{
	struct cpuid_command cmd;

	preempt_disable();
	if (cpu == smp_processor_id()) {
		cpuid(reg, &data[0], &data[1], &data[2], &data[3]);
	} else {
		cmd.cpu = cpu;
		cmd.reg = reg;
		cmd.data = data;

		smp_call_function(cpuid_smp_cpuid, &cmd, 1, 1);
	}
	preempt_enable();
}
#else				/* ! CONFIG_SMP */

static inline void do_cpuid(int cpu, u32 reg, u32 * data)
{
	cpuid(reg, &data[0], &data[1], &data[2], &data[3]);
}

#endif				/* ! CONFIG_SMP */

static loff_t cpuid_seek(struct file *file, loff_t offset, int orig)
{
	loff_t ret;

	lock_kernel();

	switch (orig) {
	case 0:
		file->f_pos = offset;
		ret = file->f_pos;
		break;
	case 1:
		file->f_pos += offset;
		ret = file->f_pos;
		break;
	default:
		ret = -EINVAL;
	}

	unlock_kernel();
	return ret;
}

static ssize_t cpuid_read(struct file *file, char __user *buf,
			  size_t count, loff_t * ppos)
{
	char __user *tmp = buf;
	u32 data[4];
	u32 reg = *ppos;
	int cpu = iminor(file->f_dentry->d_inode);

	if (count % 16)
		return -EINVAL;	/* Invalid chunk size */

	for (; count; count -= 16) {
		do_cpuid(cpu, reg, data);
		if (copy_to_user(tmp, &data, 16))
			return -EFAULT;
		tmp += 16;
		*ppos = reg++;
	}

	return tmp - buf;
}

static int cpuid_open(struct inode *inode, struct file *file)
{
	unsigned int cpu = iminor(file->f_dentry->d_inode);
	struct cpuinfo_x86 *c = &(cpu_data)[cpu];

	if (cpu >= NR_CPUS || !cpu_online(cpu))
		return -ENXIO;	/* No such CPU */
	if (c->cpuid_level < 0)
		return -EIO;	/* CPUID not supported */

	return 0;
}

/*
 * File operations we support
 */
static struct file_operations cpuid_fops = {
	.owner = THIS_MODULE,
	.llseek = cpuid_seek,
	.read = cpuid_read,
	.open = cpuid_open,
};

static int cpuid_class_device_create(int i)
{
	int err = 0;
	struct class_device *class_err;

	class_err = class_device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i);
	if (IS_ERR(class_err))
		err = PTR_ERR(class_err);
	return err;
}

#ifdef CONFIG_HOTPLUG_CPU
static int cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
{
	unsigned int cpu = (unsigned long)hcpu;

	switch (action) {
	case CPU_ONLINE:
		cpuid_class_device_create(cpu);
		break;
	case CPU_DEAD:
		class_device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
		break;
	}
	return NOTIFY_OK;
}

static struct notifier_block __cpuinitdata cpuid_class_cpu_notifier =
{
	.notifier_call = cpuid_class_cpu_callback,
};
#endif /* !CONFIG_HOTPLUG_CPU */

static int __init cpuid_init(void)
{
	int i, err = 0;
	i = 0;

	if (register_chrdev(CPUID_MAJOR, "cpu/cpuid", &cpuid_fops)) {
		printk(KERN_ERR "cpuid: unable to get major %d for cpuid\n",
		       CPUID_MAJOR);
		err = -EBUSY;
		goto out;
	}
	cpuid_class = class_create(THIS_MODULE, "cpuid");
	if (IS_ERR(cpuid_class)) {
		err = PTR_ERR(cpuid_class);
		goto out_chrdev;
	}
	for_each_online_cpu(i) {
		err = cpuid_class_device_create(i);
		if (err != 0) 
			goto out_class;
	}
	register_hotcpu_notifier(&cpuid_class_cpu_notifier);

	err = 0;
	goto out;

out_class:
	i = 0;
	for_each_online_cpu(i) {
		class_device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, i));
	}
	class_destroy(cpuid_class);
out_chrdev:
	unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");	
out:
	return err;
}

static void __exit cpuid_exit(void)
{
	int cpu = 0;

	for_each_online_cpu(cpu)
		class_device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
	class_destroy(cpuid_class);
	unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
	unregister_hotcpu_notifier(&cpuid_class_cpu_notifier);
}

module_init(cpuid_init);
module_exit(cpuid_exit);

MODULE_AUTHOR("H. Peter Anvin <hpa@zytor.com>");
MODULE_DESCRIPTION("x86 generic CPUID driver");
MODULE_LICENSE("GPL");
