Merge branch 'ux500-gpio-pins-for-arm-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson into next/gpio
Linus Walleij <linus.walleij@linaro.org> writes:
This is a pull request for the GPIO and pin control stuff
accumulated in the ST-Ericsson tree. Here we have:
- Improvements and fixes and a custom pin config API from
Rabin Vincent
- Device Tree bindings from Lee Jones
- Some accumulated patches by yours truly.
- A MSP platform data init patch from Ola Lilja that is merged
here due to dependency on pin config work. It is to be
used with work being worked on in parallel in the ALSA
SoC subsystem.
If you wonder about the custom pin config implementation this
is to be used as a transition base as I am rewriting the
driver to use pinctrl. Expect a final pull request on top
of this one that will move the ux500 over to pinctrl.
* 'ux500-gpio-pins-for-arm-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson:
ARM: ux500: Add support for MSP I2S-devices
drivers/gpio: gpio-nomadik: Add support for irqdomains
drivers/gpio: gpio-nomadik: Apply Device Tree bindings
ARM: ux500: update pin handling
ARM: ux500: implement pin API
ARM: ux500: remove a bunch of internal pull-ups
plat-nomadik: new sleep mode pincfg macros
gpio/nomadik: use ioremap() instead of static mappings
gpio/nomadik: support low EMI mode
gpio/nomadik: fix spurious interrupts with SKE
gpio/nomadik: cache [rf]w?imsc
gpio/nomadik: don't set SLPM to 1 for non-wakeup pins
Also includes an update to v3.4-rc4.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
diff --git a/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml b/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml
index 3fd3ce5..5274c24 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml
@@ -1,6 +1,6 @@
<refentry id="V4L2-PIX-FMT-NV12M">
<refmeta>
- <refentrytitle>V4L2_PIX_FMT_NV12M ('NV12M')</refentrytitle>
+ <refentrytitle>V4L2_PIX_FMT_NV12M ('NM12')</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
diff --git a/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml b/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml
index 9957863..60308f1 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml
@@ -1,6 +1,6 @@
<refentry id="V4L2-PIX-FMT-YUV420M">
<refmeta>
- <refentrytitle>V4L2_PIX_FMT_YUV420M ('YU12M')</refentrytitle>
+ <refentrytitle>V4L2_PIX_FMT_YUV420M ('YM12')</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
diff --git a/MAINTAINERS b/MAINTAINERS
index cf900fc..99e1ba8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2321,9 +2321,9 @@
F: drivers/acpi/dock.c
DOCUMENTATION
-M: Randy Dunlap <rdunlap@xenotime.net>
+M: Rob Landley <rob@landley.net>
L: linux-doc@vger.kernel.org
-T: quilt http://xenotime.net/kernel-doc-patches/current/
+T: TBD
S: Maintained
F: Documentation/
diff --git a/Makefile b/Makefile
index f6578f4..afc868e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 3
PATCHLEVEL = 4
SUBLEVEL = 0
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc4
NAME = Saber-toothed Squirrel
# *DOCUMENTATION*
diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig
index b5ac644..6b31cb6 100644
--- a/arch/arm/configs/imx_v4_v5_defconfig
+++ b/arch/arm/configs/imx_v4_v5_defconfig
@@ -112,6 +112,7 @@
CONFIG_IMX2_WDT=y
CONFIG_MFD_MC13XXX=y
CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_MC13783=y
CONFIG_REGULATOR_MC13892=y
CONFIG_FB=y
diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig
index 889d73a..7e84f45 100644
--- a/arch/arm/configs/u8500_defconfig
+++ b/arch/arm/configs/u8500_defconfig
@@ -8,8 +8,6 @@
# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
CONFIG_ARCH_U8500=y
-CONFIG_UX500_SOC_DB5500=y
-CONFIG_UX500_SOC_DB8500=y
CONFIG_MACH_HREFV60=y
CONFIG_MACH_SNOWBALL=y
CONFIG_MACH_U5500=y
@@ -39,7 +37,6 @@
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=65536
-CONFIG_MISC_DEVICES=y
CONFIG_AB8500_PWM=y
CONFIG_SENSORS_BH1780=y
CONFIG_NETDEVICES=y
@@ -65,16 +62,18 @@
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_NOMADIK=y
-CONFIG_I2C=y
-CONFIG_I2C_NOMADIK=y
CONFIG_SPI=y
CONFIG_SPI_PL022=y
CONFIG_GPIO_STMPE=y
CONFIG_GPIO_TC3589X=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_AB8500_BM=y
+CONFIG_AB8500_BATTERY_THERM_ON_BATCTRL=y
CONFIG_MFD_STMPE=y
CONFIG_MFD_TC3589X=y
CONFIG_AB5500_CORE=y
CONFIG_AB8500_CORE=y
+CONFIG_REGULATOR=y
CONFIG_REGULATOR_AB8500=y
# CONFIG_HID_SUPPORT is not set
CONFIG_USB_GADGET=y
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index 99ce5c9..05774e5 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -1173,7 +1173,6 @@
printk(KERN_INFO "AT91: No default serial console defined.\n");
}
#else
-void __init __deprecated at91_init_serial(struct at91_uart_config *config) {}
void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
void __init at91_set_serial_console(unsigned portnr) {}
void __init at91_add_device_serial(void) {}
diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c
index dd7f782..104ca40 100644
--- a/arch/arm/mach-at91/at91rm9200_time.c
+++ b/arch/arm/mach-at91/at91rm9200_time.c
@@ -23,6 +23,7 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/clockchips.h>
+#include <linux/export.h>
#include <asm/mach/time.h>
@@ -176,6 +177,7 @@
};
void __iomem *at91_st_base;
+EXPORT_SYMBOL_GPL(at91_st_base);
void __init at91rm9200_ioremap_st(u32 addr)
{
diff --git a/arch/arm/mach-at91/board-rm9200ek.c b/arch/arm/mach-at91/board-rm9200ek.c
index 11cbaa8..b2e4fe2 100644
--- a/arch/arm/mach-at91/board-rm9200ek.c
+++ b/arch/arm/mach-at91/board-rm9200ek.c
@@ -117,7 +117,7 @@
};
#define EK_FLASH_BASE AT91_CHIPSELECT_0
-#define EK_FLASH_SIZE SZ_2M
+#define EK_FLASH_SIZE SZ_8M
static struct physmap_flash_data ek_flash_data = {
.width = 2,
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
index c3f9944..065fed3 100644
--- a/arch/arm/mach-at91/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -85,8 +85,6 @@
.flags = IORESOURCE_MEM
},
[2] = {
- .start = AT91_PIN_PC11,
- .end = AT91_PIN_PC11,
.flags = IORESOURCE_IRQ
| IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE,
}
@@ -130,6 +128,8 @@
static void __init ek_add_device_dm9000(void)
{
+ struct resource *r = &dm9000_resource[2];
+
/* Configure chip-select 2 (DM9000) */
sam9_smc_configure(0, 2, &dm9000_smc_config);
@@ -139,6 +139,7 @@
/* Configure Interrupt pin as input, no pull-up */
at91_set_gpio_input(AT91_PIN_PC11, 0);
+ r->start = r->end = gpio_to_irq(AT91_PIN_PC11);
platform_device_register(&dm9000_device);
}
#else
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index a0f4d74..6b69282 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -35,6 +35,7 @@
#include "generic.h"
void __iomem *at91_pmc_base;
+EXPORT_SYMBOL_GPL(at91_pmc_base);
/*
* There's a lot more which can be done with clocks, including cpufreq
diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h
index 3660478..ea2c57a 100644
--- a/arch/arm/mach-at91/include/mach/at91_pmc.h
+++ b/arch/arm/mach-at91/include/mach/at91_pmc.h
@@ -25,7 +25,7 @@
#define at91_pmc_write(field, value) \
__raw_writel(value, at91_pmc_base + field)
#else
-.extern at91_aic_base
+.extern at91_pmc_base
#endif
#define AT91_PMC_SCER 0x00 /* System Clock Enable Register */
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
index 97cc04d..f44a2e7 100644
--- a/arch/arm/mach-at91/setup.c
+++ b/arch/arm/mach-at91/setup.c
@@ -54,6 +54,7 @@
}
void __iomem *at91_ramc_base[2];
+EXPORT_SYMBOL_GPL(at91_ramc_base);
void __init at91_ioremap_ramc(int id, u32 addr, u32 size)
{
@@ -292,6 +293,7 @@
}
void __iomem *at91_matrix_base;
+EXPORT_SYMBOL_GPL(at91_matrix_base);
void __init at91_ioremap_matrix(u32 base_addr)
{
diff --git a/arch/arm/mach-bcmring/core.c b/arch/arm/mach-bcmring/core.c
index 22e4e0a..adbfb19 100644
--- a/arch/arm/mach-bcmring/core.c
+++ b/arch/arm/mach-bcmring/core.c
@@ -52,8 +52,8 @@
#include <mach/csp/chipcHw_inline.h>
#include <mach/csp/tmrHw_reg.h>
-static AMBA_APB_DEVICE(uartA, "uarta", MM_ADDR_IO_UARTA, { IRQ_UARTA }, NULL);
-static AMBA_APB_DEVICE(uartB, "uartb", MM_ADDR_IO_UARTB, { IRQ_UARTB }, NULL);
+static AMBA_APB_DEVICE(uartA, "uartA", 0, MM_ADDR_IO_UARTA, {IRQ_UARTA}, NULL);
+static AMBA_APB_DEVICE(uartB, "uartB", 0, MM_ADDR_IO_UARTB, {IRQ_UARTB}, NULL);
static struct clk pll1_clk = {
.name = "PLL1",
diff --git a/arch/arm/mach-imx/imx27-dt.c b/arch/arm/mach-imx/imx27-dt.c
index 861ceb8..ed38d03 100644
--- a/arch/arm/mach-imx/imx27-dt.c
+++ b/arch/arm/mach-imx/imx27-dt.c
@@ -35,7 +35,7 @@
static int __init imx27_avic_add_irq_domain(struct device_node *np,
struct device_node *interrupt_parent)
{
- irq_domain_add_simple(np, 0);
+ irq_domain_add_legacy(np, 64, 0, 0, &irq_domain_simple_ops, NULL);
return 0;
}
@@ -44,7 +44,9 @@
{
static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
- irq_domain_add_simple(np, gpio_irq_base);
+ gpio_irq_base -= 32;
+ irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops,
+ NULL);
return 0;
}
diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c
index 05250ae..e10f391 100644
--- a/arch/arm/mach-imx/mm-imx5.c
+++ b/arch/arm/mach-imx/mm-imx5.c
@@ -35,7 +35,7 @@
}
clk_enable(gpc_dvfs_clk);
mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
- if (tzic_enable_wake() != 0)
+ if (!tzic_enable_wake())
cpu_do_idle();
clk_disable(gpc_dvfs_clk);
}
diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c
index 087dba0..e9cc52d 100644
--- a/arch/arm/mach-omap1/mux.c
+++ b/arch/arm/mach-omap1/mux.c
@@ -27,6 +27,7 @@
#include <linux/io.h>
#include <linux/spinlock.h>
+#include <mach/hardware.h>
#include <plat/mux.h>
diff --git a/arch/arm/mach-omap1/timer.c b/arch/arm/mach-omap1/timer.c
index 6e90665..fb202af 100644
--- a/arch/arm/mach-omap1/timer.c
+++ b/arch/arm/mach-omap1/timer.c
@@ -47,9 +47,9 @@
int n = (pdev->id - 1) << 1;
u32 l;
- l = __raw_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
+ l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
l |= source << n;
- __raw_writel(l, MOD_CONF_CTRL_1);
+ omap_writel(l, MOD_CONF_CTRL_1);
return 0;
}
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index a39fc4b..130ab00 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -20,6 +20,7 @@
#include <linux/usb/otg.h>
#include <linux/spi/spi.h>
#include <linux/i2c/twl.h>
+#include <linux/mfd/twl6040.h>
#include <linux/gpio_keys.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/fixed.h>
@@ -560,7 +561,7 @@
},
};
-static struct twl4030_codec_data twl6040_codec = {
+static struct twl6040_codec_data twl6040_codec = {
/* single-step ramp for headset and handsfree */
.hs_left_step = 0x0f,
.hs_right_step = 0x0f,
@@ -568,7 +569,7 @@
.hf_right_step = 0x1d,
};
-static struct twl4030_vibra_data twl6040_vibra = {
+static struct twl6040_vibra_data twl6040_vibra = {
.vibldrv_res = 8,
.vibrdrv_res = 3,
.viblmotor_res = 10,
@@ -577,16 +578,14 @@
.vddvibr_uV = 0, /* fixed volt supply - VBAT */
};
-static struct twl4030_audio_data twl6040_audio = {
+static struct twl6040_platform_data twl6040_data = {
.codec = &twl6040_codec,
.vibra = &twl6040_vibra,
.audpwron_gpio = 127,
- .naudint_irq = OMAP44XX_IRQ_SYS_2N,
.irq_base = TWL6040_CODEC_IRQ_BASE,
};
static struct twl4030_platform_data sdp4430_twldata = {
- .audio = &twl6040_audio,
/* Regulators */
.vusim = &sdp4430_vusim,
.vaux1 = &sdp4430_vaux1,
@@ -617,7 +616,8 @@
TWL_COMMON_REGULATOR_VCXIO |
TWL_COMMON_REGULATOR_VUSB |
TWL_COMMON_REGULATOR_CLK32KG);
- omap4_pmic_init("twl6030", &sdp4430_twldata);
+ omap4_pmic_init("twl6030", &sdp4430_twldata,
+ &twl6040_data, OMAP44XX_IRQ_SYS_2N);
omap_register_i2c_bus(2, 400, NULL, 0);
omap_register_i2c_bus(3, 400, sdp4430_i2c_3_boardinfo,
ARRAY_SIZE(sdp4430_i2c_3_boardinfo));
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 74e1687..098d183 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -137,7 +137,7 @@
static void __init omap4_i2c_init(void)
{
- omap4_pmic_init("twl6030", &sdp4430_twldata);
+ omap4_pmic_init("twl6030", &sdp4430_twldata, NULL, 0);
}
static void __init omap4_init(void)
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index d8c0e89..1b782ba 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -25,6 +25,7 @@
#include <linux/gpio.h>
#include <linux/usb/otg.h>
#include <linux/i2c/twl.h>
+#include <linux/mfd/twl6040.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/fixed.h>
#include <linux/wl12xx.h>
@@ -284,7 +285,7 @@
return 0;
}
-static struct twl4030_codec_data twl6040_codec = {
+static struct twl6040_codec_data twl6040_codec = {
/* single-step ramp for headset and handsfree */
.hs_left_step = 0x0f,
.hs_right_step = 0x0f,
@@ -292,17 +293,14 @@
.hf_right_step = 0x1d,
};
-static struct twl4030_audio_data twl6040_audio = {
+static struct twl6040_platform_data twl6040_data = {
.codec = &twl6040_codec,
.audpwron_gpio = 127,
- .naudint_irq = OMAP44XX_IRQ_SYS_2N,
.irq_base = TWL6040_CODEC_IRQ_BASE,
};
/* Panda board uses the common PMIC configuration */
-static struct twl4030_platform_data omap4_panda_twldata = {
- .audio = &twl6040_audio,
-};
+static struct twl4030_platform_data omap4_panda_twldata;
/*
* Display monitor features are burnt in their EEPROM as EDID data. The EEPROM
@@ -326,7 +324,8 @@
TWL_COMMON_REGULATOR_VCXIO |
TWL_COMMON_REGULATOR_VUSB |
TWL_COMMON_REGULATOR_CLK32KG);
- omap4_pmic_init("twl6030", &omap4_panda_twldata);
+ omap4_pmic_init("twl6030", &omap4_panda_twldata,
+ &twl6040_data, OMAP44XX_IRQ_SYS_2N);
omap_register_i2c_bus(2, 400, NULL, 0);
/*
* Bus 3 is attached to the DVI port where devices like the pico DLP
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 2c27fdb..7144ae6 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1422,6 +1422,9 @@
goto dis_opt_clks;
_write_sysconfig(v, oh);
+ if (oh->class->sysc->srst_udelay)
+ udelay(oh->class->sysc->srst_udelay);
+
if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
omap_test_timeout((omap_hwmod_read(oh,
oh->class->sysc->syss_offs)
@@ -1903,10 +1906,20 @@
*/
int omap_hwmod_softreset(struct omap_hwmod *oh)
{
- if (!oh)
+ u32 v;
+ int ret;
+
+ if (!oh || !(oh->_sysc_cache))
return -EINVAL;
- return _ocp_softreset(oh);
+ v = oh->_sysc_cache;
+ ret = _set_softreset(oh, &v);
+ if (ret)
+ goto error;
+ _write_sysconfig(v, oh);
+
+error:
+ return ret;
}
/**
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
index a5409ce..a6bde34 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -1000,7 +1000,6 @@
.flags = OMAP_FIREWALL_L4,
}
},
- .flags = OCPIF_SWSUP_IDLE,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
index c4f56cb..04a3885 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -1049,7 +1049,6 @@
.slave = &omap2430_dss_venc_hwmod,
.clk = "dss_ick",
.addr = omap2_dss_venc_addrs,
- .flags = OCPIF_SWSUP_IDLE,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 34b9766d..db86ce9 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -1676,7 +1676,6 @@
.flags = OMAP_FIREWALL_L4,
}
},
- .flags = OCPIF_SWSUP_IDLE,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index cc9bd10..6abc757 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -2594,6 +2594,15 @@
static struct omap_hwmod_class_sysconfig omap44xx_iss_sysc = {
.rev_offs = 0x0000,
.sysc_offs = 0x0010,
+ /*
+ * ISS needs 100 OCP clk cycles delay after a softreset before
+ * accessing sysconfig again.
+ * The lowest frequency at the moment for L3 bus is 100 MHz, so
+ * 1usec delay is needed. Add an x2 margin to be safe (2 usecs).
+ *
+ * TODO: Indicate errata when available.
+ */
+ .srst_udelay = 2,
.sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS |
SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 0cdd359..9fc2f44 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -108,8 +108,14 @@
static void omap_uart_set_smartidle(struct platform_device *pdev)
{
struct omap_device *od = to_omap_device(pdev);
+ u8 idlemode;
- omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_SMART);
+ if (od->hwmods[0]->class->sysc->idlemodes & SIDLE_SMART_WKUP)
+ idlemode = HWMOD_IDLEMODE_SMART_WKUP;
+ else
+ idlemode = HWMOD_IDLEMODE_SMART;
+
+ omap_hwmod_set_slave_idlemode(od->hwmods[0], idlemode);
}
#else
@@ -120,124 +126,8 @@
#endif /* CONFIG_PM */
#ifdef CONFIG_OMAP_MUX
-static struct omap_device_pad default_uart1_pads[] __initdata = {
- {
- .name = "uart1_cts.uart1_cts",
- .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
- },
- {
- .name = "uart1_rts.uart1_rts",
- .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
- },
- {
- .name = "uart1_tx.uart1_tx",
- .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
- },
- {
- .name = "uart1_rx.uart1_rx",
- .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
- .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
- .idle = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
- },
-};
-
-static struct omap_device_pad default_uart2_pads[] __initdata = {
- {
- .name = "uart2_cts.uart2_cts",
- .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
- },
- {
- .name = "uart2_rts.uart2_rts",
- .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
- },
- {
- .name = "uart2_tx.uart2_tx",
- .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
- },
- {
- .name = "uart2_rx.uart2_rx",
- .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
- .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
- .idle = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
- },
-};
-
-static struct omap_device_pad default_uart3_pads[] __initdata = {
- {
- .name = "uart3_cts_rctx.uart3_cts_rctx",
- .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
- },
- {
- .name = "uart3_rts_sd.uart3_rts_sd",
- .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
- },
- {
- .name = "uart3_tx_irtx.uart3_tx_irtx",
- .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
- },
- {
- .name = "uart3_rx_irrx.uart3_rx_irrx",
- .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
- .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
- .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
- },
-};
-
-static struct omap_device_pad default_omap36xx_uart4_pads[] __initdata = {
- {
- .name = "gpmc_wait2.uart4_tx",
- .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
- },
- {
- .name = "gpmc_wait3.uart4_rx",
- .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
- .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE2,
- .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE2,
- },
-};
-
-static struct omap_device_pad default_omap4_uart4_pads[] __initdata = {
- {
- .name = "uart4_tx.uart4_tx",
- .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
- },
- {
- .name = "uart4_rx.uart4_rx",
- .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
- .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
- .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
- },
-};
-
static void omap_serial_fill_default_pads(struct omap_board_data *bdata)
{
- switch (bdata->id) {
- case 0:
- bdata->pads = default_uart1_pads;
- bdata->pads_cnt = ARRAY_SIZE(default_uart1_pads);
- break;
- case 1:
- bdata->pads = default_uart2_pads;
- bdata->pads_cnt = ARRAY_SIZE(default_uart2_pads);
- break;
- case 2:
- bdata->pads = default_uart3_pads;
- bdata->pads_cnt = ARRAY_SIZE(default_uart3_pads);
- break;
- case 3:
- if (cpu_is_omap44xx()) {
- bdata->pads = default_omap4_uart4_pads;
- bdata->pads_cnt =
- ARRAY_SIZE(default_omap4_uart4_pads);
- } else if (cpu_is_omap3630()) {
- bdata->pads = default_omap36xx_uart4_pads;
- bdata->pads_cnt =
- ARRAY_SIZE(default_omap36xx_uart4_pads);
- }
- break;
- default:
- break;
- }
}
#else
static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {}
diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c
index 4b57757..7a7b893 100644
--- a/arch/arm/mach-omap2/twl-common.c
+++ b/arch/arm/mach-omap2/twl-common.c
@@ -37,6 +37,16 @@
.flags = I2C_CLIENT_WAKE,
};
+static struct i2c_board_info __initdata omap4_i2c1_board_info[] = {
+ {
+ .addr = 0x48,
+ .flags = I2C_CLIENT_WAKE,
+ },
+ {
+ I2C_BOARD_INFO("twl6040", 0x4b),
+ },
+};
+
void __init omap_pmic_init(int bus, u32 clkrate,
const char *pmic_type, int pmic_irq,
struct twl4030_platform_data *pmic_data)
@@ -49,14 +59,31 @@
omap_register_i2c_bus(bus, clkrate, &pmic_i2c_board_info, 1);
}
+void __init omap4_pmic_init(const char *pmic_type,
+ struct twl4030_platform_data *pmic_data,
+ struct twl6040_platform_data *twl6040_data, int twl6040_irq)
+{
+ /* PMIC part*/
+ strncpy(omap4_i2c1_board_info[0].type, pmic_type,
+ sizeof(omap4_i2c1_board_info[0].type));
+ omap4_i2c1_board_info[0].irq = OMAP44XX_IRQ_SYS_1N;
+ omap4_i2c1_board_info[0].platform_data = pmic_data;
+
+ /* TWL6040 audio IC part */
+ omap4_i2c1_board_info[1].irq = twl6040_irq;
+ omap4_i2c1_board_info[1].platform_data = twl6040_data;
+
+ omap_register_i2c_bus(1, 400, omap4_i2c1_board_info, 2);
+
+}
+
void __init omap_pmic_late_init(void)
{
/* Init the OMAP TWL parameters (if PMIC has been registerd) */
- if (!pmic_i2c_board_info.irq)
- return;
-
- omap3_twl_init();
- omap4_twl_init();
+ if (pmic_i2c_board_info.irq)
+ omap3_twl_init();
+ if (omap4_i2c1_board_info[0].irq)
+ omap4_twl_init();
}
#if defined(CONFIG_ARCH_OMAP3)
diff --git a/arch/arm/mach-omap2/twl-common.h b/arch/arm/mach-omap2/twl-common.h
index 275dde8..0962748 100644
--- a/arch/arm/mach-omap2/twl-common.h
+++ b/arch/arm/mach-omap2/twl-common.h
@@ -29,6 +29,7 @@
struct twl4030_platform_data;
+struct twl6040_platform_data;
void omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq,
struct twl4030_platform_data *pmic_data);
@@ -46,12 +47,9 @@
omap_pmic_init(1, 2600, pmic_type, INT_34XX_SYS_NIRQ, pmic_data);
}
-static inline void omap4_pmic_init(const char *pmic_type,
- struct twl4030_platform_data *pmic_data)
-{
- /* Phoenix Audio IC needs I2C1 to start with 400 KHz or less */
- omap_pmic_init(1, 400, pmic_type, OMAP44XX_IRQ_SYS_1N, pmic_data);
-}
+void omap4_pmic_init(const char *pmic_type,
+ struct twl4030_platform_data *pmic_data,
+ struct twl6040_platform_data *audio_data, int twl6040_irq);
void omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
u32 pdata_flags, u32 regulators_flags);
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index 880d02e..ef7099e 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -17,6 +17,7 @@
config UX500_SOC_DB8500
bool
select MFD_DB8500_PRCMU
+ select REGULATOR
select REGULATOR_DB8500_PRCMU
select CPU_FREQ_TABLE if CPU_FREQ
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile
index 465b9ec..015932c 100644
--- a/arch/arm/mach-ux500/Makefile
+++ b/arch/arm/mach-ux500/Makefile
@@ -3,7 +3,7 @@
#
obj-y := clock.o cpu.o devices.o devices-common.o \
- id.o usb.o timer.o
+ id.o pins.o usb.o timer.o
obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o
obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o
obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o
@@ -11,7 +11,8 @@
board-mop500-regulators.o \
board-mop500-uib.o board-mop500-stuib.o \
board-mop500-u8500uib.o \
- board-mop500-pins.o
+ board-mop500-pins.o \
+ board-mop500-msp.o
obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/arm/mach-ux500/board-mop500-msp.c b/arch/arm/mach-ux500/board-mop500-msp.c
new file mode 100644
index 0000000..c8f6300
--- /dev/null
+++ b/arch/arm/mach-ux500/board-mop500-msp.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <plat/gpio-nomadik.h>
+
+#include <plat/pincfg.h>
+#include <plat/ste_dma40.h>
+
+#include <mach/devices.h>
+#include <ste-dma40-db8500.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/msp.h>
+
+#include "board-mop500.h"
+#include "devices-db8500.h"
+#include "pins-db8500.h"
+
+/* MSP1/3 Tx/Rx usage protection */
+static DEFINE_SPINLOCK(msp_rxtx_lock);
+
+/* Reference Count */
+static int msp_rxtx_ref;
+
+static pin_cfg_t mop500_msp1_pins_init[] = {
+ GPIO33_MSP1_TXD | PIN_OUTPUT_LOW | PIN_SLPM_WAKEUP_DISABLE,
+ GPIO34_MSP1_TFS | PIN_INPUT_NOPULL | PIN_SLPM_WAKEUP_DISABLE,
+ GPIO35_MSP1_TCK | PIN_INPUT_NOPULL | PIN_SLPM_WAKEUP_DISABLE,
+ GPIO36_MSP1_RXD | PIN_INPUT_NOPULL | PIN_SLPM_WAKEUP_DISABLE,
+};
+
+static pin_cfg_t mop500_msp1_pins_exit[] = {
+ GPIO33_MSP1_TXD | PIN_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE,
+ GPIO34_MSP1_TFS | PIN_INPUT_NOPULL | PIN_SLPM_WAKEUP_ENABLE,
+ GPIO35_MSP1_TCK | PIN_INPUT_NOPULL | PIN_SLPM_WAKEUP_ENABLE,
+ GPIO36_MSP1_RXD | PIN_INPUT_NOPULL | PIN_SLPM_WAKEUP_ENABLE,
+};
+
+int msp13_i2s_init(void)
+{
+ int retval = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&msp_rxtx_lock, flags);
+ if (msp_rxtx_ref == 0)
+ retval = nmk_config_pins(
+ ARRAY_AND_SIZE(mop500_msp1_pins_init));
+ if (!retval)
+ msp_rxtx_ref++;
+ spin_unlock_irqrestore(&msp_rxtx_lock, flags);
+
+ return retval;
+}
+
+int msp13_i2s_exit(void)
+{
+ int retval = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&msp_rxtx_lock, flags);
+ WARN_ON(!msp_rxtx_ref);
+ msp_rxtx_ref--;
+ if (msp_rxtx_ref == 0)
+ retval = nmk_config_pins_sleep(
+ ARRAY_AND_SIZE(mop500_msp1_pins_exit));
+ spin_unlock_irqrestore(&msp_rxtx_lock, flags);
+
+ return retval;
+}
+
+static struct stedma40_chan_cfg msp0_dma_rx = {
+ .high_priority = true,
+ .dir = STEDMA40_PERIPH_TO_MEM,
+
+ .src_dev_type = DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX,
+ .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+
+ .src_info.psize = STEDMA40_PSIZE_LOG_4,
+ .dst_info.psize = STEDMA40_PSIZE_LOG_4,
+
+ /* data_width is set during configuration */
+};
+
+static struct stedma40_chan_cfg msp0_dma_tx = {
+ .high_priority = true,
+ .dir = STEDMA40_MEM_TO_PERIPH,
+
+ .src_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .dst_dev_type = DB8500_DMA_DEV31_MSP0_TX_SLIM0_CH0_TX,
+
+ .src_info.psize = STEDMA40_PSIZE_LOG_4,
+ .dst_info.psize = STEDMA40_PSIZE_LOG_4,
+
+ /* data_width is set during configuration */
+};
+
+static struct msp_i2s_platform_data msp0_platform_data = {
+ .id = MSP_I2S_0,
+ .msp_i2s_dma_rx = &msp0_dma_rx,
+ .msp_i2s_dma_tx = &msp0_dma_tx,
+};
+
+static struct stedma40_chan_cfg msp1_dma_rx = {
+ .high_priority = true,
+ .dir = STEDMA40_PERIPH_TO_MEM,
+
+ .src_dev_type = DB8500_DMA_DEV30_MSP3_RX,
+ .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+
+ .src_info.psize = STEDMA40_PSIZE_LOG_4,
+ .dst_info.psize = STEDMA40_PSIZE_LOG_4,
+
+ /* data_width is set during configuration */
+};
+
+static struct stedma40_chan_cfg msp1_dma_tx = {
+ .high_priority = true,
+ .dir = STEDMA40_MEM_TO_PERIPH,
+
+ .src_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .dst_dev_type = DB8500_DMA_DEV30_MSP1_TX,
+
+ .src_info.psize = STEDMA40_PSIZE_LOG_4,
+ .dst_info.psize = STEDMA40_PSIZE_LOG_4,
+
+ /* data_width is set during configuration */
+};
+
+static struct msp_i2s_platform_data msp1_platform_data = {
+ .id = MSP_I2S_1,
+ .msp_i2s_dma_rx = NULL,
+ .msp_i2s_dma_tx = &msp1_dma_tx,
+ .msp_i2s_init = msp13_i2s_init,
+ .msp_i2s_exit = msp13_i2s_exit,
+};
+
+static struct stedma40_chan_cfg msp2_dma_rx = {
+ .high_priority = true,
+ .dir = STEDMA40_PERIPH_TO_MEM,
+
+ .src_dev_type = DB8500_DMA_DEV14_MSP2_RX,
+ .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+
+ /* MSP2 DMA doesn't work with PSIZE == 4 on DB8500v2 */
+ .src_info.psize = STEDMA40_PSIZE_LOG_1,
+ .dst_info.psize = STEDMA40_PSIZE_LOG_1,
+
+ /* data_width is set during configuration */
+};
+
+static struct stedma40_chan_cfg msp2_dma_tx = {
+ .high_priority = true,
+ .dir = STEDMA40_MEM_TO_PERIPH,
+
+ .src_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .dst_dev_type = DB8500_DMA_DEV14_MSP2_TX,
+
+ .src_info.psize = STEDMA40_PSIZE_LOG_4,
+ .dst_info.psize = STEDMA40_PSIZE_LOG_4,
+
+ .use_fixed_channel = true,
+ .phy_channel = 1,
+
+ /* data_width is set during configuration */
+};
+
+static int db8500_add_msp_i2s(struct device *parent, int id,
+ resource_size_t base, int irq,
+ struct msp_i2s_platform_data *pdata)
+{
+ struct platform_device *pdev;
+ struct resource res[] = {
+ DEFINE_RES_MEM(base, SZ_4K),
+ DEFINE_RES_IRQ(irq),
+ };
+
+ pr_info("Register platform-device 'ux500-msp-i2s', id %d, irq %d\n",
+ id, irq);
+ pdev = platform_device_register_resndata(parent, "ux500-msp-i2s", id,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata));
+ if (!pdev) {
+ pr_err("Failed to register platform-device 'ux500-msp-i2s.%d'!\n",
+ id);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/* Platform device for ASoC U8500 machine */
+static struct platform_device snd_soc_u8500 = {
+ .name = "snd-soc-u8500",
+ .id = 0,
+ .dev = {
+ .platform_data = NULL,
+ },
+};
+
+/* Platform device for Ux500-PCM */
+static struct platform_device ux500_pcm = {
+ .name = "ux500-pcm",
+ .id = 0,
+ .dev = {
+ .platform_data = NULL,
+ },
+};
+
+static struct msp_i2s_platform_data msp2_platform_data = {
+ .id = MSP_I2S_2,
+ .msp_i2s_dma_rx = &msp2_dma_rx,
+ .msp_i2s_dma_tx = &msp2_dma_tx,
+};
+
+static struct msp_i2s_platform_data msp3_platform_data = {
+ .id = MSP_I2S_3,
+ .msp_i2s_dma_rx = &msp1_dma_rx,
+ .msp_i2s_dma_tx = NULL,
+ .msp_i2s_init = msp13_i2s_init,
+ .msp_i2s_exit = msp13_i2s_exit,
+};
+
+int mop500_msp_init(struct device *parent)
+{
+ int ret;
+
+ pr_info("%s: Register platform-device 'snd-soc-u8500'.\n", __func__);
+ platform_device_register(&snd_soc_u8500);
+
+ pr_info("Initialize MSP I2S-devices.\n");
+ ret = db8500_add_msp_i2s(parent, 0, U8500_MSP0_BASE, IRQ_DB8500_MSP0,
+ &msp0_platform_data);
+ ret |= db8500_add_msp_i2s(parent, 1, U8500_MSP1_BASE, IRQ_DB8500_MSP1,
+ &msp1_platform_data);
+ ret |= db8500_add_msp_i2s(parent, 2, U8500_MSP2_BASE, IRQ_DB8500_MSP2,
+ &msp2_platform_data);
+ ret |= db8500_add_msp_i2s(parent, 3, U8500_MSP3_BASE, IRQ_DB8500_MSP1,
+ &msp3_platform_data);
+
+ pr_info("%s: Register platform-device 'ux500-pcm'\n", __func__);
+ platform_device_register(&ux500_pcm);
+
+ return ret;
+}
diff --git a/arch/arm/mach-ux500/board-mop500-msp.h b/arch/arm/mach-ux500/board-mop500-msp.h
new file mode 100644
index 0000000..6fcfb5e
--- /dev/null
+++ b/arch/arm/mach-ux500/board-mop500-msp.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2012
+ *
+ * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
+ * for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+
+void mop500_msp_init(struct device *parent);
diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c
index f5413dc..df5b190 100644
--- a/arch/arm/mach-ux500/board-mop500-pins.c
+++ b/arch/arm/mach-ux500/board-mop500-pins.c
@@ -7,109 +7,47 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/bug.h>
+#include <linux/string.h>
#include <asm/mach-types.h>
#include <plat/pincfg.h>
#include <plat/gpio-nomadik.h>
+
#include <mach/hardware.h>
#include "pins-db8500.h"
+#include "pins.h"
+#include "board-mop500.h"
+
+enum custom_pin_cfg_t {
+ PINS_FOR_DEFAULT,
+ PINS_FOR_U9500,
+};
+
+static enum custom_pin_cfg_t pinsfor;
static pin_cfg_t mop500_pins_common[] = {
- /* I2C */
- GPIO147_I2C0_SCL,
- GPIO148_I2C0_SDA,
- GPIO16_I2C1_SCL,
- GPIO17_I2C1_SDA,
- GPIO10_I2C2_SDA,
- GPIO11_I2C2_SCL,
- GPIO229_I2C3_SDA,
- GPIO230_I2C3_SCL,
-
- /* MSP0 */
+ /* uMSP0 */
GPIO12_MSP0_TXD,
GPIO13_MSP0_TFS,
GPIO14_MSP0_TCK,
GPIO15_MSP0_RXD,
/* MSP2: HDMI */
- GPIO193_MSP2_TXD,
- GPIO194_MSP2_TCK,
- GPIO195_MSP2_TFS,
+ GPIO193_MSP2_TXD | PIN_INPUT_PULLDOWN,
+ GPIO194_MSP2_TCK | PIN_INPUT_PULLDOWN,
+ GPIO195_MSP2_TFS | PIN_INPUT_PULLDOWN,
GPIO196_MSP2_RXD | PIN_OUTPUT_LOW,
+ /* LCD TE0 */
+ GPIO68_LCD_VSI0 | PIN_INPUT_PULLUP,
+
/* Touch screen INTERFACE */
GPIO84_GPIO | PIN_INPUT_PULLUP, /* TOUCH_INT1 */
/* STMPE1601/tc35893 keypad IRQ */
GPIO218_GPIO | PIN_INPUT_PULLUP,
- /* MMC0 (MicroSD card) */
- GPIO18_MC0_CMDDIR | PIN_OUTPUT_HIGH,
- GPIO19_MC0_DAT0DIR | PIN_OUTPUT_HIGH,
- GPIO20_MC0_DAT2DIR | PIN_OUTPUT_HIGH,
-
- GPIO22_MC0_FBCLK | PIN_INPUT_NOPULL,
- GPIO23_MC0_CLK | PIN_OUTPUT_LOW,
- GPIO24_MC0_CMD | PIN_INPUT_PULLUP,
- GPIO25_MC0_DAT0 | PIN_INPUT_PULLUP,
- GPIO26_MC0_DAT1 | PIN_INPUT_PULLUP,
- GPIO27_MC0_DAT2 | PIN_INPUT_PULLUP,
- GPIO28_MC0_DAT3 | PIN_INPUT_PULLUP,
-
- /* SDI1 (SDIO) */
- GPIO208_MC1_CLK | PIN_OUTPUT_LOW,
- GPIO209_MC1_FBCLK | PIN_INPUT_NOPULL,
- GPIO210_MC1_CMD | PIN_INPUT_PULLUP,
- GPIO211_MC1_DAT0 | PIN_INPUT_PULLUP,
- GPIO212_MC1_DAT1 | PIN_INPUT_PULLUP,
- GPIO213_MC1_DAT2 | PIN_INPUT_PULLUP,
- GPIO214_MC1_DAT3 | PIN_INPUT_PULLUP,
-
- /* MMC2 (On-board DATA INTERFACE eMMC) */
- GPIO128_MC2_CLK | PIN_OUTPUT_LOW,
- GPIO129_MC2_CMD | PIN_INPUT_PULLUP,
- GPIO130_MC2_FBCLK | PIN_INPUT_NOPULL,
- GPIO131_MC2_DAT0 | PIN_INPUT_PULLUP,
- GPIO132_MC2_DAT1 | PIN_INPUT_PULLUP,
- GPIO133_MC2_DAT2 | PIN_INPUT_PULLUP,
- GPIO134_MC2_DAT3 | PIN_INPUT_PULLUP,
- GPIO135_MC2_DAT4 | PIN_INPUT_PULLUP,
- GPIO136_MC2_DAT5 | PIN_INPUT_PULLUP,
- GPIO137_MC2_DAT6 | PIN_INPUT_PULLUP,
- GPIO138_MC2_DAT7 | PIN_INPUT_PULLUP,
-
- /* MMC4 (On-board STORAGE INTERFACE eMMC) */
- GPIO197_MC4_DAT3 | PIN_INPUT_PULLUP,
- GPIO198_MC4_DAT2 | PIN_INPUT_PULLUP,
- GPIO199_MC4_DAT1 | PIN_INPUT_PULLUP,
- GPIO200_MC4_DAT0 | PIN_INPUT_PULLUP,
- GPIO201_MC4_CMD | PIN_INPUT_PULLUP,
- GPIO202_MC4_FBCLK | PIN_INPUT_NOPULL,
- GPIO203_MC4_CLK | PIN_OUTPUT_LOW,
- GPIO204_MC4_DAT7 | PIN_INPUT_PULLUP,
- GPIO205_MC4_DAT6 | PIN_INPUT_PULLUP,
- GPIO206_MC4_DAT5 | PIN_INPUT_PULLUP,
- GPIO207_MC4_DAT4 | PIN_INPUT_PULLUP,
-
- /* SKE keypad */
- GPIO153_KP_I7,
- GPIO154_KP_I6,
- GPIO155_KP_I5,
- GPIO156_KP_I4,
- GPIO157_KP_O7,
- GPIO158_KP_O6,
- GPIO159_KP_O5,
- GPIO160_KP_O4,
- GPIO161_KP_I3,
- GPIO162_KP_I2,
- GPIO163_KP_I1,
- GPIO164_KP_I0,
- GPIO165_KP_O3,
- GPIO166_KP_O2,
- GPIO167_KP_O1,
- GPIO168_KP_O0,
-
/* UART */
/* uart-0 pins gpio configuration should be
* kept intact to prevent glitch in tx line
@@ -128,10 +66,6 @@
GPIO30_U2_TXD | PIN_OUTPUT_HIGH,
GPIO31_U2_CTSn | PIN_INPUT_PULLUP,
GPIO32_U2_RTSn | PIN_OUTPUT_HIGH,
-
- /* Display & HDMI HW sync */
- GPIO68_LCD_VSI0 | PIN_INPUT_PULLUP,
- GPIO69_LCD_VSI1 | PIN_INPUT_PULLUP,
};
static pin_cfg_t mop500_pins_default[] = {
@@ -141,10 +75,13 @@
GPIO145_SSP0_RXD | PIN_PULL_DOWN,
GPIO146_SSP0_TXD,
+ /* XENON Flashgun INTERFACE */
+ GPIO6_IP_GPIO0 | PIN_INPUT_PULLUP,/* XENON_FLASH_ID */
+ GPIO7_IP_GPIO1 | PIN_INPUT_PULLUP,/* XENON_READY */
GPIO217_GPIO | PIN_INPUT_PULLUP, /* TC35892 IRQ */
- /* SDI0 (MicroSD card) */
+ /* sdi0 (removable MMC/SD/SDIO cards) not handled by pm_runtime */
GPIO21_MC0_DAT31DIR | PIN_OUTPUT_HIGH,
/* UART */
@@ -156,13 +93,11 @@
static pin_cfg_t hrefv60_pins[] = {
/* WLAN */
- GPIO4_GPIO | PIN_INPUT_PULLUP,/* WLAN_IRQ */
GPIO85_GPIO | PIN_OUTPUT_LOW,/* WLAN_ENA */
/* XENON Flashgun INTERFACE */
GPIO6_IP_GPIO0 | PIN_INPUT_PULLUP,/* XENON_FLASH_ID */
GPIO7_IP_GPIO1 | PIN_INPUT_PULLUP,/* XENON_READY */
- GPIO170_GPIO | PIN_OUTPUT_LOW, /* XENON_CHARGE */
/* Assistant LED INTERFACE */
GPIO21_GPIO | PIN_OUTPUT_LOW, /* XENON_EN1 */
@@ -173,7 +108,7 @@
GPIO32_GPIO | PIN_INPUT_PULLDOWN, /* Magnetometer DRDY */
/* Display Interface */
- GPIO65_GPIO | PIN_OUTPUT_LOW, /* DISP1 RST */
+ GPIO65_GPIO | PIN_OUTPUT_HIGH, /* DISP1 NO RST */
GPIO66_GPIO | PIN_OUTPUT_LOW, /* DISP2 RST */
/* Touch screen INTERFACE */
@@ -215,11 +150,8 @@
/* DiPro Sensor Interface */
GPIO139_GPIO | PIN_INPUT_PULLUP, /* DIPRO_INT */
- /* HAL SWITCH INTERFACE */
- GPIO145_GPIO | PIN_INPUT_PULLDOWN,/* HAL_SW */
-
/* Audio Amplifier Interface */
- GPIO149_GPIO | PIN_OUTPUT_LOW, /* VAUDIO_HF_EN */
+ GPIO149_GPIO | PIN_OUTPUT_HIGH, /* VAUDIO_HF_EN, enable MAX8968 */
/* GBF INTERFACE */
GPIO171_GPIO | PIN_OUTPUT_LOW, /* GBF_ENA_RESET */
@@ -231,10 +163,29 @@
GPIO82_GPIO | PIN_INPUT_PULLUP, /* ACC_INT1 */
GPIO83_GPIO | PIN_INPUT_PULLUP, /* ACC_INT2 */
- /* Proximity Sensor */
- GPIO217_GPIO | PIN_INPUT_PULLUP,
+ /* SD card detect */
+ GPIO95_GPIO | PIN_INPUT_PULLUP,
+};
+static pin_cfg_t u9500_pins[] = {
+ GPIO4_U1_RXD | PIN_INPUT_PULLUP,
+ GPIO5_U1_TXD | PIN_OUTPUT_HIGH,
+ GPIO144_GPIO | PIN_INPUT_PULLUP,/* WLAN_IRQ */
+ /* HSI */
+ GPIO219_HSIR_FLA0 | PIN_INPUT_PULLDOWN,
+ GPIO220_HSIR_DAT0 | PIN_INPUT_PULLDOWN,
+ GPIO221_HSIR_RDY0 | PIN_OUTPUT_LOW,
+ GPIO222_HSIT_FLA0 | PIN_OUTPUT_LOW,
+ GPIO223_HSIT_DAT0 | PIN_OUTPUT_LOW,
+ GPIO224_HSIT_RDY0 | PIN_INPUT_PULLDOWN,
+ GPIO225_HSIT_CAWAKE0 | PIN_INPUT_PULLDOWN, /* CA_WAKE0 */
+ GPIO226_GPIO | PIN_OUTPUT_HIGH, /* AC_WAKE0 */
+};
+
+static pin_cfg_t u8500_pins[] = {
+ GPIO226_GPIO | PIN_OUTPUT_LOW, /* WLAN_PMU_EN */
+ GPIO4_GPIO | PIN_INPUT_PULLUP,/* WLAN_IRQ */
};
static pin_cfg_t snowball_pins[] = {
@@ -275,13 +226,245 @@
/* RSTn_LAN */
GPIO141_GPIO | PIN_OUTPUT_HIGH,
+
+ /* Accelerometer/Magnetometer */
+ GPIO163_GPIO | PIN_INPUT_PULLUP, /* ACCEL_IRQ1 */
+ GPIO164_GPIO | PIN_INPUT_PULLUP, /* ACCEL_IRQ2 */
+ GPIO165_GPIO | PIN_INPUT_PULLUP, /* MAG_DRDY */
+
+ /* WLAN/GBF */
+ GPIO161_GPIO | PIN_OUTPUT_LOW, /* WLAN_PMU_EN */
+ GPIO171_GPIO | PIN_OUTPUT_HIGH,/* GBF_ENA */
+ GPIO215_GPIO | PIN_OUTPUT_LOW,/* WLAN_ENA */
+ GPIO216_GPIO | PIN_INPUT_PULLUP,/* WLAN_IRQ */
};
+/*
+ * I2C
+ */
+
+static UX500_PINS(mop500_pins_i2c0,
+ GPIO147_I2C0_SCL |
+ PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL,
+ GPIO148_I2C0_SDA |
+ PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL,
+);
+
+static UX500_PINS(mop500_pins_i2c1,
+ GPIO16_I2C1_SCL |
+ PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL,
+ GPIO17_I2C1_SDA |
+ PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL,
+);
+
+static UX500_PINS(mop500_pins_i2c2,
+ GPIO10_I2C2_SDA |
+ PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL,
+ GPIO11_I2C2_SCL |
+ PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL,
+);
+
+static UX500_PINS(mop500_pins_i2c3,
+ GPIO229_I2C3_SDA |
+ PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL,
+ GPIO230_I2C3_SCL |
+ PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL,
+);
+
+static UX500_PINS(mop500_pins_mcde_tvout,
+ GPIO78_LCD_D8,
+ GPIO79_LCD_D9,
+ GPIO80_LCD_D10,
+ GPIO81_LCD_D11,
+ GPIO150_LCDA_CLK,
+);
+
+static UX500_PINS(mop500_pins_mcde_hdmi,
+ GPIO69_LCD_VSI1 | PIN_INPUT_PULLUP,
+);
+
+static UX500_PINS(mop500_pins_ske,
+ GPIO153_KP_I7 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP,
+ GPIO154_KP_I6 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP,
+ GPIO155_KP_I5 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP,
+ GPIO156_KP_I4 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP,
+ GPIO161_KP_I3 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP,
+ GPIO162_KP_I2 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP,
+ GPIO163_KP_I1 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP,
+ GPIO164_KP_I0 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP,
+ GPIO157_KP_O7 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW,
+ GPIO158_KP_O6 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW,
+ GPIO159_KP_O5 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW,
+ GPIO160_KP_O4 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW,
+ GPIO165_KP_O3 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW,
+ GPIO166_KP_O2 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW,
+ GPIO167_KP_O1 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW,
+ GPIO168_KP_O0 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW,
+);
+
+/* sdi0 (removable MMC/SD/SDIO cards) */
+static UX500_PINS(mop500_pins_sdi0,
+ GPIO18_MC0_CMDDIR | PIN_OUTPUT_HIGH,
+ GPIO19_MC0_DAT0DIR | PIN_OUTPUT_HIGH,
+ GPIO20_MC0_DAT2DIR | PIN_OUTPUT_HIGH,
+
+ GPIO22_MC0_FBCLK | PIN_INPUT_NOPULL,
+ GPIO23_MC0_CLK | PIN_OUTPUT_LOW,
+ GPIO24_MC0_CMD | PIN_INPUT_PULLUP,
+ GPIO25_MC0_DAT0 | PIN_INPUT_PULLUP,
+ GPIO26_MC0_DAT1 | PIN_INPUT_PULLUP,
+ GPIO27_MC0_DAT2 | PIN_INPUT_PULLUP,
+ GPIO28_MC0_DAT3 | PIN_INPUT_PULLUP,
+);
+
+/* sdi1 (WLAN CW1200) */
+static UX500_PINS(mop500_pins_sdi1,
+ GPIO208_MC1_CLK | PIN_OUTPUT_LOW,
+ GPIO209_MC1_FBCLK | PIN_INPUT_NOPULL,
+ GPIO210_MC1_CMD | PIN_INPUT_PULLUP,
+ GPIO211_MC1_DAT0 | PIN_INPUT_PULLUP,
+ GPIO212_MC1_DAT1 | PIN_INPUT_PULLUP,
+ GPIO213_MC1_DAT2 | PIN_INPUT_PULLUP,
+ GPIO214_MC1_DAT3 | PIN_INPUT_PULLUP,
+);
+
+/* sdi2 (POP eMMC) */
+static UX500_PINS(mop500_pins_sdi2,
+ GPIO128_MC2_CLK | PIN_OUTPUT_LOW,
+ GPIO129_MC2_CMD | PIN_INPUT_PULLUP,
+ GPIO130_MC2_FBCLK | PIN_INPUT_NOPULL,
+ GPIO131_MC2_DAT0 | PIN_INPUT_PULLUP,
+ GPIO132_MC2_DAT1 | PIN_INPUT_PULLUP,
+ GPIO133_MC2_DAT2 | PIN_INPUT_PULLUP,
+ GPIO134_MC2_DAT3 | PIN_INPUT_PULLUP,
+ GPIO135_MC2_DAT4 | PIN_INPUT_PULLUP,
+ GPIO136_MC2_DAT5 | PIN_INPUT_PULLUP,
+ GPIO137_MC2_DAT6 | PIN_INPUT_PULLUP,
+ GPIO138_MC2_DAT7 | PIN_INPUT_PULLUP,
+);
+
+/* sdi4 (PCB eMMC) */
+static UX500_PINS(mop500_pins_sdi4,
+ GPIO197_MC4_DAT3 | PIN_INPUT_PULLUP,
+ GPIO198_MC4_DAT2 | PIN_INPUT_PULLUP,
+ GPIO199_MC4_DAT1 | PIN_INPUT_PULLUP,
+ GPIO200_MC4_DAT0 | PIN_INPUT_PULLUP,
+ GPIO201_MC4_CMD | PIN_INPUT_PULLUP,
+ GPIO202_MC4_FBCLK | PIN_INPUT_NOPULL,
+ GPIO203_MC4_CLK | PIN_OUTPUT_LOW,
+ GPIO204_MC4_DAT7 | PIN_INPUT_PULLUP,
+ GPIO205_MC4_DAT6 | PIN_INPUT_PULLUP,
+ GPIO206_MC4_DAT5 | PIN_INPUT_PULLUP,
+ GPIO207_MC4_DAT4 | PIN_INPUT_PULLUP,
+);
+
+/* USB */
+static UX500_PINS(mop500_pins_usb,
+ GPIO256_USB_NXT,
+ GPIO257_USB_STP | PIN_OUTPUT_HIGH,
+ GPIO258_USB_XCLK,
+ GPIO259_USB_DIR,
+ GPIO260_USB_DAT7,
+ GPIO261_USB_DAT6,
+ GPIO262_USB_DAT5,
+ GPIO263_USB_DAT4,
+ GPIO264_USB_DAT3,
+ GPIO265_USB_DAT2,
+ GPIO266_USB_DAT1,
+ GPIO267_USB_DAT0,
+);
+
+/* SPI2 */
+static UX500_PINS(mop500_pins_spi2,
+ GPIO216_GPIO | PIN_OUTPUT_HIGH,
+ GPIO218_SPI2_RXD | PIN_INPUT_PULLDOWN,
+ GPIO215_SPI2_TXD | PIN_OUTPUT_LOW,
+ GPIO217_SPI2_CLK | PIN_OUTPUT_LOW,
+);
+
+static UX500_PINS(mop500_pins_sensors1p_v60,
+ GPIO217_GPIO| PIN_INPUT_PULLUP |
+ PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL,
+ GPIO145_GPIO | PIN_INPUT_PULLDOWN |
+ PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL,
+ GPIO139_GPIO | PIN_INPUT_PULLUP |
+ PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL,
+);
+
+static UX500_PINS(mop500_pins_sensors1p,
+ PIN_CFG_INPUT(GPIO_PROX_SENSOR, GPIO, NOPULL),
+ PIN_CFG_INPUT(GPIO_HAL_SENSOR, GPIO, NOPULL),
+);
+
+static struct ux500_pin_lookup mop500_runtime_pins[] = {
+ PIN_LOOKUP("mcde-tvout", &mop500_pins_mcde_tvout),
+ PIN_LOOKUP("av8100-hdmi", &mop500_pins_mcde_hdmi),
+ PIN_LOOKUP("nmk-i2c.0", &mop500_pins_i2c0),
+ PIN_LOOKUP("nmk-i2c.1", &mop500_pins_i2c1),
+ PIN_LOOKUP("nmk-i2c.2", &mop500_pins_i2c2),
+ PIN_LOOKUP("nmk-i2c.3", &mop500_pins_i2c3),
+ PIN_LOOKUP("sdi0", &mop500_pins_sdi0),
+ PIN_LOOKUP("sdi1", &mop500_pins_sdi1),
+ PIN_LOOKUP("sdi2", &mop500_pins_sdi2),
+ PIN_LOOKUP("sdi4", &mop500_pins_sdi4),
+ PIN_LOOKUP("musb-ux500.0", &mop500_pins_usb),
+ PIN_LOOKUP("spi2", &mop500_pins_spi2),
+};
+
+static struct ux500_pin_lookup mop500_runtime_pins_v60[] = {
+ PIN_LOOKUP("ske", &mop500_pins_ske),
+ PIN_LOOKUP("gpio-keys.0", &mop500_pins_sensors1p_v60),
+};
+
+static struct ux500_pin_lookup mop500_runtime_pins_pre_v60[] = {
+ PIN_LOOKUP("ske", &mop500_pins_ske),
+ PIN_LOOKUP("gpio-keys.0", &mop500_pins_sensors1p),
+};
+
+/*
+ * passing "pinsfor=" in kernel cmdline allows for custom
+ * configuration of GPIOs on u8500 derived boards.
+ */
+static int __init early_pinsfor(char *p)
+{
+ pinsfor = PINS_FOR_DEFAULT;
+
+ if (strcmp(p, "u9500-21") == 0)
+ pinsfor = PINS_FOR_U9500;
+
+ return 0;
+}
+early_param("pinsfor", early_pinsfor);
+
+int pins_for_u9500(void)
+{
+ if (pinsfor == PINS_FOR_U9500)
+ return 1;
+
+ return 0;
+}
+
void __init mop500_pins_init(void)
{
nmk_config_pins(mop500_pins_common,
ARRAY_SIZE(mop500_pins_common));
+ ux500_pins_add(mop500_runtime_pins, ARRAY_SIZE(mop500_runtime_pins));
+
+ ux500_pins_add(mop500_runtime_pins_pre_v60,
+ ARRAY_SIZE(mop500_runtime_pins_pre_v60));
+
+ switch (pinsfor) {
+ case PINS_FOR_U9500:
+ nmk_config_pins(u9500_pins, ARRAY_SIZE(u9500_pins));
+ break;
+
+ case PINS_FOR_DEFAULT:
+ nmk_config_pins(u8500_pins, ARRAY_SIZE(u8500_pins));
+ default:
+ break;
+ }
+
nmk_config_pins(mop500_pins_default,
ARRAY_SIZE(mop500_pins_default));
}
@@ -291,8 +474,11 @@
nmk_config_pins(mop500_pins_common,
ARRAY_SIZE(mop500_pins_common));
- nmk_config_pins(snowball_pins,
- ARRAY_SIZE(snowball_pins));
+ ux500_pins_add(mop500_runtime_pins, ARRAY_SIZE(mop500_runtime_pins));
+
+ nmk_config_pins(u8500_pins, ARRAY_SIZE(u8500_pins));
+
+ nmk_config_pins(snowball_pins, ARRAY_SIZE(snowball_pins));
}
void __init hrefv60_pins_init(void)
@@ -300,6 +486,22 @@
nmk_config_pins(mop500_pins_common,
ARRAY_SIZE(mop500_pins_common));
+ ux500_pins_add(mop500_runtime_pins, ARRAY_SIZE(mop500_runtime_pins));
+
+ ux500_pins_add(mop500_runtime_pins_v60,
+ ARRAY_SIZE(mop500_runtime_pins_v60));
+
nmk_config_pins(hrefv60_pins,
ARRAY_SIZE(hrefv60_pins));
+
+ switch (pinsfor) {
+ case PINS_FOR_U9500:
+ nmk_config_pins(u9500_pins, ARRAY_SIZE(u9500_pins));
+ break;
+
+ case PINS_FOR_DEFAULT:
+ nmk_config_pins(u8500_pins, ARRAY_SIZE(u8500_pins));
+ default:
+ break;
+ }
}
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index 77d03c1..ca0d625 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -53,6 +53,7 @@
#include "devices-db8500.h"
#include "board-mop500.h"
#include "board-mop500-regulators.h"
+#include "board-mop500-msp.h"
static struct gpio_led snowball_led_array[] = {
{
@@ -631,6 +632,7 @@
mop500_i2c_init(parent);
mop500_sdi_init(parent);
mop500_spi_init(parent);
+ mop500_msp_init(parent);
mop500_uart_init(parent);
i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
@@ -662,6 +664,7 @@
mop500_i2c_init(parent);
snowball_sdi_init(parent);
mop500_spi_init(parent);
+ mop500_msp_init(parent);
mop500_uart_init(parent);
i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
@@ -699,6 +702,7 @@
mop500_i2c_init(parent);
hrefv60_sdi_init(parent);
mop500_spi_init(parent);
+ mop500_msp_init(parent);
mop500_uart_init(parent);
i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
@@ -746,10 +750,22 @@
#ifdef CONFIG_MACH_UX500_DT
struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
+ /* Requires DMA and call-back bindings. */
OF_DEV_AUXDATA("arm,pl011", 0x80120000, "uart0", &uart0_plat),
OF_DEV_AUXDATA("arm,pl011", 0x80121000, "uart1", &uart1_plat),
OF_DEV_AUXDATA("arm,pl011", 0x80007000, "uart2", &uart2_plat),
+ /* Requires DMA bindings. */
OF_DEV_AUXDATA("arm,pl022", 0x80002000, "ssp0", &ssp0_plat),
+ /* Requires clock name bindings. */
+ OF_DEV_AUXDATA("st,nomadik-gpio", 0x8012e000, "gpio.0", NULL),
+ OF_DEV_AUXDATA("st,nomadik-gpio", 0x8012e080, "gpio.1", NULL),
+ OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e000, "gpio.2", NULL),
+ OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e080, "gpio.3", NULL),
+ OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e100, "gpio.4", NULL),
+ OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e180, "gpio.5", NULL),
+ OF_DEV_AUXDATA("st,nomadik-gpio", 0x8011e000, "gpio.6", NULL),
+ OF_DEV_AUXDATA("st,nomadik-gpio", 0x8011e080, "gpio.7", NULL),
+ OF_DEV_AUXDATA("st,nomadik-gpio", 0xa03fe000, "gpio.8", NULL),
{},
};
diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h
index fdcfa87..91dc63f 100644
--- a/arch/arm/mach-ux500/board-mop500.h
+++ b/arch/arm/mach-ux500/board-mop500.h
@@ -7,6 +7,9 @@
#ifndef __BOARD_MOP500_H
#define __BOARD_MOP500_H
+/* For NOMADIK_NR_GPIO */
+#include <mach/irqs.h>
+
/* Snowball specific GPIO assignments, this board has no GPIO expander */
#define SNOWBALL_ACCEL_INT1_GPIO 163
#define SNOWBALL_ACCEL_INT2_GPIO 164
@@ -73,6 +76,7 @@
#define SNOWBALL_PME_ETH_GPIO MOP500_AB8500_PIN_GPIO(24) /* SYSCLKREQ7/GPIO24 */
#define SNOWBALL_EN_3V3_ETH_GPIO MOP500_AB8500_PIN_GPIO(26) /* GPIO26 */
+struct device;
struct i2c_board_info;
extern void mop500_sdi_init(struct device *parent);
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c
index ec35f0a..700042c 100644
--- a/arch/arm/mach-ux500/clock.c
+++ b/arch/arm/mach-ux500/clock.c
@@ -336,6 +336,7 @@
*/
/* Peripheral Cluster #1 */
+static DEFINE_PRCC_CLK(1, msp3, 11, 10, &clk_msp1clk);
static DEFINE_PRCC_CLK(1, i2c4, 10, 9, &clk_i2cclk);
static DEFINE_PRCC_CLK(1, gpio0, 9, -1, NULL);
static DEFINE_PRCC_CLK(1, slimbus0, 8, 8, &clk_slimclk);
@@ -405,7 +406,7 @@
CLK(slimbus0, "slimbus0", NULL),
CLK(i2c2, "nmk-i2c.2", NULL),
CLK(sdi0, "sdi0", NULL),
- CLK(msp0, "msp0", NULL),
+ CLK(msp0, "ux500-msp-i2s.0", NULL),
CLK(i2c1, "nmk-i2c.1", NULL),
CLK(uart1, "uart1", NULL),
CLK(uart0, "uart0", NULL),
@@ -455,7 +456,8 @@
/* Peripheral Cluster #1 */
CLK(i2c4, "nmk-i2c.4", NULL),
CLK(spi3, "spi3", NULL),
- CLK(msp1, "msp1", NULL),
+ CLK(msp1, "ux500-msp-i2s.1", NULL),
+ CLK(msp3, "ux500-msp-i2s.3", NULL),
/* Peripheral Cluster #2 */
CLK(gpio1, "gpio.6", NULL),
@@ -465,7 +467,7 @@
CLK(spi0, "spi0", NULL),
CLK(sdi3, "sdi3", NULL),
CLK(sdi1, "sdi1", NULL),
- CLK(msp2, "msp2", NULL),
+ CLK(msp2, "ux500-msp-i2s.2", NULL),
CLK(sdi4, "sdi4", NULL),
CLK(pwl, "pwl", NULL),
CLK(spi1, "spi1", NULL),
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
index d11f389..f6522f9 100644
--- a/arch/arm/mach-ux500/cpu.c
+++ b/arch/arm/mach-ux500/cpu.c
@@ -30,6 +30,18 @@
void __iomem *_PRCMU_BASE;
+/*
+ * FIXME: Should we set up the GPIO domain here?
+ *
+ * The problem is that we cannot put the interrupt resources into the platform
+ * device until the irqdomain has been added. Right now, we set the GIC interrupt
+ * domain from init_irq(), then load the gpio driver from
+ * core_initcall(nmk_gpio_init) and add the platform devices from
+ * arch_initcall(customize_machine).
+ *
+ * This feels fragile because it depends on the gpio device getting probed
+ * _before_ any device uses the gpio interrupts.
+*/
static const struct of_device_id ux500_dt_irq_match[] = {
{ .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
{},
diff --git a/arch/arm/mach-ux500/devices-db8500.h b/arch/arm/mach-ux500/devices-db8500.h
index 9fd93e9..e22b786 100644
--- a/arch/arm/mach-ux500/devices-db8500.h
+++ b/arch/arm/mach-ux500/devices-db8500.h
@@ -34,7 +34,6 @@
return dbx500_add_amba_device(parent, name, base, irq, pdata, 0);
}
-
#define db8500_add_i2c0(parent, pdata) \
dbx500_add_i2c(parent, 0, U8500_I2C0_BASE, IRQ_DB8500_I2C0, pdata)
#define db8500_add_i2c1(parent, pdata) \
@@ -46,15 +45,6 @@
#define db8500_add_i2c4(parent, pdata) \
dbx500_add_i2c(parent, 4, U8500_I2C4_BASE, IRQ_DB8500_I2C4, pdata)
-#define db8500_add_msp0_i2s(parent, pdata) \
- dbx500_add_msp_i2s(parent, 0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata)
-#define db8500_add_msp1_i2s(parent, pdata) \
- dbx500_add_msp_i2s(parent, 1, U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata)
-#define db8500_add_msp2_i2s(parent, pdata) \
- dbx500_add_msp_i2s(parent, 2, U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata)
-#define db8500_add_msp3_i2s(parent, pdata) \
- dbx500_add_msp_i2s(parent, 3, U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata)
-
#define db8500_add_msp0_spi(parent, pdata) \
dbx500_add_msp_spi(parent, "msp0", U8500_MSP0_BASE, \
IRQ_DB8500_MSP0, pdata)
diff --git a/arch/arm/mach-ux500/include/mach/msp.h b/arch/arm/mach-ux500/include/mach/msp.h
new file mode 100644
index 0000000..798be19
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/msp.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+#ifndef __MSP_H
+#define __MSP_H
+
+#include <plat/ste_dma40.h>
+
+enum msp_i2s_id {
+ MSP_I2S_0 = 0,
+ MSP_I2S_1,
+ MSP_I2S_2,
+ MSP_I2S_3,
+};
+
+/* Platform data structure for a MSP I2S-device */
+struct msp_i2s_platform_data {
+ enum msp_i2s_id id;
+ struct stedma40_chan_cfg *msp_i2s_dma_rx;
+ struct stedma40_chan_cfg *msp_i2s_dma_tx;
+ int (*msp_i2s_init) (void);
+ int (*msp_i2s_exit) (void);
+};
+
+#endif
diff --git a/arch/arm/mach-ux500/pins-db8500.h b/arch/arm/mach-ux500/pins-db8500.h
index 8b1d1a7..062c7ac 100644
--- a/arch/arm/mach-ux500/pins-db8500.h
+++ b/arch/arm/mach-ux500/pins-db8500.h
@@ -35,40 +35,40 @@
#define GPIO4_GPIO PIN_CFG(4, GPIO)
#define GPIO4_U1_RXD PIN_CFG(4, ALT_A)
-#define GPIO4_I2C4_SCL PIN_CFG_INPUT(4, ALT_B, PULLUP)
+#define GPIO4_I2C4_SCL PIN_CFG(4, ALT_B)
#define GPIO4_IP_TRSTn PIN_CFG(4, ALT_C)
#define GPIO5_GPIO PIN_CFG(5, GPIO)
#define GPIO5_U1_TXD PIN_CFG(5, ALT_A)
-#define GPIO5_I2C4_SDA PIN_CFG_INPUT(5, ALT_B, PULLUP)
+#define GPIO5_I2C4_SDA PIN_CFG(5, ALT_B)
#define GPIO5_IP_GPIO6 PIN_CFG(5, ALT_C)
#define GPIO6_GPIO PIN_CFG(6, GPIO)
#define GPIO6_U1_CTSn PIN_CFG(6, ALT_A)
-#define GPIO6_I2C1_SCL PIN_CFG_INPUT(6, ALT_B, PULLUP)
+#define GPIO6_I2C1_SCL PIN_CFG(6, ALT_B)
#define GPIO6_IP_GPIO0 PIN_CFG(6, ALT_C)
#define GPIO7_GPIO PIN_CFG(7, GPIO)
#define GPIO7_U1_RTSn PIN_CFG(7, ALT_A)
-#define GPIO7_I2C1_SDA PIN_CFG_INPUT(7, ALT_B, PULLUP)
+#define GPIO7_I2C1_SDA PIN_CFG(7, ALT_B)
#define GPIO7_IP_GPIO1 PIN_CFG(7, ALT_C)
#define GPIO8_GPIO PIN_CFG(8, GPIO)
-#define GPIO8_IPI2C_SDA PIN_CFG_INPUT(8, ALT_A, PULLUP)
-#define GPIO8_I2C2_SDA PIN_CFG_INPUT(8, ALT_B, PULLUP)
+#define GPIO8_IPI2C_SDA PIN_CFG(8, ALT_A)
+#define GPIO8_I2C2_SDA PIN_CFG(8, ALT_B)
#define GPIO9_GPIO PIN_CFG(9, GPIO)
-#define GPIO9_IPI2C_SCL PIN_CFG_INPUT(9, ALT_A, PULLUP)
-#define GPIO9_I2C2_SCL PIN_CFG_INPUT(9, ALT_B, PULLUP)
+#define GPIO9_IPI2C_SCL PIN_CFG(9, ALT_A)
+#define GPIO9_I2C2_SCL PIN_CFG(9, ALT_B)
#define GPIO10_GPIO PIN_CFG(10, GPIO)
-#define GPIO10_IPI2C_SDA PIN_CFG_INPUT(10, ALT_A, PULLUP)
-#define GPIO10_I2C2_SDA PIN_CFG_INPUT(10, ALT_B, PULLUP)
+#define GPIO10_IPI2C_SDA PIN_CFG(10, ALT_A)
+#define GPIO10_I2C2_SDA PIN_CFG(10, ALT_B)
#define GPIO10_IP_GPIO3 PIN_CFG(10, ALT_C)
#define GPIO11_GPIO PIN_CFG(11, GPIO)
-#define GPIO11_IPI2C_SCL PIN_CFG_INPUT(11, ALT_A, PULLUP)
-#define GPIO11_I2C2_SCL PIN_CFG_INPUT(11, ALT_B, PULLUP)
+#define GPIO11_IPI2C_SCL PIN_CFG(11, ALT_A)
+#define GPIO11_I2C2_SCL PIN_CFG(11, ALT_B)
#define GPIO11_IP_GPIO2 PIN_CFG(11, ALT_C)
#define GPIO12_GPIO PIN_CFG(12, GPIO)
@@ -87,12 +87,12 @@
#define GPIO16_GPIO PIN_CFG(16, GPIO)
#define GPIO16_MSP0_RFS PIN_CFG(16, ALT_A)
-#define GPIO16_I2C1_SCL PIN_CFG_INPUT(16, ALT_B, PULLUP)
+#define GPIO16_I2C1_SCL PIN_CFG(16, ALT_B)
#define GPIO16_SLIM0_DAT PIN_CFG(16, ALT_C)
#define GPIO17_GPIO PIN_CFG(17, GPIO)
#define GPIO17_MSP0_RCK PIN_CFG(17, ALT_A)
-#define GPIO17_I2C1_SDA PIN_CFG_INPUT(17, ALT_B, PULLUP)
+#define GPIO17_I2C1_SDA PIN_CFG(17, ALT_B)
#define GPIO17_SLIM0_CLK PIN_CFG(17, ALT_C)
#define GPIO18_GPIO PIN_CFG(18, GPIO)
@@ -434,10 +434,10 @@
#define GPIO146_SSP0_TXD PIN_CFG(146, ALT_A)
#define GPIO147_GPIO PIN_CFG(147, GPIO)
-#define GPIO147_I2C0_SCL PIN_CFG_INPUT(147, ALT_A, PULLUP)
+#define GPIO147_I2C0_SCL PIN_CFG(147, ALT_A)
#define GPIO148_GPIO PIN_CFG(148, GPIO)
-#define GPIO148_I2C0_SDA PIN_CFG_INPUT(148, ALT_A, PULLUP)
+#define GPIO148_I2C0_SDA PIN_CFG(148, ALT_A)
#define GPIO149_GPIO PIN_CFG(149, GPIO)
#define GPIO149_IP_GPIO0 PIN_CFG(149, ALT_A)
@@ -459,82 +459,82 @@
#define GPIO152_KP_O9 PIN_CFG(152, ALT_C)
#define GPIO153_GPIO PIN_CFG(153, GPIO)
-#define GPIO153_KP_I7 PIN_CFG_INPUT(153, ALT_A, PULLDOWN)
+#define GPIO153_KP_I7 PIN_CFG(153, ALT_A)
#define GPIO153_LCD_D24 PIN_CFG(153, ALT_B)
#define GPIO153_U2_RXD PIN_CFG(153, ALT_C)
#define GPIO154_GPIO PIN_CFG(154, GPIO)
-#define GPIO154_KP_I6 PIN_CFG_INPUT(154, ALT_A, PULLDOWN)
+#define GPIO154_KP_I6 PIN_CFG(154, ALT_A)
#define GPIO154_LCD_D25 PIN_CFG(154, ALT_B)
#define GPIO154_U2_TXD PIN_CFG(154, ALT_C)
#define GPIO155_GPIO PIN_CFG(155, GPIO)
-#define GPIO155_KP_I5 PIN_CFG_INPUT(155, ALT_A, PULLDOWN)
+#define GPIO155_KP_I5 PIN_CFG(155, ALT_A)
#define GPIO155_LCD_D26 PIN_CFG(155, ALT_B)
#define GPIO155_STMAPE_CLK PIN_CFG(155, ALT_C)
#define GPIO156_GPIO PIN_CFG(156, GPIO)
-#define GPIO156_KP_I4 PIN_CFG_INPUT(156, ALT_A, PULLDOWN)
+#define GPIO156_KP_I4 PIN_CFG(156, ALT_A)
#define GPIO156_LCD_D27 PIN_CFG(156, ALT_B)
#define GPIO156_STMAPE_DAT3 PIN_CFG(156, ALT_C)
#define GPIO157_GPIO PIN_CFG(157, GPIO)
-#define GPIO157_KP_O7 PIN_CFG_INPUT(157, ALT_A, PULLUP)
+#define GPIO157_KP_O7 PIN_CFG(157, ALT_A)
#define GPIO157_LCD_D28 PIN_CFG(157, ALT_B)
#define GPIO157_STMAPE_DAT2 PIN_CFG(157, ALT_C)
#define GPIO158_GPIO PIN_CFG(158, GPIO)
-#define GPIO158_KP_O6 PIN_CFG_INPUT(158, ALT_A, PULLUP)
+#define GPIO158_KP_O6 PIN_CFG(158, ALT_A)
#define GPIO158_LCD_D29 PIN_CFG(158, ALT_B)
#define GPIO158_STMAPE_DAT1 PIN_CFG(158, ALT_C)
#define GPIO159_GPIO PIN_CFG(159, GPIO)
-#define GPIO159_KP_O5 PIN_CFG_INPUT(159, ALT_A, PULLUP)
+#define GPIO159_KP_O5 PIN_CFG(159, ALT_A)
#define GPIO159_LCD_D30 PIN_CFG(159, ALT_B)
#define GPIO159_STMAPE_DAT0 PIN_CFG(159, ALT_C)
#define GPIO160_GPIO PIN_CFG(160, GPIO)
-#define GPIO160_KP_O4 PIN_CFG_INPUT(160, ALT_A, PULLUP)
+#define GPIO160_KP_O4 PIN_CFG(160, ALT_A)
#define GPIO160_LCD_D31 PIN_CFG(160, ALT_B)
#define GPIO160_NONE PIN_CFG(160, ALT_C)
#define GPIO161_GPIO PIN_CFG(161, GPIO)
-#define GPIO161_KP_I3 PIN_CFG_INPUT(161, ALT_A, PULLDOWN)
+#define GPIO161_KP_I3 PIN_CFG(161, ALT_A)
#define GPIO161_LCD_D32 PIN_CFG(161, ALT_B)
#define GPIO161_UARTMOD_RXD PIN_CFG(161, ALT_C)
#define GPIO162_GPIO PIN_CFG(162, GPIO)
-#define GPIO162_KP_I2 PIN_CFG_INPUT(162, ALT_A, PULLDOWN)
+#define GPIO162_KP_I2 PIN_CFG(162, ALT_A)
#define GPIO162_LCD_D33 PIN_CFG(162, ALT_B)
#define GPIO162_UARTMOD_TXD PIN_CFG(162, ALT_C)
#define GPIO163_GPIO PIN_CFG(163, GPIO)
-#define GPIO163_KP_I1 PIN_CFG_INPUT(163, ALT_A, PULLDOWN)
+#define GPIO163_KP_I1 PIN_CFG(163, ALT_A)
#define GPIO163_LCD_D34 PIN_CFG(163, ALT_B)
#define GPIO163_STMMOD_CLK PIN_CFG(163, ALT_C)
#define GPIO164_GPIO PIN_CFG(164, GPIO)
-#define GPIO164_KP_I0 PIN_CFG_INPUT(164, ALT_A, PULLUP)
+#define GPIO164_KP_I0 PIN_CFG(164, ALT_A)
#define GPIO164_LCD_D35 PIN_CFG(164, ALT_B)
#define GPIO164_STMMOD_DAT3 PIN_CFG(164, ALT_C)
#define GPIO165_GPIO PIN_CFG(165, GPIO)
-#define GPIO165_KP_O3 PIN_CFG_INPUT(165, ALT_A, PULLUP)
+#define GPIO165_KP_O3 PIN_CFG(165, ALT_A)
#define GPIO165_LCD_D36 PIN_CFG(165, ALT_B)
#define GPIO165_STMMOD_DAT2 PIN_CFG(165, ALT_C)
#define GPIO166_GPIO PIN_CFG(166, GPIO)
-#define GPIO166_KP_O2 PIN_CFG_INPUT(166, ALT_A, PULLUP)
+#define GPIO166_KP_O2 PIN_CFG(166, ALT_A)
#define GPIO166_LCD_D37 PIN_CFG(166, ALT_B)
#define GPIO166_STMMOD_DAT1 PIN_CFG(166, ALT_C)
#define GPIO167_GPIO PIN_CFG(167, GPIO)
-#define GPIO167_KP_O1 PIN_CFG_INPUT(167, ALT_A, PULLUP)
+#define GPIO167_KP_O1 PIN_CFG(167, ALT_A)
#define GPIO167_LCD_D38 PIN_CFG(167, ALT_B)
#define GPIO167_STMMOD_DAT0 PIN_CFG(167, ALT_C)
#define GPIO168_GPIO PIN_CFG(168, GPIO)
-#define GPIO168_KP_O0 PIN_CFG_INPUT(168, ALT_A, PULLUP)
+#define GPIO168_KP_O0 PIN_CFG(168, ALT_A)
#define GPIO168_LCD_D39 PIN_CFG(168, ALT_B)
#define GPIO168_NONE PIN_CFG(168, ALT_C)
@@ -637,7 +637,7 @@
#define GPIO216_GPIO PIN_CFG(216, GPIO)
#define GPIO216_MC1_DAT2DIR PIN_CFG(216, ALT_A)
#define GPIO216_MC3_CMDDIR PIN_CFG(216, ALT_B)
-#define GPIO216_I2C3_SDA PIN_CFG_INPUT(216, ALT_C, PULLUP)
+#define GPIO216_I2C3_SDA PIN_CFG(216, ALT_C)
#define GPIO216_SPI2_FRM PIN_CFG(216, ALT_C)
#define GPIO217_GPIO PIN_CFG(217, GPIO)
@@ -649,7 +649,7 @@
#define GPIO218_GPIO PIN_CFG(218, GPIO)
#define GPIO218_MC1_DAT31DIR PIN_CFG(218, ALT_A)
#define GPIO218_MC3_DAT0DIR PIN_CFG(218, ALT_B)
-#define GPIO218_I2C3_SCL PIN_CFG_INPUT(218, ALT_C, PULLUP)
+#define GPIO218_I2C3_SCL PIN_CFG(218, ALT_C)
#define GPIO218_SPI2_RXD PIN_CFG(218, ALT_C)
#define GPIO219_GPIO PIN_CFG(219, GPIO)
@@ -698,12 +698,12 @@
#define GPIO229_GPIO PIN_CFG(229, GPIO)
#define GPIO229_CLKOUT1 PIN_CFG(229, ALT_A)
#define GPIO229_PWL PIN_CFG(229, ALT_B)
-#define GPIO229_I2C3_SDA PIN_CFG_INPUT(229, ALT_C, PULLUP)
+#define GPIO229_I2C3_SDA PIN_CFG(229, ALT_C)
#define GPIO230_GPIO PIN_CFG(230, GPIO)
#define GPIO230_CLKOUT2 PIN_CFG(230, ALT_A)
#define GPIO230_PWL PIN_CFG(230, ALT_B)
-#define GPIO230_I2C3_SCL PIN_CFG_INPUT(230, ALT_C, PULLUP)
+#define GPIO230_I2C3_SCL PIN_CFG(230, ALT_C)
#define GPIO256_GPIO PIN_CFG(256, GPIO)
#define GPIO256_USB_NXT PIN_CFG(256, ALT_A)
diff --git a/arch/arm/mach-ux500/pins.c b/arch/arm/mach-ux500/pins.c
new file mode 100644
index 0000000..38c1d47
--- /dev/null
+++ b/arch/arm/mach-ux500/pins.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/device.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/err.h>
+#include <plat/pincfg.h>
+
+#include "pins.h"
+
+static LIST_HEAD(pin_lookups);
+static DEFINE_MUTEX(pin_lookups_mutex);
+static DEFINE_SPINLOCK(pins_lock);
+
+void __init ux500_pins_add(struct ux500_pin_lookup *pl, size_t num)
+{
+ mutex_lock(&pin_lookups_mutex);
+
+ while (num--) {
+ list_add_tail(&pl->node, &pin_lookups);
+ pl++;
+ }
+
+ mutex_unlock(&pin_lookups_mutex);
+}
+
+struct ux500_pins *ux500_pins_get(const char *name)
+{
+ struct ux500_pins *pins = NULL;
+ struct ux500_pin_lookup *pl;
+
+ mutex_lock(&pin_lookups_mutex);
+
+ list_for_each_entry(pl, &pin_lookups, node) {
+ if (!strcmp(pl->name, name)) {
+ pins = pl->pins;
+ goto out;
+ }
+ }
+
+out:
+ mutex_unlock(&pin_lookups_mutex);
+ return pins;
+}
+
+int ux500_pins_enable(struct ux500_pins *pins)
+{
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&pins_lock, flags);
+
+ if (pins->usage++ == 0)
+ ret = nmk_config_pins(pins->cfg, pins->num);
+
+ spin_unlock_irqrestore(&pins_lock, flags);
+ return ret;
+}
+
+int ux500_pins_disable(struct ux500_pins *pins)
+{
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&pins_lock, flags);
+
+ if (WARN_ON(pins->usage == 0))
+ goto out;
+
+ if (--pins->usage == 0)
+ ret = nmk_config_pins_sleep(pins->cfg, pins->num);
+
+out:
+ spin_unlock_irqrestore(&pins_lock, flags);
+ return ret;
+}
+
+void ux500_pins_put(struct ux500_pins *pins)
+{
+ WARN_ON(!pins);
+}
diff --git a/arch/arm/mach-ux500/pins.h b/arch/arm/mach-ux500/pins.h
new file mode 100644
index 0000000..0d36af2
--- /dev/null
+++ b/arch/arm/mach-ux500/pins.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#ifndef __MACH_UX500_PINS_H
+#define __MACH_UX500_PINS_H
+
+#include <linux/list.h>
+#include <plat/pincfg.h>
+
+#define PIN_LOOKUP(_name, _pins) \
+{ \
+ .name = _name, \
+ .pins = _pins, \
+}
+
+#define UX500_PINS(name, pins...) \
+struct ux500_pins name = { \
+ .cfg = (pin_cfg_t[]) {pins}, \
+ .num = ARRAY_SIZE(((pin_cfg_t[]) {pins})), \
+}
+
+struct ux500_pins {
+ int usage;
+ int num;
+ pin_cfg_t *cfg;
+};
+
+struct ux500_pin_lookup {
+ struct list_head node;
+ const char *name;
+ struct ux500_pins *pins;
+};
+
+void __init ux500_pins_add(struct ux500_pin_lookup *pl, size_t num);
+void __init ux500_offchip_gpio_init(struct ux500_pins *pins);
+struct ux500_pins *ux500_pins_get(const char *name);
+int ux500_pins_enable(struct ux500_pins *pins);
+int ux500_pins_disable(struct ux500_pins *pins);
+void ux500_pins_put(struct ux500_pins *pins);
+int pins_for_u9500(void);
+
+#endif
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
index d2058ef..eff5842 100644
--- a/arch/arm/mach-ux500/platsmp.c
+++ b/arch/arm/mach-ux500/platsmp.c
@@ -99,7 +99,7 @@
*/
write_pen_release(cpu_logical_map(cpu));
- gic_raise_softirq(cpumask_of(cpu), 1);
+ smp_send_reschedule(cpu);
timeout = jiffies + (1 * HZ);
while (time_before(jiffies, timeout)) {
diff --git a/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h b/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h
index 9605bf2..3e8b7f1 100644
--- a/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h
+++ b/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h
@@ -29,6 +29,7 @@
#define NMK_GPIO_SLPC 0x1c
#define NMK_GPIO_AFSLA 0x20
#define NMK_GPIO_AFSLB 0x24
+#define NMK_GPIO_LOWEMI 0x28
#define NMK_GPIO_RIMSC 0x40
#define NMK_GPIO_FIMSC 0x44
diff --git a/arch/arm/plat-nomadik/include/plat/pincfg.h b/arch/arm/plat-nomadik/include/plat/pincfg.h
index 22cb97d..c015133 100644
--- a/arch/arm/plat-nomadik/include/plat/pincfg.h
+++ b/arch/arm/plat-nomadik/include/plat/pincfg.h
@@ -24,6 +24,7 @@
* bit 16..18 - SLPM pull up/down state
* bit 19..20 - SLPM direction
* bit 21..22 - SLPM Value (if output)
+ * bit 23..25 - PDIS value (if input)
*
* to facilitate the definition, the following macros are provided
*
@@ -67,6 +68,10 @@
/* These two replace the above in DB8500v2+ */
#define PIN_SLPM_WAKEUP_ENABLE (NMK_GPIO_SLPM_WAKEUP_ENABLE << PIN_SLPM_SHIFT)
#define PIN_SLPM_WAKEUP_DISABLE (NMK_GPIO_SLPM_WAKEUP_DISABLE << PIN_SLPM_SHIFT)
+#define PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP PIN_SLPM_WAKEUP_DISABLE
+
+#define PIN_SLPM_GPIO PIN_SLPM_WAKEUP_ENABLE /* In SLPM, pin is a gpio */
+#define PIN_SLPM_ALTFUNC PIN_SLPM_WAKEUP_DISABLE /* In SLPM, pin is altfunc */
#define PIN_DIR_SHIFT 14
#define PIN_DIR_MASK (0x1 << PIN_DIR_SHIFT)
@@ -105,6 +110,20 @@
#define PIN_SLPM_VAL_LOW ((1 + 0) << PIN_SLPM_VAL_SHIFT)
#define PIN_SLPM_VAL_HIGH ((1 + 1) << PIN_SLPM_VAL_SHIFT)
+#define PIN_SLPM_PDIS_SHIFT 23
+#define PIN_SLPM_PDIS_MASK (0x3 << PIN_SLPM_PDIS_SHIFT)
+#define PIN_SLPM_PDIS(x) \
+ (((x) & PIN_SLPM_PDIS_MASK) >> PIN_SLPM_PDIS_SHIFT)
+#define PIN_SLPM_PDIS_NO_CHANGE (0 << PIN_SLPM_PDIS_SHIFT)
+#define PIN_SLPM_PDIS_DISABLED (1 << PIN_SLPM_PDIS_SHIFT)
+#define PIN_SLPM_PDIS_ENABLED (2 << PIN_SLPM_PDIS_SHIFT)
+
+#define PIN_LOWEMI_SHIFT 25
+#define PIN_LOWEMI_MASK (0x1 << PIN_LOWEMI_SHIFT)
+#define PIN_LOWEMI(x) (((x) & PIN_LOWEMI_MASK) >> PIN_LOWEMI_SHIFT)
+#define PIN_LOWEMI_DISABLED (0 << PIN_LOWEMI_SHIFT)
+#define PIN_LOWEMI_ENABLED (1 << PIN_LOWEMI_SHIFT)
+
/* Shortcuts. Use these instead of separate DIR, PULL, and VAL. */
#define PIN_INPUT_PULLDOWN (PIN_DIR_INPUT | PIN_PULL_DOWN)
#define PIN_INPUT_PULLUP (PIN_DIR_INPUT | PIN_PULL_UP)
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 8070145..3f26db4 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -305,6 +305,7 @@
* @rev_offs: IP block revision register offset (from module base addr)
* @sysc_offs: OCP_SYSCONFIG register offset (from module base addr)
* @syss_offs: OCP_SYSSTATUS register offset (from module base addr)
+ * @srst_udelay: Delay needed after doing a softreset in usecs
* @idlemodes: One or more of {SIDLE,MSTANDBY}_{OFF,FORCE,SMART}
* @sysc_flags: SYS{C,S}_HAS* flags indicating SYSCONFIG bits supported
* @clockact: the default value of the module CLOCKACTIVITY bits
@@ -330,9 +331,10 @@
u16 sysc_offs;
u16 syss_offs;
u16 sysc_flags;
+ struct omap_hwmod_sysc_fields *sysc_fields;
+ u8 srst_udelay;
u8 idlemodes;
u8 clockact;
- struct omap_hwmod_sysc_fields *sysc_fields;
};
/**
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index eec98af..f9a8c53 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -348,7 +348,6 @@
sdrc_actim_ctrl_b_1, sdrc_mr_1);
}
-#ifdef CONFIG_PM
void omap3_sram_restore_context(void)
{
omap_sram_ceil = omap_sram_base + omap_sram_size;
@@ -358,17 +357,18 @@
omap3_sram_configure_core_dpll_sz);
omap_push_sram_idle();
}
-#endif /* CONFIG_PM */
-
-#endif /* CONFIG_ARCH_OMAP3 */
static inline int omap34xx_sram_init(void)
{
-#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
omap3_sram_restore_context();
-#endif
return 0;
}
+#else
+static inline int omap34xx_sram_init(void)
+{
+ return 0;
+}
+#endif /* CONFIG_ARCH_OMAP3 */
static inline int am33xx_sram_init(void)
{
diff --git a/arch/ia64/include/asm/futex.h b/arch/ia64/include/asm/futex.h
index 0ab82cc..d2bf1fd 100644
--- a/arch/ia64/include/asm/futex.h
+++ b/arch/ia64/include/asm/futex.h
@@ -106,15 +106,16 @@
return -EFAULT;
{
- register unsigned long r8 __asm ("r8") = 0;
+ register unsigned long r8 __asm ("r8");
unsigned long prev;
__asm__ __volatile__(
" mf;; \n"
- " mov ar.ccv=%3;; \n"
- "[1:] cmpxchg4.acq %0=[%1],%2,ar.ccv \n"
+ " mov %0=r0 \n"
+ " mov ar.ccv=%4;; \n"
+ "[1:] cmpxchg4.acq %1=[%2],%3,ar.ccv \n"
" .xdata4 \"__ex_table\", 1b-., 2f-. \n"
"[2:]"
- : "=r" (prev)
+ : "=r" (r8), "=r" (prev)
: "r" (uaddr), "r" (newval),
"rO" ((long) (unsigned) oldval)
: "memory");
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 9d0fd7d..f00ba02 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -604,12 +604,6 @@
spin_unlock(&(x)->ctx_lock);
}
-static inline unsigned int
-pfm_do_munmap(struct mm_struct *mm, unsigned long addr, size_t len, int acct)
-{
- return do_munmap(mm, addr, len);
-}
-
static inline unsigned long
pfm_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, unsigned long exec)
{
@@ -1458,8 +1452,9 @@
* a PROTECT_CTX() section.
*/
static int
-pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long size)
+pfm_remove_smpl_mapping(void *vaddr, unsigned long size)
{
+ struct task_struct *task = current;
int r;
/* sanity checks */
@@ -1473,13 +1468,8 @@
/*
* does the actual unmapping
*/
- down_write(&task->mm->mmap_sem);
+ r = vm_munmap((unsigned long)vaddr, size);
- DPRINT(("down_write done smpl_vaddr=%p size=%lu\n", vaddr, size));
-
- r = pfm_do_munmap(task->mm, (unsigned long)vaddr, size, 0);
-
- up_write(&task->mm->mmap_sem);
if (r !=0) {
printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task_pid_nr(task), vaddr, size);
}
@@ -1945,7 +1935,7 @@
* because some VM function reenables interrupts.
*
*/
- if (smpl_buf_vaddr) pfm_remove_smpl_mapping(current, smpl_buf_vaddr, smpl_buf_size);
+ if (smpl_buf_vaddr) pfm_remove_smpl_mapping(smpl_buf_vaddr, smpl_buf_size);
return 0;
}
diff --git a/arch/m68k/configs/m5275evb_defconfig b/arch/m68k/configs/m5275evb_defconfig
index 33c32ae..a1230e8 100644
--- a/arch/m68k/configs/m5275evb_defconfig
+++ b/arch/m68k/configs/m5275evb_defconfig
@@ -49,7 +49,6 @@
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_FEC=y
-CONFIG_FEC2=y
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
CONFIG_PPP=y
diff --git a/arch/m68k/platform/527x/config.c b/arch/m68k/platform/527x/config.c
index 7ed848c..f91a532 100644
--- a/arch/m68k/platform/527x/config.c
+++ b/arch/m68k/platform/527x/config.c
@@ -74,9 +74,7 @@
writew(par | 0xf00, MCF_IPSBAR + 0x100082);
v = readb(MCF_IPSBAR + 0x100078);
writeb(v | 0xc0, MCF_IPSBAR + 0x100078);
-#endif
-#ifdef CONFIG_FEC2
/* Set multi-function pins to ethernet mode for fec1 */
par = readw(MCF_IPSBAR + 0x100082);
writew(par | 0xa0, MCF_IPSBAR + 0x100082);
diff --git a/arch/m68k/platform/68EZ328/Makefile b/arch/m68k/platform/68EZ328/Makefile
index ee97735..b44d799 100644
--- a/arch/m68k/platform/68EZ328/Makefile
+++ b/arch/m68k/platform/68EZ328/Makefile
@@ -3,9 +3,3 @@
#
obj-y := config.o
-
-extra-y := bootlogo.rh
-
-$(obj)/bootlogo.rh: $(src)/bootlogo.h
- perl $(src)/../68328/bootlogo.pl < $(src)/bootlogo.h \
- > $(obj)/bootlogo.rh
diff --git a/arch/m68k/platform/68VZ328/Makefile b/arch/m68k/platform/68VZ328/Makefile
index 447ffa0f..a49d75e 100644
--- a/arch/m68k/platform/68VZ328/Makefile
+++ b/arch/m68k/platform/68VZ328/Makefile
@@ -3,14 +3,9 @@
#
obj-y := config.o
-logo-$(UCDIMM) := bootlogo.rh
-logo-$(DRAGEN2) := screen.h
-extra-y := $(logo-y)
-
-$(obj)/bootlogo.rh: $(src)/../68EZ328/bootlogo.h
- perl $(src)/bootlogo.pl < $(src)/../68328/bootlogo.h > $(obj)/bootlogo.rh
+extra-$(DRAGEN2):= screen.h
$(obj)/screen.h: $(src)/screen.xbm $(src)/xbm2lcd.pl
perl $(src)/xbm2lcd.pl < $(src)/screen.xbm > $(obj)/screen.h
-clean-files := $(obj)/screen.h $(obj)/bootlogo.rh
+clean-files := $(obj)/screen.h
diff --git a/arch/m68k/platform/68EZ328/bootlogo.h b/arch/m68k/platform/68VZ328/bootlogo.h
similarity index 99%
rename from arch/m68k/platform/68EZ328/bootlogo.h
rename to arch/m68k/platform/68VZ328/bootlogo.h
index e842bda..b38e2b2 100644
--- a/arch/m68k/platform/68EZ328/bootlogo.h
+++ b/arch/m68k/platform/68VZ328/bootlogo.h
@@ -1,6 +1,6 @@
#define splash_width 640
#define splash_height 480
-static unsigned char splash_bits[] = {
+unsigned char __attribute__ ((aligned(16))) bootlogo_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
diff --git a/arch/m68k/platform/coldfire/device.c b/arch/m68k/platform/coldfire/device.c
index fa50c48..7af9736 100644
--- a/arch/m68k/platform/coldfire/device.c
+++ b/arch/m68k/platform/coldfire/device.c
@@ -114,7 +114,7 @@
static struct platform_device mcf_fec1 = {
.name = "fec",
- .id = 0,
+ .id = 1,
.num_resources = ARRAY_SIZE(mcf_fec1_resources),
.resource = mcf_fec1_resources,
};
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 2b7c0fb..9015060 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -90,7 +90,6 @@
select HAVE_KERNEL_XZ
select HAVE_ARCH_MUTEX_CPU_RELAX
select HAVE_ARCH_JUMP_LABEL if !MARCH_G5
- select HAVE_RCU_TABLE_FREE if SMP
select ARCH_SAVE_PAGE_KEYS if HIBERNATION
select HAVE_MEMBLOCK
select HAVE_MEMBLOCK_NODE_MAP
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index 6cf8e26..1957a9d 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -1,8 +1,12 @@
CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_AUDIT=y
-CONFIG_RCU_TRACE=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_CGROUPS=y
@@ -14,16 +18,22 @@
CONFIG_CGROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_BLK_CGROUP=y
+CONFIG_NAMESPACES=y
CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_XZ=y
+CONFIG_RD_LZO=y
+CONFIG_EXPERT=y
# CONFIG_COMPAT_BRK is not set
-CONFIG_SLAB=y
CONFIG_PROFILING=y
CONFIG_OPROFILE=y
CONFIG_KPROBES=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_IBM_PARTITION=y
CONFIG_DEFAULT_DEADLINE=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
@@ -34,18 +44,15 @@
CONFIG_BINFMT_MISC=m
CONFIG_CMM=m
CONFIG_HZ_100=y
-CONFIG_KEXEC=y
-CONFIG_PM=y
+CONFIG_CRASH_DUMP=y
CONFIG_HIBERNATION=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_NET_KEY=y
-CONFIG_AFIUCV=m
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_INET_LRO is not set
CONFIG_IPV6=y
-CONFIG_NET_SCTPPROBE=m
CONFIG_L2TP=m
CONFIG_L2TP_DEBUGFS=m
CONFIG_VLAN_8021Q=y
@@ -84,15 +91,14 @@
CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_ZFCP=y
-CONFIG_ZFCP_DIF=y
CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
CONFIG_BONDING=m
+CONFIG_DUMMY=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
-CONFIG_NET_ETHERNET=y
CONFIG_VIRTIO_NET=y
CONFIG_RAW_DRIVER=m
+CONFIG_VIRTIO_BALLOON=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
@@ -103,27 +109,21 @@
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
# CONFIG_NETWORK_FILESYSTEMS is not set
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_IBM_PARTITION=y
-CONFIG_DLM=m
CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
CONFIG_TIMER_STATS=y
CONFIG_PROVE_LOCKING=y
CONFIG_PROVE_RCU=y
CONFIG_LOCK_STAT=y
CONFIG_DEBUG_LOCKDEP=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
CONFIG_DEBUG_LIST=y
CONFIG_DEBUG_NOTIFIERS=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_RCU_TRACE=y
CONFIG_KPROBES_SANITY_TEST=y
CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
CONFIG_CPU_NOTIFIER_ERROR_INJECT=m
CONFIG_LATENCYTOP=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_DEBUG_PAGEALLOC=y
-# CONFIG_FTRACE is not set
+CONFIG_BLK_DEV_IO_TRACE=y
# CONFIG_STRICT_DEVMEM is not set
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_CRYPTD=m
@@ -173,4 +173,3 @@
CONFIG_CRYPTO_DES_S390=m
CONFIG_CRYPTO_AES_S390=m
CONFIG_CRC7=m
-CONFIG_VIRTIO_BALLOON=y
diff --git a/arch/s390/include/asm/facility.h b/arch/s390/include/asm/facility.h
index 1e5b27e..2ee66a6 100644
--- a/arch/s390/include/asm/facility.h
+++ b/arch/s390/include/asm/facility.h
@@ -38,12 +38,11 @@
unsigned long nr;
preempt_disable();
- S390_lowcore.stfl_fac_list = 0;
asm volatile(
" .insn s,0xb2b10000,0(0)\n" /* stfl */
"0:\n"
EX_TABLE(0b, 0b)
- : "=m" (S390_lowcore.stfl_fac_list));
+ : "+m" (S390_lowcore.stfl_fac_list));
nr = 4; /* bytes stored by stfl */
memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4);
if (S390_lowcore.stfl_fac_list & 0x01000000) {
diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h
index 8eef9b5..78e3041 100644
--- a/arch/s390/include/asm/pgalloc.h
+++ b/arch/s390/include/asm/pgalloc.h
@@ -22,10 +22,7 @@
unsigned long *page_table_alloc(struct mm_struct *, unsigned long);
void page_table_free(struct mm_struct *, unsigned long *);
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
void page_table_free_rcu(struct mmu_gather *, unsigned long *);
-void __tlb_remove_table(void *_table);
-#endif
static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
{
diff --git a/arch/s390/include/asm/swab.h b/arch/s390/include/asm/swab.h
index 6bdee21..a3e4ebb 100644
--- a/arch/s390/include/asm/swab.h
+++ b/arch/s390/include/asm/swab.h
@@ -77,7 +77,7 @@
asm volatile(
#ifndef __s390x__
- " icm %0,2,%O+1(%R1)\n"
+ " icm %0,2,%O1+1(%R1)\n"
" ic %0,%1\n"
: "=&d" (result) : "Q" (*x) : "cc");
#else /* __s390x__ */
diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h
index c687a2c..775a5ee 100644
--- a/arch/s390/include/asm/tlb.h
+++ b/arch/s390/include/asm/tlb.h
@@ -30,14 +30,10 @@
struct mmu_gather {
struct mm_struct *mm;
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
struct mmu_table_batch *batch;
-#endif
unsigned int fullmm;
- unsigned int need_flush;
};
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
struct mmu_table_batch {
struct rcu_head rcu;
unsigned int nr;
@@ -49,7 +45,6 @@
extern void tlb_table_flush(struct mmu_gather *tlb);
extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
-#endif
static inline void tlb_gather_mmu(struct mmu_gather *tlb,
struct mm_struct *mm,
@@ -57,29 +52,20 @@
{
tlb->mm = mm;
tlb->fullmm = full_mm_flush;
- tlb->need_flush = 0;
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
tlb->batch = NULL;
-#endif
if (tlb->fullmm)
__tlb_flush_mm(mm);
}
static inline void tlb_flush_mmu(struct mmu_gather *tlb)
{
- if (!tlb->need_flush)
- return;
- tlb->need_flush = 0;
- __tlb_flush_mm(tlb->mm);
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
tlb_table_flush(tlb);
-#endif
}
static inline void tlb_finish_mmu(struct mmu_gather *tlb,
unsigned long start, unsigned long end)
{
- tlb_flush_mmu(tlb);
+ tlb_table_flush(tlb);
}
/*
@@ -105,10 +91,8 @@
static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
unsigned long address)
{
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
if (!tlb->fullmm)
return page_table_free_rcu(tlb, (unsigned long *) pte);
-#endif
page_table_free(tlb->mm, (unsigned long *) pte);
}
@@ -125,10 +109,8 @@
#ifdef __s390x__
if (tlb->mm->context.asce_limit <= (1UL << 31))
return;
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
if (!tlb->fullmm)
return tlb_remove_table(tlb, pmd);
-#endif
crst_table_free(tlb->mm, (unsigned long *) pmd);
#endif
}
@@ -146,10 +128,8 @@
#ifdef __s390x__
if (tlb->mm->context.asce_limit <= (1UL << 42))
return;
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
if (!tlb->fullmm)
return tlb_remove_table(tlb, pud);
-#endif
crst_table_free(tlb->mm, (unsigned long *) pud);
#endif
}
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index c27a072..adccd90 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -474,9 +474,9 @@
stck __LC_LAST_UPDATE_CLOCK
spt 5f-.LPG0(%r13)
mvc __LC_LAST_UPDATE_TIMER(8),5f-.LPG0(%r13)
+ xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST
#ifndef CONFIG_MARCH_G5
# check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10}
- xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST
.insn s,0xb2b10000,__LC_STFL_FAC_LIST # store facility list
tm __LC_STFL_FAC_LIST,0x01 # stfle available ?
jz 0f
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index 1c2cdd5..8a22c27 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -118,9 +118,10 @@
"a" (__do_softirq)
: "0", "1", "2", "3", "4", "5", "14",
"cc", "memory" );
- } else
+ } else {
/* We are already on the async stack. */
__do_softirq();
+ }
}
local_irq_restore(flags);
@@ -192,11 +193,12 @@
int index = ext_hash(code);
spin_lock_irqsave(&ext_int_hash_lock, flags);
- list_for_each_entry_rcu(p, &ext_int_hash[index], entry)
+ list_for_each_entry_rcu(p, &ext_int_hash[index], entry) {
if (p->code == code && p->handler == handler) {
list_del_rcu(&p->entry);
kfree_rcu(p, rcu);
}
+ }
spin_unlock_irqrestore(&ext_int_hash_lock, flags);
return 0;
}
@@ -211,9 +213,10 @@
old_regs = set_irq_regs(regs);
irq_enter();
- if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator)
+ if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) {
/* Serve timer interrupts first. */
clock_comparator_work();
+ }
kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
if (ext_code.code != 0x1004)
__get_cpu_var(s390_idle).nohz_delay = 1;
diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c
index 4640508..cb019f4 100644
--- a/arch/s390/kernel/perf_cpum_cf.c
+++ b/arch/s390/kernel/perf_cpum_cf.c
@@ -178,7 +178,7 @@
err = lcctl(cpuhw->state);
if (err) {
pr_err("Enabling the performance measuring unit "
- "failed with rc=%lx\n", err);
+ "failed with rc=%x\n", err);
return;
}
@@ -203,7 +203,7 @@
err = lcctl(inactive);
if (err) {
pr_err("Disabling the performance measuring unit "
- "failed with rc=%lx\n", err);
+ "failed with rc=%x\n", err);
return;
}
diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c
index 7bb15fc..e1335dc 100644
--- a/arch/s390/mm/maccess.c
+++ b/arch/s390/mm/maccess.c
@@ -61,21 +61,14 @@
return copied < 0 ? -EFAULT : 0;
}
-/*
- * Copy memory in real mode (kernel to kernel)
- */
-int memcpy_real(void *dest, void *src, size_t count)
+static int __memcpy_real(void *dest, void *src, size_t count)
{
register unsigned long _dest asm("2") = (unsigned long) dest;
register unsigned long _len1 asm("3") = (unsigned long) count;
register unsigned long _src asm("4") = (unsigned long) src;
register unsigned long _len2 asm("5") = (unsigned long) count;
- unsigned long flags;
int rc = -EFAULT;
- if (!count)
- return 0;
- flags = __arch_local_irq_stnsm(0xf8UL);
asm volatile (
"0: mvcle %1,%2,0x0\n"
"1: jo 0b\n"
@@ -86,7 +79,23 @@
"+d" (_len2), "=m" (*((long *) dest))
: "m" (*((long *) src))
: "cc", "memory");
- arch_local_irq_restore(flags);
+ return rc;
+}
+
+/*
+ * Copy memory in real mode (kernel to kernel)
+ */
+int memcpy_real(void *dest, void *src, size_t count)
+{
+ unsigned long flags;
+ int rc;
+
+ if (!count)
+ return 0;
+ local_irq_save(flags);
+ __arch_local_irq_stnsm(0xfbUL);
+ rc = __memcpy_real(dest, src, count);
+ local_irq_restore(flags);
return rc;
}
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 373adf6..6e765bf 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -678,8 +678,6 @@
}
}
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
-
static void __page_table_free_rcu(void *table, unsigned bit)
{
struct page *page;
@@ -733,7 +731,66 @@
free_pages((unsigned long) table, ALLOC_ORDER);
}
-#endif
+static void tlb_remove_table_smp_sync(void *arg)
+{
+ /* Simply deliver the interrupt */
+}
+
+static void tlb_remove_table_one(void *table)
+{
+ /*
+ * This isn't an RCU grace period and hence the page-tables cannot be
+ * assumed to be actually RCU-freed.
+ *
+ * It is however sufficient for software page-table walkers that rely
+ * on IRQ disabling. See the comment near struct mmu_table_batch.
+ */
+ smp_call_function(tlb_remove_table_smp_sync, NULL, 1);
+ __tlb_remove_table(table);
+}
+
+static void tlb_remove_table_rcu(struct rcu_head *head)
+{
+ struct mmu_table_batch *batch;
+ int i;
+
+ batch = container_of(head, struct mmu_table_batch, rcu);
+
+ for (i = 0; i < batch->nr; i++)
+ __tlb_remove_table(batch->tables[i]);
+
+ free_page((unsigned long)batch);
+}
+
+void tlb_table_flush(struct mmu_gather *tlb)
+{
+ struct mmu_table_batch **batch = &tlb->batch;
+
+ if (*batch) {
+ __tlb_flush_mm(tlb->mm);
+ call_rcu_sched(&(*batch)->rcu, tlb_remove_table_rcu);
+ *batch = NULL;
+ }
+}
+
+void tlb_remove_table(struct mmu_gather *tlb, void *table)
+{
+ struct mmu_table_batch **batch = &tlb->batch;
+
+ if (*batch == NULL) {
+ *batch = (struct mmu_table_batch *)
+ __get_free_page(GFP_NOWAIT | __GFP_NOWARN);
+ if (*batch == NULL) {
+ __tlb_flush_mm(tlb->mm);
+ tlb_remove_table_one(table);
+ return;
+ }
+ (*batch)->nr = 0;
+ }
+ (*batch)->tables[(*batch)->nr++] = table;
+ if ((*batch)->nr == MAX_TABLE_BATCH)
+ tlb_table_flush(tlb);
+}
/*
* switch on pgstes for its userspace process (for kvm)
diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c
index 1210fde..160cac9 100644
--- a/arch/sparc/kernel/leon_smp.c
+++ b/arch/sparc/kernel/leon_smp.c
@@ -23,6 +23,7 @@
#include <linux/pm.h>
#include <linux/delay.h>
#include <linux/gfp.h>
+#include <linux/cpu.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
@@ -78,6 +79,8 @@
local_flush_tlb_all();
leon_configure_cache_smp();
+ notify_cpu_starting(cpuid);
+
/* Get our local ticker going. */
smp_setup_percpu_timer();
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index 232df99..3ee51f1 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -566,15 +566,10 @@
SYSCALL_DEFINE2(64_munmap, unsigned long, addr, size_t, len)
{
- long ret;
-
if (invalid_64bit_range(addr, len))
return -EINVAL;
- down_write(¤t->mm->mmap_sem);
- ret = do_munmap(current->mm, addr, len);
- up_write(¤t->mm->mmap_sem);
- return ret;
+ return vm_munmap(addr, len);
}
extern unsigned long do_mremap(unsigned long addr,
diff --git a/arch/tile/kernel/single_step.c b/arch/tile/kernel/single_step.c
index 9efbc13..89529c9 100644
--- a/arch/tile/kernel/single_step.c
+++ b/arch/tile/kernel/single_step.c
@@ -346,12 +346,10 @@
}
/* allocate a cache line of writable, executable memory */
- down_write(¤t->mm->mmap_sem);
- buffer = (void __user *) do_mmap(NULL, 0, 64,
+ buffer = (void __user *) vm_mmap(NULL, 0, 64,
PROT_EXEC | PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS,
0);
- up_write(¤t->mm->mmap_sem);
if (IS_ERR((void __force *)buffer)) {
kfree(state);
diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c
index d511d95..4824fb4 100644
--- a/arch/x86/ia32/ia32_aout.c
+++ b/arch/x86/ia32/ia32_aout.c
@@ -119,9 +119,7 @@
end = PAGE_ALIGN(end);
if (end <= start)
return;
- down_write(¤t->mm->mmap_sem);
- do_brk(start, end - start);
- up_write(¤t->mm->mmap_sem);
+ vm_brk(start, end - start);
}
#ifdef CORE_DUMP
@@ -332,9 +330,7 @@
pos = 32;
map_size = ex.a_text+ex.a_data;
- down_write(¤t->mm->mmap_sem);
- error = do_brk(text_addr & PAGE_MASK, map_size);
- up_write(¤t->mm->mmap_sem);
+ error = vm_brk(text_addr & PAGE_MASK, map_size);
if (error != (text_addr & PAGE_MASK)) {
send_sig(SIGKILL, current, 0);
@@ -373,9 +369,7 @@
if (!bprm->file->f_op->mmap || (fd_offset & ~PAGE_MASK) != 0) {
loff_t pos = fd_offset;
- down_write(¤t->mm->mmap_sem);
- do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
- up_write(¤t->mm->mmap_sem);
+ vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
bprm->file->f_op->read(bprm->file,
(char __user *)N_TXTADDR(ex),
ex.a_text+ex.a_data, &pos);
@@ -385,26 +379,22 @@
goto beyond_if;
}
- down_write(¤t->mm->mmap_sem);
- error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
+ error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE |
MAP_EXECUTABLE | MAP_32BIT,
fd_offset);
- up_write(¤t->mm->mmap_sem);
if (error != N_TXTADDR(ex)) {
send_sig(SIGKILL, current, 0);
return error;
}
- down_write(¤t->mm->mmap_sem);
- error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
+ error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE |
MAP_EXECUTABLE | MAP_32BIT,
fd_offset + ex.a_text);
- up_write(¤t->mm->mmap_sem);
if (error != N_DATADDR(ex)) {
send_sig(SIGKILL, current, 0);
return error;
@@ -476,9 +466,7 @@
error_time = jiffies;
}
#endif
- down_write(¤t->mm->mmap_sem);
- do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
- up_write(¤t->mm->mmap_sem);
+ vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
file->f_op->read(file, (char __user *)start_addr,
ex.a_text + ex.a_data, &pos);
@@ -490,12 +478,10 @@
goto out;
}
/* Now use mmap to map the library into memory. */
- down_write(¤t->mm->mmap_sem);
- error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
+ error = vm_mmap(file, start_addr, ex.a_text + ex.a_data,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_32BIT,
N_TXTOFF(ex));
- up_write(¤t->mm->mmap_sem);
retval = error;
if (error != start_addr)
goto out;
@@ -503,9 +489,7 @@
len = PAGE_ALIGN(ex.a_text + ex.a_data);
bss = ex.a_text + ex.a_data + ex.a_bss;
if (bss > len) {
- down_write(¤t->mm->mmap_sem);
- error = do_brk(start_addr + len, bss - len);
- up_write(¤t->mm->mmap_sem);
+ error = vm_brk(start_addr + len, bss - len);
retval = error;
if (error != start_addr + len)
goto out;
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 173df38..2e88438 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -459,17 +459,17 @@
pmu->available_event_types = ~entry->ebx & ((1ull << bitmap_len) - 1);
if (pmu->version == 1) {
- pmu->global_ctrl = (1 << pmu->nr_arch_gp_counters) - 1;
- return;
+ pmu->nr_arch_fixed_counters = 0;
+ } else {
+ pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f),
+ X86_PMC_MAX_FIXED);
+ pmu->counter_bitmask[KVM_PMC_FIXED] =
+ ((u64)1 << ((entry->edx >> 5) & 0xff)) - 1;
}
- pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f),
- X86_PMC_MAX_FIXED);
- pmu->counter_bitmask[KVM_PMC_FIXED] =
- ((u64)1 << ((entry->edx >> 5) & 0xff)) - 1;
- pmu->global_ctrl_mask = ~(((1 << pmu->nr_arch_gp_counters) - 1)
- | (((1ull << pmu->nr_arch_fixed_counters) - 1)
- << X86_PMC_IDX_FIXED));
+ pmu->global_ctrl = ((1 << pmu->nr_arch_gp_counters) - 1) |
+ (((1ull << pmu->nr_arch_fixed_counters) - 1) << X86_PMC_IDX_FIXED);
+ pmu->global_ctrl_mask = ~pmu->global_ctrl;
}
void kvm_pmu_init(struct kvm_vcpu *vcpu)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index ad85adf..4ff0ab9 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2210,9 +2210,12 @@
msr = find_msr_entry(vmx, msr_index);
if (msr) {
msr->data = data;
- if (msr - vmx->guest_msrs < vmx->save_nmsrs)
+ if (msr - vmx->guest_msrs < vmx->save_nmsrs) {
+ preempt_disable();
kvm_set_shared_msr(msr->index, msr->data,
msr->mask);
+ preempt_enable();
+ }
break;
}
ret = kvm_set_msr_common(vcpu, msr_index, data);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 4044ce0..91a5e98 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6336,13 +6336,11 @@
if (npages && !old.rmap) {
unsigned long userspace_addr;
- down_write(¤t->mm->mmap_sem);
- userspace_addr = do_mmap(NULL, 0,
+ userspace_addr = vm_mmap(NULL, 0,
npages * PAGE_SIZE,
PROT_READ | PROT_WRITE,
map_flags,
0);
- up_write(¤t->mm->mmap_sem);
if (IS_ERR((void *)userspace_addr))
return PTR_ERR((void *)userspace_addr);
@@ -6366,10 +6364,8 @@
if (!user_alloc && !old.user_alloc && old.rmap && !npages) {
int ret;
- down_write(¤t->mm->mmap_sem);
- ret = do_munmap(current->mm, old.userspace_addr,
+ ret = vm_munmap(old.userspace_addr,
old.npages * PAGE_SIZE);
- up_write(¤t->mm->mmap_sem);
if (ret < 0)
printk(KERN_WARNING
"kvm_vm_ioctl_set_memory_region: "
diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c
index 25feb1a..b1e6c4b 100644
--- a/arch/x86/lib/insn.c
+++ b/arch/x86/lib/insn.c
@@ -379,8 +379,8 @@
return;
}
-/* Decode moffset16/32/64 */
-static void __get_moffset(struct insn *insn)
+/* Decode moffset16/32/64. Return 0 if failed */
+static int __get_moffset(struct insn *insn)
{
switch (insn->addr_bytes) {
case 2:
@@ -397,15 +397,19 @@
insn->moffset2.value = get_next(int, insn);
insn->moffset2.nbytes = 4;
break;
+ default: /* opnd_bytes must be modified manually */
+ goto err_out;
}
insn->moffset1.got = insn->moffset2.got = 1;
+ return 1;
+
err_out:
- return;
+ return 0;
}
-/* Decode imm v32(Iz) */
-static void __get_immv32(struct insn *insn)
+/* Decode imm v32(Iz). Return 0 if failed */
+static int __get_immv32(struct insn *insn)
{
switch (insn->opnd_bytes) {
case 2:
@@ -417,14 +421,18 @@
insn->immediate.value = get_next(int, insn);
insn->immediate.nbytes = 4;
break;
+ default: /* opnd_bytes must be modified manually */
+ goto err_out;
}
+ return 1;
+
err_out:
- return;
+ return 0;
}
-/* Decode imm v64(Iv/Ov) */
-static void __get_immv(struct insn *insn)
+/* Decode imm v64(Iv/Ov), Return 0 if failed */
+static int __get_immv(struct insn *insn)
{
switch (insn->opnd_bytes) {
case 2:
@@ -441,15 +449,18 @@
insn->immediate2.value = get_next(int, insn);
insn->immediate2.nbytes = 4;
break;
+ default: /* opnd_bytes must be modified manually */
+ goto err_out;
}
insn->immediate1.got = insn->immediate2.got = 1;
+ return 1;
err_out:
- return;
+ return 0;
}
/* Decode ptr16:16/32(Ap) */
-static void __get_immptr(struct insn *insn)
+static int __get_immptr(struct insn *insn)
{
switch (insn->opnd_bytes) {
case 2:
@@ -462,14 +473,17 @@
break;
case 8:
/* ptr16:64 is not exist (no segment) */
- return;
+ return 0;
+ default: /* opnd_bytes must be modified manually */
+ goto err_out;
}
insn->immediate2.value = get_next(unsigned short, insn);
insn->immediate2.nbytes = 2;
insn->immediate1.got = insn->immediate2.got = 1;
+ return 1;
err_out:
- return;
+ return 0;
}
/**
@@ -489,7 +503,8 @@
insn_get_displacement(insn);
if (inat_has_moffset(insn->attr)) {
- __get_moffset(insn);
+ if (!__get_moffset(insn))
+ goto err_out;
goto done;
}
@@ -517,16 +532,20 @@
insn->immediate2.nbytes = 4;
break;
case INAT_IMM_PTR:
- __get_immptr(insn);
+ if (!__get_immptr(insn))
+ goto err_out;
break;
case INAT_IMM_VWORD32:
- __get_immv32(insn);
+ if (!__get_immv32(insn))
+ goto err_out;
break;
case INAT_IMM_VWORD:
- __get_immv(insn);
+ if (!__get_immv(insn))
+ goto err_out;
break;
default:
- break;
+ /* Here, insn must have an immediate, but failed */
+ goto err_out;
}
if (inat_has_second_immediate(insn->attr)) {
insn->immediate2.value = get_next(char, insn);
diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c
index 107f6f7..dd30f40 100644
--- a/crypto/sha512_generic.c
+++ b/crypto/sha512_generic.c
@@ -174,7 +174,7 @@
index = sctx->count[0] & 0x7f;
/* Update number of bytes */
- if (!(sctx->count[0] += len))
+ if ((sctx->count[0] += len) < len)
sctx->count[1]++;
part_len = 128 - index;
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c
index ab513a9..a716fed 100644
--- a/drivers/acpi/acpica/hwxface.c
+++ b/drivers/acpi/acpica/hwxface.c
@@ -74,7 +74,8 @@
/* Check if the reset register is supported */
- if (!reset_reg->address) {
+ if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) ||
+ !reset_reg->address) {
return_ACPI_STATUS(AE_NOT_EXIST);
}
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index ba14fb9..c3881b2 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -607,8 +607,7 @@
acpi_irq_handler = handler;
acpi_irq_context = context;
- if (request_threaded_irq(irq, NULL, acpi_irq, IRQF_SHARED, "acpi",
- acpi_irq)) {
+ if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) {
printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq);
acpi_irq_handler = NULL;
return AE_NOT_ACQUIRED;
diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c
index c1d6124..a6c77e8b 100644
--- a/drivers/acpi/reboot.c
+++ b/drivers/acpi/reboot.c
@@ -23,7 +23,8 @@
/* Is the reset register supported? The spec says we should be
* checking the bit width and bit offset, but Windows ignores
* these fields */
- /* Ignore also acpi_gbl_FADT.flags.ACPI_FADT_RESET_REGISTER */
+ if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER))
+ return;
reset_value = acpi_gbl_FADT.reset_value;
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 68013f9..7857e8f 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -329,6 +329,8 @@
{ 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
/* SATA Controller IDE (Lynx Point) */
{ 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+ /* SATA Controller IDE (DH89xxCC) */
+ { 0x8086, 0x2326, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
{ } /* terminate list */
};
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index e0bda9f..28db50b 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -95,7 +95,7 @@
static void ata_dev_xfermask(struct ata_device *dev);
static unsigned long ata_dev_blacklisted(const struct ata_device *dev);
-unsigned int ata_print_id = 1;
+atomic_t ata_print_id = ATOMIC_INIT(1);
struct ata_force_param {
const char *name;
@@ -6029,7 +6029,7 @@
/* give ports names and add SCSI hosts */
for (i = 0; i < host->n_ports; i++)
- host->ports[i]->print_id = ata_print_id++;
+ host->ports[i]->print_id = atomic_inc_return(&ata_print_id);
/* Create associated sysfs transport objects */
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 1ee00c8..93dabdc 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3843,7 +3843,7 @@
int rc = ap->ops->port_start(ap);
if (!rc) {
- ap->print_id = ata_print_id++;
+ ap->print_id = atomic_inc_return(&ata_print_id);
__ata_port_probe(ap);
}
@@ -3867,7 +3867,7 @@
int rc = ap->ops->port_start(ap);
if (!rc) {
- ap->print_id = ata_print_id++;
+ ap->print_id = atomic_inc_return(&ata_print_id);
rc = ata_port_probe(ap);
}
diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c
index 74aaee3..c341904 100644
--- a/drivers/ata/libata-transport.c
+++ b/drivers/ata/libata-transport.c
@@ -294,6 +294,7 @@
device_enable_async_suspend(dev);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
+ pm_runtime_forbid(dev);
transport_add_device(dev);
transport_configure_device(dev);
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 2e26fca..9d0fd0b 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -53,7 +53,7 @@
ATA_DNXFER_QUIET = (1 << 31),
};
-extern unsigned int ata_print_id;
+extern atomic_t ata_print_id;
extern int atapi_passthru16;
extern int libata_fua;
extern int libata_noacpi;
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 38950ea..7336d4a 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -4025,7 +4025,8 @@
struct ata_host *host;
struct mv_host_priv *hpriv;
struct resource *res;
- int n_ports, rc;
+ int n_ports = 0;
+ int rc;
ata_print_version_once(&pdev->dev, DRV_VERSION);
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 0e4ef3d..0d39f2f 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -375,6 +375,34 @@
return err;
}
+/*
+ * Legacy naming scheme used for virtio devices. We are stuck with it for
+ * virtio blk but don't ever use it for any new driver.
+ */
+static int virtblk_name_format(char *prefix, int index, char *buf, int buflen)
+{
+ const int base = 'z' - 'a' + 1;
+ char *begin = buf + strlen(prefix);
+ char *end = buf + buflen;
+ char *p;
+ int unit;
+
+ p = end - 1;
+ *p = '\0';
+ unit = base;
+ do {
+ if (p == begin)
+ return -EINVAL;
+ *--p = 'a' + (index % unit);
+ index = (index / unit) - 1;
+ } while (index >= 0);
+
+ memmove(begin, p, end - p);
+ memcpy(buf, prefix, strlen(prefix));
+
+ return 0;
+}
+
static int __devinit virtblk_probe(struct virtio_device *vdev)
{
struct virtio_blk *vblk;
@@ -443,18 +471,7 @@
q->queuedata = vblk;
- if (index < 26) {
- sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26);
- } else if (index < (26 + 1) * 26) {
- sprintf(vblk->disk->disk_name, "vd%c%c",
- 'a' + index / 26 - 1, 'a' + index % 26);
- } else {
- const unsigned int m1 = (index / 26 - 1) / 26 - 1;
- const unsigned int m2 = (index / 26 - 1) % 26;
- const unsigned int m3 = index % 26;
- sprintf(vblk->disk->disk_name, "vd%c%c%c",
- 'a' + m1, 'a' + m2, 'a' + m3);
- }
+ virtblk_name_format("vd", index, vblk->disk->disk_name, DISK_NAME_LEN);
vblk->disk->major = major;
vblk->disk->first_minor = index_to_minor(index);
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c
index 89860f3..4f66171 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -416,7 +416,7 @@
"discard-secure", "%d",
blkif->vbd.discard_secure);
if (err) {
- dev_warn(dev-dev, "writing discard-secure (%d)", err);
+ dev_warn(&dev->dev, "writing discard-secure (%d)", err);
return;
}
}
diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c
index 0053d7e..8f3f74c 100644
--- a/drivers/crypto/ixp4xx_crypto.c
+++ b/drivers/crypto/ixp4xx_crypto.c
@@ -18,6 +18,7 @@
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/gfp.h>
+#include <linux/module.h>
#include <crypto/ctr.h>
#include <crypto/des.h>
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index dc641c7..921039e 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -124,6 +124,9 @@
void __iomem *reg;
int irq[2];
+ /* SEC global registers lock */
+ spinlock_t reg_lock ____cacheline_aligned;
+
/* SEC version geometry (from device tree node) */
unsigned int num_channels;
unsigned int chfifo_len;
@@ -412,6 +415,7 @@
{ \
struct device *dev = (struct device *)data; \
struct talitos_private *priv = dev_get_drvdata(dev); \
+ unsigned long flags; \
\
if (ch_done_mask & 1) \
flush_channel(dev, 0, 0, 0); \
@@ -427,8 +431,10 @@
out: \
/* At this point, all completed channels have been processed */ \
/* Unmask done interrupts for channels completed later on. */ \
+ spin_lock_irqsave(&priv->reg_lock, flags); \
setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); \
+ spin_unlock_irqrestore(&priv->reg_lock, flags); \
}
DEF_TALITOS_DONE(4ch, TALITOS_ISR_4CHDONE)
DEF_TALITOS_DONE(ch0_2, TALITOS_ISR_CH_0_2_DONE)
@@ -619,22 +625,28 @@
struct device *dev = data; \
struct talitos_private *priv = dev_get_drvdata(dev); \
u32 isr, isr_lo; \
+ unsigned long flags; \
\
+ spin_lock_irqsave(&priv->reg_lock, flags); \
isr = in_be32(priv->reg + TALITOS_ISR); \
isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
/* Acknowledge interrupt */ \
out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
\
- if (unlikely((isr & ~TALITOS_ISR_4CHDONE) & ch_err_mask || isr_lo)) \
- talitos_error(dev, isr, isr_lo); \
- else \
+ if (unlikely(isr & ch_err_mask || isr_lo)) { \
+ spin_unlock_irqrestore(&priv->reg_lock, flags); \
+ talitos_error(dev, isr & ch_err_mask, isr_lo); \
+ } \
+ else { \
if (likely(isr & ch_done_mask)) { \
/* mask further done interrupts. */ \
clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
/* done_task will unmask done interrupts at exit */ \
tasklet_schedule(&priv->done_task[tlet]); \
} \
+ spin_unlock_irqrestore(&priv->reg_lock, flags); \
+ } \
\
return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
IRQ_NONE; \
@@ -2719,6 +2731,8 @@
priv->ofdev = ofdev;
+ spin_lock_init(&priv->reg_lock);
+
err = talitos_probe_irq(ofdev);
if (err)
goto err_out;
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index cf9da36..ef378b5 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -91,11 +91,10 @@
config AT_HDMAC
tristate "Atmel AHB DMA support"
- depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
+ depends on ARCH_AT91
select DMA_ENGINE
help
- Support the Atmel AHB DMA controller. This can be integrated in
- chips such as the Atmel AT91SAM9RL.
+ Support the Atmel AHB DMA controller.
config FSL_DMA
tristate "Freescale Elo and Elo Plus DMA support"
diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c
index 839624f..9b126b6d 100644
--- a/drivers/gpio/gpio-nomadik.c
+++ b/drivers/gpio/gpio-nomadik.c
@@ -22,14 +22,13 @@
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/irqdomain.h>
#include <linux/slab.h>
#include <asm/mach/irq.h>
#include <plat/pincfg.h>
#include <plat/gpio-nomadik.h>
-#include <mach/hardware.h>
-#include <asm/gpio.h>
/*
* The GPIO module in the Nomadik family of Systems-on-Chip is an
@@ -43,6 +42,7 @@
struct nmk_gpio_chip {
struct gpio_chip chip;
+ struct irq_domain *domain;
void __iomem *addr;
struct clk *clk;
unsigned int bank;
@@ -58,8 +58,10 @@
u32 real_wake;
u32 rwimsc;
u32 fwimsc;
- u32 slpm;
+ u32 rimsc;
+ u32 fimsc;
u32 pull_up;
+ u32 lowemi;
};
static struct nmk_gpio_chip *
@@ -124,6 +126,24 @@
}
}
+static void __nmk_gpio_set_lowemi(struct nmk_gpio_chip *nmk_chip,
+ unsigned offset, bool lowemi)
+{
+ u32 bit = BIT(offset);
+ bool enabled = nmk_chip->lowemi & bit;
+
+ if (lowemi == enabled)
+ return;
+
+ if (lowemi)
+ nmk_chip->lowemi |= bit;
+ else
+ nmk_chip->lowemi &= ~bit;
+
+ writel_relaxed(nmk_chip->lowemi,
+ nmk_chip->addr + NMK_GPIO_LOWEMI);
+}
+
static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip,
unsigned offset)
{
@@ -150,8 +170,8 @@
unsigned offset, int gpio_mode,
bool glitch)
{
- u32 rwimsc = readl(nmk_chip->addr + NMK_GPIO_RWIMSC);
- u32 fwimsc = readl(nmk_chip->addr + NMK_GPIO_FWIMSC);
+ u32 rwimsc = nmk_chip->rwimsc;
+ u32 fwimsc = nmk_chip->fwimsc;
if (glitch && nmk_chip->set_ioforce) {
u32 bit = BIT(offset);
@@ -173,6 +193,36 @@
}
}
+static void
+nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned offset)
+{
+ u32 falling = nmk_chip->fimsc & BIT(offset);
+ u32 rising = nmk_chip->rimsc & BIT(offset);
+ int gpio = nmk_chip->chip.base + offset;
+ int irq = NOMADIK_GPIO_TO_IRQ(gpio);
+ struct irq_data *d = irq_get_irq_data(irq);
+
+ if (!rising && !falling)
+ return;
+
+ if (!d || !irqd_irq_disabled(d))
+ return;
+
+ if (rising) {
+ nmk_chip->rimsc &= ~BIT(offset);
+ writel_relaxed(nmk_chip->rimsc,
+ nmk_chip->addr + NMK_GPIO_RIMSC);
+ }
+
+ if (falling) {
+ nmk_chip->fimsc &= ~BIT(offset);
+ writel_relaxed(nmk_chip->fimsc,
+ nmk_chip->addr + NMK_GPIO_FIMSC);
+ }
+
+ dev_dbg(nmk_chip->chip.dev, "%d: clearing interrupt mask\n", gpio);
+}
+
static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
pin_cfg_t cfg, bool sleep, unsigned int *slpmregs)
{
@@ -238,6 +288,17 @@
__nmk_gpio_set_pull(nmk_chip, offset, pull);
}
+ __nmk_gpio_set_lowemi(nmk_chip, offset, PIN_LOWEMI(cfg));
+
+ /*
+ * If the pin is switching to altfunc, and there was an interrupt
+ * installed on it which has been lazy disabled, actually mask the
+ * interrupt to prevent spurious interrupts that would occur while the
+ * pin is under control of the peripheral. Only SKE does this.
+ */
+ if (af != NMK_GPIO_ALT_GPIO)
+ nmk_gpio_disable_lazy_irq(nmk_chip, offset);
+
/*
* If we've backed up the SLPM registers (glitch workaround), modify
* the backups since they will be restored.
@@ -334,7 +395,7 @@
struct nmk_gpio_chip *nmk_chip;
int pin = PIN_NUM(cfgs[i]);
- nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(pin));
+ nmk_chip = nmk_gpio_chips[pin / NMK_GPIO_PER_CHIP];
if (!nmk_chip) {
ret = -EINVAL;
break;
@@ -342,7 +403,7 @@
clk_enable(nmk_chip->clk);
spin_lock(&nmk_chip->lock);
- __nmk_config_pin(nmk_chip, pin - nmk_chip->chip.base,
+ __nmk_config_pin(nmk_chip, pin % NMK_GPIO_PER_CHIP,
cfgs[i], sleep, glitch ? slpm : NULL);
spin_unlock(&nmk_chip->lock);
clk_disable(nmk_chip->clk);
@@ -426,7 +487,7 @@
struct nmk_gpio_chip *nmk_chip;
unsigned long flags;
- nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+ nmk_chip = nmk_gpio_chips[gpio / NMK_GPIO_PER_CHIP];
if (!nmk_chip)
return -EINVAL;
@@ -434,7 +495,7 @@
spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
spin_lock(&nmk_chip->lock);
- __nmk_gpio_set_slpm(nmk_chip, gpio - nmk_chip->chip.base, mode);
+ __nmk_gpio_set_slpm(nmk_chip, gpio % NMK_GPIO_PER_CHIP, mode);
spin_unlock(&nmk_chip->lock);
spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
@@ -461,13 +522,13 @@
struct nmk_gpio_chip *nmk_chip;
unsigned long flags;
- nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+ nmk_chip = nmk_gpio_chips[gpio / NMK_GPIO_PER_CHIP];
if (!nmk_chip)
return -EINVAL;
clk_enable(nmk_chip->clk);
spin_lock_irqsave(&nmk_chip->lock, flags);
- __nmk_gpio_set_pull(nmk_chip, gpio - nmk_chip->chip.base, pull);
+ __nmk_gpio_set_pull(nmk_chip, gpio % NMK_GPIO_PER_CHIP, pull);
spin_unlock_irqrestore(&nmk_chip->lock, flags);
clk_disable(nmk_chip->clk);
@@ -489,13 +550,13 @@
struct nmk_gpio_chip *nmk_chip;
unsigned long flags;
- nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+ nmk_chip = nmk_gpio_chips[gpio / NMK_GPIO_PER_CHIP];
if (!nmk_chip)
return -EINVAL;
clk_enable(nmk_chip->clk);
spin_lock_irqsave(&nmk_chip->lock, flags);
- __nmk_gpio_set_mode(nmk_chip, gpio - nmk_chip->chip.base, gpio_mode);
+ __nmk_gpio_set_mode(nmk_chip, gpio % NMK_GPIO_PER_CHIP, gpio_mode);
spin_unlock_irqrestore(&nmk_chip->lock, flags);
clk_disable(nmk_chip->clk);
@@ -508,11 +569,11 @@
struct nmk_gpio_chip *nmk_chip;
u32 afunc, bfunc, bit;
- nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+ nmk_chip = nmk_gpio_chips[gpio / NMK_GPIO_PER_CHIP];
if (!nmk_chip)
return -EINVAL;
- bit = 1 << (gpio - nmk_chip->chip.base);
+ bit = 1 << (gpio % NMK_GPIO_PER_CHIP);
clk_enable(nmk_chip->clk);
@@ -529,21 +590,19 @@
/* IRQ functions */
static inline int nmk_gpio_get_bitmask(int gpio)
{
- return 1 << (gpio % 32);
+ return 1 << (gpio % NMK_GPIO_PER_CHIP);
}
static void nmk_gpio_irq_ack(struct irq_data *d)
{
- int gpio;
struct nmk_gpio_chip *nmk_chip;
- gpio = NOMADIK_IRQ_TO_GPIO(d->irq);
nmk_chip = irq_data_get_irq_chip_data(d);
if (!nmk_chip)
return;
clk_enable(nmk_chip->clk);
- writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC);
+ writel(nmk_gpio_get_bitmask(d->hwirq), nmk_chip->addr + NMK_GPIO_IC);
clk_disable(nmk_chip->clk);
}
@@ -556,37 +615,52 @@
int gpio, enum nmk_gpio_irq_type which,
bool enable)
{
- u32 rimsc = which == WAKE ? NMK_GPIO_RWIMSC : NMK_GPIO_RIMSC;
- u32 fimsc = which == WAKE ? NMK_GPIO_FWIMSC : NMK_GPIO_FIMSC;
u32 bitmask = nmk_gpio_get_bitmask(gpio);
- u32 reg;
+ u32 *rimscval;
+ u32 *fimscval;
+ u32 rimscreg;
+ u32 fimscreg;
+
+ if (which == NORMAL) {
+ rimscreg = NMK_GPIO_RIMSC;
+ fimscreg = NMK_GPIO_FIMSC;
+ rimscval = &nmk_chip->rimsc;
+ fimscval = &nmk_chip->fimsc;
+ } else {
+ rimscreg = NMK_GPIO_RWIMSC;
+ fimscreg = NMK_GPIO_FWIMSC;
+ rimscval = &nmk_chip->rwimsc;
+ fimscval = &nmk_chip->fwimsc;
+ }
/* we must individually set/clear the two edges */
if (nmk_chip->edge_rising & bitmask) {
- reg = readl(nmk_chip->addr + rimsc);
if (enable)
- reg |= bitmask;
+ *rimscval |= bitmask;
else
- reg &= ~bitmask;
- writel(reg, nmk_chip->addr + rimsc);
+ *rimscval &= ~bitmask;
+ writel(*rimscval, nmk_chip->addr + rimscreg);
}
if (nmk_chip->edge_falling & bitmask) {
- reg = readl(nmk_chip->addr + fimsc);
if (enable)
- reg |= bitmask;
+ *fimscval |= bitmask;
else
- reg &= ~bitmask;
- writel(reg, nmk_chip->addr + fimsc);
+ *fimscval &= ~bitmask;
+ writel(*fimscval, nmk_chip->addr + fimscreg);
}
}
static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip,
int gpio, bool on)
{
- if (nmk_chip->sleepmode) {
- __nmk_gpio_set_slpm(nmk_chip, gpio - nmk_chip->chip.base,
- on ? NMK_GPIO_SLPM_WAKEUP_ENABLE
- : NMK_GPIO_SLPM_WAKEUP_DISABLE);
+ /*
+ * Ensure WAKEUP_ENABLE is on. No need to disable it if wakeup is
+ * disabled, since setting SLPM to 1 increases power consumption, and
+ * wakeup is anyhow controlled by the RIMSC and FIMSC registers.
+ */
+ if (nmk_chip->sleepmode && on) {
+ __nmk_gpio_set_slpm(nmk_chip, gpio % nmk_chip->chip.base,
+ NMK_GPIO_SLPM_WAKEUP_ENABLE);
}
__nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, on);
@@ -594,14 +668,12 @@
static int nmk_gpio_irq_maskunmask(struct irq_data *d, bool enable)
{
- int gpio;
struct nmk_gpio_chip *nmk_chip;
unsigned long flags;
u32 bitmask;
- gpio = NOMADIK_IRQ_TO_GPIO(d->irq);
nmk_chip = irq_data_get_irq_chip_data(d);
- bitmask = nmk_gpio_get_bitmask(gpio);
+ bitmask = nmk_gpio_get_bitmask(d->hwirq);
if (!nmk_chip)
return -EINVAL;
@@ -609,10 +681,10 @@
spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
spin_lock(&nmk_chip->lock);
- __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, enable);
+ __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, enable);
if (!(nmk_chip->real_wake & bitmask))
- __nmk_gpio_set_wake(nmk_chip, gpio, enable);
+ __nmk_gpio_set_wake(nmk_chip, d->hwirq, enable);
spin_unlock(&nmk_chip->lock);
spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
@@ -636,20 +708,18 @@
struct nmk_gpio_chip *nmk_chip;
unsigned long flags;
u32 bitmask;
- int gpio;
- gpio = NOMADIK_IRQ_TO_GPIO(d->irq);
nmk_chip = irq_data_get_irq_chip_data(d);
if (!nmk_chip)
return -EINVAL;
- bitmask = nmk_gpio_get_bitmask(gpio);
+ bitmask = nmk_gpio_get_bitmask(d->hwirq);
clk_enable(nmk_chip->clk);
spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
spin_lock(&nmk_chip->lock);
if (irqd_irq_disabled(d))
- __nmk_gpio_set_wake(nmk_chip, gpio, on);
+ __nmk_gpio_set_wake(nmk_chip, d->hwirq, on);
if (on)
nmk_chip->real_wake |= bitmask;
@@ -667,17 +737,14 @@
{
bool enabled = !irqd_irq_disabled(d);
bool wake = irqd_is_wakeup_set(d);
- int gpio;
struct nmk_gpio_chip *nmk_chip;
unsigned long flags;
u32 bitmask;
- gpio = NOMADIK_IRQ_TO_GPIO(d->irq);
nmk_chip = irq_data_get_irq_chip_data(d);
- bitmask = nmk_gpio_get_bitmask(gpio);
+ bitmask = nmk_gpio_get_bitmask(d->hwirq);
if (!nmk_chip)
return -EINVAL;
-
if (type & IRQ_TYPE_LEVEL_HIGH)
return -EINVAL;
if (type & IRQ_TYPE_LEVEL_LOW)
@@ -687,10 +754,10 @@
spin_lock_irqsave(&nmk_chip->lock, flags);
if (enabled)
- __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, false);
+ __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, false);
if (enabled || wake)
- __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, false);
+ __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, false);
nmk_chip->edge_rising &= ~bitmask;
if (type & IRQ_TYPE_EDGE_RISING)
@@ -701,10 +768,10 @@
nmk_chip->edge_falling |= bitmask;
if (enabled)
- __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, true);
+ __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, true);
if (enabled || wake)
- __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, true);
+ __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, true);
spin_unlock_irqrestore(&nmk_chip->lock, flags);
clk_disable(nmk_chip->clk);
@@ -750,7 +817,7 @@
chained_irq_enter(host_chip, desc);
nmk_chip = irq_get_handler_data(irq);
- first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
+ first_irq = nmk_chip->domain->revmap_data.legacy.first_irq;
while (status) {
int bit = __ffs(status);
@@ -784,18 +851,6 @@
static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip)
{
- unsigned int first_irq;
- int i;
-
- first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
- for (i = first_irq; i < first_irq + nmk_chip->chip.ngpio; i++) {
- irq_set_chip_and_handler(i, &nmk_gpio_irq_chip,
- handle_edge_irq);
- set_irq_flags(i, IRQF_VALID);
- irq_set_chip_data(i, nmk_chip);
- irq_set_irq_type(i, IRQ_TYPE_EDGE_FALLING);
- }
-
irq_set_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler);
irq_set_handler_data(nmk_chip->parent_irq, nmk_chip);
@@ -872,7 +927,7 @@
struct nmk_gpio_chip *nmk_chip =
container_of(chip, struct nmk_gpio_chip, chip);
- return NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base) + offset;
+ return irq_find_mapping(nmk_chip->domain, offset);
}
#ifdef CONFIG_DEBUG_FS
@@ -1008,21 +1063,11 @@
clk_enable(chip->clk);
- chip->rwimsc = readl(chip->addr + NMK_GPIO_RWIMSC);
- chip->fwimsc = readl(chip->addr + NMK_GPIO_FWIMSC);
-
writel(chip->rwimsc & chip->real_wake,
chip->addr + NMK_GPIO_RWIMSC);
writel(chip->fwimsc & chip->real_wake,
chip->addr + NMK_GPIO_FWIMSC);
- if (chip->sleepmode) {
- chip->slpm = readl(chip->addr + NMK_GPIO_SLPC);
-
- /* 0 -> wakeup enable */
- writel(~chip->real_wake, chip->addr + NMK_GPIO_SLPC);
- }
-
clk_disable(chip->clk);
}
}
@@ -1042,9 +1087,6 @@
writel(chip->rwimsc, chip->addr + NMK_GPIO_RWIMSC);
writel(chip->fwimsc, chip->addr + NMK_GPIO_FWIMSC);
- if (chip->sleepmode)
- writel(chip->slpm, chip->addr + NMK_GPIO_SLPC);
-
clk_disable(chip->clk);
}
}
@@ -1068,19 +1110,62 @@
}
}
+int nmk_gpio_irq_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hwirq)
+{
+ struct nmk_gpio_chip *nmk_chip = d->host_data;
+
+ if (!nmk_chip)
+ return -EINVAL;
+
+ irq_set_chip_and_handler(irq, &nmk_gpio_irq_chip, handle_edge_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ irq_set_chip_data(irq, nmk_chip);
+ irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING);
+
+ return 0;
+}
+
+const struct irq_domain_ops nmk_gpio_irq_simple_ops = {
+ .map = nmk_gpio_irq_map,
+ .xlate = irq_domain_xlate_twocell,
+};
+
static int __devinit nmk_gpio_probe(struct platform_device *dev)
{
struct nmk_gpio_platform_data *pdata = dev->dev.platform_data;
+ struct device_node *np = dev->dev.of_node;
struct nmk_gpio_chip *nmk_chip;
struct gpio_chip *chip;
struct resource *res;
struct clk *clk;
int secondary_irq;
+ void __iomem *base;
int irq;
int ret;
- if (!pdata)
+ if (!pdata && !np) {
+ dev_err(&dev->dev, "No platform data or device tree found\n");
return -ENODEV;
+ }
+
+ if (np) {
+ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ if (of_get_property(np, "supports-sleepmode", NULL))
+ pdata->supports_sleepmode = true;
+
+ if (of_property_read_u32(np, "gpio-bank", &dev->id)) {
+ dev_err(&dev->dev, "gpio-bank property not found\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ pdata->first_gpio = dev->id * NMK_GPIO_PER_CHIP;
+ pdata->num_gpio = NMK_GPIO_PER_CHIP;
+ }
res = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (!res) {
@@ -1106,10 +1191,16 @@
goto out;
}
+ base = ioremap(res->start, resource_size(res));
+ if (!base) {
+ ret = -ENOMEM;
+ goto out_release;
+ }
+
clk = clk_get(&dev->dev, NULL);
if (IS_ERR(clk)) {
ret = PTR_ERR(clk);
- goto out_release;
+ goto out_unmap;
}
nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL);
@@ -1117,13 +1208,14 @@
ret = -ENOMEM;
goto out_clk;
}
+
/*
* The virt address in nmk_chip->addr is in the nomadik register space,
* so we can simply convert the resource address, without remapping
*/
nmk_chip->bank = dev->id;
nmk_chip->clk = clk;
- nmk_chip->addr = io_p2v(res->start);
+ nmk_chip->addr = base;
nmk_chip->chip = nmk_gpio_template;
nmk_chip->parent_irq = irq;
nmk_chip->secondary_parent_irq = secondary_irq;
@@ -1139,6 +1231,12 @@
chip->dev = &dev->dev;
chip->owner = THIS_MODULE;
+ clk_enable(nmk_chip->clk);
+ nmk_chip->lowemi = readl_relaxed(nmk_chip->addr + NMK_GPIO_LOWEMI);
+ clk_disable(nmk_chip->clk);
+
+ chip->of_node = np;
+
ret = gpiochip_add(&nmk_chip->chip);
if (ret)
goto out_free;
@@ -1146,12 +1244,22 @@
BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips));
nmk_gpio_chips[nmk_chip->bank] = nmk_chip;
+
platform_set_drvdata(dev, nmk_chip);
+ nmk_chip->domain = irq_domain_add_legacy(np, NMK_GPIO_PER_CHIP,
+ NOMADIK_GPIO_TO_IRQ(pdata->first_gpio),
+ 0, &nmk_gpio_irq_simple_ops, nmk_chip);
+ if (!nmk_chip->domain) {
+ pr_err("%s: Failed to create irqdomain\n", np->full_name);
+ ret = -ENOSYS;
+ goto out_free;
+ }
+
nmk_gpio_init_irq(nmk_chip);
- dev_info(&dev->dev, "at address %p\n",
- nmk_chip->addr);
+ dev_info(&dev->dev, "at address %p\n", nmk_chip->addr);
+
return 0;
out_free:
@@ -1159,18 +1267,29 @@
out_clk:
clk_disable(clk);
clk_put(clk);
+out_unmap:
+ iounmap(base);
out_release:
release_mem_region(res->start, resource_size(res));
out:
dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret,
pdata->first_gpio, pdata->first_gpio+31);
+ if (np)
+ kfree(pdata);
+
return ret;
}
+static const struct of_device_id nmk_gpio_match[] = {
+ { .compatible = "st,nomadik-gpio", },
+ {}
+};
+
static struct platform_driver nmk_gpio_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "gpio",
+ .of_match_table = nmk_gpio_match,
},
.probe = nmk_gpio_probe,
};
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index 30372f7..348b367 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -1510,8 +1510,8 @@
* \param arg pointer to a drm_buf_map structure.
* \return zero on success or a negative number on failure.
*
- * Maps the AGP, SG or PCI buffer region with do_mmap(), and copies information
- * about each buffer into user space. For PCI buffers, it calls do_mmap() with
+ * Maps the AGP, SG or PCI buffer region with vm_mmap(), and copies information
+ * about each buffer into user space. For PCI buffers, it calls vm_mmap() with
* offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls
* drm_mmap_dma().
*/
@@ -1553,18 +1553,14 @@
retcode = -EINVAL;
goto done;
}
- down_write(¤t->mm->mmap_sem);
- virtual = do_mmap(file_priv->filp, 0, map->size,
+ virtual = vm_mmap(file_priv->filp, 0, map->size,
PROT_READ | PROT_WRITE,
MAP_SHARED,
token);
- up_write(¤t->mm->mmap_sem);
} else {
- down_write(¤t->mm->mmap_sem);
- virtual = do_mmap(file_priv->filp, 0, dma->byte_count,
+ virtual = vm_mmap(file_priv->filp, 0, dma->byte_count,
PROT_READ | PROT_WRITE,
MAP_SHARED, 0);
- up_write(¤t->mm->mmap_sem);
}
if (virtual > -1024UL) {
/* Real error */
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index d3aaeb6..c79870a 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3335,10 +3335,12 @@
ret = crtc->funcs->page_flip(crtc, fb, e);
if (ret) {
- spin_lock_irqsave(&dev->event_lock, flags);
- file_priv->event_space += sizeof e->event;
- spin_unlock_irqrestore(&dev->event_lock, flags);
- kfree(e);
+ if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
+ spin_lock_irqsave(&dev->event_lock, flags);
+ file_priv->event_space += sizeof e->event;
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ kfree(e);
+ }
}
out:
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index cdfbf27..123de28 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -507,12 +507,12 @@
drm_events_release(file_priv);
- if (dev->driver->driver_features & DRIVER_GEM)
- drm_gem_release(dev, file_priv);
-
if (dev->driver->driver_features & DRIVER_MODESET)
drm_fb_release(file_priv);
+ if (dev->driver->driver_features & DRIVER_GEM)
+ drm_gem_release(dev, file_priv);
+
mutex_lock(&dev->ctxlist_mutex);
if (!list_empty(&dev->ctxlist)) {
struct drm_ctx_list *pos, *n;
diff --git a/drivers/gpu/drm/drm_usb.c b/drivers/gpu/drm/drm_usb.c
index c8c83da..37c9a52 100644
--- a/drivers/gpu/drm/drm_usb.c
+++ b/drivers/gpu/drm/drm_usb.c
@@ -1,6 +1,6 @@
#include "drmP.h"
#include <linux/usb.h>
-#include <linux/export.h>
+#include <linux/module.h>
int drm_get_usb_dev(struct usb_interface *interface,
const struct usb_device_id *id,
@@ -114,3 +114,7 @@
usb_deregister(udriver);
}
EXPORT_SYMBOL(drm_usb_exit);
+
+MODULE_AUTHOR("David Airlie");
+MODULE_DESCRIPTION("USB DRM support");
+MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 26d5197..392ce71 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -581,10 +581,8 @@
obj->filp->f_op = &exynos_drm_gem_fops;
obj->filp->private_data = obj;
- down_write(¤t->mm->mmap_sem);
- addr = do_mmap(obj->filp, 0, args->size,
+ addr = vm_mmap(obj->filp, 0, args->size,
PROT_READ | PROT_WRITE, MAP_SHARED, 0);
- up_write(¤t->mm->mmap_sem);
drm_gem_object_unreference_unlocked(obj);
diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.h b/drivers/gpu/drm/gma500/mdfld_dsi_output.h
index 21071ce..36eb074 100644
--- a/drivers/gpu/drm/gma500/mdfld_dsi_output.h
+++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.h
@@ -29,7 +29,6 @@
#define __MDFLD_DSI_OUTPUT_H__
#include <linux/backlight.h>
-#include <linux/version.h>
#include <drm/drmP.h>
#include <drm/drm.h>
#include <drm/drm_crtc.h>
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c
index 2c8a60c..f920fb5 100644
--- a/drivers/gpu/drm/i810/i810_dma.c
+++ b/drivers/gpu/drm/i810/i810_dma.c
@@ -129,6 +129,7 @@
if (buf_priv->currently_mapped == I810_BUF_MAPPED)
return -EINVAL;
+ /* This is all entirely broken */
down_write(¤t->mm->mmap_sem);
old_fops = file_priv->filp->f_op;
file_priv->filp->f_op = &i810_buffer_fops;
@@ -157,11 +158,8 @@
if (buf_priv->currently_mapped != I810_BUF_MAPPED)
return -EINVAL;
- down_write(¤t->mm->mmap_sem);
- retcode = do_munmap(current->mm,
- (unsigned long)buf_priv->virtual,
+ retcode = vm_munmap((unsigned long)buf_priv->virtual,
(size_t) buf->total);
- up_write(¤t->mm->mmap_sem);
buf_priv->currently_mapped = I810_BUF_UNMAPPED;
buf_priv->virtual = NULL;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 0e3c6ac..0d1e4b7 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1087,11 +1087,9 @@
if (obj == NULL)
return -ENOENT;
- down_write(¤t->mm->mmap_sem);
- addr = do_mmap(obj->filp, 0, args->size,
+ addr = vm_mmap(obj->filp, 0, args->size,
PROT_READ | PROT_WRITE, MAP_SHARED,
args->offset);
- up_write(¤t->mm->mmap_sem);
drm_gem_object_unreference_unlocked(obj);
if (IS_ERR((void *)addr))
return addr;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index bae38ac..5908cd5 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3478,8 +3478,11 @@
return false;
}
- /* All interlaced capable intel hw wants timings in frames. */
- drm_mode_set_crtcinfo(adjusted_mode, 0);
+ /* All interlaced capable intel hw wants timings in frames. Note though
+ * that intel_lvds_mode_fixup does some funny tricks with the crtc
+ * timings, so we need to be careful not to clobber these.*/
+ if (!(adjusted_mode->private_flags & INTEL_MODE_CRTC_TIMINGS_SET))
+ drm_mode_set_crtcinfo(adjusted_mode, 0);
return true;
}
@@ -7465,7 +7468,13 @@
OUT_RING(fb->pitches[0] | obj->tiling_mode);
OUT_RING(obj->gtt_offset);
- pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE;
+ /* Contrary to the suggestions in the documentation,
+ * "Enable Panel Fitter" does not seem to be required when page
+ * flipping with a non-native mode, and worse causes a normal
+ * modeset to fail.
+ * pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE;
+ */
+ pf = 0;
pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
OUT_RING(pf | pipesrc);
ADVANCE_LP_RING();
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 5a14149..715afa1 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -105,6 +105,10 @@
#define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0)
#define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT)
#define INTEL_MODE_DP_FORCE_6BPC (0x10)
+/* This flag must be set by the encoder's mode_fixup if it changes the crtc
+ * timings in the mode to prevent the crtc fixup from overwriting them.
+ * Currently only lvds needs that. */
+#define INTEL_MODE_CRTC_TIMINGS_SET (0x20)
static inline void
intel_mode_set_pixel_multiplier(struct drm_display_mode *mode,
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index 19ecd78..6e9ee33 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -279,6 +279,8 @@
struct drm_mode_config *config = &dev->mode_config;
struct drm_plane *plane;
+ mutex_lock(&dev->mode_config.mutex);
+
ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper);
if (ret)
DRM_DEBUG("failed to restore crtc mode\n");
@@ -286,4 +288,6 @@
/* Be sure to shut off any planes that may be active */
list_for_each_entry(plane, &config->plane_list, head)
plane->funcs->disable_plane(plane);
+
+ mutex_unlock(&dev->mode_config.mutex);
}
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 95db2e9..30e2c82 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -187,6 +187,8 @@
mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos;
mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width;
+
+ mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET;
}
static void
@@ -208,6 +210,8 @@
mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos;
mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width;
+
+ mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET;
}
static inline u32 panel_fitter_scaling(u32 source, u32 target)
@@ -283,6 +287,8 @@
for_each_pipe(pipe)
I915_WRITE(BCLRPAT(pipe), 0);
+ drm_mode_set_crtcinfo(adjusted_mode, 0);
+
switch (intel_lvds->fitting_mode) {
case DRM_MODE_SCALE_CENTER:
/*
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 230a141..48177ec 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -47,8 +47,6 @@
adjusted_mode->vtotal = fixed_mode->vtotal;
adjusted_mode->clock = fixed_mode->clock;
-
- drm_mode_set_crtcinfo(adjusted_mode, 0);
}
/* adjusted_mode has been preset to be the panel's fixed mode */
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
index 34d591b..da3e7c3 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -235,6 +235,7 @@
return -EPERM;
strncpy(string, profile, sizeof(string));
+ string[sizeof(string) - 1] = 0;
if ((ptr = strchr(string, '\n')))
*ptr = '\0';
diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c
index a7844ab..2746402 100644
--- a/drivers/gpu/drm/nouveau/nv50_sor.c
+++ b/drivers/gpu/drm/nouveau/nv50_sor.c
@@ -42,7 +42,7 @@
struct drm_nouveau_private *dev_priv = dev->dev_private;
static const u8 nvaf[] = { 24, 16, 8, 0 }; /* thanks, apple.. */
static const u8 nv50[] = { 16, 8, 0, 24 };
- if (dev_priv->card_type == 0xaf)
+ if (dev_priv->chipset == 0xaf)
return nvaf[lane];
return nv50[lane];
}
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index de71243..c8187c4 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -1135,7 +1135,7 @@
}
if (rdev->flags & RADEON_IS_AGP) {
size_bf = mc->gtt_start;
- size_af = 0xFFFFFFFF - mc->gtt_end + 1;
+ size_af = 0xFFFFFFFF - mc->gtt_end;
if (size_bf > size_af) {
if (mc->mc_vram_size > size_bf) {
dev_warn(rdev->dev, "limiting VRAM\n");
@@ -1149,7 +1149,7 @@
mc->real_vram_size = size_af;
mc->mc_vram_size = size_af;
}
- mc->vram_start = mc->gtt_end;
+ mc->vram_start = mc->gtt_end + 1;
}
mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n",
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index bd05156..3c2e7a0 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -970,7 +970,7 @@
encoder = obj_to_encoder(obj);
- if (encoder->encoder_type != DRM_MODE_ENCODER_DAC ||
+ if (encoder->encoder_type != DRM_MODE_ENCODER_DAC &&
encoder->encoder_type != DRM_MODE_ENCODER_TVDAC)
continue;
@@ -1000,6 +1000,7 @@
* cases the DVI port is actually a virtual KVM port connected to the service
* processor.
*/
+out:
if ((!rdev->is_atom_bios) &&
(ret == connector_status_disconnected) &&
rdev->mode_info.bios_hardcoded_edid_size) {
@@ -1007,7 +1008,6 @@
ret = connector_status_connected;
}
-out:
/* updated in get modes as well since we need to know if it's analog or digital */
radeon_connector_update_scratch_regs(connector, ret);
return ret;
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index 66d5fe1..65060b7 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -147,6 +147,12 @@
(rdev->pdev->subsystem_device == 0x01fd))
return true;
+ /* RV515 seems to have MSI issues where it loses
+ * MSI rearms occasionally. This leads to lockups and freezes.
+ * disable it by default.
+ */
+ if (rdev->family == CHIP_RV515)
+ return false;
if (rdev->flags & RADEON_IS_IGP) {
/* APUs work fine with MSIs */
if (rdev->family >= CHIP_PALM)
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index c62ae4b..cdab1ae 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -969,7 +969,7 @@
}
if (rdev->flags & RADEON_IS_AGP) {
size_bf = mc->gtt_start;
- size_af = 0xFFFFFFFF - mc->gtt_end + 1;
+ size_af = 0xFFFFFFFF - mc->gtt_end;
if (size_bf > size_af) {
if (mc->mc_vram_size > size_bf) {
dev_warn(rdev->dev, "limiting VRAM\n");
@@ -983,7 +983,7 @@
mc->real_vram_size = size_af;
mc->mc_vram_size = size_af;
}
- mc->vram_start = mc->gtt_end;
+ mc->vram_start = mc->gtt_end + 1;
}
mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n",
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index ac7a199..27bda98 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -2999,8 +2999,8 @@
}
r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM,
&rdev->rlc.save_restore_gpu_addr);
+ radeon_bo_unreserve(rdev->rlc.save_restore_obj);
if (r) {
- radeon_bo_unreserve(rdev->rlc.save_restore_obj);
dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r);
si_rlc_fini(rdev);
return r;
@@ -3023,9 +3023,8 @@
}
r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM,
&rdev->rlc.clear_state_gpu_addr);
+ radeon_bo_unreserve(rdev->rlc.clear_state_obj);
if (r) {
-
- radeon_bo_unreserve(rdev->rlc.clear_state_obj);
dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r);
si_rlc_fini(rdev);
return r;
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index a3d0332..ffddcba 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -34,7 +34,7 @@
config HID_BATTERY_STRENGTH
bool
depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY
- default y
+ default n
config HIDRAW
bool "/dev/hidraw raw HID device support"
diff --git a/drivers/hid/hid-tivo.c b/drivers/hid/hid-tivo.c
index de47039..9f85f82 100644
--- a/drivers/hid/hid-tivo.c
+++ b/drivers/hid/hid-tivo.c
@@ -62,7 +62,7 @@
static const struct hid_device_id tivo_devices[] = {
/* TiVo Slide Bluetooth remote, pairs with a Broadcom dongle */
- { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) },
{ }
};
diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c
index 7765e4f..1958f03 100644
--- a/drivers/hwmon/ads1015.c
+++ b/drivers/hwmon/ads1015.c
@@ -59,14 +59,11 @@
struct ads1015_channel_data channel_data[ADS1015_CHANNELS];
};
-static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
- int *value)
+static int ads1015_read_adc(struct i2c_client *client, unsigned int channel)
{
u16 config;
- s16 conversion;
struct ads1015_data *data = i2c_get_clientdata(client);
unsigned int pga = data->channel_data[channel].pga;
- int fullscale;
unsigned int data_rate = data->channel_data[channel].data_rate;
unsigned int conversion_time_ms;
int res;
@@ -78,7 +75,6 @@
if (res < 0)
goto err_unlock;
config = res;
- fullscale = fullscale_table[pga];
conversion_time_ms = DIV_ROUND_UP(1000, data_rate_table[data_rate]);
/* setup and start single conversion */
@@ -105,33 +101,36 @@
}
res = i2c_smbus_read_word_swapped(client, ADS1015_CONVERSION);
- if (res < 0)
- goto err_unlock;
- conversion = res;
-
- mutex_unlock(&data->update_lock);
-
- *value = DIV_ROUND_CLOSEST(conversion * fullscale, 0x7ff0);
-
- return 0;
err_unlock:
mutex_unlock(&data->update_lock);
return res;
}
+static int ads1015_reg_to_mv(struct i2c_client *client, unsigned int channel,
+ s16 reg)
+{
+ struct ads1015_data *data = i2c_get_clientdata(client);
+ unsigned int pga = data->channel_data[channel].pga;
+ int fullscale = fullscale_table[pga];
+
+ return DIV_ROUND_CLOSEST(reg * fullscale, 0x7ff0);
+}
+
/* sysfs callback function */
static ssize_t show_in(struct device *dev, struct device_attribute *da,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct i2c_client *client = to_i2c_client(dev);
- int in;
int res;
+ int index = attr->index;
- res = ads1015_read_value(client, attr->index, &in);
+ res = ads1015_read_adc(client, index);
+ if (res < 0)
+ return res;
- return (res < 0) ? res : sprintf(buf, "%d\n", in);
+ return sprintf(buf, "%d\n", ads1015_reg_to_mv(client, index, res));
}
static const struct sensor_device_attribute ads1015_in[] = {
diff --git a/drivers/hwmon/fam15h_power.c b/drivers/hwmon/fam15h_power.c
index b7494af..37a8fc9 100644
--- a/drivers/hwmon/fam15h_power.c
+++ b/drivers/hwmon/fam15h_power.c
@@ -122,6 +122,38 @@
return true;
}
+/*
+ * Newer BKDG versions have an updated recommendation on how to properly
+ * initialize the running average range (was: 0xE, now: 0x9). This avoids
+ * counter saturations resulting in bogus power readings.
+ * We correct this value ourselves to cope with older BIOSes.
+ */
+static void __devinit tweak_runavg_range(struct pci_dev *pdev)
+{
+ u32 val;
+ const struct pci_device_id affected_device = {
+ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) };
+
+ /*
+ * let this quirk apply only to the current version of the
+ * northbridge, since future versions may change the behavior
+ */
+ if (!pci_match_id(&affected_device, pdev))
+ return;
+
+ pci_bus_read_config_dword(pdev->bus,
+ PCI_DEVFN(PCI_SLOT(pdev->devfn), 5),
+ REG_TDP_RUNNING_AVERAGE, &val);
+ if ((val & 0xf) != 0xe)
+ return;
+
+ val &= ~0xf;
+ val |= 0x9;
+ pci_bus_write_config_dword(pdev->bus,
+ PCI_DEVFN(PCI_SLOT(pdev->devfn), 5),
+ REG_TDP_RUNNING_AVERAGE, val);
+}
+
static void __devinit fam15h_power_init_data(struct pci_dev *f4,
struct fam15h_power_data *data)
{
@@ -155,6 +187,13 @@
struct device *dev;
int err;
+ /*
+ * though we ignore every other northbridge, we still have to
+ * do the tweaking on _each_ node in MCM processors as the counters
+ * are working hand-in-hand
+ */
+ tweak_runavg_range(pdev);
+
if (!fam15h_power_is_internal_node0(pdev)) {
err = -ENODEV;
goto exit;
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 2d78779..7faf4a7 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -380,8 +380,7 @@
config INPUT_TWL6040_VIBRA
tristate "Support for TWL6040 Vibrator"
- depends on TWL4030_CORE
- select TWL6040_CORE
+ depends on TWL6040_CORE
select INPUT_FF_MEMLESS
help
This option enables support for TWL6040 Vibrator Driver.
diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c
index 45874fe..14e94f5 100644
--- a/drivers/input/misc/twl6040-vibra.c
+++ b/drivers/input/misc/twl6040-vibra.c
@@ -28,7 +28,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>
-#include <linux/i2c/twl.h>
+#include <linux/input.h>
#include <linux/mfd/twl6040.h>
#include <linux/slab.h>
#include <linux/delay.h>
@@ -257,7 +257,7 @@
static int __devinit twl6040_vibra_probe(struct platform_device *pdev)
{
- struct twl4030_vibra_data *pdata = pdev->dev.platform_data;
+ struct twl6040_vibra_data *pdata = pdev->dev.platform_data;
struct vibra_info *info;
int ret;
diff --git a/drivers/leds/leds-atmel-pwm.c b/drivers/leds/leds-atmel-pwm.c
index 800243b..64ad702 100644
--- a/drivers/leds/leds-atmel-pwm.c
+++ b/drivers/leds/leds-atmel-pwm.c
@@ -35,7 +35,7 @@
* NOTE: we reuse the platform_data structure of GPIO leds,
* but repurpose its "gpio" number as a PWM channel number.
*/
-static int __init pwmled_probe(struct platform_device *pdev)
+static int __devinit pwmled_probe(struct platform_device *pdev)
{
const struct gpio_led_platform_data *pdata;
struct pwmled *leds;
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index 7f98984..eab2ea4 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -54,6 +54,7 @@
struct list_head hybrid_tuner_instance_list;
u32 if_khz;
+ u32 xtal_khz;
u32 freq_hz;
u32 bandwidth;
u8 video_standard;
@@ -214,9 +215,9 @@
.size = 12401,
};
-static const struct xc5000_fw_cfg xc5000c_41_024_5_31875 = {
- .name = "dvb-fe-xc5000c-41.024.5-31875.fw",
- .size = 16503,
+static const struct xc5000_fw_cfg xc5000c_41_024_5 = {
+ .name = "dvb-fe-xc5000c-41.024.5.fw",
+ .size = 16497,
};
static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id)
@@ -226,7 +227,7 @@
case XC5000A:
return &xc5000a_1_6_114;
case XC5000C:
- return &xc5000c_41_024_5_31875;
+ return &xc5000c_41_024_5;
}
}
@@ -572,6 +573,31 @@
return found;
}
+static int xc_set_xtal(struct dvb_frontend *fe)
+{
+ struct xc5000_priv *priv = fe->tuner_priv;
+ int ret = XC_RESULT_SUCCESS;
+
+ switch (priv->chip_id) {
+ default:
+ case XC5000A:
+ /* 32.000 MHz xtal is default */
+ break;
+ case XC5000C:
+ switch (priv->xtal_khz) {
+ default:
+ case 32000:
+ /* 32.000 MHz xtal is default */
+ break;
+ case 31875:
+ /* 31.875 MHz xtal configuration */
+ ret = xc_write_reg(priv, 0x000f, 0x8081);
+ break;
+ }
+ break;
+ }
+ return ret;
+}
static int xc5000_fwupload(struct dvb_frontend *fe)
{
@@ -603,6 +629,8 @@
} else {
printk(KERN_INFO "xc5000: firmware uploading...\n");
ret = xc_load_i2c_sequence(fe, fw->data);
+ if (XC_RESULT_SUCCESS == ret)
+ ret = xc_set_xtal(fe);
printk(KERN_INFO "xc5000: firmware upload complete...\n");
}
@@ -1164,6 +1192,9 @@
priv->if_khz = cfg->if_khz;
}
+ if (priv->xtal_khz == 0)
+ priv->xtal_khz = cfg->xtal_khz;
+
if (priv->radio_input == 0)
priv->radio_input = cfg->radio_input;
diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h
index 3396f8e..39a73bf 100644
--- a/drivers/media/common/tuners/xc5000.h
+++ b/drivers/media/common/tuners/xc5000.h
@@ -34,6 +34,7 @@
u8 i2c_address;
u32 if_khz;
u8 radio_input;
+ u32 xtal_khz;
int chip_id;
};
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 39696c6..0f64d71 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -1446,6 +1446,28 @@
__func__);
return -EINVAL;
}
+ /*
+ * Get a delivery system that is compatible with DVBv3
+ * NOTE: in order for this to work with softwares like Kaffeine that
+ * uses a DVBv5 call for DVB-S2 and a DVBv3 call to go back to
+ * DVB-S, drivers that support both should put the SYS_DVBS entry
+ * before the SYS_DVBS2, otherwise it won't switch back to DVB-S.
+ * The real fix is that userspace applications should not use DVBv3
+ * and not trust on calling FE_SET_FRONTEND to switch the delivery
+ * system.
+ */
+ ncaps = 0;
+ while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
+ if (fe->ops.delsys[ncaps] == desired_system) {
+ delsys = desired_system;
+ break;
+ }
+ ncaps++;
+ }
+ if (delsys == SYS_UNDEFINED) {
+ dprintk("%s() Couldn't find a delivery system that matches %d\n",
+ __func__, desired_system);
+ }
} else {
/*
* This is a DVBv5 call. So, it likely knows the supported
@@ -1494,9 +1516,10 @@
__func__);
return -EINVAL;
}
- c->delivery_system = delsys;
}
+ c->delivery_system = delsys;
+
/*
* The DVBv3 or DVBv5 call is requesting a different system. So,
* emulation is needed.
diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c
index 36d1175..a414b1f 100644
--- a/drivers/media/dvb/frontends/drxk_hard.c
+++ b/drivers/media/dvb/frontends/drxk_hard.c
@@ -1520,8 +1520,10 @@
dprintk(1, "\n");
if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
- ((resultLen > 0) && (result == NULL)))
- goto error;
+ ((resultLen > 0) && (result == NULL))) {
+ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ return status;
+ }
mutex_lock(&state->mutex);
diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c
index b09c5fa..af52658 100644
--- a/drivers/media/rc/winbond-cir.c
+++ b/drivers/media/rc/winbond-cir.c
@@ -1046,6 +1046,7 @@
goto exit_unregister_led;
}
+ data->dev->driver_type = RC_DRIVER_IR_RAW;
data->dev->driver_name = WBCIR_NAME;
data->dev->input_name = WBCIR_NAME;
data->dev->input_phys = "wbcir/cir0";
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index f2479c5..ce1e7ba 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -492,7 +492,7 @@
config VIDEO_MT9M032
tristate "MT9M032 camera sensor support"
- depends on I2C && VIDEO_V4L2
+ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
select VIDEO_APTINA_PLL
---help---
This driver supports MT9M032 camera sensors from Aptina, monochrome
diff --git a/drivers/media/video/mt9m032.c b/drivers/media/video/mt9m032.c
index 7636672..645973c 100644
--- a/drivers/media/video/mt9m032.c
+++ b/drivers/media/video/mt9m032.c
@@ -392,10 +392,11 @@
}
/* Scaling is not supported, the format is thus fixed. */
- ret = mt9m032_get_pad_format(subdev, fh, fmt);
+ fmt->format = *__mt9m032_get_pad_format(sensor, fh, fmt->which);
+ ret = 0;
done:
- mutex_lock(&sensor->lock);
+ mutex_unlock(&sensor->lock);
return ret;
}
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 29f463c..11e44386 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -268,10 +268,17 @@
This is used to control charging LED brightness.
config TWL6040_CORE
- bool
- depends on TWL4030_CORE && GENERIC_HARDIRQS
+ bool "Support for TWL6040 audio codec"
+ depends on I2C=y && GENERIC_HARDIRQS
select MFD_CORE
+ select REGMAP_I2C
default n
+ help
+ Say yes here if you want support for Texas Instruments TWL6040 audio
+ codec.
+ This driver provides common support for accessing the device,
+ additional drivers must be enabled in order to use the
+ functionality of the device (audio, vibra).
config MFD_STMPE
bool "Support STMicroelectronics STMPE"
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
index 1895cf9..1582c3d 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -527,7 +527,9 @@
static int asic3_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
- return (offset < ASIC3_NUM_GPIOS) ? IRQ_BOARD_START + offset : -ENXIO;
+ struct asic3 *asic = container_of(chip, struct asic3, gpio);
+
+ return (offset < ASIC3_NUM_GPIOS) ? asic->irq_base + offset : -ENXIO;
}
static __init int asic3_gpio_probe(struct platform_device *pdev,
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 95a2e54..c8aae66 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -25,7 +25,6 @@
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/spinlock.h>
-#include <linux/gpio.h>
#include <plat/usb.h>
#include <linux/pm_runtime.h>
@@ -502,19 +501,6 @@
pm_runtime_get_sync(dev);
spin_lock_irqsave(&omap->lock, flags);
- if (pdata->ehci_data->phy_reset) {
- if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
- gpio_request_one(pdata->ehci_data->reset_gpio_port[0],
- GPIOF_OUT_INIT_LOW, "USB1 PHY reset");
-
- if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
- gpio_request_one(pdata->ehci_data->reset_gpio_port[1],
- GPIOF_OUT_INIT_LOW, "USB2 PHY reset");
-
- /* Hold the PHY in RESET for enough time till DIR is high */
- udelay(10);
- }
-
omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
@@ -593,39 +579,10 @@
usbhs_omap_tll_init(dev, OMAP_TLL_CHANNEL_COUNT);
}
- if (pdata->ehci_data->phy_reset) {
- /* Hold the PHY in RESET for enough time till
- * PHY is settled and ready
- */
- udelay(10);
-
- if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
- gpio_set_value
- (pdata->ehci_data->reset_gpio_port[0], 1);
-
- if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
- gpio_set_value
- (pdata->ehci_data->reset_gpio_port[1], 1);
- }
-
spin_unlock_irqrestore(&omap->lock, flags);
pm_runtime_put_sync(dev);
}
-static void omap_usbhs_deinit(struct device *dev)
-{
- struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
- struct usbhs_omap_platform_data *pdata = &omap->platdata;
-
- if (pdata->ehci_data->phy_reset) {
- if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
- gpio_free(pdata->ehci_data->reset_gpio_port[0]);
-
- if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
- gpio_free(pdata->ehci_data->reset_gpio_port[1]);
- }
-}
-
/**
* usbhs_omap_probe - initialize TI-based HCDs
@@ -860,7 +817,6 @@
{
struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
- omap_usbhs_deinit(&pdev->dev);
iounmap(omap->tll_base);
iounmap(omap->uhh_base);
clk_put(omap->init_60m_fclk);
diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c
index 99ef944..44afae0 100644
--- a/drivers/mfd/rc5t583.c
+++ b/drivers/mfd/rc5t583.c
@@ -80,44 +80,6 @@
{.name = "rc5t583-key", }
};
-int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
- return regmap_write(rc5t583->regmap, reg, val);
-}
-
-int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
- unsigned int ival;
- int ret;
- ret = regmap_read(rc5t583->regmap, reg, &ival);
- if (!ret)
- *val = (uint8_t)ival;
- return ret;
-}
-
-int rc5t583_set_bits(struct device *dev, unsigned int reg,
- unsigned int bit_mask)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
- return regmap_update_bits(rc5t583->regmap, reg, bit_mask, bit_mask);
-}
-
-int rc5t583_clear_bits(struct device *dev, unsigned int reg,
- unsigned int bit_mask)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
- return regmap_update_bits(rc5t583->regmap, reg, bit_mask, 0);
-}
-
-int rc5t583_update(struct device *dev, unsigned int reg,
- unsigned int val, unsigned int mask)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
- return regmap_update_bits(rc5t583->regmap, reg, mask, val);
-}
-
static int __rc5t583_set_ext_pwrreq1_control(struct device *dev,
int id, int ext_pwr, int slots)
{
@@ -197,6 +159,7 @@
ds_id, ext_pwr_req);
return 0;
}
+EXPORT_SYMBOL(rc5t583_ext_power_req_config);
static int rc5t583_clear_ext_power_req(struct rc5t583 *rc5t583,
struct rc5t583_platform_data *pdata)
diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c
index b2d8e51..2d6beda 100644
--- a/drivers/mfd/twl6040-core.c
+++ b/drivers/mfd/twl6040-core.c
@@ -30,7 +30,9 @@
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/delay.h>
-#include <linux/i2c/twl.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/err.h>
#include <linux/mfd/core.h>
#include <linux/mfd/twl6040.h>
@@ -39,7 +41,7 @@
int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg)
{
int ret;
- u8 val = 0;
+ unsigned int val;
mutex_lock(&twl6040->io_mutex);
/* Vibra control registers from cache */
@@ -47,7 +49,7 @@
reg == TWL6040_REG_VIBCTLR)) {
val = twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)];
} else {
- ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg);
+ ret = regmap_read(twl6040->regmap, reg, &val);
if (ret < 0) {
mutex_unlock(&twl6040->io_mutex);
return ret;
@@ -64,7 +66,7 @@
int ret;
mutex_lock(&twl6040->io_mutex);
- ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg);
+ ret = regmap_write(twl6040->regmap, reg, val);
/* Cache the vibra control registers */
if (reg == TWL6040_REG_VIBCTLL || reg == TWL6040_REG_VIBCTLR)
twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)] = val;
@@ -77,16 +79,9 @@
int twl6040_set_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask)
{
int ret;
- u8 val;
mutex_lock(&twl6040->io_mutex);
- ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg);
- if (ret)
- goto out;
-
- val |= mask;
- ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg);
-out:
+ ret = regmap_update_bits(twl6040->regmap, reg, mask, mask);
mutex_unlock(&twl6040->io_mutex);
return ret;
}
@@ -95,16 +90,9 @@
int twl6040_clear_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask)
{
int ret;
- u8 val;
mutex_lock(&twl6040->io_mutex);
- ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg);
- if (ret)
- goto out;
-
- val &= ~mask;
- ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg);
-out:
+ ret = regmap_update_bits(twl6040->regmap, reg, mask, 0);
mutex_unlock(&twl6040->io_mutex);
return ret;
}
@@ -494,32 +482,58 @@
},
};
-static int __devinit twl6040_probe(struct platform_device *pdev)
+static bool twl6040_readable_reg(struct device *dev, unsigned int reg)
{
- struct twl4030_audio_data *pdata = pdev->dev.platform_data;
+ /* Register 0 is not readable */
+ if (!reg)
+ return false;
+ return true;
+}
+
+static struct regmap_config twl6040_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = TWL6040_REG_STATUS, /* 0x2e */
+
+ .readable_reg = twl6040_readable_reg,
+};
+
+static int __devinit twl6040_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct twl6040_platform_data *pdata = client->dev.platform_data;
struct twl6040 *twl6040;
struct mfd_cell *cell = NULL;
int ret, children = 0;
if (!pdata) {
- dev_err(&pdev->dev, "Platform data is missing\n");
+ dev_err(&client->dev, "Platform data is missing\n");
return -EINVAL;
}
/* In order to operate correctly we need valid interrupt config */
- if (!pdata->naudint_irq || !pdata->irq_base) {
- dev_err(&pdev->dev, "Invalid IRQ configuration\n");
+ if (!client->irq || !pdata->irq_base) {
+ dev_err(&client->dev, "Invalid IRQ configuration\n");
return -EINVAL;
}
- twl6040 = kzalloc(sizeof(struct twl6040), GFP_KERNEL);
- if (!twl6040)
- return -ENOMEM;
+ twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040),
+ GFP_KERNEL);
+ if (!twl6040) {
+ ret = -ENOMEM;
+ goto err;
+ }
- platform_set_drvdata(pdev, twl6040);
+ twl6040->regmap = regmap_init_i2c(client, &twl6040_regmap_config);
+ if (IS_ERR(twl6040->regmap)) {
+ ret = PTR_ERR(twl6040->regmap);
+ goto err;
+ }
- twl6040->dev = &pdev->dev;
- twl6040->irq = pdata->naudint_irq;
+ i2c_set_clientdata(client, twl6040);
+
+ twl6040->dev = &client->dev;
+ twl6040->irq = client->irq;
twl6040->irq_base = pdata->irq_base;
mutex_init(&twl6040->mutex);
@@ -588,12 +602,12 @@
}
if (children) {
- ret = mfd_add_devices(&pdev->dev, pdev->id, twl6040->cells,
+ ret = mfd_add_devices(&client->dev, -1, twl6040->cells,
children, NULL, 0);
if (ret)
goto mfd_err;
} else {
- dev_err(&pdev->dev, "No platform data found for children\n");
+ dev_err(&client->dev, "No platform data found for children\n");
ret = -ENODEV;
goto mfd_err;
}
@@ -608,14 +622,15 @@
if (gpio_is_valid(twl6040->audpwron))
gpio_free(twl6040->audpwron);
gpio1_err:
- platform_set_drvdata(pdev, NULL);
- kfree(twl6040);
+ i2c_set_clientdata(client, NULL);
+ regmap_exit(twl6040->regmap);
+err:
return ret;
}
-static int __devexit twl6040_remove(struct platform_device *pdev)
+static int __devexit twl6040_remove(struct i2c_client *client)
{
- struct twl6040 *twl6040 = platform_get_drvdata(pdev);
+ struct twl6040 *twl6040 = i2c_get_clientdata(client);
if (twl6040->power_count)
twl6040_power(twl6040, 0);
@@ -626,23 +641,30 @@
free_irq(twl6040->irq_base + TWL6040_IRQ_READY, twl6040);
twl6040_irq_exit(twl6040);
- mfd_remove_devices(&pdev->dev);
- platform_set_drvdata(pdev, NULL);
- kfree(twl6040);
+ mfd_remove_devices(&client->dev);
+ i2c_set_clientdata(client, NULL);
+ regmap_exit(twl6040->regmap);
return 0;
}
-static struct platform_driver twl6040_driver = {
+static const struct i2c_device_id twl6040_i2c_id[] = {
+ { "twl6040", 0, },
+ { },
+};
+MODULE_DEVICE_TABLE(i2c, twl6040_i2c_id);
+
+static struct i2c_driver twl6040_driver = {
+ .driver = {
+ .name = "twl6040",
+ .owner = THIS_MODULE,
+ },
.probe = twl6040_probe,
.remove = __devexit_p(twl6040_remove),
- .driver = {
- .owner = THIS_MODULE,
- .name = "twl6040",
- },
+ .id_table = twl6040_i2c_id,
};
-module_platform_driver(twl6040_driver);
+module_i2c_driver(twl6040_driver);
MODULE_DESCRIPTION("TWL6040 MFD");
MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>");
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index b180965..dabec55 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -873,7 +873,7 @@
{
struct mmc_blk_data *md = mq->data;
struct mmc_card *card = md->queue.card;
- unsigned int from, nr, arg;
+ unsigned int from, nr, arg, trim_arg, erase_arg;
int err = 0, type = MMC_BLK_SECDISCARD;
if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) {
@@ -881,20 +881,26 @@
goto out;
}
- /* The sanitize operation is supported at v4.5 only */
- if (mmc_can_sanitize(card)) {
- err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_SANITIZE_START, 1, 0);
- goto out;
- }
-
from = blk_rq_pos(req);
nr = blk_rq_sectors(req);
- if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr))
- arg = MMC_SECURE_TRIM1_ARG;
- else
- arg = MMC_SECURE_ERASE_ARG;
+ /* The sanitize operation is supported at v4.5 only */
+ if (mmc_can_sanitize(card)) {
+ erase_arg = MMC_ERASE_ARG;
+ trim_arg = MMC_TRIM_ARG;
+ } else {
+ erase_arg = MMC_SECURE_ERASE_ARG;
+ trim_arg = MMC_SECURE_TRIM1_ARG;
+ }
+
+ if (mmc_erase_group_aligned(card, from, nr))
+ arg = erase_arg;
+ else if (mmc_can_trim(card))
+ arg = trim_arg;
+ else {
+ err = -EINVAL;
+ goto out;
+ }
retry:
if (card->quirks & MMC_QUIRK_INAND_CMD38) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
@@ -904,25 +910,41 @@
INAND_CMD38_ARG_SECERASE,
0);
if (err)
- goto out;
+ goto out_retry;
}
+
err = mmc_erase(card, from, nr, arg);
- if (!err && arg == MMC_SECURE_TRIM1_ARG) {
+ if (err == -EIO)
+ goto out_retry;
+ if (err)
+ goto out;
+
+ if (arg == MMC_SECURE_TRIM1_ARG) {
if (card->quirks & MMC_QUIRK_INAND_CMD38) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
INAND_CMD38_ARG_EXT_CSD,
INAND_CMD38_ARG_SECTRIM2,
0);
if (err)
- goto out;
+ goto out_retry;
}
+
err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG);
+ if (err == -EIO)
+ goto out_retry;
+ if (err)
+ goto out;
}
-out:
- if (err == -EIO && !mmc_blk_reset(md, card->host, type))
+
+ if (mmc_can_sanitize(card))
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_SANITIZE_START, 1, 0);
+out_retry:
+ if (err && !mmc_blk_reset(md, card->host, type))
goto retry;
if (!err)
mmc_blk_reset_success(md, type);
+out:
spin_lock_irq(&md->lock);
__blk_end_request(req, err, blk_rq_bytes(req));
spin_unlock_irq(&md->lock);
@@ -1802,7 +1824,7 @@
}
#ifdef CONFIG_PM
-static int mmc_blk_suspend(struct mmc_card *card, pm_message_t state)
+static int mmc_blk_suspend(struct mmc_card *card)
{
struct mmc_blk_data *part_md;
struct mmc_blk_data *md = mmc_get_drvdata(card);
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 2517547..996f8e3 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -139,7 +139,7 @@
queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
q->limits.max_discard_sectors = max_discard;
- if (card->erased_byte == 0)
+ if (card->erased_byte == 0 && !mmc_can_discard(card))
q->limits.discard_zeroes_data = 1;
q->limits.discard_granularity = card->pref_erase << 9;
/* granularity must not be greater than max. discard */
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index 3f60606..c60cee9 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -122,14 +122,14 @@
return 0;
}
-static int mmc_bus_suspend(struct device *dev, pm_message_t state)
+static int mmc_bus_suspend(struct device *dev)
{
struct mmc_driver *drv = to_mmc_driver(dev->driver);
struct mmc_card *card = mmc_dev_to_card(dev);
int ret = 0;
if (dev->driver && drv->suspend)
- ret = drv->suspend(card, state);
+ ret = drv->suspend(card);
return ret;
}
@@ -165,20 +165,14 @@
return pm_runtime_suspend(dev);
}
-static const struct dev_pm_ops mmc_bus_pm_ops = {
- .runtime_suspend = mmc_runtime_suspend,
- .runtime_resume = mmc_runtime_resume,
- .runtime_idle = mmc_runtime_idle,
-};
-
-#define MMC_PM_OPS_PTR (&mmc_bus_pm_ops)
-
-#else /* !CONFIG_PM_RUNTIME */
-
-#define MMC_PM_OPS_PTR NULL
-
#endif /* !CONFIG_PM_RUNTIME */
+static const struct dev_pm_ops mmc_bus_pm_ops = {
+ SET_RUNTIME_PM_OPS(mmc_runtime_suspend, mmc_runtime_resume,
+ mmc_runtime_idle)
+ SET_SYSTEM_SLEEP_PM_OPS(mmc_bus_suspend, mmc_bus_resume)
+};
+
static struct bus_type mmc_bus_type = {
.name = "mmc",
.dev_attrs = mmc_dev_attrs,
@@ -186,9 +180,7 @@
.uevent = mmc_bus_uevent,
.probe = mmc_bus_probe,
.remove = mmc_bus_remove,
- .suspend = mmc_bus_suspend,
- .resume = mmc_bus_resume,
- .pm = MMC_PM_OPS_PTR,
+ .pm = &mmc_bus_pm_ops,
};
int mmc_register_bus(void)
diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/cd-gpio.c
index 29de31e..2c14be7 100644
--- a/drivers/mmc/core/cd-gpio.c
+++ b/drivers/mmc/core/cd-gpio.c
@@ -12,6 +12,7 @@
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/jiffies.h>
+#include <linux/mmc/cd-gpio.h>
#include <linux/mmc/host.h>
#include <linux/module.h>
#include <linux/slab.h>
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 7474c47..ba821fe 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1409,7 +1409,10 @@
{
unsigned int erase_timeout;
- if (card->ext_csd.erase_group_def & 1) {
+ if (arg == MMC_DISCARD_ARG ||
+ (arg == MMC_TRIM_ARG && card->ext_csd.rev >= 6)) {
+ erase_timeout = card->ext_csd.trim_timeout;
+ } else if (card->ext_csd.erase_group_def & 1) {
/* High Capacity Erase Group Size uses HC timeouts */
if (arg == MMC_TRIM_ARG)
erase_timeout = card->ext_csd.trim_timeout;
@@ -1681,8 +1684,6 @@
{
if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN)
return 1;
- if (mmc_can_discard(card))
- return 1;
return 0;
}
EXPORT_SYMBOL(mmc_can_trim);
@@ -1701,6 +1702,8 @@
int mmc_can_sanitize(struct mmc_card *card)
{
+ if (!mmc_can_trim(card) && !mmc_can_erase(card))
+ return 0;
if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE)
return 1;
return 0;
@@ -2235,6 +2238,7 @@
mmc_card_is_removable(host))
return err;
+ mmc_claim_host(host);
if (card && mmc_card_mmc(card) &&
(card->ext_csd.cache_size > 0)) {
enable = !!enable;
@@ -2252,6 +2256,7 @@
card->ext_csd.cache_ctrl = enable;
}
}
+ mmc_release_host(host);
return err;
}
@@ -2269,49 +2274,32 @@
cancel_delayed_work(&host->detect);
mmc_flush_scheduled_work();
- if (mmc_try_claim_host(host)) {
- err = mmc_cache_ctrl(host, 0);
- mmc_release_host(host);
- } else {
- err = -EBUSY;
- }
+ err = mmc_cache_ctrl(host, 0);
if (err)
goto out;
mmc_bus_get(host);
if (host->bus_ops && !host->bus_dead) {
- /*
- * A long response time is not acceptable for device drivers
- * when doing suspend. Prevent mmc_claim_host in the suspend
- * sequence, to potentially wait "forever" by trying to
- * pre-claim the host.
- */
- if (mmc_try_claim_host(host)) {
- if (host->bus_ops->suspend) {
- err = host->bus_ops->suspend(host);
- }
- mmc_release_host(host);
+ if (host->bus_ops->suspend)
+ err = host->bus_ops->suspend(host);
- if (err == -ENOSYS || !host->bus_ops->resume) {
- /*
- * We simply "remove" the card in this case.
- * It will be redetected on resume. (Calling
- * bus_ops->remove() with a claimed host can
- * deadlock.)
- */
- if (host->bus_ops->remove)
- host->bus_ops->remove(host);
- mmc_claim_host(host);
- mmc_detach_bus(host);
- mmc_power_off(host);
- mmc_release_host(host);
- host->pm_flags = 0;
- err = 0;
- }
- } else {
- err = -EBUSY;
+ if (err == -ENOSYS || !host->bus_ops->resume) {
+ /*
+ * We simply "remove" the card in this case.
+ * It will be redetected on resume. (Calling
+ * bus_ops->remove() with a claimed host can
+ * deadlock.)
+ */
+ if (host->bus_ops->remove)
+ host->bus_ops->remove(host);
+ mmc_claim_host(host);
+ mmc_detach_bus(host);
+ mmc_power_off(host);
+ mmc_release_host(host);
+ host->pm_flags = 0;
+ err = 0;
}
}
mmc_bus_put(host);
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index bf3c9b4..ab3fc46 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -526,8 +526,10 @@
return -ENODEV;
sg_len = dw_mci_pre_dma_transfer(host, data, 0);
- if (sg_len < 0)
+ if (sg_len < 0) {
+ host->dma_ops->stop(host);
return sg_len;
+ }
host->using_dma = 1;
@@ -1879,7 +1881,8 @@
if (!host->dma_ops)
goto no_dma;
- if (host->dma_ops->init) {
+ if (host->dma_ops->init && host->dma_ops->start &&
+ host->dma_ops->stop && host->dma_ops->cleanup) {
if (host->dma_ops->init(host)) {
dev_err(&host->dev, "%s: Unable to initialize "
"DMA Controller.\n", __func__);
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 5c2b1c1..56d4499 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -249,7 +249,7 @@
* the pbias cell programming support is still missing when
* booting with Device tree
*/
- if (of_have_populated_dt() && !vdd)
+ if (dev->of_node && !vdd)
return 0;
if (mmc_slot(host).before_set_reg)
@@ -1549,7 +1549,7 @@
* can't be allowed when booting with device
* tree.
*/
- (!of_have_populated_dt())) {
+ !host->dev->of_node) {
/*
* The mmc_select_voltage fn of the core does
* not seem to set the power_mode to
@@ -1741,7 +1741,7 @@
.data = &omap4_reg_offset,
},
{},
-}
+};
MODULE_DEVICE_TABLE(of, omap_mmc_of_match);
static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev)
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 6193a0d..8abdaf6 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -467,8 +467,7 @@
clk_prepare_enable(clk);
pltfm_host->clk = clk;
- if (!is_imx25_esdhc(imx_data))
- host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
+ host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data))
/* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 9aa77f3..ccefdeb 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -147,7 +147,7 @@
u32 present, irqs;
if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) ||
- !mmc_card_is_removable(host->mmc))
+ (host->mmc->caps & MMC_CAP_NONREMOVABLE))
return;
present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index d20f133..111569c 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -991,8 +991,8 @@
}
}
-static void pci_restore_config_space(struct pci_dev *pdev, int start, int end,
- int retry)
+static void pci_restore_config_space_range(struct pci_dev *pdev,
+ int start, int end, int retry)
{
int index;
@@ -1002,6 +1002,18 @@
retry);
}
+static void pci_restore_config_space(struct pci_dev *pdev)
+{
+ if (pdev->hdr_type == PCI_HEADER_TYPE_NORMAL) {
+ pci_restore_config_space_range(pdev, 10, 15, 0);
+ /* Restore BARs before the command register. */
+ pci_restore_config_space_range(pdev, 4, 9, 10);
+ pci_restore_config_space_range(pdev, 0, 3, 0);
+ } else {
+ pci_restore_config_space_range(pdev, 0, 15, 0);
+ }
+}
+
/**
* pci_restore_state - Restore the saved state of a PCI device
* @dev: - PCI device that we're dealing with
@@ -1015,13 +1027,7 @@
pci_restore_pcie_state(dev);
pci_restore_ats_state(dev);
- pci_restore_config_space(dev, 10, 15, 0);
- /*
- * The Base Address register should be programmed before the command
- * register(s)
- */
- pci_restore_config_space(dev, 4, 9, 10);
- pci_restore_config_space(dev, 0, 3, 0);
+ pci_restore_config_space(dev);
pci_restore_pcix_state(dev);
pci_restore_msi_state(dev);
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index ec3b8cc..df6296c 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -908,10 +908,6 @@
const struct pinctrl_ops *ops = pctldev->desc->pctlops;
unsigned selector = 0;
- /* No grouping */
- if (!ops)
- return 0;
-
mutex_lock(&pinctrl_mutex);
seq_puts(s, "registered pin groups:\n");
@@ -1225,6 +1221,19 @@
#endif
+static int pinctrl_check_ops(struct pinctrl_dev *pctldev)
+{
+ const struct pinctrl_ops *ops = pctldev->desc->pctlops;
+
+ if (!ops ||
+ !ops->list_groups ||
+ !ops->get_group_name ||
+ !ops->get_group_pins)
+ return -EINVAL;
+
+ return 0;
+}
+
/**
* pinctrl_register() - register a pin controller device
* @pctldesc: descriptor for this pin controller
@@ -1256,6 +1265,14 @@
INIT_LIST_HEAD(&pctldev->gpio_ranges);
pctldev->dev = dev;
+ /* check core ops for sanity */
+ ret = pinctrl_check_ops(pctldev);
+ if (ret) {
+ pr_err("%s pinctrl ops lacks necessary functions\n",
+ pctldesc->name);
+ goto out_err;
+ }
+
/* If we're implementing pinmuxing, check the ops for sanity */
if (pctldesc->pmxops) {
ret = pinmux_check_ops(pctldev);
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index c21871a..bc2e8a7 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -2844,6 +2844,7 @@
sector_t recid, trkid;
unsigned int offs;
unsigned int count, count_to_trk_end;
+ int ret;
basedev = block->base;
if (rq_data_dir(req) == READ) {
@@ -2884,8 +2885,8 @@
itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0);
if (IS_ERR(itcw)) {
- dasd_sfree_request(cqr, startdev);
- return ERR_PTR(-EINVAL);
+ ret = -EINVAL;
+ goto out_error;
}
cqr->cpaddr = itcw_get_tcw(itcw);
if (prepare_itcw(itcw, first_trk, last_trk,
@@ -2897,8 +2898,8 @@
/* Clock not in sync and XRC is enabled.
* Try again later.
*/
- dasd_sfree_request(cqr, startdev);
- return ERR_PTR(-EAGAIN);
+ ret = -EAGAIN;
+ goto out_error;
}
len_to_track_end = 0;
/*
@@ -2937,8 +2938,10 @@
tidaw_flags = 0;
last_tidaw = itcw_add_tidaw(itcw, tidaw_flags,
dst, part_len);
- if (IS_ERR(last_tidaw))
- return ERR_PTR(-EINVAL);
+ if (IS_ERR(last_tidaw)) {
+ ret = -EINVAL;
+ goto out_error;
+ }
dst += part_len;
}
}
@@ -2947,8 +2950,10 @@
dst = page_address(bv->bv_page) + bv->bv_offset;
last_tidaw = itcw_add_tidaw(itcw, 0x00,
dst, bv->bv_len);
- if (IS_ERR(last_tidaw))
- return ERR_PTR(-EINVAL);
+ if (IS_ERR(last_tidaw)) {
+ ret = -EINVAL;
+ goto out_error;
+ }
}
}
last_tidaw->flags |= TIDAW_FLAGS_LAST;
@@ -2968,6 +2973,9 @@
cqr->buildclk = get_clock();
cqr->status = DASD_CQR_FILLED;
return cqr;
+out_error:
+ dasd_sfree_request(cqr, startdev);
+ return ERR_PTR(ret);
}
static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c
index 85f4a9a..73bef0b 100644
--- a/drivers/s390/char/vmur.c
+++ b/drivers/s390/char/vmur.c
@@ -903,7 +903,7 @@
goto fail_urdev_put;
}
- cdev_init(urd->char_device, &ur_fops);
+ urd->char_device->ops = &ur_fops;
urd->char_device->dev = MKDEV(major, minor);
urd->char_device->owner = ur_fops.owner;
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c
index 24145c3..6cc4358 100644
--- a/drivers/tty/amiserial.c
+++ b/drivers/tty/amiserial.c
@@ -1073,8 +1073,10 @@
(new_serial.close_delay != port->close_delay) ||
(new_serial.xmit_fifo_size != state->xmit_fifo_size) ||
((new_serial.flags & ~ASYNC_USR_MASK) !=
- (port->flags & ~ASYNC_USR_MASK)))
+ (port->flags & ~ASYNC_USR_MASK))) {
+ tty_unlock();
return -EPERM;
+ }
port->flags = ((port->flags & ~ASYNC_USR_MASK) |
(new_serial.flags & ASYNC_USR_MASK));
state->custom_divisor = new_serial.custom_divisor;
diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c
index e6c3dbd..836fe273 100644
--- a/drivers/tty/serial/clps711x.c
+++ b/drivers/tty/serial/clps711x.c
@@ -154,10 +154,9 @@
port->x_char = 0;
return IRQ_HANDLED;
}
- if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
- clps711xuart_stop_tx(port);
- return IRQ_HANDLED;
- }
+
+ if (uart_circ_empty(xmit) || uart_tx_stopped(port))
+ goto disable_tx_irq;
count = port->fifosize >> 1;
do {
@@ -171,8 +170,11 @@
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(port);
- if (uart_circ_empty(xmit))
- clps711xuart_stop_tx(port);
+ if (uart_circ_empty(xmit)) {
+ disable_tx_irq:
+ disable_irq_nosync(TX_IRQ(port));
+ tx_enabled(port) = 0;
+ }
return IRQ_HANDLED;
}
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c
index bbbec4a..c2816f4 100644
--- a/drivers/tty/serial/pch_uart.c
+++ b/drivers/tty/serial/pch_uart.c
@@ -1447,9 +1447,11 @@
__func__);
return -EOPNOTSUPP;
#endif
- priv->use_dma = 1;
priv->use_dma_flag = 1;
dev_info(priv->port.dev, "PCH UART : Use DMA Mode\n");
+ if (!priv->use_dma)
+ pch_request_dma(port);
+ priv->use_dma = 1;
}
return 0;
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index a2aa9d6..ec6c97d 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1667,7 +1667,6 @@
{
struct usb_device *udev = *pdev;
int i;
- struct usb_hcd *hcd = bus_to_hcd(udev->bus);
/* mark the device as inactive, so any further urb submissions for
* this device (and any of its children) will fail immediately.
@@ -1690,9 +1689,7 @@
* so that the hardware is now fully quiesced.
*/
dev_dbg (&udev->dev, "unregistering device\n");
- mutex_lock(hcd->bandwidth_mutex);
usb_disable_device(udev, 0);
- mutex_unlock(hcd->bandwidth_mutex);
usb_hcd_synchronize_unlinks(udev);
usb_remove_ep_devs(&udev->ep0);
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index aed3e07..ca717da 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1136,8 +1136,6 @@
* Deallocates hcd/hardware state for the endpoints (nuking all or most
* pending urbs) and usbcore state for the interfaces, so that usbcore
* must usb_set_configuration() before any interfaces could be used.
- *
- * Must be called with hcd->bandwidth_mutex held.
*/
void usb_disable_device(struct usb_device *dev, int skip_ep0)
{
@@ -1190,7 +1188,9 @@
usb_disable_endpoint(dev, i + USB_DIR_IN, false);
}
/* Remove endpoints from the host controller internal state */
+ mutex_lock(hcd->bandwidth_mutex);
usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
+ mutex_unlock(hcd->bandwidth_mutex);
/* Second pass: remove endpoint pointers */
}
for (i = skip_ep0; i < 16; ++i) {
@@ -1750,7 +1750,6 @@
/* if it's already configured, clear out old state first.
* getting rid of old interfaces means unbinding their drivers.
*/
- mutex_lock(hcd->bandwidth_mutex);
if (dev->state != USB_STATE_ADDRESS)
usb_disable_device(dev, 1); /* Skip ep0 */
@@ -1763,6 +1762,7 @@
* host controller will not allow submissions to dropped endpoints. If
* this call fails, the device state is unchanged.
*/
+ mutex_lock(hcd->bandwidth_mutex);
ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);
if (ret < 0) {
mutex_unlock(hcd->bandwidth_mutex);
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 7bd815a..99b58d84 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -206,11 +206,11 @@
for (i = 0; i < dwc->num_event_buffers; i++) {
evt = dwc->ev_buffs[i];
- if (evt) {
+ if (evt)
dwc3_free_one_event_buffer(dwc, evt);
- dwc->ev_buffs[i] = NULL;
- }
}
+
+ kfree(dwc->ev_buffs);
}
/**
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 25910e2..3584a16 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -353,6 +353,9 @@
dwc->test_mode_nr = wIndex >> 8;
dwc->test_mode = true;
+ break;
+ default:
+ return -EINVAL;
}
break;
@@ -559,15 +562,20 @@
length = trb->size & DWC3_TRB_SIZE_MASK;
if (dwc->ep0_bounced) {
+ unsigned transfer_size = ur->length;
+ unsigned maxp = ep0->endpoint.maxpacket;
+
+ transfer_size += (maxp - (transfer_size % maxp));
transferred = min_t(u32, ur->length,
- ep0->endpoint.maxpacket - length);
+ transfer_size - length);
memcpy(ur->buf, dwc->ep0_bounce, transferred);
dwc->ep0_bounced = false;
} else {
transferred = ur->length - length;
- ur->actual += transferred;
}
+ ur->actual += transferred;
+
if ((epnum & 1) && ur->actual < ur->length) {
/* for some reason we did not get everything out */
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 0c935d7..9d7bcd9 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -1863,8 +1863,8 @@
mod_timer(&udc->vbus_timer,
jiffies + VBUS_POLL_TIMEOUT);
} else {
- if (request_irq(udc->board.vbus_pin, at91_vbus_irq,
- 0, driver_name, udc)) {
+ if (request_irq(gpio_to_irq(udc->board.vbus_pin),
+ at91_vbus_irq, 0, driver_name, udc)) {
DBG("request vbus irq %d failed\n",
udc->board.vbus_pin);
retval = -EBUSY;
@@ -1886,7 +1886,7 @@
return 0;
fail4:
if (gpio_is_valid(udc->board.vbus_pin) && !udc->board.vbus_polled)
- free_irq(udc->board.vbus_pin, udc);
+ free_irq(gpio_to_irq(udc->board.vbus_pin), udc);
fail3:
if (gpio_is_valid(udc->board.vbus_pin))
gpio_free(udc->board.vbus_pin);
@@ -1924,7 +1924,7 @@
device_init_wakeup(&pdev->dev, 0);
remove_debug_file(udc);
if (gpio_is_valid(udc->board.vbus_pin)) {
- free_irq(udc->board.vbus_pin, udc);
+ free_irq(gpio_to_irq(udc->board.vbus_pin), udc);
gpio_free(udc->board.vbus_pin);
}
free_irq(udc->udp_irq, udc);
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index 1cbba70..f52cb1a 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -712,7 +712,7 @@
if (code == FUNCTIONFS_INTERFACE_REVMAP) {
struct ffs_function *func = ffs->func;
ret = func ? ffs_func_revmap_intf(func, value) : -ENODEV;
- } else if (gadget->ops->ioctl) {
+ } else if (gadget && gadget->ops->ioctl) {
ret = gadget->ops->ioctl(gadget, code, value);
} else {
ret = -ENOTTY;
@@ -1382,6 +1382,7 @@
ffs->ep0req = NULL;
ffs->gadget = NULL;
ffs_data_put(ffs);
+ clear_bit(FFS_FL_BOUND, &ffs->flags);
}
}
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index 7b1cf18..5234365 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -500,6 +500,7 @@
if (buf) {
memcpy(req->buf, buf, n);
req->complete = rndis_response_complete;
+ req->context = rndis;
rndis_free_response(rndis->config, buf);
value = n;
}
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index 5f94e79..55abfb6 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -730,7 +730,7 @@
: (1 << (ep_index(ep)));
/* check if the pipe is empty */
- if (!(list_empty(&ep->queue))) {
+ if (!(list_empty(&ep->queue)) && !(ep_index(ep) == 0)) {
/* Add td to the end */
struct fsl_req *lastreq;
lastreq = list_entry(ep->queue.prev, struct fsl_req, queue);
@@ -918,10 +918,6 @@
return -ENOMEM;
}
- /* Update ep0 state */
- if ((ep_index(ep) == 0))
- udc->ep0_state = DATA_STATE_XMIT;
-
/* irq handler advances the queue */
if (req != NULL)
list_add_tail(&req->queue, &ep->queue);
@@ -1279,7 +1275,8 @@
udc->ep0_dir = USB_DIR_OUT;
ep = &udc->eps[0];
- udc->ep0_state = WAIT_FOR_OUT_STATUS;
+ if (udc->ep0_state != DATA_STATE_XMIT)
+ udc->ep0_state = WAIT_FOR_OUT_STATUS;
req->ep = ep;
req->req.length = 0;
@@ -1384,6 +1381,9 @@
list_add_tail(&req->queue, &ep->queue);
udc->ep0_state = DATA_STATE_XMIT;
+ if (ep0_prime_status(udc, EP_DIR_OUT))
+ ep0stall(udc);
+
return;
stall:
ep0stall(udc);
@@ -1492,6 +1492,14 @@
spin_lock(&udc->lock);
udc->ep0_state = (setup->bRequestType & USB_DIR_IN)
? DATA_STATE_XMIT : DATA_STATE_RECV;
+ /*
+ * If the data stage is IN, send status prime immediately.
+ * See 2.0 Spec chapter 8.5.3.3 for detail.
+ */
+ if (udc->ep0_state == DATA_STATE_XMIT)
+ if (ep0_prime_status(udc, EP_DIR_OUT))
+ ep0stall(udc);
+
} else {
/* No data phase, IN status from gadget */
udc->ep0_dir = USB_DIR_IN;
@@ -1520,9 +1528,8 @@
switch (udc->ep0_state) {
case DATA_STATE_XMIT:
- /* receive status phase */
- if (ep0_prime_status(udc, EP_DIR_OUT))
- ep0stall(udc);
+ /* already primed at setup_received_irq */
+ udc->ep0_state = WAIT_FOR_OUT_STATUS;
break;
case DATA_STATE_RECV:
/* send status phase */
diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
index 331cd67..a85eaf4 100644
--- a/drivers/usb/gadget/g_ffs.c
+++ b/drivers/usb/gadget/g_ffs.c
@@ -161,7 +161,7 @@
static struct ffs_data *gfs_ffs_data;
static unsigned long gfs_registered;
-static int gfs_init(void)
+static int __init gfs_init(void)
{
ENTER();
@@ -169,7 +169,7 @@
}
module_init(gfs_init);
-static void gfs_exit(void)
+static void __exit gfs_exit(void)
{
ENTER();
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index 69295ba..105b206 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -340,7 +340,7 @@
/* currently we allocate TX FIFOs for all possible endpoints,
* and assume that they are all the same size. */
- for (ep = 0; ep <= 15; ep++) {
+ for (ep = 1; ep <= 15; ep++) {
val = addr;
val |= size << S3C_DPTXFSIZn_DPTxFSize_SHIFT;
addr += size;
@@ -741,7 +741,7 @@
/* write size / packets */
writel(epsize, hsotg->regs + epsize_reg);
- if (using_dma(hsotg)) {
+ if (using_dma(hsotg) && !continuing) {
unsigned int dma_reg;
/* write DMA address to control register, buffer already
@@ -1696,10 +1696,12 @@
reg |= mpsval;
writel(reg, regs + S3C_DIEPCTL(ep));
- reg = readl(regs + S3C_DOEPCTL(ep));
- reg &= ~S3C_DxEPCTL_MPS_MASK;
- reg |= mpsval;
- writel(reg, regs + S3C_DOEPCTL(ep));
+ if (ep) {
+ reg = readl(regs + S3C_DOEPCTL(ep));
+ reg &= ~S3C_DxEPCTL_MPS_MASK;
+ reg |= mpsval;
+ writel(reg, regs + S3C_DOEPCTL(ep));
+ }
return;
@@ -1919,7 +1921,8 @@
ints & S3C_DIEPMSK_TxFIFOEmpty) {
dev_dbg(hsotg->dev, "%s: ep%d: TxFIFOEmpty\n",
__func__, idx);
- s3c_hsotg_trytx(hsotg, hs_ep);
+ if (!using_dma(hsotg))
+ s3c_hsotg_trytx(hsotg, hs_ep);
}
}
}
diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
index 56da49f..2fa9865 100644
--- a/drivers/usb/gadget/udc-core.c
+++ b/drivers/usb/gadget/udc-core.c
@@ -264,8 +264,8 @@
if (udc_is_newstyle(udc)) {
udc->driver->disconnect(udc->gadget);
udc->driver->unbind(udc->gadget);
- usb_gadget_udc_stop(udc->gadget, udc->driver);
usb_gadget_disconnect(udc->gadget);
+ usb_gadget_udc_stop(udc->gadget, udc->driver);
} else {
usb_gadget_stop(udc->gadget, udc->driver);
}
@@ -411,8 +411,12 @@
struct usb_udc *udc = container_of(dev, struct usb_udc, dev);
if (sysfs_streq(buf, "connect")) {
+ if (udc_is_newstyle(udc))
+ usb_gadget_udc_start(udc->gadget, udc->driver);
usb_gadget_connect(udc->gadget);
} else if (sysfs_streq(buf, "disconnect")) {
+ if (udc_is_newstyle(udc))
+ usb_gadget_udc_stop(udc->gadget, udc->driver);
usb_gadget_disconnect(udc->gadget);
} else {
dev_err(dev, "unsupported command '%s'\n", buf);
diff --git a/drivers/usb/gadget/uvc_queue.c b/drivers/usb/gadget/uvc_queue.c
index d776adb..0cdf89d 100644
--- a/drivers/usb/gadget/uvc_queue.c
+++ b/drivers/usb/gadget/uvc_queue.c
@@ -543,11 +543,11 @@
return ret;
}
+/* called with queue->irqlock held.. */
static struct uvc_buffer *
uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf)
{
struct uvc_buffer *nextbuf;
- unsigned long flags;
if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) &&
buf->buf.length != buf->buf.bytesused) {
@@ -556,14 +556,12 @@
return buf;
}
- spin_lock_irqsave(&queue->irqlock, flags);
list_del(&buf->queue);
if (!list_empty(&queue->irqqueue))
nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
queue);
else
nextbuf = NULL;
- spin_unlock_irqrestore(&queue->irqlock, flags);
buf->buf.sequence = queue->sequence++;
do_gettimeofday(&buf->buf.timestamp);
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index 3e73451..d0a84bd 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -218,6 +218,9 @@
u32 portsc;
struct usb_hcd *hcd = ehci_to_hcd(ehci);
void __iomem *non_ehci = hcd->regs;
+ struct fsl_usb2_platform_data *pdata;
+
+ pdata = hcd->self.controller->platform_data;
portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]);
portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW);
@@ -234,7 +237,9 @@
/* fall through */
case FSL_USB2_PHY_UTMI:
/* enable UTMI PHY */
- setbits32(non_ehci + FSL_SOC_USB_CTRL, CTRL_UTMI_PHY_EN);
+ if (pdata->have_sysif_regs)
+ setbits32(non_ehci + FSL_SOC_USB_CTRL,
+ CTRL_UTMI_PHY_EN);
portsc |= PORT_PTS_UTMI;
break;
case FSL_USB2_PHY_NONE:
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 806cc95..4a3bc5b 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -858,8 +858,13 @@
goto dead;
}
+ /*
+ * We don't use STS_FLR, but some controllers don't like it to
+ * remain on, so mask it out along with the other status bits.
+ */
+ masked_status = status & (INTR_MASK | STS_FLR);
+
/* Shared IRQ? */
- masked_status = status & INTR_MASK;
if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) {
spin_unlock(&ehci->lock);
return IRQ_NONE;
@@ -910,7 +915,7 @@
pcd_status = status;
/* resume root hub? */
- if (!(cmd & CMD_RUN))
+ if (ehci->rh_state == EHCI_RH_SUSPENDED)
usb_hcd_resume_root_hub(hcd);
/* get per-port change detect bits */
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index bba9850..5c78f9e 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -42,6 +42,7 @@
#include <plat/usb.h>
#include <linux/regulator/consumer.h>
#include <linux/pm_runtime.h>
+#include <linux/gpio.h>
/* EHCI Register Set */
#define EHCI_INSNREG04 (0xA0)
@@ -191,6 +192,19 @@
}
}
+ if (pdata->phy_reset) {
+ if (gpio_is_valid(pdata->reset_gpio_port[0]))
+ gpio_request_one(pdata->reset_gpio_port[0],
+ GPIOF_OUT_INIT_LOW, "USB1 PHY reset");
+
+ if (gpio_is_valid(pdata->reset_gpio_port[1]))
+ gpio_request_one(pdata->reset_gpio_port[1],
+ GPIOF_OUT_INIT_LOW, "USB2 PHY reset");
+
+ /* Hold the PHY in RESET for enough time till DIR is high */
+ udelay(10);
+ }
+
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
@@ -237,6 +251,19 @@
/* root ports should always stay powered */
ehci_port_power(omap_ehci, 1);
+ if (pdata->phy_reset) {
+ /* Hold the PHY in RESET for enough time till
+ * PHY is settled and ready
+ */
+ udelay(10);
+
+ if (gpio_is_valid(pdata->reset_gpio_port[0]))
+ gpio_set_value(pdata->reset_gpio_port[0], 1);
+
+ if (gpio_is_valid(pdata->reset_gpio_port[1]))
+ gpio_set_value(pdata->reset_gpio_port[1], 1);
+ }
+
return 0;
err_add_hcd:
@@ -259,8 +286,9 @@
*/
static int ehci_hcd_omap_remove(struct platform_device *pdev)
{
- struct device *dev = &pdev->dev;
- struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct device *dev = &pdev->dev;
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct ehci_hcd_omap_platform_data *pdata = dev->platform_data;
usb_remove_hcd(hcd);
disable_put_regulator(dev->platform_data);
@@ -269,6 +297,13 @@
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
+ if (pdata->phy_reset) {
+ if (gpio_is_valid(pdata->reset_gpio_port[0]))
+ gpio_free(pdata->reset_gpio_port[0]);
+
+ if (gpio_is_valid(pdata->reset_gpio_port[1]))
+ gpio_free(pdata->reset_gpio_port[1]);
+ }
return 0;
}
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 73544bd..8618336 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -731,7 +731,6 @@
err = -ENODEV;
goto fail;
}
- set_irq_flags(irq, IRQF_VALID);
#ifdef CONFIG_USB_OTG_UTILS
if (pdata->operating_mode == TEGRA_USB_OTG) {
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 09f597a..13ebeca 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -94,7 +94,7 @@
/*-------------------------------------------------------------------------*/
-static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
+static void __devexit usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
/* configure so an HC device and id are always provided */
/* always called with process context; sleeping is OK */
@@ -108,7 +108,7 @@
* then invokes the start() method for the HCD associated with it
* through the hotplug entry's driver_data.
*/
-static int usb_hcd_at91_probe(const struct hc_driver *driver,
+static int __devinit usb_hcd_at91_probe(const struct hc_driver *driver,
struct platform_device *pdev)
{
int retval;
@@ -203,7 +203,7 @@
* context, "rmmod" or something similar.
*
*/
-static void usb_hcd_at91_remove(struct usb_hcd *hcd,
+static void __devexit usb_hcd_at91_remove(struct usb_hcd *hcd,
struct platform_device *pdev)
{
usb_remove_hcd(hcd);
@@ -545,7 +545,7 @@
/*-------------------------------------------------------------------------*/
-static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
+static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev)
{
struct at91_usbh_data *pdata;
int i;
@@ -620,7 +620,7 @@
return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);
}
-static int ohci_hcd_at91_drv_remove(struct platform_device *pdev)
+static int __devexit ohci_hcd_at91_drv_remove(struct platform_device *pdev)
{
struct at91_usbh_data *pdata = pdev->dev.platform_data;
int i;
@@ -696,7 +696,7 @@
static struct platform_driver ohci_hcd_at91_driver = {
.probe = ohci_hcd_at91_drv_probe,
- .remove = ohci_hcd_at91_drv_remove,
+ .remove = __devexit_p(ohci_hcd_at91_drv_remove),
.shutdown = usb_hcd_platform_shutdown,
.suspend = ohci_hcd_at91_drv_suspend,
.resume = ohci_hcd_at91_drv_resume,
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 959145b..9dcb68f 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -423,7 +423,7 @@
unsigned i;
unsigned size = max;
- sg = kmalloc(nents * sizeof *sg, GFP_KERNEL);
+ sg = kmalloc_array(nents, sizeof *sg, GFP_KERNEL);
if (!sg)
return NULL;
sg_init_table(sg, nents);
@@ -904,6 +904,9 @@
struct ctrl_ctx context;
int i;
+ if (param->sglen == 0 || param->iterations > UINT_MAX / param->sglen)
+ return -EOPNOTSUPP;
+
spin_lock_init(&context.lock);
context.dev = dev;
init_completion(&context.complete);
@@ -1981,8 +1984,6 @@
/* queued control messaging */
case 10:
- if (param->sglen == 0)
- break;
retval = 0;
dev_info(&intf->dev,
"TEST 10: queue %d control calls, %d times\n",
@@ -2276,6 +2277,8 @@
if (status < 0) {
WARNING(dev, "couldn't get endpoints, %d\n",
status);
+ kfree(dev->buf);
+ kfree(dev);
return status;
}
/* may find bulk or ISO pipes */
diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c
index 897edda..7020146 100644
--- a/drivers/usb/misc/yurex.c
+++ b/drivers/usb/misc/yurex.c
@@ -99,9 +99,7 @@
usb_put_dev(dev->udev);
if (dev->cntl_urb) {
usb_kill_urb(dev->cntl_urb);
- if (dev->cntl_req)
- usb_free_coherent(dev->udev, YUREX_BUF_SIZE,
- dev->cntl_req, dev->cntl_urb->setup_dma);
+ kfree(dev->cntl_req);
if (dev->cntl_buffer)
usb_free_coherent(dev->udev, YUREX_BUF_SIZE,
dev->cntl_buffer, dev->cntl_urb->transfer_dma);
@@ -234,9 +232,7 @@
}
/* allocate buffer for control req */
- dev->cntl_req = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE,
- GFP_KERNEL,
- &dev->cntl_urb->setup_dma);
+ dev->cntl_req = kmalloc(YUREX_BUF_SIZE, GFP_KERNEL);
if (!dev->cntl_req) {
err("Could not allocate cntl_req");
goto error;
@@ -286,7 +282,7 @@
usb_rcvintpipe(dev->udev, dev->int_in_endpointAddr),
dev->int_buffer, YUREX_BUF_SIZE, yurex_interrupt,
dev, 1);
- dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ dev->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
if (usb_submit_urb(dev->urb, GFP_KERNEL)) {
retval = -EIO;
err("Could not submitting URB");
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 0f8b829..66aaccf 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -137,6 +137,9 @@
int i = 0;
u8 r;
u8 power;
+ int ret;
+
+ pm_runtime_get_sync(phy->io_dev);
/* Make sure the transceiver is not in low power mode */
power = musb_readb(addr, MUSB_POWER);
@@ -154,15 +157,22 @@
while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
& MUSB_ULPI_REG_CMPLT)) {
i++;
- if (i == 10000)
- return -ETIMEDOUT;
+ if (i == 10000) {
+ ret = -ETIMEDOUT;
+ goto out;
+ }
}
r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);
r &= ~MUSB_ULPI_REG_CMPLT;
musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r);
- return musb_readb(addr, MUSB_ULPI_REG_DATA);
+ ret = musb_readb(addr, MUSB_ULPI_REG_DATA);
+
+out:
+ pm_runtime_put(phy->io_dev);
+
+ return ret;
}
static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)
@@ -171,6 +181,9 @@
int i = 0;
u8 r = 0;
u8 power;
+ int ret = 0;
+
+ pm_runtime_get_sync(phy->io_dev);
/* Make sure the transceiver is not in low power mode */
power = musb_readb(addr, MUSB_POWER);
@@ -184,15 +197,20 @@
while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
& MUSB_ULPI_REG_CMPLT)) {
i++;
- if (i == 10000)
- return -ETIMEDOUT;
+ if (i == 10000) {
+ ret = -ETIMEDOUT;
+ goto out;
+ }
}
r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);
r &= ~MUSB_ULPI_REG_CMPLT;
musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r);
- return 0;
+out:
+ pm_runtime_put(phy->io_dev);
+
+ return ret;
}
#else
#define musb_ulpi_read NULL
@@ -1904,14 +1922,17 @@
if (!musb->isr) {
status = -ENODEV;
- goto fail3;
+ goto fail2;
}
if (!musb->xceiv->io_ops) {
+ musb->xceiv->io_dev = musb->controller;
musb->xceiv->io_priv = musb->mregs;
musb->xceiv->io_ops = &musb_ulpi_access;
}
+ pm_runtime_get_sync(musb->controller);
+
#ifndef CONFIG_MUSB_PIO_ONLY
if (use_dma && dev->dma_mask) {
struct dma_controller *c;
@@ -2023,6 +2044,8 @@
goto fail5;
#endif
+ pm_runtime_put(musb->controller);
+
dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n",
({char *s;
switch (musb->board_mode) {
@@ -2047,6 +2070,9 @@
musb_gadget_cleanup(musb);
fail3:
+ pm_runtime_put_sync(musb->controller);
+
+fail2:
if (musb->irq_wake)
device_init_wakeup(dev, 0);
musb_platform_exit(musb);
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 79cb0af..ef8d744 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -2098,7 +2098,7 @@
}
/* turn off DMA requests, discard state, stop polling ... */
- if (is_in) {
+ if (ep->epnum && is_in) {
/* giveback saves bulk toggle */
csr = musb_h_flush_rxfifo(ep, 0);
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index 2ae0bb3..c7785e8 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -282,7 +282,8 @@
static int omap2430_musb_init(struct musb *musb)
{
- u32 l, status = 0;
+ u32 l;
+ int status = 0;
struct device *dev = musb->controller;
struct musb_hdrc_platform_data *plat = dev->platform_data;
struct omap_musb_board_data *data = plat->board_data;
@@ -301,7 +302,7 @@
status = pm_runtime_get_sync(dev);
if (status < 0) {
- dev_err(dev, "pm_runtime_get_sync FAILED");
+ dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);
goto err1;
}
@@ -333,6 +334,7 @@
setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
+ pm_runtime_put_noidle(musb->controller);
return 0;
err1:
@@ -452,14 +454,14 @@
goto err2;
}
+ pm_runtime_enable(&pdev->dev);
+
ret = platform_device_add(musb);
if (ret) {
dev_err(&pdev->dev, "failed to register musb device\n");
goto err2;
}
- pm_runtime_enable(&pdev->dev);
-
return 0;
err2:
@@ -478,7 +480,6 @@
platform_device_del(glue->musb);
platform_device_put(glue->musb);
- pm_runtime_put(&pdev->dev);
kfree(glue);
return 0;
@@ -491,11 +492,13 @@
struct omap2430_glue *glue = dev_get_drvdata(dev);
struct musb *musb = glue_to_musb(glue);
- musb->context.otg_interfsel = musb_readl(musb->mregs,
- OTG_INTERFSEL);
+ if (musb) {
+ musb->context.otg_interfsel = musb_readl(musb->mregs,
+ OTG_INTERFSEL);
- omap2430_low_level_exit(musb);
- usb_phy_set_suspend(musb->xceiv, 1);
+ omap2430_low_level_exit(musb);
+ usb_phy_set_suspend(musb->xceiv, 1);
+ }
return 0;
}
@@ -505,11 +508,13 @@
struct omap2430_glue *glue = dev_get_drvdata(dev);
struct musb *musb = glue_to_musb(glue);
- omap2430_low_level_init(musb);
- musb_writel(musb->mregs, OTG_INTERFSEL,
- musb->context.otg_interfsel);
+ if (musb) {
+ omap2430_low_level_init(musb);
+ musb_writel(musb->mregs, OTG_INTERFSEL,
+ musb->context.otg_interfsel);
- usb_phy_set_suspend(musb->xceiv, 0);
+ usb_phy_set_suspend(musb->xceiv, 0);
+ }
return 0;
}
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 0310e2d..ec30f95 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -287,7 +287,8 @@
/* Issue the request, attempting to read 'size' bytes */
result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
request, REQTYPE_DEVICE_TO_HOST, 0x0000,
- port_priv->bInterfaceNumber, buf, size, 300);
+ port_priv->bInterfaceNumber, buf, size,
+ USB_CTRL_GET_TIMEOUT);
/* Convert data into an array of integers */
for (i = 0; i < length; i++)
@@ -340,12 +341,14 @@
result = usb_control_msg(serial->dev,
usb_sndctrlpipe(serial->dev, 0),
request, REQTYPE_HOST_TO_DEVICE, 0x0000,
- port_priv->bInterfaceNumber, buf, size, 300);
+ port_priv->bInterfaceNumber, buf, size,
+ USB_CTRL_SET_TIMEOUT);
} else {
result = usb_control_msg(serial->dev,
usb_sndctrlpipe(serial->dev, 0),
request, REQTYPE_HOST_TO_DEVICE, data[0],
- port_priv->bInterfaceNumber, NULL, 0, 300);
+ port_priv->bInterfaceNumber, NULL, 0,
+ USB_CTRL_SET_TIMEOUT);
}
kfree(buf);
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index fdd5aa2..8c8bf80 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -221,7 +221,7 @@
};
/* 'blacklist' of interfaces not served by this driver */
-static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 };
+static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11, 19, 20 };
static const struct sierra_iface_info direct_ip_interface_blacklist = {
.infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces),
.ifaceinfo = direct_ip_non_serial_ifaces,
@@ -289,7 +289,6 @@
{ USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */
{ USB_DEVICE(0x1199, 0x6859) }, /* Sierra Wireless AirCard 885 E */
{ USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */
- { USB_DEVICE(0x1199, 0x68A2) }, /* Sierra Wireless MC7710 */
/* Sierra Wireless C885 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)},
/* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */
@@ -299,6 +298,9 @@
/* Sierra Wireless HSPA Non-Composite Device */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},
{ USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */
+ { USB_DEVICE(0x1199, 0x68A2), /* Sierra Wireless MC77xx in QMI mode */
+ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
+ },
{ USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */
.driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
},
diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c
index 66797e9..810c90a 100644
--- a/drivers/uwb/hwa-rc.c
+++ b/drivers/uwb/hwa-rc.c
@@ -645,7 +645,8 @@
dev_err(dev, "NEEP: URB error %d\n", urb->status);
}
result = usb_submit_urb(urb, GFP_ATOMIC);
- if (result < 0) {
+ if (result < 0 && result != -ENODEV && result != -EPERM) {
+ /* ignoring unrecoverable errors */
dev_err(dev, "NEEP: Can't resubmit URB (%d) resetting device\n",
result);
goto error;
diff --git a/drivers/uwb/neh.c b/drivers/uwb/neh.c
index a269937..8cb71bb 100644
--- a/drivers/uwb/neh.c
+++ b/drivers/uwb/neh.c
@@ -107,6 +107,7 @@
u8 evt_type;
__le16 evt;
u8 context;
+ u8 completed;
uwb_rc_cmd_cb_f cb;
void *arg;
@@ -409,6 +410,7 @@
struct device *dev = &rc->uwb_dev.dev;
struct uwb_rc_neh *neh;
struct uwb_rceb *notif;
+ unsigned long flags;
if (rceb->bEventContext == 0) {
notif = kmalloc(size, GFP_ATOMIC);
@@ -422,7 +424,11 @@
} else {
neh = uwb_rc_neh_lookup(rc, rceb);
if (neh) {
- del_timer_sync(&neh->timer);
+ spin_lock_irqsave(&rc->neh_lock, flags);
+ /* to guard against a timeout */
+ neh->completed = 1;
+ del_timer(&neh->timer);
+ spin_unlock_irqrestore(&rc->neh_lock, flags);
uwb_rc_neh_cb(neh, rceb, size);
} else
dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n",
@@ -568,6 +574,10 @@
unsigned long flags;
spin_lock_irqsave(&rc->neh_lock, flags);
+ if (neh->completed) {
+ spin_unlock_irqrestore(&rc->neh_lock, flags);
+ return;
+ }
if (neh->context)
__uwb_rc_neh_rm(rc, neh);
else
diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c
index fc9a1d7..3de00d9 100644
--- a/drivers/vhost/test.c
+++ b/drivers/vhost/test.c
@@ -155,7 +155,7 @@
vhost_test_stop(n, &private);
vhost_test_flush(n);
- vhost_dev_cleanup(&n->dev);
+ vhost_dev_cleanup(&n->dev, false);
/* We do an extra flush before freeing memory,
* since jobs can re-queue themselves. */
vhost_test_flush(n);
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 05f0a808..c2d05a8 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -28,6 +28,13 @@
#include <linux/slab.h>
#include <linux/module.h>
+/*
+ * Balloon device works in 4K page units. So each page is pointed to by
+ * multiple balloon pages. All memory counters in this driver are in balloon
+ * page units.
+ */
+#define VIRTIO_BALLOON_PAGES_PER_PAGE (PAGE_SIZE >> VIRTIO_BALLOON_PFN_SHIFT)
+
struct virtio_balloon
{
struct virtio_device *vdev;
@@ -42,8 +49,13 @@
/* Waiting for host to ack the pages we released. */
struct completion acked;
- /* The pages we've told the Host we're not using. */
+ /* Number of balloon pages we've told the Host we're not using. */
unsigned int num_pages;
+ /*
+ * The pages we've told the Host we're not using.
+ * Each page on this list adds VIRTIO_BALLOON_PAGES_PER_PAGE
+ * to num_pages above.
+ */
struct list_head pages;
/* The array of pfns we tell the Host about. */
@@ -66,7 +78,13 @@
BUILD_BUG_ON(PAGE_SHIFT < VIRTIO_BALLOON_PFN_SHIFT);
/* Convert pfn from Linux page size to balloon page size. */
- return pfn >> (PAGE_SHIFT - VIRTIO_BALLOON_PFN_SHIFT);
+ return pfn * VIRTIO_BALLOON_PAGES_PER_PAGE;
+}
+
+static struct page *balloon_pfn_to_page(u32 pfn)
+{
+ BUG_ON(pfn % VIRTIO_BALLOON_PAGES_PER_PAGE);
+ return pfn_to_page(pfn / VIRTIO_BALLOON_PAGES_PER_PAGE);
}
static void balloon_ack(struct virtqueue *vq)
@@ -96,12 +114,23 @@
wait_for_completion(&vb->acked);
}
+static void set_page_pfns(u32 pfns[], struct page *page)
+{
+ unsigned int i;
+
+ /* Set balloon pfns pointing at this page.
+ * Note that the first pfn points at start of the page. */
+ for (i = 0; i < VIRTIO_BALLOON_PAGES_PER_PAGE; i++)
+ pfns[i] = page_to_balloon_pfn(page) + i;
+}
+
static void fill_balloon(struct virtio_balloon *vb, size_t num)
{
/* We can only do one array worth at a time. */
num = min(num, ARRAY_SIZE(vb->pfns));
- for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) {
+ for (vb->num_pfns = 0; vb->num_pfns < num;
+ vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) {
struct page *page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY |
__GFP_NOMEMALLOC | __GFP_NOWARN);
if (!page) {
@@ -113,9 +142,9 @@
msleep(200);
break;
}
- vb->pfns[vb->num_pfns] = page_to_balloon_pfn(page);
+ set_page_pfns(vb->pfns + vb->num_pfns, page);
+ vb->num_pages += VIRTIO_BALLOON_PAGES_PER_PAGE;
totalram_pages--;
- vb->num_pages++;
list_add(&page->lru, &vb->pages);
}
@@ -130,8 +159,9 @@
{
unsigned int i;
- for (i = 0; i < num; i++) {
- __free_page(pfn_to_page(pfns[i]));
+ /* Find pfns pointing at start of each page, get pages and free them. */
+ for (i = 0; i < num; i += VIRTIO_BALLOON_PAGES_PER_PAGE) {
+ __free_page(balloon_pfn_to_page(pfns[i]));
totalram_pages++;
}
}
@@ -143,11 +173,12 @@
/* We can only do one array worth at a time. */
num = min(num, ARRAY_SIZE(vb->pfns));
- for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) {
+ for (vb->num_pfns = 0; vb->num_pfns < num;
+ vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) {
page = list_first_entry(&vb->pages, struct page, lru);
list_del(&page->lru);
- vb->pfns[vb->num_pfns] = page_to_balloon_pfn(page);
- vb->num_pages--;
+ set_page_pfns(vb->pfns + vb->num_pfns, page);
+ vb->num_pages -= VIRTIO_BALLOON_PAGES_PER_PAGE;
}
/*
@@ -234,11 +265,14 @@
static inline s64 towards_target(struct virtio_balloon *vb)
{
- u32 v;
+ __le32 v;
+ s64 target;
+
vb->vdev->config->get(vb->vdev,
offsetof(struct virtio_balloon_config, num_pages),
&v, sizeof(v));
- return (s64)v - vb->num_pages;
+ target = le32_to_cpu(v);
+ return target - vb->num_pages;
}
static void update_balloon_size(struct virtio_balloon *vb)
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
index 99d8151..1ffd03b 100644
--- a/drivers/xen/gntdev.c
+++ b/drivers/xen/gntdev.c
@@ -722,7 +722,7 @@
vma->vm_flags |= VM_RESERVED|VM_DONTEXPAND;
if (use_ptemod)
- vma->vm_flags |= VM_DONTCOPY|VM_PFNMAP;
+ vma->vm_flags |= VM_DONTCOPY;
vma->vm_private_data = map;
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index b4d4eac..f100ce2 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -1029,6 +1029,7 @@
int i;
unsigned int max_nr_glist_frames, nr_glist_frames;
unsigned int nr_init_grefs;
+ int ret;
nr_grant_frames = 1;
boot_max_nr_grant_frames = __max_nr_grant_frames();
@@ -1047,12 +1048,16 @@
nr_glist_frames = (nr_grant_frames * GREFS_PER_GRANT_FRAME + RPP - 1) / RPP;
for (i = 0; i < nr_glist_frames; i++) {
gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL);
- if (gnttab_list[i] == NULL)
+ if (gnttab_list[i] == NULL) {
+ ret = -ENOMEM;
goto ini_nomem;
+ }
}
- if (gnttab_resume() < 0)
- return -ENODEV;
+ if (gnttab_resume() < 0) {
+ ret = -ENODEV;
+ goto ini_nomem;
+ }
nr_init_grefs = nr_grant_frames * GREFS_PER_GRANT_FRAME;
@@ -1070,7 +1075,7 @@
for (i--; i >= 0; i--)
free_page((unsigned long)gnttab_list[i]);
kfree(gnttab_list);
- return -ENOMEM;
+ return ret;
}
EXPORT_SYMBOL_GPL(gnttab_init);
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index 9e14ae6..412b96c 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -132,6 +132,7 @@
err = dpm_suspend_end(PMSG_FREEZE);
if (err) {
printk(KERN_ERR "dpm_suspend_end failed: %d\n", err);
+ si.cancelled = 0;
goto out_resume;
}
diff --git a/drivers/xen/xenbus/xenbus_probe_frontend.c b/drivers/xen/xenbus/xenbus_probe_frontend.c
index f20c5f1..a31b54d 100644
--- a/drivers/xen/xenbus/xenbus_probe_frontend.c
+++ b/drivers/xen/xenbus/xenbus_probe_frontend.c
@@ -135,7 +135,7 @@
return xenbus_read_otherend_details(xendev, "backend-id", "backend");
}
-static int is_device_connecting(struct device *dev, void *data)
+static int is_device_connecting(struct device *dev, void *data, bool ignore_nonessential)
{
struct xenbus_device *xendev = to_xenbus_device(dev);
struct device_driver *drv = data;
@@ -152,16 +152,41 @@
if (drv && (dev->driver != drv))
return 0;
+ if (ignore_nonessential) {
+ /* With older QEMU, for PVonHVM guests the guest config files
+ * could contain: vfb = [ 'vnc=1, vnclisten=0.0.0.0']
+ * which is nonsensical as there is no PV FB (there can be
+ * a PVKB) running as HVM guest. */
+
+ if ((strncmp(xendev->nodename, "device/vkbd", 11) == 0))
+ return 0;
+
+ if ((strncmp(xendev->nodename, "device/vfb", 10) == 0))
+ return 0;
+ }
xendrv = to_xenbus_driver(dev->driver);
return (xendev->state < XenbusStateConnected ||
(xendev->state == XenbusStateConnected &&
xendrv->is_ready && !xendrv->is_ready(xendev)));
}
+static int essential_device_connecting(struct device *dev, void *data)
+{
+ return is_device_connecting(dev, data, true /* ignore PV[KBB+FB] */);
+}
+static int non_essential_device_connecting(struct device *dev, void *data)
+{
+ return is_device_connecting(dev, data, false);
+}
-static int exists_connecting_device(struct device_driver *drv)
+static int exists_essential_connecting_device(struct device_driver *drv)
{
return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
- is_device_connecting);
+ essential_device_connecting);
+}
+static int exists_non_essential_connecting_device(struct device_driver *drv)
+{
+ return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
+ non_essential_device_connecting);
}
static int print_device_status(struct device *dev, void *data)
@@ -192,6 +217,23 @@
/* We only wait for device setup after most initcalls have run. */
static int ready_to_wait_for_devices;
+static bool wait_loop(unsigned long start, unsigned int max_delay,
+ unsigned int *seconds_waited)
+{
+ if (time_after(jiffies, start + (*seconds_waited+5)*HZ)) {
+ if (!*seconds_waited)
+ printk(KERN_WARNING "XENBUS: Waiting for "
+ "devices to initialise: ");
+ *seconds_waited += 5;
+ printk("%us...", max_delay - *seconds_waited);
+ if (*seconds_waited == max_delay)
+ return true;
+ }
+
+ schedule_timeout_interruptible(HZ/10);
+
+ return false;
+}
/*
* On a 5-minute timeout, wait for all devices currently configured. We need
* to do this to guarantee that the filesystems and / or network devices
@@ -215,19 +257,14 @@
if (!ready_to_wait_for_devices || !xen_domain())
return;
- while (exists_connecting_device(drv)) {
- if (time_after(jiffies, start + (seconds_waited+5)*HZ)) {
- if (!seconds_waited)
- printk(KERN_WARNING "XENBUS: Waiting for "
- "devices to initialise: ");
- seconds_waited += 5;
- printk("%us...", 300 - seconds_waited);
- if (seconds_waited == 300)
- break;
- }
+ while (exists_non_essential_connecting_device(drv))
+ if (wait_loop(start, 30, &seconds_waited))
+ break;
- schedule_timeout_interruptible(HZ/10);
- }
+ /* Skips PVKB and PVFB check.*/
+ while (exists_essential_connecting_device(drv))
+ if (wait_loop(start, 270, &seconds_waited))
+ break;
if (seconds_waited)
printk("\n");
diff --git a/fs/aio.c b/fs/aio.c
index da88760..67a6db3 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -93,9 +93,8 @@
put_page(info->ring_pages[i]);
if (info->mmap_size) {
- down_write(&ctx->mm->mmap_sem);
- do_munmap(ctx->mm, info->mmap_base, info->mmap_size);
- up_write(&ctx->mm->mmap_sem);
+ BUG_ON(ctx->mm != current->mm);
+ vm_munmap(info->mmap_base, info->mmap_size);
}
if (info->ring_pages && info->ring_pages != info->internal_pages)
@@ -389,6 +388,17 @@
"exit_aio:ioctx still alive: %d %d %d\n",
atomic_read(&ctx->users), ctx->dead,
ctx->reqs_active);
+ /*
+ * We don't need to bother with munmap() here -
+ * exit_mmap(mm) is coming and it'll unmap everything.
+ * Since aio_free_ring() uses non-zero ->mmap_size
+ * as indicator that it needs to unmap the area,
+ * just set it to 0; aio_free_ring() is the only
+ * place that uses ->mmap_size, so it's safe.
+ * That way we get all munmap done to current->mm -
+ * all other callers have ctx->mm == current->mm.
+ */
+ ctx->ring_info.mmap_size = 0;
put_ioctx(ctx);
}
}
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
index 2eb12f1..d146e18 100644
--- a/fs/binfmt_aout.c
+++ b/fs/binfmt_aout.c
@@ -50,9 +50,7 @@
end = PAGE_ALIGN(end);
if (end > start) {
unsigned long addr;
- down_write(¤t->mm->mmap_sem);
- addr = do_brk(start, end - start);
- up_write(¤t->mm->mmap_sem);
+ addr = vm_brk(start, end - start);
if (BAD_ADDR(addr))
return addr;
}
@@ -280,9 +278,7 @@
pos = 32;
map_size = ex.a_text+ex.a_data;
#endif
- down_write(¤t->mm->mmap_sem);
- error = do_brk(text_addr & PAGE_MASK, map_size);
- up_write(¤t->mm->mmap_sem);
+ error = vm_brk(text_addr & PAGE_MASK, map_size);
if (error != (text_addr & PAGE_MASK)) {
send_sig(SIGKILL, current, 0);
return error;
@@ -313,9 +309,7 @@
if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) {
loff_t pos = fd_offset;
- down_write(¤t->mm->mmap_sem);
- do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
- up_write(¤t->mm->mmap_sem);
+ vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
bprm->file->f_op->read(bprm->file,
(char __user *)N_TXTADDR(ex),
ex.a_text+ex.a_data, &pos);
@@ -325,24 +319,20 @@
goto beyond_if;
}
- down_write(¤t->mm->mmap_sem);
- error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
+ error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
fd_offset);
- up_write(¤t->mm->mmap_sem);
if (error != N_TXTADDR(ex)) {
send_sig(SIGKILL, current, 0);
return error;
}
- down_write(¤t->mm->mmap_sem);
- error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
+ error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
fd_offset + ex.a_text);
- up_write(¤t->mm->mmap_sem);
if (error != N_DATADDR(ex)) {
send_sig(SIGKILL, current, 0);
return error;
@@ -412,9 +402,7 @@
"N_TXTOFF is not page aligned. Please convert library: %s\n",
file->f_path.dentry->d_name.name);
}
- down_write(¤t->mm->mmap_sem);
- do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
- up_write(¤t->mm->mmap_sem);
+ vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
file->f_op->read(file, (char __user *)start_addr,
ex.a_text + ex.a_data, &pos);
@@ -425,12 +413,10 @@
goto out;
}
/* Now use mmap to map the library into memory. */
- down_write(¤t->mm->mmap_sem);
- error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
+ error = vm_mmap(file, start_addr, ex.a_text + ex.a_data,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
N_TXTOFF(ex));
- up_write(¤t->mm->mmap_sem);
retval = error;
if (error != start_addr)
goto out;
@@ -438,9 +424,7 @@
len = PAGE_ALIGN(ex.a_text + ex.a_data);
bss = ex.a_text + ex.a_data + ex.a_bss;
if (bss > len) {
- down_write(¤t->mm->mmap_sem);
- error = do_brk(start_addr + len, bss - len);
- up_write(¤t->mm->mmap_sem);
+ error = vm_brk(start_addr + len, bss - len);
retval = error;
if (error != start_addr + len)
goto out;
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 48ffb3d..16f7354 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -82,9 +82,7 @@
end = ELF_PAGEALIGN(end);
if (end > start) {
unsigned long addr;
- down_write(¤t->mm->mmap_sem);
- addr = do_brk(start, end - start);
- up_write(¤t->mm->mmap_sem);
+ addr = vm_brk(start, end - start);
if (BAD_ADDR(addr))
return addr;
}
@@ -514,9 +512,7 @@
elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1);
/* Map the last of the bss segment */
- down_write(¤t->mm->mmap_sem);
- error = do_brk(elf_bss, last_bss - elf_bss);
- up_write(¤t->mm->mmap_sem);
+ error = vm_brk(elf_bss, last_bss - elf_bss);
if (BAD_ADDR(error))
goto out_close;
}
@@ -962,10 +958,8 @@
and some applications "depend" upon this behavior.
Since we do not have the power to recompile these, we
emulate the SVr4 behavior. Sigh. */
- down_write(¤t->mm->mmap_sem);
- error = do_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC,
+ error = vm_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE, 0);
- up_write(¤t->mm->mmap_sem);
}
#ifdef ELF_PLAT_INIT
@@ -1050,8 +1044,7 @@
eppnt++;
/* Now use mmap to map the library into memory. */
- down_write(¤t->mm->mmap_sem);
- error = do_mmap(file,
+ error = vm_mmap(file,
ELF_PAGESTART(eppnt->p_vaddr),
(eppnt->p_filesz +
ELF_PAGEOFFSET(eppnt->p_vaddr)),
@@ -1059,7 +1052,6 @@
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
(eppnt->p_offset -
ELF_PAGEOFFSET(eppnt->p_vaddr)));
- up_write(¤t->mm->mmap_sem);
if (error != ELF_PAGESTART(eppnt->p_vaddr))
goto out_free_ph;
@@ -1072,11 +1064,8 @@
len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr +
ELF_MIN_ALIGN - 1);
bss = eppnt->p_memsz + eppnt->p_vaddr;
- if (bss > len) {
- down_write(¤t->mm->mmap_sem);
- do_brk(len, bss - len);
- up_write(¤t->mm->mmap_sem);
- }
+ if (bss > len)
+ vm_brk(len, bss - len);
error = 0;
out_free_ph:
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 9bd5612..d390a0f 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -390,21 +390,17 @@
(executable_stack == EXSTACK_DEFAULT && VM_STACK_FLAGS & VM_EXEC))
stack_prot |= PROT_EXEC;
- down_write(¤t->mm->mmap_sem);
- current->mm->start_brk = do_mmap(NULL, 0, stack_size, stack_prot,
+ current->mm->start_brk = vm_mmap(NULL, 0, stack_size, stack_prot,
MAP_PRIVATE | MAP_ANONYMOUS |
MAP_UNINITIALIZED | MAP_GROWSDOWN,
0);
if (IS_ERR_VALUE(current->mm->start_brk)) {
- up_write(¤t->mm->mmap_sem);
retval = current->mm->start_brk;
current->mm->start_brk = 0;
goto error_kill;
}
- up_write(¤t->mm->mmap_sem);
-
current->mm->brk = current->mm->start_brk;
current->mm->context.end_brk = current->mm->start_brk;
current->mm->context.end_brk +=
@@ -955,10 +951,8 @@
if (params->flags & ELF_FDPIC_FLAG_EXECUTABLE)
mflags |= MAP_EXECUTABLE;
- down_write(&mm->mmap_sem);
- maddr = do_mmap(NULL, load_addr, top - base,
+ maddr = vm_mmap(NULL, load_addr, top - base,
PROT_READ | PROT_WRITE | PROT_EXEC, mflags, 0);
- up_write(&mm->mmap_sem);
if (IS_ERR_VALUE(maddr))
return (int) maddr;
@@ -1096,10 +1090,8 @@
/* create the mapping */
disp = phdr->p_vaddr & ~PAGE_MASK;
- down_write(&mm->mmap_sem);
- maddr = do_mmap(file, maddr, phdr->p_memsz + disp, prot, flags,
+ maddr = vm_mmap(file, maddr, phdr->p_memsz + disp, prot, flags,
phdr->p_offset - disp);
- up_write(&mm->mmap_sem);
kdebug("mmap[%d] <file> sz=%lx pr=%x fl=%x of=%lx --> %08lx",
loop, phdr->p_memsz + disp, prot, flags,
@@ -1143,10 +1135,8 @@
unsigned long xmaddr;
flags |= MAP_FIXED | MAP_ANONYMOUS;
- down_write(&mm->mmap_sem);
- xmaddr = do_mmap(NULL, xaddr, excess - excess1,
+ xmaddr = vm_mmap(NULL, xaddr, excess - excess1,
prot, flags, 0);
- up_write(&mm->mmap_sem);
kdebug("mmap[%d] <anon>"
" ad=%lx sz=%lx pr=%x fl=%x of=0 --> %08lx",
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 024d20e..6b2daf9 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -542,10 +542,8 @@
*/
DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n");
- down_write(¤t->mm->mmap_sem);
- textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC,
+ textpos = vm_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC,
MAP_PRIVATE|MAP_EXECUTABLE, 0);
- up_write(¤t->mm->mmap_sem);
if (!textpos || IS_ERR_VALUE(textpos)) {
if (!textpos)
textpos = (unsigned long) -ENOMEM;
@@ -556,10 +554,8 @@
len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
len = PAGE_ALIGN(len);
- down_write(¤t->mm->mmap_sem);
- realdatastart = do_mmap(0, 0, len,
+ realdatastart = vm_mmap(0, 0, len,
PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
- up_write(¤t->mm->mmap_sem);
if (realdatastart == 0 || IS_ERR_VALUE(realdatastart)) {
if (!realdatastart)
@@ -603,10 +599,8 @@
len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
len = PAGE_ALIGN(len);
- down_write(¤t->mm->mmap_sem);
- textpos = do_mmap(0, 0, len,
+ textpos = vm_mmap(0, 0, len,
PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
- up_write(¤t->mm->mmap_sem);
if (!textpos || IS_ERR_VALUE(textpos)) {
if (!textpos)
diff --git a/fs/binfmt_som.c b/fs/binfmt_som.c
index e4fc746..4517aaf 100644
--- a/fs/binfmt_som.c
+++ b/fs/binfmt_som.c
@@ -147,10 +147,8 @@
code_size = SOM_PAGEALIGN(hpuxhdr->exec_tsize);
current->mm->start_code = code_start;
current->mm->end_code = code_start + code_size;
- down_write(¤t->mm->mmap_sem);
- retval = do_mmap(file, code_start, code_size, prot,
+ retval = vm_mmap(file, code_start, code_size, prot,
flags, SOM_PAGESTART(hpuxhdr->exec_tfile));
- up_write(¤t->mm->mmap_sem);
if (retval < 0 && retval > -1024)
goto out;
@@ -158,20 +156,16 @@
data_size = SOM_PAGEALIGN(hpuxhdr->exec_dsize);
current->mm->start_data = data_start;
current->mm->end_data = bss_start = data_start + data_size;
- down_write(¤t->mm->mmap_sem);
- retval = do_mmap(file, data_start, data_size,
+ retval = vm_mmap(file, data_start, data_size,
prot | PROT_WRITE, flags,
SOM_PAGESTART(hpuxhdr->exec_dfile));
- up_write(¤t->mm->mmap_sem);
if (retval < 0 && retval > -1024)
goto out;
som_brk = bss_start + SOM_PAGEALIGN(hpuxhdr->exec_bsize);
current->mm->start_brk = current->mm->brk = som_brk;
- down_write(¤t->mm->mmap_sem);
- retval = do_mmap(NULL, bss_start, som_brk - bss_start,
+ retval = vm_mmap(NULL, bss_start, som_brk - bss_start,
prot | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, 0);
- up_write(¤t->mm->mmap_sem);
if (retval > 0 || retval < -1024)
retval = 0;
out:
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 5b8ef8e..3f65a81 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2166,7 +2166,7 @@
static inline bool btrfs_root_readonly(struct btrfs_root *root)
{
- return root->root_item.flags & BTRFS_ROOT_SUBVOL_RDONLY;
+ return (root->root_item.flags & cpu_to_le64(BTRFS_ROOT_SUBVOL_RDONLY)) != 0;
}
/* struct btrfs_root_backup */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index d81e933..f31dc9a 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -109,6 +109,8 @@
/* Options which could be blank */
Opt_blank_pass,
+ Opt_blank_user,
+ Opt_blank_ip,
Opt_err
};
@@ -183,11 +185,15 @@
{ Opt_wsize, "wsize=%s" },
{ Opt_actimeo, "actimeo=%s" },
+ { Opt_blank_user, "user=" },
+ { Opt_blank_user, "username=" },
{ Opt_user, "user=%s" },
{ Opt_user, "username=%s" },
{ Opt_blank_pass, "pass=" },
{ Opt_pass, "pass=%s" },
{ Opt_pass, "password=%s" },
+ { Opt_blank_ip, "ip=" },
+ { Opt_blank_ip, "addr=" },
{ Opt_ip, "ip=%s" },
{ Opt_ip, "addr=%s" },
{ Opt_unc, "unc=%s" },
@@ -1117,7 +1123,7 @@
string = match_strdup(args);
if (string == NULL)
return -ENOMEM;
- rc = kstrtoul(string, 10, option);
+ rc = kstrtoul(string, 0, option);
kfree(string);
return rc;
@@ -1534,15 +1540,17 @@
/* String Arguments */
+ case Opt_blank_user:
+ /* null user, ie. anonymous authentication */
+ vol->nullauth = 1;
+ vol->username = NULL;
+ break;
case Opt_user:
string = match_strdup(args);
if (string == NULL)
goto out_nomem;
- if (!*string) {
- /* null user, ie. anonymous authentication */
- vol->nullauth = 1;
- } else if (strnlen(string, MAX_USERNAME_SIZE) >
+ if (strnlen(string, MAX_USERNAME_SIZE) >
MAX_USERNAME_SIZE) {
printk(KERN_WARNING "CIFS: username too long\n");
goto cifs_parse_mount_err;
@@ -1611,14 +1619,15 @@
}
vol->password[j] = '\0';
break;
+ case Opt_blank_ip:
+ vol->UNCip = NULL;
+ break;
case Opt_ip:
string = match_strdup(args);
if (string == NULL)
goto out_nomem;
- if (!*string) {
- vol->UNCip = NULL;
- } else if (strnlen(string, INET6_ADDRSTRLEN) >
+ if (strnlen(string, INET6_ADDRSTRLEN) >
INET6_ADDRSTRLEN) {
printk(KERN_WARNING "CIFS: ip address "
"too long\n");
@@ -1636,12 +1645,6 @@
if (string == NULL)
goto out_nomem;
- if (!*string) {
- printk(KERN_WARNING "CIFS: invalid path to "
- "network resource\n");
- goto cifs_parse_mount_err;
- }
-
temp_len = strnlen(string, 300);
if (temp_len == 300) {
printk(KERN_WARNING "CIFS: UNC name too long\n");
@@ -1670,11 +1673,7 @@
if (string == NULL)
goto out_nomem;
- if (!*string) {
- printk(KERN_WARNING "CIFS: invalid domain"
- " name\n");
- goto cifs_parse_mount_err;
- } else if (strnlen(string, 256) == 256) {
+ if (strnlen(string, 256) == 256) {
printk(KERN_WARNING "CIFS: domain name too"
" long\n");
goto cifs_parse_mount_err;
@@ -1693,11 +1692,7 @@
if (string == NULL)
goto out_nomem;
- if (!*string) {
- printk(KERN_WARNING "CIFS: srcaddr value not"
- " specified\n");
- goto cifs_parse_mount_err;
- } else if (!cifs_convert_address(
+ if (!cifs_convert_address(
(struct sockaddr *)&vol->srcaddr,
string, strlen(string))) {
printk(KERN_WARNING "CIFS: Could not parse"
@@ -1710,11 +1705,6 @@
if (string == NULL)
goto out_nomem;
- if (!*string) {
- printk(KERN_WARNING "CIFS: Invalid path"
- " prefix\n");
- goto cifs_parse_mount_err;
- }
temp_len = strnlen(string, 1024);
if (string[0] != '/')
temp_len++; /* missing leading slash */
@@ -1742,11 +1732,7 @@
if (string == NULL)
goto out_nomem;
- if (!*string) {
- printk(KERN_WARNING "CIFS: Invalid iocharset"
- " specified\n");
- goto cifs_parse_mount_err;
- } else if (strnlen(string, 1024) >= 65) {
+ if (strnlen(string, 1024) >= 65) {
printk(KERN_WARNING "CIFS: iocharset name "
"too long.\n");
goto cifs_parse_mount_err;
@@ -1771,11 +1757,6 @@
if (string == NULL)
goto out_nomem;
- if (!*string) {
- printk(KERN_WARNING "CIFS: No socket option"
- " specified\n");
- goto cifs_parse_mount_err;
- }
if (strnicmp(string, "TCP_NODELAY", 11) == 0)
vol->sockopt_tcp_nodelay = 1;
break;
@@ -1784,12 +1765,6 @@
if (string == NULL)
goto out_nomem;
- if (!*string) {
- printk(KERN_WARNING "CIFS: Invalid (empty)"
- " netbiosname\n");
- break;
- }
-
memset(vol->source_rfc1001_name, 0x20,
RFC1001_NAME_LEN);
/*
@@ -1817,11 +1792,6 @@
if (string == NULL)
goto out_nomem;
- if (!*string) {
- printk(KERN_WARNING "CIFS: Empty server"
- " netbiosname specified\n");
- break;
- }
/* last byte, type, is 0x20 for servr type */
memset(vol->target_rfc1001_name, 0x20,
RFC1001_NAME_LEN_WITH_NULL);
@@ -1848,12 +1818,6 @@
if (string == NULL)
goto out_nomem;
- if (!*string) {
- cERROR(1, "no protocol version specified"
- " after vers= mount option");
- goto cifs_parse_mount_err;
- }
-
if (strnicmp(string, "cifs", 4) == 0 ||
strnicmp(string, "1", 1) == 0) {
/* This is the default */
@@ -1868,12 +1832,6 @@
if (string == NULL)
goto out_nomem;
- if (!*string) {
- printk(KERN_WARNING "CIFS: no security flavor"
- " specified\n");
- break;
- }
-
if (cifs_parse_security_flavors(string, vol) != 0)
goto cifs_parse_mount_err;
break;
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index ab2594a..0e01e90 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1203,9 +1203,6 @@
unsigned long s_ext_blocks;
unsigned long s_ext_extents;
#endif
- /* ext4 extent cache stats */
- unsigned long extent_cache_hits;
- unsigned long extent_cache_misses;
/* for buddy allocator */
struct ext4_group_info ***s_group_info;
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 1421938..abcdeab 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -2066,10 +2066,6 @@
ret = 1;
}
errout:
- if (!ret)
- sbi->extent_cache_misses++;
- else
- sbi->extent_cache_hits++;
trace_ext4_ext_in_cache(inode, block, ret);
spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
return ret;
@@ -2882,7 +2878,7 @@
if (err)
goto fix_extent_len;
/* update the extent length and mark as initialized */
- ex->ee_len = cpu_to_le32(ee_len);
+ ex->ee_len = cpu_to_le16(ee_len);
ext4_ext_try_to_merge(inode, path, ex);
err = ext4_ext_dirty(handle, inode, path + depth);
goto out;
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index ceebaf8..6da193564 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1305,20 +1305,20 @@
ext4_msg(sb, KERN_ERR,
"Cannot change journaled "
"quota options when quota turned on");
- return 0;
+ return -1;
}
qname = match_strdup(args);
if (!qname) {
ext4_msg(sb, KERN_ERR,
"Not enough memory for storing quotafile name");
- return 0;
+ return -1;
}
if (sbi->s_qf_names[qtype] &&
strcmp(sbi->s_qf_names[qtype], qname)) {
ext4_msg(sb, KERN_ERR,
"%s quota file already specified", QTYPE2NAME(qtype));
kfree(qname);
- return 0;
+ return -1;
}
sbi->s_qf_names[qtype] = qname;
if (strchr(sbi->s_qf_names[qtype], '/')) {
@@ -1326,7 +1326,7 @@
"quotafile must be on filesystem root");
kfree(sbi->s_qf_names[qtype]);
sbi->s_qf_names[qtype] = NULL;
- return 0;
+ return -1;
}
set_opt(sb, QUOTA);
return 1;
@@ -1341,7 +1341,7 @@
sbi->s_qf_names[qtype]) {
ext4_msg(sb, KERN_ERR, "Cannot change journaled quota options"
" when quota turned on");
- return 0;
+ return -1;
}
/*
* The space will be released later when all options are confirmed
@@ -1450,6 +1450,16 @@
const struct mount_opts *m;
int arg = 0;
+#ifdef CONFIG_QUOTA
+ if (token == Opt_usrjquota)
+ return set_qf_name(sb, USRQUOTA, &args[0]);
+ else if (token == Opt_grpjquota)
+ return set_qf_name(sb, GRPQUOTA, &args[0]);
+ else if (token == Opt_offusrjquota)
+ return clear_qf_name(sb, USRQUOTA);
+ else if (token == Opt_offgrpjquota)
+ return clear_qf_name(sb, GRPQUOTA);
+#endif
if (args->from && match_int(args, &arg))
return -1;
switch (token) {
@@ -1549,18 +1559,6 @@
sbi->s_mount_opt |= m->mount_opt;
}
#ifdef CONFIG_QUOTA
- } else if (token == Opt_usrjquota) {
- if (!set_qf_name(sb, USRQUOTA, &args[0]))
- return -1;
- } else if (token == Opt_grpjquota) {
- if (!set_qf_name(sb, GRPQUOTA, &args[0]))
- return -1;
- } else if (token == Opt_offusrjquota) {
- if (!clear_qf_name(sb, USRQUOTA))
- return -1;
- } else if (token == Opt_offgrpjquota) {
- if (!clear_qf_name(sb, GRPQUOTA))
- return -1;
} else if (m->flags & MOPT_QFMT) {
if (sb_any_quota_loaded(sb) &&
sbi->s_jquota_fmt != m->mount_opt) {
@@ -2366,18 +2364,6 @@
EXT4_SB(sb)->s_sectors_written_start) >> 1)));
}
-static ssize_t extent_cache_hits_show(struct ext4_attr *a,
- struct ext4_sb_info *sbi, char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "%lu\n", sbi->extent_cache_hits);
-}
-
-static ssize_t extent_cache_misses_show(struct ext4_attr *a,
- struct ext4_sb_info *sbi, char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "%lu\n", sbi->extent_cache_misses);
-}
-
static ssize_t inode_readahead_blks_store(struct ext4_attr *a,
struct ext4_sb_info *sbi,
const char *buf, size_t count)
@@ -2435,8 +2421,6 @@
EXT4_RO_ATTR(delayed_allocation_blocks);
EXT4_RO_ATTR(session_write_kbytes);
EXT4_RO_ATTR(lifetime_write_kbytes);
-EXT4_RO_ATTR(extent_cache_hits);
-EXT4_RO_ATTR(extent_cache_misses);
EXT4_ATTR_OFFSET(inode_readahead_blks, 0644, sbi_ui_show,
inode_readahead_blks_store, s_inode_readahead_blks);
EXT4_RW_ATTR_SBI_UI(inode_goal, s_inode_goal);
@@ -2452,8 +2436,6 @@
ATTR_LIST(delayed_allocation_blocks),
ATTR_LIST(session_write_kbytes),
ATTR_LIST(lifetime_write_kbytes),
- ATTR_LIST(extent_cache_hits),
- ATTR_LIST(extent_cache_misses),
ATTR_LIST(inode_readahead_blks),
ATTR_LIST(inode_goal),
ATTR_LIST(mb_stats),
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 2066328..df5ac04 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -387,9 +387,6 @@
if (fc->no_create)
return -ENOSYS;
- if (flags & O_DIRECT)
- return -EINVAL;
-
forget = fuse_alloc_forget();
if (!forget)
return -ENOMEM;
@@ -644,13 +641,12 @@
fuse_put_request(fc, req);
if (!err) {
struct inode *inode = entry->d_inode;
+ struct fuse_inode *fi = get_fuse_inode(inode);
- /*
- * Set nlink to zero so the inode can be cleared, if the inode
- * does have more links this will be discovered at the next
- * lookup/getattr.
- */
- clear_nlink(inode);
+ spin_lock(&fc->lock);
+ fi->attr_version = ++fc->attr_version;
+ drop_nlink(inode);
+ spin_unlock(&fc->lock);
fuse_invalidate_attr(inode);
fuse_invalidate_attr(dir);
fuse_invalidate_entry_cache(entry);
@@ -762,8 +758,17 @@
will reflect changes in the backing inode (link count,
etc.)
*/
- if (!err || err == -EINTR)
+ if (!err) {
+ struct fuse_inode *fi = get_fuse_inode(inode);
+
+ spin_lock(&fc->lock);
+ fi->attr_version = ++fc->attr_version;
+ inc_nlink(inode);
+ spin_unlock(&fc->lock);
fuse_invalidate_attr(inode);
+ } else if (err == -EINTR) {
+ fuse_invalidate_attr(inode);
+ }
return err;
}
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index a841868..504e61b 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -194,10 +194,6 @@
struct fuse_conn *fc = get_fuse_conn(inode);
int err;
- /* VFS checks this, but only _after_ ->open() */
- if (file->f_flags & O_DIRECT)
- return -EINVAL;
-
err = generic_file_open(inode, file);
if (err)
return err;
@@ -932,17 +928,23 @@
struct file *file = iocb->ki_filp;
struct address_space *mapping = file->f_mapping;
size_t count = 0;
+ size_t ocount = 0;
ssize_t written = 0;
+ ssize_t written_buffered = 0;
struct inode *inode = mapping->host;
ssize_t err;
struct iov_iter i;
+ loff_t endbyte = 0;
WARN_ON(iocb->ki_pos != pos);
- err = generic_segment_checks(iov, &nr_segs, &count, VERIFY_READ);
+ ocount = 0;
+ err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ);
if (err)
return err;
+ count = ocount;
+
mutex_lock(&inode->i_mutex);
vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
@@ -962,11 +964,41 @@
file_update_time(file);
- iov_iter_init(&i, iov, nr_segs, count, 0);
- written = fuse_perform_write(file, mapping, &i, pos);
- if (written >= 0)
- iocb->ki_pos = pos + written;
+ if (file->f_flags & O_DIRECT) {
+ written = generic_file_direct_write(iocb, iov, &nr_segs,
+ pos, &iocb->ki_pos,
+ count, ocount);
+ if (written < 0 || written == count)
+ goto out;
+ pos += written;
+ count -= written;
+
+ iov_iter_init(&i, iov, nr_segs, count, written);
+ written_buffered = fuse_perform_write(file, mapping, &i, pos);
+ if (written_buffered < 0) {
+ err = written_buffered;
+ goto out;
+ }
+ endbyte = pos + written_buffered - 1;
+
+ err = filemap_write_and_wait_range(file->f_mapping, pos,
+ endbyte);
+ if (err)
+ goto out;
+
+ invalidate_mapping_pages(file->f_mapping,
+ pos >> PAGE_CACHE_SHIFT,
+ endbyte >> PAGE_CACHE_SHIFT);
+
+ written += written_buffered;
+ iocb->ki_pos = pos + written_buffered;
+ } else {
+ iov_iter_init(&i, iov, nr_segs, count, 0);
+ written = fuse_perform_write(file, mapping, &i, pos);
+ if (written >= 0)
+ iocb->ki_pos = pos + written;
+ }
out:
current->backing_dev_info = NULL;
mutex_unlock(&inode->i_mutex);
@@ -1101,6 +1133,24 @@
return res;
}
+static ssize_t __fuse_direct_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct inode *inode = file->f_path.dentry->d_inode;
+ ssize_t res;
+
+ res = generic_write_checks(file, ppos, &count, 0);
+ if (!res) {
+ res = fuse_direct_io(file, buf, count, ppos, 1);
+ if (res > 0)
+ fuse_write_update_size(inode, *ppos);
+ }
+
+ fuse_invalidate_attr(inode);
+
+ return res;
+}
+
static ssize_t fuse_direct_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
@@ -1112,16 +1162,9 @@
/* Don't allow parallel writes to the same file */
mutex_lock(&inode->i_mutex);
- res = generic_write_checks(file, ppos, &count, 0);
- if (!res) {
- res = fuse_direct_io(file, buf, count, ppos, 1);
- if (res > 0)
- fuse_write_update_size(inode, *ppos);
- }
+ res = __fuse_direct_write(file, buf, count, ppos);
mutex_unlock(&inode->i_mutex);
- fuse_invalidate_attr(inode);
-
return res;
}
@@ -2077,6 +2120,57 @@
return 0;
}
+static ssize_t fuse_loop_dio(struct file *filp, const struct iovec *iov,
+ unsigned long nr_segs, loff_t *ppos, int rw)
+{
+ const struct iovec *vector = iov;
+ ssize_t ret = 0;
+
+ while (nr_segs > 0) {
+ void __user *base;
+ size_t len;
+ ssize_t nr;
+
+ base = vector->iov_base;
+ len = vector->iov_len;
+ vector++;
+ nr_segs--;
+
+ if (rw == WRITE)
+ nr = __fuse_direct_write(filp, base, len, ppos);
+ else
+ nr = fuse_direct_read(filp, base, len, ppos);
+
+ if (nr < 0) {
+ if (!ret)
+ ret = nr;
+ break;
+ }
+ ret += nr;
+ if (nr != len)
+ break;
+ }
+
+ return ret;
+}
+
+
+static ssize_t
+fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
+ loff_t offset, unsigned long nr_segs)
+{
+ ssize_t ret = 0;
+ struct file *file = NULL;
+ loff_t pos = 0;
+
+ file = iocb->ki_filp;
+ pos = offset;
+
+ ret = fuse_loop_dio(file, iov, nr_segs, &pos, rw);
+
+ return ret;
+}
+
static const struct file_operations fuse_file_operations = {
.llseek = fuse_file_llseek,
.read = do_sync_read,
@@ -2120,6 +2214,7 @@
.readpages = fuse_readpages,
.set_page_dirty = __set_page_dirty_nobuffers,
.bmap = fuse_bmap,
+ .direct_IO = fuse_direct_IO,
};
void fuse_init_file_inode(struct inode *inode)
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 4aec599..26783eb 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -947,6 +947,7 @@
sb->s_magic = FUSE_SUPER_MAGIC;
sb->s_op = &fuse_super_operations;
sb->s_maxbytes = MAX_LFS_FILESIZE;
+ sb->s_time_gran = 1;
sb->s_export_op = &fuse_export_operations;
file = fget(d.fd);
diff --git a/fs/lockd/clnt4xdr.c b/fs/lockd/clnt4xdr.c
index 3ddcbb1..13ad153 100644
--- a/fs/lockd/clnt4xdr.c
+++ b/fs/lockd/clnt4xdr.c
@@ -241,7 +241,7 @@
p = xdr_inline_decode(xdr, 4);
if (unlikely(p == NULL))
goto out_overflow;
- if (unlikely(*p > nlm4_failed))
+ if (unlikely(ntohl(*p) > ntohl(nlm4_failed)))
goto out_bad_xdr;
*stat = *p;
return 0;
diff --git a/fs/lockd/clntxdr.c b/fs/lockd/clntxdr.c
index 3d35e3e..d269ada 100644
--- a/fs/lockd/clntxdr.c
+++ b/fs/lockd/clntxdr.c
@@ -236,7 +236,7 @@
p = xdr_inline_decode(xdr, 4);
if (unlikely(p == NULL))
goto out_overflow;
- if (unlikely(*p > nlm_lck_denied_grace_period))
+ if (unlikely(ntohl(*p) > ntohl(nlm_lck_denied_grace_period)))
goto out_enum;
*stat = *p;
return 0;
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 08c6e36..43f46cd 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -803,13 +803,13 @@
return p;
}
-static int
+static __be32
compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
const char *name, int namlen)
{
struct svc_export *exp;
struct dentry *dparent, *dchild;
- int rv = 0;
+ __be32 rv = nfserr_noent;
dparent = cd->fh.fh_dentry;
exp = cd->fh.fh_export;
@@ -817,26 +817,20 @@
if (isdotent(name, namlen)) {
if (namlen == 2) {
dchild = dget_parent(dparent);
- if (dchild == dparent) {
- /* filesystem root - cannot return filehandle for ".." */
- dput(dchild);
- return -ENOENT;
- }
+ /* filesystem root - cannot return filehandle for ".." */
+ if (dchild == dparent)
+ goto out;
} else
dchild = dget(dparent);
} else
dchild = lookup_one_len(name, dparent, namlen);
if (IS_ERR(dchild))
- return -ENOENT;
- rv = -ENOENT;
+ return rv;
if (d_mountpoint(dchild))
goto out;
- rv = fh_compose(fhp, exp, dchild, &cd->fh);
- if (rv)
- goto out;
if (!dchild->d_inode)
goto out;
- rv = 0;
+ rv = fh_compose(fhp, exp, dchild, &cd->fh);
out:
dput(dchild);
return rv;
@@ -845,7 +839,7 @@
static __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, int namlen)
{
struct svc_fh fh;
- int err;
+ __be32 err;
fh_init(&fh, NFS3_FHSIZE);
err = compose_entry_fh(cd, &fh, name, namlen);
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 2ed14df..987e719 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -235,17 +235,17 @@
*/
if (open->op_createmode == NFS4_CREATE_EXCLUSIVE && status == 0)
open->op_bmval[1] = (FATTR4_WORD1_TIME_ACCESS |
- FATTR4_WORD1_TIME_MODIFY);
+ FATTR4_WORD1_TIME_MODIFY);
} else {
status = nfsd_lookup(rqstp, current_fh,
open->op_fname.data, open->op_fname.len, resfh);
fh_unlock(current_fh);
- if (status)
- goto out;
- status = nfsd_check_obj_isreg(resfh);
}
if (status)
goto out;
+ status = nfsd_check_obj_isreg(resfh);
+ if (status)
+ goto out;
if (is_create_with_attrs(open) && open->op_acl != NULL)
do_set_nfs4_acl(rqstp, resfh, open->op_acl, open->op_bmval);
@@ -841,6 +841,7 @@
struct nfsd4_setattr *setattr)
{
__be32 status = nfs_ok;
+ int err;
if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
nfs4_lock_state();
@@ -852,9 +853,9 @@
return status;
}
}
- status = fh_want_write(&cstate->current_fh);
- if (status)
- return status;
+ err = fh_want_write(&cstate->current_fh);
+ if (err)
+ return nfserrno(err);
status = nfs_ok;
status = check_attr_support(rqstp, cstate, setattr->sa_bmval,
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 1841f8b..7f71c69 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -4211,16 +4211,14 @@
* vfs_test_lock. (Arguably perhaps test_lock should be done with an
* inode operation.)
*/
-static int nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock)
+static __be32 nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock)
{
struct file *file;
- int err;
-
- err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file);
- if (err)
- return err;
- err = vfs_test_lock(file, lock);
- nfsd_close(file);
+ __be32 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file);
+ if (!err) {
+ err = nfserrno(vfs_test_lock(file, lock));
+ nfsd_close(file);
+ }
return err;
}
@@ -4234,7 +4232,6 @@
struct inode *inode;
struct file_lock file_lock;
struct nfs4_lockowner *lo;
- int error;
__be32 status;
if (locks_in_grace())
@@ -4280,12 +4277,10 @@
nfs4_transform_lock_offset(&file_lock);
- status = nfs_ok;
- error = nfsd_test_lock(rqstp, &cstate->current_fh, &file_lock);
- if (error) {
- status = nfserrno(error);
+ status = nfsd_test_lock(rqstp, &cstate->current_fh, &file_lock);
+ if (status)
goto out;
- }
+
if (file_lock.fl_type != F_UNLCK) {
status = nfserr_denied;
nfs4_set_lock_denied(&file_lock, &lockt->lt_denied);
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index bcd8904..74c00bc 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1392,7 +1392,7 @@
for (i = 0; i < test_stateid->ts_num_ids; i++) {
stateid = kmalloc(sizeof(struct nfsd4_test_stateid_id), GFP_KERNEL);
if (!stateid) {
- status = PTR_ERR(stateid);
+ status = nfserrno(-ENOMEM);
goto out;
}
@@ -3410,7 +3410,7 @@
*p++ = htonl(test_stateid->ts_num_ids);
list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) {
- *p++ = htonl(stateid->ts_id_status);
+ *p++ = stateid->ts_id_status;
}
ADJUST_ARGS();
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 296d671..5686661 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1458,7 +1458,7 @@
switch (createmode) {
case NFS3_CREATE_UNCHECKED:
if (! S_ISREG(dchild->d_inode->i_mode))
- err = nfserr_exist;
+ goto out;
else if (truncp) {
/* in nfsv4, we need to treat this case a little
* differently. we don't want to truncate the
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 3165aeb..31b9463 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -1134,7 +1134,7 @@
}
el = path_leaf_el(path);
- rec = &el->l_recs[le32_to_cpu(el->l_next_free_rec) - 1];
+ rec = &el->l_recs[le16_to_cpu(el->l_next_free_rec) - 1];
ocfs2_adjust_rightmost_records(handle, et, path, rec);
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
index cf78233..9f32d7c 100644
--- a/fs/ocfs2/refcounttree.c
+++ b/fs/ocfs2/refcounttree.c
@@ -1036,14 +1036,14 @@
tmp_el = left_path->p_node[subtree_root].el;
blkno = left_path->p_node[subtree_root+1].bh->b_blocknr;
- for (i = 0; i < le32_to_cpu(tmp_el->l_next_free_rec); i++) {
+ for (i = 0; i < le16_to_cpu(tmp_el->l_next_free_rec); i++) {
if (le64_to_cpu(tmp_el->l_recs[i].e_blkno) == blkno) {
*cpos_end = le32_to_cpu(tmp_el->l_recs[i+1].e_cpos);
break;
}
}
- BUG_ON(i == le32_to_cpu(tmp_el->l_next_free_rec));
+ BUG_ON(i == le16_to_cpu(tmp_el->l_next_free_rec));
out:
ocfs2_free_path(left_path);
@@ -1468,7 +1468,7 @@
trace_ocfs2_divide_leaf_refcount_block(
(unsigned long long)ref_leaf_bh->b_blocknr,
- le32_to_cpu(rl->rl_count), le32_to_cpu(rl->rl_used));
+ le16_to_cpu(rl->rl_count), le16_to_cpu(rl->rl_used));
/*
* XXX: Improvement later.
@@ -2411,7 +2411,7 @@
rb = (struct ocfs2_refcount_block *)
prev_bh->b_data;
- if (le64_to_cpu(rb->rf_records.rl_used) +
+ if (le16_to_cpu(rb->rf_records.rl_used) +
recs_add >
le16_to_cpu(rb->rf_records.rl_count))
ref_blocks++;
@@ -2476,7 +2476,7 @@
if (prev_bh) {
rb = (struct ocfs2_refcount_block *)prev_bh->b_data;
- if (le64_to_cpu(rb->rf_records.rl_used) + recs_add >
+ if (le16_to_cpu(rb->rf_records.rl_used) + recs_add >
le16_to_cpu(rb->rf_records.rl_count))
ref_blocks++;
@@ -3629,7 +3629,7 @@
* one will split a refcount rec, so totally we need
* clusters * 2 new refcount rec.
*/
- if (le64_to_cpu(rb->rf_records.rl_used) + clusters * 2 >
+ if (le16_to_cpu(rb->rf_records.rl_used) + clusters * 2 >
le16_to_cpu(rb->rf_records.rl_count))
ref_blocks++;
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
index ba5d97e..f169da4 100644
--- a/fs/ocfs2/suballoc.c
+++ b/fs/ocfs2/suballoc.c
@@ -600,7 +600,7 @@
ret = ocfs2_free_clusters(handle, cluster_ac->ac_inode,
cluster_ac->ac_bh,
le64_to_cpu(rec->e_blkno),
- le32_to_cpu(rec->e_leaf_clusters));
+ le16_to_cpu(rec->e_leaf_clusters));
if (ret)
mlog_errno(ret);
/* Try all the clusters to free */
@@ -1628,7 +1628,7 @@
{
unsigned int bpc = le16_to_cpu(cl->cl_bpc);
unsigned int bitoff = le32_to_cpu(rec->e_cpos) * bpc;
- unsigned int bitcount = le32_to_cpu(rec->e_leaf_clusters) * bpc;
+ unsigned int bitcount = le16_to_cpu(rec->e_leaf_clusters) * bpc;
if (res->sr_bit_offset < bitoff)
return 0;
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index 8ba2c94..8f2ab8f 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -593,7 +593,7 @@
__u64 off;
__u32 namelen;
__u32 type;
- char name[0];
+ char name[];
};
#define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name)
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index 2463b61..1f90de0 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -666,23 +666,11 @@
unsigned int check_defaults:1;
unsigned int reset_registers:1;
unsigned int hs_extmute:1;
- u16 hs_left_step;
- u16 hs_right_step;
- u16 hf_left_step;
- u16 hf_right_step;
void (*set_hs_extmute)(int mute);
};
struct twl4030_vibra_data {
unsigned int coexist;
-
- /* twl6040 */
- unsigned int vibldrv_res; /* left driver resistance */
- unsigned int vibrdrv_res; /* right driver resistance */
- unsigned int viblmotor_res; /* left motor resistance */
- unsigned int vibrmotor_res; /* right motor resistance */
- int vddvibl_uV; /* VDDVIBL volt, set 0 for fixed reg */
- int vddvibr_uV; /* VDDVIBR volt, set 0 for fixed reg */
};
struct twl4030_audio_data {
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 665a260..72cbf08 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -596,6 +596,7 @@
#ifdef CONFIG_IOMMU_API
int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot);
+void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot);
int kvm_iommu_map_guest(struct kvm *kvm);
int kvm_iommu_unmap_guest(struct kvm *kvm);
int kvm_assign_device(struct kvm *kvm,
@@ -609,6 +610,11 @@
return 0;
}
+static inline void kvm_iommu_unmap_pages(struct kvm *kvm,
+ struct kvm_memory_slot *slot)
+{
+}
+
static inline int kvm_iommu_map_guest(struct kvm *kvm)
{
return -ENODEV;
diff --git a/include/linux/mfd/db5500-prcmu.h b/include/linux/mfd/db5500-prcmu.h
index 9890687..5a049df 100644
--- a/include/linux/mfd/db5500-prcmu.h
+++ b/include/linux/mfd/db5500-prcmu.h
@@ -8,70 +8,6 @@
#ifndef __MFD_DB5500_PRCMU_H
#define __MFD_DB5500_PRCMU_H
-#ifdef CONFIG_MFD_DB5500_PRCMU
-
-void db5500_prcmu_early_init(void);
-int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state);
-int db5500_prcmu_set_display_clocks(void);
-int db5500_prcmu_disable_dsipll(void);
-int db5500_prcmu_enable_dsipll(void);
-int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
-int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size);
-void db5500_prcmu_enable_wakeups(u32 wakeups);
-int db5500_prcmu_request_clock(u8 clock, bool enable);
-void db5500_prcmu_config_abb_event_readout(u32 abb_events);
-void db5500_prcmu_get_abb_event_buffer(void __iomem **buf);
-int prcmu_resetout(u8 resoutn, u8 state);
-int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk,
- bool keep_ap_pll);
-int db5500_prcmu_config_esram0_deep_sleep(u8 state);
-void db5500_prcmu_system_reset(u16 reset_code);
-u16 db5500_prcmu_get_reset_code(void);
-bool db5500_prcmu_is_ac_wake_requested(void);
-int db5500_prcmu_set_arm_opp(u8 opp);
-int db5500_prcmu_get_arm_opp(void);
-
-#else /* !CONFIG_UX500_SOC_DB5500 */
-
-static inline void db5500_prcmu_early_init(void) {}
-
-static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
-{
- return -ENOSYS;
-}
-
-static inline int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
-{
- return -ENOSYS;
-}
-
-static inline int db5500_prcmu_request_clock(u8 clock, bool enable)
-{
- return 0;
-}
-
-static inline int db5500_prcmu_set_display_clocks(void)
-{
- return 0;
-}
-
-static inline int db5500_prcmu_disable_dsipll(void)
-{
- return 0;
-}
-
-static inline int db5500_prcmu_enable_dsipll(void)
-{
- return 0;
-}
-
-static inline int db5500_prcmu_config_esram0_deep_sleep(u8 state)
-{
- return 0;
-}
-
-static inline void db5500_prcmu_enable_wakeups(u32 wakeups) {}
-
static inline int prcmu_resetout(u8 resoutn, u8 state)
{
return 0;
@@ -82,8 +18,10 @@
return 0;
}
-static inline void db5500_prcmu_get_abb_event_buffer(void __iomem **buf) {}
-static inline void db5500_prcmu_config_abb_event_readout(u32 abb_events) {}
+static inline int db5500_prcmu_request_clock(u8 clock, bool enable)
+{
+ return 0;
+}
static inline int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk,
bool keep_ap_pll)
@@ -91,7 +29,10 @@
return 0;
}
-static inline void db5500_prcmu_system_reset(u16 reset_code) {}
+static inline int db5500_prcmu_config_esram0_deep_sleep(u8 state)
+{
+ return 0;
+}
static inline u16 db5500_prcmu_get_reset_code(void)
{
@@ -113,6 +54,51 @@
return 0;
}
+static inline void db5500_prcmu_config_abb_event_readout(u32 abb_events) {}
+
+static inline void db5500_prcmu_get_abb_event_buffer(void __iomem **buf) {}
+
+static inline void db5500_prcmu_system_reset(u16 reset_code) {}
+
+static inline void db5500_prcmu_enable_wakeups(u32 wakeups) {}
+
+#ifdef CONFIG_MFD_DB5500_PRCMU
+
+void db5500_prcmu_early_init(void);
+int db5500_prcmu_set_display_clocks(void);
+int db5500_prcmu_disable_dsipll(void);
+int db5500_prcmu_enable_dsipll(void);
+int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
+int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size);
+
+#else /* !CONFIG_UX500_SOC_DB5500 */
+
+static inline void db5500_prcmu_early_init(void) {}
+
+static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
+{
+ return -ENOSYS;
+}
+
+static inline int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
+{
+ return -ENOSYS;
+}
+
+static inline int db5500_prcmu_set_display_clocks(void)
+{
+ return 0;
+}
+
+static inline int db5500_prcmu_disable_dsipll(void)
+{
+ return 0;
+}
+
+static inline int db5500_prcmu_enable_dsipll(void)
+{
+ return 0;
+}
#endif /* CONFIG_MFD_DB5500_PRCMU */
diff --git a/include/linux/mfd/rc5t583.h b/include/linux/mfd/rc5t583.h
index a2c6160..0b64b19 100644
--- a/include/linux/mfd/rc5t583.h
+++ b/include/linux/mfd/rc5t583.h
@@ -26,6 +26,7 @@
#include <linux/mutex.h>
#include <linux/types.h>
+#include <linux/regmap.h>
#define RC5T583_MAX_REGS 0xF8
@@ -279,14 +280,44 @@
bool enable_shutdown;
};
-int rc5t583_write(struct device *dev, u8 reg, uint8_t val);
-int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val);
-int rc5t583_set_bits(struct device *dev, unsigned int reg,
- unsigned int bit_mask);
-int rc5t583_clear_bits(struct device *dev, unsigned int reg,
- unsigned int bit_mask);
-int rc5t583_update(struct device *dev, unsigned int reg,
- unsigned int val, unsigned int mask);
+static inline int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val)
+{
+ struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
+ return regmap_write(rc5t583->regmap, reg, val);
+}
+
+static inline int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val)
+{
+ struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
+ unsigned int ival;
+ int ret;
+ ret = regmap_read(rc5t583->regmap, reg, &ival);
+ if (!ret)
+ *val = (uint8_t)ival;
+ return ret;
+}
+
+static inline int rc5t583_set_bits(struct device *dev, unsigned int reg,
+ unsigned int bit_mask)
+{
+ struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
+ return regmap_update_bits(rc5t583->regmap, reg, bit_mask, bit_mask);
+}
+
+static inline int rc5t583_clear_bits(struct device *dev, unsigned int reg,
+ unsigned int bit_mask)
+{
+ struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
+ return regmap_update_bits(rc5t583->regmap, reg, bit_mask, 0);
+}
+
+static inline int rc5t583_update(struct device *dev, unsigned int reg,
+ unsigned int val, unsigned int mask)
+{
+ struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
+ return regmap_update_bits(rc5t583->regmap, reg, mask, val);
+}
+
int rc5t583_ext_power_req_config(struct device *dev, int deepsleep_id,
int ext_pwr_req, int deepsleep_slot_nr);
int rc5t583_irq_init(struct rc5t583 *rc5t583, int irq, int irq_base);
diff --git a/include/linux/mfd/twl6040.h b/include/linux/mfd/twl6040.h
index 9bc9ac6..b15b5f0 100644
--- a/include/linux/mfd/twl6040.h
+++ b/include/linux/mfd/twl6040.h
@@ -174,8 +174,35 @@
#define TWL6040_SYSCLK_SEL_LPPLL 0
#define TWL6040_SYSCLK_SEL_HPPLL 1
+struct twl6040_codec_data {
+ u16 hs_left_step;
+ u16 hs_right_step;
+ u16 hf_left_step;
+ u16 hf_right_step;
+};
+
+struct twl6040_vibra_data {
+ unsigned int vibldrv_res; /* left driver resistance */
+ unsigned int vibrdrv_res; /* right driver resistance */
+ unsigned int viblmotor_res; /* left motor resistance */
+ unsigned int vibrmotor_res; /* right motor resistance */
+ int vddvibl_uV; /* VDDVIBL volt, set 0 for fixed reg */
+ int vddvibr_uV; /* VDDVIBR volt, set 0 for fixed reg */
+};
+
+struct twl6040_platform_data {
+ int audpwron_gpio; /* audio power-on gpio */
+ unsigned int irq_base;
+
+ struct twl6040_codec_data *codec;
+ struct twl6040_vibra_data *vibra;
+};
+
+struct regmap;
+
struct twl6040 {
struct device *dev;
+ struct regmap *regmap;
struct mutex mutex;
struct mutex io_mutex;
struct mutex irq_mutex;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index d8738a4..74aa71b 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1393,29 +1393,20 @@
extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
-extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
- unsigned long len, unsigned long prot,
- unsigned long flag, unsigned long pgoff);
extern unsigned long mmap_region(struct file *file, unsigned long addr,
unsigned long len, unsigned long flags,
vm_flags_t vm_flags, unsigned long pgoff);
-
-static inline unsigned long do_mmap(struct file *file, unsigned long addr,
- unsigned long len, unsigned long prot,
- unsigned long flag, unsigned long offset)
-{
- unsigned long ret = -EINVAL;
- if ((offset + PAGE_ALIGN(len)) < offset)
- goto out;
- if (!(offset & ~PAGE_MASK))
- ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
-out:
- return ret;
-}
-
+extern unsigned long do_mmap(struct file *, unsigned long,
+ unsigned long, unsigned long,
+ unsigned long, unsigned long);
extern int do_munmap(struct mm_struct *, unsigned long, size_t);
-extern unsigned long do_brk(unsigned long, unsigned long);
+/* These take the mm semaphore themselves */
+extern unsigned long vm_brk(unsigned long, unsigned long);
+extern int vm_munmap(unsigned long, size_t);
+extern unsigned long vm_mmap(struct file *, unsigned long,
+ unsigned long, unsigned long,
+ unsigned long, unsigned long);
/* truncate.c */
extern void truncate_inode_pages(struct address_space *, loff_t);
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 01beae7..629b823 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -481,7 +481,7 @@
struct device_driver drv;
int (*probe)(struct mmc_card *);
void (*remove)(struct mmc_card *);
- int (*suspend)(struct mmc_card *, pm_message_t);
+ int (*suspend)(struct mmc_card *);
int (*resume)(struct mmc_card *);
};
diff --git a/include/linux/nfsd/Kbuild b/include/linux/nfsd/Kbuild
index b8d4001..5b7d84a 100644
--- a/include/linux/nfsd/Kbuild
+++ b/include/linux/nfsd/Kbuild
@@ -1,3 +1,4 @@
+header-y += cld.h
header-y += debug.h
header-y += export.h
header-y += nfsfh.h
diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h
index fee4349..e4d1de7 100644
--- a/include/linux/pinctrl/machine.h
+++ b/include/linux/pinctrl/machine.h
@@ -12,6 +12,8 @@
#ifndef __LINUX_PINCTRL_MACHINE_H
#define __LINUX_PINCTRL_MACHINE_H
+#include <linux/bug.h>
+
#include "pinctrl-state.h"
enum pinctrl_map_type {
@@ -148,7 +150,7 @@
#define PIN_MAP_CONFIGS_GROUP_HOG_DEFAULT(dev, grp, cfgs) \
PIN_MAP_CONFIGS_GROUP(dev, PINCTRL_STATE_DEFAULT, dev, grp, cfgs)
-#ifdef CONFIG_PINMUX
+#ifdef CONFIG_PINCTRL
extern int pinctrl_register_mappings(struct pinctrl_map const *map,
unsigned num_maps);
diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h
index f67810f..38ab3f4 100644
--- a/include/linux/usb/otg.h
+++ b/include/linux/usb/otg.h
@@ -94,6 +94,7 @@
struct usb_otg *otg;
+ struct device *io_dev;
struct usb_phy_io_ops *io_ops;
void __iomem *io_priv;
diff --git a/lib/mpi/mpi-bit.c b/lib/mpi/mpi-bit.c
index 2f52662..0c50536 100644
--- a/lib/mpi/mpi-bit.c
+++ b/lib/mpi/mpi-bit.c
@@ -177,8 +177,8 @@
*/
int mpi_lshift_limbs(MPI a, unsigned int count)
{
- mpi_ptr_t ap = a->d;
- int n = a->nlimbs;
+ const int n = a->nlimbs;
+ mpi_ptr_t ap;
int i;
if (!count || !n)
@@ -187,6 +187,7 @@
if (RESIZE_IF_NEEDED(a, n + count) < 0)
return -ENOMEM;
+ ap = a->d;
for (i = n - 1; i >= 0; i--)
ap[i + count] = ap[i];
for (i = 0; i < count; i++)
diff --git a/mm/memblock.c b/mm/memblock.c
index 99f2855..a44eab3 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -330,6 +330,9 @@
phys_addr_t end = base + memblock_cap_size(base, &size);
int i, nr_new;
+ if (!size)
+ return 0;
+
/* special case for empty array */
if (type->regions[0].size == 0) {
WARN_ON(type->cnt != 1 || type->total_size);
@@ -430,6 +433,9 @@
*start_rgn = *end_rgn = 0;
+ if (!size)
+ return 0;
+
/* we'll create at most two more regions */
while (type->cnt + 2 > type->max)
if (memblock_double_array(type) < 0)
@@ -514,7 +520,6 @@
(unsigned long long)base,
(unsigned long long)base + size,
(void *)_RET_IP_);
- BUG_ON(0 == size);
return memblock_add_region(_rgn, base, size, MAX_NUMNODES);
}
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index a7165a6..b868def 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -3392,6 +3392,7 @@
* the newpage may be on LRU(or pagevec for LRU) already. We lock
* LRU while we overwrite pc->mem_cgroup.
*/
+ pc = lookup_page_cgroup(newpage);
__mem_cgroup_commit_charge(memcg, newpage, 1, pc, type, true);
}
diff --git a/mm/mmap.c b/mm/mmap.c
index a7bf6a3..848ef52 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -240,6 +240,8 @@
return next;
}
+static unsigned long do_brk(unsigned long addr, unsigned long len);
+
SYSCALL_DEFINE1(brk, unsigned long, brk)
{
unsigned long rlim, retval;
@@ -951,7 +953,7 @@
* The caller must hold down_write(¤t->mm->mmap_sem).
*/
-unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
+static unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
unsigned long len, unsigned long prot,
unsigned long flags, unsigned long pgoff)
{
@@ -1087,7 +1089,32 @@
return mmap_region(file, addr, len, flags, vm_flags, pgoff);
}
-EXPORT_SYMBOL(do_mmap_pgoff);
+
+unsigned long do_mmap(struct file *file, unsigned long addr,
+ unsigned long len, unsigned long prot,
+ unsigned long flag, unsigned long offset)
+{
+ if (unlikely(offset + PAGE_ALIGN(len) < offset))
+ return -EINVAL;
+ if (unlikely(offset & ~PAGE_MASK))
+ return -EINVAL;
+ return do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
+}
+EXPORT_SYMBOL(do_mmap);
+
+unsigned long vm_mmap(struct file *file, unsigned long addr,
+ unsigned long len, unsigned long prot,
+ unsigned long flag, unsigned long offset)
+{
+ unsigned long ret;
+ struct mm_struct *mm = current->mm;
+
+ down_write(&mm->mmap_sem);
+ ret = do_mmap(file, addr, len, prot, flag, offset);
+ up_write(&mm->mmap_sem);
+ return ret;
+}
+EXPORT_SYMBOL(vm_mmap);
SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags,
@@ -2105,21 +2132,25 @@
return 0;
}
-
EXPORT_SYMBOL(do_munmap);
-SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
+int vm_munmap(unsigned long start, size_t len)
{
int ret;
struct mm_struct *mm = current->mm;
- profile_munmap(addr);
-
down_write(&mm->mmap_sem);
- ret = do_munmap(mm, addr, len);
+ ret = do_munmap(mm, start, len);
up_write(&mm->mmap_sem);
return ret;
}
+EXPORT_SYMBOL(vm_munmap);
+
+SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
+{
+ profile_munmap(addr);
+ return vm_munmap(addr, len);
+}
static inline void verify_mm_writelocked(struct mm_struct *mm)
{
@@ -2136,7 +2167,7 @@
* anonymous maps. eventually we may be able to do some
* brk-specific accounting here.
*/
-unsigned long do_brk(unsigned long addr, unsigned long len)
+static unsigned long do_brk(unsigned long addr, unsigned long len)
{
struct mm_struct * mm = current->mm;
struct vm_area_struct * vma, * prev;
@@ -2232,7 +2263,17 @@
return addr;
}
-EXPORT_SYMBOL(do_brk);
+unsigned long vm_brk(unsigned long addr, unsigned long len)
+{
+ struct mm_struct *mm = current->mm;
+ unsigned long ret;
+
+ down_write(&mm->mmap_sem);
+ ret = do_brk(addr, len);
+ up_write(&mm->mmap_sem);
+ return ret;
+}
+EXPORT_SYMBOL(vm_brk);
/* Release all mmaps. */
void exit_mmap(struct mm_struct *mm)
diff --git a/mm/nommu.c b/mm/nommu.c
index f59e170..bb8f4f0 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1233,7 +1233,7 @@
/*
* handle mapping creation for uClinux
*/
-unsigned long do_mmap_pgoff(struct file *file,
+static unsigned long do_mmap_pgoff(struct file *file,
unsigned long addr,
unsigned long len,
unsigned long prot,
@@ -1470,7 +1470,32 @@
show_free_areas(0);
return -ENOMEM;
}
-EXPORT_SYMBOL(do_mmap_pgoff);
+
+unsigned long do_mmap(struct file *file, unsigned long addr,
+ unsigned long len, unsigned long prot,
+ unsigned long flag, unsigned long offset)
+{
+ if (unlikely(offset + PAGE_ALIGN(len) < offset))
+ return -EINVAL;
+ if (unlikely(offset & ~PAGE_MASK))
+ return -EINVAL;
+ return do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
+}
+EXPORT_SYMBOL(do_mmap);
+
+unsigned long vm_mmap(struct file *file, unsigned long addr,
+ unsigned long len, unsigned long prot,
+ unsigned long flag, unsigned long offset)
+{
+ unsigned long ret;
+ struct mm_struct *mm = current->mm;
+
+ down_write(&mm->mmap_sem);
+ ret = do_mmap(file, addr, len, prot, flag, offset);
+ up_write(&mm->mmap_sem);
+ return ret;
+}
+EXPORT_SYMBOL(vm_mmap);
SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags,
@@ -1709,16 +1734,22 @@
}
EXPORT_SYMBOL(do_munmap);
-SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
+int vm_munmap(unsigned long addr, size_t len)
{
- int ret;
struct mm_struct *mm = current->mm;
+ int ret;
down_write(&mm->mmap_sem);
ret = do_munmap(mm, addr, len);
up_write(&mm->mmap_sem);
return ret;
}
+EXPORT_SYMBOL(vm_munmap);
+
+SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
+{
+ return vm_munmap(addr, len);
+}
/*
* release all the mappings made in a process's VM space
@@ -1744,7 +1775,7 @@
kleave("");
}
-unsigned long do_brk(unsigned long addr, unsigned long len)
+unsigned long vm_brk(unsigned long addr, unsigned long len)
{
return -ENOMEM;
}
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index de639eee..faea0ec 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1869,12 +1869,6 @@
"No space is necessary after a cast\n" . $hereprev);
}
- if ($rawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
- $prevrawline =~ /^\+[ \t]*$/) {
- CHK("BLOCK_COMMENT_STYLE",
- "Don't begin block comments with only a /* line, use /* comment...\n" . $hereprev);
- }
-
# check for spaces at the beginning of a line.
# Exceptions:
# 1) within comments
diff --git a/scripts/xz_wrap.sh b/scripts/xz_wrap.sh
index 17a5798..7a2d372 100644
--- a/scripts/xz_wrap.sh
+++ b/scripts/xz_wrap.sh
@@ -12,8 +12,8 @@
BCJ=
LZMA2OPTS=
-case $ARCH in
- x86|x86_64) BCJ=--x86 ;;
+case $SRCARCH in
+ x86) BCJ=--x86 ;;
powerpc) BCJ=--powerpc ;;
ia64) BCJ=--ia64; LZMA2OPTS=pb=4 ;;
arm) BCJ=--arm ;;
diff --git a/security/commoncap.c b/security/commoncap.c
index 0cf4b53..71a166a 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -29,6 +29,7 @@
#include <linux/securebits.h>
#include <linux/user_namespace.h>
#include <linux/binfmts.h>
+#include <linux/personality.h>
/*
* If a non-root user executes a setuid-root binary in
@@ -505,6 +506,11 @@
}
skip:
+ /* if we have fs caps, clear dangerous personality flags */
+ if (!cap_issubset(new->cap_permitted, old->cap_permitted))
+ bprm->per_clear |= PER_CLEAR_ON_SETID;
+
+
/* Don't let someone trace a set[ug]id/setpcap binary with the revised
* credentials unless they have the appropriate permit
*/
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 10056f2..45c32f0 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -3640,8 +3640,38 @@
};
-static __init void init_smack_know_list(void)
+static __init void init_smack_known_list(void)
{
+ /*
+ * Initialize CIPSO locks
+ */
+ spin_lock_init(&smack_known_huh.smk_cipsolock);
+ spin_lock_init(&smack_known_hat.smk_cipsolock);
+ spin_lock_init(&smack_known_star.smk_cipsolock);
+ spin_lock_init(&smack_known_floor.smk_cipsolock);
+ spin_lock_init(&smack_known_invalid.smk_cipsolock);
+ spin_lock_init(&smack_known_web.smk_cipsolock);
+ /*
+ * Initialize rule list locks
+ */
+ mutex_init(&smack_known_huh.smk_rules_lock);
+ mutex_init(&smack_known_hat.smk_rules_lock);
+ mutex_init(&smack_known_floor.smk_rules_lock);
+ mutex_init(&smack_known_star.smk_rules_lock);
+ mutex_init(&smack_known_invalid.smk_rules_lock);
+ mutex_init(&smack_known_web.smk_rules_lock);
+ /*
+ * Initialize rule lists
+ */
+ INIT_LIST_HEAD(&smack_known_huh.smk_rules);
+ INIT_LIST_HEAD(&smack_known_hat.smk_rules);
+ INIT_LIST_HEAD(&smack_known_star.smk_rules);
+ INIT_LIST_HEAD(&smack_known_floor.smk_rules);
+ INIT_LIST_HEAD(&smack_known_invalid.smk_rules);
+ INIT_LIST_HEAD(&smack_known_web.smk_rules);
+ /*
+ * Create the known labels list
+ */
list_add(&smack_known_huh.list, &smack_known_list);
list_add(&smack_known_hat.list, &smack_known_list);
list_add(&smack_known_star.list, &smack_known_list);
@@ -3676,16 +3706,8 @@
cred = (struct cred *) current->cred;
cred->security = tsp;
- /* initialize the smack_know_list */
- init_smack_know_list();
- /*
- * Initialize locks
- */
- spin_lock_init(&smack_known_huh.smk_cipsolock);
- spin_lock_init(&smack_known_hat.smk_cipsolock);
- spin_lock_init(&smack_known_star.smk_cipsolock);
- spin_lock_init(&smack_known_floor.smk_cipsolock);
- spin_lock_init(&smack_known_invalid.smk_cipsolock);
+ /* initialize the smack_known_list */
+ init_smack_known_list();
/*
* Register with LSM
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 5c32f36..038811c 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -1614,20 +1614,6 @@
smk_cipso_doi();
smk_unlbl_ambient(NULL);
- mutex_init(&smack_known_floor.smk_rules_lock);
- mutex_init(&smack_known_hat.smk_rules_lock);
- mutex_init(&smack_known_huh.smk_rules_lock);
- mutex_init(&smack_known_invalid.smk_rules_lock);
- mutex_init(&smack_known_star.smk_rules_lock);
- mutex_init(&smack_known_web.smk_rules_lock);
-
- INIT_LIST_HEAD(&smack_known_floor.smk_rules);
- INIT_LIST_HEAD(&smack_known_hat.smk_rules);
- INIT_LIST_HEAD(&smack_known_huh.smk_rules);
- INIT_LIST_HEAD(&smack_known_invalid.smk_rules);
- INIT_LIST_HEAD(&smack_known_star.smk_rules);
- INIT_LIST_HEAD(&smack_known_web.smk_rules);
-
return err;
}
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c
index 14a286a..8575861 100644
--- a/sound/core/vmaster.c
+++ b/sound/core/vmaster.c
@@ -419,6 +419,7 @@
* snd_ctl_add_vmaster_hook - Add a hook to a vmaster control
* @kcontrol: vmaster kctl element
* @hook: the hook function
+ * @private_data: the private_data pointer to be saved
*
* Adds the given hook to the vmaster control element so that it's called
* at each time when the value is changed.
diff --git a/sound/last.c b/sound/last.c
index bdd0857..7ffc182 100644
--- a/sound/last.c
+++ b/sound/last.c
@@ -38,4 +38,4 @@
return 0;
}
-__initcall(alsa_sound_last_init);
+late_initcall_sync(alsa_sound_last_init);
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index a36488d..d906c5b 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -3971,9 +3971,14 @@
int i;
mute_outputs(codec, spec->multiout.num_dacs, spec->multiout.dac_nids);
- for (i = 0; i < cfg->hp_outs; i++)
+ for (i = 0; i < cfg->hp_outs; i++) {
+ unsigned int val = PIN_OUT;
+ if (snd_hda_query_pin_caps(codec, cfg->hp_pins[i]) &
+ AC_PINCAP_HP_DRV)
+ val |= AC_PINCTL_HP_EN;
snd_hda_codec_write(codec, cfg->hp_pins[i], 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
+ AC_VERB_SET_PIN_WIDGET_CONTROL, val);
+ }
mute_outputs(codec, cfg->hp_outs, cfg->hp_pins);
mute_outputs(codec, cfg->line_outs, cfg->line_out_pins);
mute_outputs(codec, cfg->speaker_outs, cfg->speaker_pins);
@@ -4391,8 +4396,10 @@
enum {
CXT_PINCFG_LENOVO_X200,
+ CXT_PINCFG_LENOVO_TP410,
};
+/* ThinkPad X200 & co with cxt5051 */
static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = {
{ 0x16, 0x042140ff }, /* HP (seq# overridden) */
{ 0x17, 0x21a11000 }, /* dock-mic */
@@ -4401,15 +4408,33 @@
{}
};
-static const struct cxt_pincfg *cxt_pincfg_tbl[] = {
- [CXT_PINCFG_LENOVO_X200] = cxt_pincfg_lenovo_x200,
+/* ThinkPad 410/420/510/520, X201 & co with cxt5066 */
+static const struct cxt_pincfg cxt_pincfg_lenovo_tp410[] = {
+ { 0x19, 0x042110ff }, /* HP (seq# overridden) */
+ { 0x1a, 0x21a190f0 }, /* dock-mic */
+ { 0x1c, 0x212140ff }, /* dock-HP */
+ {}
};
-static const struct snd_pci_quirk cxt_fixups[] = {
+static const struct cxt_pincfg *cxt_pincfg_tbl[] = {
+ [CXT_PINCFG_LENOVO_X200] = cxt_pincfg_lenovo_x200,
+ [CXT_PINCFG_LENOVO_TP410] = cxt_pincfg_lenovo_tp410,
+};
+
+static const struct snd_pci_quirk cxt5051_fixups[] = {
SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200),
{}
};
+static const struct snd_pci_quirk cxt5066_fixups[] = {
+ SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
+ SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410),
+ SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410),
+ SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410),
+ SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410),
+ {}
+};
+
/* add "fake" mute amp-caps to DACs on cx5051 so that mixer mute switches
* can be created (bko#42825)
*/
@@ -4446,13 +4471,13 @@
case 0x14f15051:
add_cx5051_fake_mutes(codec);
codec->pin_amp_workaround = 1;
+ apply_pin_fixup(codec, cxt5051_fixups, cxt_pincfg_tbl);
break;
default:
codec->pin_amp_workaround = 1;
+ apply_pin_fixup(codec, cxt5066_fixups, cxt_pincfg_tbl);
}
- apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
-
/* Show mute-led control only on HP laptops
* This is a sort of white-list: on HP laptops, EAPD corresponds
* only to the mute-LED without actualy amp function. Meanwhile,
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 2508f81..e65e354 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1445,6 +1445,13 @@
ALC_FIXUP_ACT_BUILD,
};
+static void alc_apply_pincfgs(struct hda_codec *codec,
+ const struct alc_pincfg *cfg)
+{
+ for (; cfg->nid; cfg++)
+ snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
+}
+
static void alc_apply_fixup(struct hda_codec *codec, int action)
{
struct alc_spec *spec = codec->spec;
@@ -1478,9 +1485,7 @@
snd_printdd(KERN_INFO "hda_codec: %s: "
"Apply pincfg for %s\n",
codec->chip_name, modelname);
- for (; cfg->nid; cfg++)
- snd_hda_codec_set_pincfg(codec, cfg->nid,
- cfg->val);
+ alc_apply_pincfgs(codec, cfg);
break;
case ALC_FIXUP_VERBS:
if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
@@ -4861,6 +4866,7 @@
ALC260_FIXUP_GPIO1_TOGGLE,
ALC260_FIXUP_REPLACER,
ALC260_FIXUP_HP_B1900,
+ ALC260_FIXUP_KN1,
};
static void alc260_gpio1_automute(struct hda_codec *codec)
@@ -4888,6 +4894,36 @@
}
}
+static void alc260_fixup_kn1(struct hda_codec *codec,
+ const struct alc_fixup *fix, int action)
+{
+ struct alc_spec *spec = codec->spec;
+ static const struct alc_pincfg pincfgs[] = {
+ { 0x0f, 0x02214000 }, /* HP/speaker */
+ { 0x12, 0x90a60160 }, /* int mic */
+ { 0x13, 0x02a19000 }, /* ext mic */
+ { 0x18, 0x01446000 }, /* SPDIF out */
+ /* disable bogus I/O pins */
+ { 0x10, 0x411111f0 },
+ { 0x11, 0x411111f0 },
+ { 0x14, 0x411111f0 },
+ { 0x15, 0x411111f0 },
+ { 0x16, 0x411111f0 },
+ { 0x17, 0x411111f0 },
+ { 0x19, 0x411111f0 },
+ { }
+ };
+
+ switch (action) {
+ case ALC_FIXUP_ACT_PRE_PROBE:
+ alc_apply_pincfgs(codec, pincfgs);
+ break;
+ case ALC_FIXUP_ACT_PROBE:
+ spec->init_amp = ALC_INIT_NONE;
+ break;
+ }
+}
+
static const struct alc_fixup alc260_fixups[] = {
[ALC260_FIXUP_HP_DC5750] = {
.type = ALC_FIXUP_PINS,
@@ -4938,7 +4974,11 @@
.v.func = alc260_fixup_gpio1_toggle,
.chained = true,
.chain_id = ALC260_FIXUP_COEF,
- }
+ },
+ [ALC260_FIXUP_KN1] = {
+ .type = ALC_FIXUP_FUNC,
+ .v.func = alc260_fixup_kn1,
+ },
};
static const struct snd_pci_quirk alc260_fixup_tbl[] = {
@@ -4948,6 +4988,7 @@
SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
+ SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
{}
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 33a9946..4742cac 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -5063,12 +5063,11 @@
if (spec->gpio_led_polarity)
muted = !muted;
- /*polarity defines *not* muted state level*/
if (!spec->vref_mute_led_nid) {
if (muted)
- spec->gpio_data &= ~spec->gpio_led; /* orange */
+ spec->gpio_data |= spec->gpio_led;
else
- spec->gpio_data |= spec->gpio_led; /* white */
+ spec->gpio_data &= ~spec->gpio_led;
stac_gpio_set(codec, spec->gpio_mask,
spec->gpio_dir, spec->gpio_data);
} else {
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 6508e8b..59d8efa 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -57,7 +57,7 @@
select SND_SOC_TPA6130A2 if I2C
select SND_SOC_TLV320DAC33 if I2C
select SND_SOC_TWL4030 if TWL4030_CORE
- select SND_SOC_TWL6040 if TWL4030_CORE
+ select SND_SOC_TWL6040 if TWL6040_CORE
select SND_SOC_UDA134X
select SND_SOC_UDA1380 if I2C
select SND_SOC_WL1273 if MFD_WL1273_CORE
@@ -276,7 +276,6 @@
tristate
config SND_SOC_TWL6040
- select TWL6040_CORE
tristate
config SND_SOC_UDA134X
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 2d8c6b8..dc7509b 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -26,7 +26,6 @@
#include <linux/pm.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
-#include <linux/i2c/twl.h>
#include <linux/mfd/twl6040.h>
#include <sound/core.h>
@@ -1528,7 +1527,7 @@
static int twl6040_probe(struct snd_soc_codec *codec)
{
struct twl6040_data *priv;
- struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev);
+ struct twl6040_codec_data *pdata = dev_get_platdata(codec->dev);
struct platform_device *pdev = container_of(codec->dev,
struct platform_device, dev);
int ret = 0;
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index e00dd0b..deafbfa 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -97,7 +97,7 @@
config SND_OMAP_SOC_OMAP_ABE_TWL6040
tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec"
- depends on TWL4030_CORE && SND_OMAP_SOC && ARCH_OMAP4
+ depends on TWL6040_CORE && SND_OMAP_SOC && ARCH_OMAP4
select SND_OMAP_SOC_DMIC
select SND_OMAP_SOC_MCPDM
select SND_SOC_TWL6040
diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore
index 416684b..26b823b 100644
--- a/tools/perf/.gitignore
+++ b/tools/perf/.gitignore
@@ -19,3 +19,5 @@
cscope*
config.mak
config.mak.autogen
+*-bison.*
+*-flex.*
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 820371f..03059e7 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -237,21 +237,20 @@
FLEX = $(CROSS_COMPILE)flex
BISON= $(CROSS_COMPILE)bison
-event-parser:
- $(QUIET_BISON)$(BISON) -v util/parse-events.y -d -o $(OUTPUT)util/parse-events-bison.c
+$(OUTPUT)util/parse-events-flex.c: util/parse-events.l
$(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c
-$(OUTPUT)util/parse-events-flex.c: event-parser
-$(OUTPUT)util/parse-events-bison.c: event-parser
+$(OUTPUT)util/parse-events-bison.c: util/parse-events.y
+ $(QUIET_BISON)$(BISON) -v util/parse-events.y -d -o $(OUTPUT)util/parse-events-bison.c
-pmu-parser:
- $(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c
+$(OUTPUT)util/pmu-flex.c: util/pmu.l
$(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c
-$(OUTPUT)util/pmu-flex.c: pmu-parser
-$(OUTPUT)util/pmu-bison.c: pmu-parser
+$(OUTPUT)util/pmu-bison.c: util/pmu.y
+ $(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c
-$(OUTPUT)util/parse-events.o: event-parser pmu-parser
+$(OUTPUT)util/parse-events.o: $(OUTPUT)util/parse-events-flex.c $(OUTPUT)util/parse-events-bison.c
+$(OUTPUT)util/pmu.o: $(OUTPUT)util/pmu-flex.c $(OUTPUT)util/pmu-bison.c
LIB_FILE=$(OUTPUT)libperf.a
@@ -527,7 +526,7 @@
endif
ifdef NO_GTK2
- BASIC_CFLAGS += -DNO_GTK2
+ BASIC_CFLAGS += -DNO_GTK2_SUPPORT
else
FLAGS_GTK2=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0)
ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2)),y)
@@ -852,8 +851,6 @@
@echo ' html - make html documentation'
@echo ' info - make GNU info documentation (access with info <foo>)'
@echo ' pdf - make pdf documentation'
- @echo ' event-parser - make event parser code'
- @echo ' pmu-parser - make pmu format parser code'
@echo ' TAGS - use etags to make tag information for source browsing'
@echo ' tags - use ctags to make tag information for source browsing'
@echo ' cscope - use cscope to make interactive browsing database'
diff --git a/tools/perf/perf-archive.sh b/tools/perf/perf-archive.sh
index 677e59d..95b6f8b 100644
--- a/tools/perf/perf-archive.sh
+++ b/tools/perf/perf-archive.sh
@@ -29,13 +29,14 @@
fi
MANIFEST=$(mktemp /tmp/perf-archive-manifest.XXXXXX)
+PERF_BUILDID_LINKDIR=$(readlink -f $PERF_BUILDID_DIR)/
cut -d ' ' -f 1 $BUILDIDS | \
while read build_id ; do
linkname=$PERF_BUILDID_DIR.build-id/${build_id:0:2}/${build_id:2}
filename=$(readlink -f $linkname)
echo ${linkname#$PERF_BUILDID_DIR} >> $MANIFEST
- echo ${filename#$PERF_BUILDID_DIR} >> $MANIFEST
+ echo ${filename#$PERF_BUILDID_LINKDIR} >> $MANIFEST
done
tar cfj $PERF_DATA.tar.bz2 -C $PERF_BUILDID_DIR -T $MANIFEST
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 00923cd..1efd3be 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -876,11 +876,11 @@
dump_sample(session, event, sample);
if (evsel == NULL) {
++session->hists.stats.nr_unknown_id;
- return -1;
+ return 0;
}
if (machine == NULL) {
++session->hists.stats.nr_unprocessable_samples;
- return -1;
+ return 0;
}
return tool->sample(tool, event, sample, evsel, machine);
case PERF_RECORD_MMAP:
diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c
index a457d21..e9fff98 100644
--- a/virt/kvm/iommu.c
+++ b/virt/kvm/iommu.c
@@ -240,9 +240,13 @@
return -ENODEV;
}
+ mutex_lock(&kvm->slots_lock);
+
kvm->arch.iommu_domain = iommu_domain_alloc(&pci_bus_type);
- if (!kvm->arch.iommu_domain)
- return -ENOMEM;
+ if (!kvm->arch.iommu_domain) {
+ r = -ENOMEM;
+ goto out_unlock;
+ }
if (!allow_unsafe_assigned_interrupts &&
!iommu_domain_has_cap(kvm->arch.iommu_domain,
@@ -253,17 +257,16 @@
" module option.\n", __func__);
iommu_domain_free(kvm->arch.iommu_domain);
kvm->arch.iommu_domain = NULL;
- return -EPERM;
+ r = -EPERM;
+ goto out_unlock;
}
r = kvm_iommu_map_memslots(kvm);
if (r)
- goto out_unmap;
+ kvm_iommu_unmap_memslots(kvm);
- return 0;
-
-out_unmap:
- kvm_iommu_unmap_memslots(kvm);
+out_unlock:
+ mutex_unlock(&kvm->slots_lock);
return r;
}
@@ -310,6 +313,11 @@
}
}
+void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot)
+{
+ kvm_iommu_put_pages(kvm, slot->base_gfn, slot->npages);
+}
+
static int kvm_iommu_unmap_memslots(struct kvm *kvm)
{
int idx;
@@ -320,7 +328,7 @@
slots = kvm_memslots(kvm);
kvm_for_each_memslot(memslot, slots)
- kvm_iommu_put_pages(kvm, memslot->base_gfn, memslot->npages);
+ kvm_iommu_unmap_pages(kvm, memslot);
srcu_read_unlock(&kvm->srcu, idx);
@@ -335,7 +343,11 @@
if (!domain)
return 0;
+ mutex_lock(&kvm->slots_lock);
kvm_iommu_unmap_memslots(kvm);
+ kvm->arch.iommu_domain = NULL;
+ mutex_unlock(&kvm->slots_lock);
+
iommu_domain_free(domain);
return 0;
}
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 42b7393..9739b53 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -808,12 +808,13 @@
if (r)
goto out_free;
- /* map the pages in iommu page table */
+ /* map/unmap the pages in iommu page table */
if (npages) {
r = kvm_iommu_map_pages(kvm, &new);
if (r)
goto out_free;
- }
+ } else
+ kvm_iommu_unmap_pages(kvm, &old);
r = -ENOMEM;
slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots),