From b49f6ed62e2f0e30713dfa6592a11fa52bc52fee Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 6 Nov 2015 09:41:08 -0800 Subject: [PATCH] 4.1-stable patches 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 --- ...ytrail-serialize-all-register-access.patch | 87 ++++++ ...aytrail-use-raw_spinlock-for-locking.patch | 249 ++++++++++++++++++ ...-add-support-for-12-port-exar-boards.patch | 78 ++++++ queue-4.1/series | 3 + 4 files changed, 417 insertions(+) create mode 100644 queue-4.1/pinctrl-baytrail-serialize-all-register-access.patch create mode 100644 queue-4.1/pinctrl-baytrail-use-raw_spinlock-for-locking.patch create mode 100644 queue-4.1/serial-8250_pci-add-support-for-12-port-exar-boards.patch 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 index 00000000000..ee5d431514a --- /dev/null +++ b/queue-4.1/pinctrl-baytrail-serialize-all-register-access.patch @@ -0,0 +1,87 @@ +From 39ce8150a079e3ae6ed9abf26d7918a558ef7c19 Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Tue, 4 Aug 2015 15:03:14 +0300 +Subject: pinctrl: baytrail: Serialize all register access + +From: Mika Westerberg + +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 +Signed-off-by: Linus Walleij +Cc: Lucas De Marchi +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..2c989d6f084 --- /dev/null +++ b/queue-4.1/pinctrl-baytrail-use-raw_spinlock-for-locking.patch @@ -0,0 +1,249 @@ +From 78e1c896932df5b8bcdff7bf5417d8e72a4d0d6b Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Mon, 17 Aug 2015 16:03:17 +0300 +Subject: pinctrl: baytrail: Use raw_spinlock for locking + +From: Mika Westerberg + +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:[] cpu_startup_entry+0x17f/0x480 + + CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.1.5-rt5 #13 + ... + Call Trace: + [] dump_stack+0x4a/0x61 + [] ___might_sleep+0xe7/0x170 + [] rt_spin_lock+0x1f/0x50 + [] byt_gpio_clear_triggering+0x38/0x60 + [] byt_irq_mask+0x11/0x20 + [] handle_level_irq+0x83/0x150 + [] generic_handle_irq+0x27/0x40 + [] byt_gpio_irq_handler+0x7f/0xc0 + [] 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 +Signed-off-by: Mika Westerberg +Signed-off-by: Linus Walleij +Cc: Lucas De Marchi +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..b869c7837bd --- /dev/null +++ b/queue-4.1/serial-8250_pci-add-support-for-12-port-exar-boards.patch @@ -0,0 +1,78 @@ +From be32c0cf0462c36f482b5ddcff1d8371be1e183c Mon Sep 17 00:00:00 2001 +From: Soeren Grunewald +Date: Thu, 11 Jun 2015 09:25:04 +0200 +Subject: serial: 8250_pci: Add support for 12 port Exar boards + +From: Soeren Grunewald + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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, diff --git a/queue-4.1/series b/queue-4.1/series index 3f09456a96f..d2044255b0d 100644 --- a/queue-4.1/series +++ b/queue-4.1/series @@ -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 -- 2.47.2