Pull battery-sbs-ac into release branch
authorLen Brown <len.brown@intel.com>
Wed, 10 Oct 2007 04:30:19 +0000 (00:30 -0400)
committerLen Brown <len.brown@intel.com>
Wed, 10 Oct 2007 04:30:19 +0000 (00:30 -0400)
140 files changed:
Documentation/devices.txt
Documentation/lockstat.txt [new file with mode: 0644]
Documentation/sysrq.txt
Documentation/thinkpad-acpi.txt
Makefile
arch/arm/kernel/bios32.c
arch/arm/mach-s3c2440/mach-osiris.c
arch/blackfin/kernel/bfin_gpio.c
arch/blackfin/mach-common/entry.S
arch/i386/boot/memory.c
arch/i386/kernel/cpu/cpufreq/longhaul.c
arch/mips/au1000/common/pci.c
arch/mips/au1000/mtx-1/board_setup.c
arch/mips/au1000/pb1000/board_setup.c
arch/mips/au1000/pb1100/board_setup.c
arch/mips/au1000/pb1500/board_setup.c
arch/mips/kernel/scall64-o32.S
arch/mips/kernel/vmlinux.lds.S
arch/mips/mm/pg-r4k.c
arch/mips/pci/ops-mace.c
arch/mips/sgi-ip32/ip32-platform.c
arch/powerpc/boot/dts/mpc8349emitx.dts
arch/powerpc/platforms/83xx/usb.c
arch/powerpc/platforms/pseries/xics.c
arch/powerpc/sysdev/commproc.c
arch/ppc/8xx_io/commproc.c
arch/sparc/kernel/ebus.c
arch/sparc64/kernel/binfmt_aout32.c
arch/sparc64/kernel/ebus.c
arch/sparc64/kernel/pci_common.c
arch/sparc64/kernel/prom.c
arch/sparc64/kernel/smp.c
arch/sparc64/kernel/vio.c
arch/sparc64/lib/NGcopy_from_user.S
arch/sparc64/lib/NGcopy_to_user.S
arch/sparc64/lib/NGmemcpy.S
arch/x86_64/vdso/voffset.h
drivers/acpi/Kconfig
drivers/acpi/hardware/hwsleep.c
drivers/acpi/sleep/main.c
drivers/acpi/tables/tbutils.c
drivers/acpi/thermal.c
drivers/acpi/video.c
drivers/ata/ata_piix.c
drivers/ata/pata_ixp4xx_cf.c
drivers/ata/pata_marvell.c
drivers/ata/sata_mv.c
drivers/base/core.c
drivers/char/Makefile
drivers/char/agp/intel-agp.c
drivers/char/drm/i915_drv.h
drivers/char/drm/i915_irq.c
drivers/char/random.c
drivers/char/vt_ioctl.c
drivers/firewire/Kconfig
drivers/ide/ppc/pmac.c
drivers/input/joystick/Kconfig
drivers/isdn/i4l/isdn_common.c
drivers/media/video/ivtv/ivtv-fileops.c
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/fujitsu-laptop.c [new file with mode: 0644]
drivers/misc/sony-laptop.c
drivers/misc/thinkpad_acpi.c
drivers/misc/thinkpad_acpi.h
drivers/net/e1000/e1000_ethtool.c
drivers/net/e1000/e1000_hw.c
drivers/net/e1000/e1000_hw.h
drivers/net/e1000/e1000_main.c
drivers/net/mv643xx_eth.c
drivers/net/mv643xx_eth.h
drivers/net/qla3xxx.c
drivers/net/r8169.c
drivers/net/sky2.c
drivers/net/usb/dm9601.c
drivers/net/wireless/Makefile
drivers/net/wireless/bcm43xx/bcm43xx_wx.c
drivers/pci/quirks.c
drivers/scsi/aic94xx/aic94xx_task.c
drivers/scsi/megaraid.c
drivers/serial/cpm_uart/cpm_uart_cpm1.h
drivers/serial/serial_cs.c
fs/aio.c
fs/binfmt_flat.c
fs/lockd/svclock.c
fs/nfs/client.c
fs/nfs/dir.c
fs/nfs/getroot.c
fs/ocfs2/localalloc.c
fs/splice.c
fs/xfs/xfs_buf_item.h
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_trans_buf.c
include/asm-blackfin/mach-bf533/bfin_serial_5xx.h
include/asm-blackfin/mach-bf537/bfin_serial_5xx.h
include/asm-blackfin/mach-bf537/portmux.h
include/asm-blackfin/mach-bf561/bfin_serial_5xx.h
include/asm-blackfin/portmux.h
include/asm-blackfin/unistd.h
include/asm-h8300/flat.h
include/asm-i386/system.h
include/asm-m32r/flat.h
include/asm-m68knommu/flat.h
include/asm-mips/cmpxchg.h [new file with mode: 0644]
include/asm-mips/fcntl.h
include/asm-mips/local.h
include/asm-mips/page.h
include/asm-mips/system.h
include/asm-sh/flat.h
include/asm-v850/flat.h
include/asm-x86_64/processor.h
include/linux/sched.h
include/linux/writeback.h
include/net/rose.h
include/net/tcp.h
kernel/futex.c
kernel/futex_compat.c
kernel/sched_fair.c
kernel/signal.c
kernel/sys.c
kernel/time/timer_stats.c
lib/Kconfig.debug
lib/Makefile
mm/Kconfig
mm/filemap.c
mm/fremap.c
mm/hugetlb.c
mm/memory.c
mm/page-writeback.c
net/ieee80211/ieee80211_rx.c
net/ieee80211/softmac/ieee80211softmac_wx.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv6/ndisc.c
net/ipv6/tcp_ipv6.c
net/rose/rose_loopback.c
net/rose/rose_route.c
net/sched/cls_u32.c
net/sched/sch_sfq.c
net/socket.c

index 8de132a..6c46730 100644 (file)
@@ -94,6 +94,8 @@ Your cooperation is appreciated.
                  9 = /dev/urandom      Faster, less secure random number gen.
                 10 = /dev/aio          Asynchronous I/O notification interface
                 11 = /dev/kmsg         Writes to this come out as printk's
+                12 = /dev/oldmem       Used by crashdump kernels to access
+                                       the memory of the kernel that crashed.
 
   1 block      RAM disk
                  0 = /dev/ram0         First RAM disk
diff --git a/Documentation/lockstat.txt b/Documentation/lockstat.txt
new file mode 100644 (file)
index 0000000..4ba4664
--- /dev/null
@@ -0,0 +1,120 @@
+
+LOCK STATISTICS
+
+- WHAT
+
+As the name suggests, it provides statistics on locks.
+
+- WHY
+
+Because things like lock contention can severely impact performance.
+
+- HOW
+
+Lockdep already has hooks in the lock functions and maps lock instances to
+lock classes. We build on that. The graph below shows the relation between
+the lock functions and the various hooks therein.
+
+        __acquire
+            |
+           lock _____
+            |        \
+            |    __contended
+            |         |
+            |       <wait>
+            | _______/
+            |/
+            |
+       __acquired
+            |
+            .
+          <hold>
+            .
+            |
+       __release
+            |
+         unlock
+
+lock, unlock   - the regular lock functions
+__*            - the hooks
+<>             - states
+
+With these hooks we provide the following statistics:
+
+ con-bounces       - number of lock contention that involved x-cpu data
+ contentions       - number of lock acquisitions that had to wait
+ wait time min     - shortest (non-0) time we ever had to wait for a lock
+           max     - longest time we ever had to wait for a lock
+           total   - total time we spend waiting on this lock
+ acq-bounces       - number of lock acquisitions that involved x-cpu data
+ acquisitions      - number of times we took the lock
+ hold time min     - shortest (non-0) time we ever held the lock
+           max     - longest time we ever held the lock
+           total   - total time this lock was held
+
+From these number various other statistics can be derived, such as:
+
+ hold time average = hold time total / acquisitions
+
+These numbers are gathered per lock class, per read/write state (when
+applicable).
+
+It also tracks 4 contention points per class. A contention point is a call site
+that had to wait on lock acquisition.
+
+ - USAGE
+
+Look at the current lock statistics:
+
+( line numbers not part of actual output, done for clarity in the explanation
+  below )
+
+# less /proc/lock_stat
+
+01 lock_stat version 0.2
+02 -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+03                               class name    con-bounces    contentions   waittime-min   waittime-max waittime-total    acq-bounces   acquisitions   holdtime-min   holdtime-max holdtime-total
+04 -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+05
+06               &inode->i_data.tree_lock-W:            15          21657           0.18     1093295.30 11547131054.85             58          10415           0.16          87.51        6387.60
+07               &inode->i_data.tree_lock-R:             0              0           0.00           0.00           0.00          23302         231198           0.25           8.45       98023.38
+08               --------------------------
+09                 &inode->i_data.tree_lock              0          [<ffffffff8027c08f>] add_to_page_cache+0x5f/0x190
+10
+11 ...............................................................................................................................................................................................
+12
+13                              dcache_lock:          1037           1161           0.38          45.32         774.51           6611         243371           0.15         306.48       77387.24
+14                              -----------
+15                              dcache_lock            180          [<ffffffff802c0d7e>] sys_getcwd+0x11e/0x230
+16                              dcache_lock            165          [<ffffffff802c002a>] d_alloc+0x15a/0x210
+17                              dcache_lock             33          [<ffffffff8035818d>] _atomic_dec_and_lock+0x4d/0x70
+18                              dcache_lock              1          [<ffffffff802beef8>] shrink_dcache_parent+0x18/0x130
+
+This excerpt shows the first two lock class statistics. Line 01 shows the
+output version - each time the format changes this will be updated. Line 02-04
+show the header with column descriptions. Lines 05-10 and 13-18 show the actual
+statistics. These statistics come in two parts; the actual stats separated by a
+short separator (line 08, 14) from the contention points.
+
+The first lock (05-10) is a read/write lock, and shows two lines above the
+short separator. The contention points don't match the column descriptors,
+they have two: contentions and [<IP>] symbol.
+
+
+View the top contending locks:
+
+# grep : /proc/lock_stat | head
+              &inode->i_data.tree_lock-W:            15          21657           0.18     1093295.30 11547131054.85             58          10415           0.16          87.51        6387.60
+              &inode->i_data.tree_lock-R:             0              0           0.00           0.00           0.00          23302         231198           0.25           8.45       98023.38
+                             dcache_lock:          1037           1161           0.38          45.32         774.51           6611         243371           0.15         306.48       77387.24
+                         &inode->i_mutex:           161            286 18446744073709       62882.54     1244614.55           3653          20598 18446744073709       62318.60     1693822.74
+                         &zone->lru_lock:            94             94           0.53           7.33          92.10           4366          32690           0.29          59.81       16350.06
+              &inode->i_data.i_mmap_lock:            79             79           0.40           3.77          53.03          11779          87755           0.28         116.93       29898.44
+                        &q->__queue_lock:            48             50           0.52          31.62          86.31            774          13131           0.17         113.08       12277.52
+                        &rq->rq_lock_key:            43             47           0.74          68.50         170.63           3706          33929           0.22         107.99       17460.62
+                      &rq->rq_lock_key#2:            39             46           0.75           6.68          49.03           2979          32292           0.17         125.17       17137.63
+                         tasklist_lock-W:            15             15           1.45          10.87          32.70           1201           7390           0.58          62.55       13648.47
+
+Clear the statistics:
+
+# echo 0 > /proc/lock_stat
index ef19142..10c8f69 100644 (file)
@@ -43,7 +43,7 @@ On x86   - You press the key combo 'ALT-SysRq-<command key>'. Note - Some
            keyboards may not have a key labeled 'SysRq'. The 'SysRq' key is
            also known as the 'Print Screen' key. Also some keyboards cannot
           handle so many keys being pressed at the same time, so you might
-          have better luck with "press Alt", "press SysRq", "release Alt",
+          have better luck with "press Alt", "press SysRq", "release SysRq",
           "press <command key>", release everything.
 
 On SPARC - You press 'ALT-STOP-<command key>', I believe.
index 60953d6..3b95bba 100644 (file)
@@ -105,10 +105,15 @@ The version of thinkpad-acpi's sysfs interface is exported by the driver
 as a driver attribute (see below).
 
 Sysfs driver attributes are on the driver's sysfs attribute space,
-for 2.6.20 this is /sys/bus/platform/drivers/thinkpad_acpi/.
+for 2.6.23 this is /sys/bus/platform/drivers/thinkpad_acpi/ and
+/sys/bus/platform/drivers/thinkpad_hwmon/
 
-Sysfs device attributes are on the driver's sysfs attribute space,
-for 2.6.20 this is /sys/devices/platform/thinkpad_acpi/.
+Sysfs device attributes are on the thinkpad_acpi device sysfs attribute
+space, for 2.6.23 this is /sys/devices/platform/thinkpad_acpi/.
+
+Sysfs device attributes for the sensors and fan are on the
+thinkpad_hwmon device's sysfs attribute space, but you should locate it
+looking for a hwmon device with the name attribute of "thinkpad".
 
 Driver version
 --------------
@@ -766,7 +771,7 @@ Temperature sensors
 -------------------
 
 procfs: /proc/acpi/ibm/thermal
-sysfs device attributes: (hwmon) temp*_input
+sysfs device attributes: (hwmon "thinkpad") temp*_input
 
 Most ThinkPads include six or more separate temperature sensors but only
 expose the CPU temperature through the standard ACPI methods.  This
@@ -989,7 +994,9 @@ Fan control and monitoring: fan speed, fan enable/disable
 ---------------------------------------------------------
 
 procfs: /proc/acpi/ibm/fan
-sysfs device attributes: (hwmon) fan_input, pwm1, pwm1_enable
+sysfs device attributes: (hwmon "thinkpad") fan1_input, pwm1,
+                         pwm1_enable
+sysfs hwmon driver attributes: fan_watchdog
 
 NOTE NOTE NOTE: fan control operations are disabled by default for
 safety reasons.  To enable them, the module parameter "fan_control=1"
@@ -1131,7 +1138,7 @@ hwmon device attribute fan1_input:
        which can take up to two minutes.  May return rubbish on older
        ThinkPads.
 
-driver attribute fan_watchdog:
+hwmon driver attribute fan_watchdog:
        Fan safety watchdog timer interval, in seconds.  Minimum is
        1 second, maximum is 120 seconds.  0 disables the watchdog.
 
@@ -1233,3 +1240,9 @@ Sysfs interface changelog:
                layer, the radio switch generates input event EV_RADIO,
                and the driver enables hot key handling by default in
                the firmware.
+
+0x020000:      ABI fix: added a separate hwmon platform device and
+               driver, which must be located by name (thinkpad)
+               and the hwmon class for libsensors4 (lm-sensors 3)
+               compatibility.  Moved all hwmon attributes to this
+               new platform device.
index 4dac253..4635a64 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 23
-EXTRAVERSION =-rc8
+EXTRAVERSION =
 NAME = Arr Matey! A Hairy Bilge Rat!
 
 # *DOCUMENTATION*
index 240c448..a2dd930 100644 (file)
@@ -338,7 +338,7 @@ pbus_assign_bus_resources(struct pci_bus *bus, struct pci_sys_data *root)
  * pcibios_fixup_bus - Called after each bus is probed,
  * but before its children are examined.
  */
-void __devinit pcibios_fixup_bus(struct pci_bus *bus)
+void pcibios_fixup_bus(struct pci_bus *bus)
 {
        struct pci_sys_data *root = bus->sysdata;
        struct pci_dev *dev;
@@ -419,7 +419,7 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
 /*
  * Convert from Linux-centric to bus-centric addresses for bridge devices.
  */
-void __devinit
+void
 pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
                         struct resource *res)
 {
index 0ba7e90..c326983 100644 (file)
@@ -276,7 +276,21 @@ static unsigned char pm_osiris_ctrl0;
 
 static int osiris_pm_suspend(struct sys_device *sd, pm_message_t state)
 {
+       unsigned int tmp;
+
        pm_osiris_ctrl0 = __raw_readb(OSIRIS_VA_CTRL0);
+       tmp = pm_osiris_ctrl0 & ~OSIRIS_CTRL0_NANDSEL;
+
+       /* ensure correct NAND slot is selected on resume */
+       if ((pm_osiris_ctrl0 & OSIRIS_CTRL0_BOOT_INT) == 0)
+               tmp |= 2;
+
+       __raw_writeb(tmp, OSIRIS_VA_CTRL0);
+
+       /* ensure that an nRESET is not generated on resume. */
+       s3c2410_gpio_setpin(S3C2410_GPA21, 1);
+       s3c2410_gpio_cfgpin(S3C2410_GPA21, S3C2410_GPA21_OUT);
+
        return 0;
 }
 
@@ -285,6 +299,10 @@ static int osiris_pm_resume(struct sys_device *sd)
        if (pm_osiris_ctrl0 & OSIRIS_CTRL0_FIX8)
                __raw_writeb(OSIRIS_CTRL1_FIX8, OSIRIS_VA_CTRL1);
 
+       __raw_writeb(pm_osiris_ctrl0, OSIRIS_VA_CTRL0);
+
+       s3c2410_gpio_cfgpin(S3C2410_GPA21, S3C2410_GPA21_nRSTOUT);
+
        return 0;
 }
 
index bafcfa5..5d488ef 100644 (file)
@@ -84,6 +84,7 @@
 #include <linux/err.h>
 #include <asm/blackfin.h>
 #include <asm/gpio.h>
+#include <asm/portmux.h>
 #include <linux/irq.h>
 
 #ifdef BF533_FAMILY
@@ -115,7 +116,11 @@ static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
 };
 #endif
 
-static unsigned short reserved_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
+static unsigned short reserved_gpio_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
+static unsigned short reserved_peri_map[gpio_bank(MAX_BLACKFIN_GPIOS + 16)];
+char *str_ident = NULL;
+
+#define RESOURCE_LABEL_SIZE 16
 
 #ifdef CONFIG_PM
 static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
@@ -143,22 +148,100 @@ inline int check_gpio(unsigned short gpio)
        return 0;
 }
 
+static void set_label(unsigned short ident, const char *label)
+{
+
+       if (label && str_ident) {
+               strncpy(str_ident + ident * RESOURCE_LABEL_SIZE, label,
+                        RESOURCE_LABEL_SIZE);
+               str_ident[ident * RESOURCE_LABEL_SIZE +
+                        RESOURCE_LABEL_SIZE - 1] = 0;
+       }
+}
+
+static char *get_label(unsigned short ident)
+{
+       if (!str_ident)
+               return "UNKNOWN";
+
+       return (str_ident[ident * RESOURCE_LABEL_SIZE] ?
+               (str_ident + ident * RESOURCE_LABEL_SIZE) : "UNKNOWN");
+}
+
+static int cmp_label(unsigned short ident, const char *label)
+{
+       if (label && str_ident)
+               return strncmp(str_ident + ident * RESOURCE_LABEL_SIZE,
+                                label, strlen(label));
+       else
+               return -EINVAL;
+}
+
 #ifdef BF537_FAMILY
 static void port_setup(unsigned short gpio, unsigned short usage)
 {
-       if (usage == GPIO_USAGE) {
-               if (*port_fer[gpio_bank(gpio)] & gpio_bit(gpio))
-                       printk(KERN_WARNING "bfin-gpio: Possible Conflict with Peripheral "
-                              "usage and GPIO %d detected!\n", gpio);
-               *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio);
-       } else
-               *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);
-       SSYNC();
+       if (!check_gpio(gpio)) {
+               if (usage == GPIO_USAGE) {
+                       *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio);
+               } else
+                       *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);
+               SSYNC();
+       }
 }
 #else
 # define port_setup(...)  do { } while (0)
 #endif
 
+#ifdef BF537_FAMILY
+
+#define PMUX_LUT_RES           0
+#define PMUX_LUT_OFFSET                1
+#define PMUX_LUT_ENTRIES       41
+#define PMUX_LUT_SIZE          2
+
+static unsigned short port_mux_lut[PMUX_LUT_ENTRIES][PMUX_LUT_SIZE] = {
+       {P_PPI0_D13, 11}, {P_PPI0_D14, 11}, {P_PPI0_D15, 11},
+       {P_SPORT1_TFS, 11}, {P_SPORT1_TSCLK, 11}, {P_SPORT1_DTPRI, 11},
+       {P_PPI0_D10, 10}, {P_PPI0_D11, 10}, {P_PPI0_D12, 10},
+       {P_SPORT1_RSCLK, 10}, {P_SPORT1_RFS, 10}, {P_SPORT1_DRPRI, 10},
+       {P_PPI0_D8, 9}, {P_PPI0_D9, 9}, {P_SPORT1_DRSEC, 9},
+       {P_SPORT1_DTSEC, 9}, {P_TMR2, 8}, {P_PPI0_FS3, 8}, {P_TMR3, 7},
+       {P_SPI0_SSEL4, 7}, {P_TMR4, 6}, {P_SPI0_SSEL5, 6}, {P_TMR5, 5},
+       {P_SPI0_SSEL6, 5}, {P_UART1_RX, 4}, {P_UART1_TX, 4}, {P_TMR6, 4},
+       {P_TMR7, 4}, {P_UART0_RX, 3}, {P_UART0_TX, 3}, {P_DMAR0, 3},
+       {P_DMAR1, 3}, {P_SPORT0_DTSEC, 1}, {P_SPORT0_DRSEC, 1},
+       {P_CAN0_RX, 1}, {P_CAN0_TX, 1}, {P_SPI0_SSEL7, 1},
+       {P_SPORT0_TFS, 0}, {P_SPORT0_DTPRI, 0}, {P_SPI0_SSEL2, 0},
+       {P_SPI0_SSEL3, 0}
+};
+
+static void portmux_setup(unsigned short per, unsigned short function)
+{
+       u16 y, muxreg, offset;
+
+       for (y = 0; y < PMUX_LUT_ENTRIES; y++) {
+               if (port_mux_lut[y][PMUX_LUT_RES] == per) {
+
+                       /* SET PORTMUX REG */
+
+                       offset = port_mux_lut[y][PMUX_LUT_OFFSET];
+                       muxreg = bfin_read_PORT_MUX();
+
+                       if (offset != 1) {
+                               muxreg &= ~(1 << offset);
+                       } else {
+                               muxreg &= ~(3 << 1);
+                       }
+
+                       muxreg |= (function << offset);
+                       bfin_write_PORT_MUX(muxreg);
+               }
+       }
+}
+
+#else
+# define portmux_setup(...)  do { } while (0)
+#endif
 
 static void default_gpio(unsigned short gpio)
 {
@@ -179,22 +262,15 @@ static void default_gpio(unsigned short gpio)
 
 static int __init bfin_gpio_init(void)
 {
-       int i;
-
-       printk(KERN_INFO "Blackfin GPIO Controller\n");
 
-       for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE)
-               reserved_map[gpio_bank(i)] = 0;
+       str_ident = kzalloc(RESOURCE_LABEL_SIZE * 256, GFP_KERNEL);
+       if (!str_ident)
+               return -ENOMEM;
 
-#if defined(BF537_FAMILY) && (defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
-# if defined(CONFIG_BFIN_MAC_RMII)
-       reserved_map[gpio_bank(PORT_H)] = 0xC373;
-# else
-       reserved_map[gpio_bank(PORT_H)] = 0xFFFF;
-# endif
-#endif
+       printk(KERN_INFO "Blackfin GPIO Controller\n");
 
        return 0;
+
 }
 
 arch_initcall(bfin_gpio_init);
@@ -223,7 +299,7 @@ arch_initcall(bfin_gpio_init);
 void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
 { \
        unsigned long flags; \
-       BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); \
+       BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); \
        local_irq_save(flags); \
        if (arg) \
                gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \
@@ -243,7 +319,7 @@ SET_GPIO(both)
 #define SET_GPIO_SC(name) \
 void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
 { \
-       BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); \
+       BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); \
        if (arg) \
                gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \
        else \
@@ -258,7 +334,7 @@ SET_GPIO_SC(maskb)
 void set_gpio_data(unsigned short gpio, unsigned short arg)
 {
        unsigned long flags;
-       BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+       BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
        local_irq_save(flags);
        if (arg)
                gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
@@ -277,7 +353,7 @@ SET_GPIO_SC(data)
 void set_gpio_toggle(unsigned short gpio)
 {
        unsigned long flags;
-       BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+       BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
        local_irq_save(flags);
        gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
        bfin_read_CHIPID();
@@ -286,7 +362,7 @@ void set_gpio_toggle(unsigned short gpio)
 #else
 void set_gpio_toggle(unsigned short gpio)
 {
-       BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+       BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
        gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
 }
 #endif
@@ -350,7 +426,7 @@ unsigned short get_gpio_data(unsigned short gpio)
 {
        unsigned long flags;
        unsigned short ret;
-       BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+       BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
        local_irq_save(flags);
        ret = 0x01 & (gpio_bankb[gpio_bank(gpio)]->data >> gpio_sub_n(gpio));
        bfin_read_CHIPID();
@@ -494,13 +570,14 @@ u32 gpio_pm_setup(void)
                        gpio_bank_saved[bank].dir   = gpio_bankb[bank]->dir;
                        gpio_bank_saved[bank].edge  = gpio_bankb[bank]->edge;
                        gpio_bank_saved[bank].both  = gpio_bankb[bank]->both;
-                       gpio_bank_saved[bank].reserved = reserved_map[bank];
+                       gpio_bank_saved[bank].reserved =
+                                               reserved_gpio_map[bank];
 
                        gpio = i;
 
                        while (mask) {
                                if (mask & 1) {
-                                       reserved_map[gpio_bank(gpio)] |=
+                                       reserved_gpio_map[gpio_bank(gpio)] |=
                                                        gpio_bit(gpio);
                                        bfin_gpio_wakeup_type(gpio,
                                                wakeup_flags_map[gpio]);
@@ -540,7 +617,8 @@ void gpio_pm_restore(void)
                        gpio_bankb[bank]->edge  = gpio_bank_saved[bank].edge;
                        gpio_bankb[bank]->both  = gpio_bank_saved[bank].both;
 
-                       reserved_map[bank] = gpio_bank_saved[bank].reserved;
+                       reserved_gpio_map[bank] =
+                                       gpio_bank_saved[bank].reserved;
 
                }
 
@@ -550,6 +628,141 @@ void gpio_pm_restore(void)
 
 #endif
 
+
+
+
+int peripheral_request(unsigned short per, const char *label)
+{
+       unsigned long flags;
+       unsigned short ident = P_IDENT(per);
+
+       /*
+        * Don't cares are pins with only one dedicated function
+        */
+
+       if (per & P_DONTCARE)
+               return 0;
+
+       if (!(per & P_DEFINED))
+               return -ENODEV;
+
+       local_irq_save(flags);
+
+       if (!check_gpio(ident)) {
+
+       if (unlikely(reserved_gpio_map[gpio_bank(ident)] & gpio_bit(ident))) {
+               printk(KERN_ERR
+                      "%s: Peripheral %d is already reserved as GPIO by %s !\n",
+                      __FUNCTION__, ident, get_label(ident));
+               dump_stack();
+               local_irq_restore(flags);
+               return -EBUSY;
+       }
+
+       }
+
+       if (unlikely(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident))) {
+
+       /*
+        * Pin functions like AMC address strobes my
+        * be requested and used by several drivers
+        */
+
+       if (!(per & P_MAYSHARE)) {
+
+       /*
+        * Allow that the identical pin function can
+        * be requested from the same driver twice
+        */
+
+               if (cmp_label(ident, label) == 0)
+                       goto anyway;
+
+                       printk(KERN_ERR
+                              "%s: Peripheral %d function %d is already"
+                              "reserved by %s !\n",
+                              __FUNCTION__, ident, P_FUNCT2MUX(per),
+                               get_label(ident));
+                       dump_stack();
+                       local_irq_restore(flags);
+                       return -EBUSY;
+               }
+
+       }
+
+anyway:
+
+
+       portmux_setup(per, P_FUNCT2MUX(per));
+
+       port_setup(ident, PERIPHERAL_USAGE);
+
+       reserved_peri_map[gpio_bank(ident)] |= gpio_bit(ident);
+       local_irq_restore(flags);
+       set_label(ident, label);
+
+       return 0;
+}
+EXPORT_SYMBOL(peripheral_request);
+
+int peripheral_request_list(unsigned short per[], const char *label)
+{
+       u16 cnt;
+       int ret;
+
+       for (cnt = 0; per[cnt] != 0; cnt++) {
+               ret = peripheral_request(per[cnt], label);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(peripheral_request_list);
+
+void peripheral_free(unsigned short per)
+{
+       unsigned long flags;
+       unsigned short ident = P_IDENT(per);
+
+       if (per & P_DONTCARE)
+               return;
+
+       if (!(per & P_DEFINED))
+               return;
+
+       if (check_gpio(ident) < 0)
+               return;
+
+       local_irq_save(flags);
+
+       if (unlikely(!(reserved_peri_map[gpio_bank(ident)]
+                        & gpio_bit(ident)))) {
+               local_irq_restore(flags);
+               return;
+       }
+
+       if (!(per & P_MAYSHARE)) {
+               port_setup(ident, GPIO_USAGE);
+       }
+
+       reserved_peri_map[gpio_bank(ident)] &= ~gpio_bit(ident);
+
+       local_irq_restore(flags);
+}
+EXPORT_SYMBOL(peripheral_free);
+
+void peripheral_free_list(unsigned short per[])
+{
+       u16 cnt;
+
+       for (cnt = 0; per[cnt] != 0; cnt++) {
+               peripheral_free(per[cnt]);
+       }
+
+}
+EXPORT_SYMBOL(peripheral_free_list);
+
 /***********************************************************
 *
 * FUNCTIONS: Blackfin GPIO Driver
@@ -574,13 +787,13 @@ int gpio_request(unsigned short gpio, const char *label)
 
        local_irq_save(flags);
 
-       if (unlikely(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
+       if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
                printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved!\n", gpio);
                dump_stack();
                local_irq_restore(flags);
                return -EBUSY;
        }
-       reserved_map[gpio_bank(gpio)] |= gpio_bit(gpio);
+       reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio);
 
        local_irq_restore(flags);
 
@@ -599,7 +812,7 @@ void gpio_free(unsigned short gpio)
 
        local_irq_save(flags);
 
-       if (unlikely(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
+       if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
                printk(KERN_ERR "bfin-gpio: GPIO %d wasn't reserved!\n", gpio);
                dump_stack();
                local_irq_restore(flags);
@@ -608,7 +821,7 @@ void gpio_free(unsigned short gpio)
 
        default_gpio(gpio);
 
-       reserved_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
+       reserved_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
 
        local_irq_restore(flags);
 }
@@ -618,7 +831,7 @@ void gpio_direction_input(unsigned short gpio)
 {
        unsigned long flags;
 
-       BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+       BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
 
        local_irq_save(flags);
        gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio);
@@ -631,7 +844,7 @@ void gpio_direction_output(unsigned short gpio)
 {
        unsigned long flags;
 
-       BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+       BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
 
        local_irq_save(flags);
        gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
index d61bba9..9604588 100644 (file)
@@ -815,7 +815,7 @@ _extable:
 
 ALIGN
 ENTRY(_sys_call_table)
-       .long _sys_ni_syscall   /* 0  -  old "setup()" system call*/
+       .long _sys_restart_syscall      /* 0 */
        .long _sys_exit
        .long _sys_fork
        .long _sys_read
@@ -978,13 +978,13 @@ ENTRY(_sys_call_table)
        .long _sys_sched_get_priority_min  /* 160 */
        .long _sys_sched_rr_get_interval
        .long _sys_nanosleep
-       .long _sys_ni_syscall   /* sys_mremap */
+       .long _sys_mremap
        .long _sys_setresuid    /* setresuid16 */
        .long _sys_getresuid    /* getresuid16 */       /* 165 */
        .long _sys_ni_syscall   /* for vm86 */
        .long _sys_ni_syscall   /* old "query_module" */
        .long _sys_ni_syscall   /* sys_poll */
-       .long _sys_ni_syscall   /* sys_nfsservctl */
+       .long _sys_nfsservctl
        .long _sys_setresgid    /* setresgid16 */       /* 170 */
        .long _sys_getresgid    /* getresgid16 */
        .long _sys_prctl
@@ -1040,7 +1040,7 @@ ENTRY(_sys_call_table)
        .long _sys_ni_syscall   /* reserved for TUX */
        .long _sys_ni_syscall
        .long _sys_gettid
-       .long _sys_ni_syscall   /* 225 */ /* sys_readahead */
+       .long _sys_readahead    /* 225 */
        .long _sys_setxattr
        .long _sys_lsetxattr
        .long _sys_fsetxattr
@@ -1157,6 +1157,21 @@ ENTRY(_sys_call_table)
        .long _sys_shmctl
        .long _sys_shmdt        /* 340 */
        .long _sys_shmget
+       .long _sys_splice
+       .long _sys_sync_file_range
+       .long _sys_tee
+       .long _sys_vmsplice     /* 345 */
+       .long _sys_epoll_pwait
+       .long _sys_utimensat
+       .long _sys_signalfd
+       .long _sys_timerfd
+       .long _sys_eventfd      /* 350 */
+       .long _sys_pread64
+       .long _sys_pwrite64
+       .long _sys_fadvise64
+       .long _sys_set_robust_list
+       .long _sys_get_robust_list      /* 355 */
+       .long _sys_fallocate
        .rept NR_syscalls-(.-_sys_call_table)/4
        .long _sys_ni_syscall
        .endr
index bccaa1c..3783539 100644 (file)
@@ -28,11 +28,14 @@ static int detect_memory_e820(void)
 
        do {
                size = sizeof(struct e820entry);
-               id = SMAP;
+
+               /* Important: %edx is clobbered by some BIOSes,
+                  so it must be either used for the error output
+                  or explicitly marked clobbered. */
                asm("int $0x15; setc %0"
-                   : "=am" (err), "+b" (next), "+d" (id), "+c" (size),
+                   : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
                      "=m" (*desc)
-                   : "D" (desc), "a" (0xe820));
+                   : "D" (desc), "d" (SMAP), "a" (0xe820));
 
                /* Some BIOSes stop returning SMAP in the middle of
                   the search loop.  We don't know exactly how the BIOS
index ef8f0bc..f0cce3c 100644 (file)
@@ -76,6 +76,7 @@ static unsigned int longhaul_index;
 /* Module parameters */
 static int scale_voltage;
 static int disable_acpi_c3;
+static int revid_errata;
 
 #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg)
 
@@ -168,7 +169,10 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index,
 
        rdmsrl(MSR_VIA_LONGHAUL, longhaul.val);
        /* Setup new frequency */
-       longhaul.bits.RevisionKey = longhaul.bits.RevisionID;
+       if (!revid_errata)
+               longhaul.bits.RevisionKey = longhaul.bits.RevisionID;
+       else
+               longhaul.bits.RevisionKey = 0;
        longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf;
        longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
        /* Setup new voltage */
@@ -272,7 +276,7 @@ static void longhaul_setstate(unsigned int table_index)
 
        dprintk ("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n",
                        fsb, mult/10, mult%10, print_speed(speed/1000));
-
+retry_loop:
        preempt_disable();
        local_irq_save(flags);
 
@@ -344,6 +348,47 @@ static void longhaul_setstate(unsigned int table_index)
        preempt_enable();
 
        freqs.new = calc_speed(longhaul_get_cpu_mult());
+       /* Check if requested frequency is set. */
+       if (unlikely(freqs.new != speed)) {
+               printk(KERN_INFO PFX "Failed to set requested frequency!\n");
+               /* Revision ID = 1 but processor is expecting revision key
+                * equal to 0. Jumpers at the bottom of processor will change
+                * multiplier and FSB, but will not change bits in Longhaul
+                * MSR nor enable voltage scaling. */
+               if (!revid_errata) {
+                       printk(KERN_INFO PFX "Enabling \"Ignore Revision ID\" "
+                                               "option.\n");
+                       revid_errata = 1;
+                       msleep(200);
+                       goto retry_loop;
+               }
+               /* Why ACPI C3 sometimes doesn't work is a mystery for me.
+                * But it does happen. Processor is entering ACPI C3 state,
+                * but it doesn't change frequency. I tried poking various
+                * bits in northbridge registers, but without success. */
+               if (longhaul_flags & USE_ACPI_C3) {
+                       printk(KERN_INFO PFX "Disabling ACPI C3 support.\n");
+                       longhaul_flags &= ~USE_ACPI_C3;
+                       if (revid_errata) {
+                               printk(KERN_INFO PFX "Disabling \"Ignore "
+                                               "Revision ID\" option.\n");
+                               revid_errata = 0;
+                       }
+                       msleep(200);
+                       goto retry_loop;
+               }
+               /* This shouldn't happen. Longhaul ver. 2 was reported not
+                * working on processors without voltage scaling, but with
+                * RevID = 1. RevID errata will make things right. Just
+                * to be 100% sure. */
+               if (longhaul_version == TYPE_LONGHAUL_V2) {
+                       printk(KERN_INFO PFX "Switching to Longhaul ver. 1\n");
+                       longhaul_version = TYPE_LONGHAUL_V1;
+                       msleep(200);
+                       goto retry_loop;
+               }
+       }
+       /* Report true CPU frequency */
        cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 
        if (!bm_timeout)
@@ -956,11 +1001,20 @@ static void __exit longhaul_exit(void)
        kfree(longhaul_table);
 }
 
+/* Even if BIOS is exporting ACPI C3 state, and it is used
+ * with success when CPU is idle, this state doesn't
+ * trigger frequency transition in some cases. */
 module_param (disable_acpi_c3, int, 0644);
 MODULE_PARM_DESC(disable_acpi_c3, "Don't use ACPI C3 support");
-
+/* Change CPU voltage with frequency. Very usefull to save
+ * power, but most VIA C3 processors aren't supporting it. */
 module_param (scale_voltage, int, 0644);
 MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor");
+/* Force revision key to 0 for processors which doesn't
+ * support voltage scaling, but are introducing itself as
+ * such. */
+module_param(revid_errata, int, 0644);
+MODULE_PARM_DESC(revid_errata, "Ignore CPU Revision ID");
 
 MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>");
 MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors.");
index 6c25e6c..9be99a6 100644 (file)
@@ -74,6 +74,7 @@ static int __init au1x_pci_setup(void)
                printk(KERN_ERR "Unable to ioremap pci space\n");
                return 1;
        }
+       au1x_controller.io_map_base = virt_io_addr;
 
 #ifdef CONFIG_DMA_NONCOHERENT
        {
index 7bc5af8..2c460c1 100644 (file)
@@ -54,11 +54,11 @@ void board_reset (void)
 
 void __init board_setup(void)
 {
-#ifdef CONFIG_USB_OHCI
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
        // enable USB power switch
        au_writel( au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR );
        au_writel( 0x100000, GPIO2_OUTPUT );
-#endif // defined (CONFIG_USB_OHCI)
+#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
 
 #ifdef CONFIG_PCI
 #if defined(__MIPSEB__)
index 824cfaf..0aed891 100644 (file)
@@ -54,7 +54,7 @@ void __init board_setup(void)
        au_writel(0, SYS_PINSTATERD);
        udelay(100);
 
-#ifdef CONFIG_USB_OHCI
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
        /* zero and disable FREQ2 */
        sys_freqctrl = au_readl(SYS_FREQCTRL0);
        sys_freqctrl &= ~0xFFF00000;
@@ -102,7 +102,7 @@ void __init board_setup(void)
        /*
         * Route 48MHz FREQ2 into USB Host and/or Device
         */
-#ifdef CONFIG_USB_OHCI
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
        sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));
 #endif
        au_writel(sys_clksrc, SYS_CLKSRC);
@@ -116,7 +116,7 @@ void __init board_setup(void)
        au_writel(pin_func, SYS_PINFUNC);
        au_writel(0x2800, SYS_TRIOUTCLR);
        au_writel(0x0030, SYS_OUTPUTCLR);
-#endif // defined (CONFIG_USB_OHCI)
+#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
 
        // make gpio 15 an input (for interrupt line)
        pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x100);
index 6bc1f8e..259ca05 100644 (file)
@@ -54,7 +54,7 @@ void __init board_setup(void)
        au_writel(0, SYS_PININPUTEN);
        udelay(100);
 
-#ifdef CONFIG_USB_OHCI
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
        {
                u32 pin_func, sys_freqctrl, sys_clksrc;
 
@@ -98,7 +98,7 @@ void __init board_setup(void)
                pin_func |= 0x8000;
                au_writel(pin_func, SYS_PINFUNC);
        }
-#endif // defined (CONFIG_USB_OHCI)
+#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
 
        /* Enable sys bus clock divider when IDLE state or no bus activity. */
        au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
index c9b6556..a2d850d 100644 (file)
@@ -56,7 +56,7 @@ void __init board_setup(void)
        au_writel(0, SYS_PINSTATERD);
        udelay(100);
 
-#ifdef CONFIG_USB_OHCI
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
 
        /* GPIO201 is input for PCMCIA card detect */
        /* GPIO203 is input for PCMCIA interrupt request */
@@ -85,7 +85,7 @@ void __init board_setup(void)
        /*
         * Route 48MHz FREQ2 into USB Host and/or Device
         */
-#ifdef CONFIG_USB_OHCI
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
        sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));
 #endif
        au_writel(sys_clksrc, SYS_CLKSRC);
@@ -95,7 +95,7 @@ void __init board_setup(void)
        // 2nd USB port is USB host
        pin_func |= 0x8000;
        au_writel(pin_func, SYS_PINFUNC);
-#endif // defined (CONFIG_USB_OHCI)
+#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
 
 
 
index b3ed731..dd68afc 100644 (file)
@@ -525,5 +525,5 @@ sys_call_table:
        PTR     compat_sys_signalfd
        PTR     compat_sys_timerfd
        PTR     sys_eventfd
-       PTR     sys_fallocate                   /* 4320 */
+       PTR     sys32_fallocate                 /* 4320 */
        .size   sys_call_table,.-sys_call_table
index 60bbaec..087ab99 100644 (file)
@@ -45,6 +45,8 @@ SECTIONS
   __dbe_table : { *(__dbe_table) }
   __stop___dbe_table = .;
 
+  NOTES
+
   RODATA
 
   /* writeable */
index dc795be..e47e9e9 100644 (file)
@@ -209,7 +209,7 @@ static inline void build_cdex_p(void)
        }
 
        if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
-               build_insn_word(0x3c01a000);    /* lui     $at, 0xa000  */
+               build_insn_word(0x8c200000);    /* lw      $zero, ($at) */
 
        mi.c_format.opcode     = cache_op;
        mi.c_format.rs         = 4;             /* $a0 */
index 8008e31..fe54514 100644 (file)
  * 4  N/C
  */
 
-#define chkslot(_bus,_devfn)                                   \
-do {                                                           \
-       if ((_bus)->number > 0 || PCI_SLOT (_devfn) < 1 \
-           || PCI_SLOT (_devfn) > 3)                           \
-               return PCIBIOS_DEVICE_NOT_FOUND;                \
-} while (0)
+static inline int mkaddr(struct pci_bus *bus, unsigned int devfn,
+       unsigned int reg)
+{
+       return ((bus->number & 0xff) << 16) |
+               ((devfn & 0xff) << 8) |
+               (reg & 0xfc);
+}
 
-#define mkaddr(_devfn, _reg) \
-((((_devfn) & 0xffUL) << 8) | ((_reg) & 0xfcUL))
 
 static int
 mace_pci_read_config(struct pci_bus *bus, unsigned int devfn,
                     int reg, int size, u32 *val)
 {
-       chkslot(bus, devfn);
-       mace->pci.config_addr = mkaddr(devfn, reg);
+       mace->pci.config_addr = mkaddr(bus, devfn, reg);
        switch (size) {
        case 1:
                *val = mace->pci.config_data.b[(reg & 3) ^ 3];
@@ -66,8 +64,7 @@ static int
 mace_pci_write_config(struct pci_bus *bus, unsigned int devfn,
                      int reg, int size, u32 val)
 {
-       chkslot(bus, devfn);
-       mace->pci.config_addr = mkaddr(devfn, reg);
+       mace->pci.config_addr = mkaddr(bus, devfn, reg);
        switch (size) {
        case 1:
                mace->pci.config_data.b[(reg & 3) ^ 3] = val;
index ba3697e..7309e48 100644 (file)
@@ -41,8 +41,8 @@ static struct platform_device uart8250_device = {
 
 static int __init uart8250_init(void)
 {
-       uart8250_data[0].iobase = (unsigned long) &mace->isa.serial1;
-       uart8250_data[1].iobase = (unsigned long) &mace->isa.serial1;
+       uart8250_data[0].membase = (void __iomem *) &mace->isa.serial1;
+       uart8250_data[1].membase = (void __iomem *) &mace->isa.serial1;
 
        return platform_device_register(&uart8250_device);
 }
index 502f47c..44c065a 100644 (file)
@@ -99,6 +99,7 @@
                        #size-cells = <0>;
                        interrupt-parent = < &ipic >;
                        interrupts = <26 8>;
+                       dr_mode = "peripheral";
                        phy_type = "ulpi";
                };
 
index e7fdf01..eafe760 100644 (file)
@@ -76,14 +76,14 @@ int mpc834x_usb_cfg(void)
                        if (port0_is_dr)
                                printk(KERN_WARNING
                                        "834x USB port0 can't be used by both DR and MPH!\n");
-                       sicrl |= MPC834X_SICRL_USB0;
+                       sicrl &= ~MPC834X_SICRL_USB0;
                }
                prop = of_get_property(np, "port1", NULL);
                if (prop) {
                        if (port1_is_dr)
                                printk(KERN_WARNING
                                        "834x USB port1 can't be used by both DR and MPH!\n");
-                       sicrl |= MPC834X_SICRL_USB1;
+                       sicrl &= ~MPC834X_SICRL_USB1;
                }
                of_node_put(np);
        }
index 5bd90a7..f0b5ff1 100644 (file)
@@ -419,7 +419,7 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
         * For the moment only implement delivery to all cpus or one cpu.
         * Get current irq_server for the given irq
         */
-       irq_server = get_irq_server(irq, 1);
+       irq_server = get_irq_server(virq, 1);
        if (irq_server == -1) {
                char cpulist[128];
                cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask);
index 4f67b89..dd5417a 100644 (file)
@@ -395,4 +395,4 @@ uint cpm_dpram_phys(u8* addr)
 {
        return (dpram_pbase + (uint)(addr - dpram_vbase));
 }
-EXPORT_SYMBOL(cpm_dpram_addr);
+EXPORT_SYMBOL(cpm_dpram_phys);
index 7088428..9da880b 100644 (file)
@@ -459,7 +459,7 @@ EXPORT_SYMBOL(cpm_dpdump);
 
 void *cpm_dpram_addr(unsigned long offset)
 {
-       return ((immap_t *)IMAP_ADDR)->im_cpm.cp_dpmem + offset;
+       return (void *)(dpram_vbase + offset);
 }
 EXPORT_SYMBOL(cpm_dpram_addr);
 
index e2d02fd..d850785 100644 (file)
@@ -156,6 +156,8 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d
        dev->prom_node = dp;
 
        regs = of_get_property(dp, "reg", &len);
+       if (!regs)
+               len = 0;
        if (len % sizeof(struct linux_prom_registers)) {
                prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
                            dev->prom_node->name, len,
index f205fc7..d208cc7 100644 (file)
@@ -177,7 +177,7 @@ static u32 __user *create_aout32_tables(char __user *p, struct linux_binprm *bpr
                        get_user(c,p++);
                } while (c);
        }
-       put_user(NULL,argv);
+       put_user(0,argv);
        current->mm->arg_end = current->mm->env_start = (unsigned long) p;
        while (envc-->0) {
                char c;
@@ -186,7 +186,7 @@ static u32 __user *create_aout32_tables(char __user *p, struct linux_binprm *bpr
                        get_user(c,p++);
                } while (c);
        }
-       put_user(NULL,envp);
+       put_user(0,envp);
        current->mm->env_end = (unsigned long) p;
        return sp;
 }
index bc9ae36..04ab81c 100644 (file)
@@ -375,7 +375,10 @@ static void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_de
                dev->num_addrs = 0;
                dev->num_irqs = 0;
        } else {
-               (void) of_get_property(dp, "reg", &len);
+               const int *regs = of_get_property(dp, "reg", &len);
+
+               if (!regs)
+                       len = 0;
                dev->num_addrs = len / sizeof(struct linux_prom_registers);
 
                for (i = 0; i < dev->num_addrs; i++)
index 2f61c4b..c76bfbb 100644 (file)
@@ -264,7 +264,7 @@ static int sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
        unsigned int func = PCI_FUNC(devfn);
        unsigned long ret;
 
-       if (bus_dev == pbm->pci_bus && devfn == 0x00)
+       if (!bus && devfn == 0x00)
                return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where,
                                                    size, value);
        if (config_out_of_range(pbm, bus, devfn, where)) {
@@ -300,7 +300,7 @@ static int sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
        unsigned int func = PCI_FUNC(devfn);
        unsigned long ret;
 
-       if (bus_dev == pbm->pci_bus && devfn == 0x00)
+       if (!bus && devfn == 0x00)
                return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where,
                                                     size, value);
        if (config_out_of_range(pbm, bus, devfn, where)) {
index 0614dff..a246e96 100644 (file)
@@ -1046,7 +1046,8 @@ static void __init irq_trans_init(struct device_node *dp)
        if (!strcmp(dp->name, "fhc") &&
            !strcmp(dp->parent->name, "central"))
                return central_irq_trans_init(dp);
-       if (!strcmp(dp->name, "virtual-devices"))
+       if (!strcmp(dp->name, "virtual-devices") ||
+           !strcmp(dp->name, "niu"))
                return sun4v_vdev_irq_trans_init(dp);
 }
 
index b84c49e..c73b7a4 100644 (file)
@@ -353,6 +353,8 @@ static int __devinit smp_boot_one_cpu(unsigned int cpu)
        int timeout, ret;
 
        p = fork_idle(cpu);
+       if (IS_ERR(p))
+               return PTR_ERR(p);
        callin_flag = 0;
        cpu_new_thread = task_thread_info(p);
 
index 1550ac5..0c1ee61 100644 (file)
@@ -292,7 +292,7 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
        }
        vdev->dp = dp;
 
-       printk(KERN_ERR "VIO: Adding device %s\n", vdev->dev.bus_id);
+       printk(KERN_INFO "VIO: Adding device %s\n", vdev->dev.bus_id);
 
        err = device_register(&vdev->dev);
        if (err) {
@@ -342,8 +342,33 @@ static struct mdesc_notifier_client vio_device_notifier = {
        .node_name      = "virtual-device-port",
 };
 
+/* We are only interested in domain service ports under the
+ * "domain-services" node.  On control nodes there is another port
+ * under "openboot" that we should not mess with as aparently that is
+ * reserved exclusively for OBP use.
+ */
+static void vio_add_ds(struct mdesc_handle *hp, u64 node)
+{
+       int found;
+       u64 a;
+
+       found = 0;
+       mdesc_for_each_arc(a, hp, node, MDESC_ARC_TYPE_BACK) {
+               u64 target = mdesc_arc_target(hp, a);
+               const char *name = mdesc_node_name(hp, target);
+
+               if (!strcmp(name, "domain-services")) {
+                       found = 1;
+                       break;
+               }
+       }
+
+       if (found)
+               (void) vio_create_one(hp, node, &root_vdev->dev);
+}
+
 static struct mdesc_notifier_client vio_ds_notifier = {
-       .add            = vio_add,
+       .add            = vio_add_ds,
        .remove         = vio_remove,
        .node_name      = "domain-services-port",
 };
index 2d93456..e7f433f 100644 (file)
@@ -1,6 +1,6 @@
 /* NGcopy_from_user.S: Niagara optimized copy from userspace.
  *
- * Copyright (C) 2006 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net)
  */
 
 #define EX_LD(x)               \
@@ -8,8 +8,8 @@
        .section .fixup;        \
        .align 4;               \
 99:    wr      %g0, ASI_AIUS, %asi;\
-       retl;                   \
-        mov    1, %o0;         \
+       ret                   \
+        restore %g0, 1, %o0;   \
        .section __ex_table,"a";\
        .align 4;               \
        .word 98b, 99b;         \
@@ -24,7 +24,7 @@
 #define LOAD(type,addr,dest)   type##a [addr] ASI_AIUS, dest
 #define LOAD_TWIN(addr_reg,dest0,dest1)        \
        ldda [addr_reg] ASI_BLK_INIT_QUAD_LDD_AIUS, dest0
-#define EX_RETVAL(x)           0
+#define EX_RETVAL(x)           %g0
 
 #ifdef __KERNEL__
 #define PREAMBLE                                       \
index 34112d5..6ea01c5 100644 (file)
@@ -1,6 +1,6 @@
 /* NGcopy_to_user.S: Niagara optimized copy to userspace.
  *
- * Copyright (C) 2006 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net)
  */
 
 #define EX_ST(x)               \
@@ -8,8 +8,8 @@
        .section .fixup;        \
        .align 4;               \
 99:    wr      %g0, ASI_AIUS, %asi;\
-       retl;                   \
-        mov    1, %o0;         \
+       ret                   \
+        restore %g0, 1, %o0;   \
        .section __ex_table,"a";\
        .align 4;               \
        .word 98b, 99b;         \
@@ -23,7 +23,7 @@
 #define FUNC_NAME              NGcopy_to_user
 #define STORE(type,src,addr)   type##a src, [addr] ASI_AIUS
 #define STORE_ASI              ASI_BLK_INIT_QUAD_LDD_AIUS
-#define EX_RETVAL(x)           0
+#define EX_RETVAL(x)           %g0
 
 #ifdef __KERNEL__
        /* Writing to %asi is _expensive_ so we hardcode it.
index 66063a9..96a14ca 100644 (file)
@@ -1,6 +1,6 @@
 /* NGmemcpy.S: Niagara optimized memcpy.
  *
- * Copyright (C) 2006 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net)
  */
 
 #ifdef __KERNEL__
        wr      %g0, ASI_PNF, %asi
 #endif
 
+#ifdef __sparc_v9__
+#define SAVE_AMOUNT    128
+#else
+#define SAVE_AMOUNT    64
+#endif
+
 #ifndef STORE_ASI
 #define STORE_ASI      ASI_BLK_INIT_QUAD_LDD_P
 #endif
 #endif
 
 #ifndef STORE_INIT
+#ifndef SIMULATE_NIAGARA_ON_NON_NIAGARA
 #define STORE_INIT(src,addr)   stxa src, [addr] %asi
+#else
+#define STORE_INIT(src,addr)   stx src, [addr + 0x00]
+#endif
 #endif
 
 #ifndef FUNC_NAME
 
        .globl  FUNC_NAME
        .type   FUNC_NAME,#function
-FUNC_NAME:     /* %o0=dst, %o1=src, %o2=len */
-       srlx            %o2, 31, %g2
+FUNC_NAME:     /* %i0=dst, %i1=src, %i2=len */
+       PREAMBLE
+       save            %sp, -SAVE_AMOUNT, %sp
+       srlx            %i2, 31, %g2
        cmp             %g2, 0
        tne             %xcc, 5
-       PREAMBLE
-       mov             %o0, GLOBAL_SPARE
-       cmp             %o2, 0
+       mov             %i0, %o0
+       cmp             %i2, 0
        be,pn           %XCC, 85f
-        or             %o0, %o1, %o3
-       cmp             %o2, 16
+        or             %o0, %i1, %i3
+       cmp             %i2, 16
        blu,a,pn        %XCC, 80f
-        or             %o3, %o2, %o3
+        or             %i3, %i2, %i3
 
        /* 2 blocks (128 bytes) is the minimum we can do the block
         * copy with.  We need to ensure that we'll iterate at least
@@ -93,31 +104,31 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
         * to (64 - 1) bytes from the length before we perform the
         * block copy loop.
         */
-       cmp             %o2, (2 * 64)
+       cmp             %i2, (2 * 64)
        blu,pt          %XCC, 70f
-        andcc          %o3, 0x7, %g0
+        andcc          %i3, 0x7, %g0
 
        /* %o0: dst
-        * %o1: src
-        * %o2: len  (known to be >= 128)
+        * %i1: src
+        * %i2: len  (known to be >= 128)
         *
-        * The block copy loops will use %o4/%o5,%g2/%g3 as
+        * The block copy loops will use %i4/%i5,%g2/%g3 as
         * temporaries while copying the data.
         */
 
-       LOAD(prefetch, %o1, #one_read)
+       LOAD(prefetch, %i1, #one_read)
        wr              %g0, STORE_ASI, %asi
 
        /* Align destination on 64-byte boundary.  */
-       andcc           %o0, (64 - 1), %o4
+       andcc           %o0, (64 - 1), %i4
        be,pt           %XCC, 2f
-        sub            %o4, 64, %o4
-       sub             %g0, %o4, %o4   ! bytes to align dst
-       sub             %o2, %o4, %o2
-1:     subcc           %o4, 1, %o4
-       EX_LD(LOAD(ldub, %o1, %g1))
+        sub            %i4, 64, %i4
+       sub             %g0, %i4, %i4   ! bytes to align dst
+       sub             %i2, %i4, %i2
+1:     subcc           %i4, 1, %i4
+       EX_LD(LOAD(ldub, %i1, %g1))
        EX_ST(STORE(stb, %g1, %o0))
-       add             %o1, 1, %o1
+       add             %i1, 1, %i1
        bne,pt          %XCC, 1b
        add             %o0, 1, %o0
 
@@ -136,111 +147,155 @@ FUNC_NAME:      /* %o0=dst, %o1=src, %o2=len */
         * aligned store data at a time, this is easy to ensure.
         */
 2:
-       andcc           %o1, (16 - 1), %o4
-       andn            %o2, (64 - 1), %g1      ! block copy loop iterator
-       sub             %o2, %g1, %o2           ! final sub-block copy bytes
+       andcc           %i1, (16 - 1), %i4
+       andn            %i2, (64 - 1), %g1      ! block copy loop iterator
        be,pt           %XCC, 50f
-        cmp            %o4, 8
-       be,a,pt         %XCC, 10f
-        sub            %o1, 0x8, %o1
+        sub            %i2, %g1, %i2           ! final sub-block copy bytes
+
+       cmp             %i4, 8
+       be,pt           %XCC, 10f
+        sub            %i1, %i4, %i1
 
        /* Neither 8-byte nor 16-byte aligned, shift and mask.  */
-       mov             %g1, %o4
-       and             %o1, 0x7, %g1
-       sll             %g1, 3, %g1
-       mov             64, %o3
-       andn            %o1, 0x7, %o1
-       EX_LD(LOAD(ldx, %o1, %g2))
-       sub             %o3, %g1, %o3
-       sllx            %g2, %g1, %g2
+       and             %i4, 0x7, GLOBAL_SPARE
+       sll             GLOBAL_SPARE, 3, GLOBAL_SPARE
+       mov             64, %i5
+       EX_LD(LOAD_TWIN(%i1, %g2, %g3))
+       sub             %i5, GLOBAL_SPARE, %i5
+       mov             16, %o4
+       mov             32, %o5
+       mov             48, %o7
+       mov             64, %i3
+
+       bg,pn           %XCC, 9f
+        nop
 
-#define SWIVEL_ONE_DWORD(SRC, TMP1, TMP2, PRE_VAL, PRE_SHIFT, POST_SHIFT, DST)\
-       EX_LD(LOAD(ldx, SRC, TMP1)); \
-       srlx            TMP1, PRE_SHIFT, TMP2; \
-       or              TMP2, PRE_VAL, TMP2; \
-       EX_ST(STORE_INIT(TMP2, DST)); \
-       sllx            TMP1, POST_SHIFT, PRE_VAL;
-
-1:     add             %o1, 0x8, %o1
-       SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x00)
-       add             %o1, 0x8, %o1
-       SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x08)
-       add             %o1, 0x8, %o1
-       SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x10)
-       add             %o1, 0x8, %o1
-       SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x18)
-       add             %o1, 32, %o1
-       LOAD(prefetch, %o1, #one_read)
-       sub             %o1, 32 - 8, %o1
-       SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x20)
-       add             %o1, 8, %o1
-       SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x28)
-       add             %o1, 8, %o1
-       SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x30)
-       add             %o1, 8, %o1
-       SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x38)
-       subcc           %o4, 64, %o4
-       bne,pt          %XCC, 1b
+#define MIX_THREE_WORDS(WORD1, WORD2, WORD3, PRE_SHIFT, POST_SHIFT, TMP) \
+       sllx            WORD1, POST_SHIFT, WORD1; \
+       srlx            WORD2, PRE_SHIFT, TMP; \
+       sllx            WORD2, POST_SHIFT, WORD2; \
+       or              WORD1, TMP, WORD1; \
+       srlx            WORD3, PRE_SHIFT, TMP; \
+       or              WORD2, TMP, WORD2;
+
+8:     EX_LD(LOAD_TWIN(%i1 + %o4, %o2, %o3))
+       MIX_THREE_WORDS(%g2, %g3, %o2, %i5, GLOBAL_SPARE, %o1)
+       LOAD(prefetch, %i1 + %i3, #one_read)
+
+       EX_ST(STORE_INIT(%g2, %o0 + 0x00))
+       EX_ST(STORE_INIT(%g3, %o0 + 0x08))
+
+       EX_LD(LOAD_TWIN(%i1 + %o5, %g2, %g3))
+       MIX_THREE_WORDS(%o2, %o3, %g2, %i5, GLOBAL_SPARE, %o1)
+
+       EX_ST(STORE_INIT(%o2, %o0 + 0x10))
+       EX_ST(STORE_INIT(%o3, %o0 + 0x18))
+
+       EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3))
+       MIX_THREE_WORDS(%g2, %g3, %o2, %i5, GLOBAL_SPARE, %o1)
+
+       EX_ST(STORE_INIT(%g2, %o0 + 0x20))
+       EX_ST(STORE_INIT(%g3, %o0 + 0x28))
+
+       EX_LD(LOAD_TWIN(%i1 + %i3, %g2, %g3))
+       add             %i1, 64, %i1
+       MIX_THREE_WORDS(%o2, %o3, %g2, %i5, GLOBAL_SPARE, %o1)
+
+       EX_ST(STORE_INIT(%o2, %o0 + 0x30))
+       EX_ST(STORE_INIT(%o3, %o0 + 0x38))
+
+       subcc           %g1, 64, %g1
+       bne,pt          %XCC, 8b
         add            %o0, 64, %o0
 
-#undef SWIVEL_ONE_DWORD
+       ba,pt           %XCC, 60f
+        add            %i1, %i4, %i1
+
+9:     EX_LD(LOAD_TWIN(%i1 + %o4, %o2, %o3))
+       MIX_THREE_WORDS(%g3, %o2, %o3, %i5, GLOBAL_SPARE, %o1)
+       LOAD(prefetch, %i1 + %i3, #one_read)
+
+       EX_ST(STORE_INIT(%g3, %o0 + 0x00))
+       EX_ST(STORE_INIT(%o2, %o0 + 0x08))
+
+       EX_LD(LOAD_TWIN(%i1 + %o5, %g2, %g3))
+       MIX_THREE_WORDS(%o3, %g2, %g3, %i5, GLOBAL_SPARE, %o1)
+
+       EX_ST(STORE_INIT(%o3, %o0 + 0x10))
+       EX_ST(STORE_INIT(%g2, %o0 + 0x18))
+
+       EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3))
+       MIX_THREE_WORDS(%g3, %o2, %o3, %i5, GLOBAL_SPARE, %o1)
+
+       EX_ST(STORE_INIT(%g3, %o0 + 0x20))
+       EX_ST(STORE_INIT(%o2, %o0 + 0x28))
+
+       EX_LD(LOAD_TWIN(%i1 + %i3, %g2, %g3))
+       add             %i1, 64, %i1
+       MIX_THREE_WORDS(%o3, %g2, %g3, %i5, GLOBAL_SPARE, %o1)
+
+       EX_ST(STORE_INIT(%o3, %o0 + 0x30))
+       EX_ST(STORE_INIT(%g2, %o0 + 0x38))
+
+       subcc           %g1, 64, %g1
+       bne,pt          %XCC, 9b
+        add            %o0, 64, %o0
 
-       srl             %g1, 3, %g1
        ba,pt           %XCC, 60f
-        add            %o1, %g1, %o1
+        add            %i1, %i4, %i1
 
 10:    /* Destination is 64-byte aligned, source was only 8-byte
         * aligned but it has been subtracted by 8 and we perform
         * one twin load ahead, then add 8 back into source when
         * we finish the loop.
         */
-       EX_LD(LOAD_TWIN(%o1, %o4, %o5))
-1:     add             %o1, 16, %o1
-       EX_LD(LOAD_TWIN(%o1, %g2, %g3))
-       add             %o1, 16 + 32, %o1
-       LOAD(prefetch, %o1, #one_read)
-       sub             %o1, 32, %o1
+       EX_LD(LOAD_TWIN(%i1, %o4, %o5))
+       mov     16, %o7
+       mov     32, %g2
+       mov     48, %g3
+       mov     64, %o1
+1:     EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3))
+       LOAD(prefetch, %i1 + %o1, #one_read)
        EX_ST(STORE_INIT(%o5, %o0 + 0x00))      ! initializes cache line
-       EX_ST(STORE_INIT(%g2, %o0 + 0x08))
-       EX_LD(LOAD_TWIN(%o1, %o4, %o5))
-       add             %o1, 16, %o1
-       EX_ST(STORE_INIT(%g3, %o0 + 0x10))
+       EX_ST(STORE_INIT(%o2, %o0 + 0x08))
+       EX_LD(LOAD_TWIN(%i1 + %g2, %o4, %o5))
+       EX_ST(STORE_INIT(%o3, %o0 + 0x10))
        EX_ST(STORE_INIT(%o4, %o0 + 0x18))
-       EX_LD(LOAD_TWIN(%o1, %g2, %g3))
-       add             %o1, 16, %o1
+       EX_LD(LOAD_TWIN(%i1 + %g3, %o2, %o3))
        EX_ST(STORE_INIT(%o5, %o0 + 0x20))
-       EX_ST(STORE_INIT(%g2, %o0 + 0x28))
-       EX_LD(LOAD_TWIN(%o1, %o4, %o5))
-       EX_ST(STORE_INIT(%g3, %o0 + 0x30))
+       EX_ST(STORE_INIT(%o2, %o0 + 0x28))
+       EX_LD(LOAD_TWIN(%i1 + %o1, %o4, %o5))
+       add             %i1, 64, %i1
+       EX_ST(STORE_INIT(%o3, %o0 + 0x30))
        EX_ST(STORE_INIT(%o4, %o0 + 0x38))
        subcc           %g1, 64, %g1
        bne,pt          %XCC, 1b
         add            %o0, 64, %o0
 
        ba,pt           %XCC, 60f
-        add            %o1, 0x8, %o1
+        add            %i1, 0x8, %i1
 
 50:    /* Destination is 64-byte aligned, and source is 16-byte
         * aligned.
         */
-1:     EX_LD(LOAD_TWIN(%o1, %o4, %o5))
-       add     %o1, 16, %o1
-       EX_LD(LOAD_TWIN(%o1, %g2, %g3))
-       add     %o1, 16 + 32, %o1
-       LOAD(prefetch, %o1, #one_read)
-       sub     %o1, 32, %o1
+       mov     16, %o7
+       mov     32, %g2
+       mov     48, %g3
+       mov     64, %o1
+1:     EX_LD(LOAD_TWIN(%i1 + %g0, %o4, %o5))
+       EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3))
+       LOAD(prefetch, %i1 + %o1, #one_read)
        EX_ST(STORE_INIT(%o4, %o0 + 0x00))      ! initializes cache line
        EX_ST(STORE_INIT(%o5, %o0 + 0x08))
-       EX_LD(LOAD_TWIN(%o1, %o4, %o5))
-       add     %o1, 16, %o1
-       EX_ST(STORE_INIT(%g2, %o0 + 0x10))
-       EX_ST(STORE_INIT(%g3, %o0 + 0x18))
-       EX_LD(LOAD_TWIN(%o1, %g2, %g3))
-       add     %o1, 16, %o1
+       EX_LD(LOAD_TWIN(%i1 + %g2, %o4, %o5))
+       EX_ST(STORE_INIT(%o2, %o0 + 0x10))
+       EX_ST(STORE_INIT(%o3, %o0 + 0x18))
+       EX_LD(LOAD_TWIN(%i1 + %g3, %o2, %o3))
+       add     %i1, 64, %i1
        EX_ST(STORE_INIT(%o4, %o0 + 0x20))
        EX_ST(STORE_INIT(%o5, %o0 + 0x28))
-       EX_ST(STORE_INIT(%g2, %o0 + 0x30))
-       EX_ST(STORE_INIT(%g3, %o0 + 0x38))
+       EX_ST(STORE_INIT(%o2, %o0 + 0x30))
+       EX_ST(STORE_INIT(%o3, %o0 + 0x38))
        subcc   %g1, 64, %g1
        bne,pt  %XCC, 1b
         add    %o0, 64, %o0
@@ -249,47 +304,47 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
 60:    
        membar          #Sync
 
-       /* %o2 contains any final bytes still needed to be copied
+       /* %i2 contains any final bytes still needed to be copied
         * over. If anything is left, we copy it one byte at a time.
         */
-       RESTORE_ASI(%o3)
-       brz,pt          %o2, 85f
-        sub            %o0, %o1, %o3
+       RESTORE_ASI(%i3)
+       brz,pt          %i2, 85f
+        sub            %o0, %i1, %i3
        ba,a,pt         %XCC, 90f
 
        .align          64
 70: /* 16 < len <= 64 */
        bne,pn          %XCC, 75f
-        sub            %o0, %o1, %o3
+        sub            %o0, %i1, %i3
 
 72:
-       andn            %o2, 0xf, %o4
-       and             %o2, 0xf, %o2
-1:     subcc           %o4, 0x10, %o4
-       EX_LD(LOAD(ldx, %o1, %o5))
-       add             %o1, 0x08, %o1
-       EX_LD(LOAD(ldx, %o1, %g1))
-       sub             %o1, 0x08, %o1
-       EX_ST(STORE(stx, %o5, %o1 + %o3))
-       add             %o1, 0x8, %o1
-       EX_ST(STORE(stx, %g1, %o1 + %o3))
+       andn            %i2, 0xf, %i4
+       and             %i2, 0xf, %i2
+1:     subcc           %i4, 0x10, %i4
+       EX_LD(LOAD(ldx, %i1, %o4))
+       add             %i1, 0x08, %i1
+       EX_LD(LOAD(ldx, %i1, %g1))
+       sub             %i1, 0x08, %i1
+       EX_ST(STORE(stx, %o4, %i1 + %i3))
+       add             %i1, 0x8, %i1
+       EX_ST(STORE(stx, %g1, %i1 + %i3))
        bgu,pt          %XCC, 1b
-        add            %o1, 0x8, %o1
-73:    andcc           %o2, 0x8, %g0
+        add            %i1, 0x8, %i1
+73:    andcc           %i2, 0x8, %g0
        be,pt           %XCC, 1f
         nop
-       sub             %o2, 0x8, %o2
-       EX_LD(LOAD(ldx, %o1, %o5))
-       EX_ST(STORE(stx, %o5, %o1 + %o3))
-       add             %o1, 0x8, %o1
-1:     andcc           %o2, 0x4, %g0
+       sub             %i2, 0x8, %i2
+       EX_LD(LOAD(ldx, %i1, %o4))
+       EX_ST(STORE(stx, %o4, %i1 + %i3))
+       add             %i1, 0x8, %i1
+1:     andcc           %i2, 0x4, %g0
        be,pt           %XCC, 1f
         nop
-       sub             %o2, 0x4, %o2
-       EX_LD(LOAD(lduw, %o1, %o5))
-       EX_ST(STORE(stw, %o5, %o1 + %o3))
-       add             %o1, 0x4, %o1
-1:     cmp             %o2, 0
+       sub             %i2, 0x4, %i2
+       EX_LD(LOAD(lduw, %i1, %i5))
+       EX_ST(STORE(stw, %i5, %i1 + %i3))
+       add             %i1, 0x4, %i1
+1:     cmp             %i2, 0
        be,pt           %XCC, 85f
         nop
        ba,pt           %xcc, 90f
@@ -300,71 +355,71 @@ FUNC_NAME:        /* %o0=dst, %o1=src, %o2=len */
        sub             %g1, 0x8, %g1
        be,pn           %icc, 2f
         sub            %g0, %g1, %g1
-       sub             %o2, %g1, %o2
+       sub             %i2, %g1, %i2
 
 1:     subcc           %g1, 1, %g1
-       EX_LD(LOAD(ldub, %o1, %o5))
-       EX_ST(STORE(stb, %o5, %o1 + %o3))
+       EX_LD(LOAD(ldub, %i1, %i5))
+       EX_ST(STORE(stb, %i5, %i1 + %i3))
        bgu,pt          %icc, 1b
-        add            %o1, 1, %o1
+        add            %i1, 1, %i1
 
-2:     add             %o1, %o3, %o0
-       andcc           %o1, 0x7, %g1
+2:     add             %i1, %i3, %o0
+       andcc           %i1, 0x7, %g1
        bne,pt          %icc, 8f
         sll            %g1, 3, %g1
 
-       cmp             %o2, 16
+       cmp             %i2, 16
        bgeu,pt         %icc, 72b
         nop
        ba,a,pt         %xcc, 73b
 
-8:     mov             64, %o3
-       andn            %o1, 0x7, %o1
-       EX_LD(LOAD(ldx, %o1, %g2))
-       sub             %o3, %g1, %o3
-       andn            %o2, 0x7, %o4
+8:     mov             64, %i3
+       andn            %i1, 0x7, %i1
+       EX_LD(LOAD(ldx, %i1, %g2))
+       sub             %i3, %g1, %i3
+       andn            %i2, 0x7, %i4
        sllx            %g2, %g1, %g2
-1:     add             %o1, 0x8, %o1
-       EX_LD(LOAD(ldx, %o1, %g3))
-       subcc           %o4, 0x8, %o4
-       srlx            %g3, %o3, %o5
-       or              %o5, %g2, %o5
-       EX_ST(STORE(stx, %o5, %o0))
+1:     add             %i1, 0x8, %i1
+       EX_LD(LOAD(ldx, %i1, %g3))
+       subcc           %i4, 0x8, %i4
+       srlx            %g3, %i3, %i5
+       or              %i5, %g2, %i5
+       EX_ST(STORE(stx, %i5, %o0))
        add             %o0, 0x8, %o0
        bgu,pt          %icc, 1b
         sllx           %g3, %g1, %g2
 
        srl             %g1, 3, %g1
-       andcc           %o2, 0x7, %o2
+       andcc           %i2, 0x7, %i2
        be,pn           %icc, 85f
-        add            %o1, %g1, %o1
+        add            %i1, %g1, %i1
        ba,pt           %xcc, 90f
-        sub            %o0, %o1, %o3
+        sub            %o0, %i1, %i3
 
        .align          64
 80: /* 0 < len <= 16 */
-       andcc           %o3, 0x3, %g0
+       andcc           %i3, 0x3, %g0
        bne,pn          %XCC, 90f
-        sub            %o0, %o1, %o3
+        sub            %o0, %i1, %i3
 
 1:
-       subcc           %o2, 4, %o2
-       EX_LD(LOAD(lduw, %o1, %g1))
-       EX_ST(STORE(stw, %g1, %o1 + %o3))
+       subcc           %i2, 4, %i2
+       EX_LD(LOAD(lduw, %i1, %g1))
+       EX_ST(STORE(stw, %g1, %i1 + %i3))
        bgu,pt          %XCC, 1b
-        add            %o1, 4, %o1
+        add            %i1, 4, %i1
 
-85:    retl
-        mov            EX_RETVAL(GLOBAL_SPARE), %o0
+85:    ret
+        restore        EX_RETVAL(%i0), %g0, %o0
 
        .align          32
 90:
-       subcc           %o2, 1, %o2
-       EX_LD(LOAD(ldub, %o1, %g1))
-       EX_ST(STORE(stb, %g1, %o1 + %o3))
+       subcc           %i2, 1, %i2
+       EX_LD(LOAD(ldub, %i1, %g1))
+       EX_ST(STORE(stb, %g1, %i1 + %i3))
        bgu,pt          %XCC, 90b
-        add            %o1, 1, %o1
-       retl
-        mov            EX_RETVAL(GLOBAL_SPARE), %o0
+        add            %i1, 1, %i1
+       ret
+        restore        EX_RETVAL(%i0), %g0, %o0
 
        .size           FUNC_NAME, .-FUNC_NAME
index 5304204..4af67c7 100644 (file)
@@ -1 +1 @@
-#define VDSO_TEXT_OFFSET 0x500
+#define VDSO_TEXT_OFFSET 0x600
index a858bc5..b833891 100644 (file)
@@ -117,6 +117,7 @@ config ACPI_BUTTON
 config ACPI_VIDEO
        tristate "Video"
        depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL
+       depends on INPUT
        help
          This driver implement the ACPI Extensions For Display Adapters
          for integrated graphics devices on motherboard, as specified in
index cf69c00..8181afb 100644 (file)
@@ -234,15 +234,11 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
                                "While executing method _SST"));
        }
 
-       /*
-        * 1) Disable/Clear all GPEs
-        */
+       /* Disable/Clear all GPEs */
+
        status = acpi_hw_disable_all_gpes();
-       if (ACPI_FAILURE(status)) {
-               return_ACPI_STATUS(status);
-       }
 
-       return_ACPI_STATUS(AE_OK);
+       return_ACPI_STATUS(status);
 }
 
 ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
index 2cbb9aa..caf8721 100644 (file)
@@ -256,6 +256,11 @@ static int acpi_hibernation_enter(void)
 
 static void acpi_hibernation_finish(void)
 {
+       /*
+        * If ACPI is not enabled by the BIOS and the boot kernel, we need to
+        * enable it here.
+        */
+       acpi_enable();
        acpi_leave_sleep_state(ACPI_STATE_S4);
        acpi_disable_wakeup_device(ACPI_STATE_S4);
 
index 8cc9492..5f1d85f 100644 (file)
@@ -400,7 +400,7 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
        u32 table_count;
        struct acpi_table_header *table;
        acpi_physical_address address;
-       acpi_physical_address rsdt_address;
+       acpi_physical_address uninitialized_var(rsdt_address);
        u32 length;
        u8 *table_entry;
        acpi_status status;
index bc6d586..69ec73b 100644 (file)
@@ -195,6 +195,7 @@ struct acpi_thermal {
        struct acpi_thermal_trips trips;
        struct acpi_handle_list devices;
        struct timer_list timer;
+       struct mutex lock;
 };
 
 static const struct file_operations acpi_thermal_state_fops = {
@@ -711,6 +712,7 @@ static void acpi_thermal_check(void *data)
        int result = 0;
        struct acpi_thermal *tz = data;
        unsigned long sleep_time = 0;
+       unsigned long timeout_jiffies = 0;
        int i = 0;
        struct acpi_thermal_state state;
 
@@ -720,11 +722,15 @@ static void acpi_thermal_check(void *data)
                return;
        }
 
+       /* Check if someone else is already running */
+       if (!mutex_trylock(&tz->lock))
+               return;
+
        state = tz->state;
 
        result = acpi_thermal_get_temperature(tz);
        if (result)
-               return;
+               goto unlock;
 
        memset(&tz->state, 0, sizeof(tz->state));
 
@@ -787,10 +793,13 @@ static void acpi_thermal_check(void *data)
         * a thermal event occurs).  Note that _TSP and _TZD values are
         * given in 1/10th seconds (we must covert to milliseconds).
         */
-       if (tz->state.passive)
+       if (tz->state.passive) {
                sleep_time = tz->trips.passive.tsp * 100;
-       else if (tz->polling_frequency > 0)
+               timeout_jiffies =  jiffies + (HZ * sleep_time) / 1000;
+       } else if (tz->polling_frequency > 0) {
                sleep_time = tz->polling_frequency * 100;
+               timeout_jiffies =  round_jiffies(jiffies + (HZ * sleep_time) / 1000);
+       }
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n",
                          tz->name, tz->temperature, sleep_time));
@@ -804,17 +813,16 @@ static void acpi_thermal_check(void *data)
                        del_timer(&(tz->timer));
        } else {
                if (timer_pending(&(tz->timer)))
-                       mod_timer(&(tz->timer),
-                                       jiffies + (HZ * sleep_time) / 1000);
+                       mod_timer(&(tz->timer), timeout_jiffies);
                else {
                        tz->timer.data = (unsigned long)tz;
                        tz->timer.function = acpi_thermal_run;
-                       tz->timer.expires = jiffies + (HZ * sleep_time) / 1000;
+                       tz->timer.expires = timeout_jiffies;
                        add_timer(&(tz->timer));
                }
        }
-
-       return;
+      unlock:
+       mutex_unlock(&tz->lock);
 }
 
 /* --------------------------------------------------------------------------
@@ -1251,7 +1259,7 @@ static int acpi_thermal_add(struct acpi_device *device)
        strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS);
        acpi_driver_data(device) = tz;
-
+       mutex_init(&tz->lock);
        result = acpi_thermal_get_info(tz);
        if (result)
                goto end;
@@ -1321,7 +1329,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
        }
 
        acpi_thermal_remove_fs(device);
-
+       mutex_destroy(&tz->lock);
        kfree(tz);
        return 0;
 }
index d05891f..f31e3c8 100644 (file)
@@ -409,14 +409,17 @@ acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
 static int
 acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
 {
-       int status;
+       int status = AE_OK;
        union acpi_object arg0 = { ACPI_TYPE_INTEGER };
        struct acpi_object_list args = { 1, &arg0 };
 
 
        arg0.integer.value = level;
-       status = acpi_evaluate_object(device->dev->handle, "_BCM", &args, NULL);
 
+       if (device->cap._BCM)
+               status = acpi_evaluate_object(device->dev->handle, "_BCM",
+                                             &args, NULL);
+       device->brightness->curr = level;
        return status;
 }
 
@@ -424,11 +427,11 @@ static int
 acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
                                        unsigned long *level)
 {
-       int status;
-
-       status = acpi_evaluate_integer(device->dev->handle, "_BQC", NULL, level);
-
-       return status;
+       if (device->cap._BQC)
+               return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL,
+                                            level);
+       *level = device->brightness->curr;
+       return AE_OK;
 }
 
 static int
@@ -1633,9 +1636,20 @@ static int
 acpi_video_get_next_level(struct acpi_video_device *device,
                          u32 level_current, u32 event)
 {
-       int min, max, min_above, max_below, i, l;
+       int min, max, min_above, max_below, i, l, delta = 255;
        max = max_below = 0;
        min = min_above = 255;
+       /* Find closest level to level_current */
+       for (i = 0; i < device->brightness->count; i++) {
+               l = device->brightness->levels[i];
+               if (abs(l - level_current) < abs(delta)) {
+                       delta = l - level_current;
+                       if (!delta)
+                               break;
+               }
+       }
+       /* Ajust level_current to closest available level */
+       level_current += delta;
        for (i = 0; i < device->brightness->count; i++) {
                l = device->brightness->levels[i];
                if (l < min)
index 3b8bf18..6996eb5 100644 (file)
@@ -921,6 +921,13 @@ static int piix_broken_suspend(void)
 {
        static struct dmi_system_id sysids[] = {
                {
+                       .ident = "TECRA M3",
+                       .matches = {
+                               DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+                               DMI_MATCH(DMI_PRODUCT_NAME, "TECRA M3"),
+                       },
+               },
+               {
                        .ident = "TECRA M5",
                        .matches = {
                                DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
index 4ca7fd6..5dea358 100644 (file)
@@ -189,6 +189,9 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
        data->cs0 = devm_ioremap(&pdev->dev, cs0->start, 0x1000);
        data->cs1 = devm_ioremap(&pdev->dev, cs1->start, 0x1000);
 
+       if (!data->cs0 || !data->cs1)
+               return -ENOMEM;
+
        irq = platform_get_irq(pdev, 0);
        if (irq)
                set_irq_type(irq, IRQT_RISING);
index ae206f3..b45506f 100644 (file)
@@ -44,10 +44,10 @@ static int marvell_pre_reset(struct ata_port *ap, unsigned long deadline)
                return -ENOMEM;
        printk("BAR5:");
        for(i = 0; i <= 0x0F; i++)
-               printk("%02X:%02X ", i, readb(barp + i));
+               printk("%02X:%02X ", i, ioread8(barp + i));
        printk("\n");
 
-       devices = readl(barp + 0x0C);
+       devices = ioread32(barp + 0x0C);
        pci_iounmap(pdev, barp);
 
        if ((pdev->device == 0x6145) && (ap->port_no == 0) &&
index 11bf6c7..cb7dec9 100644 (file)
@@ -313,7 +313,10 @@ enum {
 #define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE)
 
 enum {
-       MV_DMA_BOUNDARY         = 0xffffffffU,
+       /* DMA boundary 0xffff is required by the s/g splitting
+        * we need on /length/ in mv_fill-sg().
+        */
+       MV_DMA_BOUNDARY         = 0xffffU,
 
        /* mask of register bits containing lower 32 bits
         * of EDMA request queue DMA address
@@ -448,7 +451,7 @@ static struct scsi_host_template mv5_sht = {
        .queuecommand           = ata_scsi_queuecmd,
        .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
-       .sg_tablesize           = MV_MAX_SG_CT,
+       .sg_tablesize           = MV_MAX_SG_CT / 2,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
        .use_clustering         = 1,
@@ -466,7 +469,7 @@ static struct scsi_host_template mv6_sht = {
        .queuecommand           = ata_scsi_queuecmd,
        .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
-       .sg_tablesize           = MV_MAX_SG_CT,
+       .sg_tablesize           = MV_MAX_SG_CT / 2,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
        .use_clustering         = 1,
@@ -1139,15 +1142,27 @@ static unsigned int mv_fill_sg(struct ata_queued_cmd *qc)
                dma_addr_t addr = sg_dma_address(sg);
                u32 sg_len = sg_dma_len(sg);
 
-               mv_sg->addr = cpu_to_le32(addr & 0xffffffff);
-               mv_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16);
-               mv_sg->flags_size = cpu_to_le32(sg_len & 0xffff);
+               while (sg_len) {
+                       u32 offset = addr & 0xffff;
+                       u32 len = sg_len;
+
+                       if ((offset + sg_len > 0x10000))
+                               len = 0x10000 - offset;
+
+                       mv_sg->addr = cpu_to_le32(addr & 0xffffffff);
+                       mv_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16);
+                       mv_sg->flags_size = cpu_to_le32(len);
 
-               if (ata_sg_is_last(sg, qc))
-                       mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
+                       sg_len -= len;
+                       addr += len;
+
+                       if (!sg_len && ata_sg_is_last(sg, qc))
+                               mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
+
+                       mv_sg++;
+                       n_sg++;
+               }
 
-               mv_sg++;
-               n_sg++;
        }
 
        return n_sg;
index 67c9258..ec86d6f 100644 (file)
@@ -586,9 +586,13 @@ void device_initialize(struct device *dev)
 static struct kobject * get_device_parent(struct device *dev,
                                          struct device *parent)
 {
-       /* Set the parent to the class, not the parent device */
-       /* this keeps sysfs from having a symlink to make old udevs happy */
-       if (dev->class)
+       /*
+        * Set the parent to the class, not the parent device
+        * for topmost devices in class hierarchy.
+        * This keeps sysfs from having a symlink to make old
+        * udevs happy
+        */
+       if (dev->class && (!parent || parent->class != dev->class))
                return &dev->class->subsys.kobj;
        else if (parent)
                return &parent->kobj;
index d68ddbe..c78ff26 100644 (file)
@@ -129,7 +129,7 @@ $(obj)/defkeymap.o:  $(obj)/defkeymap.c
 
 ifdef GENERATE_KEYMAP
 
-$(obj)/defkeymap.c $(obj)/%.c: $(src)/%.map
+$(obj)/defkeymap.c: $(obj)/%.c: $(src)/%.map
        loadkeys --mktable $< > $@.tmp
        sed -e 's/^static *//' $@.tmp > $@
        rm $@.tmp
index a5d0e95..141ca17 100644 (file)
@@ -506,11 +506,6 @@ static void intel_i830_init_gtt_entries(void)
                        break;
                }
        } else {
-               /* G33's GTT stolen memory is separate from gfx data
-                * stolen memory.
-                */
-               if (IS_G33)
-                       size = 0;
                switch (gmch_ctrl & I855_GMCH_GMS_MASK) {
                case I855_GMCH_GMS_STOLEN_1M:
                        gtt_entries = MB(1) - KB(size);
index 737088b..28b9873 100644 (file)
@@ -210,6 +210,12 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
 #define I915REG_INT_MASK_R     0x020a8
 #define I915REG_INT_ENABLE_R   0x020a0
 
+#define I915REG_PIPEASTAT      0x70024
+#define I915REG_PIPEBSTAT      0x71024
+
+#define I915_VBLANK_INTERRUPT_ENABLE   (1UL<<17)
+#define I915_VBLANK_CLEAR              (1UL<<1)
+
 #define SRX_INDEX              0x3c4
 #define SRX_DATA               0x3c5
 #define SR01                   1
index 4b4b2ce..bb8e9e9 100644 (file)
@@ -214,6 +214,10 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
        struct drm_device *dev = (struct drm_device *) arg;
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        u16 temp;
+       u32 pipea_stats, pipeb_stats;
+
+       pipea_stats = I915_READ(I915REG_PIPEASTAT);
+       pipeb_stats = I915_READ(I915REG_PIPEBSTAT);
 
        temp = I915_READ16(I915REG_INT_IDENTITY_R);
 
@@ -225,6 +229,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
                return IRQ_NONE;
 
        I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
+       (void) I915_READ16(I915REG_INT_IDENTITY_R);
+       DRM_READMEMORYBARRIER();
 
        dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
 
@@ -252,6 +258,12 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
 
                if (dev_priv->swaps_pending > 0)
                        drm_locked_tasklet(dev, i915_vblank_tasklet);
+               I915_WRITE(I915REG_PIPEASTAT,
+                       pipea_stats|I915_VBLANK_INTERRUPT_ENABLE|
+                       I915_VBLANK_CLEAR);
+               I915_WRITE(I915REG_PIPEBSTAT,
+                       pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE|
+                       I915_VBLANK_CLEAR);
        }
 
        return IRQ_HANDLED;
index 397c714..af274e5 100644 (file)
@@ -1550,11 +1550,13 @@ __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr,
         *      As close as possible to RFC 793, which
         *      suggests using a 250 kHz clock.
         *      Further reading shows this assumes 2 Mb/s networks.
-        *      For 10 Gb/s Ethernet, a 1 GHz clock is appropriate.
-        *      That's funny, Linux has one built in!  Use it!
-        *      (Networks are faster now - should this be increased?)
+        *      For 10 Mb/s Ethernet, a 1 MHz clock is appropriate.
+        *      For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but
+        *      we also need to limit the resolution so that the u32 seq
+        *      overlaps less than one time per MSL (2 minutes).
+        *      Choosing a clock of 64 ns period is OK. (period of 274 s)
         */
-       seq += ktime_get_real().tv64;
+       seq += ktime_get_real().tv64 >> 6;
 #if 0
        printk("init_seq(%lx, %lx, %d, %d) = %d\n",
               saddr, daddr, sport, dport, seq);
index c6f6f42..7a61a2a 100644 (file)
@@ -770,6 +770,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                /*
                 * Switching-from response
                 */
+               acquire_console_sem();
                if (vc->vt_newvt >= 0) {
                        if (arg == 0)
                                /*
@@ -784,7 +785,6 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                                 * complete the switch.
                                 */
                                int newvt;
-                               acquire_console_sem();
                                newvt = vc->vt_newvt;
                                vc->vt_newvt = -1;
                                i = vc_allocate(newvt);
@@ -798,7 +798,6 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                                 * other console switches..
                                 */
                                complete_change_console(vc_cons[newvt].d);
-                               release_console_sem();
                        }
                }
 
@@ -810,9 +809,12 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                        /*
                         * If it's just an ACK, ignore it
                         */
-                       if (arg != VT_ACKACQ)
+                       if (arg != VT_ACKACQ) {
+                               release_console_sem();
                                return -EINVAL;
+                       }
                }
+               release_console_sem();
 
                return 0;
 
@@ -1030,7 +1032,7 @@ static DECLARE_WAIT_QUEUE_HEAD(vt_activate_queue);
 
 /*
  * Sleeps until a vt is activated, or the task is interrupted. Returns
- * 0 if activation, -EINTR if interrupted.
+ * 0 if activation, -EINTR if interrupted by a signal handler.
  */
 int vt_waitactive(int vt)
 {
@@ -1055,7 +1057,7 @@ int vt_waitactive(int vt)
                        break;
                }
                release_console_sem();
-               retval = -EINTR;
+               retval = -ERESTARTNOHAND;
                if (signal_pending(current))
                        break;
                schedule();
@@ -1208,15 +1210,18 @@ void change_console(struct vc_data *new_vc)
                /*
                 * Send the signal as privileged - kill_pid() will
                 * tell us if the process has gone or something else
-                * is awry
+                * is awry.
+                *
+                * We need to set vt_newvt *before* sending the signal or we
+                * have a race.
                 */
+               vc->vt_newvt = new_vc->vc_num;
                if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
                        /*
                         * It worked. Mark the vt to switch to and
                         * return. The process needs to send us a
                         * VT_RELDISP ioctl to complete the switch.
                         */
-                       vc->vt_newvt = new_vc->vc_num;
                        return;
                }
 
index d011a76..fe9e768 100644 (file)
@@ -11,7 +11,8 @@ config FIREWIRE
          This is the "Juju" FireWire stack, a new alternative implementation
          designed for robustness and simplicity.  You can build either this
          stack, or the classic stack (the ieee1394 driver, ohci1394 etc.)
-         or both.
+         or both.  Please read http://wiki.linux1394.org/JujuMigration before
+         you enable the new stack.
 
          To compile this driver as a module, say M here: the module will be
          called firewire-core.  It functionally replaces ieee1394, raw1394,
index f19eb6d..2fb047b 100644 (file)
@@ -1546,6 +1546,7 @@ static struct pci_device_id pmac_ide_pci_match[] = {
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID2_ATA,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {},
 };
 
 static struct pci_driver pmac_ide_pci_driver = {
index e2abe18..7c662ee 100644 (file)
@@ -277,7 +277,7 @@ config JOYSTICK_XPAD_FF
 
 config JOYSTICK_XPAD_LEDS
        bool "LED Support for Xbox360 controller 'BigX' LED"
-       depends on LEDS_CLASS && JOYSTICK_XPAD
+       depends on JOYSTICK_XPAD && (LEDS_CLASS=y || LEDS_CLASS=JOYSTICK_XPAD)
        ---help---
          This option enables support for the LED which surrounds the Big X on
          XBox 360 controller.
index ec5f404..4910bca 100644 (file)
@@ -1135,7 +1135,7 @@ isdn_read(struct file *file, char __user *buf, size_t count, loff_t * off)
                        if (count > dev->drv[drvidx]->stavail)
                                count = dev->drv[drvidx]->stavail;
                        len = dev->drv[drvidx]->interface->readstat(buf, count,
-                                               drvidx, isdn_minor2chan(minor));
+                               drvidx, isdn_minor2chan(minor - ISDN_MINOR_CTRL));
                        if (len < 0) {
                                retval = len;
                                goto out;
@@ -1207,7 +1207,8 @@ isdn_write(struct file *file, const char __user *buf, size_t count, loff_t * off
                 */
                if (dev->drv[drvidx]->interface->writecmd)
                        retval = dev->drv[drvidx]->interface->
-                               writecmd(buf, count, drvidx, isdn_minor2chan(minor));
+                               writecmd(buf, count, drvidx,
+                               isdn_minor2chan(minor - ISDN_MINOR_CTRL));
                else
                        retval = count;
                goto out;
index 0285c4a..66ea3cb 100644 (file)
@@ -754,9 +754,11 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts)
                ivtv_yuv_close(itv);
        }
        if (s->type == IVTV_DEC_STREAM_TYPE_YUV && itv->output_mode == OUT_YUV)
-           itv->output_mode = OUT_NONE;
+               itv->output_mode = OUT_NONE;
+       else if (s->type == IVTV_DEC_STREAM_TYPE_YUV && itv->output_mode == OUT_UDMA_YUV)
+               itv->output_mode = OUT_NONE;
        else if (s->type == IVTV_DEC_STREAM_TYPE_MPG && itv->output_mode == OUT_MPG)
-           itv->output_mode = OUT_NONE;
+               itv->output_mode = OUT_NONE;
 
        itv->speed = 0;
        clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);
index 73e248f..e0a1ff9 100644 (file)
@@ -111,6 +111,21 @@ config ASUS_LAPTOP
 
          If you have an ACPI-compatible ASUS laptop, say Y or M here.
 
+config FUJITSU_LAPTOP
+        tristate "Fujitsu Laptop Extras"
+        depends on X86
+        depends on ACPI
+        depends on BACKLIGHT_CLASS_DEVICE
+        ---help---
+         This is a driver for laptops built by Fujitsu:
+
+           * P2xxx/P5xxx/S6xxx/S7xxx series Lifebooks
+           * Possibly other Fujitsu laptop models
+
+         It adds support for LCD brightness control.
+
+         If you have a Fujitsu laptop, say Y or M here.
+
 config MSI_LAPTOP
         tristate "MSI Laptop Extras"
         depends on X86
@@ -134,6 +149,7 @@ config SONY_LAPTOP
        tristate "Sony Laptop Extras"
        depends on X86 && ACPI
        select BACKLIGHT_CLASS_DEVICE
+       depends on INPUT
          ---help---
          This mini-driver drives the SNC and SPIC devices present in the ACPI
          BIOS of the Sony Vaio laptops.
@@ -156,6 +172,7 @@ config THINKPAD_ACPI
        select BACKLIGHT_CLASS_DEVICE
        select HWMON
        select NVRAM
+       depends on INPUT
        ---help---
          This is a driver for the IBM and Lenovo ThinkPad laptops. It adds
          support for Fn-Fx key combinations, Bluetooth control, video
index b5ce0e3..be90d48 100644 (file)
@@ -14,4 +14,5 @@ obj-$(CONFIG_PHANTOM)         += phantom.o
 obj-$(CONFIG_SGI_IOC4)         += ioc4.o
 obj-$(CONFIG_SONY_LAPTOP)      += sony-laptop.o
 obj-$(CONFIG_THINKPAD_ACPI)    += thinkpad_acpi.o
+obj-$(CONFIG_FUJITSU_LAPTOP)   += fujitsu-laptop.o
 obj-$(CONFIG_EEPROM_93CX6)     += eeprom_93cx6.o
diff --git a/drivers/misc/fujitsu-laptop.c b/drivers/misc/fujitsu-laptop.c
new file mode 100644 (file)
index 0000000..d366a6c
--- /dev/null
@@ -0,0 +1,358 @@
+/*-*-linux-c-*-*/
+
+/*
+  Copyright (C) 2007 Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
+  Based on earlier work:
+    Copyright (C) 2003 Shane Spencer <shane@bogomip.com>
+    Adrian Yee <brewt-fujitsu@brewt.org>
+
+  Templated from msi-laptop.c which is copyright by its respective authors.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+  02110-1301, USA.
+ */
+
+/*
+ * fujitsu-laptop.c - Fujitsu laptop support, providing access to additional
+ * features made available on a range of Fujitsu laptops including the
+ * P2xxx/P5xxx/S6xxx/S7xxx series.
+ *
+ * This driver exports a few files in /sys/devices/platform/fujitsu-laptop/;
+ * others may be added at a later date.
+ *
+ *   lcd_level - Screen brightness: contains a single integer in the
+ *   range 0..7. (rw)
+ *
+ * In addition to these platform device attributes the driver
+ * registers itself in the Linux backlight control subsystem and is
+ * available to userspace under /sys/class/backlight/fujitsu-laptop/.
+ *
+ * This driver has been tested on a Fujitsu Lifebook S7020.  It should
+ * work on most P-series and S-series Lifebooks, but YMMV.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+#include <linux/backlight.h>
+#include <linux/platform_device.h>
+#include <linux/autoconf.h>
+
+#define FUJITSU_DRIVER_VERSION "0.3"
+
+#define FUJITSU_LCD_N_LEVELS 8
+
+#define ACPI_FUJITSU_CLASS              "fujitsu"
+#define ACPI_FUJITSU_HID                "FUJ02B1"
+#define ACPI_FUJITSU_DRIVER_NAME        "Fujitsu laptop FUJ02B1 ACPI extras driver"
+#define ACPI_FUJITSU_DEVICE_NAME        "Fujitsu FUJ02B1"
+
+struct fujitsu_t {
+       acpi_handle acpi_handle;
+       struct backlight_device *bl_device;
+       struct platform_device *pf_device;
+
+       unsigned long fuj02b1_state;
+       unsigned int brightness_changed;
+       unsigned int brightness_level;
+};
+
+static struct fujitsu_t *fujitsu;
+
+/* Hardware access */
+
+static int set_lcd_level(int level)
+{
+       acpi_status status = AE_OK;
+       union acpi_object arg0 = { ACPI_TYPE_INTEGER };
+       struct acpi_object_list arg_list = { 1, &arg0 };
+       acpi_handle handle = NULL;
+
+       if (level < 0 || level >= FUJITSU_LCD_N_LEVELS)
+               return -EINVAL;
+
+       if (!fujitsu)
+               return -EINVAL;
+
+       status = acpi_get_handle(fujitsu->acpi_handle, "SBLL", &handle);
+       if (ACPI_FAILURE(status)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "SBLL not present\n"));
+               return -ENODEV;
+       }
+
+       arg0.integer.value = level;
+
+       status = acpi_evaluate_object(handle, NULL, &arg_list, NULL);
+       if (ACPI_FAILURE(status))
+               return -ENODEV;
+
+       return 0;
+}
+
+static int get_lcd_level(void)
+{
+       unsigned long state = 0;
+       acpi_status status = AE_OK;
+
+       // Get the Brightness
+       status =
+           acpi_evaluate_integer(fujitsu->acpi_handle, "GBLL", NULL, &state);
+       if (status < 0)
+               return status;
+
+       fujitsu->fuj02b1_state = state;
+       fujitsu->brightness_level = state & 0x0fffffff;
+
+       if (state & 0x80000000)
+               fujitsu->brightness_changed = 1;
+       else
+               fujitsu->brightness_changed = 0;
+
+       if (status < 0)
+               return status;
+
+       return fujitsu->brightness_level;
+}
+
+/* Backlight device stuff */
+
+static int bl_get_brightness(struct backlight_device *b)
+{
+       return get_lcd_level();
+}
+
+static int bl_update_status(struct backlight_device *b)
+{
+       return set_lcd_level(b->props.brightness);
+}
+
+static struct backlight_ops fujitsubl_ops = {
+       .get_brightness = bl_get_brightness,
+       .update_status = bl_update_status,
+};
+
+/* Platform device */
+
+static ssize_t show_lcd_level(struct device *dev,
+                             struct device_attribute *attr, char *buf)
+{
+
+       int ret;
+
+       ret = get_lcd_level();
+       if (ret < 0)
+               return ret;
+
+       return sprintf(buf, "%i\n", ret);
+}
+
+static ssize_t store_lcd_level(struct device *dev,
+                              struct device_attribute *attr, const char *buf,
+                              size_t count)
+{
+
+       int level, ret;
+
+       if (sscanf(buf, "%i", &level) != 1
+           || (level < 0 || level >= FUJITSU_LCD_N_LEVELS))
+               return -EINVAL;
+
+       ret = set_lcd_level(level);
+       if (ret < 0)
+               return ret;
+
+       return count;
+}
+
+static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level);
+
+static struct attribute *fujitsupf_attributes[] = {
+       &dev_attr_lcd_level.attr,
+       NULL
+};
+
+static struct attribute_group fujitsupf_attribute_group = {
+       .attrs = fujitsupf_attributes
+};
+
+static struct platform_driver fujitsupf_driver = {
+       .driver = {
+                  .name = "fujitsu-laptop",
+                  .owner = THIS_MODULE,
+                  }
+};
+
+/* ACPI device */
+
+int acpi_fujitsu_add(struct acpi_device *device)
+{
+       int result = 0;
+       int state = 0;
+
+       ACPI_FUNCTION_TRACE("acpi_fujitsu_add");
+
+       if (!device)
+               return -EINVAL;
+
+       fujitsu->acpi_handle = device->handle;
+       sprintf(acpi_device_name(device), "%s", ACPI_FUJITSU_DEVICE_NAME);
+       sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
+       acpi_driver_data(device) = fujitsu;
+
+       result = acpi_bus_get_power(fujitsu->acpi_handle, &state);
+       if (result) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+                                 "Error reading power state\n"));
+               goto end;
+       }
+
+       printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
+              acpi_device_name(device), acpi_device_bid(device),
+              !device->power.state ? "on" : "off");
+
+      end:
+
+       return result;
+}
+
+int acpi_fujitsu_remove(struct acpi_device *device, int type)
+{
+       ACPI_FUNCTION_TRACE("acpi_fujitsu_remove");
+
+       if (!device || !acpi_driver_data(device))
+               return -EINVAL;
+       fujitsu->acpi_handle = 0;
+
+       return 0;
+}
+
+static const struct acpi_device_id fujitsu_device_ids[] = {
+       {ACPI_FUJITSU_HID, 0},
+       {"", 0},
+};
+
+static struct acpi_driver acpi_fujitsu_driver = {
+       .name = ACPI_FUJITSU_DRIVER_NAME,
+       .class = ACPI_FUJITSU_CLASS,
+       .ids = fujitsu_device_ids,
+       .ops = {
+               .add = acpi_fujitsu_add,
+               .remove = acpi_fujitsu_remove,
+               },
+};
+
+/* Initialization */
+
+static int __init fujitsu_init(void)
+{
+       int ret, result;
+
+       if (acpi_disabled)
+               return -ENODEV;
+
+       fujitsu = kmalloc(sizeof(struct fujitsu_t), GFP_KERNEL);
+       if (!fujitsu)
+               return -ENOMEM;
+       memset(fujitsu, 0, sizeof(struct fujitsu_t));
+
+       result = acpi_bus_register_driver(&acpi_fujitsu_driver);
+       if (result < 0) {
+               ret = -ENODEV;
+               goto fail_acpi;
+       }
+
+       /* Register backlight stuff */
+
+       fujitsu->bl_device =
+           backlight_device_register("fujitsu-laptop", NULL, NULL,
+                                     &fujitsubl_ops);
+       if (IS_ERR(fujitsu->bl_device))
+               return PTR_ERR(fujitsu->bl_device);
+
+       fujitsu->bl_device->props.max_brightness = FUJITSU_LCD_N_LEVELS - 1;
+       ret = platform_driver_register(&fujitsupf_driver);
+       if (ret)
+               goto fail_backlight;
+
+       /* Register platform stuff */
+
+       fujitsu->pf_device = platform_device_alloc("fujitsu-laptop", -1);
+       if (!fujitsu->pf_device) {
+               ret = -ENOMEM;
+               goto fail_platform_driver;
+       }
+
+       ret = platform_device_add(fujitsu->pf_device);
+       if (ret)
+               goto fail_platform_device1;
+
+       ret =
+           sysfs_create_group(&fujitsu->pf_device->dev.kobj,
+                              &fujitsupf_attribute_group);
+       if (ret)
+               goto fail_platform_device2;
+
+       printk(KERN_INFO "fujitsu-laptop: driver " FUJITSU_DRIVER_VERSION
+              " successfully loaded.\n");
+
+       return 0;
+
+      fail_platform_device2:
+
+       platform_device_del(fujitsu->pf_device);
+
+      fail_platform_device1:
+
+       platform_device_put(fujitsu->pf_device);
+
+      fail_platform_driver:
+
+       platform_driver_unregister(&fujitsupf_driver);
+
+      fail_backlight:
+
+       backlight_device_unregister(fujitsu->bl_device);
+
+      fail_acpi:
+
+       kfree(fujitsu);
+
+       return ret;
+}
+
+static void __exit fujitsu_cleanup(void)
+{
+       sysfs_remove_group(&fujitsu->pf_device->dev.kobj,
+                          &fujitsupf_attribute_group);
+       platform_device_unregister(fujitsu->pf_device);
+       platform_driver_unregister(&fujitsupf_driver);
+       backlight_device_unregister(fujitsu->bl_device);
+
+       acpi_bus_unregister_driver(&acpi_fujitsu_driver);
+
+       kfree(fujitsu);
+
+       printk(KERN_INFO "fujitsu-laptop: driver unloaded.\n");
+}
+
+module_init(fujitsu_init);
+module_exit(fujitsu_cleanup);
+
+MODULE_AUTHOR("Jonathan Woithe");
+MODULE_DESCRIPTION("Fujitsu laptop extras support");
+MODULE_VERSION(FUJITSU_DRIVER_VERSION);
+MODULE_LICENSE("GPL");
index d38ddce..f248080 100644 (file)
@@ -1173,7 +1173,8 @@ static struct acpi_driver sony_nc_driver = {
 #define SONYPI_TYPE3_OFFSET    0x12
 
 struct sony_pic_ioport {
-       struct acpi_resource_io io;
+       struct acpi_resource_io io1;
+       struct acpi_resource_io io2;
        struct list_head        list;
 };
 
@@ -1443,11 +1444,11 @@ static u8 sony_pic_call1(u8 dev)
 {
        u8 v1, v2;
 
-       wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2,
+       wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2,
                        ITERATIONS_LONG);
-       outb(dev, spic_dev.cur_ioport->io.minimum + 4);
-       v1 = inb_p(spic_dev.cur_ioport->io.minimum + 4);
-       v2 = inb_p(spic_dev.cur_ioport->io.minimum);
+       outb(dev, spic_dev.cur_ioport->io1.minimum + 4);
+       v1 = inb_p(spic_dev.cur_ioport->io1.minimum + 4);
+       v2 = inb_p(spic_dev.cur_ioport->io1.minimum);
        dprintk("sony_pic_call1: 0x%.4x\n", (v2 << 8) | v1);
        return v2;
 }
@@ -1456,13 +1457,13 @@ static u8 sony_pic_call2(u8 dev, u8 fn)
 {
        u8 v1;
 
-       wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2,
+       wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2,
                        ITERATIONS_LONG);
-       outb(dev, spic_dev.cur_ioport->io.minimum + 4);
-       wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2,
+       outb(dev, spic_dev.cur_ioport->io1.minimum + 4);
+       wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2,
                        ITERATIONS_LONG);
-       outb(fn, spic_dev.cur_ioport->io.minimum);
-       v1 = inb_p(spic_dev.cur_ioport->io.minimum);
+       outb(fn, spic_dev.cur_ioport->io1.minimum);
+       v1 = inb_p(spic_dev.cur_ioport->io1.minimum);
        dprintk("sony_pic_call2: 0x%.4x\n", v1);
        return v1;
 }
@@ -1471,13 +1472,13 @@ static u8 sony_pic_call3(u8 dev, u8 fn, u8 v)
 {
        u8 v1;
 
-       wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG);
-       outb(dev, spic_dev.cur_ioport->io.minimum + 4);
-       wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG);
-       outb(fn, spic_dev.cur_ioport->io.minimum);
-       wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG);
-       outb(v, spic_dev.cur_ioport->io.minimum);
-       v1 = inb_p(spic_dev.cur_ioport->io.minimum);
+       wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG);
+       outb(dev, spic_dev.cur_ioport->io1.minimum + 4);
+       wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG);
+       outb(fn, spic_dev.cur_ioport->io1.minimum);
+       wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG);
+       outb(v, spic_dev.cur_ioport->io1.minimum);
+       v1 = inb_p(spic_dev.cur_ioport->io1.minimum);
        dprintk("sony_pic_call3: 0x%.4x\n", v1);
        return v1;
 }
@@ -2074,7 +2075,18 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)
 
        switch (resource->type) {
        case ACPI_RESOURCE_TYPE_START_DEPENDENT:
+               {
+                       /* start IO enumeration */
+                       struct sony_pic_ioport *ioport = kzalloc(sizeof(*ioport), GFP_KERNEL);
+                       if (!ioport)
+                               return AE_ERROR;
+
+                       list_add(&ioport->list, &dev->ioports);
+                       return AE_OK;
+               }
+
        case ACPI_RESOURCE_TYPE_END_DEPENDENT:
+               /* end IO enumeration */
                return AE_OK;
 
        case ACPI_RESOURCE_TYPE_IRQ:
@@ -2101,7 +2113,7 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)
                                if (!interrupt)
                                        return AE_ERROR;
 
-                               list_add_tail(&interrupt->list, &dev->interrupts);
+                               list_add(&interrupt->list, &dev->interrupts);
                                interrupt->irq.triggering = p->triggering;
                                interrupt->irq.polarity = p->polarity;
                                interrupt->irq.sharable = p->sharable;
@@ -2113,18 +2125,27 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)
        case ACPI_RESOURCE_TYPE_IO:
                {
                        struct acpi_resource_io *io = &resource->data.io;
-                       struct sony_pic_ioport *ioport = NULL;
+                       struct sony_pic_ioport *ioport =
+                               list_first_entry(&dev->ioports, struct sony_pic_ioport, list);
                        if (!io) {
                                dprintk("Blank IO resource\n");
                                return AE_OK;
                        }
 
-                       ioport = kzalloc(sizeof(*ioport), GFP_KERNEL);
-                       if (!ioport)
+                       if (!ioport->io1.minimum) {
+                               memcpy(&ioport->io1, io, sizeof(*io));
+                               dprintk("IO1 at 0x%.4x (0x%.2x)\n", ioport->io1.minimum,
+                                               ioport->io1.address_length);
+                       }
+                       else if (!ioport->io2.minimum) {
+                               memcpy(&ioport->io2, io, sizeof(*io));
+                               dprintk("IO2 at 0x%.4x (0x%.2x)\n", ioport->io2.minimum,
+                                               ioport->io2.address_length);
+                       }
+                       else {
+                               printk(KERN_ERR DRV_PFX "Unknown SPIC Type, more than 2 IO Ports\n");
                                return AE_ERROR;
-
-                       list_add_tail(&ioport->list, &dev->ioports);
-                       memcpy(&ioport->io, io, sizeof(*io));
+                       }
                        return AE_OK;
                }
        default:
@@ -2199,10 +2220,22 @@ static int sony_pic_enable(struct acpi_device *device,
 {
        acpi_status status;
        int result = 0;
+       /* Type 1 resource layout is:
+        *    IO
+        *    IO
+        *    IRQNoFlags
+        *    End
+        *
+        * Type 2 and 3 resource layout is:
+        *    IO
+        *    IRQNoFlags
+        *    End
+        */
        struct {
-               struct acpi_resource io_res;
-               struct acpi_resource irq_res;
-               struct acpi_resource end;
+               struct acpi_resource res1;
+               struct acpi_resource res2;
+               struct acpi_resource res3;
+               struct acpi_resource res4;
        } *resource;
        struct acpi_buffer buffer = { 0, NULL };
 
@@ -2217,21 +2250,49 @@ static int sony_pic_enable(struct acpi_device *device,
        buffer.length = sizeof(*resource) + 1;
        buffer.pointer = resource;
 
-       /* setup io resource */
-       resource->io_res.type = ACPI_RESOURCE_TYPE_IO;
-       resource->io_res.length = sizeof(struct acpi_resource);
-       memcpy(&resource->io_res.data.io, &ioport->io,
-                       sizeof(struct acpi_resource_io));
+       /* setup Type 1 resources */
+       if (spic_dev.model == SONYPI_DEVICE_TYPE1) {
 
-       /* setup irq resource */
-       resource->irq_res.type = ACPI_RESOURCE_TYPE_IRQ;
-       resource->irq_res.length = sizeof(struct acpi_resource);
-       memcpy(&resource->irq_res.data.irq, &irq->irq,
-                       sizeof(struct acpi_resource_irq));
-       /* we requested a shared irq */
-       resource->irq_res.data.irq.sharable = ACPI_SHARED;
+               /* setup io resources */
+               resource->res1.type = ACPI_RESOURCE_TYPE_IO;
+               resource->res1.length = sizeof(struct acpi_resource);
+               memcpy(&resource->res1.data.io, &ioport->io1,
+                               sizeof(struct acpi_resource_io));
 
-       resource->end.type = ACPI_RESOURCE_TYPE_END_TAG;
+               resource->res2.type = ACPI_RESOURCE_TYPE_IO;
+               resource->res2.length = sizeof(struct acpi_resource);
+               memcpy(&resource->res2.data.io, &ioport->io2,
+                               sizeof(struct acpi_resource_io));
+
+               /* setup irq resource */
+               resource->res3.type = ACPI_RESOURCE_TYPE_IRQ;
+               resource->res3.length = sizeof(struct acpi_resource);
+               memcpy(&resource->res3.data.irq, &irq->irq,
+                               sizeof(struct acpi_resource_irq));
+               /* we requested a shared irq */
+               resource->res3.data.irq.sharable = ACPI_SHARED;
+
+               resource->res4.type = ACPI_RESOURCE_TYPE_END_TAG;
+
+       }
+       /* setup Type 2/3 resources */
+       else {
+               /* setup io resource */
+               resource->res1.type = ACPI_RESOURCE_TYPE_IO;
+               resource->res1.length = sizeof(struct acpi_resource);
+               memcpy(&resource->res1.data.io, &ioport->io1,
+                               sizeof(struct acpi_resource_io));
+
+               /* setup irq resource */
+               resource->res2.type = ACPI_RESOURCE_TYPE_IRQ;
+               resource->res2.length = sizeof(struct acpi_resource);
+               memcpy(&resource->res2.data.irq, &irq->irq,
+                               sizeof(struct acpi_resource_irq));
+               /* we requested a shared irq */
+               resource->res2.data.irq.sharable = ACPI_SHARED;
+
+               resource->res3.type = ACPI_RESOURCE_TYPE_END_TAG;
+       }
 
        /* Attempt to set the resource */
        dprintk("Evaluating _SRS\n");
@@ -2239,7 +2300,7 @@ static int sony_pic_enable(struct acpi_device *device,
 
        /* check for total failure */
        if (ACPI_FAILURE(status)) {
-               printk(KERN_ERR DRV_PFX "Error evaluating _SRS");
+               printk(KERN_ERR DRV_PFX "Error evaluating _SRS\n");
                result = -ENODEV;
                goto end;
        }
@@ -2268,11 +2329,14 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id)
 
        struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id;
 
-       ev = inb_p(dev->cur_ioport->io.minimum);
-       data_mask = inb_p(dev->cur_ioport->io.minimum + dev->evport_offset);
+       ev = inb_p(dev->cur_ioport->io1.minimum);
+       if (dev->cur_ioport->io2.minimum)
+               data_mask = inb_p(dev->cur_ioport->io2.minimum);
+       else
+               data_mask = inb_p(dev->cur_ioport->io1.minimum + dev->evport_offset);
 
        dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
-                       ev, data_mask, dev->cur_ioport->io.minimum, dev->evport_offset);
+                       ev, data_mask, dev->cur_ioport->io1.minimum, dev->evport_offset);
 
        if (ev == 0x00 || ev == 0xff)
                return IRQ_HANDLED;
@@ -2323,8 +2387,11 @@ static int sony_pic_remove(struct acpi_device *device, int type)
        }
 
        free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev);
-       release_region(spic_dev.cur_ioport->io.minimum,
-                       spic_dev.cur_ioport->io.address_length);
+       release_region(spic_dev.cur_ioport->io1.minimum,
+                       spic_dev.cur_ioport->io1.address_length);
+       if (spic_dev.cur_ioport->io2.minimum)
+               release_region(spic_dev.cur_ioport->io2.minimum,
+                               spic_dev.cur_ioport->io2.address_length);
 
        sonypi_compat_exit();
 
@@ -2397,14 +2464,36 @@ static int sony_pic_add(struct acpi_device *device)
                goto err_remove_input;
 
        /* request io port */
-       list_for_each_entry(io, &spic_dev.ioports, list) {
-               if (request_region(io->io.minimum, io->io.address_length,
+       list_for_each_entry_reverse(io, &spic_dev.ioports, list) {
+               if (request_region(io->io1.minimum, io->io1.address_length,
                                        "Sony Programable I/O Device")) {
-                       dprintk("I/O port: 0x%.4x (0x%.4x) + 0x%.2x\n",
-                                       io->io.minimum, io->io.maximum,
-                                       io->io.address_length);
-                       spic_dev.cur_ioport = io;
-                       break;
+                       dprintk("I/O port1: 0x%.4x (0x%.4x) + 0x%.2x\n",
+                                       io->io1.minimum, io->io1.maximum,
+                                       io->io1.address_length);
+                       /* Type 1 have 2 ioports */
+                       if (io->io2.minimum) {
+                               if (request_region(io->io2.minimum,
+                                               io->io2.address_length,
+                                               "Sony Programable I/O Device")) {
+                                       dprintk("I/O port2: 0x%.4x (0x%.4x) + 0x%.2x\n",
+                                                       io->io2.minimum, io->io2.maximum,
+                                                       io->io2.address_length);
+                                       spic_dev.cur_ioport = io;
+                                       break;
+                               }
+                               else {
+                                       dprintk("Unable to get I/O port2: "
+                                                       "0x%.4x (0x%.4x) + 0x%.2x\n",
+                                                       io->io2.minimum, io->io2.maximum,
+                                                       io->io2.address_length);
+                                       release_region(io->io1.minimum,
+                                                       io->io1.address_length);
+                               }
+                       }
+                       else {
+                               spic_dev.cur_ioport = io;
+                               break;
+                       }
                }
        }
        if (!spic_dev.cur_ioport) {
@@ -2414,7 +2503,7 @@ static int sony_pic_add(struct acpi_device *device)
        }
 
        /* request IRQ */
-       list_for_each_entry(irq, &spic_dev.interrupts, list) {
+       list_for_each_entry_reverse(irq, &spic_dev.interrupts, list) {
                if (!request_irq(irq->irq.interrupts[0], sony_pic_irq,
                                        IRQF_SHARED, "sony-laptop", &spic_dev)) {
                        dprintk("IRQ: %d - triggering: %d - "
@@ -2462,8 +2551,11 @@ err_free_irq:
        free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev);
 
 err_release_region:
-       release_region(spic_dev.cur_ioport->io.minimum,
-                       spic_dev.cur_ioport->io.address_length);
+       release_region(spic_dev.cur_ioport->io1.minimum,
+                       spic_dev.cur_ioport->io1.address_length);
+       if (spic_dev.cur_ioport->io2.minimum)
+               release_region(spic_dev.cur_ioport->io2.minimum,
+                               spic_dev.cur_ioport->io2.address_length);
 
 err_remove_compat:
        sonypi_compat_exit();
index 0222bba..37891a8 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 #define IBM_VERSION "0.16"
-#define TPACPI_SYSFS_VERSION 0x010000
+#define TPACPI_SYSFS_VERSION 0x020000
 
 /*
  *  Changelog:
@@ -117,6 +117,12 @@ IBM_BIOS_MODULE_ALIAS("K[U,X-Z]");
 
 #define __unused __attribute__ ((unused))
 
+static enum {
+       TPACPI_LIFE_INIT = 0,
+       TPACPI_LIFE_RUNNING,
+       TPACPI_LIFE_EXITING,
+} tpacpi_lifecycle;
+
 /****************************************************************************
  ****************************************************************************
  *
@@ -342,6 +348,9 @@ static void dispatch_acpi_notify(acpi_handle handle, u32 event, void *data)
 {
        struct ibm_struct *ibm = data;
 
+       if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING)
+               return;
+
        if (!ibm || !ibm->acpi || !ibm->acpi->notify)
                return;
 
@@ -517,8 +526,10 @@ static char *next_cmd(char **cmds)
  ****************************************************************************/
 
 static struct platform_device *tpacpi_pdev;
+static struct platform_device *tpacpi_sensors_pdev;
 static struct class_device *tpacpi_hwmon;
 static struct input_dev *tpacpi_inputdev;
+static struct mutex tpacpi_inputdev_send_mutex;
 
 
 static int tpacpi_resume_handler(struct platform_device *pdev)
@@ -543,6 +554,12 @@ static struct platform_driver tpacpi_pdriver = {
        .resume = tpacpi_resume_handler,
 };
 
+static struct platform_driver tpacpi_hwmon_pdriver = {
+       .driver = {
+               .name = IBM_HWMON_DRVR_NAME,
+               .owner = THIS_MODULE,
+       },
+};
 
 /*************************************************************************
  * thinkpad-acpi driver attributes
@@ -692,6 +709,8 @@ static int parse_strtoul(const char *buf,
 {
        char *endp;
 
+       while (*buf && isspace(*buf))
+               buf++;
        *value = simple_strtoul(buf, &endp, 0);
        while (*endp && isspace(*endp))
                endp++;
@@ -989,6 +1008,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
 
        int res, i;
        int status;
+       int hkeyv;
 
        vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n");
 
@@ -1014,18 +1034,35 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
                        return res;
 
                /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
-                  A30, R30, R31, T20-22, X20-21, X22-24 */
-               tp_features.hotkey_mask =
-                       acpi_evalf(hkey_handle, NULL, "DHKN", "qv");
+                  A30, R30, R31, T20-22, X20-21, X22-24.  Detected by checking
+                  for HKEY interface version 0x100 */
+               if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) {
+                       if ((hkeyv >> 8) != 1) {
+                               printk(IBM_ERR "unknown version of the "
+                                      "HKEY interface: 0x%x\n", hkeyv);
+                               printk(IBM_ERR "please report this to %s\n",
+                                      IBM_MAIL);
+                       } else {
+                               /*
+                                * MHKV 0x100 in A31, R40, R40e,
+                                * T4x, X31, and later
+                                * */
+                               tp_features.hotkey_mask = 1;
+                       }
+               }
 
                vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n",
                        str_supported(tp_features.hotkey_mask));
 
                if (tp_features.hotkey_mask) {
-                       /* MHKA available in A31, R40, R40e, T4x, X31, and later */
                        if (!acpi_evalf(hkey_handle, &hotkey_all_mask,
-                                       "MHKA", "qd"))
+                                       "MHKA", "qd")) {
+                               printk(IBM_ERR
+                                      "missing MHKA handler, "
+                                      "please report this to %s\n",
+                                      IBM_MAIL);
                                hotkey_all_mask = 0x080cU; /* FN+F12, FN+F4, FN+F3 */
+                       }
                }
 
                res = hotkey_get(&hotkey_orig_status, &hotkey_orig_mask);
@@ -1131,6 +1168,8 @@ static void tpacpi_input_send_key(unsigned int scancode,
                                  unsigned int keycode)
 {
        if (keycode != KEY_RESERVED) {
+               mutex_lock(&tpacpi_inputdev_send_mutex);
+
                input_report_key(tpacpi_inputdev, keycode, 1);
                if (keycode == KEY_UNKNOWN)
                        input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN,
@@ -1142,6 +1181,8 @@ static void tpacpi_input_send_key(unsigned int scancode,
                        input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN,
                                    scancode);
                input_sync(tpacpi_inputdev);
+
+               mutex_unlock(&tpacpi_inputdev_send_mutex);
        }
 }
 
@@ -1149,18 +1190,47 @@ static void tpacpi_input_send_radiosw(void)
 {
        int wlsw;
 
-       if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw))
+       mutex_lock(&tpacpi_inputdev_send_mutex);
+
+       if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) {
                input_report_switch(tpacpi_inputdev,
                                    SW_RADIO, !!wlsw);
+               input_sync(tpacpi_inputdev);
+       }
+
+       mutex_unlock(&tpacpi_inputdev_send_mutex);
 }
 
 static void hotkey_notify(struct ibm_struct *ibm, u32 event)
 {
        u32 hkey;
        unsigned int keycode, scancode;
-       int send_acpi_ev = 0;
+       int send_acpi_ev;
+       int ignore_acpi_ev;
+
+       if (event != 0x80) {
+               printk(IBM_ERR "unknown HKEY notification event %d\n", event);
+               /* forward it to userspace, maybe it knows how to handle it */
+               acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
+                                               ibm->acpi->device->dev.bus_id,
+                                               event, 0);
+               return;
+       }
+
+       while (1) {
+               if (!acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
+                       printk(IBM_ERR "failed to retrieve HKEY event\n");
+                       return;
+               }
+
+               if (hkey == 0) {
+                       /* queue empty */
+                       return;
+               }
+
+               send_acpi_ev = 0;
+               ignore_acpi_ev = 0;
 
-       if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
                switch (hkey >> 12) {
                case 1:
                        /* 0x1000-0x1FFF: key presses */
@@ -1182,9 +1252,11 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
                         * eat up known LID events */
                        if (hkey != 0x5001 && hkey != 0x5002) {
                                printk(IBM_ERR
-                                       "unknown LID-related hotkey event: 0x%04x\n",
-                                       hkey);
+                                      "unknown LID-related HKEY event: 0x%04x\n",
+                                      hkey);
                                send_acpi_ev = 1;
+                       } else {
+                               ignore_acpi_ev = 1;
                        }
                        break;
                case 7:
@@ -1202,21 +1274,18 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
                        printk(IBM_NOTICE "unhandled HKEY event 0x%04x\n", hkey);
                        send_acpi_ev = 1;
                }
-       } else {
-               printk(IBM_ERR "unknown hotkey notification event %d\n", event);
-               hkey = 0;
-               send_acpi_ev = 1;
-       }
 
-       /* Legacy events */
-       if (send_acpi_ev || hotkey_report_mode < 2)
-               acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey);
+               /* Legacy events */
+               if (!ignore_acpi_ev && (send_acpi_ev || hotkey_report_mode < 2)) {
+                       acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey);
+               }
 
-       /* netlink events */
-       if (send_acpi_ev) {
-               acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
-                                               ibm->acpi->device->dev.bus_id,
-                                               event, hkey);
+               /* netlink events */
+               if (!ignore_acpi_ev && send_acpi_ev) {
+                       acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
+                                                       ibm->acpi->device->dev.bus_id,
+                                                       event, hkey);
+               }
        }
 }
 
@@ -2812,7 +2881,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
 
        switch(thermal_read_mode) {
        case TPACPI_THERMAL_TPEC_16:
-               res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
+               res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
                                &thermal_temp_input16_group);
                if (res)
                        return res;
@@ -2820,7 +2889,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
        case TPACPI_THERMAL_TPEC_8:
        case TPACPI_THERMAL_ACPI_TMP07:
        case TPACPI_THERMAL_ACPI_UPDT:
-               res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
+               res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
                                &thermal_temp_input8_group);
                if (res)
                        return res;
@@ -2837,13 +2906,13 @@ static void thermal_exit(void)
 {
        switch(thermal_read_mode) {
        case TPACPI_THERMAL_TPEC_16:
-               sysfs_remove_group(&tpacpi_pdev->dev.kobj,
+               sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
                                   &thermal_temp_input16_group);
                break;
        case TPACPI_THERMAL_TPEC_8:
        case TPACPI_THERMAL_ACPI_TMP07:
        case TPACPI_THERMAL_ACPI_UPDT:
-               sysfs_remove_group(&tpacpi_pdev->dev.kobj,
+               sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
                                   &thermal_temp_input16_group);
                break;
        case TPACPI_THERMAL_NONE:
@@ -3626,7 +3695,7 @@ static struct device_attribute dev_attr_fan_fan1_input =
        __ATTR(fan1_input, S_IRUGO,
                fan_fan1_input_show, NULL);
 
-/* sysfs fan fan_watchdog (driver) ------------------------------------- */
+/* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */
 static ssize_t fan_fan_watchdog_show(struct device_driver *drv,
                                     char *buf)
 {
@@ -3768,10 +3837,10 @@ static int __init fan_init(struct ibm_init_struct *iibm)
 
        if (fan_status_access_mode != TPACPI_FAN_NONE ||
            fan_control_access_mode != TPACPI_FAN_WR_NONE) {
-               rc = sysfs_create_group(&tpacpi_pdev->dev.kobj,
+               rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
                                         &fan_attr_group);
                if (!(rc < 0))
-                       rc = driver_create_file(&tpacpi_pdriver.driver,
+                       rc = driver_create_file(&tpacpi_hwmon_pdriver.driver,
                                        &driver_attr_fan_watchdog);
                if (rc < 0)
                        return rc;
@@ -3854,8 +3923,8 @@ static void fan_exit(void)
        vdbg_printk(TPACPI_DBG_EXIT, "cancelling any pending fan watchdog tasks\n");
 
        /* FIXME: can we really do this unconditionally? */
-       sysfs_remove_group(&tpacpi_pdev->dev.kobj, &fan_attr_group);
-       driver_remove_file(&tpacpi_pdriver.driver, &driver_attr_fan_watchdog);
+       sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, &fan_attr_group);
+       driver_remove_file(&tpacpi_hwmon_pdriver.driver, &driver_attr_fan_watchdog);
 
        cancel_delayed_work(&fan_watchdog_task);
        flush_scheduled_work();
@@ -3888,6 +3957,9 @@ static void fan_watchdog_fire(struct work_struct *ignored)
 {
        int rc;
 
+       if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING)
+               return;
+
        printk(IBM_NOTICE "fan watchdog: enabling fan\n");
        rc = fan_set_enable();
        if (rc < 0) {
@@ -3908,7 +3980,8 @@ static void fan_watchdog_reset(void)
        if (fan_watchdog_active)
                cancel_delayed_work(&fan_watchdog_task);
 
-       if (fan_watchdog_maxinterval > 0) {
+       if (fan_watchdog_maxinterval > 0 &&
+           tpacpi_lifecycle != TPACPI_LIFE_EXITING) {
                fan_watchdog_active = 1;
                if (!schedule_delayed_work(&fan_watchdog_task,
                                msecs_to_jiffies(fan_watchdog_maxinterval
@@ -4302,6 +4375,19 @@ static struct ibm_struct fan_driver_data = {
  ****************************************************************************
  ****************************************************************************/
 
+/* sysfs name ---------------------------------------------------------- */
+static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev,
+                          struct device_attribute *attr,
+                          char *buf)
+{
+       return snprintf(buf, PAGE_SIZE, "%s\n", IBM_NAME);
+}
+
+static struct device_attribute dev_attr_thinkpad_acpi_pdev_name =
+       __ATTR(name, S_IRUGO, thinkpad_acpi_pdev_name_show, NULL);
+
+/* --------------------------------------------------------------------- */
+
 /* /proc support */
 static struct proc_dir_entry *proc_dir;
 
@@ -4674,6 +4760,8 @@ static int __init thinkpad_acpi_module_init(void)
 {
        int ret, i;
 
+       tpacpi_lifecycle = TPACPI_LIFE_INIT;
+
        /* Parameter checking */
        if (hotkey_report_mode > 2)
                return -EINVAL;
@@ -4702,19 +4790,31 @@ static int __init thinkpad_acpi_module_init(void)
 
        ret = platform_driver_register(&tpacpi_pdriver);
        if (ret) {
-               printk(IBM_ERR "unable to register platform driver\n");
+               printk(IBM_ERR "unable to register main platform driver\n");
                thinkpad_acpi_module_exit();
                return ret;
        }
        tp_features.platform_drv_registered = 1;
 
+       ret = platform_driver_register(&tpacpi_hwmon_pdriver);
+       if (ret) {
+               printk(IBM_ERR "unable to register hwmon platform driver\n");
+               thinkpad_acpi_module_exit();
+               return ret;
+       }
+       tp_features.sensors_pdrv_registered = 1;
+
        ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver);
+       if (!ret) {
+               tp_features.platform_drv_attrs_registered = 1;
+               ret = tpacpi_create_driver_attributes(&tpacpi_hwmon_pdriver.driver);
+       }
        if (ret) {
                printk(IBM_ERR "unable to create sysfs driver attributes\n");
                thinkpad_acpi_module_exit();
                return ret;
        }
-       tp_features.platform_drv_attrs_registered = 1;
+       tp_features.sensors_pdrv_attrs_registered = 1;
 
 
        /* Device initialization */
@@ -4727,7 +4827,26 @@ static int __init thinkpad_acpi_module_init(void)
                thinkpad_acpi_module_exit();
                return ret;
        }
-       tpacpi_hwmon = hwmon_device_register(&tpacpi_pdev->dev);
+       tpacpi_sensors_pdev = platform_device_register_simple(
+                                                       IBM_HWMON_DRVR_NAME,
+                                                       -1, NULL, 0);
+       if (IS_ERR(tpacpi_sensors_pdev)) {
+               ret = PTR_ERR(tpacpi_sensors_pdev);
+               tpacpi_sensors_pdev = NULL;
+               printk(IBM_ERR "unable to register hwmon platform device\n");
+               thinkpad_acpi_module_exit();
+               return ret;
+       }
+       ret = device_create_file(&tpacpi_sensors_pdev->dev,
+                                &dev_attr_thinkpad_acpi_pdev_name);
+       if (ret) {
+               printk(IBM_ERR
+                       "unable to create sysfs hwmon device attributes\n");
+               thinkpad_acpi_module_exit();
+               return ret;
+       }
+       tp_features.sensors_pdev_attrs_registered = 1;
+       tpacpi_hwmon = hwmon_device_register(&tpacpi_sensors_pdev->dev);
        if (IS_ERR(tpacpi_hwmon)) {
                ret = PTR_ERR(tpacpi_hwmon);
                tpacpi_hwmon = NULL;
@@ -4735,6 +4854,7 @@ static int __init thinkpad_acpi_module_init(void)
                thinkpad_acpi_module_exit();
                return ret;
        }
+       mutex_init(&tpacpi_inputdev_send_mutex);
        tpacpi_inputdev = input_allocate_device();
        if (!tpacpi_inputdev) {
                printk(IBM_ERR "unable to allocate input device\n");
@@ -4769,6 +4889,7 @@ static int __init thinkpad_acpi_module_init(void)
                tp_features.input_device_registered = 1;
        }
 
+       tpacpi_lifecycle = TPACPI_LIFE_RUNNING;
        return 0;
 }
 
@@ -4776,6 +4897,8 @@ static void thinkpad_acpi_module_exit(void)
 {
        struct ibm_struct *ibm, *itmp;
 
+       tpacpi_lifecycle = TPACPI_LIFE_EXITING;
+
        list_for_each_entry_safe_reverse(ibm, itmp,
                                         &tpacpi_all_drivers,
                                         all_drivers) {
@@ -4794,12 +4917,22 @@ static void thinkpad_acpi_module_exit(void)
        if (tpacpi_hwmon)
                hwmon_device_unregister(tpacpi_hwmon);
 
+       if (tp_features.sensors_pdev_attrs_registered)
+               device_remove_file(&tpacpi_sensors_pdev->dev,
+                                  &dev_attr_thinkpad_acpi_pdev_name);
+       if (tpacpi_sensors_pdev)
+               platform_device_unregister(tpacpi_sensors_pdev);
        if (tpacpi_pdev)
                platform_device_unregister(tpacpi_pdev);
 
+       if (tp_features.sensors_pdrv_attrs_registered)
+               tpacpi_remove_driver_attributes(&tpacpi_hwmon_pdriver.driver);
        if (tp_features.platform_drv_attrs_registered)
                tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver);
 
+       if (tp_features.sensors_pdrv_registered)
+               platform_driver_unregister(&tpacpi_hwmon_pdriver);
+
        if (tp_features.platform_drv_registered)
                platform_driver_unregister(&tpacpi_pdriver);
 
index 082a1cb..c5fdd68 100644 (file)
 
 #define IBM_NAME "thinkpad"
 #define IBM_DESC "ThinkPad ACPI Extras"
-#define IBM_FILE "thinkpad_acpi"
+#define IBM_FILE IBM_NAME "_acpi"
 #define IBM_URL "http://ibm-acpi.sf.net/"
 #define IBM_MAIL "ibm-acpi-devel@lists.sourceforge.net"
 
 #define IBM_PROC_DIR "ibm"
 #define IBM_ACPI_EVENT_PREFIX "ibm"
 #define IBM_DRVR_NAME IBM_FILE
+#define IBM_HWMON_DRVR_NAME IBM_NAME "_hwmon"
 
 #define IBM_LOG IBM_FILE ": "
 #define IBM_ERR           KERN_ERR    IBM_LOG
@@ -171,6 +172,7 @@ static int parse_strtoul(const char *buf, unsigned long max,
 
 /* Device model */
 static struct platform_device *tpacpi_pdev;
+static struct platform_device *tpacpi_sensors_pdev;
 static struct class_device *tpacpi_hwmon;
 static struct platform_driver tpacpi_pdriver;
 static struct input_dev *tpacpi_inputdev;
@@ -233,22 +235,25 @@ struct ibm_init_struct {
 
 static struct {
 #ifdef CONFIG_THINKPAD_ACPI_BAY
-       u16 bay_status:1;
-       u16 bay_eject:1;
-       u16 bay_status2:1;
-       u16 bay_eject2:1;
+       u32 bay_status:1;
+       u32 bay_eject:1;
+       u32 bay_status2:1;
+       u32 bay_eject2:1;
 #endif
-       u16 bluetooth:1;
-       u16 hotkey:1;
-       u16 hotkey_mask:1;
-       u16 hotkey_wlsw:1;
-       u16 light:1;
-       u16 light_status:1;
-       u16 wan:1;
-       u16 fan_ctrl_status_undef:1;
-       u16 input_device_registered:1;
-       u16 platform_drv_registered:1;
-       u16 platform_drv_attrs_registered:1;
+       u32 bluetooth:1;
+       u32 hotkey:1;
+       u32 hotkey_mask:1;
+       u32 hotkey_wlsw:1;
+       u32 light:1;
+       u32 light_status:1;
+       u32 wan:1;
+       u32 fan_ctrl_status_undef:1;
+       u32 input_device_registered:1;
+       u32 platform_drv_registered:1;
+       u32 platform_drv_attrs_registered:1;
+       u32 sensors_pdrv_registered:1;
+       u32 sensors_pdrv_attrs_registered:1;
+       u32 sensors_pdev_attrs_registered:1;
 } tp_features;
 
 struct thinkpad_id_data {
index 4c3785c..9ecc3ad 100644 (file)
@@ -1726,6 +1726,7 @@ static int e1000_wol_exclusion(struct e1000_adapter *adapter, struct ethtool_wol
        case E1000_DEV_ID_82571EB_QUAD_COPPER:
        case E1000_DEV_ID_82571EB_QUAD_FIBER:
        case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE:
+       case E1000_DEV_ID_82571PT_QUAD_COPPER:
        case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
                /* quad port adapters only support WoL on port A */
                if (!adapter->quad_port_a) {
index ba120f7..8604adb 100644 (file)
@@ -387,6 +387,7 @@ e1000_set_mac_type(struct e1000_hw *hw)
        case E1000_DEV_ID_82571EB_SERDES_DUAL:
        case E1000_DEV_ID_82571EB_SERDES_QUAD:
        case E1000_DEV_ID_82571EB_QUAD_COPPER:
+       case E1000_DEV_ID_82571PT_QUAD_COPPER:
        case E1000_DEV_ID_82571EB_QUAD_FIBER:
        case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE:
                hw->mac_type = e1000_82571;
index fe87146..07f0ea7 100644 (file)
@@ -475,6 +475,7 @@ int32_t e1000_check_phy_reset_block(struct e1000_hw *hw);
 #define E1000_DEV_ID_82571EB_FIBER       0x105F
 #define E1000_DEV_ID_82571EB_SERDES      0x1060
 #define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4
+#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5
 #define E1000_DEV_ID_82571EB_QUAD_FIBER  0x10A5
 #define E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE  0x10BC
 #define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9
index 4a22595..e7c8951 100644 (file)
@@ -108,6 +108,7 @@ static struct pci_device_id e1000_pci_tbl[] = {
        INTEL_E1000_ETHERNET_DEVICE(0x10BC),
        INTEL_E1000_ETHERNET_DEVICE(0x10C4),
        INTEL_E1000_ETHERNET_DEVICE(0x10C5),
+       INTEL_E1000_ETHERNET_DEVICE(0x10D5),
        INTEL_E1000_ETHERNET_DEVICE(0x10D9),
        INTEL_E1000_ETHERNET_DEVICE(0x10DA),
        /* required last entry */
@@ -1101,6 +1102,7 @@ e1000_probe(struct pci_dev *pdev,
        case E1000_DEV_ID_82571EB_QUAD_COPPER:
        case E1000_DEV_ID_82571EB_QUAD_FIBER:
        case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE:
+       case E1000_DEV_ID_82571PT_QUAD_COPPER:
                /* if quad port adapter, disable WoL on all but port A */
                if (global_quad_port_a != 0)
                        adapter->eeprom_wol = 0;
index 456d1e1..3153356 100644 (file)
@@ -534,7 +534,7 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id)
        }
 
        /* PHY status changed */
-       if (eth_int_cause_ext & ETH_INT_CAUSE_PHY) {
+       if (eth_int_cause_ext & (ETH_INT_CAUSE_PHY | ETH_INT_CAUSE_STATE)) {
                struct ethtool_cmd cmd;
 
                if (mii_link_ok(&mp->mii)) {
@@ -1357,7 +1357,6 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
 #endif
 
        dev->watchdog_timeo = 2 * HZ;
-       dev->tx_queue_len = mp->tx_ring_size;
        dev->base_addr = 0;
        dev->change_mtu = mv643xx_eth_change_mtu;
        dev->do_ioctl = mv643xx_eth_do_ioctl;
index 82f8c0c..565b966 100644 (file)
@@ -64,7 +64,9 @@
 #define ETH_INT_CAUSE_TX_ERROR (ETH_TX_QUEUES_ENABLED << 8)
 #define ETH_INT_CAUSE_TX       (ETH_INT_CAUSE_TX_DONE | ETH_INT_CAUSE_TX_ERROR)
 #define ETH_INT_CAUSE_PHY      0x00010000
-#define ETH_INT_UNMASK_ALL_EXT (ETH_INT_CAUSE_TX | ETH_INT_CAUSE_PHY)
+#define ETH_INT_CAUSE_STATE    0x00100000
+#define ETH_INT_UNMASK_ALL_EXT (ETH_INT_CAUSE_TX | ETH_INT_CAUSE_PHY | \
+                                       ETH_INT_CAUSE_STATE)
 
 #define ETH_INT_MASK_ALL       0x00000000
 #define ETH_INT_MASK_ALL_EXT   0x00000000
index 69da95b..ea15131 100755 (executable)
@@ -2248,6 +2248,13 @@ static int ql_tx_rx_clean(struct ql3_adapter *qdev,
                qdev->rsp_consumer_index) && (work_done < work_to_do)) {
 
                net_rsp = qdev->rsp_current;
+               rmb();
+               /*
+                * Fix 4032 chipe undocumented "feature" where bit-8 is set if the
+                * inbound completion is for a VLAN.
+                */
+               if (qdev->device_id == QL3032_DEVICE_ID)
+                       net_rsp->opcode &= 0x7f;
                switch (net_rsp->opcode) {
 
                case OPCODE_OB_MAC_IOCB_FN0:
index c921ec3..c76dd29 100644 (file)
@@ -1918,7 +1918,11 @@ static void rtl_hw_start_8169(struct net_device *dev)
 
        rtl_set_rx_max_size(ioaddr);
 
-       rtl_set_rx_tx_config_registers(tp);
+       if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
+           (tp->mac_version == RTL_GIGA_MAC_VER_02) ||
+           (tp->mac_version == RTL_GIGA_MAC_VER_03) ||
+           (tp->mac_version == RTL_GIGA_MAC_VER_04))
+               rtl_set_rx_tx_config_registers(tp);
 
        tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
 
@@ -1941,6 +1945,14 @@ static void rtl_hw_start_8169(struct net_device *dev)
 
        rtl_set_rx_tx_desc_registers(tp, ioaddr);
 
+       if ((tp->mac_version != RTL_GIGA_MAC_VER_01) &&
+           (tp->mac_version != RTL_GIGA_MAC_VER_02) &&
+           (tp->mac_version != RTL_GIGA_MAC_VER_03) &&
+           (tp->mac_version != RTL_GIGA_MAC_VER_04)) {
+               RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+               rtl_set_rx_tx_config_registers(tp);
+       }
+
        RTL_W8(Cfg9346, Cfg9346_Lock);
 
        /* Initially a 10 us delay. Turned it into a PCI commit. - FR */
@@ -1955,8 +1967,6 @@ static void rtl_hw_start_8169(struct net_device *dev)
 
        /* Enable all known interrupts by setting the interrupt mask. */
        RTL_W16(IntrMask, tp->intr_event);
-
-       RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
 }
 
 static void rtl_hw_start_8168(struct net_device *dev)
index 0792031..ea117fc 100644 (file)
@@ -910,6 +910,20 @@ static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2)
        return le;
 }
 
+static void tx_init(struct sky2_port *sky2)
+{
+       struct sky2_tx_le *le;
+
+       sky2->tx_prod = sky2->tx_cons = 0;
+       sky2->tx_tcpsum = 0;
+       sky2->tx_last_mss = 0;
+
+       le = get_tx_le(sky2);
+       le->addr = 0;
+       le->opcode = OP_ADDR64 | HW_OWNER;
+       sky2->tx_addr64 = 0;
+}
+
 static inline struct tx_ring_info *tx_le_re(struct sky2_port *sky2,
                                            struct sky2_tx_le *le)
 {
@@ -1320,7 +1334,8 @@ static int sky2_up(struct net_device *dev)
                                GFP_KERNEL);
        if (!sky2->tx_ring)
                goto err_out;
-       sky2->tx_prod = sky2->tx_cons = 0;
+
+       tx_init(sky2);
 
        sky2->rx_le = pci_alloc_consistent(hw->pdev, RX_LE_BYTES,
                                           &sky2->rx_le_map);
@@ -2148,6 +2163,15 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
        sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending;
        prefetch(sky2->rx_ring + sky2->rx_next);
 
+       /* This chip has hardware problems that generates bogus status.
+        * So do only marginal checking and expect higher level protocols
+        * to handle crap frames.
+        */
+       if (sky2->hw->chip_id == CHIP_ID_YUKON_FE_P &&
+           sky2->hw->chip_rev == CHIP_REV_YU_FE2_A0 &&
+           length != count)
+               goto okay;
+
        if (status & GMR_FS_ANY_ERR)
                goto error;
 
@@ -2156,8 +2180,9 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
 
        /* if length reported by DMA does not match PHY, packet was truncated */
        if (length != count)
-               goto len_mismatch;
+               goto len_error;
 
+okay:
        if (length < copybreak)
                skb = receive_copy(sky2, re, length);
        else
@@ -2167,13 +2192,13 @@ resubmit:
 
        return skb;
 
-len_mismatch:
+len_error:
        /* Truncation of overlength packets
           causes PHY length to not match MAC length */
        ++sky2->net_stats.rx_length_errors;
        if (netif_msg_rx_err(sky2) && net_ratelimit())
-               pr_info(PFX "%s: rx length mismatch: length %d status %#x\n",
-                       dev->name, length, status);
+               pr_info(PFX "%s: rx length error: status %#x length %d\n",
+                       dev->name, status, length);
        goto resubmit;
 
 error:
@@ -3934,13 +3959,6 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
        sky2->hw = hw;
        sky2->msg_enable = netif_msg_init(debug, default_msg);
 
-       /* This chip has hardware problems that generates
-        * bogus PHY receive status so by default shut up the message.
-        */
-       if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
-           hw->chip_rev == CHIP_REV_YU_FE2_A0)
-               sky2->msg_enable &= ~NETIF_MSG_RX_ERR;
-
        /* Auto speed and flow control */
        sky2->autoneg = AUTONEG_ENABLE;
        sky2->flow_mode = FC_BOTH;
@@ -3964,8 +3982,12 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
                dev->features |= NETIF_F_HIGHDMA;
 
 #ifdef SKY2_VLAN_TAG_USED
-       dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-       dev->vlan_rx_register = sky2_vlan_rx_register;
+       /* The workaround for FE+ status conflicts with VLAN tag detection. */
+       if (!(sky2->hw->chip_id == CHIP_ID_YUKON_FE_P &&
+             sky2->hw->chip_rev == CHIP_REV_YU_FE2_A0)) {
+               dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+               dev->vlan_rx_register = sky2_vlan_rx_register;
+       }
 #endif
 
        /* read the mac address */
index 16c7a0e..a2de32f 100644 (file)
@@ -405,7 +405,7 @@ static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)
        dev->net->ethtool_ops = &dm9601_ethtool_ops;
        dev->net->hard_header_len += DM_TX_OVERHEAD;
        dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
-       dev->rx_urb_size = dev->net->mtu + DM_RX_OVERHEAD;
+       dev->rx_urb_size = dev->net->mtu + ETH_HLEN + DM_RX_OVERHEAD;
 
        dev->mii.dev = dev->net;
        dev->mii.mdio_read = dm9601_mdio_read;
index ef35bc6..4eb6d97 100644 (file)
@@ -43,7 +43,7 @@ obj-$(CONFIG_PCMCIA_RAYCS)    += ray_cs.o
 obj-$(CONFIG_PCMCIA_WL3501)    += wl3501_cs.o
 
 obj-$(CONFIG_USB_ZD1201)       += zd1201.o
-obj-$(CONFIG_LIBERTAS_USB)     += libertas/
+obj-$(CONFIG_LIBERTAS)         += libertas/
 
 rtl8187-objs           := rtl8187_dev.o rtl8187_rtl8225.o
 obj-$(CONFIG_RTL8187)  += rtl8187.o
index d6d9413..6acfdc4 100644 (file)
@@ -444,7 +444,7 @@ static int bcm43xx_wx_set_xmitpower(struct net_device *net_dev,
        u16 maxpower;
 
        if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) {
-               printk(PFX KERN_ERR "TX power not in dBm.\n");
+               printk(KERN_ERR PFX "TX power not in dBm.\n");
                return -EOPNOTSUPP;
        }
 
index 7dcaa09..50f2dd9 100644 (file)
@@ -1444,7 +1444,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, quirk_netmos);
 static void __devinit quirk_e100_interrupt(struct pci_dev *dev)
 {
        u16 command;
-       u32 bar;
        u8 __iomem *csr;
        u8 cmd_hi;
 
@@ -1476,12 +1475,12 @@ static void __devinit quirk_e100_interrupt(struct pci_dev *dev)
         * re-enable them when it's ready.
         */
        pci_read_config_word(dev, PCI_COMMAND, &command);
-       pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar);
 
-       if (!(command & PCI_COMMAND_MEMORY) || !bar)
+       if (!(command & PCI_COMMAND_MEMORY) || !pci_resource_start(dev, 0))
                return;
 
-       csr = ioremap(bar, 8);
+       /* Convert from PCI bus to resource space.  */
+       csr = ioremap(pci_resource_start(dev, 0), 8);
        if (!csr) {
                printk(KERN_WARNING "PCI: Can't map %s e100 registers\n",
                        pci_name(dev));
index d5d8cab..ab13824 100644 (file)
@@ -451,7 +451,7 @@ static int asd_build_smp_ascb(struct asd_ascb *ascb, struct sas_task *task,
        struct scb *scb;
 
        pci_map_sg(asd_ha->pcidev, &task->smp_task.smp_req, 1,
-                  PCI_DMA_FROMDEVICE);
+                  PCI_DMA_TODEVICE);
        pci_map_sg(asd_ha->pcidev, &task->smp_task.smp_resp, 1,
                   PCI_DMA_FROMDEVICE);
 
@@ -486,7 +486,7 @@ static void asd_unbuild_smp_ascb(struct asd_ascb *a)
 
        BUG_ON(!task);
        pci_unmap_sg(a->ha->pcidev, &task->smp_task.smp_req, 1,
-                    PCI_DMA_FROMDEVICE);
+                    PCI_DMA_TODEVICE);
        pci_unmap_sg(a->ha->pcidev, &task->smp_task.smp_resp, 1,
                     PCI_DMA_FROMDEVICE);
 }
index 3907f67..da56163 100644 (file)
@@ -1753,6 +1753,14 @@ mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len)
 
        *len = 0;
 
+       if (scsi_sg_count(cmd) == 1 && !adapter->has_64bit_addr) {
+               sg = scsi_sglist(cmd);
+               scb->dma_h_bulkdata = sg_dma_address(sg);
+               *buf = (u32)scb->dma_h_bulkdata;
+               *len = sg_dma_len(sg);
+               return 0;
+       }
+
        scsi_for_each_sg(cmd, sg, sgcnt, idx) {
                if (adapter->has_64bit_addr) {
                        scb->sgl64[idx].address = sg_dma_address(sg);
index a99e45e..2a64778 100644 (file)
@@ -37,6 +37,6 @@ static inline void cpm_set_smc_fcr(volatile smc_uart_t * up)
        up->smc_tfcr = SMC_EB;
 }
 
-#define DPRAM_BASE     ((unsigned char *)&cpmp->cp_dpmem[0])
+#define DPRAM_BASE     ((unsigned char *)cpm_dpram_addr(0))
 
 #endif
index a0ea435..7c8d78f 100644 (file)
@@ -943,6 +943,7 @@ static struct pcmcia_device_id serial_ids[] = {
        PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
        PCMCIA_MFC_DEVICE_PROD_ID12(2,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
        PCMCIA_MFC_DEVICE_PROD_ID12(3,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
+       PCMCIA_DEVICE_MANF_CARD(0x0279, 0x950b),
        /* too generic */
        /* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */
        /* PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0160, 0x0002), */
index dbe699e..ea2e198 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1562,6 +1562,7 @@ int fastcall io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
                fput(file);
                return -EAGAIN;
        }
+       req->ki_filp = file;
        if (iocb->aio_flags & IOCB_FLAG_RESFD) {
                /*
                 * If the IOCB_FLAG_RESFD flag of aio_flags is set, get an
@@ -1576,7 +1577,6 @@ int fastcall io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
                }
        }
 
-       req->ki_filp = file;
        ret = put_user(req->ki_key, &user_iocb->aio_key);
        if (unlikely(ret)) {
                dprintk("EFAULT: aio_key\n");
index 861141b..fcb3405 100644 (file)
@@ -742,6 +742,7 @@ static int load_flat_file(struct linux_binprm * bprm,
         * __start to address 4 so that is okay).
         */
        if (rev > OLD_FLAT_VERSION) {
+               unsigned long persistent = 0;
                for (i=0; i < relocs; i++) {
                        unsigned long addr, relval;
 
@@ -749,6 +750,8 @@ static int load_flat_file(struct linux_binprm * bprm,
                           relocated (of course, the address has to be
                           relocated first).  */
                        relval = ntohl(reloc[i]);
+                       if (flat_set_persistent (relval, &persistent))
+                               continue;
                        addr = flat_get_relocate_addr(relval);
                        rp = (unsigned long *) calc_reloc(addr, libinfo, id, 1);
                        if (rp == (unsigned long *)RELOC_FAILED) {
@@ -757,7 +760,8 @@ static int load_flat_file(struct linux_binprm * bprm,
                        }
 
                        /* Get the pointer's value.  */
-                       addr = flat_get_addr_from_rp(rp, relval, flags);
+                       addr = flat_get_addr_from_rp(rp, relval, flags,
+                                                       &persistent);
                        if (addr != 0) {
                                /*
                                 * Do the relocation.  PIC relocs in the data section are
index d098c7a..d120ec3 100644 (file)
@@ -485,8 +485,10 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
                        return nlm_granted;
                /* Create host handle for callback */
                host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len);
-               if (host == NULL)
+               if (host == NULL) {
+                       kfree(conf);
                        return nlm_lck_denied_nolocks;
+               }
                block = nlmsvc_create_block(rqstp, host, file, lock, cookie);
                if (block == NULL) {
                        kfree(conf);
index a49f9fe..a204484 100644 (file)
@@ -588,16 +588,6 @@ static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_dat
        server->namelen  = data->namlen;
        /* Create a client RPC handle for the NFSv3 ACL management interface */
        nfs_init_server_aclclient(server);
-       if (clp->cl_nfsversion == 3) {
-               if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
-                       server->namelen = NFS3_MAXNAMLEN;
-               if (!(data->flags & NFS_MOUNT_NORDIRPLUS))
-                       server->caps |= NFS_CAP_READDIRPLUS;
-       } else {
-               if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
-                       server->namelen = NFS2_MAXNAMLEN;
-       }
-
        dprintk("<-- nfs_init_server() = 0 [new %p]\n", clp);
        return 0;
 
@@ -794,6 +784,16 @@ struct nfs_server *nfs_create_server(const struct nfs_mount_data *data,
        error = nfs_probe_fsinfo(server, mntfh, &fattr);
        if (error < 0)
                goto error;
+       if (server->nfs_client->rpc_ops->version == 3) {
+               if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
+                       server->namelen = NFS3_MAXNAMLEN;
+               if (!(data->flags & NFS_MOUNT_NORDIRPLUS))
+                       server->caps |= NFS_CAP_READDIRPLUS;
+       } else {
+               if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
+                       server->namelen = NFS2_MAXNAMLEN;
+       }
+
        if (!(fattr.valid & NFS_ATTR_FATTR)) {
                error = server->nfs_client->rpc_ops->getattr(server, mntfh, &fattr);
                if (error < 0) {
@@ -984,6 +984,9 @@ struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data,
        if (error < 0)
                goto error;
 
+       if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
+               server->namelen = NFS4_MAXNAMLEN;
+
        BUG_ON(!server->nfs_client);
        BUG_ON(!server->nfs_client->rpc_ops);
        BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
@@ -1056,6 +1059,9 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
        if (error < 0)
                goto error;
 
+       if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
+               server->namelen = NFS4_MAXNAMLEN;
+
        dprintk("Referral FSID: %llx:%llx\n",
                (unsigned long long) server->fsid.major,
                (unsigned long long) server->fsid.minor);
@@ -1115,6 +1121,9 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
        if (error < 0)
                goto out_free_server;
 
+       if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
+               server->namelen = NFS4_MAXNAMLEN;
+
        dprintk("Cloned FSID: %llx:%llx\n",
                (unsigned long long) server->fsid.major,
                (unsigned long long) server->fsid.minor);
index ea97408..e4a04d1 100644 (file)
@@ -1162,6 +1162,8 @@ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc)
        }
        if (!desc->plus || !(entry->fattr->valid & NFS_ATTR_FATTR))
                return NULL;
+       if (name.len > NFS_SERVER(dir)->namelen)
+               return NULL;
        /* Note: caller is already holding the dir->i_mutex! */
        dentry = d_alloc(parent, &name);
        if (dentry == NULL)
index d1cbf0a..522e5ad 100644 (file)
@@ -175,6 +175,9 @@ next_component:
                path++;
        name.len = path - (const char *) name.name;
 
+       if (name.len > NFS4_MAXNAMLEN)
+               return -ENAMETOOLONG;
+
 eat_dot_dir:
        while (*path == '/')
                path++;
index de984d2..d272847 100644 (file)
@@ -514,8 +514,10 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
        ac->ac_bh = osb->local_alloc_bh;
        status = 0;
 bail:
-       if (status < 0 && local_alloc_inode)
+       if (status < 0 && local_alloc_inode) {
+               mutex_unlock(&local_alloc_inode->i_mutex);
                iput(local_alloc_inode);
+       }
 
        mlog_exit(status);
        return status;
index c010a72..e95a362 100644 (file)
@@ -1224,6 +1224,33 @@ static long do_splice(struct file *in, loff_t __user *off_in,
 }
 
 /*
+ * Do a copy-from-user while holding the mmap_semaphore for reading, in a
+ * manner safe from deadlocking with simultaneous mmap() (grabbing mmap_sem
+ * for writing) and page faulting on the user memory pointed to by src.
+ * This assumes that we will very rarely hit the partial != 0 path, or this
+ * will not be a win.
+ */
+static int copy_from_user_mmap_sem(void *dst, const void __user *src, size_t n)
+{
+       int partial;
+
+       pagefault_disable();
+       partial = __copy_from_user_inatomic(dst, src, n);
+       pagefault_enable();
+
+       /*
+        * Didn't copy everything, drop the mmap_sem and do a faulting copy
+        */
+       if (unlikely(partial)) {
+               up_read(&current->mm->mmap_sem);
+               partial = copy_from_user(dst, src, n);
+               down_read(&current->mm->mmap_sem);
+       }
+
+       return partial;
+}
+
+/*
  * Map an iov into an array of pages and offset/length tupples. With the
  * partial_page structure, we can map several non-contiguous ranges into
  * our ones pages[] map instead of splitting that operation into pieces.
@@ -1236,31 +1263,26 @@ static int get_iovec_page_array(const struct iovec __user *iov,
 {
        int buffers = 0, error = 0;
 
-       /*
-        * It's ok to take the mmap_sem for reading, even
-        * across a "get_user()".
-        */
        down_read(&current->mm->mmap_sem);
 
        while (nr_vecs) {
                unsigned long off, npages;
+               struct iovec entry;
                void __user *base;
                size_t len;
                int i;
 
-               /*
-                * Get user address base and length for this iovec.
-                */
-               error = get_user(base, &iov->iov_base);
-               if (unlikely(error))
-                       break;
-               error = get_user(len, &iov->iov_len);
-               if (unlikely(error))
+               error = -EFAULT;
+               if (copy_from_user_mmap_sem(&entry, iov, sizeof(entry)))
                        break;
 
+               base = entry.iov_base;
+               len = entry.iov_len;
+
                /*
                 * Sanity check this iovec. 0 read succeeds.
                 */
+               error = 0;
                if (unlikely(!len))
                        break;
                error = -EFAULT;
index fa25b7d..d7e1361 100644 (file)
@@ -52,11 +52,6 @@ typedef struct xfs_buf_log_format_t {
 #define        XFS_BLI_UDQUOT_BUF      0x4
 #define XFS_BLI_PDQUOT_BUF     0x8
 #define        XFS_BLI_GDQUOT_BUF      0x10
-/*
- * This flag indicates that the buffer contains newly allocated
- * inodes.
- */
-#define        XFS_BLI_INODE_NEW_BUF   0x20
 
 #define        XFS_BLI_CHUNK           128
 #define        XFS_BLI_SHIFT           7
index 7174991..8ae6e8e 100644 (file)
@@ -1874,7 +1874,6 @@ xlog_recover_do_inode_buffer(
 /*ARGSUSED*/
 STATIC void
 xlog_recover_do_reg_buffer(
-       xfs_mount_t             *mp,
        xlog_recover_item_t     *item,
        xfs_buf_t               *bp,
        xfs_buf_log_format_t    *buf_f)
@@ -1885,50 +1884,6 @@ xlog_recover_do_reg_buffer(
        unsigned int            *data_map = NULL;
        unsigned int            map_size = 0;
        int                     error;
-       int                     stale_buf = 1;
-
-       /*
-        * Scan through the on-disk inode buffer and attempt to
-        * determine if it has been written to since it was logged.
-        *
-        * - If any of the magic numbers are incorrect then the buffer is stale
-        * - If any of the modes are non-zero then the buffer is not stale
-        * - If all of the modes are zero and at least one of the generation
-        *   counts is non-zero then the buffer is stale
-        *
-        * If the end result is a stale buffer then the log buffer is replayed
-        * otherwise it is skipped.
-        *
-        * This heuristic is not perfect.  It can be improved by scanning the
-        * entire inode chunk for evidence that any of the inode clusters have
-        * been updated.  To fix this problem completely we will need a major
-        * architectural change to the logging system.
-        */
-       if (buf_f->blf_flags & XFS_BLI_INODE_NEW_BUF) {
-               xfs_dinode_t    *dip;
-               int             inodes_per_buf;
-               int             mode_count = 0;
-               int             gen_count = 0;
-
-               stale_buf = 0;
-               inodes_per_buf = XFS_BUF_COUNT(bp) >> mp->m_sb.sb_inodelog;
-               for (i = 0; i < inodes_per_buf; i++) {
-                       dip = (xfs_dinode_t *)xfs_buf_offset(bp,
-                               i * mp->m_sb.sb_inodesize);
-                       if (be16_to_cpu(dip->di_core.di_magic) !=
-                                       XFS_DINODE_MAGIC) {
-                               stale_buf = 1;
-                               break;
-                       }
-                       if (dip->di_core.di_mode)
-                               mode_count++;
-                       if (dip->di_core.di_gen)
-                               gen_count++;
-               }
-
-               if (!mode_count && gen_count)
-                       stale_buf = 1;
-       }
 
        switch (buf_f->blf_type) {
        case XFS_LI_BUF:
@@ -1962,7 +1917,7 @@ xlog_recover_do_reg_buffer(
                                               -1, 0, XFS_QMOPT_DOWARN,
                                               "dquot_buf_recover");
                }
-               if (!error && stale_buf)
+               if (!error)
                        memcpy(xfs_buf_offset(bp,
                                (uint)bit << XFS_BLI_SHIFT),    /* dest */
                                item->ri_buf[i].i_addr,         /* source */
@@ -2134,7 +2089,7 @@ xlog_recover_do_dquot_buffer(
        if (log->l_quotaoffs_flag & type)
                return;
 
-       xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
+       xlog_recover_do_reg_buffer(item, bp, buf_f);
 }
 
 /*
@@ -2235,7 +2190,7 @@ xlog_recover_do_buffer_trans(
                  (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
                xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
        } else {
-               xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
+               xlog_recover_do_reg_buffer(item, bp, buf_f);
        }
        if (error)
                return XFS_ERROR(error);
index 95fff68..60b6b89 100644 (file)
@@ -966,7 +966,6 @@ xfs_trans_inode_alloc_buf(
        ASSERT(atomic_read(&bip->bli_refcount) > 0);
 
        bip->bli_flags |= XFS_BLI_INODE_ALLOC_BUF;
-       bip->bli_format.blf_flags |= XFS_BLI_INODE_NEW_BUF;
 }
 
 
index e043caf..69b9f8e 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/serial.h>
 #include <asm/dma.h>
+#include <asm/portmux.h>
 
 #define NR_PORTS                1
 
@@ -92,18 +93,24 @@ struct bfin_serial_res bfin_serial_resource[] = {
        }
 };
 
+#define DRIVER_NAME "bfin-uart"
 
 int nr_ports = NR_PORTS;
 static void bfin_serial_hw_init(struct bfin_serial_port *uart)
 {
 
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       peripheral_request(P_UART0_TX, DRIVER_NAME);
+       peripheral_request(P_UART0_RX, DRIVER_NAME);
+#endif
+
 #ifdef CONFIG_SERIAL_BFIN_CTSRTS
        if (uart->cts_pin >= 0) {
-               gpio_request(uart->cts_pin, NULL);
+               gpio_request(uart->cts_pin, DRIVER_NAME);
                gpio_direction_input(uart->cts_pin);
        }
        if (uart->rts_pin >= 0) {
-               gpio_request(uart->rts_pin, NULL);
+               gpio_request(uart->rts_pin, DRIVER_NAME);
                gpio_direction_input(uart->rts_pin);
        }
 #endif
index 8f5d9c4..6fb328f 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/serial.h>
 #include <asm/dma.h>
+#include <asm/portmux.h>
 
 #define NR_PORTS               2
 
@@ -122,25 +123,29 @@ struct bfin_serial_res bfin_serial_resource[] = {
 
 int nr_ports = ARRAY_SIZE(bfin_serial_resource);
 
+#define DRIVER_NAME "bfin-uart"
+
 static void bfin_serial_hw_init(struct bfin_serial_port *uart)
 {
-       unsigned short val;
-       val = bfin_read16(BFIN_PORT_MUX);
-       val &= ~(PFDE | PFTE);
-       bfin_write16(BFIN_PORT_MUX, val);
 
-       val = bfin_read16(PORTF_FER);
-       val |= 0xF;
-       bfin_write16(PORTF_FER, val);
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       peripheral_request(P_UART0_TX, DRIVER_NAME);
+       peripheral_request(P_UART0_RX, DRIVER_NAME);
+#endif
+
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       peripheral_request(P_UART1_TX, DRIVER_NAME);
+       peripheral_request(P_UART1_RX, DRIVER_NAME);
+#endif
 
 #ifdef CONFIG_SERIAL_BFIN_CTSRTS
        if (uart->cts_pin >= 0) {
-               gpio_request(uart->cts_pin, NULL);
+               gpio_request(uart->cts_pin, DRIVER_NAME);
                gpio_direction_input(uart->cts_pin);
        }
 
        if (uart->rts_pin >= 0) {
-               gpio_request(uart->rts_pin, NULL);
+               gpio_request(uart->rts_pin, DRIVER_NAME);
                gpio_direction_output(uart->rts_pin);
        }
 #endif
index 23e13c5..ae6c53b 100644 (file)
 #define P_SPI0_SSEL2   (P_DEFINED | P_IDENT(PORT_PJ11) | P_FUNCT(1))
 #define P_SPI0_SSEL7   (P_DEFINED | P_IDENT(PORT_PJ5) | P_FUNCT(2))
 
-#endif /* _MACH_PORTMUX_H_ */
+#define P_MII0 {\
+       P_MII0_ETxD0, \
+       P_MII0_ETxD1, \
+       P_MII0_ETxD2, \
+       P_MII0_ETxD3, \
+       P_MII0_ETxEN, \
+       P_MII0_TxCLK, \
+       P_MII0_PHYINT, \
+       P_MII0_COL, \
+       P_MII0_ERxD0, \
+       P_MII0_ERxD1, \
+       P_MII0_ERxD2, \
+       P_MII0_ERxD3, \
+       P_MII0_ERxDV, \
+       P_MII0_ERxCLK, \
+       P_MII0_ERxER, \
+       P_MII0_CRS, \
+       P_MDC, \
+       P_MDIO, 0}
+
+
+#define P_RMII0 {\
+       P_MII0_ETxD0, \
+       P_MII0_ETxD1, \
+       P_MII0_ETxEN, \
+       P_MII0_ERxD0, \
+       P_MII0_ERxD1, \
+       P_MII0_ERxER, \
+       P_RMII0_REF_CLK, \
+       P_RMII0_MDINT, \
+       P_RMII0_CRS_DV, \
+       P_MDC, \
+       P_MDIO, 0}
+#endif                                 /* _MACH_PORTMUX_H_ */
index e043caf..69b9f8e 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/serial.h>
 #include <asm/dma.h>
+#include <asm/portmux.h>
 
 #define NR_PORTS                1
 
@@ -92,18 +93,24 @@ struct bfin_serial_res bfin_serial_resource[] = {
        }
 };
 
+#define DRIVER_NAME "bfin-uart"
 
 int nr_ports = NR_PORTS;
 static void bfin_serial_hw_init(struct bfin_serial_port *uart)
 {
 
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       peripheral_request(P_UART0_TX, DRIVER_NAME);
+       peripheral_request(P_UART0_RX, DRIVER_NAME);
+#endif
+
 #ifdef CONFIG_SERIAL_BFIN_CTSRTS
        if (uart->cts_pin >= 0) {
-               gpio_request(uart->cts_pin, NULL);
+               gpio_request(uart->cts_pin, DRIVER_NAME);
                gpio_direction_input(uart->cts_pin);
        }
        if (uart->rts_pin >= 0) {
-               gpio_request(uart->rts_pin, NULL);
+               gpio_request(uart->rts_pin, DRIVER_NAME);
                gpio_direction_input(uart->rts_pin);
        }
 #endif
index 9d3681e..0d3f650 100644 (file)
 #define P_MAYSHARE     0x2000
 #define P_DONTCARE     0x1000
 
+
+int peripheral_request(unsigned short per, const char *label);
+void peripheral_free(unsigned short per);
+int peripheral_request_list(unsigned short per[], const char *label);
+void peripheral_free_list(unsigned short per[]);
+
 #include <asm/gpio.h>
 #include <asm/mach/portmux.h>
 
 #define P_SPI2_SSEL3 P_UNDEF
 #endif
 
+#ifndef P_SPI2_SSEL4
+#define P_SPI2_SSEL4 P_UNDEF
+#endif
+
+#ifndef P_SPI2_SSEL5
+#define P_SPI2_SSEL5 P_UNDEF
+#endif
+
+#ifndef P_SPI2_SSEL6
+#define P_SPI2_SSEL6 P_UNDEF
+#endif
+
+#ifndef P_SPI2_SSEL7
+#define P_SPI2_SSEL7 P_UNDEF
+#endif
+
 #ifndef P_SPI2_SCK
 #define P_SPI2_SCK P_UNDEF
 #endif
 #define P_SPI0_SSEL3 P_UNDEF
 #endif
 
+#ifndef P_SPI0_SSEL4
+#define P_SPI0_SSEL4 P_UNDEF
+#endif
+
+#ifndef P_SPI0_SSEL5
+#define P_SPI0_SSEL5 P_UNDEF
+#endif
+
+#ifndef P_SPI0_SSEL6
+#define P_SPI0_SSEL6 P_UNDEF
+#endif
+
+#ifndef P_SPI0_SSEL7
+#define P_SPI0_SSEL7 P_UNDEF
+#endif
+
 #ifndef P_UART0_TX
 #define P_UART0_TX P_UNDEF
 #endif
 #define P_SPI1_SSEL3 P_UNDEF
 #endif
 
+
+#ifndef P_SPI1_SSEL4
+#define P_SPI1_SSEL4 P_UNDEF
+#endif
+
+#ifndef P_SPI1_SSEL5
+#define P_SPI1_SSEL5 P_UNDEF
+#endif
+
+#ifndef P_SPI1_SSEL6
+#define P_SPI1_SSEL6 P_UNDEF
+#endif
+
+#ifndef P_SPI1_SSEL7
+#define P_SPI1_SSEL7 P_UNDEF
+#endif
+
 #ifndef P_SPI1_SCK
 #define P_SPI1_SCK P_UNDEF
 #endif
index 0df9f2d..07ffe8b 100644 (file)
@@ -3,6 +3,7 @@
 /*
  * This file contains the system call numbers.
  */
+#define __NR_restart_syscall     0
 #define __NR_exit                1
 #define __NR_fork                2
 #define __NR_read                3
 #define __NR_sched_get_priority_min    160
 #define __NR_sched_rr_get_interval     161
 #define __NR_nanosleep         162
-                               /* 163 __NR_mremap */
+#define __NR_mremap            163
 #define __NR_setresuid         164
 #define __NR_getresuid         165
                                /* 166 __NR_vm86 */
                                /* 167 __NR_query_module */
                                /* 168 __NR_poll */
-                               /* 169 __NR_nfsservctl */
+#define __NR_nfsservctl                169
 #define __NR_setresgid         170
 #define __NR_getresgid         171
 #define __NR_prctl             172
                                /* 222 reserved for TUX */
                                /* 223 reserved for TUX */
 #define __NR_gettid            224
-                               /* 225 __NR_readahead */
+#define __NR_readahead         225
 #define __NR_setxattr          226
 #define __NR_lsetxattr         227
 #define __NR_fsetxattr         228
 #define __NR_mq_timedreceive   (__NR_mq_open+3)
 #define __NR_mq_notify         (__NR_mq_open+4)
 #define __NR_mq_getsetattr     (__NR_mq_open+5)
-                               /* 284 __NR_sys_kexec_load */
+#define __NR_kexec_load                284
 #define __NR_waitid            285
 #define __NR_add_key           286
 #define __NR_request_key       287
 #define __NR_shmdt             340
 #define __NR_shmget            341
 
-#define __NR_syscall           342
+#define __NR_splice            342
+#define __NR_sync_file_range   343
+#define __NR_tee               344
+#define __NR_vmsplice          345
+
+#define __NR_epoll_pwait       346
+#define __NR_utimensat         347
+#define __NR_signalfd          348
+#define __NR_timerfd           349
+#define __NR_eventfd           350
+#define __NR_pread64           351
+#define __NR_pwrite64          352
+#define __NR_fadvise64         353
+#define __NR_set_robust_list   354
+#define __NR_get_robust_list   355
+#define __NR_fallocate         356
+
+#define __NR_syscall           357
 #define NR_syscalls            __NR_syscall
 
+/* Old optional stuff no one actually uses */
+#define __IGNORE_sysfs
+#define __IGNORE_uselib
+
+/* Implement the newer interfaces */
+#define __IGNORE_mmap
+#define __IGNORE_poll
+#define __IGNORE_select
+#define __IGNORE_utime
+
+/* Not relevant on no-mmu */
+#define __IGNORE_swapon
+#define __IGNORE_swapoff
+#define __IGNORE_msync
+#define __IGNORE_mlock
+#define __IGNORE_munlock
+#define __IGNORE_mlockall
+#define __IGNORE_munlockall
+#define __IGNORE_mincore
+#define __IGNORE_madvise
+#define __IGNORE_remap_file_pages
+#define __IGNORE_mbind
+#define __IGNORE_get_mempolicy
+#define __IGNORE_set_mempolicy
+#define __IGNORE_migrate_pages
+#define __IGNORE_move_pages
+#define __IGNORE_getcpu
+
 #ifdef __KERNEL__
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_STAT64
index c20eee7..2a87350 100644 (file)
@@ -9,6 +9,7 @@
 #define        flat_argvp_envp_on_stack()              1
 #define        flat_old_ram_flag(flags)                1
 #define        flat_reloc_valid(reloc, size)           ((reloc) <= (size))
+#define        flat_set_persistent(relval, p)          0
 
 /*
  * on the H8 a couple of the relocations have an instruction in the
@@ -18,7 +19,7 @@
  */
 
 #define        flat_get_relocate_addr(rel)             (rel)
-#define flat_get_addr_from_rp(rp, relval, flags) \
+#define flat_get_addr_from_rp(rp, relval, flags, persistent) \
         (get_unaligned(rp) & ((flags & FLAT_FLAG_GOTPIC) ? 0xffffffff: 0x00ffffff))
 #define flat_put_addr_at_rp(rp, addr, rel) \
        put_unaligned (((*(char *)(rp)) << 24) | ((addr) & 0x00ffffff), rp)
index 609756c..d69ba93 100644 (file)
@@ -214,11 +214,6 @@ static inline unsigned long get_limit(unsigned long segment)
  */
  
 
-/* 
- * Actually only lfence would be needed for mb() because all stores done 
- * by the kernel should be already ordered. But keep a full barrier for now. 
- */
-
 #define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)
 #define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)
 
index 1b285f6..d851cf0 100644 (file)
 #define        flat_stack_align(sp)            (*sp += (*sp & 3 ? (4 - (*sp & 3)): 0))
 #define        flat_argvp_envp_on_stack()              0
 #define        flat_old_ram_flag(flags)                (flags)
+#define        flat_set_persistent(relval, p)          0
 #define        flat_reloc_valid(reloc, size)           \
        (((reloc) - textlen_for_m32r_lo16_data) <= (size))
-#define flat_get_addr_from_rp(rp, relval, flags) \
+#define flat_get_addr_from_rp(rp, relval, flags, persistent) \
        m32r_flat_get_addr_from_rp(rp, relval, (text_len) )
 
 #define flat_put_addr_at_rp(rp, addr, relval) \
index 2d836ed..814b517 100644 (file)
@@ -9,8 +9,9 @@
 #define        flat_argvp_envp_on_stack()              1
 #define        flat_old_ram_flag(flags)                (flags)
 #define        flat_reloc_valid(reloc, size)           ((reloc) <= (size))
-#define        flat_get_addr_from_rp(rp, relval, flags)        get_unaligned(rp)
+#define        flat_get_addr_from_rp(rp, relval, flags, p)     get_unaligned(rp)
 #define        flat_put_addr_at_rp(rp, val, relval)    put_unaligned(val,rp)
 #define        flat_get_relocate_addr(rel)             (rel)
+#define        flat_set_persistent(relval, p)          0
 
 #endif /* __M68KNOMMU_FLAT_H__ */
diff --git a/include/asm-mips/cmpxchg.h b/include/asm-mips/cmpxchg.h
new file mode 100644 (file)
index 0000000..c5b4708
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * 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) 2003, 06, 07 by Ralf Baechle (ralf@linux-mips.org)
+ */
+#ifndef __ASM_CMPXCHG_H
+#define __ASM_CMPXCHG_H
+
+#include <linux/irqflags.h>
+
+#define __HAVE_ARCH_CMPXCHG 1
+
+#define __cmpxchg_asm(ld, st, m, old, new)                             \
+({                                                                     \
+       __typeof(*(m)) __ret;                                           \
+                                                                       \
+       if (cpu_has_llsc && R10000_LLSC_WAR) {                          \
+               __asm__ __volatile__(                                   \
+               "       .set    push                            \n"     \
+               "       .set    noat                            \n"     \
+               "       .set    mips3                           \n"     \
+               "1:     " ld "  %0, %2          # __cmpxchg_asm \n"     \
+               "       bne     %0, %z3, 2f                     \n"     \
+               "       .set    mips0                           \n"     \
+               "       move    $1, %z4                         \n"     \
+               "       .set    mips3                           \n"     \
+               "       " st "  $1, %1                          \n"     \
+               "       beqzl   $1, 1b                          \n"     \
+               "2:                                             \n"     \
+               "       .set    pop                             \n"     \
+               : "=&r" (__ret), "=R" (*m)                              \
+               : "R" (*m), "Jr" (old), "Jr" (new)                      \
+               : "memory");                                            \
+       } else if (cpu_has_llsc) {                                      \
+               __asm__ __volatile__(                                   \
+               "       .set    push                            \n"     \
+               "       .set    noat                            \n"     \
+               "       .set    mips3                           \n"     \
+               "1:     " ld "  %0, %2          # __cmpxchg_asm \n"     \
+               "       bne     %0, %z3, 2f                     \n"     \
+               "       .set    mips0                           \n"     \
+               "       move    $1, %z4                         \n"     \
+               "       .set    mips3                           \n"     \
+               "       " st "  $1, %1                          \n"     \
+               "       beqz    $1, 3f                          \n"     \
+               "2:                                             \n"     \
+               "       .subsection 2                           \n"     \
+               "3:     b       1b                              \n"     \
+               "       .previous                               \n"     \
+               "       .set    pop                             \n"     \
+               : "=&r" (__ret), "=R" (*m)                              \
+               : "R" (*m), "Jr" (old), "Jr" (new)                      \
+               : "memory");                                            \
+       } else {                                                        \
+               unsigned long __flags;                                  \
+                                                                       \
+               raw_local_irq_save(__flags);                            \
+               __ret = *m;                                             \
+               if (__ret == old)                                       \
+                       *m = new;                                       \
+               raw_local_irq_restore(__flags);                         \
+       }                                                               \
+                                                                       \
+       __ret;                                                          \
+})
+
+/*
+ * This function doesn't exist, so you'll get a linker error
+ * if something tries to do an invalid cmpxchg().
+ */
+extern void __cmpxchg_called_with_bad_pointer(void);
+
+#define __cmpxchg(ptr,old,new,barrier)                                 \
+({                                                                     \
+       __typeof__(ptr) __ptr = (ptr);                                  \
+       __typeof__(*(ptr)) __old = (old);                               \
+       __typeof__(*(ptr)) __new = (new);                               \
+       __typeof__(*(ptr)) __res = 0;                                   \
+                                                                       \
+       barrier;                                                        \
+                                                                       \
+       switch (sizeof(*(__ptr))) {                                     \
+       case 4:                                                         \
+               __res = __cmpxchg_asm("ll", "sc", __ptr, __old, __new); \
+               break;                                                  \
+       case 8:                                                         \
+               if (sizeof(long) == 8) {                                \
+                       __res = __cmpxchg_asm("lld", "scd", __ptr,      \
+                                          __old, __new);               \
+                       break;                                          \
+               }                                                       \
+       default:                                                        \
+               __cmpxchg_called_with_bad_pointer();                    \
+               break;                                                  \
+       }                                                               \
+                                                                       \
+       barrier;                                                        \
+                                                                       \
+       __res;                                                          \
+})
+
+#define cmpxchg(ptr, old, new)         __cmpxchg(ptr, old, new, smp_llsc_mb())
+#define cmpxchg_local(ptr, old, new)   __cmpxchg(ptr, old, new,)
+
+#endif /* __ASM_CMPXCHG_H */
index 00a50ec..2a52333 100644 (file)
@@ -13,6 +13,7 @@
 #define O_SYNC         0x0010
 #define O_NONBLOCK     0x0080
 #define O_CREAT         0x0100 /* not fcntl */
+#define O_TRUNC                0x0200  /* not fcntl */
 #define O_EXCL         0x0400  /* not fcntl */
 #define O_NOCTTY       0x0800  /* not fcntl */
 #define FASYNC         0x1000  /* fcntl, for BSD compatibility */
index ed882c8..f9a5ce5 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/percpu.h>
 #include <linux/bitops.h>
 #include <asm/atomic.h>
+#include <asm/cmpxchg.h>
 #include <asm/war.h>
 
 typedef struct
@@ -114,68 +115,6 @@ static __inline__ long local_sub_return(long i, local_t * l)
        return result;
 }
 
-/*
- * local_sub_if_positive - conditionally subtract integer from atomic variable
- * @i: integer value to subtract
- * @l: pointer of type local_t
- *
- * Atomically test @l and subtract @i if @l is greater or equal than @i.
- * The function returns the old value of @l minus @i.
- */
-static __inline__ long local_sub_if_positive(long i, local_t * l)
-{
-       unsigned long result;
-
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
-               unsigned long temp;
-
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:"    __LL    "%1, %2         # local_sub_if_positive\n"
-               "       dsubu   %0, %1, %3                              \n"
-               "       bltz    %0, 1f                                  \n"
-                       __SC    "%0, %2                                 \n"
-               "       .set    noreorder                               \n"
-               "       beqzl   %0, 1b                                  \n"
-               "        dsubu  %0, %1, %3                              \n"
-               "       .set    reorder                                 \n"
-               "1:                                                     \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
-               : "Ir" (i), "m" (l->a.counter)
-               : "memory");
-       } else if (cpu_has_llsc) {
-               unsigned long temp;
-
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:"    __LL    "%1, %2         # local_sub_if_positive\n"
-               "       dsubu   %0, %1, %3                              \n"
-               "       bltz    %0, 1f                                  \n"
-                       __SC    "%0, %2                                 \n"
-               "       .set    noreorder                               \n"
-               "       beqz    %0, 1b                                  \n"
-               "        dsubu  %0, %1, %3                              \n"
-               "       .set    reorder                                 \n"
-               "1:                                                     \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
-               : "Ir" (i), "m" (l->a.counter)
-               : "memory");
-       } else {
-               unsigned long flags;
-
-               local_irq_save(flags);
-               result = l->a.counter;
-               result -= i;
-               if (result >= 0)
-                       l->a.counter = result;
-               local_irq_restore(flags);
-       }
-
-       return result;
-}
-
 #define local_cmpxchg(l, o, n) \
        ((long)cmpxchg_local(&((l)->a.counter), (o), (n)))
 #define local_xchg(l, n) (xchg_local(&((l)->a.counter),(n)))
@@ -234,12 +173,6 @@ static __inline__ long local_sub_if_positive(long i, local_t * l)
 #define local_dec_and_test(l) (local_sub_return(1, (l)) == 0)
 
 /*
- * local_dec_if_positive - decrement by 1 if old value positive
- * @l: pointer of type local_t
- */
-#define local_dec_if_positive(l)       local_sub_if_positive(1, l)
-
-/*
  * local_add_negative - add and test if negative
  * @l: pointer of type local_t
  * @i: integer value to add
index b92dd8c..e3301e5 100644 (file)
@@ -142,7 +142,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
 /*
  * __pa()/__va() should be used only during mem init.
  */
-#if defined(CONFIG_64BIT) && !defined(CONFIG_BUILD_ELF64)
+#ifdef CONFIG_64BIT
 #define __pa(x)                                                                \
 ({                                                                     \
     unsigned long __x = (unsigned long)(x);                            \
index 357251f..480b574 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <asm/addrspace.h>
 #include <asm/barrier.h>
+#include <asm/cmpxchg.h>
 #include <asm/cpu-features.h>
 #include <asm/dsp.h>
 #include <asm/war.h>
@@ -194,266 +195,6 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
 
 #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
 
-#define __HAVE_ARCH_CMPXCHG 1
-
-static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old,
-       unsigned long new)
-{
-       __u32 retval;
-
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
-               __asm__ __volatile__(
-               "       .set    push                                    \n"
-               "       .set    noat                                    \n"
-               "       .set    mips3                                   \n"
-               "1:     ll      %0, %2                  # __cmpxchg_u32 \n"
-               "       bne     %0, %z3, 2f                             \n"
-               "       .set    mips0                                   \n"
-               "       move    $1, %z4                                 \n"
-               "       .set    mips3                                   \n"
-               "       sc      $1, %1                                  \n"
-               "       beqzl   $1, 1b                                  \n"
-               "2:                                                     \n"
-               "       .set    pop                                     \n"
-               : "=&r" (retval), "=R" (*m)
-               : "R" (*m), "Jr" (old), "Jr" (new)
-               : "memory");
-       } else if (cpu_has_llsc) {
-               __asm__ __volatile__(
-               "       .set    push                                    \n"
-               "       .set    noat                                    \n"
-               "       .set    mips3                                   \n"
-               "1:     ll      %0, %2                  # __cmpxchg_u32 \n"
-               "       bne     %0, %z3, 2f                             \n"
-               "       .set    mips0                                   \n"
-               "       move    $1, %z4                                 \n"
-               "       .set    mips3                                   \n"
-               "       sc      $1, %1                                  \n"
-               "       beqz    $1, 3f                                  \n"
-               "2:                                                     \n"
-               "       .subsection 2                                   \n"
-               "3:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    pop                                     \n"
-               : "=&r" (retval), "=R" (*m)
-               : "R" (*m), "Jr" (old), "Jr" (new)
-               : "memory");
-       } else {
-               unsigned long flags;
-
-               raw_local_irq_save(flags);
-               retval = *m;
-               if (retval == old)
-                       *m = new;
-               raw_local_irq_restore(flags);   /* implies memory barrier  */
-       }
-
-       smp_llsc_mb();
-
-       return retval;
-}
-
-static inline unsigned long __cmpxchg_u32_local(volatile int * m,
-       unsigned long old, unsigned long new)
-{
-       __u32 retval;
-
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
-               __asm__ __volatile__(
-               "       .set    push                                    \n"
-               "       .set    noat                                    \n"
-               "       .set    mips3                                   \n"
-               "1:     ll      %0, %2                  # __cmpxchg_u32 \n"
-               "       bne     %0, %z3, 2f                             \n"
-               "       .set    mips0                                   \n"
-               "       move    $1, %z4                                 \n"
-               "       .set    mips3                                   \n"
-               "       sc      $1, %1                                  \n"
-               "       beqzl   $1, 1b                                  \n"
-               "2:                                                     \n"
-               "       .set    pop                                     \n"
-               : "=&r" (retval), "=R" (*m)
-               : "R" (*m), "Jr" (old), "Jr" (new)
-               : "memory");
-       } else if (cpu_has_llsc) {
-               __asm__ __volatile__(
-               "       .set    push                                    \n"
-               "       .set    noat                                    \n"
-               "       .set    mips3                                   \n"
-               "1:     ll      %0, %2                  # __cmpxchg_u32 \n"
-               "       bne     %0, %z3, 2f                             \n"
-               "       .set    mips0                                   \n"
-               "       move    $1, %z4                                 \n"
-               "       .set    mips3                                   \n"
-               "       sc      $1, %1                                  \n"
-               "       beqz    $1, 1b                                  \n"
-               "2:                                                     \n"
-               "       .set    pop                                     \n"
-               : "=&r" (retval), "=R" (*m)
-               : "R" (*m), "Jr" (old), "Jr" (new)
-               : "memory");
-       } else {
-               unsigned long flags;
-
-               local_irq_save(flags);
-               retval = *m;
-               if (retval == old)
-                       *m = new;
-               local_irq_restore(flags);       /* implies memory barrier  */
-       }
-
-       return retval;
-}
-
-#ifdef CONFIG_64BIT
-static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old,
-       unsigned long new)
-{
-       __u64 retval;
-
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
-               __asm__ __volatile__(
-               "       .set    push                                    \n"
-               "       .set    noat                                    \n"
-               "       .set    mips3                                   \n"
-               "1:     lld     %0, %2                  # __cmpxchg_u64 \n"
-               "       bne     %0, %z3, 2f                             \n"
-               "       move    $1, %z4                                 \n"
-               "       scd     $1, %1                                  \n"
-               "       beqzl   $1, 1b                                  \n"
-               "2:                                                     \n"
-               "       .set    pop                                     \n"
-               : "=&r" (retval), "=R" (*m)
-               : "R" (*m), "Jr" (old), "Jr" (new)
-               : "memory");
-       } else if (cpu_has_llsc) {
-               __asm__ __volatile__(
-               "       .set    push                                    \n"
-               "       .set    noat                                    \n"
-               "       .set    mips3                                   \n"
-               "1:     lld     %0, %2                  # __cmpxchg_u64 \n"
-               "       bne     %0, %z3, 2f                             \n"
-               "       move    $1, %z4                                 \n"
-               "       scd     $1, %1                                  \n"
-               "       beqz    $1, 3f                                  \n"
-               "2:                                                     \n"
-               "       .subsection 2                                   \n"
-               "3:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    pop                                     \n"
-               : "=&r" (retval), "=R" (*m)
-               : "R" (*m), "Jr" (old), "Jr" (new)
-               : "memory");
-       } else {
-               unsigned long flags;
-
-               raw_local_irq_save(flags);
-               retval = *m;
-               if (retval == old)
-                       *m = new;
-               raw_local_irq_restore(flags);   /* implies memory barrier  */
-       }
-
-       smp_llsc_mb();
-
-       return retval;
-}
-
-static inline unsigned long __cmpxchg_u64_local(volatile int * m,
-       unsigned long old, unsigned long new)
-{
-       __u64 retval;
-
-       if (cpu_has_llsc && R10000_LLSC_WAR) {
-               __asm__ __volatile__(
-               "       .set    push                                    \n"
-               "       .set    noat                                    \n"
-               "       .set    mips3                                   \n"
-               "1:     lld     %0, %2                  # __cmpxchg_u64 \n"
-               "       bne     %0, %z3, 2f                             \n"
-               "       move    $1, %z4                                 \n"
-               "       scd     $1, %1                                  \n"
-               "       beqzl   $1, 1b                                  \n"
-               "2:                                                     \n"
-               "       .set    pop                                     \n"
-               : "=&r" (retval), "=R" (*m)
-               : "R" (*m), "Jr" (old), "Jr" (new)
-               : "memory");
-       } else if (cpu_has_llsc) {
-               __asm__ __volatile__(
-               "       .set    push                                    \n"
-               "       .set    noat                                    \n"
-               "       .set    mips3                                   \n"
-               "1:     lld     %0, %2                  # __cmpxchg_u64 \n"
-               "       bne     %0, %z3, 2f                             \n"
-               "       move    $1, %z4                                 \n"
-               "       scd     $1, %1                                  \n"
-               "       beqz    $1, 1b                                  \n"
-               "2:                                                     \n"
-               "       .set    pop                                     \n"
-               : "=&r" (retval), "=R" (*m)
-               : "R" (*m), "Jr" (old), "Jr" (new)
-               : "memory");
-       } else {
-               unsigned long flags;
-
-               local_irq_save(flags);
-               retval = *m;
-               if (retval == old)
-                       *m = new;
-               local_irq_restore(flags);       /* implies memory barrier  */
-       }
-
-       return retval;
-}
-
-#else
-extern unsigned long __cmpxchg_u64_unsupported_on_32bit_kernels(
-       volatile int * m, unsigned long old, unsigned long new);
-#define __cmpxchg_u64 __cmpxchg_u64_unsupported_on_32bit_kernels
-extern unsigned long __cmpxchg_u64_local_unsupported_on_32bit_kernels(
-       volatile int * m, unsigned long old, unsigned long new);
-#define __cmpxchg_u64_local __cmpxchg_u64_local_unsupported_on_32bit_kernels
-#endif
-
-/* This function doesn't exist, so you'll get a linker error
-   if something tries to do an invalid cmpxchg().  */
-extern void __cmpxchg_called_with_bad_pointer(void);
-
-static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old,
-       unsigned long new, int size)
-{
-       switch (size) {
-       case 4:
-               return __cmpxchg_u32(ptr, old, new);
-       case 8:
-               return __cmpxchg_u64(ptr, old, new);
-       }
-       __cmpxchg_called_with_bad_pointer();
-       return old;
-}
-
-static inline unsigned long __cmpxchg_local(volatile void * ptr,
-       unsigned long old, unsigned long new, int size)
-{
-       switch (size) {
-       case 4:
-               return __cmpxchg_u32_local(ptr, old, new);
-       case 8:
-               return __cmpxchg_u64_local(ptr, old, new);
-       }
-       __cmpxchg_called_with_bad_pointer();
-       return old;
-}
-
-#define cmpxchg(ptr,old,new) \
-       ((__typeof__(*(ptr)))__cmpxchg((ptr), \
-               (unsigned long)(old), (unsigned long)(new),sizeof(*(ptr))))
-
-#define cmpxchg_local(ptr,old,new) \
-       ((__typeof__(*(ptr)))__cmpxchg_local((ptr), \
-               (unsigned long)(old), (unsigned long)(new),sizeof(*(ptr))))
-
 extern void set_handler (unsigned long offset, void *addr, unsigned long len);
 extern void set_uncached_handler (unsigned long offset, void *addr, unsigned long len);
 
index 0d5cc04..dc4f595 100644 (file)
@@ -16,8 +16,9 @@
 #define        flat_argvp_envp_on_stack()              0
 #define        flat_old_ram_flag(flags)                (flags)
 #define        flat_reloc_valid(reloc, size)           ((reloc) <= (size))
-#define        flat_get_addr_from_rp(rp, relval, flags)        get_unaligned(rp)
+#define        flat_get_addr_from_rp(rp, relval, flags, p)     get_unaligned(rp)
 #define        flat_put_addr_at_rp(rp, val, relval)    put_unaligned(val,rp)
 #define        flat_get_relocate_addr(rel)             (rel)
+#define        flat_set_persistent(relval, p)          0
 
 #endif /* __ASM_SH_FLAT_H */
index 3888f59..17f0ea5 100644 (file)
@@ -25,6 +25,7 @@
 #define        flat_stack_align(sp)            /* nothing needed */
 #define        flat_argvp_envp_on_stack()      0
 #define        flat_old_ram_flag(flags)        (flags)
+#define        flat_set_persistent(relval, p)  0
 
 /* We store the type of relocation in the top 4 bits of the `relval.' */
 
@@ -46,7 +47,8 @@ flat_get_relocate_addr (unsigned long relval)
    For the v850, RP should always be half-word aligned.  */
 static inline unsigned long flat_get_addr_from_rp (unsigned long *rp,
                                                   unsigned long relval,
-                                                  unsigned long flags)
+                                                  unsigned long flags,
+                                                  unsigned long *persistent)
 {
        short *srp = (short *)rp;
 
index 1952517..31f579b 100644 (file)
@@ -371,7 +371,7 @@ static inline void sync_core(void)
 #define ARCH_HAS_PREFETCH
 static inline void prefetch(void *x) 
 { 
-       asm volatile("prefetcht0 %0" :: "m" (*(unsigned long *)x));
+       asm volatile("prefetcht0 (%0)" :: "r" (x));
 } 
 
 #define ARCH_HAS_PREFETCHW 1
index a01ac6d..313c6b6 100644 (file)
@@ -113,7 +113,7 @@ extern unsigned long avenrun[];             /* Load averages */
 
 #define FSHIFT         11              /* nr of bits of precision */
 #define FIXED_1                (1<<FSHIFT)     /* 1.0 as fixed-point */
-#define LOAD_FREQ      (5*HZ)          /* 5 sec intervals */
+#define LOAD_FREQ      (5*HZ+1)        /* 5 sec intervals */
 #define EXP_1          1884            /* 1/exp(5sec/1min) as fixed-point */
 #define EXP_5          2014            /* 1/exp(5sec/5min) */
 #define EXP_15         2037            /* 1/exp(5sec/15min) */
index 4ef4d22..b4af6bc 100644 (file)
@@ -127,7 +127,7 @@ int sync_page_range(struct inode *inode, struct address_space *mapping,
                        loff_t pos, loff_t count);
 int sync_page_range_nolock(struct inode *inode, struct address_space *mapping,
                           loff_t pos, loff_t count);
-void set_page_dirty_balance(struct page *page);
+void set_page_dirty_balance(struct page *page, int page_mkwrite);
 void writeback_set_ratelimit(void);
 
 /* pdflush.c */
index a4047d3..e5bb084 100644 (file)
@@ -188,7 +188,7 @@ extern void rose_kick(struct sock *);
 extern void rose_enquiry_response(struct sock *);
 
 /* rose_route.c */
-extern struct rose_neigh rose_loopback_neigh;
+extern struct rose_neigh *rose_loopback_neigh;
 extern const struct file_operations rose_neigh_fops;
 extern const struct file_operations rose_nodes_fops;
 extern const struct file_operations rose_routes_fops;
index 185c7ec..54053de 100644 (file)
@@ -1059,14 +1059,12 @@ struct tcp_md5sig_key {
 };
 
 struct tcp4_md5sig_key {
-       u8                      *key;
-       u16                     keylen;
+       struct tcp_md5sig_key   base;
        __be32                  addr;
 };
 
 struct tcp6_md5sig_key {
-       u8                      *key;
-       u16                     keylen;
+       struct tcp_md5sig_key   base;
 #if 0
        u32                     scope_id;       /* XXX */
 #endif
index e8935b1..fcc94e7 100644 (file)
@@ -1943,9 +1943,10 @@ static inline int fetch_robust_entry(struct robust_list __user **entry,
 void exit_robust_list(struct task_struct *curr)
 {
        struct robust_list_head __user *head = curr->robust_list;
-       struct robust_list __user *entry, *pending;
-       unsigned int limit = ROBUST_LIST_LIMIT, pi, pip;
+       struct robust_list __user *entry, *next_entry, *pending;
+       unsigned int limit = ROBUST_LIST_LIMIT, pi, next_pi, pip;
        unsigned long futex_offset;
+       int rc;
 
        /*
         * Fetch the list head (which was registered earlier, via
@@ -1965,12 +1966,14 @@ void exit_robust_list(struct task_struct *curr)
        if (fetch_robust_entry(&pending, &head->list_op_pending, &pip))
                return;
 
-       if (pending)
-               handle_futex_death((void __user *)pending + futex_offset,
-                                  curr, pip);
-
+       next_entry = NULL;      /* avoid warning with gcc */
        while (entry != &head->list) {
                /*
+                * Fetch the next entry in the list before calling
+                * handle_futex_death:
+                */
+               rc = fetch_robust_entry(&next_entry, &entry->next, &next_pi);
+               /*
                 * A pending lock might already be on the list, so
                 * don't process it twice:
                 */
@@ -1978,11 +1981,10 @@ void exit_robust_list(struct task_struct *curr)
                        if (handle_futex_death((void __user *)entry + futex_offset,
                                                curr, pi))
                                return;
-               /*
-                * Fetch the next entry in the list:
-                */
-               if (fetch_robust_entry(&entry, &entry->next, &pi))
+               if (rc)
                        return;
+               entry = next_entry;
+               pi = next_pi;
                /*
                 * Avoid excessively long or circular lists:
                 */
@@ -1991,6 +1993,10 @@ void exit_robust_list(struct task_struct *curr)
 
                cond_resched();
        }
+
+       if (pending)
+               handle_futex_death((void __user *)pending + futex_offset,
+                                  curr, pip);
 }
 
 long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
index 7e52eb0..2c2e295 100644 (file)
@@ -38,10 +38,11 @@ fetch_robust_entry(compat_uptr_t *uentry, struct robust_list __user **entry,
 void compat_exit_robust_list(struct task_struct *curr)
 {
        struct compat_robust_list_head __user *head = curr->compat_robust_list;
-       struct robust_list __user *entry, *pending;
-       unsigned int limit = ROBUST_LIST_LIMIT, pi, pip;
-       compat_uptr_t uentry, upending;
+       struct robust_list __user *entry, *next_entry, *pending;
+       unsigned int limit = ROBUST_LIST_LIMIT, pi, next_pi, pip;
+       compat_uptr_t uentry, next_uentry, upending;
        compat_long_t futex_offset;
+       int rc;
 
        /*
         * Fetch the list head (which was registered earlier, via
@@ -61,11 +62,16 @@ void compat_exit_robust_list(struct task_struct *curr)
        if (fetch_robust_entry(&upending, &pending,
                               &head->list_op_pending, &pip))
                return;
-       if (pending)
-               handle_futex_death((void __user *)pending + futex_offset, curr, pip);
 
+       next_entry = NULL;      /* avoid warning with gcc */
        while (entry != (struct robust_list __user *) &head->list) {
                /*
+                * Fetch the next entry in the list before calling
+                * handle_futex_death:
+                */
+               rc = fetch_robust_entry(&next_uentry, &next_entry,
+                       (compat_uptr_t __user *)&entry->next, &next_pi);
+               /*
                 * A pending lock might already be on the list, so
                 * dont process it twice:
                 */
@@ -74,12 +80,11 @@ void compat_exit_robust_list(struct task_struct *curr)
                                                curr, pi))
                                return;
 
-               /*
-                * Fetch the next entry in the list:
-                */
-               if (fetch_robust_entry(&uentry, &entry,
-                                      (compat_uptr_t __user *)&entry->next, &pi))
+               if (rc)
                        return;
+               uentry = next_uentry;
+               entry = next_entry;
+               pi = next_pi;
                /*
                 * Avoid excessively long or circular lists:
                 */
@@ -88,6 +93,9 @@ void compat_exit_robust_list(struct task_struct *curr)
 
                cond_resched();
        }
+       if (pending)
+               handle_futex_death((void __user *)pending + futex_offset,
+                                  curr, pip);
 }
 
 asmlinkage long
index c9fbe8e..67c67a8 100644 (file)
@@ -639,6 +639,16 @@ static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se)
 
                se->block_start = 0;
                se->sum_sleep_runtime += delta;
+
+               /*
+                * Blocking time is in units of nanosecs, so shift by 20 to
+                * get a milliseconds-range estimation of the amount of
+                * time that the task spent sleeping:
+                */
+               if (unlikely(prof_on == SLEEP_PROFILING)) {
+                       profile_hits(SLEEP_PROFILING, (void *)get_wchan(tsk),
+                                    delta >> 20);
+               }
        }
 #endif
 }
index 9fb91a3..7929523 100644 (file)
@@ -531,18 +531,18 @@ static int check_kill_permission(int sig, struct siginfo *info,
        if (!valid_signal(sig))
                return error;
 
-       error = audit_signal_info(sig, t); /* Let audit system see the signal */
-       if (error)
-               return error;
-
-       error = -EPERM;
-       if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info)))
-           && ((sig != SIGCONT) ||
-               (process_session(current) != process_session(t)))
-           && (current->euid ^ t->suid) && (current->euid ^ t->uid)
-           && (current->uid ^ t->suid) && (current->uid ^ t->uid)
-           && !capable(CAP_KILL))
+       if (info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info))) {
+               error = audit_signal_info(sig, t); /* Let audit system see the signal */
+               if (error)
+                       return error;
+               error = -EPERM;
+               if (((sig != SIGCONT) ||
+                       (process_session(current) != process_session(t)))
+                   && (current->euid ^ t->suid) && (current->euid ^ t->uid)
+                   && (current->uid ^ t->suid) && (current->uid ^ t->uid)
+                   && !capable(CAP_KILL))
                return error;
+       }
 
        return security_task_kill(t, info, sig, 0);
 }
index 1b33b05..8ae2e63 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/getcpu.h>
 #include <linux/task_io_accounting_ops.h>
 #include <linux/seccomp.h>
+#include <linux/cpu.h>
 
 #include <linux/compat.h>
 #include <linux/syscalls.h>
@@ -878,6 +879,7 @@ void kernel_power_off(void)
        kernel_shutdown_prepare(SYSTEM_POWER_OFF);
        if (pm_power_off_prepare)
                pm_power_off_prepare();
+       disable_nonboot_cpus();
        sysdev_shutdown();
        printk(KERN_EMERG "Power down.\n");
        machine_power_off();
index 3c38fb5..c36bb7e 100644 (file)
@@ -327,8 +327,9 @@ static int tstats_show(struct seq_file *m, void *v)
                ms = 1;
 
        if (events && period.tv_sec)
-               seq_printf(m, "%ld total events, %ld.%ld events/sec\n", events,
-                          events / period.tv_sec, events * 1000 / ms);
+               seq_printf(m, "%ld total events, %ld.%03ld events/sec\n",
+                          events, events * 1000 / ms,
+                          (events * 1000000 / ms) % 1000);
        else
                seq_printf(m, "%ld total events\n", events);
 
index 495863a..cdc9b09 100644 (file)
@@ -294,6 +294,8 @@ config LOCK_STAT
        help
         This feature enables tracking lock contention points
 
+        For more details, see Documentation/lockstat.txt
+
 config DEBUG_LOCKDEP
        bool "Lock dependency engine debugging"
        depends on DEBUG_KERNEL && LOCKDEP
index 6b0ba8c..4f3f3e2 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for some libs needed in the kernel.
 #
 
-lib-y := ctype.o string.o vsprintf.o kasprintf.o cmdline.o \
+lib-y := ctype.o string.o vsprintf.o cmdline.o \
         rbtree.o radix-tree.o dump_stack.o \
         idr.o int_sqrt.o bitmap.o extable.o prio_tree.o \
         sha1.o irq_regs.o reciprocal_div.o argv_split.o
@@ -13,7 +13,7 @@ lib-$(CONFIG_SMP) += cpumask.o
 lib-y  += kobject.o kref.o kobject_uevent.o klist.o
 
 obj-y += div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
-        bust_spinlocks.o hexdump.o
+        bust_spinlocks.o hexdump.o kasprintf.o
 
 ifeq ($(CONFIG_DEBUG_KOBJECT),y)
 CFLAGS_kobject.o += -DDEBUG
index e24d348..a7609cb 100644 (file)
@@ -137,6 +137,7 @@ config SPLIT_PTLOCK_CPUS
        int
        default "4096" if ARM && !CPU_CACHE_VIPT
        default "4096" if PARISC && !PA20
+       default "4096" if XEN
        default "4"
 
 #
index 90b657b..15c8413 100644 (file)
@@ -1388,6 +1388,7 @@ retry_find:
        size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
        if (unlikely(vmf->pgoff >= size)) {
                unlock_page(page);
+               page_cache_release(page);
                goto outside_data_content;
        }
 
index c395b1a..95bcb56 100644 (file)
@@ -160,7 +160,7 @@ asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size,
        if (vma->vm_private_data && !(vma->vm_flags & VM_NONLINEAR))
                goto out;
 
-       if (!vma->vm_flags & VM_CAN_NONLINEAR)
+       if (!(vma->vm_flags & VM_CAN_NONLINEAR))
                goto out;
 
        if (end <= start || start < vma->vm_start || end > vma->vm_end)
index 84c795e..eab8c42 100644 (file)
@@ -42,7 +42,7 @@ static void clear_huge_page(struct page *page, unsigned long addr)
        might_sleep();
        for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); i++) {
                cond_resched();
-               clear_user_highpage(page + i, addr);
+               clear_user_highpage(page + i, addr + i * PAGE_SIZE);
        }
 }
 
index ca8cac1..f82b359 100644 (file)
@@ -1639,6 +1639,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
        struct page *old_page, *new_page;
        pte_t entry;
        int reuse = 0, ret = 0;
+       int page_mkwrite = 0;
        struct page *dirty_page = NULL;
 
        old_page = vm_normal_page(vma, address, orig_pte);
@@ -1687,6 +1688,8 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
                        page_cache_release(old_page);
                        if (!pte_same(*page_table, orig_pte))
                                goto unlock;
+
+                       page_mkwrite = 1;
                }
                dirty_page = old_page;
                get_page(dirty_page);
@@ -1774,7 +1777,7 @@ unlock:
                 * do_no_page is protected similarly.
                 */
                wait_on_page_locked(dirty_page);
-               set_page_dirty_balance(dirty_page);
+               set_page_dirty_balance(dirty_page, page_mkwrite);
                put_page(dirty_page);
        }
        return ret;
@@ -2307,13 +2310,14 @@ oom:
  * do not need to flush old virtual caches or the TLB.
  *
  * We enter with non-exclusive mmap_sem (to exclude vma changes,
- * but allow concurrent faults), and pte mapped but not yet locked.
+ * but allow concurrent faults), and pte neither mapped nor locked.
  * We return with mmap_sem still held, but pte unmapped and unlocked.
  */
 static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
-               unsigned long address, pte_t *page_table, pmd_t *pmd,
+               unsigned long address, pmd_t *pmd,
                pgoff_t pgoff, unsigned int flags, pte_t orig_pte)
 {
+       pte_t *page_table;
        spinlock_t *ptl;
        struct page *page;
        pte_t entry;
@@ -2321,13 +2325,13 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
        struct page *dirty_page = NULL;
        struct vm_fault vmf;
        int ret;
+       int page_mkwrite = 0;
 
        vmf.virtual_address = (void __user *)(address & PAGE_MASK);
        vmf.pgoff = pgoff;
        vmf.flags = flags;
        vmf.page = NULL;
 
-       pte_unmap(page_table);
        BUG_ON(vma->vm_flags & VM_PFNMAP);
 
        if (likely(vma->vm_ops->fault)) {
@@ -2398,6 +2402,7 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
                                        anon = 1; /* no anon but release vmf.page */
                                        goto out;
                                }
+                               page_mkwrite = 1;
                        }
                }
 
@@ -2453,7 +2458,7 @@ out_unlocked:
        if (anon)
                page_cache_release(vmf.page);
        else if (dirty_page) {
-               set_page_dirty_balance(dirty_page);
+               set_page_dirty_balance(dirty_page, page_mkwrite);
                put_page(dirty_page);
        }
 
@@ -2468,8 +2473,8 @@ static int do_linear_fault(struct mm_struct *mm, struct vm_area_struct *vma,
                        - vma->vm_start) >> PAGE_CACHE_SHIFT) + vma->vm_pgoff;
        unsigned int flags = (write_access ? FAULT_FLAG_WRITE : 0);
 
-       return __do_fault(mm, vma, address, page_table, pmd, pgoff,
-                                                       flags, orig_pte);
+       pte_unmap(page_table);
+       return __do_fault(mm, vma, address, pmd, pgoff, flags, orig_pte);
 }
 
 
@@ -2552,9 +2557,7 @@ static int do_nonlinear_fault(struct mm_struct *mm, struct vm_area_struct *vma,
        }
 
        pgoff = pte_to_pgoff(orig_pte);
-
-       return __do_fault(mm, vma, address, page_table, pmd, pgoff,
-                                                       flags, orig_pte);
+       return __do_fault(mm, vma, address, pmd, pgoff, flags, orig_pte);
 }
 
 /*
index 63512a9..4472036 100644 (file)
@@ -274,9 +274,9 @@ static void balance_dirty_pages(struct address_space *mapping)
                pdflush_operation(background_writeout, 0);
 }
 
-void set_page_dirty_balance(struct page *page)
+void set_page_dirty_balance(struct page *page, int page_mkwrite)
 {
-       if (set_page_dirty(page)) {
+       if (set_page_dirty(page) || page_mkwrite) {
                struct address_space *mapping = page_mapping(page);
 
                if (mapping)
index f2de2e4..6284c99 100644 (file)
@@ -366,6 +366,12 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
        frag = WLAN_GET_SEQ_FRAG(sc);
        hdrlen = ieee80211_get_hdrlen(fc);
 
+       if (skb->len < hdrlen) {
+               printk(KERN_INFO "%s: invalid SKB length %d\n",
+                       dev->name, skb->len);
+               goto rx_dropped;
+       }
+
        /* Put this code here so that we avoid duplicating it in all
         * Rx paths. - Jean II */
 #ifdef CONFIG_WIRELESS_EXT
index 442b987..5742dc8 100644 (file)
@@ -114,7 +114,7 @@ check_assoc_again:
        sm->associnfo.associating = 1;
        /* queue lower level code to do work (if necessary) */
        schedule_delayed_work(&sm->associnfo.work, 0);
-out:
+
        mutex_unlock(&sm->associnfo.mutex);
 
        return 0;
index bbad2cd..f893e90 100644 (file)
@@ -2420,6 +2420,9 @@ static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb,
                        __u32 dval = min(tp->fackets_out, packets_acked);
                        tp->fackets_out -= dval;
                }
+               /* hint's skb might be NULL but we don't need to care */
+               tp->fastpath_cnt_hint -= min_t(u32, packets_acked,
+                                              tp->fastpath_cnt_hint);
                tp->packets_out -= packets_acked;
 
                BUG_ON(tcp_skb_pcount(skb) == 0);
index 9c94627..e089a97 100644 (file)
@@ -833,8 +833,7 @@ static struct tcp_md5sig_key *
                return NULL;
        for (i = 0; i < tp->md5sig_info->entries4; i++) {
                if (tp->md5sig_info->keys4[i].addr == addr)
-                       return (struct tcp_md5sig_key *)
-                                               &tp->md5sig_info->keys4[i];
+                       return &tp->md5sig_info->keys4[i].base;
        }
        return NULL;
 }
@@ -865,9 +864,9 @@ int tcp_v4_md5_do_add(struct sock *sk, __be32 addr,
        key = (struct tcp4_md5sig_key *)tcp_v4_md5_do_lookup(sk, addr);
        if (key) {
                /* Pre-existing entry - just update that one. */
-               kfree(key->key);
-               key->key = newkey;
-               key->keylen = newkeylen;
+               kfree(key->base.key);
+               key->base.key = newkey;
+               key->base.keylen = newkeylen;
        } else {
                struct tcp_md5sig_info *md5sig;
 
@@ -906,9 +905,9 @@ int tcp_v4_md5_do_add(struct sock *sk, __be32 addr,
                        md5sig->alloced4++;
                }
                md5sig->entries4++;
-               md5sig->keys4[md5sig->entries4 - 1].addr   = addr;
-               md5sig->keys4[md5sig->entries4 - 1].key    = newkey;
-               md5sig->keys4[md5sig->entries4 - 1].keylen = newkeylen;
+               md5sig->keys4[md5sig->entries4 - 1].addr        = addr;
+               md5sig->keys4[md5sig->entries4 - 1].base.key    = newkey;
+               md5sig->keys4[md5sig->entries4 - 1].base.keylen = newkeylen;
        }
        return 0;
 }
@@ -930,7 +929,7 @@ int tcp_v4_md5_do_del(struct sock *sk, __be32 addr)
        for (i = 0; i < tp->md5sig_info->entries4; i++) {
                if (tp->md5sig_info->keys4[i].addr == addr) {
                        /* Free the key */
-                       kfree(tp->md5sig_info->keys4[i].key);
+                       kfree(tp->md5sig_info->keys4[i].base.key);
                        tp->md5sig_info->entries4--;
 
                        if (tp->md5sig_info->entries4 == 0) {
@@ -964,7 +963,7 @@ static void tcp_v4_clear_md5_list(struct sock *sk)
        if (tp->md5sig_info->entries4) {
                int i;
                for (i = 0; i < tp->md5sig_info->entries4; i++)
-                       kfree(tp->md5sig_info->keys4[i].key);
+                       kfree(tp->md5sig_info->keys4[i].base.key);
                tp->md5sig_info->entries4 = 0;
                tcp_free_md5sig_pool();
        }
index 73a894a..5b59665 100644 (file)
@@ -1268,9 +1268,10 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
 
        if (ipv6_addr_equal(dest, target)) {
                on_link = 1;
-       } else if (!(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) {
+       } else if (ipv6_addr_type(target) !=
+                  (IPV6_ADDR_UNICAST|IPV6_ADDR_LINKLOCAL)) {
                ND_PRINTK2(KERN_WARNING
-                          "ICMPv6 Redirect: target address is not link-local.\n");
+                          "ICMPv6 Redirect: target address is not link-local unicast.\n");
                return;
        }
 
@@ -1344,9 +1345,9 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
        }
 
        if (!ipv6_addr_equal(&ipv6_hdr(skb)->daddr, target) &&
-           !(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) {
+           ipv6_addr_type(target) != (IPV6_ADDR_UNICAST|IPV6_ADDR_LINKLOCAL)) {
                ND_PRINTK2(KERN_WARNING
-                       "ICMPv6 Redirect: target address is not link-local.\n");
+                       "ICMPv6 Redirect: target address is not link-local unicast.\n");
                return;
        }
 
index 0f7defb..3e06799 100644 (file)
@@ -539,7 +539,7 @@ static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk,
 
        for (i = 0; i < tp->md5sig_info->entries6; i++) {
                if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, addr) == 0)
-                       return (struct tcp_md5sig_key *)&tp->md5sig_info->keys6[i];
+                       return &tp->md5sig_info->keys6[i].base;
        }
        return NULL;
 }
@@ -567,9 +567,9 @@ static int tcp_v6_md5_do_add(struct sock *sk, struct in6_addr *peer,
        key = (struct tcp6_md5sig_key*) tcp_v6_md5_do_lookup(sk, peer);
        if (key) {
                /* modify existing entry - just update that one */
-               kfree(key->key);
-               key->key = newkey;
-               key->keylen = newkeylen;
+               kfree(key->base.key);
+               key->base.key = newkey;
+               key->base.keylen = newkeylen;
        } else {
                /* reallocate new list if current one is full. */
                if (!tp->md5sig_info) {
@@ -603,8 +603,8 @@ static int tcp_v6_md5_do_add(struct sock *sk, struct in6_addr *peer,
 
                ipv6_addr_copy(&tp->md5sig_info->keys6[tp->md5sig_info->entries6].addr,
                               peer);
-               tp->md5sig_info->keys6[tp->md5sig_info->entries6].key = newkey;
-               tp->md5sig_info->keys6[tp->md5sig_info->entries6].keylen = newkeylen;
+               tp->md5sig_info->keys6[tp->md5sig_info->entries6].base.key = newkey;
+               tp->md5sig_info->keys6[tp->md5sig_info->entries6].base.keylen = newkeylen;
 
                tp->md5sig_info->entries6++;
        }
@@ -626,7 +626,7 @@ static int tcp_v6_md5_do_del(struct sock *sk, struct in6_addr *peer)
        for (i = 0; i < tp->md5sig_info->entries6; i++) {
                if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, peer) == 0) {
                        /* Free the key */
-                       kfree(tp->md5sig_info->keys6[i].key);
+                       kfree(tp->md5sig_info->keys6[i].base.key);
                        tp->md5sig_info->entries6--;
 
                        if (tp->md5sig_info->entries6 == 0) {
@@ -657,7 +657,7 @@ static void tcp_v6_clear_md5_list (struct sock *sk)
 
        if (tp->md5sig_info->entries6) {
                for (i = 0; i < tp->md5sig_info->entries6; i++)
-                       kfree(tp->md5sig_info->keys6[i].key);
+                       kfree(tp->md5sig_info->keys6[i].base.key);
                tp->md5sig_info->entries6 = 0;
                tcp_free_md5sig_pool();
        }
@@ -668,7 +668,7 @@ static void tcp_v6_clear_md5_list (struct sock *sk)
 
        if (tp->md5sig_info->entries4) {
                for (i = 0; i < tp->md5sig_info->entries4; i++)
-                       kfree(tp->md5sig_info->keys4[i].key);
+                       kfree(tp->md5sig_info->keys4[i].base.key);
                tp->md5sig_info->entries4 = 0;
                tcp_free_md5sig_pool();
        }
index cd01642..114df6e 100644 (file)
@@ -79,7 +79,7 @@ static void rose_loopback_timer(unsigned long param)
 
                skb_reset_transport_header(skb);
 
-               sk = rose_find_socket(lci_o, &rose_loopback_neigh);
+               sk = rose_find_socket(lci_o, rose_loopback_neigh);
                if (sk) {
                        if (rose_process_rx_frame(sk, skb) == 0)
                                kfree_skb(skb);
@@ -88,7 +88,7 @@ static void rose_loopback_timer(unsigned long param)
 
                if (frametype == ROSE_CALL_REQUEST) {
                        if ((dev = rose_dev_get(dest)) != NULL) {
-                               if (rose_rx_call_request(skb, dev, &rose_loopback_neigh, lci_o) == 0)
+                               if (rose_rx_call_request(skb, dev, rose_loopback_neigh, lci_o) == 0)
                                        kfree_skb(skb);
                        } else {
                                kfree_skb(skb);
index bbcbad1..96f61a7 100644 (file)
@@ -45,7 +45,7 @@ static DEFINE_SPINLOCK(rose_neigh_list_lock);
 static struct rose_route *rose_route_list;
 static DEFINE_SPINLOCK(rose_route_list_lock);
 
-struct rose_neigh rose_loopback_neigh;
+struct rose_neigh *rose_loopback_neigh;
 
 /*
  *     Add a new route to a node, and in the process add the node and the
@@ -362,7 +362,12 @@ out:
  */
 void rose_add_loopback_neigh(void)
 {
-       struct rose_neigh *sn = &rose_loopback_neigh;
+       struct rose_neigh *sn;
+
+       rose_loopback_neigh = kmalloc(sizeof(struct rose_neigh), GFP_KERNEL);
+       if (!rose_loopback_neigh)
+               return;
+       sn = rose_loopback_neigh;
 
        sn->callsign  = null_ax25_address;
        sn->digipeat  = NULL;
@@ -417,13 +422,13 @@ int rose_add_loopback_node(rose_address *address)
        rose_node->mask         = 10;
        rose_node->count        = 1;
        rose_node->loopback     = 1;
-       rose_node->neighbour[0] = &rose_loopback_neigh;
+       rose_node->neighbour[0] = rose_loopback_neigh;
 
        /* Insert at the head of list. Address is always mask=10 */
        rose_node->next = rose_node_list;
        rose_node_list  = rose_node;
 
-       rose_loopback_neigh.count++;
+       rose_loopback_neigh->count++;
 
 out:
        spin_unlock_bh(&rose_node_list_lock);
@@ -454,7 +459,7 @@ void rose_del_loopback_node(rose_address *address)
 
        rose_remove_node(rose_node);
 
-       rose_loopback_neigh.count--;
+       rose_loopback_neigh->count--;
 
 out:
        spin_unlock_bh(&rose_node_list_lock);
index 8dbe369..d4d5d2f 100644 (file)
@@ -502,7 +502,7 @@ static int u32_set_parms(struct tcf_proto *tp, unsigned long base,
 
 #ifdef CONFIG_NET_CLS_IND
        if (tb[TCA_U32_INDEV-1]) {
-               int err = tcf_change_indev(tp, n->indev, tb[TCA_U32_INDEV-1]);
+               err = tcf_change_indev(tp, n->indev, tb[TCA_U32_INDEV-1]);
                if (err < 0)
                        goto errout;
        }
index 3a23e30..b542c87 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/ipv6.h>
 #include <linux/skbuff.h>
+#include <linux/jhash.h>
 #include <net/ip.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
@@ -95,7 +96,7 @@ struct sfq_sched_data
 
 /* Variables */
        struct timer_list perturb_timer;
-       int             perturbation;
+       u32             perturbation;
        sfq_index       tail;           /* Index of current slot in round */
        sfq_index       max_depth;      /* Maximal depth */
 
@@ -109,12 +110,7 @@ struct sfq_sched_data
 
 static __inline__ unsigned sfq_fold_hash(struct sfq_sched_data *q, u32 h, u32 h1)
 {
-       int pert = q->perturbation;
-
-       /* Have we any rotation primitives? If not, WHY? */
-       h ^= (h1<<pert) ^ (h1>>(0x1F - pert));
-       h ^= h>>10;
-       return h & 0x3FF;
+       return jhash_2words(h, h1, q->perturbation) & (SFQ_HASH_DIVISOR - 1);
 }
 
 static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
@@ -256,6 +252,13 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc* sch)
                q->ht[hash] = x = q->dep[SFQ_DEPTH].next;
                q->hash[x] = hash;
        }
+       /* If selected queue has length q->limit, this means that
+        * all another queues are empty and that we do simple tail drop,
+        * i.e. drop _this_ packet.
+        */
+       if (q->qs[x].qlen >= q->limit)
+               return qdisc_drop(skb, sch);
+
        sch->qstats.backlog += skb->len;
        __skb_queue_tail(&q->qs[x], skb);
        sfq_inc(q, x);
@@ -294,6 +297,19 @@ sfq_requeue(struct sk_buff *skb, struct Qdisc* sch)
        }
        sch->qstats.backlog += skb->len;
        __skb_queue_head(&q->qs[x], skb);
+       /* If selected queue has length q->limit+1, this means that
+        * all another queues are empty and we do simple tail drop.
+        * This packet is still requeued at head of queue, tail packet
+        * is dropped.
+        */
+       if (q->qs[x].qlen > q->limit) {
+               skb = q->qs[x].prev;
+               __skb_unlink(skb, &q->qs[x]);
+               sch->qstats.drops++;
+               sch->qstats.backlog -= skb->len;
+               kfree_skb(skb);
+               return NET_XMIT_CN;
+       }
        sfq_inc(q, x);
        if (q->qs[x].qlen == 1) {               /* The flow is new */
                if (q->tail == SFQ_DEPTH) {     /* It is the first flow */
@@ -370,12 +386,10 @@ static void sfq_perturbation(unsigned long arg)
        struct Qdisc *sch = (struct Qdisc*)arg;
        struct sfq_sched_data *q = qdisc_priv(sch);
 
-       q->perturbation = net_random()&0x1F;
+       get_random_bytes(&q->perturbation, 4);
 
-       if (q->perturb_period) {
-               q->perturb_timer.expires = jiffies + q->perturb_period;
-               add_timer(&q->perturb_timer);
-       }
+       if (q->perturb_period)
+               mod_timer(&q->perturb_timer, jiffies + q->perturb_period);
 }
 
 static int sfq_change(struct Qdisc *sch, struct rtattr *opt)
@@ -391,7 +405,7 @@ static int sfq_change(struct Qdisc *sch, struct rtattr *opt)
        q->quantum = ctl->quantum ? : psched_mtu(sch->dev);
        q->perturb_period = ctl->perturb_period*HZ;
        if (ctl->limit)
-               q->limit = min_t(u32, ctl->limit, SFQ_DEPTH - 2);
+               q->limit = min_t(u32, ctl->limit, SFQ_DEPTH - 1);
 
        qlen = sch->q.qlen;
        while (sch->q.qlen > q->limit)
@@ -400,8 +414,8 @@ static int sfq_change(struct Qdisc *sch, struct rtattr *opt)
 
        del_timer(&q->perturb_timer);
        if (q->perturb_period) {
-               q->perturb_timer.expires = jiffies + q->perturb_period;
-               add_timer(&q->perturb_timer);
+               mod_timer(&q->perturb_timer, jiffies + q->perturb_period);
+               get_random_bytes(&q->perturbation, 4);
        }
        sch_tree_unlock(sch);
        return 0;
@@ -423,12 +437,13 @@ static int sfq_init(struct Qdisc *sch, struct rtattr *opt)
                q->dep[i+SFQ_DEPTH].next = i+SFQ_DEPTH;
                q->dep[i+SFQ_DEPTH].prev = i+SFQ_DEPTH;
        }
-       q->limit = SFQ_DEPTH - 2;
+       q->limit = SFQ_DEPTH - 1;
        q->max_depth = 0;
        q->tail = SFQ_DEPTH;
        if (opt == NULL) {
                q->quantum = psched_mtu(sch->dev);
                q->perturb_period = 0;
+               get_random_bytes(&q->perturbation, 4);
        } else {
                int err = sfq_change(sch, opt);
                if (err)
index 7d44453..b09eb90 100644 (file)
@@ -777,9 +777,6 @@ static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov,
        if (pos != 0)
                return -ESPIPE;
 
-       if (iocb->ki_left == 0) /* Match SYS5 behaviour */
-               return 0;
-
        x = alloc_sock_iocb(iocb, &siocb);
        if (!x)
                return -ENOMEM;