diff options
86 files changed, 982 insertions, 701 deletions
diff --git a/Documentation/i386/boot.txt b/Documentation/i386/boot.txt index 2f75e750e4f5..fc49b79bc1ab 100644 --- a/Documentation/i386/boot.txt +++ b/Documentation/i386/boot.txt @@ -785,3 +785,41 @@ IMPORTANT: All the hooks are required to preserve %esp, %ebp, %esi and After completing your hook, you should jump to the address that was in this field before your boot loader overwrote it (relocated, if appropriate.) + + +**** 32-bit BOOT PROTOCOL + +For machine with some new BIOS other than legacy BIOS, such as EFI, +LinuxBIOS, etc, and kexec, the 16-bit real mode setup code in kernel +based on legacy BIOS can not be used, so a 32-bit boot protocol needs +to be defined. + +In 32-bit boot protocol, the first step in loading a Linux kernel +should be to setup the boot parameters (struct boot_params, +traditionally known as "zero page"). The memory for struct boot_params +should be allocated and initialized to all zero. Then the setup header +from offset 0x01f1 of kernel image on should be loaded into struct +boot_params and examined. The end of setup header can be calculated as +follow: + + 0x0202 + byte value at offset 0x0201 + +In addition to read/modify/write the setup header of the struct +boot_params as that of 16-bit boot protocol, the boot loader should +also fill the additional fields of the struct boot_params as that +described in zero-page.txt. + +After setupping the struct boot_params, the boot loader can load the +32/64-bit kernel in the same way as that of 16-bit boot protocol. + +In 32-bit boot protocol, the kernel is started by jumping to the +32-bit kernel entry point, which is the start address of loaded +32/64-bit kernel. + +At entry, the CPU must be in 32-bit protected mode with paging +disabled; a GDT must be loaded with the descriptors for selectors +__BOOT_CS(0x10) and __BOOT_DS(0x18); both descriptors must be 4G flat +segment; __BOOS_CS must have execute/read permission, and __BOOT_DS +must have read/write permission; CS must be __BOOT_CS and DS, ES, SS +must be __BOOT_DS; interrupt must be disabled; %esi must hold the base +address of the struct boot_params; %ebp, %edi and %ebx must be zero. diff --git a/Documentation/i386/zero-page.txt b/Documentation/i386/zero-page.txt index 6c0817c45683..169ad423a3d1 100644 --- a/Documentation/i386/zero-page.txt +++ b/Documentation/i386/zero-page.txt @@ -1,99 +1,31 @@ ---------------------------------------------------------------------------- -!!!!!!!!!!!!!!!WARNING!!!!!!!! -The zero page is a kernel internal data structure, not a stable ABI. It might change -without warning and the kernel has no way to detect old version of it. -If you're writing some external code like a boot loader you should only use -the stable versioned real mode boot protocol described in boot.txt. Otherwise the kernel -might break you at any time. -!!!!!!!!!!!!!WARNING!!!!!!!!!!! ----------------------------------------------------------------------------- +The additional fields in struct boot_params as a part of 32-bit boot +protocol of kernel. These should be filled by bootloader or 16-bit +real-mode setup code of the kernel. References/settings to it mainly +are in: -Summary of boot_params layout (kernel point of view) - ( collected by Hans Lermen and Martin Mares ) - -The contents of boot_params are used to pass parameters from the -16-bit realmode code of the kernel to the 32-bit part. References/settings -to it mainly are in: + include/asm-x86/bootparam.h - arch/i386/boot/setup.S - arch/i386/boot/video.S - arch/i386/kernel/head.S - arch/i386/kernel/setup.c - -Offset Type Description ------- ---- ----------- - 0 32 bytes struct screen_info, SCREEN_INFO - ATTENTION, overlaps the following !!! - 2 unsigned short EXT_MEM_K, extended memory size in Kb (from int 0x15) - 0x20 unsigned short CL_MAGIC, commandline magic number (=0xA33F) - 0x22 unsigned short CL_OFFSET, commandline offset - Address of commandline is calculated: - 0x90000 + contents of CL_OFFSET - (only taken, when CL_MAGIC = 0xA33F) - 0x40 20 bytes struct apm_bios_info, APM_BIOS_INFO - 0x60 16 bytes Intel SpeedStep (IST) BIOS support information - 0x80 16 bytes hd0-disk-parameter from intvector 0x41 - 0x90 16 bytes hd1-disk-parameter from intvector 0x46 +Offset Proto Name Meaning +/Size - 0xa0 16 bytes System description table truncated to 16 bytes. - ( struct sys_desc_table_struct ) - 0xb0 - 0x13f Free. Add more parameters here if you really need them. - 0x140- 0x1be EDID_INFO Video mode setup - -0x1c4 unsigned long EFI system table pointer -0x1c8 unsigned long EFI memory descriptor size -0x1cc unsigned long EFI memory descriptor version -0x1d0 unsigned long EFI memory descriptor map pointer -0x1d4 unsigned long EFI memory descriptor map size -0x1e0 unsigned long ALT_MEM_K, alternative mem check, in Kb -0x1e4 unsigned long Scratch field for the kernel setup code -0x1e8 char number of entries in E820MAP (below) -0x1e9 unsigned char number of entries in EDDBUF (below) -0x1ea unsigned char number of entries in EDD_MBR_SIG_BUFFER (below) -0x1f1 char size of setup.S, number of sectors -0x1f2 unsigned short MOUNT_ROOT_RDONLY (if !=0) -0x1f4 unsigned short size of compressed kernel-part in the - (b)zImage-file (in 16 byte units, rounded up) -0x1f6 unsigned short swap_dev (unused AFAIK) -0x1f8 unsigned short RAMDISK_FLAGS -0x1fa unsigned short VGA-Mode (old one) -0x1fc unsigned short ORIG_ROOT_DEV (high=Major, low=minor) -0x1ff char AUX_DEVICE_INFO - -0x200 short jump to start of setup code aka "reserved" field. -0x202 4 bytes Signature for SETUP-header, ="HdrS" -0x206 unsigned short Version number of header format - Current version is 0x0201... -0x208 8 bytes (used by setup.S for communication with boot loaders, - look there) -0x210 char LOADER_TYPE, = 0, old one - else it is set by the loader: - 0xTV: T=0 for LILO - 1 for Loadlin - 2 for bootsect-loader - 3 for SYSLINUX - 4 for ETHERBOOT - 5 for ELILO - 7 for GRuB - 8 for U-BOOT - 9 for Xen - V = version -0x211 char loadflags: - bit0 = 1: kernel is loaded high (bzImage) - bit7 = 1: Heap and pointer (see below) set by boot - loader. -0x212 unsigned short (setup.S) -0x214 unsigned long KERNEL_START, where the loader started the kernel -0x218 unsigned long INITRD_START, address of loaded ramdisk image -0x21c unsigned long INITRD_SIZE, size in bytes of ramdisk image -0x220 4 bytes (setup.S) -0x224 unsigned short setup.S heap end pointer -0x226 unsigned short zero_pad -0x228 unsigned long cmd_line_ptr -0x22c unsigned long ramdisk_max -0x230 16 bytes trampoline -0x290 - 0x2cf EDD_MBR_SIG_BUFFER (edd.S) -0x2d0 - 0xd00 E820MAP -0xd00 - 0xeff EDDBUF (edd.S) for disk signature read sector -0xd00 - 0xeeb EDDBUF (edd.S) for edd data +000/040 ALL screen_info Text mode or frame buffer information + (struct screen_info) +040/014 ALL apm_bios_info APM BIOS information (struct apm_bios_info) +060/010 ALL ist_info Intel SpeedStep (IST) BIOS support information + (struct ist_info) +080/010 ALL hd0_info hd0 disk parameter, OBSOLETE!! +090/010 ALL hd1_info hd1 disk parameter, OBSOLETE!! +0A0/010 ALL sys_desc_table System description table (struct sys_desc_table) +140/080 ALL edid_info Video mode setup (struct edid_info) +1C0/020 ALL efi_info EFI 32 information (struct efi_info) +1E0/004 ALL alk_mem_k Alternative mem check, in KB +1E4/004 ALL scratch Scratch field for the kernel setup code +1E8/001 ALL e820_entries Number of entries in e820_map (below) +1E9/001 ALL eddbuf_entries Number of entries in eddbuf (below) +1EA/001 ALL edd_mbr_sig_buf_entries Number of entries in edd_mbr_sig_buffer + (below) +290/040 ALL edd_mbr_sig_buffer EDD MBR signatures +2D0/A00 ALL e820_map E820 memory map table + (array of struct e820entry) +D00/1EC ALL eddbuf EDD data (array of struct edd_info) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 61262c5f9c62..97da953eb5d0 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -583,6 +583,7 @@ config SNI_RM config TOSHIBA_JMR3927 bool "Toshiba JMR-TX3927 board" + select CEVT_TXX9 select DMA_NONCOHERENT select HW_HAS_PCI select MIPS_TX3927 @@ -597,6 +598,7 @@ config TOSHIBA_JMR3927 config TOSHIBA_RBTX4927 bool "Toshiba RBTX49[23]7 board" select CEVT_R4K + select CEVT_TXX9 select DMA_NONCOHERENT select HAS_TXX9_SERIAL select HW_HAS_PCI @@ -618,6 +620,7 @@ config TOSHIBA_RBTX4927 config TOSHIBA_RBTX4938 bool "Toshiba RBTX4938 board" select CEVT_R4K + select CEVT_TXX9 select DMA_NONCOHERENT select HAS_TXX9_SERIAL select HW_HAS_PCI @@ -736,6 +739,9 @@ config CEVT_GT641XX config CEVT_R4K bool +config CEVT_TXX9 + bool + config CFE bool diff --git a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c index 59e932a928d2..ddfb7f0a17a6 100644 --- a/arch/mips/au1000/common/irq.c +++ b/arch/mips/au1000/common/irq.c @@ -318,38 +318,6 @@ static struct irq_chip level_irq_type = { .end = end_irq, }; -#ifdef CONFIG_PM -void startup_match20_interrupt(irq_handler_t handler) -{ - struct irq_desc *desc = &irq_desc[AU1000_TOY_MATCH2_INT]; - - static struct irqaction action; - memset(&action, 0, sizeof(struct irqaction)); - - /* - * This is a big problem.... since we didn't use request_irq - * when kernel/irq.c calls probe_irq_xxx this interrupt will - * be probed for usage. This will end up disabling the device :( - * Give it a bogus "action" pointer -- this will keep it from - * getting auto-probed! - * - * By setting the status to match that of request_irq() we - * can avoid it. --cgray - */ - action.dev_id = handler; - action.flags = IRQF_DISABLED; - cpus_clear(action.mask); - action.name = "Au1xxx TOY"; - action.handler = handler; - action.next = NULL; - - desc->action = &action; - desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS); - - local_enable_irq(AU1000_TOY_MATCH2_INT); -} -#endif - static void __init setup_local_irq(unsigned int irq_nr, int type, int int_req) { unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c index 2556399708ba..f113b512d7b1 100644 --- a/arch/mips/au1000/common/time.c +++ b/arch/mips/au1000/common/time.c @@ -67,7 +67,7 @@ static DEFINE_SPINLOCK(time_lock); unsigned long wtimer; #ifdef CONFIG_PM -irqreturn_t counter0_irq(int irq, void *dev_id) +static irqreturn_t counter0_irq(int irq, void *dev_id) { unsigned long pc0; int time_elapsed; @@ -117,6 +117,13 @@ irqreturn_t counter0_irq(int irq, void *dev_id) return IRQ_HANDLED; } +struct irqaction counter0_action = { + .handler = counter0_irq, + .flags = IRQF_DISABLED, + .name = "alchemy-toy", + .dev_id = NULL, +}; + /* When we wakeup from sleep, we have to "catch up" on all of the * timer ticks we have missed. */ @@ -221,7 +228,7 @@ unsigned long cal_r4koff(void) return (cpu_speed / HZ); } -void __init plat_timer_setup(struct irqaction *irq) +void __init plat_time_init(void) { unsigned int est_freq; @@ -255,15 +262,10 @@ void __init plat_timer_setup(struct irqaction *irq) * we do this. */ if (no_au1xxx_32khz) { - unsigned int c0_status; - printk("WARNING: no 32KHz clock found.\n"); - /* Ensure we get CPO_COUNTER interrupts. - */ - c0_status = read_c0_status(); - c0_status |= IE_IRQ5; - write_c0_status(c0_status); + /* Ensure we get CPO_COUNTER interrupts. */ + set_c0_status(IE_IRQ5); } else { while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S); @@ -280,7 +282,7 @@ void __init plat_timer_setup(struct irqaction *irq) au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2); au_sync(); while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); - startup_match20_interrupt(counter0_irq); + setup_irq(AU1000_TOY_MATCH2_INT, &counter0_action); /* We can use the real 'wait' instruction. */ diff --git a/arch/mips/au1000/mtx-1/Makefile b/arch/mips/au1000/mtx-1/Makefile index 764bf9f7e281..afa7007d67f7 100644 --- a/arch/mips/au1000/mtx-1/Makefile +++ b/arch/mips/au1000/mtx-1/Makefile @@ -8,3 +8,4 @@ # lib-y := init.o board_setup.o irqmap.o +obj-y := platform.o diff --git a/arch/mips/au1000/mtx-1/platform.c b/arch/mips/au1000/mtx-1/platform.c new file mode 100644 index 000000000000..01ebff677978 --- /dev/null +++ b/arch/mips/au1000/mtx-1/platform.c @@ -0,0 +1,86 @@ +/* + * MTX-1 platform devices registration + * + * Copyright (C) 2007, Florian Fainelli <florian@openwrt.org> + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <linux/init.h> +#include <linux/types.h> +#include <linux/platform_device.h> +#include <linux/leds.h> + +#include <asm/gpio.h> + +static struct resource mtx1_wdt_res[] = { + [0] = { + .start = 15, + .end = 15, + .name = "mtx1-wdt-gpio", + .flags = IORESOURCE_IRQ, + } +}; + +static struct resource mtx1_sys_btn[] = { + [0] = { + .start = 7, + .end = 7, + .name = "mtx1-sys-btn-gpio", + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device mtx1_wdt = { + .name = "mtx1-wdt", + .id = 0, + .num_resources = ARRAY_SIZE(mtx1_wdt_res), + .resource = mtx1_wdt_res, +}; + +static struct gpio_led default_leds[] = { + { + .name = "mtx1:green", + .gpio = 211, + }, { + .name = "mtx1:red", + .gpio = 212, + }, +}; + +static struct gpio_led_platform_data mtx1_led_data = { + .num_leds = ARRAY_SIZE(default_leds), + .leds = default_leds, +}; + +static struct platform_device mtx1_gpio_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &mtx1_led_data, + } +}; + +static struct __initdata platform_device * mtx1_devs[] = { + &mtx1_gpio_leds, + &mtx1_wdt +}; + +static int __init mtx1_register_devices(void) +{ + return platform_add_devices(mtx1_devs, ARRAY_SIZE(mtx1_devs)); +} + +arch_initcall(mtx1_register_devices); diff --git a/arch/mips/basler/excite/excite_setup.c b/arch/mips/basler/excite/excite_setup.c index 404ca9284b30..24378b9223f9 100644 --- a/arch/mips/basler/excite/excite_setup.c +++ b/arch/mips/basler/excite/excite_setup.c @@ -68,24 +68,23 @@ DEFINE_SPINLOCK(titan_lock); int titan_irqflags; +/* + * The eXcite platform uses the alternate timer interrupt + * + * Fixme: At the time of this writing cevt-r4k.c doesn't yet know about how + * to handle the alternate timer interrupt of the RM9000. + */ void __init plat_time_init(void) { const u32 modebit5 = ocd_readl(0x00e4); - unsigned int - mult = ((modebit5 >> 11) & 0x1f) + 2, - div = ((modebit5 >> 16) & 0x1f) + 2; + unsigned int mult = ((modebit5 >> 11) & 0x1f) + 2, + unsigned int div = ((modebit5 >> 16) & 0x1f) + 2; - if (div == 33) div = 1; + if (div == 33) + div = 1; mips_hpt_frequency = EXCITE_CPU_EXT_CLOCK * mult / div / 2; } -void __init plat_timer_setup(struct irqaction *irq) -{ - /* The eXcite platform uses the alternate timer interrupt */ - set_c0_intcontrol(0x80); - setup_irq(TIMER_IRQ, irq); -} - static int __init excite_init_console(void) { #if defined(CONFIG_SERIAL_8250) diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig index 885b633647e9..5a8b7acb7dd7 100644 --- a/arch/mips/configs/db1000_defconfig +++ b/arch/mips/configs/db1000_defconfig @@ -738,7 +738,6 @@ CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y # CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_AU1X00_GPIO is not set -# CONFIG_TS_AU1X00_ADS7846 is not set # # Serial drivers diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig index e3c3a07e8a7c..d4ed90bca269 100644 --- a/arch/mips/configs/db1100_defconfig +++ b/arch/mips/configs/db1100_defconfig @@ -714,7 +714,6 @@ CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y # CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_AU1X00_GPIO is not set -# CONFIG_TS_AU1X00_ADS7846 is not set # # Serial drivers diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig index 9aa7c3ebfa3f..a055657e6983 100644 --- a/arch/mips/configs/db1200_defconfig +++ b/arch/mips/configs/db1200_defconfig @@ -775,7 +775,6 @@ CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y # CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_AU1X00_GPIO is not set -# CONFIG_TS_AU1X00_ADS7846 is not set # # Serial drivers diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig index 99240668bca1..0ad08cf446ec 100644 --- a/arch/mips/configs/db1500_defconfig +++ b/arch/mips/configs/db1500_defconfig @@ -811,7 +811,6 @@ CONFIG_SERIO_RAW=m # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_AU1X00_GPIO is not set -# CONFIG_TS_AU1X00_ADS7846 is not set # # Serial drivers diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig index 19992f76c60d..057c7d429c80 100644 --- a/arch/mips/configs/db1550_defconfig +++ b/arch/mips/configs/db1550_defconfig @@ -856,7 +856,6 @@ CONFIG_SERIO_RAW=m # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_AU1X00_GPIO is not set -# CONFIG_TS_AU1X00_ADS7846 is not set # # Serial drivers diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig index d53fa8f8e099..703d28db05b9 100644 --- a/arch/mips/configs/pb1100_defconfig +++ b/arch/mips/configs/pb1100_defconfig @@ -731,7 +731,6 @@ CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y # CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_AU1X00_GPIO is not set -# CONFIG_TS_AU1X00_ADS7846 is not set # # Serial drivers diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig index dc4aa0c66847..82f0c5cee0dc 100644 --- a/arch/mips/configs/pb1500_defconfig +++ b/arch/mips/configs/pb1500_defconfig @@ -849,7 +849,6 @@ CONFIG_SERIO_RAW=m # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_AU1X00_GPIO is not set -# CONFIG_TS_AU1X00_ADS7846 is not set # # Serial drivers diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig index 24428e13002b..147a4fc7fdd8 100644 --- a/arch/mips/configs/pb1550_defconfig +++ b/arch/mips/configs/pb1550_defconfig @@ -842,7 +842,6 @@ CONFIG_SERIO_RAW=m # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_AU1X00_GPIO is not set -# CONFIG_TS_AU1X00_ADS7846 is not set # # Serial drivers diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig index 49dfcef2518c..c2798229cbfb 100644 --- a/arch/mips/configs/sb1250-swarm_defconfig +++ b/arch/mips/configs/sb1250-swarm_defconfig @@ -468,7 +468,7 @@ CONFIG_BLK_DEV_IDEFLOPPY=y # CONFIG_IDE_GENERIC=y # CONFIG_BLK_DEV_IDEPCI is not set -# CONFIG_BLK_DEV_IDE_SWARM is not set +CONFIG_BLK_DEV_IDE_SWARM=y # CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set diff --git a/arch/mips/gt64120/wrppmc/time.c b/arch/mips/gt64120/wrppmc/time.c index b207e7f1417a..668dbd5f12c5 100644 --- a/arch/mips/gt64120/wrppmc/time.c +++ b/arch/mips/gt64120/wrppmc/time.c @@ -19,12 +19,6 @@ #define WRPPMC_CPU_CLK_FREQ 40000000 /* 40MHZ */ -void __init plat_timer_setup(struct irqaction *irq) -{ - /* Install ISR for timer interrupt */ - setup_irq(WRPPMC_MIPS_TIMER_IRQ, irq); -} - /* * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect * diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c index edb9e59248ec..06e01c8f4e3a 100644 --- a/arch/mips/jmr3927/rbhma3100/setup.c +++ b/arch/mips/jmr3927/rbhma3100/setup.c @@ -27,17 +27,13 @@ * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org) */ -#include <linux/clockchips.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/kdev_t.h> #include <linux/types.h> -#include <linux/sched.h> #include <linux/pci.h> #include <linux/ide.h> -#include <linux/irq.h> #include <linux/ioport.h> -#include <linux/param.h> /* for HZ */ #include <linux/delay.h> #include <linux/pm.h> #include <linux/platform_device.h> @@ -48,17 +44,13 @@ #endif #include <asm/addrspace.h> -#include <asm/time.h> +#include <asm/txx9tmr.h> #include <asm/reboot.h> #include <asm/jmr3927/jmr3927.h> #include <asm/mipsregs.h> extern void puts(const char *cp); -/* Tick Timer divider */ -#define JMR3927_TIMER_CCD 0 /* 1/2 */ -#define JMR3927_TIMER_CLK (JMR3927_IMCLK / (2 << JMR3927_TIMER_CCD)) - /* don't enable - see errata */ static int jmr3927_ccfg_toeon; @@ -93,66 +85,12 @@ static void jmr3927_machine_power_off(void) while (1); } -static cycle_t jmr3927_hpt_read(void) -{ - /* We assume this function is called xtime_lock held. */ - return jiffies * (JMR3927_TIMER_CLK / HZ) + jmr3927_tmrptr->trr; -} - -static void jmr3927_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - /* Nothing to do here */ -} - -struct clock_event_device jmr3927_clock_event_device = { - .name = "MIPS", - .features = CLOCK_EVT_FEAT_PERIODIC, - .shift = 32, - .rating = 300, - .cpumask = CPU_MASK_CPU0, - .irq = JMR3927_IRQ_TICK, - .set_mode = jmr3927_set_mode, -}; - -static irqreturn_t jmr3927_timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *cd = &jmr3927_clock_event_device; - - jmr3927_tmrptr->tisr = 0; /* ack interrupt */ - - cd->event_handler(cd); - - return IRQ_HANDLED; -} - -static struct irqaction jmr3927_timer_irqaction = { - .handler = jmr3927_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_PERCPU, - .name = "jmr3927-timer", -}; - void __init plat_time_init(void) { - struct clock_event_device *cd; - - clocksource_mips.read = jmr3927_hpt_read; - mips_hpt_frequency = JMR3927_TIMER_CLK; - - jmr3927_tmrptr->cpra = JMR3927_TIMER_CLK / HZ; - jmr3927_tmrptr->itmr = TXx927_TMTITMR_TIIE | TXx927_TMTITMR_TZCE; - jmr3927_tmrptr->ccdr = JMR3927_TIMER_CCD; - jmr3927_tmrptr->tcr = - TXx927_TMTCR_TCE | TXx927_TMTCR_CCDE | TXx927_TMTCR_TMODE_ITVL; - - cd = &jmr3927_clock_event_device; - /* Calculate the min / max delta */ - cd->mult = div_sc((unsigned long) JMR3927_IMCLK, NSEC_PER_SEC, 32); - cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); - cd->min_delta_ns = clockevent_delta2ns(0x300, cd); - clockevents_register_device(cd); - - setup_irq(JMR3927_IRQ_TICK, &jmr3927_timer_irqaction); + txx9_clockevent_init(TX3927_TMR_REG(0), + TXX9_IRQ_BASE + JMR3927_IRQ_IRC_TMR(0), + JMR3927_IMCLK); + txx9_clocksource_init(TX3927_TMR_REG(1), JMR3927_IMCLK); } #define DO_WRITE_THROUGH @@ -317,15 +255,8 @@ static void __init tx3927_setup(void) tx3927_ccfgptr->ccfg, tx3927_ccfgptr->pcfg); /* TMR */ - /* disable all timers */ - for (i = 0; i < TX3927_NR_TMR; i++) { - tx3927_tmrptr(i)->tcr = TXx927_TMTCR_CRE; - tx3927_tmrptr(i)->tisr = 0; - tx3927_tmrptr(i)->cpra = 0xffffffff; - tx3927_tmrptr(i)->itmr = 0; - tx3927_tmrptr(i)->ccdr = 0; - tx3927_tmrptr(i)->pgmr = 0; - } + for (i = 0; i < TX3927_NR_TMR; i++) + txx9_tmr_init(TX3927_TMR_REG(i)); /* DMA */ tx3927_dmaptr->mcr = 0; diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index d7745c8976f6..3196509a28d5 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -10,6 +10,7 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o +obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \ irix5sys.o sysirix.o diff --git a/arch/mips/kernel/cevt-gt641xx.c b/arch/mips/kernel/cevt-gt641xx.c index 4c651b2680f9..c36772631fe0 100644 --- a/arch/mips/kernel/cevt-gt641xx.c +++ b/arch/mips/kernel/cevt-gt641xx.c @@ -49,10 +49,9 @@ int gt641xx_timer0_state(void) static int gt641xx_timer0_set_next_event(unsigned long delta, struct clock_event_device *evt) { - unsigned long flags; u32 ctrl; - spin_lock_irqsave(>641xx_timer_lock, flags); + spin_lock(>641xx_timer_lock); ctrl = GT_READ(GT_TC_CONTROL_OFS); ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK); @@ -61,7 +60,7 @@ static int gt641xx_timer0_set_next_event(unsigned long delta, GT_WRITE(GT_TC0_OFS, delta); GT_WRITE(GT_TC_CONTROL_OFS, ctrl); - spin_unlock_irqrestore(>641xx_timer_lock, flags); + spin_unlock(>641xx_timer_lock); return 0; } @@ -69,10 +68,9 @@ static int gt641xx_timer0_set_next_event(unsigned long delta, static void gt641xx_timer0_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { - unsigned long flags; u32 ctrl; - spin_lock_irqsave(>641xx_timer_lock, flags); + spin_lock(>641xx_timer_lock); ctrl = GT_READ(GT_TC_CONTROL_OFS); ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK); @@ -90,7 +88,7 @@ static void gt641xx_timer0_set_mode(enum clock_event_mode mode, GT_WRITE(GT_TC_CONTROL_OFS, ctrl); - spin_unlock_irqrestore(>641xx_timer_lock, flags); + spin_unlock(>641xx_timer_lock); } static void gt641xx_timer0_event_handler(struct clock_event_device *dev) @@ -133,9 +131,9 @@ static int __init gt641xx_timer0_clockevent_init(void) cd = >641xx_timer0_clockevent; cd->rating = 200 + gt641xx_base_clock / 10000000; + clockevent_set_clock(cd, gt641xx_base_clock); cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); cd->min_delta_ns = clockevent_delta2ns(0x300, cd); - clockevent_set_clock(cd, gt641xx_base_clock); clockevents_register_device(>641xx_timer0_clockevent); diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index ae2984fff580..bab935a3d74b 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c @@ -28,7 +28,7 @@ static int mips_next_event(unsigned long delta, cnt = read_c0_count(); cnt += delta; write_c0_compare(cnt); - res = ((long)(read_c0_count() - cnt ) > 0) ? -ETIME : 0; + res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0; #ifdef CONFIG_MIPS_MT_SMTC evpe(vpflags); local_irq_restore(flags); @@ -179,7 +179,7 @@ static int c0_compare_int_pending(void) static int c0_compare_int_usable(void) { - const unsigned int delta = 0x300000; + unsigned int delta; unsigned int cnt; /* @@ -192,11 +192,17 @@ static int c0_compare_int_usable(void) return 0; } - cnt = read_c0_count(); - cnt += delta; - write_c0_compare(cnt); + for (delta = 0x10; delta <= 0x400000; delta <<= 1) { + cnt = read_c0_count(); + cnt += delta; + write_c0_compare(cnt); + irq_disable_hazard(); + if ((int)(read_c0_count() - cnt) < 0) + break; + /* increase delta if the timer was already expired */ + } - while ((long)(read_c0_count() - cnt) <= 0) + while ((int)(read_c0_count() - cnt) <= 0) ; /* Wait for expiry */ if (!c0_compare_int_pending()) @@ -218,9 +224,9 @@ void __cpuinit mips_clockevent_init(void) uint64_t mips_freq = mips_hpt_frequency; unsigned int cpu = smp_processor_id(); struct clock_event_device *cd; - unsigned int irq = MIPS_CPU_IRQ_BASE + 7; + unsigned int irq; - if (!cpu_has_counter) + if (!cpu_has_counter || !mips_hpt_frequency) return; #ifdef CONFIG_MIPS_MT_SMTC @@ -237,6 +243,15 @@ void __cpuinit mips_clockevent_init(void) if (!c0_compare_int_usable()) return; + /* + * With vectored interrupts things are getting platform specific. + * get_c0_compare_int is a hook to allow a platform to return the + * interrupt number of it's liking. + */ + irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; + if (get_c0_compare_int) + irq = get_c0_compare_int(); + cd = &per_cpu(mips_clockevent_device, cpu); cd->name = "MIPS"; @@ -261,13 +276,15 @@ void __cpuinit mips_clockevent_init(void) clockevents_register_device(cd); - if (!cp0_timer_irq_installed) { + if (!cp0_timer_irq_installed) + return; + + cp0_timer_irq_installed = 1; + #ifdef CONFIG_MIPS_MT_SMTC #define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq) - setup_irq_smtc(irq, &c0_compare_irqaction, CPUCTR_IMASKBIT); + setup_irq_smtc(irq, &c0_compare_irqaction, CPUCTR_IMASKBIT); #else - setup_irq(irq, &c0_compare_irqaction); -#endif /* CONFIG_MIPS_MT_SMTC */ - cp0_timer_irq_installed = 1; - } + setup_irq(irq, &c0_compare_irqaction); +#endif } diff --git a/arch/mips/kernel/cevt-txx9.c b/arch/mips/kernel/cevt-txx9.c new file mode 100644 index 000000000000..795cb8fb0d74 --- /dev/null +++ b/arch/mips/kernel/cevt-txx9.c @@ -0,0 +1,171 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Based on linux/arch/mips/kernel/cevt-r4k.c, + * linux/arch/mips/jmr3927/rbhma3100/setup.c + * + * Copyright 2001 MontaVista Software Inc. + * Copyright (C) 2000-2001 Toshiba Corporation + * Copyright (C) 2007 MIPS Technologies, Inc. + * Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org> + */ +#include <linux/init.h> +#include <linux/interrupt.h> +#include <asm/time.h> +#include <asm/txx9tmr.h> + +#define TCR_BASE (TXx9_TMTCR_CCDE | TXx9_TMTCR_CRE | TXx9_TMTCR_TMODE_ITVL) +#define TIMER_CCD 0 /* 1/2 */ +#define TIMER_CLK(imclk) ((imclk) / (2 << TIMER_CCD)) + +static struct txx9_tmr_reg __iomem *txx9_cs_tmrptr; + +static cycle_t txx9_cs_read(void) +{ + return __raw_readl(&txx9_cs_tmrptr->trr); +} + +/* Use 1 bit smaller width to use full bits in that width */ +#define TXX9_CLOCKSOURCE_BITS (TXX9_TIMER_BITS - 1) + +static struct clocksource txx9_clocksource = { + .name = "TXx9", + .rating = 200, + .read = txx9_cs_read, + .mask = CLOCKSOURCE_MASK(TXX9_CLOCKSOURCE_BITS), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +void __init txx9_clocksource_init(unsigned long baseaddr, + unsigned int imbusclk) +{ + struct txx9_tmr_reg __iomem *tmrptr; + + clocksource_set_clock(&txx9_clocksource, TIMER_CLK(imbusclk)); + clocksource_register(&txx9_clocksource); + + tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg)); + __raw_writel(TCR_BASE, &tmrptr->tcr); + __raw_writel(0, &tmrptr->tisr); + __raw_writel(TIMER_CCD, &tmrptr->ccdr); + __raw_writel(TXx9_TMITMR_TZCE, &tmrptr->itmr); + __raw_writel(1 << TXX9_CLOCKSOURCE_BITS, &tmrptr->cpra); + __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr); + txx9_cs_tmrptr = tmrptr; +} + +static struct txx9_tmr_reg __iomem *txx9_tmrptr; + +static void txx9tmr_stop_and_clear(struct txx9_tmr_reg __iomem *tmrptr) +{ + /* stop and reset counter */ + __raw_writel(TCR_BASE, &tmrptr->tcr); + /* clear pending interrupt */ + __raw_writel(0, &tmrptr->tisr); +} + +static void txx9tmr_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr; + + txx9tmr_stop_and_clear(tmrptr); + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + __raw_writel(TXx9_TMITMR_TIIE | TXx9_TMITMR_TZCE, + &tmrptr->itmr); + /* start timer */ + __raw_writel(((u64)(NSEC_PER_SEC / HZ) * evt->mult) >> + evt->shift, + &tmrptr->cpra); + __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr); + break; + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: + __raw_writel(0, &tmrptr->itmr); + break; + case CLOCK_EVT_MODE_ONESHOT: + __raw_writel(TXx9_TMITMR_TIIE, &tmrptr->itmr); + break; + case CLOCK_EVT_MODE_RESUME: + __raw_writel(TIMER_CCD, &tmrptr->ccdr); + __raw_writel(0, &tmrptr->itmr); + break; + } +} + +static int txx9tmr_set_next_event(unsigned long delta, + struct clock_event_device *evt) +{ + struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr; + + txx9tmr_stop_and_clear(tmrptr); + /* start timer */ + __raw_writel(delta, &tmrptr->cpra); + __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr); + return 0; +} + +static struct clock_event_device txx9tmr_clock_event_device = { + .name = "TXx9", + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .rating = 200, + .cpumask = CPU_MASK_CPU0, + .set_mode = txx9tmr_set_mode, + .set_next_event = txx9tmr_set_next_event, +}; + +static irqreturn_t txx9tmr_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *cd = &txx9tmr_clock_event_device; + struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr; + + __raw_writel(0, &tmrptr->tisr); /* ack interrupt */ + cd->event_handler(cd); + return IRQ_HANDLED; +} + +static struct irqaction txx9tmr_irq = { + .handler = txx9tmr_interrupt, + .flags = IRQF_DISABLED | IRQF_PERCPU, + .name = "txx9tmr", +}; + +void __init txx9_clockevent_init(unsigned long baseaddr, int irq, + unsigned int imbusclk) +{ + struct clock_event_device *cd = &txx9tmr_clock_event_device; + struct txx9_tmr_reg __iomem *tmrptr; + + tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg)); + txx9tmr_stop_and_clear(tmrptr); + __raw_writel(TIMER_CCD, &tmrptr->ccdr); + __raw_writel(0, &tmrptr->itmr); + txx9_tmrptr = tmrptr; + + clockevent_set_clock(cd, TIMER_CLK(imbusclk)); + cd->max_delta_ns = + clockevent_delta2ns(0xffffffff >> (32 - TXX9_TIMER_BITS), cd); + cd->min_delta_ns = clockevent_delta2ns(0xf, cd); + cd->irq = irq; + clockevents_register_device(cd); + setup_irq(irq, &txx9tmr_irq); + printk(KERN_INFO "TXx9: clockevent device at 0x%lx, irq %d\n", + baseaddr, irq); +} + +void __init txx9_tmr_init(unsigned long baseaddr) +{ + struct txx9_tmr_reg __iomem *tmrptr; + + tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg)); + __raw_writel(TXx9_TMTCR_CRE, &tmrptr->tcr); + __raw_writel(0, &tmrptr->tisr); + __raw_writel(0xffffffff, &tmrptr->cpra); + __raw_writel(0, &tmrptr->itmr); + __raw_writel(0, &tmrptr->ccdr); + __raw_writel(0, &tmrptr->pgmr); + iounmap(tmrptr); +} diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c index a0a91056fda7..33506ff25910 100644 --- a/arch/mips/kernel/irixsig.c +++ b/arch/mips/kernel/irixsig.c @@ -24,8 +24,12 @@ #define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP))) +#define _IRIX_NSIG 128 +#define _IRIX_NSIG_BPW BITS_PER_LONG +#define _IRIX_NSIG_WORDS (_IRIX_NSIG / _IRIX_NSIG_BPW) + typedef struct { - unsigned long sig[4]; + unsigned long sig[_IRIX_NSIG_WORDS]; } irix_sigset_t; struct sigctx_irix5 { @@ -527,7 +531,7 @@ asmlinkage int irix_sigpoll_sys(unsigned long __user *set, expire = schedule_timeout_interruptible(expire); - for (i=0; i<=4; i++) + for (i=0; i < _IRIX_NSIG_WORDS; i++) tmp |= (current->pending.signal.sig[i] & kset.sig[i]); if (tmp) diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 999f7853de26..35234b92b9a5 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -65,13 +65,13 @@ int ptrace_getregs(struct task_struct *child, __s64 __user *data) regs = task_pt_regs(child); for (i = 0; i < 32; i++) - __put_user(regs->regs[i], data + i); - __put_user(regs->lo, data + EF_LO - EF_R0); - __put_user(regs->hi, data + EF_HI - EF_R0); - __put_user(regs->cp0_epc, data + EF_CP0_EPC - EF_R0); - __put_user(regs->cp0_badvaddr, data + EF_CP0_BADVADDR - EF_R0); - __put_user(regs->cp0_status, data + EF_CP0_STATUS - EF_R0); - __put_user(regs->cp0_cause, data + EF_CP0_CAUSE - EF_R0); + __put_user((long)regs->regs[i], data + i); + __put_user((long)regs->lo, data + EF_LO - EF_R0); + __put_user((long)regs->hi, data + EF_HI - EF_R0); + __put_user((long)regs->cp0_epc, data + EF_CP0_EPC - EF_R0); + __put_user((long)regs->cp0_badvaddr, data + EF_CP0_BADVADDR - EF_R0); + __put_user((long)regs->cp0_status, data + EF_CP0_STATUS - EF_R0); + __put_user((long)regs->cp0_cause, data + EF_CP0_CAUSE - EF_R0); return 0; } @@ -390,11 +390,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) } case PTRACE_GETREGS: - ret = ptrace_getregs(child, (__u64 __user *) data); + ret = ptrace_getregs(child, (__s64 __user *) data); break; case PTRACE_SETREGS: - ret = ptrace_setregs(child, (__u64 __user *) data); + ret = ptrace_setregs(child, (__s64 __user *) data); break; case PTRACE_GETFPREGS: diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c index f2bffed94fa3..76818be6ba7c 100644 --- a/arch/mips/kernel/ptrace32.c +++ b/arch/mips/kernel/ptrace32.c @@ -346,11 +346,11 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) } case PTRACE_GETREGS: - ret = ptrace_getregs(child, (__u64 __user *) (__u64) data); + ret = ptrace_getregs(child, (__s64 __user *) (__u64) data); break; case PTRACE_SETREGS: - ret = ptrace_setregs(child, (__u64 __user *) (__u64) data); + ret = ptrace_setregs(child, (__s64 __user *) (__u64) data); break; case PTRACE_GETFPREGS: diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index a8c1a698d588..9c92d42996cb 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -88,11 +88,19 @@ unsigned int smtc_status = 0; /* Boot command line configuration overrides */ +static int vpe0limit; static int ipibuffers = 0; static int nostlb = 0; static int asidmask = 0; unsigned long smtc_asid_mask = 0xff; +static int __init vpe0tcs(char *str) +{ + get_option(&str, &vpe0limit); + + return 1; +} + static int __init ipibufs(char *str) { get_option(&str, &ipibuffers); @@ -125,6 +133,7 @@ static int __init asidmask_set(char *str) return 1; } +__setup("vpe0tcs=", vpe0tcs); __setup("ipibufs=", ipibufs); __setup("nostlb", stlb_disable); __setup("asidmask=", asidmask_set); @@ -340,7 +349,7 @@ static void smtc_tc_setup(int vpe, int tc, int cpu) void mipsmt_prepare_cpus(void) { - int i, vpe, tc, ntc, nvpe, tcpervpe, slop, cpu; + int i, vpe, tc, ntc, nvpe, tcpervpe[NR_CPUS], slop, cpu; unsigned long flags; unsigned long val; int nipi; @@ -401,8 +410,39 @@ void mipsmt_prepare_cpus(void) ntc = NR_CPUS; if (tclimit > 0 && ntc > tclimit) ntc = tclimit; - tcpervpe = ntc / nvpe; - slop = ntc % nvpe; /* Residual TCs, < NVPE */ + slop = ntc % nvpe; + for (i = 0; i < nvpe; i++) { + tcpervpe[i] = ntc / nvpe; + if (slop) { + if((slop - i) > 0) tcpervpe[i]++; + } + } + /* Handle command line override for VPE0 */ + if (vpe0limit > ntc) vpe0limit = ntc; + if (vpe0limit > 0) { + int slopslop; + if (vpe0limit < tcpervpe[0]) { + /* Reducing TC count - distribute to others */ + slop = tcpervpe[0] - vpe0limit; + slopslop = slop % (nvpe - 1); + tcpervpe[0] = vpe0limit; + for (i = 1; i < nvpe; i++) { + tcpervpe[i] += slop / (nvpe - 1); + if(slopslop && ((slopslop - (i - 1) > 0))) + tcpervpe[i]++; + } + } else if (vpe0limit > tcpervpe[0]) { + /* Increasing TC count - steal from others */ + slop = vpe0limit - tcpervpe[0]; + slopslop = slop % (nvpe - 1); + tcpervpe[0] = vpe0limit; + for (i = 1; i < nvpe; i++) { + tcpervpe[i] -= slop / (nvpe - 1); + if(slopslop && ((slopslop - (i - 1) > 0))) + tcpervpe[i]--; + } + } + } /* Set up shared TLB */ smtc_configure_tlb(); @@ -416,7 +456,7 @@ void mipsmt_prepare_cpus(void) if (vpe != 0) printk(", "); printk("VPE %d: TC", vpe); - for (i = 0; i < tcpervpe; i++) { + for (i = 0; i < tcpervpe[vpe]; i++) { /* * TC 0 is bound to VPE 0 at reset, * and is presumably executing this @@ -429,15 +469,6 @@ void mipsmt_prepare_cpus(void) printk(" %d", tc); tc++; } - if (slop) { - if (tc != 0) { - smtc_tc_setup(vpe, tc, cpu); - cpu++; - } - printk(" %d", tc); - tc++; - slop--; - } if (vpe != 0) { /* * Clear any stale software interrupts from VPE's Cause diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index b95fe93dd646..af1bdc897488 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -73,7 +73,14 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, task_size = STACK_TOP; + if (len > task_size) + return -ENOMEM; + if (flags & MAP_FIXED) { + /* Even MAP_FIXED mappings must reside within task_size. */ + if (task_size - len < addr) + return -EINVAL; + /* * We do not accept a shared mapping if it would violate * cache aliasing constraints. @@ -83,8 +90,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, return addr; } - if (len > task_size) - return -ENOMEM; do_color_align = 0; if (filp || (flags & MAP_SHARED)) do_color_align = 1; diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 6c6849a8f136..27228f583dae 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -11,6 +11,7 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ +#include <linux/bug.h> #include <linux/clockchips.h> #include <linux/types.h> #include <linux/kernel.h> @@ -115,10 +116,6 @@ EXPORT_SYMBOL(perf_irq); * (only needed if you intended to use cpu counter as timer interrupt * source) * 2) calculate a couple of cached variables for later usage - * 3) plat_timer_setup() - - * a) (optional) over-write any choices made above by time_init(). - * b) machine specific code should setup the timer irqaction. - * c) enable the timer interrupt */ unsigned int mips_hpt_frequency; @@ -221,8 +218,18 @@ void __init __weak plat_time_init(void) { } -void __init __weak plat_timer_setup(struct irqaction *irq) +/* + * This function exists in order to cause an error due to a duplicate + * definition if platform code should have its own implementation. The hook + * to use instead is plat_time_init. plat_time_init does not receive the + * irqaction pointer argument anymore. This is because any function which + * initializes an interrupt timer now takes care of its own request_irq rsp. + * setup_irq calls and each clock_event_device should use its own + * struct irqrequest. + */ +void __init plat_timer_setup(struct irqaction *irq) { + BUG(); } void __init time_init(void) diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 2781cff1485e..5fc2398bdb76 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -63,21 +63,23 @@ SECTIONS /* writeable */ .data : { /* Data */ - . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */ - /* - * This ALIGN is needed as a workaround for a bug a gcc bug upto 4.1 which - * limits the maximum alignment to at most 32kB and results in the following - * warning: - * - * CC arch/mips/kernel/init_task.o - * arch/mips/kernel/init_task.c:30: warning: alignment of ‘init_thread_union’ - * is greater than maximum object file alignment. Using 32768 - */ - . = ALIGN(_PAGE_SIZE); - *(.data.init_task) - - DATA_DATA - CONSTRUCTORS + . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */ + /* + * This ALIGN is needed as a workaround for a bug a + * gcc bug upto 4.1 which limits the maximum alignment + * to at most 32kB and results in the following + * warning: + * + * CC arch/mips/kernel/init_task.o + * arch/mips/kernel/init_task.c:30: warning: alignment + * of ‘init_thread_union’ is greater than maximum + * object file alignment. Using 32768 + */ + . = ALIGN(_PAGE_SIZE); + *(.data.init_task) + + DATA_DATA + CONSTRUCTORS } _gp = . + 0x8000; .lit8 : { diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index df8cbe4c7c0d..436a64ff3989 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -942,8 +942,8 @@ static int vpe_elfload(struct vpe * v) if (phdr->p_type != PT_LOAD) continue; - memcpy((void *)phdr->p_vaddr, (char *)hdr + phdr->p_offset, phdr->p_filesz); - memset((void *)phdr->p_vaddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); + memcpy((void *)phdr->p_paddr, (char *)hdr + phdr->p_offset, phdr->p_filesz); + memset((void *)phdr->p_paddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); phdr++; } diff --git a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c index 54827d0174bf..e072da4ff3b3 100644 --- a/arch/mips/lasat/setup.c +++ b/arch/mips/lasat/setup.c @@ -117,14 +117,11 @@ static struct notifier_block lasat_panic_block[] = } }; -void plat_time_init(void) +void __init plat_time_init(void) { mips_hpt_frequency = lasat_board_info.li_cpu_hz / 2; -} -void __init plat_timer_setup(struct irqaction *irq) -{ - change_c0_status(ST0_IM, IE_IRQ0 | IE_IRQ5); + change_c0_status(ST0_IM, IE_IRQ0); } void __init plat_mem_setup(void) diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index 9d6243a8c15a..f02ce6308e51 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/arch/mips/mips-boards/generic/time.c @@ -127,26 +127,6 @@ unsigned long read_persistent_clock(void) return mc146818_get_cmos_time(); } -void __init plat_time_init(void) -{ - unsigned int est_freq; - - /* Set Data mode - binary. */ - CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); - - est_freq = estimate_cpu_frequency(); - - printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, - (est_freq%1000000)*100/1000000); - - cpu_khz = est_freq / 1000; - - mips_scroll_message(); -#ifdef CONFIG_I8253 /* Only Malta has a PIT */ - setup_pit_timer(); -#endif -} - void __init plat_perf_setup(void) { cp0_perfcount_irq = -1; @@ -166,14 +146,13 @@ void __init plat_perf_setup(void) } } -void __init plat_timer_setup(struct irqaction *irq) +unsigned int __init get_c0_compare_int(void) { #ifdef MSC01E_INT_BASE if (cpu_has_veic) { set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; - } - else + } else #endif { if (cpu_has_vint) @@ -181,13 +160,26 @@ void __init plat_timer_setup(struct irqaction *irq) mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; } -#ifdef CONFIG_MIPS_MT_SMTC - setup_irq_smtc(mips_cpu_timer_irq, irq, 0x100 << cp0_compare_irq); -#else - setup_irq(mips_cpu_timer_irq, irq); -#endif /* CONFIG_MIPS_MT_SMTC */ -#ifdef CONFIG_SMP - set_irq_handler(mips_cpu_timer_irq, handle_percpu_irq); + return mips_cpu_timer_irq; +} + +void __init plat_time_init(void) +{ + unsigned int est_freq; + + /* Set Data mode - binary. */ + CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); + + est_freq = estimate_cpu_frequency(); + + printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, + (est_freq%1000000)*100/1000000); + + cpu_khz = est_freq / 1000; + + mips_scroll_message(); +#ifdef CONFIG_I8253 /* Only Malta has a PIT */ + setup_pit_timer(); #endif plat_perf_setup(); diff --git a/arch/mips/mipssim/sim_time.c b/arch/mips/mipssim/sim_time.c index e7fa0d1078a3..bfaafa38846f 100644 --- a/arch/mips/mipssim/sim_time.c +++ b/arch/mips/mipssim/sim_time.c @@ -75,25 +75,6 @@ static unsigned int __init estimate_cpu_frequency(void) return count; } -void __init plat_time_init(void) -{ - unsigned int est_freq, flags; - - local_irq_save(flags); - - /* Set Data mode - binary. */ - CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); - - est_freq = estimate_cpu_frequency(); - - printk(KERN_INFO "CPU frequency %d.%02d MHz\n", est_freq / 1000000, - (est_freq % 1000000) * 100 / 1000000); - - cpu_khz = est_freq / 1000; - - local_irq_restore(flags); -} - static int mips_cpu_timer_irq; static void mips_timer_dispatch(void) @@ -102,26 +83,37 @@ static void mips_timer_dispatch(void) } -void __init plat_timer_setup(struct irqaction *irq) +unsigned __init get_c0_compare_int(void) { +#ifdef MSC01E_INT_BASE if (cpu_has_veic) { set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; } else { +#endif if (cpu_has_vint) set_vi_handler(cp0_compare_irq, mips_timer_dispatch); mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; } - /* we are using the cpu counter for timer interrupts */ - setup_irq(mips_cpu_timer_irq, irq); + return mips_cpu_timer_irq; +} -#ifdef CONFIG_SMP - /* irq_desc(riptor) is a global resource, when the interrupt overlaps - on seperate cpu's the first one tries to handle the second interrupt. - The effect is that the int remains disabled on the second cpu. - Mark the interrupt with IRQ_PER_CPU to avoid any confusion */ - irq_desc[mips_cpu_timer_irq].flags |= IRQ_PER_CPU; - set_irq_handler(mips_cpu_timer_irq, handle_percpu_irq); -#endif +void __init plat_time_init(void) +{ + unsigned int est_freq, flags; + + local_irq_save(flags); + + /* Set Data mode - binary. */ + CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); + + est_freq = estimate_cpu_frequency(); + + printk(KERN_INFO "CPU frequency %d.%02d MHz\n", est_freq / 1000000, + (est_freq % 1000000) * 100 / 1000000); + + cpu_khz = est_freq / 1000; + + local_irq_restore(flags); } diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c index c55312f6fd3a..562abb77d1d5 100644 --- a/arch/mips/mm/c-r3k.c +++ b/arch/mips/mm/c-r3k.c @@ -7,7 +7,7 @@ * Tx39XX R4k style caches added. HK * Copyright (C) 1998, 1999, 2000 Harald Koerfgen * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov - * Copyright (C) 2001, 2004 Maciej W. Rozycki + * Copyright (C) 2001, 2004, 2007 Maciej W. Rozycki */ #include <linux/init.h> #include <linux/kernel.h> @@ -26,8 +26,6 @@ static unsigned long icache_size, dcache_size; /* Size in bytes */ static unsigned long icache_lsize, dcache_lsize; /* Size in bytes */ -#undef DEBUG_CACHE - unsigned long __init r3k_cache_size(unsigned long ca_flags) { unsigned long flags, status, dummy, size; @@ -217,26 +215,6 @@ static void r3k_flush_dcache_range(unsigned long start, unsigned long end) write_c0_status(flags); } -static inline unsigned long get_phys_page(unsigned long addr, - struct mm_struct *mm) -{ - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; - pte_t *pte; - unsigned long physpage; - - pgd = pgd_offset(mm, addr); - pud = pud_offset(pgd, addr); - pmd = pmd_offset(pud, addr); - pte = pte_offset(pmd, addr); - - if ((physpage = pte_val(*pte)) & _PAGE_VALID) - return KSEG0ADDR(physpage & PAGE_MASK); - - return 0; -} - static inline void r3k_flush_cache_all(void) { } @@ -252,12 +230,40 @@ static void r3k_flush_cache_mm(struct mm_struct *mm) } static void r3k_flush_cache_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end) + unsigned long start, unsigned long end) { } -static void r3k_flush_cache_page(struct vm_area_struct *vma, unsigned long page, unsigned long pfn) +static void r3k_flush_cache_page(struct vm_area_struct *vma, + unsigned long addr, unsigned long pfn) { + unsigned long kaddr = KSEG0ADDR(pfn << PAGE_SHIFT); + int exec = vma->vm_flags & VM_EXEC; + struct mm_struct *mm = vma->vm_mm; + pgd_t *pgdp; + pud_t *pudp; + pmd_t *pmdp; + pte_t *ptep; + + pr_debug("cpage[%08lx,%08lx]\n", + cpu_context(smp_processor_id(), mm), addr); + + /* No ASID => no such page in the cache. */ + if (cpu_context(smp_processor_id(), mm) == 0) + return; + + pgdp = pgd_offset(mm, addr); + pudp = pud_offset(pgdp, addr); + pmdp = pmd_offset(pudp, addr); + ptep = pte_offset(pmdp, addr); + + /* Invalid => no such page in the cache. */ + if (!(pte_val(*ptep) & _PAGE_PRESENT)) + return; + + r3k_flush_dcache_range(kaddr, kaddr + PAGE_SIZE); + if (exec) + r3k_flush_icache_range(kaddr, kaddr + PAGE_SIZE); } static void local_r3k_flush_data_cache_page(void *addr) @@ -272,9 +278,7 @@ static void r3k_flush_cache_sigtramp(unsigned long addr) { unsigned long flags; -#ifdef DEBUG_CACHE - printk("csigtramp[%08lx]", addr); -#endif + pr_debug("csigtramp[%08lx]\n", addr); flags = read_c0_status(); diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index d7088331fb0f..6806d58211b2 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -345,11 +345,26 @@ static void r4k___flush_cache_all(void) r4k_on_each_cpu(local_r4k___flush_cache_all, NULL, 1, 1); } +static inline int has_valid_asid(const struct mm_struct *mm) +{ +#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC) + int i; + + for_each_online_cpu(i) + if (cpu_context(i, mm)) + return 1; + + return 0; +#else + return cpu_context(smp_processor_id(), mm); +#endif +} + static inline void local_r4k_flush_cache_range(void * args) { struct vm_area_struct *vma = args; - if (!(cpu_context(smp_processor_id(), vma->vm_mm))) + if (!(has_valid_asid(vma->vm_mm))) return; r4k_blast_dcache(); @@ -368,7 +383,7 @@ static inline void local_r4k_flush_cache_mm(void * args) { struct mm_struct *mm = args; - if (!cpu_context(smp_processor_id(), mm)) + if (!has_valid_asid(mm)) return; /* @@ -420,7 +435,7 @@ static inline void local_r4k_flush_cache_page(void *args) * If ownes no valid ASID yet, cannot possibly have gotten * this page into the cache. */ - if (cpu_context(smp_processor_id(), mm) == 0) + if (!has_valid_asid(mm)) return; addr &= PAGE_MASK; diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index b1b40527658b..33519ce49540 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -12,8 +12,8 @@ #include <linux/dma-mapping.h> #include <linux/mm.h> #include <linux/module.h> -#include <linux/string.h> #include <linux/scatterlist.h> +#include <linux/string.h> #include <asm/cache.h> #include <asm/io.h> diff --git a/arch/mips/pci/fixup-pmcmsp.c b/arch/mips/pci/fixup-pmcmsp.c index 00261211dbfa..65735b1b7665 100644 --- a/arch/mips/pci/fixup-pmcmsp.c +++ b/arch/mips/pci/fixup-pmcmsp.c @@ -202,7 +202,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev) * RETURNS: IRQ number * ****************************************************************************/ -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { #if !defined(CONFIG_PMC_MSP7120_GW) && !defined(CONFIG_PMC_MSP7120_EVAL) printk(KERN_WARNING "PCI: unknown board, no PCI IRQs assigned.\n"); diff --git a/arch/mips/pci/fixup-tb0219.c b/arch/mips/pci/fixup-tb0219.c index 720a2b720c5c..ed87733f6796 100644 --- a/arch/mips/pci/fixup-tb0219.c +++ b/arch/mips/pci/fixup-tb0219.c @@ -2,7 +2,7 @@ * fixup-tb0219.c, The TANBAC TB0219 specific PCI fixups. * * Copyright (C) 2003 Megasolution Inc. <matsu@megasolution.jp> - * Copyright (C) 2004 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> + * Copyright (C) 2004-2005 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> * * 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 diff --git a/arch/mips/pci/ops-pmcmsp.c b/arch/mips/pci/ops-pmcmsp.c index 059eade96f2e..109c95ca698b 100644 --- a/arch/mips/pci/ops-pmcmsp.c +++ b/arch/mips/pci/ops-pmcmsp.c @@ -404,7 +404,7 @@ int msp_pcibios_config_access(unsigned char access_type, if (pciirqflag == 0) { request_irq(MSP_INT_PCI,/* Hardcoded internal MSP7120 wiring */ bpci_interrupt, - SA_SHIRQ | SA_INTERRUPT, + IRQF_SHARED | IRQF_DISABLED, "PMC MSP PCI Host", preg); pciirqflag = ~0; diff --git a/arch/mips/pmc-sierra/msp71xx/msp_serial.c b/arch/mips/pmc-sierra/msp71xx/msp_serial.c index 15e7b8000b4c..9de34302e5f4 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_serial.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_serial.c @@ -122,7 +122,7 @@ void __init msp_serial_setup(void) up.uartclk = uartclk; up.regshift = 2; up.iotype = UPIO_DWAPB; /* UPIO_MEM like */ - up.flags = STD_COM_FLAGS; + up.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; up.type = PORT_16550A; up.line = 0; up.private_data = (void*)UART0_STATUS_REG; diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c index f5dccf01da11..dc59c3b708ed 100644 --- a/arch/mips/sgi-ip27/ip27-timer.c +++ b/arch/mips/sgi-ip27/ip27-timer.c @@ -131,12 +131,12 @@ static struct irq_chip rt_irq_type = { static int rt_next_event(unsigned long delta, struct clock_event_device *evt) { unsigned int cpu = smp_processor_id(); - int slice = cputoslice(cpu) == 0; + int slice putoslice(cpu); unsigned long cnt; cnt = LOCAL_HUB_L(PI_RT_COUNT); cnt += delta; - LOCAL_HUB_S(slice ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, cnt); + LOCAL_HUB_S(PI_RT_COMPARE_A + PI_COUNT_OFFSET * slice, cnt); return LOCAL_HUB_L(PI_RT_COUNT) >= cnt ? -ETIME : 0; } @@ -164,9 +164,12 @@ static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id) { struct clock_event_device *cd = dev_id; unsigned int cpu = smp_processor_id(); - int slice = cputoslice(cpu) == 0; + int slice = cputoslice(cpu); - LOCAL_HUB_S(slice ? PI_RT_PEND_A : PI_RT_PEND_B, 0); /* Ack */ + /* + * Ack + */ + LOCAL_HUB_S(PI_RT_PEND_A + PI_COUNT_OFFSET * slice, cnt); cd->event_handler(cd); return IRQ_HANDLED; diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index 7e8094f617bf..aab17ddd2f30 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c @@ -40,13 +40,6 @@ static void inline flush_mace_bus(void) mace->perif.ctrl.misc; } -#undef DEBUG_IRQ -#ifdef DEBUG_IRQ -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - /* * O2 irq map * @@ -125,6 +118,7 @@ struct irqaction memerr_irq = { .mask = CPU_MASK_NONE, .name = "CRIME memory error", }; + struct irqaction cpuerr_irq = { .handler = crime_cpuerr_intr, .flags = IRQF_DISABLED, @@ -139,46 +133,70 @@ struct irqaction cpuerr_irq = { static uint64_t crime_mask; -static void enable_crime_irq(unsigned int irq) +static inline void crime_enable_irq(unsigned int irq) { - crime_mask |= 1 << (irq - 1); + unsigned int bit = irq - CRIME_IRQ_BASE; + + crime_mask |= 1 << bit; crime->imask = crime_mask; } -static void disable_crime_irq(unsigned int irq) +static inline void crime_disable_irq(unsigned int irq) { - crime_mask &= ~(1 << (irq - 1)); + unsigned int bit = irq - CRIME_IRQ_BASE; + + crime_mask &= ~(1 << bit); crime->imask = crime_mask; flush_crime_bus(); } -static void mask_and_ack_crime_irq(unsigned int irq) +static void crime_level_mask_and_ack_irq(unsigned int irq) +{ + crime_disable_irq(irq); +} + +static void crime_level_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + crime_enable_irq(irq); +} + +static struct irq_chip crime_level_interrupt = { + .name = "IP32 CRIME", + .ack = crime_level_mask_and_ack_irq, + .mask = crime_disable_irq, + .mask_ack = crime_level_mask_and_ack_irq, + .unmask = crime_enable_irq, + .end = crime_level_end_irq, +}; + +static void crime_edge_mask_and_ack_irq(unsigned int irq) { + unsigned int bit = irq - CRIME_IRQ_BASE; + uint64_t crime_int; + /* Edge triggered interrupts must be cleared. */ - if ((irq >= CRIME_GBE0_IRQ && irq <= CRIME_GBE3_IRQ) - || (irq >= CRIME_RE_EMPTY_E_IRQ && irq <= CRIME_RE_IDLE_E_IRQ) - || (irq >= CRIME_SOFT0_IRQ && irq <= CRIME_SOFT2_IRQ)) { - uint64_t crime_int; - crime_int = crime->hard_int; - crime_int &= ~(1 << (irq - 1)); - crime->hard_int = crime_int; - } - disable_crime_irq(irq); + + crime_int = crime->hard_int; + crime_int &= ~(1 << bit); + crime->hard_int = crime_int; + + crime_disable_irq(irq); } -static void end_crime_irq(unsigned int irq) +static void crime_edge_end_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - enable_crime_irq(irq); + crime_enable_irq(irq); } -static struct irq_chip ip32_crime_interrupt = { - .name = "IP32 CRIME", - .ack = mask_and_ack_crime_irq, - .mask = disable_crime_irq, - .mask_ack = mask_and_ack_crime_irq, - .unmask = enable_crime_irq, - .end = end_crime_irq, +static struct irq_chip crime_edge_interrupt = { + .name = "IP32 CRIME", + .ack = crime_edge_mask_and_ack_irq, + .mask = crime_disable_irq, + .mask_ack = crime_edge_mask_and_ack_irq, + .unmask = crime_enable_irq, + .end = crime_edge_end_irq, }; /* @@ -265,7 +283,7 @@ static void enable_maceisa_irq(unsigned int irq) { unsigned int crime_int = 0; - DBG("maceisa enable: %u\n", irq); + pr_debug("maceisa enable: %u\n", irq); switch (irq) { case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ: @@ -278,7 +296,7 @@ static void enable_maceisa_irq(unsigned int irq) crime_int = MACE_SUPERIO_INT; break; } - DBG("crime_int %08x enabled\n", crime_int); + pr_debug("crime_int %08x enabled\n", crime_int); crime_mask |= crime_int; crime->imask = crime_mask; maceisa_mask |= 1 << (irq - 33); @@ -290,11 +308,11 @@ static void disable_maceisa_irq(unsigned int irq) unsigned int crime_int = 0; maceisa_mask &= ~(1 << (irq - 33)); - if(!(maceisa_mask & MACEISA_AUDIO_INT)) + if (!(maceisa_mask & MACEISA_AUDIO_INT)) crime_int |= MACE_AUDIO_INT; - if(!(maceisa_mask & MACEISA_MISC_INT)) + if (!(maceisa_mask & MACEISA_MISC_INT)) crime_int |= MACE_MISC_INT; - if(!(maceisa_mask & MACEISA_SUPERIO_INT)) + if (!(maceisa_mask & MACEISA_SUPERIO_INT)) crime_int |= MACE_SUPERIO_INT; crime_mask &= ~crime_int; crime->imask = crime_mask; @@ -327,12 +345,12 @@ static void end_maceisa_irq(unsigned irq) } static struct irq_chip ip32_maceisa_interrupt = { - .name = "IP32 MACE ISA", - .ack = mask_and_ack_maceisa_irq, - .mask = disable_maceisa_irq, - .mask_ack = mask_and_ack_maceisa_irq, - .unmask = enable_maceisa_irq, - .end = end_maceisa_irq, + .name = "IP32 MACE ISA", + .ack = mask_and_ack_maceisa_irq, + .mask = disable_maceisa_irq, + .mask_ack = mask_and_ack_maceisa_irq, + .unmask = enable_maceisa_irq, + .end = end_maceisa_irq, }; /* This is used for regular non-ISA, non-PCI MACE interrupts. That means @@ -411,7 +429,7 @@ static void ip32_irq0(void) irq = __ffs(mace_int & maceisa_mask) + MACEISA_AUDIO_SW_IRQ; } - DBG("*irq %u*\n", irq); + pr_debug("*irq %u*\n", irq); do_IRQ(irq); } @@ -472,23 +490,31 @@ void __init arch_init_irq(void) mips_cpu_irq_init(); for (irq = MIPS_CPU_IRQ_BASE + 8; irq <= IP32_IRQ_MAX; irq++) { - struct irq_chip *chip; - switch (irq) { case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ: - chip = &ip32_mace_interrupt; + set_irq_chip(irq, &ip32_mace_interrupt); break; case MACEPCI_SCSI0_IRQ ... MACEPCI_SHARED2_IRQ: - chip = &ip32_macepci_interrupt; + set_irq_chip(irq, &ip32_macepci_interrupt); + break; + case CRIME_GBE0_IRQ ... CRIME_GBE3_IRQ: + set_irq_chip(irq, &crime_edge_interrupt); + break; + case CRIME_CPUERR_IRQ: + case CRIME_MEMERR_IRQ: + set_irq_chip(irq, &crime_level_interrupt); break; - case CRIME_GBE0_IRQ ... CRIME_VICE_IRQ: - chip = &ip32_crime_interrupt; + case CRIME_RE_EMPTY_E_IRQ ... CRIME_RE_IDLE_E_IRQ: + case CRIME_SOFT0_IRQ ... CRIME_SOFT2_IRQ: + set_irq_chip(irq, &crime_edge_interrupt); + break; + case CRIME_VICE_IRQ: + set_irq_chip(irq, &crime_edge_interrupt); break; default: - chip = &ip32_maceisa_interrupt; + set_irq_chip(irq, &ip32_maceisa_interrupt); + break; } - - set_irq_chip(irq, chip); } setup_irq(CRIME_MEMERR_IRQ, &memerr_irq); setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq); diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c index 10299bafeab7..61790c4bfb60 100644 --- a/arch/mips/sibyte/bcm1480/irq.c +++ b/arch/mips/sibyte/bcm1480/irq.c @@ -280,27 +280,6 @@ static struct irqaction bcm1480_dummy_action = { .dev_id = 0 }; -int bcm1480_steal_irq(int irq) -{ - struct irq_desc *desc = irq_desc + irq; - unsigned long flags; - int retval = 0; - - if (irq >= BCM1480_NR_IRQS) - return -EINVAL; - - spin_lock_irqsave(&desc->lock, flags); - /* Don't allow sharing at all for these */ - if (desc->action != NULL) - retval = -EBUSY; - else { - desc->action = &bcm1480_dummy_action; - desc->depth = 0; - } - spin_unlock_irqrestore(&desc->lock, flags); - return 0; -} - /* * init_IRQ is called early in the boot sequence from init/main.c. It * is responsible for setting up the interrupt mapper and installing the @@ -386,8 +365,6 @@ void __init arch_init_irq(void) __raw_writeq(tmp, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MASK_L))); } - bcm1480_steal_irq(K_BCM1480_INT_MBOX_0_0); - /* * Note that the timer interrupts are also mapped, but this is * done in bcm1480_time_init(). Also, the profiling driver @@ -411,7 +388,6 @@ void __init arch_init_irq(void) /* QQQ FIXME */ __raw_writeq(M_DUART_IMR_BRK, IO_SPACE_BASE + A_DUART_IMRREG(kgdb_port)); - bcm1480_steal_irq(kgdb_irq); __raw_writeq(IMR_IP6_VAL, IO_SPACE_BASE + A_BCM1480_IMR_REGISTER(0, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + (kgdb_irq<<3)); diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c index 610f0253954d..bbf19bfabccb 100644 --- a/arch/mips/sibyte/bcm1480/time.c +++ b/arch/mips/sibyte/bcm1480/time.c @@ -37,8 +37,6 @@ #define IMR_IP3_VAL K_BCM1480_INT_MAP_I1 #define IMR_IP4_VAL K_BCM1480_INT_MAP_I2 -extern int bcm1480_steal_irq(int irq); - /* * The general purpose timer ticks at 1MHz independent if * the rest of the system @@ -121,7 +119,7 @@ void __cpuinit sb1480_clockevent_init(void) sprintf(name, "bcm1480-counter %d", cpu); cd->name = name; cd->features = CLOCK_EVT_FEAT_PERIODIC | - CLOCK_EVT_MODE_ONESHOT; + CLOCK_EVT_FEAT_ONESHOT; clockevent_set_clock(cd, V_SCD_TIMER_FREQ); cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd); cd->min_delta_ns = clockevent_delta2ns(1, cd); @@ -142,7 +140,6 @@ void __cpuinit sb1480_clockevent_init(void) R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + (irq << 3))); bcm1480_unmask_irq(cpu, irq); - bcm1480_steal_irq(irq); action->handler = sibyte_counter_handler; action->flags = IRQF_DISABLED | IRQF_PERCPU; diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c index 53780a179d1d..52d18fc91f32 100644 --- a/arch/mips/sibyte/sb1250/irq.c +++ b/arch/mips/sibyte/sb1250/irq.c @@ -250,27 +250,6 @@ static struct irqaction sb1250_dummy_action = { .dev_id = 0 }; -int sb1250_steal_irq(int irq) -{ - struct irq_desc *desc = irq_desc + irq; - unsigned long flags; - int retval = 0; - - if (irq >= SB1250_NR_IRQS) - return -EINVAL; - - spin_lock_irqsave(&desc->lock, flags); - /* Don't allow sharing at all for these */ - if (desc->action != NULL) - retval = -EBUSY; - else { - desc->action = &sb1250_dummy_action; - desc->depth = 0; - } - spin_unlock_irqrestore(&desc->lock, flags); - return 0; -} - /* * arch_init_irq is called early in the boot sequence from init/main.c via * init_IRQ. It is responsible for setting up the interrupt mapper and @@ -342,8 +321,6 @@ void __init arch_init_irq(void) __raw_writeq(tmp, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK))); __raw_writeq(tmp, IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK))); - sb1250_steal_irq(K_INT_MBOX_0); - /* * Note that the timer interrupts are also mapped, but this is * done in sb1250_time_init(). Also, the profiling driver @@ -367,7 +344,6 @@ void __init arch_init_irq(void) __raw_writeq(M_DUART_IMR_BRK, IOADDR(A_DUART_IMRREG(kgdb_port))); - sb1250_steal_irq(kgdb_irq); __raw_writeq(IMR_IP6_VAL, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c index a41e908bc218..95ad34e3fbac 100644 --- a/arch/mips/sibyte/sb1250/time.c +++ b/arch/mips/sibyte/sb1250/time.c @@ -50,8 +50,6 @@ #define SB1250_HPT_VALUE M_SCD_TIMER_CNT /* max value */ -extern int sb1250_steal_irq(int irq); - /* * The general purpose timer ticks at 1 Mhz independent if * the rest of the system @@ -139,7 +137,7 @@ void __cpuinit sb1250_clockevent_init(void) sprintf(name, "bcm1480-counter %d", cpu); cd->name = name; cd->features = CLOCK_EVT_FEAT_PERIODIC | - CLOCK_EVT_MODE_ONESHOT; + CLOCK_EVT_FEAT_ONESHOT; clockevent_set_clock(cd, V_SCD_TIMER_FREQ); cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd); cd->min_delta_ns = clockevent_delta2ns(1, cd); @@ -159,7 +157,6 @@ void __cpuinit sb1250_clockevent_init(void) cd->cpumask = cpumask_of_cpu(0); sb1250_unmask_irq(cpu, irq); - sb1250_steal_irq(irq); action->handler = sibyte_counter_handler; action->flags = IRQF_DISABLED | IRQF_PERCPU; diff --git a/arch/mips/sni/time.c b/arch/mips/sni/time.c index 0910b35cb71f..60bc62ef0935 100644 --- a/arch/mips/sni/time.c +++ b/arch/mips/sni/time.c @@ -11,27 +11,78 @@ #define SNI_COUNTER2_DIV 64 #define SNI_COUNTER0_DIV ((SNI_CLOCK_TICK_RATE / SNI_COUNTER2_DIV) / HZ) -static void sni_a20r_timer_ack(void) +static void a20r_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) { - *(volatile u8 *)A20R_PT_TIM0_ACK = 0x0; wmb(); + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0x34; + wmb(); + *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV; + wmb(); + *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV >> 8; + wmb(); + + *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0xb4; + wmb(); + *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = SNI_COUNTER2_DIV; + wmb(); + *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = SNI_COUNTER2_DIV >> 8; + wmb(); + + break; + case CLOCK_EVT_MODE_ONESHOT: + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + break; + case CLOCK_EVT_MODE_RESUME: + break; + } } +static struct clock_event_device a20r_clockevent_device = { + .name = "a20r-timer", + .features = CLOCK_EVT_FEAT_PERIODIC, + + /* .mult, .shift, .max_delta_ns and .min_delta_ns left uninitialized */ + + .rating = 300, + .irq = SNI_A20R_IRQ_TIMER, + .set_mode = a20r_set_mode, +}; + +static irqreturn_t a20r_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *cd = dev_id; + + *(volatile u8 *)A20R_PT_TIM0_ACK = 0; + wmb(); + + cd->event_handler(cd); + + return IRQ_HANDLED; +} + +static struct irqaction a20r_irqaction = { + .handler = a20r_interrupt, + .flags = IRQF_DISABLED | IRQF_PERCPU, + .name = "a20r-timer", +}; + /* * a20r platform uses 2 counters to divide the input frequency. * Counter 2 output is connected to Counter 0 & 1 input. */ -static void __init sni_a20r_timer_setup(struct irqaction *irq) +static void __init sni_a20r_timer_setup(void) { - *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0x34; wmb(); - *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = (SNI_COUNTER0_DIV) & 0xff; wmb(); - *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = (SNI_COUNTER0_DIV >> 8) & 0xff; wmb(); + struct clock_event_device *cd = &a20r_clockevent_device; + struct irqaction *action = &a20r_irqaction; + unsigned int cpu = smp_processor_id(); - *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0xb4; wmb(); - *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = (SNI_COUNTER2_DIV) & 0xff; wmb(); - *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = (SNI_COUNTER2_DIV >> 8) & 0xff; wmb(); + cd->cpumask = cpumask_of_cpu(cpu); - setup_irq(SNI_A20R_IRQ_TIMER, irq); - mips_timer_ack = sni_a20r_timer_ack; + action->dev_id = cd; + setup_irq(SNI_A20R_IRQ_TIMER, &a20r_irqaction); } #define SNI_8254_TICK_RATE 1193182UL @@ -119,17 +170,14 @@ void __init plat_time_init(void) mips_hpt_frequency = r4k_tick * HZ; setup_pit_timer(); -} -void __init plat_timer_setup(struct irqaction *irq) -{ switch (sni_brd_type) { case SNI_BRD_10: case SNI_BRD_10NEW: case SNI_BRD_TOWER_OASIC: case SNI_BRD_MINITOWER: - sni_a20r_timer_setup(irq); - break; + sni_a20r_timer_setup(); + break; } } diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c index c7470fba6180..0299595ce1c4 100644 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c @@ -63,6 +63,7 @@ #include <asm/processor.h> #include <asm/reboot.h> #include <asm/time.h> +#include <asm/txx9tmr.h> #include <linux/bootmem.h> #include <linux/blkdev.h> #ifdef CONFIG_TOSHIBA_FPCIB0 @@ -93,7 +94,6 @@ #define TOSHIBA_RBTX4927_SETUP_EFWFU ( 1 << 3 ) #define TOSHIBA_RBTX4927_SETUP_SETUP ( 1 << 4 ) -#define TOSHIBA_RBTX4927_SETUP_TIME_INIT ( 1 << 5 ) #define TOSHIBA_RBTX4927_SETUP_PCIBIOS ( 1 << 7 ) #define TOSHIBA_RBTX4927_SETUP_PCI1 ( 1 << 8 ) #define TOSHIBA_RBTX4927_SETUP_PCI2 ( 1 << 9 ) @@ -130,7 +130,6 @@ extern void toshiba_rbtx4927_power_off(void); int tx4927_using_backplane = 0; -extern void gt64120_time_init(void); extern void toshiba_rbtx4927_irq_setup(void); char *prom_getcmdline(void); @@ -721,6 +720,7 @@ void toshiba_rbtx4927_power_off(void) void __init toshiba_rbtx4927_setup(void) { + int i; u32 cp0_config; char *argptr; @@ -764,6 +764,9 @@ void __init toshiba_rbtx4927_setup(void) _machine_halt = toshiba_rbtx4927_halt; pm_power_off = toshiba_rbtx4927_power_off; + for (i = 0; i < TX4927_NR_TMR; i++) + txx9_tmr_init(TX4927_TMR_REG(0) & 0xfffffffffULL); + #ifdef CONFIG_PCI /* PCIC */ @@ -892,7 +895,6 @@ void __init toshiba_rbtx4927_setup(void) #ifdef CONFIG_SERIAL_TXX9 { extern int early_serial_txx9_setup(struct uart_port *port); - int i; struct uart_port req; for(i = 0; i < 2; i++) { memset(&req, 0, sizeof(req)); @@ -937,12 +939,11 @@ void __init toshiba_rbtx4927_setup(void) void __init toshiba_rbtx4927_time_init(void) { - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, "-\n"); - mips_hpt_frequency = tx4927_cpu_clock / 2; - - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, "+\n"); - + if (tx4927_ccfgptr->ccfg & TX4927_CCFG_TINTDIS) + txx9_clockevent_init(TX4927_TMR_REG(0) & 0xfffffffffULL, + TXX9_IRQ_BASE + 17, + 50000000); } static int __init toshiba_rbtx4927_rtc_init(void) diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c index ceecaf498957..4a8152375efe 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c +++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c @@ -26,6 +26,7 @@ #include <asm/reboot.h> #include <asm/irq.h> #include <asm/time.h> +#include <asm/txx9tmr.h> #include <asm/uaccess.h> #include <asm/io.h> #include <asm/bootinfo.h> @@ -773,15 +774,8 @@ void __init tx4938_board_setup(void) } /* TMR */ - /* disable all timers */ - for (i = 0; i < TX4938_NR_TMR; i++) { - tx4938_tmrptr(i)->tcr = 0x00000020; - tx4938_tmrptr(i)->tisr = 0; - tx4938_tmrptr(i)->cpra = 0xffffffff; - tx4938_tmrptr(i)->itmr = 0; - tx4938_tmrptr(i)->ccdr = 0; - tx4938_tmrptr(i)->pgmr = 0; - } + for (i = 0; i < TX4938_NR_TMR; i++) + txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL); /* enable DMA */ TX4938_WR64(0xff1fb150, TX4938_DMA_MCR_MSTEN); @@ -852,12 +846,13 @@ void tx4938_report_pcic_status(void) #endif /* CONFIG_PCI */ -/* We use onchip r4k counter or TMR timer as our system wide timer - * interrupt running at 100HZ. */ - void __init plat_time_init(void) { mips_hpt_frequency = txx9_cpu_clock / 2; + if (tx4938_ccfgptr->ccfg & TX4938_CCFG_TINTDIS) + txx9_clockevent_init(TX4938_TMR_REG(0) & 0xfffffffffULL, + TXX9_IRQ_BASE + TX4938_IR_TMR(0), + txx9_gbus_clock / 2); } void __init toshiba_rbtx4938_setup(void) diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 970b2defe7df..761ca7b5f120 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -6,9 +6,8 @@ config TRACE_IRQFLAGS_SUPPORT source "lib/Kconfig.debug" config EARLY_PRINTK - bool "Early printk" if EMBEDDED && DEBUG_KERNEL + bool "Early printk" if EMBEDDED && DEBUG_KERNEL && X86_32 default y - depends on X86_32 help Write kernel log output directly into the VGA buffer or to a serial port. @@ -91,7 +90,7 @@ config DOUBLEFAULT config IOMMU_DEBUG bool "Enable IOMMU debugging" - depends on IOMMU && DEBUG_KERNEL + depends on GART_IOMMU && DEBUG_KERNEL depends on X86_64 help Force the IOMMU to on even when you have less than 4GB of @@ -113,7 +112,4 @@ config IOMMU_LEAK Add a simple leak tracer to the IOMMU code. This is useful when you are debugging a buggy device driver that leaks IOMMU mappings. -#config X86_REMOTE_DEBUG -# bool "kgdb debugging stub" - endmenu diff --git a/arch/x86/Kconfig.x86_64 b/arch/x86/Kconfig.x86_64 index e2542e5b536c..b45855c368a9 100644 --- a/arch/x86/Kconfig.x86_64 +++ b/arch/x86/Kconfig.x86_64 @@ -97,10 +97,6 @@ config X86_CMPXCHG bool default y -config EARLY_PRINTK - bool - default y - config GENERIC_ISA_DMA bool default y @@ -479,8 +475,8 @@ config HPET_EMULATE_RTC # Mark as embedded because too many people got it wrong. # The code disables itself when not needed. -config IOMMU - bool "IOMMU support" if EMBEDDED +config GART_IOMMU + bool "GART IOMMU support" if EMBEDDED default y select SWIOTLB select AGP @@ -687,7 +683,7 @@ source kernel/Kconfig.hz config K8_NB def_bool y - depends on AGP_AMD64 || IOMMU || (PCI && NUMA) + depends on AGP_AMD64 || GART_IOMMU || (PCI && NUMA) endmenu diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig index b091c5e35558..38a83f9c966f 100644 --- a/arch/x86/configs/x86_64_defconfig +++ b/arch/x86/configs/x86_64_defconfig @@ -170,7 +170,7 @@ CONFIG_HOTPLUG_CPU=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_HPET_TIMER=y CONFIG_HPET_EMULATE_RTC=y -CONFIG_IOMMU=y +CONFIG_GART_IOMMU=y # CONFIG_CALGARY_IOMMU is not set CONFIG_SWIOTLB=y CONFIG_X86_MCE=y diff --git a/arch/x86/kernel/Makefile_64 b/arch/x86/kernel/Makefile_64 index 466337ae9a1e..24671c3838b3 100644 --- a/arch/x86/kernel/Makefile_64 +++ b/arch/x86/kernel/Makefile_64 @@ -25,7 +25,7 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump_64.o obj-$(CONFIG_PM) += suspend_64.o obj-$(CONFIG_HIBERNATION) += suspend_asm_64.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o -obj-$(CONFIG_IOMMU) += pci-gart_64.o aperture_64.o +obj-$(CONFIG_GART_IOMMU) += pci-gart_64.o aperture_64.o obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary_64.o tce_64.o obj-$(CONFIG_SWIOTLB) += pci-swiotlb_64.o obj-$(CONFIG_KPROBES) += kprobes_64.o diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c index 8f681cae7bf7..5b6992799c9d 100644 --- a/arch/x86/kernel/aperture_64.c +++ b/arch/x86/kernel/aperture_64.c @@ -20,14 +20,14 @@ #include <linux/ioport.h> #include <asm/e820.h> #include <asm/io.h> -#include <asm/iommu.h> +#include <asm/gart.h> #include <asm/pci-direct.h> #include <asm/dma.h> #include <asm/k8.h> -int iommu_aperture; -int iommu_aperture_disabled __initdata = 0; -int iommu_aperture_allowed __initdata = 0; +int gart_iommu_aperture; +int gart_iommu_aperture_disabled __initdata = 0; +int gart_iommu_aperture_allowed __initdata = 0; int fallback_aper_order __initdata = 1; /* 64MB */ int fallback_aper_force __initdata = 0; @@ -204,14 +204,15 @@ static __u32 __init search_agp_bridge(u32 *order, int *valid_agp) return 0; } -void __init iommu_hole_init(void) +void __init gart_iommu_hole_init(void) { int fix, num; u32 aper_size, aper_alloc = 0, aper_order = 0, last_aper_order = 0; u64 aper_base, last_aper_base = 0; int valid_agp = 0; - if (iommu_aperture_disabled || !fix_aperture || !early_pci_allowed()) + if (gart_iommu_aperture_disabled || !fix_aperture || + !early_pci_allowed()) return; printk(KERN_INFO "Checking aperture...\n"); @@ -222,7 +223,7 @@ void __init iommu_hole_init(void) continue; iommu_detected = 1; - iommu_aperture = 1; + gart_iommu_aperture = 1; aper_order = (read_pci_config(0, num, 3, 0x90) >> 1) & 7; aper_size = (32 * 1024 * 1024) << aper_order; diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c index 2d42b414b777..066f8c6af4df 100644 --- a/arch/x86/kernel/cpu/proc.c +++ b/arch/x86/kernel/cpu/proc.c @@ -49,7 +49,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) /* Intel-defined (#2) */ "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", "smx", "est", "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL, - NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt", + NULL, NULL, "dca", "sse4_1", "sse4_2", NULL, NULL, "popcnt", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* VIA/Cyrix/Centaur-defined */ @@ -59,10 +59,10 @@ static int show_cpuinfo(struct seq_file *m, void *v) NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* AMD-defined (#2) */ - "lahf_lm", "cmp_legacy", "svm", "extapic", "cr8_legacy", - "altmovcr8", "abm", "sse4a", - "misalignsse", "3dnowprefetch", - "osvw", "ibs", NULL, NULL, NULL, NULL, + "lahf_lm", "cmp_legacy", "svm", "extapic", + "cr8_legacy", "abm", "sse4a", "misalignsse", + "3dnowprefetch", "osvw", "ibs", "sse5", + "skinit", "wdt", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index 639e6320518e..88bb83ec895f 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -17,19 +17,19 @@ #include <asm/io_apic.h> #include <asm/apic.h> -#ifdef CONFIG_IOMMU -#include <asm/iommu.h> +#ifdef CONFIG_GART_IOMMU +#include <asm/gart.h> #endif static void __init via_bugs(void) { -#ifdef CONFIG_IOMMU +#ifdef CONFIG_GART_IOMMU if ((end_pfn > MAX_DMA32_PFN || force_iommu) && - !iommu_aperture_allowed) { + !gart_iommu_aperture_allowed) { printk(KERN_INFO "Looks like a VIA chipset. Disabling IOMMU." " Override with iommu=allowed\n"); - iommu_aperture_disabled = 1; + gart_iommu_aperture_disabled = 1; } #endif } diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index 1a20fe31338b..6bf1f716909d 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c @@ -36,7 +36,7 @@ #include <linux/pci.h> #include <linux/delay.h> #include <linux/scatterlist.h> -#include <asm/iommu.h> +#include <asm/gart.h> #include <asm/calgary.h> #include <asm/tce.h> #include <asm/pci-direct.h> diff --git a/arch/x86/kernel/pci-dma_64.c b/arch/x86/kernel/pci-dma_64.c index 393e2725a6e3..aa805b11b24f 100644 --- a/arch/x86/kernel/pci-dma_64.c +++ b/arch/x86/kernel/pci-dma_64.c @@ -9,7 +9,7 @@ #include <linux/module.h> #include <linux/dmar.h> #include <asm/io.h> -#include <asm/iommu.h> +#include <asm/gart.h> #include <asm/calgary.h> int iommu_merge __read_mostly = 1; @@ -275,7 +275,7 @@ __init int iommu_setup(char *p) swiotlb = 1; #endif -#ifdef CONFIG_IOMMU +#ifdef CONFIG_GART_IOMMU gart_parse_options(p); #endif @@ -298,8 +298,8 @@ void __init pci_iommu_alloc(void) * The order of these functions is important for * fall-back/fail-over reasons */ -#ifdef CONFIG_IOMMU - iommu_hole_init(); +#ifdef CONFIG_GART_IOMMU + gart_iommu_hole_init(); #endif #ifdef CONFIG_CALGARY_IOMMU @@ -321,7 +321,7 @@ static int __init pci_iommu_init(void) intel_iommu_init(); -#ifdef CONFIG_IOMMU +#ifdef CONFIG_GART_IOMMU gart_iommu_init(); #endif diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index 79b514b381b1..06bcba536045 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c @@ -30,17 +30,17 @@ #include <asm/mtrr.h> #include <asm/pgtable.h> #include <asm/proto.h> -#include <asm/iommu.h> +#include <asm/gart.h> #include <asm/cacheflush.h> #include <asm/swiotlb.h> #include <asm/dma.h> #include <asm/k8.h> -unsigned long iommu_bus_base; /* GART remapping area (physical) */ +static unsigned long iommu_bus_base; /* GART remapping area (physical) */ static unsigned long iommu_size; /* size of remapping area bytes */ static unsigned long iommu_pages; /* .. and in pages */ -u32 *iommu_gatt_base; /* Remapping table */ +static u32 *iommu_gatt_base; /* Remapping table */ /* If this is disabled the IOMMU will use an optimized flushing strategy of only flushing when an mapping is reused. With it true the GART is flushed @@ -135,8 +135,8 @@ static void flush_gart(void) /* Debugging aid for drivers that don't free their IOMMU tables */ static void **iommu_leak_tab; static int leak_trace; -int iommu_leak_pages = 20; -void dump_leak(void) +static int iommu_leak_pages = 20; +static void dump_leak(void) { int i; static int dump; @@ -627,12 +627,12 @@ void __init gart_iommu_init(void) return; /* Did we detect a different HW IOMMU? */ - if (iommu_detected && !iommu_aperture) + if (iommu_detected && !gart_iommu_aperture) return; if (no_iommu || (!force_iommu && end_pfn <= MAX_DMA32_PFN) || - !iommu_aperture || + !gart_iommu_aperture || (no_agp && init_k8_gatt(&info) < 0)) { if (end_pfn > MAX_DMA32_PFN) { printk(KERN_ERR "WARNING more than 4GB of memory " @@ -733,9 +733,9 @@ void __init gart_parse_options(char *p) fix_aperture = 0; /* duplicated from pci-dma.c */ if (!strncmp(p,"force",5)) - iommu_aperture_allowed = 1; + gart_iommu_aperture_allowed = 1; if (!strncmp(p,"allowed",7)) - iommu_aperture_allowed = 1; + gart_iommu_aperture_allowed = 1; if (!strncmp(p, "memaper", 7)) { fallback_aper_force = 1; p += 7; diff --git a/arch/x86/kernel/pci-nommu_64.c b/arch/x86/kernel/pci-nommu_64.c index faf70bdca335..ab08e1832228 100644 --- a/arch/x86/kernel/pci-nommu_64.c +++ b/arch/x86/kernel/pci-nommu_64.c @@ -7,7 +7,7 @@ #include <linux/dma-mapping.h> #include <linux/scatterlist.h> -#include <asm/iommu.h> +#include <asm/gart.h> #include <asm/processor.h> #include <asm/dma.h> diff --git a/arch/x86/kernel/pci-swiotlb_64.c b/arch/x86/kernel/pci-swiotlb_64.c index b2f405ea7c85..102866d729a5 100644 --- a/arch/x86/kernel/pci-swiotlb_64.c +++ b/arch/x86/kernel/pci-swiotlb_64.c @@ -5,7 +5,7 @@ #include <linux/module.h> #include <linux/dma-mapping.h> -#include <asm/iommu.h> +#include <asm/gart.h> #include <asm/swiotlb.h> #include <asm/dma.h> diff --git a/arch/x86/kernel/reboot_64.c b/arch/x86/kernel/reboot_64.c index 776eb06b6512..71b13c5f5817 100644 --- a/arch/x86/kernel/reboot_64.c +++ b/arch/x86/kernel/reboot_64.c @@ -17,7 +17,7 @@ #include <asm/pgtable.h> #include <asm/tlbflush.h> #include <asm/apic.h> -#include <asm/iommu.h> +#include <asm/gart.h> /* * Power off function, if any diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index cc0e91447b76..e1e18c34c821 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -86,9 +86,6 @@ unsigned long mmu_cr4_features; /* for MCA, but anyone else can use it if they want */ unsigned int machine_id; -#ifdef CONFIG_MCA -EXPORT_SYMBOL(machine_id); -#endif unsigned int machine_submodel_id; unsigned int BIOS_revision; unsigned int mca_pentium_flag; diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c index e7a9e36bd52d..238633d3d09a 100644 --- a/arch/x86/kernel/setup_64.c +++ b/arch/x86/kernel/setup_64.c @@ -1040,7 +1040,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) /* Intel-defined (#2) */ "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", "smx", "est", "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL, - NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt", + NULL, NULL, "dca", "sse4_1", "sse4_2", NULL, NULL, "popcnt", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* VIA/Cyrix/Centaur-defined */ @@ -1050,10 +1050,10 @@ static int show_cpuinfo(struct seq_file *m, void *v) NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* AMD-defined (#2) */ - "lahf_lm", "cmp_legacy", "svm", "extapic", "cr8_legacy", - "altmovcr8", "abm", "sse4a", - "misalignsse", "3dnowprefetch", - "osvw", "ibs", NULL, NULL, NULL, NULL, + "lahf_lm", "cmp_legacy", "svm", "extapic", + "cr8_legacy", "abm", "sse4a", "misalignsse", + "3dnowprefetch", "osvw", "ibs", "sse5", + "skinit", "wdt", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/arch/x86/mm/discontig_32.c b/arch/x86/mm/discontig_32.c index fe608a45ffb6..13a474d3c6e9 100644 --- a/arch/x86/mm/discontig_32.c +++ b/arch/x86/mm/discontig_32.c @@ -40,7 +40,7 @@ struct pglist_data *node_data[MAX_NUMNODES] __read_mostly; EXPORT_SYMBOL(node_data); -bootmem_data_t node0_bdata; +static bootmem_data_t node0_bdata; /* * numa interface - we expect the numa architecture specific code to have @@ -404,7 +404,7 @@ void __init set_highmem_pages_init(int bad_ppro) } #ifdef CONFIG_MEMORY_HOTPLUG -int paddr_to_nid(u64 addr) +static int paddr_to_nid(u64 addr) { int nid; unsigned long pfn = PFN_DOWN(addr); diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig index f22c253bc09f..ccb1fa89de29 100644 --- a/drivers/char/agp/Kconfig +++ b/drivers/char/agp/Kconfig @@ -56,9 +56,9 @@ config AGP_AMD X on AMD Irongate, 761, and 762 chipsets. config AGP_AMD64 - tristate "AMD Opteron/Athlon64 on-CPU GART support" if !IOMMU + tristate "AMD Opteron/Athlon64 on-CPU GART support" if !GART_IOMMU depends on AGP && X86 - default y if IOMMU + default y if GART_IOMMU help This option gives you AGP support for the GLX component of X using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs. diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index d95662e96326..d8200ac8f8cb 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c @@ -787,7 +787,7 @@ static void __exit agp_amd64_cleanup(void) /* On AMD64 the PCI driver needs to initialize this driver early for the IOMMU, so it has to be called via a backdoor. */ -#ifndef CONFIG_IOMMU +#ifndef CONFIG_GART_IOMMU module_init(agp_amd64_init); module_exit(agp_amd64_cleanup); #endif diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 9b35259eecfa..8af1d9a261e5 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -34,7 +34,7 @@ #include "intel-iommu.h" #include <asm/proto.h> /* force_iommu in this header in x86-64*/ #include <asm/cacheflush.h> -#include <asm/iommu.h> +#include <asm/gart.h> #include "pci.h" #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index eb4ac47612a5..316a746e0080 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -434,7 +434,7 @@ int usb_sg_init ( if (dma) { io->urbs [i]->transfer_dma = sg_dma_address (sg + i); len = sg_dma_len (sg + i); -#if defined(CONFIG_HIGHMEM) || defined(CONFIG_IOMMU) +#if defined(CONFIG_HIGHMEM) || defined(CONFIG_GART_IOMMU) io->urbs[i]->transfer_buffer = NULL; #else io->urbs[i]->transfer_buffer = sg_virt(&sg[i]); diff --git a/fs/proc/array.c b/fs/proc/array.c index 63c95afb561f..eba339ecba27 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -358,7 +358,8 @@ static cputime_t task_utime(struct task_struct *p) } utime = (clock_t)temp; - return clock_t_to_cputime(utime); + p->prev_utime = max(p->prev_utime, clock_t_to_cputime(utime)); + return p->prev_utime; } static cputime_t task_stime(struct task_struct *p) @@ -373,7 +374,8 @@ static cputime_t task_stime(struct task_struct *p) stime = nsec_to_clock_t(p->se.sum_exec_runtime) - cputime_to_clock_t(task_utime(p)); - return clock_t_to_cputime(stime); + p->prev_stime = max(p->prev_stime, clock_t_to_cputime(stime)); + return p->prev_stime; } #endif diff --git a/include/asm-mips/ip32/ip32_ints.h b/include/asm-mips/ip32/ip32_ints.h index 042f821899a8..ab5612f90f6f 100644 --- a/include/asm-mips/ip32/ip32_ints.h +++ b/include/asm-mips/ip32/ip32_ints.h @@ -22,10 +22,12 @@ enum ip32_irq_no { * CPU interrupts are 0 ... 7 */ + CRIME_IRQ_BASE = MIPS_CPU_IRQ_BASE, + /* * MACE */ - MACE_VID_IN1_IRQ = MIPS_CPU_IRQ_BASE + 8, + MACE_VID_IN1_IRQ = CRIME_IRQ_BASE, MACE_VID_IN2_IRQ, MACE_VID_OUT_IRQ, MACE_ETHERNET_IRQ, diff --git a/include/asm-mips/jmr3927/jmr3927.h b/include/asm-mips/jmr3927/jmr3927.h index b2dc35f56181..81602c8047eb 100644 --- a/include/asm-mips/jmr3927/jmr3927.h +++ b/include/asm-mips/jmr3927/jmr3927.h @@ -132,9 +132,7 @@ #define JMR3927_IRQ_IRC_DMA (JMR3927_IRQ_IRC + TX3927_IR_DMA) #define JMR3927_IRQ_IRC_PIO (JMR3927_IRQ_IRC + TX3927_IR_PIO) #define JMR3927_IRQ_IRC_PCI (JMR3927_IRQ_IRC + TX3927_IR_PCI) -#define JMR3927_IRQ_IRC_TMR0 (JMR3927_IRQ_IRC + TX3927_IR_TMR0) -#define JMR3927_IRQ_IRC_TMR1 (JMR3927_IRQ_IRC + TX3927_IR_TMR1) -#define JMR3927_IRQ_IRC_TMR2 (JMR3927_IRQ_IRC + TX3927_IR_TMR2) +#define JMR3927_IRQ_IRC_TMR(ch) (JMR3927_IRQ_IRC + TX3927_IR_TMR(ch)) #define JMR3927_IRQ_IOC_PCIA (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIA) #define JMR3927_IRQ_IOC_PCIB (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIB) #define JMR3927_IRQ_IOC_PCIC (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIC) @@ -148,17 +146,12 @@ #define JMR3927_IRQ_IOCINT JMR3927_IRQ_IRC_INT1 /* TC35815 100M Ether (JMR-TX3912:JPW4:2-3 Short) */ #define JMR3927_IRQ_ETHER0 JMR3927_IRQ_IRC_INT3 -/* Clock Tick (10ms) */ -#define JMR3927_IRQ_TICK JMR3927_IRQ_IRC_TMR0 /* Clocks */ #define JMR3927_CORECLK 132710400 /* 132.7MHz */ #define JMR3927_GBUSCLK (JMR3927_CORECLK / 2) /* 66.35MHz */ #define JMR3927_IMCLK (JMR3927_CORECLK / 4) /* 33.17MHz */ -#define jmr3927_tmrptr tx3927_tmrptr(0) /* TMR0 */ - - /* * TX3927 Pin Configuration: * diff --git a/include/asm-mips/jmr3927/tx3927.h b/include/asm-mips/jmr3927/tx3927.h index 211bcf47fffb..338f99882a39 100644 --- a/include/asm-mips/jmr3927/tx3927.h +++ b/include/asm-mips/jmr3927/tx3927.h @@ -222,9 +222,7 @@ struct tx3927_ccfg_reg { #define TX3927_IR_DMA 8 #define TX3927_IR_PIO 9 #define TX3927_IR_PCI 10 -#define TX3927_IR_TMR0 13 -#define TX3927_IR_TMR1 14 -#define TX3927_IR_TMR2 15 +#define TX3927_IR_TMR(ch) (13 + (ch)) #define TX3927_NUM_IR 16 /* diff --git a/include/asm-mips/jmr3927/txx927.h b/include/asm-mips/jmr3927/txx927.h index 58a8ff6be815..0474fe8dac3f 100644 --- a/include/asm-mips/jmr3927/txx927.h +++ b/include/asm-mips/jmr3927/txx927.h @@ -10,22 +10,6 @@ #ifndef __ASM_TXX927_H #define __ASM_TXX927_H -struct txx927_tmr_reg { - volatile unsigned long tcr; - volatile unsigned long tisr; - volatile unsigned long cpra; - volatile unsigned long cprb; - volatile unsigned long itmr; - volatile unsigned long unused0[3]; - volatile unsigned long ccdr; - volatile unsigned long unused1[3]; - volatile unsigned long pgmr; - volatile unsigned long unused2[3]; - volatile unsigned long wtmr; - volatile unsigned long unused3[43]; - volatile unsigned long trr; -}; - struct txx927_sio_reg { volatile unsigned long lcr; volatile unsigned long dicr; @@ -51,27 +35,6 @@ struct txx927_pio_reg { }; /* - * TMR - */ -/* TMTCR : Timer Control */ -#define TXx927_TMTCR_TCE 0x00000080 -#define TXx927_TMTCR_CCDE 0x00000040 -#define TXx927_TMTCR_CRE 0x00000020 -#define TXx927_TMTCR_ECES 0x00000008 -#define TXx927_TMTCR_CCS 0x00000004 -#define TXx927_TMTCR_TMODE_MASK 0x00000003 -#define TXx927_TMTCR_TMODE_ITVL 0x00000000 - -/* TMTISR : Timer Int. Status */ -#define TXx927_TMTISR_TPIBS 0x00000004 -#define TXx927_TMTISR_TPIAS 0x00000002 -#define TXx927_TMTISR_TIIS 0x00000001 - -/* TMTITMR : Interval Timer Mode */ -#define TXx927_TMTITMR_TIIE 0x00008000 -#define TXx927_TMTITMR_TZCE 0x00000001 - -/* * SIO */ /* SILCR : Line Control */ diff --git a/include/asm-mips/time.h b/include/asm-mips/time.h index bc47af313bcd..0a6bc7dc158e 100644 --- a/include/asm-mips/time.h +++ b/include/asm-mips/time.h @@ -58,7 +58,6 @@ extern void local_timer_interrupt(int irq, void *dev_id); */ struct irqaction; extern void plat_time_init(void); -extern void plat_timer_setup(struct irqaction *irq); /* * mips_hpt_frequency - must be set if you intend to use an R4k-compatible @@ -78,6 +77,7 @@ extern int (*perf_irq)(void); */ #ifdef CONFIG_CEVT_R4K extern void mips_clockevent_init(void); +extern unsigned int __weak get_c0_compare_int(void); #else static inline void mips_clockevent_init(void) { diff --git a/include/asm-mips/tx4927/tx4927_pci.h b/include/asm-mips/tx4927/tx4927_pci.h index f98b2bb719d5..3f1e470192e3 100644 --- a/include/asm-mips/tx4927/tx4927_pci.h +++ b/include/asm-mips/tx4927/tx4927_pci.h @@ -9,6 +9,7 @@ #define __ASM_TX4927_TX4927_PCI_H #define TX4927_CCFG_TOE 0x00004000 +#define TX4927_CCFG_TINTDIS 0x01000000 #define TX4927_PCIMEM 0x08000000 #define TX4927_PCIMEM_SIZE 0x08000000 @@ -20,6 +21,8 @@ #define TX4927_PCIC_REG 0xff1fd000 #define TX4927_CCFG_REG 0xff1fe000 #define TX4927_IRC_REG 0xff1ff600 +#define TX4927_NR_TMR 3 +#define TX4927_TMR_REG(ch) (0xff1ff000 + (ch) * 0x100) #define TX4927_CE3 0x17f00000 /* 1M */ #define TX4927_PCIRESET_ADDR 0xbc00f006 #define TX4927_PCI_CLK_ADDR (KSEG1 + TX4927_CE3 + 0x00040020) diff --git a/include/asm-mips/tx4938/tx4938.h b/include/asm-mips/tx4938/tx4938.h index 650b010761f9..f7c448b90578 100644 --- a/include/asm-mips/tx4938/tx4938.h +++ b/include/asm-mips/tx4938/tx4938.h @@ -641,7 +641,6 @@ struct tx4938_ccfg_reg { #define tx4938_pcicptr ((struct tx4938_pcic_reg *)TX4938_PCIC_REG) #define tx4938_pcic1ptr ((struct tx4938_pcic_reg *)TX4938_PCIC1_REG) #define tx4938_ccfgptr ((struct tx4938_ccfg_reg *)TX4938_CCFG_REG) -#define tx4938_tmrptr(ch) ((struct tx4938_tmr_reg *)TX4938_TMR_REG(ch)) #define tx4938_sioptr(ch) ((struct tx4938_sio_reg *)TX4938_SIO_REG(ch)) #define tx4938_pioptr ((struct tx4938_pio_reg *)TX4938_PIO_REG) #define tx4938_aclcptr ((struct tx4938_aclc_reg *)TX4938_ACLC_REG) diff --git a/include/asm-mips/txx9tmr.h b/include/asm-mips/txx9tmr.h new file mode 100644 index 000000000000..67f70a8f09bd --- /dev/null +++ b/include/asm-mips/txx9tmr.h @@ -0,0 +1,67 @@ +/* + * include/asm-mips/txx9tmr.h + * TX39/TX49 timer controller definitions. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#ifndef __ASM_TXX9TMR_H +#define __ASM_TXX9TMR_H + +#include <linux/types.h> + +struct txx9_tmr_reg { + u32 tcr; + u32 tisr; + u32 cpra; + u32 cprb; + u32 itmr; + u32 unused0[3]; + u32 ccdr; + u32 unused1[3]; + u32 pgmr; + u32 unused2[3]; + u32 wtmr; + u32 unused3[43]; + u32 trr; +}; + +/* TMTCR : Timer Control */ +#define TXx9_TMTCR_TCE 0x00000080 +#define TXx9_TMTCR_CCDE 0x00000040 +#define TXx9_TMTCR_CRE 0x00000020 +#define TXx9_TMTCR_ECES 0x00000008 +#define TXx9_TMTCR_CCS 0x00000004 +#define TXx9_TMTCR_TMODE_MASK 0x00000003 +#define TXx9_TMTCR_TMODE_ITVL 0x00000000 +#define TXx9_TMTCR_TMODE_PGEN 0x00000001 +#define TXx9_TMTCR_TMODE_WDOG 0x00000002 + +/* TMTISR : Timer Int. Status */ +#define TXx9_TMTISR_TPIBS 0x00000004 +#define TXx9_TMTISR_TPIAS 0x00000002 +#define TXx9_TMTISR_TIIS 0x00000001 + +/* TMITMR : Interval Timer Mode */ +#define TXx9_TMITMR_TIIE 0x00008000 +#define TXx9_TMITMR_TZCE 0x00000001 + +/* TMWTMR : Watchdog Timer Mode */ +#define TXx9_TMWTMR_TWIE 0x00008000 +#define TXx9_TMWTMR_WDIS 0x00000080 +#define TXx9_TMWTMR_TWC 0x00000001 + +void txx9_clocksource_init(unsigned long baseaddr, + unsigned int imbusclk); +void txx9_clockevent_init(unsigned long baseaddr, int irq, + unsigned int imbusclk); +void txx9_tmr_init(unsigned long baseaddr); + +#ifdef CONFIG_CPU_TX39XX +#define TXX9_TIMER_BITS 24 +#else +#define TXX9_TIMER_BITS 32 +#endif + +#endif /* __ASM_TXX9TMR_H */ diff --git a/include/asm-x86/gart.h b/include/asm-x86/gart.h new file mode 100644 index 000000000000..f704c50519b8 --- /dev/null +++ b/include/asm-x86/gart.h @@ -0,0 +1,29 @@ +#ifndef _ASM_X8664_IOMMU_H +#define _ASM_X8664_IOMMU_H 1 + +extern void pci_iommu_shutdown(void); +extern void no_iommu_init(void); +extern int force_iommu, no_iommu; +extern int iommu_detected; +#ifdef CONFIG_GART_IOMMU +extern void gart_iommu_init(void); +extern void gart_iommu_shutdown(void); +extern void __init gart_parse_options(char *); +extern void gart_iommu_hole_init(void); +extern int fallback_aper_order; +extern int fallback_aper_force; +extern int gart_iommu_aperture; +extern int gart_iommu_aperture_allowed; +extern int gart_iommu_aperture_disabled; +extern int fix_aperture; +#else +#define gart_iommu_aperture 0 +#define gart_iommu_aperture_allowed 0 + +static inline void gart_iommu_shutdown(void) +{ +} + +#endif + +#endif diff --git a/include/asm-x86/iommu.h b/include/asm-x86/iommu.h index 5af471f228ee..07862fdd23c0 100644 --- a/include/asm-x86/iommu.h +++ b/include/asm-x86/iommu.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X8664_IOMMU_H -#define _ASM_X8664_IOMMU_H 1 +#ifndef _ASM_X8664_GART_H +#define _ASM_X8664_GART_H 1 extern void pci_iommu_shutdown(void); extern void no_iommu_init(void); diff --git a/include/asm-x86/pci_64.h b/include/asm-x86/pci_64.h index 9baa46d9f594..ef54226a9325 100644 --- a/include/asm-x86/pci_64.h +++ b/include/asm-x86/pci_64.h @@ -37,7 +37,7 @@ extern int iommu_setup(char *opt); */ #define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys) -#if defined(CONFIG_IOMMU) || defined(CONFIG_CALGARY_IOMMU) +#if defined(CONFIG_GART_IOMMU) || defined(CONFIG_CALGARY_IOMMU) #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ dma_addr_t ADDR_NAME; diff --git a/include/linux/sched.h b/include/linux/sched.h index 3c07d595979f..155d7438f7ad 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1009,6 +1009,7 @@ struct task_struct { unsigned int rt_priority; cputime_t utime, stime, utimescaled, stimescaled; cputime_t gtime; + cputime_t prev_utime, prev_stime; unsigned long nvcsw, nivcsw; /* context switch counts */ struct timespec start_time; /* monotonic time */ struct timespec real_start_time; /* boot based time */ diff --git a/kernel/fork.c b/kernel/fork.c index ddafdfac9456..28a740151988 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1056,6 +1056,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, p->gtime = cputime_zero; p->utimescaled = cputime_zero; p->stimescaled = cputime_zero; + p->prev_utime = cputime_zero; + p->prev_stime = cputime_zero; #ifdef CONFIG_TASK_XACCT p->rchar = 0; /* I/O counter: bytes read */ diff --git a/kernel/sched.c b/kernel/sched.c index b4fbbc440453..3f6bd1112900 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -172,6 +172,7 @@ struct task_group { unsigned long shares; /* spinlock to serialize modification to shares */ spinlock_t lock; + struct rcu_head rcu; }; /* Default task group's sched entity on each cpu */ @@ -258,7 +259,6 @@ struct cfs_rq { */ struct list_head leaf_cfs_rq_list; /* Better name : task_cfs_rq_list? */ struct task_group *tg; /* group that "owns" this runqueue */ - struct rcu_head rcu; #endif }; @@ -3355,7 +3355,7 @@ void account_user_time(struct task_struct *p, cputime_t cputime) * @p: the process that the cpu time gets accounted to * @cputime: the cpu time spent in virtual machine since the last update */ -void account_guest_time(struct task_struct *p, cputime_t cputime) +static void account_guest_time(struct task_struct *p, cputime_t cputime) { cputime64_t tmp; struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; @@ -5365,7 +5365,7 @@ static struct ctl_table sd_ctl_dir[] = { .procname = "sched_domain", .mode = 0555, }, - {0,}, + {0, }, }; static struct ctl_table sd_ctl_root[] = { @@ -5375,7 +5375,7 @@ static struct ctl_table sd_ctl_root[] = { .mode = 0555, .child = sd_ctl_dir, }, - {0,}, + {0, }, }; static struct ctl_table *sd_alloc_ctl_entry(int n) @@ -7019,8 +7019,8 @@ err: /* rcu callback to free various structures associated with a task group */ static void free_sched_group(struct rcu_head *rhp) { - struct cfs_rq *cfs_rq = container_of(rhp, struct cfs_rq, rcu); - struct task_group *tg = cfs_rq->tg; + struct task_group *tg = container_of(rhp, struct task_group, rcu); + struct cfs_rq *cfs_rq; struct sched_entity *se; int i; @@ -7041,7 +7041,7 @@ static void free_sched_group(struct rcu_head *rhp) /* Destroy runqueue etc associated with a task group */ void sched_destroy_group(struct task_group *tg) { - struct cfs_rq *cfs_rq; + struct cfs_rq *cfs_rq = NULL; int i; for_each_possible_cpu(i) { @@ -7049,10 +7049,10 @@ void sched_destroy_group(struct task_group *tg) list_del_rcu(&cfs_rq->leaf_cfs_rq_list); } - cfs_rq = tg->cfs_rq[0]; + BUG_ON(!cfs_rq); /* wait for possible concurrent references to cfs_rqs complete */ - call_rcu(&cfs_rq->rcu, free_sched_group); + call_rcu(&tg->rcu, free_sched_group); } /* change task's runqueue when it moves between groups. @@ -7211,25 +7211,53 @@ static u64 cpu_shares_read_uint(struct cgroup *cgrp, struct cftype *cft) return (u64) tg->shares; } -static struct cftype cpu_shares = { - .name = "shares", - .read_uint = cpu_shares_read_uint, - .write_uint = cpu_shares_write_uint, +static u64 cpu_usage_read(struct cgroup *cgrp, struct cftype *cft) +{ + struct task_group *tg = cgroup_tg(cgrp); + unsigned long flags; + u64 res = 0; + int i; + + for_each_possible_cpu(i) { + /* + * Lock to prevent races with updating 64-bit counters + * on 32-bit arches. + */ + spin_lock_irqsave(&cpu_rq(i)->lock, flags); + res += tg->se[i]->sum_exec_runtime; + spin_unlock_irqrestore(&cpu_rq(i)->lock, flags); + } + /* Convert from ns to ms */ + do_div(res, 1000000); + + return res; +} + +static struct cftype cpu_files[] = { + { + .name = "shares", + .read_uint = cpu_shares_read_uint, + .write_uint = cpu_shares_write_uint, + }, + { + .name = "usage", + .read_uint = cpu_usage_read, + }, }; static int cpu_cgroup_populate(struct cgroup_subsys *ss, struct cgroup *cont) { - return cgroup_add_file(cont, ss, &cpu_shares); + return cgroup_add_files(cont, ss, cpu_files, ARRAY_SIZE(cpu_files)); } struct cgroup_subsys cpu_cgroup_subsys = { - .name = "cpu", - .create = cpu_cgroup_create, - .destroy = cpu_cgroup_destroy, - .can_attach = cpu_cgroup_can_attach, - .attach = cpu_cgroup_attach, - .populate = cpu_cgroup_populate, - .subsys_id = cpu_cgroup_subsys_id, + .name = "cpu", + .create = cpu_cgroup_create, + .destroy = cpu_cgroup_destroy, + .can_attach = cpu_cgroup_can_attach, + .attach = cpu_cgroup_attach, + .populate = cpu_cgroup_populate, + .subsys_id = cpu_cgroup_subsys_id, .early_init = 1, }; diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 9971831b560e..01859f662ab7 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -1025,7 +1025,7 @@ static void task_tick_fair(struct rq *rq, struct task_struct *curr) } } -#define swap(a,b) do { typeof(a) tmp = (a); (a) = (b); (b) = tmp; } while (0) +#define swap(a, b) do { typeof(a) tmp = (a); (a) = (b); (b) = tmp; } while (0) /* * Share the fairness runtime between parent and child, thus the |