diff options
Diffstat (limited to 'arch')
483 files changed, 9414 insertions, 5544 deletions
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index da677f829f7..63af36cf7f6 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c @@ -49,15 +49,15 @@ select_smp_affinity(unsigned int irq) static int last_cpu; int cpu = last_cpu + 1; - if (!irq_desc[irq].handler->set_affinity || irq_user_affinity[irq]) + if (!irq_desc[irq].chip->set_affinity || irq_user_affinity[irq]) return 1; while (!cpu_possible(cpu)) cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0); last_cpu = cpu; - irq_affinity[irq] = cpumask_of_cpu(cpu); - irq_desc[irq].handler->set_affinity(irq, cpumask_of_cpu(cpu)); + irq_desc[irq].affinity = cpumask_of_cpu(cpu); + irq_desc[irq].chip->set_affinity(irq, cpumask_of_cpu(cpu)); return 0; } #endif /* CONFIG_SMP */ @@ -93,7 +93,7 @@ show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[irq]); #endif - seq_printf(p, " %14s", irq_desc[irq].handler->typename); + seq_printf(p, " %14s", irq_desc[irq].chip->typename); seq_printf(p, " %c%s", (action->flags & SA_INTERRUPT)?'+':' ', action->name); diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c index 9d34ce26e5e..f20f2dff9c4 100644 --- a/arch/alpha/kernel/irq_alpha.c +++ b/arch/alpha/kernel/irq_alpha.c @@ -233,7 +233,7 @@ void __init init_rtc_irq(void) { irq_desc[RTC_IRQ].status = IRQ_DISABLED; - irq_desc[RTC_IRQ].handler = &rtc_irq_type; + irq_desc[RTC_IRQ].chip = &rtc_irq_type; setup_irq(RTC_IRQ, &timer_irqaction); } diff --git a/arch/alpha/kernel/irq_i8259.c b/arch/alpha/kernel/irq_i8259.c index b188683b83f..ac893bd4803 100644 --- a/arch/alpha/kernel/irq_i8259.c +++ b/arch/alpha/kernel/irq_i8259.c @@ -109,7 +109,7 @@ init_i8259a_irqs(void) for (i = 0; i < 16; i++) { irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].handler = &i8259a_irq_type; + irq_desc[i].chip = &i8259a_irq_type; } setup_irq(2, &cascade); diff --git a/arch/alpha/kernel/irq_pyxis.c b/arch/alpha/kernel/irq_pyxis.c index 146a20b9e3d..3b581415bab 100644 --- a/arch/alpha/kernel/irq_pyxis.c +++ b/arch/alpha/kernel/irq_pyxis.c @@ -120,7 +120,7 @@ init_pyxis_irqs(unsigned long ignore_mask) if ((ignore_mask >> i) & 1) continue; irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &pyxis_irq_type; + irq_desc[i].chip = &pyxis_irq_type; } setup_irq(16+7, &isa_cascade_irqaction); diff --git a/arch/alpha/kernel/irq_srm.c b/arch/alpha/kernel/irq_srm.c index 0a87e466918..8e4d121f84c 100644 --- a/arch/alpha/kernel/irq_srm.c +++ b/arch/alpha/kernel/irq_srm.c @@ -67,7 +67,7 @@ init_srm_irqs(long max, unsigned long ignore_mask) if (i < 64 && ((ignore_mask >> i) & 1)) continue; irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &srm_irq_type; + irq_desc[i].chip = &srm_irq_type; } } diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index 2a8b364c822..4ea6711e55a 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c @@ -124,12 +124,12 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_final); void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; struct pci_controller *hose = dev->sysdata; unsigned long alignto; - unsigned long start = res->start; + resource_size_t start = res->start; if (res->flags & IORESOURCE_IO) { /* Make sure we start at our min on all hoses */ diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 558b8336855..254c507a608 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -481,7 +481,7 @@ register_cpus(void) struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL); if (!p) return -ENOMEM; - register_cpu(p, i, NULL); + register_cpu(p, i); } return 0; } diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c index d7f0e97fe56..1a1a2c7a3d9 100644 --- a/arch/alpha/kernel/sys_alcor.c +++ b/arch/alpha/kernel/sys_alcor.c @@ -144,7 +144,7 @@ alcor_init_irq(void) if (i >= 16+20 && i <= 16+30) continue; irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &alcor_irq_type; + irq_desc[i].chip = &alcor_irq_type; } i8259a_irq_type.ack = alcor_isa_mask_and_ack_irq; diff --git a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c index 8e3374d34c9..8c9e443d93a 100644 --- a/arch/alpha/kernel/sys_cabriolet.c +++ b/arch/alpha/kernel/sys_cabriolet.c @@ -124,7 +124,7 @@ common_init_irq(void (*srm_dev_int)(unsigned long v, struct pt_regs *r)) for (i = 16; i < 35; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &cabriolet_irq_type; + irq_desc[i].chip = &cabriolet_irq_type; } } diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c index d5da6b1b28e..b28c8f1c6e1 100644 --- a/arch/alpha/kernel/sys_dp264.c +++ b/arch/alpha/kernel/sys_dp264.c @@ -300,7 +300,7 @@ init_tsunami_irqs(struct hw_interrupt_type * ops, int imin, int imax) long i; for (i = imin; i <= imax; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = ops; + irq_desc[i].chip = ops; } } diff --git a/arch/alpha/kernel/sys_eb64p.c b/arch/alpha/kernel/sys_eb64p.c index 61a79c354f0..aeb8e027790 100644 --- a/arch/alpha/kernel/sys_eb64p.c +++ b/arch/alpha/kernel/sys_eb64p.c @@ -137,7 +137,7 @@ eb64p_init_irq(void) for (i = 16; i < 32; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &eb64p_irq_type; + irq_desc[i].chip = &eb64p_irq_type; } common_init_isa_dma(); diff --git a/arch/alpha/kernel/sys_eiger.c b/arch/alpha/kernel/sys_eiger.c index bd6e5f0e43c..64a785baf53 100644 --- a/arch/alpha/kernel/sys_eiger.c +++ b/arch/alpha/kernel/sys_eiger.c @@ -154,7 +154,7 @@ eiger_init_irq(void) for (i = 16; i < 128; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &eiger_irq_type; + irq_desc[i].chip = &eiger_irq_type; } } diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c index fcabb7c96a1..0148e095638 100644 --- a/arch/alpha/kernel/sys_jensen.c +++ b/arch/alpha/kernel/sys_jensen.c @@ -206,11 +206,11 @@ jensen_init_irq(void) { init_i8259a_irqs(); - irq_desc[1].handler = &jensen_local_irq_type; - irq_desc[4].handler = &jensen_local_irq_type; - irq_desc[3].handler = &jensen_local_irq_type; - irq_desc[7].handler = &jensen_local_irq_type; - irq_desc[9].handler = &jensen_local_irq_type; + irq_desc[1].chip = &jensen_local_irq_type; + irq_desc[4].chip = &jensen_local_irq_type; + irq_desc[3].chip = &jensen_local_irq_type; + irq_desc[7].chip = &jensen_local_irq_type; + irq_desc[9].chip = &jensen_local_irq_type; common_init_isa_dma(); } diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c index e32fee50522..36d21595437 100644 --- a/arch/alpha/kernel/sys_marvel.c +++ b/arch/alpha/kernel/sys_marvel.c @@ -303,7 +303,7 @@ init_io7_irqs(struct io7 *io7, /* Set up the lsi irqs. */ for (i = 0; i < 128; ++i) { irq_desc[base + i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[base + i].handler = lsi_ops; + irq_desc[base + i].chip = lsi_ops; } /* Disable the implemented irqs in hardware. */ @@ -317,7 +317,7 @@ init_io7_irqs(struct io7 *io7, /* Set up the msi irqs. */ for (i = 128; i < (128 + 512); ++i) { irq_desc[base + i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[base + i].handler = msi_ops; + irq_desc[base + i].chip = msi_ops; } for (i = 0; i < 16; ++i) @@ -335,7 +335,7 @@ marvel_init_irq(void) /* Reserve the legacy irqs. */ for (i = 0; i < 16; ++i) { irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].handler = &marvel_legacy_irq_type; + irq_desc[i].chip = &marvel_legacy_irq_type; } /* Init the io7 irqs. */ diff --git a/arch/alpha/kernel/sys_mikasa.c b/arch/alpha/kernel/sys_mikasa.c index d78a0daa616..b741600e376 100644 --- a/arch/alpha/kernel/sys_mikasa.c +++ b/arch/alpha/kernel/sys_mikasa.c @@ -117,7 +117,7 @@ mikasa_init_irq(void) for (i = 16; i < 32; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &mikasa_irq_type; + irq_desc[i].chip = &mikasa_irq_type; } init_i8259a_irqs(); diff --git a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c index 65061f5d741..55db02d318d 100644 --- a/arch/alpha/kernel/sys_noritake.c +++ b/arch/alpha/kernel/sys_noritake.c @@ -139,7 +139,7 @@ noritake_init_irq(void) for (i = 16; i < 48; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &noritake_irq_type; + irq_desc[i].chip = &noritake_irq_type; } init_i8259a_irqs(); diff --git a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c index 05888a02a60..949607e3d6f 100644 --- a/arch/alpha/kernel/sys_rawhide.c +++ b/arch/alpha/kernel/sys_rawhide.c @@ -180,7 +180,7 @@ rawhide_init_irq(void) for (i = 16; i < 128; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &rawhide_irq_type; + irq_desc[i].chip = &rawhide_irq_type; } init_i8259a_irqs(); diff --git a/arch/alpha/kernel/sys_rx164.c b/arch/alpha/kernel/sys_rx164.c index 58404243057..6ae50605263 100644 --- a/arch/alpha/kernel/sys_rx164.c +++ b/arch/alpha/kernel/sys_rx164.c @@ -117,7 +117,7 @@ rx164_init_irq(void) rx164_update_irq_hw(0); for (i = 16; i < 40; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &rx164_irq_type; + irq_desc[i].chip = &rx164_irq_type; } init_i8259a_irqs(); diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c index a7ff84474ac..24dea40c9bf 100644 --- a/arch/alpha/kernel/sys_sable.c +++ b/arch/alpha/kernel/sys_sable.c @@ -537,7 +537,7 @@ sable_lynx_init_irq(int nr_irqs) for (i = 0; i < nr_irqs; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &sable_lynx_irq_type; + irq_desc[i].chip = &sable_lynx_irq_type; } common_init_isa_dma(); diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c index 7955bdfc2db..2c75cd1fd81 100644 --- a/arch/alpha/kernel/sys_takara.c +++ b/arch/alpha/kernel/sys_takara.c @@ -154,7 +154,7 @@ takara_init_irq(void) for (i = 16; i < 128; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &takara_irq_type; + irq_desc[i].chip = &takara_irq_type; } common_init_isa_dma(); diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c index 2551fb49ae0..13f3ed8ed7a 100644 --- a/arch/alpha/kernel/sys_titan.c +++ b/arch/alpha/kernel/sys_titan.c @@ -189,7 +189,7 @@ init_titan_irqs(struct hw_interrupt_type * ops, int imin, int imax) long i; for (i = imin; i <= imax; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = ops; + irq_desc[i].chip = ops; } } diff --git a/arch/alpha/kernel/sys_wildfire.c b/arch/alpha/kernel/sys_wildfire.c index 1553f470246..22c5798fe08 100644 --- a/arch/alpha/kernel/sys_wildfire.c +++ b/arch/alpha/kernel/sys_wildfire.c @@ -199,14 +199,14 @@ wildfire_init_irq_per_pca(int qbbno, int pcano) if (i == 2) continue; irq_desc[i+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i+irq_bias].handler = &wildfire_irq_type; + irq_desc[i+irq_bias].chip = &wildfire_irq_type; } irq_desc[36+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[36+irq_bias].handler = &wildfire_irq_type; + irq_desc[36+irq_bias].chip = &wildfire_irq_type; for (i = 40; i < 64; ++i) { irq_desc[i+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i+irq_bias].handler = &wildfire_irq_type; + irq_desc[i+irq_bias].chip = &wildfire_irq_type; } setup_irq(32+irq_bias, &isa_enable); diff --git a/arch/alpha/oprofile/common.c b/arch/alpha/oprofile/common.c index ba788cfdc3c..9fc0eeb4f0a 100644 --- a/arch/alpha/oprofile/common.c +++ b/arch/alpha/oprofile/common.c @@ -112,7 +112,7 @@ op_axp_create_files(struct super_block * sb, struct dentry * root) for (i = 0; i < model->num_counters; ++i) { struct dentry *dir; - char buf[3]; + char buf[4]; snprintf(buf, sizeof buf, "%d", i); dir = oprofilefs_mkdir(sb, root, buf); diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1b7e5c2e90e..f123c7c9fc9 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -188,23 +188,27 @@ config ARCH_IMX config ARCH_IOP3XX bool "IOP3xx-based" + depends on MMU select PCI help Support for Intel's IOP3XX (XScale) family of processors. config ARCH_IXP4XX bool "IXP4xx-based" + depends on MMU help Support for Intel's IXP4XX (XScale) family of processors. config ARCH_IXP2000 bool "IXP2400/2800-based" + depends on MMU select PCI help Support for Intel's IXP2400/2800 (XScale) family of processors. config ARCH_IXP23XX bool "IXP23XX-based" + depends on MMU select PCI help Support for Intel's IXP23xx (XScale) family of processors. @@ -229,6 +233,7 @@ config ARCH_PNX4008 config ARCH_PXA bool "PXA2xx-based" + depends on MMU select ARCH_MTD_XIP help Support for Intel's PXA2XX processor line. @@ -253,7 +258,7 @@ config ARCH_SA1100 Support for StrongARM 11x0 based boards. config ARCH_S3C2410 - bool "Samsung S3C2410" + bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442" help Samsung S3C2410X CPU based systems, such as the Simtec Electronics BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or @@ -339,6 +344,10 @@ config XSCALE_PMU depends on CPU_XSCALE && !XSCALE_PMU_TIMER default y +if !MMU +source "arch/arm/Kconfig-nommu" +endif + endmenu source "arch/arm/common/Kconfig" @@ -372,7 +381,7 @@ config ISA_DMA_API bool config PCI - bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB + bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX help Find out whether you have a PCI motherboard. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 282b14e2f46..a3bbaaf480b 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -177,7 +177,7 @@ boot := arch/arm/boot # them changed. We use .arch to indicate when they were updated # last, otherwise make uses the target directory mtime. -include/asm-arm/.arch: $(wildcard include/config/arch/*.h) include/config/MARKER +include/asm-arm/.arch: $(wildcard include/config/arch/*.h) include/config/auto.conf @echo ' SYMLINK include/asm-arm/arch -> include/asm-arm/$(INCDIR)' ifneq ($(KBUILD_SRC),) $(Q)mkdir -p include/asm-arm diff --git a/arch/arm/boot/compressed/head-at91rm9200.S b/arch/arm/boot/compressed/head-at91rm9200.S index 57a3b163b2c..d68b9acd826 100644 --- a/arch/arm/boot/compressed/head-at91rm9200.S +++ b/arch/arm/boot/compressed/head-at91rm9200.S @@ -61,6 +61,12 @@ cmp r7, r3 beq 99f + @ Ajeco 1ARM : 1075 + mov r3, #(MACH_TYPE_ONEARM & 0xff) + orr r3, r3, #(MACH_TYPE_ONEARM & 0xff00) + cmp r7, r3 + beq 99f + @ Unknown board, use the AT91RM9200DK board @ mov r7, #MACH_TYPE_AT91RM9200 mov r7, #(MACH_TYPE_AT91RM9200DK & 0xff) diff --git a/arch/arm/boot/compressed/ll_char_wr.S b/arch/arm/boot/compressed/ll_char_wr.S index d7bbd9da2fc..8517c8606b4 100644 --- a/arch/arm/boot/compressed/ll_char_wr.S +++ b/arch/arm/boot/compressed/ll_char_wr.S @@ -77,7 +77,7 @@ Lrow4bpplp: subne r1, r1, #1 ldrneb r7, [r6, r1] bne Lrow4bpplp - LOADREGS(fd, sp!, {r4 - r7, pc}) + ldmfd sp!, {r4 - r7, pc} @ @ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc) @@ -105,7 +105,7 @@ Lrow8bpplp: subne r1, r1, #1 ldrneb r7, [r6, r1] bne Lrow8bpplp - LOADREGS(fd, sp!, {r4 - r7, pc}) + ldmfd sp!, {r4 - r7, pc} @ @ Smashable regs: {r0 - r3}, [r4], {r5, r6}, [r7], (r8 - fp), [ip], (sp), [lr], (pc) @@ -127,7 +127,7 @@ Lrow1bpp: strb r7, [r0], r5 mov r7, r7, lsr #8 strb r7, [r0], r5 - LOADREGS(fd, sp!, {r4 - r7, pc}) + ldmfd sp!, {r4 - r7, pc} .bss ENTRY(con_charconvtable) diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index a7dc1370695..0dafba3a701 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c @@ -629,21 +629,6 @@ static int locomo_resume(struct platform_device *dev) #endif -#define LCM_ALC_EN 0x8000 - -void frontlight_set(struct locomo *lchip, int duty, int vr, int bpwf) -{ - unsigned long flags; - - spin_lock_irqsave(&lchip->lock, flags); - locomo_writel(bpwf, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS); - udelay(100); - locomo_writel(duty, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD); - locomo_writel(bpwf | LCM_ALC_EN, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS); - spin_unlock_irqrestore(&lchip->lock, flags); -} - - /** * locomo_probe - probe for a single LoCoMo chip. * @phys_addr: physical address of device. @@ -698,14 +683,10 @@ __locomo_probe(struct device *me, struct resource *mem, int irq) , lchip->base + LOCOMO_GPD); locomo_writel(0, lchip->base + LOCOMO_GIE); - /* FrontLight */ + /* Frontlight */ locomo_writel(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS); locomo_writel(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD); - /* Same constants can be used for collie and poodle - (depending on CONFIG options in original sharp code)? */ - frontlight_set(lchip, 163, 0, 148); - /* Longtime timer */ locomo_writel(0, lchip->base + LOCOMO_LTINT); /* SPI */ @@ -1063,6 +1044,30 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int } /* + * Frontlight control + */ + +static struct locomo *locomo_chip_driver(struct locomo_dev *ldev); + +void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf) +{ + unsigned long flags; + struct locomo *lchip = locomo_chip_driver(dev); + + if (vr) + locomo_gpio_write(dev, LOCOMO_GPIO_FL_VR, 1); + else + locomo_gpio_write(dev, LOCOMO_GPIO_FL_VR, 0); + + spin_lock_irqsave(&lchip->lock, flags); + locomo_writel(bpwf, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS); + udelay(100); + locomo_writel(duty, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD); + locomo_writel(bpwf | LOCOMO_ALC_EN, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS); + spin_unlock_irqrestore(&lchip->lock, flags); +} + +/* * LoCoMo "Register Access Bus." * * We model this as a regular bus type, and hang devices directly diff --git a/arch/arm/configs/onearm_defconfig b/arch/arm/configs/onearm_defconfig new file mode 100644 index 00000000000..5401c01caef --- /dev/null +++ b/arch/arm/configs/onearm_defconfig @@ -0,0 +1,1053 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.17-git10 +# Mon Jun 26 13:45:44 2006 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_VECTORS_BASE=0xffff0000 + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_UID16=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# +# CONFIG_BLK_DEV_IO_TRACE is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +CONFIG_ARCH_AT91RM9200=y +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set + +# +# AT91RM9200 Implementations +# + +# +# AT91RM9200 Board Type +# +CONFIG_MACH_ONEARM=y +# CONFIG_ARCH_AT91RM9200DK is not set +# CONFIG_MACH_AT91RM9200EK is not set +# CONFIG_MACH_CSB337 is not set +# CONFIG_MACH_CSB637 is not set +# CONFIG_MACH_CARMEVA is not set +# CONFIG_MACH_KB9200 is not set +# CONFIG_MACH_ATEB9200 is not set +# CONFIG_MACH_KAFA is not set + +# +# AT91RM9200 Feature Selections +# +CONFIG_AT91_PROGRAMMABLE_CLOCKS=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM920T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +CONFIG_PCCARD=y +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_IOCTL=y + +# +# PC-card bridges +# +CONFIG_AT91_CF=y + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +# CONFIG_NO_IDLE_HZ is not set +CONFIG_HZ=100 +# CONFIG_AEABI is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +# CONFIG_LEDS_CPU is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set +# CONFIG_APM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x0 +CONFIG_MTD_PHYSMAP_LEN=0x0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=0 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_ARM_AT91_ETHER=y +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_AT91=y +CONFIG_SERIAL_AT91_CONSOLE=y +# CONFIG_SERIAL_AT91_TTYAT is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_AT91_WATCHDOG=y + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_CARDMAN_4000 is not set +# CONFIG_CARDMAN_4040 is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set +# CONFIG_USB_DABUSB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +CONFIG_USB_DEBUG=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Input Devices +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_TOUCHSCREEN is not set +# CONFIG_USB_YEALINK is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_ATI_REMOTE2 is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +CONFIG_USB_GADGET_AT91=y +CONFIG_USB_AT91=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_DUALSPEED is not set +# CONFIG_USB_ZERO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set + +# +# MMC/SD Card support +# +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_BLOCK=y +CONFIG_MMC_AT91RM9200=y + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_MAGIC_SYSRQ is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_VM is not set +CONFIG_FRAME_POINTER=y +# CONFIG_UNWIND_INFO is not set +CONFIG_FORCED_INLINING=y +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_ERRORS is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index e1766138009..f20814e6f49 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17 -# Tue Jun 20 18:57:01 2006 +# Linux kernel version: 2.6.17-git9 +# Sun Jun 25 23:56:32 2006 # CONFIG_ARM=y CONFIG_MMU=y @@ -49,7 +49,6 @@ CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set -CONFIG_OBSOLETE_INTERMODULE=y # # Loadable module support @@ -81,18 +80,26 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # # System Type # +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91RM9200 is not set # CONFIG_ARCH_CLPS7500 is not set # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set # CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set # CONFIG_ARCH_IOP3XX is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set # CONFIG_ARCH_IXP23XX is not set # CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PNX4008 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set @@ -100,14 +107,6 @@ CONFIG_ARCH_S3C2410=y # CONFIG_ARCH_SHARK is not set # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_OMAP is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_REALVIEW is not set -# CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_AAEC2000 is not set -# CONFIG_ARCH_AT91RM9200 is not set -# CONFIG_ARCH_PNX4008 is not set -# CONFIG_ARCH_NETX is not set # # S3C24XX Implementations @@ -123,11 +122,14 @@ CONFIG_ARCH_SMDK2410=y CONFIG_ARCH_S3C2440=y CONFIG_SMDK2440_CPU2440=y CONFIG_SMDK2440_CPU2442=y +CONFIG_MACH_SMDK2413=y CONFIG_MACH_VR1000=y CONFIG_MACH_RX3715=y CONFIG_MACH_OTOM=y CONFIG_MACH_NEXCODER_2440=y +CONFIG_S3C2410_CLOCK=y CONFIG_CPU_S3C2410=y +CONFIG_CPU_S3C2412=y CONFIG_CPU_S3C244X=y CONFIG_CPU_S3C2440=y CONFIG_CPU_S3C2442=y @@ -153,8 +155,11 @@ CONFIG_S3C2410_LOWLEVEL_UART_PORT=0 # CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y +CONFIG_CPU_ARM926T=y CONFIG_CPU_32v4=y +CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_ABRT_EV5TJ=y CONFIG_CPU_CACHE_V4WT=y CONFIG_CPU_CACHE_VIVT=y CONFIG_CPU_COPY_V4WB=y @@ -167,6 +172,7 @@ CONFIG_CPU_TLB_V4WBI=y # CONFIG_CPU_ICACHE_DISABLE is not set # CONFIG_CPU_DCACHE_DISABLE is not set # CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set # # Bus support @@ -214,6 +220,7 @@ CONFIG_CMDLINE="root=/dev/hda1 ro init=/bin/bash console=ttySAC0" CONFIG_FPE_NWFPE=y # CONFIG_FPE_NWFPE_XP is not set # CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set # # Userspace binary formats @@ -242,6 +249,8 @@ CONFIG_NET=y # CONFIG_NETDEBUG is not set # CONFIG_PACKET is not set CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -260,6 +269,8 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -267,6 +278,7 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set # @@ -321,6 +333,7 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker @@ -408,10 +421,12 @@ CONFIG_MTD_BAST_MAXSIZE=4 # CONFIG_MTD_NAND=y # CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set CONFIG_MTD_NAND_IDS=y CONFIG_MTD_NAND_S3C2410=y # CONFIG_MTD_NAND_S3C2410_DEBUG is not set # CONFIG_MTD_NAND_S3C2410_HWECC is not set +# CONFIG_MTD_NAND_S3C2410_CLKSTOP is not set # CONFIG_MTD_NAND_DISKONCHIP is not set # CONFIG_MTD_NAND_NANDSIM is not set @@ -425,8 +440,8 @@ CONFIG_MTD_NAND_S3C2410=y # CONFIG_PARPORT=y # CONFIG_PARPORT_PC is not set -# CONFIG_PARPORT_ARC is not set # CONFIG_PARPORT_GSC is not set +# CONFIG_PARPORT_AX88796 is not set CONFIG_PARPORT_1284=y # @@ -735,6 +750,7 @@ CONFIG_I2C_ALGOBIT=m # # CONFIG_I2C_ELEKTOR is not set CONFIG_I2C_ISA=m +# CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT is not set # CONFIG_I2C_PARPORT_LIGHT is not set CONFIG_I2C_S3C2410=y @@ -765,13 +781,13 @@ CONFIG_SENSORS_EEPROM=m # # Dallas's 1-wire bus # -# CONFIG_W1 is not set # # Hardware Monitoring support # CONFIG_HWMON=y CONFIG_HWMON_VID=m +# CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set @@ -799,8 +815,10 @@ CONFIG_SENSORS_LM85=m # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set # CONFIG_SENSORS_W83792D is not set # CONFIG_SENSORS_W83L785TS is not set # CONFIG_SENSORS_W83627HF is not set @@ -845,6 +863,7 @@ CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_MACMODES is not set CONFIG_FB_FIRMWARE_EDID=y +# CONFIG_FB_BACKLIGHT is not set CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_TILEBLITTING is not set # CONFIG_FB_S1D13XXX is not set @@ -976,10 +995,12 @@ CONFIG_USB_MON=y # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set +# CONFIG_USB_CY7C63 is not set # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_LD is not set # CONFIG_USB_TEST is not set @@ -1024,6 +1045,7 @@ CONFIG_FS_MBCACHE=y # CONFIG_MINIX_FS is not set CONFIG_ROMFS_FS=y CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index a601b8b55f3..7cffbaef064 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -22,6 +22,9 @@ obj-$(CONFIG_PCI) += bios32.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o +obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o +AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312 + obj-$(CONFIG_IWMMXT) += iwmmxt.o AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index c49b5d4d7fc..da69e660574 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -109,11 +109,13 @@ EXPORT_SYMBOL(memchr); EXPORT_SYMBOL(__memzero); /* user mem (segment) */ -EXPORT_SYMBOL(__arch_copy_from_user); -EXPORT_SYMBOL(__arch_copy_to_user); -EXPORT_SYMBOL(__arch_clear_user); -EXPORT_SYMBOL(__arch_strnlen_user); -EXPORT_SYMBOL(__arch_strncpy_from_user); +EXPORT_SYMBOL(__strnlen_user); +EXPORT_SYMBOL(__strncpy_from_user); + +#ifdef CONFIG_MMU +EXPORT_SYMBOL(__copy_from_user); +EXPORT_SYMBOL(__copy_to_user); +EXPORT_SYMBOL(__clear_user); EXPORT_SYMBOL(__get_user_1); EXPORT_SYMBOL(__get_user_2); @@ -123,6 +125,7 @@ EXPORT_SYMBOL(__put_user_1); EXPORT_SYMBOL(__put_user_2); EXPORT_SYMBOL(__put_user_4); EXPORT_SYMBOL(__put_user_8); +#endif /* crypto hash */ EXPORT_SYMBOL(sha_transform); diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index 396efba9bac..447ede5143a 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c @@ -60,6 +60,9 @@ int main(void) #ifdef CONFIG_IWMMXT DEFINE(TI_IWMMXT_STATE, offsetof(struct thread_info, fpstate.iwmmxt)); #endif +#ifdef CONFIG_CRUNCH + DEFINE(TI_CRUNCH_STATE, offsetof(struct thread_info, crunchstate)); +#endif BLANK(); DEFINE(S_R0, offsetof(struct pt_regs, ARM_r0)); DEFINE(S_R1, offsetof(struct pt_regs, ARM_r1)); diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index 302fc140154..45da06fc1ba 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -304,7 +304,7 @@ static inline int pdev_bad_for_parity(struct pci_dev *dev) static void __devinit pdev_fixup_device_resources(struct pci_sys_data *root, struct pci_dev *dev) { - unsigned long offset; + resource_size_t offset; int i; for (i = 0; i < PCI_NUM_RESOURCES; i++) { @@ -634,9 +634,9 @@ char * __init pcibios_setup(char *str) * which might be mirrored at 0x0100-0x03ff.. */ void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { - unsigned long start = res->start; + resource_size_t start = res->start; if (res->flags & IORESOURCE_IO && start & 0x300) start = (start + 0x3ff) & ~0x3ff; diff --git a/arch/arm/kernel/crunch-bits.S b/arch/arm/kernel/crunch-bits.S new file mode 100644 index 00000000000..a26886758c6 --- /dev/null +++ b/arch/arm/kernel/crunch-bits.S @@ -0,0 +1,305 @@ +/* + * arch/arm/kernel/crunch-bits.S + * Cirrus MaverickCrunch context switching and handling + * + * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> + * + * Shamelessly stolen from the iWMMXt code by Nicolas Pitre, which is + * Copyright (c) 2003-2004, MontaVista Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/linkage.h> +#include <asm/ptrace.h> +#include <asm/thread_info.h> +#include <asm/asm-offsets.h> +#include <asm/arch/ep93xx-regs.h> + +/* + * We can't use hex constants here due to a bug in gas. + */ +#define CRUNCH_MVDX0 0 +#define CRUNCH_MVDX1 8 +#define CRUNCH_MVDX2 16 +#define CRUNCH_MVDX3 24 +#define CRUNCH_MVDX4 32 +#define CRUNCH_MVDX5 40 +#define CRUNCH_MVDX6 48 +#define CRUNCH_MVDX7 56 +#define CRUNCH_MVDX8 64 +#define CRUNCH_MVDX9 72 +#define CRUNCH_MVDX10 80 +#define CRUNCH_MVDX11 88 +#define CRUNCH_MVDX12 96 +#define CRUNCH_MVDX13 104 +#define CRUNCH_MVDX14 112 +#define CRUNCH_MVDX15 120 +#define CRUNCH_MVAX0L 128 +#define CRUNCH_MVAX0M 132 +#define CRUNCH_MVAX0H 136 +#define CRUNCH_MVAX1L 140 +#define CRUNCH_MVAX1M 144 +#define CRUNCH_MVAX1H 148 +#define CRUNCH_MVAX2L 152 +#define CRUNCH_MVAX2M 156 +#define CRUNCH_MVAX2H 160 +#define CRUNCH_MVAX3L 164 +#define CRUNCH_MVAX3M 168 +#define CRUNCH_MVAX3H 172 +#define CRUNCH_DSPSC 176 + +#define CRUNCH_SIZE 184 + + .text + +/* + * Lazy switching of crunch coprocessor context + * + * r10 = struct thread_info pointer + * r9 = ret_from_exception + * lr = undefined instr exit + * + * called from prefetch exception handler with interrupts disabled + */ +ENTRY(crunch_task_enable) + ldr r8, =(EP93XX_APB_VIRT_BASE + 0x00130000) @ syscon addr + + ldr r1, [r8, #0x80] + tst r1, #0x00800000 @ access to crunch enabled? + movne pc, lr @ if so no business here + mov r3, #0xaa @ unlock syscon swlock + str r3, [r8, #0xc0] + orr r1, r1, #0x00800000 @ enable access to crunch + str r1, [r8, #0x80] + + ldr r3, =crunch_owner + add r0, r10, #TI_CRUNCH_STATE @ get task crunch save area + ldr r2, [sp, #60] @ current task pc value + ldr r1, [r3] @ get current crunch owner + str r0, [r3] @ this task now owns crunch + sub r2, r2, #4 @ adjust pc back + str r2, [sp, #60] + + ldr r2, [r8, #0x80] + mov r2, r2 @ flush out enable (@@@) + + teq r1, #0 @ test for last ownership + mov lr, r9 @ normal exit from exception + beq crunch_load @ no owner, skip save + +crunch_save: + cfstr64 mvdx0, [r1, #CRUNCH_MVDX0] @ save 64b registers + cfstr64 mvdx1, [r1, #CRUNCH_MVDX1] + cfstr64 mvdx2, [r1, #CRUNCH_MVDX2] + cfstr64 mvdx3, [r1, #CRUNCH_MVDX3] + cfstr64 mvdx4, [r1, #CRUNCH_MVDX4] + cfstr64 mvdx5, [r1, #CRUNCH_MVDX5] + cfstr64 mvdx6, [r1, #CRUNCH_MVDX6] + cfstr64 mvdx7, [r1, #CRUNCH_MVDX7] + cfstr64 mvdx8, [r1, #CRUNCH_MVDX8] + cfstr64 mvdx9, [r1, #CRUNCH_MVDX9] + cfstr64 mvdx10, [r1, #CRUNCH_MVDX10] + cfstr64 mvdx11, [r1, #CRUNCH_MVDX11] + cfstr64 mvdx12, [r1, #CRUNCH_MVDX12] + cfstr64 mvdx13, [r1, #CRUNCH_MVDX13] + cfstr64 mvdx14, [r1, #CRUNCH_MVDX14] + cfstr64 mvdx15, [r1, #CRUNCH_MVDX15] + +#ifdef __ARMEB__ +#error fix me for ARMEB +#endif + + cfmv32al mvfx0, mvax0 @ save 72b accumulators + cfstr32 mvfx0, [r1, #CRUNCH_MVAX0L] + cfmv32am mvfx0, mvax0 + cfstr32 mvfx0, [r1, #CRUNCH_MVAX0M] + cfmv32ah mvfx0, mvax0 + cfstr32 mvfx0, [r1, #CRUNCH_MVAX0H] + cfmv32al mvfx0, mvax1 + cfstr32 mvfx0, [r1, #CRUNCH_MVAX1L] + cfmv32am mvfx0, mvax1 + cfstr32 mvfx0, [r1, #CRUNCH_MVAX1M] + cfmv32ah mvfx0, mvax1 + cfstr32 mvfx0, [r1, #CRUNCH_MVAX1H] + cfmv32al mvfx0, mvax2 + cfstr32 mvfx0, [r1, #CRUNCH_MVAX2L] + cfmv32am mvfx0, mvax2 + cfstr32 mvfx0, [r1, #CRUNCH_MVAX2M] + cfmv32ah mvfx0, mvax2 + cfstr32 mvfx0, [r1, #CRUNCH_MVAX2H] + cfmv32al mvfx0, mvax3 + cfstr32 mvfx0, [r1, #CRUNCH_MVAX3L] + cfmv32am mvfx0, mvax3 + cfstr32 mvfx0, [r1, #CRUNCH_MVAX3M] + cfmv32ah mvfx0, mvax3 + cfstr32 mvfx0, [r1, #CRUNCH_MVAX3H] + + cfmv32sc mvdx0, dspsc @ save status word + cfstr64 mvdx0, [r1, #CRUNCH_DSPSC] + + teq r0, #0 @ anything to load? + cfldr64eq mvdx0, [r1, #CRUNCH_MVDX0] @ mvdx0 was clobbered + moveq pc, lr + +crunch_load: + cfldr64 mvdx0, [r0, #CRUNCH_DSPSC] @ load status word + cfmvsc32 dspsc, mvdx0 + + cfldr32 mvfx0, [r0, #CRUNCH_MVAX0L] @ load 72b accumulators + cfmval32 mvax0, mvfx0 + cfldr32 mvfx0, [r0, #CRUNCH_MVAX0M] + cfmvam32 mvax0, mvfx0 + cfldr32 mvfx0, [r0, #CRUNCH_MVAX0H] + cfmvah32 mvax0, mvfx0 + cfldr32 mvfx0, [r0, #CRUNCH_MVAX1L] + cfmval32 mvax1, mvfx0 + cfldr32 mvfx0, [r0, #CRUNCH_MVAX1M] + cfmvam32 mvax1, mvfx0 + cfldr32 mvfx0, [r0, #CRUNCH_MVAX1H] + cfmvah32 mvax1, mvfx0 + cfldr32 mvfx0, [r0, #CRUNCH_MVAX2L] + cfmval32 mvax2, mvfx0 + cfldr32 mvfx0, [r0, #CRUNCH_MVAX2M] + cfmvam32 mvax2, mvfx0 + cfldr32 mvfx0, [r0, #CRUNCH_MVAX2H] + cfmvah32 mvax2, mvfx0 + cfldr32 mvfx0, [r0, #CRUNCH_MVAX3L] + cfmval32 mvax3, mvfx0 + cfldr32 mvfx0, [r0, #CRUNCH_MVAX3M] + cfmvam32 mvax3, mvfx0 + cfldr32 mvfx0, [r0, #CRUNCH_MVAX3H] + cfmvah32 mvax3, mvfx0 + + cfldr64 mvdx0, [r0, #CRUNCH_MVDX0] @ load 64b registers + cfldr64 mvdx1, [r0, #CRUNCH_MVDX1] + cfldr64 mvdx2, [r0, #CRUNCH_MVDX2] + cfldr64 mvdx3, [r0, #CRUNCH_MVDX3] + cfldr64 mvdx4, [r0, #CRUNCH_MVDX4] + cfldr64 mvdx5, [r0, #CRUNCH_MVDX5] + cfldr64 mvdx6, [r0, #CRUNCH_MVDX6] + cfldr64 mvdx7, [r0, #CRUNCH_MVDX7] + cfldr64 mvdx8, [r0, #CRUNCH_MVDX8] + cfldr64 mvdx9, [r0, #CRUNCH_MVDX9] + cfldr64 mvdx10, [r0, #CRUNCH_MVDX10] + cfldr64 mvdx11, [r0, #CRUNCH_MVDX11] + cfldr64 mvdx12, [r0, #CRUNCH_MVDX12] + cfldr64 mvdx13, [r0, #CRUNCH_MVDX13] + cfldr64 mvdx14, [r0, #CRUNCH_MVDX14] + cfldr64 mvdx15, [r0, #CRUNCH_MVDX15] + + mov pc, lr + +/* + * Back up crunch regs to save area and disable access to them + * (mainly for gdb or sleep mode usage) + * + * r0 = struct thread_info pointer of target task or NULL for any + */ +ENTRY(crunch_task_disable) + stmfd sp!, {r4, r5, lr} + + mrs ip, cpsr + orr r2, ip, #PSR_I_BIT @ disable interrupts + msr cpsr_c, r2 + + ldr r4, =(EP93XX_APB_VIRT_BASE + 0x00130000) @ syscon addr + + ldr r3, =crunch_owner + add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area + ldr r1, [r3] @ get current crunch owner + teq r1, #0 @ any current owner? + beq 1f @ no: quit + teq r0, #0 @ any owner? + teqne r1, r2 @ or specified one? + bne 1f @ no: quit + + ldr r5, [r4, #0x80] @ enable access to crunch + mov r2, #0xaa + str r2, [r4, #0xc0] + orr r5, r5, #0x00800000 + str r5, [r4, #0x80] + + mov r0, #0 @ nothing to load + str r0, [r3] @ no more current owner + ldr r2, [r4, #0x80] @ flush out enable (@@@) + mov r2, r2 + bl crunch_save + + mov r2, #0xaa @ disable access to crunch + str r2, [r4, #0xc0] + bic r5, r5, #0x00800000 + str r5, [r4, #0x80] + ldr r5, [r4, #0x80] @ flush out enable (@@@) + mov r5, r5 + +1: msr cpsr_c, ip @ restore interrupt mode + ldmfd sp!, {r4, r5, pc} + +/* + * Copy crunch state to given memory address + * + * r0 = struct thread_info pointer of target task + * r1 = memory address where to store crunch state + * + * this is called mainly in the creation of signal stack frames + */ +ENTRY(crunch_task_copy) + mrs ip, cpsr + orr r2, ip, #PSR_I_BIT @ disable interrupts + msr cpsr_c, r2 + + ldr r3, =crunch_owner + add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area + ldr r3, [r3] @ get current crunch owner + teq r2, r3 @ does this task own it... + beq 1f + + @ current crunch values are in the task save area + msr cpsr_c, ip @ restore interrupt mode + mov r0, r1 + mov r1, r2 + mov r2, #CRUNCH_SIZE + b memcpy + +1: @ this task owns crunch regs -- grab a copy from there + mov r0, #0 @ nothing to load + mov r3, lr @ preserve return address + bl crunch_save + msr cpsr_c, ip @ restore interrupt mode + mov pc, r3 + +/* + * Restore crunch state from given memory address + * + * r0 = struct thread_info pointer of target task + * r1 = memory address where to get crunch state from + * + * this is used to restore crunch state when unwinding a signal stack frame + */ +ENTRY(crunch_task_restore) + mrs ip, cpsr + orr r2, ip, #PSR_I_BIT @ disable interrupts + msr cpsr_c, r2 + + ldr r3, =crunch_owner + add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area + ldr r3, [r3] @ get current crunch owner + teq r2, r3 @ does this task own it... + beq 1f + + @ this task doesn't own crunch regs -- use its save area + msr cpsr_c, ip @ restore interrupt mode + mov r0, r2 + mov r2, #CRUNCH_SIZE + b memcpy + +1: @ this task owns crunch regs -- load them directly + mov r0, r1 + mov r1, #0 @ nothing to save + mov r3, lr @ preserve return address + bl crunch_load + msr cpsr_c, ip @ restore interrupt mode + mov pc, r3 diff --git a/arch/arm/kernel/crunch.c b/arch/arm/kernel/crunch.c new file mode 100644 index 00000000000..748175921f9 --- /dev/null +++ b/arch/arm/kernel/crunch.c @@ -0,0 +1,83 @@ +/* + * arch/arm/kernel/crunch.c + * Cirrus MaverickCrunch context switching and handling + * + * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/config.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/init.h> +#include <asm/arch/ep93xx-regs.h> +#include <asm/thread_notify.h> +#include <asm/io.h> + +struct crunch_state *crunch_owner; + +void crunch_task_release(struct thread_info *thread) +{ + local_irq_disable(); + if (crunch_owner == &thread->crunchstate) + crunch_owner = NULL; + local_irq_enable(); +} + +static int crunch_enabled(u32 devcfg) +{ + return !!(devcfg & EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE); +} + +static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t) +{ + struct thread_info *thread = (struct thread_info *)t; + struct crunch_state *crunch_state; + u32 devcfg; + + crunch_state = &thread->crunchstate; + + switch (cmd) { + case THREAD_NOTIFY_FLUSH: + memset(crunch_state, 0, sizeof(*crunch_state)); + + /* + * FALLTHROUGH: Ensure we don't try to overwrite our newly + * initialised state information on the first fault. + */ + + case THREAD_NOTIFY_RELEASE: + crunch_task_release(thread); + break; + + case THREAD_NOTIFY_SWITCH: + devcfg = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG); + if (crunch_enabled(devcfg) || crunch_owner == crunch_state) { + devcfg ^= EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE; + __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); + __raw_writel(devcfg, EP93XX_SYSCON_DEVICE_CONFIG); + } + break; + } + + return NOTIFY_DONE; +} + +static struct notifier_block crunch_notifier_block = { + .notifier_call = crunch_do, +}; + +static int __init crunch_init(void) +{ + thread_register_notifier(&crunch_notifier_block); + + return 0; +} + +late_initcall(crunch_init); diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 86c92523a34..6423a38839b 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -492,9 +492,15 @@ call_fpe: b do_fpe @ CP#1 (FPE) b do_fpe @ CP#2 (FPE) mov pc, lr @ CP#3 +#ifdef CONFIG_CRUNCH + b crunch_task_enable @ CP#4 (MaverickCrunch) + b crunch_task_enable @ CP#5 (MaverickCrunch) + b crunch_task_enable @ CP#6 (MaverickCrunch) +#else mov pc, lr @ CP#4 mov pc, lr @ CP#5 mov pc, lr @ CP#6 +#endif mov pc, lr @ CP#7 mov pc, lr @ CP#8 mov pc, lr @ CP#9 diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index b5bcebca1cd..75af6d6e2f2 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -340,7 +340,7 @@ sys_mmap2: streq r5, [sp, #4] beq do_mmap2 mov r0, #-EINVAL - RETINSTR(mov,pc, lr) + mov pc, lr #else str r5, [sp, #4] b do_mmap2 diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index adf62e5eaad..2af7e44218a 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S @@ -39,7 +39,7 @@ __INIT .type stext, %function ENTRY(stext) - msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC @ ensure svc mode + msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode @ and irqs disabled mrc p15, 0, r9, c0, c0 @ get processor id bl __lookup_processor_type @ r5=procinfo r9=cpuid diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 04f7344e356..330b9476c39 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -71,7 +71,7 @@ __INIT .type stext, %function ENTRY(stext) - msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC @ ensure svc mode + msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode @ and irqs disabled mrc p15, 0, r9, c0, c0 @ get processor id bl __lookup_processor_type @ r5=procinfo r9=cpuid @@ -104,7 +104,7 @@ ENTRY(secondary_startup) * the processor type - there is no need to check the machine type * as it has already been validated by the primary processor. */ - msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC + msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE mrc p15, 0, r9, c0, c0 @ get processor id bl __lookup_processor_type movs r10, r5 @ invalid processor? diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index a1d1b2906e8..c40bdc77005 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -634,6 +634,32 @@ static int ptrace_setwmmxregs(struct task_struct *tsk, void __user *ufp) #endif +#ifdef CONFIG_CRUNCH +/* + * Get the child Crunch state. + */ +static int ptrace_getcrunchregs(struct task_struct *tsk, void __user *ufp) +{ + struct thread_info *thread = task_thread_info(tsk); + + crunch_task_disable(thread); /* force it to ram */ + return copy_to_user(ufp, &thread->crunchstate, CRUNCH_SIZE) + ? -EFAULT : 0; +} + +/* + * Set the child Crunch state. + */ +static int ptrace_setcrunchregs(struct task_struct *tsk, void __user *ufp) +{ + struct thread_info *thread = task_thread_info(tsk); + + crunch_task_release(thread); /* force a reload */ + return copy_from_user(&thread->crunchstate, ufp, CRUNCH_SIZE) + ? -EFAULT : 0; +} +#endif + long arch_ptrace(struct task_struct *child, long request, long addr, long data) { unsigned long tmp; @@ -765,6 +791,16 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) child->ptrace_message = data; break; +#ifdef CONFIG_CRUNCH + case PTRACE_GETCRUNCHREGS: + ret = ptrace_getcrunchregs(child, (void __user *)data); + break; + + case PTRACE_SETCRUNCHREGS: + ret = ptrace_setcrunchregs(child, (void __user *)data); + break; +#endif + default: ret = ptrace_request(child, request, addr, data); break; diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 9fc9af88c60..6bdf70def01 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -119,9 +119,24 @@ DEFINE_PER_CPU(struct cpuinfo_arm, cpu_data); * Standard memory resources */ static struct resource mem_res[] = { - { "Video RAM", 0, 0, IORESOURCE_MEM }, - { "Kernel text", 0, 0, IORESOURCE_MEM }, - { "Kernel data", 0, 0, IORESOURCE_MEM } + { + .name = "Video RAM", + .start = 0, + .end = 0, + .flags = IORESOURCE_MEM + }, + { + .name = "Kernel text", + .start = 0, + .end = 0, + .flags = IORESOURCE_MEM + }, + { + .name = "Kernel data", + .start = 0, + .end = 0, + .flags = IORESOURCE_MEM + } }; #define video_ram mem_res[0] @@ -129,9 +144,24 @@ static struct resource mem_res[] = { #define kernel_data mem_res[2] static struct resource io_res[] = { - { "reserved", 0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY }, - { "reserved", 0x378, 0x37f, IORESOURCE_IO | IORESOURCE_BUSY }, - { "reserved", 0x278, 0x27f, IORESOURCE_IO | IORESOURCE_BUSY } + { + .name = "reserved", + .start = 0x3bc, + .end = 0x3be, + .flags = IORESOURCE_IO | IORESOURCE_BUSY + }, + { + .name = "reserved", + .start = 0x378, + .end = 0x37f, + .flags = IORESOURCE_IO | IORESOURCE_BUSY + }, + { + .name = "reserved", + .start = 0x278, + .end = 0x27f, + .flags = IORESOURCE_IO | IORESOURCE_BUSY + } }; #define lp0 io_res[0] @@ -808,7 +838,7 @@ static int __init topology_init(void) int cpu; for_each_possible_cpu(cpu) - register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu, NULL); + register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu); return 0; } diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 1ce05ec086c..83a8d3c95eb 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -132,6 +132,37 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, return ret; } +#ifdef CONFIG_CRUNCH +static int preserve_crunch_context(struct crunch_sigframe *frame) +{ + char kbuf[sizeof(*frame) + 8]; + struct crunch_sigframe *kframe; + + /* the crunch context must be 64 bit aligned */ + kframe = (struct crunch_sigframe *)((unsigned long)(kbuf + 8) & ~7); + kframe->magic = CRUNCH_MAGIC; + kframe->size = CRUNCH_STORAGE_SIZE; + crunch_task_copy(current_thread_info(), &kframe->storage); + return __copy_to_user(frame, kframe, sizeof(*frame)); +} + +static int restore_crunch_context(struct crunch_sigframe *frame) +{ + char kbuf[sizeof(*frame) + 8]; + struct crunch_sigframe *kframe; + + /* the crunch context must be 64 bit aligned */ + kframe = (struct crunch_sigframe *)((unsigned long)(kbuf + 8) & ~7); + if (__copy_from_user(kframe, frame, sizeof(*frame))) + return -1; + if (kframe->magic != CRUNCH_MAGIC || + kframe->size != CRUNCH_STORAGE_SIZE) + return -1; + crunch_task_restore(current_thread_info(), &kframe->storage); + return 0; +} +#endif + #ifdef CONFIG_IWMMXT static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame) @@ -214,6 +245,10 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) err |= !valid_user_regs(regs); aux = (struct aux_sigframe __user *) sf->uc.uc_regspace; +#ifdef CONFIG_CRUNCH + if (err == 0) + err |= restore_crunch_context(&aux->crunch); +#endif #ifdef CONFIG_IWMMXT if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) err |= restore_iwmmxt_context(&aux->iwmmxt); @@ -333,6 +368,10 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set) err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); aux = (struct aux_sigframe __user *) sf->uc.uc_regspace; +#ifdef CONFIG_CRUNCH + if (err == 0) + err |= preserve_crunch_context(&aux->crunch); +#endif #ifdef CONFIG_IWMMXT if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) err |= preserve_iwmmxt_context(&aux->iwmmxt); diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 2b254e88595..2df9688a702 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -80,6 +80,10 @@ SECTIONS *(.exit.text) *(.exit.data) *(.exitcall.exit) +#ifndef CONFIG_MMU + *(.fixup) + *(__ex_table) +#endif } .text : { /* Real text segment */ @@ -87,7 +91,9 @@ SECTIONS *(.text) SCHED_TEXT LOCK_TEXT +#ifdef CONFIG_MMU *(.fixup) +#endif *(.gnu.warning) *(.rodata) *(.rodata.*) @@ -142,7 +148,9 @@ SECTIONS */ . = ALIGN(32); __start___ex_table = .; +#ifdef CONFIG_MMU *(__ex_table) +#endif __stop___ex_table = .; /* diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 7b726b627ea..30351cd4560 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -6,28 +6,31 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ csumpartialcopy.o csumpartialcopyuser.o clearbit.o \ - copy_page.o delay.o findbit.o memchr.o memcpy.o \ + delay.o findbit.o memchr.o memcpy.o \ memmove.o memset.o memzero.o setbit.o \ strncpy_from_user.o strnlen_user.o \ strchr.o strrchr.o \ testchangebit.o testclearbit.o testsetbit.o \ - getuser.o putuser.o clear_user.o \ ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ ucmpdi2.o lib1funcs.o div64.o sha1.o \ io-readsb.o io-writesb.o io-readsl.o io-writesl.o +mmu-y := clear_user.o copy_page.o getuser.o putuser.o + # the code in uaccess.S is not preemption safe and # probably faster on ARMv3 only ifeq ($(CONFIG_PREEMPT),y) - lib-y += copy_from_user.o copy_to_user.o + mmu-y += copy_from_user.o copy_to_user.o else ifneq ($(CONFIG_CPU_32v3),y) - lib-y += copy_from_user.o copy_to_user.o + mmu-y += copy_from_user.o copy_to_user.o else - lib-y += uaccess.o + mmu-y += uaccess.o endif endif +lib-$(CONFIG_MMU) += $(mmu-y) + ifeq ($(CONFIG_CPU_32v3),y) lib-y += io-readsw-armv3.o io-writesw-armv3.o else diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S index 16153c86c3f..91f993f2e9d 100644 --- a/arch/arm/lib/backtrace.S +++ b/arch/arm/lib/backtrace.S @@ -41,7 +41,7 @@ ENTRY(c_backtrace) movne r0, #0 movs frame, r0 1: moveq r0, #-2 - LOADREGS(eqfd, sp!, {r4 - r8, pc}) + ldmeqfd sp!, {r4 - r8, pc} 2: stmfd sp!, {pc} @ calculate offset of PC in STMIA instruction ldr r0, [sp], #4 @@ -85,7 +85,7 @@ ENTRY(c_backtrace) * A zero next framepointer means we're done. */ teq next, #0 - LOADREGS(eqfd, sp!, {r4 - r8, pc}) + ldmeqfd sp!, {r4 - r8, pc} /* * The next framepointer must be above the @@ -97,16 +97,13 @@ ENTRY(c_backtrace) b 1007f /* - * Fixup for LDMDB + * Fixup for LDMDB. Note that this must not be in the fixup section. */ - .section .fixup,"ax" - .align 0 1007: ldr r0, =.Lbad mov r1, frame bl printk - LOADREGS(fd, sp!, {r4 - r8, pc}) + ldmfd sp!, {r4 - r8, pc} .ltorg - .previous .section __ex_table,"a" .align 3 @@ -145,7 +142,7 @@ ENTRY(c_backtrace) adrne r0, .Lcr blne printk mov r0, stack - LOADREGS(fd, sp!, {instr, reg, stack, r7, r8, pc}) + ldmfd sp!, {instr, reg, stack, r7, r8, pc} .Lfp: .asciz " r%d = %08X%c" .Lcr: .asciz "\n" diff --git a/arch/arm/lib/clear_user.S b/arch/arm/lib/clear_user.S index 7ff9f831b3f..ecb28dcdaf7 100644 --- a/arch/arm/lib/clear_user.S +++ b/arch/arm/lib/clear_user.S @@ -12,13 +12,13 @@ .text -/* Prototype: int __arch_clear_user(void *addr, size_t sz) +/* Prototype: int __clear_user(void *addr, size_t sz) * Purpose : clear some user memory * Params : addr - user memory address to clear * : sz - number of bytes to clear * Returns : number of bytes NOT cleared */ -ENTRY(__arch_clear_user) +ENTRY(__clear_user) stmfd sp!, {r1, lr} mov r2, #0 cmp r1, #4 @@ -43,10 +43,10 @@ USER( strnebt r2, [r0], #1) tst r1, #1 @ x1 x0 x1 x0 x1 x0 x1 USER( strnebt r2, [r0], #1) mov r0, #0 - LOADREGS(fd,sp!, {r1, pc}) + ldmfd sp!, {r1, pc} .section .fixup,"ax" .align 0 -9001: LOADREGS(fd,sp!, {r0, pc}) +9001: ldmfd sp!, {r0, pc} .previous diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S index 7497393a0e8..6b7363ce749 100644 --- a/arch/arm/lib/copy_from_user.S +++ b/arch/arm/lib/copy_from_user.S @@ -16,7 +16,7 @@ /* * Prototype: * - * size_t __arch_copy_from_user(void *to, const void *from, size_t n) + * size_t __copy_from_user(void *to, const void *from, size_t n) * * Purpose: * @@ -83,7 +83,7 @@ .text -ENTRY(__arch_copy_from_user) +ENTRY(__copy_from_user) #include "copy_template.S" diff --git a/arch/arm/lib/copy_page.S b/arch/arm/lib/copy_page.S index 68117968482..666c99cc074 100644 --- a/arch/arm/lib/copy_page.S +++ b/arch/arm/lib/copy_page.S @@ -43,4 +43,4 @@ ENTRY(copy_page) bgt 1b @ 1 PLD( ldmeqia r1!, {r3, r4, ip, lr} ) PLD( beq 2b ) - LOADREGS(fd, sp!, {r4, pc}) @ 3 + ldmfd sp!, {r4, pc} @ 3 diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S index 4a6d8ea1402..5224d94688d 100644 --- a/arch/arm/lib/copy_to_user.S +++ b/arch/arm/lib/copy_to_user.S @@ -16,7 +16,7 @@ /* * Prototype: * - * size_t __arch_copy_to_user(void *to, const void *from, size_t n) + * size_t __copy_to_user(void *to, const void *from, size_t n) * * Purpose: * @@ -86,7 +86,7 @@ .text -ENTRY(__arch_copy_to_user) +ENTRY(__copy_to_user) #include "copy_template.S" diff --git a/arch/arm/lib/csumipv6.S b/arch/arm/lib/csumipv6.S index 7065a20ee8a..9621469beec 100644 --- a/arch/arm/lib/csumipv6.S +++ b/arch/arm/lib/csumipv6.S @@ -28,5 +28,5 @@ ENTRY(__csum_ipv6_magic) adcs r0, r0, r3 adcs r0, r0, r2 adcs r0, r0, #0 - LOADREGS(fd, sp!, {pc}) + ldmfd sp!, {pc} diff --git a/arch/arm/lib/delay.S b/arch/arm/lib/delay.S index 9183b06c0e2..930a7025922 100644 --- a/arch/arm/lib/delay.S +++ b/arch/arm/lib/delay.S @@ -31,7 +31,7 @@ ENTRY(__const_udelay) @ 0 <= r0 <= 0x7fffff06 mov r2, r2, lsr #10 @ max = 0x00007fff mul r0, r2, r0 @ max = 2^32-1 movs r0, r0, lsr #6 - RETINSTR(moveq,pc,lr) + moveq pc, lr /* * loops = r0 * HZ * loops_per_jiffy / 1000000 @@ -43,20 +43,20 @@ ENTRY(__const_udelay) @ 0 <= r0 <= 0x7fffff06 ENTRY(__delay) subs r0, r0, #1 #if 0 - RETINSTR(movls,pc,lr) + movls pc, lr subs r0, r0, #1 - RETINSTR(movls,pc,lr) + movls pc, lr subs r0, r0, #1 - RETINSTR(movls,pc,lr) + movls pc, lr subs r0, r0, #1 - RETINSTR(movls,pc,lr) + movls pc, lr subs r0, r0, #1 - RETINSTR(movls,pc,lr) + movls pc, lr subs r0, r0, #1 - RETINSTR(movls,pc,lr) + movls pc, lr subs r0, r0, #1 - RETINSTR(movls,pc,lr) + movls pc, lr subs r0, r0, #1 #endif bhi __delay - RETINSTR(mov,pc,lr) + mov pc, lr diff --git a/arch/arm/lib/ecard.S b/arch/arm/lib/ecard.S index fb7b602a6f7..c55aaa2a208 100644 --- a/arch/arm/lib/ecard.S +++ b/arch/arm/lib/ecard.S @@ -29,7 +29,7 @@ ENTRY(ecard_loader_read) CPSR2SPSR(r0) mov lr, pc mov pc, r2 - LOADREGS(fd, sp!, {r4 - r12, pc}) + ldmfd sp!, {r4 - r12, pc} @ Purpose: call an expansion card loader to reset the card @ Proto : void read_loader(int card_base, char *loader); @@ -41,5 +41,5 @@ ENTRY(ecard_loader_reset) CPSR2SPSR(r0) mov lr, pc add pc, r1, #8 - LOADREGS(fd, sp!, {r4 - r12, pc}) + ldmfd sp!, {r4 - r12, pc} diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib/findbit.S index 6f8e27a58c7..a5ca0248aa4 100644 --- a/arch/arm/lib/findbit.S +++ b/arch/arm/lib/findbit.S @@ -32,7 +32,7 @@ ENTRY(_find_first_zero_bit_le) 2: cmp r2, r1 @ any more? blo 1b 3: mov r0, r1 @ no free bits - RETINSTR(mov,pc,lr) + mov pc, lr /* * Purpose : Find next 'zero' bit @@ -66,7 +66,7 @@ ENTRY(_find_first_bit_le) 2: cmp r2, r1 @ any more? blo 1b 3: mov r0, r1 @ no free bits - RETINSTR(mov,pc,lr) + mov pc, lr /* * Purpose : Find next 'one' bit @@ -98,7 +98,7 @@ ENTRY(_find_first_zero_bit_be) 2: cmp r2, r1 @ any more? blo 1b 3: mov r0, r1 @ no free bits - RETINSTR(mov,pc,lr) + mov pc, lr ENTRY(_find_next_zero_bit_be) teq r1, #0 @@ -126,7 +126,7 @@ ENTRY(_find_first_bit_be) 2: cmp r2, r1 @ any more? blo 1b 3: mov r0, r1 @ no free bits - RETINSTR(mov,pc,lr) + mov pc, lr ENTRY(_find_next_bit_be) teq r1, #0 @@ -164,5 +164,5 @@ ENTRY(_find_next_bit_be) addeq r2, r2, #1 mov r0, r2 #endif - RETINSTR(mov,pc,lr) + mov pc, lr diff --git a/arch/arm/lib/io-readsb.S b/arch/arm/lib/io-readsb.S index d3d8de71a2c..fb966ad0276 100644 --- a/arch/arm/lib/io-readsb.S +++ b/arch/arm/lib/io-readsb.S @@ -72,7 +72,7 @@ ENTRY(__raw_readsb) bpl .Linsb_16_lp tst r2, #15 - LOADREGS(eqfd, sp!, {r4 - r6, pc}) + ldmeqfd sp!, {r4 - r6, pc} .Linsb_no_16: tst r2, #8 beq .Linsb_no_8 @@ -109,7 +109,7 @@ ENTRY(__raw_readsb) str r3, [r1], #4 .Linsb_no_4: ands r2, r2, #3 - LOADREGS(eqfd, sp!, {r4 - r6, pc}) + ldmeqfd sp!, {r4 - r6, pc} cmp r2, #2 ldrb r3, [r0] @@ -119,4 +119,4 @@ ENTRY(__raw_readsb) ldrgtb r3, [r0] strgtb r3, [r1] - LOADREGS(fd, sp!, {r4 - r6, pc}) + ldmfd sp!, {r4 - r6, pc} diff --git a/arch/arm/lib/io-readsw-armv3.S b/arch/arm/lib/io-readsw-armv3.S index 146d47c1545..4ef90418514 100644 --- a/arch/arm/lib/io-readsw-armv3.S +++ b/arch/arm/lib/io-readsw-armv3.S @@ -28,7 +28,7 @@ strb r3, [r1], #1 subs r2, r2, #1 - RETINSTR(moveq, pc, lr) + moveq pc, lr ENTRY(__raw_readsw) teq r2, #0 @ do we have to check for the zero len? @@ -69,7 +69,7 @@ ENTRY(__raw_readsw) bpl .Linsw_8_lp tst r2, #7 - LOADREGS(eqfd, sp!, {r4, r5, r6, pc}) + ldmeqfd sp!, {r4, r5, r6, pc} .Lno_insw_8: tst r2, #4 beq .Lno_insw_4 @@ -102,6 +102,6 @@ ENTRY(__raw_readsw) movne r3, r3, lsr #8 strneb r3, [r1] - LOADREGS(fd, sp!, {r4, r5, r6, pc}) + ldmfd sp!, {r4, r5, r6, pc} diff --git a/arch/arm/lib/io-writesb.S b/arch/arm/lib/io-writesb.S index 08209fc640e..7eba2b6cc69 100644 --- a/arch/arm/lib/io-writesb.S +++ b/arch/arm/lib/io-writesb.S @@ -64,7 +64,7 @@ ENTRY(__raw_writesb) bpl .Loutsb_16_lp tst r2, #15 - LOADREGS(eqfd, sp!, {r4, r5, pc}) + ldmeqfd sp!, {r4, r5, pc} .Loutsb_no_16: tst r2, #8 beq .Loutsb_no_8 @@ -80,7 +80,7 @@ ENTRY(__raw_writesb) outword r3 .Loutsb_no_4: ands r2, r2, #3 - LOADREGS(eqfd, sp!, {r4, r5, pc}) + ldmeqfd sp!, {r4, r5, pc} cmp r2, #2 ldrb r3, [r1], #1 @@ -90,4 +90,4 @@ ENTRY(__raw_writesb) ldrgtb r3, [r1] strgtb r3, [r0] - LOADREGS(fd, sp!, {r4, r5, pc}) + ldmfd sp!, {r4, r5, pc} diff --git a/arch/arm/lib/io-writesw-armv3.S b/arch/arm/lib/io-writesw-armv3.S index 52d62b48129..1607a29f49b 100644 --- a/arch/arm/lib/io-writesw-armv3.S +++ b/arch/arm/lib/io-writesw-armv3.S @@ -29,7 +29,7 @@ orr r3, r3, r3, lsl #16 str r3, [r0] subs r2, r2, #1 - RETINSTR(moveq, pc, lr) + moveq pc, lr ENTRY(__raw_writesw) teq r2, #0 @ do we have to check for the zero len? @@ -80,7 +80,7 @@ ENTRY(__raw_writesw) bpl .Loutsw_8_lp tst r2, #7 - LOADREGS(eqfd, sp!, {r4, r5, r6, pc}) + ldmeqfd sp!, {r4, r5, r6, pc} .Lno_outsw_8: tst r2, #4 beq .Lno_outsw_4 @@ -124,4 +124,4 @@ ENTRY(__raw_writesw) orrne ip, ip, ip, lsr #16 strne ip, [r0] - LOADREGS(fd, sp!, {r4, r5, r6, pc}) + ldmfd sp!, {r4, r5, r6, pc} diff --git a/arch/arm/lib/memchr.S b/arch/arm/lib/memchr.S index ac34fe55d21..e7ab1ea8eba 100644 --- a/arch/arm/lib/memchr.S +++ b/arch/arm/lib/memchr.S @@ -22,4 +22,4 @@ ENTRY(memchr) bne 1b sub r0, r0, #1 2: movne r0, #0 - RETINSTR(mov,pc,lr) + mov pc, lr diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S index a1795f59993..95b110b07a8 100644 --- a/arch/arm/lib/memset.S +++ b/arch/arm/lib/memset.S @@ -53,7 +53,7 @@ ENTRY(memset) stmgeia r0!, {r1, r3, ip, lr} stmgeia r0!, {r1, r3, ip, lr} bgt 2b - LOADREGS(eqfd, sp!, {pc}) @ Now <64 bytes to go. + ldmeqfd sp!, {pc} @ Now <64 bytes to go. /* * No need to correct the count; we're only testing bits from now on */ @@ -77,4 +77,4 @@ ENTRY(memset) strneb r1, [r0], #1 tst r2, #1 strneb r1, [r0], #1 - RETINSTR(mov,pc,lr) + mov pc, lr diff --git a/arch/arm/lib/memzero.S b/arch/arm/lib/memzero.S index 51ccc60160f..abf2508e822 100644 --- a/arch/arm/lib/memzero.S +++ b/arch/arm/lib/memzero.S @@ -53,7 +53,7 @@ ENTRY(__memzero) stmgeia r0!, {r2, r3, ip, lr} @ 4 stmgeia r0!, {r2, r3, ip, lr} @ 4 bgt 3b @ 1 - LOADREGS(eqfd, sp!, {pc}) @ 1/2 quick exit + ldmeqfd sp!, {pc} @ 1/2 quick exit /* * No need to correct the count; we're only testing bits from now on */ @@ -77,4 +77,4 @@ ENTRY(__memzero) strneb r2, [r0], #1 @ 1 tst r1, #1 @ 1 a byte left over strneb r2, [r0], #1 @ 1 - RETINSTR(mov,pc,lr) @ 1 + mov pc, lr @ 1 diff --git a/arch/arm/lib/strchr.S b/arch/arm/lib/strchr.S index 5b9b493733f..9f18d6fdee6 100644 --- a/arch/arm/lib/strchr.S +++ b/arch/arm/lib/strchr.S @@ -23,4 +23,4 @@ ENTRY(strchr) teq r2, r1 movne r0, #0 subeq r0, r0, #1 - RETINSTR(mov,pc,lr) + mov pc, lr diff --git a/arch/arm/lib/strncpy_from_user.S b/arch/arm/lib/strncpy_from_user.S index 629cc877527..36e3741a377 100644 --- a/arch/arm/lib/strncpy_from_user.S +++ b/arch/arm/lib/strncpy_from_user.S @@ -20,8 +20,7 @@ * returns the number of characters copied (strlen of copied string), * -EFAULT on exception, or "len" if we fill the whole buffer */ -ENTRY(__arch_strncpy_from_user) - save_lr +ENTRY(__strncpy_from_user) mov ip, r1 1: subs r2, r2, #1 USER( ldrplbt r3, [r1], #1) @@ -31,13 +30,13 @@ USER( ldrplbt r3, [r1], #1) bne 1b sub r1, r1, #1 @ take NUL character out of count 2: sub r0, r1, ip - restore_pc + mov pc, lr .section .fixup,"ax" .align 0 9001: mov r3, #0 strb r3, [r0, #0] @ null terminate mov r0, #-EFAULT - restore_pc + mov pc, lr .previous diff --git a/arch/arm/lib/strnlen_user.S b/arch/arm/lib/strnlen_user.S index 67bcd826812..18d8fa4f925 100644 --- a/arch/arm/lib/strnlen_user.S +++ b/arch/arm/lib/strnlen_user.S @@ -14,14 +14,13 @@ .text .align 5 -/* Prototype: unsigned long __arch_strnlen_user(const char *str, long n) +/* Prototype: unsigned long __strnlen_user(const char *str, long n) * Purpose : get length of a string in user memory * Params : str - address of string in user memory * Returns : length of string *including terminator* * or zero on exception, or n + 1 if too long */ -ENTRY(__arch_strnlen_user) - save_lr +ENTRY(__strnlen_user) mov r2, r0 1: USER( ldrbt r3, [r0], #1) @@ -31,10 +30,10 @@ USER( ldrbt r3, [r0], #1) bne 1b add r0, r0, #1 2: sub r0, r0, r2 - restore_pc + mov pc, lr .section .fixup,"ax" .align 0 9001: mov r0, #0 - restore_pc + mov pc, lr .previous diff --git a/arch/arm/lib/strrchr.S b/arch/arm/lib/strrchr.S index fa923f026f1..538df220aa4 100644 --- a/arch/arm/lib/strrchr.S +++ b/arch/arm/lib/strrchr.S @@ -22,4 +22,4 @@ ENTRY(strrchr) teq r2, #0 bne 1b mov r0, r3 - RETINSTR(mov,pc,lr) + mov pc, lr diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S index 0cc450f863b..b48bd6d5fd8 100644 --- a/arch/arm/lib/uaccess.S +++ b/arch/arm/lib/uaccess.S @@ -19,7 +19,7 @@ #define PAGE_SHIFT 12 -/* Prototype: int __arch_copy_to_user(void *to, const char *from, size_t n) +/* Prototype: int __copy_to_user(void *to, const char *from, size_t n) * Purpose : copy a block to user memory from kernel memory * Params : to - user memory * : from - kernel memory @@ -39,7 +39,7 @@ USER( strgtbt r3, [r0], #1) @ May fault sub r2, r2, ip b .Lc2u_dest_aligned -ENTRY(__arch_copy_to_user) +ENTRY(__copy_to_user) stmfd sp!, {r2, r4 - r7, lr} cmp r2, #4 blt .Lc2u_not_enough @@ -105,7 +105,7 @@ USER( strgtbt r3, [r0], #1) @ May fault movs ip, r2 bne .Lc2u_nowords .Lc2u_finished: mov r0, #0 - LOADREGS(fd,sp!,{r2, r4 - r7, pc}) + ldmfd sp!, {r2, r4 - r7, pc} .Lc2u_src_not_aligned: bic r1, r1, #3 @@ -280,10 +280,10 @@ USER( strgtbt r3, [r0], #1) @ May fault .section .fixup,"ax" .align 0 -9001: LOADREGS(fd,sp!, {r0, r4 - r7, pc}) +9001: ldmfd sp!, {r0, r4 - r7, pc} .previous -/* Prototype: unsigned long __arch_copy_from_user(void *to,const void *from,unsigned long n); +/* Prototype: unsigned long __copy_from_user(void *to,const void *from,unsigned long n); * Purpose : copy a block from user memory to kernel memory * Params : to - kernel memory * : from - user memory @@ -302,7 +302,7 @@ USER( ldrgtbt r3, [r1], #1) @ May fault sub r2, r2, ip b .Lcfu_dest_aligned -ENTRY(__arch_copy_from_user) +ENTRY(__copy_from_user) stmfd sp!, {r0, r2, r4 - r7, lr} cmp r2, #4 blt .Lcfu_not_enough @@ -369,7 +369,7 @@ USER( ldrgtbt r3, [r1], #1) @ May fault bne .Lcfu_nowords .Lcfu_finished: mov r0, #0 add sp, sp, #8 - LOADREGS(fd,sp!,{r4 - r7, pc}) + ldmfd sp!, {r4 - r7, pc} .Lcfu_src_not_aligned: bic r1, r1, #3 @@ -556,6 +556,6 @@ USER( ldrgtbt r3, [r1], #1) @ May fault movne r1, r4 blne __memzero mov r0, r4 - LOADREGS(fd,sp!, {r4 - r7, pc}) + ldmfd sp!, {r4 - r7, pc} .previous diff --git a/arch/arm/mach-at91rm9200/Kconfig b/arch/arm/mach-at91rm9200/Kconfig index 1ab5b782831..70d402f76ce 100644 --- a/arch/arm/mach-at91rm9200/Kconfig +++ b/arch/arm/mach-at91rm9200/Kconfig @@ -4,6 +4,12 @@ menu "AT91RM9200 Implementations" comment "AT91RM9200 Board Type" +config MACH_ONEARM + bool "Ajeco 1ARM Single Board Computer" + depends on ARCH_AT91RM9200 + help + Select this if you are using Ajeco's 1ARM Single Board Computer + config ARCH_AT91RM9200DK bool "Atmel AT91RM9200-DK Development board" depends on ARCH_AT91RM9200 diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91rm9200/Makefile index 81ebc6684ad..82db957322d 100644 --- a/arch/arm/mach-at91rm9200/Makefile +++ b/arch/arm/mach-at91rm9200/Makefile @@ -10,6 +10,7 @@ obj- := obj-$(CONFIG_PM) += pm.o # Board-specific support +obj-$(CONFIG_MACH_ONEARM) += board-1arm.o obj-$(CONFIG_ARCH_AT91RM9200DK) += board-dk.o obj-$(CONFIG_MACH_AT91RM9200EK) += board-ek.o obj-$(CONFIG_MACH_CSB337) += board-csb337.o diff --git a/arch/arm/mach-at91rm9200/board-1arm.c b/arch/arm/mach-at91rm9200/board-1arm.c new file mode 100644 index 00000000000..dc79e0992af --- /dev/null +++ b/arch/arm/mach-at91rm9200/board-1arm.c @@ -0,0 +1,109 @@ +/* + * linux/arch/arm/mach-at91rm9200/board-1arm.c + * + * Copyright (C) 2005 SAN People + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/config.h> +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <asm/hardware.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <asm/hardware.h> +#include <asm/arch/board.h> +#include <asm/arch/gpio.h> + +#include "generic.h" + +static void __init onearm_init_irq(void) +{ + /* Initialize AIC controller */ + at91rm9200_init_irq(NULL); + + /* Set up the GPIO interrupts */ + at91_gpio_irq_setup(PQFP_GPIO_BANKS); +} + +/* + * Serial port configuration. + * 0 .. 3 = USART0 .. USART3 + * 4 = DBGU + */ +static struct at91_uart_config __initdata onearm_uart_config = { + .console_tty = 0, /* ttyS0 */ + .nr_tty = 3, + .tty_map = { 4, 0, 1, -1, -1 }, /* ttyS0, ..., ttyS4 */ +}; + +static void __init onearm_map_io(void) +{ + at91rm9200_map_io(); + + /* Initialize clocks: 18.432 MHz crystal */ + at91_clock_init(18432000); + + /* Setup the serial ports and console */ + at91_init_serial(&onearm_uart_config); +} + +static struct at91_eth_data __initdata onearm_eth_data = { + .phy_irq_pin = AT91_PIN_PC4, + .is_rmii = 1, +}; + +static struct at91_usbh_data __initdata onearm_usbh_data = { + .ports = 1, +}; + +static struct at91_udc_data __initdata onearm_udc_data = { + .vbus_pin = AT91_PIN_PC2, + .pullup_pin = AT91_PIN_PC3, +}; + +static void __init onearm_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* Ethernet */ + at91_add_device_eth(&onearm_eth_data); + /* USB Host */ + at91_add_device_usbh(&onearm_usbh_data); + /* USB Device */ + at91_add_device_udc(&onearm_udc_data); +} + +MACHINE_START(ONEARM, "Ajeco 1ARM single board computer") + /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ + .phys_io = AT91_BASE_SYS, + .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, + .boot_params = AT91_SDRAM_BASE + 0x100, + .timer = &at91rm9200_timer, + .map_io = onearm_map_io, + .init_irq = onearm_init_irq, + .init_machine = onearm_board_init, +MACHINE_END diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig index cec5a21ca4e..e15e4c54a25 100644 --- a/arch/arm/mach-ep93xx/Kconfig +++ b/arch/arm/mach-ep93xx/Kconfig @@ -2,8 +2,19 @@ if ARCH_EP93XX menu "Cirrus EP93xx Implementation Options" +config CRUNCH + bool "Support for MaverickCrunch" + help + Enable kernel support for MaverickCrunch. + comment "EP93xx Platforms" +config MACH_EDB9315 + bool "Support Cirrus Logic EDB9315" + help + Say 'Y' here if you want your kernel to support the Cirrus + Logic EDB9315 Evaluation Board. + config MACH_GESBC9312 bool "Support Glomation GESBC-9312-sx" help diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile index 05a48a21038..dfa7e2e8a18 100644 --- a/arch/arm/mach-ep93xx/Makefile +++ b/arch/arm/mach-ep93xx/Makefile @@ -6,5 +6,6 @@ obj-m := obj-n := obj- := +obj-$(CONFIG_MACH_EDB9315) += edb9315.o obj-$(CONFIG_MACH_GESBC9312) += gesbc9312.o obj-$(CONFIG_MACH_TS72XX) += ts72xx.o diff --git a/arch/arm/mach-ep93xx/edb9315.c b/arch/arm/mach-ep93xx/edb9315.c new file mode 100644 index 00000000000..ef7482faad8 --- /dev/null +++ b/arch/arm/mach-ep93xx/edb9315.c @@ -0,0 +1,62 @@ +/* + * arch/arm/mach-ep93xx/edb9315.c + * Cirrus Logic EDB9315 support. + * + * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.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. + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/mtd/physmap.h> +#include <linux/platform_device.h> +#include <asm/io.h> +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +static struct physmap_flash_data edb9315_flash_data = { + .width = 4, +}; + +static struct resource edb9315_flash_resource = { + .start = 0x60000000, + .end = 0x61ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device edb9315_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &edb9315_flash_data, + }, + .num_resources = 1, + .resource = &edb9315_flash_resource, +}; + +static void __init edb9315_init_machine(void) +{ + ep93xx_init_devices(); + platform_device_register(&edb9315_flash); +} + +MACHINE_START(EDB9315, "Cirrus Logic EDB9315 Evaluation Board") + /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ + .phys_io = EP93XX_APB_PHYS_BASE, + .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ep93xx_map_io, + .init_irq = ep93xx_init_irq, + .timer = &ep93xx_timer, + .init_machine = edb9315_init_machine, +MACHINE_END diff --git a/arch/arm/mach-ep93xx/gesbc9312.c b/arch/arm/mach-ep93xx/gesbc9312.c index 47cc6c8b7c7..2c28d66d260 100644 --- a/arch/arm/mach-ep93xx/gesbc9312.c +++ b/arch/arm/mach-ep93xx/gesbc9312.c @@ -30,7 +30,7 @@ static struct physmap_flash_data gesbc9312_flash_data = { static struct resource gesbc9312_flash_resource = { .start = 0x60000000, - .end = 0x60800000, + .end = 0x607fffff, .flags = IORESOURCE_MEM, }; diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c index 6e5a56cd5ae..0b3b875b187 100644 --- a/arch/arm/mach-ep93xx/ts72xx.c +++ b/arch/arm/mach-ep93xx/ts72xx.c @@ -118,7 +118,7 @@ static struct physmap_flash_data ts72xx_flash_data = { static struct resource ts72xx_flash_resource = { .start = TS72XX_NOR_PHYS_BASE, - .end = TS72XX_NOR_PHYS_BASE + 0x01000000, + .end = TS72XX_NOR_PHYS_BASE + 0x00ffffff, .flags = IORESOURCE_MEM, }; diff --git a/arch/arm/mach-ixp23xx/espresso.c b/arch/arm/mach-ixp23xx/espresso.c index dc5e489c70b..357351fbb1e 100644 --- a/arch/arm/mach-ixp23xx/espresso.c +++ b/arch/arm/mach-ixp23xx/espresso.c @@ -59,7 +59,7 @@ static struct physmap_flash_data espresso_flash_data = { static struct resource espresso_flash_resource = { .start = 0x90000000, - .end = 0x92000000, + .end = 0x91ffffff, .flags = IORESOURCE_MEM, }; diff --git a/arch/arm/mach-ixp23xx/ixdp2351.c b/arch/arm/mach-ixp23xx/ixdp2351.c index 535b334ee04..e0886871cc7 100644 --- a/arch/arm/mach-ixp23xx/ixdp2351.c +++ b/arch/arm/mach-ixp23xx/ixdp2351.c @@ -304,7 +304,7 @@ static struct physmap_flash_data ixdp2351_flash_data = { static struct resource ixdp2351_flash_resource = { .start = 0x90000000, - .end = 0x94000000, + .end = 0x93ffffff, .flags = IORESOURCE_MEM, }; diff --git a/arch/arm/mach-ixp23xx/roadrunner.c b/arch/arm/mach-ixp23xx/roadrunner.c index b9f5d13fcfe..92ad18f4125 100644 --- a/arch/arm/mach-ixp23xx/roadrunner.c +++ b/arch/arm/mach-ixp23xx/roadrunner.c @@ -143,7 +143,7 @@ static struct physmap_flash_data roadrunner_flash_data = { static struct resource roadrunner_flash_resource = { .start = 0x90000000, - .end = 0x94000000, + .end = 0x93ffffff, .flags = IORESOURCE_MEM, }; diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig index 3b23f43cb16..57f23b46539 100644 --- a/arch/arm/mach-ixp4xx/Kconfig +++ b/arch/arm/mach-ixp4xx/Kconfig @@ -35,7 +35,6 @@ config ARCH_ADI_COYOTE config ARCH_IXDP425 bool "IXDP425" - select PCI help Say 'Y' here if you want your kernel to support Intel's IXDP425 Development Platform (Also known as Richfield). @@ -43,7 +42,6 @@ config ARCH_IXDP425 config MACH_IXDPG425 bool "IXDPG425" - select PCI help Say 'Y' here if you want your kernel to support Intel's IXDPG425 Development Platform (Also known as Montajade). @@ -51,7 +49,6 @@ config MACH_IXDPG425 config MACH_IXDP465 bool "IXDP465" - select PCI help Say 'Y' here if you want your kernel to support Intel's IXDP465 Development Platform (Also known as BMP). diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile index 5a4aaa0e0a0..640315d8b96 100644 --- a/arch/arm/mach-ixp4xx/Makefile +++ b/arch/arm/mach-ixp4xx/Makefile @@ -2,13 +2,23 @@ # Makefile for the linux kernel. # +obj-pci-y := +obj-pci-n := + +obj-pci-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o +obj-pci-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o +obj-pci-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o +obj-pci-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o +obj-pci-$(CONFIG_MACH_NSLU2) += nslu2-pci.o +obj-pci-$(CONFIG_MACH_NAS100D) += nas100d-pci.o + obj-y += common.o -obj-$(CONFIG_PCI) += common-pci.o -obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o ixdp425-setup.o -obj-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o coyote-setup.o -obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o coyote-setup.o -obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o gtwx5715-setup.o -obj-$(CONFIG_MACH_NSLU2) += nslu2-pci.o nslu2-setup.o nslu2-power.o -obj-$(CONFIG_MACH_NAS100D) += nas100d-pci.o nas100d-setup.o nas100d-power.o +obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-setup.o +obj-$(CONFIG_MACH_IXDPG425) += coyote-setup.o +obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-setup.o +obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-setup.o +obj-$(CONFIG_MACH_NSLU2) += nslu2-setup.o nslu2-power.o +obj-$(CONFIG_MACH_NAS100D) += nas100d-setup.o nas100d-power.o +obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index 539b596005f..d9635ff4b10 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -88,8 +88,8 @@ static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) if (type == IRQT_PROBE) { /* Don't mess with enabled GPIOs using preconfigured edges or - GPIOs set to alternate function during probe */ - if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx]) & + GPIOs set to alternate function or to output during probe */ + if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx] | GPDR(gpio)) & GPIO_bit(gpio)) return 0; if (GAFR(gpio) & (0x3 << (((gpio) & 0xf)*2))) diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S index c9862688ff3..0650bed3b96 100644 --- a/arch/arm/mach-pxa/sleep.S +++ b/arch/arm/mach-pxa/sleep.S @@ -189,7 +189,7 @@ ENTRY(pxa_cpu_suspend) .data .align 5 ENTRY(pxa_cpu_resume) - mov r0, #PSR_I_BIT | PSR_F_BIT | MODE_SVC @ set SVC, irqs off + mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off msr cpsr_c, r0 ldr r0, sleep_save_sp @ stack phys addr diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index f5d9cd498a5..b4171dd43df 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -71,13 +71,13 @@ config ARCH_S3C2440 Say Y here if you are using the SMDK2440. config SMDK2440_CPU2440 - bool "SMDK2440 with S3C2440 cpu module" + bool "SMDK2440 with S3C2440 CPU module" depends on ARCH_S3C2440 default y if ARCH_S3C2440 select CPU_S3C2440 config SMDK2440_CPU2442 - bool "SMDM2440 with S3C2442 cpu module" + bool "SMDM2440 with S3C2442 CPU module" depends on ARCH_S3C2440 select CPU_S3C2442 diff --git a/arch/arm/mach-s3c2410/s3c244x.c b/arch/arm/mach-s3c2410/s3c244x.c index 838bc525e83..9a2258270de 100644 --- a/arch/arm/mach-s3c2410/s3c244x.c +++ b/arch/arm/mach-s3c2410/s3c244x.c @@ -69,6 +69,7 @@ void __init s3c244x_map_io(struct map_desc *mach_desc, int size) s3c_device_i2c.name = "s3c2440-i2c"; s3c_device_nand.name = "s3c2440-nand"; + s3c_device_usbgadget.name = "s3c2440-usbgadget"; } void __init s3c244x_init_clocks(int xtal) diff --git a/arch/arm/mach-s3c2410/sleep.S b/arch/arm/mach-s3c2410/sleep.S index 5f6761ed96b..dc27167f4d5 100644 --- a/arch/arm/mach-s3c2410/sleep.S +++ b/arch/arm/mach-s3c2410/sleep.S @@ -128,7 +128,7 @@ s3c2410_sleep_save_phys: */ ENTRY(s3c2410_cpu_resume) - mov r0, #PSR_I_BIT | PSR_F_BIT | MODE_SVC + mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE msr cpsr_c, r0 @@ load UART to allow us to print the two characters for diff --git a/arch/arm/mach-sa1100/sleep.S b/arch/arm/mach-sa1100/sleep.S index 2fa1e289d17..5a84062f92a 100644 --- a/arch/arm/mach-sa1100/sleep.S +++ b/arch/arm/mach-sa1100/sleep.S @@ -177,7 +177,7 @@ sa1110_sdram_controller_fix: .data .align 5 ENTRY(sa1100_cpu_resume) - mov r0, #PSR_F_BIT | PSR_I_BIT | MODE_SVC + mov r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE msr cpsr_c, r0 @ set SVC, irqs off ldr r0, sleep_save_sp @ stack phys addr diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index ecf5e232a6f..c4bca753165 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -15,8 +15,8 @@ config CPU_ARM610 select CPU_32v3 select CPU_CACHE_V3 select CPU_CACHE_VIVT - select CPU_COPY_V3 - select CPU_TLB_V3 + select CPU_COPY_V3 if MMU + select CPU_TLB_V3 if MMU help The ARM610 is the successor to the ARM3 processor and was produced by VLSI Technology Inc. @@ -31,8 +31,8 @@ config CPU_ARM710 select CPU_32v3 select CPU_CACHE_V3 select CPU_CACHE_VIVT - select CPU_COPY_V3 - select CPU_TLB_V3 + select CPU_COPY_V3 if MMU + select CPU_TLB_V3 if MMU help A 32-bit RISC microprocessor based on the ARM7 processor core designed by Advanced RISC Machines Ltd. The ARM710 is the @@ -50,8 +50,8 @@ config CPU_ARM720T select CPU_ABRT_LV4T select CPU_CACHE_V4 select CPU_CACHE_VIVT - select CPU_COPY_V4WT - select CPU_TLB_V4WT + select CPU_COPY_V4WT if MMU + select CPU_TLB_V4WT if MMU help A 32-bit RISC processor with 8kByte Cache, Write Buffer and MMU built around an ARM7TDMI core. @@ -68,8 +68,8 @@ config CPU_ARM920T select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT - select CPU_COPY_V4WB - select CPU_TLB_V4WBI + select CPU_COPY_V4WB if MMU + select CPU_TLB_V4WBI if MMU help The ARM920T is licensed to be produced by numerous vendors, and is used in the Maverick EP9312 and the Samsung S3C2410. @@ -89,8 +89,8 @@ config CPU_ARM922T select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT - select CPU_COPY_V4WB - select CPU_TLB_V4WBI + select CPU_COPY_V4WB if MMU + select CPU_TLB_V4WBI if MMU help The ARM922T is a version of the ARM920T, but with smaller instruction and data caches. It is used in Altera's @@ -108,8 +108,8 @@ config CPU_ARM925T select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT - select CPU_COPY_V4WB - select CPU_TLB_V4WBI + select CPU_COPY_V4WB if MMU + select CPU_TLB_V4WBI if MMU help The ARM925T is a mix between the ARM920T and ARM926T, but with different instruction and data caches. It is used in TI's OMAP @@ -126,8 +126,8 @@ config CPU_ARM926T select CPU_32v5 select CPU_ABRT_EV5TJ select CPU_CACHE_VIVT - select CPU_COPY_V4WB - select CPU_TLB_V4WBI + select CPU_COPY_V4WB if MMU + select CPU_TLB_V4WBI if MMU help This is a variant of the ARM920. It has slightly different instruction sequences for cache and TLB operations. Curiously, @@ -144,8 +144,8 @@ config CPU_ARM1020 select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT - select CPU_COPY_V4WB - select CPU_TLB_V4WBI + select CPU_COPY_V4WB if MMU + select CPU_TLB_V4WBI if MMU help The ARM1020 is the 32K cached version of the ARM10 processor, with an addition of a floating-point unit. @@ -161,8 +161,8 @@ config CPU_ARM1020E select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT - select CPU_COPY_V4WB - select CPU_TLB_V4WBI + select CPU_COPY_V4WB if MMU + select CPU_TLB_V4WBI if MMU depends on n # ARM1022E @@ -172,8 +172,8 @@ config CPU_ARM1022 select CPU_32v5 select CPU_ABRT_EV4T select CPU_CACHE_VIVT - select CPU_COPY_V4WB # can probably do better - select CPU_TLB_V4WBI + select CPU_COPY_V4WB if MMU # can probably do better + select CPU_TLB_V4WBI if MMU help The ARM1022E is an implementation of the ARMv5TE architecture based upon the ARM10 integer core with a 16KiB L1 Harvard cache, @@ -189,8 +189,8 @@ config CPU_ARM1026 select CPU_32v5 select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10 select CPU_CACHE_VIVT - select CPU_COPY_V4WB # can probably do better - select CPU_TLB_V4WBI + select CPU_COPY_V4WB if MMU # can probably do better + select CPU_TLB_V4WBI if MMU help The ARM1026EJ-S is an implementation of the ARMv5TEJ architecture based upon the ARM10 integer core. @@ -207,8 +207,8 @@ config CPU_SA110 select CPU_ABRT_EV4 select CPU_CACHE_V4WB select CPU_CACHE_VIVT - select CPU_COPY_V4WB - select CPU_TLB_V4WB + select CPU_COPY_V4WB if MMU + select CPU_TLB_V4WB if MMU help The Intel StrongARM(R) SA-110 is a 32-bit microprocessor and is available at five speeds ranging from 100 MHz to 233 MHz. @@ -227,7 +227,7 @@ config CPU_SA1100 select CPU_ABRT_EV4 select CPU_CACHE_V4WB select CPU_CACHE_VIVT - select CPU_TLB_V4WB + select CPU_TLB_V4WB if MMU # XScale config CPU_XSCALE @@ -237,7 +237,7 @@ config CPU_XSCALE select CPU_32v5 select CPU_ABRT_EV5T select CPU_CACHE_VIVT - select CPU_TLB_V4WBI + select CPU_TLB_V4WBI if MMU # XScale Core Version 3 config CPU_XSC3 @@ -247,7 +247,7 @@ config CPU_XSC3 select CPU_32v5 select CPU_ABRT_EV5T select CPU_CACHE_VIVT - select CPU_TLB_V4WBI + select CPU_TLB_V4WBI if MMU select IO_36 # ARMv6 @@ -258,8 +258,8 @@ config CPU_V6 select CPU_ABRT_EV6 select CPU_CACHE_V6 select CPU_CACHE_VIPT - select CPU_COPY_V6 - select CPU_TLB_V6 + select CPU_COPY_V6 if MMU + select CPU_TLB_V6 if MMU # ARMv6k config CPU_32v6K @@ -277,17 +277,17 @@ config CPU_32v6K # This defines the compiler instruction set which depends on the machine type. config CPU_32v3 bool - select TLS_REG_EMUL if SMP + select TLS_REG_EMUL if SMP || !MMU select NEEDS_SYSCALL_FOR_CMPXCHG if SMP config CPU_32v4 bool - select TLS_REG_EMUL if SMP + select TLS_REG_EMUL if SMP || !MMU select NEEDS_SYSCALL_FOR_CMPXCHG if SMP config CPU_32v5 bool - select TLS_REG_EMUL if SMP + select TLS_REG_EMUL if SMP || !MMU select NEEDS_SYSCALL_FOR_CMPXCHG if SMP config CPU_32v6 @@ -334,6 +334,7 @@ config CPU_CACHE_VIVT config CPU_CACHE_VIPT bool +if MMU # The copy-page model config CPU_COPY_V3 bool @@ -372,6 +373,8 @@ config CPU_TLB_V4WBI config CPU_TLB_V6 bool +endif + # # CPU supports 36-bit I/O # diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 07a53850578..21a2770226e 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -2,10 +2,16 @@ # Makefile for the linux arm-specific parts of the memory manager. # -obj-y := consistent.o extable.o fault-armv.o \ - fault.o flush.o init.o ioremap.o mmap.o \ +obj-y := consistent.o extable.o fault.o init.o \ + iomap.o + +obj-$(CONFIG_MMU) += fault-armv.o flush.o ioremap.o mmap.o \ mm-armv.o +ifneq ($(CONFIG_MMU),y) +obj-y += nommu.o +endif + obj-$(CONFIG_MODULES) += proc-syms.o obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o diff --git a/arch/arm/mm/copypage-v3.S b/arch/arm/mm/copypage-v3.S index 3c58ebbf035..2ee394b11bc 100644 --- a/arch/arm/mm/copypage-v3.S +++ b/arch/arm/mm/copypage-v3.S @@ -35,7 +35,7 @@ ENTRY(v3_copy_user_page) stmia r0!, {r3, r4, ip, lr} @ 4 ldmneia r1!, {r3, r4, ip, lr} @ 4 bne 1b @ 1 - LOADREGS(fd, sp!, {r4, pc}) @ 3 + ldmfd sp!, {r4, pc} @ 3 .align 5 /* diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 9ea1f87a707..989fd681c82 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -26,8 +26,6 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> -#define TABLE_SIZE (2 * PTRS_PER_PTE * sizeof(pte_t)) - DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; diff --git a/arch/arm/mm/iomap.c b/arch/arm/mm/iomap.c new file mode 100644 index 00000000000..62066f3020c --- /dev/null +++ b/arch/arm/mm/iomap.c @@ -0,0 +1,55 @@ +/* + * linux/arch/arm/mm/iomap.c + * + * Map IO port and PCI memory spaces so that {read,write}[bwl] can + * be used to access this memory. + */ +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/ioport.h> + +#include <asm/io.h> + +#ifdef __io +void __iomem *ioport_map(unsigned long port, unsigned int nr) +{ + return __io(port); +} +EXPORT_SYMBOL(ioport_map); + +void ioport_unmap(void __iomem *addr) +{ +} +EXPORT_SYMBOL(ioport_unmap); +#endif + +#ifdef CONFIG_PCI +void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) +{ + unsigned long start = pci_resource_start(dev, bar); + unsigned long len = pci_resource_len(dev, bar); + unsigned long flags = pci_resource_flags(dev, bar); + + if (!len || !start) + return NULL; + if (maxlen && len > maxlen) + len = maxlen; + if (flags & IORESOURCE_IO) + return ioport_map(start, len); + if (flags & IORESOURCE_MEM) { + if (flags & IORESOURCE_CACHEABLE) + return ioremap(start, len); + return ioremap_nocache(start, len); + } + return NULL; +} +EXPORT_SYMBOL(pci_iomap); + +void pci_iounmap(struct pci_dev *dev, void __iomem *addr) +{ + if ((unsigned long)addr >= VMALLOC_START && + (unsigned long)addr < VMALLOC_END) + iounmap(addr); +} +EXPORT_SYMBOL(pci_iounmap); +#endif diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index c1f7180c7be..7691cfdba56 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c @@ -176,50 +176,3 @@ void __iounmap(void __iomem *addr) vunmap((void *)(PAGE_MASK & (unsigned long)addr)); } EXPORT_SYMBOL(__iounmap); - -#ifdef __io -void __iomem *ioport_map(unsigned long port, unsigned int nr) -{ - return __io(port); -} -EXPORT_SYMBOL(ioport_map); - -void ioport_unmap(void __iomem *addr) -{ -} -EXPORT_SYMBOL(ioport_unmap); -#endif - -#ifdef CONFIG_PCI -#include <linux/pci.h> -#include <linux/ioport.h> - -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ - unsigned long start = pci_resource_start(dev, bar); - unsigned long len = pci_resource_len(dev, bar); - unsigned long flags = pci_resource_flags(dev, bar); - - if (!len || !start) - return NULL; - if (maxlen && len > maxlen) - len = maxlen; - if (flags & IORESOURCE_IO) - return ioport_map(start, len); - if (flags & IORESOURCE_MEM) { - if (flags & IORESOURCE_CACHEABLE) - return ioremap(start, len); - return ioremap_nocache(start, len); - } - return NULL; -} -EXPORT_SYMBOL(pci_iomap); - -void pci_iounmap(struct pci_dev *dev, void __iomem *addr) -{ - if ((unsigned long)addr >= VMALLOC_START && - (unsigned long)addr < VMALLOC_END) - iounmap(addr); -} -EXPORT_SYMBOL(pci_iounmap); -#endif diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c new file mode 100644 index 00000000000..1464ed817b5 --- /dev/null +++ b/arch/arm/mm/nommu.c @@ -0,0 +1,39 @@ +/* + * linux/arch/arm/mm/nommu.c + * + * ARM uCLinux supporting functions. + */ +#include <linux/module.h> +#include <linux/mm.h> +#include <linux/pagemap.h> + +#include <asm/cacheflush.h> +#include <asm/io.h> +#include <asm/page.h> + +void flush_dcache_page(struct page *page) +{ + __cpuc_flush_dcache_page(page_address(page)); +} +EXPORT_SYMBOL(flush_dcache_page); + +void __iomem *__ioremap_pfn(unsigned long pfn, unsigned long offset, + size_t size, unsigned long flags) +{ + if (pfn >= (0x100000000ULL >> PAGE_SHIFT)) + return NULL; + return (void __iomem *) (offset + (pfn << PAGE_SHIFT)); +} +EXPORT_SYMBOL(__ioremap_pfn); + +void __iomem *__ioremap(unsigned long phys_addr, size_t size, + unsigned long flags) +{ + return (void __iomem *)phys_addr; +} +EXPORT_SYMBOL(__ioremap); + +void __iounmap(void __iomem *addr) +{ +} +EXPORT_SYMBOL(__iounmap); diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S index 959588884fa..b9abbafca81 100644 --- a/arch/arm/mm/proc-arm1020.S +++ b/arch/arm/mm/proc-arm1020.S @@ -3,6 +3,7 @@ * * Copyright (C) 2000 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd. + * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -101,7 +102,9 @@ ENTRY(cpu_arm1020_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB +#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -359,6 +362,7 @@ ENTRY(cpu_arm1020_dcache_clean_area) */ .align 5 ENTRY(cpu_arm1020_switch_mm) +#ifdef CONFIG_MMU #ifndef CONFIG_CPU_DCACHE_DISABLE mcr p15, 0, r3, c7, c10, 4 mov r1, #0xF @ 16 segments @@ -383,6 +387,7 @@ ENTRY(cpu_arm1020_switch_mm) mcr p15, 0, r1, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs +#endif /* CONFIG_MMU */ mov pc, lr /* @@ -392,6 +397,7 @@ ENTRY(cpu_arm1020_switch_mm) */ .align 5 ENTRY(cpu_arm1020_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -421,6 +427,7 @@ ENTRY(cpu_arm1020_set_pte) mcr p15, 0, r0, c7, c10, 1 @ clean D entry #endif mcr p15, 0, r0, c7, c10, 4 @ drain WB +#endif /* CONFIG_MMU */ mov pc, lr __INIT @@ -430,7 +437,9 @@ __arm1020_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 +#endif mrc p15, 0, r0, c1, c0 @ get control register v4 ldr r5, arm1020_cr1_clear bic r0, r0, r5 diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S index be6d081ff2b..bcd5ee022e0 100644 --- a/arch/arm/mm/proc-arm1020e.S +++ b/arch/arm/mm/proc-arm1020e.S @@ -3,6 +3,7 @@ * * Copyright (C) 2000 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd. + * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -101,7 +102,9 @@ ENTRY(cpu_arm1020e_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB +#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -344,6 +347,7 @@ ENTRY(cpu_arm1020e_dcache_clean_area) */ .align 5 ENTRY(cpu_arm1020e_switch_mm) +#ifdef CONFIG_MMU #ifndef CONFIG_CPU_DCACHE_DISABLE mcr p15, 0, r3, c7, c10, 4 mov r1, #0xF @ 16 segments @@ -367,6 +371,7 @@ ENTRY(cpu_arm1020e_switch_mm) mcr p15, 0, r1, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs +#endif mov pc, lr /* @@ -376,6 +381,7 @@ ENTRY(cpu_arm1020e_switch_mm) */ .align 5 ENTRY(cpu_arm1020e_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -403,6 +409,7 @@ ENTRY(cpu_arm1020e_set_pte) #ifndef CONFIG_CPU_DCACHE_DISABLE mcr p15, 0, r0, c7, c10, 1 @ clean D entry #endif +#endif /* CONFIG_MMU */ mov pc, lr __INIT @@ -412,7 +419,9 @@ __arm1020e_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 +#endif mrc p15, 0, r0, c1, c0 @ get control register v4 ldr r5, arm1020e_cr1_clear bic r0, r0, r5 diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S index f778545d57a..b0ccff4fadd 100644 --- a/arch/arm/mm/proc-arm1022.S +++ b/arch/arm/mm/proc-arm1022.S @@ -3,6 +3,7 @@ * * Copyright (C) 2000 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd. + * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -90,7 +91,9 @@ ENTRY(cpu_arm1022_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB +#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -333,6 +336,7 @@ ENTRY(cpu_arm1022_dcache_clean_area) */ .align 5 ENTRY(cpu_arm1022_switch_mm) +#ifdef CONFIG_MMU #ifndef CONFIG_CPU_DCACHE_DISABLE mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 16 segments 1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries @@ -349,6 +353,7 @@ ENTRY(cpu_arm1022_switch_mm) mcr p15, 0, r1, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs +#endif mov pc, lr /* @@ -358,6 +363,7 @@ ENTRY(cpu_arm1022_switch_mm) */ .align 5 ENTRY(cpu_arm1022_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -385,6 +391,7 @@ ENTRY(cpu_arm1022_set_pte) #ifndef CONFIG_CPU_DCACHE_DISABLE mcr p15, 0, r0, c7, c10, 1 @ clean D entry #endif +#endif /* CONFIG_MMU */ mov pc, lr __INIT @@ -394,7 +401,9 @@ __arm1022_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 +#endif mrc p15, 0, r0, c1, c0 @ get control register v4 ldr r5, arm1022_cr1_clear bic r0, r0, r5 diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S index 148c111fde7..abe850c9a64 100644 --- a/arch/arm/mm/proc-arm1026.S +++ b/arch/arm/mm/proc-arm1026.S @@ -3,6 +3,7 @@ * * Copyright (C) 2000 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd. + * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -90,7 +91,9 @@ ENTRY(cpu_arm1026_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB +#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -327,6 +330,7 @@ ENTRY(cpu_arm1026_dcache_clean_area) */ .align 5 ENTRY(cpu_arm1026_switch_mm) +#ifdef CONFIG_MMU mov r1, #0 #ifndef CONFIG_CPU_DCACHE_DISABLE 1: mrc p15, 0, r15, c7, c14, 3 @ test, clean, invalidate @@ -338,6 +342,7 @@ ENTRY(cpu_arm1026_switch_mm) mcr p15, 0, r1, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs +#endif mov pc, lr /* @@ -347,6 +352,7 @@ ENTRY(cpu_arm1026_switch_mm) */ .align 5 ENTRY(cpu_arm1026_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -374,6 +380,7 @@ ENTRY(cpu_arm1026_set_pte) #ifndef CONFIG_CPU_DCACHE_DISABLE mcr p15, 0, r0, c7, c10, 1 @ clean D entry #endif +#endif /* CONFIG_MMU */ mov pc, lr @@ -384,8 +391,10 @@ __arm1026_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 mcr p15, 0, r4, c2, c0 @ load page table pointer +#endif #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mov r0, #4 @ explicitly disable writeback mcr p15, 7, r0, c15, c0, 0 diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S index 540359b475d..7a705edfa4b 100644 --- a/arch/arm/mm/proc-arm6_7.S +++ b/arch/arm/mm/proc-arm6_7.S @@ -2,6 +2,7 @@ * linux/arch/arm/mm/proc-arm6,7.S * * Copyright (C) 1997-2000 Russell King + * hacked for non-paged-MM by Hyok S. Choi, 2003. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -199,10 +200,12 @@ ENTRY(cpu_arm7_do_idle) */ ENTRY(cpu_arm6_switch_mm) ENTRY(cpu_arm7_switch_mm) +#ifdef CONFIG_MMU mov r1, #0 mcr p15, 0, r1, c7, c0, 0 @ flush cache mcr p15, 0, r0, c2, c0, 0 @ update page table ptr mcr p15, 0, r1, c5, c0, 0 @ flush TLBs +#endif mov pc, lr /* @@ -214,6 +217,7 @@ ENTRY(cpu_arm7_switch_mm) .align 5 ENTRY(cpu_arm6_set_pte) ENTRY(cpu_arm7_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -232,6 +236,7 @@ ENTRY(cpu_arm7_set_pte) movne r2, #0 str r2, [r0] @ hardware version +#endif /* CONFIG_MMU */ mov pc, lr /* @@ -243,7 +248,9 @@ ENTRY(cpu_arm6_reset) ENTRY(cpu_arm7_reset) mov r1, #0 mcr p15, 0, r1, c7, c0, 0 @ flush cache +#ifdef CONFIG_MMU mcr p15, 0, r1, c5, c0, 0 @ flush TLB +#endif mov r1, #0x30 mcr p15, 0, r1, c1, c0, 0 @ turn off MMU etc mov pc, r0 @@ -253,19 +260,27 @@ ENTRY(cpu_arm7_reset) .type __arm6_setup, #function __arm6_setup: mov r0, #0 mcr p15, 0, r0, c7, c0 @ flush caches on v3 +#ifdef CONFIG_MMU mcr p15, 0, r0, c5, c0 @ flush TLBs on v3 mov r0, #0x3d @ . ..RS BLDP WCAM orr r0, r0, #0x100 @ . ..01 0011 1101 +#else + mov r0, #0x3c @ . ..RS BLDP WCA. +#endif mov pc, lr .size __arm6_setup, . - __arm6_setup .type __arm7_setup, #function __arm7_setup: mov r0, #0 mcr p15, 0, r0, c7, c0 @ flush caches on v3 +#ifdef CONFIG_MMU mcr p15, 0, r0, c5, c0 @ flush TLBs on v3 mcr p15, 0, r0, c3, c0 @ load domain access register mov r0, #0x7d @ . ..RS BLDP WCAM orr r0, r0, #0x100 @ . ..01 0111 1101 +#else + mov r0, #0x7c @ . ..RS BLDP WCA. +#endif mov pc, lr .size __arm7_setup, . - __arm7_setup diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S index 26f00ee2ad9..86102467d37 100644 --- a/arch/arm/mm/proc-arm720.S +++ b/arch/arm/mm/proc-arm720.S @@ -4,6 +4,7 @@ * Copyright (C) 2000 Steve Hill (sjhill@cotw.com) * Rob Scott (rscott@mtrob.fdns.net) * Copyright (C) 2000 ARM Limited, Deep Blue Solutions Ltd. + * hacked for non-paged-MM by Hyok S. Choi, 2004. * * 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 @@ -29,6 +30,7 @@ * out of 'proc-arm6,7.S' per RMK discussion * 07-25-2000 SJH Added idle function. * 08-25-2000 DBS Updated for integration of ARM Ltd version. + * 04-20-2004 HSC modified for non-paged memory management mode. */ #include <linux/linkage.h> #include <linux/init.h> @@ -75,10 +77,12 @@ ENTRY(cpu_arm720_do_idle) * the new. */ ENTRY(cpu_arm720_switch_mm) +#ifdef CONFIG_MMU mov r1, #0 mcr p15, 0, r1, c7, c7, 0 @ invalidate cache mcr p15, 0, r0, c2, c0, 0 @ update page table ptr mcr p15, 0, r1, c8, c7, 0 @ flush TLB (v4) +#endif mov pc, lr /* @@ -89,6 +93,7 @@ ENTRY(cpu_arm720_switch_mm) */ .align 5 ENTRY(cpu_arm720_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -107,6 +112,7 @@ ENTRY(cpu_arm720_set_pte) movne r2, #0 str r2, [r0] @ hardware version +#endif mov pc, lr /* @@ -117,7 +123,9 @@ ENTRY(cpu_arm720_set_pte) ENTRY(cpu_arm720_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate cache +#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ flush TLB (v4) +#endif mrc p15, 0, ip, c1, c0, 0 @ get ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x2100 @ ..v....s........ @@ -130,7 +138,9 @@ ENTRY(cpu_arm720_reset) __arm710_setup: mov r0, #0 mcr p15, 0, r0, c7, c7, 0 @ invalidate caches +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4) +#endif mrc p15, 0, r0, c1, c0 @ get control register ldr r5, arm710_cr1_clear bic r0, r0, r5 @@ -156,7 +166,9 @@ arm710_cr1_set: __arm720_setup: mov r0, #0 mcr p15, 0, r0, c7, c7, 0 @ invalidate caches +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4) +#endif mrc p15, 0, r0, c1, c0 @ get control register ldr r5, arm720_cr1_clear bic r0, r0, r5 diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S index a17f79e0199..31dc839ba07 100644 --- a/arch/arm/mm/proc-arm920.S +++ b/arch/arm/mm/proc-arm920.S @@ -3,6 +3,7 @@ * * Copyright (C) 1999,2000 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd. + * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -97,7 +98,9 @@ ENTRY(cpu_arm920_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB +#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -317,6 +320,7 @@ ENTRY(cpu_arm920_dcache_clean_area) */ .align 5 ENTRY(cpu_arm920_switch_mm) +#ifdef CONFIG_MMU mov ip, #0 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache @@ -337,6 +341,7 @@ ENTRY(cpu_arm920_switch_mm) mcr p15, 0, ip, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mov pc, lr /* @@ -346,6 +351,7 @@ ENTRY(cpu_arm920_switch_mm) */ .align 5 ENTRY(cpu_arm920_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -372,6 +378,7 @@ ENTRY(cpu_arm920_set_pte) mov r0, r0 mcr p15, 0, r0, c7, c10, 1 @ clean D entry mcr p15, 0, r0, c7, c10, 4 @ drain WB +#endif /* CONFIG_MMU */ mov pc, lr __INIT @@ -381,7 +388,9 @@ __arm920_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 +#endif mrc p15, 0, r0, c1, c0 @ get control register v4 ldr r5, arm920_cr1_clear bic r0, r0, r5 diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S index bbde4a024a4..9e57c34f5c0 100644 --- a/arch/arm/mm/proc-arm922.S +++ b/arch/arm/mm/proc-arm922.S @@ -4,6 +4,7 @@ * Copyright (C) 1999,2000 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd. * Copyright (C) 2001 Altera Corporation + * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -99,7 +100,9 @@ ENTRY(cpu_arm922_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB +#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -321,6 +324,7 @@ ENTRY(cpu_arm922_dcache_clean_area) */ .align 5 ENTRY(cpu_arm922_switch_mm) +#ifdef CONFIG_MMU mov ip, #0 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache @@ -341,6 +345,7 @@ ENTRY(cpu_arm922_switch_mm) mcr p15, 0, ip, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mov pc, lr /* @@ -350,6 +355,7 @@ ENTRY(cpu_arm922_switch_mm) */ .align 5 ENTRY(cpu_arm922_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -376,6 +382,7 @@ ENTRY(cpu_arm922_set_pte) mov r0, r0 mcr p15, 0, r0, c7, c10, 1 @ clean D entry mcr p15, 0, r0, c7, c10, 4 @ drain WB +#endif /* CONFIG_MMU */ mov pc, lr __INIT @@ -385,7 +392,9 @@ __arm922_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 +#endif mrc p15, 0, r0, c1, c0 @ get control register v4 ldr r5, arm922_cr1_clear bic r0, r0, r5 diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S index 224ce226a01..8d47c9f3f93 100644 --- a/arch/arm/mm/proc-arm925.S +++ b/arch/arm/mm/proc-arm925.S @@ -9,6 +9,8 @@ * Update for Linux-2.6 and cache flush improvements * Copyright (C) 2004 Nokia Corporation by Tony Lindgren <tony@atomide.com> * + * hacked for non-paged-MM by Hyok S. Choi, 2004. + * * 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 @@ -122,7 +124,9 @@ ENTRY(cpu_arm925_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB +#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -369,6 +373,7 @@ ENTRY(cpu_arm925_dcache_clean_area) */ .align 5 ENTRY(cpu_arm925_switch_mm) +#ifdef CONFIG_MMU mov ip, #0 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache @@ -383,6 +388,7 @@ ENTRY(cpu_arm925_switch_mm) mcr p15, 0, ip, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mov pc, lr /* @@ -392,6 +398,7 @@ ENTRY(cpu_arm925_switch_mm) */ .align 5 ENTRY(cpu_arm925_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -420,6 +427,7 @@ ENTRY(cpu_arm925_set_pte) mcr p15, 0, r0, c7, c10, 1 @ clean D entry #endif mcr p15, 0, r0, c7, c10, 4 @ drain WB +#endif /* CONFIG_MMU */ mov pc, lr __INIT @@ -438,7 +446,9 @@ __arm925_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 +#endif #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mov r0, #4 @ disable write-back on caches explicitly diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S index 4e2a087cf38..cb4d8f33d2a 100644 --- a/arch/arm/mm/proc-arm926.S +++ b/arch/arm/mm/proc-arm926.S @@ -3,6 +3,7 @@ * * Copyright (C) 1999-2001 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd. + * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -85,7 +86,9 @@ ENTRY(cpu_arm926_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB +#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -329,6 +332,7 @@ ENTRY(cpu_arm926_dcache_clean_area) */ .align 5 ENTRY(cpu_arm926_switch_mm) +#ifdef CONFIG_MMU mov ip, #0 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache @@ -341,6 +345,7 @@ ENTRY(cpu_arm926_switch_mm) mcr p15, 0, ip, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mov pc, lr /* @@ -350,6 +355,7 @@ ENTRY(cpu_arm926_switch_mm) */ .align 5 ENTRY(cpu_arm926_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -378,6 +384,7 @@ ENTRY(cpu_arm926_set_pte) mcr p15, 0, r0, c7, c10, 1 @ clean D entry #endif mcr p15, 0, r0, c7, c10, 4 @ drain WB +#endif mov pc, lr __INIT @@ -387,7 +394,9 @@ __arm926_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 +#endif #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S index a2dd5ae1077..5a760a2c629 100644 --- a/arch/arm/mm/proc-sa110.S +++ b/arch/arm/mm/proc-sa110.S @@ -2,6 +2,7 @@ * linux/arch/arm/mm/proc-sa110.S * * Copyright (C) 1997-2002 Russell King + * hacked for non-paged-MM by Hyok S. Choi, 2003. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -67,7 +68,9 @@ ENTRY(cpu_sa110_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB +#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -130,11 +133,15 @@ ENTRY(cpu_sa110_dcache_clean_area) */ .align 5 ENTRY(cpu_sa110_switch_mm) +#ifdef CONFIG_MMU str lr, [sp, #-4]! bl v4wb_flush_kern_cache_all @ clears IP mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs ldr pc, [sp], #4 +#else + mov pc, lr +#endif /* * cpu_sa110_set_pte(ptep, pte) @@ -143,6 +150,7 @@ ENTRY(cpu_sa110_switch_mm) */ .align 5 ENTRY(cpu_sa110_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -164,6 +172,7 @@ ENTRY(cpu_sa110_set_pte) mov r0, r0 mcr p15, 0, r0, c7, c10, 1 @ clean D entry mcr p15, 0, r0, c7, c10, 4 @ drain WB +#endif mov pc, lr __INIT @@ -173,7 +182,9 @@ __sa110_setup: mov r10, #0 mcr p15, 0, r10, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r10, c7, c10, 4 @ drain write buffer on v4 +#ifdef CONFIG_MMU mcr p15, 0, r10, c8, c7 @ invalidate I,D TLBs on v4 +#endif mrc p15, 0, r0, c1, c0 @ get control register v4 ldr r5, sa110_cr1_clear bic r0, r0, r5 diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S index 777ad99c143..0a2107ad4c3 100644 --- a/arch/arm/mm/proc-sa1100.S +++ b/arch/arm/mm/proc-sa1100.S @@ -2,6 +2,7 @@ * linux/arch/arm/mm/proc-sa1100.S * * Copyright (C) 1997-2002 Russell King + * hacked for non-paged-MM by Hyok S. Choi, 2003. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -77,7 +78,9 @@ ENTRY(cpu_sa1100_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB +#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -142,12 +145,16 @@ ENTRY(cpu_sa1100_dcache_clean_area) */ .align 5 ENTRY(cpu_sa1100_switch_mm) +#ifdef CONFIG_MMU str lr, [sp, #-4]! bl v4wb_flush_kern_cache_all @ clears IP mcr p15, 0, ip, c9, c0, 0 @ invalidate RB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs ldr pc, [sp], #4 +#else + mov pc, lr +#endif /* * cpu_sa1100_set_pte(ptep, pte) @@ -156,6 +163,7 @@ ENTRY(cpu_sa1100_switch_mm) */ .align 5 ENTRY(cpu_sa1100_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -177,6 +185,7 @@ ENTRY(cpu_sa1100_set_pte) mov r0, r0 mcr p15, 0, r0, c7, c10, 1 @ clean D entry mcr p15, 0, r0, c7, c10, 4 @ drain WB +#endif mov pc, lr __INIT @@ -186,7 +195,9 @@ __sa1100_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 +#endif mrc p15, 0, r0, c1, c0 @ get control register v4 ldr r5, sa1100_cr1_clear bic r0, r0, r5 diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index ee6f1529873..ca13d4d05f6 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -2,6 +2,7 @@ * linux/arch/arm/mm/proc-v6.S * * Copyright (C) 2001 Deep Blue Solutions Ltd. + * Modified by Catalin Marinas for noMMU support * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -29,38 +30,6 @@ #define TTB_RGN_WT (2 << 3) #define TTB_RGN_WB (3 << 3) - .macro cpsie, flags - .ifc \flags, f - .long 0xf1080040 - .exitm - .endif - .ifc \flags, i - .long 0xf1080080 - .exitm - .endif - .ifc \flags, if - .long 0xf10800c0 - .exitm - .endif - .err - .endm - - .macro cpsid, flags - .ifc \flags, f - .long 0xf10c0040 - .exitm - .endif - .ifc \flags, i - .long 0xf10c0080 - .exitm - .endif - .ifc \flags, if - .long 0xf10c00c0 - .exitm - .endif - .err - .endm - ENTRY(cpu_v6_proc_init) mov pc, lr @@ -120,6 +89,7 @@ ENTRY(cpu_v6_dcache_clean_area) * - we are not using split page tables */ ENTRY(cpu_v6_switch_mm) +#ifdef CONFIG_MMU mov r2, #0 ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id #ifdef CONFIG_SMP @@ -129,6 +99,7 @@ ENTRY(cpu_v6_switch_mm) mcr p15, 0, r2, c7, c10, 4 @ drain write buffer mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 mcr p15, 0, r1, c13, c0, 1 @ set context ID +#endif mov pc, lr /* @@ -151,6 +122,7 @@ ENTRY(cpu_v6_switch_mm) * 1111 0 1 1 r/w r/w */ ENTRY(cpu_v6_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version bic r2, r1, #0x000003f0 @@ -177,6 +149,7 @@ ENTRY(cpu_v6_set_pte) str r2, [r0] mcr p15, 0, r0, c7, c10, 1 @ flush_pte +#endif mov pc, lr @@ -226,12 +199,14 @@ __v6_setup: mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache mcr p15, 0, r0, c7, c15, 0 @ clean+invalidate cache mcr p15, 0, r0, c7, c10, 4 @ drain write buffer +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs mcr p15, 0, r0, c2, c0, 2 @ TTB control register #ifdef CONFIG_SMP orr r4, r4, #TTB_RGN_WBWA|TTB_S @ mark PTWs shared, outer cacheable #endif mcr p15, 0, r4, c2, c0, 1 @ load TTB1 +#endif /* CONFIG_MMU */ #ifdef CONFIG_VFP mrc p15, 0, r0, c1, c0, 2 orr r0, r0, #(0xf << 20) diff --git a/arch/arm/nwfpe/entry26.S b/arch/arm/nwfpe/entry26.S index 51940a96d6a..3e6fb5d21d6 100644 --- a/arch/arm/nwfpe/entry26.S +++ b/arch/arm/nwfpe/entry26.S @@ -26,7 +26,7 @@ It is called from the kernel with code similar to this: mov fp, #0 - teqp pc, #PSR_I_BIT | MODE_SVC + teqp pc, #PSR_I_BIT | SVC_MODE ldr r4, .LC2 ldr pc, [r4] @ Call FP module USR entry point diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 6d7de9c0412..e1372a25311 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -12,7 +12,7 @@ # # http://www.arm.linux.org.uk/developer/machines/?action=new # -# Last update: Mon May 8 20:11:05 2006 +# Last update: Mon Jun 26 22:26:08 2006 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -566,8 +566,8 @@ switchgrass MACH_SWITCHGRASS SWITCHGRASS 549 ens_cmu MACH_ENS_CMU ENS_CMU 550 mm6_sdb MACH_MM6_SDB MM6_SDB 551 saturn MACH_SATURN SATURN 552 -i30030evb MACH_ARGONPLUSEVB ARGONPLUSEVB 553 -mxc27530evb MACH_SCMA11EVB SCMA11EVB 554 +i30030evb MACH_I30030EVB I30030EVB 553 +mxc27530evb MACH_MXC27530EVB MXC27530EVB 554 smdk2800 MACH_SMDK2800 SMDK2800 555 mtwilson MACH_MTWILSON MTWILSON 556 ziti MACH_ZITI ZITI 557 @@ -647,7 +647,7 @@ sendt MACH_SENDT SENDT 630 mx2jazz MACH_MX2JAZZ MX2JAZZ 631 multiio MACH_MULTIIO MULTIIO 632 hrdisplay MACH_HRDISPLAY HRDISPLAY 633 -mxc27530ads MACH_SCMA11BB SCMA11BB 634 +mxc27530ads MACH_MXC27530ADS MXC27530ADS 634 trizeps3 MACH_TRIZEPS3 TRIZEPS3 635 zefeerdza MACH_ZEFEERDZA ZEFEERDZA 636 zefeerdzb MACH_ZEFEERDZB ZEFEERDZB 637 @@ -721,7 +721,7 @@ gp32 MACH_GP32 GP32 706 gem MACH_GEM GEM 707 i858 MACH_I858 I858 708 hx2750 MACH_HX2750 HX2750 709 -mxc91131evb MACH_ZEUSEVB ZEUSEVB 710 +mxc91131evb MACH_MXC91131EVB MXC91131EVB 710 p700 MACH_P700 P700 711 cpe MACH_CPE CPE 712 spitz MACH_SPITZ SPITZ 713 @@ -802,7 +802,7 @@ cpuat91 MACH_CPUAT91 CPUAT91 787 rea9200 MACH_REA9200 REA9200 788 acts_pune_sa1110 MACH_ACTS_PUNE_SA1110 ACTS_PUNE_SA1110 789 ixp425 MACH_IXP425 IXP425 790 -i30030ads MACH_ARGONPLUSODYSSEY ARGONPLUSODYSSEY 791 +i30030ads MACH_I30030ADS I30030ADS 791 perch MACH_PERCH PERCH 792 eis05r1 MACH_EIS05R1 EIS05R1 793 pepperpad MACH_PEPPERPAD PEPPERPAD 794 @@ -930,7 +930,7 @@ netclient MACH_NETCLIENT NETCLIENT 916 xscale_palmtt5 MACH_XSCALE_PALMTT5 XSCALE_PALMTT5 917 xscale_palmtc MACH_OMAP_PALMTC OMAP_PALMTC 918 omap_apollon MACH_OMAP_APOLLON OMAP_APOLLON 919 -mxc30030evb MACH_ARGONLVEVB ARGONLVEVB 920 +mxc30030evb MACH_MXC30030EVB MXC30030EVB 920 rea_2d MACH_REA_2D REA_2D 921 eti3e524 MACH_TI3E524 TI3E524 922 ateb9200 MACH_ATEB9200 ATEB9200 923 @@ -986,7 +986,7 @@ redfox MACH_REDFOX REDFOX 972 mysh_ep9315_1 MACH_MYSH_EP9315_1 MYSH_EP9315_1 973 tpf106 MACH_TPF106 TPF106 974 at91rm9200kg MACH_AT91RM9200KG AT91RM9200KG 975 -racemt2 MACH_SLEDB SLEDB 976 +rcmt2 MACH_SLEDB SLEDB 976 ontrack MACH_ONTRACK ONTRACK 977 pm1200 MACH_PM1200 PM1200 978 ess24562 MACH_ESS24XXX ESS24XXX 979 @@ -1022,7 +1022,7 @@ smdk2440 MACH_SMDK2440 SMDK2440 1008 smdk2412 MACH_SMDK2412 SMDK2412 1009 webbox MACH_WEBBOX WEBBOX 1010 cwwndp MACH_CWWNDP CWWNDP 1011 -dragon MACH_DRAGON DRAGON 1012 +i839 MACH_DRAGON DRAGON 1012 opendo_cpu_board MACH_OPENDO_CPU_BOARD OPENDO_CPU_BOARD 1013 ccm2200 MACH_CCM2200 CCM2200 1014 etwarm MACH_ETWARM ETWARM 1015 @@ -1040,3 +1040,56 @@ edg79524 MACH_EDG79524 EDG79524 1026 ai2410 MACH_AI2410 AI2410 1027 ixp465 MACH_IXP465 IXP465 1028 balloon3 MACH_BALLOON3 BALLOON3 1029 +heins MACH_HEINS HEINS 1030 +mpluseva MACH_MPLUSEVA MPLUSEVA 1031 +rt042 MACH_RT042 RT042 1032 +cwiem MACH_CWIEM CWIEM 1033 +cm_x270 MACH_CM_X270 CM_X270 1034 +cm_x255 MACH_CM_X255 CM_X255 1035 +esh_at91 MACH_ESH_AT91 ESH_AT91 1036 +sandgate3 MACH_SANDGATE3 SANDGATE3 1037 +primo MACH_PRIMO PRIMO 1038 +gemstone MACH_GEMSTONE GEMSTONE 1039 +pronghorn_metro MACH_PRONGHORNMETRO PRONGHORNMETRO 1040 +sidewinder MACH_SIDEWINDER SIDEWINDER 1041 +picomod1 MACH_PICOMOD1 PICOMOD1 1042 +sg590 MACH_SG590 SG590 1043 +akai9307 MACH_AKAI9307 AKAI9307 1044 +fontaine MACH_FONTAINE FONTAINE 1045 +wombat MACH_WOMBAT WOMBAT 1046 +acq300 MACH_ACQ300 ACQ300 1047 +mod_270 MACH_MOD_270 MOD_270 1048 +vmc_vc0820 MACH_VC0820 VC0820 1049 +ani_aim MACH_ANI_AIM ANI_AIM 1050 +jellyfish MACH_JELLYFISH JELLYFISH 1051 +amanita MACH_AMANITA AMANITA 1052 +vlink MACH_VLINK VLINK 1053 +dexflex MACH_DEXFLEX DEXFLEX 1054 +eigen_ttq MACH_EIGEN_TTQ EIGEN_TTQ 1055 +arcom_titan MACH_ARCOM_TITAN ARCOM_TITAN 1056 +tabla MACH_TABLA TABLA 1057 +mdirac3 MACH_MDIRAC3 MDIRAC3 1058 +mrhfbp2 MACH_MRHFBP2 MRHFBP2 1059 +at91rm9200rb MACH_AT91RM9200RB AT91RM9200RB 1060 +ani_apm MACH_ANI_APM ANI_APM 1061 +ella1 MACH_ELLA1 ELLA1 1062 +inhand_pxa27x MACH_INHAND_PXA27X INHAND_PXA27X 1063 +inhand_pxa25x MACH_INHAND_PXA25X INHAND_PXA25X 1064 +empos_xm MACH_EMPOS_XM EMPOS_XM 1065 +empos MACH_EMPOS EMPOS 1066 +empos_tiny MACH_EMPOS_TINY EMPOS_TINY 1067 +empos_sm MACH_EMPOS_SM EMPOS_SM 1068 +egret MACH_EGRET EGRET 1069 +ostrich MACH_OSTRICH OSTRICH 1070 +n50 MACH_N50 N50 1071 +ecbat91 MACH_ECBAT91 ECBAT91 1072 +stareast MACH_STAREAST STAREAST 1073 +dspg_dw MACH_DSPG_DW DSPG_DW 1074 +onearm MACH_ONEARM ONEARM 1075 +mrg110_6 MACH_MRG110_6 MRG110_6 1076 +wrt300nv2 MACH_WRT300NV2 WRT300NV2 1077 +xm_bulverde MACH_XM_BULVERDE XM_BULVERDE 1078 +msm6100 MACH_MSM6100 MSM6100 1079 +eti_b1 MACH_ETI_B1 ETI_B1 1080 +za9l_series MACH_ZILOG_ZA9L ZILOG_ZA9L 1081 +bit2440 MACH_BIT2440 BIT2440 1082 diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index 856b665020e..6a1238a29d6 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -28,6 +28,10 @@ config GENERIC_CALIBRATE_DELAY bool default y +config IRQ_PER_CPU + bool + default y + config CRIS bool default y diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c index 4b368a12201..2d5be93b519 100644 --- a/arch/cris/arch-v10/kernel/irq.c +++ b/arch/cris/arch-v10/kernel/irq.c @@ -172,7 +172,7 @@ init_IRQ(void) /* Initialize IRQ handler descriptiors. */ for(i = 2; i < NR_IRQS; i++) { - irq_desc[i].handler = &crisv10_irq_type; + irq_desc[i].chip = &crisv10_irq_type; set_int_vector(i, interrupt[i]); } diff --git a/arch/cris/arch-v32/drivers/pci/bios.c b/arch/cris/arch-v32/drivers/pci/bios.c index 1e9d062103a..a2b9c60c277 100644 --- a/arch/cris/arch-v32/drivers/pci/bios.c +++ b/arch/cris/arch-v32/drivers/pci/bios.c @@ -43,10 +43,10 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; + resource_size_t start = res->start; if (start & 0x300) { start = (start + 0x3ff) & ~0x3ff; diff --git a/arch/cris/arch-v32/kernel/irq.c b/arch/cris/arch-v32/kernel/irq.c index c78cc268513..06260874f01 100644 --- a/arch/cris/arch-v32/kernel/irq.c +++ b/arch/cris/arch-v32/kernel/irq.c @@ -369,7 +369,7 @@ init_IRQ(void) /* Point all IRQ's to bad handlers. */ for (i = FIRST_IRQ, j = 0; j < NR_IRQS; i++, j++) { - irq_desc[j].handler = &crisv32_irq_type; + irq_desc[j].chip = &crisv32_irq_type; set_exception_vector(i, interrupt[j]); } diff --git a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c index b504def3e34..6547bb64636 100644 --- a/arch/cris/kernel/irq.c +++ b/arch/cris/kernel/irq.c @@ -69,7 +69,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) diff --git a/arch/frv/mb93090-mb00/pci-frv.c b/arch/frv/mb93090-mb00/pci-frv.c index 0a26bf6f1cd..4f165c93be4 100644 --- a/arch/frv/mb93090-mb00/pci-frv.c +++ b/arch/frv/mb93090-mb00/pci-frv.c @@ -64,10 +64,10 @@ pcibios_update_resource(struct pci_dev *dev, struct resource *root, */ void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; + resource_size_t start = res->start; if (start & 0x300) { start = (start + 0x3ff) & ~0x3ff; diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 1596101cfaf..0463f633590 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -14,6 +14,10 @@ config X86_32 486, 586, Pentiums, and various instruction-set-compatible chips by AMD, Cyrix, and others. +config GENERIC_TIME + bool + default y + config SEMAPHORE_SLEEPERS bool default y @@ -229,7 +233,7 @@ config NR_CPUS config SCHED_SMT bool "SMT (Hyperthreading) scheduler support" - depends on SMP + depends on X86_HT help SMT scheduler support improves the CPU scheduler's decision making when dealing with Intel Pentium 4 chips with HyperThreading at a @@ -238,7 +242,7 @@ config SCHED_SMT config SCHED_MC bool "Multi-core scheduler support" - depends on SMP + depends on X86_HT default y help Multi-core scheduler support improves the CPU scheduler's decision @@ -324,6 +328,15 @@ config X86_MCE_P4THERMAL Enabling this feature will cause a message to be printed when the P4 enters thermal throttling. +config VM86 + default y + bool "Enable VM86 support" if EMBEDDED + help + This option is required by programs like DOSEMU to run 16-bit legacy + code on X86 processors. It also may be needed by software like + XFree86 to initialize some video cards via BIOS. Disabling this + option saves about 6k. + config TOSHIBA tristate "Toshiba Laptop support" ---help--- @@ -516,6 +529,7 @@ config X86_PAE bool depends on HIGHMEM64G default y + select RESOURCES_64BIT # Common NUMA Features config NUMA @@ -721,7 +735,7 @@ config KEXEC help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot - but it is indepedent of the system firmware. And like a reboot + but it is independent of the system firmware. And like a reboot you can start any kernel with it, not just Linux. The name comes from the similiarity to the exec system call. @@ -767,9 +781,23 @@ config HOTPLUG_CPU enable suspend on SMP systems. CPUs can be controlled through /sys/devices/system/cpu. +config COMPAT_VDSO + bool "Compat VDSO support" + default y + help + Map the VDSO to the predictable old-style address too. + ---help--- + Say N here if you are running a sufficiently recent glibc + version (2.3.3 or later), to remove the high-mapped + VDSO mapping and to exclusively use the randomized VDSO. + + If unsure, say Y. endmenu +config ARCH_ENABLE_MEMORY_HOTPLUG + def_bool y + depends on HIGHMEM menu "Power management options (ACPI, APM)" depends on !X86_VOYAGER @@ -1046,13 +1074,27 @@ config SCx200 tristate "NatSemi SCx200 support" depends on !X86_VOYAGER help - This provides basic support for the National Semiconductor SCx200 - processor. Right now this is just a driver for the GPIO pins. + This provides basic support for National Semiconductor's + (now AMD's) Geode processors. The driver probes for the + PCI-IDs of several on-chip devices, so its a good dependency + for other scx200_* drivers. - If you don't know what to do here, say N. + If compiled as a module, the driver is named scx200. - This support is also available as a module. If compiled as a - module, it will be called scx200. +config SCx200HR_TIMER + tristate "NatSemi SCx200 27MHz High-Resolution Timer Support" + depends on SCx200 && GENERIC_TIME + default y + help + This driver provides a clocksource built upon the on-chip + 27MHz high-resolution timer. Its also a workaround for + NSC Geode SC-1100's buggy TSC, which loses time when the + processor goes idle (as is done by the scheduler). The + other workaround is idle=poll boot option. + +config K8_NB + def_bool y + depends on AGP_AMD64 source "drivers/pcmcia/Kconfig" diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu index eb130482ba1..21c9a4e7110 100644 --- a/arch/i386/Kconfig.cpu +++ b/arch/i386/Kconfig.cpu @@ -41,7 +41,7 @@ config M386 - "GeodeGX1" for Geode GX1 (Cyrix MediaGX). - "Geode GX/LX" For AMD Geode GX and LX processors. - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3. - - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above). + - "VIA C3-2" for VIA C3-2 "Nehemiah" (model 9 and above). If you don't know what to do, choose "386". diff --git a/arch/i386/boot/Makefile b/arch/i386/boot/Makefile index 33e55476381..e9794662606 100644 --- a/arch/i386/boot/Makefile +++ b/arch/i386/boot/Makefile @@ -109,8 +109,13 @@ fdimage288: $(BOOTIMAGE) $(obj)/mtools.conf isoimage: $(BOOTIMAGE) -rm -rf $(obj)/isoimage mkdir $(obj)/isoimage - cp `echo /usr/lib*/syslinux/isolinux.bin | awk '{ print $1; }'` \ - $(obj)/isoimage + for i in lib lib64 share end ; do \ + if [ -f /usr/$$i/syslinux/isolinux.bin ] ; then \ + cp /usr/$$i/syslinux/isolinux.bin $(obj)/isoimage ; \ + break ; \ + fi ; \ + if [ $$i = end ] ; then exit 1 ; fi ; \ + done cp $(BOOTIMAGE) $(obj)/isoimage/linux echo '$(image_cmdline)' > $(obj)/isoimage/isolinux.cfg if [ -f '$(FDINITRD)' ] ; then \ diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c index f19f3a7492a..b2ccd543410 100644 --- a/arch/i386/boot/compressed/misc.c +++ b/arch/i386/boot/compressed/misc.c @@ -24,14 +24,6 @@ #undef memset #undef memcpy - -/* - * Why do we do this? Don't ask me.. - * - * Incomprehensible are the ways of bootloaders. - */ -static void* memset(void *, int, size_t); -static void* memcpy(void *, __const void *, size_t); #define memzero(s, n) memset ((s), 0, (n)) typedef unsigned char uch; @@ -93,7 +85,7 @@ static unsigned char *real_mode; /* Pointer to real-mode data */ #endif #define RM_SCREEN_INFO (*(struct screen_info *)(real_mode+0)) -extern char input_data[]; +extern unsigned char input_data[]; extern int input_len; static long bytes_out = 0; @@ -103,6 +95,9 @@ static unsigned long output_ptr = 0; static void *malloc(int size); static void free(void *where); +static void *memset(void *s, int c, unsigned n); +static void *memcpy(void *dest, const void *src, unsigned n); + static void putstr(const char *); extern int end; @@ -205,7 +200,7 @@ static void putstr(const char *s) outb_p(0xff & (pos >> 1), vidport+1); } -static void* memset(void* s, int c, size_t n) +static void* memset(void* s, int c, unsigned n) { int i; char *ss = (char*)s; @@ -214,14 +209,13 @@ static void* memset(void* s, int c, size_t n) return s; } -static void* memcpy(void* __dest, __const void* __src, - size_t __n) +static void* memcpy(void* dest, const void* src, unsigned n) { int i; - char *d = (char *)__dest, *s = (char *)__src; + char *d = (char *)dest, *s = (char *)src; - for (i=0;i<__n;i++) d[i] = s[i]; - return __dest; + for (i=0;i<n;i++) d[i] = s[i]; + return dest; } /* =========================================================================== @@ -309,7 +303,7 @@ static void setup_normal_output_buffer(void) #else if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < 1024) error("Less than 2MB of memory"); #endif - output_data = (char *)__PHYSICAL_START; /* Normally Points to 1M */ + output_data = (unsigned char *)__PHYSICAL_START; /* Normally Points to 1M */ free_mem_end_ptr = (long)real_mode; } @@ -324,11 +318,9 @@ static void setup_output_buffer_if_we_run_high(struct moveparams *mv) #ifdef STANDARD_MEMORY_BIOS_CALL if (RM_EXT_MEM_K < (3*1024)) error("Less than 4MB of memory"); #else - if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < - (3*1024)) - error("Less than 4MB of memory"); + if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory"); #endif - mv->low_buffer_start = output_data = (char *)LOW_BUFFER_START; + mv->low_buffer_start = output_data = (unsigned char *)LOW_BUFFER_START; low_buffer_end = ((unsigned int)real_mode > LOW_BUFFER_MAX ? LOW_BUFFER_MAX : (unsigned int)real_mode) & ~0xfff; low_buffer_size = low_buffer_end - LOW_BUFFER_START; diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S index c9343c3a808..8c2a6faeeae 100644 --- a/arch/i386/boot/video.S +++ b/arch/i386/boot/video.S @@ -1929,7 +1929,7 @@ skip10: movb %ah, %al ret store_edid: -#ifdef CONFIG_FB_FIRMWARE_EDID +#ifdef CONFIG_FIRMWARE_EDID pushw %es # just save all registers pushw %ax pushw %bx @@ -1947,6 +1947,22 @@ store_edid: rep stosl + pushw %es # save ES + xorw %di, %di # Report Capability + pushw %di + popw %es # ES:DI must be 0:0 + movw $0x4f15, %ax + xorw %bx, %bx + xorw %cx, %cx + int $0x10 + popw %es # restore ES + + cmpb $0x00, %ah # call successful + jne no_edid + + cmpb $0x4f, %al # function supported + jne no_edid + movw $0x4f15, %ax # do VBE/DDC movw $0x01, %bx movw $0x00, %cx @@ -1954,6 +1970,7 @@ store_edid: movw $0x140, %di int $0x10 +no_edid: popw %di # restore all registers popw %dx popw %cx diff --git a/arch/i386/crypto/aes-i586-asm.S b/arch/i386/crypto/aes-i586-asm.S index 911b15377f2..f942f0c8f63 100644 --- a/arch/i386/crypto/aes-i586-asm.S +++ b/arch/i386/crypto/aes-i586-asm.S @@ -36,22 +36,19 @@ .file "aes-i586-asm.S" .text -// aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1])// -// aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1])// - -#define tlen 1024 // length of each of 4 'xor' arrays (256 32-bit words) +#include <asm/asm-offsets.h> -// offsets to parameters with one register pushed onto stack - -#define in_blk 8 // input byte array address parameter -#define out_blk 12 // output byte array address parameter -#define ctx 16 // AES context structure +#define tlen 1024 // length of each of 4 'xor' arrays (256 32-bit words) -// offsets in context structure +/* offsets to parameters with one register pushed onto stack */ +#define tfm 8 +#define out_blk 12 +#define in_blk 16 -#define ekey 0 // encryption key schedule base address -#define nrnd 256 // number of rounds -#define dkey 260 // decryption key schedule base address +/* offsets in crypto_tfm structure */ +#define ekey (crypto_tfm_ctx_offset + 0) +#define nrnd (crypto_tfm_ctx_offset + 256) +#define dkey (crypto_tfm_ctx_offset + 260) // register mapping for encrypt and decrypt subroutines @@ -220,6 +217,7 @@ do_col (table, r5,r0,r1,r4, r2,r3); /* idx=r5 */ // AES (Rijndael) Encryption Subroutine +/* void aes_enc_blk(struct crypto_tfm *tfm, u8 *out_blk, const u8 *in_blk) */ .global aes_enc_blk @@ -230,7 +228,7 @@ aes_enc_blk: push %ebp - mov ctx(%esp),%ebp // pointer to context + mov tfm(%esp),%ebp // CAUTION: the order and the values used in these assigns // rely on the register mappings @@ -295,6 +293,7 @@ aes_enc_blk: ret // AES (Rijndael) Decryption Subroutine +/* void aes_dec_blk(struct crypto_tfm *tfm, u8 *out_blk, const u8 *in_blk) */ .global aes_dec_blk @@ -305,7 +304,7 @@ aes_enc_blk: aes_dec_blk: push %ebp - mov ctx(%esp),%ebp // pointer to context + mov tfm(%esp),%ebp // CAUTION: the order and the values used in these assigns // rely on the register mappings diff --git a/arch/i386/crypto/aes.c b/arch/i386/crypto/aes.c index a50397b1d5c..d3806daa3de 100644 --- a/arch/i386/crypto/aes.c +++ b/arch/i386/crypto/aes.c @@ -45,8 +45,8 @@ #include <linux/crypto.h> #include <linux/linkage.h> -asmlinkage void aes_enc_blk(const u8 *src, u8 *dst, void *ctx); -asmlinkage void aes_dec_blk(const u8 *src, u8 *dst, void *ctx); +asmlinkage void aes_enc_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src); +asmlinkage void aes_dec_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src); #define AES_MIN_KEY_SIZE 16 #define AES_MAX_KEY_SIZE 32 @@ -378,12 +378,12 @@ static void gen_tabs(void) k[8*(i)+11] = ss[3]; \ } -static int -aes_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags) +static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, + unsigned int key_len, u32 *flags) { int i; u32 ss[8]; - struct aes_ctx *ctx = ctx_arg; + struct aes_ctx *ctx = crypto_tfm_ctx(tfm); const __le32 *key = (const __le32 *)in_key; /* encryption schedule */ @@ -464,16 +464,16 @@ aes_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags) return 0; } -static inline void aes_encrypt(void *ctx, u8 *dst, const u8 *src) +static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) { - aes_enc_blk(src, dst, ctx); + aes_enc_blk(tfm, dst, src); } -static inline void aes_decrypt(void *ctx, u8 *dst, const u8 *src) + +static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) { - aes_dec_blk(src, dst, ctx); + aes_dec_blk(tfm, dst, src); } - static struct crypto_alg aes_alg = { .cra_name = "aes", .cra_driver_name = "aes-i586", diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index 96fb8a020af..5e70c2fb273 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile @@ -7,10 +7,9 @@ extra-y := head.o init_task.o vmlinux.lds obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ pci-dma.o i386_ksyms.o i387.o bootflag.o \ - quirks.o i8237.o topology.o alternative.o + quirks.o i8237.o topology.o alternative.o i8253.o tsc.o obj-y += cpu/ -obj-y += timers/ obj-y += acpi/ obj-$(CONFIG_X86_BIOS_REBOOT) += reboot.o obj-$(CONFIG_MCA) += mca.o @@ -37,6 +36,8 @@ obj-$(CONFIG_EFI) += efi.o efi_stub.o obj-$(CONFIG_DOUBLEFAULT) += doublefault.o obj-$(CONFIG_VM86) += vm86.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o +obj-$(CONFIG_HPET_TIMER) += hpet.o +obj-$(CONFIG_K8_NB) += k8.o EXTRA_AFLAGS := -traditional @@ -76,3 +77,6 @@ SYSCFLAGS_vsyscall-syms.o = -r $(obj)/vsyscall-syms.o: $(src)/vsyscall.lds \ $(obj)/vsyscall-sysenter.o $(obj)/vsyscall-note.o FORCE $(call if_changed,syscall) + +k8-y += ../../x86_64/kernel/k8.o + diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index 5cbd6f99fb2..50eb0e03777 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c @@ -4,27 +4,41 @@ #include <asm/alternative.h> #include <asm/sections.h> -#define DEBUG 0 -#if DEBUG -# define DPRINTK(fmt, args...) printk(fmt, args) -#else -# define DPRINTK(fmt, args...) -#endif +static int no_replacement = 0; +static int smp_alt_once = 0; +static int debug_alternative = 0; + +static int __init noreplacement_setup(char *s) +{ + no_replacement = 1; + return 1; +} +static int __init bootonly(char *str) +{ + smp_alt_once = 1; + return 1; +} +static int __init debug_alt(char *str) +{ + debug_alternative = 1; + return 1; +} +__setup("noreplacement", noreplacement_setup); +__setup("smp-alt-boot", bootonly); +__setup("debug-alternative", debug_alt); + +#define DPRINTK(fmt, args...) if (debug_alternative) \ + printk(KERN_DEBUG fmt, args) + +#ifdef GENERIC_NOP1 /* Use inline assembly to define this because the nops are defined as inline assembly strings in the include files and we cannot get them easily into strings. */ asm("\t.data\nintelnops: " GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6 GENERIC_NOP7 GENERIC_NOP8); -asm("\t.data\nk8nops: " - K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6 - K8_NOP7 K8_NOP8); -asm("\t.data\nk7nops: " - K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6 - K7_NOP7 K7_NOP8); - -extern unsigned char intelnops[], k8nops[], k7nops[]; +extern unsigned char intelnops[]; static unsigned char *intel_nops[ASM_NOP_MAX+1] = { NULL, intelnops, @@ -36,6 +50,13 @@ static unsigned char *intel_nops[ASM_NOP_MAX+1] = { intelnops + 1 + 2 + 3 + 4 + 5 + 6, intelnops + 1 + 2 + 3 + 4 + 5 + 6 + 7, }; +#endif + +#ifdef K8_NOP1 +asm("\t.data\nk8nops: " + K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6 + K8_NOP7 K8_NOP8); +extern unsigned char k8nops[]; static unsigned char *k8_nops[ASM_NOP_MAX+1] = { NULL, k8nops, @@ -47,6 +68,13 @@ static unsigned char *k8_nops[ASM_NOP_MAX+1] = { k8nops + 1 + 2 + 3 + 4 + 5 + 6, k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, }; +#endif + +#ifdef K7_NOP1 +asm("\t.data\nk7nops: " + K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6 + K7_NOP7 K7_NOP8); +extern unsigned char k7nops[]; static unsigned char *k7_nops[ASM_NOP_MAX+1] = { NULL, k7nops, @@ -58,6 +86,18 @@ static unsigned char *k7_nops[ASM_NOP_MAX+1] = { k7nops + 1 + 2 + 3 + 4 + 5 + 6, k7nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, }; +#endif + +#ifdef CONFIG_X86_64 + +extern char __vsyscall_0; +static inline unsigned char** find_nop_table(void) +{ + return k8_nops; +} + +#else /* CONFIG_X86_64 */ + static struct nop { int cpuid; unsigned char **noptable; @@ -67,14 +107,6 @@ static struct nop { { -1, NULL } }; - -extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; -extern struct alt_instr __smp_alt_instructions[], __smp_alt_instructions_end[]; -extern u8 *__smp_locks[], *__smp_locks_end[]; - -extern u8 __smp_alt_begin[], __smp_alt_end[]; - - static unsigned char** find_nop_table(void) { unsigned char **noptable = intel_nops; @@ -89,6 +121,14 @@ static unsigned char** find_nop_table(void) return noptable; } +#endif /* CONFIG_X86_64 */ + +extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; +extern struct alt_instr __smp_alt_instructions[], __smp_alt_instructions_end[]; +extern u8 *__smp_locks[], *__smp_locks_end[]; + +extern u8 __smp_alt_begin[], __smp_alt_end[]; + /* Replace instructions with better alternatives for this CPU type. This runs before SMP is initialized to avoid SMP problems with self modifying code. This implies that assymetric systems where @@ -99,6 +139,7 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end) { unsigned char **noptable = find_nop_table(); struct alt_instr *a; + u8 *instr; int diff, i, k; DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end); @@ -106,7 +147,16 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end) BUG_ON(a->replacementlen > a->instrlen); if (!boot_cpu_has(a->cpuid)) continue; - memcpy(a->instr, a->replacement, a->replacementlen); + instr = a->instr; +#ifdef CONFIG_X86_64 + /* vsyscall code is not mapped yet. resolve it manually. */ + if (instr >= (u8 *)VSYSCALL_START && instr < (u8*)VSYSCALL_END) { + instr = __va(instr - (u8*)VSYSCALL_START + (u8*)__pa_symbol(&__vsyscall_0)); + DPRINTK("%s: vsyscall fixup: %p => %p\n", + __FUNCTION__, a->instr, instr); + } +#endif + memcpy(instr, a->replacement, a->replacementlen); diff = a->instrlen - a->replacementlen; /* Pad the rest with nops */ for (i = a->replacementlen; diff > 0; diff -= k, i += k) { @@ -186,14 +236,6 @@ struct smp_alt_module { static LIST_HEAD(smp_alt_modules); static DEFINE_SPINLOCK(smp_alt); -static int smp_alt_once = 0; -static int __init bootonly(char *str) -{ - smp_alt_once = 1; - return 1; -} -__setup("smp-alt-boot", bootonly); - void alternatives_smp_module_add(struct module *mod, char *name, void *locks, void *locks_end, void *text, void *text_end) @@ -201,6 +243,9 @@ void alternatives_smp_module_add(struct module *mod, char *name, struct smp_alt_module *smp; unsigned long flags; + if (no_replacement) + return; + if (smp_alt_once) { if (boot_cpu_has(X86_FEATURE_UP)) alternatives_smp_unlock(locks, locks_end, @@ -235,7 +280,7 @@ void alternatives_smp_module_del(struct module *mod) struct smp_alt_module *item; unsigned long flags; - if (smp_alt_once) + if (no_replacement || smp_alt_once) return; spin_lock_irqsave(&smp_alt, flags); @@ -256,7 +301,7 @@ void alternatives_smp_switch(int smp) struct smp_alt_module *mod; unsigned long flags; - if (smp_alt_once) + if (no_replacement || smp_alt_once) return; BUG_ON(!smp && (num_online_cpus() > 1)); @@ -285,6 +330,13 @@ void alternatives_smp_switch(int smp) void __init alternative_instructions(void) { + if (no_replacement) { + printk(KERN_INFO "(SMP-)alternatives turned off\n"); + free_init_pages("SMP alternatives", + (unsigned long)__smp_alt_begin, + (unsigned long)__smp_alt_end); + return; + } apply_alternatives(__alt_instructions, __alt_instructions_end); /* switch to patch-once-at-boottime-only mode and free the diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 5ab59c12335..7ce09492fc0 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -36,6 +36,7 @@ #include <asm/arch_hooks.h> #include <asm/hpet.h> #include <asm/i8253.h> +#include <asm/nmi.h> #include <mach_apic.h> #include <mach_apicdef.h> @@ -156,7 +157,7 @@ void clear_local_APIC(void) maxlvt = get_maxlvt(); /* - * Masking an LVT entry on a P6 can trigger a local APIC error + * Masking an LVT entry can trigger a local APIC error * if the vector is zero. Mask LVTERR first to prevent this. */ if (maxlvt >= 3) { @@ -1117,7 +1118,18 @@ void disable_APIC_timer(void) unsigned long v; v = apic_read(APIC_LVTT); - apic_write_around(APIC_LVTT, v | APIC_LVT_MASKED); + /* + * When an illegal vector value (0-15) is written to an LVT + * entry and delivery mode is Fixed, the APIC may signal an + * illegal vector error, with out regard to whether the mask + * bit is set or whether an interrupt is actually seen on input. + * + * Boot sequence might call this function when the LVTT has + * '0' vector value. So make sure vector field is set to + * valid value. + */ + v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); + apic_write_around(APIC_LVTT, v); } } diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index 9e819eb6822..7c5729d1fd0 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -764,9 +764,9 @@ static int apm_do_idle(void) int idled = 0; int polling; - polling = test_thread_flag(TIF_POLLING_NRFLAG); + polling = !!(current_thread_info()->status & TS_POLLING); if (polling) { - clear_thread_flag(TIF_POLLING_NRFLAG); + current_thread_info()->status &= ~TS_POLLING; smp_mb__after_clear_bit(); } if (!need_resched()) { @@ -774,7 +774,7 @@ static int apm_do_idle(void) ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax); } if (polling) - set_thread_flag(TIF_POLLING_NRFLAG); + current_thread_info()->status |= TS_POLLING; if (!idled) return 0; diff --git a/arch/i386/kernel/asm-offsets.c b/arch/i386/kernel/asm-offsets.c index 36d66e2077d..c80271f8f08 100644 --- a/arch/i386/kernel/asm-offsets.c +++ b/arch/i386/kernel/asm-offsets.c @@ -4,6 +4,7 @@ * to extract and format the required data. */ +#include <linux/crypto.h> #include <linux/sched.h> #include <linux/signal.h> #include <linux/personality.h> @@ -13,6 +14,7 @@ #include <asm/fixmap.h> #include <asm/processor.h> #include <asm/thread_info.h> +#include <asm/elf.h> #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) @@ -53,6 +55,7 @@ void foo(void) OFFSET(TI_preempt_count, thread_info, preempt_count); OFFSET(TI_addr_limit, thread_info, addr_limit); OFFSET(TI_restart_block, thread_info, restart_block); + OFFSET(TI_sysenter_return, thread_info, sysenter_return); BLANK(); OFFSET(EXEC_DOMAIN_handler, exec_domain, handler); @@ -68,5 +71,7 @@ void foo(void) sizeof(struct tss_struct)); DEFINE(PAGE_SIZE_asm, PAGE_SIZE); - DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL)); + DEFINE(VDSO_PRELINK, VDSO_PRELINK); + + OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx); } diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c index 786d1a57048..e6a2d6b80cd 100644 --- a/arch/i386/kernel/cpu/amd.c +++ b/arch/i386/kernel/cpu/amd.c @@ -224,22 +224,26 @@ static void __init init_amd(struct cpuinfo_x86 *c) #ifdef CONFIG_X86_HT /* - * On a AMD dual core setup the lower bits of the APIC id - * distingush the cores. Assumes number of cores is a power - * of two. + * On a AMD multi core setup the lower bits of the APIC id + * distingush the cores. */ if (c->x86_max_cores > 1) { int cpu = smp_processor_id(); - unsigned bits = 0; - while ((1 << bits) < c->x86_max_cores) - bits++; - cpu_core_id[cpu] = phys_proc_id[cpu] & ((1<<bits)-1); - phys_proc_id[cpu] >>= bits; + unsigned bits = (cpuid_ecx(0x80000008) >> 12) & 0xf; + + if (bits == 0) { + while ((1 << bits) < c->x86_max_cores) + bits++; + } + c->cpu_core_id = c->phys_proc_id & ((1<<bits)-1); + c->phys_proc_id >>= bits; printk(KERN_INFO "CPU %d(%d) -> Core %d\n", - cpu, c->x86_max_cores, cpu_core_id[cpu]); + cpu, c->x86_max_cores, c->cpu_core_id); } #endif + if (cpuid_eax(0x80000000) >= 0x80000006) + num_cache_leaves = 3; } static unsigned int amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 44f2c5f2dda..70c87de582c 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -294,7 +294,7 @@ void __cpuinit generic_identify(struct cpuinfo_x86 * c) if (c->x86 >= 0x6) c->x86_model += ((tfms >> 16) & 0xF) << 4; c->x86_mask = tfms & 15; -#ifdef CONFIG_SMP +#ifdef CONFIG_X86_HT c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0); #else c->apicid = (ebx >> 24) & 0xFF; @@ -319,7 +319,7 @@ void __cpuinit generic_identify(struct cpuinfo_x86 * c) early_intel_workaround(c); #ifdef CONFIG_X86_HT - phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff; + c->phys_proc_id = (cpuid_ebx(1) >> 24) & 0xff; #endif } @@ -477,11 +477,9 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c) { u32 eax, ebx, ecx, edx; int index_msb, core_bits; - int cpu = smp_processor_id(); cpuid(1, &eax, &ebx, &ecx, &edx); - if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY)) return; @@ -492,16 +490,17 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c) } else if (smp_num_siblings > 1 ) { if (smp_num_siblings > NR_CPUS) { - printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings); + printk(KERN_WARNING "CPU: Unsupported number of the " + "siblings %d", smp_num_siblings); smp_num_siblings = 1; return; } index_msb = get_count_order(smp_num_siblings); - phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb); + c->phys_proc_id = phys_pkg_id((ebx >> 24) & 0xFF, index_msb); printk(KERN_INFO "CPU: Physical Processor ID: %d\n", - phys_proc_id[cpu]); + c->phys_proc_id); smp_num_siblings = smp_num_siblings / c->x86_max_cores; @@ -509,12 +508,12 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c) core_bits = get_count_order(c->x86_max_cores); - cpu_core_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb) & + c->cpu_core_id = phys_pkg_id((ebx >> 24) & 0xFF, index_msb) & ((1 << core_bits) - 1); if (c->x86_max_cores > 1) printk(KERN_INFO "CPU: Processor Core ID: %d\n", - cpu_core_id[cpu]); + c->cpu_core_id); } } #endif @@ -613,6 +612,12 @@ void __cpuinit cpu_init(void) set_in_cr4(X86_CR4_TSD); } + /* The CPU hotplug case */ + if (cpu_gdt_descr->address) { + gdt = (struct desc_struct *)cpu_gdt_descr->address; + memset(gdt, 0, PAGE_SIZE); + goto old_gdt; + } /* * This is a horrible hack to allocate the GDT. The problem * is that cpu_init() is called really early for the boot CPU @@ -631,7 +636,7 @@ void __cpuinit cpu_init(void) local_irq_enable(); } } - +old_gdt: /* * Initialize the per-CPU GDT with the boot GDT, * and set up the GDT descriptor: diff --git a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c index fc32c8028e2..f03b7f94c30 100644 --- a/arch/i386/kernel/cpu/cyrix.c +++ b/arch/i386/kernel/cpu/cyrix.c @@ -354,7 +354,7 @@ static void __init init_nsc(struct cpuinfo_x86 *c) * This function only handles the GX processor, and kicks every * thing else to the Cyrix init function above - that should * cover any processors that might have been branded differently - * after NSC aquired Cyrix. + * after NSC acquired Cyrix. * * If this breaks your GX1 horribly, please e-mail * info-linux@ldcmail.amd.com to tell us. diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c index 5386b29bb5a..10afc645c54 100644 --- a/arch/i386/kernel/cpu/intel.c +++ b/arch/i386/kernel/cpu/intel.c @@ -122,6 +122,12 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) select_idle_routine(c); l2 = init_intel_cacheinfo(c); + if (c->cpuid_level > 9 ) { + unsigned eax = cpuid_eax(10); + /* Check for version and the number of counters */ + if ((eax & 0xff) && (((eax>>8) & 0xff) > 1)) + set_bit(X86_FEATURE_ARCH_PERFMON, c->x86_capability); + } /* SEP CPUID bug: Pentium Pro reports SEP but doesn't have it until model 3 mask 3 */ if ((c->x86<<8 | c->x86_model<<4 | c->x86_mask) < 0x633) diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c index c8547a6fa7e..e9f0b928b0a 100644 --- a/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/arch/i386/kernel/cpu/intel_cacheinfo.c @@ -4,6 +4,7 @@ * Changes: * Venkatesh Pallipadi : Adding cache identification through cpuid(4) * Ashok Raj <ashok.raj@intel.com>: Work with CPU hotplug infrastructure. + * Andi Kleen : CPUID4 emulation on AMD. */ #include <linux/init.h> @@ -130,25 +131,111 @@ struct _cpuid4_info { cpumask_t shared_cpu_map; }; -static unsigned short num_cache_leaves; +unsigned short num_cache_leaves; + +/* AMD doesn't have CPUID4. Emulate it here to report the same + information to the user. This makes some assumptions about the machine: + No L3, L2 not shared, no SMT etc. that is currently true on AMD CPUs. + + In theory the TLBs could be reported as fake type (they are in "dummy"). + Maybe later */ +union l1_cache { + struct { + unsigned line_size : 8; + unsigned lines_per_tag : 8; + unsigned assoc : 8; + unsigned size_in_kb : 8; + }; + unsigned val; +}; + +union l2_cache { + struct { + unsigned line_size : 8; + unsigned lines_per_tag : 4; + unsigned assoc : 4; + unsigned size_in_kb : 16; + }; + unsigned val; +}; + +static const unsigned short assocs[] = { + [1] = 1, [2] = 2, [4] = 4, [6] = 8, + [8] = 16, + [0xf] = 0xffff // ?? + }; +static const unsigned char levels[] = { 1, 1, 2 }; +static const unsigned char types[] = { 1, 2, 3 }; + +static void __cpuinit amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax, + union _cpuid4_leaf_ebx *ebx, + union _cpuid4_leaf_ecx *ecx) +{ + unsigned dummy; + unsigned line_size, lines_per_tag, assoc, size_in_kb; + union l1_cache l1i, l1d; + union l2_cache l2; + + eax->full = 0; + ebx->full = 0; + ecx->full = 0; + + cpuid(0x80000005, &dummy, &dummy, &l1d.val, &l1i.val); + cpuid(0x80000006, &dummy, &dummy, &l2.val, &dummy); + + if (leaf > 2 || !l1d.val || !l1i.val || !l2.val) + return; + + eax->split.is_self_initializing = 1; + eax->split.type = types[leaf]; + eax->split.level = levels[leaf]; + eax->split.num_threads_sharing = 0; + eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1; + + if (leaf <= 1) { + union l1_cache *l1 = leaf == 0 ? &l1d : &l1i; + assoc = l1->assoc; + line_size = l1->line_size; + lines_per_tag = l1->lines_per_tag; + size_in_kb = l1->size_in_kb; + } else { + assoc = l2.assoc; + line_size = l2.line_size; + lines_per_tag = l2.lines_per_tag; + /* cpu_data has errata corrections for K7 applied */ + size_in_kb = current_cpu_data.x86_cache_size; + } + + if (assoc == 0xf) + eax->split.is_fully_associative = 1; + ebx->split.coherency_line_size = line_size - 1; + ebx->split.ways_of_associativity = assocs[assoc] - 1; + ebx->split.physical_line_partition = lines_per_tag - 1; + ecx->split.number_of_sets = (size_in_kb * 1024) / line_size / + (ebx->split.ways_of_associativity + 1) - 1; +} static int __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) { - unsigned int eax, ebx, ecx, edx; - union _cpuid4_leaf_eax cache_eax; + union _cpuid4_leaf_eax eax; + union _cpuid4_leaf_ebx ebx; + union _cpuid4_leaf_ecx ecx; + unsigned edx; - cpuid_count(4, index, &eax, &ebx, &ecx, &edx); - cache_eax.full = eax; - if (cache_eax.split.type == CACHE_TYPE_NULL) + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) + amd_cpuid4(index, &eax, &ebx, &ecx); + else + cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx); + if (eax.split.type == CACHE_TYPE_NULL) return -EIO; /* better error ? */ - this_leaf->eax.full = eax; - this_leaf->ebx.full = ebx; - this_leaf->ecx.full = ecx; - this_leaf->size = (this_leaf->ecx.split.number_of_sets + 1) * - (this_leaf->ebx.split.coherency_line_size + 1) * - (this_leaf->ebx.split.physical_line_partition + 1) * - (this_leaf->ebx.split.ways_of_associativity + 1); + this_leaf->eax = eax; + this_leaf->ebx = ebx; + this_leaf->ecx = ecx; + this_leaf->size = (ecx.split.number_of_sets + 1) * + (ebx.split.coherency_line_size + 1) * + (ebx.split.physical_line_partition + 1) * + (ebx.split.ways_of_associativity + 1); return 0; } @@ -174,7 +261,7 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */ unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb; -#ifdef CONFIG_SMP +#ifdef CONFIG_X86_HT unsigned int cpu = (c == &boot_cpu_data) ? 0 : (c - cpu_data); #endif @@ -296,14 +383,14 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) if (new_l2) { l2 = new_l2; -#ifdef CONFIG_SMP +#ifdef CONFIG_X86_HT cpu_llc_id[cpu] = l2_id; #endif } if (new_l3) { l3 = new_l3; -#ifdef CONFIG_SMP +#ifdef CONFIG_X86_HT cpu_llc_id[cpu] = l3_id; #endif } @@ -642,7 +729,7 @@ static void __cpuexit cache_remove_dev(struct sys_device * sys_dev) return; } -static int cacheinfo_cpu_callback(struct notifier_block *nfb, +static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; @@ -660,7 +747,7 @@ static int cacheinfo_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block cacheinfo_cpu_notifier = +static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier = { .notifier_call = cacheinfo_cpu_callback, }; diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c index a19fcb262db..f54a15268ed 100644 --- a/arch/i386/kernel/cpu/proc.c +++ b/arch/i386/kernel/cpu/proc.c @@ -18,7 +18,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) * applications want to get the raw CPUID data, they should access * /dev/cpu/<cpu_nr>/cpuid instead. */ - static char *x86_cap_flags[] = { + static const char * const x86_cap_flags[] = { /* Intel-defined */ "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov", @@ -62,7 +62,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; - static char *x86_power_flags[] = { + static const char * const x86_power_flags[] = { "ts", /* temperature sensor */ "fid", /* frequency id control */ "vid", /* voltage id control */ @@ -109,9 +109,9 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size); #ifdef CONFIG_X86_HT if (c->x86_max_cores * smp_num_siblings > 1) { - seq_printf(m, "physical id\t: %d\n", phys_proc_id[n]); + seq_printf(m, "physical id\t: %d\n", c->phys_proc_id); seq_printf(m, "siblings\t: %d\n", cpus_weight(cpu_core_map[n])); - seq_printf(m, "core id\t\t: %d\n", cpu_core_id[n]); + seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id); seq_printf(m, "cpu cores\t: %d\n", c->booted_cores); } #endif diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c index 1d9a4abcdfc..f6dfa9fb675 100644 --- a/arch/i386/kernel/cpuid.c +++ b/arch/i386/kernel/cpuid.c @@ -183,7 +183,7 @@ static int cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long ac return NOTIFY_OK; } -static struct notifier_block cpuid_class_cpu_notifier = +static struct notifier_block __cpuinitdata cpuid_class_cpu_notifier = { .notifier_call = cpuid_class_cpu_callback, }; diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c index 21dc1bbb806..48f0f62f781 100644 --- a/arch/i386/kernel/crash.c +++ b/arch/i386/kernel/crash.c @@ -120,14 +120,9 @@ static int crash_nmi_callback(struct pt_regs *regs, int cpu) return 1; } -/* - * By using the NMI code instead of a vector we just sneak thru the - * word generator coming out with just what we want. AND it does - * not matter if clustered_apic_mode is set or not. - */ static void smp_send_nmi_allbutself(void) { - send_IPI_allbutself(APIC_DM_NMI); + send_IPI_allbutself(NMI_VECTOR); } static void nmi_shootdown_cpus(void) @@ -163,7 +158,7 @@ static void nmi_shootdown_cpus(void) void machine_crash_shutdown(struct pt_regs *regs) { /* This function is only called after the system - * has paniced or is otherwise in a critical state. + * has panicked or is otherwise in a critical state. * The minimum amount of code to allow a kexec'd kernel * to run successfully needs to happen here. * diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c index 9202b67c4b2..8beb0f07d99 100644 --- a/arch/i386/kernel/efi.c +++ b/arch/i386/kernel/efi.c @@ -601,8 +601,10 @@ efi_initialize_iomem_resources(struct resource *code_resource, res->end = res->start + ((md->num_pages << EFI_PAGE_SHIFT) - 1); res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; if (request_resource(&iomem_resource, res) < 0) - printk(KERN_ERR PFX "Failed to allocate res %s : 0x%lx-0x%lx\n", - res->name, res->start, res->end); + printk(KERN_ERR PFX "Failed to allocate res %s : " + "0x%llx-0x%llx\n", res->name, + (unsigned long long)res->start, + (unsigned long long)res->end); /* * We don't know which region contains kernel data so we try * it repeatedly and let the resource manager test it. diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index cfc683f153b..fbdb933251b 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -48,6 +48,7 @@ #include <asm/smp.h> #include <asm/page.h> #include <asm/desc.h> +#include <asm/dwarf2.h> #include "irq_vectors.h" #define nr_syscalls ((syscall_table_size)/4) @@ -82,34 +83,76 @@ VM_MASK = 0x00020000 #define resume_kernel restore_nocheck #endif +#ifdef CONFIG_VM86 +#define resume_userspace_sig check_userspace +#else +#define resume_userspace_sig resume_userspace +#endif + #define SAVE_ALL \ cld; \ pushl %es; \ + CFI_ADJUST_CFA_OFFSET 4;\ + /*CFI_REL_OFFSET es, 0;*/\ pushl %ds; \ + CFI_ADJUST_CFA_OFFSET 4;\ + /*CFI_REL_OFFSET ds, 0;*/\ pushl %eax; \ + CFI_ADJUST_CFA_OFFSET 4;\ + CFI_REL_OFFSET eax, 0;\ pushl %ebp; \ + CFI_ADJUST_CFA_OFFSET 4;\ + CFI_REL_OFFSET ebp, 0;\ pushl %edi; \ + CFI_ADJUST_CFA_OFFSET 4;\ + CFI_REL_OFFSET edi, 0;\ pushl %esi; \ + CFI_ADJUST_CFA_OFFSET 4;\ + CFI_REL_OFFSET esi, 0;\ pushl %edx; \ + CFI_ADJUST_CFA_OFFSET 4;\ + CFI_REL_OFFSET edx, 0;\ pushl %ecx; \ + CFI_ADJUST_CFA_OFFSET 4;\ + CFI_REL_OFFSET ecx, 0;\ pushl %ebx; \ + CFI_ADJUST_CFA_OFFSET 4;\ + CFI_REL_OFFSET ebx, 0;\ movl $(__USER_DS), %edx; \ movl %edx, %ds; \ movl %edx, %es; #define RESTORE_INT_REGS \ popl %ebx; \ + CFI_ADJUST_CFA_OFFSET -4;\ + CFI_RESTORE ebx;\ popl %ecx; \ + CFI_ADJUST_CFA_OFFSET -4;\ + CFI_RESTORE ecx;\ popl %edx; \ + CFI_ADJUST_CFA_OFFSET -4;\ + CFI_RESTORE edx;\ popl %esi; \ + CFI_ADJUST_CFA_OFFSET -4;\ + CFI_RESTORE esi;\ popl %edi; \ + CFI_ADJUST_CFA_OFFSET -4;\ + CFI_RESTORE edi;\ popl %ebp; \ - popl %eax + CFI_ADJUST_CFA_OFFSET -4;\ + CFI_RESTORE ebp;\ + popl %eax; \ + CFI_ADJUST_CFA_OFFSET -4;\ + CFI_RESTORE eax #define RESTORE_REGS \ RESTORE_INT_REGS; \ 1: popl %ds; \ + CFI_ADJUST_CFA_OFFSET -4;\ + /*CFI_RESTORE ds;*/\ 2: popl %es; \ + CFI_ADJUST_CFA_OFFSET -4;\ + /*CFI_RESTORE es;*/\ .section .fixup,"ax"; \ 3: movl $0,(%esp); \ jmp 1b; \ @@ -122,13 +165,43 @@ VM_MASK = 0x00020000 .long 2b,4b; \ .previous +#define RING0_INT_FRAME \ + CFI_STARTPROC simple;\ + CFI_DEF_CFA esp, 3*4;\ + /*CFI_OFFSET cs, -2*4;*/\ + CFI_OFFSET eip, -3*4 + +#define RING0_EC_FRAME \ + CFI_STARTPROC simple;\ + CFI_DEF_CFA esp, 4*4;\ + /*CFI_OFFSET cs, -2*4;*/\ + CFI_OFFSET eip, -3*4 + +#define RING0_PTREGS_FRAME \ + CFI_STARTPROC simple;\ + CFI_DEF_CFA esp, OLDESP-EBX;\ + /*CFI_OFFSET cs, CS-OLDESP;*/\ + CFI_OFFSET eip, EIP-OLDESP;\ + /*CFI_OFFSET es, ES-OLDESP;*/\ + /*CFI_OFFSET ds, DS-OLDESP;*/\ + CFI_OFFSET eax, EAX-OLDESP;\ + CFI_OFFSET ebp, EBP-OLDESP;\ + CFI_OFFSET edi, EDI-OLDESP;\ + CFI_OFFSET esi, ESI-OLDESP;\ + CFI_OFFSET edx, EDX-OLDESP;\ + CFI_OFFSET ecx, ECX-OLDESP;\ + CFI_OFFSET ebx, EBX-OLDESP ENTRY(ret_from_fork) + CFI_STARTPROC pushl %eax + CFI_ADJUST_CFA_OFFSET -4 call schedule_tail GET_THREAD_INFO(%ebp) popl %eax + CFI_ADJUST_CFA_OFFSET -4 jmp syscall_exit + CFI_ENDPROC /* * Return to user mode is not as complex as all this looks, @@ -139,10 +212,12 @@ ENTRY(ret_from_fork) # userspace resumption stub bypassing syscall exit tracing ALIGN + RING0_PTREGS_FRAME ret_from_exception: preempt_stop ret_from_intr: GET_THREAD_INFO(%ebp) +check_userspace: movl EFLAGS(%esp), %eax # mix EFLAGS and CS movb CS(%esp), %al testl $(VM_MASK | 3), %eax @@ -171,20 +246,38 @@ need_resched: call preempt_schedule_irq jmp need_resched #endif + CFI_ENDPROC /* SYSENTER_RETURN points to after the "sysenter" instruction in the vsyscall page. See vsyscall-sysentry.S, which defines the symbol. */ # sysenter call handler stub ENTRY(sysenter_entry) + CFI_STARTPROC simple + CFI_DEF_CFA esp, 0 + CFI_REGISTER esp, ebp movl TSS_sysenter_esp0(%esp),%esp sysenter_past_esp: sti pushl $(__USER_DS) + CFI_ADJUST_CFA_OFFSET 4 + /*CFI_REL_OFFSET ss, 0*/ pushl %ebp + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET esp, 0 pushfl + CFI_ADJUST_CFA_OFFSET 4 pushl $(__USER_CS) - pushl $SYSENTER_RETURN + CFI_ADJUST_CFA_OFFSET 4 + /*CFI_REL_OFFSET cs, 0*/ + /* + * Push current_thread_info()->sysenter_return to the stack. + * A tiny bit of offset fixup is necessary - 4*4 means the 4 words + * pushed above; +8 corresponds to copy_thread's esp0 setting. + */ + pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp) + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET eip, 0 /* * Load the potential sixth argument from user stack. @@ -199,6 +292,7 @@ sysenter_past_esp: .previous pushl %eax + CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL GET_THREAD_INFO(%ebp) @@ -219,11 +313,14 @@ sysenter_past_esp: xorl %ebp,%ebp sti sysexit + CFI_ENDPROC # system call handler stub ENTRY(system_call) + RING0_INT_FRAME # can't unwind into user space anyway pushl %eax # save orig_eax + CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL GET_THREAD_INFO(%ebp) testl $TF_MASK,EFLAGS(%esp) @@ -256,10 +353,12 @@ restore_all: movb CS(%esp), %al andl $(VM_MASK | (4 << 8) | 3), %eax cmpl $((4 << 8) | 3), %eax + CFI_REMEMBER_STATE je ldt_ss # returning to user-space with LDT SS restore_nocheck: RESTORE_REGS addl $4, %esp + CFI_ADJUST_CFA_OFFSET -4 1: iret .section .fixup,"ax" iret_exc: @@ -273,6 +372,7 @@ iret_exc: .long 1b,iret_exc .previous + CFI_RESTORE_STATE ldt_ss: larl OLDSS(%esp), %eax jnz restore_nocheck @@ -285,11 +385,13 @@ ldt_ss: * CPUs, which we can try to work around to make * dosemu and wine happy. */ subl $8, %esp # reserve space for switch16 pointer + CFI_ADJUST_CFA_OFFSET 8 cli movl %esp, %eax /* Set up the 16bit stack frame with switch32 pointer on top, * and a switch16 pointer on top of the current frame. */ call setup_x86_bogus_stack + CFI_ADJUST_CFA_OFFSET -8 # frame has moved RESTORE_REGS lss 20+4(%esp), %esp # switch to 16bit stack 1: iret @@ -297,9 +399,11 @@ ldt_ss: .align 4 .long 1b,iret_exc .previous + CFI_ENDPROC # perform work that needs to be done immediately before resumption ALIGN + RING0_PTREGS_FRAME # can't unwind into user space anyway work_pending: testb $_TIF_NEED_RESCHED, %cl jz work_notifysig @@ -323,18 +427,20 @@ work_notifysig: # deal with pending signals and # vm86-space xorl %edx, %edx call do_notify_resume - jmp resume_userspace + jmp resume_userspace_sig ALIGN work_notifysig_v86: #ifdef CONFIG_VM86 pushl %ecx # save ti_flags for do_notify_resume + CFI_ADJUST_CFA_OFFSET 4 call save_v86_state # %eax contains pt_regs pointer popl %ecx + CFI_ADJUST_CFA_OFFSET -4 movl %eax, %esp xorl %edx, %edx call do_notify_resume - jmp resume_userspace + jmp resume_userspace_sig #endif # perform syscall exit tracing @@ -363,19 +469,21 @@ syscall_exit_work: movl $1, %edx call do_syscall_trace jmp resume_userspace + CFI_ENDPROC - ALIGN + RING0_INT_FRAME # can't unwind into user space anyway syscall_fault: pushl %eax # save orig_eax + CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL GET_THREAD_INFO(%ebp) movl $-EFAULT,EAX(%esp) jmp resume_userspace - ALIGN syscall_badsys: movl $-ENOSYS,EAX(%esp) jmp resume_userspace + CFI_ENDPROC #define FIXUP_ESPFIX_STACK \ movl %esp, %eax; \ @@ -387,16 +495,21 @@ syscall_badsys: movl %eax, %esp; #define UNWIND_ESPFIX_STACK \ pushl %eax; \ + CFI_ADJUST_CFA_OFFSET 4; \ movl %ss, %eax; \ /* see if on 16bit stack */ \ cmpw $__ESPFIX_SS, %ax; \ - jne 28f; \ - movl $__KERNEL_DS, %edx; \ - movl %edx, %ds; \ - movl %edx, %es; \ + je 28f; \ +27: popl %eax; \ + CFI_ADJUST_CFA_OFFSET -4; \ +.section .fixup,"ax"; \ +28: movl $__KERNEL_DS, %eax; \ + movl %eax, %ds; \ + movl %eax, %es; \ /* switch to 32bit stack */ \ - FIXUP_ESPFIX_STACK \ -28: popl %eax; + FIXUP_ESPFIX_STACK; \ + jmp 27b; \ +.previous /* * Build the entry stubs and pointer table with @@ -408,9 +521,14 @@ ENTRY(interrupt) vector=0 ENTRY(irq_entries_start) + RING0_INT_FRAME .rept NR_IRQS ALIGN -1: pushl $vector-256 + .if vector + CFI_ADJUST_CFA_OFFSET -4 + .endif +1: pushl $~(vector) + CFI_ADJUST_CFA_OFFSET 4 jmp common_interrupt .data .long 1b @@ -424,60 +542,99 @@ common_interrupt: movl %esp,%eax call do_IRQ jmp ret_from_intr + CFI_ENDPROC #define BUILD_INTERRUPT(name, nr) \ ENTRY(name) \ - pushl $nr-256; \ - SAVE_ALL \ + RING0_INT_FRAME; \ + pushl $~(nr); \ + CFI_ADJUST_CFA_OFFSET 4; \ + SAVE_ALL; \ movl %esp,%eax; \ call smp_/**/name; \ - jmp ret_from_intr; + jmp ret_from_intr; \ + CFI_ENDPROC /* The include is where all of the SMP etc. interrupts come from */ #include "entry_arch.h" ENTRY(divide_error) + RING0_INT_FRAME pushl $0 # no error code + CFI_ADJUST_CFA_OFFSET 4 pushl $do_divide_error + CFI_ADJUST_CFA_OFFSET 4 ALIGN error_code: pushl %ds + CFI_ADJUST_CFA_OFFSET 4 + /*CFI_REL_OFFSET ds, 0*/ pushl %eax + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET eax, 0 xorl %eax, %eax pushl %ebp + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ebp, 0 pushl %edi + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET edi, 0 pushl %esi + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET esi, 0 pushl %edx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET edx, 0 decl %eax # eax = -1 pushl %ecx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ecx, 0 pushl %ebx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ebx, 0 cld pushl %es + CFI_ADJUST_CFA_OFFSET 4 + /*CFI_REL_OFFSET es, 0*/ UNWIND_ESPFIX_STACK popl %ecx + CFI_ADJUST_CFA_OFFSET -4 + /*CFI_REGISTER es, ecx*/ movl ES(%esp), %edi # get the function address movl ORIG_EAX(%esp), %edx # get the error code movl %eax, ORIG_EAX(%esp) movl %ecx, ES(%esp) + /*CFI_REL_OFFSET es, ES*/ movl $(__USER_DS), %ecx movl %ecx, %ds movl %ecx, %es movl %esp,%eax # pt_regs pointer call *%edi jmp ret_from_exception + CFI_ENDPROC ENTRY(coprocessor_error) + RING0_INT_FRAME pushl $0 + CFI_ADJUST_CFA_OFFSET 4 pushl $do_coprocessor_error + CFI_ADJUST_CFA_OFFSET 4 jmp error_code + CFI_ENDPROC ENTRY(simd_coprocessor_error) + RING0_INT_FRAME pushl $0 + CFI_ADJUST_CFA_OFFSET 4 pushl $do_simd_coprocessor_error + CFI_ADJUST_CFA_OFFSET 4 jmp error_code + CFI_ENDPROC ENTRY(device_not_available) + RING0_INT_FRAME pushl $-1 # mark this as an int + CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL movl %cr0, %eax testl $0x4, %eax # EM (math emulation bit) @@ -487,9 +644,12 @@ ENTRY(device_not_available) jmp ret_from_exception device_not_available_emulate: pushl $0 # temporary storage for ORIG_EIP + CFI_ADJUST_CFA_OFFSET 4 call math_emulate addl $4, %esp + CFI_ADJUST_CFA_OFFSET -4 jmp ret_from_exception + CFI_ENDPROC /* * Debug traps and NMI can happen at the one SYSENTER instruction @@ -514,16 +674,19 @@ label: \ pushl $sysenter_past_esp KPROBE_ENTRY(debug) + RING0_INT_FRAME cmpl $sysenter_entry,(%esp) jne debug_stack_correct FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn) debug_stack_correct: pushl $-1 # mark this as an int + CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL xorl %edx,%edx # error code 0 movl %esp,%eax # pt_regs pointer call do_debug jmp ret_from_exception + CFI_ENDPROC .previous .text /* * NMI is doubly nasty. It can happen _while_ we're handling @@ -534,14 +697,18 @@ debug_stack_correct: * fault happened on the sysenter path. */ ENTRY(nmi) + RING0_INT_FRAME pushl %eax + CFI_ADJUST_CFA_OFFSET 4 movl %ss, %eax cmpw $__ESPFIX_SS, %ax popl %eax + CFI_ADJUST_CFA_OFFSET -4 je nmi_16bit_stack cmpl $sysenter_entry,(%esp) je nmi_stack_fixup pushl %eax + CFI_ADJUST_CFA_OFFSET 4 movl %esp,%eax /* Do not access memory above the end of our stack page, * it might not exist. @@ -549,16 +716,19 @@ ENTRY(nmi) andl $(THREAD_SIZE-1),%eax cmpl $(THREAD_SIZE-20),%eax popl %eax + CFI_ADJUST_CFA_OFFSET -4 jae nmi_stack_correct cmpl $sysenter_entry,12(%esp) je nmi_debug_stack_check nmi_stack_correct: pushl %eax + CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL xorl %edx,%edx # zero error code movl %esp,%eax # pt_regs pointer call do_nmi jmp restore_all + CFI_ENDPROC nmi_stack_fixup: FIX_STACK(12,nmi_stack_correct, 1) @@ -574,94 +744,177 @@ nmi_debug_stack_check: jmp nmi_stack_correct nmi_16bit_stack: + RING0_INT_FRAME /* create the pointer to lss back */ pushl %ss + CFI_ADJUST_CFA_OFFSET 4 pushl %esp + CFI_ADJUST_CFA_OFFSET 4 movzwl %sp, %esp addw $4, (%esp) /* copy the iret frame of 12 bytes */ .rept 3 pushl 16(%esp) + CFI_ADJUST_CFA_OFFSET 4 .endr pushl %eax + CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL FIXUP_ESPFIX_STACK # %eax == %esp + CFI_ADJUST_CFA_OFFSET -20 # the frame has now moved xorl %edx,%edx # zero error code call do_nmi RESTORE_REGS lss 12+4(%esp), %esp # back to 16bit stack 1: iret + CFI_ENDPROC .section __ex_table,"a" .align 4 .long 1b,iret_exc .previous KPROBE_ENTRY(int3) + RING0_INT_FRAME pushl $-1 # mark this as an int + CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL xorl %edx,%edx # zero error code movl %esp,%eax # pt_regs pointer call do_int3 jmp ret_from_exception + CFI_ENDPROC .previous .text ENTRY(overflow) + RING0_INT_FRAME pushl $0 + CFI_ADJUST_CFA_OFFSET 4 pushl $do_overflow + CFI_ADJUST_CFA_OFFSET 4 jmp error_code + CFI_ENDPROC ENTRY(bounds) + RING0_INT_FRAME pushl $0 + CFI_ADJUST_CFA_OFFSET 4 pushl $do_bounds + CFI_ADJUST_CFA_OFFSET 4 jmp error_code + CFI_ENDPROC ENTRY(invalid_op) + RING0_INT_FRAME pushl $0 + CFI_ADJUST_CFA_OFFSET 4 pushl $do_invalid_op + CFI_ADJUST_CFA_OFFSET 4 jmp error_code + CFI_ENDPROC ENTRY(coprocessor_segment_overrun) + RING0_INT_FRAME pushl $0 + CFI_ADJUST_CFA_OFFSET 4 pushl $do_coprocessor_segment_overrun + CFI_ADJUST_CFA_OFFSET 4 jmp error_code + CFI_ENDPROC ENTRY(invalid_TSS) + RING0_EC_FRAME pushl $do_invalid_TSS + CFI_ADJUST_CFA_OFFSET 4 jmp error_code + CFI_ENDPROC ENTRY(segment_not_present) + RING0_EC_FRAME pushl $do_segment_not_present + CFI_ADJUST_CFA_OFFSET 4 jmp error_code + CFI_ENDPROC ENTRY(stack_segment) + RING0_EC_FRAME pushl $do_stack_segment + CFI_ADJUST_CFA_OFFSET 4 jmp error_code + CFI_ENDPROC KPROBE_ENTRY(general_protection) + RING0_EC_FRAME pushl $do_general_protection + CFI_ADJUST_CFA_OFFSET 4 jmp error_code + CFI_ENDPROC .previous .text ENTRY(alignment_check) + RING0_EC_FRAME pushl $do_alignment_check + CFI_ADJUST_CFA_OFFSET 4 jmp error_code + CFI_ENDPROC KPROBE_ENTRY(page_fault) + RING0_EC_FRAME pushl $do_page_fault + CFI_ADJUST_CFA_OFFSET 4 jmp error_code + CFI_ENDPROC .previous .text #ifdef CONFIG_X86_MCE ENTRY(machine_check) + RING0_INT_FRAME pushl $0 + CFI_ADJUST_CFA_OFFSET 4 pushl machine_check_vector + CFI_ADJUST_CFA_OFFSET 4 jmp error_code + CFI_ENDPROC #endif ENTRY(spurious_interrupt_bug) + RING0_INT_FRAME pushl $0 + CFI_ADJUST_CFA_OFFSET 4 pushl $do_spurious_interrupt_bug + CFI_ADJUST_CFA_OFFSET 4 jmp error_code + CFI_ENDPROC + +#ifdef CONFIG_STACK_UNWIND +ENTRY(arch_unwind_init_running) + CFI_STARTPROC + movl 4(%esp), %edx + movl (%esp), %ecx + leal 4(%esp), %eax + movl %ebx, EBX(%edx) + xorl %ebx, %ebx + movl %ebx, ECX(%edx) + movl %ebx, EDX(%edx) + movl %esi, ESI(%edx) + movl %edi, EDI(%edx) + movl %ebp, EBP(%edx) + movl %ebx, EAX(%edx) + movl $__USER_DS, DS(%edx) + movl $__USER_DS, ES(%edx) + movl %ebx, ORIG_EAX(%edx) + movl %ecx, EIP(%edx) + movl 12(%esp), %ecx + movl $__KERNEL_CS, CS(%edx) + movl %ebx, EFLAGS(%edx) + movl %eax, OLDESP(%edx) + movl 8(%esp), %eax + movl %ecx, 8(%esp) + movl EBX(%edx), %ebx + movl $__KERNEL_DS, OLDSS(%edx) + jmpl *%eax + CFI_ENDPROC +ENDPROC(arch_unwind_init_running) +#endif .section .rodata,"a" #include "syscall_table.S" diff --git a/arch/i386/kernel/hpet.c b/arch/i386/kernel/hpet.c new file mode 100644 index 00000000000..c6737c35815 --- /dev/null +++ b/arch/i386/kernel/hpet.c @@ -0,0 +1,67 @@ +#include <linux/clocksource.h> +#include <linux/errno.h> +#include <linux/hpet.h> +#include <linux/init.h> + +#include <asm/hpet.h> +#include <asm/io.h> + +#define HPET_MASK CLOCKSOURCE_MASK(32) +#define HPET_SHIFT 22 + +/* FSEC = 10^-15 NSEC = 10^-9 */ +#define FSEC_PER_NSEC 1000000 + +static void *hpet_ptr; + +static cycle_t read_hpet(void) +{ + return (cycle_t)readl(hpet_ptr); +} + +static struct clocksource clocksource_hpet = { + .name = "hpet", + .rating = 250, + .read = read_hpet, + .mask = HPET_MASK, + .mult = 0, /* set below */ + .shift = HPET_SHIFT, + .is_continuous = 1, +}; + +static int __init init_hpet_clocksource(void) +{ + unsigned long hpet_period; + void __iomem* hpet_base; + u64 tmp; + + if (!hpet_address) + return -ENODEV; + + /* calculate the hpet address: */ + hpet_base = + (void __iomem*)ioremap_nocache(hpet_address, HPET_MMAP_SIZE); + hpet_ptr = hpet_base + HPET_COUNTER; + + /* calculate the frequency: */ + hpet_period = readl(hpet_base + HPET_PERIOD); + + /* + * hpet period is in femto seconds per cycle + * so we need to convert this to ns/cyc units + * aproximated by mult/2^shift + * + * fsec/cyc * 1nsec/1000000fsec = nsec/cyc = mult/2^shift + * fsec/cyc * 1ns/1000000fsec * 2^shift = mult + * fsec/cyc * 2^shift * 1nsec/1000000fsec = mult + * (fsec/cyc << shift)/1000000 = mult + * (hpet_period << shift)/FSEC_PER_NSEC = mult + */ + tmp = (u64)hpet_period << HPET_SHIFT; + do_div(tmp, FSEC_PER_NSEC); + clocksource_hpet.mult = (u32)tmp; + + return clocksource_register(&clocksource_hpet); +} + +module_init(init_hpet_clocksource); diff --git a/arch/i386/kernel/i8253.c b/arch/i386/kernel/i8253.c new file mode 100644 index 00000000000..477b24daff5 --- /dev/null +++ b/arch/i386/kernel/i8253.c @@ -0,0 +1,118 @@ +/* + * i8253.c 8253/PIT functions + * + */ +#include <linux/clocksource.h> +#include <linux/spinlock.h> +#include <linux/jiffies.h> +#include <linux/sysdev.h> +#include <linux/module.h> +#include <linux/init.h> + +#include <asm/smp.h> +#include <asm/delay.h> +#include <asm/i8253.h> +#include <asm/io.h> + +#include "io_ports.h" + +DEFINE_SPINLOCK(i8253_lock); +EXPORT_SYMBOL(i8253_lock); + +void setup_pit_timer(void) +{ + unsigned long flags; + + spin_lock_irqsave(&i8253_lock, flags); + outb_p(0x34,PIT_MODE); /* binary, mode 2, LSB/MSB, ch 0 */ + udelay(10); + outb_p(LATCH & 0xff , PIT_CH0); /* LSB */ + udelay(10); + outb(LATCH >> 8 , PIT_CH0); /* MSB */ + spin_unlock_irqrestore(&i8253_lock, flags); +} + +/* + * Since the PIT overflows every tick, its not very useful + * to just read by itself. So use jiffies to emulate a free + * running counter: + */ +static cycle_t pit_read(void) +{ + unsigned long flags; + int count; + u32 jifs; + static int old_count; + static u32 old_jifs; + + spin_lock_irqsave(&i8253_lock, flags); + /* + * Although our caller may have the read side of xtime_lock, + * this is now a seqlock, and we are cheating in this routine + * by having side effects on state that we cannot undo if + * there is a collision on the seqlock and our caller has to + * retry. (Namely, old_jifs and old_count.) So we must treat + * jiffies as volatile despite the lock. We read jiffies + * before latching the timer count to guarantee that although + * the jiffies value might be older than the count (that is, + * the counter may underflow between the last point where + * jiffies was incremented and the point where we latch the + * count), it cannot be newer. + */ + jifs = jiffies; + outb_p(0x00, PIT_MODE); /* latch the count ASAP */ + count = inb_p(PIT_CH0); /* read the latched count */ + count |= inb_p(PIT_CH0) << 8; + + /* VIA686a test code... reset the latch if count > max + 1 */ + if (count > LATCH) { + outb_p(0x34, PIT_MODE); + outb_p(LATCH & 0xff, PIT_CH0); + outb(LATCH >> 8, PIT_CH0); + count = LATCH - 1; + } + + /* + * It's possible for count to appear to go the wrong way for a + * couple of reasons: + * + * 1. The timer counter underflows, but we haven't handled the + * resulting interrupt and incremented jiffies yet. + * 2. Hardware problem with the timer, not giving us continuous time, + * the counter does small "jumps" upwards on some Pentium systems, + * (see c't 95/10 page 335 for Neptun bug.) + * + * Previous attempts to handle these cases intelligently were + * buggy, so we just do the simple thing now. + */ + if (count > old_count && jifs == old_jifs) { + count = old_count; + } + old_count = count; + old_jifs = jifs; + + spin_unlock_irqrestore(&i8253_lock, flags); + + count = (LATCH - 1) - count; + + return (cycle_t)(jifs * LATCH) + count; +} + +static struct clocksource clocksource_pit = { + .name = "pit", + .rating = 110, + .read = pit_read, + .mask = CLOCKSOURCE_MASK(32), + .mult = 0, + .shift = 20, +}; + +static int __init init_pit_clocksource(void) +{ + if (num_possible_cpus() > 4) /* PIT does not scale! */ + return 0; + + clocksource_pit.mult = clocksource_hz2mult(CLOCK_TICK_RATE, 20); + return clocksource_register(&clocksource_pit); +} +module_init(init_pit_clocksource); diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c index b7636b96e10..3c6063671a9 100644 --- a/arch/i386/kernel/i8259.c +++ b/arch/i386/kernel/i8259.c @@ -132,7 +132,7 @@ void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); io_apic_irqs &= ~(1<<irq); - irq_desc[irq].handler = &i8259A_irq_type; + irq_desc[irq].chip = &i8259A_irq_type; enable_irq(irq); } @@ -175,7 +175,7 @@ static void mask_and_ack_8259A(unsigned int irq) * Lightweight spurious IRQ detection. We do not want * to overdo spurious IRQ handling - it's usually a sign * of hardware problems, so we only do the checks we can - * do without slowing down good hardware unnecesserily. + * do without slowing down good hardware unnecessarily. * * Note that IRQ7 and IRQ15 (the two spurious IRQs * usually resulting from the 8259A-1|2 PICs) occur @@ -386,12 +386,12 @@ void __init init_ISA_irqs (void) /* * 16 old-style INTA-cycle interrupts: */ - irq_desc[i].handler = &i8259A_irq_type; + irq_desc[i].chip = &i8259A_irq_type; } else { /* * 'high' PCI IRQs filled in on demand */ - irq_desc[i].handler = &no_irq_type; + irq_desc[i].chip = &no_irq_type; } } } diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index a62df3e764c..ec9ea0269d3 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -38,6 +38,7 @@ #include <asm/desc.h> #include <asm/timer.h> #include <asm/i8259.h> +#include <asm/nmi.h> #include <mach_apic.h> @@ -50,6 +51,7 @@ atomic_t irq_mis_count; static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; static DEFINE_SPINLOCK(ioapic_lock); +static DEFINE_SPINLOCK(vector_lock); int timer_over_8254 __initdata = 1; @@ -579,7 +581,7 @@ static int balanced_irq(void *unused) /* push everything to CPU 0 to give us a starting point. */ for (i = 0 ; i < NR_IRQS ; i++) { - pending_irq_cpumask[i] = cpumask_of_cpu(0); + irq_desc[i].pending_mask = cpumask_of_cpu(0); set_pending_irq(i, cpumask_of_cpu(0)); } @@ -1161,10 +1163,17 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; int assign_irq_vector(int irq) { static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; + unsigned long flags; + int vector; + + BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS); - BUG_ON(irq >= NR_IRQ_VECTORS); - if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) + spin_lock_irqsave(&vector_lock, flags); + + if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) { + spin_unlock_irqrestore(&vector_lock, flags); return IO_APIC_VECTOR(irq); + } next: current_vector += 8; if (current_vector == SYSCALL_VECTOR) @@ -1172,16 +1181,21 @@ next: if (current_vector >= FIRST_SYSTEM_VECTOR) { offset++; - if (!(offset%8)) + if (!(offset%8)) { + spin_unlock_irqrestore(&vector_lock, flags); return -ENOSPC; + } current_vector = FIRST_DEVICE_VECTOR + offset; } - vector_irq[current_vector] = irq; + vector = current_vector; + vector_irq[vector] = irq; if (irq != AUTO_ASSIGN) - IO_APIC_VECTOR(irq) = current_vector; + IO_APIC_VECTOR(irq) = vector; + + spin_unlock_irqrestore(&vector_lock, flags); - return current_vector; + return vector; } static struct hw_interrupt_type ioapic_level_type; @@ -1191,23 +1205,18 @@ static struct hw_interrupt_type ioapic_edge_type; #define IOAPIC_EDGE 0 #define IOAPIC_LEVEL 1 -static inline void ioapic_register_intr(int irq, int vector, unsigned long trigger) +static void ioapic_register_intr(int irq, int vector, unsigned long trigger) { - if (use_pci_vector() && !platform_legacy_irq(irq)) { - if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || - trigger == IOAPIC_LEVEL) - irq_desc[vector].handler = &ioapic_level_type; - else - irq_desc[vector].handler = &ioapic_edge_type; - set_intr_gate(vector, interrupt[vector]); - } else { - if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || - trigger == IOAPIC_LEVEL) - irq_desc[irq].handler = &ioapic_level_type; - else - irq_desc[irq].handler = &ioapic_edge_type; - set_intr_gate(vector, interrupt[irq]); - } + unsigned idx; + + idx = use_pci_vector() && !platform_legacy_irq(irq) ? vector : irq; + + if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || + trigger == IOAPIC_LEVEL) + irq_desc[idx].chip = &ioapic_level_type; + else + irq_desc[idx].chip = &ioapic_edge_type; + set_intr_gate(vector, interrupt[idx]); } static void __init setup_IO_APIC_irqs(void) @@ -1318,7 +1327,7 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in * The timer IRQ doesn't have to know that behind the * scene we have a 8259A-master in AEOI mode ... */ - irq_desc[0].handler = &ioapic_edge_type; + irq_desc[0].chip = &ioapic_edge_type; /* * Add it to the IO-APIC irq-routing table: @@ -2062,6 +2071,13 @@ static void set_ioapic_affinity_vector (unsigned int vector, #endif #endif +static int ioapic_retrigger(unsigned int irq) +{ + send_IPI_self(IO_APIC_VECTOR(irq)); + + return 1; +} + /* * Level and edge triggered IO-APIC interrupts need different handling, * so we use two separate IRQ descriptors. Edge triggered IRQs can be @@ -2081,6 +2097,7 @@ static struct hw_interrupt_type ioapic_edge_type __read_mostly = { #ifdef CONFIG_SMP .set_affinity = set_ioapic_affinity, #endif + .retrigger = ioapic_retrigger, }; static struct hw_interrupt_type ioapic_level_type __read_mostly = { @@ -2094,6 +2111,7 @@ static struct hw_interrupt_type ioapic_level_type __read_mostly = { #ifdef CONFIG_SMP .set_affinity = set_ioapic_affinity, #endif + .retrigger = ioapic_retrigger, }; static inline void init_IO_APIC_traps(void) @@ -2128,7 +2146,7 @@ static inline void init_IO_APIC_traps(void) make_8259A_irq(irq); else /* Strange. Oh, well.. */ - irq_desc[irq].handler = &no_irq_type; + irq_desc[irq].chip = &no_irq_type; } } } @@ -2344,7 +2362,7 @@ static inline void check_timer(void) printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); disable_8259A_irq(0); - irq_desc[0].handler = &lapic_irq_type; + irq_desc[0].chip = &lapic_irq_type; apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ enable_8259A_irq(0); diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index 49ce4c31b71..16b49170396 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c @@ -53,13 +53,19 @@ static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly; */ fastcall unsigned int do_IRQ(struct pt_regs *regs) { - /* high bits used in ret_from_ code */ - int irq = regs->orig_eax & 0xff; + /* high bit used in ret_from_ code */ + int irq = ~regs->orig_eax; #ifdef CONFIG_4KSTACKS union irq_ctx *curctx, *irqctx; u32 *isp; #endif + if (unlikely((unsigned)irq >= NR_IRQS)) { + printk(KERN_EMERG "%s: cannot handle IRQ %d\n", + __FUNCTION__, irq); + BUG(); + } + irq_enter(); #ifdef CONFIG_DEBUG_STACKOVERFLOW /* Debugging check for stack overflow: is there less than 1KB free? */ @@ -76,6 +82,10 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) } #endif + if (!irq_desc[irq].handle_irq) { + __do_IRQ(irq, regs); + goto out_exit; + } #ifdef CONFIG_4KSTACKS curctx = (union irq_ctx *) current_thread_info(); @@ -100,8 +110,8 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) * softirq checks work in the hardirq context. */ irqctx->tinfo.preempt_count = - irqctx->tinfo.preempt_count & ~SOFTIRQ_MASK | - curctx->tinfo.preempt_count & SOFTIRQ_MASK; + (irqctx->tinfo.preempt_count & ~SOFTIRQ_MASK) | + (curctx->tinfo.preempt_count & SOFTIRQ_MASK); asm volatile( " xchgl %%ebx,%%esp \n" @@ -115,6 +125,7 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) #endif __do_IRQ(irq, regs); +out_exit: irq_exit(); return 1; @@ -227,7 +238,7 @@ int show_interrupts(struct seq_file *p, void *v) if (i == 0) { seq_printf(p, " "); for_each_online_cpu(j) - seq_printf(p, "CPU%d ",j); + seq_printf(p, "CPU%-8d",j); seq_putc(p, '\n'); } @@ -243,7 +254,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -285,13 +296,13 @@ void fixup_irqs(cpumask_t map) if (irq == 2) continue; - cpus_and(mask, irq_affinity[irq], map); + cpus_and(mask, irq_desc[irq].affinity, map); if (any_online_cpu(mask) == NR_CPUS) { printk("Breaking affinity for irq %i\n", irq); mask = map; } - if (irq_desc[irq].handler->set_affinity) - irq_desc[irq].handler->set_affinity(irq, mask); + if (irq_desc[irq].chip->set_affinity) + irq_desc[irq].chip->set_affinity(irq, mask); else if (irq_desc[irq].action && !(warned++)) printk("Cannot set affinity for irq %i\n", irq); } diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index 395a9a6dff8..727e419ad78 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c @@ -57,34 +57,85 @@ static __always_inline void set_jmp_op(void *from, void *to) /* * returns non-zero if opcodes can be boosted. */ -static __always_inline int can_boost(kprobe_opcode_t opcode) +static __always_inline int can_boost(kprobe_opcode_t *opcodes) { - switch (opcode & 0xf0 ) { +#define W(row,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf) \ + (((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) | \ + (b4##UL << 0x4)|(b5##UL << 0x5)|(b6##UL << 0x6)|(b7##UL << 0x7) | \ + (b8##UL << 0x8)|(b9##UL << 0x9)|(ba##UL << 0xa)|(bb##UL << 0xb) | \ + (bc##UL << 0xc)|(bd##UL << 0xd)|(be##UL << 0xe)|(bf##UL << 0xf)) \ + << (row % 32)) + /* + * Undefined/reserved opcodes, conditional jump, Opcode Extension + * Groups, and some special opcodes can not be boost. + */ + static const unsigned long twobyte_is_boostable[256 / 32] = { + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + /* ------------------------------- */ + W(0x00, 0,0,1,1,0,0,1,0,1,1,0,0,0,0,0,0)| /* 00 */ + W(0x10, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), /* 10 */ + W(0x20, 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0)| /* 20 */ + W(0x30, 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0), /* 30 */ + W(0x40, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 40 */ + W(0x50, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), /* 50 */ + W(0x60, 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1)| /* 60 */ + W(0x70, 0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1), /* 70 */ + W(0x80, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)| /* 80 */ + W(0x90, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1), /* 90 */ + W(0xa0, 1,1,0,1,1,1,0,0,1,1,0,1,1,1,0,1)| /* a0 */ + W(0xb0, 1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1), /* b0 */ + W(0xc0, 1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1)| /* c0 */ + W(0xd0, 0,1,1,1,0,1,0,0,1,1,0,1,1,1,0,1), /* d0 */ + W(0xe0, 0,1,1,0,0,1,0,0,1,1,0,1,1,1,0,1)| /* e0 */ + W(0xf0, 0,1,1,1,0,1,0,0,1,1,1,0,1,1,1,0) /* f0 */ + /* ------------------------------- */ + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + }; +#undef W + kprobe_opcode_t opcode; + kprobe_opcode_t *orig_opcodes = opcodes; +retry: + if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1) + return 0; + opcode = *(opcodes++); + + /* 2nd-byte opcode */ + if (opcode == 0x0f) { + if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1) + return 0; + return test_bit(*opcodes, twobyte_is_boostable); + } + + switch (opcode & 0xf0) { + case 0x60: + if (0x63 < opcode && opcode < 0x67) + goto retry; /* prefixes */ + /* can't boost Address-size override and bound */ + return (opcode != 0x62 && opcode != 0x67); case 0x70: return 0; /* can't boost conditional jump */ - case 0x90: - /* can't boost call and pushf */ - return opcode != 0x9a && opcode != 0x9c; case 0xc0: - /* can't boost undefined opcodes and soft-interruptions */ - return (0xc1 < opcode && opcode < 0xc6) || - (0xc7 < opcode && opcode < 0xcc) || opcode == 0xcf; + /* can't boost software-interruptions */ + return (0xc1 < opcode && opcode < 0xcc) || opcode == 0xcf; case 0xd0: /* can boost AA* and XLAT */ return (opcode == 0xd4 || opcode == 0xd5 || opcode == 0xd7); case 0xe0: - /* can boost in/out and (may be) jmps */ - return (0xe3 < opcode && opcode != 0xe8); + /* can boost in/out and absolute jmps */ + return ((opcode & 0x04) || opcode == 0xea); case 0xf0: + if ((opcode & 0x0c) == 0 && opcode != 0xf1) + goto retry; /* lock/rep(ne) prefix */ /* clear and set flags can be boost */ return (opcode == 0xf5 || (0xf7 < opcode && opcode < 0xfe)); default: - /* currently, can't boost 2 bytes opcodes */ - return opcode != 0x0f; + if (opcode == 0x26 || opcode == 0x36 || opcode == 0x3e) + goto retry; /* prefixes */ + /* can't boost CS override and call */ + return (opcode != 0x2e && opcode != 0x9a); } } - /* * returns non-zero if opcode modifies the interrupt flag. */ @@ -109,7 +160,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); p->opcode = *p->addr; - if (can_boost(p->opcode)) { + if (can_boost(p->addr)) { p->ainsn.boostable = 0; } else { p->ainsn.boostable = -1; @@ -208,7 +259,9 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) struct kprobe_ctlblk *kcb; #ifdef CONFIG_PREEMPT unsigned pre_preempt_count = preempt_count(); -#endif /* CONFIG_PREEMPT */ +#else + unsigned pre_preempt_count = 1; +#endif addr = (kprobe_opcode_t *)(regs->eip - sizeof(kprobe_opcode_t)); @@ -285,22 +338,14 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) /* handler has already set things up, so skip ss setup */ return 1; - if (p->ainsn.boostable == 1 && -#ifdef CONFIG_PREEMPT - !(pre_preempt_count) && /* - * This enables booster when the direct - * execution path aren't preempted. - */ -#endif /* CONFIG_PREEMPT */ - !p->post_handler && !p->break_handler ) { +ss_probe: + if (pre_preempt_count && p->ainsn.boostable == 1 && !p->post_handler){ /* Boost up -- we can execute copied instructions directly */ reset_current_kprobe(); regs->eip = (unsigned long)p->ainsn.insn; preempt_enable_no_resched(); return 1; } - -ss_probe: prepare_singlestep(p, regs); kcb->kprobe_status = KPROBE_HIT_SS; return 1; diff --git a/arch/i386/kernel/machine_kexec.c b/arch/i386/kernel/machine_kexec.c index f73d7374a2b..511abe52a94 100644 --- a/arch/i386/kernel/machine_kexec.c +++ b/arch/i386/kernel/machine_kexec.c @@ -133,9 +133,9 @@ typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)( unsigned long start_address, unsigned int has_pae) ATTRIB_NORET; -const extern unsigned char relocate_new_kernel[]; +extern const unsigned char relocate_new_kernel[]; extern void relocate_new_kernel_end(void); -const extern unsigned int relocate_new_kernel_size; +extern const unsigned int relocate_new_kernel_size; /* * A architecture hook called to validate the diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c index 7a328230e54..d022cb8fd72 100644 --- a/arch/i386/kernel/msr.c +++ b/arch/i386/kernel/msr.c @@ -266,7 +266,7 @@ static int msr_class_cpu_callback(struct notifier_block *nfb, unsigned long acti return NOTIFY_OK; } -static struct notifier_block msr_class_cpu_notifier = +static struct notifier_block __cpuinitdata msr_class_cpu_notifier = { .notifier_call = msr_class_cpu_callback, }; diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index d43b498ec74..a76e9314658 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -14,21 +14,17 @@ */ #include <linux/config.h> -#include <linux/mm.h> #include <linux/delay.h> -#include <linux/bootmem.h> -#include <linux/smp_lock.h> #include <linux/interrupt.h> -#include <linux/mc146818rtc.h> -#include <linux/kernel_stat.h> #include <linux/module.h> #include <linux/nmi.h> #include <linux/sysdev.h> #include <linux/sysctl.h> +#include <linux/percpu.h> #include <asm/smp.h> -#include <asm/div64.h> #include <asm/nmi.h> +#include <asm/intel_arch_perfmon.h> #include "mach_traps.h" @@ -100,6 +96,9 @@ int nmi_active; (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \ P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE) +#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL +#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK + #ifdef CONFIG_SMP /* The performance counters used by NMI_LOCAL_APIC don't trigger when * the CPU is idle. To make sure the NMI watchdog really ticks on all @@ -212,6 +211,8 @@ static int __init setup_nmi_watchdog(char *str) __setup("nmi_watchdog=", setup_nmi_watchdog); +static void disable_intel_arch_watchdog(void); + static void disable_lapic_nmi_watchdog(void) { if (nmi_active <= 0) @@ -221,6 +222,10 @@ static void disable_lapic_nmi_watchdog(void) wrmsr(MSR_K7_EVNTSEL0, 0, 0); break; case X86_VENDOR_INTEL: + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { + disable_intel_arch_watchdog(); + break; + } switch (boot_cpu_data.x86) { case 6: if (boot_cpu_data.x86_model > 0xd) @@ -449,6 +454,53 @@ static int setup_p4_watchdog(void) return 1; } +static void disable_intel_arch_watchdog(void) +{ + unsigned ebx; + + /* + * Check whether the Architectural PerfMon supports + * Unhalted Core Cycles Event or not. + * NOTE: Corresponding bit = 0 in ebp indicates event present. + */ + ebx = cpuid_ebx(10); + if (!(ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) + wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, 0, 0); +} + +static int setup_intel_arch_watchdog(void) +{ + unsigned int evntsel; + unsigned ebx; + + /* + * Check whether the Architectural PerfMon supports + * Unhalted Core Cycles Event or not. + * NOTE: Corresponding bit = 0 in ebp indicates event present. + */ + ebx = cpuid_ebx(10); + if ((ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) + return 0; + + nmi_perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0; + + clear_msr_range(MSR_ARCH_PERFMON_EVENTSEL0, 2); + clear_msr_range(MSR_ARCH_PERFMON_PERFCTR0, 2); + + evntsel = ARCH_PERFMON_EVENTSEL_INT + | ARCH_PERFMON_EVENTSEL_OS + | ARCH_PERFMON_EVENTSEL_USR + | ARCH_PERFMON_NMI_EVENT_SEL + | ARCH_PERFMON_NMI_EVENT_UMASK; + + wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, evntsel, 0); + write_watchdog_counter("INTEL_ARCH_PERFCTR0"); + apic_write(APIC_LVTPC, APIC_DM_NMI); + evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE; + wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, evntsel, 0); + return 1; +} + void setup_apic_nmi_watchdog (void) { switch (boot_cpu_data.x86_vendor) { @@ -458,6 +510,11 @@ void setup_apic_nmi_watchdog (void) setup_k7_watchdog(); break; case X86_VENDOR_INTEL: + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { + if (!setup_intel_arch_watchdog()) + return; + break; + } switch (boot_cpu_data.x86) { case 6: if (boot_cpu_data.x86_model > 0xd) @@ -561,7 +618,8 @@ void nmi_watchdog_tick (struct pt_regs * regs) wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); apic_write(APIC_LVTPC, APIC_DM_NMI); } - else if (nmi_perfctr_msr == MSR_P6_PERFCTR0) { + else if (nmi_perfctr_msr == MSR_P6_PERFCTR0 || + nmi_perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) { /* Only P6 based Pentium M need to re-unmask * the apic vector but it doesn't hurt * other P6 variant */ diff --git a/arch/i386/kernel/numaq.c b/arch/i386/kernel/numaq.c index 5f5b075f860..0caf14652ba 100644 --- a/arch/i386/kernel/numaq.c +++ b/arch/i386/kernel/numaq.c @@ -79,10 +79,12 @@ int __init get_memcfg_numaq(void) return 1; } -static int __init numaq_dsc_disable(void) +static int __init numaq_tsc_disable(void) { - printk(KERN_DEBUG "NUMAQ: disabling TSC\n"); - tsc_disable = 1; + if (num_online_nodes() > 1) { + printk(KERN_DEBUG "NUMAQ: disabling TSC\n"); + tsc_disable = 1; + } return 0; } -core_initcall(numaq_dsc_disable); +arch_initcall(numaq_tsc_disable); diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 6259afea46d..6946b06e278 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -102,7 +102,7 @@ void default_idle(void) local_irq_enable(); if (!hlt_counter && boot_cpu_data.hlt_works_ok) { - clear_thread_flag(TIF_POLLING_NRFLAG); + current_thread_info()->status &= ~TS_POLLING; smp_mb__after_clear_bit(); while (!need_resched()) { local_irq_disable(); @@ -111,7 +111,7 @@ void default_idle(void) else local_irq_enable(); } - set_thread_flag(TIF_POLLING_NRFLAG); + current_thread_info()->status |= TS_POLLING; } else { while (!need_resched()) cpu_relax(); @@ -174,7 +174,7 @@ void cpu_idle(void) { int cpu = smp_processor_id(); - set_thread_flag(TIF_POLLING_NRFLAG); + current_thread_info()->status |= TS_POLLING; /* endless idle loop with no priority at all */ while (1) { @@ -312,7 +312,7 @@ void show_regs(struct pt_regs * regs) cr3 = read_cr3(); cr4 = read_cr4_safe(); printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4); - show_trace(NULL, ®s->esp); + show_trace(NULL, regs, ®s->esp); } /* diff --git a/arch/i386/kernel/scx200.c b/arch/i386/kernel/scx200.c index 321f5fd26e7..9bf590cefc7 100644 --- a/arch/i386/kernel/scx200.c +++ b/arch/i386/kernel/scx200.c @@ -9,6 +9,7 @@ #include <linux/errno.h> #include <linux/kernel.h> #include <linux/init.h> +#include <linux/mutex.h> #include <linux/pci.h> #include <linux/scx200.h> @@ -45,11 +46,19 @@ static struct pci_driver scx200_pci_driver = { .probe = scx200_probe, }; -static DEFINE_SPINLOCK(scx200_gpio_config_lock); +static DEFINE_MUTEX(scx200_gpio_config_lock); -static int __devinit scx200_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +static void __devinit scx200_init_shadow(void) { int bank; + + /* read the current values driven on the GPIO signals */ + for (bank = 0; bank < 2; ++bank) + scx200_gpio_shadow[bank] = inl(scx200_gpio_base + 0x10 * bank); +} + +static int __devinit scx200_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ unsigned base; if (pdev->device == PCI_DEVICE_ID_NS_SCx200_BRIDGE || @@ -63,10 +72,7 @@ static int __devinit scx200_probe(struct pci_dev *pdev, const struct pci_device_ } scx200_gpio_base = base; - - /* read the current values driven on the GPIO signals */ - for (bank = 0; bank < 2; ++bank) - scx200_gpio_shadow[bank] = inl(scx200_gpio_base + 0x10 * bank); + scx200_init_shadow(); } else { /* find the base of the Configuration Block */ @@ -87,12 +93,11 @@ static int __devinit scx200_probe(struct pci_dev *pdev, const struct pci_device_ return 0; } -u32 scx200_gpio_configure(int index, u32 mask, u32 bits) +u32 scx200_gpio_configure(unsigned index, u32 mask, u32 bits) { u32 config, new_config; - unsigned long flags; - spin_lock_irqsave(&scx200_gpio_config_lock, flags); + mutex_lock(&scx200_gpio_config_lock); outl(index, scx200_gpio_base + 0x20); config = inl(scx200_gpio_base + 0x24); @@ -100,45 +105,11 @@ u32 scx200_gpio_configure(int index, u32 mask, u32 bits) new_config = (config & mask) | bits; outl(new_config, scx200_gpio_base + 0x24); - spin_unlock_irqrestore(&scx200_gpio_config_lock, flags); + mutex_unlock(&scx200_gpio_config_lock); return config; } -#if 0 -void scx200_gpio_dump(unsigned index) -{ - u32 config = scx200_gpio_configure(index, ~0, 0); - printk(KERN_DEBUG "GPIO%02u: 0x%08lx", index, (unsigned long)config); - - if (config & 1) - printk(" OE"); /* output enabled */ - else - printk(" TS"); /* tristate */ - if (config & 2) - printk(" PP"); /* push pull */ - else - printk(" OD"); /* open drain */ - if (config & 4) - printk(" PUE"); /* pull up enabled */ - else - printk(" PUD"); /* pull up disabled */ - if (config & 8) - printk(" LOCKED"); /* locked */ - if (config & 16) - printk(" LEVEL"); /* level input */ - else - printk(" EDGE"); /* edge input */ - if (config & 32) - printk(" HI"); /* trigger on rising edge */ - else - printk(" LO"); /* trigger on falling edge */ - if (config & 64) - printk(" DEBOUNCE"); /* debounce */ - printk("\n"); -} -#endif /* 0 */ - static int __init scx200_init(void) { printk(KERN_INFO NAME ": NatSemi SCx200 Driver\n"); @@ -159,10 +130,3 @@ EXPORT_SYMBOL(scx200_gpio_base); EXPORT_SYMBOL(scx200_gpio_shadow); EXPORT_SYMBOL(scx200_gpio_configure); EXPORT_SYMBOL(scx200_cb_base); - -/* - Local variables: - compile-command: "make -k -C ../../.. SUBDIRS=arch/i386/kernel modules" - c-basic-offset: 8 - End: -*/ diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 6c1639836e0..6712f0d2eb3 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -48,7 +48,6 @@ #include <linux/crash_dump.h> #include <linux/dmi.h> #include <linux/pfn.h> -#include <linux/suspend.h> #include <video/edid.h> @@ -1315,8 +1314,10 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat probe_roms(); for (i = 0; i < e820.nr_map; i++) { struct resource *res; +#ifndef CONFIG_RESOURCES_64BIT if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL) continue; +#endif res = kzalloc(sizeof(struct resource), GFP_ATOMIC); switch (e820.map[i].type) { case E820_RAM: res->name = "System RAM"; break; @@ -1427,111 +1428,6 @@ static void set_mca_bus(int x) static void set_mca_bus(int x) { } #endif -#ifdef CONFIG_SOFTWARE_SUSPEND -static void __init mark_nosave_page_range(unsigned long start, unsigned long end) -{ - struct page *page; - while (start <= end) { - page = pfn_to_page(start); - SetPageNosave(page); - start++; - } -} - -static void __init e820_nosave_reserved_pages(void) -{ - int i; - unsigned long r_start = 0, r_end = 0; - - /* Assume e820 map is sorted */ - for (i = 0; i < e820.nr_map; i++) { - struct e820entry *ei = &e820.map[i]; - unsigned long start, end; - - start = PFN_DOWN(ei->addr); - end = PFN_UP(ei->addr + ei->size); - if (start >= end) - continue; - if (ei->type == E820_RESERVED) - continue; - r_end = start; - /* - * Highmem 'Reserved' pages are marked as reserved, swsusp - * will not save/restore them, so we ignore these pages here. - */ - if (r_end > max_low_pfn) - r_end = max_low_pfn; - if (r_end > r_start) - mark_nosave_page_range(r_start, r_end-1); - if (r_end >= max_low_pfn) - break; - r_start = end; - } -} - -static void __init e820_save_acpi_pages(void) -{ - int i; - - /* Assume e820 map is sorted */ - for (i = 0; i < e820.nr_map; i++) { - struct e820entry *ei = &e820.map[i]; - unsigned long start, end; - - start = ei->addr; - end = ei->addr + ei->size; - if (start >= end) - continue; - if (ei->type != E820_ACPI && ei->type != E820_NVS) - continue; - /* - * If the region is below max_low_pfn, it will be - * saved/restored by swsusp follow 'RAM' type. - */ - if (start < (max_low_pfn << PAGE_SHIFT)) - start = max_low_pfn << PAGE_SHIFT; - /* - * Highmem pages (ACPI NVS/Data) are reserved, but swsusp - * highmem save/restore will not save/restore them. We marked - * them as arch saveable pages here - */ - if (end > start) - swsusp_add_arch_pages(start, end); - } -} - -extern char __start_rodata, __end_rodata; -/* - * BIOS reserved region/hole - no save/restore - * ACPI NVS - save/restore - * ACPI Data - this is a little tricky, the mem could be used by OS after OS - * reads tables from the region, but anyway save/restore the memory hasn't any - * side effect and Linux runtime module load/unload might use it. - * kernel rodata - no save/restore (kernel rodata isn't changed) - */ -static int __init mark_nosave_pages(void) -{ - unsigned long pfn_start, pfn_end; - - /* FIXME: provide a version for efi BIOS */ - if (efi_enabled) - return 0; - /* BIOS reserved regions & holes */ - e820_nosave_reserved_pages(); - - /* kernel rodata */ - pfn_start = PFN_UP(virt_to_phys(&__start_rodata)); - pfn_end = PFN_DOWN(virt_to_phys(&__end_rodata)); - mark_nosave_page_range(pfn_start, pfn_end-1); - - /* record ACPI Data/NVS as saveable */ - e820_save_acpi_pages(); - - return 0; -} -core_initcall(mark_nosave_pages); -#endif - /* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures @@ -1681,6 +1577,7 @@ void __init setup_arch(char **cmdline_p) conswitchp = &dummy_con; #endif #endif + tsc_init(); } static __init int add_pcspkr(void) diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c index 5c352c3a9e7..43002cfb40c 100644 --- a/arch/i386/kernel/signal.c +++ b/arch/i386/kernel/signal.c @@ -351,7 +351,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, goto give_sigsegv; } - restorer = &__kernel_sigreturn; + restorer = (void *)VDSO_SYM(&__kernel_sigreturn); if (ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer; @@ -447,7 +447,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, goto give_sigsegv; /* Set up to return from userspace. */ - restorer = &__kernel_rt_sigreturn; + restorer = (void *)VDSO_SYM(&__kernel_rt_sigreturn); if (ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer; err |= __put_user(restorer, &frame->pretcode); diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index d134e9643a5..c10789d7a9d 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -114,7 +114,17 @@ DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_m static inline int __prepare_ICR (unsigned int shortcut, int vector) { - return APIC_DM_FIXED | shortcut | vector | APIC_DEST_LOGICAL; + unsigned int icr = shortcut | APIC_DEST_LOGICAL; + + switch (vector) { + default: + icr |= APIC_DM_FIXED | vector; + break; + case NMI_VECTOR: + icr |= APIC_DM_NMI; + break; + } + return icr; } static inline int __prepare_ICR2 (unsigned int mask) diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index bd0ca5c9f05..89e7315e539 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -52,6 +52,7 @@ #include <asm/tlbflush.h> #include <asm/desc.h> #include <asm/arch_hooks.h> +#include <asm/nmi.h> #include <mach_apic.h> #include <mach_wakecpu.h> @@ -66,12 +67,6 @@ int smp_num_siblings = 1; EXPORT_SYMBOL(smp_num_siblings); #endif -/* Package ID of each logical CPU */ -int phys_proc_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID}; - -/* Core ID of each logical CPU */ -int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID}; - /* Last level cache ID of each logical CPU */ int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID}; @@ -453,10 +448,12 @@ cpumask_t cpu_coregroup_map(int cpu) struct cpuinfo_x86 *c = cpu_data + cpu; /* * For perf, we return last level cache shared map. - * TBD: when power saving sched policy is added, we will return - * cpu_core_map when power saving policy is enabled + * And for power savings, we return cpu_core_map */ - return c->llc_shared_map; + if (sched_mc_power_savings || sched_smt_power_savings) + return cpu_core_map[cpu]; + else + return c->llc_shared_map; } /* representing cpus for which sibling maps can be computed */ @@ -472,8 +469,8 @@ set_cpu_sibling_map(int cpu) if (smp_num_siblings > 1) { for_each_cpu_mask(i, cpu_sibling_setup_map) { - if (phys_proc_id[cpu] == phys_proc_id[i] && - cpu_core_id[cpu] == cpu_core_id[i]) { + if (c[cpu].phys_proc_id == c[i].phys_proc_id && + c[cpu].cpu_core_id == c[i].cpu_core_id) { cpu_set(i, cpu_sibling_map[cpu]); cpu_set(cpu, cpu_sibling_map[i]); cpu_set(i, cpu_core_map[cpu]); @@ -500,7 +497,7 @@ set_cpu_sibling_map(int cpu) cpu_set(i, c[cpu].llc_shared_map); cpu_set(cpu, c[i].llc_shared_map); } - if (phys_proc_id[cpu] == phys_proc_id[i]) { + if (c[cpu].phys_proc_id == c[i].phys_proc_id) { cpu_set(i, cpu_core_map[cpu]); cpu_set(cpu, cpu_core_map[i]); /* @@ -1055,6 +1052,7 @@ static int __cpuinit __smp_prepare_cpu(int cpu) struct warm_boot_cpu_info info; struct work_struct task; int apicid, ret; + struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); apicid = x86_cpu_to_apicid[cpu]; if (apicid == BAD_APICID) { @@ -1062,6 +1060,18 @@ static int __cpuinit __smp_prepare_cpu(int cpu) goto exit; } + /* + * the CPU isn't initialized at boot time, allocate gdt table here. + * cpu_init will initialize it + */ + if (!cpu_gdt_descr->address) { + cpu_gdt_descr->address = get_zeroed_page(GFP_KERNEL); + if (!cpu_gdt_descr->address) + printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu); + ret = -ENOMEM; + goto exit; + } + info.complete = &done; info.apicid = apicid; info.cpu = cpu; @@ -1339,8 +1349,8 @@ remove_siblinginfo(int cpu) cpu_clear(cpu, cpu_sibling_map[sibling]); cpus_clear(cpu_sibling_map[cpu]); cpus_clear(cpu_core_map[cpu]); - phys_proc_id[cpu] = BAD_APICID; - cpu_core_id[cpu] = BAD_APICID; + c[cpu].phys_proc_id = 0; + c[cpu].cpu_core_id = 0; cpu_clear(cpu, cpu_sibling_setup_map); } diff --git a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c index 0bada1870bd..713ba39d32c 100644 --- a/arch/i386/kernel/sysenter.c +++ b/arch/i386/kernel/sysenter.c @@ -2,6 +2,8 @@ * linux/arch/i386/kernel/sysenter.c * * (C) Copyright 2002 Linus Torvalds + * Portions based on the vdso-randomization code from exec-shield: + * Copyright(C) 2005-2006, Red Hat, Inc., Ingo Molnar * * This file contains the needed initializations to support sysenter. */ @@ -13,12 +15,31 @@ #include <linux/gfp.h> #include <linux/string.h> #include <linux/elf.h> +#include <linux/mm.h> +#include <linux/module.h> #include <asm/cpufeature.h> #include <asm/msr.h> #include <asm/pgtable.h> #include <asm/unistd.h> +/* + * Should the kernel map a VDSO page into processes and pass its + * address down to glibc upon exec()? + */ +unsigned int __read_mostly vdso_enabled = 1; + +EXPORT_SYMBOL_GPL(vdso_enabled); + +static int __init vdso_setup(char *s) +{ + vdso_enabled = simple_strtoul(s, NULL, 0); + + return 1; +} + +__setup("vdso=", vdso_setup); + extern asmlinkage void sysenter_entry(void); void enable_sep_cpu(void) @@ -45,23 +66,120 @@ void enable_sep_cpu(void) */ extern const char vsyscall_int80_start, vsyscall_int80_end; extern const char vsyscall_sysenter_start, vsyscall_sysenter_end; +static void *syscall_page; int __init sysenter_setup(void) { - void *page = (void *)get_zeroed_page(GFP_ATOMIC); + syscall_page = (void *)get_zeroed_page(GFP_ATOMIC); - __set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY_EXEC); +#ifdef CONFIG_COMPAT_VDSO + __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_READONLY); + printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO)); +#else + /* + * In the non-compat case the ELF coredumping code needs the fixmap: + */ + __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_KERNEL_RO); +#endif if (!boot_cpu_has(X86_FEATURE_SEP)) { - memcpy(page, + memcpy(syscall_page, &vsyscall_int80_start, &vsyscall_int80_end - &vsyscall_int80_start); return 0; } - memcpy(page, + memcpy(syscall_page, &vsyscall_sysenter_start, &vsyscall_sysenter_end - &vsyscall_sysenter_start); return 0; } + +static struct page *syscall_nopage(struct vm_area_struct *vma, + unsigned long adr, int *type) +{ + struct page *p = virt_to_page(adr - vma->vm_start + syscall_page); + get_page(p); + return p; +} + +/* Prevent VMA merging */ +static void syscall_vma_close(struct vm_area_struct *vma) +{ +} + +static struct vm_operations_struct syscall_vm_ops = { + .close = syscall_vma_close, + .nopage = syscall_nopage, +}; + +/* Defined in vsyscall-sysenter.S */ +extern void SYSENTER_RETURN; + +/* Setup a VMA at program startup for the vsyscall page */ +int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) +{ + struct vm_area_struct *vma; + struct mm_struct *mm = current->mm; + unsigned long addr; + int ret; + + down_write(&mm->mmap_sem); + addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0); + if (IS_ERR_VALUE(addr)) { + ret = addr; + goto up_fail; + } + + vma = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL); + if (!vma) { + ret = -ENOMEM; + goto up_fail; + } + + vma->vm_start = addr; + vma->vm_end = addr + PAGE_SIZE; + /* MAYWRITE to allow gdb to COW and set breakpoints */ + vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE; + vma->vm_flags |= mm->def_flags; + vma->vm_page_prot = protection_map[vma->vm_flags & 7]; + vma->vm_ops = &syscall_vm_ops; + vma->vm_mm = mm; + + ret = insert_vm_struct(mm, vma); + if (unlikely(ret)) { + kmem_cache_free(vm_area_cachep, vma); + goto up_fail; + } + + current->mm->context.vdso = (void *)addr; + current_thread_info()->sysenter_return = + (void *)VDSO_SYM(&SYSENTER_RETURN); + mm->total_vm++; +up_fail: + up_write(&mm->mmap_sem); + return ret; +} + +const char *arch_vma_name(struct vm_area_struct *vma) +{ + if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) + return "[vdso]"; + return NULL; +} + +struct vm_area_struct *get_gate_vma(struct task_struct *tsk) +{ + return NULL; +} + +int in_gate_area(struct task_struct *task, unsigned long addr) +{ + return 0; +} + +int in_gate_area_no_task(unsigned long addr) +{ + return 0; +} diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c index 9d307475985..5f43d041012 100644 --- a/arch/i386/kernel/time.c +++ b/arch/i386/kernel/time.c @@ -82,13 +82,6 @@ extern unsigned long wall_jiffies; DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); -#include <asm/i8253.h> - -DEFINE_SPINLOCK(i8253_lock); -EXPORT_SYMBOL(i8253_lock); - -struct timer_opts *cur_timer __read_mostly = &timer_none; - /* * This is a special lock that is owned by the CPU and holds the index * register we are working with. It is required for NMI access to the @@ -118,99 +111,19 @@ void rtc_cmos_write(unsigned char val, unsigned char addr) } EXPORT_SYMBOL(rtc_cmos_write); -/* - * This version of gettimeofday has microsecond resolution - * and better than microsecond precision on fast x86 machines with TSC. - */ -void do_gettimeofday(struct timeval *tv) -{ - unsigned long seq; - unsigned long usec, sec; - unsigned long max_ntp_tick; - - do { - unsigned long lost; - - seq = read_seqbegin(&xtime_lock); - - usec = cur_timer->get_offset(); - lost = jiffies - wall_jiffies; - - /* - * If time_adjust is negative then NTP is slowing the clock - * so make sure not to go into next possible interval. - * Better to lose some accuracy than have time go backwards.. - */ - if (unlikely(time_adjust < 0)) { - max_ntp_tick = (USEC_PER_SEC / HZ) - tickadj; - usec = min(usec, max_ntp_tick); - - if (lost) - usec += lost * max_ntp_tick; - } - else if (unlikely(lost)) - usec += lost * (USEC_PER_SEC / HZ); - - sec = xtime.tv_sec; - usec += (xtime.tv_nsec / 1000); - } while (read_seqretry(&xtime_lock, seq)); - - while (usec >= 1000000) { - usec -= 1000000; - sec++; - } - - tv->tv_sec = sec; - tv->tv_usec = usec; -} - -EXPORT_SYMBOL(do_gettimeofday); - -int do_settimeofday(struct timespec *tv) -{ - time_t wtm_sec, sec = tv->tv_sec; - long wtm_nsec, nsec = tv->tv_nsec; - - if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) - return -EINVAL; - - write_seqlock_irq(&xtime_lock); - /* - * This is revolting. We need to set "xtime" correctly. However, the - * value in this location is the value at the most recent update of - * wall time. Discover what correction gettimeofday() would have - * made, and then undo it! - */ - nsec -= cur_timer->get_offset() * NSEC_PER_USEC; - nsec -= (jiffies - wall_jiffies) * TICK_NSEC; - - wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); - wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); - - set_normalized_timespec(&xtime, sec, nsec); - set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); - - ntp_clear(); - write_sequnlock_irq(&xtime_lock); - clock_was_set(); - return 0; -} - -EXPORT_SYMBOL(do_settimeofday); - static int set_rtc_mmss(unsigned long nowtime) { int retval; - - WARN_ON(irqs_disabled()); + unsigned long flags; /* gets recalled with irq locally disabled */ - spin_lock_irq(&rtc_lock); + /* XXX - does irqsave resolve this? -johnstul */ + spin_lock_irqsave(&rtc_lock, flags); if (efi_enabled) retval = efi_set_rtc_mmss(nowtime); else retval = mach_set_rtc_mmss(nowtime); - spin_unlock_irq(&rtc_lock); + spin_unlock_irqrestore(&rtc_lock, flags); return retval; } @@ -218,16 +131,6 @@ static int set_rtc_mmss(unsigned long nowtime) int timer_ack; -/* monotonic_clock(): returns # of nanoseconds passed since time_init() - * Note: This function is required to return accurate - * time even in the absence of multiple timer ticks. - */ -unsigned long long monotonic_clock(void) -{ - return cur_timer->monotonic_clock(); -} -EXPORT_SYMBOL(monotonic_clock); - #if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER) unsigned long profile_pc(struct pt_regs *regs) { @@ -242,11 +145,21 @@ EXPORT_SYMBOL(profile_pc); #endif /* - * timer_interrupt() needs to keep up the real-time clock, - * as well as call the "do_timer()" routine every clocktick + * This is the same as the above, except we _also_ save the current + * Time Stamp Counter value at the time of the timer interrupt, so that + * we later on can estimate the time of day more exactly. */ -static inline void do_timer_interrupt(int irq, struct pt_regs *regs) +irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { + /* + * Here we are in the timer irq handler. We just have irqs locally + * disabled but we don't know if the timer_bh is running on the other + * CPU. We need to avoid to SMP race with it. NOTE: we don' t need + * the irq version of write_lock because as just said we have irq + * locally disabled. -arca + */ + write_seqlock(&xtime_lock); + #ifdef CONFIG_X86_IO_APIC if (timer_ack) { /* @@ -279,27 +192,6 @@ static inline void do_timer_interrupt(int irq, struct pt_regs *regs) irq = inb_p( 0x61 ); /* read the current state */ outb_p( irq|0x80, 0x61 ); /* reset the IRQ */ } -} - -/* - * This is the same as the above, except we _also_ save the current - * Time Stamp Counter value at the time of the timer interrupt, so that - * we later on can estimate the time of day more exactly. - */ -irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - /* - * Here we are in the timer irq handler. We just have irqs locally - * disabled but we don't know if the timer_bh is running on the other - * CPU. We need to avoid to SMP race with it. NOTE: we don' t need - * the irq version of write_lock because as just said we have irq - * locally disabled. -arca - */ - write_seqlock(&xtime_lock); - - cur_timer->mark_offset(); - - do_timer_interrupt(irq, regs); write_sequnlock(&xtime_lock); @@ -380,7 +272,6 @@ void notify_arch_cmos_timer(void) static long clock_cmos_diff, sleep_start; -static struct timer_opts *last_timer; static int timer_suspend(struct sys_device *dev, pm_message_t state) { /* @@ -389,10 +280,6 @@ static int timer_suspend(struct sys_device *dev, pm_message_t state) clock_cmos_diff = -get_cmos_time(); clock_cmos_diff += get_seconds(); sleep_start = get_cmos_time(); - last_timer = cur_timer; - cur_timer = &timer_none; - if (last_timer->suspend) - last_timer->suspend(state); return 0; } @@ -415,10 +302,6 @@ static int timer_resume(struct sys_device *dev) jiffies_64 += sleep_length; wall_jiffies += sleep_length; write_sequnlock_irqrestore(&xtime_lock, flags); - if (last_timer->resume) - last_timer->resume(); - cur_timer = last_timer; - last_timer = NULL; touch_softlockup_watchdog(); return 0; } @@ -460,9 +343,6 @@ static void __init hpet_time_init(void) printk("Using HPET for base-timer\n"); } - cur_timer = select_timer(); - printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name); - time_init_hook(); } #endif @@ -484,8 +364,5 @@ void __init time_init(void) set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); - cur_timer = select_timer(); - printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name); - time_init_hook(); } diff --git a/arch/i386/kernel/timers/Makefile b/arch/i386/kernel/timers/Makefile deleted file mode 100644 index 8fa12be658d..00000000000 --- a/arch/i386/kernel/timers/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# Makefile for x86 timers -# - -obj-y := timer.o timer_none.o timer_tsc.o timer_pit.o common.o - -obj-$(CONFIG_X86_CYCLONE_TIMER) += timer_cyclone.o -obj-$(CONFIG_HPET_TIMER) += timer_hpet.o -obj-$(CONFIG_X86_PM_TIMER) += timer_pm.o diff --git a/arch/i386/kernel/timers/common.c b/arch/i386/kernel/timers/common.c deleted file mode 100644 index 8163fe0cf1f..00000000000 --- a/arch/i386/kernel/timers/common.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Common functions used across the timers go here - */ - -#include <linux/init.h> -#include <linux/timex.h> -#include <linux/errno.h> -#include <linux/jiffies.h> -#include <linux/module.h> - -#include <asm/io.h> -#include <asm/timer.h> -#include <asm/hpet.h> - -#include "mach_timer.h" - -/* ------ Calibrate the TSC ------- - * Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset(). - * Too much 64-bit arithmetic here to do this cleanly in C, and for - * accuracy's sake we want to keep the overhead on the CTC speaker (channel 2) - * output busy loop as low as possible. We avoid reading the CTC registers - * directly because of the awkward 8-bit access mechanism of the 82C54 - * device. - */ - -#define CALIBRATE_TIME (5 * 1000020/HZ) - -unsigned long calibrate_tsc(void) -{ - mach_prepare_counter(); - - { - unsigned long startlow, starthigh; - unsigned long endlow, endhigh; - unsigned long count; - - rdtsc(startlow,starthigh); - mach_countup(&count); - rdtsc(endlow,endhigh); - - - /* Error: ECTCNEVERSET */ - if (count <= 1) - goto bad_ctc; - - /* 64-bit subtract - gcc just messes up with long longs */ - __asm__("subl %2,%0\n\t" - "sbbl %3,%1" - :"=a" (endlow), "=d" (endhigh) - :"g" (startlow), "g" (starthigh), - "0" (endlow), "1" (endhigh)); - - /* Error: ECPUTOOFAST */ - if (endhigh) - goto bad_ctc; - - /* Error: ECPUTOOSLOW */ - if (endlow <= CALIBRATE_TIME) - goto bad_ctc; - - __asm__("divl %2" - :"=a" (endlow), "=d" (endhigh) - :"r" (endlow), "0" (0), "1" (CALIBRATE_TIME)); - - return endlow; - } - - /* - * The CTC wasn't reliable: we got a hit on the very first read, - * or the CPU was so fast/slow that the quotient wouldn't fit in - * 32 bits.. - */ -bad_ctc: - return 0; -} - -#ifdef CONFIG_HPET_TIMER -/* ------ Calibrate the TSC using HPET ------- - * Return 2^32 * (1 / (TSC clocks per usec)) for getting the CPU freq. - * Second output is parameter 1 (when non NULL) - * Set 2^32 * (1 / (tsc per HPET clk)) for delay_hpet(). - * calibrate_tsc() calibrates the processor TSC by comparing - * it to the HPET timer of known frequency. - * Too much 64-bit arithmetic here to do this cleanly in C - */ -#define CALIBRATE_CNT_HPET (5 * hpet_tick) -#define CALIBRATE_TIME_HPET (5 * KERNEL_TICK_USEC) - -unsigned long __devinit calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr) -{ - unsigned long tsc_startlow, tsc_starthigh; - unsigned long tsc_endlow, tsc_endhigh; - unsigned long hpet_start, hpet_end; - unsigned long result, remain; - - hpet_start = hpet_readl(HPET_COUNTER); - rdtsc(tsc_startlow, tsc_starthigh); - do { - hpet_end = hpet_readl(HPET_COUNTER); - } while ((hpet_end - hpet_start) < CALIBRATE_CNT_HPET); - rdtsc(tsc_endlow, tsc_endhigh); - - /* 64-bit subtract - gcc just messes up with long longs */ - __asm__("subl %2,%0\n\t" - "sbbl %3,%1" - :"=a" (tsc_endlow), "=d" (tsc_endhigh) - :"g" (tsc_startlow), "g" (tsc_starthigh), - "0" (tsc_endlow), "1" (tsc_endhigh)); - - /* Error: ECPUTOOFAST */ - if (tsc_endhigh) - goto bad_calibration; - - /* Error: ECPUTOOSLOW */ - if (tsc_endlow <= CALIBRATE_TIME_HPET) - goto bad_calibration; - - ASM_DIV64_REG(result, remain, tsc_endlow, 0, CALIBRATE_TIME_HPET); - if (remain > (tsc_endlow >> 1)) - result++; /* rounding the result */ - - if (tsc_hpet_quotient_ptr) { - unsigned long tsc_hpet_quotient; - - ASM_DIV64_REG(tsc_hpet_quotient, remain, tsc_endlow, 0, - CALIBRATE_CNT_HPET); - if (remain > (tsc_endlow >> 1)) - tsc_hpet_quotient++; /* rounding the result */ - *tsc_hpet_quotient_ptr = tsc_hpet_quotient; - } - - return result; -bad_calibration: - /* - * the CPU was so fast/slow that the quotient wouldn't fit in - * 32 bits.. - */ - return 0; -} -#endif - - -unsigned long read_timer_tsc(void) -{ - unsigned long retval; - rdtscl(retval); - return retval; -} - - -/* calculate cpu_khz */ -void init_cpu_khz(void) -{ - if (cpu_has_tsc) { - unsigned long tsc_quotient = calibrate_tsc(); - if (tsc_quotient) { - /* report CPU clock rate in Hz. - * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) = - * clock/second. Our precision is about 100 ppm. - */ - { unsigned long eax=0, edx=1000; - __asm__("divl %2" - :"=a" (cpu_khz), "=d" (edx) - :"r" (tsc_quotient), - "0" (eax), "1" (edx)); - printk("Detected %u.%03u MHz processor.\n", - cpu_khz / 1000, cpu_khz % 1000); - } - } - } -} - diff --git a/arch/i386/kernel/timers/timer.c b/arch/i386/kernel/timers/timer.c deleted file mode 100644 index 7e39ed8e33f..00000000000 --- a/arch/i386/kernel/timers/timer.c +++ /dev/null @@ -1,75 +0,0 @@ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <asm/timer.h> - -#ifdef CONFIG_HPET_TIMER -/* - * HPET memory read is slower than tsc reads, but is more dependable as it - * always runs at constant frequency and reduces complexity due to - * cpufreq. So, we prefer HPET timer to tsc based one. Also, we cannot use - * timer_pit when HPET is active. So, we default to timer_tsc. - */ -#endif -/* list of timers, ordered by preference, NULL terminated */ -static struct init_timer_opts* __initdata timers[] = { -#ifdef CONFIG_X86_CYCLONE_TIMER - &timer_cyclone_init, -#endif -#ifdef CONFIG_HPET_TIMER - &timer_hpet_init, -#endif -#ifdef CONFIG_X86_PM_TIMER - &timer_pmtmr_init, -#endif - &timer_tsc_init, - &timer_pit_init, - NULL, -}; - -static char clock_override[10] __initdata; - -static int __init clock_setup(char* str) -{ - if (str) - strlcpy(clock_override, str, sizeof(clock_override)); - return 1; -} -__setup("clock=", clock_setup); - - -/* The chosen timesource has been found to be bad. - * Fall back to a known good timesource (the PIT) - */ -void clock_fallback(void) -{ - cur_timer = &timer_pit; -} - -/* iterates through the list of timers, returning the first - * one that initializes successfully. - */ -struct timer_opts* __init select_timer(void) -{ - int i = 0; - - /* find most preferred working timer */ - while (timers[i]) { - if (timers[i]->init) - if (timers[i]->init(clock_override) == 0) - return timers[i]->opts; - ++i; - } - - panic("select_timer: Cannot find a suitable timer\n"); - return NULL; -} - -int read_current_timer(unsigned long *timer_val) -{ - if (cur_timer->read_timer) { - *timer_val = cur_timer->read_timer(); - return 0; - } - return -1; -} diff --git a/arch/i386/kernel/timers/timer_cyclone.c b/arch/i386/kernel/timers/timer_cyclone.c deleted file mode 100644 index 13892a65c94..00000000000 --- a/arch/i386/kernel/timers/timer_cyclone.c +++ /dev/null @@ -1,259 +0,0 @@ -/* Cyclone-timer: - * This code implements timer_ops for the cyclone counter found - * on IBM x440, x360, and other Summit based systems. - * - * Copyright (C) 2002 IBM, John Stultz (johnstul@us.ibm.com) - */ - - -#include <linux/spinlock.h> -#include <linux/init.h> -#include <linux/timex.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/jiffies.h> - -#include <asm/timer.h> -#include <asm/io.h> -#include <asm/pgtable.h> -#include <asm/fixmap.h> -#include <asm/i8253.h> - -#include "io_ports.h" - -/* Number of usecs that the last interrupt was delayed */ -static int delay_at_last_interrupt; - -#define CYCLONE_CBAR_ADDR 0xFEB00CD0 -#define CYCLONE_PMCC_OFFSET 0x51A0 -#define CYCLONE_MPMC_OFFSET 0x51D0 -#define CYCLONE_MPCS_OFFSET 0x51A8 -#define CYCLONE_TIMER_FREQ 100000000 -#define CYCLONE_TIMER_MASK (((u64)1<<40)-1) /* 40 bit mask */ -int use_cyclone = 0; - -static u32* volatile cyclone_timer; /* Cyclone MPMC0 register */ -static u32 last_cyclone_low; -static u32 last_cyclone_high; -static unsigned long long monotonic_base; -static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED; - -/* helper macro to atomically read both cyclone counter registers */ -#define read_cyclone_counter(low,high) \ - do{ \ - high = cyclone_timer[1]; low = cyclone_timer[0]; \ - } while (high != cyclone_timer[1]); - - -static void mark_offset_cyclone(void) -{ - unsigned long lost, delay; - unsigned long delta = last_cyclone_low; - int count; - unsigned long long this_offset, last_offset; - - write_seqlock(&monotonic_lock); - last_offset = ((unsigned long long)last_cyclone_high<<32)|last_cyclone_low; - - spin_lock(&i8253_lock); - read_cyclone_counter(last_cyclone_low,last_cyclone_high); - - /* read values for delay_at_last_interrupt */ - outb_p(0x00, 0x43); /* latch the count ASAP */ - - count = inb_p(0x40); /* read the latched count */ - count |= inb(0x40) << 8; - - /* - * VIA686a test code... reset the latch if count > max + 1 - * from timer_pit.c - cjb - */ - if (count > LATCH) { - outb_p(0x34, PIT_MODE); - outb_p(LATCH & 0xff, PIT_CH0); - outb(LATCH >> 8, PIT_CH0); - count = LATCH - 1; - } - spin_unlock(&i8253_lock); - - /* lost tick compensation */ - delta = last_cyclone_low - delta; - delta /= (CYCLONE_TIMER_FREQ/1000000); - delta += delay_at_last_interrupt; - lost = delta/(1000000/HZ); - delay = delta%(1000000/HZ); - if (lost >= 2) - jiffies_64 += lost-1; - - /* update the monotonic base value */ - this_offset = ((unsigned long long)last_cyclone_high<<32)|last_cyclone_low; - monotonic_base += (this_offset - last_offset) & CYCLONE_TIMER_MASK; - write_sequnlock(&monotonic_lock); - - /* calculate delay_at_last_interrupt */ - count = ((LATCH-1) - count) * TICK_SIZE; - delay_at_last_interrupt = (count + LATCH/2) / LATCH; - - - /* catch corner case where tick rollover occured - * between cyclone and pit reads (as noted when - * usec delta is > 90% # of usecs/tick) - */ - if (lost && abs(delay - delay_at_last_interrupt) > (900000/HZ)) - jiffies_64++; -} - -static unsigned long get_offset_cyclone(void) -{ - u32 offset; - - if(!cyclone_timer) - return delay_at_last_interrupt; - - /* Read the cyclone timer */ - offset = cyclone_timer[0]; - - /* .. relative to previous jiffy */ - offset = offset - last_cyclone_low; - - /* convert cyclone ticks to microseconds */ - /* XXX slow, can we speed this up? */ - offset = offset/(CYCLONE_TIMER_FREQ/1000000); - - /* our adjusted time offset in microseconds */ - return delay_at_last_interrupt + offset; -} - -static unsigned long long monotonic_clock_cyclone(void) -{ - u32 now_low, now_high; - unsigned long long last_offset, this_offset, base; - unsigned long long ret; - unsigned seq; - - /* atomically read monotonic base & last_offset */ - do { - seq = read_seqbegin(&monotonic_lock); - last_offset = ((unsigned long long)last_cyclone_high<<32)|last_cyclone_low; - base = monotonic_base; - } while (read_seqretry(&monotonic_lock, seq)); - - - /* Read the cyclone counter */ - read_cyclone_counter(now_low,now_high); - this_offset = ((unsigned long long)now_high<<32)|now_low; - - /* convert to nanoseconds */ - ret = base + ((this_offset - last_offset)&CYCLONE_TIMER_MASK); - return ret * (1000000000 / CYCLONE_TIMER_FREQ); -} - -static int __init init_cyclone(char* override) -{ - u32* reg; - u32 base; /* saved cyclone base address */ - u32 pageaddr; /* page that contains cyclone_timer register */ - u32 offset; /* offset from pageaddr to cyclone_timer register */ - int i; - - /* check clock override */ - if (override[0] && strncmp(override,"cyclone",7)) - return -ENODEV; - - /*make sure we're on a summit box*/ - if(!use_cyclone) return -ENODEV; - - printk(KERN_INFO "Summit chipset: Starting Cyclone Counter.\n"); - - /* find base address */ - pageaddr = (CYCLONE_CBAR_ADDR)&PAGE_MASK; - offset = (CYCLONE_CBAR_ADDR)&(~PAGE_MASK); - set_fixmap_nocache(FIX_CYCLONE_TIMER, pageaddr); - reg = (u32*)(fix_to_virt(FIX_CYCLONE_TIMER) + offset); - if(!reg){ - printk(KERN_ERR "Summit chipset: Could not find valid CBAR register.\n"); - return -ENODEV; - } - base = *reg; - if(!base){ - printk(KERN_ERR "Summit chipset: Could not find valid CBAR value.\n"); - return -ENODEV; - } - - /* setup PMCC */ - pageaddr = (base + CYCLONE_PMCC_OFFSET)&PAGE_MASK; - offset = (base + CYCLONE_PMCC_OFFSET)&(~PAGE_MASK); - set_fixmap_nocache(FIX_CYCLONE_TIMER, pageaddr); - reg = (u32*)(fix_to_virt(FIX_CYCLONE_TIMER) + offset); - if(!reg){ - printk(KERN_ERR "Summit chipset: Could not find valid PMCC register.\n"); - return -ENODEV; - } - reg[0] = 0x00000001; - - /* setup MPCS */ - pageaddr = (base + CYCLONE_MPCS_OFFSET)&PAGE_MASK; - offset = (base + CYCLONE_MPCS_OFFSET)&(~PAGE_MASK); - set_fixmap_nocache(FIX_CYCLONE_TIMER, pageaddr); - reg = (u32*)(fix_to_virt(FIX_CYCLONE_TIMER) + offset); - if(!reg){ - printk(KERN_ERR "Summit chipset: Could not find valid MPCS register.\n"); - return -ENODEV; - } - reg[0] = 0x00000001; - - /* map in cyclone_timer */ - pageaddr = (base + CYCLONE_MPMC_OFFSET)&PAGE_MASK; - offset = (base + CYCLONE_MPMC_OFFSET)&(~PAGE_MASK); - set_fixmap_nocache(FIX_CYCLONE_TIMER, pageaddr); - cyclone_timer = (u32*)(fix_to_virt(FIX_CYCLONE_TIMER) + offset); - if(!cyclone_timer){ - printk(KERN_ERR "Summit chipset: Could not find valid MPMC register.\n"); - return -ENODEV; - } - - /*quick test to make sure its ticking*/ - for(i=0; i<3; i++){ - u32 old = cyclone_timer[0]; - int stall = 100; - while(stall--) barrier(); - if(cyclone_timer[0] == old){ - printk(KERN_ERR "Summit chipset: Counter not counting! DISABLED\n"); - cyclone_timer = 0; - return -ENODEV; - } - } - - init_cpu_khz(); - - /* Everything looks good! */ - return 0; -} - - -static void delay_cyclone(unsigned long loops) -{ - unsigned long bclock, now; - if(!cyclone_timer) - return; - bclock = cyclone_timer[0]; - do { - rep_nop(); - now = cyclone_timer[0]; - } while ((now-bclock) < loops); -} -/************************************************************/ - -/* cyclone timer_opts struct */ -static struct timer_opts timer_cyclone = { - .name = "cyclone", - .mark_offset = mark_offset_cyclone, - .get_offset = get_offset_cyclone, - .monotonic_clock = monotonic_clock_cyclone, - .delay = delay_cyclone, -}; - -struct init_timer_opts __initdata timer_cyclone_init = { - .init = init_cyclone, - .opts = &timer_cyclone, -}; diff --git a/arch/i386/kernel/timers/timer_hpet.c b/arch/i386/kernel/timers/timer_hpet.c deleted file mode 100644 index 17a6fe7166e..00000000000 --- a/arch/i386/kernel/timers/timer_hpet.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * This code largely moved from arch/i386/kernel/time.c. - * See comments there for proper credits. - */ - -#include <linux/spinlock.h> -#include <linux/init.h> -#include <linux/timex.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/jiffies.h> - -#include <asm/timer.h> -#include <asm/io.h> -#include <asm/processor.h> - -#include "io_ports.h" -#include "mach_timer.h" -#include <asm/hpet.h> - -static unsigned long hpet_usec_quotient __read_mostly; /* convert hpet clks to usec */ -static unsigned long tsc_hpet_quotient __read_mostly; /* convert tsc to hpet clks */ -static unsigned long hpet_last; /* hpet counter value at last tick*/ -static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */ -static unsigned long last_tsc_high; /* msb 32 bits of Time Stamp Counter */ -static unsigned long long monotonic_base; -static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED; - -/* convert from cycles(64bits) => nanoseconds (64bits) - * basic equation: - * ns = cycles / (freq / ns_per_sec) - * ns = cycles * (ns_per_sec / freq) - * ns = cycles * (10^9 / (cpu_khz * 10^3)) - * ns = cycles * (10^6 / cpu_khz) - * - * Then we use scaling math (suggested by george@mvista.com) to get: - * ns = cycles * (10^6 * SC / cpu_khz) / SC - * ns = cycles * cyc2ns_scale / SC - * - * And since SC is a constant power of two, we can convert the div - * into a shift. - * - * We can use khz divisor instead of mhz to keep a better percision, since - * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits. - * (mathieu.desnoyers@polymtl.ca) - * - * -johnstul@us.ibm.com "math is hard, lets go shopping!" - */ -static unsigned long cyc2ns_scale __read_mostly; -#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ - -static inline void set_cyc2ns_scale(unsigned long cpu_khz) -{ - cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz; -} - -static inline unsigned long long cycles_2_ns(unsigned long long cyc) -{ - return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; -} - -static unsigned long long monotonic_clock_hpet(void) -{ - unsigned long long last_offset, this_offset, base; - unsigned seq; - - /* atomically read monotonic base & last_offset */ - do { - seq = read_seqbegin(&monotonic_lock); - last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; - base = monotonic_base; - } while (read_seqretry(&monotonic_lock, seq)); - - /* Read the Time Stamp Counter */ - rdtscll(this_offset); - - /* return the value in ns */ - return base + cycles_2_ns(this_offset - last_offset); -} - -static unsigned long get_offset_hpet(void) -{ - register unsigned long eax, edx; - - eax = hpet_readl(HPET_COUNTER); - eax -= hpet_last; /* hpet delta */ - eax = min(hpet_tick, eax); - /* - * Time offset = (hpet delta) * ( usecs per HPET clock ) - * = (hpet delta) * ( usecs per tick / HPET clocks per tick) - * = (hpet delta) * ( hpet_usec_quotient ) / (2^32) - * - * Where, - * hpet_usec_quotient = (2^32 * usecs per tick)/HPET clocks per tick - * - * Using a mull instead of a divl saves some cycles in critical path. - */ - ASM_MUL64_REG(eax, edx, hpet_usec_quotient, eax); - - /* our adjusted time offset in microseconds */ - return edx; -} - -static void mark_offset_hpet(void) -{ - unsigned long long this_offset, last_offset; - unsigned long offset; - - write_seqlock(&monotonic_lock); - last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; - rdtsc(last_tsc_low, last_tsc_high); - - if (hpet_use_timer) - offset = hpet_readl(HPET_T0_CMP) - hpet_tick; - else - offset = hpet_readl(HPET_COUNTER); - if (unlikely(((offset - hpet_last) >= (2*hpet_tick)) && (hpet_last != 0))) { - int lost_ticks = ((offset - hpet_last) / hpet_tick) - 1; - jiffies_64 += lost_ticks; - } - hpet_last = offset; - - /* update the monotonic base value */ - this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; - monotonic_base += cycles_2_ns(this_offset - last_offset); - write_sequnlock(&monotonic_lock); -} - -static void delay_hpet(unsigned long loops) -{ - unsigned long hpet_start, hpet_end; - unsigned long eax; - - /* loops is the number of cpu cycles. Convert it to hpet clocks */ - ASM_MUL64_REG(eax, loops, tsc_hpet_quotient, loops); - - hpet_start = hpet_readl(HPET_COUNTER); - do { - rep_nop(); - hpet_end = hpet_readl(HPET_COUNTER); - } while ((hpet_end - hpet_start) < (loops)); -} - -static struct timer_opts timer_hpet; - -static int __init init_hpet(char* override) -{ - unsigned long result, remain; - - /* check clock override */ - if (override[0] && strncmp(override,"hpet",4)) - return -ENODEV; - - if (!is_hpet_enabled()) - return -ENODEV; - - printk("Using HPET for gettimeofday\n"); - if (cpu_has_tsc) { - unsigned long tsc_quotient = calibrate_tsc_hpet(&tsc_hpet_quotient); - if (tsc_quotient) { - /* report CPU clock rate in Hz. - * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) = - * clock/second. Our precision is about 100 ppm. - */ - { unsigned long eax=0, edx=1000; - ASM_DIV64_REG(cpu_khz, edx, tsc_quotient, - eax, edx); - printk("Detected %u.%03u MHz processor.\n", - cpu_khz / 1000, cpu_khz % 1000); - } - set_cyc2ns_scale(cpu_khz); - } - /* set this only when cpu_has_tsc */ - timer_hpet.read_timer = read_timer_tsc; - } - - /* - * Math to calculate hpet to usec multiplier - * Look for the comments at get_offset_hpet() - */ - ASM_DIV64_REG(result, remain, hpet_tick, 0, KERNEL_TICK_USEC); - if (remain > (hpet_tick >> 1)) - result++; /* rounding the result */ - hpet_usec_quotient = result; - - return 0; -} - -static int hpet_resume(void) -{ - write_seqlock(&monotonic_lock); - /* Assume this is the last mark offset time */ - rdtsc(last_tsc_low, last_tsc_high); - - if (hpet_use_timer) - hpet_last = hpet_readl(HPET_T0_CMP) - hpet_tick; - else - hpet_last = hpet_readl(HPET_COUNTER); - write_sequnlock(&monotonic_lock); - return 0; -} -/************************************************************/ - -/* tsc timer_opts struct */ -static struct timer_opts timer_hpet __read_mostly = { - .name = "hpet", - .mark_offset = mark_offset_hpet, - .get_offset = get_offset_hpet, - .monotonic_clock = monotonic_clock_hpet, - .delay = delay_hpet, - .resume = hpet_resume, -}; - -struct init_timer_opts __initdata timer_hpet_init = { - .init = init_hpet, - .opts = &timer_hpet, -}; diff --git a/arch/i386/kernel/timers/timer_none.c b/arch/i386/kernel/timers/timer_none.c deleted file mode 100644 index 4ea2f414dbb..00000000000 --- a/arch/i386/kernel/timers/timer_none.c +++ /dev/null @@ -1,39 +0,0 @@ -#include <linux/init.h> -#include <asm/timer.h> - -static void mark_offset_none(void) -{ - /* nothing needed */ -} - -static unsigned long get_offset_none(void) -{ - return 0; -} - -static unsigned long long monotonic_clock_none(void) -{ - return 0; -} - -static void delay_none(unsigned long loops) -{ - int d0; - __asm__ __volatile__( - "\tjmp 1f\n" - ".align 16\n" - "1:\tjmp 2f\n" - ".align 16\n" - "2:\tdecl %0\n\tjns 2b" - :"=&a" (d0) - :"0" (loops)); -} - -/* none timer_opts struct */ -struct timer_opts timer_none = { - .name = "none", - .mark_offset = mark_offset_none, - .get_offset = get_offset_none, - .monotonic_clock = monotonic_clock_none, - .delay = delay_none, -}; diff --git a/arch/i386/kernel/timers/timer_pit.c b/arch/i386/kernel/timers/timer_pit.c deleted file mode 100644 index b9b6bd56b9b..00000000000 --- a/arch/i386/kernel/timers/timer_pit.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * This code largely moved from arch/i386/kernel/time.c. - * See comments there for proper credits. - */ - -#include <linux/spinlock.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/sysdev.h> -#include <linux/timex.h> -#include <asm/delay.h> -#include <asm/mpspec.h> -#include <asm/timer.h> -#include <asm/smp.h> -#include <asm/io.h> -#include <asm/arch_hooks.h> -#include <asm/i8253.h> - -#include "do_timer.h" -#include "io_ports.h" - -static int count_p; /* counter in get_offset_pit() */ - -static int __init init_pit(char* override) -{ - /* check clock override */ - if (override[0] && strncmp(override,"pit",3)) - printk(KERN_ERR "Warning: clock= override failed. Defaulting " - "to PIT\n"); - init_cpu_khz(); - count_p = LATCH; - return 0; -} - -static void mark_offset_pit(void) -{ - /* nothing needed */ -} - -static unsigned long long monotonic_clock_pit(void) -{ - return 0; -} - -static void delay_pit(unsigned long loops) -{ - int d0; - __asm__ __volatile__( - "\tjmp 1f\n" - ".align 16\n" - "1:\tjmp 2f\n" - ".align 16\n" - "2:\tdecl %0\n\tjns 2b" - :"=&a" (d0) - :"0" (loops)); -} - - -/* This function must be called with xtime_lock held. - * It was inspired by Steve McCanne's microtime-i386 for BSD. -- jrs - * - * However, the pc-audio speaker driver changes the divisor so that - * it gets interrupted rather more often - it loads 64 into the - * counter rather than 11932! This has an adverse impact on - * do_gettimeoffset() -- it stops working! What is also not - * good is that the interval that our timer function gets called - * is no longer 10.0002 ms, but 9.9767 ms. To get around this - * would require using a different timing source. Maybe someone - * could use the RTC - I know that this can interrupt at frequencies - * ranging from 8192Hz to 2Hz. If I had the energy, I'd somehow fix - * it so that at startup, the timer code in sched.c would select - * using either the RTC or the 8253 timer. The decision would be - * based on whether there was any other device around that needed - * to trample on the 8253. I'd set up the RTC to interrupt at 1024 Hz, - * and then do some jiggery to have a version of do_timer that - * advanced the clock by 1/1024 s. Every time that reached over 1/100 - * of a second, then do all the old code. If the time was kept correct - * then do_gettimeoffset could just return 0 - there is no low order - * divider that can be accessed. - * - * Ideally, you would be able to use the RTC for the speaker driver, - * but it appears that the speaker driver really needs interrupt more - * often than every 120 us or so. - * - * Anyway, this needs more thought.... pjsg (1993-08-28) - * - * If you are really that interested, you should be reading - * comp.protocols.time.ntp! - */ - -static unsigned long get_offset_pit(void) -{ - int count; - unsigned long flags; - static unsigned long jiffies_p = 0; - - /* - * cache volatile jiffies temporarily; we have xtime_lock. - */ - unsigned long jiffies_t; - - spin_lock_irqsave(&i8253_lock, flags); - /* timer count may underflow right here */ - outb_p(0x00, PIT_MODE); /* latch the count ASAP */ - - count = inb_p(PIT_CH0); /* read the latched count */ - - /* - * We do this guaranteed double memory access instead of a _p - * postfix in the previous port access. Wheee, hackady hack - */ - jiffies_t = jiffies; - - count |= inb_p(PIT_CH0) << 8; - - /* VIA686a test code... reset the latch if count > max + 1 */ - if (count > LATCH) { - outb_p(0x34, PIT_MODE); - outb_p(LATCH & 0xff, PIT_CH0); - outb(LATCH >> 8, PIT_CH0); - count = LATCH - 1; - } - - /* - * avoiding timer inconsistencies (they are rare, but they happen)... - * there are two kinds of problems that must be avoided here: - * 1. the timer counter underflows - * 2. hardware problem with the timer, not giving us continuous time, - * the counter does small "jumps" upwards on some Pentium systems, - * (see c't 95/10 page 335 for Neptun bug.) - */ - - if( jiffies_t == jiffies_p ) { - if( count > count_p ) { - /* the nutcase */ - count = do_timer_overflow(count); - } - } else - jiffies_p = jiffies_t; - - count_p = count; - - spin_unlock_irqrestore(&i8253_lock, flags); - - count = ((LATCH-1) - count) * TICK_SIZE; - count = (count + LATCH/2) / LATCH; - - return count; -} - - -/* tsc timer_opts struct */ -struct timer_opts timer_pit = { - .name = "pit", - .mark_offset = mark_offset_pit, - .get_offset = get_offset_pit, - .monotonic_clock = monotonic_clock_pit, - .delay = delay_pit, -}; - -struct init_timer_opts __initdata timer_pit_init = { - .init = init_pit, - .opts = &timer_pit, -}; - -void setup_pit_timer(void) -{ - unsigned long flags; - - spin_lock_irqsave(&i8253_lock, flags); - outb_p(0x34,PIT_MODE); /* binary, mode 2, LSB/MSB, ch 0 */ - udelay(10); - outb_p(LATCH & 0xff , PIT_CH0); /* LSB */ - udelay(10); - outb(LATCH >> 8 , PIT_CH0); /* MSB */ - spin_unlock_irqrestore(&i8253_lock, flags); -} diff --git a/arch/i386/kernel/timers/timer_pm.c b/arch/i386/kernel/timers/timer_pm.c deleted file mode 100644 index 144e94a0493..00000000000 --- a/arch/i386/kernel/timers/timer_pm.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * (C) Dominik Brodowski <linux@brodo.de> 2003 - * - * Driver to use the Power Management Timer (PMTMR) available in some - * southbridges as primary timing source for the Linux kernel. - * - * Based on parts of linux/drivers/acpi/hardware/hwtimer.c, timer_pit.c, - * timer_hpet.c, and on Arjan van de Ven's implementation for 2.4. - * - * This file is licensed under the GPL v2. - */ - - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <asm/types.h> -#include <asm/timer.h> -#include <asm/smp.h> -#include <asm/io.h> -#include <asm/arch_hooks.h> - -#include <linux/timex.h> -#include "mach_timer.h" - -/* Number of PMTMR ticks expected during calibration run */ -#define PMTMR_TICKS_PER_SEC 3579545 -#define PMTMR_EXPECTED_RATE \ - ((CALIBRATE_LATCH * (PMTMR_TICKS_PER_SEC >> 10)) / (CLOCK_TICK_RATE>>10)) - - -/* The I/O port the PMTMR resides at. - * The location is detected during setup_arch(), - * in arch/i386/acpi/boot.c */ -u32 pmtmr_ioport = 0; - - -/* value of the Power timer at last timer interrupt */ -static u32 offset_tick; -static u32 offset_delay; - -static unsigned long long monotonic_base; -static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED; - -#define ACPI_PM_MASK 0xFFFFFF /* limit it to 24 bits */ - -static int pmtmr_need_workaround __read_mostly = 1; - -/*helper function to safely read acpi pm timesource*/ -static inline u32 read_pmtmr(void) -{ - if (pmtmr_need_workaround) { - u32 v1, v2, v3; - - /* It has been reported that because of various broken - * chipsets (ICH4, PIIX4 and PIIX4E) where the ACPI PM time - * source is not latched, so you must read it multiple - * times to insure a safe value is read. - */ - do { - v1 = inl(pmtmr_ioport); - v2 = inl(pmtmr_ioport); - v3 = inl(pmtmr_ioport); - } while ((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1) - || (v3 > v1 && v3 < v2)); - - /* mask the output to 24 bits */ - return v2 & ACPI_PM_MASK; - } - - return inl(pmtmr_ioport) & ACPI_PM_MASK; -} - - -/* - * Some boards have the PMTMR running way too fast. We check - * the PMTMR rate against PIT channel 2 to catch these cases. - */ -static int verify_pmtmr_rate(void) -{ - u32 value1, value2; - unsigned long count, delta; - - mach_prepare_counter(); - value1 = read_pmtmr(); - mach_countup(&count); - value2 = read_pmtmr(); - delta = (value2 - value1) & ACPI_PM_MASK; - - /* Check that the PMTMR delta is within 5% of what we expect */ - if (delta < (PMTMR_EXPECTED_RATE * 19) / 20 || - delta > (PMTMR_EXPECTED_RATE * 21) / 20) { - printk(KERN_INFO "PM-Timer running at invalid rate: %lu%% of normal - aborting.\n", 100UL * delta / PMTMR_EXPECTED_RATE); - return -1; - } - - return 0; -} - - -static int init_pmtmr(char* override) -{ - u32 value1, value2; - unsigned int i; - - if (override[0] && strncmp(override,"pmtmr",5)) - return -ENODEV; - - if (!pmtmr_ioport) - return -ENODEV; - - /* we use the TSC for delay_pmtmr, so make sure it exists */ - if (!cpu_has_tsc) - return -ENODEV; - - /* "verify" this timing source */ - value1 = read_pmtmr(); - for (i = 0; i < 10000; i++) { - value2 = read_pmtmr(); - if (value2 == value1) - continue; - if (value2 > value1) - goto pm_good; - if ((value2 < value1) && ((value2) < 0xFFF)) - goto pm_good; - printk(KERN_INFO "PM-Timer had inconsistent results: 0x%#x, 0x%#x - aborting.\n", value1, value2); - return -EINVAL; - } - printk(KERN_INFO "PM-Timer had no reasonable result: 0x%#x - aborting.\n", value1); - return -ENODEV; - -pm_good: - if (verify_pmtmr_rate() != 0) - return -ENODEV; - - init_cpu_khz(); - return 0; -} - -static inline u32 cyc2us(u32 cycles) -{ - /* The Power Management Timer ticks at 3.579545 ticks per microsecond. - * 1 / PM_TIMER_FREQUENCY == 0.27936511 =~ 286/1024 [error: 0.024%] - * - * Even with HZ = 100, delta is at maximum 35796 ticks, so it can - * easily be multiplied with 286 (=0x11E) without having to fear - * u32 overflows. - */ - cycles *= 286; - return (cycles >> 10); -} - -/* - * this gets called during each timer interrupt - * - Called while holding the writer xtime_lock - */ -static void mark_offset_pmtmr(void) -{ - u32 lost, delta, last_offset; - static int first_run = 1; - last_offset = offset_tick; - - write_seqlock(&monotonic_lock); - - offset_tick = read_pmtmr(); - - /* calculate tick interval */ - delta = (offset_tick - last_offset) & ACPI_PM_MASK; - - /* convert to usecs */ - delta = cyc2us(delta); - - /* update the monotonic base value */ - monotonic_base += delta * NSEC_PER_USEC; - write_sequnlock(&monotonic_lock); - - /* convert to ticks */ - delta += offset_delay; - lost = delta / (USEC_PER_SEC / HZ); - offset_delay = delta % (USEC_PER_SEC / HZ); - - - /* compensate for lost ticks */ - if (lost >= 2) - jiffies_64 += lost - 1; - - /* don't calculate delay for first run, - or if we've got less then a tick */ - if (first_run || (lost < 1)) { - first_run = 0; - offset_delay = 0; - } -} - -static int pmtmr_resume(void) -{ - write_seqlock(&monotonic_lock); - /* Assume this is the last mark offset time */ - offset_tick = read_pmtmr(); - write_sequnlock(&monotonic_lock); - return 0; -} - -static unsigned long long monotonic_clock_pmtmr(void) -{ - u32 last_offset, this_offset; - unsigned long long base, ret; - unsigned seq; - - - /* atomically read monotonic base & last_offset */ - do { - seq = read_seqbegin(&monotonic_lock); - last_offset = offset_tick; - base = monotonic_base; - } while (read_seqretry(&monotonic_lock, seq)); - - /* Read the pmtmr */ - this_offset = read_pmtmr(); - - /* convert to nanoseconds */ - ret = (this_offset - last_offset) & ACPI_PM_MASK; - ret = base + (cyc2us(ret) * NSEC_PER_USEC); - return ret; -} - -static void delay_pmtmr(unsigned long loops) -{ - unsigned long bclock, now; - - rdtscl(bclock); - do - { - rep_nop(); - rdtscl(now); - } while ((now-bclock) < loops); -} - - -/* - * get the offset (in microseconds) from the last call to mark_offset() - * - Called holding a reader xtime_lock - */ -static unsigned long get_offset_pmtmr(void) -{ - u32 now, offset, delta = 0; - - offset = offset_tick; - now = read_pmtmr(); - delta = (now - offset)&ACPI_PM_MASK; - - return (unsigned long) offset_delay + cyc2us(delta); -} - - -/* acpi timer_opts struct */ -static struct timer_opts timer_pmtmr = { - .name = "pmtmr", - .mark_offset = mark_offset_pmtmr, - .get_offset = get_offset_pmtmr, - .monotonic_clock = monotonic_clock_pmtmr, - .delay = delay_pmtmr, - .read_timer = read_timer_tsc, - .resume = pmtmr_resume, -}; - -struct init_timer_opts __initdata timer_pmtmr_init = { - .init = init_pmtmr, - .opts = &timer_pmtmr, -}; - -#ifdef CONFIG_PCI -/* - * PIIX4 Errata: - * - * The power management timer may return improper results when read. - * Although the timer value settles properly after incrementing, - * while incrementing there is a 3 ns window every 69.8 ns where the - * timer value is indeterminate (a 4.2% chance that the data will be - * incorrect when read). As a result, the ACPI free running count up - * timer specification is violated due to erroneous reads. - */ -static int __init pmtmr_bug_check(void) -{ - static struct pci_device_id gray_list[] __initdata = { - /* these chipsets may have bug. */ - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_82801DB_0) }, - { }, - }; - struct pci_dev *dev; - int pmtmr_has_bug = 0; - u8 rev; - - if (cur_timer != &timer_pmtmr || !pmtmr_need_workaround) - return 0; - - dev = pci_get_device(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_82371AB_3, NULL); - if (dev) { - pci_read_config_byte(dev, PCI_REVISION_ID, &rev); - /* the bug has been fixed in PIIX4M */ - if (rev < 3) { - printk(KERN_WARNING "* Found PM-Timer Bug on this " - "chipset. Due to workarounds for a bug,\n" - "* this time source is slow. Consider trying " - "other time sources (clock=)\n"); - pmtmr_has_bug = 1; - } - pci_dev_put(dev); - } - - if (pci_dev_present(gray_list)) { - printk(KERN_WARNING "* This chipset may have PM-Timer Bug. Due" - " to workarounds for a bug,\n" - "* this time source is slow. If you are sure your timer" - " does not have\n" - "* this bug, please use \"pmtmr_good\" to disable the " - "workaround\n"); - pmtmr_has_bug = 1; - } - - if (!pmtmr_has_bug) - pmtmr_need_workaround = 0; - - return 0; -} -device_initcall(pmtmr_bug_check); -#endif - -static int __init pmtr_good_setup(char *__str) -{ - pmtmr_need_workaround = 0; - return 1; -} -__setup("pmtmr_good", pmtr_good_setup); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>"); -MODULE_DESCRIPTION("Power Management Timer (PMTMR) as primary timing source for x86"); diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c deleted file mode 100644 index f1187ddb0d0..00000000000 --- a/arch/i386/kernel/timers/timer_tsc.c +++ /dev/null @@ -1,617 +0,0 @@ -/* - * This code largely moved from arch/i386/kernel/time.c. - * See comments there for proper credits. - * - * 2004-06-25 Jesper Juhl - * moved mark_offset_tsc below cpufreq_delayed_get to avoid gcc 3.4 - * failing to inline. - */ - -#include <linux/spinlock.h> -#include <linux/init.h> -#include <linux/timex.h> -#include <linux/errno.h> -#include <linux/cpufreq.h> -#include <linux/string.h> -#include <linux/jiffies.h> - -#include <asm/timer.h> -#include <asm/io.h> -/* processor.h for distable_tsc flag */ -#include <asm/processor.h> - -#include "io_ports.h" -#include "mach_timer.h" - -#include <asm/hpet.h> -#include <asm/i8253.h> - -#ifdef CONFIG_HPET_TIMER -static unsigned long hpet_usec_quotient; -static unsigned long hpet_last; -static struct timer_opts timer_tsc; -#endif - -static inline void cpufreq_delayed_get(void); - -int tsc_disable __devinitdata = 0; - -static int use_tsc; -/* Number of usecs that the last interrupt was delayed */ -static int delay_at_last_interrupt; - -static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */ -static unsigned long last_tsc_high; /* msb 32 bits of Time Stamp Counter */ -static unsigned long long monotonic_base; -static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED; - -/* Avoid compensating for lost ticks before TSCs are synched */ -static int detect_lost_ticks; -static int __init start_lost_tick_compensation(void) -{ - detect_lost_ticks = 1; - return 0; -} -late_initcall(start_lost_tick_compensation); - -/* convert from cycles(64bits) => nanoseconds (64bits) - * basic equation: - * ns = cycles / (freq / ns_per_sec) - * ns = cycles * (ns_per_sec / freq) - * ns = cycles * (10^9 / (cpu_khz * 10^3)) - * ns = cycles * (10^6 / cpu_khz) - * - * Then we use scaling math (suggested by george@mvista.com) to get: - * ns = cycles * (10^6 * SC / cpu_khz) / SC - * ns = cycles * cyc2ns_scale / SC - * - * And since SC is a constant power of two, we can convert the div - * into a shift. - * - * We can use khz divisor instead of mhz to keep a better percision, since - * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits. - * (mathieu.desnoyers@polymtl.ca) - * - * -johnstul@us.ibm.com "math is hard, lets go shopping!" - */ -static unsigned long cyc2ns_scale __read_mostly; -#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ - -static inline void set_cyc2ns_scale(unsigned long cpu_khz) -{ - cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz; -} - -static inline unsigned long long cycles_2_ns(unsigned long long cyc) -{ - return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; -} - -static int count2; /* counter for mark_offset_tsc() */ - -/* Cached *multiplier* to convert TSC counts to microseconds. - * (see the equation below). - * Equal to 2^32 * (1 / (clocks per usec) ). - * Initialized in time_init. - */ -static unsigned long fast_gettimeoffset_quotient; - -static unsigned long get_offset_tsc(void) -{ - register unsigned long eax, edx; - - /* Read the Time Stamp Counter */ - - rdtsc(eax,edx); - - /* .. relative to previous jiffy (32 bits is enough) */ - eax -= last_tsc_low; /* tsc_low delta */ - - /* - * Time offset = (tsc_low delta) * fast_gettimeoffset_quotient - * = (tsc_low delta) * (usecs_per_clock) - * = (tsc_low delta) * (usecs_per_jiffy / clocks_per_jiffy) - * - * Using a mull instead of a divl saves up to 31 clock cycles - * in the critical path. - */ - - __asm__("mull %2" - :"=a" (eax), "=d" (edx) - :"rm" (fast_gettimeoffset_quotient), - "0" (eax)); - - /* our adjusted time offset in microseconds */ - return delay_at_last_interrupt + edx; -} - -static unsigned long long monotonic_clock_tsc(void) -{ - unsigned long long last_offset, this_offset, base; - unsigned seq; - - /* atomically read monotonic base & last_offset */ - do { - seq = read_seqbegin(&monotonic_lock); - last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; - base = monotonic_base; - } while (read_seqretry(&monotonic_lock, seq)); - - /* Read the Time Stamp Counter */ - rdtscll(this_offset); - - /* return the value in ns */ - return base + cycles_2_ns(this_offset - last_offset); -} - -/* - * Scheduler clock - returns current time in nanosec units. - */ -unsigned long long sched_clock(void) -{ - unsigned long long this_offset; - - /* - * In the NUMA case we dont use the TSC as they are not - * synchronized across all CPUs. - */ -#ifndef CONFIG_NUMA - if (!use_tsc) -#endif - /* no locking but a rare wrong value is not a big deal */ - return jiffies_64 * (1000000000 / HZ); - - /* Read the Time Stamp Counter */ - rdtscll(this_offset); - - /* return the value in ns */ - return cycles_2_ns(this_offset); -} - -static void delay_tsc(unsigned long loops) -{ - unsigned long bclock, now; - - rdtscl(bclock); - do - { - rep_nop(); - rdtscl(now); - } while ((now-bclock) < loops); -} - -#ifdef CONFIG_HPET_TIMER -static void mark_offset_tsc_hpet(void) -{ - unsigned long long this_offset, last_offset; - unsigned long offset, temp, hpet_current; - - write_seqlock(&monotonic_lock); - last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; - /* - * It is important that these two operations happen almost at - * the same time. We do the RDTSC stuff first, since it's - * faster. To avoid any inconsistencies, we need interrupts - * disabled locally. - */ - /* - * Interrupts are just disabled locally since the timer irq - * has the SA_INTERRUPT flag set. -arca - */ - /* read Pentium cycle counter */ - - hpet_current = hpet_readl(HPET_COUNTER); - rdtsc(last_tsc_low, last_tsc_high); - - /* lost tick compensation */ - offset = hpet_readl(HPET_T0_CMP) - hpet_tick; - if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0)) - && detect_lost_ticks) { - int lost_ticks = (offset - hpet_last) / hpet_tick; - jiffies_64 += lost_ticks; - } - hpet_last = hpet_current; - - /* update the monotonic base value */ - this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; - monotonic_base += cycles_2_ns(this_offset - last_offset); - write_sequnlock(&monotonic_lock); - - /* calculate delay_at_last_interrupt */ - /* - * Time offset = (hpet delta) * ( usecs per HPET clock ) - * = (hpet delta) * ( usecs per tick / HPET clocks per tick) - * = (hpet delta) * ( hpet_usec_quotient ) / (2^32) - * Where, - * hpet_usec_quotient = (2^32 * usecs per tick)/HPET clocks per tick - */ - delay_at_last_interrupt = hpet_current - offset; - ASM_MUL64_REG(temp, delay_at_last_interrupt, - hpet_usec_quotient, delay_at_last_interrupt); -} -#endif - - -#ifdef CONFIG_CPU_FREQ -#include <linux/workqueue.h> - -static unsigned int cpufreq_delayed_issched = 0; -static unsigned int cpufreq_init = 0; -static struct work_struct cpufreq_delayed_get_work; - -static void handle_cpufreq_delayed_get(void *v) -{ - unsigned int cpu; - for_each_online_cpu(cpu) { - cpufreq_get(cpu); - } - cpufreq_delayed_issched = 0; -} - -/* if we notice lost ticks, schedule a call to cpufreq_get() as it tries - * to verify the CPU frequency the timing core thinks the CPU is running - * at is still correct. - */ -static inline void cpufreq_delayed_get(void) -{ - if (cpufreq_init && !cpufreq_delayed_issched) { - cpufreq_delayed_issched = 1; - printk(KERN_DEBUG "Losing some ticks... checking if CPU frequency changed.\n"); - schedule_work(&cpufreq_delayed_get_work); - } -} - -/* If the CPU frequency is scaled, TSC-based delays will need a different - * loops_per_jiffy value to function properly. - */ - -static unsigned int ref_freq = 0; -static unsigned long loops_per_jiffy_ref = 0; - -#ifndef CONFIG_SMP -static unsigned long fast_gettimeoffset_ref = 0; -static unsigned int cpu_khz_ref = 0; -#endif - -static int -time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, - void *data) -{ - struct cpufreq_freqs *freq = data; - - if (val != CPUFREQ_RESUMECHANGE && val != CPUFREQ_SUSPENDCHANGE) - write_seqlock_irq(&xtime_lock); - if (!ref_freq) { - if (!freq->old){ - ref_freq = freq->new; - goto end; - } - ref_freq = freq->old; - loops_per_jiffy_ref = cpu_data[freq->cpu].loops_per_jiffy; -#ifndef CONFIG_SMP - fast_gettimeoffset_ref = fast_gettimeoffset_quotient; - cpu_khz_ref = cpu_khz; -#endif - } - - if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) || - (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) || - (val == CPUFREQ_RESUMECHANGE)) { - if (!(freq->flags & CPUFREQ_CONST_LOOPS)) - cpu_data[freq->cpu].loops_per_jiffy = cpufreq_scale(loops_per_jiffy_ref, ref_freq, freq->new); -#ifndef CONFIG_SMP - if (cpu_khz) - cpu_khz = cpufreq_scale(cpu_khz_ref, ref_freq, freq->new); - if (use_tsc) { - if (!(freq->flags & CPUFREQ_CONST_LOOPS)) { - fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_ref, freq->new, ref_freq); - set_cyc2ns_scale(cpu_khz); - } - } -#endif - } - -end: - if (val != CPUFREQ_RESUMECHANGE && val != CPUFREQ_SUSPENDCHANGE) - write_sequnlock_irq(&xtime_lock); - - return 0; -} - -static struct notifier_block time_cpufreq_notifier_block = { - .notifier_call = time_cpufreq_notifier -}; - - -static int __init cpufreq_tsc(void) -{ - int ret; - INIT_WORK(&cpufreq_delayed_get_work, handle_cpufreq_delayed_get, NULL); - ret = cpufreq_register_notifier(&time_cpufreq_notifier_block, - CPUFREQ_TRANSITION_NOTIFIER); - if (!ret) - cpufreq_init = 1; - return ret; -} -core_initcall(cpufreq_tsc); - -#else /* CONFIG_CPU_FREQ */ -static inline void cpufreq_delayed_get(void) { return; } -#endif - -int recalibrate_cpu_khz(void) -{ -#ifndef CONFIG_SMP - unsigned int cpu_khz_old = cpu_khz; - - if (cpu_has_tsc) { - local_irq_disable(); - init_cpu_khz(); - local_irq_enable(); - cpu_data[0].loops_per_jiffy = - cpufreq_scale(cpu_data[0].loops_per_jiffy, - cpu_khz_old, - cpu_khz); - return 0; - } else - return -ENODEV; -#else - return -ENODEV; -#endif -} -EXPORT_SYMBOL(recalibrate_cpu_khz); - -static void mark_offset_tsc(void) -{ - unsigned long lost,delay; - unsigned long delta = last_tsc_low; - int count; - int countmp; - static int count1 = 0; - unsigned long long this_offset, last_offset; - static int lost_count = 0; - - write_seqlock(&monotonic_lock); - last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; - /* - * It is important that these two operations happen almost at - * the same time. We do the RDTSC stuff first, since it's - * faster. To avoid any inconsistencies, we need interrupts - * disabled locally. - */ - - /* - * Interrupts are just disabled locally since the timer irq - * has the SA_INTERRUPT flag set. -arca - */ - - /* read Pentium cycle counter */ - - rdtsc(last_tsc_low, last_tsc_high); - - spin_lock(&i8253_lock); - outb_p(0x00, PIT_MODE); /* latch the count ASAP */ - - count = inb_p(PIT_CH0); /* read the latched count */ - count |= inb(PIT_CH0) << 8; - - /* - * VIA686a test code... reset the latch if count > max + 1 - * from timer_pit.c - cjb - */ - if (count > LATCH) { - outb_p(0x34, PIT_MODE); - outb_p(LATCH & 0xff, PIT_CH0); - outb(LATCH >> 8, PIT_CH0); - count = LATCH - 1; - } - - spin_unlock(&i8253_lock); - - if (pit_latch_buggy) { - /* get center value of last 3 time lutch */ - if ((count2 >= count && count >= count1) - || (count1 >= count && count >= count2)) { - count2 = count1; count1 = count; - } else if ((count1 >= count2 && count2 >= count) - || (count >= count2 && count2 >= count1)) { - countmp = count;count = count2; - count2 = count1;count1 = countmp; - } else { - count2 = count1; count1 = count; count = count1; - } - } - - /* lost tick compensation */ - delta = last_tsc_low - delta; - { - register unsigned long eax, edx; - eax = delta; - __asm__("mull %2" - :"=a" (eax), "=d" (edx) - :"rm" (fast_gettimeoffset_quotient), - "0" (eax)); - delta = edx; - } - delta += delay_at_last_interrupt; - lost = delta/(1000000/HZ); - delay = delta%(1000000/HZ); - if (lost >= 2 && detect_lost_ticks) { - jiffies_64 += lost-1; - - /* sanity check to ensure we're not always losing ticks */ - if (lost_count++ > 100) { - printk(KERN_WARNING "Losing too many ticks!\n"); - printk(KERN_WARNING "TSC cannot be used as a timesource. \n"); - printk(KERN_WARNING "Possible reasons for this are:\n"); - printk(KERN_WARNING " You're running with Speedstep,\n"); - printk(KERN_WARNING " You don't have DMA enabled for your hard disk (see hdparm),\n"); - printk(KERN_WARNING " Incorrect TSC synchronization on an SMP system (see dmesg).\n"); - printk(KERN_WARNING "Falling back to a sane timesource now.\n"); - - clock_fallback(); - } - /* ... but give the TSC a fair chance */ - if (lost_count > 25) - cpufreq_delayed_get(); - } else - lost_count = 0; - /* update the monotonic base value */ - this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; - monotonic_base += cycles_2_ns(this_offset - last_offset); - write_sequnlock(&monotonic_lock); - - /* calculate delay_at_last_interrupt */ - count = ((LATCH-1) - count) * TICK_SIZE; - delay_at_last_interrupt = (count + LATCH/2) / LATCH; - - /* catch corner case where tick rollover occured - * between tsc and pit reads (as noted when - * usec delta is > 90% # of usecs/tick) - */ - if (lost && abs(delay - delay_at_last_interrupt) > (900000/HZ)) - jiffies_64++; -} - -static int __init init_tsc(char* override) -{ - - /* check clock override */ - if (override[0] && strncmp(override,"tsc",3)) { -#ifdef CONFIG_HPET_TIMER - if (is_hpet_enabled()) { - printk(KERN_ERR "Warning: clock= override failed. Defaulting to tsc\n"); - } else -#endif - { - return -ENODEV; - } - } - - /* - * If we have APM enabled or the CPU clock speed is variable - * (CPU stops clock on HLT or slows clock to save power) - * then the TSC timestamps may diverge by up to 1 jiffy from - * 'real time' but nothing will break. - * The most frequent case is that the CPU is "woken" from a halt - * state by the timer interrupt itself, so we get 0 error. In the - * rare cases where a driver would "wake" the CPU and request a - * timestamp, the maximum error is < 1 jiffy. But timestamps are - * still perfectly ordered. - * Note that the TSC counter will be reset if APM suspends - * to disk; this won't break the kernel, though, 'cuz we're - * smart. See arch/i386/kernel/apm.c. - */ - /* - * Firstly we have to do a CPU check for chips with - * a potentially buggy TSC. At this point we haven't run - * the ident/bugs checks so we must run this hook as it - * may turn off the TSC flag. - * - * NOTE: this doesn't yet handle SMP 486 machines where only - * some CPU's have a TSC. Thats never worked and nobody has - * moaned if you have the only one in the world - you fix it! - */ - - count2 = LATCH; /* initialize counter for mark_offset_tsc() */ - - if (cpu_has_tsc) { - unsigned long tsc_quotient; -#ifdef CONFIG_HPET_TIMER - if (is_hpet_enabled() && hpet_use_timer) { - unsigned long result, remain; - printk("Using TSC for gettimeofday\n"); - tsc_quotient = calibrate_tsc_hpet(NULL); - timer_tsc.mark_offset = &mark_offset_tsc_hpet; - /* - * Math to calculate hpet to usec multiplier - * Look for the comments at get_offset_tsc_hpet() - */ - ASM_DIV64_REG(result, remain, hpet_tick, - 0, KERNEL_TICK_USEC); - if (remain > (hpet_tick >> 1)) - result++; /* rounding the result */ - - hpet_usec_quotient = result; - } else -#endif - { - tsc_quotient = calibrate_tsc(); - } - - if (tsc_quotient) { - fast_gettimeoffset_quotient = tsc_quotient; - use_tsc = 1; - /* - * We could be more selective here I suspect - * and just enable this for the next intel chips ? - */ - /* report CPU clock rate in Hz. - * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) = - * clock/second. Our precision is about 100 ppm. - */ - { unsigned long eax=0, edx=1000; - __asm__("divl %2" - :"=a" (cpu_khz), "=d" (edx) - :"r" (tsc_quotient), - "0" (eax), "1" (edx)); - printk("Detected %u.%03u MHz processor.\n", - cpu_khz / 1000, cpu_khz % 1000); - } - set_cyc2ns_scale(cpu_khz); - return 0; - } - } - return -ENODEV; -} - -static int tsc_resume(void) -{ - write_seqlock(&monotonic_lock); - /* Assume this is the last mark offset time */ - rdtsc(last_tsc_low, last_tsc_high); -#ifdef CONFIG_HPET_TIMER - if (is_hpet_enabled() && hpet_use_timer) - hpet_last = hpet_readl(HPET_COUNTER); -#endif - write_sequnlock(&monotonic_lock); - return 0; -} - -#ifndef CONFIG_X86_TSC -/* disable flag for tsc. Takes effect by clearing the TSC cpu flag - * in cpu/common.c */ -static int __init tsc_setup(char *str) -{ - tsc_disable = 1; - return 1; -} -#else -static int __init tsc_setup(char *str) -{ - printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, " - "cannot disable TSC.\n"); - return 1; -} -#endif -__setup("notsc", tsc_setup); - - - -/************************************************************/ - -/* tsc timer_opts struct */ -static struct timer_opts timer_tsc = { - .name = "tsc", - .mark_offset = mark_offset_tsc, - .get_offset = get_offset_tsc, - .monotonic_clock = monotonic_clock_tsc, - .delay = delay_tsc, - .read_timer = read_timer_tsc, - .resume = tsc_resume, -}; - -struct init_timer_opts __initdata timer_tsc_init = { - .init = init_tsc, - .opts = &timer_tsc, -}; diff --git a/arch/i386/kernel/topology.c b/arch/i386/kernel/topology.c index 296355292c7..e2e281d4bcc 100644 --- a/arch/i386/kernel/topology.c +++ b/arch/i386/kernel/topology.c @@ -32,15 +32,8 @@ static struct i386_cpu cpu_devices[NR_CPUS]; -int arch_register_cpu(int num){ - struct node *parent = NULL; - -#ifdef CONFIG_NUMA - int node = cpu_to_node(num); - if (node_online(node)) - parent = &node_devices[node].node; -#endif /* CONFIG_NUMA */ - +int arch_register_cpu(int num) +{ /* * CPU0 cannot be offlined due to several * restrictions and assumptions in kernel. This basically @@ -50,21 +43,13 @@ int arch_register_cpu(int num){ if (!num) cpu_devices[num].cpu.no_control = 1; - return register_cpu(&cpu_devices[num].cpu, num, parent); + return register_cpu(&cpu_devices[num].cpu, num); } #ifdef CONFIG_HOTPLUG_CPU void arch_unregister_cpu(int num) { - struct node *parent = NULL; - -#ifdef CONFIG_NUMA - int node = cpu_to_node(num); - if (node_online(node)) - parent = &node_devices[node].node; -#endif /* CONFIG_NUMA */ - - return unregister_cpu(&cpu_devices[num].cpu, parent); + return unregister_cpu(&cpu_devices[num].cpu); } EXPORT_SYMBOL(arch_register_cpu); EXPORT_SYMBOL(arch_unregister_cpu); @@ -74,16 +59,13 @@ EXPORT_SYMBOL(arch_unregister_cpu); #ifdef CONFIG_NUMA #include <linux/mmzone.h> -#include <asm/node.h> - -struct i386_node node_devices[MAX_NUMNODES]; static int __init topology_init(void) { int i; for_each_online_node(i) - arch_register_node(i); + register_one_node(i); for_each_present_cpu(i) arch_register_cpu(i); diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index dcc14477af1..78464097470 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -28,6 +28,7 @@ #include <linux/utsname.h> #include <linux/kprobes.h> #include <linux/kexec.h> +#include <linux/unwind.h> #ifdef CONFIG_EISA #include <linux/ioport.h> @@ -47,7 +48,7 @@ #include <asm/desc.h> #include <asm/i387.h> #include <asm/nmi.h> - +#include <asm/unwind.h> #include <asm/smp.h> #include <asm/arch_hooks.h> #include <asm/kdebug.h> @@ -92,6 +93,7 @@ asmlinkage void spurious_interrupt_bug(void); asmlinkage void machine_check(void); static int kstack_depth_to_print = 24; +static int call_trace = 1; ATOMIC_NOTIFIER_HEAD(i386die_chain); int register_die_notifier(struct notifier_block *nb) @@ -170,7 +172,23 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo, return ebp; } -static void show_trace_log_lvl(struct task_struct *task, +static asmlinkage int show_trace_unwind(struct unwind_frame_info *info, void *log_lvl) +{ + int n = 0; + int printed = 0; /* nr of entries already printed on current line */ + + while (unwind(info) == 0 && UNW_PC(info)) { + ++n; + printed = print_addr_and_symbol(UNW_PC(info), log_lvl, printed); + if (arch_unw_user_mode(info)) + break; + } + if (printed) + printk("\n"); + return n; +} + +static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, unsigned long *stack, char *log_lvl) { unsigned long ebp; @@ -178,6 +196,26 @@ static void show_trace_log_lvl(struct task_struct *task, if (!task) task = current; + if (call_trace >= 0) { + int unw_ret = 0; + struct unwind_frame_info info; + + if (regs) { + if (unwind_init_frame_info(&info, task, regs) == 0) + unw_ret = show_trace_unwind(&info, log_lvl); + } else if (task == current) + unw_ret = unwind_init_running(&info, show_trace_unwind, log_lvl); + else { + if (unwind_init_blocked(&info, task) == 0) + unw_ret = show_trace_unwind(&info, log_lvl); + } + if (unw_ret > 0) { + if (call_trace > 0) + return; + printk("%sLegacy call trace:\n", log_lvl); + } + } + if (task == current) { /* Grab ebp right from our regs */ asm ("movl %%ebp, %0" : "=r" (ebp) : ); @@ -198,13 +236,13 @@ static void show_trace_log_lvl(struct task_struct *task, } } -void show_trace(struct task_struct *task, unsigned long * stack) +void show_trace(struct task_struct *task, struct pt_regs *regs, unsigned long * stack) { - show_trace_log_lvl(task, stack, ""); + show_trace_log_lvl(task, regs, stack, ""); } -static void show_stack_log_lvl(struct task_struct *task, unsigned long *esp, - char *log_lvl) +static void show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, + unsigned long *esp, char *log_lvl) { unsigned long *stack; int i; @@ -225,13 +263,13 @@ static void show_stack_log_lvl(struct task_struct *task, unsigned long *esp, printk("%08lx ", *stack++); } printk("\n%sCall Trace:\n", log_lvl); - show_trace_log_lvl(task, esp, log_lvl); + show_trace_log_lvl(task, regs, esp, log_lvl); } void show_stack(struct task_struct *task, unsigned long *esp) { printk(" "); - show_stack_log_lvl(task, esp, ""); + show_stack_log_lvl(task, NULL, esp, ""); } /* @@ -241,7 +279,7 @@ void dump_stack(void) { unsigned long stack; - show_trace(current, &stack); + show_trace(current, NULL, &stack); } EXPORT_SYMBOL(dump_stack); @@ -285,7 +323,7 @@ void show_registers(struct pt_regs *regs) u8 __user *eip; printk("\n" KERN_EMERG "Stack: "); - show_stack_log_lvl(NULL, (unsigned long *)esp, KERN_EMERG); + show_stack_log_lvl(NULL, regs, (unsigned long *)esp, KERN_EMERG); printk(KERN_EMERG "Code: "); @@ -1215,3 +1253,15 @@ static int __init kstack_setup(char *s) return 1; } __setup("kstack=", kstack_setup); + +static int __init call_trace_setup(char *s) +{ + if (strcmp(s, "old") == 0) + call_trace = -1; + else if (strcmp(s, "both") == 0) + call_trace = 0; + else if (strcmp(s, "new") == 0) + call_trace = 1; + return 1; +} +__setup("call_trace=", call_trace_setup); diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c new file mode 100644 index 00000000000..7e0d8dab207 --- /dev/null +++ b/arch/i386/kernel/tsc.c @@ -0,0 +1,478 @@ +/* + * This code largely moved from arch/i386/kernel/timer/timer_tsc.c + * which was originally moved from arch/i386/kernel/time.c. + * See comments there for proper credits. + */ + +#include <linux/clocksource.h> +#include <linux/workqueue.h> +#include <linux/cpufreq.h> +#include <linux/jiffies.h> +#include <linux/init.h> +#include <linux/dmi.h> + +#include <asm/delay.h> +#include <asm/tsc.h> +#include <asm/delay.h> +#include <asm/io.h> + +#include "mach_timer.h" + +/* + * On some systems the TSC frequency does not + * change with the cpu frequency. So we need + * an extra value to store the TSC freq + */ +unsigned int tsc_khz; + +int tsc_disable __cpuinitdata = 0; + +#ifdef CONFIG_X86_TSC +static int __init tsc_setup(char *str) +{ + printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, " + "cannot disable TSC.\n"); + return 1; +} +#else +/* + * disable flag for tsc. Takes effect by clearing the TSC cpu flag + * in cpu/common.c + */ +static int __init tsc_setup(char *str) +{ + tsc_disable = 1; + + return 1; +} +#endif + +__setup("notsc", tsc_setup); + +/* + * code to mark and check if the TSC is unstable + * due to cpufreq or due to unsynced TSCs + */ +static int tsc_unstable; + +static inline int check_tsc_unstable(void) +{ + return tsc_unstable; +} + +void mark_tsc_unstable(void) +{ + tsc_unstable = 1; +} +EXPORT_SYMBOL_GPL(mark_tsc_unstable); + +/* Accellerators for sched_clock() + * convert from cycles(64bits) => nanoseconds (64bits) + * basic equation: + * ns = cycles / (freq / ns_per_sec) + * ns = cycles * (ns_per_sec / freq) + * ns = cycles * (10^9 / (cpu_khz * 10^3)) + * ns = cycles * (10^6 / cpu_khz) + * + * Then we use scaling math (suggested by george@mvista.com) to get: + * ns = cycles * (10^6 * SC / cpu_khz) / SC + * ns = cycles * cyc2ns_scale / SC + * + * And since SC is a constant power of two, we can convert the div + * into a shift. + * + * We can use khz divisor instead of mhz to keep a better percision, since + * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits. + * (mathieu.desnoyers@polymtl.ca) + * + * -johnstul@us.ibm.com "math is hard, lets go shopping!" + */ +static unsigned long cyc2ns_scale __read_mostly; + +#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ + +static inline void set_cyc2ns_scale(unsigned long cpu_khz) +{ + cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz; +} + +static inline unsigned long long cycles_2_ns(unsigned long long cyc) +{ + return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; +} + +/* + * Scheduler clock - returns current time in nanosec units. + */ +unsigned long long sched_clock(void) +{ + unsigned long long this_offset; + + /* + * in the NUMA case we dont use the TSC as they are not + * synchronized across all CPUs. + */ +#ifndef CONFIG_NUMA + if (!cpu_khz || check_tsc_unstable()) +#endif + /* no locking but a rare wrong value is not a big deal */ + return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ); + + /* read the Time Stamp Counter: */ + rdtscll(this_offset); + + /* return the value in ns */ + return cycles_2_ns(this_offset); +} + +static unsigned long calculate_cpu_khz(void) +{ + unsigned long long start, end; + unsigned long count; + u64 delta64; + int i; + unsigned long flags; + + local_irq_save(flags); + + /* run 3 times to ensure the cache is warm */ + for (i = 0; i < 3; i++) { + mach_prepare_counter(); + rdtscll(start); + mach_countup(&count); + rdtscll(end); + } + /* + * Error: ECTCNEVERSET + * The CTC wasn't reliable: we got a hit on the very first read, + * or the CPU was so fast/slow that the quotient wouldn't fit in + * 32 bits.. + */ + if (count <= 1) + goto err; + + delta64 = end - start; + + /* cpu freq too fast: */ + if (delta64 > (1ULL<<32)) + goto err; + + /* cpu freq too slow: */ + if (delta64 <= CALIBRATE_TIME_MSEC) + goto err; + + delta64 += CALIBRATE_TIME_MSEC/2; /* round for do_div */ + do_div(delta64,CALIBRATE_TIME_MSEC); + + local_irq_restore(flags); + return (unsigned long)delta64; +err: + local_irq_restore(flags); + return 0; +} + +int recalibrate_cpu_khz(void) +{ +#ifndef CONFIG_SMP + unsigned long cpu_khz_old = cpu_khz; + + if (cpu_has_tsc) { + cpu_khz = calculate_cpu_khz(); + tsc_khz = cpu_khz; + cpu_data[0].loops_per_jiffy = + cpufreq_scale(cpu_data[0].loops_per_jiffy, + cpu_khz_old, cpu_khz); + return 0; + } else + return -ENODEV; +#else + return -ENODEV; +#endif +} + +EXPORT_SYMBOL(recalibrate_cpu_khz); + +void tsc_init(void) +{ + if (!cpu_has_tsc || tsc_disable) + return; + + cpu_khz = calculate_cpu_khz(); + tsc_khz = cpu_khz; + + if (!cpu_khz) + return; + + printk("Detected %lu.%03lu MHz processor.\n", + (unsigned long)cpu_khz / 1000, + (unsigned long)cpu_khz % 1000); + + set_cyc2ns_scale(cpu_khz); + use_tsc_delay(); +} + +#ifdef CONFIG_CPU_FREQ + +static unsigned int cpufreq_delayed_issched = 0; +static unsigned int cpufreq_init = 0; +static struct work_struct cpufreq_delayed_get_work; + +static void handle_cpufreq_delayed_get(void *v) +{ + unsigned int cpu; + + for_each_online_cpu(cpu) + cpufreq_get(cpu); + + cpufreq_delayed_issched = 0; +} + +/* + * if we notice cpufreq oddness, schedule a call to cpufreq_get() as it tries + * to verify the CPU frequency the timing core thinks the CPU is running + * at is still correct. + */ +static inline void cpufreq_delayed_get(void) +{ + if (cpufreq_init && !cpufreq_delayed_issched) { + cpufreq_delayed_issched = 1; + printk(KERN_DEBUG "Checking if CPU frequency changed.\n"); + schedule_work(&cpufreq_delayed_get_work); + } +} + +/* + * if the CPU frequency is scaled, TSC-based delays will need a different + * loops_per_jiffy value to function properly. + */ +static unsigned int ref_freq = 0; +static unsigned long loops_per_jiffy_ref = 0; +static unsigned long cpu_khz_ref = 0; + +static int +time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data) +{ + struct cpufreq_freqs *freq = data; + + if (val != CPUFREQ_RESUMECHANGE && val != CPUFREQ_SUSPENDCHANGE) + write_seqlock_irq(&xtime_lock); + + if (!ref_freq) { + if (!freq->old){ + ref_freq = freq->new; + goto end; + } + ref_freq = freq->old; + loops_per_jiffy_ref = cpu_data[freq->cpu].loops_per_jiffy; + cpu_khz_ref = cpu_khz; + } + + if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) || + (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) || + (val == CPUFREQ_RESUMECHANGE)) { + if (!(freq->flags & CPUFREQ_CONST_LOOPS)) + cpu_data[freq->cpu].loops_per_jiffy = + cpufreq_scale(loops_per_jiffy_ref, + ref_freq, freq->new); + + if (cpu_khz) { + + if (num_online_cpus() == 1) + cpu_khz = cpufreq_scale(cpu_khz_ref, + ref_freq, freq->new); + if (!(freq->flags & CPUFREQ_CONST_LOOPS)) { + tsc_khz = cpu_khz; + set_cyc2ns_scale(cpu_khz); + /* + * TSC based sched_clock turns + * to junk w/ cpufreq + */ + mark_tsc_unstable(); + } + } + } +end: + if (val != CPUFREQ_RESUMECHANGE && val != CPUFREQ_SUSPENDCHANGE) + write_sequnlock_irq(&xtime_lock); + + return 0; +} + +static struct notifier_block time_cpufreq_notifier_block = { + .notifier_call = time_cpufreq_notifier +}; + +static int __init cpufreq_tsc(void) +{ + int ret; + + INIT_WORK(&cpufreq_delayed_get_work, handle_cpufreq_delayed_get, NULL); + ret = cpufreq_register_notifier(&time_cpufreq_notifier_block, + CPUFREQ_TRANSITION_NOTIFIER); + if (!ret) + cpufreq_init = 1; + + return ret; +} + +core_initcall(cpufreq_tsc); + +#endif + +/* clock source code */ + +static unsigned long current_tsc_khz = 0; +static int tsc_update_callback(void); + +static cycle_t read_tsc(void) +{ + cycle_t ret; + + rdtscll(ret); + + return ret; +} + +static struct clocksource clocksource_tsc = { + .name = "tsc", + .rating = 300, + .read = read_tsc, + .mask = CLOCKSOURCE_MASK(64), + .mult = 0, /* to be set */ + .shift = 22, + .update_callback = tsc_update_callback, + .is_continuous = 1, +}; + +static int tsc_update_callback(void) +{ + int change = 0; + + /* check to see if we should switch to the safe clocksource: */ + if (clocksource_tsc.rating != 50 && check_tsc_unstable()) { + clocksource_tsc.rating = 50; + clocksource_reselect(); + change = 1; + } + + /* only update if tsc_khz has changed: */ + if (current_tsc_khz != tsc_khz) { + current_tsc_khz = tsc_khz; + clocksource_tsc.mult = clocksource_khz2mult(current_tsc_khz, + clocksource_tsc.shift); + change = 1; + } + + return change; +} + +static int __init dmi_mark_tsc_unstable(struct dmi_system_id *d) +{ + printk(KERN_NOTICE "%s detected: marking TSC unstable.\n", + d->ident); + mark_tsc_unstable(); + return 0; +} + +/* List of systems that have known TSC problems */ +static struct dmi_system_id __initdata bad_tsc_dmi_table[] = { + { + .callback = dmi_mark_tsc_unstable, + .ident = "IBM Thinkpad 380XD", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), + DMI_MATCH(DMI_BOARD_NAME, "2635FA0"), + }, + }, + {} +}; + +#define TSC_FREQ_CHECK_INTERVAL (10*MSEC_PER_SEC) /* 10sec in MS */ +static struct timer_list verify_tsc_freq_timer; + +/* XXX - Probably should add locking */ +static void verify_tsc_freq(unsigned long unused) +{ + static u64 last_tsc; + static unsigned long last_jiffies; + + u64 now_tsc, interval_tsc; + unsigned long now_jiffies, interval_jiffies; + + + if (check_tsc_unstable()) + return; + + rdtscll(now_tsc); + now_jiffies = jiffies; + + if (!last_jiffies) { + goto out; + } + + interval_jiffies = now_jiffies - last_jiffies; + interval_tsc = now_tsc - last_tsc; + interval_tsc *= HZ; + do_div(interval_tsc, cpu_khz*1000); + + if (interval_tsc < (interval_jiffies * 3 / 4)) { + printk("TSC appears to be running slowly. " + "Marking it as unstable\n"); + mark_tsc_unstable(); + return; + } + +out: + last_tsc = now_tsc; + last_jiffies = now_jiffies; + /* set us up to go off on the next interval: */ + mod_timer(&verify_tsc_freq_timer, + jiffies + msecs_to_jiffies(TSC_FREQ_CHECK_INTERVAL)); +} + +/* + * Make an educated guess if the TSC is trustworthy and synchronized + * over all CPUs. + */ +static __init int unsynchronized_tsc(void) +{ + /* + * Intel systems are normally all synchronized. + * Exceptions must mark TSC as unstable: + */ + if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) + return 0; + + /* assume multi socket systems are not synchronized: */ + return num_possible_cpus() > 1; +} + +static int __init init_tsc_clocksource(void) +{ + + if (cpu_has_tsc && tsc_khz && !tsc_disable) { + /* check blacklist */ + dmi_check_system(bad_tsc_dmi_table); + + if (unsynchronized_tsc()) /* mark unstable if unsynced */ + mark_tsc_unstable(); + current_tsc_khz = tsc_khz; + clocksource_tsc.mult = clocksource_khz2mult(current_tsc_khz, + clocksource_tsc.shift); + /* lower the rating if we already know its unstable: */ + if (check_tsc_unstable()) + clocksource_tsc.rating = 50; + + init_timer(&verify_tsc_freq_timer); + verify_tsc_freq_timer.function = verify_tsc_freq; + verify_tsc_freq_timer.expires = + jiffies + msecs_to_jiffies(TSC_FREQ_CHECK_INTERVAL); + add_timer(&verify_tsc_freq_timer); + + return clocksource_register(&clocksource_tsc); + } + + return 0; +} + +module_init(init_tsc_clocksource); diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index 7512f39c9f2..2d4f1386e2b 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -71,6 +71,15 @@ SECTIONS .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) } _edata = .; /* End of data section */ +#ifdef CONFIG_STACK_UNWIND + . = ALIGN(4); + .eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) { + __start_unwind = .; + *(.eh_frame) + __end_unwind = .; + } +#endif + . = ALIGN(THREAD_SIZE); /* init_task */ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { *(.data.init_task) diff --git a/arch/i386/kernel/vsyscall-sysenter.S b/arch/i386/kernel/vsyscall-sysenter.S index 3b62baa6a37..1a36d26e15e 100644 --- a/arch/i386/kernel/vsyscall-sysenter.S +++ b/arch/i386/kernel/vsyscall-sysenter.S @@ -42,10 +42,10 @@ __kernel_vsyscall: /* 7: align return point with nop's to make disassembly easier */ .space 7,0x90 - /* 14: System call restart point is here! (SYSENTER_RETURN - 2) */ + /* 14: System call restart point is here! (SYSENTER_RETURN-2) */ jmp .Lenter_kernel /* 16: System call normal return point is here! */ - .globl SYSENTER_RETURN /* Symbol used by entry.S. */ + .globl SYSENTER_RETURN /* Symbol used by sysenter.c */ SYSENTER_RETURN: pop %ebp .Lpop_ebp: diff --git a/arch/i386/kernel/vsyscall.lds.S b/arch/i386/kernel/vsyscall.lds.S index 98699ca6e52..e26975fc68b 100644 --- a/arch/i386/kernel/vsyscall.lds.S +++ b/arch/i386/kernel/vsyscall.lds.S @@ -7,7 +7,7 @@ SECTIONS { - . = VSYSCALL_BASE + SIZEOF_HEADERS; + . = VDSO_PRELINK + SIZEOF_HEADERS; .hash : { *(.hash) } :text .dynsym : { *(.dynsym) } @@ -20,7 +20,7 @@ SECTIONS For the layouts to match, we need to skip more than enough space for the dynamic symbol table et al. If this amount is insufficient, ld -shared will barf. Just increase it here. */ - . = VSYSCALL_BASE + 0x400; + . = VDSO_PRELINK + 0x400; .text : { *(.text) } :text =0x90909090 .note : { *(.note.*) } :text :note diff --git a/arch/i386/lib/delay.c b/arch/i386/lib/delay.c index c49a6acbee5..3c0714c4b66 100644 --- a/arch/i386/lib/delay.c +++ b/arch/i386/lib/delay.c @@ -10,43 +10,92 @@ * we have to worry about. */ +#include <linux/module.h> #include <linux/config.h> #include <linux/sched.h> #include <linux/delay.h> -#include <linux/module.h> + #include <asm/processor.h> #include <asm/delay.h> #include <asm/timer.h> #ifdef CONFIG_SMP -#include <asm/smp.h> +# include <asm/smp.h> #endif -extern struct timer_opts* timer; +/* simple loop based delay: */ +static void delay_loop(unsigned long loops) +{ + int d0; + + __asm__ __volatile__( + "\tjmp 1f\n" + ".align 16\n" + "1:\tjmp 2f\n" + ".align 16\n" + "2:\tdecl %0\n\tjns 2b" + :"=&a" (d0) + :"0" (loops)); +} + +/* TSC based delay: */ +static void delay_tsc(unsigned long loops) +{ + unsigned long bclock, now; + + rdtscl(bclock); + do { + rep_nop(); + rdtscl(now); + } while ((now-bclock) < loops); +} + +/* + * Since we calibrate only once at boot, this + * function should be set once at boot and not changed + */ +static void (*delay_fn)(unsigned long) = delay_loop; + +void use_tsc_delay(void) +{ + delay_fn = delay_tsc; +} + +int read_current_timer(unsigned long *timer_val) +{ + if (delay_fn == delay_tsc) { + rdtscl(*timer_val); + return 0; + } + return -1; +} void __delay(unsigned long loops) { - cur_timer->delay(loops); + delay_fn(loops); } inline void __const_udelay(unsigned long xloops) { int d0; + xloops *= 4; __asm__("mull %0" :"=d" (xloops), "=&a" (d0) - :"1" (xloops),"0" (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (HZ/4))); - __delay(++xloops); + :"1" (xloops), "0" + (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (HZ/4))); + + __delay(++xloops); } void __udelay(unsigned long usecs) { - __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ + __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ } void __ndelay(unsigned long nsecs) { - __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ + __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ } EXPORT_SYMBOL(__delay); diff --git a/arch/i386/mach-visws/setup.c b/arch/i386/mach-visws/setup.c index 8a9e1a6f745..1f84cdb2477 100644 --- a/arch/i386/mach-visws/setup.c +++ b/arch/i386/mach-visws/setup.c @@ -140,8 +140,8 @@ void __init time_init_hook(void) #define MB (1024 * 1024) -static unsigned long sgivwfb_mem_phys; -static unsigned long sgivwfb_mem_size; +unsigned long sgivwfb_mem_phys; +unsigned long sgivwfb_mem_size; long long mem_size __initdata = 0; @@ -177,8 +177,4 @@ char * __init machine_specific_memory_setup(void) add_memory_region(sgivwfb_mem_phys, sgivwfb_mem_size, E820_RESERVED); return "PROM"; - - /* Remove gcc warnings */ - (void) sanitize_e820_map(NULL, NULL); - (void) copy_e820_map(NULL, 0); } diff --git a/arch/i386/mach-visws/visws_apic.c b/arch/i386/mach-visws/visws_apic.c index 3e64fb72129..c418521dd55 100644 --- a/arch/i386/mach-visws/visws_apic.c +++ b/arch/i386/mach-visws/visws_apic.c @@ -278,22 +278,22 @@ void init_VISWS_APIC_irqs(void) irq_desc[i].depth = 1; if (i == 0) { - irq_desc[i].handler = &cobalt_irq_type; + irq_desc[i].chip = &cobalt_irq_type; } else if (i == CO_IRQ_IDE0) { - irq_desc[i].handler = &cobalt_irq_type; + irq_desc[i].chip = &cobalt_irq_type; } else if (i == CO_IRQ_IDE1) { - irq_desc[i].handler = &cobalt_irq_type; + irq_desc[i].chip = &cobalt_irq_type; } else if (i == CO_IRQ_8259) { - irq_desc[i].handler = &piix4_master_irq_type; + irq_desc[i].chip = &piix4_master_irq_type; } else if (i < CO_IRQ_APIC0) { - irq_desc[i].handler = &piix4_virtual_irq_type; + irq_desc[i].chip = &piix4_virtual_irq_type; } else if (IS_CO_APIC(i)) { - irq_desc[i].handler = &cobalt_irq_type; + irq_desc[i].chip = &cobalt_irq_type; } } diff --git a/arch/i386/mach-voyager/setup.c b/arch/i386/mach-voyager/setup.c index 0e225054e22..defc6ebbd56 100644 --- a/arch/i386/mach-voyager/setup.c +++ b/arch/i386/mach-voyager/setup.c @@ -5,10 +5,10 @@ #include <linux/config.h> #include <linux/init.h> #include <linux/interrupt.h> -#include <asm/acpi.h> #include <asm/arch_hooks.h> #include <asm/voyager.h> #include <asm/e820.h> +#include <asm/io.h> #include <asm/setup.h> void __init pre_intr_init_hook(void) @@ -27,8 +27,7 @@ void __init intr_init_hook(void) smp_intr_init(); #endif - if (!acpi_ioapic) - setup_irq(2, &irq2); + setup_irq(2, &irq2); } void __init pre_setup_arch_hook(void) diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c index 70e560a1b79..5b8b579a079 100644 --- a/arch/i386/mach-voyager/voyager_smp.c +++ b/arch/i386/mach-voyager/voyager_smp.c @@ -661,6 +661,7 @@ do_boot_cpu(__u8 cpu) print_cpu_info(&cpu_data[cpu]); wmb(); cpu_set(cpu, cpu_callout_map); + cpu_set(cpu, cpu_present_map); } else { printk("CPU%d FAILED TO BOOT: ", cpu); @@ -1418,7 +1419,7 @@ smp_intr_init(void) * This is for later: first 16 correspond to PC IRQs; next 16 * are Primary MC IRQs and final 16 are Secondary MC IRQs */ for(i = 0; i < 48; i++) - irq_desc[i].handler = &vic_irq_type; + irq_desc[i].chip = &vic_irq_type; } /* send a CPI at level cpi to a set of cpus in cpuset (set 1 bit per @@ -1912,6 +1913,7 @@ void __devinit smp_prepare_boot_cpu(void) cpu_set(smp_processor_id(), cpu_online_map); cpu_set(smp_processor_id(), cpu_callout_map); cpu_set(smp_processor_id(), cpu_possible_map); + cpu_set(smp_processor_id(), cpu_present_map); } int __devinit diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index bd6fe96cc16..6ee7faaf2c1 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c @@ -30,6 +30,40 @@ extern void die(const char *,struct pt_regs *,long); +#ifdef CONFIG_KPROBES +ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); +int register_page_fault_notifier(struct notifier_block *nb) +{ + vmalloc_sync_all(); + return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); +} + +int unregister_page_fault_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); +} + +static inline int notify_page_fault(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + struct die_args args = { + .regs = regs, + .str = str, + .err = err, + .trapnr = trap, + .signr = sig + }; + return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); +} +#else +static inline int notify_page_fault(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + return NOTIFY_DONE; +} +#endif + + /* * Unlock any spinlocks which will prevent us from getting the * message out @@ -324,7 +358,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, if (unlikely(address >= TASK_SIZE)) { if (!(error_code & 0x0000000d) && vmalloc_fault(address) >= 0) return; - if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, + if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, SIGSEGV) == NOTIFY_STOP) return; /* @@ -334,7 +368,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, goto bad_area_nosemaphore; } - if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, + if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, SIGSEGV) == NOTIFY_STOP) return; diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index bf19513f0ce..f84b16e007f 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -23,6 +23,7 @@ #include <linux/init.h> #include <linux/highmem.h> #include <linux/pagemap.h> +#include <linux/poison.h> #include <linux/bootmem.h> #include <linux/slab.h> #include <linux/proc_fs.h> @@ -654,7 +655,7 @@ void __init mem_init(void) */ #ifdef CONFIG_MEMORY_HOTPLUG #ifndef CONFIG_NEED_MULTIPLE_NODES -int add_memory(u64 start, u64 size) +int arch_add_memory(int nid, u64 start, u64 size) { struct pglist_data *pgdata = &contig_page_data; struct zone *zone = pgdata->node_zones + MAX_NR_ZONES-1; @@ -753,7 +754,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) for (addr = begin; addr < end; addr += PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); init_page_count(virt_to_page(addr)); - memset((void *)addr, 0xcc, PAGE_SIZE); + memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); free_page(addr); totalram_pages++; } diff --git a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c index 0887b34bc59..353a836ed63 100644 --- a/arch/i386/mm/pageattr.c +++ b/arch/i386/mm/pageattr.c @@ -229,8 +229,8 @@ void kernel_map_pages(struct page *page, int numpages, int enable) if (PageHighMem(page)) return; if (!enable) - mutex_debug_check_no_locks_freed(page_address(page), - numpages * PAGE_SIZE); + debug_check_no_locks_freed(page_address(page), + numpages * PAGE_SIZE); /* the return value is ignored - the calls cannot fail, * large pages are disabled at boot time. diff --git a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c index ec0fd3cfa77..fa8a37bcb39 100644 --- a/arch/i386/oprofile/nmi_int.c +++ b/arch/i386/oprofile/nmi_int.c @@ -281,9 +281,9 @@ static int nmi_create_files(struct super_block * sb, struct dentry * root) for (i = 0; i < model->num_counters; ++i) { struct dentry * dir; - char buf[2]; + char buf[4]; - snprintf(buf, 2, "%d", i); + snprintf(buf, sizeof(buf), "%d", i); dir = oprofilefs_mkdir(sb, root, buf); oprofilefs_create_ulong(sb, dir, "enabled", &counter_config[i].enabled); oprofilefs_create_ulong(sb, dir, "event", &counter_config[i].event); diff --git a/arch/i386/oprofile/op_model_athlon.c b/arch/i386/oprofile/op_model_athlon.c index 3ad9a72a503..693bdea4a52 100644 --- a/arch/i386/oprofile/op_model_athlon.c +++ b/arch/i386/oprofile/op_model_athlon.c @@ -13,6 +13,7 @@ #include <linux/oprofile.h> #include <asm/ptrace.h> #include <asm/msr.h> +#include <asm/nmi.h> #include "op_x86_model.h" #include "op_counter.h" diff --git a/arch/i386/oprofile/op_model_p4.c b/arch/i386/oprofile/op_model_p4.c index ac8a066035c..7c61d357b82 100644 --- a/arch/i386/oprofile/op_model_p4.c +++ b/arch/i386/oprofile/op_model_p4.c @@ -14,6 +14,7 @@ #include <asm/ptrace.h> #include <asm/fixmap.h> #include <asm/apic.h> +#include <asm/nmi.h> #include "op_x86_model.h" #include "op_counter.h" diff --git a/arch/i386/oprofile/op_model_ppro.c b/arch/i386/oprofile/op_model_ppro.c index d719015fc04..5c3ab4b027a 100644 --- a/arch/i386/oprofile/op_model_ppro.c +++ b/arch/i386/oprofile/op_model_ppro.c @@ -14,6 +14,7 @@ #include <asm/ptrace.h> #include <asm/msr.h> #include <asm/apic.h> +#include <asm/nmi.h> #include "op_x86_model.h" #include "op_counter.h" diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c index a151f7a99f5..10154a2cac6 100644 --- a/arch/i386/pci/i386.c +++ b/arch/i386/pci/i386.c @@ -48,10 +48,10 @@ */ void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; + resource_size_t start = res->start; if (start & 0x300) { start = (start + 0x3ff) & ~0x3ff; diff --git a/arch/i386/pci/pcbios.c b/arch/i386/pci/pcbios.c index 1eec0868f4b..ed1512a175a 100644 --- a/arch/i386/pci/pcbios.c +++ b/arch/i386/pci/pcbios.c @@ -371,8 +371,7 @@ void __devinit pcibios_sort(void) list_for_each(ln, &pci_devices) { d = pci_dev_g(ln); if (d->bus->number == bus && d->devfn == devfn) { - list_del(&d->global_list); - list_add_tail(&d->global_list, &sorted_devices); + list_move_tail(&d->global_list, &sorted_devices); if (d == dev) found = 1; break; @@ -390,8 +389,7 @@ void __devinit pcibios_sort(void) if (!found) { printk(KERN_WARNING "PCI: Device %s not found by BIOS\n", pci_name(dev)); - list_del(&dev->global_list); - list_add_tail(&dev->global_list, &sorted_devices); + list_move_tail(&dev->global_list, &sorted_devices); } } list_splice(&sorted_devices, &pci_devices); diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 18318749884..b487e227a1f 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -271,6 +271,9 @@ config HOTPLUG_CPU can be controlled through /sys/devices/system/cpu/cpu#. Say N if you want to disable CPU hotplug. +config ARCH_ENABLE_MEMORY_HOTPLUG + def_bool y + config SCHED_SMT bool "SMT scheduler support" depends on SMP @@ -374,6 +377,10 @@ config HAVE_ARCH_EARLY_PFN_TO_NID def_bool y depends on NEED_MULTIPLE_NODES +config HAVE_ARCH_NODEDATA_EXTENSION + def_bool y + depends on NUMA + config IA32_SUPPORT bool "Support for Linux/x86 binaries" help @@ -485,6 +492,10 @@ config GENERIC_PENDING_IRQ depends on GENERIC_HARDIRQS && SMP default y +config IRQ_PER_CPU + bool + default y + source "arch/ia64/hp/sim/Kconfig" menu "Instrumentation Support" diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig index 766bf495543..9d1cffb57cd 100644 --- a/arch/ia64/configs/tiger_defconfig +++ b/arch/ia64/configs/tiger_defconfig @@ -114,7 +114,7 @@ CONFIG_IA64_CYCLONE=y CONFIG_IOSAPIC=y CONFIG_FORCE_MAX_ZONEORDER=17 CONFIG_SMP=y -CONFIG_NR_CPUS=4 +CONFIG_NR_CPUS=16 CONFIG_HOTPLUG_CPU=y CONFIG_PERMIT_BSP_REMOVE=y CONFIG_FORCE_CPEI_RETARGET=y diff --git a/arch/ia64/hp/sim/hpsim_irq.c b/arch/ia64/hp/sim/hpsim_irq.c index c0d25a2a3e9..8145547bb52 100644 --- a/arch/ia64/hp/sim/hpsim_irq.c +++ b/arch/ia64/hp/sim/hpsim_irq.c @@ -44,8 +44,8 @@ hpsim_irq_init (void) int i; for (i = 0; i < NR_IRQS; ++i) { - idesc = irq_descp(i); - if (idesc->handler == &no_irq_type) - idesc->handler = &irq_type_hp_sim; + idesc = irq_desc + i; + if (idesc->chip == &no_irq_type) + idesc->chip = &irq_type_hp_sim; } } diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index d58c1c5c903..efc7df4b0fd 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -456,7 +456,7 @@ iosapic_startup_edge_irq (unsigned int irq) static void iosapic_ack_edge_irq (unsigned int irq) { - irq_desc_t *idesc = irq_descp(irq); + irq_desc_t *idesc = irq_desc + irq; move_native_irq(irq); /* @@ -659,14 +659,14 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery, else irq_type = &irq_type_iosapic_level; - idesc = irq_descp(vector); - if (idesc->handler != irq_type) { - if (idesc->handler != &no_irq_type) + idesc = irq_desc + vector; + if (idesc->chip != irq_type) { + if (idesc->chip != &no_irq_type) printk(KERN_WARNING "%s: changing vector %d from %s to %s\n", __FUNCTION__, vector, - idesc->handler->typename, irq_type->typename); - idesc->handler = irq_type; + idesc->chip->typename, irq_type->typename); + idesc->chip = irq_type; } return 0; } @@ -793,14 +793,14 @@ again: return -ENOSPC; } - spin_lock_irqsave(&irq_descp(vector)->lock, flags); + spin_lock_irqsave(&irq_desc[vector].lock, flags); spin_lock(&iosapic_lock); { if (gsi_to_vector(gsi) > 0) { if (list_empty(&iosapic_intr_info[vector].rtes)) free_irq_vector(vector); spin_unlock(&iosapic_lock); - spin_unlock_irqrestore(&irq_descp(vector)->lock, + spin_unlock_irqrestore(&irq_desc[vector].lock, flags); goto again; } @@ -810,7 +810,7 @@ again: polarity, trigger); if (err < 0) { spin_unlock(&iosapic_lock); - spin_unlock_irqrestore(&irq_descp(vector)->lock, + spin_unlock_irqrestore(&irq_desc[vector].lock, flags); return err; } @@ -825,7 +825,7 @@ again: set_rte(gsi, vector, dest, mask); } spin_unlock(&iosapic_lock); - spin_unlock_irqrestore(&irq_descp(vector)->lock, flags); + spin_unlock_irqrestore(&irq_desc[vector].lock, flags); printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n", gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), @@ -860,7 +860,7 @@ iosapic_unregister_intr (unsigned int gsi) } vector = irq_to_vector(irq); - idesc = irq_descp(irq); + idesc = irq_desc + irq; spin_lock_irqsave(&idesc->lock, flags); spin_lock(&iosapic_lock); { @@ -903,7 +903,7 @@ iosapic_unregister_intr (unsigned int gsi) BUG_ON(iosapic_intr_info[vector].count); /* Clear the interrupt controller descriptor */ - idesc->handler = &no_irq_type; + idesc->chip = &no_irq_type; /* Clear the interrupt information */ memset(&iosapic_intr_info[vector], 0, diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c index 9c72ea3f643..7852382de2f 100644 --- a/arch/ia64/kernel/irq.c +++ b/arch/ia64/kernel/irq.c @@ -76,7 +76,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); } #endif - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -100,7 +100,7 @@ void set_irq_affinity_info (unsigned int irq, int hwid, int redir) cpu_set(cpu_logical_id(hwid), mask); if (irq < NR_IRQS) { - irq_affinity[irq] = mask; + irq_desc[irq].affinity = mask; irq_redir[irq] = (char) (redir & 0xff); } } @@ -120,7 +120,7 @@ static void migrate_irqs(void) int irq, new_cpu; for (irq=0; irq < NR_IRQS; irq++) { - desc = irq_descp(irq); + desc = irq_desc + irq; /* * No handling for now. @@ -131,7 +131,7 @@ static void migrate_irqs(void) if (desc->status == IRQ_PER_CPU) continue; - cpus_and(mask, irq_affinity[irq], cpu_online_map); + cpus_and(mask, irq_desc[irq].affinity, cpu_online_map); if (any_online_cpu(mask) == NR_CPUS) { /* * Save it for phase 2 processing @@ -144,15 +144,15 @@ static void migrate_irqs(void) /* * Al three are essential, currently WARN_ON.. maybe panic? */ - if (desc->handler && desc->handler->disable && - desc->handler->enable && desc->handler->set_affinity) { - desc->handler->disable(irq); - desc->handler->set_affinity(irq, mask); - desc->handler->enable(irq); + if (desc->chip && desc->chip->disable && + desc->chip->enable && desc->chip->set_affinity) { + desc->chip->disable(irq); + desc->chip->set_affinity(irq, mask); + desc->chip->enable(irq); } else { - WARN_ON((!(desc->handler) || !(desc->handler->disable) || - !(desc->handler->enable) || - !(desc->handler->set_affinity))); + WARN_ON((!(desc->chip) || !(desc->chip->disable) || + !(desc->chip->enable) || + !(desc->chip->set_affinity))); } } } diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index ef9a2b49307..f5035304594 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -249,9 +249,9 @@ register_percpu_irq (ia64_vector vec, struct irqaction *action) for (irq = 0; irq < NR_IRQS; ++irq) if (irq_to_vector(irq) == vec) { - desc = irq_descp(irq); + desc = irq_desc + irq; desc->status |= IRQ_PER_CPU; - desc->handler = &irq_type_ia64_lsapic; + desc->chip = &irq_type_ia64_lsapic; if (action) setup_irq(irq, action); } diff --git a/arch/ia64/kernel/irq_lsapic.c b/arch/ia64/kernel/irq_lsapic.c index ea14e6a0440..1ab58b09f3d 100644 --- a/arch/ia64/kernel/irq_lsapic.c +++ b/arch/ia64/kernel/irq_lsapic.c @@ -26,6 +26,13 @@ lsapic_noop (unsigned int irq) /* nuthing to do... */ } +static int lsapic_retrigger(unsigned int irq) +{ + ia64_resend_irq(irq); + + return 1; +} + struct hw_interrupt_type irq_type_ia64_lsapic = { .typename = "LSAPIC", .startup = lsapic_noop_startup, @@ -33,5 +40,6 @@ struct hw_interrupt_type irq_type_ia64_lsapic = { .enable = lsapic_noop, .disable = lsapic_noop, .ack = lsapic_noop, - .end = lsapic_noop + .end = lsapic_noop, + .retrigger = lsapic_retrigger, }; diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 6a0880639bc..d7dc5e63de6 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -1788,7 +1788,7 @@ ia64_mca_late_init(void) cpe_poll_enabled = 0; for (irq = 0; irq < NR_IRQS; ++irq) if (irq_to_vector(irq) == cpe_vector) { - desc = irq_descp(irq); + desc = irq_desc + irq; desc->status |= IRQ_PER_CPU; setup_irq(irq, &mca_cpe_irqaction); ia64_cpe_irq = irq; diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c index 859fb37ff49..8a120841913 100644 --- a/arch/ia64/kernel/palinfo.c +++ b/arch/ia64/kernel/palinfo.c @@ -959,7 +959,7 @@ remove_palinfo_proc_entries(unsigned int hcpu) } } -static int palinfo_cpu_callback(struct notifier_block *nfb, +static int __cpuinit palinfo_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { @@ -978,7 +978,7 @@ static int palinfo_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block palinfo_cpu_notifier = +static struct notifier_block __cpuinitdata palinfo_cpu_notifier = { .notifier_call = palinfo_cpu_callback, .priority = 0, @@ -998,7 +998,7 @@ palinfo_init(void) } /* Register for future delivery via notify registration */ - register_cpu_notifier(&palinfo_cpu_notifier); + register_hotcpu_notifier(&palinfo_cpu_notifier); return 0; } diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 6d7bc8ff7b3..a0055d3d695 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -6165,7 +6165,7 @@ pfm_load_regs (struct task_struct *task) /* * will replay the PMU interrupt */ - if (need_irq_resend) hw_resend_irq(NULL, IA64_PERFMON_VECTOR); + if (need_irq_resend) ia64_resend_irq(IA64_PERFMON_VECTOR); pfm_stats[smp_processor_id()].pfm_replay_ovfl_intr_count++; } @@ -6305,7 +6305,7 @@ pfm_load_regs (struct task_struct *task) /* * will replay the PMU interrupt */ - if (need_irq_resend) hw_resend_irq(NULL, IA64_PERFMON_VECTOR); + if (need_irq_resend) ia64_resend_irq(IA64_PERFMON_VECTOR); pfm_stats[smp_processor_id()].pfm_replay_ovfl_intr_count++; } diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 355d57970ba..b045c279136 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -272,9 +272,9 @@ cpu_idle (void) /* endless idle loop with no priority at all */ while (1) { if (can_do_pal_halt) - clear_thread_flag(TIF_POLLING_NRFLAG); + current_thread_info()->status &= ~TS_POLLING; else - set_thread_flag(TIF_POLLING_NRFLAG); + current_thread_info()->status |= TS_POLLING; if (!need_resched()) { void (*idle)(void); diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c index 663a186ad19..9065f0f01ba 100644 --- a/arch/ia64/kernel/salinfo.c +++ b/arch/ia64/kernel/salinfo.c @@ -572,7 +572,7 @@ static struct file_operations salinfo_data_fops = { }; #ifdef CONFIG_HOTPLUG_CPU -static int +static int __devinit salinfo_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) { unsigned int i, cpu = (unsigned long)hcpu; @@ -673,9 +673,7 @@ salinfo_init(void) salinfo_timer.function = &salinfo_timeout; add_timer(&salinfo_timer); -#ifdef CONFIG_HOTPLUG_CPU - register_cpu_notifier(&salinfo_cpu_notifier); -#endif + register_hotcpu_notifier(&salinfo_cpu_notifier); return 0; } diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 44e9547878a..5203df78f15 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -677,16 +677,16 @@ int migrate_platform_irqs(unsigned int cpu) new_cpei_cpu = any_online_cpu(cpu_online_map); mask = cpumask_of_cpu(new_cpei_cpu); set_cpei_target_cpu(new_cpei_cpu); - desc = irq_descp(ia64_cpe_irq); + desc = irq_desc + ia64_cpe_irq; /* * Switch for now, immediatly, we need to do fake intr * as other interrupts, but need to study CPEI behaviour with * polling before making changes. */ if (desc) { - desc->handler->disable(ia64_cpe_irq); - desc->handler->set_affinity(ia64_cpe_irq, mask); - desc->handler->enable(ia64_cpe_irq); + desc->chip->disable(ia64_cpe_irq); + desc->chip->set_affinity(ia64_cpe_irq, mask); + desc->chip->enable(ia64_cpe_irq); printk ("Re-targetting CPEI to cpu %d\n", new_cpei_cpu); } } diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c index 879edb51d1e..5511d9c6c70 100644 --- a/arch/ia64/kernel/topology.c +++ b/arch/ia64/kernel/topology.c @@ -26,19 +26,10 @@ #include <asm/numa.h> #include <asm/cpu.h> -#ifdef CONFIG_NUMA -static struct node *sysfs_nodes; -#endif static struct ia64_cpu *sysfs_cpus; int arch_register_cpu(int num) { - struct node *parent = NULL; - -#ifdef CONFIG_NUMA - parent = &sysfs_nodes[cpu_to_node(num)]; -#endif /* CONFIG_NUMA */ - #if defined (CONFIG_ACPI) && defined (CONFIG_HOTPLUG_CPU) /* * If CPEI cannot be re-targetted, and this is @@ -48,21 +39,14 @@ int arch_register_cpu(int num) sysfs_cpus[num].cpu.no_control = 1; #endif - return register_cpu(&sysfs_cpus[num].cpu, num, parent); + return register_cpu(&sysfs_cpus[num].cpu, num); } #ifdef CONFIG_HOTPLUG_CPU void arch_unregister_cpu(int num) { - struct node *parent = NULL; - -#ifdef CONFIG_NUMA - int node = cpu_to_node(num); - parent = &sysfs_nodes[node]; -#endif /* CONFIG_NUMA */ - - return unregister_cpu(&sysfs_cpus[num].cpu, parent); + return unregister_cpu(&sysfs_cpus[num].cpu); } EXPORT_SYMBOL(arch_register_cpu); EXPORT_SYMBOL(arch_unregister_cpu); @@ -74,17 +58,11 @@ static int __init topology_init(void) int i, err = 0; #ifdef CONFIG_NUMA - sysfs_nodes = kzalloc(sizeof(struct node) * MAX_NUMNODES, GFP_KERNEL); - if (!sysfs_nodes) { - err = -ENOMEM; - goto out; - } - /* * MCD - Do we want to register all ONLINE nodes, or all POSSIBLE nodes? */ for_each_online_node(i) { - if ((err = register_node(&sysfs_nodes[i], i, 0))) + if ((err = register_one_node(i))) goto out; } #endif @@ -426,7 +404,7 @@ static int __cpuinit cache_remove_dev(struct sys_device * sys_dev) * When a cpu is hot-plugged, do a check and initiate * cache kobject if necessary */ -static int cache_cpu_callback(struct notifier_block *nfb, +static int __cpuinit cache_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; @@ -444,7 +422,7 @@ static int cache_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block cache_cpu_notifier = +static struct notifier_block __cpuinitdata cache_cpu_notifier = { .notifier_call = cache_cpu_callback }; diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index b6bcc9fa360..525b082eb66 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c @@ -33,7 +33,6 @@ */ struct early_node_data { struct ia64_node_data *node_data; - pg_data_t *pgdat; unsigned long pernode_addr; unsigned long pernode_size; struct bootmem_data bootmem_data; @@ -46,6 +45,8 @@ struct early_node_data { static struct early_node_data mem_data[MAX_NUMNODES] __initdata; static nodemask_t memory_less_mask __initdata; +static pg_data_t *pgdat_list[MAX_NUMNODES]; + /* * To prevent cache aliasing effects, align per-node structures so that they * start at addresses that are strided by node number. @@ -99,7 +100,7 @@ static int __init build_node_maps(unsigned long start, unsigned long len, * acpi_boot_init() (which builds the node_to_cpu_mask array) hasn't been * called yet. Note that node 0 will also count all non-existent cpus. */ -static int __init early_nr_cpus_node(int node) +static int __meminit early_nr_cpus_node(int node) { int cpu, n = 0; @@ -114,7 +115,7 @@ static int __init early_nr_cpus_node(int node) * compute_pernodesize - compute size of pernode data * @node: the node id. */ -static unsigned long __init compute_pernodesize(int node) +static unsigned long __meminit compute_pernodesize(int node) { unsigned long pernodesize = 0, cpus; @@ -175,13 +176,13 @@ static void __init fill_pernode(int node, unsigned long pernode, pernode += PERCPU_PAGE_SIZE * cpus; pernode += node * L1_CACHE_BYTES; - mem_data[node].pgdat = __va(pernode); + pgdat_list[node] = __va(pernode); pernode += L1_CACHE_ALIGN(sizeof(pg_data_t)); mem_data[node].node_data = __va(pernode); pernode += L1_CACHE_ALIGN(sizeof(struct ia64_node_data)); - mem_data[node].pgdat->bdata = bdp; + pgdat_list[node]->bdata = bdp; pernode += L1_CACHE_ALIGN(sizeof(pg_data_t)); cpu_data = per_cpu_node_setup(cpu_data, node); @@ -268,7 +269,7 @@ static int __init find_pernode_space(unsigned long start, unsigned long len, static int __init free_node_bootmem(unsigned long start, unsigned long len, int node) { - free_bootmem_node(mem_data[node].pgdat, start, len); + free_bootmem_node(pgdat_list[node], start, len); return 0; } @@ -287,7 +288,7 @@ static void __init reserve_pernode_space(void) int node; for_each_online_node(node) { - pg_data_t *pdp = mem_data[node].pgdat; + pg_data_t *pdp = pgdat_list[node]; if (node_isset(node, memory_less_mask)) continue; @@ -307,6 +308,17 @@ static void __init reserve_pernode_space(void) } } +static void __meminit scatter_node_data(void) +{ + pg_data_t **dst; + int node; + + for_each_online_node(node) { + dst = LOCAL_DATA_ADDR(pgdat_list[node])->pg_data_ptrs; + memcpy(dst, pgdat_list, sizeof(pgdat_list)); + } +} + /** * initialize_pernode_data - fixup per-cpu & per-node pointers * @@ -317,17 +329,10 @@ static void __init reserve_pernode_space(void) */ static void __init initialize_pernode_data(void) { - pg_data_t *pgdat_list[MAX_NUMNODES]; int cpu, node; - for_each_online_node(node) - pgdat_list[node] = mem_data[node].pgdat; + scatter_node_data(); - /* Copy the pg_data_t list to each node and init the node field */ - for_each_online_node(node) { - memcpy(mem_data[node].node_data->pg_data_ptrs, pgdat_list, - sizeof(pgdat_list)); - } #ifdef CONFIG_SMP /* Set the node_data pointer for each per-cpu struct */ for (cpu = 0; cpu < NR_CPUS; cpu++) { @@ -372,7 +377,7 @@ static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize) if (bestnode == -1) bestnode = anynode; - ptr = __alloc_bootmem_node(mem_data[bestnode].pgdat, pernodesize, + ptr = __alloc_bootmem_node(pgdat_list[bestnode], pernodesize, PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS)); return ptr; @@ -476,7 +481,7 @@ void __init find_memory(void) pernodesize = mem_data[node].pernode_size; map = pernode + pernodesize; - init_bootmem_node(mem_data[node].pgdat, + init_bootmem_node(pgdat_list[node], map>>PAGE_SHIFT, bdp->node_boot_start>>PAGE_SHIFT, bdp->node_low_pfn); @@ -786,3 +791,21 @@ void __init paging_init(void) zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page)); } + +pg_data_t *arch_alloc_nodedata(int nid) +{ + unsigned long size = compute_pernodesize(nid); + + return kzalloc(size, GFP_KERNEL); +} + +void arch_free_nodedata(pg_data_t *pgdat) +{ + kfree(pgdat); +} + +void arch_refresh_nodedata(int update_node, pg_data_t *update_pgdat) +{ + pgdat_list[update_node] = update_pgdat; + scatter_node_data(); +} diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c index d98ec49570b..14ef7cceb20 100644 --- a/arch/ia64/mm/fault.c +++ b/arch/ia64/mm/fault.c @@ -19,6 +19,40 @@ extern void die (char *, struct pt_regs *, long); +#ifdef CONFIG_KPROBES +ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); + +/* Hook to register for page fault notifications */ +int register_page_fault_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); +} + +int unregister_page_fault_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); +} + +static inline int notify_page_fault(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + struct die_args args = { + .regs = regs, + .str = str, + .err = err, + .trapnr = trap, + .signr = sig + }; + return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); +} +#else +static inline int notify_page_fault(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + return NOTIFY_DONE; +} +#endif + /* * Return TRUE if ADDRESS points at a page in the kernel's mapped segment * (inside region 5, on ia64) and that page is present. @@ -84,7 +118,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re /* * This is to handle the kprobes on user space access instructions */ - if (notify_die(DIE_PAGE_FAULT, "page fault", regs, code, TRAP_BRKPT, + if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, code, TRAP_BRKPT, SIGSEGV) == NOTIFY_STOP) return; diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 11f08001f8c..38306e98f04 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -652,7 +652,7 @@ void online_page(struct page *page) num_physpages++; } -int add_memory(u64 start, u64 size) +int arch_add_memory(int nid, u64 start, u64 size) { pg_data_t *pgdat; struct zone *zone; @@ -660,7 +660,7 @@ int add_memory(u64 start, u64 size) unsigned long nr_pages = size >> PAGE_SHIFT; int ret; - pgdat = NODE_DATA(0); + pgdat = NODE_DATA(nid); zone = pgdat->node_zones + ZONE_NORMAL; ret = __add_pages(zone, start_pfn, nr_pages); @@ -671,7 +671,6 @@ int add_memory(u64 start, u64 size) return ret; } -EXPORT_SYMBOL_GPL(add_memory); int remove_memory(u64 start, u64 size) { diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 77375a55da3..5bef0e3603f 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -568,7 +568,7 @@ pcibios_disable_device (struct pci_dev *dev) void pcibios_align_resource (void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { } diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index dc8e2b69671..7bb6ad188ba 100644 --- a/arch/ia64/sn/kernel/irq.c +++ b/arch/ia64/sn/kernel/irq.c @@ -27,7 +27,7 @@ static void unregister_intr_pda(struct sn_irq_info *sn_irq_info); int sn_force_interrupt_flag = 1; extern int sn_ioif_inited; struct list_head **sn_irq_lh; -static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */ +static DEFINE_SPINLOCK(sn_irq_info_lock); /* non-IRQ lock */ u64 sn_intr_alloc(nasid_t local_nasid, int local_widget, struct sn_irq_info *sn_irq_info, @@ -225,8 +225,8 @@ void sn_irq_init(void) ia64_last_device_vector = IA64_SN2_LAST_DEVICE_VECTOR; for (i = 0; i < NR_IRQS; i++) { - if (base_desc[i].handler == &no_irq_type) { - base_desc[i].handler = &irq_type_sn; + if (base_desc[i].chip == &no_irq_type) { + base_desc[i].chip = &irq_type_sn; } } } diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index 93577abae36..3bfccf35434 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c @@ -458,7 +458,7 @@ void __init sn_setup(char **cmdline_p) * support here so we don't have to listen to failed keyboard probe * messages. */ - if (version <= 0x0209 && acpi_kbd_controller_present) { + if (is_shub1() && version <= 0x0209 && acpi_kbd_controller_present) { printk(KERN_INFO "Disabling legacy keyboard support as prom " "is too old and doesn't provide FADT\n"); acpi_kbd_controller_present = 0; @@ -577,7 +577,8 @@ void __init sn_cpu_init(void) int i; static int wars_have_been_checked; - if (smp_processor_id() == 0 && IS_MEDUSA()) { + cpuid = smp_processor_id(); + if (cpuid == 0 && IS_MEDUSA()) { if (ia64_sn_is_fake_prom()) sn_prom_type = 2; else @@ -597,6 +598,12 @@ void __init sn_cpu_init(void) sn_hub_info->as_shift = sn_hub_info->nasid_shift - 2; /* + * Don't check status. The SAL call is not supported on all PROMs + * but a failure is harmless. + */ + (void) ia64_sn_set_cpu_number(cpuid); + + /* * The boot cpu makes this call again after platform initialization is * complete. */ @@ -607,7 +614,6 @@ void __init sn_cpu_init(void) if (ia64_sn_get_prom_feature_set(i, &sn_prom_features[i]) != 0) break; - cpuid = smp_processor_id(); cpuphyid = get_sapicid(); if (ia64_sn_get_sapic_info(cpuphyid, &nasid, &subnode, &slice)) diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c index 20de72791b9..e4aa839d018 100644 --- a/arch/ia64/sn/pci/tioca_provider.c +++ b/arch/ia64/sn/pci/tioca_provider.c @@ -595,7 +595,7 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont /* sanity check prom rev */ - if (sn_sal_rev() < 0x0406) { + if (is_shub1() && sn_sal_rev() < 0x0406) { printk (KERN_ERR "%s: SGI prom rev 4.06 or greater required " "for tioca support\n", __FUNCTION__); diff --git a/arch/m32r/kernel/irq.c b/arch/m32r/kernel/irq.c index a4634b06f67..3841861df6a 100644 --- a/arch/m32r/kernel/irq.c +++ b/arch/m32r/kernel/irq.c @@ -54,7 +54,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c index 3cd3c2988a4..1ff483c8a4c 100644 --- a/arch/m32r/kernel/setup.c +++ b/arch/m32r/kernel/setup.c @@ -275,7 +275,7 @@ static int __init topology_init(void) int i; for_each_present_cpu(i) - register_cpu(&cpu_devices[i], i, NULL); + register_cpu(&cpu_devices[i], i); return 0; } diff --git a/arch/m32r/kernel/setup_m32104ut.c b/arch/m32r/kernel/setup_m32104ut.c index 6328e1357a8..f9f56c27019 100644 --- a/arch/m32r/kernel/setup_m32104ut.c +++ b/arch/m32r/kernel/setup_m32104ut.c @@ -87,7 +87,7 @@ void __init init_IRQ(void) #if defined(CONFIG_SMC91X) /* INT#0: LAN controller on M32104UT-LAN (SMC91C111)*/ irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT0].handler = &m32104ut_irq_type; + irq_desc[M32R_IRQ_INT0].chip = &m32104ut_irq_type; irq_desc[M32R_IRQ_INT0].action = 0; irq_desc[M32R_IRQ_INT0].depth = 1; icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD11; /* "H" level sense */ @@ -96,7 +96,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].handler = &m32104ut_irq_type; + irq_desc[M32R_IRQ_MFT2].chip = &m32104ut_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -105,7 +105,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SERIAL_M32R_SIO /* SIO0_R : uart receive data */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].handler = &m32104ut_irq_type; + irq_desc[M32R_IRQ_SIO0_R].chip = &m32104ut_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = M32R_ICUCR_IEN; @@ -113,7 +113,7 @@ void __init init_IRQ(void) /* SIO0_S : uart send data */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].handler = &m32104ut_irq_type; + irq_desc[M32R_IRQ_SIO0_S].chip = &m32104ut_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = M32R_ICUCR_IEN; diff --git a/arch/m32r/kernel/setup_m32700ut.c b/arch/m32r/kernel/setup_m32700ut.c index fad1fc99bb2..b6ab00eff58 100644 --- a/arch/m32r/kernel/setup_m32700ut.c +++ b/arch/m32r/kernel/setup_m32700ut.c @@ -301,7 +301,7 @@ void __init init_IRQ(void) #if defined(CONFIG_SMC91X) /* INT#0: LAN controller on M32700UT-LAN (SMC91C111)*/ irq_desc[M32700UT_LAN_IRQ_LAN].status = IRQ_DISABLED; - irq_desc[M32700UT_LAN_IRQ_LAN].handler = &m32700ut_lanpld_irq_type; + irq_desc[M32700UT_LAN_IRQ_LAN].chip = &m32700ut_lanpld_irq_type; irq_desc[M32700UT_LAN_IRQ_LAN].action = 0; irq_desc[M32700UT_LAN_IRQ_LAN].depth = 1; /* disable nested irq */ lanpld_icu_data[irq2lanpldirq(M32700UT_LAN_IRQ_LAN)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* "H" edge sense */ @@ -310,7 +310,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].handler = &m32700ut_irq_type; + irq_desc[M32R_IRQ_MFT2].chip = &m32700ut_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -318,7 +318,7 @@ void __init init_IRQ(void) /* SIO0 : receive */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].handler = &m32700ut_irq_type; + irq_desc[M32R_IRQ_SIO0_R].chip = &m32700ut_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = 0; @@ -326,7 +326,7 @@ void __init init_IRQ(void) /* SIO0 : send */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].handler = &m32700ut_irq_type; + irq_desc[M32R_IRQ_SIO0_S].chip = &m32700ut_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = 0; @@ -334,7 +334,7 @@ void __init init_IRQ(void) /* SIO1 : receive */ irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_R].handler = &m32700ut_irq_type; + irq_desc[M32R_IRQ_SIO1_R].chip = &m32700ut_irq_type; irq_desc[M32R_IRQ_SIO1_R].action = 0; irq_desc[M32R_IRQ_SIO1_R].depth = 1; icu_data[M32R_IRQ_SIO1_R].icucr = 0; @@ -342,7 +342,7 @@ void __init init_IRQ(void) /* SIO1 : send */ irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_S].handler = &m32700ut_irq_type; + irq_desc[M32R_IRQ_SIO1_S].chip = &m32700ut_irq_type; irq_desc[M32R_IRQ_SIO1_S].action = 0; irq_desc[M32R_IRQ_SIO1_S].depth = 1; icu_data[M32R_IRQ_SIO1_S].icucr = 0; @@ -350,7 +350,7 @@ void __init init_IRQ(void) /* DMA1 : */ irq_desc[M32R_IRQ_DMA1].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_DMA1].handler = &m32700ut_irq_type; + irq_desc[M32R_IRQ_DMA1].chip = &m32700ut_irq_type; irq_desc[M32R_IRQ_DMA1].action = 0; irq_desc[M32R_IRQ_DMA1].depth = 1; icu_data[M32R_IRQ_DMA1].icucr = 0; @@ -359,7 +359,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SERIAL_M32R_PLDSIO /* INT#1: SIO0 Receive on PLD */ irq_desc[PLD_IRQ_SIO0_RCV].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_SIO0_RCV].handler = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_SIO0_RCV].chip = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_SIO0_RCV].action = 0; irq_desc[PLD_IRQ_SIO0_RCV].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_RCV)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; @@ -367,7 +367,7 @@ void __init init_IRQ(void) /* INT#1: SIO0 Send on PLD */ irq_desc[PLD_IRQ_SIO0_SND].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_SIO0_SND].handler = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_SIO0_SND].chip = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_SIO0_SND].action = 0; irq_desc[PLD_IRQ_SIO0_SND].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_SND)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; @@ -376,7 +376,7 @@ void __init init_IRQ(void) /* INT#1: CFC IREQ on PLD */ irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFIREQ].handler = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_CFIREQ].chip = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_CFIREQ].action = 0; irq_desc[PLD_IRQ_CFIREQ].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CFIREQ)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* 'L' level sense */ @@ -384,7 +384,7 @@ void __init init_IRQ(void) /* INT#1: CFC Insert on PLD */ irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFC_INSERT].handler = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_CFC_INSERT].chip = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_CFC_INSERT].action = 0; irq_desc[PLD_IRQ_CFC_INSERT].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CFC_INSERT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD00; /* 'L' edge sense */ @@ -392,7 +392,7 @@ void __init init_IRQ(void) /* INT#1: CFC Eject on PLD */ irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFC_EJECT].handler = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_CFC_EJECT].chip = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_CFC_EJECT].action = 0; irq_desc[PLD_IRQ_CFC_EJECT].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CFC_EJECT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* 'H' edge sense */ @@ -416,7 +416,7 @@ void __init init_IRQ(void) outw(USBCR_OTGS, USBCR); /* USBCR: non-OTG */ irq_desc[M32700UT_LCD_IRQ_USB_INT1].status = IRQ_DISABLED; - irq_desc[M32700UT_LCD_IRQ_USB_INT1].handler = &m32700ut_lcdpld_irq_type; + irq_desc[M32700UT_LCD_IRQ_USB_INT1].chip = &m32700ut_lcdpld_irq_type; irq_desc[M32700UT_LCD_IRQ_USB_INT1].action = 0; irq_desc[M32700UT_LCD_IRQ_USB_INT1].depth = 1; lcdpld_icu_data[irq2lcdpldirq(M32700UT_LCD_IRQ_USB_INT1)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* "L" level sense */ @@ -434,7 +434,7 @@ void __init init_IRQ(void) * INT3# is used for AR */ irq_desc[M32R_IRQ_INT3].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT3].handler = &m32700ut_irq_type; + irq_desc[M32R_IRQ_INT3].chip = &m32700ut_irq_type; irq_desc[M32R_IRQ_INT3].action = 0; irq_desc[M32R_IRQ_INT3].depth = 1; icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; diff --git a/arch/m32r/kernel/setup_mappi.c b/arch/m32r/kernel/setup_mappi.c index 00f253209cb..c268044185f 100644 --- a/arch/m32r/kernel/setup_mappi.c +++ b/arch/m32r/kernel/setup_mappi.c @@ -86,7 +86,7 @@ void __init init_IRQ(void) #ifdef CONFIG_NE2000 /* INT0 : LAN controller (RTL8019AS) */ irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT0].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_INT0].chip = &mappi_irq_type; irq_desc[M32R_IRQ_INT0].action = 0; irq_desc[M32R_IRQ_INT0].depth = 1; icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; @@ -95,7 +95,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_MFT2].chip = &mappi_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -104,7 +104,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SERIAL_M32R_SIO /* SIO0_R : uart receive data */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO0_R].chip = &mappi_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = 0; @@ -112,7 +112,7 @@ void __init init_IRQ(void) /* SIO0_S : uart send data */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO0_S].chip = &mappi_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = 0; @@ -120,7 +120,7 @@ void __init init_IRQ(void) /* SIO1_R : uart receive data */ irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_R].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO1_R].chip = &mappi_irq_type; irq_desc[M32R_IRQ_SIO1_R].action = 0; irq_desc[M32R_IRQ_SIO1_R].depth = 1; icu_data[M32R_IRQ_SIO1_R].icucr = 0; @@ -128,7 +128,7 @@ void __init init_IRQ(void) /* SIO1_S : uart send data */ irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_S].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO1_S].chip = &mappi_irq_type; irq_desc[M32R_IRQ_SIO1_S].action = 0; irq_desc[M32R_IRQ_SIO1_S].depth = 1; icu_data[M32R_IRQ_SIO1_S].icucr = 0; @@ -138,7 +138,7 @@ void __init init_IRQ(void) #if defined(CONFIG_M32R_PCC) /* INT1 : pccard0 interrupt */ irq_desc[M32R_IRQ_INT1].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT1].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_INT1].chip = &mappi_irq_type; irq_desc[M32R_IRQ_INT1].action = 0; irq_desc[M32R_IRQ_INT1].depth = 1; icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD00; @@ -146,7 +146,7 @@ void __init init_IRQ(void) /* INT2 : pccard1 interrupt */ irq_desc[M32R_IRQ_INT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT2].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_INT2].chip = &mappi_irq_type; irq_desc[M32R_IRQ_INT2].action = 0; irq_desc[M32R_IRQ_INT2].depth = 1; icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD00; diff --git a/arch/m32r/kernel/setup_mappi2.c b/arch/m32r/kernel/setup_mappi2.c index eebc9d8b4e7..bd2327d5cca 100644 --- a/arch/m32r/kernel/setup_mappi2.c +++ b/arch/m32r/kernel/setup_mappi2.c @@ -87,7 +87,7 @@ void __init init_IRQ(void) #if defined(CONFIG_SMC91X) /* INT0 : LAN controller (SMC91111) */ irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT0].handler = &mappi2_irq_type; + irq_desc[M32R_IRQ_INT0].chip = &mappi2_irq_type; irq_desc[M32R_IRQ_INT0].action = 0; irq_desc[M32R_IRQ_INT0].depth = 1; icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; @@ -96,7 +96,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].handler = &mappi2_irq_type; + irq_desc[M32R_IRQ_MFT2].chip = &mappi2_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -105,7 +105,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SERIAL_M32R_SIO /* SIO0_R : uart receive data */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].handler = &mappi2_irq_type; + irq_desc[M32R_IRQ_SIO0_R].chip = &mappi2_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = 0; @@ -113,14 +113,14 @@ void __init init_IRQ(void) /* SIO0_S : uart send data */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].handler = &mappi2_irq_type; + irq_desc[M32R_IRQ_SIO0_S].chip = &mappi2_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = 0; disable_mappi2_irq(M32R_IRQ_SIO0_S); /* SIO1_R : uart receive data */ irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_R].handler = &mappi2_irq_type; + irq_desc[M32R_IRQ_SIO1_R].chip = &mappi2_irq_type; irq_desc[M32R_IRQ_SIO1_R].action = 0; irq_desc[M32R_IRQ_SIO1_R].depth = 1; icu_data[M32R_IRQ_SIO1_R].icucr = 0; @@ -128,7 +128,7 @@ void __init init_IRQ(void) /* SIO1_S : uart send data */ irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_S].handler = &mappi2_irq_type; + irq_desc[M32R_IRQ_SIO1_S].chip = &mappi2_irq_type; irq_desc[M32R_IRQ_SIO1_S].action = 0; irq_desc[M32R_IRQ_SIO1_S].depth = 1; icu_data[M32R_IRQ_SIO1_S].icucr = 0; @@ -138,7 +138,7 @@ void __init init_IRQ(void) #if defined(CONFIG_USB) /* INT1 : USB Host controller interrupt */ irq_desc[M32R_IRQ_INT1].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT1].handler = &mappi2_irq_type; + irq_desc[M32R_IRQ_INT1].chip = &mappi2_irq_type; irq_desc[M32R_IRQ_INT1].action = 0; irq_desc[M32R_IRQ_INT1].depth = 1; icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_ISMOD01; @@ -147,7 +147,7 @@ void __init init_IRQ(void) /* ICUCR40: CFC IREQ */ irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFIREQ].handler = &mappi2_irq_type; + irq_desc[PLD_IRQ_CFIREQ].chip = &mappi2_irq_type; irq_desc[PLD_IRQ_CFIREQ].action = 0; irq_desc[PLD_IRQ_CFIREQ].depth = 1; /* disable nested irq */ icu_data[PLD_IRQ_CFIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01; @@ -156,7 +156,7 @@ void __init init_IRQ(void) #if defined(CONFIG_M32R_CFC) /* ICUCR41: CFC Insert */ irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFC_INSERT].handler = &mappi2_irq_type; + irq_desc[PLD_IRQ_CFC_INSERT].chip = &mappi2_irq_type; irq_desc[PLD_IRQ_CFC_INSERT].action = 0; irq_desc[PLD_IRQ_CFC_INSERT].depth = 1; /* disable nested irq */ icu_data[PLD_IRQ_CFC_INSERT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00; @@ -164,7 +164,7 @@ void __init init_IRQ(void) /* ICUCR42: CFC Eject */ irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFC_EJECT].handler = &mappi2_irq_type; + irq_desc[PLD_IRQ_CFC_EJECT].chip = &mappi2_irq_type; irq_desc[PLD_IRQ_CFC_EJECT].action = 0; irq_desc[PLD_IRQ_CFC_EJECT].depth = 1; /* disable nested irq */ icu_data[PLD_IRQ_CFC_EJECT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; diff --git a/arch/m32r/kernel/setup_mappi3.c b/arch/m32r/kernel/setup_mappi3.c index d2ff021e2d3..014b51d1750 100644 --- a/arch/m32r/kernel/setup_mappi3.c +++ b/arch/m32r/kernel/setup_mappi3.c @@ -87,7 +87,7 @@ void __init init_IRQ(void) #if defined(CONFIG_SMC91X) /* INT0 : LAN controller (SMC91111) */ irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT0].handler = &mappi3_irq_type; + irq_desc[M32R_IRQ_INT0].chip = &mappi3_irq_type; irq_desc[M32R_IRQ_INT0].action = 0; irq_desc[M32R_IRQ_INT0].depth = 1; icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; @@ -96,7 +96,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].handler = &mappi3_irq_type; + irq_desc[M32R_IRQ_MFT2].chip = &mappi3_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -105,7 +105,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SERIAL_M32R_SIO /* SIO0_R : uart receive data */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].handler = &mappi3_irq_type; + irq_desc[M32R_IRQ_SIO0_R].chip = &mappi3_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = 0; @@ -113,14 +113,14 @@ void __init init_IRQ(void) /* SIO0_S : uart send data */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].handler = &mappi3_irq_type; + irq_desc[M32R_IRQ_SIO0_S].chip = &mappi3_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = 0; disable_mappi3_irq(M32R_IRQ_SIO0_S); /* SIO1_R : uart receive data */ irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_R].handler = &mappi3_irq_type; + irq_desc[M32R_IRQ_SIO1_R].chip = &mappi3_irq_type; irq_desc[M32R_IRQ_SIO1_R].action = 0; irq_desc[M32R_IRQ_SIO1_R].depth = 1; icu_data[M32R_IRQ_SIO1_R].icucr = 0; @@ -128,7 +128,7 @@ void __init init_IRQ(void) /* SIO1_S : uart send data */ irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_S].handler = &mappi3_irq_type; + irq_desc[M32R_IRQ_SIO1_S].chip = &mappi3_irq_type; irq_desc[M32R_IRQ_SIO1_S].action = 0; irq_desc[M32R_IRQ_SIO1_S].depth = 1; icu_data[M32R_IRQ_SIO1_S].icucr = 0; @@ -138,7 +138,7 @@ void __init init_IRQ(void) #if defined(CONFIG_USB) /* INT1 : USB Host controller interrupt */ irq_desc[M32R_IRQ_INT1].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT1].handler = &mappi3_irq_type; + irq_desc[M32R_IRQ_INT1].chip = &mappi3_irq_type; irq_desc[M32R_IRQ_INT1].action = 0; irq_desc[M32R_IRQ_INT1].depth = 1; icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_ISMOD01; @@ -147,7 +147,7 @@ void __init init_IRQ(void) /* CFC IREQ */ irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFIREQ].handler = &mappi3_irq_type; + irq_desc[PLD_IRQ_CFIREQ].chip = &mappi3_irq_type; irq_desc[PLD_IRQ_CFIREQ].action = 0; irq_desc[PLD_IRQ_CFIREQ].depth = 1; /* disable nested irq */ icu_data[PLD_IRQ_CFIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01; @@ -156,7 +156,7 @@ void __init init_IRQ(void) #if defined(CONFIG_M32R_CFC) /* ICUCR41: CFC Insert & eject */ irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFC_INSERT].handler = &mappi3_irq_type; + irq_desc[PLD_IRQ_CFC_INSERT].chip = &mappi3_irq_type; irq_desc[PLD_IRQ_CFC_INSERT].action = 0; irq_desc[PLD_IRQ_CFC_INSERT].depth = 1; /* disable nested irq */ icu_data[PLD_IRQ_CFC_INSERT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00; @@ -166,7 +166,7 @@ void __init init_IRQ(void) /* IDE IREQ */ irq_desc[PLD_IRQ_IDEIREQ].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_IDEIREQ].handler = &mappi3_irq_type; + irq_desc[PLD_IRQ_IDEIREQ].chip = &mappi3_irq_type; irq_desc[PLD_IRQ_IDEIREQ].action = 0; irq_desc[PLD_IRQ_IDEIREQ].depth = 1; /* disable nested irq */ icu_data[PLD_IRQ_IDEIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; diff --git a/arch/m32r/kernel/setup_oaks32r.c b/arch/m32r/kernel/setup_oaks32r.c index 0e9e63538c0..ea64831aef7 100644 --- a/arch/m32r/kernel/setup_oaks32r.c +++ b/arch/m32r/kernel/setup_oaks32r.c @@ -85,7 +85,7 @@ void __init init_IRQ(void) #ifdef CONFIG_NE2000 /* INT3 : LAN controller (RTL8019AS) */ irq_desc[M32R_IRQ_INT3].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT3].handler = &oaks32r_irq_type; + irq_desc[M32R_IRQ_INT3].chip = &oaks32r_irq_type; irq_desc[M32R_IRQ_INT3].action = 0; irq_desc[M32R_IRQ_INT3].depth = 1; icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; @@ -94,7 +94,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].handler = &oaks32r_irq_type; + irq_desc[M32R_IRQ_MFT2].chip = &oaks32r_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -103,7 +103,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SERIAL_M32R_SIO /* SIO0_R : uart receive data */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].handler = &oaks32r_irq_type; + irq_desc[M32R_IRQ_SIO0_R].chip = &oaks32r_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = 0; @@ -111,7 +111,7 @@ void __init init_IRQ(void) /* SIO0_S : uart send data */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].handler = &oaks32r_irq_type; + irq_desc[M32R_IRQ_SIO0_S].chip = &oaks32r_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = 0; @@ -119,7 +119,7 @@ void __init init_IRQ(void) /* SIO1_R : uart receive data */ irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_R].handler = &oaks32r_irq_type; + irq_desc[M32R_IRQ_SIO1_R].chip = &oaks32r_irq_type; irq_desc[M32R_IRQ_SIO1_R].action = 0; irq_desc[M32R_IRQ_SIO1_R].depth = 1; icu_data[M32R_IRQ_SIO1_R].icucr = 0; @@ -127,7 +127,7 @@ void __init init_IRQ(void) /* SIO1_S : uart send data */ irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_S].handler = &oaks32r_irq_type; + irq_desc[M32R_IRQ_SIO1_S].chip = &oaks32r_irq_type; irq_desc[M32R_IRQ_SIO1_S].action = 0; irq_desc[M32R_IRQ_SIO1_S].depth = 1; icu_data[M32R_IRQ_SIO1_S].icucr = 0; diff --git a/arch/m32r/kernel/setup_opsput.c b/arch/m32r/kernel/setup_opsput.c index 548e8fc7949..55e8972d455 100644 --- a/arch/m32r/kernel/setup_opsput.c +++ b/arch/m32r/kernel/setup_opsput.c @@ -302,7 +302,7 @@ void __init init_IRQ(void) #if defined(CONFIG_SMC91X) /* INT#0: LAN controller on OPSPUT-LAN (SMC91C111)*/ irq_desc[OPSPUT_LAN_IRQ_LAN].status = IRQ_DISABLED; - irq_desc[OPSPUT_LAN_IRQ_LAN].handler = &opsput_lanpld_irq_type; + irq_desc[OPSPUT_LAN_IRQ_LAN].chip = &opsput_lanpld_irq_type; irq_desc[OPSPUT_LAN_IRQ_LAN].action = 0; irq_desc[OPSPUT_LAN_IRQ_LAN].depth = 1; /* disable nested irq */ lanpld_icu_data[irq2lanpldirq(OPSPUT_LAN_IRQ_LAN)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* "H" edge sense */ @@ -311,7 +311,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].handler = &opsput_irq_type; + irq_desc[M32R_IRQ_MFT2].chip = &opsput_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -319,7 +319,7 @@ void __init init_IRQ(void) /* SIO0 : receive */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].handler = &opsput_irq_type; + irq_desc[M32R_IRQ_SIO0_R].chip = &opsput_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = 0; @@ -327,7 +327,7 @@ void __init init_IRQ(void) /* SIO0 : send */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].handler = &opsput_irq_type; + irq_desc[M32R_IRQ_SIO0_S].chip = &opsput_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = 0; @@ -335,7 +335,7 @@ void __init init_IRQ(void) /* SIO1 : receive */ irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_R].handler = &opsput_irq_type; + irq_desc[M32R_IRQ_SIO1_R].chip = &opsput_irq_type; irq_desc[M32R_IRQ_SIO1_R].action = 0; irq_desc[M32R_IRQ_SIO1_R].depth = 1; icu_data[M32R_IRQ_SIO1_R].icucr = 0; @@ -343,7 +343,7 @@ void __init init_IRQ(void) /* SIO1 : send */ irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_S].handler = &opsput_irq_type; + irq_desc[M32R_IRQ_SIO1_S].chip = &opsput_irq_type; irq_desc[M32R_IRQ_SIO1_S].action = 0; irq_desc[M32R_IRQ_SIO1_S].depth = 1; icu_data[M32R_IRQ_SIO1_S].icucr = 0; @@ -351,7 +351,7 @@ void __init init_IRQ(void) /* DMA1 : */ irq_desc[M32R_IRQ_DMA1].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_DMA1].handler = &opsput_irq_type; + irq_desc[M32R_IRQ_DMA1].chip = &opsput_irq_type; irq_desc[M32R_IRQ_DMA1].action = 0; irq_desc[M32R_IRQ_DMA1].depth = 1; icu_data[M32R_IRQ_DMA1].icucr = 0; @@ -360,7 +360,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SERIAL_M32R_PLDSIO /* INT#1: SIO0 Receive on PLD */ irq_desc[PLD_IRQ_SIO0_RCV].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_SIO0_RCV].handler = &opsput_pld_irq_type; + irq_desc[PLD_IRQ_SIO0_RCV].chip = &opsput_pld_irq_type; irq_desc[PLD_IRQ_SIO0_RCV].action = 0; irq_desc[PLD_IRQ_SIO0_RCV].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_RCV)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; @@ -368,7 +368,7 @@ void __init init_IRQ(void) /* INT#1: SIO0 Send on PLD */ irq_desc[PLD_IRQ_SIO0_SND].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_SIO0_SND].handler = &opsput_pld_irq_type; + irq_desc[PLD_IRQ_SIO0_SND].chip = &opsput_pld_irq_type; irq_desc[PLD_IRQ_SIO0_SND].action = 0; irq_desc[PLD_IRQ_SIO0_SND].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_SND)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; @@ -378,7 +378,7 @@ void __init init_IRQ(void) #if defined(CONFIG_M32R_CFC) /* INT#1: CFC IREQ on PLD */ irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFIREQ].handler = &opsput_pld_irq_type; + irq_desc[PLD_IRQ_CFIREQ].chip = &opsput_pld_irq_type; irq_desc[PLD_IRQ_CFIREQ].action = 0; irq_desc[PLD_IRQ_CFIREQ].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CFIREQ)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* 'L' level sense */ @@ -386,7 +386,7 @@ void __init init_IRQ(void) /* INT#1: CFC Insert on PLD */ irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFC_INSERT].handler = &opsput_pld_irq_type; + irq_desc[PLD_IRQ_CFC_INSERT].chip = &opsput_pld_irq_type; irq_desc[PLD_IRQ_CFC_INSERT].action = 0; irq_desc[PLD_IRQ_CFC_INSERT].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CFC_INSERT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD00; /* 'L' edge sense */ @@ -394,7 +394,7 @@ void __init init_IRQ(void) /* INT#1: CFC Eject on PLD */ irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFC_EJECT].handler = &opsput_pld_irq_type; + irq_desc[PLD_IRQ_CFC_EJECT].chip = &opsput_pld_irq_type; irq_desc[PLD_IRQ_CFC_EJECT].action = 0; irq_desc[PLD_IRQ_CFC_EJECT].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CFC_EJECT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* 'H' edge sense */ @@ -420,7 +420,7 @@ void __init init_IRQ(void) outw(USBCR_OTGS, USBCR); /* USBCR: non-OTG */ irq_desc[OPSPUT_LCD_IRQ_USB_INT1].status = IRQ_DISABLED; - irq_desc[OPSPUT_LCD_IRQ_USB_INT1].handler = &opsput_lcdpld_irq_type; + irq_desc[OPSPUT_LCD_IRQ_USB_INT1].chip = &opsput_lcdpld_irq_type; irq_desc[OPSPUT_LCD_IRQ_USB_INT1].action = 0; irq_desc[OPSPUT_LCD_IRQ_USB_INT1].depth = 1; lcdpld_icu_data[irq2lcdpldirq(OPSPUT_LCD_IRQ_USB_INT1)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* "L" level sense */ @@ -438,7 +438,7 @@ void __init init_IRQ(void) * INT3# is used for AR */ irq_desc[M32R_IRQ_INT3].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT3].handler = &opsput_irq_type; + irq_desc[M32R_IRQ_INT3].chip = &opsput_irq_type; irq_desc[M32R_IRQ_INT3].action = 0; irq_desc[M32R_IRQ_INT3].depth = 1; icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; diff --git a/arch/m32r/kernel/setup_usrv.c b/arch/m32r/kernel/setup_usrv.c index 64be659a23e..7fa12d8f66b 100644 --- a/arch/m32r/kernel/setup_usrv.c +++ b/arch/m32r/kernel/setup_usrv.c @@ -158,7 +158,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_MFT2].chip = &mappi_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -167,7 +167,7 @@ void __init init_IRQ(void) #if defined(CONFIG_SERIAL_M32R_SIO) /* SIO0_R : uart receive data */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO0_R].chip = &mappi_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = 0; @@ -175,7 +175,7 @@ void __init init_IRQ(void) /* SIO0_S : uart send data */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO0_S].chip = &mappi_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = 0; @@ -183,7 +183,7 @@ void __init init_IRQ(void) /* SIO1_R : uart receive data */ irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_R].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO1_R].chip = &mappi_irq_type; irq_desc[M32R_IRQ_SIO1_R].action = 0; irq_desc[M32R_IRQ_SIO1_R].depth = 1; icu_data[M32R_IRQ_SIO1_R].icucr = 0; @@ -191,7 +191,7 @@ void __init init_IRQ(void) /* SIO1_S : uart send data */ irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_S].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO1_S].chip = &mappi_irq_type; irq_desc[M32R_IRQ_SIO1_S].action = 0; irq_desc[M32R_IRQ_SIO1_S].depth = 1; icu_data[M32R_IRQ_SIO1_S].icucr = 0; @@ -201,7 +201,7 @@ void __init init_IRQ(void) /* INT#67-#71: CFC#0 IREQ on PLD */ for (i = 0 ; i < CONFIG_CFC_NUM ; i++ ) { irq_desc[PLD_IRQ_CF0 + i].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CF0 + i].handler = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_CF0 + i].chip = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_CF0 + i].action = 0; irq_desc[PLD_IRQ_CF0 + i].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CF0 + i)].icucr @@ -212,7 +212,7 @@ void __init init_IRQ(void) #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) /* INT#76: 16552D#0 IREQ on PLD */ irq_desc[PLD_IRQ_UART0].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_UART0].handler = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_UART0].chip = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_UART0].action = 0; irq_desc[PLD_IRQ_UART0].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_UART0)].icucr @@ -221,7 +221,7 @@ void __init init_IRQ(void) /* INT#77: 16552D#1 IREQ on PLD */ irq_desc[PLD_IRQ_UART1].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_UART1].handler = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_UART1].chip = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_UART1].action = 0; irq_desc[PLD_IRQ_UART1].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_UART1)].icucr @@ -232,7 +232,7 @@ void __init init_IRQ(void) #if defined(CONFIG_IDC_AK4524) || defined(CONFIG_IDC_AK4524_MODULE) /* INT#80: AK4524 IREQ on PLD */ irq_desc[PLD_IRQ_SNDINT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_SNDINT].handler = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_SNDINT].chip = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_SNDINT].action = 0; irq_desc[PLD_IRQ_SNDINT].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_SNDINT)].icucr diff --git a/arch/m68k/mm/memory.c b/arch/m68k/mm/memory.c index d6d582a5abb..a226668f20c 100644 --- a/arch/m68k/mm/memory.c +++ b/arch/m68k/mm/memory.c @@ -94,8 +94,7 @@ pmd_t *get_pointer_table (void) PD_MARKBITS(dp) = mask & ~tmp; if (!PD_MARKBITS(dp)) { /* move to end of list */ - list_del(dp); - list_add_tail(dp, &ptable_list); + list_move_tail(dp, &ptable_list); } return (pmd_t *) (page_address(PD_PAGE(dp)) + off); } @@ -123,8 +122,7 @@ int free_pointer_table (pmd_t *ptable) * move this descriptor to the front of the list, since * it has one or more free tables. */ - list_del(dp); - list_add(dp, &ptable_list); + list_move(dp, &ptable_list); } return 0; } diff --git a/arch/m68k/sun3/sun3dvma.c b/arch/m68k/sun3/sun3dvma.c index f04a1d25f1a..97c7bfde8ae 100644 --- a/arch/m68k/sun3/sun3dvma.c +++ b/arch/m68k/sun3/sun3dvma.c @@ -119,8 +119,7 @@ static inline int refill(void) if(hole->end == prev->start) { hole->size += prev->size; hole->end = prev->end; - list_del(&(prev->list)); - list_add(&(prev->list), &hole_cache); + list_move(&(prev->list), &hole_cache); ret++; } @@ -182,8 +181,7 @@ static inline unsigned long get_baddr(int len, unsigned long align) #endif return hole->end; } else if(hole->size == newlen) { - list_del(&(hole->list)); - list_add(&(hole->list), &hole_cache); + list_move(&(hole->list), &hole_cache); dvma_entry_use(hole->start) = newlen; #ifdef DVMA_DEBUG dvma_allocs++; diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig index 3cde6822ead..e767f2ddae7 100644 --- a/arch/m68knommu/Kconfig +++ b/arch/m68knommu/Kconfig @@ -5,7 +5,7 @@ mainmenu "uClinux/68k (w/o MMU) Kernel Configuration" -config M68KNOMMU +config M68K bool default y @@ -119,6 +119,11 @@ config M5307 help Motorola ColdFire 5307 processor support. +config M532x + bool "MCF532x" + help + Freescale (Motorola) ColdFire 532x processor support. + config M5407 bool "MCF5407" help @@ -133,125 +138,43 @@ config M527x config COLDFIRE bool - depends on (M5206 || M5206e || M520x || M523x || M5249 || M527x || M5272 || M528x || M5307 || M5407) + depends on (M5206 || M5206e || M520x || M523x || M5249 || M527x || M5272 || M528x || M5307 || M532x || M5407) default y -choice - prompt "CPU CLOCK Frequency" - default AUTO - -config CLOCK_AUTO - bool "AUTO" - ---help--- - Define the CPU clock frequency in use. On many boards you don't - really need to know, so you can select the AUTO option. On some - boards you need to know the real clock frequency to determine other - system timing (for example baud rate dividors, etc). Some processors - have an internal PLL and you can select a frequency to run at. - You need to know a little about the internals of your processor to - set this. If in doubt choose the AUTO option. - -config CLOCK_11MHz - bool "11MHz" - help - Select a 11MHz CPU clock frequency. - -config CLOCK_16MHz - bool "16MHz" - help - Select a 16MHz CPU clock frequency. - -config CLOCK_20MHz - bool "20MHz" - help - Select a 20MHz CPU clock frequency. - -config CLOCK_24MHz - bool "24MHz" - help - Select a 24MHz CPU clock frequency. - -config CLOCK_25MHz - bool "25MHz" - help - Select a 25MHz CPU clock frequency. - -config CLOCK_33MHz - bool "33MHz" - help - Select a 33MHz CPU clock frequency. - -config CLOCK_40MHz - bool "40MHz" - help - Select a 40MHz CPU clock frequency. - -config CLOCK_45MHz - bool "45MHz" - help - Select a 45MHz CPU clock frequency. - -config CLOCK_48MHz - bool "48MHz" - help - Select a 48MHz CPU clock frequency. - -config CLOCK_50MHz - bool "50MHz" - help - Select a 50MHz CPU clock frequency. - -config CLOCK_54MHz - bool "54MHz" - help - Select a 54MHz CPU clock frequency. - -config CLOCK_60MHz - bool "60MHz" - help - Select a 60MHz CPU clock frequency. - -config CLOCK_62_5MHz - bool "62.5MHz" - help - Select a 62.5MHz CPU clock frequency. - -config CLOCK_64MHz - bool "64MHz" - help - Select a 64MHz CPU clock frequency. - -config CLOCK_66MHz - bool "66MHz" - help - Select a 66MHz CPU clock frequency. - -config CLOCK_70MHz - bool "70MHz" - help - Select a 70MHz CPU clock frequency. - -config CLOCK_100MHz - bool "100MHz" - help - Select a 100MHz CPU clock frequency. - -config CLOCK_140MHz - bool "140MHz" - help - Select a 140MHz CPU clock frequency. - -config CLOCK_150MHz - bool "150MHz" - help - Select a 150MHz CPU clock frequency. - -config CLOCK_166MHz - bool "166MHz" +config CLOCK_SET + bool "Enable setting the CPU clock frequency" + default n help - Select a 166MHz CPU clock frequency. - -endchoice + On some CPU's you do not need to know what the core CPU clock + frequency is. On these you can disable clock setting. On some + traditional 68K parts, and on all ColdFire parts you need to set + the appropriate CPU clock frequency. On these devices many of the + onboard peripherals derive their timing from the master CPU clock + frequency. + +config CLOCK_FREQ + int "Set the core clock frequency" + default "66666666" + depends on CLOCK_SET + help + Define the CPU clock frequency in use. This is the core clock + frequency, it may or may not be the same as the external clock + crystal fitted to your board. Some processors have an internal + PLL and can have their frequency programmed at run time, others + use internal dividers. In gernal the kernel won't setup a PLL + if it is fitted (there are some expections). This value will be + specific to the exact CPU that you are using. + +config CLOCK_DIV + int "Set the core/bus clock divide ratio" + default "1" + depends on CLOCK_SET + help + On many SoC style CPUs the master CPU clock is also used to drive + on-chip peripherals. The clock that is distributed to these + peripherals is sometimes a fixed ratio of the master clock + frequency. If so then set this to the divider ration of the + master clock to the peripheral clock. If not sure then select 1. config OLDMASK bool "Old mask 5307 (1H55J) silicon" @@ -377,6 +300,12 @@ config COBRA5272 help Support for the senTec COBRA5272 board. +config AVNET5282 + bool "Avnet 5282 board support" + depends on M528x + help + Support for the Avnet 5282 board. + config M5282EVB bool "Motorola M5282EVB board support" depends on M528x @@ -419,6 +348,18 @@ config SECUREEDGEMP3 help Support for the SnapGear SecureEdge/MP3 platform. +config M5329EVB + bool "Freescale (Motorola) M5329EVB board support" + depends on M532x + help + Support for the Freescale (Motorola) M5329EVB board. + +config COBRA5329 + bool "senTec COBRA5329 board support" + depends on M532x + help + Support for the senTec COBRA5329 board. + config M5407C3 bool "Motorola M5407C3 board support" depends on M5407 @@ -487,7 +428,7 @@ config ARNEWSH config FREESCALE bool default y - depends on (M5206eC3 || M5208EVB || M5235EVB || M5249C3 || M5271EVB || M5272C3 || M5275EVB || M5282EVB || M5307C3 || M5407C3) + depends on (M5206eC3 || M5208EVB || M5235EVB || M5249C3 || M5271EVB || M5272C3 || M5275EVB || M5282EVB || M5307C3 || M5329EVB || M5407C3) config HW_FEITH bool @@ -508,6 +449,11 @@ config SNEHA bool default y depends on CPU16B + +config AVNET + bool + default y + depends on (AVNET5282) config LARGE_ALLOCS bool "Allow allocating large blocks (> 1MB) of memory" @@ -526,38 +472,46 @@ config 4KSTACKS running more threads on a system and also reduces the pressure on the VM subsystem for higher order allocations. -choice - prompt "RAM size" - default AUTO - -config RAMAUTO - bool "AUTO" - ---help--- - Configure the RAM size on your platform. Many platforms can auto - detect this, on those choose the AUTO option. Otherwise set the - RAM size you intend using. +comment "RAM configuration" -config RAM4MB - bool "4MiB" +config RAMBASE + hex "Address of the base of RAM" + default "0" help - Set RAM size to be 4MiB. + Define the address that RAM starts at. On many platforms this is + 0, the base of the address space. And this is the default. Some + platforms choose to setup their RAM at other addresses within the + processor address space. -config RAM8MB - bool "8MiB" +config RAMSIZE + hex "Size of RAM (in bytes)" + default "0x400000" help - Set RAM size to be 8MiB. + Define the size of the system RAM. If you select 0 then the + kernel will try to probe the RAM size at runtime. This is not + supported on all CPU types. -config RAM16MB - bool "16MiB" +config VECTORBASE + hex "Address of the base of system vectors" + default "0" help - Set RAM size to be 16MiB. + Define the address of the the system vectors. Commonly this is + put at the start of RAM, but it doesn't have to be. On ColdFire + platforms this address is programmed into the VBR register, thus + actually setting the address to use. -config RAM32MB - bool "32MiB" +config KERNELBASE + hex "Address of the base of kernel code" + default "0x400" help - Set RAM size to be 32MiB. - -endchoice + Typically on m68k systems the kernel will not start at the base + of RAM, but usually some small offset from it. Define the start + address of the kernel here. The most common setup will have the + processor vectors at the base of RAM and then the start of the + kernel. On some platforms some RAM is reserved for boot loaders + and the kernel starts after that. The 0x400 default was based on + a system with the RAM based at address 0, and leaving enough room + for the theoretical maximum number of 256 vectors. choice prompt "RAM bus width" @@ -565,7 +519,7 @@ choice config RAMAUTOBIT bool "AUTO" - ---help--- + help Select the physical RAM data bus size. Not needed on most platforms, so you can generally choose AUTO. @@ -586,6 +540,59 @@ config RAM32BIT endchoice +comment "ROM configuration" + +config ROM + bool "Specify ROM linker regions" + default n + help + Define a ROM region for the linker script. This creates a kernel + that can be stored in flash, with possibly the text, and data + regions being copied out to RAM at startup. + +config ROMBASE + hex "Address of the base of ROM device" + default "0" + depends on ROM + help + Define the address that the ROM region starts at. Some platforms + use this to set their chip select region accordingly for the boot + device. + +config ROMVEC + hex "Address of the base of the ROM vectors" + default "0" + depends on ROM + help + This is almost always the same as the base of the ROM. Since on all + 68000 type varients the vectors are at the base of the boot device + on system startup. + +config ROMVECSIZE + hex "Size of ROM vector region (in bytes)" + default "0x400" + depends on ROM + help + Define the size of the vector region in ROM. For most 68000 + varients this would be 0x400 bytes in size. Set to 0 if you do + not want a vector region at the start of the ROM. + +config ROMSTART + hex "Address of the base of system image in ROM" + default "0x400" + depends on ROM + help + Define the start address of the system image in ROM. Commonly this + is strait after the ROM vectors. + +config ROMSIZE + hex "Size of the ROM device" + default "0x100000" + depends on ROM + help + Size of the ROM device. On some platforms this is used to setup + the chip select that controls the boot ROM device. + choice prompt "Kernel executes from" ---help--- @@ -599,7 +606,9 @@ config RAMKERNEL config ROMKERNEL bool "ROM" help - The kernel will be resident in FLASH/ROM when running. + The kernel will be resident in FLASH/ROM when running. This is + often referred to as Execute-in-Place (XIP), since the kernel + code executes from the position it is stored in the FLASH/ROM. endchoice diff --git a/arch/m68knommu/Makefile b/arch/m68knommu/Makefile index 6f880cbff1c..8951793fd8d 100644 --- a/arch/m68knommu/Makefile +++ b/arch/m68knommu/Makefile @@ -21,6 +21,7 @@ platform-$(CONFIG_M527x) := 527x platform-$(CONFIG_M5272) := 5272 platform-$(CONFIG_M528x) := 528x platform-$(CONFIG_M5307) := 5307 +platform-$(CONFIG_M532x) := 532x platform-$(CONFIG_M5407) := 5407 PLATFORM := $(platform-y) @@ -44,6 +45,7 @@ board-$(CONFIG_senTec) := senTec board-$(CONFIG_SNEHA) := SNEHA board-$(CONFIG_M5208EVB) := M5208EVB board-$(CONFIG_MOD5272) := MOD5272 +board-$(CONFIG_AVNET) := AVNET BOARD := $(board-y) model-$(CONFIG_RAMKERNEL) := ram @@ -65,6 +67,7 @@ cpuclass-$(CONFIG_M527x) := 5307 cpuclass-$(CONFIG_M5272) := 5307 cpuclass-$(CONFIG_M528x) := 5307 cpuclass-$(CONFIG_M5307) := 5307 +cpuclass-$(CONFIG_M532x) := 5307 cpuclass-$(CONFIG_M5407) := 5307 cpuclass-$(CONFIG_M68328) := 68328 cpuclass-$(CONFIG_M68EZ328) := 68328 @@ -81,16 +84,17 @@ export PLATFORM BOARD MODEL CPUCLASS # # Some CFLAG additions based on specific CPU type. # -cflags-$(CONFIG_M5206) := -m5200 -Wa,-S -Wa,-m5200 -cflags-$(CONFIG_M5206e) := -m5200 -Wa,-S -Wa,-m5200 -cflags-$(CONFIG_M520x) := -m5307 -Wa,-S -Wa,-m5307 -cflags-$(CONFIG_M523x) := -m5307 -Wa,-S -Wa,-m5307 -cflags-$(CONFIG_M5249) := -m5200 -Wa,-S -Wa,-m5200 -cflags-$(CONFIG_M527x) := -m5307 -Wa,-S -Wa,-m5307 -cflags-$(CONFIG_M5272) := -m5307 -Wa,-S -Wa,-m5307 -cflags-$(CONFIG_M528x) := -m5307 -Wa,-S -Wa,-m5307 -cflags-$(CONFIG_M5307) := -m5307 -Wa,-S -Wa,-m5307 -cflags-$(CONFIG_M5407) := -m5200 -Wa,-S -Wa,-m5200 +cflags-$(CONFIG_M5206) := -m5200 +cflags-$(CONFIG_M5206e) := -m5200 +cflags-$(CONFIG_M520x) := -m5307 +cflags-$(CONFIG_M523x) := -m5307 +cflags-$(CONFIG_M5249) := -m5200 +cflags-$(CONFIG_M527x) := -m5307 +cflags-$(CONFIG_M5272) := -m5307 +cflags-$(CONFIG_M528x) := -m5307 +cflags-$(CONFIG_M5307) := -m5307 +cflags-$(CONFIG_M532x) := -m5307 +cflags-$(CONFIG_M5407) := -m5200 cflags-$(CONFIG_M68328) := -m68000 cflags-$(CONFIG_M68EZ328) := -m68000 cflags-$(CONFIG_M68VZ328) := -m68000 diff --git a/arch/m68knommu/defconfig b/arch/m68knommu/defconfig index 2d59ba1a79b..3891de09ac2 100644 --- a/arch/m68knommu/defconfig +++ b/arch/m68knommu/defconfig @@ -1,21 +1,22 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.13-uc0 -# Wed Aug 31 15:03:26 2005 +# Linux kernel version: 2.6.17 +# Tue Jun 27 12:57:06 2006 # -CONFIG_M68KNOMMU=y +CONFIG_M68K=y # CONFIG_MMU is not set # CONFIG_FPU is not set -CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_TIME_LOW_RES=y # # Code maturity level options # CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 @@ -23,26 +24,30 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 # General setup # CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +# CONFIG_SYSVIPC is not set # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_SYSCTL is not set # CONFIG_AUDIT is not set -# CONFIG_HOTPLUG is not set -# CONFIG_KOBJECT_UEVENT is not set # CONFIG_IKCONFIG is not set +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_UID16=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_EMBEDDED=y # CONFIG_KALLSYMS is not set +# CONFIG_HOTPLUG is not set CONFIG_PRINTK=y CONFIG_BUG=y +CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set # CONFIG_EPOLL is not set -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 +CONFIG_SLAB=y +CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set # # Loadable module support @@ -50,6 +55,24 @@ CONFIG_BASE_SMALL=0 # CONFIG_MODULES is not set # +# Block layer +# +# CONFIG_BLK_DEV_IO_TRACE is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" + +# # Processor type and features # # CONFIG_M68328 is not set @@ -58,6 +81,7 @@ CONFIG_BASE_SMALL=0 # CONFIG_M68360 is not set # CONFIG_M5206 is not set # CONFIG_M5206e is not set +# CONFIG_M520x is not set # CONFIG_M523x is not set # CONFIG_M5249 is not set # CONFIG_M5271 is not set @@ -65,29 +89,12 @@ CONFIG_M5272=y # CONFIG_M5275 is not set # CONFIG_M528x is not set # CONFIG_M5307 is not set +# CONFIG_M532x is not set # CONFIG_M5407 is not set CONFIG_COLDFIRE=y -# CONFIG_CLOCK_AUTO is not set -# CONFIG_CLOCK_11MHz is not set -# CONFIG_CLOCK_16MHz is not set -# CONFIG_CLOCK_20MHz is not set -# CONFIG_CLOCK_24MHz is not set -# CONFIG_CLOCK_25MHz is not set -# CONFIG_CLOCK_33MHz is not set -# CONFIG_CLOCK_40MHz is not set -# CONFIG_CLOCK_45MHz is not set -# CONFIG_CLOCK_48MHz is not set -# CONFIG_CLOCK_50MHz is not set -# CONFIG_CLOCK_54MHz is not set -# CONFIG_CLOCK_60MHz is not set -# CONFIG_CLOCK_62_5MHz is not set -# CONFIG_CLOCK_64MHz is not set -CONFIG_CLOCK_66MHz=y -# CONFIG_CLOCK_70MHz is not set -# CONFIG_CLOCK_100MHz is not set -# CONFIG_CLOCK_140MHz is not set -# CONFIG_CLOCK_150MHz is not set -# CONFIG_CLOCK_166MHz is not set +CONFIG_CLOCK_SET=y +CONFIG_CLOCK_FREQ=66666666 +CONFIG_CLOCK_DIV=1 # # Platform @@ -102,11 +109,14 @@ CONFIG_M5272C3=y CONFIG_FREESCALE=y # CONFIG_LARGE_ALLOCS is not set CONFIG_4KSTACKS=y -CONFIG_RAMAUTO=y -# CONFIG_RAM4MB is not set -# CONFIG_RAM8MB is not set -# CONFIG_RAM16MB is not set -# CONFIG_RAM32MB is not set + +# +# RAM configuration +# +CONFIG_RAMBASE=0x0 +CONFIG_RAMSIZE=0x800000 +CONFIG_VECTORBASE=0x0 +CONFIG_KERNELBASE=0x20000 CONFIG_RAMAUTOBIT=y # CONFIG_RAM8BIT is not set # CONFIG_RAM16BIT is not set @@ -119,6 +129,8 @@ CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) @@ -140,6 +152,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_BINFMT_FLAT=y # CONFIG_BINFMT_ZFLAT is not set # CONFIG_BINFMT_SHARED_FLAT is not set +# CONFIG_BINFMT_AOUT is not set # CONFIG_BINFMT_MISC is not set # @@ -155,6 +168,7 @@ CONFIG_NET=y # # Networking options # +# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -171,18 +185,30 @@ CONFIG_IP_FIB_HASH=y # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set -# CONFIG_IP_TCPDIAG is not set -# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_INET_DIAG is not set # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set # CONFIG_NETFILTER is not set # +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# # SCTP Configuration (EXPERIMENTAL) # # CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set @@ -195,8 +221,11 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# # CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set # # Network testing @@ -205,6 +234,7 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_IEEE80211 is not set # # Device Drivers @@ -218,6 +248,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# # Memory Technology Devices (MTD) # CONFIG_MTD=y @@ -235,6 +270,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set # CONFIG_NFTL is not set # CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set # # RAM/ROM/Flash chip drivers @@ -254,13 +290,13 @@ CONFIG_MTD_CFI_I2=y CONFIG_MTD_RAM=y # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set # # Mapping drivers for chip access # # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_UCLINUX=y -# CONFIG_MTD_SNAPGEARuC is not set # CONFIG_MTD_PLATRAM is not set # @@ -269,7 +305,6 @@ CONFIG_MTD_UCLINUX=y # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set # CONFIG_MTD_BLOCK2MTD is not set # @@ -285,6 +320,11 @@ CONFIG_MTD_UCLINUX=y # CONFIG_MTD_NAND is not set # +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# # Parallel port support # # CONFIG_PARPORT is not set @@ -296,7 +336,6 @@ CONFIG_MTD_UCLINUX=y # # Block devices # -# CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set @@ -304,16 +343,7 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_BLK_DEV_INITRD is not set -CONFIG_INITRAMFS_SOURCE="" # CONFIG_CDROM_PKTCDVD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set # CONFIG_ATA_OVER_ETH is not set # @@ -324,6 +354,7 @@ CONFIG_IOSCHED_NOOP=y # # SCSI device support # +# CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # @@ -354,13 +385,15 @@ CONFIG_NETDEVICES=y # CONFIG_TUN is not set # +# PHY device support +# +# CONFIG_PHYLIB is not set + +# # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y # CONFIG_MII is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NE2000 is not set -# CONFIG_NET_PCI is not set CONFIG_FEC=y # CONFIG_FEC2 is not set @@ -392,6 +425,7 @@ CONFIG_PPP=y # CONFIG_PPP_SYNC_TTY is not set # CONFIG_PPP_DEFLATE is not set # CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPP_MPPE is not set # CONFIG_PPPOE is not set # CONFIG_SLIP is not set # CONFIG_SHAPER is not set @@ -425,8 +459,6 @@ CONFIG_PPP=y # # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_LEDMAN is not set -# CONFIG_RESETSWITCH is not set # # Serial drivers @@ -450,8 +482,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_MCFWATCHDOG is not set -# CONFIG_RTC is not set # CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set @@ -464,14 +494,19 @@ CONFIG_LEGACY_PTY_COUNT=256 # # TPM devices # -# CONFIG_MCF_QSPI is not set -# CONFIG_M41T11M6 is not set +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set # # I2C support # # CONFIG_I2C is not set -# CONFIG_I2C_SENSOR is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set # # Dallas's 1-wire bus @@ -482,6 +517,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # Hardware Monitoring support # # CONFIG_HWMON is not set +# CONFIG_HWMON_VID is not set # # Misc devices @@ -491,6 +527,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -503,11 +540,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_FB is not set # -# SPI support -# -# CONFIG_SPI is not set - -# # Sound # # CONFIG_SOUND is not set @@ -517,6 +549,11 @@ CONFIG_LEGACY_PTY_COUNT=256 # # CONFIG_USB_ARCH_HAS_HCD is not set # CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# # # USB Gadget Support @@ -529,29 +566,43 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_MMC is not set # +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# # InfiniBand support # # -# SN Devices +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) # # +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# # File systems # CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set - -# -# XFS support -# # CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set CONFIG_ROMFS_FS=y # CONFIG_INOTIFY is not set @@ -559,6 +610,7 @@ CONFIG_ROMFS_FS=y # CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -581,6 +633,7 @@ CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -611,6 +664,7 @@ CONFIG_RAMFS=y # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set # # Partition Types @@ -627,8 +681,12 @@ CONFIG_MSDOS_PARTITION=y # Kernel hacking # # CONFIG_PRINTK_TIME is not set +# CONFIG_MAGIC_SYSRQ is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_UNWIND_INFO is not set # CONFIG_FULLDEBUG is not set # CONFIG_HIGHPROFILE is not set # CONFIG_BOOTPARAM is not set @@ -655,5 +713,6 @@ CONFIG_LOG_BUF_SHIFT=14 # Library routines # # CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set # CONFIG_CRC32 is not set # CONFIG_LIBCRC32C is not set diff --git a/arch/m68knommu/kernel/comempci.c b/arch/m68knommu/kernel/comempci.c index 8670938f110..db7a0c1ceba 100644 --- a/arch/m68knommu/kernel/comempci.c +++ b/arch/m68knommu/kernel/comempci.c @@ -357,7 +357,8 @@ void pcibios_fixup_bus(struct pci_bus *b) /*****************************************************************************/ -void pcibios_align_resource(void *data, struct resource *res, unsigned long size, unsigned long align) +void pcibios_align_resource(void *data, struct resource *res, + resource_size_t size, resource_size_t align) { } diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c index 93120b9bfff..99d038e9ab3 100644 --- a/arch/m68knommu/kernel/setup.c +++ b/arch/m68knommu/kernel/setup.c @@ -42,7 +42,6 @@ #include <asm/pgtable.h> #endif -unsigned long rom_length; unsigned long memory_start; unsigned long memory_end; @@ -56,29 +55,29 @@ static void dummy_waitbut(void) { } -void (*mach_sched_init) (irqreturn_t (*handler)(int, void *, struct pt_regs *)) = NULL; -void (*mach_tick)( void ) = NULL; +void (*mach_sched_init) (irqreturn_t (*handler)(int, void *, struct pt_regs *)); +void (*mach_tick)( void ); /* machine dependent keyboard functions */ -int (*mach_keyb_init) (void) = NULL; -int (*mach_kbdrate) (struct kbd_repeat *) = NULL; -void (*mach_kbd_leds) (unsigned int) = NULL; +int (*mach_keyb_init) (void); +int (*mach_kbdrate) (struct kbd_repeat *); +void (*mach_kbd_leds) (unsigned int); /* machine dependent irq functions */ -void (*mach_init_IRQ) (void) = NULL; -irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL; -int (*mach_get_irq_list) (struct seq_file *, void *) = NULL; -void (*mach_process_int) (int irq, struct pt_regs *fp) = NULL; +void (*mach_init_IRQ) (void); +irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *); +int (*mach_get_irq_list) (struct seq_file *, void *); +void (*mach_process_int) (int irq, struct pt_regs *fp); void (*mach_trap_init) (void); /* machine dependent timer functions */ -unsigned long (*mach_gettimeoffset) (void) = NULL; -void (*mach_gettod) (int*, int*, int*, int*, int*, int*) = NULL; -int (*mach_hwclk) (int, struct hwclk_time*) = NULL; -int (*mach_set_clock_mmss) (unsigned long) = NULL; -void (*mach_mksound)( unsigned int count, unsigned int ticks ) = NULL; -void (*mach_reset)( void ) = NULL; +unsigned long (*mach_gettimeoffset) (void); +void (*mach_gettod) (int*, int*, int*, int*, int*, int*); +int (*mach_hwclk) (int, struct hwclk_time*); +int (*mach_set_clock_mmss) (unsigned long); +void (*mach_mksound)( unsigned int count, unsigned int ticks ); +void (*mach_reset)( void ); void (*waitbut)(void) = dummy_waitbut; -void (*mach_debug_init)(void) = NULL; -void (*mach_halt)( void ) = NULL; -void (*mach_power_off)( void ) = NULL; +void (*mach_debug_init)(void); +void (*mach_halt)( void ); +void (*mach_power_off)( void ); #ifdef CONFIG_M68000 @@ -129,6 +128,9 @@ void (*mach_power_off)( void ) = NULL; #if defined(CONFIG_M5307) #define CPU "COLDFIRE(m5307)" #endif +#if defined(CONFIG_M532x) + #define CPU "COLDFIRE(m532x)" +#endif #if defined(CONFIG_M5407) #define CPU "COLDFIRE(m5407)" #endif @@ -267,34 +269,6 @@ void setup_arch(char **cmdline_p) paging_init(); } -int get_cpuinfo(char * buffer) -{ - char *cpu, *mmu, *fpu; - u_long clockfreq; - - cpu = CPU; - mmu = "none"; - fpu = "none"; - -#ifdef CONFIG_COLDFIRE - clockfreq = (loops_per_jiffy*HZ)*3; -#else - clockfreq = (loops_per_jiffy*HZ)*16; -#endif - - return(sprintf(buffer, "CPU:\t\t%s\n" - "MMU:\t\t%s\n" - "FPU:\t\t%s\n" - "Clocking:\t%lu.%1luMHz\n" - "BogoMips:\t%lu.%02lu\n" - "Calibration:\t%lu loops\n", - cpu, mmu, fpu, - clockfreq/1000000,(clockfreq/100000)%10, - (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100, - (loops_per_jiffy*HZ))); - -} - /* * Get CPU information for use by the procfs. */ diff --git a/arch/m68knommu/kernel/signal.c b/arch/m68knommu/kernel/signal.c index 8e2c5a88efa..437f8c6c14a 100644 --- a/arch/m68knommu/kernel/signal.c +++ b/arch/m68knommu/kernel/signal.c @@ -608,7 +608,7 @@ adjust_stack: if (regs->stkadj) { struct pt_regs *tregs = (struct pt_regs *)((ulong)regs + regs->stkadj); -#if DEBUG +#if defined(DEBUG) printk(KERN_DEBUG "Performing stackadjust=%04x\n", regs->stkadj); #endif /* This must be copied with decreasing addresses to @@ -678,7 +678,7 @@ adjust_stack: if (regs->stkadj) { struct pt_regs *tregs = (struct pt_regs *)((ulong)regs + regs->stkadj); -#if DEBUG +#if defined(DEBUG) printk(KERN_DEBUG "Performing stackadjust=%04x\n", regs->stkadj); #endif /* This must be copied with decreasing addresses to diff --git a/arch/m68knommu/kernel/traps.c b/arch/m68knommu/kernel/traps.c index 5bc06846286..44ff74e643b 100644 --- a/arch/m68knommu/kernel/traps.c +++ b/arch/m68knommu/kernel/traps.c @@ -93,12 +93,12 @@ asmlinkage void buserr_c(struct frame *fp) if (user_mode(&fp->ptregs)) current->thread.esp0 = (unsigned long) fp; -#if DEBUG +#if defined(DEBUG) printk (KERN_DEBUG "*** Bus Error *** Format is %x\n", fp->ptregs.format); #endif die_if_kernel("bad frame format",&fp->ptregs,0); -#if DEBUG +#if defined(DEBUG) printk(KERN_DEBUG "Unknown SIGSEGV - 4\n"); #endif force_sig(SIGSEGV, current); diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S index a331cc90797..59ced831b79 100644 --- a/arch/m68knommu/kernel/vmlinux.lds.S +++ b/arch/m68knommu/kernel/vmlinux.lds.S @@ -1,205 +1,30 @@ /* * vmlinux.lds.S -- master linker script for m68knommu arch * - * (C) Copyright 2002-2004, Greg Ungerer <gerg@snapgear.com> + * (C) Copyright 2002-2006, Greg Ungerer <gerg@snapgear.com> * - * This ends up looking compilcated, because of the number of - * address variations for ram and rom/flash layouts. The real - * work of the linker script is all at the end, and reasonably - * strait forward. + * This linker script is equiped to build either ROM loaded or RAM + * run kernels. */ #include <linux/config.h> #include <asm-generic/vmlinux.lds.h> -/* - * Original Palm pilot (same for Xcopilot). - * There is really only a rom target for this. - */ -#ifdef CONFIG_PILOT3 -#define ROMVEC_START 0x10c00000 -#define ROMVEC_LENGTH 0x10400 -#define ROM_START 0x10c10400 -#define ROM_LENGTH 0xfec00 -#define ROM_END 0x10d00000 -#define RAMVEC_START 0x00000000 -#define RAMVEC_LENGTH 0x400 -#define RAM_START 0x10000400 -#define RAM_LENGTH 0xffc00 -#define RAM_END 0x10100000 -#define _ramend _ram_end_notused -#define DATA_ADDR RAM_START -#endif - -/* - * Same setup on both the uCsimm and uCdimm. - */ -#if defined(CONFIG_UCSIMM) || defined(CONFIG_UCDIMM) -#ifdef CONFIG_RAMKERNEL -#define ROMVEC_START 0x10c10000 -#define ROMVEC_LENGTH 0x400 -#define ROM_START 0x10c10400 -#define ROM_LENGTH 0x1efc00 -#define ROM_END 0x10e00000 -#define RAMVEC_START 0x00000000 -#define RAMVEC_LENGTH 0x400 -#define RAM_START 0x00020400 -#define RAM_LENGTH 0x7dfc00 -#define RAM_END 0x00800000 -#endif -#ifdef CONFIG_ROMKERNEL -#define ROMVEC_START 0x10c10000 -#define ROMVEC_LENGTH 0x400 -#define ROM_START 0x10c10400 -#define ROM_LENGTH 0x1efc00 -#define ROM_END 0x10e00000 -#define RAMVEC_START 0x00000000 -#define RAMVEC_LENGTH 0x400 -#define RAM_START 0x00020000 -#define RAM_LENGTH 0x600000 -#define RAM_END 0x00800000 -#endif -#ifdef CONFIG_HIMEMKERNEL -#define ROMVEC_START 0x00600000 -#define ROMVEC_LENGTH 0x400 -#define ROM_START 0x00600400 -#define ROM_LENGTH 0x1efc00 -#define ROM_END 0x007f0000 -#define RAMVEC_START 0x00000000 -#define RAMVEC_LENGTH 0x400 -#define RAM_START 0x00020000 -#define RAM_LENGTH 0x5e0000 -#define RAM_END 0x00600000 -#endif -#endif - -#ifdef CONFIG_DRAGEN2 -#define RAM_START 0x10000 -#define RAM_LENGTH 0x7f0000 -#endif - -#ifdef CONFIG_UCQUICC -#define ROMVEC_START 0x00000000 -#define ROMVEC_LENGTH 0x404 -#define ROM_START 0x00000404 -#define ROM_LENGTH 0x1ff6fc -#define ROM_END 0x00200000 -#define RAMVEC_START 0x00200000 -#define RAMVEC_LENGTH 0x404 -#define RAM_START 0x00200404 -#define RAM_LENGTH 0x1ff6fc -#define RAM_END 0x00400000 -#endif - -/* - * The standard Arnewsh 5206 board only has 1MiB of ram. Not normally - * enough to be useful. Assume the user has fitted something larger, - * at least 4MiB in size. No point in not letting the kernel completely - * link, it will be obvious if it is too big when they go to load it. - */ -#if defined(CONFIG_ARN5206) -#define RAM_START 0x10000 -#define RAM_LENGTH 0x3f0000 -#endif - -/* - * The Motorola 5206eLITE board only has 1MiB of static RAM. - */ -#if defined(CONFIG_ELITE) -#define RAM_START 0x30020000 -#define RAM_LENGTH 0xe0000 -#endif - -/* - * All the Motorola eval boards have the same basic arrangement. - * The end of RAM will vary depending on how much ram is fitted, - * but this isn't important here, we assume at least 4MiB. - */ -#if defined(CONFIG_M5206eC3) || defined(CONFIG_M5249C3) || \ - defined(CONFIG_M5272C3) || defined(CONFIG_M5307C3) || \ - defined(CONFIG_ARN5307) || defined(CONFIG_M5407C3) || \ - defined(CONFIG_M5271EVB) || defined(CONFIG_M5275EVB) || \ - defined(CONFIG_M5235EVB) -#define RAM_START 0x20000 -#define RAM_LENGTH 0x3e0000 -#endif - -/* - * The Freescale 5208EVB board has 32MB of RAM. - */ -#if defined(CONFIG_M5208EVB) -#define RAM_START 0x40020000 -#define RAM_LENGTH 0x01fe0000 -#endif - -/* - * The senTec COBRA5272 board has nearly the same memory layout as - * the M5272C3. We assume 16MiB ram. - */ -#if defined(CONFIG_COBRA5272) -#define RAM_START 0x20000 -#define RAM_LENGTH 0xfe0000 -#endif - -#if defined(CONFIG_M5282EVB) -#define RAM_START 0x10000 -#define RAM_LENGTH 0x3f0000 -#endif - -/* - * The senTec COBRA5282 board has the same memory layout as the M5282EVB. - */ -#if defined(CONFIG_COBRA5282) -#define RAM_START 0x10000 -#define RAM_LENGTH 0x3f0000 -#endif - - -/* - * The EMAC SoM-5282EM module. - */ -#if defined(CONFIG_SOM5282EM) -#define RAM_START 0x10000 -#define RAM_LENGTH 0xff0000 -#endif - - -/* - * These flash boot boards use all of ram for operation. Again the - * actual memory size is not important here, assume at least 4MiB. - * They currently have no support for running in flash. - */ -#if defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \ - defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) || \ - defined(CONFIG_HW_FEITH) -#define RAM_START 0x400 -#define RAM_LENGTH 0x3ffc00 -#endif - -/* - * Sneha Boards mimimun memory - * The end of RAM will vary depending on how much ram is fitted, - * but this isn't important here, we assume at least 4MiB. - */ -#if defined(CONFIG_CPU16B) -#define RAM_START 0x20000 -#define RAM_LENGTH 0x3e0000 -#endif - -#if defined(CONFIG_MOD5272) -#define RAM_START 0x02000000 -#define RAM_LENGTH 0x00800000 -#define RAMVEC_START 0x20000000 -#define RAMVEC_LENGTH 0x00000400 -#endif - #if defined(CONFIG_RAMKERNEL) +#define RAM_START CONFIG_KERNELBASE +#define RAM_LENGTH (CONFIG_RAMBASE + CONFIG_RAMSIZE - CONFIG_KERNELBASE) #define TEXT ram #define DATA ram #define INIT ram #define BSS ram #endif #if defined(CONFIG_ROMKERNEL) || defined(CONFIG_HIMEMKERNEL) +#define RAM_START CONFIG_RAMBASE +#define RAM_LENGTH CONFIG_RAMSIZE +#define ROMVEC_START CONFIG_ROMVEC +#define ROMVEC_LENGTH CONFIG_ROMVECSIZE +#define ROM_START CONFIG_ROMSTART +#define ROM_LENGTH CONFIG_ROMSIZE #define TEXT rom #define DATA ram #define INIT ram @@ -215,17 +40,10 @@ OUTPUT_ARCH(m68k) ENTRY(_start) MEMORY { -#ifdef RAMVEC_START - ramvec : ORIGIN = RAMVEC_START, LENGTH = RAMVEC_LENGTH -#endif ram : ORIGIN = RAM_START, LENGTH = RAM_LENGTH -#ifdef RAM_END - eram : ORIGIN = RAM_END, LENGTH = 0 -#endif #ifdef ROM_START romvec : ORIGIN = ROMVEC_START, LENGTH = ROMVEC_LENGTH rom : ORIGIN = ROM_START, LENGTH = ROM_LENGTH - erom : ORIGIN = ROM_END, LENGTH = 0 #endif } @@ -302,19 +120,6 @@ SECTIONS { _etext = . ; } > TEXT -#ifdef ROM_END - . = ROM_END ; - .erom : { - __rom_end = . ; - } > erom -#endif -#ifdef RAMVEC_START - . = RAMVEC_START ; - .ramvec : { - __ramvec = .; - } > ramvec -#endif - .data DATA_ADDR : { . = ALIGN(4); _sdata = . ; @@ -373,12 +178,5 @@ SECTIONS { _ebss = . ; } > BSS -#ifdef RAM_END - . = RAM_END ; - .eram : { - __ramend = . ; - _ramend = . ; - } > eram -#endif } diff --git a/arch/m68knommu/mm/init.c b/arch/m68knommu/mm/init.c index d79503fe6e4..70d1653be3d 100644 --- a/arch/m68knommu/mm/init.c +++ b/arch/m68knommu/mm/init.c @@ -63,8 +63,6 @@ static unsigned long empty_bad_page; unsigned long empty_zero_page; -extern unsigned long rom_length; - void show_mem(void) { unsigned long i; @@ -178,11 +176,9 @@ void mem_init(void) initk = (&__init_begin - &__init_end) >> 10; tmp = nr_free_pages() << PAGE_SHIFT; - printk(KERN_INFO "Memory available: %luk/%luk RAM, %luk/%luk ROM (%dk kernel code, %dk data)\n", + printk(KERN_INFO "Memory available: %luk/%luk RAM, (%dk kernel code, %dk data)\n", tmp >> 10, len >> 10, - (rom_length > 0) ? ((rom_length >> 10) - codek) : 0, - rom_length >> 10, codek, datak ); diff --git a/arch/m68knommu/platform/5307/Makefile b/arch/m68knommu/platform/5307/Makefile index 8d1619dc1ea..2fd37dcc309 100644 --- a/arch/m68knommu/platform/5307/Makefile +++ b/arch/m68knommu/platform/5307/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_M5249) += timers.o obj-$(CONFIG_M527x) += pit.o obj-$(CONFIG_M5272) += timers.o obj-$(CONFIG_M5307) += config.o timers.o +obj-$(CONFIG_M532x) += timers.o obj-$(CONFIG_M528x) += pit.o obj-$(CONFIG_M5407) += timers.o diff --git a/arch/m68knommu/platform/5307/entry.S b/arch/m68knommu/platform/5307/entry.S index 89b180d4ed6..9ddf5476ef8 100644 --- a/arch/m68knommu/platform/5307/entry.S +++ b/arch/m68knommu/platform/5307/entry.S @@ -4,8 +4,8 @@ * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com) * Copyright (C) 1998 D. Jeff Dionne <jeff@lineo.ca>, * Kenneth Albanowski <kjahds@kjahds.com>, - * Copyright (C) 2000 Lineo Inc. (www.lineo.com) - * Copyright (C) 2004 Macq Electronique SA. (www.macqel.com) + * Copyright (C) 2000 Lineo Inc. (www.lineo.com) + * Copyright (C) 2004-2006 Macq Electronique SA. (www.macqel.com) * * Based on: * @@ -56,32 +56,27 @@ sw_usp: .globl inthandler .globl fasthandler +enosys: + mov.l #sys_ni_syscall,%d3 + bra 1f + ENTRY(system_call) SAVE_ALL move #0x2000,%sr /* enable intrs again */ - movel #-LENOSYS,%d2 - movel %d2,PT_D0(%sp) /* default return value in d0 */ - /* original D0 is in orig_d0 */ - movel %d0,%d2 - - /* save top of frame */ - pea %sp@ - jbsr set_esp0 - addql #4,%sp - - cmpl #NR_syscalls,%d2 - jcc ret_from_exception + cmpl #NR_syscalls,%d0 + jcc enosys lea sys_call_table,%a0 - lsll #2,%d2 /* movel %a0@(%d2:l:4),%d3 */ - movel %a0@(%d2),%d3 - jeq ret_from_exception - lsrl #2,%d2 + lsll #2,%d0 /* movel %a0@(%d0:l:4),%d3 */ + movel %a0@(%d0),%d3 + jeq enosys +1: movel %sp,%d2 /* get thread_info pointer */ andl #-THREAD_SIZE,%d2 /* at start of kernel stack */ movel %d2,%a0 - btst #TIF_SYSCALL_TRACE,%a0@(TI_FLAGS) + movel %sp,%a0@(THREAD_ESP0) /* save top of frame */ + btst #(TIF_SYSCALL_TRACE%8),%a0@(TI_FLAGS+(31-TIF_SYSCALL_TRACE)/8) bnes 1f movel %d3,%a0 @@ -126,8 +121,8 @@ Luser_return: jne Lwork_to_do /* still work to do */ Lreturn: - move #0x2700,%sr /* disable intrs */ - movel sw_usp,%a0 /* get usp */ + move #0x2700,%sr /* disable intrs */ + movel sw_usp,%a0 /* get usp */ movel %sp@(PT_PC),%a0@- /* copy exception program counter */ movel %sp@(PT_FORMATVEC),%a0@-/* copy exception format/vector/sr */ moveml %sp@,%d1-%d5/%a0-%a2 @@ -170,7 +165,7 @@ ENTRY(inthandler) movel %d0,%sp@(PT_ORIG_D0) addql #1,local_irq_count - movew %sp@(PT_FORMATVEC),%d0 /* put exception # in d0 */ + movew %sp@(PT_FORMATVEC),%d0 /* put exception # in d0 */ andl #0x03fc,%d0 /* mask out vector only */ leal per_cpu__kstat+STAT_IRQ,%a0 @@ -184,7 +179,7 @@ ENTRY(inthandler) movel %sp,%sp@- /* push regs arg onto stack */ movel %a0@(8),%sp@- /* push devid arg */ - movel %d0,%sp@- /* push vector # on stack */ + movel %d0,%sp@- /* push vector # on stack */ movel %a0@,%a0 /* get function to call */ jbsr %a0@ /* call vector handler */ @@ -201,7 +196,7 @@ ENTRY(inthandler) ENTRY(fasthandler) SAVE_LOCAL - movew %sp@(PT_FORMATVEC),%d0 + movew %sp@(PT_FORMATVEC),%d0 andl #0x03fc,%d0 /* mask out vector only */ leal per_cpu__kstat+STAT_IRQ,%a0 @@ -210,7 +205,7 @@ ENTRY(fasthandler) movel %sp,%sp@- /* push regs arg onto stack */ clrl %sp@- /* push devid arg */ lsrl #2,%d0 /* calculate real vector # */ - movel %d0,%sp@- /* push vector # on stack */ + movel %d0,%sp@- /* push vector # on stack */ lsll #4,%d0 /* adjust for array offset */ lea irq_list,%a0 @@ -265,4 +260,3 @@ ENTRY(resume) movew %a1@(TASK_THREAD+THREAD_SR),%d0 /* restore thread status reg */ movew %d0, %sr rts - diff --git a/arch/m68knommu/platform/5307/head.S b/arch/m68knommu/platform/5307/head.S index c30c462b99b..1d9eb301d7a 100644 --- a/arch/m68knommu/platform/5307/head.S +++ b/arch/m68knommu/platform/5307/head.S @@ -3,7 +3,7 @@ /* * head.S -- common startup code for ColdFire CPUs. * - * (C) Copyright 1999-2004, Greg Ungerer (gerg@snapgear.com). + * (C) Copyright 1999-2006, Greg Ungerer <gerg@snapgear.com>. */ /*****************************************************************************/ @@ -19,47 +19,15 @@ /*****************************************************************************/ /* - * Define fixed memory sizes. Configuration of a fixed memory size - * overrides everything else. If the user defined a size we just - * blindly use it (they know what they are doing right :-) - */ -#if defined(CONFIG_RAM32MB) -#define MEM_SIZE 0x02000000 /* memory size 32Mb */ -#elif defined(CONFIG_RAM16MB) -#define MEM_SIZE 0x01000000 /* memory size 16Mb */ -#elif defined(CONFIG_RAM8MB) -#define MEM_SIZE 0x00800000 /* memory size 8Mb */ -#elif defined(CONFIG_RAM4MB) -#define MEM_SIZE 0x00400000 /* memory size 4Mb */ -#elif defined(CONFIG_RAM1MB) -#define MEM_SIZE 0x00100000 /* memory size 1Mb */ -#endif - -/* - * Memory size exceptions for special cases. Some boards may be set - * for auto memory sizing, but we can't do it that way for some reason. - * For example the 5206eLITE board has static RAM, and auto-detecting - * the SDRAM will do you no good at all. Same goes for the MOD5272. - */ -#ifdef CONFIG_RAMAUTO -#if defined(CONFIG_M5206eLITE) -#define MEM_SIZE 0x00100000 /* 1MiB default memory */ -#endif -#if defined(CONFIG_MOD5272) -#define MEM_SIZE 0x00800000 /* 8MiB default memory */ -#endif -#endif /* CONFIG_RAMAUTO */ - - -/* - * If we don't have a fixed memory size now, then lets build in code + * If we don't have a fixed memory size, then lets build in code * to auto detect the DRAM size. Obviously this is the prefered - * method, and should work for most boards (it won't work for those - * that do not have their RAM starting at address 0). + * method, and should work for most boards. It won't work for those + * that do not have their RAM starting at address 0, and it only + * works on SDRAM (not boards fitted with SRAM). */ -#if defined(MEM_SIZE) +#if CONFIG_RAMSIZE != 0 .macro GET_MEM_SIZE - movel #MEM_SIZE,%d0 /* hard coded memory size */ + movel #CONFIG_RAMSIZE,%d0 /* hard coded memory size */ .endm #elif defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ @@ -98,37 +66,7 @@ .endm #else -#error "ERROR: I don't know how to determine your boards memory size?" -#endif - - -/* - * Most ColdFire boards have their DRAM starting at address 0. - * Notable exception is the 5206eLITE board, another is the MOD5272. - */ -#if defined(CONFIG_M5206eLITE) -#define MEM_BASE 0x30000000 -#endif -#if defined(CONFIG_MOD5272) -#define MEM_BASE 0x02000000 -#define VBR_BASE 0x20000000 /* vectors in SRAM */ -#endif -#if defined(CONFIG_M5208EVB) -#define MEM_BASE 0x40000000 -#endif - -#ifndef MEM_BASE -#define MEM_BASE 0x00000000 /* memory base at address 0 */ -#endif - -/* - * The default location for the vectors is at the base of RAM. - * Some boards might like to use internal SRAM or something like - * that. If no board specific header defines an alternative then - * use the base of RAM. - */ -#ifndef VBR_BASE -#define VBR_BASE MEM_BASE /* vector address */ +#error "ERROR: I don't know how to probe your boards memory size?" #endif /*****************************************************************************/ @@ -191,11 +129,11 @@ _start: * Create basic memory configuration. Set VBR accordingly, * and size memory. */ - movel #VBR_BASE,%a7 + movel #CONFIG_VECTORBASE,%a7 movec %a7,%VBR /* set vectors addr */ movel %a7,_ramvec - movel #MEM_BASE,%a7 /* mark the base of RAM */ + movel #CONFIG_RAMBASE,%a7 /* mark the base of RAM */ movel %a7,_rambase GET_MEM_SIZE /* macro code determines size */ diff --git a/arch/m68knommu/platform/5307/pit.c b/arch/m68knommu/platform/5307/pit.c index 323f2677e49..ef174748825 100644 --- a/arch/m68knommu/platform/5307/pit.c +++ b/arch/m68knommu/platform/5307/pit.c @@ -1,11 +1,11 @@ /***************************************************************************/ /* - * pit.c -- Motorola ColdFire PIT timer. Currently this type of - * hardware timer only exists in the Motorola ColdFire + * pit.c -- Freescale ColdFire PIT timer. Currently this type of + * hardware timer only exists in the Freescale ColdFire * 5270/5271, 5282 and other CPUs. * - * Copyright (C) 1999-2004, Greg Ungerer (gerg@snapgear.com) + * Copyright (C) 1999-2006, Greg Ungerer (gerg@snapgear.com) * Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com) * */ @@ -18,6 +18,7 @@ #include <linux/param.h> #include <linux/init.h> #include <linux/interrupt.h> +#include <asm/io.h> #include <asm/irq.h> #include <asm/coldfire.h> #include <asm/mcfpit.h> @@ -25,13 +26,20 @@ /***************************************************************************/ +/* + * By default use timer1 as the system clock timer. + */ +#define TA(a) (MCF_IPSBAR + MCFPIT_BASE1 + (a)) + +/***************************************************************************/ + void coldfire_pit_tick(void) { - volatile struct mcfpit *tp; + unsigned short pcsr; /* Reset the ColdFire timer */ - tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1); - tp->pcsr |= MCFPIT_PCSR_PIF; + pcsr = __raw_readw(TA(MCFPIT_PCSR)); + __raw_writew(pcsr | MCFPIT_PCSR_PIF, TA(MCFPIT_PCSR)); } /***************************************************************************/ @@ -40,7 +48,6 @@ void coldfire_pit_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)) { volatile unsigned char *icrp; volatile unsigned long *imrp; - volatile struct mcfpit *tp; request_irq(MCFINT_VECBASE + MCFINT_PIT1, handler, SA_INTERRUPT, "ColdFire Timer", NULL); @@ -53,27 +60,23 @@ void coldfire_pit_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)) *imrp &= ~MCFPIT_IMR_IBIT; /* Set up PIT timer 1 as poll clock */ - tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1); - tp->pcsr = MCFPIT_PCSR_DISABLE; - - tp->pmr = ((MCF_CLK / 2) / 64) / HZ; - tp->pcsr = MCFPIT_PCSR_EN | MCFPIT_PCSR_PIE | MCFPIT_PCSR_OVW | - MCFPIT_PCSR_RLD | MCFPIT_PCSR_CLK64; + __raw_writew(MCFPIT_PCSR_DISABLE, TA(MCFPIT_PCSR)); + __raw_writew(((MCF_CLK / 2) / 64) / HZ, TA(MCFPIT_PMR)); + __raw_writew(MCFPIT_PCSR_EN | MCFPIT_PCSR_PIE | MCFPIT_PCSR_OVW | + MCFPIT_PCSR_RLD | MCFPIT_PCSR_CLK64, TA(MCFPIT_PCSR)); } /***************************************************************************/ unsigned long coldfire_pit_offset(void) { - volatile struct mcfpit *tp; volatile unsigned long *ipr; unsigned long pmr, pcntr, offset; - tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1); ipr = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFPIT_IMR); - pmr = *(&tp->pmr); - pcntr = *(&tp->pcntr); + pmr = __raw_readw(TA(MCFPIT_PMR)); + pcntr = __raw_readw(TA(MCFPIT_PCNTR)); /* * If we are still in the first half of the upcount and a diff --git a/arch/m68knommu/platform/5307/timers.c b/arch/m68knommu/platform/5307/timers.c index ef49596aa09..83b8b89dfa0 100644 --- a/arch/m68knommu/platform/5307/timers.c +++ b/arch/m68knommu/platform/5307/timers.c @@ -14,6 +14,7 @@ #include <linux/param.h> #include <linux/interrupt.h> #include <linux/init.h> +#include <asm/io.h> #include <asm/irq.h> #include <asm/traps.h> #include <asm/machdep.h> @@ -24,6 +25,11 @@ /***************************************************************************/ /* + * By default use timer1 as the system clock timer. + */ +#define TA(a) (MCF_MBAR + MCFTIMER_BASE1 + (a)) + +/* * Default the timer and vector to use for ColdFire. Some ColdFire * CPU's and some boards may want different. Their sub-architecture * startup code (in config.c) can change these if they want. @@ -32,8 +38,6 @@ unsigned int mcf_timervector = 29; unsigned int mcf_profilevector = 31; unsigned int mcf_timerlevel = 5; -static volatile struct mcftimer *mcf_timerp; - /* * These provide the underlying interrupt vector support. * Unfortunately it is a little different on each ColdFire. @@ -46,20 +50,17 @@ extern int mcf_timerirqpending(int timer); void coldfire_tick(void) { /* Reset the ColdFire timer */ - mcf_timerp->ter = MCFTIMER_TER_CAP | MCFTIMER_TER_REF; + __raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, TA(MCFTIMER_TER)); } /***************************************************************************/ void coldfire_timer_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)) { - /* Set up an internal TIMER as poll clock */ - mcf_timerp = (volatile struct mcftimer *) (MCF_MBAR + MCFTIMER_BASE1); - mcf_timerp->tmr = MCFTIMER_TMR_DISABLE; - - mcf_timerp->trr = (unsigned short) ((MCF_BUSCLK / 16) / HZ); - mcf_timerp->tmr = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | - MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE; + __raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR)); + __raw_writew(((MCF_BUSCLK / 16) / HZ), TA(MCFTIMER_TRR)); + __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | + MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, TA(MCFTIMER_TMR)); request_irq(mcf_timervector, handler, SA_INTERRUPT, "timer", NULL); mcf_settimericr(1, mcf_timerlevel); @@ -75,13 +76,8 @@ unsigned long coldfire_timer_offset(void) { unsigned long trr, tcn, offset; - /* - * The change to pointer and de-reference is to force the compiler - * to read the registers with a single 16bit access. Otherwise it - * does some crazy 8bit read combining. - */ - tcn = *(&mcf_timerp->tcn); - trr = *(&mcf_timerp->trr); + tcn = __raw_readw(TA(MCFTIMER_TCN)); + trr = __raw_readw(TA(MCFTIMER_TRR)); offset = (tcn * (1000000 / HZ)) / trr; /* Check if we just wrapped the counters and maybe missed a tick */ @@ -95,21 +91,23 @@ unsigned long coldfire_timer_offset(void) /***************************************************************************/ /* + * By default use timer2 as the profiler clock timer. + */ +#define PA(a) (MCF_MBAR + MCFTIMER_BASE2 + (a)) + +/* * Choose a reasonably fast profile timer. Make it an odd value to * try and get good coverage of kernal operations. */ #define PROFILEHZ 1013 -static volatile struct mcftimer *mcf_proftp; - /* * Use the other timer to provide high accuracy profiling info. */ - void coldfire_profile_tick(int irq, void *dummy, struct pt_regs *regs) { /* Reset ColdFire timer2 */ - mcf_proftp->ter = MCFTIMER_TER_CAP | MCFTIMER_TER_REF; + __raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, PA(MCFTIMER_TER)); if (current->pid) profile_tick(CPU_PROFILING, regs); } @@ -121,12 +119,11 @@ void coldfire_profile_init(void) printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n", PROFILEHZ); /* Set up TIMER 2 as high speed profile clock */ - mcf_proftp = (volatile struct mcftimer *) (MCF_MBAR + MCFTIMER_BASE2); - mcf_proftp->tmr = MCFTIMER_TMR_DISABLE; + __raw_writew(MCFTIMER_TMR_DISABLE, PA(MCFTIMER_TMR)); - mcf_proftp->trr = (unsigned short) ((MCF_CLK / 16) / PROFILEHZ); - mcf_proftp->tmr = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | - MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE; + __raw_writew(((MCF_CLK / 16) / PROFILEHZ), PA(MCFTIMER_TRR)); + __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | + MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, PA(MCFTIMER_TMR)); request_irq(mcf_profilevector, coldfire_profile_tick, (SA_INTERRUPT | IRQ_FLG_FAST), "profile timer", NULL); diff --git a/arch/m68knommu/platform/532x/Makefile b/arch/m68knommu/platform/532x/Makefile new file mode 100644 index 00000000000..12301803b9e --- /dev/null +++ b/arch/m68knommu/platform/532x/Makefile @@ -0,0 +1,20 @@ +# +# Makefile for the m68knommu linux kernel. +# + +# +# If you want to play with the HW breakpoints then you will +# need to add define this, which will give you a stack backtrace +# on the console port whenever a DBG interrupt occurs. You have to +# set up you HW breakpoints to trigger a DBG interrupt: +# +# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT +# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT +# + +ifdef CONFIG_FULLDEBUG +AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif + +#obj-y := config.o usb-mcf532x.o spi-mcf532x.o +obj-y := config.o diff --git a/arch/m68knommu/platform/532x/config.c b/arch/m68knommu/platform/532x/config.c new file mode 100644 index 00000000000..ceef9bc181e --- /dev/null +++ b/arch/m68knommu/platform/532x/config.c @@ -0,0 +1,486 @@ +/***************************************************************************/ + +/* + * linux/arch/m68knommu/platform/532x/config.c + * + * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com) + * Copyright (C) 2000, Lineo (www.lineo.com) + * Yaroslav Vinogradov yaroslav.vinogradov@freescale.com + * Copyright Freescale Semiconductor, Inc 2006 + * Copyright (c) 2006, emlix, Sebastian Hess <sh@emlix.com> + * + * 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. + */ + +/***************************************************************************/ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/param.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <asm/irq.h> +#include <asm/dma.h> +#include <asm/traps.h> +#include <asm/machdep.h> +#include <asm/coldfire.h> +#include <asm/mcftimer.h> +#include <asm/mcfsim.h> +#include <asm/mcfdma.h> +#include <asm/mcfwdebug.h> + +/***************************************************************************/ + +void coldfire_tick(void); +void coldfire_timer_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); +unsigned long coldfire_timer_offset(void); +void coldfire_trap_init(void); +void coldfire_reset(void); + +extern unsigned int mcf_timervector; +extern unsigned int mcf_profilevector; +extern unsigned int mcf_timerlevel; + +/***************************************************************************/ + +/* + * DMA channel base address table. + */ +unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = { }; +unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS]; + +/***************************************************************************/ + +void mcf_settimericr(unsigned int timer, unsigned int level) +{ + volatile unsigned char *icrp; + unsigned int icr; + unsigned char irq; + + if (timer <= 2) { + switch (timer) { + case 2: irq = 33; icr = MCFSIM_ICR_TIMER2; break; + default: irq = 32; icr = MCFSIM_ICR_TIMER1; break; + } + + icrp = (volatile unsigned char *) (MCF_MBAR + icr); + *icrp = level; + mcf_enable_irq0(irq); + } +} + +/***************************************************************************/ + +int mcf_timerirqpending(int timer) +{ + unsigned int imr = 0; + + switch (timer) { + case 1: imr = 0x1; break; + case 2: imr = 0x2; break; + default: break; + } + return (mcf_getiprh() & imr); +} + +/***************************************************************************/ + +void config_BSP(char *commandp, int size) +{ + mcf_setimr(MCFSIM_IMR_MASKALL); + +#if defined(CONFIG_BOOTPARAM) + strncpy(commandp, CONFIG_BOOTPARAM_STRING, size); + commandp[size-1] = 0; +#else + /* Copy command line from FLASH to local buffer... */ + memcpy(commandp, (char *) 0x4000, 4); + if(strncmp(commandp, "kcl ", 4) == 0){ + memcpy(commandp, (char *) 0x4004, size); + commandp[size-1] = 0; + } else { + memset(commandp, 0, size); + } +#endif + + mcf_timervector = 64+32; + mcf_profilevector = 64+33; + mach_sched_init = coldfire_timer_init; + mach_tick = coldfire_tick; + mach_gettimeoffset = coldfire_timer_offset; + mach_trap_init = coldfire_trap_init; + mach_reset = coldfire_reset; + +#ifdef MCF_BDM_DISABLE + /* + * Disable the BDM clocking. This also turns off most of the rest of + * the BDM device. This is good for EMC reasons. This option is not + * incompatible with the memory protection option. + */ + wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK); +#endif +} + +/***************************************************************************/ +/* Board initialization */ + +/********************************************************************/ +/* + * PLL min/max specifications + */ +#define MAX_FVCO 500000 /* KHz */ +#define MAX_FSYS 80000 /* KHz */ +#define MIN_FSYS 58333 /* KHz */ +#define FREF 16000 /* KHz */ + + +#define MAX_MFD 135 /* Multiplier */ +#define MIN_MFD 88 /* Multiplier */ +#define BUSDIV 6 /* Divider */ + +/* + * Low Power Divider specifications + */ +#define MIN_LPD (1 << 0) /* Divider (not encoded) */ +#define MAX_LPD (1 << 15) /* Divider (not encoded) */ +#define DEFAULT_LPD (1 << 1) /* Divider (not encoded) */ + +#define SYS_CLK_KHZ 80000 +#define SYSTEM_PERIOD 12.5 +/* + * SDRAM Timing Parameters + */ +#define SDRAM_BL 8 /* # of beats in a burst */ +#define SDRAM_TWR 2 /* in clocks */ +#define SDRAM_CASL 2.5 /* CASL in clocks */ +#define SDRAM_TRCD 2 /* in clocks */ +#define SDRAM_TRP 2 /* in clocks */ +#define SDRAM_TRFC 7 /* in clocks */ +#define SDRAM_TREFI 7800 /* in ns */ + +#define EXT_SRAM_ADDRESS (0xC0000000) +#define FLASH_ADDRESS (0x00000000) +#define SDRAM_ADDRESS (0x40000000) + +#define NAND_FLASH_ADDRESS (0xD0000000) + +int sys_clk_khz = 0; +int sys_clk_mhz = 0; + +void wtm_init(void); +void scm_init(void); +void gpio_init(void); +void fbcs_init(void); +void sdramc_init(void); +int clock_pll (int fsys, int flags); +int clock_limp (int); +int clock_exit_limp (void); +int get_sys_clock (void); + +asmlinkage void __init sysinit(void) +{ + sys_clk_khz = clock_pll(0, 0); + sys_clk_mhz = sys_clk_khz/1000; + + wtm_init(); + scm_init(); + gpio_init(); + fbcs_init(); + sdramc_init(); +} + +void wtm_init(void) +{ + /* Disable watchdog timer */ + MCF_WTM_WCR = 0; +} + +#define MCF_SCM_BCR_GBW (0x00000100) +#define MCF_SCM_BCR_GBR (0x00000200) + +void scm_init(void) +{ + /* All masters are trusted */ + MCF_SCM_MPR = 0x77777777; + + /* Allow supervisor/user, read/write, and trusted/untrusted + access to all slaves */ + MCF_SCM_PACRA = 0; + MCF_SCM_PACRB = 0; + MCF_SCM_PACRC = 0; + MCF_SCM_PACRD = 0; + MCF_SCM_PACRE = 0; + MCF_SCM_PACRF = 0; + + /* Enable bursts */ + MCF_SCM_BCR = (MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW); +} + + +void fbcs_init(void) +{ + MCF_GPIO_PAR_CS = 0x0000003E; + + /* Latch chip select */ + MCF_FBCS1_CSAR = 0x10080000; + + MCF_FBCS1_CSCR = 0x002A3780; + MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V); + + /* Initialize latch to drive signals to inactive states */ + *((u16 *)(0x10080000)) = 0xFFFF; + + /* External SRAM */ + MCF_FBCS1_CSAR = EXT_SRAM_ADDRESS; + MCF_FBCS1_CSCR = (MCF_FBCS_CSCR_PS_16 + | MCF_FBCS_CSCR_AA + | MCF_FBCS_CSCR_SBM + | MCF_FBCS_CSCR_WS(1)); + MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_512K + | MCF_FBCS_CSMR_V); + + /* Boot Flash connected to FBCS0 */ + MCF_FBCS0_CSAR = FLASH_ADDRESS; + MCF_FBCS0_CSCR = (MCF_FBCS_CSCR_PS_16 + | MCF_FBCS_CSCR_BEM + | MCF_FBCS_CSCR_AA + | MCF_FBCS_CSCR_SBM + | MCF_FBCS_CSCR_WS(7)); + MCF_FBCS0_CSMR = (MCF_FBCS_CSMR_BAM_32M + | MCF_FBCS_CSMR_V); +} + +void sdramc_init(void) +{ + /* + * Check to see if the SDRAM has already been initialized + * by a run control tool + */ + if (!(MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)) { + /* SDRAM chip select initialization */ + + /* Initialize SDRAM chip select */ + MCF_SDRAMC_SDCS0 = (0 + | MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS) + | MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE)); + + /* + * Basic configuration and initialization + */ + MCF_SDRAMC_SDCFG1 = (0 + | MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5 )) + | MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1) + | MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL*2) + 2)) + | MCF_SDRAMC_SDCFG1_ACT2RW((int)((SDRAM_TRCD ) + 0.5)) + | MCF_SDRAMC_SDCFG1_PRE2ACT((int)((SDRAM_TRP ) + 0.5)) + | MCF_SDRAMC_SDCFG1_REF2ACT((int)(((SDRAM_TRFC) ) + 0.5)) + | MCF_SDRAMC_SDCFG1_WTLAT(3)); + MCF_SDRAMC_SDCFG2 = (0 + | MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL/2 + 1) + | MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL/2 + SDRAM_TWR) + | MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL+SDRAM_BL/2-1.0)+0.5)) + | MCF_SDRAMC_SDCFG2_BL(SDRAM_BL-1)); + + + /* + * Precharge and enable write to SDMR + */ + MCF_SDRAMC_SDCR = (0 + | MCF_SDRAMC_SDCR_MODE_EN + | MCF_SDRAMC_SDCR_CKE + | MCF_SDRAMC_SDCR_DDR + | MCF_SDRAMC_SDCR_MUX(1) + | MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI/(SYSTEM_PERIOD*64)) - 1) + 0.5)) + | MCF_SDRAMC_SDCR_PS_16 + | MCF_SDRAMC_SDCR_IPALL); + + /* + * Write extended mode register + */ + MCF_SDRAMC_SDMR = (0 + | MCF_SDRAMC_SDMR_BNKAD_LEMR + | MCF_SDRAMC_SDMR_AD(0x0) + | MCF_SDRAMC_SDMR_CMD); + + /* + * Write mode register and reset DLL + */ + MCF_SDRAMC_SDMR = (0 + | MCF_SDRAMC_SDMR_BNKAD_LMR + | MCF_SDRAMC_SDMR_AD(0x163) + | MCF_SDRAMC_SDMR_CMD); + + /* + * Execute a PALL command + */ + MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IPALL; + + /* + * Perform two REF cycles + */ + MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF; + MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF; + + /* + * Write mode register and clear reset DLL + */ + MCF_SDRAMC_SDMR = (0 + | MCF_SDRAMC_SDMR_BNKAD_LMR + | MCF_SDRAMC_SDMR_AD(0x063) + | MCF_SDRAMC_SDMR_CMD); + + /* + * Enable auto refresh and lock SDMR + */ + MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_MODE_EN; + MCF_SDRAMC_SDCR |= (0 + | MCF_SDRAMC_SDCR_REF + | MCF_SDRAMC_SDCR_DQS_OE(0xC)); + } +} + +void gpio_init(void) +{ + /* Enable UART0 pins */ + MCF_GPIO_PAR_UART = ( 0 + | MCF_GPIO_PAR_UART_PAR_URXD0 + | MCF_GPIO_PAR_UART_PAR_UTXD0); + + /* Initialize TIN3 as a GPIO output to enable the write + half of the latch */ + MCF_GPIO_PAR_TIMER = 0x00; + MCF_GPIO_PDDR_TIMER = 0x08; + MCF_GPIO_PCLRR_TIMER = 0x0; + +} + +int clock_pll(int fsys, int flags) +{ + int fref, temp, fout, mfd; + u32 i; + + fref = FREF; + + if (fsys == 0) { + /* Return current PLL output */ + mfd = MCF_PLL_PFDR; + + return (fref * mfd / (BUSDIV * 4)); + } + + /* Check bounds of requested system clock */ + if (fsys > MAX_FSYS) + fsys = MAX_FSYS; + if (fsys < MIN_FSYS) + fsys = MIN_FSYS; + + /* Multiplying by 100 when calculating the temp value, + and then dividing by 100 to calculate the mfd allows + for exact values without needing to include floating + point libraries. */ + temp = 100 * fsys / fref; + mfd = 4 * BUSDIV * temp / 100; + + /* Determine the output frequency for selected values */ + fout = (fref * mfd / (BUSDIV * 4)); + + /* + * Check to see if the SDRAM has already been initialized. + * If it has then the SDRAM needs to be put into self refresh + * mode before reprogramming the PLL. + */ + if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF) + /* Put SDRAM into self refresh mode */ + MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_CKE; + + /* + * Initialize the PLL to generate the new system clock frequency. + * The device must be put into LIMP mode to reprogram the PLL. + */ + + /* Enter LIMP mode */ + clock_limp(DEFAULT_LPD); + + /* Reprogram PLL for desired fsys */ + MCF_PLL_PODR = (0 + | MCF_PLL_PODR_CPUDIV(BUSDIV/3) + | MCF_PLL_PODR_BUSDIV(BUSDIV)); + + MCF_PLL_PFDR = mfd; + + /* Exit LIMP mode */ + clock_exit_limp(); + + /* + * Return the SDRAM to normal operation if it is in use. + */ + if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF) + /* Exit self refresh mode */ + MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_CKE; + + /* Errata - workaround for SDRAM opeartion after exiting LIMP mode */ + MCF_SDRAMC_LIMP_FIX = MCF_SDRAMC_REFRESH; + + /* wait for DQS logic to relock */ + for (i = 0; i < 0x200; i++) + ; + + return fout; +} + +int clock_limp(int div) +{ + u32 temp; + + /* Check bounds of divider */ + if (div < MIN_LPD) + div = MIN_LPD; + if (div > MAX_LPD) + div = MAX_LPD; + + /* Save of the current value of the SSIDIV so we don't + overwrite the value*/ + temp = (MCF_CCM_CDR & MCF_CCM_CDR_SSIDIV(0xF)); + + /* Apply the divider to the system clock */ + MCF_CCM_CDR = ( 0 + | MCF_CCM_CDR_LPDIV(div) + | MCF_CCM_CDR_SSIDIV(temp)); + + MCF_CCM_MISCCR |= MCF_CCM_MISCCR_LIMP; + + return (FREF/(3*(1 << div))); +} + +int clock_exit_limp(void) +{ + int fout; + + /* Exit LIMP mode */ + MCF_CCM_MISCCR = (MCF_CCM_MISCCR & ~ MCF_CCM_MISCCR_LIMP); + + /* Wait for PLL to lock */ + while (!(MCF_CCM_MISCCR & MCF_CCM_MISCCR_PLL_LOCK)) + ; + + fout = get_sys_clock(); + + return fout; +} + +int get_sys_clock(void) +{ + int divider; + + /* Test to see if device is in LIMP mode */ + if (MCF_CCM_MISCCR & MCF_CCM_MISCCR_LIMP) { + divider = MCF_CCM_CDR & MCF_CCM_CDR_LPDIV(0xF); + return (FREF/(2 << divider)); + } + else + return ((FREF * MCF_PLL_PFDR) / (BUSDIV * 4)); +} diff --git a/arch/m68knommu/platform/68328/Makefile b/arch/m68knommu/platform/68328/Makefile index 1b3b719e447..5e5435552d5 100644 --- a/arch/m68knommu/platform/68328/Makefile +++ b/arch/m68knommu/platform/68328/Makefile @@ -8,6 +8,7 @@ head-$(CONFIG_DRAGEN2) = head-de2.o obj-y += entry.o ints.o timers.o obj-$(CONFIG_M68328) += config.o +obj-$(CONFIG_ROM) += romvec.o extra-y := head.o extra-$(CONFIG_M68328) += bootlogo.rh head.o diff --git a/arch/m68knommu/platform/68328/head-pilot.S b/arch/m68knommu/platform/68328/head-pilot.S index c46775fe04b..46b3604f999 100644 --- a/arch/m68knommu/platform/68328/head-pilot.S +++ b/arch/m68knommu/platform/68328/head-pilot.S @@ -21,7 +21,6 @@ .global _start .global _rambase -.global __ramvec .global _ramvec .global _ramstart .global _ramend @@ -121,7 +120,7 @@ L0: DBG_PUTC('B') /* Copy command line from beginning of RAM (+16) to end of bss */ - movel #__ramvec, %d7 + movel #CONFIG_VECTORBASE, %d7 addl #16, %d7 moveal %d7, %a0 moveal #_ebss, %a1 diff --git a/arch/m68knommu/platform/68328/head-ram.S b/arch/m68knommu/platform/68328/head-ram.S index 6bdc9bce43f..e8dc9241ff9 100644 --- a/arch/m68knommu/platform/68328/head-ram.S +++ b/arch/m68knommu/platform/68328/head-ram.S @@ -1,10 +1,7 @@ #include <linux/config.h> .global __main - .global __ram_start - .global __ram_end .global __rom_start - .global __rom_end .global _rambase .global _ramstart @@ -12,6 +9,7 @@ .global splash_bits .global _start .global _stext + .global _edata #define DEBUG #define ROM_OFFSET 0x10C00000 @@ -73,7 +71,7 @@ pclp1: #ifdef CONFIG_RELOCATE /* Copy me to RAM */ moveal #__rom_start, %a0 - moveal #__ram_start, %a1 + moveal #_stext, %a1 moveal #_edata, %a2 /* Copy %a0 to %a1 until %a1 == %a2 */ diff --git a/arch/m68knommu/platform/68328/head-rom.S b/arch/m68knommu/platform/68328/head-rom.S index 2b448a29701..234430b9551 100644 --- a/arch/m68knommu/platform/68328/head-rom.S +++ b/arch/m68knommu/platform/68328/head-rom.S @@ -28,6 +28,8 @@ _ramstart: _ramend: .long 0 +#define RAMEND (CONFIG_RAMBASE + CONFIG_RAMSIZE) + #ifdef CONFIG_INIT_LCD splash_bits: #include "bootlogo.rh" @@ -48,7 +50,7 @@ _stext: movew #0x2700,%sr moveb #0x81, 0xfffffA27 /* LCKCON */ movew #0xff00, 0xfffff412 /* LCD pins */ #endif - moveal #__ramend-CONFIG_MEMORY_RESERVE*0x100000 - 0x10, %sp + moveal #RAMEND-CONFIG_MEMORY_RESERVE*0x100000 - 0x10, %sp movew #32767, %d0 /* PLL settle wait loop */ 1: subq #1, %d0 bne 1b @@ -73,13 +75,13 @@ _stext: movew #0x2700,%sr bhi 1b movel #_sdata, %d0 - movel %d0, _rambase - movel #_ebss, %d0 - movel %d0, _ramstart - movel #__ramend-CONFIG_MEMORY_RESERVE*0x100000, %d0 - movel %d0, _ramend - movel #__ramvec, %d0 - movel %d0, _ramvec + movel %d0, _rambase + movel #_ebss, %d0 + movel %d0, _ramstart + movel #RAMEND-CONFIG_MEMORY_RESERVE*0x100000, %d0 + movel %d0, _ramend + movel #CONFIG_VECTORBASE, %d0 + movel %d0, _ramvec /* * load the current task pointer and stack diff --git a/arch/m68knommu/platform/68328/ints.c b/arch/m68knommu/platform/68328/ints.c index 7437217813d..2dda7339aae 100644 --- a/arch/m68knommu/platform/68328/ints.c +++ b/arch/m68knommu/platform/68328/ints.c @@ -18,6 +18,7 @@ #include <asm/system.h> #include <asm/irq.h> +#include <asm/irqnode.h> #include <asm/traps.h> #include <asm/io.h> #include <asm/machdep.h> @@ -82,25 +83,6 @@ unsigned int local_irq_count[NR_CPUS]; /* irq node variables for the 32 (potential) on chip sources */ static irq_node_t int_irq_list[NR_IRQS]; -#if !defined(CONFIG_DRAGEN2) -asm (".global _start, __ramend/n/t" - ".section .romvec/n" - "e_vectors:\n\t" - ".long __ramend-4, _start, buserr, trap, trap, trap, trap, trap\n\t" - ".long trap, trap, trap, trap, trap, trap, trap, trap\n\t" - ".long trap, trap, trap, trap, trap, trap, trap, trap\n\t" - ".long trap, trap, trap, trap\n\t" - ".long trap, trap, trap, trap\n\t" - /*.long inthandler, inthandler, inthandler, inthandler - .long inthandler4, inthandler, inthandler, inthandler */ - /* TRAP #0-15 */ - ".long system_call, trap, trap, trap, trap, trap, trap, trap\n\t" - ".long trap, trap, trap, trap, trap, trap, trap, trap\n\t" - ".long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n\t" - ".text\n" - "ignore: rte"); -#endif - /* * This function should be called during kernel startup to initialize * the IRQ handling routines. diff --git a/arch/m68knommu/platform/68328/romvec.S b/arch/m68knommu/platform/68328/romvec.S new file mode 100644 index 00000000000..3e7fe1e1491 --- /dev/null +++ b/arch/m68knommu/platform/68328/romvec.S @@ -0,0 +1,37 @@ +/* + * linux/arch/m68knommu/platform/68328/romvec.S + * + * 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. + * + * Copyright 1996 Roman Zippel + * Copyright 1999 D. Jeff Dionne <jeff@rt-control.com> + * Copyright 2006 Greg Ungerer <gerg@snapgear.com> + */ + +#include <linux/config.h> + +.global _start +.global _buserr +.global trap +.global system_call + +.section .romvec + +e_vectors: +.long CONFIG_RAMBASE+CONFIG_RAMSIZE-4, _start, buserr, trap +.long trap, trap, trap, trap +.long trap, trap, trap, trap +.long trap, trap, trap, trap +.long trap, trap, trap, trap +.long trap, trap, trap, trap +.long trap, trap, trap, trap +.long trap, trap, trap, trap +/* TRAP #0-15 */ +.long system_call, trap, trap, trap +.long trap, trap, trap, trap +.long trap, trap, trap, trap +.long trap, trap, trap, trap +.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + diff --git a/arch/m68knommu/platform/68360/config.c b/arch/m68knommu/platform/68360/config.c index 3db244625f0..69c670dfd62 100644 --- a/arch/m68knommu/platform/68360/config.c +++ b/arch/m68knommu/platform/68360/config.c @@ -141,13 +141,13 @@ int BSP_set_clock_mmss (unsigned long nowtime) void BSP_reset (void) { local_irq_disable(); - asm volatile (" - moveal #_start, %a0; - moveb #0, 0xFFFFF300; - moveal 0(%a0), %sp; - moveal 4(%a0), %a0; - jmp (%a0); - "); + asm volatile ( + "moveal #_start, %a0;\n" + "moveb #0, 0xFFFFF300;\n" + "moveal 0(%a0), %sp;\n" + "moveal 4(%a0), %a0;\n" + "jmp (%a0);\n" + ); } unsigned char *scc1_hwaddr; diff --git a/arch/m68knommu/platform/68360/head-ram.S b/arch/m68knommu/platform/68360/head-ram.S index a5c639a51ee..f497713a4ec 100644 --- a/arch/m68knommu/platform/68360/head-ram.S +++ b/arch/m68knommu/platform/68360/head-ram.S @@ -18,7 +18,6 @@ .global _start .global _rambase -.global __ramvec .global _ramvec .global _ramstart .global _ramend @@ -26,6 +25,8 @@ .global _quicc_base .global _periph_base +#define RAMEND (CONFIG_RAMBASE + CONFIG_RAMSIZE) + #define REGB 0x1000 #define PEPAR (_dprbase + REGB + 0x0016) #define GMR (_dprbase + REGB + 0x0040) @@ -103,7 +104,7 @@ _stext: nop ori.w #MCU_DISABLE_INTRPTS, %sr /* disable interrupts: */ /* We should not need to setup the boot stack the reset should do it. */ - movea.l #__ramend, %sp /*set up stack at the end of DRAM:*/ + movea.l #RAMEND, %sp /*set up stack at the end of DRAM:*/ set_mbar_register: moveq.l #0x07, %d1 /* Setup MBAR */ @@ -163,7 +164,7 @@ configure_memory_controller: move.l %d0, GMR configure_chip_select_0: - move.l #__ramend, %d0 + move.l #RAMEND, %d0 subi.l #__ramstart, %d0 subq.l #0x01, %d0 eori.l #SIM_OR_MASK, %d0 @@ -234,16 +235,10 @@ store_ram_size: /* Set ram size information */ move.l #_sdata, _rambase move.l #_ebss, _ramstart - move.l #__ramend, %d0 + move.l #RAMEND, %d0 sub.l #0x1000, %d0 /* Reserve 4K for stack space.*/ - move.l %d0, _ramend /* Different from __ramend.*/ + move.l %d0, _ramend /* Different from RAMEND.*/ -store_flash_size: - /* Set rom size information */ - move.l #__rom_end, %d0 - sub.l #__rom_start, %d0 - move.l %d0, rom_length - pea 0 pea env pea %sp@(4) @@ -286,7 +281,7 @@ _dprbase: */ .section ".data.initvect","awx" - .long __ramend /* Reset: Initial Stack Pointer - 0. */ + .long RAMEND /* Reset: Initial Stack Pointer - 0. */ .long _start /* Reset: Initial Program Counter - 1. */ .long buserr /* Bus Error - 2. */ .long trap /* Address Error - 3. */ diff --git a/arch/m68knommu/platform/68360/head-rom.S b/arch/m68knommu/platform/68360/head-rom.S index 0da357a4cfe..2d28c3e19a8 100644 --- a/arch/m68knommu/platform/68360/head-rom.S +++ b/arch/m68knommu/platform/68360/head-rom.S @@ -18,7 +18,6 @@ .global _start .global _rambase -.global __ramvec .global _ramvec .global _ramstart .global _ramend @@ -26,6 +25,8 @@ .global _quicc_base .global _periph_base +#define RAMEND (CONFIG_RAMBASE + CONFIG_RAMSIZE) + #define REGB 0x1000 #define PEPAR (_dprbase + REGB + 0x0016) #define GMR (_dprbase + REGB + 0x0040) @@ -115,7 +116,7 @@ _stext: nop ori.w #MCU_DISABLE_INTRPTS, %sr /* disable interrupts: */ /* We should not need to setup the boot stack the reset should do it. */ - movea.l #__ramend, %sp /* set up stack at the end of DRAM:*/ + movea.l #RAMEND, %sp /* set up stack at the end of DRAM:*/ set_mbar_register: @@ -245,16 +246,10 @@ store_ram_size: /* Set ram size information */ move.l #_sdata, _rambase move.l #_ebss, _ramstart - move.l #__ramend, %d0 + move.l #RAMEND, %d0 sub.l #0x1000, %d0 /* Reserve 4K for stack space.*/ - move.l %d0, _ramend /* Different from __ramend.*/ + move.l %d0, _ramend /* Different from RAMEND.*/ -store_flash_size: - /* Set rom size information */ - move.l #__rom_end, %d0 - sub.l #__rom_start, %d0 - move.l %d0, rom_length - pea 0 pea env pea %sp@(4) @@ -298,7 +293,7 @@ _dprbase: */ .section ".data.initvect","awx" - .long __ramend /* Reset: Initial Stack Pointer - 0. */ + .long RAMEND /* Reset: Initial Stack Pointer - 0. */ .long _start /* Reset: Initial Program Counter - 1. */ .long buserr /* Bus Error - 2. */ .long trap /* Address Error - 3. */ diff --git a/arch/m68knommu/platform/68360/ints.c b/arch/m68knommu/platform/68360/ints.c index ba184db1651..0245fc4a478 100644 --- a/arch/m68knommu/platform/68360/ints.c +++ b/arch/m68knommu/platform/68360/ints.c @@ -20,6 +20,7 @@ #include <asm/system.h> #include <asm/irq.h> +#include <asm/irqnode.h> #include <asm/traps.h> #include <asm/io.h> #include <asm/machdep.h> diff --git a/arch/m68knommu/platform/68EZ328/config.c b/arch/m68knommu/platform/68EZ328/config.c index d8d56e5de31..15a14a67c2b 100644 --- a/arch/m68knommu/platform/68EZ328/config.c +++ b/arch/m68knommu/platform/68EZ328/config.c @@ -42,13 +42,13 @@ void m68328_timer_gettod(int *year, int *mon, int *day, int *hour, int *min, int void m68ez328_reset(void) { local_irq_disable(); - asm volatile (" - moveal #0x10c00000, %a0; - moveb #0, 0xFFFFF300; - moveal 0(%a0), %sp; - moveal 4(%a0), %a0; - jmp (%a0); - "); + asm volatile ( + "moveal #0x10c00000, %a0;\n" + "moveb #0, 0xFFFFF300;\n" + "moveal 0(%a0), %sp;\n" + "moveal 4(%a0), %a0;\n" + "jmp (%a0);\n" + ); } /***************************************************************************/ diff --git a/arch/m68knommu/platform/68VZ328/config.c b/arch/m68knommu/platform/68VZ328/config.c index d926524cdf8..4058de5c8fa 100644 --- a/arch/m68knommu/platform/68VZ328/config.c +++ b/arch/m68knommu/platform/68VZ328/config.c @@ -141,13 +141,13 @@ static void init_hardware(char *command, int size) static void m68vz328_reset(void) { local_irq_disable(); - asm volatile (" - moveal #0x10c00000, %a0; - moveb #0, 0xFFFFF300; - moveal 0(%a0), %sp; - moveal 4(%a0), %a0; - jmp (%a0); - "); + asm volatile ( + "moveal #0x10c00000, %a0;\n\t" + "moveb #0, 0xFFFFF300;\n\t" + "moveal 0(%a0), %sp;\n\t" + "moveal 4(%a0), %a0;\n\t" + "jmp (%a0);\n" + ); } unsigned char *cs8900a_hwaddr; diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 35e038a974c..08c2ece4ae4 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1618,6 +1618,11 @@ config GENERIC_IRQ_PROBE bool default y +config IRQ_PER_CPU + depends on SMP + bool + default y + # # - Highmem only makes sense for the 32-bit kernel. # - The current highmem code will only work properly on physically indexed diff --git a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c index afe05ec12c2..da74ac21954 100644 --- a/arch/mips/au1000/common/irq.c +++ b/arch/mips/au1000/common/irq.c @@ -333,31 +333,31 @@ static void setup_local_irq(unsigned int irq_nr, int type, int int_req) au_writel(1<<(irq_nr-32), IC1_CFG2CLR); au_writel(1<<(irq_nr-32), IC1_CFG1CLR); au_writel(1<<(irq_nr-32), IC1_CFG0SET); - irq_desc[irq_nr].handler = &rise_edge_irq_type; + irq_desc[irq_nr].chip = &rise_edge_irq_type; break; case INTC_INT_FALL_EDGE: /* 0:1:0 */ au_writel(1<<(irq_nr-32), IC1_CFG2CLR); au_writel(1<<(irq_nr-32), IC1_CFG1SET); au_writel(1<<(irq_nr-32), IC1_CFG0CLR); - irq_desc[irq_nr].handler = &fall_edge_irq_type; + irq_desc[irq_nr].chip = &fall_edge_irq_type; break; case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ au_writel(1<<(irq_nr-32), IC1_CFG2CLR); au_writel(1<<(irq_nr-32), IC1_CFG1SET); au_writel(1<<(irq_nr-32), IC1_CFG0SET); - irq_desc[irq_nr].handler = &either_edge_irq_type; + irq_desc[irq_nr].chip = &either_edge_irq_type; break; case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ au_writel(1<<(irq_nr-32), IC1_CFG2SET); au_writel(1<<(irq_nr-32), IC1_CFG1CLR); au_writel(1<<(irq_nr-32), IC1_CFG0SET); - irq_desc[irq_nr].handler = &level_irq_type; + irq_desc[irq_nr].chip = &level_irq_type; break; case INTC_INT_LOW_LEVEL: /* 1:1:0 */ au_writel(1<<(irq_nr-32), IC1_CFG2SET); au_writel(1<<(irq_nr-32), IC1_CFG1SET); au_writel(1<<(irq_nr-32), IC1_CFG0CLR); - irq_desc[irq_nr].handler = &level_irq_type; + irq_desc[irq_nr].chip = &level_irq_type; break; case INTC_INT_DISABLED: /* 0:0:0 */ au_writel(1<<(irq_nr-32), IC1_CFG0CLR); @@ -385,31 +385,31 @@ static void setup_local_irq(unsigned int irq_nr, int type, int int_req) au_writel(1<<irq_nr, IC0_CFG2CLR); au_writel(1<<irq_nr, IC0_CFG1CLR); au_writel(1<<irq_nr, IC0_CFG0SET); - irq_desc[irq_nr].handler = &rise_edge_irq_type; + irq_desc[irq_nr].chip = &rise_edge_irq_type; break; case INTC_INT_FALL_EDGE: /* 0:1:0 */ au_writel(1<<irq_nr, IC0_CFG2CLR); au_writel(1<<irq_nr, IC0_CFG1SET); au_writel(1<<irq_nr, IC0_CFG0CLR); - irq_desc[irq_nr].handler = &fall_edge_irq_type; + irq_desc[irq_nr].chip = &fall_edge_irq_type; break; case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ au_writel(1<<irq_nr, IC0_CFG2CLR); au_writel(1<<irq_nr, IC0_CFG1SET); au_writel(1<<irq_nr, IC0_CFG0SET); - irq_desc[irq_nr].handler = &either_edge_irq_type; + irq_desc[irq_nr].chip = &either_edge_irq_type; break; case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ au_writel(1<<irq_nr, IC0_CFG2SET); au_writel(1<<irq_nr, IC0_CFG1CLR); au_writel(1<<irq_nr, IC0_CFG0SET); - irq_desc[irq_nr].handler = &level_irq_type; + irq_desc[irq_nr].chip = &level_irq_type; break; case INTC_INT_LOW_LEVEL: /* 1:1:0 */ au_writel(1<<irq_nr, IC0_CFG2SET); au_writel(1<<irq_nr, IC0_CFG1SET); au_writel(1<<irq_nr, IC0_CFG0CLR); - irq_desc[irq_nr].handler = &level_irq_type; + irq_desc[irq_nr].chip = &level_irq_type; break; case INTC_INT_DISABLED: /* 0:0:0 */ au_writel(1<<irq_nr, IC0_CFG0CLR); diff --git a/arch/mips/au1000/pb1200/irqmap.c b/arch/mips/au1000/pb1200/irqmap.c index bacc0c6bfe6..5dd164fc188 100644 --- a/arch/mips/au1000/pb1200/irqmap.c +++ b/arch/mips/au1000/pb1200/irqmap.c @@ -172,7 +172,7 @@ void _board_init_irq(void) for (irq_nr = PB1200_INT_BEGIN; irq_nr <= PB1200_INT_END; irq_nr++) { - irq_desc[irq_nr].handler = &external_irq_type; + irq_desc[irq_nr].chip = &external_irq_type; pb1200_disable_irq(irq_nr); } diff --git a/arch/mips/ddb5xxx/ddb5477/irq_5477.c b/arch/mips/ddb5xxx/ddb5477/irq_5477.c index 5fcd5f070cd..63c3d6534b3 100644 --- a/arch/mips/ddb5xxx/ddb5477/irq_5477.c +++ b/arch/mips/ddb5xxx/ddb5477/irq_5477.c @@ -107,7 +107,7 @@ void __init vrc5477_irq_init(u32 irq_base) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].handler = &vrc5477_irq_controller; + irq_desc[i].chip = &vrc5477_irq_controller; } vrc5477_irq_base = irq_base; diff --git a/arch/mips/dec/ioasic-irq.c b/arch/mips/dec/ioasic-irq.c index d5bca5d233b..da2dbb42f91 100644 --- a/arch/mips/dec/ioasic-irq.c +++ b/arch/mips/dec/ioasic-irq.c @@ -144,13 +144,13 @@ void __init init_ioasic_irqs(int base) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; - irq_desc[i].handler = &ioasic_irq_type; + irq_desc[i].chip = &ioasic_irq_type; } for (; i < base + IO_IRQ_LINES; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; - irq_desc[i].handler = &ioasic_dma_irq_type; + irq_desc[i].chip = &ioasic_dma_irq_type; } ioasic_irq_base = base; diff --git a/arch/mips/dec/kn02-irq.c b/arch/mips/dec/kn02-irq.c index 898bed502a3..d44c00d9e80 100644 --- a/arch/mips/dec/kn02-irq.c +++ b/arch/mips/dec/kn02-irq.c @@ -123,7 +123,7 @@ void __init init_kn02_irqs(int base) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; - irq_desc[i].handler = &kn02_irq_type; + irq_desc[i].chip = &kn02_irq_type; } kn02_irq_base = base; diff --git a/arch/mips/gt64120/ev64120/irq.c b/arch/mips/gt64120/ev64120/irq.c index 46c468b26b3..f489a8067a9 100644 --- a/arch/mips/gt64120/ev64120/irq.c +++ b/arch/mips/gt64120/ev64120/irq.c @@ -138,7 +138,7 @@ void __init arch_init_irq(void) /* Let's initialize our IRQ descriptors */ for (i = 0; i < NR_IRQS; i++) { irq_desc[i].status = 0; - irq_desc[i].handler = &no_irq_type; + irq_desc[i].chip = &no_irq_type; irq_desc[i].action = NULL; irq_desc[i].depth = 0; spin_lock_init(&irq_desc[i].lock); diff --git a/arch/mips/ite-boards/generic/irq.c b/arch/mips/ite-boards/generic/irq.c index 77be7216bdd..a6749c56fe3 100644 --- a/arch/mips/ite-boards/generic/irq.c +++ b/arch/mips/ite-boards/generic/irq.c @@ -208,10 +208,10 @@ void __init arch_init_irq(void) #endif for (i = 0; i <= IT8172_LAST_IRQ; i++) { - irq_desc[i].handler = &it8172_irq_type; + irq_desc[i].chip = &it8172_irq_type; spin_lock_init(&irq_desc[i].lock); } - irq_desc[MIPS_CPU_TIMER_IRQ].handler = &cp0_irq_type; + irq_desc[MIPS_CPU_TIMER_IRQ].chip = &cp0_irq_type; set_c0_status(ALLINTS_NOTIMER); } diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c index becc9accd49..478be9858a1 100644 --- a/arch/mips/jazz/irq.c +++ b/arch/mips/jazz/irq.c @@ -73,7 +73,7 @@ void __init init_r4030_ints(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; - irq_desc[i].handler = &r4030_irq_type; + irq_desc[i].chip = &r4030_irq_type; } r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 0); diff --git a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c index 11304d1354f..380046ea1db 100644 --- a/arch/mips/jmr3927/rbhma3100/irq.c +++ b/arch/mips/jmr3927/rbhma3100/irq.c @@ -435,7 +435,7 @@ void jmr3927_irq_init(u32 irq_base) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].handler = &jmr3927_irq_controller; + irq_desc[i].chip = &jmr3927_irq_controller; } jmr3927_irq_base = irq_base; diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index 0cb8ed5662f..91ffb1233ca 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c @@ -120,7 +120,7 @@ int i8259A_irq_pending(unsigned int irq) void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &i8259A_irq_type; + irq_desc[irq].chip = &i8259A_irq_type; enable_irq(irq); } @@ -327,7 +327,7 @@ void __init init_i8259_irqs (void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].handler = &i8259A_irq_type; + irq_desc[i].chip = &i8259A_irq_type; } setup_irq(2, &irq2); diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c index 97ebdc754b9..f8cd1ac64d8 100644 --- a/arch/mips/kernel/irq-msc01.c +++ b/arch/mips/kernel/irq-msc01.c @@ -174,14 +174,14 @@ void __init init_msc_irqs(unsigned int base, msc_irqmap_t *imp, int nirq) switch (imp->im_type) { case MSC01_IRQ_EDGE: - irq_desc[base+n].handler = &msc_edgeirq_type; + irq_desc[base+n].chip = &msc_edgeirq_type; if (cpu_has_veic) MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT); else MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT | imp->im_lvl); break; case MSC01_IRQ_LEVEL: - irq_desc[base+n].handler = &msc_levelirq_type; + irq_desc[base+n].chip = &msc_levelirq_type; if (cpu_has_veic) MSCIC_WRITE(MSC01_IC_SUP+n*8, 0); else diff --git a/arch/mips/kernel/irq-mv6434x.c b/arch/mips/kernel/irq-mv6434x.c index 0613f1f36b1..f9c763a6554 100644 --- a/arch/mips/kernel/irq-mv6434x.c +++ b/arch/mips/kernel/irq-mv6434x.c @@ -155,7 +155,7 @@ void __init mv64340_irq_init(unsigned int base) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 2; - irq_desc[i].handler = &mv64340_irq_type; + irq_desc[i].chip = &mv64340_irq_type; } irq_base = base; diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c index 0b130c5ac5d..121da385a94 100644 --- a/arch/mips/kernel/irq-rm7000.c +++ b/arch/mips/kernel/irq-rm7000.c @@ -91,7 +91,7 @@ void __init rm7k_cpu_irq_init(int base) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].handler = &rm7k_irq_controller; + irq_desc[i].chip = &rm7k_irq_controller; } irq_base = base; diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c index 9b5f20c32ac..25109c103e4 100644 --- a/arch/mips/kernel/irq-rm9000.c +++ b/arch/mips/kernel/irq-rm9000.c @@ -139,11 +139,11 @@ void __init rm9k_cpu_irq_init(int base) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].handler = &rm9k_irq_controller; + irq_desc[i].chip = &rm9k_irq_controller; } rm9000_perfcount_irq = base + 1; - irq_desc[rm9000_perfcount_irq].handler = &rm9k_perfcounter_irq; + irq_desc[rm9000_perfcount_irq].chip = &rm9k_perfcounter_irq; irq_base = base; } diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index 3dce742e716..5c9dcd5eed5 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -95,7 +95,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -137,7 +137,7 @@ void __init init_IRQ(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].handler = &no_irq_type; + irq_desc[i].chip = &no_irq_type; spin_lock_init(&irq_desc[i].lock); #ifdef CONFIG_MIPS_MT_SMTC irq_hwmask[i] = 0; diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c index 5db67e31ec1..0e455a8ad86 100644 --- a/arch/mips/kernel/irq_cpu.c +++ b/arch/mips/kernel/irq_cpu.c @@ -167,14 +167,14 @@ void __init mips_cpu_irq_init(int irq_base) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].handler = &mips_mt_cpu_irq_controller; + irq_desc[i].chip = &mips_mt_cpu_irq_controller; } for (i = irq_base + 2; i < irq_base + 8; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].handler = &mips_cpu_irq_controller; + irq_desc[i].chip = &mips_cpu_irq_controller; } mips_cpu_irq_base = irq_base; diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 298f82fe844..9096a5ea422 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -446,7 +446,7 @@ static int __init topology_init(void) int ret; for_each_present_cpu(cpu) { - ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu, NULL); + ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu); if (ret) printk(KERN_WARNING "topology_init: register_cpu %d " "failed (%d)\n", cpu, ret); diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 2e8e52c135e..70cf09afdf5 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -367,7 +367,7 @@ void mipsmt_prepare_cpus(void) dvpe(); dmt(); - freeIPIq.lock = SPIN_LOCK_UNLOCKED; + spin_lock_init(&freeIPIq.lock); /* * We probably don't have as many VPEs as we do SMP "CPUs", @@ -375,7 +375,7 @@ void mipsmt_prepare_cpus(void) */ for (i=0; i<NR_CPUS; i++) { IPIQ[i].head = IPIQ[i].tail = NULL; - IPIQ[i].lock = SPIN_LOCK_UNLOCKED; + spin_lock_init(&IPIQ[i].lock); IPIQ[i].depth = 0; ipi_timer_latch[i] = 0; } diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c index 2d3472b21eb..9316a024a81 100644 --- a/arch/mips/lasat/interrupt.c +++ b/arch/mips/lasat/interrupt.c @@ -156,6 +156,6 @@ void __init arch_init_irq(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; - irq_desc[i].handler = &lasat_irq_type; + irq_desc[i].chip = &lasat_irq_type; } } diff --git a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c index db53950b7cf..9dd6b892558 100644 --- a/arch/mips/mips-boards/atlas/atlas_int.c +++ b/arch/mips/mips-boards/atlas/atlas_int.c @@ -215,7 +215,7 @@ void __init arch_init_irq(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; - irq_desc[i].handler = &atlas_irq_type; + irq_desc[i].chip = &atlas_irq_type; spin_lock_init(&irq_desc[i].lock); } } diff --git a/arch/mips/momentum/ocelot_c/cpci-irq.c b/arch/mips/momentum/ocelot_c/cpci-irq.c index bd885785e2f..31d179c4673 100644 --- a/arch/mips/momentum/ocelot_c/cpci-irq.c +++ b/arch/mips/momentum/ocelot_c/cpci-irq.c @@ -147,6 +147,6 @@ void cpci_irq_init(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 2; - irq_desc[i].handler = &cpci_irq_type; + irq_desc[i].chip = &cpci_irq_type; } } diff --git a/arch/mips/momentum/ocelot_c/uart-irq.c b/arch/mips/momentum/ocelot_c/uart-irq.c index 755bde5146b..852265026fd 100644 --- a/arch/mips/momentum/ocelot_c/uart-irq.c +++ b/arch/mips/momentum/ocelot_c/uart-irq.c @@ -137,10 +137,10 @@ void uart_irq_init(void) irq_desc[80].status = IRQ_DISABLED; irq_desc[80].action = 0; irq_desc[80].depth = 2; - irq_desc[80].handler = &uart_irq_type; + irq_desc[80].chip = &uart_irq_type; irq_desc[81].status = IRQ_DISABLED; irq_desc[81].action = 0; irq_desc[81].depth = 2; - irq_desc[81].handler = &uart_irq_type; + irq_desc[81].chip = &uart_irq_type; } diff --git a/arch/mips/momentum/ocelot_g/gt-irq.c b/arch/mips/momentum/ocelot_g/gt-irq.c index e5eceed1bef..8bd9b844fa9 100644 --- a/arch/mips/momentum/ocelot_g/gt-irq.c +++ b/arch/mips/momentum/ocelot_g/gt-irq.c @@ -59,7 +59,7 @@ void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr) * bit_num - Indicates which bit number in the cause register * * Outputs : - * 1 if succesful, 0 if failure + * 1 if successful, 0 if failure */ int enable_galileo_irq(int int_cause, int bit_num) { @@ -83,7 +83,7 @@ int enable_galileo_irq(int int_cause, int bit_num) * bit_num - Indicates which bit number in the cause register * * Outputs : - * 1 if succesful, 0 if failure + * 1 if successful, 0 if failure */ int disable_galileo_irq(int int_cause, int bit_num) { diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c index c31e4cff64e..65eb55400d7 100644 --- a/arch/mips/oprofile/common.c +++ b/arch/mips/oprofile/common.c @@ -38,7 +38,7 @@ static int op_mips_create_files(struct super_block * sb, struct dentry * root) for (i = 0; i < model->num_counters; ++i) { struct dentry *dir; - char buf[3]; + char buf[4]; snprintf(buf, sizeof buf, "%d", i); dir = oprofilefs_mkdir(sb, root, buf); diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 4dfce154d4a..ba66f8c9bd4 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -51,11 +51,11 @@ unsigned long PCIBIOS_MIN_MEM = 0; */ void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; struct pci_controller *hose = dev->sysdata; - unsigned long start = res->start; + resource_size_t start = res->start; if (res->flags & IORESOURCE_IO) { /* Make sure we start at our min on all hoses */ diff --git a/arch/mips/philips/pnx8550/common/int.c b/arch/mips/philips/pnx8550/common/int.c index 39ee6314f62..8f18764a235 100644 --- a/arch/mips/philips/pnx8550/common/int.c +++ b/arch/mips/philips/pnx8550/common/int.c @@ -236,7 +236,7 @@ void __init arch_init_irq(void) int configPR; for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) { - irq_desc[i].handler = &level_irq_type; + irq_desc[i].chip = &level_irq_type; pnx8550_ack(i); /* mask the irq just in case */ } @@ -273,7 +273,7 @@ void __init arch_init_irq(void) /* mask/priority is still 0 so we will not get any * interrupts until it is unmasked */ - irq_desc[i].handler = &level_irq_type; + irq_desc[i].chip = &level_irq_type; } /* Priority level 0 */ @@ -282,12 +282,12 @@ void __init arch_init_irq(void) /* Set int vector table address */ PNX8550_GIC_VECTOR_0 = PNX8550_GIC_VECTOR_1 = 0; - irq_desc[MIPS_CPU_GIC_IRQ].handler = &level_irq_type; + irq_desc[MIPS_CPU_GIC_IRQ].chip = &level_irq_type; setup_irq(MIPS_CPU_GIC_IRQ, &gic_action); /* init of Timer interrupts */ for (i = PNX8550_INT_TIMER_MIN; i <= PNX8550_INT_TIMER_MAX; i++) { - irq_desc[i].handler = &level_irq_type; + irq_desc[i].chip = &level_irq_type; } /* Stop Timer 1-3 */ @@ -295,7 +295,7 @@ void __init arch_init_irq(void) configPR |= 0x00000038; write_c0_config7(configPR); - irq_desc[MIPS_CPU_TIMER_IRQ].handler = &level_irq_type; + irq_desc[MIPS_CPU_TIMER_IRQ].chip = &level_irq_type; setup_irq(MIPS_CPU_TIMER_IRQ, &timer_action); } diff --git a/arch/mips/pmc-sierra/yosemite/ht.c b/arch/mips/pmc-sierra/yosemite/ht.c index 54b65a80abf..fb523ebcafa 100644 --- a/arch/mips/pmc-sierra/yosemite/ht.c +++ b/arch/mips/pmc-sierra/yosemite/ht.c @@ -383,12 +383,12 @@ void pcibios_update_resource(struct pci_dev *dev, struct resource *root, void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; + resource_size_t start = res->start; /* We need to avoid collisions with `mirrored' VGA ports and other strange ISA hardware, so we always want the diff --git a/arch/mips/sgi-ip22/ip22-eisa.c b/arch/mips/sgi-ip22/ip22-eisa.c index b19820110aa..989167b49ce 100644 --- a/arch/mips/sgi-ip22/ip22-eisa.c +++ b/arch/mips/sgi-ip22/ip22-eisa.c @@ -279,9 +279,9 @@ int __init ip22_eisa_init(void) irq_desc[i].action = 0; irq_desc[i].depth = 1; if (i < (SGINT_EISA + 8)) - irq_desc[i].handler = &ip22_eisa1_irq_type; + irq_desc[i].chip = &ip22_eisa1_irq_type; else - irq_desc[i].handler = &ip22_eisa2_irq_type; + irq_desc[i].chip = &ip22_eisa2_irq_type; } /* Cannot use request_irq because of kmalloc not being ready at such diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c index fc6a7e2b189..18906af6969 100644 --- a/arch/mips/sgi-ip22/ip22-int.c +++ b/arch/mips/sgi-ip22/ip22-int.c @@ -436,7 +436,7 @@ void __init arch_init_irq(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; - irq_desc[i].handler = handler; + irq_desc[i].chip = handler; } /* vector handler. this register the IRQ as non-sharable */ diff --git a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c index a9c58e067b5..8134220ed60 100644 --- a/arch/mips/sgi-ip22/ip22-reset.c +++ b/arch/mips/sgi-ip22/ip22-reset.c @@ -34,7 +34,7 @@ #define POWERDOWN_TIMEOUT 120 /* - * Blink frequency during reboot grace period and when paniced. + * Blink frequency during reboot grace period and when panicked. */ #define POWERDOWN_FREQ (HZ / 4) #define PANIC_FREQ (HZ / 8) diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index 0b61a39ce2b..869566c360a 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c @@ -386,7 +386,7 @@ void __devinit register_bridge_irq(unsigned int irq) irq_desc[irq].status = IRQ_DISABLED; irq_desc[irq].action = 0; irq_desc[irq].depth = 1; - irq_desc[irq].handler = &bridge_irq_type; + irq_desc[irq].chip = &bridge_irq_type; } int __devinit request_bridge_irq(struct bridge_controller *bc) diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index 8ba08047d16..00b94aaf637 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c @@ -591,7 +591,7 @@ void __init arch_init_irq(void) irq_desc[irq].status = IRQ_DISABLED; irq_desc[irq].action = 0; irq_desc[irq].depth = 0; - irq_desc[irq].handler = controller; + irq_desc[irq].chip = controller; } setup_irq(CRIME_MEMERR_IRQ, &memerr_irq); setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq); diff --git a/arch/mips/sgi-ip32/ip32-reset.c b/arch/mips/sgi-ip32/ip32-reset.c index ab9d9cef089..79ddb460565 100644 --- a/arch/mips/sgi-ip32/ip32-reset.c +++ b/arch/mips/sgi-ip32/ip32-reset.c @@ -28,13 +28,13 @@ #define POWERDOWN_TIMEOUT 120 /* - * Blink frequency during reboot grace period and when paniced. + * Blink frequency during reboot grace period and when panicked. */ #define POWERDOWN_FREQ (HZ / 4) #define PANIC_FREQ (HZ / 8) static struct timer_list power_timer, blink_timer, debounce_timer; -static int has_paniced, shuting_down; +static int has_panicked, shuting_down; static void ip32_machine_restart(char *command) __attribute__((noreturn)); static void ip32_machine_halt(void) __attribute__((noreturn)); @@ -109,7 +109,7 @@ static void debounce(unsigned long data) } CMOS_WRITE(reg_a & ~DS_REGA_DV0, RTC_REG_A); - if (has_paniced) + if (has_panicked) ip32_machine_restart(NULL); enable_irq(MACEISA_RTC_IRQ); @@ -117,7 +117,7 @@ static void debounce(unsigned long data) static inline void ip32_power_button(void) { - if (has_paniced) + if (has_panicked) return; if (shuting_down || kill_proc(1, SIGINT, 1)) { @@ -161,9 +161,9 @@ static int panic_event(struct notifier_block *this, unsigned long event, { unsigned long led; - if (has_paniced) + if (has_panicked) return NOTIFY_DONE; - has_paniced = 1; + has_panicked = 1; /* turn off the green LED */ led = mace->perif.ctrl.misc | MACEISA_LED_GREEN; diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c index e61760b14d9..610df40cb82 100644 --- a/arch/mips/sibyte/bcm1480/irq.c +++ b/arch/mips/sibyte/bcm1480/irq.c @@ -276,10 +276,10 @@ void __init init_bcm1480_irqs(void) irq_desc[i].action = 0; irq_desc[i].depth = 1; if (i < BCM1480_NR_IRQS) { - irq_desc[i].handler = &bcm1480_irq_type; + irq_desc[i].chip = &bcm1480_irq_type; bcm1480_irq_owner[i] = 0; } else { - irq_desc[i].handler = &no_irq_type; + irq_desc[i].chip = &no_irq_type; } } } diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c index f853c32f60a..fcc61940f1f 100644 --- a/arch/mips/sibyte/sb1250/irq.c +++ b/arch/mips/sibyte/sb1250/irq.c @@ -246,10 +246,10 @@ void __init init_sb1250_irqs(void) irq_desc[i].action = 0; irq_desc[i].depth = 1; if (i < SB1250_NR_IRQS) { - irq_desc[i].handler = &sb1250_irq_type; + irq_desc[i].chip = &sb1250_irq_type; sb1250_irq_owner[i] = 0; } else { - irq_desc[i].handler = &no_irq_type; + irq_desc[i].chip = &no_irq_type; } } } diff --git a/arch/mips/sni/irq.c b/arch/mips/sni/irq.c index 7365b4853dd..c19e158ec40 100644 --- a/arch/mips/sni/irq.c +++ b/arch/mips/sni/irq.c @@ -203,7 +203,7 @@ void __init arch_init_irq(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; - irq_desc[i].handler = &pciasic_irq_type; + irq_desc[i].chip = &pciasic_irq_type; } change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ2|IE_IRQ3|IE_IRQ4); diff --git a/arch/mips/tx4927/common/tx4927_irq.c b/arch/mips/tx4927/common/tx4927_irq.c index 8ca68015cf4..a42be00483e 100644 --- a/arch/mips/tx4927/common/tx4927_irq.c +++ b/arch/mips/tx4927/common/tx4927_irq.c @@ -227,7 +227,7 @@ static void __init tx4927_irq_cp0_init(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; - irq_desc[i].handler = &tx4927_irq_cp0_type; + irq_desc[i].chip = &tx4927_irq_cp0_type; } return; @@ -435,7 +435,7 @@ static void __init tx4927_irq_pic_init(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 2; - irq_desc[i].handler = &tx4927_irq_pic_type; + irq_desc[i].chip = &tx4927_irq_pic_type; } setup_irq(TX4927_IRQ_NEST_PIC_ON_CP0, &tx4927_irq_pic_action); diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c index aee07ff2212..c67978b6dae 100644 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c @@ -368,7 +368,7 @@ static void __init toshiba_rbtx4927_irq_ioc_init(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 3; - irq_desc[i].handler = &toshiba_rbtx4927_irq_ioc_type; + irq_desc[i].chip = &toshiba_rbtx4927_irq_ioc_type; } setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC, @@ -526,7 +526,7 @@ static void __init toshiba_rbtx4927_irq_isa_init(void) irq_desc[i].action = 0; irq_desc[i].depth = ((i < TOSHIBA_RBTX4927_IRQ_ISA_MID) ? (4) : (5)); - irq_desc[i].handler = &toshiba_rbtx4927_irq_isa_type; + irq_desc[i].chip = &toshiba_rbtx4927_irq_isa_type; } setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC, @@ -692,13 +692,13 @@ void toshiba_rbtx4927_irq_dump(char *key) { u32 i, j = 0; for (i = 0; i < NR_IRQS; i++) { - if (strcmp(irq_desc[i].handler->typename, "none") + if (strcmp(irq_desc[i].chip->typename, "none") == 0) continue; if ((i >= 1) - && (irq_desc[i - 1].handler->typename == - irq_desc[i].handler->typename)) { + && (irq_desc[i - 1].chip->typename == + irq_desc[i].chip->typename)) { j++; } else { j = 0; @@ -707,12 +707,12 @@ void toshiba_rbtx4927_irq_dump(char *key) (TOSHIBA_RBTX4927_IRQ_INFO, "%s irq=0x%02x/%3d s=0x%08x h=0x%08x a=0x%08x ah=0x%08x d=%1d n=%s/%02d\n", key, i, i, irq_desc[i].status, - (u32) irq_desc[i].handler, + (u32) irq_desc[i].chip, (u32) irq_desc[i].action, (u32) (irq_desc[i].action ? irq_desc[i]. action->handler : 0), irq_desc[i].depth, - irq_desc[i].handler->typename, j); + irq_desc[i].chip->typename, j); } } #endif diff --git a/arch/mips/tx4938/common/irq.c b/arch/mips/tx4938/common/irq.c index 873805178d8..0b2f8c84921 100644 --- a/arch/mips/tx4938/common/irq.c +++ b/arch/mips/tx4938/common/irq.c @@ -102,7 +102,7 @@ tx4938_irq_cp0_init(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; - irq_desc[i].handler = &tx4938_irq_cp0_type; + irq_desc[i].chip = &tx4938_irq_cp0_type; } return; @@ -306,7 +306,7 @@ tx4938_irq_pic_init(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 2; - irq_desc[i].handler = &tx4938_irq_pic_type; + irq_desc[i].chip = &tx4938_irq_pic_type; } setup_irq(TX4938_IRQ_NEST_PIC_ON_CP0, &tx4938_irq_pic_action); diff --git a/arch/mips/tx4938/toshiba_rbtx4938/irq.c b/arch/mips/tx4938/toshiba_rbtx4938/irq.c index 9cd9c0fe226..3b8245dc5bd 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/irq.c +++ b/arch/mips/tx4938/toshiba_rbtx4938/irq.c @@ -146,7 +146,7 @@ toshiba_rbtx4938_irq_ioc_init(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 3; - irq_desc[i].handler = &toshiba_rbtx4938_irq_ioc_type; + irq_desc[i].chip = &toshiba_rbtx4938_irq_ioc_type; } setup_irq(RBTX4938_IRQ_IOCINT, diff --git a/arch/mips/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c index 07ae19cf0c2..b9323302cc4 100644 --- a/arch/mips/vr41xx/common/icu.c +++ b/arch/mips/vr41xx/common/icu.c @@ -722,10 +722,10 @@ static int __init vr41xx_icu_init(void) icu2_write(MGIUINTHREG, 0xffff); for (i = SYSINT1_IRQ_BASE; i <= SYSINT1_IRQ_LAST; i++) - irq_desc[i].handler = &sysint1_irq_type; + irq_desc[i].chip = &sysint1_irq_type; for (i = SYSINT2_IRQ_BASE; i <= SYSINT2_IRQ_LAST; i++) - irq_desc[i].handler = &sysint2_irq_type; + irq_desc[i].chip = &sysint2_irq_type; cascade_irq(INT0_IRQ, icu_get_irq); cascade_irq(INT1_IRQ, icu_get_irq); diff --git a/arch/mips/vr41xx/common/irq.c b/arch/mips/vr41xx/common/irq.c index 86796bb63c3..66aa50802de 100644 --- a/arch/mips/vr41xx/common/irq.c +++ b/arch/mips/vr41xx/common/irq.c @@ -73,13 +73,13 @@ static void irq_dispatch(unsigned int irq, struct pt_regs *regs) if (cascade->get_irq != NULL) { unsigned int source_irq = irq; desc = irq_desc + source_irq; - desc->handler->ack(source_irq); + desc->chip->ack(source_irq); irq = cascade->get_irq(irq, regs); if (irq < 0) atomic_inc(&irq_err_count); else irq_dispatch(irq, regs); - desc->handler->end(source_irq); + desc->chip->end(source_irq); } else do_IRQ(irq, regs); } diff --git a/arch/mips/vr41xx/common/vrc4173.c b/arch/mips/vr41xx/common/vrc4173.c index 3e31f8193d2..2d287b8893d 100644 --- a/arch/mips/vr41xx/common/vrc4173.c +++ b/arch/mips/vr41xx/common/vrc4173.c @@ -483,7 +483,7 @@ static inline int vrc4173_icu_init(int cascade_irq) vr41xx_set_irq_level(GIU_IRQ_TO_PIN(cascade_irq), LEVEL_LOW); for (i = VRC4173_IRQ_BASE; i <= VRC4173_IRQ_LAST; i++) - irq_desc[i].handler = &vrc4173_irq_type; + irq_desc[i].chip = &vrc4173_irq_type; return 0; } diff --git a/arch/mips/vr41xx/nec-cmbvr4133/irq.c b/arch/mips/vr41xx/nec-cmbvr4133/irq.c index 31db6b61a39..7b2511ca0a6 100644 --- a/arch/mips/vr41xx/nec-cmbvr4133/irq.c +++ b/arch/mips/vr41xx/nec-cmbvr4133/irq.c @@ -104,7 +104,7 @@ void __init rockhopper_init_irq(void) } for (i = I8259_IRQ_BASE; i <= I8259_IRQ_LAST; i++) - irq_desc[i].handler = &i8259_irq_type; + irq_desc[i].chip = &i8259_irq_type; setup_irq(I8259_SLAVE_IRQ, &i8259_slave_cascade); diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 910fb3afc0b..6dd0ea8f88e 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -51,6 +51,10 @@ config GENERIC_HARDIRQS config GENERIC_IRQ_PROBE def_bool y +config IRQ_PER_CPU + bool + default y + # unless you want to implement ACPI on PA-RISC ... ;-) config PM bool diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index 197936d9359..82fe6ba2972 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -94,7 +94,7 @@ int cpu_check_affinity(unsigned int irq, cpumask_t *dest) if (irq == TIMER_IRQ || irq == IPI_IRQ) { /* Bad linux design decision. The mask has already * been set; we must reset it */ - irq_affinity[irq] = CPU_MASK_ALL; + irq_desc[irq].affinity = CPU_MASK_ALL; return -EINVAL; } @@ -110,7 +110,7 @@ static void cpu_set_affinity_irq(unsigned int irq, cpumask_t dest) if (cpu_check_affinity(irq, &dest)) return; - irq_affinity[irq] = dest; + irq_desc[irq].affinity = dest; } #endif @@ -125,6 +125,10 @@ static struct hw_interrupt_type cpu_interrupt_type = { #ifdef CONFIG_SMP .set_affinity = cpu_set_affinity_irq, #endif + /* XXX: Needs to be written. We managed without it so far, but + * we really ought to write it. + */ + .retrigger = NULL, }; int show_interrupts(struct seq_file *p, void *v) @@ -158,7 +162,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_printf(p, "%10u ", kstat_irqs(i)); #endif - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); #ifndef PARISC_IRQ_CR16_COUNTS seq_printf(p, " %s", action->name); @@ -210,12 +214,12 @@ int cpu_claim_irq(unsigned int irq, struct hw_interrupt_type *type, void *data) { if (irq_desc[irq].action) return -EBUSY; - if (irq_desc[irq].handler != &cpu_interrupt_type) + if (irq_desc[irq].chip != &cpu_interrupt_type) return -EBUSY; if (type) { - irq_desc[irq].handler = type; - irq_desc[irq].handler_data = data; + irq_desc[irq].chip = type; + irq_desc[irq].chip_data = data; cpu_interrupt_type.enable(irq); } return 0; @@ -265,7 +269,7 @@ int txn_alloc_irq(unsigned int bits_wide) unsigned long txn_affinity_addr(unsigned int irq, int cpu) { #ifdef CONFIG_SMP - irq_affinity[irq] = cpumask_of_cpu(cpu); + irq_desc[irq].affinity = cpumask_of_cpu(cpu); #endif return cpu_data[cpu].txn_addr; @@ -326,7 +330,7 @@ void do_cpu_irq_mask(struct pt_regs *regs) /* Work our way from MSb to LSb...same order we alloc EIRs */ for (irq = TIMER_IRQ; eirr_val && bit; bit>>=1, irq++) { #ifdef CONFIG_SMP - cpumask_t dest = irq_affinity[irq]; + cpumask_t dest = irq_desc[irq].affinity; #endif if (!(bit & eirr_val)) continue; @@ -378,7 +382,7 @@ static void claim_cpu_irqs(void) { int i; for (i = CPU_IRQ_BASE; i <= CPU_IRQ_MAX; i++) { - irq_desc[i].handler = &cpu_interrupt_type; + irq_desc[i].chip = &cpu_interrupt_type; } irq_desc[TIMER_IRQ].action = &timer_action; @@ -404,13 +408,6 @@ void __init init_IRQ(void) } -void hw_resend_irq(struct hw_interrupt_type *type, unsigned int irq) -{ - /* XXX: Needs to be written. We managed without it so far, but - * we really ought to write it. - */ -} - void ack_bad_irq(unsigned int irq) { printk("unexpected IRQ %d\n", irq); diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index 79c7db2705f..7d6967ee367 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c @@ -289,7 +289,7 @@ EXPORT_SYMBOL(pcibios_bus_to_resource); * than res->start. */ void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long alignment) + resource_size_t size, resource_size_t alignment) { unsigned long mask, align; diff --git a/arch/parisc/kernel/topology.c b/arch/parisc/kernel/topology.c index 3ba040050e4..068b20d822e 100644 --- a/arch/parisc/kernel/topology.c +++ b/arch/parisc/kernel/topology.c @@ -26,11 +26,10 @@ static struct cpu cpu_devices[NR_CPUS] __read_mostly; static int __init topology_init(void) { - struct node *parent = NULL; int num; for_each_present_cpu(num) { - register_cpu(&cpu_devices[num], num, parent); + register_cpu(&cpu_devices[num], num); } return 0; } diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index e922a88b2ba..d43e4521abf 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -30,6 +30,10 @@ config GENERIC_HARDIRQS bool default y +config IRQ_PER_CPU + bool + default y + config RWSEM_GENERIC_SPINLOCK bool @@ -618,6 +622,9 @@ config HOTPLUG_CPU Say N if you are unsure. +config ARCH_ENABLE_MEMORY_HOTPLUG + def_bool y + config KEXEC bool "kexec system call (EXPERIMENTAL)" depends on PPC_MULTIPLATFORM && EXPERIMENTAL diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index dbcb85994f4..22ceba844bf 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c @@ -179,7 +179,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs) /* * This function is only called after the system - * has paniced or is otherwise in a critical state. + * has panicked or is otherwise in a critical state. * The minimum amount of code to allow a kexec'd kernel * to run successfully needs to happen here. * @@ -190,13 +190,13 @@ void default_machine_crash_shutdown(struct pt_regs *regs) local_irq_disable(); for_each_irq(irq) { - struct irq_desc *desc = irq_descp(irq); + struct irq_desc *desc = irq_desc + irq; if (desc->status & IRQ_INPROGRESS) - desc->handler->end(irq); + desc->chip->end(irq); if (!(desc->status & IRQ_DISABLED)) - desc->handler->disable(irq); + desc->chip->disable(irq); } if (ppc_md.kexec_cpu_down) diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 40d4c14fde8..24f6050aa4a 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -120,8 +120,8 @@ int show_interrupts(struct seq_file *p, void *v) #else seq_printf(p, "%10u ", kstat_irqs(i)); #endif /* CONFIG_SMP */ - if (desc->handler) - seq_printf(p, " %s ", desc->handler->typename); + if (desc->chip) + seq_printf(p, " %s ", desc->chip->typename); else seq_puts(p, " None "); seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge "); @@ -164,13 +164,13 @@ void fixup_irqs(cpumask_t map) if (irq_desc[irq].status & IRQ_PER_CPU) continue; - cpus_and(mask, irq_affinity[irq], map); + cpus_and(mask, irq_desc[irq].affinity, map); if (any_online_cpu(mask) == NR_CPUS) { printk("Breaking affinity for irq %i\n", irq); mask = map; } - if (irq_desc[irq].handler->set_affinity) - irq_desc[irq].handler->set_affinity(irq, mask); + if (irq_desc[irq].chip->set_affinity) + irq_desc[irq].chip->set_affinity(irq, mask); else if (irq_desc[irq].action && !(warned++)) printk("Cannot set affinity for irq %i\n", irq); } diff --git a/arch/powerpc/kernel/machine_kexec_32.c b/arch/powerpc/kernel/machine_kexec_32.c index 443606134df..cbaa3419679 100644 --- a/arch/powerpc/kernel/machine_kexec_32.c +++ b/arch/powerpc/kernel/machine_kexec_32.c @@ -30,8 +30,8 @@ typedef NORET_TYPE void (*relocate_new_kernel_t)( */ void default_machine_kexec(struct kimage *image) { - const extern unsigned char relocate_new_kernel[]; - const extern unsigned int relocate_new_kernel_size; + extern const unsigned char relocate_new_kernel[]; + extern const unsigned int relocate_new_kernel_size; unsigned long page_list; unsigned long reboot_code_buffer, reboot_code_buffer_phys; relocate_new_kernel_t rnk; diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index b5431ccf114..8474355a1a4 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c @@ -99,7 +99,7 @@ pcibios_fixup_resources(struct pci_dev *dev) if (!res->flags) continue; if (res->end == 0xffffffff) { - DBG("PCI:%s Resource %d [%08lx-%08lx] is unassigned\n", + DBG("PCI:%s Resource %d [%016llx-%016llx] is unassigned\n", pci_name(dev), i, res->start, res->end); res->end -= res->start; res->start = 0; @@ -117,7 +117,7 @@ pcibios_fixup_resources(struct pci_dev *dev) res->start += offset; res->end += offset; #ifdef DEBUG - printk("Fixup res %d (%lx) of dev %s: %lx -> %lx\n", + printk("Fixup res %d (%lx) of dev %s: %llx -> %llx\n", i, res->flags, pci_name(dev), res->start - offset, res->start); #endif @@ -173,18 +173,18 @@ EXPORT_SYMBOL(pcibios_bus_to_resource); * but we want to try to avoid allocating at 0x2900-0x2bff * which might have be mirrored at 0x0100-0x03ff.. */ -void pcibios_align_resource(void *data, struct resource *res, unsigned long size, - unsigned long align) +void pcibios_align_resource(void *data, struct resource *res, + resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; + resource_size_t start = res->start; if (size > 0x100) { printk(KERN_ERR "PCI: I/O Region %s/%d too large" - " (%ld bytes)\n", pci_name(dev), - dev->resource - res, size); + " (%lld bytes)\n", pci_name(dev), + dev->resource - res, (unsigned long long)size); } if (start & 0x300) { @@ -255,8 +255,8 @@ pcibios_allocate_bus_resources(struct list_head *bus_list) } } - DBG("PCI: bridge rsrc %lx..%lx (%lx), parent %p\n", - res->start, res->end, res->flags, pr); + DBG("PCI: bridge rsrc %llx..%llx (%lx), parent %p\n", + res->start, res->end, res->flags, pr); if (pr) { if (request_resource(pr, res) == 0) continue; @@ -306,7 +306,7 @@ reparent_resources(struct resource *parent, struct resource *res) *pp = NULL; for (p = res->child; p != NULL; p = p->sibling) { p->parent = res; - DBG(KERN_INFO "PCI: reparented %s [%lx..%lx] under %s\n", + DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n", p->name, p->start, p->end, res->name); } return 0; @@ -362,13 +362,14 @@ pci_relocate_bridge_resource(struct pci_bus *bus, int i) try = conflict->start - 1; } if (request_resource(pr, res)) { - DBG(KERN_ERR "PCI: huh? couldn't move to %lx..%lx\n", + DBG(KERN_ERR "PCI: huh? couldn't move to %llx..%llx\n", res->start, res->end); return -1; /* "can't happen" */ } update_bridge_base(bus, i); - printk(KERN_INFO "PCI: bridge %d resource %d moved to %lx..%lx\n", - bus->number, i, res->start, res->end); + printk(KERN_INFO "PCI: bridge %d resource %d moved to %llx..%llx\n", + bus->number, i, (unsigned long long)res->start, + (unsigned long long)res->end); return 0; } @@ -479,14 +480,14 @@ static inline void alloc_resource(struct pci_dev *dev, int idx) { struct resource *pr, *r = &dev->resource[idx]; - DBG("PCI:%s: Resource %d: %08lx-%08lx (f=%lx)\n", + DBG("PCI:%s: Resource %d: %016llx-%016llx (f=%lx)\n", pci_name(dev), idx, r->start, r->end, r->flags); pr = pci_find_parent_resource(dev, r); if (!pr || request_resource(pr, r) < 0) { printk(KERN_ERR "PCI: Cannot allocate resource region %d" " of device %s\n", idx, pci_name(dev)); if (pr) - DBG("PCI: parent is %p: %08lx-%08lx (f=%lx)\n", + DBG("PCI: parent is %p: %016llx-%016llx (f=%lx)\n", pr, pr->start, pr->end, pr->flags); /* We'll assign a new address later */ r->flags |= IORESOURCE_UNSET; @@ -956,7 +957,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose, res = &hose->io_resource; res->flags = IORESOURCE_IO; res->start = ranges[2]; - DBG("PCI: IO 0x%lx -> 0x%lx\n", + DBG("PCI: IO 0x%llx -> 0x%llx\n", res->start, res->start + size - 1); break; case 2: /* memory space */ @@ -978,7 +979,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose, if(ranges[0] & 0x40000000) res->flags |= IORESOURCE_PREFETCH; res->start = ranges[na+2]; - DBG("PCI: MEM[%d] 0x%lx -> 0x%lx\n", memno, + DBG("PCI: MEM[%d] 0x%llx -> 0x%llx\n", memno, res->start, res->start + size - 1); } break; @@ -1074,7 +1075,7 @@ do_update_p2p_io_resource(struct pci_bus *bus, int enable_vga) DBG("Remapping Bus %d, bridge: %s\n", bus->number, pci_name(bridge)); res.start -= ((unsigned long) hose->io_base_virt - isa_io_base); res.end -= ((unsigned long) hose->io_base_virt - isa_io_base); - DBG(" IO window: %08lx-%08lx\n", res.start, res.end); + DBG(" IO window: %016llx-%016llx\n", res.start, res.end); /* Set up the top and bottom of the PCI I/O segment for this bus. */ pci_read_config_dword(bridge, PCI_IO_BASE, &l); @@ -1223,8 +1224,8 @@ do_fixup_p2p_level(struct pci_bus *bus) continue; if ((r->flags & IORESOURCE_IO) == 0) continue; - DBG("Trying to allocate from %08lx, size %08lx from parent" - " res %d: %08lx -> %08lx\n", + DBG("Trying to allocate from %016llx, size %016llx from parent" + " res %d: %016llx -> %016llx\n", res->start, res->end, i, r->start, r->end); if (allocate_resource(r, res, res->end + 1, res->start, max, @@ -1574,8 +1575,8 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, else prot |= _PAGE_GUARDED; - printk("PCI map for %s:%lx, prot: %lx\n", pci_name(dev), rp->start, - prot); + printk("PCI map for %s:%llx, prot: %lx\n", pci_name(dev), + (unsigned long long)rp->start, prot); return __pgprot(prot); } @@ -1755,7 +1756,7 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) void pci_resource_to_user(const struct pci_dev *dev, int bar, const struct resource *rsrc, - u64 *start, u64 *end) + resource_size_t *start, resource_size_t *end) { struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); unsigned long offset = 0; diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 247937dd8b7..286aa52aae3 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -138,11 +138,11 @@ EXPORT_SYMBOL(pcibios_bus_to_resource); * which might have be mirrored at 0x0100-0x03ff.. */ void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; struct pci_controller *hose = pci_bus_to_host(dev->bus); - unsigned long start = res->start; + resource_size_t start = res->start; unsigned long alignto; if (res->flags & IORESOURCE_IO) { diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index e5a44812441..0932a62a1c9 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -215,7 +215,7 @@ int __init ppc_init(void) /* register CPU devices */ for_each_possible_cpu(i) - register_cpu(&cpu_devices[i], i, NULL); + register_cpu(&cpu_devices[i], i); /* call platform init */ if (ppc_md.init != NULL) { diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 5bc2585c803..4662b580efa 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -279,7 +279,7 @@ static void unregister_cpu_online(unsigned int cpu) } #endif /* CONFIG_HOTPLUG_CPU */ -static int sysfs_cpu_notify(struct notifier_block *self, +static int __devinit sysfs_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned int)(long)hcpu; @@ -297,30 +297,19 @@ static int sysfs_cpu_notify(struct notifier_block *self, return NOTIFY_OK; } -static struct notifier_block sysfs_cpu_nb = { +static struct notifier_block __devinitdata sysfs_cpu_nb = { .notifier_call = sysfs_cpu_notify, }; /* NUMA stuff */ #ifdef CONFIG_NUMA -static struct node node_devices[MAX_NUMNODES]; - static void register_nodes(void) { int i; - for (i = 0; i < MAX_NUMNODES; i++) { - if (node_online(i)) { - int p_node = parent_node(i); - struct node *parent = NULL; - - if (p_node != i) - parent = &node_devices[p_node]; - - register_node(&node_devices[i], i, parent); - } - } + for (i = 0; i < MAX_NUMNODES; i++) + register_one_node(i); } int sysfs_add_device_to_node(struct sys_device *dev, int nid) @@ -359,23 +348,13 @@ static SYSDEV_ATTR(physical_id, 0444, show_physical_id, NULL); static int __init topology_init(void) { int cpu; - struct node *parent = NULL; register_nodes(); - register_cpu_notifier(&sysfs_cpu_nb); for_each_possible_cpu(cpu) { struct cpu *c = &per_cpu(cpu_devices, cpu); -#ifdef CONFIG_NUMA - /* The node to which a cpu belongs can't be known - * until the cpu is made present. - */ - parent = NULL; - if (cpu_present(cpu)) - parent = &node_devices[cpu_to_node(cpu)]; -#endif /* * For now, we just see if the system supports making * the RTAS calls for CPU hotplug. But, there may be a @@ -387,7 +366,7 @@ static int __init topology_init(void) c->no_control = 1; if (cpu_online(cpu) || (c->no_control == 0)) { - register_cpu(c, cpu, parent); + register_cpu(c, cpu); sysdev_create_file(&c->sysdev, &attr_physical_id); } diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index d20907561f4..7dd5dab789a 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -102,7 +102,7 @@ EXPORT_SYMBOL(tb_ticks_per_sec); /* for cputime_t conversions */ u64 tb_to_xs; unsigned tb_to_us; -#define TICKLEN_SCALE (SHIFT_SCALE - 10) +#define TICKLEN_SCALE TICK_LENGTH_SHIFT u64 last_tick_len; /* units are ns / 2^TICKLEN_SCALE */ u64 ticklen_to_xs; /* 0.64 fraction */ diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index fdbba4206d5..a0a9e1e0061 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -40,6 +40,40 @@ #include <asm/kdebug.h> #include <asm/siginfo.h> +#ifdef CONFIG_KPROBES +ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); + +/* Hook to register for page fault notifications */ +int register_page_fault_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); +} + +int unregister_page_fault_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); +} + +static inline int notify_page_fault(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + struct die_args args = { + .regs = regs, + .str = str, + .err = err, + .trapnr = trap, + .signr = sig + }; + return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); +} +#else +static inline int notify_page_fault(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + return NOTIFY_DONE; +} +#endif + /* * Check whether the instruction at regs->nip is a store using * an update addressing form which will update r1. @@ -142,7 +176,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, is_write = error_code & ESR_DST; #endif /* CONFIG_4xx || CONFIG_BOOKE */ - if (notify_die(DIE_PAGE_FAULT, "page_fault", regs, error_code, + if (notify_page_fault(DIE_PAGE_FAULT, "page_fault", regs, error_code, 11, SIGSEGV) == NOTIFY_STOP) return 0; diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index 9e30f968c18..d454caada26 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -41,6 +41,7 @@ #include <linux/idr.h> #include <linux/nodemask.h> #include <linux/module.h> +#include <linux/poison.h> #include <asm/pgalloc.h> #include <asm/page.h> @@ -90,7 +91,7 @@ void free_initmem(void) addr = (unsigned long)__init_begin; for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) { - memset((void *)addr, 0xcc, PAGE_SIZE); + memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); ClearPageReserved(virt_to_page(addr)); init_page_count(virt_to_page(addr)); free_page(addr); diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 69f3b9a20be..089d939a0b3 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -114,15 +114,20 @@ void online_page(struct page *page) num_physpages++; } -int __devinit add_memory(u64 start, u64 size) +#ifdef CONFIG_NUMA +int memory_add_physaddr_to_nid(u64 start) +{ + return hot_add_scn_to_nid(start); +} +#endif + +int __devinit arch_add_memory(int nid, u64 start, u64 size) { struct pglist_data *pgdata; struct zone *zone; - int nid; unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; - nid = hot_add_scn_to_nid(start); pgdata = NODE_DATA(nid); start = (unsigned long)__va(start); diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index aa98cb3b59d..fbe23933f73 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -334,7 +334,7 @@ out: return nid; } -static int cpu_numa_callback(struct notifier_block *nfb, +static int __cpuinit cpu_numa_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { @@ -609,14 +609,15 @@ static void __init *careful_allocation(int nid, unsigned long size, return (void *)ret; } +static struct notifier_block __cpuinitdata ppc64_numa_nb = { + .notifier_call = cpu_numa_callback, + .priority = 1 /* Must run before sched domains notifier. */ +}; + void __init do_init_bootmem(void) { int nid; unsigned int i; - static struct notifier_block ppc64_numa_nb = { - .notifier_call = cpu_numa_callback, - .priority = 1 /* Must run before sched domains notifier. */ - }; min_low_pfn = 0; max_low_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT; diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c index 27ad56bd227..fd0bbbe7a4d 100644 --- a/arch/powerpc/oprofile/common.c +++ b/arch/powerpc/oprofile/common.c @@ -94,7 +94,7 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root) for (i = 0; i < model->num_counters; ++i) { struct dentry *dir; - char buf[3]; + char buf[4]; snprintf(buf, sizeof buf, "%d", i); dir = oprofilefs_mkdir(sb, root, buf); diff --git a/arch/powerpc/platforms/83xx/pci.c b/arch/powerpc/platforms/83xx/pci.c index 16f7d3b30e1..3baceb00fef 100644 --- a/arch/powerpc/platforms/83xx/pci.c +++ b/arch/powerpc/platforms/83xx/pci.c @@ -91,9 +91,10 @@ int __init add_bridge(struct device_node *dev) mpc83xx_pci2_busno = hose->first_busno; } - printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%08lx. " + printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%016llx. " "Firmware bus number: %d->%d\n", - rsrc.start, hose->first_busno, hose->last_busno); + (unsigned long long)rsrc.start, hose->first_busno, + hose->last_busno); DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", hose, hose->cfg_addr, hose->cfg_data); diff --git a/arch/powerpc/platforms/85xx/pci.c b/arch/powerpc/platforms/85xx/pci.c index bad290110ed..48c8849c07c 100644 --- a/arch/powerpc/platforms/85xx/pci.c +++ b/arch/powerpc/platforms/85xx/pci.c @@ -79,9 +79,10 @@ int __init add_bridge(struct device_node *dev) mpc85xx_pci2_busno = hose->first_busno; } - printk(KERN_INFO "Found MPC85xx PCI host bridge at 0x%08lx. " + printk(KERN_INFO "Found MPC85xx PCI host bridge at 0x%016llx. " "Firmware bus number: %d->%d\n", - rsrc.start, hose->first_busno, hose->last_busno); + (unsigned long long)rsrc.start, hose->first_busno, + hose->last_busno); DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", hose, hose->cfg_addr, hose->cfg_data); diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c index 1bbf822b4ef..7bff3cbc572 100644 --- a/arch/powerpc/platforms/cell/interrupt.c +++ b/arch/powerpc/platforms/cell/interrupt.c @@ -307,7 +307,7 @@ static void iic_request_ipi(int ipi, const char *name) irq = iic_ipi_to_irq(ipi); /* IPIs are marked SA_INTERRUPT as they must run with irqs * disabled */ - get_irq_desc(irq)->handler = &iic_pic; + get_irq_desc(irq)->chip = &iic_pic; get_irq_desc(irq)->status |= IRQ_PER_CPU; request_irq(irq, iic_ipi_action, SA_INTERRUPT, name, NULL); } @@ -330,7 +330,7 @@ static void iic_setup_spe_handlers(void) for (be=0; be < num_present_cpus() / 2; be++) { for (isrc = 0; isrc < IIC_CLASS_STRIDE * 3; isrc++) { int irq = IIC_NODE_STRIDE * be + IIC_SPE_OFFSET + isrc; - get_irq_desc(irq)->handler = &iic_pic; + get_irq_desc(irq)->chip = &iic_pic; } } } diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c index 55cbdd77a62..7c3a0b6d34f 100644 --- a/arch/powerpc/platforms/cell/spider-pic.c +++ b/arch/powerpc/platforms/cell/spider-pic.c @@ -162,7 +162,7 @@ void spider_init_IRQ_hardcoded(void) spider_pics[node] = ioremap(spiderpic, 0x800); for (n = 0; n < IIC_NUM_EXT; n++) { int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE; - get_irq_desc(irq)->handler = &spider_pic; + get_irq_desc(irq)->chip = &spider_pic; } /* do not mask any interrupts because of level */ @@ -217,7 +217,7 @@ void spider_init_IRQ(void) for (n = 0; n < IIC_NUM_EXT; n++) { int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE; - get_irq_desc(irq)->handler = &spider_pic; + get_irq_desc(irq)->chip = &spider_pic; } /* do not mask any interrupts because of level */ diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 80c02660e61..7854a380dce 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -1150,7 +1150,7 @@ static unsigned int spufs_mfc_poll(struct file *file,poll_table *wait) return mask; } -static int spufs_mfc_flush(struct file *file) +static int spufs_mfc_flush(struct file *file, fl_owner_t id) { struct spu_context *ctx = file->private_data; int ret; @@ -1176,7 +1176,7 @@ out: static int spufs_mfc_fsync(struct file *file, struct dentry *dentry, int datasync) { - return spufs_mfc_flush(file); + return spufs_mfc_flush(file, NULL); } static int spufs_mfc_fasync(int fd, struct file *file, int on) diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index b30e55dab83..a656d810a44 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c @@ -2100,7 +2100,7 @@ EXPORT_SYMBOL_GPL(spu_save); * @spu: pointer to SPU iomem structure. * * Perform harvest + restore, as we may not be coming - * from a previous succesful save operation, and the + * from a previous successful save operation, and the * hardware state is unknown. */ int spu_restore(struct spu_state *new, struct spu *spu) @@ -2203,7 +2203,7 @@ void spu_init_csa(struct spu_state *csa) memset(lscsa, 0, sizeof(struct spu_lscsa)); csa->lscsa = lscsa; - csa->register_lock = SPIN_LOCK_UNLOCKED; + spin_lock_init(&csa->register_lock); /* Set LS pages reserved to allow for user-space mapping. */ for (p = lscsa->ls; p < lscsa->ls + LS_SIZE; p += PAGE_SIZE) diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c index ac224876ce5..53515daf01b 100644 --- a/arch/powerpc/platforms/chrp/pci.c +++ b/arch/powerpc/platforms/chrp/pci.c @@ -143,7 +143,7 @@ hydra_init(void) if (np == NULL || of_address_to_resource(np, 0, &r)) return 0; Hydra = ioremap(r.start, r.end-r.start); - printk("Hydra Mac I/O at %lx\n", r.start); + printk("Hydra Mac I/O at %llx\n", (unsigned long long)r.start); printk("Hydra Feature_Control was %x", in_le32(&Hydra->Feature_Control)); out_le32(&Hydra->Feature_Control, (HYDRA_FC_SCC_CELL_EN | @@ -267,7 +267,7 @@ chrp_find_bridges(void) bus_range[0], bus_range[1]); printk(" controlled by %s", dev->type); if (!is_longtrail) - printk(" at %lx", r.start); + printk(" at %llx", (unsigned long long)r.start); printk("\n"); hose = pcibios_alloc_controller(); diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c index 62bbbcf5ded..33bb4aa0e1e 100644 --- a/arch/powerpc/platforms/iseries/irq.c +++ b/arch/powerpc/platforms/iseries/irq.c @@ -242,9 +242,9 @@ void __init iSeries_activate_IRQs() for_each_irq (irq) { irq_desc_t *desc = get_irq_desc(irq); - if (desc && desc->handler && desc->handler->startup) { + if (desc && desc->chip && desc->chip->startup) { spin_lock_irqsave(&desc->lock, flags); - desc->handler->startup(irq); + desc->chip->startup(irq); spin_unlock_irqrestore(&desc->lock, flags); } } @@ -324,7 +324,7 @@ int __init iSeries_allocate_IRQ(HvBusNumber bus, + function; virtirq = virt_irq_create_mapping(realirq); - irq_desc[virtirq].handler = &iSeries_IRQ_handler; + irq_desc[virtirq].chip = &iSeries_IRQ_handler; return virtirq; } diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c index 9a4efc0c3b2..f7170ff86da 100644 --- a/arch/powerpc/platforms/maple/pci.c +++ b/arch/powerpc/platforms/maple/pci.c @@ -376,9 +376,10 @@ static void __init maple_fixup_phb_resources(void) unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base; hose->io_resource.start += offset; hose->io_resource.end += offset; - printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n", + printk(KERN_INFO "PCI Host %d, io start: %llx; io end: %llx\n", hose->global_number, - hose->io_resource.start, hose->io_resource.end); + (unsigned long long)hose->io_resource.start, + (unsigned long long)hose->io_resource.end); } } diff --git a/arch/powerpc/platforms/powermac/backlight.c b/arch/powerpc/platforms/powermac/backlight.c index 498b042e183..c7a27eddca6 100644 --- a/arch/powerpc/platforms/powermac/backlight.c +++ b/arch/powerpc/platforms/powermac/backlight.c @@ -119,7 +119,14 @@ int pmac_backlight_set_legacy_brightness(int brightness) down(&pmac_backlight->sem); props = pmac_backlight->props; props->brightness = brightness * - props->max_brightness / OLD_BACKLIGHT_MAX; + (props->max_brightness + 1) / + (OLD_BACKLIGHT_MAX + 1); + + if (props->brightness > props->max_brightness) + props->brightness = props->max_brightness; + else if (props->brightness < 0) + props->brightness = 0; + props->update_status(pmac_backlight); up(&pmac_backlight->sem); @@ -140,8 +147,11 @@ int pmac_backlight_get_legacy_brightness() down(&pmac_backlight->sem); props = pmac_backlight->props; + result = props->brightness * - OLD_BACKLIGHT_MAX / props->max_brightness; + (OLD_BACKLIGHT_MAX + 1) / + (props->max_brightness + 1); + up(&pmac_backlight->sem); } mutex_unlock(&pmac_backlight_mutex); diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index 80035853467..d524a915aa8 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c @@ -939,9 +939,10 @@ static int __init add_bridge(struct device_node *dev) disp_name = "Chaos"; primary = 0; } - printk(KERN_INFO "Found %s PCI host bridge at 0x%08lx. " + printk(KERN_INFO "Found %s PCI host bridge at 0x%016llx. " "Firmware bus number: %d->%d\n", - disp_name, rsrc.start, hose->first_busno, hose->last_busno); + disp_name, (unsigned long long)rsrc.start, hose->first_busno, + hose->last_busno); #endif /* CONFIG_PPC32 */ DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c index 047f954a89e..93e7505debc 100644 --- a/arch/powerpc/platforms/powermac/pfunc_core.c +++ b/arch/powerpc/platforms/powermac/pfunc_core.c @@ -546,7 +546,7 @@ struct pmf_device { }; static LIST_HEAD(pmf_devices); -static spinlock_t pmf_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(pmf_lock); static DEFINE_MUTEX(pmf_irq_mutex); static void pmf_release_device(struct kref *kref) diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 18bf3011d1e..9f6189af6dd 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -446,7 +446,7 @@ static void __init pmac_pic_probe_oldstyle(void) /* Set the handler for the main PIC */ for ( i = 0; i < max_real_irqs ; i++ ) - irq_desc[i].handler = &pmac_pic; + irq_desc[i].chip = &pmac_pic; /* Get addresses of first controller if we have a node for it */ BUG_ON(of_address_to_resource(master, 0, &r)); @@ -493,7 +493,7 @@ static void __init pmac_pic_probe_oldstyle(void) /* Setup handlers for secondary controller and hook cascade irq*/ if (slave) { for ( i = max_real_irqs ; i < max_irqs ; i++ ) - irq_desc[i].handler = &gatwick_pic; + irq_desc[i].chip = &gatwick_pic; setup_irq(irq_cascade, &gatwick_cascade_action); } printk(KERN_INFO "irq: System has %d possible interrupts\n", max_irqs); diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c index 98c23aec85b..c37a8497c60 100644 --- a/arch/powerpc/platforms/pseries/eeh_cache.c +++ b/arch/powerpc/platforms/pseries/eeh_cache.c @@ -287,7 +287,7 @@ void pci_addr_cache_remove_device(struct pci_dev *dev) * find the pci device that corresponds to a given address. * This routine scans all pci busses to build the cache. * Must be run late in boot process, after the pci controllers - * have been scaned for devices (after all device resources are known). + * have been scanned for devices (after all device resources are known). */ void __init pci_addr_cache_build(void) { diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c index 8f2d12935b9..45ccc687e57 100644 --- a/arch/powerpc/platforms/pseries/eeh_event.c +++ b/arch/powerpc/platforms/pseries/eeh_event.c @@ -35,7 +35,7 @@ */ /* EEH event workqueue setup. */ -static spinlock_t eeh_eventlist_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(eeh_eventlist_lock); LIST_HEAD(eeh_eventlist); static void eeh_thread_launcher(void *); DECLARE_WORK(eeh_event_wq, eeh_thread_launcher, NULL); diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index b14f9b5c114..19c03dd4300 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c @@ -238,7 +238,7 @@ static int get_irq_server(unsigned int irq) { unsigned int server; /* For the moment only implement delivery to all cpus or one cpu */ - cpumask_t cpumask = irq_affinity[irq]; + cpumask_t cpumask = irq_desc[irq].affinity; cpumask_t tmp = CPU_MASK_NONE; if (!distribute_irqs) @@ -558,7 +558,7 @@ nextnode: } for (i = irq_offset_value(); i < NR_IRQS; ++i) - get_irq_desc(i)->handler = &xics_pic; + get_irq_desc(i)->chip = &xics_pic; xics_setup_cpu(); @@ -701,9 +701,9 @@ void xics_migrate_irqs_away(void) continue; /* We only need to migrate enabled IRQS */ - if (desc == NULL || desc->handler == NULL + if (desc == NULL || desc->chip == NULL || desc->action == NULL - || desc->handler->set_affinity == NULL) + || desc->chip->set_affinity == NULL) continue; spin_lock_irqsave(&desc->lock, flags); @@ -728,8 +728,8 @@ void xics_migrate_irqs_away(void) virq, cpu); /* Reset affinity to all cpus */ - desc->handler->set_affinity(virq, CPU_MASK_ALL); - irq_affinity[virq] = CPU_MASK_ALL; + desc->chip->set_affinity(virq, CPU_MASK_ALL); + irq_desc[irq].affinity = CPU_MASK_ALL; unlock: spin_unlock_irqrestore(&desc->lock, flags); } diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c index b7ac32fdd77..2bff30f6d63 100644 --- a/arch/powerpc/sysdev/i8259.c +++ b/arch/powerpc/sysdev/i8259.c @@ -208,7 +208,7 @@ void __init i8259_init(unsigned long intack_addr, int offset) spin_unlock_irqrestore(&i8259_lock, flags); for (i = 0; i < NUM_ISA_INTERRUPTS; ++i) - irq_desc[offset + i].handler = &i8259_pic; + irq_desc[offset + i].chip = &i8259_pic; /* reserve our resources */ setup_irq(offset + 2, &i8259_irqaction); diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c index 8f01e0f1d84..46801f5ec03 100644 --- a/arch/powerpc/sysdev/ipic.c +++ b/arch/powerpc/sysdev/ipic.c @@ -472,7 +472,7 @@ void __init ipic_init(phys_addr_t phys_addr, ipic_write(primary_ipic->regs, IPIC_SEMSR, temp); for (i = 0 ; i < NR_IPIC_INTS ; i++) { - irq_desc[i+irq_offset].handler = &ipic; + irq_desc[i+irq_offset].chip = &ipic; irq_desc[i+irq_offset].status = IRQ_LEVEL; } diff --git a/arch/powerpc/sysdev/mmio_nvram.c b/arch/powerpc/sysdev/mmio_nvram.c index 74e0d31a355..615350d46b5 100644 --- a/arch/powerpc/sysdev/mmio_nvram.c +++ b/arch/powerpc/sysdev/mmio_nvram.c @@ -32,7 +32,7 @@ static void __iomem *mmio_nvram_start; static long mmio_nvram_len; -static spinlock_t mmio_nvram_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(mmio_nvram_lock); static ssize_t mmio_nvram_read(char *buf, size_t count, loff_t *index) { diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index bffe50d02c9..28df9c827ca 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -379,14 +379,14 @@ static inline u32 mpic_physmask(u32 cpumask) /* Get the mpic structure from the IPI number */ static inline struct mpic * mpic_from_ipi(unsigned int ipi) { - return container_of(irq_desc[ipi].handler, struct mpic, hc_ipi); + return container_of(irq_desc[ipi].chip, struct mpic, hc_ipi); } #endif /* Get the mpic structure from the irq number */ static inline struct mpic * mpic_from_irq(unsigned int irq) { - return container_of(irq_desc[irq].handler, struct mpic, hc_irq); + return container_of(irq_desc[irq].chip, struct mpic, hc_irq); } /* Send an EOI */ @@ -752,7 +752,7 @@ void __init mpic_init(struct mpic *mpic) if (!(mpic->flags & MPIC_PRIMARY)) continue; irq_desc[mpic->ipi_offset+i].status |= IRQ_PER_CPU; - irq_desc[mpic->ipi_offset+i].handler = &mpic->hc_ipi; + irq_desc[mpic->ipi_offset+i].chip = &mpic->hc_ipi; #endif /* CONFIG_SMP */ } @@ -813,7 +813,7 @@ void __init mpic_init(struct mpic *mpic) /* init linux descriptors */ if (i < mpic->irq_count) { irq_desc[mpic->irq_offset+i].status = level ? IRQ_LEVEL : 0; - irq_desc[mpic->irq_offset+i].handler = &mpic->hc_irq; + irq_desc[mpic->irq_offset+i].chip = &mpic->hc_irq; } } @@ -906,7 +906,7 @@ void mpic_setup_this_cpu(void) /* let the mpic know we want intrs. default affinity is 0xffffffff * until changed via /proc. That's how it's done on x86. If we want * it differently, then we should make sure we also change the default - * values of irq_affinity in irq.c. + * values of irq_desc[].affinity in irq.c. */ if (distribute_irqs) { for (i = 0; i < mpic->num_sources ; i++) diff --git a/arch/ppc/8xx_io/commproc.c b/arch/ppc/8xx_io/commproc.c index 12b84ca5132..9b3ace26280 100644 --- a/arch/ppc/8xx_io/commproc.c +++ b/arch/ppc/8xx_io/commproc.c @@ -187,7 +187,7 @@ cpm_interrupt_init(void) * interrupt vectors */ for ( i = CPM_IRQ_OFFSET ; i < CPM_IRQ_OFFSET + NR_CPM_INTS ; i++ ) - irq_desc[i].handler = &cpm_pic; + irq_desc[i].chip = &cpm_pic; /* Set our interrupt handler with the core CPU. */ if (setup_irq(CPM_INTERRUPT, &cpm_interrupt_irqaction)) diff --git a/arch/ppc/kernel/machine_kexec.c b/arch/ppc/kernel/machine_kexec.c index 84d65a87191..a469ba438cb 100644 --- a/arch/ppc/kernel/machine_kexec.c +++ b/arch/ppc/kernel/machine_kexec.c @@ -25,8 +25,8 @@ typedef NORET_TYPE void (*relocate_new_kernel_t)( unsigned long reboot_code_buffer, unsigned long start_address) ATTRIB_NORET; -const extern unsigned char relocate_new_kernel[]; -const extern unsigned int relocate_new_kernel_size; +extern const unsigned char relocate_new_kernel[]; +extern const unsigned int relocate_new_kernel_size; void machine_shutdown(void) { diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index d20accf9650..242bb052be6 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -95,8 +95,10 @@ pcibios_fixup_resources(struct pci_dev *dev) if (!res->flags) continue; if (res->end == 0xffffffff) { - DBG("PCI:%s Resource %d [%08lx-%08lx] is unassigned\n", - pci_name(dev), i, res->start, res->end); + DBG("PCI:%s Resource %d [%016llx-%016llx] is unassigned\n", + pci_name(dev), i, + (unsigned long long)res->start, + (unsigned long long)res->end); res->end -= res->start; res->start = 0; res->flags |= IORESOURCE_UNSET; @@ -169,18 +171,18 @@ EXPORT_SYMBOL(pcibios_bus_to_resource); * but we want to try to avoid allocating at 0x2900-0x2bff * which might have be mirrored at 0x0100-0x03ff.. */ -void pcibios_align_resource(void *data, struct resource *res, unsigned long size, - unsigned long align) +void pcibios_align_resource(void *data, struct resource *res, + resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; + resource_size_t start = res->start; if (size > 0x100) { printk(KERN_ERR "PCI: I/O Region %s/%d too large" - " (%ld bytes)\n", pci_name(dev), - dev->resource - res, size); + " (%lld bytes)\n", pci_name(dev), + dev->resource - res, (unsigned long long)size); } if (start & 0x300) { @@ -251,8 +253,9 @@ pcibios_allocate_bus_resources(struct list_head *bus_list) } } - DBG("PCI: bridge rsrc %lx..%lx (%lx), parent %p\n", - res->start, res->end, res->flags, pr); + DBG("PCI: bridge rsrc %llx..%llx (%lx), parent %p\n", + (unsigned long long)res->start, + (unsigned long long)res->end, res->flags, pr); if (pr) { if (request_resource(pr, res) == 0) continue; @@ -302,8 +305,9 @@ reparent_resources(struct resource *parent, struct resource *res) *pp = NULL; for (p = res->child; p != NULL; p = p->sibling) { p->parent = res; - DBG(KERN_INFO "PCI: reparented %s [%lx..%lx] under %s\n", - p->name, p->start, p->end, res->name); + DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n", + p->name, (unsigned long long)p->start, + (unsigned long long)p->end, res->name); } return 0; } @@ -358,13 +362,15 @@ pci_relocate_bridge_resource(struct pci_bus *bus, int i) try = conflict->start - 1; } if (request_resource(pr, res)) { - DBG(KERN_ERR "PCI: huh? couldn't move to %lx..%lx\n", - res->start, res->end); + DBG(KERN_ERR "PCI: huh? couldn't move to %llx..%llx\n", + (unsigned long long)res->start, + (unsigned long long)res->end); return -1; /* "can't happen" */ } update_bridge_base(bus, i); - printk(KERN_INFO "PCI: bridge %d resource %d moved to %lx..%lx\n", - bus->number, i, res->start, res->end); + printk(KERN_INFO "PCI: bridge %d resource %d moved to %llx..%llx\n", + bus->number, i, (unsigned long long)res->start, + (unsigned long long)res->end); return 0; } @@ -475,15 +481,17 @@ static inline void alloc_resource(struct pci_dev *dev, int idx) { struct resource *pr, *r = &dev->resource[idx]; - DBG("PCI:%s: Resource %d: %08lx-%08lx (f=%lx)\n", - pci_name(dev), idx, r->start, r->end, r->flags); + DBG("PCI:%s: Resource %d: %016llx-%016llx (f=%lx)\n", + pci_name(dev), idx, (unsigned long long)r->start, + (unsigned long long)r->end, r->flags); pr = pci_find_parent_resource(dev, r); if (!pr || request_resource(pr, r) < 0) { printk(KERN_ERR "PCI: Cannot allocate resource region %d" " of device %s\n", idx, pci_name(dev)); if (pr) - DBG("PCI: parent is %p: %08lx-%08lx (f=%lx)\n", - pr, pr->start, pr->end, pr->flags); + DBG("PCI: parent is %p: %016llx-%016llx (f=%lx)\n", + pr, (unsigned long long)pr->start, + (unsigned long long)pr->end, pr->flags); /* We'll assign a new address later */ r->flags |= IORESOURCE_UNSET; r->end -= r->start; @@ -952,8 +960,8 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, else prot |= _PAGE_GUARDED; - printk("PCI map for %s:%lx, prot: %lx\n", pci_name(dev), rp->start, - prot); + printk("PCI map for %s:%llx, prot: %lx\n", pci_name(dev), + (unsigned long long)rp->start, prot); return __pgprot(prot); } @@ -1122,7 +1130,7 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) void pci_resource_to_user(const struct pci_dev *dev, int bar, const struct resource *rsrc, - u64 *start, u64 *end) + resource_size_t *start, resource_size_t *end) { struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); unsigned long offset = 0; diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 1f79e84ab46..4b4607d89bf 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -475,7 +475,7 @@ int __init ppc_init(void) /* register CPU devices */ for_each_possible_cpu(i) - register_cpu(&cpu_devices[i], i, NULL); + register_cpu(&cpu_devices[i], i); /* call platform init */ if (ppc_md.init != NULL) { diff --git a/arch/ppc/platforms/apus_setup.c b/arch/ppc/platforms/apus_setup.c index fe0cdc04d43..5c4118a459f 100644 --- a/arch/ppc/platforms/apus_setup.c +++ b/arch/ppc/platforms/apus_setup.c @@ -734,9 +734,9 @@ void apus_init_IRQ(void) for ( i = 0 ; i < AMI_IRQS; i++ ) { irq_desc[i].status = IRQ_LEVEL; if (i < IRQ_AMIGA_AUTO) { - irq_desc[i].handler = &amiga_irqctrl; + irq_desc[i].chip = &amiga_irqctrl; } else { - irq_desc[i].handler = &amiga_sys_irqctrl; + irq_desc[i].chip = &amiga_sys_irqctrl; action = &amiga_sys_irqaction[i-IRQ_AMIGA_AUTO]; if (action->name) setup_irq(i, action); diff --git a/arch/ppc/platforms/sbc82xx.c b/arch/ppc/platforms/sbc82xx.c index 866807b4ad0..41006d2b4b3 100644 --- a/arch/ppc/platforms/sbc82xx.c +++ b/arch/ppc/platforms/sbc82xx.c @@ -172,7 +172,7 @@ void __init sbc82xx_init_IRQ(void) /* Set up the interrupt handlers for the i8259 IRQs */ for (i = NR_SIU_INTS; i < NR_SIU_INTS + 8; i++) { - irq_desc[i].handler = &sbc82xx_i8259_ic; + irq_desc[i].chip = &sbc82xx_i8259_ic; irq_desc[i].status |= IRQ_LEVEL; } diff --git a/arch/ppc/syslib/cpc700_pic.c b/arch/ppc/syslib/cpc700_pic.c index 5add0a919ef..172aa215fdb 100644 --- a/arch/ppc/syslib/cpc700_pic.c +++ b/arch/ppc/syslib/cpc700_pic.c @@ -140,12 +140,12 @@ cpc700_init_IRQ(void) /* IRQ 0 is highest */ for (i = 0; i < 17; i++) { - irq_desc[i].handler = &cpc700_pic; + irq_desc[i].chip = &cpc700_pic; cpc700_pic_init_irq(i); } for (i = 20; i < 32; i++) { - irq_desc[i].handler = &cpc700_pic; + irq_desc[i].chip = &cpc700_pic; cpc700_pic_init_irq(i); } diff --git a/arch/ppc/syslib/cpm2_pic.c b/arch/ppc/syslib/cpm2_pic.c index 29d95d415ce..c0fee0beb81 100644 --- a/arch/ppc/syslib/cpm2_pic.c +++ b/arch/ppc/syslib/cpm2_pic.c @@ -171,7 +171,7 @@ void cpm2_init_IRQ(void) /* Enable chaining to OpenPIC, and make everything level */ for (i = 0; i < NR_CPM_INTS; i++) { - irq_desc[i+CPM_IRQ_OFFSET].handler = &cpm2_pic; + irq_desc[i+CPM_IRQ_OFFSET].chip = &cpm2_pic; irq_desc[i+CPM_IRQ_OFFSET].status |= IRQ_LEVEL; } } diff --git a/arch/ppc/syslib/gt64260_pic.c b/arch/ppc/syslib/gt64260_pic.c index dc3bd9ecbbf..91096b38ae7 100644 --- a/arch/ppc/syslib/gt64260_pic.c +++ b/arch/ppc/syslib/gt64260_pic.c @@ -98,7 +98,7 @@ gt64260_init_irq(void) /* use the gt64260 for all (possible) interrupt sources */ for (i = gt64260_irq_base; i < (gt64260_irq_base + 96); i++) - irq_desc[i].handler = >64260_pic; + irq_desc[i].chip = >64260_pic; if (ppc_md.progress) ppc_md.progress("gt64260_init_irq: exit", 0x0); diff --git a/arch/ppc/syslib/m82xx_pci.c b/arch/ppc/syslib/m82xx_pci.c index 1941a8c7ca9..63fa5b31339 100644 --- a/arch/ppc/syslib/m82xx_pci.c +++ b/arch/ppc/syslib/m82xx_pci.c @@ -159,7 +159,7 @@ pq2pci_init_irq(void) immap->im_memctl.memc_or8 = 0xffff8010; #endif for (irq = NR_CPM_INTS; irq < NR_CPM_INTS + 4; irq++) - irq_desc[irq].handler = &pq2pci_ic; + irq_desc[irq].chip = &pq2pci_ic; /* make PCI IRQ level sensitive */ immap->im_intctl.ic_siexr &= diff --git a/arch/ppc/syslib/m8xx_setup.c b/arch/ppc/syslib/m8xx_setup.c index dae9af78bde..0c4c0de7c59 100644 --- a/arch/ppc/syslib/m8xx_setup.c +++ b/arch/ppc/syslib/m8xx_setup.c @@ -347,13 +347,13 @@ m8xx_init_IRQ(void) int i; for (i = SIU_IRQ_OFFSET ; i < SIU_IRQ_OFFSET + NR_SIU_INTS ; i++) - irq_desc[i].handler = &ppc8xx_pic; + irq_desc[i].chip = &ppc8xx_pic; cpm_interrupt_init(); #if defined(CONFIG_PCI) for (i = I8259_IRQ_OFFSET ; i < I8259_IRQ_OFFSET + NR_8259_INTS ; i++) - irq_desc[i].handler = &i8259_pic; + irq_desc[i].chip = &i8259_pic; i8259_pic_irq_offset = I8259_IRQ_OFFSET; i8259_init(0); diff --git a/arch/ppc/syslib/mpc52xx_pic.c b/arch/ppc/syslib/mpc52xx_pic.c index c4406f9dc6a..6425b5cee7d 100644 --- a/arch/ppc/syslib/mpc52xx_pic.c +++ b/arch/ppc/syslib/mpc52xx_pic.c @@ -204,9 +204,9 @@ mpc52xx_init_irq(void) out_be32(&intr->main_pri1, 0); out_be32(&intr->main_pri2, 0); - /* Initialize irq_desc[i].handler's with mpc52xx_ic. */ + /* Initialize irq_desc[i].chip's with mpc52xx_ic. */ for (i = 0; i < NR_IRQS; i++) { - irq_desc[i].handler = &mpc52xx_ic; + irq_desc[i].chip = &mpc52xx_ic; irq_desc[i].status = IRQ_LEVEL; } diff --git a/arch/ppc/syslib/mv64360_pic.c b/arch/ppc/syslib/mv64360_pic.c index 5a19697060f..a4244d46838 100644 --- a/arch/ppc/syslib/mv64360_pic.c +++ b/arch/ppc/syslib/mv64360_pic.c @@ -119,7 +119,7 @@ mv64360_init_irq(void) /* All interrupts are level interrupts */ for (i = mv64360_irq_base; i < (mv64360_irq_base + 96); i++) { irq_desc[i].status |= IRQ_LEVEL; - irq_desc[i].handler = &mv64360_pic; + irq_desc[i].chip = &mv64360_pic; } if (ppc_md.progress) diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c index 70456c8f998..767a0bc9581 100644 --- a/arch/ppc/syslib/open_pic.c +++ b/arch/ppc/syslib/open_pic.c @@ -373,7 +373,7 @@ void __init openpic_init(int offset) OPENPIC_VEC_IPI+i+offset); /* IPIs are per-CPU */ irq_desc[OPENPIC_VEC_IPI+i+offset].status |= IRQ_PER_CPU; - irq_desc[OPENPIC_VEC_IPI+i+offset].handler = &open_pic_ipi; + irq_desc[OPENPIC_VEC_IPI+i+offset].chip = &open_pic_ipi; } #endif @@ -408,7 +408,7 @@ void __init openpic_init(int offset) /* Init descriptors */ for (i = offset; i < NumSources + offset; i++) - irq_desc[i].handler = &open_pic; + irq_desc[i].chip = &open_pic; /* Initialize the spurious interrupt */ if (ppc_md.progress) ppc_md.progress("openpic: spurious",0x3bd); @@ -615,8 +615,8 @@ void __devinit do_openpic_setup_cpu(void) /* let the openpic know we want intrs. default affinity * is 0xffffffff until changed via /proc * That's how it's done on x86. If we want it differently, then - * we should make sure we also change the default values of irq_affinity - * in irq.c. + * we should make sure we also change the default values of + * irq_desc[].affinity in irq.c. */ for (i = 0; i < NumSources; i++) openpic_mapirq(i, msk, CPU_MASK_ALL); diff --git a/arch/ppc/syslib/open_pic2.c b/arch/ppc/syslib/open_pic2.c index bcbe40de26f..b8154efff6e 100644 --- a/arch/ppc/syslib/open_pic2.c +++ b/arch/ppc/syslib/open_pic2.c @@ -290,7 +290,7 @@ void __init openpic2_init(int offset) /* Init descriptors */ for (i = offset; i < NumSources + offset; i++) - irq_desc[i].handler = &open_pic2; + irq_desc[i].chip = &open_pic2; /* Initialize the spurious interrupt */ if (ppc_md.progress) ppc_md.progress("openpic2: spurious",0x3bd); diff --git a/arch/ppc/syslib/ppc403_pic.c b/arch/ppc/syslib/ppc403_pic.c index c46043c4722..1584c8b1229 100644 --- a/arch/ppc/syslib/ppc403_pic.c +++ b/arch/ppc/syslib/ppc403_pic.c @@ -121,5 +121,5 @@ ppc4xx_pic_init(void) ppc_md.get_irq = ppc403_pic_get_irq; for (i = 0; i < NR_IRQS; i++) - irq_desc[i].handler = &ppc403_aic; + irq_desc[i].chip = &ppc403_aic; } diff --git a/arch/ppc/syslib/ppc4xx_pic.c b/arch/ppc/syslib/ppc4xx_pic.c index fd9af0fc0e9..e669c1335d4 100644 --- a/arch/ppc/syslib/ppc4xx_pic.c +++ b/arch/ppc/syslib/ppc4xx_pic.c @@ -276,7 +276,7 @@ void __init ppc4xx_pic_init(void) /* Attach low-level handlers */ for (i = 0; i < (NR_UICS << 5); ++i) { - irq_desc[i].handler = &__uic[i >> 5].decl; + irq_desc[i].chip = &__uic[i >> 5].decl; if (is_level_sensitive(i)) irq_desc[i].status |= IRQ_LEVEL; } diff --git a/arch/ppc/syslib/xilinx_pic.c b/arch/ppc/syslib/xilinx_pic.c index e672b600f31..39a93dc6375 100644 --- a/arch/ppc/syslib/xilinx_pic.c +++ b/arch/ppc/syslib/xilinx_pic.c @@ -143,7 +143,7 @@ ppc4xx_pic_init(void) ppc_md.get_irq = xilinx_pic_get_irq; for (i = 0; i < NR_IRQS; ++i) { - irq_desc[i].handler = &xilinx_intc; + irq_desc[i].chip = &xilinx_intc; if (XPAR_INTC_0_KIND_OF_INTR & (0x00000001 << i)) irq_desc[i].status &= ~IRQ_LEVEL; diff --git a/arch/s390/appldata/appldata.h b/arch/s390/appldata/appldata.h index e806a8922bb..71d65eb3065 100644 --- a/arch/s390/appldata/appldata.h +++ b/arch/s390/appldata/appldata.h @@ -3,9 +3,9 @@ * * Definitions and interface for Linux - z/VM Monitor Stream. * - * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. + * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. * - * Author: Gerald Schaefer <geraldsc@de.ibm.com> + * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com> */ //#define APPLDATA_DEBUG /* Debug messages on/off */ @@ -29,6 +29,22 @@ #define CTL_APPLDATA_NET_SUM 2125 #define CTL_APPLDATA_PROC 2126 +#ifndef CONFIG_64BIT + +#define APPLDATA_START_INTERVAL_REC 0x00 /* Function codes for */ +#define APPLDATA_STOP_REC 0x01 /* DIAG 0xDC */ +#define APPLDATA_GEN_EVENT_RECORD 0x02 +#define APPLDATA_START_CONFIG_REC 0x03 + +#else + +#define APPLDATA_START_INTERVAL_REC 0x80 +#define APPLDATA_STOP_REC 0x81 +#define APPLDATA_GEN_EVENT_RECORD 0x82 +#define APPLDATA_START_CONFIG_REC 0x83 + +#endif /* CONFIG_64BIT */ + #define P_INFO(x...) printk(KERN_INFO MY_PRINT_NAME " info: " x) #define P_ERROR(x...) printk(KERN_ERR MY_PRINT_NAME " error: " x) #define P_WARNING(x...) printk(KERN_WARNING MY_PRINT_NAME " status: " x) @@ -53,7 +69,11 @@ struct appldata_ops { void *data; /* record data */ unsigned int size; /* size of record */ struct module *owner; /* THIS_MODULE */ + char mod_lvl[2]; /* modification level, EBCDIC */ }; extern int appldata_register_ops(struct appldata_ops *ops); extern void appldata_unregister_ops(struct appldata_ops *ops); +extern int appldata_diag(char record_nr, u16 function, unsigned long buffer, + u16 length, char *mod_lvl); + diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index 9a22434a580..61bc44626c0 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -5,9 +5,9 @@ * Exports appldata_register_ops() and appldata_unregister_ops() for the * data gathering modules. * - * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. + * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. * - * Author: Gerald Schaefer <geraldsc@de.ibm.com> + * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com> */ #include <linux/config.h> @@ -40,22 +40,6 @@ #define TOD_MICRO 0x01000 /* nr. of TOD clock units for 1 microsecond */ -#ifndef CONFIG_64BIT - -#define APPLDATA_START_INTERVAL_REC 0x00 /* Function codes for */ -#define APPLDATA_STOP_REC 0x01 /* DIAG 0xDC */ -#define APPLDATA_GEN_EVENT_RECORD 0x02 -#define APPLDATA_START_CONFIG_REC 0x03 - -#else - -#define APPLDATA_START_INTERVAL_REC 0x80 -#define APPLDATA_STOP_REC 0x81 -#define APPLDATA_GEN_EVENT_RECORD 0x82 -#define APPLDATA_START_CONFIG_REC 0x83 - -#endif /* CONFIG_64BIT */ - /* * Parameter list for DIAGNOSE X'DC' @@ -195,8 +179,8 @@ static void appldata_work_fn(void *data) * * prepare parameter list, issue DIAG 0xDC */ -static int appldata_diag(char record_nr, u16 function, unsigned long buffer, - u16 length) +int appldata_diag(char record_nr, u16 function, unsigned long buffer, + u16 length, char *mod_lvl) { unsigned long ry; struct appldata_product_id { @@ -214,7 +198,7 @@ static int appldata_diag(char record_nr, u16 function, unsigned long buffer, .record_nr = record_nr, .version_nr = {0xF2, 0xF6}, /* "26" */ .release_nr = {0xF0, 0xF1}, /* "01" */ - .mod_lvl = {0xF0, 0xF0}, /* "00" */ + .mod_lvl = {mod_lvl[0], mod_lvl[1]}, }; struct appldata_parameter_list appldata_parameter_list = { .diag = 0xDC, @@ -467,24 +451,25 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, module_put(ops->owner); return -ENODEV; } - ops->active = 1; ops->callback(ops->data); // init record rc = appldata_diag(ops->record_nr, APPLDATA_START_INTERVAL_REC, - (unsigned long) ops->data, ops->size); + (unsigned long) ops->data, ops->size, + ops->mod_lvl); if (rc != 0) { P_ERROR("START DIAG 0xDC for %s failed, " "return code: %d\n", ops->name, rc); module_put(ops->owner); - ops->active = 0; } else { P_INFO("Monitoring %s data enabled, " "DIAG 0xDC started.\n", ops->name); + ops->active = 1; } } else if ((buf[0] == '0') && (ops->active == 1)) { ops->active = 0; rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC, - (unsigned long) ops->data, ops->size); + (unsigned long) ops->data, ops->size, + ops->mod_lvl); if (rc != 0) { P_ERROR("STOP DIAG 0xDC for %s failed, " "return code: %d\n", ops->name, rc); @@ -633,7 +618,7 @@ appldata_offline_cpu(int cpu) spin_unlock(&appldata_timer_lock); } -static int +static int __cpuinit appldata_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { @@ -652,7 +637,7 @@ appldata_cpu_notify(struct notifier_block *self, return NOTIFY_OK; } -static struct notifier_block appldata_nb = { +static struct notifier_block __devinitdata appldata_nb = { .notifier_call = appldata_cpu_notify, }; @@ -710,7 +695,8 @@ static void __exit appldata_exit(void) list_for_each(lh, &appldata_ops_list) { ops = list_entry(lh, struct appldata_ops, list); rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC, - (unsigned long) ops->data, ops->size); + (unsigned long) ops->data, ops->size, + ops->mod_lvl); if (rc != 0) { P_ERROR("STOP DIAG 0xDC for %s failed, " "return code: %d\n", ops->name, rc); @@ -739,6 +725,7 @@ MODULE_DESCRIPTION("Linux-VM Monitor Stream, base infrastructure"); EXPORT_SYMBOL_GPL(appldata_register_ops); EXPORT_SYMBOL_GPL(appldata_unregister_ops); +EXPORT_SYMBOL_GPL(appldata_diag); #ifdef MODULE /* @@ -779,7 +766,6 @@ unsigned long nr_iowait(void) #endif /* MODULE */ EXPORT_SYMBOL_GPL(si_swapinfo); EXPORT_SYMBOL_GPL(nr_threads); -EXPORT_SYMBOL_GPL(avenrun); EXPORT_SYMBOL_GPL(get_full_page_state); EXPORT_SYMBOL_GPL(nr_running); EXPORT_SYMBOL_GPL(nr_iowait); diff --git a/arch/s390/appldata/appldata_mem.c b/arch/s390/appldata/appldata_mem.c index f0e2fbed3d4..7915a197d96 100644 --- a/arch/s390/appldata/appldata_mem.c +++ b/arch/s390/appldata/appldata_mem.c @@ -4,9 +4,9 @@ * Data gathering module for Linux-VM Monitor Stream, Stage 1. * Collects data related to memory management. * - * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. + * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. * - * Author: Gerald Schaefer <geraldsc@de.ibm.com> + * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com> */ #include <linux/config.h> @@ -152,6 +152,7 @@ static struct appldata_ops ops = { .callback = &appldata_get_mem_data, .data = &appldata_mem_data, .owner = THIS_MODULE, + .mod_lvl = {0xF0, 0xF0}, /* EBCDIC "00" */ }; diff --git a/arch/s390/appldata/appldata_net_sum.c b/arch/s390/appldata/appldata_net_sum.c index 2a4c7432db4..39b7bdecbf0 100644 --- a/arch/s390/appldata/appldata_net_sum.c +++ b/arch/s390/appldata/appldata_net_sum.c @@ -5,9 +5,9 @@ * Collects accumulated network statistics (Packets received/transmitted, * dropped, errors, ...). * - * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. + * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. * - * Author: Gerald Schaefer <geraldsc@de.ibm.com> + * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com> */ #include <linux/config.h> @@ -152,6 +152,7 @@ static struct appldata_ops ops = { .callback = &appldata_get_net_sum_data, .data = &appldata_net_sum_data, .owner = THIS_MODULE, + .mod_lvl = {0xF0, 0xF0}, /* EBCDIC "00" */ }; diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c index 99ddd3bf2fb..f2b44a2f1de 100644 --- a/arch/s390/appldata/appldata_os.c +++ b/arch/s390/appldata/appldata_os.c @@ -4,9 +4,9 @@ * Data gathering module for Linux-VM Monitor Stream, Stage 1. * Collects misc. OS related data (CPU utilization, running processes). * - * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. + * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. * - * Author: Gerald Schaefer <geraldsc@de.ibm.com> + * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com> */ #include <linux/config.h> @@ -44,11 +44,14 @@ struct appldata_os_per_cpu { u32 per_cpu_system; /* ... spent in kernel mode */ u32 per_cpu_idle; /* ... spent in idle mode */ -// New in 2.6 --> + /* New in 2.6 */ u32 per_cpu_irq; /* ... spent in interrupts */ u32 per_cpu_softirq; /* ... spent in softirqs */ u32 per_cpu_iowait; /* ... spent while waiting for I/O */ -// <-- New in 2.6 + + /* New in modification level 01 */ + u32 per_cpu_steal; /* ... stolen by hypervisor */ + u32 cpu_id; /* number of this CPU */ } __attribute__((packed)); struct appldata_os_data { @@ -68,10 +71,9 @@ struct appldata_os_data { u32 avenrun[3]; /* average nr. of running processes during */ /* the last 1, 5 and 15 minutes */ -// New in 2.6 --> + /* New in 2.6 */ u32 nr_iowait; /* number of blocked threads (waiting for I/O) */ -// <-- New in 2.6 /* per cpu data */ struct appldata_os_per_cpu os_cpu[0]; @@ -79,6 +81,14 @@ struct appldata_os_data { static struct appldata_os_data *appldata_os_data; +static struct appldata_ops ops = { + .ctl_nr = CTL_APPLDATA_OS, + .name = "os", + .record_nr = APPLDATA_RECORD_OS_ID, + .owner = THIS_MODULE, + .mod_lvl = {0xF0, 0xF1}, /* EBCDIC "01" */ +}; + static inline void appldata_print_debug(struct appldata_os_data *os_data) { @@ -100,15 +110,17 @@ static inline void appldata_print_debug(struct appldata_os_data *os_data) P_DEBUG("nr_cpus = %u\n", os_data->nr_cpus); for (i = 0; i < os_data->nr_cpus; i++) { P_DEBUG("cpu%u : user = %u, nice = %u, system = %u, " - "idle = %u, irq = %u, softirq = %u, iowait = %u\n", - i, + "idle = %u, irq = %u, softirq = %u, iowait = %u, " + "steal = %u\n", + os_data->os_cpu[i].cpu_id, os_data->os_cpu[i].per_cpu_user, os_data->os_cpu[i].per_cpu_nice, os_data->os_cpu[i].per_cpu_system, os_data->os_cpu[i].per_cpu_idle, os_data->os_cpu[i].per_cpu_irq, os_data->os_cpu[i].per_cpu_softirq, - os_data->os_cpu[i].per_cpu_iowait); + os_data->os_cpu[i].per_cpu_iowait, + os_data->os_cpu[i].per_cpu_steal); } P_DEBUG("sync_count_1 = %u\n", os_data->sync_count_1); @@ -123,14 +135,13 @@ static inline void appldata_print_debug(struct appldata_os_data *os_data) */ static void appldata_get_os_data(void *data) { - int i, j; + int i, j, rc; struct appldata_os_data *os_data; + unsigned int new_size; os_data = data; os_data->sync_count_1++; - os_data->nr_cpus = num_online_cpus(); - os_data->nr_threads = nr_threads; os_data->nr_running = nr_running(); os_data->nr_iowait = nr_iowait(); @@ -154,9 +165,44 @@ static void appldata_get_os_data(void *data) cputime_to_jiffies(kstat_cpu(i).cpustat.softirq); os_data->os_cpu[j].per_cpu_iowait = cputime_to_jiffies(kstat_cpu(i).cpustat.iowait); + os_data->os_cpu[j].per_cpu_steal = + cputime_to_jiffies(kstat_cpu(i).cpustat.steal); + os_data->os_cpu[j].cpu_id = i; j++; } + os_data->nr_cpus = j; + + new_size = sizeof(struct appldata_os_data) + + (os_data->nr_cpus * sizeof(struct appldata_os_per_cpu)); + if (ops.size != new_size) { + if (ops.active) { + rc = appldata_diag(APPLDATA_RECORD_OS_ID, + APPLDATA_START_INTERVAL_REC, + (unsigned long) ops.data, new_size, + ops.mod_lvl); + if (rc != 0) { + P_ERROR("os: START NEW DIAG 0xDC failed, " + "return code: %d, new size = %i\n", rc, + new_size); + P_INFO("os: stopping old record now\n"); + } else + P_INFO("os: new record size = %i\n", new_size); + + rc = appldata_diag(APPLDATA_RECORD_OS_ID, + APPLDATA_STOP_REC, + (unsigned long) ops.data, ops.size, + ops.mod_lvl); + if (rc != 0) + P_ERROR("os: STOP OLD DIAG 0xDC failed, " + "return code: %d, old size = %i\n", rc, + ops.size); + else + P_INFO("os: old record size = %i stopped\n", + ops.size); + } + ops.size = new_size; + } os_data->timestamp = get_clock(); os_data->sync_count_2++; #ifdef APPLDATA_DEBUG @@ -165,15 +211,6 @@ static void appldata_get_os_data(void *data) } -static struct appldata_ops ops = { - .ctl_nr = CTL_APPLDATA_OS, - .name = "os", - .record_nr = APPLDATA_RECORD_OS_ID, - .callback = &appldata_get_os_data, - .owner = THIS_MODULE, -}; - - /* * appldata_os_init() * @@ -181,26 +218,25 @@ static struct appldata_ops ops = { */ static int __init appldata_os_init(void) { - int rc, size; + int rc, max_size; - size = sizeof(struct appldata_os_data) + - (NR_CPUS * sizeof(struct appldata_os_per_cpu)); - if (size > APPLDATA_MAX_REC_SIZE) { - P_ERROR("Size of record = %i, bigger than maximum (%i)!\n", - size, APPLDATA_MAX_REC_SIZE); + max_size = sizeof(struct appldata_os_data) + + (NR_CPUS * sizeof(struct appldata_os_per_cpu)); + if (max_size > APPLDATA_MAX_REC_SIZE) { + P_ERROR("Max. size of OS record = %i, bigger than maximum " + "record size (%i)\n", max_size, APPLDATA_MAX_REC_SIZE); rc = -ENOMEM; goto out; } - P_DEBUG("sizeof(os) = %i, sizeof(os_cpu) = %lu\n", size, + P_DEBUG("max. sizeof(os) = %i, sizeof(os_cpu) = %lu\n", max_size, sizeof(struct appldata_os_per_cpu)); - appldata_os_data = kmalloc(size, GFP_DMA); + appldata_os_data = kzalloc(max_size, GFP_DMA); if (appldata_os_data == NULL) { P_ERROR("No memory for %s!\n", ops.name); rc = -ENOMEM; goto out; } - memset(appldata_os_data, 0, size); appldata_os_data->per_cpu_size = sizeof(struct appldata_os_per_cpu); appldata_os_data->cpu_offset = offsetof(struct appldata_os_data, @@ -208,7 +244,7 @@ static int __init appldata_os_init(void) P_DEBUG("cpu offset = %u\n", appldata_os_data->cpu_offset); ops.data = appldata_os_data; - ops.size = size; + ops.callback = &appldata_get_os_data; rc = appldata_register_ops(&ops); if (rc != 0) { P_ERROR("Error registering ops, rc = %i\n", rc); diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index c5ca2dc5d42..5713c7e5bd1 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c @@ -37,10 +37,10 @@ struct s390_aes_ctx { int key_len; }; -static int aes_set_key(void *ctx, const u8 *in_key, unsigned int key_len, - u32 *flags) +static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, + unsigned int key_len, u32 *flags) { - struct s390_aes_ctx *sctx = ctx; + struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); switch (key_len) { case 16: @@ -70,9 +70,9 @@ fail: return -EINVAL; } -static void aes_encrypt(void *ctx, u8 *out, const u8 *in) +static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) { - const struct s390_aes_ctx *sctx = ctx; + const struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); switch (sctx->key_len) { case 16: @@ -90,9 +90,9 @@ static void aes_encrypt(void *ctx, u8 *out, const u8 *in) } } -static void aes_decrypt(void *ctx, u8 *out, const u8 *in) +static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) { - const struct s390_aes_ctx *sctx = ctx; + const struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); switch (sctx->key_len) { case 16: diff --git a/arch/s390/crypto/des_s390.c b/arch/s390/crypto/des_s390.c index e3c37aa0a19..b3f7496a79b 100644 --- a/arch/s390/crypto/des_s390.c +++ b/arch/s390/crypto/des_s390.c @@ -44,10 +44,10 @@ struct crypt_s390_des3_192_ctx { u8 key[DES3_192_KEY_SIZE]; }; -static int des_setkey(void *ctx, const u8 *key, unsigned int keylen, - u32 *flags) +static int des_setkey(struct crypto_tfm *tfm, const u8 *key, + unsigned int keylen, u32 *flags) { - struct crypt_s390_des_ctx *dctx = ctx; + struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm); int ret; /* test if key is valid (not a weak key) */ @@ -57,16 +57,16 @@ static int des_setkey(void *ctx, const u8 *key, unsigned int keylen, return ret; } -static void des_encrypt(void *ctx, u8 *out, const u8 *in) +static void des_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) { - struct crypt_s390_des_ctx *dctx = ctx; + struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm); crypt_s390_km(KM_DEA_ENCRYPT, dctx->key, out, in, DES_BLOCK_SIZE); } -static void des_decrypt(void *ctx, u8 *out, const u8 *in) +static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) { - struct crypt_s390_des_ctx *dctx = ctx; + struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm); crypt_s390_km(KM_DEA_DECRYPT, dctx->key, out, in, DES_BLOCK_SIZE); } @@ -166,11 +166,11 @@ static struct crypto_alg des_alg = { * Implementers MUST reject keys that exhibit this property. * */ -static int des3_128_setkey(void *ctx, const u8 *key, unsigned int keylen, - u32 *flags) +static int des3_128_setkey(struct crypto_tfm *tfm, const u8 *key, + unsigned int keylen, u32 *flags) { int i, ret; - struct crypt_s390_des3_128_ctx *dctx = ctx; + struct crypt_s390_des3_128_ctx *dctx = crypto_tfm_ctx(tfm); const u8* temp_key = key; if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE))) { @@ -186,17 +186,17 @@ static int des3_128_setkey(void *ctx, const u8 *key, unsigned int keylen, return 0; } -static void des3_128_encrypt(void *ctx, u8 *dst, const u8 *src) +static void des3_128_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) { - struct crypt_s390_des3_128_ctx *dctx = ctx; + struct crypt_s390_des3_128_ctx *dctx = crypto_tfm_ctx(tfm); crypt_s390_km(KM_TDEA_128_ENCRYPT, dctx->key, dst, (void*)src, DES3_128_BLOCK_SIZE); } -static void des3_128_decrypt(void *ctx, u8 *dst, const u8 *src) +static void des3_128_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) { - struct crypt_s390_des3_128_ctx *dctx = ctx; + struct crypt_s390_des3_128_ctx *dctx = crypto_tfm_ctx(tfm); crypt_s390_km(KM_TDEA_128_DECRYPT, dctx->key, dst, (void*)src, DES3_128_BLOCK_SIZE); @@ -302,11 +302,11 @@ static struct crypto_alg des3_128_alg = { * property. * */ -static int des3_192_setkey(void *ctx, const u8 *key, unsigned int keylen, - u32 *flags) +static int des3_192_setkey(struct crypto_tfm *tfm, const u8 *key, + unsigned int keylen, u32 *flags) { int i, ret; - struct crypt_s390_des3_192_ctx *dctx = ctx; + struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm); const u8* temp_key = key; if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && @@ -325,17 +325,17 @@ static int des3_192_setkey(void *ctx, const u8 *key, unsigned int keylen, return 0; } -static void des3_192_encrypt(void *ctx, u8 *dst, const u8 *src) +static void des3_192_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) { - struct crypt_s390_des3_192_ctx *dctx = ctx; + struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm); crypt_s390_km(KM_TDEA_192_ENCRYPT, dctx->key, dst, (void*)src, DES3_192_BLOCK_SIZE); } -static void des3_192_decrypt(void *ctx, u8 *dst, const u8 *src) +static void des3_192_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) { - struct crypt_s390_des3_192_ctx *dctx = ctx; + struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm); crypt_s390_km(KM_TDEA_192_DECRYPT, dctx->key, dst, (void*)src, DES3_192_BLOCK_SIZE); diff --git a/arch/s390/crypto/sha1_s390.c b/arch/s390/crypto/sha1_s390.c index 98c896b86dc..9d34a35b1aa 100644 --- a/arch/s390/crypto/sha1_s390.c +++ b/arch/s390/crypto/sha1_s390.c @@ -40,28 +40,29 @@ struct crypt_s390_sha1_ctx { u8 buffer[2 * SHA1_BLOCK_SIZE]; }; -static void -sha1_init(void *ctx) +static void sha1_init(struct crypto_tfm *tfm) { - static const struct crypt_s390_sha1_ctx initstate = { - .state = { - 0x67452301, - 0xEFCDAB89, - 0x98BADCFE, - 0x10325476, - 0xC3D2E1F0 - }, + struct crypt_s390_sha1_ctx *ctx = crypto_tfm_ctx(tfm); + static const u32 initstate[5] = { + 0x67452301, + 0xEFCDAB89, + 0x98BADCFE, + 0x10325476, + 0xC3D2E1F0 }; - memcpy(ctx, &initstate, sizeof(initstate)); + + ctx->count = 0; + memcpy(ctx->state, &initstate, sizeof(initstate)); + ctx->buf_len = 0; } -static void -sha1_update(void *ctx, const u8 *data, unsigned int len) +static void sha1_update(struct crypto_tfm *tfm, const u8 *data, + unsigned int len) { struct crypt_s390_sha1_ctx *sctx; long imd_len; - sctx = ctx; + sctx = crypto_tfm_ctx(tfm); sctx->count += len * 8; //message bit length //anything in buffer yet? -> must be completed @@ -110,10 +111,9 @@ pad_message(struct crypt_s390_sha1_ctx* sctx) } /* Add padding and return the message digest. */ -static void -sha1_final(void* ctx, u8 *out) +static void sha1_final(struct crypto_tfm *tfm, u8 *out) { - struct crypt_s390_sha1_ctx *sctx = ctx; + struct crypt_s390_sha1_ctx *sctx = crypto_tfm_ctx(tfm); //must perform manual padding pad_message(sctx); diff --git a/arch/s390/crypto/sha256_s390.c b/arch/s390/crypto/sha256_s390.c index 1ec5e92b345..f573df30f31 100644 --- a/arch/s390/crypto/sha256_s390.c +++ b/arch/s390/crypto/sha256_s390.c @@ -31,9 +31,9 @@ struct s390_sha256_ctx { u8 buf[2 * SHA256_BLOCK_SIZE]; }; -static void sha256_init(void *ctx) +static void sha256_init(struct crypto_tfm *tfm) { - struct s390_sha256_ctx *sctx = ctx; + struct s390_sha256_ctx *sctx = crypto_tfm_ctx(tfm); sctx->state[0] = 0x6a09e667; sctx->state[1] = 0xbb67ae85; @@ -44,12 +44,12 @@ static void sha256_init(void *ctx) sctx->state[6] = 0x1f83d9ab; sctx->state[7] = 0x5be0cd19; sctx->count = 0; - memset(sctx->buf, 0, sizeof(sctx->buf)); } -static void sha256_update(void *ctx, const u8 *data, unsigned int len) +static void sha256_update(struct crypto_tfm *tfm, const u8 *data, + unsigned int len) { - struct s390_sha256_ctx *sctx = ctx; + struct s390_sha256_ctx *sctx = crypto_tfm_ctx(tfm); unsigned int index; int ret; @@ -108,9 +108,9 @@ static void pad_message(struct s390_sha256_ctx* sctx) } /* Add padding and return the message digest */ -static void sha256_final(void* ctx, u8 *out) +static void sha256_final(struct crypto_tfm *tfm, u8 *out) { - struct s390_sha256_ctx *sctx = ctx; + struct s390_sha256_ctx *sctx = crypto_tfm_ctx(tfm); /* must perform manual padding */ pad_message(sctx); diff --git a/arch/s390/kernel/binfmt_elf32.c b/arch/s390/kernel/binfmt_elf32.c index 1f451c2cb07..12a6311e983 100644 --- a/arch/s390/kernel/binfmt_elf32.c +++ b/arch/s390/kernel/binfmt_elf32.c @@ -177,11 +177,6 @@ struct elf_prpsinfo32 #include <linux/highuid.h> -#undef NEW_TO_OLD_UID -#undef NEW_TO_OLD_GID -#define NEW_TO_OLD_UID(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid) -#define NEW_TO_OLD_GID(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid) - #define elf_addr_t u32 /* #define init_elf_binfmt init_elf32_binfmt diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index b2448487854..aa8b52c2140 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -93,13 +93,22 @@ STACK_SIZE = 1 << STACK_SHIFT l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 .endm - .macro SAVE_ALL psworg,savearea,sync + .macro SAVE_ALL_SYNC psworg,savearea la %r12,\psworg - .if \sync tm \psworg+1,0x01 # test problem state bit bz BASED(2f) # skip stack setup save l %r15,__LC_KERNEL_STACK # problem state -> load ksp - .else +#ifdef CONFIG_CHECK_STACK + b BASED(3f) +2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD + bz BASED(stack_overflow) +3: +#endif +2: + .endm + + .macro SAVE_ALL_ASYNC psworg,savearea + la %r12,\psworg tm \psworg+1,0x01 # test problem state bit bnz BASED(1f) # from user -> load async stack clc \psworg+4(4),BASED(.Lcritical_end) @@ -115,7 +124,6 @@ STACK_SIZE = 1 << STACK_SHIFT sra %r14,STACK_SHIFT be BASED(2f) 1: l %r15,__LC_ASYNC_STACK - .endif #ifdef CONFIG_CHECK_STACK b BASED(3f) 2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD @@ -196,7 +204,7 @@ system_call: STORE_TIMER __LC_SYNC_ENTER_TIMER sysc_saveall: SAVE_ALL_BASE __LC_SAVE_AREA - SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA lh %r7,0x8a # get svc number from lowcore #ifdef CONFIG_VIRT_CPU_ACCOUNTING @@ -425,7 +433,7 @@ pgm_check_handler: SAVE_ALL_BASE __LC_SAVE_AREA tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception bnz BASED(pgm_per) # got per exception -> special case - SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -464,7 +472,7 @@ pgm_per: # Normal per exception # pgm_per_std: - SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -490,7 +498,7 @@ pgm_no_vtime2: # it was a single stepped SVC that is causing all the trouble # pgm_svcper: - SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -519,7 +527,7 @@ io_int_handler: STORE_TIMER __LC_ASYNC_ENTER_TIMER stck __LC_INT_CLOCK SAVE_ALL_BASE __LC_SAVE_AREA+16 - SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+16,0 + SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -631,7 +639,7 @@ ext_int_handler: STORE_TIMER __LC_ASYNC_ENTER_TIMER stck __LC_INT_CLOCK SAVE_ALL_BASE __LC_SAVE_AREA+16 - SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16,0 + SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -657,21 +665,31 @@ __critical_end: .globl mcck_int_handler mcck_int_handler: spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer - mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs SAVE_ALL_BASE __LC_SAVE_AREA+32 la %r12,__LC_MCK_OLD_PSW tm __LC_MCCK_CODE,0x80 # system damage? bo BASED(mcck_int_main) # yes -> rest of mcck code invalid - tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? - bo BASED(0f) - spt __LC_LAST_UPDATE_TIMER # revalidate cpu timer #ifdef CONFIG_VIRT_CPU_ACCOUNTING - mvc __LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER - mvc __LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER - mvc __LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER + mvc __LC_SAVE_AREA+52(8),__LC_ASYNC_ENTER_TIMER + mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA + tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? + bo BASED(1f) + la %r14,__LC_SYNC_ENTER_TIMER + clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER + bl BASED(0f) + la %r14,__LC_ASYNC_ENTER_TIMER +0: clc 0(8,%r14),__LC_EXIT_TIMER + bl BASED(0f) + la %r14,__LC_EXIT_TIMER +0: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER + bl BASED(0f) + la %r14,__LC_LAST_UPDATE_TIMER +0: spt 0(%r14) + mvc __LC_ASYNC_ENTER_TIMER(8),0(%r14) +1: #endif -0: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? + tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? bno BASED(mcck_int_main) # no -> skip cleanup critical tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit bnz BASED(mcck_int_main) # from user -> load async stack @@ -691,7 +709,7 @@ mcck_int_main: #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? bno BASED(mcck_no_vtime) # no -> skip cleanup critical - tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ? + tm SP_PSW+1(%r15),0x01 # interrupting from user ? bz BASED(mcck_no_vtime) UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER @@ -715,6 +733,20 @@ mcck_no_vtime: l %r1,BASED(.Ls390_handle_mcck) basr %r14,%r1 # call machine check handler mcck_return: + mvc __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW + ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit +#ifdef CONFIG_VIRT_CPU_ACCOUNTING + mvc __LC_ASYNC_ENTER_TIMER(8),__LC_SAVE_AREA+52 + tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? + bno BASED(0f) + lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 + stpt __LC_EXIT_TIMER + lpsw __LC_RETURN_MCCK_PSW # back to caller +0: +#endif + lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 + lpsw __LC_RETURN_MCCK_PSW # back to caller + RESTORE_ALL __LC_RETURN_MCCK_PSW,0 #ifdef CONFIG_SMP @@ -781,6 +813,8 @@ cleanup_table_sysc_leave: .long sysc_leave + 0x80000000, sysc_work_loop + 0x80000000 cleanup_table_sysc_work_loop: .long sysc_work_loop + 0x80000000, sysc_reschedule + 0x80000000 +cleanup_table_io_return: + .long io_return + 0x80000000, io_leave + 0x80000000 cleanup_table_io_leave: .long io_leave + 0x80000000, io_done + 0x80000000 cleanup_table_io_work_loop: @@ -807,6 +841,11 @@ cleanup_critical: clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4) bl BASED(cleanup_sysc_return) 0: + clc 4(4,%r12),BASED(cleanup_table_io_return) + bl BASED(0f) + clc 4(4,%r12),BASED(cleanup_table_io_return+4) + bl BASED(cleanup_io_return) +0: clc 4(4,%r12),BASED(cleanup_table_io_leave) bl BASED(0f) clc 4(4,%r12),BASED(cleanup_table_io_leave+4) @@ -839,7 +878,7 @@ cleanup_system_call: mvc __LC_SAVE_AREA(16),0(%r12) 0: st %r13,4(%r12) st %r12,__LC_SAVE_AREA+48 # argh - SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA l %r12,__LC_SAVE_AREA+48 # argh st %r15,12(%r12) @@ -980,7 +1019,6 @@ cleanup_io_leave_insn: .long cleanup_critical #define SYSCALL(esa,esame,emu) .long esa - .globl sys_call_table sys_call_table: #include "syscalls.S" #undef SYSCALL diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 2ac095bc0e2..f3222a1b286 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -87,13 +87,22 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ larl %r13,system_call .endm - .macro SAVE_ALL psworg,savearea,sync + .macro SAVE_ALL_SYNC psworg,savearea la %r12,\psworg - .if \sync tm \psworg+1,0x01 # test problem state bit jz 2f # skip stack setup save lg %r15,__LC_KERNEL_STACK # problem state -> load ksp - .else +#ifdef CONFIG_CHECK_STACK + j 3f +2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD + jz stack_overflow +3: +#endif +2: + .endm + + .macro SAVE_ALL_ASYNC psworg,savearea + la %r12,\psworg tm \psworg+1,0x01 # test problem state bit jnz 1f # from user -> load kernel stack clc \psworg+8(8),BASED(.Lcritical_end) @@ -108,7 +117,6 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ srag %r14,%r14,STACK_SHIFT jz 2f 1: lg %r15,__LC_ASYNC_STACK # load async stack - .endif #ifdef CONFIG_CHECK_STACK j 3f 2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD @@ -187,7 +195,7 @@ system_call: STORE_TIMER __LC_SYNC_ENTER_TIMER sysc_saveall: SAVE_ALL_BASE __LC_SAVE_AREA - SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore #ifdef CONFIG_VIRT_CPU_ACCOUNTING @@ -446,7 +454,7 @@ pgm_check_handler: SAVE_ALL_BASE __LC_SAVE_AREA tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception jnz pgm_per # got per exception -> special case - SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -485,7 +493,7 @@ pgm_per: # Normal per exception # pgm_per_std: - SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -511,7 +519,7 @@ pgm_no_vtime2: # it was a single stepped SVC that is causing all the trouble # pgm_svcper: - SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -539,7 +547,7 @@ io_int_handler: STORE_TIMER __LC_ASYNC_ENTER_TIMER stck __LC_INT_CLOCK SAVE_ALL_BASE __LC_SAVE_AREA+32 - SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+32,0 + SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+32 CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+32 #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -647,7 +655,7 @@ ext_int_handler: STORE_TIMER __LC_ASYNC_ENTER_TIMER stck __LC_INT_CLOCK SAVE_ALL_BASE __LC_SAVE_AREA+32 - SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32,0 + SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32 CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32 #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -672,21 +680,32 @@ __critical_end: mcck_int_handler: la %r1,4095 # revalidate r1 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer - mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r1) lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs SAVE_ALL_BASE __LC_SAVE_AREA+64 la %r12,__LC_MCK_OLD_PSW tm __LC_MCCK_CODE,0x80 # system damage? jo mcck_int_main # yes -> rest of mcck code invalid - tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? - jo 0f - spt __LC_LAST_UPDATE_TIMER #ifdef CONFIG_VIRT_CPU_ACCOUNTING - mvc __LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER - mvc __LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER - mvc __LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER + la %r14,4095 + mvc __LC_SAVE_AREA+104(8),__LC_ASYNC_ENTER_TIMER + mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r14) + tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? + jo 1f + la %r14,__LC_SYNC_ENTER_TIMER + clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER + jl 0f + la %r14,__LC_ASYNC_ENTER_TIMER +0: clc 0(8,%r14),__LC_EXIT_TIMER + jl 0f + la %r14,__LC_EXIT_TIMER +0: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER + jl 0f + la %r14,__LC_LAST_UPDATE_TIMER +0: spt 0(%r14) + mvc __LC_ASYNC_ENTER_TIMER(8),0(%r14) +1: #endif -0: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? + tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? jno mcck_int_main # no -> skip cleanup critical tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit jnz mcck_int_main # from user -> load kernel stack @@ -705,7 +724,7 @@ mcck_int_main: #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? jno mcck_no_vtime # no -> no timer update - tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ? + tm SP_PSW+1(%r15),0x01 # interrupting from user ? jz mcck_no_vtime UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER @@ -727,7 +746,17 @@ mcck_no_vtime: jno mcck_return brasl %r14,s390_handle_mcck mcck_return: - RESTORE_ALL __LC_RETURN_MCCK_PSW,0 + mvc __LC_RETURN_MCCK_PSW(16),SP_PSW(%r15) # move return PSW + ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit + lmg %r0,%r15,SP_R0(%r15) # load gprs 0-15 +#ifdef CONFIG_VIRT_CPU_ACCOUNTING + mvc __LC_ASYNC_ENTER_TIMER(8),__LC_SAVE_AREA+104 + tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? + jno 0f + stpt __LC_EXIT_TIMER +0: +#endif + lpswe __LC_RETURN_MCCK_PSW # back to caller #ifdef CONFIG_SMP /* @@ -789,6 +818,8 @@ cleanup_table_sysc_leave: .quad sysc_leave, sysc_work_loop cleanup_table_sysc_work_loop: .quad sysc_work_loop, sysc_reschedule +cleanup_table_io_return: + .quad io_return, io_leave cleanup_table_io_leave: .quad io_leave, io_done cleanup_table_io_work_loop: @@ -815,6 +846,11 @@ cleanup_critical: clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop+8) jl cleanup_sysc_return 0: + clc 8(8,%r12),BASED(cleanup_table_io_return) + jl 0f + clc 8(8,%r12),BASED(cleanup_table_io_return+8) + jl cleanup_io_return +0: clc 8(8,%r12),BASED(cleanup_table_io_leave) jl 0f clc 8(8,%r12),BASED(cleanup_table_io_leave+8) @@ -847,7 +883,7 @@ cleanup_system_call: mvc __LC_SAVE_AREA(32),0(%r12) 0: stg %r13,8(%r12) stg %r12,__LC_SAVE_AREA+96 # argh - SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA lg %r12,__LC_SAVE_AREA+96 # argh stg %r15,24(%r12) @@ -957,7 +993,6 @@ cleanup_io_leave_insn: .quad __critical_end #define SYSCALL(esa,esame,emu) .long esame - .globl sys_call_table sys_call_table: #include "syscalls.S" #undef SYSCALL @@ -965,7 +1000,6 @@ sys_call_table: #ifdef CONFIG_COMPAT #define SYSCALL(esa,esame,emu) .long emu - .globl sys_call_table_emu sys_call_table_emu: #include "syscalls.S" #undef SYSCALL diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index ea88d066bf0..538c82da49b 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S @@ -1,7 +1,7 @@ /* * arch/s390/kernel/head.S * - * (C) Copyright IBM Corp. 1999, 2005 + * Copyright (C) IBM Corp. 1999,2006 * * Author(s): Hartmut Penner <hp@de.ibm.com> * Martin Schwidefsky <schwidefsky@de.ibm.com> @@ -482,24 +482,23 @@ start: .macro GET_IPL_DEVICE .Lget_ipl_device: - basr %r12,0 -.LGID: l %r1,0xb8 # get sid + l %r1,0xb8 # get sid sll %r1,15 # test if subchannel is enabled srl %r1,31 ltr %r1,%r1 - bz 0(%r14) # subchannel disabled + bz 2f-.LPG1(%r13) # subchannel disabled l %r1,0xb8 - la %r5,.Lipl_schib-.LGID(%r12) + la %r5,.Lipl_schib-.LPG1(%r13) stsch 0(%r5) # get schib of subchannel - bnz 0(%r14) # schib not available + bnz 2f-.LPG1(%r13) # schib not available tm 5(%r5),0x01 # devno valid? - bno 0(%r14) - la %r6,ipl_parameter_flags-.LGID(%r12) + bno 2f-.LPG1(%r13) + la %r6,ipl_parameter_flags-.LPG1(%r13) oi 3(%r6),0x01 # set flag - la %r2,ipl_devno-.LGID(%r12) + la %r2,ipl_devno-.LPG1(%r13) mvc 0(2,%r2),6(%r5) # store devno tm 4(%r5),0x80 # qdio capable device? - bno 0(%r14) + bno 2f-.LPG1(%r13) oi 3(%r6),0x02 # set flag # copy ipl parameters @@ -523,7 +522,7 @@ start: ar %r2,%r1 sr %r0,%r4 jne 1b - b 0(%r14) + b 2f-.LPG1(%r13) .align 4 .Lipl_schib: @@ -537,6 +536,7 @@ ipl_parameter_flags: .globl ipl_devno ipl_devno: .word 0 +2: .endm #ifdef CONFIG_64BIT diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S index 2d3b089bfb8..d00de17b377 100644 --- a/arch/s390/kernel/head31.S +++ b/arch/s390/kernel/head31.S @@ -1,7 +1,7 @@ /* * arch/s390/kernel/head31.S * - * (C) Copyright IBM Corp. 2005 + * Copyright (C) IBM Corp. 2005,2006 * * Author(s): Hartmut Penner <hp@de.ibm.com> * Martin Schwidefsky <schwidefsky@de.ibm.com> @@ -16,12 +16,31 @@ # or linload or SALIPL # .org 0x10000 -startup:basr %r13,0 # get base -.LPG1: l %r1, .Lget_ipl_device_addr-.LPG1(%r13) - basr %r14, %r1 +startup:basr %r13,0 # get base +.LPG0: l %r13,0f-.LPG0(%r13) + b 0(%r13) +0: .long startup_continue + +# +# params at 10400 (setup.h) +# + .org PARMAREA + .long 0,0 # IPL_DEVICE + .long 0,RAMDISK_ORIGIN # INITRD_START + .long 0,RAMDISK_SIZE # INITRD_SIZE + + .org COMMAND_LINE + .byte "root=/dev/ram0 ro" + .byte 0 + + .org 0x11000 + +startup_continue: + basr %r13,0 # get base +.LPG1: GET_IPL_DEVICE lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers - la %r12,_pstart-.LPG1(%r13) # pointer to parameter area - # move IPL device to lowcore + l %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area + # move IPL device to lowcore mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12) # @@ -51,8 +70,8 @@ startup:basr %r13,0 # get base a %r1,__LC_EXT_NEW_PSW+4 # set handler st %r1,__LC_EXT_NEW_PSW+4 - la %r4,_pstart-.LPG1(%r13) # %r4 is our index for sccb stuff - la %r1, .Lsccb-PARMAREA(%r4) # our sccb + l %r4,.Lsccbaddr-.LPG1(%r13) # %r4 is our index for sccb stuff + lr %r1,%r4 # our sccb .insn rre,0xb2200000,%r2,%r1 # service call ipm %r1 srl %r1,28 # get cc code @@ -63,7 +82,7 @@ startup:basr %r13,0 # get base be .Lservicecall-.LPG1(%r13) lpsw .Lwaitsclp-.LPG1(%r13) .Lsclph: - lh %r1,.Lsccbr-PARMAREA(%r4) + lh %r1,.Lsccbr-.Lsccb(%r4) chi %r1,0x10 # 0x0010 is the sucess code je .Lprocsccb # let's process the sccb chi %r1,0x1f0 @@ -74,7 +93,7 @@ startup:basr %r13,0 # get base b .Lservicecall-.LPG1(%r13) .Lprocsccb: lhi %r1,0 - icm %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0 + icm %r1,3,.Lscpincr1-.Lsccb(%r4) # use this one if != 0 jnz .Lscnd lhi %r1,0x800 # otherwise report 2GB .Lscnd: @@ -84,10 +103,10 @@ startup:basr %r13,0 # get base lr %r1,%r3 .Lno2gb: xr %r3,%r3 # same logic - ic %r3,.Lscpa1-PARMAREA(%r4) + ic %r3,.Lscpa1-.Lsccb(%r4) chi %r3,0x00 jne .Lcompmem - l %r3,.Lscpa2-PARMAREA(%r13) + l %r3,.Lscpa2-.Lsccb(%r4) .Lcompmem: mr %r2,%r1 # mem in MB on 128-bit l %r1,.Lonemb-.LPG1(%r13) @@ -95,8 +114,6 @@ startup:basr %r13,0 # get base b .Lfchunk-.LPG1(%r13) .align 4 -.Lget_ipl_device_addr: - .long .Lget_ipl_device .Lpmask: .byte 0 .align 8 @@ -242,6 +259,8 @@ startup:basr %r13,0 # get base .long 0 # cr13: home space segment table .long 0xc0000000 # cr14: machine check handling off .long 0 # cr15: linkage stack operations +.Lduct: .long 0,0,0,0,0,0,0,0 + .long 0,0,0,0,0,0,0,0 .Lpcmem:.long 0x00080000,0x80000000 + .Lchkmem .Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu .Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp @@ -252,25 +271,9 @@ startup:basr %r13,0 # get base .Lmflags:.long machine_flags .Lbss_bgn: .long __bss_start .Lbss_end: .long _end - - .org PARMAREA-64 -.Lduct: .long 0,0,0,0,0,0,0,0 - .long 0,0,0,0,0,0,0,0 - -# -# params at 10400 (setup.h) -# - .org PARMAREA - .global _pstart -_pstart: - .long 0,0 # IPL_DEVICE - .long 0,RAMDISK_ORIGIN # INITRD_START - .long 0,RAMDISK_SIZE # INITRD_SIZE - - .org COMMAND_LINE - .byte "root=/dev/ram0 ro" - .byte 0 - .org 0x11000 +.Lparmaddr: .long PARMAREA +.Lsccbaddr: .long .Lsccb + .align 4096 .Lsccb: .hword 0x1000 # length, one page .byte 0x00,0x00,0x00 @@ -287,18 +290,14 @@ _pstart: .Lscpincr2: .quad 0x00 .fill 3984,1,0 - .org 0x12000 - .global _pend -_pend: - - GET_IPL_DEVICE + .align 4096 #ifdef CONFIG_SHARED_KERNEL .org 0x100000 #endif # -# startup-code, running in virtual mode +# startup-code, running in absolute addressing mode # .globl _stext _stext: basr %r13,0 # get base diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index f08c06f45d5..47744fcca93 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S @@ -1,7 +1,7 @@ /* * arch/s390/kernel/head64.S * - * (C) Copyright IBM Corp. 1999,2005 + * Copyright (C) IBM Corp. 1999,2006 * * Author(s): Hartmut Penner <hp@de.ibm.com> * Martin Schwidefsky <schwidefsky@de.ibm.com> @@ -15,18 +15,37 @@ # this is called either by the ipl loader or directly by PSW restart # or linload or SALIPL # - .org 0x10000 -startup:basr %r13,0 # get base + .org 0x10000 +startup:basr %r13,0 # get base +.LPG0: l %r13,0f-.LPG0(%r13) + b 0(%r13) +0: .long startup_continue + +# +# params at 10400 (setup.h) +# + .org PARMAREA + .quad 0 # IPL_DEVICE + .quad RAMDISK_ORIGIN # INITRD_START + .quad RAMDISK_SIZE # INITRD_SIZE + + .org COMMAND_LINE + .byte "root=/dev/ram0 ro" + .byte 0 + + .org 0x11000 + +startup_continue: + basr %r13,0 # get base .LPG1: sll %r13,1 # remove high order bit srl %r13,1 - l %r1,.Lget_ipl_device_addr-.LPG1(%r13) - basr %r14,%r1 + GET_IPL_DEVICE lhi %r1,1 # mode 1 = esame slr %r0,%r0 # set cpuid to zero sigp %r1,%r0,0x12 # switch to esame mode sam64 # switch to 64 bit mode lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers - larl %r12,_pstart # pointer to parameter area + lg %r12,.Lparmaddr-.LPG1(%r13)# pointer to parameter area # move IPL device to lowcore mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12) @@ -55,8 +74,8 @@ startup:basr %r13,0 # get base larl %r1,.Lsclph stg %r1,__LC_EXT_NEW_PSW+8 # set handler - larl %r4,_pstart # %r4 is our index for sccb stuff - la %r1,.Lsccb-PARMAREA(%r4) # our sccb + larl %r4,.Lsccb # %r4 is our index for sccb stuff + lgr %r1,%r4 # our sccb .insn rre,0xb2200000,%r2,%r1 # service call ipm %r1 srl %r1,28 # get cc code @@ -67,7 +86,7 @@ startup:basr %r13,0 # get base be .Lservicecall-.LPG1(%r13) lpswe .Lwaitsclp-.LPG1(%r13) .Lsclph: - lh %r1,.Lsccbr-PARMAREA(%r4) + lh %r1,.Lsccbr-.Lsccb(%r4) chi %r1,0x10 # 0x0010 is the sucess code je .Lprocsccb # let's process the sccb chi %r1,0x1f0 @@ -78,15 +97,15 @@ startup:basr %r13,0 # get base b .Lservicecall-.LPG1(%r13) .Lprocsccb: lghi %r1,0 - icm %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0 + icm %r1,3,.Lscpincr1-.Lsccb(%r4) # use this one if != 0 jnz .Lscnd - lg %r1,.Lscpincr2-PARMAREA(%r4) # otherwise use this one + lg %r1,.Lscpincr2-.Lsccb(%r4) # otherwise use this one .Lscnd: xr %r3,%r3 # same logic - ic %r3,.Lscpa1-PARMAREA(%r4) + ic %r3,.Lscpa1-.Lsccb(%r4) chi %r3,0x00 jne .Lcompmem - l %r3,.Lscpa2-PARMAREA(%r13) + l %r3,.Lscpa2-.Lsccb(%r4) .Lcompmem: mlgr %r2,%r1 # mem in MB on 128-bit l %r1,.Lonemb-.LPG1(%r13) @@ -94,8 +113,6 @@ startup:basr %r13,0 # get base b .Lfchunk-.LPG1(%r13) .align 4 -.Lget_ipl_device_addr: - .long .Lget_ipl_device .Lpmask: .byte 0 .align 8 @@ -242,29 +259,16 @@ startup:basr %r13,0 # get base .quad 0 # cr13: home space segment table .quad 0xc0000000 # cr14: machine check handling off .quad 0 # cr15: linkage stack operations +.Lduct: .long 0,0,0,0,0,0,0,0 + .long 0,0,0,0,0,0,0,0 .Lpcmsk:.quad 0x0000000180000000 .L4malign:.quad 0xffffffffffc00000 .Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 .Lnop: .long 0x07000700 +.Lparmaddr: + .quad PARMAREA - .org PARMAREA-64 -.Lduct: .long 0,0,0,0,0,0,0,0 - .long 0,0,0,0,0,0,0,0 - -# -# params at 10400 (setup.h) -# - .org PARMAREA - .global _pstart -_pstart: - .quad 0 # IPL_DEVICE - .quad RAMDISK_ORIGIN # INITRD_START - .quad RAMDISK_SIZE # INITRD_SIZE - - .org COMMAND_LINE - .byte "root=/dev/ram0 ro" - .byte 0 - .org 0x11000 + .align 4096 .Lsccb: .hword 0x1000 # length, one page .byte 0x00,0x00,0x00 @@ -281,18 +285,14 @@ _pstart: .Lscpincr2: .quad 0x00 .fill 3984,1,0 - .org 0x12000 - .global _pend -_pend: - - GET_IPL_DEVICE + .align 4096 #ifdef CONFIG_SHARED_KERNEL .org 0x100000 #endif # -# startup-code, running in virtual mode +# startup-code, running in absolute addressing mode # .globl _stext _stext: basr %r13,0 # get base @@ -326,4 +326,3 @@ _stext: basr %r13,0 # get base .align 8 .Ldw: .quad 0x0002000180000000,0x0000000000000000 .Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c index bad81b5832d..fbde6a91526 100644 --- a/arch/s390/kernel/machine_kexec.c +++ b/arch/s390/kernel/machine_kexec.c @@ -27,8 +27,8 @@ static void kexec_halt_all_cpus(void *); typedef void (*relocate_kernel_t) (kimage_entry_t *, unsigned long); -const extern unsigned char relocate_kernel[]; -const extern unsigned long long relocate_kernel_len; +extern const unsigned char relocate_kernel[]; +extern const unsigned long long relocate_kernel_len; int machine_kexec_prepare(struct kimage *image) diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c index 4176c77670c..0886e739d12 100644 --- a/arch/s390/kernel/s390_ksyms.c +++ b/arch/s390/kernel/s390_ksyms.c @@ -46,8 +46,6 @@ EXPORT_SYMBOL(__down_interruptible); */ extern int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs); EXPORT_SYMBOL(dump_fpu); -EXPORT_SYMBOL(overflowuid); -EXPORT_SYMBOL(overflowgid); EXPORT_SYMBOL(empty_zero_page); /* diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index b282034452a..2b2551e3510 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -37,6 +37,7 @@ #include <linux/seq_file.h> #include <linux/kernel_stat.h> #include <linux/device.h> +#include <linux/notifier.h> #include <asm/uaccess.h> #include <asm/system.h> @@ -115,6 +116,7 @@ void __devinit cpu_init (void) */ char vmhalt_cmd[128] = ""; char vmpoff_cmd[128] = ""; +char vmpanic_cmd[128] = ""; static inline void strncpy_skip_quote(char *dst, char *src, int n) { @@ -146,6 +148,38 @@ static int __init vmpoff_setup(char *str) __setup("vmpoff=", vmpoff_setup); +static int vmpanic_notify(struct notifier_block *self, unsigned long event, + void *data) +{ + if (MACHINE_IS_VM && strlen(vmpanic_cmd) > 0) + cpcmd(vmpanic_cmd, NULL, 0, NULL); + + return NOTIFY_OK; +} + +#define PANIC_PRI_VMPANIC 0 + +static struct notifier_block vmpanic_nb = { + .notifier_call = vmpanic_notify, + .priority = PANIC_PRI_VMPANIC +}; + +static int __init vmpanic_setup(char *str) +{ + static int register_done __initdata = 0; + + strncpy_skip_quote(vmpanic_cmd, str, 127); + vmpanic_cmd[127] = 0; + if (!register_done) { + register_done = 1; + atomic_notifier_chain_register(&panic_notifier_list, + &vmpanic_nb); + } + return 1; +} + +__setup("vmpanic=", vmpanic_setup); + /* * condev= and conmode= setup parameter. */ @@ -289,19 +323,34 @@ void (*_machine_power_off)(void) = do_machine_power_off_nonsmp; void machine_restart(char *command) { - console_unblank(); + if (!in_interrupt() || oops_in_progress) + /* + * Only unblank the console if we are called in enabled + * context or a bust_spinlocks cleared the way for us. + */ + console_unblank(); _machine_restart(command); } void machine_halt(void) { - console_unblank(); + if (!in_interrupt() || oops_in_progress) + /* + * Only unblank the console if we are called in enabled + * context or a bust_spinlocks cleared the way for us. + */ + console_unblank(); _machine_halt(); } void machine_power_off(void) { - console_unblank(); + if (!in_interrupt() || oops_in_progress) + /* + * Only unblank the console if we are called in enabled + * context or a bust_spinlocks cleared the way for us. + */ + console_unblank(); _machine_power_off(); } diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 343120c9223..8e03219eea7 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -869,7 +869,7 @@ static int __init topology_init(void) int ret; for_each_possible_cpu(cpu) { - ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu, NULL); + ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu); if (ret) printk(KERN_WARNING "topology_init: register_cpu %d " "failed (%d)\n", cpu, ret); diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index a46793beedd..b7630436f69 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -150,13 +150,11 @@ void show_stack(struct task_struct *task, unsigned long *sp) unsigned long *stack; int i; - // debugging aid: "show_stack(NULL);" prints the - // back trace for this cpu. - if (!sp) - sp = task ? (unsigned long *) task->thread.ksp : __r15; + stack = task ? (unsigned long *) task->thread.ksp : __r15; + else + stack = sp; - stack = sp; for (i = 0; i < kstack_depth_to_print; i++) { if (((addr_t) stack & (THREAD_SIZE-1)) == 0) break; diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index dfe6f085661..1f0439dc245 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -356,7 +356,7 @@ static void internal_add_vtimer(struct vtimer_list *timer) set_vtimer(event->expires); spin_unlock_irqrestore(&vt_list->lock, flags); - /* release CPU aquired in prepare_vtimer or mod_virt_timer() */ + /* release CPU acquired in prepare_vtimer or mod_virt_timer() */ put_cpu(); } diff --git a/arch/sh/Makefile b/arch/sh/Makefile index c72e17a96ee..e467a450662 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -147,7 +147,7 @@ endif # them changed. We use .arch and .mach to indicate when they were # updated last, otherwise make uses the target directory mtime. -include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/MARKER +include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/auto.conf @echo ' SYMLINK include/asm-sh/cpu -> include/asm-sh/$(cpuincdir-y)' $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi $(Q)ln -fsn $(incdir-prefix)$(cpuincdir-y) include/asm-sh/cpu @@ -157,7 +157,7 @@ include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/MARKER # don't, just reference the parent directory so the semantics are # kept roughly the same. -include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/MARKER +include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/auto.conf @echo -n ' SYMLINK include/asm-sh/mach -> ' $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi $(Q)if [ -d $(incdir-prefix)$(incdir-y) ]; then \ diff --git a/arch/sh/boards/adx/irq_maskreg.c b/arch/sh/boards/adx/irq_maskreg.c index c0973f8d57b..357fab1bac2 100644 --- a/arch/sh/boards/adx/irq_maskreg.c +++ b/arch/sh/boards/adx/irq_maskreg.c @@ -102,6 +102,6 @@ static void end_maskreg_irq(unsigned int irq) void make_maskreg_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &maskreg_irq_type; + irq_desc[irq].chip = &maskreg_irq_type; disable_maskreg_irq(irq); } diff --git a/arch/sh/boards/bigsur/irq.c b/arch/sh/boards/bigsur/irq.c index 6ddbcc77244..1d32425782c 100644 --- a/arch/sh/boards/bigsur/irq.c +++ b/arch/sh/boards/bigsur/irq.c @@ -253,7 +253,7 @@ static void make_bigsur_l1isr(unsigned int irq) { /* sanity check first */ if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) { /* save the handler in the main description table */ - irq_desc[irq].handler = &bigsur_l1irq_type; + irq_desc[irq].chip = &bigsur_l1irq_type; irq_desc[irq].status = IRQ_DISABLED; irq_desc[irq].action = 0; irq_desc[irq].depth = 1; @@ -270,7 +270,7 @@ static void make_bigsur_l2isr(unsigned int irq) { /* sanity check first */ if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) { /* save the handler in the main description table */ - irq_desc[irq].handler = &bigsur_l2irq_type; + irq_desc[irq].chip = &bigsur_l2irq_type; irq_desc[irq].status = IRQ_DISABLED; irq_desc[irq].action = 0; irq_desc[irq].depth = 1; diff --git a/arch/sh/boards/cqreek/irq.c b/arch/sh/boards/cqreek/irq.c index d1da0d84456..2955adc5231 100644 --- a/arch/sh/boards/cqreek/irq.c +++ b/arch/sh/boards/cqreek/irq.c @@ -103,7 +103,7 @@ void __init init_cqreek_IRQ(void) cqreek_irq_data[14].stat_port = BRIDGE_IDE_INTR_STAT; cqreek_irq_data[14].bit = 1; - irq_desc[14].handler = &cqreek_irq_type; + irq_desc[14].chip = &cqreek_irq_type; irq_desc[14].status = IRQ_DISABLED; irq_desc[14].action = 0; irq_desc[14].depth = 1; @@ -117,7 +117,7 @@ void __init init_cqreek_IRQ(void) cqreek_irq_data[10].bit = (1 << 10); /* XXX: Err... we may need demultiplexer for ISA irq... */ - irq_desc[10].handler = &cqreek_irq_type; + irq_desc[10].chip = &cqreek_irq_type; irq_desc[10].status = IRQ_DISABLED; irq_desc[10].action = 0; irq_desc[10].depth = 1; diff --git a/arch/sh/boards/dreamcast/setup.c b/arch/sh/boards/dreamcast/setup.c index 55dece35cde..0027b80a234 100644 --- a/arch/sh/boards/dreamcast/setup.c +++ b/arch/sh/boards/dreamcast/setup.c @@ -70,7 +70,7 @@ int __init platform_setup(void) /* Assign all virtual IRQs to the System ASIC int. handler */ for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) - irq_desc[i].handler = &systemasic_int; + irq_desc[i].chip = &systemasic_int; board_time_init = aica_time_init; diff --git a/arch/sh/boards/ec3104/setup.c b/arch/sh/boards/ec3104/setup.c index 5130ba2b6ff..4b3ef16a0e9 100644 --- a/arch/sh/boards/ec3104/setup.c +++ b/arch/sh/boards/ec3104/setup.c @@ -63,7 +63,7 @@ int __init platform_setup(void) str[i] = ctrl_readb(EC3104_BASE + i); for (i = EC3104_IRQBASE; i < EC3104_IRQBASE + 32; i++) - irq_desc[i].handler = &ec3104_int; + irq_desc[i].chip = &ec3104_int; printk("initializing EC3104 \"%.8s\" at %08x, IRQ %d, IRQ base %d\n", str, EC3104_BASE, EC3104_IRQ, EC3104_IRQBASE); diff --git a/arch/sh/boards/harp/irq.c b/arch/sh/boards/harp/irq.c index 52d0ba39031..701fa55d529 100644 --- a/arch/sh/boards/harp/irq.c +++ b/arch/sh/boards/harp/irq.c @@ -114,7 +114,7 @@ static void enable_harp_irq(unsigned int irq) static void __init make_harp_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &harp_irq_type; + irq_desc[irq].chip = &harp_irq_type; disable_harp_irq(irq); } diff --git a/arch/sh/boards/mpc1211/pci.c b/arch/sh/boards/mpc1211/pci.c index ba3a6543975..9f7ccd33ffb 100644 --- a/arch/sh/boards/mpc1211/pci.c +++ b/arch/sh/boards/mpc1211/pci.c @@ -273,9 +273,9 @@ void __init pcibios_fixup_irqs(void) } void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { - unsigned long start = res->start; + resource_size_t start = res->start; if (res->flags & IORESOURCE_IO) { if (start >= 0x10000UL) { diff --git a/arch/sh/boards/mpc1211/setup.c b/arch/sh/boards/mpc1211/setup.c index 2bb581b9168..b72f009c52c 100644 --- a/arch/sh/boards/mpc1211/setup.c +++ b/arch/sh/boards/mpc1211/setup.c @@ -194,7 +194,7 @@ static struct hw_interrupt_type mpc1211_irq_type = { static void make_mpc1211_irq(unsigned int irq) { - irq_desc[irq].handler = &mpc1211_irq_type; + irq_desc[irq].chip = &mpc1211_irq_type; irq_desc[irq].status = IRQ_DISABLED; irq_desc[irq].action = 0; irq_desc[irq].depth = 1; diff --git a/arch/sh/boards/overdrive/galileo.c b/arch/sh/boards/overdrive/galileo.c index 276fa11ee4c..b055809d2ac 100644 --- a/arch/sh/boards/overdrive/galileo.c +++ b/arch/sh/boards/overdrive/galileo.c @@ -536,7 +536,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) } void pcibios_align_resource(void *data, struct resource *res, - unsigned long size) + resource_size_t size) { } diff --git a/arch/sh/boards/overdrive/irq.c b/arch/sh/boards/overdrive/irq.c index 715e8feb3a6..2c13a7de6b2 100644 --- a/arch/sh/boards/overdrive/irq.c +++ b/arch/sh/boards/overdrive/irq.c @@ -150,7 +150,7 @@ static void enable_od_irq(unsigned int irq) static void __init make_od_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &od_irq_type; + irq_desc[irq].chip = &od_irq_type; disable_od_irq(irq); } diff --git a/arch/sh/boards/renesas/hs7751rvoip/irq.c b/arch/sh/boards/renesas/hs7751rvoip/irq.c index ed4c5b50ea4..52a98b524e1 100644 --- a/arch/sh/boards/renesas/hs7751rvoip/irq.c +++ b/arch/sh/boards/renesas/hs7751rvoip/irq.c @@ -86,7 +86,7 @@ static struct hw_interrupt_type hs7751rvoip_irq_type = { static void make_hs7751rvoip_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &hs7751rvoip_irq_type; + irq_desc[irq].chip = &hs7751rvoip_irq_type; disable_hs7751rvoip_irq(irq); } diff --git a/arch/sh/boards/renesas/rts7751r2d/irq.c b/arch/sh/boards/renesas/rts7751r2d/irq.c index d36c9374aed..e16915d9cda 100644 --- a/arch/sh/boards/renesas/rts7751r2d/irq.c +++ b/arch/sh/boards/renesas/rts7751r2d/irq.c @@ -100,7 +100,7 @@ static struct hw_interrupt_type rts7751r2d_irq_type = { static void make_rts7751r2d_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &rts7751r2d_irq_type; + irq_desc[irq].chip = &rts7751r2d_irq_type; disable_rts7751r2d_irq(irq); } diff --git a/arch/sh/boards/renesas/systemh/irq.c b/arch/sh/boards/renesas/systemh/irq.c index 7a2eb10edb5..84597918105 100644 --- a/arch/sh/boards/renesas/systemh/irq.c +++ b/arch/sh/boards/renesas/systemh/irq.c @@ -105,7 +105,7 @@ static void end_systemh_irq(unsigned int irq) void make_systemh_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &systemh_irq_type; + irq_desc[irq].chip = &systemh_irq_type; disable_systemh_irq(irq); } diff --git a/arch/sh/boards/se/73180/irq.c b/arch/sh/boards/se/73180/irq.c index 70f04caad9a..402735c7c89 100644 --- a/arch/sh/boards/se/73180/irq.c +++ b/arch/sh/boards/se/73180/irq.c @@ -85,7 +85,7 @@ void make_intreq_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &intreq_irq_type; + irq_desc[irq].chip = &intreq_irq_type; disable_intreq_irq(irq); } diff --git a/arch/sh/boards/superh/microdev/irq.c b/arch/sh/boards/superh/microdev/irq.c index efcbd86b7cd..cb5999425d1 100644 --- a/arch/sh/boards/superh/microdev/irq.c +++ b/arch/sh/boards/superh/microdev/irq.c @@ -147,7 +147,7 @@ static void enable_microdev_irq(unsigned int irq) static void __init make_microdev_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = µdev_irq_type; + irq_desc[irq].chip = µdev_irq_type; disable_microdev_irq(irq); } diff --git a/arch/sh/cchips/hd6446x/hd64461/setup.c b/arch/sh/cchips/hd6446x/hd64461/setup.c index f014b9bf692..724db04cb39 100644 --- a/arch/sh/cchips/hd6446x/hd64461/setup.c +++ b/arch/sh/cchips/hd6446x/hd64461/setup.c @@ -154,7 +154,7 @@ int __init setup_hd64461(void) outw(0xffff, HD64461_NIMR); for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) { - irq_desc[i].handler = &hd64461_irq_type; + irq_desc[i].chip = &hd64461_irq_type; } setup_irq(CONFIG_HD64461_IRQ, &irq0); diff --git a/arch/sh/cchips/hd6446x/hd64465/setup.c b/arch/sh/cchips/hd6446x/hd64465/setup.c index 68e4c4e4283..cf9142c620b 100644 --- a/arch/sh/cchips/hd6446x/hd64465/setup.c +++ b/arch/sh/cchips/hd6446x/hd64465/setup.c @@ -182,7 +182,7 @@ static int __init setup_hd64465(void) outw(0xffff, HD64465_REG_NIMR); /* mask all interrupts */ for (i = 0; i < HD64465_IRQ_NUM ; i++) { - irq_desc[HD64465_IRQ_BASE + i].handler = &hd64465_irq_type; + irq_desc[HD64465_IRQ_BASE + i].chip = &hd64465_irq_type; } setup_irq(CONFIG_HD64465_IRQ, &irq0); diff --git a/arch/sh/cchips/voyagergx/irq.c b/arch/sh/cchips/voyagergx/irq.c index 2ee330b3c38..892214bade1 100644 --- a/arch/sh/cchips/voyagergx/irq.c +++ b/arch/sh/cchips/voyagergx/irq.c @@ -191,7 +191,7 @@ void __init setup_voyagergx_irq(void) flag = 1; } if (flag == 1) - irq_desc[VOYAGER_IRQ_BASE + i].handler = &voyagergx_irq_type; + irq_desc[VOYAGER_IRQ_BASE + i].chip = &voyagergx_irq_type; } setup_irq(IRQ_VOYAGER, &irq0); diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index c1669905abe..3d546ba329c 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -75,7 +75,7 @@ pcibios_update_resource(struct pci_dev *dev, struct resource *root, } void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) __attribute__ ((weak)); /* @@ -85,10 +85,10 @@ void pcibios_align_resource(void *data, struct resource *res, * modulo 0x400. */ void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; + resource_size_t start = res->start; if (start & 0x300) { start = (start + 0x3ff) & ~0x3ff; diff --git a/arch/sh/kernel/cpu/irq/imask.c b/arch/sh/kernel/cpu/irq/imask.c index baed9a550d3..a33ae3e0a5a 100644 --- a/arch/sh/kernel/cpu/irq/imask.c +++ b/arch/sh/kernel/cpu/irq/imask.c @@ -105,6 +105,6 @@ static void shutdown_imask_irq(unsigned int irq) void make_imask_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &imask_irq_type; + irq_desc[irq].chip = &imask_irq_type; enable_irq(irq); } diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c index 06e8afab32e..30064bf6e15 100644 --- a/arch/sh/kernel/cpu/irq/intc2.c +++ b/arch/sh/kernel/cpu/irq/intc2.c @@ -137,7 +137,7 @@ void make_intc2_irq(unsigned int irq, local_irq_restore(flags); - irq_desc[irq].handler = &intc2_irq_type; + irq_desc[irq].chip = &intc2_irq_type; disable_intc2_irq(irq); } diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c index e55150ed085..0373b65c77f 100644 --- a/arch/sh/kernel/cpu/irq/ipr.c +++ b/arch/sh/kernel/cpu/irq/ipr.c @@ -115,7 +115,7 @@ void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority) ipr_data[irq].shift = pos*4; /* POSition (0-3) x 4 means shift */ ipr_data[irq].priority = priority; - irq_desc[irq].handler = &ipr_irq_type; + irq_desc[irq].chip = &ipr_irq_type; disable_ipr_irq(irq); } diff --git a/arch/sh/kernel/cpu/irq/pint.c b/arch/sh/kernel/cpu/irq/pint.c index 95d6024fe1a..714963a25bb 100644 --- a/arch/sh/kernel/cpu/irq/pint.c +++ b/arch/sh/kernel/cpu/irq/pint.c @@ -85,7 +85,7 @@ static void end_pint_irq(unsigned int irq) void make_pint_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &pint_irq_type; + irq_desc[irq].chip = &pint_irq_type; disable_pint_irq(irq); } diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index b56e79632f2..c2e07f7f349 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -47,7 +47,7 @@ int show_interrupts(struct seq_file *p, void *v) goto unlock; seq_printf(p, "%3d: ",i); seq_printf(p, "%10u ", kstat_irqs(i)); - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c index 43546525f28..6bcd8d92399 100644 --- a/arch/sh/kernel/machine_kexec.c +++ b/arch/sh/kernel/machine_kexec.c @@ -25,8 +25,8 @@ typedef NORET_TYPE void (*relocate_new_kernel_t)( unsigned long start_address, unsigned long vbr_reg) ATTRIB_NORET; -const extern unsigned char relocate_new_kernel[]; -const extern unsigned int relocate_new_kernel_size; +extern const unsigned char relocate_new_kernel[]; +extern const unsigned int relocate_new_kernel_size; extern void *gdb_vbr_vector; /* diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index bb229ef030f..9af22116c9a 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -402,7 +402,7 @@ static int __init topology_init(void) int cpu_id; for_each_possible_cpu(cpu_id) - register_cpu(&cpu[cpu_id], cpu_id, NULL); + register_cpu(&cpu[cpu_id], cpu_id); return 0; } diff --git a/arch/sh/oprofile/op_model_sh7750.c b/arch/sh/oprofile/op_model_sh7750.c index 5ec9ddcc4b0..c265185b22a 100644 --- a/arch/sh/oprofile/op_model_sh7750.c +++ b/arch/sh/oprofile/op_model_sh7750.c @@ -198,7 +198,7 @@ static int sh7750_perf_counter_create_files(struct super_block *sb, struct dentr for (i = 0; i < NR_CNTRS; i++) { struct dentry *dir; - char buf[3]; + char buf[4]; snprintf(buf, sizeof(buf), "%d", i); dir = oprofilefs_mkdir(sb, root, buf); diff --git a/arch/sh64/kernel/irq.c b/arch/sh64/kernel/irq.c index d69879c0e06..675776a5477 100644 --- a/arch/sh64/kernel/irq.c +++ b/arch/sh64/kernel/irq.c @@ -65,7 +65,7 @@ int show_interrupts(struct seq_file *p, void *v) goto unlock; seq_printf(p, "%3d: ",i); seq_printf(p, "%10u ", kstat_irqs(i)); - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) diff --git a/arch/sh64/kernel/irq_intc.c b/arch/sh64/kernel/irq_intc.c index fc99bf4e362..fa730f5fe2e 100644 --- a/arch/sh64/kernel/irq_intc.c +++ b/arch/sh64/kernel/irq_intc.c @@ -178,7 +178,7 @@ static void end_intc_irq(unsigned int irq) void make_intc_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &intc_irq_type; + irq_desc[irq].chip = &intc_irq_type; disable_intc_irq(irq); } @@ -208,7 +208,7 @@ void __init init_IRQ(void) /* Set default: per-line enable/disable, priority driven ack/eoi */ for (i = 0; i < NR_INTC_IRQS; i++) { if (platform_int_priority[i] != NO_PRIORITY) { - irq_desc[i].handler = &intc_irq_type; + irq_desc[i].chip = &intc_irq_type; } } diff --git a/arch/sh64/kernel/pcibios.c b/arch/sh64/kernel/pcibios.c index 50c61dcb9fa..945920bc24d 100644 --- a/arch/sh64/kernel/pcibios.c +++ b/arch/sh64/kernel/pcibios.c @@ -69,10 +69,10 @@ pcibios_update_resource(struct pci_dev *dev, struct resource *root, * modulo 0x400. */ void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; + resource_size_t start = res->start; if (start & 0x300) { start = (start + 0x3ff) & ~0x3ff; diff --git a/arch/sh64/kernel/setup.c b/arch/sh64/kernel/setup.c index d2711c9c9d1..da98d8dbcf9 100644 --- a/arch/sh64/kernel/setup.c +++ b/arch/sh64/kernel/setup.c @@ -309,7 +309,7 @@ static struct cpu cpu[1]; static int __init topology_init(void) { - return register_cpu(cpu, 0, NULL); + return register_cpu(cpu, 0); } subsys_initcall(topology_init); diff --git a/arch/sh64/mach-cayman/irq.c b/arch/sh64/mach-cayman/irq.c index f797c84bfdd..05eb7cdc26f 100644 --- a/arch/sh64/mach-cayman/irq.c +++ b/arch/sh64/mach-cayman/irq.c @@ -187,7 +187,7 @@ void init_cayman_irq(void) } for (i=0; i<NR_EXT_IRQS; i++) { - irq_desc[START_EXT_IRQS + i].handler = &cayman_irq_type; + irq_desc[START_EXT_IRQS + i].chip = &cayman_irq_type; } /* Setup the SMSC interrupt */ diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index ae4c667c906..79d177149fd 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -208,7 +208,7 @@ _sparc_ioremap(struct resource *res, u32 bus, u32 pa, int sz) pa &= PAGE_MASK; sparc_mapiorange(bus, pa, res->start, res->end - res->start + 1); - return (void __iomem *) (res->start + offset); + return (void __iomem *)(unsigned long)(res->start + offset); } /* @@ -325,7 +325,7 @@ void *sbus_alloc_consistent(struct sbus_dev *sdev, long len, u32 *dma_addrp) res->name = sdev->prom_name; } - return (void *)res->start; + return (void *)(unsigned long)res->start; err_noiommu: release_resource(res); @@ -819,7 +819,9 @@ _sparc_io_get_info(char *buf, char **start, off_t fpos, int length, int *eof, if (p + 32 >= e) /* Better than nothing */ break; if ((nm = r->name) == 0) nm = "???"; - p += sprintf(p, "%08lx-%08lx: %s\n", r->start, r->end, nm); + p += sprintf(p, "%016llx-%016llx: %s\n", + (unsigned long long)r->start, + (unsigned long long)r->end, nm); } return p-buf; diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c index 001b8673b4b..80a80947878 100644 --- a/arch/sparc/kernel/of_device.c +++ b/arch/sparc/kernel/of_device.c @@ -138,6 +138,7 @@ struct bus_type ebus_bus_type = { .suspend = of_device_suspend, .resume = of_device_resume, }; +EXPORT_SYMBOL(ebus_bus_type); #endif #ifdef CONFIG_SBUS @@ -149,6 +150,7 @@ struct bus_type sbus_bus_type = { .suspend = of_device_suspend, .resume = of_device_resume, }; +EXPORT_SYMBOL(sbus_bus_type); #endif static int __init of_bus_driver_init(void) diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index bcfdddd0418..5df3ebdc0ab 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -860,7 +860,7 @@ char * __init pcibios_setup(char *str) } void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { } diff --git a/arch/sparc/kernel/prom.c b/arch/sparc/kernel/prom.c index 63b2b9bd778..946ce6d1581 100644 --- a/arch/sparc/kernel/prom.c +++ b/arch/sparc/kernel/prom.c @@ -27,6 +27,11 @@ static struct device_node *allnodes; +/* use when traversing tree through the allnext, child, sibling, + * or parent members of struct device_node. + */ +static DEFINE_RWLOCK(devtree_lock); + int of_device_is_compatible(struct device_node *device, const char *compat) { const char* cp; @@ -185,6 +190,54 @@ int of_getintprop_default(struct device_node *np, const char *name, int def) } EXPORT_SYMBOL(of_getintprop_default); +int of_set_property(struct device_node *dp, const char *name, void *val, int len) +{ + struct property **prevp; + void *new_val; + int err; + + new_val = kmalloc(len, GFP_KERNEL); + if (!new_val) + return -ENOMEM; + + memcpy(new_val, val, len); + + err = -ENODEV; + + write_lock(&devtree_lock); + prevp = &dp->properties; + while (*prevp) { + struct property *prop = *prevp; + + if (!strcmp(prop->name, name)) { + void *old_val = prop->value; + int ret; + + ret = prom_setprop(dp->node, name, val, len); + err = -EINVAL; + if (ret >= 0) { + prop->value = new_val; + prop->length = len; + + if (OF_IS_DYNAMIC(prop)) + kfree(old_val); + + OF_MARK_DYNAMIC(prop); + + err = 0; + } + break; + } + prevp = &(*prevp)->next; + } + write_unlock(&devtree_lock); + + /* XXX Upate procfs if necessary... */ + + return err; +} +EXPORT_SYMBOL(of_set_property); + static unsigned int prom_early_allocated; static void * __init prom_early_alloc(unsigned long size) @@ -354,7 +407,9 @@ static char * __init build_full_name(struct device_node *dp) return n; } -static struct property * __init build_one_prop(phandle node, char *prev) +static unsigned int unique_id; + +static struct property * __init build_one_prop(phandle node, char *prev, char *special_name, void *special_val, int special_len) { static struct property *tmp = NULL; struct property *p; @@ -364,25 +419,34 @@ static struct property * __init build_one_prop(phandle node, char *prev) p = tmp; memset(p, 0, sizeof(*p) + 32); tmp = NULL; - } else + } else { p = prom_early_alloc(sizeof(struct property) + 32); + p->unique_id = unique_id++; + } p->name = (char *) (p + 1); - if (prev == NULL) { - prom_firstprop(node, p->name); + if (special_name) { + p->length = special_len; + p->value = prom_early_alloc(special_len); + memcpy(p->value, special_val, special_len); } else { - prom_nextprop(node, prev, p->name); - } - if (strlen(p->name) == 0) { - tmp = p; - return NULL; - } - p->length = prom_getproplen(node, p->name); - if (p->length <= 0) { - p->length = 0; - } else { - p->value = prom_early_alloc(p->length); - len = prom_getproperty(node, p->name, p->value, p->length); + if (prev == NULL) { + prom_firstprop(node, p->name); + } else { + prom_nextprop(node, prev, p->name); + } + if (strlen(p->name) == 0) { + tmp = p; + return NULL; + } + p->length = prom_getproplen(node, p->name); + if (p->length <= 0) { + p->length = 0; + } else { + p->value = prom_early_alloc(p->length + 1); + prom_getproperty(node, p->name, p->value, p->length); + ((unsigned char *)p->value)[p->length] = '\0'; + } } return p; } @@ -391,9 +455,14 @@ static struct property * __init build_prop_list(phandle node) { struct property *head, *tail; - head = tail = build_one_prop(node, NULL); + head = tail = build_one_prop(node, NULL, + ".node", &node, sizeof(node)); + + tail->next = build_one_prop(node, NULL, NULL, NULL, 0); + tail = tail->next; while(tail) { - tail->next = build_one_prop(node, tail->name); + tail->next = build_one_prop(node, tail->name, + NULL, NULL, 0); tail = tail->next; } @@ -422,6 +491,7 @@ static struct device_node * __init create_node(phandle node) return NULL; dp = prom_early_alloc(sizeof(*dp)); + dp->unique_id = unique_id++; kref_init(&dp->kref); diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c index a893a9cc953..2e5d08ce217 100644 --- a/arch/sparc/kernel/setup.c +++ b/arch/sparc/kernel/setup.c @@ -496,7 +496,7 @@ static int __init topology_init(void) if (!p) err = -ENOMEM; else - register_cpu(p, i, NULL); + register_cpu(p, i); } return err; diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile index fa500694606..5db7e1d8538 100644 --- a/arch/sparc/lib/Makefile +++ b/arch/sparc/lib/Makefile @@ -9,3 +9,5 @@ lib-y := mul.o rem.o sdiv.o udiv.o umul.o urem.o ashrdi3.o memcpy.o memset.o \ strncpy_from_user.o divdi3.o udivdi3.o strlen_user.o \ copy_user.o locks.o atomic.o atomic32.o bitops.o \ lshrdi3.o ashldi3.o rwsem.o muldi3.o bitext.o + +obj-y += iomap.o diff --git a/arch/sparc/lib/iomap.c b/arch/sparc/lib/iomap.c new file mode 100644 index 00000000000..54501c1ca78 --- /dev/null +++ b/arch/sparc/lib/iomap.c @@ -0,0 +1,48 @@ +/* + * Implement the sparc iomap interfaces + */ +#include <linux/pci.h> +#include <linux/module.h> +#include <asm/io.h> + +/* Create a virtual mapping cookie for an IO port range */ +void __iomem *ioport_map(unsigned long port, unsigned int nr) +{ + return (void __iomem *) (unsigned long) port; +} + +void ioport_unmap(void __iomem *addr) +{ + /* Nothing to do */ +} +EXPORT_SYMBOL(ioport_map); +EXPORT_SYMBOL(ioport_unmap); + +/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ +void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) +{ + unsigned long start = pci_resource_start(dev, bar); + unsigned long len = pci_resource_len(dev, bar); + unsigned long flags = pci_resource_flags(dev, bar); + + if (!len || !start) + return NULL; + if (maxlen && len > maxlen) + len = maxlen; + if (flags & IORESOURCE_IO) + return ioport_map(start, len); + if (flags & IORESOURCE_MEM) { + if (flags & IORESOURCE_CACHEABLE) + return ioremap(start, len); + return ioremap_nocache(start, len); + } + /* What? */ + return NULL; +} + +void pci_iounmap(struct pci_dev *dev, void __iomem * addr) +{ + /* nothing to do */ +} +EXPORT_SYMBOL(pci_iomap); +EXPORT_SYMBOL(pci_iounmap); diff --git a/arch/sparc64/kernel/auxio.c b/arch/sparc64/kernel/auxio.c index 2c42894b188..c2c69c167d1 100644 --- a/arch/sparc64/kernel/auxio.c +++ b/arch/sparc64/kernel/auxio.c @@ -6,6 +6,7 @@ */ #include <linux/config.h> +#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/ioport.h> @@ -16,8 +17,8 @@ #include <asm/ebus.h> #include <asm/auxio.h> -/* This cannot be static, as it is referenced in irq.c */ void __iomem *auxio_register = NULL; +EXPORT_SYMBOL(auxio_register); enum auxio_type { AUXIO_TYPE_NODEV, diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index 31e0fbb0d82..ab9e640df22 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -151,7 +151,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %9s", irq_desc[i].handler->typename); + seq_printf(p, " %9s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -224,7 +224,7 @@ static inline struct ino_bucket *virt_irq_to_bucket(unsigned int virt_irq) #ifdef CONFIG_SMP static int irq_choose_cpu(unsigned int virt_irq) { - cpumask_t mask = irq_affinity[virt_irq]; + cpumask_t mask = irq_desc[virt_irq].affinity; int cpuid; if (cpus_equal(mask, CPU_MASK_ALL)) { @@ -414,8 +414,8 @@ void irq_install_pre_handler(int virt_irq, data->pre_handler_arg1 = arg1; data->pre_handler_arg2 = arg2; - desc->handler = (desc->handler == &sun4u_irq ? - &sun4u_irq_ack : &sun4v_irq_ack); + desc->chip = (desc->chip == &sun4u_irq ? + &sun4u_irq_ack : &sun4v_irq_ack); } unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) @@ -431,7 +431,7 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) bucket = &ivector_table[ino]; if (!bucket->virt_irq) { bucket->virt_irq = virt_irq_alloc(__irq(bucket)); - irq_desc[bucket->virt_irq].handler = &sun4u_irq; + irq_desc[bucket->virt_irq].chip = &sun4u_irq; } desc = irq_desc + bucket->virt_irq; @@ -465,7 +465,7 @@ unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino) bucket = &ivector_table[sysino]; if (!bucket->virt_irq) { bucket->virt_irq = virt_irq_alloc(__irq(bucket)); - irq_desc[bucket->virt_irq].handler = &sun4v_irq; + irq_desc[bucket->virt_irq].chip = &sun4v_irq; } desc = irq_desc + bucket->virt_irq; @@ -563,67 +563,6 @@ void handler_irq(int irq, struct pt_regs *regs) irq_exit(); } -#ifdef CONFIG_BLK_DEV_FD -extern irqreturn_t floppy_interrupt(int, void *, struct pt_regs *); - -/* XXX No easy way to include asm/floppy.h XXX */ -extern unsigned char *pdma_vaddr; -extern unsigned long pdma_size; -extern volatile int doing_pdma; -extern unsigned long fdc_status; - -irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie, struct pt_regs *regs) -{ - if (likely(doing_pdma)) { - void __iomem *stat = (void __iomem *) fdc_status; - unsigned char *vaddr = pdma_vaddr; - unsigned long size = pdma_size; - u8 val; - - while (size) { - val = readb(stat); - if (unlikely(!(val & 0x80))) { - pdma_vaddr = vaddr; - pdma_size = size; - return IRQ_HANDLED; - } - if (unlikely(!(val & 0x20))) { - pdma_vaddr = vaddr; - pdma_size = size; - doing_pdma = 0; - goto main_interrupt; - } - if (val & 0x40) { - /* read */ - *vaddr++ = readb(stat + 1); - } else { - unsigned char data = *vaddr++; - - /* write */ - writeb(data, stat + 1); - } - size--; - } - - pdma_vaddr = vaddr; - pdma_size = size; - - /* Send Terminal Count pulse to floppy controller. */ - val = readb(auxio_register); - val |= AUXIO_AUX1_FTCNT; - writeb(val, auxio_register); - val &= ~AUXIO_AUX1_FTCNT; - writeb(val, auxio_register); - - doing_pdma = 0; - } - -main_interrupt: - return floppy_interrupt(irq, dev_cookie, regs); -} -EXPORT_SYMBOL(sparc_floppy_irq); -#endif - struct sun5_timer { u64 count0; u64 limit0; diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index 566aa343aa6..768475bbce8 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c @@ -138,6 +138,7 @@ struct bus_type isa_bus_type = { .suspend = of_device_suspend, .resume = of_device_resume, }; +EXPORT_SYMBOL(isa_bus_type); struct bus_type ebus_bus_type = { .name = "ebus", @@ -147,6 +148,7 @@ struct bus_type ebus_bus_type = { .suspend = of_device_suspend, .resume = of_device_resume, }; +EXPORT_SYMBOL(ebus_bus_type); #endif #ifdef CONFIG_SBUS @@ -158,6 +160,7 @@ struct bus_type sbus_bus_type = { .suspend = of_device_suspend, .resume = of_device_resume, }; +EXPORT_SYMBOL(sbus_bus_type); #endif static int __init of_bus_driver_init(void) diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 6c9e3e94aba..20ca9ec8fd3 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -357,7 +357,7 @@ void pcibios_update_irq(struct pci_dev *pdev, int irq) } void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { } diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index e9d703eea80..8e87e7ea032 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c @@ -27,6 +27,11 @@ static struct device_node *allnodes; +/* use when traversing tree through the allnext, child, sibling, + * or parent members of struct device_node. + */ +static DEFINE_RWLOCK(devtree_lock); + int of_device_is_compatible(struct device_node *device, const char *compat) { const char* cp; @@ -185,6 +190,54 @@ int of_getintprop_default(struct device_node *np, const char *name, int def) } EXPORT_SYMBOL(of_getintprop_default); +int of_set_property(struct device_node *dp, const char *name, void *val, int len) +{ + struct property **prevp; + void *new_val; + int err; + + new_val = kmalloc(len, GFP_KERNEL); + if (!new_val) + return -ENOMEM; + + memcpy(new_val, val, len); + + err = -ENODEV; + + write_lock(&devtree_lock); + prevp = &dp->properties; + while (*prevp) { + struct property *prop = *prevp; + + if (!strcmp(prop->name, name)) { + void *old_val = prop->value; + int ret; + + ret = prom_setprop(dp->node, name, val, len); + err = -EINVAL; + if (ret >= 0) { + prop->value = new_val; + prop->length = len; + + if (OF_IS_DYNAMIC(prop)) + kfree(old_val); + + OF_MARK_DYNAMIC(prop); + + err = 0; + } + break; + } + prevp = &(*prevp)->next; + } + write_unlock(&devtree_lock); + + /* XXX Upate procfs if necessary... */ + + return err; +} +EXPORT_SYMBOL(of_set_property); + static unsigned int prom_early_allocated; static void * __init prom_early_alloc(unsigned long size) @@ -531,7 +584,9 @@ static char * __init build_full_name(struct device_node *dp) return n; } -static struct property * __init build_one_prop(phandle node, char *prev) +static unsigned int unique_id; + +static struct property * __init build_one_prop(phandle node, char *prev, char *special_name, void *special_val, int special_len) { static struct property *tmp = NULL; struct property *p; @@ -540,25 +595,35 @@ static struct property * __init build_one_prop(phandle node, char *prev) p = tmp; memset(p, 0, sizeof(*p) + 32); tmp = NULL; - } else + } else { p = prom_early_alloc(sizeof(struct property) + 32); + p->unique_id = unique_id++; + } p->name = (char *) (p + 1); - if (prev == NULL) { - prom_firstprop(node, p->name); + if (special_name) { + strcpy(p->name, special_name); + p->length = special_len; + p->value = prom_early_alloc(special_len); + memcpy(p->value, special_val, special_len); } else { - prom_nextprop(node, prev, p->name); - } - if (strlen(p->name) == 0) { - tmp = p; - return NULL; - } - p->length = prom_getproplen(node, p->name); - if (p->length <= 0) { - p->length = 0; - } else { - p->value = prom_early_alloc(p->length); - prom_getproperty(node, p->name, p->value, p->length); + if (prev == NULL) { + prom_firstprop(node, p->name); + } else { + prom_nextprop(node, prev, p->name); + } + if (strlen(p->name) == 0) { + tmp = p; + return NULL; + } + p->length = prom_getproplen(node, p->name); + if (p->length <= 0) { + p->length = 0; + } else { + p->value = prom_early_alloc(p->length + 1); + prom_getproperty(node, p->name, p->value, p->length); + ((unsigned char *)p->value)[p->length] = '\0'; + } } return p; } @@ -567,9 +632,14 @@ static struct property * __init build_prop_list(phandle node) { struct property *head, *tail; - head = tail = build_one_prop(node, NULL); + head = tail = build_one_prop(node, NULL, + ".node", &node, sizeof(node)); + + tail->next = build_one_prop(node, NULL, NULL, NULL, 0); + tail = tail->next; while(tail) { - tail->next = build_one_prop(node, tail->name); + tail->next = build_one_prop(node, tail->name, + NULL, NULL, 0); tail = tail->next; } @@ -598,6 +668,7 @@ static struct device_node * __init create_node(phandle node) return NULL; dp = prom_early_alloc(sizeof(*dp)); + dp->unique_id = unique_id++; kref_init(&dp->kref); diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index a6a7d816834..116d9632002 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c @@ -537,7 +537,7 @@ static int __init topology_init(void) for_each_possible_cpu(i) { struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL); if (p) { - register_cpu(p, i, NULL); + register_cpu(p, i); err = 0; } } diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index 6e002aacb96..1605967cce9 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c @@ -31,6 +31,40 @@ #include <asm/kdebug.h> #include <asm/mmu_context.h> +#ifdef CONFIG_KPROBES +ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); + +/* Hook to register for page fault notifications */ +int register_page_fault_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); +} + +int unregister_page_fault_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); +} + +static inline int notify_page_fault(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + struct die_args args = { + .regs = regs, + .str = str, + .err = err, + .trapnr = trap, + .signr = sig + }; + return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); +} +#else +static inline int notify_page_fault(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + return NOTIFY_DONE; +} +#endif + /* * To debug kernel to catch accesses to certain virtual/physical addresses. * Mode = 0 selects physical watchpoints, mode = 1 selects virtual watchpoints. @@ -263,7 +297,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) fault_code = get_thread_fault_code(); - if (notify_die(DIE_PAGE_FAULT, "page_fault", regs, + if (notify_page_fault(DIE_PAGE_FAULT, "page_fault", regs, fault_code, 0, SIGSEGV) == NOTIFY_STOP) return; diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 51399341474..cb75a27adb5 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -18,6 +18,7 @@ #include <linux/initrd.h> #include <linux/swap.h> #include <linux/pagemap.h> +#include <linux/poison.h> #include <linux/fs.h> #include <linux/seq_file.h> #include <linux/kprobes.h> @@ -1520,7 +1521,7 @@ void free_initmem(void) page = (addr + ((unsigned long) __va(kern_base)) - ((unsigned long) KERNBASE)); - memset((void *)addr, 0xcc, PAGE_SIZE); + memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); p = virt_to_page(page); ClearPageReserved(p); @@ -1568,6 +1569,7 @@ pgprot_t PAGE_EXEC __read_mostly; unsigned long pg_iobits __read_mostly; unsigned long _PAGE_IE __read_mostly; +EXPORT_SYMBOL(_PAGE_IE); unsigned long _PAGE_E __read_mostly; EXPORT_SYMBOL(_PAGE_E); diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 0897852b09a..290cec6d69e 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -1222,7 +1222,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared, } } - /* Succesful return case! */ + /* Successful return case! */ if(backing_file_out == NULL) return(fd); diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 2ffda012385..fae43a3054a 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -63,7 +63,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -451,13 +451,13 @@ void __init init_IRQ(void) irq_desc[TIMER_IRQ].status = IRQ_DISABLED; irq_desc[TIMER_IRQ].action = NULL; irq_desc[TIMER_IRQ].depth = 1; - irq_desc[TIMER_IRQ].handler = &SIGVTALRM_irq_type; + irq_desc[TIMER_IRQ].chip = &SIGVTALRM_irq_type; enable_irq(TIMER_IRQ); for (i = 1; i < NR_IRQS; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].handler = &normal_irq_type; + irq_desc[i].chip = &normal_irq_type; enable_irq(i); } } diff --git a/arch/v850/kernel/irq.c b/arch/v850/kernel/irq.c index 7a151c26f82..858c45819aa 100644 --- a/arch/v850/kernel/irq.c +++ b/arch/v850/kernel/irq.c @@ -65,10 +65,10 @@ int show_interrupts(struct seq_file *p, void *v) int j; int count = 0; int num = -1; - const char *type_name = irq_desc[irq].handler->typename; + const char *type_name = irq_desc[irq].chip->typename; for (j = 0; j < NR_IRQS; j++) - if (irq_desc[j].handler->typename == type_name){ + if (irq_desc[j].chip->typename == type_name){ if (irq == j) num = count; count++; @@ -117,7 +117,7 @@ init_irq_handlers (int base_irq, int num, int interval, irq_desc[base_irq].status = IRQ_DISABLED; irq_desc[base_irq].action = NULL; irq_desc[base_irq].depth = 1; - irq_desc[base_irq].handler = irq_type; + irq_desc[base_irq].chip = irq_type; base_irq += interval; } } diff --git a/arch/v850/kernel/rte_mb_a_pci.c b/arch/v850/kernel/rte_mb_a_pci.c index ffbb6d073bf..3a7c5c9c3ac 100644 --- a/arch/v850/kernel/rte_mb_a_pci.c +++ b/arch/v850/kernel/rte_mb_a_pci.c @@ -329,7 +329,7 @@ void pcibios_fixup_bus(struct pci_bus *b) void pcibios_align_resource (void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { } diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index af44130f0d6..91039844820 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -370,6 +370,8 @@ config HOTPLUG_CPU can be controlled through /sys/devices/system/cpu/cpu#. Say N if you want to disable CPU hotplug. +config ARCH_ENABLE_MEMORY_HOTPLUG + def_bool y config HPET_TIMER bool @@ -386,24 +388,45 @@ config HPET_EMULATE_RTC bool "Provide RTC interrupt" depends on HPET_TIMER && RTC=y -config GART_IOMMU - bool "K8 GART IOMMU support" +# Mark as embedded because too many people got it wrong. +# The code disables itself when not needed. +config IOMMU + bool "IOMMU support" if EMBEDDED default y select SWIOTLB select AGP depends on PCI help - Support for hardware IOMMU in AMD's Opteron/Athlon64 Processors - and for the bounce buffering software IOMMU. - Needed to run systems with more than 3GB of memory properly with - 32-bit PCI devices that do not support DAC (Double Address Cycle). - The IOMMU can be turned off at runtime with the iommu=off parameter. - Normally the kernel will take the right choice by itself. - This option includes a driver for the AMD Opteron/Athlon64 IOMMU - northbridge and a software emulation used on other systems without - hardware IOMMU. If unsure, say Y. - -# need this always selected by GART_IOMMU for the VIA workaround + Support for full DMA access of devices with 32bit memory access only + on systems with more than 3GB. This is usually needed for USB, + sound, many IDE/SATA chipsets and some other devices. + Provides a driver for the AMD Athlon64/Opteron/Turion/Sempron GART + based IOMMU and a software bounce buffer based IOMMU used on Intel + systems and as fallback. + The code is only active when needed (enough memory and limited + device) unless CONFIG_IOMMU_DEBUG or iommu=force is specified + too. + +config CALGARY_IOMMU + bool "IBM Calgary IOMMU support" + default y + select SWIOTLB + depends on PCI && EXPERIMENTAL + help + Support for hardware IOMMUs in IBM's xSeries x366 and x460 + systems. Needed to run systems with more than 3GB of memory + properly with 32-bit PCI devices that do not support DAC + (Double Address Cycle). Calgary also supports bus level + isolation, where all DMAs pass through the IOMMU. This + prevents them from going anywhere except their intended + destination. This catches hard-to-find kernel bugs and + mis-behaving drivers and devices that do not use the DMA-API + properly to set up their DMA buffers. The IOMMU can be + turned off at boot time with the iommu=off parameter. + Normally the kernel will make the right choice by itself. + If unsure, say Y. + +# need this always selected by IOMMU for the VIA workaround config SWIOTLB bool @@ -501,6 +524,10 @@ config REORDER optimal TLB usage. If you have pretty much any version of binutils, this can increase your kernel build time by roughly one minute. +config K8_NB + def_bool y + depends on AGP_AMD64 || IOMMU || (PCI && NUMA) + endmenu # diff --git a/arch/x86_64/Kconfig.debug b/arch/x86_64/Kconfig.debug index ea31b4c6210..1d92ab56c0f 100644 --- a/arch/x86_64/Kconfig.debug +++ b/arch/x86_64/Kconfig.debug @@ -13,7 +13,7 @@ config DEBUG_RODATA If in doubt, say "N". config IOMMU_DEBUG - depends on GART_IOMMU && DEBUG_KERNEL + depends on IOMMU && DEBUG_KERNEL bool "Enable IOMMU debugging" help Force the IOMMU to on even when you have less than 4GB of @@ -35,6 +35,22 @@ 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 DEBUG_STACKOVERFLOW + bool "Check for stack overflows" + depends on DEBUG_KERNEL + help + This option will cause messages to be printed if free stack space + drops below a certain limit. + +config DEBUG_STACK_USAGE + bool "Stack utilization instrumentation" + depends on DEBUG_KERNEL + help + Enables the display of the minimum amount of free stack which each + task has ever had available in the sysrq-T and sysrq-P debug output. + + This option will slow down process creation somewhat. + #config X86_REMOTE_DEBUG # bool "kgdb debugging stub" diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile index e573e2ab551..431bb4bc36c 100644 --- a/arch/x86_64/Makefile +++ b/arch/x86_64/Makefile @@ -27,6 +27,7 @@ LDFLAGS_vmlinux := CHECKFLAGS += -D__x86_64__ -m64 cflags-y := +cflags-kernel-y := cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8) cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona) cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic) @@ -35,7 +36,7 @@ cflags-y += -m64 cflags-y += -mno-red-zone cflags-y += -mcmodel=kernel cflags-y += -pipe -cflags-$(CONFIG_REORDER) += -ffunction-sections +cflags-kernel-$(CONFIG_REORDER) += -ffunction-sections # this makes reading assembly source easier, but produces worse code # actually it makes the kernel smaller too. cflags-y += -fno-reorder-blocks @@ -55,6 +56,7 @@ cflags-y += $(call cc-option,-funit-at-a-time) cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,) CFLAGS += $(cflags-y) +CFLAGS_KERNEL += $(cflags-kernel-y) AFLAGS += -m64 head-y := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o diff --git a/arch/x86_64/boot/Makefile b/arch/x86_64/boot/Makefile index 43ee6c50c27..deb063e7762 100644 --- a/arch/x86_64/boot/Makefile +++ b/arch/x86_64/boot/Makefile @@ -107,8 +107,13 @@ fdimage288: $(BOOTIMAGE) $(obj)/mtools.conf isoimage: $(BOOTIMAGE) -rm -rf $(obj)/isoimage mkdir $(obj)/isoimage - cp `echo /usr/lib*/syslinux/isolinux.bin | awk '{ print $1; }'` \ - $(obj)/isoimage + for i in lib lib64 share end ; do \ + if [ -f /usr/$$i/syslinux/isolinux.bin ] ; then \ + cp /usr/$$i/syslinux/isolinux.bin $(obj)/isoimage ; \ + break ; \ + fi ; \ + if [ $$i = end ] ; then exit 1 ; fi ; \ + done cp $(BOOTIMAGE) $(obj)/isoimage/linux echo '$(image_cmdline)' > $(obj)/isoimage/isolinux.cfg if [ -f '$(FDINITRD)' ] ; then \ diff --git a/arch/x86_64/boot/compressed/misc.c b/arch/x86_64/boot/compressed/misc.c index cf4b88c416d..3755b2e394d 100644 --- a/arch/x86_64/boot/compressed/misc.c +++ b/arch/x86_64/boot/compressed/misc.c @@ -77,11 +77,11 @@ static void gzip_release(void **); */ static unsigned char *real_mode; /* Pointer to real-mode data */ -#define EXT_MEM_K (*(unsigned short *)(real_mode + 0x2)) +#define RM_EXT_MEM_K (*(unsigned short *)(real_mode + 0x2)) #ifndef STANDARD_MEMORY_BIOS_CALL -#define ALT_MEM_K (*(unsigned long *)(real_mode + 0x1e0)) +#define RM_ALT_MEM_K (*(unsigned long *)(real_mode + 0x1e0)) #endif -#define SCREEN_INFO (*(struct screen_info *)(real_mode+0)) +#define RM_SCREEN_INFO (*(struct screen_info *)(real_mode+0)) extern unsigned char input_data[]; extern int input_len; @@ -92,9 +92,9 @@ static unsigned long output_ptr = 0; static void *malloc(int size); static void free(void *where); - -void* memset(void* s, int c, unsigned n); -void* memcpy(void* dest, const void* src, unsigned n); + +static void *memset(void *s, int c, unsigned n); +static void *memcpy(void *dest, const void *src, unsigned n); static void putstr(const char *); @@ -162,8 +162,8 @@ static void putstr(const char *s) int x,y,pos; char c; - x = SCREEN_INFO.orig_x; - y = SCREEN_INFO.orig_y; + x = RM_SCREEN_INFO.orig_x; + y = RM_SCREEN_INFO.orig_y; while ( ( c = *s++ ) != '\0' ) { if ( c == '\n' ) { @@ -184,8 +184,8 @@ static void putstr(const char *s) } } - SCREEN_INFO.orig_x = x; - SCREEN_INFO.orig_y = y; + RM_SCREEN_INFO.orig_x = x; + RM_SCREEN_INFO.orig_y = y; pos = (x + cols * y) * 2; /* Update cursor position */ outb_p(14, vidport); @@ -194,7 +194,7 @@ static void putstr(const char *s) outb_p(0xff & (pos >> 1), vidport+1); } -void* memset(void* s, int c, unsigned n) +static void* memset(void* s, int c, unsigned n) { int i; char *ss = (char*)s; @@ -203,7 +203,7 @@ void* memset(void* s, int c, unsigned n) return s; } -void* memcpy(void* dest, const void* src, unsigned n) +static void* memcpy(void* dest, const void* src, unsigned n) { int i; char *d = (char *)dest, *s = (char *)src; @@ -278,15 +278,15 @@ static void error(char *x) putstr(x); putstr("\n\n -- System halted"); - while(1); + while(1); /* Halt */ } -void setup_normal_output_buffer(void) +static void setup_normal_output_buffer(void) { #ifdef STANDARD_MEMORY_BIOS_CALL - if (EXT_MEM_K < 1024) error("Less than 2MB of memory"); + if (RM_EXT_MEM_K < 1024) error("Less than 2MB of memory"); #else - if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory"); + if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < 1024) error("Less than 2MB of memory"); #endif output_data = (unsigned char *)__PHYSICAL_START; /* Normally Points to 1M */ free_mem_end_ptr = (long)real_mode; @@ -297,13 +297,13 @@ struct moveparams { uch *high_buffer_start; int hcount; }; -void setup_output_buffer_if_we_run_high(struct moveparams *mv) +static void setup_output_buffer_if_we_run_high(struct moveparams *mv) { high_buffer_start = (uch *)(((ulg)&end) + HEAP_SIZE); #ifdef STANDARD_MEMORY_BIOS_CALL - if (EXT_MEM_K < (3*1024)) error("Less than 4MB of memory"); + if (RM_EXT_MEM_K < (3*1024)) error("Less than 4MB of memory"); #else - if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory"); + if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory"); #endif mv->low_buffer_start = output_data = (unsigned char *)LOW_BUFFER_START; low_buffer_end = ((unsigned int)real_mode > LOW_BUFFER_MAX @@ -319,7 +319,7 @@ void setup_output_buffer_if_we_run_high(struct moveparams *mv) mv->high_buffer_start = high_buffer_start; } -void close_output_buffer_if_we_run_high(struct moveparams *mv) +static void close_output_buffer_if_we_run_high(struct moveparams *mv) { if (bytes_out > low_buffer_size) { mv->lcount = low_buffer_size; @@ -335,7 +335,7 @@ int decompress_kernel(struct moveparams *mv, void *rmode) { real_mode = rmode; - if (SCREEN_INFO.orig_video_mode == 7) { + if (RM_SCREEN_INFO.orig_video_mode == 7) { vidmem = (char *) 0xb0000; vidport = 0x3b4; } else { @@ -343,8 +343,8 @@ int decompress_kernel(struct moveparams *mv, void *rmode) vidport = 0x3d4; } - lines = SCREEN_INFO.orig_video_lines; - cols = SCREEN_INFO.orig_video_cols; + lines = RM_SCREEN_INFO.orig_video_lines; + cols = RM_SCREEN_INFO.orig_video_cols; if (free_mem_ptr < 0x100000) setup_normal_output_buffer(); else setup_output_buffer_if_we_run_high(mv); diff --git a/arch/x86_64/boot/tools/build.c b/arch/x86_64/boot/tools/build.c index c44f5e2ec10..eae86691709 100644 --- a/arch/x86_64/boot/tools/build.c +++ b/arch/x86_64/boot/tools/build.c @@ -149,10 +149,8 @@ int main(int argc, char ** argv) sz = sb.st_size; fprintf (stderr, "System is %d kB\n", sz/1024); sys_size = (sz + 15) / 16; - /* 0x40000*16 = 4.0 MB, reasonable estimate for the current maximum */ - if (sys_size > (is_big_kernel ? 0x40000 : DEF_SYSSIZE)) - die("System is too big. Try using %smodules.", - is_big_kernel ? "" : "bzImage or "); + if (!is_big_kernel && sys_size > DEF_SYSSIZE) + die("System is too big. Try using bzImage or modules."); while (sz > 0) { int l, n; diff --git a/arch/x86_64/boot/video.S b/arch/x86_64/boot/video.S index 32327bb37af..2aa565c136e 100644 --- a/arch/x86_64/boot/video.S +++ b/arch/x86_64/boot/video.S @@ -1929,6 +1929,7 @@ skip10: movb %ah, %al ret store_edid: +#ifdef CONFIG_FIRMWARE_EDID pushw %es # just save all registers pushw %ax pushw %bx @@ -1946,6 +1947,22 @@ store_edid: rep stosl + pushw %es # save ES + xorw %di, %di # Report Capability + pushw %di + popw %es # ES:DI must be 0:0 + movw $0x4f15, %ax + xorw %bx, %bx + xorw %cx, %cx + int $0x10 + popw %es # restore ES + + cmpb $0x00, %ah # call successful + jne no_edid + + cmpb $0x4f, %al # function supported + jne no_edid + movw $0x4f15, %ax # do VBE/DDC movw $0x01, %bx movw $0x00, %cx @@ -1953,12 +1970,14 @@ store_edid: movw $0x140, %di int $0x10 +no_edid: popw %di # restore all registers popw %dx popw %cx popw %bx popw %ax popw %es +#endif ret # VIDEO_SELECT-only variables diff --git a/arch/x86_64/crypto/aes-x86_64-asm.S b/arch/x86_64/crypto/aes-x86_64-asm.S index 483cbb23ab8..26b40de4d0b 100644 --- a/arch/x86_64/crypto/aes-x86_64-asm.S +++ b/arch/x86_64/crypto/aes-x86_64-asm.S @@ -15,6 +15,10 @@ .text +#include <asm/asm-offsets.h> + +#define BASE crypto_tfm_ctx_offset + #define R1 %rax #define R1E %eax #define R1X %ax @@ -46,19 +50,19 @@ #define R10 %r10 #define R11 %r11 -#define prologue(FUNC,BASE,B128,B192,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11) \ +#define prologue(FUNC,KEY,B128,B192,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11) \ .global FUNC; \ .type FUNC,@function; \ .align 8; \ FUNC: movq r1,r2; \ movq r3,r4; \ - leaq BASE+52(r8),r9; \ + leaq BASE+KEY+52(r8),r9; \ movq r10,r11; \ movl (r7),r5 ## E; \ movl 4(r7),r1 ## E; \ movl 8(r7),r6 ## E; \ movl 12(r7),r7 ## E; \ - movl (r8),r10 ## E; \ + movl BASE(r8),r10 ## E; \ xorl -48(r9),r5 ## E; \ xorl -44(r9),r1 ## E; \ xorl -40(r9),r6 ## E; \ @@ -128,8 +132,8 @@ FUNC: movq r1,r2; \ movl r3 ## E,r1 ## E; \ movl r4 ## E,r2 ## E; -#define entry(FUNC,BASE,B128,B192) \ - prologue(FUNC,BASE,B128,B192,R2,R8,R7,R9,R1,R3,R4,R6,R10,R5,R11) +#define entry(FUNC,KEY,B128,B192) \ + prologue(FUNC,KEY,B128,B192,R2,R8,R7,R9,R1,R3,R4,R6,R10,R5,R11) #define return epilogue(R8,R2,R9,R7,R5,R6,R3,R4,R11) @@ -147,9 +151,9 @@ FUNC: movq r1,r2; \ #define decrypt_final(TAB,OFFSET) \ round(TAB,OFFSET,R2,R1,R4,R3,R6,R5,R7,R10,R5,R6,R3,R4) -/* void aes_encrypt(void *ctx, u8 *out, const u8 *in) */ +/* void aes_enc_blk(stuct crypto_tfm *tfm, u8 *out, const u8 *in) */ - entry(aes_encrypt,0,enc128,enc192) + entry(aes_enc_blk,0,enc128,enc192) encrypt_round(aes_ft_tab,-96) encrypt_round(aes_ft_tab,-80) enc192: encrypt_round(aes_ft_tab,-64) @@ -166,9 +170,9 @@ enc128: encrypt_round(aes_ft_tab,-32) encrypt_final(aes_fl_tab,112) return -/* void aes_decrypt(void *ctx, u8 *out, const u8 *in) */ +/* void aes_dec_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in) */ - entry(aes_decrypt,240,dec128,dec192) + entry(aes_dec_blk,240,dec128,dec192) decrypt_round(aes_it_tab,-96) decrypt_round(aes_it_tab,-80) dec192: decrypt_round(aes_it_tab,-64) diff --git a/arch/x86_64/crypto/aes.c b/arch/x86_64/crypto/aes.c index 6f77e7700d3..68866fab37a 100644 --- a/arch/x86_64/crypto/aes.c +++ b/arch/x86_64/crypto/aes.c @@ -227,10 +227,10 @@ static void __init gen_tabs(void) t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t; \ } -static int aes_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, - u32 *flags) +static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, + unsigned int key_len, u32 *flags) { - struct aes_ctx *ctx = ctx_arg; + struct aes_ctx *ctx = crypto_tfm_ctx(tfm); const __le32 *key = (const __le32 *)in_key; u32 i, j, t, u, v, w; @@ -283,8 +283,18 @@ static int aes_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, return 0; } -extern void aes_encrypt(void *ctx_arg, u8 *out, const u8 *in); -extern void aes_decrypt(void *ctx_arg, u8 *out, const u8 *in); +asmlinkage void aes_enc_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in); +asmlinkage void aes_dec_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in); + +static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +{ + aes_enc_blk(tfm, dst, src); +} + +static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +{ + aes_dec_blk(tfm, dst, src); +} static struct crypto_alg aes_alg = { .cra_name = "aes", diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig index 69db0c0721d..e69d403949c 100644 --- a/arch/x86_64/defconfig +++ b/arch/x86_64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-rc1-git11 -# Sun Apr 16 07:22:36 2006 +# Linux kernel version: 2.6.17-git6 +# Sat Jun 24 00:52:28 2006 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -42,7 +42,6 @@ CONFIG_IKCONFIG_PROC=y # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_UID16=y -CONFIG_VM86=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y @@ -57,7 +56,6 @@ CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y -CONFIG_DOUBLEFAULT=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -144,7 +142,8 @@ CONFIG_NR_CPUS=32 CONFIG_HOTPLUG_CPU=y CONFIG_HPET_TIMER=y CONFIG_HPET_EMULATE_RTC=y -CONFIG_GART_IOMMU=y +CONFIG_IOMMU=y +# CONFIG_CALGARY_IOMMU is not set CONFIG_SWIOTLB=y CONFIG_X86_MCE=y CONFIG_X86_MCE_INTEL=y @@ -158,6 +157,7 @@ CONFIG_HZ_250=y # CONFIG_HZ_1000 is not set CONFIG_HZ=250 # CONFIG_REORDER is not set +CONFIG_K8_NB=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_ISA_DMA_API=y @@ -293,6 +293,8 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -305,7 +307,10 @@ CONFIG_IPV6=y # CONFIG_INET6_IPCOMP is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET6_XFRM_MODE_TUNNEL is not set # CONFIG_IPV6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set # @@ -344,6 +349,7 @@ CONFIG_IPV6=y # Network testing # # CONFIG_NET_PKTGEN is not set +# CONFIG_NET_TCPPROBE is not set # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set @@ -360,6 +366,7 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y # CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker @@ -526,6 +533,7 @@ CONFIG_SCSI_ATA_PIIX=y # CONFIG_SCSI_SATA_MV is not set CONFIG_SCSI_SATA_NV=y # CONFIG_SCSI_PDC_ADMA is not set +# CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_SATA_QSTOR is not set # CONFIG_SCSI_SATA_PROMISE is not set # CONFIG_SCSI_SATA_SX4 is not set @@ -591,10 +599,7 @@ CONFIG_IEEE1394=y # # Device Drivers # - -# -# Texas Instruments PCILynx requires I2C -# +# CONFIG_IEEE1394_PCILYNX is not set CONFIG_IEEE1394_OHCI1394=y # @@ -645,7 +650,16 @@ CONFIG_VORTEX=y # # Tulip family network device support # -# CONFIG_NET_TULIP is not set +CONFIG_NET_TULIP=y +# CONFIG_DE2104X is not set +CONFIG_TULIP=y +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_NAPI is not set +# CONFIG_DE4X5 is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_DM9102 is not set +# CONFIG_ULI526X is not set # CONFIG_HP100 is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set @@ -697,6 +711,7 @@ CONFIG_TIGON3=y # CONFIG_IXGB is not set CONFIG_S2IO=m # CONFIG_S2IO_NAPI is not set +# CONFIG_MYRI10GE is not set # # Token Ring devices @@ -887,7 +902,56 @@ CONFIG_HPET_MMAP=y # # I2C support # -# CONFIG_I2C is not set +CONFIG_I2C=m +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +CONFIG_I2C_ISA=m +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set # # SPI support @@ -898,14 +962,51 @@ CONFIG_HPET_MMAP=y # # Dallas's 1-wire bus # -# CONFIG_W1 is not set # # Hardware Monitoring support # CONFIG_HWMON=y # CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +CONFIG_SENSORS_SMSC47B397=m +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set # CONFIG_SENSORS_HDAPS is not set # CONFIG_HWMON_DEBUG_CHIP is not set @@ -918,6 +1019,7 @@ CONFIG_HWMON=y # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -953,28 +1055,17 @@ CONFIG_SOUND=y # Open Sound System # CONFIG_SOUND_PRIME=y -CONFIG_OBSOLETE_OSS_DRIVER=y # CONFIG_SOUND_BT878 is not set -# CONFIG_SOUND_CMPCI is not set # CONFIG_SOUND_EMU10K1 is not set # CONFIG_SOUND_FUSION is not set -# CONFIG_SOUND_CS4281 is not set -# CONFIG_SOUND_ES1370 is not set # CONFIG_SOUND_ES1371 is not set -# CONFIG_SOUND_ESSSOLO1 is not set -# CONFIG_SOUND_MAESTRO is not set -# CONFIG_SOUND_MAESTRO3 is not set CONFIG_SOUND_ICH=y -# CONFIG_SOUND_SONICVIBES is not set # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set # CONFIG_SOUND_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set -# CONFIG_SOUND_ALI5455 is not set -# CONFIG_SOUND_FORTE is not set -# CONFIG_SOUND_RME96XX is not set -# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_TVMIXER is not set # # USB support @@ -1000,6 +1091,7 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_EHCI_TT_NEWSCHED is not set # CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=y # CONFIG_USB_OHCI_BIG_ENDIAN is not set @@ -1089,10 +1181,12 @@ CONFIG_USB_MON=y # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set +# CONFIG_USB_CY7C63 is not set # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set # CONFIG_USB_TEST is not set @@ -1141,6 +1235,19 @@ CONFIG_USB_MON=y # CONFIG_RTC_CLASS is not set # +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# # Firmware Drivers # # CONFIG_EDD is not set @@ -1175,6 +1282,7 @@ CONFIG_FS_POSIX_ACL=y # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y CONFIG_AUTOFS_FS=y @@ -1331,7 +1439,8 @@ CONFIG_DETECT_SOFTLOCKUP=y CONFIG_DEBUG_FS=y # CONFIG_DEBUG_VM is not set # CONFIG_FRAME_POINTER is not set -# CONFIG_UNWIND_INFO is not set +CONFIG_UNWIND_INFO=y +CONFIG_STACK_UNWIND=y # CONFIG_FORCED_INLINING is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_RODATA is not set diff --git a/arch/x86_64/ia32/fpu32.c b/arch/x86_64/ia32/fpu32.c index 1c23095f181..2c8209a3605 100644 --- a/arch/x86_64/ia32/fpu32.c +++ b/arch/x86_64/ia32/fpu32.c @@ -2,7 +2,6 @@ * Copyright 2002 Andi Kleen, SuSE Labs. * FXSAVE<->i387 conversion support. Based on code by Gareth Hughes. * This is used for ptrace, signals and coredumps in 32bit emulation. - * $Id: fpu32.c,v 1.1 2002/03/21 14:16:32 ak Exp $ */ #include <linux/sched.h> diff --git a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c index e0a92439f63..25e5ca22204 100644 --- a/arch/x86_64/ia32/ia32_signal.c +++ b/arch/x86_64/ia32/ia32_signal.c @@ -6,8 +6,6 @@ * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes * 2000-12-* x86-64 compatibility mode signal handling by Andi Kleen - * - * $Id: ia32_signal.c,v 1.22 2002/07/29 10:34:03 ak Exp $ */ #include <linux/sched.h> diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S index 4ec594ab1a9..c536fa98ea3 100644 --- a/arch/x86_64/ia32/ia32entry.S +++ b/arch/x86_64/ia32/ia32entry.S @@ -155,6 +155,7 @@ sysenter_tracesys: .previous jmp sysenter_do_call CFI_ENDPROC +ENDPROC(ia32_sysenter_target) /* * 32bit SYSCALL instruction entry. @@ -178,7 +179,7 @@ sysenter_tracesys: */ ENTRY(ia32_cstar_target) CFI_STARTPROC32 simple - CFI_DEF_CFA rsp,0 + CFI_DEF_CFA rsp,PDA_STACKOFFSET CFI_REGISTER rip,rcx /*CFI_REGISTER rflags,r11*/ swapgs @@ -249,6 +250,7 @@ cstar_tracesys: .quad 1b,ia32_badarg .previous jmp cstar_do_call +END(ia32_cstar_target) ia32_badarg: movq $-EFAULT,%rax @@ -314,16 +316,13 @@ ia32_tracesys: LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */ RESTORE_REST jmp ia32_do_syscall +END(ia32_syscall) ia32_badsys: movq $0,ORIG_RAX-ARGOFFSET(%rsp) movq $-ENOSYS,RAX-ARGOFFSET(%rsp) jmp int_ret_from_sys_call -ni_syscall: - movq %rax,%rdi - jmp sys32_ni_syscall - quiet_ni_syscall: movq $-ENOSYS,%rax ret @@ -370,10 +369,10 @@ ENTRY(ia32_ptregs_common) RESTORE_REST jmp ia32_sysret /* misbalances the return cache */ CFI_ENDPROC +END(ia32_ptregs_common) .section .rodata,"a" .align 8 - .globl ia32_sys_call_table ia32_sys_call_table: .quad sys_restart_syscall .quad sys_exit diff --git a/arch/x86_64/ia32/ptrace32.c b/arch/x86_64/ia32/ptrace32.c index 23a4515a73b..a590b7a0d92 100644 --- a/arch/x86_64/ia32/ptrace32.c +++ b/arch/x86_64/ia32/ptrace32.c @@ -7,8 +7,6 @@ * * This allows to access 64bit processes too; but there is no way to see the extended * register contents. - * - * $Id: ptrace32.c,v 1.16 2003/03/14 16:06:35 ak Exp $ */ #include <linux/kernel.h> @@ -27,6 +25,7 @@ #include <asm/debugreg.h> #include <asm/i387.h> #include <asm/fpu32.h> +#include <asm/ia32.h> /* * Determines which flags the user has access to [1 = access, 0 = no access]. @@ -199,6 +198,24 @@ static int getreg32(struct task_struct *child, unsigned regno, u32 *val) #undef R32 +static long ptrace32_siginfo(unsigned request, u32 pid, u32 addr, u32 data) +{ + int ret; + compat_siginfo_t *si32 = (compat_siginfo_t *)compat_ptr(data); + siginfo_t *si = compat_alloc_user_space(sizeof(siginfo_t)); + if (request == PTRACE_SETSIGINFO) { + ret = copy_siginfo_from_user32(si, si32); + if (ret) + return ret; + } + ret = sys_ptrace(request, pid, addr, (unsigned long)si); + if (ret) + return ret; + if (request == PTRACE_GETSIGINFO) + ret = copy_siginfo_to_user32(si32, si); + return ret; +} + asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) { struct task_struct *child; @@ -208,9 +225,19 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) __u32 val; switch (request) { - default: + case PTRACE_TRACEME: + case PTRACE_ATTACH: + case PTRACE_KILL: + case PTRACE_CONT: + case PTRACE_SINGLESTEP: + case PTRACE_DETACH: + case PTRACE_SYSCALL: + case PTRACE_SETOPTIONS: return sys_ptrace(request, pid, addr, data); + default: + return -EINVAL; + case PTRACE_PEEKTEXT: case PTRACE_PEEKDATA: case PTRACE_POKEDATA: @@ -225,10 +252,11 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) case PTRACE_GETFPXREGS: case PTRACE_GETEVENTMSG: break; - } - if (request == PTRACE_TRACEME) - return ptrace_traceme(); + case PTRACE_SETSIGINFO: + case PTRACE_GETSIGINFO: + return ptrace32_siginfo(request, pid, addr, data); + } child = ptrace_get_task_struct(pid); if (IS_ERR(child)) @@ -349,8 +377,7 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) break; default: - ret = -EINVAL; - break; + BUG(); } out: diff --git a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c index f182b20858e..dc88154c412 100644 --- a/arch/x86_64/ia32/sys_ia32.c +++ b/arch/x86_64/ia32/sys_ia32.c @@ -508,19 +508,6 @@ sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, int options) return compat_sys_wait4(pid, stat_addr, options, NULL); } -int sys32_ni_syscall(int call) -{ - struct task_struct *me = current; - static char lastcomm[sizeof(me->comm)]; - - if (strncmp(lastcomm, me->comm, sizeof(lastcomm))) { - printk(KERN_INFO "IA32 syscall %d from %s not implemented\n", - call, me->comm); - strncpy(lastcomm, me->comm, sizeof(lastcomm)); - } - return -ENOSYS; -} - /* 32-bit timeval and related flotsam. */ asmlinkage long @@ -916,7 +903,7 @@ long sys32_vm86_warning(void) struct task_struct *me = current; static char lastcomm[sizeof(me->comm)]; if (strncmp(lastcomm, me->comm, sizeof(lastcomm))) { - printk(KERN_INFO "%s: vm86 mode not supported on 64 bit kernel\n", + compat_printk(KERN_INFO "%s: vm86 mode not supported on 64 bit kernel\n", me->comm); strncpy(lastcomm, me->comm, sizeof(lastcomm)); } @@ -929,13 +916,3 @@ long sys32_lookup_dcookie(u32 addr_low, u32 addr_high, return sys_lookup_dcookie(((u64)addr_high << 32) | addr_low, buf, len); } -static int __init ia32_init (void) -{ - printk("IA32 emulation $Id: sys_ia32.c,v 1.32 2002/03/24 13:02:28 ak Exp $\n"); - return 0; -} - -__initcall(ia32_init); - -extern unsigned long ia32_sys_call_table[]; -EXPORT_SYMBOL(ia32_sys_call_table); diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile index 059c88313f4..aeb9c560be8 100644 --- a/arch/x86_64/kernel/Makefile +++ b/arch/x86_64/kernel/Makefile @@ -8,7 +8,7 @@ obj-y := process.o signal.o entry.o traps.o irq.o \ ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \ x8664_ksyms.o i387.o syscall.o vsyscall.o \ setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o \ - pci-dma.o pci-nommu.o + pci-dma.o pci-nommu.o alternative.o obj-$(CONFIG_X86_MCE) += mce.o obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o @@ -28,11 +28,13 @@ obj-$(CONFIG_PM) += suspend.o obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend_asm.o obj-$(CONFIG_CPU_FREQ) += cpufreq/ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o -obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o +obj-$(CONFIG_IOMMU) += pci-gart.o aperture.o +obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary.o tce.o obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o obj-$(CONFIG_X86_VSMP) += vsmp.o +obj-$(CONFIG_K8_NB) += k8.o obj-$(CONFIG_MODULES) += module.o @@ -49,3 +51,5 @@ intel_cacheinfo-y += ../../i386/kernel/cpu/intel_cacheinfo.o quirks-y += ../../i386/kernel/quirks.o i8237-y += ../../i386/kernel/i8237.o msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o +alternative-y += ../../i386/kernel/alternative.o + diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c index 70b9d21ed67..a195ef06ec5 100644 --- a/arch/x86_64/kernel/aperture.c +++ b/arch/x86_64/kernel/aperture.c @@ -8,7 +8,6 @@ * because only the bootmem allocator can allocate 32+MB. * * Copyright 2002 Andi Kleen, SuSE Labs. - * $Id: aperture.c,v 1.7 2003/08/01 03:36:18 ak Exp $ */ #include <linux/config.h> #include <linux/kernel.h> @@ -24,6 +23,7 @@ #include <asm/proto.h> #include <asm/pci-direct.h> #include <asm/dma.h> +#include <asm/k8.h> int iommu_aperture; int iommu_aperture_disabled __initdata = 0; @@ -37,8 +37,6 @@ int fix_aperture __initdata = 1; /* This code runs before the PCI subsystem is initialized, so just access the northbridge directly. */ -#define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16)) - static u32 __init allocate_aperture(void) { pg_data_t *nd0 = NODE_DATA(0); @@ -68,20 +66,20 @@ static u32 __init allocate_aperture(void) return (u32)__pa(p); } -static int __init aperture_valid(char *name, u64 aper_base, u32 aper_size) +static int __init aperture_valid(u64 aper_base, u32 aper_size) { if (!aper_base) return 0; if (aper_size < 64*1024*1024) { - printk("Aperture from %s too small (%d MB)\n", name, aper_size>>20); + printk("Aperture too small (%d MB)\n", aper_size>>20); return 0; } if (aper_base + aper_size >= 0xffffffff) { - printk("Aperture from %s beyond 4GB. Ignoring.\n",name); + printk("Aperture beyond 4GB. Ignoring.\n"); return 0; } if (e820_any_mapped(aper_base, aper_base + aper_size, E820_RAM)) { - printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name); + printk("Aperture pointing to e820 RAM. Ignoring.\n"); return 0; } return 1; @@ -140,7 +138,7 @@ static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order) printk("Aperture from AGP @ %Lx size %u MB (APSIZE %x)\n", aper, 32 << *order, apsizereg); - if (!aperture_valid("AGP bridge", aper, (32*1024*1024) << *order)) + if (!aperture_valid(aper, (32*1024*1024) << *order)) return 0; return (u32)aper; } @@ -208,10 +206,10 @@ void __init iommu_hole_init(void) fix = 0; for (num = 24; num < 32; num++) { - char name[30]; - if (read_pci_config(0, num, 3, 0x00) != NB_ID_3) - continue; + if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00))) + continue; + iommu_detected = 1; iommu_aperture = 1; aper_order = (read_pci_config(0, num, 3, 0x90) >> 1) & 7; @@ -222,9 +220,7 @@ void __init iommu_hole_init(void) printk("CPU %d: aperture @ %Lx size %u MB\n", num-24, aper_base, aper_size>>20); - sprintf(name, "northbridge cpu %d", num-24); - - if (!aperture_valid(name, aper_base, aper_size)) { + if (!aperture_valid(aper_base, aper_size)) { fix = 1; break; } @@ -273,7 +269,7 @@ void __init iommu_hole_init(void) /* Fix up the north bridges */ for (num = 24; num < 32; num++) { - if (read_pci_config(0, num, 3, 0x00) != NB_ID_3) + if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00))) continue; /* Don't enable translation yet. That is done later. diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c index 29ef99001e0..b2ead91df21 100644 --- a/arch/x86_64/kernel/apic.c +++ b/arch/x86_64/kernel/apic.c @@ -100,7 +100,7 @@ void clear_local_APIC(void) maxlvt = get_maxlvt(); /* - * Masking an LVT entry on a P6 can trigger a local APIC error + * Masking an LVT entry can trigger a local APIC error * if the vector is zero. Mask LVTERR first to prevent this. */ if (maxlvt >= 3) { @@ -851,7 +851,18 @@ void disable_APIC_timer(void) unsigned long v; v = apic_read(APIC_LVTT); - apic_write(APIC_LVTT, v | APIC_LVT_MASKED); + /* + * When an illegal vector value (0-15) is written to an LVT + * entry and delivery mode is Fixed, the APIC may signal an + * illegal vector error, with out regard to whether the mask + * bit is set or whether an interrupt is actually seen on input. + * + * Boot sequence might call this function when the LVTT has + * '0' vector value. So make sure vector field is set to + * valid value. + */ + v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); + apic_write(APIC_LVTT, v); } } @@ -909,15 +920,13 @@ int setup_profiling_timer(unsigned int multiplier) return -EINVAL; } -#ifdef CONFIG_X86_MCE_AMD -void setup_threshold_lvt(unsigned long lvt_off) +void setup_APIC_extened_lvt(unsigned char lvt_off, unsigned char vector, + unsigned char msg_type, unsigned char mask) { - unsigned int v = 0; - unsigned long reg = (lvt_off << 4) + 0x500; - v |= THRESHOLD_APIC_VECTOR; + unsigned long reg = (lvt_off << 4) + K8_APIC_EXT_LVT_BASE; + unsigned int v = (mask << 16) | (msg_type << 8) | vector; apic_write(reg, v); } -#endif /* CONFIG_X86_MCE_AMD */ #undef APIC_DIVISOR @@ -983,7 +992,7 @@ void smp_apic_timer_interrupt(struct pt_regs *regs) } /* - * oem_force_hpet_timer -- force HPET mode for some boxes. + * apic_is_clustered_box() -- Check if we can expect good TSC * * Thus far, the major user of this is IBM's Summit2 series: * @@ -991,7 +1000,7 @@ void smp_apic_timer_interrupt(struct pt_regs *regs) * multi-chassis. Use available data to take a good guess. * If in doubt, go HPET. */ -__cpuinit int oem_force_hpet_timer(void) +__cpuinit int apic_is_clustered_box(void) { int i, clusters, zeros; unsigned id; @@ -1022,8 +1031,7 @@ __cpuinit int oem_force_hpet_timer(void) } /* - * If clusters > 2, then should be multi-chassis. Return 1 for HPET. - * Else return 0 to use TSC. + * If clusters > 2, then should be multi-chassis. * May have to revisit this when multi-core + hyperthreaded CPUs come * out, but AFAIK this will work even for them. */ diff --git a/arch/x86_64/kernel/asm-offsets.c b/arch/x86_64/kernel/asm-offsets.c index 38834bbbae1..96687e2beb2 100644 --- a/arch/x86_64/kernel/asm-offsets.c +++ b/arch/x86_64/kernel/asm-offsets.c @@ -4,6 +4,7 @@ * and format the required data. */ +#include <linux/crypto.h> #include <linux/sched.h> #include <linux/stddef.h> #include <linux/errno.h> @@ -68,5 +69,7 @@ int main(void) DEFINE(pbe_next, offsetof(struct pbe, next)); BLANK(); DEFINE(TSS_ist, offsetof(struct tss_struct, ist)); + BLANK(); + DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx)); return 0; } diff --git a/arch/x86_64/kernel/crash.c b/arch/x86_64/kernel/crash.c index 4e6c3b729e3..d8d5750d610 100644 --- a/arch/x86_64/kernel/crash.c +++ b/arch/x86_64/kernel/crash.c @@ -111,14 +111,14 @@ static int crash_nmi_callback(struct pt_regs *regs, int cpu) atomic_dec(&waiting_for_crash_ipi); /* Assume hlt works */ for(;;) - asm("hlt"); + halt(); return 1; } static void smp_send_nmi_allbutself(void) { - send_IPI_allbutself(APIC_DM_NMI); + send_IPI_allbutself(NMI_VECTOR); } /* @@ -161,7 +161,7 @@ void machine_crash_shutdown(struct pt_regs *regs) { /* * This function is only called after the system - * has paniced or is otherwise in a critical state. + * has panicked or is otherwise in a critical state. * The minimum amount of code to allow a kexec'd kernel * to run successfully needs to happen here. * diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c index 1ef6028f721..9e94d834624 100644 --- a/arch/x86_64/kernel/e820.c +++ b/arch/x86_64/kernel/e820.c @@ -1,7 +1,6 @@ /* * Handle the memory map. * The functions here do the job until bootmem takes over. - * $Id: e820.c,v 1.4 2002/09/19 19:25:32 ak Exp $ * * Getting sanitize_e820_map() in sync with i386 version by applying change: * - Provisions for empty E820 memory regions (reported by certain BIOSes). @@ -621,6 +620,7 @@ void __init parse_memmapopt(char *p, char **from) } unsigned long pci_mem_start = 0xaeedbabe; +EXPORT_SYMBOL(pci_mem_start); /* * Search for the biggest gap in the low 32 bits of the e820 diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index 586b34c00c4..22cac4487b5 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S @@ -154,6 +154,7 @@ rff_trace: GET_THREAD_INFO(%rcx) jmp rff_action CFI_ENDPROC +END(ret_from_fork) /* * System call entry. Upto 6 arguments in registers are supported. @@ -188,7 +189,7 @@ rff_trace: ENTRY(system_call) CFI_STARTPROC simple - CFI_DEF_CFA rsp,0 + CFI_DEF_CFA rsp,PDA_STACKOFFSET CFI_REGISTER rip,rcx /*CFI_REGISTER rflags,r11*/ swapgs @@ -285,6 +286,7 @@ tracesys: /* Use IRET because user could have changed frame */ jmp int_ret_from_sys_call CFI_ENDPROC +END(system_call) /* * Syscall return path ending with IRET. @@ -364,6 +366,7 @@ int_restore_rest: cli jmp int_with_check CFI_ENDPROC +END(int_ret_from_sys_call) /* * Certain special system calls that need to save a complete full stack frame. @@ -375,6 +378,7 @@ int_restore_rest: leaq \func(%rip),%rax leaq -ARGOFFSET+8(%rsp),\arg /* 8 for return address */ jmp ptregscall_common +END(\label) .endm CFI_STARTPROC @@ -404,6 +408,7 @@ ENTRY(ptregscall_common) CFI_REL_OFFSET rip, 0 ret CFI_ENDPROC +END(ptregscall_common) ENTRY(stub_execve) CFI_STARTPROC @@ -418,6 +423,7 @@ ENTRY(stub_execve) RESTORE_REST jmp int_ret_from_sys_call CFI_ENDPROC +END(stub_execve) /* * sigreturn is special because it needs to restore all registers on return. @@ -435,6 +441,7 @@ ENTRY(stub_rt_sigreturn) RESTORE_REST jmp int_ret_from_sys_call CFI_ENDPROC +END(stub_rt_sigreturn) /* * initial frame state for interrupts and exceptions @@ -466,29 +473,18 @@ ENTRY(stub_rt_sigreturn) /* 0(%rsp): interrupt number */ .macro interrupt func cld -#ifdef CONFIG_DEBUG_INFO - SAVE_ALL - movq %rsp,%rdi - /* - * Setup a stack frame pointer. This allows gdb to trace - * back to the original stack. - */ - movq %rsp,%rbp - CFI_DEF_CFA_REGISTER rbp -#else SAVE_ARGS leaq -ARGOFFSET(%rsp),%rdi # arg1 for handler -#endif + pushq %rbp + CFI_ADJUST_CFA_OFFSET 8 + CFI_REL_OFFSET rbp, 0 + movq %rsp,%rbp + CFI_DEF_CFA_REGISTER rbp testl $3,CS(%rdi) je 1f swapgs 1: incl %gs:pda_irqcount # RED-PEN should check preempt count - movq %gs:pda_irqstackptr,%rax - cmoveq %rax,%rsp /*todo This needs CFI annotation! */ - pushq %rdi # save old stack -#ifndef CONFIG_DEBUG_INFO - CFI_ADJUST_CFA_OFFSET 8 -#endif + cmoveq %gs:pda_irqstackptr,%rsp call \func .endm @@ -497,17 +493,11 @@ ENTRY(common_interrupt) interrupt do_IRQ /* 0(%rsp): oldrsp-ARGOFFSET */ ret_from_intr: - popq %rdi -#ifndef CONFIG_DEBUG_INFO - CFI_ADJUST_CFA_OFFSET -8 -#endif cli decl %gs:pda_irqcount -#ifdef CONFIG_DEBUG_INFO - movq RBP(%rdi),%rbp + leaveq CFI_DEF_CFA_REGISTER rsp -#endif - leaq ARGOFFSET(%rdi),%rsp /*todo This needs CFI annotation! */ + CFI_ADJUST_CFA_OFFSET -8 exit_intr: GET_THREAD_INFO(%rcx) testl $3,CS-ARGOFFSET(%rsp) @@ -589,14 +579,16 @@ retint_kernel: call preempt_schedule_irq jmp exit_intr #endif + CFI_ENDPROC +END(common_interrupt) /* * APIC interrupts. */ .macro apicinterrupt num,func INTR_FRAME - pushq $\num-256 + pushq $~(\num) CFI_ADJUST_CFA_OFFSET 8 interrupt \func jmp ret_from_intr @@ -605,17 +597,21 @@ retint_kernel: ENTRY(thermal_interrupt) apicinterrupt THERMAL_APIC_VECTOR,smp_thermal_interrupt +END(thermal_interrupt) ENTRY(threshold_interrupt) apicinterrupt THRESHOLD_APIC_VECTOR,mce_threshold_interrupt +END(threshold_interrupt) #ifdef CONFIG_SMP ENTRY(reschedule_interrupt) apicinterrupt RESCHEDULE_VECTOR,smp_reschedule_interrupt +END(reschedule_interrupt) .macro INVALIDATE_ENTRY num ENTRY(invalidate_interrupt\num) apicinterrupt INVALIDATE_TLB_VECTOR_START+\num,smp_invalidate_interrupt +END(invalidate_interrupt\num) .endm INVALIDATE_ENTRY 0 @@ -629,17 +625,21 @@ ENTRY(invalidate_interrupt\num) ENTRY(call_function_interrupt) apicinterrupt CALL_FUNCTION_VECTOR,smp_call_function_interrupt +END(call_function_interrupt) #endif #ifdef CONFIG_X86_LOCAL_APIC ENTRY(apic_timer_interrupt) apicinterrupt LOCAL_TIMER_VECTOR,smp_apic_timer_interrupt +END(apic_timer_interrupt) ENTRY(error_interrupt) apicinterrupt ERROR_APIC_VECTOR,smp_error_interrupt +END(error_interrupt) ENTRY(spurious_interrupt) apicinterrupt SPURIOUS_APIC_VECTOR,smp_spurious_interrupt +END(spurious_interrupt) #endif /* @@ -777,6 +777,7 @@ error_kernelspace: cmpq $gs_change,RIP(%rsp) je error_swapgs jmp error_sti +END(error_entry) /* Reload gs selector with exception handling */ /* edi: new selector */ @@ -794,6 +795,7 @@ gs_change: CFI_ADJUST_CFA_OFFSET -8 ret CFI_ENDPROC +ENDPROC(load_gs_index) .section __ex_table,"a" .align 8 @@ -847,7 +849,7 @@ ENTRY(kernel_thread) UNFAKE_STACK_FRAME ret CFI_ENDPROC - +ENDPROC(kernel_thread) child_rip: /* @@ -860,6 +862,7 @@ child_rip: # exit xorl %edi, %edi call do_exit +ENDPROC(child_rip) /* * execve(). This function needs to use IRET, not SYSRET, to set up all state properly. @@ -889,19 +892,24 @@ ENTRY(execve) UNFAKE_STACK_FRAME ret CFI_ENDPROC +ENDPROC(execve) KPROBE_ENTRY(page_fault) errorentry do_page_fault +END(page_fault) .previous .text ENTRY(coprocessor_error) zeroentry do_coprocessor_error +END(coprocessor_error) ENTRY(simd_coprocessor_error) zeroentry do_simd_coprocessor_error +END(simd_coprocessor_error) ENTRY(device_not_available) zeroentry math_state_restore +END(device_not_available) /* runs on exception stack */ KPROBE_ENTRY(debug) @@ -911,6 +919,7 @@ KPROBE_ENTRY(debug) paranoidentry do_debug, DEBUG_STACK jmp paranoid_exit CFI_ENDPROC +END(debug) .previous .text /* runs on exception stack */ @@ -961,6 +970,7 @@ paranoid_schedule: cli jmp paranoid_userspace CFI_ENDPROC +END(nmi) .previous .text KPROBE_ENTRY(int3) @@ -970,22 +980,28 @@ KPROBE_ENTRY(int3) paranoidentry do_int3, DEBUG_STACK jmp paranoid_exit CFI_ENDPROC +END(int3) .previous .text ENTRY(overflow) zeroentry do_overflow +END(overflow) ENTRY(bounds) zeroentry do_bounds +END(bounds) ENTRY(invalid_op) zeroentry do_invalid_op +END(invalid_op) ENTRY(coprocessor_segment_overrun) zeroentry do_coprocessor_segment_overrun +END(coprocessor_segment_overrun) ENTRY(reserved) zeroentry do_reserved +END(reserved) /* runs on exception stack */ ENTRY(double_fault) @@ -993,12 +1009,15 @@ ENTRY(double_fault) paranoidentry do_double_fault jmp paranoid_exit CFI_ENDPROC +END(double_fault) ENTRY(invalid_TSS) errorentry do_invalid_TSS +END(invalid_TSS) ENTRY(segment_not_present) errorentry do_segment_not_present +END(segment_not_present) /* runs on exception stack */ ENTRY(stack_segment) @@ -1006,19 +1025,24 @@ ENTRY(stack_segment) paranoidentry do_stack_segment jmp paranoid_exit CFI_ENDPROC +END(stack_segment) KPROBE_ENTRY(general_protection) errorentry do_general_protection +END(general_protection) .previous .text ENTRY(alignment_check) errorentry do_alignment_check +END(alignment_check) ENTRY(divide_error) zeroentry do_divide_error +END(divide_error) ENTRY(spurious_interrupt_bug) zeroentry do_spurious_interrupt_bug +END(spurious_interrupt_bug) #ifdef CONFIG_X86_MCE /* runs on exception stack */ @@ -1029,6 +1053,7 @@ ENTRY(machine_check) paranoidentry do_machine_check jmp paranoid_exit CFI_ENDPROC +END(machine_check) #endif ENTRY(call_softirq) @@ -1046,3 +1071,37 @@ ENTRY(call_softirq) decl %gs:pda_irqcount ret CFI_ENDPROC +ENDPROC(call_softirq) + +#ifdef CONFIG_STACK_UNWIND +ENTRY(arch_unwind_init_running) + CFI_STARTPROC + movq %r15, R15(%rdi) + movq %r14, R14(%rdi) + xchgq %rsi, %rdx + movq %r13, R13(%rdi) + movq %r12, R12(%rdi) + xorl %eax, %eax + movq %rbp, RBP(%rdi) + movq %rbx, RBX(%rdi) + movq (%rsp), %rcx + movq %rax, R11(%rdi) + movq %rax, R10(%rdi) + movq %rax, R9(%rdi) + movq %rax, R8(%rdi) + movq %rax, RAX(%rdi) + movq %rax, RCX(%rdi) + movq %rax, RDX(%rdi) + movq %rax, RSI(%rdi) + movq %rax, RDI(%rdi) + movq %rax, ORIG_RAX(%rdi) + movq %rcx, RIP(%rdi) + leaq 8(%rsp), %rcx + movq $__KERNEL_CS, CS(%rdi) + movq %rax, EFLAGS(%rdi) + movq %rcx, RSP(%rdi) + movq $__KERNEL_DS, SS(%rdi) + jmpq *%rdx + CFI_ENDPROC +ENDPROC(arch_unwind_init_running) +#endif diff --git a/arch/x86_64/kernel/genapic_flat.c b/arch/x86_64/kernel/genapic_flat.c index 1a2ab825be9..21c7066e236 100644 --- a/arch/x86_64/kernel/genapic_flat.c +++ b/arch/x86_64/kernel/genapic_flat.c @@ -78,22 +78,29 @@ static void flat_send_IPI_mask(cpumask_t cpumask, int vector) static void flat_send_IPI_allbutself(int vector) { -#ifndef CONFIG_HOTPLUG_CPU - if (((num_online_cpus()) - 1) >= 1) - __send_IPI_shortcut(APIC_DEST_ALLBUT, vector,APIC_DEST_LOGICAL); +#ifdef CONFIG_HOTPLUG_CPU + int hotplug = 1; #else - cpumask_t allbutme = cpu_online_map; + int hotplug = 0; +#endif + if (hotplug || vector == NMI_VECTOR) { + cpumask_t allbutme = cpu_online_map; - cpu_clear(smp_processor_id(), allbutme); + cpu_clear(smp_processor_id(), allbutme); - if (!cpus_empty(allbutme)) - flat_send_IPI_mask(allbutme, vector); -#endif + if (!cpus_empty(allbutme)) + flat_send_IPI_mask(allbutme, vector); + } else if (num_online_cpus() > 1) { + __send_IPI_shortcut(APIC_DEST_ALLBUT, vector,APIC_DEST_LOGICAL); + } } static void flat_send_IPI_all(int vector) { - __send_IPI_shortcut(APIC_DEST_ALLINC, vector, APIC_DEST_LOGICAL); + if (vector == NMI_VECTOR) + flat_send_IPI_mask(cpu_online_map, vector); + else + __send_IPI_shortcut(APIC_DEST_ALLINC, vector, APIC_DEST_LOGICAL); } static int flat_apic_id_registered(void) @@ -108,10 +115,7 @@ static unsigned int flat_cpu_mask_to_apicid(cpumask_t cpumask) static unsigned int phys_pkg_id(int index_msb) { - u32 ebx; - - ebx = cpuid_ebx(1); - return ((ebx >> 24) & 0xFF) >> index_msb; + return hard_smp_processor_id() >> index_msb; } struct genapic apic_flat = { diff --git a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c index cea20a66c15..e6a71c9556d 100644 --- a/arch/x86_64/kernel/head64.c +++ b/arch/x86_64/kernel/head64.c @@ -2,8 +2,6 @@ * linux/arch/x86_64/kernel/head64.c -- prepare to run common code * * Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE - * - * $Id: head64.c,v 1.22 2001/07/06 14:28:20 ak Exp $ */ #include <linux/init.h> diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c index 5ecd34ab8c2..3dd1659427d 100644 --- a/arch/x86_64/kernel/i8259.c +++ b/arch/x86_64/kernel/i8259.c @@ -44,11 +44,11 @@ BI(x,8) BI(x,9) BI(x,a) BI(x,b) \ BI(x,c) BI(x,d) BI(x,e) BI(x,f) -#define BUILD_14_IRQS(x) \ +#define BUILD_15_IRQS(x) \ BI(x,0) BI(x,1) BI(x,2) BI(x,3) \ BI(x,4) BI(x,5) BI(x,6) BI(x,7) \ BI(x,8) BI(x,9) BI(x,a) BI(x,b) \ - BI(x,c) BI(x,d) + BI(x,c) BI(x,d) BI(x,e) /* * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts: @@ -73,13 +73,13 @@ BUILD_16_IRQS(0x8) BUILD_16_IRQS(0x9) BUILD_16_IRQS(0xa) BUILD_16_IRQS(0xb) BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) #ifdef CONFIG_PCI_MSI - BUILD_14_IRQS(0xe) + BUILD_15_IRQS(0xe) #endif #endif #undef BUILD_16_IRQS -#undef BUILD_14_IRQS +#undef BUILD_15_IRQS #undef BI @@ -92,11 +92,11 @@ BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \ IRQ(x,c), IRQ(x,d), IRQ(x,e), IRQ(x,f) -#define IRQLIST_14(x) \ +#define IRQLIST_15(x) \ IRQ(x,0), IRQ(x,1), IRQ(x,2), IRQ(x,3), \ IRQ(x,4), IRQ(x,5), IRQ(x,6), IRQ(x,7), \ IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \ - IRQ(x,c), IRQ(x,d) + IRQ(x,c), IRQ(x,d), IRQ(x,e) void (*interrupt[NR_IRQS])(void) = { IRQLIST_16(0x0), @@ -108,7 +108,7 @@ void (*interrupt[NR_IRQS])(void) = { IRQLIST_16(0xc), IRQLIST_16(0xd) #ifdef CONFIG_PCI_MSI - , IRQLIST_14(0xe) + , IRQLIST_15(0xe) #endif #endif @@ -235,7 +235,7 @@ void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); io_apic_irqs &= ~(1<<irq); - irq_desc[irq].handler = &i8259A_irq_type; + irq_desc[irq].chip = &i8259A_irq_type; enable_irq(irq); } @@ -278,7 +278,7 @@ static void mask_and_ack_8259A(unsigned int irq) * Lightweight spurious IRQ detection. We do not want * to overdo spurious IRQ handling - it's usually a sign * of hardware problems, so we only do the checks we can - * do without slowing down good hardware unnecesserily. + * do without slowing down good hardware unnecessarily. * * Note that IRQ7 and IRQ15 (the two spurious IRQs * usually resulting from the 8259A-1|2 PICs) occur @@ -468,12 +468,12 @@ void __init init_ISA_irqs (void) /* * 16 old-style INTA-cycle interrupts: */ - irq_desc[i].handler = &i8259A_irq_type; + irq_desc[i].chip = &i8259A_irq_type; } else { /* * 'high' PCI IRQs filled in on demand */ - irq_desc[i].handler = &no_irq_type; + irq_desc[i].chip = &no_irq_type; } } } diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 9cc7031b715..401b687fef2 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -41,6 +41,7 @@ #include <asm/mach_apic.h> #include <asm/acpi.h> #include <asm/dma.h> +#include <asm/nmi.h> #define __apicdebuginit __init @@ -56,6 +57,7 @@ int timer_over_8254 __initdata = 0; static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; static DEFINE_SPINLOCK(ioapic_lock); +static DEFINE_SPINLOCK(vector_lock); /* * # of IRQ routing registers @@ -317,7 +319,7 @@ void __init check_ioapic(void) vendor &= 0xffff; switch (vendor) { case PCI_VENDOR_ID_VIA: -#ifdef CONFIG_GART_IOMMU +#ifdef CONFIG_IOMMU if ((end_pfn > MAX_DMA32_PFN || force_iommu) && !iommu_aperture_allowed) { @@ -834,10 +836,17 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; int assign_irq_vector(int irq) { static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; + unsigned long flags; + int vector; BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS); - if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) + + spin_lock_irqsave(&vector_lock, flags); + + if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) { + spin_unlock_irqrestore(&vector_lock, flags); return IO_APIC_VECTOR(irq); + } next: current_vector += 8; if (current_vector == IA32_SYSCALL_VECTOR) @@ -849,11 +858,14 @@ next: current_vector = FIRST_DEVICE_VECTOR + offset; } - vector_irq[current_vector] = irq; + vector = current_vector; + vector_irq[vector] = irq; if (irq != AUTO_ASSIGN) - IO_APIC_VECTOR(irq) = current_vector; + IO_APIC_VECTOR(irq) = vector; - return current_vector; + spin_unlock_irqrestore(&vector_lock, flags); + + return vector; } extern void (*interrupt[NR_IRQS])(void); @@ -864,23 +876,18 @@ static struct hw_interrupt_type ioapic_edge_type; #define IOAPIC_EDGE 0 #define IOAPIC_LEVEL 1 -static inline void ioapic_register_intr(int irq, int vector, unsigned long trigger) +static void ioapic_register_intr(int irq, int vector, unsigned long trigger) { - if (use_pci_vector() && !platform_legacy_irq(irq)) { - if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || - trigger == IOAPIC_LEVEL) - irq_desc[vector].handler = &ioapic_level_type; - else - irq_desc[vector].handler = &ioapic_edge_type; - set_intr_gate(vector, interrupt[vector]); - } else { - if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || - trigger == IOAPIC_LEVEL) - irq_desc[irq].handler = &ioapic_level_type; - else - irq_desc[irq].handler = &ioapic_edge_type; - set_intr_gate(vector, interrupt[irq]); - } + unsigned idx; + + idx = use_pci_vector() && !platform_legacy_irq(irq) ? vector : irq; + + if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || + trigger == IOAPIC_LEVEL) + irq_desc[idx].chip = &ioapic_level_type; + else + irq_desc[idx].chip = &ioapic_edge_type; + set_intr_gate(vector, interrupt[idx]); } static void __init setup_IO_APIC_irqs(void) @@ -981,7 +988,7 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in * The timer IRQ doesn't have to know that behind the * scene we have a 8259A-master in AEOI mode ... */ - irq_desc[0].handler = &ioapic_edge_type; + irq_desc[0].chip = &ioapic_edge_type; /* * Add it to the IO-APIC irq-routing table: @@ -1611,6 +1618,13 @@ static void set_ioapic_affinity_vector (unsigned int vector, #endif // CONFIG_SMP #endif // CONFIG_PCI_MSI +static int ioapic_retrigger(unsigned int irq) +{ + send_IPI_self(IO_APIC_VECTOR(irq)); + + return 1; +} + /* * Level and edge triggered IO-APIC interrupts need different handling, * so we use two separate IRQ descriptors. Edge triggered IRQs can be @@ -1631,6 +1645,7 @@ static struct hw_interrupt_type ioapic_edge_type __read_mostly = { #ifdef CONFIG_SMP .set_affinity = set_ioapic_affinity, #endif + .retrigger = ioapic_retrigger, }; static struct hw_interrupt_type ioapic_level_type __read_mostly = { @@ -1644,6 +1659,7 @@ static struct hw_interrupt_type ioapic_level_type __read_mostly = { #ifdef CONFIG_SMP .set_affinity = set_ioapic_affinity, #endif + .retrigger = ioapic_retrigger, }; static inline void init_IO_APIC_traps(void) @@ -1678,7 +1694,7 @@ static inline void init_IO_APIC_traps(void) make_8259A_irq(irq); else /* Strange. Oh, well.. */ - irq_desc[irq].handler = &no_irq_type; + irq_desc[irq].chip = &no_irq_type; } } } @@ -1895,7 +1911,7 @@ static inline void check_timer(void) apic_printk(APIC_VERBOSE, KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); disable_8259A_irq(0); - irq_desc[0].handler = &lapic_irq_type; + irq_desc[0].chip = &lapic_irq_type; apic_write(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ enable_8259A_irq(0); diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c index d8bd0b345b1..a1f1df5f7bf 100644 --- a/arch/x86_64/kernel/irq.c +++ b/arch/x86_64/kernel/irq.c @@ -26,6 +26,30 @@ atomic_t irq_mis_count; #endif #endif +#ifdef CONFIG_DEBUG_STACKOVERFLOW +/* + * Probabilistic stack overflow check: + * + * Only check the stack in process context, because everything else + * runs on the big interrupt stacks. Checking reliably is too expensive, + * so we just check from interrupts. + */ +static inline void stack_overflow_check(struct pt_regs *regs) +{ + u64 curbase = (u64) current->thread_info; + static unsigned long warned = -60*HZ; + + if (regs->rsp >= curbase && regs->rsp <= curbase + THREAD_SIZE && + regs->rsp < curbase + sizeof(struct thread_info) + 128 && + time_after(jiffies, warned + 60*HZ)) { + printk("do_IRQ: %s near stack overflow (cur:%Lx,rsp:%lx)\n", + current->comm, curbase, regs->rsp); + show_stack(NULL,NULL); + warned = jiffies; + } +} +#endif + /* * Generic, controller-independent functions: */ @@ -39,7 +63,7 @@ int show_interrupts(struct seq_file *p, void *v) if (i == 0) { seq_printf(p, " "); for_each_online_cpu(j) - seq_printf(p, "CPU%d ",j); + seq_printf(p, "CPU%-8d",j); seq_putc(p, '\n'); } @@ -55,7 +79,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -91,12 +115,20 @@ skip: */ asmlinkage unsigned int do_IRQ(struct pt_regs *regs) { - /* high bits used in ret_from_ code */ - unsigned irq = regs->orig_rax & 0xff; + /* high bit used in ret_from_ code */ + unsigned irq = ~regs->orig_rax; + + if (unlikely(irq >= NR_IRQS)) { + printk(KERN_EMERG "%s: cannot handle IRQ %d\n", + __FUNCTION__, irq); + BUG(); + } exit_idle(); irq_enter(); - +#ifdef CONFIG_DEBUG_STACKOVERFLOW + stack_overflow_check(regs); +#endif __do_IRQ(irq, regs); irq_exit(); @@ -114,13 +146,13 @@ void fixup_irqs(cpumask_t map) if (irq == 2) continue; - cpus_and(mask, irq_affinity[irq], map); + cpus_and(mask, irq_desc[irq].affinity, map); if (any_online_cpu(mask) == NR_CPUS) { printk("Breaking affinity for irq %i\n", irq); mask = map; } - if (irq_desc[irq].handler->set_affinity) - irq_desc[irq].handler->set_affinity(irq, mask); + if (irq_desc[irq].chip->set_affinity) + irq_desc[irq].chip->set_affinity(irq, mask); else if (irq_desc[irq].action && !(warned++)) printk("Cannot set affinity for irq %i\n", irq); } diff --git a/arch/x86_64/kernel/k8.c b/arch/x86_64/kernel/k8.c new file mode 100644 index 00000000000..6416682d33d --- /dev/null +++ b/arch/x86_64/kernel/k8.c @@ -0,0 +1,118 @@ +/* + * Shared support code for AMD K8 northbridges and derivates. + * Copyright 2006 Andi Kleen, SUSE Labs. Subject to GPLv2. + */ +#include <linux/gfp.h> +#include <linux/types.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/module.h> +#include <linux/spinlock.h> +#include <asm/k8.h> + +int num_k8_northbridges; +EXPORT_SYMBOL(num_k8_northbridges); + +static u32 *flush_words; + +struct pci_device_id k8_nb_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1103) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1203) }, + {} +}; +EXPORT_SYMBOL(k8_nb_ids); + +struct pci_dev **k8_northbridges; +EXPORT_SYMBOL(k8_northbridges); + +static struct pci_dev *next_k8_northbridge(struct pci_dev *dev) +{ + do { + dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev); + if (!dev) + break; + } while (!pci_match_id(&k8_nb_ids[0], dev)); + return dev; +} + +int cache_k8_northbridges(void) +{ + int i; + struct pci_dev *dev; + if (num_k8_northbridges) + return 0; + + num_k8_northbridges = 0; + dev = NULL; + while ((dev = next_k8_northbridge(dev)) != NULL) + num_k8_northbridges++; + + k8_northbridges = kmalloc((num_k8_northbridges + 1) * sizeof(void *), + GFP_KERNEL); + if (!k8_northbridges) + return -ENOMEM; + + flush_words = kmalloc(num_k8_northbridges * sizeof(u32), GFP_KERNEL); + if (!flush_words) { + kfree(k8_northbridges); + return -ENOMEM; + } + + dev = NULL; + i = 0; + while ((dev = next_k8_northbridge(dev)) != NULL) { + k8_northbridges[i++] = dev; + pci_read_config_dword(dev, 0x9c, &flush_words[i]); + } + k8_northbridges[i] = NULL; + return 0; +} +EXPORT_SYMBOL_GPL(cache_k8_northbridges); + +/* Ignores subdevice/subvendor but as far as I can figure out + they're useless anyways */ +int __init early_is_k8_nb(u32 device) +{ + struct pci_device_id *id; + u32 vendor = device & 0xffff; + device >>= 16; + for (id = k8_nb_ids; id->vendor; id++) + if (vendor == id->vendor && device == id->device) + return 1; + return 0; +} + +void k8_flush_garts(void) +{ + int flushed, i; + unsigned long flags; + static DEFINE_SPINLOCK(gart_lock); + + /* Avoid races between AGP and IOMMU. In theory it's not needed + but I'm not sure if the hardware won't lose flush requests + when another is pending. This whole thing is so expensive anyways + that it doesn't matter to serialize more. -AK */ + spin_lock_irqsave(&gart_lock, flags); + flushed = 0; + for (i = 0; i < num_k8_northbridges; i++) { + pci_write_config_dword(k8_northbridges[i], 0x9c, + flush_words[i]|1); + flushed++; + } + for (i = 0; i < num_k8_northbridges; i++) { + u32 w; + /* Make sure the hardware actually executed the flush*/ + for (;;) { + pci_read_config_dword(k8_northbridges[i], + 0x9c, &w); + if (!(w & 1)) + break; + cpu_relax(); + } + } + spin_unlock_irqrestore(&gart_lock, flags); + if (!flushed) + printk("nothing to flush?\n"); +} +EXPORT_SYMBOL_GPL(k8_flush_garts); + diff --git a/arch/x86_64/kernel/machine_kexec.c b/arch/x86_64/kernel/machine_kexec.c index 25ac8a3faae..83fb24a0282 100644 --- a/arch/x86_64/kernel/machine_kexec.c +++ b/arch/x86_64/kernel/machine_kexec.c @@ -149,8 +149,8 @@ typedef NORET_TYPE void (*relocate_new_kernel_t)(unsigned long indirection_page, unsigned long start_address, unsigned long pgtable) ATTRIB_NORET; -const extern unsigned char relocate_new_kernel[]; -const extern unsigned long relocate_new_kernel_size; +extern const unsigned char relocate_new_kernel[]; +extern const unsigned long relocate_new_kernel_size; int machine_kexec_prepare(struct kimage *image) { diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index c69fc43cee7..88845674c66 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c @@ -562,7 +562,7 @@ static struct sysdev_class mce_sysclass = { set_kset_name("machinecheck"), }; -static DEFINE_PER_CPU(struct sys_device, device_mce); +DEFINE_PER_CPU(struct sys_device, device_mce); /* Why are there no generic functions for this? */ #define ACCESSOR(name, var, start) \ @@ -629,7 +629,7 @@ static __cpuinit void mce_remove_device(unsigned int cpu) #endif /* Get notified when a cpu comes on/off. Be hotplug friendly. */ -static int +static __cpuinit int mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; @@ -647,7 +647,7 @@ mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) return NOTIFY_OK; } -static struct notifier_block mce_cpu_notifier = { +static struct notifier_block __cpuinitdata mce_cpu_notifier = { .notifier_call = mce_cpu_callback, }; diff --git a/arch/x86_64/kernel/mce_amd.c b/arch/x86_64/kernel/mce_amd.c index d13b241ad09..335200aa273 100644 --- a/arch/x86_64/kernel/mce_amd.c +++ b/arch/x86_64/kernel/mce_amd.c @@ -1,5 +1,5 @@ /* - * (c) 2005 Advanced Micro Devices, Inc. + * (c) 2005, 2006 Advanced Micro Devices, Inc. * Your use of this code is subject to the terms and conditions of the * GNU general public license version 2. See "COPYING" or * http://www.gnu.org/licenses/gpl.html @@ -8,9 +8,10 @@ * * Support : jacob.shin@amd.com * - * MC4_MISC0 DRAM ECC Error Threshold available under AMD K8 Rev F. - * MC4_MISC0 exists per physical processor. + * April 2006 + * - added support for AMD Family 0x10 processors * + * All MC4_MISCi registers are shared between multi-cores */ #include <linux/cpu.h> @@ -29,32 +30,45 @@ #include <asm/percpu.h> #include <asm/idle.h> -#define PFX "mce_threshold: " -#define VERSION "version 1.00.9" -#define NR_BANKS 5 -#define THRESHOLD_MAX 0xFFF -#define INT_TYPE_APIC 0x00020000 -#define MASK_VALID_HI 0x80000000 -#define MASK_LVTOFF_HI 0x00F00000 -#define MASK_COUNT_EN_HI 0x00080000 -#define MASK_INT_TYPE_HI 0x00060000 -#define MASK_OVERFLOW_HI 0x00010000 +#define PFX "mce_threshold: " +#define VERSION "version 1.1.1" +#define NR_BANKS 6 +#define NR_BLOCKS 9 +#define THRESHOLD_MAX 0xFFF +#define INT_TYPE_APIC 0x00020000 +#define MASK_VALID_HI 0x80000000 +#define MASK_LVTOFF_HI 0x00F00000 +#define MASK_COUNT_EN_HI 0x00080000 +#define MASK_INT_TYPE_HI 0x00060000 +#define MASK_OVERFLOW_HI 0x00010000 #define MASK_ERR_COUNT_HI 0x00000FFF -#define MASK_OVERFLOW 0x0001000000000000L +#define MASK_BLKPTR_LO 0xFF000000 +#define MCG_XBLK_ADDR 0xC0000400 -struct threshold_bank { +struct threshold_block { + unsigned int block; + unsigned int bank; unsigned int cpu; - u8 bank; - u8 interrupt_enable; + u32 address; + u16 interrupt_enable; u16 threshold_limit; struct kobject kobj; + struct list_head miscj; }; -static struct threshold_bank threshold_defaults = { +/* defaults used early on boot */ +static struct threshold_block threshold_defaults = { .interrupt_enable = 0, .threshold_limit = THRESHOLD_MAX, }; +struct threshold_bank { + struct kobject kobj; + struct threshold_block *blocks; + cpumask_t cpus; +}; +static DEFINE_PER_CPU(struct threshold_bank *, threshold_banks[NR_BANKS]); + #ifdef CONFIG_SMP static unsigned char shared_bank[NR_BANKS] = { 0, 0, 0, 0, 1 @@ -68,12 +82,12 @@ static DEFINE_PER_CPU(unsigned char, bank_map); /* see which banks are on */ */ /* must be called with correct cpu affinity */ -static void threshold_restart_bank(struct threshold_bank *b, +static void threshold_restart_bank(struct threshold_block *b, int reset, u16 old_limit) { u32 mci_misc_hi, mci_misc_lo; - rdmsr(MSR_IA32_MC0_MISC + b->bank * 4, mci_misc_lo, mci_misc_hi); + rdmsr(b->address, mci_misc_lo, mci_misc_hi); if (b->threshold_limit < (mci_misc_hi & THRESHOLD_MAX)) reset = 1; /* limit cannot be lower than err count */ @@ -94,35 +108,57 @@ static void threshold_restart_bank(struct threshold_bank *b, (mci_misc_hi &= ~MASK_INT_TYPE_HI); mci_misc_hi |= MASK_COUNT_EN_HI; - wrmsr(MSR_IA32_MC0_MISC + b->bank * 4, mci_misc_lo, mci_misc_hi); + wrmsr(b->address, mci_misc_lo, mci_misc_hi); } +/* cpu init entry point, called from mce.c with preempt off */ void __cpuinit mce_amd_feature_init(struct cpuinfo_x86 *c) { - int bank; - u32 mci_misc_lo, mci_misc_hi; + unsigned int bank, block; unsigned int cpu = smp_processor_id(); + u32 low = 0, high = 0, address = 0; for (bank = 0; bank < NR_BANKS; ++bank) { - rdmsr(MSR_IA32_MC0_MISC + bank * 4, mci_misc_lo, mci_misc_hi); + for (block = 0; block < NR_BLOCKS; ++block) { + if (block == 0) + address = MSR_IA32_MC0_MISC + bank * 4; + else if (block == 1) + address = MCG_XBLK_ADDR + + ((low & MASK_BLKPTR_LO) >> 21); + else + ++address; + + if (rdmsr_safe(address, &low, &high)) + continue; - /* !valid, !counter present, bios locked */ - if (!(mci_misc_hi & MASK_VALID_HI) || - !(mci_misc_hi & MASK_VALID_HI >> 1) || - (mci_misc_hi & MASK_VALID_HI >> 2)) - continue; + if (!(high & MASK_VALID_HI)) { + if (block) + continue; + else + break; + } - per_cpu(bank_map, cpu) |= (1 << bank); + if (!(high & MASK_VALID_HI >> 1) || + (high & MASK_VALID_HI >> 2)) + continue; + if (!block) + per_cpu(bank_map, cpu) |= (1 << bank); #ifdef CONFIG_SMP - if (shared_bank[bank] && cpu_core_id[cpu]) - continue; + if (shared_bank[bank] && c->cpu_core_id) + break; #endif + high &= ~MASK_LVTOFF_HI; + high |= K8_APIC_EXT_LVT_ENTRY_THRESHOLD << 20; + wrmsr(address, low, high); - setup_threshold_lvt((mci_misc_hi & MASK_LVTOFF_HI) >> 20); - threshold_defaults.cpu = cpu; - threshold_defaults.bank = bank; - threshold_restart_bank(&threshold_defaults, 0, 0); + setup_APIC_extened_lvt(K8_APIC_EXT_LVT_ENTRY_THRESHOLD, + THRESHOLD_APIC_VECTOR, + K8_APIC_EXT_INT_MSG_FIX, 0); + + threshold_defaults.address = address; + threshold_restart_bank(&threshold_defaults, 0, 0); + } } } @@ -137,8 +173,9 @@ void __cpuinit mce_amd_feature_init(struct cpuinfo_x86 *c) */ asmlinkage void mce_threshold_interrupt(void) { - int bank; + unsigned int bank, block; struct mce m; + u32 low = 0, high = 0, address = 0; ack_APIC_irq(); exit_idle(); @@ -150,15 +187,42 @@ asmlinkage void mce_threshold_interrupt(void) /* assume first bank caused it */ for (bank = 0; bank < NR_BANKS; ++bank) { - m.bank = MCE_THRESHOLD_BASE + bank; - rdmsrl(MSR_IA32_MC0_MISC + bank * 4, m.misc); + for (block = 0; block < NR_BLOCKS; ++block) { + if (block == 0) + address = MSR_IA32_MC0_MISC + bank * 4; + else if (block == 1) + address = MCG_XBLK_ADDR + + ((low & MASK_BLKPTR_LO) >> 21); + else + ++address; + + if (rdmsr_safe(address, &low, &high)) + continue; - if (m.misc & MASK_OVERFLOW) { - mce_log(&m); - goto out; + if (!(high & MASK_VALID_HI)) { + if (block) + continue; + else + break; + } + + if (!(high & MASK_VALID_HI >> 1) || + (high & MASK_VALID_HI >> 2)) + continue; + + if (high & MASK_OVERFLOW_HI) { + rdmsrl(address, m.misc); + rdmsrl(MSR_IA32_MC0_STATUS + bank * 4, + m.status); + m.bank = K8_MCE_THRESHOLD_BASE + + bank * NR_BLOCKS + + block; + mce_log(&m); + goto out; + } } } - out: +out: irq_exit(); } @@ -166,20 +230,12 @@ asmlinkage void mce_threshold_interrupt(void) * Sysfs Interface */ -static struct sysdev_class threshold_sysclass = { - set_kset_name("threshold"), -}; - -static DEFINE_PER_CPU(struct sys_device, device_threshold); - struct threshold_attr { - struct attribute attr; - ssize_t(*show) (struct threshold_bank *, char *); - ssize_t(*store) (struct threshold_bank *, const char *, size_t count); + struct attribute attr; + ssize_t(*show) (struct threshold_block *, char *); + ssize_t(*store) (struct threshold_block *, const char *, size_t count); }; -static DEFINE_PER_CPU(struct threshold_bank *, threshold_banks[NR_BANKS]); - static cpumask_t affinity_set(unsigned int cpu) { cpumask_t oldmask = current->cpus_allowed; @@ -194,15 +250,15 @@ static void affinity_restore(cpumask_t oldmask) set_cpus_allowed(current, oldmask); } -#define SHOW_FIELDS(name) \ - static ssize_t show_ ## name(struct threshold_bank * b, char *buf) \ - { \ - return sprintf(buf, "%lx\n", (unsigned long) b->name); \ - } +#define SHOW_FIELDS(name) \ +static ssize_t show_ ## name(struct threshold_block * b, char *buf) \ +{ \ + return sprintf(buf, "%lx\n", (unsigned long) b->name); \ +} SHOW_FIELDS(interrupt_enable) SHOW_FIELDS(threshold_limit) -static ssize_t store_interrupt_enable(struct threshold_bank *b, +static ssize_t store_interrupt_enable(struct threshold_block *b, const char *buf, size_t count) { char *end; @@ -219,7 +275,7 @@ static ssize_t store_interrupt_enable(struct threshold_bank *b, return end - buf; } -static ssize_t store_threshold_limit(struct threshold_bank *b, +static ssize_t store_threshold_limit(struct threshold_block *b, const char *buf, size_t count) { char *end; @@ -242,18 +298,18 @@ static ssize_t store_threshold_limit(struct threshold_bank *b, return end - buf; } -static ssize_t show_error_count(struct threshold_bank *b, char *buf) +static ssize_t show_error_count(struct threshold_block *b, char *buf) { u32 high, low; cpumask_t oldmask; oldmask = affinity_set(b->cpu); - rdmsr(MSR_IA32_MC0_MISC + b->bank * 4, low, high); /* ignore low 32 */ + rdmsr(b->address, low, high); affinity_restore(oldmask); return sprintf(buf, "%x\n", (high & 0xFFF) - (THRESHOLD_MAX - b->threshold_limit)); } -static ssize_t store_error_count(struct threshold_bank *b, +static ssize_t store_error_count(struct threshold_block *b, const char *buf, size_t count) { cpumask_t oldmask; @@ -269,13 +325,13 @@ static ssize_t store_error_count(struct threshold_bank *b, .store = _store, \ }; -#define ATTR_FIELDS(name) \ - static struct threshold_attr name = \ +#define RW_ATTR(name) \ +static struct threshold_attr name = \ THRESHOLD_ATTR(name, 0644, show_## name, store_## name) -ATTR_FIELDS(interrupt_enable); -ATTR_FIELDS(threshold_limit); -ATTR_FIELDS(error_count); +RW_ATTR(interrupt_enable); +RW_ATTR(threshold_limit); +RW_ATTR(error_count); static struct attribute *default_attrs[] = { &interrupt_enable.attr, @@ -284,12 +340,12 @@ static struct attribute *default_attrs[] = { NULL }; -#define to_bank(k) container_of(k,struct threshold_bank,kobj) -#define to_attr(a) container_of(a,struct threshold_attr,attr) +#define to_block(k) container_of(k, struct threshold_block, kobj) +#define to_attr(a) container_of(a, struct threshold_attr, attr) static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) { - struct threshold_bank *b = to_bank(kobj); + struct threshold_block *b = to_block(kobj); struct threshold_attr *a = to_attr(attr); ssize_t ret; ret = a->show ? a->show(b, buf) : -EIO; @@ -299,7 +355,7 @@ static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) static ssize_t store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count) { - struct threshold_bank *b = to_bank(kobj); + struct threshold_block *b = to_block(kobj); struct threshold_attr *a = to_attr(attr); ssize_t ret; ret = a->store ? a->store(b, buf, count) : -EIO; @@ -316,69 +372,174 @@ static struct kobj_type threshold_ktype = { .default_attrs = default_attrs, }; +static __cpuinit int allocate_threshold_blocks(unsigned int cpu, + unsigned int bank, + unsigned int block, + u32 address) +{ + int err; + u32 low, high; + struct threshold_block *b = NULL; + + if ((bank >= NR_BANKS) || (block >= NR_BLOCKS)) + return 0; + + if (rdmsr_safe(address, &low, &high)) + goto recurse; + + if (!(high & MASK_VALID_HI)) { + if (block) + goto recurse; + else + return 0; + } + + if (!(high & MASK_VALID_HI >> 1) || + (high & MASK_VALID_HI >> 2)) + goto recurse; + + b = kzalloc(sizeof(struct threshold_block), GFP_KERNEL); + if (!b) + return -ENOMEM; + memset(b, 0, sizeof(struct threshold_block)); + + b->block = block; + b->bank = bank; + b->cpu = cpu; + b->address = address; + b->interrupt_enable = 0; + b->threshold_limit = THRESHOLD_MAX; + + INIT_LIST_HEAD(&b->miscj); + + if (per_cpu(threshold_banks, cpu)[bank]->blocks) + list_add(&b->miscj, + &per_cpu(threshold_banks, cpu)[bank]->blocks->miscj); + else + per_cpu(threshold_banks, cpu)[bank]->blocks = b; + + kobject_set_name(&b->kobj, "misc%i", block); + b->kobj.parent = &per_cpu(threshold_banks, cpu)[bank]->kobj; + b->kobj.ktype = &threshold_ktype; + err = kobject_register(&b->kobj); + if (err) + goto out_free; +recurse: + if (!block) { + address = (low & MASK_BLKPTR_LO) >> 21; + if (!address) + return 0; + address += MCG_XBLK_ADDR; + } else + ++address; + + err = allocate_threshold_blocks(cpu, bank, ++block, address); + if (err) + goto out_free; + + return err; + +out_free: + if (b) { + kobject_unregister(&b->kobj); + kfree(b); + } + return err; +} + /* symlinks sibling shared banks to first core. first core owns dir/files. */ -static __cpuinit int threshold_create_bank(unsigned int cpu, int bank) +static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) { - int err = 0; + int i, err = 0; struct threshold_bank *b = NULL; + cpumask_t oldmask = CPU_MASK_NONE; + char name[32]; + + sprintf(name, "threshold_bank%i", bank); #ifdef CONFIG_SMP - if (cpu_core_id[cpu] && shared_bank[bank]) { /* symlink */ - char name[16]; - unsigned lcpu = first_cpu(cpu_core_map[cpu]); - if (cpu_core_id[lcpu]) - goto out; /* first core not up yet */ + if (cpu_data[cpu].cpu_core_id && shared_bank[bank]) { /* symlink */ + i = first_cpu(cpu_core_map[cpu]); + + /* first core not up yet */ + if (cpu_data[i].cpu_core_id) + goto out; + + /* already linked */ + if (per_cpu(threshold_banks, cpu)[bank]) + goto out; + + b = per_cpu(threshold_banks, i)[bank]; - b = per_cpu(threshold_banks, lcpu)[bank]; if (!b) goto out; - sprintf(name, "bank%i", bank); - err = sysfs_create_link(&per_cpu(device_threshold, cpu).kobj, + + err = sysfs_create_link(&per_cpu(device_mce, cpu).kobj, &b->kobj, name); if (err) goto out; + + b->cpus = cpu_core_map[cpu]; per_cpu(threshold_banks, cpu)[bank] = b; goto out; } #endif - b = kmalloc(sizeof(struct threshold_bank), GFP_KERNEL); + b = kzalloc(sizeof(struct threshold_bank), GFP_KERNEL); if (!b) { err = -ENOMEM; goto out; } memset(b, 0, sizeof(struct threshold_bank)); - b->cpu = cpu; - b->bank = bank; - b->interrupt_enable = 0; - b->threshold_limit = THRESHOLD_MAX; - kobject_set_name(&b->kobj, "bank%i", bank); - b->kobj.parent = &per_cpu(device_threshold, cpu).kobj; - b->kobj.ktype = &threshold_ktype; - + kobject_set_name(&b->kobj, "threshold_bank%i", bank); + b->kobj.parent = &per_cpu(device_mce, cpu).kobj; +#ifndef CONFIG_SMP + b->cpus = CPU_MASK_ALL; +#else + b->cpus = cpu_core_map[cpu]; +#endif err = kobject_register(&b->kobj); - if (err) { - kfree(b); - goto out; - } + if (err) + goto out_free; + per_cpu(threshold_banks, cpu)[bank] = b; - out: + + oldmask = affinity_set(cpu); + err = allocate_threshold_blocks(cpu, bank, 0, + MSR_IA32_MC0_MISC + bank * 4); + affinity_restore(oldmask); + + if (err) + goto out_free; + + for_each_cpu_mask(i, b->cpus) { + if (i == cpu) + continue; + + err = sysfs_create_link(&per_cpu(device_mce, i).kobj, + &b->kobj, name); + if (err) + goto out; + + per_cpu(threshold_banks, i)[bank] = b; + } + + goto out; + +out_free: + per_cpu(threshold_banks, cpu)[bank] = NULL; + kfree(b); +out: return err; } /* create dir/files for all valid threshold banks */ static __cpuinit int threshold_create_device(unsigned int cpu) { - int bank; + unsigned int bank; int err = 0; - per_cpu(device_threshold, cpu).id = cpu; - per_cpu(device_threshold, cpu).cls = &threshold_sysclass; - err = sysdev_register(&per_cpu(device_threshold, cpu)); - if (err) - goto out; - for (bank = 0; bank < NR_BANKS; ++bank) { if (!(per_cpu(bank_map, cpu) & 1 << bank)) continue; @@ -386,7 +547,7 @@ static __cpuinit int threshold_create_device(unsigned int cpu) if (err) goto out; } - out: +out: return err; } @@ -397,92 +558,85 @@ static __cpuinit int threshold_create_device(unsigned int cpu) * of shared sysfs dir/files, and rest of the cores will be symlinked to it. */ -/* cpu hotplug call removes all symlinks before first core dies */ +static __cpuinit void deallocate_threshold_block(unsigned int cpu, + unsigned int bank) +{ + struct threshold_block *pos = NULL; + struct threshold_block *tmp = NULL; + struct threshold_bank *head = per_cpu(threshold_banks, cpu)[bank]; + + if (!head) + return; + + list_for_each_entry_safe(pos, tmp, &head->blocks->miscj, miscj) { + kobject_unregister(&pos->kobj); + list_del(&pos->miscj); + kfree(pos); + } + + kfree(per_cpu(threshold_banks, cpu)[bank]->blocks); + per_cpu(threshold_banks, cpu)[bank]->blocks = NULL; +} + static __cpuinit void threshold_remove_bank(unsigned int cpu, int bank) { + int i = 0; struct threshold_bank *b; - char name[16]; + char name[32]; b = per_cpu(threshold_banks, cpu)[bank]; + if (!b) return; - if (shared_bank[bank] && atomic_read(&b->kobj.kref.refcount) > 2) { - sprintf(name, "bank%i", bank); - sysfs_remove_link(&per_cpu(device_threshold, cpu).kobj, name); - per_cpu(threshold_banks, cpu)[bank] = NULL; - } else { - kobject_unregister(&b->kobj); - kfree(per_cpu(threshold_banks, cpu)[bank]); + + if (!b->blocks) + goto free_out; + + sprintf(name, "threshold_bank%i", bank); + + /* sibling symlink */ + if (shared_bank[bank] && b->blocks->cpu != cpu) { + sysfs_remove_link(&per_cpu(device_mce, cpu).kobj, name); + per_cpu(threshold_banks, i)[bank] = NULL; + return; + } + + /* remove all sibling symlinks before unregistering */ + for_each_cpu_mask(i, b->cpus) { + if (i == cpu) + continue; + + sysfs_remove_link(&per_cpu(device_mce, i).kobj, name); + per_cpu(threshold_banks, i)[bank] = NULL; } + + deallocate_threshold_block(cpu, bank); + +free_out: + kobject_unregister(&b->kobj); + kfree(b); + per_cpu(threshold_banks, cpu)[bank] = NULL; } static __cpuinit void threshold_remove_device(unsigned int cpu) { - int bank; + unsigned int bank; for (bank = 0; bank < NR_BANKS; ++bank) { if (!(per_cpu(bank_map, cpu) & 1 << bank)) continue; threshold_remove_bank(cpu, bank); } - sysdev_unregister(&per_cpu(device_threshold, cpu)); } -/* link all existing siblings when first core comes up */ -static __cpuinit int threshold_create_symlinks(unsigned int cpu) -{ - int bank, err = 0; - unsigned int lcpu = 0; - - if (cpu_core_id[cpu]) - return 0; - for_each_cpu_mask(lcpu, cpu_core_map[cpu]) { - if (lcpu == cpu) - continue; - for (bank = 0; bank < NR_BANKS; ++bank) { - if (!(per_cpu(bank_map, cpu) & 1 << bank)) - continue; - if (!shared_bank[bank]) - continue; - err = threshold_create_bank(lcpu, bank); - } - } - return err; -} - -/* remove all symlinks before first core dies. */ -static __cpuinit void threshold_remove_symlinks(unsigned int cpu) -{ - int bank; - unsigned int lcpu = 0; - if (cpu_core_id[cpu]) - return; - for_each_cpu_mask(lcpu, cpu_core_map[cpu]) { - if (lcpu == cpu) - continue; - for (bank = 0; bank < NR_BANKS; ++bank) { - if (!(per_cpu(bank_map, cpu) & 1 << bank)) - continue; - if (!shared_bank[bank]) - continue; - threshold_remove_bank(lcpu, bank); - } - } -} #else /* !CONFIG_HOTPLUG_CPU */ -static __cpuinit void threshold_create_symlinks(unsigned int cpu) -{ -} -static __cpuinit void threshold_remove_symlinks(unsigned int cpu) -{ -} static void threshold_remove_device(unsigned int cpu) { } #endif /* get notified when a cpu comes on/off */ -static int threshold_cpu_callback(struct notifier_block *nfb, +static int __cpuinit threshold_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { /* cpu was unsigned int to begin with */ @@ -494,13 +648,6 @@ static int threshold_cpu_callback(struct notifier_block *nfb, switch (action) { case CPU_ONLINE: threshold_create_device(cpu); - threshold_create_symlinks(cpu); - break; - case CPU_DOWN_PREPARE: - threshold_remove_symlinks(cpu); - break; - case CPU_DOWN_FAILED: - threshold_create_symlinks(cpu); break; case CPU_DEAD: threshold_remove_device(cpu); @@ -512,29 +659,22 @@ static int threshold_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block threshold_cpu_notifier = { +static struct notifier_block threshold_cpu_notifier __cpuinitdata = { .notifier_call = threshold_cpu_callback, }; static __init int threshold_init_device(void) { - int err; - int lcpu = 0; - - err = sysdev_class_register(&threshold_sysclass); - if (err) - goto out; + unsigned lcpu = 0; /* to hit CPUs online before the notifier is up */ for_each_online_cpu(lcpu) { - err = threshold_create_device(lcpu); + int err = threshold_create_device(lcpu); if (err) - goto out; + return err; } register_cpu_notifier(&threshold_cpu_notifier); - - out: - return err; + return 0; } device_initcall(threshold_init_device); diff --git a/arch/x86_64/kernel/module.c b/arch/x86_64/kernel/module.c index bac195c74bc..9d0958ff547 100644 --- a/arch/x86_64/kernel/module.c +++ b/arch/x86_64/kernel/module.c @@ -145,26 +145,38 @@ int apply_relocate(Elf_Shdr *sechdrs, return -ENOSYS; } -extern void apply_alternatives(void *start, void *end); - int module_finalize(const Elf_Ehdr *hdr, - const Elf_Shdr *sechdrs, - struct module *me) + const Elf_Shdr *sechdrs, + struct module *me) { - const Elf_Shdr *s; + const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL; char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; - /* look for .altinstructions to patch */ - for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { - void *seg; - if (strcmp(".altinstructions", secstrings + s->sh_name)) - continue; - seg = (void *)s->sh_addr; - apply_alternatives(seg, seg + s->sh_size); - } + for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { + if (!strcmp(".text", secstrings + s->sh_name)) + text = s; + if (!strcmp(".altinstructions", secstrings + s->sh_name)) + alt = s; + if (!strcmp(".smp_locks", secstrings + s->sh_name)) + locks= s; + } + + if (alt) { + /* patch .altinstructions */ + void *aseg = (void *)alt->sh_addr; + apply_alternatives(aseg, aseg + alt->sh_size); + } + if (locks && text) { + void *lseg = (void *)locks->sh_addr; + void *tseg = (void *)text->sh_addr; + alternatives_smp_module_add(me, me->name, + lseg, lseg + locks->sh_size, + tseg, tseg + text->sh_size); + } return 0; } void module_arch_cleanup(struct module *mod) { + alternatives_smp_module_del(mod); } diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index 4e6357fe0ec..0ef9cf2bc45 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c @@ -15,11 +15,7 @@ #include <linux/config.h> #include <linux/mm.h> #include <linux/delay.h> -#include <linux/bootmem.h> -#include <linux/smp_lock.h> #include <linux/interrupt.h> -#include <linux/mc146818rtc.h> -#include <linux/kernel_stat.h> #include <linux/module.h> #include <linux/sysdev.h> #include <linux/nmi.h> @@ -27,14 +23,11 @@ #include <linux/kprobes.h> #include <asm/smp.h> -#include <asm/mtrr.h> -#include <asm/mpspec.h> #include <asm/nmi.h> -#include <asm/msr.h> #include <asm/proto.h> #include <asm/kdebug.h> -#include <asm/local.h> #include <asm/mce.h> +#include <asm/intel_arch_perfmon.h> /* * lapic_nmi_owner tracks the ownership of the lapic NMI hardware: @@ -74,6 +67,9 @@ static unsigned int nmi_p4_cccr_val; #define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76 #define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING +#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL +#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK + #define MSR_P4_MISC_ENABLE 0x1A0 #define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7) #define MSR_P4_MISC_ENABLE_PEBS_UNAVAIL (1<<12) @@ -105,7 +101,10 @@ static __cpuinit inline int nmi_known_cpu(void) case X86_VENDOR_AMD: return boot_cpu_data.x86 == 15; case X86_VENDOR_INTEL: - return boot_cpu_data.x86 == 15; + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) + return 1; + else + return (boot_cpu_data.x86 == 15); } return 0; } @@ -211,6 +210,8 @@ int __init setup_nmi_watchdog(char *str) __setup("nmi_watchdog=", setup_nmi_watchdog); +static void disable_intel_arch_watchdog(void); + static void disable_lapic_nmi_watchdog(void) { if (nmi_active <= 0) @@ -223,6 +224,8 @@ static void disable_lapic_nmi_watchdog(void) if (boot_cpu_data.x86 == 15) { wrmsr(MSR_P4_IQ_CCCR0, 0, 0); wrmsr(MSR_P4_CRU_ESCR0, 0, 0); + } else if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { + disable_intel_arch_watchdog(); } break; } @@ -375,6 +378,53 @@ static void setup_k7_watchdog(void) wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); } +static void disable_intel_arch_watchdog(void) +{ + unsigned ebx; + + /* + * Check whether the Architectural PerfMon supports + * Unhalted Core Cycles Event or not. + * NOTE: Corresponding bit = 0 in ebp indicates event present. + */ + ebx = cpuid_ebx(10); + if (!(ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) + wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, 0, 0); +} + +static int setup_intel_arch_watchdog(void) +{ + unsigned int evntsel; + unsigned ebx; + + /* + * Check whether the Architectural PerfMon supports + * Unhalted Core Cycles Event or not. + * NOTE: Corresponding bit = 0 in ebp indicates event present. + */ + ebx = cpuid_ebx(10); + if ((ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) + return 0; + + nmi_perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0; + + clear_msr_range(MSR_ARCH_PERFMON_EVENTSEL0, 2); + clear_msr_range(MSR_ARCH_PERFMON_PERFCTR0, 2); + + evntsel = ARCH_PERFMON_EVENTSEL_INT + | ARCH_PERFMON_EVENTSEL_OS + | ARCH_PERFMON_EVENTSEL_USR + | ARCH_PERFMON_NMI_EVENT_SEL + | ARCH_PERFMON_NMI_EVENT_UMASK; + + wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, evntsel, 0); + wrmsrl(MSR_ARCH_PERFMON_PERFCTR0, -((u64)cpu_khz * 1000 / nmi_hz)); + apic_write(APIC_LVTPC, APIC_DM_NMI); + evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE; + wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, evntsel, 0); + return 1; +} + static int setup_p4_watchdog(void) { @@ -428,10 +478,16 @@ void setup_apic_nmi_watchdog(void) setup_k7_watchdog(); break; case X86_VENDOR_INTEL: - if (boot_cpu_data.x86 != 15) - return; - if (!setup_p4_watchdog()) + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { + if (!setup_intel_arch_watchdog()) + return; + } else if (boot_cpu_data.x86 == 15) { + if (!setup_p4_watchdog()) + return; + } else { return; + } + break; default: @@ -516,7 +572,14 @@ void __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) */ wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); apic_write(APIC_LVTPC, APIC_DM_NMI); - } + } else if (nmi_perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) { + /* + * For Intel based architectural perfmon + * - LVTPC is masked on interrupt and must be + * unmasked by the LVTPC handler. + */ + apic_write(APIC_LVTPC, APIC_DM_NMI); + } wrmsrl(nmi_perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz)); } } @@ -544,11 +607,13 @@ void set_nmi_callback(nmi_callback_t callback) vmalloc_sync_all(); rcu_assign_pointer(nmi_callback, callback); } +EXPORT_SYMBOL_GPL(set_nmi_callback); void unset_nmi_callback(void) { nmi_callback = dummy_nmi_callback; } +EXPORT_SYMBOL_GPL(unset_nmi_callback); #ifdef CONFIG_SYSCTL diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c new file mode 100644 index 00000000000..d91cb843f54 --- /dev/null +++ b/arch/x86_64/kernel/pci-calgary.c @@ -0,0 +1,1018 @@ +/* + * Derived from arch/powerpc/kernel/iommu.c + * + * Copyright (C) 2006 Jon Mason <jdmason@us.ibm.com>, IBM Corporation + * Copyright (C) 2006 Muli Ben-Yehuda <muli@il.ibm.com>, IBM Corporation + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/types.h> +#include <linux/slab.h> +#include <linux/mm.h> +#include <linux/spinlock.h> +#include <linux/string.h> +#include <linux/dma-mapping.h> +#include <linux/init.h> +#include <linux/bitops.h> +#include <linux/pci_ids.h> +#include <linux/pci.h> +#include <linux/delay.h> +#include <asm/proto.h> +#include <asm/calgary.h> +#include <asm/tce.h> +#include <asm/pci-direct.h> +#include <asm/system.h> +#include <asm/dma.h> + +#define PCI_DEVICE_ID_IBM_CALGARY 0x02a1 +#define PCI_VENDOR_DEVICE_ID_CALGARY \ + (PCI_VENDOR_ID_IBM | PCI_DEVICE_ID_IBM_CALGARY << 16) + +/* we need these for register space address calculation */ +#define START_ADDRESS 0xfe000000 +#define CHASSIS_BASE 0 +#define ONE_BASED_CHASSIS_NUM 1 + +/* register offsets inside the host bridge space */ +#define PHB_CSR_OFFSET 0x0110 +#define PHB_PLSSR_OFFSET 0x0120 +#define PHB_CONFIG_RW_OFFSET 0x0160 +#define PHB_IOBASE_BAR_LOW 0x0170 +#define PHB_IOBASE_BAR_HIGH 0x0180 +#define PHB_MEM_1_LOW 0x0190 +#define PHB_MEM_1_HIGH 0x01A0 +#define PHB_IO_ADDR_SIZE 0x01B0 +#define PHB_MEM_1_SIZE 0x01C0 +#define PHB_MEM_ST_OFFSET 0x01D0 +#define PHB_AER_OFFSET 0x0200 +#define PHB_CONFIG_0_HIGH 0x0220 +#define PHB_CONFIG_0_LOW 0x0230 +#define PHB_CONFIG_0_END 0x0240 +#define PHB_MEM_2_LOW 0x02B0 +#define PHB_MEM_2_HIGH 0x02C0 +#define PHB_MEM_2_SIZE_HIGH 0x02D0 +#define PHB_MEM_2_SIZE_LOW 0x02E0 +#define PHB_DOSHOLE_OFFSET 0x08E0 + +/* PHB_CONFIG_RW */ +#define PHB_TCE_ENABLE 0x20000000 +#define PHB_SLOT_DISABLE 0x1C000000 +#define PHB_DAC_DISABLE 0x01000000 +#define PHB_MEM2_ENABLE 0x00400000 +#define PHB_MCSR_ENABLE 0x00100000 +/* TAR (Table Address Register) */ +#define TAR_SW_BITS 0x0000ffffffff800fUL +#define TAR_VALID 0x0000000000000008UL +/* CSR (Channel/DMA Status Register) */ +#define CSR_AGENT_MASK 0xffe0ffff + +#define MAX_NUM_OF_PHBS 8 /* how many PHBs in total? */ +#define MAX_PHB_BUS_NUM (MAX_NUM_OF_PHBS * 2) /* max dev->bus->number */ +#define PHBS_PER_CALGARY 4 + +/* register offsets in Calgary's internal register space */ +static const unsigned long tar_offsets[] = { + 0x0580 /* TAR0 */, + 0x0588 /* TAR1 */, + 0x0590 /* TAR2 */, + 0x0598 /* TAR3 */ +}; + +static const unsigned long split_queue_offsets[] = { + 0x4870 /* SPLIT QUEUE 0 */, + 0x5870 /* SPLIT QUEUE 1 */, + 0x6870 /* SPLIT QUEUE 2 */, + 0x7870 /* SPLIT QUEUE 3 */ +}; + +static const unsigned long phb_offsets[] = { + 0x8000 /* PHB0 */, + 0x9000 /* PHB1 */, + 0xA000 /* PHB2 */, + 0xB000 /* PHB3 */ +}; + +void* tce_table_kva[MAX_NUM_OF_PHBS * MAX_NUMNODES]; +unsigned int specified_table_size = TCE_TABLE_SIZE_UNSPECIFIED; +static int translate_empty_slots __read_mostly = 0; +static int calgary_detected __read_mostly = 0; + +/* + * the bitmap of PHBs the user requested that we disable + * translation on. + */ +static DECLARE_BITMAP(translation_disabled, MAX_NUMNODES * MAX_PHB_BUS_NUM); + +static void tce_cache_blast(struct iommu_table *tbl); + +/* enable this to stress test the chip's TCE cache */ +#ifdef CONFIG_IOMMU_DEBUG +static inline void tce_cache_blast_stress(struct iommu_table *tbl) +{ + tce_cache_blast(tbl); +} +#else +static inline void tce_cache_blast_stress(struct iommu_table *tbl) +{ +} +#endif /* BLAST_TCE_CACHE_ON_UNMAP */ + +static inline unsigned int num_dma_pages(unsigned long dma, unsigned int dmalen) +{ + unsigned int npages; + + npages = PAGE_ALIGN(dma + dmalen) - (dma & PAGE_MASK); + npages >>= PAGE_SHIFT; + + return npages; +} + +static inline int translate_phb(struct pci_dev* dev) +{ + int disabled = test_bit(dev->bus->number, translation_disabled); + return !disabled; +} + +static void iommu_range_reserve(struct iommu_table *tbl, + unsigned long start_addr, unsigned int npages) +{ + unsigned long index; + unsigned long end; + + index = start_addr >> PAGE_SHIFT; + + /* bail out if we're asked to reserve a region we don't cover */ + if (index >= tbl->it_size) + return; + + end = index + npages; + if (end > tbl->it_size) /* don't go off the table */ + end = tbl->it_size; + + while (index < end) { + if (test_bit(index, tbl->it_map)) + printk(KERN_ERR "Calgary: entry already allocated at " + "0x%lx tbl %p dma 0x%lx npages %u\n", + index, tbl, start_addr, npages); + ++index; + } + set_bit_string(tbl->it_map, start_addr >> PAGE_SHIFT, npages); +} + +static unsigned long iommu_range_alloc(struct iommu_table *tbl, + unsigned int npages) +{ + unsigned long offset; + + BUG_ON(npages == 0); + + offset = find_next_zero_string(tbl->it_map, tbl->it_hint, + tbl->it_size, npages); + if (offset == ~0UL) { + tce_cache_blast(tbl); + offset = find_next_zero_string(tbl->it_map, 0, + tbl->it_size, npages); + if (offset == ~0UL) { + printk(KERN_WARNING "Calgary: IOMMU full.\n"); + if (panic_on_overflow) + panic("Calgary: fix the allocator.\n"); + else + return bad_dma_address; + } + } + + set_bit_string(tbl->it_map, offset, npages); + tbl->it_hint = offset + npages; + BUG_ON(tbl->it_hint > tbl->it_size); + + return offset; +} + +static dma_addr_t iommu_alloc(struct iommu_table *tbl, void *vaddr, + unsigned int npages, int direction) +{ + unsigned long entry, flags; + dma_addr_t ret = bad_dma_address; + + spin_lock_irqsave(&tbl->it_lock, flags); + + entry = iommu_range_alloc(tbl, npages); + + if (unlikely(entry == bad_dma_address)) + goto error; + + /* set the return dma address */ + ret = (entry << PAGE_SHIFT) | ((unsigned long)vaddr & ~PAGE_MASK); + + /* put the TCEs in the HW table */ + tce_build(tbl, entry, npages, (unsigned long)vaddr & PAGE_MASK, + direction); + + spin_unlock_irqrestore(&tbl->it_lock, flags); + + return ret; + +error: + spin_unlock_irqrestore(&tbl->it_lock, flags); + printk(KERN_WARNING "Calgary: failed to allocate %u pages in " + "iommu %p\n", npages, tbl); + return bad_dma_address; +} + +static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, + unsigned int npages) +{ + unsigned long entry; + unsigned long i; + + entry = dma_addr >> PAGE_SHIFT; + + BUG_ON(entry + npages > tbl->it_size); + + tce_free(tbl, entry, npages); + + for (i = 0; i < npages; ++i) { + if (!test_bit(entry + i, tbl->it_map)) + printk(KERN_ERR "Calgary: bit is off at 0x%lx " + "tbl %p dma 0x%Lx entry 0x%lx npages %u\n", + entry + i, tbl, dma_addr, entry, npages); + } + + __clear_bit_string(tbl->it_map, entry, npages); + + tce_cache_blast_stress(tbl); +} + +static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, + unsigned int npages) +{ + unsigned long flags; + + spin_lock_irqsave(&tbl->it_lock, flags); + + __iommu_free(tbl, dma_addr, npages); + + spin_unlock_irqrestore(&tbl->it_lock, flags); +} + +static void __calgary_unmap_sg(struct iommu_table *tbl, + struct scatterlist *sglist, int nelems, int direction) +{ + while (nelems--) { + unsigned int npages; + dma_addr_t dma = sglist->dma_address; + unsigned int dmalen = sglist->dma_length; + + if (dmalen == 0) + break; + + npages = num_dma_pages(dma, dmalen); + __iommu_free(tbl, dma, npages); + sglist++; + } +} + +void calgary_unmap_sg(struct device *dev, struct scatterlist *sglist, + int nelems, int direction) +{ + unsigned long flags; + struct iommu_table *tbl = to_pci_dev(dev)->bus->self->sysdata; + + if (!translate_phb(to_pci_dev(dev))) + return; + + spin_lock_irqsave(&tbl->it_lock, flags); + + __calgary_unmap_sg(tbl, sglist, nelems, direction); + + spin_unlock_irqrestore(&tbl->it_lock, flags); +} + +static int calgary_nontranslate_map_sg(struct device* dev, + struct scatterlist *sg, int nelems, int direction) +{ + int i; + + for (i = 0; i < nelems; i++ ) { + struct scatterlist *s = &sg[i]; + BUG_ON(!s->page); + s->dma_address = virt_to_bus(page_address(s->page) +s->offset); + s->dma_length = s->length; + } + return nelems; +} + +int calgary_map_sg(struct device *dev, struct scatterlist *sg, + int nelems, int direction) +{ + struct iommu_table *tbl = to_pci_dev(dev)->bus->self->sysdata; + unsigned long flags; + unsigned long vaddr; + unsigned int npages; + unsigned long entry; + int i; + + if (!translate_phb(to_pci_dev(dev))) + return calgary_nontranslate_map_sg(dev, sg, nelems, direction); + + spin_lock_irqsave(&tbl->it_lock, flags); + + for (i = 0; i < nelems; i++ ) { + struct scatterlist *s = &sg[i]; + BUG_ON(!s->page); + + vaddr = (unsigned long)page_address(s->page) + s->offset; + npages = num_dma_pages(vaddr, s->length); + + entry = iommu_range_alloc(tbl, npages); + if (entry == bad_dma_address) { + /* makes sure unmap knows to stop */ + s->dma_length = 0; + goto error; + } + + s->dma_address = (entry << PAGE_SHIFT) | s->offset; + + /* insert into HW table */ + tce_build(tbl, entry, npages, vaddr & PAGE_MASK, + direction); + + s->dma_length = s->length; + } + + spin_unlock_irqrestore(&tbl->it_lock, flags); + + return nelems; +error: + __calgary_unmap_sg(tbl, sg, nelems, direction); + for (i = 0; i < nelems; i++) { + sg[i].dma_address = bad_dma_address; + sg[i].dma_length = 0; + } + spin_unlock_irqrestore(&tbl->it_lock, flags); + return 0; +} + +dma_addr_t calgary_map_single(struct device *dev, void *vaddr, + size_t size, int direction) +{ + dma_addr_t dma_handle = bad_dma_address; + unsigned long uaddr; + unsigned int npages; + struct iommu_table *tbl = to_pci_dev(dev)->bus->self->sysdata; + + uaddr = (unsigned long)vaddr; + npages = num_dma_pages(uaddr, size); + + if (translate_phb(to_pci_dev(dev))) + dma_handle = iommu_alloc(tbl, vaddr, npages, direction); + else + dma_handle = virt_to_bus(vaddr); + + return dma_handle; +} + +void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle, + size_t size, int direction) +{ + struct iommu_table *tbl = to_pci_dev(dev)->bus->self->sysdata; + unsigned int npages; + + if (!translate_phb(to_pci_dev(dev))) + return; + + npages = num_dma_pages(dma_handle, size); + iommu_free(tbl, dma_handle, npages); +} + +void* calgary_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag) +{ + void *ret = NULL; + dma_addr_t mapping; + unsigned int npages, order; + struct iommu_table *tbl; + + tbl = to_pci_dev(dev)->bus->self->sysdata; + + size = PAGE_ALIGN(size); /* size rounded up to full pages */ + npages = size >> PAGE_SHIFT; + order = get_order(size); + + /* alloc enough pages (and possibly more) */ + ret = (void *)__get_free_pages(flag, order); + if (!ret) + goto error; + memset(ret, 0, size); + + if (translate_phb(to_pci_dev(dev))) { + /* set up tces to cover the allocated range */ + mapping = iommu_alloc(tbl, ret, npages, DMA_BIDIRECTIONAL); + if (mapping == bad_dma_address) + goto free; + + *dma_handle = mapping; + } else /* non translated slot */ + *dma_handle = virt_to_bus(ret); + + return ret; + +free: + free_pages((unsigned long)ret, get_order(size)); + ret = NULL; +error: + return ret; +} + +static struct dma_mapping_ops calgary_dma_ops = { + .alloc_coherent = calgary_alloc_coherent, + .map_single = calgary_map_single, + .unmap_single = calgary_unmap_single, + .map_sg = calgary_map_sg, + .unmap_sg = calgary_unmap_sg, +}; + +static inline int busno_to_phbid(unsigned char num) +{ + return bus_to_phb(num) % PHBS_PER_CALGARY; +} + +static inline unsigned long split_queue_offset(unsigned char num) +{ + size_t idx = busno_to_phbid(num); + + return split_queue_offsets[idx]; +} + +static inline unsigned long tar_offset(unsigned char num) +{ + size_t idx = busno_to_phbid(num); + + return tar_offsets[idx]; +} + +static inline unsigned long phb_offset(unsigned char num) +{ + size_t idx = busno_to_phbid(num); + + return phb_offsets[idx]; +} + +static inline void __iomem* calgary_reg(void __iomem *bar, unsigned long offset) +{ + unsigned long target = ((unsigned long)bar) | offset; + return (void __iomem*)target; +} + +static void tce_cache_blast(struct iommu_table *tbl) +{ + u64 val; + u32 aer; + int i = 0; + void __iomem *bbar = tbl->bbar; + void __iomem *target; + + /* disable arbitration on the bus */ + target = calgary_reg(bbar, phb_offset(tbl->it_busno) | PHB_AER_OFFSET); + aer = readl(target); + writel(0, target); + + /* read plssr to ensure it got there */ + target = calgary_reg(bbar, phb_offset(tbl->it_busno) | PHB_PLSSR_OFFSET); + val = readl(target); + + /* poll split queues until all DMA activity is done */ + target = calgary_reg(bbar, split_queue_offset(tbl->it_busno)); + do { + val = readq(target); + i++; + } while ((val & 0xff) != 0xff && i < 100); + if (i == 100) + printk(KERN_WARNING "Calgary: PCI bus not quiesced, " + "continuing anyway\n"); + + /* invalidate TCE cache */ + target = calgary_reg(bbar, tar_offset(tbl->it_busno)); + writeq(tbl->tar_val, target); + + /* enable arbitration */ + target = calgary_reg(bbar, phb_offset(tbl->it_busno) | PHB_AER_OFFSET); + writel(aer, target); + (void)readl(target); /* flush */ +} + +static void __init calgary_reserve_mem_region(struct pci_dev *dev, u64 start, + u64 limit) +{ + unsigned int numpages; + + limit = limit | 0xfffff; + limit++; + + numpages = ((limit - start) >> PAGE_SHIFT); + iommu_range_reserve(dev->sysdata, start, numpages); +} + +static void __init calgary_reserve_peripheral_mem_1(struct pci_dev *dev) +{ + void __iomem *target; + u64 low, high, sizelow; + u64 start, limit; + struct iommu_table *tbl = dev->sysdata; + unsigned char busnum = dev->bus->number; + void __iomem *bbar = tbl->bbar; + + /* peripheral MEM_1 region */ + target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_1_LOW); + low = be32_to_cpu(readl(target)); + target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_1_HIGH); + high = be32_to_cpu(readl(target)); + target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_1_SIZE); + sizelow = be32_to_cpu(readl(target)); + + start = (high << 32) | low; + limit = sizelow; + + calgary_reserve_mem_region(dev, start, limit); +} + +static void __init calgary_reserve_peripheral_mem_2(struct pci_dev *dev) +{ + void __iomem *target; + u32 val32; + u64 low, high, sizelow, sizehigh; + u64 start, limit; + struct iommu_table *tbl = dev->sysdata; + unsigned char busnum = dev->bus->number; + void __iomem *bbar = tbl->bbar; + + /* is it enabled? */ + target = calgary_reg(bbar, phb_offset(busnum) | PHB_CONFIG_RW_OFFSET); + val32 = be32_to_cpu(readl(target)); + if (!(val32 & PHB_MEM2_ENABLE)) + return; + + target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_2_LOW); + low = be32_to_cpu(readl(target)); + target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_2_HIGH); + high = be32_to_cpu(readl(target)); + target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_2_SIZE_LOW); + sizelow = be32_to_cpu(readl(target)); + target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_2_SIZE_HIGH); + sizehigh = be32_to_cpu(readl(target)); + + start = (high << 32) | low; + limit = (sizehigh << 32) | sizelow; + + calgary_reserve_mem_region(dev, start, limit); +} + +/* + * some regions of the IO address space do not get translated, so we + * must not give devices IO addresses in those regions. The regions + * are the 640KB-1MB region and the two PCI peripheral memory holes. + * Reserve all of them in the IOMMU bitmap to avoid giving them out + * later. + */ +static void __init calgary_reserve_regions(struct pci_dev *dev) +{ + unsigned int npages; + void __iomem *bbar; + unsigned char busnum; + u64 start; + struct iommu_table *tbl = dev->sysdata; + + bbar = tbl->bbar; + busnum = dev->bus->number; + + /* reserve bad_dma_address in case it's a legal address */ + iommu_range_reserve(tbl, bad_dma_address, 1); + + /* avoid the BIOS/VGA first 640KB-1MB region */ + start = (640 * 1024); + npages = ((1024 - 640) * 1024) >> PAGE_SHIFT; + iommu_range_reserve(tbl, start, npages); + + /* reserve the two PCI peripheral memory regions in IO space */ + calgary_reserve_peripheral_mem_1(dev); + calgary_reserve_peripheral_mem_2(dev); +} + +static int __init calgary_setup_tar(struct pci_dev *dev, void __iomem *bbar) +{ + u64 val64; + u64 table_phys; + void __iomem *target; + int ret; + struct iommu_table *tbl; + + /* build TCE tables for each PHB */ + ret = build_tce_table(dev, bbar); + if (ret) + return ret; + + calgary_reserve_regions(dev); + + /* set TARs for each PHB */ + target = calgary_reg(bbar, tar_offset(dev->bus->number)); + val64 = be64_to_cpu(readq(target)); + + /* zero out all TAR bits under sw control */ + val64 &= ~TAR_SW_BITS; + + tbl = dev->sysdata; + table_phys = (u64)__pa(tbl->it_base); + val64 |= table_phys; + + BUG_ON(specified_table_size > TCE_TABLE_SIZE_8M); + val64 |= (u64) specified_table_size; + + tbl->tar_val = cpu_to_be64(val64); + writeq(tbl->tar_val, target); + readq(target); /* flush */ + + return 0; +} + +static void __init calgary_free_tar(struct pci_dev *dev) +{ + u64 val64; + struct iommu_table *tbl = dev->sysdata; + void __iomem *target; + + target = calgary_reg(tbl->bbar, tar_offset(dev->bus->number)); + val64 = be64_to_cpu(readq(target)); + val64 &= ~TAR_SW_BITS; + writeq(cpu_to_be64(val64), target); + readq(target); /* flush */ + + kfree(tbl); + dev->sysdata = NULL; +} + +static void calgary_watchdog(unsigned long data) +{ + struct pci_dev *dev = (struct pci_dev *)data; + struct iommu_table *tbl = dev->sysdata; + void __iomem *bbar = tbl->bbar; + u32 val32; + void __iomem *target; + + target = calgary_reg(bbar, phb_offset(tbl->it_busno) | PHB_CSR_OFFSET); + val32 = be32_to_cpu(readl(target)); + + /* If no error, the agent ID in the CSR is not valid */ + if (val32 & CSR_AGENT_MASK) { + printk(KERN_EMERG "calgary_watchdog: DMA error on bus %d, " + "CSR = %#x\n", dev->bus->number, val32); + writel(0, target); + + /* Disable bus that caused the error */ + target = calgary_reg(bbar, phb_offset(tbl->it_busno) | + PHB_CONFIG_RW_OFFSET); + val32 = be32_to_cpu(readl(target)); + val32 |= PHB_SLOT_DISABLE; + writel(cpu_to_be32(val32), target); + readl(target); /* flush */ + } else { + /* Reset the timer */ + mod_timer(&tbl->watchdog_timer, jiffies + 2 * HZ); + } +} + +static void __init calgary_enable_translation(struct pci_dev *dev) +{ + u32 val32; + unsigned char busnum; + void __iomem *target; + void __iomem *bbar; + struct iommu_table *tbl; + + busnum = dev->bus->number; + tbl = dev->sysdata; + bbar = tbl->bbar; + + /* enable TCE in PHB Config Register */ + target = calgary_reg(bbar, phb_offset(busnum) | PHB_CONFIG_RW_OFFSET); + val32 = be32_to_cpu(readl(target)); + val32 |= PHB_TCE_ENABLE | PHB_DAC_DISABLE | PHB_MCSR_ENABLE; + + printk(KERN_INFO "Calgary: enabling translation on PHB %d\n", busnum); + printk(KERN_INFO "Calgary: errant DMAs will now be prevented on this " + "bus.\n"); + + writel(cpu_to_be32(val32), target); + readl(target); /* flush */ + + init_timer(&tbl->watchdog_timer); + tbl->watchdog_timer.function = &calgary_watchdog; + tbl->watchdog_timer.data = (unsigned long)dev; + mod_timer(&tbl->watchdog_timer, jiffies); +} + +static void __init calgary_disable_translation(struct pci_dev *dev) +{ + u32 val32; + unsigned char busnum; + void __iomem *target; + void __iomem *bbar; + struct iommu_table *tbl; + + busnum = dev->bus->number; + tbl = dev->sysdata; + bbar = tbl->bbar; + + /* disable TCE in PHB Config Register */ + target = calgary_reg(bbar, phb_offset(busnum) | PHB_CONFIG_RW_OFFSET); + val32 = be32_to_cpu(readl(target)); + val32 &= ~(PHB_TCE_ENABLE | PHB_DAC_DISABLE | PHB_MCSR_ENABLE); + + printk(KERN_INFO "Calgary: disabling translation on PHB %d!\n", busnum); + writel(cpu_to_be32(val32), target); + readl(target); /* flush */ + + del_timer_sync(&tbl->watchdog_timer); +} + +static inline unsigned int __init locate_register_space(struct pci_dev *dev) +{ + int rionodeid; + u32 address; + + rionodeid = (dev->bus->number % 15 > 4) ? 3 : 2; + /* + * register space address calculation as follows: + * FE0MB-8MB*OneBasedChassisNumber+1MB*(RioNodeId-ChassisBase) + * ChassisBase is always zero for x366/x260/x460 + * RioNodeId is 2 for first Calgary, 3 for second Calgary + */ + address = START_ADDRESS - + (0x800000 * (ONE_BASED_CHASSIS_NUM + dev->bus->number / 15)) + + (0x100000) * (rionodeid - CHASSIS_BASE); + return address; +} + +static int __init calgary_init_one_nontraslated(struct pci_dev *dev) +{ + dev->sysdata = NULL; + dev->bus->self = dev; + + return 0; +} + +static int __init calgary_init_one(struct pci_dev *dev) +{ + u32 address; + void __iomem *bbar; + int ret; + + address = locate_register_space(dev); + /* map entire 1MB of Calgary config space */ + bbar = ioremap_nocache(address, 1024 * 1024); + if (!bbar) { + ret = -ENODATA; + goto done; + } + + ret = calgary_setup_tar(dev, bbar); + if (ret) + goto iounmap; + + dev->bus->self = dev; + calgary_enable_translation(dev); + + return 0; + +iounmap: + iounmap(bbar); +done: + return ret; +} + +static int __init calgary_init(void) +{ + int i, ret = -ENODEV; + struct pci_dev *dev = NULL; + + for (i = 0; i <= num_online_nodes() * MAX_NUM_OF_PHBS; i++) { + dev = pci_get_device(PCI_VENDOR_ID_IBM, + PCI_DEVICE_ID_IBM_CALGARY, + dev); + if (!dev) + break; + if (!translate_phb(dev)) { + calgary_init_one_nontraslated(dev); + continue; + } + if (!tce_table_kva[i] && !translate_empty_slots) { + pci_dev_put(dev); + continue; + } + ret = calgary_init_one(dev); + if (ret) + goto error; + } + + return ret; + +error: + for (i--; i >= 0; i--) { + dev = pci_find_device_reverse(PCI_VENDOR_ID_IBM, + PCI_DEVICE_ID_IBM_CALGARY, + dev); + if (!translate_phb(dev)) { + pci_dev_put(dev); + continue; + } + if (!tce_table_kva[i] && !translate_empty_slots) + continue; + calgary_disable_translation(dev); + calgary_free_tar(dev); + pci_dev_put(dev); + } + + return ret; +} + +static inline int __init determine_tce_table_size(u64 ram) +{ + int ret; + + if (specified_table_size != TCE_TABLE_SIZE_UNSPECIFIED) + return specified_table_size; + + /* + * Table sizes are from 0 to 7 (TCE_TABLE_SIZE_64K to + * TCE_TABLE_SIZE_8M). Table size 0 has 8K entries and each + * larger table size has twice as many entries, so shift the + * max ram address by 13 to divide by 8K and then look at the + * order of the result to choose between 0-7. + */ + ret = get_order(ram >> 13); + if (ret > TCE_TABLE_SIZE_8M) + ret = TCE_TABLE_SIZE_8M; + + return ret; +} + +void __init detect_calgary(void) +{ + u32 val; + int bus, table_idx; + void *tbl; + int detected = 0; + + /* + * if the user specified iommu=off or iommu=soft or we found + * another HW IOMMU already, bail out. + */ + if (swiotlb || no_iommu || iommu_detected) + return; + + specified_table_size = determine_tce_table_size(end_pfn * PAGE_SIZE); + + for (bus = 0, table_idx = 0; + bus <= num_online_nodes() * MAX_PHB_BUS_NUM; + bus++) { + BUG_ON(bus > MAX_NUMNODES * MAX_PHB_BUS_NUM); + if (read_pci_config(bus, 0, 0, 0) != PCI_VENDOR_DEVICE_ID_CALGARY) + continue; + if (test_bit(bus, translation_disabled)) { + printk(KERN_INFO "Calgary: translation is disabled for " + "PHB 0x%x\n", bus); + /* skip this phb, don't allocate a tbl for it */ + tce_table_kva[table_idx] = NULL; + table_idx++; + continue; + } + /* + * scan the first slot of the PCI bus to see if there + * are any devices present + */ + val = read_pci_config(bus, 1, 0, 0); + if (val != 0xffffffff || translate_empty_slots) { + tbl = alloc_tce_table(); + if (!tbl) + goto cleanup; + detected = 1; + } else + tbl = NULL; + + tce_table_kva[table_idx] = tbl; + table_idx++; + } + + if (detected) { + iommu_detected = 1; + calgary_detected = 1; + printk(KERN_INFO "PCI-DMA: Calgary IOMMU detected. " + "TCE table spec is %d.\n", specified_table_size); + } + return; + +cleanup: + for (--table_idx; table_idx >= 0; --table_idx) + if (tce_table_kva[table_idx]) + free_tce_table(tce_table_kva[table_idx]); +} + +int __init calgary_iommu_init(void) +{ + int ret; + + if (no_iommu || swiotlb) + return -ENODEV; + + if (!calgary_detected) + return -ENODEV; + + /* ok, we're trying to use Calgary - let's roll */ + printk(KERN_INFO "PCI-DMA: Using Calgary IOMMU\n"); + + ret = calgary_init(); + if (ret) { + printk(KERN_ERR "PCI-DMA: Calgary init failed %d, " + "falling back to no_iommu\n", ret); + if (end_pfn > MAX_DMA32_PFN) + printk(KERN_ERR "WARNING more than 4GB of memory, " + "32bit PCI may malfunction.\n"); + return ret; + } + + force_iommu = 1; + dma_ops = &calgary_dma_ops; + + return 0; +} + +static int __init calgary_parse_options(char *p) +{ + unsigned int bridge; + size_t len; + char* endp; + + while (*p) { + if (!strncmp(p, "64k", 3)) + specified_table_size = TCE_TABLE_SIZE_64K; + else if (!strncmp(p, "128k", 4)) + specified_table_size = TCE_TABLE_SIZE_128K; + else if (!strncmp(p, "256k", 4)) + specified_table_size = TCE_TABLE_SIZE_256K; + else if (!strncmp(p, "512k", 4)) + specified_table_size = TCE_TABLE_SIZE_512K; + else if (!strncmp(p, "1M", 2)) + specified_table_size = TCE_TABLE_SIZE_1M; + else if (!strncmp(p, "2M", 2)) + specified_table_size = TCE_TABLE_SIZE_2M; + else if (!strncmp(p, "4M", 2)) + specified_table_size = TCE_TABLE_SIZE_4M; + else if (!strncmp(p, "8M", 2)) + specified_table_size = TCE_TABLE_SIZE_8M; + + len = strlen("translate_empty_slots"); + if (!strncmp(p, "translate_empty_slots", len)) + translate_empty_slots = 1; + + len = strlen("disable"); + if (!strncmp(p, "disable", len)) { + p += len; + if (*p == '=') + ++p; + if (*p == '\0') + break; + bridge = simple_strtol(p, &endp, 0); + if (p == endp) + break; + + if (bridge <= (num_online_nodes() * MAX_PHB_BUS_NUM)) { + printk(KERN_INFO "Calgary: disabling " + "translation for PHB 0x%x\n", bridge); + set_bit(bridge, translation_disabled); + } + } + + p = strpbrk(p, ","); + if (!p) + break; + + p++; /* skip ',' */ + } + return 1; +} +__setup("calgary=", calgary_parse_options); diff --git a/arch/x86_64/kernel/pci-dma.c b/arch/x86_64/kernel/pci-dma.c index a9275c9557c..9c44f4f2433 100644 --- a/arch/x86_64/kernel/pci-dma.c +++ b/arch/x86_64/kernel/pci-dma.c @@ -9,6 +9,7 @@ #include <linux/module.h> #include <asm/io.h> #include <asm/proto.h> +#include <asm/calgary.h> int iommu_merge __read_mostly = 0; EXPORT_SYMBOL(iommu_merge); @@ -33,12 +34,15 @@ int panic_on_overflow __read_mostly = 0; int force_iommu __read_mostly= 0; #endif +/* Set this to 1 if there is a HW IOMMU in the system */ +int iommu_detected __read_mostly = 0; + /* Dummy device used for NULL arguments (normally ISA). Better would be probably a smaller DMA mask, but this is bug-to-bug compatible to i386. */ struct device fallback_dev = { .bus_id = "fallback device", - .coherent_dma_mask = 0xffffffff, + .coherent_dma_mask = DMA_32BIT_MASK, .dma_mask = &fallback_dev.coherent_dma_mask, }; @@ -77,7 +81,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, dev = &fallback_dev; dma_mask = dev->coherent_dma_mask; if (dma_mask == 0) - dma_mask = 0xffffffff; + dma_mask = DMA_32BIT_MASK; /* Don't invoke OOM killer */ gfp |= __GFP_NORETRY; @@ -90,7 +94,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, larger than 16MB and in this case we have a chance of finding fitting memory in the next higher zone first. If not retry with true GFP_DMA. -AK */ - if (dma_mask <= 0xffffffff) + if (dma_mask <= DMA_32BIT_MASK) gfp |= GFP_DMA32; again: @@ -111,7 +115,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, /* Don't use the 16MB ZONE_DMA unless absolutely needed. It's better to use remapping first. */ - if (dma_mask < 0xffffffff && !(gfp & GFP_DMA)) { + if (dma_mask < DMA_32BIT_MASK && !(gfp & GFP_DMA)) { gfp = (gfp & ~GFP_DMA32) | GFP_DMA; goto again; } @@ -174,7 +178,7 @@ int dma_supported(struct device *dev, u64 mask) /* Copied from i386. Doesn't make much sense, because it will only work for pci_alloc_coherent. The caller just has to use GFP_DMA in this case. */ - if (mask < 0x00ffffff) + if (mask < DMA_24BIT_MASK) return 0; /* Tell the device to use SAC when IOMMU force is on. This @@ -189,7 +193,7 @@ int dma_supported(struct device *dev, u64 mask) SAC for these. Assume all masks <= 40 bits are of this type. Normally this doesn't make any difference, but gives more gentle handling of IOMMU overflow. */ - if (iommu_sac_force && (mask >= 0xffffffffffULL)) { + if (iommu_sac_force && (mask >= DMA_40BIT_MASK)) { printk(KERN_INFO "%s: Force SAC with mask %Lx\n", dev->bus_id,mask); return 0; } @@ -266,7 +270,7 @@ __init int iommu_setup(char *p) swiotlb = 1; #endif -#ifdef CONFIG_GART_IOMMU +#ifdef CONFIG_IOMMU gart_parse_options(p); #endif @@ -276,3 +280,40 @@ __init int iommu_setup(char *p) } return 1; } +__setup("iommu=", iommu_setup); + +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(); +#endif + +#ifdef CONFIG_CALGARY_IOMMU + detect_calgary(); +#endif + +#ifdef CONFIG_SWIOTLB + pci_swiotlb_init(); +#endif +} + +static int __init pci_iommu_init(void) +{ +#ifdef CONFIG_CALGARY_IOMMU + calgary_iommu_init(); +#endif + +#ifdef CONFIG_IOMMU + gart_iommu_init(); +#endif + + no_iommu_init(); + return 0; +} + +/* Must execute after PCI subsystem */ +fs_initcall(pci_iommu_init); diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c index 82a7c9bfdfa..4ca674d16b0 100644 --- a/arch/x86_64/kernel/pci-gart.c +++ b/arch/x86_64/kernel/pci-gart.c @@ -32,6 +32,7 @@ #include <asm/kdebug.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_size; /* size of remapping area bytes */ @@ -46,8 +47,6 @@ u32 *iommu_gatt_base; /* Remapping table */ also seen with Qlogic at least). */ int iommu_fullflush = 1; -#define MAX_NB 8 - /* Allocation bitmap for the remapping area */ static DEFINE_SPINLOCK(iommu_bitmap_lock); static unsigned long *iommu_gart_bitmap; /* guarded by iommu_bitmap_lock */ @@ -63,13 +62,6 @@ static u32 gart_unmapped_entry; #define to_pages(addr,size) \ (round_up(((addr) & ~PAGE_MASK) + (size), PAGE_SIZE) >> PAGE_SHIFT) -#define for_all_nb(dev) \ - dev = NULL; \ - while ((dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x1103, dev))!=NULL) - -static struct pci_dev *northbridges[MAX_NB]; -static u32 northbridge_flush_word[MAX_NB]; - #define EMERGENCY_PAGES 32 /* = 128KB */ #ifdef CONFIG_AGP @@ -93,7 +85,7 @@ static unsigned long alloc_iommu(int size) offset = find_next_zero_string(iommu_gart_bitmap,next_bit,iommu_pages,size); if (offset == -1) { need_flush = 1; - offset = find_next_zero_string(iommu_gart_bitmap,0,next_bit,size); + offset = find_next_zero_string(iommu_gart_bitmap,0,iommu_pages,size); } if (offset != -1) { set_bit_string(iommu_gart_bitmap, offset, size); @@ -120,44 +112,17 @@ static void free_iommu(unsigned long offset, int size) /* * Use global flush state to avoid races with multiple flushers. */ -static void flush_gart(struct device *dev) +static void flush_gart(void) { unsigned long flags; - int flushed = 0; - int i, max; - spin_lock_irqsave(&iommu_bitmap_lock, flags); - if (need_flush) { - max = 0; - for (i = 0; i < MAX_NB; i++) { - if (!northbridges[i]) - continue; - pci_write_config_dword(northbridges[i], 0x9c, - northbridge_flush_word[i] | 1); - flushed++; - max = i; - } - for (i = 0; i <= max; i++) { - u32 w; - if (!northbridges[i]) - continue; - /* Make sure the hardware actually executed the flush. */ - for (;;) { - pci_read_config_dword(northbridges[i], 0x9c, &w); - if (!(w & 1)) - break; - cpu_relax(); - } - } - if (!flushed) - printk("nothing to flush?\n"); + if (need_flush) { + k8_flush_garts(); need_flush = 0; } spin_unlock_irqrestore(&iommu_bitmap_lock, flags); } - - #ifdef CONFIG_IOMMU_LEAK #define SET_LEAK(x) if (iommu_leak_tab) \ @@ -266,7 +231,7 @@ static dma_addr_t gart_map_simple(struct device *dev, char *buf, size_t size, int dir) { dma_addr_t map = dma_map_area(dev, virt_to_bus(buf), size, dir); - flush_gart(dev); + flush_gart(); return map; } @@ -289,6 +254,28 @@ dma_addr_t gart_map_single(struct device *dev, void *addr, size_t size, int dir) } /* + * Free a DMA mapping. + */ +void gart_unmap_single(struct device *dev, dma_addr_t dma_addr, + size_t size, int direction) +{ + unsigned long iommu_page; + int npages; + int i; + + if (dma_addr < iommu_bus_base + EMERGENCY_PAGES*PAGE_SIZE || + dma_addr >= iommu_bus_base + iommu_size) + return; + iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT; + npages = to_pages(dma_addr, size); + for (i = 0; i < npages; i++) { + iommu_gatt_base[iommu_page + i] = gart_unmapped_entry; + CLEAR_LEAK(iommu_page + i); + } + free_iommu(iommu_page, npages); +} + +/* * Wrapper for pci_unmap_single working with scatterlists. */ void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) @@ -299,7 +286,7 @@ void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int di struct scatterlist *s = &sg[i]; if (!s->dma_length || !s->length) break; - dma_unmap_single(dev, s->dma_address, s->dma_length, dir); + gart_unmap_single(dev, s->dma_address, s->dma_length, dir); } } @@ -329,7 +316,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg, s->dma_address = addr; s->dma_length = s->length; } - flush_gart(dev); + flush_gart(); return nents; } @@ -436,13 +423,13 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) if (dma_map_cont(sg, start, i, sg+out, pages, need) < 0) goto error; out++; - flush_gart(dev); + flush_gart(); if (out < nents) sg[out].dma_length = 0; return out; error: - flush_gart(NULL); + flush_gart(); gart_unmap_sg(dev, sg, nents, dir); /* When it was forced or merged try again in a dumb way */ if (force_iommu || iommu_merge) { @@ -458,28 +445,6 @@ error: return 0; } -/* - * Free a DMA mapping. - */ -void gart_unmap_single(struct device *dev, dma_addr_t dma_addr, - size_t size, int direction) -{ - unsigned long iommu_page; - int npages; - int i; - - if (dma_addr < iommu_bus_base + EMERGENCY_PAGES*PAGE_SIZE || - dma_addr >= iommu_bus_base + iommu_size) - return; - iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT; - npages = to_pages(dma_addr, size); - for (i = 0; i < npages; i++) { - iommu_gatt_base[iommu_page + i] = gart_unmapped_entry; - CLEAR_LEAK(iommu_page + i); - } - free_iommu(iommu_page, npages); -} - static int no_agp; static __init unsigned long check_iommu_size(unsigned long aper, u64 aper_size) @@ -532,10 +497,13 @@ static __init int init_k8_gatt(struct agp_kern_info *info) void *gatt; unsigned aper_base, new_aper_base; unsigned aper_size, gatt_size, new_aper_size; - + int i; + printk(KERN_INFO "PCI-DMA: Disabling AGP.\n"); aper_size = aper_base = info->aper_size = 0; - for_all_nb(dev) { + dev = NULL; + for (i = 0; i < num_k8_northbridges; i++) { + dev = k8_northbridges[i]; new_aper_base = read_aperture(dev, &new_aper_size); if (!new_aper_base) goto nommu; @@ -558,11 +526,12 @@ static __init int init_k8_gatt(struct agp_kern_info *info) panic("Cannot allocate GATT table"); memset(gatt, 0, gatt_size); agp_gatt_table = gatt; - - for_all_nb(dev) { + + for (i = 0; i < num_k8_northbridges; i++) { u32 ctl; u32 gatt_reg; + dev = k8_northbridges[i]; gatt_reg = __pa(gatt) >> 12; gatt_reg <<= 4; pci_write_config_dword(dev, 0x98, gatt_reg); @@ -573,7 +542,7 @@ static __init int init_k8_gatt(struct agp_kern_info *info) pci_write_config_dword(dev, 0x90, ctl); } - flush_gart(NULL); + flush_gart(); printk("PCI-DMA: aperture base @ %x size %u KB\n",aper_base, aper_size>>10); return 0; @@ -602,15 +571,19 @@ static struct dma_mapping_ops gart_dma_ops = { .unmap_sg = gart_unmap_sg, }; -static int __init pci_iommu_init(void) +void __init gart_iommu_init(void) { struct agp_kern_info info; unsigned long aper_size; unsigned long iommu_start; - struct pci_dev *dev; unsigned long scratch; long i; + if (cache_k8_northbridges() < 0 || num_k8_northbridges == 0) { + printk(KERN_INFO "PCI-GART: No AMD northbridge found.\n"); + return; + } + #ifndef CONFIG_AGP_AMD64 no_agp = 1; #else @@ -622,7 +595,11 @@ static int __init pci_iommu_init(void) #endif if (swiotlb) - return -1; + return; + + /* Did we detect a different HW IOMMU? */ + if (iommu_detected && !iommu_aperture) + return; if (no_iommu || (!force_iommu && end_pfn <= MAX_DMA32_PFN) || @@ -634,15 +611,7 @@ static int __init pci_iommu_init(void) "but IOMMU not available.\n" KERN_ERR "WARNING 32bit PCI may malfunction.\n"); } - return -1; - } - - i = 0; - for_all_nb(dev) - i++; - if (i > MAX_NB) { - printk(KERN_ERR "PCI-GART: Too many northbridges (%ld). Disabled\n", i); - return -1; + return; } printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n"); @@ -707,26 +676,10 @@ static int __init pci_iommu_init(void) for (i = EMERGENCY_PAGES; i < iommu_pages; i++) iommu_gatt_base[i] = gart_unmapped_entry; - for_all_nb(dev) { - u32 flag; - int cpu = PCI_SLOT(dev->devfn) - 24; - if (cpu >= MAX_NB) - continue; - northbridges[cpu] = dev; - pci_read_config_dword(dev, 0x9c, &flag); /* cache flush word */ - northbridge_flush_word[cpu] = flag; - } - - flush_gart(NULL); - + flush_gart(); dma_ops = &gart_dma_ops; - - return 0; } -/* Must execute after PCI subsystem */ -fs_initcall(pci_iommu_init); - void gart_parse_options(char *p) { int arg; diff --git a/arch/x86_64/kernel/pci-nommu.c b/arch/x86_64/kernel/pci-nommu.c index 1f6ecc62061..c4c3cc36ac5 100644 --- a/arch/x86_64/kernel/pci-nommu.c +++ b/arch/x86_64/kernel/pci-nommu.c @@ -4,6 +4,8 @@ #include <linux/init.h> #include <linux/pci.h> #include <linux/string.h> +#include <linux/dma-mapping.h> + #include <asm/proto.h> #include <asm/processor.h> #include <asm/dma.h> @@ -12,10 +14,11 @@ static int check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size) { if (hwdev && bus + size > *hwdev->dma_mask) { - if (*hwdev->dma_mask >= 0xffffffffULL) + if (*hwdev->dma_mask >= DMA_32BIT_MASK) printk(KERN_ERR - "nommu_%s: overflow %Lx+%lu of device mask %Lx\n", - name, (long long)bus, size, (long long)*hwdev->dma_mask); + "nommu_%s: overflow %Lx+%zu of device mask %Lx\n", + name, (long long)bus, size, + (long long)*hwdev->dma_mask); return 0; } return 1; diff --git a/arch/x86_64/kernel/pci-swiotlb.c b/arch/x86_64/kernel/pci-swiotlb.c index 990ed67896f..ebdb77fe205 100644 --- a/arch/x86_64/kernel/pci-swiotlb.c +++ b/arch/x86_64/kernel/pci-swiotlb.c @@ -31,7 +31,7 @@ struct dma_mapping_ops swiotlb_dma_ops = { void pci_swiotlb_init(void) { /* don't initialize swiotlb if iommu=off (no_iommu=1) */ - if (!iommu_aperture && !no_iommu && + if (!iommu_detected && !no_iommu && (end_pfn > MAX_DMA32_PFN || force_iommu)) swiotlb = 1; if (swiotlb) { diff --git a/arch/x86_64/kernel/pmtimer.c b/arch/x86_64/kernel/pmtimer.c index bf421ed2680..7554458dc9c 100644 --- a/arch/x86_64/kernel/pmtimer.c +++ b/arch/x86_64/kernel/pmtimer.c @@ -27,7 +27,7 @@ /* The I/O port the PMTMR resides at. * The location is detected during setup_arch(), * in arch/i386/kernel/acpi/boot.c */ -u32 pmtmr_ioport; +u32 pmtmr_ioport __read_mostly; /* value of the Power timer at last timer interrupt */ static u32 offset_delay; diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index fb903e65e07..ca56e19b8b6 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c @@ -10,7 +10,6 @@ * Andi Kleen. * * CPU hotplug support - ashok.raj@intel.com - * $Id: process.c,v 1.38 2002/01/15 10:08:03 ak Exp $ */ /* @@ -64,6 +63,7 @@ EXPORT_SYMBOL(boot_option_idle_override); * Powermanagement idle function, if any.. */ void (*pm_idle)(void); +EXPORT_SYMBOL(pm_idle); static DEFINE_PER_CPU(unsigned int, cpu_idle_state); static ATOMIC_NOTIFIER_HEAD(idle_notifier); @@ -111,7 +111,7 @@ static void default_idle(void) { local_irq_enable(); - clear_thread_flag(TIF_POLLING_NRFLAG); + current_thread_info()->status &= ~TS_POLLING; smp_mb__after_clear_bit(); while (!need_resched()) { local_irq_disable(); @@ -120,7 +120,7 @@ static void default_idle(void) else local_irq_enable(); } - set_thread_flag(TIF_POLLING_NRFLAG); + current_thread_info()->status |= TS_POLLING; } /* @@ -203,8 +203,7 @@ static inline void play_dead(void) */ void cpu_idle (void) { - set_thread_flag(TIF_POLLING_NRFLAG); - + current_thread_info()->status |= TS_POLLING; /* endless idle loop with no priority at all */ while (1) { while (!need_resched()) { @@ -335,7 +334,7 @@ void show_regs(struct pt_regs *regs) { printk("CPU %d:", smp_processor_id()); __show_regs(regs); - show_trace(®s->rsp); + show_trace(NULL, regs, (void *)(regs + 1)); } /* @@ -365,8 +364,11 @@ void flush_thread(void) struct task_struct *tsk = current; struct thread_info *t = current_thread_info(); - if (t->flags & _TIF_ABI_PENDING) + if (t->flags & _TIF_ABI_PENDING) { t->flags ^= (_TIF_ABI_PENDING | _TIF_IA32); + if (t->flags & _TIF_IA32) + current_thread_info()->status |= TS_COMPAT; + } tsk->thread.debugreg0 = 0; tsk->thread.debugreg1 = 0; diff --git a/arch/x86_64/kernel/reboot.c b/arch/x86_64/kernel/reboot.c index 57117b8beb2..2d676984745 100644 --- a/arch/x86_64/kernel/reboot.c +++ b/arch/x86_64/kernel/reboot.c @@ -20,6 +20,7 @@ * Power off function, if any */ void (*pm_power_off)(void); +EXPORT_SYMBOL(pm_power_off); static long no_idt[3]; static enum { diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index fdb82658b1a..1129918ede8 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -5,8 +5,6 @@ * * Nov 2001 Dave Jones <davej@suse.de> * Forked from i386 setup code. - * - * $Id$ */ /* @@ -47,7 +45,6 @@ #include <linux/dmi.h> #include <linux/dma-mapping.h> #include <linux/ctype.h> -#include <linux/suspend.h> #include <asm/mtrr.h> #include <asm/uaccess.h> @@ -66,9 +63,7 @@ #include <asm/setup.h> #include <asm/mach_apic.h> #include <asm/numa.h> -#include <asm/swiotlb.h> #include <asm/sections.h> -#include <asm/gart-mapping.h> #include <asm/dmi.h> /* @@ -76,6 +71,7 @@ */ struct cpuinfo_x86 boot_cpu_data __read_mostly; +EXPORT_SYMBOL(boot_cpu_data); unsigned long mmu_cr4_features; @@ -104,12 +100,14 @@ char dmi_alloc_data[DMI_MAX_DATA]; * Setup options */ struct screen_info screen_info; +EXPORT_SYMBOL(screen_info); struct sys_desc_table_struct { unsigned short length; unsigned char table[0]; }; struct edid_info edid_info; +EXPORT_SYMBOL_GPL(edid_info); struct e820map e820; extern int root_mountflags; @@ -474,80 +472,6 @@ contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn) } #endif -/* Use inline assembly to define this because the nops are defined - as inline assembly strings in the include files and we cannot - get them easily into strings. */ -asm("\t.data\nk8nops: " - K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6 - K8_NOP7 K8_NOP8); - -extern unsigned char k8nops[]; -static unsigned char *k8_nops[ASM_NOP_MAX+1] = { - NULL, - k8nops, - k8nops + 1, - k8nops + 1 + 2, - k8nops + 1 + 2 + 3, - k8nops + 1 + 2 + 3 + 4, - k8nops + 1 + 2 + 3 + 4 + 5, - k8nops + 1 + 2 + 3 + 4 + 5 + 6, - k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, -}; - -extern char __vsyscall_0; - -/* Replace instructions with better alternatives for this CPU type. - - This runs before SMP is initialized to avoid SMP problems with - self modifying code. This implies that assymetric systems where - APs have less capabilities than the boot processor are not handled. - In this case boot with "noreplacement". */ -void apply_alternatives(void *start, void *end) -{ - struct alt_instr *a; - int diff, i, k; - for (a = start; (void *)a < end; a++) { - u8 *instr; - - if (!boot_cpu_has(a->cpuid)) - continue; - - BUG_ON(a->replacementlen > a->instrlen); - instr = a->instr; - /* vsyscall code is not mapped yet. resolve it manually. */ - if (instr >= (u8 *)VSYSCALL_START && instr < (u8*)VSYSCALL_END) - instr = __va(instr - (u8*)VSYSCALL_START + (u8*)__pa_symbol(&__vsyscall_0)); - __inline_memcpy(instr, a->replacement, a->replacementlen); - diff = a->instrlen - a->replacementlen; - - /* Pad the rest with nops */ - for (i = a->replacementlen; diff > 0; diff -= k, i += k) { - k = diff; - if (k > ASM_NOP_MAX) - k = ASM_NOP_MAX; - __inline_memcpy(instr + i, k8_nops[k], k); - } - } -} - -static int no_replacement __initdata = 0; - -void __init alternative_instructions(void) -{ - extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; - if (no_replacement) - return; - apply_alternatives(__alt_instructions, __alt_instructions_end); -} - -static int __init noreplacement_setup(char *s) -{ - no_replacement = 1; - return 1; -} - -__setup("noreplacement", noreplacement_setup); - #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) struct edd edd; #ifdef CONFIG_EDD_MODULE @@ -596,100 +520,6 @@ static void discover_ebda(void) ebda_size = 64*1024; } -#ifdef CONFIG_SOFTWARE_SUSPEND -static void __init mark_nosave_page_range(unsigned long start, unsigned long end) -{ - struct page *page; - while (start <= end) { - page = pfn_to_page(start); - SetPageNosave(page); - start++; - } -} - -static void __init e820_nosave_reserved_pages(void) -{ - int i; - unsigned long r_start = 0, r_end = 0; - - /* Assume e820 map is sorted */ - for (i = 0; i < e820.nr_map; i++) { - struct e820entry *ei = &e820.map[i]; - unsigned long start, end; - - start = round_down(ei->addr, PAGE_SIZE); - end = round_up(ei->addr + ei->size, PAGE_SIZE); - if (start >= end) - continue; - if (ei->type == E820_RESERVED) - continue; - r_end = start>>PAGE_SHIFT; - /* swsusp ignores invalid pfn, ignore these pages here */ - if (r_end > end_pfn) - r_end = end_pfn; - if (r_end > r_start) - mark_nosave_page_range(r_start, r_end-1); - if (r_end >= end_pfn) - break; - r_start = end>>PAGE_SHIFT; - } -} - -static void __init e820_save_acpi_pages(void) -{ - int i; - - /* Assume e820 map is sorted */ - for (i = 0; i < e820.nr_map; i++) { - struct e820entry *ei = &e820.map[i]; - unsigned long start, end; - - start = ei->addr, PAGE_SIZE; - end = ei->addr + ei->size; - if (start >= end) - continue; - if (ei->type != E820_ACPI && ei->type != E820_NVS) - continue; - /* - * If the region is below end_pfn, it will be - * saved/restored by swsusp follow 'RAM' type. - */ - if (start < (end_pfn << PAGE_SHIFT)) - start = end_pfn << PAGE_SHIFT; - if (end > start) - swsusp_add_arch_pages(start, end); - } -} - -extern char __start_rodata, __end_rodata; -/* - * BIOS reserved region/hole - no save/restore - * ACPI NVS - save/restore - * ACPI Data - this is a little tricky, the mem could be used by OS after OS - * reads tables from the region, but anyway save/restore the memory hasn't any - * side effect and Linux runtime module load/unload might use it. - * kernel rodata - no save/restore (kernel rodata isn't changed) - */ -static int __init mark_nosave_pages(void) -{ - unsigned long pfn_start, pfn_end; - - /* BIOS reserved regions & holes */ - e820_nosave_reserved_pages(); - - /* kernel rodata */ - pfn_start = round_up(__pa_symbol(&__start_rodata), PAGE_SIZE) >> PAGE_SHIFT; - pfn_end = round_down(__pa_symbol(&__end_rodata), PAGE_SIZE) >> PAGE_SHIFT; - mark_nosave_page_range(pfn_start, pfn_end-1); - - /* record ACPI Data/NVS as saveable */ - e820_save_acpi_pages(); - - return 0; -} -core_initcall(mark_nosave_pages); -#endif - void __init setup_arch(char **cmdline_p) { unsigned long kernel_end; @@ -874,10 +704,6 @@ void __init setup_arch(char **cmdline_p) e820_setup_gap(); -#ifdef CONFIG_GART_IOMMU - iommu_hole_init(); -#endif - #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE) conswitchp = &vga_con; @@ -962,24 +788,32 @@ static int nearby_node(int apicid) static void __init amd_detect_cmp(struct cpuinfo_x86 *c) { #ifdef CONFIG_SMP - int cpu = smp_processor_id(); unsigned bits; #ifdef CONFIG_NUMA + int cpu = smp_processor_id(); int node = 0; unsigned apicid = hard_smp_processor_id(); #endif + unsigned ecx = cpuid_ecx(0x80000008); - bits = 0; - while ((1 << bits) < c->x86_max_cores) - bits++; + c->x86_max_cores = (ecx & 0xff) + 1; + + /* CPU telling us the core id bits shift? */ + bits = (ecx >> 12) & 0xF; + + /* Otherwise recompute */ + if (bits == 0) { + while ((1 << bits) < c->x86_max_cores) + bits++; + } /* Low order bits define the core id (index of core in socket) */ - cpu_core_id[cpu] = phys_proc_id[cpu] & ((1 << bits)-1); + c->cpu_core_id = c->phys_proc_id & ((1 << bits)-1); /* Convert the APIC ID into the socket ID */ - phys_proc_id[cpu] = phys_pkg_id(bits); + c->phys_proc_id = phys_pkg_id(bits); #ifdef CONFIG_NUMA - node = phys_proc_id[cpu]; + node = c->phys_proc_id; if (apicid_to_node[apicid] != NUMA_NO_NODE) node = apicid_to_node[apicid]; if (!node_online(node)) { @@ -992,7 +826,7 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c) but in the same order as the HT nodeids. If that doesn't result in a usable node fall back to the path for the previous case. */ - int ht_nodeid = apicid - (phys_proc_id[0] << bits); + int ht_nodeid = apicid - (cpu_data[0].phys_proc_id << bits); if (ht_nodeid >= 0 && apicid_to_node[ht_nodeid] != NUMA_NO_NODE) node = apicid_to_node[ht_nodeid]; @@ -1002,15 +836,13 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c) } numa_set_node(cpu, node); - printk(KERN_INFO "CPU %d/%x(%d) -> Node %d -> Core %d\n", - cpu, apicid, c->x86_max_cores, node, cpu_core_id[cpu]); + printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node); #endif #endif } -static int __init init_amd(struct cpuinfo_x86 *c) +static void __init init_amd(struct cpuinfo_x86 *c) { - int r; unsigned level; #ifdef CONFIG_SMP @@ -1043,8 +875,8 @@ static int __init init_amd(struct cpuinfo_x86 *c) if (c->x86 >= 6) set_bit(X86_FEATURE_FXSAVE_LEAK, &c->x86_capability); - r = get_model_name(c); - if (!r) { + level = get_model_name(c); + if (!level) { switch (c->x86) { case 15: /* Should distinguish Models here, but this is only @@ -1059,13 +891,12 @@ static int __init init_amd(struct cpuinfo_x86 *c) if (c->x86_power & (1<<8)) set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability); - if (c->extended_cpuid_level >= 0x80000008) { - c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1; - + /* Multi core CPU? */ + if (c->extended_cpuid_level >= 0x80000008) amd_detect_cmp(c); - } - return r; + /* Fix cpuid4 emulation for more */ + num_cache_leaves = 3; } static void __cpuinit detect_ht(struct cpuinfo_x86 *c) @@ -1073,13 +904,14 @@ static void __cpuinit detect_ht(struct cpuinfo_x86 *c) #ifdef CONFIG_SMP u32 eax, ebx, ecx, edx; int index_msb, core_bits; - int cpu = smp_processor_id(); cpuid(1, &eax, &ebx, &ecx, &edx); - if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY)) + if (!cpu_has(c, X86_FEATURE_HT)) return; + if (cpu_has(c, X86_FEATURE_CMP_LEGACY)) + goto out; smp_num_siblings = (ebx & 0xff0000) >> 16; @@ -1094,10 +926,7 @@ static void __cpuinit detect_ht(struct cpuinfo_x86 *c) } index_msb = get_count_order(smp_num_siblings); - phys_proc_id[cpu] = phys_pkg_id(index_msb); - - printk(KERN_INFO "CPU: Physical Processor ID: %d\n", - phys_proc_id[cpu]); + c->phys_proc_id = phys_pkg_id(index_msb); smp_num_siblings = smp_num_siblings / c->x86_max_cores; @@ -1105,13 +934,15 @@ static void __cpuinit detect_ht(struct cpuinfo_x86 *c) core_bits = get_count_order(c->x86_max_cores); - cpu_core_id[cpu] = phys_pkg_id(index_msb) & + c->cpu_core_id = phys_pkg_id(index_msb) & ((1 << core_bits) - 1); - - if (c->x86_max_cores > 1) - printk(KERN_INFO "CPU: Processor Core ID: %d\n", - cpu_core_id[cpu]); } +out: + if ((c->x86_max_cores * smp_num_siblings) > 1) { + printk(KERN_INFO "CPU: Physical Processor ID: %d\n", c->phys_proc_id); + printk(KERN_INFO "CPU: Processor Core ID: %d\n", c->cpu_core_id); + } + #endif } @@ -1120,15 +951,12 @@ static void __cpuinit detect_ht(struct cpuinfo_x86 *c) */ static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c) { - unsigned int eax; + unsigned int eax, t; if (c->cpuid_level < 4) return 1; - __asm__("cpuid" - : "=a" (eax) - : "0" (4), "c" (0) - : "bx", "dx"); + cpuid_count(4, 0, &eax, &t, &t, &t); if (eax & 0x1f) return ((eax >> 26) + 1); @@ -1141,16 +969,17 @@ static void srat_detect_node(void) #ifdef CONFIG_NUMA unsigned node; int cpu = smp_processor_id(); + int apicid = hard_smp_processor_id(); /* Don't do the funky fallback heuristics the AMD version employs for now. */ - node = apicid_to_node[hard_smp_processor_id()]; + node = apicid_to_node[apicid]; if (node == NUMA_NO_NODE) node = first_node(node_online_map); numa_set_node(cpu, node); if (acpi_numa > 0) - printk(KERN_INFO "CPU %d -> Node %d\n", cpu, node); + printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node); #endif } @@ -1160,6 +989,13 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) unsigned n; init_intel_cacheinfo(c); + if (c->cpuid_level > 9 ) { + unsigned eax = cpuid_eax(10); + /* Check for version and the number of counters */ + if ((eax & 0xff) && (((eax>>8) & 0xff) > 1)) + set_bit(X86_FEATURE_ARCH_PERFMON, &c->x86_capability); + } + n = c->extended_cpuid_level; if (n >= 0x80000008) { unsigned eax = cpuid_eax(0x80000008); @@ -1251,7 +1087,7 @@ void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c) } #ifdef CONFIG_SMP - phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff; + c->phys_proc_id = (cpuid_ebx(1) >> 24) & 0xff; #endif } @@ -1378,7 +1214,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "nx", NULL, "mmxext", NULL, - NULL, "fxsr_opt", "rdtscp", NULL, NULL, "lm", "3dnowext", "3dnow", + NULL, "fxsr_opt", NULL, "rdtscp", NULL, "lm", "3dnowext", "3dnow", /* Transmeta-defined */ "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL, @@ -1389,7 +1225,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) /* Other (Linux-defined) */ "cxmmx", NULL, "cyrix_arr", "centaur_mcr", NULL, "constant_tsc", NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + "up", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -1459,9 +1295,9 @@ static int show_cpuinfo(struct seq_file *m, void *v) #ifdef CONFIG_SMP if (smp_num_siblings * c->x86_max_cores > 1) { int cpu = c - cpu_data; - seq_printf(m, "physical id\t: %d\n", phys_proc_id[cpu]); + seq_printf(m, "physical id\t: %d\n", c->phys_proc_id); seq_printf(m, "siblings\t: %d\n", cpus_weight(cpu_core_map[cpu])); - seq_printf(m, "core id\t\t: %d\n", cpu_core_id[cpu]); + seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id); seq_printf(m, "cpu cores\t: %d\n", c->booted_cores); } #endif @@ -1535,7 +1371,7 @@ struct seq_operations cpuinfo_op = { .show = show_cpuinfo, }; -#ifdef CONFIG_INPUT_PCSPKR +#if defined(CONFIG_INPUT_PCSPKR) || defined(CONFIG_INPUT_PCSPKR_MODULE) #include <linux/platform_device.h> static __init int add_pcspkr(void) { diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c index 8a691fa6d39..f5934cb4a2b 100644 --- a/arch/x86_64/kernel/setup64.c +++ b/arch/x86_64/kernel/setup64.c @@ -3,7 +3,6 @@ * Copyright (C) 1995 Linus Torvalds * Copyright 2001, 2002, 2003 SuSE Labs / Andi Kleen. * See setup.c for older changelog. - * $Id: setup64.c,v 1.12 2002/03/21 10:09:17 ak Exp $ */ #include <linux/config.h> #include <linux/init.h> @@ -31,6 +30,7 @@ char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,}; cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE; struct x8664_pda *_cpu_pda[NR_CPUS] __read_mostly; +EXPORT_SYMBOL(_cpu_pda); struct x8664_pda boot_cpu_pda[NR_CPUS] __cacheline_aligned; struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; @@ -38,6 +38,7 @@ struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned"))); unsigned long __supported_pte_mask __read_mostly = ~0UL; +EXPORT_SYMBOL(__supported_pte_mask); static int do_not_nx __cpuinitdata = 0; /* noexec=on|off diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c index e5f5ce7909a..28161170fb0 100644 --- a/arch/x86_64/kernel/signal.c +++ b/arch/x86_64/kernel/signal.c @@ -7,8 +7,6 @@ * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes * 2000-2002 x86-64 support by Andi Kleen - * - * $Id: signal.c,v 1.18 2001/10/17 22:30:37 ak Exp $ */ #include <linux/sched.h> @@ -239,7 +237,6 @@ get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size) rsp = regs->rsp - 128; /* This is the X/Open sanctioned signal stack switching. */ - /* RED-PEN: redzone on that stack? */ if (ka->sa.sa_flags & SA_ONSTACK) { if (sas_ss_flags(rsp) == 0) rsp = current->sas_ss_sp + current->sas_ss_size; diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c index 4a6628b14d9..5a1c0a3bf87 100644 --- a/arch/x86_64/kernel/smp.c +++ b/arch/x86_64/kernel/smp.c @@ -135,10 +135,10 @@ asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs) cpu = smp_processor_id(); /* - * orig_rax contains the interrupt vector - 256. + * orig_rax contains the negated interrupt vector. * Use that to determine where the sender put the data. */ - sender = regs->orig_rax + 256 - INVALIDATE_TLB_VECTOR_START; + sender = ~regs->orig_rax - INVALIDATE_TLB_VECTOR_START; f = &per_cpu(flush_state, sender); if (!cpu_isset(cpu, f->flush_cpumask)) @@ -224,6 +224,7 @@ void flush_tlb_current_task(void) flush_tlb_others(cpu_mask, mm, FLUSH_ALL); preempt_enable(); } +EXPORT_SYMBOL(flush_tlb_current_task); void flush_tlb_mm (struct mm_struct * mm) { @@ -244,6 +245,7 @@ void flush_tlb_mm (struct mm_struct * mm) preempt_enable(); } +EXPORT_SYMBOL(flush_tlb_mm); void flush_tlb_page(struct vm_area_struct * vma, unsigned long va) { @@ -266,6 +268,7 @@ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va) preempt_enable(); } +EXPORT_SYMBOL(flush_tlb_page); static void do_flush_tlb_all(void* info) { @@ -443,6 +446,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, spin_unlock(&call_lock); return 0; } +EXPORT_SYMBOL(smp_call_function); void smp_stop_cpu(void) { @@ -460,7 +464,7 @@ static void smp_really_stop_cpu(void *dummy) { smp_stop_cpu(); for (;;) - asm("hlt"); + halt(); } void smp_send_stop(void) @@ -470,7 +474,7 @@ void smp_send_stop(void) return; /* Don't deadlock on the call lock in panic */ if (!spin_trylock(&call_lock)) { - /* ignore locking because we have paniced anyways */ + /* ignore locking because we have panicked anyways */ nolock = 1; } __smp_call_function(smp_really_stop_cpu, NULL, 0, 0); @@ -520,13 +524,13 @@ asmlinkage void smp_call_function_interrupt(void) int safe_smp_processor_id(void) { - int apicid, i; + unsigned apicid, i; if (disable_apic) return 0; apicid = hard_smp_processor_id(); - if (x86_cpu_to_apicid[apicid] == apicid) + if (apicid < NR_CPUS && x86_cpu_to_apicid[apicid] == apicid) return apicid; for (i = 0; i < NR_CPUS; ++i) { diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index 71a7222cf9c..540c0ccbccc 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c @@ -63,13 +63,11 @@ /* Number of siblings per CPU package */ int smp_num_siblings = 1; -/* Package ID of each logical CPU */ -u8 phys_proc_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID }; -/* core ID of each logical CPU */ -u8 cpu_core_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID }; +EXPORT_SYMBOL(smp_num_siblings); /* Last level cache ID of each logical CPU */ u8 cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID}; +EXPORT_SYMBOL(cpu_llc_id); /* Bitmask of currently online CPUs */ cpumask_t cpu_online_map __read_mostly; @@ -82,18 +80,21 @@ EXPORT_SYMBOL(cpu_online_map); */ cpumask_t cpu_callin_map; cpumask_t cpu_callout_map; +EXPORT_SYMBOL(cpu_callout_map); cpumask_t cpu_possible_map; EXPORT_SYMBOL(cpu_possible_map); /* Per CPU bogomips and other parameters */ struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; +EXPORT_SYMBOL(cpu_data); /* Set when the idlers are all forked */ int smp_threads_ready; /* representing HT siblings of each logical CPU */ cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly; +EXPORT_SYMBOL(cpu_sibling_map); /* representing HT and core siblings of each logical CPU */ cpumask_t cpu_core_map[NR_CPUS] __read_mostly; @@ -454,10 +455,12 @@ cpumask_t cpu_coregroup_map(int cpu) struct cpuinfo_x86 *c = cpu_data + cpu; /* * For perf, we return last level cache shared map. - * TBD: when power saving sched policy is added, we will return - * cpu_core_map when power saving policy is enabled + * And for power savings, we return cpu_core_map */ - return c->llc_shared_map; + if (sched_mc_power_savings || sched_smt_power_savings) + return cpu_core_map[cpu]; + else + return c->llc_shared_map; } /* representing cpus for which sibling maps can be computed */ @@ -472,8 +475,8 @@ static inline void set_cpu_sibling_map(int cpu) if (smp_num_siblings > 1) { for_each_cpu_mask(i, cpu_sibling_setup_map) { - if (phys_proc_id[cpu] == phys_proc_id[i] && - cpu_core_id[cpu] == cpu_core_id[i]) { + if (c[cpu].phys_proc_id == c[i].phys_proc_id && + c[cpu].cpu_core_id == c[i].cpu_core_id) { cpu_set(i, cpu_sibling_map[cpu]); cpu_set(cpu, cpu_sibling_map[i]); cpu_set(i, cpu_core_map[cpu]); @@ -500,7 +503,7 @@ static inline void set_cpu_sibling_map(int cpu) cpu_set(i, c[cpu].llc_shared_map); cpu_set(cpu, c[i].llc_shared_map); } - if (phys_proc_id[cpu] == phys_proc_id[i]) { + if (c[cpu].phys_proc_id == c[i].phys_proc_id) { cpu_set(i, cpu_core_map[cpu]); cpu_set(cpu, cpu_core_map[i]); /* @@ -797,6 +800,8 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid) } + alternatives_smp_switch(1); + c_idle.idle = get_idle_for_cpu(cpu); if (c_idle.idle) { @@ -1199,8 +1204,8 @@ static void remove_siblinginfo(int cpu) cpu_clear(cpu, cpu_sibling_map[sibling]); cpus_clear(cpu_sibling_map[cpu]); cpus_clear(cpu_core_map[cpu]); - phys_proc_id[cpu] = BAD_APICID; - cpu_core_id[cpu] = BAD_APICID; + c[cpu].phys_proc_id = 0; + c[cpu].cpu_core_id = 0; cpu_clear(cpu, cpu_sibling_setup_map); } @@ -1259,6 +1264,8 @@ void __cpu_die(unsigned int cpu) /* They ack this in play_dead by setting CPU_DEAD */ if (per_cpu(cpu_state, cpu) == CPU_DEAD) { printk ("CPU %d is now offline\n", cpu); + if (1 == num_online_cpus()) + alternatives_smp_switch(0); return; } msleep(100); diff --git a/arch/x86_64/kernel/tce.c b/arch/x86_64/kernel/tce.c new file mode 100644 index 00000000000..8d4c67f61b8 --- /dev/null +++ b/arch/x86_64/kernel/tce.c @@ -0,0 +1,202 @@ +/* + * Derived from arch/powerpc/platforms/pseries/iommu.c + * + * Copyright (C) 2006 Jon Mason <jdmason@us.ibm.com>, IBM Corporation + * Copyright (C) 2006 Muli Ben-Yehuda <muli@il.ibm.com>, IBM Corporation + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/config.h> +#include <linux/types.h> +#include <linux/slab.h> +#include <linux/mm.h> +#include <linux/spinlock.h> +#include <linux/string.h> +#include <linux/pci.h> +#include <linux/dma-mapping.h> +#include <linux/bootmem.h> +#include <asm/tce.h> +#include <asm/calgary.h> +#include <asm/proto.h> + +/* flush a tce at 'tceaddr' to main memory */ +static inline void flush_tce(void* tceaddr) +{ + /* a single tce can't cross a cache line */ + if (cpu_has_clflush) + asm volatile("clflush (%0)" :: "r" (tceaddr)); + else + asm volatile("wbinvd":::"memory"); +} + +void tce_build(struct iommu_table *tbl, unsigned long index, + unsigned int npages, unsigned long uaddr, int direction) +{ + u64* tp; + u64 t; + u64 rpn; + + t = (1 << TCE_READ_SHIFT); + if (direction != DMA_TO_DEVICE) + t |= (1 << TCE_WRITE_SHIFT); + + tp = ((u64*)tbl->it_base) + index; + + while (npages--) { + rpn = (virt_to_bus((void*)uaddr)) >> PAGE_SHIFT; + t &= ~TCE_RPN_MASK; + t |= (rpn << TCE_RPN_SHIFT); + + *tp = cpu_to_be64(t); + flush_tce(tp); + + uaddr += PAGE_SIZE; + tp++; + } +} + +void tce_free(struct iommu_table *tbl, long index, unsigned int npages) +{ + u64* tp; + + tp = ((u64*)tbl->it_base) + index; + + while (npages--) { + *tp = cpu_to_be64(0); + flush_tce(tp); + tp++; + } +} + +static inline unsigned int table_size_to_number_of_entries(unsigned char size) +{ + /* + * size is the order of the table, 0-7 + * smallest table is 8K entries, so shift result by 13 to + * multiply by 8K + */ + return (1 << size) << 13; +} + +static int tce_table_setparms(struct pci_dev *dev, struct iommu_table *tbl) +{ + unsigned int bitmapsz; + unsigned int tce_table_index; + unsigned long bmppages; + int ret; + + tbl->it_busno = dev->bus->number; + + /* set the tce table size - measured in entries */ + tbl->it_size = table_size_to_number_of_entries(specified_table_size); + + tce_table_index = bus_to_phb(tbl->it_busno); + tbl->it_base = (unsigned long)tce_table_kva[tce_table_index]; + if (!tbl->it_base) { + printk(KERN_ERR "Calgary: iommu_table_setparms: " + "no table allocated?!\n"); + ret = -ENOMEM; + goto done; + } + + /* + * number of bytes needed for the bitmap size in number of + * entries; we need one bit per entry + */ + bitmapsz = tbl->it_size / BITS_PER_BYTE; + bmppages = __get_free_pages(GFP_KERNEL, get_order(bitmapsz)); + if (!bmppages) { + printk(KERN_ERR "Calgary: cannot allocate bitmap\n"); + ret = -ENOMEM; + goto done; + } + + tbl->it_map = (unsigned long*)bmppages; + + memset(tbl->it_map, 0, bitmapsz); + + tbl->it_hint = 0; + + spin_lock_init(&tbl->it_lock); + + return 0; + +done: + return ret; +} + +int build_tce_table(struct pci_dev *dev, void __iomem *bbar) +{ + struct iommu_table *tbl; + int ret; + + if (dev->sysdata) { + printk(KERN_ERR "Calgary: dev %p has sysdata %p\n", + dev, dev->sysdata); + BUG(); + } + + tbl = kzalloc(sizeof(struct iommu_table), GFP_KERNEL); + if (!tbl) { + printk(KERN_ERR "Calgary: error allocating iommu_table\n"); + ret = -ENOMEM; + goto done; + } + + ret = tce_table_setparms(dev, tbl); + if (ret) + goto free_tbl; + + tce_free(tbl, 0, tbl->it_size); + + tbl->bbar = bbar; + + /* + * NUMA is already using the bus's sysdata pointer, so we use + * the bus's pci_dev's sysdata instead. + */ + dev->sysdata = tbl; + + return 0; + +free_tbl: + kfree(tbl); +done: + return ret; +} + +void* alloc_tce_table(void) +{ + unsigned int size; + + size = table_size_to_number_of_entries(specified_table_size); + size *= TCE_ENTRY_SIZE; + + return __alloc_bootmem_low(size, size, 0); +} + +void free_tce_table(void *tbl) +{ + unsigned int size; + + if (!tbl) + return; + + size = table_size_to_number_of_entries(specified_table_size); + size *= TCE_ENTRY_SIZE; + + free_bootmem(__pa(tbl), size); +} diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index 7392570f975..ebbee6f59ff 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c @@ -8,7 +8,7 @@ * Copyright (c) 1995 Markus Kuhn * Copyright (c) 1996 Ingo Molnar * Copyright (c) 1998 Andrea Arcangeli - * Copyright (c) 2002 Vojtech Pavlik + * Copyright (c) 2002,2006 Vojtech Pavlik * Copyright (c) 2003 Andi Kleen * RTC support code taken from arch/i386/kernel/timers/time_hpet.c */ @@ -51,14 +51,21 @@ extern int using_apic_timer; static char *time_init_gtod(void); DEFINE_SPINLOCK(rtc_lock); +EXPORT_SYMBOL(rtc_lock); DEFINE_SPINLOCK(i8253_lock); int nohpet __initdata = 0; static int notsc __initdata = 0; -#undef HPET_HACK_ENABLE_DANGEROUS +#define USEC_PER_TICK (USEC_PER_SEC / HZ) +#define NSEC_PER_TICK (NSEC_PER_SEC / HZ) +#define FSEC_PER_TICK (FSEC_PER_SEC / HZ) + +#define NS_SCALE 10 /* 2^10, carefully chosen */ +#define US_SCALE 32 /* 2^32, arbitralrily chosen */ unsigned int cpu_khz; /* TSC clocks / usec, not used here */ +EXPORT_SYMBOL(cpu_khz); static unsigned long hpet_period; /* fsecs / HPET clock */ unsigned long hpet_tick; /* HPET clocks / interrupt */ int hpet_use_timer; /* Use counter of hpet for time keeping, otherwise PIT */ @@ -90,7 +97,7 @@ static inline unsigned int do_gettimeoffset_tsc(void) t = get_cycles_sync(); if (t < vxtime.last_tsc) t = vxtime.last_tsc; /* hack */ - x = ((t - vxtime.last_tsc) * vxtime.tsc_quot) >> 32; + x = ((t - vxtime.last_tsc) * vxtime.tsc_quot) >> US_SCALE; return x; } @@ -98,7 +105,7 @@ static inline unsigned int do_gettimeoffset_hpet(void) { /* cap counter read to one tick to avoid inconsistencies */ unsigned long counter = hpet_readl(HPET_COUNTER) - vxtime.last; - return (min(counter,hpet_tick) * vxtime.quot) >> 32; + return (min(counter,hpet_tick) * vxtime.quot) >> US_SCALE; } unsigned int (*do_gettimeoffset)(void) = do_gettimeoffset_tsc; @@ -118,7 +125,7 @@ void do_gettimeofday(struct timeval *tv) seq = read_seqbegin(&xtime_lock); sec = xtime.tv_sec; - usec = xtime.tv_nsec / 1000; + usec = xtime.tv_nsec / NSEC_PER_USEC; /* i386 does some correction here to keep the clock monotonous even when ntpd is fixing drift. @@ -129,14 +136,14 @@ void do_gettimeofday(struct timeval *tv) in arch/x86_64/kernel/vsyscall.c and export all needed variables in vmlinux.lds. -AK */ - t = (jiffies - wall_jiffies) * (1000000L / HZ) + + t = (jiffies - wall_jiffies) * USEC_PER_TICK + do_gettimeoffset(); usec += t; } while (read_seqretry(&xtime_lock, seq)); - tv->tv_sec = sec + usec / 1000000; - tv->tv_usec = usec % 1000000; + tv->tv_sec = sec + usec / USEC_PER_SEC; + tv->tv_usec = usec % USEC_PER_SEC; } EXPORT_SYMBOL(do_gettimeofday); @@ -157,8 +164,8 @@ int do_settimeofday(struct timespec *tv) write_seqlock_irq(&xtime_lock); - nsec -= do_gettimeoffset() * 1000 + - (jiffies - wall_jiffies) * (NSEC_PER_SEC/HZ); + nsec -= do_gettimeoffset() * NSEC_PER_USEC + + (jiffies - wall_jiffies) * NSEC_PER_TICK; wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); @@ -288,7 +295,7 @@ unsigned long long monotonic_clock(void) this_offset = hpet_readl(HPET_COUNTER); } while (read_seqretry(&xtime_lock, seq)); offset = (this_offset - last_offset); - offset *= (NSEC_PER_SEC/HZ) / hpet_tick; + offset *= NSEC_PER_TICK / hpet_tick; } else { do { seq = read_seqbegin(&xtime_lock); @@ -297,7 +304,8 @@ unsigned long long monotonic_clock(void) base = monotonic_base; } while (read_seqretry(&xtime_lock, seq)); this_offset = get_cycles_sync(); - offset = (this_offset - last_offset)*1000 / cpu_khz; + /* FIXME: 1000 or 1000000? */ + offset = (this_offset - last_offset)*1000 / cpu_khz; } return base + offset; } @@ -382,7 +390,7 @@ void main_timer_handler(struct pt_regs *regs) } monotonic_base += - (offset - vxtime.last)*(NSEC_PER_SEC/HZ) / hpet_tick; + (offset - vxtime.last) * NSEC_PER_TICK / hpet_tick; vxtime.last = offset; #ifdef CONFIG_X86_PM_TIMER @@ -391,24 +399,25 @@ void main_timer_handler(struct pt_regs *regs) #endif } else { offset = (((tsc - vxtime.last_tsc) * - vxtime.tsc_quot) >> 32) - (USEC_PER_SEC / HZ); + vxtime.tsc_quot) >> US_SCALE) - USEC_PER_TICK; if (offset < 0) offset = 0; - if (offset > (USEC_PER_SEC / HZ)) { - lost = offset / (USEC_PER_SEC / HZ); - offset %= (USEC_PER_SEC / HZ); + if (offset > USEC_PER_TICK) { + lost = offset / USEC_PER_TICK; + offset %= USEC_PER_TICK; } - monotonic_base += (tsc - vxtime.last_tsc)*1000000/cpu_khz ; + /* FIXME: 1000 or 1000000? */ + monotonic_base += (tsc - vxtime.last_tsc) * 1000000 / cpu_khz; vxtime.last_tsc = tsc - vxtime.quot * delay / vxtime.tsc_quot; if ((((tsc - vxtime.last_tsc) * - vxtime.tsc_quot) >> 32) < offset) + vxtime.tsc_quot) >> US_SCALE) < offset) vxtime.last_tsc = tsc - - (((long) offset << 32) / vxtime.tsc_quot) - 1; + (((long) offset << US_SCALE) / vxtime.tsc_quot) - 1; } if (lost > 0) { @@ -468,16 +477,15 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) } static unsigned int cyc2ns_scale __read_mostly; -#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ static inline void set_cyc2ns_scale(unsigned long cpu_khz) { - cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz; + cyc2ns_scale = (NSEC_PER_MSEC << NS_SCALE) / cpu_khz; } static inline unsigned long long cycles_2_ns(unsigned long long cyc) { - return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; + return (cyc * cyc2ns_scale) >> NS_SCALE; } unsigned long long sched_clock(void) @@ -490,7 +498,7 @@ unsigned long long sched_clock(void) Disadvantage is a small drift between CPUs in some configurations, but that should be tolerable. */ if (__vxtime.mode == VXTIME_HPET) - return (hpet_readl(HPET_COUNTER) * vxtime.quot) >> 32; + return (hpet_readl(HPET_COUNTER) * vxtime.quot) >> US_SCALE; #endif /* Could do CPU core sync here. Opteron can execute rdtsc speculatively, @@ -633,7 +641,7 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, cpu_khz = cpufreq_scale(cpu_khz_ref, ref_freq, freq->new); if (!(freq->flags & CPUFREQ_CONST_LOOPS)) - vxtime.tsc_quot = (1000L << 32) / cpu_khz; + vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz; } set_cyc2ns_scale(cpu_khz_ref); @@ -789,8 +797,8 @@ static int hpet_timer_stop_set_go(unsigned long tick) if (hpet_use_timer) { hpet_writel(HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL | HPET_TN_32BIT, HPET_T0_CFG); - hpet_writel(hpet_tick, HPET_T0_CMP); - hpet_writel(hpet_tick, HPET_T0_CMP); /* AK: why twice? */ + hpet_writel(hpet_tick, HPET_T0_CMP); /* next interrupt */ + hpet_writel(hpet_tick, HPET_T0_CMP); /* period */ cfg |= HPET_CFG_LEGACY; } /* @@ -825,8 +833,7 @@ static int hpet_init(void) if (hpet_period < 100000 || hpet_period > 100000000) return -1; - hpet_tick = (1000000000L * (USEC_PER_SEC / HZ) + hpet_period / 2) / - hpet_period; + hpet_tick = (FSEC_PER_TICK + hpet_period / 2) / hpet_period; hpet_use_timer = (id & HPET_ID_LEGSUP); @@ -890,18 +897,6 @@ void __init time_init(void) char *timename; char *gtod; -#ifdef HPET_HACK_ENABLE_DANGEROUS - if (!vxtime.hpet_address) { - printk(KERN_WARNING "time.c: WARNING: Enabling HPET base " - "manually!\n"); - outl(0x800038a0, 0xcf8); - outl(0xff000001, 0xcfc); - outl(0x800038a0, 0xcf8); - vxtime.hpet_address = inl(0xcfc) & 0xfffffffe; - printk(KERN_WARNING "time.c: WARNING: Enabled HPET " - "at %#lx.\n", vxtime.hpet_address); - } -#endif if (nohpet) vxtime.hpet_address = 0; @@ -912,7 +907,7 @@ void __init time_init(void) -xtime.tv_sec, -xtime.tv_nsec); if (!hpet_init()) - vxtime_hz = (1000000000000000L + hpet_period / 2) / hpet_period; + vxtime_hz = (FSEC_PER_SEC + hpet_period / 2) / hpet_period; else vxtime.hpet_address = 0; @@ -941,8 +936,8 @@ void __init time_init(void) vxtime_hz / 1000000, vxtime_hz % 1000000, timename, gtod); printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000); - vxtime.quot = (1000000L << 32) / vxtime_hz; - vxtime.tsc_quot = (1000L << 32) / cpu_khz; + vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz; + vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz; vxtime.last_tsc = get_cycles_sync(); setup_irq(0, &irq0); @@ -956,10 +951,10 @@ void __init time_init(void) __cpuinit int unsynchronized_tsc(void) { #ifdef CONFIG_SMP - if (oem_force_hpet_timer()) + if (apic_is_clustered_box()) return 1; /* Intel systems are normally all synchronized. Exceptions - are handled in the OEM check above. */ + are handled in the check above. */ if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) return 0; #endif diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index cea335e8746..3d11a2fe45b 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -6,8 +6,6 @@ * * Pentium III FXSR, SSE support * Gareth Hughes <gareth@valinux.com>, May 2000 - * - * $Id: traps.c,v 1.36 2002/03/24 11:09:10 ak Exp $ */ /* @@ -31,6 +29,7 @@ #include <linux/nmi.h> #include <linux/kprobes.h> #include <linux/kexec.h> +#include <linux/unwind.h> #include <asm/system.h> #include <asm/uaccess.h> @@ -41,7 +40,7 @@ #include <asm/i387.h> #include <asm/kdebug.h> #include <asm/processor.h> - +#include <asm/unwind.h> #include <asm/smp.h> #include <asm/pgalloc.h> #include <asm/pda.h> @@ -71,6 +70,7 @@ asmlinkage void machine_check(void); asmlinkage void spurious_interrupt_bug(void); ATOMIC_NOTIFIER_HEAD(die_chain); +EXPORT_SYMBOL(die_chain); int register_die_notifier(struct notifier_block *nb) { @@ -107,7 +107,8 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) preempt_enable_no_resched(); } -static int kstack_depth_to_print = 10; +static int kstack_depth_to_print = 12; +static int call_trace = 1; #ifdef CONFIG_KALLSYMS #include <linux/kallsyms.h> @@ -191,6 +192,25 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, return NULL; } +static int show_trace_unwind(struct unwind_frame_info *info, void *context) +{ + int i = 11, n = 0; + + while (unwind(info) == 0 && UNW_PC(info)) { + ++n; + if (i > 50) { + printk("\n "); + i = 7; + } else + i += printk(" "); + i += printk_address(UNW_PC(info)); + if (arch_unw_user_mode(info)) + break; + } + printk("\n"); + return n; +} + /* * x86-64 can have upto three kernel stacks: * process stack @@ -198,15 +218,39 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack */ -void show_trace(unsigned long *stack) +void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * stack) { const unsigned cpu = safe_smp_processor_id(); unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr; - int i; + int i = 11; unsigned used = 0; printk("\nCall Trace:"); + if (!tsk) + tsk = current; + + if (call_trace >= 0) { + int unw_ret = 0; + struct unwind_frame_info info; + + if (regs) { + if (unwind_init_frame_info(&info, tsk, regs) == 0) + unw_ret = show_trace_unwind(&info, NULL); + } else if (tsk == current) + unw_ret = unwind_init_running(&info, show_trace_unwind, NULL); + else { + if (unwind_init_blocked(&info, tsk) == 0) + unw_ret = show_trace_unwind(&info, NULL); + } + if (unw_ret > 0) { + if (call_trace > 0) + return; + printk("Legacy call trace:"); + i = 18; + } + } + #define HANDLE_STACK(cond) \ do while (cond) { \ unsigned long addr = *stack++; \ @@ -229,7 +273,7 @@ void show_trace(unsigned long *stack) } \ } while (0) - for(i = 11; ; ) { + for(; ; ) { const char *id; unsigned long *estack_end; estack_end = in_exception_stack(cpu, (unsigned long)stack, @@ -264,7 +308,7 @@ void show_trace(unsigned long *stack) printk("\n"); } -void show_stack(struct task_struct *tsk, unsigned long * rsp) +static void _show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long * rsp) { unsigned long *stack; int i; @@ -298,7 +342,12 @@ void show_stack(struct task_struct *tsk, unsigned long * rsp) printk("%016lx ", *stack++); touch_nmi_watchdog(); } - show_trace((unsigned long *)rsp); + show_trace(tsk, regs, rsp); +} + +void show_stack(struct task_struct *tsk, unsigned long * rsp) +{ + _show_stack(tsk, NULL, rsp); } /* @@ -307,7 +356,7 @@ void show_stack(struct task_struct *tsk, unsigned long * rsp) void dump_stack(void) { unsigned long dummy; - show_trace(&dummy); + show_trace(NULL, NULL, &dummy); } EXPORT_SYMBOL(dump_stack); @@ -334,7 +383,7 @@ void show_registers(struct pt_regs *regs) if (in_kernel) { printk("Stack: "); - show_stack(NULL, (unsigned long*)rsp); + _show_stack(NULL, regs, (unsigned long*)rsp); printk("\nCode: "); if (regs->rip < PAGE_OFFSET) @@ -383,6 +432,7 @@ void out_of_line_bug(void) { BUG(); } +EXPORT_SYMBOL(out_of_line_bug); #endif static DEFINE_SPINLOCK(die_lock); @@ -1012,3 +1062,14 @@ static int __init kstack_setup(char *s) } __setup("kstack=", kstack_setup); +static int __init call_trace_setup(char *s) +{ + if (strcmp(s, "old") == 0) + call_trace = -1; + else if (strcmp(s, "both") == 0) + call_trace = 0; + else if (strcmp(s, "new") == 0) + call_trace = 1; + return 1; +} +__setup("call_trace=", call_trace_setup); diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index b81f473c4a1..1c6a5f32291 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S @@ -45,6 +45,15 @@ SECTIONS RODATA +#ifdef CONFIG_STACK_UNWIND + . = ALIGN(8); + .eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) { + __start_unwind = .; + *(.eh_frame) + __end_unwind = .; + } +#endif + /* Data */ .data : AT(ADDR(.data) - LOAD_OFFSET) { *(.data) @@ -131,6 +140,26 @@ SECTIONS *(.data.page_aligned) } + /* might get freed after init */ + . = ALIGN(4096); + __smp_alt_begin = .; + __smp_alt_instructions = .; + .smp_altinstructions : AT(ADDR(.smp_altinstructions) - LOAD_OFFSET) { + *(.smp_altinstructions) + } + __smp_alt_instructions_end = .; + . = ALIGN(8); + __smp_locks = .; + .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { + *(.smp_locks) + } + __smp_locks_end = .; + .smp_altinstr_replacement : AT(ADDR(.smp_altinstr_replacement) - LOAD_OFFSET) { + *(.smp_altinstr_replacement) + } + . = ALIGN(4096); + __smp_alt_end = .; + . = ALIGN(4096); /* Init code and data */ __init_begin = .; .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c index 9468fb20b0b..f603037df16 100644 --- a/arch/x86_64/kernel/vsyscall.c +++ b/arch/x86_64/kernel/vsyscall.c @@ -107,7 +107,7 @@ static __always_inline long time_syscall(long *t) int __vsyscall(0) vgettimeofday(struct timeval * tv, struct timezone * tz) { - if (unlikely(!__sysctl_vsyscall)) + if (!__sysctl_vsyscall) return gettimeofday(tv,tz); if (tv) do_vgettimeofday(tv); @@ -120,7 +120,7 @@ int __vsyscall(0) vgettimeofday(struct timeval * tv, struct timezone * tz) * unlikely */ time_t __vsyscall(1) vtime(time_t *t) { - if (unlikely(!__sysctl_vsyscall)) + if (!__sysctl_vsyscall) return time_syscall(t); else if (t) *t = __xtime.tv_sec; diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c index 1def21c9f7c..370952c4ff2 100644 --- a/arch/x86_64/kernel/x8664_ksyms.c +++ b/arch/x86_64/kernel/x8664_ksyms.c @@ -1,66 +1,21 @@ +/* Exports for assembly files. + All C exports should go in the respective C files. */ + #include <linux/config.h> #include <linux/module.h> #include <linux/smp.h> -#include <linux/user.h> -#include <linux/sched.h> -#include <linux/in6.h> -#include <linux/interrupt.h> -#include <linux/smp_lock.h> -#include <linux/pm.h> -#include <linux/pci.h> -#include <linux/apm_bios.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/syscalls.h> -#include <linux/tty.h> #include <asm/semaphore.h> #include <asm/processor.h> -#include <asm/i387.h> #include <asm/uaccess.h> -#include <asm/checksum.h> -#include <asm/io.h> -#include <asm/delay.h> -#include <asm/irq.h> -#include <asm/mmx.h> -#include <asm/desc.h> #include <asm/pgtable.h> -#include <asm/pgalloc.h> -#include <asm/nmi.h> -#include <asm/kdebug.h> -#include <asm/unistd.h> -#include <asm/tlbflush.h> -#include <asm/kdebug.h> - -extern spinlock_t rtc_lock; -#ifdef CONFIG_SMP -extern void __write_lock_failed(rwlock_t *rw); -extern void __read_lock_failed(rwlock_t *rw); -#endif - -/* platform dependent support */ -EXPORT_SYMBOL(boot_cpu_data); -//EXPORT_SYMBOL(dump_fpu); -EXPORT_SYMBOL(__ioremap); -EXPORT_SYMBOL(ioremap_nocache); -EXPORT_SYMBOL(iounmap); EXPORT_SYMBOL(kernel_thread); -EXPORT_SYMBOL(pm_idle); -EXPORT_SYMBOL(pm_power_off); EXPORT_SYMBOL(__down_failed); EXPORT_SYMBOL(__down_failed_interruptible); EXPORT_SYMBOL(__down_failed_trylock); EXPORT_SYMBOL(__up_wakeup); -/* Networking helper routines. */ -EXPORT_SYMBOL(csum_partial_copy_nocheck); -EXPORT_SYMBOL(ip_compute_csum); -/* Delay loops */ -EXPORT_SYMBOL(__udelay); -EXPORT_SYMBOL(__ndelay); -EXPORT_SYMBOL(__delay); -EXPORT_SYMBOL(__const_udelay); EXPORT_SYMBOL(__get_user_1); EXPORT_SYMBOL(__get_user_2); @@ -71,42 +26,20 @@ EXPORT_SYMBOL(__put_user_2); EXPORT_SYMBOL(__put_user_4); EXPORT_SYMBOL(__put_user_8); -EXPORT_SYMBOL(strncpy_from_user); -EXPORT_SYMBOL(__strncpy_from_user); -EXPORT_SYMBOL(clear_user); -EXPORT_SYMBOL(__clear_user); EXPORT_SYMBOL(copy_user_generic); EXPORT_SYMBOL(copy_from_user); EXPORT_SYMBOL(copy_to_user); -EXPORT_SYMBOL(copy_in_user); -EXPORT_SYMBOL(strnlen_user); - -#ifdef CONFIG_PCI -EXPORT_SYMBOL(pci_mem_start); -#endif EXPORT_SYMBOL(copy_page); EXPORT_SYMBOL(clear_page); -EXPORT_SYMBOL(_cpu_pda); #ifdef CONFIG_SMP -EXPORT_SYMBOL(cpu_data); +extern void FASTCALL( __write_lock_failed(rwlock_t *rw)); +extern void FASTCALL( __read_lock_failed(rwlock_t *rw)); EXPORT_SYMBOL(__write_lock_failed); EXPORT_SYMBOL(__read_lock_failed); - -EXPORT_SYMBOL(smp_call_function); -EXPORT_SYMBOL(cpu_callout_map); -#endif - -#ifdef CONFIG_VT -EXPORT_SYMBOL(screen_info); #endif -EXPORT_SYMBOL(rtc_lock); - -EXPORT_SYMBOL_GPL(set_nmi_callback); -EXPORT_SYMBOL_GPL(unset_nmi_callback); - /* Export string functions. We normally rely on gcc builtin for most of these, but gcc sometimes decides not to inline them. */ #undef memcpy @@ -114,51 +47,14 @@ EXPORT_SYMBOL_GPL(unset_nmi_callback); #undef memmove extern void * memset(void *,int,__kernel_size_t); -extern size_t strlen(const char *); -extern void * memmove(void * dest,const void *src,size_t count); extern void * memcpy(void *,const void *,__kernel_size_t); extern void * __memcpy(void *,const void *,__kernel_size_t); EXPORT_SYMBOL(memset); -EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(__memcpy); -#ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM -/* prototypes are wrong, these are assembly with custom calling functions */ -extern void rwsem_down_read_failed_thunk(void); -extern void rwsem_wake_thunk(void); -extern void rwsem_downgrade_thunk(void); -extern void rwsem_down_write_failed_thunk(void); -EXPORT_SYMBOL(rwsem_down_read_failed_thunk); -EXPORT_SYMBOL(rwsem_wake_thunk); -EXPORT_SYMBOL(rwsem_downgrade_thunk); -EXPORT_SYMBOL(rwsem_down_write_failed_thunk); -#endif - EXPORT_SYMBOL(empty_zero_page); - -EXPORT_SYMBOL(die_chain); - -#ifdef CONFIG_SMP -EXPORT_SYMBOL(cpu_sibling_map); -EXPORT_SYMBOL(smp_num_siblings); -#endif - -#ifdef CONFIG_BUG -EXPORT_SYMBOL(out_of_line_bug); -#endif - EXPORT_SYMBOL(init_level4_pgt); - -extern unsigned long __supported_pte_mask; -EXPORT_SYMBOL(__supported_pte_mask); - -#ifdef CONFIG_SMP -EXPORT_SYMBOL(flush_tlb_page); -#endif - -EXPORT_SYMBOL(cpu_khz); - EXPORT_SYMBOL(load_gs_index); diff --git a/arch/x86_64/lib/csum-partial.c b/arch/x86_64/lib/csum-partial.c index 5384e227cdf..c493735218d 100644 --- a/arch/x86_64/lib/csum-partial.c +++ b/arch/x86_64/lib/csum-partial.c @@ -147,4 +147,5 @@ unsigned short ip_compute_csum(unsigned char * buff, int len) { return csum_fold(csum_partial(buff,len,0)); } +EXPORT_SYMBOL(ip_compute_csum); diff --git a/arch/x86_64/lib/csum-wrappers.c b/arch/x86_64/lib/csum-wrappers.c index 94323f20816..b1320ec5842 100644 --- a/arch/x86_64/lib/csum-wrappers.c +++ b/arch/x86_64/lib/csum-wrappers.c @@ -109,6 +109,7 @@ csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, int len, { return csum_partial_copy_generic(src,dst,len,sum,NULL,NULL); } +EXPORT_SYMBOL(csum_partial_copy_nocheck); unsigned short csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr, __u32 len, unsigned short proto, unsigned int sum) diff --git a/arch/x86_64/lib/delay.c b/arch/x86_64/lib/delay.c index 03c460cbdd1..b6cd3cca2f4 100644 --- a/arch/x86_64/lib/delay.c +++ b/arch/x86_64/lib/delay.c @@ -9,6 +9,7 @@ */ #include <linux/config.h> +#include <linux/module.h> #include <linux/sched.h> #include <linux/delay.h> #include <asm/delay.h> @@ -36,18 +37,22 @@ void __delay(unsigned long loops) } while((now-bclock) < loops); } +EXPORT_SYMBOL(__delay); inline void __const_udelay(unsigned long xloops) { __delay((xloops * HZ * cpu_data[raw_smp_processor_id()].loops_per_jiffy) >> 32); } +EXPORT_SYMBOL(__const_udelay); void __udelay(unsigned long usecs) { __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */ } +EXPORT_SYMBOL(__udelay); void __ndelay(unsigned long nsecs) { __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ } +EXPORT_SYMBOL(__ndelay); diff --git a/arch/x86_64/lib/memmove.c b/arch/x86_64/lib/memmove.c index e93d5255fdc..751ebae8ec4 100644 --- a/arch/x86_64/lib/memmove.c +++ b/arch/x86_64/lib/memmove.c @@ -3,12 +3,13 @@ */ #define _STRING_C #include <linux/string.h> +#include <linux/module.h> #undef memmove void *memmove(void * dest,const void *src,size_t count) { if (dest < src) { - __inline_memcpy(dest,src,count); + return memcpy(dest,src,count); } else { char *p = (char *) dest + count; char *s = (char *) src + count; @@ -17,3 +18,4 @@ void *memmove(void * dest,const void *src,size_t count) } return dest; } +EXPORT_SYMBOL(memmove); diff --git a/arch/x86_64/lib/usercopy.c b/arch/x86_64/lib/usercopy.c index 9bc2c295818..893d43f838c 100644 --- a/arch/x86_64/lib/usercopy.c +++ b/arch/x86_64/lib/usercopy.c @@ -5,6 +5,7 @@ * Copyright 1997 Linus Torvalds * Copyright 2002 Andi Kleen <ak@suse.de> */ +#include <linux/module.h> #include <asm/uaccess.h> /* @@ -47,15 +48,17 @@ __strncpy_from_user(char *dst, const char __user *src, long count) __do_strncpy_from_user(dst, src, count, res); return res; } +EXPORT_SYMBOL(__strncpy_from_user); long strncpy_from_user(char *dst, const char __user *src, long count) { long res = -EFAULT; if (access_ok(VERIFY_READ, src, 1)) - __do_strncpy_from_user(dst, src, count, res); + return __strncpy_from_user(dst, src, count); return res; } +EXPORT_SYMBOL(strncpy_from_user); /* * Zero Userspace @@ -94,7 +97,7 @@ unsigned long __clear_user(void __user *addr, unsigned long size) [zero] "r" (0UL), [eight] "r" (8UL)); return size; } - +EXPORT_SYMBOL(__clear_user); unsigned long clear_user(void __user *to, unsigned long n) { @@ -102,6 +105,7 @@ unsigned long clear_user(void __user *to, unsigned long n) return __clear_user(to, n); return n; } +EXPORT_SYMBOL(clear_user); /* * Return the size of a string (including the ending 0) @@ -125,6 +129,7 @@ long __strnlen_user(const char __user *s, long n) s++; } } +EXPORT_SYMBOL(__strnlen_user); long strnlen_user(const char __user *s, long n) { @@ -132,6 +137,7 @@ long strnlen_user(const char __user *s, long n) return 0; return __strnlen_user(s, n); } +EXPORT_SYMBOL(strnlen_user); long strlen_user(const char __user *s) { @@ -147,6 +153,7 @@ long strlen_user(const char __user *s) s++; } } +EXPORT_SYMBOL(strlen_user); unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len) { @@ -155,3 +162,5 @@ unsigned long copy_in_user(void __user *to, const void __user *from, unsigned le } return len; } +EXPORT_SYMBOL(copy_in_user); + diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c index 55250593d8c..08dc696f54e 100644 --- a/arch/x86_64/mm/fault.c +++ b/arch/x86_64/mm/fault.c @@ -41,6 +41,41 @@ #define PF_RSVD (1<<3) #define PF_INSTR (1<<4) +#ifdef CONFIG_KPROBES +ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); + +/* Hook to register for page fault notifications */ +int register_page_fault_notifier(struct notifier_block *nb) +{ + vmalloc_sync_all(); + return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); +} + +int unregister_page_fault_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); +} + +static inline int notify_page_fault(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + struct die_args args = { + .regs = regs, + .str = str, + .err = err, + .trapnr = trap, + .signr = sig + }; + return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); +} +#else +static inline int notify_page_fault(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + return NOTIFY_DONE; +} +#endif + void bust_spinlocks(int yes) { int loglevel_save = console_loglevel; @@ -160,7 +195,7 @@ void dump_pagetable(unsigned long address) printk("PGD %lx ", pgd_val(*pgd)); if (!pgd_present(*pgd)) goto ret; - pud = __pud_offset_k((pud_t *)pgd_page(*pgd), address); + pud = pud_offset(pgd, address); if (bad_address(pud)) goto bad; printk("PUD %lx ", pud_val(*pud)); if (!pud_present(*pud)) goto ret; @@ -348,7 +383,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, if (vmalloc_fault(address) >= 0) return; } - if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, + if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, SIGSEGV) == NOTIFY_STOP) return; /* @@ -358,7 +393,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, goto bad_area_nosemaphore; } - if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, + if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, SIGSEGV) == NOTIFY_STOP) return; @@ -410,8 +445,10 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, if (!(vma->vm_flags & VM_GROWSDOWN)) goto bad_area; if (error_code & 4) { - // XXX: align red zone size with ABI - if (address + 128 < regs->rsp) + /* Allow userspace just enough access below the stack pointer + * to let the 'enter' instruction work. + */ + if (address + 65536 + 32 * sizeof(unsigned long) < regs->rsp) goto bad_area; } if (expand_stack(vma, address)) diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index 4ba34e95d83..95bd232ff0c 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c @@ -23,6 +23,7 @@ #include <linux/bootmem.h> #include <linux/proc_fs.h> #include <linux/pci.h> +#include <linux/poison.h> #include <linux/dma-mapping.h> #include <linux/module.h> #include <linux/memory_hotplug.h> @@ -41,8 +42,6 @@ #include <asm/proto.h> #include <asm/smp.h> #include <asm/sections.h> -#include <asm/dma-mapping.h> -#include <asm/swiotlb.h> #ifndef Dprintk #define Dprintk(x...) @@ -90,8 +89,6 @@ void show_mem(void) printk(KERN_INFO "%lu pages swap cached\n",cached); } -/* References to section boundaries */ - int after_bootmem; static __init void *spp_getpage(void) @@ -261,9 +258,10 @@ phys_pmd_init(pmd_t *pmd, unsigned long address, unsigned long end) for (i = 0; i < PTRS_PER_PMD; pmd++, i++, address += PMD_SIZE) { unsigned long entry; - if (address > end) { - for (; i < PTRS_PER_PMD; i++, pmd++) - set_pmd(pmd, __pmd(0)); + if (address >= end) { + if (!after_bootmem) + for (; i < PTRS_PER_PMD; i++, pmd++) + set_pmd(pmd, __pmd(0)); break; } entry = _PAGE_NX|_PAGE_PSE|_KERNPG_TABLE|_PAGE_GLOBAL|address; @@ -341,7 +339,8 @@ static void __init find_early_table_space(unsigned long end) table_end = table_start; early_printk("kernel direct mapping tables up to %lx @ %lx-%lx\n", - end, table_start << PAGE_SHIFT, table_end << PAGE_SHIFT); + end, table_start << PAGE_SHIFT, + (table_start << PAGE_SHIFT) + tables); } /* Setup the direct mapping of the physical memory at PAGE_OFFSET. @@ -372,7 +371,7 @@ void __meminit init_memory_mapping(unsigned long start, unsigned long end) pud_t *pud; if (after_bootmem) - pud = pud_offset_k(pgd, start & PGDIR_MASK); + pud = pud_offset(pgd, start & PGDIR_MASK); else pud = alloc_low_page(&map, &pud_phys); @@ -508,8 +507,6 @@ void __init clear_kernel_mapping(unsigned long address, unsigned long size) /* * Memory hotplug specific functions */ -#if defined(CONFIG_ACPI_HOTPLUG_MEMORY) || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE) - void online_page(struct page *page) { ClearPageReserved(page); @@ -519,31 +516,17 @@ void online_page(struct page *page) num_physpages++; } -#ifndef CONFIG_MEMORY_HOTPLUG +#ifdef CONFIG_MEMORY_HOTPLUG /* - * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance, - * just online the pages. + * XXX: memory_add_physaddr_to_nid() is to find node id from physical address + * via probe interface of sysfs. If acpi notifies hot-add event, then it + * can tell node id by searching dsdt. But, probe interface doesn't have + * node id. So, return 0 as node id at this time. */ -int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages) +#ifdef CONFIG_NUMA +int memory_add_physaddr_to_nid(u64 start) { - int err = -EIO; - unsigned long pfn; - unsigned long total = 0, mem = 0; - for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) { - if (pfn_valid(pfn)) { - online_page(pfn_to_page(pfn)); - err = 0; - mem++; - } - total++; - } - if (!err) { - z->spanned_pages += total; - z->present_pages += mem; - z->zone_pgdat->node_spanned_pages += total; - z->zone_pgdat->node_present_pages += mem; - } - return err; + return 0; } #endif @@ -551,9 +534,9 @@ int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages) * Memory is added always to NORMAL zone. This means you will never get * additional DMA/DMA32 memory. */ -int add_memory(u64 start, u64 size) +int arch_add_memory(int nid, u64 start, u64 size) { - struct pglist_data *pgdat = NODE_DATA(0); + struct pglist_data *pgdat = NODE_DATA(nid); struct zone *zone = pgdat->node_zones + MAX_NR_ZONES-2; unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; @@ -570,7 +553,7 @@ error: printk("%s: Problem encountered in __add_pages!\n", __func__); return ret; } -EXPORT_SYMBOL_GPL(add_memory); +EXPORT_SYMBOL_GPL(arch_add_memory); int remove_memory(u64 start, u64 size) { @@ -578,7 +561,33 @@ int remove_memory(u64 start, u64 size) } EXPORT_SYMBOL_GPL(remove_memory); -#endif +#else /* CONFIG_MEMORY_HOTPLUG */ +/* + * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance, + * just online the pages. + */ +int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages) +{ + int err = -EIO; + unsigned long pfn; + unsigned long total = 0, mem = 0; + for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) { + if (pfn_valid(pfn)) { + online_page(pfn_to_page(pfn)); + err = 0; + mem++; + } + total++; + } + if (!err) { + z->spanned_pages += total; + z->present_pages += mem; + z->zone_pgdat->node_spanned_pages += total; + z->zone_pgdat->node_present_pages += mem; + } + return err; +} +#endif /* CONFIG_MEMORY_HOTPLUG */ static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules, kcore_vsyscall; @@ -587,10 +596,7 @@ void __init mem_init(void) { long codesize, reservedpages, datasize, initsize; -#ifdef CONFIG_SWIOTLB - pci_swiotlb_init(); -#endif - no_iommu_init(); + pci_iommu_alloc(); /* How many end-of-memory variables you have, grandma! */ max_low_pfn = end_pfn; @@ -644,20 +650,31 @@ void __init mem_init(void) #endif } -void free_initmem(void) +void free_init_pages(char *what, unsigned long begin, unsigned long end) { unsigned long addr; - addr = (unsigned long)(&__init_begin); - for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { + if (begin >= end) + return; + + printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); + for (addr = begin; addr < end; addr += PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); init_page_count(virt_to_page(addr)); - memset((void *)(addr & ~(PAGE_SIZE-1)), 0xcc, PAGE_SIZE); + memset((void *)(addr & ~(PAGE_SIZE-1)), + POISON_FREE_INITMEM, PAGE_SIZE); free_page(addr); totalram_pages++; } - memset(__initdata_begin, 0xba, __initdata_end - __initdata_begin); - printk ("Freeing unused kernel memory: %luk freed\n", (__init_end - __init_begin) >> 10); +} + +void free_initmem(void) +{ + memset(__initdata_begin, POISON_FREE_INITDATA, + __initdata_end - __initdata_begin); + free_init_pages("unused kernel memory", + (unsigned long)(&__init_begin), + (unsigned long)(&__init_end)); } #ifdef CONFIG_DEBUG_RODATA @@ -686,15 +703,7 @@ void mark_rodata_ro(void) #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { - if (start >= end) - return; - printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); - for (; start < end; start += PAGE_SIZE) { - ClearPageReserved(virt_to_page(start)); - init_page_count(virt_to_page(start)); - free_page(start); - totalram_pages++; - } + free_init_pages("initrd memory", start, end); } #endif diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c index ae207064201..45d7d823c3b 100644 --- a/arch/x86_64/mm/ioremap.c +++ b/arch/x86_64/mm/ioremap.c @@ -11,6 +11,7 @@ #include <linux/vmalloc.h> #include <linux/init.h> #include <linux/slab.h> +#include <linux/module.h> #include <asm/io.h> #include <asm/pgalloc.h> #include <asm/fixmap.h> @@ -219,6 +220,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l } return (__force void __iomem *) (offset + (char *)addr); } +EXPORT_SYMBOL(__ioremap); /** * ioremap_nocache - map bus memory into CPU space @@ -246,6 +248,7 @@ void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size) { return __ioremap(phys_addr, size, _PAGE_PCD); } +EXPORT_SYMBOL(ioremap_nocache); /** * iounmap - Free a IO remapping @@ -291,3 +294,5 @@ void iounmap(volatile void __iomem *addr) BUG_ON(p != o || o == NULL); kfree(p); } +EXPORT_SYMBOL(iounmap); + diff --git a/arch/x86_64/pci/k8-bus.c b/arch/x86_64/pci/k8-bus.c index 3acf60ded2a..b50a7c7c47f 100644 --- a/arch/x86_64/pci/k8-bus.c +++ b/arch/x86_64/pci/k8-bus.c @@ -2,6 +2,7 @@ #include <linux/pci.h> #include <asm/mpspec.h> #include <linux/cpumask.h> +#include <asm/k8.h> /* * This discovers the pcibus <-> node mapping on AMD K8. @@ -18,7 +19,6 @@ #define NR_LDT_BUS_NUMBER_REGISTERS 3 #define SECONDARY_LDT_BUS_NUMBER(dword) ((dword >> 8) & 0xFF) #define SUBORDINATE_LDT_BUS_NUMBER(dword) ((dword >> 16) & 0xFF) -#define PCI_DEVICE_ID_K8HTCONFIG 0x1100 /** * fill_mp_bus_to_cpumask() @@ -28,8 +28,7 @@ __init static int fill_mp_bus_to_cpumask(void) { - struct pci_dev *nb_dev = NULL; - int i, j; + int i, j, k; u32 ldtbus, nid; static int lbnr[3] = { LDT_BUS_NUMBER_REGISTER_0, @@ -37,8 +36,9 @@ fill_mp_bus_to_cpumask(void) LDT_BUS_NUMBER_REGISTER_2 }; - while ((nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, - PCI_DEVICE_ID_K8HTCONFIG, nb_dev))) { + cache_k8_northbridges(); + for (k = 0; k < num_k8_northbridges; k++) { + struct pci_dev *nb_dev = k8_northbridges[k]; pci_read_config_dword(nb_dev, NODE_ID_REGISTER, &nid); for (i = 0; i < NR_LDT_BUS_NUMBER_REGISTERS; i++) { diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 98fac8489ae..3a3a4c66ef8 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -71,7 +71,7 @@ archprepare: $(archinc)/.platform # Update machine cpu and platform symlinks if something which affects # them changed. -$(archinc)/.platform: $(wildcard include/config/arch/*.h) include/config/MARKER +$(archinc)/.platform: $(wildcard include/config/arch/*.h) include/config/auto.conf @echo ' SYMLINK $(archinc)/xtensa/config -> $(archinc)/xtensa/config-$(CPU)' $(Q)mkdir -p $(archinc) $(Q)mkdir -p $(archinc)/xtensa diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c index 51f9bed455f..1cf744ee095 100644 --- a/arch/xtensa/kernel/irq.c +++ b/arch/xtensa/kernel/irq.c @@ -100,7 +100,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -181,7 +181,7 @@ void __init init_IRQ(void) int i; for (i=0; i < XTENSA_NR_IRQS; i++) - irq_desc[i].handler = &xtensa_irq_type; + irq_desc[i].chip = &xtensa_irq_type; cached_irq_mask = 0; diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c index c6f471b9eaa..eda029fc897 100644 --- a/arch/xtensa/kernel/pci.c +++ b/arch/xtensa/kernel/pci.c @@ -71,13 +71,13 @@ static int pci_bus_count; * which might have be mirrored at 0x0100-0x03ff.. */ void -pcibios_align_resource(void *data, struct resource *res, unsigned long size, - unsigned long align) +pcibios_align_resource(void *data, struct resource *res, resource_size_t size, + resource_size_t align) { struct pci_dev *dev = data; if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; + resource_size_t start = res->start; if (size > 0x100) { printk(KERN_ERR "PCI: I/O Region %s/%d too large" diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c index 937d81f62f4..fe14909f45e 100644 --- a/arch/xtensa/kernel/time.c +++ b/arch/xtensa/kernel/time.c @@ -29,7 +29,7 @@ extern volatile unsigned long wall_jiffies; -spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; +DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index 225d64d73f0..27e409089a7 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -461,7 +461,7 @@ void show_code(unsigned int *pc) } } -spinlock_t die_lock = SPIN_LOCK_UNLOCKED; +DEFINE_SPINLOCK(die_lock); void die(const char * str, struct pt_regs * regs, long err) { |