]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 6 Nov 2015 17:41:08 +0000 (09:41 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 6 Nov 2015 17:41:08 +0000 (09:41 -0800)
added patches:
pinctrl-baytrail-serialize-all-register-access.patch
pinctrl-baytrail-use-raw_spinlock-for-locking.patch
serial-8250_pci-add-support-for-12-port-exar-boards.patch

queue-4.1/pinctrl-baytrail-serialize-all-register-access.patch [new file with mode: 0644]
queue-4.1/pinctrl-baytrail-use-raw_spinlock-for-locking.patch [new file with mode: 0644]
queue-4.1/serial-8250_pci-add-support-for-12-port-exar-boards.patch [new file with mode: 0644]
queue-4.1/series

diff --git a/queue-4.1/pinctrl-baytrail-serialize-all-register-access.patch b/queue-4.1/pinctrl-baytrail-serialize-all-register-access.patch
new file mode 100644 (file)
index 0000000..ee5d431
--- /dev/null
@@ -0,0 +1,87 @@
+From 39ce8150a079e3ae6ed9abf26d7918a558ef7c19 Mon Sep 17 00:00:00 2001
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+Date: Tue, 4 Aug 2015 15:03:14 +0300
+Subject: pinctrl: baytrail: Serialize all register access
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+commit 39ce8150a079e3ae6ed9abf26d7918a558ef7c19 upstream.
+
+There is a hardware issue in Intel Baytrail where concurrent GPIO register
+access might result reads of 0xffffffff and writes might get dropped
+completely.
+
+Prevent this from happening by taking the serializing lock in all places
+where it is possible that more than one thread might be accessing the
+hardware concurrently.
+
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Cc: Lucas De Marchi <lucas.de.marchi@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pinctrl/intel/pinctrl-baytrail.c |   21 ++++++++++++++++-----
+ 1 file changed, 16 insertions(+), 5 deletions(-)
+
+--- a/drivers/pinctrl/intel/pinctrl-baytrail.c
++++ b/drivers/pinctrl/intel/pinctrl-baytrail.c
+@@ -201,6 +201,9 @@ static int byt_gpio_request(struct gpio_
+       struct byt_gpio *vg = to_byt_gpio(chip);
+       void __iomem *reg = byt_gpio_reg(chip, offset, BYT_CONF0_REG);
+       u32 value, gpio_mux;
++      unsigned long flags;
++
++      spin_lock_irqsave(&vg->lock, flags);
+       /*
+        * In most cases, func pin mux 000 means GPIO function.
+@@ -214,18 +217,16 @@ static int byt_gpio_request(struct gpio_
+       value = readl(reg) & BYT_PIN_MUX;
+       gpio_mux = byt_get_gpio_mux(vg, offset);
+       if (WARN_ON(gpio_mux != value)) {
+-              unsigned long flags;
+-
+-              spin_lock_irqsave(&vg->lock, flags);
+               value = readl(reg) & ~BYT_PIN_MUX;
+               value |= gpio_mux;
+               writel(value, reg);
+-              spin_unlock_irqrestore(&vg->lock, flags);
+               dev_warn(&vg->pdev->dev,
+                        "pin %u forcibly re-configured as GPIO\n", offset);
+       }
++      spin_unlock_irqrestore(&vg->lock, flags);
++
+       pm_runtime_get(&vg->pdev->dev);
+       return 0;
+@@ -277,7 +278,15 @@ static int byt_irq_type(struct irq_data
+ static int byt_gpio_get(struct gpio_chip *chip, unsigned offset)
+ {
+       void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG);
+-      return readl(reg) & BYT_LEVEL;
++      struct byt_gpio *vg = to_byt_gpio(chip);
++      unsigned long flags;
++      u32 val;
++
++      spin_lock_irqsave(&vg->lock, flags);
++      val = readl(reg);
++      spin_unlock_irqrestore(&vg->lock, flags);
++
++      return val & BYT_LEVEL;
+ }
+ static void byt_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+@@ -450,8 +459,10 @@ static void byt_irq_ack(struct irq_data
+       unsigned offset = irqd_to_hwirq(d);
+       void __iomem *reg;
++      spin_lock(&vg->lock);
+       reg = byt_gpio_reg(&vg->chip, offset, BYT_INT_STAT_REG);
+       writel(BIT(offset % 32), reg);
++      spin_unlock(&vg->lock);
+ }
+ static void byt_irq_unmask(struct irq_data *d)
diff --git a/queue-4.1/pinctrl-baytrail-use-raw_spinlock-for-locking.patch b/queue-4.1/pinctrl-baytrail-use-raw_spinlock-for-locking.patch
new file mode 100644 (file)
index 0000000..2c989d6
--- /dev/null
@@ -0,0 +1,249 @@
+From 78e1c896932df5b8bcdff7bf5417d8e72a4d0d6b Mon Sep 17 00:00:00 2001
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+Date: Mon, 17 Aug 2015 16:03:17 +0300
+Subject: pinctrl: baytrail: Use raw_spinlock for locking
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+commit 78e1c896932df5b8bcdff7bf5417d8e72a4d0d6b upstream.
+
+The Intel Baytrail pinctrl driver implements irqchip callbacks which are
+called with desc->lock raw_spinlock held. In mainline this is fine because
+spinlock resolves to raw_spinlock. However, running the same code in -rt we
+get:
+
+ BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:917
+ in_atomic(): 1, irqs_disabled(): 1, pid: 0, name: swapper/0
+ Preemption disabled at:[<ffffffff81092e9f>] cpu_startup_entry+0x17f/0x480
+
+ CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.1.5-rt5 #13
+  ...
+ Call Trace:
+  <IRQ>  [<ffffffff816283c6>] dump_stack+0x4a/0x61
+  [<ffffffff81077e17>] ___might_sleep+0xe7/0x170
+  [<ffffffff8162d6cf>] rt_spin_lock+0x1f/0x50
+  [<ffffffff812e3b88>] byt_gpio_clear_triggering+0x38/0x60
+  [<ffffffff812e3bc1>] byt_irq_mask+0x11/0x20
+  [<ffffffff810a7013>] handle_level_irq+0x83/0x150
+  [<ffffffff810a3457>] generic_handle_irq+0x27/0x40
+  [<ffffffff812e3a5f>] byt_gpio_irq_handler+0x7f/0xc0
+  [<ffffffff810050aa>] handle_irq+0xaa/0x190
+  ...
+
+This is because in -rt spinlocks are preemptible so taking the driver
+private spinlock in irqchip callbacks causes might_sleep() to trigger.
+
+In order to keep -rt happy but at the same time make sure that register
+accesses get serialized, convert the driver to use raw_spinlock instead.
+
+Also shorten the critical section a bit in few places.
+
+Suggested-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Cc: Lucas De Marchi <lucas.de.marchi@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pinctrl/intel/pinctrl-baytrail.c |   50 +++++++++++++++----------------
+ 1 file changed, 25 insertions(+), 25 deletions(-)
+
+--- a/drivers/pinctrl/intel/pinctrl-baytrail.c
++++ b/drivers/pinctrl/intel/pinctrl-baytrail.c
+@@ -146,7 +146,7 @@ struct byt_gpio_pin_context {
+ struct byt_gpio {
+       struct gpio_chip                chip;
+       struct platform_device          *pdev;
+-      spinlock_t                      lock;
++      raw_spinlock_t                  lock;
+       void __iomem                    *reg_base;
+       struct pinctrl_gpio_range       *range;
+       struct byt_gpio_pin_context     *saved_context;
+@@ -174,11 +174,11 @@ static void byt_gpio_clear_triggering(st
+       unsigned long flags;
+       u32 value;
+-      spin_lock_irqsave(&vg->lock, flags);
++      raw_spin_lock_irqsave(&vg->lock, flags);
+       value = readl(reg);
+       value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
+       writel(value, reg);
+-      spin_unlock_irqrestore(&vg->lock, flags);
++      raw_spin_unlock_irqrestore(&vg->lock, flags);
+ }
+ static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned offset)
+@@ -203,7 +203,7 @@ static int byt_gpio_request(struct gpio_
+       u32 value, gpio_mux;
+       unsigned long flags;
+-      spin_lock_irqsave(&vg->lock, flags);
++      raw_spin_lock_irqsave(&vg->lock, flags);
+       /*
+        * In most cases, func pin mux 000 means GPIO function.
+@@ -225,7 +225,7 @@ static int byt_gpio_request(struct gpio_
+                        "pin %u forcibly re-configured as GPIO\n", offset);
+       }
+-      spin_unlock_irqrestore(&vg->lock, flags);
++      raw_spin_unlock_irqrestore(&vg->lock, flags);
+       pm_runtime_get(&vg->pdev->dev);
+@@ -251,7 +251,7 @@ static int byt_irq_type(struct irq_data
+       if (offset >= vg->chip.ngpio)
+               return -EINVAL;
+-      spin_lock_irqsave(&vg->lock, flags);
++      raw_spin_lock_irqsave(&vg->lock, flags);
+       value = readl(reg);
+       WARN(value & BYT_DIRECT_IRQ_EN,
+@@ -270,7 +270,7 @@ static int byt_irq_type(struct irq_data
+       else if (type & IRQ_TYPE_LEVEL_MASK)
+               __irq_set_handler_locked(d->irq, handle_level_irq);
+-      spin_unlock_irqrestore(&vg->lock, flags);
++      raw_spin_unlock_irqrestore(&vg->lock, flags);
+       return 0;
+ }
+@@ -282,9 +282,9 @@ static int byt_gpio_get(struct gpio_chip
+       unsigned long flags;
+       u32 val;
+-      spin_lock_irqsave(&vg->lock, flags);
++      raw_spin_lock_irqsave(&vg->lock, flags);
+       val = readl(reg);
+-      spin_unlock_irqrestore(&vg->lock, flags);
++      raw_spin_unlock_irqrestore(&vg->lock, flags);
+       return val & BYT_LEVEL;
+ }
+@@ -296,7 +296,7 @@ static void byt_gpio_set(struct gpio_chi
+       unsigned long flags;
+       u32 old_val;
+-      spin_lock_irqsave(&vg->lock, flags);
++      raw_spin_lock_irqsave(&vg->lock, flags);
+       old_val = readl(reg);
+@@ -305,7 +305,7 @@ static void byt_gpio_set(struct gpio_chi
+       else
+               writel(old_val & ~BYT_LEVEL, reg);
+-      spin_unlock_irqrestore(&vg->lock, flags);
++      raw_spin_unlock_irqrestore(&vg->lock, flags);
+ }
+ static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+@@ -315,13 +315,13 @@ static int byt_gpio_direction_input(stru
+       unsigned long flags;
+       u32 value;
+-      spin_lock_irqsave(&vg->lock, flags);
++      raw_spin_lock_irqsave(&vg->lock, flags);
+       value = readl(reg) | BYT_DIR_MASK;
+       value &= ~BYT_INPUT_EN;         /* active low */
+       writel(value, reg);
+-      spin_unlock_irqrestore(&vg->lock, flags);
++      raw_spin_unlock_irqrestore(&vg->lock, flags);
+       return 0;
+ }
+@@ -335,7 +335,7 @@ static int byt_gpio_direction_output(str
+       unsigned long flags;
+       u32 reg_val;
+-      spin_lock_irqsave(&vg->lock, flags);
++      raw_spin_lock_irqsave(&vg->lock, flags);
+       /*
+        * Before making any direction modifications, do a check if gpio
+@@ -354,7 +354,7 @@ static int byt_gpio_direction_output(str
+       else
+               writel(reg_val & ~BYT_LEVEL, reg);
+-      spin_unlock_irqrestore(&vg->lock, flags);
++      raw_spin_unlock_irqrestore(&vg->lock, flags);
+       return 0;
+ }
+@@ -363,18 +363,19 @@ static void byt_gpio_dbg_show(struct seq
+ {
+       struct byt_gpio *vg = to_byt_gpio(chip);
+       int i;
+-      unsigned long flags;
+       u32 conf0, val, offs;
+-      spin_lock_irqsave(&vg->lock, flags);
+-
+       for (i = 0; i < vg->chip.ngpio; i++) {
+               const char *pull_str = NULL;
+               const char *pull = NULL;
++              unsigned long flags;
+               const char *label;
+               offs = vg->range->pins[i] * 16;
++
++              raw_spin_lock_irqsave(&vg->lock, flags);
+               conf0 = readl(vg->reg_base + offs + BYT_CONF0_REG);
+               val = readl(vg->reg_base + offs + BYT_VAL_REG);
++              raw_spin_unlock_irqrestore(&vg->lock, flags);
+               label = gpiochip_is_requested(chip, i);
+               if (!label)
+@@ -427,7 +428,6 @@ static void byt_gpio_dbg_show(struct seq
+               seq_puts(s, "\n");
+       }
+-      spin_unlock_irqrestore(&vg->lock, flags);
+ }
+ static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
+@@ -459,10 +459,10 @@ static void byt_irq_ack(struct irq_data
+       unsigned offset = irqd_to_hwirq(d);
+       void __iomem *reg;
+-      spin_lock(&vg->lock);
++      raw_spin_lock(&vg->lock);
+       reg = byt_gpio_reg(&vg->chip, offset, BYT_INT_STAT_REG);
+       writel(BIT(offset % 32), reg);
+-      spin_unlock(&vg->lock);
++      raw_spin_unlock(&vg->lock);
+ }
+ static void byt_irq_unmask(struct irq_data *d)
+@@ -474,9 +474,9 @@ static void byt_irq_unmask(struct irq_da
+       void __iomem *reg;
+       u32 value;
+-      spin_lock_irqsave(&vg->lock, flags);
+-
+       reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG);
++
++      raw_spin_lock_irqsave(&vg->lock, flags);
+       value = readl(reg);
+       switch (irqd_get_trigger_type(d)) {
+@@ -497,7 +497,7 @@ static void byt_irq_unmask(struct irq_da
+       writel(value, reg);
+-      spin_unlock_irqrestore(&vg->lock, flags);
++      raw_spin_unlock_irqrestore(&vg->lock, flags);
+ }
+ static void byt_irq_mask(struct irq_data *d)
+@@ -589,7 +589,7 @@ static int byt_gpio_probe(struct platfor
+       if (IS_ERR(vg->reg_base))
+               return PTR_ERR(vg->reg_base);
+-      spin_lock_init(&vg->lock);
++      raw_spin_lock_init(&vg->lock);
+       gc = &vg->chip;
+       gc->label = dev_name(&pdev->dev);
diff --git a/queue-4.1/serial-8250_pci-add-support-for-12-port-exar-boards.patch b/queue-4.1/serial-8250_pci-add-support-for-12-port-exar-boards.patch
new file mode 100644 (file)
index 0000000..b869c78
--- /dev/null
@@ -0,0 +1,78 @@
+From be32c0cf0462c36f482b5ddcff1d8371be1e183c Mon Sep 17 00:00:00 2001
+From: Soeren Grunewald <soeren.grunewald@desy.de>
+Date: Thu, 11 Jun 2015 09:25:04 +0200
+Subject: serial: 8250_pci: Add support for 12 port Exar boards
+
+From: Soeren Grunewald <soeren.grunewald@desy.de>
+
+commit be32c0cf0462c36f482b5ddcff1d8371be1e183c upstream.
+
+The Exar XR17V358 can also be combined with a XR17V354 chip to act as a
+single 12 port chip. This works the same way as the combining two XR17V358
+chips. But the reported device id then is 0x4358.
+
+Signed-off-by: Soeren Grunewald <soeren.grunewald@desy.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/8250/8250_pci.c |   21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+--- a/drivers/tty/serial/8250/8250_pci.c
++++ b/drivers/tty/serial/8250/8250_pci.c
+@@ -1998,6 +1998,7 @@ pci_wch_ch38x_setup(struct serial_privat
+ #define PCIE_DEVICE_ID_WCH_CH382_2S1P 0x3250
+ #define PCIE_DEVICE_ID_WCH_CH384_4S   0x3470
++#define PCI_DEVICE_ID_EXAR_XR17V4358  0x4358
+ #define PCI_DEVICE_ID_EXAR_XR17V8358  0x8358
+ #define PCI_VENDOR_ID_PERICOM                 0x12D8
+@@ -2515,6 +2516,13 @@ static struct pci_serial_quirk pci_seria
+       },
+       {
+               .vendor = PCI_VENDOR_ID_EXAR,
++              .device = PCI_DEVICE_ID_EXAR_XR17V4358,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .setup          = pci_xr17v35x_setup,
++      },
++      {
++              .vendor = PCI_VENDOR_ID_EXAR,
+               .device = PCI_DEVICE_ID_EXAR_XR17V8358,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+@@ -2999,6 +3007,7 @@ enum pci_board_num_t {
+       pbn_exar_XR17V352,
+       pbn_exar_XR17V354,
+       pbn_exar_XR17V358,
++      pbn_exar_XR17V4358,
+       pbn_exar_XR17V8358,
+       pbn_exar_ibm_saturn,
+       pbn_pasemi_1682M,
+@@ -3690,6 +3699,14 @@ static struct pciserial_board pci_boards
+               .reg_shift      = 0,
+               .first_offset   = 0,
+       },
++      [pbn_exar_XR17V4358] = {
++              .flags          = FL_BASE0,
++              .num_ports      = 12,
++              .base_baud      = 7812500,
++              .uart_offset    = 0x400,
++              .reg_shift      = 0,
++              .first_offset   = 0,
++      },
+       [pbn_exar_XR17V8358] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 16,
+@@ -5133,6 +5150,10 @@ static struct pci_device_id serial_pci_t
+               PCI_ANY_ID, PCI_ANY_ID,
+               0,
+               0, pbn_exar_XR17V358 },
++      {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V4358,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0,
++              0, pbn_exar_XR17V4358 },
+       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V8358,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0,
index 3f09456a96fcb1b693b48895854cb524d8142b76..d2044255b0d2fe8cfafce86e829411902ded6da7 100644 (file)
@@ -79,3 +79,6 @@ arm64-compat-fix-stxr-failure-case-in-swp-emulation.patch
 nvme-fix-memory-leak-on-retried-commands.patch
 drm-vmwgfx-fix-up-user_dmabuf-refcounting.patch
 thp-use-is_zero_pfn-only-after-pte_present-check.patch
+pinctrl-baytrail-serialize-all-register-access.patch
+pinctrl-baytrail-use-raw_spinlock-for-locking.patch
+serial-8250_pci-add-support-for-12-port-exar-boards.patch