aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/powerpc/booting-without-of.txt5
-rw-r--r--Documentation/thinkpad-acpi.txt73
-rw-r--r--MAINTAINERS2
-rw-r--r--arch/m68k/atari/atakeyb.c3
-rw-r--r--arch/mips/Kconfig33
-rw-r--r--arch/mips/au1000/Kconfig1
-rw-r--r--arch/mips/kernel/Makefile2
-rw-r--r--arch/mips/kernel/cevt-r4k.c14
-rw-r--r--arch/mips/kernel/csrc-r4k.c29
-rw-r--r--arch/mips/kernel/setup.c31
-rw-r--r--arch/mips/kernel/smp-up.c67
-rw-r--r--arch/mips/kernel/time.c112
-rw-r--r--arch/mips/kernel/vpe.c4
-rw-r--r--arch/mips/math-emu/ieee754.c2
-rw-r--r--arch/mips/math-emu/ieee754dp.c2
-rw-r--r--arch/mips/math-emu/ieee754sp.c2
-rw-r--r--arch/mips/mipssim/sim_time.c6
-rw-r--r--arch/mips/mm/dma-default.c37
-rw-r--r--arch/mips/mm/init.c43
-rw-r--r--arch/mips/pmc-sierra/Kconfig2
-rw-r--r--arch/mips/sgi-ip22/ip22-eisa.c134
-rw-r--r--arch/mips/sgi-ip22/ip22-nvram.c40
-rw-r--r--arch/mips/sgi-ip32/ip32-irq.c24
-rw-r--r--arch/mips/vr41xx/Kconfig6
-rw-r--r--arch/powerpc/boot/dts/mpc832x_mds.dts16
-rw-r--r--arch/powerpc/boot/dts/mpc834x_mds.dts9
-rw-r--r--arch/powerpc/boot/dts/mpc836x_mds.dts9
-rw-r--r--arch/powerpc/boot/dts/mpc8544ds.dts20
-rw-r--r--arch/powerpc/boot/dts/mpc8572ds.dts108
-rw-r--r--arch/powerpc/boot/dts/mpc8641_hpcn.dts126
-rw-r--r--arch/powerpc/configs/mpc832x_mds_defconfig48
-rw-r--r--arch/powerpc/configs/mpc832x_rdb_defconfig41
-rw-r--r--arch/powerpc/configs/mpc834x_itx_defconfig2
-rw-r--r--arch/powerpc/configs/mpc834x_itxgp_defconfig88
-rw-r--r--arch/powerpc/configs/mpc834x_mds_defconfig48
-rw-r--r--arch/powerpc/configs/mpc836x_mds_defconfig48
-rw-r--r--arch/powerpc/configs/mpc8568mds_defconfig48
-rw-r--r--arch/powerpc/kernel/asm-offsets.c4
-rw-r--r--arch/powerpc/kernel/rtas.c111
-rw-r--r--arch/powerpc/kernel/time.c5
-rw-r--r--arch/powerpc/kernel/vdso.c11
-rw-r--r--arch/powerpc/kernel/vdso32/cacheflush.S41
-rw-r--r--arch/powerpc/kernel/vdso64/cacheflush.S41
-rw-r--r--arch/powerpc/mm/mem.c2
-rw-r--r--arch/powerpc/mm/mmu_decl.h2
-rw-r--r--arch/powerpc/mm/stab.c1
-rw-r--r--arch/powerpc/platforms/40x/walnut.c3
-rw-r--r--arch/powerpc/platforms/44x/bamboo.c3
-rw-r--r--arch/powerpc/platforms/44x/ebony.c3
-rw-r--r--arch/powerpc/platforms/44x/sequoia.c3
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_mds.c31
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_rdb.c14
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_mds.c24
-rw-r--r--arch/powerpc/platforms/83xx/mpc836x_mds.c55
-rw-r--r--arch/powerpc/platforms/83xx/usb.c8
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c1
-rw-r--r--arch/powerpc/platforms/embedded6xx/prpmc2800.c1
-rw-r--r--arch/powerpc/platforms/pasemi/setup.c2
-rw-r--r--arch/powerpc/platforms/pseries/Kconfig2
-rw-r--r--arch/powerpc/platforms/pseries/setup.c3
-rw-r--r--arch/powerpc/sysdev/uic.c18
-rw-r--r--arch/ppc/kernel/setup.c7
-rw-r--r--arch/ppc/mm/init.c2
-rw-r--r--arch/ppc/mm/mmu_decl.h2
-rw-r--r--arch/ppc/platforms/4xx/yucca.c1
-rw-r--r--arch/ppc/syslib/virtex_devices.c31
-rw-r--r--arch/s390/appldata/appldata.h1
-rw-r--r--arch/s390/appldata/appldata_base.c74
-rw-r--r--arch/s390/appldata/appldata_mem.c1
-rw-r--r--arch/s390/appldata/appldata_net_sum.c1
-rw-r--r--arch/s390/appldata/appldata_os.c1
-rw-r--r--arch/s390/kernel/early.c2
-rw-r--r--arch/s390/kernel/entry.S120
-rw-r--r--arch/s390/kernel/entry64.S114
-rw-r--r--arch/s390/kernel/setup.c6
-rw-r--r--arch/s390/kernel/smp.c56
-rw-r--r--arch/s390/kernel/traps.c1
-rw-r--r--arch/s390/mm/cmm.c3
-rw-r--r--arch/x86/Makefile5
-rw-r--r--arch/x86/kernel/acpi/processor.c3
-rw-r--r--arch/x86/kernel/acpi/sleep_64.c3
-rw-r--r--arch/x86/kernel/io_apic_32.c21
-rw-r--r--arch/x86/kernel/io_apic_64.c24
-rw-r--r--arch/x86/pci/acpi.c2
-rw-r--r--drivers/acpi/Kconfig18
-rw-r--r--drivers/acpi/Makefile2
-rw-r--r--drivers/acpi/ac.c20
-rw-r--r--drivers/acpi/battery.c22
-rw-r--r--drivers/acpi/ec.c100
-rw-r--r--drivers/acpi/osl.c25
-rw-r--r--drivers/acpi/processor_core.c19
-rw-r--r--drivers/acpi/processor_idle.c111
-rw-r--r--drivers/acpi/processor_throttling.c286
-rw-r--r--drivers/acpi/sbs.c43
-rw-r--r--drivers/acpi/tables/tbutils.c2
-rw-r--r--drivers/acpi/video.c155
-rw-r--r--drivers/isdn/i4l/isdn_net.c8
-rw-r--r--drivers/misc/thinkpad_acpi.c231
-rw-r--r--drivers/misc/thinkpad_acpi.h4
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c24
-rw-r--r--drivers/s390/cio/css.c2
-rw-r--r--drivers/s390/cio/device_fsm.c2
-rw-r--r--drivers/s390/cio/device_id.c45
-rw-r--r--drivers/zorro/zorro-driver.c15
-rw-r--r--include/acpi/processor.h1
-rw-r--r--include/asm-mips/8253pit.h10
-rw-r--r--include/asm-mips/dma.h1
-rw-r--r--include/asm-mips/futex.h6
-rw-r--r--include/asm-mips/i8253.h2
-rw-r--r--include/asm-mips/ip32/ip32_ints.h2
-rw-r--r--include/asm-mips/system.h8
-rw-r--r--include/asm-mips/time.h16
-rw-r--r--include/asm-powerpc/page_32.h4
-rw-r--r--include/asm-powerpc/pci-bridge.h5
-rw-r--r--include/asm-powerpc/rtas.h3
-rw-r--r--include/asm-powerpc/vdso_datapage.h8
-rw-r--r--include/asm-s390/system.h5
-rw-r--r--include/linux/acpi.h5
-rw-r--r--include/linux/cpuidle.h1
-rw-r--r--include/linux/sysctl.h6
-rw-r--r--include/sound/version.h2
-rw-r--r--kernel/sysctl_check.c14
-rw-r--r--mm/rmap.c9
-rw-r--r--net/iucv/iucv.c107
-rw-r--r--sound/drivers/mpu401/mpu401_uart.c12
-rw-r--r--sound/drivers/portman2x4.c2
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c18
-rw-r--r--sound/pci/ca0106/ca0106_proc.c4
-rw-r--r--sound/pci/cmipci.c5
-rw-r--r--sound/pci/emu10k1/emumixer.c65
-rw-r--r--sound/pci/emu10k1/p16v.c4
-rw-r--r--sound/pci/hda/hda_codec.c40
-rw-r--r--sound/pci/hda/hda_local.h1
-rw-r--r--sound/pci/hda/patch_analog.c8
-rw-r--r--sound/pci/hda/patch_sigmatel.c57
-rw-r--r--sound/soc/codecs/cs4270.c3
-rw-r--r--sound/soc/s3c24xx/s3c2443-ac97.c2
137 files changed, 2378 insertions, 1347 deletions
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index ac1be25c1e2..e9a3cb1d6b0 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -1645,8 +1645,9 @@ platforms are moved over to use the flattened-device-tree model.
MAC addresses passed by the firmware when no information other
than indices is available to associate an address with a device.
- phy-connection-type : a string naming the controller/PHY interface type,
- i.e., "mii" (default), "rmii", "gmii", "rgmii", "rgmii-id", "tbi",
- or "rtbi".
+ i.e., "mii" (default), "rmii", "gmii", "rgmii", "rgmii-id" (Internal
+ Delay), "rgmii-txid" (delay on TX only), "rgmii-rxid" (delay on RX only),
+ "tbi", or "rtbi".
Example:
ucc@2000 {
diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt
index ec499265dec..10c041ca13c 100644
--- a/Documentation/thinkpad-acpi.txt
+++ b/Documentation/thinkpad-acpi.txt
@@ -1,7 +1,7 @@
ThinkPad ACPI Extras Driver
- Version 0.16
- August 2nd, 2007
+ Version 0.17
+ October 04th, 2007
Borislav Deianov <borislav@users.sf.net>
Henrique de Moraes Holschuh <hmh@hmh.eng.br>
@@ -923,19 +923,34 @@ sysfs backlight device "thinkpad_screen"
This feature allows software control of the LCD brightness on ThinkPad
models which don't have a hardware brightness slider.
-It has some limitations: the LCD backlight cannot be actually turned on or off
-by this interface, and in many ThinkPad models, the "dim while on battery"
-functionality will be enabled by the BIOS when this interface is used, and
-cannot be controlled.
-
-The backlight control has eight levels, ranging from 0 to 7. Some of the
-levels may not be distinct.
-
-There are two interfaces to the firmware for brightness control, EC and CMOS.
-To select which one should be used, use the brightness_mode module parameter:
-brightness_mode=1 selects EC mode, brightness_mode=2 selects CMOS mode,
-brightness_mode=3 selects both EC and CMOS. The driver tries to autodetect
-which interface to use.
+It has some limitations: the LCD backlight cannot be actually turned on or
+off by this interface, and in many ThinkPad models, the "dim while on
+battery" functionality will be enabled by the BIOS when this interface is
+used, and cannot be controlled.
+
+On IBM (and some of the earlier Lenovo) ThinkPads, the backlight control
+has eight brightness levels, ranging from 0 to 7. Some of the levels
+may not be distinct. Later Lenovo models that implement the ACPI
+display backlight brightness control methods have 16 levels, ranging
+from 0 to 15.
+
+There are two interfaces to the firmware for direct brightness control,
+EC and CMOS. To select which one should be used, use the
+brightness_mode module parameter: brightness_mode=1 selects EC mode,
+brightness_mode=2 selects CMOS mode, brightness_mode=3 selects both EC
+and CMOS. The driver tries to autodetect which interface to use.
+
+When display backlight brightness controls are available through the
+standard ACPI interface, it is best to use it instead of this direct
+ThinkPad-specific interface. The driver will disable its native
+backlight brightness control interface if it detects that the standard
+ACPI interface is available in the ThinkPad.
+
+The brightness_enable module parameter can be used to control whether
+the LCD brightness control feature will be enabled when available.
+brightness_enable=0 forces it to be disabled. brightness_enable=1
+forces it to be enabled when available, even if the standard ACPI
+interface is also available.
Procfs notes:
@@ -947,11 +962,11 @@ Procfs notes:
Sysfs notes:
-The interface is implemented through the backlight sysfs class, which is poorly
-documented at this time.
+The interface is implemented through the backlight sysfs class, which is
+poorly documented at this time.
-Locate the thinkpad_screen device under /sys/class/backlight, and inside it
-there will be the following attributes:
+Locate the thinkpad_screen device under /sys/class/backlight, and inside
+it there will be the following attributes:
max_brightness:
Reads the maximum brightness the hardware can be set to.
@@ -961,17 +976,19 @@ there will be the following attributes:
Reads what brightness the screen is set to at this instant.
brightness:
- Writes request the driver to change brightness to the given
- value. Reads will tell you what brightness the driver is trying
- to set the display to when "power" is set to zero and the display
- has not been dimmed by a kernel power management event.
+ Writes request the driver to change brightness to the
+ given value. Reads will tell you what brightness the
+ driver is trying to set the display to when "power" is set
+ to zero and the display has not been dimmed by a kernel
+ power management event.
power:
- power management mode, where 0 is "display on", and 1 to 3 will
- dim the display backlight to brightness level 0 because
- thinkpad-acpi cannot really turn the backlight off. Kernel
- power management events can temporarily increase the current
- power management level, i.e. they can dim the display.
+ power management mode, where 0 is "display on", and 1 to 3
+ will dim the display backlight to brightness level 0
+ because thinkpad-acpi cannot really turn the backlight
+ off. Kernel power management events can temporarily
+ increase the current power management level, i.e. they can
+ dim the display.
Volume control -- /proc/acpi/ibm/volume
diff --git a/MAINTAINERS b/MAINTAINERS
index cad0882754a..a8df8e40e39 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2446,7 +2446,7 @@ M68K ON APPLE MACINTOSH
P: Joshua Thompson
M: funaho@jurai.org
W: http://www.mac.linux-m68k.org/
-L: linux-mac68k@mac.linux-m68k.org
+L: linux-m68k@lists.linux-m68k.org
S: Maintained
M68K ON HP9000/300
diff --git a/arch/m68k/atari/atakeyb.c b/arch/m68k/atari/atakeyb.c
index 880add120eb..8a2a53b3361 100644
--- a/arch/m68k/atari/atakeyb.c
+++ b/arch/m68k/atari/atakeyb.c
@@ -565,7 +565,7 @@ void atari_kbd_leds(unsigned int leds)
static int atari_keyb_done = 0;
-int __init atari_keyb_init(void)
+int atari_keyb_init(void)
{
if (atari_keyb_done)
return 0;
@@ -631,6 +631,7 @@ int __init atari_keyb_init(void)
atari_keyb_done = 1;
return 0;
}
+EXPORT_SYMBOL_GPL(atari_keyb_init);
int atari_kbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode)
{
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 2f2ce0c28bc..455bd1f560a 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -22,6 +22,7 @@ config MACH_ALCHEMY
config BASLER_EXCITE
bool "Basler eXcite smart camera"
select CEVT_R4K
+ select CSRC_R4K
select DMA_COHERENT
select HW_HAS_PCI
select IRQ_CPU
@@ -49,6 +50,7 @@ config BASLER_EXCITE_PROTOTYPE
config BCM47XX
bool "BCM47XX based boards"
select CEVT_R4K
+ select CSRC_R4K
select DMA_NONCOHERENT
select HW_HAS_PCI
select IRQ_CPU
@@ -66,6 +68,7 @@ config BCM47XX
config MIPS_COBALT
bool "Cobalt Server"
select CEVT_R4K
+ select CSRC_R4K
select CEVT_GT641XX
select DMA_NONCOHERENT
select HW_HAS_PCI
@@ -85,6 +88,7 @@ config MACH_DECSTATION
bool "DECstations"
select BOOT_ELF32
select CEVT_R4K
+ select CSRC_R4K
select DMA_NONCOHERENT
select NO_IOPORT
select IRQ_CPU
@@ -117,6 +121,7 @@ config MACH_JAZZ
select ARC32
select ARCH_MAY_HAVE_PC_FDC
select CEVT_R4K
+ select CSRC_R4K
select GENERIC_ISA_DMA
select IRQ_CPU
select I8253
@@ -137,6 +142,7 @@ config MACH_JAZZ
config LASAT
bool "LASAT Networks platforms"
select CEVT_R4K
+ select CSRC_R4K
select DMA_NONCOHERENT
select SYS_HAS_EARLY_PRINTK
select HW_HAS_PCI
@@ -154,6 +160,7 @@ config LEMOTE_FULONG
bool "Lemote Fulong mini-PC"
select ARCH_SPARSEMEM_ENABLE
select CEVT_R4K
+ select CSRC_R4K
select SYS_HAS_CPU_LOONGSON2
select DMA_NONCOHERENT
select BOOT_ELF32
@@ -179,6 +186,7 @@ config MIPS_ATLAS
bool "MIPS Atlas board"
select BOOT_ELF32
select CEVT_R4K
+ select CSRC_R4K
select DMA_NONCOHERENT
select SYS_HAS_EARLY_PRINTK
select IRQ_CPU
@@ -210,6 +218,7 @@ config MIPS_MALTA
select ARCH_MAY_HAVE_PC_FDC
select BOOT_ELF32
select CEVT_R4K
+ select CSRC_R4K
select DMA_NONCOHERENT
select GENERIC_ISA_DMA
select IRQ_CPU
@@ -241,6 +250,7 @@ config MIPS_MALTA
config MIPS_SEAD
bool "MIPS SEAD board"
select CEVT_R4K
+ select CSRC_R4K
select IRQ_CPU
select DMA_NONCOHERENT
select SYS_HAS_EARLY_PRINTK
@@ -260,6 +270,7 @@ config MIPS_SEAD
config MIPS_SIM
bool 'MIPS simulator (MIPSsim)'
select CEVT_R4K
+ select CSRC_R4K
select DMA_NONCOHERENT
select SYS_HAS_EARLY_PRINTK
select IRQ_CPU
@@ -278,6 +289,7 @@ config MIPS_SIM
config MARKEINS
bool "NEC EMMA2RH Mark-eins"
select CEVT_R4K
+ select CSRC_R4K
select DMA_NONCOHERENT
select HW_HAS_PCI
select IRQ_CPU
@@ -293,6 +305,7 @@ config MARKEINS
config MACH_VR41XX
bool "NEC VR4100 series based machines"
select CEVT_R4K
+ select CSRC_R4K
select SYS_HAS_CPU_VR41XX
select GENERIC_HARDIRQS_NO__DO_IRQ
@@ -330,6 +343,7 @@ config PMC_MSP
config PMC_YOSEMITE
bool "PMC-Sierra Yosemite eval board"
select CEVT_R4K
+ select CSRC_R4K
select DMA_COHERENT
select HW_HAS_PCI
select IRQ_CPU
@@ -351,6 +365,7 @@ config PMC_YOSEMITE
config QEMU
bool "Qemu"
select CEVT_R4K
+ select CSRC_R4K
select DMA_COHERENT
select GENERIC_ISA_DMA
select HAVE_STD_PC_SERIAL_PORT
@@ -382,9 +397,11 @@ config SGI_IP22
select ARC32
select BOOT_ELF32
select CEVT_R4K
+ select CSRC_R4K
select DMA_NONCOHERENT
select HW_HAS_EISA
select I8253
+ select I8259
select IP22_CPU_SCACHE
select IRQ_CPU
select GENERIC_ISA_DMA_SUPPORT_BROKEN
@@ -427,6 +444,7 @@ config SGI_IP32
select ARC32
select BOOT_ELF32
select CEVT_R4K
+ select CSRC_R4K
select DMA_NONCOHERENT
select HW_HAS_PCI
select IRQ_CPU
@@ -498,6 +516,7 @@ config SIBYTE_SWARM
select SYS_SUPPORTS_HIGHMEM
select SYS_SUPPORTS_KGDB
select SYS_SUPPORTS_LITTLE_ENDIAN
+ select ZONE_DMA32 if 64BIT
config SIBYTE_LITTLESUR
bool "Sibyte BCM91250C2-LittleSur"
@@ -548,6 +567,7 @@ config SIBYTE_BIGSUR
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_HIGHMEM
select SYS_SUPPORTS_LITTLE_ENDIAN
+ select ZONE_DMA32 if 64BIT
config SNI_RM
bool "SNI RM200/300/400"
@@ -556,6 +576,7 @@ config SNI_RM
select ARCH_MAY_HAVE_PC_FDC
select BOOT_ELF32
select CEVT_R4K
+ select CSRC_R4K
select DMA_NONCOHERENT
select GENERIC_ISA_DMA
select HW_HAS_EISA
@@ -599,6 +620,7 @@ config TOSHIBA_JMR3927
config TOSHIBA_RBTX4927
bool "Toshiba RBTX49[23]7 board"
select CEVT_R4K
+ select CSRC_R4K
select CEVT_TXX9
select DMA_NONCOHERENT
select HAS_TXX9_SERIAL
@@ -621,6 +643,7 @@ config TOSHIBA_RBTX4927
config TOSHIBA_RBTX4938
bool "Toshiba RBTX4938 board"
select CEVT_R4K
+ select CSRC_R4K
select CEVT_TXX9
select DMA_NONCOHERENT
select HAS_TXX9_SERIAL
@@ -642,6 +665,7 @@ config TOSHIBA_RBTX4938
config WR_PPMC
bool "Wind River PPMC board"
select CEVT_R4K
+ select CSRC_R4K
select IRQ_CPU
select BOOT_ELF32
select DMA_NONCOHERENT
@@ -752,6 +776,9 @@ config CEVT_TXX9
config CSRC_BCM1480
bool
+config CSRC_R4K
+ bool
+
config CSRC_SB1250
bool
@@ -1640,6 +1667,9 @@ config ARCH_DISCONTIGMEM_ENABLE
or have huge holes in the physical address space for other reasons.
See <file:Documentation/vm/numa> for more.
+config ARCH_POPULATES_NODE_MAP
+ def_bool y
+
config ARCH_SPARSEMEM_ENABLE
bool
select SPARSEMEM_STATIC
@@ -1945,6 +1975,9 @@ config I8253
config PCSPEAKER
bool
+config ZONE_DMA32
+ bool
+
source "drivers/pcmcia/Kconfig"
source "drivers/pci/hotplug/Kconfig"
diff --git a/arch/mips/au1000/Kconfig b/arch/mips/au1000/Kconfig
index b36cec58a9a..05d1354aad3 100644
--- a/arch/mips/au1000/Kconfig
+++ b/arch/mips/au1000/Kconfig
@@ -138,6 +138,7 @@ config SOC_AU1X00
bool
select 64BIT_PHYS_ADDR
select CEVT_R4K
+ select CSRC_R4K
select IRQ_CPU
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_32BIT_KERNEL
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index b551535b7e4..ffa08362de1 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o
obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o
obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o
obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o
+obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o
obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o
binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \
@@ -43,6 +44,7 @@ obj-$(CONFIG_CPU_TX49XX) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_VR41XX) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_SMP_UP) += smp-up.o
obj-$(CONFIG_MIPS_MT) += mips-mt.o
obj-$(CONFIG_MIPS_MT_FPAFF) += mips-mt-fpaff.o
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
index bab935a3d74..24a2d907aa0 100644
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -219,7 +219,7 @@ static int c0_compare_int_usable(void)
return 1;
}
-void __cpuinit mips_clockevent_init(void)
+int __cpuinit mips_clockevent_init(void)
{
uint64_t mips_freq = mips_hpt_frequency;
unsigned int cpu = smp_processor_id();
@@ -227,7 +227,7 @@ void __cpuinit mips_clockevent_init(void)
unsigned int irq;
if (!cpu_has_counter || !mips_hpt_frequency)
- return;
+ return -ENXIO;
#ifdef CONFIG_MIPS_MT_SMTC
setup_smtc_dummy_clockevent_device();
@@ -237,11 +237,11 @@ void __cpuinit mips_clockevent_init(void)
* device.
*/
if (cpu)
- return;
+ return 0;
#endif
if (!c0_compare_int_usable())
- return;
+ return -ENXIO;
/*
* With vectored interrupts things are getting platform specific.
@@ -276,8 +276,8 @@ void __cpuinit mips_clockevent_init(void)
clockevents_register_device(cd);
- if (!cp0_timer_irq_installed)
- return;
+ if (cp0_timer_irq_installed)
+ return 0;
cp0_timer_irq_installed = 1;
@@ -287,4 +287,6 @@ void __cpuinit mips_clockevent_init(void)
#else
setup_irq(irq, &c0_compare_irqaction);
#endif
+
+ return 0;
}
diff --git a/arch/mips/kernel/csrc-r4k.c b/arch/mips/kernel/csrc-r4k.c
new file mode 100644
index 00000000000..74c5c62365a
--- /dev/null
+++ b/arch/mips/kernel/csrc-r4k.c
@@ -0,0 +1,29 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 by Ralf Baechle
+ */
+
+static cycle_t c0_hpt_read(void)
+{
+ return read_c0_count();
+}
+
+static struct clocksource clocksource_mips = {
+ .name = "MIPS",
+ .read = c0_hpt_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void __init init_mips_clocksource(void)
+{
+ /* Calclate a somewhat reasonable rating value */
+ clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
+
+ clocksource_set_clock(&clocksource_mips, mips_hpt_frequency);
+
+ clocksource_register(&clocksource_mips);
+}
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index a06a27d6cfc..7f6ddcb5d48 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -269,7 +269,7 @@ static void __init bootmem_init(void)
static void __init bootmem_init(void)
{
- unsigned long reserved_end;
+ unsigned long init_begin, reserved_end;
unsigned long mapstart = ~0UL;
unsigned long bootmap_size;
int i;
@@ -342,6 +342,35 @@ static void __init bootmem_init(void)
*/
bootmap_size = init_bootmem_node(NODE_DATA(0), mapstart,
min_low_pfn, max_low_pfn);
+
+
+ init_begin = PFN_UP(__pa_symbol(&__init_begin));
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ unsigned long start, end;
+
+ start = PFN_UP(boot_mem_map.map[i].addr);
+ end = PFN_DOWN(boot_mem_map.map[i].addr
+ + boot_mem_map.map[i].size);
+
+ if (start <= init_begin)
+ start = init_begin;
+ if (start >= end)
+ continue;
+
+#ifndef CONFIG_HIGHMEM
+ if (end > max_low_pfn)
+ end = max_low_pfn;
+
+ /*
+ * ... finally, is the area going away?
+ */
+ if (end <= start)
+ continue;
+#endif
+
+ add_active_range(0, start, end);
+ }
+
/*
* Register fully available low RAM pages with the bootmem allocator.
*/
diff --git a/arch/mips/kernel/smp-up.c b/arch/mips/kernel/smp-up.c
new file mode 100644
index 00000000000..ead6c30eeb1
--- /dev/null
+++ b/arch/mips/kernel/smp-up.c
@@ -0,0 +1,67 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006, 07 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * Symmetric Uniprocessor (TM) Support
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+/*
+ * Send inter-processor interrupt
+ */
+void up_send_ipi_single(int cpu, unsigned int action)
+{
+ panic(KERN_ERR "%s called", __func__);
+}
+
+static inline void up_send_ipi_mask(cpumask_t mask, unsigned int action)
+{
+ panic(KERN_ERR "%s called", __func__);
+}
+
+/*
+ * After we've done initial boot, this function is called to allow the
+ * board code to clean up state, if needed
+ */
+void __cpuinit up_init_secondary(void)
+{
+}
+
+void __cpuinit up_smp_finish(void)
+{
+}
+
+/* Hook for after all CPUs are online */
+void up_cpus_done(void)
+{
+}
+
+/*
+ * Firmware CPU startup hook
+ */
+void __cpuinit up_boot_secondary(int cpu, struct task_struct *idle)
+{
+}
+
+void __init up_smp_setup(void)
+{
+}
+
+void __init up_prepare_cpus(unsigned int max_cpus)
+{
+}
+
+struct plat_smp_ops up_smp_ops = {
+ .send_ipi_single = up_send_ipi_single,
+ .send_ipi_mask = up_send_ipi_mask,
+ .init_secondary = up_init_secondary,
+ .smp_finish = up_smp_finish,
+ .cpus_done = up_cpus_done,
+ .boot_secondary = up_boot_secondary,
+ .smp_setup = up_smp_setup,
+ .prepare_cpus = up_prepare_cpus,
+};
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 3284b9b4eca..52075426c37 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -50,14 +50,6 @@ int update_persistent_clock(struct timespec now)
return rtc_mips_set_mmss(now.tv_sec);
}
-/*
- * High precision timer functions for a R4k-compatible timer.
- */
-static cycle_t c0_hpt_read(void)
-{
- return read_c0_count();
-}
-
int (*mips_timer_state)(void);
int null_perf_irq(void)
@@ -84,55 +76,6 @@ EXPORT_SYMBOL(perf_irq);
unsigned int mips_hpt_frequency;
-static struct clocksource clocksource_mips = {
- .name = "MIPS",
- .read = c0_hpt_read,
- .mask = CLOCKSOURCE_MASK(32),
- .flags = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-static unsigned int __init calibrate_hpt(void)
-{
- cycle_t frequency, hpt_start, hpt_end, hpt_count, hz;
-
- const int loops = HZ / 10;
- int log_2_loops = 0;
- int i;
-
- /*
- * We want to calibrate for 0.1s, but to avoid a 64-bit
- * division we round the number of loops up to the nearest
- * power of 2.
- */
- while (loops > 1 << log_2_loops)
- log_2_loops++;
- i = 1 << log_2_loops;
-
- /*
- * Wait for a rising edge of the timer interrupt.
- */
- while (mips_timer_state());
- while (!mips_timer_state());
-
- /*
- * Now see how many high precision timer ticks happen
- * during the calculated number of periods between timer
- * interrupts.
- */
- hpt_start = clocksource_mips.read();
- do {
- while (mips_timer_state());
- while (!mips_timer_state());
- } while (--i);
- hpt_end = clocksource_mips.read();
-
- hpt_count = (hpt_end - hpt_start) & clocksource_mips.mask;
- hz = HZ;
- frequency = hpt_count * hz;
-
- return frequency >> log_2_loops;
-}
-
void __init clocksource_set_clock(struct clocksource *cs, unsigned int clock)
{
u64 temp;
@@ -166,16 +109,6 @@ void __cpuinit clockevent_set_clock(struct clock_event_device *cd,
cd->mult = (u32) temp;
}
-static void __init init_mips_clocksource(void)
-{
- /* Calclate a somewhat reasonable rating value */
- clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
-
- clocksource_set_clock(&clocksource_mips, mips_hpt_frequency);
-
- clocksource_register(&clocksource_mips);
-}
-
void __init __weak plat_time_init(void)
{
}
@@ -194,21 +127,42 @@ void __init plat_timer_setup(void)
BUG();
}
+static __init int cpu_has_mfc0_count_bug(void)
+{
+ switch (current_cpu_type()) {
+ case CPU_R4000PC:
+ case CPU_R4000SC:
+ case CPU_R4000MC:
+ /*
+ * V3.0 is documented as suffering from the mfc0 from count bug.
+ * Afaik this is the last version of the R4000. Later versions
+ * were marketed as R4400.
+ */
+ return 1;
+
+ case CPU_R4400PC:
+ case CPU_R4400SC:
+ case CPU_R4400MC:
+ /*
+ * The published errata for the R4400 upto 3.0 say the CPU
+ * has the mfc0 from count bug.
+ */
+ if ((current_cpu_data.processor_id & 0xff) <= 0x30)
+ return 1;
+
+ /*
+ * I don't have erratas for newer R4400 so be paranoid.
+ */
+ return 1;
+ }
+
+ return 0;
+}
+
void __init time_init(void)
{
plat_time_init();
- if (cpu_has_counter && (mips_hpt_frequency || mips_timer_state)) {
- /* We know counter frequency. Or we can get it. */
- if (!mips_hpt_frequency)
- mips_hpt_frequency = calibrate_hpt();
-
- /* Report the high precision timer rate for a reference. */
- printk("Using %u.%03u MHz high precision timer.\n",
- ((mips_hpt_frequency + 500) / 1000) / 1000,
- ((mips_hpt_frequency + 500) / 1000) % 1000);
+ if (mips_clockevent_init() || !cpu_has_mfc0_count_bug())
init_mips_clocksource();
- }
-
- mips_clockevent_init();
}
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 38bd33fa2a2..c06eb812a95 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -470,7 +470,7 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location,
*/
if (v != l->value) {
printk(KERN_DEBUG "VPE loader: "
- "apply_r_mips_lo16/hi16: "
+ "apply_r_mips_lo16/hi16: \t"
"inconsistent value information\n");
return -ENOEXEC;
}
@@ -629,7 +629,7 @@ static void simplify_symbols(Elf_Shdr * sechdrs,
break;
case SHN_MIPS_SCOMMON:
- printk(KERN_DEBUG "simplify_symbols: ignoring SHN_MIPS_SCOMMON"
+ printk(KERN_DEBUG "simplify_symbols: ignoring SHN_MIPS_SCOMMON "
"symbol <%s> st_shndx %d\n", strtab + sym[i].st_name,
sym[i].st_shndx);
// .sbss section
diff --git a/arch/mips/math-emu/ieee754.c b/arch/mips/math-emu/ieee754.c
index 946aee33178..cb1b6822711 100644
--- a/arch/mips/math-emu/ieee754.c
+++ b/arch/mips/math-emu/ieee754.c
@@ -108,6 +108,7 @@ int ieee754si_xcpt(int r, const char *op, ...)
ax.rv.si = r;
va_start(ax.ap, op);
ieee754_xcpt(&ax);
+ va_end(ax.ap);
return ax.rv.si;
}
@@ -122,5 +123,6 @@ s64 ieee754di_xcpt(s64 r, const char *op, ...)
ax.rv.di = r;
va_start(ax.ap, op);
ieee754_xcpt(&ax);
+ va_end(ax.ap);
return ax.rv.di;
}
diff --git a/arch/mips/math-emu/ieee754dp.c b/arch/mips/math-emu/ieee754dp.c
index 3e214aac4b1..6d2d89f3247 100644
--- a/arch/mips/math-emu/ieee754dp.c
+++ b/arch/mips/math-emu/ieee754dp.c
@@ -57,6 +57,7 @@ ieee754dp ieee754dp_xcpt(ieee754dp r, const char *op, ...)
ax.rv.dp = r;
va_start(ax.ap, op);
ieee754_xcpt(&ax);
+ va_end(ax.ap);
return ax.rv.dp;
}
@@ -83,6 +84,7 @@ ieee754dp ieee754dp_nanxcpt(ieee754dp r, const char *op, ...)
ax.rv.dp = r;
va_start(ax.ap, op);
ieee754_xcpt(&ax);
+ va_end(ax.ap);
return ax.rv.dp;
}
diff --git a/arch/mips/math-emu/ieee754sp.c b/arch/mips/math-emu/ieee754sp.c
index adda851cd04..463534045ab 100644
--- a/arch/mips/math-emu/ieee754sp.c
+++ b/arch/mips/math-emu/ieee754sp.c
@@ -58,6 +58,7 @@ ieee754sp ieee754sp_xcpt(ieee754sp r, const char *op, ...)
ax.rv.sp = r;
va_start(ax.ap, op);
ieee754_xcpt(&ax);
+ va_end(ax.ap);
return ax.rv.sp;
}
@@ -84,6 +85,7 @@ ieee754sp ieee754sp_nanxcpt(ieee754sp r, const char *op, ...)
ax.rv.sp = r;
va_start(ax.ap, op);
ieee754_xcpt(&ax);
+ va_end(ax.ap);
return ax.rv.sp;
}
diff --git a/arch/mips/mipssim/sim_time.c b/arch/mips/mipssim/sim_time.c
index bfaafa38846..e39bbe989da 100644
--- a/arch/mips/mipssim/sim_time.c
+++ b/arch/mips/mipssim/sim_time.c
@@ -101,9 +101,7 @@ unsigned __init get_c0_compare_int(void)
void __init plat_time_init(void)
{
- unsigned int est_freq, flags;
-
- local_irq_save(flags);
+ unsigned int est_freq;
/* Set Data mode - binary. */
CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
@@ -114,6 +112,4 @@ void __init plat_time_init(void)
(est_freq % 1000000) * 100 / 1000000);
cpu_khz = est_freq / 1000;
-
- local_irq_restore(flags);
}
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 33519ce4954..ae76795685c 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -40,16 +40,38 @@ static inline int cpu_is_noncoherent_r10000(struct device *dev)
current_cpu_type() == CPU_R12000);
}
+static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp)
+{
+ /* ignore region specifiers */
+ gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
+
+#ifdef CONFIG_ZONE_DMA32
+ if (dev == NULL)
+ gfp |= __GFP_DMA;
+ else if (dev->coherent_dma_mask < DMA_BIT_MASK(24))
+ gfp |= __GFP_DMA;
+ else
+#endif
+#ifdef CONFIG_ZONE_DMA32
+ if (dev->coherent_dma_mask < DMA_BIT_MASK(32))
+ gfp |= __GFP_DMA32;
+ else
+#endif
+ ;
+
+ /* Don't invoke OOM killer */
+ gfp |= __GFP_NORETRY;
+
+ return gfp;
+}
+
void *dma_alloc_noncoherent(struct device *dev, size_t size,
dma_addr_t * dma_handle, gfp_t gfp)
{
void *ret;
- /* ignore region specifiers */
- gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
+ gfp = massage_gfp_flags(dev, gfp);
- if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
- gfp |= GFP_DMA;
ret = (void *) __get_free_pages(gfp, get_order(size));
if (ret != NULL) {
@@ -67,11 +89,8 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
{
void *ret;
- /* ignore region specifiers */
- gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
+ gfp = massage_gfp_flags(dev, gfp);
- if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
- gfp |= GFP_DMA;
ret = (void *) __get_free_pages(gfp, get_order(size));
if (ret) {
@@ -343,7 +362,7 @@ int dma_supported(struct device *dev, u64 mask)
* so we can't guarantee allocations that must be
* within a tighter range than GFP_DMA..
*/
- if (mask < 0x00ffffff)
+ if (mask < DMA_BIT_MASK(24))
return 0;
return 1;
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index ec3b9e9f30f..480dec04f55 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -347,11 +347,8 @@ static int __init page_is_ram(unsigned long pagenr)
void __init paging_init(void)
{
- unsigned long zones_size[MAX_NR_ZONES] = { 0, };
-#ifndef CONFIG_FLATMEM
- unsigned long zholes_size[MAX_NR_ZONES] = { 0, };
- unsigned long i, j, pfn;
-#endif
+ unsigned long max_zone_pfns[MAX_NR_ZONES];
+ unsigned long lastpfn;
pagetable_init();
@@ -361,35 +358,27 @@ void __init paging_init(void)
kmap_coherent_init();
#ifdef CONFIG_ZONE_DMA
- if (min_low_pfn < MAX_DMA_PFN && MAX_DMA_PFN <= max_low_pfn) {
- zones_size[ZONE_DMA] = MAX_DMA_PFN - min_low_pfn;
- zones_size[ZONE_NORMAL] = max_low_pfn - MAX_DMA_PFN;
- } else if (max_low_pfn < MAX_DMA_PFN)
- zones_size[ZONE_DMA] = max_low_pfn - min_low_pfn;
- else
+ max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN;
#endif
- zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn;
-
+#ifdef CONFIG_ZONE_DMA32
+ max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN;
+#endif
+ max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
+ lastpfn = max_low_pfn;
#ifdef CONFIG_HIGHMEM
- zones_size[ZONE_HIGHMEM] = highend_pfn - highstart_pfn;
+ max_zone_pfns[ZONE_HIGHMEM] = highend_pfn;
+ lastpfn = highend_pfn;
- if (cpu_has_dc_aliases && zones_size[ZONE_HIGHMEM]) {
+ if (cpu_has_dc_aliases && max_low_pfn != highend_pfn) {
printk(KERN_WARNING "This processor doesn't support highmem."
- " %ldk highmem ignored\n", zones_size[ZONE_HIGHMEM]);
- zones_size[ZONE_HIGHMEM] = 0;
+ " %ldk highmem ignored\n",
+ (highend_pfn - max_low_pfn) << (PAGE_SHIFT - 10));
+ max_zone_pfns[ZONE_HIGHMEM] = max_low_pfn;
+ lastpfn = max_low_pfn;
}
#endif
-#ifdef CONFIG_FLATMEM
- free_area_init(zones_size);
-#else
- pfn = min_low_pfn;
- for (i = 0; i < MAX_NR_ZONES; i++)
- for (j = 0; j < zones_size[i]; j++, pfn++)
- if (!page_is_ram(pfn))
- zholes_size[i]++;
- free_area_init_node(0, NODE_DATA(0), zones_size, 0, zholes_size);
-#endif
+ free_area_init_nodes(max_zone_pfns);
}
static struct kcore_list kcore_mem, kcore_vmalloc;
diff --git a/arch/mips/pmc-sierra/Kconfig b/arch/mips/pmc-sierra/Kconfig
index 6b293ce0935..90261b83db0 100644
--- a/arch/mips/pmc-sierra/Kconfig
+++ b/arch/mips/pmc-sierra/Kconfig
@@ -5,12 +5,14 @@ choice
config PMC_MSP4200_EVAL
bool "PMC-Sierra MSP4200 Eval Board"
select CEVT_R4K
+ select CSRC_R4K
select IRQ_MSP_SLP
select HW_HAS_PCI
config PMC_MSP4200_GW
bool "PMC-Sierra MSP4200 VoIP Gateway"
select CEVT_R4K
+ select CSRC_R4K
select IRQ_MSP_SLP
select HW_HAS_PCI
diff --git a/arch/mips/sgi-ip22/ip22-eisa.c b/arch/mips/sgi-ip22/ip22-eisa.c
index 26854fb11e7..1617241d273 100644
--- a/arch/mips/sgi-ip22/ip22-eisa.c
+++ b/arch/mips/sgi-ip22/ip22-eisa.c
@@ -36,6 +36,7 @@
#include <asm/sgi/ioc.h>
#include <asm/sgi/mc.h>
#include <asm/sgi/ip22.h>
+#include <asm/i8259.h>
/* I2 has four EISA slots. */
#define IP22_EISA_MAX_SLOTS 4
@@ -93,126 +94,11 @@ static irqreturn_t ip22_eisa_intr(int irq, void *dev_id)
return IRQ_NONE;
}
-static void enable_eisa1_irq(unsigned int irq)
-{
- u8 mask;
-
- mask = inb(EISA_INT1_MASK);
- mask &= ~((u8) (1 << irq));
- outb(mask, EISA_INT1_MASK);
-}
-
-static unsigned int startup_eisa1_irq(unsigned int irq)
-{
- u8 edge;
-
- /* Only use edge interrupts for EISA */
-
- edge = inb(EISA_INT1_EDGE_LEVEL);
- edge &= ~((u8) (1 << irq));
- outb(edge, EISA_INT1_EDGE_LEVEL);
-
- enable_eisa1_irq(irq);
- return 0;
-}
-
-static void disable_eisa1_irq(unsigned int irq)
-{
- u8 mask;
-
- mask = inb(EISA_INT1_MASK);
- mask |= ((u8) (1 << irq));
- outb(mask, EISA_INT1_MASK);
-}
-
-static void mask_and_ack_eisa1_irq(unsigned int irq)
-{
- disable_eisa1_irq(irq);
-
- outb(0x20, EISA_INT1_CTRL);
-}
-
-static void end_eisa1_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
- enable_eisa1_irq(irq);
-}
-
-static struct irq_chip ip22_eisa1_irq_type = {
- .name = "IP22 EISA",
- .startup = startup_eisa1_irq,
- .ack = mask_and_ack_eisa1_irq,
- .mask = disable_eisa1_irq,
- .mask_ack = mask_and_ack_eisa1_irq,
- .unmask = enable_eisa1_irq,
- .end = end_eisa1_irq,
-};
-
-static void enable_eisa2_irq(unsigned int irq)
-{
- u8 mask;
-
- mask = inb(EISA_INT2_MASK);
- mask &= ~((u8) (1 << (irq - 8)));
- outb(mask, EISA_INT2_MASK);
-}
-
-static unsigned int startup_eisa2_irq(unsigned int irq)
-{
- u8 edge;
-
- /* Only use edge interrupts for EISA */
-
- edge = inb(EISA_INT2_EDGE_LEVEL);
- edge &= ~((u8) (1 << (irq - 8)));
- outb(edge, EISA_INT2_EDGE_LEVEL);
-
- enable_eisa2_irq(irq);
- return 0;
-}
-
-static void disable_eisa2_irq(unsigned int irq)
-{
- u8 mask;
-
- mask = inb(EISA_INT2_MASK);
- mask |= ((u8) (1 << (irq - 8)));
- outb(mask, EISA_INT2_MASK);
-}
-
-static void mask_and_ack_eisa2_irq(unsigned int irq)
-{
- disable_eisa2_irq(irq);
-
- outb(0x20, EISA_INT2_CTRL);
-}
-
-static void end_eisa2_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
- enable_eisa2_irq(irq);
-}
-
-static struct irq_chip ip22_eisa2_irq_type = {
- .name = "IP22 EISA",
- .startup = startup_eisa2_irq,
- .ack = mask_and_ack_eisa2_irq,
- .mask = disable_eisa2_irq,
- .mask_ack = mask_and_ack_eisa2_irq,
- .unmask = enable_eisa2_irq,
- .end = end_eisa2_irq,
-};
-
static struct irqaction eisa_action = {
.handler = ip22_eisa_intr,
.name = "EISA",
};
-static struct irqaction cascade_action = {
- .handler = no_action,
- .name = "EISA cascade",
-};
-
int __init ip22_eisa_init(void)
{
int i, c;
@@ -248,29 +134,13 @@ int __init ip22_eisa_init(void)
outb(1, EISA_EXT_NMI_RESET_CTRL);
udelay(50); /* Wait long enough for the dust to settle */
outb(0, EISA_EXT_NMI_RESET_CTRL);
- outb(0x11, EISA_INT1_CTRL);
- outb(0x11, EISA_INT2_CTRL);
- outb(0, EISA_INT1_MASK);
- outb(8, EISA_INT2_MASK);
- outb(4, EISA_INT1_MASK);
- outb(2, EISA_INT2_MASK);
- outb(1, EISA_INT1_MASK);
- outb(1, EISA_INT2_MASK);
- outb(0xfb, EISA_INT1_MASK);
- outb(0xff, EISA_INT2_MASK);
outb(0, EISA_DMA2_WRITE_SINGLE);
- for (i = SGINT_EISA; i < (SGINT_EISA + EISA_MAX_IRQ); i++) {
- if (i < (SGINT_EISA + 8))
- set_irq_chip(i, &ip22_eisa1_irq_type);
- else
- set_irq_chip(i, &ip22_eisa2_irq_type);
- }
+ init_i8259_irqs();
/* Cannot use request_irq because of kmalloc not being ready at such
* an early stage. Yes, I've been bitten... */
setup_irq(SGI_EISA_IRQ, &eisa_action);
- setup_irq(SGINT_EISA + 2, &cascade_action);
EISA_bus = 1;
return 0;
diff --git a/arch/mips/sgi-ip22/ip22-nvram.c b/arch/mips/sgi-ip22/ip22-nvram.c
index e19d60d5fcc..0177566475d 100644
--- a/arch/mips/sgi-ip22/ip22-nvram.c
+++ b/arch/mips/sgi-ip22/ip22-nvram.c
@@ -32,19 +32,19 @@
for (x=0; x<100000; x++) __asm__ __volatile__(""); })
#define eeprom_cs_on(ptr) ({ \
- *ptr &= ~EEPROM_DATO; \
- *ptr &= ~EEPROM_ECLK; \
- *ptr &= ~EEPROM_EPROT; \
- delay(); \
- *ptr |= EEPROM_CSEL; \
- *ptr |= EEPROM_ECLK; })
+ __raw_writel(__raw_readl(ptr) & ~EEPROM_DATO, ptr); \
+ __raw_writel(__raw_readl(ptr) & ~EEPROM_ECLK, ptr); \
+ __raw_writel(__raw_readl(ptr) & ~EEPROM_EPROT, ptr); \
+ delay(); \
+ __raw_writel(__raw_readl(ptr) | EEPROM_CSEL, ptr); \
+ __raw_writel(__raw_readl(ptr) | EEPROM_ECLK, ptr); })
#define eeprom_cs_off(ptr) ({ \
- *ptr &= ~EEPROM_ECLK; \
- *ptr &= ~EEPROM_CSEL; \
- *ptr |= EEPROM_EPROT; \
- *ptr |= EEPROM_ECLK; })
+ __raw_writel(__raw_readl(ptr) & ~EEPROM_ECLK, ptr); \
+ __raw_writel(__raw_readl(ptr) & ~EEPROM_CSEL, ptr); \
+ __raw_writel(__raw_readl(ptr) | EEPROM_EPROT, ptr); \
+ __raw_writel(__raw_readl(ptr) | EEPROM_ECLK, ptr); })
#define BITS_IN_COMMAND 11
/*
@@ -60,15 +60,17 @@ static inline void eeprom_cmd(unsigned int *ctrl, unsigned cmd, unsigned reg)
ser_cmd = cmd | (reg << (16 - BITS_IN_COMMAND));
for (i = 0; i < BITS_IN_COMMAND; i++) {
if (ser_cmd & (1<<15)) /* if high order bit set */
- writel(readl(ctrl) | EEPROM_DATO, ctrl);
+ __raw_writel(__raw_readl(ctrl) | EEPROM_DATO, ctrl);
else
- writel(readl(ctrl) & ~EEPROM_DATO, ctrl);
- writel(readl(ctrl) & ~EEPROM_ECLK, ctrl);
- writel(readl(ctrl) | EEPROM_ECLK, ctrl);
+ __raw_writel(__raw_readl(ctrl) & ~EEPROM_DATO, ctrl);
+ __raw_writel(__raw_readl(ctrl) & ~EEPROM_ECLK, ctrl);
+ delay();
+ __raw_writel(__raw_readl(ctrl) | EEPROM_ECLK, ctrl);
+ delay();
ser_cmd <<= 1;
}
/* see data sheet timing diagram */
- writel(readl(ctrl) & ~EEPROM_DATO, ctrl);
+ __raw_writel(__raw_readl(ctrl) & ~EEPROM_DATO, ctrl);
}
unsigned short ip22_eeprom_read(unsigned int *ctrl, int reg)
@@ -76,18 +78,18 @@ unsigned short ip22_eeprom_read(unsigned int *ctrl, int reg)
unsigned short res = 0;
int i;
- writel(readl(ctrl) & ~EEPROM_EPROT, ctrl);
+ __raw_writel(__raw_readl(ctrl) & ~EEPROM_EPROT, ctrl);
eeprom_cs_on(ctrl);
eeprom_cmd(ctrl, EEPROM_READ, reg);
/* clock the data ouf of serial mem */
for (i = 0; i < 16; i++) {
- writel(readl(ctrl) & ~EEPROM_ECLK, ctrl);
+ __raw_writel(__raw_readl(ctrl) & ~EEPROM_ECLK, ctrl);
delay();
- writel(readl(ctrl) | EEPROM_ECLK, ctrl);
+ __raw_writel(__raw_readl(ctrl) | EEPROM_ECLK, ctrl);
delay();
res <<= 1;
- if (readl(ctrl) & EEPROM_DATI)
+ if (__raw_readl(ctrl) & EEPROM_DATI)
res |= 1;
}
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c
index aab17ddd2f3..cab7cc22ab6 100644
--- a/arch/mips/sgi-ip32/ip32-irq.c
+++ b/arch/mips/sgi-ip32/ip32-irq.c
@@ -209,18 +209,18 @@ static unsigned long macepci_mask;
static void enable_macepci_irq(unsigned int irq)
{
- macepci_mask |= MACEPCI_CONTROL_INT(irq - 9);
+ macepci_mask |= MACEPCI_CONTROL_INT(irq - MACEPCI_SCSI0_IRQ);
mace->pci.control = macepci_mask;
- crime_mask |= 1 << (irq - 1);
+ crime_mask |= 1 << (irq - CRIME_IRQ_BASE);
crime->imask = crime_mask;
}
static void disable_macepci_irq(unsigned int irq)
{
- crime_mask &= ~(1 << (irq - 1));
+ crime_mask &= ~(1 << (irq - CRIME_IRQ_BASE));
crime->imask = crime_mask;
flush_crime_bus();
- macepci_mask &= ~MACEPCI_CONTROL_INT(irq - 9);
+ macepci_mask &= ~MACEPCI_CONTROL_INT(irq - MACEPCI_SCSI0_IRQ);
mace->pci.control = macepci_mask;
flush_mace_bus();
}
@@ -299,7 +299,7 @@ static void enable_maceisa_irq(unsigned int irq)
pr_debug("crime_int %08x enabled\n", crime_int);
crime_mask |= crime_int;
crime->imask = crime_mask;
- maceisa_mask |= 1 << (irq - 33);
+ maceisa_mask |= 1 << (irq - MACEISA_AUDIO_SW_IRQ);
mace->perif.ctrl.imask = maceisa_mask;
}
@@ -307,7 +307,7 @@ static void disable_maceisa_irq(unsigned int irq)
{
unsigned int crime_int = 0;
- maceisa_mask &= ~(1 << (irq - 33));
+ maceisa_mask &= ~(1 << (irq - MACEISA_AUDIO_SW_IRQ));
if (!(maceisa_mask & MACEISA_AUDIO_INT))
crime_int |= MACE_AUDIO_INT;
if (!(maceisa_mask & MACEISA_MISC_INT))
@@ -331,7 +331,7 @@ static void mask_and_ack_maceisa_irq(unsigned int irq)
case MACEISA_SERIAL2_TDMAPR_IRQ:
/* edge triggered */
mace_int = mace->perif.ctrl.istat;
- mace_int &= ~(1 << (irq - 33));
+ mace_int &= ~(1 << (irq - MACEISA_AUDIO_SW_IRQ));
mace->perif.ctrl.istat = mace_int;
break;
}
@@ -359,13 +359,17 @@ static struct irq_chip ip32_maceisa_interrupt = {
static void enable_mace_irq(unsigned int irq)
{
- crime_mask |= 1 << (irq - 1);
+ unsigned int bit = irq - CRIME_IRQ_BASE;
+
+ crime_mask |= (1 << bit);
crime->imask = crime_mask;
}
static void disable_mace_irq(unsigned int irq)
{
- crime_mask &= ~(1 << (irq - 1));
+ unsigned int bit = irq - CRIME_IRQ_BASE;
+
+ crime_mask &= ~(1 << bit);
crime->imask = crime_mask;
flush_crime_bus();
}
@@ -489,7 +493,7 @@ void __init arch_init_irq(void)
mace->perif.ctrl.imask = 0;
mips_cpu_irq_init();
- for (irq = MIPS_CPU_IRQ_BASE + 8; irq <= IP32_IRQ_MAX; irq++) {
+ for (irq = CRIME_IRQ_BASE; irq <= IP32_IRQ_MAX; irq++) {
switch (irq) {
case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ:
set_irq_chip(irq, &ip32_mace_interrupt);
diff --git a/arch/mips/vr41xx/Kconfig b/arch/mips/vr41xx/Kconfig
index eeb089f20c0..559acc09c81 100644
--- a/arch/mips/vr41xx/Kconfig
+++ b/arch/mips/vr41xx/Kconfig
@@ -6,6 +6,7 @@ choice
config CASIO_E55
bool "CASIO CASSIOPEIA E-10/15/55/65"
select CEVT_R4K
+ select CSRC_R4K
select DMA_NONCOHERENT
select IRQ_CPU
select ISA
@@ -15,6 +16,7 @@ config CASIO_E55
config IBM_WORKPAD
bool "IBM WorkPad z50"
select CEVT_R4K
+ select CSRC_R4K
select DMA_NONCOHERENT
select IRQ_CPU
select ISA
@@ -24,6 +26,7 @@ config IBM_WORKPAD
config NEC_CMBVR4133
bool "NEC CMB-VR4133"
select CEVT_R4K
+ select CSRC_R4K
select DMA_NONCOHERENT
select IRQ_CPU
select HW_HAS_PCI
@@ -33,6 +36,7 @@ config NEC_CMBVR4133
config TANBAC_TB022X
bool "TANBAC VR4131 multichip module and TANBAC VR4131DIMM"
select CEVT_R4K
+ select CSRC_R4K
select DMA_NONCOHERENT
select IRQ_CPU
select HW_HAS_PCI
@@ -48,6 +52,7 @@ config TANBAC_TB022X
config VICTOR_MPC30X
bool "Victor MP-C303/304"
select CEVT_R4K
+ select CSRC_R4K
select DMA_NONCOHERENT
select IRQ_CPU
select HW_HAS_PCI
@@ -58,6 +63,7 @@ config VICTOR_MPC30X
config ZAO_CAPCELLA
bool "ZAO Networks Capcella"
select CEVT_R4K
+ select CSRC_R4K
select DMA_NONCOHERENT
select IRQ_CPU
select HW_HAS_PCI
diff --git a/arch/powerpc/boot/dts/mpc832x_mds.dts b/arch/powerpc/boot/dts/mpc832x_mds.dts
index fcd333c391e..c64f3037a13 100644
--- a/arch/powerpc/boot/dts/mpc832x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc832x_mds.dts
@@ -57,12 +57,19 @@
};
i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
device_type = "i2c";
compatible = "fsl-i2c";
reg = <3000 100>;
interrupts = <e 8>;
interrupt-parent = < &ipic >;
dfsrr;
+
+ rtc@68 {
+ compatible = "dallas,ds1374";
+ reg = <68>;
+ };
};
serial@4500 {
@@ -104,7 +111,7 @@
reg = <700 100>;
device_type = "ipic";
};
-
+
par_io@1400 {
reg = <1400 100>;
device_type = "par_io";
@@ -117,7 +124,6 @@
3 5 1 0 2 0 /* MDC */
0 d 2 0 1 0 /* RX_CLK (CLK9) */
3 18 2 0 1 0 /* TX_CLK (CLK10) */
- 1 1 1 0 1 0 /* TxD1 */
1 0 1 0 1 0 /* TxD0 */
1 1 1 0 1 0 /* TxD1 */
1 2 1 0 1 0 /* TxD2 */
@@ -165,11 +171,11 @@
reg = <e0100000 480>;
brg-frequency = <0>;
bus-frequency = <BCD3D80>;
-
+
muram@10000 {
device_type = "muram";
ranges = <0 00010000 00004000>;
-
+
data-only@0 {
reg = <0 4000>;
};
@@ -228,7 +234,7 @@
compatible = "ucc_geth";
model = "UCC";
device-id = <4>;
- reg = <3000 200>;
+ reg = <3200 200>;
interrupts = <23>;
interrupt-parent = < &qeic >;
/*
diff --git a/arch/powerpc/boot/dts/mpc834x_mds.dts b/arch/powerpc/boot/dts/mpc834x_mds.dts
index e5a84ef9f4b..49363f89cb7 100644
--- a/arch/powerpc/boot/dts/mpc834x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc834x_mds.dts
@@ -57,15 +57,24 @@
};
i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
device_type = "i2c";
compatible = "fsl-i2c";
reg = <3000 100>;
interrupts = <e 8>;
interrupt-parent = < &ipic >;
dfsrr;
+
+ rtc@68 {
+ compatible = "dallas,ds1374";
+ reg = <68>;
+ };
};
i2c@3100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
device_type = "i2c";
compatible = "fsl-i2c";
reg = <3100 100>;
diff --git a/arch/powerpc/boot/dts/mpc836x_mds.dts b/arch/powerpc/boot/dts/mpc836x_mds.dts
index fbd1573c348..0b2d2b588da 100644
--- a/arch/powerpc/boot/dts/mpc836x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc836x_mds.dts
@@ -62,15 +62,24 @@
};
i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
device_type = "i2c";
compatible = "fsl-i2c";
reg = <3000 100>;
interrupts = <e 8>;
interrupt-parent = < &ipic >;
dfsrr;
+
+ rtc@68 {
+ compatible = "dallas,ds1374";
+ reg = <68>;
+ };
};
i2c@3100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
device_type = "i2c";
compatible = "fsl-i2c";
reg = <3100 100>;
diff --git a/arch/powerpc/boot/dts/mpc8544ds.dts b/arch/powerpc/boot/dts/mpc8544ds.dts
index 3f9d15cf13e..6c608de1fc1 100644
--- a/arch/powerpc/boot/dts/mpc8544ds.dts
+++ b/arch/powerpc/boot/dts/mpc8544ds.dts
@@ -272,24 +272,24 @@
clock-frequency = <1fca055>;
interrupt-parent = <&mpic>;
interrupts = <1b 2>;
- interrupt-map-mask = <fb00 0 0 0>;
+ interrupt-map-mask = <ff00 0 0 1>;
interrupt-map = <
// IDSEL 0x1c USB
- e000 0 0 0 &i8259 c 2
- e100 0 0 0 &i8259 9 2
- e200 0 0 0 &i8259 a 2
- e300 0 0 0 &i8259 b 2
+ e000 0 0 1 &i8259 c 2
+ e100 0 0 1 &i8259 9 2
+ e200 0 0 1 &i8259 a 2
+ e300 0 0 1 &i8259 b 2
// IDSEL 0x1d Audio
- e800 0 0 0 &i8259 6 2
+ e800 0 0 1 &i8259 6 2
// IDSEL 0x1e Legacy
- f000 0 0 0 &i8259 7 2
- f100 0 0 0 &i8259 7 2
+ f000 0 0 1 &i8259 7 2
+ f100 0 0 1 &i8259 7 2
// IDSEL 0x1f IDE/SATA
- f800 0 0 0 &i8259 e 2
- f900 0 0 0 &i8259 5 2
+ f800 0 0 1 &i8259 e 2
+ f900 0 0 1 &i8259 5 2
>;
pcie@0 {
diff --git a/arch/powerpc/boot/dts/mpc8572ds.dts b/arch/powerpc/boot/dts/mpc8572ds.dts
index d638deec765..0eb44fb9647 100644
--- a/arch/powerpc/boot/dts/mpc8572ds.dts
+++ b/arch/powerpc/boot/dts/mpc8572ds.dts
@@ -219,36 +219,120 @@
clock-frequency = <1fca055>;
interrupt-parent = <&mpic>;
interrupts = <18 2>;
- interrupt-map-mask = <fb00 0 0 0>;
+ interrupt-map-mask = <ff00 0 0 7>;
interrupt-map = <
- /* IDSEL 0x11 - PCI slot 1 */
+ /* IDSEL 0x11 func 0 - PCI slot 1 */
8800 0 0 1 &mpic 2 1
8800 0 0 2 &mpic 3 1
8800 0 0 3 &mpic 4 1
8800 0 0 4 &mpic 1 1
- /* IDSEL 0x12 - PCI slot 2 */
+ /* IDSEL 0x11 func 1 - PCI slot 1 */
+ 8900 0 0 1 &mpic 2 1
+ 8900 0 0 2 &mpic 3 1
+ 8900 0 0 3 &mpic 4 1
+ 8900 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 2 - PCI slot 1 */
+ 8a00 0 0 1 &mpic 2 1
+ 8a00 0 0 2 &mpic 3 1
+ 8a00 0 0 3 &mpic 4 1
+ 8a00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 3 - PCI slot 1 */
+ 8b00 0 0 1 &mpic 2 1
+ 8b00 0 0 2 &mpic 3 1
+ 8b00 0 0 3 &mpic 4 1
+ 8b00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 4 - PCI slot 1 */
+ 8c00 0 0 1 &mpic 2 1
+ 8c00 0 0 2 &mpic 3 1
+ 8c00 0 0 3 &mpic 4 1
+ 8c00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 5 - PCI slot 1 */
+ 8d00 0 0 1 &mpic 2 1
+ 8d00 0 0 2 &mpic 3 1
+ 8d00 0 0 3 &mpic 4 1
+ 8d00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 6 - PCI slot 1 */
+ 8e00 0 0 1 &mpic 2 1
+ 8e00 0 0 2 &mpic 3 1
+ 8e00 0 0 3 &mpic 4 1
+ 8e00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 7 - PCI slot 1 */
+ 8f00 0 0 1 &mpic 2 1
+ 8f00 0 0 2 &mpic 3 1
+ 8f00 0 0 3 &mpic 4 1
+ 8f00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x12 func 0 - PCI slot 2 */
9000 0 0 1 &mpic 3 1
9000 0 0 2 &mpic 4 1
9000 0 0 3 &mpic 1 1
9000 0 0 4 &mpic 2 1
+ /* IDSEL 0x12 func 1 - PCI slot 2 */
+ 9100 0 0 1 &mpic 3 1
+ 9100 0 0 2 &mpic 4 1
+ 9100 0 0 3 &mpic 1 1
+ 9100 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 2 - PCI slot 2 */
+ 9200 0 0 1 &mpic 3 1
+ 9200 0 0 2 &mpic 4 1
+ 9200 0 0 3 &mpic 1 1
+ 9200 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 3 - PCI slot 2 */
+ 9300 0 0 1 &mpic 3 1
+ 9300 0 0 2 &mpic 4 1
+ 9300 0 0 3 &mpic 1 1
+ 9300 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 4 - PCI slot 2 */
+ 9400 0 0 1 &mpic 3 1
+ 9400 0 0 2 &mpic 4 1
+ 9400 0 0 3 &mpic 1 1
+ 9400 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 5 - PCI slot 2 */
+ 9500 0 0 1 &mpic 3 1
+ 9500 0 0 2 &mpic 4 1
+ 9500 0 0 3 &mpic 1 1
+ 9500 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 6 - PCI slot 2 */
+ 9600 0 0 1 &mpic 3 1
+ 9600 0 0 2 &mpic 4 1
+ 9600 0 0 3 &mpic 1 1
+ 9600 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 7 - PCI slot 2 */
+ 9700 0 0 1 &mpic 3 1
+ 9700 0 0 2 &mpic 4 1
+ 9700 0 0 3 &mpic 1 1
+ 9700 0 0 4 &mpic 2 1
+
// IDSEL 0x1c USB
- e000 0 0 0 &i8259 c 2
- e100 0 0 0 &i8259 9 2
- e200 0 0 0 &i8259 a 2
- e300 0 0 0 &i8259 b 2
+ e000 0 0 1 &i8259 c 2
+ e100 0 0 1 &i8259 9 2
+ e200 0 0 1 &i8259 a 2
+ e300 0 0 1 &i8259 b 2
// IDSEL 0x1d Audio
- e800 0 0 0 &i8259 6 2
+ e800 0 0 1 &i8259 6 2
// IDSEL 0x1e Legacy
- f000 0 0 0 &i8259 7 2
- f100 0 0 0 &i8259 7 2
+ f000 0 0 1 &i8259 7 2
+ f100 0 0 1 &i8259 7 2
// IDSEL 0x1f IDE/SATA
- f800 0 0 0 &i8259 e 2
- f900 0 0 0 &i8259 5 2
+ f800 0 0 1 &i8259 e 2
+ f900 0 0 1 &i8259 5 2
>;
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
index 367765937a0..abb26dc4255 100644
--- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts
+++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
@@ -235,36 +235,120 @@
clock-frequency = <1fca055>;
interrupt-parent = <&mpic>;
interrupts = <18 2>;
- interrupt-map-mask = <fb00 0 0 0>;
+ interrupt-map-mask = <ff00 0 0 7>;
interrupt-map = <
- /* IDSEL 0x11 */
- 8800 0 0 1 &i8259 9 2
- 8800 0 0 2 &i8259 a 2
- 8800 0 0 3 &i8259 b 2
- 8800 0 0 4 &i8259 c 2
-
- /* IDSEL 0x12 */
- 9000 0 0 1 &i8259 a 2
- 9000 0 0 2 &i8259 b 2
- 9000 0 0 3 &i8259 c 2
- 9000 0 0 4 &i8259 9 2
+ /* IDSEL 0x11 func 0 - PCI slot 1 */
+ 8800 0 0 1 &mpic 2 1
+ 8800 0 0 2 &mpic 3 1
+ 8800 0 0 3 &mpic 4 1
+ 8800 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 1 - PCI slot 1 */
+ 8900 0 0 1 &mpic 2 1
+ 8900 0 0 2 &mpic 3 1
+ 8900 0 0 3 &mpic 4 1
+ 8900 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 2 - PCI slot 1 */
+ 8a00 0 0 1 &mpic 2 1
+ 8a00 0 0 2 &mpic 3 1
+ 8a00 0 0 3 &mpic 4 1
+ 8a00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 3 - PCI slot 1 */
+ 8b00 0 0 1 &mpic 2 1
+ 8b00 0 0 2 &mpic 3 1
+ 8b00 0 0 3 &mpic 4 1
+ 8b00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 4 - PCI slot 1 */
+ 8c00 0 0 1 &mpic 2 1
+ 8c00 0 0 2 &mpic 3 1
+ 8c00 0 0 3 &mpic 4 1
+ 8c00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 5 - PCI slot 1 */
+ 8d00 0 0 1 &mpic 2 1
+ 8d00 0 0 2 &mpic 3 1
+ 8d00 0 0 3 &mpic 4 1
+ 8d00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 6 - PCI slot 1 */
+ 8e00 0 0 1 &mpic 2 1
+ 8e00 0 0 2 &mpic 3 1
+ 8e00 0 0 3 &mpic 4 1
+ 8e00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 7 - PCI slot 1 */
+ 8f00 0 0 1 &mpic 2 1
+ 8f00 0 0 2 &mpic 3 1
+ 8f00 0 0 3 &mpic 4 1
+ 8f00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x12 func 0 - PCI slot 2 */
+ 9000 0 0 1 &mpic 3 1
+ 9000 0 0 2 &mpic 4 1
+ 9000 0 0 3 &mpic 1 1
+ 9000 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 1 - PCI slot 2 */
+ 9100 0 0 1 &mpic 3 1
+ 9100 0 0 2 &mpic 4 1
+ 9100 0 0 3 &mpic 1 1
+ 9100 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 2 - PCI slot 2 */
+ 9200 0 0 1 &mpic 3 1
+ 9200 0 0 2 &mpic 4 1
+ 9200 0 0 3 &mpic 1 1
+ 9200 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 3 - PCI slot 2 */
+ 9300 0 0 1 &mpic 3 1
+ 9300 0 0 2 &mpic 4 1
+ 9300 0 0 3 &mpic 1 1
+ 9300 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 4 - PCI slot 2 */
+ 9400 0 0 1 &mpic 3 1
+ 9400 0 0 2 &mpic 4 1
+ 9400 0 0 3 &mpic 1 1
+ 9400 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 5 - PCI slot 2 */
+ 9500 0 0 1 &mpic 3 1
+ 9500 0 0 2 &mpic 4 1
+ 9500 0 0 3 &mpic 1 1
+ 9500 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 6 - PCI slot 2 */
+ 9600 0 0 1 &mpic 3 1
+ 9600 0 0 2 &mpic 4 1
+ 9600 0 0 3 &mpic 1 1
+ 9600 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 7 - PCI slot 2 */
+ 9700 0 0 1 &mpic 3 1
+ 9700 0 0 2 &mpic 4 1
+ 9700 0 0 3 &mpic 1 1
+ 9700 0 0 4 &mpic 2 1
// IDSEL 0x1c USB
- e000 0 0 0 &i8259 c 2
- e100 0 0 0 &i8259 9 2
- e200 0 0 0 &i8259 a 2
- e300 0 0 0 &i8259 b 2
+ e000 0 0 1 &i8259 c 2
+ e100 0 0 1 &i8259 9 2
+ e200 0 0 1 &i8259 a 2
+ e300 0 0 1 &i8259 b 2
// IDSEL 0x1d Audio
- e800 0 0 0 &i8259 6 2
+ e800 0 0 1 &i8259 6 2
// IDSEL 0x1e Legacy
- f000 0 0 0 &i8259 7 2
- f100 0 0 0 &i8259 7 2
+ f000 0 0 1 &i8259 7 2
+ f100 0 0 1 &i8259 7 2
// IDSEL 0x1f IDE/SATA
- f800 0 0 0 &i8259 e 2
- f900 0 0 0 &i8259 5 2
+ f800 0 0 1 &i8259 e 2
+ f900 0 0 1 &i8259 5 2
>;
pcie@0 {
diff --git a/arch/powerpc/configs/mpc832x_mds_defconfig b/arch/powerpc/configs/mpc832x_mds_defconfig
index dd68d1818d6..e069018276c 100644
--- a/arch/powerpc/configs/mpc832x_mds_defconfig
+++ b/arch/powerpc/configs/mpc832x_mds_defconfig
@@ -774,7 +774,53 @@ CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_NEW_LEDS is not set
# CONFIG_INFINIBAND is not set
# CONFIG_EDAC is not set
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+CONFIG_RTC_DRV_DS1374=y
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
#
# DMA Engine support
diff --git a/arch/powerpc/configs/mpc832x_rdb_defconfig b/arch/powerpc/configs/mpc832x_rdb_defconfig
index 4f391028c79..7a5b13f4140 100644
--- a/arch/powerpc/configs/mpc832x_rdb_defconfig
+++ b/arch/powerpc/configs/mpc832x_rdb_defconfig
@@ -685,8 +685,21 @@ CONFIG_I2C_MPC=y
#
# SPI support
#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_MPC83xx=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
@@ -710,6 +723,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
# CONFIG_SENSORS_LM75 is not set
# CONFIG_SENSORS_LM77 is not set
# CONFIG_SENSORS_LM78 is not set
@@ -896,7 +910,24 @@ CONFIG_USB_MON=y
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
-# CONFIG_MMC is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_WBSD is not set
+# CONFIG_MMC_TIFM_SD is not set
+CONFIG_MMC_SPI=y
# CONFIG_NEW_LEDS is not set
# CONFIG_INFINIBAND is not set
# CONFIG_EDAC is not set
@@ -1101,9 +1132,9 @@ CONFIG_UCC=y
CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
-# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC_ITU_T=y
CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
+CONFIG_CRC7=y
# CONFIG_LIBCRC32C is not set
CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
diff --git a/arch/powerpc/configs/mpc834x_itx_defconfig b/arch/powerpc/configs/mpc834x_itx_defconfig
index eb28dd85cb2..ba512d13f3a 100644
--- a/arch/powerpc/configs/mpc834x_itx_defconfig
+++ b/arch/powerpc/configs/mpc834x_itx_defconfig
@@ -867,7 +867,7 @@ CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_FSL=y
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_OHCI_HCD is not set
-# CONFIG_USB_UHCI_HCD is not set
+CONFIG_USB_UHCI_HCD=y
# CONFIG_USB_SL811_HCD is not set
# CONFIG_USB_R8A66597_HCD is not set
diff --git a/arch/powerpc/configs/mpc834x_itxgp_defconfig b/arch/powerpc/configs/mpc834x_itxgp_defconfig
index 22b95462c91..9faa948c22a 100644
--- a/arch/powerpc/configs/mpc834x_itxgp_defconfig
+++ b/arch/powerpc/configs/mpc834x_itxgp_defconfig
@@ -760,15 +760,101 @@ CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB_ARCH_HAS_EHCI=y
-# CONFIG_USB is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
CONFIG_USB_EHCI_FSL=y
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+CONFIG_USB_UHCI_HCD=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
#
#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+
+#
+# USB DSL modem support
+#
+
+#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
diff --git a/arch/powerpc/configs/mpc834x_mds_defconfig b/arch/powerpc/configs/mpc834x_mds_defconfig
index e59a88e9548..356f736a5d3 100644
--- a/arch/powerpc/configs/mpc834x_mds_defconfig
+++ b/arch/powerpc/configs/mpc834x_mds_defconfig
@@ -721,7 +721,53 @@ CONFIG_USB_EHCI_FSL=y
# CONFIG_NEW_LEDS is not set
# CONFIG_INFINIBAND is not set
# CONFIG_EDAC is not set
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+CONFIG_RTC_DRV_DS1374=y
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
#
# DMA Engine support
diff --git a/arch/powerpc/configs/mpc836x_mds_defconfig b/arch/powerpc/configs/mpc836x_mds_defconfig
index 75657528518..1b4d37570eb 100644
--- a/arch/powerpc/configs/mpc836x_mds_defconfig
+++ b/arch/powerpc/configs/mpc836x_mds_defconfig
@@ -773,7 +773,53 @@ CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_NEW_LEDS is not set
# CONFIG_INFINIBAND is not set
# CONFIG_EDAC is not set
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+CONFIG_RTC_DRV_DS1374=y
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
#
# DMA Engine support
diff --git a/arch/powerpc/configs/mpc8568mds_defconfig b/arch/powerpc/configs/mpc8568mds_defconfig
index 883d8af9deb..d665e7a797c 100644
--- a/arch/powerpc/configs/mpc8568mds_defconfig
+++ b/arch/powerpc/configs/mpc8568mds_defconfig
@@ -768,7 +768,53 @@ CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_NEW_LEDS is not set
# CONFIG_INFINIBAND is not set
# CONFIG_EDAC is not set
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+CONFIG_RTC_DRV_DS1374=y
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
#
# DMA Engine support
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 2c8e756d19a..d67bcd84f32 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -284,6 +284,10 @@ int main(void)
DEFINE(CFG_SYSCALL_MAP32, offsetof(struct vdso_data, syscall_map_32));
DEFINE(WTOM_CLOCK_SEC, offsetof(struct vdso_data, wtom_clock_sec));
DEFINE(WTOM_CLOCK_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
+ DEFINE(CFG_ICACHE_BLOCKSZ, offsetof(struct vdso_data, icache_block_size));
+ DEFINE(CFG_DCACHE_BLOCKSZ, offsetof(struct vdso_data, dcache_block_size));
+ DEFINE(CFG_ICACHE_LOGBLOCKSZ, offsetof(struct vdso_data, icache_log_block_size));
+ DEFINE(CFG_DCACHE_LOGBLOCKSZ, offsetof(struct vdso_data, dcache_log_block_size));
#ifdef CONFIG_PPC64
DEFINE(CFG_SYSCALL_MAP64, offsetof(struct vdso_data, syscall_map_64));
DEFINE(TVAL64_TV_SEC, offsetof(struct timeval, tv_sec));
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 21478079828..053cac19f71 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -19,6 +19,9 @@
#include <linux/init.h>
#include <linux/capability.h>
#include <linux/delay.h>
+#include <linux/smp.h>
+#include <linux/completion.h>
+#include <linux/cpumask.h>
#include <asm/prom.h>
#include <asm/rtas.h>
@@ -34,6 +37,8 @@
#include <asm/lmb.h>
#include <asm/udbg.h>
#include <asm/syscalls.h>
+#include <asm/smp.h>
+#include <asm/atomic.h>
struct rtas_t rtas = {
.lock = SPIN_LOCK_UNLOCKED
@@ -41,8 +46,10 @@ struct rtas_t rtas = {
EXPORT_SYMBOL(rtas);
struct rtas_suspend_me_data {
- long waiting;
- struct rtas_args *args;
+ atomic_t working; /* number of cpus accessing this struct */
+ int token; /* ibm,suspend-me */
+ int error;
+ struct completion *complete; /* wait on this until working == 0 */
};
DEFINE_SPINLOCK(rtas_data_buf_lock);
@@ -631,18 +638,18 @@ void rtas_halt(void)
/* Must be in the RMO region, so we place it here */
static char rtas_os_term_buf[2048];
-void rtas_os_term(char *str)
+void rtas_panic_msg(char *str)
{
- int status;
+ snprintf(rtas_os_term_buf, 2048, "OS panic: %s", str);
+}
- if (panic_timeout)
- return;
+void rtas_os_term(void)
+{
+ int status;
if (RTAS_UNKNOWN_SERVICE == rtas_token("ibm,os-term"))
return;
- snprintf(rtas_os_term_buf, 2048, "OS panic: %s", str);
-
do {
status = rtas_call(rtas_token("ibm,os-term"), 1, 1, NULL,
__pa(rtas_os_term_buf));
@@ -657,50 +664,62 @@ static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE;
#ifdef CONFIG_PPC_PSERIES
static void rtas_percpu_suspend_me(void *info)
{
- int i;
long rc;
- long flags;
+ unsigned long msr_save;
+ int cpu;
struct rtas_suspend_me_data *data =
(struct rtas_suspend_me_data *)info;
- /*
- * We use "waiting" to indicate our state. As long
- * as it is >0, we are still trying to all join up.
- * If it goes to 0, we have successfully joined up and
- * one thread got H_CONTINUE. If any error happens,
- * we set it to <0.
- */
- local_irq_save(flags);
- do {
- rc = plpar_hcall_norets(H_JOIN);
- smp_rmb();
- } while (rc == H_SUCCESS && data->waiting > 0);
- if (rc == H_SUCCESS)
- goto out;
+ atomic_inc(&data->working);
+
+ /* really need to ensure MSR.EE is off for H_JOIN */
+ msr_save = mfmsr();
+ mtmsr(msr_save & ~(MSR_EE));
+
+ rc = plpar_hcall_norets(H_JOIN);
- if (rc == H_CONTINUE) {
- data->waiting = 0;
- data->args->args[data->args->nargs] =
- rtas_call(ibm_suspend_me_token, 0, 1, NULL);
- for_each_possible_cpu(i)
- plpar_hcall_norets(H_PROD,i);
+ mtmsr(msr_save);
+
+ if (rc == H_SUCCESS) {
+ /* This cpu was prodded and the suspend is complete. */
+ goto out;
+ } else if (rc == H_CONTINUE) {
+ /* All other cpus are in H_JOIN, this cpu does
+ * the suspend.
+ */
+ printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n",
+ smp_processor_id());
+ data->error = rtas_call(data->token, 0, 1, NULL);
+
+ if (data->error)
+ printk(KERN_DEBUG "ibm,suspend-me returned %d\n",
+ data->error);
} else {
- data->waiting = -EBUSY;
- printk(KERN_ERR "Error on H_JOIN hypervisor call\n");
+ printk(KERN_ERR "H_JOIN on cpu %i failed with rc = %ld\n",
+ smp_processor_id(), rc);
+ data->error = rc;
}
-
+ /* This cpu did the suspend or got an error; in either case,
+ * we need to prod all other other cpus out of join state.
+ * Extra prods are harmless.
+ */
+ for_each_online_cpu(cpu)
+ plpar_hcall_norets(H_PROD, get_hard_smp_processor_id(cpu));
out:
- local_irq_restore(flags);
- return;
+ if (atomic_dec_return(&data->working) == 0)
+ complete(data->complete);
}
static int rtas_ibm_suspend_me(struct rtas_args *args)
{
- int i;
long state;
long rc;
unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
struct rtas_suspend_me_data data;
+ DECLARE_COMPLETION_ONSTACK(done);
+
+ if (!rtas_service_present("ibm,suspend-me"))
+ return -ENOSYS;
/* Make sure the state is valid */
rc = plpar_hcall(H_VASI_STATE, retbuf,
@@ -721,25 +740,23 @@ static int rtas_ibm_suspend_me(struct rtas_args *args)
return 0;
}
- data.waiting = 1;
- data.args = args;
+ atomic_set(&data.working, 0);
+ data.token = rtas_token("ibm,suspend-me");
+ data.error = 0;
+ data.complete = &done;
/* Call function on all CPUs. One of us will make the
* rtas call
*/
if (on_each_cpu(rtas_percpu_suspend_me, &data, 1, 0))
- data.waiting = -EINVAL;
+ data.error = -EINVAL;
- if (data.waiting != 0)
- printk(KERN_ERR "Error doing global join\n");
+ wait_for_completion(&done);
- /* Prod each CPU. This won't hurt, and will wake
- * anyone we successfully put to sleep with H_JOIN.
- */
- for_each_possible_cpu(i)
- plpar_hcall_norets(H_PROD, i);
+ if (data.error != 0)
+ printk(KERN_ERR "Error doing global join\n");
- return data.waiting;
+ return data.error;
}
#else /* CONFIG_PPC_PSERIES */
static int rtas_ibm_suspend_me(struct rtas_args *args)
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index c0d77723ba1..a925a8eae12 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -241,8 +241,9 @@ void account_system_vtime(struct task_struct *tsk)
/* deltascaled includes both user and system time.
* Hence scale it based on the purr ratio to estimate
* the system time */
- deltascaled = deltascaled * get_paca()->system_time /
- (get_paca()->system_time + get_paca()->user_time);
+ if (get_paca()->user_time)
+ deltascaled = deltascaled * get_paca()->system_time /
+ (get_paca()->system_time + get_paca()->user_time);
delta += get_paca()->system_time;
get_paca()->system_time = 0;
}
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index 2322ba5cce4..3702df7dc56 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -699,11 +699,22 @@ static int __init vdso_init(void)
vdso_data->icache_size = ppc64_caches.isize;
vdso_data->icache_line_size = ppc64_caches.iline_size;
+ /* XXXOJN: Blocks should be added to ppc64_caches and used instead */
+ vdso_data->dcache_block_size = ppc64_caches.dline_size;
+ vdso_data->icache_block_size = ppc64_caches.iline_size;
+ vdso_data->dcache_log_block_size = ppc64_caches.log_dline_size;
+ vdso_data->icache_log_block_size = ppc64_caches.log_iline_size;
+
/*
* Calculate the size of the 64 bits vDSO
*/
vdso64_pages = (&vdso64_end - &vdso64_start) >> PAGE_SHIFT;
DBG("vdso64_kbase: %p, 0x%x pages\n", vdso64_kbase, vdso64_pages);
+#else
+ vdso_data->dcache_block_size = L1_CACHE_BYTES;
+ vdso_data->dcache_log_block_size = L1_CACHE_SHIFT;
+ vdso_data->icache_block_size = L1_CACHE_BYTES;
+ vdso_data->icache_log_block_size = L1_CACHE_SHIFT;
#endif /* CONFIG_PPC64 */
diff --git a/arch/powerpc/kernel/vdso32/cacheflush.S b/arch/powerpc/kernel/vdso32/cacheflush.S
index 9cb319992c3..1ba6feb71b3 100644
--- a/arch/powerpc/kernel/vdso32/cacheflush.S
+++ b/arch/powerpc/kernel/vdso32/cacheflush.S
@@ -23,29 +23,46 @@
*
* Flushes the data cache & invalidate the instruction cache for the
* provided range [start, end[
- *
- * Note: all CPUs supported by this kernel have a 128 bytes cache
- * line size so we don't have to peek that info from the datapage
*/
V_FUNCTION_BEGIN(__kernel_sync_dicache)
.cfi_startproc
- li r5,127
- andc r6,r3,r5 /* round low to line bdy */
+ mflr r12
+ .cfi_register lr,r12
+ mr r11,r3
+ bl __get_datapage@local
+ mtlr r12
+ mr r10,r3
+
+ lwz r7,CFG_DCACHE_BLOCKSZ(r10)
+ addi r5,r7,-1
+ andc r6,r11,r5 /* round low to line bdy */
subf r8,r6,r4 /* compute length */
add r8,r8,r5 /* ensure we get enough */
- srwi. r8,r8,7 /* compute line count */
+ lwz r9,CFG_DCACHE_LOGBLOCKSZ(r10)
+ srw. r8,r8,r9 /* compute line count */
crclr cr0*4+so
beqlr /* nothing to do? */
mtctr r8
- mr r3,r6
-1: dcbst 0,r3
- addi r3,r3,128
+1: dcbst 0,r6
+ add r6,r6,r7
bdnz 1b
sync
+
+/* Now invalidate the instruction cache */
+
+ lwz r7,CFG_ICACHE_BLOCKSZ(r10)
+ addi r5,r7,-1
+ andc r6,r11,r5 /* round low to line bdy */
+ subf r8,r6,r4 /* compute length */
+ add r8,r8,r5
+ lwz r9,CFG_ICACHE_LOGBLOCKSZ(r10)
+ srw. r8,r8,r9 /* compute line count */
+ crclr cr0*4+so
+ beqlr /* nothing to do? */
mtctr r8
-1: icbi 0,r6
- addi r6,r6,128
- bdnz 1b
+2: icbi 0,r6
+ add r6,r6,r7
+ bdnz 2b
isync
li r3,0
blr
diff --git a/arch/powerpc/kernel/vdso64/cacheflush.S b/arch/powerpc/kernel/vdso64/cacheflush.S
index 66a36d3cc6a..69c5af2b3c9 100644
--- a/arch/powerpc/kernel/vdso64/cacheflush.S
+++ b/arch/powerpc/kernel/vdso64/cacheflush.S
@@ -23,29 +23,46 @@
*
* Flushes the data cache & invalidate the instruction cache for the
* provided range [start, end[
- *
- * Note: all CPUs supported by this kernel have a 128 bytes cache
- * line size so we don't have to peek that info from the datapage
*/
V_FUNCTION_BEGIN(__kernel_sync_dicache)
.cfi_startproc
- li r5,127
- andc r6,r3,r5 /* round low to line bdy */
+ mflr r12
+ .cfi_register lr,r12
+ mr r11,r3
+ bl V_LOCAL_FUNC(__get_datapage)
+ mtlr r12
+ mr r10,r3
+
+ lwz r7,CFG_DCACHE_BLOCKSZ(r10)
+ addi r5,r7,-1
+ andc r6,r11,r5 /* round low to line bdy */
subf r8,r6,r4 /* compute length */
add r8,r8,r5 /* ensure we get enough */
- srwi. r8,r8,7 /* compute line count */
+ lwz r9,CFG_DCACHE_LOGBLOCKSZ(r10)
+ srw. r8,r8,r9 /* compute line count */
crclr cr0*4+so
beqlr /* nothing to do? */
mtctr r8
- mr r3,r6
-1: dcbst 0,r3
- addi r3,r3,128
+1: dcbst 0,r6
+ add r6,r6,r7
bdnz 1b
sync
+
+/* Now invalidate the instruction cache */
+
+ lwz r7,CFG_ICACHE_BLOCKSZ(r10)
+ addi r5,r7,-1
+ andc r6,r11,r5 /* round low to line bdy */
+ subf r8,r6,r4 /* compute length */
+ add r8,r8,r5
+ lwz r9,CFG_ICACHE_LOGBLOCKSZ(r10)
+ srw. r8,r8,r9 /* compute line count */
+ crclr cr0*4+so
+ beqlr /* nothing to do? */
mtctr r8
-1: icbi 0,r6
- addi r6,r6,128
- bdnz 1b
+2: icbi 0,r6
+ add r6,r6,r7
+ bdnz 2b
isync
li r3,0
blr
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 81eb96ec13b..5402fb6b3aa 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -464,7 +464,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
* we invalidate the TLB here, thus avoiding dcbst
* misbehaviour.
*/
- _tlbie(address);
+ _tlbie(address, 0 /* 8xx doesn't care about PID */);
#endif
if (!PageReserved(page)
&& !test_bit(PG_arch_1, &page->flags)) {
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index eb3a732e91d..ebfd13dc9d1 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -56,7 +56,7 @@ extern unsigned long total_lowmem;
* architectures. -- Dan
*/
#if defined(CONFIG_8xx)
-#define flush_HPTE(X, va, pg) _tlbie(va)
+#define flush_HPTE(X, va, pg) _tlbie(va, 0 /* 8xx doesn't care about PID */)
#define MMU_init_hw() do { } while(0)
#define mmu_mapin_ram() (0UL)
diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c
index 9e85bda7621..50448d5de9d 100644
--- a/arch/powerpc/mm/stab.c
+++ b/arch/powerpc/mm/stab.c
@@ -20,6 +20,7 @@
#include <asm/lmb.h>
#include <asm/abs_addr.h>
#include <asm/firmware.h>
+#include <asm/iseries/hv_call.h>
struct stab_entry {
unsigned long esid_data;
diff --git a/arch/powerpc/platforms/40x/walnut.c b/arch/powerpc/platforms/40x/walnut.c
index eb0c136b1c4..ff6db243179 100644
--- a/arch/powerpc/platforms/40x/walnut.c
+++ b/arch/powerpc/platforms/40x/walnut.c
@@ -17,12 +17,13 @@
*/
#include <linux/init.h>
+#include <linux/of_platform.h>
+
#include <asm/machdep.h>
#include <asm/prom.h>
#include <asm/udbg.h>
#include <asm/time.h>
#include <asm/uic.h>
-#include <asm/of_platform.h>
static struct of_device_id walnut_of_bus[] = {
{ .compatible = "ibm,plb3", },
diff --git a/arch/powerpc/platforms/44x/bamboo.c b/arch/powerpc/platforms/44x/bamboo.c
index 470e1a3fd75..be23f112184 100644
--- a/arch/powerpc/platforms/44x/bamboo.c
+++ b/arch/powerpc/platforms/44x/bamboo.c
@@ -14,12 +14,13 @@
* option) any later version.
*/
#include <linux/init.h>
+#include <linux/of_platform.h>
+
#include <asm/machdep.h>
#include <asm/prom.h>
#include <asm/udbg.h>
#include <asm/time.h>
#include <asm/uic.h>
-#include <asm/of_platform.h>
#include "44x.h"
static struct of_device_id bamboo_of_bus[] = {
diff --git a/arch/powerpc/platforms/44x/ebony.c b/arch/powerpc/platforms/44x/ebony.c
index 40e18fcb666..6cd3476767c 100644
--- a/arch/powerpc/platforms/44x/ebony.c
+++ b/arch/powerpc/platforms/44x/ebony.c
@@ -17,12 +17,13 @@
*/
#include <linux/init.h>
+#include <linux/of_platform.h>
+
#include <asm/machdep.h>
#include <asm/prom.h>
#include <asm/udbg.h>
#include <asm/time.h>
#include <asm/uic.h>
-#include <asm/of_platform.h>
#include "44x.h"
diff --git a/arch/powerpc/platforms/44x/sequoia.c b/arch/powerpc/platforms/44x/sequoia.c
index 30700b31d43..21a9dd14f29 100644
--- a/arch/powerpc/platforms/44x/sequoia.c
+++ b/arch/powerpc/platforms/44x/sequoia.c
@@ -14,12 +14,13 @@
* option) any later version.
*/
#include <linux/init.h>
+#include <linux/of_platform.h>
+
#include <asm/machdep.h>
#include <asm/prom.h>
#include <asm/udbg.h>
#include <asm/time.h>
#include <asm/uic.h>
-#include <asm/of_platform.h>
#include "44x.h"
static struct of_device_id sequoia_of_bus[] = {
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
index 972fa8528a8..39ee7a13b25 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -90,10 +90,11 @@ static void __init mpc832x_sys_setup_arch(void)
if ((np = of_find_compatible_node(NULL, "network", "ucc_geth"))
!= NULL){
- /* Reset the Ethernet PHY */
- bcsr_regs[9] &= ~0x20;
+ /* Reset the Ethernet PHYs */
+#define BCSR8_FETH_RST 0x50
+ bcsr_regs[8] &= ~BCSR8_FETH_RST;
udelay(1000);
- bcsr_regs[9] |= 0x20;
+ bcsr_regs[8] |= BCSR8_FETH_RST;
iounmap(bcsr_regs);
of_node_put(np);
}
@@ -145,30 +146,6 @@ static void __init mpc832x_sys_init_IRQ(void)
#endif /* CONFIG_QUICC_ENGINE */
}
-#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
-extern ulong ds1374_get_rtc_time(void);
-extern int ds1374_set_rtc_time(ulong);
-
-static int __init mpc832x_rtc_hookup(void)
-{
- struct timespec tv;
-
- if (!machine_is(mpc832x_mds))
- return 0;
-
- ppc_md.get_rtc_time = ds1374_get_rtc_time;
- ppc_md.set_rtc_time = ds1374_set_rtc_time;
-
- tv.tv_nsec = 0;
- tv.tv_sec = (ppc_md.get_rtc_time) ();
- do_settimeofday(&tv);
-
- return 0;
-}
-
-late_initcall(mpc832x_rtc_hookup);
-#endif
-
/*
* Called very early, MMU is off, device-tree isn't unflattened
*/
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index fbca336aa0a..d4bd04001b9 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -15,7 +15,10 @@
*/
#include <linux/pci.h>
+#include <linux/interrupt.h>
#include <linux/spi/spi.h>
+#include <linux/spi/mmc_spi.h>
+#include <linux/mmc/host.h>
#include <asm/of_platform.h>
#include <asm/time.h>
@@ -46,15 +49,16 @@ static void mpc83xx_spi_deactivate_cs(u8 cs, u8 polarity)
par_io_data_set(3, 13, !polarity);
}
+static struct mmc_spi_platform_data mpc832x_mmc_pdata = {
+ .ocr_mask = MMC_VDD_33_34,
+};
+
static struct spi_board_info mpc832x_spi_boardinfo = {
.bus_num = 0x4c0,
.chip_select = 0,
.max_speed_hz = 50000000,
- /*
- * XXX: This is spidev (spi in userspace) stub, should
- * be replaced by "mmc_spi" when mmc_spi will hit mainline.
- */
- .modalias = "spidev",
+ .modalias = "mmc_spi",
+ .platform_data = &mpc832x_mmc_pdata,
};
static int __init mpc832x_spi_init(void)
diff --git a/arch/powerpc/platforms/83xx/mpc834x_mds.c b/arch/powerpc/platforms/83xx/mpc834x_mds.c
index 00aed7c2269..a81bb3ce6b9 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c
@@ -106,30 +106,6 @@ static void __init mpc834x_mds_init_IRQ(void)
ipic_set_default_priority();
}
-#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
-extern ulong ds1374_get_rtc_time(void);
-extern int ds1374_set_rtc_time(ulong);
-
-static int __init mpc834x_rtc_hookup(void)
-{
- struct timespec tv;
-
- if (!machine_is(mpc834x_mds))
- return 0;
-
- ppc_md.get_rtc_time = ds1374_get_rtc_time;
- ppc_md.set_rtc_time = ds1374_set_rtc_time;
-
- tv.tv_nsec = 0;
- tv.tv_sec = (ppc_md.get_rtc_time) ();
- do_settimeofday(&tv);
-
- return 0;
-}
-
-late_initcall(mpc834x_rtc_hookup);
-#endif
-
/*
* Called very early, MMU is off, device-tree isn't unflattened
*/
diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c
index 0f3855c95ff..e40012f8f48 100644
--- a/arch/powerpc/platforms/83xx/mpc836x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c
@@ -96,14 +96,39 @@ static void __init mpc836x_mds_setup_arch(void)
if ((np = of_find_compatible_node(NULL, "network", "ucc_geth"))
!= NULL){
+ uint svid;
+
/* Reset the Ethernet PHY */
- bcsr_regs[9] &= ~0x20;
+#define BCSR9_GETHRST 0x20
+ clrbits8(&bcsr_regs[9], BCSR9_GETHRST);
udelay(1000);
- bcsr_regs[9] |= 0x20;
+ setbits8(&bcsr_regs[9], BCSR9_GETHRST);
+
+ /* handle mpc8360ea rev.2.1 erratum 2: RGMII Timing */
+ svid = mfspr(SPRN_SVR);
+ if (svid == 0x80480021) {
+ void __iomem *immap;
+
+ immap = ioremap(get_immrbase() + 0x14a8, 8);
+
+ /*
+ * IMMR + 0x14A8[4:5] = 11 (clk delay for UCC 2)
+ * IMMR + 0x14A8[18:19] = 11 (clk delay for UCC 1)
+ */
+ setbits32(immap, 0x0c003000);
+
+ /*
+ * IMMR + 0x14AC[20:27] = 10101010
+ * (data delay for both UCC's)
+ */
+ clrsetbits_be32(immap + 4, 0xff0, 0xaa0);
+
+ iounmap(immap);
+ }
+
iounmap(bcsr_regs);
of_node_put(np);
}
-
#endif /* CONFIG_QUICC_ENGINE */
}
@@ -152,30 +177,6 @@ static void __init mpc836x_mds_init_IRQ(void)
#endif /* CONFIG_QUICC_ENGINE */
}
-#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
-extern ulong ds1374_get_rtc_time(void);
-extern int ds1374_set_rtc_time(ulong);
-
-static int __init mpc8360_rtc_hookup(void)
-{
- struct timespec tv;
-
- if (!machine_is(mpc836x_mds))
- return 0;
-
- ppc_md.get_rtc_time = ds1374_get_rtc_time;
- ppc_md.set_rtc_time = ds1374_set_rtc_time;
-
- tv.tv_nsec = 0;
- tv.tv_sec = (ppc_md.get_rtc_time) ();
- do_settimeofday(&tv);
-
- return 0;
-}
-
-late_initcall(mpc8360_rtc_hookup);
-#endif
-
/*
* Called very early, MMU is off, device-tree isn't unflattened
*/
diff --git a/arch/powerpc/platforms/83xx/usb.c b/arch/powerpc/platforms/83xx/usb.c
index eafe7605cda..b45160f8d08 100644
--- a/arch/powerpc/platforms/83xx/usb.c
+++ b/arch/powerpc/platforms/83xx/usb.c
@@ -130,7 +130,7 @@ int mpc831x_usb_cfg(void)
out_be32(immap + MPC83XX_SCCR_OFFS, temp);
/* Configure pin mux for ULPI. There is no pin mux for UTMI */
- if (!strcmp(prop, "ulpi")) {
+ if (prop && !strcmp(prop, "ulpi")) {
temp = in_be32(immap + MPC83XX_SICRL_OFFS);
temp &= ~MPC831X_SICRL_USB_MASK;
temp |= MPC831X_SICRL_USB_ULPI;
@@ -153,13 +153,13 @@ int mpc831x_usb_cfg(void)
usb_regs = ioremap(res.start, res.end - res.start + 1);
/* Using on-chip PHY */
- if (!strcmp(prop, "utmi_wide") ||
- !strcmp(prop, "utmi")) {
+ if (prop && (!strcmp(prop, "utmi_wide") ||
+ !strcmp(prop, "utmi"))) {
/* Set UTMI_PHY_EN, REFSEL to 48MHZ */
out_be32(usb_regs + FSL_USB2_CONTROL_OFFS,
CONTROL_UTMI_PHY_EN | CONTROL_REFSEL_48MHZ);
/* Using external UPLI PHY */
- } else if (!strcmp(prop, "ulpi")) {
+ } else if (prop && !strcmp(prop, "ulpi")) {
/* Set PHY_CLK_SEL to ULPI */
temp = CONTROL_PHY_CLK_SEL_ULPI;
#ifdef CONFIG_USB_OTG
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 0966d093db4..c0e968a4c21 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -171,6 +171,7 @@ static int spufs_rmdir(struct inode *parent, struct dentry *dir)
{
/* remove all entries */
spufs_prune_dir(dir);
+ d_drop(dir);
return simple_rmdir(parent, dir);
}
diff --git a/arch/powerpc/platforms/embedded6xx/prpmc2800.c b/arch/powerpc/platforms/embedded6xx/prpmc2800.c
index e484cac7509..653a5eb91c9 100644
--- a/arch/powerpc/platforms/embedded6xx/prpmc2800.c
+++ b/arch/powerpc/platforms/embedded6xx/prpmc2800.c
@@ -144,6 +144,7 @@ static int __init prpmc2800_probe(void)
strncpy(prpmc2800_platform_name, m,
min((int)len, PLATFORM_NAME_MAX - 1));
+ _set_L2CR(_get_L2CR() | L2CR_L2E);
return 1;
}
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index 3a5d112af5e..3d62060498b 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -214,7 +214,7 @@ static __init void pas_init_IRQ(void)
printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr);
mpic = mpic_alloc(mpic_node, openpic_addr,
- MPIC_PRIMARY|MPIC_LARGE_VECTORS|MPIC_WANTS_RESET,
+ MPIC_PRIMARY|MPIC_LARGE_VECTORS,
0, 0, " PAS-OPIC ");
BUG_ON(!mpic);
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index 16e4e401b82..306a9d07491 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -21,7 +21,7 @@ config PPC_SPLPAR
config EEH
bool "PCI Extended Error Handling (EEH)" if EMBEDDED
- depends on PPC_PSERIES
+ depends on PPC_PSERIES && PCI
default y if !EMBEDDED
config SCANLOG
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index fdb9b1c8f97..fdeefe54ea9 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -507,7 +507,8 @@ define_machine(pseries) {
.restart = rtas_restart,
.power_off = pSeries_power_off,
.halt = rtas_halt,
- .panic = rtas_os_term,
+ .panic = rtas_panic_msg,
+ .machine_shutdown = rtas_os_term,
.get_boot_time = rtas_get_boot_time,
.get_rtc_time = rtas_get_rtc_time,
.set_rtc_time = rtas_set_rtc_time,
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
index 5149716c734..847a5496b86 100644
--- a/arch/powerpc/sysdev/uic.c
+++ b/arch/powerpc/sysdev/uic.c
@@ -97,6 +97,22 @@ static void uic_ack_irq(unsigned int virq)
spin_unlock_irqrestore(&uic->lock, flags);
}
+static void uic_mask_ack_irq(unsigned int virq)
+{
+ struct uic *uic = get_irq_chip_data(virq);
+ unsigned int src = uic_irq_to_hw(virq);
+ unsigned long flags;
+ u32 er, sr;
+
+ sr = 1 << (31-src);
+ spin_lock_irqsave(&uic->lock, flags);
+ er = mfdcr(uic->dcrbase + UIC_ER);
+ er &= ~sr;
+ mtdcr(uic->dcrbase + UIC_ER, er);
+ mtdcr(uic->dcrbase + UIC_SR, sr);
+ spin_unlock_irqrestore(&uic->lock, flags);
+}
+
static int uic_set_irq_type(unsigned int virq, unsigned int flow_type)
{
struct uic *uic = get_irq_chip_data(virq);
@@ -152,7 +168,7 @@ static struct irq_chip uic_irq_chip = {
.typename = " UIC ",
.unmask = uic_unmask_irq,
.mask = uic_mask_irq,
-/* .mask_ack = uic_mask_irq_and_ack, */
+ .mask_ack = uic_mask_ack_irq,
.ack = uic_ack_irq,
.set_type = uic_set_irq_type,
};
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index aac88c2f3db..5255bd80aa6 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -312,7 +312,14 @@ early_init(int r3, int r4, int r5)
* Identify the CPU type and fix up code sections
* that depend on which cpu we have.
*/
+#if defined(CONFIG_440EP) && defined(CONFIG_PPC_FPU)
+ /* We pass the virtual PVR here for 440EP as 440EP and 440GR have
+ * identical PVRs and there is no reliable way to check for the FPU
+ */
+ spec = identify_cpu(offset, (mfspr(SPRN_PVR) | 0x8));
+#else
spec = identify_cpu(offset, mfspr(SPRN_PVR));
+#endif
do_feature_fixups(spec->cpu_features,
PTRRELOC(&__start___ftr_fixup),
PTRRELOC(&__stop___ftr_fixup));
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index 390dd1995c2..dd898d32480 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -561,7 +561,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
* That means the zeroed TLB has to be invalidated
* whenever a page miss occurs.
*/
- _tlbie(address);
+ _tlbie(address, 0 /* 8xx doesn't care about PID */);
#endif
if (!PageReserved(page)
&& !test_bit(PG_arch_1, &page->flags)) {
diff --git a/arch/ppc/mm/mmu_decl.h b/arch/ppc/mm/mmu_decl.h
index f1d4f2109a9..b298b60c202 100644
--- a/arch/ppc/mm/mmu_decl.h
+++ b/arch/ppc/mm/mmu_decl.h
@@ -49,7 +49,7 @@ extern unsigned int num_tlbcam_entries;
* architectures. -- Dan
*/
#if defined(CONFIG_8xx)
-#define flush_HPTE(X, va, pg) _tlbie(va)
+#define flush_HPTE(X, va, pg) _tlbie(va, 0 /* 8xx doesn't care about PID */)
#define MMU_init_hw() do { } while(0)
#define mmu_mapin_ram() (0UL)
diff --git a/arch/ppc/platforms/4xx/yucca.c b/arch/ppc/platforms/4xx/yucca.c
index a83b0baea01..66a44ff0d92 100644
--- a/arch/ppc/platforms/4xx/yucca.c
+++ b/arch/ppc/platforms/4xx/yucca.c
@@ -211,6 +211,7 @@ static void __init yucca_setup_pcie_fpga_rootpoint(int port)
break;
default:
+ iounmap(pcie_reg_fpga_base);
return;
}
diff --git a/arch/ppc/syslib/virtex_devices.c b/arch/ppc/syslib/virtex_devices.c
index ace4ec08de5..f658ff3b389 100644
--- a/arch/ppc/syslib/virtex_devices.c
+++ b/arch/ppc/syslib/virtex_devices.c
@@ -87,6 +87,29 @@
}, \
}
+#define XPAR_AC97_CONTROLLER_REFERENCE(num) { \
+ .name = "ml403_ac97cr", \
+ .id = num, \
+ .num_resources = 3, \
+ .resource = (struct resource[]) { \
+ { \
+ .start = XPAR_OPB_AC97_CONTROLLER_REF_##num##_BASEADDR, \
+ .end = XPAR_OPB_AC97_CONTROLLER_REF_##num##_HIGHADDR, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ { \
+ .start = XPAR_OPB_INTC_0_OPB_AC97_CONTROLLER_REF_##num##_PLAYBACK_INTERRUPT_INTR, \
+ .end = XPAR_OPB_INTC_0_OPB_AC97_CONTROLLER_REF_##num##_PLAYBACK_INTERRUPT_INTR, \
+ .flags = IORESOURCE_IRQ, \
+ }, \
+ { \
+ .start = XPAR_OPB_INTC_0_OPB_AC97_CONTROLLER_REF_##num##_RECORD_INTERRUPT_INTR, \
+ .end = XPAR_OPB_INTC_0_OPB_AC97_CONTROLLER_REF_##num##_RECORD_INTERRUPT_INTR, \
+ .flags = IORESOURCE_IRQ, \
+ }, \
+ }, \
+}
+
/* UART 8250 driver platform data table */
struct plat_serial8250_port virtex_serial_platform_data[] = {
#if defined(XPAR_UARTNS550_0_BASEADDR)
@@ -173,6 +196,14 @@ struct platform_device virtex_platform_devices[] = {
#if defined(XPAR_TFT_3_BASEADDR)
XPAR_TFT(3),
#endif
+
+ /* AC97 Controller Reference instances */
+#if defined(XPAR_OPB_AC97_CONTROLLER_REF_0_BASEADDR)
+ XPAR_AC97_CONTROLLER_REFERENCE(0),
+#endif
+#if defined(XPAR_OPB_AC97_CONTROLLER_REF_1_BASEADDR)
+ XPAR_AC97_CONTROLLER_REFERENCE(1),
+#endif
};
/* Early serial support functions */
diff --git a/arch/s390/appldata/appldata.h b/arch/s390/appldata/appldata.h
index 4069b81f7f1..db3ae850510 100644
--- a/arch/s390/appldata/appldata.h
+++ b/arch/s390/appldata/appldata.h
@@ -45,7 +45,6 @@ struct appldata_ops {
int active; /* monitoring status */
/* fill in from here */
- unsigned int ctl_nr; /* sysctl ID */
char name[APPLDATA_PROC_NAME_LENGTH]; /* name of /proc fs node */
unsigned char record_nr; /* Record Nr. for Product ID */
void (*callback)(void *data); /* callback function */
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c
index ac61cf43a7d..655d52543e2 100644
--- a/arch/s390/appldata/appldata_base.c
+++ b/arch/s390/appldata/appldata_base.c
@@ -53,29 +53,26 @@ static int appldata_interval_handler(ctl_table *ctl, int write,
static struct ctl_table_header *appldata_sysctl_header;
static struct ctl_table appldata_table[] = {
{
- .ctl_name = CTL_APPLDATA_TIMER,
.procname = "timer",
.mode = S_IRUGO | S_IWUSR,
.proc_handler = &appldata_timer_handler,
},
{
- .ctl_name = CTL_APPLDATA_INTERVAL,
.procname = "interval",
.mode = S_IRUGO | S_IWUSR,
.proc_handler = &appldata_interval_handler,
},
- { .ctl_name = 0 }
+ { },
};
static struct ctl_table appldata_dir_table[] = {
{
- .ctl_name = CTL_APPLDATA,
.procname = appldata_proc_name,
.maxlen = 0,
.mode = S_IRUGO | S_IXUGO,
.child = appldata_table,
},
- { .ctl_name = 0 }
+ { },
};
/*
@@ -441,75 +438,38 @@ out:
*/
int appldata_register_ops(struct appldata_ops *ops)
{
- struct list_head *lh;
- struct appldata_ops *tmp_ops;
- int i;
-
- i = 0;
+ if ((ops->size > APPLDATA_MAX_REC_SIZE) || (ops->size < 0))
+ return -EINVAL;
- if ((ops->size > APPLDATA_MAX_REC_SIZE) ||
- (ops->size < 0)){
- P_ERROR("Invalid size of %s record = %i, maximum = %i!\n",
- ops->name, ops->size, APPLDATA_MAX_REC_SIZE);
- return -ENOMEM;
- }
- if ((ops->ctl_nr == CTL_APPLDATA) ||
- (ops->ctl_nr == CTL_APPLDATA_TIMER) ||
- (ops->ctl_nr == CTL_APPLDATA_INTERVAL)) {
- P_ERROR("ctl_nr %i already in use!\n", ops->ctl_nr);
- return -EBUSY;
- }
- ops->ctl_table = kzalloc(4*sizeof(struct ctl_table), GFP_KERNEL);
- if (ops->ctl_table == NULL) {
- P_ERROR("Not enough memory for %s ctl_table!\n", ops->name);
+ ops->ctl_table = kzalloc(4 * sizeof(struct ctl_table), GFP_KERNEL);
+ if (!ops->ctl_table)
return -ENOMEM;
- }
spin_lock(&appldata_ops_lock);
- list_for_each(lh, &appldata_ops_list) {
- tmp_ops = list_entry(lh, struct appldata_ops, list);
- P_DEBUG("register_ops loop: %i) name = %s, ctl = %i\n",
- ++i, tmp_ops->name, tmp_ops->ctl_nr);
- P_DEBUG("Comparing %s (ctl %i) with %s (ctl %i)\n",
- tmp_ops->name, tmp_ops->ctl_nr, ops->name,
- ops->ctl_nr);
- if (strncmp(tmp_ops->name, ops->name,
- APPLDATA_PROC_NAME_LENGTH) == 0) {
- P_ERROR("Name \"%s\" already registered!\n", ops->name);
- kfree(ops->ctl_table);
- spin_unlock(&appldata_ops_lock);
- return -EBUSY;
- }
- if (tmp_ops->ctl_nr == ops->ctl_nr) {
- P_ERROR("ctl_nr %i already registered!\n", ops->ctl_nr);
- kfree(ops->ctl_table);
- spin_unlock(&appldata_ops_lock);
- return -EBUSY;
- }
- }
list_add(&ops->list, &appldata_ops_list);
spin_unlock(&appldata_ops_lock);
- ops->ctl_table[0].ctl_name = CTL_APPLDATA;
ops->ctl_table[0].procname = appldata_proc_name;
ops->ctl_table[0].maxlen = 0;
ops->ctl_table[0].mode = S_IRUGO | S_IXUGO;
ops->ctl_table[0].child = &ops->ctl_table[2];
- ops->ctl_table[1].ctl_name = 0;
-
- ops->ctl_table[2].ctl_name = ops->ctl_nr;
ops->ctl_table[2].procname = ops->name;
ops->ctl_table[2].mode = S_IRUGO | S_IWUSR;
ops->ctl_table[2].proc_handler = appldata_generic_handler;
ops->ctl_table[2].data = ops;
- ops->ctl_table[3].ctl_name = 0;
-
ops->sysctl_header = register_sysctl_table(ops->ctl_table);
-
+ if (!ops->sysctl_header)
+ goto out;
P_INFO("%s-ops registered!\n", ops->name);
return 0;
+out:
+ spin_lock(&appldata_ops_lock);
+ list_del(&ops->list);
+ spin_unlock(&appldata_ops_lock);
+ kfree(ops->ctl_table);
+ return -ENOMEM;
}
/*
@@ -519,15 +479,11 @@ int appldata_register_ops(struct appldata_ops *ops)
*/
void appldata_unregister_ops(struct appldata_ops *ops)
{
- void *table;
spin_lock(&appldata_ops_lock);
list_del(&ops->list);
- /* at that point any incoming access will fail */
- table = ops->ctl_table;
- ops->ctl_table = NULL;
spin_unlock(&appldata_ops_lock);
unregister_sysctl_table(ops->sysctl_header);
- kfree(table);
+ kfree(ops->ctl_table);
P_INFO("%s-ops unregistered!\n", ops->name);
}
/********************** module-ops management <END> **************************/
diff --git a/arch/s390/appldata/appldata_mem.c b/arch/s390/appldata/appldata_mem.c
index 697eb30a68a..51181ccdb87 100644
--- a/arch/s390/appldata/appldata_mem.c
+++ b/arch/s390/appldata/appldata_mem.c
@@ -147,7 +147,6 @@ static void appldata_get_mem_data(void *data)
static struct appldata_ops ops = {
- .ctl_nr = CTL_APPLDATA_MEM,
.name = "mem",
.record_nr = APPLDATA_RECORD_MEM_ID,
.size = sizeof(struct appldata_mem_data),
diff --git a/arch/s390/appldata/appldata_net_sum.c b/arch/s390/appldata/appldata_net_sum.c
index 6c1815a4771..4d834433600 100644
--- a/arch/s390/appldata/appldata_net_sum.c
+++ b/arch/s390/appldata/appldata_net_sum.c
@@ -142,7 +142,6 @@ static void appldata_get_net_sum_data(void *data)
static struct appldata_ops ops = {
- .ctl_nr = CTL_APPLDATA_NET_SUM,
.name = "net_sum",
.record_nr = APPLDATA_RECORD_NET_SUM_ID,
.size = sizeof(struct appldata_net_sum_data),
diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c
index 76a15523ae9..6b3eafe1045 100644
--- a/arch/s390/appldata/appldata_os.c
+++ b/arch/s390/appldata/appldata_os.c
@@ -82,7 +82,6 @@ struct appldata_os_data {
static struct appldata_os_data *appldata_os_data;
static struct appldata_ops ops = {
- .ctl_nr = CTL_APPLDATA_OS,
.name = "os",
.record_nr = APPLDATA_RECORD_OS_ID,
.owner = THIS_MODULE,
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index 8bf4ae1150b..1b3af7dab81 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -200,7 +200,7 @@ static noinline __init void find_memory_chunks(unsigned long memsize)
cc = __tprot(addr);
while (cc == old_cc) {
addr += CHUNK_INCR;
- if (addr >= memsize)
+ if (memsize && addr >= memsize)
break;
#ifndef CONFIG_64BIT
if (addr == ADDR2G)
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 139ca153d5c..b2b2edc40eb 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -69,13 +69,31 @@ STACK_SIZE = 1 << STACK_SHIFT
basr %r14,%r1
.endm
- .macro LOCKDEP_SYS_EXIT
- l %r1,BASED(.Llockdep_sys_exit)
+ .macro TRACE_IRQS_CHECK
+ tm SP_PSW(%r15),0x03 # irqs enabled?
+ jz 0f
+ l %r1,BASED(.Ltrace_irq_on)
basr %r14,%r1
+ j 1f
+0: l %r1,BASED(.Ltrace_irq_off)
+ basr %r14,%r1
+1:
.endm
#else
#define TRACE_IRQS_ON
#define TRACE_IRQS_OFF
+#define TRACE_IRQS_CHECK
+#endif
+
+#ifdef CONFIG_LOCKDEP
+ .macro LOCKDEP_SYS_EXIT
+ tm SP_PSW+1(%r15),0x01 # returning to user ?
+ jz 0f
+ l %r1,BASED(.Llockdep_sys_exit)
+ basr %r14,%r1
+0:
+ .endm
+#else
#define LOCKDEP_SYS_EXIT
#endif
@@ -234,8 +252,6 @@ sysc_saveall:
lh %r7,0x8a # get svc number from lowcore
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
sysc_vtime:
- tm SP_PSW+1(%r15),0x01 # interrupting from user ?
- bz BASED(sysc_do_svc)
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
sysc_stime:
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
@@ -263,19 +279,34 @@ sysc_do_restart:
sysc_return:
tm SP_PSW+1(%r15),0x01 # returning to user ?
- bno BASED(sysc_leave)
+ bno BASED(sysc_restore)
tm __TI_flags+3(%r9),_TIF_WORK_SVC
bnz BASED(sysc_work) # there is work to do (signals etc.)
+sysc_restore:
+#ifdef CONFIG_TRACE_IRQFLAGS
+ la %r1,BASED(sysc_restore_trace_psw)
+ lpsw 0(%r1)
+sysc_restore_trace:
+ TRACE_IRQS_CHECK
LOCKDEP_SYS_EXIT
+#endif
sysc_leave:
RESTORE_ALL __LC_RETURN_PSW,1
+sysc_done:
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+ .align 8
+ .globl sysc_restore_trace_psw
+sysc_restore_trace_psw:
+ .long 0, sysc_restore_trace + 0x80000000
+#endif
#
# recheck if there is more work to do
#
sysc_work_loop:
tm __TI_flags+3(%r9),_TIF_WORK_SVC
- bz BASED(sysc_leave) # there is no work to do
+ bz BASED(sysc_restore) # there is no work to do
#
# One of the work bits is on. Find out which one.
#
@@ -290,8 +321,8 @@ sysc_work:
bo BASED(sysc_restart)
tm __TI_flags+3(%r9),_TIF_SINGLE_STEP
bo BASED(sysc_singlestep)
- LOCKDEP_SYS_EXIT
- b BASED(sysc_leave)
+ b BASED(sysc_restore)
+sysc_work_done:
#
# _TIF_NEED_RESCHED is set, call schedule
@@ -458,6 +489,7 @@ pgm_check_handler:
pgm_no_vtime:
#endif
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
+ TRACE_IRQS_OFF
l %r3,__LC_PGM_ILC # load program interruption code
la %r8,0x7f
nr %r8,%r3
@@ -497,6 +529,7 @@ pgm_per_std:
pgm_no_vtime2:
#endif
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
+ TRACE_IRQS_OFF
l %r1,__TI_task(%r9)
mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
@@ -517,15 +550,13 @@ pgm_svcper:
SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
- tm SP_PSW+1(%r15),0x01 # interrupting from user ?
- bz BASED(pgm_no_vtime3)
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
-pgm_no_vtime3:
#endif
lh %r7,0x8a # get svc number from lowcore
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
+ TRACE_IRQS_OFF
l %r1,__TI_task(%r9)
mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
@@ -542,7 +573,7 @@ kernel_per:
mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check
la %r2,SP_PTREGS(%r15) # address of register-save area
l %r1,BASED(.Lhandle_per) # load adr. of per handler
- la %r14,BASED(sysc_leave) # load adr. of system return
+ la %r14,BASED(sysc_restore)# load adr. of system return
br %r1 # branch to do_single_step
/*
@@ -569,26 +600,38 @@ io_no_vtime:
l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ
la %r2,SP_PTREGS(%r15) # address of register-save area
basr %r14,%r1 # branch to standard irq handler
- TRACE_IRQS_ON
-
io_return:
tm SP_PSW+1(%r15),0x01 # returning to user ?
#ifdef CONFIG_PREEMPT
bno BASED(io_preempt) # no -> check for preemptive scheduling
#else
- bno BASED(io_leave) # no-> skip resched & signal
+ bno BASED(io_restore) # no-> skip resched & signal
#endif
tm __TI_flags+3(%r9),_TIF_WORK_INT
bnz BASED(io_work) # there is work to do (signals etc.)
+io_restore:
+#ifdef CONFIG_TRACE_IRQFLAGS
+ la %r1,BASED(io_restore_trace_psw)
+ lpsw 0(%r1)
+io_restore_trace:
+ TRACE_IRQS_CHECK
LOCKDEP_SYS_EXIT
+#endif
io_leave:
RESTORE_ALL __LC_RETURN_PSW,0
io_done:
+#ifdef CONFIG_TRACE_IRQFLAGS
+ .align 8
+ .globl io_restore_trace_psw
+io_restore_trace_psw:
+ .long 0, io_restore_trace + 0x80000000
+#endif
+
#ifdef CONFIG_PREEMPT
io_preempt:
icm %r0,15,__TI_precount(%r9)
- bnz BASED(io_leave)
+ bnz BASED(io_restore)
l %r1,SP_R15(%r15)
s %r1,BASED(.Lc_spsize)
mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
@@ -596,14 +639,10 @@ io_preempt:
lr %r15,%r1
io_resume_loop:
tm __TI_flags+3(%r9),_TIF_NEED_RESCHED
- bno BASED(io_leave)
- mvc __TI_precount(4,%r9),BASED(.Lc_pactive)
- stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
- l %r1,BASED(.Lschedule)
- basr %r14,%r1 # call schedule
- stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
- xc __TI_precount(4,%r9),__TI_precount(%r9)
- b BASED(io_resume_loop)
+ bno BASED(io_restore)
+ l %r1,BASED(.Lpreempt_schedule_irq)
+ la %r14,BASED(io_resume_loop)
+ br %r1 # call schedule
#endif
#
@@ -627,40 +666,42 @@ io_work_loop:
bo BASED(io_reschedule)
tm __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)
bnz BASED(io_sigpending)
- LOCKDEP_SYS_EXIT
- b BASED(io_leave)
+ b BASED(io_restore)
+io_work_done:
#
# _TIF_MCCK_PENDING is set, call handler
#
io_mcck_pending:
- TRACE_IRQS_OFF
l %r1,BASED(.Ls390_handle_mcck)
basr %r14,%r1 # TIF bit will be cleared by handler
- TRACE_IRQS_ON
b BASED(io_work_loop)
#
# _TIF_NEED_RESCHED is set, call schedule
#
io_reschedule:
+ TRACE_IRQS_ON
l %r1,BASED(.Lschedule)
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
basr %r14,%r1 # call scheduler
stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
+ TRACE_IRQS_OFF
tm __TI_flags+3(%r9),_TIF_WORK_INT
- bz BASED(io_leave) # there is no work to do
+ bz BASED(io_restore) # there is no work to do
b BASED(io_work_loop)
#
# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal
#
io_sigpending:
+ TRACE_IRQS_ON
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
la %r2,SP_PTREGS(%r15) # load pt_regs
l %r1,BASED(.Ldo_signal)
basr %r14,%r1 # call do_signal
stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
+ TRACE_IRQS_OFF
b BASED(io_work_loop)
/*
@@ -688,7 +729,6 @@ ext_no_vtime:
lh %r3,__LC_EXT_INT_CODE # get interruption code
l %r1,BASED(.Ldo_extint)
basr %r14,%r1
- TRACE_IRQS_ON
b BASED(io_return)
__critical_end:
@@ -853,15 +893,15 @@ cleanup_table_system_call:
cleanup_table_sysc_return:
.long sysc_return + 0x80000000, sysc_leave + 0x80000000
cleanup_table_sysc_leave:
- .long sysc_leave + 0x80000000, sysc_work_loop + 0x80000000
+ .long sysc_leave + 0x80000000, sysc_done + 0x80000000
cleanup_table_sysc_work_loop:
- .long sysc_work_loop + 0x80000000, sysc_reschedule + 0x80000000
+ .long sysc_work_loop + 0x80000000, sysc_work_done + 0x80000000
cleanup_table_io_return:
.long io_return + 0x80000000, io_leave + 0x80000000
cleanup_table_io_leave:
.long io_leave + 0x80000000, io_done + 0x80000000
cleanup_table_io_work_loop:
- .long io_work_loop + 0x80000000, io_mcck_pending + 0x80000000
+ .long io_work_loop + 0x80000000, io_work_done + 0x80000000
cleanup_critical:
clc 4(4,%r12),BASED(cleanup_table_system_call)
@@ -930,8 +970,6 @@ cleanup_system_call:
cleanup_vtime:
clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12)
bhe BASED(cleanup_stime)
- tm SP_PSW+1(%r15),0x01 # interrupting from user ?
- bz BASED(cleanup_novtime)
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
cleanup_stime:
clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+16)
@@ -939,7 +977,6 @@ cleanup_stime:
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
cleanup_update:
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
-cleanup_novtime:
#endif
mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_system_call+4)
la %r12,__LC_RETURN_PSW
@@ -978,10 +1015,10 @@ cleanup_sysc_leave:
2: la %r12,__LC_RETURN_PSW
br %r14
cleanup_sysc_leave_insn:
+ .long sysc_done - 4 + 0x80000000
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
- .long sysc_leave + 14 + 0x80000000
+ .long sysc_done - 8 + 0x80000000
#endif
- .long sysc_leave + 10 + 0x80000000
cleanup_io_return:
mvc __LC_RETURN_PSW(4),0(%r12)
@@ -1008,10 +1045,10 @@ cleanup_io_leave:
2: la %r12,__LC_RETURN_PSW
br %r14
cleanup_io_leave_insn:
+ .long io_done - 4 + 0x80000000
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
- .long io_leave + 18 + 0x80000000
+ .long io_done - 8 + 0x80000000
#endif
- .long io_leave + 14 + 0x80000000
/*
* Integer constants
@@ -1019,7 +1056,6 @@ cleanup_io_leave_insn:
.align 4
.Lc_spsize: .long SP_SIZE
.Lc_overhead: .long STACK_FRAME_OVERHEAD
-.Lc_pactive: .long PREEMPT_ACTIVE
.Lnr_syscalls: .long NR_syscalls
.L0x018: .short 0x018
.L0x020: .short 0x020
@@ -1043,6 +1079,8 @@ cleanup_io_leave_insn:
.Lexecve_tail: .long execve_tail
.Ljump_table: .long pgm_check_table
.Lschedule: .long schedule
+.Lpreempt_schedule_irq:
+ .long preempt_schedule_irq
.Ltrace: .long syscall_trace
.Lschedtail: .long schedule_tail
.Lsysc_table: .long sys_call_table
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 05e26d1fdf4..a3e47b893f0 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -67,12 +67,28 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
brasl %r14,trace_hardirqs_off
.endm
- .macro LOCKDEP_SYS_EXIT
- brasl %r14,lockdep_sys_exit
+ .macro TRACE_IRQS_CHECK
+ tm SP_PSW(%r15),0x03 # irqs enabled?
+ jz 0f
+ brasl %r14,trace_hardirqs_on
+ j 1f
+0: brasl %r14,trace_hardirqs_off
+1:
.endm
#else
#define TRACE_IRQS_ON
#define TRACE_IRQS_OFF
+#define TRACE_IRQS_CHECK
+#endif
+
+#ifdef CONFIG_LOCKDEP
+ .macro LOCKDEP_SYS_EXIT
+ tm SP_PSW+1(%r15),0x01 # returning to user ?
+ jz 0f
+ brasl %r14,lockdep_sys_exit
+0:
+ .endm
+#else
#define LOCKDEP_SYS_EXIT
#endif
@@ -222,8 +238,6 @@ sysc_saveall:
llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
sysc_vtime:
- tm SP_PSW+1(%r15),0x01 # interrupting from user ?
- jz sysc_do_svc
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
sysc_stime:
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
@@ -257,19 +271,34 @@ sysc_noemu:
sysc_return:
tm SP_PSW+1(%r15),0x01 # returning to user ?
- jno sysc_leave
+ jno sysc_restore
tm __TI_flags+7(%r9),_TIF_WORK_SVC
jnz sysc_work # there is work to do (signals etc.)
+sysc_restore:
+#ifdef CONFIG_TRACE_IRQFLAGS
+ larl %r1,sysc_restore_trace_psw
+ lpswe 0(%r1)
+sysc_restore_trace:
+ TRACE_IRQS_CHECK
LOCKDEP_SYS_EXIT
+#endif
sysc_leave:
RESTORE_ALL __LC_RETURN_PSW,1
+sysc_done:
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+ .align 8
+ .globl sysc_restore_trace_psw
+sysc_restore_trace_psw:
+ .quad 0, sysc_restore_trace
+#endif
#
# recheck if there is more work to do
#
sysc_work_loop:
tm __TI_flags+7(%r9),_TIF_WORK_SVC
- jz sysc_leave # there is no work to do
+ jz sysc_restore # there is no work to do
#
# One of the work bits is on. Find out which one.
#
@@ -284,8 +313,8 @@ sysc_work:
jo sysc_restart
tm __TI_flags+7(%r9),_TIF_SINGLE_STEP
jo sysc_singlestep
- LOCKDEP_SYS_EXIT
- j sysc_leave
+ j sysc_restore
+sysc_work_done:
#
# _TIF_NEED_RESCHED is set, call schedule
@@ -445,6 +474,7 @@ pgm_check_handler:
pgm_no_vtime:
#endif
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
+ TRACE_IRQS_OFF
lgf %r3,__LC_PGM_ILC # load program interruption code
lghi %r8,0x7f
ngr %r8,%r3
@@ -484,6 +514,7 @@ pgm_per_std:
pgm_no_vtime2:
#endif
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
+ TRACE_IRQS_OFF
lg %r1,__TI_task(%r9)
tm SP_PSW+1(%r15),0x01 # kernel per event ?
jz kernel_per
@@ -504,12 +535,9 @@ pgm_svcper:
SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
- tm SP_PSW+1(%r15),0x01 # interrupting from user ?
- jz pgm_no_vtime3
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
-pgm_no_vtime3:
#endif
llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
@@ -529,7 +557,7 @@ kernel_per:
lhi %r0,__LC_PGM_OLD_PSW
sth %r0,SP_TRAP(%r15) # set trap indication to pgm check
la %r2,SP_PTREGS(%r15) # address of register-save area
- larl %r14,sysc_leave # load adr. of system ret, no work
+ larl %r14,sysc_restore # load adr. of system ret, no work
jg do_single_step # branch to do_single_step
/*
@@ -554,26 +582,38 @@ io_no_vtime:
TRACE_IRQS_OFF
la %r2,SP_PTREGS(%r15) # address of register-save area
brasl %r14,do_IRQ # call standard irq handler
- TRACE_IRQS_ON
-
io_return:
tm SP_PSW+1(%r15),0x01 # returning to user ?
#ifdef CONFIG_PREEMPT
jno io_preempt # no -> check for preemptive scheduling
#else
- jno io_leave # no-> skip resched & signal
+ jno io_restore # no-> skip resched & signal
#endif
tm __TI_flags+7(%r9),_TIF_WORK_INT
jnz io_work # there is work to do (signals etc.)
+io_restore:
+#ifdef CONFIG_TRACE_IRQFLAGS
+ larl %r1,io_restore_trace_psw
+ lpswe 0(%r1)
+io_restore_trace:
+ TRACE_IRQS_CHECK
LOCKDEP_SYS_EXIT
+#endif
io_leave:
RESTORE_ALL __LC_RETURN_PSW,0
io_done:
+#ifdef CONFIG_TRACE_IRQFLAGS
+ .align 8
+ .globl io_restore_trace_psw
+io_restore_trace_psw:
+ .quad 0, io_restore_trace
+#endif
+
#ifdef CONFIG_PREEMPT
io_preempt:
icm %r0,15,__TI_precount(%r9)
- jnz io_leave
+ jnz io_restore
# switch to kernel stack
lg %r1,SP_R15(%r15)
aghi %r1,-SP_SIZE
@@ -582,14 +622,9 @@ io_preempt:
lgr %r15,%r1
io_resume_loop:
tm __TI_flags+7(%r9),_TIF_NEED_RESCHED
- jno io_leave
- larl %r1,.Lc_pactive
- mvc __TI_precount(4,%r9),0(%r1)
- stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
- brasl %r14,schedule # call schedule
- stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
- xc __TI_precount(4,%r9),__TI_precount(%r9)
- j io_resume_loop
+ jno io_restore
+ larl %r14,io_resume_loop
+ jg preempt_schedule_irq
#endif
#
@@ -613,37 +648,39 @@ io_work_loop:
jo io_reschedule
tm __TI_flags+7(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)
jnz io_sigpending
- LOCKDEP_SYS_EXIT
- j io_leave
+ j io_restore
+io_work_done:
#
# _TIF_MCCK_PENDING is set, call handler
#
io_mcck_pending:
- TRACE_IRQS_OFF
brasl %r14,s390_handle_mcck # TIF bit will be cleared by handler
- TRACE_IRQS_ON
j io_work_loop
#
# _TIF_NEED_RESCHED is set, call schedule
#
io_reschedule:
+ TRACE_IRQS_ON
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
brasl %r14,schedule # call scheduler
stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
+ TRACE_IRQS_OFF
tm __TI_flags+7(%r9),_TIF_WORK_INT
- jz io_leave # there is no work to do
+ jz io_restore # there is no work to do
j io_work_loop
#
# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal
#
io_sigpending:
+ TRACE_IRQS_ON
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
la %r2,SP_PTREGS(%r15) # load pt_regs
brasl %r14,do_signal # call do_signal
stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
+ TRACE_IRQS_OFF
j io_work_loop
/*
@@ -669,7 +706,6 @@ ext_no_vtime:
la %r2,SP_PTREGS(%r15) # address of register-save area
llgh %r3,__LC_EXT_INT_CODE # get interruption code
brasl %r14,do_extint
- TRACE_IRQS_ON
j io_return
__critical_end:
@@ -824,15 +860,15 @@ cleanup_table_system_call:
cleanup_table_sysc_return:
.quad sysc_return, sysc_leave
cleanup_table_sysc_leave:
- .quad sysc_leave, sysc_work_loop
+ .quad sysc_leave, sysc_done
cleanup_table_sysc_work_loop:
- .quad sysc_work_loop, sysc_reschedule
+ .quad sysc_work_loop, sysc_work_done
cleanup_table_io_return:
.quad io_return, io_leave
cleanup_table_io_leave:
.quad io_leave, io_done
cleanup_table_io_work_loop:
- .quad io_work_loop, io_mcck_pending
+ .quad io_work_loop, io_work_done
cleanup_critical:
clc 8(8,%r12),BASED(cleanup_table_system_call)
@@ -901,8 +937,6 @@ cleanup_system_call:
cleanup_vtime:
clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24)
jhe cleanup_stime
- tm SP_PSW+1(%r15),0x01 # interrupting from user ?
- jz cleanup_novtime
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
cleanup_stime:
clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+32)
@@ -910,7 +944,6 @@ cleanup_stime:
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
cleanup_update:
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
-cleanup_novtime:
#endif
mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_system_call+8)
la %r12,__LC_RETURN_PSW
@@ -949,10 +982,10 @@ cleanup_sysc_leave:
2: la %r12,__LC_RETURN_PSW
br %r14
cleanup_sysc_leave_insn:
+ .quad sysc_done - 4
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
- .quad sysc_leave + 16
+ .quad sysc_done - 8
#endif
- .quad sysc_leave + 12
cleanup_io_return:
mvc __LC_RETURN_PSW(8),0(%r12)
@@ -979,17 +1012,16 @@ cleanup_io_leave:
2: la %r12,__LC_RETURN_PSW
br %r14
cleanup_io_leave_insn:
+ .quad io_done - 4
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
- .quad io_leave + 20
+ .quad io_done - 8
#endif
- .quad io_leave + 16
/*
* Integer constants
*/
.align 4
.Lconst:
-.Lc_pactive: .long PREEMPT_ACTIVE
.Lnr_syscalls: .long NR_syscalls
.L0x0130: .short 0x130
.L0x0140: .short 0x140
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 7e1bfb98406..50f8f1e3760 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -347,7 +347,7 @@ void (*_machine_power_off)(void) = do_machine_power_off_nonsmp;
void machine_restart(char *command)
{
- if (!in_interrupt() || oops_in_progress)
+ if ((!in_interrupt() && !in_atomic()) || oops_in_progress)
/*
* Only unblank the console if we are called in enabled
* context or a bust_spinlocks cleared the way for us.
@@ -492,6 +492,10 @@ static void setup_addressing_mode(void)
printk("S390 address spaces switched, ");
set_amode_and_uaccess(PSW_ASC_PRIMARY, PSW32_ASC_PRIMARY);
}
+#ifdef CONFIG_TRACE_IRQFLAGS
+ sysc_restore_trace_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK;
+ io_restore_trace_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK;
+#endif
}
static void __init
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index b05ae858425..264ea906db4 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -193,72 +193,30 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
}
EXPORT_SYMBOL(smp_call_function_single);
-static void do_send_stop(void)
+void smp_send_stop(void)
{
int cpu, rc;
- /* stop all processors */
- for_each_online_cpu(cpu) {
- if (cpu == smp_processor_id())
- continue;
- do {
- rc = signal_processor(cpu, sigp_stop);
- } while (rc == sigp_busy);
- }
-}
+ /* Disable all interrupts/machine checks */
+ __load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK);
-static void do_store_status(void)
-{
- int cpu, rc;
+ /* write magic number to zero page (absolute 0) */
+ lowcore_ptr[smp_processor_id()]->panic_magic = __PANIC_MAGIC;
- /* store status of all processors in their lowcores (real 0) */
+ /* stop all processors */
for_each_online_cpu(cpu) {
if (cpu == smp_processor_id())
continue;
do {
- rc = signal_processor_p(
- (__u32)(unsigned long) lowcore_ptr[cpu], cpu,
- sigp_store_status_at_address);
+ rc = signal_processor(cpu, sigp_stop);
} while (rc == sigp_busy);
- }
-}
-static void do_wait_for_stop(void)
-{
- int cpu;
-
- /* Wait for all other cpus to enter stopped state */
- for_each_online_cpu(cpu) {
- if (cpu == smp_processor_id())
- continue;
while (!smp_cpu_not_running(cpu))
cpu_relax();
}
}
/*
- * this function sends a 'stop' sigp to all other CPUs in the system.
- * it goes straight through.
- */
-void smp_send_stop(void)
-{
- /* Disable all interrupts/machine checks */
- __load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK);
-
- /* write magic number to zero page (absolute 0) */
- lowcore_ptr[smp_processor_id()]->panic_magic = __PANIC_MAGIC;
-
- /* stop other processors. */
- do_send_stop();
-
- /* wait until other processors are stopped */
- do_wait_for_stop();
-
- /* store status of other processors. */
- do_store_status();
-}
-
-/*
* Reboot, halt and power_off routines for SMP.
*/
void machine_restart_smp(char *__unused)
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 8ec9def83cc..8ed16a83fba 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -260,6 +260,7 @@ void die(const char * str, struct pt_regs * regs, long err)
bust_spinlocks(1);
printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
print_modules();
+ notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV);
show_regs(regs);
bust_spinlocks(0);
add_taint(TAINT_DIE);
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
index d4ed93dfb9c..413c240cbca 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -341,19 +341,16 @@ cmm_timeout_handler(ctl_table *ctl, int write, struct file *filp,
static struct ctl_table cmm_table[] = {
{
- .ctl_name = VM_CMM_PAGES,
.procname = "cmm_pages",
.mode = 0644,
.proc_handler = &cmm_pages_handler,
},
{
- .ctl_name = VM_CMM_TIMED_PAGES,
.procname = "cmm_timed_pages",
.mode = 0644,
.proc_handler = &cmm_pages_handler,
},
{
- .ctl_name = VM_CMM_TIMEOUT,
.procname = "cmm_timeout",
.mode = 0644,
.proc_handler = &cmm_timeout_handler,
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 116b03a4563..7aa1dc6d67c 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -11,10 +11,9 @@ endif
$(srctree)/arch/x86/Makefile%: ;
ifeq ($(CONFIG_X86_32),y)
+ UTS_MACHINE := i386
include $(srctree)/arch/x86/Makefile_32
else
+ UTS_MACHINE := x86_64
include $(srctree)/arch/x86/Makefile_64
endif
-
-
-
diff --git a/arch/x86/kernel/acpi/processor.c b/arch/x86/kernel/acpi/processor.c
index f63e5ff0aca..a25db514c71 100644
--- a/arch/x86/kernel/acpi/processor.c
+++ b/arch/x86/kernel/acpi/processor.c
@@ -49,6 +49,9 @@ static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c)
if (cpu_has(c, X86_FEATURE_EST))
buf[2] |= ACPI_PDC_EST_CAPABILITY_SWSMP;
+ if (cpu_has(c, X86_FEATURE_ACPI))
+ buf[2] |= ACPI_PDC_T_FFH;
+
obj->type = ACPI_TYPE_BUFFER;
obj->buffer.length = 12;
obj->buffer.pointer = (u8 *) buf;
diff --git a/arch/x86/kernel/acpi/sleep_64.c b/arch/x86/kernel/acpi/sleep_64.c
index 79475d23707..da42de261ba 100644
--- a/arch/x86/kernel/acpi/sleep_64.c
+++ b/arch/x86/kernel/acpi/sleep_64.c
@@ -115,6 +115,3 @@ static int __init acpi_sleep_setup(char *str)
__setup("acpi_sleep=", acpi_sleep_setup);
-void acpi_pci_link_exit(void)
-{
-}
diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c
index f35c6eb33da..6bb80ea5f4e 100644
--- a/arch/x86/kernel/io_apic_32.c
+++ b/arch/x86/kernel/io_apic_32.c
@@ -962,7 +962,7 @@ static int EISA_ELCR(unsigned int irq)
#define default_MCA_trigger(idx) (1)
#define default_MCA_polarity(idx) (0)
-static int __init MPBIOS_polarity(int idx)
+static int MPBIOS_polarity(int idx)
{
int bus = mp_irqs[idx].mpc_srcbus;
int polarity;
@@ -2830,6 +2830,25 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a
return 0;
}
+int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
+{
+ int i;
+
+ if (skip_ioapic_setup)
+ return -1;
+
+ for (i = 0; i < mp_irq_entries; i++)
+ if (mp_irqs[i].mpc_irqtype == mp_INT &&
+ mp_irqs[i].mpc_srcbusirq == bus_irq)
+ break;
+ if (i >= mp_irq_entries)
+ return -1;
+
+ *trigger = irq_trigger(i);
+ *polarity = irq_polarity(i);
+ return 0;
+}
+
#endif /* CONFIG_ACPI */
static int __init parse_disable_timer_pin_1(char *arg)
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c
index 953328b55a3..435a8c9b55f 100644
--- a/arch/x86/kernel/io_apic_64.c
+++ b/arch/x86/kernel/io_apic_64.c
@@ -546,7 +546,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
#define default_PCI_trigger(idx) (1)
#define default_PCI_polarity(idx) (1)
-static int __init MPBIOS_polarity(int idx)
+static int MPBIOS_polarity(int idx)
{
int bus = mp_irqs[idx].mpc_srcbus;
int polarity;
@@ -2222,8 +2222,27 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int p
return 0;
}
-#endif /* CONFIG_ACPI */
+int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
+{
+ int i;
+
+ if (skip_ioapic_setup)
+ return -1;
+
+ for (i = 0; i < mp_irq_entries; i++)
+ if (mp_irqs[i].mpc_irqtype == mp_INT &&
+ mp_irqs[i].mpc_srcbusirq == bus_irq)
+ break;
+ if (i >= mp_irq_entries)
+ return -1;
+
+ *trigger = irq_trigger(i);
+ *polarity = irq_polarity(i);
+ return 0;
+}
+
+#endif /* CONFIG_ACPI */
/*
* This function currently is only a helper for the i386 smp boot process where
@@ -2260,3 +2279,4 @@ void __init setup_ioapic_dest(void)
}
}
#endif
+
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 7e35078673a..0234f2831bf 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -13,7 +13,7 @@ static int __devinit can_skip_ioresource_align(const struct dmi_system_id *d)
return 0;
}
-static struct dmi_system_id acpi_pciprobe_dmi_table[] = {
+static struct dmi_system_id acpi_pciprobe_dmi_table[] __devinitdata = {
/*
* Systems where PCI IO resource ISA alignment can be skipped
* when the ISA enable bit in the bridge control is not set
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 087a7028ae8..b9f923ef173 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -50,7 +50,6 @@ config ACPI_SLEEP
config ACPI_PROCFS
bool "Deprecated /proc/acpi files"
depends on PROC_FS
- default y
---help---
For backwards compatibility, this option allows
deprecated /proc/acpi/ files to exist, even when
@@ -61,7 +60,6 @@ config ACPI_PROCFS
/proc/acpi/info (/sys/modules/acpi/parameters/acpica_version)
/proc/acpi/dsdt (/sys/firmware/acpi/tables/DSDT)
/proc/acpi/fadt (/sys/firmware/acpi/tables/FACP)
- /proc/acpi/battery (/sys/class/power_supply)
/proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer)
/proc/acpi/debug_level (/sys/module/acpi/parameters/debug_level)
@@ -69,7 +67,21 @@ config ACPI_PROCFS
and functions which do not yet exist in /sys.
Say N to delete /proc/acpi/ files that have moved to /sys/
-
+config ACPI_PROCFS_POWER
+ bool "Deprecated power /proc/acpi folders"
+ depends on PROC_FS
+ default y
+ ---help---
+ For backwards compatibility, this option allows
+ deprecated power /proc/acpi/ folders to exist, even when
+ they have been replaced by functions in /sys.
+ The deprecated folders (and their replacements) include:
+ /proc/acpi/battery/* (/sys/class/power_supply/*)
+ /proc/acpi/ac_adapter/* (sys/class/power_supply/*)
+ This option has no effect on /proc/acpi/ folders
+ and functions, which do not yet exist in /sys
+
+ Say N to delete power /proc/acpi/ folders that have moved to /sys/
config ACPI_PROC_EVENT
bool "Deprecated /proc/acpi/event support"
depends on PROC_FS
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 54e3ab0e5fc..456446f9007 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -58,6 +58,6 @@ obj-$(CONFIG_ACPI_NUMA) += numa.o
obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o
obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
-obj-y += cm_sbs.o
+obj-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
obj-$(CONFIG_ACPI_SBS) += sbs.o
obj-$(CONFIG_ACPI_SBS) += sbshc.o
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 30238f6ff23..76ed4f52beb 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -27,7 +27,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#endif
@@ -51,7 +51,7 @@ MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION("ACPI AC Adapter Driver");
MODULE_LICENSE("GPL");
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
extern struct proc_dir_entry *acpi_lock_ac_dir(void);
extern void *acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir);
static int acpi_ac_open_fs(struct inode *inode, struct file *file);
@@ -86,7 +86,7 @@ struct acpi_ac {
#define to_acpi_ac(x) container_of(x, struct acpi_ac, charger);
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
static const struct file_operations acpi_ac_fops = {
.open = acpi_ac_open_fs,
.read = seq_read,
@@ -136,7 +136,7 @@ static int acpi_ac_get_state(struct acpi_ac *ac)
return 0;
}
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
@@ -275,7 +275,7 @@ static int acpi_ac_add(struct acpi_device *device)
if (result)
goto end;
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
result = acpi_ac_add_fs(device);
#endif
if (result)
@@ -300,7 +300,7 @@ static int acpi_ac_add(struct acpi_device *device)
end:
if (result) {
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_ac_remove_fs(device);
#endif
kfree(ac);
@@ -339,7 +339,7 @@ static int acpi_ac_remove(struct acpi_device *device, int type)
ACPI_ALL_NOTIFY, acpi_ac_notify);
if (ac->charger.dev)
power_supply_unregister(&ac->charger);
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_ac_remove_fs(device);
#endif
@@ -355,7 +355,7 @@ static int __init acpi_ac_init(void)
if (acpi_disabled)
return -ENODEV;
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_ac_dir = acpi_lock_ac_dir();
if (!acpi_ac_dir)
return -ENODEV;
@@ -363,7 +363,7 @@ static int __init acpi_ac_init(void)
result = acpi_bus_register_driver(&acpi_ac_driver);
if (result < 0) {
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_unlock_ac_dir(acpi_ac_dir);
#endif
return -ENODEV;
@@ -377,7 +377,7 @@ static void __exit acpi_ac_exit(void)
acpi_bus_unregister_driver(&acpi_ac_driver);
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_unlock_ac_dir(acpi_ac_dir);
#endif
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 192c244f619..7d6be23eff8 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -31,7 +31,7 @@
#include <linux/types.h>
#include <linux/jiffies.h>
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h>
@@ -63,7 +63,7 @@ static unsigned int cache_time = 1000;
module_param(cache_time, uint, 0644);
MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
extern struct proc_dir_entry *acpi_lock_battery_dir(void);
extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
@@ -153,6 +153,8 @@ static int acpi_battery_get_property(struct power_supply *psy,
val->intval = POWER_SUPPLY_STATUS_CHARGING;
else if (battery->state == 0)
val->intval = POWER_SUPPLY_STATUS_FULL;
+ else
+ val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
break;
case POWER_SUPPLY_PROP_PRESENT:
val->intval = acpi_battery_present(battery);
@@ -221,7 +223,7 @@ static enum power_supply_property energy_battery_props[] = {
POWER_SUPPLY_PROP_MANUFACTURER,
};
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
inline char *acpi_battery_units(struct acpi_battery *battery)
{
return (battery->power_unit)?"mA":"mW";
@@ -479,7 +481,7 @@ static int acpi_battery_update(struct acpi_battery *battery)
FS Interface (/proc)
-------------------------------------------------------------------------- */
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
static struct proc_dir_entry *acpi_battery_dir;
static int acpi_battery_print_info(struct seq_file *seq, int result)
@@ -786,7 +788,7 @@ static int acpi_battery_add(struct acpi_device *device)
acpi_driver_data(device) = battery;
mutex_init(&battery->lock);
acpi_battery_update(battery);
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
result = acpi_battery_add_fs(device);
if (result)
goto end;
@@ -804,7 +806,7 @@ static int acpi_battery_add(struct acpi_device *device)
device->status.battery_present ? "present" : "absent");
end:
if (result) {
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_battery_remove_fs(device);
#endif
kfree(battery);
@@ -823,7 +825,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
status = acpi_remove_notify_handler(device->handle,
ACPI_ALL_NOTIFY,
acpi_battery_notify);
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_battery_remove_fs(device);
#endif
sysfs_remove_battery(battery);
@@ -859,13 +861,13 @@ static int __init acpi_battery_init(void)
{
if (acpi_disabled)
return -ENODEV;
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_battery_dir = acpi_lock_battery_dir();
if (!acpi_battery_dir)
return -ENODEV;
#endif
if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_unlock_battery_dir(acpi_battery_dir);
#endif
return -ENODEV;
@@ -876,7 +878,7 @@ static int __init acpi_battery_init(void)
static void __exit acpi_battery_exit(void)
{
acpi_bus_unregister_driver(&acpi_battery_driver);
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_unlock_battery_dir(acpi_battery_dir);
#endif
}
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 06b78e5e33a..d411017f8c0 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -47,6 +47,9 @@
#undef PREFIX
#define PREFIX "ACPI: EC: "
+/* Uncomment next line to get verbose print outs*/
+/* #define DEBUG */
+
/* EC status register */
#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */
#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */
@@ -75,7 +78,10 @@ enum {
EC_FLAGS_WAIT_GPE = 0, /* Don't check status until GPE arrives */
EC_FLAGS_QUERY_PENDING, /* Query is pending */
EC_FLAGS_GPE_MODE, /* Expect GPE to be sent for status change */
- EC_FLAGS_ONLY_IBF_GPE, /* Expect GPE only for IBF = 0 event */
+ EC_FLAGS_NO_ADDRESS_GPE, /* Expect GPE only for non-address event */
+ EC_FLAGS_ADDRESS, /* Address is being written */
+ EC_FLAGS_NO_WDATA_GPE, /* Don't expect WDATA GPE event */
+ EC_FLAGS_WDATA, /* Data is being written */
};
static int acpi_ec_remove(struct acpi_device *device, int type);
@@ -131,21 +137,27 @@ static struct acpi_ec {
static inline u8 acpi_ec_read_status(struct acpi_ec *ec)
{
- return inb(ec->command_addr);
+ u8 x = inb(ec->command_addr);
+ pr_debug(PREFIX "---> status = 0x%2x\n", x);
+ return x;
}
static inline u8 acpi_ec_read_data(struct acpi_ec *ec)
{
+ u8 x = inb(ec->data_addr);
+ pr_debug(PREFIX "---> data = 0x%2x\n", x);
return inb(ec->data_addr);
}
static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command)
{
+ pr_debug(PREFIX "<--- command = 0x%2x\n", command);
outb(command, ec->command_addr);
}
static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
{
+ pr_debug(PREFIX "<--- data = 0x%2x\n", data);
outb(data, ec->data_addr);
}
@@ -166,38 +178,54 @@ static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event)
static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
{
+ int ret = 0;
+ if (unlikely(test_bit(EC_FLAGS_ADDRESS, &ec->flags) &&
+ test_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags)))
+ force_poll = 1;
+ if (unlikely(test_bit(EC_FLAGS_WDATA, &ec->flags) &&
+ test_bit(EC_FLAGS_NO_WDATA_GPE, &ec->flags)))
+ force_poll = 1;
if (likely(test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) &&
likely(!force_poll)) {
if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event),
msecs_to_jiffies(ACPI_EC_DELAY)))
- return 0;
+ goto end;
clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
if (acpi_ec_check_status(ec, event)) {
- if (event == ACPI_EC_EVENT_OBF_1) {
- /* miss OBF = 1 GPE, don't expect it anymore */
- printk(KERN_INFO PREFIX "missing OBF_1 confirmation,"
- "switching to degraded mode.\n");
- set_bit(EC_FLAGS_ONLY_IBF_GPE, &ec->flags);
+ if (test_bit(EC_FLAGS_ADDRESS, &ec->flags)) {
+ /* miss address GPE, don't expect it anymore */
+ pr_info(PREFIX "missing address confirmation, "
+ "don't expect it any longer.\n");
+ set_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags);
+ } else if (test_bit(EC_FLAGS_WDATA, &ec->flags)) {
+ /* miss write data GPE, don't expect it */
+ pr_info(PREFIX "missing write data confirmation, "
+ "don't expect it any longer.\n");
+ set_bit(EC_FLAGS_NO_WDATA_GPE, &ec->flags);
} else {
/* missing GPEs, switch back to poll mode */
- printk(KERN_INFO PREFIX "missing IBF_1 confirmations,"
- "switch off interrupt mode.\n");
+ if (printk_ratelimit())
+ pr_info(PREFIX "missing confirmations, "
+ "switch off interrupt mode.\n");
clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
}
- return 0;
+ goto end;
}
} else {
unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
while (time_before(jiffies, delay)) {
if (acpi_ec_check_status(ec, event))
- return 0;
+ goto end;
}
}
- printk(KERN_ERR PREFIX "acpi_ec_wait timeout,"
+ pr_err(PREFIX "acpi_ec_wait timeout,"
" status = %d, expect_event = %d\n",
acpi_ec_read_status(ec), event);
- return -ETIME;
+ ret = -ETIME;
+ end:
+ clear_bit(EC_FLAGS_ADDRESS, &ec->flags);
+ return ret;
}
static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
@@ -208,22 +236,26 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
int result = 0;
set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
acpi_ec_write_cmd(ec, command);
-
+ pr_debug(PREFIX "transaction start\n");
for (; wdata_len > 0; --wdata_len) {
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
if (result) {
- printk(KERN_ERR PREFIX
+ pr_err(PREFIX
"write_cmd timeout, command = %d\n", command);
goto end;
}
+ /* mark the address byte written to EC */
+ if (rdata_len + wdata_len > 1)
+ set_bit(EC_FLAGS_ADDRESS, &ec->flags);
set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
acpi_ec_write_data(ec, *(wdata++));
}
if (!rdata_len) {
+ set_bit(EC_FLAGS_WDATA, &ec->flags);
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
if (result) {
- printk(KERN_ERR PREFIX
+ pr_err(PREFIX
"finish-write timeout, command = %d\n", command);
goto end;
}
@@ -231,12 +263,9 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
for (; rdata_len > 0; --rdata_len) {
- if (test_bit(EC_FLAGS_ONLY_IBF_GPE, &ec->flags))
- force_poll = 1;
result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, force_poll);
if (result) {
- printk(KERN_ERR PREFIX "read timeout, command = %d\n",
- command);
+ pr_err(PREFIX "read timeout, command = %d\n", command);
goto end;
}
/* Don't expect GPE after last read */
@@ -245,6 +274,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
*(rdata++) = acpi_ec_read_data(ec);
}
end:
+ pr_debug(PREFIX "transaction end\n");
return result;
}
@@ -273,8 +303,8 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0);
if (status) {
- printk(KERN_ERR PREFIX
- "input buffer is not empty, aborting transaction\n");
+ pr_err(PREFIX "input buffer is not empty, "
+ "aborting transaction\n");
goto end;
}
@@ -488,6 +518,7 @@ static u32 acpi_ec_gpe_handler(void *data)
acpi_status status = AE_OK;
struct acpi_ec *ec = data;
+ pr_debug(PREFIX "~~~> interrupt\n");
clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))
wake_up(&ec->wait);
@@ -498,8 +529,9 @@ static u32 acpi_ec_gpe_handler(void *data)
acpi_ec_gpe_query, ec);
} else if (unlikely(!test_bit(EC_FLAGS_GPE_MODE, &ec->flags))) {
/* this is non-query, must be confirmation */
- printk(KERN_INFO PREFIX "non-query interrupt received,"
- " switching to interrupt mode\n");
+ if (printk_ratelimit())
+ pr_info(PREFIX "non-query interrupt received,"
+ " switching to interrupt mode\n");
set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
}
@@ -701,10 +733,10 @@ static void ec_remove_handlers(struct acpi_ec *ec)
{
if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
- printk(KERN_ERR PREFIX "failed to remove space handler\n");
+ pr_err(PREFIX "failed to remove space handler\n");
if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe,
&acpi_ec_gpe_handler)))
- printk(KERN_ERR PREFIX "failed to remove gpe handler\n");
+ pr_err(PREFIX "failed to remove gpe handler\n");
ec->handlers_installed = 0;
}
@@ -747,9 +779,9 @@ static int acpi_ec_add(struct acpi_device *device)
first_ec = ec;
acpi_driver_data(device) = ec;
acpi_ec_add_fs(device);
- printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
+ pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
ec->gpe, ec->command_addr, ec->data_addr);
- printk(KERN_INFO PREFIX "driver started in %s mode\n",
+ pr_info(PREFIX "driver started in %s mode\n",
(test_bit(EC_FLAGS_GPE_MODE, &ec->flags))?"interrupt":"poll");
return 0;
}
@@ -875,18 +907,26 @@ int __init acpi_ec_ecdt_probe(void)
status = acpi_get_table(ACPI_SIG_ECDT, 1,
(struct acpi_table_header **)&ecdt_ptr);
if (ACPI_SUCCESS(status)) {
- printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n");
+ pr_info(PREFIX "EC description table is found, configuring boot EC\n");
boot_ec->command_addr = ecdt_ptr->control.address;
boot_ec->data_addr = ecdt_ptr->data.address;
boot_ec->gpe = ecdt_ptr->gpe;
boot_ec->handle = ACPI_ROOT_OBJECT;
} else {
+ /* This workaround is needed only on some broken machines,
+ * which require early EC, but fail to provide ECDT */
+ acpi_handle x;
printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n");
status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device,
boot_ec, NULL);
/* Check that acpi_get_devices actually find something */
if (ACPI_FAILURE(status) || !boot_ec->handle)
goto error;
+ /* We really need to limit this workaround, the only ASUS,
+ * which needs it, has fake EC._INI method, so use it as flag.
+ */
+ if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &x)))
+ goto error;
}
ret = ec_install_handlers(boot_ec);
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index aabc6ca4a81..e3a673a0084 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -387,17 +387,14 @@ acpi_status acpi_os_read_port(acpi_io_address port, u32 * value, u32 width)
if (!value)
value = &dummy;
- switch (width) {
- case 8:
+ *value = 0;
+ if (width <= 8) {
*(u8 *) value = inb(port);
- break;
- case 16:
+ } else if (width <= 16) {
*(u16 *) value = inw(port);
- break;
- case 32:
+ } else if (width <= 32) {
*(u32 *) value = inl(port);
- break;
- default:
+ } else {
BUG();
}
@@ -408,17 +405,13 @@ EXPORT_SYMBOL(acpi_os_read_port);
acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width)
{
- switch (width) {
- case 8:
+ if (width <= 8) {
outb(value, port);
- break;
- case 16:
+ } else if (width <= 16) {
outw(value, port);
- break;
- case 32:
+ } else if (width <= 32) {
outl(value, port);
- break;
- default:
+ } else {
BUG();
}
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 235a51e328c..015689d295c 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -612,12 +612,6 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid)
request_region(pr->throttling.address, 6, "ACPI CPU throttle");
}
-#ifdef CONFIG_CPU_FREQ
- acpi_processor_ppc_has_changed(pr);
-#endif
- acpi_processor_get_throttling_info(pr);
- acpi_processor_get_limit_info(pr);
-
return 0;
}
@@ -647,7 +641,7 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
*/
if (processor_device_array[pr->id] != NULL &&
processor_device_array[pr->id] != device) {
- printk(KERN_WARNING "BIOS reported wrong ACPI id"
+ printk(KERN_WARNING "BIOS reported wrong ACPI id "
"for the processor\n");
return -ENODEV;
}
@@ -665,6 +659,12 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
/* _PDC call should be done before doing anything else (if reqd.). */
arch_acpi_processor_init_pdc(pr);
acpi_processor_set_pdc(pr);
+#ifdef CONFIG_CPU_FREQ
+ acpi_processor_ppc_has_changed(pr);
+#endif
+ acpi_processor_get_throttling_info(pr);
+ acpi_processor_get_limit_info(pr);
+
acpi_processor_power_init(pr, device);
@@ -684,7 +684,7 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
{
struct acpi_processor *pr = data;
struct acpi_device *device = NULL;
-
+ int saved;
if (!pr)
return;
@@ -694,7 +694,10 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
switch (event) {
case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
+ saved = pr->performance_platform_limit;
acpi_processor_ppc_has_changed(pr);
+ if (saved == pr->performance_platform_limit)
+ break;
acpi_bus_generate_proc_event(device, event,
pr->performance_platform_limit);
acpi_bus_generate_netlink_event(device->pnp.device_class,
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index f996d0e3768..7b6c20eeeaf 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -197,6 +197,19 @@ static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2)
return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2);
}
+static void acpi_safe_halt(void)
+{
+ current_thread_info()->status &= ~TS_POLLING;
+ /*
+ * TS_POLLING-cleared state must be visible before we
+ * test NEED_RESCHED:
+ */
+ smp_mb();
+ if (!need_resched())
+ safe_halt();
+ current_thread_info()->status |= TS_POLLING;
+}
+
#ifndef CONFIG_CPU_IDLE
static void
@@ -239,19 +252,6 @@ acpi_processor_power_activate(struct acpi_processor *pr,
return;
}
-static void acpi_safe_halt(void)
-{
- current_thread_info()->status &= ~TS_POLLING;
- /*
- * TS_POLLING-cleared state must be visible before we
- * test NEED_RESCHED:
- */
- smp_mb();
- if (!need_resched())
- safe_halt();
- current_thread_info()->status |= TS_POLLING;
-}
-
static atomic_t c3_cpu_count;
/* Common C-state entry for C2, C3, .. */
@@ -1373,15 +1373,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
if (pr->flags.bm_check)
acpi_idle_update_bm_rld(pr, cx);
- current_thread_info()->status &= ~TS_POLLING;
- /*
- * TS_POLLING-cleared state must be visible before we test
- * NEED_RESCHED:
- */
- smp_mb();
- if (!need_resched())
- safe_halt();
- current_thread_info()->status |= TS_POLLING;
+ acpi_safe_halt();
cx->usage++;
@@ -1399,6 +1391,8 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
struct acpi_processor *pr;
struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
u32 t1, t2;
+ int sleep_ticks = 0;
+
pr = processors[smp_processor_id()];
if (unlikely(!pr))
@@ -1428,6 +1422,8 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
ACPI_FLUSH_CPU_CACHE();
t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ /* Tell the scheduler that we are going deep-idle: */
+ sched_clock_idle_sleep_event();
acpi_state_timer_broadcast(pr, cx, 1);
acpi_idle_do_entry(cx);
t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
@@ -1436,6 +1432,10 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
/* TSC could halt in idle, so notify users */
mark_tsc_unstable("TSC halts in idle");;
#endif
+ sleep_ticks = ticks_elapsed(t1, t2);
+
+ /* Tell the scheduler how much we idled: */
+ sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
local_irq_enable();
current_thread_info()->status |= TS_POLLING;
@@ -1443,7 +1443,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
cx->usage++;
acpi_state_timer_broadcast(pr, cx, 0);
- cx->time += ticks_elapsed(t1, t2);
+ cx->time += sleep_ticks;
return ticks_elapsed_in_us(t1, t2);
}
@@ -1463,6 +1463,8 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
struct acpi_processor *pr;
struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
u32 t1, t2;
+ int sleep_ticks = 0;
+
pr = processors[smp_processor_id()];
if (unlikely(!pr))
@@ -1471,6 +1473,15 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
if (acpi_idle_suspend)
return(acpi_idle_enter_c1(dev, state));
+ if (acpi_idle_bm_check()) {
+ if (dev->safe_state) {
+ return dev->safe_state->enter(dev, dev->safe_state);
+ } else {
+ acpi_safe_halt();
+ return 0;
+ }
+ }
+
local_irq_disable();
current_thread_info()->status &= ~TS_POLLING;
/*
@@ -1485,38 +1496,45 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
return 0;
}
+ /* Tell the scheduler that we are going deep-idle: */
+ sched_clock_idle_sleep_event();
/*
* Must be done before busmaster disable as we might need to
* access HPET !
*/
acpi_state_timer_broadcast(pr, cx, 1);
- if (acpi_idle_bm_check()) {
- cx = pr->power.bm_state;
-
- acpi_idle_update_bm_rld(pr, cx);
-
- t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
- acpi_idle_do_entry(cx);
- t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
- } else {
- acpi_idle_update_bm_rld(pr, cx);
+ acpi_idle_update_bm_rld(pr, cx);
+ /*
+ * disable bus master
+ * bm_check implies we need ARB_DIS
+ * !bm_check implies we need cache flush
+ * bm_control implies whether we can do ARB_DIS
+ *
+ * That leaves a case where bm_check is set and bm_control is
+ * not set. In that case we cannot do much, we enter C3
+ * without doing anything.
+ */
+ if (pr->flags.bm_check && pr->flags.bm_control) {
spin_lock(&c3_lock);
c3_cpu_count++;
/* Disable bus master arbitration when all CPUs are in C3 */
if (c3_cpu_count == num_online_cpus())
acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
spin_unlock(&c3_lock);
+ } else if (!pr->flags.bm_check) {
+ ACPI_FLUSH_CPU_CACHE();
+ }
- t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
- acpi_idle_do_entry(cx);
- t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ acpi_idle_do_entry(cx);
+ t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ /* Re-enable bus master arbitration */
+ if (pr->flags.bm_check && pr->flags.bm_control) {
spin_lock(&c3_lock);
- /* Re-enable bus master arbitration */
- if (c3_cpu_count == num_online_cpus())
- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
+ acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
c3_cpu_count--;
spin_unlock(&c3_lock);
}
@@ -1525,6 +1543,9 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
/* TSC could halt in idle, so notify users */
mark_tsc_unstable("TSC halts in idle");
#endif
+ sleep_ticks = ticks_elapsed(t1, t2);
+ /* Tell the scheduler how much we idled: */
+ sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
local_irq_enable();
current_thread_info()->status |= TS_POLLING;
@@ -1532,7 +1553,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
cx->usage++;
acpi_state_timer_broadcast(pr, cx, 0);
- cx->time += ticks_elapsed(t1, t2);
+ cx->time += sleep_ticks;
return ticks_elapsed_in_us(t1, t2);
}
@@ -1584,12 +1605,14 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
case ACPI_STATE_C1:
state->flags |= CPUIDLE_FLAG_SHALLOW;
state->enter = acpi_idle_enter_c1;
+ dev->safe_state = state;
break;
case ACPI_STATE_C2:
state->flags |= CPUIDLE_FLAG_BALANCED;
state->flags |= CPUIDLE_FLAG_TIME_VALID;
state->enter = acpi_idle_enter_simple;
+ dev->safe_state = state;
break;
case ACPI_STATE_C3:
@@ -1610,14 +1633,6 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
if (!count)
return -EINVAL;
- /* find the deepest state that can handle active BM */
- if (pr->flags.bm_check) {
- for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++)
- if (pr->power.states[i].type == ACPI_STATE_C3)
- break;
- pr->power.bm_state = &pr->power.states[i-1];
- }
-
return 0;
}
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 0b8204e7082..c26c61fb36c 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -70,7 +70,55 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
int acpi_processor_tstate_has_changed(struct acpi_processor *pr)
{
- return acpi_processor_get_platform_limit(pr);
+ int result = 0;
+ int throttling_limit;
+ int current_state;
+ struct acpi_processor_limit *limit;
+ int target_state;
+
+ result = acpi_processor_get_platform_limit(pr);
+ if (result) {
+ /* Throttling Limit is unsupported */
+ return result;
+ }
+
+ throttling_limit = pr->throttling_platform_limit;
+ if (throttling_limit >= pr->throttling.state_count) {
+ /* Uncorrect Throttling Limit */
+ return -EINVAL;
+ }
+
+ current_state = pr->throttling.state;
+ if (current_state > throttling_limit) {
+ /*
+ * The current state can meet the requirement of
+ * _TPC limit. But it is reasonable that OSPM changes
+ * t-states from high to low for better performance.
+ * Of course the limit condition of thermal
+ * and user should be considered.
+ */
+ limit = &pr->limit;
+ target_state = throttling_limit;
+ if (limit->thermal.tx > target_state)
+ target_state = limit->thermal.tx;
+ if (limit->user.tx > target_state)
+ target_state = limit->user.tx;
+ } else if (current_state == throttling_limit) {
+ /*
+ * Unnecessary to change the throttling state
+ */
+ return 0;
+ } else {
+ /*
+ * If the current state is lower than the limit of _TPC, it
+ * will be forced to switch to the throttling state defined
+ * by throttling_platfor_limit.
+ * Because the previous state meets with the limit condition
+ * of thermal and user, it is unnecessary to check it again.
+ */
+ target_state = throttling_limit;
+ }
+ return acpi_processor_set_throttling(pr, target_state);
}
/*
@@ -83,6 +131,7 @@ static int acpi_processor_get_throttling_control(struct acpi_processor *pr)
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *ptc = NULL;
union acpi_object obj = { 0 };
+ struct acpi_processor_throttling *throttling;
status = acpi_evaluate_object(pr->handle, "_PTC", NULL, &buffer);
if (ACPI_FAILURE(status)) {
@@ -134,6 +183,22 @@ static int acpi_processor_get_throttling_control(struct acpi_processor *pr)
memcpy(&pr->throttling.status_register, obj.buffer.pointer,
sizeof(struct acpi_ptc_register));
+ throttling = &pr->throttling;
+
+ if ((throttling->control_register.bit_width +
+ throttling->control_register.bit_offset) > 32) {
+ printk(KERN_ERR PREFIX "Invalid _PTC control register\n");
+ result = -EFAULT;
+ goto end;
+ }
+
+ if ((throttling->status_register.bit_width +
+ throttling->status_register.bit_offset) > 32) {
+ printk(KERN_ERR PREFIX "Invalid _PTC status register\n");
+ result = -EFAULT;
+ goto end;
+ }
+
end:
kfree(buffer.pointer);
@@ -328,44 +393,132 @@ static int acpi_processor_get_throttling_fadt(struct acpi_processor *pr)
return 0;
}
-static int acpi_read_throttling_status(struct acpi_processor_throttling
- *throttling)
+#ifdef CONFIG_X86
+static int acpi_throttling_rdmsr(struct acpi_processor *pr,
+ acpi_integer * value)
{
- int value = -1;
+ struct cpuinfo_x86 *c;
+ u64 msr_high, msr_low;
+ unsigned int cpu;
+ u64 msr = 0;
+ int ret = -1;
+
+ cpu = pr->id;
+ c = &cpu_data(cpu);
+
+ if ((c->x86_vendor != X86_VENDOR_INTEL) ||
+ !cpu_has(c, X86_FEATURE_ACPI)) {
+ printk(KERN_ERR PREFIX
+ "HARDWARE addr space,NOT supported yet\n");
+ } else {
+ msr_low = 0;
+ msr_high = 0;
+ rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL,
+ (u32 *)&msr_low , (u32 *) &msr_high);
+ msr = (msr_high << 32) | msr_low;
+ *value = (acpi_integer) msr;
+ ret = 0;
+ }
+ return ret;
+}
+
+static int acpi_throttling_wrmsr(struct acpi_processor *pr, acpi_integer value)
+{
+ struct cpuinfo_x86 *c;
+ unsigned int cpu;
+ int ret = -1;
+ u64 msr;
+
+ cpu = pr->id;
+ c = &cpu_data(cpu);
+
+ if ((c->x86_vendor != X86_VENDOR_INTEL) ||
+ !cpu_has(c, X86_FEATURE_ACPI)) {
+ printk(KERN_ERR PREFIX
+ "HARDWARE addr space,NOT supported yet\n");
+ } else {
+ msr = value;
+ wrmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL,
+ msr & 0xffffffff, msr >> 32);
+ ret = 0;
+ }
+ return ret;
+}
+#else
+static int acpi_throttling_rdmsr(struct acpi_processor *pr,
+ acpi_integer * value)
+{
+ printk(KERN_ERR PREFIX
+ "HARDWARE addr space,NOT supported yet\n");
+ return -1;
+}
+
+static int acpi_throttling_wrmsr(struct acpi_processor *pr, acpi_integer value)
+{
+ printk(KERN_ERR PREFIX
+ "HARDWARE addr space,NOT supported yet\n");
+ return -1;
+}
+#endif
+
+static int acpi_read_throttling_status(struct acpi_processor *pr,
+ acpi_integer *value)
+{
+ u32 bit_width, bit_offset;
+ u64 ptc_value;
+ u64 ptc_mask;
+ struct acpi_processor_throttling *throttling;
+ int ret = -1;
+
+ throttling = &pr->throttling;
switch (throttling->status_register.space_id) {
case ACPI_ADR_SPACE_SYSTEM_IO:
+ ptc_value = 0;
+ bit_width = throttling->status_register.bit_width;
+ bit_offset = throttling->status_register.bit_offset;
+
acpi_os_read_port((acpi_io_address) throttling->status_register.
- address, &value,
- (u32) throttling->status_register.bit_width *
- 8);
+ address, (u32 *) &ptc_value,
+ (u32) (bit_width + bit_offset));
+ ptc_mask = (1 << bit_width) - 1;
+ *value = (acpi_integer) ((ptc_value >> bit_offset) & ptc_mask);
+ ret = 0;
break;
case ACPI_ADR_SPACE_FIXED_HARDWARE:
- printk(KERN_ERR PREFIX
- "HARDWARE addr space,NOT supported yet\n");
+ ret = acpi_throttling_rdmsr(pr, value);
break;
default:
printk(KERN_ERR PREFIX "Unknown addr space %d\n",
(u32) (throttling->status_register.space_id));
}
- return value;
+ return ret;
}
-static int acpi_write_throttling_state(struct acpi_processor_throttling
- *throttling, int value)
+static int acpi_write_throttling_state(struct acpi_processor *pr,
+ acpi_integer value)
{
+ u32 bit_width, bit_offset;
+ u64 ptc_value;
+ u64 ptc_mask;
+ struct acpi_processor_throttling *throttling;
int ret = -1;
+ throttling = &pr->throttling;
switch (throttling->control_register.space_id) {
case ACPI_ADR_SPACE_SYSTEM_IO:
+ bit_width = throttling->control_register.bit_width;
+ bit_offset = throttling->control_register.bit_offset;
+ ptc_mask = (1 << bit_width) - 1;
+ ptc_value = value & ptc_mask;
+
acpi_os_write_port((acpi_io_address) throttling->
- control_register.address, value,
- (u32) throttling->control_register.
- bit_width * 8);
+ control_register.address,
+ (u32) (ptc_value << bit_offset),
+ (u32) (bit_width + bit_offset));
ret = 0;
break;
case ACPI_ADR_SPACE_FIXED_HARDWARE:
- printk(KERN_ERR PREFIX
- "HARDWARE addr space,NOT supported yet\n");
+ ret = acpi_throttling_wrmsr(pr, value);
break;
default:
printk(KERN_ERR PREFIX "Unknown addr space %d\n",
@@ -374,7 +527,8 @@ static int acpi_write_throttling_state(struct acpi_processor_throttling
return ret;
}
-static int acpi_get_throttling_state(struct acpi_processor *pr, int value)
+static int acpi_get_throttling_state(struct acpi_processor *pr,
+ acpi_integer value)
{
int i;
@@ -390,22 +544,26 @@ static int acpi_get_throttling_state(struct acpi_processor *pr, int value)
return i;
}
-static int acpi_get_throttling_value(struct acpi_processor *pr, int state)
+static int acpi_get_throttling_value(struct acpi_processor *pr,
+ int state, acpi_integer *value)
{
- int value = -1;
+ int ret = -1;
+
if (state >= 0 && state <= pr->throttling.state_count) {
struct acpi_processor_tx_tss *tx =
(struct acpi_processor_tx_tss *)&(pr->throttling.
states_tss[state]);
- value = tx->control;
+ *value = tx->control;
+ ret = 0;
}
- return value;
+ return ret;
}
static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr)
{
int state = 0;
- u32 value = 0;
+ int ret;
+ acpi_integer value;
if (!pr)
return -EINVAL;
@@ -415,8 +573,9 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr)
pr->throttling.state = 0;
local_irq_disable();
- value = acpi_read_throttling_status(&pr->throttling);
- if (value >= 0) {
+ value = 0;
+ ret = acpi_read_throttling_status(pr, &value);
+ if (ret >= 0) {
state = acpi_get_throttling_state(pr, value);
pr->throttling.state = state;
}
@@ -430,6 +589,40 @@ static int acpi_processor_get_throttling(struct acpi_processor *pr)
return pr->throttling.acpi_processor_get_throttling(pr);
}
+static int acpi_processor_get_fadt_info(struct acpi_processor *pr)
+{
+ int i, step;
+
+ if (!pr->throttling.address) {
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n"));
+ return -EINVAL;
+ } else if (!pr->throttling.duty_width) {
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling states\n"));
+ return -EINVAL;
+ }
+ /* TBD: Support duty_cycle values that span bit 4. */
+ else if ((pr->throttling.duty_offset + pr->throttling.duty_width) > 4) {
+ printk(KERN_WARNING PREFIX "duty_cycle spans bit 4\n");
+ return -EINVAL;
+ }
+
+ pr->throttling.state_count = 1 << acpi_gbl_FADT.duty_width;
+
+ /*
+ * Compute state values. Note that throttling displays a linear power
+ * performance relationship (at 50% performance the CPU will consume
+ * 50% power). Values are in 1/10th of a percent to preserve accuracy.
+ */
+
+ step = (1000 / pr->throttling.state_count);
+
+ for (i = 0; i < pr->throttling.state_count; i++) {
+ pr->throttling.states[i].performance = 1000 - step * i;
+ pr->throttling.states[i].power = 1000 - step * i;
+ }
+ return 0;
+}
+
static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr,
int state)
{
@@ -506,7 +699,8 @@ static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr,
static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr,
int state)
{
- u32 value = 0;
+ int ret;
+ acpi_integer value;
if (!pr)
return -EINVAL;
@@ -524,10 +718,10 @@ static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr,
return -EPERM;
local_irq_disable();
-
- value = acpi_get_throttling_value(pr, state);
- if (value >= 0) {
- acpi_write_throttling_state(&pr->throttling, value);
+ value = 0;
+ ret = acpi_get_throttling_value(pr, state, &value);
+ if (ret >= 0) {
+ acpi_write_throttling_state(pr, value);
pr->throttling.state = state;
}
local_irq_enable();
@@ -543,8 +737,6 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
int acpi_processor_get_throttling_info(struct acpi_processor *pr)
{
int result = 0;
- int step = 0;
- int i = 0;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n",
@@ -563,6 +755,8 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
acpi_processor_get_throttling_states(pr) ||
acpi_processor_get_platform_limit(pr))
{
+ if (acpi_processor_get_fadt_info(pr))
+ return 0;
pr->throttling.acpi_processor_get_throttling =
&acpi_processor_get_throttling_fadt;
pr->throttling.acpi_processor_set_throttling =
@@ -576,19 +770,6 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
acpi_processor_get_tsd(pr);
- if (!pr->throttling.address) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n"));
- return 0;
- } else if (!pr->throttling.duty_width) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling states\n"));
- return 0;
- }
- /* TBD: Support duty_cycle values that span bit 4. */
- else if ((pr->throttling.duty_offset + pr->throttling.duty_width) > 4) {
- printk(KERN_WARNING PREFIX "duty_cycle spans bit 4\n");
- return 0;
- }
-
/*
* PIIX4 Errata: We don't support throttling on the original PIIX4.
* This shouldn't be an issue as few (if any) mobile systems ever
@@ -600,21 +781,6 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
return 0;
}
- pr->throttling.state_count = 1 << acpi_gbl_FADT.duty_width;
-
- /*
- * Compute state values. Note that throttling displays a linear power/
- * performance relationship (at 50% performance the CPU will consume
- * 50% power). Values are in 1/10th of a percent to preserve accuracy.
- */
-
- step = (1000 / pr->throttling.state_count);
-
- for (i = 0; i < pr->throttling.state_count; i++) {
- pr->throttling.states[i].performance = step * i;
- pr->throttling.states[i].power = step * i;
- }
-
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d throttling states\n",
pr->throttling.state_count));
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 90fd09c65f9..6045cdbe176 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -29,7 +29,7 @@
#include <linux/moduleparam.h>
#include <linux/kernel.h>
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h>
@@ -88,7 +88,7 @@ MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
struct acpi_battery {
struct power_supply bat;
struct acpi_sbs *sbs;
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
struct proc_dir_entry *proc_entry;
#endif
unsigned long update_time;
@@ -113,6 +113,7 @@ struct acpi_battery {
u16 spec;
u8 id;
u8 present:1;
+ u8 have_sysfs_alarm:1;
};
#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
@@ -122,7 +123,7 @@ struct acpi_sbs {
struct acpi_device *device;
struct acpi_smb_hc *hc;
struct mutex lock;
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
struct proc_dir_entry *charger_entry;
#endif
struct acpi_battery battery[MAX_SBS_BAT];
@@ -468,7 +469,7 @@ static struct device_attribute alarm_attr = {
FS Interface (/proc/acpi)
-------------------------------------------------------------------------- */
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
/* Generic Routines */
static int
acpi_sbs_add_fs(struct proc_dir_entry **dir,
@@ -789,7 +790,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
return result;
sprintf(battery->name, ACPI_BATTERY_DIR_NAME, id);
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_sbs_add_fs(&battery->proc_entry, acpi_battery_dir,
battery->name, &acpi_battery_info_fops,
&acpi_battery_state_fops, &acpi_battery_alarm_fops,
@@ -808,7 +809,13 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
}
battery->bat.get_property = acpi_sbs_battery_get_property;
result = power_supply_register(&sbs->device->dev, &battery->bat);
- device_create_file(battery->bat.dev, &alarm_attr);
+ if (result)
+ goto end;
+ result = device_create_file(battery->bat.dev, &alarm_attr);
+ if (result)
+ goto end;
+ battery->have_sysfs_alarm = 1;
+ end:
printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",
ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
battery->name, sbs->battery->present ? "present" : "absent");
@@ -817,14 +824,16 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
{
- if (sbs->battery[id].bat.dev)
- device_remove_file(sbs->battery[id].bat.dev, &alarm_attr);
- power_supply_unregister(&sbs->battery[id].bat);
-#ifdef CONFIG_ACPI_PROCFS
- if (sbs->battery[id].proc_entry) {
- acpi_sbs_remove_fs(&(sbs->battery[id].proc_entry),
- acpi_battery_dir);
+ struct acpi_battery *battery = &sbs->battery[id];
+
+ if (battery->bat.dev) {
+ if (battery->have_sysfs_alarm)
+ device_remove_file(battery->bat.dev, &alarm_attr);
+ power_supply_unregister(&battery->bat);
}
+#ifdef CONFIG_ACPI_PROCFS_POWER
+ if (battery->proc_entry)
+ acpi_sbs_remove_fs(&battery->proc_entry, acpi_battery_dir);
#endif
}
@@ -835,7 +844,7 @@ static int acpi_charger_add(struct acpi_sbs *sbs)
result = acpi_ac_get_present(sbs);
if (result)
goto end;
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
result = acpi_sbs_add_fs(&sbs->charger_entry, acpi_ac_dir,
ACPI_AC_DIR_NAME, NULL,
&acpi_ac_state_fops, NULL, sbs);
@@ -859,7 +868,7 @@ static void acpi_charger_remove(struct acpi_sbs *sbs)
{
if (sbs->charger.dev)
power_supply_unregister(&sbs->charger);
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
if (sbs->charger_entry)
acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir);
#endif
@@ -965,7 +974,7 @@ static int acpi_sbs_remove(struct acpi_device *device, int type)
static void acpi_sbs_rmdirs(void)
{
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
if (acpi_ac_dir) {
acpi_unlock_ac_dir(acpi_ac_dir);
acpi_ac_dir = NULL;
@@ -1004,7 +1013,7 @@ static int __init acpi_sbs_init(void)
if (acpi_disabled)
return -ENODEV;
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_ac_dir = acpi_lock_ac_dir();
if (!acpi_ac_dir)
return -ENODEV;
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
index 5f1d85f2ffe..010f19652f8 100644
--- a/drivers/acpi/tables/tbutils.c
+++ b/drivers/acpi/tables/tbutils.c
@@ -449,7 +449,7 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
/* XSDT has NULL entry, RSDT is used */
address = rsdt_address;
table_entry_size = sizeof(u32);
- ACPI_WARNING((AE_INFO, "BIOS XSDT has NULL entry,"
+ ACPI_WARNING((AE_INFO, "BIOS XSDT has NULL entry, "
"using RSDT"));
}
}
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index bac956b30c5..44a0d9ba9bd 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -29,6 +29,7 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/list.h>
+#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/input.h>
@@ -135,8 +136,8 @@ struct acpi_video_bus {
u8 attached_count;
struct acpi_video_bus_cap cap;
struct acpi_video_bus_flags flags;
- struct semaphore sem;
struct list_head video_device_list;
+ struct mutex device_list_lock; /* protects video_device_list */
struct proc_dir_entry *dir;
struct input_dev *input;
char phys[32]; /* for input device */
@@ -896,7 +897,7 @@ acpi_video_device_write_brightness(struct file *file,
{
struct seq_file *m = file->private_data;
struct acpi_video_device *dev = m->private;
- char str[4] = { 0 };
+ char str[5] = { 0 };
unsigned int level = 0;
int i;
@@ -1436,9 +1437,9 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
return -ENODEV;
}
- down(&video->sem);
+ mutex_lock(&video->device_list_lock);
list_add_tail(&data->entry, &video->video_device_list);
- up(&video->sem);
+ mutex_unlock(&video->device_list_lock);
acpi_video_device_add_fs(device);
@@ -1462,12 +1463,14 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
static void acpi_video_device_rebind(struct acpi_video_bus *video)
{
- struct list_head *node, *next;
- list_for_each_safe(node, next, &video->video_device_list) {
- struct acpi_video_device *dev =
- container_of(node, struct acpi_video_device, entry);
+ struct acpi_video_device *dev;
+
+ mutex_lock(&video->device_list_lock);
+
+ list_for_each_entry(dev, &video->video_device_list, entry)
acpi_video_device_bind(video, dev);
- }
+
+ mutex_unlock(&video->device_list_lock);
}
/*
@@ -1592,30 +1595,33 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
static int acpi_video_switch_output(struct acpi_video_bus *video, int event)
{
- struct list_head *node, *next;
+ struct list_head *node;
struct acpi_video_device *dev = NULL;
struct acpi_video_device *dev_next = NULL;
struct acpi_video_device *dev_prev = NULL;
unsigned long state;
int status = 0;
+ mutex_lock(&video->device_list_lock);
- list_for_each_safe(node, next, &video->video_device_list) {
+ list_for_each(node, &video->video_device_list) {
dev = container_of(node, struct acpi_video_device, entry);
status = acpi_video_device_get_state(dev, &state);
if (state & 0x2) {
- dev_next =
- container_of(node->next, struct acpi_video_device,
- entry);
- dev_prev =
- container_of(node->prev, struct acpi_video_device,
- entry);
+ dev_next = container_of(node->next,
+ struct acpi_video_device, entry);
+ dev_prev = container_of(node->prev,
+ struct acpi_video_device, entry);
goto out;
}
}
+
dev_next = container_of(node->next, struct acpi_video_device, entry);
dev_prev = container_of(node->prev, struct acpi_video_device, entry);
- out:
+
+ out:
+ mutex_unlock(&video->device_list_lock);
+
switch (event) {
case ACPI_VIDEO_NOTIFY_CYCLE:
case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT:
@@ -1691,24 +1697,17 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video,
struct acpi_device *device)
{
int status = 0;
- struct list_head *node, *next;
-
+ struct acpi_device *dev;
acpi_video_device_enumerate(video);
- list_for_each_safe(node, next, &device->children) {
- struct acpi_device *dev =
- list_entry(node, struct acpi_device, node);
-
- if (!dev)
- continue;
+ list_for_each_entry(dev, &device->children, node) {
status = acpi_video_bus_get_one_device(dev, video);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, "Cant attach device"));
continue;
}
-
}
return status;
}
@@ -1724,9 +1723,6 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
video = device->video;
- down(&video->sem);
- list_del(&device->entry);
- up(&video->sem);
acpi_video_device_remove_fs(device->dev);
status = acpi_remove_notify_handler(device->dev->handle,
@@ -1734,32 +1730,34 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
acpi_video_device_notify);
backlight_device_unregister(device->backlight);
video_output_unregister(device->output_dev);
+
return 0;
}
static int acpi_video_bus_put_devices(struct acpi_video_bus *video)
{
int status;
- struct list_head *node, *next;
+ struct acpi_video_device *dev, *next;
+ mutex_lock(&video->device_list_lock);
- list_for_each_safe(node, next, &video->video_device_list) {
- struct acpi_video_device *data =
- list_entry(node, struct acpi_video_device, entry);
- if (!data)
- continue;
+ list_for_each_entry_safe(dev, next, &video->video_device_list, entry) {
- status = acpi_video_bus_put_one_device(data);
+ status = acpi_video_bus_put_one_device(dev);
if (ACPI_FAILURE(status))
printk(KERN_WARNING PREFIX
"hhuuhhuu bug in acpi video driver.\n");
- if (data->brightness)
- kfree(data->brightness->levels);
- kfree(data->brightness);
- kfree(data);
+ if (dev->brightness) {
+ kfree(dev->brightness->levels);
+ kfree(dev->brightness);
+ }
+ list_del(&dev->entry);
+ kfree(dev);
}
+ mutex_unlock(&video->device_list_lock);
+
return 0;
}
@@ -1782,9 +1780,6 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
struct input_dev *input;
int keycode;
-
- printk("video bus notify\n");
-
if (!video)
return;
@@ -1897,14 +1892,10 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
static int instance;
static int acpi_video_bus_add(struct acpi_device *device)
{
- int result = 0;
- acpi_status status = 0;
- struct acpi_video_bus *video = NULL;
+ acpi_status status;
+ struct acpi_video_bus *video;
struct input_dev *input;
-
-
- if (!device)
- return -EINVAL;
+ int error;
video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL);
if (!video)
@@ -1923,15 +1914,15 @@ static int acpi_video_bus_add(struct acpi_device *device)
acpi_driver_data(device) = video;
acpi_video_bus_find_cap(video);
- result = acpi_video_bus_check(video);
- if (result)
- goto end;
+ error = acpi_video_bus_check(video);
+ if (error)
+ goto err_free_video;
- result = acpi_video_bus_add_fs(device);
- if (result)
- goto end;
+ error = acpi_video_bus_add_fs(device);
+ if (error)
+ goto err_free_video;
- init_MUTEX(&video->sem);
+ mutex_init(&video->device_list_lock);
INIT_LIST_HEAD(&video->video_device_list);
acpi_video_bus_get_devices(video, device);
@@ -1943,16 +1934,15 @@ static int acpi_video_bus_add(struct acpi_device *device)
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Error installing notify handler\n"));
- acpi_video_bus_stop_devices(video);
- acpi_video_bus_put_devices(video);
- kfree(video->attached_array);
- acpi_video_bus_remove_fs(device);
- result = -ENODEV;
- goto end;
+ error = -ENODEV;
+ goto err_stop_video;
}
-
video->input = input = input_allocate_device();
+ if (!input) {
+ error = -ENOMEM;
+ goto err_uninstall_notify;
+ }
snprintf(video->phys, sizeof(video->phys),
"%s/video/input0", acpi_device_hid(video->device));
@@ -1961,6 +1951,7 @@ static int acpi_video_bus_add(struct acpi_device *device)
input->phys = video->phys;
input->id.bustype = BUS_HOST;
input->id.product = 0x06;
+ input->dev.parent = &device->dev;
input->evbit[0] = BIT(EV_KEY);
set_bit(KEY_SWITCHVIDEOMODE, input->keybit);
set_bit(KEY_VIDEO_NEXT, input->keybit);
@@ -1971,18 +1962,10 @@ static int acpi_video_bus_add(struct acpi_device *device)
set_bit(KEY_BRIGHTNESS_ZERO, input->keybit);
set_bit(KEY_DISPLAY_OFF, input->keybit);
set_bit(KEY_UNKNOWN, input->keybit);
- result = input_register_device(input);
- if (result) {
- acpi_remove_notify_handler(video->device->handle,
- ACPI_DEVICE_NOTIFY,
- acpi_video_bus_notify);
- acpi_video_bus_stop_devices(video);
- acpi_video_bus_put_devices(video);
- kfree(video->attached_array);
- acpi_video_bus_remove_fs(device);
- goto end;
- }
+ error = input_register_device(input);
+ if (error)
+ goto err_free_input_dev;
printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n",
ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
@@ -1990,11 +1973,23 @@ static int acpi_video_bus_add(struct acpi_device *device)
video->flags.rom ? "yes" : "no",
video->flags.post ? "yes" : "no");
- end:
- if (result)
- kfree(video);
+ return 0;
+
+ err_free_input_dev:
+ input_free_device(input);
+ err_uninstall_notify:
+ acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
+ acpi_video_bus_notify);
+ err_stop_video:
+ acpi_video_bus_stop_devices(video);
+ acpi_video_bus_put_devices(video);
+ kfree(video->attached_array);
+ acpi_video_bus_remove_fs(device);
+ err_free_video:
+ kfree(video);
+ acpi_driver_data(device) = NULL;
- return result;
+ return error;
}
static int acpi_video_bus_remove(struct acpi_device *device, int type)
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index b39d1f5b378..ced83c202ca 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -2104,7 +2104,7 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
u_long flags;
isdn_net_dev *p;
isdn_net_phone *n;
- char nr[32];
+ char nr[ISDN_MSNLEN];
char *my_eaz;
/* Search name in netdev-chain */
@@ -2113,7 +2113,7 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
nr[1] = '\0';
printk(KERN_INFO "isdn_net: Incoming call without OAD, assuming '0'\n");
} else
- strcpy(nr, setup->phone);
+ strlcpy(nr, setup->phone, ISDN_MSNLEN);
si1 = (int) setup->si1;
si2 = (int) setup->si2;
if (!setup->eazmsn[0]) {
@@ -2789,7 +2789,7 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
chidx = -1;
}
}
- strcpy(lp->msn, cfg->eaz);
+ strlcpy(lp->msn, cfg->eaz, sizeof(lp->msn));
lp->pre_device = drvidx;
lp->pre_channel = chidx;
lp->onhtime = cfg->onhtime;
@@ -2936,7 +2936,7 @@ isdn_net_addphone(isdn_net_ioctl_phone * phone)
if (p) {
if (!(n = kmalloc(sizeof(isdn_net_phone), GFP_KERNEL)))
return -ENOMEM;
- strcpy(n->num, phone->phone);
+ strlcpy(n->num, phone->phone, sizeof(n->num));
n->next = p->local->phone[phone->outgoing & 1];
p->local->phone[phone->outgoing & 1] = n;
return 0;
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index e953276664a..ab23a322158 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -21,7 +21,7 @@
* 02110-1301, USA.
*/
-#define IBM_VERSION "0.16"
+#define IBM_VERSION "0.17"
#define TPACPI_SYSFS_VERSION 0x020000
/*
@@ -964,15 +964,15 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */
KEY_UNKNOWN, /* 0x0D: FN+INSERT */
KEY_UNKNOWN, /* 0x0E: FN+DELETE */
- KEY_BRIGHTNESSUP, /* 0x0F: FN+HOME (brightness up) */
+ KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */
/* Scan codes 0x10 to 0x1F: Extended ACPI HKEY hot keys */
- KEY_BRIGHTNESSDOWN, /* 0x10: FN+END (brightness down) */
+ KEY_RESERVED, /* 0x10: FN+END (brightness down) */
KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */
KEY_UNKNOWN, /* 0x12: FN+PGDOWN */
KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */
- KEY_VOLUMEUP, /* 0x14: VOLUME UP */
- KEY_VOLUMEDOWN, /* 0x15: VOLUME DOWN */
- KEY_MUTE, /* 0x16: MUTE */
+ KEY_RESERVED, /* 0x14: VOLUME UP */
+ KEY_RESERVED, /* 0x15: VOLUME DOWN */
+ KEY_RESERVED, /* 0x16: MUTE */
KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */
/* (assignments unknown, please report if found) */
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
@@ -993,9 +993,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */
KEY_UNKNOWN, /* 0x12: FN+PGDOWN */
KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */
- KEY_VOLUMEUP, /* 0x14: VOLUME UP */
- KEY_VOLUMEDOWN, /* 0x15: VOLUME DOWN */
- KEY_MUTE, /* 0x16: MUTE */
+ KEY_RESERVED, /* 0x14: VOLUME UP */
+ KEY_RESERVED, /* 0x15: VOLUME DOWN */
+ KEY_RESERVED, /* 0x16: MUTE */
KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */
/* (assignments unknown, please report if found) */
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
@@ -1342,9 +1342,8 @@ static int hotkey_read(char *p)
return len;
}
- res = mutex_lock_interruptible(&hotkey_mutex);
- if (res < 0)
- return res;
+ if (mutex_lock_interruptible(&hotkey_mutex))
+ return -ERESTARTSYS;
res = hotkey_get(&status, &mask);
mutex_unlock(&hotkey_mutex);
if (res)
@@ -1373,9 +1372,8 @@ static int hotkey_write(char *buf)
if (!tp_features.hotkey)
return -ENODEV;
- res = mutex_lock_interruptible(&hotkey_mutex);
- if (res < 0)
- return res;
+ if (mutex_lock_interruptible(&hotkey_mutex))
+ return -ERESTARTSYS;
res = hotkey_get(&status, &mask);
if (res)
@@ -3114,6 +3112,99 @@ static struct backlight_ops ibm_backlight_data = {
static struct mutex brightness_mutex;
+static int __init tpacpi_query_bcll_levels(acpi_handle handle)
+{
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
+ int rc;
+
+ if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) {
+ obj = (union acpi_object *)buffer.pointer;
+ if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
+ printk(IBM_ERR "Unknown BCLL data, "
+ "please report this to %s\n", IBM_MAIL);
+ rc = 0;
+ } else {
+ rc = obj->package.count;
+ }
+ } else {
+ return 0;
+ }
+
+ kfree(buffer.pointer);
+ return rc;
+}
+
+static acpi_status __init brightness_find_bcll(acpi_handle handle, u32 lvl,
+ void *context, void **rv)
+{
+ char name[ACPI_PATH_SEGMENT_LENGTH];
+ struct acpi_buffer buffer = { sizeof(name), &name };
+
+ if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
+ !strncmp("BCLL", name, sizeof(name) - 1)) {
+ if (tpacpi_query_bcll_levels(handle) == 16) {
+ *rv = handle;
+ return AE_CTRL_TERMINATE;
+ } else {
+ return AE_OK;
+ }
+ } else {
+ return AE_OK;
+ }
+}
+
+static int __init brightness_check_levels(void)
+{
+ int status;
+ void *found_node = NULL;
+
+ if (!vid_handle) {
+ IBM_ACPIHANDLE_INIT(vid);
+ }
+ if (!vid_handle)
+ return 0;
+
+ /* Search for a BCLL package with 16 levels */
+ status = acpi_walk_namespace(ACPI_TYPE_PACKAGE, vid_handle, 3,
+ brightness_find_bcll, NULL, &found_node);
+
+ return (ACPI_SUCCESS(status) && found_node != NULL);
+}
+
+static acpi_status __init brightness_find_bcl(acpi_handle handle, u32 lvl,
+ void *context, void **rv)
+{
+ char name[ACPI_PATH_SEGMENT_LENGTH];
+ struct acpi_buffer buffer = { sizeof(name), &name };
+
+ if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
+ !strncmp("_BCL", name, sizeof(name) - 1)) {
+ *rv = handle;
+ return AE_CTRL_TERMINATE;
+ } else {
+ return AE_OK;
+ }
+}
+
+static int __init brightness_check_std_acpi_support(void)
+{
+ int status;
+ void *found_node = NULL;
+
+ if (!vid_handle) {
+ IBM_ACPIHANDLE_INIT(vid);
+ }
+ if (!vid_handle)
+ return 0;
+
+ /* Search for a _BCL method, but don't execute it */
+ status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3,
+ brightness_find_bcl, NULL, &found_node);
+
+ return (ACPI_SUCCESS(status) && found_node != NULL);
+}
+
static int __init brightness_init(struct ibm_init_struct *iibm)
{
int b;
@@ -3122,6 +3213,18 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
mutex_init(&brightness_mutex);
+ if (!brightness_enable) {
+ dbg_printk(TPACPI_DBG_INIT,
+ "brightness support disabled by module parameter\n");
+ return 1;
+ } else if (brightness_enable > 1) {
+ if (brightness_check_std_acpi_support()) {
+ printk(IBM_NOTICE
+ "standard ACPI backlight interface available, not loading native one...\n");
+ return 1;
+ }
+ }
+
if (!brightness_mode) {
if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO)
brightness_mode = 2;
@@ -3135,10 +3238,17 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
if (brightness_mode > 3)
return -EINVAL;
+ tp_features.bright_16levels =
+ thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO &&
+ brightness_check_levels();
+
b = brightness_get(NULL);
if (b < 0)
return 1;
+ if (tp_features.bright_16levels)
+ printk(IBM_INFO "detected a 16-level brightness capable ThinkPad\n");
+
ibm_backlight_device = backlight_device_register(
TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL,
&ibm_backlight_data);
@@ -3148,7 +3258,8 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
}
vdbg_printk(TPACPI_DBG_INIT, "brightness is supported\n");
- ibm_backlight_device->props.max_brightness = 7;
+ ibm_backlight_device->props.max_brightness =
+ (tp_features.bright_16levels)? 15 : 7;
ibm_backlight_device->props.brightness = b;
backlight_update_status(ibm_backlight_device);
@@ -3167,6 +3278,8 @@ static void brightness_exit(void)
static int brightness_update_status(struct backlight_device *bd)
{
+ /* it is the backlight class's job (caller) to handle
+ * EINTR and other errors properly */
return brightness_set(
(bd->props.fb_blank == FB_BLANK_UNBLANK &&
bd->props.power == FB_BLANK_UNBLANK) ?
@@ -3184,13 +3297,14 @@ static int brightness_get(struct backlight_device *bd)
if (brightness_mode & 1) {
if (!acpi_ec_read(brightness_offset, &lec))
return -EIO;
- lec &= 7;
+ lec &= (tp_features.bright_16levels)? 0x0f : 0x07;
level = lec;
};
if (brightness_mode & 2) {
lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
& TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
>> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
+ lcmos &= (tp_features.bright_16levels)? 0x0f : 0x07;
level = lcmos;
}
@@ -3206,12 +3320,13 @@ static int brightness_get(struct backlight_device *bd)
return level;
}
+/* May return EINTR which can always be mapped to ERESTARTSYS */
static int brightness_set(int value)
{
int cmos_cmd, inc, i, res;
int current_value;
- if (value > 7)
+ if (value > ((tp_features.bright_16levels)? 15 : 7))
return -EINVAL;
res = mutex_lock_interruptible(&brightness_mutex);
@@ -3227,7 +3342,7 @@ static int brightness_set(int value)
cmos_cmd = value > current_value ?
TP_CMOS_BRIGHTNESS_UP :
TP_CMOS_BRIGHTNESS_DOWN;
- inc = value > current_value ? 1 : -1;
+ inc = (value > current_value)? 1 : -1;
res = 0;
for (i = current_value; i != value; i += inc) {
@@ -3256,10 +3371,11 @@ static int brightness_read(char *p)
if ((level = brightness_get(NULL)) < 0) {
len += sprintf(p + len, "level:\t\tunreadable\n");
} else {
- len += sprintf(p + len, "level:\t\t%d\n", level & 0x7);
+ len += sprintf(p + len, "level:\t\t%d\n", level);
len += sprintf(p + len, "commands:\tup, down\n");
len += sprintf(p + len, "commands:\tlevel <level>"
- " (<level> is 0-7)\n");
+ " (<level> is 0-%d)\n",
+ (tp_features.bright_16levels) ? 15 : 7);
}
return len;
@@ -3268,28 +3384,34 @@ static int brightness_read(char *p)
static int brightness_write(char *buf)
{
int level;
- int new_level;
+ int rc;
char *cmd;
+ int max_level = (tp_features.bright_16levels) ? 15 : 7;
- while ((cmd = next_cmd(&buf))) {
- if ((level = brightness_get(NULL)) < 0)
- return level;
- level &= 7;
+ level = brightness_get(NULL);
+ if (level < 0)
+ return level;
+ while ((cmd = next_cmd(&buf))) {
if (strlencmp(cmd, "up") == 0) {
- new_level = level == 7 ? 7 : level + 1;
+ if (level < max_level)
+ level++;
} else if (strlencmp(cmd, "down") == 0) {
- new_level = level == 0 ? 0 : level - 1;
- } else if (sscanf(cmd, "level %d", &new_level) == 1 &&
- new_level >= 0 && new_level <= 7) {
- /* new_level set */
+ if (level > 0)
+ level--;
+ } else if (sscanf(cmd, "level %d", &level) == 1 &&
+ level >= 0 && level <= max_level) {
+ /* new level set */
} else
return -EINVAL;
-
- brightness_set(new_level);
}
- return 0;
+ /*
+ * Now we know what the final level should be, so we try to set it.
+ * Doing it this way makes the syscall restartable in case of EINTR
+ */
+ rc = brightness_set(level);
+ return (rc == -EINTR)? ERESTARTSYS : rc;
}
static struct ibm_struct brightness_driver_data = {
@@ -3652,9 +3774,8 @@ static ssize_t fan_pwm1_store(struct device *dev,
/* scale down from 0-255 to 0-7 */
newlevel = (s >> 5) & 0x07;
- rc = mutex_lock_interruptible(&fan_mutex);
- if (rc < 0)
- return rc;
+ if (mutex_lock_interruptible(&fan_mutex))
+ return -ERESTARTSYS;
rc = fan_get_status(&status);
if (!rc && (status &
@@ -3904,9 +4025,8 @@ static int fan_get_status_safe(u8 *status)
int rc;
u8 s;
- rc = mutex_lock_interruptible(&fan_mutex);
- if (rc < 0)
- return rc;
+ if (mutex_lock_interruptible(&fan_mutex))
+ return -ERESTARTSYS;
rc = fan_get_status(&s);
if (!rc)
fan_update_desired_level(s);
@@ -4040,9 +4160,8 @@ static int fan_set_level_safe(int level)
if (!fan_control_allowed)
return -EPERM;
- rc = mutex_lock_interruptible(&fan_mutex);
- if (rc < 0)
- return rc;
+ if (mutex_lock_interruptible(&fan_mutex))
+ return -ERESTARTSYS;
if (level == TPACPI_FAN_LAST_LEVEL)
level = fan_control_desired_level;
@@ -4063,9 +4182,8 @@ static int fan_set_enable(void)
if (!fan_control_allowed)
return -EPERM;
- rc = mutex_lock_interruptible(&fan_mutex);
- if (rc < 0)
- return rc;
+ if (mutex_lock_interruptible(&fan_mutex))
+ return -ERESTARTSYS;
switch (fan_control_access_mode) {
case TPACPI_FAN_WR_ACPI_FANS:
@@ -4119,9 +4237,8 @@ static int fan_set_disable(void)
if (!fan_control_allowed)
return -EPERM;
- rc = mutex_lock_interruptible(&fan_mutex);
- if (rc < 0)
- return rc;
+ if (mutex_lock_interruptible(&fan_mutex))
+ return -ERESTARTSYS;
rc = 0;
switch (fan_control_access_mode) {
@@ -4158,9 +4275,8 @@ static int fan_set_speed(int speed)
if (!fan_control_allowed)
return -EPERM;
- rc = mutex_lock_interruptible(&fan_mutex);
- if (rc < 0)
- return rc;
+ if (mutex_lock_interruptible(&fan_mutex))
+ return -ERESTARTSYS;
rc = 0;
switch (fan_control_access_mode) {
@@ -4701,9 +4817,15 @@ static int __init set_ibm_param(const char *val, struct kernel_param *kp)
unsigned int i;
struct ibm_struct *ibm;
+ if (!kp || !kp->name || !val)
+ return -EINVAL;
+
for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
ibm = ibms_init[i].data;
- BUG_ON(ibm == NULL);
+ WARN_ON(ibm == NULL);
+
+ if (!ibm || !ibm->name)
+ continue;
if (strcmp(ibm->name, kp->name) == 0 && ibm->write) {
if (strlen(val) > sizeof(ibms_init[i].param) - 2)
@@ -4732,6 +4854,9 @@ module_param_named(fan_control, fan_control_allowed, bool, 0);
static int brightness_mode;
module_param_named(brightness_mode, brightness_mode, int, 0);
+static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */
+module_param(brightness_enable, uint, 0);
+
static unsigned int hotkey_report_mode;
module_param(hotkey_report_mode, uint, 0);
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 3abcc812063..8fba2bbe345 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -84,7 +84,7 @@
/* ThinkPad CMOS NVRAM constants */
#define TP_NVRAM_ADDR_BRIGHTNESS 0x5e
-#define TP_NVRAM_MASK_LEVEL_BRIGHTNESS 0x07
+#define TP_NVRAM_MASK_LEVEL_BRIGHTNESS 0x0f
#define TP_NVRAM_POS_LEVEL_BRIGHTNESS 0
#define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off")
@@ -246,6 +246,7 @@ static struct {
u32 hotkey_wlsw:1;
u32 light:1;
u32 light_status:1;
+ u32 bright_16levels:1;
u32 wan:1;
u32 fan_ctrl_status_undef:1;
u32 input_device_registered:1;
@@ -338,6 +339,7 @@ static int bluetooth_write(char *buf);
static struct backlight_device *ibm_backlight_device;
static int brightness_offset = 0x31;
static int brightness_mode;
+static unsigned int brightness_enable; /* 0 = no, 1 = yes, 2 = auto */
static int brightness_init(struct ibm_init_struct *iibm);
static void brightness_exit(void);
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index cd0a204d96d..11adab13f2b 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -75,6 +75,7 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res,
{
int i = 0;
int irq;
+ int p, t;
if (!valid_IRQ(gsi))
return;
@@ -85,15 +86,22 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res,
if (i >= PNP_MAX_IRQ)
return;
-#ifdef CONFIG_X86
- if (gsi < 16 && (triggering != ACPI_EDGE_SENSITIVE ||
- polarity != ACPI_ACTIVE_HIGH)) {
- pnp_warn("BIOS BUG: legacy PNP IRQ %d should be edge trigger, "
- "active high", gsi);
- triggering = ACPI_EDGE_SENSITIVE;
- polarity = ACPI_ACTIVE_HIGH;
+ /*
+ * in IO-APIC mode, use overrided attribute. Two reasons:
+ * 1. BIOS bug in DSDT
+ * 2. BIOS uses IO-APIC mode Interrupt Source Override
+ */
+ if (!acpi_get_override_irq(gsi, &t, &p)) {
+ t = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
+ p = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
+
+ if (triggering != t || polarity != p) {
+ pnp_warn("IRQ %d override to %s, %s",
+ gsi, t ? "edge":"level", p ? "low":"high");
+ triggering = t;
+ polarity = p;
+ }
}
-#endif
res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag
res->irq_resource[i].flags |= irq_flags(triggering, polarity);
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 838f7ac0dc3..6db31089d2d 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -483,7 +483,7 @@ static DECLARE_WORK(css_reprobe_work, reprobe_all);
void css_schedule_reprobe(void)
{
need_reprobe = 1;
- queue_work(ccw_device_work, &css_reprobe_work);
+ queue_work(slow_path_wq, &css_reprobe_work);
}
EXPORT_SYMBOL_GPL(css_schedule_reprobe);
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 8867443b806..bfad421cda6 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -1034,7 +1034,7 @@ device_trigger_reprobe(struct subchannel *sch)
if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) {
PREPARE_WORK(&cdev->private->kick_work,
ccw_device_move_to_orphanage);
- queue_work(ccw_device_work, &cdev->private->kick_work);
+ queue_work(slow_path_wq, &cdev->private->kick_work);
} else
ccw_device_start_id(cdev, 0);
}
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c
index f232832f2b2..2f6bf462425 100644
--- a/drivers/s390/cio/device_id.c
+++ b/drivers/s390/cio/device_id.c
@@ -113,19 +113,10 @@ __ccw_device_sense_id_start(struct ccw_device *cdev)
{
struct subchannel *sch;
struct ccw1 *ccw;
- int ret;
sch = to_subchannel(cdev->dev.parent);
/* Setup sense channel program. */
ccw = cdev->private->iccws;
- if (sch->schib.pmcw.pim != 0x80) {
- /* more than one path installed. */
- ccw->cmd_code = CCW_CMD_SUSPEND_RECONN;
- ccw->cda = 0;
- ccw->count = 0;
- ccw->flags = CCW_FLAG_SLI | CCW_FLAG_CC;
- ccw++;
- }
ccw->cmd_code = CCW_CMD_SENSE_ID;
ccw->cda = (__u32) __pa (&cdev->private->senseid);
ccw->count = sizeof (struct senseid);
@@ -133,25 +124,9 @@ __ccw_device_sense_id_start(struct ccw_device *cdev)
/* Reset device status. */
memset(&cdev->private->irb, 0, sizeof(struct irb));
+ cdev->private->flags.intretry = 0;
- /* Try on every path. */
- ret = -ENODEV;
- while (cdev->private->imask != 0) {
- if ((sch->opm & cdev->private->imask) != 0 &&
- cdev->private->iretry > 0) {
- cdev->private->iretry--;
- /* Reset internal retry indication. */
- cdev->private->flags.intretry = 0;
- ret = cio_start (sch, cdev->private->iccws,
- cdev->private->imask);
- /* ret is 0, -EBUSY, -EACCES or -ENODEV */
- if (ret != -EACCES)
- return ret;
- }
- cdev->private->imask >>= 1;
- cdev->private->iretry = 5;
- }
- return ret;
+ return cio_start(sch, ccw, LPM_ANYPATH);
}
void
@@ -161,8 +136,7 @@ ccw_device_sense_id_start(struct ccw_device *cdev)
memset (&cdev->private->senseid, 0, sizeof (struct senseid));
cdev->private->senseid.cu_type = 0xFFFF;
- cdev->private->imask = 0x80;
- cdev->private->iretry = 5;
+ cdev->private->iretry = 3;
ret = __ccw_device_sense_id_start(cdev);
if (ret && ret != -EBUSY)
ccw_device_sense_id_done(cdev, ret);
@@ -278,14 +252,13 @@ ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event)
ccw_device_sense_id_done(cdev, ret);
break;
case -EACCES: /* channel is not operational. */
- sch->lpm &= ~cdev->private->imask;
- cdev->private->imask >>= 1;
- cdev->private->iretry = 5;
- /* fall through. */
case -EAGAIN: /* try again. */
- ret = __ccw_device_sense_id_start(cdev);
- if (ret == 0 || ret == -EBUSY)
- break;
+ cdev->private->iretry--;
+ if (cdev->private->iretry > 0) {
+ ret = __ccw_device_sense_id_start(cdev);
+ if (ret == 0 || ret == -EBUSY)
+ break;
+ }
/* fall through. */
default: /* Sense ID failed. Try asking VM. */
if (MACHINE_IS_VM) {
diff --git a/drivers/zorro/zorro-driver.c b/drivers/zorro/zorro-driver.c
index 067c07be928..e6c4390d8bd 100644
--- a/drivers/zorro/zorro-driver.c
+++ b/drivers/zorro/zorro-driver.c
@@ -60,6 +60,20 @@ static int zorro_device_probe(struct device *dev)
}
+static int zorro_device_remove(struct device *dev)
+{
+ struct zorro_dev *z = to_zorro_dev(dev);
+ struct zorro_driver *drv = to_zorro_driver(dev->driver);
+
+ if (drv) {
+ if (drv->remove)
+ drv->remove(z);
+ z->driver = NULL;
+ }
+ return 0;
+}
+
+
/**
* zorro_register_driver - register a new Zorro driver
* @drv: the driver structure to register
@@ -128,6 +142,7 @@ struct bus_type zorro_bus_type = {
.name = "zorro",
.match = zorro_bus_match,
.probe = zorro_device_probe,
+ .remove = zorro_device_remove,
};
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 26d79f6db8a..76411b1fc4f 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -78,7 +78,6 @@ struct acpi_processor_cx {
struct acpi_processor_power {
struct cpuidle_device dev;
struct acpi_processor_cx *state;
- struct acpi_processor_cx *bm_state;
unsigned long bm_check_timestamp;
u32 default_state;
u32 bm_activity;
diff --git a/include/asm-mips/8253pit.h b/include/asm-mips/8253pit.h
deleted file mode 100644
index 285f78488cc..00000000000
--- a/include/asm-mips/8253pit.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * 8253/8254 Programmable Interval Timer
- */
-
-#ifndef _8253PIT_H
-#define _8253PIT_H
-
-#define PIT_TICK_RATE 1193182UL
-
-#endif
diff --git a/include/asm-mips/dma.h b/include/asm-mips/dma.h
index 833437d31ef..d6a6c21f16d 100644
--- a/include/asm-mips/dma.h
+++ b/include/asm-mips/dma.h
@@ -92,6 +92,7 @@
#define MAX_DMA_ADDRESS (PAGE_OFFSET + 0x01000000)
#endif
#define MAX_DMA_PFN PFN_DOWN(virt_to_phys((void *)MAX_DMA_ADDRESS))
+#define MAX_DMA32_PFN (1UL << (32 - PAGE_SHIFT))
/* 8237 DMA controllers */
#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */
diff --git a/include/asm-mips/futex.h b/include/asm-mips/futex.h
index 3e7e30d4f41..17f082cfea8 100644
--- a/include/asm-mips/futex.h
+++ b/include/asm-mips/futex.h
@@ -35,7 +35,7 @@
" .set mips0 \n" \
" .section .fixup,\"ax\" \n" \
"4: li %0, %6 \n" \
- " j 2b \n" \
+ " j 3b \n" \
" .previous \n" \
" .section __ex_table,\"a\" \n" \
" "__UA_ADDR "\t1b, 4b \n" \
@@ -61,7 +61,7 @@
" .set mips0 \n" \
" .section .fixup,\"ax\" \n" \
"4: li %0, %6 \n" \
- " j 2b \n" \
+ " j 3b \n" \
" .previous \n" \
" .section __ex_table,\"a\" \n" \
" "__UA_ADDR "\t1b, 4b \n" \
@@ -200,4 +200,4 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
}
#endif
-#endif
+#endif /* _ASM_FUTEX_H */
diff --git a/include/asm-mips/i8253.h b/include/asm-mips/i8253.h
index 032ca73f181..5dabc870b32 100644
--- a/include/asm-mips/i8253.h
+++ b/include/asm-mips/i8253.h
@@ -12,6 +12,8 @@
#define PIT_CH0 0x40
#define PIT_CH2 0x42
+#define PIT_TICK_RATE 1193182UL
+
extern spinlock_t i8253_lock;
extern void setup_pit_timer(void);
diff --git a/include/asm-mips/ip32/ip32_ints.h b/include/asm-mips/ip32/ip32_ints.h
index ab5612f90f6..85bc5302bce 100644
--- a/include/asm-mips/ip32/ip32_ints.h
+++ b/include/asm-mips/ip32/ip32_ints.h
@@ -22,7 +22,7 @@ enum ip32_irq_no {
* CPU interrupts are 0 ... 7
*/
- CRIME_IRQ_BASE = MIPS_CPU_IRQ_BASE,
+ CRIME_IRQ_BASE = MIPS_CPU_IRQ_BASE + 8,
/*
* MACE
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index 90e4b403f53..1030562d6ea 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -68,11 +68,15 @@ do { \
if (cpu_has_dsp) \
__save_dsp(prev); \
(last) = resume(prev, next, task_thread_info(next)); \
+} while (0)
+
+#define finish_arch_switch(prev) \
+do { \
if (cpu_has_dsp) \
__restore_dsp(current); \
if (cpu_has_userlocal) \
- write_c0_userlocal(task_thread_info(current)->tp_value);\
-} while(0)
+ write_c0_userlocal(current_thread_info()->tp_value); \
+} while (0)
static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
{
diff --git a/include/asm-mips/time.h b/include/asm-mips/time.h
index ee1663e64da..7717934f94c 100644
--- a/include/asm-mips/time.h
+++ b/include/asm-mips/time.h
@@ -58,10 +58,22 @@ extern int (*perf_irq)(void);
* Initialize the calling CPU's compare interrupt as clockevent device
*/
#ifdef CONFIG_CEVT_R4K
-extern void mips_clockevent_init(void);
+extern int mips_clockevent_init(void);
extern unsigned int __weak get_c0_compare_int(void);
#else
-static inline void mips_clockevent_init(void)
+static inline int mips_clockevent_init(void)
+{
+ return -ENXIO;
+}
+#endif
+
+/*
+ * Initialize the count register as a clocksource
+ */
+#ifdef CONFIG_CEVT_R4K
+extern void init_mips_clocksource(void);
+#else
+static inline void init_mips_clocksource(void)
{
}
#endif
diff --git a/include/asm-powerpc/page_32.h b/include/asm-powerpc/page_32.h
index 374d0db37e1..17110aff26e 100644
--- a/include/asm-powerpc/page_32.h
+++ b/include/asm-powerpc/page_32.h
@@ -6,6 +6,10 @@
#define PPC_MEMSTART 0
+#ifdef CONFIG_NOT_COHERENT_CACHE
+#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES
+#endif
+
#ifndef __ASSEMBLY__
/*
* The basic type of a PTE - 64 bits for those CPUs with > 32 bit
diff --git a/include/asm-powerpc/pci-bridge.h b/include/asm-powerpc/pci-bridge.h
index dc318458b5f..d8bdc79db12 100644
--- a/include/asm-powerpc/pci-bridge.h
+++ b/include/asm-powerpc/pci-bridge.h
@@ -246,7 +246,6 @@ static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus)
return PCI_DN(busdn)->phb;
}
-extern void pcibios_free_controller(struct pci_controller *phb);
extern void isa_bridge_find_early(struct pci_controller *hose);
@@ -282,9 +281,11 @@ extern void
pci_process_bridge_OF_ranges(struct pci_controller *hose,
struct device_node *dev, int primary);
-/* Allocate a new PCI host bridge structure */
+/* Allocate & free a PCI host bridge structure */
extern struct pci_controller *
pcibios_alloc_controller(struct device_node *dev);
+extern void pcibios_free_controller(struct pci_controller *phb);
+
#ifdef CONFIG_PCI
extern unsigned long pci_address_to_pio(phys_addr_t address);
extern int pcibios_vaddr_is_ioport(void __iomem *address);
diff --git a/include/asm-powerpc/rtas.h b/include/asm-powerpc/rtas.h
index 8eaa7b28d9d..87db8728e82 100644
--- a/include/asm-powerpc/rtas.h
+++ b/include/asm-powerpc/rtas.h
@@ -164,7 +164,8 @@ extern int rtas_call(int token, int, int, int *, ...);
extern void rtas_restart(char *cmd);
extern void rtas_power_off(void);
extern void rtas_halt(void);
-extern void rtas_os_term(char *str);
+extern void rtas_panic_msg(char *str);
+extern void rtas_os_term(void);
extern int rtas_get_sensor(int sensor, int index, int *state);
extern int rtas_get_power_level(int powerdomain, int *level);
extern int rtas_set_power_level(int powerdomain, int level, int *setlevel);
diff --git a/include/asm-powerpc/vdso_datapage.h b/include/asm-powerpc/vdso_datapage.h
index 8a94f0eba5e..f01393224b5 100644
--- a/include/asm-powerpc/vdso_datapage.h
+++ b/include/asm-powerpc/vdso_datapage.h
@@ -77,6 +77,10 @@ struct vdso_data {
/* those additional ones don't have to be located anywhere
* special as they were not part of the original systemcfg
*/
+ __u32 dcache_block_size; /* L1 d-cache block size */
+ __u32 icache_block_size; /* L1 i-cache block size */
+ __u32 dcache_log_block_size; /* L1 d-cache log block size */
+ __u32 icache_log_block_size; /* L1 i-cache log block size */
__s32 wtom_clock_sec; /* Wall to monotonic clock */
__s32 wtom_clock_nsec;
__u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls */
@@ -99,6 +103,10 @@ struct vdso_data {
__s32 wtom_clock_sec; /* Wall to monotonic clock */
__s32 wtom_clock_nsec;
__u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */
+ __u32 dcache_block_size; /* L1 d-cache block size */
+ __u32 icache_block_size; /* L1 i-cache block size */
+ __u32 dcache_log_block_size; /* L1 d-cache log block size */
+ __u32 icache_log_block_size; /* L1 i-cache log block size */
};
#endif /* CONFIG_PPC64 */
diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h
index d866d338555..44bda786eef 100644
--- a/include/asm-s390/system.h
+++ b/include/asm-s390/system.h
@@ -388,6 +388,11 @@ extern void (*_machine_power_off)(void);
#define arch_align_stack(x) (x)
+#ifdef CONFIG_TRACE_IRQFLAGS
+extern psw_t sysc_restore_trace_psw;
+extern psw_t io_restore_trace_psw;
+#endif
+
#endif /* __KERNEL__ */
#endif
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 8ccedf7a0a5..e3c16c981e4 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -132,6 +132,11 @@ extern unsigned long acpi_realmode_flags;
int acpi_register_gsi (u32 gsi, int triggering, int polarity);
int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
+#ifdef CONFIG_X86_IO_APIC
+extern int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity);
+#else
+#define acpi_get_override_irq(bus, trigger, polarity) (-1)
+#endif
/*
* This function undoes the effect of one call to acpi_register_gsi().
* If this matches the last registration, any IRQ resources for gsi
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index 16a51546db4..c4e00161a24 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -92,6 +92,7 @@ struct cpuidle_device {
struct kobject kobj;
struct completion kobj_unregister;
void *governor_data;
+ struct cpuidle_state *safe_state;
};
DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index e99171f01b4..4f5047df8a9 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -70,7 +70,6 @@ enum
CTL_ABI=9, /* Binary emulation */
CTL_CPU=10, /* CPU stuff (speed scaling, etc) */
CTL_ARLAN=254, /* arlan wireless driver */
- CTL_APPLDATA=2120, /* s390 appldata */
CTL_S390DBF=5677, /* s390 debug */
CTL_SUNRPC=7249, /* sunrpc debug */
CTL_PM=9899, /* frv power management */
@@ -207,11 +206,6 @@ enum
VM_PANIC_ON_OOM=33, /* panic at out-of-memory */
VM_VDSO_ENABLED=34, /* map VDSO into new processes? */
VM_MIN_SLAB=35, /* Percent pages ignored by zone reclaim */
-
- /* s390 vm cmm sysctls */
- VM_CMM_PAGES=1111,
- VM_CMM_TIMED_PAGES=1112,
- VM_CMM_TIMEOUT=1113,
};
diff --git a/include/sound/version.h b/include/sound/version.h
index a2be8ad8894..a9781eb0da0 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
/* include/version.h. Generated by alsa/ksync script. */
#define CONFIG_SND_VERSION "1.0.15"
-#define CONFIG_SND_DATE " (Tue Oct 23 06:09:18 2007 UTC)"
+#define CONFIG_SND_DATE " (Tue Nov 20 19:16:42 2007 UTC)"
diff --git a/kernel/sysctl_check.c b/kernel/sysctl_check.c
index 4abc6d2306f..8f5baac1eb0 100644
--- a/kernel/sysctl_check.c
+++ b/kernel/sysctl_check.c
@@ -140,9 +140,6 @@ static struct trans_ctl_table trans_vm_table[] = {
{ VM_PANIC_ON_OOM, "panic_on_oom" },
{ VM_VDSO_ENABLED, "vdso_enabled" },
{ VM_MIN_SLAB, "min_slab_ratio" },
- { VM_CMM_PAGES, "cmm_pages" },
- { VM_CMM_TIMED_PAGES, "cmm_timed_pages" },
- { VM_CMM_TIMEOUT, "cmm_timeout" },
{}
};
@@ -1219,16 +1216,6 @@ static struct trans_ctl_table trans_arlan_table[] = {
{}
};
-static struct trans_ctl_table trans_appldata_table[] = {
- { CTL_APPLDATA_TIMER, "timer" },
- { CTL_APPLDATA_INTERVAL, "interval" },
- { CTL_APPLDATA_OS, "os" },
- { CTL_APPLDATA_NET_SUM, "net_sum" },
- { CTL_APPLDATA_MEM, "mem" },
- {}
-
-};
-
static struct trans_ctl_table trans_s390dbf_table[] = {
{ 5678 /* CTL_S390DBF_STOPPABLE */, "debug_stoppable" },
{ 5679 /* CTL_S390DBF_ACTIVE */, "debug_active" },
@@ -1273,7 +1260,6 @@ static struct trans_ctl_table trans_root_table[] = {
{ CTL_ABI, "abi" },
/* CTL_CPU not used */
{ CTL_ARLAN, "arlan", trans_arlan_table },
- { CTL_APPLDATA, "appldata", trans_appldata_table },
{ CTL_S390DBF, "s390dbf", trans_s390dbf_table },
{ CTL_SUNRPC, "sunrpc", trans_sunrpc_table },
{ CTL_PM, "pm", trans_pm_table },
diff --git a/mm/rmap.c b/mm/rmap.c
index dc3be5f5b0d..dbc2ca2057a 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -471,11 +471,12 @@ int page_mkclean(struct page *page)
if (page_mapped(page)) {
struct address_space *mapping = page_mapping(page);
- if (mapping)
+ if (mapping) {
ret = page_mkclean_file(mapping, page);
- if (page_test_dirty(page)) {
- page_clear_dirty(page);
- ret = 1;
+ if (page_test_dirty(page)) {
+ page_clear_dirty(page);
+ ret = 1;
+ }
}
}
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c
index a2f5a6ea389..7698f6c459d 100644
--- a/net/iucv/iucv.c
+++ b/net/iucv/iucv.c
@@ -97,7 +97,7 @@ struct iucv_irq_list {
struct iucv_irq_data data;
};
-static struct iucv_irq_data *iucv_irq_data;
+static struct iucv_irq_data *iucv_irq_data[NR_CPUS];
static cpumask_t iucv_buffer_cpumask = CPU_MASK_NONE;
static cpumask_t iucv_irq_cpumask = CPU_MASK_NONE;
@@ -277,7 +277,7 @@ union iucv_param {
/*
* Anchor for per-cpu IUCV command parameter block.
*/
-static union iucv_param *iucv_param;
+static union iucv_param *iucv_param[NR_CPUS];
/**
* iucv_call_b2f0
@@ -356,7 +356,7 @@ static void iucv_allow_cpu(void *data)
* 0x10 - Flag to allow priority message completion interrupts
* 0x08 - Flag to allow IUCV control interrupts
*/
- parm = percpu_ptr(iucv_param, smp_processor_id());
+ parm = iucv_param[cpu];
memset(parm, 0, sizeof(union iucv_param));
parm->set_mask.ipmask = 0xf8;
iucv_call_b2f0(IUCV_SETMASK, parm);
@@ -377,7 +377,7 @@ static void iucv_block_cpu(void *data)
union iucv_param *parm;
/* Disable all iucv interrupts. */
- parm = percpu_ptr(iucv_param, smp_processor_id());
+ parm = iucv_param[cpu];
memset(parm, 0, sizeof(union iucv_param));
iucv_call_b2f0(IUCV_SETMASK, parm);
@@ -401,9 +401,9 @@ static void iucv_declare_cpu(void *data)
return;
/* Declare interrupt buffer. */
- parm = percpu_ptr(iucv_param, cpu);
+ parm = iucv_param[cpu];
memset(parm, 0, sizeof(union iucv_param));
- parm->db.ipbfadr1 = virt_to_phys(percpu_ptr(iucv_irq_data, cpu));
+ parm->db.ipbfadr1 = virt_to_phys(iucv_irq_data[cpu]);
rc = iucv_call_b2f0(IUCV_DECLARE_BUFFER, parm);
if (rc) {
char *err = "Unknown";
@@ -458,7 +458,7 @@ static void iucv_retrieve_cpu(void *data)
iucv_block_cpu(NULL);
/* Retrieve interrupt buffer. */
- parm = percpu_ptr(iucv_param, cpu);
+ parm = iucv_param[cpu];
iucv_call_b2f0(IUCV_RETRIEVE_BUFFER, parm);
/* Clear indication that an iucv buffer exists for this cpu. */
@@ -558,22 +558,23 @@ static int __cpuinit iucv_cpu_notify(struct notifier_block *self,
switch (action) {
case CPU_UP_PREPARE:
case CPU_UP_PREPARE_FROZEN:
- if (!percpu_populate(iucv_irq_data,
- sizeof(struct iucv_irq_data),
- GFP_KERNEL|GFP_DMA, cpu))
+ iucv_irq_data[cpu] = kmalloc_node(sizeof(struct iucv_irq_data),
+ GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
+ if (!iucv_irq_data[cpu])
return NOTIFY_BAD;
- if (!percpu_populate(iucv_param, sizeof(union iucv_param),
- GFP_KERNEL|GFP_DMA, cpu)) {
- percpu_depopulate(iucv_irq_data, cpu);
+ iucv_param[cpu] = kmalloc_node(sizeof(union iucv_param),
+ GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
+ if (!iucv_param[cpu])
return NOTIFY_BAD;
- }
break;
case CPU_UP_CANCELED:
case CPU_UP_CANCELED_FROZEN:
case CPU_DEAD:
case CPU_DEAD_FROZEN:
- percpu_depopulate(iucv_param, cpu);
- percpu_depopulate(iucv_irq_data, cpu);
+ kfree(iucv_param[cpu]);
+ iucv_param[cpu] = NULL;
+ kfree(iucv_irq_data[cpu]);
+ iucv_irq_data[cpu] = NULL;
break;
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
@@ -612,7 +613,7 @@ static int iucv_sever_pathid(u16 pathid, u8 userdata[16])
{
union iucv_param *parm;
- parm = percpu_ptr(iucv_param, smp_processor_id());
+ parm = iucv_param[smp_processor_id()];
memset(parm, 0, sizeof(union iucv_param));
if (userdata)
memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser));
@@ -755,7 +756,7 @@ int iucv_path_accept(struct iucv_path *path, struct iucv_handler *handler,
local_bh_disable();
/* Prepare parameter block. */
- parm = percpu_ptr(iucv_param, smp_processor_id());
+ parm = iucv_param[smp_processor_id()];
memset(parm, 0, sizeof(union iucv_param));
parm->ctrl.ippathid = path->pathid;
parm->ctrl.ipmsglim = path->msglim;
@@ -799,7 +800,7 @@ int iucv_path_connect(struct iucv_path *path, struct iucv_handler *handler,
BUG_ON(in_atomic());
spin_lock_bh(&iucv_table_lock);
iucv_cleanup_queue();
- parm = percpu_ptr(iucv_param, smp_processor_id());
+ parm = iucv_param[smp_processor_id()];
memset(parm, 0, sizeof(union iucv_param));
parm->ctrl.ipmsglim = path->msglim;
parm->ctrl.ipflags1 = path->flags;
@@ -854,7 +855,7 @@ int iucv_path_quiesce(struct iucv_path *path, u8 userdata[16])
int rc;
local_bh_disable();
- parm = percpu_ptr(iucv_param, smp_processor_id());
+ parm = iucv_param[smp_processor_id()];
memset(parm, 0, sizeof(union iucv_param));
if (userdata)
memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser));
@@ -881,7 +882,7 @@ int iucv_path_resume(struct iucv_path *path, u8 userdata[16])
int rc;
local_bh_disable();
- parm = percpu_ptr(iucv_param, smp_processor_id());
+ parm = iucv_param[smp_processor_id()];
memset(parm, 0, sizeof(union iucv_param));
if (userdata)
memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser));
@@ -936,7 +937,7 @@ int iucv_message_purge(struct iucv_path *path, struct iucv_message *msg,
int rc;
local_bh_disable();
- parm = percpu_ptr(iucv_param, smp_processor_id());
+ parm = iucv_param[smp_processor_id()];
memset(parm, 0, sizeof(union iucv_param));
parm->purge.ippathid = path->pathid;
parm->purge.ipmsgid = msg->id;
@@ -1003,7 +1004,7 @@ int iucv_message_receive(struct iucv_path *path, struct iucv_message *msg,
}
local_bh_disable();
- parm = percpu_ptr(iucv_param, smp_processor_id());
+ parm = iucv_param[smp_processor_id()];
memset(parm, 0, sizeof(union iucv_param));
parm->db.ipbfadr1 = (u32)(addr_t) buffer;
parm->db.ipbfln1f = (u32) size;
@@ -1040,7 +1041,7 @@ int iucv_message_reject(struct iucv_path *path, struct iucv_message *msg)
int rc;
local_bh_disable();
- parm = percpu_ptr(iucv_param, smp_processor_id());
+ parm = iucv_param[smp_processor_id()];
memset(parm, 0, sizeof(union iucv_param));
parm->db.ippathid = path->pathid;
parm->db.ipmsgid = msg->id;
@@ -1074,7 +1075,7 @@ int iucv_message_reply(struct iucv_path *path, struct iucv_message *msg,
int rc;
local_bh_disable();
- parm = percpu_ptr(iucv_param, smp_processor_id());
+ parm = iucv_param[smp_processor_id()];
memset(parm, 0, sizeof(union iucv_param));
if (flags & IUCV_IPRMDATA) {
parm->dpl.ippathid = path->pathid;
@@ -1118,7 +1119,7 @@ int iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
int rc;
local_bh_disable();
- parm = percpu_ptr(iucv_param, smp_processor_id());
+ parm = iucv_param[smp_processor_id()];
memset(parm, 0, sizeof(union iucv_param));
if (flags & IUCV_IPRMDATA) {
/* Message of 8 bytes can be placed into the parameter list. */
@@ -1172,7 +1173,7 @@ int iucv_message_send2way(struct iucv_path *path, struct iucv_message *msg,
int rc;
local_bh_disable();
- parm = percpu_ptr(iucv_param, smp_processor_id());
+ parm = iucv_param[smp_processor_id()];
memset(parm, 0, sizeof(union iucv_param));
if (flags & IUCV_IPRMDATA) {
parm->dpl.ippathid = path->pathid;
@@ -1559,7 +1560,7 @@ static void iucv_external_interrupt(u16 code)
struct iucv_irq_data *p;
struct iucv_irq_list *work;
- p = percpu_ptr(iucv_irq_data, smp_processor_id());
+ p = iucv_irq_data[smp_processor_id()];
if (p->ippathid >= iucv_max_pathid) {
printk(KERN_WARNING "iucv_do_int: Got interrupt with "
"pathid %d > max_connections (%ld)\n",
@@ -1598,6 +1599,7 @@ static void iucv_external_interrupt(u16 code)
static int __init iucv_init(void)
{
int rc;
+ int cpu;
if (!MACHINE_IS_VM) {
rc = -EPROTONOSUPPORT;
@@ -1617,19 +1619,23 @@ static int __init iucv_init(void)
rc = PTR_ERR(iucv_root);
goto out_bus;
}
- /* Note: GFP_DMA used to get memory below 2G */
- iucv_irq_data = percpu_alloc(sizeof(struct iucv_irq_data),
- GFP_KERNEL|GFP_DMA);
- if (!iucv_irq_data) {
- rc = -ENOMEM;
- goto out_root;
- }
- /* Allocate parameter blocks. */
- iucv_param = percpu_alloc(sizeof(union iucv_param),
- GFP_KERNEL|GFP_DMA);
- if (!iucv_param) {
- rc = -ENOMEM;
- goto out_extint;
+
+ for_each_online_cpu(cpu) {
+ /* Note: GFP_DMA used to get memory below 2G */
+ iucv_irq_data[cpu] = kmalloc_node(sizeof(struct iucv_irq_data),
+ GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
+ if (!iucv_irq_data[cpu]) {
+ rc = -ENOMEM;
+ goto out_free;
+ }
+
+ /* Allocate parameter blocks. */
+ iucv_param[cpu] = kmalloc_node(sizeof(union iucv_param),
+ GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
+ if (!iucv_param[cpu]) {
+ rc = -ENOMEM;
+ goto out_free;
+ }
}
register_hotcpu_notifier(&iucv_cpu_notifier);
ASCEBC(iucv_error_no_listener, 16);
@@ -1638,9 +1644,13 @@ static int __init iucv_init(void)
iucv_available = 1;
return 0;
-out_extint:
- percpu_free(iucv_irq_data);
-out_root:
+out_free:
+ for_each_possible_cpu(cpu) {
+ kfree(iucv_param[cpu]);
+ iucv_param[cpu] = NULL;
+ kfree(iucv_irq_data[cpu]);
+ iucv_irq_data[cpu] = NULL;
+ }
s390_root_dev_unregister(iucv_root);
out_bus:
bus_unregister(&iucv_bus);
@@ -1658,6 +1668,7 @@ out:
static void __exit iucv_exit(void)
{
struct iucv_irq_list *p, *n;
+ int cpu;
spin_lock_irq(&iucv_queue_lock);
list_for_each_entry_safe(p, n, &iucv_task_queue, list)
@@ -1666,8 +1677,12 @@ static void __exit iucv_exit(void)
kfree(p);
spin_unlock_irq(&iucv_queue_lock);
unregister_hotcpu_notifier(&iucv_cpu_notifier);
- percpu_free(iucv_param);
- percpu_free(iucv_irq_data);
+ for_each_possible_cpu(cpu) {
+ kfree(iucv_param[cpu]);
+ iucv_param[cpu] = NULL;
+ kfree(iucv_irq_data[cpu]);
+ iucv_irq_data[cpu] = NULL;
+ }
s390_root_dev_unregister(iucv_root);
bus_unregister(&iucv_bus);
unregister_external_interrupt(0x4000, iucv_external_interrupt);
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c
index 3306ecd4924..b57f2d5a1c9 100644
--- a/sound/drivers/mpu401/mpu401_uart.c
+++ b/sound/drivers/mpu401/mpu401_uart.c
@@ -97,23 +97,27 @@ static void snd_mpu401_uart_clear_rx(struct snd_mpu401 *mpu)
static void uart_interrupt_tx(struct snd_mpu401 *mpu)
{
+ unsigned long flags;
+
if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) &&
test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) {
- spin_lock(&mpu->output_lock);
+ spin_lock_irqsave(&mpu->output_lock, flags);
snd_mpu401_uart_output_write(mpu);
- spin_unlock(&mpu->output_lock);
+ spin_unlock_irqrestore(&mpu->output_lock, flags);
}
}
static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu)
{
+ unsigned long flags;
+
if (mpu->info_flags & MPU401_INFO_INPUT) {
- spin_lock(&mpu->input_lock);
+ spin_lock_irqsave(&mpu->input_lock, flags);
if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode))
snd_mpu401_uart_input_read(mpu);
else
snd_mpu401_uart_clear_rx(mpu);
- spin_unlock(&mpu->input_lock);
+ spin_unlock_irqrestore(&mpu->input_lock, flags);
}
if (! (mpu->info_flags & MPU401_INFO_TX_IRQ))
/* ok. for better Tx performance try do some output
diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c
index e065b2a6444..1b832870cc8 100644
--- a/sound/drivers/portman2x4.c
+++ b/sound/drivers/portman2x4.c
@@ -668,7 +668,7 @@ static int __devinit snd_portman_probe_port(struct parport *p)
parport_release(pardev);
parport_unregister_device(pardev);
- return res;
+ return res ? -EIO : 0;
}
static void __devinit snd_portman_attach(struct parport *p)
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index be519a17dfa..3f9b5c56003 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -86,7 +86,7 @@ static int snd_ca0106_shared_spdif_get(struct snd_kcontrol *kcontrol,
{
struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
- ucontrol->value.enumerated.item[0] = emu->spdif_enable;
+ ucontrol->value.integer.value[0] = emu->spdif_enable;
return 0;
}
@@ -98,11 +98,11 @@ static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol,
int change = 0;
u32 mask;
- val = ucontrol->value.enumerated.item[0] ;
+ val = !!ucontrol->value.integer.value[0];
change = (emu->spdif_enable != val);
if (change) {
emu->spdif_enable = val;
- if (val == 1) {
+ if (val) {
/* Digital */
snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000);
@@ -159,6 +159,8 @@ static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
u32 source;
val = ucontrol->value.enumerated.item[0] ;
+ if (val >= 6)
+ return -EINVAL;
change = (emu->capture_source != val);
if (change) {
emu->capture_source = val;
@@ -207,6 +209,8 @@ static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
* for the particular source.
*/
source_id = ucontrol->value.enumerated.item[0] ;
+ if (source_id >= 4)
+ return -EINVAL;
change = (emu->i2c_capture_source != source_id);
if (change) {
snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
@@ -271,6 +275,8 @@ static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
u32 tmp;
val = ucontrol->value.enumerated.item[0] ;
+ if (val > 1)
+ return -EINVAL;
change = (emu->capture_mic_line_in != val);
if (change) {
emu->capture_mic_line_in = val;
@@ -443,7 +449,7 @@ static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol,
ogain = emu->i2c_capture_volume[source_id][0]; /* Left */
ngain = ucontrol->value.integer.value[0];
if (ngain > 0xff)
- return 0;
+ return -EINVAL;
if (ogain != ngain) {
if (emu->i2c_capture_source == source_id)
snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) );
@@ -453,7 +459,7 @@ static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol,
ogain = emu->i2c_capture_volume[source_id][1]; /* Right */
ngain = ucontrol->value.integer.value[1];
if (ngain > 0xff)
- return 0;
+ return -EINVAL;
if (ogain != ngain) {
if (emu->i2c_capture_source == source_id)
snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
@@ -497,7 +503,7 @@ static int spi_mute_put(struct snd_kcontrol *kcontrol,
}
ret = snd_ca0106_spi_write(emu, emu->spi_dac_reg[reg]);
- return ret ? -1 : 1;
+ return ret ? -EINVAL : 1;
}
#define CA_VOLUME(xname,chid,reg) \
diff --git a/sound/pci/ca0106/ca0106_proc.c b/sound/pci/ca0106/ca0106_proc.c
index ae80f51d8c4..61f2718ae35 100644
--- a/sound/pci/ca0106/ca0106_proc.c
+++ b/sound/pci/ca0106/ca0106_proc.c
@@ -445,13 +445,11 @@ int __devinit snd_ca0106_proc_init(struct snd_ca0106 * emu)
snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read1);
entry->c.text.write = snd_ca0106_proc_reg_write;
entry->mode |= S_IWUSR;
-// entry->private_data = emu;
}
if(! snd_card_proc_new(emu->card, "ca0106_i2c", &entry)) {
- snd_info_set_text_ops(entry, emu, snd_ca0106_proc_i2c_write);
entry->c.text.write = snd_ca0106_proc_i2c_write;
+ entry->private_data = emu;
entry->mode |= S_IWUSR;
-// entry->private_data = emu;
}
if(! snd_card_proc_new(emu->card, "ca0106_regs2", &entry))
snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read2);
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 6832649879c..1fa5f004e85 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -246,10 +246,9 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address.");
#define CM_MMODE_MASK 0x00000E00 /* model DAA interface mode */
#define CM_SPDIF_SELECT2 0x00000100 /* for model > 039 ? */
#define CM_ENCENTER 0x00000080
-#define CM_FLINKON 0x00000080 /* force modem link detection on, model 037 */
+#define CM_FLINKON 0x00000040 /* force modem link detection on, model 037 */
#define CM_MUTECH1 0x00000040 /* mute PCI ch1 to DAC */
-#define CM_FLINKOFF 0x00000040 /* force modem link detection off, model 037 */
-#define CM_UNKNOWN_18_5 0x00000020 /* ? */
+#define CM_FLINKOFF 0x00000020 /* force modem link detection off, model 037 */
#define CM_MIDSMP 0x00000010 /* 1/2 interpolation at front end DAC */
#define CM_UPDDMA_MASK 0x0000000C /* TDMA position update notification */
#define CM_UPDDMA_2048 0x00000000
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index 54a2034d8ed..ccacd7b890e 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -58,6 +58,9 @@ static int snd_emu10k1_spdif_get(struct snd_kcontrol *kcontrol,
unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
unsigned long flags;
+ /* Limit: emu->spdif_bits */
+ if (idx >= 3)
+ return -EINVAL;
spin_lock_irqsave(&emu->reg_lock, flags);
ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff;
ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff;
@@ -272,9 +275,12 @@ static int snd_emu1010_output_source_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- int channel;
+ unsigned int channel;
channel = (kcontrol->private_value) & 0xff;
+ /* Limit: emu1010_output_dst, emu->emu1010.output_source */
+ if (channel >= 24)
+ return -EINVAL;
ucontrol->value.enumerated.item[0] = emu->emu1010.output_source[channel];
return 0;
}
@@ -285,11 +291,17 @@ static int snd_emu1010_output_source_put(struct snd_kcontrol *kcontrol,
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
int change = 0;
unsigned int val;
- int channel;
+ unsigned int channel;
+ val = ucontrol->value.enumerated.item[0];
+ if (val >= 53)
+ return -EINVAL;
channel = (kcontrol->private_value) & 0xff;
- if (emu->emu1010.output_source[channel] != ucontrol->value.enumerated.item[0]) {
- val = emu->emu1010.output_source[channel] = ucontrol->value.enumerated.item[0];
+ /* Limit: emu1010_output_dst, emu->emu1010.output_source */
+ if (channel >= 24)
+ return -EINVAL;
+ if (emu->emu1010.output_source[channel] != val) {
+ emu->emu1010.output_source[channel] = val;
change = 1;
snd_emu1010_fpga_link_dst_src_write(emu,
emu1010_output_dst[channel], emu1010_src_regs[val]);
@@ -301,9 +313,12 @@ static int snd_emu1010_input_source_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- int channel;
+ unsigned int channel;
channel = (kcontrol->private_value) & 0xff;
+ /* Limit: emu1010_input_dst, emu->emu1010.input_source */
+ if (channel >= 22)
+ return -EINVAL;
ucontrol->value.enumerated.item[0] = emu->emu1010.input_source[channel];
return 0;
}
@@ -314,11 +329,17 @@ static int snd_emu1010_input_source_put(struct snd_kcontrol *kcontrol,
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
int change = 0;
unsigned int val;
- int channel;
+ unsigned int channel;
+ val = ucontrol->value.enumerated.item[0];
+ if (val >= 53)
+ return -EINVAL;
channel = (kcontrol->private_value) & 0xff;
- if (emu->emu1010.input_source[channel] != ucontrol->value.enumerated.item[0]) {
- val = emu->emu1010.input_source[channel] = ucontrol->value.enumerated.item[0];
+ /* Limit: emu1010_input_dst, emu->emu1010.input_source */
+ if (channel >= 22)
+ return -EINVAL;
+ if (emu->emu1010.input_source[channel] != val) {
+ emu->emu1010.input_source[channel] = val;
change = 1;
snd_emu1010_fpga_link_dst_src_write(emu,
emu1010_input_dst[channel], emu1010_src_regs[val]);
@@ -533,6 +554,9 @@ static int snd_emu1010_internal_clock_put(struct snd_kcontrol *kcontrol,
int change = 0;
val = ucontrol->value.enumerated.item[0] ;
+ /* Limit: uinfo->value.enumerated.items = 4; */
+ if (val >= 4)
+ return -EINVAL;
change = (emu->emu1010.internal_clock != val);
if (change) {
emu->emu1010.internal_clock = val;
@@ -669,7 +693,11 @@ static int snd_audigy_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
* update the capture volume from the cached value
* for the particular source.
*/
- source_id = ucontrol->value.enumerated.item[0]; /* Use 2 and 3 */
+ source_id = ucontrol->value.enumerated.item[0];
+ /* Limit: uinfo->value.enumerated.items = 2; */
+ /* emu->i2c_capture_volume */
+ if (source_id >= 2)
+ return -EINVAL;
change = (emu->i2c_capture_source != source_id);
if (change) {
snd_emu10k1_i2c_write(emu, ADC_MUX, 0); /* Mute input */
@@ -720,9 +748,13 @@ static int snd_audigy_i2c_volume_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- int source_id;
+ unsigned int source_id;
source_id = kcontrol->private_value;
+ /* Limit: emu->i2c_capture_volume */
+ /* capture_source: uinfo->value.enumerated.items = 2 */
+ if (source_id >= 2)
+ return -EINVAL;
ucontrol->value.integer.value[0] = emu->i2c_capture_volume[source_id][0];
ucontrol->value.integer.value[1] = emu->i2c_capture_volume[source_id][1];
@@ -735,10 +767,14 @@ static int snd_audigy_i2c_volume_put(struct snd_kcontrol *kcontrol,
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
unsigned int ogain;
unsigned int ngain;
- int source_id;
+ unsigned int source_id;
int change = 0;
source_id = kcontrol->private_value;
+ /* Limit: emu->i2c_capture_volume */
+ /* capture_source: uinfo->value.enumerated.items = 2 */
+ if (source_id >= 2)
+ return -EINVAL;
ogain = emu->i2c_capture_volume[source_id][0]; /* Left */
ngain = ucontrol->value.integer.value[0];
if (ngain > 0xff)
@@ -746,7 +782,7 @@ static int snd_audigy_i2c_volume_put(struct snd_kcontrol *kcontrol,
if (ogain != ngain) {
if (emu->i2c_capture_source == source_id)
snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) );
- emu->i2c_capture_volume[source_id][0] = ucontrol->value.integer.value[0];
+ emu->i2c_capture_volume[source_id][0] = ngain;
change = 1;
}
ogain = emu->i2c_capture_volume[source_id][1]; /* Right */
@@ -756,7 +792,7 @@ static int snd_audigy_i2c_volume_put(struct snd_kcontrol *kcontrol,
if (ogain != ngain) {
if (emu->i2c_capture_source == source_id)
snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
- emu->i2c_capture_volume[source_id][1] = ucontrol->value.integer.value[1];
+ emu->i2c_capture_volume[source_id][1] = ngain;
change = 1;
}
@@ -877,6 +913,9 @@ static int snd_emu10k1_spdif_put(struct snd_kcontrol *kcontrol,
unsigned int val;
unsigned long flags;
+ /* Limit: emu->spdif_bits */
+ if (idx >= 3)
+ return -EINVAL;
val = (ucontrol->value.iec958.status[0] << 0) |
(ucontrol->value.iec958.status[1] << 8) |
(ucontrol->value.iec958.status[2] << 16) |
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
index d619a3842cd..9fd3135f311 100644
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -742,6 +742,8 @@ static int snd_p16v_capture_source_put(struct snd_kcontrol *kcontrol,
u32 source;
val = ucontrol->value.enumerated.item[0] ;
+ if (val > 7)
+ return -EINVAL;
change = (emu->p16v_capture_source != val);
if (change) {
emu->p16v_capture_source = val;
@@ -784,6 +786,8 @@ static int snd_p16v_capture_channel_put(struct snd_kcontrol *kcontrol,
u32 tmp;
val = ucontrol->value.enumerated.item[0] ;
+ if (val > 3)
+ return -EINVAL;
change = (emu->p16v_capture_channel != val);
if (change) {
emu->p16v_capture_channel = val;
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index ad4cb38109f..8cbe3bf1e31 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1625,19 +1625,26 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
nid = codec->start_nid;
for (i = 0; i < codec->num_nodes; i++, nid++) {
- if (get_wcaps(codec, nid) & AC_WCAP_POWER) {
- unsigned int pincap;
- /*
- * don't power down the widget if it controls eapd
- * and EAPD_BTLENABLE is set.
- */
- pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
- if (pincap & AC_PINCAP_EAPD) {
- int eapd = snd_hda_codec_read(codec, nid,
- 0, AC_VERB_GET_EAPD_BTLENABLE, 0);
- eapd &= 0x02;
- if (power_state == AC_PWRST_D3 && eapd)
- continue;
+ unsigned int wcaps = get_wcaps(codec, nid);
+ if (wcaps & AC_WCAP_POWER) {
+ unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >>
+ AC_WCAP_TYPE_SHIFT;
+ if (wid_type == AC_WID_PIN) {
+ unsigned int pincap;
+ /*
+ * don't power down the widget if it controls
+ * eapd and EAPD_BTLENABLE is set.
+ */
+ pincap = snd_hda_param_read(codec, nid,
+ AC_PAR_PIN_CAP);
+ if (pincap & AC_PINCAP_EAPD) {
+ int eapd = snd_hda_codec_read(codec,
+ nid, 0,
+ AC_VERB_GET_EAPD_BTLENABLE, 0);
+ eapd &= 0x02;
+ if (power_state == AC_PWRST_D3 && eapd)
+ continue;
+ }
}
snd_hda_codec_write(codec, nid, 0,
AC_VERB_SET_POWER_STATE,
@@ -2485,13 +2492,14 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
/* front */
snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
0, format);
- if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT])
+ if (!mout->no_share_stream &&
+ mout->hp_nid && mout->hp_nid != nids[HDA_FRONT])
/* headphone out will just decode front left/right (stereo) */
snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
0, format);
/* extra outputs copied from front */
for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
- if (mout->extra_out_nid[i])
+ if (!mout->no_share_stream && mout->extra_out_nid[i])
snd_hda_codec_setup_stream(codec,
mout->extra_out_nid[i],
stream_tag, 0, format);
@@ -2501,7 +2509,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
if (chs >= (i + 1) * 2) /* independent out */
snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
i * 2, format);
- else /* copy front */
+ else if (!mout->no_share_stream) /* copy front */
snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
0, format);
}
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 20c5e625037..8c56c9cb0d0 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -220,6 +220,7 @@ struct hda_multi_out {
hda_nid_t dig_out_nid; /* digital out audio widget */
int max_channels; /* currently supported analog channels */
int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */
+ int no_share_stream; /* don't share a stream with multiple pins */
};
int snd_hda_multi_out_dig_open(struct hda_codec *codec,
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 0ee8ae4d441..196ad3c9405 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -957,6 +957,14 @@ static int patch_ad1986a(struct hda_codec *codec)
break;
}
+ /* AD1986A has a hardware problem that it can't share a stream
+ * with multiple output pins. The copy of front to surrounds
+ * causes noisy or silent outputs at a certain timing, e.g.
+ * changing the volume.
+ * So, let's disable the shared stream.
+ */
+ spec->multiout.no_share_stream = 1;
+
return 0;
}
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index f9b2c435a13..04012237096 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -111,7 +111,6 @@ struct sigmatel_spec {
unsigned int alt_switch: 1;
unsigned int hp_detect: 1;
unsigned int gpio_mute: 1;
- unsigned int no_vol_knob :1;
unsigned int gpio_mask, gpio_data;
@@ -342,42 +341,6 @@ static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol,
return 1;
}
-static int stac92xx_volknob_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 127;
- return 0;
-}
-
-static int stac92xx_volknob_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = kcontrol->private_value & 0xff;
- return 0;
-}
-
-static int stac92xx_volknob_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int val = kcontrol->private_value & 0xff;
-
- if (val == ucontrol->value.integer.value[0])
- return 0;
-
- val = ucontrol->value.integer.value[0];
- kcontrol->private_value &= ~0xff;
- kcontrol->private_value |= val;
-
- snd_hda_codec_write_cache(codec, kcontrol->private_value >> 16, 0,
- AC_VERB_SET_VOLUME_KNOB_CONTROL, val | 0x80);
- return 1;
-}
-
-
static struct hda_verb stac9200_core_init[] = {
/* set dac0mux for dac converter */
{ 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -446,18 +409,6 @@ static struct hda_verb stac9205_core_init[] = {
.private_value = verb_read | (verb_write << 16), \
}
-#define STAC_VOLKNOB(knob_nid) \
- { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = "Master Playback Volume", \
- .count = 1, \
- .info = stac92xx_volknob_info, \
- .get = stac92xx_volknob_get, \
- .put = stac92xx_volknob_put, \
- .private_value = 127 | (knob_nid << 16), \
- }
-
-
static struct snd_kcontrol_new stac9200_mixer[] = {
HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
@@ -487,7 +438,6 @@ static struct snd_kcontrol_new stac9205_mixer[] = {
},
STAC_INPUT_SOURCE(2),
STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0),
- STAC_VOLKNOB(0x24),
HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT),
HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT),
@@ -503,7 +453,6 @@ static struct snd_kcontrol_new stac9205_mixer[] = {
/* This needs to be generated dynamically based on sequence */
static struct snd_kcontrol_new stac922x_mixer[] = {
STAC_INPUT_SOURCE(2),
- STAC_VOLKNOB(0x16),
HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT),
HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x12, 0x0, HDA_OUTPUT),
@@ -517,7 +466,6 @@ static struct snd_kcontrol_new stac922x_mixer[] = {
static struct snd_kcontrol_new stac927x_mixer[] = {
STAC_INPUT_SOURCE(3),
- STAC_VOLKNOB(0x24),
STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB),
HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT),
@@ -1931,8 +1879,7 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
}
if (spec->multiout.hp_nid) {
const char *pfx;
- if (old_num_dacs == spec->multiout.num_dacs &&
- spec->no_vol_knob)
+ if (old_num_dacs == spec->multiout.num_dacs)
pfx = "Master";
else
pfx = "Headphone";
@@ -2489,7 +2436,6 @@ static int patch_stac9200(struct hda_codec *codec)
codec->spec = spec;
spec->num_pins = ARRAY_SIZE(stac9200_pin_nids);
spec->pin_nids = stac9200_pin_nids;
- spec->no_vol_knob = 1;
spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS,
stac9200_models,
stac9200_cfg_tbl);
@@ -2544,7 +2490,6 @@ static int patch_stac925x(struct hda_codec *codec)
codec->spec = spec;
spec->num_pins = ARRAY_SIZE(stac925x_pin_nids);
spec->pin_nids = stac925x_pin_nids;
- spec->no_vol_knob = 1;
spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS,
stac925x_models,
stac925x_cfg_tbl);
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 5d601ad6da7..abac62866da 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -725,7 +725,8 @@ static int cs4270_probe(struct platform_device *pdev)
codec->owner = THIS_MODULE;
codec->dai = &cs4270_dai;
codec->num_dai = 1;
- codec->private_data = codec + ALIGN(sizeof(struct snd_soc_codec), 4);
+ codec->private_data = (void *) codec +
+ ALIGN(sizeof(struct snd_soc_codec), 4);
socdev->codec = codec;
diff --git a/sound/soc/s3c24xx/s3c2443-ac97.c b/sound/soc/s3c24xx/s3c2443-ac97.c
index 75acf7ef552..758a2637e7a 100644
--- a/sound/soc/s3c24xx/s3c2443-ac97.c
+++ b/sound/soc/s3c24xx/s3c2443-ac97.c
@@ -32,7 +32,7 @@
#include <asm/hardware.h>
#include <asm/io.h>
-#include <asm/arch/regs-ac97.h>
+#include <asm/plat-s3c/regs-ac97.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/regs-clock.h>
#include <asm/arch/audio.h>