Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/dvrabel...
authorDavid Vrabel <dv02@dv02pc01.europe.root.pri>
Fri, 10 Oct 2008 10:47:31 +0000 (11:47 +0100)
committerDavid Vrabel <dv02@dv02pc01.europe.root.pri>
Fri, 10 Oct 2008 10:47:31 +0000 (11:47 +0100)
341 files changed:
Documentation/DMA-mapping.txt
Documentation/HOWTO
Documentation/SubmitChecklist
Documentation/cpu-freq/index.txt
Documentation/hwmon/adt7473
Documentation/hwmon/sysfs-interface
Documentation/ioctl/cdrom.txt
Documentation/sysctl/kernel.txt
Documentation/usb/anchors.txt
Documentation/video4linux/CARDLIST.em28xx
Documentation/video4linux/gspca.txt
MAINTAINERS
Makefile
arch/arm/kernel/kgdb.c
arch/arm/mach-davinci/psc.c
arch/arm/mach-pxa/time.c
arch/arm/mach-sa1100/generic.c
arch/arm/mach-sa1100/include/mach/jornada720.h
arch/arm/mach-sa1100/jornada720_ssp.c
arch/arm/mach-versatile/core.c
arch/arm/plat-omap/devices.c
arch/avr32/boards/atstk1000/atstk1002.c
arch/avr32/boot/images/.gitignore [new file with mode: 0644]
arch/avr32/kernel/.gitignore [new file with mode: 0644]
arch/avr32/kernel/avr32_ksyms.c
arch/avr32/kernel/syscall-stubs.S
arch/avr32/kernel/syscall_table.S
arch/avr32/kernel/traps.c
arch/avr32/lib/findbit.S
arch/ia64/include/asm/sections.h
arch/ia64/kernel/efi.c
arch/ia64/kernel/head.S
arch/ia64/kernel/setup.c
arch/ia64/kernel/vmlinux.lds.S
arch/ia64/kvm/kvm-ia64.c
arch/ia64/mm/contig.c
arch/ia64/mm/discontig.c
arch/m32r/Kconfig
arch/m32r/kernel/entry.S
arch/m32r/kernel/head.S
arch/m32r/kernel/irq.c
arch/m32r/kernel/m32r_ksyms.c
arch/m32r/kernel/process.c
arch/m32r/kernel/smp.c
arch/m32r/kernel/time.c
arch/m32r/kernel/traps.c
arch/m32r/lib/delay.c
arch/mips/Kconfig
arch/mips/au1000/common/gpio.c
arch/mips/kernel/Makefile
arch/mips/kernel/cevt-r4k.c
arch/mips/kernel/cevt-smtc.c [new file with mode: 0644]
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/entry.S
arch/mips/kernel/genex.S
arch/mips/kernel/head.S
arch/mips/kernel/kgdb.c
arch/mips/kernel/mips-mt-fpaff.c
arch/mips/kernel/process.c
arch/mips/kernel/ptrace.c
arch/mips/kernel/smtc.c
arch/mips/kernel/traps.c
arch/mips/kernel/vmlinux.lds.S
arch/mips/lib/csum_partial.S
arch/mips/mti-malta/Makefile
arch/mips/mti-malta/malta-smtc.c
arch/mips/pci/Makefile
arch/mips/pci/pci-bcm47xx.c [new file with mode: 0644]
arch/mips/pci/pci-ip27.c
arch/mips/sibyte/swarm/Makefile
arch/mips/sibyte/swarm/platform.c [new file with mode: 0644]
arch/mn10300/kernel/irq.c
arch/mn10300/kernel/time.c
arch/mn10300/unit-asb2303/unit-init.c
arch/mn10300/unit-asb2305/unit-init.c
arch/powerpc/boot/Makefile
arch/powerpc/boot/dts/holly.dts
arch/powerpc/boot/dts/mpc8610_hpcd.dts
arch/powerpc/include/asm/elf.h
arch/powerpc/include/asm/sections.h
arch/powerpc/kernel/idle.c
arch/powerpc/kernel/kgdb.c
arch/powerpc/kernel/module_64.c
arch/powerpc/platforms/fsl_uli1575.c
arch/s390/kernel/time.c
arch/s390/lib/delay.c
arch/sparc64/kernel/irq.c
arch/sparc64/kernel/of_device.c
arch/sparc64/kernel/pci.c
arch/sparc64/kernel/pci_psycho.c
arch/sparc64/kernel/traps.c
arch/x86/boot/compressed/relocs.c
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/amd_iommu.c
arch/x86/kernel/apm_32.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
arch/x86/kernel/cpu/mtrr/main.c
arch/x86/kernel/kdebugfs.c
arch/x86/kernel/kgdb.c
arch/x86/kernel/pci-gart_64.c
arch/x86/kernel/process.c
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c
arch/x86/kernel/setup.c
arch/x86/kernel/vmi_32.c
arch/x86/kernel/vsmp_64.c
arch/x86/mm/init_32.c
arch/x86/oprofile/nmi_int.c
arch/x86/xen/setup.c
drivers/accessibility/braille/braille_console.c
drivers/acpi/glue.c
drivers/acpi/sleep/proc.c
drivers/ata/sata_nv.c
drivers/bluetooth/bpa10x.c
drivers/bluetooth/btusb.c
drivers/char/tty_io.c
drivers/clocksource/acpi_pm.c
drivers/dma/dw_dmac.c
drivers/hwmon/abituguru3.c
drivers/hwmon/ad7414.c
drivers/hwmon/atxp1.c
drivers/hwmon/it87.c
drivers/i2c/busses/i2c-powermac.c
drivers/i2c/i2c-dev.c
drivers/ide/Kconfig
drivers/ide/ide-cd.c
drivers/ide/ide-dma.c
drivers/ide/ide-probe.c
drivers/ide/ide-tape.c
drivers/ide/mips/Makefile
drivers/ide/mips/swarm.c [deleted file]
drivers/infiniband/hw/mlx4/qp.c
drivers/infiniband/hw/nes/nes_cm.c
drivers/infiniband/ulp/ipoib/ipoib.h
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
drivers/input/mouse/bcm5974.c
drivers/input/touchscreen/jornada720_ts.c
drivers/leds/leds-fsg.c
drivers/leds/leds-pca955x.c
drivers/md/dm-mpath.c
drivers/md/dm.c
drivers/md/md.c
drivers/media/common/tuners/tuner-xc2028.h
drivers/media/dvb/b2c2/flexcop-fe-tuner.c
drivers/media/dvb/dvb-core/dmxdev.c
drivers/media/dvb/dvb-core/dvb_demux.c
drivers/media/dvb/frontends/s5h1420.c
drivers/media/dvb/frontends/s5h1420.h
drivers/media/dvb/siano/sms-cards.c
drivers/media/video/bt8xx/bttv-driver.c
drivers/media/video/cafe_ccic.c
drivers/media/video/cpia2/cpia2_usb.c
drivers/media/video/cx18/cx18-cards.c
drivers/media/video/em28xx/em28xx-audio.c
drivers/media/video/em28xx/em28xx-cards.c
drivers/media/video/em28xx/em28xx-dvb.c
drivers/media/video/gspca/gspca.c
drivers/media/video/gspca/pac7311.c
drivers/media/video/gspca/sonixb.c
drivers/media/video/gspca/sonixj.c
drivers/media/video/gspca/spca561.c
drivers/media/video/gspca/zc3xx.c
drivers/media/video/ov511.c
drivers/media/video/pvrusb2/pvrusb2-devattr.c
drivers/media/video/s2255drv.c
drivers/media/video/uvc/uvc_ctrl.c
drivers/media/video/w9968cf.c
drivers/media/video/wm8739.c
drivers/media/video/zoran_card.c
drivers/media/video/zoran_driver.c
drivers/mfd/Kconfig
drivers/mfd/asic3.c
drivers/misc/eeepc-laptop.c
drivers/mmc/card/block.c
drivers/mmc/card/mmc_test.c
drivers/mmc/host/atmel-mci.c
drivers/mmc/host/tmio_mmc.h
drivers/net/bnx2.h
drivers/net/e100.c
drivers/net/e1000/e1000_hw.c
drivers/net/e1000e/e1000.h
drivers/net/e1000e/ethtool.c
drivers/net/e1000e/ich8lan.c
drivers/net/e1000e/netdev.c
drivers/net/e1000e/param.c
drivers/net/forcedeth.c
drivers/net/mlx4/mr.c
drivers/net/wireless/ath9k/core.c
drivers/net/wireless/ath9k/core.h
drivers/net/wireless/ath9k/main.c
drivers/net/wireless/ath9k/xmit.c
drivers/net/wireless/zd1211rw/zd_usb.c
drivers/pci/pci-sysfs.c
drivers/pci/pcie/aspm.c
drivers/pci/search.c
drivers/pcmcia/ds.c
drivers/rtc/rtc-dev.c
drivers/s390/cio/ccwgroup.c
drivers/s390/cio/cio.c
drivers/s390/cio/qdio_setup.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qlogicpti.c
drivers/scsi/scsi_lib.c
drivers/serial/atmel_serial.c
drivers/spi/orion_spi.c
drivers/spi/pxa2xx_spi.c
drivers/ssb/main.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/gadget/fsl_usb2_udc.c
drivers/usb/gadget/omap_udc.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-sched.c
drivers/usb/musb/Kconfig
drivers/usb/musb/musb_core.c
drivers/usb/musb/omap2430.c
drivers/usb/musb/omap2430.h
drivers/usb/serial/cp2101.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.h
drivers/usb/serial/option.c
drivers/usb/serial/sierra.c
drivers/usb/serial/ti_usb_3410_5052.c
drivers/usb/serial/usb-serial.c
drivers/usb/storage/Kconfig
drivers/usb/storage/Makefile
drivers/usb/storage/unusual_devs.h
drivers/usb/storage/usb.c
drivers/video/console/fbcon.c
drivers/video/console/fbcon.h
drivers/watchdog/geodewdt.c
drivers/watchdog/ibmasr.c
drivers/watchdog/pnx4008_wdt.c
drivers/watchdog/rc32434_wdt.c
drivers/watchdog/rdc321x_wdt.c
drivers/watchdog/wdt285.c
fs/9p/vfs_inode.c
fs/dcache.c
fs/exec.c
fs/inotify_user.c
fs/ramfs/file-nommu.c
fs/splice.c
fs/ubifs/debug.c
fs/ubifs/dir.c
fs/ubifs/find.c
fs/ubifs/gc.c
fs/ubifs/super.c
fs/ubifs/tnc.c
fs/xfs/linux-2.6/xfs_aops.c
fs/xfs/linux-2.6/xfs_super.c
fs/xfs/xfs_buf_item.c
fs/xfs/xfs_dfrag.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_log.c
fs/xfs/xfs_log_priv.h
fs/xfs/xfs_vnodeops.c
include/asm-mips/cevt-r4k.h [new file with mode: 0644]
include/asm-mips/irqflags.h
include/asm-mips/mipsregs.h
include/asm-mips/pgtable-32.h
include/asm-mips/smtc.h
include/asm-mips/sn/mapped_kernel.h
include/asm-mips/stackframe.h
include/asm-x86/acpi.h
include/asm-x86/cpufeature.h
include/asm-x86/idle.h
include/asm-x86/kgdb.h
include/asm-x86/uaccess_64.h
include/linux/cnt32_to_63.h [moved from arch/arm/include/asm/cnt32_to_63.h with 87% similarity]
include/linux/hrtimer.h
include/linux/ide.h
include/linux/mlx4/device.h
include/linux/pci.h
include/linux/ramfs.h
include/linux/smb.h
include/linux/stacktrace.h
include/net/9p/9p.h
include/net/9p/transport.h
include/net/sctp/sm.h
init/main.c
kernel/cgroup.c
kernel/exit.c
kernel/hrtimer.c
kernel/kexec.c
kernel/kgdb.c
kernel/posix-timers.c
kernel/sched.c
kernel/sched_rt.c
kernel/time/clockevents.c
kernel/time/tick-broadcast.c
kernel/time/tick-common.c
kernel/time/tick-internal.h
kernel/time/tick-sched.c
kernel/trace/trace_sysprof.c
mm/memcontrol.c
mm/page_alloc.c
mm/page_isolation.c
mm/slob.c
mm/tiny-shmem.c
net/9p/client.c
net/9p/conv.c
net/9p/mod.c
net/9p/trans_fd.c
net/9p/trans_virtio.c
net/ax25/af_ax25.c
net/ax25/ax25_std_timer.c
net/core/dev.c
net/core/rtnetlink.c
net/ipv4/tcp_hybla.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/udp.c
net/ipv6/netfilter/ip6t_hbh.c
net/ipv6/route.c
net/ipv6/tcp_ipv6.c
net/iucv/iucv.c
net/key/af_key.c
net/netrom/af_netrom.c
net/sctp/associola.c
net/sctp/output.c
net/sctp/sm_make_chunk.c
net/sctp/sm_statefuns.c
net/socket.c
net/xfrm/xfrm_output.c
scripts/kconfig/conf.c
scripts/kconfig/confdata.c
scripts/kernel-doc
scripts/mod/modpost.c
security/selinux/ss/services.c
sound/core/pcm.c
sound/core/pcm_native.c
sound/core/rawmidi.c
sound/pci/hda/patch_sigmatel.c
sound/ppc/awacs.c
sound/soc/at32/at32-pcm.c
sound/soc/codecs/cs4270.c
sound/soc/codecs/wm8753.c

index b463ecd..c74fec8 100644 (file)
@@ -740,7 +740,7 @@ failure can be determined by:
        dma_addr_t dma_handle;
 
        dma_handle = pci_map_single(pdev, addr, size, direction);
-       if (pci_dma_mapping_error(dma_handle)) {
+       if (pci_dma_mapping_error(pdev, dma_handle)) {
                /*
                 * reduce current DMA mapping usage,
                 * delay and try again later or
index c2371c5..48a3955 100644 (file)
@@ -77,7 +77,8 @@ documentation files are also added which explain how to use the feature.
 When a kernel change causes the interface that the kernel exposes to
 userspace to change, it is recommended that you send the information or
 a patch to the manual pages explaining the change to the manual pages
-maintainer at mtk.manpages@gmail.com.
+maintainer at mtk.manpages@gmail.com, and CC the list
+linux-api@vger.kernel.org.
 
 Here is a list of files that are in the kernel source tree that are
 required reading:
index da10e07..21f0795 100644 (file)
@@ -67,6 +67,8 @@ kernel patches.
 
 19: All new userspace interfaces are documented in Documentation/ABI/.
     See Documentation/ABI/README for more information.
+    Patches that change userspace interfaces should be CCed to
+    linux-api@vger.kernel.org.
 
 20: Check that it all passes `make headers_check'.
 
index ffdb532..3d0b915 100644 (file)
@@ -35,11 +35,9 @@ Mailing List
 ------------
 There is a CPU frequency changing CVS commit and general list where
 you can report bugs, problems or submit patches. To post a message,
-send an email to cpufreq@lists.linux.org.uk, to subscribe go to
-http://lists.linux.org.uk/mailman/listinfo/cpufreq. Previous post to the
-mailing list are available to subscribers at
-http://lists.linux.org.uk/mailman/private/cpufreq/.
-
+send an email to cpufreq@vger.kernel.org, to subscribe go to
+http://vger.kernel.org/vger-lists.html#cpufreq and follow the
+instructions there.
 
 Links
 -----
@@ -50,7 +48,7 @@ how to access the CVS repository:
 * http://cvs.arm.linux.org.uk/
 
 the CPUFreq Mailing list:
-* http://lists.linux.org.uk/mailman/listinfo/cpufreq
+* http://vger.kernel.org/vger-lists.html#cpufreq
 
 Clock and voltage scaling for the SA-1100:
 * http://www.lartmaker.nl/projects/scaling
index 2126de3..1cbf671 100644 (file)
@@ -14,14 +14,14 @@ Description
 
 This driver implements support for the Analog Devices ADT7473 chip family.
 
-The LM85 uses the 2-wire interface compatible with the SMBUS 2.0
+The ADT7473 uses the 2-wire interface compatible with the SMBUS 2.0
 specification. Using an analog to digital converter it measures three (3)
-temperatures and two (2) voltages. It has three (3) 16-bit counters for
+temperatures and two (2) voltages. It has four (4) 16-bit counters for
 measuring fan speed. There are three (3) PWM outputs that can be used
 to control fan speed.
 
 A sophisticated control system for the PWM outputs is designed into the
-LM85 that allows fan speed to be adjusted automatically based on any of the
+ADT7473 that allows fan speed to be adjusted automatically based on any of the
 three temperature sensors. Each PWM output is individually adjustable and
 programmable. Once configured, the ADT7473 will adjust the PWM outputs in
 response to the measured temperatures without further host intervention.
@@ -46,14 +46,6 @@ from the raw value to get the temperature value.
 The Analog Devices datasheet is very detailed and describes a procedure for
 determining an optimal configuration for the automatic PWM control.
 
-Hardware Configurations
------------------------
-
-The ADT7473 chips have an optional SMBALERT output that can be used to
-signal the chipset in case a limit is exceeded or the temperature sensors
-fail. Individual sensor interrupts can be masked so they won't trigger
-SMBALERT. The SMBALERT output if configured replaces the PWM2 function.
-
 Configuration Notes
 -------------------
 
@@ -61,8 +53,8 @@ Besides standard interfaces driver adds the following:
 
 * PWM Control
 
-* pwm#_auto_point1_pwm and pwm#_auto_point1_temp and
-* pwm#_auto_point2_pwm and pwm#_auto_point2_temp -
+* pwm#_auto_point1_pwm and temp#_auto_point1_temp and
+* pwm#_auto_point2_pwm and temp#_auto_point2_temp -
 
 point1: Set the pwm speed at a lower temperature bound.
 point2: Set the pwm speed at a higher temperature bound.
index 2d84573..6dbfd5e 100644 (file)
@@ -329,6 +329,10 @@ power[1-*]_average         Average power use
                                Unit: microWatt
                                RO
 
+power[1-*]_average_interval    Power use averaging interval
+                               Unit: milliseconds
+                               RW
+
 power[1-*]_average_highest     Historical average maximum power use
                                Unit: microWatt
                                RO
@@ -353,6 +357,14 @@ power[1-*]_reset_history   Reset input_highest, input_lowest,
                                average_highest and average_lowest.
                                WO
 
+**********
+* Energy *
+**********
+
+energy[1-*]_input              Cumulative energy use
+                               Unit: microJoule
+                               RO
+
 **********
 * Alarms *
 **********
index 62d4af4..59df81c 100644 (file)
@@ -271,14 +271,14 @@ CDROMCLOSETRAY                    pendant of CDROMEJECT
 
        usage:
 
-         ioctl(fd, CDROMEJECT, 0);
+         ioctl(fd, CDROMCLOSETRAY, 0);
 
        inputs:         none
 
        outputs:        none
 
        error returns:
-         ENOSYS        cd drive not capable of ejecting
+         ENOSYS        cd drive not capable of closing the tray
          EBUSY         other processes are accessing drive, or door is locked
 
        notes:
index 276a7e6..e1ff0d9 100644 (file)
@@ -351,9 +351,10 @@ kernel.  This value defaults to SHMMAX.
 
 softlockup_thresh:
 
-This value can be used to lower the softlockup tolerance
-threshold. The default threshold is 10s.  If a cpu is locked up
-for 10s, the kernel complains.  Valid values are 1-60s.
+This value can be used to lower the softlockup tolerance threshold.  The
+default threshold is 60 seconds.  If a cpu is locked up for 60 seconds,
+the kernel complains.  Valid values are 1-60 seconds.  Setting this
+tunable to zero will disable the softlockup detection altogether.
 
 ==============================================================
 
index 7304bcf..5e6b64c 100644 (file)
@@ -42,9 +42,21 @@ This function kills all URBs associated with an anchor. The URBs
 are called in the reverse temporal order they were submitted.
 This way no data can be reordered.
 
+usb_unlink_anchored_urbs()
+--------------------------
+
+This function unlinks all URBs associated with an anchor. The URBs
+are processed in the reverse temporal order they were submitted.
+This is similar to usb_kill_anchored_urbs(), but it will not sleep.
+Therefore no guarantee is made that the URBs have been unlinked when
+the call returns. They may be unlinked later but will be unlinked in
+finite time.
+
 usb_wait_anchor_empty_timeout()
 -------------------------------
 
 This function waits for all URBs associated with an anchor to finish
 or a timeout, whichever comes first. Its return value will tell you
 whether the timeout was reached.
+
+
index 89c7f32..53449cb 100644 (file)
@@ -46,7 +46,7 @@
  45 -> Pinnacle PCTV DVB-T                      (em2870)
  46 -> Compro, VideoMate U3                     (em2870)        [185b:2870]
  47 -> KWorld DVB-T 305U                        (em2880)        [eb1a:e305]
- 48 -> KWorld DVB-T 310U                        (em2880)
+ 48 -> KWorld DVB-T 310U                        (em2880)        [eb1a:e310]
  49 -> MSI DigiVox A/D                          (em2880)        [eb1a:e310]
  50 -> MSI DigiVox A/D II                       (em2880)        [eb1a:e320]
  51 -> Terratec Hybrid XS Secam                 (em2880)        [0ccd:004c]
index 0f03900..9a3e4d7 100644 (file)
@@ -190,6 +190,7 @@ pac7311             093a:260f       SnakeCam
 pac7311                093a:2621       PAC731x
 pac7311                093a:2624       PAC7302
 pac7311                093a:2626       Labtec 2200
+pac7311                093a:262a       Webcam 300k
 zc3xx          0ac8:0302       Z-star Vimicro zc0302
 vc032x         0ac8:0321       Vimicro generic vc0321
 vc032x         0ac8:0323       Vimicro Vc0323
index 6345827..4674c64 100644 (file)
@@ -271,20 +271,20 @@ W:        http://www.lesswatts.org/projects/acpi/
 S:     Supported
 
 ACPI WMI DRIVER
-P:      Carlos Corbacho
-M:      carlos@strangeworlds.co.uk
-L:      linux-acpi@vger.kernel.org
-W:      http://www.lesswatts.org/projects/acpi/
-S:      Maintained
+P:     Carlos Corbacho
+M:     carlos@strangeworlds.co.uk
+L:     linux-acpi@vger.kernel.org
+W:     http://www.lesswatts.org/projects/acpi/
+S:     Maintained
 
 AD1889 ALSA SOUND DRIVER
-P:     Kyle McMartin
-M:     kyle@mcmartin.ca
-P:     Thibaut Varene
-M:     T-Bone@parisc-linux.org
-W:     http://wiki.parisc-linux.org/AD1889
-L:     linux-parisc@vger.kernel.org
-S:     Maintained
+P:     Kyle McMartin
+M:     kyle@mcmartin.ca
+P:     Thibaut Varene
+M:     T-Bone@parisc-linux.org
+W:     http://wiki.parisc-linux.org/AD1889
+L:     linux-parisc@vger.kernel.org
+S:     Maintained
 
 ADM1025 HARDWARE MONITOR DRIVER
 P:     Jean Delvare
@@ -473,11 +473,11 @@ L:        linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
 S:     Maintained
 
 ARM/ATMEL AT91RM9200 ARM ARCHITECTURE
-P:      Andrew Victor
-M:      linux@maxim.org.za
-L:      linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
-W:      http://maxim.org.za/at91_26.html
-S:      Maintained
+P:     Andrew Victor
+M:     linux@maxim.org.za
+L:     linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+W:     http://maxim.org.za/at91_26.html
+S:     Maintained
 
 ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE
 P:     Lennert Buytenhek
@@ -532,10 +532,10 @@ L:        linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
 S:     Maintained
 
 ARM/HP JORNADA 7XX MACHINE SUPPORT
-P:      Kristoffer Ericson
-M:      kristoffer.ericson@gmail.com
-W:      www.jlime.com
-S:      Maintained
+P:     Kristoffer Ericson
+M:     kristoffer.ericson@gmail.com
+W:     www.jlime.com
+S:     Maintained
 
 ARM/INTEL IOP32X ARM ARCHITECTURE
 P:     Lennert Buytenhek
@@ -1017,7 +1017,7 @@ T:        git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
 S:     Maintained
 
 CAFE CMOS INTEGRATED CAMERA CONTROLLER DRIVER
-P:     Jonathan Corbet
+P:     Jonathan Corbet
 M:     corbet@lwn.net
 L:     video4linux-list@redhat.com
 S:     Maintained
@@ -1204,9 +1204,7 @@ M:        hpa@zytor.com
 S:     Maintained
 
 CPUSETS
-P:     Paul Jackson
 P:     Paul Menage
-M:     pj@sgi.com
 M:     menage@google.com
 L:     linux-kernel@vger.kernel.org
 W:     http://www.bullopensource.org/cpuset/
@@ -1365,7 +1363,7 @@ P:        Digi International, Inc
 M:     Eng.Linux@digi.com
 L:     Eng.Linux@digi.com
 W:     http://www.digi.com
-S:     Orphaned
+S:     Orphan
 
 DIRECTORY NOTIFICATION
 P:     Stephen Rothwell
@@ -1429,12 +1427,12 @@ L:      linux-acpi@vger.kernel.org
 S:     Supported
 
 DOCUMENTATION (/Documentation directory)
-P:     Michael Kerrisk
-M:     mtk.manpages@gmail.com
-P:     Randy Dunlap
-M:     rdunlap@xenotime.net
-L:     linux-doc@vger.kernel.org
-S:     Maintained
+P:     Michael Kerrisk
+M:     mtk.manpages@gmail.com
+P:     Randy Dunlap
+M:     rdunlap@xenotime.net
+L:     linux-doc@vger.kernel.org
+S:     Maintained
 
 DOUBLETALK DRIVER
 P:     James R. Van Zandt
@@ -1465,7 +1463,7 @@ S:        Maintained
 DVB SUBSYSTEM AND DRIVERS
 P:     LinuxTV.org Project
 M:     v4l-dvb-maintainer@linuxtv.org
-L:     linux-dvb@linuxtv.org (subscription required)
+L:     linux-dvb@linuxtv.org (subscription required)
 W:     http://linuxtv.org/
 T:     git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
 S:     Maintained
@@ -1803,7 +1801,7 @@ FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit)
 P:     Rik Faith
 M:     faith@cs.unc.edu
 L:     linux-scsi@vger.kernel.org
-S:     Odd fixes (e.g., new signatures)
+S:     Odd Fixes (e.g., new signatures)
 
 GDT SCSI DISK ARRAY CONTROLLER DRIVER
 P:     Achim Leubner
@@ -1844,10 +1842,10 @@ S:      Maintained
 HARDWARE MONITORING
 L:     lm-sensors@lm-sensors.org
 W:     http://www.lm-sensors.org/
-S:     Orphaned
+S:     Orphan
 
 HARDWARE RANDOM NUMBER GENERATOR CORE
-S:     Orphaned
+S:     Orphan
 
 HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER
 P:     Robert Love
@@ -1990,7 +1988,7 @@ S:        Maintained
 I2C/SMBUS STUB DRIVER
 P:     Mark M. Hoffman
 M:     mhoffman@lightlink.com
-L:     lm-sensors@lm-sensors.org
+L:     i2c@lm-sensors.org
 S:     Maintained
 
 I2C SUBSYSTEM
@@ -2114,7 +2112,7 @@ M:        rolandd@cisco.com
 P:     Sean Hefty
 M:     sean.hefty@intel.com
 P:     Hal Rosenstock
-M:     hal.rosenstock@gmail.com 
+M:     hal.rosenstock@gmail.com
 L:     general@lists.openfabrics.org
 W:     http://www.openib.org/
 T:     git kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git
@@ -2702,17 +2700,18 @@ S:      Maintained
 
 MARVELL YUKON / SYSKONNECT DRIVER
 P:     Mirko Lindner
-M:     mlindner@syskonnect.de
+M:     mlindner@syskonnect.de
 P:     Ralph Roesler
-M:     rroesler@syskonnect.de
-W:     http://www.syskonnect.com
-S:     Supported
+M:     rroesler@syskonnect.de
+W:     http://www.syskonnect.com
+S:     Supported
 
 MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7
 P:     Michael Kerrisk
 M:     mtk.manpages@gmail.com
-W:     http://www.kernel.org/doc/man-pages
-S:     Supported
+W:     http://www.kernel.org/doc/man-pages
+L:     linux-man@vger.kernel.org
+S:     Supported
 
 MARVELL LIBERTAS WIRELESS DRIVER
 P:     Dan Williams
@@ -2741,7 +2740,7 @@ S:        Maintained
 MEGARAID SCSI DRIVERS
 P:     Neela Syam Kolli
 M:     megaraidlinux@lsi.com
-S:     linux-scsi@vger.kernel.org
+L:     linux-scsi@vger.kernel.org
 W:     http://megaraid.lsilogic.com
 S:     Maintained
 
@@ -2859,7 +2858,7 @@ MULTIMEDIA CARD (MMC) ETC. OVER SPI
 P:     David Brownell
 M:     dbrownell@users.sourceforge.net
 L:     linux-kernel@vger.kernel.org
-S:     Odd fixes
+S:     Odd Fixes
 
 MULTISOUND SOUND DRIVER
 P:     Andrew Veliath
@@ -2873,10 +2872,10 @@ L:      linux-kernel@vger.kernel.org
 S:     Maintained
 
 MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER
-P:     Felipe Balbi
-M:     felipe.balbi@nokia.com
-L:     linux-usb@vger.kernel.org
-S:     Maintained
+P:     Felipe Balbi
+M:     felipe.balbi@nokia.com
+L:     linux-usb@vger.kernel.org
+S:     Maintained
 
 MYRICOM MYRI-10G 10GbE DRIVER (MYRI10GE)
 P:     Andrew Gallatin
@@ -2888,7 +2887,7 @@ W:        http://www.myri.com/scs/download-Myri10GE.html
 S:     Supported
 
 NATSEMI ETHERNET DRIVER (DP8381x)
-P:     Tim Hockin
+P:     Tim Hockin
 M:     thockin@hockin.org
 S:     Maintained
 
@@ -3107,7 +3106,7 @@ M:        laforge@gnumonks.org
 S:     Maintained
 
 OMNIVISION OV7670 SENSOR DRIVER
-P:     Jonathan Corbet
+P:     Jonathan Corbet
 M:     corbet@lwn.net
 L:     video4linux-list@redhat.com
 S:     Maintained
@@ -3217,7 +3216,7 @@ T:        git kernel.org:/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git
 S:     Supported
 
 PCI HOTPLUG CORE
-P:     Kristen Carlson Accardi
+P:     Kristen Carlson Accardi
 M:     kristen.c.accardi@intel.com
 S:     Supported
 
@@ -3656,7 +3655,7 @@ M:        jmorris@namei.org
 P:     Eric Paris
 M:     eparis@parisplace.org
 L:     linux-kernel@vger.kernel.org (kernel issues)
-L:     selinux@tycho.nsa.gov (subscribers-only, general discussion)
+L:     selinux@tycho.nsa.gov (subscribers-only, general discussion)
 W:     http://www.nsa.gov/selinux
 S:     Supported
 
@@ -3732,7 +3731,7 @@ S:        Maintained
 SIS 96X I2C/SMBUS DRIVER
 P:     Mark M. Hoffman
 M:     mhoffman@lightlink.com
-L:     lm-sensors@lm-sensors.org
+L:     i2c@lm-sensors.org
 S:     Maintained
 
 SIS FRAMEBUFFER DRIVER
@@ -3774,10 +3773,10 @@ M:      bn@niasdigital.com
 S:     Maintained
 
 SOC-CAMERA V4L2 SUBSYSTEM
-P:     Guennadi Liakhovetski
-M:     g.liakhovetski@gmx.de
-L:     video4linux-list@redhat.com
-S:     Maintained
+P:     Guennadi Liakhovetski
+M:     g.liakhovetski@gmx.de
+L:     video4linux-list@redhat.com
+S:     Maintained
 
 SOFTWARE RAID (Multiple Disks) SUPPORT
 P:     Ingo Molnar
@@ -3839,11 +3838,12 @@ S:      Maintained
 
 SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT
 P:     Liam Girdwood
-M:     liam.girdwood@wolfsonmicro.com
+M:     lrg@slimlogic.co.uk
 P:     Mark Brown
 M:     broonie@opensource.wolfsonmicro.com
 T:     git opensource.wolfsonmicro.com/linux-2.6-asoc
 L:     alsa-devel@alsa-project.org (subscribers-only)
+W:     http://alsa-project.org/main/index.php/ASoC
 S:     Supported
 
 SPI SUBSYSTEM
@@ -3931,7 +3931,7 @@ S:        Maintained
 
 STARMODE RADIO IP (STRIP) PROTOCOL DRIVER
 W:     http://mosquitonet.Stanford.EDU/strip.html
-S:     Unsupported ?
+S:     Orphan
 
 STRADIS MPEG-2 DECODER DRIVER
 P:     Nathan Laredo
@@ -4012,9 +4012,9 @@ T:        git repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git
 S:     Maintained
 
 TI FLASH MEDIA INTERFACE DRIVER
-P:      Alex Dubov
-M:      oakad@yahoo.com
-S:      Maintained
+P:     Alex Dubov
+M:     oakad@yahoo.com
+S:     Maintained
 
 TI OMAP MMC INTERFACE DRIVER
 P:     Carlos Aguiar, Anderson Briglia and Syed Khasim
@@ -4166,13 +4166,13 @@ USB BLOCK DRIVER (UB ub)
 P:     Pete Zaitcev
 M:     zaitcev@redhat.com
 L:     linux-kernel@vger.kernel.org
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Supported
 
 USB CDC ETHERNET DRIVER
 P:     Greg Kroah-Hartman
 M:     greg@kroah.com
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Maintained
 W:     http://www.kroah.com/linux-usb/
 
@@ -4199,13 +4199,13 @@ S:      Maintained
 USB EHCI DRIVER
 P:     David Brownell
 M:     dbrownell@users.sourceforge.net
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Odd Fixes
 
 USB ET61X[12]51 DRIVER
 P:     Luca Risolia
 M:     luca.risolia@studio.unibo.it
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 L:     video4linux-list@redhat.com
 W:     http://www.linux-projects.org
 S:     Maintained
@@ -4213,33 +4213,33 @@ S:      Maintained
 USB GADGET/PERIPHERAL SUBSYSTEM
 P:     David Brownell
 M:     dbrownell@users.sourceforge.net
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 W:     http://www.linux-usb.org/gadget
 S:     Maintained
 
 USB HID/HIDBP DRIVERS (USB KEYBOARDS, MICE, REMOTE CONTROLS, ...)
 P:     Jiri Kosina
 M:     jkosina@suse.cz
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 T:     git kernel.org:/pub/scm/linux/kernel/git/jikos/hid.git
 S:     Maintained
 
 USB ISP116X DRIVER
 P:     Olav Kongas
 M:     ok@artecdesign.ee
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Maintained
 
 USB KAWASAKI LSI DRIVER
 P:     Oliver Neukum
 M:     oliver@neukum.name
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Maintained
 
 USB MASS STORAGE DRIVER
 P:     Matthew Dharm
 M:     mdharm-usb@one-eyed-alien.net
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 L:     usb-storage@lists.one-eyed-alien.net
 S:     Maintained
 W:     http://www.one-eyed-alien.net/~mdharm/linux-usb/
@@ -4247,26 +4247,26 @@ W:      http://www.one-eyed-alien.net/~mdharm/linux-usb/
 USB OHCI DRIVER
 P:     David Brownell
 M:     dbrownell@users.sourceforge.net
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Odd Fixes
 
 USB OPTION-CARD DRIVER
 P:     Matthias Urlichs
 M:     smurf@smurf.noris.de
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Maintained
 
 USB OV511 DRIVER
 P:     Mark McClelland
 M:     mmcclell@bigfoot.com
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 W:     http://alpha.dyndns.org/ov511/
 S:     Maintained
 
 USB PEGASUS DRIVER
 P:     Petko Manolov
 M:     petkan@users.sourceforge.net
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 L:     netdev@vger.kernel.org
 W:     http://pegasus2.sourceforge.net/
 S:     Maintained
@@ -4274,13 +4274,13 @@ S:      Maintained
 USB PRINTER DRIVER (usblp)
 P:     Pete Zaitcev
 M:     zaitcev@redhat.com
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Supported
 
 USB RTL8150 DRIVER
 P:     Petko Manolov
 M:     petkan@users.sourceforge.net
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 L:     netdev@vger.kernel.org
 W:     http://pegasus2.sourceforge.net/
 S:     Maintained
@@ -4288,20 +4288,20 @@ S:      Maintained
 USB SE401 DRIVER
 P:     Jeroen Vreeken
 M:     pe1rxq@amsat.org
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 W:     http://www.chello.nl/~j.vreeken/se401/
 S:     Maintained
 
 USB SERIAL BELKIN F5U103 DRIVER
 P:     William Greathouse
 M:     wgreathouse@smva.com
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Maintained
 
 USB SERIAL CYPRESS M8 DRIVER
 P:     Lonnie Mendez
 M:     dignome@gmail.com
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Maintained
 W:     http://geocities.com/i0xox0i
 W:     http://firstlight.net/cvs
@@ -4316,39 +4316,39 @@ USB SERIAL DIGI ACCELEPORT DRIVER
 P:     Peter Berger and Al Borchers
 M:     pberger@brimson.com
 M:     alborchers@steinerpoint.com
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Maintained
 
 USB SERIAL DRIVER
 P:     Greg Kroah-Hartman
 M:     gregkh@suse.de
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Supported
 
 USB SERIAL EMPEG EMPEG-CAR MARK I/II DRIVER
 P:     Gary Brubaker
 M:     xavyer@ix.netcom.com
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Maintained
 
 USB SERIAL KEYSPAN DRIVER
 P:     Greg Kroah-Hartman
 M:     greg@kroah.com
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 W:     http://www.kroah.com/linux/
 S:     Maintained
 
 USB SERIAL WHITEHEAT DRIVER
 P:     Support Department
 M:     support@connecttech.com
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 W:     http://www.connecttech.com
 S:     Supported
 
 USB SN9C1xx DRIVER
 P:     Luca Risolia
 M:     luca.risolia@studio.unibo.it
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 L:     video4linux-list@redhat.com
 W:     http://www.linux-projects.org
 S:     Maintained
@@ -4356,7 +4356,7 @@ S:        Maintained
 USB SUBSYSTEM
 P:     Greg Kroah-Hartman
 M:     gregkh@suse.de
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 W:     http://www.linux-usb.org
 T:     quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
 S:     Supported
@@ -4364,7 +4364,7 @@ S:        Supported
 USB UHCI DRIVER
 P:     Alan Stern
 M:     stern@rowland.harvard.edu
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Maintained
 
 USB "USBNET" DRIVER FRAMEWORK
@@ -4385,7 +4385,7 @@ S:        Maintained
 USB W996[87]CF DRIVER
 P:     Luca Risolia
 M:     luca.risolia@studio.unibo.it
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 L:     video4linux-list@redhat.com
 W:     http://www.linux-projects.org
 S:     Maintained
@@ -4399,7 +4399,7 @@ S:        Maintained
 USB ZC0301 DRIVER
 P:     Luca Risolia
 M:     luca.risolia@studio.unibo.it
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 L:     video4linux-list@redhat.com
 W:     http://www.linux-projects.org
 S:     Maintained
@@ -4407,14 +4407,14 @@ S:      Maintained
 USB ZD1201 DRIVER
 P:     Jeroen Vreeken
 M:     pe1rxq@amsat.org
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 W:     http://linux-lc100020.sourceforge.net
 S:     Maintained
 
 USB ZR364XX DRIVER
 P:     Antoine Jacquet
 M:     royale@zerezo.com
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 L:     video4linux-list@redhat.com
 W:     http://royale.zerezo.com/zr364xx/
 S:     Maintained
index 4ff83ea..16e3fbb 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 27
-EXTRAVERSION = -rc6
+EXTRAVERSION =
 NAME = Rotary Wombat
 
 # *DOCUMENTATION*
index aaffaec..ba8ccfe 100644 (file)
@@ -111,8 +111,6 @@ int kgdb_arch_handle_exception(int exception_vector, int signo,
        case 'D':
        case 'k':
        case 'c':
-               kgdb_contthread = NULL;
-
                /*
                 * Try to read optional parameter, pc unchanged if no parm.
                 * If this was a compiled breakpoint, we need to move
index 720c48b..aa2fc37 100644 (file)
@@ -70,9 +70,6 @@ void davinci_psc_config(unsigned int domain, unsigned int id, char enable)
 {
        u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl, mdstat_mask;
 
-       if (id < 0)
-               return;
-
        mdctl = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id);
        if (enable)
                mdctl |= 0x00000003;    /* Enable Module */
index 67e1850..b0d6b32 100644 (file)
@@ -17,9 +17,9 @@
 #include <linux/interrupt.h>
 #include <linux/clockchips.h>
 #include <linux/sched.h>
+#include <linux/cnt32_to_63.h>
 
 #include <asm/div64.h>
-#include <asm/cnt32_to_63.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
 #include <mach/pxa-regs.h>
index 1362994..b422526 100644 (file)
@@ -18,9 +18,9 @@
 #include <linux/ioport.h>
 #include <linux/sched.h>       /* just for sched_clock() - funny that */
 #include <linux/platform_device.h>
+#include <linux/cnt32_to_63.h>
 
 #include <asm/div64.h>
-#include <asm/cnt32_to_63.h>
 #include <mach/hardware.h>
 #include <asm/system.h>
 #include <asm/pgtable.h>
index bc12085..cc6b4bf 100644 (file)
@@ -1,10 +1,10 @@
 /*
  * arch/arm/mach-sa1100/include/mach/jornada720.h
  *
- * This file contains SSP/MCU communication definitions for HP Jornada 710/720/728
+ * SSP/MCU communication definitions for HP Jornada 710/720/728
  *
- * Copyright (C) 2007 Kristoffer Ericson <Kristoffer.Ericson@gmail.com>
- *  Copyright (C) 2000 John Ankcorn <jca@lcs.mit.edu>
+ * Copyright 2007,2008 Kristoffer Ericson <Kristoffer.Ericson@gmail.com>
+ *  Copyright 2000 John Ankcorn <jca@lcs.mit.edu>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -25,3 +25,8 @@
 #define PWMOFF                 0xDF
 #define TXDUMMY                        0x11
 #define ERRORCODE              0x00
+
+extern void jornada_ssp_start(void);
+extern void jornada_ssp_end(void);
+extern int jornada_ssp_inout(u8 byte);
+extern int jornada_ssp_byte(u8 byte);
index 06ea7ab..28cf369 100644 (file)
@@ -21,8 +21,8 @@
 #include <linux/slab.h>
 
 #include <mach/hardware.h>
-#include <asm/hardware/ssp.h>
 #include <mach/jornada720.h>
+#include <asm/hardware/ssp.h>
 
 static DEFINE_SPINLOCK(jornada_ssp_lock);
 static unsigned long jornada_ssp_flags;
@@ -109,12 +109,12 @@ EXPORT_SYMBOL(jornada_ssp_inout);
  * jornada_ssp_start - enable mcu
  *
  */
-int jornada_ssp_start()
+void jornada_ssp_start(void)
 {
        spin_lock_irqsave(&jornada_ssp_lock, jornada_ssp_flags);
        GPCR = GPIO_GPIO25;
        udelay(50);
-       return 0;
+       return;
 };
 EXPORT_SYMBOL(jornada_ssp_start);
 
@@ -122,11 +122,11 @@ EXPORT_SYMBOL(jornada_ssp_start);
  * jornada_ssp_end - disable mcu and turn off lock
  *
  */
-int jornada_ssp_end()
+void jornada_ssp_end(void)
 {
        GPSR = GPIO_GPIO25;
        spin_unlock_irqrestore(&jornada_ssp_lock, jornada_ssp_flags);
-       return 0;
+       return;
 };
 EXPORT_SYMBOL(jornada_ssp_end);
 
index d75e795..b638f10 100644 (file)
@@ -28,8 +28,8 @@
 #include <linux/amba/clcd.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
+#include <linux/cnt32_to_63.h>
 
-#include <asm/cnt32_to_63.h>
 #include <asm/system.h>
 #include <mach/hardware.h>
 #include <asm/io.h>
index bc1cf30..01da719 100644 (file)
@@ -316,19 +316,6 @@ static inline void omap_init_mmc_conf(const struct omap_mmc_config *mmc_conf)
                                omap_cfg_reg(MMC_DAT3);
                        }
                }
-#if defined(CONFIG_ARCH_OMAP2420)
-               if (mmc_conf->mmc[0].internal_clock) {
-                       /*
-                        * Use internal loop-back in MMC/SDIO
-                        * Module Input Clock selection
-                        */
-                       if (cpu_is_omap24xx()) {
-                               u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
-                               v |= (1 << 24); /* not used in 243x */
-                               omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
-                       }
-               }
-#endif
        }
 
 #ifdef CONFIG_ARCH_OMAP16XX
index ee4c292..dfc3443 100644 (file)
@@ -325,7 +325,7 @@ static int __init atstk1002_init(void)
 #ifdef CONFIG_BOARD_ATSTK100X_SPI1
        at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
 #endif
-#ifndef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM
+#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
        at32_add_device_mci(0, MCI_PDATA);
 #endif
 #ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM
diff --git a/arch/avr32/boot/images/.gitignore b/arch/avr32/boot/images/.gitignore
new file mode 100644 (file)
index 0000000..64ea9d0
--- /dev/null
@@ -0,0 +1,4 @@
+uImage
+uImage.srec
+vmlinux.cso
+sfdwarf.log
diff --git a/arch/avr32/kernel/.gitignore b/arch/avr32/kernel/.gitignore
new file mode 100644 (file)
index 0000000..c5f676c
--- /dev/null
@@ -0,0 +1 @@
+vmlinux.lds
index 84a7d44..11e310c 100644 (file)
@@ -58,6 +58,7 @@ EXPORT_SYMBOL(find_first_zero_bit);
 EXPORT_SYMBOL(find_next_zero_bit);
 EXPORT_SYMBOL(find_first_bit);
 EXPORT_SYMBOL(find_next_bit);
+EXPORT_SYMBOL(generic_find_next_le_bit);
 EXPORT_SYMBOL(generic_find_next_zero_le_bit);
 
 /* I/O primitives (lib/io-*.S) */
index 890286a..673178e 100644 (file)
@@ -109,3 +109,12 @@ __sys_epoll_pwait:
        rcall   sys_epoll_pwait
        sub     sp, -4
        popm    pc
+
+       .global __sys_sync_file_range
+       .type   __sys_sync_file_range,@function
+__sys_sync_file_range:
+       pushm   lr
+       st.w    --sp, ARG6
+       rcall   sys_sync_file_range
+       sub     sp, -4
+       popm    pc
index 478bda4..7ee0057 100644 (file)
@@ -275,7 +275,7 @@ sys_call_table:
        .long   sys_set_robust_list
        .long   sys_get_robust_list     /* 260 */
        .long   __sys_splice
-       .long   sys_sync_file_range
+       .long   __sys_sync_file_range
        .long   sys_tee
        .long   sys_vmsplice
        .long   __sys_epoll_pwait       /* 265 */
index b835c4c..0d98737 100644 (file)
@@ -116,15 +116,15 @@ asmlinkage void do_nmi(unsigned long ecr, struct pt_regs *regs)
        switch (ret) {
        case NOTIFY_OK:
        case NOTIFY_STOP:
-               return;
+               break;
        case NOTIFY_BAD:
                die("Fatal Non-Maskable Interrupt", regs, SIGINT);
        default:
+               printk(KERN_ALERT "Got NMI, but nobody cared. Disabling...\n");
+               nmi_disable();
                break;
        }
-
-       printk(KERN_ALERT "Got NMI, but nobody cared. Disabling...\n");
-       nmi_disable();
+       nmi_exit();
 }
 
 asmlinkage void do_critical_exception(unsigned long ecr, struct pt_regs *regs)
index c6b91de..997b33b 100644 (file)
@@ -123,6 +123,36 @@ ENTRY(find_next_bit)
        brgt    1b
        retal   r11
 
+ENTRY(generic_find_next_le_bit)
+       lsr     r8, r10, 5
+       sub     r9, r11, r10
+       retle   r11
+
+       lsl     r8, 2
+       add     r12, r8
+       andl    r10, 31, COH
+       breq    1f
+
+       /* offset is not word-aligned. Handle the first (32 - r10) bits */
+       ldswp.w r8, r12[0]
+       sub     r12, -4
+       lsr     r8, r8, r10
+       brne    .L_found
+
+       /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */
+       add     r9, r10
+       sub     r9, 32
+       retle   r11
+
+       /* Main loop. offset must be word-aligned */
+1:     ldswp.w r8, r12[0]
+       cp.w    r8, 0
+       brne    .L_found
+       sub     r12, -4
+       sub     r9, 32
+       brgt    1b
+       retal   r11
+
 ENTRY(generic_find_next_zero_le_bit)
        lsr     r8, r10, 5
        sub     r9, r11, r10
index f667998..1a873b3 100644 (file)
@@ -11,6 +11,9 @@
 #include <asm-generic/sections.h>
 
 extern char __per_cpu_start[], __per_cpu_end[], __phys_per_cpu_start[];
+#ifdef CONFIG_SMP
+extern char __cpu0_per_cpu[];
+#endif
 extern char __start___vtop_patchlist[], __end___vtop_patchlist[];
 extern char __start___rse_patchlist[], __end___rse_patchlist[];
 extern char __start___mckinley_e9_bundles[], __end___mckinley_e9_bundles[];
index d45f215..51b75ce 100644 (file)
@@ -1232,9 +1232,10 @@ efi_initialize_iomem_resources(struct resource *code_resource,
                                if (md->attribute & EFI_MEMORY_WP) {
                                        name = "System ROM";
                                        flags |= IORESOURCE_READONLY;
-                               } else {
+                               } else if (md->attribute == EFI_MEMORY_UC)
+                                       name = "Uncached RAM";
+                               else
                                        name = "System RAM";
-                               }
                                break;
 
                        case EFI_ACPI_MEMORY_NVS:
index 8bdea8e..66e491d 100644 (file)
@@ -367,16 +367,17 @@ start_ap:
        ;;
 #else
 (isAP) br.few 2f
-       mov r20=r19
-       sub r19=r19,r18
+       movl r20=__cpu0_per_cpu
        ;;
        shr.u r18=r18,3
 1:
-       ld8 r21=[r20],8;;
-       st8[r19]=r21,8
+       ld8 r21=[r19],8;;
+       st8[r20]=r21,8
        adds r18=-1,r18;;
        cmp4.lt p7,p6=0,r18
 (p7)   br.cond.dptk.few 1b
+       mov r19=r20
+       ;;
 2:
 #endif
        tpa r19=r19
index c27d5b2..de636b2 100644 (file)
@@ -616,7 +616,9 @@ setup_arch (char **cmdline_p)
                ia64_mca_init();
 
        platform_setup(cmdline_p);
+#ifndef CONFIG_IA64_HP_SIM
        check_sal_cache_flush();
+#endif
        paging_init();
 }
 
index de71da8..10a7d47 100644 (file)
@@ -215,9 +215,6 @@ SECTIONS
   /* Per-cpu data: */
   percpu : { } :percpu
   . = ALIGN(PERCPU_PAGE_SIZE);
-#ifdef CONFIG_SMP
-  . = . + PERCPU_PAGE_SIZE;    /* cpu0 per-cpu space */
-#endif
   __phys_per_cpu_start = .;
   .data.percpu PERCPU_ADDR : AT(__phys_per_cpu_start - LOAD_OFFSET)
        {
@@ -233,6 +230,11 @@ SECTIONS
   data : { } :data
   .data : AT(ADDR(.data) - LOAD_OFFSET)
        {
+#ifdef CONFIG_SMP
+  . = ALIGN(PERCPU_PAGE_SIZE);
+               __cpu0_per_cpu = .;
+  . = . + PERCPU_PAGE_SIZE;    /* cpu0 per-cpu space */
+#endif
                DATA_DATA
                *(.data1)
                *(.gnu.linkonce.d*)
index 7a37d06..cd0d1a7 100644 (file)
@@ -38,6 +38,7 @@
 #include <asm/cacheflush.h>
 #include <asm/div64.h>
 #include <asm/tlb.h>
+#include <asm/elf.h>
 
 #include "misc.h"
 #include "vti.h"
@@ -61,12 +62,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
        { NULL }
 };
 
-
-struct fdesc{
-    unsigned long ip;
-    unsigned long gp;
-};
-
 static void kvm_flush_icache(unsigned long start, unsigned long len)
 {
        int l;
index e566ff4..0ee085e 100644 (file)
@@ -163,7 +163,7 @@ per_cpu_init (void)
         * get_zeroed_page().
         */
        if (first_time) {
-               void *cpu0_data = __phys_per_cpu_start - PERCPU_PAGE_SIZE;
+               void *cpu0_data = __cpu0_per_cpu;
 
                first_time=0;
 
index 78026aa..d8c5fcd 100644 (file)
@@ -144,7 +144,7 @@ static void *per_cpu_node_setup(void *cpu_data, int node)
 
        for_each_possible_early_cpu(cpu) {
                if (cpu == 0) {
-                       void *cpu0_data = __phys_per_cpu_start - PERCPU_PAGE_SIZE;
+                       void *cpu0_data = __cpu0_per_cpu;
                        __per_cpu_offset[cpu] = (char*)cpu0_data -
                                __per_cpu_start;
                } else if (node == node_cpuid[cpu].nid) {
index a5f864c..f57113f 100644 (file)
@@ -216,10 +216,6 @@ config MEMORY_SIZE
        default "01000000" if PLAT_M32104UT
        default "00800000" if PLAT_OAKS32R
 
-config NOHIGHMEM
-       bool
-       default y
-
 config ARCH_DISCONTIGMEM_ENABLE
        bool "Internal RAM Support"
        depends on CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP || CHIP_M32104
@@ -410,11 +406,7 @@ config PCI_DIRECT
 source "drivers/pci/Kconfig"
 
 config ISA
-       bool "ISA support"
-       help
-         Find out whether you have ISA slots on your motherboard.  ISA is the
-         name of a bus system, i.e. the way the CPU talks to the other stuff
-         inside your box.  If you have ISA, say Y, otherwise N.
+       bool
 
 source "drivers/pcmcia/Kconfig"
 
index d4eaa2f..612d35b 100644 (file)
@@ -143,7 +143,7 @@ ret_from_intr:
        and3    r4, r4, #0x8000         ; check BSM bit
 #endif
        beqz    r4, resume_kernel
-ENTRY(resume_userspace)
+resume_userspace:
        DISABLE_INTERRUPTS(r4)          ; make sure we don't miss an interrupt
                                        ; setting need_resched or sigpending
                                        ; between sampling and the iret
index dab7436..4018077 100644 (file)
@@ -29,7 +29,6 @@ __INITDATA
        .global _end
 ENTRY(stext)
 ENTRY(_stext)
-ENTRY(startup_32)
        /* Setup up the stack pointer */
        LDIMM   (r0, spi_stack_top)
        LDIMM   (r1, spu_stack_top)
index d0c5b0b..2aeae46 100644 (file)
@@ -22,9 +22,6 @@
 #include <linux/module.h>
 #include <asm/uaccess.h>
 
-atomic_t irq_err_count;
-atomic_t irq_mis_count;
-
 /*
  * Generic, controller-independent functions:
  */
@@ -63,9 +60,6 @@ int show_interrupts(struct seq_file *p, void *v)
                seq_putc(p, '\n');
 skip:
                spin_unlock_irqrestore(&irq_desc[i].lock, flags);
-       } else if (i == NR_IRQS) {
-               seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
-               seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
        }
        return 0;
 }
index 16bcb18..22624b5 100644 (file)
@@ -14,6 +14,7 @@
 #include <asm/delay.h>
 #include <asm/irq.h>
 #include <asm/tlbflush.h>
+#include <asm/pgtable.h>
 
 /* platform dependent support */
 EXPORT_SYMBOL(boot_cpu_data);
@@ -65,6 +66,7 @@ EXPORT_SYMBOL(memset);
 EXPORT_SYMBOL(copy_page);
 EXPORT_SYMBOL(clear_page);
 EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(empty_zero_page);
 
 EXPORT_SYMBOL(_inb);
 EXPORT_SYMBOL(_inw);
index a689e29..5be4faa 100644 (file)
@@ -35,8 +35,6 @@
 
 #include <linux/err.h>
 
-static int hlt_counter=0;
-
 /*
  * Return saved PC of a blocked thread.
  */
@@ -48,31 +46,16 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
 /*
  * Powermanagement idle function, if any..
  */
-void (*pm_idle)(void) = NULL;
-EXPORT_SYMBOL(pm_idle);
+static void (*pm_idle)(void) = NULL;
 
 void (*pm_power_off)(void) = NULL;
 EXPORT_SYMBOL(pm_power_off);
 
-void disable_hlt(void)
-{
-       hlt_counter++;
-}
-
-EXPORT_SYMBOL(disable_hlt);
-
-void enable_hlt(void)
-{
-       hlt_counter--;
-}
-
-EXPORT_SYMBOL(enable_hlt);
-
 /*
  * We use this is we don't have any better
  * idle routine..
  */
-void default_idle(void)
+static void default_idle(void)
 {
        /* M32R_FIXME: Please use "cpu_sleep" mode.  */
        cpu_relax();
@@ -260,15 +243,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long spu,
        return 0;
 }
 
-/*
- * Capture the user space registers if the task is not running (in user space)
- */
-int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
-{
-       /* M32R_FIXME */
-       return 1;
-}
-
 asmlinkage int sys_fork(unsigned long r0, unsigned long r1, unsigned long r2,
        unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6,
        struct pt_regs regs)
index 7577f97..929e5c9 100644 (file)
@@ -84,7 +84,7 @@ void smp_send_timer(void);
 void smp_ipi_timer_interrupt(struct pt_regs *);
 void smp_local_timer_interrupt(void);
 
-void send_IPI_allbutself(int, int);
+static void send_IPI_allbutself(int, int);
 static void send_IPI_mask(cpumask_t, int, int);
 unsigned long send_IPI_mask_phys(cpumask_t, int, int);
 
@@ -722,7 +722,7 @@ void smp_local_timer_interrupt(void)
  * ---------- --- --------------------------------------------------------
  *
  *==========================================================================*/
-void send_IPI_allbutself(int ipi_num, int try)
+static void send_IPI_allbutself(int ipi_num, int try)
 {
        cpumask_t cpumask;
 
index 994cc15..6ea0177 100644 (file)
@@ -34,7 +34,6 @@
 #include <asm/hw_irq.h>
 
 #ifdef CONFIG_SMP
-extern void send_IPI_allbutself(int, int);
 extern void smp_local_timer_interrupt(void);
 #endif
 
@@ -188,7 +187,7 @@ static long last_rtc_update = 0;
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
-irqreturn_t timer_interrupt(int irq, void *dev_id)
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
 {
 #ifndef CONFIG_SMP
        profile_tick(CPU_PROFILING);
@@ -228,7 +227,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-struct irqaction irq0 = {
+static struct irqaction irq0 = {
        .handler = timer_interrupt,
        .flags = IRQF_DISABLED,
        .mask = CPU_MASK_NONE,
index 46159a4..03b14e5 100644 (file)
@@ -61,7 +61,7 @@ extern unsigned long  eit_vector[];
        ((unsigned long)func - (unsigned long)eit_vector - entry*4)/4 \
        + 0xff000000UL
 
-void   set_eit_vector_entries(void)
+static void set_eit_vector_entries(void)
 {
        extern void default_eit_handler(void);
        extern void system_call(void);
@@ -121,9 +121,9 @@ void __init trap_init(void)
        cpu_init();
 }
 
-int kstack_depth_to_print = 24;
+static int kstack_depth_to_print = 24;
 
-void show_trace(struct task_struct *task, unsigned long *stack)
+static void show_trace(struct task_struct *task, unsigned long *stack)
 {
        unsigned long addr;
 
@@ -224,7 +224,7 @@ bad:
        printk("\n");
 }
 
-DEFINE_SPINLOCK(die_lock);
+static DEFINE_SPINLOCK(die_lock);
 
 void die(const char * str, struct pt_regs * regs, long err)
 {
index 59bfc34..ced549b 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <linux/param.h>
+#include <linux/module.h>
 #ifdef CONFIG_SMP
 #include <linux/sched.h>
 #include <asm/current.h>
@@ -121,3 +122,4 @@ void __ndelay(unsigned long nsecs)
 {
        __const_udelay(nsecs * 0x00005);  /* 2**32 / 1000000000 (rounded up) */
 }
+EXPORT_SYMBOL(__ndelay);
index 49896a2..1e06d23 100644 (file)
@@ -211,6 +211,7 @@ config MIPS_MALTA
        select SYS_SUPPORTS_64BIT_KERNEL
        select SYS_SUPPORTS_BIG_ENDIAN
        select SYS_SUPPORTS_LITTLE_ENDIAN
+       select SYS_SUPPORTS_MIPS_CMP if BROKEN  # because SYNC_R4K is broken
        select SYS_SUPPORTS_MULTITHREADING
        select SYS_SUPPORTS_SMARTMIPS
        help
@@ -1403,7 +1404,6 @@ config MIPS_MT_SMTC
        depends on CPU_MIPS32_R2
        #depends on CPU_MIPS64_R2               # once there is hardware ...
        depends on SYS_SUPPORTS_MULTITHREADING
-       select GENERIC_CLOCKEVENTS_BROADCAST
        select CPU_MIPSR2_IRQ_VI
        select CPU_MIPSR2_IRQ_EI
        select MIPS_MT
@@ -1451,32 +1451,17 @@ config MIPS_VPE_LOADER
          Includes a loader for loading an elf relocatable object
          onto another VPE and running it.
 
-config MIPS_MT_SMTC_INSTANT_REPLAY
-       bool "Low-latency Dispatch of Deferred SMTC IPIs"
-       depends on MIPS_MT_SMTC && !PREEMPT
-       default y
-       help
-         SMTC pseudo-interrupts between TCs are deferred and queued
-         if the target TC is interrupt-inhibited (IXMT). In the first
-         SMTC prototypes, these queued IPIs were serviced on return
-         to user mode, or on entry into the kernel idle loop. The
-         INSTANT_REPLAY option dispatches them as part of local_irq_restore()
-         processing, which adds runtime overhead (hence the option to turn
-         it off), but ensures that IPIs are handled promptly even under
-         heavy I/O interrupt load.
-
 config MIPS_MT_SMTC_IM_BACKSTOP
        bool "Use per-TC register bits as backstop for inhibited IM bits"
        depends on MIPS_MT_SMTC
-       default y
+       default n
        help
          To support multiple TC microthreads acting as "CPUs" within
          a VPE, VPE-wide interrupt mask bits must be specially manipulated
          during interrupt handling. To support legacy drivers and interrupt
          controller management code, SMTC has a "backstop" to track and
          if necessary restore the interrupt mask. This has some performance
-         impact on interrupt service overhead. Disable it only if you know
-         what you are doing.
+         impact on interrupt service overhead.
 
 config MIPS_MT_SMTC_IRQAFF
        bool "Support IRQ affinity API"
@@ -1486,10 +1471,8 @@ config MIPS_MT_SMTC_IRQAFF
          Enables SMP IRQ affinity API (/proc/irq/*/smp_affinity, etc.)
          for SMTC Linux kernel. Requires platform support, of which
          an example can be found in the MIPS kernel i8259 and Malta
-         platform code.  It is recommended that MIPS_MT_SMTC_INSTANT_REPLAY
-         be enabled if MIPS_MT_SMTC_IRQAFF is used. Adds overhead to
-         interrupt dispatch, and should be used only if you know what
-         you are doing.
+         platform code.  Adds some overhead to interrupt dispatch, and
+         should be used only if you know what you are doing.
 
 config MIPS_VPE_LOADER_TOM
        bool "Load VPE program into memory hidden from linux"
@@ -1517,6 +1500,18 @@ config MIPS_APSP_KSPD
          "exit" syscall notifying other kernel modules the SP program is
          exiting.  You probably want to say yes here.
 
+config MIPS_CMP
+       bool "MIPS CMP framework support"
+       depends on SYS_SUPPORTS_MIPS_CMP
+       select SYNC_R4K if BROKEN
+       select SYS_SUPPORTS_SMP
+       select SYS_SUPPORTS_SCHED_SMT if SMP
+       select WEAK_ORDERING
+       default n
+       help
+         This is a placeholder option for the GCMP work. It will need to
+         be handled differently...
+
 config SB1_PASS_1_WORKAROUNDS
        bool
        depends on CPU_SB1_PASS_1
@@ -1693,6 +1688,9 @@ config SMP
 config SMP_UP
        bool
 
+config SYS_SUPPORTS_MIPS_CMP
+       bool
+
 config SYS_SUPPORTS_SMP
        bool
 
@@ -1740,17 +1738,6 @@ config NR_CPUS
          performance should round up your number of processors to the next
          power of two.
 
-config MIPS_CMP
-       bool "MIPS CMP framework support"
-       depends on SMP
-       select SYNC_R4K
-       select SYS_SUPPORTS_SCHED_SMT
-       select WEAK_ORDERING
-       default n
-       help
-         This is a placeholder option for the GCMP work. It will need to
-         be handled differently...
-
 source "kernel/time/Kconfig"
 
 #
index b485d94..e660ddd 100644 (file)
@@ -48,7 +48,7 @@ static void au1xxx_gpio2_write(unsigned gpio, int value)
 {
        gpio -= AU1XXX_GPIO_BASE;
 
-       gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << gpio) | (value << gpio);
+       gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << gpio) | ((!!value) << gpio);
 }
 
 static int au1xxx_gpio2_direction_input(unsigned gpio)
@@ -61,7 +61,8 @@ static int au1xxx_gpio2_direction_input(unsigned gpio)
 static int au1xxx_gpio2_direction_output(unsigned gpio, int value)
 {
        gpio -= AU1XXX_GPIO_BASE;
-       gpio2->dir = (0x01 << gpio) | (value << gpio);
+       gpio2->dir |= 0x01 << gpio;
+       gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << gpio) | ((!!value) << gpio);
        return 0;
 }
 
@@ -90,6 +91,7 @@ static int au1xxx_gpio1_direction_input(unsigned gpio)
 static int au1xxx_gpio1_direction_output(unsigned gpio, int value)
 {
        gpio1->trioutclr = (0x01 & gpio);
+       au1xxx_gpio1_write(gpio, value);
        return 0;
 }
 
index 706f939..25775cb 100644 (file)
@@ -10,6 +10,7 @@ obj-y         += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
 
 obj-$(CONFIG_CEVT_BCM1480)     += cevt-bcm1480.o
 obj-$(CONFIG_CEVT_R4K)         += cevt-r4k.o
+obj-$(CONFIG_MIPS_MT_SMTC)     += cevt-smtc.o
 obj-$(CONFIG_CEVT_DS1287)      += cevt-ds1287.o
 obj-$(CONFIG_CEVT_GT641XX)     += cevt-gt641xx.o
 obj-$(CONFIG_CEVT_SB1250)      += cevt-sb1250.o
index 24a2d90..4a4c59f 100644 (file)
 
 #include <asm/smtc_ipi.h>
 #include <asm/time.h>
+#include <asm/cevt-r4k.h>
+
+/*
+ * The SMTC Kernel for the 34K, 1004K, et. al. replaces several
+ * of these routines with SMTC-specific variants.
+ */
+
+#ifndef CONFIG_MIPS_MT_SMTC
 
 static int mips_next_event(unsigned long delta,
                            struct clock_event_device *evt)
@@ -19,60 +27,27 @@ static int mips_next_event(unsigned long delta,
        unsigned int cnt;
        int res;
 
-#ifdef CONFIG_MIPS_MT_SMTC
-       {
-       unsigned long flags, vpflags;
-       local_irq_save(flags);
-       vpflags = dvpe();
-#endif
        cnt = read_c0_count();
        cnt += delta;
        write_c0_compare(cnt);
        res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0;
-#ifdef CONFIG_MIPS_MT_SMTC
-       evpe(vpflags);
-       local_irq_restore(flags);
-       }
-#endif
        return res;
 }
 
-static void mips_set_mode(enum clock_event_mode mode,
-                          struct clock_event_device *evt)
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+void mips_set_clock_mode(enum clock_event_mode mode,
+                               struct clock_event_device *evt)
 {
        /* Nothing to do ...  */
 }
 
-static DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device);
-static int cp0_timer_irq_installed;
+DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device);
+int cp0_timer_irq_installed;
 
-/*
- * Timer ack for an R4k-compatible timer of a known frequency.
- */
-static void c0_timer_ack(void)
-{
-       write_c0_compare(read_c0_compare());
-}
+#ifndef CONFIG_MIPS_MT_SMTC
 
-/*
- * Possibly handle a performance counter interrupt.
- * Return true if the timer interrupt should not be checked
- */
-static inline int handle_perf_irq(int r2)
-{
-       /*
-        * The performance counter overflow interrupt may be shared with the
-        * timer interrupt (cp0_perfcount_irq < 0). If it is and a
-        * performance counter has overflowed (perf_irq() == IRQ_HANDLED)
-        * and we can't reliably determine if a counter interrupt has also
-        * happened (!r2) then don't check for a timer interrupt.
-        */
-       return (cp0_perfcount_irq < 0) &&
-               perf_irq() == IRQ_HANDLED &&
-               !r2;
-}
-
-static irqreturn_t c0_compare_interrupt(int irq, void *dev_id)
+irqreturn_t c0_compare_interrupt(int irq, void *dev_id)
 {
        const int r2 = cpu_has_mips_r2;
        struct clock_event_device *cd;
@@ -93,12 +68,8 @@ static irqreturn_t c0_compare_interrupt(int irq, void *dev_id)
         * interrupt.  Being the paranoiacs we are we check anyway.
         */
        if (!r2 || (read_c0_cause() & (1 << 30))) {
-               c0_timer_ack();
-#ifdef CONFIG_MIPS_MT_SMTC
-               if (cpu_data[cpu].vpe_id)
-                       goto out;
-               cpu = 0;
-#endif
+               /* Clear Count/Compare Interrupt */
+               write_c0_compare(read_c0_compare());
                cd = &per_cpu(mips_clockevent_device, cpu);
                cd->event_handler(cd);
        }
@@ -107,65 +78,16 @@ out:
        return IRQ_HANDLED;
 }
 
-static struct irqaction c0_compare_irqaction = {
+#endif /* Not CONFIG_MIPS_MT_SMTC */
+
+struct irqaction c0_compare_irqaction = {
        .handler = c0_compare_interrupt,
-#ifdef CONFIG_MIPS_MT_SMTC
-       .flags = IRQF_DISABLED,
-#else
        .flags = IRQF_DISABLED | IRQF_PERCPU,
-#endif
        .name = "timer",
 };
 
-#ifdef CONFIG_MIPS_MT_SMTC
-DEFINE_PER_CPU(struct clock_event_device, smtc_dummy_clockevent_device);
-
-static void smtc_set_mode(enum clock_event_mode mode,
-                          struct clock_event_device *evt)
-{
-}
-
-static void mips_broadcast(cpumask_t mask)
-{
-       unsigned int cpu;
-
-       for_each_cpu_mask(cpu, mask)
-               smtc_send_ipi(cpu, SMTC_CLOCK_TICK, 0);
-}
-
-static void setup_smtc_dummy_clockevent_device(void)
-{
-       //uint64_t mips_freq = mips_hpt_^frequency;
-       unsigned int cpu = smp_processor_id();
-       struct clock_event_device *cd;
 
-       cd = &per_cpu(smtc_dummy_clockevent_device, cpu);
-
-       cd->name                = "SMTC";
-       cd->features            = CLOCK_EVT_FEAT_DUMMY;
-
-       /* Calculate the min / max delta */
-       cd->mult        = 0; //div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32);
-       cd->shift               = 0; //32;
-       cd->max_delta_ns        = 0; //clockevent_delta2ns(0x7fffffff, cd);
-       cd->min_delta_ns        = 0; //clockevent_delta2ns(0x30, cd);
-
-       cd->rating              = 200;
-       cd->irq                 = 17; //-1;
-//     if (cpu)
-//             cd->cpumask     = CPU_MASK_ALL; // cpumask_of_cpu(cpu);
-//     else
-               cd->cpumask     = cpumask_of_cpu(cpu);
-
-       cd->set_mode            = smtc_set_mode;
-
-       cd->broadcast           = mips_broadcast;
-
-       clockevents_register_device(cd);
-}
-#endif
-
-static void mips_event_handler(struct clock_event_device *dev)
+void mips_event_handler(struct clock_event_device *dev)
 {
 }
 
@@ -177,7 +99,23 @@ static int c0_compare_int_pending(void)
        return (read_c0_cause() >> cp0_compare_irq) & 0x100;
 }
 
-static int c0_compare_int_usable(void)
+/*
+ * Compare interrupt can be routed and latched outside the core,
+ * so a single execution hazard barrier may not be enough to give
+ * it time to clear as seen in the Cause register.  4 time the
+ * pipeline depth seems reasonably conservative, and empirically
+ * works better in configurations with high CPU/bus clock ratios.
+ */
+
+#define compare_change_hazard() \
+       do { \
+               irq_disable_hazard(); \
+               irq_disable_hazard(); \
+               irq_disable_hazard(); \
+               irq_disable_hazard(); \
+       } while (0)
+
+int c0_compare_int_usable(void)
 {
        unsigned int delta;
        unsigned int cnt;
@@ -187,7 +125,7 @@ static int c0_compare_int_usable(void)
         */
        if (c0_compare_int_pending()) {
                write_c0_compare(read_c0_count());
-               irq_disable_hazard();
+               compare_change_hazard();
                if (c0_compare_int_pending())
                        return 0;
        }
@@ -196,7 +134,7 @@ static int c0_compare_int_usable(void)
                cnt = read_c0_count();
                cnt += delta;
                write_c0_compare(cnt);
-               irq_disable_hazard();
+               compare_change_hazard();
                if ((int)(read_c0_count() - cnt) < 0)
                    break;
                /* increase delta if the timer was already expired */
@@ -205,11 +143,12 @@ static int c0_compare_int_usable(void)
        while ((int)(read_c0_count() - cnt) <= 0)
                ;       /* Wait for expiry  */
 
+       compare_change_hazard();
        if (!c0_compare_int_pending())
                return 0;
 
        write_c0_compare(read_c0_count());
-       irq_disable_hazard();
+       compare_change_hazard();
        if (c0_compare_int_pending())
                return 0;
 
@@ -219,6 +158,8 @@ static int c0_compare_int_usable(void)
        return 1;
 }
 
+#ifndef CONFIG_MIPS_MT_SMTC
+
 int __cpuinit mips_clockevent_init(void)
 {
        uint64_t mips_freq = mips_hpt_frequency;
@@ -229,17 +170,6 @@ int __cpuinit mips_clockevent_init(void)
        if (!cpu_has_counter || !mips_hpt_frequency)
                return -ENXIO;
 
-#ifdef CONFIG_MIPS_MT_SMTC
-       setup_smtc_dummy_clockevent_device();
-
-       /*
-        * On SMTC we only register VPE0's compare interrupt as clockevent
-        * device.
-        */
-       if (cpu)
-               return 0;
-#endif
-
        if (!c0_compare_int_usable())
                return -ENXIO;
 
@@ -265,13 +195,9 @@ int __cpuinit mips_clockevent_init(void)
 
        cd->rating              = 300;
        cd->irq                 = irq;
-#ifdef CONFIG_MIPS_MT_SMTC
-       cd->cpumask             = CPU_MASK_ALL;
-#else
        cd->cpumask             = cpumask_of_cpu(cpu);
-#endif
        cd->set_next_event      = mips_next_event;
-       cd->set_mode            = mips_set_mode;
+       cd->set_mode            = mips_set_clock_mode;
        cd->event_handler       = mips_event_handler;
 
        clockevents_register_device(cd);
@@ -281,12 +207,9 @@ int __cpuinit mips_clockevent_init(void)
 
        cp0_timer_irq_installed = 1;
 
-#ifdef CONFIG_MIPS_MT_SMTC
-#define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq)
-       setup_irq_smtc(irq, &c0_compare_irqaction, CPUCTR_IMASKBIT);
-#else
        setup_irq(irq, &c0_compare_irqaction);
-#endif
 
        return 0;
 }
+
+#endif /* Not CONFIG_MIPS_MT_SMTC */
diff --git a/arch/mips/kernel/cevt-smtc.c b/arch/mips/kernel/cevt-smtc.c
new file mode 100644 (file)
index 0000000..5162fe4
--- /dev/null
@@ -0,0 +1,321 @@
+/*
+ * 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 MIPS Technologies, Inc.
+ * Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org>
+ * Copyright (C) 2008 Kevin D. Kissell, Paralogos sarl
+ */
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/percpu.h>
+
+#include <asm/smtc_ipi.h>
+#include <asm/time.h>
+#include <asm/cevt-r4k.h>
+
+/*
+ * Variant clock event timer support for SMTC on MIPS 34K, 1004K
+ * or other MIPS MT cores.
+ *
+ * Notes on SMTC Support:
+ *
+ * SMTC has multiple microthread TCs pretending to be Linux CPUs.
+ * But there's only one Count/Compare pair per VPE, and Compare
+ * interrupts are taken opportunisitically by available TCs
+ * bound to the VPE with the Count register.  The new timer
+ * framework provides for global broadcasts, but we really
+ * want VPE-level multicasts for best behavior. So instead
+ * of invoking the high-level clock-event broadcast code,
+ * this version of SMTC support uses the historical SMTC
+ * multicast mechanisms "under the hood", appearing to the
+ * generic clock layer as if the interrupts are per-CPU.
+ *
+ * The approach taken here is to maintain a set of NR_CPUS
+ * virtual timers, and track which "CPU" needs to be alerted
+ * at each event.
+ *
+ * It's unlikely that we'll see a MIPS MT core with more than
+ * 2 VPEs, but we *know* that we won't need to handle more
+ * VPEs than we have "CPUs".  So NCPUs arrays of NCPUs elements
+ * is always going to be overkill, but always going to be enough.
+ */
+
+unsigned long smtc_nexttime[NR_CPUS][NR_CPUS];
+static int smtc_nextinvpe[NR_CPUS];
+
+/*
+ * Timestamps stored are absolute values to be programmed
+ * into Count register.  Valid timestamps will never be zero.
+ * If a Zero Count value is actually calculated, it is converted
+ * to be a 1, which will introduce 1 or two CPU cycles of error
+ * roughly once every four billion events, which at 1000 HZ means
+ * about once every 50 days.  If that's actually a problem, one
+ * could alternate squashing 0 to 1 and to -1.
+ */
+
+#define MAKEVALID(x) (((x) == 0L) ? 1L : (x))
+#define ISVALID(x) ((x) != 0L)
+
+/*
+ * Time comparison is subtle, as it's really truncated
+ * modular arithmetic.
+ */
+
+#define IS_SOONER(a, b, reference) \
+    (((a) - (unsigned long)(reference)) < ((b) - (unsigned long)(reference)))
+
+/*
+ * CATCHUP_INCREMENT, used when the function falls behind the counter.
+ * Could be an increasing function instead of a constant;
+ */
+
+#define CATCHUP_INCREMENT 64
+
+static int mips_next_event(unsigned long delta,
+                               struct clock_event_device *evt)
+{
+       unsigned long flags;
+       unsigned int mtflags;
+       unsigned long timestamp, reference, previous;
+       unsigned long nextcomp = 0L;
+       int vpe = current_cpu_data.vpe_id;
+       int cpu = smp_processor_id();
+       local_irq_save(flags);
+       mtflags = dmt();
+
+       /*
+        * Maintain the per-TC virtual timer
+        * and program the per-VPE shared Count register
+        * as appropriate here...
+        */
+       reference = (unsigned long)read_c0_count();
+       timestamp = MAKEVALID(reference + delta);
+       /*
+        * To really model the clock, we have to catch the case
+        * where the current next-in-VPE timestamp is the old
+        * timestamp for the calling CPE, but the new value is
+        * in fact later.  In that case, we have to do a full
+        * scan and discover the new next-in-VPE CPU id and
+        * timestamp.
+        */
+       previous = smtc_nexttime[vpe][cpu];
+       if (cpu == smtc_nextinvpe[vpe] && ISVALID(previous)
+           && IS_SOONER(previous, timestamp, reference)) {
+               int i;
+               int soonest = cpu;
+
+               /*
+                * Update timestamp array here, so that new
+                * value gets considered along with those of
+                * other virtual CPUs on the VPE.
+                */
+               smtc_nexttime[vpe][cpu] = timestamp;
+               for_each_online_cpu(i) {
+                       if (ISVALID(smtc_nexttime[vpe][i])
+                           && IS_SOONER(smtc_nexttime[vpe][i],
+                               smtc_nexttime[vpe][soonest], reference)) {
+                                   soonest = i;
+                       }
+               }
+               smtc_nextinvpe[vpe] = soonest;
+               nextcomp = smtc_nexttime[vpe][soonest];
+       /*
+        * Otherwise, we don't have to process the whole array rank,
+        * we just have to see if the event horizon has gotten closer.
+        */
+       } else {
+               if (!ISVALID(smtc_nexttime[vpe][smtc_nextinvpe[vpe]]) ||
+                   IS_SOONER(timestamp,
+                       smtc_nexttime[vpe][smtc_nextinvpe[vpe]], reference)) {
+                           smtc_nextinvpe[vpe] = cpu;
+                           nextcomp = timestamp;
+               }
+               /*
+                * Since next-in-VPE may me the same as the executing
+                * virtual CPU, we update the array *after* checking
+                * its value.
+                */
+               smtc_nexttime[vpe][cpu] = timestamp;
+       }
+
+       /*
+        * It may be that, in fact, we don't need to update Compare,
+        * but if we do, we want to make sure we didn't fall into
+        * a crack just behind Count.
+        */
+       if (ISVALID(nextcomp)) {
+               write_c0_compare(nextcomp);
+               ehb();
+               /*
+                * We never return an error, we just make sure
+                * that we trigger the handlers as quickly as
+                * we can if we fell behind.
+                */
+               while ((nextcomp - (unsigned long)read_c0_count())
+                       > (unsigned long)LONG_MAX) {
+                       nextcomp += CATCHUP_INCREMENT;
+                       write_c0_compare(nextcomp);
+                       ehb();
+               }
+       }
+       emt(mtflags);
+       local_irq_restore(flags);
+       return 0;
+}
+
+
+void smtc_distribute_timer(int vpe)
+{
+       unsigned long flags;
+       unsigned int mtflags;
+       int cpu;
+       struct clock_event_device *cd;
+       unsigned long nextstamp = 0L;
+       unsigned long reference;
+
+
+repeat:
+       for_each_online_cpu(cpu) {
+           /*
+            * Find virtual CPUs within the current VPE who have
+            * unserviced timer requests whose time is now past.
+            */
+           local_irq_save(flags);
+           mtflags = dmt();
+           if (cpu_data[cpu].vpe_id == vpe &&
+               ISVALID(smtc_nexttime[vpe][cpu])) {
+               reference = (unsigned long)read_c0_count();
+               if ((smtc_nexttime[vpe][cpu] - reference)
+                        > (unsigned long)LONG_MAX) {
+                           smtc_nexttime[vpe][cpu] = 0L;
+                           emt(mtflags);
+                           local_irq_restore(flags);
+                           /*
+                            * We don't send IPIs to ourself.
+                            */
+                           if (cpu != smp_processor_id()) {
+                               smtc_send_ipi(cpu, SMTC_CLOCK_TICK, 0);
+                           } else {
+                               cd = &per_cpu(mips_clockevent_device, cpu);
+                               cd->event_handler(cd);
+                           }
+               } else {
+                       /* Local to VPE but Valid Time not yet reached. */
+                       if (!ISVALID(nextstamp) ||
+                           IS_SOONER(smtc_nexttime[vpe][cpu], nextstamp,
+                           reference)) {
+                               smtc_nextinvpe[vpe] = cpu;
+                               nextstamp = smtc_nexttime[vpe][cpu];
+                       }
+                       emt(mtflags);
+                       local_irq_restore(flags);
+               }
+           } else {
+               emt(mtflags);
+               local_irq_restore(flags);
+
+           }
+       }
+       /* Reprogram for interrupt at next soonest timestamp for VPE */
+       if (ISVALID(nextstamp)) {
+               write_c0_compare(nextstamp);
+               ehb();
+               if ((nextstamp - (unsigned long)read_c0_count())
+                       > (unsigned long)LONG_MAX)
+                               goto repeat;
+       }
+}
+
+
+irqreturn_t c0_compare_interrupt(int irq, void *dev_id)
+{
+       int cpu = smp_processor_id();
+
+       /* If we're running SMTC, we've got MIPS MT and therefore MIPS32R2 */
+       handle_perf_irq(1);
+
+       if (read_c0_cause() & (1 << 30)) {
+               /* Clear Count/Compare Interrupt */
+               write_c0_compare(read_c0_compare());
+               smtc_distribute_timer(cpu_data[cpu].vpe_id);
+       }
+       return IRQ_HANDLED;
+}
+
+
+int __cpuinit mips_clockevent_init(void)
+{
+       uint64_t mips_freq = mips_hpt_frequency;
+       unsigned int cpu = smp_processor_id();
+       struct clock_event_device *cd;
+       unsigned int irq;
+       int i;
+       int j;
+
+       if (!cpu_has_counter || !mips_hpt_frequency)
+               return -ENXIO;
+       if (cpu == 0) {
+               for (i = 0; i < num_possible_cpus(); i++) {
+                       smtc_nextinvpe[i] = 0;
+                       for (j = 0; j < num_possible_cpus(); j++)
+                               smtc_nexttime[i][j] = 0L;
+               }
+               /*
+                * SMTC also can't have the usablility test
+                * run by secondary TCs once Compare is in use.
+                */
+               if (!c0_compare_int_usable())
+                       return -ENXIO;
+       }
+
+       /*
+        * With vectored interrupts things are getting platform specific.
+        * get_c0_compare_int is a hook to allow a platform to return the
+        * interrupt number of it's liking.
+        */
+       irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
+       if (get_c0_compare_int)
+               irq = get_c0_compare_int();
+
+       cd = &per_cpu(mips_clockevent_device, cpu);
+
+       cd->name                = "MIPS";
+       cd->features            = CLOCK_EVT_FEAT_ONESHOT;
+
+       /* Calculate the min / max delta */
+       cd->mult        = div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32);
+       cd->shift               = 32;
+       cd->max_delta_ns        = clockevent_delta2ns(0x7fffffff, cd);
+       cd->min_delta_ns        = clockevent_delta2ns(0x300, cd);
+
+       cd->rating              = 300;
+       cd->irq                 = irq;
+       cd->cpumask             = cpumask_of_cpu(cpu);
+       cd->set_next_event      = mips_next_event;
+       cd->set_mode            = mips_set_clock_mode;
+       cd->event_handler       = mips_event_handler;
+
+       clockevents_register_device(cd);
+
+       /*
+        * On SMTC we only want to do the data structure
+        * initialization and IRQ setup once.
+        */
+       if (cpu)
+               return 0;
+       /*
+        * And we need the hwmask associated with the c0_compare
+        * vector to be initialized.
+        */
+       irq_hwmask[irq] = (0x100 << cp0_compare_irq);
+       if (cp0_timer_irq_installed)
+               return 0;
+
+       cp0_timer_irq_installed = 1;
+
+       setup_irq(irq, &c0_compare_irqaction);
+
+       return 0;
+}
index 335a6ae..e621fda 100644 (file)
@@ -45,18 +45,7 @@ static void r39xx_wait(void)
        local_irq_enable();
 }
 
-/*
- * There is a race when WAIT instruction executed with interrupt
- * enabled.
- * But it is implementation-dependent wheter the pipelie restarts when
- * a non-enabled interrupt is requested.
- */
-static void r4k_wait(void)
-{
-       __asm__("       .set    mips3                   \n"
-               "       wait                            \n"
-               "       .set    mips0                   \n");
-}
+extern void r4k_wait(void);
 
 /*
  * This variant is preferable as it allows testing need_resched and going to
@@ -65,14 +54,18 @@ static void r4k_wait(void)
  * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes
  * using this version a gamble.
  */
-static void r4k_wait_irqoff(void)
+void r4k_wait_irqoff(void)
 {
        local_irq_disable();
        if (!need_resched())
-               __asm__("       .set    mips3           \n"
+               __asm__("       .set    push            \n"
+                       "       .set    mips3           \n"
                        "       wait                    \n"
-                       "       .set    mips0           \n");
+                       "       .set    pop             \n");
        local_irq_enable();
+       __asm__("       .globl __pastwait       \n"
+               "__pastwait:                    \n");
+       return;
 }
 
 /*
@@ -128,7 +121,7 @@ static int __init wait_disable(char *s)
 
 __setup("nowait", wait_disable);
 
-static inline void check_wait(void)
+void __init check_wait(void)
 {
        struct cpuinfo_mips *c = &current_cpu_data;
 
@@ -242,7 +235,6 @@ static inline void check_errata(void)
 
 void __init check_bugs32(void)
 {
-       check_wait();
        check_errata();
 }
 
index e29598a..ffa3310 100644 (file)
@@ -79,11 +79,6 @@ FEXPORT(syscall_exit)
 
 FEXPORT(restore_all)                   # restore full frame
 #ifdef CONFIG_MIPS_MT_SMTC
-/* Detect and execute deferred IPI "interrupts" */
-       LONG_L  s0, TI_REGS($28)
-       LONG_S  sp, TI_REGS($28)
-       jal     deferred_smtc_ipi
-       LONG_S  s0, TI_REGS($28)
 #ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
 /* Re-arm any temporarily masked interrupts not explicitly "acked" */
        mfc0    v0, CP0_TCSTATUS
@@ -112,6 +107,11 @@ FEXPORT(restore_all)                       # restore full frame
        xor     t0, t0, t3
        mtc0    t0, CP0_TCCONTEXT
 #endif /* CONFIG_MIPS_MT_SMTC_IM_BACKSTOP */
+/* Detect and execute deferred IPI "interrupts" */
+       LONG_L  s0, TI_REGS($28)
+       LONG_S  sp, TI_REGS($28)
+       jal     deferred_smtc_ipi
+       LONG_S  s0, TI_REGS($28)
 #endif /* CONFIG_MIPS_MT_SMTC */
        .set    noat
        RESTORE_TEMP
index c6ada98..01dcbe3 100644 (file)
@@ -20,6 +20,7 @@
 #include <asm/stackframe.h>
 #include <asm/war.h>
 #include <asm/page.h>
+#include <asm/thread_info.h>
 
 #define PANIC_PIC(msg)                                 \
                .set push;                              \
@@ -126,7 +127,42 @@ handle_vcei:
 
        __FINIT
 
+       .align  5       /* 32 byte rollback region */
+LEAF(r4k_wait)
+       .set    push
+       .set    noreorder
+       /* start of rollback region */
+       LONG_L  t0, TI_FLAGS($28)
+       nop
+       andi    t0, _TIF_NEED_RESCHED
+       bnez    t0, 1f
+        nop
+       nop
+       nop
+       .set    mips3
+       wait
+       /* end of rollback region (the region size must be power of two) */
+       .set    pop
+1:
+       jr      ra
+       END(r4k_wait)
+
+       .macro  BUILD_ROLLBACK_PROLOGUE handler
+       FEXPORT(rollback_\handler)
+       .set    push
+       .set    noat
+       MFC0    k0, CP0_EPC
+       PTR_LA  k1, r4k_wait
+       ori     k0, 0x1f        /* 32 byte rollback region */
+       xori    k0, 0x1f
+       bne     k0, k1, 9f
+       MTC0    k0, CP0_EPC
+9:
+       .set pop
+       .endm
+
        .align  5
+BUILD_ROLLBACK_PROLOGUE handle_int
 NESTED(handle_int, PT_SIZE, sp)
 #ifdef CONFIG_TRACE_IRQFLAGS
        /*
@@ -201,6 +237,7 @@ NESTED(except_vec_ejtag_debug, 0, sp)
  * This prototype is copied to ebase + n*IntCtl.VS and patched
  * to invoke the handler
  */
+BUILD_ROLLBACK_PROLOGUE except_vec_vi
 NESTED(except_vec_vi, 0, sp)
        SAVE_SOME
        SAVE_AT
@@ -245,8 +282,8 @@ NESTED(except_vec_vi_handler, 0, sp)
        and     t0, a0, t1
 #ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
        mfc0    t2, CP0_TCCONTEXT
-       or      t0, t0, t2
-       mtc0    t0, CP0_TCCONTEXT
+       or      t2, t0, t2
+       mtc0    t2, CP0_TCCONTEXT
 #endif /* CONFIG_MIPS_MT_SMTC_IM_BACKSTOP */
        xor     t1, t1, t0
        mtc0    t1, CP0_STATUS
index 3613645..492a0a8 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/irqflags.h>
 #include <asm/regdef.h>
 #include <asm/page.h>
+#include <asm/pgtable-bits.h>
 #include <asm/mipsregs.h>
 #include <asm/stackframe.h>
 
index 8f6d58e..6e152c8 100644 (file)
@@ -236,8 +236,7 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code,
 
                atomic_set(&kgdb_cpu_doing_single_step, -1);
                if (remcom_in_buffer[0] == 's')
-                       if (kgdb_contthread)
-                               atomic_set(&kgdb_cpu_doing_single_step, cpu);
+                       atomic_set(&kgdb_cpu_doing_single_step, cpu);
 
                return 0;
        }
index df4d3f2..dc9eb72 100644 (file)
@@ -159,7 +159,7 @@ __setup("fpaff=", fpaff_thresh);
 /*
  * FPU Use Factor empirically derived from experiments on 34K
  */
-#define FPUSEFACTOR 333
+#define FPUSEFACTOR 2000
 
 static __init int mt_fp_affinity_init(void)
 {
index b16facd..22fc19b 100644 (file)
@@ -55,7 +55,7 @@ void __noreturn cpu_idle(void)
        while (1) {
                tick_nohz_stop_sched_tick(1);
                while (!need_resched()) {
-#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
+#ifdef CONFIG_MIPS_MT_SMTC
                        extern void smtc_idle_loop_hook(void);
 
                        smtc_idle_loop_hook();
@@ -145,17 +145,18 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
         */
        p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1);
        childregs->cp0_status &= ~(ST0_CU2|ST0_CU1);
-       clear_tsk_thread_flag(p, TIF_USEDFPU);
 
-#ifdef CONFIG_MIPS_MT_FPAFF
+#ifdef CONFIG_MIPS_MT_SMTC
        /*
-        * FPU affinity support is cleaner if we track the
-        * user-visible CPU affinity from the very beginning.
-        * The generic cpus_allowed mask will already have
-        * been copied from the parent before copy_thread
-        * is invoked.
+        * SMTC restores TCStatus after Status, and the CU bits
+        * are aliased there.
         */
-       p->thread.user_cpus_allowed = p->cpus_allowed;
+       childregs->cp0_tcstatus &= ~(ST0_CU2|ST0_CU1);
+#endif
+       clear_tsk_thread_flag(p, TIF_USEDFPU);
+
+#ifdef CONFIG_MIPS_MT_FPAFF
+       clear_tsk_thread_flag(p, TIF_FPUBOUND);
 #endif /* CONFIG_MIPS_MT_FPAFF */
 
        if (clone_flags & CLONE_SETTLS)
index 35234b9..96ffc9c 100644 (file)
@@ -238,7 +238,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                case FPC_EIR: { /* implementation / version register */
                        unsigned int flags;
 #ifdef CONFIG_MIPS_MT_SMTC
-                       unsigned int irqflags;
+                       unsigned long irqflags;
                        unsigned int mtflags;
 #endif /* CONFIG_MIPS_MT_SMTC */
 
index a516286..897fb2b 100644 (file)
@@ -1,4 +1,21 @@
-/* Copyright (C) 2004 Mips Technologies, Inc */
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Copyright (C) 2004 Mips Technologies, Inc
+ * Copyright (C) 2008 Kevin D. Kissell
+ */
 
 #include <linux/clockchips.h>
 #include <linux/kernel.h>
@@ -21,7 +38,6 @@
 #include <asm/time.h>
 #include <asm/addrspace.h>
 #include <asm/smtc.h>
-#include <asm/smtc_ipi.h>
 #include <asm/smtc_proc.h>
 
 /*
@@ -58,11 +74,6 @@ unsigned long irq_hwmask[NR_IRQS];
 
 asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS];
 
-/*
- * Clock interrupt "latch" buffers, per "CPU"
- */
-
-static atomic_t ipi_timer_latch[NR_CPUS];
 
 /*
  * Number of InterProcessor Interrupt (IPI) message buffers to allocate
@@ -70,7 +81,7 @@ static atomic_t ipi_timer_latch[NR_CPUS];
 
 #define IPIBUF_PER_CPU 4
 
-static struct smtc_ipi_q IPIQ[NR_CPUS];
+struct smtc_ipi_q IPIQ[NR_CPUS];
 static struct smtc_ipi_q freeIPIq;
 
 
@@ -282,7 +293,7 @@ static void smtc_configure_tlb(void)
  * phys_cpu_present_map and the logical/physical mappings.
  */
 
-int __init mipsmt_build_cpu_map(int start_cpu_slot)
+int __init smtc_build_cpu_map(int start_cpu_slot)
 {
        int i, ntcs;
 
@@ -325,7 +336,12 @@ static void smtc_tc_setup(int vpe, int tc, int cpu)
        write_tc_c0_tcstatus((read_tc_c0_tcstatus()
                        & ~(TCSTATUS_TKSU | TCSTATUS_DA | TCSTATUS_IXMT))
                        | TCSTATUS_A);
-       write_tc_c0_tccontext(0);
+       /*
+        * TCContext gets an offset from the base of the IPIQ array
+        * to be used in low-level code to detect the presence of
+        * an active IPI queue
+        */
+       write_tc_c0_tccontext((sizeof(struct smtc_ipi_q) * cpu) << 16);
        /* Bind tc to vpe */
        write_tc_c0_tcbind(vpe);
        /* In general, all TCs should have the same cpu_data indications */
@@ -336,10 +352,18 @@ static void smtc_tc_setup(int vpe, int tc, int cpu)
                cpu_data[cpu].options &= ~MIPS_CPU_FPU;
        cpu_data[cpu].vpe_id = vpe;
        cpu_data[cpu].tc_id = tc;
+       /* Multi-core SMTC hasn't been tested, but be prepared */
+       cpu_data[cpu].core = (read_vpe_c0_ebase() >> 1) & 0xff;
 }
 
+/*
+ * Tweak to get Count registes in as close a sync as possible.
+ * Value seems good for 34K-class cores.
+ */
+
+#define CP0_SKEW 8
 
-void mipsmt_prepare_cpus(void)
+void smtc_prepare_cpus(int cpus)
 {
        int i, vpe, tc, ntc, nvpe, tcpervpe[NR_CPUS], slop, cpu;
        unsigned long flags;
@@ -363,13 +387,13 @@ void mipsmt_prepare_cpus(void)
                IPIQ[i].head = IPIQ[i].tail = NULL;
                spin_lock_init(&IPIQ[i].lock);
                IPIQ[i].depth = 0;
-               atomic_set(&ipi_timer_latch[i], 0);
        }
 
        /* cpu_data index starts at zero */
        cpu = 0;
        cpu_data[cpu].vpe_id = 0;
        cpu_data[cpu].tc_id = 0;
+       cpu_data[cpu].core = (read_c0_ebase() >> 1) & 0xff;
        cpu++;
 
        /* Report on boot-time options */
@@ -484,7 +508,8 @@ void mipsmt_prepare_cpus(void)
                        write_vpe_c0_compare(0);
                        /* Propagate Config7 */
                        write_vpe_c0_config7(read_c0_config7());
-                       write_vpe_c0_count(read_c0_count());
+                       write_vpe_c0_count(read_c0_count() + CP0_SKEW);
+                       ehb();
                }
                /* enable multi-threading within VPE */
                write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() | VPECONTROL_TE);
@@ -556,7 +581,7 @@ void mipsmt_prepare_cpus(void)
 void __cpuinit smtc_boot_secondary(int cpu, struct task_struct *idle)
 {
        extern u32 kernelsp[NR_CPUS];
-       long flags;
+       unsigned long flags;
        int mtflags;
 
        LOCK_MT_PRA();
@@ -585,24 +610,22 @@ void __cpuinit smtc_boot_secondary(int cpu, struct task_struct *idle)
 
 void smtc_init_secondary(void)
 {
-       /*
-        * Start timer on secondary VPEs if necessary.
-        * plat_timer_setup has already have been invoked by init/main
-        * on "boot" TC.  Like per_cpu_trap_init() hack, this assumes that
-        * SMTC init code assigns TCs consdecutively and in ascending order
-        * to across available VPEs.
-        */
-       if (((read_c0_tcbind() & TCBIND_CURTC) != 0) &&
-           ((read_c0_tcbind() & TCBIND_CURVPE)
-           != cpu_data[smp_processor_id() - 1].vpe_id)){
-               write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ);
-       }
-
        local_irq_enable();
 }
 
 void smtc_smp_finish(void)
 {
+       int cpu = smp_processor_id();
+
+       /*
+        * Lowest-numbered CPU per VPE starts a clock tick.
+        * Like per_cpu_trap_init() hack, this assumes that
+        * SMTC init code assigns TCs consdecutively and
+        * in ascending order across available VPEs.
+        */
+       if (cpu > 0 && (cpu_data[cpu].vpe_id != cpu_data[cpu - 1].vpe_id))
+               write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ);
+
        printk("TC %d going on-line as CPU %d\n",
                cpu_data[smp_processor_id()].tc_id, smp_processor_id());
 }
@@ -753,8 +776,10 @@ void smtc_send_ipi(int cpu, int type, unsigned int action)
 {
        int tcstatus;
        struct smtc_ipi *pipi;
-       long flags;
+       unsigned long flags;
        int mtflags;
+       unsigned long tcrestart;
+       extern void r4k_wait_irqoff(void), __pastwait(void);
 
        if (cpu == smp_processor_id()) {
                printk("Cannot Send IPI to self!\n");
@@ -771,8 +796,6 @@ void smtc_send_ipi(int cpu, int type, unsigned int action)
        pipi->arg = (void *)action;
        pipi->dest = cpu;
        if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) {
-               if (type == SMTC_CLOCK_TICK)
-                       atomic_inc(&ipi_timer_latch[cpu]);
                /* If not on same VPE, enqueue and send cross-VPE interrupt */
                smtc_ipi_nq(&IPIQ[cpu], pipi);
                LOCK_CORE_PRA();
@@ -800,22 +823,29 @@ void smtc_send_ipi(int cpu, int type, unsigned int action)
 
                if ((tcstatus & TCSTATUS_IXMT) != 0) {
                        /*
-                        * Spin-waiting here can deadlock,
-                        * so we queue the message for the target TC.
+                        * If we're in the the irq-off version of the wait
+                        * loop, we need to force exit from the wait and
+                        * do a direct post of the IPI.
+                        */
+                       if (cpu_wait == r4k_wait_irqoff) {
+                               tcrestart = read_tc_c0_tcrestart();
+                               if (tcrestart >= (unsigned long)r4k_wait_irqoff
+                                   && tcrestart < (unsigned long)__pastwait) {
+                                       write_tc_c0_tcrestart(__pastwait);
+                                       tcstatus &= ~TCSTATUS_IXMT;
+                                       write_tc_c0_tcstatus(tcstatus);
+                                       goto postdirect;
+                               }
+                       }
+                       /*
+                        * Otherwise we queue the message for the target TC
+                        * to pick up when he does a local_irq_restore()
                         */
                        write_tc_c0_tchalt(0);
                        UNLOCK_CORE_PRA();
-                       /* Try to reduce redundant timer interrupt messages */
-                       if (type == SMTC_CLOCK_TICK) {
-                           if (atomic_postincrement(&ipi_timer_latch[cpu])!=0){
-                               smtc_ipi_nq(&freeIPIq, pipi);
-                               return;
-                           }
-                       }
                        smtc_ipi_nq(&IPIQ[cpu], pipi);
                } else {
-                       if (type == SMTC_CLOCK_TICK)
-                               atomic_inc(&ipi_timer_latch[cpu]);
+postdirect:
                        post_direct_ipi(cpu, pipi);
                        write_tc_c0_tchalt(0);
                        UNLOCK_CORE_PRA();
@@ -883,7 +913,7 @@ static void ipi_call_interrupt(void)
        smp_call_function_interrupt();
 }
 
-DECLARE_PER_CPU(struct clock_event_device, smtc_dummy_clockevent_device);
+DECLARE_PER_CPU(struct clock_event_device, mips_clockevent_device);
 
 void ipi_decode(struct smtc_ipi *pipi)
 {
@@ -891,20 +921,13 @@ void ipi_decode(struct smtc_ipi *pipi)
        struct clock_event_device *cd;
        void *arg_copy = pipi->arg;
        int type_copy = pipi->type;
-       int ticks;
-
        smtc_ipi_nq(&freeIPIq, pipi);
        switch (type_copy) {
        case SMTC_CLOCK_TICK:
                irq_enter();
                kstat_this_cpu.irqs[MIPS_CPU_IRQ_BASE + 1]++;
-               cd = &per_cpu(smtc_dummy_clockevent_device, cpu);
-               ticks = atomic_read(&ipi_timer_latch[cpu]);
-               atomic_sub(ticks, &ipi_timer_latch[cpu]);
-               while (ticks) {
-                       cd->event_handler(cd);
-                       ticks--;
-               }
+               cd = &per_cpu(mips_clockevent_device, cpu);
+               cd->event_handler(cd);
                irq_exit();
                break;
 
@@ -937,24 +960,48 @@ void ipi_decode(struct smtc_ipi *pipi)
        }
 }
 
+/*
+ * Similar to smtc_ipi_replay(), but invoked from context restore,
+ * so it reuses the current exception frame rather than set up a
+ * new one with self_ipi.
+ */
+
 void deferred_smtc_ipi(void)
 {
-       struct smtc_ipi *pipi;
-       unsigned long flags;
-/* DEBUG */
-       int q = smp_processor_id();
+       int cpu = smp_processor_id();
 
        /*
         * Test is not atomic, but much faster than a dequeue,
         * and the vast majority of invocations will have a null queue.
+        * If irq_disabled when this was called, then any IPIs queued
+        * after we test last will be taken on the next irq_enable/restore.
+        * If interrupts were enabled, then any IPIs added after the
+        * last test will be taken directly.
         */
-       if (IPIQ[q].head != NULL) {
-               while((pipi = smtc_ipi_dq(&IPIQ[q])) != NULL) {
-                       /* ipi_decode() should be called with interrupts off */
-                       local_irq_save(flags);
+
+       while (IPIQ[cpu].head != NULL) {
+               struct smtc_ipi_q *q = &IPIQ[cpu];
+               struct smtc_ipi *pipi;
+               unsigned long flags;
+
+               /*
+                * It may be possible we'll come in with interrupts
+                * already enabled.
+                */
+               local_irq_save(flags);
+
+               spin_lock(&q->lock);
+               pipi = __smtc_ipi_dq(q);
+               spin_unlock(&q->lock);
+               if (pipi != NULL)
                        ipi_decode(pipi);
-                       local_irq_restore(flags);
-               }
+               /*
+                * The use of the __raw_local restore isn't
+                * as obviously necessary here as in smtc_ipi_replay(),
+                * but it's more efficient, given that we're already
+                * running down the IPI queue.
+                */
+               __raw_local_irq_restore(flags);
        }
 }
 
@@ -975,7 +1022,7 @@ static irqreturn_t ipi_interrupt(int irq, void *dev_idm)
        struct smtc_ipi *pipi;
        unsigned long tcstatus;
        int sent;
-       long flags;
+       unsigned long flags;
        unsigned int mtflags;
        unsigned int vpflags;
 
@@ -1066,55 +1113,53 @@ static void setup_cross_vpe_interrupts(unsigned int nvpe)
 
 /*
  * SMTC-specific hacks invoked from elsewhere in the kernel.
- *
- * smtc_ipi_replay is called from raw_local_irq_restore which is only ever
- * called with interrupts disabled.  We do rely on interrupts being disabled
- * here because using spin_lock_irqsave()/spin_unlock_irqrestore() would
- * result in a recursive call to raw_local_irq_restore().
  */
 
-static void __smtc_ipi_replay(void)
+ /*
+  * smtc_ipi_replay is called from raw_local_irq_restore
+  */
+
+void smtc_ipi_replay(void)
 {
        unsigned int cpu = smp_processor_id();
 
        /*
         * To the extent that we've ever turned interrupts off,
         * we may have accumulated deferred IPIs.  This is subtle.
-        * If we use the smtc_ipi_qdepth() macro, we'll get an
-        * exact number - but we'll also disable interrupts
-        * and create a window of failure where a new IPI gets
-        * queued after we test the depth but before we re-enable
-        * interrupts. So long as IXMT never gets set, however,
         * we should be OK:  If we pick up something and dispatch
         * it here, that's great. If we see nothing, but concurrent
         * with this operation, another TC sends us an IPI, IXMT
         * is clear, and we'll handle it as a real pseudo-interrupt
-        * and not a pseudo-pseudo interrupt.
+        * and not a pseudo-pseudo interrupt.  The important thing
+        * is to do the last check for queued message *after* the
+        * re-enabling of interrupts.
         */
-       if (IPIQ[cpu].depth > 0) {
-               while (1) {
-                       struct smtc_ipi_q *q = &IPIQ[cpu];
-                       struct smtc_ipi *pipi;
-                       extern void self_ipi(struct smtc_ipi *);
-
-                       spin_lock(&q->lock);
-                       pipi = __smtc_ipi_dq(q);
-                       spin_unlock(&q->lock);
-                       if (!pipi)
-                               break;
+       while (IPIQ[cpu].head != NULL) {
+               struct smtc_ipi_q *q = &IPIQ[cpu];
+               struct smtc_ipi *pipi;
+               unsigned long flags;
+
+               /*
+                * It's just possible we'll come in with interrupts
+                * already enabled.
+                */
+               local_irq_save(flags);
+
+               spin_lock(&q->lock);
+               pipi = __smtc_ipi_dq(q);
+               spin_unlock(&q->lock);
+               /*
+                ** But use a raw restore here to avoid recursion.
+                */
+               __raw_local_irq_restore(flags);
 
+               if (pipi) {
                        self_ipi(pipi);
                        smtc_cpu_stats[cpu].selfipis++;
                }
        }
 }
 
-void smtc_ipi_replay(void)
-{
-       raw_local_irq_disable();
-       __smtc_ipi_replay();
-}
-
 EXPORT_SYMBOL(smtc_ipi_replay);
 
 void smtc_idle_loop_hook(void)
@@ -1193,40 +1238,13 @@ void smtc_idle_loop_hook(void)
                }
        }
 
-       /*
-        * Now that we limit outstanding timer IPIs, check for hung TC
-        */
-       for (tc = 0; tc < NR_CPUS; tc++) {
-               /* Don't check ourself - we'll dequeue IPIs just below */
-               if ((tc != smp_processor_id()) &&
-                   atomic_read(&ipi_timer_latch[tc]) > timerq_limit) {
-                   if (clock_hang_reported[tc] == 0) {
-                       pdb_msg += sprintf(pdb_msg,
-                               "TC %d looks hung with timer latch at %d\n",
-                               tc, atomic_read(&ipi_timer_latch[tc]));
-                       clock_hang_reported[tc]++;
-                       }
-               }
-       }
        emt(mtflags);
        local_irq_restore(flags);
        if (pdb_msg != &id_ho_db_msg[0])
                printk("CPU%d: %s", smp_processor_id(), id_ho_db_msg);
 #endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
 
-       /*
-        * Replay any accumulated deferred IPIs. If "Instant Replay"
-        * is in use, there should never be any.
-        */
-#ifndef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY
-       {
-               unsigned long flags;
-
-               local_irq_save(flags);
-               __smtc_ipi_replay();
-               local_irq_restore(flags);
-       }
-#endif /* CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY */
+       smtc_ipi_replay();
 }
 
 void smtc_soft_dump(void)
@@ -1242,10 +1260,6 @@ void smtc_soft_dump(void)
                printk("%d: %ld\n", i, smtc_cpu_stats[i].selfipis);
        }
        smtc_ipi_qdump();
-       printk("Timer IPI Backlogs:\n");
-       for (i=0; i < NR_CPUS; i++) {
-               printk("%d: %d\n", i, atomic_read(&ipi_timer_latch[i]));
-       }
        printk("%d Recoveries of \"stolen\" FPU\n",
               atomic_read(&smtc_fpu_recoveries));
 }
index 6bee290..b602ac6 100644 (file)
@@ -46,6 +46,9 @@
 #include <asm/types.h>
 #include <asm/stacktrace.h>
 
+extern void check_wait(void);
+extern asmlinkage void r4k_wait(void);
+extern asmlinkage void rollback_handle_int(void);
 extern asmlinkage void handle_int(void);
 extern asmlinkage void handle_tlbm(void);
 extern asmlinkage void handle_tlbl(void);
@@ -822,8 +825,10 @@ static void mt_ase_fp_affinity(void)
                if (cpus_intersects(current->cpus_allowed, mt_fpu_cpumask)) {
                        cpumask_t tmask;
 
-                       cpus_and(tmask, current->thread.user_cpus_allowed,
-                                mt_fpu_cpumask);
+                       current->thread.user_cpus_allowed
+                               = current->cpus_allowed;
+                       cpus_and(tmask, current->cpus_allowed,
+                               mt_fpu_cpumask);
                        set_cpus_allowed(current, tmask);
                        set_thread_flag(TIF_FPUBOUND);
                }
@@ -1251,6 +1256,9 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
 
                extern char except_vec_vi, except_vec_vi_lui;
                extern char except_vec_vi_ori, except_vec_vi_end;
+               extern char rollback_except_vec_vi;
+               char *vec_start = (cpu_wait == r4k_wait) ?
+                       &rollback_except_vec_vi : &except_vec_vi;
 #ifdef CONFIG_MIPS_MT_SMTC
                /*
                 * We need to provide the SMTC vectored interrupt handler
@@ -1258,11 +1266,11 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
                 * Status.IM bit to be masked before going there.
                 */
                extern char except_vec_vi_mori;
-               const int mori_offset = &except_vec_vi_mori - &except_vec_vi;
+               const int mori_offset = &except_vec_vi_mori - vec_start;
 #endif /* CONFIG_MIPS_MT_SMTC */
-               const int handler_len = &except_vec_vi_end - &except_vec_vi;
-               const int lui_offset = &except_vec_vi_lui - &except_vec_vi;
-               const int ori_offset = &except_vec_vi_ori - &except_vec_vi;
+               const int handler_len = &except_vec_vi_end - vec_start;
+               const int lui_offset = &except_vec_vi_lui - vec_start;
+               const int ori_offset = &except_vec_vi_ori - vec_start;
 
                if (handler_len > VECTORSPACING) {
                        /*
@@ -1272,7 +1280,7 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
                        panic("VECTORSPACING too small");
                }
 
-               memcpy(b, &except_vec_vi, handler_len);
+               memcpy(b, vec_start, handler_len);
 #ifdef CONFIG_MIPS_MT_SMTC
                BUG_ON(n > 7);  /* Vector index %d exceeds SMTC maximum. */
 
@@ -1554,6 +1562,10 @@ void __init trap_init(void)
        extern char except_vec3_generic, except_vec3_r4000;
        extern char except_vec4;
        unsigned long i;
+       int rollback;
+
+       check_wait();
+       rollback = (cpu_wait == r4k_wait);
 
 #if defined(CONFIG_KGDB)
        if (kgdb_early_setup)
@@ -1618,7 +1630,7 @@ void __init trap_init(void)
        if (board_be_init)
                board_be_init();
 
-       set_except_vector(0, handle_int);
+       set_except_vector(0, rollback ? rollback_handle_int : handle_int);
        set_except_vector(1, handle_tlbm);
        set_except_vector(2, handle_tlbl);
        set_except_vector(3, handle_tlbs);
index b5470ce..afb119f 100644 (file)
@@ -36,6 +36,7 @@ SECTIONS
                SCHED_TEXT
                LOCK_TEXT
                KPROBES_TEXT
+               *(.text.*)
                *(.fixup)
                *(.gnu.warning)
        } :text = 0
index 8d77841..edac989 100644 (file)
 #ifdef USE_DOUBLE
 
 #define LOAD   ld
+#define LOAD32 lwu
 #define ADD    daddu
 #define NBYTES 8
 
 #else
 
 #define LOAD   lw
+#define LOAD32 lw
 #define ADD    addu
 #define NBYTES 4
 
        ADD     sum, v1;                                        \
        .set    pop
 
+#define ADDC32(sum,reg)                                                \
+       .set    push;                                           \
+       .set    noat;                                           \
+       addu    sum, reg;                                       \
+       sltu    v1, sum, reg;                                   \
+       addu    sum, v1;                                        \
+       .set    pop
+
 #define CSUM_BIGCHUNK1(src, offset, sum, _t0, _t1, _t2, _t3)   \
        LOAD    _t0, (offset + UNIT(0))(src);                   \
        LOAD    _t1, (offset + UNIT(1))(src);                   \
@@ -132,7 +142,7 @@ LEAF(csum_partial)
        beqz    t8, .Lqword_align
         andi   t8, src, 0x8
 
-       lw      t0, 0x00(src)
+       LOAD32  t0, 0x00(src)
        LONG_SUBU       a1, a1, 0x4
        ADDC(sum, t0)
        PTR_ADDU        src, src, 0x4
@@ -211,7 +221,7 @@ LEAF(csum_partial)
        LONG_SRL        t8, t8, 0x2
 
 .Lend_words:
-       lw      t0, (src)
+       LOAD32  t0, (src)
        LONG_SUBU       t8, t8, 0x1
        ADDC(sum, t0)
        .set    reorder                         /* DADDI_WAR */
@@ -230,6 +240,9 @@ LEAF(csum_partial)
        /* Still a full word to go  */
        ulw     t1, (src)
        PTR_ADDIU       src, 4
+#ifdef USE_DOUBLE
+       dsll    t1, t1, 32                      /* clear lower 32bit */
+#endif
        ADDC(sum, t1)
 
 1:     move    t1, zero
@@ -280,7 +293,7 @@ LEAF(csum_partial)
 1:
        .set    reorder
        /* Add the passed partial csum.  */
-       ADDC(sum, a2)
+       ADDC32(sum, a2)
        jr      ra
        .set    noreorder
        END(csum_partial)
@@ -681,7 +694,7 @@ EXC(        sb      t0, NBYTES-2(dst), .Ls_exc)
        .set    pop
 1:
        .set reorder
-       ADDC(sum, psum)
+       ADDC32(sum, psum)
        jr      ra
        .set noreorder
 
index 3b7dd72..cef2db8 100644 (file)
@@ -15,6 +15,6 @@ obj-$(CONFIG_EARLY_PRINTK)    += malta-console.o
 obj-$(CONFIG_PCI)              += malta-pci.o
 
 # FIXME FIXME FIXME
-obj-$(CONFIG_MIPS_MT_SMTC)     += malta_smtc.o
+obj-$(CONFIG_MIPS_MT_SMTC)     += malta-smtc.o
 
 EXTRA_CFLAGS += -Werror
index 5ea705e..f84a46a 100644 (file)
@@ -84,12 +84,17 @@ static void msmtc_cpus_done(void)
 
 static void __init msmtc_smp_setup(void)
 {
-       mipsmt_build_cpu_map(0);
+       /*
+        * we won't get the definitive value until
+        * we've run smtc_prepare_cpus later, but
+        * we would appear to need an upper bound now.
+        */
+       smp_num_siblings = smtc_build_cpu_map(0);
 }
 
 static void __init msmtc_prepare_cpus(unsigned int max_cpus)
 {
-       mipsmt_prepare_cpus();
+       smtc_prepare_cpus(max_cpus);
 }
 
 struct plat_smp_ops msmtc_smp_ops = {
index 15e01ae..c8c32f4 100644 (file)
@@ -15,6 +15,7 @@ obj-$(CONFIG_SOC_TX3927)      += ops-tx3927.o
 obj-$(CONFIG_PCI_VR41XX)       += ops-vr41xx.o pci-vr41xx.o
 obj-$(CONFIG_MARKEINS)         += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o
 obj-$(CONFIG_PCI_TX4927)       += ops-tx4927.o
+obj-$(CONFIG_BCM47XX)          += pci-bcm47xx.o
 
 #
 # These are still pretty much in the old state, watch, go blind.
diff --git a/arch/mips/pci/pci-bcm47xx.c b/arch/mips/pci/pci-bcm47xx.c
new file mode 100644 (file)
index 0000000..bea9b6c
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ *  Copyright (C) 2008 Aurelien Jarno <aurelien@aurel32.net>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/ssb/ssb.h>
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+       return 0;
+}
+
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+       int res;
+       u8 slot, pin;
+
+       res = ssb_pcibios_plat_dev_init(dev);
+       if (res < 0) {
+               printk(KERN_ALERT "PCI: Failed to init device %s\n",
+                      pci_name(dev));
+               return res;
+       }
+
+       pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+       slot = PCI_SLOT(dev->devfn);
+       res = ssb_pcibios_map_irq(dev, slot, pin);
+
+       /* IRQ-0 and IRQ-1 are software interrupts. */
+       if (res < 2) {
+               printk(KERN_ALERT "PCI: Failed to map IRQ of device %s\n",
+                      pci_name(dev));
+               return res;
+       }
+
+       dev->irq = res;
+       return 0;
+}
+
index bd78368..f97ab14 100644 (file)
@@ -142,26 +142,48 @@ int __cpuinit bridge_probe(nasid_t nasid, int widget_id, int masterwid)
  * on any one of the hubs connected to its xbow.
  */
 int __devinit pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+       return 0;
+}
+
+/* Most MIPS systems have straight-forward swizzling needs.  */
+static inline u8 bridge_swizzle(u8 pin, u8 slot)
+{
+       return (((pin - 1) + slot) % 4) + 1;
+}
+
+static inline struct pci_dev *bridge_root_dev(struct pci_dev *dev)
+{
+       while (dev->bus->parent) {
+               /* Move up the chain of bridges. */
+               dev = dev->bus->self;
+       }
+
+       return dev;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
 {
        struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
-       int irq = bc->pci_int[slot];
+       struct pci_dev *rdev = bridge_root_dev(dev);
+       int slot = PCI_SLOT(rdev->devfn);
+       int irq;
 
+       irq = bc->pci_int[slot];
        if (irq == -1) {
-               irq = bc->pci_int[slot] = request_bridge_irq(bc);
+               irq = request_bridge_irq(bc);
                if (irq < 0)
-                       panic("Can't allocate interrupt for PCI device %s\n",
-                             pci_name(dev));
+                       return irq;
+
+               bc->pci_int[slot] = irq;
        }
 
        irq_to_bridge[irq] = bc;
        irq_to_slot[irq] = slot;
 
-       return irq;
-}
+       dev->irq = irq;
 
-/* Do platform specific device initialization at pci_enable_device() time */
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
        return 0;
 }
 
index f18ba92..7b45f19 100644 (file)
@@ -1,3 +1,4 @@
-obj-y                          := setup.o rtc_xicor1241.o rtc_m41t81.o
+obj-y                          := platform.o setup.o rtc_xicor1241.o \
+                                  rtc_m41t81.o
 
 obj-$(CONFIG_I2C_BOARDINFO)    += swarm-i2c.o
diff --git a/arch/mips/sibyte/swarm/platform.c b/arch/mips/sibyte/swarm/platform.c
new file mode 100644 (file)
index 0000000..54847fe
--- /dev/null
@@ -0,0 +1,85 @@
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+
+#include <asm/sibyte/board.h>
+#include <asm/sibyte/sb1250_genbus.h>
+#include <asm/sibyte/sb1250_regs.h>
+
+#if defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_LITTLESUR)
+
+#define DRV_NAME       "pata-swarm"
+
+#define SWARM_IDE_SHIFT        5
+#define SWARM_IDE_BASE 0x1f0
+#define SWARM_IDE_CTRL 0x3f6
+
+static struct resource swarm_pata_resource[] = {
+       {
+               .name   = "Swarm GenBus IDE",
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .name   = "Swarm GenBus IDE",
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .name   = "Swarm GenBus IDE",
+               .flags  = IORESOURCE_IRQ,
+               .start  = K_INT_GB_IDE,
+               .end    = K_INT_GB_IDE,
+       },
+};
+
+static struct pata_platform_info pata_platform_data = {
+       .ioport_shift   = SWARM_IDE_SHIFT,
+};
+
+static struct platform_device swarm_pata_device = {
+       .name           = "pata_platform",
+       .id             = -1,
+       .resource       = swarm_pata_resource,
+       .num_resources  = ARRAY_SIZE(swarm_pata_resource),
+       .dev  = {
+               .platform_data          = &pata_platform_data,
+               .coherent_dma_mask      = ~0,   /* grumble */
+       },
+};
+
+static int __init swarm_pata_init(void)
+{
+       u8 __iomem *base;
+       phys_t offset, size;
+       struct resource *r;
+
+       if (!SIBYTE_HAVE_IDE)
+               return -ENODEV;
+
+       base = ioremap(A_IO_EXT_BASE, 0x800);
+       offset = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS));
+       size = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_MULT_SIZE, IDE_CS));
+       iounmap(base);
+
+       offset = G_IO_START_ADDR(offset) << S_IO_ADDRBASE;
+       size = (G_IO_MULT_SIZE(size) + 1) << S_IO_REGSIZE;
+       if (offset < A_PHYS_GENBUS || offset >= A_PHYS_GENBUS_END) {
+               pr_info(DRV_NAME ": PATA interface at GenBus disabled\n");
+
+               return -EBUSY;
+       }
+
+       pr_info(DRV_NAME ": PATA interface at GenBus slot %i\n", IDE_CS);
+
+       r = swarm_pata_resource;
+       r[0].start = offset + (SWARM_IDE_BASE << SWARM_IDE_SHIFT);
+       r[0].end   = offset + ((SWARM_IDE_BASE + 8) << SWARM_IDE_SHIFT) - 1;
+       r[1].start = offset + (SWARM_IDE_CTRL << SWARM_IDE_SHIFT);
+       r[1].end   = offset + ((SWARM_IDE_CTRL + 1) << SWARM_IDE_SHIFT) - 1;
+
+       return platform_device_register(&swarm_pata_device);
+}
+
+device_initcall(swarm_pata_init);
+
+#endif /* defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_LITTLESUR) */
index 761c434..56c64cc 100644 (file)
@@ -20,22 +20,8 @@ EXPORT_SYMBOL(__mn10300_irq_enabled_epsw);
 atomic_t irq_err_count;
 
 /*
- * MN10300 INTC controller operations
+ * MN10300 interrupt controller operations
  */
-static void mn10300_cpupic_disable(unsigned int irq)
-{
-       u16 tmp = GxICR(irq);
-       GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_DETECT;
-       tmp = GxICR(irq);
-}
-
-static void mn10300_cpupic_enable(unsigned int irq)
-{
-       u16 tmp = GxICR(irq);
-       GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE;
-       tmp = GxICR(irq);
-}
-
 static void mn10300_cpupic_ack(unsigned int irq)
 {
        u16 tmp;
@@ -60,26 +46,54 @@ static void mn10300_cpupic_mask_ack(unsigned int irq)
 static void mn10300_cpupic_unmask(unsigned int irq)
 {
        u16 tmp = GxICR(irq);
-       GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT;
+       GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE;
        tmp = GxICR(irq);
 }
 
-static void mn10300_cpupic_end(unsigned int irq)
+static void mn10300_cpupic_unmask_clear(unsigned int irq)
 {
+       /* the MN10300 PIC latches its interrupt request bit, even after the
+        * device has ceased to assert its interrupt line and the interrupt
+        * channel has been disabled in the PIC, so for level-triggered
+        * interrupts we need to clear the request bit when we re-enable */
        u16 tmp = GxICR(irq);
-       GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE;
+       GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT;
        tmp = GxICR(irq);
 }
 
-static struct irq_chip mn10300_cpu_pic = {
-       .name           = "cpu",
-       .disable        = mn10300_cpupic_disable,
-       .enable         = mn10300_cpupic_enable,
+/*
+ * MN10300 PIC level-triggered IRQ handling.
+ *
+ * The PIC has no 'ACK' function per se.  It is possible to clear individual
+ * channel latches, but each latch relatches whether or not the channel is
+ * masked, so we need to clear the latch when we unmask the channel.
+ *
+ * Also for this reason, we don't supply an ack() op (it's unused anyway if
+ * mask_ack() is provided), and mask_ack() just masks.
+ */
+static struct irq_chip mn10300_cpu_pic_level = {
+       .name           = "cpu_l",
+       .disable        = mn10300_cpupic_mask,
+       .enable         = mn10300_cpupic_unmask_clear,
+       .ack            = NULL,
+       .mask           = mn10300_cpupic_mask,
+       .mask_ack       = mn10300_cpupic_mask,
+       .unmask         = mn10300_cpupic_unmask_clear,
+};
+
+/*
+ * MN10300 PIC edge-triggered IRQ handling.
+ *
+ * We use the latch clearing function of the PIC as the 'ACK' function.
+ */
+static struct irq_chip mn10300_cpu_pic_edge = {
+       .name           = "cpu_e",
+       .disable        = mn10300_cpupic_mask,
+       .enable         = mn10300_cpupic_unmask,
        .ack            = mn10300_cpupic_ack,
        .mask           = mn10300_cpupic_mask,
        .mask_ack       = mn10300_cpupic_mask_ack,
        .unmask         = mn10300_cpupic_unmask,
-       .end            = mn10300_cpupic_end,
 };
 
 /*
@@ -114,7 +128,8 @@ void set_intr_level(int irq, u16 level)
  */
 void set_intr_postackable(int irq)
 {
-       set_irq_handler(irq, handle_level_irq);
+       set_irq_chip_and_handler(irq, &mn10300_cpu_pic_level,
+                                handle_level_irq);
 }
 
 /*
@@ -126,8 +141,12 @@ void __init init_IRQ(void)
 
        for (irq = 0; irq < NR_IRQS; irq++)
                if (irq_desc[irq].chip == &no_irq_type)
-                       set_irq_chip_and_handler(irq, &mn10300_cpu_pic,
-                                                handle_edge_irq);
+                       /* due to the PIC latching interrupt requests, even
+                        * when the IRQ is disabled, IRQ_PENDING is superfluous
+                        * and we can use handle_level_irq() for edge-triggered
+                        * interrupts */
+                       set_irq_chip_and_handler(irq, &mn10300_cpu_pic_edge,
+                                                handle_level_irq);
        unit_init_IRQ();
 }
 
index babb7c2..e460658 100644 (file)
@@ -1,6 +1,6 @@
 /* MN10300 Low level time management
  *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2007-2008 Red Hat, Inc. All Rights Reserved.
  * Written by David Howells (dhowells@redhat.com)
  * - Derived from arch/i386/kernel/time.c
  *
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/smp.h>
 #include <linux/profile.h>
+#include <linux/cnt32_to_63.h>
 #include <asm/irq.h>
 #include <asm/div64.h>
 #include <asm/processor.h>
@@ -40,27 +41,54 @@ static struct irqaction timer_irq = {
        .name           = "timer",
 };
 
+static unsigned long sched_clock_multiplier;
+
 /*
  * scheduler clock - returns current time in nanosec units.
  */
 unsigned long long sched_clock(void)
 {
        union {
-               unsigned long long l;
-               u32 w[2];
-       } quot;
+               unsigned long long ll;
+               unsigned l[2];
+       } tsc64, result;
+       unsigned long tsc, tmp;
+       unsigned product[3]; /* 96-bit intermediate value */
+
+       /* read the TSC value
+        */
+       tsc = 0 - get_cycles(); /* get_cycles() counts down */
 
-       quot.w[0] = mn10300_last_tsc - get_cycles();
-       quot.w[1] = 1000000000;
+       /* expand to 64-bits.
+        * - sched_clock() must be called once a minute or better or the
+        *   following will go horribly wrong - see cnt32_to_63()
+        */
+       tsc64.ll = cnt32_to_63(tsc) & 0x7fffffffffffffffULL;
 
-       asm("mulu %2,%3,%0,%1"
-           : "=r"(quot.w[1]), "=r"(quot.w[0])
-           : "0"(quot.w[1]), "1"(quot.w[0])
+       /* scale the 64-bit TSC value to a nanosecond value via a 96-bit
+        * intermediate
+        */
+       asm("mulu       %2,%0,%3,%0     \n"     /* LSW * mult ->  0:%3:%0 */
+           "mulu       %2,%1,%2,%1     \n"     /* MSW * mult -> %2:%1:0 */
+           "add        %3,%1           \n"
+           "addc       0,%2            \n"     /* result in %2:%1:%0 */
+           : "=r"(product[0]), "=r"(product[1]), "=r"(product[2]), "=r"(tmp)
+           :  "0"(tsc64.l[0]),  "1"(tsc64.l[1]),  "2"(sched_clock_multiplier)
            : "cc");
 
-       do_div(quot.l, MN10300_TSCCLK);
+       result.l[0] = product[1] << 16 | product[0] >> 16;
+       result.l[1] = product[2] << 16 | product[1] >> 16;
 
-       return quot.l;
+       return result.ll;
+}
+
+/*
+ * initialise the scheduler clock
+ */
+static void __init mn10300_sched_clock_init(void)
+{
+       sched_clock_multiplier =
+               __muldiv64u(NSEC_PER_SEC, 1 << 16, MN10300_TSCCLK);
 }
 
 /*
@@ -128,4 +156,6 @@ void __init time_init(void)
        /* start the watchdog timer */
        watchdog_go();
 #endif
+
+       mn10300_sched_clock_init();
 }
index 14b2c81..70e8cb4 100644 (file)
@@ -51,7 +51,7 @@ void __init unit_init_IRQ(void)
                switch (GET_XIRQ_TRIGGER(extnum)) {
                case XIRQ_TRIGGER_HILEVEL:
                case XIRQ_TRIGGER_LOWLEVEL:
-                       set_irq_handler(XIRQ2IRQ(extnum), handle_level_irq);
+                       set_intr_postackable(XIRQ2IRQ(extnum));
                        break;
                default:
                        break;
index 6a35241..72812a9 100644 (file)
@@ -52,7 +52,7 @@ void __init unit_init_IRQ(void)
                switch (GET_XIRQ_TRIGGER(extnum)) {
                case XIRQ_TRIGGER_HILEVEL:
                case XIRQ_TRIGGER_LOWLEVEL:
-                       set_irq_handler(XIRQ2IRQ(extnum), handle_level_irq);
+                       set_intr_postackable(XIRQ2IRQ(extnum));
                        break;
                default:
                        break;
index 717a3bc..65d1a84 100644 (file)
@@ -195,7 +195,7 @@ image-$(CONFIG_PPC_CELLEB)          += zImage.pseries
 image-$(CONFIG_PPC_CHRP)               += zImage.chrp
 image-$(CONFIG_PPC_EFIKA)              += zImage.chrp
 image-$(CONFIG_PPC_PMAC)               += zImage.pmac
-image-$(CONFIG_PPC_HOLLY)              += zImage.holly
+image-$(CONFIG_PPC_HOLLY)              += dtbImage.holly
 image-$(CONFIG_PPC_PRPMC2800)          += dtbImage.prpmc2800
 image-$(CONFIG_PPC_ISERIES)            += zImage.iseries
 image-$(CONFIG_DEFAULT_UIMAGE)         += uImage
index f87fe7b..c6e11eb 100644 (file)
                        reg = <0x00007400 0x00000400>;
                        big-endian;
                };
+       };
 
-               pci@1000 {
-                       device_type = "pci";
-                       compatible = "tsi109-pci", "tsi108-pci";
-                       #interrupt-cells = <1>;
-                       #size-cells = <2>;
-                       #address-cells = <3>;
-                       reg = <0x00001000 0x00001000>;
-                       bus-range = <0x0 0x0>;
-                       /*----------------------------------------------------+
-                       | PCI memory range.
-                       | 01 denotes I/O space
-                       | 02 denotes 32-bit memory space
-                       +----------------------------------------------------*/
-                       ranges = <0x02000000 0x00000000 0x40000000 0x40000000 0x00000000 0x10000000
-                                 0x01000000 0x00000000 0x00000000 0x7e000000 0x00000000 0x00010000>;
-                       clock-frequency = <133333332>;
-                       interrupt-parent = <&MPIC>;
+       pci@c0001000 {
+               device_type = "pci";
+               compatible = "tsi109-pci", "tsi108-pci";
+               #interrupt-cells = <1>;
+               #size-cells = <2>;
+               #address-cells = <3>;
+               reg = <0xc0001000 0x00001000>;
+               bus-range = <0x0 0x0>;
+               /*----------------------------------------------------+
+               | PCI memory range.
+               | 01 denotes I/O space
+               | 02 denotes 32-bit memory space
+               +----------------------------------------------------*/
+               ranges = <0x02000000 0x00000000 0x40000000 0x40000000 0x00000000 0x10000000
+                         0x01000000 0x00000000 0x00000000 0x7e000000 0x00000000 0x00010000>;
+               clock-frequency = <133333332>;
+               interrupt-parent = <&MPIC>;
+               interrupts = <0x17 0x2>;
+               interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+               /*----------------------------------------------------+
+               | The INTA, INTB, INTC, INTD are shared.
+               +----------------------------------------------------*/
+               interrupt-map = <
+                       0x800 0x0 0x0 0x1 &RT0 0x24 0x0
+                       0x800 0x0 0x0 0x2 &RT0 0x25 0x0
+                       0x800 0x0 0x0 0x3 &RT0 0x26 0x0
+                       0x800 0x0 0x0 0x4 &RT0 0x27 0x0
+
+                       0x1000 0x0 0x0 0x1 &RT0 0x25 0x0
+                       0x1000 0x0 0x0 0x2 &RT0 0x26 0x0
+                       0x1000 0x0 0x0 0x3 &RT0 0x27 0x0
+                       0x1000 0x0 0x0 0x4 &RT0 0x24 0x0
+
+                       0x1800 0x0 0x0 0x1 &RT0 0x26 0x0
+                       0x1800 0x0 0x0 0x2 &RT0 0x27 0x0
+                       0x1800 0x0 0x0 0x3 &RT0 0x24 0x0
+                       0x1800 0x0 0x0 0x4 &RT0 0x25 0x0
+
+                       0x2000 0x0 0x0 0x1 &RT0 0x27 0x0
+                       0x2000 0x0 0x0 0x2 &RT0 0x24 0x0
+                       0x2000 0x0 0x0 0x3 &RT0 0x25 0x0
+                       0x2000 0x0 0x0 0x4 &RT0 0x26 0x0
+                       >;
+
+               RT0: router@1180 {
+                       device_type = "pic-router";
+                       interrupt-controller;
+                       big-endian;
+                       clock-frequency = <0>;
+                       #address-cells = <0>;
+                       #interrupt-cells = <2>;
                        interrupts = <0x17 0x2>;
-                       interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
-                       /*----------------------------------------------------+
-                       | The INTA, INTB, INTC, INTD are shared.
-                       +----------------------------------------------------*/
-                       interrupt-map = <
-                               0x800 0x0 0x0 0x1 &RT0 0x24 0x0
-                               0x800 0x0 0x0 0x2 &RT0 0x25 0x0
-                               0x800 0x0 0x0 0x3 &RT0 0x26 0x0
-                               0x800 0x0 0x0 0x4 &RT0 0x27 0x0
-
-                               0x1000 0x0 0x0 0x1 &RT0 0x25 0x0
-                               0x1000 0x0 0x0 0x2 &RT0 0x26 0x0
-                               0x1000 0x0 0x0 0x3 &RT0 0x27 0x0
-                               0x1000 0x0 0x0 0x4 &RT0 0x24 0x0
-
-                               0x1800 0x0 0x0 0x1 &RT0 0x26 0x0
-                               0x1800 0x0 0x0 0x2 &RT0 0x27 0x0
-                               0x1800 0x0 0x0 0x3 &RT0 0x24 0x0
-                               0x1800 0x0 0x0 0x4 &RT0 0x25 0x0
-
-                               0x2000 0x0 0x0 0x1 &RT0 0x27 0x0
-                               0x2000 0x0 0x0 0x2 &RT0 0x24 0x0
-                               0x2000 0x0 0x0 0x3 &RT0 0x25 0x0
-                               0x2000 0x0 0x0 0x4 &RT0 0x26 0x0
-                               >;
-
-                       RT0: router@1180 {
-                               device_type = "pic-router";
-                               interrupt-controller;
-                               big-endian;
-                               clock-frequency = <0>;
-                               #address-cells = <0>;
-                               #interrupt-cells = <2>;
-                               interrupts = <0x17 0x2>;
-                               interrupt-parent = <&MPIC>;
-                       };
+                       interrupt-parent = <&MPIC>;
                };
        };
 
index 3b3a106..584a4f1 100644 (file)
                                cell-index = <0>;
                                reg = <0x0 0x80>;
                                interrupt-parent = <&mpic>;
-                               interrupts = <60 2>;
+                               interrupts = <76 2>;
                        };
                        dma-channel@1 {
                                compatible = "fsl,mpc8610-dma-channel",
                                cell-index = <1>;
                                reg = <0x80 0x80>;
                                interrupt-parent = <&mpic>;
-                               interrupts = <61 2>;
+                               interrupts = <77 2>;
                        };
                        dma-channel@2 {
                                compatible = "fsl,mpc8610-dma-channel",
                                cell-index = <2>;
                                reg = <0x100 0x80>;
                                interrupt-parent = <&mpic>;
-                               interrupts = <62 2>;
+                               interrupts = <78 2>;
                        };
                        dma-channel@3 {
                                compatible = "fsl,mpc8610-dma-channel",
                                cell-index = <3>;
                                reg = <0x180 0x80>;
                                interrupt-parent = <&mpic>;
-                               interrupts = <63 2>;
+                               interrupts = <79 2>;
                        };
                };
 
index 80d1f39..64c6ee2 100644 (file)
@@ -409,6 +409,13 @@ do {                                                                       \
 /* Keep this the last entry.  */
 #define R_PPC64_NUM            107
 
+/* There's actually a third entry here, but it's unused */
+struct ppc64_opd_entry
+{
+       unsigned long funcaddr;
+       unsigned long r2;
+};
+
 #ifdef  __KERNEL__
 
 #ifdef CONFIG_SPU_BASE
index 7710e9e..07956f3 100644 (file)
@@ -2,6 +2,8 @@
 #define _ASM_POWERPC_SECTIONS_H
 #ifdef __KERNEL__
 
+#include <linux/elf.h>
+#include <linux/uaccess.h>
 #include <asm-generic/sections.h>
 
 #ifdef __powerpc64__
@@ -17,7 +19,15 @@ static inline int in_kernel_text(unsigned long addr)
 }
 
 #undef dereference_function_descriptor
-void *dereference_function_descriptor(void *);
+static inline void *dereference_function_descriptor(void *ptr)
+{
+       struct ppc64_opd_entry *desc = ptr;
+       void *p;
+
+       if (!probe_kernel_address(&desc->funcaddr, p))
+               ptr = p;
+       return ptr;
+}
 
 #endif
 
index d308a9f..31982d0 100644 (file)
 #include <asm/smp.h>
 
 #ifdef CONFIG_HOTPLUG_CPU
-/* this is used for software suspend, and that shuts down
- * CPUs even while the system is still booting... */
-#define cpu_should_die()       (cpu_is_offline(smp_processor_id()) && \
-                                  (system_state == SYSTEM_RUNNING     \
-                                || system_state == SYSTEM_BOOTING))
+#define cpu_should_die()       cpu_is_offline(smp_processor_id())
 #else
 #define cpu_should_die()       0
 #endif
index b4fdf2f..fe8f71d 100644 (file)
@@ -347,9 +347,8 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code,
                        linux_regs->msr |= MSR_SE;
 #endif
                        kgdb_single_step = 1;
-                       if (kgdb_contthread)
-                               atomic_set(&kgdb_cpu_doing_single_step,
-                                          raw_smp_processor_id());
+                       atomic_set(&kgdb_cpu_doing_single_step,
+                                  raw_smp_processor_id());
                }
                return 0;
        }
index ad79de2..1af2377 100644 (file)
@@ -21,9 +21,7 @@
 #include <linux/err.h>
 #include <linux/vmalloc.h>
 #include <linux/bug.h>
-#include <linux/uaccess.h>
 #include <asm/module.h>
-#include <asm/sections.h>
 #include <asm/firmware.h>
 #include <asm/code-patching.h>
 #include <linux/sort.h>
 #define DEBUGP(fmt , ...)
 #endif
 
-/* There's actually a third entry here, but it's unused */
-struct ppc64_opd_entry
-{
-       unsigned long funcaddr;
-       unsigned long r2;
-};
-
 /* Like PPC32, we need little trampolines to do > 24-bit jumps (into
    the kernel itself).  But on PPC64, these need to be used for every
    jump, actually, to reset r2 (TOC+0x8000). */
@@ -452,13 +443,3 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
 
        return 0;
 }
-
-void *dereference_function_descriptor(void *ptr)
-{
-       struct ppc64_opd_entry *desc = ptr;
-       void *p;
-
-       if (!probe_kernel_address(&desc->funcaddr, p))
-               ptr = p;
-       return ptr;
-}
index ef74a07..8c61996 100644 (file)
@@ -219,11 +219,21 @@ static void __devinit quirk_final_uli5249(struct pci_dev *dev)
        int i;
        u8 *dummy;
        struct pci_bus *bus = dev->bus;
+       resource_size_t end = 0;
+
+       for (i = PCI_BRIDGE_RESOURCES; i < PCI_BRIDGE_RESOURCES+3; i++) {
+               unsigned long flags = pci_resource_flags(dev, i);
+               if ((flags & (IORESOURCE_MEM|IORESOURCE_PREFETCH)) == IORESOURCE_MEM)
+                       end = pci_resource_end(dev, i);
+       }
 
        for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
                if ((bus->resource[i]) &&
                        (bus->resource[i]->flags & IORESOURCE_MEM)) {
-                       dummy = ioremap(bus->resource[i]->end - 3, 0x4);
+                       if (bus->resource[i]->end == end)
+                               dummy = ioremap(bus->resource[i]->start, 0x4);
+                       else
+                               dummy = ioremap(bus->resource[i]->end - 3, 0x4);
                        if (dummy) {
                                in_8(dummy);
                                iounmap(dummy);
index ca114fe..06acb1a 100644 (file)
@@ -169,6 +169,8 @@ void init_cpu_timer(void)
 
 static void clock_comparator_interrupt(__u16 code)
 {
+       if (S390_lowcore.clock_comparator == -1ULL)
+               set_clock_comparator(S390_lowcore.clock_comparator);
 }
 
 static void etr_timing_alert(struct etr_irq_parm *);
index fc6ab60..0953cee 100644 (file)
@@ -1,14 +1,9 @@
 /*
- *  arch/s390/lib/delay.c
  *    Precise Delay Loops for S390
  *
- *  S390 version
- *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
- *
- *  Derived from "arch/i386/lib/delay.c"
- *    Copyright (C) 1993 Linus Torvalds
- *    Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ *    Copyright IBM Corp. 1999,2008
+ *    Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ *              Heiko Carstens <heiko.carstens@de.ibm.com>,
  */
 
 #include <linux/sched.h>
@@ -29,30 +24,31 @@ void __delay(unsigned long loops)
        asm volatile("0: brct %0,0b" : : "d" ((loops/2) + 1));
 }
 
-/*
- * Waits for 'usecs' microseconds using the TOD clock comparator.
- */
-void __udelay(unsigned long usecs)
+static void __udelay_disabled(unsigned long usecs)
 {
-       u64 end, time, old_cc = 0;
-       unsigned long flags, cr0, mask, dummy;
-       int irq_context;
+       unsigned long mask, cr0, cr0_saved;
+       u64 clock_saved;
 
-       irq_context = in_interrupt();
-       if (!irq_context)
-               local_bh_disable();
-       local_irq_save(flags);
-       if (raw_irqs_disabled_flags(flags)) {
-               old_cc = local_tick_disable();
-               S390_lowcore.clock_comparator = -1ULL;
-               __ctl_store(cr0, 0, 0);
-               dummy = (cr0 & 0xffff00e0) | 0x00000800;
-               __ctl_load(dummy , 0, 0);
-               mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT;
-       } else
-               mask = psw_kernel_bits | PSW_MASK_WAIT |
-                       PSW_MASK_EXT | PSW_MASK_IO;
+       clock_saved = local_tick_disable();
+       set_clock_comparator(get_clock() + ((u64) usecs << 12));
+       __ctl_store(cr0_saved, 0, 0);
+       cr0 = (cr0_saved & 0xffff00e0) | 0x00000800;
+       __ctl_load(cr0 , 0, 0);
+       mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT;
+       trace_hardirqs_on();
+       __load_psw_mask(mask);
+       local_irq_disable();
+       __ctl_load(cr0_saved, 0, 0);
+       local_tick_enable(clock_saved);
+       set_clock_comparator(S390_lowcore.clock_comparator);
+}
 
+static void __udelay_enabled(unsigned long usecs)
+{
+       unsigned long mask;
+       u64 end, time;
+
+       mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT | PSW_MASK_IO;
        end = get_clock() + ((u64) usecs << 12);
        do {
                time = end < S390_lowcore.clock_comparator ?
@@ -62,13 +58,37 @@ void __udelay(unsigned long usecs)
                __load_psw_mask(mask);
                local_irq_disable();
        } while (get_clock() < end);
+       set_clock_comparator(S390_lowcore.clock_comparator);
+}
 
-       if (raw_irqs_disabled_flags(flags)) {
-               __ctl_load(cr0, 0, 0);
-               local_tick_enable(old_cc);
+/*
+ * Waits for 'usecs' microseconds using the TOD clock comparator.
+ */
+void __udelay(unsigned long usecs)
+{
+       unsigned long flags;
+
+       preempt_disable();
+       local_irq_save(flags);
+       if (in_irq()) {
+               __udelay_disabled(usecs);
+               goto out;
+       }
+       if (in_softirq()) {
+               if (raw_irqs_disabled_flags(flags))
+                       __udelay_disabled(usecs);
+               else
+                       __udelay_enabled(usecs);
+               goto out;
        }
-       if (!irq_context)
+       if (raw_irqs_disabled_flags(flags)) {
+               local_bh_disable();
+               __udelay_disabled(usecs);
                _local_bh_enable();
-       set_clock_comparator(S390_lowcore.clock_comparator);
+               goto out;
+       }
+       __udelay_enabled(usecs);
+out:
        local_irq_restore(flags);
+       preempt_enable();
 }
index 2396388..7495bc7 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/linkage.h>
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/kernel_stat.h>
@@ -866,7 +867,7 @@ static void kill_prom_timer(void)
        : "g1", "g2");
 }
 
-void init_irqwork_curcpu(void)
+void notrace init_irqwork_curcpu(void)
 {
        int cpu = hard_smp_processor_id();
 
@@ -897,7 +898,7 @@ static void __cpuinit register_one_mondo(unsigned long paddr, unsigned long type
        }
 }
 
-void __cpuinit sun4v_register_mondo_queues(int this_cpu)
+void __cpuinit notrace sun4v_register_mondo_queues(int this_cpu)
 {
        struct trap_per_cpu *tb = &trap_block[this_cpu];
 
index f845f15..100ebd5 100644 (file)
@@ -169,7 +169,7 @@ static unsigned long of_bus_default_get_flags(const u32 *addr, unsigned long fla
 
 static int of_bus_pci_match(struct device_node *np)
 {
-       if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) {
+       if (!strcmp(np->name, "pci")) {
                const char *model = of_get_property(np, "model", NULL);
 
                if (model && !strcmp(model, "SUNW,simba"))
@@ -200,7 +200,7 @@ static int of_bus_simba_match(struct device_node *np)
        /* Treat PCI busses lacking ranges property just like
         * simba.
         */
-       if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) {
+       if (!strcmp(np->name, "pci")) {
                if (!of_find_property(np, "ranges", NULL))
                        return 1;
        }
@@ -429,7 +429,7 @@ static int __init use_1to1_mapping(struct device_node *pp)
         * it lacks a ranges property, and this will include
         * cases like Simba.
         */
-       if (!strcmp(pp->type, "pci") || !strcmp(pp->type, "pciex"))
+       if (!strcmp(pp->name, "pci"))
                return 0;
 
        return 1;
@@ -714,8 +714,7 @@ static unsigned int __init build_one_device_irq(struct of_device *op,
                                break;
                        }
                } else {
-                       if (!strcmp(pp->type, "pci") ||
-                           !strcmp(pp->type, "pciex")) {
+                       if (!strcmp(pp->name, "pci")) {
                                unsigned int this_orig_irq = irq;
 
                                irq = pci_irq_swizzle(dp, pp, irq);
index 5509619..80dad76 100644 (file)
@@ -425,7 +425,7 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
        dev->current_state = 4;         /* unknown power state */
        dev->error_state = pci_channel_io_normal;
 
-       if (!strcmp(type, "pci") || !strcmp(type, "pciex")) {
+       if (!strcmp(node->name, "pci")) {
                /* a PCI-PCI bridge */
                dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
                dev->rom_base_reg = PCI_ROM_ADDRESS1;
index e205ade..f85b6be 100644 (file)
@@ -575,7 +575,7 @@ static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm, int is_pbm
 {
        unsigned long csr_reg, csr, csr_error_bits;
        irqreturn_t ret = IRQ_NONE;
-       u16 stat;
+       u16 stat, *addr;
 
        if (is_pbm_a) {
                csr_reg = pbm->controller_regs + PSYCHO_PCIA_CTRL;
@@ -597,7 +597,9 @@ static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm, int is_pbm
                        printk("%s: PCI SERR signal asserted.\n", pbm->name);
                ret = IRQ_HANDLED;
        }
-       pci_read_config_word(pbm->pci_bus->self, PCI_STATUS, &stat);
+       addr = psycho_pci_config_mkaddr(pbm, pbm->pci_first_busno,
+                                       0, PCI_STATUS);
+       pci_config_read16(addr, &stat);
        if (stat & (PCI_STATUS_PARITY |
                    PCI_STATUS_SIG_TARGET_ABORT |
                    PCI_STATUS_REC_TARGET_ABORT |
@@ -605,7 +607,7 @@ static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm, int is_pbm
                    PCI_STATUS_SIG_SYSTEM_ERROR)) {
                printk("%s: PCI bus error, PCI_STATUS[%04x]\n",
                       pbm->name, stat);
-               pci_write_config_word(pbm->pci_bus->self, PCI_STATUS, 0xffff);
+               pci_config_write16(addr, 0xffff);
                ret = IRQ_HANDLED;
        }
        return ret;
index 3d92412..c824df1 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/linkage.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
 #include <linux/smp.h>
@@ -2453,7 +2454,7 @@ struct trap_per_cpu trap_block[NR_CPUS];
 /* This can get invoked before sched_init() so play it super safe
  * and use hard_smp_processor_id().
  */
-void init_cur_cpu_trap(struct thread_info *t)
+void notrace init_cur_cpu_trap(struct thread_info *t)
 {
        int cpu = hard_smp_processor_id();
        struct trap_per_cpu *p = &trap_block[cpu];
index a1310c5..857e492 100644 (file)
@@ -492,7 +492,7 @@ static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym))
                        continue;
                }
                sh_symtab = sec_symtab->symtab;
-               sym_strtab = sec->link->strtab;
+               sym_strtab = sec_symtab->link->strtab;
                for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {
                        Elf32_Rel *rel;
                        Elf32_Sym *sym;
index bfd10fd..c102af8 100644 (file)
@@ -1603,6 +1603,14 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = {
         * is not connected at all.  Force ignoring BIOS IRQ0 pin2
         * override in that cases.
         */
+       {
+        .callback = dmi_ignore_irq0_timer_override,
+        .ident = "HP nx6115 laptop",
+        .matches = {
+                    DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+                    DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6115"),
+                    },
+        },
        {
         .callback = dmi_ignore_irq0_timer_override,
         .ident = "HP NX6125 laptop",
@@ -1619,6 +1627,14 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = {
                     DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"),
                     },
         },
+       {
+        .callback = dmi_ignore_irq0_timer_override,
+        .ident = "HP 6715b laptop",
+        .matches = {
+                    DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+                    DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6715b"),
+                    },
+        },
        {}
 };
 
index 69b4d06..042fdc2 100644 (file)
@@ -101,10 +101,10 @@ static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
  */
 static int iommu_completion_wait(struct amd_iommu *iommu)
 {
-       int ret, ready = 0;
+       int ret = 0, ready = 0;
        unsigned status = 0;
        struct iommu_cmd cmd;
-       unsigned long i = 0;
+       unsigned long flags, i = 0;
 
        memset(&cmd, 0, sizeof(cmd));
        cmd.data[0] = CMD_COMPL_WAIT_INT_MASK;
@@ -112,10 +112,12 @@ static int iommu_completion_wait(struct amd_iommu *iommu)
 
        iommu->need_sync = 0;
 
-       ret = iommu_queue_command(iommu, &cmd);
+       spin_lock_irqsave(&iommu->lock, flags);
+
+       ret = __iommu_queue_command(iommu, &cmd);
 
        if (ret)
-               return ret;
+               goto out;
 
        while (!ready && (i < EXIT_LOOP_COUNT)) {
                ++i;
@@ -130,6 +132,8 @@ static int iommu_completion_wait(struct amd_iommu *iommu)
 
        if (unlikely((i == EXIT_LOOP_COUNT) && printk_ratelimit()))
                printk(KERN_WARNING "AMD IOMMU: Completion wait loop failed\n");
+out:
+       spin_unlock_irqrestore(&iommu->lock, flags);
 
        return 0;
 }
@@ -140,6 +144,7 @@ static int iommu_completion_wait(struct amd_iommu *iommu)
 static int iommu_queue_inv_dev_entry(struct amd_iommu *iommu, u16 devid)
 {
        struct iommu_cmd cmd;
+       int ret;
 
        BUG_ON(iommu == NULL);
 
@@ -147,9 +152,11 @@ static int iommu_queue_inv_dev_entry(struct amd_iommu *iommu, u16 devid)
        CMD_SET_TYPE(&cmd, CMD_INV_DEV_ENTRY);
        cmd.data[0] = devid;
 
+       ret = iommu_queue_command(iommu, &cmd);
+
        iommu->need_sync = 1;
 
-       return iommu_queue_command(iommu, &cmd);
+       return ret;
 }
 
 /*
@@ -159,6 +166,7 @@ static int iommu_queue_inv_iommu_pages(struct amd_iommu *iommu,
                u64 address, u16 domid, int pde, int s)
 {
        struct iommu_cmd cmd;
+       int ret;
 
        memset(&cmd, 0, sizeof(cmd));
        address &= PAGE_MASK;
@@ -171,9 +179,11 @@ static int iommu_queue_inv_iommu_pages(struct amd_iommu *iommu,
        if (pde) /* PDE bit - we wan't flush everything not only the PTEs */
                cmd.data[2] |= CMD_INV_IOMMU_PAGES_PDE_MASK;
 
+       ret = iommu_queue_command(iommu, &cmd);
+
        iommu->need_sync = 1;
 
-       return iommu_queue_command(iommu, &cmd);
+       return ret;
 }
 
 /*
index 9ee24e6..732d1f4 100644 (file)
 #include <asm/uaccess.h>
 #include <asm/desc.h>
 #include <asm/i8253.h>
+#include <asm/olpc.h>
 #include <asm/paravirt.h>
 #include <asm/reboot.h>
 
@@ -2217,7 +2218,7 @@ static int __init apm_init(void)
 
        dmi_check_system(apm_dmi_table);
 
-       if (apm_info.bios.version == 0 || paravirt_enabled()) {
+       if (apm_info.bios.version == 0 || paravirt_enabled() || machine_is_olpc()) {
                printk(KERN_INFO "apm: BIOS not found.\n");
                return -ENODEV;
        }
index 8aab851..4e456bd 100644 (file)
@@ -344,31 +344,15 @@ static void __init early_cpu_detect(void)
 
 /*
  * The NOPL instruction is supposed to exist on all CPUs with
- * family >= 6, unfortunately, that's not true in practice because
+ * family >= 6; unfortunately, that's not true in practice because
  * of early VIA chips and (more importantly) broken virtualizers that
- * are not easy to detect.  Hence, probe for it based on first
- * principles.
+ * are not easy to detect.  In the latter case it doesn't even *fail*
+ * reliably, so probing for it doesn't even work.  Disable it completely
+ * unless we can find a reliable way to detect all the broken cases.
  */
 static void __cpuinit detect_nopl(struct cpuinfo_x86 *c)
 {
-       const u32 nopl_signature = 0x888c53b1; /* Random number */
-       u32 has_nopl = nopl_signature;
-
        clear_cpu_cap(c, X86_FEATURE_NOPL);
-       if (c->x86 >= 6) {
-               asm volatile("\n"
-                            "1:      .byte 0x0f,0x1f,0xc0\n" /* nopl %eax */
-                            "2:\n"
-                            "        .section .fixup,\"ax\"\n"
-                            "3:      xor %0,%0\n"
-                            "        jmp 2b\n"
-                            "        .previous\n"
-                            _ASM_EXTABLE(1b,3b)
-                            : "+a" (has_nopl));
-
-               if (has_nopl == nopl_signature)
-                       set_cpu_cap(c, X86_FEATURE_NOPL);
-       }
 }
 
 static void __cpuinit generic_identify(struct cpuinfo_x86 *c)
index f1685fb..b8e05ee 100644 (file)
@@ -171,7 +171,7 @@ static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c)
        }
 
        if (c->x86 != 0xF) {
-               printk(KERN_WARNING PFX "Unknown p4-clockmod-capable CPU. Please send an e-mail to <cpufreq@lists.linux.org.uk>\n");
+               printk(KERN_WARNING PFX "Unknown p4-clockmod-capable CPU. Please send an e-mail to <cpufreq@vger.kernel.org>\n");
                return 0;
        }
 
index 15e13c0..3b5f064 100644 (file)
@@ -26,7 +26,7 @@
 #include <asm/cpufeature.h>
 
 #define PFX            "speedstep-centrino: "
-#define MAINTAINER     "cpufreq@lists.linux.org.uk"
+#define MAINTAINER     "cpufreq@vger.kernel.org"
 
 #define dprintk(msg...) \
        cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-centrino", msg)
index b117d7f..885c826 100644 (file)
@@ -834,7 +834,7 @@ static int __init enable_mtrr_cleanup_setup(char *str)
                enable_mtrr_cleanup = 1;
        return 0;
 }
-early_param("enble_mtrr_cleanup", enable_mtrr_cleanup_setup);
+early_param("enable_mtrr_cleanup", enable_mtrr_cleanup_setup);
 
 struct var_mtrr_state {
        unsigned long   range_startk;
index f2d43bc..ff7d3b0 100644 (file)
@@ -139,6 +139,7 @@ static int __init create_setup_data_nodes(struct dentry *parent)
                if (PageHighMem(pg)) {
                        data = ioremap_cache(pa_data, sizeof(*data));
                        if (!data) {
+                               kfree(node);
                                error = -ENXIO;
                                goto err_dir;
                        }
index f47f0eb..10435a1 100644 (file)
@@ -69,6 +69,9 @@ static int gdb_x86vector = -1;
  */
 void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 {
+#ifndef CONFIG_X86_32
+       u32 *gdb_regs32 = (u32 *)gdb_regs;
+#endif
        gdb_regs[GDB_AX]        = regs->ax;
        gdb_regs[GDB_BX]        = regs->bx;
        gdb_regs[GDB_CX]        = regs->cx;
@@ -76,9 +79,9 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
        gdb_regs[GDB_SI]        = regs->si;
        gdb_regs[GDB_DI]        = regs->di;
        gdb_regs[GDB_BP]        = regs->bp;
-       gdb_regs[GDB_PS]        = regs->flags;
        gdb_regs[GDB_PC]        = regs->ip;
 #ifdef CONFIG_X86_32
+       gdb_regs[GDB_PS]        = regs->flags;
        gdb_regs[GDB_DS]        = regs->ds;
        gdb_regs[GDB_ES]        = regs->es;
        gdb_regs[GDB_CS]        = regs->cs;
@@ -94,6 +97,9 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
        gdb_regs[GDB_R13]       = regs->r13;
        gdb_regs[GDB_R14]       = regs->r14;
        gdb_regs[GDB_R15]       = regs->r15;
+       gdb_regs32[GDB_PS]      = regs->flags;
+       gdb_regs32[GDB_CS]      = regs->cs;
+       gdb_regs32[GDB_SS]      = regs->ss;
 #endif
        gdb_regs[GDB_SP]        = regs->sp;
 }
@@ -112,6 +118,9 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
  */
 void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
 {
+#ifndef CONFIG_X86_32
+       u32 *gdb_regs32 = (u32 *)gdb_regs;
+#endif
        gdb_regs[GDB_AX]        = 0;
        gdb_regs[GDB_BX]        = 0;
        gdb_regs[GDB_CX]        = 0;
@@ -129,8 +138,10 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
        gdb_regs[GDB_FS]        = 0xFFFF;
        gdb_regs[GDB_GS]        = 0xFFFF;
 #else
-       gdb_regs[GDB_PS]        = *(unsigned long *)(p->thread.sp + 8);
-       gdb_regs[GDB_PC]        = 0;
+       gdb_regs32[GDB_PS]      = *(unsigned long *)(p->thread.sp + 8);
+       gdb_regs32[GDB_CS]      = __KERNEL_CS;
+       gdb_regs32[GDB_SS]      = __KERNEL_DS;
+       gdb_regs[GDB_PC]        = p->thread.ip;
        gdb_regs[GDB_R8]        = 0;
        gdb_regs[GDB_R9]        = 0;
        gdb_regs[GDB_R10]       = 0;
@@ -153,6 +164,9 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
  */
 void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 {
+#ifndef CONFIG_X86_32
+       u32 *gdb_regs32 = (u32 *)gdb_regs;
+#endif
        regs->ax                = gdb_regs[GDB_AX];
        regs->bx                = gdb_regs[GDB_BX];
        regs->cx                = gdb_regs[GDB_CX];
@@ -160,9 +174,9 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
        regs->si                = gdb_regs[GDB_SI];
        regs->di                = gdb_regs[GDB_DI];
        regs->bp                = gdb_regs[GDB_BP];
-       regs->flags             = gdb_regs[GDB_PS];
        regs->ip                = gdb_regs[GDB_PC];
 #ifdef CONFIG_X86_32
+       regs->flags             = gdb_regs[GDB_PS];
        regs->ds                = gdb_regs[GDB_DS];
        regs->es                = gdb_regs[GDB_ES];
        regs->cs                = gdb_regs[GDB_CS];
@@ -175,6 +189,9 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
        regs->r13               = gdb_regs[GDB_R13];
        regs->r14               = gdb_regs[GDB_R14];
        regs->r15               = gdb_regs[GDB_R15];
+       regs->flags             = gdb_regs32[GDB_PS];
+       regs->cs                = gdb_regs32[GDB_CS];
+       regs->ss                = gdb_regs32[GDB_SS];
 #endif
 }
 
@@ -378,10 +395,8 @@ int kgdb_arch_handle_exception(int e_vector, int signo, int err_code,
                if (remcomInBuffer[0] == 's') {
                        linux_regs->flags |= X86_EFLAGS_TF;
                        kgdb_single_step = 1;
-                       if (kgdb_contthread) {
-                               atomic_set(&kgdb_cpu_doing_single_step,
-                                          raw_smp_processor_id());
-                       }
+                       atomic_set(&kgdb_cpu_doing_single_step,
+                                  raw_smp_processor_id());
                }
 
                get_debugreg(dr6, 6);
@@ -440,12 +455,7 @@ static int __kgdb_notify(struct die_args *args, unsigned long cmd)
                return NOTIFY_DONE;
 
        case DIE_NMI_IPI:
-               if (atomic_read(&kgdb_active) != -1) {
-                       /* KGDB CPU roundup */
-                       kgdb_nmicallback(raw_smp_processor_id(), regs);
-                       was_in_debug_nmi[raw_smp_processor_id()] = 1;
-                       touch_nmi_watchdog();
-               }
+               /* Just ignore, we will handle the roundup on DIE_NMI. */
                return NOTIFY_DONE;
 
        case DIE_NMIUNKNOWN:
@@ -466,9 +476,15 @@ static int __kgdb_notify(struct die_args *args, unsigned long cmd)
 
        case DIE_DEBUG:
                if (atomic_read(&kgdb_cpu_doing_single_step) ==
-                       raw_smp_processor_id() &&
-                       user_mode(regs))
-                       return single_step_cont(regs, args);
+                   raw_smp_processor_id()) {
+                       if (user_mode(regs))
+                               return single_step_cont(regs, args);
+                       break;
+               } else if (test_thread_flag(TIF_SINGLESTEP))
+                       /* This means a user thread is single stepping
+                        * a system call which should be ignored
+                        */
+                       return NOTIFY_DONE;
                /* fall through */
        default:
                if (user_mode(regs))
index 49285f8..be33a54 100644 (file)
@@ -626,7 +626,6 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
        struct pci_dev *dev;
        void *gatt;
        int i, error;
-       unsigned long start_pfn, end_pfn;
 
        printk(KERN_INFO "PCI-DMA: Disabling AGP.\n");
        aper_size = aper_base = info->aper_size = 0;
@@ -672,12 +671,6 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
        printk(KERN_INFO "PCI-DMA: aperture base @ %x size %u KB\n",
               aper_base, aper_size>>10);
 
-       /* need to map that range */
-       end_pfn = (aper_base>>PAGE_SHIFT) + (aper_size>>PAGE_SHIFT);
-       if (end_pfn > max_low_pfn_mapped) {
-               start_pfn = (aper_base>>PAGE_SHIFT);
-               init_memory_mapping(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
-       }
        return 0;
 
  nommu:
@@ -727,7 +720,8 @@ void __init gart_iommu_init(void)
 {
        struct agp_kern_info info;
        unsigned long iommu_start;
-       unsigned long aper_size;
+       unsigned long aper_base, aper_size;
+       unsigned long start_pfn, end_pfn;
        unsigned long scratch;
        long i;
 
@@ -765,8 +759,16 @@ void __init gart_iommu_init(void)
                return;
        }
 
+       /* need to map that range */
+       aper_size = info.aper_size << 20;
+       aper_base = info.aper_base;
+       end_pfn = (aper_base>>PAGE_SHIFT) + (aper_size>>PAGE_SHIFT);
+       if (end_pfn > max_low_pfn_mapped) {
+               start_pfn = (aper_base>>PAGE_SHIFT);
+               init_memory_mapping(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
+       }
+
        printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n");
-       aper_size = info.aper_size * 1024 * 1024;
        iommu_size = check_iommu_size(info.aper_base, aper_size);
        iommu_pages = iommu_size >> PAGE_SHIFT;
 
index 7fc4d5b..876e918 100644 (file)
@@ -246,6 +246,14 @@ static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c)
        return 1;
 }
 
+static cpumask_t c1e_mask = CPU_MASK_NONE;
+static int c1e_detected;
+
+void c1e_remove_cpu(int cpu)
+{
+       cpu_clear(cpu, c1e_mask);
+}
+
 /*
  * C1E aware idle routine. We check for C1E active in the interrupt
  * pending message MSR. If we detect C1E, then we handle it the same
@@ -253,9 +261,6 @@ static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c)
  */
 static void c1e_idle(void)
 {
-       static cpumask_t c1e_mask = CPU_MASK_NONE;
-       static int c1e_detected;
-
        if (need_resched())
                return;
 
@@ -265,8 +270,10 @@ static void c1e_idle(void)
                rdmsr(MSR_K8_INT_PENDING_MSG, lo, hi);
                if (lo & K8_INTP_C1E_ACTIVE_MASK) {
                        c1e_detected = 1;
-                       mark_tsc_unstable("TSC halt in C1E");
-                       printk(KERN_INFO "System has C1E enabled\n");
+                       if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
+                               mark_tsc_unstable("TSC halt in AMD C1E");
+                       printk(KERN_INFO "System has AMD C1E enabled\n");
+                       set_cpu_cap(&boot_cpu_data, X86_FEATURE_AMDC1E);
                }
        }
 
index 3b7a1dd..31f40b2 100644 (file)
@@ -55,6 +55,7 @@
 #include <asm/tlbflush.h>
 #include <asm/cpu.h>
 #include <asm/kdebug.h>
+#include <asm/idle.h>
 
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 
@@ -88,6 +89,7 @@ static void cpu_exit_clear(void)
        cpu_clear(cpu, cpu_callin_map);
 
        numa_remove_cpu(cpu);
+       c1e_remove_cpu(cpu);
 }
 
 /* We don't actually take CPU down, just spin without interrupts. */
index 71553b6..e12e0e4 100644 (file)
@@ -93,6 +93,8 @@ DECLARE_PER_CPU(int, cpu_state);
 static inline void play_dead(void)
 {
        idle_task_exit();
+       c1e_remove_cpu(raw_smp_processor_id());
+
        mb();
        /* Ack it */
        __get_cpu_var(cpu_state) = CPU_DEAD;
index 362d4e7..9838f25 100644 (file)
@@ -670,6 +670,10 @@ void __init setup_arch(char **cmdline_p)
 
        parse_early_param();
 
+#ifdef CONFIG_X86_64
+       check_efer();
+#endif
+
 #if defined(CONFIG_VMI) && defined(CONFIG_X86_32)
        /*
         * Must be before kernel pagetables are setup
@@ -738,7 +742,6 @@ void __init setup_arch(char **cmdline_p)
 #else
        num_physpages = max_pfn;
 
-       check_efer();
 
        /* How many end-of-memory variables you have, grandma! */
        /* need this before calling reserve_initrd */
index 6ca515d..edfb09f 100644 (file)
@@ -235,7 +235,7 @@ static void vmi_write_ldt_entry(struct desc_struct *dt, int entry,
                                const void *desc)
 {
        u32 *ldt_entry = (u32 *)desc;
-       vmi_ops.write_idt_entry(dt, entry, ldt_entry[0], ldt_entry[1]);
+       vmi_ops.write_ldt_entry(dt, entry, ldt_entry[0], ldt_entry[1]);
 }
 
 static void vmi_load_sp0(struct tss_struct *tss,
index 0c029e8..7766d36 100644 (file)
@@ -61,7 +61,7 @@ static void vsmp_irq_enable(void)
        native_restore_fl((flags | X86_EFLAGS_IF) & (~X86_EFLAGS_AC));
 }
 
-static unsigned __init vsmp_patch(u8 type, u16 clobbers, void *ibuf,
+static unsigned __init_or_module vsmp_patch(u8 type, u16 clobbers, void *ibuf,
                                  unsigned long addr, unsigned len)
 {
        switch (type) {
index d37f293..60ec1d0 100644 (file)
@@ -458,11 +458,7 @@ static void __init pagetable_init(void)
 {
        pgd_t *pgd_base = swapper_pg_dir;
 
-       paravirt_pagetable_setup_start(pgd_base);
-
        permanent_kmaps_init(pgd_base);
-
-       paravirt_pagetable_setup_done(pgd_base);
 }
 
 #ifdef CONFIG_ACPI_SLEEP
index 0227694..8a5f161 100644 (file)
@@ -295,10 +295,12 @@ static void nmi_cpu_shutdown(void *dummy)
 
 static void nmi_shutdown(void)
 {
-       struct op_msrs *msrs = &get_cpu_var(cpu_msrs);
+       struct op_msrs *msrs;
+
        nmi_enabled = 0;
        on_each_cpu(nmi_cpu_shutdown, NULL, 1);
        unregister_die_notifier(&profile_exceptions_nb);
+       msrs = &get_cpu_var(cpu_msrs);
        model->shutdown(msrs);
        free_msrs();
        put_cpu_var(cpu_msrs);
index b6acc3a..d679010 100644 (file)
@@ -42,7 +42,7 @@ char * __init xen_memory_setup(void)
 
        e820.nr_map = 0;
 
-       e820_add_region(0, PFN_PHYS(max_pfn), E820_RAM);
+       e820_add_region(0, PFN_PHYS((u64)max_pfn), E820_RAM);
 
        /*
         * Even though this is normal, usable memory under Xen, reserve
index 0a5f6b2..d672cfe 100644 (file)
@@ -376,6 +376,8 @@ int braille_register_console(struct console *console, int index,
        console->flags |= CON_ENABLED;
        console->index = index;
        braille_co = console;
+       register_keyboard_notifier(&keyboard_notifier_block);
+       register_vt_notifier(&vt_notifier_block);
        return 0;
 }
 
@@ -383,15 +385,8 @@ int braille_unregister_console(struct console *console)
 {
        if (braille_co != console)
                return -EINVAL;
+       unregister_keyboard_notifier(&keyboard_notifier_block);
+       unregister_vt_notifier(&vt_notifier_block);
        braille_co = NULL;
        return 0;
 }
-
-static int __init braille_init(void)
-{
-       register_keyboard_notifier(&keyboard_notifier_block);
-       register_vt_notifier(&vt_notifier_block);
-       return 0;
-}
-
-console_initcall(braille_init);
index 0841095..8dd3336 100644 (file)
@@ -165,8 +165,11 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle)
                                "firmware_node");
                ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
                                "physical_node");
-               if (acpi_dev->wakeup.flags.valid)
+               if (acpi_dev->wakeup.flags.valid) {
                        device_set_wakeup_capable(dev, true);
+                       device_set_wakeup_enable(dev,
+                                               acpi_dev->wakeup.state.enabled);
+               }
        }
 
        return 0;
index 4ebbba2..bf5b04d 100644 (file)
@@ -377,6 +377,14 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
        return 0;
 }
 
+static void physical_device_enable_wakeup(struct acpi_device *adev)
+{
+       struct device *dev = acpi_get_physical_device(adev->handle);
+
+       if (dev && device_can_wakeup(dev))
+               device_set_wakeup_enable(dev, adev->wakeup.state.enabled);
+}
+
 static ssize_t
 acpi_system_write_wakeup_device(struct file *file,
                                const char __user * buffer,
@@ -411,6 +419,7 @@ acpi_system_write_wakeup_device(struct file *file,
                }
        }
        if (found_dev) {
+               physical_device_enable_wakeup(found_dev);
                list_for_each_safe(node, next, &acpi_wakeup_device_list) {
                        struct acpi_device *dev = container_of(node,
                                                               struct
@@ -428,6 +437,7 @@ acpi_system_write_wakeup_device(struct file *file,
                                       dev->pnp.bus_id, found_dev->pnp.bus_id);
                                dev->wakeup.state.enabled =
                                    found_dev->wakeup.state.enabled;
+                               physical_device_enable_wakeup(dev);
                        }
                }
        }
index 1e1f3f3..14601dc 100644 (file)
@@ -309,6 +309,8 @@ static void nv_nf2_freeze(struct ata_port *ap);
 static void nv_nf2_thaw(struct ata_port *ap);
 static void nv_ck804_freeze(struct ata_port *ap);
 static void nv_ck804_thaw(struct ata_port *ap);
+static int nv_hardreset(struct ata_link *link, unsigned int *class,
+                       unsigned long deadline);
 static int nv_adma_slave_config(struct scsi_device *sdev);
 static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc);
 static void nv_adma_qc_prep(struct ata_queued_cmd *qc);
@@ -403,28 +405,45 @@ static struct scsi_host_template nv_swncq_sht = {
        .slave_configure        = nv_swncq_slave_config,
 };
 
-static struct ata_port_operations nv_generic_ops = {
+/* OSDL bz3352 reports that some nv controllers can't determine device
+ * signature reliably and nv_hardreset is implemented to work around
+ * the problem.  This was reported on nf3 and it's unclear whether any
+ * other controllers are affected.  However, the workaround has been
+ * applied to all variants and there isn't much to gain by trying to
+ * find out exactly which ones are affected at this point especially
+ * because NV has moved over to ahci for newer controllers.
+ */
+static struct ata_port_operations nv_common_ops = {
        .inherits               = &ata_bmdma_port_ops,
-       .hardreset              = ATA_OP_NULL,
+       .hardreset              = nv_hardreset,
        .scr_read               = nv_scr_read,
        .scr_write              = nv_scr_write,
 };
 
+/* OSDL bz11195 reports that link doesn't come online after hardreset
+ * on generic nv's and there have been several other similar reports
+ * on linux-ide.  Disable hardreset for generic nv's.
+ */
+static struct ata_port_operations nv_generic_ops = {
+       .inherits               = &nv_common_ops,
+       .hardreset              = ATA_OP_NULL,
+};
+
 static struct ata_port_operations nv_nf2_ops = {
-       .inherits               = &nv_generic_ops,
+       .inherits               = &nv_common_ops,
        .freeze                 = nv_nf2_freeze,
        .thaw                   = nv_nf2_thaw,
 };
 
 static struct ata_port_operations nv_ck804_ops = {
-       .inherits               = &nv_generic_ops,
+       .inherits               = &nv_common_ops,
        .freeze                 = nv_ck804_freeze,
        .thaw                   = nv_ck804_thaw,
        .host_stop              = nv_ck804_host_stop,
 };
 
 static struct ata_port_operations nv_adma_ops = {
-       .inherits               = &nv_generic_ops,
+       .inherits               = &nv_common_ops,
 
        .check_atapi_dma        = nv_adma_check_atapi_dma,
        .sff_tf_read            = nv_adma_tf_read,
@@ -448,7 +467,7 @@ static struct ata_port_operations nv_adma_ops = {
 };
 
 static struct ata_port_operations nv_swncq_ops = {
-       .inherits               = &nv_generic_ops,
+       .inherits               = &nv_common_ops,
 
        .qc_defer               = ata_std_qc_defer,
        .qc_prep                = nv_swncq_qc_prep,
@@ -1586,6 +1605,21 @@ static void nv_mcp55_thaw(struct ata_port *ap)
        ata_sff_thaw(ap);
 }
 
+static int nv_hardreset(struct ata_link *link, unsigned int *class,
+                       unsigned long deadline)
+{
+       int rc;
+
+       /* SATA hardreset fails to retrieve proper device signature on
+        * some controllers.  Request follow up SRST.  For more info,
+        * see http://bugzilla.kernel.org/show_bug.cgi?id=3352
+        */
+       rc = sata_sff_hardreset(link, class, deadline);
+       if (rc)
+               return rc;
+       return -EAGAIN;
+}
+
 static void nv_adma_error_handler(struct ata_port *ap)
 {
        struct nv_adma_port_priv *pp = ap->private_data;
index 1e55a65..32f3a8e 100644 (file)
@@ -256,7 +256,6 @@ static inline int bpa10x_submit_intr_urb(struct hci_dev *hdev)
                BT_ERR("%s urb %p submission failed (%d)",
                                                hdev->name, urb, -err);
                usb_unanchor_urb(urb);
-               kfree(buf);
        }
 
        usb_free_urb(urb);
@@ -298,7 +297,6 @@ static inline int bpa10x_submit_bulk_urb(struct hci_dev *hdev)
                BT_ERR("%s urb %p submission failed (%d)",
                                                hdev->name, urb, -err);
                usb_unanchor_urb(urb);
-               kfree(buf);
        }
 
        usb_free_urb(urb);
index 6a01068..af472e0 100644 (file)
@@ -102,14 +102,19 @@ static struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x0a5c, 0x2101), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
 
        /* Broadcom BCM2046 */
+       { USB_DEVICE(0x0a5c, 0x2146), .driver_info = BTUSB_RESET },
        { USB_DEVICE(0x0a5c, 0x2151), .driver_info = BTUSB_RESET },
 
+       /* Apple MacBook Pro with Broadcom chip */
+       { USB_DEVICE(0x05ac, 0x820f), .driver_info = BTUSB_RESET },
+
        /* IBM/Lenovo ThinkPad with Broadcom chip */
        { USB_DEVICE(0x0a5c, 0x201e), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
        { USB_DEVICE(0x0a5c, 0x2110), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
 
        /* Targus ACB10US */
        { USB_DEVICE(0x0a5c, 0x2100), .driver_info = BTUSB_RESET },
+       { USB_DEVICE(0x0a5c, 0x2154), .driver_info = BTUSB_RESET },
 
        /* ANYCOM Bluetooth USB-200 and USB-250 */
        { USB_DEVICE(0x0a5c, 0x2111), .driver_info = BTUSB_RESET },
@@ -147,6 +152,9 @@ static struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x050d, 0x0012), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
        { USB_DEVICE(0x050d, 0x0013), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
 
+       /* Belkin F8T016 device */
+       { USB_DEVICE(0x050d, 0x016a), .driver_info = BTUSB_RESET },
+
        /* Digianswer devices */
        { USB_DEVICE(0x08fd, 0x0001), .driver_info = BTUSB_DIGIANSWER },
        { USB_DEVICE(0x08fd, 0x0002), .driver_info = BTUSB_IGNORE },
@@ -169,6 +177,7 @@ static struct usb_device_id blacklist_table[] = {
 struct btusb_data {
        struct hci_dev       *hdev;
        struct usb_device    *udev;
+       struct usb_interface *intf;
        struct usb_interface *isoc;
 
        spinlock_t lock;
@@ -267,7 +276,6 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev)
                BT_ERR("%s urb %p submission failed (%d)",
                                                hdev->name, urb, -err);
                usb_unanchor_urb(urb);
-               kfree(buf);
        }
 
        usb_free_urb(urb);
@@ -350,7 +358,6 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev)
                BT_ERR("%s urb %p submission failed (%d)",
                                                hdev->name, urb, -err);
                usb_unanchor_urb(urb);
-               kfree(buf);
        }
 
        usb_free_urb(urb);
@@ -471,7 +478,6 @@ static int btusb_submit_isoc_urb(struct hci_dev *hdev)
                BT_ERR("%s urb %p submission failed (%d)",
                                                hdev->name, urb, -err);
                usb_unanchor_urb(urb);
-               kfree(buf);
        }
 
        usb_free_urb(urb);
@@ -516,7 +522,7 @@ static int btusb_open(struct hci_dev *hdev)
 
        err = btusb_submit_intr_urb(hdev);
        if (err < 0) {
-               clear_bit(BTUSB_INTR_RUNNING, &hdev->flags);
+               clear_bit(BTUSB_INTR_RUNNING, &data->flags);
                clear_bit(HCI_RUNNING, &hdev->flags);
        }
 
@@ -532,8 +538,10 @@ static int btusb_close(struct hci_dev *hdev)
        if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
                return 0;
 
+       cancel_work_sync(&data->work);
+
        clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
-       usb_kill_anchored_urbs(&data->intr_anchor);
+       usb_kill_anchored_urbs(&data->isoc_anchor);
 
        clear_bit(BTUSB_BULK_RUNNING, &data->flags);
        usb_kill_anchored_urbs(&data->bulk_anchor);
@@ -821,6 +829,7 @@ static int btusb_probe(struct usb_interface *intf,
        }
 
        data->udev = interface_to_usbdev(intf);
+       data->intf = intf;
 
        spin_lock_init(&data->lock);
 
@@ -889,7 +898,7 @@ static int btusb_probe(struct usb_interface *intf,
 
        if (data->isoc) {
                err = usb_driver_claim_interface(&btusb_driver,
-                                                       data->isoc, NULL);
+                                                       data->isoc, data);
                if (err < 0) {
                        hci_free_dev(hdev);
                        kfree(data);
@@ -921,13 +930,22 @@ static void btusb_disconnect(struct usb_interface *intf)
 
        hdev = data->hdev;
 
-       if (data->isoc)
-               usb_driver_release_interface(&btusb_driver, data->isoc);
+       __hci_dev_hold(hdev);
 
-       usb_set_intfdata(intf, NULL);
+       usb_set_intfdata(data->intf, NULL);
+
+       if (data->isoc)
+               usb_set_intfdata(data->isoc, NULL);
 
        hci_unregister_dev(hdev);
 
+       if (intf == data->isoc)
+               usb_driver_release_interface(&btusb_driver, data->intf);
+       else if (data->isoc)
+               usb_driver_release_interface(&btusb_driver, data->isoc);
+
+       __hci_dev_put(hdev);
+
        hci_free_dev(hdev);
 }
 
index daeb8f7..e4dce87 100644 (file)
@@ -695,13 +695,23 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line)
 {
        struct tty_driver *p, *res = NULL;
        int tty_line = 0;
+       int len;
        char *str;
 
+       for (str = name; *str; str++)
+               if ((*str >= '0' && *str <= '9') || *str == ',')
+                       break;
+       if (!*str)
+               return NULL;
+
+       len = str - name;
+       tty_line = simple_strtoul(str, &str, 10);
+
        mutex_lock(&tty_mutex);
        /* Search through the tty devices to look for a match */
        list_for_each_entry(p, &tty_drivers, tty_drivers) {
-               str = name + strlen(p->name);
-               tty_line = simple_strtoul(str, &str, 10);
+               if (strncmp(name, p->name, len) != 0)
+                       continue;
                if (*str == ',')
                        str++;
                if (*str == '\0')
index 4eee533..71d2ac4 100644 (file)
@@ -178,11 +178,13 @@ static int verify_pmtmr_rate(void)
 
 /* Number of monotonicity checks to perform during initialization */
 #define ACPI_PM_MONOTONICITY_CHECKS 10
+/* Number of reads we try to get two different values */
+#define ACPI_PM_READ_CHECKS 10000
 
 static int __init init_acpi_pm_clocksource(void)
 {
        cycle_t value1, value2;
-       unsigned int i, j, good = 0;
+       unsigned int i, j = 0;
 
        if (!pmtmr_ioport)
                return -ENODEV;
@@ -192,29 +194,26 @@ static int __init init_acpi_pm_clocksource(void)
 
        /* "verify" this timing source: */
        for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) {
+               udelay(100 * j);
                value1 = clocksource_acpi_pm.read();
-               for (i = 0; i < 10000; i++) {
+               for (i = 0; i < ACPI_PM_READ_CHECKS; i++) {
                        value2 = clocksource_acpi_pm.read();
                        if (value2 == value1)
                                continue;
                        if (value2 > value1)
-                               good++;
                                break;
                        if ((value2 < value1) && ((value2) < 0xFFF))
-                               good++;
                                break;
                        printk(KERN_INFO "PM-Timer had inconsistent results:"
                               " 0x%#llx, 0x%#llx - aborting.\n",
                               value1, value2);
                        return -EINVAL;
                }
-               udelay(300 * i);
-       }
-
-       if (good != ACPI_PM_MONOTONICITY_CHECKS) {
-               printk(KERN_INFO "PM-Timer failed consistency check "
-                      " (0x%#llx) - aborting.\n", value1);
-               return -ENODEV;
+               if (i == ACPI_PM_READ_CHECKS) {
+                       printk(KERN_INFO "PM-Timer failed consistency check "
+                              " (0x%#llx) - aborting.\n", value1);
+                       return -ENODEV;
+               }
        }
 
        if (verify_pmtmr_rate() != 0)
index 94df917..0778d99 100644 (file)
@@ -364,7 +364,7 @@ static void dw_dma_tasklet(unsigned long data)
        int i;
 
        status_block = dma_readl(dw, RAW.BLOCK);
-       status_xfer = dma_readl(dw, RAW.BLOCK);
+       status_xfer = dma_readl(dw, RAW.XFER);
        status_err = dma_readl(dw, RAW.ERROR);
 
        dev_vdbg(dw->dma.dev, "tasklet: status_block=%x status_err=%x\n",
index d568c65..d9e7a49 100644 (file)
@@ -279,7 +279,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "OTES1 Fan",          36, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x0011, NULL /* Abit AT8 32X, need DMI string */, {
+       { 0x0011, "AT8 32X(ATI RD580-ULI M1575)", {
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR",                 1, 0, 20, 1, 0 },
                { "DDR VTT",             2, 0, 10, 1, 0 },
@@ -303,6 +303,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "SYS Fan",            34, 2, 60, 1, 0 },
                { "AUX1 Fan",           35, 2, 60, 1, 0 },
                { "AUX2 Fan",           36, 2, 60, 1, 0 },
+               { "AUX3 Fan",           37, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
        { 0x0012, NULL /* Abit AN8 32X, need DMI string */, {
index ce8d94f..bfda8c8 100644 (file)
@@ -69,7 +69,7 @@ static inline int ad7414_write(struct i2c_client *client, u8 reg, u8 value)
        return i2c_smbus_write_byte_data(client, reg, value);
 }
 
-struct ad7414_data *ad7414_update_device(struct device *dev)
+static struct ad7414_data *ad7414_update_device(struct device *dev)
 {
        struct i2c_client *client = to_i2c_client(dev);
        struct ad7414_data *data = i2c_get_clientdata(client);
index d191118..d6b490d 100644 (file)
@@ -31,7 +31,7 @@
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("System voltages control via Attansic ATXP1");
-MODULE_VERSION("0.6.2");
+MODULE_VERSION("0.6.3");
 MODULE_AUTHOR("Sebastian Witt <se.witt@gmx.net>");
 
 #define ATXP1_VID      0x00
@@ -289,16 +289,16 @@ static int atxp1_detect(struct i2c_client *new_client, int kind,
        if (!((i2c_smbus_read_byte_data(new_client, 0x3e) == 0) &&
             (i2c_smbus_read_byte_data(new_client, 0x3f) == 0) &&
             (i2c_smbus_read_byte_data(new_client, 0xfe) == 0) &&
-            (i2c_smbus_read_byte_data(new_client, 0xff) == 0) )) {
+            (i2c_smbus_read_byte_data(new_client, 0xff) == 0)))
+               return -ENODEV;
 
-               /* No vendor ID, now checking if registers 0x10,0x11 (non-existent)
-                * showing the same as register 0x00 */
-               temp = i2c_smbus_read_byte_data(new_client, 0x00);
+       /* No vendor ID, now checking if registers 0x10,0x11 (non-existent)
+        * showing the same as register 0x00 */
+       temp = i2c_smbus_read_byte_data(new_client, 0x00);
 
-               if (!((i2c_smbus_read_byte_data(new_client, 0x10) == temp) &&
-                        (i2c_smbus_read_byte_data(new_client, 0x11) == temp) ))
-                       return -ENODEV;
-       }
+       if (!((i2c_smbus_read_byte_data(new_client, 0x10) == temp) &&
+             (i2c_smbus_read_byte_data(new_client, 0x11) == temp)))
+               return -ENODEV;
 
        /* Get VRM */
        temp = vid_which_vrm();
index 30cdb09..d793cc0 100644 (file)
@@ -46,6 +46,8 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
+#include <linux/string.h>
+#include <linux/dmi.h>
 #include <asm/io.h>
 
 #define DRVNAME "it87"
@@ -236,6 +238,8 @@ struct it87_sio_data {
        /* Values read from Super-I/O config space */
        u8 revision;
        u8 vid_value;
+       /* Values set based on DMI strings */
+       u8 skip_pwm;
 };
 
 /* For each registered chip, we need to keep some data in memory.
@@ -273,10 +277,10 @@ struct it87_data {
 static inline int has_16bit_fans(const struct it87_data *data)
 {
        /* IT8705F Datasheet 0.4.1, 3h == Version G.
-          IT8712F Datasheet 0.9.1, section 8.3.5 indicates 7h == Version I.
+          IT8712F Datasheet 0.9.1, section 8.3.5 indicates 8h == Version J.
           These are the first revisions with 16bit tachometer support. */
        return (data->type == it87 && data->revision >= 0x03)
-           || (data->type == it8712 && data->revision >= 0x07)
+           || (data->type == it8712 && data->revision >= 0x08)
            || data->type == it8716
            || data->type == it8718;
 }
@@ -964,6 +968,7 @@ static int __init it87_find(unsigned short *address,
 {
        int err = -ENODEV;
        u16 chip_type;
+       const char *board_vendor, *board_name;
 
        superio_enter();
        chip_type = force_id ? force_id : superio_inw(DEVID);
@@ -1022,6 +1027,24 @@ static int __init it87_find(unsigned short *address,
                        pr_info("it87: in7 is VCCH (+5V Stand-By)\n");
        }
 
+       /* Disable specific features based on DMI strings */
+       board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
+       board_name = dmi_get_system_info(DMI_BOARD_NAME);
+       if (board_vendor && board_name) {
+               if (strcmp(board_vendor, "nVIDIA") == 0
+                && strcmp(board_name, "FN68PT") == 0) {
+                       /* On the Shuttle SN68PT, FAN_CTL2 is apparently not
+                          connected to a fan, but to something else. One user
+                          has reported instant system power-off when changing
+                          the PWM2 duty cycle, so we disable it.
+                          I use the board name string as the trigger in case
+                          the same board is ever used in other systems. */
+                       pr_info("it87: Disabling pwm2 due to "
+                               "hardware constraints\n");
+                       sio_data->skip_pwm = (1 << 1);
+               }
+       }
+
 exit:
        superio_exit();
        return err;
@@ -1168,25 +1191,33 @@ static int __devinit it87_probe(struct platform_device *pdev)
        }
 
        if (enable_pwm_interface) {
-               if ((err = device_create_file(dev,
-                    &sensor_dev_attr_pwm1_enable.dev_attr))
-                || (err = device_create_file(dev,
-                    &sensor_dev_attr_pwm2_enable.dev_attr))
-                || (err = device_create_file(dev,
-                    &sensor_dev_attr_pwm3_enable.dev_attr))
-                || (err = device_create_file(dev,
-                    &sensor_dev_attr_pwm1.dev_attr))
-                || (err = device_create_file(dev,
-                    &sensor_dev_attr_pwm2.dev_attr))
-                || (err = device_create_file(dev,
-                    &sensor_dev_attr_pwm3.dev_attr))
-                || (err = device_create_file(dev,
-                    &dev_attr_pwm1_freq))
-                || (err = device_create_file(dev,
-                    &dev_attr_pwm2_freq))
-                || (err = device_create_file(dev,
-                    &dev_attr_pwm3_freq)))
-                       goto ERROR4;
+               if (!(sio_data->skip_pwm & (1 << 0))) {
+                       if ((err = device_create_file(dev,
+                            &sensor_dev_attr_pwm1_enable.dev_attr))
+                        || (err = device_create_file(dev,
+                            &sensor_dev_attr_pwm1.dev_attr))
+                        || (err = device_create_file(dev,
+                            &dev_attr_pwm1_freq)))
+                               goto ERROR4;
+               }
+               if (!(sio_data->skip_pwm & (1 << 1))) {
+                       if ((err = device_create_file(dev,
+                            &sensor_dev_attr_pwm2_enable.dev_attr))
+                        || (err = device_create_file(dev,
+                            &sensor_dev_attr_pwm2.dev_attr))
+                        || (err = device_create_file(dev,
+                            &dev_attr_pwm2_freq)))
+                               goto ERROR4;
+               }
+               if (!(sio_data->skip_pwm & (1 << 2))) {
+                       if ((err = device_create_file(dev,
+                            &sensor_dev_attr_pwm3_enable.dev_attr))
+                        || (err = device_create_file(dev,
+                            &sensor_dev_attr_pwm3.dev_attr))
+                        || (err = device_create_file(dev,
+                            &dev_attr_pwm3_freq)))
+                               goto ERROR4;
+               }
        }
 
        if (data->type == it8712 || data->type == it8716
@@ -1546,6 +1577,7 @@ static int __init sm_it87_init(void)
        unsigned short isa_address=0;
        struct it87_sio_data sio_data;
 
+       memset(&sio_data, 0, sizeof(struct it87_sio_data));
        err = it87_find(&isa_address, &sio_data);
        if (err)
                return err;
index 22f6d5c..0e7b1c6 100644 (file)
@@ -180,7 +180,7 @@ static const struct i2c_algorithm i2c_powermac_algorithm = {
 };
 
 
-static int i2c_powermac_remove(struct platform_device *dev)
+static int __devexit i2c_powermac_remove(struct platform_device *dev)
 {
        struct i2c_adapter      *adapter = platform_get_drvdata(dev);
        struct pmac_i2c_bus     *bus = i2c_get_adapdata(adapter);
@@ -200,7 +200,7 @@ static int i2c_powermac_remove(struct platform_device *dev)
 }
 
 
-static int __devexit i2c_powermac_probe(struct platform_device *dev)
+static int __devinit i2c_powermac_probe(struct platform_device *dev)
 {
        struct pmac_i2c_bus *bus = dev->dev.platform_data;
        struct device_node *parent = NULL;
index af4491f..307d976 100644 (file)
@@ -583,8 +583,10 @@ static int __init i2c_dev_init(void)
                goto out;
 
        i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");
-       if (IS_ERR(i2c_dev_class))
+       if (IS_ERR(i2c_dev_class)) {
+               res = PTR_ERR(i2c_dev_class);
                goto out_unreg_chrdev;
+       }
 
        res = i2c_add_driver(&i2cdev_driver);
        if (res)
index fc735ab..052879a 100644 (file)
@@ -292,6 +292,20 @@ config IDE_GENERIC
        tristate "generic/default IDE chipset support"
        depends on ALPHA || X86 || IA64 || M32R || MIPS
        help
+         This is the generic IDE driver.  This driver attaches to the
+         fixed legacy ports (e.g. on PCs 0x1f0/0x170, 0x1e8/0x168 and
+         so on).  Please note that if this driver is built into the
+         kernel or loaded before other ATA (IDE or libata) drivers
+         and the controller is located at legacy ports, this driver
+         may grab those ports and thus can prevent the controller
+         specific driver from attaching.
+
+         Also, currently, IDE generic doesn't allow IRQ sharing
+         meaning that the IRQs it grabs won't be available to other
+         controllers sharing those IRQs which usually makes drivers
+         for those controllers fail.  Generally, it's not a good idea
+         to load IDE generic driver on modern systems.
+
          If unsure, say N.
 
 config BLK_DEV_PLATFORM
@@ -766,10 +780,6 @@ config BLK_DEV_IDEDMA_PMAC
          to transfer data to and from memory.  Saying Y is safe and improves
          performance.
 
-config BLK_DEV_IDE_SWARM
-       tristate "IDE for Sibyte evaluation boards"
-       depends on SIBYTE_SB1xxx_SOC
-
 config BLK_DEV_IDE_AU1XXX
        bool "IDE for AMD Alchemy Au1200"
        depends on SOC_AU1200
index 49a8c58..f16bb46 100644 (file)
@@ -1661,7 +1661,9 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
                cdi->mask &= ~CDC_PLAY_AUDIO;
 
        mechtype = buf[8 + 6] >> 5;
-       if (mechtype == mechtype_caddy || mechtype == mechtype_popup)
+       if (mechtype == mechtype_caddy ||
+           mechtype == mechtype_popup ||
+           (drive->atapi_flags & IDE_AFLAG_NO_AUTOCLOSE))
                cdi->mask |= CDC_CLOSE_TRAY;
 
        if (cdi->sanyo_slot > 0) {
@@ -1859,6 +1861,8 @@ static const struct cd_list_entry ide_cd_quirks_list[] = {
        { "MATSHITADVD-ROM SR-8176", NULL,   IDE_AFLAG_PLAY_AUDIO_OK         },
        { "MATSHITADVD-ROM SR-8174", NULL,   IDE_AFLAG_PLAY_AUDIO_OK         },
        { "Optiarc DVD RW AD-5200A", NULL,   IDE_AFLAG_PLAY_AUDIO_OK         },
+       { "Optiarc DVD RW AD-7200A", NULL,   IDE_AFLAG_PLAY_AUDIO_OK         },
+       { "Optiarc DVD RW AD-7543A", NULL,   IDE_AFLAG_NO_AUTOCLOSE          },
        { NULL, NULL, 0 }
 };
 
index adc6827..3fa07c0 100644 (file)
@@ -211,7 +211,7 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
                                xcount = bcount & 0xffff;
                                if (is_trm290)
                                        xcount = ((xcount >> 2) - 1) << 16;
-                               if (xcount == 0x0000) {
+                               else if (xcount == 0x0000) {
        /* 
         * Most chipsets correctly interpret a length of 0x0000 as 64KB,
         * but at least one (e.g. CS5530) misinterprets it as zero (!).
index 994e410..a51a30e 100644 (file)
@@ -1492,7 +1492,7 @@ static struct device_attribute *ide_port_attrs[] = {
 
 static int ide_sysfs_register_port(ide_hwif_t *hwif)
 {
-       int i, rc;
+       int i, uninitialized_var(rc);
 
        for (i = 0; ide_port_attrs[i]; i++) {
                rc = device_create_file(hwif->portdev, ide_port_attrs[i]);
index 1bce84b..3833189 100644 (file)
@@ -2338,7 +2338,7 @@ static void idetape_get_inquiry_results(ide_drive_t *drive)
 {
        idetape_tape_t *tape = drive->driver_data;
        struct ide_atapi_pc pc;
-       char fw_rev[6], vendor_id[10], product_id[18];
+       char fw_rev[4], vendor_id[8], product_id[16];
 
        idetape_create_inquiry_cmd(&pc);
        if (idetape_queue_pc_tail(drive, &pc)) {
@@ -2350,11 +2350,11 @@ static void idetape_get_inquiry_results(ide_drive_t *drive)
        memcpy(product_id, &pc.buf[16], 16);
        memcpy(fw_rev, &pc.buf[32], 4);
 
-       ide_fixstring(vendor_id, 10, 0);
-       ide_fixstring(product_id, 18, 0);
-       ide_fixstring(fw_rev, 6, 0);
+       ide_fixstring(vendor_id, 8, 0);
+       ide_fixstring(product_id, 16, 0);
+       ide_fixstring(fw_rev, 4, 0);
 
-       printk(KERN_INFO "ide-tape: %s <-> %s: %s %s rev %s\n",
+       printk(KERN_INFO "ide-tape: %s <-> %s: %.8s %.16s rev %.4s\n",
                        drive->name, tape->name, vendor_id, product_id, fw_rev);
 }
 
index 677c7b2..5873fa0 100644 (file)
@@ -1,4 +1,3 @@
-obj-$(CONFIG_BLK_DEV_IDE_SWARM)                += swarm.o
 obj-$(CONFIG_BLK_DEV_IDE_AU1XXX)       += au1xxx-ide.o
 
 EXTRA_CFLAGS    := -Idrivers/ide
diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c
deleted file mode 100644 (file)
index badf79f..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2001, 2002, 2003 Broadcom Corporation
- * Copyright (C) 2004 MontaVista Software Inc.
- *     Author: Manish Lachwani, mlachwani@mvista.com
- * Copyright (C) 2004  MIPS Technologies, Inc.  All rights reserved.
- *     Author: Maciej W. Rozycki <macro@mips.com>
- * Copyright (c) 2006, 2008  Maciej W. Rozycki
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-/*
- *  Derived loosely from ide-pmac.c, so:
- *  Copyright (C) 1998 Paul Mackerras.
- *  Copyright (C) 1995-1998 Mark Lord
- */
-
-/*
- * Boards with SiByte processors so far have supported IDE devices via
- * the Generic Bus, PCI bus, and built-in PCMCIA interface.  In all
- * cases, byte-swapping must be avoided for these devices (whereas
- * other PCI devices, for example, will require swapping).  Any
- * SiByte-targetted kernel including IDE support will include this
- * file.  Probing of a Generic Bus for an IDE device is controlled by
- * the definition of "SIBYTE_HAVE_IDE", which is provided by
- * <asm/sibyte/board.h> for Broadcom boards.
- */
-
-#include <linux/ide.h>
-#include <linux/ioport.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/platform_device.h>
-
-#include <asm/io.h>
-
-#include <asm/sibyte/board.h>
-#include <asm/sibyte/sb1250_genbus.h>
-#include <asm/sibyte/sb1250_regs.h>
-
-#define DRV_NAME "ide-swarm"
-
-static char swarm_ide_string[] = DRV_NAME;
-
-static struct resource swarm_ide_resource = {
-       .name   = "SWARM GenBus IDE",
-       .flags  = IORESOURCE_MEM,
-};
-
-static struct platform_device *swarm_ide_dev;
-
-static const struct ide_port_info swarm_port_info = {
-       .name                   = DRV_NAME,
-       .host_flags             = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
-};
-
-/*
- * swarm_ide_probe - if the board header indicates the existence of
- * Generic Bus IDE, allocate a HWIF for it.
- */
-static int __devinit swarm_ide_probe(struct device *dev)
-{
-       u8 __iomem *base;
-       struct ide_host *host;
-       phys_t offset, size;
-       int i, rc;
-       hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
-
-       if (!SIBYTE_HAVE_IDE)
-               return -ENODEV;
-
-       base = ioremap(A_IO_EXT_BASE, 0x800);
-       offset = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS));
-       size = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_MULT_SIZE, IDE_CS));
-       iounmap(base);
-
-       offset = G_IO_START_ADDR(offset) << S_IO_ADDRBASE;
-       size = (G_IO_MULT_SIZE(size) + 1) << S_IO_REGSIZE;
-       if (offset < A_PHYS_GENBUS || offset >= A_PHYS_GENBUS_END) {
-               printk(KERN_INFO DRV_NAME
-                      ": IDE interface at GenBus disabled\n");
-               return -EBUSY;
-       }
-
-       printk(KERN_INFO DRV_NAME ": IDE interface at GenBus slot %i\n",
-              IDE_CS);
-
-       swarm_ide_resource.start = offset;
-       swarm_ide_resource.end = offset + size - 1;
-       if (request_resource(&iomem_resource, &swarm_ide_resource)) {
-               printk(KERN_ERR DRV_NAME
-                      ": can't request I/O memory resource\n");
-               return -EBUSY;
-       }
-
-       base = ioremap(offset, size);
-
-       for (i = 0; i <= 7; i++)
-               hw.io_ports_array[i] =
-                               (unsigned long)(base + ((0x1f0 + i) << 5));
-       hw.io_ports.ctl_addr =
-                               (unsigned long)(base + (0x3f6 << 5));
-       hw.irq = K_INT_GB_IDE;
-       hw.chipset = ide_generic;
-
-       rc = ide_host_add(&swarm_port_info, hws, &host);
-       if (rc)
-               goto err;
-
-       dev_set_drvdata(dev, host);
-
-       return 0;
-err:
-       release_resource(&swarm_ide_resource);
-       iounmap(base);
-       return rc;
-}
-
-static struct device_driver swarm_ide_driver = {
-       .name   = swarm_ide_string,
-       .bus    = &platform_bus_type,
-       .probe  = swarm_ide_probe,
-};
-
-static void swarm_ide_platform_release(struct device *device)
-{
-       struct platform_device *pldev;
-
-       /* free device */
-       pldev = to_platform_device(device);
-       kfree(pldev);
-}
-
-static int __devinit swarm_ide_init_module(void)
-{
-       struct platform_device *pldev;
-       int err;
-
-       printk(KERN_INFO "SWARM IDE driver\n");
-
-       if (driver_register(&swarm_ide_driver)) {
-               printk(KERN_ERR "Driver registration failed\n");
-               err = -ENODEV;
-               goto out;
-       }
-
-        if (!(pldev = kzalloc(sizeof (*pldev), GFP_KERNEL))) {
-               err = -ENOMEM;
-               goto out_unregister_driver;
-       }
-
-       pldev->name             = swarm_ide_string;
-       pldev->id               = 0;
-       pldev->dev.release      = swarm_ide_platform_release;
-
-       if (platform_device_register(pldev)) {
-               err = -ENODEV;
-               goto out_free_pldev;
-       }
-
-        if (!pldev->dev.driver) {
-               /*
-                * The driver was not bound to this device, there was
-                 * no hardware at this address. Unregister it, as the
-                * release fuction will take care of freeing the
-                * allocated structure
-                */
-               platform_device_unregister (pldev);
-       }
-
-       swarm_ide_dev = pldev;
-
-       return 0;
-
-out_free_pldev:
-       kfree(pldev);
-
-out_unregister_driver:
-       driver_unregister(&swarm_ide_driver);
-out:
-       return err;
-}
-
-module_init(swarm_ide_init_module);
index f29dbb7..9559248 100644 (file)
@@ -1342,6 +1342,12 @@ static __be32 convert_access(int acc)
 static void set_fmr_seg(struct mlx4_wqe_fmr_seg *fseg, struct ib_send_wr *wr)
 {
        struct mlx4_ib_fast_reg_page_list *mfrpl = to_mfrpl(wr->wr.fast_reg.page_list);
+       int i;
+
+       for (i = 0; i < wr->wr.fast_reg.page_list_len; ++i)
+               wr->wr.fast_reg.page_list->page_list[i] =
+                       cpu_to_be64(wr->wr.fast_reg.page_list->page_list[i] |
+                                   MLX4_MTT_FLAG_PRESENT);
 
        fseg->flags             = convert_access(wr->wr.fast_reg.access_flags);
        fseg->mem_key           = cpu_to_be32(wr->wr.fast_reg.rkey);
index 9f0b964..499d3cf 100644 (file)
@@ -1956,13 +1956,6 @@ static int mini_cm_reject(struct nes_cm_core *cm_core,
                return ret;
        cleanup_retrans_entry(cm_node);
        cm_node->state = NES_CM_STATE_CLOSED;
-       ret = send_fin(cm_node, NULL);
-
-       if (cm_node->accept_pend) {
-               BUG_ON(!cm_node->listener);
-               atomic_dec(&cm_node->listener->pend_accepts_cnt);
-               BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0);
-       }
 
        ret = send_reset(cm_node, NULL);
        return ret;
@@ -2383,6 +2376,7 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp)
                        atomic_inc(&cm_disconnects);
                        cm_event.event = IW_CM_EVENT_DISCONNECT;
                        if (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET) {
+                               issued_disconnect_reset = 1;
                                cm_event.status = IW_CM_EVENT_STATUS_RESET;
                                nes_debug(NES_DBG_CM, "Generating a CM "
                                        "Disconnect Event (status reset) for "
@@ -2508,7 +2502,6 @@ static int nes_disconnect(struct nes_qp *nesqp, int abrupt)
                nes_debug(NES_DBG_CM, "Call close API\n");
 
                g_cm_core->api->close(g_cm_core, nesqp->cm_node);
-               nesqp->cm_node = NULL;
        }
 
        return ret;
@@ -2837,6 +2830,7 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
        cm_node->apbvt_set = 1;
        nesqp->cm_node = cm_node;
        cm_node->nesqp = nesqp;
+       nes_add_ref(&nesqp->ibqp);
 
        return 0;
 }
@@ -3167,7 +3161,6 @@ static void cm_event_connect_error(struct nes_cm_event *event)
        if (ret)
                printk(KERN_ERR "%s[%u] OFA CM event_handler returned, "
                        "ret=%d\n", __func__, __LINE__, ret);
-       nes_rem_ref(&nesqp->ibqp);
        cm_id->rem_ref(cm_id);
 
        rem_ref_cm_node(event->cm_node->cm_core, event->cm_node);
index b0ffc9a..05eb41b 100644 (file)
@@ -293,6 +293,7 @@ struct ipoib_dev_priv {
 
        struct delayed_work pkey_poll_task;
        struct delayed_work mcast_task;
+       struct work_struct carrier_on_task;
        struct work_struct flush_light;
        struct work_struct flush_normal;
        struct work_struct flush_heavy;
@@ -464,6 +465,7 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port);
 void ipoib_dev_cleanup(struct net_device *dev);
 
 void ipoib_mcast_join_task(struct work_struct *work);
+void ipoib_mcast_carrier_on_task(struct work_struct *work);
 void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb);
 
 void ipoib_mcast_restart_task(struct work_struct *work);
index 7e9e218..e9ca3cb 100644 (file)
@@ -404,7 +404,7 @@ static void path_rec_completion(int status,
        struct net_device *dev = path->dev;
        struct ipoib_dev_priv *priv = netdev_priv(dev);
        struct ipoib_ah *ah = NULL;
-       struct ipoib_ah *old_ah;
+       struct ipoib_ah *old_ah = NULL;
        struct ipoib_neigh *neigh, *tn;
        struct sk_buff_head skqueue;
        struct sk_buff *skb;
@@ -428,12 +428,12 @@ static void path_rec_completion(int status,
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       old_ah   = path->ah;
-       path->ah = ah;
-
        if (ah) {
                path->pathrec = *pathrec;
 
+               old_ah   = path->ah;
+               path->ah = ah;
+
                ipoib_dbg(priv, "created address handle %p for LID 0x%04x, SL %d\n",
                          ah, be16_to_cpu(pathrec->dlid), pathrec->sl);
 
@@ -1075,6 +1075,7 @@ static void ipoib_setup(struct net_device *dev)
 
        INIT_DELAYED_WORK(&priv->pkey_poll_task, ipoib_pkey_poll);
        INIT_DELAYED_WORK(&priv->mcast_task,   ipoib_mcast_join_task);
+       INIT_WORK(&priv->carrier_on_task, ipoib_mcast_carrier_on_task);
        INIT_WORK(&priv->flush_light,   ipoib_ib_dev_flush_light);
        INIT_WORK(&priv->flush_normal,   ipoib_ib_dev_flush_normal);
        INIT_WORK(&priv->flush_heavy,   ipoib_ib_dev_flush_heavy);
index ac33c8f..aae2862 100644 (file)
@@ -366,6 +366,21 @@ static int ipoib_mcast_sendonly_join(struct ipoib_mcast *mcast)
        return ret;
 }
 
+void ipoib_mcast_carrier_on_task(struct work_struct *work)
+{
+       struct ipoib_dev_priv *priv = container_of(work, struct ipoib_dev_priv,
+                                                  carrier_on_task);
+
+       /*
+        * Take rtnl_lock to avoid racing with ipoib_stop() and
+        * turning the carrier back on while a device is being
+        * removed.
+        */
+       rtnl_lock();
+       netif_carrier_on(priv->dev);
+       rtnl_unlock();
+}
+
 static int ipoib_mcast_join_complete(int status,
                                     struct ib_sa_multicast *multicast)
 {
@@ -392,16 +407,12 @@ static int ipoib_mcast_join_complete(int status,
                                           &priv->mcast_task, 0);
                mutex_unlock(&mcast_mutex);
 
-               if (mcast == priv->broadcast) {
-                       /*
-                        * Take RTNL lock here to avoid racing with
-                        * ipoib_stop() and turning the carrier back
-                        * on while a device is being removed.
-                        */
-                       rtnl_lock();
-                       netif_carrier_on(dev);
-                       rtnl_unlock();
-               }
+               /*
+                * Defer carrier on work to ipoib_workqueue to avoid a
+                * deadlock on rtnl_lock here.
+                */
+               if (mcast == priv->broadcast)
+                       queue_work(ipoib_workqueue, &priv->carrier_on_task);
 
                return 0;
        }
index 18f4d7f..2998a6a 100644 (file)
@@ -351,8 +351,9 @@ static int report_tp_state(struct bcm5974 *dev, int size)
 #define BCM5974_WELLSPRING_MODE_REQUEST_VALUE          0x300
 #define BCM5974_WELLSPRING_MODE_REQUEST_INDEX          0
 #define BCM5974_WELLSPRING_MODE_VENDOR_VALUE           0x01
+#define BCM5974_WELLSPRING_MODE_NORMAL_VALUE           0x08
 
-static int bcm5974_wellspring_mode(struct bcm5974 *dev)
+static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on)
 {
        char *data = kmalloc(8, GFP_KERNEL);
        int retval = 0, size;
@@ -377,7 +378,9 @@ static int bcm5974_wellspring_mode(struct bcm5974 *dev)
        }
 
        /* apply the mode switch */
-       data[0] = BCM5974_WELLSPRING_MODE_VENDOR_VALUE;
+       data[0] = on ?
+               BCM5974_WELLSPRING_MODE_VENDOR_VALUE :
+               BCM5974_WELLSPRING_MODE_NORMAL_VALUE;
 
        /* write configuration */
        size = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
@@ -392,7 +395,8 @@ static int bcm5974_wellspring_mode(struct bcm5974 *dev)
                goto out;
        }
 
-       dprintk(2, "bcm5974: switched to wellspring mode.\n");
+       dprintk(2, "bcm5974: switched to %s mode.\n",
+               on ? "wellspring" : "normal");
 
  out:
        kfree(data);
@@ -481,7 +485,7 @@ exit:
  */
 static int bcm5974_start_traffic(struct bcm5974 *dev)
 {
-       if (bcm5974_wellspring_mode(dev)) {
+       if (bcm5974_wellspring_mode(dev, true)) {
                dprintk(1, "bcm5974: mode switch failed\n");
                goto error;
        }
@@ -504,6 +508,7 @@ static void bcm5974_pause_traffic(struct bcm5974 *dev)
 {
        usb_kill_urb(dev->tp_urb);
        usb_kill_urb(dev->bt_urb);
+       bcm5974_wellspring_mode(dev, false);
 }
 
 /*
index bf44f9d..c8b7e8a 100644 (file)
@@ -119,8 +119,8 @@ static int __devinit jornada720_ts_probe(struct platform_device *pdev)
        input_dev->id.bustype = BUS_HOST;
        input_dev->dev.parent = &pdev->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-       input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
        input_set_abs_params(input_dev, ABS_X, 270, 3900, 0, 0);
        input_set_abs_params(input_dev, ABS_Y, 180, 3700, 0, 0);
 
index be0e121..3493515 100644 (file)
@@ -161,6 +161,16 @@ static int fsg_led_probe(struct platform_device *pdev)
 {
        int ret;
 
+       /* Map the LED chip select address space */
+       latch_address = (unsigned short *) ioremap(IXP4XX_EXP_BUS_BASE(2), 512);
+       if (!latch_address) {
+               ret = -ENOMEM;
+               goto failremap;
+       }
+
+       latch_value = 0xffff;
+       *latch_address = latch_value;
+
        ret = led_classdev_register(&pdev->dev, &fsg_wlan_led);
        if (ret < 0)
                goto failwlan;
@@ -185,20 +195,8 @@ static int fsg_led_probe(struct platform_device *pdev)
        if (ret < 0)
                goto failring;
 
-       /* Map the LED chip select address space */
-       latch_address = (unsigned short *) ioremap(IXP4XX_EXP_BUS_BASE(2), 512);
-       if (!latch_address) {
-               ret = -ENOMEM;
-               goto failremap;
-       }
-
-       latch_value = 0xffff;
-       *latch_address = latch_value;
-
        return ret;
 
- failremap:
-       led_classdev_unregister(&fsg_ring_led);
  failring:
        led_classdev_unregister(&fsg_sync_led);
  failsync:
@@ -210,14 +208,14 @@ static int fsg_led_probe(struct platform_device *pdev)
  failwan:
        led_classdev_unregister(&fsg_wlan_led);
  failwlan:
+       iounmap(latch_address);
+ failremap:
 
        return ret;
 }
 
 static int fsg_led_remove(struct platform_device *pdev)
 {
-       iounmap(latch_address);
-
        led_classdev_unregister(&fsg_wlan_led);
        led_classdev_unregister(&fsg_wan_led);
        led_classdev_unregister(&fsg_sata_led);
@@ -225,6 +223,8 @@ static int fsg_led_remove(struct platform_device *pdev)
        led_classdev_unregister(&fsg_sync_led);
        led_classdev_unregister(&fsg_ring_led);
 
+       iounmap(latch_address);
+
        return 0;
 }
 
index 146c069..f508729 100644 (file)
@@ -248,11 +248,10 @@ static int __devinit pca955x_probe(struct i2c_client *client,
                                        const struct i2c_device_id *id)
 {
        struct pca955x_led *pca955x;
-       int i;
-       int err = -ENODEV;
        struct pca955x_chipdef *chip;
        struct i2c_adapter *adapter;
        struct led_platform_data *pdata;
+       int i, err;
 
        chip = &pca955x_chipdefs[id->driver_data];
        adapter = to_i2c_adapter(client->dev.parent);
@@ -282,43 +281,41 @@ static int __devinit pca955x_probe(struct i2c_client *client,
                }
        }
 
+       pca955x = kzalloc(sizeof(*pca955x) * chip->bits, GFP_KERNEL);
+       if (!pca955x)
+               return -ENOMEM;
+
+       i2c_set_clientdata(client, pca955x);
+
        for (i = 0; i < chip->bits; i++) {
-               pca955x = kzalloc(sizeof(struct pca955x_led), GFP_KERNEL);
-               if (!pca955x) {
-                       err = -ENOMEM;
-                       goto exit;
-               }
+               pca955x[i].chipdef = chip;
+               pca955x[i].client = client;
+               pca955x[i].led_num = i;
 
-               pca955x->chipdef = chip;
-               pca955x->client = client;
-               pca955x->led_num = i;
                /* Platform data can specify LED names and default triggers */
                if (pdata) {
                        if (pdata->leds[i].name)
-                               snprintf(pca955x->name, 32, "pca955x:%s",
-                                                       pdata->leds[i].name);
+                               snprintf(pca955x[i].name,
+                                        sizeof(pca955x[i].name), "pca955x:%s",
+                                        pdata->leds[i].name);
                        if (pdata->leds[i].default_trigger)
-                               pca955x->led_cdev.default_trigger =
+                               pca955x[i].led_cdev.default_trigger =
                                        pdata->leds[i].default_trigger;
                } else {
-                       snprintf(pca955x->name, 32, "pca955x:%d", i);
+                       snprintf(pca955x[i].name, sizeof(pca955x[i].name),
+                                "pca955x:%d", i);
                }
-               spin_lock_init(&pca955x->lock);
 
-               pca955x->led_cdev.name = pca955x->name;
-               pca955x->led_cdev.brightness_set =
-                               pca955x_led_set;
+               spin_lock_init(&pca955x[i].lock);
 
-               /*
-                * Client data is a pointer to the _first_ pca955x_led
-                * struct
-                */
-               if (i == 0)
-                       i2c_set_clientdata(client, pca955x);
+               pca955x[i].led_cdev.name = pca955x[i].name;
+               pca955x[i].led_cdev.brightness_set = pca955x_led_set;
 
-               INIT_WORK(&(pca955x->work), pca955x_led_work);
+               INIT_WORK(&pca955x[i].work, pca955x_led_work);
 
-               led_classdev_register(&client->dev, &(pca955x->led_cdev));
+               err = led_classdev_register(&client->dev, &pca955x[i].led_cdev);
+               if (err < 0)
+                       goto exit;
        }
 
        /* Turn off LEDs */
@@ -336,23 +333,32 @@ static int __devinit pca955x_probe(struct i2c_client *client,
        pca955x_write_psc(client, 1, 0);
 
        return 0;
+
 exit:
+       while (i--) {
+               led_classdev_unregister(&pca955x[i].led_cdev);
+               cancel_work_sync(&pca955x[i].work);
+       }
+
+       kfree(pca955x);
+       i2c_set_clientdata(client, NULL);
+
        return err;
 }
 
 static int __devexit pca955x_remove(struct i2c_client *client)
 {
        struct pca955x_led *pca955x = i2c_get_clientdata(client);
-       int leds = pca955x->chipdef->bits;
        int i;
 
-       for (i = 0; i < leds; i++) {
-               led_classdev_unregister(&(pca955x->led_cdev));
-               cancel_work_sync(&(pca955x->work));
-               kfree(pca955x);
-               pca955x = pca955x + 1;
+       for (i = 0; i < pca955x->chipdef->bits; i++) {
+               led_classdev_unregister(&pca955x[i].led_cdev);
+               cancel_work_sync(&pca955x[i].work);
        }
 
+       kfree(pca955x);
+       i2c_set_clientdata(client, NULL);
+
        return 0;
 }
 
index 71dd65a..c2fcf28 100644 (file)
@@ -63,6 +63,7 @@ struct multipath {
 
        const char *hw_handler_name;
        struct work_struct activate_path;
+       struct pgpath *pgpath_to_activate;
        unsigned nr_priority_groups;
        struct list_head priority_groups;
        unsigned pg_init_required;      /* pg_init needs calling? */
@@ -146,6 +147,7 @@ static struct priority_group *alloc_priority_group(void)
 
 static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti)
 {
+       unsigned long flags;
        struct pgpath *pgpath, *tmp;
        struct multipath *m = ti->private;
 
@@ -154,6 +156,10 @@ static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti)
                if (m->hw_handler_name)
                        scsi_dh_detach(bdev_get_queue(pgpath->path.dev->bdev));
                dm_put_device(ti, pgpath->path.dev);
+               spin_lock_irqsave(&m->lock, flags);
+               if (m->pgpath_to_activate == pgpath)
+                       m->pgpath_to_activate = NULL;
+               spin_unlock_irqrestore(&m->lock, flags);
                free_pgpath(pgpath);
        }
 }
@@ -421,6 +427,7 @@ static void process_queued_ios(struct work_struct *work)
                __choose_pgpath(m);
 
        pgpath = m->current_pgpath;
+       m->pgpath_to_activate = m->current_pgpath;
 
        if ((pgpath && !m->queue_io) ||
            (!pgpath && !m->queue_if_no_path))
@@ -1093,8 +1100,15 @@ static void activate_path(struct work_struct *work)
        int ret;
        struct multipath *m =
                container_of(work, struct multipath, activate_path);
-       struct dm_path *path = &m->current_pgpath->path;
+       struct dm_path *path;
+       unsigned long flags;
 
+       spin_lock_irqsave(&m->lock, flags);
+       path = &m->pgpath_to_activate->path;
+       m->pgpath_to_activate = NULL;
+       spin_unlock_irqrestore(&m->lock, flags);
+       if (!path)
+               return;
        ret = scsi_dh_activate(bdev_get_queue(path->dev->bdev));
        pg_init_done(path, ret);
 }
index bca448e..ace998c 100644 (file)
@@ -837,12 +837,14 @@ static int dm_merge_bvec(struct request_queue *q,
        struct dm_table *map = dm_get_table(md);
        struct dm_target *ti;
        sector_t max_sectors;
-       int max_size;
+       int max_size = 0;
 
        if (unlikely(!map))
-               return 0;
+               goto out;
 
        ti = dm_table_find_target(map, bvm->bi_sector);
+       if (!dm_target_is_valid(ti))
+               goto out_table;
 
        /*
         * Find maximum amount of I/O that won't need splitting
@@ -861,14 +863,16 @@ static int dm_merge_bvec(struct request_queue *q,
        if (max_size && ti->type->merge)
                max_size = ti->type->merge(ti, bvm, biovec, max_size);
 
+out_table:
+       dm_table_put(map);
+
+out:
        /*
         * Always allow an entire first page
         */
        if (max_size <= biovec->bv_len && !(bvm->bi_size >> SECTOR_SHIFT))
                max_size = biovec->bv_len;
 
-       dm_table_put(map);
-
        return max_size;
 }
 
index 4790c83..deeac4b 100644 (file)
@@ -5761,7 +5761,11 @@ void md_do_sync(mddev_t *mddev)
                                         * time 'round when curr_resync == 2
                                         */
                                        continue;
-                               prepare_to_wait(&resync_wait, &wq, TASK_UNINTERRUPTIBLE);
+                               /* We need to wait 'interruptible' so as not to
+                                * contribute to the load average, and not to
+                                * be caught by 'softlockup'
+                                */
+                               prepare_to_wait(&resync_wait, &wq, TASK_INTERRUPTIBLE);
                                if (!kthread_should_stop() &&
                                    mddev2->curr_resync >= mddev->curr_resync) {
                                        printk(KERN_INFO "md: delaying %s of %s"
@@ -5769,6 +5773,8 @@ void md_do_sync(mddev_t *mddev)
                                               " share one or more physical units)\n",
                                               desc, mdname(mddev), mdname(mddev2));
                                        mddev_put(mddev2);
+                                       if (signal_pending(current))
+                                               flush_signals(current);
                                        schedule();
                                        finish_wait(&resync_wait, &wq);
                                        goto try_again;
index 216025c..2c5b628 100644 (file)
@@ -10,6 +10,7 @@
 #include "dvb_frontend.h"
 
 #define XC2028_DEFAULT_FIRMWARE "xc3028-v27.fw"
+#define XC3028L_DEFAULT_FIRMWARE "xc3028L-v36.fw"
 
 /*      Dmoduler               IF (kHz) */
 #define        XC3028_FE_DEFAULT       0               /* Don't load SCODE */
index 4eed783..a127a41 100644 (file)
@@ -491,6 +491,7 @@ static struct s5h1420_config skystar2_rev2_7_s5h1420_config = {
        .demod_address = 0x53,
        .invert = 1,
        .repeated_start_workaround = 1,
+       .serial_mpeg = 1,
 };
 
 static struct itd1000_config skystar2_rev2_7_itd1000_config = {
index 069d847..0c733c6 100644 (file)
@@ -364,15 +364,16 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
                                       enum dmx_success success)
 {
        struct dmxdev_filter *dmxdevfilter = filter->priv;
+       unsigned long flags;
        int ret;
 
        if (dmxdevfilter->buffer.error) {
                wake_up(&dmxdevfilter->buffer.queue);
                return 0;
        }
-       spin_lock(&dmxdevfilter->dev->lock);
+       spin_lock_irqsave(&dmxdevfilter->dev->lock, flags);
        if (dmxdevfilter->state != DMXDEV_STATE_GO) {
-               spin_unlock(&dmxdevfilter->dev->lock);
+               spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
                return 0;
        }
        del_timer(&dmxdevfilter->timer);
@@ -391,7 +392,7 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
        }
        if (dmxdevfilter->params.sec.flags & DMX_ONESHOT)
                dmxdevfilter->state = DMXDEV_STATE_DONE;
-       spin_unlock(&dmxdevfilter->dev->lock);
+       spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
        wake_up(&dmxdevfilter->buffer.queue);
        return 0;
 }
@@ -403,11 +404,12 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
 {
        struct dmxdev_filter *dmxdevfilter = feed->priv;
        struct dvb_ringbuffer *buffer;
+       unsigned long flags;
        int ret;
 
-       spin_lock(&dmxdevfilter->dev->lock);
+       spin_lock_irqsave(&dmxdevfilter->dev->lock, flags);
        if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) {
-               spin_unlock(&dmxdevfilter->dev->lock);
+               spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
                return 0;
        }
 
@@ -417,7 +419,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
        else
                buffer = &dmxdevfilter->dev->dvr_buffer;
        if (buffer->error) {
-               spin_unlock(&dmxdevfilter->dev->lock);
+               spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
                wake_up(&buffer->queue);
                return 0;
        }
@@ -428,7 +430,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
                dvb_ringbuffer_flush(buffer);
                buffer->error = ret;
        }
-       spin_unlock(&dmxdevfilter->dev->lock);
+       spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
        wake_up(&buffer->queue);
        return 0;
 }
index e2eca0b..a2c1fd5 100644 (file)
@@ -399,7 +399,9 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
 void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
                              size_t count)
 {
-       spin_lock(&demux->lock);
+       unsigned long flags;
+
+       spin_lock_irqsave(&demux->lock, flags);
 
        while (count--) {
                if (buf[0] == 0x47)
@@ -407,16 +409,17 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
                buf += 188;
        }
 
-       spin_unlock(&demux->lock);
+       spin_unlock_irqrestore(&demux->lock, flags);
 }
 
 EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
 
 void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
 {
+       unsigned long flags;
        int p = 0, i, j;
 
-       spin_lock(&demux->lock);
+       spin_lock_irqsave(&demux->lock, flags);
 
        if (demux->tsbufp) {
                i = demux->tsbufp;
@@ -449,17 +452,18 @@ void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
        }
 
 bailout:
-       spin_unlock(&demux->lock);
+       spin_unlock_irqrestore(&demux->lock, flags);
 }
 
 EXPORT_SYMBOL(dvb_dmx_swfilter);
 
 void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
 {
+       unsigned long flags;
        int p = 0, i, j;
        u8 tmppack[188];
 
-       spin_lock(&demux->lock);
+       spin_lock_irqsave(&demux->lock, flags);
 
        if (demux->tsbufp) {
                i = demux->tsbufp;
@@ -500,7 +504,7 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
        }
 
 bailout:
-       spin_unlock(&demux->lock);
+       spin_unlock_irqrestore(&demux->lock, flags);
 }
 
 EXPORT_SYMBOL(dvb_dmx_swfilter_204);
index 747d3fa..2e9fd28 100644 (file)
@@ -59,7 +59,7 @@ struct s5h1420_state {
         * it does not support repeated-start, workaround: write addr-1
         * and then read
         */
-       u8 shadow[255];
+       u8 shadow[256];
 };
 
 static u32 s5h1420_getsymbolrate(struct s5h1420_state* state);
@@ -94,8 +94,11 @@ static u8 s5h1420_readreg(struct s5h1420_state *state, u8 reg)
                if (ret != 3)
                        return ret;
        } else {
-               ret = i2c_transfer(state->i2c, &msg[1], 2);
-               if (ret != 2)
+               ret = i2c_transfer(state->i2c, &msg[1], 1);
+               if (ret != 1)
+                       return ret;
+               ret = i2c_transfer(state->i2c, &msg[2], 1);
+               if (ret != 1)
                        return ret;
        }
 
@@ -823,7 +826,7 @@ static int s5h1420_init (struct dvb_frontend* fe)
        struct s5h1420_state* state = fe->demodulator_priv;
 
        /* disable power down and do reset */
-       state->CON_1_val = 0x10;
+       state->CON_1_val = state->config->serial_mpeg << 4;
        s5h1420_writereg(state, 0x02, state->CON_1_val);
        msleep(10);
        s5h1420_reset(state);
index 4c913f1..ff30813 100644 (file)
@@ -32,10 +32,12 @@ struct s5h1420_config
        u8 demod_address;
 
        /* does the inversion require inversion? */
-       u8 invert : 1;
+       u8 invert:1;
 
-       u8 repeated_start_workaround : 1;
-       u8 cdclk_polarity : 1; /* 1 == falling edge, 0 == raising edge */
+       u8 repeated_start_workaround:1;
+       u8 cdclk_polarity:1; /* 1 == falling edge, 0 == raising edge */
+
+       u8 serial_mpeg:1;
 };
 
 #if defined(CONFIG_DVB_S5H1420) || (defined(CONFIG_DVB_S5H1420_MODULE) && defined(MODULE))
index cc5efb6..9da260f 100644 (file)
@@ -40,6 +40,8 @@ struct usb_device_id smsusb_id_table[] = {
                .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B },
        { USB_DEVICE(0x2040, 0x5500),
                .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+       { USB_DEVICE(0x2040, 0x5510),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
        { USB_DEVICE(0x2040, 0x5580),
                .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
        { USB_DEVICE(0x2040, 0x5590),
@@ -87,7 +89,7 @@ static struct sms_board sms_boards[] = {
                .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw",
        },
        [SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = {
-               .name   = "Hauppauge WinTV-Nova-T-MiniStick",
+               .name   = "Hauppauge WinTV MiniStick",
                .type   = SMS_NOVA_B0,
                .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-01.fw",
        },
index 6ae4cc8..933eaef 100644 (file)
@@ -3431,7 +3431,7 @@ static int radio_open(struct inode *inode, struct file *file)
        dprintk("bttv: open minor=%d\n",minor);
 
        for (i = 0; i < bttv_num; i++) {
-               if (bttvs[i].radio_dev->minor == minor) {
+               if (bttvs[i].radio_dev && bttvs[i].radio_dev->minor == minor) {
                        btv = &bttvs[i];
                        break;
                }
index c149b7d..5405c30 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/fs.h>
+#include <linux/mm.h>
 #include <linux/pci.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
index a457474..a8a1990 100644 (file)
@@ -632,7 +632,7 @@ int cpia2_usb_transfer_cmd(struct camera_data *cam,
 static int submit_urbs(struct camera_data *cam)
 {
        struct urb *urb;
-       int fx, err, i;
+       int fx, err, i, j;
 
        for(i=0; i<NUM_SBUF; ++i) {
                if (cam->sbuf[i].data)
@@ -657,6 +657,9 @@ static int submit_urbs(struct camera_data *cam)
                }
                urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
                if (!urb) {
+                       ERR("%s: usb_alloc_urb error!\n", __func__);
+                       for (j = 0; j < i; j++)
+                               usb_free_urb(cam->sbuf[j].urb);
                        return -ENOMEM;
                }
 
index 8fe5f38..3cb9734 100644 (file)
@@ -163,7 +163,7 @@ static const struct cx18_card cx18_card_h900 = {
        },
        .audio_inputs = {
                { CX18_CARD_INPUT_AUD_TUNER,
-                 CX18_AV_AUDIO8, 0 },
+                 CX18_AV_AUDIO5, 0 },
                { CX18_CARD_INPUT_LINE_IN1,
                  CX18_AV_AUDIO_SERIAL1, 0 },
        },
index 3c00610..ac3292d 100644 (file)
@@ -117,10 +117,10 @@ static void em28xx_audio_isocirq(struct urb *urb)
 
                        if (oldptr + length >= runtime->buffer_size) {
                                unsigned int cnt =
-                                   runtime->buffer_size - oldptr - 1;
+                                   runtime->buffer_size - oldptr;
                                memcpy(runtime->dma_area + oldptr * stride, cp,
                                       cnt * stride);
-                               memcpy(runtime->dma_area, cp + cnt,
+                               memcpy(runtime->dma_area, cp + cnt * stride,
                                       length * stride - cnt * stride);
                        } else {
                                memcpy(runtime->dma_area + oldptr * stride, cp,
@@ -161,8 +161,14 @@ static int em28xx_init_audio_isoc(struct em28xx *dev)
 
                memset(dev->adev->transfer_buffer[i], 0x80, sb_size);
                urb = usb_alloc_urb(EM28XX_NUM_AUDIO_PACKETS, GFP_ATOMIC);
-               if (!urb)
+               if (!urb) {
+                       em28xx_errdev("usb_alloc_urb failed!\n");
+                       for (j = 0; j < i; j++) {
+                               usb_free_urb(dev->adev->urb[j]);
+                               kfree(dev->adev->transfer_buffer[j]);
+                       }
                        return -ENOMEM;
+               }
 
                urb->dev = dev->udev;
                urb->context = dev;
index 452da70..de943cf 100644 (file)
@@ -93,28 +93,6 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = 0,
                } },
        },
-       [EM2800_BOARD_KWORLD_USB2800] = {
-               .name         = "Kworld USB2800",
-               .valid        = EM28XX_BOARD_NOT_VALIDATED,
-               .is_em2800    = 1,
-               .vchannels    = 3,
-               .tuner_type   = TUNER_PHILIPS_FCV1236D,
-               .tda9887_conf = TDA9887_PRESENT,
-               .decoder      = EM28XX_SAA7113,
-               .input          = { {
-                       .type     = EM28XX_VMUX_TELEVISION,
-                       .vmux     = SAA7115_COMPOSITE2,
-                       .amux     = 0,
-               }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
-                       .vmux     = SAA7115_COMPOSITE0,
-                       .amux     = 1,
-               }, {
-                       .type     = EM28XX_VMUX_SVIDEO,
-                       .vmux     = SAA7115_SVIDEO3,
-                       .amux     = 1,
-               } },
-       },
        [EM2820_BOARD_KWORLD_PVRTV2800RF] = {
                .name         = "Kworld PVR TV 2800 RF",
                .is_em2800    = 0,
@@ -599,7 +577,7 @@ struct em28xx_board em28xx_boards[] = {
                }, {
                        .type     = EM28XX_VMUX_COMPOSITE1,
                        .vmux     = TVP5150_COMPOSITE1,
-                       .amux     = 1,
+                       .amux     = 3,
                }, {
                        .type     = EM28XX_VMUX_SVIDEO,
                        .vmux     = TVP5150_SVIDEO,
@@ -952,22 +930,23 @@ struct em28xx_board em28xx_boards[] = {
        },
        [EM2880_BOARD_KWORLD_DVB_310U] = {
                .name         = "KWorld DVB-T 310U",
-               .valid        = EM28XX_BOARD_NOT_VALIDATED,
                .vchannels    = 3,
                .tuner_type   = TUNER_XC2028,
+               .has_dvb      = 1,
+               .mts_firmware = 1,
                .decoder      = EM28XX_TVP5150,
                .input          = { {
                        .type     = EM28XX_VMUX_TELEVISION,
                        .vmux     = TVP5150_COMPOSITE0,
-                       .amux     = 0,
+                       .amux     = EM28XX_AMUX_VIDEO,
                }, {
                        .type     = EM28XX_VMUX_COMPOSITE1,
                        .vmux     = TVP5150_COMPOSITE1,
-                       .amux     = 1,
-               }, {
+                       .amux     = EM28XX_AMUX_AC97_LINE_IN,
+               }, {    /* S-video has not been tested yet */
                        .type     = EM28XX_VMUX_SVIDEO,
                        .vmux     = TVP5150_SVIDEO,
-                       .amux     = 1,
+                       .amux     = EM28XX_AMUX_AC97_LINE_IN,
                } },
        },
        [EM2881_BOARD_DNT_DA2_HYBRID] = {
@@ -1282,6 +1261,7 @@ static struct em28xx_reg_seq em2882_terratec_hybrid_xs_digital[] = {
 static struct em28xx_hash_table em28xx_eeprom_hash [] = {
        /* P/N: SA 60002070465 Tuner: TVF7533-MF */
        {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF},
+       {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028},
 };
 
 /* I2C devicelist hash table for devices with generic USB IDs */
@@ -1552,9 +1532,12 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
                /* djh - Not sure which demod we need here */
                ctl->demod = XC3028_FE_DEFAULT;
                break;
+       case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
+               ctl->demod = XC3028_FE_DEFAULT;
+               ctl->fname = XC3028L_DEFAULT_FIRMWARE;
+               break;
        case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
        case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
-       case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
                /* FIXME: Better to specify the needed IF */
                ctl->demod = XC3028_FE_DEFAULT;
                break;
@@ -1764,6 +1747,20 @@ void em28xx_card_setup(struct em28xx *dev)
                break;
        case EM2820_BOARD_UNKNOWN:
        case EM2800_BOARD_UNKNOWN:
+               /*
+                * The K-WORLD DVB-T 310U is detected as an MSI Digivox AD.
+                *
+                * This occurs because they share identical USB vendor and
+                * product IDs.
+                *
+                * What we do here is look up the EEPROM hash of the K-WORLD
+                * and if it is found then we decide that we do not have
+                * a DIGIVOX and reset the device to the K-WORLD instead.
+                *
+                * This solution is only valid if they do not share eeprom
+                * hash identities which has not been determined as yet.
+                */
+       case EM2880_BOARD_MSI_DIGIVOX_AD:
                if (!em28xx_hint_board(dev))
                        em28xx_set_model(dev);
                break;
index 4b992bc..d2b1a1a 100644 (file)
@@ -452,6 +452,15 @@ static int dvb_init(struct em28xx *dev)
                        goto out_free;
                }
                break;
+       case EM2880_BOARD_KWORLD_DVB_310U:
+               dvb->frontend = dvb_attach(zl10353_attach,
+                                               &em28xx_zl10353_with_xc3028,
+                                               &dev->i2c_adap);
+               if (attach_xc3028(0x61, dev) < 0) {
+                       result = -EINVAL;
+                       goto out_free;
+               }
+               break;
        default:
                printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card"
                                " isn't supported yet\n",
index 7be6928..ac95c55 100644 (file)
@@ -459,6 +459,7 @@ static int create_urbs(struct gspca_dev *gspca_dev,
                urb = usb_alloc_urb(npkt, GFP_KERNEL);
                if (!urb) {
                        err("usb_alloc_urb failed");
+                       destroy_urbs(gspca_dev);
                        return -ENOMEM;
                }
                urb->transfer_buffer = usb_buffer_alloc(gspca_dev->dev,
@@ -468,8 +469,8 @@ static int create_urbs(struct gspca_dev *gspca_dev,
 
                if (urb->transfer_buffer == NULL) {
                        usb_free_urb(urb);
-                       destroy_urbs(gspca_dev);
                        err("usb_buffer_urb failed");
+                       destroy_urbs(gspca_dev);
                        return -ENOMEM;
                }
                gspca_dev->urb[n] = urb;
index d4be518..ba865b7 100644 (file)
@@ -1063,6 +1063,7 @@ static __devinitdata struct usb_device_id device_table[] = {
        {USB_DEVICE(0x093a, 0x2621), .driver_info = SENSOR_PAC7302},
        {USB_DEVICE(0x093a, 0x2624), .driver_info = SENSOR_PAC7302},
        {USB_DEVICE(0x093a, 0x2626), .driver_info = SENSOR_PAC7302},
+       {USB_DEVICE(0x093a, 0x262a), .driver_info = SENSOR_PAC7302},
        {}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
index 5dd78c6..12b81ae 100644 (file)
@@ -232,7 +232,7 @@ static struct ctrl sd_ctrls[] = {
 static struct v4l2_pix_format vga_mode[] = {
        {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
                .bytesperline = 160,
-               .sizeimage = 160 * 120 * 5 / 4,
+               .sizeimage = 160 * 120,
                .colorspace = V4L2_COLORSPACE_SRGB,
                .priv = 2 | MODE_RAW},
        {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
@@ -264,7 +264,7 @@ static struct v4l2_pix_format sif_mode[] = {
                .priv = 1 | MODE_REDUCED_SIF},
        {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
                .bytesperline = 176,
-               .sizeimage = 176 * 144 * 5 / 4,
+               .sizeimage = 176 * 144,
                .colorspace = V4L2_COLORSPACE_SRGB,
                .priv = 1 | MODE_RAW},
        {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
index d75b1d2..572b0f3 100644 (file)
@@ -707,6 +707,7 @@ static void i2c_w8(struct gspca_dev *gspca_dev,
                        0x08, 0,                /* value, index */
                        gspca_dev->usb_buf, 8,
                        500);
+       msleep(2);
 }
 
 /* read 5 bytes in gspca_dev->usb_buf */
@@ -976,13 +977,13 @@ static int sd_init(struct gspca_dev *gspca_dev)
        case BRIDGE_SN9C105:
                if (regF1 != 0x11)
                        return -ENODEV;
-               reg_w(gspca_dev, 0x02, regGpio, 2);
+               reg_w(gspca_dev, 0x01, regGpio, 2);
                break;
        case BRIDGE_SN9C120:
                if (regF1 != 0x12)
                        return -ENODEV;
                regGpio[1] = 0x70;
-               reg_w(gspca_dev, 0x02, regGpio, 2);
+               reg_w(gspca_dev, 0x01, regGpio, 2);
                break;
        default:
 /*     case BRIDGE_SN9C110: */
@@ -1183,7 +1184,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
        static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
        static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd };    /* MI0360 */
        static const __u8 CE_ov76xx[] =
-                       { 0x32, 0xdd, 0x32, 0xdd };     /* OV7630/48 */
+                               { 0x32, 0xdd, 0x32, 0xdd };
 
        sn9c1xx = sn_tb[(int) sd->sensor];
        configure_gpio(gspca_dev, sn9c1xx);
@@ -1223,8 +1224,15 @@ static void sd_start(struct gspca_dev *gspca_dev)
        reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
        for (i = 0; i < 8; i++)
                reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
+       switch (sd->sensor) {
+       case SENSOR_OV7660:
+               reg_w1(gspca_dev, 0x9a, 0x05);
+               break;
+       default:
                reg_w1(gspca_dev, 0x9a, 0x08);
                reg_w1(gspca_dev, 0x99, 0x59);
+               break;
+       }
 
        mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
        if (mode)
@@ -1275,8 +1283,8 @@ static void sd_start(struct gspca_dev *gspca_dev)
 /*                     reg1 = 0x44; */
 /*                     reg1 = 0x46;    (done) */
                } else {
-                       reg17 = 0x22;   /* 640 MCKSIZE */
-                       reg1 = 0x06;
+                       reg17 = 0xa2;   /* 640 */
+                       reg1 = 0x44;
                }
                break;
        }
@@ -1285,6 +1293,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
        switch (sd->sensor) {
        case SENSOR_OV7630:
        case SENSOR_OV7648:
+       case SENSOR_OV7660:
                reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
                break;
        default:
index cfbc9eb..95fcfcb 100644 (file)
@@ -225,7 +225,7 @@ static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
        reg_w_val(gspca_dev->dev, 0x8802, (mode | 0x01));
        do {
                reg_r(gspca_dev, 0x8803, 1);
-               if (!gspca_dev->usb_buf)
+               if (!gspca_dev->usb_buf[0])
                        break;
        } while (--retry);
        if (retry == 0)
index 8d7c27e..d61ef72 100644 (file)
@@ -6576,8 +6576,8 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
                 cs2102_60HZ, cs2102_60HZScale},
 /* SENSOR_CS2102K 1 */
                {cs2102_NoFliker, cs2102_NoFlikerScale,
-                cs2102_50HZ, cs2102_50HZScale,
-                cs2102_60HZ, cs2102_60HZScale},
+                NULL, NULL, /* currently disabled */
+                NULL, NULL},
 /* SENSOR_GC0305 2 */
                {gc0305_NoFliker, gc0305_NoFliker,
                 gc0305_50HZ, gc0305_50HZ,
index 3d3c48d..c685240 100644 (file)
@@ -3591,7 +3591,7 @@ static int
 ov51x_init_isoc(struct usb_ov511 *ov)
 {
        struct urb *urb;
-       int fx, err, n, size;
+       int fx, err, n, i, size;
 
        PDEBUG(3, "*** Initializing capture ***");
 
@@ -3662,6 +3662,8 @@ ov51x_init_isoc(struct usb_ov511 *ov)
                urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
                if (!urb) {
                        err("init isoc: usb_alloc_urb ret. NULL");
+                       for (i = 0; i < n; i++)
+                               usb_free_urb(ov->sbuf[i].urb);
                        return -ENOMEM;
                }
                ov->sbuf[n].urb = urb;
@@ -5651,7 +5653,7 @@ static ssize_t show_exposure(struct device *cd,
        if (!ov->dev)
                return -ENODEV;
        sensor_get_exposure(ov, &exp);
-       return sprintf(buf, "%d\n", exp >> 8);
+       return sprintf(buf, "%d\n", exp);
 }
 static DEVICE_ATTR(exposure, S_IRUGO, show_exposure, NULL);
 
index 88e1751..cbe2a34 100644 (file)
@@ -489,6 +489,8 @@ static const struct pvr2_device_desc pvr2_device_751xx = {
 struct usb_device_id pvr2_device_table[] = {
        { USB_DEVICE(0x2040, 0x2900),
          .driver_info = (kernel_ulong_t)&pvr2_device_29xxx},
+       { USB_DEVICE(0x2040, 0x2950), /* Logically identical to 2900 */
+         .driver_info = (kernel_ulong_t)&pvr2_device_29xxx},
        { USB_DEVICE(0x2040, 0x2400),
          .driver_info = (kernel_ulong_t)&pvr2_device_24xxx},
        { USB_DEVICE(0x1164, 0x0622),
index b1d09d8..92b83fe 100644 (file)
@@ -669,7 +669,7 @@ static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf,
                (unsigned long)vbuf, pos);
        /* tell v4l buffer was filled */
 
-       buf->vb.field_count++;
+       buf->vb.field_count = dev->frame_count[chn] * 2;
        do_gettimeofday(&ts);
        buf->vb.ts = ts;
        buf->vb.state = VIDEOBUF_DONE;
@@ -1268,6 +1268,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
        dev->last_frame[chn] = -1;
        dev->bad_payload[chn] = 0;
        dev->cur_frame[chn] = 0;
+       dev->frame_count[chn] = 0;
        for (j = 0; j < SYS_FRAMES; j++) {
                dev->buffer[chn].frame[j].ulState = 0;
                dev->buffer[chn].frame[j].cur_size = 0;
index 6ef3e52..feab12a 100644 (file)
@@ -592,7 +592,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
        if (ctrl == NULL)
                return -EINVAL;
 
-       data = kmalloc(8, GFP_KERNEL);
+       data = kmalloc(ctrl->info->size, GFP_KERNEL);
        if (data == NULL)
                return -ENOMEM;
 
index 168baab..11edf79 100644 (file)
@@ -911,7 +911,6 @@ static int w9968cf_start_transfer(struct w9968cf_device* cam)
 
        for (i = 0; i < W9968CF_URBS; i++) {
                urb = usb_alloc_urb(W9968CF_ISO_PACKETS, GFP_KERNEL);
-               cam->urb[i] = urb;
                if (!urb) {
                        for (j = 0; j < i; j++)
                                usb_free_urb(cam->urb[j]);
@@ -919,6 +918,7 @@ static int w9968cf_start_transfer(struct w9968cf_device* cam)
                        return -ENOMEM;
                }
 
+               cam->urb[i] = urb;
                urb->dev = udev;
                urb->context = (void*)cam;
                urb->pipe = usb_rcvisocpipe(udev, 1);
index 95c79ad..54ac3fe 100644 (file)
@@ -274,10 +274,8 @@ static int wm8739_probe(struct i2c_client *client,
                        client->addr << 1, client->adapter->name);
 
        state = kmalloc(sizeof(struct wm8739_state), GFP_KERNEL);
-       if (state == NULL) {
-               kfree(client);
+       if (state == NULL)
                return -ENOMEM;
-       }
        state->vol_l = 0x17; /* 0dB */
        state->vol_r = 0x17; /* 0dB */
        state->muted = 0;
index d842a7c..3282be7 100644 (file)
@@ -988,7 +988,7 @@ zoran_open_init_params (struct zoran *zr)
        zr->v4l_grab_seq = 0;
        zr->v4l_settings.width = 192;
        zr->v4l_settings.height = 144;
-       zr->v4l_settings.format = &zoran_formats[4];    /* YUY2 - YUV-4:2:2 packed */
+       zr->v4l_settings.format = &zoran_formats[7];    /* YUY2 - YUV-4:2:2 packed */
        zr->v4l_settings.bytesperline =
            zr->v4l_settings.width *
            ((zr->v4l_settings.format->depth + 7) / 8);
index ec6f596..2dab9ee 100644 (file)
@@ -134,7 +134,7 @@ const struct zoran_format zoran_formats[] = {
        }, {
                .name = "16-bit RGB BE",
                ZFMT(-1,
-                    V4L2_PIX_FMT_RGB565, V4L2_COLORSPACE_SRGB),
+                    V4L2_PIX_FMT_RGB565X, V4L2_COLORSPACE_SRGB),
                .depth = 16,
                .flags = ZORAN_FORMAT_CAPTURE |
                         ZORAN_FORMAT_OVERLAY,
@@ -2737,7 +2737,8 @@ zoran_do_ioctl (struct inode *inode,
                                    fh->v4l_settings.format->fourcc;
                                fmt->fmt.pix.colorspace =
                                    fh->v4l_settings.format->colorspace;
-                               fmt->fmt.pix.bytesperline = 0;
+                               fmt->fmt.pix.bytesperline =
+                                   fh->v4l_settings.bytesperline;
                                if (BUZ_MAX_HEIGHT <
                                    (fh->v4l_settings.height * 2))
                                        fmt->fmt.pix.field =
@@ -2833,13 +2834,6 @@ zoran_do_ioctl (struct inode *inode,
                                fmt->fmt.pix.pixelformat,
                                (char *) &printformat);
 
-                       if (fmt->fmt.pix.bytesperline > 0) {
-                               dprintk(5,
-                                       KERN_ERR "%s: bpl not supported\n",
-                                       ZR_DEVNAME(zr));
-                               return -EINVAL;
-                       }
-
                        /* we can be requested to do JPEG/raw playback/capture */
                        if (!
                            (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
@@ -2923,6 +2917,7 @@ zoran_do_ioctl (struct inode *inode,
                                fh->jpg_buffers.buffer_size =
                                    zoran_v4l2_calc_bufsize(&fh->
                                                            jpg_settings);
+                               fmt->fmt.pix.bytesperline = 0;
                                fmt->fmt.pix.sizeimage =
                                    fh->jpg_buffers.buffer_size;
 
@@ -2979,6 +2974,8 @@ zoran_do_ioctl (struct inode *inode,
 
                                /* tell the user the
                                 * results/missing stuff */
+                               fmt->fmt.pix.bytesperline =
+                                       fh->v4l_settings.bytesperline;
                                fmt->fmt.pix.sizeimage =
                                        fh->v4l_settings.height *
                                        fh->v4l_settings.bytesperline;
index 10c44d3..68dc8d9 100644 (file)
@@ -21,7 +21,7 @@ config MFD_SM501
 
 config MFD_SM501_GPIO
        bool "Export GPIO via GPIO layer"
-       depends on MFD_SM501 && HAVE_GPIO_LIB
+       depends on MFD_SM501 && GPIOLIB
         ---help---
         This option uses the gpio library layer to export the 64 GPIO
         lines on the SM501. The platform data is used to supply the
@@ -29,7 +29,7 @@ config MFD_SM501_GPIO
 
 config MFD_ASIC3
        bool "Support for Compaq ASIC3"
-       depends on GENERIC_HARDIRQS && HAVE_GPIO_LIB && ARM
+       depends on GENERIC_HARDIRQS && GPIOLIB && ARM
         ---help---
          This driver supports the ASIC3 multifunction chip found on many
          PDAs (mainly iPAQ and HTC based ones)
index bc2a807..ba5aa20 100644 (file)
@@ -312,7 +312,6 @@ static int __init asic3_irq_probe(struct platform_device *pdev)
        struct asic3 *asic = platform_get_drvdata(pdev);
        unsigned long clksel = 0;
        unsigned int irq, irq_base;
-       int map_size;
        int ret;
 
        ret = platform_get_irq(pdev, 0);
@@ -534,6 +533,7 @@ static int __init asic3_probe(struct platform_device *pdev)
        struct asic3 *asic;
        struct resource *mem;
        unsigned long clksel;
+       int map_size;
        int ret = 0;
 
        asic = kzalloc(sizeof(struct asic3), GFP_KERNEL);
index facdb98..1ee8501 100644 (file)
@@ -450,12 +450,14 @@ static int eeepc_get_fan_pwm(void)
        int value = 0;
 
        read_acpi_int(NULL, EEEPC_EC_FAN_PWM, &value);
+       value = value * 255 / 100;
        return (value);
 }
 
 static void eeepc_set_fan_pwm(int value)
 {
-       value = SENSORS_LIMIT(value, 0, 100);
+       value = SENSORS_LIMIT(value, 0, 255);
+       value = value * 100 / 255;
        ec_write(EEEPC_EC_SC02, value);
 }
 
@@ -520,15 +522,23 @@ static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
        static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
 
 EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
-EEEPC_CREATE_SENSOR_ATTR(fan1_pwm, S_IRUGO | S_IWUSR,
+EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
                         eeepc_get_fan_pwm, eeepc_set_fan_pwm);
 EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
                         eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
 
+static ssize_t
+show_name(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       return sprintf(buf, "eeepc\n");
+}
+static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
+
 static struct attribute *hwmon_attributes[] = {
-       &sensor_dev_attr_fan1_pwm.dev_attr.attr,
+       &sensor_dev_attr_pwm1.dev_attr.attr,
        &sensor_dev_attr_fan1_input.dev_attr.attr,
        &sensor_dev_attr_pwm1_enable.dev_attr.attr,
+       &sensor_dev_attr_name.dev_attr.attr,
        NULL
 };
 
index 6986f39..ebc8b9d 100644 (file)
@@ -615,14 +615,19 @@ static struct mmc_driver mmc_driver = {
 
 static int __init mmc_blk_init(void)
 {
-       int res = -ENOMEM;
+       int res;
 
        res = register_blkdev(MMC_BLOCK_MAJOR, "mmc");
        if (res)
                goto out;
 
-       return mmc_register_driver(&mmc_driver);
+       res = mmc_register_driver(&mmc_driver);
+       if (res)
+               goto out2;
 
+       return 0;
+ out2:
+       unregister_blkdev(MMC_BLOCK_MAJOR, "mmc");
  out:
        return res;
 }
index f26b01d..b92b172 100644 (file)
@@ -1040,7 +1040,7 @@ static const struct mmc_test_case mmc_test_cases[] = {
 
 };
 
-static struct mutex mmc_test_lock;
+static DEFINE_MUTEX(mmc_test_lock);
 
 static void mmc_test_run(struct mmc_test_card *test, int testcase)
 {
@@ -1171,8 +1171,6 @@ static int mmc_test_probe(struct mmc_card *card)
        if ((card->type != MMC_TYPE_MMC) && (card->type != MMC_TYPE_SD))
                return -ENODEV;
 
-       mutex_init(&mmc_test_lock);
-
        ret = device_create_file(&card->dev, &dev_attr_test);
        if (ret)
                return ret;
index 0bd06f5..0000896 100644 (file)
@@ -195,7 +195,9 @@ static int atmci_regs_show(struct seq_file *s, void *v)
 
        /* Grab a more or less consistent snapshot */
        spin_lock_irq(&host->mmc->lock);
+       clk_enable(host->mck);
        memcpy_fromio(buf, host->regs, MCI_REGS_SIZE);
+       clk_disable(host->mck);
        spin_unlock_irq(&host->mmc->lock);
 
        seq_printf(s, "MR:\t0x%08x%s%s CLKDIV=%u\n",
@@ -216,6 +218,8 @@ static int atmci_regs_show(struct seq_file *s, void *v)
        atmci_show_status_reg(s, "SR", buf[MCI_SR / 4]);
        atmci_show_status_reg(s, "IMR", buf[MCI_IMR / 4]);
 
+       kfree(buf);
+
        return 0;
 }
 
@@ -237,7 +241,6 @@ static void atmci_init_debugfs(struct atmel_mci *host)
        struct mmc_host *mmc;
        struct dentry   *root;
        struct dentry   *node;
-       struct resource *res;
 
        mmc = host->mmc;
        root = mmc->debugfs_root;
@@ -251,9 +254,6 @@ static void atmci_init_debugfs(struct atmel_mci *host)
        if (!node)
                goto err;
 
-       res = platform_get_resource(host->pdev, IORESOURCE_MEM, 0);
-       node->d_inode->i_size = res->end - res->start + 1;
-
        node = debugfs_create_file("req", S_IRUSR, root, host, &atmci_req_fops);
        if (!node)
                goto err;
@@ -426,8 +426,6 @@ static u32 atmci_submit_data(struct mmc_host *mmc, struct mmc_data *data)
        host->sg = NULL;
        host->data = data;
 
-       mci_writel(host, BLKR, MCI_BCNT(data->blocks)
-                       | MCI_BLKLEN(data->blksz));
        dev_vdbg(&mmc->class_dev, "BLKR=0x%08x\n",
                        MCI_BCNT(data->blocks) | MCI_BLKLEN(data->blksz));
 
@@ -483,6 +481,10 @@ static void atmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
                if (data->blocks > 1 && data->blksz & 3)
                        goto fail;
                atmci_set_timeout(host, data);
+
+               /* Must set block count/size before sending command */
+               mci_writel(host, BLKR, MCI_BCNT(data->blocks)
+                               | MCI_BLKLEN(data->blksz));
        }
 
        iflags = MCI_CMDRDY;
@@ -1059,6 +1061,10 @@ static int __init atmci_probe(struct platform_device *pdev)
                        host->present = !gpio_get_value(host->detect_pin);
                }
        }
+
+       if (!gpio_is_valid(host->detect_pin))
+               mmc->caps |= MMC_CAP_NEEDS_POLL;
+
        if (gpio_is_valid(host->wp_pin)) {
                if (gpio_request(host->wp_pin, "mmc_wp")) {
                        dev_dbg(&mmc->class_dev, "no WP pin available\n");
index 9e647a0..ba2b424 100644 (file)
@@ -159,10 +159,10 @@ static inline void tmio_mmc_kunmap_atomic(struct tmio_mmc_host *host,
 #define STATUS_TO_TEXT(a) \
        do { \
                if (status & TMIO_STAT_##a) \
-                       printf(#a); \
+                       printk(#a); \
        } while (0)
 
-void debug_status(u32 status)
+void pr_debug_status(u32 status)
 {
        printk(KERN_DEBUG "status: %08x = ", status);
        STATUS_TO_TEXT(CARD_REMOVE);
index c3c579f..dfacd31 100644 (file)
@@ -6597,7 +6597,7 @@ struct flash_spec {
 
 struct bnx2_irq {
        irq_handler_t   handler;
-       u16             vector;
+       unsigned int    vector;
        u8              requested;
        char            name[16];
 };
index 453115a..5cf78d6 100644 (file)
@@ -2738,9 +2738,7 @@ static int __devinit e100_probe(struct pci_dev *pdev,
                nic->flags |= wol_magic;
 
        /* ack any pending wake events, disable PME */
-       err = pci_enable_wake(pdev, 0, 0);
-       if (err)
-               DPRINTK(PROBE, ERR, "Error clearing wake event\n");
+       pci_pme_active(pdev, false);
 
        strcpy(netdev->name, "eth%d");
        if((err = register_netdev(netdev))) {
index 9d6edf3..d04eef5 100644 (file)
@@ -144,6 +144,8 @@ static s32 e1000_host_if_read_cookie(struct e1000_hw *hw, u8 *buffer);
 static u8 e1000_calculate_mng_checksum(char *buffer, u32 length);
 static s32 e1000_configure_kmrn_for_10_100(struct e1000_hw *hw, u16 duplex);
 static s32 e1000_configure_kmrn_for_1000(struct e1000_hw *hw);
+static s32 e1000_do_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
+static s32 e1000_do_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
 
 /* IGP cable length table */
 static const
@@ -168,6 +170,8 @@ u16 e1000_igp_2_cable_length_table[IGP02E1000_AGC_LENGTH_TABLE_SIZE] =
       83, 89, 95, 100, 105, 109, 113, 116, 119, 122, 124,
       104, 109, 114, 118, 121, 124};
 
+static DEFINE_SPINLOCK(e1000_eeprom_lock);
+
 /******************************************************************************
  * Set the phy type member in the hw struct.
  *
@@ -4903,6 +4907,15 @@ static s32 e1000_spi_eeprom_ready(struct e1000_hw *hw)
  * words - number of words to read
  *****************************************************************************/
 s32 e1000_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
+{
+    s32 ret;
+    spin_lock(&e1000_eeprom_lock);
+    ret = e1000_do_read_eeprom(hw, offset, words, data);
+    spin_unlock(&e1000_eeprom_lock);
+    return ret;
+}
+
+static s32 e1000_do_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
 {
     struct e1000_eeprom_info *eeprom = &hw->eeprom;
     u32 i = 0;
@@ -5235,6 +5248,16 @@ s32 e1000_update_eeprom_checksum(struct e1000_hw *hw)
  * EEPROM will most likely contain an invalid checksum.
  *****************************************************************************/
 s32 e1000_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
+{
+    s32 ret;
+    spin_lock(&e1000_eeprom_lock);
+    ret = e1000_do_write_eeprom(hw, offset, words, data);
+    spin_unlock(&e1000_eeprom_lock);
+    return ret;
+}
+
+
+static s32 e1000_do_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
 {
     struct e1000_eeprom_info *eeprom = &hw->eeprom;
     s32 status = 0;
index ac4e506..5ea6b60 100644 (file)
@@ -257,7 +257,6 @@ struct e1000_adapter {
        struct net_device *netdev;
        struct pci_dev *pdev;
        struct net_device_stats net_stats;
-       spinlock_t stats_lock;      /* prevent concurrent stats updates */
 
        /* structs defined in e1000_hw.h */
        struct e1000_hw hw;
@@ -284,6 +283,8 @@ struct e1000_adapter {
        unsigned long led_status;
 
        unsigned int flags;
+       struct work_struct downshift_task;
+       struct work_struct update_phy_task;
 };
 
 struct e1000_info {
@@ -305,6 +306,7 @@ struct e1000_info {
 #define FLAG_HAS_CTRLEXT_ON_LOAD          (1 << 5)
 #define FLAG_HAS_SWSM_ON_LOAD             (1 << 6)
 #define FLAG_HAS_JUMBO_FRAMES             (1 << 7)
+#define FLAG_READ_ONLY_NVM                (1 << 8)
 #define FLAG_IS_ICH                       (1 << 9)
 #define FLAG_HAS_SMART_POWER_DOWN         (1 << 11)
 #define FLAG_IS_QUAD_PORT_A               (1 << 12)
@@ -385,6 +387,7 @@ extern bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw);
 extern bool e1000e_get_laa_state_82571(struct e1000_hw *hw);
 extern void e1000e_set_laa_state_82571(struct e1000_hw *hw, bool state);
 
+extern void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw);
 extern void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
                                                 bool state);
 extern void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
index e21c9e0..33a3ff1 100644 (file)
@@ -432,6 +432,10 @@ static void e1000_get_regs(struct net_device *netdev,
        regs_buff[11] = er32(TIDV);
 
        regs_buff[12] = adapter->hw.phy.type;  /* PHY type (IGP=1, M88=0) */
+
+       /* ethtool doesn't use anything past this point, so all this
+        * code is likely legacy junk for apps that may or may not
+        * exist */
        if (hw->phy.type == e1000_phy_m88) {
                e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
                regs_buff[13] = (u32)phy_data; /* cable length */
@@ -447,7 +451,7 @@ static void e1000_get_regs(struct net_device *netdev,
                regs_buff[22] = adapter->phy_stats.receive_errors;
                regs_buff[23] = regs_buff[13]; /* mdix mode */
        }
-       regs_buff[21] = adapter->phy_stats.idle_errors;  /* phy idle errors */
+       regs_buff[21] = 0; /* was idle_errors */
        e1e_rphy(hw, PHY_1000T_STATUS, &phy_data);
        regs_buff[24] = (u32)phy_data;  /* phy local receiver status */
        regs_buff[25] = regs_buff[24];  /* phy remote receiver status */
@@ -529,6 +533,9 @@ static int e1000_set_eeprom(struct net_device *netdev,
        if (eeprom->magic != (adapter->pdev->vendor | (adapter->pdev->device << 16)))
                return -EFAULT;
 
+       if (adapter->flags & FLAG_READ_ONLY_NVM)
+               return -EINVAL;
+
        max_len = hw->nvm.word_size * 2;
 
        first_word = eeprom->offset >> 1;
index 9e38452..bcd2bc4 100644 (file)
@@ -58,6 +58,7 @@
 #define ICH_FLASH_HSFCTL               0x0006
 #define ICH_FLASH_FADDR                        0x0008
 #define ICH_FLASH_FDATA0               0x0010
+#define ICH_FLASH_PR0                  0x0074
 
 #define ICH_FLASH_READ_COMMAND_TIMEOUT 500
 #define ICH_FLASH_WRITE_COMMAND_TIMEOUT        500
@@ -150,6 +151,19 @@ union ich8_hws_flash_regacc {
        u16 regval;
 };
 
+/* ICH Flash Protected Region */
+union ich8_flash_protected_range {
+       struct ich8_pr {
+               u32 base:13;     /* 0:12 Protected Range Base */
+               u32 reserved1:2; /* 13:14 Reserved */
+               u32 rpe:1;       /* 15 Read Protection Enable */
+               u32 limit:13;    /* 16:28 Protected Range Limit */
+               u32 reserved2:2; /* 29:30 Reserved */
+               u32 wpe:1;       /* 31 Write Protection Enable */
+       } range;
+       u32 regval;
+};
+
 static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw);
 static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw);
 static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw);
@@ -366,6 +380,9 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
        return 0;
 }
 
+static DEFINE_MUTEX(nvm_mutex);
+static pid_t nvm_owner = -1;
+
 /**
  *  e1000_acquire_swflag_ich8lan - Acquire software control flag
  *  @hw: pointer to the HW structure
@@ -379,6 +396,15 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
        u32 extcnf_ctrl;
        u32 timeout = PHY_CFG_TIMEOUT;
 
+       might_sleep();
+
+       if (!mutex_trylock(&nvm_mutex)) {
+               WARN(1, KERN_ERR "e1000e mutex contention. Owned by pid %d\n",
+                    nvm_owner);
+               mutex_lock(&nvm_mutex);
+       }
+       nvm_owner = current->pid;
+
        while (timeout) {
                extcnf_ctrl = er32(EXTCNF_CTRL);
                extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
@@ -393,6 +419,8 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
 
        if (!timeout) {
                hw_dbg(hw, "FW or HW has locked the resource for too long.\n");
+               nvm_owner = -1;
+               mutex_unlock(&nvm_mutex);
                return -E1000_ERR_CONFIG;
        }
 
@@ -414,6 +442,9 @@ static void e1000_release_swflag_ich8lan(struct e1000_hw *hw)
        extcnf_ctrl = er32(EXTCNF_CTRL);
        extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
        ew32(EXTCNF_CTRL, extcnf_ctrl);
+
+       nvm_owner = -1;
+       mutex_unlock(&nvm_mutex);
 }
 
 /**
@@ -1284,6 +1315,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
         * programming failed.
         */
        if (ret_val) {
+               /* Possibly read-only, see e1000e_write_protect_nvm_ich8lan() */
                hw_dbg(hw, "Flash commit failed.\n");
                e1000_release_swflag_ich8lan(hw);
                return ret_val;
@@ -1373,6 +1405,49 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw)
        return e1000e_validate_nvm_checksum_generic(hw);
 }
 
+/**
+ *  e1000e_write_protect_nvm_ich8lan - Make the NVM read-only
+ *  @hw: pointer to the HW structure
+ *
+ *  To prevent malicious write/erase of the NVM, set it to be read-only
+ *  so that the hardware ignores all write/erase cycles of the NVM via
+ *  the flash control registers.  The shadow-ram copy of the NVM will
+ *  still be updated, however any updates to this copy will not stick
+ *  across driver reloads.
+ **/
+void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw)
+{
+       union ich8_flash_protected_range pr0;
+       union ich8_hws_flash_status hsfsts;
+       u32 gfpreg;
+       s32 ret_val;
+
+       ret_val = e1000_acquire_swflag_ich8lan(hw);
+       if (ret_val)
+               return;
+
+       gfpreg = er32flash(ICH_FLASH_GFPREG);
+
+       /* Write-protect GbE Sector of NVM */
+       pr0.regval = er32flash(ICH_FLASH_PR0);
+       pr0.range.base = gfpreg & FLASH_GFPREG_BASE_MASK;
+       pr0.range.limit = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK);
+       pr0.range.wpe = true;
+       ew32flash(ICH_FLASH_PR0, pr0.regval);
+
+       /*
+        * Lock down a subset of GbE Flash Control Registers, e.g.
+        * PR0 to prevent the write-protection from being lifted.
+        * Once FLOCKDN is set, the registers protected by it cannot
+        * be written until FLOCKDN is cleared by a hardware reset.
+        */
+       hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
+       hsfsts.hsf_status.flockdn = true;
+       ew32flash(ICH_FLASH_HSFSTS, hsfsts.regval);
+
+       e1000_release_swflag_ich8lan(hw);
+}
+
 /**
  *  e1000_write_flash_data_ich8lan - Writes bytes to the NVM
  *  @hw: pointer to the HW structure
@@ -1720,6 +1795,9 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
        ew32(CTRL, (ctrl | E1000_CTRL_RST));
        msleep(20);
 
+       /* release the swflag because it is not reset by hardware reset */
+       e1000_release_swflag_ich8lan(hw);
+
        ret_val = e1000e_get_auto_rd_done(hw);
        if (ret_val) {
                /*
index d266510..b81c423 100644 (file)
@@ -47,7 +47,7 @@
 
 #include "e1000.h"
 
-#define DRV_VERSION "0.3.3.3-k2"
+#define DRV_VERSION "0.3.3.3-k6"
 char e1000e_driver_name[] = "e1000e";
 const char e1000e_driver_version[] = DRV_VERSION;
 
@@ -1115,6 +1115,14 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter)
        writel(0, adapter->hw.hw_addr + rx_ring->tail);
 }
 
+static void e1000e_downshift_workaround(struct work_struct *work)
+{
+       struct e1000_adapter *adapter = container_of(work,
+                                       struct e1000_adapter, downshift_task);
+
+       e1000e_gig_downshift_workaround_ich8lan(&adapter->hw);
+}
+
 /**
  * e1000_intr_msi - Interrupt Handler
  * @irq: interrupt number
@@ -1139,7 +1147,7 @@ static irqreturn_t e1000_intr_msi(int irq, void *data)
                 */
                if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) &&
                    (!(er32(STATUS) & E1000_STATUS_LU)))
-                       e1000e_gig_downshift_workaround_ich8lan(hw);
+                       schedule_work(&adapter->downshift_task);
 
                /*
                 * 80003ES2LAN workaround-- For packet buffer work-around on
@@ -1205,7 +1213,7 @@ static irqreturn_t e1000_intr(int irq, void *data)
                 */
                if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) &&
                    (!(er32(STATUS) & E1000_STATUS_LU)))
-                       e1000e_gig_downshift_workaround_ich8lan(hw);
+                       schedule_work(&adapter->downshift_task);
 
                /*
                 * 80003ES2LAN workaround--
@@ -2592,8 +2600,6 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
        /* Explicitly disable IRQ since the NIC can be in any state. */
        e1000_irq_disable(adapter);
 
-       spin_lock_init(&adapter->stats_lock);
-
        set_bit(__E1000_DOWN, &adapter->state);
        return 0;
 
@@ -2912,6 +2918,21 @@ static int e1000_set_mac(struct net_device *netdev, void *p)
        return 0;
 }
 
+/**
+ * e1000e_update_phy_task - work thread to update phy
+ * @work: pointer to our work struct
+ *
+ * this worker thread exists because we must acquire a
+ * semaphore to read the phy, which we could msleep while
+ * waiting for it, and we can't msleep in a timer.
+ **/
+static void e1000e_update_phy_task(struct work_struct *work)
+{
+       struct e1000_adapter *adapter = container_of(work,
+                                       struct e1000_adapter, update_phy_task);
+       e1000_get_phy_info(&adapter->hw);
+}
+
 /*
  * Need to wait a few seconds after link up to get diagnostic information from
  * the phy
@@ -2919,7 +2940,7 @@ static int e1000_set_mac(struct net_device *netdev, void *p)
 static void e1000_update_phy_info(unsigned long data)
 {
        struct e1000_adapter *adapter = (struct e1000_adapter *) data;
-       e1000_get_phy_info(&adapter->hw);
+       schedule_work(&adapter->update_phy_task);
 }
 
 /**
@@ -2930,10 +2951,6 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
 {
        struct e1000_hw *hw = &adapter->hw;
        struct pci_dev *pdev = adapter->pdev;
-       unsigned long irq_flags;
-       u16 phy_tmp;
-
-#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
 
        /*
         * Prevent stats update while adapter is being reset, or if the pci
@@ -2944,14 +2961,6 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
        if (pci_channel_offline(pdev))
                return;
 
-       spin_lock_irqsave(&adapter->stats_lock, irq_flags);
-
-       /*
-        * these counters are modified from e1000_adjust_tbi_stats,
-        * called from the interrupt context, so they must only
-        * be written while holding adapter->stats_lock
-        */
-
        adapter->stats.crcerrs += er32(CRCERRS);
        adapter->stats.gprc += er32(GPRC);
        adapter->stats.gorc += er32(GORCL);
@@ -3022,21 +3031,10 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
 
        /* Tx Dropped needs to be maintained elsewhere */
 
-       /* Phy Stats */
-       if (hw->phy.media_type == e1000_media_type_copper) {
-               if ((adapter->link_speed == SPEED_1000) &&
-                  (!e1e_rphy(hw, PHY_1000T_STATUS, &phy_tmp))) {
-                       phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
-                       adapter->phy_stats.idle_errors += phy_tmp;
-               }
-       }
-
        /* Management Stats */
        adapter->stats.mgptc += er32(MGTPTC);
        adapter->stats.mgprc += er32(MGTPRC);
        adapter->stats.mgpdc += er32(MGTPDC);
-
-       spin_unlock_irqrestore(&adapter->stats_lock, irq_flags);
 }
 
 /**
@@ -3048,10 +3046,6 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter)
        struct e1000_hw *hw = &adapter->hw;
        struct e1000_phy_regs *phy = &adapter->phy_regs;
        int ret_val;
-       unsigned long irq_flags;
-
-
-       spin_lock_irqsave(&adapter->stats_lock, irq_flags);
 
        if ((er32(STATUS) & E1000_STATUS_LU) &&
            (adapter->hw.phy.media_type == e1000_media_type_copper)) {
@@ -3082,8 +3076,6 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter)
                phy->stat1000 = 0;
                phy->estatus = (ESTATUS_1000_TFULL | ESTATUS_1000_THALF);
        }
-
-       spin_unlock_irqrestore(&adapter->stats_lock, irq_flags);
 }
 
 static void e1000_print_link_info(struct e1000_adapter *adapter)
@@ -4467,6 +4459,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 
        adapter->bd_number = cards_found++;
 
+       e1000e_check_options(adapter);
+
        /* setup adapter struct */
        err = e1000_sw_init(adapter);
        if (err)
@@ -4482,6 +4476,10 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        if (err)
                goto err_hw_init;
 
+       if ((adapter->flags & FLAG_IS_ICH) &&
+           (adapter->flags & FLAG_READ_ONLY_NVM))
+               e1000e_write_protect_nvm_ich8lan(&adapter->hw);
+
        hw->mac.ops.get_bus_info(&adapter->hw);
 
        adapter->hw.phy.autoneg_wait_to_complete = 0;
@@ -4572,8 +4570,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 
        INIT_WORK(&adapter->reset_task, e1000_reset_task);
        INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task);
-
-       e1000e_check_options(adapter);
+       INIT_WORK(&adapter->downshift_task, e1000e_downshift_workaround);
+       INIT_WORK(&adapter->update_phy_task, e1000e_update_phy_task);
 
        /* Initialize link parameters. User can change them with ethtool */
        adapter->hw.mac.autoneg = 1;
index ed912e0..d91dbf7 100644 (file)
@@ -133,6 +133,15 @@ E1000_PARAM(SmartPowerDownEnable, "Enable PHY smart power down");
  */
 E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround");
 
+/*
+ * Write Protect NVM
+ *
+ * Valid Range: 0, 1
+ *
+ * Default Value: 1 (enabled)
+ */
+E1000_PARAM(WriteProtectNVM, "Write-protect NVM [WARNING: disabling this can lead to corrupted NVM]");
+
 struct e1000_option {
        enum { enable_option, range_option, list_option } type;
        const char *name;
@@ -388,4 +397,25 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
                                                                       opt.def);
                }
        }
+       { /* Write-protect NVM */
+               const struct e1000_option opt = {
+                       .type = enable_option,
+                       .name = "Write-protect NVM",
+                       .err  = "defaulting to Enabled",
+                       .def  = OPTION_ENABLED
+               };
+
+               if (adapter->flags & FLAG_IS_ICH) {
+                       if (num_WriteProtectNVM > bd) {
+                               unsigned int write_protect_nvm = WriteProtectNVM[bd];
+                               e1000_validate_option(&write_protect_nvm, &opt,
+                                                     adapter);
+                               if (write_protect_nvm)
+                                       adapter->flags |= FLAG_READ_ONLY_NVM;
+                       } else {
+                               if (opt.def)
+                                       adapter->flags |= FLAG_READ_ONLY_NVM;
+                       }
+               }
+       }
 }
index 0b6ecef..eeb55ed 100644 (file)
@@ -5643,6 +5643,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
                dev->dev_addr[4] = (np->orig_mac[0] >>  8) & 0xff;
                dev->dev_addr[5] = (np->orig_mac[0] >>  0) & 0xff;
                writel(txreg|NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + NvRegTransmitPoll);
+               printk(KERN_DEBUG "nv_probe: set workaround bit for reversed mac addr\n");
        }
        memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
@@ -5890,14 +5891,12 @@ static void nv_restore_phy(struct net_device *dev)
        }
 }
 
-static void __devexit nv_remove(struct pci_dev *pci_dev)
+static void nv_restore_mac_addr(struct pci_dev *pci_dev)
 {
        struct net_device *dev = pci_get_drvdata(pci_dev);
        struct fe_priv *np = netdev_priv(dev);
        u8 __iomem *base = get_hwbase(dev);
 
-       unregister_netdev(dev);
-
        /* special op: write back the misordered MAC address - otherwise
         * the next nv_probe would see a wrong address.
         */
@@ -5905,6 +5904,15 @@ static void __devexit nv_remove(struct pci_dev *pci_dev)
        writel(np->orig_mac[1], base + NvRegMacAddrB);
        writel(readl(base + NvRegTransmitPoll) & ~NVREG_TRANSMITPOLL_MAC_ADDR_REV,
               base + NvRegTransmitPoll);
+}
+
+static void __devexit nv_remove(struct pci_dev *pci_dev)
+{
+       struct net_device *dev = pci_get_drvdata(pci_dev);
+
+       unregister_netdev(dev);
+
+       nv_restore_mac_addr(pci_dev);
 
        /* restore any phy related changes */
        nv_restore_phy(dev);
@@ -5975,6 +5983,8 @@ static void nv_shutdown(struct pci_dev *pdev)
        if (netif_running(dev))
                nv_close(dev);
 
+       nv_restore_mac_addr(pdev);
+
        pci_disable_device(pdev);
        if (system_state == SYSTEM_POWER_OFF) {
                if (pci_enable_wake(pdev, PCI_D3cold, np->wolenabled))
index 62071d9..d1dd5b4 100644 (file)
@@ -67,11 +67,10 @@ struct mlx4_mpt_entry {
 #define MLX4_MPT_FLAG_PHYSICAL     (1 <<  9)
 #define MLX4_MPT_FLAG_REGION       (1 <<  8)
 
-#define MLX4_MPT_PD_FLAG_FAST_REG   (1 << 26)
+#define MLX4_MPT_PD_FLAG_FAST_REG   (1 << 27)
+#define MLX4_MPT_PD_FLAG_RAE       (1 << 28)
 #define MLX4_MPT_PD_FLAG_EN_INV            (3 << 24)
 
-#define MLX4_MTT_FLAG_PRESENT          1
-
 #define MLX4_MPT_STATUS_SW             0xF0
 #define MLX4_MPT_STATUS_HW             0x00
 
@@ -348,7 +347,10 @@ int mlx4_mr_enable(struct mlx4_dev *dev, struct mlx4_mr *mr)
        if (mr->mtt.order >= 0 && mr->mtt.page_shift == 0) {
                /* fast register MR in free state */
                mpt_entry->flags    |= cpu_to_be32(MLX4_MPT_FLAG_FREE);
-               mpt_entry->pd_flags |= cpu_to_be32(MLX4_MPT_PD_FLAG_FAST_REG);
+               mpt_entry->pd_flags |= cpu_to_be32(MLX4_MPT_PD_FLAG_FAST_REG |
+                                                  MLX4_MPT_PD_FLAG_RAE);
+               mpt_entry->mtt_sz    = cpu_to_be32((1 << mr->mtt.order) *
+                                                  MLX4_MTT_ENTRY_PER_SEG);
        } else {
                mpt_entry->flags    |= cpu_to_be32(MLX4_MPT_FLAG_SW_OWNS);
        }
index f6c4528..87e37bc 100644 (file)
@@ -294,8 +294,6 @@ static int ath_stop(struct ath_softc *sc)
         * hardware is gone (invalid).
         */
 
-       if (!sc->sc_invalid)
-               ath9k_hw_set_interrupts(ah, 0);
        ath_draintxq(sc, false);
        if (!sc->sc_invalid) {
                ath_stoprecv(sc);
@@ -797,6 +795,12 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
        if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
                sc->sc_imask |= ATH9K_INT_CST;
 
+       /* Note: We disable MIB interrupts for now as we don't yet
+        * handle processing ANI, otherwise you will get an interrupt
+        * storm after about 7 hours of usage making the system unusable
+        * with huge latency. Once we do have ANI processing included
+        * we can re-enable this interrupt. */
+#if 0
        /*
         * Enable MIB interrupts when there are hardware phy counters.
         * Note we only do this (at the moment) for station mode.
@@ -804,6 +808,7 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
        if (ath9k_hw_phycounters(ah) &&
            ((sc->sc_opmode == ATH9K_M_STA) || (sc->sc_opmode == ATH9K_M_IBSS)))
                sc->sc_imask |= ATH9K_INT_MIB;
+#endif
        /*
         * Some hardware processes the TIM IE and fires an
         * interrupt when the TIM bit is set.  For hardware
@@ -1336,6 +1341,8 @@ void ath_deinit(struct ath_softc *sc)
 
        DPRINTF(sc, ATH_DBG_CONFIG, "%s\n", __func__);
 
+       tasklet_kill(&sc->intr_tq);
+       tasklet_kill(&sc->bcon_tasklet);
        ath_stop(sc);
        if (!sc->sc_invalid)
                ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
index 4ee695b..2f84093 100644 (file)
@@ -974,7 +974,6 @@ struct ath_softc {
        u32 sc_keymax;          /* size of key cache */
        DECLARE_BITMAP(sc_keymap, ATH_KEYMAX);  /* key use bit map */
        u8 sc_splitmic;         /* split TKIP MIC keys */
-       int sc_keytype;
 
        /* RX */
        struct list_head sc_rxbuf;
index 99badf1..acebdf1 100644 (file)
@@ -206,8 +206,6 @@ static int ath_key_config(struct ath_softc *sc,
        if (!ret)
                return -EIO;
 
-       if (mac)
-               sc->sc_keytype = hk.kv_type;
        return 0;
 }
 
@@ -778,7 +776,6 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
        case DISABLE_KEY:
                ath_key_delete(sc, key);
                clear_bit(key->keyidx, sc->sc_keymap);
-               sc->sc_keytype = ATH9K_CIPHER_CLR;
                break;
        default:
                ret = -EINVAL;
@@ -1414,10 +1411,17 @@ static void ath_pci_remove(struct pci_dev *pdev)
 {
        struct ieee80211_hw *hw = pci_get_drvdata(pdev);
        struct ath_softc *sc = hw->priv;
+       enum ath9k_int status;
 
-       if (pdev->irq)
+       if (pdev->irq) {
+               ath9k_hw_set_interrupts(sc->sc_ah, 0);
+               /* clear the ISR */
+               ath9k_hw_getisr(sc->sc_ah, &status);
+               sc->sc_invalid = 1;
                free_irq(pdev->irq, sc);
+       }
        ath_detach(sc);
+
        pci_iounmap(pdev, sc->mem);
        pci_release_region(pdev, 0);
        pci_disable_device(pdev);
index 550129f..8b332e1 100644 (file)
@@ -315,11 +315,11 @@ static int ath_tx_prepare(struct ath_softc *sc,
                txctl->keyix = tx_info->control.hw_key->hw_key_idx;
                txctl->frmlen += tx_info->control.icv_len;
 
-               if (sc->sc_keytype == ATH9K_CIPHER_WEP)
+               if (tx_info->control.hw_key->alg == ALG_WEP)
                        txctl->keytype = ATH9K_KEY_TYPE_WEP;
-               else if (sc->sc_keytype == ATH9K_CIPHER_TKIP)
+               else if (tx_info->control.hw_key->alg == ALG_TKIP)
                        txctl->keytype = ATH9K_KEY_TYPE_TKIP;
-               else if (sc->sc_keytype == ATH9K_CIPHER_AES_CCM)
+               else if (tx_info->control.hw_key->alg == ALG_CCMP)
                        txctl->keytype = ATH9K_KEY_TYPE_AES;
        }
 
index da8b743..a60ae86 100644 (file)
@@ -58,6 +58,7 @@ static struct usb_device_id usb_ids[] = {
        { USB_DEVICE(0x0586, 0x3407), .driver_info = DEVICE_ZD1211 },
        { USB_DEVICE(0x129b, 0x1666), .driver_info = DEVICE_ZD1211 },
        { USB_DEVICE(0x157e, 0x300a), .driver_info = DEVICE_ZD1211 },
+       { USB_DEVICE(0x0105, 0x145f), .driver_info = DEVICE_ZD1211 },
        /* ZD1211B */
        { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B },
        { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
index 9c71858..77baff0 100644 (file)
@@ -16,6 +16,7 @@
 
 
 #include <linux/kernel.h>
+#include <linux/sched.h>
 #include <linux/pci.h>
 #include <linux/stat.h>
 #include <linux/topology.h>
@@ -484,6 +485,21 @@ pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr,
 #endif /* HAVE_PCI_LEGACY */
 
 #ifdef HAVE_PCI_MMAP
+
+static int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma)
+{
+       unsigned long nr, start, size;
+
+       nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+       start = vma->vm_pgoff;
+       size = pci_resource_len(pdev, resno) >> PAGE_SHIFT;
+       if (start < size && size - start >= nr)
+               return 1;
+       WARN(1, "process \"%s\" tried to map 0x%08lx-0x%08lx on %s BAR %d (size 0x%08lx)\n",
+               current->comm, start, start+nr, pci_name(pdev), resno, size);
+       return 0;
+}
+
 /**
  * pci_mmap_resource - map a PCI resource into user memory space
  * @kobj: kobject for mapping
@@ -510,6 +526,9 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
        if (i >= PCI_ROM_RESOURCE)
                return -ENODEV;
 
+       if (!pci_mmap_fits(pdev, i, vma))
+               return -EINVAL;
+
        /* pci_mmap_page_range() expects the same kind of entry as coming
         * from /proc/bus/pci/ which is a "user visible" value. If this is
         * different from the resource itself, arch will do necessary fixup.
index 9a7c9e1..851f5b8 100644 (file)
@@ -527,7 +527,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
                 */
                pci_read_config_dword(child_dev, child_pos + PCI_EXP_DEVCAP,
                        &reg32);
-               if (!(reg32 & PCI_EXP_DEVCAP_RBER && !aspm_force)) {
+               if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) {
                        printk("Pre-1.1 PCIe device detected, "
                                "disable ASPM for %s. It can be enabled forcedly"
                                " with 'pcie_aspm=force'\n", pci_name(pdev));
index 3b3b5f1..4edfc47 100644 (file)
@@ -162,7 +162,7 @@ EXPORT_SYMBOL(pci_find_slot);
  * time.
  */
 struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device,
-                               const struct pci_dev *from)
+                               struct pci_dev *from)
 {
        struct pci_dev *pdev;
 
@@ -263,7 +263,7 @@ static int match_pci_dev_by_id(struct device *dev, void *data)
  * this file.
  */
 static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id,
-                                        const struct pci_dev *from)
+                                        struct pci_dev *from)
 {
        struct device *dev;
        struct device *dev_start = NULL;
@@ -303,7 +303,7 @@ static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id,
  */
 struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device,
                               unsigned int ss_vendor, unsigned int ss_device,
-                              const struct pci_dev *from)
+                              struct pci_dev *from)
 {
        struct pci_dev *pdev;
        struct pci_device_id *id;
index 4174d96..34c83d3 100644 (file)
@@ -427,6 +427,18 @@ static int pcmcia_device_probe(struct device * dev)
        p_drv = to_pcmcia_drv(dev->driver);
        s = p_dev->socket;
 
+       /* The PCMCIA code passes the match data in via dev->driver_data
+        * which is an ugly hack. Once the driver probe is called it may
+        * and often will overwrite the match data so we must save it first
+        *
+        * handle pseudo multifunction devices:
+        * there are at most two pseudo multifunction devices.
+        * if we're matching against the first, schedule a
+        * call which will then check whether there are two
+        * pseudo devices, and if not, add the second one.
+        */
+       did = p_dev->dev.driver_data;
+
        ds_dbg(1, "trying to bind %s to %s\n", p_dev->dev.bus_id,
               p_drv->drv.name);
 
@@ -455,21 +467,14 @@ static int pcmcia_device_probe(struct device * dev)
                goto put_module;
        }
 
-       /* handle pseudo multifunction devices:
-        * there are at most two pseudo multifunction devices.
-        * if we're matching against the first, schedule a
-        * call which will then check whether there are two
-        * pseudo devices, and if not, add the second one.
-        */
-       did = p_dev->dev.driver_data;
        if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) &&
            (p_dev->socket->device_count == 1) && (p_dev->device_no == 0))
                pcmcia_add_device_later(p_dev->socket, 0);
 
- put_module:
+put_module:
        if (ret)
                module_put(p_drv->owner);
- put_dev:
+put_dev:
        if (ret)
                put_device(dev);
        return (ret);
index f118252..52e2743 100644 (file)
@@ -422,6 +422,12 @@ done:
        return err;
 }
 
+static int rtc_dev_fasync(int fd, struct file *file, int on)
+{
+       struct rtc_device *rtc = file->private_data;
+       return fasync_helper(fd, file, on, &rtc->async_queue);
+}
+
 static int rtc_dev_release(struct inode *inode, struct file *file)
 {
        struct rtc_device *rtc = file->private_data;
@@ -434,16 +440,13 @@ static int rtc_dev_release(struct inode *inode, struct file *file)
        if (rtc->ops->release)
                rtc->ops->release(rtc->dev.parent);
 
+       if (file->f_flags & FASYNC)
+               rtc_dev_fasync(-1, file, 0);
+
        clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags);
        return 0;
 }
 
-static int rtc_dev_fasync(int fd, struct file *file, int on)
-{
-       struct rtc_device *rtc = file->private_data;
-       return fasync_helper(fd, file, on, &rtc->async_queue);
-}
-
 static const struct file_operations rtc_dev_fops = {
        .owner          = THIS_MODULE,
        .llseek         = no_llseek,
index e0ce65f..9a50f24 100644 (file)
@@ -113,7 +113,8 @@ ccwgroup_release (struct device *dev)
 
        for (i = 0; i < gdev->count; i++) {
                if (gdev->cdev[i]) {
-                       dev_set_drvdata(&gdev->cdev[i]->dev, NULL);
+                       if (dev_get_drvdata(&gdev->cdev[i]->dev) == gdev)
+                               dev_set_drvdata(&gdev->cdev[i]->dev, NULL);
                        put_device(&gdev->cdev[i]->dev);
                }
        }
@@ -296,6 +297,7 @@ error:
                        if (dev_get_drvdata(&gdev->cdev[i]->dev) == gdev)
                                dev_set_drvdata(&gdev->cdev[i]->dev, NULL);
                        put_device(&gdev->cdev[i]->dev);
+                       gdev->cdev[i] = NULL;
                }
        mutex_unlock(&gdev->reg_mutex);
        put_device(&gdev->dev);
index 5954b90..326f4cc 100644 (file)
@@ -174,6 +174,7 @@ cio_start_key (struct subchannel *sch,      /* subchannel structure */
        CIO_TRACE_EVENT(4, sch->dev.bus_id);
 
        orb = &to_io_private(sch)->orb;
+       memset(orb, 0, sizeof(union orb));
        /* sch is always under 2G. */
        orb->cmd.intparm = (u32)(addr_t)sch;
        orb->cmd.fmt = 1;
index 1679e2f..a0b6b46 100644 (file)
@@ -447,51 +447,36 @@ void qdio_print_subchannel_info(struct qdio_irq *irq_ptr,
 {
        char s[80];
 
-       sprintf(s, "%s sc:%x ", cdev->dev.bus_id, irq_ptr->schid.sch_no);
-
+       sprintf(s, "qdio: %s ", dev_name(&cdev->dev));
        switch (irq_ptr->qib.qfmt) {
        case QDIO_QETH_QFMT:
-               sprintf(s + strlen(s), "OSADE ");
+               sprintf(s + strlen(s), "OSA ");
                break;
        case QDIO_ZFCP_QFMT:
                sprintf(s + strlen(s), "ZFCP ");
                break;
        case QDIO_IQDIO_QFMT:
-               sprintf(s + strlen(s), "HiperSockets ");
+               sprintf(s + strlen(s), "HS ");
                break;
        }
-       sprintf(s + strlen(s), "using: ");
-
-       if (!is_thinint_irq(irq_ptr))
-               sprintf(s + strlen(s), "no");
-       sprintf(s + strlen(s), "AdapterInterrupts ");
-       if (!(irq_ptr->sch_token != 0))
-               sprintf(s + strlen(s), "no");
-       sprintf(s + strlen(s), "QEBSM ");
-       if (!(irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED))
-               sprintf(s + strlen(s), "no");
-       sprintf(s + strlen(s), "OutboundPCI ");
-       if (!css_general_characteristics.aif_tdd)
-               sprintf(s + strlen(s), "no");
-       sprintf(s + strlen(s), "TDD\n");
-       printk(KERN_INFO "qdio: %s", s);
-
-       memset(s, 0, sizeof(s));
-       sprintf(s, "%s SIGA required: ", cdev->dev.bus_id);
-       if (irq_ptr->siga_flag.input)
-               sprintf(s + strlen(s), "Read ");
-       if (irq_ptr->siga_flag.output)
-               sprintf(s + strlen(s), "Write ");
-       if (irq_ptr->siga_flag.sync)
-               sprintf(s + strlen(s), "Sync ");
-       if (!irq_ptr->siga_flag.no_sync_ti)
-               sprintf(s + strlen(s), "SyncAI ");
-       if (!irq_ptr->siga_flag.no_sync_out_ti)
-               sprintf(s + strlen(s), "SyncOutAI ");
-       if (!irq_ptr->siga_flag.no_sync_out_pci)
-               sprintf(s + strlen(s), "SyncOutPCI");
+       sprintf(s + strlen(s), "on SC %x using ", irq_ptr->schid.sch_no);
+       sprintf(s + strlen(s), "AI:%d ", is_thinint_irq(irq_ptr));
+       sprintf(s + strlen(s), "QEBSM:%d ", (irq_ptr->sch_token) ? 1 : 0);
+       sprintf(s + strlen(s), "PCI:%d ",
+               (irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED) ? 1 : 0);
+       sprintf(s + strlen(s), "TDD:%d ", css_general_characteristics.aif_tdd);
+       sprintf(s + strlen(s), "SIGA:");
+       sprintf(s + strlen(s), "%s", (irq_ptr->siga_flag.input) ? "R" : " ");
+       sprintf(s + strlen(s), "%s", (irq_ptr->siga_flag.output) ? "W" : " ");
+       sprintf(s + strlen(s), "%s", (irq_ptr->siga_flag.sync) ? "S" : " ");
+       sprintf(s + strlen(s), "%s",
+               (!irq_ptr->siga_flag.no_sync_ti) ? "A" : " ");
+       sprintf(s + strlen(s), "%s",
+               (!irq_ptr->siga_flag.no_sync_out_ti) ? "O" : " ");
+       sprintf(s + strlen(s), "%s",
+               (!irq_ptr->siga_flag.no_sync_out_pci) ? "P" : " ");
        sprintf(s + strlen(s), "\n");
-       printk(KERN_INFO "qdio: %s", s);
+       printk(KERN_INFO "%s", s);
 }
 
 int __init qdio_setup_init(void)
index 45a3b93..bf41887 100644 (file)
@@ -1834,7 +1834,6 @@ clear_risc_ints:
                WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_HOST_INT);
        }
        spin_unlock_irq(&ha->hardware_lock);
-       ha->isp_ops->enable_intrs(ha);
 
 fail:
        return ret;
index 26afe44..6d0f0e5 100644 (file)
@@ -1740,6 +1740,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        if (ret)
                goto probe_failed;
 
+       ha->isp_ops->enable_intrs(ha);
+
        scsi_scan_host(host);
 
        qla2x00_alloc_sysfs_attr(ha);
index 4a1cf63..9053508 100644 (file)
@@ -914,6 +914,7 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd,
                                ds[i].d_count = sg_dma_len(s);
                        }
                        sg_count -= n;
+                       sg = s;
                }
        } else {
                cmd->dataseg[0].d_base = 0;
index ff5d56b..62307bd 100644 (file)
@@ -852,7 +852,7 @@ static void scsi_end_bidi_request(struct scsi_cmnd *cmd)
 void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
 {
        int result = cmd->result;
-       int this_count = scsi_bufflen(cmd);
+       int this_count;
        struct request_queue *q = cmd->device->request_queue;
        struct request *req = cmd->request;
        int error = 0;
@@ -908,6 +908,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
         */
        if (scsi_end_request(cmd, error, good_bytes, result == 0) == NULL)
                return;
+       this_count = blk_rq_bytes(req);
 
        /* good_bytes = 0, or (inclusive) there were leftovers and
         * result = 0, so scsi_end_request couldn't retry.
index 3a6da80..61fb8b6 100644 (file)
@@ -131,7 +131,8 @@ struct atmel_uart_char {
 struct atmel_uart_port {
        struct uart_port        uart;           /* uart */
        struct clk              *clk;           /* uart clock */
-       unsigned short          suspended;      /* is port suspended? */
+       int                     may_wakeup;     /* cached value of device_may_wakeup for times we need to disable it */
+       u32                     backup_imr;     /* IMR saved during suspend */
        int                     break_active;   /* break being received */
 
        short                   use_dma_rx;     /* enable PDC receiver */
@@ -984,8 +985,15 @@ static void atmel_serial_pm(struct uart_port *port, unsigned int state,
                 * This is called on uart_open() or a resume event.
                 */
                clk_enable(atmel_port->clk);
+
+               /* re-enable interrupts if we disabled some on suspend */
+               UART_PUT_IER(port, atmel_port->backup_imr);
                break;
        case 3:
+               /* Back up the interrupt mask and disable all interrupts */
+               atmel_port->backup_imr = UART_GET_IMR(port);
+               UART_PUT_IDR(port, -1);
+
                /*
                 * Disable the peripheral clock for this serial port.
                 * This is called on uart_close() or a suspend event.
@@ -1475,13 +1483,12 @@ static int atmel_serial_suspend(struct platform_device *pdev,
                        cpu_relax();
        }
 
-       if (device_may_wakeup(&pdev->dev)
-           && !atmel_serial_clk_will_stop())
-               enable_irq_wake(port->irq);
-       else {
-               uart_suspend_port(&atmel_uart, port);
-               atmel_port->suspended = 1;
-       }
+       /* we can not wake up if we're running on slow clock */
+       atmel_port->may_wakeup = device_may_wakeup(&pdev->dev);
+       if (atmel_serial_clk_will_stop())
+               device_set_wakeup_enable(&pdev->dev, 0);
+
+       uart_suspend_port(&atmel_uart, port);
 
        return 0;
 }
@@ -1491,11 +1498,8 @@ static int atmel_serial_resume(struct platform_device *pdev)
        struct uart_port *port = platform_get_drvdata(pdev);
        struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
 
-       if (atmel_port->suspended) {
-               uart_resume_port(&atmel_uart, port);
-               atmel_port->suspended = 0;
-       } else
-               disable_irq_wake(port->irq);
+       uart_resume_port(&atmel_uart, port);
+       device_set_wakeup_enable(&pdev->dev, atmel_port->may_wakeup);
 
        return 0;
 }
@@ -1513,6 +1517,8 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev)
        BUILD_BUG_ON(!is_power_of_2(ATMEL_SERIAL_RINGSIZE));
 
        port = &atmel_ports[pdev->id];
+       port->backup_imr = 0;
+
        atmel_init_port(port, pdev);
 
        if (!atmel_use_dma_rx(&port->uart)) {
index c4eaacd..b872bfa 100644 (file)
@@ -427,7 +427,7 @@ static int orion_spi_transfer(struct spi_device *spi, struct spi_message *m)
                        goto msg_rejected;
                }
 
-               if (t->speed_hz < orion_spi->min_speed) {
+               if (t->speed_hz && t->speed_hz < orion_spi->min_speed) {
                        dev_err(&spi->dev,
                                "message rejected : "
                                "device min speed (%d Hz) exceeds "
index 0e53354..d47d363 100644 (file)
@@ -49,7 +49,7 @@ MODULE_ALIAS("platform:pxa2xx-spi");
 
 #define DMA_INT_MASK           (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
 #define RESET_DMA_CHANNEL      (DCSR_NODESC | DMA_INT_MASK)
-#define IS_DMA_ALIGNED(x)      (((x) & 0x07) == 0)
+#define IS_DMA_ALIGNED(x)      ((((u32)(x)) & 0x07) == 0)
 #define MAX_DMA_LEN            8191
 
 /*
@@ -896,7 +896,7 @@ static void pump_transfers(unsigned long data)
                                || transfer->rx_dma || transfer->tx_dma) {
                        dev_err(&drv_data->pdev->dev,
                                "pump_transfers: mapped transfer length "
-                               "of %lu is greater than %d\n",
+                               "of %u is greater than %d\n",
                                transfer->len, MAX_DMA_LEN);
                        message->status = -EINVAL;
                        giveback(drv_data);
index 87ab244..0ffabf5 100644 (file)
@@ -471,6 +471,7 @@ static int ssb_devices_register(struct ssb_bus *bus)
 #endif
                        break;
                case SSB_BUSTYPE_SSB:
+                       dev->dma_mask = &dev->coherent_dma_mask;
                        break;
                }
 
index 8abd4e5..8ab389d 100644 (file)
@@ -1876,7 +1876,8 @@ int usb_add_hcd(struct usb_hcd *hcd,
                 * with IRQF_SHARED. As usb_hcd_irq() will always disable
                 * interrupts we can remove it here.
                 */
-               irqflags &= ~IRQF_DISABLED;
+               if (irqflags & IRQF_SHARED)
+                       irqflags &= ~IRQF_DISABLED;
 
                snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d",
                                hcd->driver->description, hcd->self.busnum);
index 6a5cb01..d999638 100644 (file)
@@ -2683,35 +2683,17 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                                USB_PORT_STAT_C_ENABLE);
 #endif
 
-       /* Try to use the debounce delay for protection against
-        * port-enable changes caused, for example, by EMI.
-        */
-       if (portchange & (USB_PORT_STAT_C_CONNECTION |
-                               USB_PORT_STAT_C_ENABLE)) {
-               status = hub_port_debounce(hub, port1);
-               if (status < 0) {
-                       if (printk_ratelimit())
-                               dev_err (hub_dev, "connect-debounce failed, "
-                                               "port %d disabled\n", port1);
-                       portstatus &= ~USB_PORT_STAT_CONNECTION;
-               } else {
-                       portstatus = status;
-               }
-       }
-
        /* Try to resuscitate an existing device */
        udev = hdev->children[port1-1];
        if ((portstatus & USB_PORT_STAT_CONNECTION) && udev &&
                        udev->state != USB_STATE_NOTATTACHED) {
-
                usb_lock_device(udev);
                if (portstatus & USB_PORT_STAT_ENABLE) {
                        status = 0;             /* Nothing to do */
-               } else if (!udev->persist_enabled) {
-                       status = -ENODEV;       /* Mustn't resuscitate */
 
 #ifdef CONFIG_USB_SUSPEND
-               } else if (udev->state == USB_STATE_SUSPENDED) {
+               } else if (udev->state == USB_STATE_SUSPENDED &&
+                               udev->persist_enabled) {
                        /* For a suspended device, treat this as a
                         * remote wakeup event.
                         */
@@ -2726,7 +2708,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
 #endif
 
                } else {
-                       status = usb_reset_device(udev);
+                       status = -ENODEV;       /* Don't resuscitate */
                }
                usb_unlock_device(udev);
 
@@ -2741,6 +2723,19 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                usb_disconnect(&hdev->children[port1-1]);
        clear_bit(port1, hub->change_bits);
 
+       if (portchange & (USB_PORT_STAT_C_CONNECTION |
+                               USB_PORT_STAT_C_ENABLE)) {
+               status = hub_port_debounce(hub, port1);
+               if (status < 0) {
+                       if (printk_ratelimit())
+                               dev_err(hub_dev, "connect-debounce failed, "
+                                               "port %d disabled\n", port1);
+                       portstatus &= ~USB_PORT_STAT_CONNECTION;
+               } else {
+                       portstatus = status;
+               }
+       }
+
        /* Return now if debouncing failed or nothing is connected */
        if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
 
@@ -2748,7 +2743,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2
                                && !(portstatus & (1 << USB_PORT_FEAT_POWER)))
                        set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
+
                if (portstatus & USB_PORT_STAT_ENABLE)
                        goto done;
                return;
index 1cfccf1..45ad556 100644 (file)
@@ -223,7 +223,7 @@ static int dr_controller_setup(struct fsl_udc *udc)
        fsl_writel(tmp, &dr_regs->endpointlistaddr);
 
        VDBG("vir[qh_base] is %p phy[qh_base] is 0x%8x reg is 0x%8x",
-               (int)udc->ep_qh, (int)tmp,
+               udc->ep_qh, (int)tmp,
                fsl_readl(&dr_regs->endpointlistaddr));
 
        /* Config PHY interface */
index 574c538..bb54cca 100644 (file)
@@ -787,7 +787,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel)
                        omap_set_dma_dest_params(ep->lch,
                                OMAP_DMA_PORT_TIPB,
                                OMAP_DMA_AMODE_CONSTANT,
-                               (unsigned long) io_v2p(UDC_DATA_DMA),
+                               UDC_DATA_DMA,
                                0, 0);
                }
        } else {
@@ -804,7 +804,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel)
                        omap_set_dma_src_params(ep->lch,
                                OMAP_DMA_PORT_TIPB,
                                OMAP_DMA_AMODE_CONSTANT,
-                               (unsigned long) io_v2p(UDC_DATA_DMA),
+                               UDC_DATA_DMA,
                                0, 0);
                        /* EMIFF or SDRC */
                        omap_set_dma_dest_burst_mode(ep->lch,
index d9d53f2..8409e07 100644 (file)
@@ -145,16 +145,6 @@ static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
        return -ETIMEDOUT;
 }
 
-static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr,
-                                      u32 mask, u32 done, int usec)
-{
-       int error = handshake(ehci, ptr, mask, done, usec);
-       if (error)
-               ehci_to_hcd(ehci)->state = HC_STATE_HALT;
-
-       return error;
-}
-
 /* force HC to halt state from unknown (EHCI spec section 2.3) */
 static int ehci_halt (struct ehci_hcd *ehci)
 {
@@ -173,6 +163,22 @@ static int ehci_halt (struct ehci_hcd *ehci)
                          STS_HALT, STS_HALT, 16 * 125);
 }
 
+static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr,
+                                      u32 mask, u32 done, int usec)
+{
+       int error;
+
+       error = handshake(ehci, ptr, mask, done, usec);
+       if (error) {
+               ehci_halt(ehci);
+               ehci_to_hcd(ehci)->state = HC_STATE_HALT;
+               ehci_err(ehci, "force halt; handhake %p %08x %08x -> %d\n",
+                       ptr, mask, done, error);
+       }
+
+       return error;
+}
+
 /* put TDI/ARC silicon into EHCI mode */
 static void tdi_reset (struct ehci_hcd *ehci)
 {
index b7853c8..4a0c5a7 100644 (file)
@@ -437,6 +437,9 @@ static int enable_periodic (struct ehci_hcd *ehci)
        u32     cmd;
        int     status;
 
+       if (ehci->periodic_sched++)
+               return 0;
+
        /* did clearing PSE did take effect yet?
         * takes effect only at frame boundaries...
         */
@@ -461,6 +464,9 @@ static int disable_periodic (struct ehci_hcd *ehci)
        u32     cmd;
        int     status;
 
+       if (--ehci->periodic_sched)
+               return 0;
+
        /* did setting PSE not take effect yet?
         * takes effect only at frame boundaries...
         */
@@ -544,13 +550,10 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
                : (qh->usecs * 8);
 
        /* maybe enable periodic schedule processing */
-       if (!ehci->periodic_sched++)
-               return enable_periodic (ehci);
-
-       return 0;
+       return enable_periodic(ehci);
 }
 
-static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
+static int qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)
 {
        unsigned        i;
        unsigned        period;
@@ -586,9 +589,7 @@ static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
        qh_put (qh);
 
        /* maybe turn off periodic schedule */
-       ehci->periodic_sched--;
-       if (!ehci->periodic_sched)
-               (void) disable_periodic (ehci);
+       return disable_periodic(ehci);
 }
 
 static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
@@ -1562,9 +1563,7 @@ itd_link_urb (
        urb->hcpriv = NULL;
 
        timer_action (ehci, TIMER_IO_WATCHDOG);
-       if (unlikely (!ehci->periodic_sched++))
-               return enable_periodic (ehci);
-       return 0;
+       return enable_periodic(ehci);
 }
 
 #define        ISO_ERRS (EHCI_ISOC_BUF_ERR | EHCI_ISOC_BABBLE | EHCI_ISOC_XACTERR)
@@ -1642,7 +1641,7 @@ itd_complete (
        ehci_urb_done(ehci, urb, 0);
        retval = true;
        urb = NULL;
-       ehci->periodic_sched--;
+       (void) disable_periodic(ehci);
        ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
 
        if (unlikely (list_empty (&stream->td_list))) {
@@ -1951,9 +1950,7 @@ sitd_link_urb (
        urb->hcpriv = NULL;
 
        timer_action (ehci, TIMER_IO_WATCHDOG);
-       if (!ehci->periodic_sched++)
-               return enable_periodic (ehci);
-       return 0;
+       return enable_periodic(ehci);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -2019,7 +2016,7 @@ sitd_complete (
        ehci_urb_done(ehci, urb, 0);
        retval = true;
        urb = NULL;
-       ehci->periodic_sched--;
+       (void) disable_periodic(ehci);
        ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
 
        if (list_empty (&stream->td_list)) {
@@ -2243,8 +2240,7 @@ restart:
                        if (unlikely (modified)) {
                                if (likely(ehci->periodic_sched > 0))
                                        goto restart;
-                               /* maybe we can short-circuit this scan! */
-                               disable_periodic(ehci);
+                               /* short-circuit this scan */
                                now_uframe = clock;
                                break;
                        }
index a001748..58b2b8f 100644 (file)
@@ -9,6 +9,7 @@ comment "Enable Host or Gadget support to see Inventra options"
 # (M)HDRC = (Multipoint) Highspeed Dual-Role Controller
 config USB_MUSB_HDRC
        depends on (USB || USB_GADGET) && HAVE_CLK
+       depends on !SUPERH
        select TWL4030_USB if MACH_OMAP_3430SDP
        tristate 'Inventra Highspeed Dual Role Controller (TI, ...)'
        help
index c5b8f02..128e949 100644 (file)
 #include <linux/io.h>
 
 #ifdef CONFIG_ARM
-#include <asm/arch/hardware.h>
-#include <asm/arch/memory.h>
+#include <mach/hardware.h>
+#include <mach/memory.h>
 #include <asm/mach-types.h>
 #endif
 
index 298b22e..9d2dcb1 100644 (file)
@@ -35,8 +35,8 @@
 #include <linux/io.h>
 
 #include <asm/mach-types.h>
-#include <asm/arch/hardware.h>
-#include <asm/arch/mux.h>
+#include <mach/hardware.h>
+#include <mach/mux.h>
 
 #include "musb_core.h"
 #include "omap2430.h"
index 786a620..dc76707 100644 (file)
@@ -11,8 +11,8 @@
 #define __MUSB_OMAP243X_H__
 
 #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
-#include <asm/arch/hardware.h>
-#include <asm/arch/usb.h>
+#include <mach/hardware.h>
+#include <mach/usb.h>
 
 /*
  * OMAP2430-specific definitions
index 442cba6..1279553 100644 (file)
@@ -72,6 +72,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */
        { USB_DEVICE(0x10C4, 0x80DD) }, /* Tracient RFID */
        { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */
+       { USB_DEVICE(0x10C4, 0x8115) }, /* Arygon NFC/Mifare Reader */
        { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */
        { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
        { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
@@ -83,6 +84,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */
        { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
        { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */
+       { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
        { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
@@ -93,6 +95,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */
        { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */
        { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
+       { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
        { } /* Terminating Entry */
 };
 
index 984f6ef..3dc93b5 100644 (file)
@@ -654,6 +654,9 @@ static struct usb_device_id id_table_combined [] = {
                .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
        { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
        { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) },
+       { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) },
        { },                                    /* Optional parameter entry */
        { }                                     /* Terminating entry */
 };
index 382265b..8a5b6df 100644 (file)
 
 #define PAPOUCH_VID                    0x5050  /* Vendor ID */
 #define PAPOUCH_TMU_PID                        0x0400  /* TMU USB Thermometer */
+#define PAPOUCH_QUIDO4x4_PID           0x0900  /* Quido 4/4 Module */
 
 /*
  * ACG Identification Technologies GmbH products (http://www.acg.de/).
 /* Rig Expert Ukraine devices */
 #define FTDI_REU_TINY_PID              0xED22  /* RigExpert Tiny */
 
+/* Domintell products  http://www.domintell.com */
+#define FTDI_DOMINTELL_DGQG_PID        0xEF50  /* Master */
+#define FTDI_DOMINTELL_DUSB_PID        0xEF51  /* DUSB01 module */
+
 /* Commands */
 #define FTDI_SIO_RESET                 0 /* Reset the port */
 #define FTDI_SIO_MODEM_CTRL    1 /* Set the modem control register */
index 9f9cd36..73f8277 100644 (file)
@@ -218,6 +218,7 @@ static int  option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
 /* ZTE PRODUCTS */
 #define ZTE_VENDOR_ID                          0x19d2
 #define ZTE_PRODUCT_MF628                      0x0015
+#define ZTE_PRODUCT_CDMA_TECH                  0xfffe
 
 static struct usb_device_id option_ids[] = {
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
@@ -347,6 +348,7 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */
        { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
        { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) },
+       { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) },
        { } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
index 7060337..ea1a103 100644 (file)
@@ -14,7 +14,7 @@
   Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org>
 */
 
-#define DRIVER_VERSION "v.1.2.13a"
+#define DRIVER_VERSION "v.1.3.2"
 #define DRIVER_AUTHOR "Kevin Lloyd <klloyd@sierrawireless.com>"
 #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems"
 
@@ -30,9 +30,6 @@
 
 #define SWIMS_USB_REQUEST_SetPower     0x00
 #define SWIMS_USB_REQUEST_SetNmea      0x07
-#define SWIMS_USB_REQUEST_SetMode      0x0B
-#define SWIMS_USB_REQUEST_GetSwocInfo  0x0A
-#define SWIMS_SET_MODE_Modem           0x0001
 
 /* per port private data */
 #define N_IN_URB       4
@@ -163,7 +160,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */
        { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */
        { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
-       { USB_DEVICE(0x0f30, 0x1b1d) }, /* Sierra Wireless MC5720 */
+       { USB_DEVICE(0x03f0, 0x1b1d) }, /* HP ev2200 a.k.a MC5720 */
        { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
        { USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */
        { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */
@@ -175,6 +172,8 @@ static struct usb_device_id id_table [] = {
         /* Sierra Wireless Device */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) },
        { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless Device */
+       { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless Device */
+       { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless Device */
 
        { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
        { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
@@ -187,6 +186,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */
        { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */
        { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */
+       { USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */
        { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */
        { USB_DEVICE(0x1199, 0x683C) }, /* Sierra Wireless MC8790 */
        { USB_DEVICE(0x1199, 0x683D) }, /* Sierra Wireless MC8790 */
@@ -204,6 +204,8 @@ static struct usb_device_id id_table [] = {
        /* Sierra Wireless Device */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)},
        /* Sierra Wireless Device */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6891, 0xFF, 0xFF, 0xFF)},
+       /* Sierra Wireless Device */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},
 
        { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
index e39c779..9a3e495 100644 (file)
@@ -1744,7 +1744,7 @@ static int ti_download_firmware(struct ti_device *tdev, int type)
        if (buffer) {
                memcpy(buffer, fw_p->data, fw_p->size);
                memset(buffer + fw_p->size, 0xff, buffer_size - fw_p->size);
-               ti_do_download(dev, pipe, buffer, fw_p->size);
+               status = ti_do_download(dev, pipe, buffer, fw_p->size);
                kfree(buffer);
        }
        release_firmware(fw_p);
index b157c48..4f7f9e3 100644 (file)
@@ -733,7 +733,9 @@ int usb_serial_probe(struct usb_interface *interface,
            ((le16_to_cpu(dev->descriptor.idVendor) == ATEN_VENDOR_ID) &&
             (le16_to_cpu(dev->descriptor.idProduct) == ATEN_PRODUCT_ID)) ||
            ((le16_to_cpu(dev->descriptor.idVendor) == ALCOR_VENDOR_ID) &&
-            (le16_to_cpu(dev->descriptor.idProduct) == ALCOR_PRODUCT_ID))) {
+            (le16_to_cpu(dev->descriptor.idProduct) == ALCOR_PRODUCT_ID)) ||
+           ((le16_to_cpu(dev->descriptor.idVendor) == SIEMENS_VENDOR_ID) &&
+            (le16_to_cpu(dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_EF81))) {
                if (interface != dev->actconfig->interface[0]) {
                        /* check out the endpoints of the other interface*/
                        iface_desc = dev->actconfig->interface[0]->cur_altsetting;
index c760346..3d92496 100644 (file)
@@ -146,18 +146,6 @@ config USB_STORAGE_KARMA
          on the resulting scsi device node returns the Karma to normal
          operation.
 
-config USB_STORAGE_SIERRA
-       bool "Sierra Wireless TRU-Install Feature Support"
-       depends on USB_STORAGE
-       help
-         Say Y here to include additional code to support Sierra Wireless
-         products with the TRU-Install feature (e.g., AC597E, AC881U).
-
-         This code switches the Sierra Wireless device from being in
-         Mass Storage mode to Modem mode. It also has the ability to
-         support host software upgrades should full Linux support be added
-         to TRU-Install.
-
 config USB_STORAGE_CYPRESS_ATACB
        bool "SAT emulation on Cypress USB/ATA Bridge with ATACB"
        depends on USB_STORAGE
index bc3415b..7f8beb5 100644 (file)
@@ -21,11 +21,10 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT)      += jumpshot.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_ALAUDA)   += alauda.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_KARMA)    += karma.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_SIERRA)   += sierra_ms.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += cypress_atacb.o
 
 usb-storage-objs :=    scsiglue.o protocol.o transport.o usb.o \
-                       initializers.o $(usb-storage-obj-y)
+                       initializers.o sierra_ms.o $(usb-storage-obj-y)
 
 ifneq ($(CONFIG_USB_LIBUSUAL),)
        obj-$(CONFIG_USB)       += libusual.o
index ba412e6..cd15547 100644 (file)
@@ -160,6 +160,13 @@ UNUSUAL_DEV(  0x0421, 0x0019, 0x0592, 0x0592,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_MAX_SECTORS_64 ),
 
+/* Reported by Filip Joelsson <filip@blueturtle.nu> */
+UNUSUAL_DEV(  0x0421, 0x005d, 0x0001, 0x0600,
+               "Nokia",
+               "Nokia 3110c",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_FIX_CAPACITY ),
+
 /* Reported by Mario Rettig <mariorettig@web.de> */
 UNUSUAL_DEV(  0x0421, 0x042e, 0x0100, 0x0100,
                "Nokia",
@@ -232,6 +239,20 @@ UNUSUAL_DEV(  0x0421, 0x04b9, 0x0551, 0x0551,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_CAPACITY ),
 
+/* Reported by Richard Nauber <RichardNauber@web.de> */
+UNUSUAL_DEV(  0x0421, 0x04fa, 0x0601, 0x0601,
+               "Nokia",
+               "6300",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_FIX_CAPACITY ),
+
+/* Patch for Nokia 5310 capacity */
+UNUSUAL_DEV(  0x0421, 0x006a, 0x0000, 0x0591,
+       "Nokia",
+       "5310",
+       US_SC_DEVICE, US_PR_DEVICE, NULL,
+       US_FL_FIX_CAPACITY ),
+
 /* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */
 UNUSUAL_DEV(  0x0424, 0x0fdc, 0x0210, 0x0210,
                "SMSC",
@@ -987,6 +1008,13 @@ UNUSUAL_DEV(  0x069b, 0x3004, 0x0001, 0x0001,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_CAPACITY ),
 
+/* Reported by Adrian Pilchowiec <adi1981@epf.pl> */
+UNUSUAL_DEV(  0x071b, 0x3203, 0x0000, 0x0000,
+               "RockChip",
+               "MP3",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_NO_WP_DETECT | US_FL_MAX_SECTORS_64),
+
 /* Reported by Massimiliano Ghilardi <massimiliano.ghilardi@gmail.com>
  * This USB MP3/AVI player device fails and disconnects if more than 128
  * sectors (64kB) are read/written in a single command, and may be present
@@ -1576,7 +1604,6 @@ UNUSUAL_DEV(  0x10d6, 0x2200, 0x0100, 0x0100,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                0),
 
-#ifdef CONFIG_USB_STORAGE_SIERRA
 /* Reported by Kevin Lloyd <linux@sierrawireless.com>
  * Entry is needed for the initializer function override,
  * which instructs the device to load as a modem
@@ -1587,7 +1614,6 @@ UNUSUAL_DEV(  0x1199, 0x0fff, 0x0000, 0x9999,
                "USB MMC Storage",
                US_SC_DEVICE, US_PR_DEVICE, sierra_ms_init,
                0),
-#endif
 
 /* Reported by Jaco Kroon <jaco@kroon.co.za>
  * The usb-storage module found on the Digitech GNX4 (and supposedly other
index 73679aa..27016fd 100644 (file)
 #ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB
 #include "cypress_atacb.h"
 #endif
-#ifdef CONFIG_USB_STORAGE_SIERRA
 #include "sierra_ms.h"
-#endif
 
 /* Some informational data */
 MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>");
index c6299e8..9cbff84 100644 (file)
@@ -2400,11 +2400,15 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
 
        if (!fbcon_is_inactive(vc, info)) {
                if (ops->blank_state != blank) {
+                       int ret = 1;
+
                        ops->blank_state = blank;
                        fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
                        ops->cursor_flash = (!blank);
 
-                       if (fb_blank(info, blank))
+                       if (info->fbops->fb_blank)
+                               ret = info->fbops->fb_blank(blank, info);
+                       if (ret)
                                fbcon_generic_blank(vc, info, blank);
                }
 
index a6e38e9..89a3468 100644 (file)
@@ -110,7 +110,7 @@ static inline int mono_col(const struct fb_info *info)
        __u32 max_len;
        max_len = max(info->var.green.length, info->var.red.length);
        max_len = max(info->var.blue.length, max_len);
-       return ~(0xfff << (max_len & 0xff));
+       return (~(0xfff << max_len)) & 0xff;
 }
 
 static inline int attr_col_ec(int shift, struct vc_data *vc,
index 614a5c7..6799a6d 100644 (file)
@@ -130,8 +130,8 @@ static ssize_t geodewdt_write(struct file *file, const char __user *data,
        return len;
 }
 
-static int geodewdt_ioctl(struct inode *inode, struct file *file,
-                               unsigned int cmd, unsigned long arg)
+static long geodewdt_ioctl(struct file *file, unsigned int cmd,
+                               unsigned long arg)
 {
        void __user *argp = (void __user *)arg;
        int __user *p = argp;
@@ -198,7 +198,7 @@ static const struct file_operations geodewdt_fops = {
        .owner          = THIS_MODULE,
        .llseek         = no_llseek,
        .write          = geodewdt_write,
-       .ioctl          = geodewdt_ioctl,
+       .unlocked_ioctl = geodewdt_ioctl,
        .open           = geodewdt_open,
        .release        = geodewdt_release,
 };
index b82405c..89fcefc 100644 (file)
@@ -85,7 +85,6 @@ static void __asr_toggle(void)
 
        outb(reg & ~asr_toggle_mask, asr_write_addr);
        reg = inb(asr_read_addr);
-       spin_unlock(&asr_lock);
 }
 
 static void asr_toggle(void)
index 0ed8416..6d9f3d4 100644 (file)
@@ -173,8 +173,8 @@ static const struct watchdog_info ident = {
        .identity = "PNX4008 Watchdog",
 };
 
-static long pnx4008_wdt_ioctl(struct inode *inode, struct file *file,
-                                       unsigned int cmd, unsigned long arg)
+static long pnx4008_wdt_ioctl(struct file *file, unsigned int cmd,
+                               unsigned long arg)
 {
        int ret = -ENOTTY;
        int time;
index 6756bcb..c9c73b6 100644 (file)
@@ -182,8 +182,8 @@ static ssize_t rc32434_wdt_write(struct file *file, const char *data,
        return 0;
 }
 
-static int rc32434_wdt_ioctl(struct inode *inode, struct file *file,
-       unsigned int cmd, unsigned long arg)
+static long rc32434_wdt_ioctl(struct file *file, unsigned int cmd,
+                               unsigned long arg)
 {
        void __user *argp = (void __user *)arg;
        int new_timeout;
@@ -242,7 +242,7 @@ static struct file_operations rc32434_wdt_fops = {
        .owner          = THIS_MODULE,
        .llseek         = no_llseek,
        .write          = rc32434_wdt_write,
-       .ioctl          = rc32434_wdt_ioctl,
+       .unlocked_ioctl = rc32434_wdt_ioctl,
        .open           = rc32434_wdt_open,
        .release        = rc32434_wdt_release,
 };
index 9108efa..bf92802 100644 (file)
@@ -144,8 +144,8 @@ static int rdc321x_wdt_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static int rdc321x_wdt_ioctl(struct inode *inode, struct file *file,
-                               unsigned int cmd, unsigned long arg)
+static long rdc321x_wdt_ioctl(struct file *file, unsigned int cmd,
+                               unsigned long arg)
 {
        void __user *argp = (void __user *)arg;
        unsigned int value;
@@ -204,7 +204,7 @@ static ssize_t rdc321x_wdt_write(struct file *file, const char __user *buf,
 static const struct file_operations rdc321x_wdt_fops = {
        .owner          = THIS_MODULE,
        .llseek         = no_llseek,
-       .ioctl          = rdc321x_wdt_ioctl,
+       .unlocked_ioctl = rdc321x_wdt_ioctl,
        .open           = rdc321x_wdt_open,
        .write          = rdc321x_wdt_write,
        .release        = rdc321x_wdt_release,
index db362c3..191ea63 100644 (file)
@@ -115,8 +115,8 @@ static int watchdog_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static ssize_t watchdog_write(struct file *file, const char *data,
-                                               size_t len, loff_t *ppos)
+static ssize_t watchdog_write(struct file *file, const char __user *data,
+                             size_t len, loff_t *ppos)
 {
        /*
         *      Refresh the timer.
@@ -133,21 +133,22 @@ static const struct watchdog_info ident = {
 };
 
 static long watchdog_ioctl(struct file *file, unsigned int cmd,
-                                                       unsigned long arg)
+                          unsigned long arg)
 {
        unsigned int new_margin;
+       int __user *int_arg = (int __user *)arg;
        int ret = -ENOTTY;
 
        switch (cmd) {
        case WDIOC_GETSUPPORT:
                ret = 0;
-               if (copy_to_user((void *)arg, &ident, sizeof(ident)))
+               if (copy_to_user((void __user *)arg, &ident, sizeof(ident)))
                        ret = -EFAULT;
                break;
 
        case WDIOC_GETSTATUS:
        case WDIOC_GETBOOTSTATUS:
-               ret = put_user(0, (int *)arg);
+               ret = put_user(0, int_arg);
                break;
 
        case WDIOC_KEEPALIVE:
@@ -156,7 +157,7 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd,
                break;
 
        case WDIOC_SETTIMEOUT:
-               ret = get_user(new_margin, (int *)arg);
+               ret = get_user(new_margin, int_arg);
                if (ret)
                        break;
 
@@ -171,7 +172,7 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd,
                watchdog_ping();
                /* Fall */
        case WDIOC_GETTIMEOUT:
-               ret = put_user(soft_margin, (int *)arg);
+               ret = put_user(soft_margin, int_arg);
                break;
        }
        return ret;
index c95295c..e83aa5e 100644 (file)
@@ -626,8 +626,7 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
        return NULL;
 
 error:
-       if (fid)
-               p9_client_clunk(fid);
+       p9_client_clunk(fid);
 
        return ERR_PTR(result);
 }
index 80e9395..e7a1a99 100644 (file)
@@ -1395,6 +1395,10 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name)
                if (dentry->d_parent != parent)
                        goto next;
 
+               /* non-existing due to RCU? */
+               if (d_unhashed(dentry))
+                       goto next;
+
                /*
                 * It is safe to compare names since d_move() cannot
                 * change the qstr (protected by d_lock).
@@ -1410,10 +1414,8 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name)
                                goto next;
                }
 
-               if (!d_unhashed(dentry)) {
-                       atomic_inc(&dentry->d_count);
-                       found = dentry;
-               }
+               atomic_inc(&dentry->d_count);
+               found = dentry;
                spin_unlock(&dentry->d_lock);
                break;
 next:
index 32993be..cecee50 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -752,11 +752,11 @@ static int exec_mmap(struct mm_struct *mm)
        tsk->active_mm = mm;
        activate_mm(active_mm, mm);
        task_unlock(tsk);
-       mm_update_next_owner(old_mm);
        arch_pick_mmap_layout(mm);
        if (old_mm) {
                up_read(&old_mm->mmap_sem);
                BUG_ON(active_mm != old_mm);
+               mm_update_next_owner(old_mm);
                mmput(old_mm);
                return 0;
        }
index 6024942..d85c7d9 100644 (file)
@@ -323,7 +323,7 @@ out:
 }
 
 /*
- * remove_kevent - cleans up and ultimately frees the given kevent
+ * remove_kevent - cleans up the given kevent
  *
  * Caller must hold dev->ev_mutex.
  */
@@ -334,7 +334,13 @@ static void remove_kevent(struct inotify_device *dev,
 
        dev->event_count--;
        dev->queue_size -= sizeof(struct inotify_event) + kevent->event.len;
+}
 
+/*
+ * free_kevent - frees the given kevent.
+ */
+static void free_kevent(struct inotify_kernel_event *kevent)
+{
        kfree(kevent->name);
        kmem_cache_free(event_cachep, kevent);
 }
@@ -350,6 +356,7 @@ static void inotify_dev_event_dequeue(struct inotify_device *dev)
                struct inotify_kernel_event *kevent;
                kevent = inotify_dev_get_event(dev);
                remove_kevent(dev, kevent);
+               free_kevent(kevent);
        }
 }
 
@@ -433,17 +440,15 @@ static ssize_t inotify_read(struct file *file, char __user *buf,
        dev = file->private_data;
 
        while (1) {
-               int events;
 
                prepare_to_wait(&dev->wq, &wait, TASK_INTERRUPTIBLE);
 
                mutex_lock(&dev->ev_mutex);
-               events = !list_empty(&dev->events);
-               mutex_unlock(&dev->ev_mutex);
-               if (events) {
+               if (!list_empty(&dev->events)) {
                        ret = 0;
                        break;
                }
+               mutex_unlock(&dev->ev_mutex);
 
                if (file->f_flags & O_NONBLOCK) {
                        ret = -EAGAIN;
@@ -462,7 +467,6 @@ static ssize_t inotify_read(struct file *file, char __user *buf,
        if (ret)
                return ret;
 
-       mutex_lock(&dev->ev_mutex);
        while (1) {
                struct inotify_kernel_event *kevent;
 
@@ -481,6 +485,13 @@ static ssize_t inotify_read(struct file *file, char __user *buf,
                        }
                        break;
                }
+               remove_kevent(dev, kevent);
+
+               /*
+                * Must perform the copy_to_user outside the mutex in order
+                * to avoid a lock order reversal with mmap_sem.
+                */
+               mutex_unlock(&dev->ev_mutex);
 
                if (copy_to_user(buf, &kevent->event, event_size)) {
                        ret = -EFAULT;
@@ -498,7 +509,9 @@ static ssize_t inotify_read(struct file *file, char __user *buf,
                        count -= kevent->event.len;
                }
 
-               remove_kevent(dev, kevent);
+               free_kevent(kevent);
+
+               mutex_lock(&dev->ev_mutex);
        }
        mutex_unlock(&dev->ev_mutex);
 
index 52312ec..5145cb9 100644 (file)
@@ -58,7 +58,7 @@ const struct inode_operations ramfs_file_inode_operations = {
  * size 0 on the assumption that it's going to be used for an mmap of shared
  * memory
  */
-static int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)
+int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)
 {
        struct pagevec lru_pvec;
        unsigned long npages, xpages, loop, limit;
index 1bbc6f4..a1e701c 100644 (file)
@@ -898,6 +898,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
        if (unlikely(!(out->f_mode & FMODE_WRITE)))
                return -EBADF;
 
+       if (unlikely(out->f_flags & O_APPEND))
+               return -EINVAL;
+
        ret = rw_verify_area(WRITE, out, ppos, len);
        if (unlikely(ret < 0))
                return ret;
index b9cb774..d7f7645 100644 (file)
@@ -538,7 +538,7 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node)
                printk(KERN_DEBUG "\t%d orphan inode numbers:\n", n);
                for (i = 0; i < n; i++)
                        printk(KERN_DEBUG "\t  ino %llu\n",
-                              le64_to_cpu(orph->inos[i]));
+                              (unsigned long long)le64_to_cpu(orph->inos[i]));
                break;
        }
        default:
index 2b267c9..526c01e 100644 (file)
@@ -426,7 +426,7 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
 
        while (1) {
                dbg_gen("feed '%s', ino %llu, new f_pos %#x",
-                       dent->name, le64_to_cpu(dent->inum),
+                       dent->name, (unsigned long long)le64_to_cpu(dent->inum),
                        key_hash_flash(c, &dent->key));
                ubifs_assert(dent->ch.sqnum > ubifs_inode(dir)->creat_sqnum);
 
index e045c8b..47814cd 100644 (file)
@@ -507,7 +507,6 @@ int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *free,
                rsvd_idx_lebs = 0;
        lebs = c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt -
               c->lst.taken_empty_lebs;
-       ubifs_assert(lebs + c->lst.idx_lebs >= c->min_idx_lebs);
        if (rsvd_idx_lebs < lebs)
                /*
                 * OK to allocate an empty LEB, but we still don't want to go
index 13f1019..02aba36 100644 (file)
@@ -334,15 +334,15 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp)
 
                err = move_nodes(c, sleb);
                if (err)
-                       goto out;
+                       goto out_inc_seq;
 
                err = gc_sync_wbufs(c);
                if (err)
-                       goto out;
+                       goto out_inc_seq;
 
                err = ubifs_change_one_lp(c, lnum, c->leb_size, 0, 0, 0, 0);
                if (err)
-                       goto out;
+                       goto out_inc_seq;
 
                /* Allow for races with TNC */
                c->gced_lnum = lnum;
@@ -369,6 +369,14 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp)
 out:
        ubifs_scan_destroy(sleb);
        return err;
+
+out_inc_seq:
+       /* We may have moved at least some nodes so allow for races with TNC */
+       c->gced_lnum = lnum;
+       smp_wmb();
+       c->gc_seq += 1;
+       smp_wmb();
+       goto out;
 }
 
 /**
index 7562464..3f49020 100644 (file)
@@ -1024,14 +1024,13 @@ static int mount_ubifs(struct ubifs_info *c)
                goto out_dereg;
        }
 
+       sprintf(c->bgt_name, BGT_NAME_PATTERN, c->vi.ubi_num, c->vi.vol_id);
        if (!mounted_read_only) {
                err = alloc_wbufs(c);
                if (err)
                        goto out_cbuf;
 
                /* Create background thread */
-               sprintf(c->bgt_name, BGT_NAME_PATTERN, c->vi.ubi_num,
-                       c->vi.vol_id);
                c->bgt = kthread_create(ubifs_bg_thread, c, c->bgt_name);
                if (!c->bgt)
                        c->bgt = ERR_PTR(-EINVAL);
index 7da209a..7634c59 100644 (file)
@@ -1476,7 +1476,7 @@ again:
        }
 
        err = fallible_read_node(c, key, &zbr, node);
-       if (maybe_leb_gced(c, zbr.lnum, gc_seq1)) {
+       if (err <= 0 || maybe_leb_gced(c, zbr.lnum, gc_seq1)) {
                /*
                 * The node may have been GC'ed out from under us so try again
                 * while keeping the TNC mutex locked.
index f42f80a..a44d68e 100644 (file)
@@ -1338,6 +1338,10 @@ __xfs_get_blocks(
        offset = (xfs_off_t)iblock << inode->i_blkbits;
        ASSERT(bh_result->b_size >= (1 << inode->i_blkbits));
        size = bh_result->b_size;
+
+       if (!create && direct && offset >= i_size_read(inode))
+               return 0;
+
        error = xfs_iomap(XFS_I(inode), offset, size,
                             create ? flags : BMAPI_READ, &iomap, &niomap);
        if (error)
index 73c65f1..18d3c84 100644 (file)
@@ -1302,9 +1302,29 @@ xfs_fs_remount(
                        mp->m_flags &= ~XFS_MOUNT_BARRIER;
                        break;
                default:
+                       /*
+                        * Logically we would return an error here to prevent
+                        * users from believing they might have changed
+                        * mount options using remount which can't be changed.
+                        *
+                        * But unfortunately mount(8) adds all options from
+                        * mtab and fstab to the mount arguments in some cases
+                        * so we can't blindly reject options, but have to
+                        * check for each specified option if it actually
+                        * differs from the currently set option and only
+                        * reject it if that's the case.
+                        *
+                        * Until that is implemented we return success for
+                        * every remount request, and silently ignore all
+                        * options that we can't actually change.
+                        */
+#if 0
                        printk(KERN_INFO
        "XFS: mount option \"%s\" not supported for remount\n", p);
                        return -EINVAL;
+#else
+                       return 0;
+#endif
                }
        }
 
index 608c30c..002fc26 100644 (file)
@@ -732,6 +732,7 @@ xfs_buf_item_init(
        bip->bli_item.li_ops = &xfs_buf_item_ops;
        bip->bli_item.li_mountp = mp;
        bip->bli_buf = bp;
+       xfs_buf_hold(bp);
        bip->bli_format.blf_type = XFS_LI_BUF;
        bip->bli_format.blf_blkno = (__int64_t)XFS_BUF_ADDR(bp);
        bip->bli_format.blf_len = (ushort)BTOBB(XFS_BUF_COUNT(bp));
@@ -867,6 +868,21 @@ xfs_buf_item_dirty(
        return (bip->bli_flags & XFS_BLI_DIRTY);
 }
 
+STATIC void
+xfs_buf_item_free(
+       xfs_buf_log_item_t      *bip)
+{
+#ifdef XFS_TRANS_DEBUG
+       kmem_free(bip->bli_orig);
+       kmem_free(bip->bli_logged);
+#endif /* XFS_TRANS_DEBUG */
+
+#ifdef XFS_BLI_TRACE
+       ktrace_free(bip->bli_trace);
+#endif
+       kmem_zone_free(xfs_buf_item_zone, bip);
+}
+
 /*
  * This is called when the buf log item is no longer needed.  It should
  * free the buf log item associated with the given buffer and clear
@@ -887,18 +903,8 @@ xfs_buf_item_relse(
            (XFS_BUF_IODONE_FUNC(bp) != NULL)) {
                XFS_BUF_CLR_IODONE_FUNC(bp);
        }
-
-#ifdef XFS_TRANS_DEBUG
-       kmem_free(bip->bli_orig);
-       bip->bli_orig = NULL;
-       kmem_free(bip->bli_logged);
-       bip->bli_logged = NULL;
-#endif /* XFS_TRANS_DEBUG */
-
-#ifdef XFS_BLI_TRACE
-       ktrace_free(bip->bli_trace);
-#endif
-       kmem_zone_free(xfs_buf_item_zone, bip);
+       xfs_buf_rele(bp);
+       xfs_buf_item_free(bip);
 }
 
 
@@ -1120,6 +1126,7 @@ xfs_buf_iodone(
 
        ASSERT(bip->bli_buf == bp);
 
+       xfs_buf_rele(bp);
        mp = bip->bli_item.li_mountp;
 
        /*
@@ -1136,18 +1143,7 @@ xfs_buf_iodone(
         * xfs_trans_delete_ail() drops the AIL lock.
         */
        xfs_trans_delete_ail(mp, (xfs_log_item_t *)bip);
-
-#ifdef XFS_TRANS_DEBUG
-       kmem_free(bip->bli_orig);
-       bip->bli_orig = NULL;
-       kmem_free(bip->bli_logged);
-       bip->bli_logged = NULL;
-#endif /* XFS_TRANS_DEBUG */
-
-#ifdef XFS_BLI_TRACE
-       ktrace_free(bip->bli_trace);
-#endif
-       kmem_zone_free(xfs_buf_item_zone, bip);
+       xfs_buf_item_free(bip);
 }
 
 #if defined(XFS_BLI_TRACE)
index 760f4c5..75b0cd4 100644 (file)
@@ -149,7 +149,14 @@ xfs_swap_extents(
 
        sbp = &sxp->sx_stat;
 
-       xfs_lock_two_inodes(ip, tip, lock_flags);
+       /*
+        * we have to do two separate lock calls here to keep lockdep
+        * happy. If we try to get all the locks in one call, lock will
+        * report false positives when we drop the ILOCK and regain them
+        * below.
+        */
+       xfs_lock_two_inodes(ip, tip, XFS_IOLOCK_EXCL);
+       xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL);
        locked = 1;
 
        /* Verify that both files have the same format */
index 00e80df..dbd9cef 100644 (file)
@@ -4118,7 +4118,7 @@ xfs_iext_indirect_to_direct(
        ASSERT(nextents <= XFS_LINEAR_EXTS);
        size = nextents * sizeof(xfs_bmbt_rec_t);
 
-       xfs_iext_irec_compact_full(ifp);
+       xfs_iext_irec_compact_pages(ifp);
        ASSERT(ifp->if_real_bytes == XFS_IEXT_BUFSZ);
 
        ep = ifp->if_u1.if_ext_irec->er_extbuf;
@@ -4449,8 +4449,7 @@ xfs_iext_irec_remove(
  * compaction policy is as follows:
  *
  *    Full Compaction: Extents fit into a single page (or inline buffer)
- *    Full Compaction: Extents occupy less than 10% of allocated space
- * Partial Compaction: Extents occupy > 10% and < 50% of allocated space
+ * Partial Compaction: Extents occupy less than 50% of allocated space
  *      No Compaction: Extents occupy at least 50% of allocated space
  */
 void
@@ -4471,8 +4470,6 @@ xfs_iext_irec_compact(
                xfs_iext_direct_to_inline(ifp, nextents);
        } else if (nextents <= XFS_LINEAR_EXTS) {
                xfs_iext_indirect_to_direct(ifp);
-       } else if (nextents < (nlists * XFS_LINEAR_EXTS) >> 3) {
-               xfs_iext_irec_compact_full(ifp);
        } else if (nextents < (nlists * XFS_LINEAR_EXTS) >> 1) {
                xfs_iext_irec_compact_pages(ifp);
        }
@@ -4496,7 +4493,7 @@ xfs_iext_irec_compact_pages(
                erp_next = erp + 1;
                if (erp_next->er_extcount <=
                    (XFS_LINEAR_EXTS - erp->er_extcount)) {
-                       memmove(&erp->er_extbuf[erp->er_extcount],
+                       memcpy(&erp->er_extbuf[erp->er_extcount],
                                erp_next->er_extbuf, erp_next->er_extcount *
                                sizeof(xfs_bmbt_rec_t));
                        erp->er_extcount += erp_next->er_extcount;
@@ -4515,91 +4512,6 @@ xfs_iext_irec_compact_pages(
        }
 }
 
-/*
- * Fully compact the extent records managed by the indirection array.
- */
-void
-xfs_iext_irec_compact_full(
-       xfs_ifork_t     *ifp)                   /* inode fork pointer */
-{
-       xfs_bmbt_rec_host_t *ep, *ep_next;      /* extent record pointers */
-       xfs_ext_irec_t  *erp, *erp_next;        /* extent irec pointers */
-       int             erp_idx = 0;            /* extent irec index */
-       int             ext_avail;              /* empty entries in ex list */
-       int             ext_diff;               /* number of exts to add */
-       int             nlists;                 /* number of irec's (ex lists) */
-
-       ASSERT(ifp->if_flags & XFS_IFEXTIREC);
-
-       nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
-       erp = ifp->if_u1.if_ext_irec;
-       ep = &erp->er_extbuf[erp->er_extcount];
-       erp_next = erp + 1;
-       ep_next = erp_next->er_extbuf;
-
-       while (erp_idx < nlists - 1) {
-               /*
-                * Check how many extent records are available in this irec.
-                * If there is none skip the whole exercise.
-                */
-               ext_avail = XFS_LINEAR_EXTS - erp->er_extcount;
-               if (ext_avail) {
-
-                       /*
-                        * Copy over as many as possible extent records into
-                        * the previous page.
-                        */
-                       ext_diff = MIN(ext_avail, erp_next->er_extcount);
-                       memcpy(ep, ep_next, ext_diff * sizeof(xfs_bmbt_rec_t));
-                       erp->er_extcount += ext_diff;
-                       erp_next->er_extcount -= ext_diff;
-
-                       /*
-                        * If the next irec is empty now we can simply
-                        * remove it.
-                        */
-                       if (erp_next->er_extcount == 0) {
-                               /*
-                                * Free page before removing extent record
-                                * so er_extoffs don't get modified in
-                                * xfs_iext_irec_remove.
-                                */
-                               kmem_free(erp_next->er_extbuf);
-                               erp_next->er_extbuf = NULL;
-                               xfs_iext_irec_remove(ifp, erp_idx + 1);
-                               erp = &ifp->if_u1.if_ext_irec[erp_idx];
-                               nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
-
-                       /*
-                        * If the next irec is not empty move up the content
-                        * that has not been copied to the previous page to
-                        * the beggining of this one.
-                        */
-                       } else {
-                               memmove(erp_next->er_extbuf, &ep_next[ext_diff],
-                                       erp_next->er_extcount *
-                                       sizeof(xfs_bmbt_rec_t));
-                               ep_next = erp_next->er_extbuf;
-                               memset(&ep_next[erp_next->er_extcount], 0,
-                                       (XFS_LINEAR_EXTS -
-                                               erp_next->er_extcount) *
-                                       sizeof(xfs_bmbt_rec_t));
-                       }
-               }
-
-               if (erp->er_extcount == XFS_LINEAR_EXTS) {
-                       erp_idx++;
-                       if (erp_idx < nlists)
-                               erp = &ifp->if_u1.if_ext_irec[erp_idx];
-                       else
-                               break;
-               }
-               ep = &erp->er_extbuf[erp->er_extcount];
-               erp_next = erp + 1;
-               ep_next = erp_next->er_extbuf;
-       }
-}
-
 /*
  * This is called to update the er_extoff field in the indirection
  * array when extents have been added or removed from one of the
index ccba14e..503ea89 100644 (file)
@@ -124,16 +124,27 @@ STATIC void       xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog,
 STATIC int     xlog_iclogs_empty(xlog_t *log);
 
 #if defined(XFS_LOG_TRACE)
+
+#define XLOG_TRACE_LOGGRANT_SIZE       2048
+#define XLOG_TRACE_ICLOG_SIZE          256
+
+void
+xlog_trace_loggrant_alloc(xlog_t *log)
+{
+       log->l_grant_trace = ktrace_alloc(XLOG_TRACE_LOGGRANT_SIZE, KM_NOFS);
+}
+
+void
+xlog_trace_loggrant_dealloc(xlog_t *log)
+{
+       ktrace_free(log->l_grant_trace);
+}
+
 void
 xlog_trace_loggrant(xlog_t *log, xlog_ticket_t *tic, xfs_caddr_t string)
 {
        unsigned long cnts;
 
-       if (!log->l_grant_trace) {
-               log->l_grant_trace = ktrace_alloc(2048, KM_NOSLEEP);
-               if (!log->l_grant_trace)
-                       return;
-       }
        /* ticket counts are 1 byte each */
        cnts = ((unsigned long)tic->t_ocnt) | ((unsigned long)tic->t_cnt) << 8;
 
@@ -156,11 +167,21 @@ xlog_trace_loggrant(xlog_t *log, xlog_ticket_t *tic, xfs_caddr_t string)
                     (void *)((unsigned long)tic->t_unit_res));
 }
 
+void
+xlog_trace_iclog_alloc(xlog_in_core_t *iclog)
+{
+       iclog->ic_trace = ktrace_alloc(XLOG_TRACE_ICLOG_SIZE, KM_NOFS);
+}
+
+void
+xlog_trace_iclog_dealloc(xlog_in_core_t *iclog)
+{
+       ktrace_free(iclog->ic_trace);
+}
+
 void
 xlog_trace_iclog(xlog_in_core_t *iclog, uint state)
 {
-       if (!iclog->ic_trace)
-               iclog->ic_trace = ktrace_alloc(256, KM_NOFS);
        ktrace_enter(iclog->ic_trace,
                     (void *)((unsigned long)state),
                     (void *)((unsigned long)current_pid()),
@@ -170,8 +191,15 @@ xlog_trace_iclog(xlog_in_core_t *iclog, uint state)
                     (void *)NULL, (void *)NULL);
 }
 #else
+
+#define        xlog_trace_loggrant_alloc(log)
+#define        xlog_trace_loggrant_dealloc(log)
 #define        xlog_trace_loggrant(log,tic,string)
+
+#define        xlog_trace_iclog_alloc(iclog)
+#define        xlog_trace_iclog_dealloc(iclog)
 #define        xlog_trace_iclog(iclog,state)
+
 #endif /* XFS_LOG_TRACE */
 
 
@@ -1009,7 +1037,7 @@ xlog_iodone(xfs_buf_t *bp)
         * layer, it means the underlyin device no longer supports
         * barrier I/O. Warn loudly and turn off barriers.
         */
-       if ((l->l_mp->m_flags & XFS_MOUNT_BARRIER) && !XFS_BUF_ORDERED(bp)) {
+       if ((l->l_mp->m_flags & XFS_MOUNT_BARRIER) && !XFS_BUF_ISORDERED(bp)) {
                l->l_mp->m_flags &= ~XFS_MOUNT_BARRIER;
                xfs_fs_cmn_err(CE_WARN, l->l_mp,
                                "xlog_iodone: Barriers are no longer supported"
@@ -1231,6 +1259,7 @@ xlog_alloc_log(xfs_mount_t        *mp,
        spin_lock_init(&log->l_grant_lock);
        sv_init(&log->l_flush_wait, 0, "flush_wait");
 
+       xlog_trace_loggrant_alloc(log);
        /* log record size must be multiple of BBSIZE; see xlog_rec_header_t */
        ASSERT((XFS_BUF_SIZE(bp) & BBMASK) == 0);
 
@@ -1285,6 +1314,8 @@ xlog_alloc_log(xfs_mount_t        *mp,
                sv_init(&iclog->ic_force_wait, SV_DEFAULT, "iclog-force");
                sv_init(&iclog->ic_write_wait, SV_DEFAULT, "iclog-write");
 
+               xlog_trace_iclog_alloc(iclog);
+
                iclogp = &iclog->ic_next;
        }
        *iclogp = log->l_iclog;                 /* complete ring */
@@ -1565,11 +1596,7 @@ xlog_dealloc_log(xlog_t *log)
                sv_destroy(&iclog->ic_force_wait);
                sv_destroy(&iclog->ic_write_wait);
                xfs_buf_free(iclog->ic_bp);
-#ifdef XFS_LOG_TRACE
-               if (iclog->ic_trace != NULL) {
-                       ktrace_free(iclog->ic_trace);
-               }
-#endif
+               xlog_trace_iclog_dealloc(iclog);
                next_iclog = iclog->ic_next;
                kmem_free(iclog);
                iclog = next_iclog;
@@ -1578,14 +1605,7 @@ xlog_dealloc_log(xlog_t *log)
        spinlock_destroy(&log->l_grant_lock);
 
        xfs_buf_free(log->l_xbuf);
-#ifdef XFS_LOG_TRACE
-       if (log->l_trace != NULL) {
-               ktrace_free(log->l_trace);
-       }
-       if (log->l_grant_trace != NULL) {
-               ktrace_free(log->l_grant_trace);
-       }
-#endif
+       xlog_trace_loggrant_dealloc(log);
        log->l_mp->m_log = NULL;
        kmem_free(log);
 }      /* xlog_dealloc_log */
index c8a5b22..e7d8f84 100644 (file)
@@ -448,7 +448,6 @@ typedef struct log {
        int                     l_grant_write_bytes;
 
 #ifdef XFS_LOG_TRACE
-       struct ktrace           *l_trace;
        struct ktrace           *l_grant_trace;
 #endif
 
index aa238c8..8b6812f 100644 (file)
@@ -1838,6 +1838,12 @@ again:
 #endif
 }
 
+/*
+ * xfs_lock_two_inodes() can only be used to lock one type of lock
+ * at a time - the iolock or the ilock, but not both at once. If
+ * we lock both at once, lockdep will report false positives saying
+ * we have violated locking orders.
+ */
 void
 xfs_lock_two_inodes(
        xfs_inode_t             *ip0,
@@ -1848,6 +1854,8 @@ xfs_lock_two_inodes(
        int                     attempts = 0;
        xfs_log_item_t          *lp;
 
+       if (lock_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL))
+               ASSERT((lock_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL)) == 0);
        ASSERT(ip0->i_ino != ip1->i_ino);
 
        if (ip0->i_ino > ip1->i_ino) {
@@ -3152,6 +3160,13 @@ error1:  /* Just cancel transaction */
 /*
  * Zero file bytes between startoff and endoff inclusive.
  * The iolock is held exclusive and no blocks are buffered.
+ *
+ * This function is used by xfs_free_file_space() to zero
+ * partial blocks when the range to free is not block aligned.
+ * When unreserving space with boundaries that are not block
+ * aligned we round up the start and round down the end
+ * boundaries and then use this function to zero the parts of
+ * the blocks that got dropped during the rounding.
  */
 STATIC int
 xfs_zero_remaining_bytes(
@@ -3168,6 +3183,17 @@ xfs_zero_remaining_bytes(
        int                     nimap;
        int                     error = 0;
 
+       /*
+        * Avoid doing I/O beyond eof - it's not necessary
+        * since nothing can read beyond eof.  The space will
+        * be zeroed when the file is extended anyway.
+        */
+       if (startoff >= ip->i_size)
+               return 0;
+
+       if (endoff > ip->i_size)
+               endoff = ip->i_size;
+
        bp = xfs_buf_get_noaddr(mp->m_sb.sb_blocksize,
                                XFS_IS_REALTIME_INODE(ip) ?
                                mp->m_rtdev_targp : mp->m_ddev_targp);
diff --git a/include/asm-mips/cevt-r4k.h b/include/asm-mips/cevt-r4k.h
new file mode 100644 (file)
index 0000000..fa4328f
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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) 2008 Kevin D. Kissell
+ */
+
+/*
+ * Definitions used for common event timer implementation
+ * for MIPS 4K-type processors and their MIPS MT variants.
+ * Avoids unsightly extern declarations in C files.
+ */
+#ifndef __ASM_CEVT_R4K_H
+#define __ASM_CEVT_R4K_H
+
+DECLARE_PER_CPU(struct clock_event_device, mips_clockevent_device);
+
+void mips_event_handler(struct clock_event_device *dev);
+int c0_compare_int_usable(void);
+void mips_set_clock_mode(enum clock_event_mode, struct clock_event_device *);
+irqreturn_t c0_compare_interrupt(int, void *);
+
+extern struct irqaction c0_compare_irqaction;
+extern int cp0_timer_irq_installed;
+
+/*
+ * Possibly handle a performance counter interrupt.
+ * Return true if the timer interrupt should not be checked
+ */
+
+static inline int handle_perf_irq(int r2)
+{
+       /*
+        * The performance counter overflow interrupt may be shared with the
+        * timer interrupt (cp0_perfcount_irq < 0). If it is and a
+        * performance counter has overflowed (perf_irq() == IRQ_HANDLED)
+        * and we can't reliably determine if a counter interrupt has also
+        * happened (!r2) then don't check for a timer interrupt.
+        */
+       return (cp0_perfcount_irq < 0) &&
+               perf_irq() == IRQ_HANDLED &&
+               !r2;
+}
+
+#endif /* __ASM_CEVT_R4K_H */
index 881e886..701ec0b 100644 (file)
@@ -38,8 +38,17 @@ __asm__(
        "       .set    pop                                             \n"
        "       .endm");
 
+extern void smtc_ipi_replay(void);
+
 static inline void raw_local_irq_enable(void)
 {
+#ifdef CONFIG_MIPS_MT_SMTC
+       /*
+        * SMTC kernel needs to do a software replay of queued
+        * IPIs, at the cost of call overhead on each local_irq_enable()
+        */
+       smtc_ipi_replay();
+#endif
        __asm__ __volatile__(
                "raw_local_irq_enable"
                : /* no outputs */
@@ -47,6 +56,7 @@ static inline void raw_local_irq_enable(void)
                : "memory");
 }
 
+
 /*
  * For cli() we have to insert nops to make sure that the new value
  * has actually arrived in the status register before the end of this
@@ -185,15 +195,14 @@ __asm__(
        "       .set    pop                                             \n"
        "       .endm                                                   \n");
 
-extern void smtc_ipi_replay(void);
 
 static inline void raw_local_irq_restore(unsigned long flags)
 {
        unsigned long __tmp1;
 
-#ifdef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY
+#ifdef CONFIG_MIPS_MT_SMTC
        /*
-        * CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY does prompt replay of deferred
+        * SMTC kernel needs to do a software replay of queued
         * IPIs, at the cost of branch and call overhead on each
         * local_irq_restore()
         */
@@ -208,6 +217,17 @@ static inline void raw_local_irq_restore(unsigned long flags)
                : "memory");
 }
 
+static inline void __raw_local_irq_restore(unsigned long flags)
+{
+       unsigned long __tmp1;
+
+       __asm__ __volatile__(
+               "raw_local_irq_restore\t%0"
+               : "=r" (__tmp1)
+               : "0" (flags)
+               : "memory");
+}
+
 static inline int raw_irqs_disabled_flags(unsigned long flags)
 {
 #ifdef CONFIG_MIPS_MT_SMTC
index a46f8e2..9798660 100644 (file)
@@ -1462,7 +1462,7 @@ set_c0_##name(unsigned int set)                                   \
 {                                                              \
        unsigned int res;                                       \
        unsigned int omt;                                       \
-       unsigned int flags;                                     \
+       unsigned long flags;                                    \
                                                                \
        local_irq_save(flags);                                  \
        omt = __dmt();                                          \
@@ -1480,7 +1480,7 @@ clear_c0_##name(unsigned int clear)                               \
 {                                                              \
        unsigned int res;                                       \
        unsigned int omt;                                       \
-       unsigned int flags;                                     \
+       unsigned long flags;                                    \
                                                                \
        local_irq_save(flags);                                  \
        omt = __dmt();                                          \
@@ -1498,7 +1498,7 @@ change_c0_##name(unsigned int change, unsigned int new)           \
 {                                                              \
        unsigned int res;                                       \
        unsigned int omt;                                       \
-       unsigned int flags;                                     \
+       unsigned long flags;                                    \
                                                                \
        local_irq_save(flags);                                  \
                                                                \
index 4396e9f..55813d6 100644 (file)
@@ -57,7 +57,7 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
 #define PMD_ORDER      1
 #define PTE_ORDER      0
 
-#define PTRS_PER_PGD   ((PAGE_SIZE << PGD_ORDER) / sizeof(pgd_t))
+#define PTRS_PER_PGD   (USER_PTRS_PER_PGD * 2)
 #define PTRS_PER_PTE   ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t))
 
 #define USER_PTRS_PER_PGD      (0x80000000UL/PGDIR_SIZE)
index 3639b28..ea60bf0 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <asm/mips_mt.h>
+#include <asm/smtc_ipi.h>
 
 /*
  * System-wide SMTC status information
@@ -38,14 +39,15 @@ struct mm_struct;
 struct task_struct;
 
 void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu);
-
+void self_ipi(struct smtc_ipi *);
 void smtc_flush_tlb_asid(unsigned long asid);
-extern int mipsmt_build_cpu_map(int startslot);
-extern void mipsmt_prepare_cpus(void);
+extern int smtc_build_cpu_map(int startslot);
+extern void smtc_prepare_cpus(int cpus);
 extern void smtc_smp_finish(void);
 extern void smtc_boot_secondary(int cpu, struct task_struct *t);
 extern void smtc_cpus_done(void);
 
+
 /*
  * Sharing the TLB between multiple VPEs means that the
  * "random" index selection function is not allowed to
index c3dd5d0..721496a 100644 (file)
@@ -5,6 +5,8 @@
 #ifndef __ASM_SN_MAPPED_KERNEL_H
 #define __ASM_SN_MAPPED_KERNEL_H
 
+#include <linux/mmzone.h>
+
 /*
  * Note on how mapped kernels work: the text and data section is
  * compiled at cksseg segment (LOADADDR = 0xc001c000), and the
 #define MAPPED_ADDR_RO_TO_PHYS(x)      (x - REP_BASE)
 #define MAPPED_ADDR_RW_TO_PHYS(x)      (x - REP_BASE - 16777216)
 
-#define MAPPED_KERN_RO_PHYSBASE(n) \
-                       (PLAT_NODE_DATA(n)->kern_vars.kv_ro_baseaddr)
-#define MAPPED_KERN_RW_PHYSBASE(n) \
-                       (PLAT_NODE_DATA(n)->kern_vars.kv_rw_baseaddr)
+#define MAPPED_KERN_RO_PHYSBASE(n) (hub_data(n)->kern_vars.kv_ro_baseaddr)
+#define MAPPED_KERN_RW_PHYSBASE(n) (hub_data(n)->kern_vars.kv_rw_baseaddr)
 
 #define MAPPED_KERN_RO_TO_PHYS(x) \
                                ((unsigned long)MAPPED_ADDR_RO_TO_PHYS(x) | \
index 051e1af..4c37c4e 100644 (file)
 #ifdef CONFIG_MIPS_MT_SMTC
                .set    mips32r2
                /*
-                * This may not really be necessary if ints are already
-                * inhibited here.
+                * We need to make sure the read-modify-write
+                * of Status below isn't perturbed by an interrupt
+                * or cross-TC access, so we need to do at least a DMT,
+                * protected by an interrupt-inhibit. But setting IXMT
+                * also creates a few-cycle window where an IPI could
+                * be queued and not be detected before potentially
+                * returning to a WAIT or user-mode loop. It must be
+                * replayed.
+                *
+                * We're in the middle of a context switch, and
+                * we can't dispatch it directly without trashing
+                * some registers, so we'll try to detect this unlikely
+                * case and program a software interrupt in the VPE,
+                * as would be done for a cross-VPE IPI.  To accomodate
+                * the handling of that case, we're doing a DVPE instead
+                * of just a DMT here to protect against other threads.
+                * This is a lot of cruft to cover a tiny window.
+                * If you can find a better design, implement it!
+                *
                 */
                mfc0    v0, CP0_TCSTATUS
                ori     v0, TCSTATUS_IXMT
                mtc0    v0, CP0_TCSTATUS
                _ehb
-               DMT     5                               # dmt a1
+               DVPE    5                               # dvpe a1
                jal     mips_ihb
 #endif /* CONFIG_MIPS_MT_SMTC */
                mfc0    a0, CP0_STATUS
  */
                LONG_L  v1, PT_TCSTATUS(sp)
                _ehb
-               mfc0    v0, CP0_TCSTATUS
+               mfc0    a0, CP0_TCSTATUS
                andi    v1, TCSTATUS_IXMT
-               /* We know that TCStatua.IXMT should be set from above */
-               xori    v0, v0, TCSTATUS_IXMT
-               or      v0, v0, v1
-               mtc0    v0, CP0_TCSTATUS
-               _ehb
-               andi    a1, a1, VPECONTROL_TE
+               bnez    v1, 0f
+
+/*
+ * We'd like to detect any IPIs queued in the tiny window
+ * above and request an software interrupt to service them
+ * when we ERET.
+ *
+ * Computing the offset into the IPIQ array of the executing
+ * TC's IPI queue in-line would be tedious.  We use part of
+ * the TCContext register to hold 16 bits of offset that we
+ * can add in-line to find the queue head.
+ */
+               mfc0    v0, CP0_TCCONTEXT
+               la      a2, IPIQ
+               srl     v0, v0, 16
+               addu    a2, a2, v0
+               LONG_L  v0, 0(a2)
+               beqz    v0, 0f
+/*
+ * If we have a queue, provoke dispatch within the VPE by setting C_SW1
+ */
+               mfc0    v0, CP0_CAUSE
+               ori     v0, v0, C_SW1
+               mtc0    v0, CP0_CAUSE
+0:
+               /*
+                * This test should really never branch but
+                * let's be prudent here.  Having atomized
+                * the shared register modifications, we can
+                * now EVPE, and must do so before interrupts
+                * are potentially re-enabled.
+                */
+               andi    a1, a1, MVPCONTROL_EVP
                beqz    a1, 1f
-               emt
+               evpe
 1:
+               /* We know that TCStatua.IXMT should be set from above */
+               xori    a0, a0, TCSTATUS_IXMT
+               or      a0, a0, v1
+               mtc0    a0, CP0_TCSTATUS
+               _ehb
+
                .set    mips0
 #endif /* CONFIG_MIPS_MT_SMTC */
                LONG_L  v1, PT_EPC(sp)
index 635d764..35d1743 100644 (file)
@@ -140,6 +140,8 @@ static inline unsigned int acpi_processor_cstate_check(unsigned int max_cstate)
            boot_cpu_data.x86_model <= 0x05 &&
            boot_cpu_data.x86_mask < 0x0A)
                return 1;
+       else if (boot_cpu_has(X86_FEATURE_AMDC1E))
+               return 1;
        else
                return max_cstate;
 }
index 9489283..cfcfb0a 100644 (file)
@@ -81,6 +81,7 @@
 #define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* Lfence synchronizes RDTSC */
 #define X86_FEATURE_11AP       (3*32+19) /* Bad local APIC aka 11AP */
 #define X86_FEATURE_NOPL       (3*32+20) /* The NOPL (0F 1F) instructions */
+#define X86_FEATURE_AMDC1E     (3*32+21) /* AMD C1E detected */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
 #define X86_FEATURE_XMM3       (4*32+ 0) /* Streaming SIMD Extensions-3 */
index d240e5b..cbb6491 100644 (file)
@@ -10,4 +10,6 @@ void idle_notifier_register(struct notifier_block *n);
 void enter_idle(void);
 void exit_idle(void);
 
+void c1e_remove_cpu(int cpu);
+
 #endif
index 484c475..94d63db 100644 (file)
@@ -39,12 +39,13 @@ enum regnames {
        GDB_FS,                 /* 14 */
        GDB_GS,                 /* 15 */
 };
+#define NUMREGBYTES            ((GDB_GS+1)*4)
 #else /* ! CONFIG_X86_32 */
-enum regnames {
+enum regnames64 {
        GDB_AX,                 /* 0 */
-       GDB_DX,                 /* 1 */
+       GDB_BX,                 /* 1 */
        GDB_CX,                 /* 2 */
-       GDB_BX,                 /* 3 */
+       GDB_DX,                 /* 3 */
        GDB_SI,                 /* 4 */
        GDB_DI,                 /* 5 */
        GDB_BP,                 /* 6 */
@@ -58,18 +59,15 @@ enum regnames {
        GDB_R14,                /* 14 */
        GDB_R15,                /* 15 */
        GDB_PC,                 /* 16 */
-       GDB_PS,                 /* 17 */
 };
-#endif /* CONFIG_X86_32 */
 
-/*
- * Number of bytes of registers:
- */
-#ifdef CONFIG_X86_32
-# define NUMREGBYTES           64
-#else
-# define NUMREGBYTES           ((GDB_PS+1)*8)
-#endif
+enum regnames32 {
+       GDB_PS = 34,
+       GDB_CS,
+       GDB_SS,
+};
+#define NUMREGBYTES            ((GDB_SS+1)*4)
+#endif /* CONFIG_X86_32 */
 
 static inline void arch_kgdb_breakpoint(void)
 {
index 515d4dc..45806d6 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/compiler.h>
 #include <linux/errno.h>
 #include <linux/prefetch.h>
+#include <linux/lockdep.h>
 #include <asm/page.h>
 
 /*
similarity index 87%
rename from arch/arm/include/asm/cnt32_to_63.h
rename to include/linux/cnt32_to_63.h
index 480c873..8c0f950 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  include/asm/cnt32_to_63.h -- extend a 32-bit counter to 63 bits
+ *  Extend a 32-bit counter to 63 bits
  *
  *  Author:    Nicolas Pitre
  *  Created:   December 3, 2006
  * as published by the Free Software Foundation.
  */
 
-#ifndef __INCLUDE_CNT32_TO_63_H__
-#define __INCLUDE_CNT32_TO_63_H__
+#ifndef __LINUX_CNT32_TO_63_H__
+#define __LINUX_CNT32_TO_63_H__
 
 #include <linux/compiler.h>
-#include <asm/types.h>
+#include <linux/types.h>
 #include <asm/byteorder.h>
 
-/*
- * Prototype: u64 cnt32_to_63(u32 cnt)
+/* this is used only to give gcc a clue about good code generation */
+union cnt32_to_63 {
+       struct {
+#if defined(__LITTLE_ENDIAN)
+               u32 lo, hi;
+#elif defined(__BIG_ENDIAN)
+               u32 hi, lo;
+#endif
+       };
+       u64 val;
+};
+
+
+/**
+ * cnt32_to_63 - Expand a 32-bit counter to a 63-bit counter
+ * @cnt_lo: The low part of the counter
+ *
  * Many hardware clock counters are only 32 bits wide and therefore have
  * a relatively short period making wrap-arounds rather frequent.  This
  * is a problem when implementing sched_clock() for example, where a 64-bit
  * clear-bit instruction. Otherwise caller must remember to clear the top
  * bit explicitly.
  */
-
-/* this is used only to give gcc a clue about good code generation */
-typedef union {
-       struct {
-#if defined(__LITTLE_ENDIAN)
-               u32 lo, hi;
-#elif defined(__BIG_ENDIAN)
-               u32 hi, lo;
-#endif
-       };
-       u64 val;
-} cnt32_to_63_t;
-
 #define cnt32_to_63(cnt_lo) \
 ({ \
-       static volatile u32 __m_cnt_hi = 0; \
-       cnt32_to_63_t __x; \
+       static volatile u32 __m_cnt_hi; \
+       union cnt32_to_63 __x; \
        __x.hi = __m_cnt_hi; \
        __x.lo = (cnt_lo); \
-       if (unlikely((s32)(__x.hi ^ __x.lo) < 0)) \
+       if (unlikely((s32)(__x.hi ^ __x.lo) < 0)) \
                __m_cnt_hi = __x.hi = (__x.hi ^ 0x80000000) + (__x.hi >> 31); \
        __x.val; \
 })
index 6d93dce..2f245fe 100644 (file)
@@ -47,14 +47,22 @@ enum hrtimer_restart {
  *     HRTIMER_CB_IRQSAFE:             Callback may run in hardirq context
  *     HRTIMER_CB_IRQSAFE_NO_RESTART:  Callback may run in hardirq context and
  *                                     does not restart the timer
- *     HRTIMER_CB_IRQSAFE_NO_SOFTIRQ:  Callback must run in hardirq context
- *                                     Special mode for tick emultation
+ *     HRTIMER_CB_IRQSAFE_PERCPU:      Callback must run in hardirq context
+ *                                     Special mode for tick emulation and
+ *                                     scheduler timer. Such timers are per
+ *                                     cpu and not allowed to be migrated on
+ *                                     cpu unplug.
+ *     HRTIMER_CB_IRQSAFE_UNLOCKED:    Callback should run in hardirq context
+ *                                     with timer->base lock unlocked
+ *                                     used for timers which call wakeup to
+ *                                     avoid lock order problems with rq->lock
  */
 enum hrtimer_cb_mode {
        HRTIMER_CB_SOFTIRQ,
        HRTIMER_CB_IRQSAFE,
        HRTIMER_CB_IRQSAFE_NO_RESTART,
-       HRTIMER_CB_IRQSAFE_NO_SOFTIRQ,
+       HRTIMER_CB_IRQSAFE_PERCPU,
+       HRTIMER_CB_IRQSAFE_UNLOCKED,
 };
 
 /*
@@ -67,9 +75,10 @@ enum hrtimer_cb_mode {
  * 0x02                callback function running
  * 0x04                callback pending (high resolution mode)
  *
- * Special case:
+ * Special cases:
  * 0x03                callback function running and enqueued
  *             (was requeued on another CPU)
+ * 0x09                timer was migrated on CPU hotunplug
  * The "callback function running and enqueued" status is only possible on
  * SMP. It happens for example when a posix timer expired and the callback
  * queued a signal. Between dropping the lock which protects the posix timer
@@ -87,6 +96,7 @@ enum hrtimer_cb_mode {
 #define HRTIMER_STATE_ENQUEUED 0x01
 #define HRTIMER_STATE_CALLBACK 0x02
 #define HRTIMER_STATE_PENDING  0x04
+#define HRTIMER_STATE_MIGRATE  0x08
 
 /**
  * struct hrtimer - the basic hrtimer structure
index 1524829..6514db8 100644 (file)
@@ -366,7 +366,9 @@ enum {
        /* Currently on a filemark */
        IDE_AFLAG_FILEMARK              = (1 << 25),
        /* 0 = no tape is loaded, so we don't rewind after ejecting */
-       IDE_AFLAG_MEDIUM_PRESENT        = (1 << 26)
+       IDE_AFLAG_MEDIUM_PRESENT        = (1 << 26),
+
+       IDE_AFLAG_NO_AUTOCLOSE          = (1 << 27),
 };
 
 struct ide_drive_s {
index 655ea0d..b2f9444 100644 (file)
@@ -141,6 +141,10 @@ enum {
        MLX4_STAT_RATE_OFFSET   = 5
 };
 
+enum {
+       MLX4_MTT_FLAG_PRESENT           = 1
+};
+
 static inline u64 mlx4_fw_ver(u64 major, u64 minor, u64 subminor)
 {
        return (major << 32) | (minor << 16) | subminor;
index c0e1400..98dc624 100644 (file)
@@ -534,7 +534,7 @@ extern void pci_sort_breadthfirst(void);
 #ifdef CONFIG_PCI_LEGACY
 struct pci_dev __deprecated *pci_find_device(unsigned int vendor,
                                             unsigned int device,
-                                            const struct pci_dev *from);
+                                            struct pci_dev *from);
 struct pci_dev __deprecated *pci_find_slot(unsigned int bus,
                                           unsigned int devfn);
 #endif /* CONFIG_PCI_LEGACY */
@@ -550,7 +550,7 @@ struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device,
                                struct pci_dev *from);
 struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device,
                                unsigned int ss_vendor, unsigned int ss_device,
-                               const struct pci_dev *from);
+                               struct pci_dev *from);
 struct pci_dev *pci_get_slot(struct pci_bus *bus, unsigned int devfn);
 struct pci_dev *pci_get_bus_and_slot(unsigned int bus, unsigned int devfn);
 struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from);
@@ -816,7 +816,7 @@ _PCI_NOP_ALL(write,)
 
 static inline struct pci_dev *pci_find_device(unsigned int vendor,
                                              unsigned int device,
-                                             const struct pci_dev *from)
+                                             struct pci_dev *from)
 {
        return NULL;
 }
@@ -838,7 +838,7 @@ static inline struct pci_dev *pci_get_subsys(unsigned int vendor,
                                             unsigned int device,
                                             unsigned int ss_vendor,
                                             unsigned int ss_device,
-                                            const struct pci_dev *from)
+                                            struct pci_dev *from)
 {
        return NULL;
 }
index b160fb1..37aaf2b 100644 (file)
@@ -6,6 +6,7 @@ extern int ramfs_get_sb(struct file_system_type *fs_type,
         int flags, const char *dev_name, void *data, struct vfsmount *mnt);
 
 #ifndef CONFIG_MMU
+extern int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize);
 extern unsigned long ramfs_nommu_get_unmapped_area(struct file *file,
                                                   unsigned long addr,
                                                   unsigned long len,
index caa43b2..82fefdd 100644 (file)
@@ -11,7 +11,9 @@
 
 #include <linux/types.h>
 #include <linux/magic.h>
+#ifdef __KERNEL__
 #include <linux/time.h>
+#endif
 
 enum smb_protocol { 
        SMB_PROTOCOL_NONE, 
index 5da9794..b106fd8 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef __LINUX_STACKTRACE_H
 #define __LINUX_STACKTRACE_H
 
+struct task_struct;
+
 #ifdef CONFIG_STACKTRACE
 struct stack_trace {
        unsigned int nr_entries, max_entries;
index b3d3e27..c3626c0 100644 (file)
@@ -596,4 +596,5 @@ int p9_idpool_check(int id, struct p9_idpool *p);
 int p9_error_init(void);
 int p9_errstr2errno(char *, int);
 int p9_trans_fd_init(void);
+void p9_trans_fd_exit(void);
 #endif /* NET_9P_H */
index 0db3a40..3ca7371 100644 (file)
@@ -26,6 +26,8 @@
 #ifndef NET_9P_TRANSPORT_H
 #define NET_9P_TRANSPORT_H
 
+#include <linux/module.h>
+
 /**
  * enum p9_trans_status - different states of underlying transports
  * @Connected: transport is connected and healthy
@@ -91,9 +93,12 @@ struct p9_trans_module {
        int maxsize;            /* max message size of transport */
        int def;                /* this transport should be default */
        struct p9_trans * (*create)(const char *, char *, int, unsigned char);
+       struct module *owner;
 };
 
 void v9fs_register_trans(struct p9_trans_module *m);
-struct p9_trans_module *v9fs_match_trans(const substring_t *name);
-struct p9_trans_module *v9fs_default_trans(void);
+void v9fs_unregister_trans(struct p9_trans_module *m);
+struct p9_trans_module *v9fs_get_trans_by_name(const substring_t *name);
+struct p9_trans_module *v9fs_get_default_trans(void);
+void v9fs_put_trans(struct p9_trans_module *m);
 #endif /* NET_9P_TRANSPORT_H */
index 2481173..029a54a 100644 (file)
@@ -227,6 +227,9 @@ struct sctp_chunk *sctp_make_abort_violation(const struct sctp_association *,
                                   const struct sctp_chunk *,
                                   const __u8 *,
                                   const size_t );
+struct sctp_chunk *sctp_make_violation_paramlen(const struct sctp_association *,
+                                  const struct sctp_chunk *,
+                                  struct sctp_paramhdr *);
 struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *,
                                  const struct sctp_transport *,
                                  const void *payload,
index f6f7042..3820323 100644 (file)
@@ -708,7 +708,7 @@ int do_one_initcall(initcall_t fn)
        int result;
 
        if (initcall_debug) {
-               print_fn_descriptor_symbol("calling  %s\n", fn);
+               printk("calling  %pF\n", fn);
                t0 = ktime_get();
        }
 
@@ -718,8 +718,8 @@ int do_one_initcall(initcall_t fn)
                t1 = ktime_get();
                delta = ktime_sub(t1, t0);
 
-               print_fn_descriptor_symbol("initcall %s", fn);
-               printk(" returned %d after %Ld msecs\n", result,
+               printk("initcall %pF returned %d after %Ld msecs\n",
+                       fn, result,
                        (unsigned long long) delta.tv64 >> 20);
        }
 
@@ -737,8 +737,7 @@ int do_one_initcall(initcall_t fn)
                local_irq_enable();
        }
        if (msgbuf[0]) {
-               print_fn_descriptor_symbol(KERN_WARNING "initcall %s", fn);
-               printk(" returned with %s\n", msgbuf);
+               printk("initcall %pF returned with %s\n", fn, msgbuf);
        }
 
        return result;
index 13932ab..a0123d7 100644 (file)
@@ -2738,14 +2738,15 @@ void cgroup_fork_callbacks(struct task_struct *child)
  */
 void cgroup_mm_owner_callbacks(struct task_struct *old, struct task_struct *new)
 {
-       struct cgroup *oldcgrp, *newcgrp;
+       struct cgroup *oldcgrp, *newcgrp = NULL;
 
        if (need_mm_owner_callback) {
                int i;
                for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
                        struct cgroup_subsys *ss = subsys[i];
                        oldcgrp = task_cgroup(old, ss->subsys_id);
-                       newcgrp = task_cgroup(new, ss->subsys_id);
+                       if (new)
+                               newcgrp = task_cgroup(new, ss->subsys_id);
                        if (oldcgrp == newcgrp)
                                continue;
                        if (ss->mm_owner_changed)
index 1639564..85a83c8 100644 (file)
@@ -583,8 +583,6 @@ mm_need_new_owner(struct mm_struct *mm, struct task_struct *p)
         * If there are other users of the mm and the owner (us) is exiting
         * we need to find a new owner to take on the responsibility.
         */
-       if (!mm)
-               return 0;
        if (atomic_read(&mm->mm_users) <= 1)
                return 0;
        if (mm->owner != p)
@@ -627,6 +625,16 @@ retry:
        } while_each_thread(g, c);
 
        read_unlock(&tasklist_lock);
+       /*
+        * We found no owner yet mm_users > 1: this implies that we are
+        * most likely racing with swapoff (try_to_unuse()) or /proc or
+        * ptrace or page migration (get_task_mm()).  Mark owner as NULL,
+        * so that subsystems can understand the callback and take action.
+        */
+       down_write(&mm->mmap_sem);
+       cgroup_mm_owner_callbacks(mm->owner, NULL);
+       mm->owner = NULL;
+       up_write(&mm->mmap_sem);
        return;
 
 assign_new_owner:
index b8e4dce..cdec83e 100644 (file)
@@ -672,13 +672,14 @@ static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer,
                         */
                        BUG_ON(timer->function(timer) != HRTIMER_NORESTART);
                        return 1;
-               case HRTIMER_CB_IRQSAFE_NO_SOFTIRQ:
+               case HRTIMER_CB_IRQSAFE_PERCPU:
+               case HRTIMER_CB_IRQSAFE_UNLOCKED:
                        /*
                         * This is solely for the sched tick emulation with
                         * dynamic tick support to ensure that we do not
                         * restart the tick right on the edge and end up with
                         * the tick timer in the softirq ! The calling site
-                        * takes care of this.
+                        * takes care of this. Also used for hrtimer sleeper !
                         */
                        debug_hrtimer_deactivate(timer);
                        return 1;
@@ -1245,7 +1246,8 @@ static void __run_hrtimer(struct hrtimer *timer)
        timer_stats_account_hrtimer(timer);
 
        fn = timer->function;
-       if (timer->cb_mode == HRTIMER_CB_IRQSAFE_NO_SOFTIRQ) {
+       if (timer->cb_mode == HRTIMER_CB_IRQSAFE_PERCPU ||
+           timer->cb_mode == HRTIMER_CB_IRQSAFE_UNLOCKED) {
                /*
                 * Used for scheduler timers, avoid lock inversion with
                 * rq->lock and tasklist_lock.
@@ -1452,7 +1454,7 @@ void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, struct task_struct *task)
        sl->timer.function = hrtimer_wakeup;
        sl->task = task;
 #ifdef CONFIG_HIGH_RES_TIMERS
-       sl->timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ;
+       sl->timer.cb_mode = HRTIMER_CB_IRQSAFE_UNLOCKED;
 #endif
 }
 
@@ -1591,29 +1593,95 @@ static void __cpuinit init_hrtimers_cpu(int cpu)
 
 #ifdef CONFIG_HOTPLUG_CPU
 
-static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base,
-                               struct hrtimer_clock_base *new_base)
+static int migrate_hrtimer_list(struct hrtimer_clock_base *old_base,
+                               struct hrtimer_clock_base *new_base, int dcpu)
 {
        struct hrtimer *timer;
        struct rb_node *node;
+       int raise = 0;
 
        while ((node = rb_first(&old_base->active))) {
                timer = rb_entry(node, struct hrtimer, node);
                BUG_ON(hrtimer_callback_running(timer));
                debug_hrtimer_deactivate(timer);
-               __remove_hrtimer(timer, old_base, HRTIMER_STATE_INACTIVE, 0);
+
+               /*
+                * Should not happen. Per CPU timers should be
+                * canceled _before_ the migration code is called
+                */
+               if (timer->cb_mode == HRTIMER_CB_IRQSAFE_PERCPU) {
+                       __remove_hrtimer(timer, old_base,
+                                        HRTIMER_STATE_INACTIVE, 0);
+                       WARN(1, "hrtimer (%p %p)active but cpu %d dead\n",
+                            timer, timer->function, dcpu);
+                       continue;
+               }
+
+               /*
+                * Mark it as STATE_MIGRATE not INACTIVE otherwise the
+                * timer could be seen as !active and just vanish away
+                * under us on another CPU
+                */
+               __remove_hrtimer(timer, old_base, HRTIMER_STATE_MIGRATE, 0);
                timer->base = new_base;
                /*
                 * Enqueue the timer. Allow reprogramming of the event device
                 */
                enqueue_hrtimer(timer, new_base, 1);
+
+#ifdef CONFIG_HIGH_RES_TIMERS
+               /*
+                * Happens with high res enabled when the timer was
+                * already expired and the callback mode is
+                * HRTIMER_CB_IRQSAFE_UNLOCKED (hrtimer_sleeper). The
+                * enqueue code does not move them to the soft irq
+                * pending list for performance/latency reasons, but
+                * in the migration state, we need to do that
+                * otherwise we end up with a stale timer.
+                */
+               if (timer->state == HRTIMER_STATE_MIGRATE) {
+                       timer->state = HRTIMER_STATE_PENDING;
+                       list_add_tail(&timer->cb_entry,
+                                     &new_base->cpu_base->cb_pending);
+                       raise = 1;
+               }
+#endif
+               /* Clear the migration state bit */
+               timer->state &= ~HRTIMER_STATE_MIGRATE;
+       }
+       return raise;
+}
+
+#ifdef CONFIG_HIGH_RES_TIMERS
+static int migrate_hrtimer_pending(struct hrtimer_cpu_base *old_base,
+                                  struct hrtimer_cpu_base *new_base)
+{
+       struct hrtimer *timer;
+       int raise = 0;
+
+       while (!list_empty(&old_base->cb_pending)) {
+               timer = list_entry(old_base->cb_pending.next,
+                                  struct hrtimer, cb_entry);
+
+               __remove_hrtimer(timer, timer->base, HRTIMER_STATE_PENDING, 0);
+               timer->base = &new_base->clock_base[timer->base->index];
+               list_add_tail(&timer->cb_entry, &new_base->cb_pending);
+               raise = 1;
        }
+       return raise;
+}
+#else
+static int migrate_hrtimer_pending(struct hrtimer_cpu_base *old_base,
+                                  struct hrtimer_cpu_base *new_base)
+{
+       return 0;
 }
+#endif
 
 static void migrate_hrtimers(int cpu)
 {
        struct hrtimer_cpu_base *old_base, *new_base;
-       int i;
+       int i, raise = 0;
 
        BUG_ON(cpu_online(cpu));
        old_base = &per_cpu(hrtimer_bases, cpu);
@@ -1626,14 +1694,21 @@ static void migrate_hrtimers(int cpu)
        spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING);
 
        for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) {
-               migrate_hrtimer_list(&old_base->clock_base[i],
-                                    &new_base->clock_base[i]);
+               if (migrate_hrtimer_list(&old_base->clock_base[i],
+                                        &new_base->clock_base[i], cpu))
+                       raise = 1;
        }
 
+       if (migrate_hrtimer_pending(old_base, new_base))
+               raise = 1;
+
        spin_unlock(&old_base->lock);
        spin_unlock(&new_base->lock);
        local_irq_enable();
        put_cpu_var(hrtimer_bases);
+
+       if (raise)
+               hrtimer_raise_softirq();
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
index 59f3f0d..aef2653 100644 (file)
@@ -753,8 +753,14 @@ static struct page *kimage_alloc_page(struct kimage *image,
                        *old = addr | (*old & ~PAGE_MASK);
 
                        /* The old page I have found cannot be a
-                        * destination page, so return it.
+                        * destination page, so return it if it's
+                        * gfp_flags honor the ones passed in.
                         */
+                       if (!(gfp_mask & __GFP_HIGHMEM) &&
+                           PageHighMem(old_page)) {
+                               kimage_free_pages(old_page);
+                               continue;
+                       }
                        addr = old_addr;
                        page = old_page;
                        break;
index eaa21fc..e4dcfb2 100644 (file)
@@ -488,7 +488,7 @@ static int write_mem_msg(int binary)
                if (err)
                        return err;
                if (CACHE_FLUSH_IS_SAFE)
-                       flush_icache_range(addr, addr + length + 1);
+                       flush_icache_range(addr, addr + length);
                return 0;
        }
 
@@ -590,6 +590,7 @@ static void kgdb_wait(struct pt_regs *regs)
 
        /* Signal the primary CPU that we are done: */
        atomic_set(&cpu_in_kgdb[cpu], 0);
+       touch_softlockup_watchdog();
        clocksource_touch_watchdog();
        local_irq_restore(flags);
 }
@@ -1432,6 +1433,7 @@ acquirelock:
            atomic_read(&kgdb_cpu_doing_single_step) != cpu) {
 
                atomic_set(&kgdb_active, -1);
+               touch_softlockup_watchdog();
                clocksource_touch_watchdog();
                local_irq_restore(flags);
 
@@ -1462,7 +1464,7 @@ acquirelock:
         * Get the passive CPU lock which will hold all the non-primary
         * CPU in a spin state while the debugger is active
         */
-       if (!kgdb_single_step || !kgdb_contthread) {
+       if (!kgdb_single_step) {
                for (i = 0; i < NR_CPUS; i++)
                        atomic_set(&passive_cpu_wait[i], 1);
        }
@@ -1475,7 +1477,7 @@ acquirelock:
 
 #ifdef CONFIG_SMP
        /* Signal the other CPUs to enter kgdb_wait() */
-       if ((!kgdb_single_step || !kgdb_contthread) && kgdb_do_roundup)
+       if ((!kgdb_single_step) && kgdb_do_roundup)
                kgdb_roundup_cpus(flags);
 #endif
 
@@ -1494,7 +1496,7 @@ acquirelock:
        kgdb_post_primary_code(ks->linux_regs, ks->ex_vector, ks->err_code);
        kgdb_deactivate_sw_breakpoints();
        kgdb_single_step = 0;
-       kgdb_contthread = NULL;
+       kgdb_contthread = current;
        exception_level = 0;
 
        /* Talk to debugger with gdbserial protocol */
@@ -1508,7 +1510,7 @@ acquirelock:
        kgdb_info[ks->cpu].task = NULL;
        atomic_set(&cpu_in_kgdb[ks->cpu], 0);
 
-       if (!kgdb_single_step || !kgdb_contthread) {
+       if (!kgdb_single_step) {
                for (i = NR_CPUS-1; i >= 0; i--)
                        atomic_set(&passive_cpu_wait[i], 0);
                /*
@@ -1524,6 +1526,7 @@ acquirelock:
 kgdb_restore:
        /* Free kgdb_active */
        atomic_set(&kgdb_active, -1);
+       touch_softlockup_watchdog();
        clocksource_touch_watchdog();
        local_irq_restore(flags);
 
index e36d579..5131e54 100644 (file)
@@ -441,7 +441,7 @@ static struct k_itimer * alloc_posix_timer(void)
                return tmr;
        if (unlikely(!(tmr->sigq = sigqueue_alloc()))) {
                kmem_cache_free(posix_timers_cache, tmr);
-               tmr = NULL;
+               return NULL;
        }
        memset(&tmr->sigq->info, 0, sizeof(siginfo_t));
        return tmr;
index cc1f81b..ad1962d 100644 (file)
@@ -201,7 +201,7 @@ void init_rt_bandwidth(struct rt_bandwidth *rt_b, u64 period, u64 runtime)
        hrtimer_init(&rt_b->rt_period_timer,
                        CLOCK_MONOTONIC, HRTIMER_MODE_REL);
        rt_b->rt_period_timer.function = sched_rt_period_timer;
-       rt_b->rt_period_timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ;
+       rt_b->rt_period_timer.cb_mode = HRTIMER_CB_IRQSAFE_UNLOCKED;
 }
 
 static void start_rt_bandwidth(struct rt_bandwidth *rt_b)
@@ -1087,7 +1087,7 @@ hotplug_hrtick(struct notifier_block *nfb, unsigned long action, void *hcpu)
        return NOTIFY_DONE;
 }
 
-static void init_hrtick(void)
+static __init void init_hrtick(void)
 {
        hotcpu_notifier(hotplug_hrtick, 0);
 }
@@ -1119,7 +1119,7 @@ static void init_rq_hrtick(struct rq *rq)
 
        hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
        rq->hrtick_timer.function = hrtick;
-       rq->hrtick_timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ;
+       rq->hrtick_timer.cb_mode = HRTIMER_CB_IRQSAFE_PERCPU;
 }
 #else
 static inline void hrtick_clear(struct rq *rq)
@@ -8909,6 +8909,9 @@ static int sched_rt_global_constraints(void)
        u64 rt_runtime, rt_period;
        int ret = 0;
 
+       if (sysctl_sched_rt_period <= 0)
+               return -EINVAL;
+
        rt_period = ktime_to_ns(tg->rt_bandwidth.rt_period);
        rt_runtime = tg->rt_bandwidth.rt_runtime;
 
@@ -8925,6 +8928,9 @@ static int sched_rt_global_constraints(void)
        unsigned long flags;
        int i;
 
+       if (sysctl_sched_rt_period <= 0)
+               return -EINVAL;
+
        spin_lock_irqsave(&def_rt_bandwidth.rt_runtime_lock, flags);
        for_each_possible_cpu(i) {
                struct rt_rq *rt_rq = &cpu_rq(i)->rt;
index 5523107..1113157 100644 (file)
@@ -350,6 +350,7 @@ static void __enable_runtime(struct rq *rq)
                spin_lock(&rt_rq->rt_runtime_lock);
                rt_rq->rt_runtime = rt_b->rt_runtime;
                rt_rq->rt_time = 0;
+               rt_rq->rt_throttled = 0;
                spin_unlock(&rt_rq->rt_runtime_lock);
                spin_unlock(&rt_b->rt_runtime_lock);
        }
index 1876b52..f8d9680 100644 (file)
@@ -71,6 +71,16 @@ void clockevents_set_mode(struct clock_event_device *dev,
        }
 }
 
+/**
+ * clockevents_shutdown - shutdown the device and clear next_event
+ * @dev:       device to shutdown
+ */
+void clockevents_shutdown(struct clock_event_device *dev)
+{
+       clockevents_set_mode(dev, CLOCK_EVT_MODE_SHUTDOWN);
+       dev->next_event.tv64 = KTIME_MAX;
+}
+
 /**
  * clockevents_program_event - Reprogram the clock event device.
  * @expires:   absolute expiry time (monotonic clock)
@@ -206,7 +216,7 @@ void clockevents_exchange_device(struct clock_event_device *old,
 
        if (new) {
                BUG_ON(new->mode != CLOCK_EVT_MODE_UNUSED);
-               clockevents_set_mode(new, CLOCK_EVT_MODE_SHUTDOWN);
+               clockevents_shutdown(new);
        }
        local_irq_restore(flags);
 }
index 2f5a382..cb01cd8 100644 (file)
@@ -235,9 +235,9 @@ static void tick_do_broadcast_on_off(void *why)
        case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
                if (!cpu_isset(cpu, tick_broadcast_mask)) {
                        cpu_set(cpu, tick_broadcast_mask);
-                       if (td->mode == TICKDEV_MODE_PERIODIC)
-                               clockevents_set_mode(dev,
-                                                    CLOCK_EVT_MODE_SHUTDOWN);
+                       if (tick_broadcast_device.mode ==
+                           TICKDEV_MODE_PERIODIC)
+                               clockevents_shutdown(dev);
                }
                if (*reason == CLOCK_EVT_NOTIFY_BROADCAST_FORCE)
                        tick_broadcast_force = 1;
@@ -246,7 +246,8 @@ static void tick_do_broadcast_on_off(void *why)
                if (!tick_broadcast_force &&
                    cpu_isset(cpu, tick_broadcast_mask)) {
                        cpu_clear(cpu, tick_broadcast_mask);
-                       if (td->mode == TICKDEV_MODE_PERIODIC)
+                       if (tick_broadcast_device.mode ==
+                           TICKDEV_MODE_PERIODIC)
                                tick_setup_periodic(dev, 0);
                }
                break;
@@ -254,7 +255,7 @@ static void tick_do_broadcast_on_off(void *why)
 
        if (cpus_empty(tick_broadcast_mask)) {
                if (!bc_stopped)
-                       clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
+                       clockevents_shutdown(bc);
        } else if (bc_stopped) {
                if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC)
                        tick_broadcast_start_periodic(bc);
@@ -306,7 +307,7 @@ void tick_shutdown_broadcast(unsigned int *cpup)
 
        if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) {
                if (bc && cpus_empty(tick_broadcast_mask))
-                       clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
+                       clockevents_shutdown(bc);
        }
 
        spin_unlock_irqrestore(&tick_broadcast_lock, flags);
@@ -321,7 +322,7 @@ void tick_suspend_broadcast(void)
 
        bc = tick_broadcast_device.evtdev;
        if (bc)
-               clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
+               clockevents_shutdown(bc);
 
        spin_unlock_irqrestore(&tick_broadcast_lock, flags);
 }
@@ -576,4 +577,12 @@ void tick_shutdown_broadcast_oneshot(unsigned int *cpup)
        spin_unlock_irqrestore(&tick_broadcast_lock, flags);
 }
 
+/*
+ * Check, whether the broadcast device is in one shot mode
+ */
+int tick_broadcast_oneshot_active(void)
+{
+       return tick_broadcast_device.mode == TICKDEV_MODE_ONESHOT;
+}
+
 #endif
index c477719..df12434 100644 (file)
@@ -33,7 +33,7 @@ DEFINE_PER_CPU(struct tick_device, tick_cpu_device);
  */
 ktime_t tick_next_period;
 ktime_t tick_period;
-int tick_do_timer_cpu __read_mostly = -1;
+int tick_do_timer_cpu __read_mostly = TICK_DO_TIMER_BOOT;
 DEFINE_SPINLOCK(tick_device_lock);
 
 /*
@@ -109,7 +109,8 @@ void tick_setup_periodic(struct clock_event_device *dev, int broadcast)
        if (!tick_device_is_functional(dev))
                return;
 
-       if (dev->features & CLOCK_EVT_FEAT_PERIODIC) {
+       if ((dev->features & CLOCK_EVT_FEAT_PERIODIC) &&
+           !tick_broadcast_oneshot_active()) {
                clockevents_set_mode(dev, CLOCK_EVT_MODE_PERIODIC);
        } else {
                unsigned long seq;
@@ -148,7 +149,7 @@ static void tick_setup_device(struct tick_device *td,
                 * If no cpu took the do_timer update, assign it to
                 * this cpu:
                 */
-               if (tick_do_timer_cpu == -1) {
+               if (tick_do_timer_cpu == TICK_DO_TIMER_BOOT) {
                        tick_do_timer_cpu = cpu;
                        tick_next_period = ktime_get();
                        tick_period = ktime_set(0, NSEC_PER_SEC / HZ);
@@ -249,7 +250,7 @@ static int tick_check_new_device(struct clock_event_device *newdev)
         * not give it back to the clockevents layer !
         */
        if (tick_is_broadcast_device(curdev)) {
-               clockevents_set_mode(curdev, CLOCK_EVT_MODE_SHUTDOWN);
+               clockevents_shutdown(curdev);
                curdev = NULL;
        }
        clockevents_exchange_device(curdev, newdev);
@@ -300,7 +301,8 @@ static void tick_shutdown(unsigned int *cpup)
        if (*cpup == tick_do_timer_cpu) {
                int cpu = first_cpu(cpu_online_map);
 
-               tick_do_timer_cpu = (cpu != NR_CPUS) ? cpu : -1;
+               tick_do_timer_cpu = (cpu != NR_CPUS) ? cpu :
+                       TICK_DO_TIMER_NONE;
        }
        spin_unlock_irqrestore(&tick_device_lock, flags);
 }
@@ -311,7 +313,7 @@ static void tick_suspend(void)
        unsigned long flags;
 
        spin_lock_irqsave(&tick_device_lock, flags);
-       clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_SHUTDOWN);
+       clockevents_shutdown(td->evtdev);
        spin_unlock_irqrestore(&tick_device_lock, flags);
 }
 
index 0ffc291..4692487 100644 (file)
@@ -1,6 +1,10 @@
 /*
  * tick internal variable and functions used by low/high res code
  */
+
+#define TICK_DO_TIMER_NONE     -1
+#define TICK_DO_TIMER_BOOT     -2
+
 DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
 extern spinlock_t tick_device_lock;
 extern ktime_t tick_next_period;
@@ -10,6 +14,8 @@ extern int tick_do_timer_cpu __read_mostly;
 extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast);
 extern void tick_handle_periodic(struct clock_event_device *dev);
 
+extern void clockevents_shutdown(struct clock_event_device *dev);
+
 /*
  * NO_HZ / high resolution timer shared code
  */
@@ -29,6 +35,7 @@ extern void tick_broadcast_oneshot_control(unsigned long reason);
 extern void tick_broadcast_switch_to_oneshot(void);
 extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup);
 extern int tick_resume_broadcast_oneshot(struct clock_event_device *bc);
+extern int tick_broadcast_oneshot_active(void);
 # else /* BROADCAST */
 static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
 {
@@ -37,6 +44,7 @@ static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
 static inline void tick_broadcast_oneshot_control(unsigned long reason) { }
 static inline void tick_broadcast_switch_to_oneshot(void) { }
 static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { }
+static inline int tick_broadcast_oneshot_active(void) { return 0; }
 # endif /* !BROADCAST */
 
 #else /* !ONESHOT */
@@ -66,6 +74,7 @@ static inline int tick_resume_broadcast_oneshot(struct clock_event_device *bc)
 {
        return 0;
 }
+static inline int tick_broadcast_oneshot_active(void) { return 0; }
 #endif /* !TICK_ONESHOT */
 
 /*
index a87b046..cb02324 100644 (file)
@@ -75,6 +75,9 @@ static void tick_do_update_jiffies64(ktime_t now)
                                                           incr * ticks);
                }
                do_timer(++ticks);
+
+               /* Keep the tick_next_period variable up to date */
+               tick_next_period = ktime_add(last_jiffies_update, tick_period);
        }
        write_sequnlock(&xtime_lock);
 }
@@ -221,7 +224,7 @@ void tick_nohz_stop_sched_tick(int inidle)
         */
        if (unlikely(!cpu_online(cpu))) {
                if (cpu == tick_do_timer_cpu)
-                       tick_do_timer_cpu = -1;
+                       tick_do_timer_cpu = TICK_DO_TIMER_NONE;
        }
 
        if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE))
@@ -303,7 +306,7 @@ void tick_nohz_stop_sched_tick(int inidle)
                 * invoked.
                 */
                if (cpu == tick_do_timer_cpu)
-                       tick_do_timer_cpu = -1;
+                       tick_do_timer_cpu = TICK_DO_TIMER_NONE;
 
                ts->idle_sleeps++;
 
@@ -468,7 +471,7 @@ static void tick_nohz_handler(struct clock_event_device *dev)
         * this duty, then the jiffies update is still serialized by
         * xtime_lock.
         */
-       if (unlikely(tick_do_timer_cpu == -1))
+       if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE))
                tick_do_timer_cpu = cpu;
 
        /* Check, if the jiffies need an update */
@@ -570,7 +573,7 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer)
         * this duty, then the jiffies update is still serialized by
         * xtime_lock.
         */
-       if (unlikely(tick_do_timer_cpu == -1))
+       if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE))
                tick_do_timer_cpu = cpu;
 #endif
 
@@ -622,7 +625,7 @@ void tick_setup_sched_timer(void)
         */
        hrtimer_init(&ts->sched_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
        ts->sched_timer.function = tick_sched_timer;
-       ts->sched_timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ;
+       ts->sched_timer.cb_mode = HRTIMER_CB_IRQSAFE_PERCPU;
 
        /* Get the next period (per cpu) */
        ts->sched_timer.expires = tick_init_jiffy_update();
index bb948e5..db58fb6 100644 (file)
@@ -202,7 +202,7 @@ static void start_stack_timer(int cpu)
 
        hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
        hrtimer->function = stack_trace_timer_fn;
-       hrtimer->cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ;
+       hrtimer->cb_mode = HRTIMER_CB_IRQSAFE_PERCPU;
 
        hrtimer_start(hrtimer, ns_to_ktime(sample_period), HRTIMER_MODE_REL);
 }
index 0f1f7a7..36896f3 100644 (file)
@@ -250,6 +250,14 @@ static struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont)
 
 struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p)
 {
+       /*
+        * mm_update_next_owner() may clear mm->owner to NULL
+        * if it races with swapoff, page migration, etc.
+        * So this can be called with p == NULL.
+        */
+       if (unlikely(!p))
+               return NULL;
+
        return container_of(task_subsys_state(p, mem_cgroup_subsys_id),
                                struct mem_cgroup, css);
 }
@@ -549,6 +557,11 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm,
        if (likely(!memcg)) {
                rcu_read_lock();
                mem = mem_cgroup_from_task(rcu_dereference(mm->owner));
+               if (unlikely(!mem)) {
+                       rcu_read_unlock();
+                       kmem_cache_free(page_cgroup_cache, pc);
+                       return 0;
+               }
                /*
                 * For every charge from the cgroup, increment reference count
                 */
@@ -801,11 +814,16 @@ int mem_cgroup_shrink_usage(struct mm_struct *mm, gfp_t gfp_mask)
 
        rcu_read_lock();
        mem = mem_cgroup_from_task(rcu_dereference(mm->owner));
+       if (unlikely(!mem)) {
+               rcu_read_unlock();
+               return 0;
+       }
        css_get(&mem->css);
        rcu_read_unlock();
 
        do {
                progress = try_to_free_mem_cgroup_pages(mem, gfp_mask);
+               progress += res_counter_check_under_limit(&mem->res);
        } while (!progress && --retry);
 
        css_put(&mem->css);
index e293c58..27b8681 100644 (file)
@@ -268,13 +268,14 @@ void prep_compound_page(struct page *page, unsigned long order)
 {
        int i;
        int nr_pages = 1 << order;
+       struct page *p = page + 1;
 
        set_compound_page_dtor(page, free_compound_page);
        set_compound_order(page, order);
        __SetPageHead(page);
-       for (i = 1; i < nr_pages; i++) {
-               struct page *p = page + i;
-
+       for (i = 1; i < nr_pages; i++, p++) {
+               if (unlikely((i & (MAX_ORDER_NR_PAGES - 1)) == 0))
+                       p = pfn_to_page(page_to_pfn(page) + i);
                __SetPageTail(p);
                p->first_page = page;
        }
@@ -284,6 +285,7 @@ static void destroy_compound_page(struct page *page, unsigned long order)
 {
        int i;
        int nr_pages = 1 << order;
+       struct page *p = page + 1;
 
        if (unlikely(compound_order(page) != order))
                bad_page(page);
@@ -291,8 +293,9 @@ static void destroy_compound_page(struct page *page, unsigned long order)
        if (unlikely(!PageHead(page)))
                        bad_page(page);
        __ClearPageHead(page);
-       for (i = 1; i < nr_pages; i++) {
-               struct page *p = page + i;
+       for (i = 1; i < nr_pages; i++, p++) {
+               if (unlikely((i & (MAX_ORDER_NR_PAGES - 1)) == 0))
+                       p = pfn_to_page(page_to_pfn(page) + i);
 
                if (unlikely(!PageTail(p) |
                                (p->first_page != page)))
index c69f84f..b70a7fe 100644 (file)
@@ -114,8 +114,10 @@ __test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn)
 
 int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn)
 {
-       unsigned long pfn;
+       unsigned long pfn, flags;
        struct page *page;
+       struct zone *zone;
+       int ret;
 
        pfn = start_pfn;
        /*
@@ -131,7 +133,9 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn)
        if (pfn < end_pfn)
                return -EBUSY;
        /* Check all pages are free or Marked as ISOLATED */
-       if (__test_page_isolated_in_pageblock(start_pfn, end_pfn))
-               return 0;
-       return -EBUSY;
+       zone = page_zone(pfn_to_page(pfn));
+       spin_lock_irqsave(&zone->lock, flags);
+       ret = __test_page_isolated_in_pageblock(start_pfn, end_pfn);
+       spin_unlock_irqrestore(&zone->lock, flags);
+       return ret ? 0 : -EBUSY;
 }
index 4c82dd4..cb675d1 100644 (file)
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -514,9 +514,11 @@ size_t ksize(const void *block)
                return 0;
 
        sp = (struct slob_page *)virt_to_page(block);
-       if (slob_page(sp))
-               return ((slob_t *)block - 1)->units + SLOB_UNIT;
-       else
+       if (slob_page(sp)) {
+               int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
+               unsigned int *m = (unsigned int *)(block - align);
+               return SLOB_UNITS(*m) * SLOB_UNIT;
+       } else
                return sp->page.private;
 }
 
index ae532f5..8d7a27a 100644 (file)
@@ -65,31 +65,31 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags)
        if (!dentry)
                goto put_memory;
 
+       error = -ENFILE;
+       file = get_empty_filp();
+       if (!file)
+               goto put_dentry;
+
        error = -ENOSPC;
        inode = ramfs_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0);
        if (!inode)
-               goto put_dentry;
+               goto close_file;
 
        d_instantiate(dentry, inode);
-       error = -ENFILE;
-       file = alloc_file(shm_mnt, dentry, FMODE_WRITE | FMODE_READ,
-                       &ramfs_file_operations);
-       if (!file)
-               goto put_dentry;
-
+       inode->i_size = size;
        inode->i_nlink = 0;     /* It is unlinked */
+       init_file(file, shm_mnt, dentry, FMODE_WRITE | FMODE_READ,
+                       &ramfs_file_operations);
 
-       /* notify everyone as to the change of file size */
-       error = do_truncate(dentry, size, 0, file);
-       if (error < 0)
+#ifndef CONFIG_MMU
+       error = ramfs_nommu_expand_for_mapping(inode, size);
+       if (error)
                goto close_file;
-
+#endif
        return file;
 
 close_file:
        put_filp(file);
-       return ERR_PTR(error);
-
 put_dentry:
        dput(dentry);
 put_memory:
index 2ffe40c..10e3203 100644 (file)
@@ -75,7 +75,6 @@ static int parse_opts(char *opts, struct p9_client *clnt)
        int option;
        int ret = 0;
 
-       clnt->trans_mod = v9fs_default_trans();
        clnt->dotu = 1;
        clnt->msize = 8192;
 
@@ -108,7 +107,7 @@ static int parse_opts(char *opts, struct p9_client *clnt)
                        clnt->msize = option;
                        break;
                case Opt_trans:
-                       clnt->trans_mod = v9fs_match_trans(&args[0]);
+                       clnt->trans_mod = v9fs_get_trans_by_name(&args[0]);
                        break;
                case Opt_legacy:
                        clnt->dotu = 0;
@@ -117,6 +116,10 @@ static int parse_opts(char *opts, struct p9_client *clnt)
                        continue;
                }
        }
+
+       if (!clnt->trans_mod)
+               clnt->trans_mod = v9fs_get_default_trans();
+
        kfree(options);
        return ret;
 }
@@ -150,6 +153,7 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
        if (!clnt)
                return ERR_PTR(-ENOMEM);
 
+       clnt->trans_mod = NULL;
        clnt->trans = NULL;
        spin_lock_init(&clnt->lock);
        INIT_LIST_HEAD(&clnt->fidlist);
@@ -235,6 +239,8 @@ void p9_client_destroy(struct p9_client *clnt)
                clnt->trans = NULL;
        }
 
+       v9fs_put_trans(clnt->trans_mod);
+
        list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist)
                p9_fid_destroy(fid);
 
index 4454720..5ad3a3b 100644 (file)
@@ -451,8 +451,10 @@ p9_put_data(struct cbuf *bufp, const char *data, int count,
                   unsigned char **pdata)
 {
        *pdata = buf_alloc(bufp, count);
+       if (*pdata == NULL)
+               return -ENOMEM;
        memmove(*pdata, data, count);
-       return count;
+       return 0;
 }
 
 static int
@@ -460,6 +462,8 @@ p9_put_user_data(struct cbuf *bufp, const char __user *data, int count,
                   unsigned char **pdata)
 {
        *pdata = buf_alloc(bufp, count);
+       if (*pdata == NULL)
+               return -ENOMEM;
        return copy_from_user(*pdata, data, count);
 }
 
index bdee1fb..1084feb 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/parser.h>
 #include <net/9p/transport.h>
 #include <linux/list.h>
+#include <linux/spinlock.h>
 
 #ifdef CONFIG_NET_9P_DEBUG
 unsigned int p9_debug_level = 0;       /* feature-rific global debug level  */
@@ -44,8 +45,8 @@ MODULE_PARM_DESC(debug, "9P debugging level");
  *
  */
 
+static DEFINE_SPINLOCK(v9fs_trans_lock);
 static LIST_HEAD(v9fs_trans_list);
-static struct p9_trans_module *v9fs_default_transport;
 
 /**
  * v9fs_register_trans - register a new transport with 9p
@@ -54,48 +55,87 @@ static struct p9_trans_module *v9fs_default_transport;
  */
 void v9fs_register_trans(struct p9_trans_module *m)
 {
+       spin_lock(&v9fs_trans_lock);
        list_add_tail(&m->list, &v9fs_trans_list);
-       if (m->def)
-               v9fs_default_transport = m;
+       spin_unlock(&v9fs_trans_lock);
 }
 EXPORT_SYMBOL(v9fs_register_trans);
 
 /**
- * v9fs_match_trans - match transport versus registered transports
+ * v9fs_unregister_trans - unregister a 9p transport
+ * @m: the transport to remove
+ *
+ */
+void v9fs_unregister_trans(struct p9_trans_module *m)
+{
+       spin_lock(&v9fs_trans_lock);
+       list_del_init(&m->list);
+       spin_unlock(&v9fs_trans_lock);
+}
+EXPORT_SYMBOL(v9fs_unregister_trans);
+
+/**
+ * v9fs_get_trans_by_name - get transport with the matching name
  * @name: string identifying transport
  *
  */
-struct p9_trans_module *v9fs_match_trans(const substring_t *name)
+struct p9_trans_module *v9fs_get_trans_by_name(const substring_t *name)
 {
-       struct list_head *p;
-       struct p9_trans_module *t = NULL;
-
-       list_for_each(p, &v9fs_trans_list) {
-               t = list_entry(p, struct p9_trans_module, list);
-               if (strncmp(t->name, name->from, name->to-name->from) == 0)
-                       return t;
-       }
-       return NULL;
+       struct p9_trans_module *t, *found = NULL;
+
+       spin_lock(&v9fs_trans_lock);
+
+       list_for_each_entry(t, &v9fs_trans_list, list)
+               if (strncmp(t->name, name->from, name->to-name->from) == 0 &&
+                   try_module_get(t->owner)) {
+                       found = t;
+                       break;
+               }
+
+       spin_unlock(&v9fs_trans_lock);
+       return found;
 }
-EXPORT_SYMBOL(v9fs_match_trans);
+EXPORT_SYMBOL(v9fs_get_trans_by_name);
 
 /**
- * v9fs_default_trans - returns pointer to default transport
+ * v9fs_get_default_trans - get the default transport
  *
  */
 
-struct p9_trans_module *v9fs_default_trans(void)
+struct p9_trans_module *v9fs_get_default_trans(void)
 {
-       if (v9fs_default_transport)
-               return v9fs_default_transport;
-       else if (!list_empty(&v9fs_trans_list))
-               return list_first_entry(&v9fs_trans_list,
-                                       struct p9_trans_module, list);
-       else
-               return NULL;
+       struct p9_trans_module *t, *found = NULL;
+
+       spin_lock(&v9fs_trans_lock);
+
+       list_for_each_entry(t, &v9fs_trans_list, list)
+               if (t->def && try_module_get(t->owner)) {
+                       found = t;
+                       break;
+               }
+
+       if (!found)
+               list_for_each_entry(t, &v9fs_trans_list, list)
+                       if (try_module_get(t->owner)) {
+                               found = t;
+                               break;
+                       }
+
+       spin_unlock(&v9fs_trans_lock);
+       return found;
 }
-EXPORT_SYMBOL(v9fs_default_trans);
+EXPORT_SYMBOL(v9fs_get_default_trans);
 
+/**
+ * v9fs_put_trans - put trans
+ * @m: transport to put
+ *
+ */
+void v9fs_put_trans(struct p9_trans_module *m)
+{
+       if (m)
+               module_put(m->owner);
+}
 
 /**
  * v9fs_init - Initialize module
@@ -120,6 +160,8 @@ static int __init init_p9(void)
 static void __exit exit_p9(void)
 {
        printk(KERN_INFO "Unloading 9P2000 support\n");
+
+       p9_trans_fd_exit();
 }
 
 module_init(init_p9)
index cdf137a..d652baf 100644 (file)
@@ -151,7 +151,6 @@ struct p9_mux_poll_task {
  * @trans: reference to transport instance for this connection
  * @tagpool: id accounting for transactions
  * @err: error state
- * @equeue: event wait_q (?)
  * @req_list: accounting for requests which have been sent
  * @unsent_req_list: accounting for requests that haven't been sent
  * @rcall: current response &p9_fcall structure
@@ -178,7 +177,6 @@ struct p9_conn {
        struct p9_trans *trans;
        struct p9_idpool *tagpool;
        int err;
-       wait_queue_head_t equeue;
        struct list_head req_list;
        struct list_head unsent_req_list;
        struct p9_fcall *rcall;
@@ -240,22 +238,6 @@ static int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc,
 
 static void p9_conn_cancel(struct p9_conn *m, int err);
 
-static int p9_mux_global_init(void)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++)
-               p9_mux_poll_tasks[i].task = NULL;
-
-       p9_mux_wq = create_workqueue("v9fs");
-       if (!p9_mux_wq) {
-               printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n");
-               return -ENOMEM;
-       }
-
-       return 0;
-}
-
 static u16 p9_mux_get_tag(struct p9_conn *m)
 {
        int tag;
@@ -409,11 +391,11 @@ static void p9_mux_poll_stop(struct p9_conn *m)
 static struct p9_conn *p9_conn_create(struct p9_trans *trans)
 {
        int i, n;
-       struct p9_conn *m, *mtmp;
+       struct p9_conn *m;
 
        P9_DPRINTK(P9_DEBUG_MUX, "transport %p msize %d\n", trans,
                                                                trans->msize);
-       m = kmalloc(sizeof(struct p9_conn), GFP_KERNEL);
+       m = kzalloc(sizeof(struct p9_conn), GFP_KERNEL);
        if (!m)
                return ERR_PTR(-ENOMEM);
 
@@ -424,25 +406,14 @@ static struct p9_conn *p9_conn_create(struct p9_trans *trans)
        m->trans = trans;
        m->tagpool = p9_idpool_create();
        if (IS_ERR(m->tagpool)) {
-               mtmp = ERR_PTR(-ENOMEM);
                kfree(m);
-               return mtmp;
+               return ERR_PTR(-ENOMEM);
        }
 
-       m->err = 0;
-       init_waitqueue_head(&m->equeue);
        INIT_LIST_HEAD(&m->req_list);
        INIT_LIST_HEAD(&m->unsent_req_list);
-       m->rcall = NULL;
-       m->rpos = 0;
-       m->rbuf = NULL;
-       m->wpos = m->wsize = 0;
-       m->wbuf = NULL;
        INIT_WORK(&m->rq, p9_read_work);
        INIT_WORK(&m->wq, p9_write_work);
-       m->wsched = 0;
-       memset(&m->poll_waddr, 0, sizeof(m->poll_waddr));
-       m->poll_task = NULL;
        n = p9_mux_poll_start(m);
        if (n) {
                kfree(m);
@@ -463,10 +434,8 @@ static struct p9_conn *p9_conn_create(struct p9_trans *trans)
        for (i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) {
                if (IS_ERR(m->poll_waddr[i])) {
                        p9_mux_poll_stop(m);
-                       mtmp = (void *)m->poll_waddr;   /* the error code */
                        kfree(m);
-                       m = mtmp;
-                       break;
+                       return (void *)m->poll_waddr;   /* the error code */
                }
        }
 
@@ -483,18 +452,13 @@ static void p9_conn_destroy(struct p9_conn *m)
 {
        P9_DPRINTK(P9_DEBUG_MUX, "mux %p prev %p next %p\n", m,
                m->mux_list.prev, m->mux_list.next);
-       p9_conn_cancel(m, -ECONNRESET);
-
-       if (!list_empty(&m->req_list)) {
-               /* wait until all processes waiting on this session exit */
-               P9_DPRINTK(P9_DEBUG_MUX,
-                       "mux %p waiting for empty request queue\n", m);
-               wait_event_timeout(m->equeue, (list_empty(&m->req_list)), 5000);
-               P9_DPRINTK(P9_DEBUG_MUX, "mux %p request queue empty: %d\n", m,
-                       list_empty(&m->req_list));
-       }
 
        p9_mux_poll_stop(m);
+       cancel_work_sync(&m->rq);
+       cancel_work_sync(&m->wq);
+
+       p9_conn_cancel(m, -ECONNRESET);
+
        m->trans = NULL;
        p9_idpool_destroy(m->tagpool);
        kfree(m);
@@ -840,8 +804,6 @@ static void p9_read_work(struct work_struct *work)
                                        (*req->cb) (req, req->cba);
                                else
                                        kfree(req->rcall);
-
-                               wake_up(&m->equeue);
                        }
                } else {
                        if (err >= 0 && rcall->id != P9_RFLUSH)
@@ -908,8 +870,10 @@ static struct p9_req *p9_send_request(struct p9_conn *m,
        else
                n = p9_mux_get_tag(m);
 
-       if (n < 0)
+       if (n < 0) {
+               kfree(req);
                return ERR_PTR(-ENOMEM);
+       }
 
        p9_set_tag(tc, n);
 
@@ -984,8 +948,6 @@ static void p9_mux_flush_cb(struct p9_req *freq, void *a)
                        (*req->cb) (req, req->cba);
                else
                        kfree(req->rcall);
-
-               wake_up(&m->equeue);
        }
 
        kfree(freq->tcall);
@@ -1191,8 +1153,6 @@ void p9_conn_cancel(struct p9_conn *m, int err)
                else
                        kfree(req->rcall);
        }
-
-       wake_up(&m->equeue);
 }
 
 /**
@@ -1370,7 +1330,6 @@ p9_fd_poll(struct p9_trans *trans, struct poll_table_struct *pt)
 {
        int ret, n;
        struct p9_trans_fd *ts = NULL;
-       mm_segment_t oldfs;
 
        if (trans && trans->status == Connected)
                ts = trans->priv;
@@ -1384,24 +1343,17 @@ p9_fd_poll(struct p9_trans *trans, struct poll_table_struct *pt)
        if (!ts->wr->f_op || !ts->wr->f_op->poll)
                return -EIO;
 
-       oldfs = get_fs();
-       set_fs(get_ds());
-
        ret = ts->rd->f_op->poll(ts->rd, pt);
        if (ret < 0)
-               goto end;
+               return ret;
 
        if (ts->rd != ts->wr) {
                n = ts->wr->f_op->poll(ts->wr, pt);
-               if (n < 0) {
-                       ret = n;
-                       goto end;
-               }
+               if (n < 0)
+                       return n;
                ret = (ret & ~POLLOUT) | (n & ~POLLIN);
        }
 
-end:
-       set_fs(oldfs);
        return ret;
 }
 
@@ -1629,6 +1581,7 @@ static struct p9_trans_module p9_tcp_trans = {
        .maxsize = MAX_SOCK_BUF,
        .def = 1,
        .create = p9_trans_create_tcp,
+       .owner = THIS_MODULE,
 };
 
 static struct p9_trans_module p9_unix_trans = {
@@ -1636,6 +1589,7 @@ static struct p9_trans_module p9_unix_trans = {
        .maxsize = MAX_SOCK_BUF,
        .def = 0,
        .create = p9_trans_create_unix,
+       .owner = THIS_MODULE,
 };
 
 static struct p9_trans_module p9_fd_trans = {
@@ -1643,14 +1597,20 @@ static struct p9_trans_module p9_fd_trans = {
        .maxsize = MAX_SOCK_BUF,
        .def = 0,
        .create = p9_trans_create_fd,
+       .owner = THIS_MODULE,
 };
 
 int p9_trans_fd_init(void)
 {
-       int ret = p9_mux_global_init();
-       if (ret) {
-               printk(KERN_WARNING "9p: starting mux failed\n");
-               return ret;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++)
+               p9_mux_poll_tasks[i].task = NULL;
+
+       p9_mux_wq = create_workqueue("v9fs");
+       if (!p9_mux_wq) {
+               printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n");
+               return -ENOMEM;
        }
 
        v9fs_register_trans(&p9_tcp_trans);
@@ -1659,4 +1619,12 @@ int p9_trans_fd_init(void)
 
        return 0;
 }
-EXPORT_SYMBOL(p9_trans_fd_init);
+
+void p9_trans_fd_exit(void)
+{
+       v9fs_unregister_trans(&p9_tcp_trans);
+       v9fs_unregister_trans(&p9_unix_trans);
+       v9fs_unregister_trans(&p9_fd_trans);
+
+       destroy_workqueue(p9_mux_wq);
+}
index 42adc05..94912e0 100644 (file)
@@ -528,6 +528,7 @@ static struct p9_trans_module p9_virtio_trans = {
        .create = p9_virtio_create,
        .maxsize = PAGE_SIZE*16,
        .def = 0,
+       .owner = THIS_MODULE,
 };
 
 /* The standard init function */
@@ -545,6 +546,7 @@ static int __init p9_virtio_init(void)
 static void __exit p9_virtio_cleanup(void)
 {
        unregister_virtio_driver(&p9_virtio_drv);
+       v9fs_unregister_trans(&p9_virtio_trans);
 }
 
 module_init(p9_virtio_init);
index 01c83e2..28c7157 100644 (file)
@@ -317,6 +317,9 @@ void ax25_destroy_socket(ax25_cb *ax25)
                                /* Queue the unaccepted socket for death */
                                sock_orphan(skb->sk);
 
+                               /* 9A4GL: hack to release unaccepted sockets */
+                               skb->sk->sk_state = TCP_LISTEN;
+
                                ax25_start_heartbeat(sax25);
                                sax25->state = AX25_STATE_0;
                        }
index cdc7e75..96e4b92 100644 (file)
@@ -39,9 +39,11 @@ void ax25_std_heartbeat_expiry(ax25_cb *ax25)
 
        switch (ax25->state) {
        case AX25_STATE_0:
-               if (!sk ||
-                   sock_flag(sk, SOCK_DESTROY) ||
-                   sock_flag(sk, SOCK_DEAD)) {
+               /* Magic here: If we listen() and a new link dies before it
+                  is accepted() it isn't 'dead' so doesn't get removed. */
+               if (!sk || sock_flag(sk, SOCK_DESTROY) ||
+                   (sk->sk_state == TCP_LISTEN &&
+                    sock_flag(sk, SOCK_DEAD))) {
                        if (sk) {
                                sock_hold(sk);
                                ax25_destroy_socket(ax25);
index e719ed2..0ae08d3 100644 (file)
 #include <linux/if_arp.h>
 #include <linux/if_vlan.h>
 #include <linux/ip.h>
+#include <net/ip.h>
 #include <linux/ipv6.h>
 #include <linux/in.h>
 #include <linux/jhash.h>
@@ -1667,7 +1668,7 @@ static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb)
 {
        u32 addr1, addr2, ports;
        u32 hash, ihl;
-       u8 ip_proto;
+       u8 ip_proto = 0;
 
        if (unlikely(!simple_tx_hashrnd_initialized)) {
                get_random_bytes(&simple_tx_hashrnd, 4);
@@ -1676,7 +1677,8 @@ static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb)
 
        switch (skb->protocol) {
        case __constant_htons(ETH_P_IP):
-               ip_proto = ip_hdr(skb)->protocol;
+               if (!(ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)))
+                       ip_proto = ip_hdr(skb)->protocol;
                addr1 = ip_hdr(skb)->saddr;
                addr2 = ip_hdr(skb)->daddr;
                ihl = ip_hdr(skb)->ihl;
@@ -2916,6 +2918,12 @@ int netdev_set_master(struct net_device *slave, struct net_device *master)
        return 0;
 }
 
+static void dev_change_rx_flags(struct net_device *dev, int flags)
+{
+       if (dev->flags & IFF_UP && dev->change_rx_flags)
+               dev->change_rx_flags(dev, flags);
+}
+
 static int __dev_set_promiscuity(struct net_device *dev, int inc)
 {
        unsigned short old_flags = dev->flags;
@@ -2953,8 +2961,7 @@ static int __dev_set_promiscuity(struct net_device *dev, int inc)
                                current->uid, current->gid,
                                audit_get_sessionid(current));
 
-               if (dev->change_rx_flags)
-                       dev->change_rx_flags(dev, IFF_PROMISC);
+               dev_change_rx_flags(dev, IFF_PROMISC);
        }
        return 0;
 }
@@ -3020,8 +3027,7 @@ int dev_set_allmulti(struct net_device *dev, int inc)
                }
        }
        if (dev->flags ^ old_flags) {
-               if (dev->change_rx_flags)
-                       dev->change_rx_flags(dev, IFF_ALLMULTI);
+               dev_change_rx_flags(dev, IFF_ALLMULTI);
                dev_set_rx_mode(dev);
        }
        return 0;
@@ -3345,8 +3351,8 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
         *      Load in the correct multicast list now the flags have changed.
         */
 
-       if (dev->change_rx_flags && (old_flags ^ flags) & IFF_MULTICAST)
-               dev->change_rx_flags(dev, IFF_MULTICAST);
+       if ((old_flags ^ flags) & IFF_MULTICAST)
+               dev_change_rx_flags(dev, IFF_MULTICAST);
 
        dev_set_rx_mode(dev);
 
@@ -3806,14 +3812,11 @@ static int dev_new_index(struct net *net)
 }
 
 /* Delayed registration/unregisteration */
-static DEFINE_SPINLOCK(net_todo_list_lock);
 static LIST_HEAD(net_todo_list);
 
 static void net_set_todo(struct net_device *dev)
 {
-       spin_lock(&net_todo_list_lock);
        list_add_tail(&dev->todo_list, &net_todo_list);
-       spin_unlock(&net_todo_list_lock);
 }
 
 static void rollback_registered(struct net_device *dev)
@@ -4140,33 +4143,24 @@ static void netdev_wait_allrefs(struct net_device *dev)
  *     free_netdev(y1);
  *     free_netdev(y2);
  *
- * We are invoked by rtnl_unlock() after it drops the semaphore.
+ * We are invoked by rtnl_unlock().
  * This allows us to deal with problems:
  * 1) We can delete sysfs objects which invoke hotplug
  *    without deadlocking with linkwatch via keventd.
  * 2) Since we run with the RTNL semaphore not held, we can sleep
  *    safely in order to wait for the netdev refcnt to drop to zero.
+ *
+ * We must not return until all unregister events added during
+ * the interval the lock was held have been completed.
  */
-static DEFINE_MUTEX(net_todo_run_mutex);
 void netdev_run_todo(void)
 {
        struct list_head list;
 
-       /* Need to guard against multiple cpu's getting out of order. */
-       mutex_lock(&net_todo_run_mutex);
-
-       /* Not safe to do outside the semaphore.  We must not return
-        * until all unregister events invoked by the local processor
-        * have been completed (either by this todo run, or one on
-        * another cpu).
-        */
-       if (list_empty(&net_todo_list))
-               goto out;
-
        /* Snapshot list, allow later requests */
-       spin_lock(&net_todo_list_lock);
        list_replace_init(&net_todo_list, &list);
-       spin_unlock(&net_todo_list_lock);
+
+       __rtnl_unlock();
 
        while (!list_empty(&list)) {
                struct net_device *dev
@@ -4198,9 +4192,6 @@ void netdev_run_todo(void)
                /* Free network device */
                kobject_put(&dev->dev.kobj);
        }
-
-out:
-       mutex_unlock(&net_todo_run_mutex);
 }
 
 static struct net_device_stats *internal_stats(struct net_device *dev)
index 71edb8b..d6381c2 100644 (file)
@@ -73,7 +73,7 @@ void __rtnl_unlock(void)
 
 void rtnl_unlock(void)
 {
-       mutex_unlock(&rtnl_mutex);
+       /* This fellow will unlock it for us. */
        netdev_run_todo();
 }
 
index bfcbd14..c209e05 100644 (file)
@@ -150,7 +150,11 @@ static void hybla_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
                ca->snd_cwnd_cents -= 128;
                tp->snd_cwnd_cnt = 0;
        }
-
+       /* check when cwnd has not been incremented for a while */
+       if (increment == 0 && odd == 0 && tp->snd_cwnd_cnt >= tp->snd_cwnd) {
+               tp->snd_cwnd++;
+               tp->snd_cwnd_cnt = 0;
+       }
        /* clamp down slowstart cwnd to ssthresh value. */
        if (is_slowstart)
                tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh);
index 67ccce2..7abc6b8 100644 (file)
@@ -4879,7 +4879,8 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
                                        goto no_ack;
                        }
 
-                       __tcp_ack_snd_check(sk, 0);
+                       if (!copied_early || tp->rcv_nxt != tp->rcv_wup)
+                               __tcp_ack_snd_check(sk, 0);
 no_ack:
 #ifdef CONFIG_NET_DMA
                        if (copied_early)
index 1b4fee2..011478e 100644 (file)
@@ -618,7 +618,7 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
                        ];
        } rep;
        struct ip_reply_arg arg;
-       struct net *net = dev_net(skb->dev);
+       struct net *net = dev_net(skb->dst->dev);
 
        memset(&rep.th, 0, sizeof(struct tcphdr));
        memset(&arg, 0, sizeof(arg));
index 8e42fbb..57e26fa 100644 (file)
@@ -951,6 +951,27 @@ int udp_disconnect(struct sock *sk, int flags)
        return 0;
 }
 
+static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
+{
+       int is_udplite = IS_UDPLITE(sk);
+       int rc;
+
+       if ((rc = sock_queue_rcv_skb(sk, skb)) < 0) {
+               /* Note that an ENOMEM error is charged twice */
+               if (rc == -ENOMEM)
+                       UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_RCVBUFERRORS,
+                                        is_udplite);
+               goto drop;
+       }
+
+       return 0;
+
+drop:
+       UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
+       kfree_skb(skb);
+       return -1;
+}
+
 /* returns:
  *  -1: error
  *   0: success
@@ -989,9 +1010,7 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
                    up->encap_rcv != NULL) {
                        int ret;
 
-                       bh_unlock_sock(sk);
                        ret = (*up->encap_rcv)(sk, skb);
-                       bh_lock_sock(sk);
                        if (ret <= 0) {
                                UDP_INC_STATS_BH(sock_net(sk),
                                                 UDP_MIB_INDATAGRAMS,
@@ -1044,17 +1063,16 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
                        goto drop;
        }
 
-       if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) {
-               /* Note that an ENOMEM error is charged twice */
-               if (rc == -ENOMEM) {
-                       UDP_INC_STATS_BH(sock_net(sk),
-                                       UDP_MIB_RCVBUFERRORS, is_udplite);
-                       atomic_inc(&sk->sk_drops);
-               }
-               goto drop;
-       }
+       rc = 0;
 
-       return 0;
+       bh_lock_sock(sk);
+       if (!sock_owned_by_user(sk))
+               rc = __udp_queue_rcv_skb(sk, skb);
+       else
+               sk_add_backlog(sk, skb);
+       bh_unlock_sock(sk);
+
+       return rc;
 
 drop:
        UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
@@ -1092,15 +1110,7 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
                                skb1 = skb_clone(skb, GFP_ATOMIC);
 
                        if (skb1) {
-                               int ret = 0;
-
-                               bh_lock_sock(sk);
-                               if (!sock_owned_by_user(sk))
-                                       ret = udp_queue_rcv_skb(sk, skb1);
-                               else
-                                       sk_add_backlog(sk, skb1);
-                               bh_unlock_sock(sk);
-
+                               int ret = udp_queue_rcv_skb(sk, skb1);
                                if (ret > 0)
                                        /* we should probably re-process instead
                                         * of dropping packets here. */
@@ -1195,13 +1205,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
                        uh->dest, inet_iif(skb), udptable);
 
        if (sk != NULL) {
-               int ret = 0;
-               bh_lock_sock(sk);
-               if (!sock_owned_by_user(sk))
-                       ret = udp_queue_rcv_skb(sk, skb);
-               else
-                       sk_add_backlog(sk, skb);
-               bh_unlock_sock(sk);
+               int ret = udp_queue_rcv_skb(sk, skb);
                sock_put(sk);
 
                /* a return value > 0 means to resubmit the input, but
@@ -1494,7 +1498,7 @@ struct proto udp_prot = {
        .sendmsg           = udp_sendmsg,
        .recvmsg           = udp_recvmsg,
        .sendpage          = udp_sendpage,
-       .backlog_rcv       = udp_queue_rcv_skb,
+       .backlog_rcv       = __udp_queue_rcv_skb,
        .hash              = udp_lib_hash,
        .unhash            = udp_lib_unhash,
        .get_port          = udp_v4_get_port,
index 62e39ac..26654b2 100644 (file)
@@ -97,8 +97,6 @@ hbh_mt6(const struct sk_buff *skb, const struct net_device *in,
        hdrlen -= 2;
        if (!(optinfo->flags & IP6T_OPTS_OPTS)) {
                return ret;
-       } else if (optinfo->flags & IP6T_OPTS_NSTRICT) {
-               pr_debug("Not strict - not implemented");
        } else {
                pr_debug("Strict ");
                pr_debug("#%d ", optinfo->optsnr);
@@ -177,6 +175,12 @@ hbh_mt6_check(const char *tablename, const void *entry,
                pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags);
                return false;
        }
+
+       if (optsinfo->flags & IP6T_OPTS_NSTRICT) {
+               pr_debug("ip6t_opts: Not strict - not implemented");
+               return false;
+       }
+
        return true;
 }
 
index 9af6115..63442a1 100644 (file)
@@ -2688,6 +2688,8 @@ int __init ip6_route_init(void)
        if (ret)
                goto out_kmem_cache;
 
+       ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep;
+
        /* Registering of the loopback is done before this portion of code,
         * the loopback reference in rt6_info will not be taken, do it
         * manually for init_net */
index b585c85..10e22fd 100644 (file)
@@ -1050,7 +1050,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
        struct tcphdr *th = tcp_hdr(skb), *t1;
        struct sk_buff *buff;
        struct flowi fl;
-       struct net *net = dev_net(skb->dev);
+       struct net *net = dev_net(skb->dst->dev);
        struct sock *ctl_sk = net->ipv6.tcp_sk;
        unsigned int tot_len = sizeof(struct tcphdr);
        __be32 *topt;
index 705959b..d7b54b5 100644 (file)
@@ -524,7 +524,6 @@ static int iucv_enable(void)
        get_online_cpus();
        for_each_online_cpu(cpu)
                smp_call_function_single(cpu, iucv_declare_cpu, NULL, 1);
-       preempt_enable();
        if (cpus_empty(iucv_buffer_cpumask))
                /* No cpu could declare an iucv buffer. */
                goto out_path;
@@ -547,7 +546,9 @@ out:
  */
 static void iucv_disable(void)
 {
+       get_online_cpus();
        on_each_cpu(iucv_retrieve_cpu, NULL, 1);
+       put_online_cpus();
        kfree(iucv_path_table);
 }
 
index d628df9..b7f5a1c 100644 (file)
@@ -73,22 +73,18 @@ static int pfkey_can_dump(struct sock *sk)
        return 0;
 }
 
-static int pfkey_do_dump(struct pfkey_sock *pfk)
+static void pfkey_terminate_dump(struct pfkey_sock *pfk)
 {
-       int rc;
-
-       rc = pfk->dump.dump(pfk);
-       if (rc == -ENOBUFS)
-               return 0;
-
-       pfk->dump.done(pfk);
-       pfk->dump.dump = NULL;
-       pfk->dump.done = NULL;
-       return rc;
+       if (pfk->dump.dump) {
+               pfk->dump.done(pfk);
+               pfk->dump.dump = NULL;
+               pfk->dump.done = NULL;
+       }
 }
 
 static void pfkey_sock_destruct(struct sock *sk)
 {
+       pfkey_terminate_dump(pfkey_sk(sk));
        skb_queue_purge(&sk->sk_receive_queue);
 
        if (!sock_flag(sk, SOCK_DEAD)) {
@@ -310,6 +306,18 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation,
        return err;
 }
 
+static int pfkey_do_dump(struct pfkey_sock *pfk)
+{
+       int rc;
+
+       rc = pfk->dump.dump(pfk);
+       if (rc == -ENOBUFS)
+               return 0;
+
+       pfkey_terminate_dump(pfk);
+       return rc;
+}
+
 static inline void pfkey_hdr_dup(struct sadb_msg *new, struct sadb_msg *orig)
 {
        *new = *orig;
index 532e4fa..9f1ea4a 100644 (file)
@@ -525,6 +525,7 @@ static int nr_release(struct socket *sock)
        if (sk == NULL) return 0;
 
        sock_hold(sk);
+       sock_orphan(sk);
        lock_sock(sk);
        nr = nr_sk(sk);
 
@@ -548,7 +549,6 @@ static int nr_release(struct socket *sock)
                sk->sk_state    = TCP_CLOSE;
                sk->sk_shutdown |= SEND_SHUTDOWN;
                sk->sk_state_change(sk);
-               sock_orphan(sk);
                sock_set_flag(sk, SOCK_DESTROY);
                break;
 
index 8472b8b..abd51ce 100644 (file)
@@ -599,11 +599,12 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
        /* Check to see if this is a duplicate. */
        peer = sctp_assoc_lookup_paddr(asoc, addr);
        if (peer) {
+               /* An UNKNOWN state is only set on transports added by
+                * user in sctp_connectx() call.  Such transports should be
+                * considered CONFIRMED per RFC 4960, Section 5.4.
+                */
                if (peer->state == SCTP_UNKNOWN) {
-                       if (peer_state == SCTP_ACTIVE)
-                               peer->state = SCTP_ACTIVE;
-                       if (peer_state == SCTP_UNCONFIRMED)
-                               peer->state = SCTP_UNCONFIRMED;
+                       peer->state = SCTP_ACTIVE;
                }
                return peer;
        }
index 0dc4a7d..225c712 100644 (file)
@@ -533,7 +533,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
        if (!(dst->dev->features & NETIF_F_NO_CSUM)) {
                crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len);
                crc32 = sctp_end_cksum(crc32);
-       }
+       } else
+               nskb->ip_summed = CHECKSUM_UNNECESSARY;
 
        /* 3) Put the resultant value into the checksum field in the
         *    common header, and leave the rest of the bits unchanged.
index e8ca4e5..d68869f 100644 (file)
@@ -1012,6 +1012,29 @@ end:
        return retval;
 }
 
+struct sctp_chunk *sctp_make_violation_paramlen(
+       const struct sctp_association *asoc,
+       const struct sctp_chunk *chunk,
+       struct sctp_paramhdr *param)
+{
+       struct sctp_chunk *retval;
+       static const char error[] = "The following parameter had invalid length:";
+       size_t payload_len = sizeof(error) + sizeof(sctp_errhdr_t) +
+                               sizeof(sctp_paramhdr_t);
+
+       retval = sctp_make_abort(asoc, chunk, payload_len);
+       if (!retval)
+               goto nodata;
+
+       sctp_init_cause(retval, SCTP_ERROR_PROTO_VIOLATION,
+                       sizeof(error) + sizeof(sctp_paramhdr_t));
+       sctp_addto_chunk(retval, sizeof(error), error);
+       sctp_addto_param(retval, sizeof(sctp_paramhdr_t), param);
+
+nodata:
+       return retval;
+}
+
 /* Make a HEARTBEAT chunk.  */
 struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc,
                                  const struct sctp_transport *transport,
@@ -1782,11 +1805,6 @@ static int sctp_process_inv_paramlength(const struct sctp_association *asoc,
                                        const struct sctp_chunk *chunk,
                                        struct sctp_chunk **errp)
 {
-       static const char error[] = "The following parameter had invalid length:";
-       size_t          payload_len = WORD_ROUND(sizeof(error)) +
-                                               sizeof(sctp_paramhdr_t);
-
-
        /* This is a fatal error.  Any accumulated non-fatal errors are
         * not reported.
         */
@@ -1794,14 +1812,7 @@ static int sctp_process_inv_paramlength(const struct sctp_association *asoc,
                sctp_chunk_free(*errp);
 
        /* Create an error chunk and fill it in with our payload. */
-       *errp = sctp_make_op_error_space(asoc, chunk, payload_len);
-
-       if (*errp) {
-               sctp_init_cause(*errp, SCTP_ERROR_PROTO_VIOLATION,
-                               sizeof(error) + sizeof(sctp_paramhdr_t));
-               sctp_addto_chunk(*errp, sizeof(error), error);
-               sctp_addto_param(*errp, sizeof(sctp_paramhdr_t), param);
-       }
+       *errp = sctp_make_violation_paramlen(asoc, chunk, param);
 
        return 0;
 }
@@ -1886,11 +1897,13 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
                            /* if the peer reports AUTH, assume that he
                             * supports AUTH.
                             */
-                           asoc->peer.auth_capable = 1;
+                           if (sctp_auth_enable)
+                                   asoc->peer.auth_capable = 1;
                            break;
                    case SCTP_CID_ASCONF:
                    case SCTP_CID_ASCONF_ACK:
-                           asoc->peer.asconf_capable = 1;
+                           if (sctp_addip_enable)
+                                   asoc->peer.asconf_capable = 1;
                            break;
                    default:
                            break;
@@ -2319,12 +2332,10 @@ clean_up:
        /* Release the transport structures. */
        list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
                transport = list_entry(pos, struct sctp_transport, transports);
-               list_del_init(pos);
-               sctp_transport_free(transport);
+               if (transport->state != SCTP_ACTIVE)
+                       sctp_assoc_rm_peer(asoc, transport);
        }
 
-       asoc->peer.transport_count = 0;
-
 nomem:
        return 0;
 }
@@ -2460,6 +2471,9 @@ do_addr_param:
                break;
 
        case SCTP_PARAM_SET_PRIMARY:
+               if (!sctp_addip_enable)
+                       goto fall_through;
+
                addr_param = param.v + sizeof(sctp_addip_param_t);
 
                af = sctp_get_af_specific(param_type2af(param.p->type));
index 8848d32..7c622af 100644 (file)
@@ -119,7 +119,7 @@ static sctp_disposition_t sctp_sf_violation_paramlen(
                                     const struct sctp_endpoint *ep,
                                     const struct sctp_association *asoc,
                                     const sctp_subtype_t type,
-                                    void *arg,
+                                    void *arg, void *ext,
                                     sctp_cmd_seq_t *commands);
 
 static sctp_disposition_t sctp_sf_violation_ctsn(
@@ -3425,7 +3425,7 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
        addr_param = (union sctp_addr_param *)hdr->params;
        length = ntohs(addr_param->p.length);
        if (length < sizeof(sctp_paramhdr_t))
-               return sctp_sf_violation_paramlen(ep, asoc, type,
+               return sctp_sf_violation_paramlen(ep, asoc, type, arg,
                           (void *)addr_param, commands);
 
        /* Verify the ASCONF chunk before processing it. */
@@ -3433,8 +3433,8 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
                            (sctp_paramhdr_t *)((void *)addr_param + length),
                            (void *)chunk->chunk_end,
                            &err_param))
-               return sctp_sf_violation_paramlen(ep, asoc, type,
-                                                 (void *)&err_param, commands);
+               return sctp_sf_violation_paramlen(ep, asoc, type, arg,
+                                                 (void *)err_param, commands);
 
        /* ADDIP 5.2 E1) Compare the value of the serial number to the value
         * the endpoint stored in a new association variable
@@ -3542,8 +3542,8 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
            (sctp_paramhdr_t *)addip_hdr->params,
            (void *)asconf_ack->chunk_end,
            &err_param))
-               return sctp_sf_violation_paramlen(ep, asoc, type,
-                          (void *)&err_param, commands);
+               return sctp_sf_violation_paramlen(ep, asoc, type, arg,
+                          (void *)err_param, commands);
 
        if (last_asconf) {
                addip_hdr = (sctp_addiphdr_t *)last_asconf->subh.addip_hdr;
@@ -4240,12 +4240,38 @@ static sctp_disposition_t sctp_sf_violation_paramlen(
                                     const struct sctp_endpoint *ep,
                                     const struct sctp_association *asoc,
                                     const sctp_subtype_t type,
-                                    void *arg,
-                                    sctp_cmd_seq_t *commands) {
-       static const char err_str[] = "The following parameter had invalid length:";
+                                    void *arg, void *ext,
+                                    sctp_cmd_seq_t *commands)
+{
+       struct sctp_chunk *chunk =  arg;
+       struct sctp_paramhdr *param = ext;
+       struct sctp_chunk *abort = NULL;
 
-       return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str,
-                                       sizeof(err_str));
+       if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc))
+               goto discard;
+
+       /* Make the abort chunk. */
+       abort = sctp_make_violation_paramlen(asoc, chunk, param);
+       if (!abort)
+               goto nomem;
+
+       sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
+       SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
+
+       sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
+                       SCTP_ERROR(ECONNABORTED));
+       sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
+                       SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION));
+       SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
+
+discard:
+       sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands);
+
+       SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
+
+       return SCTP_DISPOSITION_ABORT;
+nomem:
+       return SCTP_DISPOSITION_NOMEM;
 }
 
 /* Handle a protocol violation when the peer trying to advance the
index 8ef8ba8..3e8d4e3 100644 (file)
@@ -1511,6 +1511,7 @@ out_fd:
        goto out_put;
 }
 
+#if 0
 #ifdef HAVE_SET_RESTORE_SIGMASK
 asmlinkage long sys_paccept(int fd, struct sockaddr __user *upeer_sockaddr,
                            int __user *upeer_addrlen,
@@ -1564,6 +1565,7 @@ asmlinkage long sys_paccept(int fd, struct sockaddr __user *upeer_sockaddr,
        return do_accept(fd, upeer_sockaddr, upeer_addrlen, flags);
 }
 #endif
+#endif
 
 asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr,
                           int __user *upeer_addrlen)
index ac25b4c..dc50f1e 100644 (file)
@@ -27,10 +27,14 @@ static int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb)
                - skb_headroom(skb);
        int ntail = dst->dev->needed_tailroom - skb_tailroom(skb);
 
-       if (nhead > 0 || ntail > 0)
-               return pskb_expand_head(skb, nhead, ntail, GFP_ATOMIC);
-
-       return 0;
+       if (nhead <= 0) {
+               if (ntail <= 0)
+                       return 0;
+               nhead = 0;
+       } else if (ntail < 0)
+               ntail = 0;
+
+       return pskb_expand_head(skb, nhead, ntail, GFP_ATOMIC);
 }
 
 static int xfrm_output_one(struct sk_buff *skb, int err)
index 36b5eed..3e1057f 100644 (file)
@@ -32,6 +32,7 @@ char *defconfig_file;
 
 static int indent = 1;
 static int valid_stdin = 1;
+static int sync_kconfig;
 static int conf_cnt;
 static char line[128];
 static struct menu *rootEntry;
@@ -65,7 +66,7 @@ static void strip(char *str)
 
 static void check_stdin(void)
 {
-       if (!valid_stdin && input_mode == ask_silent) {
+       if (!valid_stdin) {
                printf(_("aborted!\n\n"));
                printf(_("Console input/output is redirected. "));
                printf(_("Run 'make oldconfig' to update configuration.\n\n"));
@@ -427,43 +428,6 @@ static void check_conf(struct menu *menu)
                check_conf(child);
 }
 
-static void conf_do_update(void)
-{
-       /* Update until a loop caused no more changes */
-       do {
-               conf_cnt = 0;
-               check_conf(&rootmenu);
-       } while (conf_cnt);
-}
-
-static int conf_silent_update(void)
-{
-       const char *name;
-
-       if (conf_get_changed()) {
-               name = getenv("KCONFIG_NOSILENTUPDATE");
-               if (name && *name) {
-                       fprintf(stderr,
-                       _("\n*** Kernel configuration requires explicit update.\n\n"));
-                       return 1;
-               }
-               conf_do_update();
-       }
-       return 0;
-}
-
-static int conf_update(void)
-{
-       rootEntry = &rootmenu;
-       conf(&rootmenu);
-       if (input_mode == ask_all) {
-               input_mode = ask_silent;
-               valid_stdin = 1;
-       }
-       conf_do_update();
-       return 0;
-}
-
 int main(int ac, char **av)
 {
        int opt;
@@ -477,11 +441,11 @@ int main(int ac, char **av)
        while ((opt = getopt(ac, av, "osdD:nmyrh")) != -1) {
                switch (opt) {
                case 'o':
-                       input_mode = ask_new;
+                       input_mode = ask_silent;
                        break;
                case 's':
                        input_mode = ask_silent;
-                       valid_stdin = isatty(0) && isatty(1) && isatty(2);
+                       sync_kconfig = 1;
                        break;
                case 'd':
                        input_mode = set_default;
@@ -519,6 +483,19 @@ int main(int ac, char **av)
        name = av[optind];
        conf_parse(name);
        //zconfdump(stdout);
+       if (sync_kconfig) {
+               if (stat(".config", &tmpstat)) {
+                       fprintf(stderr, _("***\n"
+                               "*** You have not yet configured your kernel!\n"
+                               "*** (missing kernel .config file)\n"
+                               "***\n"
+                               "*** Please run some configurator (e.g. \"make oldconfig\" or\n"
+                               "*** \"make menuconfig\" or \"make xconfig\").\n"
+                               "***\n"));
+                       exit(1);
+               }
+       }
+
        switch (input_mode) {
        case set_default:
                if (!defconfig_file)
@@ -531,16 +508,6 @@ int main(int ac, char **av)
                }
                break;
        case ask_silent:
-               if (stat(".config", &tmpstat)) {
-                       printf(_("***\n"
-                               "*** You have not yet configured your kernel!\n"
-                               "*** (missing kernel .config file)\n"
-                               "***\n"
-                               "*** Please run some configurator (e.g. \"make oldconfig\" or\n"
-                               "*** \"make menuconfig\" or \"make xconfig\").\n"
-                               "***\n"));
-                       exit(1);
-               }
        case ask_all:
        case ask_new:
                conf_read(NULL);
@@ -569,6 +536,19 @@ int main(int ac, char **av)
        default:
                break;
        }
+
+       if (sync_kconfig) {
+               if (conf_get_changed()) {
+                       name = getenv("KCONFIG_NOSILENTUPDATE");
+                       if (name && *name) {
+                               fprintf(stderr,
+                                       _("\n*** Kernel configuration requires explicit update.\n\n"));
+                               return 1;
+                       }
+               }
+               valid_stdin = isatty(0) && isatty(1) && isatty(2);
+       }
+
        switch (input_mode) {
        case set_no:
                conf_set_all_new_symbols(def_no);
@@ -585,27 +565,38 @@ int main(int ac, char **av)
        case set_default:
                conf_set_all_new_symbols(def_default);
                break;
-       case ask_silent:
        case ask_new:
-               if (conf_silent_update())
-                       exit(1);
-               break;
        case ask_all:
-               if (conf_update())
-                       exit(1);
+               rootEntry = &rootmenu;
+               conf(&rootmenu);
+               input_mode = ask_silent;
+               /* fall through */
+       case ask_silent:
+               /* Update until a loop caused no more changes */
+               do {
+                       conf_cnt = 0;
+                       check_conf(&rootmenu);
+               } while (conf_cnt);
                break;
        }
 
-       if (conf_write(NULL)) {
-               fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
-               exit(1);
-       }
-       /* ask_silent is used during the build so we shall update autoconf.
-        * All other commands are only used to generate a config.
-        */
-       if (input_mode == ask_silent && conf_write_autoconf()) {
-               fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
-               return 1;
+       if (sync_kconfig) {
+               /* silentoldconfig is used during the build so we shall update autoconf.
+                * All other commands are only used to generate a config.
+                */
+               if (conf_get_changed() && conf_write(NULL)) {
+                       fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
+                       exit(1);
+               }
+               if (conf_write_autoconf()) {
+                       fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n"));
+                       return 1;
+               }
+       } else {
+               if (conf_write(NULL)) {
+                       fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
+                       exit(1);
+               }
        }
        return 0;
 }
index df6a188..b91cf24 100644 (file)
@@ -222,8 +222,10 @@ load:
                                continue;
                        if (def == S_DEF_USER) {
                                sym = sym_find(line + 9);
-                               if (!sym)
+                               if (!sym) {
+                                       sym_add_change_count(1);
                                        break;
+                               }
                        } else {
                                sym = sym_lookup(line + 9, 0);
                                if (sym->type == S_UNKNOWN)
@@ -259,8 +261,10 @@ load:
                        }
                        if (def == S_DEF_USER) {
                                sym = sym_find(line + 7);
-                               if (!sym)
+                               if (!sym) {
+                                       sym_add_change_count(1);
                                        break;
+                               }
                        } else {
                                sym = sym_lookup(line + 7, 0);
                                if (sym->type == S_UNKNOWN)
index ff787e6..44ee94d 100755 (executable)
@@ -781,6 +781,7 @@ sub output_struct_xml(%) {
     print " <refsect1>\n";
     print "  <title>Members</title>\n";
 
+    if ($#{$args{'parameterlist'}} >= 0) {
     print "  <variablelist>\n";
     foreach $parameter (@{$args{'parameterlist'}}) {
       ($parameter =~ /^#/) && next;
@@ -798,6 +799,9 @@ sub output_struct_xml(%) {
       print "    </varlistentry>\n";
     }
     print "  </variablelist>\n";
+    } else {
+       print " <para>\n  None\n </para>\n";
+    }
     print " </refsect1>\n";
 
     output_section_xml(@_);
index 418cd7d..8e0de6a 100644 (file)
@@ -1986,11 +1986,13 @@ static void read_markers(const char *fname)
 
                mod = find_module(modname);
                if (!mod) {
-                       if (is_vmlinux(modname))
-                               have_vmlinux = 1;
                        mod = new_module(NOFAIL(strdup(modname)));
                        mod->skip = 1;
                }
+               if (is_vmlinux(modname)) {
+                       have_vmlinux = 1;
+                       mod->skip = 0;
+               }
 
                if (!mod->skip)
                        add_marker(mod, marker, fmt);
index d11a815..8551952 100644 (file)
@@ -2737,6 +2737,7 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
                if (ctx == NULL)
                        goto netlbl_secattr_to_sid_return;
 
+               context_init(&ctx_new);
                ctx_new.user = ctx->user;
                ctx_new.role = ctx->role;
                ctx_new.type = ctx->type;
@@ -2745,13 +2746,9 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
                        if (ebitmap_netlbl_import(&ctx_new.range.level[0].cat,
                                                  secattr->attr.mls.cat) != 0)
                                goto netlbl_secattr_to_sid_return;
-                       ctx_new.range.level[1].cat.highbit =
-                               ctx_new.range.level[0].cat.highbit;
-                       ctx_new.range.level[1].cat.node =
-                               ctx_new.range.level[0].cat.node;
-               } else {
-                       ebitmap_init(&ctx_new.range.level[0].cat);
-                       ebitmap_init(&ctx_new.range.level[1].cat);
+                       memcpy(&ctx_new.range.level[1].cat,
+                              &ctx_new.range.level[0].cat,
+                              sizeof(ctx_new.range.level[0].cat));
                }
                if (mls_context_isvalid(&policydb, &ctx_new) != 1)
                        goto netlbl_secattr_to_sid_return_cleanup;
index 9dd9bc7..ece25c7 100644 (file)
@@ -781,7 +781,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
                return -ENODEV;
 
        card = pcm->card;
-       down_read(&card->controls_rwsem);
+       read_lock(&card->ctl_files_rwlock);
        list_for_each_entry(kctl, &card->ctl_files, list) {
                if (kctl->pid == current->pid) {
                        prefer_subdevice = kctl->prefer_pcm_subdevice;
@@ -789,7 +789,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
                                break;
                }
        }
-       up_read(&card->controls_rwsem);
+       read_unlock(&card->ctl_files_rwlock);
 
        switch (stream) {
        case SNDRV_PCM_STREAM_PLAYBACK:
index c49b9d9..c487025 100644 (file)
@@ -1546,16 +1546,10 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream)
        card = substream->pcm->card;
 
        if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
-           runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
+           runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED ||
+           runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
                return -EBADFD;
 
-       snd_power_lock(card);
-       if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
-               result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
-               if (result < 0)
-                       goto _unlock;
-       }
-
        snd_pcm_stream_lock_irq(substream);
        /* resume pause */
        if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
@@ -1564,8 +1558,7 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream)
        snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
        /* runtime->control->appl_ptr = runtime->status->hw_ptr; */
        snd_pcm_stream_unlock_irq(substream);
- _unlock:
-       snd_power_unlock(card);
+
        return result;
 }
 
index f7ea728..b917a9f 100644 (file)
@@ -418,7 +418,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
        mutex_lock(&rmidi->open_mutex);
        while (1) {
                subdevice = -1;
-               down_read(&card->controls_rwsem);
+               read_lock(&card->ctl_files_rwlock);
                list_for_each_entry(kctl, &card->ctl_files, list) {
                        if (kctl->pid == current->pid) {
                                subdevice = kctl->prefer_rawmidi_subdevice;
@@ -426,7 +426,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
                                        break;
                        }
                }
-               up_read(&card->controls_rwsem);
+               read_unlock(&card->ctl_files_rwlock);
                err = snd_rawmidi_kernel_open(rmidi->card, rmidi->device,
                                              subdevice, fflags, rawmidi_file);
                if (err >= 0)
index ad994fc..f3da621 100644 (file)
@@ -1683,8 +1683,8 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = {
        /* Dell 3 stack systems with verb table in BIOS */
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL,  0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL,  0x0227, "Dell Vostro 1400  ", STAC_DELL_BIOS),
-       SND_PCI_QUIRK(PCI_VENDOR_ID_DELL,  0x022f, "Dell     ", STAC_DELL_BIOS),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL,  0x022e, "Dell     ", STAC_DELL_BIOS),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_DELL,  0x022f, "Dell Inspiron 1525", STAC_DELL_3ST),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL,  0x0242, "Dell     ", STAC_DELL_BIOS),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL,  0x0243, "Dell     ", STAC_DELL_BIOS),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL,  0x02ff, "Dell     ", STAC_DELL_BIOS),
index 566a6d0..106c482 100644 (file)
@@ -621,6 +621,13 @@ static struct snd_kcontrol_new snd_pmac_screamer_mixers_imac[] __initdata = {
        AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
 };
 
+static struct snd_kcontrol_new snd_pmac_screamer_mixers_g4agp[] __initdata = {
+       AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
+       AWACS_VOLUME("Master Playback Volume", 5, 6, 1),
+       AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
+       AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
+};
+
 static struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac7500[] __initdata = {
        AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
        AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
@@ -688,7 +695,10 @@ static struct snd_kcontrol_new snd_pmac_awacs_speaker_vol[] __initdata = {
 static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw __initdata =
 AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1);
 
-static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac __initdata =
+static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac1 __initdata =
+AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_PAROUT1, 1);
+
+static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac2 __initdata =
 AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_PAROUT1, 0);
 
 
@@ -765,11 +775,12 @@ static void snd_pmac_awacs_resume(struct snd_pmac *chip)
 
 #define IS_PM7500 (machine_is_compatible("AAPL,7500"))
 #define IS_BEIGE (machine_is_compatible("AAPL,Gossamer"))
-#define IS_IMAC (machine_is_compatible("PowerMac2,1") \
-               || machine_is_compatible("PowerMac2,2") \
+#define IS_IMAC1 (machine_is_compatible("PowerMac2,1"))
+#define IS_IMAC2 (machine_is_compatible("PowerMac2,2") \
                || machine_is_compatible("PowerMac4,1"))
+#define IS_G4AGP (machine_is_compatible("PowerMac3,1"))
 
-static int imac;
+static int imac1, imac2;
 
 #ifdef PMAC_SUPPORT_AUTOMUTE
 /*
@@ -815,13 +826,18 @@ static void snd_pmac_awacs_update_automute(struct snd_pmac *chip, int do_notify)
                {
                        int reg = chip->awacs_reg[1]
                                | (MASK_HDMUTE | MASK_SPKMUTE);
-                       if (imac) {
+                       if (imac1) {
+                               reg &= ~MASK_SPKMUTE;
+                               reg |= MASK_PAROUT1;
+                       } else if (imac2) {
                                reg &= ~MASK_SPKMUTE;
                                reg &= ~MASK_PAROUT1;
                        }
                        if (snd_pmac_awacs_detect_headphone(chip))
                                reg &= ~MASK_HDMUTE;
-                       else if (imac)
+                       else if (imac1)
+                               reg &= ~MASK_PAROUT1;
+                       else if (imac2)
                                reg |= MASK_PAROUT1;
                        else
                                reg &= ~MASK_SPKMUTE;
@@ -850,9 +866,13 @@ snd_pmac_awacs_init(struct snd_pmac *chip)
 {
        int pm7500 = IS_PM7500;
        int beige = IS_BEIGE;
+       int g4agp = IS_G4AGP;
+       int imac;
        int err, vol;
 
-       imac = IS_IMAC;
+       imac1 = IS_IMAC1;
+       imac2 = IS_IMAC2;
+       imac = imac1 || imac2;
        /* looks like MASK_GAINLINE triggers something, so we set here
         * as start-up
         */
@@ -939,7 +959,7 @@ snd_pmac_awacs_init(struct snd_pmac *chip)
                                snd_pmac_awacs_mixers);
        if (err < 0)
                return err;
-       if (beige)
+       if (beige || g4agp)
                ;
        else if (chip->model == PMAC_SCREAMER)
                err = build_mixers(chip, ARRAY_SIZE(snd_pmac_screamer_mixers2),
@@ -961,13 +981,17 @@ snd_pmac_awacs_init(struct snd_pmac *chip)
                err = build_mixers(chip,
                                   ARRAY_SIZE(snd_pmac_screamer_mixers_imac),
                                   snd_pmac_screamer_mixers_imac);
+       else if (g4agp)
+               err = build_mixers(chip,
+                                  ARRAY_SIZE(snd_pmac_screamer_mixers_g4agp),
+                                  snd_pmac_screamer_mixers_g4agp);
        else
                err = build_mixers(chip,
                                   ARRAY_SIZE(snd_pmac_awacs_mixers_pmac),
                                   snd_pmac_awacs_mixers_pmac);
        if (err < 0)
                return err;
-       chip->master_sw_ctl = snd_ctl_new1((pm7500 || imac)
+       chip->master_sw_ctl = snd_ctl_new1((pm7500 || imac || g4agp)
                        ? &snd_pmac_awacs_master_sw_imac
                        : &snd_pmac_awacs_master_sw, chip);
        err = snd_ctl_add(chip->card, chip->master_sw_ctl);
@@ -1004,15 +1028,17 @@ snd_pmac_awacs_init(struct snd_pmac *chip)
                                        snd_pmac_awacs_speaker_vol);
                if (err < 0)
                        return err;
-               chip->speaker_sw_ctl = snd_ctl_new1(imac
-                               ? &snd_pmac_awacs_speaker_sw_imac
+               chip->speaker_sw_ctl = snd_ctl_new1(imac1
+                               ? &snd_pmac_awacs_speaker_sw_imac1
+                               : imac2
+                               ? &snd_pmac_awacs_speaker_sw_imac2
                                : &snd_pmac_awacs_speaker_sw, chip);
                err = snd_ctl_add(chip->card, chip->speaker_sw_ctl);
                if (err < 0)
                        return err;
        }
 
-       if (beige)
+       if (beige || g4agp)
                err = build_mixers(chip,
                                ARRAY_SIZE(snd_pmac_screamer_mic_boost_beige),
                                snd_pmac_screamer_mic_boost_beige);
index 435f1da..c83584f 100644 (file)
@@ -434,7 +434,8 @@ static int at32_pcm_suspend(struct platform_device *pdev,
        params = prtd->params;
 
        /* Disable the PDC and save the PDC registers */
-       ssc_writex(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable);
+       ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
+                  params->mask->pdc_disable);
 
        prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr);
        prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr);
@@ -464,7 +465,7 @@ static int at32_pcm_resume(struct platform_device *pdev,
        ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save);
        ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save);
 
-       ssc_writex(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable);
+       ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, params->mask->pdc_enable);
        return 0;
 }
 #else /* CONFIG_PM */
index 9deb8c7..0bbd945 100644 (file)
@@ -490,34 +490,7 @@ static int cs4270_mute(struct snd_soc_dai *dai, int mute)
 
 #endif
 
-static int cs4270_i2c_probe(struct i2c_adapter *adap, int addr, int kind);
-
-/*
- * Notify the driver that a new I2C bus has been found.
- *
- * This function is called for each I2C bus in the system.  The function
- * then asks the I2C subsystem to probe that bus at the addresses on which
- * our device (the CS4270) could exist.  If a device is found at one of
- * those addresses, then our probe function (cs4270_i2c_probe) is called.
- */
-static int cs4270_i2c_attach(struct i2c_adapter *adapter)
-{
-       return i2c_probe(adapter, &addr_data, cs4270_i2c_probe);
-}
-
-static int cs4270_i2c_detach(struct i2c_client *client)
-{
-       struct snd_soc_codec *codec = i2c_get_clientdata(client);
-
-       i2c_detach_client(client);
-       codec->control_data = NULL;
-
-       kfree(codec->reg_cache);
-       codec->reg_cache = NULL;
-
-       kfree(client);
-       return 0;
-}
+static int cs4270_i2c_probe(struct i2c_client *, const struct i2c_device_id *);
 
 /* A list of non-DAPM controls that the CS4270 supports */
 static const struct snd_kcontrol_new cs4270_snd_controls[] = {
@@ -525,14 +498,19 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
                CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1)
 };
 
+static const struct i2c_device_id cs4270_id[] = {
+       {"cs4270", 0},
+       {}
+};
+MODULE_DEVICE_TABLE(i2c, cs4270_id);
+
 static struct i2c_driver cs4270_i2c_driver = {
        .driver = {
                .name = "CS4270 I2C",
                .owner = THIS_MODULE,
        },
-       .id =             I2C_DRIVERID_CS4270,
-       .attach_adapter = cs4270_i2c_attach,
-       .detach_client =  cs4270_i2c_detach,
+       .id_table = cs4270_id,
+       .probe = cs4270_i2c_probe,
 };
 
 /*
@@ -561,11 +539,11 @@ static struct snd_soc_device *cs4270_socdev;
  * Note: snd_soc_new_pcms() must be called before this function can be called,
  * because of snd_ctl_add().
  */
-static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
+static int cs4270_i2c_probe(struct i2c_client *i2c_client,
+       const struct i2c_device_id *id)
 {
        struct snd_soc_device *socdev = cs4270_socdev;
        struct snd_soc_codec *codec = socdev->codec;
-       struct i2c_client *i2c_client = NULL;
        int i;
        int ret = 0;
 
@@ -578,12 +556,6 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
 
        /* Note: codec_dai->codec is NULL here */
 
-       i2c_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (!i2c_client) {
-               printk(KERN_ERR "cs4270: could not allocate I2C client\n");
-               return -ENOMEM;
-       }
-
        codec->reg_cache = kzalloc(CS4270_NUMREGS, GFP_KERNEL);
        if (!codec->reg_cache) {
                printk(KERN_ERR "cs4270: could not allocate register cache\n");
@@ -591,13 +563,6 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
                goto error;
        }
 
-       i2c_set_clientdata(i2c_client, codec);
-       strcpy(i2c_client->name, "CS4270");
-
-       i2c_client->driver = &cs4270_i2c_driver;
-       i2c_client->adapter = adapter;
-       i2c_client->addr = addr;
-
        /* Verify that we have a CS4270 */
 
        ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
@@ -612,18 +577,10 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
                goto error;
        }
 
-       printk(KERN_INFO "cs4270: found device at I2C address %X\n", addr);
+       printk(KERN_INFO "cs4270: found device at I2C address %X\n",
+               i2c_client->addr);
        printk(KERN_INFO "cs4270: hardware revision %X\n", ret & 0xF);
 
-       /* Tell the I2C layer a new client has arrived */
-
-       ret = i2c_attach_client(i2c_client);
-       if (ret) {
-               printk(KERN_ERR "cs4270: could not attach codec, "
-                       "I2C address %x, error code %i\n", addr, ret);
-               goto error;
-       }
-
        codec->control_data = i2c_client;
        codec->read = cs4270_read_reg_cache;
        codec->write = cs4270_i2c_write;
@@ -648,20 +605,17 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
                        goto error;
        }
 
+       i2c_set_clientdata(i2c_client, codec);
+
        return 0;
 
 error:
-       if (codec->control_data) {
-               i2c_detach_client(i2c_client);
-               codec->control_data = NULL;
-       }
+       codec->control_data = NULL;
 
        kfree(codec->reg_cache);
        codec->reg_cache = NULL;
        codec->reg_cache_size = 0;
 
-       kfree(i2c_client);
-
        return ret;
 }
 
@@ -727,7 +681,7 @@ static int cs4270_probe(struct platform_device *pdev)
        ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
        if (ret < 0) {
                printk(KERN_ERR "cs4270: failed to create PCMs\n");
-               return ret;
+               goto error_free_codec;
        }
 
 #ifdef USE_I2C
@@ -736,8 +690,7 @@ static int cs4270_probe(struct platform_device *pdev)
        ret = i2c_add_driver(&cs4270_i2c_driver);
        if (ret) {
                printk(KERN_ERR "cs4270: failed to attach driver");
-               snd_soc_free_pcms(socdev);
-               return ret;
+               goto error_free_pcms;
        }
 
        /* Did we find a CS4270 on the I2C bus? */
@@ -759,10 +712,23 @@ static int cs4270_probe(struct platform_device *pdev)
        ret = snd_soc_register_card(socdev);
        if (ret < 0) {
                printk(KERN_ERR "cs4270: failed to register card\n");
-               snd_soc_free_pcms(socdev);
-               return ret;
+               goto error_del_driver;
        }
 
+       return 0;
+
+error_del_driver:
+#ifdef USE_I2C
+       i2c_del_driver(&cs4270_i2c_driver);
+
+error_free_pcms:
+#endif
+       snd_soc_free_pcms(socdev);
+
+error_free_codec:
+       kfree(socdev->codec);
+       socdev->codec = NULL;
+
        return ret;
 }
 
@@ -773,8 +739,7 @@ static int cs4270_remove(struct platform_device *pdev)
        snd_soc_free_pcms(socdev);
 
 #ifdef USE_I2C
-       if (socdev->codec->control_data)
-               i2c_del_driver(&cs4270_i2c_driver);
+       i2c_del_driver(&cs4270_i2c_driver);
 #endif
 
        kfree(socdev->codec);
index 5761164..e873414 100644 (file)
@@ -583,7 +583,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
 
        /* out 4 */
        {"Out4 Mux", "VREF", "VREF"},
-       {"Out4 Mux", "Capture ST", "Capture ST Mixer"},
+       {"Out4 Mux", "Capture ST", "Playback Mixer"},
        {"Out4 Mux", "LOUT2", "LOUT2"},
        {"Out 4", NULL, "Out4 Mux"},
        {"OUT4", NULL, "Out 4"},
@@ -607,7 +607,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
        /* Capture Right Mux */
        {"Capture Right Mux", "PGA", "Right Capture Volume"},
        {"Capture Right Mux", "Line or RXP-RXN", "Line Right Mux"},
-       {"Capture Right Mux", "Sidetone", "Capture ST Mixer"},
+       {"Capture Right Mux", "Sidetone", "Playback Mixer"},
 
        /* Mono Capture mixer-mux */
        {"Capture Right Mixer", "Stereo", "Capture Right Mux"},