diff options
Diffstat (limited to 'arch/arm/mach-gemini')
23 files changed, 235 insertions, 237 deletions
diff --git a/arch/arm/mach-gemini/Makefile b/arch/arm/mach-gemini/Makefile index c5b24b95a76..7963a77be63 100644 --- a/arch/arm/mach-gemini/Makefile +++ b/arch/arm/mach-gemini/Makefile @@ -4,7 +4,7 @@  # Object file lists. -obj-y			:= irq.o mm.o time.o devices.o gpio.o +obj-y			:= irq.o mm.o time.o devices.o gpio.o idle.o reset.o  # Board-specific support  obj-$(CONFIG_MACH_NAS4220B)	+= board-nas4220b.o diff --git a/arch/arm/mach-gemini/Makefile.boot b/arch/arm/mach-gemini/Makefile.boot index 22a52c228d9..683f52b20e3 100644 --- a/arch/arm/mach-gemini/Makefile.boot +++ b/arch/arm/mach-gemini/Makefile.boot @@ -1,9 +1,9 @@  ifeq ($(CONFIG_GEMINI_MEM_SWAP),y) -   zreladdr-y	:= 0x00008000 +   zreladdr-y	+= 0x00008000  params_phys-y	:= 0x00000100  initrd_phys-y	:= 0x00800000  else -   zreladdr-y	:= 0x10008000 +   zreladdr-y	+= 0x10008000  params_phys-y	:= 0x10000100  initrd_phys-y	:= 0x10800000  endif diff --git a/arch/arm/mach-gemini/board-nas4220b.c b/arch/arm/mach-gemini/board-nas4220b.c index 2ba096de003..ca8a25bb352 100644 --- a/arch/arm/mach-gemini/board-nas4220b.c +++ b/arch/arm/mach-gemini/board-nas4220b.c @@ -31,10 +31,6 @@  #include "common.h" -static struct sys_timer ib4220b_timer = { -	.init	= gemini_timer_init, -}; -  static struct gpio_led ib4220b_leds[] = {  	{  		.name			= "nas4220b:orange:hdd", @@ -98,12 +94,14 @@ static void __init ib4220b_init(void)  	platform_register_pflash(SZ_16M, NULL, 0);  	platform_device_register(&ib4220b_led_device);  	platform_device_register(&ib4220b_key_device); +	platform_register_rtc();  }  MACHINE_START(NAS4220B, "Raidsonic NAS IB-4220-B") -	.boot_params	= 0x100, +	.atag_offset	= 0x100,  	.map_io		= gemini_map_io,  	.init_irq	= gemini_init_irq, -	.timer		= &ib4220b_timer, +	.init_time	= gemini_timer_init,  	.init_machine	= ib4220b_init, +	.restart	= gemini_restart,  MACHINE_END diff --git a/arch/arm/mach-gemini/board-rut1xx.c b/arch/arm/mach-gemini/board-rut1xx.c index a9a0d8b0194..7a675f88ffd 100644 --- a/arch/arm/mach-gemini/board-rut1xx.c +++ b/arch/arm/mach-gemini/board-rut1xx.c @@ -14,6 +14,7 @@  #include <linux/leds.h>  #include <linux/input.h>  #include <linux/gpio_keys.h> +#include <linux/sizes.h>  #include <asm/mach-types.h>  #include <asm/mach/arch.h> @@ -71,10 +72,6 @@ static struct platform_device rut1xx_leds = {  	},  }; -static struct sys_timer rut1xx_timer = { -	.init	= gemini_timer_init, -}; -  static void __init rut1xx_init(void)  {  	gemini_gpio_init(); @@ -82,12 +79,14 @@ static void __init rut1xx_init(void)  	platform_register_pflash(SZ_8M, NULL, 0);  	platform_device_register(&rut1xx_leds);  	platform_device_register(&rut1xx_keys_device); +	platform_register_rtc();  }  MACHINE_START(RUT100, "Teltonika RUT100") -	.boot_params	= 0x100, +	.atag_offset	= 0x100,  	.map_io		= gemini_map_io,  	.init_irq	= gemini_init_irq, -	.timer		= &rut1xx_timer, +	.init_time	= gemini_timer_init,  	.init_machine	= rut1xx_init, +	.restart	= gemini_restart,  MACHINE_END diff --git a/arch/arm/mach-gemini/board-wbd111.c b/arch/arm/mach-gemini/board-wbd111.c index 8b88d50d433..418188cd171 100644 --- a/arch/arm/mach-gemini/board-wbd111.c +++ b/arch/arm/mach-gemini/board-wbd111.c @@ -80,11 +80,6 @@ static struct platform_device wbd111_leds_device = {  	},  }; -static struct sys_timer wbd111_timer = { -	.init	= gemini_timer_init, -}; - -#ifdef CONFIG_MTD_PARTITIONS  static struct mtd_partition wbd111_partitions[] = {  	{  		.name		= "RedBoot", @@ -116,11 +111,7 @@ static struct mtd_partition wbd111_partitions[] = {  		.mask_flags	= MTD_WRITEABLE,  	}  }; -#define wbd111_num_partitions	ARRAY_SIZE(wbd111_partitions) -#else -#define wbd111_partitions	NULL -#define wbd111_num_partitions	0 -#endif /* CONFIG_MTD_PARTITIONS */ +#define wbd111_num_partitions  ARRAY_SIZE(wbd111_partitions)  static void __init wbd111_init(void)  { @@ -130,12 +121,14 @@ static void __init wbd111_init(void)  				 wbd111_num_partitions);  	platform_device_register(&wbd111_leds_device);  	platform_device_register(&wbd111_keys_device); +	platform_register_rtc();  }  MACHINE_START(WBD111, "Wiliboard WBD-111") -	.boot_params	= 0x100, +	.atag_offset	= 0x100,  	.map_io		= gemini_map_io,  	.init_irq	= gemini_init_irq, -	.timer		= &wbd111_timer, +	.init_time	= gemini_timer_init,  	.init_machine	= wbd111_init, +	.restart	= gemini_restart,  MACHINE_END diff --git a/arch/arm/mach-gemini/board-wbd222.c b/arch/arm/mach-gemini/board-wbd222.c index 1eebcecd1c3..266b265090c 100644 --- a/arch/arm/mach-gemini/board-wbd222.c +++ b/arch/arm/mach-gemini/board-wbd222.c @@ -80,11 +80,6 @@ static struct platform_device wbd222_leds_device = {  	},  }; -static struct sys_timer wbd222_timer = { -	.init	= gemini_timer_init, -}; - -#ifdef CONFIG_MTD_PARTITIONS  static struct mtd_partition wbd222_partitions[] = {  	{  		.name		= "RedBoot", @@ -116,11 +111,7 @@ static struct mtd_partition wbd222_partitions[] = {  		.mask_flags	= MTD_WRITEABLE,  	}  }; -#define wbd222_num_partitions	ARRAY_SIZE(wbd222_partitions) -#else -#define wbd222_partitions	NULL -#define wbd222_num_partitions	0 -#endif /* CONFIG_MTD_PARTITIONS */ +#define wbd222_num_partitions  ARRAY_SIZE(wbd222_partitions)  static void __init wbd222_init(void)  { @@ -130,12 +121,14 @@ static void __init wbd222_init(void)  		wbd222_num_partitions);  	platform_device_register(&wbd222_leds_device);  	platform_device_register(&wbd222_keys_device); +	platform_register_rtc();  }  MACHINE_START(WBD222, "Wiliboard WBD-222") -	.boot_params	= 0x100, +	.atag_offset	= 0x100,  	.map_io		= gemini_map_io,  	.init_irq	= gemini_init_irq, -	.timer		= &wbd222_timer, +	.init_time	= gemini_timer_init,  	.init_machine	= wbd222_init, +	.restart	= gemini_restart,  MACHINE_END diff --git a/arch/arm/mach-gemini/common.h b/arch/arm/mach-gemini/common.h index 9392834a214..38a45260a7c 100644 --- a/arch/arm/mach-gemini/common.h +++ b/arch/arm/mach-gemini/common.h @@ -18,6 +18,7 @@ extern void gemini_map_io(void);  extern void gemini_init_irq(void);  extern void gemini_timer_init(void);  extern void gemini_gpio_init(void); +extern void platform_register_rtc(void);  /* Common platform devices registration functions */  extern int platform_register_uart(void); @@ -25,4 +26,6 @@ extern int platform_register_pflash(unsigned int size,  				    struct mtd_partition *parts,  				    unsigned int nr_parts); +extern void gemini_restart(char mode, const char *cmd); +  #endif /* __GEMINI_COMMON_H__ */ diff --git a/arch/arm/mach-gemini/devices.c b/arch/arm/mach-gemini/devices.c index 6b525253d02..5cff29818b7 100644 --- a/arch/arm/mach-gemini/devices.c +++ b/arch/arm/mach-gemini/devices.c @@ -90,3 +90,29 @@ int platform_register_pflash(unsigned int size, struct mtd_partition *parts,  	return platform_device_register(&pflash_device);  } + +static struct resource gemini_rtc_resources[] = { +	[0] = { +		.start  = GEMINI_RTC_BASE, +		.end    = GEMINI_RTC_BASE + 0x24, +		.flags  = IORESOURCE_MEM, +	}, +	[1] = { +		.start  = IRQ_RTC, +		.end    = IRQ_RTC, +		.flags  = IORESOURCE_IRQ, +	}, +}; + +static struct platform_device gemini_rtc_device = { +	.name		= "rtc-gemini", +	.id		= 0, +	.num_resources	= ARRAY_SIZE(gemini_rtc_resources), +	.resource	= gemini_rtc_resources, +}; + +int __init platform_register_rtc(void) +{ +	return platform_device_register(&gemini_rtc_device); +} + diff --git a/arch/arm/mach-gemini/gpio.c b/arch/arm/mach-gemini/gpio.c index fe3bd5ac8b1..f8cb5710d6e 100644 --- a/arch/arm/mach-gemini/gpio.c +++ b/arch/arm/mach-gemini/gpio.c @@ -23,6 +23,7 @@  #include <mach/irqs.h>  #define GPIO_BASE(x)		IO_ADDRESS(GEMINI_GPIO_BASE(x)) +#define irq_to_gpio(x)		((x) - GPIO_IRQ_BASE)  /* GPIO registers definition */  #define GPIO_DATA_OUT		0x0 @@ -44,7 +45,7 @@  #define GPIO_PORT_NUM		3 -static void _set_gpio_irqenable(unsigned int base, unsigned int index, +static void _set_gpio_irqenable(void __iomem *base, unsigned int index,  				int enable)  {  	unsigned int reg; @@ -54,35 +55,35 @@ static void _set_gpio_irqenable(unsigned int base, unsigned int index,  	__raw_writel(reg, base + GPIO_INT_EN);  } -static void gpio_ack_irq(unsigned int irq) +static void gpio_ack_irq(struct irq_data *d)  { -	unsigned int gpio = irq_to_gpio(irq); -	unsigned int base = GPIO_BASE(gpio / 32); +	unsigned int gpio = irq_to_gpio(d->irq); +	void __iomem *base = GPIO_BASE(gpio / 32);  	__raw_writel(1 << (gpio % 32), base + GPIO_INT_CLR);  } -static void gpio_mask_irq(unsigned int irq) +static void gpio_mask_irq(struct irq_data *d)  { -	unsigned int gpio = irq_to_gpio(irq); -	unsigned int base = GPIO_BASE(gpio / 32); +	unsigned int gpio = irq_to_gpio(d->irq); +	void __iomem *base = GPIO_BASE(gpio / 32);  	_set_gpio_irqenable(base, gpio % 32, 0);  } -static void gpio_unmask_irq(unsigned int irq) +static void gpio_unmask_irq(struct irq_data *d)  { -	unsigned int gpio = irq_to_gpio(irq); -	unsigned int base = GPIO_BASE(gpio / 32); +	unsigned int gpio = irq_to_gpio(d->irq); +	void __iomem *base = GPIO_BASE(gpio / 32);  	_set_gpio_irqenable(base, gpio % 32, 1);  } -static int gpio_set_irq_type(unsigned int irq, unsigned int type) +static int gpio_set_irq_type(struct irq_data *d, unsigned int type)  { -	unsigned int gpio = irq_to_gpio(irq); +	unsigned int gpio = irq_to_gpio(d->irq);  	unsigned int gpio_mask = 1 << (gpio % 32); -	unsigned int base = GPIO_BASE(gpio / 32); +	void __iomem *base = GPIO_BASE(gpio / 32);  	unsigned int reg_both, reg_level, reg_type;  	reg_type = __raw_readl(base + GPIO_INT_TYPE); @@ -120,15 +121,15 @@ static int gpio_set_irq_type(unsigned int irq, unsigned int type)  	__raw_writel(reg_level, base + GPIO_INT_LEVEL);  	__raw_writel(reg_both, base + GPIO_INT_BOTH_EDGE); -	gpio_ack_irq(irq); +	gpio_ack_irq(d);  	return 0;  }  static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)  { +	unsigned int port = (unsigned int)irq_desc_get_handler_data(desc);  	unsigned int gpio_irq_no, irq_stat; -	unsigned int port = (unsigned int)get_irq_data(irq);  	irq_stat = __raw_readl(GPIO_BASE(port) + GPIO_INT_STAT); @@ -138,24 +139,22 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)  		if ((irq_stat & 1) == 0)  			continue; -		BUG_ON(!(irq_desc[gpio_irq_no].handle_irq)); -		irq_desc[gpio_irq_no].handle_irq(gpio_irq_no, -				&irq_desc[gpio_irq_no]); +		generic_handle_irq(gpio_irq_no);  	}  }  static struct irq_chip gpio_irq_chip = {  	.name = "GPIO", -	.ack = gpio_ack_irq, -	.mask = gpio_mask_irq, -	.unmask = gpio_unmask_irq, -	.set_type = gpio_set_irq_type, +	.irq_ack = gpio_ack_irq, +	.irq_mask = gpio_mask_irq, +	.irq_unmask = gpio_unmask_irq, +	.irq_set_type = gpio_set_irq_type,  };  static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,  				int dir)  { -	unsigned int base = GPIO_BASE(offset / 32); +	void __iomem *base = GPIO_BASE(offset / 32);  	unsigned int reg;  	reg = __raw_readl(base + GPIO_DIR); @@ -168,7 +167,7 @@ static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,  static void gemini_gpio_set(struct gpio_chip *chip, unsigned offset, int value)  { -	unsigned int base = GPIO_BASE(offset / 32); +	void __iomem *base = GPIO_BASE(offset / 32);  	if (value)  		__raw_writel(1 << (offset % 32), base + GPIO_DATA_SET); @@ -178,7 +177,7 @@ static void gemini_gpio_set(struct gpio_chip *chip, unsigned offset, int value)  static int gemini_gpio_get(struct gpio_chip *chip, unsigned offset)  { -	unsigned int base = GPIO_BASE(offset / 32); +	void __iomem *base = GPIO_BASE(offset / 32);  	return (__raw_readl(base + GPIO_DATA_IN) >> (offset % 32)) & 1;  } @@ -219,13 +218,13 @@ void __init gemini_gpio_init(void)  		for (j = GPIO_IRQ_BASE + i * 32;  		     j < GPIO_IRQ_BASE + (i + 1) * 32; j++) { -			set_irq_chip(j, &gpio_irq_chip); -			set_irq_handler(j, handle_edge_irq); +			irq_set_chip_and_handler(j, &gpio_irq_chip, +						 handle_edge_irq);  			set_irq_flags(j, IRQF_VALID);  		} -		set_irq_chained_handler(IRQ_GPIO(i), gpio_irq_handler); -		set_irq_data(IRQ_GPIO(i), (void *)i); +		irq_set_chained_handler(IRQ_GPIO(i), gpio_irq_handler); +		irq_set_handler_data(IRQ_GPIO(i), (void *)i);  	}  	BUG_ON(gpiochip_add(&gemini_gpio_chip)); diff --git a/arch/arm/mach-gemini/idle.c b/arch/arm/mach-gemini/idle.c new file mode 100644 index 00000000000..ddf8ec9d203 --- /dev/null +++ b/arch/arm/mach-gemini/idle.c @@ -0,0 +1,31 @@ +/* + * arch/arm/mach-gemini/idle.c + */ + +#include <linux/init.h> +#include <asm/system_misc.h> +#include <asm/proc-fns.h> + +static void gemini_idle(void) +{ +	/* +	 * Because of broken hardware we have to enable interrupts or the CPU +	 * will never wakeup... Acctualy it is not very good to enable +	 * interrupts first since scheduler can miss a tick, but there is +	 * no other way around this. Platforms that needs it for power saving +	 * should enable it in init code, since by default it is +	 * disabled. +	 */ + +	/* FIXME: Enabling interrupts here is racy! */ +	local_irq_enable(); +	cpu_do_idle(); +} + +static int __init gemini_idle_init(void) +{ +	arm_pm_idle = gemini_idle; +	return 0; +} + +arch_initcall(gemini_idle_init); diff --git a/arch/arm/mach-gemini/include/mach/debug-macro.S b/arch/arm/mach-gemini/include/mach/debug-macro.S deleted file mode 100644 index f40e006d296..00000000000 --- a/arch/arm/mach-gemini/include/mach/debug-macro.S +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Debugging macro include header - * - *  Copyright (C) 1994-1999 Russell King - *  Copyright (C) 2001-2006 Storlink, Corp. - *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> - * - * 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. - */ -#include <mach/hardware.h> - -	.macro	addruart, rp, rv -	ldr	\rp, =GEMINI_UART_BASE			@ physical -	ldr	\rv, =IO_ADDRESS(GEMINI_UART_BASE)	@ virtual -	.endm - -#define UART_SHIFT	2 -#define FLOW_CONTROL -#include <asm/hardware/debug-8250.S> diff --git a/arch/arm/mach-gemini/include/mach/entry-macro.S b/arch/arm/mach-gemini/include/mach/entry-macro.S index 1624f91a2b8..f044e430bfa 100644 --- a/arch/arm/mach-gemini/include/mach/entry-macro.S +++ b/arch/arm/mach-gemini/include/mach/entry-macro.S @@ -12,15 +12,9 @@  #define IRQ_STATUS	0x14 -	.macro  disable_fiq -	.endm -  	.macro  get_irqnr_preamble, base, tmp  	.endm -	.macro  arch_ret_to_user, tmp1, tmp2 -	.endm -  	.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp  	ldr     \irqstat, =IO_ADDRESS(GEMINI_INTERRUPT_BASE + IRQ_STATUS)  	ldr     \irqnr, [\irqstat] diff --git a/arch/arm/mach-gemini/include/mach/gpio.h b/arch/arm/mach-gemini/include/mach/gpio.h deleted file mode 100644 index 3bc2c70f298..00000000000 --- a/arch/arm/mach-gemini/include/mach/gpio.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Gemini gpiolib specific defines - * - * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> - * - * 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 of the License, or - * (at your option) any later version. - */ - -#ifndef __MACH_GPIO_H__ -#define __MACH_GPIO_H__ - -#include <mach/irqs.h> -#include <asm-generic/gpio.h> - -#define gpio_get_value	__gpio_get_value -#define gpio_set_value	__gpio_set_value -#define gpio_cansleep	__gpio_cansleep - -#define gpio_to_irq(x)	((x) + GPIO_IRQ_BASE) -#define irq_to_gpio(x)	((x) - GPIO_IRQ_BASE) - -#endif /* __MACH_GPIO_H__ */ diff --git a/arch/arm/mach-gemini/include/mach/hardware.h b/arch/arm/mach-gemini/include/mach/hardware.h index 213a4fcfeb1..98e7b0f286b 100644 --- a/arch/arm/mach-gemini/include/mach/hardware.h +++ b/arch/arm/mach-gemini/include/mach/hardware.h @@ -33,7 +33,7 @@  #define GEMINI_LPC_HOST_BASE	0x47000000  #define GEMINI_LPC_IO_BASE	0x47800000  #define GEMINI_INTERRUPT_BASE	0x48000000 -/* TODO: Different interrupt controlers when SMP +/* TODO: Different interrupt controllers when SMP   * #define GEMINI_INTERRUPT0_BASE	0x48000000   * #define GEMINI_INTERRUPT1_BASE	0x49000000   */ @@ -69,6 +69,6 @@  /*   * macro to get at IO space when running virtually   */ -#define IO_ADDRESS(x)	((((x) & 0xFFF00000) >> 4) | ((x) & 0x000FFFFF) | 0xF0000000) +#define IO_ADDRESS(x)	IOMEM((((x) & 0xFFF00000) >> 4) | ((x) & 0x000FFFFF) | 0xF0000000)  #endif diff --git a/arch/arm/mach-gemini/include/mach/io.h b/arch/arm/mach-gemini/include/mach/io.h deleted file mode 100644 index c548056b98b..00000000000 --- a/arch/arm/mach-gemini/include/mach/io.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - *  Copyright (C) 2001-2006 Storlink, Corp. - *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> - * - * 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 of the License, or - * (at your option) any later version. - */ -#ifndef __MACH_IO_H -#define __MACH_IO_H - -#define IO_SPACE_LIMIT	0xffffffff - -#define __io(a)		__typesafe_io(a) -#define __mem_pci(a)	(a) - -#endif /* __MACH_IO_H */ diff --git a/arch/arm/mach-gemini/include/mach/memory.h b/arch/arm/mach-gemini/include/mach/memory.h deleted file mode 100644 index 2d14d5bf1f9..00000000000 --- a/arch/arm/mach-gemini/include/mach/memory.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - *  Copyright (C) 2001-2006 Storlink, Corp. - *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> - * - * 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 of the License, or - * (at your option) any later version. - */ -#ifndef __MACH_MEMORY_H -#define __MACH_MEMORY_H - -#ifdef CONFIG_GEMINI_MEM_SWAP -# define PHYS_OFFSET	UL(0x00000000) -#else -# define PHYS_OFFSET	UL(0x10000000) -#endif - -#endif /* __MACH_MEMORY_H */ diff --git a/arch/arm/mach-gemini/include/mach/timex.h b/arch/arm/mach-gemini/include/mach/timex.h deleted file mode 100644 index dc5690ba975..00000000000 --- a/arch/arm/mach-gemini/include/mach/timex.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Gemini timex specifications - * - * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> - * - * 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 of the License, or - * (at your option) any later version. - */ - -/* When AHB bus frequency is 150MHz */ -#define CLOCK_TICK_RATE	38000000 diff --git a/arch/arm/mach-gemini/include/mach/uncompress.h b/arch/arm/mach-gemini/include/mach/uncompress.h index 5483f61a806..02e225673ac 100644 --- a/arch/arm/mach-gemini/include/mach/uncompress.h +++ b/arch/arm/mach-gemini/include/mach/uncompress.h @@ -16,7 +16,7 @@  #include <linux/serial_reg.h>  #include <mach/hardware.h> -static volatile unsigned long *UART = (unsigned long *)GEMINI_UART_BASE; +static volatile unsigned long * const UART = (unsigned long *)GEMINI_UART_BASE;  /*   * The following code assumes the serial port has already been @@ -39,6 +39,4 @@ static inline void flush(void)   */  #define arch_decomp_setup() -#define arch_decomp_wdog() -  #endif /* __MACH_UNCOMPRESS_H */ diff --git a/arch/arm/mach-gemini/include/mach/vmalloc.h b/arch/arm/mach-gemini/include/mach/vmalloc.h deleted file mode 100644 index 45371eb86fc..00000000000 --- a/arch/arm/mach-gemini/include/mach/vmalloc.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> - * - * 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 of the License, or - * (at your option) any later version. - */ - -#define VMALLOC_END	0xf0000000UL diff --git a/arch/arm/mach-gemini/irq.c b/arch/arm/mach-gemini/irq.c index 9e613ca8120..44f50dcb616 100644 --- a/arch/arm/mach-gemini/irq.c +++ b/arch/arm/mach-gemini/irq.c @@ -15,8 +15,11 @@  #include <linux/stddef.h>  #include <linux/list.h>  #include <linux/sched.h> +#include <linux/cpu.h> +  #include <asm/irq.h>  #include <asm/mach/irq.h> +#include <asm/system_misc.h>  #include <mach/hardware.h>  #define IRQ_SOURCE(base_addr)	(base_addr + 0x00) @@ -32,40 +35,40 @@  #define FIQ_LEVEL(base_addr)	(base_addr + 0x30)  #define FIQ_STATUS(base_addr)	(base_addr + 0x34) -static void gemini_ack_irq(unsigned int irq) +static void gemini_ack_irq(struct irq_data *d)  { -	__raw_writel(1 << irq, IRQ_CLEAR(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); +	__raw_writel(1 << d->irq, IRQ_CLEAR(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));  } -static void gemini_mask_irq(unsigned int irq) +static void gemini_mask_irq(struct irq_data *d)  {  	unsigned int mask;  	mask = __raw_readl(IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); -	mask &= ~(1 << irq); +	mask &= ~(1 << d->irq);  	__raw_writel(mask, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));  } -static void gemini_unmask_irq(unsigned int irq) +static void gemini_unmask_irq(struct irq_data *d)  {  	unsigned int mask;  	mask = __raw_readl(IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); -	mask |= (1 << irq); +	mask |= (1 << d->irq);  	__raw_writel(mask, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));  }  static struct irq_chip gemini_irq_chip = { -	.name	= "INTC", -	.ack	= gemini_ack_irq, -	.mask	= gemini_mask_irq, -	.unmask	= gemini_unmask_irq, +	.name		= "INTC", +	.irq_ack	= gemini_ack_irq, +	.irq_mask	= gemini_mask_irq, +	.irq_unmask	= gemini_unmask_irq,  };  static struct resource irq_resource = {  	.name	= "irq_handler", -	.start	= IO_ADDRESS(GEMINI_INTERRUPT_BASE), -	.end	= IO_ADDRESS(FIQ_STATUS(GEMINI_INTERRUPT_BASE)) + 4, +	.start	= GEMINI_INTERRUPT_BASE, +	.end	= FIQ_STATUS(GEMINI_INTERRUPT_BASE) + 4,  };  void __init gemini_init_irq(void) @@ -73,21 +76,21 @@ void __init gemini_init_irq(void)  	unsigned int i, mode = 0, level = 0;  	/* -	 * Disable arch_idle() by default since it is buggy -	 * For more info see arch/arm/mach-gemini/include/mach/system.h +	 * Disable the idle handler by default since it is buggy +	 * For more info see arch/arm/mach-gemini/idle.c  	 */ -	disable_hlt(); +	cpu_idle_poll_ctrl(true);  	request_resource(&iomem_resource, &irq_resource);  	for (i = 0; i < NR_IRQS; i++) { -		set_irq_chip(i, &gemini_irq_chip); +		irq_set_chip(i, &gemini_irq_chip);  		if((i >= IRQ_TIMER1 && i <= IRQ_TIMER3) || (i >= IRQ_SERIRQ0 && i <= IRQ_SERIRQ1)) { -			set_irq_handler(i, handle_edge_irq); +			irq_set_handler(i, handle_edge_irq);  			mode |= 1 << i;  			level |= 1 << i;  		} else {			 -			set_irq_handler(i, handle_level_irq); +			irq_set_handler(i, handle_level_irq);  		}  		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);  	} diff --git a/arch/arm/mach-gemini/mm.c b/arch/arm/mach-gemini/mm.c index 51948242ec0..2c2cd284bb6 100644 --- a/arch/arm/mach-gemini/mm.c +++ b/arch/arm/mach-gemini/mm.c @@ -19,57 +19,57 @@  /* Page table mapping for I/O region */  static struct map_desc gemini_io_desc[] __initdata = {  	{ -		.virtual	= IO_ADDRESS(GEMINI_GLOBAL_BASE), +		.virtual	= (unsigned long)IO_ADDRESS(GEMINI_GLOBAL_BASE),  		.pfn		=__phys_to_pfn(GEMINI_GLOBAL_BASE),  		.length		= SZ_512K,  		.type 		= MT_DEVICE,  	}, { -		.virtual	= IO_ADDRESS(GEMINI_UART_BASE), +		.virtual	= (unsigned long)IO_ADDRESS(GEMINI_UART_BASE),  		.pfn		= __phys_to_pfn(GEMINI_UART_BASE),  		.length		= SZ_512K,  		.type 		= MT_DEVICE,  	}, { -		.virtual	= IO_ADDRESS(GEMINI_TIMER_BASE), +		.virtual	= (unsigned long)IO_ADDRESS(GEMINI_TIMER_BASE),  		.pfn		= __phys_to_pfn(GEMINI_TIMER_BASE),  		.length		= SZ_512K,  		.type 		= MT_DEVICE,  	}, { -		.virtual	= IO_ADDRESS(GEMINI_INTERRUPT_BASE), +		.virtual	= (unsigned long)IO_ADDRESS(GEMINI_INTERRUPT_BASE),  		.pfn		= __phys_to_pfn(GEMINI_INTERRUPT_BASE),  		.length		= SZ_512K,  		.type 		= MT_DEVICE,  	}, { -		.virtual	= IO_ADDRESS(GEMINI_POWER_CTRL_BASE), +		.virtual	= (unsigned long)IO_ADDRESS(GEMINI_POWER_CTRL_BASE),  		.pfn		= __phys_to_pfn(GEMINI_POWER_CTRL_BASE),  		.length		= SZ_512K,  		.type 		= MT_DEVICE,  	}, { -		.virtual	= IO_ADDRESS(GEMINI_GPIO_BASE(0)), +		.virtual	= (unsigned long)IO_ADDRESS(GEMINI_GPIO_BASE(0)),  		.pfn		= __phys_to_pfn(GEMINI_GPIO_BASE(0)),  		.length		= SZ_512K,  		.type 		= MT_DEVICE,  	}, { -		.virtual	= IO_ADDRESS(GEMINI_GPIO_BASE(1)), +		.virtual	= (unsigned long)IO_ADDRESS(GEMINI_GPIO_BASE(1)),  		.pfn		= __phys_to_pfn(GEMINI_GPIO_BASE(1)),  		.length		= SZ_512K,  		.type 		= MT_DEVICE,  	}, { -		.virtual	= IO_ADDRESS(GEMINI_GPIO_BASE(2)), +		.virtual	= (unsigned long)IO_ADDRESS(GEMINI_GPIO_BASE(2)),  		.pfn		= __phys_to_pfn(GEMINI_GPIO_BASE(2)),  		.length		= SZ_512K,  		.type 		= MT_DEVICE,  	}, { -		.virtual	= IO_ADDRESS(GEMINI_FLASH_CTRL_BASE), +		.virtual	= (unsigned long)IO_ADDRESS(GEMINI_FLASH_CTRL_BASE),  		.pfn		= __phys_to_pfn(GEMINI_FLASH_CTRL_BASE),  		.length		= SZ_512K,  		.type 		= MT_DEVICE,  	}, { -		.virtual	= IO_ADDRESS(GEMINI_DRAM_CTRL_BASE), +		.virtual	= (unsigned long)IO_ADDRESS(GEMINI_DRAM_CTRL_BASE),  		.pfn		= __phys_to_pfn(GEMINI_DRAM_CTRL_BASE),  		.length		= SZ_512K,  		.type 		= MT_DEVICE,  	}, { -		.virtual	= IO_ADDRESS(GEMINI_GENERAL_DMA_BASE), +		.virtual	= (unsigned long)IO_ADDRESS(GEMINI_GENERAL_DMA_BASE),  		.pfn		= __phys_to_pfn(GEMINI_GENERAL_DMA_BASE),  		.length		= SZ_512K,  		.type 		= MT_DEVICE, diff --git a/arch/arm/mach-gemini/include/mach/system.h b/arch/arm/mach-gemini/reset.c index 4d9c1f87247..b26659759e2 100644 --- a/arch/arm/mach-gemini/include/mach/system.h +++ b/arch/arm/mach-gemini/reset.c @@ -14,21 +14,7 @@  #include <mach/hardware.h>  #include <mach/global_reg.h> -static inline void arch_idle(void) -{ -	/* -	 * Because of broken hardware we have to enable interrupts or the CPU -	 * will never wakeup... Acctualy it is not very good to enable -	 * interrupts here since scheduler can miss a tick, but there is -	 * no other way around this. Platforms that needs it for power saving -	 * should call enable_hlt() in init code, since by default it is -	 * disabled. -	 */ -	local_irq_enable(); -	cpu_do_idle(); -} - -static inline void arch_reset(char mode, const char *cmd) +void gemini_restart(char mode, const char *cmd)  {  	__raw_writel(RESET_GLOBAL | RESET_CPU1,  		     IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_RESET); diff --git a/arch/arm/mach-gemini/time.c b/arch/arm/mach-gemini/time.c index 21dc5a89d1c..0a63c4d25b6 100644 --- a/arch/arm/mach-gemini/time.c +++ b/arch/arm/mach-gemini/time.c @@ -13,6 +13,8 @@  #include <mach/hardware.h>  #include <mach/global_reg.h>  #include <asm/mach/time.h> +#include <linux/clockchips.h> +#include <linux/clocksource.h>  /*   * Register definitions for the timers @@ -33,19 +35,89 @@  #define TIMER_3_CR_CLOCK		(1 << 7)  #define TIMER_3_CR_INT			(1 << 8) +static unsigned int tick_rate; + +static int gemini_timer_set_next_event(unsigned long cycles, +				       struct clock_event_device *evt) +{ +	u32 cr; + +	cr = readl(TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE))); + +	/* This may be overdoing it, feel free to test without this */ +	cr &= ~TIMER_2_CR_ENABLE; +	cr &= ~TIMER_2_CR_INT; +	writel(cr, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE))); + +	/* Set next event */ +	writel(cycles, TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER2_BASE))); +	writel(cycles, TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER2_BASE))); +	cr |= TIMER_2_CR_ENABLE; +	cr |= TIMER_2_CR_INT; +	writel(cr, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE))); + +	return 0; +} + +static void gemini_timer_set_mode(enum clock_event_mode mode, +				  struct clock_event_device *evt) +{ +	u32 period = DIV_ROUND_CLOSEST(tick_rate, HZ); +	u32 cr; + +	switch (mode) { +        case CLOCK_EVT_MODE_PERIODIC: +		/* Start the timer */ +		writel(period, +		       TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER2_BASE))); +		writel(period, +		       TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER2_BASE))); +		cr = readl(TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE))); +		cr |= TIMER_2_CR_ENABLE; +		cr |= TIMER_2_CR_INT; +		writel(cr, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE))); +		break; +	case CLOCK_EVT_MODE_ONESHOT: +	case CLOCK_EVT_MODE_UNUSED: +        case CLOCK_EVT_MODE_SHUTDOWN: +	case CLOCK_EVT_MODE_RESUME: +		/* +		 * Disable also for oneshot: the set_next() call will +		 * arm the timer instead. +		 */ +		cr = readl(TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE))); +		cr &= ~TIMER_2_CR_ENABLE; +		cr &= ~TIMER_2_CR_INT; +		writel(cr, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE))); +		break; +	default: +                break; +	} +} + +/* Use TIMER2 as clock event */ +static struct clock_event_device gemini_clockevent = { +	.name		= "TIMER2", +	.rating		= 300, /* Reasonably fast and accurate clock event */ +	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, +	.set_next_event	= gemini_timer_set_next_event, +	.set_mode	= gemini_timer_set_mode, +}; +  /*   * IRQ handler for the timer   */  static irqreturn_t gemini_timer_interrupt(int irq, void *dev_id)  { -	timer_tick(); +	struct clock_event_device *evt = &gemini_clockevent; +	evt->event_handler(evt);  	return IRQ_HANDLED;  }  static struct irqaction gemini_timer_irq = {  	.name		= "Gemini Timer Tick", -	.flags		= IRQF_DISABLED | IRQF_TIMER, +	.flags		= IRQF_TIMER,  	.handler	= gemini_timer_interrupt,  }; @@ -54,9 +126,9 @@ static struct irqaction gemini_timer_irq = {   */  void __init gemini_timer_init(void)  { -	unsigned int tick_rate, reg_v; +	u32 reg_v; -	reg_v = __raw_readl(IO_ADDRESS(GEMINI_GLOBAL_BASE + GLOBAL_STATUS)); +	reg_v = readl(IO_ADDRESS(GEMINI_GLOBAL_BASE + GLOBAL_STATUS));  	tick_rate = REG_TO_AHB_SPEED(reg_v) * 1000000;  	printk(KERN_INFO "Bus: %dMHz", tick_rate / 1000000); @@ -82,8 +154,17 @@ void __init gemini_timer_init(void)  	 * Make irqs happen for the system timer  	 */  	setup_irq(IRQ_TIMER2, &gemini_timer_irq); -	/* Start the timer */ -	__raw_writel(tick_rate / HZ, TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER2_BASE))); -	__raw_writel(tick_rate / HZ, TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER2_BASE))); -	__raw_writel(TIMER_2_CR_ENABLE | TIMER_2_CR_INT, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE))); + +	/* Enable and use TIMER1 as clock source */ +	writel(0xffffffff, TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER1_BASE))); +	writel(0xffffffff, TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER1_BASE))); +	writel(TIMER_1_CR_ENABLE, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE))); +	if (clocksource_mmio_init(TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER1_BASE)), +				  "TIMER1", tick_rate, 300, 32, +				  clocksource_mmio_readl_up)) +		pr_err("timer: failed to initialize gemini clock source\n"); + +	/* Configure and register the clockevent */ +	clockevents_config_and_register(&gemini_clockevent, tick_rate, +					1, 0xffffffff);  }  | 
