|  | @@ -864,3 +864,140 @@ err_request:
 | 
	
		
			
				|  |  |  #ifdef CONFIG_CPU_FREQ
 | 
	
		
			
				|  |  |  static int viper_cpufreq_notifier(struct notifier_block *nb,
 | 
	
		
			
				|  |  |  				  unsigned long val, void *data)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	struct cpufreq_freqs *freq = data;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* TODO: Adjust timings??? */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	switch (val) {
 | 
	
		
			
				|  |  | +	case CPUFREQ_PRECHANGE:
 | 
	
		
			
				|  |  | +		if (freq->old < freq->new) {
 | 
	
		
			
				|  |  | +			/* we are getting faster so raise the voltage
 | 
	
		
			
				|  |  | +			 * before we change freq */
 | 
	
		
			
				|  |  | +			viper_set_core_cpu_voltage(freq->new, 0);
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		break;
 | 
	
		
			
				|  |  | +	case CPUFREQ_POSTCHANGE:
 | 
	
		
			
				|  |  | +		if (freq->old > freq->new) {
 | 
	
		
			
				|  |  | +			/* we are slowing down so drop the power
 | 
	
		
			
				|  |  | +			 * after we change freq */
 | 
	
		
			
				|  |  | +			viper_set_core_cpu_voltage(freq->new, 0);
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		break;
 | 
	
		
			
				|  |  | +	case CPUFREQ_RESUMECHANGE:
 | 
	
		
			
				|  |  | +		viper_set_core_cpu_voltage(freq->new, 0);
 | 
	
		
			
				|  |  | +		break;
 | 
	
		
			
				|  |  | +	default:
 | 
	
		
			
				|  |  | +		/* ignore */
 | 
	
		
			
				|  |  | +		break;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	return 0;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static struct notifier_block viper_cpufreq_notifier_block = {
 | 
	
		
			
				|  |  | +	.notifier_call  = viper_cpufreq_notifier
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static void __init viper_init_cpufreq(void)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	if (cpufreq_register_notifier(&viper_cpufreq_notifier_block,
 | 
	
		
			
				|  |  | +				      CPUFREQ_TRANSITION_NOTIFIER))
 | 
	
		
			
				|  |  | +		pr_err("viper: Failed to setup cpufreq notifier\n");
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +#else
 | 
	
		
			
				|  |  | +static inline void viper_init_cpufreq(void) {}
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static void viper_power_off(void)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	pr_notice("Shutting off UPS\n");
 | 
	
		
			
				|  |  | +	gpio_set_value(VIPER_UPS_GPIO, 1);
 | 
	
		
			
				|  |  | +	/* Spin to death... */
 | 
	
		
			
				|  |  | +	while (1);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static void __init viper_init(void)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	u8 version;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	pm_power_off = viper_power_off;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	pxa2xx_mfp_config(ARRAY_AND_SIZE(viper_pin_config));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	pxa_set_ffuart_info(NULL);
 | 
	
		
			
				|  |  | +	pxa_set_btuart_info(NULL);
 | 
	
		
			
				|  |  | +	pxa_set_stuart_info(NULL);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* Wake-up serial console */
 | 
	
		
			
				|  |  | +	viper_init_serial_gpio();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	pxa_set_fb_info(NULL, &fb_info);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* v1 hardware cannot use the datacs line */
 | 
	
		
			
				|  |  | +	version = viper_hw_version();
 | 
	
		
			
				|  |  | +	if (version == 0)
 | 
	
		
			
				|  |  | +		smc91x_device.num_resources--;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	pxa_set_i2c_info(NULL);
 | 
	
		
			
				|  |  | +	platform_add_devices(viper_devs, ARRAY_SIZE(viper_devs));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	viper_init_vcore_gpios();
 | 
	
		
			
				|  |  | +	viper_init_cpufreq();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	register_syscore_ops(&viper_cpu_syscore_ops);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (version) {
 | 
	
		
			
				|  |  | +		pr_info("viper: hardware v%di%d detected. "
 | 
	
		
			
				|  |  | +			"CPLD revision %d.\n",
 | 
	
		
			
				|  |  | +			VIPER_BOARD_VERSION(version),
 | 
	
		
			
				|  |  | +			VIPER_BOARD_ISSUE(version),
 | 
	
		
			
				|  |  | +			VIPER_CPLD_REVISION(version));
 | 
	
		
			
				|  |  | +		system_rev = (VIPER_BOARD_VERSION(version) << 8) |
 | 
	
		
			
				|  |  | +			     (VIPER_BOARD_ISSUE(version) << 4) |
 | 
	
		
			
				|  |  | +			     VIPER_CPLD_REVISION(version);
 | 
	
		
			
				|  |  | +	} else {
 | 
	
		
			
				|  |  | +		pr_info("viper: No version register.\n");
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	i2c_register_board_info(1, ARRAY_AND_SIZE(viper_i2c_devices));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	viper_tpm_init();
 | 
	
		
			
				|  |  | +	pxa_set_ac97_info(NULL);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static struct map_desc viper_io_desc[] __initdata = {
 | 
	
		
			
				|  |  | +	{
 | 
	
		
			
				|  |  | +		.virtual = VIPER_CPLD_BASE,
 | 
	
		
			
				|  |  | +		.pfn     = __phys_to_pfn(VIPER_CPLD_PHYS),
 | 
	
		
			
				|  |  | +		.length  = 0x00300000,
 | 
	
		
			
				|  |  | +		.type    = MT_DEVICE,
 | 
	
		
			
				|  |  | +	},
 | 
	
		
			
				|  |  | +	{
 | 
	
		
			
				|  |  | +		.virtual = VIPER_PC104IO_BASE,
 | 
	
		
			
				|  |  | +		.pfn     = __phys_to_pfn(0x30000000),
 | 
	
		
			
				|  |  | +		.length  = 0x00800000,
 | 
	
		
			
				|  |  | +		.type    = MT_DEVICE,
 | 
	
		
			
				|  |  | +	},
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static void __init viper_map_io(void)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	pxa25x_map_io();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	iotable_init(viper_io_desc, ARRAY_SIZE(viper_io_desc));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	PCFR |= PCFR_OPDE;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +MACHINE_START(VIPER, "Arcom/Eurotech VIPER SBC")
 | 
	
		
			
				|  |  | +	/* Maintainer: Marc Zyngier <maz@misterjones.org> */
 | 
	
		
			
				|  |  | +	.atag_offset	= 0x100,
 | 
	
		
			
				|  |  | +	.map_io		= viper_map_io,
 | 
	
		
			
				|  |  | +	.nr_irqs	= PXA_NR_IRQS,
 | 
	
		
			
				|  |  | +	.init_irq	= viper_init_irq,
 | 
	
		
			
				|  |  | +	.handle_irq	= pxa25x_handle_irq,
 | 
	
		
			
				|  |  | +	.timer          = &pxa_timer,
 | 
	
		
			
				|  |  | +	.init_machine	= viper_init,
 | 
	
		
			
				|  |  | +	.restart	= pxa_restart,
 | 
	
		
			
				|  |  | +MACHINE_END
 |