]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 12 Feb 2011 00:29:57 +0000 (16:29 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 12 Feb 2011 00:29:57 +0000 (16:29 -0800)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm:
  dlm: use single thread workqueues

37 files changed:
arch/arm/mach-s5pv310/Kconfig
arch/arm/mach-s5pv310/include/mach/map.h
arch/arm/mach-s5pv310/include/mach/sysmmu.h
arch/arm/plat-s5p/Kconfig
arch/arm/plat-s5p/Makefile
arch/arm/plat-s5p/include/plat/sysmmu.h [deleted file]
arch/arm/plat-s5p/sysmmu.c
arch/arm/plat-samsung/include/plat/pm.h
arch/microblaze/include/asm/irqflags.h
arch/microblaze/include/asm/pgtable.h
arch/microblaze/kernel/cpu/pvr.c
arch/microblaze/kernel/head.S
arch/microblaze/kernel/setup.c
drivers/block/nbd.c
drivers/char/tpm/tpm.c
drivers/char/tpm/tpm.h
drivers/char/tpm/tpm_tis.c
drivers/gpio/pca953x.c
drivers/hwmon/emc1403.c
drivers/hwmon/lm63.c
drivers/pci/pci-sysfs.c
drivers/rtc/rtc-proc.c
drivers/w1/masters/omap_hdq.c
fs/cifs/cifsglob.h
fs/cifs/connect.c
fs/cifs/transport.c
fs/namei.c
fs/open.c
fs/super.c
include/linux/security.h
kernel/capability.c
kernel/ptrace.c
mm/huge_memory.c
mm/memblock.c
mm/memory.c
mm/vmscan.c
security/security.c

index 09c4c21b70cc995623d38a101cb44069ed79e17e..b2a9acc5185fb1f9e056216636e870d815841956 100644 (file)
@@ -122,6 +122,7 @@ config MACH_SMDKV310
        select S3C_DEV_HSMMC2
        select S3C_DEV_HSMMC3
        select S5PV310_DEV_PD
+       select S5PV310_DEV_SYSMMU
        select S5PV310_SETUP_I2C1
        select S5PV310_SETUP_SDHCI
        help
index 74d400625a239258a1a124a929aeb338e197f15f..3060f78e12ab92b24528d6757dc84bef0cf6195a 100644 (file)
 #define S5PV310_PA_SYSMMU_TV           0x12E20000
 #define S5PV310_PA_SYSMMU_MFC_L                0x13620000
 #define S5PV310_PA_SYSMMU_MFC_R                0x13630000
-#define S5PV310_SYSMMU_TOTAL_IPNUM     16
-#define S5P_SYSMMU_TOTAL_IPNUM         S5PV310_SYSMMU_TOTAL_IPNUM
 
 /* compatibiltiy defines. */
 #define S3C_PA_UART                    S5PV310_PA_UART
index 662fe85ff4d57c2b427b61c97890bba098dc27c6..598fc5c9211bcc3d4047ab7eb4623714d7a29f22 100644 (file)
@@ -13,6 +13,9 @@
 #ifndef __ASM_ARM_ARCH_SYSMMU_H
 #define __ASM_ARM_ARCH_SYSMMU_H __FILE__
 
+#define S5PV310_SYSMMU_TOTAL_IPNUM     16
+#define S5P_SYSMMU_TOTAL_IPNUM         S5PV310_SYSMMU_TOTAL_IPNUM
+
 enum s5pv310_sysmmu_ips {
        SYSMMU_MDMA,
        SYSMMU_SSS,
@@ -32,7 +35,7 @@ enum s5pv310_sysmmu_ips {
        SYSMMU_MFC_R,
 };
 
-static char *sysmmu_ips_name[S5P_SYSMMU_TOTAL_IPNUM] = {
+static char *sysmmu_ips_name[S5PV310_SYSMMU_TOTAL_IPNUM] = {
        "SYSMMU_MDMA"   ,
        "SYSMMU_SSS"    ,
        "SYSMMU_FIMC0"  ,
index deb39951a22e8d83c4ca75cf88bf20df7deb6e95..557f8c507f6d44ea0bd23daec5f4752bd140f65e 100644 (file)
@@ -37,6 +37,14 @@ config S5P_GPIO_INT
        help
          Common code for the GPIO interrupts (other than external interrupts.)
 
+comment "System MMU"
+
+config S5P_SYSTEM_MMU
+       bool "S5P SYSTEM MMU"
+       depends on ARCH_S5PV310
+       help
+         Say Y here if you want to enable System MMU
+
 config S5P_DEV_FIMC0
        bool
        help
@@ -66,19 +74,3 @@ config S5P_DEV_CSIS1
        bool
        help
          Compile in platform device definitions for MIPI-CSIS channel 1
-
-menuconfig S5P_SYSMMU
-       bool "SYSMMU support"
-       depends on ARCH_S5PV310
-       help
-         This is a System MMU driver for Samsung ARM based Soc.
-
-if S5P_SYSMMU
-
-config S5P_SYSMMU_DEBUG
-       bool "Enables debug messages"
-       depends on S5P_SYSMMU
-       help
-         This enables SYSMMU driver debug massages.
-
-endif
index 92efe1adcfd61aea04ba449a31ea72b8c35b5676..4bd5cf908977382a8c15562ab1b664cf2edf4a00 100644 (file)
@@ -19,6 +19,7 @@ obj-y                         += clock.o
 obj-y                          += irq.o
 obj-$(CONFIG_S5P_EXT_INT)      += irq-eint.o
 obj-$(CONFIG_S5P_GPIO_INT)     += irq-gpioint.o
+obj-$(CONFIG_S5P_SYSTEM_MMU)   += sysmmu.o
 obj-$(CONFIG_PM)               += pm.o
 obj-$(CONFIG_PM)               += irq-pm.o
 
@@ -30,4 +31,3 @@ obj-$(CONFIG_S5P_DEV_FIMC2)   += dev-fimc2.o
 obj-$(CONFIG_S5P_DEV_ONENAND)  += dev-onenand.o
 obj-$(CONFIG_S5P_DEV_CSIS0)    += dev-csis0.o
 obj-$(CONFIG_S5P_DEV_CSIS1)    += dev-csis1.o
-obj-$(CONFIG_S5P_SYSMMU)       += sysmmu.o
diff --git a/arch/arm/plat-s5p/include/plat/sysmmu.h b/arch/arm/plat-s5p/include/plat/sysmmu.h
deleted file mode 100644 (file)
index db298fc..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/* linux/arch/arm/plat-s5p/include/plat/sysmmu.h
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * Samsung sysmmu driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_PLAT_S5P_SYSMMU_H
-#define __ASM_PLAT_S5P_SYSMMU_H __FILE__
-
-/* debug macro */
-#ifdef CONFIG_S5P_SYSMMU_DEBUG
-#define sysmmu_debug(fmt, arg...)      printk(KERN_INFO "[%s] " fmt, __func__, ## arg)
-#else
-#define sysmmu_debug(fmt, arg...)      do { } while (0)
-#endif
-
-#endif /* __ASM_PLAT_S5P_SYSMMU_H */
index d804914dc2e2671f4fc96714531d94e3786ac8f6..ffe8a48bc3c1f671fb8b461645e07f62c2cd140f 100644 (file)
@@ -16,8 +16,6 @@
 #include <mach/regs-sysmmu.h>
 #include <mach/sysmmu.h>
 
-#include <plat/sysmmu.h>
-
 struct sysmmu_controller s5p_sysmmu_cntlrs[S5P_SYSMMU_TOTAL_IPNUM];
 
 void s5p_sysmmu_register(struct sysmmu_controller *sysmmuconp)
@@ -123,7 +121,7 @@ static int s5p_sysmmu_set_tablebase(sysmmu_ips ips)
                : "=r" (pg) : : "cc");          \
                pg &= ~0x3fff;
 
-       sysmmu_debug("CP15 TTBR0 : 0x%x\n", pg);
+       printk(KERN_INFO "%s: CP15 TTBR0 : 0x%x\n", __func__, pg);
 
        /* Set sysmmu page table base address */
        __raw_writel(pg, sysmmuconp->regs + S5P_PT_BASE_ADDR);
index d9025e377675b6c323d28355b616d0c718cd1c9d..30518cc9a67cf0c6dc130979036637b54da0c513 100644 (file)
@@ -17,6 +17,8 @@
 
 #include <linux/irq.h>
 
+struct sys_device;
+
 #ifdef CONFIG_PM
 
 extern __init int s3c_pm_init(void);
index 5fd31905775d691cb6d4e4fffbb0eeb91ad40013..c4532f032b3b3ad2b082332132a0d90a6ba94868 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/types.h>
 #include <asm/registers.h>
 
-#ifdef CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
 
 static inline unsigned long arch_local_irq_save(void)
 {
index b23f68075879b90e1e2b462e012eefd2777a6cbd..885574a73f01ebc590f76b6daae1449ad6233680 100644 (file)
@@ -411,20 +411,19 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 static inline unsigned long pte_update(pte_t *p, unsigned long clr,
                                unsigned long set)
 {
-       unsigned long old, tmp, msr;
-
-       __asm__ __volatile__("\
-       msrclr  %2, 0x2\n\
-       nop\n\
-       lw      %0, %4, r0\n\
-       andn    %1, %0, %5\n\
-       or      %1, %1, %6\n\
-       sw      %1, %4, r0\n\
-       mts     rmsr, %2\n\
-       nop"
-       : "=&r" (old), "=&r" (tmp), "=&r" (msr), "=m" (*p)
-       : "r" ((unsigned long)(p + 1) - 4), "r" (clr), "r" (set), "m" (*p)
-       : "cc");
+       unsigned long flags, old, tmp;
+
+       raw_local_irq_save(flags);
+
+       __asm__ __volatile__(   "lw     %0, %2, r0      \n"
+                               "andn   %1, %0, %3      \n"
+                               "or     %1, %1, %4      \n"
+                               "sw     %1, %2, r0      \n"
+                       : "=&r" (old), "=&r" (tmp)
+                       : "r" ((unsigned long)(p + 1) - 4), "r" (clr), "r" (set)
+                       : "cc");
+
+       raw_local_irq_restore(flags);
 
        return old;
 }
index e01afa68273ede2302d7cd6da97f0c63430f7eaa..488c1ed24e381ff379c018dd81e8092a904145e7 100644 (file)
@@ -27,7 +27,7 @@
        register unsigned tmp __asm__("r3");                    \
        tmp = 0x0;      /* Prevent warning about unused */      \
        __asm__ __volatile__ (                                  \
-                       "mfs    %0, rpvr" #pvrid ";"    \
+                       "mfs    %0, rpvr" #pvrid ";"            \
                        : "=r" (tmp) : : "memory");             \
        val = tmp;                                              \
 }
@@ -54,7 +54,7 @@ int cpu_has_pvr(void)
        if (!(flags & PVR_MSR_BIT))
                return 0;
 
-       get_single_pvr(0x00, pvr0);
+       get_single_pvr(0, pvr0);
        pr_debug("%s: pvr0 is 0x%08x\n", __func__, pvr0);
 
        if (pvr0 & PVR0_PVR_FULL_MASK)
index 0db20b5abb54e44489362d2bcc53e2600ccb8ad5..778a5ce2e4fc2426ce479def5739401cd32cb8de 100644 (file)
@@ -62,15 +62,14 @@ real_start:
        andi    r1, r1, ~2
        mts     rmsr, r1
 /*
- * Here is checking mechanism which check if Microblaze has msr instructions
- * We load msr and compare it with previous r1 value - if is the same,
- * msr instructions works if not - cpu don't have them.
+ * According to Xilinx, msrclr instruction behaves like 'mfs rX,rpc'
+ * if the msrclr instruction is not enabled. We use this to detect
+ * if the opcode is available, by issuing msrclr and then testing the result.
+ * r8 == 0 - msr instructions are implemented
+ * r8 != 0 - msr instructions are not implemented
  */
-       /* r8=0 - I have msr instr, 1 - I don't have them */
-       rsubi   r0, r0, 1       /* set the carry bit */
-       msrclr  r0, 0x4         /* try to clear it */
-       /* read the carry bit, r8 will be '0' if msrclr exists */
-       addik   r8, r0, 0
+       msrclr  r8, 0 /* clear nothing - just read msr for test */
+       cmpu    r8, r8, r1 /* r1 must contain msr reg content */
 
 /* r7 may point to an FDT, or there may be one linked in.
    if it's in r7, we've got to save it away ASAP.
index bb1558e4b283f0d59f2a00bb2976427c521c845d..9312fbb37efd4868e4c00e9fe69c7b6c03c73557 100644 (file)
@@ -161,11 +161,11 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
 #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
        if (msr)
                eprintk("!!!Your kernel has setup MSR instruction but "
-                               "CPU don't have it %d\n", msr);
+                               "CPU don't have it %x\n", msr);
 #else
        if (!msr)
                eprintk("!!!Your kernel not setup MSR instruction but "
-                               "CPU have it %d\n", msr);
+                               "CPU have it %x\n", msr);
 #endif
 
        for (src = __ivt_start; src < __ivt_end; src++, dst++)
index a32fb41246f883a0a29fecca2cf70d17b0e7bae2..e6fc716aca4521cc7537e09a393b6213b0a3ea88 100644 (file)
@@ -53,7 +53,6 @@
 #define DBG_BLKDEV      0x0100
 #define DBG_RX          0x0200
 #define DBG_TX          0x0400
-static DEFINE_MUTEX(nbd_mutex);
 static unsigned int debugflags;
 #endif /* NDEBUG */
 
@@ -718,11 +717,9 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
        dprintk(DBG_IOCTL, "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n",
                        lo->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg);
 
-       mutex_lock(&nbd_mutex);
        mutex_lock(&lo->tx_lock);
        error = __nbd_ioctl(bdev, lo, cmd, arg);
        mutex_unlock(&lo->tx_lock);
-       mutex_unlock(&nbd_mutex);
 
        return error;
 }
index 36e0fa161c2bf0b46206a6e0af00698935ad158b..faf5a2c659262aeea3d419142b78d32deac721a9 100644 (file)
@@ -577,9 +577,11 @@ duration:
        if (rc)
                return;
 
-       if (be32_to_cpu(tpm_cmd.header.out.return_code)
-           != 3 * sizeof(u32))
+       if (be32_to_cpu(tpm_cmd.header.out.return_code) != 0 ||
+           be32_to_cpu(tpm_cmd.header.out.length)
+           != sizeof(tpm_cmd.header.out) + sizeof(u32) + 3 * sizeof(u32))
                return;
+
        duration_cap = &tpm_cmd.params.getcap_out.cap.duration;
        chip->vendor.duration[TPM_SHORT] =
            usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_short));
@@ -939,6 +941,18 @@ ssize_t tpm_show_caps_1_2(struct device * dev,
 }
 EXPORT_SYMBOL_GPL(tpm_show_caps_1_2);
 
+ssize_t tpm_show_timeouts(struct device *dev, struct device_attribute *attr,
+                         char *buf)
+{
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%d %d %d\n",
+                      jiffies_to_usecs(chip->vendor.duration[TPM_SHORT]),
+                      jiffies_to_usecs(chip->vendor.duration[TPM_MEDIUM]),
+                      jiffies_to_usecs(chip->vendor.duration[TPM_LONG]));
+}
+EXPORT_SYMBOL_GPL(tpm_show_timeouts);
+
 ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
                        const char *buf, size_t count)
 {
index 72ddb031b69a24e425a22d5892283b91f6cc1eec..d84ff772c26f7ccde9fbdcb2720f8c20e025d1ed 100644 (file)
@@ -56,6 +56,8 @@ extern ssize_t tpm_show_owned(struct device *, struct device_attribute *attr,
                                char *);
 extern ssize_t tpm_show_temp_deactivated(struct device *,
                                         struct device_attribute *attr, char *);
+extern ssize_t tpm_show_timeouts(struct device *,
+                                struct device_attribute *attr, char *);
 
 struct tpm_chip;
 
index dd21df55689d96a39d5fea3f66d2161dfec44467..0d1d38e5f266137dc9c426abab641a769f054ddd 100644 (file)
@@ -376,6 +376,7 @@ static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
                   NULL);
 static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL);
 static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
+static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL);
 
 static struct attribute *tis_attrs[] = {
        &dev_attr_pubek.attr,
@@ -385,7 +386,8 @@ static struct attribute *tis_attrs[] = {
        &dev_attr_owned.attr,
        &dev_attr_temp_deactivated.attr,
        &dev_attr_caps.attr,
-       &dev_attr_cancel.attr, NULL,
+       &dev_attr_cancel.attr,
+       &dev_attr_timeouts.attr, NULL,
 };
 
 static struct attribute_group tis_attr_grp = {
index a261972f603d56003d5446eeb1c09511d80b4bf1..b473429eee75157a105c7144bb3cbc9dcd4d2cde 100644 (file)
@@ -60,6 +60,7 @@ struct pca953x_chip {
        unsigned gpio_start;
        uint16_t reg_output;
        uint16_t reg_direction;
+       struct mutex i2c_lock;
 
 #ifdef CONFIG_GPIO_PCA953X_IRQ
        struct mutex irq_lock;
@@ -119,13 +120,17 @@ static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off)
 
        chip = container_of(gc, struct pca953x_chip, gpio_chip);
 
+       mutex_lock(&chip->i2c_lock);
        reg_val = chip->reg_direction | (1u << off);
        ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val);
        if (ret)
-               return ret;
+               goto exit;
 
        chip->reg_direction = reg_val;
-       return 0;
+       ret = 0;
+exit:
+       mutex_unlock(&chip->i2c_lock);
+       return ret;
 }
 
 static int pca953x_gpio_direction_output(struct gpio_chip *gc,
@@ -137,6 +142,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
 
        chip = container_of(gc, struct pca953x_chip, gpio_chip);
 
+       mutex_lock(&chip->i2c_lock);
        /* set output level */
        if (val)
                reg_val = chip->reg_output | (1u << off);
@@ -145,7 +151,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
 
        ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val);
        if (ret)
-               return ret;
+               goto exit;
 
        chip->reg_output = reg_val;
 
@@ -153,10 +159,13 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
        reg_val = chip->reg_direction & ~(1u << off);
        ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val);
        if (ret)
-               return ret;
+               goto exit;
 
        chip->reg_direction = reg_val;
-       return 0;
+       ret = 0;
+exit:
+       mutex_unlock(&chip->i2c_lock);
+       return ret;
 }
 
 static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
@@ -167,7 +176,9 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
 
        chip = container_of(gc, struct pca953x_chip, gpio_chip);
 
+       mutex_lock(&chip->i2c_lock);
        ret = pca953x_read_reg(chip, PCA953X_INPUT, &reg_val);
+       mutex_unlock(&chip->i2c_lock);
        if (ret < 0) {
                /* NOTE:  diagnostic already emitted; that's all we should
                 * do unless gpio_*_value_cansleep() calls become different
@@ -187,6 +198,7 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
 
        chip = container_of(gc, struct pca953x_chip, gpio_chip);
 
+       mutex_lock(&chip->i2c_lock);
        if (val)
                reg_val = chip->reg_output | (1u << off);
        else
@@ -194,9 +206,11 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
 
        ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val);
        if (ret)
-               return;
+               goto exit;
 
        chip->reg_output = reg_val;
+exit:
+       mutex_unlock(&chip->i2c_lock);
 }
 
 static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
@@ -517,6 +531,8 @@ static int __devinit pca953x_probe(struct i2c_client *client,
 
        chip->names = pdata->names;
 
+       mutex_init(&chip->i2c_lock);
+
        /* initialize cached registers from their original values.
         * we can't share this chip with another i2c master.
         */
index 5dea9faa1656804e1be018d396e005b78ad77a02..cd2a6e437aecba36d2fa6f6a7022bfcd40e29d76 100644 (file)
@@ -344,7 +344,7 @@ static int emc1403_remove(struct i2c_client *client)
 }
 
 static const unsigned short emc1403_address_list[] = {
-       0x18, 0x2a, 0x4c, 0x4d, I2C_CLIENT_END
+       0x18, 0x29, 0x4c, 0x4d, I2C_CLIENT_END
 };
 
 static const struct i2c_device_id emc1403_idtable[] = {
index 776aeb3019d2b443a585fb38b96750ca53174099..508cb291f71bfc35681bfda50dbad88a1a8a8dc2 100644 (file)
@@ -98,6 +98,9 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END };
  * value, it uses signed 8-bit values with LSB = 1 degree Celsius.
  * For remote temperature, low and high limits, it uses signed 11-bit values
  * with LSB = 0.125 degree Celsius, left-justified in 16-bit registers.
+ * For LM64 the actual remote diode temperature is 16 degree Celsius higher
+ * than the register reading. Remote temperature setpoints have to be
+ * adapted accordingly.
  */
 
 #define FAN_FROM_REG(reg)      ((reg) == 0xFFFC || (reg) == 0 ? 0 : \
@@ -165,6 +168,8 @@ struct lm63_data {
        struct mutex update_lock;
        char valid; /* zero until following fields are valid */
        unsigned long last_updated; /* in jiffies */
+       int kind;
+       int temp2_offset;
 
        /* registers values */
        u8 config, config_fan;
@@ -247,16 +252,34 @@ static ssize_t show_pwm1_enable(struct device *dev, struct device_attribute *dum
        return sprintf(buf, "%d\n", data->config_fan & 0x20 ? 1 : 2);
 }
 
-static ssize_t show_temp8(struct device *dev, struct device_attribute *devattr,
-                         char *buf)
+/*
+ * There are 8bit registers for both local(temp1) and remote(temp2) sensor.
+ * For remote sensor registers temp2_offset has to be considered,
+ * for local sensor it must not.
+ * So we need separate 8bit accessors for local and remote sensor.
+ */
+static ssize_t show_local_temp8(struct device *dev,
+                               struct device_attribute *devattr,
+                               char *buf)
 {
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
        struct lm63_data *data = lm63_update_device(dev);
        return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[attr->index]));
 }
 
-static ssize_t set_temp8(struct device *dev, struct device_attribute *dummy,
-                        const char *buf, size_t count)
+static ssize_t show_remote_temp8(struct device *dev,
+                                struct device_attribute *devattr,
+                                char *buf)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct lm63_data *data = lm63_update_device(dev);
+       return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[attr->index])
+                      + data->temp2_offset);
+}
+
+static ssize_t set_local_temp8(struct device *dev,
+                              struct device_attribute *dummy,
+                              const char *buf, size_t count)
 {
        struct i2c_client *client = to_i2c_client(dev);
        struct lm63_data *data = i2c_get_clientdata(client);
@@ -274,7 +297,8 @@ static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr,
 {
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
        struct lm63_data *data = lm63_update_device(dev);
-       return sprintf(buf, "%d\n", TEMP11_FROM_REG(data->temp11[attr->index]));
+       return sprintf(buf, "%d\n", TEMP11_FROM_REG(data->temp11[attr->index])
+                      + data->temp2_offset);
 }
 
 static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
@@ -294,7 +318,7 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
        int nr = attr->index;
 
        mutex_lock(&data->update_lock);
-       data->temp11[nr] = TEMP11_TO_REG(val);
+       data->temp11[nr] = TEMP11_TO_REG(val - data->temp2_offset);
        i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2],
                                  data->temp11[nr] >> 8);
        i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1],
@@ -310,6 +334,7 @@ static ssize_t show_temp2_crit_hyst(struct device *dev, struct device_attribute
 {
        struct lm63_data *data = lm63_update_device(dev);
        return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[2])
+                      + data->temp2_offset
                       - TEMP8_FROM_REG(data->temp2_crit_hyst));
 }
 
@@ -324,7 +349,7 @@ static ssize_t set_temp2_crit_hyst(struct device *dev, struct device_attribute *
        long hyst;
 
        mutex_lock(&data->update_lock);
-       hyst = TEMP8_FROM_REG(data->temp8[2]) - val;
+       hyst = TEMP8_FROM_REG(data->temp8[2]) + data->temp2_offset - val;
        i2c_smbus_write_byte_data(client, LM63_REG_REMOTE_TCRIT_HYST,
                                  HYST_TO_REG(hyst));
        mutex_unlock(&data->update_lock);
@@ -355,16 +380,21 @@ static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan,
 static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1);
 static DEVICE_ATTR(pwm1_enable, S_IRUGO, show_pwm1_enable, NULL);
 
-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp8, NULL, 0);
-static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp8,
-       set_temp8, 1);
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_local_temp8, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_local_temp8,
+       set_local_temp8, 1);
 
 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0);
 static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11,
        set_temp11, 1);
 static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11,
        set_temp11, 2);
-static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp8, NULL, 2);
+/*
+ * On LM63, temp2_crit can be set only once, which should be job
+ * of the bootloader.
+ */
+static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_remote_temp8,
+       NULL, 2);
 static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst,
        set_temp2_crit_hyst);
 
@@ -479,7 +509,12 @@ static int lm63_probe(struct i2c_client *new_client,
        data->valid = 0;
        mutex_init(&data->update_lock);
 
-       /* Initialize the LM63 chip */
+       /* Set the device type */
+       data->kind = id->driver_data;
+       if (data->kind == lm64)
+               data->temp2_offset = 16000;
+
+       /* Initialize chip */
        lm63_init_client(new_client);
 
        /* Register sysfs hooks */
index 8ecaac983923d9c6b22c2e0246907db089b5e43a..f7771f336b7d0ccbdb0f5b695ed6f7ae9a6163ab 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/mm.h>
 #include <linux/fs.h>
 #include <linux/capability.h>
+#include <linux/security.h>
 #include <linux/pci-aspm.h>
 #include <linux/slab.h>
 #include "pci.h"
@@ -368,7 +369,7 @@ pci_read_config(struct file *filp, struct kobject *kobj,
        u8 *data = (u8*) buf;
 
        /* Several chips lock up trying to read undefined config space */
-       if (cap_raised(filp->f_cred->cap_effective, CAP_SYS_ADMIN)) {
+       if (security_capable(filp->f_cred, CAP_SYS_ADMIN)) {
                size = dev->cfg_size;
        } else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
                size = 128;
index c086fc30a84c9ad3b4e834559a4d433688758a1a..242bbf86c74a7bbfa9f9e5c8748c41c047a6b1ff 100644 (file)
@@ -81,12 +81,16 @@ static int rtc_proc_show(struct seq_file *seq, void *offset)
 
 static int rtc_proc_open(struct inode *inode, struct file *file)
 {
+       int ret;
        struct rtc_device *rtc = PDE(inode)->data;
 
        if (!try_module_get(THIS_MODULE))
                return -ENODEV;
 
-       return single_open(file, rtc_proc_show, rtc);
+       ret = single_open(file, rtc_proc_show, rtc);
+       if (ret)
+               module_put(THIS_MODULE);
+       return ret;
 }
 
 static int rtc_proc_release(struct inode *inode, struct file *file)
index 3a7e9ff8a7462cd38df8d12cff80ff44ac5d2739..38e96ab90945c8c821e60a18f907dee53a9eddc7 100644 (file)
@@ -593,19 +593,17 @@ static int __devinit omap_hdq_probe(struct platform_device *pdev)
 
        /* get interface & functional clock objects */
        hdq_data->hdq_ick = clk_get(&pdev->dev, "ick");
-       hdq_data->hdq_fck = clk_get(&pdev->dev, "fck");
+       if (IS_ERR(hdq_data->hdq_ick)) {
+               dev_dbg(&pdev->dev, "Can't get HDQ ick clock object\n");
+               ret = PTR_ERR(hdq_data->hdq_ick);
+               goto err_ick;
+       }
 
-       if (IS_ERR(hdq_data->hdq_ick) || IS_ERR(hdq_data->hdq_fck)) {
-               dev_dbg(&pdev->dev, "Can't get HDQ clock objects\n");
-               if (IS_ERR(hdq_data->hdq_ick)) {
-                       ret = PTR_ERR(hdq_data->hdq_ick);
-                       goto err_clk;
-               }
-               if (IS_ERR(hdq_data->hdq_fck)) {
-                       ret = PTR_ERR(hdq_data->hdq_fck);
-                       clk_put(hdq_data->hdq_ick);
-                       goto err_clk;
-               }
+       hdq_data->hdq_fck = clk_get(&pdev->dev, "fck");
+       if (IS_ERR(hdq_data->hdq_fck)) {
+               dev_dbg(&pdev->dev, "Can't get HDQ fck clock object\n");
+               ret = PTR_ERR(hdq_data->hdq_fck);
+               goto err_fck;
        }
 
        hdq_data->hdq_usecount = 0;
@@ -665,10 +663,12 @@ err_fnclk:
        clk_disable(hdq_data->hdq_ick);
 
 err_intfclk:
-       clk_put(hdq_data->hdq_ick);
        clk_put(hdq_data->hdq_fck);
 
-err_clk:
+err_fck:
+       clk_put(hdq_data->hdq_ick);
+
+err_ick:
        iounmap(hdq_data->hdq_base);
 
 err_ioremap:
index edd5b29b53c9a354ac6c0a8d934a793c0221cea0..17afb0fbcaed362b85935d43d12702f8e815efb5 100644 (file)
@@ -188,6 +188,8 @@ struct TCP_Server_Info {
        /* multiplexed reads or writes */
        unsigned int maxBuf;    /* maxBuf specifies the maximum */
        /* message size the server can send or receive for non-raw SMBs */
+       /* maxBuf is returned by SMB NegotiateProtocol so maxBuf is only 0 */
+       /* when socket is setup (and during reconnect) before NegProt sent */
        unsigned int max_rw;    /* maxRw specifies the maximum */
        /* message size the server can send or receive for */
        /* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */
@@ -652,7 +654,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param,
 #define   MID_REQUEST_SUBMITTED 2
 #define   MID_RESPONSE_RECEIVED 4
 #define   MID_RETRY_NEEDED      8 /* session closed while this request out */
-#define   MID_NO_RESP_NEEDED 0x10
+#define   MID_RESPONSE_MALFORMED 0x10
 
 /* Types of response buffer returned from SendReceive2 */
 #define   CIFS_NO_BUFFER        0    /* Response buffer not returned */
index 257b6d895e20d519adcb04ff84de9a3cc5cd93c2..8d6c17ab593dafd9dcb742da7febeaa546ec0c93 100644 (file)
@@ -338,10 +338,11 @@ cifs_echo_request(struct work_struct *work)
                                        struct TCP_Server_Info, echo.work);
 
        /*
-        * We cannot send an echo until the NEGOTIATE_PROTOCOL request is done.
-        * Also, no need to ping if we got a response recently
+        * We cannot send an echo until the NEGOTIATE_PROTOCOL request is
+        * done, which is indicated by maxBuf != 0. Also, no need to ping if
+        * we got a response recently
         */
-       if (server->tcpStatus != CifsGood ||
+       if (server->maxBuf == 0 ||
            time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ))
                goto requeue_echo;
 
@@ -585,11 +586,20 @@ incomplete_rcv:
                total_read += 4; /* account for rfc1002 hdr */
 
                dump_smb(smb_buffer, total_read);
-               if (checkSMB(smb_buffer, smb_buffer->Mid, total_read)) {
+
+               /*
+                * We know that we received enough to get to the MID as we
+                * checked the pdu_length earlier. Now check to see
+                * if the rest of the header is OK. We borrow the length
+                * var for the rest of the loop to avoid a new stack var.
+                *
+                * 48 bytes is enough to display the header and a little bit
+                * into the payload for debugging purposes.
+                */
+               length = checkSMB(smb_buffer, smb_buffer->Mid, total_read);
+               if (length != 0)
                        cifs_dump_mem("Bad SMB: ", smb_buffer,
-                                       total_read < 48 ? total_read : 48);
-                       continue;
-               }
+                                       min_t(unsigned int, total_read, 48));
 
                mid_entry = NULL;
                server->lstrp = jiffies;
@@ -601,7 +611,8 @@ incomplete_rcv:
                        if ((mid_entry->mid == smb_buffer->Mid) &&
                            (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
                            (mid_entry->command == smb_buffer->Command)) {
-                               if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
+                               if (length == 0 &&
+                                  check2ndT2(smb_buffer, server->maxBuf) > 0) {
                                        /* We have a multipart transact2 resp */
                                        isMultiRsp = true;
                                        if (mid_entry->resp_buf) {
@@ -636,7 +647,12 @@ incomplete_rcv:
                                mid_entry->resp_buf = smb_buffer;
                                mid_entry->largeBuf = isLargeBuf;
 multi_t2_fnd:
-                               mid_entry->midState = MID_RESPONSE_RECEIVED;
+                               if (length == 0)
+                                       mid_entry->midState =
+                                                       MID_RESPONSE_RECEIVED;
+                               else
+                                       mid_entry->midState =
+                                                       MID_RESPONSE_MALFORMED;
 #ifdef CONFIG_CIFS_STATS2
                                mid_entry->when_received = jiffies;
 #endif
@@ -657,6 +673,9 @@ multi_t2_fnd:
                                else
                                        smallbuf = NULL;
                        }
+               } else if (length != 0) {
+                       /* response sanity checks failed */
+                       continue;
                } else if (!is_valid_oplock_break(smb_buffer, server) &&
                           !isMultiRsp) {
                        cERROR(1, "No task to wake, unknown frame received! "
index fbc5aace54b18dab347af2f624d0686ca8986c9d..46d8756f2b241673878da87a8c1b905537c4c935 100644 (file)
@@ -457,6 +457,9 @@ sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
        case MID_RETRY_NEEDED:
                rc = -EAGAIN;
                break;
+       case MID_RESPONSE_MALFORMED:
+               rc = -EIO;
+               break;
        default:
                cERROR(1, "%s: invalid mid state mid=%d state=%d", __func__,
                        mid->mid, mid->midState);
index 7d77f24d32a98a115e320605369006eeef30ae0d..ec4b2d0190a8584db09b2252260bd6a8fb8771b2 100644 (file)
@@ -561,10 +561,14 @@ static inline int nameidata_drop_rcu_last_maybe(struct nameidata *nd)
  */
 void release_open_intent(struct nameidata *nd)
 {
-       if (nd->intent.open.file->f_path.dentry == NULL)
-               put_filp(nd->intent.open.file);
-       else
-               fput(nd->intent.open.file);
+       struct file *file = nd->intent.open.file;
+
+       if (file && !IS_ERR(file)) {
+               if (file->f_path.dentry == NULL)
+                       put_filp(file);
+               else
+                       fput(file);
+       }
 }
 
 /*
@@ -2265,8 +2269,6 @@ static struct file *finish_open(struct nameidata *nd,
        return filp;
 
 exit:
-       if (!IS_ERR(nd->intent.open.file))
-               release_open_intent(nd);
        path_put(&nd->path);
        return ERR_PTR(error);
 }
@@ -2389,8 +2391,6 @@ exit_mutex_unlock:
 exit_dput:
        path_put_conditional(path, nd);
 exit:
-       if (!IS_ERR(nd->intent.open.file))
-               release_open_intent(nd);
        path_put(&nd->path);
        return ERR_PTR(error);
 }
@@ -2477,6 +2477,7 @@ struct file *do_filp_open(int dfd, const char *pathname,
        }
        audit_inode(pathname, nd.path.dentry);
        filp = finish_open(&nd, open_flag, acc_mode);
+       release_open_intent(&nd);
        return filp;
 
 creat:
@@ -2553,6 +2554,7 @@ out:
                path_put(&nd.root);
        if (filp == ERR_PTR(-ESTALE) && !(flags & LOOKUP_REVAL))
                goto reval;
+       release_open_intent(&nd);
        return filp;
 
 exit_dput:
@@ -2560,8 +2562,6 @@ exit_dput:
 out_path:
        path_put(&nd.path);
 out_filp:
-       if (!IS_ERR(nd.intent.open.file))
-               release_open_intent(&nd);
        filp = ERR_PTR(error);
        goto out;
 }
index e52389e1f05b4c010b49ef9a6e4d8cb11bfac504..5a2c6ebc22b5d9a1e355050cb14d3218f7a9d0d3 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -790,6 +790,8 @@ struct file *nameidata_to_filp(struct nameidata *nd)
 
        /* Pick up the filp from the open intent */
        filp = nd->intent.open.file;
+       nd->intent.open.file = NULL;
+
        /* Has the filesystem initialised the file for us? */
        if (filp->f_path.dentry == NULL) {
                path_get(&nd->path);
index 74e149efed8194b9ad45b06f654533cd884f0ca1..7e9dd4cc2c01170d0d7a38035a430e554c90cc57 100644 (file)
@@ -177,6 +177,11 @@ void deactivate_locked_super(struct super_block *s)
        struct file_system_type *fs = s->s_type;
        if (atomic_dec_and_test(&s->s_active)) {
                fs->kill_sb(s);
+               /*
+                * We need to call rcu_barrier so all the delayed rcu free
+                * inodes are flushed before we release the fs module.
+                */
+               rcu_barrier();
                put_filesystem(fs);
                put_super(s);
        } else {
index c642bb8b8f5a4894b3878a0977a017b684efefe4..b2b7f9749f5eb2da633264afd7453fe0a6263561 100644 (file)
@@ -1662,7 +1662,7 @@ int security_capset(struct cred *new, const struct cred *old,
                    const kernel_cap_t *effective,
                    const kernel_cap_t *inheritable,
                    const kernel_cap_t *permitted);
-int security_capable(int cap);
+int security_capable(const struct cred *cred, int cap);
 int security_real_capable(struct task_struct *tsk, int cap);
 int security_real_capable_noaudit(struct task_struct *tsk, int cap);
 int security_sysctl(struct ctl_table *table, int op);
@@ -1856,9 +1856,9 @@ static inline int security_capset(struct cred *new,
        return cap_capset(new, old, effective, inheritable, permitted);
 }
 
-static inline int security_capable(int cap)
+static inline int security_capable(const struct cred *cred, int cap)
 {
-       return cap_capable(current, current_cred(), cap, SECURITY_CAP_AUDIT);
+       return cap_capable(current, cred, cap, SECURITY_CAP_AUDIT);
 }
 
 static inline int security_real_capable(struct task_struct *tsk, int cap)
index 2f05303715a5c4066a04b128251ebeec08d3779b..9e9385f132c81759ca2fbe6891d45d25775ff07d 100644 (file)
@@ -306,7 +306,7 @@ int capable(int cap)
                BUG();
        }
 
-       if (security_capable(cap) == 0) {
+       if (security_capable(current_cred(), cap) == 0) {
                current->flags |= PF_SUPERPRIV;
                return 1;
        }
index 99bbaa3e5b0d4332a0d9ff7e1f057dbbecc10a50..1708b1e2972d60df5ad7e461a57b4e8dbf0f103d 100644 (file)
@@ -313,7 +313,7 @@ int ptrace_detach(struct task_struct *child, unsigned int data)
                child->exit_code = data;
                dead = __ptrace_detach(current, child);
                if (!child->exit_state)
-                       wake_up_process(child);
+                       wake_up_state(child, TASK_TRACED | TASK_STOPPED);
        }
        write_unlock_irq(&tasklist_lock);
 
index b6c1ce3c53b548e5a6ffab498889a5c79d1eae69..e62ddb8f24b6ef9287956bbebb4a2d0d12afddce 100644 (file)
@@ -1852,7 +1852,6 @@ static void collapse_huge_page(struct mm_struct *mm,
                set_pmd_at(mm, address, pmd, _pmd);
                spin_unlock(&mm->page_table_lock);
                anon_vma_unlock(vma->anon_vma);
-               mem_cgroup_uncharge_page(new_page);
                goto out;
        }
 
@@ -1898,6 +1897,7 @@ out_up_write:
        return;
 
 out:
+       mem_cgroup_uncharge_page(new_page);
 #ifdef CONFIG_NUMA
        put_page(new_page);
 #endif
index bdba245d8afd9a75babf696030255d2d239e11de..4618fda975a0e1c149b6735d64b6a779cc8c301d 100644 (file)
@@ -137,8 +137,6 @@ static phys_addr_t __init_memblock memblock_find_base(phys_addr_t size,
 
        BUG_ON(0 == size);
 
-       size = memblock_align_up(size, align);
-
        /* Pump up max_addr */
        if (end == MEMBLOCK_ALLOC_ACCESSIBLE)
                end = memblock.current_limit;
index 31250faff39050bd6e45d9ace17cf5e9983ea8f2..8e8c183248631cccce48a97943168d1da5e28223 100644 (file)
@@ -2219,7 +2219,6 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
                                                         &ptl);
                        if (!pte_same(*page_table, orig_pte)) {
                                unlock_page(old_page);
-                               page_cache_release(old_page);
                                goto unlock;
                        }
                        page_cache_release(old_page);
@@ -2289,7 +2288,6 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
                                                         &ptl);
                        if (!pte_same(*page_table, orig_pte)) {
                                unlock_page(old_page);
-                               page_cache_release(old_page);
                                goto unlock;
                        }
 
@@ -2367,16 +2365,6 @@ gotten:
        }
        __SetPageUptodate(new_page);
 
-       /*
-        * Don't let another task, with possibly unlocked vma,
-        * keep the mlocked page.
-        */
-       if ((vma->vm_flags & VM_LOCKED) && old_page) {
-               lock_page(old_page);    /* for LRU manipulation */
-               clear_page_mlock(old_page);
-               unlock_page(old_page);
-       }
-
        if (mem_cgroup_newpage_charge(new_page, mm, GFP_KERNEL))
                goto oom_free_new;
 
@@ -2444,10 +2432,20 @@ gotten:
 
        if (new_page)
                page_cache_release(new_page);
-       if (old_page)
-               page_cache_release(old_page);
 unlock:
        pte_unmap_unlock(page_table, ptl);
+       if (old_page) {
+               /*
+                * Don't let another task, with possibly unlocked vma,
+                * keep the mlocked page.
+                */
+               if ((ret & VM_FAULT_WRITE) && (vma->vm_flags & VM_LOCKED)) {
+                       lock_page(old_page);    /* LRU manipulation */
+                       munlock_vma_page(old_page);
+                       unlock_page(old_page);
+               }
+               page_cache_release(old_page);
+       }
        return ret;
 oom_free_new:
        page_cache_release(new_page);
@@ -3053,12 +3051,6 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
                                goto out;
                        }
                        charged = 1;
-                       /*
-                        * Don't let another task, with possibly unlocked vma,
-                        * keep the mlocked page.
-                        */
-                       if (vma->vm_flags & VM_LOCKED)
-                               clear_page_mlock(vmf.page);
                        copy_user_highpage(page, vmf.page, address, vma);
                        __SetPageUptodate(page);
                } else {
index 148c6e630df2002d8f72b35cca1ed79b7bedb334..17497d0cd8b9e4c95bf5ce39abf1f59d2eb15f2f 100644 (file)
@@ -1882,12 +1882,12 @@ static void shrink_zone(int priority, struct zone *zone,
        unsigned long nr[NR_LRU_LISTS];
        unsigned long nr_to_scan;
        enum lru_list l;
-       unsigned long nr_reclaimed;
+       unsigned long nr_reclaimed, nr_scanned;
        unsigned long nr_to_reclaim = sc->nr_to_reclaim;
-       unsigned long nr_scanned = sc->nr_scanned;
 
 restart:
        nr_reclaimed = 0;
+       nr_scanned = sc->nr_scanned;
        get_scan_count(zone, sc, nr, priority);
 
        while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] ||
index 739e40362f44fab2a8fa4a0f4b1310ec14f8bb65..7b7308ace8c5b1b26bd79369d8c142ea6e14734c 100644 (file)
@@ -154,10 +154,9 @@ int security_capset(struct cred *new, const struct cred *old,
                                    effective, inheritable, permitted);
 }
 
-int security_capable(int cap)
+int security_capable(const struct cred *cred, int cap)
 {
-       return security_ops->capable(current, current_cred(), cap,
-                                    SECURITY_CAP_AUDIT);
+       return security_ops->capable(current, cred, cap, SECURITY_CAP_AUDIT);
 }
 
 int security_real_capable(struct task_struct *tsk, int cap)