aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig3
-rw-r--r--arch/arm/include/asm/mach/udc_pxa2xx.h4
-rw-r--r--arch/arm/include/asm/processor.h4
-rw-r--r--arch/arm/kernel/perf_event.c2
-rw-r--r--arch/arm/mach-mx3/mach-mx31lilly.c33
-rw-r--r--arch/arm/mach-omap2/board-omap3stalker.c4
-rw-r--r--arch/arm/mach-omap2/clock44xx_data.c2
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c9
-rw-r--r--arch/arm/mach-omap2/pm34xx.c4
-rw-r--r--arch/arm/mach-omap2/usb-ehci.c2
-rw-r--r--arch/arm/mach-pxa/mioa701.c2
-rw-r--r--arch/arm/mach-pxa/z2.c26
-rw-r--r--arch/arm/mach-realview/Kconfig2
-rw-r--r--arch/arm/mach-realview/include/mach/barriers.h8
-rw-r--r--arch/arm/mach-realview/realview_eb.c3
-rw-r--r--arch/arm/mach-realview/realview_pb1176.c3
-rw-r--r--arch/arm/mach-realview/realview_pb11mp.c3
-rw-r--r--arch/arm/mach-realview/realview_pba8.c3
-rw-r--r--arch/arm/mach-realview/realview_pbx.c3
-rw-r--r--arch/arm/mach-s5p6442/clock.c2
-rw-r--r--arch/arm/mach-s5pv210/clock.c115
-rw-r--r--arch/arm/mach-vexpress/ct-ca9x4.c3
-rw-r--r--arch/arm/mm/Kconfig21
-rw-r--r--arch/arm/mm/cache-v6.S18
-rw-r--r--arch/arm/mm/dma-mapping.c18
-rw-r--r--arch/arm/plat-omap/dmtimer.c6
-rw-r--r--arch/arm/plat-omap/gpio.c1
-rw-r--r--arch/arm/plat-omap/iovmm.c4
-rw-r--r--arch/arm/plat-pxa/Makefile3
-rw-r--r--arch/arm/plat-s5p/irq-eint.c2
-rw-r--r--arch/arm/plat-samsung/include/plat/sdhci.h4
-rw-r--r--arch/ia64/mm/tlb.c2
-rw-r--r--arch/mips/alchemy/common/power.c12
-rw-r--r--arch/mips/alchemy/common/sleeper.S81
-rw-r--r--arch/mips/ar7/platform.c2
-rw-r--r--arch/mips/bcm47xx/Makefile2
-rw-r--r--arch/mips/bcm47xx/nvram.c94
-rw-r--r--arch/mips/bcm47xx/setup.c39
-rw-r--r--arch/mips/include/asm/mach-ar7/ar7.h6
-rw-r--r--arch/mips/include/asm/mach-ar7/gpio.h2
-rw-r--r--arch/mips/include/asm/mach-au1x00/au1000.h3
-rw-r--r--arch/mips/include/asm/mach-bcm47xx/nvram.h36
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/gpio.h2
-rw-r--r--arch/mips/kernel/ftrace.c184
-rw-r--r--arch/mips/kernel/mcount.S55
-rw-r--r--arch/mips/kernel/mips-mt-fpaff.c87
-rw-r--r--arch/mips/kernel/traps.c2
-rw-r--r--arch/mips/loongson/Kconfig6
-rw-r--r--arch/mips/loongson/common/Makefile1
-rw-r--r--arch/mips/loongson/common/cs5536/cs5536_ehci.c2
-rw-r--r--arch/mips/loongson/common/cs5536/cs5536_ide.c15
-rw-r--r--arch/mips/loongson/common/cs5536/cs5536_isa.c4
-rw-r--r--arch/mips/loongson/common/cs5536/cs5536_ohci.c2
-rw-r--r--arch/mips/loongson/common/rtc.c43
-rw-r--r--arch/mips/math-emu/dp_simple.c1
-rw-r--r--arch/mips/math-emu/sp_simple.c1
-rw-r--r--arch/mips/oprofile/op_model_loongson2.c8
-rw-r--r--arch/powerpc/Kconfig4
-rw-r--r--arch/powerpc/Makefile4
-rw-r--r--arch/powerpc/include/asm/ptrace.h32
-rw-r--r--arch/powerpc/kernel/crash.c2
-rw-r--r--arch/powerpc/kernel/irq.c5
-rw-r--r--arch/powerpc/kernel/perf_event.c5
-rw-r--r--arch/powerpc/kernel/prom_init.c2
-rw-r--r--arch/powerpc/kernel/prom_init_check.sh6
-rw-r--r--arch/powerpc/lib/Makefile4
-rw-r--r--arch/powerpc/lib/crtsavres.S129
-rw-r--r--arch/powerpc/lib/feature-fixups.c17
-rw-r--r--arch/powerpc/platforms/iseries/pci.c6
-rw-r--r--arch/um/os-Linux/mem.c1
-rw-r--r--arch/x86/kernel/cpu/perf_event_amd.c4
-rw-r--r--arch/x86/kernel/pci-calgary_64.c4
-rw-r--r--arch/x86/kernel/traps.c11
-rw-r--r--arch/x86/mm/pat_rbtree.c34
74 files changed, 912 insertions, 367 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 1f254bd6c937..98922f7d2d12 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -955,7 +955,8 @@ config XSCALE_PMU
default y
config CPU_HAS_PMU
- depends on CPU_V6 || CPU_V7 || XSCALE_PMU
+ depends on (CPU_V6 || CPU_V7 || XSCALE_PMU) && \
+ (!ARCH_OMAP3 || OMAP3_EMU)
default y
bool
diff --git a/arch/arm/include/asm/mach/udc_pxa2xx.h b/arch/arm/include/asm/mach/udc_pxa2xx.h
index f3eabf1ecec3..833306ee9e7f 100644
--- a/arch/arm/include/asm/mach/udc_pxa2xx.h
+++ b/arch/arm/include/asm/mach/udc_pxa2xx.h
@@ -21,8 +21,8 @@ struct pxa2xx_udc_mach_info {
* here. Note that sometimes the signals go through inverters...
*/
bool gpio_vbus_inverted;
- u16 gpio_vbus; /* high == vbus present */
+ int gpio_vbus; /* high == vbus present */
bool gpio_pullup_inverted;
- u16 gpio_pullup; /* high == pullup activated */
+ int gpio_pullup; /* high == pullup activated */
};
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
index 6a89567ffc5b..7bed3daf83b8 100644
--- a/arch/arm/include/asm/processor.h
+++ b/arch/arm/include/asm/processor.h
@@ -91,7 +91,11 @@ extern void release_thread(struct task_struct *);
unsigned long get_wchan(struct task_struct *p);
+#if __LINUX_ARM_ARCH__ == 6
+#define cpu_relax() smp_mb()
+#else
#define cpu_relax() barrier()
+#endif
/*
* Create a new kernel thread
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index c45768614c8a..de12536d687f 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -201,7 +201,7 @@ armpmu_event_update(struct perf_event *event,
{
int shift = 64 - 32;
s64 prev_raw_count, new_raw_count;
- s64 delta;
+ u64 delta;
again:
prev_raw_count = atomic64_read(&hwc->prev_count);
diff --git a/arch/arm/mach-mx3/mach-mx31lilly.c b/arch/arm/mach-mx3/mach-mx31lilly.c
index d3d5877c750e..b2c7f512070f 100644
--- a/arch/arm/mach-mx3/mach-mx31lilly.c
+++ b/arch/arm/mach-mx3/mach-mx31lilly.c
@@ -115,6 +115,8 @@ static struct platform_device physmap_flash_device = {
/* USB */
+#if defined(CONFIG_USB_ULPI)
+
#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
@@ -244,10 +246,20 @@ static struct mxc_usbh_platform_data usbh2_pdata = {
.flags = MXC_EHCI_POWER_PINS_ENABLED,
};
-static struct platform_device *devices[] __initdata = {
- &smsc91x_device,
- &physmap_flash_device,
-};
+static void lilly1131_usb_init(void)
+{
+ usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+ USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+ usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+ USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+ mxc_register_device(&mxc_usbh1, &usbh1_pdata);
+ mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+}
+
+#else
+static inline void lilly1131_usb_init(void) {}
+#endif /* CONFIG_USB_ULPI */
/* SPI */
@@ -279,6 +291,11 @@ static struct spi_board_info mc13783_dev __initdata = {
.platform_data = &mc13783_pdata,
};
+static struct platform_device *devices[] __initdata = {
+ &smsc91x_device,
+ &physmap_flash_device,
+};
+
static int mx31lilly_baseboard;
core_param(mx31lilly_baseboard, mx31lilly_baseboard, int, 0444);
@@ -321,13 +338,7 @@ static void __init mx31lilly_board_init(void)
platform_add_devices(devices, ARRAY_SIZE(devices));
/* USB */
- usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
- USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
- usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
- USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
-
- mxc_register_device(&mxc_usbh1, &usbh1_pdata);
- mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+ lilly1131_usb_init();
}
static void __init mx31lilly_timer_init(void)
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index f848ba8dbc16..a04cffd691c5 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -538,9 +538,7 @@ static void ads7846_dev_init(void)
printk(KERN_ERR "can't get ads7846 pen down GPIO\n");
gpio_direction_input(OMAP3_STALKER_TS_GPIO);
-
- omap_set_gpio_debounce(OMAP3_STALKER_TS_GPIO, 1);
- omap_set_gpio_debounce_time(OMAP3_STALKER_TS_GPIO, 0xa);
+ gpio_set_debounce(OMAP3_STALKER_TS_GPIO, 310);
}
static int ads7846_get_pendown_state(void)
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
index 02804224517b..e10db7a90cb2 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -1369,6 +1369,7 @@ static struct clk emif1_ick = {
.ops = &clkops_omap2_dflt,
.enable_reg = OMAP4430_CM_MEMIF_EMIF_1_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .flags = ENABLE_ON_INIT,
.clkdm_name = "l3_emif_clkdm",
.parent = &ddrphy_ck,
.recalc = &followparent_recalc,
@@ -1379,6 +1380,7 @@ static struct clk emif2_ick = {
.ops = &clkops_omap2_dflt,
.enable_reg = OMAP4430_CM_MEMIF_EMIF_2_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .flags = ENABLE_ON_INIT,
.clkdm_name = "l3_emif_clkdm",
.parent = &ddrphy_ck,
.recalc = &followparent_recalc,
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 95c9a5f774e1..b7a4133267d8 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -409,10 +409,11 @@ static int _init_main_clk(struct omap_hwmod *oh)
return 0;
oh->_clk = omap_clk_get_by_name(oh->main_clk);
- if (!oh->_clk)
+ if (!oh->_clk) {
pr_warning("omap_hwmod: %s: cannot clk_get main_clk %s\n",
oh->name, oh->main_clk);
return -EINVAL;
+ }
if (!oh->_clk->clkdm)
pr_warning("omap_hwmod: %s: missing clockdomain for %s.\n",
@@ -444,10 +445,11 @@ static int _init_interface_clks(struct omap_hwmod *oh)
continue;
c = omap_clk_get_by_name(os->clk);
- if (!c)
+ if (!c) {
pr_warning("omap_hwmod: %s: cannot clk_get interface_clk %s\n",
oh->name, os->clk);
ret = -EINVAL;
+ }
os->_clk = c;
}
@@ -470,10 +472,11 @@ static int _init_opt_clks(struct omap_hwmod *oh)
for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) {
c = omap_clk_get_by_name(oc->clk);
- if (!c)
+ if (!c) {
pr_warning("omap_hwmod: %s: cannot clk_get opt_clk %s\n",
oh->name, oc->clk);
ret = -EINVAL;
+ }
oc->_clk = c;
}
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 2e967716cc3f..b88737fd6cfe 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -99,7 +99,7 @@ static void omap3_enable_io_chain(void)
/* Do a readback to assure write has been done */
prm_read_mod_reg(WKUP_MOD, PM_WKEN);
- while (!(prm_read_mod_reg(WKUP_MOD, PM_WKST) &
+ while (!(prm_read_mod_reg(WKUP_MOD, PM_WKEN) &
OMAP3430_ST_IO_CHAIN_MASK)) {
timeout++;
if (timeout > 1000) {
@@ -108,7 +108,7 @@ static void omap3_enable_io_chain(void)
return;
}
prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK,
- WKUP_MOD, PM_WKST);
+ WKUP_MOD, PM_WKEN);
}
}
}
diff --git a/arch/arm/mach-omap2/usb-ehci.c b/arch/arm/mach-omap2/usb-ehci.c
index c68f799e83c5..d72d1ac30333 100644
--- a/arch/arm/mach-omap2/usb-ehci.c
+++ b/arch/arm/mach-omap2/usb-ehci.c
@@ -20,6 +20,8 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+
#include <asm/io.h>
#include <plat/mux.h>
diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c
index d60db87dde08..fa6a708b4099 100644
--- a/arch/arm/mach-pxa/mioa701.c
+++ b/arch/arm/mach-pxa/mioa701.c
@@ -697,7 +697,7 @@ static struct i2c_board_info __initdata mioa701_pi2c_devices[] = {
};
/* Board I2C devices. */
-static struct i2c_board_info __initdata mioa701_i2c_devices[] = {
+static struct i2c_board_info mioa701_i2c_devices[] = {
{
I2C_BOARD_INFO("mt9m111", 0x5d),
},
diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c
index f5d1ae3db3a4..d303c6929d32 100644
--- a/arch/arm/mach-pxa/z2.c
+++ b/arch/arm/mach-pxa/z2.c
@@ -3,8 +3,9 @@
*
* Support for the Zipit Z2 Handheld device.
*
- * Author: Ken McGuire
- * Created: Jan 25, 2009
+ * Copyright (C) 2009-2010 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on research and code by: Ken McGuire
* Based on mainstone.c as modified for the Zipit Z2.
*
* This program is free software; you can redistribute it and/or modify
@@ -157,21 +158,14 @@ static struct mtd_partition z2_flash_parts[] = {
{
.name = "U-Boot Bootloader",
.offset = 0x0,
- .size = 0x20000,
- },
- {
- .name = "Linux Kernel",
- .offset = 0x20000,
- .size = 0x220000,
- },
- {
- .name = "Filesystem",
- .offset = 0x240000,
- .size = 0x5b0000,
- },
- {
+ .size = 0x40000,
+ }, {
.name = "U-Boot Environment",
- .offset = 0x7f0000,
+ .offset = 0x40000,
+ .size = 0x60000,
+ }, {
+ .name = "Flash",
+ .offset = 0x60000,
.size = MTDPART_SIZ_FULL,
},
};
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
index ee5e392430e8..b4575ae9648e 100644
--- a/arch/arm/mach-realview/Kconfig
+++ b/arch/arm/mach-realview/Kconfig
@@ -18,6 +18,7 @@ config REALVIEW_EB_ARM11MP
bool "Support ARM11MPCore tile"
depends on MACH_REALVIEW_EB
select CPU_V6
+ select ARCH_HAS_BARRIERS if SMP
help
Enable support for the ARM11MPCore tile on the Realview platform.
@@ -35,6 +36,7 @@ config MACH_REALVIEW_PB11MP
select CPU_V6
select ARM_GIC
select HAVE_PATA_PLATFORM
+ select ARCH_HAS_BARRIERS if SMP
help
Include support for the ARM(R) RealView MPCore Platform Baseboard.
PB11MPCore is a platform with an on-board ARM11MPCore and has
diff --git a/arch/arm/mach-realview/include/mach/barriers.h b/arch/arm/mach-realview/include/mach/barriers.h
new file mode 100644
index 000000000000..0c5d749d7b5f
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/barriers.h
@@ -0,0 +1,8 @@
+/*
+ * Barriers redefined for RealView ARM11MPCore platforms with L220 cache
+ * controller to work around hardware errata causing the outer_sync()
+ * operation to deadlock the system.
+ */
+#define mb() dsb()
+#define rmb() dmb()
+#define wmb() mb()
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 422ccd70d5f5..4425018fab82 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -32,6 +32,7 @@
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/pmu.h>
+#include <asm/pgtable.h>
#include <asm/hardware/gic.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/localtimer.h>
@@ -457,7 +458,7 @@ static void __init realview_eb_init(void)
MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .phys_io = REALVIEW_EB_UART0_BASE,
+ .phys_io = REALVIEW_EB_UART0_BASE & SECTION_MASK,
.io_pg_offst = (IO_ADDRESS(REALVIEW_EB_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
.fixup = realview_fixup,
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index 96568ebfa2bb..099a1f125cf8 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -32,6 +32,7 @@
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/pmu.h>
+#include <asm/pgtable.h>
#include <asm/hardware/gic.h>
#include <asm/hardware/cache-l2x0.h>
@@ -351,7 +352,7 @@ static void __init realview_pb1176_init(void)
MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .phys_io = REALVIEW_PB1176_UART0_BASE,
+ .phys_io = REALVIEW_PB1176_UART0_BASE & SECTION_MASK,
.io_pg_offst = (IO_ADDRESS(REALVIEW_PB1176_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
.fixup = realview_pb1176_fixup,
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index 7fbefbbebaf0..0e07a5ccb75f 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -32,6 +32,7 @@
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/pmu.h>
+#include <asm/pgtable.h>
#include <asm/hardware/gic.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/localtimer.h>
@@ -373,7 +374,7 @@ static void __init realview_pb11mp_init(void)
MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .phys_io = REALVIEW_PB11MP_UART0_BASE,
+ .phys_io = REALVIEW_PB11MP_UART0_BASE & SECTION_MASK,
.io_pg_offst = (IO_ADDRESS(REALVIEW_PB11MP_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
.fixup = realview_fixup,
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index d3c113b3dfce..ac2f06f1ca50 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -31,6 +31,7 @@
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/pmu.h>
+#include <asm/pgtable.h>
#include <asm/hardware/gic.h>
#include <asm/mach/arch.h>
@@ -323,7 +324,7 @@ static void __init realview_pba8_init(void)
MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .phys_io = REALVIEW_PBA8_UART0_BASE,
+ .phys_io = REALVIEW_PBA8_UART0_BASE & SECTION_MASK,
.io_pg_offst = (IO_ADDRESS(REALVIEW_PBA8_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
.fixup = realview_fixup,
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index a235ba30996b..08fd683adc4c 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -31,6 +31,7 @@
#include <asm/mach-types.h>
#include <asm/pmu.h>
#include <asm/smp_twd.h>
+#include <asm/pgtable.h>
#include <asm/hardware/gic.h>
#include <asm/hardware/cache-l2x0.h>
@@ -409,7 +410,7 @@ static void __init realview_pbx_init(void)
MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .phys_io = REALVIEW_PBX_UART0_BASE,
+ .phys_io = REALVIEW_PBX_UART0_BASE & SECTION_MASK,
.io_pg_offst = (IO_ADDRESS(REALVIEW_PBX_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
.fixup = realview_pbx_fixup,
diff --git a/arch/arm/mach-s5p6442/clock.c b/arch/arm/mach-s5p6442/clock.c
index 3aadbf42c112..087e57f20ad5 100644
--- a/arch/arm/mach-s5p6442/clock.c
+++ b/arch/arm/mach-s5p6442/clock.c
@@ -294,7 +294,7 @@ void __init_or_cpufreq s5p6442_setup_clocks(void)
mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
epll = s5p_get_pll45xx(xtal, __raw_readl(S5P_EPLL_CON), pll_4500);
- printk(KERN_INFO "S5P6440: PLL settings, A=%ld, M=%ld, E=%ld",
+ printk(KERN_INFO "S5P6442: PLL settings, A=%ld, M=%ld, E=%ld",
apll, mpll, epll);
clk_fout_apll.rate = apll;
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index 154bca4abc09..af91fefef2c6 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -183,6 +183,11 @@ static int s5pv210_clk_mask0_ctrl(struct clk *clk, int enable)
return s5p_gatectrl(S5P_CLK_SRC_MASK0, clk, enable);
}
+static int s5pv210_clk_mask1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLK_SRC_MASK1, clk, enable);
+}
+
static struct clk clk_sclk_hdmi27m = {
.name = "sclk_hdmi27m",
.id = -1,
@@ -406,14 +411,14 @@ static struct clk init_clocks_disable[] = {
.id = 0,
.parent = &clk_p,
.enable = s5pv210_clk_ip3_ctrl,
- .ctrlbit = (1<<4),
+ .ctrlbit = (1 << 5),
}, {
.name = "i2s_v32",
.id = 1,
.parent = &clk_p,
.enable = s5pv210_clk_ip3_ctrl,
- .ctrlbit = (1<<4),
- }
+ .ctrlbit = (1 << 6),
+ },
};
static struct clk init_clocks[] = {
@@ -429,25 +434,25 @@ static struct clk init_clocks[] = {
.id = 0,
.parent = &clk_pclk_psys.clk,
.enable = s5pv210_clk_ip3_ctrl,
- .ctrlbit = (1<<7),
+ .ctrlbit = (1 << 17),
}, {
.name = "uart",
.id = 1,
.parent = &clk_pclk_psys.clk,
.enable = s5pv210_clk_ip3_ctrl,
- .ctrlbit = (1<<8),
+ .ctrlbit = (1 << 18),
}, {
.name = "uart",
.id = 2,
.parent = &clk_pclk_psys.clk,
.enable = s5pv210_clk_ip3_ctrl,
- .ctrlbit = (1<<9),
+ .ctrlbit = (1 << 19),
}, {
.name = "uart",
.id = 3,
.parent = &clk_pclk_psys.clk,
.enable = s5pv210_clk_ip3_ctrl,
- .ctrlbit = (1<<10),
+ .ctrlbit = (1 << 20),
},
};
@@ -497,8 +502,8 @@ static struct clksrc_clk clk_sclk_dac = {
.clk = {
.name = "sclk_dac",
.id = -1,
- .ctrlbit = (1 << 10),
- .enable = s5pv210_clk_ip1_ctrl,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 2),
},
.sources = &clkset_sclk_dac,
.reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 1 },
@@ -527,8 +532,8 @@ static struct clksrc_clk clk_sclk_hdmi = {
.clk = {
.name = "sclk_hdmi",
.id = -1,
- .enable = s5pv210_clk_ip1_ctrl,
- .ctrlbit = (1 << 11),
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 0),
},
.sources = &clkset_sclk_hdmi,
.reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 },
@@ -565,8 +570,8 @@ static struct clksrc_clk clk_sclk_audio0 = {
.clk = {
.name = "sclk_audio",
.id = 0,
- .enable = s5pv210_clk_ip3_ctrl,
- .ctrlbit = (1 << 4),
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 24),
},
.sources = &clkset_sclk_audio0,
.reg_src = { .reg = S5P_CLK_SRC6, .shift = 0, .size = 4 },
@@ -594,8 +599,8 @@ static struct clksrc_clk clk_sclk_audio1 = {
.clk = {
.name = "sclk_audio",
.id = 1,
- .enable = s5pv210_clk_ip3_ctrl,
- .ctrlbit = (1 << 5),
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 25),
},
.sources = &clkset_sclk_audio1,
.reg_src = { .reg = S5P_CLK_SRC6, .shift = 4, .size = 4 },
@@ -623,8 +628,8 @@ static struct clksrc_clk clk_sclk_audio2 = {
.clk = {
.name = "sclk_audio",
.id = 2,
- .enable = s5pv210_clk_ip3_ctrl,
- .ctrlbit = (1 << 6),
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 26),
},
.sources = &clkset_sclk_audio2,
.reg_src = { .reg = S5P_CLK_SRC6, .shift = 8, .size = 4 },
@@ -680,8 +685,8 @@ static struct clksrc_clk clksrcs[] = {
.clk = {
.name = "uclk1",
.id = 0,
- .ctrlbit = (1<<17),
- .enable = s5pv210_clk_ip3_ctrl,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 12),
},
.sources = &clkset_uart,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
@@ -690,8 +695,8 @@ static struct clksrc_clk clksrcs[] = {
.clk = {
.name = "uclk1",
.id = 1,
- .enable = s5pv210_clk_ip3_ctrl,
- .ctrlbit = (1 << 18),
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 13),
},
.sources = &clkset_uart,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 },
@@ -700,8 +705,8 @@ static struct clksrc_clk clksrcs[] = {
.clk = {
.name = "uclk1",
.id = 2,
- .enable = s5pv210_clk_ip3_ctrl,
- .ctrlbit = (1 << 19),
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 14),
},
.sources = &clkset_uart,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 },
@@ -710,8 +715,8 @@ static struct clksrc_clk clksrcs[] = {
.clk = {
.name = "uclk1",
.id = 3,
- .enable = s5pv210_clk_ip3_ctrl,
- .ctrlbit = (1 << 20),
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 15),
},
.sources = &clkset_uart,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 },
@@ -720,8 +725,8 @@ static struct clksrc_clk clksrcs[] = {
.clk = {
.name = "sclk_mixer",
.id = -1,
- .enable = s5pv210_clk_ip1_ctrl,
- .ctrlbit = (1 << 9),
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 1),
},
.sources = &clkset_sclk_mixer,
.reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 },
@@ -738,8 +743,8 @@ static struct clksrc_clk clksrcs[] = {
.clk = {
.name = "sclk_fimc",
.id = 0,
- .enable = s5pv210_clk_ip0_ctrl,
- .ctrlbit = (1 << 24),
+ .enable = s5pv210_clk_mask1_ctrl,
+ .ctrlbit = (1 << 2),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 4 },
@@ -748,8 +753,8 @@ static struct clksrc_clk clksrcs[] = {
.clk = {
.name = "sclk_fimc",
.id = 1,
- .enable = s5pv210_clk_ip0_ctrl,
- .ctrlbit = (1 << 25),
+ .enable = s5pv210_clk_mask1_ctrl,
+ .ctrlbit = (1 << 3),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 4 },
@@ -758,8 +763,8 @@ static struct clksrc_clk clksrcs[] = {
.clk = {
.name = "sclk_fimc",
.id = 2,
- .enable = s5pv210_clk_ip0_ctrl,
- .ctrlbit = (1 << 26),
+ .enable = s5pv210_clk_mask1_ctrl,
+ .ctrlbit = (1 << 4),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 4 },
@@ -768,6 +773,8 @@ static struct clksrc_clk clksrcs[] = {
.clk = {
.name = "sclk_cam",
.id = 0,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 3),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 4 },
@@ -776,6 +783,8 @@ static struct clksrc_clk clksrcs[] = {
.clk = {
.name = "sclk_cam",
.id = 1,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 4),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC1, .shift = 16, .size = 4 },
@@ -784,8 +793,8 @@ static struct clksrc_clk clksrcs[] = {
.clk = {
.name = "sclk_fimd",
.id = -1,
- .enable = s5pv210_clk_ip1_ctrl,
- .ctrlbit = (1 << 0),
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 5),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC1, .shift = 20, .size = 4 },
@@ -794,8 +803,8 @@ static struct clksrc_clk clksrcs[] = {
.clk = {
.name = "sclk_mmc",
.id = 0,
- .enable = s5pv210_clk_ip2_ctrl,
- .ctrlbit = (1 << 16),
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 8),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 0, .size = 4 },
@@ -804,8 +813,8 @@ static struct clksrc_clk clksrcs[] = {
.clk = {
.name = "sclk_mmc",
.id = 1,
- .enable = s5pv210_clk_ip2_ctrl,
- .ctrlbit = (1 << 17),
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 9),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 4, .size = 4 },
@@ -814,8 +823,8 @@ static struct clksrc_clk clksrcs[] = {
.clk = {
.name = "sclk_mmc",
.id = 2,
- .enable = s5pv210_clk_ip2_ctrl,
- .ctrlbit = (1 << 18),
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 10),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 8, .size = 4 },
@@ -824,8 +833,8 @@ static struct clksrc_clk clksrcs[] = {
.clk = {
.name = "sclk_mmc",
.id = 3,
- .enable = s5pv210_clk_ip2_ctrl,
- .ctrlbit = (1 << 19),
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 11),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 12, .size = 4 },
@@ -864,8 +873,8 @@ static struct clksrc_clk clksrcs[] = {
.clk = {
.name = "sclk_csis",
.id = -1,
- .enable = s5pv210_clk_ip0_ctrl,
- .ctrlbit = (1 << 31),
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 6),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC1, .shift = 24, .size = 4 },
@@ -874,8 +883,8 @@ static struct clksrc_clk clksrcs[] = {
.clk = {
.name = "sclk_spi",
.id = 0,
- .enable = s5pv210_clk_ip3_ctrl,
- .ctrlbit = (1 << 12),
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 16),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC5, .shift = 0, .size = 4 },
@@ -884,8 +893,8 @@ static struct clksrc_clk clksrcs[] = {
.clk = {
.name = "sclk_spi",
.id = 1,
- .enable = s5pv210_clk_ip3_ctrl,
- .ctrlbit = (1 << 13),
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 17),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC5, .shift = 4, .size = 4 },
@@ -894,8 +903,8 @@ static struct clksrc_clk clksrcs[] = {
.clk = {
.name = "sclk_pwi",
.id = -1,
- .enable = &s5pv210_clk_ip4_ctrl,
- .ctrlbit = (1 << 2),
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 29),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC6, .shift = 20, .size = 4 },
@@ -904,8 +913,8 @@ static struct clksrc_clk clksrcs[] = {
.clk = {
.name = "sclk_pwm",
.id = -1,
- .enable = s5pv210_clk_ip3_ctrl,
- .ctrlbit = (1 << 23),
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 19),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC5, .shift = 12, .size = 4 },
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index 9b11eedba65f..6353459bb567 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -10,6 +10,7 @@
#include <linux/amba/clcd.h>
#include <asm/clkdev.h>
+#include <asm/pgtable.h>
#include <asm/hardware/arm_timer.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/hardware/gic.h>
@@ -236,7 +237,7 @@ static void ct_ca9x4_init(void)
}
MACHINE_START(VEXPRESS, "ARM-Versatile Express CA9x4")
- .phys_io = V2M_UART0,
+ .phys_io = V2M_UART0 & SECTION_MASK,
.io_pg_offst = (__MMIO_P2V(V2M_UART0) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
.map_io = ct_ca9x4_map_io,
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 346ae14824a5..101105e52610 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -735,6 +735,25 @@ config NEEDS_SYSCALL_FOR_CMPXCHG
Forget about fast user space cmpxchg support.
It is just not possible.
+config DMA_CACHE_RWFO
+ bool "Enable read/write for ownership DMA cache maintenance"
+ depends on CPU_V6 && SMP
+ default y
+ help
+ The Snoop Control Unit on ARM11MPCore does not detect the
+ cache maintenance operations and the dma_{map,unmap}_area()
+ functions may leave stale cache entries on other CPUs. By
+ enabling this option, Read or Write For Ownership in the ARMv6
+ DMA cache maintenance functions is performed. These LDR/STR
+ instructions change the cache line state to shared or modified
+ so that the cache operation has the desired effect.
+
+ Note that the workaround is only valid on processors that do
+ not perform speculative loads into the D-cache. For such
+ processors, if cache maintenance operations are not broadcast
+ in hardware, other workarounds are needed (e.g. cache
+ maintenance broadcasting in software via FIQ).
+
config OUTER_CACHE
bool
@@ -794,6 +813,8 @@ config ARM_L1_CACHE_SHIFT
config ARM_DMA_MEM_BUFFERABLE
bool "Use non-cacheable memory for DMA" if CPU_V6 && !CPU_V7
+ depends on !(MACH_REALVIEW_PB1176 || REALVIEW_EB_ARM11MP || \
+ MACH_REALVIEW_PB11MP)
default y if CPU_V6 || CPU_V7
help
Historically, the kernel has used strongly ordered mappings to
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S
index e46ecd847138..86aa689ef1aa 100644
--- a/arch/arm/mm/cache-v6.S
+++ b/arch/arm/mm/cache-v6.S
@@ -211,8 +211,9 @@ v6_dma_inv_range:
mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line
#endif
1:
-#ifdef CONFIG_SMP
- str r0, [r0] @ write for ownership
+#ifdef CONFIG_DMA_CACHE_RWFO
+ ldr r2, [r0] @ read for ownership
+ str r2, [r0] @ write for ownership
#endif
#ifdef HARVARD_CACHE
mcr p15, 0, r0, c7, c6, 1 @ invalidate D line
@@ -234,7 +235,7 @@ v6_dma_inv_range:
v6_dma_clean_range:
bic r0, r0, #D_CACHE_LINE_SIZE - 1
1:
-#ifdef CONFIG_SMP
+#ifdef CONFIG_DMA_CACHE_RWFO
ldr r2, [r0] @ read for ownership
#endif
#ifdef HARVARD_CACHE
@@ -257,7 +258,7 @@ v6_dma_clean_range:
ENTRY(v6_dma_flush_range)
bic r0, r0, #D_CACHE_LINE_SIZE - 1
1:
-#ifdef CONFIG_SMP
+#ifdef CONFIG_DMA_CACHE_RWFO
ldr r2, [r0] @ read for ownership
str r2, [r0] @ write for ownership
#endif
@@ -283,9 +284,13 @@ ENTRY(v6_dma_map_area)
add r1, r1, r0
teq r2, #DMA_FROM_DEVICE
beq v6_dma_inv_range
+#ifndef CONFIG_DMA_CACHE_RWFO
+ b v6_dma_clean_range
+#else
teq r2, #DMA_TO_DEVICE
beq v6_dma_clean_range
b v6_dma_flush_range
+#endif
ENDPROC(v6_dma_map_area)
/*
@@ -295,6 +300,11 @@ ENDPROC(v6_dma_map_area)
* - dir - DMA direction
*/
ENTRY(v6_dma_unmap_area)
+#ifndef CONFIG_DMA_CACHE_RWFO
+ add r1, r1, r0
+ teq r2, #DMA_TO_DEVICE
+ bne v6_dma_inv_range
+#endif
mov pc, lr
ENDPROC(v6_dma_unmap_area)
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 13fa536d82e6..9e7742f0a102 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -24,15 +24,6 @@
#include <asm/tlbflush.h>
#include <asm/sizes.h>
-/* Sanity check size */
-#if (CONSISTENT_DMA_SIZE % SZ_2M)
-#error "CONSISTENT_DMA_SIZE must be multiple of 2MiB"
-#endif
-
-#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT)
-#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT)
-#define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT)
-
static u64 get_coherent_dma_mask(struct device *dev)
{
u64 mask = ISA_DMA_THRESHOLD;
@@ -123,6 +114,15 @@ static void __dma_free_buffer(struct page *page, size_t size)
}
#ifdef CONFIG_MMU
+/* Sanity check size */
+#if (CONSISTENT_DMA_SIZE % SZ_2M)
+#error "CONSISTENT_DMA_SIZE must be multiple of 2MiB"
+#endif
+
+#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT)
+#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT)
+#define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT)
+
/*
* These are the page tables (2MB each) covering uncached, DMA consistent allocations
*/
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index c64875f11fac..44bafdab2dce 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -541,11 +541,11 @@ void omap_dm_timer_stop(struct omap_dm_timer *timer)
* timer is stopped
*/
udelay(3500000 / clk_get_rate(timer->fclk) + 1);
- /* Ack possibly pending interrupt */
- omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG,
- OMAP_TIMER_INT_OVERFLOW);
#endif
}
+ /* Ack possibly pending interrupt */
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG,
+ OMAP_TIMER_INT_OVERFLOW);
}
EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 393e9219a5b6..9b7e3545f325 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -673,6 +673,7 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
if (cpu_is_omap34xx() || cpu_is_omap44xx())
clk_disable(bank->dbck);
}
+ bank->dbck_enable_mask = val;
__raw_writel(val, reg);
}
diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c
index e43983ba59c5..8ce0de247c71 100644
--- a/arch/arm/plat-omap/iovmm.c
+++ b/arch/arm/plat-omap/iovmm.c
@@ -140,8 +140,10 @@ static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags)
return ERR_PTR(-ENOMEM);
err = sg_alloc_table(sgt, nr_entries, GFP_KERNEL);
- if (err)
+ if (err) {
+ kfree(sgt);
return ERR_PTR(err);
+ }
pr_debug("%s: sgt:%p(%d entries)\n", __func__, sgt, nr_entries);
diff --git a/arch/arm/plat-pxa/Makefile b/arch/arm/plat-pxa/Makefile
index 6187edfbcb77..a17cc0c6a6b0 100644
--- a/arch/arm/plat-pxa/Makefile
+++ b/arch/arm/plat-pxa/Makefile
@@ -2,8 +2,9 @@
# Makefile for code common across different PXA processor families
#
-obj-y := dma.o pmu.o
+obj-y := dma.o
+obj-$(CONFIG_ARCH_PXA) += pmu.o
obj-$(CONFIG_GENERIC_GPIO) += gpio.o
obj-$(CONFIG_PXA3xx) += mfp.o
obj-$(CONFIG_ARCH_MMP) += mfp.o
diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c
index e56c8075df97..f36cd3327025 100644
--- a/arch/arm/plat-s5p/irq-eint.c
+++ b/arch/arm/plat-s5p/irq-eint.c
@@ -71,7 +71,7 @@ static int s5p_irq_eint_set_type(unsigned int irq, unsigned int type)
break;
case IRQ_TYPE_EDGE_FALLING:
- newvalue = S5P_EXTINT_RISEEDGE;
+ newvalue = S5P_EXTINT_FALLEDGE;
break;
case IRQ_TYPE_EDGE_BOTH:
diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h
index 13f9fb20900a..016674fa20dd 100644
--- a/arch/arm/plat-samsung/include/plat/sdhci.h
+++ b/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -166,8 +166,10 @@ static inline void s3c6410_default_sdhci2(void) { }
#else
static inline void s3c6410_default_sdhci0(void) { }
static inline void s3c6410_default_sdhci1(void) { }
+static inline void s3c6410_default_sdhci2(void) { }
static inline void s3c6400_default_sdhci0(void) { }
static inline void s3c6400_default_sdhci1(void) { }
+static inline void s3c6400_default_sdhci2(void) { }
#endif /* CONFIG_S3C64XX_SETUP_SDHCI */
@@ -239,7 +241,7 @@ static inline void s5pv210_default_sdhci0(void)
s3c_hsmmc0_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
}
#else
-static inline void s5pc100_default_sdhci0(void) { }
+static inline void s5pv210_default_sdhci0(void) { }
#endif /* CONFIG_S3C_DEV_HSMMC */
#ifdef CONFIG_S3C_DEV_HSMMC1
diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c
index 5dfd916e9ea6..7b3cdc6c6d91 100644
--- a/arch/ia64/mm/tlb.c
+++ b/arch/ia64/mm/tlb.c
@@ -121,7 +121,7 @@ static inline void down_spin(struct spinaphore *ss)
ia64_invala();
for (;;) {
- asm volatile ("ld4.c.nc %0=[%1]" : "=r"(serve) : "r"(&ss->serve) : "memory");
+ asm volatile ("ld8.c.nc %0=[%1]" : "=r"(serve) : "r"(&ss->serve) : "memory");
if (time_before(t, serve))
return;
cpu_relax();
diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c
index 14eb8c492da2..5ef06a164a82 100644
--- a/arch/mips/alchemy/common/power.c
+++ b/arch/mips/alchemy/common/power.c
@@ -193,9 +193,15 @@ static void restore_core_regs(void)
void au_sleep(void)
{
- save_core_regs();
- au1xxx_save_and_sleep();
- restore_core_regs();
+ int cpuid = alchemy_get_cputype();
+ if (cpuid != ALCHEMY_CPU_UNKNOWN) {
+ save_core_regs();
+ if (cpuid <= ALCHEMY_CPU_AU1500)
+ alchemy_sleep_au1000();
+ else if (cpuid <= ALCHEMY_CPU_AU1200)
+ alchemy_sleep_au1550();
+ restore_core_regs();
+ }
}
#endif /* CONFIG_PM */
diff --git a/arch/mips/alchemy/common/sleeper.S b/arch/mips/alchemy/common/sleeper.S
index 4f4b16741d12..77f3c743b716 100644
--- a/arch/mips/alchemy/common/sleeper.S
+++ b/arch/mips/alchemy/common/sleeper.S
@@ -22,10 +22,9 @@
.set noat
.align 5
-/* Save all of the processor general registers and go to sleep.
- * A wakeup condition will get us back here to restore the registers.
- */
-LEAF(au1xxx_save_and_sleep)
+
+/* preparatory stuff */
+.macro SETUP_SLEEP
subu sp, PT_SIZE
sw $1, PT_R1(sp)
sw $2, PT_R2(sp)
@@ -69,12 +68,32 @@ LEAF(au1xxx_save_and_sleep)
*/
lui t3, 0xb190 /* sys_xxx */
sw sp, 0x0018(t3)
- la k0, 3f /* resume path */
+ la k0, alchemy_sleep_wakeup /* resume path */
sw k0, 0x001c(t3)
+.endm
- /* Put SDRAM into self refresh: Preload instructions into cache,
- * issue a precharge, auto/self refresh, then sleep commands to it.
- */
+.macro DO_SLEEP
+ /* put power supply and processor to sleep */
+ sw zero, 0x0078(t3) /* sys_slppwr */
+ sync
+ sw zero, 0x007c(t3) /* sys_sleep */
+ sync
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+.endm
+
+/* sleep code for Au1000/Au1100/Au1500 memory controller type */
+LEAF(alchemy_sleep_au1000)
+
+ SETUP_SLEEP
+
+ /* cache following instructions, as memory gets put to sleep */
la t0, 1f
.set mips3
cache 0x14, 0(t0)
@@ -84,17 +103,32 @@ LEAF(au1xxx_save_and_sleep)
.set mips0
1: lui a0, 0xb400 /* mem_xxx */
-#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100) || \
- defined(CONFIG_SOC_AU1500)
sw zero, 0x001c(a0) /* Precharge */
sync
sw zero, 0x0020(a0) /* Auto Refresh */
sync
sw zero, 0x0030(a0) /* Sleep */
sync
-#endif
-#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
+ DO_SLEEP
+
+END(alchemy_sleep_au1000)
+
+/* sleep code for Au1550/Au1200 memory controller type */
+LEAF(alchemy_sleep_au1550)
+
+ SETUP_SLEEP
+
+ /* cache following instructions, as memory gets put to sleep */
+ la t0, 1f
+ .set mips3
+ cache 0x14, 0(t0)
+ cache 0x14, 32(t0)
+ cache 0x14, 64(t0)
+ cache 0x14, 96(t0)
+ .set mips0
+
+1: lui a0, 0xb400 /* mem_xxx */
sw zero, 0x08c0(a0) /* Precharge */
sync
sw zero, 0x08d0(a0) /* Self Refresh */
@@ -114,26 +148,17 @@ LEAF(au1xxx_save_and_sleep)
and t1, t0, t1 /* clear CE[1:0] */
sw t1, 0x0840(a0) /* mem_sdconfiga */
sync
-#endif
- /* put power supply and processor to sleep */
- sw zero, 0x0078(t3) /* sys_slppwr */
- sync
- sw zero, 0x007c(t3) /* sys_sleep */
- sync
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
+ DO_SLEEP
+
+END(alchemy_sleep_au1550)
+
/* This is where we return upon wakeup.
* Reload all of the registers and return.
*/
-3: lw k0, 0x20(sp)
+LEAF(alchemy_sleep_wakeup)
+ lw k0, 0x20(sp)
mtc0 k0, CP0_STATUS
lw k0, 0x1c(sp)
mtc0 k0, CP0_CONTEXT
@@ -169,4 +194,4 @@ LEAF(au1xxx_save_and_sleep)
lw $31, PT_R31(sp)
jr ra
addiu sp, PT_SIZE
-END(au1xxx_save_and_sleep)
+END(alchemy_sleep_wakeup)
diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c
index 566f2d7f2ea3..8f31d1d59683 100644
--- a/arch/mips/ar7/platform.c
+++ b/arch/mips/ar7/platform.c
@@ -542,7 +542,7 @@ static int __init ar7_register_uarts(void)
if (IS_ERR(bus_clk))
panic("unable to get bus clk\n");
- uart_port.type = PORT_16550A;
+ uart_port.type = PORT_AR7;
uart_port.uartclk = clk_get_rate(bus_clk) / 2;
uart_port.iotype = UPIO_MEM32;
uart_port.regshift = 2;
diff --git a/arch/mips/bcm47xx/Makefile b/arch/mips/bcm47xx/Makefile
index 35294b12d638..7465e8a72d9a 100644
--- a/arch/mips/bcm47xx/Makefile
+++ b/arch/mips/bcm47xx/Makefile
@@ -3,4 +3,4 @@
# under Linux.
#
-obj-y := gpio.o irq.o prom.o serial.o setup.o time.o wgt634u.o
+obj-y := gpio.o irq.o nvram.o prom.o serial.o setup.o time.o wgt634u.o
diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c
new file mode 100644
index 000000000000..06e03b222f6d
--- /dev/null
+++ b/arch/mips/bcm47xx/nvram.c
@@ -0,0 +1,94 @@
+/*
+ * BCM947xx nvram variable access
+ *
+ * Copyright (C) 2005 Broadcom Corporation
+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/ssb/ssb.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <asm/addrspace.h>
+#include <asm/mach-bcm47xx/nvram.h>
+#include <asm/mach-bcm47xx/bcm47xx.h>
+
+static char nvram_buf[NVRAM_SPACE];
+
+/* Probe for NVRAM header */
+static void __init early_nvram_init(void)
+{
+ struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
+ struct nvram_header *header;
+ int i;
+ u32 base, lim, off;
+ u32 *src, *dst;
+
+ base = mcore->flash_window;
+ lim = mcore->flash_window_size;
+
+ off = FLASH_MIN;
+ while (off <= lim) {
+ /* Windowed flash access */
+ header = (struct nvram_header *)
+ KSEG1ADDR(base + off - NVRAM_SPACE);
+ if (header->magic == NVRAM_HEADER)
+ goto found;
+ off <<= 1;
+ }
+
+ /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
+ header = (struct nvram_header *) KSEG1ADDR(base + 4096);
+ if (header->magic == NVRAM_HEADER)
+ goto found;
+
+ header = (struct nvram_header *) KSEG1ADDR(base + 1024);
+ if (header->magic == NVRAM_HEADER)
+ goto found;
+
+ return;
+
+found:
+ src = (u32 *) header;
+ dst = (u32 *) nvram_buf;
+ for (i = 0; i < sizeof(struct nvram_header); i += 4)
+ *dst++ = *src++;
+ for (; i < header->len && i < NVRAM_SPACE; i += 4)
+ *dst++ = le32_to_cpu(*src++);
+}
+
+int nvram_getenv(char *name, char *val, size_t val_len)
+{
+ char *var, *value, *end, *eq;
+
+ if (!name)
+ return 1;
+
+ if (!nvram_buf[0])
+ early_nvram_init();
+
+ /* Look for name=value and return value */
+ var = &nvram_buf[sizeof(struct nvram_header)];
+ end = nvram_buf + sizeof(nvram_buf) - 2;
+ end[0] = end[1] = '\0';
+ for (; *var; var = value + strlen(value) + 1) {
+ eq = strchr(var, '=');
+ if (!eq)
+ break;
+ value = eq + 1;
+ if ((eq - var) == strlen(name) &&
+ strncmp(var, name, (eq - var)) == 0) {
+ snprintf(val, val_len, "%s", value);
+ return 0;
+ }
+ }
+ return 1;
+}
+EXPORT_SYMBOL(nvram_getenv);
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index d442e11625fa..b1aee33efd11 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -1,8 +1,8 @@
/*
* Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org>
- * Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org>
* Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2006 Michael Buesch <mb@bu3sch.de>
+ * Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.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
@@ -33,6 +33,7 @@
#include <asm/time.h>
#include <bcm47xx.h>
#include <asm/fw/cfe/cfe_api.h>
+#include <asm/mach-bcm47xx/nvram.h>
struct ssb_bus ssb_bcm47xx;
EXPORT_SYMBOL(ssb_bcm47xx);
@@ -81,28 +82,42 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus,
/* Fill boardinfo structure */
memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo));
- if (cfe_getenv("boardvendor", buf, sizeof(buf)) >= 0)
+ if (cfe_getenv("boardvendor", buf, sizeof(buf)) >= 0 ||
+ nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0)
iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0);
- if (cfe_getenv("boardtype", buf, sizeof(buf)) >= 0)
+ if (cfe_getenv("boardtype", buf, sizeof(buf)) >= 0 ||
+ nvram_getenv("boardtype", buf, sizeof(buf)) >= 0)
iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0);
- if (cfe_getenv("boardrev", buf, sizeof(buf)) >= 0)
+ if (cfe_getenv("boardrev", buf, sizeof(buf)) >= 0 ||
+ nvram_getenv("boardrev", buf, sizeof(buf)) >= 0)
iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0);
/* Fill sprom structure */
memset(&(iv->sprom), 0, sizeof(struct ssb_sprom));
iv->sprom.revision = 3;
- if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
+ if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0 ||
+ nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
str2eaddr(buf, iv->sprom.et0mac);
- if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0)
+
+ if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0 ||
+ nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0)
str2eaddr(buf, iv->sprom.et1mac);
- if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0)
- iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 10);
- if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0)
- iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 10);
- if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0)
+
+ if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0 ||
+ nvram_getenv("et0phyaddr", buf, sizeof(buf)) >= 0)
+ iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 0);
+
+ if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0 ||
+ nvram_getenv("et1phyaddr", buf, sizeof(buf)) >= 0)
+ iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 0);
+
+ if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0 ||
+ nvram_getenv("et0mdcport", buf, sizeof(buf)) >= 0)
iv->sprom.et0mdcport = simple_strtoul(buf, NULL, 10);
- if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0)
+
+ if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0 ||
+ nvram_getenv("et1mdcport", buf, sizeof(buf)) >= 0)
iv->sprom.et1mdcport = simple_strtoul(buf, NULL, 10);
return 0;
diff --git a/arch/mips/include/asm/mach-ar7/ar7.h b/arch/mips/include/asm/mach-ar7/ar7.h
index f1cf38943497..483ffea9ecb1 100644
--- a/arch/mips/include/asm/mach-ar7/ar7.h
+++ b/arch/mips/include/asm/mach-ar7/ar7.h
@@ -50,7 +50,7 @@
#define UR8_REGS_WDT (AR7_REGS_BASE + 0x0b00)
#define UR8_REGS_UART1 (AR7_REGS_BASE + 0x0f00)
-#define AR7_RESET_PEREPHERIAL 0x0
+#define AR7_RESET_PERIPHERAL 0x0
#define AR7_RESET_SOFTWARE 0x4
#define AR7_RESET_STATUS 0x8
@@ -128,7 +128,7 @@ static inline int ar7_has_high_cpmac(void)
static inline void ar7_device_enable(u32 bit)
{
void *reset_reg =
- (void *)KSEG1ADDR(AR7_REGS_RESET + AR7_RESET_PEREPHERIAL);
+ (void *)KSEG1ADDR(AR7_REGS_RESET + AR7_RESET_PERIPHERAL);
writel(readl(reset_reg) | (1 << bit), reset_reg);
msleep(20);
}
@@ -136,7 +136,7 @@ static inline void ar7_device_enable(u32 bit)
static inline void ar7_device_disable(u32 bit)
{
void *reset_reg =
- (void *)KSEG1ADDR(AR7_REGS_RESET + AR7_RESET_PEREPHERIAL);
+ (void *)KSEG1ADDR(AR7_REGS_RESET + AR7_RESET_PERIPHERAL);
writel(readl(reset_reg) & ~(1 << bit), reset_reg);
msleep(20);
}
diff --git a/arch/mips/include/asm/mach-ar7/gpio.h b/arch/mips/include/asm/mach-ar7/gpio.h
index 73f9b162c970..abc317c0372e 100644
--- a/arch/mips/include/asm/mach-ar7/gpio.h
+++ b/arch/mips/include/asm/mach-ar7/gpio.h
@@ -24,7 +24,7 @@
#define AR7_GPIO_MAX 32
#define NR_BUILTIN_GPIO AR7_GPIO_MAX
-#define gpio_to_irq(gpio) NULL
+#define gpio_to_irq(gpio) -1
#define gpio_get_value __gpio_get_value
#define gpio_set_value __gpio_set_value
diff --git a/arch/mips/include/asm/mach-au1x00/au1000.h b/arch/mips/include/asm/mach-au1x00/au1000.h
index e76941db2312..a6976619160a 100644
--- a/arch/mips/include/asm/mach-au1x00/au1000.h
+++ b/arch/mips/include/asm/mach-au1x00/au1000.h
@@ -188,7 +188,8 @@ extern unsigned long get_au1x00_uart_baud_base(void);
extern unsigned long au1xxx_calc_clock(void);
/* PM: arch/mips/alchemy/common/sleeper.S, power.c, irq.c */
-void au1xxx_save_and_sleep(void);
+void alchemy_sleep_au1000(void);
+void alchemy_sleep_au1550(void);
void au_sleep(void);
diff --git a/arch/mips/include/asm/mach-bcm47xx/nvram.h b/arch/mips/include/asm/mach-bcm47xx/nvram.h
new file mode 100644
index 000000000000..0d8cc146f7a4
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm47xx/nvram.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2005, Broadcom Corporation
+ * Copyright (C) 2006, Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __NVRAM_H
+#define __NVRAM_H
+
+#include <linux/types.h>
+
+struct nvram_header {
+ u32 magic;
+ u32 len;
+ u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
+ u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */
+ u32 config_ncdl; /* ncdl values for memc */
+};
+
+#define NVRAM_HEADER 0x48534C46 /* 'FLSH' */
+#define NVRAM_VERSION 1
+#define NVRAM_HEADER_SIZE 20
+#define NVRAM_SPACE 0x8000
+
+#define FLASH_MIN 0x00020000 /* Minimum flash size */
+
+#define NVRAM_MAX_VALUE_LEN 255
+#define NVRAM_MAX_PARAM_LEN 64
+
+extern int nvram_getenv(char *name, char *val, size_t val_len);
+
+#endif
diff --git a/arch/mips/include/asm/mach-bcm63xx/gpio.h b/arch/mips/include/asm/mach-bcm63xx/gpio.h
index 7cda8c0a3979..1eb534de8e3b 100644
--- a/arch/mips/include/asm/mach-bcm63xx/gpio.h
+++ b/arch/mips/include/asm/mach-bcm63xx/gpio.h
@@ -3,7 +3,7 @@
#include <bcm63xx_gpio.h>
-#define gpio_to_irq(gpio) NULL
+#define gpio_to_irq(gpio) -1
#define gpio_get_value __gpio_get_value
#define gpio_set_value __gpio_set_value
diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c
index e9e64e0ff7aa..5a84a1f11231 100644
--- a/arch/mips/kernel/ftrace.c
+++ b/arch/mips/kernel/ftrace.c
@@ -2,7 +2,7 @@
* Code for replacing ftrace calls with jumps.
*
* Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
- * Copyright (C) 2009 DSLab, Lanzhou University, China
+ * Copyright (C) 2009, 2010 DSLab, Lanzhou University, China
* Author: Wu Zhangjin <wuzhangjin@gmail.com>
*
* Thanks goes to Steven Rostedt for writing the original x86 version.
@@ -12,18 +12,62 @@
#include <linux/init.h>
#include <linux/ftrace.h>
-#include <asm/cacheflush.h>
#include <asm/asm.h>
#include <asm/asm-offsets.h>
+#include <asm/cacheflush.h>
+#include <asm/uasm.h>
+
+/*
+ * If the Instruction Pointer is in module space (0xc0000000), return true;
+ * otherwise, it is in kernel space (0x80000000), return false.
+ *
+ * FIXME: This will not work when the kernel space and module space are the
+ * same. If they are the same, we need to modify scripts/recordmcount.pl,
+ * ftrace_make_nop/call() and the other related parts to ensure the
+ * enabling/disabling of the calling site to _mcount is right for both kernel
+ * and module.
+ */
+
+static inline int in_module(unsigned long ip)
+{
+ return ip & 0x40000000;
+}
#ifdef CONFIG_DYNAMIC_FTRACE
#define JAL 0x0c000000 /* jump & link: ip --> ra, jump to target */
#define ADDR_MASK 0x03ffffff /* op_code|addr : 31...26|25 ....0 */
-#define jump_insn_encode(op_code, addr) \
- ((unsigned int)((op_code) | (((addr) >> 2) & ADDR_MASK)))
-static unsigned int ftrace_nop = 0x00000000;
+#define INSN_B_1F_4 0x10000004 /* b 1f; offset = 4 */
+#define INSN_B_1F_5 0x10000005 /* b 1f; offset = 5 */
+#define INSN_NOP 0x00000000 /* nop */
+#define INSN_JAL(addr) \
+ ((unsigned int)(JAL | (((addr) >> 2) & ADDR_MASK)))
+
+static unsigned int insn_jal_ftrace_caller __read_mostly;
+static unsigned int insn_lui_v1_hi16_mcount __read_mostly;
+static unsigned int insn_j_ftrace_graph_caller __maybe_unused __read_mostly;
+
+static inline void ftrace_dyn_arch_init_insns(void)
+{
+ u32 *buf;
+ unsigned int v1;
+
+ /* lui v1, hi16_mcount */
+ v1 = 3;
+ buf = (u32 *)&insn_lui_v1_hi16_mcount;
+ UASM_i_LA_mostly(&buf, v1, MCOUNT_ADDR);
+
+ /* jal (ftrace_caller + 8), jump over the first two instruction */
+ buf = (u32 *)&insn_jal_ftrace_caller;
+ uasm_i_jal(&buf, (FTRACE_ADDR + 8));
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ /* j ftrace_graph_caller */
+ buf = (u32 *)&insn_j_ftrace_graph_caller;
+ uasm_i_j(&buf, (unsigned long)ftrace_graph_caller);
+#endif
+}
static int ftrace_modify_code(unsigned long ip, unsigned int new_code)
{
@@ -40,67 +84,56 @@ static int ftrace_modify_code(unsigned long ip, unsigned int new_code)
return 0;
}
-static int lui_v1;
-static int jal_mcount;
-
int ftrace_make_nop(struct module *mod,
struct dyn_ftrace *rec, unsigned long addr)
{
unsigned int new;
- int faulted;
unsigned long ip = rec->ip;
- /* We have compiled module with -mlong-calls, but compiled the kernel
- * without it, we need to cope with them respectively. */
- if (ip & 0x40000000) {
- /* record it for ftrace_make_call */
- if (lui_v1 == 0) {
- /* lui_v1 = *(unsigned int *)ip; */
- safe_load_code(lui_v1, ip, faulted);
-
- if (unlikely(faulted))
- return -EFAULT;
- }
-
- /* lui v1, hi_16bit_of_mcount --> b 1f (0x10000004)
+ /*
+ * We have compiled module with -mlong-calls, but compiled the kernel
+ * without it, we need to cope with them respectively.
+ */
+ if (in_module(ip)) {
+#if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT)
+ /*
+ * lui v1, hi_16bit_of_mcount --> b 1f (0x10000005)
+ * addiu v1, v1, low_16bit_of_mcount
+ * move at, ra
+ * move $12, ra_address
+ * jalr v1
+ * sub sp, sp, 8
+ * 1: offset = 5 instructions
+ */
+ new = INSN_B_1F_5;
+#else
+ /*
+ * lui v1, hi_16bit_of_mcount --> b 1f (0x10000004)
* addiu v1, v1, low_16bit_of_mcount
* move at, ra
* jalr v1
- * nop
- * 1f: (ip + 12)
+ * nop | move $12, ra_address | sub sp, sp, 8
+ * 1: offset = 4 instructions
*/
- new = 0x10000004;
+ new = INSN_B_1F_4;
+#endif
} else {
- /* record/calculate it for ftrace_make_call */
- if (jal_mcount == 0) {
- /* We can record it directly like this:
- * jal_mcount = *(unsigned int *)ip;
- * Herein, jump over the first two nop instructions */
- jal_mcount = jump_insn_encode(JAL, (MCOUNT_ADDR + 8));
- }
-
- /* move at, ra
- * jalr v1 --> nop
+ /*
+ * move at, ra
+ * jal _mcount --> nop
*/
- new = ftrace_nop;
+ new = INSN_NOP;
}
return ftrace_modify_code(ip, new);
}
-static int modified; /* initialized as 0 by default */
-
int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
{
unsigned int new;
unsigned long ip = rec->ip;
- /* We just need to remove the "b ftrace_stub" at the fist time! */
- if (modified == 0) {
- modified = 1;
- ftrace_modify_code(addr, ftrace_nop);
- }
/* ip, module: 0xc0000000, kernel: 0x80000000 */
- new = (ip & 0x40000000) ? lui_v1 : jal_mcount;
+ new = in_module(ip) ? insn_lui_v1_hi16_mcount : insn_jal_ftrace_caller;
return ftrace_modify_code(ip, new);
}
@@ -111,44 +144,48 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
{
unsigned int new;
- new = jump_insn_encode(JAL, (unsigned long)func);
+ new = INSN_JAL((unsigned long)func);
return ftrace_modify_code(FTRACE_CALL_IP, new);
}
int __init ftrace_dyn_arch_init(void *data)
{
+ /* Encode the instructions when booting */
+ ftrace_dyn_arch_init_insns();
+
+ /* Remove "b ftrace_stub" to ensure ftrace_caller() is executed */
+ ftrace_modify_code(MCOUNT_ADDR, INSN_NOP);
+
/* The return code is retured via data */
*(unsigned long *)data = 0;
return 0;
}
-#endif /* CONFIG_DYNAMIC_FTRACE */
+#endif /* CONFIG_DYNAMIC_FTRACE */
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
#ifdef CONFIG_DYNAMIC_FTRACE
extern void ftrace_graph_call(void);
-#define JMP 0x08000000 /* jump to target directly */
-#define CALL_FTRACE_GRAPH_CALLER \
- jump_insn_encode(JMP, (unsigned long)(&ftrace_graph_caller))
#define FTRACE_GRAPH_CALL_IP ((unsigned long)(&ftrace_graph_call))
int ftrace_enable_ftrace_graph_caller(void)
{
return ftrace_modify_code(FTRACE_GRAPH_CALL_IP,
- CALL_FTRACE_GRAPH_CALLER);
+ insn_j_ftrace_graph_caller);
}
int ftrace_disable_ftrace_graph_caller(void)
{
- return ftrace_modify_code(FTRACE_GRAPH_CALL_IP, ftrace_nop);
+ return ftrace_modify_code(FTRACE_GRAPH_CALL_IP, INSN_NOP);
}
-#endif /* !CONFIG_DYNAMIC_FTRACE */
+#endif /* CONFIG_DYNAMIC_FTRACE */
#ifndef KBUILD_MCOUNT_RA_ADDRESS
+
#define S_RA_SP (0xafbf << 16) /* s{d,w} ra, offset(sp) */
#define S_R_SP (0xafb0 << 16) /* s{d,w} R, offset(sp) */
#define OFFSET_MASK 0xffff /* stack offset range: 0 ~ PT_SIZE */
@@ -162,17 +199,17 @@ unsigned long ftrace_get_parent_addr(unsigned long self_addr,
unsigned int code;
int faulted;
- /* in module or kernel? */
- if (self_addr & 0x40000000) {
- /* module: move to the instruction "lui v1, HI_16BIT_OF_MCOUNT" */
- ip = self_addr - 20;
- } else {
- /* kernel: move to the instruction "move ra, at" */
- ip = self_addr - 12;
- }
+ /*
+ * For module, move the ip from calling site of mcount to the
+ * instruction "lui v1, hi_16bit_of_mcount"(offset is 20), but for
+ * kernel, move to the instruction "move ra, at"(offset is 12)
+ */
+ ip = self_addr - (in_module(self_addr) ? 20 : 12);
- /* search the text until finding the non-store instruction or "s{d,w}
- * ra, offset(sp)" instruction */
+ /*
+ * search the text until finding the non-store instruction or "s{d,w}
+ * ra, offset(sp)" instruction
+ */
do {
ip -= 4;
@@ -181,10 +218,11 @@ unsigned long ftrace_get_parent_addr(unsigned long self_addr,
if (unlikely(faulted))
return 0;
-
- /* If we hit the non-store instruction before finding where the
+ /*
+ * If we hit the non-store instruction before finding where the
* ra is stored, then this is a leaf function and it does not
- * store the ra on the stack. */
+ * store the ra on the stack
+ */
if ((code & S_R_SP) != S_R_SP)
return parent_addr;
@@ -202,7 +240,7 @@ unsigned long ftrace_get_parent_addr(unsigned long self_addr,
return 0;
}
-#endif
+#endif /* !KBUILD_MCOUNT_RA_ADDRESS */
/*
* Hook the return address and push it in the stack of return addrs
@@ -220,7 +258,8 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
if (unlikely(atomic_read(&current->tracing_graph_pause)))
return;
- /* "parent" is the stack address saved the return address of the caller
+ /*
+ * "parent" is the stack address saved the return address of the caller
* of _mcount.
*
* if the gcc < 4.5, a leaf function does not save the return address
@@ -242,10 +281,11 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
goto out;
#ifndef KBUILD_MCOUNT_RA_ADDRESS
parent = (unsigned long *)ftrace_get_parent_addr(self_addr, old,
- (unsigned long)parent,
- fp);
- /* If fails when getting the stack address of the non-leaf function's
- * ra, stop function graph tracer and return */
+ (unsigned long)parent, fp);
+ /*
+ * If fails when getting the stack address of the non-leaf function's
+ * ra, stop function graph tracer and return
+ */
if (parent == 0)
goto out;
#endif
@@ -272,4 +312,4 @@ out:
ftrace_graph_stop();
WARN_ON(1);
}
-#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
diff --git a/arch/mips/kernel/mcount.S b/arch/mips/kernel/mcount.S
index 6851fc97a511..6bfcb7a00ec6 100644
--- a/arch/mips/kernel/mcount.S
+++ b/arch/mips/kernel/mcount.S
@@ -6,6 +6,7 @@
* more details.
*
* Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University, China
+ * Copyright (C) 2010 DSLab, Lanzhou University, China
* Author: Wu Zhangjin <wuzhangjin@gmail.com>
*/
@@ -45,8 +46,6 @@
PTR_L a5, PT_R9(sp)
PTR_L a6, PT_R10(sp)
PTR_L a7, PT_R11(sp)
-#endif
-#ifdef CONFIG_64BIT
PTR_ADDIU sp, PT_SIZE
#else
PTR_ADDIU sp, (PT_SIZE + 8)
@@ -58,6 +57,12 @@
move ra, AT
.endm
+/*
+ * The -mmcount-ra-address option of gcc 4.5 uses register $12 to pass
+ * the location of the parent's return address.
+ */
+#define MCOUNT_RA_ADDRESS_REG $12
+
#ifdef CONFIG_DYNAMIC_FTRACE
NESTED(ftrace_caller, PT_SIZE, ra)
@@ -71,14 +76,14 @@ _mcount:
MCOUNT_SAVE_REGS
#ifdef KBUILD_MCOUNT_RA_ADDRESS
- PTR_S t0, PT_R12(sp) /* t0 saved the location of the return address(at) by -mmcount-ra-address */
+ PTR_S MCOUNT_RA_ADDRESS_REG, PT_R12(sp)
#endif
- move a0, ra /* arg1: next ip, selfaddr */
+ move a0, ra /* arg1: self return address */
.globl ftrace_call
ftrace_call:
nop /* a placeholder for the call to a real tracing function */
- move a1, AT /* arg2: the caller's next ip, parent */
+ move a1, AT /* arg2: parent's return address */
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
.globl ftrace_graph_call
@@ -119,9 +124,9 @@ NESTED(_mcount, PT_SIZE, ra)
static_trace:
MCOUNT_SAVE_REGS
- move a0, ra /* arg1: next ip, selfaddr */
+ move a0, ra /* arg1: self return address */
jalr t2 /* (1) call *ftrace_trace_function */
- move a1, AT /* arg2: the caller's next ip, parent */
+ move a1, AT /* arg2: parent's return address */
MCOUNT_RESTORE_REGS
.globl ftrace_stub
@@ -134,28 +139,34 @@ ftrace_stub:
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
NESTED(ftrace_graph_caller, PT_SIZE, ra)
-#ifdef CONFIG_DYNAMIC_FTRACE
- PTR_L a1, PT_R31(sp) /* load the original ra from the stack */
-#ifdef KBUILD_MCOUNT_RA_ADDRESS
- PTR_L t0, PT_R12(sp) /* load the original t0 from the stack */
-#endif
-#else
+#ifndef CONFIG_DYNAMIC_FTRACE
MCOUNT_SAVE_REGS
- move a1, ra /* arg2: next ip, selfaddr */
#endif
+ /* arg1: Get the location of the parent's return address */
#ifdef KBUILD_MCOUNT_RA_ADDRESS
- bnez t0, 1f /* non-leaf func: t0 saved the location of the return address */
+#ifdef CONFIG_DYNAMIC_FTRACE
+ PTR_L a0, PT_R12(sp)
+#else
+ move a0, MCOUNT_RA_ADDRESS_REG
+#endif
+ bnez a0, 1f /* non-leaf func: stored in MCOUNT_RA_ADDRESS_REG */
nop
- PTR_LA t0, PT_R1(sp) /* leaf func: get the location of at(old ra) from our own stack */
-1: move a0, t0 /* arg1: the location of the return address */
+#endif
+ PTR_LA a0, PT_R1(sp) /* leaf func: the location in current stack */
+1:
+
+ /* arg2: Get self return address */
+#ifdef CONFIG_DYNAMIC_FTRACE
+ PTR_L a1, PT_R31(sp)
#else
- PTR_LA a0, PT_R1(sp) /* arg1: &AT -> a0 */
+ move a1, ra
#endif
- jal prepare_ftrace_return
+
+ /* arg3: Get frame pointer of current stack */
#ifdef CONFIG_FRAME_POINTER
- move a2, fp /* arg3: frame pointer */
-#else
+ move a2, fp
+#else /* ! CONFIG_FRAME_POINTER */
#ifdef CONFIG_64BIT
PTR_LA a2, PT_SIZE(sp)
#else
@@ -163,6 +174,8 @@ NESTED(ftrace_graph_caller, PT_SIZE, ra)
#endif
#endif
+ jal prepare_ftrace_return
+ nop
MCOUNT_RESTORE_REGS
RETURN_BACK
END(ftrace_graph_caller)
diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c
index f5981c499109..2340f11dc29c 100644
--- a/arch/mips/kernel/mips-mt-fpaff.c
+++ b/arch/mips/kernel/mips-mt-fpaff.c
@@ -3,6 +3,7 @@
* Copyright (C) 2005 Mips Technologies, Inc
*/
#include <linux/cpu.h>
+#include <linux/cpuset.h>
#include <linux/cpumask.h>
#include <linux/delay.h>
#include <linux/kernel.h>
@@ -39,6 +40,21 @@ static inline struct task_struct *find_process_by_pid(pid_t pid)
return pid ? find_task_by_vpid(pid) : current;
}
+/*
+ * check the target process has a UID that matches the current process's
+ */
+static bool check_same_owner(struct task_struct *p)
+{
+ const struct cred *cred = current_cred(), *pcred;
+ bool match;
+
+ rcu_read_lock();
+ pcred = __task_cred(p);
+ match = (cred->euid == pcred->euid ||
+ cred->euid == pcred->uid);
+ rcu_read_unlock();
+ return match;
+}
/*
* mipsmt_sys_sched_setaffinity - set the cpu affinity of a process
@@ -46,12 +62,10 @@ static inline struct task_struct *find_process_by_pid(pid_t pid)
asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,
unsigned long __user *user_mask_ptr)
{
- cpumask_t new_mask;
- cpumask_t effective_mask;
- int retval;
- struct task_struct *p;
+ cpumask_var_t cpus_allowed, new_mask, effective_mask;
struct thread_info *ti;
- uid_t euid;
+ struct task_struct *p;
+ int retval;
if (len < sizeof(new_mask))
return -EINVAL;
@@ -60,53 +74,74 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,
return -EFAULT;
get_online_cpus();
- read_lock(&tasklist_lock);
+ rcu_read_lock();
p = find_process_by_pid(pid);
if (!p) {
- read_unlock(&tasklist_lock);
+ rcu_read_unlock();
put_online_cpus();
return -ESRCH;
}
- /*
- * It is not safe to call set_cpus_allowed with the
- * tasklist_lock held. We will bump the task_struct's
- * usage count and drop tasklist_lock before invoking
- * set_cpus_allowed.
- */
+ /* Prevent p going away */
get_task_struct(p);
+ rcu_read_unlock();
- euid = current_euid();
+ if (!alloc_cpumask_var(&cpus_allowed, GFP_KERNEL)) {
+ retval = -ENOMEM;
+ goto out_put_task;
+ }
+ if (!alloc_cpumask_var(&new_mask, GFP_KERNEL)) {
+ retval = -ENOMEM;
+ goto out_free_cpus_allowed;
+ }
+ if (!alloc_cpumask_var(&effective_mask, GFP_KERNEL)) {
+ retval = -ENOMEM;
+ goto out_free_new_mask;
+ }
retval = -EPERM;
- if (euid != p->cred->euid && euid != p->cred->uid &&
- !capable(CAP_SYS_NICE)) {
- read_unlock(&tasklist_lock);
+ if (!check_same_owner(p) && !capable(CAP_SYS_NICE))
goto out_unlock;
- }
retval = security_task_setscheduler(p, 0, NULL);
if (retval)
goto out_unlock;
/* Record new user-specified CPU set for future reference */
- p->thread.user_cpus_allowed = new_mask;
-
- /* Unlock the task list */
- read_unlock(&tasklist_lock);
+ cpumask_copy(&p->thread.user_cpus_allowed, new_mask);
+ again:
/* Compute new global allowed CPU set if necessary */
ti = task_thread_info(p);
if (test_ti_thread_flag(ti, TIF_FPUBOUND) &&
- cpus_intersects(new_mask, mt_fpu_cpumask)) {
- cpus_and(effective_mask, new_mask, mt_fpu_cpumask);
- retval = set_cpus_allowed_ptr(p, &effective_mask);
+ cpus_intersects(*new_mask, mt_fpu_cpumask)) {
+ cpus_and(*effective_mask, *new_mask, mt_fpu_cpumask);
+ retval = set_cpus_allowed_ptr(p, effective_mask);
} else {
+ cpumask_copy(effective_mask, new_mask);
clear_ti_thread_flag(ti, TIF_FPUBOUND);
- retval = set_cpus_allowed_ptr(p, &new_mask);
+ retval = set_cpus_allowed_ptr(p, new_mask);
}
+ if (!retval) {
+ cpuset_cpus_allowed(p, cpus_allowed);
+ if (!cpumask_subset(effective_mask, cpus_allowed)) {
+ /*
+ * We must have raced with a concurrent cpuset
+ * update. Just reset the cpus_allowed to the
+ * cpuset's cpus_allowed
+ */
+ cpumask_copy(new_mask, cpus_allowed);
+ goto again;
+ }
+ }
out_unlock:
+ free_cpumask_var(effective_mask);
+out_free_new_mask:
+ free_cpumask_var(new_mask);
+out_free_cpus_allowed:
+ free_cpumask_var(cpus_allowed);
+out_put_task:
put_task_struct(p);
put_online_cpus();
return retval;
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 8bdd6a663c7f..852780868fb4 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -976,7 +976,7 @@ asmlinkage void do_cpu(struct pt_regs *regs)
case 2:
raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs);
- break;
+ return;
case 3:
break;
diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig
index 3df1967dea08..c97ca69b94e0 100644
--- a/arch/mips/loongson/Kconfig
+++ b/arch/mips/loongson/Kconfig
@@ -23,6 +23,7 @@ config LEMOTE_FULOONG2E
select GENERIC_HARDIRQS_NO__DO_IRQ
select GENERIC_ISA_DMA_SUPPORT_BROKEN
select CPU_HAS_WB
+ select LOONGSON_MC146818
help
Lemote Fuloong(2e) mini-PC board based on the Chinese Loongson-2E CPU and
an FPGA northbridge
@@ -51,6 +52,7 @@ config LEMOTE_MACH2F
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_HIGHMEM
select SYS_SUPPORTS_LITTLE_ENDIAN
+ select LOONGSON_MC146818
help
Lemote Loongson 2F family machines utilize the 2F revision of
Loongson processor and the AMD CS5536 south bridge.
@@ -83,3 +85,7 @@ config LOONGSON_UART_BASE
bool
default y
depends on EARLY_PRINTK || SERIAL_8250
+
+config LOONGSON_MC146818
+ bool
+ default n
diff --git a/arch/mips/loongson/common/Makefile b/arch/mips/loongson/common/Makefile
index cdd2e812ba1a..e526488df655 100644
--- a/arch/mips/loongson/common/Makefile
+++ b/arch/mips/loongson/common/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_GENERIC_GPIO) += gpio.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_SERIAL_8250) += serial.o
obj-$(CONFIG_LOONGSON_UART_BASE) += uart_base.o
+obj-$(CONFIG_LOONGSON_MC146818) += rtc.o
#
# Enable CS5536 Virtual Support Module(VSM) to virtulize the PCI configure
diff --git a/arch/mips/loongson/common/cs5536/cs5536_ehci.c b/arch/mips/loongson/common/cs5536/cs5536_ehci.c
index eaf8b86e3318..5b5cbba699b3 100644
--- a/arch/mips/loongson/common/cs5536/cs5536_ehci.c
+++ b/arch/mips/loongson/common/cs5536/cs5536_ehci.c
@@ -49,6 +49,8 @@ void pci_ehci_write_reg(int reg, u32 value)
lo |= SOFT_BAR_EHCI_FLAG;
_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
} else if ((value & 0x01) == 0x00) {
+ _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+ lo = value;
_wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
value &= 0xfffffff0;
diff --git a/arch/mips/loongson/common/cs5536/cs5536_ide.c b/arch/mips/loongson/common/cs5536/cs5536_ide.c
index 9a96b5664c78..681d1291a2c7 100644
--- a/arch/mips/loongson/common/cs5536/cs5536_ide.c
+++ b/arch/mips/loongson/common/cs5536/cs5536_ide.c
@@ -51,6 +51,7 @@ void pci_ide_write_reg(int reg, u32 value)
lo |= SOFT_BAR_IDE_FLAG;
_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
} else if (value & 0x01) {
+ _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
lo = (value & 0xfffffff0) | 0x1;
_wrmsr(IDE_MSR_REG(IDE_IO_BAR), hi, lo);
@@ -65,19 +66,30 @@ void pci_ide_write_reg(int reg, u32 value)
_rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo);
lo |= 0x01;
_wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo);
- } else
+ } else {
+ _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo);
+ lo = value;
_wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo);
+ }
break;
case PCI_IDE_DTC_REG:
+ _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo);
+ lo = value;
_wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo);
break;
case PCI_IDE_CAST_REG:
+ _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo);
+ lo = value;
_wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo);
break;
case PCI_IDE_ETC_REG:
+ _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo);
+ lo = value;
_wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo);
break;
case PCI_IDE_PM_REG:
+ _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo);
+ lo = value;
_wrmsr(IDE_MSR_REG(IDE_INTERNAL_PM), hi, lo);
break;
default:
@@ -167,6 +179,7 @@ u32 pci_ide_read_reg(int reg)
case PCI_IDE_ETC_REG:
_rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo);
conf_data = lo;
+ break;
case PCI_IDE_PM_REG:
_rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo);
conf_data = lo;
diff --git a/arch/mips/loongson/common/cs5536/cs5536_isa.c b/arch/mips/loongson/common/cs5536/cs5536_isa.c
index f5c0818831b2..4d9f65abeaff 100644
--- a/arch/mips/loongson/common/cs5536/cs5536_isa.c
+++ b/arch/mips/loongson/common/cs5536/cs5536_isa.c
@@ -61,7 +61,7 @@ static void divil_lbar_enable(void)
for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) {
_rdmsr(DIVIL_MSR_REG(offset), &hi, &lo);
hi |= 0x01;
- _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), hi, lo);
+ _wrmsr(DIVIL_MSR_REG(offset), hi, lo);
}
}
@@ -76,7 +76,7 @@ static void divil_lbar_disable(void)
for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) {
_rdmsr(DIVIL_MSR_REG(offset), &hi, &lo);
hi &= ~0x01;
- _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), hi, lo);
+ _wrmsr(DIVIL_MSR_REG(offset), hi, lo);
}
}
diff --git a/arch/mips/loongson/common/cs5536/cs5536_ohci.c b/arch/mips/loongson/common/cs5536/cs5536_ohci.c
index db5900aadd6b..bdedf512baf7 100644
--- a/arch/mips/loongson/common/cs5536/cs5536_ohci.c
+++ b/arch/mips/loongson/common/cs5536/cs5536_ohci.c
@@ -49,6 +49,8 @@ void pci_ohci_write_reg(int reg, u32 value)
lo |= SOFT_BAR_OHCI_FLAG;
_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
} else if ((value & 0x01) == 0x00) {
+ _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
+ lo = value;
_wrmsr(USB_MSR_REG(USB_OHCI), hi, lo);
value &= 0xfffffff0;
diff --git a/arch/mips/loongson/common/rtc.c b/arch/mips/loongson/common/rtc.c
new file mode 100644
index 000000000000..a90d87c01555
--- /dev/null
+++ b/arch/mips/loongson/common/rtc.c
@@ -0,0 +1,43 @@
+/*
+ * Lemote Fuloong platform support
+ *
+ * Copyright(c) 2010 Arnaud Patard <apatard@mandriva.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/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mc146818rtc.h>
+
+struct resource loongson_rtc_resources[] = {
+ {
+ .start = RTC_PORT(0),
+ .end = RTC_PORT(1),
+ .flags = IORESOURCE_IO,
+ }, {
+ .start = RTC_IRQ,
+ .end = RTC_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device loongson_rtc_device = {
+ .name = "rtc_cmos",
+ .id = -1,
+ .resource = loongson_rtc_resources,
+ .num_resources = ARRAY_SIZE(loongson_rtc_resources),
+};
+
+
+static int __init loongson_rtc_platform_init(void)
+{
+ platform_device_register(&loongson_rtc_device);
+ return 0;
+}
+
+device_initcall(loongson_rtc_platform_init);
diff --git a/arch/mips/math-emu/dp_simple.c b/arch/mips/math-emu/dp_simple.c
index d9ae1dbabda7..b90974246e5b 100644
--- a/arch/mips/math-emu/dp_simple.c
+++ b/arch/mips/math-emu/dp_simple.c
@@ -78,6 +78,7 @@ ieee754dp ieee754dp_abs(ieee754dp x)
DPSIGN(x) = 0;
if (xc == IEEE754_CLASS_SNAN) {
+ SETCX(IEEE754_INVALID_OPERATION);
return ieee754dp_nanxcpt(ieee754dp_indef(), "abs");
}
diff --git a/arch/mips/math-emu/sp_simple.c b/arch/mips/math-emu/sp_simple.c
index 3175477d36f6..2fd53c920e99 100644
--- a/arch/mips/math-emu/sp_simple.c
+++ b/arch/mips/math-emu/sp_simple.c
@@ -78,6 +78,7 @@ ieee754sp ieee754sp_abs(ieee754sp x)
SPSIGN(x) = 0;
if (xc == IEEE754_CLASS_SNAN) {
+ SETCX(IEEE754_INVALID_OPERATION);
return ieee754sp_nanxcpt(ieee754sp_indef(), "abs");
}
diff --git a/arch/mips/oprofile/op_model_loongson2.c b/arch/mips/oprofile/op_model_loongson2.c
index d0d24e047676..60d3ea602118 100644
--- a/arch/mips/oprofile/op_model_loongson2.c
+++ b/arch/mips/oprofile/op_model_loongson2.c
@@ -43,6 +43,12 @@ static struct loongson2_register_config {
static char *oprofid = "LoongsonPerf";
static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id);
+static void reset_counters(void *arg)
+{
+ write_c0_perfctrl(0);
+ write_c0_perfcnt(0);
+}
+
static void loongson2_reg_setup(struct op_counter_config *cfg)
{
unsigned int ctrl = 0;
@@ -139,7 +145,7 @@ static int __init loongson2_init(void)
static void loongson2_exit(void)
{
- write_c0_perfctrl(0);
+ reset_counters(NULL);
free_irq(LOONGSON2_PERFCNT_IRQ, oprofid);
}
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 328774bd41ee..6506bf4fbff1 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -400,7 +400,7 @@ config IRQ_ALL_CPUS
config SPARSE_IRQ
bool "Support sparse irq numbering"
- default y
+ default n
help
This enables support for sparse irqs. This is useful for distro
kernels that want to define a high CONFIG_NR_CPUS value but still
@@ -409,7 +409,7 @@ config SPARSE_IRQ
( Sparse IRQs can also be beneficial on NUMA boxes, as they spread
out the irq_desc[] array in a more NUMA-friendly way. )
- If you don't know what to do here, say Y.
+ If you don't know what to do here, say N.
config NUMA
bool "NUMA support"
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 42dcd3f4ad7b..77cfe7a29e25 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -92,10 +92,10 @@ endif
else
KBUILD_CFLAGS += $(call cc-option,-mtune=power4)
endif
-else
-LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o
endif
+LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o
+
ifeq ($(CONFIG_TUNE_CELL),y)
KBUILD_CFLAGS += $(call cc-option,-mtune=cell)
endif
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
index 5d8be0416227..0175a676b34b 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -24,11 +24,7 @@
* 2 of the License, or (at your option) any later version.
*/
-#ifdef __KERNEL__
#include <linux/types.h>
-#else
-#include <stdint.h>
-#endif
#ifndef __ASSEMBLY__
@@ -364,13 +360,13 @@ static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
#ifndef __ASSEMBLY__
struct ppc_debug_info {
- uint32_t version; /* Only version 1 exists to date */
- uint32_t num_instruction_bps;
- uint32_t num_data_bps;
- uint32_t num_condition_regs;
- uint32_t data_bp_alignment;
- uint32_t sizeof_condition; /* size of the DVC register */
- uint64_t features;
+ __u32 version; /* Only version 1 exists to date */
+ __u32 num_instruction_bps;
+ __u32 num_data_bps;
+ __u32 num_condition_regs;
+ __u32 data_bp_alignment;
+ __u32 sizeof_condition; /* size of the DVC register */
+ __u64 features;
};
#endif /* __ASSEMBLY__ */
@@ -386,13 +382,13 @@ struct ppc_debug_info {
#ifndef __ASSEMBLY__
struct ppc_hw_breakpoint {
- uint32_t version; /* currently, version must be 1 */
- uint32_t trigger_type; /* only some combinations allowed */
- uint32_t addr_mode; /* address match mode */
- uint32_t condition_mode; /* break/watchpoint condition flags */
- uint64_t addr; /* break/watchpoint address */
- uint64_t addr2; /* range end or mask */
- uint64_t condition_value; /* contents of the DVC register */
+ __u32 version; /* currently, version must be 1 */
+ __u32 trigger_type; /* only some combinations allowed */
+ __u32 addr_mode; /* address match mode */
+ __u32 condition_mode; /* break/watchpoint condition flags */
+ __u64 addr; /* break/watchpoint address */
+ __u64 addr2; /* range end or mask */
+ __u64 condition_value; /* contents of the DVC register */
};
#endif /* __ASSEMBLY__ */
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c
index b46f2e09bd81..29df48f2b61a 100644
--- a/arch/powerpc/kernel/crash.c
+++ b/arch/powerpc/kernel/crash.c
@@ -447,7 +447,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
crash_kexec_prepare_cpus(crashing_cpu);
cpu_set(crashing_cpu, cpus_in_crash);
crash_kexec_stop_spus();
-#ifdef CONFIG_PPC_STD_MMU_64
+#if defined(CONFIG_PPC_STD_MMU_64) && defined(CONFIG_SMP)
crash_kexec_wait_realmode(crashing_cpu);
#endif
if (ppc_md.kexec_cpu_down)
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 3333bbdd23ef..77be3d058a65 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -295,7 +295,10 @@ void fixup_irqs(const struct cpumask *map)
for_each_irq(irq) {
desc = irq_to_desc(irq);
- if (desc && desc->status & IRQ_PER_CPU)
+ if (!desc)
+ continue;
+
+ if (desc->status & IRQ_PER_CPU)
continue;
cpumask_and(mask, desc->affinity, map);
diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c
index 43b83c35cf54..5c14ffe51258 100644
--- a/arch/powerpc/kernel/perf_event.c
+++ b/arch/powerpc/kernel/perf_event.c
@@ -791,8 +791,11 @@ static void power_pmu_disable(struct perf_event *event)
cpuhw = &__get_cpu_var(cpu_hw_events);
for (i = 0; i < cpuhw->n_events; ++i) {
if (event == cpuhw->event[i]) {
- while (++i < cpuhw->n_events)
+ while (++i < cpuhw->n_events) {
cpuhw->event[i-1] = cpuhw->event[i];
+ cpuhw->events[i-1] = cpuhw->events[i];
+ cpuhw->flags[i-1] = cpuhw->flags[i];
+ }
--cpuhw->n_events;
ppmu->disable_pmc(event->hw.idx - 1, cpuhw->mmcr);
if (event->hw.idx) {
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 97d4bd9442d3..3b6f8ae9b8cc 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -872,7 +872,7 @@ static void __init prom_send_capabilities(void)
"ibm_architecture_vec structure inconsistent: 0x%x !\n",
*cores);
} else {
- *cores = NR_CPUS / prom_count_smt_threads();
+ *cores = DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads());
prom_printf("Max number of cores passed to firmware: 0x%x\n",
(unsigned long)*cores);
}
diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh
index 1ac136b128f0..9f82f4937892 100644
--- a/arch/powerpc/kernel/prom_init_check.sh
+++ b/arch/powerpc/kernel/prom_init_check.sh
@@ -52,12 +52,18 @@ do
if [ "${UNDEF:0:9}" = "_restgpr_" ]; then
OK=1
fi
+ if [ "${UNDEF:0:10}" = "_restgpr0_" ]; then
+ OK=1
+ fi
if [ "${UNDEF:0:11}" = "_rest32gpr_" ]; then
OK=1
fi
if [ "${UNDEF:0:9}" = "_savegpr_" ]; then
OK=1
fi
+ if [ "${UNDEF:0:10}" = "_savegpr0_" ]; then
+ OK=1
+ fi
if [ "${UNDEF:0:11}" = "_save32gpr_" ]; then
OK=1
fi
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 3040dac18a37..111da1c03a11 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -12,8 +12,8 @@ CFLAGS_REMOVE_code-patching.o = -pg
CFLAGS_REMOVE_feature-fixups.o = -pg
obj-y := string.o alloc.o \
- checksum_$(CONFIG_WORD_SIZE).o
-obj-$(CONFIG_PPC32) += div64.o copy_32.o crtsavres.o
+ checksum_$(CONFIG_WORD_SIZE).o crtsavres.o
+obj-$(CONFIG_PPC32) += div64.o copy_32.o
obj-$(CONFIG_HAS_IOMEM) += devres.o
obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o \
diff --git a/arch/powerpc/lib/crtsavres.S b/arch/powerpc/lib/crtsavres.S
index 70a9cd8a3008..1c893f05d224 100644
--- a/arch/powerpc/lib/crtsavres.S
+++ b/arch/powerpc/lib/crtsavres.S
@@ -6,6 +6,7 @@
* Written By Michael Meissner
*
* Based on gcc/config/rs6000/crtsavres.asm from gcc
+ * 64 bit additions from reading the PPC elf64abi document.
*
* This file is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -44,6 +45,8 @@
#ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
+#ifndef CONFIG_PPC64
+
/* Routines for saving integer registers, called by the compiler. */
/* Called with r11 pointing to the stack header word of the caller of the */
/* function, just beyond the end of the integer save area. */
@@ -226,4 +229,130 @@ _GLOBAL(_rest32gpr_31_x)
mtlr 0
mr 1,11
blr
+
+#else /* CONFIG_PPC64 */
+
+.globl _savegpr0_14
+_savegpr0_14:
+ std r14,-144(r1)
+.globl _savegpr0_15
+_savegpr0_15:
+ std r15,-136(r1)
+.globl _savegpr0_16
+_savegpr0_16:
+ std r16,-128(r1)
+.globl _savegpr0_17
+_savegpr0_17:
+ std r17,-120(r1)
+.globl _savegpr0_18
+_savegpr0_18:
+ std r18,-112(r1)
+.globl _savegpr0_19
+_savegpr0_19:
+ std r19,-104(r1)
+.globl _savegpr0_20
+_savegpr0_20:
+ std r20,-96(r1)
+.globl _savegpr0_21
+_savegpr0_21:
+ std r21,-88(r1)
+.globl _savegpr0_22
+_savegpr0_22:
+ std r22,-80(r1)
+.globl _savegpr0_23
+_savegpr0_23:
+ std r23,-72(r1)
+.globl _savegpr0_24
+_savegpr0_24:
+ std r24,-64(r1)
+.globl _savegpr0_25
+_savegpr0_25:
+ std r25,-56(r1)
+.globl _savegpr0_26
+_savegpr0_26:
+ std r26,-48(r1)
+.globl _savegpr0_27
+_savegpr0_27:
+ std r27,-40(r1)
+.globl _savegpr0_28
+_savegpr0_28:
+ std r28,-32(r1)
+.globl _savegpr0_29
+_savegpr0_29:
+ std r29,-24(r1)
+.globl _savegpr0_30
+_savegpr0_30:
+ std r30,-16(r1)
+.globl _savegpr0_31
+_savegpr0_31:
+ std r31,-8(r1)
+ std r0,16(r1)
+ blr
+
+.globl _restgpr0_14
+_restgpr0_14:
+ ld r14,-144(r1)
+.globl _restgpr0_15
+_restgpr0_15:
+ ld r15,-136(r1)
+.globl _restgpr0_16
+_restgpr0_16:
+ ld r16,-128(r1)
+.globl _restgpr0_17
+_restgpr0_17:
+ ld r17,-120(r1)
+.globl _restgpr0_18
+_restgpr0_18:
+ ld r18,-112(r1)
+.globl _restgpr0_19
+_restgpr0_19:
+ ld r19,-104(r1)
+.globl _restgpr0_20
+_restgpr0_20:
+ ld r20,-96(r1)
+.globl _restgpr0_21
+_restgpr0_21:
+ ld r21,-88(r1)
+.globl _restgpr0_22
+_restgpr0_22:
+ ld r22,-80(r1)
+.globl _restgpr0_23
+_restgpr0_23:
+ ld r23,-72(r1)
+.globl _restgpr0_24
+_restgpr0_24:
+ ld r24,-64(r1)
+.globl _restgpr0_25
+_restgpr0_25:
+ ld r25,-56(r1)
+.globl _restgpr0_26
+_restgpr0_26:
+ ld r26,-48(r1)
+.globl _restgpr0_27
+_restgpr0_27:
+ ld r27,-40(r1)
+.globl _restgpr0_28
+_restgpr0_28:
+ ld r28,-32(r1)
+.globl _restgpr0_29
+_restgpr0_29:
+ ld r0,16(r1)
+ ld r29,-24(r1)
+ mtlr r0
+ ld r30,-16(r1)
+ ld r31,-8(r1)
+ blr
+
+.globl _restgpr0_30
+_restgpr0_30:
+ ld r30,-16(r1)
+.globl _restgpr0_31
+_restgpr0_31:
+ ld r0,16(r1)
+ ld r31,-8(r1)
+ mtlr r0
+ blr
+
+#endif /* CONFIG_PPC64 */
+
#endif
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c
index e640175b65ae..0d08d0171392 100644
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -12,6 +12,7 @@
* 2 of the License, or (at your option) any later version.
*/
+#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/init.h>
@@ -288,8 +289,8 @@ static void test_alternative_case_with_external_branch(void)
static void test_cpu_macros(void)
{
- extern void ftr_fixup_test_FTR_macros;
- extern void ftr_fixup_test_FTR_macros_expected;
+ extern u8 ftr_fixup_test_FTR_macros;
+ extern u8 ftr_fixup_test_FTR_macros_expected;
unsigned long size = &ftr_fixup_test_FTR_macros_expected -
&ftr_fixup_test_FTR_macros;
@@ -301,8 +302,8 @@ static void test_cpu_macros(void)
static void test_fw_macros(void)
{
#ifdef CONFIG_PPC64
- extern void ftr_fixup_test_FW_FTR_macros;
- extern void ftr_fixup_test_FW_FTR_macros_expected;
+ extern u8 ftr_fixup_test_FW_FTR_macros;
+ extern u8 ftr_fixup_test_FW_FTR_macros_expected;
unsigned long size = &ftr_fixup_test_FW_FTR_macros_expected -
&ftr_fixup_test_FW_FTR_macros;
@@ -314,10 +315,10 @@ static void test_fw_macros(void)
static void test_lwsync_macros(void)
{
- extern void lwsync_fixup_test;
- extern void end_lwsync_fixup_test;
- extern void lwsync_fixup_test_expected_LWSYNC;
- extern void lwsync_fixup_test_expected_SYNC;
+ extern u8 lwsync_fixup_test;
+ extern u8 end_lwsync_fixup_test;
+ extern u8 lwsync_fixup_test_expected_LWSYNC;
+ extern u8 lwsync_fixup_test_expected_SYNC;
unsigned long size = &end_lwsync_fixup_test -
&lwsync_fixup_test;
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index 3fc2e6494b8b..ab3962b0d246 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -445,7 +445,11 @@ void __init iSeries_pcibios_fixup_resources(struct pci_dev *pdev)
}
allocate_device_bars(pdev);
- iseries_device_information(pdev, bus, *sub_bus);
+ if (likely(sub_bus))
+ iseries_device_information(pdev, bus, *sub_bus);
+ else
+ printk(KERN_ERR "PCI: Device node %s has missing or invalid "
+ "linux,subbus property\n", node->full_name);
}
/*
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
index 93a11d7edfa0..e696144d2be3 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -10,6 +10,7 @@
#include <errno.h>
#include <fcntl.h>
#include <string.h>
+#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/param.h>
#include "init.h"
diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c
index 611df11ba15e..c2897b7b4a3b 100644
--- a/arch/x86/kernel/cpu/perf_event_amd.c
+++ b/arch/x86/kernel/cpu/perf_event_amd.c
@@ -102,8 +102,8 @@ static const u64 amd_perfmon_event_map[] =
[PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0,
[PERF_COUNT_HW_CACHE_REFERENCES] = 0x0080,
[PERF_COUNT_HW_CACHE_MISSES] = 0x0081,
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4,
- [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c2,
+ [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c3,
};
static u64 amd_pmu_event_map(int hw_event)
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 0b96b5589f08..078d4ec1a9d9 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -110,7 +110,7 @@ int use_calgary __read_mostly = 0;
* x3950 (PCIE): 8 chassis, 32 PHBs per chassis = 256
* x3950 (PCIX): 8 chassis, 16 PHBs per chassis = 128
*/
-#define MAX_PHB_BUS_NUM 384
+#define MAX_PHB_BUS_NUM 256
#define PHBS_PER_CALGARY 4
@@ -1056,8 +1056,6 @@ static int __init calgary_init_one(struct pci_dev *dev)
struct iommu_table *tbl;
int ret;
- BUG_ON(dev->bus->number >= MAX_PHB_BUS_NUM);
-
bbar = busno_to_bbar(dev->bus->number);
ret = calgary_setup_tar(dev, bbar);
if (ret)
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 142d70c74b02..725ef4d17cd5 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -526,6 +526,7 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
{
struct task_struct *tsk = current;
+ int user_icebp = 0;
unsigned long dr6;
int si_code;
@@ -534,6 +535,14 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
/* Filter out all the reserved bits which are preset to 1 */
dr6 &= ~DR6_RESERVED;
+ /*
+ * If dr6 has no reason to give us about the origin of this trap,
+ * then it's very likely the result of an icebp/int01 trap.
+ * User wants a sigtrap for that.
+ */
+ if (!dr6 && user_mode(regs))
+ user_icebp = 1;
+
/* Catch kmemcheck conditions first of all! */
if ((dr6 & DR_STEP) && kmemcheck_trap(regs))
return;
@@ -575,7 +584,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
regs->flags &= ~X86_EFLAGS_TF;
}
si_code = get_si_code(tsk->thread.debugreg6);
- if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS))
+ if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS) || user_icebp)
send_sigtrap(tsk, regs, error_code, si_code);
preempt_conditional_cli(regs);
diff --git a/arch/x86/mm/pat_rbtree.c b/arch/x86/mm/pat_rbtree.c
index f20eeec85a86..8acaddd0fb21 100644
--- a/arch/x86/mm/pat_rbtree.c
+++ b/arch/x86/mm/pat_rbtree.c
@@ -34,8 +34,7 @@
* memtype_lock protects the rbtree.
*/
-static void memtype_rb_augment_cb(struct rb_node *node);
-static struct rb_root memtype_rbroot = RB_AUGMENT_ROOT(&memtype_rb_augment_cb);
+static struct rb_root memtype_rbroot = RB_ROOT;
static int is_node_overlap(struct memtype *node, u64 start, u64 end)
{
@@ -56,7 +55,7 @@ static u64 get_subtree_max_end(struct rb_node *node)
}
/* Update 'subtree_max_end' for a node, based on node and its children */
-static void update_node_max_end(struct rb_node *node)
+static void memtype_rb_augment_cb(struct rb_node *node, void *__unused)
{
struct memtype *data;
u64 max_end, child_max_end;
@@ -78,25 +77,6 @@ static void update_node_max_end(struct rb_node *node)
data->subtree_max_end = max_end;
}
-/* Update 'subtree_max_end' for a node and all its ancestors */
-static void update_path_max_end(struct rb_node *node)
-{
- u64 old_max_end, new_max_end;
-
- while (node) {
- struct memtype *data = container_of(node, struct memtype, rb);
-
- old_max_end = data->subtree_max_end;
- update_node_max_end(node);
- new_max_end = data->subtree_max_end;
-
- if (new_max_end == old_max_end)
- break;
-
- node = rb_parent(node);
- }
-}
-
/* Find the first (lowest start addr) overlapping range from rb tree */
static struct memtype *memtype_rb_lowest_match(struct rb_root *root,
u64 start, u64 end)
@@ -190,12 +170,6 @@ failure:
return -EBUSY;
}
-static void memtype_rb_augment_cb(struct rb_node *node)
-{
- if (node)
- update_path_max_end(node);
-}
-
static void memtype_rb_insert(struct rb_root *root, struct memtype *newdata)
{
struct rb_node **node = &(root->rb_node);
@@ -213,6 +187,7 @@ static void memtype_rb_insert(struct rb_root *root, struct memtype *newdata)
rb_link_node(&newdata->rb, parent, node);
rb_insert_color(&newdata->rb, root);
+ rb_augment_insert(&newdata->rb, memtype_rb_augment_cb, NULL);
}
int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type)
@@ -234,13 +209,16 @@ int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type)
struct memtype *rbt_memtype_erase(u64 start, u64 end)
{
+ struct rb_node *deepest;
struct memtype *data;
data = memtype_rb_exact_match(&memtype_rbroot, start, end);
if (!data)
goto out;
+ deepest = rb_augment_erase_begin(&data->rb);
rb_erase(&data->rb, &memtype_rbroot);
+ rb_augment_erase_end(deepest, memtype_rb_augment_cb, NULL);
out:
return data;
}