diff options
Diffstat (limited to '4.8.7/1005_linux-4.8.6.patch')
-rw-r--r-- | 4.8.7/1005_linux-4.8.6.patch | 5137 |
1 files changed, 5137 insertions, 0 deletions
diff --git a/4.8.7/1005_linux-4.8.6.patch b/4.8.7/1005_linux-4.8.6.patch new file mode 100644 index 0000000..641ba27 --- /dev/null +++ b/4.8.7/1005_linux-4.8.6.patch @@ -0,0 +1,5137 @@ +diff --git a/Makefile b/Makefile +index daa3a01..b249529 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 8 +-SUBLEVEL = 5 ++SUBLEVEL = 6 + EXTRAVERSION = + NAME = Psychotic Stoned Sheep + +diff --git a/arch/arm/boot/dts/arm-realview-eb.dtsi b/arch/arm/boot/dts/arm-realview-eb.dtsi +index 1c6a040..e2e9599 100644 +--- a/arch/arm/boot/dts/arm-realview-eb.dtsi ++++ b/arch/arm/boot/dts/arm-realview-eb.dtsi +@@ -51,14 +51,6 @@ + regulator-boot-on; + }; + +- veth: fixedregulator@0 { +- compatible = "regulator-fixed"; +- regulator-name = "veth"; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; +- regulator-boot-on; +- }; +- + xtal24mhz: xtal24mhz@24M { + #clock-cells = <0>; + compatible = "fixed-clock"; +@@ -134,16 +126,15 @@ + bank-width = <4>; + }; + +- /* SMSC 9118 ethernet with PHY and EEPROM */ ++ /* SMSC LAN91C111 ethernet with PHY and EEPROM */ + ethernet: ethernet@4e000000 { +- compatible = "smsc,lan9118", "smsc,lan9115"; ++ compatible = "smsc,lan91c111"; + reg = <0x4e000000 0x10000>; +- phy-mode = "mii"; +- reg-io-width = <4>; +- smsc,irq-active-high; +- smsc,irq-push-pull; +- vdd33a-supply = <&veth>; +- vddvario-supply = <&veth>; ++ /* ++ * This means the adapter can be accessed with 8, 16 or ++ * 32 bit reads/writes. ++ */ ++ reg-io-width = <7>; + }; + + usb: usb@4f000000 { +diff --git a/arch/arm/boot/dts/bcm958625hr.dts b/arch/arm/boot/dts/bcm958625hr.dts +index 03b8bbe..652418a 100644 +--- a/arch/arm/boot/dts/bcm958625hr.dts ++++ b/arch/arm/boot/dts/bcm958625hr.dts +@@ -47,7 +47,8 @@ + }; + + memory { +- reg = <0x60000000 0x20000000>; ++ device_type = "memory"; ++ reg = <0x60000000 0x80000000>; + }; + }; + +diff --git a/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi b/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi +index ca86da6..854117d 100644 +--- a/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi ++++ b/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi +@@ -119,7 +119,7 @@ + pinctrl-names = "default"; + pinctrl-0 = <&mcspi1_pins>; + +- lcd0: display { ++ lcd0: display@1 { + compatible = "lgphilips,lb035q02"; + label = "lcd35"; + +diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi +index f68b324..3f528a3 100644 +--- a/arch/arm/boot/dts/sun9i-a80.dtsi ++++ b/arch/arm/boot/dts/sun9i-a80.dtsi +@@ -899,8 +899,7 @@ + resets = <&apbs_rst 0>; + gpio-controller; + interrupt-controller; +- #address-cells = <1>; +- #size-cells = <0>; ++ #interrupt-cells = <3>; + #gpio-cells = <3>; + + r_ir_pins: r_ir { +diff --git a/arch/arm/crypto/ghash-ce-glue.c b/arch/arm/crypto/ghash-ce-glue.c +index 1568cb5..b88364a 100644 +--- a/arch/arm/crypto/ghash-ce-glue.c ++++ b/arch/arm/crypto/ghash-ce-glue.c +@@ -220,6 +220,27 @@ static int ghash_async_digest(struct ahash_request *req) + } + } + ++static int ghash_async_import(struct ahash_request *req, const void *in) ++{ ++ struct ahash_request *cryptd_req = ahash_request_ctx(req); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); ++ struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm); ++ struct shash_desc *desc = cryptd_shash_desc(cryptd_req); ++ ++ desc->tfm = cryptd_ahash_child(ctx->cryptd_tfm); ++ desc->flags = req->base.flags; ++ ++ return crypto_shash_import(desc, in); ++} ++ ++static int ghash_async_export(struct ahash_request *req, void *out) ++{ ++ struct ahash_request *cryptd_req = ahash_request_ctx(req); ++ struct shash_desc *desc = cryptd_shash_desc(cryptd_req); ++ ++ return crypto_shash_export(desc, out); ++} ++ + static int ghash_async_setkey(struct crypto_ahash *tfm, const u8 *key, + unsigned int keylen) + { +@@ -268,7 +289,10 @@ static struct ahash_alg ghash_async_alg = { + .final = ghash_async_final, + .setkey = ghash_async_setkey, + .digest = ghash_async_digest, ++ .import = ghash_async_import, ++ .export = ghash_async_export, + .halg.digestsize = GHASH_DIGEST_SIZE, ++ .halg.statesize = sizeof(struct ghash_desc_ctx), + .halg.base = { + .cra_name = "ghash", + .cra_driver_name = "ghash-ce", +diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c +index d920681..c71c483 100644 +--- a/arch/arm/mach-pxa/corgi_pm.c ++++ b/arch/arm/mach-pxa/corgi_pm.c +@@ -131,16 +131,11 @@ static int corgi_should_wakeup(unsigned int resume_on_alarm) + return is_resume; + } + +-static unsigned long corgi_charger_wakeup(void) ++static bool corgi_charger_wakeup(void) + { +- unsigned long ret; +- +- ret = (!gpio_get_value(CORGI_GPIO_AC_IN) << GPIO_bit(CORGI_GPIO_AC_IN)) +- | (!gpio_get_value(CORGI_GPIO_KEY_INT) +- << GPIO_bit(CORGI_GPIO_KEY_INT)) +- | (!gpio_get_value(CORGI_GPIO_WAKEUP) +- << GPIO_bit(CORGI_GPIO_WAKEUP)); +- return ret; ++ return !gpio_get_value(CORGI_GPIO_AC_IN) || ++ !gpio_get_value(CORGI_GPIO_KEY_INT) || ++ !gpio_get_value(CORGI_GPIO_WAKEUP); + } + + unsigned long corgipm_read_devdata(int type) +diff --git a/arch/arm/mach-pxa/pxa_cplds_irqs.c b/arch/arm/mach-pxa/pxa_cplds_irqs.c +index 2385052..e362f86 100644 +--- a/arch/arm/mach-pxa/pxa_cplds_irqs.c ++++ b/arch/arm/mach-pxa/pxa_cplds_irqs.c +@@ -41,30 +41,35 @@ static irqreturn_t cplds_irq_handler(int in_irq, void *d) + unsigned long pending; + unsigned int bit; + +- pending = readl(fpga->base + FPGA_IRQ_SET_CLR) & fpga->irq_mask; +- for_each_set_bit(bit, &pending, CPLDS_NB_IRQ) +- generic_handle_irq(irq_find_mapping(fpga->irqdomain, bit)); ++ do { ++ pending = readl(fpga->base + FPGA_IRQ_SET_CLR) & fpga->irq_mask; ++ for_each_set_bit(bit, &pending, CPLDS_NB_IRQ) { ++ generic_handle_irq(irq_find_mapping(fpga->irqdomain, ++ bit)); ++ } ++ } while (pending); + + return IRQ_HANDLED; + } + +-static void cplds_irq_mask_ack(struct irq_data *d) ++static void cplds_irq_mask(struct irq_data *d) + { + struct cplds *fpga = irq_data_get_irq_chip_data(d); + unsigned int cplds_irq = irqd_to_hwirq(d); +- unsigned int set, bit = BIT(cplds_irq); ++ unsigned int bit = BIT(cplds_irq); + + fpga->irq_mask &= ~bit; + writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN); +- set = readl(fpga->base + FPGA_IRQ_SET_CLR); +- writel(set & ~bit, fpga->base + FPGA_IRQ_SET_CLR); + } + + static void cplds_irq_unmask(struct irq_data *d) + { + struct cplds *fpga = irq_data_get_irq_chip_data(d); + unsigned int cplds_irq = irqd_to_hwirq(d); +- unsigned int bit = BIT(cplds_irq); ++ unsigned int set, bit = BIT(cplds_irq); ++ ++ set = readl(fpga->base + FPGA_IRQ_SET_CLR); ++ writel(set & ~bit, fpga->base + FPGA_IRQ_SET_CLR); + + fpga->irq_mask |= bit; + writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN); +@@ -72,7 +77,8 @@ static void cplds_irq_unmask(struct irq_data *d) + + static struct irq_chip cplds_irq_chip = { + .name = "pxa_cplds", +- .irq_mask_ack = cplds_irq_mask_ack, ++ .irq_ack = cplds_irq_mask, ++ .irq_mask = cplds_irq_mask, + .irq_unmask = cplds_irq_unmask, + .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE, + }; +diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c +index b80eab9..249b7bd 100644 +--- a/arch/arm/mach-pxa/sharpsl_pm.c ++++ b/arch/arm/mach-pxa/sharpsl_pm.c +@@ -744,7 +744,7 @@ static int sharpsl_off_charge_battery(void) + time = RCNR; + while (1) { + /* Check if any wakeup event had occurred */ +- if (sharpsl_pm.machinfo->charger_wakeup() != 0) ++ if (sharpsl_pm.machinfo->charger_wakeup()) + return 0; + /* Check for timeout */ + if ((RCNR - time) > SHARPSL_WAIT_CO_TIME) +diff --git a/arch/arm/mach-pxa/sharpsl_pm.h b/arch/arm/mach-pxa/sharpsl_pm.h +index 905be67..fa75b6d 100644 +--- a/arch/arm/mach-pxa/sharpsl_pm.h ++++ b/arch/arm/mach-pxa/sharpsl_pm.h +@@ -34,7 +34,7 @@ struct sharpsl_charger_machinfo { + #define SHARPSL_STATUS_LOCK 5 + #define SHARPSL_STATUS_CHRGFULL 6 + #define SHARPSL_STATUS_FATAL 7 +- unsigned long (*charger_wakeup)(void); ++ bool (*charger_wakeup)(void); + int (*should_wakeup)(unsigned int resume_on_alarm); + void (*backlight_limit)(int); + int (*backlight_get_status) (void); +diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c +index ea9f903..4e64a14 100644 +--- a/arch/arm/mach-pxa/spitz_pm.c ++++ b/arch/arm/mach-pxa/spitz_pm.c +@@ -165,13 +165,10 @@ static int spitz_should_wakeup(unsigned int resume_on_alarm) + return is_resume; + } + +-static unsigned long spitz_charger_wakeup(void) ++static bool spitz_charger_wakeup(void) + { +- unsigned long ret; +- ret = ((!gpio_get_value(SPITZ_GPIO_KEY_INT) +- << GPIO_bit(SPITZ_GPIO_KEY_INT)) +- | gpio_get_value(SPITZ_GPIO_SYNC)); +- return ret; ++ return !gpio_get_value(SPITZ_GPIO_KEY_INT) || ++ gpio_get_value(SPITZ_GPIO_SYNC); + } + + unsigned long spitzpm_read_devdata(int type) +diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h +index 263bf39..9bd84ba 100644 +--- a/arch/powerpc/include/asm/book3s/64/pgtable.h ++++ b/arch/powerpc/include/asm/book3s/64/pgtable.h +@@ -6,6 +6,8 @@ + */ + #define _PAGE_BIT_SWAP_TYPE 0 + ++#define _PAGE_RO 0 ++ + #define _PAGE_EXEC 0x00001 /* execute permission */ + #define _PAGE_WRITE 0x00002 /* write access allowed */ + #define _PAGE_READ 0x00004 /* read access allowed */ +diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c +index 64174bf..05a0a91 100644 +--- a/arch/powerpc/kernel/nvram_64.c ++++ b/arch/powerpc/kernel/nvram_64.c +@@ -956,7 +956,7 @@ int __init nvram_remove_partition(const char *name, int sig, + + /* Make partition a free partition */ + part->header.signature = NVRAM_SIG_FREE; +- strncpy(part->header.name, "wwwwwwwwwwww", 12); ++ memset(part->header.name, 'w', 12); + part->header.checksum = nvram_checksum(&part->header); + rc = nvram_write_header(part); + if (rc <= 0) { +@@ -974,8 +974,8 @@ int __init nvram_remove_partition(const char *name, int sig, + } + if (prev) { + prev->header.length += part->header.length; +- prev->header.checksum = nvram_checksum(&part->header); +- rc = nvram_write_header(part); ++ prev->header.checksum = nvram_checksum(&prev->header); ++ rc = nvram_write_header(prev); + if (rc <= 0) { + printk(KERN_ERR "nvram_remove_partition: nvram_write failed (%d)\n", rc); + return rc; +diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c +index 9ee2623..ad37aa1 100644 +--- a/arch/powerpc/kernel/process.c ++++ b/arch/powerpc/kernel/process.c +@@ -88,7 +88,13 @@ static void check_if_tm_restore_required(struct task_struct *tsk) + set_thread_flag(TIF_RESTORE_TM); + } + } ++ ++static inline bool msr_tm_active(unsigned long msr) ++{ ++ return MSR_TM_ACTIVE(msr); ++} + #else ++static inline bool msr_tm_active(unsigned long msr) { return false; } + static inline void check_if_tm_restore_required(struct task_struct *tsk) { } + #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ + +@@ -208,7 +214,7 @@ void enable_kernel_fp(void) + EXPORT_SYMBOL(enable_kernel_fp); + + static int restore_fp(struct task_struct *tsk) { +- if (tsk->thread.load_fp) { ++ if (tsk->thread.load_fp || msr_tm_active(tsk->thread.regs->msr)) { + load_fp_state(¤t->thread.fp_state); + current->thread.load_fp++; + return 1; +@@ -278,7 +284,8 @@ EXPORT_SYMBOL_GPL(flush_altivec_to_thread); + + static int restore_altivec(struct task_struct *tsk) + { +- if (cpu_has_feature(CPU_FTR_ALTIVEC) && tsk->thread.load_vec) { ++ if (cpu_has_feature(CPU_FTR_ALTIVEC) && ++ (tsk->thread.load_vec || msr_tm_active(tsk->thread.regs->msr))) { + load_vr_state(&tsk->thread.vr_state); + tsk->thread.used_vr = 1; + tsk->thread.load_vec++; +@@ -438,6 +445,7 @@ void giveup_all(struct task_struct *tsk) + return; + + msr_check_and_set(msr_all_available); ++ check_if_tm_restore_required(tsk); + + #ifdef CONFIG_PPC_FPU + if (usermsr & MSR_FP) +@@ -464,7 +472,8 @@ void restore_math(struct pt_regs *regs) + { + unsigned long msr; + +- if (!current->thread.load_fp && !loadvec(current->thread)) ++ if (!msr_tm_active(regs->msr) && ++ !current->thread.load_fp && !loadvec(current->thread)) + return; + + msr = regs->msr; +@@ -983,6 +992,13 @@ void restore_tm_state(struct pt_regs *regs) + msr_diff = current->thread.ckpt_regs.msr & ~regs->msr; + msr_diff &= MSR_FP | MSR_VEC | MSR_VSX; + ++ /* Ensure that restore_math() will restore */ ++ if (msr_diff & MSR_FP) ++ current->thread.load_fp = 1; ++#ifdef CONFIG_ALIVEC ++ if (cpu_has_feature(CPU_FTR_ALTIVEC) && msr_diff & MSR_VEC) ++ current->thread.load_vec = 1; ++#endif + restore_math(regs); + + regs->msr |= msr_diff; +diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c +index 7372ee1..a5d3ecd 100644 +--- a/arch/powerpc/mm/hugetlbpage.c ++++ b/arch/powerpc/mm/hugetlbpage.c +@@ -1019,8 +1019,15 @@ int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, + + pte = READ_ONCE(*ptep); + mask = _PAGE_PRESENT | _PAGE_READ; ++ ++ /* ++ * On some CPUs like the 8xx, _PAGE_RW hence _PAGE_WRITE is defined ++ * as 0 and _PAGE_RO has to be set when a page is not writable ++ */ + if (write) + mask |= _PAGE_WRITE; ++ else ++ mask |= _PAGE_RO; + + if ((pte_val(pte) & mask) != mask) + return 0; +diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c +index de7501e..8b8852b 100644 +--- a/arch/x86/kernel/early-quirks.c ++++ b/arch/x86/kernel/early-quirks.c +@@ -317,16 +317,11 @@ static phys_addr_t __init i85x_stolen_base(int num, int slot, int func, + static phys_addr_t __init i865_stolen_base(int num, int slot, int func, + size_t stolen_size) + { +- u16 toud; ++ u16 toud = 0; + +- /* +- * FIXME is the graphics stolen memory region +- * always at TOUD? Ie. is it always the last +- * one to be allocated by the BIOS? +- */ + toud = read_pci_config_16(0, 0, 0, I865_TOUD); + +- return (phys_addr_t)toud << 16; ++ return (phys_addr_t)(toud << 16) + i845_tseg_size(); + } + + static phys_addr_t __init gen3_stolen_base(int num, int slot, int func, +diff --git a/crypto/gcm.c b/crypto/gcm.c +index 70a892e8..f624ac9 100644 +--- a/crypto/gcm.c ++++ b/crypto/gcm.c +@@ -117,7 +117,7 @@ static int crypto_gcm_setkey(struct crypto_aead *aead, const u8 *key, + struct crypto_skcipher *ctr = ctx->ctr; + struct { + be128 hash; +- u8 iv[8]; ++ u8 iv[16]; + + struct crypto_gcm_setkey_result result; + +diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c +index 01d4be2..f5c26a5 100644 +--- a/drivers/char/hw_random/omap-rng.c ++++ b/drivers/char/hw_random/omap-rng.c +@@ -385,7 +385,7 @@ static int omap_rng_probe(struct platform_device *pdev) + + pm_runtime_enable(&pdev->dev); + ret = pm_runtime_get_sync(&pdev->dev); +- if (ret) { ++ if (ret < 0) { + dev_err(&pdev->dev, "Failed to runtime_get device: %d\n", ret); + pm_runtime_put_noidle(&pdev->dev); + goto err_ioremap; +@@ -443,7 +443,7 @@ static int __maybe_unused omap_rng_resume(struct device *dev) + int ret; + + ret = pm_runtime_get_sync(dev); +- if (ret) { ++ if (ret < 0) { + dev_err(dev, "Failed to runtime_get device: %d\n", ret); + pm_runtime_put_noidle(dev); + return ret; +diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c +index 7a79708..0fc71cb 100644 +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -1006,16 +1006,28 @@ static int bcm2835_clock_set_rate(struct clk_hw *hw, + return 0; + } + ++static bool ++bcm2835_clk_is_pllc(struct clk_hw *hw) ++{ ++ if (!hw) ++ return false; ++ ++ return strncmp(clk_hw_get_name(hw), "pllc", 4) == 0; ++} ++ + static int bcm2835_clock_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) + { + struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); + struct clk_hw *parent, *best_parent = NULL; ++ bool current_parent_is_pllc; + unsigned long rate, best_rate = 0; + unsigned long prate, best_prate = 0; + size_t i; + u32 div; + ++ current_parent_is_pllc = bcm2835_clk_is_pllc(clk_hw_get_parent(hw)); ++ + /* + * Select parent clock that results in the closest but lower rate + */ +@@ -1023,6 +1035,17 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw, + parent = clk_hw_get_parent_by_index(hw, i); + if (!parent) + continue; ++ ++ /* ++ * Don't choose a PLLC-derived clock as our parent ++ * unless it had been manually set that way. PLLC's ++ * frequency gets adjusted by the firmware due to ++ * over-temp or under-voltage conditions, without ++ * prior notification to our clock consumer. ++ */ ++ if (bcm2835_clk_is_pllc(parent) && !current_parent_is_pllc) ++ continue; ++ + prate = clk_hw_get_rate(parent); + div = bcm2835_clock_choose_div(hw, req->rate, prate, true); + rate = bcm2835_clock_rate_from_divisor(clock, prate, div); +diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c +index a0f55bc..96386ff 100644 +--- a/drivers/clk/clk-divider.c ++++ b/drivers/clk/clk-divider.c +@@ -352,7 +352,7 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, + + /* if read only, just return current value */ + if (divider->flags & CLK_DIVIDER_READ_ONLY) { +- bestdiv = readl(divider->reg) >> divider->shift; ++ bestdiv = clk_readl(divider->reg) >> divider->shift; + bestdiv &= div_mask(divider->width); + bestdiv = _get_div(divider->table, bestdiv, divider->flags, + divider->width); +diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c +index 58566a17..20b1055 100644 +--- a/drivers/clk/clk-qoriq.c ++++ b/drivers/clk/clk-qoriq.c +@@ -766,7 +766,11 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx) + if (!hwc) + return NULL; + +- hwc->reg = cg->regs + 0x20 * idx; ++ if (cg->info.flags & CG_VER3) ++ hwc->reg = cg->regs + 0x70000 + 0x20 * idx; ++ else ++ hwc->reg = cg->regs + 0x20 * idx; ++ + hwc->info = cg->info.cmux_groups[cg->info.cmux_to_group[idx]]; + + /* +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +index 820a939..2877a4d 100644 +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -1908,10 +1908,6 @@ int clk_set_phase(struct clk *clk, int degrees) + + clk_prepare_lock(); + +- /* bail early if nothing to do */ +- if (degrees == clk->core->phase) +- goto out; +- + trace_clk_set_phase(clk->core, degrees); + + if (clk->core->ops->set_phase) +@@ -1922,7 +1918,6 @@ int clk_set_phase(struct clk *clk, int degrees) + if (!ret) + clk->core->phase = degrees; + +-out: + clk_prepare_unlock(); + + return ret; +@@ -3186,7 +3181,7 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, + { + struct of_clk_provider *provider; + struct clk *clk = ERR_PTR(-EPROBE_DEFER); +- struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER); ++ struct clk_hw *hw; + + if (!clkspec) + return ERR_PTR(-EINVAL); +@@ -3194,12 +3189,13 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, + /* Check if we have such a provider in our array */ + mutex_lock(&of_clk_mutex); + list_for_each_entry(provider, &of_clk_providers, link) { +- if (provider->node == clkspec->np) ++ if (provider->node == clkspec->np) { + hw = __of_clk_get_hw_from_provider(provider, clkspec); +- if (!IS_ERR(hw)) { + clk = __clk_create_clk(hw, dev_id, con_id); ++ } + +- if (!IS_ERR(clk) && !__clk_get(clk)) { ++ if (!IS_ERR(clk)) { ++ if (!__clk_get(clk)) { + __clk_free_clk(clk); + clk = ERR_PTR(-ENOENT); + } +diff --git a/drivers/clk/imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c +index b0978d3..d302ed3 100644 +--- a/drivers/clk/imx/clk-imx35.c ++++ b/drivers/clk/imx/clk-imx35.c +@@ -115,7 +115,7 @@ static void __init _mx35_clocks_init(void) + } + + clk[ckih] = imx_clk_fixed("ckih", 24000000); +- clk[ckil] = imx_clk_fixed("ckih", 32768); ++ clk[ckil] = imx_clk_fixed("ckil", 32768); + clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX35, "mpll", "ckih", base + MX35_CCM_MPCTL); + clk[ppll] = imx_clk_pllv1(IMX_PLLV1_IMX35, "ppll", "ckih", base + MX35_CCM_PPCTL); + +diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig +index 95e3b3e..98909b1 100644 +--- a/drivers/clk/qcom/Kconfig ++++ b/drivers/clk/qcom/Kconfig +@@ -117,6 +117,7 @@ config MSM_MMCC_8974 + + config MSM_GCC_8996 + tristate "MSM8996 Global Clock Controller" ++ select QCOM_GDSC + depends on COMMON_CLK_QCOM + help + Support for the global clock controller on msm8996 devices. +@@ -126,6 +127,7 @@ config MSM_GCC_8996 + config MSM_MMCC_8996 + tristate "MSM8996 Multimedia Clock Controller" + select MSM_GCC_8996 ++ select QCOM_GDSC + depends on COMMON_CLK_QCOM + help + Support for the multimedia clock controller on msm8996 devices. +diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c +index bbf732b..9f643cc 100644 +--- a/drivers/clk/qcom/gcc-msm8996.c ++++ b/drivers/clk/qcom/gcc-msm8996.c +@@ -2592,9 +2592,9 @@ static struct clk_branch gcc_pcie_2_aux_clk = { + }; + + static struct clk_branch gcc_pcie_2_pipe_clk = { +- .halt_reg = 0x6e108, ++ .halt_reg = 0x6e018, + .clkr = { +- .enable_reg = 0x6e108, ++ .enable_reg = 0x6e018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_2_pipe_clk", +diff --git a/drivers/crypto/ccp/ccp-dmaengine.c b/drivers/crypto/ccp/ccp-dmaengine.c +index 94f77b0..32f645e 100644 +--- a/drivers/crypto/ccp/ccp-dmaengine.c ++++ b/drivers/crypto/ccp/ccp-dmaengine.c +@@ -650,7 +650,7 @@ int ccp_dmaengine_register(struct ccp_device *ccp) + dma_desc_cache_name = devm_kasprintf(ccp->dev, GFP_KERNEL, + "%s-dmaengine-desc-cache", + ccp->name); +- if (!dma_cmd_cache_name) ++ if (!dma_desc_cache_name) + return -ENOMEM; + ccp->dma_desc_cache = kmem_cache_create(dma_desc_cache_name, + sizeof(struct ccp_dma_desc), +diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c +index d64af86..37dadb2 100644 +--- a/drivers/crypto/marvell/cesa.c ++++ b/drivers/crypto/marvell/cesa.c +@@ -166,6 +166,7 @@ static irqreturn_t mv_cesa_int(int irq, void *priv) + if (!req) + break; + ++ ctx = crypto_tfm_ctx(req->tfm); + mv_cesa_complete_req(ctx, req, 0); + } + } +diff --git a/drivers/crypto/marvell/hash.c b/drivers/crypto/marvell/hash.c +index 82e0f4e6..b111e14 100644 +--- a/drivers/crypto/marvell/hash.c ++++ b/drivers/crypto/marvell/hash.c +@@ -805,13 +805,14 @@ static int mv_cesa_md5_init(struct ahash_request *req) + struct mv_cesa_op_ctx tmpl = { }; + + mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_MD5); ++ ++ mv_cesa_ahash_init(req, &tmpl, true); ++ + creq->state[0] = MD5_H0; + creq->state[1] = MD5_H1; + creq->state[2] = MD5_H2; + creq->state[3] = MD5_H3; + +- mv_cesa_ahash_init(req, &tmpl, true); +- + return 0; + } + +@@ -873,14 +874,15 @@ static int mv_cesa_sha1_init(struct ahash_request *req) + struct mv_cesa_op_ctx tmpl = { }; + + mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_SHA1); ++ ++ mv_cesa_ahash_init(req, &tmpl, false); ++ + creq->state[0] = SHA1_H0; + creq->state[1] = SHA1_H1; + creq->state[2] = SHA1_H2; + creq->state[3] = SHA1_H3; + creq->state[4] = SHA1_H4; + +- mv_cesa_ahash_init(req, &tmpl, false); +- + return 0; + } + +@@ -942,6 +944,9 @@ static int mv_cesa_sha256_init(struct ahash_request *req) + struct mv_cesa_op_ctx tmpl = { }; + + mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_SHA256); ++ ++ mv_cesa_ahash_init(req, &tmpl, false); ++ + creq->state[0] = SHA256_H0; + creq->state[1] = SHA256_H1; + creq->state[2] = SHA256_H2; +@@ -951,8 +956,6 @@ static int mv_cesa_sha256_init(struct ahash_request *req) + creq->state[6] = SHA256_H6; + creq->state[7] = SHA256_H7; + +- mv_cesa_ahash_init(req, &tmpl, false); +- + return 0; + } + +diff --git a/drivers/dma/ipu/ipu_irq.c b/drivers/dma/ipu/ipu_irq.c +index 2bf37e6..dd184b5 100644 +--- a/drivers/dma/ipu/ipu_irq.c ++++ b/drivers/dma/ipu/ipu_irq.c +@@ -286,22 +286,21 @@ static void ipu_irq_handler(struct irq_desc *desc) + raw_spin_unlock(&bank_lock); + while ((line = ffs(status))) { + struct ipu_irq_map *map; +- unsigned int irq = NO_IRQ; ++ unsigned int irq; + + line--; + status &= ~(1UL << line); + + raw_spin_lock(&bank_lock); + map = src2map(32 * i + line); +- if (map) +- irq = map->irq; +- raw_spin_unlock(&bank_lock); +- + if (!map) { ++ raw_spin_unlock(&bank_lock); + pr_err("IPU: Interrupt on unmapped source %u bank %d\n", + line, i); + continue; + } ++ irq = map->irq; ++ raw_spin_unlock(&bank_lock); + generic_handle_irq(irq); + } + } +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +index 17e1362..4e71a68 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +@@ -43,6 +43,9 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev, struct amdgpu_ctx *ctx) + ctx->rings[i].sequence = 1; + ctx->rings[i].fences = &ctx->fences[amdgpu_sched_jobs * i]; + } ++ ++ ctx->reset_counter = atomic_read(&adev->gpu_reset_counter); ++ + /* create context entity for each ring */ + for (i = 0; i < adev->num_rings; i++) { + struct amdgpu_ring *ring = adev->rings[i]; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c +index fe36caf..14f57d9 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c +@@ -113,24 +113,26 @@ void amdgpu_dpm_print_ps_status(struct amdgpu_device *adev, + printk("\n"); + } + ++ + u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev) + { + struct drm_device *dev = adev->ddev; + struct drm_crtc *crtc; + struct amdgpu_crtc *amdgpu_crtc; +- u32 line_time_us, vblank_lines; ++ u32 vblank_in_pixels; + u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */ + + if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) { + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + amdgpu_crtc = to_amdgpu_crtc(crtc); + if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) { +- line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) / +- amdgpu_crtc->hw_mode.clock; +- vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end - ++ vblank_in_pixels = ++ amdgpu_crtc->hw_mode.crtc_htotal * ++ (amdgpu_crtc->hw_mode.crtc_vblank_end - + amdgpu_crtc->hw_mode.crtc_vdisplay + +- (amdgpu_crtc->v_border * 2); +- vblank_time_us = vblank_lines * line_time_us; ++ (amdgpu_crtc->v_border * 2)); ++ ++ vblank_time_us = vblank_in_pixels * 1000 / amdgpu_crtc->hw_mode.clock; + break; + } + } +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +index d942654..e24a8af 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +@@ -292,7 +292,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file + type = AMD_IP_BLOCK_TYPE_UVD; + ring_mask = adev->uvd.ring.ready ? 1 : 0; + ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; +- ib_size_alignment = 8; ++ ib_size_alignment = 16; + break; + case AMDGPU_HW_IP_VCE: + type = AMD_IP_BLOCK_TYPE_VCE; +diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +index c1b04e9..172bed9 100644 +--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +@@ -425,16 +425,6 @@ static void dce_v10_0_hpd_init(struct amdgpu_device *adev) + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); + +- if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || +- connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { +- /* don't try to enable hpd on eDP or LVDS avoid breaking the +- * aux dp channel on imac and help (but not completely fix) +- * https://bugzilla.redhat.com/show_bug.cgi?id=726143 +- * also avoid interrupt storms during dpms. +- */ +- continue; +- } +- + switch (amdgpu_connector->hpd.hpd) { + case AMDGPU_HPD_1: + idx = 0; +@@ -458,6 +448,19 @@ static void dce_v10_0_hpd_init(struct amdgpu_device *adev) + continue; + } + ++ if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || ++ connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { ++ /* don't try to enable hpd on eDP or LVDS avoid breaking the ++ * aux dp channel on imac and help (but not completely fix) ++ * https://bugzilla.redhat.com/show_bug.cgi?id=726143 ++ * also avoid interrupt storms during dpms. ++ */ ++ tmp = RREG32(mmDC_HPD_INT_CONTROL + hpd_offsets[idx]); ++ tmp = REG_SET_FIELD(tmp, DC_HPD_INT_CONTROL, DC_HPD_INT_EN, 0); ++ WREG32(mmDC_HPD_INT_CONTROL + hpd_offsets[idx], tmp); ++ continue; ++ } ++ + tmp = RREG32(mmDC_HPD_CONTROL + hpd_offsets[idx]); + tmp = REG_SET_FIELD(tmp, DC_HPD_CONTROL, DC_HPD_EN, 1); + WREG32(mmDC_HPD_CONTROL + hpd_offsets[idx], tmp); +diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +index d4bf133..67c7c05 100644 +--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +@@ -443,16 +443,6 @@ static void dce_v11_0_hpd_init(struct amdgpu_device *adev) + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); + +- if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || +- connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { +- /* don't try to enable hpd on eDP or LVDS avoid breaking the +- * aux dp channel on imac and help (but not completely fix) +- * https://bugzilla.redhat.com/show_bug.cgi?id=726143 +- * also avoid interrupt storms during dpms. +- */ +- continue; +- } +- + switch (amdgpu_connector->hpd.hpd) { + case AMDGPU_HPD_1: + idx = 0; +@@ -476,6 +466,19 @@ static void dce_v11_0_hpd_init(struct amdgpu_device *adev) + continue; + } + ++ if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || ++ connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { ++ /* don't try to enable hpd on eDP or LVDS avoid breaking the ++ * aux dp channel on imac and help (but not completely fix) ++ * https://bugzilla.redhat.com/show_bug.cgi?id=726143 ++ * also avoid interrupt storms during dpms. ++ */ ++ tmp = RREG32(mmDC_HPD_INT_CONTROL + hpd_offsets[idx]); ++ tmp = REG_SET_FIELD(tmp, DC_HPD_INT_CONTROL, DC_HPD_INT_EN, 0); ++ WREG32(mmDC_HPD_INT_CONTROL + hpd_offsets[idx], tmp); ++ continue; ++ } ++ + tmp = RREG32(mmDC_HPD_CONTROL + hpd_offsets[idx]); + tmp = REG_SET_FIELD(tmp, DC_HPD_CONTROL, DC_HPD_EN, 1); + WREG32(mmDC_HPD_CONTROL + hpd_offsets[idx], tmp); +@@ -3109,6 +3112,7 @@ static int dce_v11_0_sw_fini(void *handle) + + dce_v11_0_afmt_fini(adev); + ++ drm_mode_config_cleanup(adev->ddev); + adev->mode_info.mode_config_initialized = false; + + return 0; +diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +index 4fdfab1..ea07c50 100644 +--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +@@ -395,15 +395,6 @@ static void dce_v8_0_hpd_init(struct amdgpu_device *adev) + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); + +- if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || +- connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { +- /* don't try to enable hpd on eDP or LVDS avoid breaking the +- * aux dp channel on imac and help (but not completely fix) +- * https://bugzilla.redhat.com/show_bug.cgi?id=726143 +- * also avoid interrupt storms during dpms. +- */ +- continue; +- } + switch (amdgpu_connector->hpd.hpd) { + case AMDGPU_HPD_1: + WREG32(mmDC_HPD1_CONTROL, tmp); +@@ -426,6 +417,45 @@ static void dce_v8_0_hpd_init(struct amdgpu_device *adev) + default: + break; + } ++ ++ if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || ++ connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { ++ /* don't try to enable hpd on eDP or LVDS avoid breaking the ++ * aux dp channel on imac and help (but not completely fix) ++ * https://bugzilla.redhat.com/show_bug.cgi?id=726143 ++ * also avoid interrupt storms during dpms. ++ */ ++ u32 dc_hpd_int_cntl_reg, dc_hpd_int_cntl; ++ ++ switch (amdgpu_connector->hpd.hpd) { ++ case AMDGPU_HPD_1: ++ dc_hpd_int_cntl_reg = mmDC_HPD1_INT_CONTROL; ++ break; ++ case AMDGPU_HPD_2: ++ dc_hpd_int_cntl_reg = mmDC_HPD2_INT_CONTROL; ++ break; ++ case AMDGPU_HPD_3: ++ dc_hpd_int_cntl_reg = mmDC_HPD3_INT_CONTROL; ++ break; ++ case AMDGPU_HPD_4: ++ dc_hpd_int_cntl_reg = mmDC_HPD4_INT_CONTROL; ++ break; ++ case AMDGPU_HPD_5: ++ dc_hpd_int_cntl_reg = mmDC_HPD5_INT_CONTROL; ++ break; ++ case AMDGPU_HPD_6: ++ dc_hpd_int_cntl_reg = mmDC_HPD6_INT_CONTROL; ++ break; ++ default: ++ continue; ++ } ++ ++ dc_hpd_int_cntl = RREG32(dc_hpd_int_cntl_reg); ++ dc_hpd_int_cntl &= ~DC_HPD1_INT_CONTROL__DC_HPD1_INT_EN_MASK; ++ WREG32(dc_hpd_int_cntl_reg, dc_hpd_int_cntl); ++ continue; ++ } ++ + dce_v8_0_hpd_set_polarity(adev, amdgpu_connector->hpd.hpd); + amdgpu_irq_get(adev, &adev->hpd_irq, amdgpu_connector->hpd.hpd); + } +diff --git a/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c b/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c +index 635fc4b..92b1178 100644 +--- a/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c ++++ b/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c +@@ -262,6 +262,8 @@ static const pem_event_action * const display_config_change_event[] = { + unblock_adjust_power_state_tasks, + set_cpu_power_state, + notify_hw_power_source_tasks, ++ get_2d_performance_state_tasks, ++ set_performance_state_tasks, + /* updateDALConfigurationTasks, + variBrightDisplayConfigurationChangeTasks, */ + adjust_power_state_tasks, +diff --git a/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c b/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c +index a46225c..d6bee72 100644 +--- a/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c ++++ b/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c +@@ -100,11 +100,12 @@ int psm_adjust_power_state_dynamic(struct pp_eventmgr *eventmgr, bool skip) + if (requested == NULL) + return 0; + ++ phm_apply_state_adjust_rules(hwmgr, requested, pcurrent); ++ + if (pcurrent == NULL || (0 != phm_check_states_equal(hwmgr, &pcurrent->hardware, &requested->hardware, &equal))) + equal = false; + + if (!equal || phm_check_smc_update_required_for_display_configuration(hwmgr)) { +- phm_apply_state_adjust_rules(hwmgr, requested, pcurrent); + phm_set_power_state(hwmgr, &pcurrent->hardware, &requested->hardware); + hwmgr->current_ps = requested; + } +diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c +index 780589b..9c4387d 100644 +--- a/drivers/gpu/drm/drm_prime.c ++++ b/drivers/gpu/drm/drm_prime.c +@@ -335,14 +335,17 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = { + * using the PRIME helpers. + */ + struct dma_buf *drm_gem_prime_export(struct drm_device *dev, +- struct drm_gem_object *obj, int flags) ++ struct drm_gem_object *obj, ++ int flags) + { +- DEFINE_DMA_BUF_EXPORT_INFO(exp_info); +- +- exp_info.ops = &drm_gem_prime_dmabuf_ops; +- exp_info.size = obj->size; +- exp_info.flags = flags; +- exp_info.priv = obj; ++ struct dma_buf_export_info exp_info = { ++ .exp_name = KBUILD_MODNAME, /* white lie for debug */ ++ .owner = dev->driver->fops->owner, ++ .ops = &drm_gem_prime_dmabuf_ops, ++ .size = obj->size, ++ .flags = flags, ++ .priv = obj, ++ }; + + if (dev->driver->gem_prime_res_obj) + exp_info.resv = dev->driver->gem_prime_res_obj(obj); +diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +index 7882387..5fc8ebd 100644 +--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c ++++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +@@ -330,6 +330,7 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev) + const char *pix_clk_in_name; + const struct of_device_id *id; + int ret; ++ u8 div_ratio_shift = 0; + + fsl_dev = devm_kzalloc(dev, sizeof(*fsl_dev), GFP_KERNEL); + if (!fsl_dev) +@@ -382,11 +383,14 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev) + pix_clk_in = fsl_dev->clk; + } + ++ if (of_property_read_bool(dev->of_node, "big-endian")) ++ div_ratio_shift = 24; ++ + pix_clk_in_name = __clk_get_name(pix_clk_in); + snprintf(pix_clk_name, sizeof(pix_clk_name), "%s_pix", pix_clk_in_name); + fsl_dev->pix_clk = clk_register_divider(dev, pix_clk_name, + pix_clk_in_name, 0, base + DCU_DIV_RATIO, +- 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL); ++ div_ratio_shift, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL); + if (IS_ERR(fsl_dev->pix_clk)) { + dev_err(dev, "failed to register pix clk\n"); + ret = PTR_ERR(fsl_dev->pix_clk); +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index f68c789..84a0010 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -631,6 +631,8 @@ struct drm_i915_display_funcs { + struct intel_crtc_state *crtc_state); + void (*crtc_enable)(struct drm_crtc *crtc); + void (*crtc_disable)(struct drm_crtc *crtc); ++ void (*update_crtcs)(struct drm_atomic_state *state, ++ unsigned int *crtc_vblank_mask); + void (*audio_codec_enable)(struct drm_connector *connector, + struct intel_encoder *encoder, + const struct drm_display_mode *adjusted_mode); +@@ -1965,11 +1967,11 @@ struct drm_i915_private { + struct vlv_s0ix_state vlv_s0ix_state; + + enum { +- I915_SKL_SAGV_UNKNOWN = 0, +- I915_SKL_SAGV_DISABLED, +- I915_SKL_SAGV_ENABLED, +- I915_SKL_SAGV_NOT_CONTROLLED +- } skl_sagv_status; ++ I915_SAGV_UNKNOWN = 0, ++ I915_SAGV_DISABLED, ++ I915_SAGV_ENABLED, ++ I915_SAGV_NOT_CONTROLLED ++ } sagv_status; + + struct { + /* +@@ -2280,21 +2282,19 @@ struct drm_i915_gem_object { + /** Record of address bit 17 of each page at last unbind. */ + unsigned long *bit_17; + +- union { +- /** for phy allocated objects */ +- struct drm_dma_handle *phys_handle; +- +- struct i915_gem_userptr { +- uintptr_t ptr; +- unsigned read_only :1; +- unsigned workers :4; ++ struct i915_gem_userptr { ++ uintptr_t ptr; ++ unsigned read_only :1; ++ unsigned workers :4; + #define I915_GEM_USERPTR_MAX_WORKERS 15 + +- struct i915_mm_struct *mm; +- struct i915_mmu_object *mmu_object; +- struct work_struct *work; +- } userptr; +- }; ++ struct i915_mm_struct *mm; ++ struct i915_mmu_object *mmu_object; ++ struct work_struct *work; ++ } userptr; ++ ++ /** for phys allocated objects */ ++ struct drm_dma_handle *phys_handle; + }; + #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base) + +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index 66be299a1..2bb69f3 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -115,17 +115,28 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) + + base = bsm & INTEL_BSM_MASK; + } else if (IS_I865G(dev)) { ++ u32 tseg_size = 0; + u16 toud = 0; ++ u8 tmp; ++ ++ pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 0), ++ I845_ESMRAMC, &tmp); ++ ++ if (tmp & TSEG_ENABLE) { ++ switch (tmp & I845_TSEG_SIZE_MASK) { ++ case I845_TSEG_SIZE_512K: ++ tseg_size = KB(512); ++ break; ++ case I845_TSEG_SIZE_1M: ++ tseg_size = MB(1); ++ break; ++ } ++ } + +- /* +- * FIXME is the graphics stolen memory region +- * always at TOUD? Ie. is it always the last +- * one to be allocated by the BIOS? +- */ + pci_bus_read_config_word(dev->pdev->bus, PCI_DEVFN(0, 0), + I865_TOUD, &toud); + +- base = toud << 16; ++ base = (toud << 16) + tseg_size; + } else if (IS_I85X(dev)) { + u32 tseg_size = 0; + u32 tom; +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 175595f..e9a64fb 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -2980,6 +2980,7 @@ static void skylake_update_primary_plane(struct drm_plane *plane, + struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc); + struct drm_framebuffer *fb = plane_state->base.fb; + struct drm_i915_gem_object *obj = intel_fb_obj(fb); ++ const struct skl_wm_values *wm = &dev_priv->wm.skl_results; + int pipe = intel_crtc->pipe; + u32 plane_ctl, stride_div, stride; + u32 tile_height, plane_offset, plane_size; +@@ -3031,6 +3032,9 @@ static void skylake_update_primary_plane(struct drm_plane *plane, + intel_crtc->adjusted_x = x_offset; + intel_crtc->adjusted_y = y_offset; + ++ if (wm->dirty_pipes & drm_crtc_mask(&intel_crtc->base)) ++ skl_write_plane_wm(intel_crtc, wm, 0); ++ + I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl); + I915_WRITE(PLANE_OFFSET(pipe, 0), plane_offset); + I915_WRITE(PLANE_SIZE(pipe, 0), plane_size); +@@ -3061,7 +3065,15 @@ static void skylake_disable_primary_plane(struct drm_plane *primary, + { + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = to_i915(dev); +- int pipe = to_intel_crtc(crtc)->pipe; ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ int pipe = intel_crtc->pipe; ++ ++ /* ++ * We only populate skl_results on watermark updates, and if the ++ * plane's visiblity isn't actually changing neither is its watermarks. ++ */ ++ if (!to_intel_plane_state(crtc->primary->state)->visible) ++ skl_write_plane_wm(intel_crtc, &dev_priv->wm.skl_results, 0); + + I915_WRITE(PLANE_CTL(pipe, 0), 0); + I915_WRITE(PLANE_SURF(pipe, 0), 0); +@@ -8995,6 +9007,24 @@ static void ironlake_compute_dpll(struct intel_crtc *intel_crtc, + if (intel_crtc_has_dp_encoder(crtc_state)) + dpll |= DPLL_SDVO_HIGH_SPEED; + ++ /* ++ * The high speed IO clock is only really required for ++ * SDVO/HDMI/DP, but we also enable it for CRT to make it ++ * possible to share the DPLL between CRT and HDMI. Enabling ++ * the clock needlessly does no real harm, except use up a ++ * bit of power potentially. ++ * ++ * We'll limit this to IVB with 3 pipes, since it has only two ++ * DPLLs and so DPLL sharing is the only way to get three pipes ++ * driving PCH ports at the same time. On SNB we could do this, ++ * and potentially avoid enabling the second DPLL, but it's not ++ * clear if it''s a win or loss power wise. No point in doing ++ * this on ILK at all since it has a fixed DPLL<->pipe mapping. ++ */ ++ if (INTEL_INFO(dev_priv)->num_pipes == 3 && ++ intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) ++ dpll |= DPLL_SDVO_HIGH_SPEED; ++ + /* compute bitmask from p1 value */ + dpll |= (1 << (crtc_state->dpll.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; + /* also FPA1 */ +@@ -10306,9 +10336,13 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base, + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ const struct skl_wm_values *wm = &dev_priv->wm.skl_results; + int pipe = intel_crtc->pipe; + uint32_t cntl = 0; + ++ if (INTEL_GEN(dev_priv) >= 9 && wm->dirty_pipes & drm_crtc_mask(crtc)) ++ skl_write_cursor_wm(intel_crtc, wm); ++ + if (plane_state && plane_state->visible) { + cntl = MCURSOR_GAMMA_ENABLE; + switch (plane_state->base.crtc_w) { +@@ -12956,16 +12990,23 @@ static void verify_wm_state(struct drm_crtc *crtc, + hw_entry->start, hw_entry->end); + } + +- /* cursor */ +- hw_entry = &hw_ddb.plane[pipe][PLANE_CURSOR]; +- sw_entry = &sw_ddb->plane[pipe][PLANE_CURSOR]; +- +- if (!skl_ddb_entry_equal(hw_entry, sw_entry)) { +- DRM_ERROR("mismatch in DDB state pipe %c cursor " +- "(expected (%u,%u), found (%u,%u))\n", +- pipe_name(pipe), +- sw_entry->start, sw_entry->end, +- hw_entry->start, hw_entry->end); ++ /* ++ * cursor ++ * If the cursor plane isn't active, we may not have updated it's ddb ++ * allocation. In that case since the ddb allocation will be updated ++ * once the plane becomes visible, we can skip this check ++ */ ++ if (intel_crtc->cursor_addr) { ++ hw_entry = &hw_ddb.plane[pipe][PLANE_CURSOR]; ++ sw_entry = &sw_ddb->plane[pipe][PLANE_CURSOR]; ++ ++ if (!skl_ddb_entry_equal(hw_entry, sw_entry)) { ++ DRM_ERROR("mismatch in DDB state pipe %c cursor " ++ "(expected (%u,%u), found (%u,%u))\n", ++ pipe_name(pipe), ++ sw_entry->start, sw_entry->end, ++ hw_entry->start, hw_entry->end); ++ } + } + } + +@@ -13671,6 +13712,111 @@ static bool needs_vblank_wait(struct intel_crtc_state *crtc_state) + return false; + } + ++static void intel_update_crtc(struct drm_crtc *crtc, ++ struct drm_atomic_state *state, ++ struct drm_crtc_state *old_crtc_state, ++ unsigned int *crtc_vblank_mask) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_i915_private *dev_priv = to_i915(dev); ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc->state); ++ bool modeset = needs_modeset(crtc->state); ++ ++ if (modeset) { ++ update_scanline_offset(intel_crtc); ++ dev_priv->display.crtc_enable(crtc); ++ } else { ++ intel_pre_plane_update(to_intel_crtc_state(old_crtc_state)); ++ } ++ ++ if (drm_atomic_get_existing_plane_state(state, crtc->primary)) { ++ intel_fbc_enable( ++ intel_crtc, pipe_config, ++ to_intel_plane_state(crtc->primary->state)); ++ } ++ ++ drm_atomic_helper_commit_planes_on_crtc(old_crtc_state); ++ ++ if (needs_vblank_wait(pipe_config)) ++ *crtc_vblank_mask |= drm_crtc_mask(crtc); ++} ++ ++static void intel_update_crtcs(struct drm_atomic_state *state, ++ unsigned int *crtc_vblank_mask) ++{ ++ struct drm_crtc *crtc; ++ struct drm_crtc_state *old_crtc_state; ++ int i; ++ ++ for_each_crtc_in_state(state, crtc, old_crtc_state, i) { ++ if (!crtc->state->active) ++ continue; ++ ++ intel_update_crtc(crtc, state, old_crtc_state, ++ crtc_vblank_mask); ++ } ++} ++ ++static void skl_update_crtcs(struct drm_atomic_state *state, ++ unsigned int *crtc_vblank_mask) ++{ ++ struct drm_device *dev = state->dev; ++ struct drm_i915_private *dev_priv = to_i915(dev); ++ struct intel_atomic_state *intel_state = to_intel_atomic_state(state); ++ struct drm_crtc *crtc; ++ struct drm_crtc_state *old_crtc_state; ++ struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb; ++ struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb; ++ unsigned int updated = 0; ++ bool progress; ++ enum pipe pipe; ++ ++ /* ++ * Whenever the number of active pipes changes, we need to make sure we ++ * update the pipes in the right order so that their ddb allocations ++ * never overlap with eachother inbetween CRTC updates. Otherwise we'll ++ * cause pipe underruns and other bad stuff. ++ */ ++ do { ++ int i; ++ progress = false; ++ ++ for_each_crtc_in_state(state, crtc, old_crtc_state, i) { ++ bool vbl_wait = false; ++ unsigned int cmask = drm_crtc_mask(crtc); ++ pipe = to_intel_crtc(crtc)->pipe; ++ ++ if (updated & cmask || !crtc->state->active) ++ continue; ++ if (skl_ddb_allocation_overlaps(state, cur_ddb, new_ddb, ++ pipe)) ++ continue; ++ ++ updated |= cmask; ++ ++ /* ++ * If this is an already active pipe, it's DDB changed, ++ * and this isn't the last pipe that needs updating ++ * then we need to wait for a vblank to pass for the ++ * new ddb allocation to take effect. ++ */ ++ if (!skl_ddb_allocation_equals(cur_ddb, new_ddb, pipe) && ++ !crtc->state->active_changed && ++ intel_state->wm_results.dirty_pipes != updated) ++ vbl_wait = true; ++ ++ intel_update_crtc(crtc, state, old_crtc_state, ++ crtc_vblank_mask); ++ ++ if (vbl_wait) ++ intel_wait_for_vblank(dev, pipe); ++ ++ progress = true; ++ } ++ } while (progress); ++} ++ + static void intel_atomic_commit_tail(struct drm_atomic_state *state) + { + struct drm_device *dev = state->dev; +@@ -13763,23 +13909,15 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) + * SKL workaround: bspec recommends we disable the SAGV when we + * have more then one pipe enabled + */ +- if (IS_SKYLAKE(dev_priv) && !skl_can_enable_sagv(state)) +- skl_disable_sagv(dev_priv); ++ if (!intel_can_enable_sagv(state)) ++ intel_disable_sagv(dev_priv); + + intel_modeset_verify_disabled(dev); + } + +- /* Now enable the clocks, plane, pipe, and connectors that we set up. */ ++ /* Complete the events for pipes that have now been disabled */ + for_each_crtc_in_state(state, crtc, old_crtc_state, i) { +- struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + bool modeset = needs_modeset(crtc->state); +- struct intel_crtc_state *pipe_config = +- to_intel_crtc_state(crtc->state); +- +- if (modeset && crtc->state->active) { +- update_scanline_offset(to_intel_crtc(crtc)); +- dev_priv->display.crtc_enable(crtc); +- } + + /* Complete events for now disable pipes here. */ + if (modeset && !crtc->state->active && crtc->state->event) { +@@ -13789,21 +13927,11 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) + + crtc->state->event = NULL; + } +- +- if (!modeset) +- intel_pre_plane_update(to_intel_crtc_state(old_crtc_state)); +- +- if (crtc->state->active && +- drm_atomic_get_existing_plane_state(state, crtc->primary)) +- intel_fbc_enable(intel_crtc, pipe_config, to_intel_plane_state(crtc->primary->state)); +- +- if (crtc->state->active) +- drm_atomic_helper_commit_planes_on_crtc(old_crtc_state); +- +- if (pipe_config->base.active && needs_vblank_wait(pipe_config)) +- crtc_vblank_mask |= 1 << i; + } + ++ /* Now enable the clocks, plane, pipe, and connectors that we set up. */ ++ dev_priv->display.update_crtcs(state, &crtc_vblank_mask); ++ + /* FIXME: We should call drm_atomic_helper_commit_hw_done() here + * already, but still need the state for the delayed optimization. To + * fix this: +@@ -13839,9 +13967,8 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) + intel_modeset_verify_crtc(crtc, old_crtc_state, crtc->state); + } + +- if (IS_SKYLAKE(dev_priv) && intel_state->modeset && +- skl_can_enable_sagv(state)) +- skl_enable_sagv(dev_priv); ++ if (intel_state->modeset && intel_can_enable_sagv(state)) ++ intel_enable_sagv(dev_priv); + + drm_atomic_helper_commit_hw_done(state); + +@@ -14221,10 +14348,12 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc, + struct drm_crtc_state *old_crtc_state) + { + struct drm_device *dev = crtc->dev; ++ struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_crtc_state *old_intel_state = + to_intel_crtc_state(old_crtc_state); + bool modeset = needs_modeset(crtc->state); ++ enum pipe pipe = intel_crtc->pipe; + + /* Perform vblank evasion around commit operation */ + intel_pipe_update_start(intel_crtc); +@@ -14239,8 +14368,12 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc, + + if (to_intel_crtc_state(crtc->state)->update_pipe) + intel_update_pipe_config(intel_crtc, old_intel_state); +- else if (INTEL_INFO(dev)->gen >= 9) ++ else if (INTEL_GEN(dev_priv) >= 9) { + skl_detach_scalers(intel_crtc); ++ ++ I915_WRITE(PIPE_WM_LINETIME(pipe), ++ dev_priv->wm.skl_hw.wm_linetime[pipe]); ++ } + } + + static void intel_finish_crtc_commit(struct drm_crtc *crtc, +@@ -15347,6 +15480,11 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv) + skl_modeset_calc_cdclk; + } + ++ if (dev_priv->info.gen >= 9) ++ dev_priv->display.update_crtcs = skl_update_crtcs; ++ else ++ dev_priv->display.update_crtcs = intel_update_crtcs; ++ + switch (INTEL_INFO(dev_priv)->gen) { + case 2: + dev_priv->display.queue_flip = intel_gen2_queue_flip; +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 21b04c3..1ca155f 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -4148,7 +4148,7 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv, + * + * Return %true if @port is connected, %false otherwise. + */ +-bool intel_digital_port_connected(struct drm_i915_private *dev_priv, ++static bool intel_digital_port_connected(struct drm_i915_private *dev_priv, + struct intel_digital_port *port) + { + if (HAS_PCH_IBX(dev_priv)) +@@ -4207,7 +4207,7 @@ intel_dp_unset_edid(struct intel_dp *intel_dp) + intel_dp->has_audio = false; + } + +-static void ++static enum drm_connector_status + intel_dp_long_pulse(struct intel_connector *intel_connector) + { + struct drm_connector *connector = &intel_connector->base; +@@ -4232,7 +4232,7 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) + else + status = connector_status_disconnected; + +- if (status != connector_status_connected) { ++ if (status == connector_status_disconnected) { + intel_dp->compliance_test_active = 0; + intel_dp->compliance_test_type = 0; + intel_dp->compliance_test_data = 0; +@@ -4284,8 +4284,8 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) + intel_dp->aux.i2c_defer_count = 0; + + intel_dp_set_edid(intel_dp); +- +- status = connector_status_connected; ++ if (is_edp(intel_dp) || intel_connector->detect_edid) ++ status = connector_status_connected; + intel_dp->detect_done = true; + + /* Try to read the source of the interrupt */ +@@ -4303,12 +4303,11 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) + } + + out: +- if ((status != connector_status_connected) && +- (intel_dp->is_mst == false)) ++ if (status != connector_status_connected && !intel_dp->is_mst) + intel_dp_unset_edid(intel_dp); + + intel_display_power_put(to_i915(dev), power_domain); +- return; ++ return status; + } + + static enum drm_connector_status +@@ -4317,7 +4316,7 @@ intel_dp_detect(struct drm_connector *connector, bool force) + struct intel_dp *intel_dp = intel_attached_dp(connector); + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct intel_encoder *intel_encoder = &intel_dig_port->base; +- struct intel_connector *intel_connector = to_intel_connector(connector); ++ enum drm_connector_status status = connector->status; + + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", + connector->base.id, connector->name); +@@ -4332,14 +4331,11 @@ intel_dp_detect(struct drm_connector *connector, bool force) + + /* If full detect is not performed yet, do a full detect */ + if (!intel_dp->detect_done) +- intel_dp_long_pulse(intel_dp->attached_connector); ++ status = intel_dp_long_pulse(intel_dp->attached_connector); + + intel_dp->detect_done = false; + +- if (is_edp(intel_dp) || intel_connector->detect_edid) +- return connector_status_connected; +- else +- return connector_status_disconnected; ++ return status; + } + + static void +@@ -4696,36 +4692,34 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) + port_name(intel_dig_port->port), + long_hpd ? "long" : "short"); + ++ if (long_hpd) { ++ intel_dp->detect_done = false; ++ return IRQ_NONE; ++ } ++ + power_domain = intel_display_port_aux_power_domain(intel_encoder); + intel_display_power_get(dev_priv, power_domain); + +- if (long_hpd) { +- intel_dp_long_pulse(intel_dp->attached_connector); +- if (intel_dp->is_mst) +- ret = IRQ_HANDLED; +- goto put_power; +- +- } else { +- if (intel_dp->is_mst) { +- if (intel_dp_check_mst_status(intel_dp) == -EINVAL) { +- /* +- * If we were in MST mode, and device is not +- * there, get out of MST mode +- */ +- DRM_DEBUG_KMS("MST device may have disappeared %d vs %d\n", +- intel_dp->is_mst, intel_dp->mst_mgr.mst_state); +- intel_dp->is_mst = false; +- drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, +- intel_dp->is_mst); +- goto put_power; +- } ++ if (intel_dp->is_mst) { ++ if (intel_dp_check_mst_status(intel_dp) == -EINVAL) { ++ /* ++ * If we were in MST mode, and device is not ++ * there, get out of MST mode ++ */ ++ DRM_DEBUG_KMS("MST device may have disappeared %d vs %d\n", ++ intel_dp->is_mst, intel_dp->mst_mgr.mst_state); ++ intel_dp->is_mst = false; ++ drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, ++ intel_dp->is_mst); ++ intel_dp->detect_done = false; ++ goto put_power; + } ++ } + +- if (!intel_dp->is_mst) { +- if (!intel_dp_short_pulse(intel_dp)) { +- intel_dp_long_pulse(intel_dp->attached_connector); +- goto put_power; +- } ++ if (!intel_dp->is_mst) { ++ if (!intel_dp_short_pulse(intel_dp)) { ++ intel_dp->detect_done = false; ++ goto put_power; + } + } + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index ff399b9..9a58800 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -236,6 +236,7 @@ struct intel_panel { + bool enabled; + bool combination_mode; /* gen 2/4 only */ + bool active_low_pwm; ++ bool alternate_pwm_increment; /* lpt+ */ + + /* PWM chip */ + bool util_pin_active_low; /* bxt+ */ +@@ -1387,8 +1388,6 @@ void intel_edp_drrs_disable(struct intel_dp *intel_dp); + void intel_edp_drrs_invalidate(struct drm_device *dev, + unsigned frontbuffer_bits); + void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits); +-bool intel_digital_port_connected(struct drm_i915_private *dev_priv, +- struct intel_digital_port *port); + + void + intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, +@@ -1716,9 +1715,21 @@ void ilk_wm_get_hw_state(struct drm_device *dev); + void skl_wm_get_hw_state(struct drm_device *dev); + void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, + struct skl_ddb_allocation *ddb /* out */); +-bool skl_can_enable_sagv(struct drm_atomic_state *state); +-int skl_enable_sagv(struct drm_i915_private *dev_priv); +-int skl_disable_sagv(struct drm_i915_private *dev_priv); ++bool intel_can_enable_sagv(struct drm_atomic_state *state); ++int intel_enable_sagv(struct drm_i915_private *dev_priv); ++int intel_disable_sagv(struct drm_i915_private *dev_priv); ++bool skl_ddb_allocation_equals(const struct skl_ddb_allocation *old, ++ const struct skl_ddb_allocation *new, ++ enum pipe pipe); ++bool skl_ddb_allocation_overlaps(struct drm_atomic_state *state, ++ const struct skl_ddb_allocation *old, ++ const struct skl_ddb_allocation *new, ++ enum pipe pipe); ++void skl_write_cursor_wm(struct intel_crtc *intel_crtc, ++ const struct skl_wm_values *wm); ++void skl_write_plane_wm(struct intel_crtc *intel_crtc, ++ const struct skl_wm_values *wm, ++ int plane); + uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config); + bool ilk_disable_lp_wm(struct drm_device *dev); + int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6); +diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c +index 4df9f38..c3aa9e6 100644 +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -1422,24 +1422,22 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector, bool has_edid) + } + + static bool +-intel_hdmi_set_edid(struct drm_connector *connector, bool force) ++intel_hdmi_set_edid(struct drm_connector *connector) + { + struct drm_i915_private *dev_priv = to_i915(connector->dev); + struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); +- struct edid *edid = NULL; ++ struct edid *edid; + bool connected = false; + +- if (force) { +- intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); ++ intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); + +- edid = drm_get_edid(connector, +- intel_gmbus_get_adapter(dev_priv, +- intel_hdmi->ddc_bus)); ++ edid = drm_get_edid(connector, ++ intel_gmbus_get_adapter(dev_priv, ++ intel_hdmi->ddc_bus)); + +- intel_hdmi_dp_dual_mode_detect(connector, edid != NULL); ++ intel_hdmi_dp_dual_mode_detect(connector, edid != NULL); + +- intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); +- } ++ intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); + + to_intel_connector(connector)->detect_edid = edid; + if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) { +@@ -1465,37 +1463,16 @@ static enum drm_connector_status + intel_hdmi_detect(struct drm_connector *connector, bool force) + { + enum drm_connector_status status; +- struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); + struct drm_i915_private *dev_priv = to_i915(connector->dev); +- bool live_status = false; +- unsigned int try; + + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", + connector->base.id, connector->name); + + intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); + +- for (try = 0; !live_status && try < 9; try++) { +- if (try) +- msleep(10); +- live_status = intel_digital_port_connected(dev_priv, +- hdmi_to_dig_port(intel_hdmi)); +- } +- +- if (!live_status) { +- DRM_DEBUG_KMS("HDMI live status down\n"); +- /* +- * Live status register is not reliable on all intel platforms. +- * So consider live_status only for certain platforms, for +- * others, read EDID to determine presence of sink. +- */ +- if (INTEL_INFO(dev_priv)->gen < 7 || IS_IVYBRIDGE(dev_priv)) +- live_status = true; +- } +- + intel_hdmi_unset_edid(connector); + +- if (intel_hdmi_set_edid(connector, live_status)) { ++ if (intel_hdmi_set_edid(connector)) { + struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); + + hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; +@@ -1521,7 +1498,7 @@ intel_hdmi_force(struct drm_connector *connector) + if (connector->status != connector_status_connected) + return; + +- intel_hdmi_set_edid(connector, true); ++ intel_hdmi_set_edid(connector); + hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; + } + +diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c +index 96c65d7..9a2393a 100644 +--- a/drivers/gpu/drm/i915/intel_panel.c ++++ b/drivers/gpu/drm/i915/intel_panel.c +@@ -841,7 +841,7 @@ static void lpt_enable_backlight(struct intel_connector *connector) + { + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; +- u32 pch_ctl1, pch_ctl2; ++ u32 pch_ctl1, pch_ctl2, schicken; + + pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1); + if (pch_ctl1 & BLM_PCH_PWM_ENABLE) { +@@ -850,6 +850,22 @@ static void lpt_enable_backlight(struct intel_connector *connector) + I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1); + } + ++ if (HAS_PCH_LPT(dev_priv)) { ++ schicken = I915_READ(SOUTH_CHICKEN2); ++ if (panel->backlight.alternate_pwm_increment) ++ schicken |= LPT_PWM_GRANULARITY; ++ else ++ schicken &= ~LPT_PWM_GRANULARITY; ++ I915_WRITE(SOUTH_CHICKEN2, schicken); ++ } else { ++ schicken = I915_READ(SOUTH_CHICKEN1); ++ if (panel->backlight.alternate_pwm_increment) ++ schicken |= SPT_PWM_GRANULARITY; ++ else ++ schicken &= ~SPT_PWM_GRANULARITY; ++ I915_WRITE(SOUTH_CHICKEN1, schicken); ++ } ++ + pch_ctl2 = panel->backlight.max << 16; + I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2); + +@@ -1242,10 +1258,10 @@ static u32 bxt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) + */ + static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) + { +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); ++ struct intel_panel *panel = &connector->panel; + u32 mul; + +- if (I915_READ(SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY) ++ if (panel->backlight.alternate_pwm_increment) + mul = 128; + else + mul = 16; +@@ -1261,9 +1277,10 @@ static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) + static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) + { + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); ++ struct intel_panel *panel = &connector->panel; + u32 mul, clock; + +- if (I915_READ(SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY) ++ if (panel->backlight.alternate_pwm_increment) + mul = 16; + else + mul = 128; +@@ -1414,6 +1431,13 @@ static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unus + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 pch_ctl1, pch_ctl2, val; ++ bool alt; ++ ++ if (HAS_PCH_LPT(dev_priv)) ++ alt = I915_READ(SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY; ++ else ++ alt = I915_READ(SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY; ++ panel->backlight.alternate_pwm_increment = alt; + + pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1); + panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY; +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 2d24813..e59a28c 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2119,32 +2119,34 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8]) + GEN9_MEM_LATENCY_LEVEL_MASK; + + /* ++ * If a level n (n > 1) has a 0us latency, all levels m (m >= n) ++ * need to be disabled. We make sure to sanitize the values out ++ * of the punit to satisfy this requirement. ++ */ ++ for (level = 1; level <= max_level; level++) { ++ if (wm[level] == 0) { ++ for (i = level + 1; i <= max_level; i++) ++ wm[i] = 0; ++ break; ++ } ++ } ++ ++ /* + * WaWmMemoryReadLatency:skl + * + * punit doesn't take into account the read latency so we need +- * to add 2us to the various latency levels we retrieve from +- * the punit. +- * - W0 is a bit special in that it's the only level that +- * can't be disabled if we want to have display working, so +- * we always add 2us there. +- * - For levels >=1, punit returns 0us latency when they are +- * disabled, so we respect that and don't add 2us then +- * +- * Additionally, if a level n (n > 1) has a 0us latency, all +- * levels m (m >= n) need to be disabled. We make sure to +- * sanitize the values out of the punit to satisfy this +- * requirement. ++ * to add 2us to the various latency levels we retrieve from the ++ * punit when level 0 response data us 0us. + */ +- wm[0] += 2; +- for (level = 1; level <= max_level; level++) +- if (wm[level] != 0) ++ if (wm[0] == 0) { ++ wm[0] += 2; ++ for (level = 1; level <= max_level; level++) { ++ if (wm[level] == 0) ++ break; + wm[level] += 2; +- else { +- for (i = level + 1; i <= max_level; i++) +- wm[i] = 0; +- +- break; + } ++ } ++ + } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { + uint64_t sskpd = I915_READ64(MCH_SSKPD); + +@@ -2876,6 +2878,19 @@ skl_wm_plane_id(const struct intel_plane *plane) + } + } + ++static bool ++intel_has_sagv(struct drm_i915_private *dev_priv) ++{ ++ if (IS_KABYLAKE(dev_priv)) ++ return true; ++ ++ if (IS_SKYLAKE(dev_priv) && ++ dev_priv->sagv_status != I915_SAGV_NOT_CONTROLLED) ++ return true; ++ ++ return false; ++} ++ + /* + * SAGV dynamically adjusts the system agent voltage and clock frequencies + * depending on power and performance requirements. The display engine access +@@ -2888,12 +2903,14 @@ skl_wm_plane_id(const struct intel_plane *plane) + * - We're not using an interlaced display configuration + */ + int +-skl_enable_sagv(struct drm_i915_private *dev_priv) ++intel_enable_sagv(struct drm_i915_private *dev_priv) + { + int ret; + +- if (dev_priv->skl_sagv_status == I915_SKL_SAGV_NOT_CONTROLLED || +- dev_priv->skl_sagv_status == I915_SKL_SAGV_ENABLED) ++ if (!intel_has_sagv(dev_priv)) ++ return 0; ++ ++ if (dev_priv->sagv_status == I915_SAGV_ENABLED) + return 0; + + DRM_DEBUG_KMS("Enabling the SAGV\n"); +@@ -2909,21 +2926,21 @@ skl_enable_sagv(struct drm_i915_private *dev_priv) + * Some skl systems, pre-release machines in particular, + * don't actually have an SAGV. + */ +- if (ret == -ENXIO) { ++ if (IS_SKYLAKE(dev_priv) && ret == -ENXIO) { + DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n"); +- dev_priv->skl_sagv_status = I915_SKL_SAGV_NOT_CONTROLLED; ++ dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED; + return 0; + } else if (ret < 0) { + DRM_ERROR("Failed to enable the SAGV\n"); + return ret; + } + +- dev_priv->skl_sagv_status = I915_SKL_SAGV_ENABLED; ++ dev_priv->sagv_status = I915_SAGV_ENABLED; + return 0; + } + + static int +-skl_do_sagv_disable(struct drm_i915_private *dev_priv) ++intel_do_sagv_disable(struct drm_i915_private *dev_priv) + { + int ret; + uint32_t temp = GEN9_SAGV_DISABLE; +@@ -2937,19 +2954,21 @@ skl_do_sagv_disable(struct drm_i915_private *dev_priv) + } + + int +-skl_disable_sagv(struct drm_i915_private *dev_priv) ++intel_disable_sagv(struct drm_i915_private *dev_priv) + { + int ret, result; + +- if (dev_priv->skl_sagv_status == I915_SKL_SAGV_NOT_CONTROLLED || +- dev_priv->skl_sagv_status == I915_SKL_SAGV_DISABLED) ++ if (!intel_has_sagv(dev_priv)) ++ return 0; ++ ++ if (dev_priv->sagv_status == I915_SAGV_DISABLED) + return 0; + + DRM_DEBUG_KMS("Disabling the SAGV\n"); + mutex_lock(&dev_priv->rps.hw_lock); + + /* bspec says to keep retrying for at least 1 ms */ +- ret = wait_for(result = skl_do_sagv_disable(dev_priv), 1); ++ ret = wait_for(result = intel_do_sagv_disable(dev_priv), 1); + mutex_unlock(&dev_priv->rps.hw_lock); + + if (ret == -ETIMEDOUT) { +@@ -2961,20 +2980,20 @@ skl_disable_sagv(struct drm_i915_private *dev_priv) + * Some skl systems, pre-release machines in particular, + * don't actually have an SAGV. + */ +- if (result == -ENXIO) { ++ if (IS_SKYLAKE(dev_priv) && result == -ENXIO) { + DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n"); +- dev_priv->skl_sagv_status = I915_SKL_SAGV_NOT_CONTROLLED; ++ dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED; + return 0; + } else if (result < 0) { + DRM_ERROR("Failed to disable the SAGV\n"); + return result; + } + +- dev_priv->skl_sagv_status = I915_SKL_SAGV_DISABLED; ++ dev_priv->sagv_status = I915_SAGV_DISABLED; + return 0; + } + +-bool skl_can_enable_sagv(struct drm_atomic_state *state) ++bool intel_can_enable_sagv(struct drm_atomic_state *state) + { + struct drm_device *dev = state->dev; + struct drm_i915_private *dev_priv = to_i915(dev); +@@ -2983,6 +3002,9 @@ bool skl_can_enable_sagv(struct drm_atomic_state *state) + enum pipe pipe; + int level, plane; + ++ if (!intel_has_sagv(dev_priv)) ++ return false; ++ + /* + * SKL workaround: bspec recommends we disable the SAGV when we have + * more then one pipe enabled +@@ -3473,29 +3495,14 @@ static uint32_t skl_wm_method1(uint32_t pixel_rate, uint8_t cpp, uint32_t latenc + } + + static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, +- uint32_t horiz_pixels, uint8_t cpp, +- uint64_t tiling, uint32_t latency) ++ uint32_t latency, uint32_t plane_blocks_per_line) + { + uint32_t ret; +- uint32_t plane_bytes_per_line, plane_blocks_per_line; + uint32_t wm_intermediate_val; + + if (latency == 0) + return UINT_MAX; + +- plane_bytes_per_line = horiz_pixels * cpp; +- +- if (tiling == I915_FORMAT_MOD_Y_TILED || +- tiling == I915_FORMAT_MOD_Yf_TILED) { +- plane_bytes_per_line *= 4; +- plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); +- plane_blocks_per_line /= 4; +- } else if (tiling == DRM_FORMAT_MOD_NONE) { +- plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512) + 1; +- } else { +- plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); +- } +- + wm_intermediate_val = latency * pixel_rate; + ret = DIV_ROUND_UP(wm_intermediate_val, pipe_htotal * 1000) * + plane_blocks_per_line; +@@ -3546,6 +3553,7 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv, + uint8_t cpp; + uint32_t width = 0, height = 0; + uint32_t plane_pixel_rate; ++ uint32_t y_tile_minimum, y_min_scanlines; + + if (latency == 0 || !cstate->base.active || !intel_pstate->visible) { + *enabled = false; +@@ -3561,38 +3569,51 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv, + cpp = drm_format_plane_cpp(fb->pixel_format, 0); + plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate, intel_pstate); + ++ if (intel_rotation_90_or_270(pstate->rotation)) { ++ int cpp = (fb->pixel_format == DRM_FORMAT_NV12) ? ++ drm_format_plane_cpp(fb->pixel_format, 1) : ++ drm_format_plane_cpp(fb->pixel_format, 0); ++ ++ switch (cpp) { ++ case 1: ++ y_min_scanlines = 16; ++ break; ++ case 2: ++ y_min_scanlines = 8; ++ break; ++ default: ++ WARN(1, "Unsupported pixel depth for rotation"); ++ case 4: ++ y_min_scanlines = 4; ++ break; ++ } ++ } else { ++ y_min_scanlines = 4; ++ } ++ ++ plane_bytes_per_line = width * cpp; ++ if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || ++ fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) { ++ plane_blocks_per_line = ++ DIV_ROUND_UP(plane_bytes_per_line * y_min_scanlines, 512); ++ plane_blocks_per_line /= y_min_scanlines; ++ } else if (fb->modifier[0] == DRM_FORMAT_MOD_NONE) { ++ plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512) ++ + 1; ++ } else { ++ plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); ++ } ++ + method1 = skl_wm_method1(plane_pixel_rate, cpp, latency); + method2 = skl_wm_method2(plane_pixel_rate, + cstate->base.adjusted_mode.crtc_htotal, +- width, +- cpp, +- fb->modifier[0], +- latency); ++ latency, ++ plane_blocks_per_line); + +- plane_bytes_per_line = width * cpp; +- plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); ++ y_tile_minimum = plane_blocks_per_line * y_min_scanlines; + + if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || + fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) { +- uint32_t min_scanlines = 4; +- uint32_t y_tile_minimum; +- if (intel_rotation_90_or_270(pstate->rotation)) { +- int cpp = (fb->pixel_format == DRM_FORMAT_NV12) ? +- drm_format_plane_cpp(fb->pixel_format, 1) : +- drm_format_plane_cpp(fb->pixel_format, 0); +- +- switch (cpp) { +- case 1: +- min_scanlines = 16; +- break; +- case 2: +- min_scanlines = 8; +- break; +- case 8: +- WARN(1, "Unsupported pixel depth for rotation"); +- } +- } +- y_tile_minimum = plane_blocks_per_line * min_scanlines; + selected_result = max(method2, y_tile_minimum); + } else { + if ((ddb_allocation / plane_blocks_per_line) >= 1) +@@ -3606,10 +3627,12 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv, + + if (level >= 1 && level <= 7) { + if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || +- fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) +- res_lines += 4; +- else ++ fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) { ++ res_blocks += y_tile_minimum; ++ res_lines += y_min_scanlines; ++ } else { + res_blocks++; ++ } + } + + if (res_blocks >= ddb_allocation || res_lines > 31) { +@@ -3828,183 +3851,82 @@ static void skl_ddb_entry_write(struct drm_i915_private *dev_priv, + I915_WRITE(reg, 0); + } + +-static void skl_write_wm_values(struct drm_i915_private *dev_priv, +- const struct skl_wm_values *new) ++void skl_write_plane_wm(struct intel_crtc *intel_crtc, ++ const struct skl_wm_values *wm, ++ int plane) + { +- struct drm_device *dev = &dev_priv->drm; +- struct intel_crtc *crtc; +- +- for_each_intel_crtc(dev, crtc) { +- int i, level, max_level = ilk_wm_max_level(dev); +- enum pipe pipe = crtc->pipe; +- +- if ((new->dirty_pipes & drm_crtc_mask(&crtc->base)) == 0) +- continue; +- if (!crtc->active) +- continue; +- +- I915_WRITE(PIPE_WM_LINETIME(pipe), new->wm_linetime[pipe]); +- +- for (level = 0; level <= max_level; level++) { +- for (i = 0; i < intel_num_planes(crtc); i++) +- I915_WRITE(PLANE_WM(pipe, i, level), +- new->plane[pipe][i][level]); +- I915_WRITE(CUR_WM(pipe, level), +- new->plane[pipe][PLANE_CURSOR][level]); +- } +- for (i = 0; i < intel_num_planes(crtc); i++) +- I915_WRITE(PLANE_WM_TRANS(pipe, i), +- new->plane_trans[pipe][i]); +- I915_WRITE(CUR_WM_TRANS(pipe), +- new->plane_trans[pipe][PLANE_CURSOR]); +- +- for (i = 0; i < intel_num_planes(crtc); i++) { +- skl_ddb_entry_write(dev_priv, +- PLANE_BUF_CFG(pipe, i), +- &new->ddb.plane[pipe][i]); +- skl_ddb_entry_write(dev_priv, +- PLANE_NV12_BUF_CFG(pipe, i), +- &new->ddb.y_plane[pipe][i]); +- } ++ struct drm_crtc *crtc = &intel_crtc->base; ++ struct drm_device *dev = crtc->dev; ++ struct drm_i915_private *dev_priv = to_i915(dev); ++ int level, max_level = ilk_wm_max_level(dev); ++ enum pipe pipe = intel_crtc->pipe; + +- skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), +- &new->ddb.plane[pipe][PLANE_CURSOR]); ++ for (level = 0; level <= max_level; level++) { ++ I915_WRITE(PLANE_WM(pipe, plane, level), ++ wm->plane[pipe][plane][level]); + } +-} ++ I915_WRITE(PLANE_WM_TRANS(pipe, plane), wm->plane_trans[pipe][plane]); + +-/* +- * When setting up a new DDB allocation arrangement, we need to correctly +- * sequence the times at which the new allocations for the pipes are taken into +- * account or we'll have pipes fetching from space previously allocated to +- * another pipe. +- * +- * Roughly the sequence looks like: +- * 1. re-allocate the pipe(s) with the allocation being reduced and not +- * overlapping with a previous light-up pipe (another way to put it is: +- * pipes with their new allocation strickly included into their old ones). +- * 2. re-allocate the other pipes that get their allocation reduced +- * 3. allocate the pipes having their allocation increased +- * +- * Steps 1. and 2. are here to take care of the following case: +- * - Initially DDB looks like this: +- * | B | C | +- * - enable pipe A. +- * - pipe B has a reduced DDB allocation that overlaps with the old pipe C +- * allocation +- * | A | B | C | +- * +- * We need to sequence the re-allocation: C, B, A (and not B, C, A). +- */ ++ skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane), ++ &wm->ddb.plane[pipe][plane]); ++ skl_ddb_entry_write(dev_priv, PLANE_NV12_BUF_CFG(pipe, plane), ++ &wm->ddb.y_plane[pipe][plane]); ++} + +-static void +-skl_wm_flush_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, int pass) ++void skl_write_cursor_wm(struct intel_crtc *intel_crtc, ++ const struct skl_wm_values *wm) + { +- int plane; +- +- DRM_DEBUG_KMS("flush pipe %c (pass %d)\n", pipe_name(pipe), pass); ++ struct drm_crtc *crtc = &intel_crtc->base; ++ struct drm_device *dev = crtc->dev; ++ struct drm_i915_private *dev_priv = to_i915(dev); ++ int level, max_level = ilk_wm_max_level(dev); ++ enum pipe pipe = intel_crtc->pipe; + +- for_each_plane(dev_priv, pipe, plane) { +- I915_WRITE(PLANE_SURF(pipe, plane), +- I915_READ(PLANE_SURF(pipe, plane))); ++ for (level = 0; level <= max_level; level++) { ++ I915_WRITE(CUR_WM(pipe, level), ++ wm->plane[pipe][PLANE_CURSOR][level]); + } +- I915_WRITE(CURBASE(pipe), I915_READ(CURBASE(pipe))); ++ I915_WRITE(CUR_WM_TRANS(pipe), wm->plane_trans[pipe][PLANE_CURSOR]); ++ ++ skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), ++ &wm->ddb.plane[pipe][PLANE_CURSOR]); + } + +-static bool +-skl_ddb_allocation_included(const struct skl_ddb_allocation *old, +- const struct skl_ddb_allocation *new, +- enum pipe pipe) ++bool skl_ddb_allocation_equals(const struct skl_ddb_allocation *old, ++ const struct skl_ddb_allocation *new, ++ enum pipe pipe) + { +- uint16_t old_size, new_size; +- +- old_size = skl_ddb_entry_size(&old->pipe[pipe]); +- new_size = skl_ddb_entry_size(&new->pipe[pipe]); +- +- return old_size != new_size && +- new->pipe[pipe].start >= old->pipe[pipe].start && +- new->pipe[pipe].end <= old->pipe[pipe].end; ++ return new->pipe[pipe].start == old->pipe[pipe].start && ++ new->pipe[pipe].end == old->pipe[pipe].end; + } + +-static void skl_flush_wm_values(struct drm_i915_private *dev_priv, +- struct skl_wm_values *new_values) ++static inline bool skl_ddb_entries_overlap(const struct skl_ddb_entry *a, ++ const struct skl_ddb_entry *b) + { +- struct drm_device *dev = &dev_priv->drm; +- struct skl_ddb_allocation *cur_ddb, *new_ddb; +- bool reallocated[I915_MAX_PIPES] = {}; +- struct intel_crtc *crtc; +- enum pipe pipe; +- +- new_ddb = &new_values->ddb; +- cur_ddb = &dev_priv->wm.skl_hw.ddb; +- +- /* +- * First pass: flush the pipes with the new allocation contained into +- * the old space. +- * +- * We'll wait for the vblank on those pipes to ensure we can safely +- * re-allocate the freed space without this pipe fetching from it. +- */ +- for_each_intel_crtc(dev, crtc) { +- if (!crtc->active) +- continue; +- +- pipe = crtc->pipe; +- +- if (!skl_ddb_allocation_included(cur_ddb, new_ddb, pipe)) +- continue; +- +- skl_wm_flush_pipe(dev_priv, pipe, 1); +- intel_wait_for_vblank(dev, pipe); +- +- reallocated[pipe] = true; +- } +- ++ return a->start < b->end && b->start < a->end; ++} + +- /* +- * Second pass: flush the pipes that are having their allocation +- * reduced, but overlapping with a previous allocation. +- * +- * Here as well we need to wait for the vblank to make sure the freed +- * space is not used anymore. +- */ +- for_each_intel_crtc(dev, crtc) { +- if (!crtc->active) +- continue; ++bool skl_ddb_allocation_overlaps(struct drm_atomic_state *state, ++ const struct skl_ddb_allocation *old, ++ const struct skl_ddb_allocation *new, ++ enum pipe pipe) ++{ ++ struct drm_device *dev = state->dev; ++ struct intel_crtc *intel_crtc; ++ enum pipe otherp; + +- pipe = crtc->pipe; ++ for_each_intel_crtc(dev, intel_crtc) { ++ otherp = intel_crtc->pipe; + +- if (reallocated[pipe]) ++ if (otherp == pipe) + continue; + +- if (skl_ddb_entry_size(&new_ddb->pipe[pipe]) < +- skl_ddb_entry_size(&cur_ddb->pipe[pipe])) { +- skl_wm_flush_pipe(dev_priv, pipe, 2); +- intel_wait_for_vblank(dev, pipe); +- reallocated[pipe] = true; +- } ++ if (skl_ddb_entries_overlap(&new->pipe[pipe], ++ &old->pipe[otherp])) ++ return true; + } + +- /* +- * Third pass: flush the pipes that got more space allocated. +- * +- * We don't need to actively wait for the update here, next vblank +- * will just get more DDB space with the correct WM values. +- */ +- for_each_intel_crtc(dev, crtc) { +- if (!crtc->active) +- continue; +- +- pipe = crtc->pipe; +- +- /* +- * At this point, only the pipes more space than before are +- * left to re-allocate. +- */ +- if (reallocated[pipe]) +- continue; +- +- skl_wm_flush_pipe(dev_priv, pipe, 3); +- } ++ return false; + } + + static int skl_update_pipe_wm(struct drm_crtc_state *cstate, +@@ -4041,6 +3963,41 @@ pipes_modified(struct drm_atomic_state *state) + return ret; + } + ++int ++skl_ddb_add_affected_planes(struct intel_crtc_state *cstate) ++{ ++ struct drm_atomic_state *state = cstate->base.state; ++ struct drm_device *dev = state->dev; ++ struct drm_crtc *crtc = cstate->base.crtc; ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ struct drm_i915_private *dev_priv = to_i915(dev); ++ struct intel_atomic_state *intel_state = to_intel_atomic_state(state); ++ struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb; ++ struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb; ++ struct drm_plane_state *plane_state; ++ struct drm_plane *plane; ++ enum pipe pipe = intel_crtc->pipe; ++ int id; ++ ++ WARN_ON(!drm_atomic_get_existing_crtc_state(state, crtc)); ++ ++ drm_for_each_plane_mask(plane, dev, crtc->state->plane_mask) { ++ id = skl_wm_plane_id(to_intel_plane(plane)); ++ ++ if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][id], ++ &new_ddb->plane[pipe][id]) && ++ skl_ddb_entry_equal(&cur_ddb->y_plane[pipe][id], ++ &new_ddb->y_plane[pipe][id])) ++ continue; ++ ++ plane_state = drm_atomic_get_plane_state(state, plane); ++ if (IS_ERR(plane_state)) ++ return PTR_ERR(plane_state); ++ } ++ ++ return 0; ++} ++ + static int + skl_compute_ddb(struct drm_atomic_state *state) + { +@@ -4105,6 +4062,10 @@ skl_compute_ddb(struct drm_atomic_state *state) + if (ret) + return ret; + ++ ret = skl_ddb_add_affected_planes(cstate); ++ if (ret) ++ return ret; ++ + ret = drm_atomic_add_affected_planes(state, &intel_crtc->base); + if (ret) + return ret; +@@ -4206,7 +4167,7 @@ static void skl_update_wm(struct drm_crtc *crtc) + struct skl_wm_values *hw_vals = &dev_priv->wm.skl_hw; + struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); + struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal; +- int pipe; ++ enum pipe pipe = intel_crtc->pipe; + + if ((results->dirty_pipes & drm_crtc_mask(crtc)) == 0) + return; +@@ -4215,15 +4176,22 @@ static void skl_update_wm(struct drm_crtc *crtc) + + mutex_lock(&dev_priv->wm.wm_mutex); + +- skl_write_wm_values(dev_priv, results); +- skl_flush_wm_values(dev_priv, results); +- + /* +- * Store the new configuration (but only for the pipes that have +- * changed; the other values weren't recomputed). ++ * If this pipe isn't active already, we're going to be enabling it ++ * very soon. Since it's safe to update a pipe's ddb allocation while ++ * the pipe's shut off, just do so here. Already active pipes will have ++ * their watermarks updated once we update their planes. + */ +- for_each_pipe_masked(dev_priv, pipe, results->dirty_pipes) +- skl_copy_wm_for_pipe(hw_vals, results, pipe); ++ if (crtc->state->active_changed) { ++ int plane; ++ ++ for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) ++ skl_write_plane_wm(intel_crtc, results, plane); ++ ++ skl_write_cursor_wm(intel_crtc, results); ++ } ++ ++ skl_copy_wm_for_pipe(hw_vals, results, pipe); + + mutex_unlock(&dev_priv->wm.wm_mutex); + } +diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c +index 7c08e4f..4178849 100644 +--- a/drivers/gpu/drm/i915/intel_sprite.c ++++ b/drivers/gpu/drm/i915/intel_sprite.c +@@ -203,6 +203,9 @@ skl_update_plane(struct drm_plane *drm_plane, + struct intel_plane *intel_plane = to_intel_plane(drm_plane); + struct drm_framebuffer *fb = plane_state->base.fb; + struct drm_i915_gem_object *obj = intel_fb_obj(fb); ++ const struct skl_wm_values *wm = &dev_priv->wm.skl_results; ++ struct drm_crtc *crtc = crtc_state->base.crtc; ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + const int pipe = intel_plane->pipe; + const int plane = intel_plane->plane + 1; + u32 plane_ctl, stride_div, stride; +@@ -238,6 +241,9 @@ skl_update_plane(struct drm_plane *drm_plane, + crtc_w--; + crtc_h--; + ++ if (wm->dirty_pipes & drm_crtc_mask(crtc)) ++ skl_write_plane_wm(intel_crtc, wm, plane); ++ + if (key->flags) { + I915_WRITE(PLANE_KEYVAL(pipe, plane), key->min_value); + I915_WRITE(PLANE_KEYMAX(pipe, plane), key->max_value); +@@ -308,6 +314,14 @@ skl_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc) + const int pipe = intel_plane->pipe; + const int plane = intel_plane->plane + 1; + ++ /* ++ * We only populate skl_results on watermark updates, and if the ++ * plane's visiblity isn't actually changing neither is its watermarks. ++ */ ++ if (!to_intel_plane_state(dplane->state)->visible) ++ skl_write_plane_wm(to_intel_crtc(crtc), ++ &dev_priv->wm.skl_results, plane); ++ + I915_WRITE(PLANE_CTL(pipe, plane), 0); + + I915_WRITE(PLANE_SURF(pipe, plane), 0); +diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c +index ff80a81..ec28b15 100644 +--- a/drivers/gpu/drm/i915/intel_uncore.c ++++ b/drivers/gpu/drm/i915/intel_uncore.c +@@ -796,10 +796,9 @@ __unclaimed_reg_debug(struct drm_i915_private *dev_priv, + const bool read, + const bool before) + { +- if (WARN(check_for_unclaimed_mmio(dev_priv), +- "Unclaimed register detected %s %s register 0x%x\n", +- before ? "before" : "after", +- read ? "reading" : "writing to", ++ if (WARN(check_for_unclaimed_mmio(dev_priv) && !before, ++ "Unclaimed %s register 0x%x\n", ++ read ? "read from" : "write to", + i915_mmio_reg_offset(reg))) + i915.mmio_debug--; /* Only report the first N failures */ + } +diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c +index 6a4b020..5a26eb4 100644 +--- a/drivers/gpu/drm/radeon/r600_dpm.c ++++ b/drivers/gpu/drm/radeon/r600_dpm.c +@@ -156,19 +156,20 @@ u32 r600_dpm_get_vblank_time(struct radeon_device *rdev) + struct drm_device *dev = rdev->ddev; + struct drm_crtc *crtc; + struct radeon_crtc *radeon_crtc; +- u32 line_time_us, vblank_lines; ++ u32 vblank_in_pixels; + u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */ + + if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) { + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + radeon_crtc = to_radeon_crtc(crtc); + if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) { +- line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) / +- radeon_crtc->hw_mode.clock; +- vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end - +- radeon_crtc->hw_mode.crtc_vdisplay + +- (radeon_crtc->v_border * 2); +- vblank_time_us = vblank_lines * line_time_us; ++ vblank_in_pixels = ++ radeon_crtc->hw_mode.crtc_htotal * ++ (radeon_crtc->hw_mode.crtc_vblank_end - ++ radeon_crtc->hw_mode.crtc_vdisplay + ++ (radeon_crtc->v_border * 2)); ++ ++ vblank_time_us = vblank_in_pixels * 1000 / radeon_crtc->hw_mode.clock; + break; + } + } +diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c +index a00dd2f..554ca71 100644 +--- a/drivers/gpu/drm/radeon/radeon_device.c ++++ b/drivers/gpu/drm/radeon/radeon_device.c +@@ -661,8 +661,9 @@ bool radeon_card_posted(struct radeon_device *rdev) + { + uint32_t reg; + +- /* for pass through, always force asic_init */ +- if (radeon_device_is_virtual()) ++ /* for pass through, always force asic_init for CI */ ++ if (rdev->family >= CHIP_BONAIRE && ++ radeon_device_is_virtual()) + return false; + + /* required for EFI mode on macbook2,1 which uses an r5xx asic */ +diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c +index 1f78ec2..89bdf20 100644 +--- a/drivers/gpu/drm/radeon/si_dpm.c ++++ b/drivers/gpu/drm/radeon/si_dpm.c +@@ -4112,7 +4112,7 @@ static int si_populate_smc_voltage_tables(struct radeon_device *rdev, + &rdev->pm.dpm.dyn_state.phase_shedding_limits_table)) { + si_populate_smc_voltage_table(rdev, &si_pi->vddc_phase_shed_table, table); + +- table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC] = ++ table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC_PHASE_SHEDDING] = + cpu_to_be32(si_pi->vddc_phase_shed_table.mask_low); + + si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_phase_shedding_delay, +diff --git a/drivers/gpu/drm/radeon/sislands_smc.h b/drivers/gpu/drm/radeon/sislands_smc.h +index 3c77983..966e3a5 100644 +--- a/drivers/gpu/drm/radeon/sislands_smc.h ++++ b/drivers/gpu/drm/radeon/sislands_smc.h +@@ -194,6 +194,7 @@ typedef struct SISLANDS_SMC_SWSTATE SISLANDS_SMC_SWSTATE; + #define SISLANDS_SMC_VOLTAGEMASK_VDDC 0 + #define SISLANDS_SMC_VOLTAGEMASK_MVDD 1 + #define SISLANDS_SMC_VOLTAGEMASK_VDDCI 2 ++#define SISLANDS_SMC_VOLTAGEMASK_VDDC_PHASE_SHEDDING 3 + #define SISLANDS_SMC_VOLTAGEMASK_MAX 4 + + struct SISLANDS_SMC_VOLTAGEMASKTABLE +diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h +index 428e249..f696b75 100644 +--- a/drivers/gpu/drm/vc4/vc4_drv.h ++++ b/drivers/gpu/drm/vc4/vc4_drv.h +@@ -122,9 +122,16 @@ to_vc4_dev(struct drm_device *dev) + struct vc4_bo { + struct drm_gem_cma_object base; + +- /* seqno of the last job to render to this BO. */ ++ /* seqno of the last job to render using this BO. */ + uint64_t seqno; + ++ /* seqno of the last job to use the RCL to write to this BO. ++ * ++ * Note that this doesn't include binner overflow memory ++ * writes. ++ */ ++ uint64_t write_seqno; ++ + /* List entry for the BO's position in either + * vc4_exec_info->unref_list or vc4_dev->bo_cache.time_list + */ +@@ -216,6 +223,9 @@ struct vc4_exec_info { + /* Sequence number for this bin/render job. */ + uint64_t seqno; + ++ /* Latest write_seqno of any BO that binning depends on. */ ++ uint64_t bin_dep_seqno; ++ + /* Last current addresses the hardware was processing when the + * hangcheck timer checked on us. + */ +@@ -230,6 +240,13 @@ struct vc4_exec_info { + struct drm_gem_cma_object **bo; + uint32_t bo_count; + ++ /* List of BOs that are being written by the RCL. Other than ++ * the binner temporary storage, this is all the BOs written ++ * by the job. ++ */ ++ struct drm_gem_cma_object *rcl_write_bo[4]; ++ uint32_t rcl_write_bo_count; ++ + /* Pointers for our position in vc4->job_list */ + struct list_head head; + +diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c +index b262c5c..ae1609e 100644 +--- a/drivers/gpu/drm/vc4/vc4_gem.c ++++ b/drivers/gpu/drm/vc4/vc4_gem.c +@@ -471,6 +471,11 @@ vc4_update_bo_seqnos(struct vc4_exec_info *exec, uint64_t seqno) + list_for_each_entry(bo, &exec->unref_list, unref_head) { + bo->seqno = seqno; + } ++ ++ for (i = 0; i < exec->rcl_write_bo_count; i++) { ++ bo = to_vc4_bo(&exec->rcl_write_bo[i]->base); ++ bo->write_seqno = seqno; ++ } + } + + /* Queues a struct vc4_exec_info for execution. If no job is +@@ -673,6 +678,14 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec) + goto fail; + + ret = vc4_validate_shader_recs(dev, exec); ++ if (ret) ++ goto fail; ++ ++ /* Block waiting on any previous rendering into the CS's VBO, ++ * IB, or textures, so that pixels are actually written by the ++ * time we try to read them. ++ */ ++ ret = vc4_wait_for_seqno(dev, exec->bin_dep_seqno, ~0ull, true); + + fail: + drm_free_large(temp); +diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c +index 0f12418..08886a3 100644 +--- a/drivers/gpu/drm/vc4/vc4_render_cl.c ++++ b/drivers/gpu/drm/vc4/vc4_render_cl.c +@@ -45,6 +45,8 @@ struct vc4_rcl_setup { + + struct drm_gem_cma_object *rcl; + u32 next_offset; ++ ++ u32 next_write_bo_index; + }; + + static inline void rcl_u8(struct vc4_rcl_setup *setup, u8 val) +@@ -407,6 +409,8 @@ static int vc4_rcl_msaa_surface_setup(struct vc4_exec_info *exec, + if (!*obj) + return -EINVAL; + ++ exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj; ++ + if (surf->offset & 0xf) { + DRM_ERROR("MSAA write must be 16b aligned.\n"); + return -EINVAL; +@@ -417,7 +421,8 @@ static int vc4_rcl_msaa_surface_setup(struct vc4_exec_info *exec, + + static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, + struct drm_gem_cma_object **obj, +- struct drm_vc4_submit_rcl_surface *surf) ++ struct drm_vc4_submit_rcl_surface *surf, ++ bool is_write) + { + uint8_t tiling = VC4_GET_FIELD(surf->bits, + VC4_LOADSTORE_TILE_BUFFER_TILING); +@@ -440,6 +445,9 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, + if (!*obj) + return -EINVAL; + ++ if (is_write) ++ exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj; ++ + if (surf->flags & VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) { + if (surf == &exec->args->zs_write) { + DRM_ERROR("general zs write may not be a full-res.\n"); +@@ -542,6 +550,8 @@ vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec, + if (!*obj) + return -EINVAL; + ++ exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj; ++ + if (tiling > VC4_TILING_FORMAT_LT) { + DRM_ERROR("Bad tiling format\n"); + return -EINVAL; +@@ -599,15 +609,18 @@ int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec) + if (ret) + return ret; + +- ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read); ++ ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read, ++ false); + if (ret) + return ret; + +- ret = vc4_rcl_surface_setup(exec, &setup.zs_read, &args->zs_read); ++ ret = vc4_rcl_surface_setup(exec, &setup.zs_read, &args->zs_read, ++ false); + if (ret) + return ret; + +- ret = vc4_rcl_surface_setup(exec, &setup.zs_write, &args->zs_write); ++ ret = vc4_rcl_surface_setup(exec, &setup.zs_write, &args->zs_write, ++ true); + if (ret) + return ret; + +diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c +index 9ce1d0a..26503e3 100644 +--- a/drivers/gpu/drm/vc4/vc4_validate.c ++++ b/drivers/gpu/drm/vc4/vc4_validate.c +@@ -267,6 +267,9 @@ validate_indexed_prim_list(VALIDATE_ARGS) + if (!ib) + return -EINVAL; + ++ exec->bin_dep_seqno = max(exec->bin_dep_seqno, ++ to_vc4_bo(&ib->base)->write_seqno); ++ + if (offset > ib->base.size || + (ib->base.size - offset) / index_size < length) { + DRM_ERROR("IB access overflow (%d + %d*%d > %zd)\n", +@@ -555,8 +558,7 @@ static bool + reloc_tex(struct vc4_exec_info *exec, + void *uniform_data_u, + struct vc4_texture_sample_info *sample, +- uint32_t texture_handle_index) +- ++ uint32_t texture_handle_index, bool is_cs) + { + struct drm_gem_cma_object *tex; + uint32_t p0 = *(uint32_t *)(uniform_data_u + sample->p_offset[0]); +@@ -714,6 +716,11 @@ reloc_tex(struct vc4_exec_info *exec, + + *validated_p0 = tex->paddr + p0; + ++ if (is_cs) { ++ exec->bin_dep_seqno = max(exec->bin_dep_seqno, ++ to_vc4_bo(&tex->base)->write_seqno); ++ } ++ + return true; + fail: + DRM_INFO("Texture p0 at %d: 0x%08x\n", sample->p_offset[0], p0); +@@ -835,7 +842,8 @@ validate_gl_shader_rec(struct drm_device *dev, + if (!reloc_tex(exec, + uniform_data_u, + &validated_shader->texture_samples[tex], +- texture_handles_u[tex])) { ++ texture_handles_u[tex], ++ i == 2)) { + return -EINVAL; + } + } +@@ -867,6 +875,9 @@ validate_gl_shader_rec(struct drm_device *dev, + uint32_t stride = *(uint8_t *)(pkt_u + o + 5); + uint32_t max_index; + ++ exec->bin_dep_seqno = max(exec->bin_dep_seqno, ++ to_vc4_bo(&vbo->base)->write_seqno); ++ + if (state->addr & 0x8) + stride |= (*(uint32_t *)(pkt_u + 100 + i * 4)) & ~0xff; + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +index dc5beff..8a15c4a 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +@@ -34,6 +34,24 @@ + + #define VMW_RES_HT_ORDER 12 + ++ /** ++ * enum vmw_resource_relocation_type - Relocation type for resources ++ * ++ * @vmw_res_rel_normal: Traditional relocation. The resource id in the ++ * command stream is replaced with the actual id after validation. ++ * @vmw_res_rel_nop: NOP relocation. The command is unconditionally replaced ++ * with a NOP. ++ * @vmw_res_rel_cond_nop: Conditional NOP relocation. If the resource id ++ * after validation is -1, the command is replaced with a NOP. Otherwise no ++ * action. ++ */ ++enum vmw_resource_relocation_type { ++ vmw_res_rel_normal, ++ vmw_res_rel_nop, ++ vmw_res_rel_cond_nop, ++ vmw_res_rel_max ++}; ++ + /** + * struct vmw_resource_relocation - Relocation info for resources + * +@@ -41,11 +59,13 @@ + * @res: Non-ref-counted pointer to the resource. + * @offset: Offset of 4 byte entries into the command buffer where the + * id that needs fixup is located. ++ * @rel_type: Type of relocation. + */ + struct vmw_resource_relocation { + struct list_head head; + const struct vmw_resource *res; +- unsigned long offset; ++ u32 offset:29; ++ enum vmw_resource_relocation_type rel_type:3; + }; + + /** +@@ -410,10 +430,13 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, + * @res: The resource. + * @offset: Offset into the command buffer currently being parsed where the + * id that needs fixup is located. Granularity is 4 bytes. ++ * @rel_type: Relocation type. + */ + static int vmw_resource_relocation_add(struct list_head *list, + const struct vmw_resource *res, +- unsigned long offset) ++ unsigned long offset, ++ enum vmw_resource_relocation_type ++ rel_type) + { + struct vmw_resource_relocation *rel; + +@@ -425,6 +448,7 @@ static int vmw_resource_relocation_add(struct list_head *list, + + rel->res = res; + rel->offset = offset; ++ rel->rel_type = rel_type; + list_add_tail(&rel->head, list); + + return 0; +@@ -459,11 +483,23 @@ static void vmw_resource_relocations_apply(uint32_t *cb, + { + struct vmw_resource_relocation *rel; + ++ /* Validate the struct vmw_resource_relocation member size */ ++ BUILD_BUG_ON(SVGA_CB_MAX_SIZE >= (1 << 29)); ++ BUILD_BUG_ON(vmw_res_rel_max >= (1 << 3)); ++ + list_for_each_entry(rel, list, head) { +- if (likely(rel->res != NULL)) ++ switch (rel->rel_type) { ++ case vmw_res_rel_normal: + cb[rel->offset] = rel->res->id; +- else ++ break; ++ case vmw_res_rel_nop: + cb[rel->offset] = SVGA_3D_CMD_NOP; ++ break; ++ default: ++ if (rel->res->id == -1) ++ cb[rel->offset] = SVGA_3D_CMD_NOP; ++ break; ++ } + } + } + +@@ -655,7 +691,8 @@ static int vmw_cmd_res_reloc_add(struct vmw_private *dev_priv, + *p_val = NULL; + ret = vmw_resource_relocation_add(&sw_context->res_relocations, + res, +- id_loc - sw_context->buf_start); ++ id_loc - sw_context->buf_start, ++ vmw_res_rel_normal); + if (unlikely(ret != 0)) + return ret; + +@@ -721,7 +758,8 @@ vmw_cmd_res_check(struct vmw_private *dev_priv, + + return vmw_resource_relocation_add + (&sw_context->res_relocations, res, +- id_loc - sw_context->buf_start); ++ id_loc - sw_context->buf_start, ++ vmw_res_rel_normal); + } + + ret = vmw_user_resource_lookup_handle(dev_priv, +@@ -2144,7 +2182,8 @@ static int vmw_cmd_shader_define(struct vmw_private *dev_priv, + + return vmw_resource_relocation_add(&sw_context->res_relocations, + NULL, &cmd->header.id - +- sw_context->buf_start); ++ sw_context->buf_start, ++ vmw_res_rel_nop); + + return 0; + } +@@ -2189,7 +2228,8 @@ static int vmw_cmd_shader_destroy(struct vmw_private *dev_priv, + + return vmw_resource_relocation_add(&sw_context->res_relocations, + NULL, &cmd->header.id - +- sw_context->buf_start); ++ sw_context->buf_start, ++ vmw_res_rel_nop); + + return 0; + } +@@ -2848,8 +2888,7 @@ static int vmw_cmd_dx_cid_check(struct vmw_private *dev_priv, + * @header: Pointer to the command header in the command stream. + * + * Check that the view exists, and if it was not created using this +- * command batch, make sure it's validated (present in the device) so that +- * the remove command will not confuse the device. ++ * command batch, conditionally make this command a NOP. + */ + static int vmw_cmd_dx_view_remove(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, +@@ -2877,10 +2916,15 @@ static int vmw_cmd_dx_view_remove(struct vmw_private *dev_priv, + return ret; + + /* +- * Add view to the validate list iff it was not created using this +- * command batch. ++ * If the view wasn't created during this command batch, it might ++ * have been removed due to a context swapout, so add a ++ * relocation to conditionally make this command a NOP to avoid ++ * device errors. + */ +- return vmw_view_res_val_add(sw_context, view); ++ return vmw_resource_relocation_add(&sw_context->res_relocations, ++ view, ++ &cmd->header.id - sw_context->buf_start, ++ vmw_res_rel_cond_nop); + } + + /** +@@ -3848,14 +3892,14 @@ static void *vmw_execbuf_cmdbuf(struct vmw_private *dev_priv, + int ret; + + *header = NULL; +- if (!dev_priv->cman || kernel_commands) +- return kernel_commands; +- + if (command_size > SVGA_CB_MAX_SIZE) { + DRM_ERROR("Command buffer is too large.\n"); + return ERR_PTR(-EINVAL); + } + ++ if (!dev_priv->cman || kernel_commands) ++ return kernel_commands; ++ + /* If possible, add a little space for fencing. */ + cmdbuf_size = command_size + 512; + cmdbuf_size = min_t(size_t, cmdbuf_size, SVGA_CB_MAX_SIZE); +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 4ed9a4f..e92b09d 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -64,6 +64,9 @@ + #define USB_VENDOR_ID_AKAI 0x2011 + #define USB_DEVICE_ID_AKAI_MPKMINI2 0x0715 + ++#define USB_VENDOR_ID_AKAI_09E8 0x09E8 ++#define USB_DEVICE_ID_AKAI_09E8_MIDIMIX 0x0031 ++ + #define USB_VENDOR_ID_ALCOR 0x058f + #define USB_DEVICE_ID_ALCOR_USBRS232 0x9720 + +diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c +index b4b8c6a..bb40008 100644 +--- a/drivers/hid/usbhid/hid-quirks.c ++++ b/drivers/hid/usbhid/hid-quirks.c +@@ -56,6 +56,7 @@ static const struct hid_blacklist { + + { USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2, HID_QUIRK_NO_INIT_REPORTS }, ++ { USB_VENDOR_ID_AKAI_09E8, USB_DEVICE_ID_AKAI_09E8_MIDIMIX, HID_QUIRK_NO_INIT_REPORTS }, + { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, +diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c +index 9e02ac9..3978cbb 100644 +--- a/drivers/hwtracing/coresight/coresight-tmc.c ++++ b/drivers/hwtracing/coresight/coresight-tmc.c +@@ -388,9 +388,6 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) + err_misc_register: + coresight_unregister(drvdata->csdev); + err_devm_kzalloc: +- if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) +- dma_free_coherent(dev, drvdata->size, +- drvdata->vaddr, drvdata->paddr); + return ret; + } + +diff --git a/drivers/iio/dac/ad5755.c b/drivers/iio/dac/ad5755.c +index 0fde593..5f79682 100644 +--- a/drivers/iio/dac/ad5755.c ++++ b/drivers/iio/dac/ad5755.c +@@ -655,7 +655,7 @@ static struct ad5755_platform_data *ad5755_parse_dt(struct device *dev) + + devnr = 0; + for_each_child_of_node(np, pp) { +- if (devnr > AD5755_NUM_CHANNELS) { ++ if (devnr >= AD5755_NUM_CHANNELS) { + dev_err(dev, + "There is to many channels defined in DT\n"); + goto error_out; +diff --git a/drivers/iio/light/us5182d.c b/drivers/iio/light/us5182d.c +index 20c40f7..18cf2e2 100644 +--- a/drivers/iio/light/us5182d.c ++++ b/drivers/iio/light/us5182d.c +@@ -894,7 +894,7 @@ static int us5182d_probe(struct i2c_client *client, + goto out_err; + + if (data->default_continuous) { +- pm_runtime_set_active(&client->dev); ++ ret = pm_runtime_set_active(&client->dev); + if (ret < 0) + goto out_err; + } +diff --git a/drivers/infiniband/hw/hfi1/qp.c b/drivers/infiniband/hw/hfi1/qp.c +index 4e4d831..c17c9dd 100644 +--- a/drivers/infiniband/hw/hfi1/qp.c ++++ b/drivers/infiniband/hw/hfi1/qp.c +@@ -808,6 +808,13 @@ void *qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp, + kfree(priv); + return ERR_PTR(-ENOMEM); + } ++ iowait_init( ++ &priv->s_iowait, ++ 1, ++ _hfi1_do_send, ++ iowait_sleep, ++ iowait_wakeup, ++ iowait_sdma_drained); + setup_timer(&priv->s_rnr_timer, hfi1_rc_rnr_retry, (unsigned long)qp); + qp->s_timer.function = hfi1_rc_timeout; + return priv; +@@ -873,13 +880,6 @@ void notify_qp_reset(struct rvt_qp *qp) + { + struct hfi1_qp_priv *priv = qp->priv; + +- iowait_init( +- &priv->s_iowait, +- 1, +- _hfi1_do_send, +- iowait_sleep, +- iowait_wakeup, +- iowait_sdma_drained); + priv->r_adefered = 0; + clear_ahg(qp); + } +diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c +index e19537c..bff8707a 100644 +--- a/drivers/infiniband/hw/mlx5/main.c ++++ b/drivers/infiniband/hw/mlx5/main.c +@@ -1843,6 +1843,7 @@ static struct mlx5_ib_flow_handler *create_leftovers_rule(struct mlx5_ib_dev *de + &leftovers_specs[LEFTOVERS_UC].flow_attr, + dst); + if (IS_ERR(handler_ucast)) { ++ mlx5_del_flow_rule(handler->rule); + kfree(handler); + handler = handler_ucast; + } else { +diff --git a/drivers/infiniband/hw/qib/qib.h b/drivers/infiniband/hw/qib/qib.h +index bbf0a16..54bb655f 100644 +--- a/drivers/infiniband/hw/qib/qib.h ++++ b/drivers/infiniband/hw/qib/qib.h +@@ -1131,7 +1131,6 @@ extern spinlock_t qib_devs_lock; + extern struct qib_devdata *qib_lookup(int unit); + extern u32 qib_cpulist_count; + extern unsigned long *qib_cpulist; +-extern u16 qpt_mask; + extern unsigned qib_cc_table_size; + + int qib_init(struct qib_devdata *, int); +diff --git a/drivers/infiniband/hw/qib/qib_qp.c b/drivers/infiniband/hw/qib/qib_qp.c +index f9b8cd2..99d31ef 100644 +--- a/drivers/infiniband/hw/qib/qib_qp.c ++++ b/drivers/infiniband/hw/qib/qib_qp.c +@@ -41,14 +41,6 @@ + + #include "qib.h" + +-/* +- * mask field which was present in now deleted qib_qpn_table +- * is not present in rvt_qpn_table. Defining the same field +- * as qpt_mask here instead of adding the mask field to +- * rvt_qpn_table. +- */ +-u16 qpt_mask; +- + static inline unsigned mk_qpn(struct rvt_qpn_table *qpt, + struct rvt_qpn_map *map, unsigned off) + { +@@ -57,7 +49,7 @@ static inline unsigned mk_qpn(struct rvt_qpn_table *qpt, + + static inline unsigned find_next_offset(struct rvt_qpn_table *qpt, + struct rvt_qpn_map *map, unsigned off, +- unsigned n) ++ unsigned n, u16 qpt_mask) + { + if (qpt_mask) { + off++; +@@ -179,6 +171,7 @@ int qib_alloc_qpn(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt, + struct qib_ibdev *verbs_dev = container_of(rdi, struct qib_ibdev, rdi); + struct qib_devdata *dd = container_of(verbs_dev, struct qib_devdata, + verbs_dev); ++ u16 qpt_mask = dd->qpn_mask; + + if (type == IB_QPT_SMI || type == IB_QPT_GSI) { + unsigned n; +@@ -215,7 +208,7 @@ int qib_alloc_qpn(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt, + goto bail; + } + offset = find_next_offset(qpt, map, offset, +- dd->n_krcv_queues); ++ dd->n_krcv_queues, qpt_mask); + qpn = mk_qpn(qpt, map, offset); + /* + * This test differs from alloc_pidmap(). +diff --git a/drivers/infiniband/hw/qib/qib_verbs.c b/drivers/infiniband/hw/qib/qib_verbs.c +index fd1dfbc..b2b845f 100644 +--- a/drivers/infiniband/hw/qib/qib_verbs.c ++++ b/drivers/infiniband/hw/qib/qib_verbs.c +@@ -1606,8 +1606,6 @@ int qib_register_ib_device(struct qib_devdata *dd) + /* Only need to initialize non-zero fields. */ + setup_timer(&dev->mem_timer, mem_timer, (unsigned long)dev); + +- qpt_mask = dd->qpn_mask; +- + INIT_LIST_HEAD(&dev->piowait); + INIT_LIST_HEAD(&dev->dmawait); + INIT_LIST_HEAD(&dev->txwait); +diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c +index 870b4f2..5911c53 100644 +--- a/drivers/infiniband/sw/rdmavt/qp.c ++++ b/drivers/infiniband/sw/rdmavt/qp.c +@@ -501,12 +501,9 @@ static void rvt_remove_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp) + */ + static void rvt_reset_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp, + enum ib_qp_type type) +- __releases(&qp->s_lock) +- __releases(&qp->s_hlock) +- __releases(&qp->r_lock) +- __acquires(&qp->r_lock) +- __acquires(&qp->s_hlock) +- __acquires(&qp->s_lock) ++ __must_hold(&qp->r_lock) ++ __must_hold(&qp->s_hlock) ++ __must_hold(&qp->s_lock) + { + if (qp->state != IB_QPS_RESET) { + qp->state = IB_QPS_RESET; +diff --git a/drivers/net/ethernet/intel/i40e/i40e_client.c b/drivers/net/ethernet/intel/i40e/i40e_client.c +index 618f184..c65e17f 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_client.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_client.c +@@ -1009,7 +1009,6 @@ int i40e_unregister_client(struct i40e_client *client) + if (!i40e_client_is_registered(client)) { + pr_info("i40e: Client %s has not been registered\n", + client->name); +- mutex_unlock(&i40e_client_mutex); + ret = -ENODEV; + goto out; + } +diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c +index dad15b6..c74d164 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -7990,45 +7990,34 @@ static int i40e_setup_misc_vector(struct i40e_pf *pf) + static int i40e_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed, + u8 *lut, u16 lut_size) + { +- struct i40e_aqc_get_set_rss_key_data rss_key; + struct i40e_pf *pf = vsi->back; + struct i40e_hw *hw = &pf->hw; +- bool pf_lut = false; +- u8 *rss_lut; +- int ret, i; +- +- memcpy(&rss_key, seed, sizeof(rss_key)); +- +- rss_lut = kzalloc(pf->rss_table_size, GFP_KERNEL); +- if (!rss_lut) +- return -ENOMEM; +- +- /* Populate the LUT with max no. of queues in round robin fashion */ +- for (i = 0; i < vsi->rss_table_size; i++) +- rss_lut[i] = i % vsi->rss_size; ++ int ret = 0; + +- ret = i40e_aq_set_rss_key(hw, vsi->id, &rss_key); +- if (ret) { +- dev_info(&pf->pdev->dev, +- "Cannot set RSS key, err %s aq_err %s\n", +- i40e_stat_str(&pf->hw, ret), +- i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); +- goto config_rss_aq_out; ++ if (seed) { ++ struct i40e_aqc_get_set_rss_key_data *seed_dw = ++ (struct i40e_aqc_get_set_rss_key_data *)seed; ++ ret = i40e_aq_set_rss_key(hw, vsi->id, seed_dw); ++ if (ret) { ++ dev_info(&pf->pdev->dev, ++ "Cannot set RSS key, err %s aq_err %s\n", ++ i40e_stat_str(hw, ret), ++ i40e_aq_str(hw, hw->aq.asq_last_status)); ++ return ret; ++ } + } ++ if (lut) { ++ bool pf_lut = vsi->type == I40E_VSI_MAIN ? true : false; + +- if (vsi->type == I40E_VSI_MAIN) +- pf_lut = true; +- +- ret = i40e_aq_set_rss_lut(hw, vsi->id, pf_lut, rss_lut, +- vsi->rss_table_size); +- if (ret) +- dev_info(&pf->pdev->dev, +- "Cannot set RSS lut, err %s aq_err %s\n", +- i40e_stat_str(&pf->hw, ret), +- i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); +- +-config_rss_aq_out: +- kfree(rss_lut); ++ ret = i40e_aq_set_rss_lut(hw, vsi->id, pf_lut, lut, lut_size); ++ if (ret) { ++ dev_info(&pf->pdev->dev, ++ "Cannot set RSS lut, err %s aq_err %s\n", ++ i40e_stat_str(hw, ret), ++ i40e_aq_str(hw, hw->aq.asq_last_status)); ++ return ret; ++ } ++ } + return ret; + } + +diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c +index 24c8d65..09ca634 100644 +--- a/drivers/net/wireless/ath/ath10k/htt_rx.c ++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c +@@ -2394,6 +2394,8 @@ static void ath10k_htt_txrx_compl_task(unsigned long ptr) + skb_queue_splice_init(&htt->rx_in_ord_compl_q, &rx_ind_q); + spin_unlock_irqrestore(&htt->rx_in_ord_compl_q.lock, flags); + ++ ath10k_mac_tx_push_pending(ar); ++ + spin_lock_irqsave(&htt->tx_fetch_ind_q.lock, flags); + skb_queue_splice_init(&htt->tx_fetch_ind_q, &tx_ind_q); + spin_unlock_irqrestore(&htt->tx_fetch_ind_q.lock, flags); +diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c +index 0bbd0a0..146365b 100644 +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -3777,7 +3777,9 @@ int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw, + enum ath10k_hw_txrx_mode txmode; + enum ath10k_mac_tx_path txpath; + struct sk_buff *skb; ++ struct ieee80211_hdr *hdr; + size_t skb_len; ++ bool is_mgmt, is_presp; + int ret; + + spin_lock_bh(&ar->htt.tx_lock); +@@ -3801,6 +3803,22 @@ int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw, + skb_len = skb->len; + txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb); + txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode); ++ is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT); ++ ++ if (is_mgmt) { ++ hdr = (struct ieee80211_hdr *)skb->data; ++ is_presp = ieee80211_is_probe_resp(hdr->frame_control); ++ ++ spin_lock_bh(&ar->htt.tx_lock); ++ ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp); ++ ++ if (ret) { ++ ath10k_htt_tx_dec_pending(htt); ++ spin_unlock_bh(&ar->htt.tx_lock); ++ return ret; ++ } ++ spin_unlock_bh(&ar->htt.tx_lock); ++ } + + ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb); + if (unlikely(ret)) { +@@ -3808,6 +3826,8 @@ int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw, + + spin_lock_bh(&ar->htt.tx_lock); + ath10k_htt_tx_dec_pending(htt); ++ if (is_mgmt) ++ ath10k_htt_tx_mgmt_dec_pending(htt); + spin_unlock_bh(&ar->htt.tx_lock); + + return ret; +@@ -6538,7 +6558,7 @@ static int ath10k_get_survey(struct ieee80211_hw *hw, int idx, + goto exit; + } + +- ath10k_mac_update_bss_chan_survey(ar, survey->channel); ++ ath10k_mac_update_bss_chan_survey(ar, &sband->channels[idx]); + + spin_lock_bh(&ar->data_lock); + memcpy(survey, ar_survey, sizeof(*survey)); +diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c +index b29a86a..28ff5cb 100644 +--- a/drivers/net/wireless/ath/ath10k/txrx.c ++++ b/drivers/net/wireless/ath/ath10k/txrx.c +@@ -119,8 +119,6 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt, + ieee80211_tx_status(htt->ar->hw, msdu); + /* we do not own the msdu anymore */ + +- ath10k_mac_tx_push_pending(ar); +- + return 0; + } + +diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h +index 3ef4688..f67cc19 100644 +--- a/drivers/net/wireless/ath/ath10k/wmi.h ++++ b/drivers/net/wireless/ath/ath10k/wmi.h +@@ -180,6 +180,7 @@ enum wmi_service { + WMI_SERVICE_MESH_NON_11S, + WMI_SERVICE_PEER_STATS, + WMI_SERVICE_RESTRT_CHNL_SUPPORT, ++ WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT, + WMI_SERVICE_TX_MODE_PUSH_ONLY, + WMI_SERVICE_TX_MODE_PUSH_PULL, + WMI_SERVICE_TX_MODE_DYNAMIC, +@@ -305,6 +306,7 @@ enum wmi_10_4_service { + WMI_10_4_SERVICE_RESTRT_CHNL_SUPPORT, + WMI_10_4_SERVICE_PEER_STATS, + WMI_10_4_SERVICE_MESH_11S, ++ WMI_10_4_SERVICE_PERIODIC_CHAN_STAT_SUPPORT, + WMI_10_4_SERVICE_TX_MODE_PUSH_ONLY, + WMI_10_4_SERVICE_TX_MODE_PUSH_PULL, + WMI_10_4_SERVICE_TX_MODE_DYNAMIC, +@@ -402,6 +404,7 @@ static inline char *wmi_service_name(int service_id) + SVCSTR(WMI_SERVICE_MESH_NON_11S); + SVCSTR(WMI_SERVICE_PEER_STATS); + SVCSTR(WMI_SERVICE_RESTRT_CHNL_SUPPORT); ++ SVCSTR(WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT); + SVCSTR(WMI_SERVICE_TX_MODE_PUSH_ONLY); + SVCSTR(WMI_SERVICE_TX_MODE_PUSH_PULL); + SVCSTR(WMI_SERVICE_TX_MODE_DYNAMIC); +@@ -652,6 +655,8 @@ static inline void wmi_10_4_svc_map(const __le32 *in, unsigned long *out, + WMI_SERVICE_PEER_STATS, len); + SVCMAP(WMI_10_4_SERVICE_MESH_11S, + WMI_SERVICE_MESH_11S, len); ++ SVCMAP(WMI_10_4_SERVICE_PERIODIC_CHAN_STAT_SUPPORT, ++ WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT, len); + SVCMAP(WMI_10_4_SERVICE_TX_MODE_PUSH_ONLY, + WMI_SERVICE_TX_MODE_PUSH_ONLY, len); + SVCMAP(WMI_10_4_SERVICE_TX_MODE_PUSH_PULL, +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +index 43f8f7d..adba3b0 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +@@ -564,11 +564,16 @@ static void iwl_set_hw_address_from_csr(struct iwl_trans *trans, + __le32 mac_addr0 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR0_STRAP)); + __le32 mac_addr1 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR1_STRAP)); + +- /* If OEM did not fuse address - get it from OTP */ +- if (!mac_addr0 && !mac_addr1) { +- mac_addr0 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR0_OTP)); +- mac_addr1 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR1_OTP)); +- } ++ iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr); ++ /* ++ * If the OEM fused a valid address, use it instead of the one in the ++ * OTP ++ */ ++ if (is_valid_ether_addr(data->hw_addr)) ++ return; ++ ++ mac_addr0 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR0_OTP)); ++ mac_addr1 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR1_OTP)); + + iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr); + } +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +index 7e0cdbf..794c574 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +@@ -1214,9 +1214,12 @@ int iwl_mvm_up(struct iwl_mvm *mvm) + } + + /* TODO: read the budget from BIOS / Platform NVM */ +- if (iwl_mvm_is_ctdp_supported(mvm) && mvm->cooling_dev.cur_state > 0) ++ if (iwl_mvm_is_ctdp_supported(mvm) && mvm->cooling_dev.cur_state > 0) { + ret = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_START, + mvm->cooling_dev.cur_state); ++ if (ret) ++ goto error; ++ } + #else + /* Initialize tx backoffs to the minimal possible */ + iwl_mvm_tt_tx_backoff(mvm, 0); +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +index 69c42ce..d742d27 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +@@ -539,6 +539,11 @@ void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif) + iwl_mvm_disable_txq(mvm, IWL_MVM_OFFCHANNEL_QUEUE, + IWL_MVM_OFFCHANNEL_QUEUE, + IWL_MAX_TID_COUNT, 0); ++ else ++ iwl_mvm_disable_txq(mvm, ++ IWL_MVM_DQA_P2P_DEVICE_QUEUE, ++ vif->hw_queue[0], IWL_MAX_TID_COUNT, ++ 0); + + break; + case NL80211_IFTYPE_AP: +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +index df6c32c..afb7eb6 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +@@ -598,9 +598,10 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm, + + mvm_sta = iwl_mvm_sta_from_mac80211(sta); + +- /* not a data packet */ +- if (!ieee80211_is_data_qos(hdr->frame_control) || +- is_multicast_ether_addr(hdr->addr1)) ++ /* not a data packet or a bar */ ++ if (!ieee80211_is_back_req(hdr->frame_control) && ++ (!ieee80211_is_data_qos(hdr->frame_control) || ++ is_multicast_ether_addr(hdr->addr1))) + return false; + + if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) +@@ -624,6 +625,11 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm, + + spin_lock_bh(&buffer->lock); + ++ if (ieee80211_is_back_req(hdr->frame_control)) { ++ iwl_mvm_release_frames(mvm, sta, napi, buffer, nssn); ++ goto drop; ++ } ++ + /* + * If there was a significant jump in the nssn - adjust. + * If the SN is smaller than the NSSN it might need to first go into +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +index 3130b9c..e933c12 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +@@ -576,9 +576,7 @@ static int iwl_mvm_scd_queue_redirect(struct iwl_mvm *mvm, int queue, int tid, + ret); + + /* Make sure the SCD wrptr is correctly set before reconfiguring */ +- iwl_trans_txq_enable(mvm->trans, queue, iwl_mvm_ac_to_tx_fifo[ac], +- cmd.sta_id, tid, LINK_QUAL_AGG_FRAME_LIMIT_DEF, +- ssn, wdg_timeout); ++ iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, NULL, wdg_timeout); + + /* TODO: Work-around SCD bug when moving back by multiples of 0x40 */ + +@@ -1270,9 +1268,31 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, + ret = iwl_mvm_drain_sta(mvm, mvm_sta, false); + + /* If DQA is supported - the queues can be disabled now */ +- if (iwl_mvm_is_dqa_supported(mvm)) ++ if (iwl_mvm_is_dqa_supported(mvm)) { ++ u8 reserved_txq = mvm_sta->reserved_queue; ++ enum iwl_mvm_queue_status *status; ++ + iwl_mvm_disable_sta_queues(mvm, vif, mvm_sta); + ++ /* ++ * If no traffic has gone through the reserved TXQ - it ++ * is still marked as IWL_MVM_QUEUE_RESERVED, and ++ * should be manually marked as free again ++ */ ++ spin_lock_bh(&mvm->queue_info_lock); ++ status = &mvm->queue_info[reserved_txq].status; ++ if (WARN((*status != IWL_MVM_QUEUE_RESERVED) && ++ (*status != IWL_MVM_QUEUE_FREE), ++ "sta_id %d reserved txq %d status %d", ++ mvm_sta->sta_id, reserved_txq, *status)) { ++ spin_unlock_bh(&mvm->queue_info_lock); ++ return -EINVAL; ++ } ++ ++ *status = IWL_MVM_QUEUE_FREE; ++ spin_unlock_bh(&mvm->queue_info_lock); ++ } ++ + if (vif->type == NL80211_IFTYPE_STATION && + mvmvif->ap_sta_id == mvm_sta->sta_id) { + /* if associated - we can't remove the AP STA now */ +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +index b3a87a3..a0c1e3d 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +@@ -903,9 +903,13 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb, + tid = IWL_MAX_TID_COUNT; + } + +- if (iwl_mvm_is_dqa_supported(mvm)) ++ if (iwl_mvm_is_dqa_supported(mvm)) { + txq_id = mvmsta->tid_data[tid].txq_id; + ++ if (ieee80211_is_mgmt(fc)) ++ tx_cmd->tid_tspec = IWL_TID_NON_QOS; ++ } ++ + /* Copy MAC header from skb into command buffer */ + memcpy(tx_cmd->hdr, hdr, hdrlen); + +diff --git a/drivers/net/wireless/marvell/mwifiex/join.c b/drivers/net/wireless/marvell/mwifiex/join.c +index 1c7b006..b89596c 100644 +--- a/drivers/net/wireless/marvell/mwifiex/join.c ++++ b/drivers/net/wireless/marvell/mwifiex/join.c +@@ -669,9 +669,8 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, + priv->assoc_rsp_size = min(le16_to_cpu(resp->size) - S_DS_GEN, + sizeof(priv->assoc_rsp_buf)); + +- memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size); +- + assoc_rsp->a_id = cpu_to_le16(aid); ++ memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size); + + if (status_code) { + priv->adapter->dbg.num_cmd_assoc_failure++; +diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c +index a422f33..7e394d4 100644 +--- a/drivers/net/wireless/marvell/mwifiex/sta_event.c ++++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c +@@ -708,7 +708,11 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) + + case EVENT_EXT_SCAN_REPORT: + mwifiex_dbg(adapter, EVENT, "event: EXT_SCAN Report\n"); +- if (adapter->ext_scan && !priv->scan_aborting) ++ /* We intend to skip this event during suspend, but handle ++ * it in interface disabled case ++ */ ++ if (adapter->ext_scan && (!priv->scan_aborting || ++ !netif_running(priv->netdev))) + ret = mwifiex_handle_event_ext_scan_report(priv, + adapter->event_skb->data); + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +index 7cf26c6..6005e14 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +@@ -831,8 +831,10 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, + rt2x00dev->anchor = devm_kmalloc(&usb_dev->dev, + sizeof(struct usb_anchor), + GFP_KERNEL); +- if (!rt2x00dev->anchor) ++ if (!rt2x00dev->anchor) { ++ retval = -ENOMEM; + goto exit_free_reg; ++ } + + init_usb_anchor(rt2x00dev->anchor); + return 0; +diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c +index 935866f..a8b6949 100644 +--- a/drivers/nvdimm/bus.c ++++ b/drivers/nvdimm/bus.c +@@ -217,6 +217,8 @@ long nvdimm_clear_poison(struct device *dev, phys_addr_t phys, + return rc; + if (cmd_rc < 0) + return cmd_rc; ++ ++ nvdimm_clear_from_poison_list(nvdimm_bus, phys, len); + return clear_err.cleared; + } + EXPORT_SYMBOL_GPL(nvdimm_clear_poison); +diff --git a/drivers/nvdimm/core.c b/drivers/nvdimm/core.c +index 4d7bbd2..7ceba08 100644 +--- a/drivers/nvdimm/core.c ++++ b/drivers/nvdimm/core.c +@@ -547,11 +547,12 @@ void nvdimm_badblocks_populate(struct nd_region *nd_region, + } + EXPORT_SYMBOL_GPL(nvdimm_badblocks_populate); + +-static int add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length) ++static int add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length, ++ gfp_t flags) + { + struct nd_poison *pl; + +- pl = kzalloc(sizeof(*pl), GFP_KERNEL); ++ pl = kzalloc(sizeof(*pl), flags); + if (!pl) + return -ENOMEM; + +@@ -567,7 +568,7 @@ static int bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length) + struct nd_poison *pl; + + if (list_empty(&nvdimm_bus->poison_list)) +- return add_poison(nvdimm_bus, addr, length); ++ return add_poison(nvdimm_bus, addr, length, GFP_KERNEL); + + /* + * There is a chance this is a duplicate, check for those first. +@@ -587,7 +588,7 @@ static int bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length) + * as any overlapping ranges will get resolved when the list is consumed + * and converted to badblocks + */ +- return add_poison(nvdimm_bus, addr, length); ++ return add_poison(nvdimm_bus, addr, length, GFP_KERNEL); + } + + int nvdimm_bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length) +@@ -602,6 +603,70 @@ int nvdimm_bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length) + } + EXPORT_SYMBOL_GPL(nvdimm_bus_add_poison); + ++void nvdimm_clear_from_poison_list(struct nvdimm_bus *nvdimm_bus, ++ phys_addr_t start, unsigned int len) ++{ ++ struct list_head *poison_list = &nvdimm_bus->poison_list; ++ u64 clr_end = start + len - 1; ++ struct nd_poison *pl, *next; ++ ++ nvdimm_bus_lock(&nvdimm_bus->dev); ++ WARN_ON_ONCE(list_empty(poison_list)); ++ ++ /* ++ * [start, clr_end] is the poison interval being cleared. ++ * [pl->start, pl_end] is the poison_list entry we're comparing ++ * the above interval against. The poison list entry may need ++ * to be modified (update either start or length), deleted, or ++ * split into two based on the overlap characteristics ++ */ ++ ++ list_for_each_entry_safe(pl, next, poison_list, list) { ++ u64 pl_end = pl->start + pl->length - 1; ++ ++ /* Skip intervals with no intersection */ ++ if (pl_end < start) ++ continue; ++ if (pl->start > clr_end) ++ continue; ++ /* Delete completely overlapped poison entries */ ++ if ((pl->start >= start) && (pl_end <= clr_end)) { ++ list_del(&pl->list); ++ kfree(pl); ++ continue; ++ } ++ /* Adjust start point of partially cleared entries */ ++ if ((start <= pl->start) && (clr_end > pl->start)) { ++ pl->length -= clr_end - pl->start + 1; ++ pl->start = clr_end + 1; ++ continue; ++ } ++ /* Adjust pl->length for partial clearing at the tail end */ ++ if ((pl->start < start) && (pl_end <= clr_end)) { ++ /* pl->start remains the same */ ++ pl->length = start - pl->start; ++ continue; ++ } ++ /* ++ * If clearing in the middle of an entry, we split it into ++ * two by modifying the current entry to represent one half of ++ * the split, and adding a new entry for the second half. ++ */ ++ if ((pl->start < start) && (pl_end > clr_end)) { ++ u64 new_start = clr_end + 1; ++ u64 new_len = pl_end - new_start + 1; ++ ++ /* Add new entry covering the right half */ ++ add_poison(nvdimm_bus, new_start, new_len, GFP_NOIO); ++ /* Adjust this entry to cover the left half */ ++ pl->length = start - pl->start; ++ continue; ++ } ++ } ++ nvdimm_bus_unlock(&nvdimm_bus->dev); ++} ++EXPORT_SYMBOL_GPL(nvdimm_clear_from_poison_list); ++ + #ifdef CONFIG_BLK_DEV_INTEGRITY + int nd_integrity_init(struct gendisk *disk, unsigned long meta_size) + { +diff --git a/drivers/pci/host/pci-aardvark.c b/drivers/pci/host/pci-aardvark.c +index ef9893f..4f5e567 100644 +--- a/drivers/pci/host/pci-aardvark.c ++++ b/drivers/pci/host/pci-aardvark.c +@@ -848,7 +848,7 @@ static int advk_pcie_parse_request_of_pci_ranges(struct advk_pcie *pcie) + int err, res_valid = 0; + struct device *dev = &pcie->pdev->dev; + struct device_node *np = dev->of_node; +- struct resource_entry *win; ++ struct resource_entry *win, *tmp; + resource_size_t iobase; + + INIT_LIST_HEAD(&pcie->resources); +@@ -862,7 +862,7 @@ static int advk_pcie_parse_request_of_pci_ranges(struct advk_pcie *pcie) + if (err) + goto out_release_res; + +- resource_list_for_each_entry(win, &pcie->resources) { ++ resource_list_for_each_entry_safe(win, tmp, &pcie->resources) { + struct resource *res = win->res; + + switch (resource_type(res)) { +@@ -874,9 +874,11 @@ static int advk_pcie_parse_request_of_pci_ranges(struct advk_pcie *pcie) + lower_32_bits(res->start), + OB_PCIE_IO); + err = pci_remap_iospace(res, iobase); +- if (err) ++ if (err) { + dev_warn(dev, "error %d: failed to map resource %pR\n", + err, res); ++ resource_list_destroy_entry(win); ++ } + break; + case IORESOURCE_MEM: + advk_pcie_set_ob_win(pcie, 0, +diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c +index 9d9d34e..61eb4d4 100644 +--- a/drivers/pci/host/pci-host-common.c ++++ b/drivers/pci/host/pci-host-common.c +@@ -29,7 +29,7 @@ static int gen_pci_parse_request_of_pci_ranges(struct device *dev, + int err, res_valid = 0; + struct device_node *np = dev->of_node; + resource_size_t iobase; +- struct resource_entry *win; ++ struct resource_entry *win, *tmp; + + err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, &iobase); + if (err) +@@ -39,15 +39,17 @@ static int gen_pci_parse_request_of_pci_ranges(struct device *dev, + if (err) + return err; + +- resource_list_for_each_entry(win, resources) { ++ resource_list_for_each_entry_safe(win, tmp, resources) { + struct resource *res = win->res; + + switch (resource_type(res)) { + case IORESOURCE_IO: + err = pci_remap_iospace(res, iobase); +- if (err) ++ if (err) { + dev_warn(dev, "error %d: failed to map resource %pR\n", + err, res); ++ resource_list_destroy_entry(win); ++ } + break; + case IORESOURCE_MEM: + res_valid |= !(res->flags & IORESOURCE_PREFETCH); +diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c +index 84d650d..7ec1e80 100644 +--- a/drivers/pci/host/pci-tegra.c ++++ b/drivers/pci/host/pci-tegra.c +@@ -621,7 +621,11 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) + if (err < 0) + return err; + +- pci_add_resource_offset(&sys->resources, &pcie->pio, sys->io_offset); ++ err = pci_remap_iospace(&pcie->pio, pcie->io.start); ++ if (!err) ++ pci_add_resource_offset(&sys->resources, &pcie->pio, ++ sys->io_offset); ++ + pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); + pci_add_resource_offset(&sys->resources, &pcie->prefetch, + sys->mem_offset); +@@ -631,7 +635,6 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) + if (err < 0) + return err; + +- pci_remap_iospace(&pcie->pio, pcie->io.start); + return 1; + } + +diff --git a/drivers/pci/host/pci-versatile.c b/drivers/pci/host/pci-versatile.c +index f2344057..b7dc070 100644 +--- a/drivers/pci/host/pci-versatile.c ++++ b/drivers/pci/host/pci-versatile.c +@@ -74,7 +74,7 @@ static int versatile_pci_parse_request_of_pci_ranges(struct device *dev, + int err, mem = 1, res_valid = 0; + struct device_node *np = dev->of_node; + resource_size_t iobase; +- struct resource_entry *win; ++ struct resource_entry *win, *tmp; + + err = of_pci_get_host_bridge_resources(np, 0, 0xff, res, &iobase); + if (err) +@@ -84,15 +84,17 @@ static int versatile_pci_parse_request_of_pci_ranges(struct device *dev, + if (err) + goto out_release_res; + +- resource_list_for_each_entry(win, res) { ++ resource_list_for_each_entry_safe(win, tmp, res) { + struct resource *res = win->res; + + switch (resource_type(res)) { + case IORESOURCE_IO: + err = pci_remap_iospace(res, iobase); +- if (err) ++ if (err) { + dev_warn(dev, "error %d: failed to map resource %pR\n", + err, res); ++ resource_list_destroy_entry(win); ++ } + break; + case IORESOURCE_MEM: + res_valid |= !(res->flags & IORESOURCE_PREFETCH); +diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c +index 12afce1..2a500f2 100644 +--- a/drivers/pci/host/pcie-designware.c ++++ b/drivers/pci/host/pcie-designware.c +@@ -436,7 +436,7 @@ int dw_pcie_host_init(struct pcie_port *pp) + struct resource *cfg_res; + int i, ret; + LIST_HEAD(res); +- struct resource_entry *win; ++ struct resource_entry *win, *tmp; + + cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config"); + if (cfg_res) { +@@ -457,17 +457,20 @@ int dw_pcie_host_init(struct pcie_port *pp) + goto error; + + /* Get the I/O and memory ranges from DT */ +- resource_list_for_each_entry(win, &res) { ++ resource_list_for_each_entry_safe(win, tmp, &res) { + switch (resource_type(win->res)) { + case IORESOURCE_IO: +- pp->io = win->res; +- pp->io->name = "I/O"; +- pp->io_size = resource_size(pp->io); +- pp->io_bus_addr = pp->io->start - win->offset; +- ret = pci_remap_iospace(pp->io, pp->io_base); +- if (ret) ++ ret = pci_remap_iospace(win->res, pp->io_base); ++ if (ret) { + dev_warn(pp->dev, "error %d: failed to map resource %pR\n", +- ret, pp->io); ++ ret, win->res); ++ resource_list_destroy_entry(win); ++ } else { ++ pp->io = win->res; ++ pp->io->name = "I/O"; ++ pp->io_size = resource_size(pp->io); ++ pp->io_bus_addr = pp->io->start - win->offset; ++ } + break; + case IORESOURCE_MEM: + pp->mem = win->res; +diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c +index 65db7a2..5f7fcc9 100644 +--- a/drivers/pci/host/pcie-rcar.c ++++ b/drivers/pci/host/pcie-rcar.c +@@ -945,7 +945,7 @@ static int rcar_pcie_parse_request_of_pci_ranges(struct rcar_pcie *pci) + struct device *dev = pci->dev; + struct device_node *np = dev->of_node; + resource_size_t iobase; +- struct resource_entry *win; ++ struct resource_entry *win, *tmp; + + err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pci->resources, &iobase); + if (err) +@@ -955,14 +955,17 @@ static int rcar_pcie_parse_request_of_pci_ranges(struct rcar_pcie *pci) + if (err) + goto out_release_res; + +- resource_list_for_each_entry(win, &pci->resources) { ++ resource_list_for_each_entry_safe(win, tmp, &pci->resources) { + struct resource *res = win->res; + + if (resource_type(res) == IORESOURCE_IO) { + err = pci_remap_iospace(res, iobase); +- if (err) ++ if (err) { + dev_warn(dev, "error %d: failed to map resource %pR\n", + err, res); ++ ++ resource_list_destroy_entry(win); ++ } + } + } + +diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c +index 51c42d7..775c883 100644 +--- a/drivers/pinctrl/qcom/pinctrl-msm.c ++++ b/drivers/pinctrl/qcom/pinctrl-msm.c +@@ -156,7 +156,7 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev, + spin_lock_irqsave(&pctrl->lock, flags); + + val = readl(pctrl->regs + g->ctl_reg); +- val &= mask; ++ val &= ~mask; + val |= i << g->mux_bit; + writel(val, pctrl->regs + g->ctl_reg); + +diff --git a/drivers/power/bq24257_charger.c b/drivers/power/bq24257_charger.c +index 1fea2c7..6fc31bd 100644 +--- a/drivers/power/bq24257_charger.c ++++ b/drivers/power/bq24257_charger.c +@@ -1068,6 +1068,12 @@ static int bq24257_probe(struct i2c_client *client, + return ret; + } + ++ ret = bq24257_power_supply_init(bq); ++ if (ret < 0) { ++ dev_err(dev, "Failed to register power supply\n"); ++ return ret; ++ } ++ + ret = devm_request_threaded_irq(dev, client->irq, NULL, + bq24257_irq_handler_thread, + IRQF_TRIGGER_FALLING | +@@ -1078,12 +1084,6 @@ static int bq24257_probe(struct i2c_client *client, + return ret; + } + +- ret = bq24257_power_supply_init(bq); +- if (ret < 0) { +- dev_err(dev, "Failed to register power supply\n"); +- return ret; +- } +- + ret = sysfs_create_group(&bq->charger->dev.kobj, &bq24257_attr_group); + if (ret < 0) { + dev_err(dev, "Can't create sysfs entries\n"); +diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c +index 6b1577c..285b400 100644 +--- a/drivers/s390/char/con3270.c ++++ b/drivers/s390/char/con3270.c +@@ -124,7 +124,12 @@ con3270_create_status(struct con3270 *cp) + static void + con3270_update_string(struct con3270 *cp, struct string *s, int nr) + { +- if (s->len >= cp->view.cols - 5) ++ if (s->len < 4) { ++ /* This indicates a bug, but printing a warning would ++ * cause a deadlock. */ ++ return; ++ } ++ if (s->string[s->len - 4] != TO_RA) + return; + raw3270_buffer_address(cp->view.dev, s->string + s->len - 3, + cp->view.cols * (nr + 1)); +@@ -460,11 +465,11 @@ con3270_cline_end(struct con3270 *cp) + cp->cline->len + 4 : cp->view.cols; + s = con3270_alloc_string(cp, size); + memcpy(s->string, cp->cline->string, cp->cline->len); +- if (s->len < cp->view.cols - 5) { ++ if (cp->cline->len < cp->view.cols - 5) { + s->string[s->len - 4] = TO_RA; + s->string[s->len - 1] = 0; + } else { +- while (--size > cp->cline->len) ++ while (--size >= cp->cline->len) + s->string[size] = cp->view.ascebc[' ']; + } + /* Replace cline with allocated line s and reset cline. */ +diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c +index 940e725..1167469 100644 +--- a/drivers/s390/cio/chsc.c ++++ b/drivers/s390/cio/chsc.c +@@ -95,12 +95,13 @@ struct chsc_ssd_area { + int chsc_get_ssd_info(struct subchannel_id schid, struct chsc_ssd_info *ssd) + { + struct chsc_ssd_area *ssd_area; ++ unsigned long flags; + int ccode; + int ret; + int i; + int mask; + +- spin_lock_irq(&chsc_page_lock); ++ spin_lock_irqsave(&chsc_page_lock, flags); + memset(chsc_page, 0, PAGE_SIZE); + ssd_area = chsc_page; + ssd_area->request.length = 0x0010; +@@ -144,7 +145,7 @@ int chsc_get_ssd_info(struct subchannel_id schid, struct chsc_ssd_info *ssd) + ssd->fla[i] = ssd_area->fla[i]; + } + out: +- spin_unlock_irq(&chsc_page_lock); ++ spin_unlock_irqrestore(&chsc_page_lock, flags); + return ret; + } + +@@ -832,9 +833,10 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable) + u32 fmt : 4; + u32 : 16; + } __attribute__ ((packed)) *secm_area; ++ unsigned long flags; + int ret, ccode; + +- spin_lock_irq(&chsc_page_lock); ++ spin_lock_irqsave(&chsc_page_lock, flags); + memset(chsc_page, 0, PAGE_SIZE); + secm_area = chsc_page; + secm_area->request.length = 0x0050; +@@ -864,7 +866,7 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable) + CIO_CRW_EVENT(2, "chsc: secm failed (rc=%04x)\n", + secm_area->response.code); + out: +- spin_unlock_irq(&chsc_page_lock); ++ spin_unlock_irqrestore(&chsc_page_lock, flags); + return ret; + } + +@@ -992,6 +994,7 @@ chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv, + + int chsc_get_channel_measurement_chars(struct channel_path *chp) + { ++ unsigned long flags; + int ccode, ret; + + struct { +@@ -1021,7 +1024,7 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp) + if (!css_chsc_characteristics.scmc || !css_chsc_characteristics.secm) + return -EINVAL; + +- spin_lock_irq(&chsc_page_lock); ++ spin_lock_irqsave(&chsc_page_lock, flags); + memset(chsc_page, 0, PAGE_SIZE); + scmc_area = chsc_page; + scmc_area->request.length = 0x0010; +@@ -1053,7 +1056,7 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp) + chsc_initialize_cmg_chars(chp, scmc_area->cmcv, + (struct cmg_chars *) &scmc_area->data); + out: +- spin_unlock_irq(&chsc_page_lock); ++ spin_unlock_irqrestore(&chsc_page_lock, flags); + return ret; + } + +@@ -1134,6 +1137,7 @@ struct css_chsc_char css_chsc_characteristics; + int __init + chsc_determine_css_characteristics(void) + { ++ unsigned long flags; + int result; + struct { + struct chsc_header request; +@@ -1146,7 +1150,7 @@ chsc_determine_css_characteristics(void) + u32 chsc_char[508]; + } __attribute__ ((packed)) *scsc_area; + +- spin_lock_irq(&chsc_page_lock); ++ spin_lock_irqsave(&chsc_page_lock, flags); + memset(chsc_page, 0, PAGE_SIZE); + scsc_area = chsc_page; + scsc_area->request.length = 0x0010; +@@ -1168,7 +1172,7 @@ chsc_determine_css_characteristics(void) + CIO_CRW_EVENT(2, "chsc: scsc failed (rc=%04x)\n", + scsc_area->response.code); + exit: +- spin_unlock_irq(&chsc_page_lock); ++ spin_unlock_irqrestore(&chsc_page_lock, flags); + return result; + } + +diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c +index 661bb94..228b99e 100644 +--- a/drivers/scsi/cxlflash/main.c ++++ b/drivers/scsi/cxlflash/main.c +@@ -823,17 +823,6 @@ static void notify_shutdown(struct cxlflash_cfg *cfg, bool wait) + } + + /** +- * cxlflash_shutdown() - shutdown handler +- * @pdev: PCI device associated with the host. +- */ +-static void cxlflash_shutdown(struct pci_dev *pdev) +-{ +- struct cxlflash_cfg *cfg = pci_get_drvdata(pdev); +- +- notify_shutdown(cfg, false); +-} +- +-/** + * cxlflash_remove() - PCI entry point to tear down host + * @pdev: PCI device associated with the host. + * +@@ -844,6 +833,11 @@ static void cxlflash_remove(struct pci_dev *pdev) + struct cxlflash_cfg *cfg = pci_get_drvdata(pdev); + ulong lock_flags; + ++ if (!pci_is_enabled(pdev)) { ++ pr_debug("%s: Device is disabled\n", __func__); ++ return; ++ } ++ + /* If a Task Management Function is active, wait for it to complete + * before continuing with remove. + */ +@@ -2685,7 +2679,7 @@ static struct pci_driver cxlflash_driver = { + .id_table = cxlflash_pci_table, + .probe = cxlflash_probe, + .remove = cxlflash_remove, +- .shutdown = cxlflash_shutdown, ++ .shutdown = cxlflash_remove, + .err_handler = &cxlflash_err_handler, + }; + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index cd91a68..4cb7990 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -4701,7 +4701,7 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) + le16_to_cpu(mpi_reply->DevHandle)); + mpt3sas_trigger_scsi(ioc, data.skey, data.asc, data.ascq); + +- if (!(ioc->logging_level & MPT_DEBUG_REPLY) && ++ if ((ioc->logging_level & MPT_DEBUG_REPLY) && + ((scmd->sense_buffer[2] == UNIT_ATTENTION) || + (scmd->sense_buffer[2] == MEDIUM_ERROR) || + (scmd->sense_buffer[2] == HARDWARE_ERROR))) +diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c +index 9e9dadb..eec5e3f 100644 +--- a/drivers/spi/spi-fsl-dspi.c ++++ b/drivers/spi/spi-fsl-dspi.c +@@ -760,7 +760,6 @@ static int dspi_remove(struct platform_device *pdev) + /* Disconnect from the SPI framework */ + clk_disable_unprepare(dspi->clk); + spi_unregister_master(dspi->master); +- spi_master_put(dspi->master); + + return 0; + } +diff --git a/drivers/staging/android/ion/Kconfig b/drivers/staging/android/ion/Kconfig +index 19c1572..800245e 100644 +--- a/drivers/staging/android/ion/Kconfig ++++ b/drivers/staging/android/ion/Kconfig +@@ -36,6 +36,7 @@ config ION_TEGRA + config ION_HISI + tristate "Ion for Hisilicon" + depends on ARCH_HISI && ION ++ select ION_OF + help + Choose this option if you wish to use ion on Hisilicon Platform. + +diff --git a/drivers/staging/ks7010/ks_hostif.c b/drivers/staging/ks7010/ks_hostif.c +index a8822fe..f4cee81 100644 +--- a/drivers/staging/ks7010/ks_hostif.c ++++ b/drivers/staging/ks7010/ks_hostif.c +@@ -69,16 +69,20 @@ inline u32 get_DWORD(struct ks_wlan_private *priv) + return data; + } + +-void ks_wlan_hw_wakeup_task(struct work_struct *work) ++static void ks_wlan_hw_wakeup_task(struct work_struct *work) + { + struct ks_wlan_private *priv = + container_of(work, struct ks_wlan_private, ks_wlan_wakeup_task); + int ps_status = atomic_read(&priv->psstatus.status); ++ long time_left; + + if (ps_status == PS_SNOOZE) { + ks_wlan_hw_wakeup_request(priv); +- if (!wait_for_completion_interruptible_timeout(&priv->psstatus.wakeup_wait, HZ / 50)) { /* 20ms timeout */ +- DPRINTK(1, "wake up timeout !!!\n"); ++ time_left = wait_for_completion_interruptible_timeout( ++ &priv->psstatus.wakeup_wait, ++ msecs_to_jiffies(20)); ++ if (time_left <= 0) { ++ DPRINTK(1, "wake up timeout or interrupted !!!\n"); + schedule_work(&priv->ks_wlan_wakeup_task); + return; + } +@@ -1505,7 +1509,7 @@ void hostif_infrastructure_set_request(struct ks_wlan_private *priv) + ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp)), NULL, NULL, NULL); + } + +-void hostif_infrastructure_set2_request(struct ks_wlan_private *priv) ++static void hostif_infrastructure_set2_request(struct ks_wlan_private *priv) + { + struct hostif_infrastructure_set2_request_t *pp; + uint16_t capability; +diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c +index 7748523..32d3a9c 100644 +--- a/drivers/staging/rtl8188eu/core/rtw_cmd.c ++++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c +@@ -670,13 +670,13 @@ u8 rtw_addbareq_cmd(struct adapter *padapter, u8 tid, u8 *addr) + u8 res = _SUCCESS; + + +- ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); + if (!ph2c) { + res = _FAIL; + goto exit; + } + +- paddbareq_parm = kzalloc(sizeof(struct addBaReq_parm), GFP_KERNEL); ++ paddbareq_parm = kzalloc(sizeof(struct addBaReq_parm), GFP_ATOMIC); + if (!paddbareq_parm) { + kfree(ph2c); + res = _FAIL; +diff --git a/drivers/staging/sm750fb/ddk750_mode.c b/drivers/staging/sm750fb/ddk750_mode.c +index ccb4e06..e29d4bd 100644 +--- a/drivers/staging/sm750fb/ddk750_mode.c ++++ b/drivers/staging/sm750fb/ddk750_mode.c +@@ -63,7 +63,7 @@ static unsigned long displayControlAdjust_SM750LE(mode_parameter_t *pModeParam, + dispControl |= (CRT_DISPLAY_CTRL_CRTSELECT | CRT_DISPLAY_CTRL_RGBBIT); + + /* Set bit 14 of display controller */ +- dispControl = DISPLAY_CTRL_CLOCK_PHASE; ++ dispControl |= DISPLAY_CTRL_CLOCK_PHASE; + + POKE32(CRT_DISPLAY_CTRL, dispControl); + +diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c +index 915facb..e1134a4 100644 +--- a/drivers/uio/uio_dmem_genirq.c ++++ b/drivers/uio/uio_dmem_genirq.c +@@ -229,7 +229,7 @@ static int uio_dmem_genirq_probe(struct platform_device *pdev) + ++uiomem; + } + +- priv->dmem_region_start = i; ++ priv->dmem_region_start = uiomem - &uioinfo->mem[0]; + priv->num_dmem_regions = pdata->num_dynamic_regions; + + for (i = 0; i < pdata->num_dynamic_regions; ++i) { +diff --git a/fs/9p/acl.c b/fs/9p/acl.c +index 5b6a174..b3c2cc7 100644 +--- a/fs/9p/acl.c ++++ b/fs/9p/acl.c +@@ -276,32 +276,26 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler, + switch (handler->flags) { + case ACL_TYPE_ACCESS: + if (acl) { +- umode_t mode = inode->i_mode; +- retval = posix_acl_equiv_mode(acl, &mode); +- if (retval < 0) ++ struct iattr iattr; ++ ++ retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl); ++ if (retval) + goto err_out; +- else { +- struct iattr iattr; +- if (retval == 0) { +- /* +- * ACL can be represented +- * by the mode bits. So don't +- * update ACL. +- */ +- acl = NULL; +- value = NULL; +- size = 0; +- } +- /* Updte the mode bits */ +- iattr.ia_mode = ((mode & S_IALLUGO) | +- (inode->i_mode & ~S_IALLUGO)); +- iattr.ia_valid = ATTR_MODE; +- /* FIXME should we update ctime ? +- * What is the following setxattr update the +- * mode ? ++ if (!acl) { ++ /* ++ * ACL can be represented ++ * by the mode bits. So don't ++ * update ACL. + */ +- v9fs_vfs_setattr_dotl(dentry, &iattr); ++ value = NULL; ++ size = 0; + } ++ iattr.ia_valid = ATTR_MODE; ++ /* FIXME should we update ctime ? ++ * What is the following setxattr update the ++ * mode ? ++ */ ++ v9fs_vfs_setattr_dotl(dentry, &iattr); + } + break; + case ACL_TYPE_DEFAULT: +diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c +index 53bb7af..247b8df 100644 +--- a/fs/btrfs/acl.c ++++ b/fs/btrfs/acl.c +@@ -79,11 +79,9 @@ static int __btrfs_set_acl(struct btrfs_trans_handle *trans, + case ACL_TYPE_ACCESS: + name = XATTR_NAME_POSIX_ACL_ACCESS; + if (acl) { +- ret = posix_acl_equiv_mode(acl, &inode->i_mode); +- if (ret < 0) ++ ret = posix_acl_update_mode(inode, &inode->i_mode, &acl); ++ if (ret) + return ret; +- if (ret == 0) +- acl = NULL; + } + ret = 0; + break; +diff --git a/fs/ceph/acl.c b/fs/ceph/acl.c +index 4f67227..d0b6b342 100644 +--- a/fs/ceph/acl.c ++++ b/fs/ceph/acl.c +@@ -95,11 +95,9 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type) + case ACL_TYPE_ACCESS: + name = XATTR_NAME_POSIX_ACL_ACCESS; + if (acl) { +- ret = posix_acl_equiv_mode(acl, &new_mode); +- if (ret < 0) ++ ret = posix_acl_update_mode(inode, &new_mode, &acl); ++ if (ret) + goto out; +- if (ret == 0) +- acl = NULL; + } + break; + case ACL_TYPE_DEFAULT: +diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c +index 42f1d18..e725aa0 100644 +--- a/fs/ext2/acl.c ++++ b/fs/ext2/acl.c +@@ -190,15 +190,11 @@ ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type) + case ACL_TYPE_ACCESS: + name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS; + if (acl) { +- error = posix_acl_equiv_mode(acl, &inode->i_mode); +- if (error < 0) ++ error = posix_acl_update_mode(inode, &inode->i_mode, &acl); ++ if (error) + return error; +- else { +- inode->i_ctime = CURRENT_TIME_SEC; +- mark_inode_dirty(inode); +- if (error == 0) +- acl = NULL; +- } ++ inode->i_ctime = CURRENT_TIME_SEC; ++ mark_inode_dirty(inode); + } + break; + +diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c +index c6601a4..dfa5199 100644 +--- a/fs/ext4/acl.c ++++ b/fs/ext4/acl.c +@@ -193,15 +193,11 @@ __ext4_set_acl(handle_t *handle, struct inode *inode, int type, + case ACL_TYPE_ACCESS: + name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS; + if (acl) { +- error = posix_acl_equiv_mode(acl, &inode->i_mode); +- if (error < 0) ++ error = posix_acl_update_mode(inode, &inode->i_mode, &acl); ++ if (error) + return error; +- else { +- inode->i_ctime = ext4_current_time(inode); +- ext4_mark_inode_dirty(handle, inode); +- if (error == 0) +- acl = NULL; +- } ++ inode->i_ctime = ext4_current_time(inode); ++ ext4_mark_inode_dirty(handle, inode); + } + break; + +diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c +index 4dcc9e2..3134424 100644 +--- a/fs/f2fs/acl.c ++++ b/fs/f2fs/acl.c +@@ -210,12 +210,10 @@ static int __f2fs_set_acl(struct inode *inode, int type, + case ACL_TYPE_ACCESS: + name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS; + if (acl) { +- error = posix_acl_equiv_mode(acl, &inode->i_mode); +- if (error < 0) ++ error = posix_acl_update_mode(inode, &inode->i_mode, &acl); ++ if (error) + return error; + set_acl_inode(inode, inode->i_mode); +- if (error == 0) +- acl = NULL; + } + break; + +diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c +index 363ba9e..2524807 100644 +--- a/fs/gfs2/acl.c ++++ b/fs/gfs2/acl.c +@@ -92,17 +92,11 @@ int __gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) + if (type == ACL_TYPE_ACCESS) { + umode_t mode = inode->i_mode; + +- error = posix_acl_equiv_mode(acl, &mode); +- if (error < 0) ++ error = posix_acl_update_mode(inode, &inode->i_mode, &acl); ++ if (error) + return error; +- +- if (error == 0) +- acl = NULL; +- +- if (mode != inode->i_mode) { +- inode->i_mode = mode; ++ if (mode != inode->i_mode) + mark_inode_dirty(inode); +- } + } + + if (acl) { +diff --git a/fs/hfsplus/posix_acl.c b/fs/hfsplus/posix_acl.c +index ab7ea25..9b92058 100644 +--- a/fs/hfsplus/posix_acl.c ++++ b/fs/hfsplus/posix_acl.c +@@ -65,8 +65,8 @@ int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl, + case ACL_TYPE_ACCESS: + xattr_name = XATTR_NAME_POSIX_ACL_ACCESS; + if (acl) { +- err = posix_acl_equiv_mode(acl, &inode->i_mode); +- if (err < 0) ++ err = posix_acl_update_mode(inode, &inode->i_mode, &acl); ++ if (err) + return err; + } + err = 0; +diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c +index bc2693d..2a0f2a1 100644 +--- a/fs/jffs2/acl.c ++++ b/fs/jffs2/acl.c +@@ -233,9 +233,10 @@ int jffs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) + case ACL_TYPE_ACCESS: + xprefix = JFFS2_XPREFIX_ACL_ACCESS; + if (acl) { +- umode_t mode = inode->i_mode; +- rc = posix_acl_equiv_mode(acl, &mode); +- if (rc < 0) ++ umode_t mode; ++ ++ rc = posix_acl_update_mode(inode, &mode, &acl); ++ if (rc) + return rc; + if (inode->i_mode != mode) { + struct iattr attr; +@@ -247,8 +248,6 @@ int jffs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) + if (rc < 0) + return rc; + } +- if (rc == 0) +- acl = NULL; + } + break; + case ACL_TYPE_DEFAULT: +diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c +index 21fa92b..3a1e155 100644 +--- a/fs/jfs/acl.c ++++ b/fs/jfs/acl.c +@@ -78,13 +78,11 @@ static int __jfs_set_acl(tid_t tid, struct inode *inode, int type, + case ACL_TYPE_ACCESS: + ea_name = XATTR_NAME_POSIX_ACL_ACCESS; + if (acl) { +- rc = posix_acl_equiv_mode(acl, &inode->i_mode); +- if (rc < 0) ++ rc = posix_acl_update_mode(inode, &inode->i_mode, &acl); ++ if (rc) + return rc; + inode->i_ctime = CURRENT_TIME; + mark_inode_dirty(inode); +- if (rc == 0) +- acl = NULL; + } + break; + case ACL_TYPE_DEFAULT: +diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c +index 2162434..164307b 100644 +--- a/fs/ocfs2/acl.c ++++ b/fs/ocfs2/acl.c +@@ -241,13 +241,11 @@ int ocfs2_set_acl(handle_t *handle, + case ACL_TYPE_ACCESS: + name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS; + if (acl) { +- umode_t mode = inode->i_mode; +- ret = posix_acl_equiv_mode(acl, &mode); +- if (ret < 0) +- return ret; ++ umode_t mode; + +- if (ret == 0) +- acl = NULL; ++ ret = posix_acl_update_mode(inode, &mode, &acl); ++ if (ret) ++ return ret; + + ret = ocfs2_acl_set_mode(inode, di_bh, + handle, mode); +diff --git a/fs/orangefs/acl.c b/fs/orangefs/acl.c +index 28f2195..7a37544 100644 +--- a/fs/orangefs/acl.c ++++ b/fs/orangefs/acl.c +@@ -73,14 +73,11 @@ int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type) + case ACL_TYPE_ACCESS: + name = XATTR_NAME_POSIX_ACL_ACCESS; + if (acl) { +- umode_t mode = inode->i_mode; +- /* +- * can we represent this with the traditional file +- * mode permission bits? +- */ +- error = posix_acl_equiv_mode(acl, &mode); +- if (error < 0) { +- gossip_err("%s: posix_acl_equiv_mode err: %d\n", ++ umode_t mode; ++ ++ error = posix_acl_update_mode(inode, &mode, &acl); ++ if (error) { ++ gossip_err("%s: posix_acl_update_mode err: %d\n", + __func__, + error); + return error; +@@ -90,8 +87,6 @@ int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type) + SetModeFlag(orangefs_inode); + inode->i_mode = mode; + mark_inode_dirty_sync(inode); +- if (error == 0) +- acl = NULL; + } + break; + case ACL_TYPE_DEFAULT: +diff --git a/fs/posix_acl.c b/fs/posix_acl.c +index 59d47ab0..bfc3ec3 100644 +--- a/fs/posix_acl.c ++++ b/fs/posix_acl.c +@@ -626,6 +626,37 @@ posix_acl_create(struct inode *dir, umode_t *mode, + } + EXPORT_SYMBOL_GPL(posix_acl_create); + ++/** ++ * posix_acl_update_mode - update mode in set_acl ++ * ++ * Update the file mode when setting an ACL: compute the new file permission ++ * bits based on the ACL. In addition, if the ACL is equivalent to the new ++ * file mode, set *acl to NULL to indicate that no ACL should be set. ++ * ++ * As with chmod, clear the setgit bit if the caller is not in the owning group ++ * or capable of CAP_FSETID (see inode_change_ok). ++ * ++ * Called from set_acl inode operations. ++ */ ++int posix_acl_update_mode(struct inode *inode, umode_t *mode_p, ++ struct posix_acl **acl) ++{ ++ umode_t mode = inode->i_mode; ++ int error; ++ ++ error = posix_acl_equiv_mode(*acl, &mode); ++ if (error < 0) ++ return error; ++ if (error == 0) ++ *acl = NULL; ++ if (!in_group_p(inode->i_gid) && ++ !capable_wrt_inode_uidgid(inode, CAP_FSETID)) ++ mode &= ~S_ISGID; ++ *mode_p = mode; ++ return 0; ++} ++EXPORT_SYMBOL(posix_acl_update_mode); ++ + /* + * Fix up the uids and gids in posix acl extended attributes in place. + */ +diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c +index dbed42f..2737668 100644 +--- a/fs/reiserfs/xattr_acl.c ++++ b/fs/reiserfs/xattr_acl.c +@@ -242,13 +242,9 @@ __reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode, + case ACL_TYPE_ACCESS: + name = XATTR_NAME_POSIX_ACL_ACCESS; + if (acl) { +- error = posix_acl_equiv_mode(acl, &inode->i_mode); +- if (error < 0) ++ error = posix_acl_update_mode(inode, &inode->i_mode, &acl); ++ if (error) + return error; +- else { +- if (error == 0) +- acl = NULL; +- } + } + break; + case ACL_TYPE_DEFAULT: +diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c +index b6e527b..8a0dec8 100644 +--- a/fs/xfs/xfs_acl.c ++++ b/fs/xfs/xfs_acl.c +@@ -257,16 +257,11 @@ xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) + return error; + + if (type == ACL_TYPE_ACCESS) { +- umode_t mode = inode->i_mode; +- error = posix_acl_equiv_mode(acl, &mode); +- +- if (error <= 0) { +- acl = NULL; +- +- if (error < 0) +- return error; +- } ++ umode_t mode; + ++ error = posix_acl_update_mode(inode, &mode, &acl); ++ if (error) ++ return error; + error = xfs_set_mode(inode, mode); + if (error) + return error; +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index d377865..988903a 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -938,7 +938,8 @@ static inline int drm_debugfs_remove_files(const struct drm_info_list *files, + #endif + + extern struct dma_buf *drm_gem_prime_export(struct drm_device *dev, +- struct drm_gem_object *obj, int flags); ++ struct drm_gem_object *obj, ++ int flags); + extern int drm_gem_prime_handle_to_fd(struct drm_device *dev, + struct drm_file *file_priv, uint32_t handle, uint32_t flags, + int *prime_fd); +diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h +index c26d463..fe99e6f 100644 +--- a/include/linux/hugetlb.h ++++ b/include/linux/hugetlb.h +@@ -450,8 +450,8 @@ static inline pgoff_t basepage_index(struct page *page) + return __basepage_index(page); + } + +-extern void dissolve_free_huge_pages(unsigned long start_pfn, +- unsigned long end_pfn); ++extern int dissolve_free_huge_pages(unsigned long start_pfn, ++ unsigned long end_pfn); + static inline bool hugepage_migration_supported(struct hstate *h) + { + #ifdef CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION +@@ -518,7 +518,7 @@ static inline pgoff_t basepage_index(struct page *page) + { + return page->index; + } +-#define dissolve_free_huge_pages(s, e) do {} while (0) ++#define dissolve_free_huge_pages(s, e) 0 + #define hugepage_migration_supported(h) false + + static inline spinlock_t *huge_pte_lockptr(struct hstate *h, +diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h +index b519e13..bbfce62 100644 +--- a/include/linux/libnvdimm.h ++++ b/include/linux/libnvdimm.h +@@ -129,6 +129,8 @@ static inline struct nd_blk_region_desc *to_blk_region_desc( + } + + int nvdimm_bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length); ++void nvdimm_clear_from_poison_list(struct nvdimm_bus *nvdimm_bus, ++ phys_addr_t start, unsigned int len); + struct nvdimm_bus *nvdimm_bus_register(struct device *parent, + struct nvdimm_bus_descriptor *nfit_desc); + void nvdimm_bus_unregister(struct nvdimm_bus *nvdimm_bus); +diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h +index d5d3d74..bf1046d 100644 +--- a/include/linux/posix_acl.h ++++ b/include/linux/posix_acl.h +@@ -93,6 +93,7 @@ extern int set_posix_acl(struct inode *, int, struct posix_acl *); + extern int posix_acl_chmod(struct inode *, umode_t); + extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **, + struct posix_acl **); ++extern int posix_acl_update_mode(struct inode *, umode_t *, struct posix_acl **); + + extern int simple_set_acl(struct inode *, struct posix_acl *, int); + extern int simple_acl_create(struct inode *, struct inode *); +diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c +index abd286a..a4775f3 100644 +--- a/kernel/irq/generic-chip.c ++++ b/kernel/irq/generic-chip.c +@@ -411,8 +411,29 @@ int irq_map_generic_chip(struct irq_domain *d, unsigned int virq, + } + EXPORT_SYMBOL_GPL(irq_map_generic_chip); + ++static void irq_unmap_generic_chip(struct irq_domain *d, unsigned int virq) ++{ ++ struct irq_data *data = irq_domain_get_irq_data(d, virq); ++ struct irq_domain_chip_generic *dgc = d->gc; ++ unsigned int hw_irq = data->hwirq; ++ struct irq_chip_generic *gc; ++ int irq_idx; ++ ++ gc = irq_get_domain_generic_chip(d, hw_irq); ++ if (!gc) ++ return; ++ ++ irq_idx = hw_irq % dgc->irqs_per_chip; ++ ++ clear_bit(irq_idx, &gc->installed); ++ irq_domain_set_info(d, virq, hw_irq, &no_irq_chip, NULL, NULL, NULL, ++ NULL); ++ ++} ++ + struct irq_domain_ops irq_generic_chip_ops = { + .map = irq_map_generic_chip, ++ .unmap = irq_unmap_generic_chip, + .xlate = irq_domain_xlate_onetwocell, + }; + EXPORT_SYMBOL_GPL(irq_generic_chip_ops); +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index 603bdd0..770d83e 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -1437,22 +1437,32 @@ static int free_pool_huge_page(struct hstate *h, nodemask_t *nodes_allowed, + + /* + * Dissolve a given free hugepage into free buddy pages. This function does +- * nothing for in-use (including surplus) hugepages. ++ * nothing for in-use (including surplus) hugepages. Returns -EBUSY if the ++ * number of free hugepages would be reduced below the number of reserved ++ * hugepages. + */ +-static void dissolve_free_huge_page(struct page *page) ++static int dissolve_free_huge_page(struct page *page) + { ++ int rc = 0; ++ + spin_lock(&hugetlb_lock); + if (PageHuge(page) && !page_count(page)) { + struct page *head = compound_head(page); + struct hstate *h = page_hstate(head); + int nid = page_to_nid(head); ++ if (h->free_huge_pages - h->resv_huge_pages == 0) { ++ rc = -EBUSY; ++ goto out; ++ } + list_del(&head->lru); + h->free_huge_pages--; + h->free_huge_pages_node[nid]--; + h->max_huge_pages--; + update_and_free_page(h, head); + } ++out: + spin_unlock(&hugetlb_lock); ++ return rc; + } + + /* +@@ -1460,16 +1470,28 @@ static void dissolve_free_huge_page(struct page *page) + * make specified memory blocks removable from the system. + * Note that this will dissolve a free gigantic hugepage completely, if any + * part of it lies within the given range. ++ * Also note that if dissolve_free_huge_page() returns with an error, all ++ * free hugepages that were dissolved before that error are lost. + */ +-void dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn) ++int dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn) + { + unsigned long pfn; ++ struct page *page; ++ int rc = 0; + + if (!hugepages_supported()) +- return; ++ return rc; ++ ++ for (pfn = start_pfn; pfn < end_pfn; pfn += 1 << minimum_order) { ++ page = pfn_to_page(pfn); ++ if (PageHuge(page) && !page_count(page)) { ++ rc = dissolve_free_huge_page(page); ++ if (rc) ++ break; ++ } ++ } + +- for (pfn = start_pfn; pfn < end_pfn; pfn += 1 << minimum_order) +- dissolve_free_huge_page(pfn_to_page(pfn)); ++ return rc; + } + + /* +diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c +index 9d29ba0..9629273 100644 +--- a/mm/memory_hotplug.c ++++ b/mm/memory_hotplug.c +@@ -1945,7 +1945,9 @@ static int __ref __offline_pages(unsigned long start_pfn, + * dissolve free hugepages in the memory block before doing offlining + * actually in order to make hugetlbfs's object counting consistent. + */ +- dissolve_free_huge_pages(start_pfn, end_pfn); ++ ret = dissolve_free_huge_pages(start_pfn, end_pfn); ++ if (ret) ++ goto failed_removal; + /* check again */ + offlined_pages = check_pages_isolated(start_pfn, end_pfn); + if (offlined_pages < 0) { +diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c +index 3774b11..49b65d4 100644 +--- a/sound/soc/intel/boards/bxt_da7219_max98357a.c ++++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c +@@ -255,7 +255,7 @@ static struct snd_soc_ops broxton_da7219_ops = { + /* broxton digital audio interface glue - connects codec <--> CPU */ + static struct snd_soc_dai_link broxton_dais[] = { + /* Front End DAI links */ +- [BXT_DPCM_AUDIO_PB] ++ [BXT_DPCM_AUDIO_PB] = + { + .name = "Bxt Audio Port", + .stream_name = "Audio", +@@ -271,7 +271,7 @@ static struct snd_soc_dai_link broxton_dais[] = { + .dpcm_playback = 1, + .ops = &broxton_da7219_fe_ops, + }, +- [BXT_DPCM_AUDIO_CP] ++ [BXT_DPCM_AUDIO_CP] = + { + .name = "Bxt Audio Capture Port", + .stream_name = "Audio Record", +@@ -286,7 +286,7 @@ static struct snd_soc_dai_link broxton_dais[] = { + .dpcm_capture = 1, + .ops = &broxton_da7219_fe_ops, + }, +- [BXT_DPCM_AUDIO_REF_CP] ++ [BXT_DPCM_AUDIO_REF_CP] = + { + .name = "Bxt Audio Reference cap", + .stream_name = "Refcap", +@@ -300,7 +300,7 @@ static struct snd_soc_dai_link broxton_dais[] = { + .nonatomic = 1, + .dynamic = 1, + }, +- [BXT_DPCM_AUDIO_HDMI1_PB] ++ [BXT_DPCM_AUDIO_HDMI1_PB] = + { + .name = "Bxt HDMI Port1", + .stream_name = "Hdmi1", +@@ -313,7 +313,7 @@ static struct snd_soc_dai_link broxton_dais[] = { + .nonatomic = 1, + .dynamic = 1, + }, +- [BXT_DPCM_AUDIO_HDMI2_PB] ++ [BXT_DPCM_AUDIO_HDMI2_PB] = + { + .name = "Bxt HDMI Port2", + .stream_name = "Hdmi2", +@@ -326,7 +326,7 @@ static struct snd_soc_dai_link broxton_dais[] = { + .nonatomic = 1, + .dynamic = 1, + }, +- [BXT_DPCM_AUDIO_HDMI3_PB] ++ [BXT_DPCM_AUDIO_HDMI3_PB] = + { + .name = "Bxt HDMI Port3", + .stream_name = "Hdmi3", +diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c +index 253d7bf..d610bdca 100644 +--- a/sound/soc/intel/boards/bxt_rt298.c ++++ b/sound/soc/intel/boards/bxt_rt298.c +@@ -271,7 +271,7 @@ static const struct snd_soc_ops broxton_rt286_fe_ops = { + /* broxton digital audio interface glue - connects codec <--> CPU */ + static struct snd_soc_dai_link broxton_rt298_dais[] = { + /* Front End DAI links */ +- [BXT_DPCM_AUDIO_PB] ++ [BXT_DPCM_AUDIO_PB] = + { + .name = "Bxt Audio Port", + .stream_name = "Audio", +@@ -286,7 +286,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = { + .dpcm_playback = 1, + .ops = &broxton_rt286_fe_ops, + }, +- [BXT_DPCM_AUDIO_CP] ++ [BXT_DPCM_AUDIO_CP] = + { + .name = "Bxt Audio Capture Port", + .stream_name = "Audio Record", +@@ -300,7 +300,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = { + .dpcm_capture = 1, + .ops = &broxton_rt286_fe_ops, + }, +- [BXT_DPCM_AUDIO_REF_CP] ++ [BXT_DPCM_AUDIO_REF_CP] = + { + .name = "Bxt Audio Reference cap", + .stream_name = "refcap", +@@ -313,7 +313,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = { + .nonatomic = 1, + .dynamic = 1, + }, +- [BXT_DPCM_AUDIO_DMIC_CP] ++ [BXT_DPCM_AUDIO_DMIC_CP] = + { + .name = "Bxt Audio DMIC cap", + .stream_name = "dmiccap", +@@ -327,7 +327,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = { + .dynamic = 1, + .ops = &broxton_dmic_ops, + }, +- [BXT_DPCM_AUDIO_HDMI1_PB] ++ [BXT_DPCM_AUDIO_HDMI1_PB] = + { + .name = "Bxt HDMI Port1", + .stream_name = "Hdmi1", +@@ -340,7 +340,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = { + .nonatomic = 1, + .dynamic = 1, + }, +- [BXT_DPCM_AUDIO_HDMI2_PB] ++ [BXT_DPCM_AUDIO_HDMI2_PB] = + { + .name = "Bxt HDMI Port2", + .stream_name = "Hdmi2", +@@ -353,7 +353,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = { + .nonatomic = 1, + .dynamic = 1, + }, +- [BXT_DPCM_AUDIO_HDMI3_PB] ++ [BXT_DPCM_AUDIO_HDMI3_PB] = + { + .name = "Bxt HDMI Port3", + .stream_name = "Hdmi3", +diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c +index d908ff8..801082f 100644 +--- a/sound/soc/soc-dapm.c ++++ b/sound/soc/soc-dapm.c +@@ -823,6 +823,7 @@ static int dapm_create_or_share_kcontrol(struct snd_soc_dapm_widget *w, + case snd_soc_dapm_switch: + case snd_soc_dapm_mixer: + case snd_soc_dapm_pga: ++ case snd_soc_dapm_out_drv: + wname_in_long_name = true; + kcname_in_long_name = true; + break; +@@ -3049,6 +3050,9 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, + } + mutex_unlock(&card->dapm_mutex); + ++ if (ret) ++ return ret; ++ + if (invert) + ucontrol->value.integer.value[0] = max - val; + else +@@ -3200,7 +3204,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, + if (e->shift_l != e->shift_r) { + if (item[1] > e->items) + return -EINVAL; +- val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_l; ++ val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_r; + mask |= e->mask << e->shift_r; + } + +diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c +index ee7f15a..3406907 100644 +--- a/sound/soc/soc-topology.c ++++ b/sound/soc/soc-topology.c +@@ -1475,6 +1475,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg, + if (widget == NULL) { + dev_err(tplg->dev, "ASoC: failed to create widget %s controls\n", + w->name); ++ ret = -ENOMEM; + goto hdr_err; + } + +diff --git a/tools/perf/perf-sys.h b/tools/perf/perf-sys.h +index 7ed72a4..e4b717e 100644 +--- a/tools/perf/perf-sys.h ++++ b/tools/perf/perf-sys.h +@@ -20,7 +20,6 @@ + #endif + + #ifdef __powerpc__ +-#include "../../arch/powerpc/include/uapi/asm/unistd.h" + #define CPUINFO_PROC {"cpu"} + #endif + +diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c +index 13d4143..7aee954 100644 +--- a/tools/perf/ui/browsers/hists.c ++++ b/tools/perf/ui/browsers/hists.c +@@ -1091,7 +1091,6 @@ static int __hpp__slsmg_color_printf(struct perf_hpp *hpp, const char *fmt, ...) + ret = scnprintf(hpp->buf, hpp->size, fmt, len, percent); + ui_browser__printf(arg->b, "%s", hpp->buf); + +- advance_hpp(hpp, ret); + return ret; + } + +@@ -2046,6 +2045,7 @@ void hist_browser__init(struct hist_browser *browser, + struct hists *hists) + { + struct perf_hpp_fmt *fmt; ++ struct perf_hpp_list_node *node; + + browser->hists = hists; + browser->b.refresh = hist_browser__refresh; +@@ -2058,6 +2058,11 @@ void hist_browser__init(struct hist_browser *browser, + perf_hpp__reset_width(fmt, hists); + ++browser->b.columns; + } ++ /* hierarchy entries have their own hpp list */ ++ list_for_each_entry(node, &hists->hpp_formats, list) { ++ perf_hpp_list__for_each_format(&node->hpp, fmt) ++ perf_hpp__reset_width(fmt, hists); ++ } + } + + struct hist_browser *hist_browser__new(struct hists *hists) +diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c +index f04a631..d0cae75 100644 +--- a/tools/perf/ui/stdio/hist.c ++++ b/tools/perf/ui/stdio/hist.c +@@ -628,14 +628,6 @@ hists__fprintf_hierarchy_headers(struct hists *hists, + struct perf_hpp *hpp, + FILE *fp) + { +- struct perf_hpp_list_node *fmt_node; +- struct perf_hpp_fmt *fmt; +- +- list_for_each_entry(fmt_node, &hists->hpp_formats, list) { +- perf_hpp_list__for_each_format(&fmt_node->hpp, fmt) +- perf_hpp__reset_width(fmt, hists); +- } +- + return print_hierarchy_header(hists, hpp, symbol_conf.field_sep, fp); + } + +@@ -714,6 +706,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, + bool use_callchain) + { + struct perf_hpp_fmt *fmt; ++ struct perf_hpp_list_node *node; + struct rb_node *nd; + size_t ret = 0; + const char *sep = symbol_conf.field_sep; +@@ -726,6 +719,11 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, + + hists__for_each_format(hists, fmt) + perf_hpp__reset_width(fmt, hists); ++ /* hierarchy entries have their own hpp list */ ++ list_for_each_entry(node, &hists->hpp_formats, list) { ++ perf_hpp_list__for_each_format(&node->hpp, fmt) ++ perf_hpp__reset_width(fmt, hists); ++ } + + if (symbol_conf.col_width_list_str) + perf_hpp__set_user_width(symbol_conf.col_width_list_str); +diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c +index 4f979bb..7123f4d 100644 +--- a/tools/perf/util/data-convert-bt.c ++++ b/tools/perf/util/data-convert-bt.c +@@ -437,7 +437,7 @@ add_bpf_output_values(struct bt_ctf_event_class *event_class, + int ret; + + if (nr_elements * sizeof(u32) != raw_size) +- pr_warning("Incorrect raw_size (%u) in bpf output event, skip %lu bytes\n", ++ pr_warning("Incorrect raw_size (%u) in bpf output event, skip %zu bytes\n", + raw_size, nr_elements * sizeof(u32) - raw_size); + + len_type = bt_ctf_event_class_get_field_by_name(event_class, "raw_len"); +diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c +index a811c13..f77b316 100644 +--- a/tools/perf/util/symbol-elf.c ++++ b/tools/perf/util/symbol-elf.c +@@ -1113,9 +1113,8 @@ int dso__load_sym(struct dso *dso, struct map *map, + * For misannotated, zeroed, ASM function sizes. + */ + if (nr > 0) { +- if (!symbol_conf.allow_aliases) +- symbols__fixup_duplicate(&dso->symbols[map->type]); + symbols__fixup_end(&dso->symbols[map->type]); ++ symbols__fixup_duplicate(&dso->symbols[map->type]); + if (kmap) { + /* + * We need to fixup this here too because we create new +diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c +index 37e8d20..f29f336 100644 +--- a/tools/perf/util/symbol.c ++++ b/tools/perf/util/symbol.c +@@ -152,6 +152,9 @@ void symbols__fixup_duplicate(struct rb_root *symbols) + struct rb_node *nd; + struct symbol *curr, *next; + ++ if (symbol_conf.allow_aliases) ++ return; ++ + nd = rb_first(symbols); + + while (nd) { +@@ -1234,8 +1237,8 @@ int __dso__load_kallsyms(struct dso *dso, const char *filename, + if (kallsyms__delta(map, filename, &delta)) + return -1; + +- symbols__fixup_duplicate(&dso->symbols[map->type]); + symbols__fixup_end(&dso->symbols[map->type]); ++ symbols__fixup_duplicate(&dso->symbols[map->type]); + + if (dso->kernel == DSO_TYPE_GUEST_KERNEL) + dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS; |