diff options
Diffstat (limited to 'arch/arm/mach-pxa/pxa27x.c')
| -rw-r--r-- | arch/arm/mach-pxa/pxa27x.c | 181 | 
1 files changed, 112 insertions, 69 deletions
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index d1fbf29d561..301471a07a1 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -11,23 +11,29 @@   * it under the terms of the GNU General Public License version 2 as   * published by the Free Software Foundation.   */ +#include <linux/gpio.h> +#include <linux/gpio-pxa.h>  #include <linux/module.h>  #include <linux/kernel.h>  #include <linux/init.h>  #include <linux/suspend.h>  #include <linux/platform_device.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/i2c/pxa-i2c.h> +#include <asm/mach/map.h>  #include <mach/hardware.h>  #include <asm/irq.h> +#include <asm/suspend.h>  #include <mach/irqs.h> -#include <mach/gpio.h>  #include <mach/pxa27x.h>  #include <mach/reset.h> -#include <mach/ohci.h> +#include <linux/platform_data/usb-ohci-pxa27x.h>  #include <mach/pm.h>  #include <mach/dma.h> -#include <plat/i2c.h> +#include <mach/smemc.h>  #include "generic.h"  #include "devices.h" @@ -41,23 +47,31 @@ void pxa27x_clear_otgph(void)  EXPORT_SYMBOL(pxa27x_clear_otgph);  static unsigned long ac97_reset_config[] = { -	GPIO113_GPIO, +	GPIO113_AC97_nRESET_GPIO_HIGH,  	GPIO113_AC97_nRESET, -	GPIO95_GPIO, +	GPIO95_AC97_nRESET_GPIO_HIGH,  	GPIO95_AC97_nRESET,  }; -void pxa27x_assert_ac97reset(int reset_gpio, int on) +void pxa27x_configure_ac97reset(int reset_gpio, bool to_gpio)  { +	/* +	 * This helper function is used to work around a bug in the pxa27x's +	 * ac97 controller during a warm reset.  The configuration of the +	 * reset_gpio is changed as follows: +	 * to_gpio == true: configured to generic output gpio and driven high +	 * to_gpio == false: configured to ac97 controller alt fn AC97_nRESET +	 */ +  	if (reset_gpio == 113) -		pxa2xx_mfp_config(on ? &ac97_reset_config[0] : -				       &ac97_reset_config[1], 1); +		pxa2xx_mfp_config(to_gpio ? &ac97_reset_config[0] : +				  &ac97_reset_config[1], 1);  	if (reset_gpio == 95) -		pxa2xx_mfp_config(on ? &ac97_reset_config[2] : -				       &ac97_reset_config[3], 1); +		pxa2xx_mfp_config(to_gpio ? &ac97_reset_config[2] : +				  &ac97_reset_config[3], 1);  } -EXPORT_SYMBOL_GPL(pxa27x_assert_ac97reset); +EXPORT_SYMBOL_GPL(pxa27x_configure_ac97reset);  /* Crystal clock: 13MHz */  #define BASE_CLK	13000000 @@ -107,10 +121,9 @@ unsigned int pxa27x_get_clk_frequency_khz(int info)  }  /* - * Return the current mem clock frequency in units of 10kHz as - * reflected by CCCR[A], B, and L + * Return the current mem clock frequency as reflected by CCCR[A], B, and L   */ -unsigned int pxa27x_get_memclk_frequency_10khz(void) +static unsigned long clk_pxa27x_mem_getrate(struct clk *clk)  {  	unsigned long ccsr, clkcfg;  	unsigned int l, L, m, M; @@ -129,9 +142,15 @@ unsigned int pxa27x_get_memclk_frequency_10khz(void)  	L = l * BASE_CLK;  	M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2)); -	return (M / 10000); +	return M;  } +static const struct clkops clk_pxa27x_mem_ops = { +	.enable		= clk_dummy_enable, +	.disable	= clk_dummy_disable, +	.getrate	= clk_pxa27x_mem_getrate, +}; +  /*   * Return the current LCD clock frequency in units of 10kHz as   */ @@ -157,36 +176,38 @@ static unsigned long clk_pxa27x_lcd_getrate(struct clk *clk)  }  static const struct clkops clk_pxa27x_lcd_ops = { -	.enable		= clk_cken_enable, -	.disable	= clk_cken_disable, +	.enable		= clk_pxa2xx_cken_enable, +	.disable	= clk_pxa2xx_cken_disable,  	.getrate	= clk_pxa27x_lcd_getrate,  }; +static DEFINE_PXA2_CKEN(pxa27x_ffuart, FFUART, 14857000, 1); +static DEFINE_PXA2_CKEN(pxa27x_btuart, BTUART, 14857000, 1); +static DEFINE_PXA2_CKEN(pxa27x_stuart, STUART, 14857000, 1); +static DEFINE_PXA2_CKEN(pxa27x_i2s, I2S, 14682000, 0); +static DEFINE_PXA2_CKEN(pxa27x_i2c, I2C, 32842000, 0); +static DEFINE_PXA2_CKEN(pxa27x_usb, USB, 48000000, 5); +static DEFINE_PXA2_CKEN(pxa27x_mmc, MMC, 19500000, 0); +static DEFINE_PXA2_CKEN(pxa27x_ficp, FICP, 48000000, 0); +static DEFINE_PXA2_CKEN(pxa27x_usbhost, USBHOST, 48000000, 0); +static DEFINE_PXA2_CKEN(pxa27x_pwri2c, PWRI2C, 13000000, 0); +static DEFINE_PXA2_CKEN(pxa27x_keypad, KEYPAD, 32768, 0); +static DEFINE_PXA2_CKEN(pxa27x_ssp1, SSP1, 13000000, 0); +static DEFINE_PXA2_CKEN(pxa27x_ssp2, SSP2, 13000000, 0); +static DEFINE_PXA2_CKEN(pxa27x_ssp3, SSP3, 13000000, 0); +static DEFINE_PXA2_CKEN(pxa27x_pwm0, PWM0, 13000000, 0); +static DEFINE_PXA2_CKEN(pxa27x_pwm1, PWM1, 13000000, 0); +static DEFINE_PXA2_CKEN(pxa27x_ac97, AC97, 24576000, 0); +static DEFINE_PXA2_CKEN(pxa27x_ac97conf, AC97CONF, 24576000, 0); +static DEFINE_PXA2_CKEN(pxa27x_msl, MSL, 48000000, 0); +static DEFINE_PXA2_CKEN(pxa27x_usim, USIM, 48000000, 0); +static DEFINE_PXA2_CKEN(pxa27x_memstk, MEMSTK, 19500000, 0); +static DEFINE_PXA2_CKEN(pxa27x_im, IM, 0, 0); +static DEFINE_PXA2_CKEN(pxa27x_memc, MEMC, 0, 0); +  static DEFINE_CK(pxa27x_lcd, LCD, &clk_pxa27x_lcd_ops);  static DEFINE_CK(pxa27x_camera, CAMERA, &clk_pxa27x_lcd_ops); -static DEFINE_CKEN(pxa27x_ffuart, FFUART, 14857000, 1); -static DEFINE_CKEN(pxa27x_btuart, BTUART, 14857000, 1); -static DEFINE_CKEN(pxa27x_stuart, STUART, 14857000, 1); -static DEFINE_CKEN(pxa27x_i2s, I2S, 14682000, 0); -static DEFINE_CKEN(pxa27x_i2c, I2C, 32842000, 0); -static DEFINE_CKEN(pxa27x_usb, USB, 48000000, 5); -static DEFINE_CKEN(pxa27x_mmc, MMC, 19500000, 0); -static DEFINE_CKEN(pxa27x_ficp, FICP, 48000000, 0); -static DEFINE_CKEN(pxa27x_usbhost, USBHOST, 48000000, 0); -static DEFINE_CKEN(pxa27x_pwri2c, PWRI2C, 13000000, 0); -static DEFINE_CKEN(pxa27x_keypad, KEYPAD, 32768, 0); -static DEFINE_CKEN(pxa27x_ssp1, SSP1, 13000000, 0); -static DEFINE_CKEN(pxa27x_ssp2, SSP2, 13000000, 0); -static DEFINE_CKEN(pxa27x_ssp3, SSP3, 13000000, 0); -static DEFINE_CKEN(pxa27x_pwm0, PWM0, 13000000, 0); -static DEFINE_CKEN(pxa27x_pwm1, PWM1, 13000000, 0); -static DEFINE_CKEN(pxa27x_ac97, AC97, 24576000, 0); -static DEFINE_CKEN(pxa27x_ac97conf, AC97CONF, 24576000, 0); -static DEFINE_CKEN(pxa27x_msl, MSL, 48000000, 0); -static DEFINE_CKEN(pxa27x_usim, USIM, 48000000, 0); -static DEFINE_CKEN(pxa27x_memstk, MEMSTK, 19500000, 0); -static DEFINE_CKEN(pxa27x_im, IM, 0, 0); -static DEFINE_CKEN(pxa27x_memc, MEMC, 0, 0); +static DEFINE_CLK(pxa27x_mem, &clk_pxa27x_mem_ops, 0, 0);  static struct clk_lookup pxa27x_clkregs[] = {  	INIT_CLKREG(&clk_pxa27x_lcd, "pxa2xx-fb", NULL), @@ -215,6 +236,9 @@ static struct clk_lookup pxa27x_clkregs[] = {  	INIT_CLKREG(&clk_pxa27x_memstk, NULL, "MSTKCLK"),  	INIT_CLKREG(&clk_pxa27x_im, NULL, "IMCLK"),  	INIT_CLKREG(&clk_pxa27x_memc, NULL, "MEMCLK"), +	INIT_CLKREG(&clk_pxa27x_mem, "pxa2xx-pcmcia", NULL), +	INIT_CLKREG(&clk_dummy, "pxa27x-gpio", NULL), +	INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),  };  #ifdef CONFIG_PM @@ -246,7 +270,6 @@ int __init pxa27x_set_pwrmode(unsigned int mode)   */  enum {  	SLEEP_SAVE_PSTR, -	SLEEP_SAVE_CKEN,  	SLEEP_SAVE_MDREFR,  	SLEEP_SAVE_PCFR,  	SLEEP_SAVE_COUNT @@ -254,27 +277,30 @@ enum {  void pxa27x_cpu_pm_save(unsigned long *sleep_save)  { -	SAVE(MDREFR); +	sleep_save[SLEEP_SAVE_MDREFR] = __raw_readl(MDREFR);  	SAVE(PCFR); -	SAVE(CKEN);  	SAVE(PSTR);  }  void pxa27x_cpu_pm_restore(unsigned long *sleep_save)  { -	RESTORE(MDREFR); +	__raw_writel(sleep_save[SLEEP_SAVE_MDREFR], MDREFR);  	RESTORE(PCFR);  	PSSR = PSSR_RDH | PSSR_PH; -	RESTORE(CKEN);  	RESTORE(PSTR);  }  void pxa27x_cpu_pm_enter(suspend_state_t state)  {  	extern void pxa_cpu_standby(void); +#ifndef CONFIG_IWMMXT +	u64 acc0; + +	asm volatile("mra %Q0, %R0, acc0" : "=r" (acc0)); +#endif  	/* ensure voltage-change sequencer not initiated, which hangs */  	PCFR &= ~PCFR_FVC; @@ -290,7 +316,10 @@ void pxa27x_cpu_pm_enter(suspend_state_t state)  		pxa_cpu_standby();  		break;  	case PM_SUSPEND_MEM: -		pxa27x_cpu_suspend(pwrmode); +		cpu_suspend(pwrmode, pxa27x_finish_suspend); +#ifndef CONFIG_IWMMXT +		asm volatile("mar acc0, %Q0, %R0" : "=r" (acc0)); +#endif  		break;  	}  } @@ -303,7 +332,7 @@ static int pxa27x_cpu_pm_valid(suspend_state_t state)  static int pxa27x_cpu_pm_prepare(void)  {  	/* set resume return address */ -	PSPR = virt_to_phys(pxa_cpu_resume); +	PSPR = virt_to_phys(cpu_resume);  	return 0;  } @@ -334,18 +363,18 @@ static inline void pxa27x_init_pm(void) {}  /* PXA27x:  Various gpios can issue wakeup events.  This logic only   * handles the simple cases, not the WEMUX2 and WEMUX3 options   */ -static int pxa27x_set_wake(unsigned int irq, unsigned int on) +static int pxa27x_set_wake(struct irq_data *d, unsigned int on)  { -	int gpio = IRQ_TO_GPIO(irq); +	int gpio = pxa_irq_to_gpio(d->irq);  	uint32_t mask;  	if (gpio >= 0 && gpio < 128)  		return gpio_set_wake(gpio, on); -	if (irq == IRQ_KEYPAD) +	if (d->irq == IRQ_KEYPAD)  		return keypad_set_wake(on); -	switch (irq) { +	switch (d->irq) {  	case IRQ_RTCAlrm:  		mask = PWER_RTC;  		break; @@ -367,7 +396,27 @@ static int pxa27x_set_wake(unsigned int irq, unsigned int on)  void __init pxa27x_init_irq(void)  {  	pxa_init_irq(34, pxa27x_set_wake); -	pxa_init_gpio(IRQ_GPIO_2_x, 2, 120, pxa27x_set_wake); +} + +static struct map_desc pxa27x_io_desc[] __initdata = { +	{	/* Mem Ctl */ +		.virtual	= (unsigned long)SMEMC_VIRT, +		.pfn		= __phys_to_pfn(PXA2XX_SMEMC_BASE), +		.length		= 0x00200000, +		.type		= MT_DEVICE +	}, {	/* IMem ctl */ +		.virtual	=  0xfe000000, +		.pfn		= __phys_to_pfn(0x58000000), +		.length		= 0x00100000, +		.type		= MT_DEVICE +	}, +}; + +void __init pxa27x_map_io(void) +{ +	pxa_map_io(); +	iotable_init(ARRAY_AND_SIZE(pxa27x_io_desc)); +	pxa27x_get_clk_frequency_khz(1);  }  /* @@ -381,6 +430,11 @@ void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info)  	pxa_register_device(&pxa27x_device_i2c_power, info);  } +static struct pxa_gpio_platform_data pxa27x_gpio_info __initdata = { +	.irq_base	= PXA_GPIO_TO_IRQ(0), +	.gpio_set_wake	= gpio_set_wake, +}; +  static struct platform_device *devices[] __initdata = {  	&pxa27x_device_udc,  	&pxa_device_pmu, @@ -398,19 +452,9 @@ static struct platform_device *devices[] __initdata = {  	&pxa27x_device_pwm1,  }; -static struct sys_device pxa27x_sysdev[] = { -	{ -		.cls	= &pxa_irq_sysclass, -	}, { -		.cls	= &pxa2xx_mfp_sysclass, -	}, { -		.cls	= &pxa_gpio_sysclass, -	}, -}; -  static int __init pxa27x_init(void)  { -	int i, ret = 0; +	int ret = 0;  	if (cpu_is_pxa27x()) { @@ -423,12 +467,11 @@ static int __init pxa27x_init(void)  		pxa27x_init_pm(); -		for (i = 0; i < ARRAY_SIZE(pxa27x_sysdev); i++) { -			ret = sysdev_register(&pxa27x_sysdev[i]); -			if (ret) -				pr_err("failed to register sysdev[%d]\n", i); -		} +		register_syscore_ops(&pxa_irq_syscore_ops); +		register_syscore_ops(&pxa2xx_mfp_syscore_ops); +		register_syscore_ops(&pxa2xx_clock_syscore_ops); +		pxa_register_device(&pxa27x_device_gpio, &pxa27x_gpio_info);  		ret = platform_add_devices(devices, ARRAY_SIZE(devices));  	}  | 
