Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc:
powerpc: TIF_ABI_PENDING bit removal
powerpc/pseries: Fix xics build without CONFIG_SMP
powerpc/4xx: Add pcix type 1 transactions
powerpc/pci: Add missing call to header fixup
powerpc/pci: Add missing hookup to pci_slot
powerpc/pci: Add calls to set_pcie_port_type() and set_pcie_hotplug_bridge()
powerpc/40x: Update the PowerPC 40x board defconfigs
powerpc/44x: Update PowerPC 44x board defconfigs
diff --git a/Documentation/input/multi-touch-protocol.txt b/Documentation/input/multi-touch-protocol.txt
index a12ea3b..8490480 100644
--- a/Documentation/input/multi-touch-protocol.txt
+++ b/Documentation/input/multi-touch-protocol.txt
@@ -27,12 +27,30 @@
A set of ABS_MT events with the desired properties is defined. The events
are divided into categories, to allow for partial implementation. The
-minimum set consists of ABS_MT_TOUCH_MAJOR, ABS_MT_POSITION_X and
-ABS_MT_POSITION_Y, which allows for multiple fingers to be tracked. If the
-device supports it, the ABS_MT_WIDTH_MAJOR may be used to provide the size
-of the approaching finger. Anisotropy and direction may be specified with
-ABS_MT_TOUCH_MINOR, ABS_MT_WIDTH_MINOR and ABS_MT_ORIENTATION. The
-ABS_MT_TOOL_TYPE may be used to specify whether the touching tool is a
+minimum set consists of ABS_MT_POSITION_X and ABS_MT_POSITION_Y, which
+allows for multiple fingers to be tracked. If the device supports it, the
+ABS_MT_TOUCH_MAJOR and ABS_MT_WIDTH_MAJOR may be used to provide the size
+of the contact area and approaching finger, respectively.
+
+The TOUCH and WIDTH parameters have a geometrical interpretation; imagine
+looking through a window at someone gently holding a finger against the
+glass. You will see two regions, one inner region consisting of the part
+of the finger actually touching the glass, and one outer region formed by
+the perimeter of the finger. The diameter of the inner region is the
+ABS_MT_TOUCH_MAJOR, the diameter of the outer region is
+ABS_MT_WIDTH_MAJOR. Now imagine the person pressing the finger harder
+against the glass. The inner region will increase, and in general, the
+ratio ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR, which is always smaller than
+unity, is related to the finger pressure. For pressure-based devices,
+ABS_MT_PRESSURE may be used to provide the pressure on the contact area
+instead.
+
+In addition to the MAJOR parameters, the oval shape of the finger can be
+described by adding the MINOR parameters, such that MAJOR and MINOR are the
+major and minor axis of an ellipse. Finally, the orientation of the oval
+shape can be describe with the ORIENTATION parameter.
+
+The ABS_MT_TOOL_TYPE may be used to specify whether the touching tool is a
finger or a pen or something else. Devices with more granular information
may specify general shapes as blobs, i.e., as a sequence of rectangular
shapes grouped together by an ABS_MT_BLOB_ID. Finally, for the few devices
@@ -42,11 +60,9 @@
Here is what a minimal event sequence for a two-finger touch would look
like:
- ABS_MT_TOUCH_MAJOR
ABS_MT_POSITION_X
ABS_MT_POSITION_Y
SYN_MT_REPORT
- ABS_MT_TOUCH_MAJOR
ABS_MT_POSITION_X
ABS_MT_POSITION_Y
SYN_MT_REPORT
@@ -87,6 +103,12 @@
the notion of pressure. The fingers of the hand and the palm all have
different characteristic widths [1].
+ABS_MT_PRESSURE
+
+The pressure, in arbitrary units, on the contact area. May be used instead
+of TOUCH and WIDTH for pressure-based devices or any device with a spatial
+signal intensity distribution.
+
ABS_MT_ORIENTATION
The orientation of the ellipse. The value should describe a signed quarter
@@ -170,6 +192,16 @@
make use of these native identifiers to reduce bandwidth and cpu usage.
+Gestures
+--------
+
+In the specific application of creating gesture events, the TOUCH and WIDTH
+parameters can be used to, e.g., approximate finger pressure or distinguish
+between index finger and thumb. With the addition of the MINOR parameters,
+one can also distinguish between a sweeping finger and a pointing finger,
+and with ORIENTATION, one can detect twisting of fingers.
+
+
Notes
-----
diff --git a/Makefile b/Makefile
index 67d6cff..394aec7 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 33
-EXTRAVERSION = -rc5
+EXTRAVERSION = -rc6
NAME = Man-Eating Seals of Antiquity
# *DOCUMENTATION*
diff --git a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
index 8bf4153..3bf6304 100644
--- a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
+++ b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
@@ -13,6 +13,7 @@
#include <linux/platform_device.h>
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
+#include <linux/gpio.h>
#include <linux/spi/flash.h>
#include <linux/spi/spi.h>
#include <linux/spi/orion_spi.h>
@@ -53,6 +54,11 @@
*/
kirkwood_init();
+ orion_gpio_set_valid(RD88F6192_GPIO_USB_VBUS, 1);
+ if (gpio_request(RD88F6192_GPIO_USB_VBUS, "USB VBUS") != 0 ||
+ gpio_direction_output(RD88F6192_GPIO_USB_VBUS, 1) != 0)
+ pr_err("RD-88F6192-NAS: failed to setup USB VBUS GPIO\n");
+
kirkwood_ehci_init();
kirkwood_ge00_init(&rd88f6192_ge00_data);
kirkwood_sata_init(&rd88f6192_sata_data);
diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c
index b31ca4c..8f159db 100644
--- a/arch/arm/mach-orion5x/dns323-setup.c
+++ b/arch/arm/mach-orion5x/dns323-setup.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/pci.h>
#include <linux/irq.h>
@@ -32,6 +33,7 @@
#define DNS323_GPIO_LED_RIGHT_AMBER 1
#define DNS323_GPIO_LED_LEFT_AMBER 2
+#define DNS323_GPIO_SYSTEM_UP 3
#define DNS323_GPIO_LED_POWER 5
#define DNS323_GPIO_OVERTEMP 6
#define DNS323_GPIO_RTC 7
@@ -239,7 +241,7 @@
{
.name = "power:blue",
.gpio = DNS323_GPIO_LED_POWER,
- .active_low = 1,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
}, {
.name = "right:amber",
.gpio = DNS323_GPIO_LED_RIGHT_AMBER,
@@ -334,7 +336,7 @@
{ 0, MPP_UNUSED },
{ 1, MPP_GPIO }, /* right amber LED (sata ch0) */
{ 2, MPP_GPIO }, /* left amber LED (sata ch1) */
- { 3, MPP_UNUSED },
+ { 3, MPP_GPIO }, /* system up flag */
{ 4, MPP_GPIO }, /* power button LED */
{ 5, MPP_GPIO }, /* power button LED */
{ 6, MPP_GPIO }, /* GMT G751-2f overtemp */
@@ -372,13 +374,23 @@
},
};
-/* DNS-323 specific power off method */
-static void dns323_power_off(void)
+/* DNS-323 rev. A specific power off method */
+static void dns323a_power_off(void)
{
pr_info("%s: triggering power-off...\n", __func__);
gpio_set_value(DNS323_GPIO_POWER_OFF, 1);
}
+/* DNS-323 rev B specific power off method */
+static void dns323b_power_off(void)
+{
+ pr_info("%s: triggering power-off...\n", __func__);
+ /* Pin has to be changed to 1 and back to 0 to do actual power off. */
+ gpio_set_value(DNS323_GPIO_POWER_OFF, 1);
+ mdelay(100);
+ gpio_set_value(DNS323_GPIO_POWER_OFF, 0);
+}
+
static void __init dns323_init(void)
{
/* Setup basic Orion functions. Need to be called early. */
@@ -424,11 +436,20 @@
if (dns323_dev_id() == MV88F5182_DEV_ID)
orion5x_sata_init(&dns323_sata_data);
- /* register dns323 specific power-off method */
+ /* The 5182 has flag to indicate the system is up. Without this flag
+ * set, power LED will flash and cannot be controlled via leds-gpio.
+ */
+ if (dns323_dev_id() == MV88F5182_DEV_ID)
+ gpio_set_value(DNS323_GPIO_SYSTEM_UP, 1);
+
+ /* Register dns323 specific power-off method */
if (gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0 ||
gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0)
pr_err("DNS323: failed to setup power-off GPIO\n");
- pm_power_off = dns323_power_off;
+ if (dns323_dev_id() == MV88F5182_DEV_ID)
+ pm_power_off = dns323b_power_off;
+ else
+ pm_power_off = dns323a_power_off;
}
/* Warning: D-Link uses a wrong mach-type (=526) in their bootloader */
diff --git a/arch/arm/mach-orion5x/wrt350n-v2-setup.c b/arch/arm/mach-orion5x/wrt350n-v2-setup.c
index 1b4ad9d..cb0feca 100644
--- a/arch/arm/mach-orion5x/wrt350n-v2-setup.c
+++ b/arch/arm/mach-orion5x/wrt350n-v2-setup.c
@@ -15,6 +15,9 @@
#include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
#include <net/dsa.h>
#include <asm/mach-types.h>
#include <asm/gpio.h>
@@ -24,6 +27,80 @@
#include "common.h"
#include "mpp.h"
+/*
+ * LEDs attached to GPIO
+ */
+static struct gpio_led wrt350n_v2_led_pins[] = {
+ {
+ .name = "wrt350nv2:green:power",
+ .gpio = 0,
+ .active_low = 1,
+ }, {
+ .name = "wrt350nv2:green:security",
+ .gpio = 1,
+ .active_low = 1,
+ }, {
+ .name = "wrt350nv2:orange:power",
+ .gpio = 5,
+ .active_low = 1,
+ }, {
+ .name = "wrt350nv2:green:usb",
+ .gpio = 6,
+ .active_low = 1,
+ }, {
+ .name = "wrt350nv2:green:wireless",
+ .gpio = 7,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data wrt350n_v2_led_data = {
+ .leds = wrt350n_v2_led_pins,
+ .num_leds = ARRAY_SIZE(wrt350n_v2_led_pins),
+};
+
+static struct platform_device wrt350n_v2_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &wrt350n_v2_led_data,
+ },
+};
+
+/*
+ * Buttons attached to GPIO
+ */
+static struct gpio_keys_button wrt350n_v2_buttons[] = {
+ {
+ .code = KEY_RESTART,
+ .gpio = 3,
+ .desc = "Reset Button",
+ .active_low = 1,
+ }, {
+ .code = KEY_WLAN,
+ .gpio = 2,
+ .desc = "WPS Button",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data wrt350n_v2_button_data = {
+ .buttons = wrt350n_v2_buttons,
+ .nbuttons = ARRAY_SIZE(wrt350n_v2_buttons),
+};
+
+static struct platform_device wrt350n_v2_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &wrt350n_v2_button_data,
+ },
+};
+
+/*
+ * General setup
+ */
static struct orion5x_mpp_mode wrt350n_v2_mpp_modes[] __initdata = {
{ 0, MPP_GPIO }, /* Power LED green (0=on) */
{ 1, MPP_GPIO }, /* Security LED (0=on) */
@@ -140,6 +217,8 @@
orion5x_setup_dev_boot_win(WRT350N_V2_NOR_BOOT_BASE,
WRT350N_V2_NOR_BOOT_SIZE);
platform_device_register(&wrt350n_v2_nor_flash);
+ platform_device_register(&wrt350n_v2_leds);
+ platform_device_register(&wrt350n_v2_button_device);
}
static int __init wrt350n_v2_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 74446cf..da3156d86 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -457,6 +457,7 @@
* USB Device Controller
*/
static struct pxa2xx_udc_mach_info udc_info __initdata = {
+ .gpio_vbus = -1,
/* no connect GPIO; corgi can't tell connection status */
.gpio_pullup = CORGI_GPIO_USB_PULLUP,
};
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h b/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
index b13dc02..9c78785 100644
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
@@ -169,7 +169,6 @@
#define GPIO86_nSDCS2 MFP_CFG_OUT(GPIO86, AF0, DRIVE_HIGH)
#define GPIO87_nSDCS3 MFP_CFG_OUT(GPIO87, AF0, DRIVE_HIGH)
#define GPIO88_RDnWR MFP_CFG_OUT(GPIO88, AF0, DRIVE_HIGH)
-#define GPIO89_nACRESET MFP_CFG_OUT(GPIO89, AF0, DRIVE_HIGH)
/* USB */
#define GPIO9_USB_RCV MFP_CFG_IN(GPIO9, AF1)
@@ -186,6 +185,9 @@
#define GPIO30_ASSP_TXD MFP_CFG_OUT(GPIO30, AF3, DRIVE_LOW)
#define GPIO31_ASSP_SFRM_IN MFP_CFG_IN(GPIO31, AF1)
#define GPIO31_ASSP_SFRM_OUT MFP_CFG_OUT(GPIO31, AF3, DRIVE_LOW)
-#endif
+
+/* AC97 */
+#define GPIO89_AC97_nRESET MFP_CFG_OUT(GPIO89, AF0, DRIVE_HIGH)
+#endif /* CONFIG_CPU_PXA26x */
#endif /* __ASM_ARCH_MFP_PXA25X_H */
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index 6112af4..1beb40f 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -164,8 +164,11 @@
saved_icmr[i] = _ICMR(irq);
_ICMR(irq) = 0;
}
- for (i = 0; i < pxa_internal_irq_nr; i++)
- saved_ipr[i] = IPR(i);
+
+ if (cpu_is_pxa27x() || cpu_is_pxa3xx()) {
+ for (i = 0; i < pxa_internal_irq_nr; i++)
+ saved_ipr[i] = IPR(i);
+ }
return 0;
}
@@ -174,12 +177,15 @@
{
int i, irq = PXA_IRQ(0);
+ if (cpu_is_pxa27x() || cpu_is_pxa3xx()) {
+ for (i = 0; i < pxa_internal_irq_nr; i++)
+ IPR(i) = saved_ipr[i];
+ }
+
for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) {
_ICMR(irq) = saved_icmr[i];
_ICLR(irq) = 0;
}
- for (i = 0; i < pxa_internal_irq_nr; i++)
- IPR(i) = saved_ipr[i];
ICCR = 1;
return 0;
diff --git a/arch/arm/plat-orion/pcie.c b/arch/arm/plat-orion/pcie.c
index d41d41d..54c84a4 100644
--- a/arch/arm/plat-orion/pcie.c
+++ b/arch/arm/plat-orion/pcie.c
@@ -133,6 +133,12 @@
}
/*
+ * Round up 'size' to the nearest power of two.
+ */
+ if ((size & (size - 1)) != 0)
+ size = 1 << fls(size);
+
+ /*
* Setup BAR[1] to all DRAM banks.
*/
writel(dram->cs[0].base, base + PCIE_BAR_LO_OFF(1));
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index c3a74ce..5a79fc6 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: Wed Dec 16 20:06:34 2009
+# Last update: Thu Jan 28 22:15:54 2010
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
@@ -2536,6 +2536,7 @@
c3ax03 MACH_C3AX03 C3AX03 2549
mxt_td60 MACH_MXT_TD60 MXT_TD60 2550
esyx MACH_ESYX ESYX 2551
+dove_db2 MACH_DOVE_DB2 DOVE_DB2 2552
bulldog MACH_BULLDOG BULLDOG 2553
derell_me2000 MACH_DERELL_ME2000 DERELL_ME2000 2554
bcmring_base MACH_BCMRING_BASE BCMRING_BASE 2555
@@ -2555,6 +2556,7 @@
cezanne MACH_CEZANNE CEZANNE 2569
lucca MACH_LUCCA LUCCA 2570
supersmart MACH_SUPERSMART SUPERSMART 2571
+arm11_board MACH_CS_MISANO CS_MISANO 2572
magnolia2 MACH_MAGNOLIA2 MAGNOLIA2 2573
emxx MACH_EMXX EMXX 2574
outlaw MACH_OUTLAW OUTLAW 2575
@@ -2578,3 +2580,59 @@
phrazer_bulldog MACH_PHRAZER_BULLDOG PHRAZER_BULLDOG 2593
omap3_bulldog MACH_OMAP3_BULLDOG OMAP3_BULLDOG 2594
pca101 MACH_PCA101 PCA101 2595
+buzzc MACH_BUZZC BUZZC 2596
+sasie2 MACH_SASIE2 SASIE2 2597
+davinci_cio MACH_DAVINCI_CIO DAVINCI_CIO 2598
+smartmeter_dl MACH_SMARTMETER_DL SMARTMETER_DL 2599
+wzl6410 MACH_WZL6410 WZL6410 2600
+wzl6410m MACH_WZL6410M WZL6410M 2601
+wzl6410f MACH_WZL6410F WZL6410F 2602
+wzl6410i MACH_WZL6410I WZL6410I 2603
+spacecom1 MACH_SPACECOM1 SPACECOM1 2604
+pingu920 MACH_PINGU920 PINGU920 2605
+bravoc MACH_BRAVOC BRAVOC 2606
+cybo2440 MACH_CYBO2440 CYBO2440 2607
+vdssw MACH_VDSSW VDSSW 2608
+romulus MACH_ROMULUS ROMULUS 2609
+omap_magic MACH_OMAP_MAGIC OMAP_MAGIC 2610
+eltd100 MACH_ELTD100 ELTD100 2611
+capc7117 MACH_CAPC7117 CAPC7117 2612
+swan MACH_SWAN SWAN 2613
+veu MACH_VEU VEU 2614
+rm2 MACH_RM2 RM2 2615
+tt2100 MACH_TT2100 TT2100 2616
+venice MACH_VENICE VENICE 2617
+pc7323 MACH_PC7323 PC7323 2618
+masp MACH_MASP MASP 2619
+fujitsu_tvstbsoc0 MACH_FUJITSU_TVSTBSOC FUJITSU_TVSTBSOC 2620
+fujitsu_tvstbsoc1 MACH_FUJITSU_TVSTBSOC1 FUJITSU_TVSTBSOC1 2621
+lexikon MACH_LEXIKON LEXIKON 2622
+mini2440v2 MACH_MINI2440V2 MINI2440V2 2623
+icontrol MACH_ICONTROL ICONTROL 2624
+sheevad MACH_SHEEVAD SHEEVAD 2625
+qsd8x50a_st1_1 MACH_QSD8X50A_ST1_1 QSD8X50A_ST1_1 2626
+qsd8x50a_st1_5 MACH_QSD8X50A_ST1_5 QSD8X50A_ST1_5 2627
+bee MACH_BEE BEE 2628
+mx23evk MACH_MX23EVK MX23EVK 2629
+ap4evb MACH_AP4EVB AP4EVB 2630
+stockholm MACH_STOCKHOLM STOCKHOLM 2631
+lpc_h3131 MACH_LPC_H3131 LPC_H3131 2632
+stingray MACH_STINGRAY STINGRAY 2633
+kraken MACH_KRAKEN KRAKEN 2634
+gw2388 MACH_GW2388 GW2388 2635
+jadecpu MACH_JADECPU JADECPU 2636
+carlisle MACH_CARLISLE CARLISLE 2637
+lux_sf9 MACH_LUX_SFT9 LUX_SFT9 2638
+nemid_tb MACH_NEMID_TB NEMID_TB 2639
+terrier MACH_TERRIER TERRIER 2640
+turbot MACH_TURBOT TURBOT 2641
+sanddab MACH_SANDDAB SANDDAB 2642
+mx35_cicada MACH_MX35_CICADA MX35_CICADA 2643
+ghi2703d MACH_GHI2703D GHI2703D 2644
+lux_sfx9 MACH_LUX_SFX9 LUX_SFX9 2645
+lux_sf9g MACH_LUX_SF9G LUX_SF9G 2646
+lux_edk9 MACH_LUX_EDK9 LUX_EDK9 2647
+hw90240 MACH_HW90240 HW90240 2648
+dm365_leopard MACH_DM365_LEOPARD DM365_LEOPARD 2649
+mityomapl138 MACH_MITYOMAPL138 MITYOMAPL138 2650
+scat110 MACH_SCAT110 SCAT110 2651
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 9541171..8b5d174 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1311,6 +1311,7 @@
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_BZIP2
select HAVE_KERNEL_LZMA
+ select HAVE_KERNEL_LZO
config SYS_SUPPORTS_ZBOOT_UART16550
bool
diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile
index 671d344..9df903d 100644
--- a/arch/mips/boot/compressed/Makefile
+++ b/arch/mips/boot/compressed/Makefile
@@ -14,8 +14,11 @@
# compressed kernel load addr: VMLINUZ_LOAD_ADDRESS > VMLINUX_LOAD_ADDRESS + VMLINUX_SIZE
VMLINUX_SIZE := $(shell wc -c $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | cut -d' ' -f1)
-VMLINUX_SIZE := $(shell [ -n "$(VMLINUX_SIZE)" ] && echo $$(($(VMLINUX_SIZE) + (65536 - $(VMLINUX_SIZE) % 65536))))
-VMLINUZ_LOAD_ADDRESS := 0x$(shell [ -n "$(VMLINUX_SIZE)" ] && printf %x $$(($(VMLINUX_LOAD_ADDRESS) + $(VMLINUX_SIZE))))
+VMLINUX_SIZE := $(shell [ -n "$(VMLINUX_SIZE)" ] && echo -n $$(($(VMLINUX_SIZE) + (65536 - $(VMLINUX_SIZE) % 65536))))
+# VMLINUZ_LOAD_ADDRESS = concat "high32 of VMLINUX_LOAD_ADDRESS" and "(low32 of VMLINUX_LOAD_ADDRESS) + VMLINUX_SIZE"
+HIGH32 := $(shell A=$(VMLINUX_LOAD_ADDRESS); [ $${\#A} -gt 10 ] && expr substr "$(VMLINUX_LOAD_ADDRESS)" 3 $$(($${\#A} - 10)))
+LOW32 := $(shell [ -n "$(HIGH32)" ] && A=11 || A=3; expr substr "$(VMLINUX_LOAD_ADDRESS)" $${A} 8)
+VMLINUZ_LOAD_ADDRESS := 0x$(shell [ -n "$(VMLINUX_SIZE)" -a -n "$(LOW32)" ] && printf "$(HIGH32)%08x" $$(($(VMLINUX_SIZE) + 0x$(LOW32))))
# set the default size of the mallocing area for decompressing
BOOT_HEAP_SIZE := 0x400000
@@ -41,9 +44,11 @@
suffix_$(CONFIG_KERNEL_GZIP) = gz
suffix_$(CONFIG_KERNEL_BZIP2) = bz2
suffix_$(CONFIG_KERNEL_LZMA) = lzma
+suffix_$(CONFIG_KERNEL_LZO) = lzo
tool_$(CONFIG_KERNEL_GZIP) = gzip
tool_$(CONFIG_KERNEL_BZIP2) = bzip2
tool_$(CONFIG_KERNEL_LZMA) = lzma
+tool_$(CONFIG_KERNEL_LZO) = lzo
$(obj)/vmlinux.$(suffix_y): $(obj)/vmlinux.bin
$(call if_changed,$(tool_y))
diff --git a/arch/mips/boot/compressed/decompress.c b/arch/mips/boot/compressed/decompress.c
index e48fd72..55d02b3 100644
--- a/arch/mips/boot/compressed/decompress.c
+++ b/arch/mips/boot/compressed/decompress.c
@@ -77,6 +77,10 @@
#include "../../../../lib/decompress_unlzma.c"
#endif
+#ifdef CONFIG_KERNEL_LZO
+#include "../../../../lib/decompress_unlzo.c"
+#endif
+
void decompress_kernel(unsigned long boot_heap_start)
{
int zimage_size;
diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h
index 0696036..dea4aed 100644
--- a/arch/mips/include/asm/irq.h
+++ b/arch/mips/include/asm/irq.h
@@ -135,6 +135,7 @@
#define CP0_LEGACY_COMPARE_IRQ 7
extern int cp0_compare_irq;
+extern int cp0_compare_irq_shift;
extern int cp0_perfcount_irq;
#endif /* _ASM_IRQ_H */
diff --git a/arch/mips/include/asm/mach-powertv/asic_reg_map.h b/arch/mips/include/asm/mach-powertv/asic_reg_map.h
new file mode 100644
index 0000000..6f26cb0
--- /dev/null
+++ b/arch/mips/include/asm/mach-powertv/asic_reg_map.h
@@ -0,0 +1,90 @@
+/*
+ * asic_reg_map.h
+ *
+ * A macro-enclosed list of the elements for the register_map structure for
+ * use in defining and manipulating the structure.
+ *
+ * Copyright (C) 2009 Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+REGISTER_MAP_ELEMENT(eic_slow0_strt_add)
+REGISTER_MAP_ELEMENT(eic_cfg_bits)
+REGISTER_MAP_ELEMENT(eic_ready_status)
+REGISTER_MAP_ELEMENT(chipver3)
+REGISTER_MAP_ELEMENT(chipver2)
+REGISTER_MAP_ELEMENT(chipver1)
+REGISTER_MAP_ELEMENT(chipver0)
+REGISTER_MAP_ELEMENT(uart1_intstat)
+REGISTER_MAP_ELEMENT(uart1_inten)
+REGISTER_MAP_ELEMENT(uart1_config1)
+REGISTER_MAP_ELEMENT(uart1_config2)
+REGISTER_MAP_ELEMENT(uart1_divisorhi)
+REGISTER_MAP_ELEMENT(uart1_divisorlo)
+REGISTER_MAP_ELEMENT(uart1_data)
+REGISTER_MAP_ELEMENT(uart1_status)
+REGISTER_MAP_ELEMENT(int_stat_3)
+REGISTER_MAP_ELEMENT(int_stat_2)
+REGISTER_MAP_ELEMENT(int_stat_1)
+REGISTER_MAP_ELEMENT(int_stat_0)
+REGISTER_MAP_ELEMENT(int_config)
+REGISTER_MAP_ELEMENT(int_int_scan)
+REGISTER_MAP_ELEMENT(ien_int_3)
+REGISTER_MAP_ELEMENT(ien_int_2)
+REGISTER_MAP_ELEMENT(ien_int_1)
+REGISTER_MAP_ELEMENT(ien_int_0)
+REGISTER_MAP_ELEMENT(int_level_3_3)
+REGISTER_MAP_ELEMENT(int_level_3_2)
+REGISTER_MAP_ELEMENT(int_level_3_1)
+REGISTER_MAP_ELEMENT(int_level_3_0)
+REGISTER_MAP_ELEMENT(int_level_2_3)
+REGISTER_MAP_ELEMENT(int_level_2_2)
+REGISTER_MAP_ELEMENT(int_level_2_1)
+REGISTER_MAP_ELEMENT(int_level_2_0)
+REGISTER_MAP_ELEMENT(int_level_1_3)
+REGISTER_MAP_ELEMENT(int_level_1_2)
+REGISTER_MAP_ELEMENT(int_level_1_1)
+REGISTER_MAP_ELEMENT(int_level_1_0)
+REGISTER_MAP_ELEMENT(int_level_0_3)
+REGISTER_MAP_ELEMENT(int_level_0_2)
+REGISTER_MAP_ELEMENT(int_level_0_1)
+REGISTER_MAP_ELEMENT(int_level_0_0)
+REGISTER_MAP_ELEMENT(int_docsis_en)
+REGISTER_MAP_ELEMENT(mips_pll_setup)
+REGISTER_MAP_ELEMENT(usb_fs)
+REGISTER_MAP_ELEMENT(test_bus)
+REGISTER_MAP_ELEMENT(crt_spare)
+REGISTER_MAP_ELEMENT(usb2_ohci_int_mask)
+REGISTER_MAP_ELEMENT(usb2_strap)
+REGISTER_MAP_ELEMENT(ehci_hcapbase)
+REGISTER_MAP_ELEMENT(ohci_hc_revision)
+REGISTER_MAP_ELEMENT(bcm1_bs_lmi_steer)
+REGISTER_MAP_ELEMENT(usb2_control)
+REGISTER_MAP_ELEMENT(usb2_stbus_obc)
+REGISTER_MAP_ELEMENT(usb2_stbus_mess_size)
+REGISTER_MAP_ELEMENT(usb2_stbus_chunk_size)
+REGISTER_MAP_ELEMENT(pcie_regs)
+REGISTER_MAP_ELEMENT(tim_ch)
+REGISTER_MAP_ELEMENT(tim_cl)
+REGISTER_MAP_ELEMENT(gpio_dout)
+REGISTER_MAP_ELEMENT(gpio_din)
+REGISTER_MAP_ELEMENT(gpio_dir)
+REGISTER_MAP_ELEMENT(watchdog)
+REGISTER_MAP_ELEMENT(front_panel)
+REGISTER_MAP_ELEMENT(misc_clk_ctl1)
+REGISTER_MAP_ELEMENT(misc_clk_ctl2)
+REGISTER_MAP_ELEMENT(crt_ext_ctl)
+REGISTER_MAP_ELEMENT(register_maps)
diff --git a/arch/mips/include/asm/mach-powertv/asic_regs.h b/arch/mips/include/asm/mach-powertv/asic_regs.h
index 9a65c93..1e11236 100644
--- a/arch/mips/include/asm/mach-powertv/asic_regs.h
+++ b/arch/mips/include/asm/mach-powertv/asic_regs.h
@@ -35,11 +35,12 @@
#define CRONUS_11 0x0B4C1C21
#define CRONUSLITE_10 0x0B4C1C40
-#define NAND_FLASH_BASE 0x03000000
-#define ZEUS_IO_BASE 0x09000000
+#define NAND_FLASH_BASE 0x03000000
#define CALLIOPE_IO_BASE 0x08000000
-#define CRONUS_IO_BASE 0x09000000
-#define ASIC_IO_SIZE 0x01000000
+#define CRONUS_IO_BASE 0x09000000
+#define ZEUS_IO_BASE 0x09000000
+
+#define ASIC_IO_SIZE 0x01000000
/* Definitions for backward compatibility */
#define UART1_INTSTAT uart1_intstat
@@ -52,96 +53,62 @@
#define UART1_STATUS uart1_status
/* ASIC register enumeration */
-struct register_map {
- u32 eic_slow0_strt_add;
- u32 eic_cfg_bits;
- u32 eic_ready_status;
-
- u32 chipver3;
- u32 chipver2;
- u32 chipver1;
- u32 chipver0;
-
- u32 uart1_intstat;
- u32 uart1_inten;
- u32 uart1_config1;
- u32 uart1_config2;
- u32 uart1_divisorhi;
- u32 uart1_divisorlo;
- u32 uart1_data;
- u32 uart1_status;
-
- u32 int_stat_3;
- u32 int_stat_2;
- u32 int_stat_1;
- u32 int_stat_0;
- u32 int_config;
- u32 int_int_scan;
- u32 ien_int_3;
- u32 ien_int_2;
- u32 ien_int_1;
- u32 ien_int_0;
- u32 int_level_3_3;
- u32 int_level_3_2;
- u32 int_level_3_1;
- u32 int_level_3_0;
- u32 int_level_2_3;
- u32 int_level_2_2;
- u32 int_level_2_1;
- u32 int_level_2_0;
- u32 int_level_1_3;
- u32 int_level_1_2;
- u32 int_level_1_1;
- u32 int_level_1_0;
- u32 int_level_0_3;
- u32 int_level_0_2;
- u32 int_level_0_1;
- u32 int_level_0_0;
- u32 int_docsis_en;
-
- u32 mips_pll_setup;
- u32 usb_fs;
- u32 test_bus;
- u32 crt_spare;
- u32 usb2_ohci_int_mask;
- u32 usb2_strap;
- u32 ehci_hcapbase;
- u32 ohci_hc_revision;
- u32 bcm1_bs_lmi_steer;
- u32 usb2_control;
- u32 usb2_stbus_obc;
- u32 usb2_stbus_mess_size;
- u32 usb2_stbus_chunk_size;
-
- u32 pcie_regs;
- u32 tim_ch;
- u32 tim_cl;
- u32 gpio_dout;
- u32 gpio_din;
- u32 gpio_dir;
- u32 watchdog;
- u32 front_panel;
-
- u32 register_maps;
+union register_map_entry {
+ unsigned long phys;
+ u32 *virt;
};
-extern enum asic_type asic;
-extern const struct register_map *register_map;
-extern unsigned long asic_phy_base; /* Physical address of ASIC */
-extern unsigned long asic_base; /* Virtual address of ASIC */
+#define REGISTER_MAP_ELEMENT(x) union register_map_entry x;
+struct register_map {
+#include <asm/mach-powertv/asic_reg_map.h>
+};
+#undef REGISTER_MAP_ELEMENT
+
+/**
+ * register_map_offset_phys - add an offset to the physical address
+ * @map: Pointer to the &struct register_map
+ * @offset: Value to add
+ *
+ * Only adds the base to non-zero physical addresses
+ */
+static inline void register_map_offset_phys(struct register_map *map,
+ unsigned long offset)
+{
+#define REGISTER_MAP_ELEMENT(x) do { \
+ if (map->x.phys != 0) \
+ map->x.phys += offset; \
+ } while (false);
+
+#include <asm/mach-powertv/asic_reg_map.h>
+#undef REGISTER_MAP_ELEMENT
+}
+
+/**
+ * register_map_virtualize - Convert ®ister_map to virtual addresses
+ * @map: Pointer to ®ister_map to virtualize
+ */
+static inline void register_map_virtualize(struct register_map *map)
+{
+#define REGISTER_MAP_ELEMENT(x) do { \
+ map->x.virt = (!map->x.phys) ? NULL : \
+ UNCAC_ADDR(phys_to_virt(map->x.phys)); \
+ } while (false);
+
+#include <asm/mach-powertv/asic_reg_map.h>
+#undef REGISTER_MAP_ELEMENT
+}
+
+extern struct register_map _asic_register_map;
/*
* Macros to interface to registers through their ioremapped address
- * asic_reg_offset Returns the offset of a given register from the start
- * of the ASIC address space
* asic_reg_phys_addr Returns the physical address of the given register
* asic_reg_addr Returns the iomapped virtual address of the given
* register.
*/
-#define asic_reg_offset(x) (register_map->x)
-#define asic_reg_phys_addr(x) (asic_phy_base + asic_reg_offset(x))
-#define asic_reg_addr(x) \
- ((unsigned int *) (asic_base + asic_reg_offset(x)))
+#define asic_reg_addr(x) (_asic_register_map.x.virt)
+#define asic_reg_phys_addr(x) (virt_to_phys((void *) CAC_ADDR( \
+ (unsigned long) asic_reg_addr(x))))
/*
* The asic_reg macro is gone. It should be replaced by either asic_read or
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index a581d60..f4ab313 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -406,6 +406,16 @@
#define ST0_XX 0x80000000 /* MIPS IV naming */
/*
+ * Bitfields and bit numbers in the coprocessor 0 IntCtl register. (MIPSR2)
+ *
+ * Refer to your MIPS R4xx0 manual, chapter 5 for explanation.
+ */
+#define INTCTLB_IPPCI 26
+#define INTCTLF_IPPCI (_ULCAST_(7) << INTCTLB_IPPCI)
+#define INTCTLB_IPTI 29
+#define INTCTLF_IPTI (_ULCAST_(7) << INTCTLB_IPTI)
+
+/*
* Bitfields and bit numbers in the coprocessor 0 cause register.
*
* Refer to your MIPS R4xx0 manual, chapter 5 for explanation.
@@ -434,6 +444,8 @@
#define CAUSEF_IV (_ULCAST_(1) << 23)
#define CAUSEB_CE 28
#define CAUSEF_CE (_ULCAST_(3) << 28)
+#define CAUSEB_TI 30
+#define CAUSEF_TI (_ULCAST_(1) << 30)
#define CAUSEB_BD 31
#define CAUSEF_BD (_ULCAST_(1) << 31)
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
index b469ad0..0b2450c 100644
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -97,7 +97,7 @@
*/
static int c0_compare_int_pending(void)
{
- return (read_c0_cause() >> cp0_compare_irq) & 0x100;
+ return (read_c0_cause() >> cp0_compare_irq_shift) & (1ul << CAUSEB_IP);
}
/*
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 308e434..338dfe8 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1403,6 +1403,7 @@
* Timer interrupt
*/
int cp0_compare_irq;
+int cp0_compare_irq_shift;
/*
* Performance counter IRQ or -1 if shared with timer
@@ -1493,8 +1494,9 @@
* o read IntCtl.IPPCI to determine the performance counter interrupt
*/
if (cpu_has_mips_r2) {
- cp0_compare_irq = (read_c0_intctl() >> 29) & 7;
- cp0_perfcount_irq = (read_c0_intctl() >> 26) & 7;
+ cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP;
+ cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7;
+ cp0_perfcount_irq = (read_c0_intctl() >> INTCTLB_IPPCI) & 7;
if (cp0_perfcount_irq == cp0_compare_irq)
cp0_perfcount_irq = -1;
} else {
diff --git a/arch/mips/powertv/asic/asic-calliope.c b/arch/mips/powertv/asic/asic-calliope.c
index 03d3884..1ae6623 100644
--- a/arch/mips/powertv/asic/asic-calliope.c
+++ b/arch/mips/powertv/asic/asic-calliope.c
@@ -23,76 +23,79 @@
* Description: Defines the platform resources for the SA settop.
*/
+#include <linux/init.h>
#include <asm/mach-powertv/asic.h>
-const struct register_map calliope_register_map = {
- .eic_slow0_strt_add = 0x800000,
- .eic_cfg_bits = 0x800038,
- .eic_ready_status = 0x80004c,
+#define CALLIOPE_ADDR(x) (CALLIOPE_IO_BASE + (x))
- .chipver3 = 0xA00800,
- .chipver2 = 0xA00804,
- .chipver1 = 0xA00808,
- .chipver0 = 0xA0080c,
+const struct register_map calliope_register_map __initdata = {
+ .eic_slow0_strt_add = {.phys = CALLIOPE_ADDR(0x800000)},
+ .eic_cfg_bits = {.phys = CALLIOPE_ADDR(0x800038)},
+ .eic_ready_status = {.phys = CALLIOPE_ADDR(0x80004c)},
+
+ .chipver3 = {.phys = CALLIOPE_ADDR(0xA00800)},
+ .chipver2 = {.phys = CALLIOPE_ADDR(0xA00804)},
+ .chipver1 = {.phys = CALLIOPE_ADDR(0xA00808)},
+ .chipver0 = {.phys = CALLIOPE_ADDR(0xA0080c)},
/* The registers of IRBlaster */
- .uart1_intstat = 0xA01800,
- .uart1_inten = 0xA01804,
- .uart1_config1 = 0xA01808,
- .uart1_config2 = 0xA0180C,
- .uart1_divisorhi = 0xA01810,
- .uart1_divisorlo = 0xA01814,
- .uart1_data = 0xA01818,
- .uart1_status = 0xA0181C,
+ .uart1_intstat = {.phys = CALLIOPE_ADDR(0xA01800)},
+ .uart1_inten = {.phys = CALLIOPE_ADDR(0xA01804)},
+ .uart1_config1 = {.phys = CALLIOPE_ADDR(0xA01808)},
+ .uart1_config2 = {.phys = CALLIOPE_ADDR(0xA0180C)},
+ .uart1_divisorhi = {.phys = CALLIOPE_ADDR(0xA01810)},
+ .uart1_divisorlo = {.phys = CALLIOPE_ADDR(0xA01814)},
+ .uart1_data = {.phys = CALLIOPE_ADDR(0xA01818)},
+ .uart1_status = {.phys = CALLIOPE_ADDR(0xA0181C)},
- .int_stat_3 = 0xA02800,
- .int_stat_2 = 0xA02804,
- .int_stat_1 = 0xA02808,
- .int_stat_0 = 0xA0280c,
- .int_config = 0xA02810,
- .int_int_scan = 0xA02818,
- .ien_int_3 = 0xA02830,
- .ien_int_2 = 0xA02834,
- .ien_int_1 = 0xA02838,
- .ien_int_0 = 0xA0283c,
- .int_level_3_3 = 0xA02880,
- .int_level_3_2 = 0xA02884,
- .int_level_3_1 = 0xA02888,
- .int_level_3_0 = 0xA0288c,
- .int_level_2_3 = 0xA02890,
- .int_level_2_2 = 0xA02894,
- .int_level_2_1 = 0xA02898,
- .int_level_2_0 = 0xA0289c,
- .int_level_1_3 = 0xA028a0,
- .int_level_1_2 = 0xA028a4,
- .int_level_1_1 = 0xA028a8,
- .int_level_1_0 = 0xA028ac,
- .int_level_0_3 = 0xA028b0,
- .int_level_0_2 = 0xA028b4,
- .int_level_0_1 = 0xA028b8,
- .int_level_0_0 = 0xA028bc,
- .int_docsis_en = 0xA028F4,
+ .int_stat_3 = {.phys = CALLIOPE_ADDR(0xA02800)},
+ .int_stat_2 = {.phys = CALLIOPE_ADDR(0xA02804)},
+ .int_stat_1 = {.phys = CALLIOPE_ADDR(0xA02808)},
+ .int_stat_0 = {.phys = CALLIOPE_ADDR(0xA0280c)},
+ .int_config = {.phys = CALLIOPE_ADDR(0xA02810)},
+ .int_int_scan = {.phys = CALLIOPE_ADDR(0xA02818)},
+ .ien_int_3 = {.phys = CALLIOPE_ADDR(0xA02830)},
+ .ien_int_2 = {.phys = CALLIOPE_ADDR(0xA02834)},
+ .ien_int_1 = {.phys = CALLIOPE_ADDR(0xA02838)},
+ .ien_int_0 = {.phys = CALLIOPE_ADDR(0xA0283c)},
+ .int_level_3_3 = {.phys = CALLIOPE_ADDR(0xA02880)},
+ .int_level_3_2 = {.phys = CALLIOPE_ADDR(0xA02884)},
+ .int_level_3_1 = {.phys = CALLIOPE_ADDR(0xA02888)},
+ .int_level_3_0 = {.phys = CALLIOPE_ADDR(0xA0288c)},
+ .int_level_2_3 = {.phys = CALLIOPE_ADDR(0xA02890)},
+ .int_level_2_2 = {.phys = CALLIOPE_ADDR(0xA02894)},
+ .int_level_2_1 = {.phys = CALLIOPE_ADDR(0xA02898)},
+ .int_level_2_0 = {.phys = CALLIOPE_ADDR(0xA0289c)},
+ .int_level_1_3 = {.phys = CALLIOPE_ADDR(0xA028a0)},
+ .int_level_1_2 = {.phys = CALLIOPE_ADDR(0xA028a4)},
+ .int_level_1_1 = {.phys = CALLIOPE_ADDR(0xA028a8)},
+ .int_level_1_0 = {.phys = CALLIOPE_ADDR(0xA028ac)},
+ .int_level_0_3 = {.phys = CALLIOPE_ADDR(0xA028b0)},
+ .int_level_0_2 = {.phys = CALLIOPE_ADDR(0xA028b4)},
+ .int_level_0_1 = {.phys = CALLIOPE_ADDR(0xA028b8)},
+ .int_level_0_0 = {.phys = CALLIOPE_ADDR(0xA028bc)},
+ .int_docsis_en = {.phys = CALLIOPE_ADDR(0xA028F4)},
- .mips_pll_setup = 0x980000,
- .usb_fs = 0x980030, /* -default 72800028- */
- .test_bus = 0x9800CC,
- .crt_spare = 0x9800d4,
- .usb2_ohci_int_mask = 0x9A000c,
- .usb2_strap = 0x9A0014,
- .ehci_hcapbase = 0x9BFE00,
- .ohci_hc_revision = 0x9BFC00,
- .bcm1_bs_lmi_steer = 0x9E0004,
- .usb2_control = 0x9E0054,
- .usb2_stbus_obc = 0x9BFF00,
- .usb2_stbus_mess_size = 0x9BFF04,
- .usb2_stbus_chunk_size = 0x9BFF08,
+ .mips_pll_setup = {.phys = CALLIOPE_ADDR(0x980000)},
+ .usb_fs = {.phys = CALLIOPE_ADDR(0x980030)},
+ .test_bus = {.phys = CALLIOPE_ADDR(0x9800CC)},
+ .crt_spare = {.phys = CALLIOPE_ADDR(0x9800d4)},
+ .usb2_ohci_int_mask = {.phys = CALLIOPE_ADDR(0x9A000c)},
+ .usb2_strap = {.phys = CALLIOPE_ADDR(0x9A0014)},
+ .ehci_hcapbase = {.phys = CALLIOPE_ADDR(0x9BFE00)},
+ .ohci_hc_revision = {.phys = CALLIOPE_ADDR(0x9BFC00)},
+ .bcm1_bs_lmi_steer = {.phys = CALLIOPE_ADDR(0x9E0004)},
+ .usb2_control = {.phys = CALLIOPE_ADDR(0x9E0054)},
+ .usb2_stbus_obc = {.phys = CALLIOPE_ADDR(0x9BFF00)},
+ .usb2_stbus_mess_size = {.phys = CALLIOPE_ADDR(0x9BFF04)},
+ .usb2_stbus_chunk_size = {.phys = CALLIOPE_ADDR(0x9BFF08)},
- .pcie_regs = 0x000000, /* -doesn't exist- */
- .tim_ch = 0xA02C10,
- .tim_cl = 0xA02C14,
- .gpio_dout = 0xA02c20,
- .gpio_din = 0xA02c24,
- .gpio_dir = 0xA02c2C,
- .watchdog = 0xA02c30,
- .front_panel = 0x000000, /* -not used- */
+ .pcie_regs = {.phys = 0x000000}, /* -doesn't exist- */
+ .tim_ch = {.phys = CALLIOPE_ADDR(0xA02C10)},
+ .tim_cl = {.phys = CALLIOPE_ADDR(0xA02C14)},
+ .gpio_dout = {.phys = CALLIOPE_ADDR(0xA02c20)},
+ .gpio_din = {.phys = CALLIOPE_ADDR(0xA02c24)},
+ .gpio_dir = {.phys = CALLIOPE_ADDR(0xA02c2C)},
+ .watchdog = {.phys = CALLIOPE_ADDR(0xA02c30)},
+ .front_panel = {.phys = 0x000000}, /* -not used- */
};
diff --git a/arch/mips/powertv/asic/asic-cronus.c b/arch/mips/powertv/asic/asic-cronus.c
index 5f4589c..5bb64bf 100644
--- a/arch/mips/powertv/asic/asic-cronus.c
+++ b/arch/mips/powertv/asic/asic-cronus.c
@@ -23,76 +23,79 @@
* Description: Defines the platform resources for the SA settop.
*/
+#include <linux/init.h>
#include <asm/mach-powertv/asic.h>
-const struct register_map cronus_register_map = {
- .eic_slow0_strt_add = 0x000000,
- .eic_cfg_bits = 0x000038,
- .eic_ready_status = 0x00004C,
+#define CRONUS_ADDR(x) (CRONUS_IO_BASE + (x))
- .chipver3 = 0x2A0800,
- .chipver2 = 0x2A0804,
- .chipver1 = 0x2A0808,
- .chipver0 = 0x2A080C,
+const struct register_map cronus_register_map __initdata = {
+ .eic_slow0_strt_add = {.phys = CRONUS_ADDR(0x000000)},
+ .eic_cfg_bits = {.phys = CRONUS_ADDR(0x000038)},
+ .eic_ready_status = {.phys = CRONUS_ADDR(0x00004C)},
+
+ .chipver3 = {.phys = CRONUS_ADDR(0x2A0800)},
+ .chipver2 = {.phys = CRONUS_ADDR(0x2A0804)},
+ .chipver1 = {.phys = CRONUS_ADDR(0x2A0808)},
+ .chipver0 = {.phys = CRONUS_ADDR(0x2A080C)},
/* The registers of IRBlaster */
- .uart1_intstat = 0x2A1800,
- .uart1_inten = 0x2A1804,
- .uart1_config1 = 0x2A1808,
- .uart1_config2 = 0x2A180C,
- .uart1_divisorhi = 0x2A1810,
- .uart1_divisorlo = 0x2A1814,
- .uart1_data = 0x2A1818,
- .uart1_status = 0x2A181C,
+ .uart1_intstat = {.phys = CRONUS_ADDR(0x2A1800)},
+ .uart1_inten = {.phys = CRONUS_ADDR(0x2A1804)},
+ .uart1_config1 = {.phys = CRONUS_ADDR(0x2A1808)},
+ .uart1_config2 = {.phys = CRONUS_ADDR(0x2A180C)},
+ .uart1_divisorhi = {.phys = CRONUS_ADDR(0x2A1810)},
+ .uart1_divisorlo = {.phys = CRONUS_ADDR(0x2A1814)},
+ .uart1_data = {.phys = CRONUS_ADDR(0x2A1818)},
+ .uart1_status = {.phys = CRONUS_ADDR(0x2A181C)},
- .int_stat_3 = 0x2A2800,
- .int_stat_2 = 0x2A2804,
- .int_stat_1 = 0x2A2808,
- .int_stat_0 = 0x2A280C,
- .int_config = 0x2A2810,
- .int_int_scan = 0x2A2818,
- .ien_int_3 = 0x2A2830,
- .ien_int_2 = 0x2A2834,
- .ien_int_1 = 0x2A2838,
- .ien_int_0 = 0x2A283C,
- .int_level_3_3 = 0x2A2880,
- .int_level_3_2 = 0x2A2884,
- .int_level_3_1 = 0x2A2888,
- .int_level_3_0 = 0x2A288C,
- .int_level_2_3 = 0x2A2890,
- .int_level_2_2 = 0x2A2894,
- .int_level_2_1 = 0x2A2898,
- .int_level_2_0 = 0x2A289C,
- .int_level_1_3 = 0x2A28A0,
- .int_level_1_2 = 0x2A28A4,
- .int_level_1_1 = 0x2A28A8,
- .int_level_1_0 = 0x2A28AC,
- .int_level_0_3 = 0x2A28B0,
- .int_level_0_2 = 0x2A28B4,
- .int_level_0_1 = 0x2A28B8,
- .int_level_0_0 = 0x2A28BC,
- .int_docsis_en = 0x2A28F4,
+ .int_stat_3 = {.phys = CRONUS_ADDR(0x2A2800)},
+ .int_stat_2 = {.phys = CRONUS_ADDR(0x2A2804)},
+ .int_stat_1 = {.phys = CRONUS_ADDR(0x2A2808)},
+ .int_stat_0 = {.phys = CRONUS_ADDR(0x2A280C)},
+ .int_config = {.phys = CRONUS_ADDR(0x2A2810)},
+ .int_int_scan = {.phys = CRONUS_ADDR(0x2A2818)},
+ .ien_int_3 = {.phys = CRONUS_ADDR(0x2A2830)},
+ .ien_int_2 = {.phys = CRONUS_ADDR(0x2A2834)},
+ .ien_int_1 = {.phys = CRONUS_ADDR(0x2A2838)},
+ .ien_int_0 = {.phys = CRONUS_ADDR(0x2A283C)},
+ .int_level_3_3 = {.phys = CRONUS_ADDR(0x2A2880)},
+ .int_level_3_2 = {.phys = CRONUS_ADDR(0x2A2884)},
+ .int_level_3_1 = {.phys = CRONUS_ADDR(0x2A2888)},
+ .int_level_3_0 = {.phys = CRONUS_ADDR(0x2A288C)},
+ .int_level_2_3 = {.phys = CRONUS_ADDR(0x2A2890)},
+ .int_level_2_2 = {.phys = CRONUS_ADDR(0x2A2894)},
+ .int_level_2_1 = {.phys = CRONUS_ADDR(0x2A2898)},
+ .int_level_2_0 = {.phys = CRONUS_ADDR(0x2A289C)},
+ .int_level_1_3 = {.phys = CRONUS_ADDR(0x2A28A0)},
+ .int_level_1_2 = {.phys = CRONUS_ADDR(0x2A28A4)},
+ .int_level_1_1 = {.phys = CRONUS_ADDR(0x2A28A8)},
+ .int_level_1_0 = {.phys = CRONUS_ADDR(0x2A28AC)},
+ .int_level_0_3 = {.phys = CRONUS_ADDR(0x2A28B0)},
+ .int_level_0_2 = {.phys = CRONUS_ADDR(0x2A28B4)},
+ .int_level_0_1 = {.phys = CRONUS_ADDR(0x2A28B8)},
+ .int_level_0_0 = {.phys = CRONUS_ADDR(0x2A28BC)},
+ .int_docsis_en = {.phys = CRONUS_ADDR(0x2A28F4)},
- .mips_pll_setup = 0x1C0000,
- .usb_fs = 0x1C0018,
- .test_bus = 0x1C00CC,
- .crt_spare = 0x1c00d4,
- .usb2_ohci_int_mask = 0x20000C,
- .usb2_strap = 0x200014,
- .ehci_hcapbase = 0x21FE00,
- .ohci_hc_revision = 0x1E0000,
- .bcm1_bs_lmi_steer = 0x2E0008,
- .usb2_control = 0x2E004C,
- .usb2_stbus_obc = 0x21FF00,
- .usb2_stbus_mess_size = 0x21FF04,
- .usb2_stbus_chunk_size = 0x21FF08,
+ .mips_pll_setup = {.phys = CRONUS_ADDR(0x1C0000)},
+ .usb_fs = {.phys = CRONUS_ADDR(0x1C0018)},
+ .test_bus = {.phys = CRONUS_ADDR(0x1C00CC)},
+ .crt_spare = {.phys = CRONUS_ADDR(0x1c00d4)},
+ .usb2_ohci_int_mask = {.phys = CRONUS_ADDR(0x20000C)},
+ .usb2_strap = {.phys = CRONUS_ADDR(0x200014)},
+ .ehci_hcapbase = {.phys = CRONUS_ADDR(0x21FE00)},
+ .ohci_hc_revision = {.phys = CRONUS_ADDR(0x1E0000)},
+ .bcm1_bs_lmi_steer = {.phys = CRONUS_ADDR(0x2E0008)},
+ .usb2_control = {.phys = CRONUS_ADDR(0x2E004C)},
+ .usb2_stbus_obc = {.phys = CRONUS_ADDR(0x21FF00)},
+ .usb2_stbus_mess_size = {.phys = CRONUS_ADDR(0x21FF04)},
+ .usb2_stbus_chunk_size = {.phys = CRONUS_ADDR(0x21FF08)},
- .pcie_regs = 0x220000,
- .tim_ch = 0x2A2C10,
- .tim_cl = 0x2A2C14,
- .gpio_dout = 0x2A2C20,
- .gpio_din = 0x2A2C24,
- .gpio_dir = 0x2A2C2C,
- .watchdog = 0x2A2C30,
- .front_panel = 0x2A3800,
+ .pcie_regs = {.phys = CRONUS_ADDR(0x220000)},
+ .tim_ch = {.phys = CRONUS_ADDR(0x2A2C10)},
+ .tim_cl = {.phys = CRONUS_ADDR(0x2A2C14)},
+ .gpio_dout = {.phys = CRONUS_ADDR(0x2A2C20)},
+ .gpio_din = {.phys = CRONUS_ADDR(0x2A2C24)},
+ .gpio_dir = {.phys = CRONUS_ADDR(0x2A2C2C)},
+ .watchdog = {.phys = CRONUS_ADDR(0x2A2C30)},
+ .front_panel = {.phys = CRONUS_ADDR(0x2A3800)},
};
diff --git a/arch/mips/powertv/asic/asic-zeus.c b/arch/mips/powertv/asic/asic-zeus.c
index 1469daa..095cbe10 100644
--- a/arch/mips/powertv/asic/asic-zeus.c
+++ b/arch/mips/powertv/asic/asic-zeus.c
@@ -23,76 +23,79 @@
* Description: Defines the platform resources for the SA settop.
*/
+#include <linux/init.h>
#include <asm/mach-powertv/asic.h>
-const struct register_map zeus_register_map = {
- .eic_slow0_strt_add = 0x000000,
- .eic_cfg_bits = 0x000038,
- .eic_ready_status = 0x00004c,
+#define ZEUS_ADDR(x) (ZEUS_IO_BASE + (x))
- .chipver3 = 0x280800,
- .chipver2 = 0x280804,
- .chipver1 = 0x280808,
- .chipver0 = 0x28080c,
+const struct register_map zeus_register_map __initdata = {
+ .eic_slow0_strt_add = {.phys = ZEUS_ADDR(0x000000)},
+ .eic_cfg_bits = {.phys = ZEUS_ADDR(0x000038)},
+ .eic_ready_status = {.phys = ZEUS_ADDR(0x00004c)},
+
+ .chipver3 = {.phys = ZEUS_ADDR(0x280800)},
+ .chipver2 = {.phys = ZEUS_ADDR(0x280804)},
+ .chipver1 = {.phys = ZEUS_ADDR(0x280808)},
+ .chipver0 = {.phys = ZEUS_ADDR(0x28080c)},
/* The registers of IRBlaster */
- .uart1_intstat = 0x281800,
- .uart1_inten = 0x281804,
- .uart1_config1 = 0x281808,
- .uart1_config2 = 0x28180C,
- .uart1_divisorhi = 0x281810,
- .uart1_divisorlo = 0x281814,
- .uart1_data = 0x281818,
- .uart1_status = 0x28181C,
+ .uart1_intstat = {.phys = ZEUS_ADDR(0x281800)},
+ .uart1_inten = {.phys = ZEUS_ADDR(0x281804)},
+ .uart1_config1 = {.phys = ZEUS_ADDR(0x281808)},
+ .uart1_config2 = {.phys = ZEUS_ADDR(0x28180C)},
+ .uart1_divisorhi = {.phys = ZEUS_ADDR(0x281810)},
+ .uart1_divisorlo = {.phys = ZEUS_ADDR(0x281814)},
+ .uart1_data = {.phys = ZEUS_ADDR(0x281818)},
+ .uart1_status = {.phys = ZEUS_ADDR(0x28181C)},
- .int_stat_3 = 0x282800,
- .int_stat_2 = 0x282804,
- .int_stat_1 = 0x282808,
- .int_stat_0 = 0x28280c,
- .int_config = 0x282810,
- .int_int_scan = 0x282818,
- .ien_int_3 = 0x282830,
- .ien_int_2 = 0x282834,
- .ien_int_1 = 0x282838,
- .ien_int_0 = 0x28283c,
- .int_level_3_3 = 0x282880,
- .int_level_3_2 = 0x282884,
- .int_level_3_1 = 0x282888,
- .int_level_3_0 = 0x28288c,
- .int_level_2_3 = 0x282890,
- .int_level_2_2 = 0x282894,
- .int_level_2_1 = 0x282898,
- .int_level_2_0 = 0x28289c,
- .int_level_1_3 = 0x2828a0,
- .int_level_1_2 = 0x2828a4,
- .int_level_1_1 = 0x2828a8,
- .int_level_1_0 = 0x2828ac,
- .int_level_0_3 = 0x2828b0,
- .int_level_0_2 = 0x2828b4,
- .int_level_0_1 = 0x2828b8,
- .int_level_0_0 = 0x2828bc,
- .int_docsis_en = 0x2828F4,
+ .int_stat_3 = {.phys = ZEUS_ADDR(0x282800)},
+ .int_stat_2 = {.phys = ZEUS_ADDR(0x282804)},
+ .int_stat_1 = {.phys = ZEUS_ADDR(0x282808)},
+ .int_stat_0 = {.phys = ZEUS_ADDR(0x28280c)},
+ .int_config = {.phys = ZEUS_ADDR(0x282810)},
+ .int_int_scan = {.phys = ZEUS_ADDR(0x282818)},
+ .ien_int_3 = {.phys = ZEUS_ADDR(0x282830)},
+ .ien_int_2 = {.phys = ZEUS_ADDR(0x282834)},
+ .ien_int_1 = {.phys = ZEUS_ADDR(0x282838)},
+ .ien_int_0 = {.phys = ZEUS_ADDR(0x28283c)},
+ .int_level_3_3 = {.phys = ZEUS_ADDR(0x282880)},
+ .int_level_3_2 = {.phys = ZEUS_ADDR(0x282884)},
+ .int_level_3_1 = {.phys = ZEUS_ADDR(0x282888)},
+ .int_level_3_0 = {.phys = ZEUS_ADDR(0x28288c)},
+ .int_level_2_3 = {.phys = ZEUS_ADDR(0x282890)},
+ .int_level_2_2 = {.phys = ZEUS_ADDR(0x282894)},
+ .int_level_2_1 = {.phys = ZEUS_ADDR(0x282898)},
+ .int_level_2_0 = {.phys = ZEUS_ADDR(0x28289c)},
+ .int_level_1_3 = {.phys = ZEUS_ADDR(0x2828a0)},
+ .int_level_1_2 = {.phys = ZEUS_ADDR(0x2828a4)},
+ .int_level_1_1 = {.phys = ZEUS_ADDR(0x2828a8)},
+ .int_level_1_0 = {.phys = ZEUS_ADDR(0x2828ac)},
+ .int_level_0_3 = {.phys = ZEUS_ADDR(0x2828b0)},
+ .int_level_0_2 = {.phys = ZEUS_ADDR(0x2828b4)},
+ .int_level_0_1 = {.phys = ZEUS_ADDR(0x2828b8)},
+ .int_level_0_0 = {.phys = ZEUS_ADDR(0x2828bc)},
+ .int_docsis_en = {.phys = ZEUS_ADDR(0x2828F4)},
- .mips_pll_setup = 0x1a0000,
- .usb_fs = 0x1a0018,
- .test_bus = 0x1a0238,
- .crt_spare = 0x1a0090,
- .usb2_ohci_int_mask = 0x1e000c,
- .usb2_strap = 0x1e0014,
- .ehci_hcapbase = 0x1FFE00,
- .ohci_hc_revision = 0x1FFC00,
- .bcm1_bs_lmi_steer = 0x2C0008,
- .usb2_control = 0x2c01a0,
- .usb2_stbus_obc = 0x1FFF00,
- .usb2_stbus_mess_size = 0x1FFF04,
- .usb2_stbus_chunk_size = 0x1FFF08,
+ .mips_pll_setup = {.phys = ZEUS_ADDR(0x1a0000)},
+ .usb_fs = {.phys = ZEUS_ADDR(0x1a0018)},
+ .test_bus = {.phys = ZEUS_ADDR(0x1a0238)},
+ .crt_spare = {.phys = ZEUS_ADDR(0x1a0090)},
+ .usb2_ohci_int_mask = {.phys = ZEUS_ADDR(0x1e000c)},
+ .usb2_strap = {.phys = ZEUS_ADDR(0x1e0014)},
+ .ehci_hcapbase = {.phys = ZEUS_ADDR(0x1FFE00)},
+ .ohci_hc_revision = {.phys = ZEUS_ADDR(0x1FFC00)},
+ .bcm1_bs_lmi_steer = {.phys = ZEUS_ADDR(0x2C0008)},
+ .usb2_control = {.phys = ZEUS_ADDR(0x2c01a0)},
+ .usb2_stbus_obc = {.phys = ZEUS_ADDR(0x1FFF00)},
+ .usb2_stbus_mess_size = {.phys = ZEUS_ADDR(0x1FFF04)},
+ .usb2_stbus_chunk_size = {.phys = ZEUS_ADDR(0x1FFF08)},
- .pcie_regs = 0x200000,
- .tim_ch = 0x282C10,
- .tim_cl = 0x282C14,
- .gpio_dout = 0x282c20,
- .gpio_din = 0x282c24,
- .gpio_dir = 0x282c2C,
- .watchdog = 0x282c30,
- .front_panel = 0x283800,
+ .pcie_regs = {.phys = ZEUS_ADDR(0x200000)},
+ .tim_ch = {.phys = ZEUS_ADDR(0x282C10)},
+ .tim_cl = {.phys = ZEUS_ADDR(0x282C14)},
+ .gpio_dout = {.phys = ZEUS_ADDR(0x282c20)},
+ .gpio_din = {.phys = ZEUS_ADDR(0x282c24)},
+ .gpio_dir = {.phys = ZEUS_ADDR(0x282c2C)},
+ .watchdog = {.phys = ZEUS_ADDR(0x282c30)},
+ .front_panel = {.phys = ZEUS_ADDR(0x283800)},
};
diff --git a/arch/mips/powertv/asic/asic_devices.c b/arch/mips/powertv/asic/asic_devices.c
index bae8288..6a88219 100644
--- a/arch/mips/powertv/asic/asic_devices.c
+++ b/arch/mips/powertv/asic/asic_devices.c
@@ -67,8 +67,8 @@
unsigned int platform_features;
unsigned int platform_family;
-const struct register_map *register_map;
-EXPORT_SYMBOL(register_map); /* Exported for testing */
+struct register_map _asic_register_map;
+EXPORT_SYMBOL(_asic_register_map); /* Exported for testing */
unsigned long asic_phy_base;
unsigned long asic_base;
EXPORT_SYMBOL(asic_base); /* Exported for testing */
@@ -418,6 +418,15 @@
{
}
+static void __init set_register_map(unsigned long phys_base,
+ const struct register_map *map)
+{
+ asic_phy_base = phys_base;
+ _asic_register_map = *map;
+ register_map_virtualize(&_asic_register_map);
+ asic_base = (unsigned long)ioremap_nocache(phys_base, ASIC_IO_SIZE);
+}
+
/**
* configure_platform - configuration based on platform type.
*/
@@ -431,10 +440,7 @@
case FAMILY_1500VZF:
platform_features = FFS_CAPABLE;
asic = ASIC_CALLIOPE;
- asic_phy_base = CALLIOPE_IO_BASE;
- register_map = &calliope_register_map;
- asic_base = (unsigned long)ioremap_nocache(asic_phy_base,
- ASIC_IO_SIZE);
+ set_register_map(CALLIOPE_IO_BASE, &calliope_register_map);
if (platform_family == FAMILY_1500VZE) {
gp_resources = non_dvr_vze_calliope_resources;
@@ -455,10 +461,7 @@
platform_features = FFS_CAPABLE | PCIE_CAPABLE |
DISPLAY_CAPABLE;
asic = ASIC_ZEUS;
- asic_phy_base = ZEUS_IO_BASE;
- register_map = &zeus_register_map;
- asic_base = (unsigned long)ioremap_nocache(asic_phy_base,
- ASIC_IO_SIZE);
+ set_register_map(ZEUS_IO_BASE, &zeus_register_map);
gp_resources = non_dvr_zeus_resources;
pr_info("Platform: 4500 - ZEUS, NON_DVR_CAPABLE\n");
@@ -471,11 +474,6 @@
/* The settop has PCIE but it isn't used, so don't advertise
* it*/
platform_features = FFS_CAPABLE | DISPLAY_CAPABLE;
- asic_phy_base = CRONUS_IO_BASE; /* same as Cronus */
- register_map = &cronus_register_map; /* same as Cronus */
- asic_base = (unsigned long)ioremap_nocache(asic_phy_base,
- ASIC_IO_SIZE);
- gp_resources = non_dvr_cronuslite_resources;
/* ASIC version will determine if this is a real CronusLite or
* Castrati(Cronus) */
@@ -489,6 +487,9 @@
else
asic = ASIC_CRONUSLITE;
+ /* Cronus and Cronus Lite have the same register map */
+ set_register_map(CRONUS_IO_BASE, &cronus_register_map);
+ gp_resources = non_dvr_cronuslite_resources;
pr_info("Platform: 4600 - %s, NON_DVR_CAPABLE, "
"chipversion=0x%08X\n",
(asic == ASIC_CRONUS) ? "CRONUS" : "CRONUS LITE",
@@ -498,10 +499,7 @@
case FAMILY_4600VZA:
platform_features = FFS_CAPABLE | DISPLAY_CAPABLE;
asic = ASIC_CRONUS;
- asic_phy_base = CRONUS_IO_BASE;
- register_map = &cronus_register_map;
- asic_base = (unsigned long)ioremap_nocache(asic_phy_base,
- ASIC_IO_SIZE);
+ set_register_map(CRONUS_IO_BASE, &cronus_register_map);
gp_resources = non_dvr_cronus_resources;
pr_info("Platform: Vz Class A - CRONUS, NON_DVR_CAPABLE\n");
@@ -512,10 +510,7 @@
platform_features = DVR_CAPABLE | PCIE_CAPABLE |
DISPLAY_CAPABLE;
asic = ASIC_ZEUS;
- asic_phy_base = ZEUS_IO_BASE;
- register_map = &zeus_register_map;
- asic_base = (unsigned long)ioremap_nocache(asic_phy_base,
- ASIC_IO_SIZE);
+ set_register_map(ZEUS_IO_BASE, &zeus_register_map);
gp_resources = dvr_zeus_resources;
pr_info("Platform: 8500/RNG200 - ZEUS, DVR_CAPABLE\n");
@@ -526,10 +521,7 @@
platform_features = DVR_CAPABLE | PCIE_CAPABLE |
DISPLAY_CAPABLE;
asic = ASIC_CRONUS;
- asic_phy_base = CRONUS_IO_BASE;
- register_map = &cronus_register_map;
- asic_base = (unsigned long)ioremap_nocache(asic_phy_base,
- ASIC_IO_SIZE);
+ set_register_map(CRONUS_IO_BASE, &cronus_register_map);
gp_resources = dvr_cronus_resources;
pr_info("Platform: 8600/Vz Class B - CRONUS, "
diff --git a/arch/s390/include/asm/irqflags.h b/arch/s390/include/asm/irqflags.h
index 3f26131..c2fb432f 100644
--- a/arch/s390/include/asm/irqflags.h
+++ b/arch/s390/include/asm/irqflags.h
@@ -1,14 +1,12 @@
/*
- * include/asm-s390/irqflags.h
- *
- * Copyright (C) IBM Corp. 2006
- * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
+ * Copyright IBM Corp. 2006,2010
+ * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
#ifndef __ASM_IRQFLAGS_H
#define __ASM_IRQFLAGS_H
-#ifdef __KERNEL__
+#include <linux/types.h>
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
@@ -102,5 +100,4 @@
/* For spinlocks etc */
#define raw_local_irq_save(x) ((x) = raw_local_irq_disable())
-#endif /* __KERNEL__ */
#endif /* __ASM_IRQFLAGS_H */
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 48215d1..e8ef21c 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -571,6 +571,7 @@
mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
TRACE_IRQS_ON
+ lm %r2,%r6,SP_R2(%r15) # load svc arguments
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
b BASED(sysc_do_svc)
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 9aff1d4..f33658f 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -549,6 +549,7 @@
mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
TRACE_IRQS_ON
+ lmg %r2,%r6,SP_R2(%r15) # load svc arguments
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
j sysc_do_svc
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 1675c48..6289945 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -64,7 +64,7 @@
recalc_sigpending();
spin_unlock_irq(¤t->sighand->siglock);
- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);
schedule();
set_thread_flag(TIF_RESTORE_SIGMASK);
diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c
index 31f80c6..ec79faf 100644
--- a/arch/sh/kernel/process_64.c
+++ b/arch/sh/kernel/process_64.c
@@ -368,7 +368,7 @@
void flush_thread(void)
{
- /* Called by fs/exec.c (flush_old_exec) to remove traces of a
+ /* Called by fs/exec.c (setup_new_exec) to remove traces of a
* previously running executable. */
#ifdef CONFIG_SH_FPU
if (last_task_used_math == current) {
diff --git a/arch/sparc/include/asm/elf_64.h b/arch/sparc/include/asm/elf_64.h
index ff66bb8..e678803 100644
--- a/arch/sparc/include/asm/elf_64.h
+++ b/arch/sparc/include/asm/elf_64.h
@@ -195,17 +195,10 @@
#define ELF_PLATFORM (NULL)
#define SET_PERSONALITY(ex) \
-do { unsigned long new_flags = current_thread_info()->flags; \
- new_flags &= _TIF_32BIT; \
- if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
- new_flags |= _TIF_32BIT; \
+do { if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
+ set_thread_flag(TIF_32BIT); \
else \
- new_flags &= ~_TIF_32BIT; \
- if ((current_thread_info()->flags & _TIF_32BIT) \
- != new_flags) \
- set_thread_flag(TIF_ABI_PENDING); \
- else \
- clear_thread_flag(TIF_ABI_PENDING); \
+ clear_thread_flag(TIF_32BIT); \
/* flush_thread will update pgd cache */ \
if (personality(current->personality) != PER_LINUX32) \
set_personality(PER_LINUX | \
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h
index 7257ebb..39be9f2 100644
--- a/arch/sparc/include/asm/thread_info_64.h
+++ b/arch/sparc/include/asm/thread_info_64.h
@@ -228,12 +228,11 @@
#define TIF_SECCOMP 9 /* secure computing */
#define TIF_SYSCALL_AUDIT 10 /* syscall auditing active */
#define TIF_SYSCALL_TRACEPOINT 11 /* syscall tracepoint instrumentation */
-/* flag bit 11 is available */
/* NOTE: Thread flags >= 12 should be ones we have no interest
* in using in assembly, else we can't use the mask as
* an immediate value in instructions such as andcc.
*/
-#define TIF_ABI_PENDING 12
+/* flag bit 12 is available */
#define TIF_MEMDIE 13
#define TIF_POLLING_NRFLAG 14
#define TIF_FREEZE 15 /* is freezing for suspend */
@@ -248,7 +247,6 @@
#define _TIF_SECCOMP (1<<TIF_SECCOMP)
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
-#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_FREEZE (1<<TIF_FREEZE)
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index f2179cc..e1cbdb9 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -268,10 +268,8 @@
return cpuid;
}
#else
-static int irq_choose_cpu(unsigned int virt_irq, const struct cpumask *affinity)
-{
- return real_hard_smp_processor_id();
-}
+#define irq_choose_cpu(virt_irq, affinity) \
+ real_hard_smp_processor_id()
#endif
static void sun4u_irq_enable(unsigned int virt_irq)
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
index 18d6785..c3f1cce 100644
--- a/arch/sparc/kernel/process_64.c
+++ b/arch/sparc/kernel/process_64.c
@@ -365,14 +365,6 @@
struct thread_info *t = current_thread_info();
struct mm_struct *mm;
- if (test_ti_thread_flag(t, TIF_ABI_PENDING)) {
- clear_ti_thread_flag(t, TIF_ABI_PENDING);
- if (test_ti_thread_flag(t, TIF_32BIT))
- clear_ti_thread_flag(t, TIF_32BIT);
- else
- set_ti_thread_flag(t, TIF_32BIT);
- }
-
mm = t->task->mm;
if (mm)
tsb_context_switch(mm);
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index cbcbfde..eb40925 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -989,12 +989,6 @@
with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
/dev/cpu/31/cpuid.
-config X86_CPU_DEBUG
- tristate "/sys/kernel/debug/x86/cpu/* - CPU Debug support"
- ---help---
- If you select this option, this will provide various x86 CPUs
- information through debugfs.
-
choice
prompt "High Memory Support"
default HIGHMEM4G if !X86_NUMAQ
diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c
index 2a4d073..f9f4724 100644
--- a/arch/x86/ia32/ia32_aout.c
+++ b/arch/x86/ia32/ia32_aout.c
@@ -308,14 +308,15 @@
if (retval)
return retval;
- regs->cs = __USER32_CS;
- regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 =
- regs->r13 = regs->r14 = regs->r15 = 0;
-
/* OK, This is the point of no return */
set_personality(PER_LINUX);
set_thread_flag(TIF_IA32);
- clear_thread_flag(TIF_ABI_PENDING);
+
+ setup_new_exec(bprm);
+
+ regs->cs = __USER32_CS;
+ regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 =
+ regs->r13 = regs->r14 = regs->r15 = 0;
current->mm->end_code = ex.a_text +
(current->mm->start_code = N_TXTADDR(ex));
diff --git a/arch/x86/include/asm/cpu_debug.h b/arch/x86/include/asm/cpu_debug.h
deleted file mode 100644
index d96c1ee..0000000
--- a/arch/x86/include/asm/cpu_debug.h
+++ /dev/null
@@ -1,127 +0,0 @@
-#ifndef _ASM_X86_CPU_DEBUG_H
-#define _ASM_X86_CPU_DEBUG_H
-
-/*
- * CPU x86 architecture debug
- *
- * Copyright(C) 2009 Jaswinder Singh Rajput
- */
-
-/* Register flags */
-enum cpu_debug_bit {
-/* Model Specific Registers (MSRs) */
- CPU_MC_BIT, /* Machine Check */
- CPU_MONITOR_BIT, /* Monitor */
- CPU_TIME_BIT, /* Time */
- CPU_PMC_BIT, /* Performance Monitor */
- CPU_PLATFORM_BIT, /* Platform */
- CPU_APIC_BIT, /* APIC */
- CPU_POWERON_BIT, /* Power-on */
- CPU_CONTROL_BIT, /* Control */
- CPU_FEATURES_BIT, /* Features control */
- CPU_LBRANCH_BIT, /* Last Branch */
- CPU_BIOS_BIT, /* BIOS */
- CPU_FREQ_BIT, /* Frequency */
- CPU_MTTR_BIT, /* MTRR */
- CPU_PERF_BIT, /* Performance */
- CPU_CACHE_BIT, /* Cache */
- CPU_SYSENTER_BIT, /* Sysenter */
- CPU_THERM_BIT, /* Thermal */
- CPU_MISC_BIT, /* Miscellaneous */
- CPU_DEBUG_BIT, /* Debug */
- CPU_PAT_BIT, /* PAT */
- CPU_VMX_BIT, /* VMX */
- CPU_CALL_BIT, /* System Call */
- CPU_BASE_BIT, /* BASE Address */
- CPU_VER_BIT, /* Version ID */
- CPU_CONF_BIT, /* Configuration */
- CPU_SMM_BIT, /* System mgmt mode */
- CPU_SVM_BIT, /*Secure Virtual Machine*/
- CPU_OSVM_BIT, /* OS-Visible Workaround*/
-/* Standard Registers */
- CPU_TSS_BIT, /* Task Stack Segment */
- CPU_CR_BIT, /* Control Registers */
- CPU_DT_BIT, /* Descriptor Table */
-/* End of Registers flags */
- CPU_REG_ALL_BIT, /* Select all Registers */
-};
-
-#define CPU_REG_ALL (~0) /* Select all Registers */
-
-#define CPU_MC (1 << CPU_MC_BIT)
-#define CPU_MONITOR (1 << CPU_MONITOR_BIT)
-#define CPU_TIME (1 << CPU_TIME_BIT)
-#define CPU_PMC (1 << CPU_PMC_BIT)
-#define CPU_PLATFORM (1 << CPU_PLATFORM_BIT)
-#define CPU_APIC (1 << CPU_APIC_BIT)
-#define CPU_POWERON (1 << CPU_POWERON_BIT)
-#define CPU_CONTROL (1 << CPU_CONTROL_BIT)
-#define CPU_FEATURES (1 << CPU_FEATURES_BIT)
-#define CPU_LBRANCH (1 << CPU_LBRANCH_BIT)
-#define CPU_BIOS (1 << CPU_BIOS_BIT)
-#define CPU_FREQ (1 << CPU_FREQ_BIT)
-#define CPU_MTRR (1 << CPU_MTTR_BIT)
-#define CPU_PERF (1 << CPU_PERF_BIT)
-#define CPU_CACHE (1 << CPU_CACHE_BIT)
-#define CPU_SYSENTER (1 << CPU_SYSENTER_BIT)
-#define CPU_THERM (1 << CPU_THERM_BIT)
-#define CPU_MISC (1 << CPU_MISC_BIT)
-#define CPU_DEBUG (1 << CPU_DEBUG_BIT)
-#define CPU_PAT (1 << CPU_PAT_BIT)
-#define CPU_VMX (1 << CPU_VMX_BIT)
-#define CPU_CALL (1 << CPU_CALL_BIT)
-#define CPU_BASE (1 << CPU_BASE_BIT)
-#define CPU_VER (1 << CPU_VER_BIT)
-#define CPU_CONF (1 << CPU_CONF_BIT)
-#define CPU_SMM (1 << CPU_SMM_BIT)
-#define CPU_SVM (1 << CPU_SVM_BIT)
-#define CPU_OSVM (1 << CPU_OSVM_BIT)
-#define CPU_TSS (1 << CPU_TSS_BIT)
-#define CPU_CR (1 << CPU_CR_BIT)
-#define CPU_DT (1 << CPU_DT_BIT)
-
-/* Register file flags */
-enum cpu_file_bit {
- CPU_INDEX_BIT, /* index */
- CPU_VALUE_BIT, /* value */
-};
-
-#define CPU_FILE_VALUE (1 << CPU_VALUE_BIT)
-
-#define MAX_CPU_FILES 512
-
-struct cpu_private {
- unsigned cpu;
- unsigned type;
- unsigned reg;
- unsigned file;
-};
-
-struct cpu_debug_base {
- char *name; /* Register name */
- unsigned flag; /* Register flag */
- unsigned write; /* Register write flag */
-};
-
-/*
- * Currently it looks similar to cpu_debug_base but once we add more files
- * cpu_file_base will go in different direction
- */
-struct cpu_file_base {
- char *name; /* Register file name */
- unsigned flag; /* Register file flag */
- unsigned write; /* Register write flag */
-};
-
-struct cpu_cpuX_base {
- struct dentry *dentry; /* Register dentry */
- int init; /* Register index file */
-};
-
-struct cpu_debug_range {
- unsigned min; /* Register range min */
- unsigned max; /* Register range max */
- unsigned flag; /* Supported flags */
-};
-
-#endif /* _ASM_X86_CPU_DEBUG_H */
diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index b4501ee..1994d3f 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -181,14 +181,8 @@
void start_thread_ia32(struct pt_regs *regs, u32 new_ip, u32 new_sp);
#define compat_start_thread start_thread_ia32
-#define COMPAT_SET_PERSONALITY(ex) \
-do { \
- if (test_thread_flag(TIF_IA32)) \
- clear_thread_flag(TIF_ABI_PENDING); \
- else \
- set_thread_flag(TIF_ABI_PENDING); \
- current->personality |= force_personality32; \
-} while (0)
+void set_personality_ia32(void);
+#define COMPAT_SET_PERSONALITY(ex) set_personality_ia32()
#define COMPAT_ELF_PLATFORM ("i686")
diff --git a/arch/x86/include/asm/hpet.h b/arch/x86/include/asm/hpet.h
index 5d89fd2..1d5c08a 100644
--- a/arch/x86/include/asm/hpet.h
+++ b/arch/x86/include/asm/hpet.h
@@ -67,6 +67,7 @@
extern unsigned long force_hpet_address;
extern u8 hpet_blockid;
extern int hpet_force_user;
+extern u8 hpet_msi_disable;
extern int is_hpet_enabled(void);
extern int hpet_enable(void);
extern void hpet_disable(void);
diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index c24ca9a..ef51b50 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -12,8 +12,6 @@
enum ucode_state { UCODE_ERROR, UCODE_OK, UCODE_NFOUND };
struct microcode_ops {
- void (*init)(struct device *device);
- void (*fini)(void);
enum ucode_state (*request_microcode_user) (int cpu,
const void __user *buf, size_t size);
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index 375c917..e0d2890 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -87,7 +87,6 @@
#define TIF_NOTSC 16 /* TSC is not accessible in userland */
#define TIF_IA32 17 /* 32bit process */
#define TIF_FORK 18 /* ret_from_fork */
-#define TIF_ABI_PENDING 19
#define TIF_MEMDIE 20
#define TIF_DEBUG 21 /* uses debug registers */
#define TIF_IO_BITMAP 22 /* uses I/O bitmap */
@@ -112,7 +111,6 @@
#define _TIF_NOTSC (1 << TIF_NOTSC)
#define _TIF_IA32 (1 << TIF_IA32)
#define _TIF_FORK (1 << TIF_FORK)
-#define _TIF_ABI_PENDING (1 << TIF_ABI_PENDING)
#define _TIF_DEBUG (1 << TIF_DEBUG)
#define _TIF_IO_BITMAP (1 << TIF_IO_BITMAP)
#define _TIF_FREEZE (1 << TIF_FREEZE)
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index 1d2cb38..c202b62 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -19,8 +19,6 @@
obj-$(CONFIG_X86_32) += bugs.o cmpxchg.o
obj-$(CONFIG_X86_64) += bugs_64.o
-obj-$(CONFIG_X86_CPU_DEBUG) += cpu_debug.o
-
obj-$(CONFIG_CPU_SUP_INTEL) += intel.o
obj-$(CONFIG_CPU_SUP_AMD) += amd.o
obj-$(CONFIG_CPU_SUP_CYRIX_32) += cyrix.o
diff --git a/arch/x86/kernel/cpu/cpu_debug.c b/arch/x86/kernel/cpu/cpu_debug.c
deleted file mode 100644
index b368cd8..0000000
--- a/arch/x86/kernel/cpu/cpu_debug.c
+++ /dev/null
@@ -1,688 +0,0 @@
-/*
- * CPU x86 architecture debug code
- *
- * Copyright(C) 2009 Jaswinder Singh Rajput
- *
- * For licencing details see kernel-base/COPYING
- */
-
-#include <linux/interrupt.h>
-#include <linux/compiler.h>
-#include <linux/seq_file.h>
-#include <linux/debugfs.h>
-#include <linux/kprobes.h>
-#include <linux/uaccess.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/percpu.h>
-#include <linux/signal.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/smp.h>
-
-#include <asm/cpu_debug.h>
-#include <asm/paravirt.h>
-#include <asm/system.h>
-#include <asm/traps.h>
-#include <asm/apic.h>
-#include <asm/desc.h>
-
-static DEFINE_PER_CPU(struct cpu_cpuX_base [CPU_REG_ALL_BIT], cpud_arr);
-static DEFINE_PER_CPU(struct cpu_private * [MAX_CPU_FILES], cpud_priv_arr);
-static DEFINE_PER_CPU(int, cpud_priv_count);
-
-static DEFINE_MUTEX(cpu_debug_lock);
-
-static struct dentry *cpu_debugfs_dir;
-
-static struct cpu_debug_base cpu_base[] = {
- { "mc", CPU_MC, 0 },
- { "monitor", CPU_MONITOR, 0 },
- { "time", CPU_TIME, 0 },
- { "pmc", CPU_PMC, 1 },
- { "platform", CPU_PLATFORM, 0 },
- { "apic", CPU_APIC, 0 },
- { "poweron", CPU_POWERON, 0 },
- { "control", CPU_CONTROL, 0 },
- { "features", CPU_FEATURES, 0 },
- { "lastbranch", CPU_LBRANCH, 0 },
- { "bios", CPU_BIOS, 0 },
- { "freq", CPU_FREQ, 0 },
- { "mtrr", CPU_MTRR, 0 },
- { "perf", CPU_PERF, 0 },
- { "cache", CPU_CACHE, 0 },
- { "sysenter", CPU_SYSENTER, 0 },
- { "therm", CPU_THERM, 0 },
- { "misc", CPU_MISC, 0 },
- { "debug", CPU_DEBUG, 0 },
- { "pat", CPU_PAT, 0 },
- { "vmx", CPU_VMX, 0 },
- { "call", CPU_CALL, 0 },
- { "base", CPU_BASE, 0 },
- { "ver", CPU_VER, 0 },
- { "conf", CPU_CONF, 0 },
- { "smm", CPU_SMM, 0 },
- { "svm", CPU_SVM, 0 },
- { "osvm", CPU_OSVM, 0 },
- { "tss", CPU_TSS, 0 },
- { "cr", CPU_CR, 0 },
- { "dt", CPU_DT, 0 },
- { "registers", CPU_REG_ALL, 0 },
-};
-
-static struct cpu_file_base cpu_file[] = {
- { "index", CPU_REG_ALL, 0 },
- { "value", CPU_REG_ALL, 1 },
-};
-
-/* CPU Registers Range */
-static struct cpu_debug_range cpu_reg_range[] = {
- { 0x00000000, 0x00000001, CPU_MC, },
- { 0x00000006, 0x00000007, CPU_MONITOR, },
- { 0x00000010, 0x00000010, CPU_TIME, },
- { 0x00000011, 0x00000013, CPU_PMC, },
- { 0x00000017, 0x00000017, CPU_PLATFORM, },
- { 0x0000001B, 0x0000001B, CPU_APIC, },
- { 0x0000002A, 0x0000002B, CPU_POWERON, },
- { 0x0000002C, 0x0000002C, CPU_FREQ, },
- { 0x0000003A, 0x0000003A, CPU_CONTROL, },
- { 0x00000040, 0x00000047, CPU_LBRANCH, },
- { 0x00000060, 0x00000067, CPU_LBRANCH, },
- { 0x00000079, 0x00000079, CPU_BIOS, },
- { 0x00000088, 0x0000008A, CPU_CACHE, },
- { 0x0000008B, 0x0000008B, CPU_BIOS, },
- { 0x0000009B, 0x0000009B, CPU_MONITOR, },
- { 0x000000C1, 0x000000C4, CPU_PMC, },
- { 0x000000CD, 0x000000CD, CPU_FREQ, },
- { 0x000000E7, 0x000000E8, CPU_PERF, },
- { 0x000000FE, 0x000000FE, CPU_MTRR, },
-
- { 0x00000116, 0x0000011E, CPU_CACHE, },
- { 0x00000174, 0x00000176, CPU_SYSENTER, },
- { 0x00000179, 0x0000017B, CPU_MC, },
- { 0x00000186, 0x00000189, CPU_PMC, },
- { 0x00000198, 0x00000199, CPU_PERF, },
- { 0x0000019A, 0x0000019A, CPU_TIME, },
- { 0x0000019B, 0x0000019D, CPU_THERM, },
- { 0x000001A0, 0x000001A0, CPU_MISC, },
- { 0x000001C9, 0x000001C9, CPU_LBRANCH, },
- { 0x000001D7, 0x000001D8, CPU_LBRANCH, },
- { 0x000001D9, 0x000001D9, CPU_DEBUG, },
- { 0x000001DA, 0x000001E0, CPU_LBRANCH, },
-
- { 0x00000200, 0x0000020F, CPU_MTRR, },
- { 0x00000250, 0x00000250, CPU_MTRR, },
- { 0x00000258, 0x00000259, CPU_MTRR, },
- { 0x00000268, 0x0000026F, CPU_MTRR, },
- { 0x00000277, 0x00000277, CPU_PAT, },
- { 0x000002FF, 0x000002FF, CPU_MTRR, },
-
- { 0x00000300, 0x00000311, CPU_PMC, },
- { 0x00000345, 0x00000345, CPU_PMC, },
- { 0x00000360, 0x00000371, CPU_PMC, },
- { 0x0000038D, 0x00000390, CPU_PMC, },
- { 0x000003A0, 0x000003BE, CPU_PMC, },
- { 0x000003C0, 0x000003CD, CPU_PMC, },
- { 0x000003E0, 0x000003E1, CPU_PMC, },
- { 0x000003F0, 0x000003F2, CPU_PMC, },
-
- { 0x00000400, 0x00000417, CPU_MC, },
- { 0x00000480, 0x0000048B, CPU_VMX, },
-
- { 0x00000600, 0x00000600, CPU_DEBUG, },
- { 0x00000680, 0x0000068F, CPU_LBRANCH, },
- { 0x000006C0, 0x000006CF, CPU_LBRANCH, },
-
- { 0x000107CC, 0x000107D3, CPU_PMC, },
-
- { 0xC0000080, 0xC0000080, CPU_FEATURES, },
- { 0xC0000081, 0xC0000084, CPU_CALL, },
- { 0xC0000100, 0xC0000102, CPU_BASE, },
- { 0xC0000103, 0xC0000103, CPU_TIME, },
-
- { 0xC0010000, 0xC0010007, CPU_PMC, },
- { 0xC0010010, 0xC0010010, CPU_CONF, },
- { 0xC0010015, 0xC0010015, CPU_CONF, },
- { 0xC0010016, 0xC001001A, CPU_MTRR, },
- { 0xC001001D, 0xC001001D, CPU_MTRR, },
- { 0xC001001F, 0xC001001F, CPU_CONF, },
- { 0xC0010030, 0xC0010035, CPU_BIOS, },
- { 0xC0010044, 0xC0010048, CPU_MC, },
- { 0xC0010050, 0xC0010056, CPU_SMM, },
- { 0xC0010058, 0xC0010058, CPU_CONF, },
- { 0xC0010060, 0xC0010060, CPU_CACHE, },
- { 0xC0010061, 0xC0010068, CPU_SMM, },
- { 0xC0010069, 0xC001006B, CPU_SMM, },
- { 0xC0010070, 0xC0010071, CPU_SMM, },
- { 0xC0010111, 0xC0010113, CPU_SMM, },
- { 0xC0010114, 0xC0010118, CPU_SVM, },
- { 0xC0010140, 0xC0010141, CPU_OSVM, },
- { 0xC0011022, 0xC0011023, CPU_CONF, },
-};
-
-static int is_typeflag_valid(unsigned cpu, unsigned flag)
-{
- int i;
-
- /* Standard Registers should be always valid */
- if (flag >= CPU_TSS)
- return 1;
-
- for (i = 0; i < ARRAY_SIZE(cpu_reg_range); i++) {
- if (cpu_reg_range[i].flag == flag)
- return 1;
- }
-
- /* Invalid */
- return 0;
-}
-
-static unsigned get_cpu_range(unsigned cpu, unsigned *min, unsigned *max,
- int index, unsigned flag)
-{
- if (cpu_reg_range[index].flag == flag) {
- *min = cpu_reg_range[index].min;
- *max = cpu_reg_range[index].max;
- } else
- *max = 0;
-
- return *max;
-}
-
-/* This function can also be called with seq = NULL for printk */
-static void print_cpu_data(struct seq_file *seq, unsigned type,
- u32 low, u32 high)
-{
- struct cpu_private *priv;
- u64 val = high;
-
- if (seq) {
- priv = seq->private;
- if (priv->file) {
- val = (val << 32) | low;
- seq_printf(seq, "0x%llx\n", val);
- } else
- seq_printf(seq, " %08x: %08x_%08x\n",
- type, high, low);
- } else
- printk(KERN_INFO " %08x: %08x_%08x\n", type, high, low);
-}
-
-/* This function can also be called with seq = NULL for printk */
-static void print_msr(struct seq_file *seq, unsigned cpu, unsigned flag)
-{
- unsigned msr, msr_min, msr_max;
- struct cpu_private *priv;
- u32 low, high;
- int i;
-
- if (seq) {
- priv = seq->private;
- if (priv->file) {
- if (!rdmsr_safe_on_cpu(priv->cpu, priv->reg,
- &low, &high))
- print_cpu_data(seq, priv->reg, low, high);
- return;
- }
- }
-
- for (i = 0; i < ARRAY_SIZE(cpu_reg_range); i++) {
- if (!get_cpu_range(cpu, &msr_min, &msr_max, i, flag))
- continue;
-
- for (msr = msr_min; msr <= msr_max; msr++) {
- if (rdmsr_safe_on_cpu(cpu, msr, &low, &high))
- continue;
- print_cpu_data(seq, msr, low, high);
- }
- }
-}
-
-static void print_tss(void *arg)
-{
- struct pt_regs *regs = task_pt_regs(current);
- struct seq_file *seq = arg;
- unsigned int seg;
-
- seq_printf(seq, " RAX\t: %016lx\n", regs->ax);
- seq_printf(seq, " RBX\t: %016lx\n", regs->bx);
- seq_printf(seq, " RCX\t: %016lx\n", regs->cx);
- seq_printf(seq, " RDX\t: %016lx\n", regs->dx);
-
- seq_printf(seq, " RSI\t: %016lx\n", regs->si);
- seq_printf(seq, " RDI\t: %016lx\n", regs->di);
- seq_printf(seq, " RBP\t: %016lx\n", regs->bp);
- seq_printf(seq, " ESP\t: %016lx\n", regs->sp);
-
-#ifdef CONFIG_X86_64
- seq_printf(seq, " R08\t: %016lx\n", regs->r8);
- seq_printf(seq, " R09\t: %016lx\n", regs->r9);
- seq_printf(seq, " R10\t: %016lx\n", regs->r10);
- seq_printf(seq, " R11\t: %016lx\n", regs->r11);
- seq_printf(seq, " R12\t: %016lx\n", regs->r12);
- seq_printf(seq, " R13\t: %016lx\n", regs->r13);
- seq_printf(seq, " R14\t: %016lx\n", regs->r14);
- seq_printf(seq, " R15\t: %016lx\n", regs->r15);
-#endif
-
- asm("movl %%cs,%0" : "=r" (seg));
- seq_printf(seq, " CS\t: %04x\n", seg);
- asm("movl %%ds,%0" : "=r" (seg));
- seq_printf(seq, " DS\t: %04x\n", seg);
- seq_printf(seq, " SS\t: %04lx\n", regs->ss & 0xffff);
- asm("movl %%es,%0" : "=r" (seg));
- seq_printf(seq, " ES\t: %04x\n", seg);
- asm("movl %%fs,%0" : "=r" (seg));
- seq_printf(seq, " FS\t: %04x\n", seg);
- asm("movl %%gs,%0" : "=r" (seg));
- seq_printf(seq, " GS\t: %04x\n", seg);
-
- seq_printf(seq, " EFLAGS\t: %016lx\n", regs->flags);
-
- seq_printf(seq, " EIP\t: %016lx\n", regs->ip);
-}
-
-static void print_cr(void *arg)
-{
- struct seq_file *seq = arg;
-
- seq_printf(seq, " cr0\t: %016lx\n", read_cr0());
- seq_printf(seq, " cr2\t: %016lx\n", read_cr2());
- seq_printf(seq, " cr3\t: %016lx\n", read_cr3());
- seq_printf(seq, " cr4\t: %016lx\n", read_cr4_safe());
-#ifdef CONFIG_X86_64
- seq_printf(seq, " cr8\t: %016lx\n", read_cr8());
-#endif
-}
-
-static void print_desc_ptr(char *str, struct seq_file *seq, struct desc_ptr dt)
-{
- seq_printf(seq, " %s\t: %016llx\n", str, (u64)(dt.address | dt.size));
-}
-
-static void print_dt(void *seq)
-{
- struct desc_ptr dt;
- unsigned long ldt;
-
- /* IDT */
- store_idt((struct desc_ptr *)&dt);
- print_desc_ptr("IDT", seq, dt);
-
- /* GDT */
- store_gdt((struct desc_ptr *)&dt);
- print_desc_ptr("GDT", seq, dt);
-
- /* LDT */
- store_ldt(ldt);
- seq_printf(seq, " LDT\t: %016lx\n", ldt);
-
- /* TR */
- store_tr(ldt);
- seq_printf(seq, " TR\t: %016lx\n", ldt);
-}
-
-static void print_dr(void *arg)
-{
- struct seq_file *seq = arg;
- unsigned long dr;
- int i;
-
- for (i = 0; i < 8; i++) {
- /* Ignore db4, db5 */
- if ((i == 4) || (i == 5))
- continue;
- get_debugreg(dr, i);
- seq_printf(seq, " dr%d\t: %016lx\n", i, dr);
- }
-
- seq_printf(seq, "\n MSR\t:\n");
-}
-
-static void print_apic(void *arg)
-{
- struct seq_file *seq = arg;
-
-#ifdef CONFIG_X86_LOCAL_APIC
- seq_printf(seq, " LAPIC\t:\n");
- seq_printf(seq, " ID\t\t: %08x\n", apic_read(APIC_ID) >> 24);
- seq_printf(seq, " LVR\t\t: %08x\n", apic_read(APIC_LVR));
- seq_printf(seq, " TASKPRI\t: %08x\n", apic_read(APIC_TASKPRI));
- seq_printf(seq, " ARBPRI\t\t: %08x\n", apic_read(APIC_ARBPRI));
- seq_printf(seq, " PROCPRI\t: %08x\n", apic_read(APIC_PROCPRI));
- seq_printf(seq, " LDR\t\t: %08x\n", apic_read(APIC_LDR));
- seq_printf(seq, " DFR\t\t: %08x\n", apic_read(APIC_DFR));
- seq_printf(seq, " SPIV\t\t: %08x\n", apic_read(APIC_SPIV));
- seq_printf(seq, " ISR\t\t: %08x\n", apic_read(APIC_ISR));
- seq_printf(seq, " ESR\t\t: %08x\n", apic_read(APIC_ESR));
- seq_printf(seq, " ICR\t\t: %08x\n", apic_read(APIC_ICR));
- seq_printf(seq, " ICR2\t\t: %08x\n", apic_read(APIC_ICR2));
- seq_printf(seq, " LVTT\t\t: %08x\n", apic_read(APIC_LVTT));
- seq_printf(seq, " LVTTHMR\t: %08x\n", apic_read(APIC_LVTTHMR));
- seq_printf(seq, " LVTPC\t\t: %08x\n", apic_read(APIC_LVTPC));
- seq_printf(seq, " LVT0\t\t: %08x\n", apic_read(APIC_LVT0));
- seq_printf(seq, " LVT1\t\t: %08x\n", apic_read(APIC_LVT1));
- seq_printf(seq, " LVTERR\t\t: %08x\n", apic_read(APIC_LVTERR));
- seq_printf(seq, " TMICT\t\t: %08x\n", apic_read(APIC_TMICT));
- seq_printf(seq, " TMCCT\t\t: %08x\n", apic_read(APIC_TMCCT));
- seq_printf(seq, " TDCR\t\t: %08x\n", apic_read(APIC_TDCR));
- if (boot_cpu_has(X86_FEATURE_EXTAPIC)) {
- unsigned int i, v, maxeilvt;
-
- v = apic_read(APIC_EFEAT);
- maxeilvt = (v >> 16) & 0xff;
- seq_printf(seq, " EFEAT\t\t: %08x\n", v);
- seq_printf(seq, " ECTRL\t\t: %08x\n", apic_read(APIC_ECTRL));
-
- for (i = 0; i < maxeilvt; i++) {
- v = apic_read(APIC_EILVTn(i));
- seq_printf(seq, " EILVT%d\t\t: %08x\n", i, v);
- }
- }
-#endif /* CONFIG_X86_LOCAL_APIC */
- seq_printf(seq, "\n MSR\t:\n");
-}
-
-static int cpu_seq_show(struct seq_file *seq, void *v)
-{
- struct cpu_private *priv = seq->private;
-
- if (priv == NULL)
- return -EINVAL;
-
- switch (cpu_base[priv->type].flag) {
- case CPU_TSS:
- smp_call_function_single(priv->cpu, print_tss, seq, 1);
- break;
- case CPU_CR:
- smp_call_function_single(priv->cpu, print_cr, seq, 1);
- break;
- case CPU_DT:
- smp_call_function_single(priv->cpu, print_dt, seq, 1);
- break;
- case CPU_DEBUG:
- if (priv->file == CPU_INDEX_BIT)
- smp_call_function_single(priv->cpu, print_dr, seq, 1);
- print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
- break;
- case CPU_APIC:
- if (priv->file == CPU_INDEX_BIT)
- smp_call_function_single(priv->cpu, print_apic, seq, 1);
- print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
- break;
-
- default:
- print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
- break;
- }
- seq_printf(seq, "\n");
-
- return 0;
-}
-
-static void *cpu_seq_start(struct seq_file *seq, loff_t *pos)
-{
- if (*pos == 0) /* One time is enough ;-) */
- return seq;
-
- return NULL;
-}
-
-static void *cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-{
- (*pos)++;
-
- return cpu_seq_start(seq, pos);
-}
-
-static void cpu_seq_stop(struct seq_file *seq, void *v)
-{
-}
-
-static const struct seq_operations cpu_seq_ops = {
- .start = cpu_seq_start,
- .next = cpu_seq_next,
- .stop = cpu_seq_stop,
- .show = cpu_seq_show,
-};
-
-static int cpu_seq_open(struct inode *inode, struct file *file)
-{
- struct cpu_private *priv = inode->i_private;
- struct seq_file *seq;
- int err;
-
- err = seq_open(file, &cpu_seq_ops);
- if (!err) {
- seq = file->private_data;
- seq->private = priv;
- }
-
- return err;
-}
-
-static int write_msr(struct cpu_private *priv, u64 val)
-{
- u32 low, high;
-
- high = (val >> 32) & 0xffffffff;
- low = val & 0xffffffff;
-
- if (!wrmsr_safe_on_cpu(priv->cpu, priv->reg, low, high))
- return 0;
-
- return -EPERM;
-}
-
-static int write_cpu_register(struct cpu_private *priv, const char *buf)
-{
- int ret = -EPERM;
- u64 val;
-
- ret = strict_strtoull(buf, 0, &val);
- if (ret < 0)
- return ret;
-
- /* Supporting only MSRs */
- if (priv->type < CPU_TSS_BIT)
- return write_msr(priv, val);
-
- return ret;
-}
-
-static ssize_t cpu_write(struct file *file, const char __user *ubuf,
- size_t count, loff_t *off)
-{
- struct seq_file *seq = file->private_data;
- struct cpu_private *priv = seq->private;
- char buf[19];
-
- if ((priv == NULL) || (count >= sizeof(buf)))
- return -EINVAL;
-
- if (copy_from_user(&buf, ubuf, count))
- return -EFAULT;
-
- buf[count] = 0;
-
- if ((cpu_base[priv->type].write) && (cpu_file[priv->file].write))
- if (!write_cpu_register(priv, buf))
- return count;
-
- return -EACCES;
-}
-
-static const struct file_operations cpu_fops = {
- .owner = THIS_MODULE,
- .open = cpu_seq_open,
- .read = seq_read,
- .write = cpu_write,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-static int cpu_create_file(unsigned cpu, unsigned type, unsigned reg,
- unsigned file, struct dentry *dentry)
-{
- struct cpu_private *priv = NULL;
-
- /* Already intialized */
- if (file == CPU_INDEX_BIT)
- if (per_cpu(cpud_arr[type].init, cpu))
- return 0;
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (priv == NULL)
- return -ENOMEM;
-
- priv->cpu = cpu;
- priv->type = type;
- priv->reg = reg;
- priv->file = file;
- mutex_lock(&cpu_debug_lock);
- per_cpu(cpud_priv_arr[type], cpu) = priv;
- per_cpu(cpud_priv_count, cpu)++;
- mutex_unlock(&cpu_debug_lock);
-
- if (file)
- debugfs_create_file(cpu_file[file].name, S_IRUGO,
- dentry, (void *)priv, &cpu_fops);
- else {
- debugfs_create_file(cpu_base[type].name, S_IRUGO,
- per_cpu(cpud_arr[type].dentry, cpu),
- (void *)priv, &cpu_fops);
- mutex_lock(&cpu_debug_lock);
- per_cpu(cpud_arr[type].init, cpu) = 1;
- mutex_unlock(&cpu_debug_lock);
- }
-
- return 0;
-}
-
-static int cpu_init_regfiles(unsigned cpu, unsigned int type, unsigned reg,
- struct dentry *dentry)
-{
- unsigned file;
- int err = 0;
-
- for (file = 0; file < ARRAY_SIZE(cpu_file); file++) {
- err = cpu_create_file(cpu, type, reg, file, dentry);
- if (err)
- return err;
- }
-
- return err;
-}
-
-static int cpu_init_msr(unsigned cpu, unsigned type, struct dentry *dentry)
-{
- struct dentry *cpu_dentry = NULL;
- unsigned reg, reg_min, reg_max;
- int i, err = 0;
- char reg_dir[12];
- u32 low, high;
-
- for (i = 0; i < ARRAY_SIZE(cpu_reg_range); i++) {
- if (!get_cpu_range(cpu, ®_min, ®_max, i,
- cpu_base[type].flag))
- continue;
-
- for (reg = reg_min; reg <= reg_max; reg++) {
- if (rdmsr_safe_on_cpu(cpu, reg, &low, &high))
- continue;
-
- sprintf(reg_dir, "0x%x", reg);
- cpu_dentry = debugfs_create_dir(reg_dir, dentry);
- err = cpu_init_regfiles(cpu, type, reg, cpu_dentry);
- if (err)
- return err;
- }
- }
-
- return err;
-}
-
-static int cpu_init_allreg(unsigned cpu, struct dentry *dentry)
-{
- struct dentry *cpu_dentry = NULL;
- unsigned type;
- int err = 0;
-
- for (type = 0; type < ARRAY_SIZE(cpu_base) - 1; type++) {
- if (!is_typeflag_valid(cpu, cpu_base[type].flag))
- continue;
- cpu_dentry = debugfs_create_dir(cpu_base[type].name, dentry);
- per_cpu(cpud_arr[type].dentry, cpu) = cpu_dentry;
-
- if (type < CPU_TSS_BIT)
- err = cpu_init_msr(cpu, type, cpu_dentry);
- else
- err = cpu_create_file(cpu, type, 0, CPU_INDEX_BIT,
- cpu_dentry);
- if (err)
- return err;
- }
-
- return err;
-}
-
-static int cpu_init_cpu(void)
-{
- struct dentry *cpu_dentry = NULL;
- struct cpuinfo_x86 *cpui;
- char cpu_dir[12];
- unsigned cpu;
- int err = 0;
-
- for (cpu = 0; cpu < nr_cpu_ids; cpu++) {
- cpui = &cpu_data(cpu);
- if (!cpu_has(cpui, X86_FEATURE_MSR))
- continue;
-
- sprintf(cpu_dir, "cpu%d", cpu);
- cpu_dentry = debugfs_create_dir(cpu_dir, cpu_debugfs_dir);
- err = cpu_init_allreg(cpu, cpu_dentry);
-
- pr_info("cpu%d(%d) debug files %d\n",
- cpu, nr_cpu_ids, per_cpu(cpud_priv_count, cpu));
- if (per_cpu(cpud_priv_count, cpu) > MAX_CPU_FILES) {
- pr_err("Register files count %d exceeds limit %d\n",
- per_cpu(cpud_priv_count, cpu), MAX_CPU_FILES);
- per_cpu(cpud_priv_count, cpu) = MAX_CPU_FILES;
- err = -ENFILE;
- }
- if (err)
- return err;
- }
-
- return err;
-}
-
-static int __init cpu_debug_init(void)
-{
- cpu_debugfs_dir = debugfs_create_dir("cpu", arch_debugfs_dir);
-
- return cpu_init_cpu();
-}
-
-static void __exit cpu_debug_exit(void)
-{
- int i, cpu;
-
- if (cpu_debugfs_dir)
- debugfs_remove_recursive(cpu_debugfs_dir);
-
- for (cpu = 0; cpu < nr_cpu_ids; cpu++)
- for (i = 0; i < per_cpu(cpud_priv_count, cpu); i++)
- kfree(per_cpu(cpud_priv_arr[i], cpu));
-}
-
-module_init(cpu_debug_init);
-module_exit(cpu_debug_exit);
-
-MODULE_AUTHOR("Jaswinder Singh Rajput");
-MODULE_DESCRIPTION("CPU Debug module");
-MODULE_LICENSE("GPL");
diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c
index cb27fd6..83e5e62 100644
--- a/arch/x86/kernel/cpuid.c
+++ b/arch/x86/kernel/cpuid.c
@@ -229,7 +229,7 @@
for_each_online_cpu(cpu)
cpuid_device_destroy(cpu);
class_destroy(cpuid_class);
- unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
+ __unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid");
unregister_hotcpu_notifier(&cpuid_class_cpu_notifier);
}
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index ba6e658..ad80a1c 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -34,6 +34,8 @@
*/
unsigned long hpet_address;
u8 hpet_blockid; /* OS timer block num */
+u8 hpet_msi_disable;
+
#ifdef CONFIG_PCI_MSI
static unsigned long hpet_num_timers;
#endif
@@ -596,6 +598,9 @@
unsigned int num_timers_used = 0;
int i;
+ if (hpet_msi_disable)
+ return;
+
if (boot_cpu_has(X86_FEATURE_ARAT))
return;
id = hpet_readl(HPET_ID);
@@ -928,6 +933,9 @@
hpet_reserve_platform_timers(hpet_readl(HPET_ID));
hpet_print_config();
+ if (hpet_msi_disable)
+ return 0;
+
if (boot_cpu_has(X86_FEATURE_ARAT))
return 0;
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c
index 37542b67..e1af7c0 100644
--- a/arch/x86/kernel/microcode_amd.c
+++ b/arch/x86/kernel/microcode_amd.c
@@ -36,9 +36,6 @@
#define UCODE_EQUIV_CPU_TABLE_TYPE 0x00000000
#define UCODE_UCODE_TYPE 0x00000001
-const struct firmware *firmware;
-static int supported_cpu;
-
struct equiv_cpu_entry {
u32 installed_cpu;
u32 fixed_errata_mask;
@@ -77,12 +74,15 @@
static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig)
{
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
u32 dummy;
- if (!supported_cpu)
- return -1;
-
memset(csig, 0, sizeof(*csig));
+ if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) {
+ pr_warning("microcode: CPU%d: AMD CPU family 0x%x not "
+ "supported\n", cpu, c->x86);
+ return -1;
+ }
rdmsr(MSR_AMD64_PATCH_LEVEL, csig->rev, dummy);
pr_info("CPU%d: patch_level=0x%x\n", cpu, csig->rev);
return 0;
@@ -294,10 +294,14 @@
static enum ucode_state request_microcode_fw(int cpu, struct device *device)
{
+ const char *fw_name = "amd-ucode/microcode_amd.bin";
+ const struct firmware *firmware;
enum ucode_state ret;
- if (firmware == NULL)
+ if (request_firmware(&firmware, fw_name, device)) {
+ printk(KERN_ERR "microcode: failed to load file %s\n", fw_name);
return UCODE_NFOUND;
+ }
if (*(u32 *)firmware->data != UCODE_MAGIC) {
pr_err("invalid UCODE_MAGIC (0x%08x)\n",
@@ -307,6 +311,8 @@
ret = generic_load_microcode(cpu, firmware->data, firmware->size);
+ release_firmware(firmware);
+
return ret;
}
@@ -325,31 +331,7 @@
uci->mc = NULL;
}
-void init_microcode_amd(struct device *device)
-{
- const char *fw_name = "amd-ucode/microcode_amd.bin";
- struct cpuinfo_x86 *c = &boot_cpu_data;
-
- WARN_ON(c->x86_vendor != X86_VENDOR_AMD);
-
- if (c->x86 < 0x10) {
- pr_warning("AMD CPU family 0x%x not supported\n", c->x86);
- return;
- }
- supported_cpu = 1;
-
- if (request_firmware(&firmware, fw_name, device))
- pr_err("failed to load file %s\n", fw_name);
-}
-
-void fini_microcode_amd(void)
-{
- release_firmware(firmware);
-}
-
static struct microcode_ops microcode_amd_ops = {
- .init = init_microcode_amd,
- .fini = fini_microcode_amd,
.request_microcode_user = request_microcode_user,
.request_microcode_fw = request_microcode_fw,
.collect_cpu_info = collect_cpu_info_amd,
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c
index 0c86324..cceb5bc 100644
--- a/arch/x86/kernel/microcode_core.c
+++ b/arch/x86/kernel/microcode_core.c
@@ -521,9 +521,6 @@
return PTR_ERR(microcode_pdev);
}
- if (microcode_ops->init)
- microcode_ops->init(µcode_pdev->dev);
-
get_online_cpus();
mutex_lock(µcode_mutex);
@@ -566,9 +563,6 @@
platform_device_unregister(microcode_pdev);
- if (microcode_ops->fini)
- microcode_ops->fini();
-
microcode_ops = NULL;
pr_info("Microcode Update Driver: v" MICROCODE_VERSION " removed.\n");
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index 4bd93c9..206735a 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -285,7 +285,7 @@
for_each_online_cpu(cpu)
msr_device_destroy(cpu);
class_destroy(msr_class);
- unregister_chrdev(MSR_MAJOR, "cpu/msr");
+ __unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr");
unregister_hotcpu_notifier(&msr_class_cpu_notifier);
}
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 02c3ee0..c9b3522 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -115,18 +115,6 @@
{
struct task_struct *tsk = current;
-#ifdef CONFIG_X86_64
- if (test_tsk_thread_flag(tsk, TIF_ABI_PENDING)) {
- clear_tsk_thread_flag(tsk, TIF_ABI_PENDING);
- if (test_tsk_thread_flag(tsk, TIF_IA32)) {
- clear_tsk_thread_flag(tsk, TIF_IA32);
- } else {
- set_tsk_thread_flag(tsk, TIF_IA32);
- current_thread_info()->status |= TS_COMPAT;
- }
- }
-#endif
-
flush_ptrace_hw_breakpoint(tsk);
memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
/*
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index f9e0331..41a26a8 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -521,6 +521,17 @@
current->personality &= ~READ_IMPLIES_EXEC;
}
+void set_personality_ia32(void)
+{
+ /* inherit personality from parent */
+
+ /* Make sure to be in 32bit mode */
+ set_thread_flag(TIF_IA32);
+
+ /* Prepare the first "return" to user space */
+ current_thread_info()->status |= TS_COMPAT;
+}
+
unsigned long get_wchan(struct task_struct *p)
{
unsigned long stack;
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c
index 18093d7..12e9fea 100644
--- a/arch/x86/kernel/quirks.c
+++ b/arch/x86/kernel/quirks.c
@@ -491,6 +491,19 @@
break;
}
}
+
+/*
+ * HPET MSI on some boards (ATI SB700/SB800) has side effect on
+ * floppy DMA. Disable HPET MSI on such platforms.
+ */
+static void force_disable_hpet_msi(struct pci_dev *unused)
+{
+ hpet_msi_disable = 1;
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS,
+ force_disable_hpet_msi);
+
#endif
#if defined(CONFIG_PCI) && defined(CONFIG_NUMA)
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c
index a271241..28c6876 100644
--- a/arch/x86/mm/srat_64.c
+++ b/arch/x86/mm/srat_64.c
@@ -229,9 +229,11 @@
printk(KERN_ERR "SRAT: Hotplug zone not continuous. Partly ignored\n");
}
- if (changed)
+ if (changed) {
+ node_set(node, cpu_nodes_parsed);
printk(KERN_INFO "SRAT: hot plug zone found %Lx - %Lx\n",
nd->start, nd->end);
+ }
}
/* Callback for parsing of the Proximity Domain <-> Memory Area mappings */
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
index 564b008..39fba37 100644
--- a/arch/x86/pci/Makefile
+++ b/arch/x86/pci/Makefile
@@ -15,7 +15,7 @@
obj-y += common.o early.o
obj-y += amd_bus.o
-obj-$(CONFIG_X86_64) += bus_numa.o intel_bus.o
+obj-$(CONFIG_X86_64) += bus_numa.o
ifeq ($(CONFIG_PCI_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG
diff --git a/arch/x86/pci/intel_bus.c b/arch/x86/pci/intel_bus.c
deleted file mode 100644
index f81a2fa..0000000
--- a/arch/x86/pci/intel_bus.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * to read io range from IOH pci conf, need to do it after mmconfig is there
- */
-
-#include <linux/delay.h>
-#include <linux/dmi.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <asm/pci_x86.h>
-
-#include "bus_numa.h"
-
-static inline void print_ioh_resources(struct pci_root_info *info)
-{
- int res_num;
- int busnum;
- int i;
-
- printk(KERN_DEBUG "IOH bus: [%02x, %02x]\n",
- info->bus_min, info->bus_max);
- res_num = info->res_num;
- busnum = info->bus_min;
- for (i = 0; i < res_num; i++) {
- struct resource *res;
-
- res = &info->res[i];
- printk(KERN_DEBUG "IOH bus: %02x index %x %s: [%llx, %llx]\n",
- busnum, i,
- (res->flags & IORESOURCE_IO) ? "io port" :
- "mmio",
- res->start, res->end);
- }
-}
-
-#define IOH_LIO 0x108
-#define IOH_LMMIOL 0x10c
-#define IOH_LMMIOH 0x110
-#define IOH_LMMIOH_BASEU 0x114
-#define IOH_LMMIOH_LIMITU 0x118
-#define IOH_LCFGBUS 0x11c
-
-static void __devinit pci_root_bus_res(struct pci_dev *dev)
-{
- u16 word;
- u32 dword;
- struct pci_root_info *info;
- u16 io_base, io_end;
- u32 mmiol_base, mmiol_end;
- u64 mmioh_base, mmioh_end;
- int bus_base, bus_end;
-
- /* some sys doesn't get mmconf enabled */
- if (dev->cfg_size < 0x120)
- return;
-
- if (pci_root_num >= PCI_ROOT_NR) {
- printk(KERN_DEBUG "intel_bus.c: PCI_ROOT_NR is too small\n");
- return;
- }
-
- info = &pci_root_info[pci_root_num];
- pci_root_num++;
-
- pci_read_config_word(dev, IOH_LCFGBUS, &word);
- bus_base = (word & 0xff);
- bus_end = (word & 0xff00) >> 8;
- sprintf(info->name, "PCI Bus #%02x", bus_base);
- info->bus_min = bus_base;
- info->bus_max = bus_end;
-
- pci_read_config_word(dev, IOH_LIO, &word);
- io_base = (word & 0xf0) << (12 - 4);
- io_end = (word & 0xf000) | 0xfff;
- update_res(info, io_base, io_end, IORESOURCE_IO, 0);
-
- pci_read_config_dword(dev, IOH_LMMIOL, &dword);
- mmiol_base = (dword & 0xff00) << (24 - 8);
- mmiol_end = (dword & 0xff000000) | 0xffffff;
- update_res(info, mmiol_base, mmiol_end, IORESOURCE_MEM, 0);
-
- pci_read_config_dword(dev, IOH_LMMIOH, &dword);
- mmioh_base = ((u64)(dword & 0xfc00)) << (26 - 10);
- mmioh_end = ((u64)(dword & 0xfc000000) | 0x3ffffff);
- pci_read_config_dword(dev, IOH_LMMIOH_BASEU, &dword);
- mmioh_base |= ((u64)(dword & 0x7ffff)) << 32;
- pci_read_config_dword(dev, IOH_LMMIOH_LIMITU, &dword);
- mmioh_end |= ((u64)(dword & 0x7ffff)) << 32;
- update_res(info, mmioh_base, mmioh_end, IORESOURCE_MEM, 0);
-
- print_ioh_resources(info);
-}
-
-/* intel IOH */
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x342e, pci_root_bus_res);
diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c
index 7083bcc..5045156 100644
--- a/drivers/firewire/core-card.c
+++ b/drivers/firewire/core-card.c
@@ -57,6 +57,8 @@
static int descriptor_count;
static __be32 tmp_config_rom[256];
+/* ROM header, bus info block, root dir header, capabilities = 7 quadlets */
+static size_t config_rom_length = 1 + 4 + 1 + 1;
#define BIB_CRC(v) ((v) << 0)
#define BIB_CRC_LENGTH(v) ((v) << 16)
@@ -73,7 +75,7 @@
#define BIB_CMC ((1) << 30)
#define BIB_IMC ((1) << 31)
-static size_t generate_config_rom(struct fw_card *card, __be32 *config_rom)
+static void generate_config_rom(struct fw_card *card, __be32 *config_rom)
{
struct fw_descriptor *desc;
int i, j, k, length;
@@ -130,23 +132,30 @@
for (i = 0; i < j; i += length + 1)
length = fw_compute_block_crc(config_rom + i);
- return j;
+ WARN_ON(j != config_rom_length);
}
static void update_config_roms(void)
{
struct fw_card *card;
- size_t length;
list_for_each_entry (card, &card_list, link) {
- length = generate_config_rom(card, tmp_config_rom);
- card->driver->set_config_rom(card, tmp_config_rom, length);
+ generate_config_rom(card, tmp_config_rom);
+ card->driver->set_config_rom(card, tmp_config_rom,
+ config_rom_length);
}
}
+static size_t required_space(struct fw_descriptor *desc)
+{
+ /* descriptor + entry into root dir + optional immediate entry */
+ return desc->length + 1 + (desc->immediate > 0 ? 1 : 0);
+}
+
int fw_core_add_descriptor(struct fw_descriptor *desc)
{
size_t i;
+ int ret;
/*
* Check descriptor is valid; the length of all blocks in the
@@ -162,15 +171,21 @@
mutex_lock(&card_mutex);
- list_add_tail(&desc->link, &descriptor_list);
- descriptor_count++;
- if (desc->immediate > 0)
+ if (config_rom_length + required_space(desc) > 256) {
+ ret = -EBUSY;
+ } else {
+ list_add_tail(&desc->link, &descriptor_list);
+ config_rom_length += required_space(desc);
descriptor_count++;
- update_config_roms();
+ if (desc->immediate > 0)
+ descriptor_count++;
+ update_config_roms();
+ ret = 0;
+ }
mutex_unlock(&card_mutex);
- return 0;
+ return ret;
}
EXPORT_SYMBOL(fw_core_add_descriptor);
@@ -179,6 +194,7 @@
mutex_lock(&card_mutex);
list_del(&desc->link);
+ config_rom_length -= required_space(desc);
descriptor_count--;
if (desc->immediate > 0)
descriptor_count--;
@@ -428,7 +444,6 @@
int fw_card_add(struct fw_card *card,
u32 max_receive, u32 link_speed, u64 guid)
{
- size_t length;
int ret;
card->max_receive = max_receive;
@@ -437,8 +452,8 @@
mutex_lock(&card_mutex);
- length = generate_config_rom(card, tmp_config_rom);
- ret = card->driver->enable(card, tmp_config_rom, length);
+ generate_config_rom(card, tmp_config_rom);
+ ret = card->driver->enable(card, tmp_config_rom, config_rom_length);
if (ret == 0)
list_add_tail(&card->link, &card_list);
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index e6d63849..4eeaed5 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -35,6 +35,7 @@
#include <linux/preempt.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
+#include <linux/string.h>
#include <linux/time.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
@@ -595,13 +596,20 @@
client->device->max_speed);
}
+static inline bool is_fcp_request(struct fw_request *request)
+{
+ return request == NULL;
+}
+
static void release_request(struct client *client,
struct client_resource *resource)
{
struct inbound_transaction_resource *r = container_of(resource,
struct inbound_transaction_resource, resource);
- if (r->request)
+ if (is_fcp_request(r->request))
+ kfree(r->data);
+ else
fw_send_response(client->device->card, r->request,
RCODE_CONFLICT_ERROR);
kfree(r);
@@ -616,6 +624,7 @@
struct address_handler_resource *handler = callback_data;
struct inbound_transaction_resource *r;
struct inbound_transaction_event *e;
+ void *fcp_frame = NULL;
int ret;
r = kmalloc(sizeof(*r), GFP_ATOMIC);
@@ -627,6 +636,18 @@
r->data = payload;
r->length = length;
+ if (is_fcp_request(request)) {
+ /*
+ * FIXME: Let core-transaction.c manage a
+ * single reference-counted copy?
+ */
+ fcp_frame = kmemdup(payload, length, GFP_ATOMIC);
+ if (fcp_frame == NULL)
+ goto failed;
+
+ r->data = fcp_frame;
+ }
+
r->resource.release = release_request;
ret = add_client_resource(handler->client, &r->resource, GFP_ATOMIC);
if (ret < 0)
@@ -640,13 +661,15 @@
e->request.closure = handler->closure;
queue_event(handler->client, &e->event,
- &e->request, sizeof(e->request), payload, length);
+ &e->request, sizeof(e->request), r->data, length);
return;
failed:
kfree(r);
kfree(e);
- if (request)
+ kfree(fcp_frame);
+
+ if (!is_fcp_request(request))
fw_send_response(card, request, RCODE_CONFLICT_ERROR);
}
@@ -717,18 +740,17 @@
r = container_of(resource, struct inbound_transaction_resource,
resource);
- if (r->request) {
- if (request->length < r->length)
- r->length = request->length;
- if (copy_from_user(r->data, u64_to_uptr(request->data),
- r->length)) {
- ret = -EFAULT;
- kfree(r->request);
- goto out;
- }
- fw_send_response(client->device->card, r->request,
- request->rcode);
+ if (is_fcp_request(r->request))
+ goto out;
+
+ if (request->length < r->length)
+ r->length = request->length;
+ if (copy_from_user(r->data, u64_to_uptr(request->data), r->length)) {
+ ret = -EFAULT;
+ kfree(r->request);
+ goto out;
}
+ fw_send_response(client->device->card, r->request, request->rcode);
out:
kfree(r);
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index a61571c..2345d41 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -2420,6 +2420,7 @@
#define PCI_VENDOR_ID_AGERE PCI_VENDOR_ID_ATT
#define PCI_DEVICE_ID_AGERE_FW643 0x5901
+#define PCI_DEVICE_ID_TI_TSB43AB23 0x8024
static int __devinit pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
@@ -2488,7 +2489,8 @@
#if !defined(CONFIG_X86_32)
/* dual-buffer mode is broken with descriptor addresses above 2G */
if (dev->vendor == PCI_VENDOR_ID_TI &&
- dev->device == PCI_DEVICE_ID_TI_TSB43AB22)
+ (dev->device == PCI_DEVICE_ID_TI_TSB43AB22 ||
+ dev->device == PCI_DEVICE_ID_TI_TSB43AB23))
ohci->use_dualbuffer = false;
#endif
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index e9dbb48..8bf3770 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -142,19 +142,6 @@
if (IS_ERR(obj->filp))
goto free;
- /* Basically we want to disable the OOM killer and handle ENOMEM
- * ourselves by sacrificing pages from cached buffers.
- * XXX shmem_file_[gs]et_gfp_mask()
- */
- mapping_set_gfp_mask(obj->filp->f_path.dentry->d_inode->i_mapping,
- GFP_HIGHUSER |
- __GFP_COLD |
- __GFP_FS |
- __GFP_RECLAIMABLE |
- __GFP_NORETRY |
- __GFP_NOWARN |
- __GFP_NOMEMALLOC);
-
kref_init(&obj->refcount);
kref_init(&obj->handlecount);
obj->size = size;
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 9c9998c..a894ade 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -290,7 +290,7 @@
list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) {
obj = obj_priv->obj;
if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) {
- ret = i915_gem_object_get_pages(obj);
+ ret = i915_gem_object_get_pages(obj, 0);
if (ret) {
DRM_ERROR("Failed to get pages: %d\n", ret);
spin_unlock(&dev_priv->mm.active_list_lock);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 2c16694..aaf934d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -872,7 +872,7 @@
void i915_gem_detach_phys_object(struct drm_device *dev,
struct drm_gem_object *obj);
void i915_gem_free_all_phys_object(struct drm_device *dev);
-int i915_gem_object_get_pages(struct drm_gem_object *obj);
+int i915_gem_object_get_pages(struct drm_gem_object *obj, gfp_t gfpmask);
void i915_gem_object_put_pages(struct drm_gem_object *obj);
void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv);
void i915_gem_object_flush_write_domain(struct drm_gem_object *obj);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 0c67924..dda787a 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -277,7 +277,7 @@
mutex_lock(&dev->struct_mutex);
- ret = i915_gem_object_get_pages(obj);
+ ret = i915_gem_object_get_pages(obj, 0);
if (ret != 0)
goto fail_unlock;
@@ -321,40 +321,24 @@
return ret;
}
-static inline gfp_t
-i915_gem_object_get_page_gfp_mask (struct drm_gem_object *obj)
-{
- return mapping_gfp_mask(obj->filp->f_path.dentry->d_inode->i_mapping);
-}
-
-static inline void
-i915_gem_object_set_page_gfp_mask (struct drm_gem_object *obj, gfp_t gfp)
-{
- mapping_set_gfp_mask(obj->filp->f_path.dentry->d_inode->i_mapping, gfp);
-}
-
static int
i915_gem_object_get_pages_or_evict(struct drm_gem_object *obj)
{
int ret;
- ret = i915_gem_object_get_pages(obj);
+ ret = i915_gem_object_get_pages(obj, __GFP_NORETRY | __GFP_NOWARN);
/* If we've insufficient memory to map in the pages, attempt
* to make some space by throwing out some old buffers.
*/
if (ret == -ENOMEM) {
struct drm_device *dev = obj->dev;
- gfp_t gfp;
ret = i915_gem_evict_something(dev, obj->size);
if (ret)
return ret;
- gfp = i915_gem_object_get_page_gfp_mask(obj);
- i915_gem_object_set_page_gfp_mask(obj, gfp & ~__GFP_NORETRY);
- ret = i915_gem_object_get_pages(obj);
- i915_gem_object_set_page_gfp_mask (obj, gfp);
+ ret = i915_gem_object_get_pages(obj, 0);
}
return ret;
@@ -790,7 +774,7 @@
mutex_lock(&dev->struct_mutex);
- ret = i915_gem_object_get_pages(obj);
+ ret = i915_gem_object_get_pages(obj, 0);
if (ret != 0)
goto fail_unlock;
@@ -2230,7 +2214,8 @@
}
int
-i915_gem_object_get_pages(struct drm_gem_object *obj)
+i915_gem_object_get_pages(struct drm_gem_object *obj,
+ gfp_t gfpmask)
{
struct drm_i915_gem_object *obj_priv = obj->driver_private;
int page_count, i;
@@ -2256,7 +2241,10 @@
inode = obj->filp->f_path.dentry->d_inode;
mapping = inode->i_mapping;
for (i = 0; i < page_count; i++) {
- page = read_mapping_page(mapping, i, NULL);
+ page = read_cache_page_gfp(mapping, i,
+ mapping_gfp_mask (mapping) |
+ __GFP_COLD |
+ gfpmask);
if (IS_ERR(page)) {
ret = PTR_ERR(page);
i915_gem_object_put_pages(obj);
@@ -2579,7 +2567,7 @@
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj_priv = obj->driver_private;
struct drm_mm_node *free_space;
- bool retry_alloc = false;
+ gfp_t gfpmask = __GFP_NORETRY | __GFP_NOWARN;
int ret;
if (obj_priv->madv != I915_MADV_WILLNEED) {
@@ -2623,15 +2611,7 @@
DRM_INFO("Binding object of size %zd at 0x%08x\n",
obj->size, obj_priv->gtt_offset);
#endif
- if (retry_alloc) {
- i915_gem_object_set_page_gfp_mask (obj,
- i915_gem_object_get_page_gfp_mask (obj) & ~__GFP_NORETRY);
- }
- ret = i915_gem_object_get_pages(obj);
- if (retry_alloc) {
- i915_gem_object_set_page_gfp_mask (obj,
- i915_gem_object_get_page_gfp_mask (obj) | __GFP_NORETRY);
- }
+ ret = i915_gem_object_get_pages(obj, gfpmask);
if (ret) {
drm_mm_put_block(obj_priv->gtt_space);
obj_priv->gtt_space = NULL;
@@ -2641,9 +2621,9 @@
ret = i915_gem_evict_something(dev, obj->size);
if (ret) {
/* now try to shrink everyone else */
- if (! retry_alloc) {
- retry_alloc = true;
- goto search_free;
+ if (gfpmask) {
+ gfpmask = 0;
+ goto search_free;
}
return ret;
@@ -4946,7 +4926,7 @@
if (!obj_priv->phys_obj)
return;
- ret = i915_gem_object_get_pages(obj);
+ ret = i915_gem_object_get_pages(obj, 0);
if (ret)
goto out;
@@ -5004,7 +4984,7 @@
obj_priv->phys_obj = dev_priv->mm.phys_objs[id - 1];
obj_priv->phys_obj->cur_obj = obj;
- ret = i915_gem_object_get_pages(obj);
+ ret = i915_gem_object_get_pages(obj, 0);
if (ret) {
DRM_ERROR("failed to get page list\n");
goto out;
diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c
index b368406..100da85 100644
--- a/drivers/infiniband/hw/ipath/ipath_fs.c
+++ b/drivers/infiniband/hw/ipath/ipath_fs.c
@@ -346,10 +346,8 @@
list_for_each_entry_safe(dd, tmp, &ipath_dev_list, ipath_list) {
spin_unlock_irqrestore(&ipath_devs_lock, flags);
ret = create_device_files(sb, dd);
- if (ret) {
- deactivate_locked_super(sb);
+ if (ret)
goto bail;
- }
spin_lock_irqsave(&ipath_devs_lock, flags);
}
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 30b503b..86cb2d2 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -46,6 +46,7 @@
ABS_MT_TOOL_TYPE,
ABS_MT_BLOB_ID,
ABS_MT_TRACKING_ID,
+ ABS_MT_PRESSURE,
0
};
static unsigned long input_abs_bypass[BITS_TO_LONGS(ABS_CNT)];
diff --git a/drivers/input/misc/winbond-cir.c b/drivers/input/misc/winbond-cir.c
index 33309fe..c8f5a9a 100644
--- a/drivers/input/misc/winbond-cir.c
+++ b/drivers/input/misc/winbond-cir.c
@@ -768,7 +768,7 @@
return;
}
- dev_info(dev, "IR-RC6 ad 0x%02X cm 0x%02X cu 0x%04X "
+ dev_dbg(dev, "IR-RC6 ad 0x%02X cm 0x%02X cu 0x%04X "
"toggle %u mode %u scan 0x%08X\n",
address,
command,
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index 6d7aa10..7c1d7d4 100644
--- a/drivers/input/mouse/lifebook.c
+++ b/drivers/input/mouse/lifebook.c
@@ -53,6 +53,12 @@
{
/* LifeBook B */
.matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Lifebook B Series"),
+ },
+ },
+ {
+ /* LifeBook B */
+ .matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B Series"),
},
},
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c
index c21e6d3..794d070 100644
--- a/drivers/input/touchscreen/ad7879.c
+++ b/drivers/input/touchscreen/ad7879.c
@@ -47,6 +47,7 @@
#include <linux/workqueue.h>
#include <linux/spi/spi.h>
#include <linux/i2c.h>
+#include <linux/gpio.h>
#include <linux/spi/ad7879.h>
@@ -132,7 +133,9 @@
struct input_dev *input;
struct work_struct work;
struct timer_list timer;
-
+#ifdef CONFIG_GPIOLIB
+ struct gpio_chip gc;
+#endif
struct mutex mutex;
unsigned disabled:1; /* P: mutex */
@@ -150,11 +153,9 @@
u8 median;
u16 x_plate_ohms;
u16 pressure_max;
- u16 gpio_init;
u16 cmd_crtl1;
u16 cmd_crtl2;
u16 cmd_crtl3;
- unsigned gpio:1;
};
static int ad7879_read(bus_device *, u8);
@@ -237,24 +238,6 @@
static void ad7879_setup(struct ad7879 *ts)
{
- ts->cmd_crtl3 = AD7879_YPLUS_BIT |
- AD7879_XPLUS_BIT |
- AD7879_Z2_BIT |
- AD7879_Z1_BIT |
- AD7879_TEMPMASK_BIT |
- AD7879_AUXVBATMASK_BIT |
- AD7879_GPIOALERTMASK_BIT;
-
- ts->cmd_crtl2 = AD7879_PM(AD7879_PM_DYN) | AD7879_DFR |
- AD7879_AVG(ts->averaging) |
- AD7879_MFS(ts->median) |
- AD7879_FCD(ts->first_conversion_delay) |
- ts->gpio_init;
-
- ts->cmd_crtl1 = AD7879_MODE_INT | AD7879_MODE_SEQ1 |
- AD7879_ACQ(ts->acquisition_time) |
- AD7879_TMR(ts->pen_down_acc_interval);
-
ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2);
ad7879_write(ts->bus, AD7879_REG_CTRL3, ts->cmd_crtl3);
ad7879_write(ts->bus, AD7879_REG_CTRL1, ts->cmd_crtl1);
@@ -324,42 +307,8 @@
static DEVICE_ATTR(disable, 0664, ad7879_disable_show, ad7879_disable_store);
-static ssize_t ad7879_gpio_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct ad7879 *ts = dev_get_drvdata(dev);
-
- return sprintf(buf, "%u\n", ts->gpio);
-}
-
-static ssize_t ad7879_gpio_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct ad7879 *ts = dev_get_drvdata(dev);
- unsigned long val;
- int error;
-
- error = strict_strtoul(buf, 10, &val);
- if (error)
- return error;
-
- mutex_lock(&ts->mutex);
- ts->gpio = !!val;
- error = ad7879_write(ts->bus, AD7879_REG_CTRL2,
- ts->gpio ?
- ts->cmd_crtl2 & ~AD7879_GPIO_DATA :
- ts->cmd_crtl2 | AD7879_GPIO_DATA);
- mutex_unlock(&ts->mutex);
-
- return error ? : count;
-}
-
-static DEVICE_ATTR(gpio, 0664, ad7879_gpio_show, ad7879_gpio_store);
-
static struct attribute *ad7879_attributes[] = {
&dev_attr_disable.attr,
- &dev_attr_gpio.attr,
NULL
};
@@ -367,6 +316,124 @@
.attrs = ad7879_attributes,
};
+#ifdef CONFIG_GPIOLIB
+static int ad7879_gpio_direction_input(struct gpio_chip *chip,
+ unsigned gpio)
+{
+ struct ad7879 *ts = container_of(chip, struct ad7879, gc);
+ int err;
+
+ mutex_lock(&ts->mutex);
+ ts->cmd_crtl2 |= AD7879_GPIO_EN | AD7879_GPIODIR | AD7879_GPIOPOL;
+ err = ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2);
+ mutex_unlock(&ts->mutex);
+
+ return err;
+}
+
+static int ad7879_gpio_direction_output(struct gpio_chip *chip,
+ unsigned gpio, int level)
+{
+ struct ad7879 *ts = container_of(chip, struct ad7879, gc);
+ int err;
+
+ mutex_lock(&ts->mutex);
+ ts->cmd_crtl2 &= ~AD7879_GPIODIR;
+ ts->cmd_crtl2 |= AD7879_GPIO_EN | AD7879_GPIOPOL;
+ if (level)
+ ts->cmd_crtl2 |= AD7879_GPIO_DATA;
+ else
+ ts->cmd_crtl2 &= ~AD7879_GPIO_DATA;
+
+ err = ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2);
+ mutex_unlock(&ts->mutex);
+
+ return err;
+}
+
+static int ad7879_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
+{
+ struct ad7879 *ts = container_of(chip, struct ad7879, gc);
+ u16 val;
+
+ mutex_lock(&ts->mutex);
+ val = ad7879_read(ts->bus, AD7879_REG_CTRL2);
+ mutex_unlock(&ts->mutex);
+
+ return !!(val & AD7879_GPIO_DATA);
+}
+
+static void ad7879_gpio_set_value(struct gpio_chip *chip,
+ unsigned gpio, int value)
+{
+ struct ad7879 *ts = container_of(chip, struct ad7879, gc);
+
+ mutex_lock(&ts->mutex);
+ if (value)
+ ts->cmd_crtl2 |= AD7879_GPIO_DATA;
+ else
+ ts->cmd_crtl2 &= ~AD7879_GPIO_DATA;
+
+ ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2);
+ mutex_unlock(&ts->mutex);
+}
+
+static int __devinit ad7879_gpio_add(struct device *dev)
+{
+ struct ad7879 *ts = dev_get_drvdata(dev);
+ struct ad7879_platform_data *pdata = dev->platform_data;
+ int ret = 0;
+
+ if (pdata->gpio_export) {
+ ts->gc.direction_input = ad7879_gpio_direction_input;
+ ts->gc.direction_output = ad7879_gpio_direction_output;
+ ts->gc.get = ad7879_gpio_get_value;
+ ts->gc.set = ad7879_gpio_set_value;
+ ts->gc.can_sleep = 1;
+ ts->gc.base = pdata->gpio_base;
+ ts->gc.ngpio = 1;
+ ts->gc.label = "AD7879-GPIO";
+ ts->gc.owner = THIS_MODULE;
+ ts->gc.dev = dev;
+
+ ret = gpiochip_add(&ts->gc);
+ if (ret)
+ dev_err(dev, "failed to register gpio %d\n",
+ ts->gc.base);
+ }
+
+ return ret;
+}
+
+/*
+ * We mark ad7879_gpio_remove inline so there is a chance the code
+ * gets discarded when not needed. We can't do __devinit/__devexit
+ * markup since it is used in both probe and remove methods.
+ */
+static inline void ad7879_gpio_remove(struct device *dev)
+{
+ struct ad7879 *ts = dev_get_drvdata(dev);
+ struct ad7879_platform_data *pdata = dev->platform_data;
+ int ret;
+
+ if (pdata->gpio_export) {
+ ret = gpiochip_remove(&ts->gc);
+ if (ret)
+ dev_err(dev, "failed to remove gpio %d\n",
+ ts->gc.base);
+ }
+}
+#else
+static inline int ad7879_gpio_add(struct device *dev)
+{
+ return 0;
+}
+
+static inline void ad7879_gpio_remove(struct device *dev)
+{
+}
+#endif
+
static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts)
{
struct input_dev *input_dev;
@@ -403,12 +470,6 @@
ts->pen_down_acc_interval = pdata->pen_down_acc_interval;
ts->median = pdata->median;
- if (pdata->gpio_output)
- ts->gpio_init = AD7879_GPIO_EN |
- (pdata->gpio_default ? 0 : AD7879_GPIO_DATA);
- else
- ts->gpio_init = AD7879_GPIO_EN | AD7879_GPIODIR;
-
snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&bus->dev));
input_dev->name = "AD7879 Touchscreen";
@@ -446,6 +507,23 @@
goto err_free_mem;
}
+ ts->cmd_crtl3 = AD7879_YPLUS_BIT |
+ AD7879_XPLUS_BIT |
+ AD7879_Z2_BIT |
+ AD7879_Z1_BIT |
+ AD7879_TEMPMASK_BIT |
+ AD7879_AUXVBATMASK_BIT |
+ AD7879_GPIOALERTMASK_BIT;
+
+ ts->cmd_crtl2 = AD7879_PM(AD7879_PM_DYN) | AD7879_DFR |
+ AD7879_AVG(ts->averaging) |
+ AD7879_MFS(ts->median) |
+ AD7879_FCD(ts->first_conversion_delay);
+
+ ts->cmd_crtl1 = AD7879_MODE_INT | AD7879_MODE_SEQ1 |
+ AD7879_ACQ(ts->acquisition_time) |
+ AD7879_TMR(ts->pen_down_acc_interval);
+
ad7879_setup(ts);
err = request_irq(bus->irq, ad7879_irq,
@@ -460,15 +538,21 @@
if (err)
goto err_free_irq;
- err = input_register_device(input_dev);
+ err = ad7879_gpio_add(&bus->dev);
if (err)
goto err_remove_attr;
+ err = input_register_device(input_dev);
+ if (err)
+ goto err_remove_gpio;
+
dev_info(&bus->dev, "Rev.%d touchscreen, irq %d\n",
revid >> 8, bus->irq);
return 0;
+err_remove_gpio:
+ ad7879_gpio_remove(&bus->dev);
err_remove_attr:
sysfs_remove_group(&bus->dev.kobj, &ad7879_attr_group);
err_free_irq:
@@ -481,6 +565,7 @@
static int __devexit ad7879_destroy(bus_device *bus, struct ad7879 *ts)
{
+ ad7879_gpio_remove(&bus->dev);
ad7879_disable(ts);
sysfs_remove_group(&ts->bus->dev.kobj, &ad7879_attr_group);
free_irq(ts->bus->irq, ts);
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 85bc6a6..44d2037 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -4330,6 +4330,8 @@
if (ioc->bus_type == SPI)
num_chain *= MPT_SCSI_CAN_QUEUE;
+ else if (ioc->bus_type == SAS)
+ num_chain *= MPT_SAS_CAN_QUEUE;
else
num_chain *= MPT_FC_CAN_QUEUE;
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 8f0d184..e09eb48 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -3,7 +3,7 @@
#
obj-$(CONFIG_MFD_SM501) += sm501.o
-obj-$(CONFIG_MFD_ASIC3) += asic3.o
+obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o
obj-$(CONFIG_MFD_SH_MOBILE_SDHI) += sh_mobile_sdhi.o
obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index f237ddb..111ea41 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -853,7 +853,6 @@
break;
}
- req.name[req.name_len] = '\0';
err = verify_mkvol_req(ubi, &req);
if (err)
break;
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c
index 8c30a95..223052b 100644
--- a/drivers/pci/pcie/aer/aer_inject.c
+++ b/drivers/pci/pcie/aer/aer_inject.c
@@ -321,7 +321,7 @@
unsigned long flags;
unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn);
int pos_cap_err, rp_pos_cap_err;
- u32 sever, mask;
+ u32 sever, cor_mask, uncor_mask;
int ret = 0;
dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn);
@@ -339,6 +339,9 @@
goto out_put;
}
pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever);
+ pci_read_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK, &cor_mask);
+ pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK,
+ &uncor_mask);
rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR);
if (!rp_pos_cap_err) {
@@ -374,17 +377,14 @@
err->header_log2 = einj->header_log2;
err->header_log3 = einj->header_log3;
- pci_read_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK, &mask);
- if (einj->cor_status && !(einj->cor_status & ~mask)) {
+ if (einj->cor_status && !(einj->cor_status & ~cor_mask)) {
ret = -EINVAL;
printk(KERN_WARNING "The correctable error(s) is masked "
"by device\n");
spin_unlock_irqrestore(&inject_lock, flags);
goto out_put;
}
-
- pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK, &mask);
- if (einj->uncor_status && !(einj->uncor_status & ~mask)) {
+ if (einj->uncor_status && !(einj->uncor_status & ~uncor_mask)) {
ret = -EINVAL;
printk(KERN_WARNING "The uncorrectable error(s) is masked "
"by device\n");
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index fdb2e7c..5905936 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -1004,8 +1004,8 @@
if (device == NULL ||
device != dasd_device_from_cdev_locked(cdev) ||
strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
- DBF_DEV_EVENT(DBF_DEBUG, device, "invalid device in request: "
- "bus_id %s", dev_name(&cdev->dev));
+ DBF_EVENT_DEVID(DBF_DEBUG, cdev, "%s",
+ "invalid device in request");
return;
}
@@ -1078,8 +1078,8 @@
device = (struct dasd_device *) cqr->startdev;
if (!device ||
strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
- DBF_DEV_EVENT(DBF_DEBUG, device, "invalid device in request: "
- "bus_id %s", dev_name(&cdev->dev));
+ DBF_EVENT_DEVID(DBF_DEBUG, cdev, "%s",
+ "invalid device in request");
return;
}
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 1c500c4..1cca21a 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -3033,7 +3033,7 @@
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" in req: %p CS: 0x%02X DS: 0x%02X CC: 0x%02X RC: %d\n",
req, scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw),
- scsw_cc(&irb->scsw), req->intrc);
+ scsw_cc(&irb->scsw), req ? req->intrc : 0);
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" device %s: Failing CCW: %p\n",
dev_name(&device->cdev->dev),
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index fc7b30b..7039d9c 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -260,7 +260,7 @@
struct ccw_dev_id dev_id;
base = block->base;
- if (!base->discipline->fill_info)
+ if (!base->discipline || !base->discipline->fill_info)
return -EINVAL;
dasd_info = kzalloc(sizeof(struct dasd_information2_t), GFP_KERNEL);
@@ -303,10 +303,7 @@
dasd_info->features |=
((base->features & DASD_FEATURE_READONLY) != 0);
- if (base->discipline)
- memcpy(dasd_info->type, base->discipline->name, 4);
- else
- memcpy(dasd_info->type, "none", 4);
+ memcpy(dasd_info->type, base->discipline->name, 4);
if (block->request_queue->request_fn) {
struct list_head *l;
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
index 6315fbd..71f95f5 100644
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -72,7 +72,7 @@
/* Print device number. */
seq_printf(m, "%s", dev_name(&device->cdev->dev));
/* Print discipline string. */
- if (device != NULL && device->discipline != NULL)
+ if (device->discipline != NULL)
seq_printf(m, "(%s)", device->discipline->name);
else
seq_printf(m, "(none)");
@@ -92,10 +92,7 @@
substr = (device->features & DASD_FEATURE_READONLY) ? "(ro)" : " ";
seq_printf(m, "%4s: ", substr);
/* Print device status information. */
- switch ((device != NULL) ? device->state : -1) {
- case -1:
- seq_printf(m, "unknown");
- break;
+ switch (device->state) {
case DASD_STATE_NEW:
seq_printf(m, "new");
break;
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index b9d2a00..3796ffd 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -495,6 +495,10 @@
if (tty->driver_data == NULL)
return -ENOMEM;
tty->low_latency = 0;
+ if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
+ tty->winsize.ws_row = 24;
+ tty->winsize.ws_col = 80;
+ }
}
return 0;
}
diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c
index a23726a..142f72a 100644
--- a/drivers/s390/crypto/zcrypt_pcicc.c
+++ b/drivers/s390/crypto/zcrypt_pcicc.c
@@ -373,6 +373,8 @@
zdev->max_mod_size = PCICC_MAX_MOD_SIZE_OLD;
return -EAGAIN;
}
+ if (service_rc == 8 && service_rs == 72)
+ return -EINVAL;
zdev->online = 0;
return -EAGAIN; /* repeat the request on a different device. */
}
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
index 79c1205..68f3e62 100644
--- a/drivers/s390/crypto/zcrypt_pcixcc.c
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -470,6 +470,8 @@
}
if (service_rc == 12 && service_rs == 769)
return -EINVAL;
+ if (service_rc == 8 && service_rs == 72)
+ return -EINVAL;
zdev->online = 0;
return -EAGAIN; /* repeat the request on a different device. */
}
diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c
index f932400..0eb6eef 100644
--- a/drivers/s390/scsi/zfcp_cfdc.c
+++ b/drivers/s390/scsi/zfcp_cfdc.c
@@ -12,6 +12,7 @@
#include <linux/types.h>
#include <linux/miscdevice.h>
+#include <asm/compat.h>
#include <asm/ccwdev.h>
#include "zfcp_def.h"
#include "zfcp_ext.h"
@@ -163,7 +164,7 @@
}
static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
- unsigned long buffer)
+ unsigned long arg)
{
struct zfcp_cfdc_data *data;
struct zfcp_cfdc_data __user *data_user;
@@ -175,7 +176,11 @@
if (command != ZFCP_CFDC_IOC)
return -ENOTTY;
- data_user = (void __user *) buffer;
+ if (is_compat_task())
+ data_user = compat_ptr(arg);
+ else
+ data_user = (void __user *)arg;
+
if (!data_user)
return -EINVAL;
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index 8445095..7369c89 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -327,7 +327,7 @@
break;
zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd);
zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial);
- p += sprintf(*p, "\n");
+ *p += sprintf(*p, "\n");
break;
case FSF_QTCB_OPEN_PORT_WITH_DID:
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 03dec83..66bdb34 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -108,6 +108,7 @@
extern int zfcp_fc_gs_setup(struct zfcp_adapter *);
extern void zfcp_fc_gs_destroy(struct zfcp_adapter *);
extern int zfcp_fc_exec_bsg_job(struct fc_bsg_job *);
+extern int zfcp_fc_timeout_bsg_job(struct fc_bsg_job *);
/* zfcp_fsf.c */
extern int zfcp_fsf_open_port(struct zfcp_erp_action *);
@@ -129,9 +130,9 @@
extern int zfcp_fsf_status_read(struct zfcp_qdio *);
extern int zfcp_status_read_refill(struct zfcp_adapter *adapter);
extern int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *, struct zfcp_fsf_ct_els *,
- mempool_t *);
+ mempool_t *, unsigned int);
extern int zfcp_fsf_send_els(struct zfcp_adapter *, u32,
- struct zfcp_fsf_ct_els *);
+ struct zfcp_fsf_ct_els *, unsigned int);
extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *,
struct scsi_cmnd *);
extern void zfcp_fsf_req_free(struct zfcp_fsf_req *);
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index ac5e3b7..0f7b493 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -258,7 +258,8 @@
gid_pn->gid_pn_req.gid_pn.fn_wwpn = port->wwpn;
ret = zfcp_fsf_send_ct(&adapter->gs->ds, &gid_pn->ct,
- adapter->pool.gid_pn_req);
+ adapter->pool.gid_pn_req,
+ ZFCP_FC_CTELS_TMO);
if (!ret) {
wait_for_completion(&completion);
zfcp_fc_ns_gid_pn_eval(gid_pn);
@@ -421,7 +422,8 @@
hton24(adisc->adisc_req.adisc_port_id,
fc_host_port_id(adapter->scsi_host));
- ret = zfcp_fsf_send_els(adapter, port->d_id, &adisc->els);
+ ret = zfcp_fsf_send_els(adapter, port->d_id, &adisc->els,
+ ZFCP_FC_CTELS_TMO);
if (ret)
kmem_cache_free(zfcp_data.adisc_cache, adisc);
@@ -532,7 +534,8 @@
ct->req = &gpn_ft->sg_req;
ct->resp = gpn_ft->sg_resp;
- ret = zfcp_fsf_send_ct(&adapter->gs->ds, ct, NULL);
+ ret = zfcp_fsf_send_ct(&adapter->gs->ds, ct, NULL,
+ ZFCP_FC_CTELS_TMO);
if (!ret)
wait_for_completion(&completion);
return ret;
@@ -677,6 +680,44 @@
job->job_done(job);
}
+static struct zfcp_fc_wka_port *zfcp_fc_job_wka_port(struct fc_bsg_job *job)
+{
+ u32 preamble_word1;
+ u8 gs_type;
+ struct zfcp_adapter *adapter;
+
+ preamble_word1 = job->request->rqst_data.r_ct.preamble_word1;
+ gs_type = (preamble_word1 & 0xff000000) >> 24;
+
+ adapter = (struct zfcp_adapter *) job->shost->hostdata[0];
+
+ switch (gs_type) {
+ case FC_FST_ALIAS:
+ return &adapter->gs->as;
+ case FC_FST_MGMT:
+ return &adapter->gs->ms;
+ case FC_FST_TIME:
+ return &adapter->gs->ts;
+ break;
+ case FC_FST_DIR:
+ return &adapter->gs->ds;
+ break;
+ default:
+ return NULL;
+ }
+}
+
+static void zfcp_fc_ct_job_handler(void *data)
+{
+ struct fc_bsg_job *job = data;
+ struct zfcp_fc_wka_port *wka_port;
+
+ wka_port = zfcp_fc_job_wka_port(job);
+ zfcp_fc_wka_port_put(wka_port);
+
+ zfcp_fc_ct_els_job_handler(data);
+}
+
static int zfcp_fc_exec_els_job(struct fc_bsg_job *job,
struct zfcp_adapter *adapter)
{
@@ -695,43 +736,27 @@
} else
d_id = ntoh24(job->request->rqst_data.h_els.port_id);
- return zfcp_fsf_send_els(adapter, d_id, els);
+ els->handler = zfcp_fc_ct_els_job_handler;
+ return zfcp_fsf_send_els(adapter, d_id, els, job->req->timeout / HZ);
}
static int zfcp_fc_exec_ct_job(struct fc_bsg_job *job,
struct zfcp_adapter *adapter)
{
int ret;
- u8 gs_type;
struct zfcp_fsf_ct_els *ct = job->dd_data;
struct zfcp_fc_wka_port *wka_port;
- u32 preamble_word1;
- preamble_word1 = job->request->rqst_data.r_ct.preamble_word1;
- gs_type = (preamble_word1 & 0xff000000) >> 24;
-
- switch (gs_type) {
- case FC_FST_ALIAS:
- wka_port = &adapter->gs->as;
- break;
- case FC_FST_MGMT:
- wka_port = &adapter->gs->ms;
- break;
- case FC_FST_TIME:
- wka_port = &adapter->gs->ts;
- break;
- case FC_FST_DIR:
- wka_port = &adapter->gs->ds;
- break;
- default:
- return -EINVAL; /* no such service */
- }
+ wka_port = zfcp_fc_job_wka_port(job);
+ if (!wka_port)
+ return -EINVAL;
ret = zfcp_fc_wka_port_get(wka_port);
if (ret)
return ret;
- ret = zfcp_fsf_send_ct(wka_port, ct, NULL);
+ ct->handler = zfcp_fc_ct_job_handler;
+ ret = zfcp_fsf_send_ct(wka_port, ct, NULL, job->req->timeout / HZ);
if (ret)
zfcp_fc_wka_port_put(wka_port);
@@ -752,7 +777,6 @@
ct_els->req = job->request_payload.sg_list;
ct_els->resp = job->reply_payload.sg_list;
- ct_els->handler = zfcp_fc_ct_els_job_handler;
ct_els->handler_data = job;
switch (job->request->msgcode) {
@@ -767,6 +791,12 @@
}
}
+int zfcp_fc_timeout_bsg_job(struct fc_bsg_job *job)
+{
+ /* hardware tracks timeout, reset bsg timeout to not interfere */
+ return -EAGAIN;
+}
+
int zfcp_fc_gs_setup(struct zfcp_adapter *adapter)
{
struct zfcp_fc_wka_ports *wka_ports;
diff --git a/drivers/s390/scsi/zfcp_fc.h b/drivers/s390/scsi/zfcp_fc.h
index cb2a366..0747b08 100644
--- a/drivers/s390/scsi/zfcp_fc.h
+++ b/drivers/s390/scsi/zfcp_fc.h
@@ -27,6 +27,8 @@
#define ZFCP_FC_GPN_FT_MAX_ENT (ZFCP_FC_GPN_FT_NUM_BUFS * \
(ZFCP_FC_GPN_FT_ENT_PAGE + 1))
+#define ZFCP_FC_CTELS_TMO (2 * FC_DEF_R_A_TOV / 1000)
+
/**
* struct zfcp_fc_gid_pn_req - container for ct header plus gid_pn request
* @ct_hdr: FC GS common transport header
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 482dcd9..e8fb4d9 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -1068,20 +1068,20 @@
static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req,
struct scatterlist *sg_req,
struct scatterlist *sg_resp,
- int max_sbals)
+ int max_sbals, unsigned int timeout)
{
int ret;
- unsigned int fcp_chan_timeout;
ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp, max_sbals);
if (ret)
return ret;
/* common settings for ct/gs and els requests */
- fcp_chan_timeout = 2 * FC_DEF_R_A_TOV / 1000;
+ if (timeout > 255)
+ timeout = 255; /* max value accepted by hardware */
req->qtcb->bottom.support.service_class = FSF_CLASS_3;
- req->qtcb->bottom.support.timeout = fcp_chan_timeout;
- zfcp_fsf_start_timer(req, (fcp_chan_timeout + 10) * HZ);
+ req->qtcb->bottom.support.timeout = timeout;
+ zfcp_fsf_start_timer(req, (timeout + 10) * HZ);
return 0;
}
@@ -1092,7 +1092,8 @@
* @pool: if non-null this mempool is used to allocate struct zfcp_fsf_req
*/
int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port,
- struct zfcp_fsf_ct_els *ct, mempool_t *pool)
+ struct zfcp_fsf_ct_els *ct, mempool_t *pool,
+ unsigned int timeout)
{
struct zfcp_qdio *qdio = wka_port->adapter->qdio;
struct zfcp_fsf_req *req;
@@ -1111,7 +1112,7 @@
req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
ret = zfcp_fsf_setup_ct_els(req, ct->req, ct->resp,
- FSF_MAX_SBALS_PER_REQ);
+ FSF_MAX_SBALS_PER_REQ, timeout);
if (ret)
goto failed_send;
@@ -1188,7 +1189,7 @@
* @els: pointer to struct zfcp_send_els with data for the command
*/
int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id,
- struct zfcp_fsf_ct_els *els)
+ struct zfcp_fsf_ct_els *els, unsigned int timeout)
{
struct zfcp_fsf_req *req;
struct zfcp_qdio *qdio = adapter->qdio;
@@ -1206,7 +1207,7 @@
}
req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
- ret = zfcp_fsf_setup_ct_els(req, els->req, els->resp, 2);
+ ret = zfcp_fsf_setup_ct_els(req, els->req, els->resp, 2, timeout);
if (ret)
goto failed_send;
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 771cc53..8e6fc68 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -652,6 +652,7 @@
.show_host_port_state = 1,
.show_host_active_fc4s = 1,
.bsg_request = zfcp_fc_exec_bsg_job,
+ .bsg_timeout = zfcp_fc_timeout_bsg_job,
/* no functions registered for following dynamic attributes but
directly set by LLDD */
.show_host_port_type = 1,
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 2a88985..7e26ebc 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -293,7 +293,10 @@
status = -EINVAL;
}
}
- aac_fib_complete(fibptr);
+ /* Do not set XferState to zero unless receives a response from F/W */
+ if (status >= 0)
+ aac_fib_complete(fibptr);
+
/* Send a CT_COMMIT_CONFIG to enable discovery of devices */
if (status >= 0) {
if ((aac_commit == 1) || commit_flag) {
@@ -310,13 +313,18 @@
FsaNormal,
1, 1,
NULL, NULL);
- aac_fib_complete(fibptr);
+ /* Do not set XferState to zero unless
+ * receives a response from F/W */
+ if (status >= 0)
+ aac_fib_complete(fibptr);
} else if (aac_commit == 0) {
printk(KERN_WARNING
"aac_get_config_status: Foreign device configurations are being ignored\n");
}
}
- aac_fib_free(fibptr);
+ /* FIB should be freed only after getting the response from the F/W */
+ if (status != -ERESTARTSYS)
+ aac_fib_free(fibptr);
return status;
}
@@ -355,7 +363,9 @@
maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries);
aac_fib_complete(fibptr);
}
- aac_fib_free(fibptr);
+ /* FIB should be freed only after getting the response from the F/W */
+ if (status != -ERESTARTSYS)
+ aac_fib_free(fibptr);
if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS)
maximum_num_containers = MAXIMUM_NUM_CONTAINERS;
@@ -1245,8 +1255,12 @@
NULL);
if (rcode < 0) {
- aac_fib_complete(fibptr);
- aac_fib_free(fibptr);
+ /* FIB should be freed only after
+ * getting the response from the F/W */
+ if (rcode != -ERESTARTSYS) {
+ aac_fib_complete(fibptr);
+ aac_fib_free(fibptr);
+ }
return rcode;
}
memcpy(&dev->adapter_info, info, sizeof(*info));
@@ -1270,6 +1284,12 @@
if (rcode >= 0)
memcpy(&dev->supplement_adapter_info, sinfo, sizeof(*sinfo));
+ if (rcode == -ERESTARTSYS) {
+ fibptr = aac_fib_alloc(dev);
+ if (!fibptr)
+ return -ENOMEM;
+ }
+
}
@@ -1470,9 +1490,11 @@
(dev->scsi_host_ptr->sg_tablesize * 8) + 112;
}
}
-
- aac_fib_complete(fibptr);
- aac_fib_free(fibptr);
+ /* FIB should be freed only after getting the response from the F/W */
+ if (rcode != -ERESTARTSYS) {
+ aac_fib_complete(fibptr);
+ aac_fib_free(fibptr);
+ }
return rcode;
}
@@ -1633,6 +1655,7 @@
* Alocate and initialize a Fib
*/
if (!(cmd_fibcontext = aac_fib_alloc(dev))) {
+ printk(KERN_WARNING "aac_read: fib allocation failed\n");
return -1;
}
@@ -1712,9 +1735,14 @@
* Allocate and initialize a Fib then setup a BlockWrite command
*/
if (!(cmd_fibcontext = aac_fib_alloc(dev))) {
- scsicmd->result = DID_ERROR << 16;
- scsicmd->scsi_done(scsicmd);
- return 0;
+ /* FIB temporarily unavailable,not catastrophic failure */
+
+ /* scsicmd->result = DID_ERROR << 16;
+ * scsicmd->scsi_done(scsicmd);
+ * return 0;
+ */
+ printk(KERN_WARNING "aac_write: fib allocation failed\n");
+ return -1;
}
status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua);
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 83986ed..619c02d 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -12,7 +12,7 @@
*----------------------------------------------------------------------------*/
#ifndef AAC_DRIVER_BUILD
-# define AAC_DRIVER_BUILD 2461
+# define AAC_DRIVER_BUILD 24702
# define AAC_DRIVER_BRANCH "-ms"
#endif
#define MAXIMUM_NUM_CONTAINERS 32
@@ -1036,6 +1036,9 @@
u8 printf_enabled;
u8 in_reset;
u8 msi;
+ int management_fib_count;
+ spinlock_t manage_lock;
+
};
#define aac_adapter_interrupt(dev) \
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
index 0391d75..9c0c911 100644
--- a/drivers/scsi/aacraid/commctrl.c
+++ b/drivers/scsi/aacraid/commctrl.c
@@ -153,7 +153,7 @@
fibptr->hw_fib_pa = hw_fib_pa;
fibptr->hw_fib_va = hw_fib;
}
- if (retval != -EINTR)
+ if (retval != -ERESTARTSYS)
aac_fib_free(fibptr);
return retval;
}
@@ -322,7 +322,7 @@
}
if (f.wait) {
if(down_interruptible(&fibctx->wait_sem) < 0) {
- status = -EINTR;
+ status = -ERESTARTSYS;
} else {
/* Lock again and retry */
spin_lock_irqsave(&dev->fib_lock, flags);
@@ -593,10 +593,10 @@
u64 addr;
void* p;
if (upsg->sg[i].count >
- (dev->adapter_info.options &
+ ((dev->adapter_info.options &
AAC_OPT_NEW_COMM) ?
(dev->scsi_host_ptr->max_sectors << 9) :
- 65536) {
+ 65536)) {
rcode = -EINVAL;
goto cleanup;
}
@@ -645,10 +645,10 @@
u64 addr;
void* p;
if (usg->sg[i].count >
- (dev->adapter_info.options &
+ ((dev->adapter_info.options &
AAC_OPT_NEW_COMM) ?
(dev->scsi_host_ptr->max_sectors << 9) :
- 65536) {
+ 65536)) {
rcode = -EINVAL;
goto cleanup;
}
@@ -695,10 +695,10 @@
uintptr_t addr;
void* p;
if (usg->sg[i].count >
- (dev->adapter_info.options &
+ ((dev->adapter_info.options &
AAC_OPT_NEW_COMM) ?
(dev->scsi_host_ptr->max_sectors << 9) :
- 65536) {
+ 65536)) {
rcode = -EINVAL;
goto cleanup;
}
@@ -734,10 +734,10 @@
dma_addr_t addr;
void* p;
if (upsg->sg[i].count >
- (dev->adapter_info.options &
+ ((dev->adapter_info.options &
AAC_OPT_NEW_COMM) ?
(dev->scsi_host_ptr->max_sectors << 9) :
- 65536) {
+ 65536)) {
rcode = -EINVAL;
goto cleanup;
}
@@ -772,8 +772,8 @@
psg->count = cpu_to_le32(sg_indx+1);
status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL);
}
- if (status == -EINTR) {
- rcode = -EINTR;
+ if (status == -ERESTARTSYS) {
+ rcode = -ERESTARTSYS;
goto cleanup;
}
@@ -810,7 +810,7 @@
for(i=0; i <= sg_indx; i++){
kfree(sg_list[i]);
}
- if (rcode != -EINTR) {
+ if (rcode != -ERESTARTSYS) {
aac_fib_complete(srbfib);
aac_fib_free(srbfib);
}
@@ -848,7 +848,7 @@
*/
status = aac_dev_ioctl(dev, cmd, arg);
- if(status != -ENOTTY)
+ if (status != -ENOTTY)
return status;
switch (cmd) {
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 666d515..a726148 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -194,7 +194,9 @@
if (status >= 0)
aac_fib_complete(fibctx);
- aac_fib_free(fibctx);
+ /* FIB should be freed only after getting the response from the F/W */
+ if (status != -ERESTARTSYS)
+ aac_fib_free(fibctx);
return status;
}
@@ -304,6 +306,8 @@
/*
* Check the preferred comm settings, defaults from template.
*/
+ dev->management_fib_count = 0;
+ spin_lock_init(&dev->manage_lock);
dev->max_fib_size = sizeof(struct hw_fib);
dev->sg_tablesize = host->sg_tablesize = (dev->max_fib_size
- sizeof(struct aac_fibhdr)
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 956261f..94d2954 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -189,7 +189,14 @@
void aac_fib_free(struct fib *fibptr)
{
- unsigned long flags;
+ unsigned long flags, flagsv;
+
+ spin_lock_irqsave(&fibptr->event_lock, flagsv);
+ if (fibptr->done == 2) {
+ spin_unlock_irqrestore(&fibptr->event_lock, flagsv);
+ return;
+ }
+ spin_unlock_irqrestore(&fibptr->event_lock, flagsv);
spin_lock_irqsave(&fibptr->dev->fib_lock, flags);
if (unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT))
@@ -390,6 +397,8 @@
struct hw_fib * hw_fib = fibptr->hw_fib_va;
unsigned long flags = 0;
unsigned long qflags;
+ unsigned long mflags = 0;
+
if (!(hw_fib->header.XferState & cpu_to_le32(HostOwned)))
return -EBUSY;
@@ -471,9 +480,31 @@
if (!dev->queues)
return -EBUSY;
- if(wait)
+ if (wait) {
+
+ spin_lock_irqsave(&dev->manage_lock, mflags);
+ if (dev->management_fib_count >= AAC_NUM_MGT_FIB) {
+ printk(KERN_INFO "No management Fibs Available:%d\n",
+ dev->management_fib_count);
+ spin_unlock_irqrestore(&dev->manage_lock, mflags);
+ return -EBUSY;
+ }
+ dev->management_fib_count++;
+ spin_unlock_irqrestore(&dev->manage_lock, mflags);
spin_lock_irqsave(&fibptr->event_lock, flags);
- aac_adapter_deliver(fibptr);
+ }
+
+ if (aac_adapter_deliver(fibptr) != 0) {
+ printk(KERN_ERR "aac_fib_send: returned -EBUSY\n");
+ if (wait) {
+ spin_unlock_irqrestore(&fibptr->event_lock, flags);
+ spin_lock_irqsave(&dev->manage_lock, mflags);
+ dev->management_fib_count--;
+ spin_unlock_irqrestore(&dev->manage_lock, mflags);
+ }
+ return -EBUSY;
+ }
+
/*
* If the caller wanted us to wait for response wait now.
@@ -516,14 +547,15 @@
udelay(5);
}
} else if (down_interruptible(&fibptr->event_wait)) {
- fibptr->done = 2;
- up(&fibptr->event_wait);
+ /* Do nothing ... satisfy
+ * down_interruptible must_check */
}
+
spin_lock_irqsave(&fibptr->event_lock, flags);
- if ((fibptr->done == 0) || (fibptr->done == 2)) {
+ if (fibptr->done == 0) {
fibptr->done = 2; /* Tell interrupt we aborted */
spin_unlock_irqrestore(&fibptr->event_lock, flags);
- return -EINTR;
+ return -ERESTARTSYS;
}
spin_unlock_irqrestore(&fibptr->event_lock, flags);
BUG_ON(fibptr->done == 0);
@@ -689,6 +721,7 @@
int aac_fib_complete(struct fib *fibptr)
{
+ unsigned long flags;
struct hw_fib * hw_fib = fibptr->hw_fib_va;
/*
@@ -709,6 +742,13 @@
* command is complete that we had sent to the adapter and this
* cdb could be reused.
*/
+ spin_lock_irqsave(&fibptr->event_lock, flags);
+ if (fibptr->done == 2) {
+ spin_unlock_irqrestore(&fibptr->event_lock, flags);
+ return 0;
+ }
+ spin_unlock_irqrestore(&fibptr->event_lock, flags);
+
if((hw_fib->header.XferState & cpu_to_le32(SentFromHost)) &&
(hw_fib->header.XferState & cpu_to_le32(AdapterProcessed)))
{
@@ -1355,7 +1395,10 @@
if (status >= 0)
aac_fib_complete(fibctx);
- aac_fib_free(fibctx);
+ /* FIB should be freed only after getting
+ * the response from the F/W */
+ if (status != -ERESTARTSYS)
+ aac_fib_free(fibctx);
}
}
@@ -1759,6 +1802,7 @@
struct fib *fibptr;
if ((fibptr = aac_fib_alloc(dev))) {
+ int status;
__le32 *info;
aac_fib_init(fibptr);
@@ -1769,15 +1813,21 @@
*info = cpu_to_le32(now.tv_sec);
- (void)aac_fib_send(SendHostTime,
+ status = aac_fib_send(SendHostTime,
fibptr,
sizeof(*info),
FsaNormal,
1, 1,
NULL,
NULL);
- aac_fib_complete(fibptr);
- aac_fib_free(fibptr);
+ /* Do not set XferState to zero unless
+ * receives a response from F/W */
+ if (status >= 0)
+ aac_fib_complete(fibptr);
+ /* FIB should be freed only after
+ * getting the response from the F/W */
+ if (status != -ERESTARTSYS)
+ aac_fib_free(fibptr);
}
difference = (long)(unsigned)update_interval*HZ;
} else {
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c
index abc9ef5..9c7408fe 100644
--- a/drivers/scsi/aacraid/dpcsup.c
+++ b/drivers/scsi/aacraid/dpcsup.c
@@ -57,9 +57,9 @@
struct hw_fib * hwfib;
struct fib * fib;
int consumed = 0;
- unsigned long flags;
+ unsigned long flags, mflags;
- spin_lock_irqsave(q->lock, flags);
+ spin_lock_irqsave(q->lock, flags);
/*
* Keep pulling response QEs off the response queue and waking
* up the waiters until there are no more QEs. We then return
@@ -125,12 +125,21 @@
} else {
unsigned long flagv;
spin_lock_irqsave(&fib->event_lock, flagv);
- if (!fib->done)
+ if (!fib->done) {
fib->done = 1;
- up(&fib->event_wait);
+ up(&fib->event_wait);
+ }
spin_unlock_irqrestore(&fib->event_lock, flagv);
+
+ spin_lock_irqsave(&dev->manage_lock, mflags);
+ dev->management_fib_count--;
+ spin_unlock_irqrestore(&dev->manage_lock, mflags);
+
FIB_COUNTER_INCREMENT(aac_config.NormalRecved);
if (fib->done == 2) {
+ spin_lock_irqsave(&fib->event_lock, flagv);
+ fib->done = 0;
+ spin_unlock_irqrestore(&fib->event_lock, flagv);
aac_fib_complete(fib);
aac_fib_free(fib);
}
@@ -232,6 +241,7 @@
unsigned int aac_intr_normal(struct aac_dev * dev, u32 index)
{
+ unsigned long mflags;
dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, index));
if ((index & 0x00000002L)) {
struct hw_fib * hw_fib;
@@ -320,11 +330,25 @@
unsigned long flagv;
dprintk((KERN_INFO "event_wait up\n"));
spin_lock_irqsave(&fib->event_lock, flagv);
- if (!fib->done)
+ if (!fib->done) {
fib->done = 1;
- up(&fib->event_wait);
+ up(&fib->event_wait);
+ }
spin_unlock_irqrestore(&fib->event_lock, flagv);
+
+ spin_lock_irqsave(&dev->manage_lock, mflags);
+ dev->management_fib_count--;
+ spin_unlock_irqrestore(&dev->manage_lock, mflags);
+
FIB_COUNTER_INCREMENT(aac_config.NormalRecved);
+ if (fib->done == 2) {
+ spin_lock_irqsave(&fib->event_lock, flagv);
+ fib->done = 0;
+ spin_unlock_irqrestore(&fib->event_lock, flagv);
+ aac_fib_complete(fib);
+ aac_fib_free(fib);
+ }
+
}
return 0;
}
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c
index 4d419c1..78971db 100644
--- a/drivers/scsi/aic7xxx/aic79xx_core.c
+++ b/drivers/scsi/aic7xxx/aic79xx_core.c
@@ -3171,13 +3171,16 @@
tinfo->curr.transport_version = 2;
tinfo->goal.transport_version = 2;
tinfo->goal.ppr_options = 0;
- /*
- * Remove any SCBs in the waiting for selection
- * queue that may also be for this target so
- * that command ordering is preserved.
- */
- ahd_freeze_devq(ahd, scb);
- ahd_qinfifo_requeue_tail(ahd, scb);
+ if (scb != NULL) {
+ /*
+ * Remove any SCBs in the waiting
+ * for selection queue that may
+ * also be for this target so that
+ * command ordering is preserved.
+ */
+ ahd_freeze_devq(ahd, scb);
+ ahd_qinfifo_requeue_tail(ahd, scb);
+ }
printerror = 0;
}
} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE)
@@ -3194,13 +3197,16 @@
MSG_EXT_WDTR_BUS_8_BIT,
AHD_TRANS_CUR|AHD_TRANS_GOAL,
/*paused*/TRUE);
- /*
- * Remove any SCBs in the waiting for selection
- * queue that may also be for this target so that
- * command ordering is preserved.
- */
- ahd_freeze_devq(ahd, scb);
- ahd_qinfifo_requeue_tail(ahd, scb);
+ if (scb != NULL) {
+ /*
+ * Remove any SCBs in the waiting for
+ * selection queue that may also be for
+ * this target so that command ordering
+ * is preserved.
+ */
+ ahd_freeze_devq(ahd, scb);
+ ahd_qinfifo_requeue_tail(ahd, scb);
+ }
printerror = 0;
} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE)
&& ppr_busfree == 0) {
@@ -3217,13 +3223,16 @@
/*ppr_options*/0,
AHD_TRANS_CUR|AHD_TRANS_GOAL,
/*paused*/TRUE);
- /*
- * Remove any SCBs in the waiting for selection
- * queue that may also be for this target so that
- * command ordering is preserved.
- */
- ahd_freeze_devq(ahd, scb);
- ahd_qinfifo_requeue_tail(ahd, scb);
+ if (scb != NULL) {
+ /*
+ * Remove any SCBs in the waiting for
+ * selection queue that may also be for
+ * this target so that command ordering
+ * is preserved.
+ */
+ ahd_freeze_devq(ahd, scb);
+ ahd_qinfifo_requeue_tail(ahd, scb);
+ }
printerror = 0;
} else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0
&& ahd_sent_msg(ahd, AHDMSG_1B,
@@ -3251,7 +3260,7 @@
* the message phases. We check it last in case we
* had to send some other message that caused a busfree.
*/
- if (printerror != 0
+ if (scb != NULL && printerror != 0
&& (lastphase == P_MESGIN || lastphase == P_MESGOUT)
&& ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0)) {
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
old mode 100755
new mode 100644
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
old mode 100755
new mode 100644
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 608e675..1263d97 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -1586,8 +1586,7 @@
*/
#define FCF_FABRIC_DEVICE BIT_0
#define FCF_LOGIN_NEEDED BIT_1
-#define FCF_TAPE_PRESENT BIT_2
-#define FCF_FCP2_DEVICE BIT_3
+#define FCF_FCP2_DEVICE BIT_2
/* No loop ID flag. */
#define FC_NO_LOOP_ID 0x1000
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index b4a0eac..3f8e849 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -205,7 +205,7 @@
switch (data[0]) {
case MBS_COMMAND_COMPLETE:
- if (fcport->flags & FCF_TAPE_PRESENT)
+ if (fcport->flags & FCF_FCP2_DEVICE)
opts |= BIT_1;
rval = qla2x00_get_port_database(vha, fcport, opts);
if (rval != QLA_SUCCESS)
@@ -2726,7 +2726,7 @@
/*
* Logout all previous fabric devices marked lost, except
- * tape devices.
+ * FCP2 devices.
*/
list_for_each_entry(fcport, &vha->vp_fcports, list) {
if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
@@ -2739,7 +2739,7 @@
qla2x00_mark_device_lost(vha, fcport,
ql2xplogiabsentdevice, 0);
if (fcport->loop_id != FC_NO_LOOP_ID &&
- (fcport->flags & FCF_TAPE_PRESENT) == 0 &&
+ (fcport->flags & FCF_FCP2_DEVICE) == 0 &&
fcport->port_type != FCT_INITIATOR &&
fcport->port_type != FCT_BROADCAST) {
ha->isp_ops->fabric_logout(vha,
@@ -3018,7 +3018,7 @@
fcport->d_id.b24 = new_fcport->d_id.b24;
fcport->flags |= FCF_LOGIN_NEEDED;
if (fcport->loop_id != FC_NO_LOOP_ID &&
- (fcport->flags & FCF_TAPE_PRESENT) == 0 &&
+ (fcport->flags & FCF_FCP2_DEVICE) == 0 &&
fcport->port_type != FCT_INITIATOR &&
fcport->port_type != FCT_BROADCAST) {
ha->isp_ops->fabric_logout(vha, fcport->loop_id,
@@ -3272,9 +3272,9 @@
rval = qla2x00_fabric_login(vha, fcport, next_loopid);
if (rval == QLA_SUCCESS) {
- /* Send an ADISC to tape devices.*/
+ /* Send an ADISC to FCP2 devices.*/
opts = 0;
- if (fcport->flags & FCF_TAPE_PRESENT)
+ if (fcport->flags & FCF_FCP2_DEVICE)
opts |= BIT_1;
rval = qla2x00_get_port_database(vha, fcport, opts);
if (rval != QLA_SUCCESS) {
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 209f50e..8529eb1 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1188,7 +1188,6 @@
scsi_qla_host_t *vha = shost_priv(sdev->host);
struct qla_hw_data *ha = vha->hw;
struct fc_rport *rport = starget_to_rport(sdev->sdev_target);
- fc_port_t *fcport = *(fc_port_t **)rport->dd_data;
struct req_que *req = vha->req;
if (sdev->tagged_supported)
@@ -1197,8 +1196,6 @@
scsi_deactivate_tcq(sdev, req->max_q_depth);
rport->dev_loss_tmo = ha->port_down_retry_count;
- if (sdev->type == TYPE_TAPE)
- fcport->flags |= FCF_TAPE_PRESENT;
return 0;
}
@@ -2805,7 +2802,7 @@
fcport->login_retry--;
if (fcport->flags & FCF_FABRIC_DEVICE) {
- if (fcport->flags & FCF_TAPE_PRESENT)
+ if (fcport->flags & FCF_FCP2_DEVICE)
ha->isp_ops->fabric_logout(vha,
fcport->loop_id,
fcport->d_id.b.domain,
@@ -3141,7 +3138,10 @@
if (!IS_QLA2100(ha) && vha->link_down_timeout)
atomic_set(&vha->loop_state, LOOP_DEAD);
- /* Schedule an ISP abort to return any tape commands. */
+ /*
+ * Schedule an ISP abort to return any FCP2-device
+ * commands.
+ */
/* NPIV - scan physical port only */
if (!vha->vp_idx) {
spin_lock_irqsave(&ha->hardware_lock,
@@ -3158,7 +3158,7 @@
if (sp->ctx)
continue;
sfcp = sp->fcport;
- if (!(sfcp->flags & FCF_TAPE_PRESENT))
+ if (!(sfcp->flags & FCF_FCP2_DEVICE))
continue;
set_bit(ISP_ABORT_NEEDED,
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index 010e69b..371dc89 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -2292,11 +2292,14 @@
uint32_t faddr, left, burst;
struct qla_hw_data *ha = vha->hw;
+ if (IS_QLA25XX(ha) || IS_QLA81XX(ha))
+ goto try_fast;
if (offset & 0xfff)
goto slow_read;
if (length < OPTROM_BURST_SIZE)
goto slow_read;
+try_fast:
optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE,
&optrom_dma, GFP_KERNEL);
if (!optrom) {
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index a65dd95..ed36279 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,7 +7,7 @@
/*
* Driver version
*/
-#define QLA2XXX_VERSION "8.03.01-k9"
+#define QLA2XXX_VERSION "8.03.01-k10"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 3
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index d892768..c664242 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -749,9 +749,9 @@
*/
req->next_rq->resid_len = scsi_in(cmd)->resid;
+ scsi_release_buffers(cmd);
blk_end_request_all(req, 0);
- scsi_release_buffers(cmd);
scsi_next_command(cmd);
return;
}
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index ddfcecd..653f22a 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -3527,7 +3527,10 @@
if (!done && i->f->bsg_timeout) {
/* call LLDD to abort the i/o as it has timed out */
err = i->f->bsg_timeout(job);
- if (err)
+ if (err == -EAGAIN) {
+ job->ref_cnt--;
+ return BLK_EH_RESET_TIMER;
+ } else if (err)
printk(KERN_ERR "ERROR: FC BSG request timeout - LLD "
"abort failed with status %d\n", err);
}
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index 14a8644..69357c0 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -188,7 +188,8 @@
P9_DPRINTK(P9_DEBUG_VFS, " %p\n", s);
- v9fs_dentry_release(s->s_root); /* clunk root */
+ if (s->s_root)
+ v9fs_dentry_release(s->s_root); /* clunk root */
kill_anon_super(s);
diff --git a/fs/affs/affs.h b/fs/affs/affs.h
index e511dc6..0e40caa 100644
--- a/fs/affs/affs.h
+++ b/fs/affs/affs.h
@@ -106,8 +106,8 @@
u32 s_last_bmap;
struct buffer_head *s_bmap_bh;
char *s_prefix; /* Prefix for volumes and assigns. */
- int s_prefix_len; /* Length of prefix. */
char s_volume[32]; /* Volume prefix for absolute symlinks. */
+ spinlock_t symlink_lock; /* protects the previous two */
};
#define SF_INTL 0x0001 /* International filesystem. */
diff --git a/fs/affs/namei.c b/fs/affs/namei.c
index 960d336..d70bbba 100644
--- a/fs/affs/namei.c
+++ b/fs/affs/namei.c
@@ -341,10 +341,13 @@
p = (char *)AFFS_HEAD(bh)->table;
lc = '/';
if (*symname == '/') {
+ struct affs_sb_info *sbi = AFFS_SB(sb);
while (*symname == '/')
symname++;
- while (AFFS_SB(sb)->s_volume[i]) /* Cannot overflow */
- *p++ = AFFS_SB(sb)->s_volume[i++];
+ spin_lock(&sbi->symlink_lock);
+ while (sbi->s_volume[i]) /* Cannot overflow */
+ *p++ = sbi->s_volume[i++];
+ spin_unlock(&sbi->symlink_lock);
}
while (i < maxlen && (c = *symname++)) {
if (c == '.' && lc == '/' && *symname == '.' && symname[1] == '/') {
diff --git a/fs/affs/super.c b/fs/affs/super.c
index 104fdcb..d41e967 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -203,7 +203,7 @@
switch (token) {
case Opt_bs:
if (match_int(&args[0], &n))
- return -EINVAL;
+ return 0;
if (n != 512 && n != 1024 && n != 2048
&& n != 4096) {
printk ("AFFS: Invalid blocksize (512, 1024, 2048, 4096 allowed)\n");
@@ -213,7 +213,7 @@
break;
case Opt_mode:
if (match_octal(&args[0], &option))
- return 1;
+ return 0;
*mode = option & 0777;
*mount_opts |= SF_SETMODE;
break;
@@ -221,8 +221,6 @@
*mount_opts |= SF_MUFS;
break;
case Opt_prefix:
- /* Free any previous prefix */
- kfree(*prefix);
*prefix = match_strdup(&args[0]);
if (!*prefix)
return 0;
@@ -233,21 +231,21 @@
break;
case Opt_reserved:
if (match_int(&args[0], reserved))
- return 1;
+ return 0;
break;
case Opt_root:
if (match_int(&args[0], root))
- return 1;
+ return 0;
break;
case Opt_setgid:
if (match_int(&args[0], &option))
- return 1;
+ return 0;
*gid = option;
*mount_opts |= SF_SETGID;
break;
case Opt_setuid:
if (match_int(&args[0], &option))
- return -EINVAL;
+ return 0;
*uid = option;
*mount_opts |= SF_SETUID;
break;
@@ -311,11 +309,14 @@
return -ENOMEM;
sb->s_fs_info = sbi;
mutex_init(&sbi->s_bmlock);
+ spin_lock_init(&sbi->symlink_lock);
if (!parse_options(data,&uid,&gid,&i,&reserved,&root_block,
&blocksize,&sbi->s_prefix,
sbi->s_volume, &mount_flags)) {
printk(KERN_ERR "AFFS: Error parsing options\n");
+ kfree(sbi->s_prefix);
+ kfree(sbi);
return -EINVAL;
}
/* N.B. after this point s_prefix must be released */
@@ -516,14 +517,18 @@
unsigned long mount_flags;
int res = 0;
char *new_opts = kstrdup(data, GFP_KERNEL);
+ char volume[32];
+ char *prefix = NULL;
pr_debug("AFFS: remount(flags=0x%x,opts=\"%s\")\n",*flags,data);
*flags |= MS_NODIRATIME;
+ memcpy(volume, sbi->s_volume, 32);
if (!parse_options(data, &uid, &gid, &mode, &reserved, &root_block,
- &blocksize, &sbi->s_prefix, sbi->s_volume,
+ &blocksize, &prefix, volume,
&mount_flags)) {
+ kfree(prefix);
kfree(new_opts);
return -EINVAL;
}
@@ -534,6 +539,14 @@
sbi->s_mode = mode;
sbi->s_uid = uid;
sbi->s_gid = gid;
+ /* protect against readers */
+ spin_lock(&sbi->symlink_lock);
+ if (prefix) {
+ kfree(sbi->s_prefix);
+ sbi->s_prefix = prefix;
+ }
+ memcpy(sbi->s_volume, volume, 32);
+ spin_unlock(&sbi->symlink_lock);
if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
unlock_kernel();
diff --git a/fs/affs/symlink.c b/fs/affs/symlink.c
index 4178253..ee00f08 100644
--- a/fs/affs/symlink.c
+++ b/fs/affs/symlink.c
@@ -20,7 +20,6 @@
int i, j;
char c;
char lc;
- char *pf;
pr_debug("AFFS: follow_link(ino=%lu)\n",inode->i_ino);
@@ -32,11 +31,15 @@
j = 0;
lf = (struct slink_front *)bh->b_data;
lc = 0;
- pf = AFFS_SB(inode->i_sb)->s_prefix ? AFFS_SB(inode->i_sb)->s_prefix : "/";
if (strchr(lf->symname,':')) { /* Handle assign or volume name */
+ struct affs_sb_info *sbi = AFFS_SB(inode->i_sb);
+ char *pf;
+ spin_lock(&sbi->symlink_lock);
+ pf = sbi->s_prefix ? sbi->s_prefix : "/";
while (i < 1023 && (c = pf[i]))
link[i++] = c;
+ spin_unlock(&sbi->symlink_lock);
while (i < 1023 && lf->symname[j] != ':')
link[i++] = lf->symname[j++];
if (i < 1023)
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index 6f60336..8f3d9fd 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -353,35 +353,35 @@
struct inode *inode;
unsigned i, imap_len;
struct bfs_sb_info *info;
- long ret = -EINVAL;
+ int ret = -EINVAL;
unsigned long i_sblock, i_eblock, i_eoff, s_size;
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
+ mutex_init(&info->bfs_lock);
s->s_fs_info = info;
sb_set_blocksize(s, BFS_BSIZE);
- bh = sb_bread(s, 0);
- if(!bh)
+ info->si_sbh = sb_bread(s, 0);
+ if (!info->si_sbh)
goto out;
- bfs_sb = (struct bfs_super_block *)bh->b_data;
+ bfs_sb = (struct bfs_super_block *)info->si_sbh->b_data;
if (le32_to_cpu(bfs_sb->s_magic) != BFS_MAGIC) {
if (!silent)
printf("No BFS filesystem on %s (magic=%08x)\n",
s->s_id, le32_to_cpu(bfs_sb->s_magic));
- goto out;
+ goto out1;
}
if (BFS_UNCLEAN(bfs_sb, s) && !silent)
printf("%s is unclean, continuing\n", s->s_id);
s->s_magic = BFS_MAGIC;
- info->si_sbh = bh;
if (le32_to_cpu(bfs_sb->s_start) > le32_to_cpu(bfs_sb->s_end)) {
printf("Superblock is corrupted\n");
- goto out;
+ goto out1;
}
info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE) /
@@ -390,7 +390,7 @@
imap_len = (info->si_lasti / 8) + 1;
info->si_imap = kzalloc(imap_len, GFP_KERNEL);
if (!info->si_imap)
- goto out;
+ goto out1;
for (i = 0; i < BFS_ROOT_INO; i++)
set_bit(i, info->si_imap);
@@ -398,15 +398,13 @@
inode = bfs_iget(s, BFS_ROOT_INO);
if (IS_ERR(inode)) {
ret = PTR_ERR(inode);
- kfree(info->si_imap);
- goto out;
+ goto out2;
}
s->s_root = d_alloc_root(inode);
if (!s->s_root) {
iput(inode);
ret = -ENOMEM;
- kfree(info->si_imap);
- goto out;
+ goto out2;
}
info->si_blocks = (le32_to_cpu(bfs_sb->s_end) + 1) >> BFS_BSIZE_BITS;
@@ -419,10 +417,8 @@
bh = sb_bread(s, info->si_blocks - 1);
if (!bh) {
printf("Last block not available: %lu\n", info->si_blocks - 1);
- iput(inode);
ret = -EIO;
- kfree(info->si_imap);
- goto out;
+ goto out3;
}
brelse(bh);
@@ -459,11 +455,8 @@
printf("Inode 0x%08x corrupted\n", i);
brelse(bh);
- s->s_root = NULL;
- kfree(info->si_imap);
- kfree(info);
- s->s_fs_info = NULL;
- return -EIO;
+ ret = -EIO;
+ goto out3;
}
if (!di->i_ino) {
@@ -483,11 +476,17 @@
s->s_dirt = 1;
}
dump_imap("read_super", s);
- mutex_init(&info->bfs_lock);
return 0;
+out3:
+ dput(s->s_root);
+ s->s_root = NULL;
+out2:
+ kfree(info->si_imap);
+out1:
+ brelse(info->si_sbh);
out:
- brelse(bh);
+ mutex_destroy(&info->bfs_lock);
kfree(info);
s->s_fs_info = NULL;
return ret;
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
index 346b694..fdd3970 100644
--- a/fs/binfmt_aout.c
+++ b/fs/binfmt_aout.c
@@ -264,6 +264,7 @@
#else
set_personality(PER_LINUX);
#endif
+ setup_new_exec(bprm);
current->mm->end_code = ex.a_text +
(current->mm->start_code = N_TXTADDR(ex));
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index edd90c4..fd5b2ea 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -662,27 +662,6 @@
if (elf_interpreter[elf_ppnt->p_filesz - 1] != '\0')
goto out_free_interp;
- /*
- * The early SET_PERSONALITY here is so that the lookup
- * for the interpreter happens in the namespace of the
- * to-be-execed image. SET_PERSONALITY can select an
- * alternate root.
- *
- * However, SET_PERSONALITY is NOT allowed to switch
- * this task into the new images's memory mapping
- * policy - that is, TASK_SIZE must still evaluate to
- * that which is appropriate to the execing application.
- * This is because exit_mmap() needs to have TASK_SIZE
- * evaluate to the size of the old image.
- *
- * So if (say) a 64-bit application is execing a 32-bit
- * application it is the architecture's responsibility
- * to defer changing the value of TASK_SIZE until the
- * switch really is going to happen - do this in
- * flush_thread(). - akpm
- */
- SET_PERSONALITY(loc->elf_ex);
-
interpreter = open_exec(elf_interpreter);
retval = PTR_ERR(interpreter);
if (IS_ERR(interpreter))
@@ -730,9 +709,6 @@
/* Verify the interpreter has a valid arch */
if (!elf_check_arch(&loc->interp_elf_ex))
goto out_free_dentry;
- } else {
- /* Executables without an interpreter also need a personality */
- SET_PERSONALITY(loc->elf_ex);
}
/* Flush all traces of the currently running executable */
@@ -752,7 +728,8 @@
if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
current->flags |= PF_RANDOMIZE;
- arch_pick_mmap_layout(current->mm);
+
+ setup_new_exec(bprm);
/* Do this so that we can load the interpreter, if need be. We will
change some of these later */
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index c57d9ce..18d7729 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -321,6 +321,9 @@
set_personality(PER_LINUX_FDPIC);
if (elf_read_implies_exec(&exec_params.hdr, executable_stack))
current->personality |= READ_IMPLIES_EXEC;
+
+ setup_new_exec(bprm);
+
set_binfmt(&elf_fdpic_format);
current->mm->start_code = 0;
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index d4a00ea..42c6b4a 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -519,6 +519,7 @@
/* OK, This is the point of no return */
set_personality(PER_LINUX_32BIT);
+ setup_new_exec(bprm);
}
/*
diff --git a/fs/binfmt_som.c b/fs/binfmt_som.c
index 2a9b533..cc8560f 100644
--- a/fs/binfmt_som.c
+++ b/fs/binfmt_som.c
@@ -227,6 +227,7 @@
/* OK, This is the point of no return */
current->flags &= ~PF_FORKNOEXEC;
current->personality = PER_HPUX;
+ setup_new_exec(bprm);
/* Set the task size for HP-UX processes such that
* the gateway page is outside the address space.
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c
index 54f4798..6df6d6e 100644
--- a/fs/btrfs/acl.c
+++ b/fs/btrfs/acl.c
@@ -244,6 +244,7 @@
ACL_TYPE_ACCESS);
}
}
+ posix_acl_release(clone);
}
failed:
posix_acl_release(acl);
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 9f806dd..2aa8ec6 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1161,6 +1161,7 @@
#define BTRFS_MOUNT_SSD_SPREAD (1 << 8)
#define BTRFS_MOUNT_NOSSD (1 << 9)
#define BTRFS_MOUNT_DISCARD (1 << 10)
+#define BTRFS_MOUNT_FORCE_COMPRESS (1 << 11)
#define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt)
#define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 009e3bd..87b2554 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1993,6 +1993,12 @@
if (!fs_info->fs_root)
goto fail_trans_kthread;
+ if (!(sb->s_flags & MS_RDONLY)) {
+ down_read(&fs_info->cleanup_work_sem);
+ btrfs_orphan_cleanup(fs_info->fs_root);
+ up_read(&fs_info->cleanup_work_sem);
+ }
+
return tree_root;
fail_trans_kthread:
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index 46bea0f..428fcac 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -155,20 +155,6 @@
return NULL;
}
-/*
- * look for an offset in the tree, and if it can't be found, return
- * the first offset we can find smaller than 'offset'.
- */
-static inline struct rb_node *tree_search(struct rb_root *root, u64 offset)
-{
- struct rb_node *prev;
- struct rb_node *ret;
- ret = __tree_search(root, offset, &prev, NULL);
- if (!ret)
- return prev;
- return ret;
-}
-
/* check to see if two extent_map structs are adjacent and safe to merge */
static int mergable_maps(struct extent_map *prev, struct extent_map *next)
{
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index b330e27c..8cd1099 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -483,7 +483,8 @@
nr_pages_ret = 0;
/* flag the file so we don't compress in the future */
- BTRFS_I(inode)->flags |= BTRFS_INODE_NOCOMPRESS;
+ if (!btrfs_test_opt(root, FORCE_COMPRESS))
+ BTRFS_I(inode)->flags |= BTRFS_INODE_NOCOMPRESS;
}
if (will_compress) {
*num_added += 1;
@@ -3796,12 +3797,6 @@
if (location.type == BTRFS_INODE_ITEM_KEY) {
inode = btrfs_iget(dir->i_sb, &location, root);
- if (unlikely(root->clean_orphans) &&
- !(inode->i_sb->s_flags & MS_RDONLY)) {
- down_read(&root->fs_info->cleanup_work_sem);
- btrfs_orphan_cleanup(root);
- up_read(&root->fs_info->cleanup_work_sem);
- }
return inode;
}
@@ -5799,7 +5794,7 @@
}
static int prealloc_file_range(struct inode *inode, u64 start, u64 end,
- u64 alloc_hint, int mode)
+ u64 alloc_hint, int mode, loff_t actual_len)
{
struct btrfs_trans_handle *trans;
struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -5808,6 +5803,7 @@
u64 cur_offset = start;
u64 num_bytes = end - start;
int ret = 0;
+ u64 i_size;
while (num_bytes > 0) {
alloc_size = min(num_bytes, root->fs_info->max_extent);
@@ -5846,8 +5842,12 @@
BTRFS_I(inode)->flags |= BTRFS_INODE_PREALLOC;
if (!(mode & FALLOC_FL_KEEP_SIZE) &&
cur_offset > inode->i_size) {
- i_size_write(inode, cur_offset);
- btrfs_ordered_update_i_size(inode, cur_offset, NULL);
+ if (cur_offset > actual_len)
+ i_size = actual_len;
+ else
+ i_size = cur_offset;
+ i_size_write(inode, i_size);
+ btrfs_ordered_update_i_size(inode, i_size, NULL);
}
ret = btrfs_update_inode(trans, root, inode);
@@ -5940,7 +5940,7 @@
!test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) {
ret = prealloc_file_range(inode,
cur_offset, last_byte,
- alloc_hint, mode);
+ alloc_hint, mode, offset+len);
if (ret < 0) {
free_extent_map(em);
break;
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 3f9b457..8a1ea6e 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -66,7 +66,8 @@
Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow,
Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier,
Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl,
- Opt_compress, Opt_notreelog, Opt_ratio, Opt_flushoncommit,
+ Opt_compress, Opt_compress_force, Opt_notreelog, Opt_ratio,
+ Opt_flushoncommit,
Opt_discard, Opt_err,
};
@@ -82,6 +83,7 @@
{Opt_alloc_start, "alloc_start=%s"},
{Opt_thread_pool, "thread_pool=%d"},
{Opt_compress, "compress"},
+ {Opt_compress_force, "compress-force"},
{Opt_ssd, "ssd"},
{Opt_ssd_spread, "ssd_spread"},
{Opt_nossd, "nossd"},
@@ -173,6 +175,11 @@
printk(KERN_INFO "btrfs: use compression\n");
btrfs_set_opt(info->mount_opt, COMPRESS);
break;
+ case Opt_compress_force:
+ printk(KERN_INFO "btrfs: forcing compression\n");
+ btrfs_set_opt(info->mount_opt, FORCE_COMPRESS);
+ btrfs_set_opt(info->mount_opt, COMPRESS);
+ break;
case Opt_ssd:
printk(KERN_INFO "btrfs: use ssd allocation scheme\n");
btrfs_set_opt(info->mount_opt, SSD);
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 220dad5..41ecbb2 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1135,7 +1135,7 @@
root->fs_info->avail_metadata_alloc_bits;
if ((all_avail & BTRFS_BLOCK_GROUP_RAID10) &&
- root->fs_info->fs_devices->rw_devices <= 4) {
+ root->fs_info->fs_devices->num_devices <= 4) {
printk(KERN_ERR "btrfs: unable to go below four devices "
"on raid10\n");
ret = -EINVAL;
@@ -1143,7 +1143,7 @@
}
if ((all_avail & BTRFS_BLOCK_GROUP_RAID1) &&
- root->fs_info->fs_devices->rw_devices <= 2) {
+ root->fs_info->fs_devices->num_devices <= 2) {
printk(KERN_ERR "btrfs: unable to go below two "
"devices on raid1\n");
ret = -EINVAL;
@@ -1434,8 +1434,8 @@
return -EINVAL;
bdev = open_bdev_exclusive(device_path, 0, root->fs_info->bdev_holder);
- if (!bdev)
- return -EIO;
+ if (IS_ERR(bdev))
+ return PTR_ERR(bdev);
if (root->fs_info->fs_devices->seeding) {
seeding_dev = 1;
@@ -2538,6 +2538,11 @@
if (!em)
return 1;
+ if (btrfs_test_opt(root, DEGRADED)) {
+ free_extent_map(em);
+ return 0;
+ }
+
map = (struct map_lookup *)em->bdev;
for (i = 0; i < map->num_stripes; i++) {
if (!map->stripes[i].dev->writeable) {
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index b486169..274ac86 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -160,15 +160,8 @@
* block. A pointer to that is in the struct vfsmount that we
* have around.
*/
- if (!parent) {
- if (debugfs_mount && debugfs_mount->mnt_sb) {
- parent = debugfs_mount->mnt_sb->s_root;
- }
- }
- if (!parent) {
- pr_debug("debugfs: Ah! can not find a parent!\n");
- return -EFAULT;
- }
+ if (!parent)
+ parent = debugfs_mount->mnt_sb->s_root;
*dentry = NULL;
mutex_lock(&parent->d_inode->i_mutex);
diff --git a/fs/exec.c b/fs/exec.c
index 632b02e..675c3f4 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -941,9 +941,7 @@
int flush_old_exec(struct linux_binprm * bprm)
{
- char * name;
- int i, ch, retval;
- char tcomm[sizeof(current->comm)];
+ int retval;
/*
* Make sure we have a private signal table and that
@@ -963,6 +961,20 @@
goto out;
bprm->mm = NULL; /* We're using it now */
+ return 0;
+
+out:
+ return retval;
+}
+EXPORT_SYMBOL(flush_old_exec);
+
+void setup_new_exec(struct linux_binprm * bprm)
+{
+ int i, ch;
+ char * name;
+ char tcomm[sizeof(current->comm)];
+
+ arch_pick_mmap_layout(current->mm);
/* This is the point of no return */
current->sas_ss_sp = current->sas_ss_size = 0;
@@ -1019,14 +1031,8 @@
flush_signal_handlers(current, 0);
flush_old_files(current->files);
-
- return 0;
-
-out:
- return retval;
}
-
-EXPORT_SYMBOL(flush_old_exec);
+EXPORT_SYMBOL(setup_new_exec);
/*
* Prepare credentials and lock ->cred_guard_mutex.
diff --git a/fs/romfs/super.c b/fs/romfs/super.c
index c117fa8..42d2135 100644
--- a/fs/romfs/super.c
+++ b/fs/romfs/super.c
@@ -544,6 +544,7 @@
error_rsb_inval:
ret = -EINVAL;
error_rsb:
+ kfree(rsb);
return ret;
}
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index cd4349b..89c6249 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -109,6 +109,7 @@
extern int __must_check remove_arg_zero(struct linux_binprm *);
extern int search_binary_handler(struct linux_binprm *,struct pt_regs *);
extern int flush_old_exec(struct linux_binprm * bprm);
+extern void setup_new_exec(struct linux_binprm * bprm);
extern int suid_dumpable;
#define SUID_DUMP_DISABLE 0 /* No setuid dumping */
diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h
index 1f716d9..520ecf8 100644
--- a/include/linux/firewire-cdev.h
+++ b/include/linux/firewire-cdev.h
@@ -380,7 +380,7 @@
* @immediate: If non-zero, immediate key to insert before pointer
* @key: Upper 8 bits of root directory pointer
* @data: Userspace pointer to contents of descriptor block
- * @length: Length of descriptor block data, in bytes
+ * @length: Length of descriptor block data, in quadlets
* @handle: Handle to the descriptor, written by the kernel
*
* Add a descriptor block and optionally a preceding immediate key to the local
@@ -394,6 +394,8 @@
* If not 0, the @immediate field specifies an immediate key which will be
* inserted before the root directory pointer.
*
+ * @immediate, @key, and @data array elements are CPU-endian quadlets.
+ *
* If successful, the kernel adds the descriptor and writes back a handle to the
* kernel-side object to be used for later removal of the descriptor block and
* immediate key.
diff --git a/include/linux/input.h b/include/linux/input.h
index 7be8a65..735ceaf 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -660,6 +660,7 @@
#define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */
#define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */
#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */
+#define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */
#define ABS_MAX 0x3f
#define ABS_CNT (ABS_MAX+1)
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index ed5d750..3c62ed4 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -253,6 +253,8 @@
extern struct page * read_cache_page(struct address_space *mapping,
pgoff_t index, filler_t *filler,
void *data);
+extern struct page * read_cache_page_gfp(struct address_space *mapping,
+ pgoff_t index, gfp_t gfp_mask);
extern int read_cache_pages(struct address_space *mapping,
struct list_head *pages, filler_t *filler, void *data);
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 6f7bba9..abdfacc 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1369,7 +1369,7 @@
char comm[TASK_COMM_LEN]; /* executable name excluding path
- access with [gs]et_task_comm (which lock
it with task_lock())
- - initialized normally by flush_old_exec */
+ - initialized normally by setup_new_exec */
/* file system info */
int link_count, total_link_count;
#ifdef CONFIG_SYSVIPC
diff --git a/include/linux/spi/ad7879.h b/include/linux/spi/ad7879.h
index 4231104..6334cee 100644
--- a/include/linux/spi/ad7879.h
+++ b/include/linux/spi/ad7879.h
@@ -28,8 +28,12 @@
* 1 = 4, 2 = 8, 3 = 16 (median > averaging)
*/
u8 median;
- /* 1 = AUX/VBAT/GPIO set to GPIO Output */
- u8 gpio_output;
- /* Initial GPIO pin state (valid if gpio_output = 1) */
- u8 gpio_default;
+ /* 1 = AUX/VBAT/GPIO export GPIO to gpiolib
+ * requires CONFIG_GPIOLIB
+ */
+ bool gpio_export;
+ /* identifies the first GPIO number handled by this chip;
+ * or, if negative, requests dynamic ID allocation.
+ */
+ s32 gpio_base;
};
diff --git a/include/scsi/scsi_bsg_fc.h b/include/scsi/scsi_bsg_fc.h
index a4b2333..91a4e4f 100644
--- a/include/scsi/scsi_bsg_fc.h
+++ b/include/scsi/scsi_bsg_fc.h
@@ -292,7 +292,7 @@
struct fc_bsg_rport_els r_els;
struct fc_bsg_rport_ct r_ct;
} rqst_data;
-};
+} __attribute__((packed));
/* response (request sense data) structure of the sg_io_v4 */
diff --git a/mm/filemap.c b/mm/filemap.c
index 96ac6b0..e373692 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1634,14 +1634,15 @@
static struct page *__read_cache_page(struct address_space *mapping,
pgoff_t index,
int (*filler)(void *,struct page*),
- void *data)
+ void *data,
+ gfp_t gfp)
{
struct page *page;
int err;
repeat:
page = find_get_page(mapping, index);
if (!page) {
- page = page_cache_alloc_cold(mapping);
+ page = __page_cache_alloc(gfp | __GFP_COLD);
if (!page)
return ERR_PTR(-ENOMEM);
err = add_to_page_cache_lru(page, mapping, index, GFP_KERNEL);
@@ -1661,31 +1662,18 @@
return page;
}
-/**
- * read_cache_page_async - read into page cache, fill it if needed
- * @mapping: the page's address_space
- * @index: the page index
- * @filler: function to perform the read
- * @data: destination for read data
- *
- * Same as read_cache_page, but don't wait for page to become unlocked
- * after submitting it to the filler.
- *
- * Read into the page cache. If a page already exists, and PageUptodate() is
- * not set, try to fill the page but don't wait for it to become unlocked.
- *
- * If the page does not get brought uptodate, return -EIO.
- */
-struct page *read_cache_page_async(struct address_space *mapping,
+static struct page *do_read_cache_page(struct address_space *mapping,
pgoff_t index,
int (*filler)(void *,struct page*),
- void *data)
+ void *data,
+ gfp_t gfp)
+
{
struct page *page;
int err;
retry:
- page = __read_cache_page(mapping, index, filler, data);
+ page = __read_cache_page(mapping, index, filler, data, gfp);
if (IS_ERR(page))
return page;
if (PageUptodate(page))
@@ -1710,8 +1698,67 @@
mark_page_accessed(page);
return page;
}
+
+/**
+ * read_cache_page_async - read into page cache, fill it if needed
+ * @mapping: the page's address_space
+ * @index: the page index
+ * @filler: function to perform the read
+ * @data: destination for read data
+ *
+ * Same as read_cache_page, but don't wait for page to become unlocked
+ * after submitting it to the filler.
+ *
+ * Read into the page cache. If a page already exists, and PageUptodate() is
+ * not set, try to fill the page but don't wait for it to become unlocked.
+ *
+ * If the page does not get brought uptodate, return -EIO.
+ */
+struct page *read_cache_page_async(struct address_space *mapping,
+ pgoff_t index,
+ int (*filler)(void *,struct page*),
+ void *data)
+{
+ return do_read_cache_page(mapping, index, filler, data, mapping_gfp_mask(mapping));
+}
EXPORT_SYMBOL(read_cache_page_async);
+static struct page *wait_on_page_read(struct page *page)
+{
+ if (!IS_ERR(page)) {
+ wait_on_page_locked(page);
+ if (!PageUptodate(page)) {
+ page_cache_release(page);
+ page = ERR_PTR(-EIO);
+ }
+ }
+ return page;
+}
+
+/**
+ * read_cache_page_gfp - read into page cache, using specified page allocation flags.
+ * @mapping: the page's address_space
+ * @index: the page index
+ * @gfp: the page allocator flags to use if allocating
+ *
+ * This is the same as "read_mapping_page(mapping, index, NULL)", but with
+ * any new page allocations done using the specified allocation flags. Note
+ * that the Radix tree operations will still use GFP_KERNEL, so you can't
+ * expect to do this atomically or anything like that - but you can pass in
+ * other page requirements.
+ *
+ * If the page does not get brought uptodate, return -EIO.
+ */
+struct page *read_cache_page_gfp(struct address_space *mapping,
+ pgoff_t index,
+ gfp_t gfp)
+{
+ filler_t *filler = (filler_t *)mapping->a_ops->readpage;
+
+ return wait_on_page_read(do_read_cache_page(mapping, index, filler, NULL, gfp));
+}
+EXPORT_SYMBOL(read_cache_page_gfp);
+
/**
* read_cache_page - read into page cache, fill it if needed
* @mapping: the page's address_space
@@ -1729,18 +1776,7 @@
int (*filler)(void *,struct page*),
void *data)
{
- struct page *page;
-
- page = read_cache_page_async(mapping, index, filler, data);
- if (IS_ERR(page))
- goto out;
- wait_on_page_locked(page);
- if (!PageUptodate(page)) {
- page_cache_release(page);
- page = ERR_PTR(-EIO);
- }
- out:
- return page;
+ return wait_on_page_read(read_cache_page_async(mapping, index, filler, data));
}
EXPORT_SYMBOL(read_cache_page);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index d2a8889..8deb9d0 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -556,8 +556,9 @@
page = list_entry(list->prev, struct page, lru);
/* must delete as __free_one_page list manipulates */
list_del(&page->lru);
- __free_one_page(page, zone, 0, migratetype);
- trace_mm_page_pcpu_drain(page, 0, migratetype);
+ /* MIGRATE_MOVABLE list may include MIGRATE_RESERVEs */
+ __free_one_page(page, zone, 0, page_private(page));
+ trace_mm_page_pcpu_drain(page, 0, page_private(page));
} while (--count && --batch_free && !list_empty(list));
}
spin_unlock(&zone->lock);
diff --git a/security/inode.c b/security/inode.c
index f7496c6..c3a7938 100644
--- a/security/inode.c
+++ b/security/inode.c
@@ -156,15 +156,8 @@
* block. A pointer to that is in the struct vfsmount that we
* have around.
*/
- if (!parent ) {
- if (mount && mount->mnt_sb) {
- parent = mount->mnt_sb->s_root;
- }
- }
- if (!parent) {
- pr_debug("securityfs: Ah! can not find a parent!\n");
- return -EFAULT;
- }
+ if (!parent)
+ parent = mount->mnt_sb->s_root;
mutex_lock(&parent->d_inode->i_mutex);
*dentry = lookup_one_len(name, parent, strlen(name));