--- /dev/null
+From 37c367ecdb9a01c9acc980e6e17913570a1788a7 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 24 Feb 2014 15:23:10 +0100
+Subject: ALSA: hda - Add a fixup for HP Folio 13 mute LED
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 37c367ecdb9a01c9acc980e6e17913570a1788a7 upstream.
+
+HP Folio 13 may have a broken BIOS that doesn't set up the mute LED
+GPIO properly, and the driver guesses it wrongly, too. Add a new
+fixup entry for setting the GPIO pin statically for this laptop.
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=70991
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_sigmatel.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+--- a/sound/pci/hda/patch_sigmatel.c
++++ b/sound/pci/hda/patch_sigmatel.c
+@@ -98,6 +98,7 @@ enum {
+ STAC_92HD83XXX_HP_LED,
+ STAC_92HD83XXX_HP_INV_LED,
+ STAC_92HD83XXX_HP_MIC_LED,
++ STAC_HP_LED_GPIO10,
+ STAC_92HD83XXX_HEADSET_JACK,
+ STAC_92HD83XXX_HP,
+ STAC_HP_ENVY_BASS,
+@@ -2112,6 +2113,17 @@ static void stac92hd83xxx_fixup_hp_mic_l
+ }
+ }
+
++static void stac92hd83xxx_fixup_hp_led_gpio10(struct hda_codec *codec,
++ const struct hda_fixup *fix, int action)
++{
++ struct sigmatel_spec *spec = codec->spec;
++
++ if (action == HDA_FIXUP_ACT_PRE_PROBE) {
++ spec->gpio_led = 0x10; /* GPIO4 */
++ spec->default_polarity = 0;
++ }
++}
++
+ static void stac92hd83xxx_fixup_headset_jack(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+ {
+@@ -2606,6 +2618,12 @@ static const struct hda_fixup stac92hd83
+ .chained = true,
+ .chain_id = STAC_92HD83XXX_HP,
+ },
++ [STAC_HP_LED_GPIO10] = {
++ .type = HDA_FIXUP_FUNC,
++ .v.func = stac92hd83xxx_fixup_hp_led_gpio10,
++ .chained = true,
++ .chain_id = STAC_92HD83XXX_HP,
++ },
+ [STAC_92HD83XXX_HEADSET_JACK] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = stac92hd83xxx_fixup_headset_jack,
+@@ -2684,6 +2702,8 @@ static const struct snd_pci_quirk stac92
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1888,
+ "HP Envy Spectre", STAC_HP_ENVY_BASS),
++ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1899,
++ "HP Folio 13", STAC_HP_LED_GPIO10),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18df,
+ "HP Folio", STAC_HP_BNB13_EQ),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18F8,
--- /dev/null
+From a0657716416f834ef7710a9044614d50a36c3bdc Mon Sep 17 00:00:00 2001
+From: Denis CIOCCA <denis.ciocca@st.com>
+Date: Fri, 14 Feb 2014 14:15:00 +0000
+Subject: iio:gyro: bug on L3GD20H gyroscope support
+
+From: Denis CIOCCA <denis.ciocca@st.com>
+
+commit a0657716416f834ef7710a9044614d50a36c3bdc upstream.
+
+The driver was not able to manage the sensor: during probe function
+and wai check, the driver stops and writes: "device name and WhoAmI mismatch."
+The correct value of L3GD20H wai is 0xd7 instead of 0xd4.
+Dropped support for the sensor.
+
+Signed-off-by: Denis Ciocca <denis.ciocca@st.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/gyro/Kconfig | 2 +-
+ drivers/iio/gyro/st_gyro.h | 1 -
+ drivers/iio/gyro/st_gyro_core.c | 9 ++++-----
+ drivers/iio/gyro/st_gyro_i2c.c | 1 -
+ drivers/iio/gyro/st_gyro_spi.c | 1 -
+ 5 files changed, 5 insertions(+), 9 deletions(-)
+
+--- a/drivers/iio/gyro/Kconfig
++++ b/drivers/iio/gyro/Kconfig
+@@ -70,7 +70,7 @@ config IIO_ST_GYRO_3AXIS
+ select IIO_TRIGGERED_BUFFER if (IIO_BUFFER)
+ help
+ Say yes here to build support for STMicroelectronics gyroscopes:
+- L3G4200D, LSM330DL, L3GD20, L3GD20H, LSM330DLC, L3G4IS, LSM330.
++ L3G4200D, LSM330DL, L3GD20, LSM330DLC, L3G4IS, LSM330.
+
+ This driver can also be built as a module. If so, these modules
+ will be created:
+--- a/drivers/iio/gyro/st_gyro.h
++++ b/drivers/iio/gyro/st_gyro.h
+@@ -19,7 +19,6 @@
+ #define LSM330DL_GYRO_DEV_NAME "lsm330dl_gyro"
+ #define LSM330DLC_GYRO_DEV_NAME "lsm330dlc_gyro"
+ #define L3GD20_GYRO_DEV_NAME "l3gd20"
+-#define L3GD20H_GYRO_DEV_NAME "l3gd20h"
+ #define L3G4IS_GYRO_DEV_NAME "l3g4is_ui"
+ #define LSM330_GYRO_DEV_NAME "lsm330_gyro"
+
+--- a/drivers/iio/gyro/st_gyro_core.c
++++ b/drivers/iio/gyro/st_gyro_core.c
+@@ -167,11 +167,10 @@ static const struct st_sensors st_gyro_s
+ .wai = ST_GYRO_2_WAI_EXP,
+ .sensors_supported = {
+ [0] = L3GD20_GYRO_DEV_NAME,
+- [1] = L3GD20H_GYRO_DEV_NAME,
+- [2] = LSM330D_GYRO_DEV_NAME,
+- [3] = LSM330DLC_GYRO_DEV_NAME,
+- [4] = L3G4IS_GYRO_DEV_NAME,
+- [5] = LSM330_GYRO_DEV_NAME,
++ [1] = LSM330D_GYRO_DEV_NAME,
++ [2] = LSM330DLC_GYRO_DEV_NAME,
++ [3] = L3G4IS_GYRO_DEV_NAME,
++ [4] = LSM330_GYRO_DEV_NAME,
+ },
+ .ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
+ .odr = {
+--- a/drivers/iio/gyro/st_gyro_i2c.c
++++ b/drivers/iio/gyro/st_gyro_i2c.c
+@@ -55,7 +55,6 @@ static const struct i2c_device_id st_gyr
+ { LSM330DL_GYRO_DEV_NAME },
+ { LSM330DLC_GYRO_DEV_NAME },
+ { L3GD20_GYRO_DEV_NAME },
+- { L3GD20H_GYRO_DEV_NAME },
+ { L3G4IS_GYRO_DEV_NAME },
+ { LSM330_GYRO_DEV_NAME },
+ {},
+--- a/drivers/iio/gyro/st_gyro_spi.c
++++ b/drivers/iio/gyro/st_gyro_spi.c
+@@ -54,7 +54,6 @@ static const struct spi_device_id st_gyr
+ { LSM330DL_GYRO_DEV_NAME },
+ { LSM330DLC_GYRO_DEV_NAME },
+ { L3GD20_GYRO_DEV_NAME },
+- { L3GD20H_GYRO_DEV_NAME },
+ { L3G4IS_GYRO_DEV_NAME },
+ { LSM330_GYRO_DEV_NAME },
+ {},
--- /dev/null
+From 97a644208d1a08b7104d1fe2ace8cef011222711 Mon Sep 17 00:00:00 2001
+From: Yifan Zhang <zhangyf@marvell.com>
+Date: Fri, 3 Jan 2014 12:01:26 +0000
+Subject: iommu/arm-smmu: fix pud/pmd entry fill sequence
+
+From: Yifan Zhang <zhangyf@marvell.com>
+
+commit 97a644208d1a08b7104d1fe2ace8cef011222711 upstream.
+
+The ARM SMMU driver's population of puds and pmds is broken, since we
+iterate over the next level of table repeatedly setting the current
+level descriptor to point at the pmd being initialised. This is clearly
+wrong when dealing with multiple pmds/puds.
+
+This patch fixes the problem by moving the pud/pmd population out of the
+loop and instead performing it when we allocate the next level (like we
+correctly do for ptes already). The starting address for the next level
+is then calculated prior to entering the loop.
+
+Signed-off-by: Yifan Zhang <zhangyf@marvell.com>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/arm-smmu.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+--- a/drivers/iommu/arm-smmu.c
++++ b/drivers/iommu/arm-smmu.c
+@@ -1317,6 +1317,11 @@ static int arm_smmu_alloc_init_pmd(struc
+ pmd = pmd_alloc_one(NULL, addr);
+ if (!pmd)
+ return -ENOMEM;
++
++ pud_populate(NULL, pud, pmd);
++ arm_smmu_flush_pgtable(smmu, pud, sizeof(*pud));
++
++ pmd += pmd_index(addr);
+ } else
+ #endif
+ pmd = pmd_offset(pud, addr);
+@@ -1325,8 +1330,6 @@ static int arm_smmu_alloc_init_pmd(struc
+ next = pmd_addr_end(addr, end);
+ ret = arm_smmu_alloc_init_pte(smmu, pmd, addr, end, pfn,
+ flags, stage);
+- pud_populate(NULL, pud, pmd);
+- arm_smmu_flush_pgtable(smmu, pud, sizeof(*pud));
+ phys += next - addr;
+ } while (pmd++, addr = next, addr < end);
+
+@@ -1346,6 +1349,11 @@ static int arm_smmu_alloc_init_pud(struc
+ pud = pud_alloc_one(NULL, addr);
+ if (!pud)
+ return -ENOMEM;
++
++ pgd_populate(NULL, pgd, pud);
++ arm_smmu_flush_pgtable(smmu, pgd, sizeof(*pgd));
++
++ pud += pud_index(addr);
+ } else
+ #endif
+ pud = pud_offset(pgd, addr);
+@@ -1354,8 +1362,6 @@ static int arm_smmu_alloc_init_pud(struc
+ next = pud_addr_end(addr, end);
+ ret = arm_smmu_alloc_init_pmd(smmu, pud, addr, next, phys,
+ flags, stage);
+- pgd_populate(NULL, pud, pgd);
+- arm_smmu_flush_pgtable(smmu, pgd, sizeof(*pgd));
+ phys += next - addr;
+ } while (pud++, addr = next, addr < end);
+
--- /dev/null
+From 6dd35f45b8dac827b6f9dd86f5aca6436cdd2410 Mon Sep 17 00:00:00 2001
+From: Will Deacon <will.deacon@arm.com>
+Date: Wed, 5 Feb 2014 17:49:34 +0000
+Subject: iommu/arm-smmu: fix table flushing during initial allocations
+
+From: Will Deacon <will.deacon@arm.com>
+
+commit 6dd35f45b8dac827b6f9dd86f5aca6436cdd2410 upstream.
+
+Now that we populate page tables as we traverse them ("iommu/arm-smmu:
+fix pud/pmd entry fill sequence"), we need to ensure that we flush out
+our zeroed tables after initial allocation, to prevent speculative TLB
+fills using bogus data.
+
+This patch adds additional calls to arm_smmu_flush_pgtable during
+initial table allocation, and moves the dsb required by coherent table
+walkers into the helper.
+
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/arm-smmu.c | 51 ++++++++++++++++++++++++-----------------------
+ 1 file changed, 27 insertions(+), 24 deletions(-)
+
+--- a/drivers/iommu/arm-smmu.c
++++ b/drivers/iommu/arm-smmu.c
+@@ -78,7 +78,6 @@
+
+ #define ARM_SMMU_PTE_CONT_SIZE (PAGE_SIZE * ARM_SMMU_PTE_CONT_ENTRIES)
+ #define ARM_SMMU_PTE_CONT_MASK (~(ARM_SMMU_PTE_CONT_SIZE - 1))
+-#define ARM_SMMU_PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(pte_t))
+
+ /* Stage-1 PTE */
+ #define ARM_SMMU_PTE_AP_UNPRIV (((pteval_t)1) << 6)
+@@ -631,6 +630,28 @@ static irqreturn_t arm_smmu_global_fault
+ return IRQ_HANDLED;
+ }
+
++static void arm_smmu_flush_pgtable(struct arm_smmu_device *smmu, void *addr,
++ size_t size)
++{
++ unsigned long offset = (unsigned long)addr & ~PAGE_MASK;
++
++
++ /* Ensure new page tables are visible to the hardware walker */
++ if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK) {
++ dsb();
++ } else {
++ /*
++ * If the SMMU can't walk tables in the CPU caches, treat them
++ * like non-coherent DMA since we need to flush the new entries
++ * all the way out to memory. There's no possibility of
++ * recursion here as the SMMU table walker will not be wired
++ * through another SMMU.
++ */
++ dma_map_page(smmu->dev, virt_to_page(addr), offset, size,
++ DMA_TO_DEVICE);
++ }
++}
++
+ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)
+ {
+ u32 reg;
+@@ -714,6 +735,8 @@ static void arm_smmu_init_context_bank(s
+ }
+
+ /* TTBR0 */
++ arm_smmu_flush_pgtable(smmu, root_cfg->pgd,
++ PTRS_PER_PGD * sizeof(pgd_t));
+ reg = __pa(root_cfg->pgd);
+ writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO);
+ reg = (phys_addr_t)__pa(root_cfg->pgd) >> 32;
+@@ -1176,23 +1199,6 @@ static void arm_smmu_detach_dev(struct i
+ arm_smmu_domain_remove_master(smmu_domain, master);
+ }
+
+-static void arm_smmu_flush_pgtable(struct arm_smmu_device *smmu, void *addr,
+- size_t size)
+-{
+- unsigned long offset = (unsigned long)addr & ~PAGE_MASK;
+-
+- /*
+- * If the SMMU can't walk tables in the CPU caches, treat them
+- * like non-coherent DMA since we need to flush the new entries
+- * all the way out to memory. There's no possibility of recursion
+- * here as the SMMU table walker will not be wired through another
+- * SMMU.
+- */
+- if (!(smmu->features & ARM_SMMU_FEAT_COHERENT_WALK))
+- dma_map_page(smmu->dev, virt_to_page(addr), offset, size,
+- DMA_TO_DEVICE);
+-}
+-
+ static bool arm_smmu_pte_is_contiguous_range(unsigned long addr,
+ unsigned long end)
+ {
+@@ -1213,8 +1219,7 @@ static int arm_smmu_alloc_init_pte(struc
+ if (!table)
+ return -ENOMEM;
+
+- arm_smmu_flush_pgtable(smmu, page_address(table),
+- ARM_SMMU_PTE_HWTABLE_SIZE);
++ arm_smmu_flush_pgtable(smmu, page_address(table), PAGE_SIZE);
+ if (!pgtable_page_ctor(table)) {
+ __free_page(table);
+ return -ENOMEM;
+@@ -1318,6 +1323,7 @@ static int arm_smmu_alloc_init_pmd(struc
+ if (!pmd)
+ return -ENOMEM;
+
++ arm_smmu_flush_pgtable(smmu, pmd, PAGE_SIZE);
+ pud_populate(NULL, pud, pmd);
+ arm_smmu_flush_pgtable(smmu, pud, sizeof(*pud));
+
+@@ -1350,6 +1356,7 @@ static int arm_smmu_alloc_init_pud(struc
+ if (!pud)
+ return -ENOMEM;
+
++ arm_smmu_flush_pgtable(smmu, pud, PAGE_SIZE);
+ pgd_populate(NULL, pgd, pud);
+ arm_smmu_flush_pgtable(smmu, pgd, sizeof(*pgd));
+
+@@ -1418,10 +1425,6 @@ static int arm_smmu_handle_mapping(struc
+ out_unlock:
+ spin_unlock(&smmu_domain->lock);
+
+- /* Ensure new page tables are visible to the hardware walker */
+- if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
+- dsb();
+-
+ return ret;
+ }
+
--- /dev/null
+From c9d09e2748eaa55cac2af274574baa6368189bc1 Mon Sep 17 00:00:00 2001
+From: Will Deacon <will.deacon@arm.com>
+Date: Tue, 4 Feb 2014 22:12:42 +0000
+Subject: iommu/arm-smmu: really fix page table locking
+
+From: Will Deacon <will.deacon@arm.com>
+
+commit c9d09e2748eaa55cac2af274574baa6368189bc1 upstream.
+
+Commit a44a9791e778 ("iommu/arm-smmu: use mutex instead of spinlock for
+locking page tables") replaced the page table spinlock with a mutex, to
+allow blocking allocations to satisfy lazy mapping requests.
+
+Unfortunately, it turns out that IOMMU mappings are created from atomic
+context (e.g. spinlock held during a dma_map), so this change doesn't
+really help us in practice.
+
+This patch is a partial revert of the offending commit, bringing back
+the original spinlock but replacing our page table allocations for any
+levels below the pgd (which is allocated during domain init) with
+GFP_ATOMIC instead of GFP_KERNEL.
+
+Reported-by: Andreas Herrmann <andreas.herrmann@calxeda.com>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/arm-smmu.c | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+--- a/drivers/iommu/arm-smmu.c
++++ b/drivers/iommu/arm-smmu.c
+@@ -392,7 +392,7 @@ struct arm_smmu_domain {
+ struct arm_smmu_cfg root_cfg;
+ phys_addr_t output_mask;
+
+- struct mutex lock;
++ spinlock_t lock;
+ };
+
+ static DEFINE_SPINLOCK(arm_smmu_devices_lock);
+@@ -900,7 +900,7 @@ static int arm_smmu_domain_init(struct i
+ goto out_free_domain;
+ smmu_domain->root_cfg.pgd = pgd;
+
+- mutex_init(&smmu_domain->lock);
++ spin_lock_init(&smmu_domain->lock);
+ domain->priv = smmu_domain;
+ return 0;
+
+@@ -1137,7 +1137,7 @@ static int arm_smmu_attach_dev(struct io
+ * Sanity check the domain. We don't currently support domains
+ * that cross between different SMMU chains.
+ */
+- mutex_lock(&smmu_domain->lock);
++ spin_lock(&smmu_domain->lock);
+ if (!smmu_domain->leaf_smmu) {
+ /* Now that we have a master, we can finalise the domain */
+ ret = arm_smmu_init_domain_context(domain, dev);
+@@ -1152,7 +1152,7 @@ static int arm_smmu_attach_dev(struct io
+ dev_name(device_smmu->dev));
+ goto err_unlock;
+ }
+- mutex_unlock(&smmu_domain->lock);
++ spin_unlock(&smmu_domain->lock);
+
+ /* Looks ok, so add the device to the domain */
+ master = find_smmu_master(smmu_domain->leaf_smmu, dev->of_node);
+@@ -1162,7 +1162,7 @@ static int arm_smmu_attach_dev(struct io
+ return arm_smmu_domain_add_master(smmu_domain, master);
+
+ err_unlock:
+- mutex_unlock(&smmu_domain->lock);
++ spin_unlock(&smmu_domain->lock);
+ return ret;
+ }
+
+@@ -1209,7 +1209,7 @@ static int arm_smmu_alloc_init_pte(struc
+
+ if (pmd_none(*pmd)) {
+ /* Allocate a new set of tables */
+- pgtable_t table = alloc_page(PGALLOC_GFP);
++ pgtable_t table = alloc_page(GFP_ATOMIC|__GFP_ZERO);
+ if (!table)
+ return -ENOMEM;
+
+@@ -1314,7 +1314,7 @@ static int arm_smmu_alloc_init_pmd(struc
+
+ #ifndef __PAGETABLE_PMD_FOLDED
+ if (pud_none(*pud)) {
+- pmd = pmd_alloc_one(NULL, addr);
++ pmd = (pmd_t *)get_zeroed_page(GFP_ATOMIC);
+ if (!pmd)
+ return -ENOMEM;
+
+@@ -1346,7 +1346,7 @@ static int arm_smmu_alloc_init_pud(struc
+
+ #ifndef __PAGETABLE_PUD_FOLDED
+ if (pgd_none(*pgd)) {
+- pud = pud_alloc_one(NULL, addr);
++ pud = (pud_t *)get_zeroed_page(GFP_ATOMIC);
+ if (!pud)
+ return -ENOMEM;
+
+@@ -1400,7 +1400,7 @@ static int arm_smmu_handle_mapping(struc
+ if (paddr & ~output_mask)
+ return -ERANGE;
+
+- mutex_lock(&smmu_domain->lock);
++ spin_lock(&smmu_domain->lock);
+ pgd += pgd_index(iova);
+ end = iova + size;
+ do {
+@@ -1416,7 +1416,7 @@ static int arm_smmu_handle_mapping(struc
+ } while (pgd++, iova != end);
+
+ out_unlock:
+- mutex_unlock(&smmu_domain->lock);
++ spin_unlock(&smmu_domain->lock);
+
+ /* Ensure new page tables are visible to the hardware walker */
+ if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
--- /dev/null
+From 57ca90f6800987ac274d7ba065ae6692cdf9bcd7 Mon Sep 17 00:00:00 2001
+From: Will Deacon <will.deacon@arm.com>
+Date: Thu, 6 Feb 2014 14:59:05 +0000
+Subject: iommu/arm-smmu: set CBARn.BPSHCFG to NSH for s1-s2-bypass contexts
+
+From: Will Deacon <will.deacon@arm.com>
+
+commit 57ca90f6800987ac274d7ba065ae6692cdf9bcd7 upstream.
+
+Whilst trying to bring-up an SMMUv2 implementation with the table
+walker plumbed into a coherent interconnect, I noticed that the memory
+transactions targetting the CPU caches from the SMMU were marked as
+outer-shareable instead of inner-shareable.
+
+After a bunch of digging, it seems that we actually need to program
+CBARn.BPSHCFG for s1-s2-bypass contexts to act as non-shareable in order
+for the shareability configured in the corresponding TTBCR not to be
+overridden with an outer-shareable attribute.
+
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/arm-smmu.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+--- a/drivers/iommu/arm-smmu.c
++++ b/drivers/iommu/arm-smmu.c
+@@ -189,6 +189,9 @@
+ #define ARM_SMMU_GR1_CBAR(n) (0x0 + ((n) << 2))
+ #define CBAR_VMID_SHIFT 0
+ #define CBAR_VMID_MASK 0xff
++#define CBAR_S1_BPSHCFG_SHIFT 8
++#define CBAR_S1_BPSHCFG_MASK 3
++#define CBAR_S1_BPSHCFG_NSH 3
+ #define CBAR_S1_MEMATTR_SHIFT 12
+ #define CBAR_S1_MEMATTR_MASK 0xf
+ #define CBAR_S1_MEMATTR_WB 0xf
+@@ -670,11 +673,16 @@ static void arm_smmu_init_context_bank(s
+ if (smmu->version == 1)
+ reg |= root_cfg->irptndx << CBAR_IRPTNDX_SHIFT;
+
+- /* Use the weakest memory type, so it is overridden by the pte */
+- if (stage1)
+- reg |= (CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT);
+- else
++ /*
++ * Use the weakest shareability/memory types, so they are
++ * overridden by the ttbcr/pte.
++ */
++ if (stage1) {
++ reg |= (CBAR_S1_BPSHCFG_NSH << CBAR_S1_BPSHCFG_SHIFT) |
++ (CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT);
++ } else {
+ reg |= ARM_SMMU_CB_VMID(root_cfg) << CBAR_VMID_SHIFT;
++ }
+ writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(root_cfg->cbndx));
+
+ if (smmu->version > 1) {
--- /dev/null
+From 7b119fd1bdc59a8060df5b659b9f7a70e0169fd6 Mon Sep 17 00:00:00 2001
+From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+Date: Thu, 23 Jan 2014 23:38:04 +0100
+Subject: irqchip: orion: clear bridge cause register on init
+
+From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+
+commit 7b119fd1bdc59a8060df5b659b9f7a70e0169fd6 upstream.
+
+It is good practice to mask and clear pending irqs on init. We already
+mask all irqs, so also clear the bridge irq cause register.
+
+Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Signed-off-by: Jason Cooper <jason@lakedaemon.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/irqchip/irq-orion.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/irqchip/irq-orion.c
++++ b/drivers/irqchip/irq-orion.c
+@@ -180,8 +180,9 @@ static int __init orion_bridge_irq_init(
+ gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
+ gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
+
+- /* mask all interrupts */
++ /* mask and clear all interrupts */
+ writel(0, gc->reg_base + ORION_BRIDGE_IRQ_MASK);
++ writel(0, gc->reg_base + ORION_BRIDGE_IRQ_CAUSE);
+
+ irq_set_handler_data(irq, domain);
+ irq_set_chained_handler(irq, orion_bridge_irq_handler);
--- /dev/null
+From e0318ec3bf3f1502cd11b21b1eb00aa355b40b67 Mon Sep 17 00:00:00 2001
+From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+Date: Fri, 24 Jan 2014 00:10:32 +0100
+Subject: irqchip: orion: clear stale interrupts in irq_startup
+
+From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+
+commit e0318ec3bf3f1502cd11b21b1eb00aa355b40b67 upstream.
+
+Bridge IRQ_CAUSE bits are asserted regardless of the corresponding bit in
+IRQ_MASK register. To avoid interrupt events on stale irqs, we have to clear
+them before unmask. This installs an .irq_startup callback to ensure stale
+irqs are cleared before initial unmask.
+
+Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Signed-off-by: Jason Cooper <jason@lakedaemon.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/irqchip/irq-orion.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/drivers/irqchip/irq-orion.c
++++ b/drivers/irqchip/irq-orion.c
+@@ -123,6 +123,19 @@ static void orion_bridge_irq_handler(uns
+ }
+ }
+
++/*
++ * Bridge IRQ_CAUSE is asserted regardless of IRQ_MASK register.
++ * To avoid interrupt events on stale irqs, we clear them before unmask.
++ */
++static unsigned int orion_bridge_irq_startup(struct irq_data *d)
++{
++ struct irq_chip_type *ct = irq_data_get_chip_type(d);
++
++ ct->chip.irq_ack(d);
++ ct->chip.irq_unmask(d);
++ return 0;
++}
++
+ static int __init orion_bridge_irq_init(struct device_node *np,
+ struct device_node *parent)
+ {
+@@ -176,6 +189,7 @@ static int __init orion_bridge_irq_init(
+
+ gc->chip_types[0].regs.ack = ORION_BRIDGE_IRQ_CAUSE;
+ gc->chip_types[0].regs.mask = ORION_BRIDGE_IRQ_MASK;
++ gc->chip_types[0].chip.irq_startup = orion_bridge_irq_startup;
+ gc->chip_types[0].chip.irq_ack = irq_gc_ack_clr_bit;
+ gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
+ gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
--- /dev/null
+From d86e9af6336c0ad586a5dbd70064253d40bbb5ff Mon Sep 17 00:00:00 2001
+From: Andrew Lunn <andrew@lunn.ch>
+Date: Fri, 7 Feb 2014 00:41:58 +0100
+Subject: irqchip: orion: Fix getting generic chip pointer.
+
+From: Andrew Lunn <andrew@lunn.ch>
+
+commit d86e9af6336c0ad586a5dbd70064253d40bbb5ff upstream.
+
+Enabling SPARSE_IRQ shows up a bug in the irq-orion bridge interrupt
+handler. The bridge interrupt is implemented using a single generic
+chip. Thus the parameter passed to irq_get_domain_generic_chip()
+should always be zero.
+
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+Acked-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+Fixes: 9dbd90f17e4f ("irqchip: Add support for Marvell Orion SoCs")
+Signed-off-by: Jason Cooper <jason@lakedaemon.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/irqchip/irq-orion.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/irqchip/irq-orion.c
++++ b/drivers/irqchip/irq-orion.c
+@@ -111,7 +111,8 @@ IRQCHIP_DECLARE(orion_intc, "marvell,ori
+ static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc)
+ {
+ struct irq_domain *d = irq_get_handler_data(irq);
+- struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, irq);
++
++ struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, 0);
+ u32 stat = readl_relaxed(gc->reg_base + ORION_BRIDGE_IRQ_CAUSE) &
+ gc->mask_cache;
+
--- /dev/null
+From 5f40067fc86f0e49329ad4a852c278998ff4394e Mon Sep 17 00:00:00 2001
+From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+Date: Thu, 23 Jan 2014 23:38:05 +0100
+Subject: irqchip: orion: use handle_edge_irq on bridge irqs
+
+From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+
+commit 5f40067fc86f0e49329ad4a852c278998ff4394e upstream.
+
+Bridge irqs are edge-triggered, i.e. they get asserted on low-to-high
+transitions and not on the level of the downstream interrupt line.
+This replaces handle_level_irq by the more appropriate handle_edge_irq.
+
+Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Signed-off-by: Jason Cooper <jason@lakedaemon.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/irqchip/irq-orion.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/irqchip/irq-orion.c
++++ b/drivers/irqchip/irq-orion.c
+@@ -143,7 +143,7 @@ static int __init orion_bridge_irq_init(
+ }
+
+ ret = irq_alloc_domain_generic_chips(domain, nrirqs, 1, np->name,
+- handle_level_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE);
++ handle_edge_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE);
+ if (ret) {
+ pr_err("%s: unable to alloc irq domain gc\n", np->name);
+ return ret;
--- /dev/null
+From e3703f8cdfcf39c25c4338c3ad8e68891cca3731 Mon Sep 17 00:00:00 2001
+From: Peter Zijlstra <peterz@infradead.org>
+Date: Mon, 24 Feb 2014 12:06:12 +0100
+Subject: perf: Fix hotplug splat
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+commit e3703f8cdfcf39c25c4338c3ad8e68891cca3731 upstream.
+
+Drew Richardson reported that he could make the kernel go *boom* when hotplugging
+while having perf events active.
+
+It turned out that when you have a group event, the code in
+__perf_event_exit_context() fails to remove the group siblings from
+the context.
+
+We then proceed with destroying and freeing the event, and when you
+re-plug the CPU and try and add another event to that CPU, things go
+*boom* because you've still got dead entries there.
+
+Reported-by: Drew Richardson <drew.richardson@arm.com>
+Signed-off-by: Peter Zijlstra <peterz@infradead.org>
+Cc: Will Deacon <will.deacon@arm.com>
+Link: http://lkml.kernel.org/n/tip-k6v5wundvusvcseqj1si0oz0@git.kernel.org
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/events/core.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -7833,14 +7833,14 @@ static void perf_pmu_rotate_stop(struct
+ static void __perf_event_exit_context(void *__info)
+ {
+ struct perf_event_context *ctx = __info;
+- struct perf_event *event, *tmp;
++ struct perf_event *event;
+
+ perf_pmu_rotate_stop(ctx->pmu);
+
+- list_for_each_entry_safe(event, tmp, &ctx->pinned_groups, group_entry)
+- __perf_remove_from_context(event);
+- list_for_each_entry_safe(event, tmp, &ctx->flexible_groups, group_entry)
++ rcu_read_lock();
++ list_for_each_entry_rcu(event, &ctx->event_list, event_entry)
+ __perf_remove_from_context(event);
++ rcu_read_unlock();
+ }
+
+ static void perf_event_exit_cpu_context(int cpu)
+@@ -7864,11 +7864,11 @@ static void perf_event_exit_cpu(int cpu)
+ {
+ struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu);
+
++ perf_event_exit_cpu_context(cpu);
++
+ mutex_lock(&swhash->hlist_mutex);
+ swevent_hlist_release(swhash);
+ mutex_unlock(&swhash->hlist_mutex);
+-
+- perf_event_exit_cpu_context(cpu);
+ }
+ #else
+ static inline void perf_event_exit_cpu(int cpu) { }
--- /dev/null
+From 79d26a6a19ace19faabf8d8d27d3430be2e26d34 Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Thu, 6 Feb 2014 01:00:35 +0000
+Subject: perf trace: Add fallback definition of EFD_SEMAPHORE
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+commit 79d26a6a19ace19faabf8d8d27d3430be2e26d34 upstream.
+
+glibc 2.17 is missing this on sparc, despite the fact that it's not
+architecture-specific.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Fixes: 49af9e93adfa ('perf trace: Beautify eventfd2 'flags' arg')
+Cc: <stable@vger.kernel.org>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Link: http://lkml.kernel.org/r/1391648435.3003.100.camel@deadeye.wl.decadent.org.uk
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ tools/perf/builtin-trace.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/tools/perf/builtin-trace.c
++++ b/tools/perf/builtin-trace.c
+@@ -35,6 +35,10 @@
+ # define MADV_UNMERGEABLE 13
+ #endif
+
++#ifndef EFD_SEMAPHORE
++# define EFD_SEMAPHORE 1
++#endif
++
+ struct tp_field {
+ int offset;
+ union {
mtd-nand-omap-fix-ecclayout-to-be-in-sync-with-u-boot-nand-driver.patch
mtd-nand-omap-fix-ecclayout-oobfree-offset.patch
mtd-nand-omap-fix-ecclayout-oobfree-length.patch
+staging-binder-fix-death-notifications.patch
+staging-iio-adc-mxs-lradc-fix-touchscreen-statemachine.patch
+staging-r8188eu-add-new-device-id.patch
+iio-gyro-bug-on-l3gd20h-gyroscope-support.patch
+iommu-arm-smmu-fix-pud-pmd-entry-fill-sequence.patch
+iommu-arm-smmu-really-fix-page-table-locking.patch
+iommu-arm-smmu-fix-table-flushing-during-initial-allocations.patch
+iommu-arm-smmu-set-cbarn.bpshcfg-to-nsh-for-s1-s2-bypass-contexts.patch
+perf-trace-add-fallback-definition-of-efd_semaphore.patch
+perf-fix-hotplug-splat.patch
+alsa-hda-add-a-fixup-for-hp-folio-13-mute-led.patch
+irqchip-orion-clear-bridge-cause-register-on-init.patch
+irqchip-orion-use-handle_edge_irq-on-bridge-irqs.patch
+irqchip-orion-clear-stale-interrupts-in-irq_startup.patch
+irqchip-orion-fix-getting-generic-chip-pointer.patch
+xtensa-save-current-register-frame-in-fast_syscall_spill_registers_fixup.patch
+xtensa-introduce-spill_registers_kernel-macro.patch
--- /dev/null
+From e194fd8a5d8e0a7eeed239a8534460724b62fe2d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= <arve@android.com>
+Date: Mon, 17 Feb 2014 13:58:29 -0800
+Subject: staging: binder: Fix death notifications
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= <arve@android.com>
+
+commit e194fd8a5d8e0a7eeed239a8534460724b62fe2d upstream.
+
+The change (008fa749e0fe5b2fffd20b7fe4891bb80d072c6a) that moved the
+node release code to a separate function broke death notifications in
+some cases. When it encountered a reference without a death
+notification request, it would skip looking at the remaining
+references, and therefore fail to send death notifications for them.
+
+Cc: Colin Cross <ccross@android.com>
+Cc: Android Kernel Team <kernel-team@android.com>
+Signed-off-by: Arve Hjønnevåg <arve@android.com>
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Signed-off-by: Jeremy Compostella <jeremy.compostella@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/android/binder.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/staging/android/binder.c
++++ b/drivers/staging/android/binder.c
+@@ -2904,7 +2904,7 @@ static int binder_node_release(struct bi
+ refs++;
+
+ if (!ref->death)
+- goto out;
++ continue;
+
+ death++;
+
+@@ -2917,7 +2917,6 @@ static int binder_node_release(struct bi
+ BUG();
+ }
+
+-out:
+ binder_debug(BINDER_DEBUG_DEAD_BINDER,
+ "node %d now dead, refs %d, death %d\n",
+ node->debug_id, refs, death);
--- /dev/null
+From 760dbe1dcb6d3dd3ead73dc69b23f206b52273bb Mon Sep 17 00:00:00 2001
+From: Juergen Beisert <jbe@pengutronix.de>
+Date: Mon, 24 Feb 2014 14:39:00 +0000
+Subject: staging:iio:adc:MXS:LRADC: fix touchscreen statemachine
+
+From: Juergen Beisert <jbe@pengutronix.de>
+
+commit 760dbe1dcb6d3dd3ead73dc69b23f206b52273bb upstream.
+
+Releasing the touchscreen lets the internal statemachine left in a wrong state.
+Due to this the release coordinate will be reported again by accident when the next
+touchscreen event happens. This change sets up the correct state when waiting
+for the next touchscreen event.
+
+This has led to reported issues with calibrating the touchscreen.
+Bug was introduced somewhere in the series that began with
+18da755de59b406ce2371a55fb15ed676eb08ed2
+Staging/iio/adc/touchscreen/MXS: add proper clock handling
+in which the way this driver worked was substantially changed
+to be interrupt driven rather than relying on a busy loop.
+This was a regression in the 3.13 kernel.
+
+Signed-off-by: Juergen Beisert <jbe@pengutronix.de>
+Tested-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/iio/adc/mxs-lradc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/staging/iio/adc/mxs-lradc.c
++++ b/drivers/staging/iio/adc/mxs-lradc.c
+@@ -698,6 +698,7 @@ static void mxs_lradc_finish_touch_event
+ }
+
+ /* if it is released, wait for the next touch via IRQ */
++ lradc->cur_plate = LRADC_TOUCH;
+ mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ, LRADC_CTRL1);
+ mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1);
+ }
--- /dev/null
+From 260ea9c2e2d330303163e286ab01b66dbcfe3a6f Mon Sep 17 00:00:00 2001
+From: Manu Gupta <manugupt1@gmail.com>
+Date: Mon, 24 Feb 2014 12:12:28 -0600
+Subject: staging: r8188eu: Add new device ID
+
+From: Manu Gupta <manugupt1@gmail.com>
+
+commit 260ea9c2e2d330303163e286ab01b66dbcfe3a6f upstream.
+
+The D-Link DWA-123 REV D1 with USB ID 2001:3310 uses this driver.
+
+Signed-off-by: Manu Gupta <manugupt1@gmail.com>
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/rtl8188eu/os_dep/usb_intf.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c
++++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c
+@@ -55,6 +55,7 @@ static struct usb_device_id rtw_usb_id_t
+ /****** 8188EUS ********/
+ {USB_DEVICE(0x07b8, 0x8179)}, /* Abocom - Abocom */
+ {USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */
++ {USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */
+ {} /* Terminating entry */
+ };
+
--- /dev/null
+From e2fd1374c705abe4661df3fb6fadb3879c7c1846 Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc@gmail.com>
+Date: Wed, 22 Jan 2014 08:04:43 +0400
+Subject: xtensa: introduce spill_registers_kernel macro
+
+From: Max Filippov <jcmvbkbc@gmail.com>
+
+commit e2fd1374c705abe4661df3fb6fadb3879c7c1846 upstream.
+
+Most in-kernel users want registers spilled on the kernel stack and
+don't require PS.EXCM to be set. That means that they don't need fixup
+routine and could reuse regular window overflow mechanism for that,
+which makes spill routine very simple.
+
+Suggested-by: Chris Zankel <chris@zankel.net>
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/xtensa/include/asm/traps.h | 44 ++++++++++++++++++-----------
+ arch/xtensa/kernel/entry.S | 60 ++++++++++++++++++++++++++++++++--------
+ 2 files changed, 76 insertions(+), 28 deletions(-)
+
+--- a/arch/xtensa/include/asm/traps.h
++++ b/arch/xtensa/include/asm/traps.h
+@@ -22,25 +22,37 @@ extern void do_unhandled(struct pt_regs
+
+ static inline void spill_registers(void)
+ {
+-
++#if XCHAL_NUM_AREGS > 16
+ __asm__ __volatile__ (
+- "movi a14, "__stringify((1 << PS_EXCM_BIT) | LOCKLEVEL)"\n\t"
+- "mov a12, a0\n\t"
+- "rsr a13, sar\n\t"
+- "xsr a14, ps\n\t"
+- "movi a0, _spill_registers\n\t"
+- "rsync\n\t"
+- "callx0 a0\n\t"
+- "mov a0, a12\n\t"
+- "wsr a13, sar\n\t"
+- "wsr a14, ps\n\t"
+- : :
+-#if defined(CONFIG_FRAME_POINTER)
+- : "a2", "a3", "a4", "a11", "a12", "a13", "a14", "a15",
++ " call12 1f\n"
++ " _j 2f\n"
++ " retw\n"
++ " .align 4\n"
++ "1:\n"
++ " _entry a1, 48\n"
++ " addi a12, a0, 3\n"
++#if XCHAL_NUM_AREGS > 32
++ " .rept (" __stringify(XCHAL_NUM_AREGS) " - 32) / 12\n"
++ " _entry a1, 48\n"
++ " mov a12, a0\n"
++ " .endr\n"
++#endif
++ " _entry a1, 48\n"
++#if XCHAL_NUM_AREGS % 12 == 0
++ " mov a8, a8\n"
++#elif XCHAL_NUM_AREGS % 12 == 4
++ " mov a12, a12\n"
++#elif XCHAL_NUM_AREGS % 12 == 8
++ " mov a4, a4\n"
++#endif
++ " retw\n"
++ "2:\n"
++ : : : "a12", "a13", "memory");
+ #else
+- : "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15",
++ __asm__ __volatile__ (
++ " mov a12, a12\n"
++ : : : "memory");
+ #endif
+- "memory");
+ }
+
+ #endif /* _XTENSA_TRAPS_H */
+--- a/arch/xtensa/kernel/entry.S
++++ b/arch/xtensa/kernel/entry.S
+@@ -1806,6 +1806,43 @@ ENTRY(system_call)
+
+ ENDPROC(system_call)
+
++/*
++ * Spill live registers on the kernel stack macro.
++ *
++ * Entry condition: ps.woe is set, ps.excm is cleared
++ * Exit condition: windowstart has single bit set
++ * May clobber: a12, a13
++ */
++ .macro spill_registers_kernel
++
++#if XCHAL_NUM_AREGS > 16
++ call12 1f
++ _j 2f
++ retw
++ .align 4
++1:
++ _entry a1, 48
++ addi a12, a0, 3
++#if XCHAL_NUM_AREGS > 32
++ .rept (XCHAL_NUM_AREGS - 32) / 12
++ _entry a1, 48
++ mov a12, a0
++ .endr
++#endif
++ _entry a1, 48
++#if XCHAL_NUM_AREGS % 12 == 0
++ mov a8, a8
++#elif XCHAL_NUM_AREGS % 12 == 4
++ mov a12, a12
++#elif XCHAL_NUM_AREGS % 12 == 8
++ mov a4, a4
++#endif
++ retw
++2:
++#else
++ mov a12, a12
++#endif
++ .endm
+
+ /*
+ * Task switch.
+@@ -1818,21 +1855,20 @@ ENTRY(_switch_to)
+
+ entry a1, 16
+
+- mov a12, a2 # preserve 'prev' (a2)
+- mov a13, a3 # and 'next' (a3)
++ mov a10, a2 # preserve 'prev' (a2)
++ mov a11, a3 # and 'next' (a3)
+
+ l32i a4, a2, TASK_THREAD_INFO
+ l32i a5, a3, TASK_THREAD_INFO
+
+- save_xtregs_user a4 a6 a8 a9 a10 a11 THREAD_XTREGS_USER
++ save_xtregs_user a4 a6 a8 a9 a12 a13 THREAD_XTREGS_USER
+
+- s32i a0, a12, THREAD_RA # save return address
+- s32i a1, a12, THREAD_SP # save stack pointer
++ s32i a0, a10, THREAD_RA # save return address
++ s32i a1, a10, THREAD_SP # save stack pointer
+
+ /* Disable ints while we manipulate the stack pointer. */
+
+- movi a14, (1 << PS_EXCM_BIT) | LOCKLEVEL
+- xsr a14, ps
++ rsil a14, LOCKLEVEL
+ rsr a3, excsave1
+ rsync
+ s32i a3, a3, EXC_TABLE_FIXUP /* enter critical section */
+@@ -1847,7 +1883,7 @@ ENTRY(_switch_to)
+
+ /* Flush register file. */
+
+- call0 _spill_registers # destroys a3, a4, and SAR
++ spill_registers_kernel
+
+ /* Set kernel stack (and leave critical section)
+ * Note: It's save to set it here. The stack will not be overwritten
+@@ -1863,13 +1899,13 @@ ENTRY(_switch_to)
+
+ /* restore context of the task 'next' */
+
+- l32i a0, a13, THREAD_RA # restore return address
+- l32i a1, a13, THREAD_SP # restore stack pointer
++ l32i a0, a11, THREAD_RA # restore return address
++ l32i a1, a11, THREAD_SP # restore stack pointer
+
+- load_xtregs_user a5 a6 a8 a9 a10 a11 THREAD_XTREGS_USER
++ load_xtregs_user a5 a6 a8 a9 a12 a13 THREAD_XTREGS_USER
+
+ wsr a14, ps
+- mov a2, a12 # return 'prev'
++ mov a2, a10 # return 'prev'
+ rsync
+
+ retw
--- /dev/null
+From 3251f1e27a5a17f0efd436cfd1e7b9896cfab0a0 Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc@gmail.com>
+Date: Wed, 30 Oct 2013 16:18:25 +0400
+Subject: xtensa: save current register frame in fast_syscall_spill_registers_fixup
+
+From: Max Filippov <jcmvbkbc@gmail.com>
+
+commit 3251f1e27a5a17f0efd436cfd1e7b9896cfab0a0 upstream.
+
+We need it saved because it contains a3 where we track which register
+windows we still need to spill, and fixup handler may call C exception
+handlers. Also fix comments.
+
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/xtensa/kernel/entry.S | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/arch/xtensa/kernel/entry.S
++++ b/arch/xtensa/kernel/entry.S
+@@ -1117,6 +1117,13 @@ ENDPROC(fast_syscall_spill_registers)
+ * We basically restore WINDOWBASE and WINDOWSTART to the condition when
+ * we entered the spill routine and jump to the user exception handler.
+ *
++ * Note that we only need to restore the bits in windowstart that have not
++ * been spilled yet by the _spill_register routine. Luckily, a3 contains a
++ * rotated windowstart with only those bits set for frames that haven't been
++ * spilled yet. Because a3 is rotated such that bit 0 represents the register
++ * frame for the current windowbase - 1, we need to rotate a3 left by the
++ * value of the current windowbase + 1 and move it to windowstart.
++ *
+ * a0: value of depc, original value in depc
+ * a2: trashed, original value in EXC_TABLE_DOUBLE_SAVE
+ * a3: exctable, original value in excsave1
+@@ -1131,10 +1138,15 @@ ENTRY(fast_syscall_spill_registers_fixup
+ /* We need to make sure the current registers (a0-a3) are preserved.
+ * To do this, we simply set the bit for the current window frame
+ * in WS, so that the exception handlers save them to the task stack.
++ *
++ * Note: we use a3 to set the windowbase, so we take a special care
++ * of it, saving it in the original _spill_registers frame across
++ * the exception handler call.
+ */
+
+ xsr a3, excsave1 # get spill-mask
+ slli a3, a3, 1 # shift left by one
++ addi a3, a3, 1 # set the bit for the current window frame
+
+ slli a2, a3, 32-WSBITS
+ src a2, a3, a2 # a2 = xxwww1yyxxxwww1yy......