Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 9 Nov 2019 02:21:05 +0000 (18:21 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 9 Nov 2019 02:21:05 +0000 (18:21 -0800)
Pull networking fixes from David Miller:

 1) BPF sample build fixes from Björn Töpel

 2) Fix powerpc bpf tail call implementation, from Eric Dumazet.

 3) DCCP leaks jiffies on the wire, fix also from Eric Dumazet.

 4) Fix crash in ebtables when using dnat target, from Florian Westphal.

 5) Fix port disable handling whne removing bcm_sf2 driver, from Florian
    Fainelli.

 6) Fix kTLS sk_msg trim on fallback to copy mode, from Jakub Kicinski.

 7) Various KCSAN fixes all over the networking, from Eric Dumazet.

 8) Memory leaks in mlx5 driver, from Alex Vesker.

 9) SMC interface refcounting fix, from Ursula Braun.

10) TSO descriptor handling fixes in stmmac driver, from Jose Abreu.

11) Add a TX lock to synchonize the kTLS TX path properly with crypto
    operations. From Jakub Kicinski.

12) Sock refcount during shutdown fix in vsock/virtio code, from Stefano
    Garzarella.

13) Infinite loop in Intel ice driver, from Colin Ian King.

* git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (108 commits)
  ixgbe: need_wakeup flag might not be set for Tx
  i40e: need_wakeup flag might not be set for Tx
  igb/igc: use ktime accessors for skb->tstamp
  i40e: Fix for ethtool -m issue on X722 NIC
  iavf: initialize ITRN registers with correct values
  ice: fix potential infinite loop because loop counter being too small
  qede: fix NULL pointer deref in __qede_remove()
  net: fix data-race in neigh_event_send()
  vsock/virtio: fix sock refcnt holding during the shutdown
  net: ethernet: octeon_mgmt: Account for second possible VLAN header
  mac80211: fix station inactive_time shortly after boot
  net/fq_impl: Switch to kvmalloc() for memory allocation
  mac80211: fix ieee80211_txq_setup_flows() failure path
  ipv4: Fix table id reference in fib_sync_down_addr
  ipv6: fixes rt6_probe() and fib6_nh->last_probe init
  net: hns: Fix the stray netpoll locks causing deadlock in NAPI path
  net: usb: qmi_wwan: add support for DW5821e with eSIM support
  CDC-NCM: handle incomplete transfer of MTU
  nfc: netlink: fix double device reference drop
  NFC: st21nfca: fix double free
  ...

150 files changed:
MAINTAINERS
Makefile
arch/arm64/include/asm/pgtable.h
arch/powerpc/include/asm/book3s/32/kup.h
arch/powerpc/include/asm/elf.h
arch/powerpc/kernel/prom_init.c
arch/powerpc/kernel/prom_init_check.sh
arch/powerpc/platforms/powernv/eeh-powernv.c
arch/powerpc/platforms/powernv/smp.c
arch/s390/include/asm/unwind.h
arch/s390/kernel/idle.c
arch/s390/kernel/unwind_bc.c
arch/s390/mm/cmm.c
block/blk-cgroup.c
drivers/block/drbd/drbd_main.c
drivers/clk/at91/clk-main.c
drivers/clk/at91/sam9x60.c
drivers/clk/at91/sckc.c
drivers/clk/clk-ast2600.c
drivers/clk/imx/clk-imx8mm.c
drivers/clk/imx/clk-imx8mn.c
drivers/clk/meson/g12a.c
drivers/clk/meson/gxbb.c
drivers/clk/samsung/clk-exynos5420.c
drivers/clk/samsung/clk-exynos5433.c
drivers/clk/sunxi-ng/ccu-sun9i-a80.c
drivers/clk/sunxi/clk-sunxi.c
drivers/clk/ti/clk-dra7-atl.c
drivers/clk/ti/clkctrl.c
drivers/cpufreq/intel_pstate.c
drivers/gpio/gpio-merrifield.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c
drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
drivers/gpu/drm/amd/amdgpu/soc15.c
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
drivers/gpu/drm/amd/powerplay/navi10_ppt.c
drivers/gpu/drm/amd/powerplay/vega20_ppt.c
drivers/gpu/drm/drm_atomic_helper.c
drivers/gpu/drm/drm_self_refresh_helper.c
drivers/gpu/drm/i915/display/intel_crt.c
drivers/gpu/drm/i915/display/intel_dp.c
drivers/gpu/drm/i915/display/intel_hdmi.c
drivers/gpu/drm/radeon/si_dpm.c
drivers/hid/i2c-hid/i2c-hid-core.c
drivers/hid/wacom.h
drivers/hid/wacom_wac.c
drivers/hwmon/ina3221.c
drivers/hwmon/nct7904.c
drivers/nvme/host/multipath.c
drivers/nvme/host/rdma.c
drivers/pwm/core.c
drivers/pwm/pwm-bcm-iproc.c
drivers/scsi/lpfc/lpfc_nportdisc.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_bsg.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/sd.c
drivers/scsi/ufs/ufs_bsg.c
drivers/target/iscsi/cxgbit/cxgbit_cm.c
drivers/usb/cdns3/gadget.c
drivers/usb/cdns3/host-export.h
drivers/usb/cdns3/host.c
drivers/usb/core/config.c
drivers/usb/dwc3/Kconfig
drivers/usb/dwc3/core.c
drivers/usb/dwc3/dwc3-pci.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/composite.c
drivers/usb/gadget/configfs.c
drivers/usb/gadget/udc/atmel_usba_udc.c
drivers/usb/gadget/udc/core.c
drivers/usb/gadget/udc/fsl_udc_core.c
drivers/usb/gadget/udc/renesas_usb3.c
drivers/usb/host/xhci-debugfs.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/misc/ldusb.c
drivers/usb/mtu3/mtu3_core.c
drivers/usb/renesas_usbhs/common.c
drivers/usb/renesas_usbhs/mod_gadget.c
drivers/usb/serial/whiteheat.c
drivers/usb/serial/whiteheat.h
drivers/usb/storage/scsiglue.c
drivers/usb/storage/uas.c
drivers/usb/usbip/vhci_tx.c
drivers/video/fbdev/c2p_core.h
fs/ceph/caps.c
fs/ceph/dir.c
fs/ceph/file.c
fs/ceph/inode.c
fs/ceph/super.c
fs/cifs/smb2ops.c
fs/fs-writeback.c
fs/ocfs2/file.c
include/drm/drm_gem_shmem_helper.h
include/drm/drm_self_refresh_helper.h
include/linux/idr.h
include/linux/mm.h
include/linux/mm_types.h
include/linux/page-flags.h
include/linux/radix-tree.h
include/uapi/linux/nvme_ioctl.h
include/uapi/linux/sched.h
kernel/fork.c
lib/dump_stack.c
lib/idr.c
lib/radix-tree.c
lib/test_xarray.c
lib/xarray.c
mm/khugepaged.c
mm/memcontrol.c
mm/memory_hotplug.c
mm/mmu_notifier.c
mm/page_alloc.c
mm/slab.h
mm/vmstat.c
scripts/gdb/linux/symbols.py
scripts/nsdeps
sound/core/compress_offload.c
sound/core/timer.c
sound/firewire/bebob/bebob_focusrite.c
sound/pci/hda/patch_ca0132.c
sound/pci/hda/patch_hdmi.c
sound/soc/codecs/hdac_hda.c
sound/soc/codecs/hdmi-codec.c
sound/soc/codecs/max98373.c
sound/soc/codecs/msm8916-wcd-analog.c
sound/soc/kirkwood/kirkwood-i2s.c
sound/soc/rockchip/rockchip_max98090.c
sound/soc/sh/rcar/dma.c
sound/soc/sof/debug.c
sound/soc/sof/intel/hda-stream.c
sound/soc/sof/ipc.c
sound/soc/sof/topology.c
sound/soc/stm/stm32_sai_sub.c
sound/soc/ti/sdma-pcm.c
tools/gpio/Makefile
tools/testing/selftests/vm/gup_benchmark.c
tools/usb/usbip/libsrc/usbip_device_driver.c

index 25f8bd78fc26a74635a787acf911c40aac6b1624..8f148f49966054beafbf127b9faa82d039e91964 100644 (file)
@@ -10520,8 +10520,12 @@ F:     mm/memblock.c
 F:     Documentation/core-api/boot-time-mm.rst
 
 MEMORY MANAGEMENT
+M:     Andrew Morton <akpm@linux-foundation.org>
 L:     linux-mm@kvack.org
 W:     http://www.linux-mm.org
+T:     quilt https://ozlabs.org/~akpm/mmotm/
+T:     quilt https://ozlabs.org/~akpm/mmots/
+T:     git git://github.com/hnaz/linux-mm.git
 S:     Maintained
 F:     include/linux/mm.h
 F:     include/linux/gfp.h
@@ -18035,6 +18039,7 @@ F:      Documentation/vm/zsmalloc.rst
 ZSWAP COMPRESSED SWAP CACHING
 M:     Seth Jennings <sjenning@redhat.com>
 M:     Dan Streetman <ddstreet@ieee.org>
+M:     Vitaly Wool <vitaly.wool@konsulko.com>
 L:     linux-mm@kvack.org
 S:     Maintained
 F:     mm/zswap.c
index 79be70bf28991e13160703119f633982d24ce039..b37d0e8fc61d5422eb03b7a00ad6ee991b66f103 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 5
 PATCHLEVEL = 4
 SUBLEVEL = 0
-EXTRAVERSION = -rc5
+EXTRAVERSION = -rc6
 NAME = Kleptomaniac Octopus
 
 # *DOCUMENTATION*
index 8330810f699e31bd01794f8dc5ad17dd419646f6..565aa45ef1344e481b0ad201194613305a39eb90 100644 (file)
@@ -283,23 +283,6 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
        set_pte(ptep, pte);
 }
 
-#define __HAVE_ARCH_PTE_SAME
-static inline int pte_same(pte_t pte_a, pte_t pte_b)
-{
-       pteval_t lhs, rhs;
-
-       lhs = pte_val(pte_a);
-       rhs = pte_val(pte_b);
-
-       if (pte_present(pte_a))
-               lhs &= ~PTE_RDONLY;
-
-       if (pte_present(pte_b))
-               rhs &= ~PTE_RDONLY;
-
-       return (lhs == rhs);
-}
-
 /*
  * Huge pte definitions.
  */
index 677e9babef801305e61951244f0b32298c1725c7..f9dc597b0b86884dca4dc9c5e1814312bb34e41e 100644 (file)
@@ -91,6 +91,7 @@
 
 static inline void kuap_update_sr(u32 sr, u32 addr, u32 end)
 {
+       addr &= 0xf0000000;     /* align addr to start of segment */
        barrier();      /* make sure thread.kuap is updated before playing with SRs */
        while (addr < end) {
                mtsrin(sr, addr);
index 409c9bfb43d9dff09e4413f1095e03eaf184f2b1..57c229a86f0811e783c9526283e617f96c485bbf 100644 (file)
@@ -175,4 +175,7 @@ do {                                                                        \
        ARCH_DLINFO_CACHE_GEOMETRY;                                     \
 } while (0)
 
+/* Relocate the kernel image to @final_address */
+void relocate(unsigned long final_address);
+
 #endif /* _ASM_POWERPC_ELF_H */
index a4e7762dd28648ac5dc8e64bc96a6854b532087c..100f1b57ec2fd18531dd16b16c0885c0550f114c 100644 (file)
@@ -3249,7 +3249,20 @@ static void setup_secure_guest(unsigned long kbase, unsigned long fdt)
        /* Switch to secure mode. */
        prom_printf("Switching to secure mode.\n");
 
+       /*
+        * The ultravisor will do an integrity check of the kernel image but we
+        * relocated it so the check will fail. Restore the original image by
+        * relocating it back to the kernel virtual base address.
+        */
+       if (IS_ENABLED(CONFIG_RELOCATABLE))
+               relocate(KERNELBASE);
+
        ret = enter_secure_mode(kbase, fdt);
+
+       /* Relocate the kernel again. */
+       if (IS_ENABLED(CONFIG_RELOCATABLE))
+               relocate(kbase);
+
        if (ret != U_SUCCESS) {
                prom_printf("Returned %d from switching to secure mode.\n", ret);
                prom_rtas_os_term("Switch to secure mode failed.\n");
index 78bab17b1396aefe35ac0a4573fbbbab39acd148..b183ab9c5107c9236930b3d3d9e1f2c7dd27b302 100644 (file)
@@ -26,7 +26,8 @@ _end enter_prom $MEM_FUNCS reloc_offset __secondary_hold
 __secondary_hold_acknowledge __secondary_hold_spinloop __start
 logo_linux_clut224 btext_prepare_BAT
 reloc_got2 kernstart_addr memstart_addr linux_banner _stext
-__prom_init_toc_start __prom_init_toc_end btext_setup_display TOC."
+__prom_init_toc_start __prom_init_toc_end btext_setup_display TOC.
+relocate"
 
 NM="$1"
 OBJ="$2"
index 6bc24a47e9ef956e654ea022b4e6a9b52c0903df..6f300ab7f0e9b368114d65232d59d0a355d1201d 100644 (file)
@@ -42,7 +42,7 @@ void pnv_pcibios_bus_add_device(struct pci_dev *pdev)
 {
        struct pci_dn *pdn = pci_get_pdn(pdev);
 
-       if (eeh_has_flag(EEH_FORCE_DISABLED))
+       if (!pdn || eeh_has_flag(EEH_FORCE_DISABLED))
                return;
 
        dev_dbg(&pdev->dev, "EEH: Setting up device\n");
index fbd6e6b7bbf28c4ac806681e4abd42e488504af8..13e25169934665e6655c780def5d3d056775d124 100644 (file)
@@ -146,20 +146,25 @@ static int pnv_smp_cpu_disable(void)
        return 0;
 }
 
+static void pnv_flush_interrupts(void)
+{
+       if (cpu_has_feature(CPU_FTR_ARCH_300)) {
+               if (xive_enabled())
+                       xive_flush_interrupt();
+               else
+                       icp_opal_flush_interrupt();
+       } else {
+               icp_native_flush_interrupt();
+       }
+}
+
 static void pnv_smp_cpu_kill_self(void)
 {
+       unsigned long srr1, unexpected_mask, wmask;
        unsigned int cpu;
-       unsigned long srr1, wmask;
        u64 lpcr_val;
 
        /* Standard hot unplug procedure */
-       /*
-        * This hard disables local interurpts, ensuring we have no lazy
-        * irqs pending.
-        */
-       WARN_ON(irqs_disabled());
-       hard_irq_disable();
-       WARN_ON(lazy_irq_pending());
 
        idle_task_exit();
        current->active_mm = NULL; /* for sanity */
@@ -172,6 +177,27 @@ static void pnv_smp_cpu_kill_self(void)
        if (cpu_has_feature(CPU_FTR_ARCH_207S))
                wmask = SRR1_WAKEMASK_P8;
 
+       /*
+        * This turns the irq soft-disabled state we're called with, into a
+        * hard-disabled state with pending irq_happened interrupts cleared.
+        *
+        * PACA_IRQ_DEC   - Decrementer should be ignored.
+        * PACA_IRQ_HMI   - Can be ignored, processing is done in real mode.
+        * PACA_IRQ_DBELL, EE, PMI - Unexpected.
+        */
+       hard_irq_disable();
+       if (generic_check_cpu_restart(cpu))
+               goto out;
+
+       unexpected_mask = ~(PACA_IRQ_DEC | PACA_IRQ_HMI | PACA_IRQ_HARD_DIS);
+       if (local_paca->irq_happened & unexpected_mask) {
+               if (local_paca->irq_happened & PACA_IRQ_EE)
+                       pnv_flush_interrupts();
+               DBG("CPU%d Unexpected exit while offline irq_happened=%lx!\n",
+                               cpu, local_paca->irq_happened);
+       }
+       local_paca->irq_happened = PACA_IRQ_HARD_DIS;
+
        /*
         * We don't want to take decrementer interrupts while we are
         * offline, so clear LPCR:PECE1. We keep PECE2 (and
@@ -197,6 +223,7 @@ static void pnv_smp_cpu_kill_self(void)
 
                srr1 = pnv_cpu_offline(cpu);
 
+               WARN_ON_ONCE(!irqs_disabled());
                WARN_ON(lazy_irq_pending());
 
                /*
@@ -212,13 +239,7 @@ static void pnv_smp_cpu_kill_self(void)
                 */
                if (((srr1 & wmask) == SRR1_WAKEEE) ||
                    ((srr1 & wmask) == SRR1_WAKEHVI)) {
-                       if (cpu_has_feature(CPU_FTR_ARCH_300)) {
-                               if (xive_enabled())
-                                       xive_flush_interrupt();
-                               else
-                                       icp_opal_flush_interrupt();
-                       } else
-                               icp_native_flush_interrupt();
+                       pnv_flush_interrupts();
                } else if ((srr1 & wmask) == SRR1_WAKEHDBELL) {
                        unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER);
                        asm volatile(PPC_MSGCLR(%0) : : "r" (msg));
@@ -266,7 +287,7 @@ static void pnv_smp_cpu_kill_self(void)
         */
        lpcr_val = mfspr(SPRN_LPCR) | (u64)LPCR_PECE1;
        pnv_program_cpu_hotplug_lpcr(cpu, lpcr_val);
-
+out:
        DBG("CPU%d coming online...\n", cpu);
 }
 
index d827b5b9a32cd6a44d7beddba18b96cdcbb18aa9..eaaefeceef6f0810c53108b390420b351257a052 100644 (file)
@@ -35,6 +35,7 @@ struct unwind_state {
        struct task_struct *task;
        struct pt_regs *regs;
        unsigned long sp, ip;
+       bool reuse_sp;
        int graph_idx;
        bool reliable;
        bool error;
index b9d8fe45737aa2e529cb9eec244349e121803858..8f8456816d83e890a3f3150ccec184f21810a509 100644 (file)
@@ -69,18 +69,26 @@ DEVICE_ATTR(idle_count, 0444, show_idle_count, NULL);
 static ssize_t show_idle_time(struct device *dev,
                                struct device_attribute *attr, char *buf)
 {
+       unsigned long long now, idle_time, idle_enter, idle_exit, in_idle;
        struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id);
-       unsigned long long now, idle_time, idle_enter, idle_exit;
        unsigned int seq;
 
        do {
-               now = get_tod_clock();
                seq = read_seqcount_begin(&idle->seqcount);
                idle_time = READ_ONCE(idle->idle_time);
                idle_enter = READ_ONCE(idle->clock_idle_enter);
                idle_exit = READ_ONCE(idle->clock_idle_exit);
        } while (read_seqcount_retry(&idle->seqcount, seq));
-       idle_time += idle_enter ? ((idle_exit ? : now) - idle_enter) : 0;
+       in_idle = 0;
+       now = get_tod_clock();
+       if (idle_enter) {
+               if (idle_exit) {
+                       in_idle = idle_exit - idle_enter;
+               } else if (now > idle_enter) {
+                       in_idle = now - idle_enter;
+               }
+       }
+       idle_time += in_idle;
        return sprintf(buf, "%llu\n", idle_time >> 12);
 }
 DEVICE_ATTR(idle_time_us, 0444, show_idle_time, NULL);
@@ -88,17 +96,24 @@ DEVICE_ATTR(idle_time_us, 0444, show_idle_time, NULL);
 u64 arch_cpu_idle_time(int cpu)
 {
        struct s390_idle_data *idle = &per_cpu(s390_idle, cpu);
-       unsigned long long now, idle_enter, idle_exit;
+       unsigned long long now, idle_enter, idle_exit, in_idle;
        unsigned int seq;
 
        do {
-               now = get_tod_clock();
                seq = read_seqcount_begin(&idle->seqcount);
                idle_enter = READ_ONCE(idle->clock_idle_enter);
                idle_exit = READ_ONCE(idle->clock_idle_exit);
        } while (read_seqcount_retry(&idle->seqcount, seq));
-
-       return cputime_to_nsecs(idle_enter ? ((idle_exit ?: now) - idle_enter) : 0);
+       in_idle = 0;
+       now = get_tod_clock();
+       if (idle_enter) {
+               if (idle_exit) {
+                       in_idle = idle_exit - idle_enter;
+               } else if (now > idle_enter) {
+                       in_idle = now - idle_enter;
+               }
+       }
+       return cputime_to_nsecs(in_idle);
 }
 
 void arch_cpu_idle_enter(void)
index 8fc9daae47a2ee89a25161ff9775673ee9f37dd8..a8204f952315d9edda9090a1d3762e37cc5fb99c 100644 (file)
@@ -46,10 +46,15 @@ bool unwind_next_frame(struct unwind_state *state)
 
        regs = state->regs;
        if (unlikely(regs)) {
-               sp = READ_ONCE_NOCHECK(regs->gprs[15]);
-               if (unlikely(outside_of_stack(state, sp))) {
-                       if (!update_stack_info(state, sp))
-                               goto out_err;
+               if (state->reuse_sp) {
+                       sp = state->sp;
+                       state->reuse_sp = false;
+               } else {
+                       sp = READ_ONCE_NOCHECK(regs->gprs[15]);
+                       if (unlikely(outside_of_stack(state, sp))) {
+                               if (!update_stack_info(state, sp))
+                                       goto out_err;
+                       }
                }
                sf = (struct stack_frame *) sp;
                ip = READ_ONCE_NOCHECK(sf->gprs[8]);
@@ -107,9 +112,9 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task,
 {
        struct stack_info *info = &state->stack_info;
        unsigned long *mask = &state->stack_mask;
+       bool reliable, reuse_sp;
        struct stack_frame *sf;
        unsigned long ip;
-       bool reliable;
 
        memset(state, 0, sizeof(*state));
        state->task = task;
@@ -134,10 +139,12 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task,
        if (regs) {
                ip = READ_ONCE_NOCHECK(regs->psw.addr);
                reliable = true;
+               reuse_sp = true;
        } else {
                sf = (struct stack_frame *) sp;
                ip = READ_ONCE_NOCHECK(sf->gprs[8]);
                reliable = false;
+               reuse_sp = false;
        }
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
@@ -151,5 +158,6 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task,
        state->sp = sp;
        state->ip = ip;
        state->reliable = reliable;
+       state->reuse_sp = reuse_sp;
 }
 EXPORT_SYMBOL_GPL(__unwind_start);
index 510a18299196f3b797be51fd22b2bbfbe5cd003f..a51c892f14f3ee5bd393ed74003c96fd80268979 100644 (file)
@@ -298,16 +298,16 @@ static int cmm_timeout_handler(struct ctl_table *ctl, int write,
        }
 
        if (write) {
-               len = *lenp;
-               if (copy_from_user(buf, buffer,
-                                  len > sizeof(buf) ? sizeof(buf) : len))
+               len = min(*lenp, sizeof(buf));
+               if (copy_from_user(buf, buffer, len))
                        return -EFAULT;
-               buf[sizeof(buf) - 1] = '\0';
+               buf[len - 1] = '\0';
                cmm_skip_blanks(buf, &p);
                nr = simple_strtoul(p, &p, 0);
                cmm_skip_blanks(p, &p);
                seconds = simple_strtoul(p, &p, 0);
                cmm_set_timeout(nr, seconds);
+               *ppos += *lenp;
        } else {
                len = sprintf(buf, "%ld %ld\n",
                              cmm_timeout_pages, cmm_timeout_seconds);
@@ -315,9 +315,9 @@ static int cmm_timeout_handler(struct ctl_table *ctl, int write,
                        len = *lenp;
                if (copy_to_user(buffer, buf, len))
                        return -EFAULT;
+               *lenp = len;
+               *ppos += len;
        }
-       *lenp = len;
-       *ppos += len;
        return 0;
 }
 
index 5d21027b1faf03b1a16bcd38b8670657c9f02380..1eb8895be4c6b8bb17d49022583d2ee411336e94 100644 (file)
@@ -934,9 +934,14 @@ static int blkcg_print_stat(struct seq_file *sf, void *v)
                int i;
                bool has_stats = false;
 
+               spin_lock_irq(&blkg->q->queue_lock);
+
+               if (!blkg->online)
+                       goto skip;
+
                dname = blkg_dev_name(blkg);
                if (!dname)
-                       continue;
+                       goto skip;
 
                /*
                 * Hooray string manipulation, count is the size written NOT
@@ -946,8 +951,6 @@ static int blkcg_print_stat(struct seq_file *sf, void *v)
                 */
                off += scnprintf(buf+off, size-off, "%s ", dname);
 
-               spin_lock_irq(&blkg->q->queue_lock);
-
                blkg_rwstat_recursive_sum(blkg, NULL,
                                offsetof(struct blkcg_gq, stat_bytes), &rwstat);
                rbytes = rwstat.cnt[BLKG_RWSTAT_READ];
@@ -960,8 +963,6 @@ static int blkcg_print_stat(struct seq_file *sf, void *v)
                wios = rwstat.cnt[BLKG_RWSTAT_WRITE];
                dios = rwstat.cnt[BLKG_RWSTAT_DISCARD];
 
-               spin_unlock_irq(&blkg->q->queue_lock);
-
                if (rbytes || wbytes || rios || wios) {
                        has_stats = true;
                        off += scnprintf(buf+off, size-off,
@@ -999,6 +1000,8 @@ static int blkcg_print_stat(struct seq_file *sf, void *v)
                                seq_commit(sf, -1);
                        }
                }
+       skip:
+               spin_unlock_irq(&blkg->q->queue_lock);
        }
 
        rcu_read_unlock();
index 5b248763a672414e925f217216fc21c9a2a257fb..a18155cdce4167dd8dfa6a614c3f084c798c7009 100644 (file)
@@ -786,7 +786,6 @@ int __drbd_send_protocol(struct drbd_connection *connection, enum drbd_packet cm
 
        if (nc->tentative && connection->agreed_pro_version < 92) {
                rcu_read_unlock();
-               mutex_unlock(&sock->mutex);
                drbd_err(connection, "--dry-run is not supported by peer");
                return -EOPNOTSUPP;
        }
index 87083b3a2769d2f383f381a1f82cc219a6ac953e..37c22667e8319011aa5528613c26a9e0544e3e6e 100644 (file)
@@ -297,7 +297,10 @@ static int clk_main_probe_frequency(struct regmap *regmap)
                regmap_read(regmap, AT91_CKGR_MCFR, &mcfr);
                if (mcfr & AT91_PMC_MAINRDY)
                        return 0;
-               usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT);
+               if (system_state < SYSTEM_RUNNING)
+                       udelay(MAINF_LOOP_MIN_WAIT);
+               else
+                       usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT);
        } while (time_before(prep_time, timeout));
 
        return -ETIMEDOUT;
index 9790ddfa5b3cba525c368bc4860a7a64067aac96..86238d5ecb4da948add6b2b3b203cda5cdd7bc21 100644 (file)
@@ -43,6 +43,7 @@ static const struct clk_pll_characteristics upll_characteristics = {
 };
 
 static const struct clk_programmable_layout sam9x60_programmable_layout = {
+       .pres_mask = 0xff,
        .pres_shift = 8,
        .css_mask = 0x1f,
        .have_slck_mck = 0,
index 9bfe9a28294a7ec7f5acbb38f7e21f477355839e..fac0ca56d42d92a3df623f2d3e69cb5ca380e639 100644 (file)
@@ -76,7 +76,10 @@ static int clk_slow_osc_prepare(struct clk_hw *hw)
 
        writel(tmp | osc->bits->cr_osc32en, sckcr);
 
-       usleep_range(osc->startup_usec, osc->startup_usec + 1);
+       if (system_state < SYSTEM_RUNNING)
+               udelay(osc->startup_usec);
+       else
+               usleep_range(osc->startup_usec, osc->startup_usec + 1);
 
        return 0;
 }
@@ -187,7 +190,10 @@ static int clk_slow_rc_osc_prepare(struct clk_hw *hw)
 
        writel(readl(sckcr) | osc->bits->cr_rcen, sckcr);
 
-       usleep_range(osc->startup_usec, osc->startup_usec + 1);
+       if (system_state < SYSTEM_RUNNING)
+               udelay(osc->startup_usec);
+       else
+               usleep_range(osc->startup_usec, osc->startup_usec + 1);
 
        return 0;
 }
@@ -288,7 +294,10 @@ static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index)
 
        writel(tmp, sckcr);
 
-       usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1);
+       if (system_state < SYSTEM_RUNNING)
+               udelay(SLOWCK_SW_TIME_USEC);
+       else
+               usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1);
 
        return 0;
 }
@@ -533,7 +542,10 @@ static int clk_sama5d4_slow_osc_prepare(struct clk_hw *hw)
                return 0;
        }
 
-       usleep_range(osc->startup_usec, osc->startup_usec + 1);
+       if (system_state < SYSTEM_RUNNING)
+               udelay(osc->startup_usec);
+       else
+               usleep_range(osc->startup_usec, osc->startup_usec + 1);
        osc->prepared = true;
 
        return 0;
index 1c1bb39bb04e672ccb73bd66f78ba61f6fbac787..b1318e6b655bcc615cef2354d96278ea71f836ea 100644 (file)
@@ -266,10 +266,11 @@ static int aspeed_g6_clk_enable(struct clk_hw *hw)
 
        /* Enable clock */
        if (gate->flags & CLK_GATE_SET_TO_DISABLE) {
-               regmap_write(gate->map, get_clock_reg(gate), clk);
-       } else {
-               /* Use set to clear register */
+               /* Clock is clear to enable, so use set to clear register */
                regmap_write(gate->map, get_clock_reg(gate) + 0x04, clk);
+       } else {
+               /* Clock is set to enable, so use write to set register */
+               regmap_write(gate->map, get_clock_reg(gate), clk);
        }
 
        if (gate->reset_idx >= 0) {
index 067ab876911dd4979dae95746b0389f5bcd3caa8..172589e94f60e17658c4896b5127f0c94a170f95 100644 (file)
@@ -638,7 +638,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
                                           clks[IMX8MM_CLK_A53_DIV],
                                           clks[IMX8MM_CLK_A53_SRC],
                                           clks[IMX8MM_ARM_PLL_OUT],
-                                          clks[IMX8MM_CLK_24M]);
+                                          clks[IMX8MM_SYS_PLL1_800M]);
 
        imx_check_clocks(clks, ARRAY_SIZE(clks));
 
index 47a4b44ba3cb00319297e5afa2ec1490c50481be..58b5acee38306909e76e08587f6f310bceeab3ff 100644 (file)
@@ -610,7 +610,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
                                           clks[IMX8MN_CLK_A53_DIV],
                                           clks[IMX8MN_CLK_A53_SRC],
                                           clks[IMX8MN_ARM_PLL_OUT],
-                                          clks[IMX8MN_CLK_24M]);
+                                          clks[IMX8MN_SYS_PLL1_800M]);
 
        imx_check_clocks(clks, ARRAY_SIZE(clks));
 
index ea4c791f106ddb9604779c7805168c059cbfbf8e..b3af61cc6fb9497059aefa08e015e95c470ea294 100644 (file)
@@ -343,6 +343,7 @@ static struct clk_regmap g12a_cpu_clk_premux0 = {
                .offset = HHI_SYS_CPU_CLK_CNTL0,
                .mask = 0x3,
                .shift = 0,
+               .flags = CLK_MUX_ROUND_CLOSEST,
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_dyn0_sel",
@@ -353,8 +354,7 @@ static struct clk_regmap g12a_cpu_clk_premux0 = {
                        { .hw = &g12a_fclk_div3.hw },
                },
                .num_parents = 3,
-               /* This sub-tree is used a parking clock */
-               .flags = CLK_SET_RATE_NO_REPARENT,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -410,6 +410,7 @@ static struct clk_regmap g12a_cpu_clk_postmux0 = {
                .offset = HHI_SYS_CPU_CLK_CNTL0,
                .mask = 0x1,
                .shift = 2,
+               .flags = CLK_MUX_ROUND_CLOSEST,
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_dyn0",
@@ -466,6 +467,7 @@ static struct clk_regmap g12a_cpu_clk_dyn = {
                .offset = HHI_SYS_CPU_CLK_CNTL0,
                .mask = 0x1,
                .shift = 10,
+               .flags = CLK_MUX_ROUND_CLOSEST,
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_dyn",
@@ -485,6 +487,7 @@ static struct clk_regmap g12a_cpu_clk = {
                .offset = HHI_SYS_CPU_CLK_CNTL0,
                .mask = 0x1,
                .shift = 11,
+               .flags = CLK_MUX_ROUND_CLOSEST,
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk",
@@ -504,6 +507,7 @@ static struct clk_regmap g12b_cpu_clk = {
                .offset = HHI_SYS_CPU_CLK_CNTL0,
                .mask = 0x1,
                .shift = 11,
+               .flags = CLK_MUX_ROUND_CLOSEST,
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk",
@@ -523,6 +527,7 @@ static struct clk_regmap g12b_cpub_clk_premux0 = {
                .offset = HHI_SYS_CPUB_CLK_CNTL,
                .mask = 0x3,
                .shift = 0,
+               .flags = CLK_MUX_ROUND_CLOSEST,
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_dyn0_sel",
@@ -533,6 +538,7 @@ static struct clk_regmap g12b_cpub_clk_premux0 = {
                        { .hw = &g12a_fclk_div3.hw },
                },
                .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -567,6 +573,7 @@ static struct clk_regmap g12b_cpub_clk_postmux0 = {
                .offset = HHI_SYS_CPUB_CLK_CNTL,
                .mask = 0x1,
                .shift = 2,
+               .flags = CLK_MUX_ROUND_CLOSEST,
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_dyn0",
@@ -644,6 +651,7 @@ static struct clk_regmap g12b_cpub_clk_dyn = {
                .offset = HHI_SYS_CPUB_CLK_CNTL,
                .mask = 0x1,
                .shift = 10,
+               .flags = CLK_MUX_ROUND_CLOSEST,
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_dyn",
@@ -663,6 +671,7 @@ static struct clk_regmap g12b_cpub_clk = {
                .offset = HHI_SYS_CPUB_CLK_CNTL,
                .mask = 0x1,
                .shift = 11,
+               .flags = CLK_MUX_ROUND_CLOSEST,
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk",
index 7cfb998eeb3e0e05234f041ce0bb6938dc7db1f9..1f9c056e684ce0bf93cff9f4868da37d7f4282f2 100644 (file)
@@ -935,6 +935,7 @@ static struct clk_regmap gxbb_sar_adc_clk_div = {
                        &gxbb_sar_adc_clk_sel.hw
                },
                .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
index 7670cc596c74245205babf39e339c8e0b5e087f6..31466cd1842f860727869e651a748839e67ec2e5 100644 (file)
@@ -165,12 +165,18 @@ static const unsigned long exynos5x_clk_regs[] __initconst = {
        GATE_BUS_CPU,
        GATE_SCLK_CPU,
        CLKOUT_CMU_CPU,
+       CPLL_CON0,
+       DPLL_CON0,
        EPLL_CON0,
        EPLL_CON1,
        EPLL_CON2,
        RPLL_CON0,
        RPLL_CON1,
        RPLL_CON2,
+       IPLL_CON0,
+       SPLL_CON0,
+       VPLL_CON0,
+       MPLL_CON0,
        SRC_TOP0,
        SRC_TOP1,
        SRC_TOP2,
@@ -1172,8 +1178,6 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = {
        GATE(CLK_SCLK_ISP_SENSOR2, "sclk_isp_sensor2", "dout_isp_sensor2",
                        GATE_TOP_SCLK_ISP, 12, CLK_SET_RATE_PARENT, 0),
 
-       GATE(CLK_G3D, "g3d", "mout_user_aclk_g3d", GATE_IP_G3D, 9, 0, 0),
-
        /* CDREX */
        GATE(CLK_CLKM_PHY0, "clkm_phy0", "dout_sclk_cdrex",
                        GATE_BUS_CDREX0, 0, 0, 0),
@@ -1248,6 +1252,15 @@ static struct exynos5_subcmu_reg_dump exynos5x_gsc_suspend_regs[] = {
        { DIV2_RATIO0, 0, 0x30 },       /* DIV dout_gscl_blk_300 */
 };
 
+static const struct samsung_gate_clock exynos5x_g3d_gate_clks[] __initconst = {
+       GATE(CLK_G3D, "g3d", "mout_user_aclk_g3d", GATE_IP_G3D, 9, 0, 0),
+};
+
+static struct exynos5_subcmu_reg_dump exynos5x_g3d_suspend_regs[] = {
+       { GATE_IP_G3D, 0x3ff, 0x3ff },  /* G3D gates */
+       { SRC_TOP5, 0, BIT(16) },       /* MUX mout_user_aclk_g3d */
+};
+
 static const struct samsung_div_clock exynos5x_mfc_div_clks[] __initconst = {
        DIV(0, "dout_mfc_blk", "mout_user_aclk333", DIV4_RATIO, 0, 2),
 };
@@ -1320,6 +1333,14 @@ static const struct exynos5_subcmu_info exynos5x_gsc_subcmu = {
        .pd_name        = "GSC",
 };
 
+static const struct exynos5_subcmu_info exynos5x_g3d_subcmu = {
+       .gate_clks      = exynos5x_g3d_gate_clks,
+       .nr_gate_clks   = ARRAY_SIZE(exynos5x_g3d_gate_clks),
+       .suspend_regs   = exynos5x_g3d_suspend_regs,
+       .nr_suspend_regs = ARRAY_SIZE(exynos5x_g3d_suspend_regs),
+       .pd_name        = "G3D",
+};
+
 static const struct exynos5_subcmu_info exynos5x_mfc_subcmu = {
        .div_clks       = exynos5x_mfc_div_clks,
        .nr_div_clks    = ARRAY_SIZE(exynos5x_mfc_div_clks),
@@ -1351,6 +1372,7 @@ static const struct exynos5_subcmu_info exynos5800_mau_subcmu = {
 static const struct exynos5_subcmu_info *exynos5x_subcmus[] = {
        &exynos5x_disp_subcmu,
        &exynos5x_gsc_subcmu,
+       &exynos5x_g3d_subcmu,
        &exynos5x_mfc_subcmu,
        &exynos5x_mscl_subcmu,
 };
@@ -1358,6 +1380,7 @@ static const struct exynos5_subcmu_info *exynos5x_subcmus[] = {
 static const struct exynos5_subcmu_info *exynos5800_subcmus[] = {
        &exynos5x_disp_subcmu,
        &exynos5x_gsc_subcmu,
+       &exynos5x_g3d_subcmu,
        &exynos5x_mfc_subcmu,
        &exynos5x_mscl_subcmu,
        &exynos5800_mau_subcmu,
index 7824c2ba3d8e6c29c850f67655da8b9fd0d6201d..4b1aa9382ad28e01e755e6207d78c0720ec5c665 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/slab.h>
 
 #include <dt-bindings/clock/exynos5433.h>
 
@@ -5584,6 +5585,8 @@ static int __init exynos5433_cmu_probe(struct platform_device *pdev)
 
        data->clk_save = samsung_clk_alloc_reg_dump(info->clk_regs,
                                                    info->nr_clk_regs);
+       if (!data->clk_save)
+               return -ENOMEM;
        data->nr_clk_save = info->nr_clk_regs;
        data->clk_suspend = info->suspend_regs;
        data->nr_clk_suspend = info->nr_suspend_regs;
@@ -5592,12 +5595,19 @@ static int __init exynos5433_cmu_probe(struct platform_device *pdev)
        if (data->nr_pclks > 0) {
                data->pclks = devm_kcalloc(dev, sizeof(struct clk *),
                                           data->nr_pclks, GFP_KERNEL);
-
+               if (!data->pclks) {
+                       kfree(data->clk_save);
+                       return -ENOMEM;
+               }
                for (i = 0; i < data->nr_pclks; i++) {
                        struct clk *clk = of_clk_get(dev->of_node, i);
 
-                       if (IS_ERR(clk))
+                       if (IS_ERR(clk)) {
+                               kfree(data->clk_save);
+                               while (--i >= 0)
+                                       clk_put(data->pclks[i]);
                                return PTR_ERR(clk);
+                       }
                        data->pclks[i] = clk;
                }
        }
index dcac1391767f6887913d91f8c5938d26822b5bc5..ef29582676f6eee6a5aeed679730ebd5c942ecae 100644 (file)
@@ -1224,7 +1224,7 @@ static int sun9i_a80_ccu_probe(struct platform_device *pdev)
 
        /* Enforce d1 = 0, d2 = 0 for Audio PLL */
        val = readl(reg + SUN9I_A80_PLL_AUDIO_REG);
-       val &= (BIT(16) & BIT(18));
+       val &= ~(BIT(16) | BIT(18));
        writel(val, reg + SUN9I_A80_PLL_AUDIO_REG);
 
        /* Enforce P = 1 for both CPU cluster PLLs */
index d3a43381a792700a96f618e4e86924612d529aa3..27201fd26e4422b7bd5eba152be7e0693029c95a 100644 (file)
@@ -1080,8 +1080,8 @@ static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node,
                                                 rate_hw, rate_ops,
                                                 gate_hw, &clk_gate_ops,
                                                 clkflags |
-                                                data->div[i].critical ?
-                                                       CLK_IS_CRITICAL : 0);
+                                                (data->div[i].critical ?
+                                                       CLK_IS_CRITICAL : 0));
 
                WARN_ON(IS_ERR(clk_data->clks[i]));
        }
index a01ca9395179a77c9f0c620e5389fe98b1d0fba3..f65e16c4f3c4b8585ea56cc97633730a6882a01f 100644 (file)
@@ -174,7 +174,6 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node)
        struct clk_init_data init = { NULL };
        const char **parent_names = NULL;
        struct clk *clk;
-       int ret;
 
        clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
        if (!clk_hw) {
@@ -207,11 +206,6 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node)
        clk = ti_clk_register(NULL, &clk_hw->hw, node->name);
 
        if (!IS_ERR(clk)) {
-               ret = ti_clk_add_alias(NULL, clk, node->name);
-               if (ret) {
-                       clk_unregister(clk);
-                       goto cleanup;
-               }
                of_clk_add_provider(node, of_clk_src_simple_get, clk);
                kfree(parent_names);
                return;
index 975995eea15cb51d64100e625f6b433c34998998..b0c0690a5a121ab35b173bc26a40c4720a2d18a1 100644 (file)
@@ -100,11 +100,12 @@ static bool _omap4_is_timeout(union omap4_timeout *time, u32 timeout)
         * can be from a timer that requires pm_runtime access, which
         * will eventually bring us here with timekeeping_suspended,
         * during both suspend entry and resume paths. This happens
-        * at least on am43xx platform.
+        * at least on am43xx platform. Account for flakeyness
+        * with udelay() by multiplying the timeout value by 2.
         */
        if (unlikely(_early_timeout || timekeeping_suspended)) {
                if (time->cycles++ < timeout) {
-                       udelay(1);
+                       udelay(1 * 2);
                        return false;
                }
        } else {
index 53a51c169451f7f71f1f99652a42cb5532aa5963..8ab31702cf6a26daa5e9e9ab6e641f309f0d228a 100644 (file)
@@ -847,11 +847,9 @@ static void intel_pstate_hwp_force_min_perf(int cpu)
        value |= HWP_MAX_PERF(min_perf);
        value |= HWP_MIN_PERF(min_perf);
 
-       /* Set EPP/EPB to min */
+       /* Set EPP to min */
        if (boot_cpu_has(X86_FEATURE_HWP_EPP))
                value |= HWP_ENERGY_PERF_PREFERENCE(HWP_EPP_POWERSAVE);
-       else
-               intel_pstate_set_epb(cpu, HWP_EPP_BALANCE_POWERSAVE);
 
        wrmsrl_on_cpu(cpu, MSR_HWP_REQUEST, value);
 }
index 2f1e9da81c1e422644e1611fd5c43b6a14cc0b85..3302125e5265110722d131c7979a8a5d4da0e081 100644 (file)
@@ -362,9 +362,8 @@ static void mrfld_irq_handler(struct irq_desc *desc)
        chained_irq_exit(irqchip, desc);
 }
 
-static int mrfld_irq_init_hw(struct gpio_chip *chip)
+static void mrfld_irq_init_hw(struct mrfld_gpio *priv)
 {
-       struct mrfld_gpio *priv = gpiochip_get_data(chip);
        void __iomem *reg;
        unsigned int base;
 
@@ -376,8 +375,6 @@ static int mrfld_irq_init_hw(struct gpio_chip *chip)
                reg = gpio_reg(&priv->chip, base, GFER);
                writel(0, reg);
        }
-
-       return 0;
 }
 
 static const char *mrfld_gpio_get_pinctrl_dev_name(struct mrfld_gpio *priv)
@@ -400,7 +397,6 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id
 {
        const struct mrfld_gpio_pinrange *range;
        const char *pinctrl_dev_name;
-       struct gpio_irq_chip *girq;
        struct mrfld_gpio *priv;
        u32 gpio_base, irq_base;
        void __iomem *base;
@@ -448,21 +444,6 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id
 
        raw_spin_lock_init(&priv->lock);
 
-       girq = &priv->chip.irq;
-       girq->chip = &mrfld_irqchip;
-       girq->init_hw = mrfld_irq_init_hw;
-       girq->parent_handler = mrfld_irq_handler;
-       girq->num_parents = 1;
-       girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents,
-                                    sizeof(*girq->parents),
-                                    GFP_KERNEL);
-       if (!girq->parents)
-               return -ENOMEM;
-       girq->parents[0] = pdev->irq;
-       girq->first = irq_base;
-       girq->default_type = IRQ_TYPE_NONE;
-       girq->handler = handle_bad_irq;
-
        pci_set_drvdata(pdev, priv);
        retval = devm_gpiochip_add_data(&pdev->dev, &priv->chip, priv);
        if (retval) {
@@ -484,6 +465,18 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id
                }
        }
 
+       retval = gpiochip_irqchip_add(&priv->chip, &mrfld_irqchip, irq_base,
+                                     handle_bad_irq, IRQ_TYPE_NONE);
+       if (retval) {
+               dev_err(&pdev->dev, "could not connect irqchip to gpiochip\n");
+               return retval;
+       }
+
+       mrfld_irq_init_hw(priv);
+
+       gpiochip_set_chained_irqchip(&priv->chip, &mrfld_irqchip, pdev->irq,
+                                    mrfld_irq_handler);
+
        return 0;
 }
 
index 6614d8a6f4c8d367dcb8bb281f70514f6a054f22..2cdaf3b2a72170c5a638530dce89007e850735a8 100644 (file)
@@ -604,8 +604,11 @@ void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr)
                        continue;
                }
 
-               for (i = 0; i < num_entities; i++)
+               for (i = 0; i < num_entities; i++) {
+                       mutex_lock(&ctx->adev->lock_reset);
                        drm_sched_entity_fini(&ctx->entities[0][i].entity);
+                       mutex_unlock(&ctx->adev->lock_reset);
+               }
        }
 }
 
index 5a1939dbd4e3e6785066854f4224f6ffe881f7fd..7a6c837c0a85feb7d9ae4ef218a3852c0457229b 100644 (file)
@@ -2885,6 +2885,13 @@ fence_driver_init:
                        DRM_INFO("amdgpu: acceleration disabled, skipping benchmarks\n");
        }
 
+       /*
+        * Register gpu instance before amdgpu_device_enable_mgpu_fan_boost.
+        * Otherwise the mgpu fan boost feature will be skipped due to the
+        * gpu instance is counted less.
+        */
+       amdgpu_register_gpu_instance(adev);
+
        /* enable clockgating, etc. after ib tests, etc. since some blocks require
         * explicit gating rather than handling it automatically.
         */
index 2a00a36106b2d6c78cd6536d2d79ae7933dc4bdc..e1c15721611a89a6f314b2f5b41038a6396488d8 100644 (file)
@@ -1016,6 +1016,7 @@ static const struct pci_device_id pciidlist[] = {
        {0x1002, 0x7340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI14|AMD_EXP_HW_SUPPORT},
        {0x1002, 0x7341, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI14|AMD_EXP_HW_SUPPORT},
        {0x1002, 0x7347, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI14|AMD_EXP_HW_SUPPORT},
+       {0x1002, 0x734F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI14|AMD_EXP_HW_SUPPORT},
 
        /* Renoir */
        {0x1002, 0x1636, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RENOIR|AMD_IS_APU|AMD_EXP_HW_SUPPORT},
index 6ee4021910e2cddbad2900f7bb2fe8860f592100..6d19183b478b5d10262a7e94bd568481827b9dcc 100644 (file)
@@ -289,6 +289,7 @@ struct amdgpu_gfx {
        uint32_t                        mec2_feature_version;
        bool                            mec_fw_write_wait;
        bool                            me_fw_write_wait;
+       bool                            cp_fw_write_wait;
        struct amdgpu_ring              gfx_ring[AMDGPU_MAX_GFX_RINGS];
        unsigned                        num_gfx_rings;
        struct amdgpu_ring              compute_ring[AMDGPU_MAX_COMPUTE_RINGS];
index d55f5baa83d37343edad07b6946f35fb04c698ac..a042ef471fbd8bd9d318683524c5876ac3af0eca 100644 (file)
@@ -190,7 +190,6 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags)
                pm_runtime_put_autosuspend(dev->dev);
        }
 
-       amdgpu_register_gpu_instance(adev);
 out:
        if (r) {
                /* balance pm_runtime_get_sync in amdgpu_driver_unload_kms */
index 8dfc775626a7a080ee68f58f79dc18462db14cc9..53090eae0082edb0751826c5db3729e5beb655d2 100644 (file)
@@ -564,6 +564,32 @@ static void gfx_v10_0_free_microcode(struct amdgpu_device *adev)
        kfree(adev->gfx.rlc.register_list_format);
 }
 
+static void gfx_v10_0_check_fw_write_wait(struct amdgpu_device *adev)
+{
+       adev->gfx.cp_fw_write_wait = false;
+
+       switch (adev->asic_type) {
+       case CHIP_NAVI10:
+       case CHIP_NAVI12:
+       case CHIP_NAVI14:
+               if ((adev->gfx.me_fw_version >= 0x00000046) &&
+                   (adev->gfx.me_feature_version >= 27) &&
+                   (adev->gfx.pfp_fw_version >= 0x00000068) &&
+                   (adev->gfx.pfp_feature_version >= 27) &&
+                   (adev->gfx.mec_fw_version >= 0x0000005b) &&
+                   (adev->gfx.mec_feature_version >= 27))
+                       adev->gfx.cp_fw_write_wait = true;
+               break;
+       default:
+               break;
+       }
+
+       if (adev->gfx.cp_fw_write_wait == false)
+               DRM_WARN_ONCE("Warning: check cp_fw_version and update it to realize \
+                             GRBM requires 1-cycle delay in cp firmware\n");
+}
+
+
 static void gfx_v10_0_init_rlc_ext_microcode(struct amdgpu_device *adev)
 {
        const struct rlc_firmware_header_v2_1 *rlc_hdr;
@@ -832,6 +858,7 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
                }
        }
 
+       gfx_v10_0_check_fw_write_wait(adev);
 out:
        if (err) {
                dev_err(adev->dev,
@@ -4765,6 +4792,24 @@ static void gfx_v10_0_ring_emit_reg_wait(struct amdgpu_ring *ring, uint32_t reg,
        gfx_v10_0_wait_reg_mem(ring, 0, 0, 0, reg, 0, val, mask, 0x20);
 }
 
+static void gfx_v10_0_ring_emit_reg_write_reg_wait(struct amdgpu_ring *ring,
+                                                  uint32_t reg0, uint32_t reg1,
+                                                  uint32_t ref, uint32_t mask)
+{
+       int usepfp = (ring->funcs->type == AMDGPU_RING_TYPE_GFX);
+       struct amdgpu_device *adev = ring->adev;
+       bool fw_version_ok = false;
+
+       fw_version_ok = adev->gfx.cp_fw_write_wait;
+
+       if (fw_version_ok)
+               gfx_v10_0_wait_reg_mem(ring, usepfp, 0, 1, reg0, reg1,
+                                      ref, mask, 0x20);
+       else
+               amdgpu_ring_emit_reg_write_reg_wait_helper(ring, reg0, reg1,
+                                                          ref, mask);
+}
+
 static void
 gfx_v10_0_set_gfx_eop_interrupt_state(struct amdgpu_device *adev,
                                      uint32_t me, uint32_t pipe,
@@ -5155,6 +5200,7 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_gfx = {
        .emit_tmz = gfx_v10_0_ring_emit_tmz,
        .emit_wreg = gfx_v10_0_ring_emit_wreg,
        .emit_reg_wait = gfx_v10_0_ring_emit_reg_wait,
+       .emit_reg_write_reg_wait = gfx_v10_0_ring_emit_reg_write_reg_wait,
 };
 
 static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_compute = {
@@ -5188,6 +5234,7 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_compute = {
        .pad_ib = amdgpu_ring_generic_pad_ib,
        .emit_wreg = gfx_v10_0_ring_emit_wreg,
        .emit_reg_wait = gfx_v10_0_ring_emit_reg_wait,
+       .emit_reg_write_reg_wait = gfx_v10_0_ring_emit_reg_write_reg_wait,
 };
 
 static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_kiq = {
@@ -5218,6 +5265,7 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_kiq = {
        .emit_rreg = gfx_v10_0_ring_emit_rreg,
        .emit_wreg = gfx_v10_0_ring_emit_wreg,
        .emit_reg_wait = gfx_v10_0_ring_emit_reg_wait,
+       .emit_reg_write_reg_wait = gfx_v10_0_ring_emit_reg_write_reg_wait,
 };
 
 static void gfx_v10_0_set_ring_funcs(struct amdgpu_device *adev)
index dcadc73bffd27b111a64319cd9fe7f0a49509544..dfca83a2de47ecde430b47e191c06372354e52ca 100644 (file)
@@ -973,6 +973,13 @@ static void gfx_v9_0_check_fw_write_wait(struct amdgpu_device *adev)
        adev->gfx.me_fw_write_wait = false;
        adev->gfx.mec_fw_write_wait = false;
 
+       if ((adev->gfx.mec_fw_version < 0x000001a5) ||
+           (adev->gfx.mec_feature_version < 46) ||
+           (adev->gfx.pfp_fw_version < 0x000000b7) ||
+           (adev->gfx.pfp_feature_version < 46))
+               DRM_WARN_ONCE("Warning: check cp_fw_version and update it to realize \
+                             GRBM requires 1-cycle delay in cp firmware\n");
+
        switch (adev->asic_type) {
        case CHIP_VEGA10:
                if ((adev->gfx.me_fw_version >= 0x0000009c) &&
@@ -1039,6 +1046,12 @@ static void gfx_v9_0_check_if_need_gfxoff(struct amdgpu_device *adev)
                            !adev->gfx.rlc.is_rlc_v2_1))
                        adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
 
+               if (adev->pm.pp_feature & PP_GFXOFF_MASK)
+                       adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG |
+                               AMD_PG_SUPPORT_CP |
+                               AMD_PG_SUPPORT_RLC_SMU_HS;
+               break;
+       case CHIP_RENOIR:
                if (adev->pm.pp_feature & PP_GFXOFF_MASK)
                        adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG |
                                AMD_PG_SUPPORT_CP |
index 354e6200ca9a129c903399fbebf6848089266bd1..5c7d5f73f54f6f8e1d23c0cb2e248f29e7e9b77c 100644 (file)
@@ -344,11 +344,9 @@ static uint64_t gmc_v10_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring,
        amdgpu_ring_emit_wreg(ring, hub->ctx0_ptb_addr_hi32 + (2 * vmid),
                              upper_32_bits(pd_addr));
 
-       amdgpu_ring_emit_wreg(ring, hub->vm_inv_eng0_req + eng, req);
-
-       /* wait for the invalidate to complete */
-       amdgpu_ring_emit_reg_wait(ring, hub->vm_inv_eng0_ack + eng,
-                                 1 << vmid, 1 << vmid);
+       amdgpu_ring_emit_reg_write_reg_wait(ring, hub->vm_inv_eng0_req + eng,
+                                           hub->vm_inv_eng0_ack + eng,
+                                           req, 1 << vmid);
 
        return pd_addr;
 }
index 0cf7ef44b4b5c7015d018612a872fb32596b3a54..9ed178fa241cc8266847db8ff265fb7b0af9bace 100644 (file)
@@ -219,6 +219,15 @@ static void mmhub_v9_4_init_cache_regs(struct amdgpu_device *adev, int hubid)
                            hubid * MMHUB_INSTANCE_REGISTER_OFFSET, tmp);
 
        tmp = mmVML2PF0_VM_L2_CNTL3_DEFAULT;
+       if (adev->gmc.translate_further) {
+               tmp = REG_SET_FIELD(tmp, VML2PF0_VM_L2_CNTL3, BANK_SELECT, 12);
+               tmp = REG_SET_FIELD(tmp, VML2PF0_VM_L2_CNTL3,
+                                   L2_CACHE_BIGK_FRAGMENT_SIZE, 9);
+       } else {
+               tmp = REG_SET_FIELD(tmp, VML2PF0_VM_L2_CNTL3, BANK_SELECT, 9);
+               tmp = REG_SET_FIELD(tmp, VML2PF0_VM_L2_CNTL3,
+                                   L2_CACHE_BIGK_FRAGMENT_SIZE, 6);
+       }
        WREG32_SOC15_OFFSET(MMHUB, 0, mmVML2PF0_VM_L2_CNTL3,
                            hubid * MMHUB_INSTANCE_REGISTER_OFFSET, tmp);
 
index f6e81680dd7e8edd03cc2ada50008db924d93692..8493bfbbc148437254ae5efbad1e5708738f9424 100644 (file)
@@ -1173,6 +1173,16 @@ static void sdma_v5_0_ring_emit_reg_wait(struct amdgpu_ring *ring, uint32_t reg,
                          SDMA_PKT_POLL_REGMEM_DW5_INTERVAL(10));
 }
 
+static void sdma_v5_0_ring_emit_reg_write_reg_wait(struct amdgpu_ring *ring,
+                                                  uint32_t reg0, uint32_t reg1,
+                                                  uint32_t ref, uint32_t mask)
+{
+       amdgpu_ring_emit_wreg(ring, reg0, ref);
+       /* wait for a cycle to reset vm_inv_eng*_ack */
+       amdgpu_ring_emit_reg_wait(ring, reg0, 0, 0);
+       amdgpu_ring_emit_reg_wait(ring, reg1, mask, mask);
+}
+
 static int sdma_v5_0_early_init(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
@@ -1588,7 +1598,7 @@ static const struct amdgpu_ring_funcs sdma_v5_0_ring_funcs = {
                6 + /* sdma_v5_0_ring_emit_pipeline_sync */
                /* sdma_v5_0_ring_emit_vm_flush */
                SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
-               SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 6 +
+               SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 6 * 2 +
                10 + 10 + 10, /* sdma_v5_0_ring_emit_fence x3 for user fence, vm fence */
        .emit_ib_size = 7 + 6, /* sdma_v5_0_ring_emit_ib */
        .emit_ib = sdma_v5_0_ring_emit_ib,
@@ -1602,6 +1612,7 @@ static const struct amdgpu_ring_funcs sdma_v5_0_ring_funcs = {
        .pad_ib = sdma_v5_0_ring_pad_ib,
        .emit_wreg = sdma_v5_0_ring_emit_wreg,
        .emit_reg_wait = sdma_v5_0_ring_emit_reg_wait,
+       .emit_reg_write_reg_wait = sdma_v5_0_ring_emit_reg_write_reg_wait,
        .init_cond_exec = sdma_v5_0_ring_init_cond_exec,
        .patch_cond_exec = sdma_v5_0_ring_patch_cond_exec,
        .preempt_ib = sdma_v5_0_ring_preempt_ib,
index f8ab80c8801b1bfbce2ec1f1735feb5a857cb21e..4ccfcdf8f16a5ccf565c47639f808273fce7e48e 100644 (file)
@@ -1186,11 +1186,6 @@ static int soc15_common_early_init(void *handle)
                                 AMD_PG_SUPPORT_VCN |
                                 AMD_PG_SUPPORT_VCN_DPG;
                adev->external_rev_id = adev->rev_id + 0x91;
-
-               if (adev->pm.pp_feature & PP_GFXOFF_MASK)
-                       adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG |
-                               AMD_PG_SUPPORT_CP |
-                               AMD_PG_SUPPORT_RLC_SMU_HS;
                break;
        default:
                /* FIXME: not supported yet */
index 9c58670d541402d0f0b5780cfaa22d3dff4346b2..ca20b150afcc237ba21f8ad46f4bc3bb3b1d97d4 100644 (file)
@@ -2767,15 +2767,6 @@ void core_link_enable_stream(
                                        CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
                                        COLOR_DEPTH_UNDEFINED);
 
-               /* This second call is needed to reconfigure the DIG
-                * as a workaround for the incorrect value being applied
-                * from transmitter control.
-                */
-               if (!dc_is_virtual_signal(pipe_ctx->stream->signal))
-                       stream->link->link_enc->funcs->setup(
-                               stream->link->link_enc,
-                               pipe_ctx->stream->signal);
-
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
                if (pipe_ctx->stream->timing.flags.DSC) {
                        if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
index dfb208285a9cdd6cb817afbc3cf0ac3a1964200b..6b2f2f1a1c9ce96fc683a37e3118478367a68e4b 100644 (file)
@@ -1107,6 +1107,11 @@ struct stream_encoder *dcn20_stream_encoder_create(
        if (!enc1)
                return NULL;
 
+       if (ASICREV_IS_NAVI14_M(ctx->asic_id.hw_internal_rev)) {
+               if (eng_id >= ENGINE_ID_DIGD)
+                       eng_id++;
+       }
+
        dcn20_stream_encoder_construct(enc1, ctx, ctx->dc_bios, eng_id,
                                        &stream_enc_regs[eng_id],
                                        &se_shift, &se_mask);
index 0b461404af6b489972fd62dca5217c8bc32191cc..3ec5a10a7c4d5d079de59d8395ced020f8bed7ab 100644 (file)
@@ -205,7 +205,7 @@ static struct smu_11_0_cmn2aisc_mapping navi10_workload_map[PP_SMC_POWER_PROFILE
        WORKLOAD_MAP(PP_SMC_POWER_PROFILE_POWERSAVING,          WORKLOAD_PPLIB_POWER_SAVING_BIT),
        WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VIDEO,                WORKLOAD_PPLIB_VIDEO_BIT),
        WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VR,                   WORKLOAD_PPLIB_VR_BIT),
-       WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE,              WORKLOAD_PPLIB_CUSTOM_BIT),
+       WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE,              WORKLOAD_PPLIB_COMPUTE_BIT),
        WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM,               WORKLOAD_PPLIB_CUSTOM_BIT),
 };
 
index bbd8ebd58434bd2b00316a5d71bbbfd05d456fce..92c393f613d3785c8c610bd12dc91131eb9cd258 100644 (file)
@@ -219,7 +219,7 @@ static struct smu_11_0_cmn2aisc_mapping vega20_workload_map[PP_SMC_POWER_PROFILE
        WORKLOAD_MAP(PP_SMC_POWER_PROFILE_POWERSAVING,          WORKLOAD_PPLIB_POWER_SAVING_BIT),
        WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VIDEO,                WORKLOAD_PPLIB_VIDEO_BIT),
        WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VR,                   WORKLOAD_PPLIB_VR_BIT),
-       WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE,              WORKLOAD_PPLIB_CUSTOM_BIT),
+       WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE,              WORKLOAD_PPLIB_COMPUTE_BIT),
        WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM,               WORKLOAD_PPLIB_CUSTOM_BIT),
 };
 
index 3ef2ac52ce942c303fbec865587fa7b95933ad15..2dd2cd87cdbb39776c1671772270d5ff89fcbb19 100644 (file)
@@ -1581,8 +1581,11 @@ static void commit_tail(struct drm_atomic_state *old_state)
 {
        struct drm_device *dev = old_state->dev;
        const struct drm_mode_config_helper_funcs *funcs;
+       struct drm_crtc_state *new_crtc_state;
+       struct drm_crtc *crtc;
        ktime_t start;
        s64 commit_time_ms;
+       unsigned int i, new_self_refresh_mask = 0;
 
        funcs = dev->mode_config.helper_private;
 
@@ -1602,6 +1605,15 @@ static void commit_tail(struct drm_atomic_state *old_state)
 
        drm_atomic_helper_wait_for_dependencies(old_state);
 
+       /*
+        * We cannot safely access new_crtc_state after
+        * drm_atomic_helper_commit_hw_done() so figure out which crtc's have
+        * self-refresh active beforehand:
+        */
+       for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i)
+               if (new_crtc_state->self_refresh_active)
+                       new_self_refresh_mask |= BIT(i);
+
        if (funcs && funcs->atomic_commit_tail)
                funcs->atomic_commit_tail(old_state);
        else
@@ -1610,7 +1622,8 @@ static void commit_tail(struct drm_atomic_state *old_state)
        commit_time_ms = ktime_ms_delta(ktime_get(), start);
        if (commit_time_ms > 0)
                drm_self_refresh_helper_update_avg_times(old_state,
-                                                (unsigned long)commit_time_ms);
+                                                (unsigned long)commit_time_ms,
+                                                new_self_refresh_mask);
 
        drm_atomic_helper_commit_cleanup_done(old_state);
 
index 68f4765a5896472775500836b7dfc537de0b862a..dd33fec5aabdedcdbac2c99180c56b6737875aab 100644 (file)
@@ -133,29 +133,33 @@ out_drop_locks:
  * drm_self_refresh_helper_update_avg_times - Updates a crtc's SR time averages
  * @state: the state which has just been applied to hardware
  * @commit_time_ms: the amount of time in ms that this commit took to complete
+ * @new_self_refresh_mask: bitmask of crtc's that have self_refresh_active in
+ *    new state
  *
  * Called after &drm_mode_config_funcs.atomic_commit_tail, this function will
  * update the average entry/exit self refresh times on self refresh transitions.
  * These averages will be used when calculating how long to delay before
  * entering self refresh mode after activity.
  */
-void drm_self_refresh_helper_update_avg_times(struct drm_atomic_state *state,
-                                             unsigned int commit_time_ms)
+void
+drm_self_refresh_helper_update_avg_times(struct drm_atomic_state *state,
+                                        unsigned int commit_time_ms,
+                                        unsigned int new_self_refresh_mask)
 {
        struct drm_crtc *crtc;
-       struct drm_crtc_state *old_crtc_state, *new_crtc_state;
+       struct drm_crtc_state *old_crtc_state;
        int i;
 
-       for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
-                                     new_crtc_state, i) {
+       for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) {
+               bool new_self_refresh_active = new_self_refresh_mask & BIT(i);
                struct drm_self_refresh_data *sr_data = crtc->self_refresh_data;
                struct ewma_psr_time *time;
 
                if (old_crtc_state->self_refresh_active ==
-                   new_crtc_state->self_refresh_active)
+                   new_self_refresh_active)
                        continue;
 
-               if (new_crtc_state->self_refresh_active)
+               if (new_self_refresh_active)
                        time = &sr_data->entry_avg_ms;
                else
                        time = &sr_data->exit_avg_ms;
index e6e8d4a820446a7fd99f7b7af735a378d8d0918e..0a08354a61836af78bd47c08c090ba2cc1c75b85 100644 (file)
@@ -864,6 +864,13 @@ load_detect:
 
 out:
        intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref);
+
+       /*
+        * Make sure the refs for power wells enabled during detect are
+        * dropped to avoid a new detect cycle triggered by HPD polling.
+        */
+       intel_display_power_flush_work(dev_priv);
+
        return status;
 }
 
index 57e9f0ba331b4e7a31ecd4898dfc5410020c3980..9b15ac4f2fb6e00a259b162dc273cc57a3495160 100644 (file)
@@ -1256,6 +1256,9 @@ static u32 skl_get_aux_send_ctl(struct intel_dp *intel_dp,
                                u32 unused)
 {
        struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+       struct drm_i915_private *i915 =
+                       to_i915(intel_dig_port->base.base.dev);
+       enum phy phy = intel_port_to_phy(i915, intel_dig_port->base.port);
        u32 ret;
 
        ret = DP_AUX_CH_CTL_SEND_BUSY |
@@ -1268,7 +1271,8 @@ static u32 skl_get_aux_send_ctl(struct intel_dp *intel_dp,
              DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(32) |
              DP_AUX_CH_CTL_SYNC_PULSE_SKL(32);
 
-       if (intel_dig_port->tc_mode == TC_PORT_TBT_ALT)
+       if (intel_phy_is_tc(i915, phy) &&
+           intel_dig_port->tc_mode == TC_PORT_TBT_ALT)
                ret |= DP_AUX_CH_CTL_TBT_IO;
 
        return ret;
@@ -5436,6 +5440,12 @@ out:
        if (status != connector_status_connected && !intel_dp->is_mst)
                intel_dp_unset_edid(intel_dp);
 
+       /*
+        * Make sure the refs for power wells enabled during detect are
+        * dropped to avoid a new detect cycle triggered by HPD polling.
+        */
+       intel_display_power_flush_work(dev_priv);
+
        return status;
 }
 
index e02f0faecf02806235df03dbe870ec88dd9b5a73..b030f7ae330290393f3fe7136ccc078503b33828 100644 (file)
@@ -2565,6 +2565,12 @@ out:
        if (status != connector_status_connected)
                cec_notifier_phys_addr_invalidate(intel_hdmi->cec_notifier);
 
+       /*
+        * Make sure the refs for power wells enabled during detect are
+        * dropped to avoid a new detect cycle triggered by HPD polling.
+        */
+       intel_display_power_flush_work(dev_priv);
+
        return status;
 }
 
index 460fd98e40a78ded29005383d0e56b34737f2e3d..a0b382a637a6428d15dfad0ed28558aa7add4677 100644 (file)
@@ -1958,6 +1958,7 @@ static void si_initialize_powertune_defaults(struct radeon_device *rdev)
                case 0x682C:
                        si_pi->cac_weights = cac_weights_cape_verde_pro;
                        si_pi->dte_data = dte_data_sun_xt;
+                       update_dte_from_pl2 = true;
                        break;
                case 0x6825:
                case 0x6827:
index d9c55e30f986b6e04927c2f94c20ceb387e0104c..04c088131e044bc649bbe7b414bb892bd01fe2b0 100644 (file)
@@ -447,8 +447,12 @@ static int i2c_hid_hwreset(struct i2c_client *client)
        if (ret) {
                dev_err(&client->dev, "failed to reset device.\n");
                i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
+               goto out_unlock;
        }
 
+       /* At least some SIS devices need this after reset */
+       ret = i2c_hid_set_power(client, I2C_HID_PWR_ON);
+
 out_unlock:
        mutex_unlock(&ihid->reset_lock);
        return ret;
index 4a7f8d363220dc1cd507e0476edc92a7d7724ad9..203d27d198b818a364c2614097fb62f3748f0d21 100644 (file)
@@ -202,6 +202,21 @@ static inline void wacom_schedule_work(struct wacom_wac *wacom_wac,
        }
 }
 
+/*
+ * Convert a signed 32-bit integer to an unsigned n-bit integer. Undoes
+ * the normally-helpful work of 'hid_snto32' for fields that use signed
+ * ranges for questionable reasons.
+ */
+static inline __u32 wacom_s32tou(s32 value, __u8 n)
+{
+       switch (n) {
+       case 8:  return ((__u8)value);
+       case 16: return ((__u16)value);
+       case 32: return ((__u32)value);
+       }
+       return value & (1 << (n - 1)) ? value & (~(~0U << n)) : value;
+}
+
 extern const struct hid_device_id wacom_ids[];
 
 void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len);
index 2b0a5b8ca6e692850aa71ab21c3663fc5b56041b..ccb74529bc78243689d0720bbe2d81cfd8a52004 100644 (file)
@@ -2303,7 +2303,7 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
        case HID_DG_TOOLSERIALNUMBER:
                if (value) {
                        wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL);
-                       wacom_wac->serial[0] |= (__u32)value;
+                       wacom_wac->serial[0] |= wacom_s32tou(value, field->report_size);
                }
                return;
        case HID_DG_TWIST:
@@ -2319,15 +2319,17 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
                return;
        case WACOM_HID_WD_SERIALHI:
                if (value) {
+                       __u32 raw_value = wacom_s32tou(value, field->report_size);
+
                        wacom_wac->serial[0] = (wacom_wac->serial[0] & 0xFFFFFFFF);
-                       wacom_wac->serial[0] |= ((__u64)value) << 32;
+                       wacom_wac->serial[0] |= ((__u64)raw_value) << 32;
                        /*
                         * Non-USI EMR devices may contain additional tool type
                         * information here. See WACOM_HID_WD_TOOLTYPE case for
                         * more details.
                         */
                        if (value >> 20 == 1) {
-                               wacom_wac->id[0] |= value & 0xFFFFF;
+                               wacom_wac->id[0] |= raw_value & 0xFFFFF;
                        }
                }
                return;
@@ -2339,7 +2341,7 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
                 * bitwise OR so the complete value can be built
                 * up over time :(
                 */
-               wacom_wac->id[0] |= value;
+               wacom_wac->id[0] |= wacom_s32tou(value, field->report_size);
                return;
        case WACOM_HID_WD_OFFSETLEFT:
                if (features->offset_left && value != features->offset_left)
index 0037e2bdacd6b25ea2edca74fa7d11b542e0b843..8a51dcf055eab73222c828a64ba7c4a5b743aefb 100644 (file)
@@ -170,7 +170,7 @@ static inline int ina3221_wait_for_data(struct ina3221_data *ina)
 
        /* Polling the CVRF bit to make sure read data is ready */
        return regmap_field_read_poll_timeout(ina->fields[F_CVRF],
-                                             cvrf, cvrf, wait, 100000);
+                                             cvrf, cvrf, wait, wait * 2);
 }
 
 static int ina3221_read_value(struct ina3221_data *ina, unsigned int reg,
index b26419dbe840cb467ba487f88dd630e118e0e103..281c81edabc65740df60c154b4b1e59c4c995fc7 100644 (file)
 #define FANCTL1_FMR_REG                0x00    /* Bank 3; 1 reg per channel */
 #define FANCTL1_OUT_REG                0x10    /* Bank 3; 1 reg per channel */
 
+#define VOLT_MONITOR_MODE      0x0
+#define THERMAL_DIODE_MODE     0x1
+#define THERMISTOR_MODE                0x3
+
 #define ENABLE_TSI     BIT(1)
 
 static const unsigned short normal_i2c[] = {
@@ -935,11 +939,16 @@ static int nct7904_probe(struct i2c_client *client,
        for (i = 0; i < 4; i++) {
                val = (ret >> (i * 2)) & 0x03;
                bit = (1 << i);
-               if (val == 0) {
+               if (val == VOLT_MONITOR_MODE) {
                        data->tcpu_mask &= ~bit;
+               } else if (val == THERMAL_DIODE_MODE && i < 2) {
+                       data->temp_mode |= bit;
+                       data->vsen_mask &= ~(0x06 << (i * 2));
+               } else if (val == THERMISTOR_MODE) {
+                       data->vsen_mask &= ~(0x02 << (i * 2));
                } else {
-                       if (val == 0x1 || val == 0x2)
-                               data->temp_mode |= bit;
+                       /* Reserved */
+                       data->tcpu_mask &= ~bit;
                        data->vsen_mask &= ~(0x06 << (i * 2));
                }
        }
index fc99a40c1ec4c0e6a561e5e791a5602393fad475..e0f064dcbd0211ec188cde84de322ffc7880d40a 100644 (file)
@@ -158,9 +158,11 @@ void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl)
        struct nvme_ns *ns;
 
        mutex_lock(&ctrl->scan_lock);
+       down_read(&ctrl->namespaces_rwsem);
        list_for_each_entry(ns, &ctrl->namespaces, list)
                if (nvme_mpath_clear_current_path(ns))
                        kblockd_schedule_work(&ns->head->requeue_work);
+       up_read(&ctrl->namespaces_rwsem);
        mutex_unlock(&ctrl->scan_lock);
 }
 
index f19a28b4e997f473c40c56c0564645565b8c71e7..cb4c3000a57e88fa5cbb0ce740713d14238f0845 100644 (file)
@@ -2133,8 +2133,16 @@ err_unreg_client:
 
 static void __exit nvme_rdma_cleanup_module(void)
 {
+       struct nvme_rdma_ctrl *ctrl;
+
        nvmf_unregister_transport(&nvme_rdma_transport);
        ib_unregister_client(&nvme_rdma_ib_client);
+
+       mutex_lock(&nvme_rdma_ctrl_mutex);
+       list_for_each_entry(ctrl, &nvme_rdma_ctrl_list, list)
+               nvme_delete_ctrl(&ctrl->ctrl);
+       mutex_unlock(&nvme_rdma_ctrl_mutex);
+       flush_workqueue(nvme_delete_wq);
 }
 
 module_init(nvme_rdma_init_module);
index 6ad51aa60c03dd1cf8afd00410a53a459f4d0a35..f877e77d9184be47710178e11ba8d30bf8522259 100644 (file)
@@ -472,14 +472,7 @@ int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state)
                if (err)
                        return err;
 
-               /*
-                * .apply might have to round some values in *state, if possible
-                * read the actually implemented value back.
-                */
-               if (chip->ops->get_state)
-                       chip->ops->get_state(chip, pwm, &pwm->state);
-               else
-                       pwm->state = *state;
+               pwm->state = *state;
        } else {
                /*
                 * FIXME: restore the initial state in case of error.
index 56c38cfae92ca9285d69e6bd6596cd80d95fcae7..1f829edd8ee709c18b0b247c8ca945c607d4d505 100644 (file)
@@ -187,6 +187,7 @@ static int iproc_pwmc_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 static const struct pwm_ops iproc_pwm_ops = {
        .apply = iproc_pwmc_apply,
        .get_state = iproc_pwmc_get_state,
+       .owner = THIS_MODULE,
 };
 
 static int iproc_pwmc_probe(struct platform_device *pdev)
index f4b879d25fe9d33229d40a5ab5675577b539c45a..fc6e4546d738a59ab1be40271f406c520437dca2 100644 (file)
@@ -851,9 +851,9 @@ lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 
        if (!(vport->fc_flag & FC_PT2PT)) {
                /* Check config parameter use-adisc or FCP-2 */
-               if ((vport->cfg_use_adisc && (vport->fc_flag & FC_RSCN_MODE)) ||
+               if (vport->cfg_use_adisc && ((vport->fc_flag & FC_RSCN_MODE) ||
                    ((ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) &&
-                    (ndlp->nlp_type & NLP_FCP_TARGET))) {
+                    (ndlp->nlp_type & NLP_FCP_TARGET)))) {
                        spin_lock_irq(shost->host_lock);
                        ndlp->nlp_flag |= NLP_NPR_ADISC;
                        spin_unlock_irq(shost->host_lock);
index a0c6945b81392e1f07e02934f9702e0ac783197f..614f78dddafe0f0ae1e78b0f22beafc081b57993 100644 (file)
@@ -7866,7 +7866,7 @@ lpfc_sli4_process_missed_mbox_completions(struct lpfc_hba *phba)
        if (sli4_hba->hdwq) {
                for (eqidx = 0; eqidx < phba->cfg_irq_chann; eqidx++) {
                        eq = phba->sli4_hba.hba_eq_hdl[eqidx].eq;
-                       if (eq->queue_id == sli4_hba->mbx_cq->assoc_qid) {
+                       if (eq && eq->queue_id == sli4_hba->mbx_cq->assoc_qid) {
                                fpeq = eq;
                                break;
                        }
index 30bafd9d21e984461b237651358196a26eb8d514..7259bce85e0e3e54be6ed45d8cd82593685c7390 100644 (file)
@@ -440,9 +440,6 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj,
                valid = 0;
                if (ha->optrom_size == OPTROM_SIZE_2300 && start == 0)
                        valid = 1;
-               else if (start == (ha->flt_region_boot * 4) ||
-                   start == (ha->flt_region_fw * 4))
-                       valid = 1;
                else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha))
                        valid = 1;
                if (!valid) {
@@ -489,8 +486,10 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj,
                    "Writing flash region -- 0x%x/0x%x.\n",
                    ha->optrom_region_start, ha->optrom_region_size);
 
-               ha->isp_ops->write_optrom(vha, ha->optrom_buffer,
+               rval = ha->isp_ops->write_optrom(vha, ha->optrom_buffer,
                    ha->optrom_region_start, ha->optrom_region_size);
+               if (rval)
+                       rval = -EIO;
                break;
        default:
                rval = -EINVAL;
index 28d587a89ba61efcab7a497e8c9319a7b9272359..99f0a1a08143e0864e0ba69718945fe538ffd447 100644 (file)
@@ -253,7 +253,7 @@ qla2x00_process_els(struct bsg_job *bsg_job)
        srb_t *sp;
        const char *type;
        int req_sg_cnt, rsp_sg_cnt;
-       int rval =  (DRIVER_ERROR << 16);
+       int rval =  (DID_ERROR << 16);
        uint16_t nextlid = 0;
 
        if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
@@ -432,7 +432,7 @@ qla2x00_process_ct(struct bsg_job *bsg_job)
        struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
        scsi_qla_host_t *vha = shost_priv(host);
        struct qla_hw_data *ha = vha->hw;
-       int rval = (DRIVER_ERROR << 16);
+       int rval = (DID_ERROR << 16);
        int req_sg_cnt, rsp_sg_cnt;
        uint16_t loop_id;
        struct fc_port *fcport;
@@ -1950,7 +1950,7 @@ qlafx00_mgmt_cmd(struct bsg_job *bsg_job)
        struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
        scsi_qla_host_t *vha = shost_priv(host);
        struct qla_hw_data *ha = vha->hw;
-       int rval = (DRIVER_ERROR << 16);
+       int rval = (DID_ERROR << 16);
        struct qla_mt_iocb_rqst_fx00 *piocb_rqst;
        srb_t *sp;
        int req_sg_cnt = 0, rsp_sg_cnt = 0;
index 1cc6913f76c4745242b72cc7aa71e5edaae54519..4a1f21c11758ea5b8ee0e2222bfb4f05fc49dc84 100644 (file)
@@ -702,6 +702,7 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
                mcp->mb[2] = LSW(risc_addr);
                mcp->mb[3] = 0;
                mcp->mb[4] = 0;
+               mcp->mb[11] = 0;
                ha->flags.using_lr_setting = 0;
                if (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) ||
                    IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
@@ -746,7 +747,7 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
                if (ha->flags.exchoffld_enabled)
                        mcp->mb[4] |= ENABLE_EXCHANGE_OFFLD;
 
-               mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
+               mcp->out_mb |= MBX_4 | MBX_3 | MBX_2 | MBX_1 | MBX_11;
                mcp->in_mb |= MBX_3 | MBX_2 | MBX_1;
        } else {
                mcp->mb[1] = LSW(risc_addr);
index bcb1e8598888891796c1b486f83cb8049449ddcf..337162ac3a7716c46bc18774410f7a1796e2b33a 100644 (file)
@@ -3535,6 +3535,10 @@ qla2x00_shutdown(struct pci_dev *pdev)
                qla2x00_try_to_stop_firmware(vha);
        }
 
+       /* Disable timer */
+       if (vha->timer_active)
+               qla2x00_stop_timer(vha);
+
        /* Turn adapter off line */
        vha->flags.online = 0;
 
index 03163ac5fe9583362491efa831275c77a59e6122..ebb40160539f52e1c6ee65802fb9dd731868ed89 100644 (file)
@@ -1166,11 +1166,12 @@ static blk_status_t sd_setup_read_write_cmnd(struct scsi_cmnd *cmd)
        sector_t lba = sectors_to_logical(sdp, blk_rq_pos(rq));
        sector_t threshold;
        unsigned int nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
-       bool dif, dix;
        unsigned int mask = logical_to_sectors(sdp, 1) - 1;
        bool write = rq_data_dir(rq) == WRITE;
        unsigned char protect, fua;
        blk_status_t ret;
+       unsigned int dif;
+       bool dix;
 
        ret = scsi_init_io(cmd);
        if (ret != BLK_STS_OK)
index a9344eb4e047f1e73c28212024c1e8dcefb19228..dc2f6d2b46edc306f8696cd4471358a86dd6df49 100644 (file)
@@ -98,6 +98,8 @@ static int ufs_bsg_request(struct bsg_job *job)
 
        bsg_reply->reply_payload_rcv_len = 0;
 
+       pm_runtime_get_sync(hba->dev);
+
        msgcode = bsg_request->msgcode;
        switch (msgcode) {
        case UPIU_TRANSACTION_QUERY_REQ:
@@ -135,6 +137,8 @@ static int ufs_bsg_request(struct bsg_job *job)
                break;
        }
 
+       pm_runtime_put_sync(hba->dev);
+
        if (!desc_buff)
                goto out;
 
index c70caf4ea49012006c3a8ac754ff9e1c16399ec7..a2b5c796bbc4a5dfee4513bd93a6449e57d4dbc4 100644 (file)
@@ -1831,7 +1831,7 @@ static void cxgbit_fw4_ack(struct cxgbit_sock *csk, struct sk_buff *skb)
 
        while (credits) {
                struct sk_buff *p = cxgbit_sock_peek_wr(csk);
-               const u32 csum = (__force u32)p->csum;
+               u32 csum;
 
                if (unlikely(!p)) {
                        pr_err("csk 0x%p,%u, cr %u,%u+%u, empty.\n",
@@ -1840,6 +1840,7 @@ static void cxgbit_fw4_ack(struct cxgbit_sock *csk, struct sk_buff *skb)
                        break;
                }
 
+               csum = (__force u32)p->csum;
                if (unlikely(credits < csum)) {
                        pr_warn("csk 0x%p,%u, cr %u,%u+%u, < %u.\n",
                                csk,  csk->tid,
index 9050b380ab8304061fe56e83d43427717d795cbd..4c1e755093039d0582ca30922d620009441aed0c 100644 (file)
@@ -2329,8 +2329,6 @@ static void cdns3_gadget_config(struct cdns3_device *priv_dev)
        writel(USB_CONF_CLK2OFFDS | USB_CONF_L1DS, &regs->usb_conf);
 
        cdns3_configure_dmult(priv_dev, NULL);
-
-       cdns3_gadget_pullup(&priv_dev->gadget, 1);
 }
 
 /**
@@ -2345,9 +2343,35 @@ static int cdns3_gadget_udc_start(struct usb_gadget *gadget,
 {
        struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget);
        unsigned long flags;
+       enum usb_device_speed max_speed = driver->max_speed;
 
        spin_lock_irqsave(&priv_dev->lock, flags);
        priv_dev->gadget_driver = driver;
+
+       /* limit speed if necessary */
+       max_speed = min(driver->max_speed, gadget->max_speed);
+
+       switch (max_speed) {
+       case USB_SPEED_FULL:
+               writel(USB_CONF_SFORCE_FS, &priv_dev->regs->usb_conf);
+               writel(USB_CONF_USB3DIS, &priv_dev->regs->usb_conf);
+               break;
+       case USB_SPEED_HIGH:
+               writel(USB_CONF_USB3DIS, &priv_dev->regs->usb_conf);
+               break;
+       case USB_SPEED_SUPER:
+               break;
+       default:
+               dev_err(priv_dev->dev,
+                       "invalid maximum_speed parameter %d\n",
+                       max_speed);
+               /* fall through */
+       case USB_SPEED_UNKNOWN:
+               /* default to superspeed */
+               max_speed = USB_SPEED_SUPER;
+               break;
+       }
+
        cdns3_gadget_config(priv_dev);
        spin_unlock_irqrestore(&priv_dev->lock, flags);
        return 0;
@@ -2381,6 +2405,8 @@ static int cdns3_gadget_udc_stop(struct usb_gadget *gadget)
                writel(EP_CMD_EPRST, &priv_dev->regs->ep_cmd);
                readl_poll_timeout_atomic(&priv_dev->regs->ep_cmd, val,
                                          !(val & EP_CMD_EPRST), 1, 100);
+
+               priv_ep->flags &= ~EP_CLAIMED;
        }
 
        /* disable interrupt for device */
@@ -2575,12 +2601,7 @@ static int cdns3_gadget_start(struct cdns3 *cdns)
        /* Check the maximum_speed parameter */
        switch (max_speed) {
        case USB_SPEED_FULL:
-               writel(USB_CONF_SFORCE_FS, &priv_dev->regs->usb_conf);
-               writel(USB_CONF_USB3DIS, &priv_dev->regs->usb_conf);
-               break;
        case USB_SPEED_HIGH:
-               writel(USB_CONF_USB3DIS, &priv_dev->regs->usb_conf);
-               break;
        case USB_SPEED_SUPER:
                break;
        default:
@@ -2713,8 +2734,6 @@ static int cdns3_gadget_suspend(struct cdns3 *cdns, bool do_wakeup)
        /* disable interrupt for device */
        writel(0, &priv_dev->regs->usb_ien);
 
-       cdns3_gadget_pullup(&priv_dev->gadget, 0);
-
        return 0;
 }
 
index b498a170b7e881f3e98f6ba860db27cb928f4fde..ae11810f882618c052e4d4315315380fa74e3f9e 100644 (file)
@@ -12,7 +12,6 @@
 #ifdef CONFIG_USB_CDNS3_HOST
 
 int cdns3_host_init(struct cdns3 *cdns);
-void cdns3_host_exit(struct cdns3 *cdns);
 
 #else
 
index 2733a8f71fcd6572634899324e5152538e00299d..ad788bf3fe4f6f8e9ac1865fd3d6c6ca518ba341 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/platform_device.h>
 #include "core.h"
 #include "drd.h"
+#include "host-export.h"
 
 static int __cdns3_host_init(struct cdns3 *cdns)
 {
index 151a74a54386226c1f0fc6a134556151a5bd28dc..1ac1095bfeac8448ff7fae2179a033fb558bb6ff 100644 (file)
@@ -348,6 +348,11 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
 
        /* Validate the wMaxPacketSize field */
        maxp = usb_endpoint_maxp(&endpoint->desc);
+       if (maxp == 0) {
+               dev_warn(ddev, "config %d interface %d altsetting %d endpoint 0x%X has wMaxPacketSize 0, skipping\n",
+                   cfgno, inum, asnum, d->bEndpointAddress);
+               goto skip_to_next_endpoint_or_interface_descriptor;
+       }
 
        /* Find the highest legal maxpacket size for this endpoint */
        i = 0;          /* additional transactions per microframe */
index 89abc6078703f218b48d4239ac60c0c11a1d71a3..556a876c7896251811288f99968f8636ecf310b6 100644 (file)
@@ -102,6 +102,7 @@ config USB_DWC3_MESON_G12A
        depends on ARCH_MESON || COMPILE_TEST
        default USB_DWC3
        select USB_ROLE_SWITCH
+       select REGMAP_MMIO
        help
          Support USB2/3 functionality in Amlogic G12A platforms.
         Say 'Y' or 'M' if you have one such device.
index 999ce5e84d3c934758855e5272d2c11f4d62a367..97d6ae3c4df2fc572f4fbae2f0d6aa9c513d1d88 100644 (file)
@@ -312,8 +312,7 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc)
 
        reg = dwc3_readl(dwc->regs, DWC3_GFLADJ);
        dft = reg & DWC3_GFLADJ_30MHZ_MASK;
-       if (!dev_WARN_ONCE(dwc->dev, dft == dwc->fladj,
-           "request value same as default, ignoring\n")) {
+       if (dft != dwc->fladj) {
                reg &= ~DWC3_GFLADJ_30MHZ_MASK;
                reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | dwc->fladj;
                dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
index 5e8e18222f922c00a646063b91599be7100feb41..023f0357efd77eae3182aaf596120b8a8847fa8b 100644 (file)
@@ -258,7 +258,7 @@ static int dwc3_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
 
        ret = platform_device_add_properties(dwc->dwc3, p);
        if (ret < 0)
-               return ret;
+               goto err;
 
        ret = dwc3_pci_quirks(dwc);
        if (ret)
index 86dc1db788a9e5e02fa11b2564ed1c417f0b0d92..a9aba716bf80be70c3a8df033f8e468f59477560 100644 (file)
@@ -707,6 +707,12 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep)
 
                dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
        }
+
+       while (!list_empty(&dep->cancelled_list)) {
+               req = next_request(&dep->cancelled_list);
+
+               dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
+       }
 }
 
 /**
index d516e8d6cd7f939bd6c7bad09ded75bd40353d80..5ec54b69c29c58b1432b3c42b9d9bc58238db1d7 100644 (file)
@@ -2170,14 +2170,18 @@ void composite_dev_cleanup(struct usb_composite_dev *cdev)
                        usb_ep_dequeue(cdev->gadget->ep0, cdev->os_desc_req);
 
                kfree(cdev->os_desc_req->buf);
+               cdev->os_desc_req->buf = NULL;
                usb_ep_free_request(cdev->gadget->ep0, cdev->os_desc_req);
+               cdev->os_desc_req = NULL;
        }
        if (cdev->req) {
                if (cdev->setup_pending)
                        usb_ep_dequeue(cdev->gadget->ep0, cdev->req);
 
                kfree(cdev->req->buf);
+               cdev->req->buf = NULL;
                usb_ep_free_request(cdev->gadget->ep0, cdev->req);
+               cdev->req = NULL;
        }
        cdev->next_string_id = 0;
        device_remove_file(&cdev->gadget->dev, &dev_attr_suspended);
index 02512994289463b43107c49871995816272db5f8..33852c2b29d1a5cdf7d04ed35b66873e138e2e1b 100644 (file)
@@ -61,6 +61,8 @@ struct gadget_info {
        bool use_os_desc;
        char b_vendor_code;
        char qw_sign[OS_STRING_QW_SIGN_LEN];
+       spinlock_t spinlock;
+       bool unbind;
 };
 
 static inline struct gadget_info *to_gadget_info(struct config_item *item)
@@ -1244,6 +1246,7 @@ static int configfs_composite_bind(struct usb_gadget *gadget,
        int                             ret;
 
        /* the gi->lock is hold by the caller */
+       gi->unbind = 0;
        cdev->gadget = gadget;
        set_gadget_data(gadget, cdev);
        ret = composite_dev_prepare(composite, cdev);
@@ -1376,31 +1379,128 @@ static void configfs_composite_unbind(struct usb_gadget *gadget)
 {
        struct usb_composite_dev        *cdev;
        struct gadget_info              *gi;
+       unsigned long flags;
 
        /* the gi->lock is hold by the caller */
 
        cdev = get_gadget_data(gadget);
        gi = container_of(cdev, struct gadget_info, cdev);
+       spin_lock_irqsave(&gi->spinlock, flags);
+       gi->unbind = 1;
+       spin_unlock_irqrestore(&gi->spinlock, flags);
 
        kfree(otg_desc[0]);
        otg_desc[0] = NULL;
        purge_configs_funcs(gi);
        composite_dev_cleanup(cdev);
        usb_ep_autoconfig_reset(cdev->gadget);
+       spin_lock_irqsave(&gi->spinlock, flags);
        cdev->gadget = NULL;
        set_gadget_data(gadget, NULL);
+       spin_unlock_irqrestore(&gi->spinlock, flags);
+}
+
+static int configfs_composite_setup(struct usb_gadget *gadget,
+               const struct usb_ctrlrequest *ctrl)
+{
+       struct usb_composite_dev *cdev;
+       struct gadget_info *gi;
+       unsigned long flags;
+       int ret;
+
+       cdev = get_gadget_data(gadget);
+       if (!cdev)
+               return 0;
+
+       gi = container_of(cdev, struct gadget_info, cdev);
+       spin_lock_irqsave(&gi->spinlock, flags);
+       cdev = get_gadget_data(gadget);
+       if (!cdev || gi->unbind) {
+               spin_unlock_irqrestore(&gi->spinlock, flags);
+               return 0;
+       }
+
+       ret = composite_setup(gadget, ctrl);
+       spin_unlock_irqrestore(&gi->spinlock, flags);
+       return ret;
+}
+
+static void configfs_composite_disconnect(struct usb_gadget *gadget)
+{
+       struct usb_composite_dev *cdev;
+       struct gadget_info *gi;
+       unsigned long flags;
+
+       cdev = get_gadget_data(gadget);
+       if (!cdev)
+               return;
+
+       gi = container_of(cdev, struct gadget_info, cdev);
+       spin_lock_irqsave(&gi->spinlock, flags);
+       cdev = get_gadget_data(gadget);
+       if (!cdev || gi->unbind) {
+               spin_unlock_irqrestore(&gi->spinlock, flags);
+               return;
+       }
+
+       composite_disconnect(gadget);
+       spin_unlock_irqrestore(&gi->spinlock, flags);
+}
+
+static void configfs_composite_suspend(struct usb_gadget *gadget)
+{
+       struct usb_composite_dev *cdev;
+       struct gadget_info *gi;
+       unsigned long flags;
+
+       cdev = get_gadget_data(gadget);
+       if (!cdev)
+               return;
+
+       gi = container_of(cdev, struct gadget_info, cdev);
+       spin_lock_irqsave(&gi->spinlock, flags);
+       cdev = get_gadget_data(gadget);
+       if (!cdev || gi->unbind) {
+               spin_unlock_irqrestore(&gi->spinlock, flags);
+               return;
+       }
+
+       composite_suspend(gadget);
+       spin_unlock_irqrestore(&gi->spinlock, flags);
+}
+
+static void configfs_composite_resume(struct usb_gadget *gadget)
+{
+       struct usb_composite_dev *cdev;
+       struct gadget_info *gi;
+       unsigned long flags;
+
+       cdev = get_gadget_data(gadget);
+       if (!cdev)
+               return;
+
+       gi = container_of(cdev, struct gadget_info, cdev);
+       spin_lock_irqsave(&gi->spinlock, flags);
+       cdev = get_gadget_data(gadget);
+       if (!cdev || gi->unbind) {
+               spin_unlock_irqrestore(&gi->spinlock, flags);
+               return;
+       }
+
+       composite_resume(gadget);
+       spin_unlock_irqrestore(&gi->spinlock, flags);
 }
 
 static const struct usb_gadget_driver configfs_driver_template = {
        .bind           = configfs_composite_bind,
        .unbind         = configfs_composite_unbind,
 
-       .setup          = composite_setup,
-       .reset          = composite_disconnect,
-       .disconnect     = composite_disconnect,
+       .setup          = configfs_composite_setup,
+       .reset          = configfs_composite_disconnect,
+       .disconnect     = configfs_composite_disconnect,
 
-       .suspend        = composite_suspend,
-       .resume         = composite_resume,
+       .suspend        = configfs_composite_suspend,
+       .resume         = configfs_composite_resume,
 
        .max_speed      = USB_SPEED_SUPER,
        .driver = {
index 86ffc83078647b2ba1dfbfc6e796489af15c9192..1d0d8952a74bfa4a786c6966fff1bbcbc66438a7 100644 (file)
@@ -449,9 +449,11 @@ static void submit_request(struct usba_ep *ep, struct usba_request *req)
                next_fifo_transaction(ep, req);
                if (req->last_transaction) {
                        usba_ep_writel(ep, CTL_DIS, USBA_TX_PK_RDY);
-                       usba_ep_writel(ep, CTL_ENB, USBA_TX_COMPLETE);
+                       if (ep_is_control(ep))
+                               usba_ep_writel(ep, CTL_ENB, USBA_TX_COMPLETE);
                } else {
-                       usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE);
+                       if (ep_is_control(ep))
+                               usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE);
                        usba_ep_writel(ep, CTL_ENB, USBA_TX_PK_RDY);
                }
        }
index 92af8dc98c3dcd1d5f0c474293916636049d8332..51fa614b40794310e3216f5b086442d969b5b3be 100644 (file)
@@ -98,6 +98,17 @@ int usb_ep_enable(struct usb_ep *ep)
        if (ep->enabled)
                goto out;
 
+       /* UDC drivers can't handle endpoints with maxpacket size 0 */
+       if (usb_endpoint_maxp(ep->desc) == 0) {
+               /*
+                * We should log an error message here, but we can't call
+                * dev_err() because there's no way to find the gadget
+                * given only ep.
+                */
+               ret = -EINVAL;
+               goto out;
+       }
+
        ret = ep->ops->enable(ep, ep->desc);
        if (ret)
                goto out;
index 20141c3096f68ab4a2f51762dc0617715e473633..9a05863b28768a3e8fea85b376935baf961d36e9 100644 (file)
@@ -2576,7 +2576,7 @@ static int fsl_udc_remove(struct platform_device *pdev)
        dma_pool_destroy(udc_controller->td_pool);
        free_irq(udc_controller->irq, udc_controller);
        iounmap(dr_regs);
-       if (pdata->operating_mode == FSL_USB2_DR_DEVICE)
+       if (res && (pdata->operating_mode == FSL_USB2_DR_DEVICE))
                release_mem_region(res->start, resource_size(res));
 
        /* free udc --wait for the release() finished */
index e098f16c01cb5dedef6e4084c33a7ec39f43acdc..33703140233aa592001eaeb64298b5f119da9b0a 100644 (file)
@@ -1544,10 +1544,10 @@ static void usb3_set_device_address(struct renesas_usb3 *usb3, u16 addr)
 static bool usb3_std_req_set_address(struct renesas_usb3 *usb3,
                                     struct usb_ctrlrequest *ctrl)
 {
-       if (ctrl->wValue >= 128)
+       if (le16_to_cpu(ctrl->wValue) >= 128)
                return true;    /* stall */
 
-       usb3_set_device_address(usb3, ctrl->wValue);
+       usb3_set_device_address(usb3, le16_to_cpu(ctrl->wValue));
        usb3_set_p0_con_for_no_data(usb3);
 
        return false;
@@ -1582,6 +1582,7 @@ static bool usb3_std_req_get_status(struct renesas_usb3 *usb3,
        struct renesas_usb3_ep *usb3_ep;
        int num;
        u16 status = 0;
+       __le16 tx_data;
 
        switch (ctrl->bRequestType & USB_RECIP_MASK) {
        case USB_RECIP_DEVICE:
@@ -1604,10 +1605,10 @@ static bool usb3_std_req_get_status(struct renesas_usb3 *usb3,
        }
 
        if (!stall) {
-               status = cpu_to_le16(status);
+               tx_data = cpu_to_le16(status);
                dev_dbg(usb3_to_dev(usb3), "get_status: req = %p\n",
                        usb_req_to_usb3_req(usb3->ep0_req));
-               usb3_pipe0_internal_xfer(usb3, &status, sizeof(status),
+               usb3_pipe0_internal_xfer(usb3, &tx_data, sizeof(tx_data),
                                         usb3_pipe0_get_status_completion);
        }
 
@@ -1772,7 +1773,7 @@ static bool usb3_std_req_set_sel(struct renesas_usb3 *usb3,
 static bool usb3_std_req_set_configuration(struct renesas_usb3 *usb3,
                                           struct usb_ctrlrequest *ctrl)
 {
-       if (ctrl->wValue > 0)
+       if (le16_to_cpu(ctrl->wValue) > 0)
                usb3_set_bit(usb3, USB_COM_CON_CONF, USB3_USB_COM_CON);
        else
                usb3_clear_bit(usb3, USB_COM_CON_CONF, USB3_USB_COM_CON);
index 7ba6afc7ef230ed69da605ce48e31cac4783a709..76c3f29562d2b9d2e3263f3d3dc1b45b92728140 100644 (file)
@@ -202,10 +202,10 @@ static void xhci_ring_dump_segment(struct seq_file *s,
                trb = &seg->trbs[i];
                dma = seg->dma + i * sizeof(*trb);
                seq_printf(s, "%pad: %s\n", &dma,
-                          xhci_decode_trb(trb->generic.field[0],
-                                          trb->generic.field[1],
-                                          trb->generic.field[2],
-                                          trb->generic.field[3]));
+                          xhci_decode_trb(le32_to_cpu(trb->generic.field[0]),
+                                          le32_to_cpu(trb->generic.field[1]),
+                                          le32_to_cpu(trb->generic.field[2]),
+                                          le32_to_cpu(trb->generic.field[3])));
        }
 }
 
@@ -263,10 +263,10 @@ static int xhci_slot_context_show(struct seq_file *s, void *unused)
        xhci = hcd_to_xhci(bus_to_hcd(dev->udev->bus));
        slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx);
        seq_printf(s, "%pad: %s\n", &dev->out_ctx->dma,
-                  xhci_decode_slot_context(slot_ctx->dev_info,
-                                           slot_ctx->dev_info2,
-                                           slot_ctx->tt_info,
-                                           slot_ctx->dev_state));
+                  xhci_decode_slot_context(le32_to_cpu(slot_ctx->dev_info),
+                                           le32_to_cpu(slot_ctx->dev_info2),
+                                           le32_to_cpu(slot_ctx->tt_info),
+                                           le32_to_cpu(slot_ctx->dev_state)));
 
        return 0;
 }
@@ -286,10 +286,10 @@ static int xhci_endpoint_context_show(struct seq_file *s, void *unused)
                ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, dci);
                dma = dev->out_ctx->dma + dci * CTX_SIZE(xhci->hcc_params);
                seq_printf(s, "%pad: %s\n", &dma,
-                          xhci_decode_ep_context(ep_ctx->ep_info,
-                                                 ep_ctx->ep_info2,
-                                                 ep_ctx->deq,
-                                                 ep_ctx->tx_info));
+                          xhci_decode_ep_context(le32_to_cpu(ep_ctx->ep_info),
+                                                 le32_to_cpu(ep_ctx->ep_info2),
+                                                 le64_to_cpu(ep_ctx->deq),
+                                                 le32_to_cpu(ep_ctx->tx_info)));
        }
 
        return 0;
index 85ceb43e34056097fb63c8391a05c67a1acf80ed..e7aab31fd9a5a38b260e498947de7808259098d0 100644 (file)
@@ -3330,6 +3330,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                        if (xhci_urb_suitable_for_idt(urb)) {
                                memcpy(&send_addr, urb->transfer_buffer,
                                       trb_buff_len);
+                               le64_to_cpus(&send_addr);
                                field |= TRB_IDT;
                        }
                }
@@ -3475,6 +3476,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                if (xhci_urb_suitable_for_idt(urb)) {
                        memcpy(&addr, urb->transfer_buffer,
                               urb->transfer_buffer_length);
+                       le64_to_cpus(&addr);
                        field |= TRB_IDT;
                } else {
                        addr = (u64) urb->transfer_dma;
index 517ec3206f6eb0681075c75c2c432b27350b51df..6c17e3fe181a2113464d4120984ad1125405888c 100644 (file)
@@ -3071,6 +3071,48 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int ep_index,
        }
 }
 
+static void xhci_endpoint_disable(struct usb_hcd *hcd,
+                                 struct usb_host_endpoint *host_ep)
+{
+       struct xhci_hcd         *xhci;
+       struct xhci_virt_device *vdev;
+       struct xhci_virt_ep     *ep;
+       struct usb_device       *udev;
+       unsigned long           flags;
+       unsigned int            ep_index;
+
+       xhci = hcd_to_xhci(hcd);
+rescan:
+       spin_lock_irqsave(&xhci->lock, flags);
+
+       udev = (struct usb_device *)host_ep->hcpriv;
+       if (!udev || !udev->slot_id)
+               goto done;
+
+       vdev = xhci->devs[udev->slot_id];
+       if (!vdev)
+               goto done;
+
+       ep_index = xhci_get_endpoint_index(&host_ep->desc);
+       ep = &vdev->eps[ep_index];
+       if (!ep)
+               goto done;
+
+       /* wait for hub_tt_work to finish clearing hub TT */
+       if (ep->ep_state & EP_CLEARING_TT) {
+               spin_unlock_irqrestore(&xhci->lock, flags);
+               schedule_timeout_uninterruptible(1);
+               goto rescan;
+       }
+
+       if (ep->ep_state)
+               xhci_dbg(xhci, "endpoint disable with ep_state 0x%x\n",
+                        ep->ep_state);
+done:
+       host_ep->hcpriv = NULL;
+       spin_unlock_irqrestore(&xhci->lock, flags);
+}
+
 /*
  * Called after usb core issues a clear halt control message.
  * The host side of the halt should already be cleared by a reset endpoint
@@ -5238,20 +5280,13 @@ static void xhci_clear_tt_buffer_complete(struct usb_hcd *hcd,
        unsigned int ep_index;
        unsigned long flags;
 
-       /*
-        * udev might be NULL if tt buffer is cleared during a failed device
-        * enumeration due to a halted control endpoint. Usb core might
-        * have allocated a new udev for the next enumeration attempt.
-        */
-
        xhci = hcd_to_xhci(hcd);
+
+       spin_lock_irqsave(&xhci->lock, flags);
        udev = (struct usb_device *)ep->hcpriv;
-       if (!udev)
-               return;
        slot_id = udev->slot_id;
        ep_index = xhci_get_endpoint_index(&ep->desc);
 
-       spin_lock_irqsave(&xhci->lock, flags);
        xhci->devs[slot_id]->eps[ep_index].ep_state &= ~EP_CLEARING_TT;
        xhci_ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
        spin_unlock_irqrestore(&xhci->lock, flags);
@@ -5288,6 +5323,7 @@ static const struct hc_driver xhci_hc_driver = {
        .free_streams =         xhci_free_streams,
        .add_endpoint =         xhci_add_endpoint,
        .drop_endpoint =        xhci_drop_endpoint,
+       .endpoint_disable =     xhci_endpoint_disable,
        .endpoint_reset =       xhci_endpoint_reset,
        .check_bandwidth =      xhci_check_bandwidth,
        .reset_bandwidth =      xhci_reset_bandwidth,
index 15b5f06fb0b306dcd7579169fee65194c1e09323..8f86b4ebca898b32e572cba6006ca01ab414b2ea 100644 (file)
@@ -487,7 +487,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
        }
        bytes_to_read = min(count, *actual_buffer);
        if (bytes_to_read < *actual_buffer)
-               dev_warn(&dev->intf->dev, "Read buffer overflow, %zd bytes dropped\n",
+               dev_warn(&dev->intf->dev, "Read buffer overflow, %zu bytes dropped\n",
                         *actual_buffer-bytes_to_read);
 
        /* copy one interrupt_in_buffer from ring_buffer into userspace */
@@ -495,11 +495,11 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
                retval = -EFAULT;
                goto unlock_exit;
        }
-       dev->ring_tail = (dev->ring_tail+1) % ring_buffer_size;
-
        retval = bytes_to_read;
 
        spin_lock_irq(&dev->rbsl);
+       dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size;
+
        if (dev->buffer_overflow) {
                dev->buffer_overflow = 0;
                spin_unlock_irq(&dev->rbsl);
@@ -562,8 +562,9 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer,
        /* write the data into interrupt_out_buffer from userspace */
        bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size);
        if (bytes_to_write < count)
-               dev_warn(&dev->intf->dev, "Write buffer overflow, %zd bytes dropped\n", count-bytes_to_write);
-       dev_dbg(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n",
+               dev_warn(&dev->intf->dev, "Write buffer overflow, %zu bytes dropped\n",
+                       count - bytes_to_write);
+       dev_dbg(&dev->intf->dev, "%s: count = %zu, bytes_to_write = %zu\n",
                __func__, count, bytes_to_write);
 
        if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) {
@@ -580,7 +581,7 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer,
                                         1 << 8, 0,
                                         dev->interrupt_out_buffer,
                                         bytes_to_write,
-                                        USB_CTRL_SET_TIMEOUT * HZ);
+                                        USB_CTRL_SET_TIMEOUT);
                if (retval < 0)
                        dev_err(&dev->intf->dev,
                                "Couldn't submit HID_REQ_SET_REPORT %d\n",
index c3d5c1206eec808bb96d54ef5cc713219c39c93e..9dd02160cca97e9242aac125d104df80cd72e3e3 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/platform_device.h>
 
 #include "mtu3.h"
+#include "mtu3_dr.h"
 #include "mtu3_debug.h"
 #include "mtu3_trace.h"
 
index 4c3de777ef6cf691abd606d0b98081c6f10143ce..a3c30b609433bacca844f3d0c0c174c6301e0d51 100644 (file)
@@ -162,17 +162,17 @@ void usbhs_usbreq_get_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req)
        req->bRequest           = (val >> 8) & 0xFF;
        req->bRequestType       = (val >> 0) & 0xFF;
 
-       req->wValue     = usbhs_read(priv, USBVAL);
-       req->wIndex     = usbhs_read(priv, USBINDX);
-       req->wLength    = usbhs_read(priv, USBLENG);
+       req->wValue     = cpu_to_le16(usbhs_read(priv, USBVAL));
+       req->wIndex     = cpu_to_le16(usbhs_read(priv, USBINDX));
+       req->wLength    = cpu_to_le16(usbhs_read(priv, USBLENG));
 }
 
 void usbhs_usbreq_set_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req)
 {
        usbhs_write(priv, USBREQ,  (req->bRequest << 8) | req->bRequestType);
-       usbhs_write(priv, USBVAL,  req->wValue);
-       usbhs_write(priv, USBINDX, req->wIndex);
-       usbhs_write(priv, USBLENG, req->wLength);
+       usbhs_write(priv, USBVAL,  le16_to_cpu(req->wValue));
+       usbhs_write(priv, USBINDX, le16_to_cpu(req->wIndex));
+       usbhs_write(priv, USBLENG, le16_to_cpu(req->wLength));
 
        usbhs_bset(priv, DCPCTR, SUREQ, SUREQ);
 }
index e5ef56991dbac3a9607575ca7414e5c24bf11320..cd38d74b322320db3c9607f4ab30758d701949be 100644 (file)
@@ -265,7 +265,7 @@ static int usbhsg_recip_handler_std_set_device(struct usbhs_priv *priv,
        case USB_DEVICE_TEST_MODE:
                usbhsg_recip_handler_std_control_done(priv, uep, ctrl);
                udelay(100);
-               usbhs_sys_set_test_mode(priv, le16_to_cpu(ctrl->wIndex >> 8));
+               usbhs_sys_set_test_mode(priv, le16_to_cpu(ctrl->wIndex) >> 8);
                break;
        default:
                usbhsg_recip_handler_std_control_done(priv, uep, ctrl);
@@ -315,7 +315,7 @@ static void __usbhsg_recip_send_status(struct usbhsg_gpriv *gpriv,
        struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp);
        struct device *dev = usbhsg_gpriv_to_dev(gpriv);
        struct usb_request *req;
-       unsigned short *buf;
+       __le16 *buf;
 
        /* alloc new usb_request for recip */
        req = usb_ep_alloc_request(&dcp->ep, GFP_ATOMIC);
index 79314d8c94a446b9378aa7d5ebcb9a533e31cf1e..ca3bd58f2025a9957742970122cacd997ba67085 100644 (file)
@@ -559,6 +559,10 @@ static int firm_send_command(struct usb_serial_port *port, __u8 command,
 
        command_port = port->serial->port[COMMAND_PORT];
        command_info = usb_get_serial_port_data(command_port);
+
+       if (command_port->bulk_out_size < datasize + 1)
+               return -EIO;
+
        mutex_lock(&command_info->mutex);
        command_info->command_finished = false;
 
@@ -632,6 +636,7 @@ static void firm_setup_port(struct tty_struct *tty)
        struct device *dev = &port->dev;
        struct whiteheat_port_settings port_settings;
        unsigned int cflag = tty->termios.c_cflag;
+       speed_t baud;
 
        port_settings.port = port->port_number + 1;
 
@@ -692,11 +697,13 @@ static void firm_setup_port(struct tty_struct *tty)
        dev_dbg(dev, "%s - XON = %2x, XOFF = %2x\n", __func__, port_settings.xon, port_settings.xoff);
 
        /* get the baud rate wanted */
-       port_settings.baud = tty_get_baud_rate(tty);
-       dev_dbg(dev, "%s - baud rate = %d\n", __func__, port_settings.baud);
+       baud = tty_get_baud_rate(tty);
+       port_settings.baud = cpu_to_le32(baud);
+       dev_dbg(dev, "%s - baud rate = %u\n", __func__, baud);
 
        /* fixme: should set validated settings */
-       tty_encode_baud_rate(tty, port_settings.baud, port_settings.baud);
+       tty_encode_baud_rate(tty, baud, baud);
+
        /* handle any settings that aren't specified in the tty structure */
        port_settings.lloop = 0;
 
index 00398149cd8ddcf0985dd363d24d66415196cdd8..269e727a92f9c5bbe7c2825d988c06f0e640491c 100644 (file)
@@ -87,7 +87,7 @@ struct whiteheat_simple {
 
 struct whiteheat_port_settings {
        __u8    port;           /* port number (1 to N) */
-       __u32   baud;           /* any value 7 - 460800, firmware calculates
+       __le32  baud;           /* any value 7 - 460800, firmware calculates
                                   best fit; arrives little endian */
        __u8    bits;           /* 5, 6, 7, or 8 */
        __u8    stop;           /* 1 or 2, default 1 (2 = 1.5 if bits = 5) */
index 6737fab9495949c0187364cfce1e7469687da9fa..54a3c8195c969785a6ab2a359a2787f321cce553 100644 (file)
@@ -68,7 +68,6 @@ static const char* host_info(struct Scsi_Host *host)
 static int slave_alloc (struct scsi_device *sdev)
 {
        struct us_data *us = host_to_us(sdev->host);
-       int maxp;
 
        /*
         * Set the INQUIRY transfer length to 36.  We don't use any of
@@ -77,15 +76,6 @@ static int slave_alloc (struct scsi_device *sdev)
         */
        sdev->inquiry_len = 36;
 
-       /*
-        * USB has unusual scatter-gather requirements: the length of each
-        * scatterlist element except the last must be divisible by the
-        * Bulk maxpacket value.  Fortunately this value is always a
-        * power of 2.  Inform the block layer about this requirement.
-        */
-       maxp = usb_maxpacket(us->pusb_dev, us->recv_bulk_pipe, 0);
-       blk_queue_virt_boundary(sdev->request_queue, maxp - 1);
-
        /*
         * Some host controllers may have alignment requirements.
         * We'll play it safe by requiring 512-byte alignment always.
index bf80d6f81f587f4269b2bf7a96d74099f63e9d15..34538253f12cdf6d4213167543b24ed207267f78 100644 (file)
@@ -789,29 +789,9 @@ static int uas_slave_alloc(struct scsi_device *sdev)
 {
        struct uas_dev_info *devinfo =
                (struct uas_dev_info *)sdev->host->hostdata;
-       int maxp;
 
        sdev->hostdata = devinfo;
 
-       /*
-        * We have two requirements here. We must satisfy the requirements
-        * of the physical HC and the demands of the protocol, as we
-        * definitely want no additional memory allocation in this path
-        * ruling out using bounce buffers.
-        *
-        * For a transmission on USB to continue we must never send
-        * a package that is smaller than maxpacket. Hence the length of each
-         * scatterlist element except the last must be divisible by the
-         * Bulk maxpacket value.
-        * If the HC does not ensure that through SG,
-        * the upper layer must do that. We must assume nothing
-        * about the capabilities off the HC, so we use the most
-        * pessimistic requirement.
-        */
-
-       maxp = usb_maxpacket(devinfo->udev, devinfo->data_in_pipe, 0);
-       blk_queue_virt_boundary(sdev->request_queue, maxp - 1);
-
        /*
         * The protocol has no requirements on alignment in the strict sense.
         * Controllers may or may not have alignment restrictions.
index c3803785f6eff23a74c2225cd696a7a69ea1a757..0ae40a13a9fea89650c4200a359530dd7c954281 100644 (file)
@@ -147,7 +147,10 @@ static int vhci_send_cmd_submit(struct vhci_device *vdev)
                }
 
                kfree(iov);
+               /* This is only for isochronous case */
                kfree(iso_buffer);
+               iso_buffer = NULL;
+
                usbip_dbg_vhci_tx("send txdata\n");
 
                total_size += txsize;
index e1035a865fb945f0df23ecede70aafbc4b593a1b..45a6d895a7d7208ee26c1517e5bee5e1d25f65d7 100644 (file)
@@ -29,7 +29,7 @@ static inline void _transp(u32 d[], unsigned int i1, unsigned int i2,
 
 extern void c2p_unsupported(void);
 
-static inline u32 get_mask(unsigned int n)
+static __always_inline u32 get_mask(unsigned int n)
 {
        switch (n) {
        case 1:
@@ -57,7 +57,7 @@ static inline u32 get_mask(unsigned int n)
      *  Transpose operations on 8 32-bit words
      */
 
-static inline void transp8(u32 d[], unsigned int n, unsigned int m)
+static __always_inline void transp8(u32 d[], unsigned int n, unsigned int m)
 {
        u32 mask = get_mask(n);
 
@@ -99,7 +99,7 @@ static inline void transp8(u32 d[], unsigned int n, unsigned int m)
      *  Transpose operations on 4 32-bit words
      */
 
-static inline void transp4(u32 d[], unsigned int n, unsigned int m)
+static __always_inline void transp4(u32 d[], unsigned int n, unsigned int m)
 {
        u32 mask = get_mask(n);
 
@@ -126,7 +126,7 @@ static inline void transp4(u32 d[], unsigned int n, unsigned int m)
      *  Transpose operations on 4 32-bit words (reverse order)
      */
 
-static inline void transp4x(u32 d[], unsigned int n, unsigned int m)
+static __always_inline void transp4x(u32 d[], unsigned int n, unsigned int m)
 {
        u32 mask = get_mask(n);
 
index d3b9c9d5c1bd242170d671521d91ddb6cb90a0ac..f5a38910a82bfb94d71ceab28af196b3d0165c6f 100644 (file)
@@ -1058,6 +1058,11 @@ void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release)
 
        dout("__ceph_remove_cap %p from %p\n", cap, &ci->vfs_inode);
 
+       /* remove from inode's cap rbtree, and clear auth cap */
+       rb_erase(&cap->ci_node, &ci->i_caps);
+       if (ci->i_auth_cap == cap)
+               ci->i_auth_cap = NULL;
+
        /* remove from session list */
        spin_lock(&session->s_cap_lock);
        if (session->s_cap_iterator == cap) {
@@ -1091,11 +1096,6 @@ void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release)
 
        spin_unlock(&session->s_cap_lock);
 
-       /* remove from inode list */
-       rb_erase(&cap->ci_node, &ci->i_caps);
-       if (ci->i_auth_cap == cap)
-               ci->i_auth_cap = NULL;
-
        if (removed)
                ceph_put_cap(mdsc, cap);
 
index 4ca0b8ff9a7270c7479fa13920cce5570df8e1ee..d17a789fd856b45d6a2f8b201d85f3433321762e 100644 (file)
@@ -1553,36 +1553,37 @@ static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags)
 {
        int valid = 0;
        struct dentry *parent;
-       struct inode *dir;
+       struct inode *dir, *inode;
 
        if (flags & LOOKUP_RCU) {
                parent = READ_ONCE(dentry->d_parent);
                dir = d_inode_rcu(parent);
                if (!dir)
                        return -ECHILD;
+               inode = d_inode_rcu(dentry);
        } else {
                parent = dget_parent(dentry);
                dir = d_inode(parent);
+               inode = d_inode(dentry);
        }
 
        dout("d_revalidate %p '%pd' inode %p offset %lld\n", dentry,
-            dentry, d_inode(dentry), ceph_dentry(dentry)->offset);
+            dentry, inode, ceph_dentry(dentry)->offset);
 
        /* always trust cached snapped dentries, snapdir dentry */
        if (ceph_snap(dir) != CEPH_NOSNAP) {
                dout("d_revalidate %p '%pd' inode %p is SNAPPED\n", dentry,
-                    dentry, d_inode(dentry));
+                    dentry, inode);
                valid = 1;
-       } else if (d_really_is_positive(dentry) &&
-                  ceph_snap(d_inode(dentry)) == CEPH_SNAPDIR) {
+       } else if (inode && ceph_snap(inode) == CEPH_SNAPDIR) {
                valid = 1;
        } else {
                valid = dentry_lease_is_valid(dentry, flags);
                if (valid == -ECHILD)
                        return valid;
                if (valid || dir_lease_is_valid(dir, dentry)) {
-                       if (d_really_is_positive(dentry))
-                               valid = ceph_is_any_caps(d_inode(dentry));
+                       if (inode)
+                               valid = ceph_is_any_caps(inode);
                        else
                                valid = 1;
                }
index d277f71abe0b8e653ef0e439782c2ee930388bbf..bd77adb64bfd9812d25e0f0b92c0fb55689a9d7c 100644 (file)
@@ -462,6 +462,9 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
                err = ceph_security_init_secctx(dentry, mode, &as_ctx);
                if (err < 0)
                        goto out_ctx;
+       } else if (!d_in_lookup(dentry)) {
+               /* If it's not being looked up, it's negative */
+               return -ENOENT;
        }
 
        /* do the open */
@@ -1956,10 +1959,18 @@ static ssize_t __ceph_copy_file_range(struct file *src_file, loff_t src_off,
        if (ceph_test_mount_opt(src_fsc, NOCOPYFROM))
                return -EOPNOTSUPP;
 
+       /*
+        * Striped file layouts require that we copy partial objects, but the
+        * OSD copy-from operation only supports full-object copies.  Limit
+        * this to non-striped file layouts for now.
+        */
        if ((src_ci->i_layout.stripe_unit != dst_ci->i_layout.stripe_unit) ||
-           (src_ci->i_layout.stripe_count != dst_ci->i_layout.stripe_count) ||
-           (src_ci->i_layout.object_size != dst_ci->i_layout.object_size))
+           (src_ci->i_layout.stripe_count != 1) ||
+           (dst_ci->i_layout.stripe_count != 1) ||
+           (src_ci->i_layout.object_size != dst_ci->i_layout.object_size)) {
+               dout("Invalid src/dst files layout\n");
                return -EOPNOTSUPP;
+       }
 
        if (len < src_ci->i_layout.object_size)
                return -EOPNOTSUPP; /* no remote copy will be done */
index 9f135624ae476a23ab610cff33d173646e111724..c07407586ce873f236a1cf61d0ea48efa27590c4 100644 (file)
@@ -1434,6 +1434,7 @@ retry_lookup:
                dout(" final dn %p\n", dn);
        } else if ((req->r_op == CEPH_MDS_OP_LOOKUPSNAP ||
                    req->r_op == CEPH_MDS_OP_MKSNAP) &&
+                  test_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags) &&
                   !test_bit(CEPH_MDS_R_ABORTED, &req->r_req_flags)) {
                struct inode *dir = req->r_parent;
 
index edfd643a8205ec3222daaec8f0374d4549bba1f3..b47f43fc2d688113c5dbcbf3e28bb18e1712e9f7 100644 (file)
@@ -268,6 +268,7 @@ static int parse_fsopt_token(char *c, void *private)
                }
                break;
        case Opt_fscache_uniq:
+#ifdef CONFIG_CEPH_FSCACHE
                kfree(fsopt->fscache_uniq);
                fsopt->fscache_uniq = kstrndup(argstr[0].from,
                                               argstr[0].to-argstr[0].from,
@@ -276,7 +277,10 @@ static int parse_fsopt_token(char *c, void *private)
                        return -ENOMEM;
                fsopt->flags |= CEPH_MOUNT_OPT_FSCACHE;
                break;
-               /* misc */
+#else
+               pr_err("fscache support is disabled\n");
+               return -EINVAL;
+#endif
        case Opt_wsize:
                if (intval < (int)PAGE_SIZE || intval > CEPH_MAX_WRITE_SIZE)
                        return -EINVAL;
@@ -353,10 +357,15 @@ static int parse_fsopt_token(char *c, void *private)
                fsopt->flags &= ~CEPH_MOUNT_OPT_INO32;
                break;
        case Opt_fscache:
+#ifdef CONFIG_CEPH_FSCACHE
                fsopt->flags |= CEPH_MOUNT_OPT_FSCACHE;
                kfree(fsopt->fscache_uniq);
                fsopt->fscache_uniq = NULL;
                break;
+#else
+               pr_err("fscache support is disabled\n");
+               return -EINVAL;
+#endif
        case Opt_nofscache:
                fsopt->flags &= ~CEPH_MOUNT_OPT_FSCACHE;
                kfree(fsopt->fscache_uniq);
index 4c092259646740da18a7e3be2b31d1647320aaa4..cd55af9b7cc5aca5669fb53018efb0ea29494bff 100644 (file)
@@ -4084,6 +4084,7 @@ free_pages:
 
        kfree(dw->ppages);
        cifs_small_buf_release(dw->buf);
+       kfree(dw);
 }
 
 
@@ -4157,7 +4158,7 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid,
                dw->server = server;
                dw->ppages = pages;
                dw->len = len;
-               queue_work(cifsiod_wq, &dw->decrypt);
+               queue_work(decrypt_wq, &dw->decrypt);
                *num_mids = 0; /* worker thread takes care of finding mid */
                return -1;
        }
index 8461a63220398024c2aef5d4795d2f2aadd4ebfa..335607b8c5c001ca35847c5ec22409ab04d83b05 100644 (file)
@@ -576,10 +576,13 @@ void wbc_attach_and_unlock_inode(struct writeback_control *wbc,
        spin_unlock(&inode->i_lock);
 
        /*
-        * A dying wb indicates that the memcg-blkcg mapping has changed
-        * and a new wb is already serving the memcg.  Switch immediately.
+        * A dying wb indicates that either the blkcg associated with the
+        * memcg changed or the associated memcg is dying.  In the first
+        * case, a replacement wb should already be available and we should
+        * refresh the wb immediately.  In the second case, trying to
+        * refresh will keep failing.
         */
-       if (unlikely(wb_dying(wbc->wb)))
+       if (unlikely(wb_dying(wbc->wb) && !css_is_dying(wbc->wb->memcg_css)))
                inode_switch_wbs(inode, wbc->wb_id);
 }
 EXPORT_SYMBOL_GPL(wbc_attach_and_unlock_inode);
index 53939bf9d7d260f1ebfb1da514973a76a92322b3..9876db52913a4fda2a67ecf746a553bd0728eea1 100644 (file)
@@ -2098,53 +2098,89 @@ static int ocfs2_is_io_unaligned(struct inode *inode, size_t count, loff_t pos)
        return 0;
 }
 
-static int ocfs2_prepare_inode_for_refcount(struct inode *inode,
-                                           struct file *file,
-                                           loff_t pos, size_t count,
-                                           int *meta_level)
+static int ocfs2_inode_lock_for_extent_tree(struct inode *inode,
+                                           struct buffer_head **di_bh,
+                                           int meta_level,
+                                           int overwrite_io,
+                                           int write_sem,
+                                           int wait)
 {
-       int ret;
-       struct buffer_head *di_bh = NULL;
-       u32 cpos = pos >> OCFS2_SB(inode->i_sb)->s_clustersize_bits;
-       u32 clusters =
-               ocfs2_clusters_for_bytes(inode->i_sb, pos + count) - cpos;
+       int ret = 0;
 
-       ret = ocfs2_inode_lock(inode, &di_bh, 1);
-       if (ret) {
-               mlog_errno(ret);
+       if (wait)
+               ret = ocfs2_inode_lock(inode, NULL, meta_level);
+       else
+               ret = ocfs2_try_inode_lock(inode,
+                       overwrite_io ? NULL : di_bh, meta_level);
+       if (ret < 0)
                goto out;
+
+       if (wait) {
+               if (write_sem)
+                       down_write(&OCFS2_I(inode)->ip_alloc_sem);
+               else
+                       down_read(&OCFS2_I(inode)->ip_alloc_sem);
+       } else {
+               if (write_sem)
+                       ret = down_write_trylock(&OCFS2_I(inode)->ip_alloc_sem);
+               else
+                       ret = down_read_trylock(&OCFS2_I(inode)->ip_alloc_sem);
+
+               if (!ret) {
+                       ret = -EAGAIN;
+                       goto out_unlock;
+               }
        }
 
-       *meta_level = 1;
+       return ret;
 
-       ret = ocfs2_refcount_cow(inode, di_bh, cpos, clusters, UINT_MAX);
-       if (ret)
-               mlog_errno(ret);
+out_unlock:
+       brelse(*di_bh);
+       ocfs2_inode_unlock(inode, meta_level);
 out:
-       brelse(di_bh);
        return ret;
 }
 
+static void ocfs2_inode_unlock_for_extent_tree(struct inode *inode,
+                                              struct buffer_head **di_bh,
+                                              int meta_level,
+                                              int write_sem)
+{
+       if (write_sem)
+               up_write(&OCFS2_I(inode)->ip_alloc_sem);
+       else
+               up_read(&OCFS2_I(inode)->ip_alloc_sem);
+
+       brelse(*di_bh);
+       *di_bh = NULL;
+
+       if (meta_level >= 0)
+               ocfs2_inode_unlock(inode, meta_level);
+}
+
 static int ocfs2_prepare_inode_for_write(struct file *file,
                                         loff_t pos, size_t count, int wait)
 {
        int ret = 0, meta_level = 0, overwrite_io = 0;
+       int write_sem = 0;
        struct dentry *dentry = file->f_path.dentry;
        struct inode *inode = d_inode(dentry);
        struct buffer_head *di_bh = NULL;
+       u32 cpos;
+       u32 clusters;
 
        /*
         * We start with a read level meta lock and only jump to an ex
         * if we need to make modifications here.
         */
        for(;;) {
-               if (wait)
-                       ret = ocfs2_inode_lock(inode, NULL, meta_level);
-               else
-                       ret = ocfs2_try_inode_lock(inode,
-                               overwrite_io ? NULL : &di_bh, meta_level);
+               ret = ocfs2_inode_lock_for_extent_tree(inode,
+                                                      &di_bh,
+                                                      meta_level,
+                                                      overwrite_io,
+                                                      write_sem,
+                                                      wait);
                if (ret < 0) {
-                       meta_level = -1;
                        if (ret != -EAGAIN)
                                mlog_errno(ret);
                        goto out;
@@ -2156,15 +2192,8 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
                 */
                if (!wait && !overwrite_io) {
                        overwrite_io = 1;
-                       if (!down_read_trylock(&OCFS2_I(inode)->ip_alloc_sem)) {
-                               ret = -EAGAIN;
-                               goto out_unlock;
-                       }
 
                        ret = ocfs2_overwrite_io(inode, di_bh, pos, count);
-                       brelse(di_bh);
-                       di_bh = NULL;
-                       up_read(&OCFS2_I(inode)->ip_alloc_sem);
                        if (ret < 0) {
                                if (ret != -EAGAIN)
                                        mlog_errno(ret);
@@ -2183,7 +2212,10 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
                 * set inode->i_size at the end of a write. */
                if (should_remove_suid(dentry)) {
                        if (meta_level == 0) {
-                               ocfs2_inode_unlock(inode, meta_level);
+                               ocfs2_inode_unlock_for_extent_tree(inode,
+                                                                  &di_bh,
+                                                                  meta_level,
+                                                                  write_sem);
                                meta_level = 1;
                                continue;
                        }
@@ -2197,18 +2229,32 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
 
                ret = ocfs2_check_range_for_refcount(inode, pos, count);
                if (ret == 1) {
-                       ocfs2_inode_unlock(inode, meta_level);
-                       meta_level = -1;
-
-                       ret = ocfs2_prepare_inode_for_refcount(inode,
-                                                              file,
-                                                              pos,
-                                                              count,
-                                                              &meta_level);
+                       ocfs2_inode_unlock_for_extent_tree(inode,
+                                                          &di_bh,
+                                                          meta_level,
+                                                          write_sem);
+                       ret = ocfs2_inode_lock_for_extent_tree(inode,
+                                                              &di_bh,
+                                                              meta_level,
+                                                              overwrite_io,
+                                                              1,
+                                                              wait);
+                       write_sem = 1;
+                       if (ret < 0) {
+                               if (ret != -EAGAIN)
+                                       mlog_errno(ret);
+                               goto out;
+                       }
+
+                       cpos = pos >> OCFS2_SB(inode->i_sb)->s_clustersize_bits;
+                       clusters =
+                               ocfs2_clusters_for_bytes(inode->i_sb, pos + count) - cpos;
+                       ret = ocfs2_refcount_cow(inode, di_bh, cpos, clusters, UINT_MAX);
                }
 
                if (ret < 0) {
-                       mlog_errno(ret);
+                       if (ret != -EAGAIN)
+                               mlog_errno(ret);
                        goto out_unlock;
                }
 
@@ -2219,10 +2265,10 @@ out_unlock:
        trace_ocfs2_prepare_inode_for_write(OCFS2_I(inode)->ip_blkno,
                                            pos, count, wait);
 
-       brelse(di_bh);
-
-       if (meta_level >= 0)
-               ocfs2_inode_unlock(inode, meta_level);
+       ocfs2_inode_unlock_for_extent_tree(inode,
+                                          &di_bh,
+                                          meta_level,
+                                          write_sem);
 
 out:
        return ret;
index 01f514521687cddf6458e7f7f6c8fa2abd5d082e..7865e6b5d36cd91d11e9cf4b90d2b52db3352d26 100644 (file)
@@ -44,7 +44,20 @@ struct drm_gem_shmem_object {
         */
        unsigned int pages_use_count;
 
+       /**
+        * @madv: State for madvise
+        *
+        * 0 is active/inuse.
+        * A negative value is the object is purged.
+        * Positive values are driver specific and not used by the helpers.
+        */
        int madv;
+
+       /**
+        * @madv_list: List entry for madvise tracking
+        *
+        * Typically used by drivers to track purgeable objects
+        */
        struct list_head madv_list;
 
        /**
index 5b79d253fb46e80e0319e16f5eb9d2edbb74b1f6..520235c20708b5089b623caf9459dfd9351a72c8 100644 (file)
@@ -13,7 +13,8 @@ struct drm_crtc;
 
 void drm_self_refresh_helper_alter_state(struct drm_atomic_state *state);
 void drm_self_refresh_helper_update_avg_times(struct drm_atomic_state *state,
-                                             unsigned int commit_time_ms);
+                                       unsigned int commit_time_ms,
+                                       unsigned int new_self_refresh_mask);
 
 int drm_self_refresh_helper_init(struct drm_crtc *crtc);
 void drm_self_refresh_helper_cleanup(struct drm_crtc *crtc);
index 4ec8986e5dfb61c7f2fd47abd2563893bb4deaa0..ac6e946b6767bba3d6750fafb374e364af1191b8 100644 (file)
@@ -185,7 +185,7 @@ static inline void idr_preload_end(void)
  * is convenient for a "not found" value.
  */
 #define idr_for_each_entry(idr, entry, id)                     \
-       for (id = 0; ((entry) = idr_get_next(idr, &(id))) != NULL; ++id)
+       for (id = 0; ((entry) = idr_get_next(idr, &(id))) != NULL; id += 1U)
 
 /**
  * idr_for_each_entry_ul() - Iterate over an IDR's elements of a given type.
index cc292273e6ba0c0ac56d38d16aa1f87d65730393..a2adf95b3f9c5e1e026a3d1db1cb7136c992ca83 100644 (file)
@@ -695,11 +695,6 @@ static inline void *kvcalloc(size_t n, size_t size, gfp_t flags)
 
 extern void kvfree(const void *addr);
 
-static inline atomic_t *compound_mapcount_ptr(struct page *page)
-{
-       return &page[1].compound_mapcount;
-}
-
 static inline int compound_mapcount(struct page *page)
 {
        VM_BUG_ON_PAGE(!PageCompound(page), page);
index 2222fa795284183344d603c5286fcfd8c40dffa3..270aa8fd2800b4234297fa7c27577705f8c24395 100644 (file)
@@ -221,6 +221,11 @@ struct page {
 #endif
 } _struct_page_alignment;
 
+static inline atomic_t *compound_mapcount_ptr(struct page *page)
+{
+       return &page[1].compound_mapcount;
+}
+
 /*
  * Used for sizing the vmemmap region on some architectures
  */
index f91cb8898ff0af60d751f7c026c7b9f852fe620b..1bf83c8fcaa77e31cd3acd8e2f16c54e6ea05bf5 100644 (file)
@@ -622,12 +622,28 @@ static inline int PageTransCompound(struct page *page)
  *
  * Unlike PageTransCompound, this is safe to be called only while
  * split_huge_pmd() cannot run from under us, like if protected by the
- * MMU notifier, otherwise it may result in page->_mapcount < 0 false
+ * MMU notifier, otherwise it may result in page->_mapcount check false
  * positives.
+ *
+ * We have to treat page cache THP differently since every subpage of it
+ * would get _mapcount inc'ed once it is PMD mapped.  But, it may be PTE
+ * mapped in the current process so comparing subpage's _mapcount to
+ * compound_mapcount to filter out PTE mapped case.
  */
 static inline int PageTransCompoundMap(struct page *page)
 {
-       return PageTransCompound(page) && atomic_read(&page->_mapcount) < 0;
+       struct page *head;
+
+       if (!PageTransCompound(page))
+               return 0;
+
+       if (PageAnon(page))
+               return atomic_read(&page->_mapcount) < 0;
+
+       head = compound_head(page);
+       /* File THP is PMD mapped and not PTE mapped */
+       return atomic_read(&page->_mapcount) ==
+              atomic_read(compound_mapcount_ptr(head));
 }
 
 /*
index b5116013f27ef981bc1d5fcac8dd34831b60e04c..63e62372443a501d33d42e6333419004ae614b6f 100644 (file)
@@ -315,24 +315,6 @@ radix_tree_iter_lookup(const struct radix_tree_root *root,
        return radix_tree_next_chunk(root, iter, RADIX_TREE_ITER_CONTIG);
 }
 
-/**
- * radix_tree_iter_find - find a present entry
- * @root: radix tree root
- * @iter: iterator state
- * @index: start location
- *
- * This function returns the slot containing the entry with the lowest index
- * which is at least @index.  If @index is larger than any present entry, this
- * function returns NULL.  The @iter is updated to describe the entry found.
- */
-static inline void __rcu **
-radix_tree_iter_find(const struct radix_tree_root *root,
-                       struct radix_tree_iter *iter, unsigned long index)
-{
-       radix_tree_iter_init(iter, index);
-       return radix_tree_next_chunk(root, iter, 0);
-}
-
 /**
  * radix_tree_iter_retry - retry this chunk of the iteration
  * @iter:      iterator state
index e168dc59e9a0d6c4b8b79242848c7db0a0b93337..d99b5a772698037a9a9fd51a3711a69393a166ef 100644 (file)
@@ -63,6 +63,7 @@ struct nvme_passthru_cmd64 {
        __u32   cdw14;
        __u32   cdw15;
        __u32   timeout_ms;
+       __u32   rsvd2;
        __u64   result;
 };
 
index 99335e1f4a275b1dbc86219a6dee7701b18fd624..25b4fa00bad1f4ccc22f7dfe708a95807415b151 100644 (file)
  *               sent when the child exits.
  * @stack:       Specify the location of the stack for the
  *               child process.
+ *               Note, @stack is expected to point to the
+ *               lowest address. The stack direction will be
+ *               determined by the kernel and set up
+ *               appropriately based on @stack_size.
  * @stack_size:  The size of the stack for the child process.
  * @tls:         If CLONE_SETTLS is set, the tls descriptor
  *               is set to tls.
index bcdf5312521036486b7613e7499d7174e62526c6..55af6931c6ec3f8b817836c7fc78d56638f7de8c 100644 (file)
@@ -2561,7 +2561,35 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs,
        return 0;
 }
 
-static bool clone3_args_valid(const struct kernel_clone_args *kargs)
+/**
+ * clone3_stack_valid - check and prepare stack
+ * @kargs: kernel clone args
+ *
+ * Verify that the stack arguments userspace gave us are sane.
+ * In addition, set the stack direction for userspace since it's easy for us to
+ * determine.
+ */
+static inline bool clone3_stack_valid(struct kernel_clone_args *kargs)
+{
+       if (kargs->stack == 0) {
+               if (kargs->stack_size > 0)
+                       return false;
+       } else {
+               if (kargs->stack_size == 0)
+                       return false;
+
+               if (!access_ok((void __user *)kargs->stack, kargs->stack_size))
+                       return false;
+
+#if !defined(CONFIG_STACK_GROWSUP) && !defined(CONFIG_IA64)
+               kargs->stack += kargs->stack_size;
+#endif
+       }
+
+       return true;
+}
+
+static bool clone3_args_valid(struct kernel_clone_args *kargs)
 {
        /*
         * All lower bits of the flag word are taken.
@@ -2581,6 +2609,9 @@ static bool clone3_args_valid(const struct kernel_clone_args *kargs)
            kargs->exit_signal)
                return false;
 
+       if (!clone3_stack_valid(kargs))
+               return false;
+
        return true;
 }
 
index 5cff72f18c4a4ce4f0770f968dadefd4e6d190ad..33ffbf30885394c89d2c8c933eeb50a7769c357e 100644 (file)
@@ -106,7 +106,12 @@ retry:
                was_locked = 1;
        } else {
                local_irq_restore(flags);
-               cpu_relax();
+               /*
+                * Wait for the lock to release before jumping to
+                * atomic_cmpxchg() in order to mitigate the thundering herd
+                * problem.
+                */
+               do { cpu_relax(); } while (atomic_read(&dump_lock) != -1);
                goto retry;
        }
 
index 66a3748924828dcf4be6f3ffb06ef4a785600f7d..c2cf2c52bbde5c54534b2227cee2176baf78383a 100644 (file)
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -215,7 +215,7 @@ int idr_for_each(const struct idr *idr,
 EXPORT_SYMBOL(idr_for_each);
 
 /**
- * idr_get_next() - Find next populated entry.
+ * idr_get_next_ul() - Find next populated entry.
  * @idr: IDR handle.
  * @nextid: Pointer to an ID.
  *
@@ -224,7 +224,7 @@ EXPORT_SYMBOL(idr_for_each);
  * to the ID of the found value.  To use in a loop, the value pointed to by
  * nextid must be incremented by the user.
  */
-void *idr_get_next(struct idr *idr, int *nextid)
+void *idr_get_next_ul(struct idr *idr, unsigned long *nextid)
 {
        struct radix_tree_iter iter;
        void __rcu **slot;
@@ -245,18 +245,14 @@ void *idr_get_next(struct idr *idr, int *nextid)
        }
        if (!slot)
                return NULL;
-       id = iter.index + base;
-
-       if (WARN_ON_ONCE(id > INT_MAX))
-               return NULL;
 
-       *nextid = id;
+       *nextid = iter.index + base;
        return entry;
 }
-EXPORT_SYMBOL(idr_get_next);
+EXPORT_SYMBOL(idr_get_next_ul);
 
 /**
- * idr_get_next_ul() - Find next populated entry.
+ * idr_get_next() - Find next populated entry.
  * @idr: IDR handle.
  * @nextid: Pointer to an ID.
  *
@@ -265,22 +261,17 @@ EXPORT_SYMBOL(idr_get_next);
  * to the ID of the found value.  To use in a loop, the value pointed to by
  * nextid must be incremented by the user.
  */
-void *idr_get_next_ul(struct idr *idr, unsigned long *nextid)
+void *idr_get_next(struct idr *idr, int *nextid)
 {
-       struct radix_tree_iter iter;
-       void __rcu **slot;
-       unsigned long base = idr->idr_base;
        unsigned long id = *nextid;
+       void *entry = idr_get_next_ul(idr, &id);
 
-       id = (id < base) ? 0 : id - base;
-       slot = radix_tree_iter_find(&idr->idr_rt, &iter, id);
-       if (!slot)
+       if (WARN_ON_ONCE(id > INT_MAX))
                return NULL;
-
-       *nextid = iter.index + base;
-       return rcu_dereference_raw(*slot);
+       *nextid = id;
+       return entry;
 }
-EXPORT_SYMBOL(idr_get_next_ul);
+EXPORT_SYMBOL(idr_get_next);
 
 /**
  * idr_replace() - replace pointer for given ID.
index 18c1dfbb1765487a3df6bd5792c8d6e599fed15c..c8fa1d274530299a124bedf0d689dd108dc5776e 100644 (file)
@@ -1529,7 +1529,7 @@ void __rcu **idr_get_free(struct radix_tree_root *root,
                        offset = radix_tree_find_next_bit(node, IDR_FREE,
                                                        offset + 1);
                        start = next_index(start, node, offset);
-                       if (start > max)
+                       if (start > max || start == 0)
                                return ERR_PTR(-ENOSPC);
                        while (offset == RADIX_TREE_MAP_SIZE) {
                                offset = node->offset + 1;
index 9d631a7b6a70520bc9afccbef042cf8519ee5143..7df4f7f395bf2810913725747d29f1717eb4e1ec 100644 (file)
@@ -1110,6 +1110,28 @@ static noinline void check_find_entry(struct xarray *xa)
        XA_BUG_ON(xa, !xa_empty(xa));
 }
 
+static noinline void check_move_tiny(struct xarray *xa)
+{
+       XA_STATE(xas, xa, 0);
+
+       XA_BUG_ON(xa, !xa_empty(xa));
+       rcu_read_lock();
+       XA_BUG_ON(xa, xas_next(&xas) != NULL);
+       XA_BUG_ON(xa, xas_next(&xas) != NULL);
+       rcu_read_unlock();
+       xa_store_index(xa, 0, GFP_KERNEL);
+       rcu_read_lock();
+       xas_set(&xas, 0);
+       XA_BUG_ON(xa, xas_next(&xas) != xa_mk_index(0));
+       XA_BUG_ON(xa, xas_next(&xas) != NULL);
+       xas_set(&xas, 0);
+       XA_BUG_ON(xa, xas_prev(&xas) != xa_mk_index(0));
+       XA_BUG_ON(xa, xas_prev(&xas) != NULL);
+       rcu_read_unlock();
+       xa_erase_index(xa, 0);
+       XA_BUG_ON(xa, !xa_empty(xa));
+}
+
 static noinline void check_move_small(struct xarray *xa, unsigned long idx)
 {
        XA_STATE(xas, xa, 0);
@@ -1217,6 +1239,8 @@ static noinline void check_move(struct xarray *xa)
 
        xa_destroy(xa);
 
+       check_move_tiny(xa);
+
        for (i = 0; i < 16; i++)
                check_move_small(xa, 1UL << i);
 
index 446b956c918888d06dfca776d00aed8f3c2e54de..1237c213f52bc08ad3f58387aa603979c7cafbcd 100644 (file)
@@ -994,6 +994,8 @@ void *__xas_prev(struct xa_state *xas)
 
        if (!xas_frozen(xas->xa_node))
                xas->xa_index--;
+       if (!xas->xa_node)
+               return set_bounds(xas);
        if (xas_not_node(xas->xa_node))
                return xas_load(xas);
 
@@ -1031,6 +1033,8 @@ void *__xas_next(struct xa_state *xas)
 
        if (!xas_frozen(xas->xa_node))
                xas->xa_index++;
+       if (!xas->xa_node)
+               return set_bounds(xas);
        if (xas_not_node(xas->xa_node))
                return xas_load(xas);
 
index 0a1b4b484ac5b4a0eed5e5148f04849d9e09607b..f05d27b7183dcd9699427e19fdc1b8cd00642028 100644 (file)
@@ -1028,12 +1028,13 @@ static void collapse_huge_page(struct mm_struct *mm,
 
        anon_vma_lock_write(vma->anon_vma);
 
-       pte = pte_offset_map(pmd, address);
-       pte_ptl = pte_lockptr(mm, pmd);
-
        mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, NULL, mm,
                                address, address + HPAGE_PMD_SIZE);
        mmu_notifier_invalidate_range_start(&range);
+
+       pte = pte_offset_map(pmd, address);
+       pte_ptl = pte_lockptr(mm, pmd);
+
        pmd_ptl = pmd_lock(mm, pmd); /* probably unnecessary */
        /*
         * After this gup_fast can't run anymore. This also removes
index 363106578876152b06ced3999cdacefaac0aa485..37592dd7ae3264ba4bf8cc94c63910f56585aa5b 100644 (file)
@@ -484,7 +484,7 @@ ino_t page_cgroup_ino(struct page *page)
        unsigned long ino = 0;
 
        rcu_read_lock();
-       if (PageHead(page) && PageSlab(page))
+       if (PageSlab(page) && !PageTail(page))
                memcg = memcg_from_slab_page(page);
        else
                memcg = READ_ONCE(page->mem_cgroup);
@@ -2534,6 +2534,15 @@ retry:
                goto retry;
        }
 
+       /*
+        * Memcg doesn't have a dedicated reserve for atomic
+        * allocations. But like the global atomic pool, we need to
+        * put the burden of reclaim on regular allocation requests
+        * and let these go through as privileged allocations.
+        */
+       if (gfp_mask & __GFP_ATOMIC)
+               goto force;
+
        /*
         * Unlike in global OOM situations, memcg is not in a physical
         * memory shortage.  Allow dying and OOM-killed tasks to
@@ -5014,12 +5023,6 @@ static void __mem_cgroup_free(struct mem_cgroup *memcg)
 {
        int node;
 
-       /*
-        * Flush percpu vmstats and vmevents to guarantee the value correctness
-        * on parent's and all ancestor levels.
-        */
-       memcg_flush_percpu_vmstats(memcg, false);
-       memcg_flush_percpu_vmevents(memcg);
        for_each_node(node)
                free_mem_cgroup_per_node_info(memcg, node);
        free_percpu(memcg->vmstats_percpu);
@@ -5030,6 +5033,12 @@ static void __mem_cgroup_free(struct mem_cgroup *memcg)
 static void mem_cgroup_free(struct mem_cgroup *memcg)
 {
        memcg_wb_domain_exit(memcg);
+       /*
+        * Flush percpu vmstats and vmevents to guarantee the value correctness
+        * on parent's and all ancestor levels.
+        */
+       memcg_flush_percpu_vmstats(memcg, false);
+       memcg_flush_percpu_vmevents(memcg);
        __mem_cgroup_free(memcg);
 }
 
index df570e5c71cc6b8f696ac44d225529e17703876d..07e5c67f48a85c9c67391a4e6b0a6e3f48466d3b 100644 (file)
@@ -447,6 +447,14 @@ static void update_pgdat_span(struct pglist_data *pgdat)
                                             zone->spanned_pages;
 
                /* No need to lock the zones, they can't change. */
+               if (!zone->spanned_pages)
+                       continue;
+               if (!node_end_pfn) {
+                       node_start_pfn = zone->zone_start_pfn;
+                       node_end_pfn = zone_end_pfn;
+                       continue;
+               }
+
                if (zone_end_pfn > node_end_pfn)
                        node_end_pfn = zone_end_pfn;
                if (zone->zone_start_pfn < node_start_pfn)
index 7fde88695f35d62c1f22ffe1cc724ffe85ea92e9..9a889e456168bcc72957dc79fe4c7c234243aa73 100644 (file)
@@ -180,7 +180,7 @@ int __mmu_notifier_invalidate_range_start(struct mmu_notifier_range *range)
                                        mn->ops->invalidate_range_start, _ret,
                                        !mmu_notifier_range_blockable(range) ? "non-" : "");
                                WARN_ON(mmu_notifier_range_blockable(range) ||
-                                       ret != -EAGAIN);
+                                       _ret != -EAGAIN);
                                ret = _ret;
                        }
                }
index ecc3dbad606b04ce690e584e4d6609e85c66173b..f391c0c4ed1deb2299a7552dcd27c8d68e4b1412 100644 (file)
@@ -1947,6 +1947,14 @@ void __init page_alloc_init_late(void)
        /* Block until all are initialised */
        wait_for_completion(&pgdat_init_all_done_comp);
 
+       /*
+        * The number of managed pages has changed due to the initialisation
+        * so the pcpu batch and high limits needs to be updated or the limits
+        * will be artificially small.
+        */
+       for_each_populated_zone(zone)
+               zone_pcp_update(zone);
+
        /*
         * We initialized the rest of the deferred pages.  Permanently disable
         * on-demand struct page initialization.
@@ -3720,10 +3728,6 @@ try_this_zone:
 static void warn_alloc_show_mem(gfp_t gfp_mask, nodemask_t *nodemask)
 {
        unsigned int filter = SHOW_MEM_FILTER_NODES;
-       static DEFINE_RATELIMIT_STATE(show_mem_rs, HZ, 1);
-
-       if (!__ratelimit(&show_mem_rs))
-               return;
 
        /*
         * This documents exceptions given to allocations in certain
@@ -3744,8 +3748,7 @@ void warn_alloc(gfp_t gfp_mask, nodemask_t *nodemask, const char *fmt, ...)
 {
        struct va_format vaf;
        va_list args;
-       static DEFINE_RATELIMIT_STATE(nopage_rs, DEFAULT_RATELIMIT_INTERVAL,
-                                     DEFAULT_RATELIMIT_BURST);
+       static DEFINE_RATELIMIT_STATE(nopage_rs, 10*HZ, 1);
 
        if ((gfp_mask & __GFP_NOWARN) || !__ratelimit(&nopage_rs))
                return;
@@ -8514,7 +8517,6 @@ void free_contig_range(unsigned long pfn, unsigned int nr_pages)
        WARN(count != 0, "%d pages are still in use!\n", count);
 }
 
-#ifdef CONFIG_MEMORY_HOTPLUG
 /*
  * The zone indicated has a new number of managed_pages; batch sizes and percpu
  * page high values need to be recalulated.
@@ -8528,7 +8530,6 @@ void __meminit zone_pcp_update(struct zone *zone)
                                per_cpu_ptr(zone->pageset, cpu));
        mutex_unlock(&pcp_batch_high_lock);
 }
-#endif
 
 void zone_pcp_reset(struct zone *zone)
 {
index 68e455f2b698cbfab04ac4a1d61df3c1a32cfe9e..b2b01694dc43f63259fa3ee1e1b59ef3505f794b 100644 (file)
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -323,8 +323,8 @@ static inline struct kmem_cache *memcg_root_cache(struct kmem_cache *s)
  * Expects a pointer to a slab page. Please note, that PageSlab() check
  * isn't sufficient, as it returns true also for tail compound slab pages,
  * which do not have slab_cache pointer set.
- * So this function assumes that the page can pass PageHead() and PageSlab()
- * checks.
+ * So this function assumes that the page can pass PageSlab() && !PageTail()
+ * check.
  *
  * The kmem_cache can be reparented asynchronously. The caller must ensure
  * the memcg lifetime, e.g. by taking rcu_read_lock() or cgroup_mutex.
index 6afc892a148a0408a901695d42529a2a1be99939..a8222041bd44d648a4c8b5a1e5e345314efb050e 100644 (file)
@@ -1383,12 +1383,29 @@ static void pagetypeinfo_showfree_print(struct seq_file *m,
                        unsigned long freecount = 0;
                        struct free_area *area;
                        struct list_head *curr;
+                       bool overflow = false;
 
                        area = &(zone->free_area[order]);
 
-                       list_for_each(curr, &area->free_list[mtype])
-                               freecount++;
-                       seq_printf(m, "%6lu ", freecount);
+                       list_for_each(curr, &area->free_list[mtype]) {
+                               /*
+                                * Cap the free_list iteration because it might
+                                * be really large and we are under a spinlock
+                                * so a long time spent here could trigger a
+                                * hard lockup detector. Anyway this is a
+                                * debugging tool so knowing there is a handful
+                                * of pages of this order should be more than
+                                * sufficient.
+                                */
+                               if (++freecount >= 100000) {
+                                       overflow = true;
+                                       break;
+                               }
+                       }
+                       seq_printf(m, "%s%6lu ", overflow ? ">" : "", freecount);
+                       spin_unlock_irq(&zone->lock);
+                       cond_resched();
+                       spin_lock_irq(&zone->lock);
                }
                seq_putc(m, '\n');
        }
@@ -1972,7 +1989,7 @@ void __init init_mm_internals(void)
 #endif
 #ifdef CONFIG_PROC_FS
        proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op);
-       proc_create_seq("pagetypeinfo", 0444, NULL, &pagetypeinfo_op);
+       proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op);
        proc_create_seq("vmstat", 0444, NULL, &vmstat_op);
        proc_create_seq("zoneinfo", 0444, NULL, &zoneinfo_op);
 #endif
index 7b7c2fafbc687d2f9cb0316089c8e124bf9a9fd0..be984aa29b759cb1e42bb2c8d6e42eb4b061fb9c 100644 (file)
@@ -99,7 +99,8 @@ lx-symbols command."""
             attrs[n]['name'].string(): attrs[n]['address']
             for n in range(int(sect_attrs['nsections']))}
         args = []
-        for section_name in [".data", ".data..read_mostly", ".rodata", ".bss"]:
+        for section_name in [".data", ".data..read_mostly", ".rodata", ".bss",
+                             ".text", ".text.hot", ".text.unlikely"]:
             address = section_name_to_address.get(section_name)
             if address:
                 args.append(" -s {name} {addr}".format(
index dda6fbac016e413983e18982c1ca4b32e79f3c47..04cea092167368dad12f213b9bdd6b32562aac66 100644 (file)
@@ -31,12 +31,12 @@ generate_deps() {
        local mod_file=`echo $@ | sed -e 's/\.ko/\.mod/'`
        local ns_deps_file=`echo $@ | sed -e 's/\.ko/\.ns_deps/'`
        if [ ! -f "$ns_deps_file" ]; then return; fi
-       local mod_source_files=`cat $mod_file | sed -n 1p                      \
+       local mod_source_files="`cat $mod_file | sed -n 1p                      \
                                              | sed -e 's/\.o/\.c/g'           \
-                                             | sed "s|[^ ]* *|${srctree}/&|g"`
+                                             | sed "s|[^ ]* *|${srctree}/&|g"`"
        for ns in `cat $ns_deps_file`; do
                echo "Adding namespace $ns to module $mod_name (if needed)."
-               generate_deps_for_ns $ns $mod_source_files
+               generate_deps_for_ns $ns "$mod_source_files"
                # sort the imports
                for source_file in $mod_source_files; do
                        sed '/MODULE_IMPORT_NS/Q' $source_file > ${source_file}.tmp
index 41905afada63fee667d34478301217e05b98d3c5..f34ce564d92c481791c4121c5b4c8b64f953be9e 100644 (file)
@@ -528,7 +528,7 @@ static int snd_compress_check_input(struct snd_compr_params *params)
 {
        /* first let's check the buffer parameter's */
        if (params->buffer.fragment_size == 0 ||
-           params->buffer.fragments > INT_MAX / params->buffer.fragment_size ||
+           params->buffer.fragments > U32_MAX / params->buffer.fragment_size ||
            params->buffer.fragments == 0)
                return -EINVAL;
 
index 6b724d2ee2de9b0de0106bf5d2586e8f77677cd7..59ae21b0bb936c0757d58573b1bac3ed3defcb1a 100644 (file)
@@ -284,11 +284,11 @@ int snd_timer_open(struct snd_timer_instance **ti,
                goto unlock;
        }
        if (!list_empty(&timer->open_list_head)) {
-               timeri = list_entry(timer->open_list_head.next,
+               struct snd_timer_instance *t =
+                       list_entry(timer->open_list_head.next,
                                    struct snd_timer_instance, open_list);
-               if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) {
+               if (t->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) {
                        err = -EBUSY;
-                       timeri = NULL;
                        goto unlock;
                }
        }
index 32b864bee25f109b04c704274de4b2a543e56352..06d6a37cd8532427dbbd286e5085a592f5e2914b 100644 (file)
@@ -27,6 +27,8 @@
 #define SAFFIRE_CLOCK_SOURCE_SPDIF             1
 
 /* clock sources as returned from register of Saffire Pro 10 and 26 */
+#define SAFFIREPRO_CLOCK_SOURCE_SELECT_MASK    0x000000ff
+#define SAFFIREPRO_CLOCK_SOURCE_DETECT_MASK    0x0000ff00
 #define SAFFIREPRO_CLOCK_SOURCE_INTERNAL       0
 #define SAFFIREPRO_CLOCK_SOURCE_SKIP           1 /* never used on hardware */
 #define SAFFIREPRO_CLOCK_SOURCE_SPDIF          2
@@ -189,6 +191,7 @@ saffirepro_both_clk_src_get(struct snd_bebob *bebob, unsigned int *id)
                map = saffirepro_clk_maps[1];
 
        /* In a case that this driver cannot handle the value of register. */
+       value &= SAFFIREPRO_CLOCK_SOURCE_SELECT_MASK;
        if (value >= SAFFIREPRO_CLOCK_SOURCE_COUNT || map[value] < 0) {
                err = -EIO;
                goto end;
index 6d1fb7c11f17ed93b5ca4f2f12e295c3970b6ec4..b7a1abb3e2318ecc1051e6b8bbef49ea6fa46f73 100644 (file)
@@ -7604,7 +7604,7 @@ static void hp_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
        /* Delay enabling the HP amp, to let the mic-detection
         * state machine run.
         */
-       cancel_delayed_work_sync(&spec->unsol_hp_work);
+       cancel_delayed_work(&spec->unsol_hp_work);
        schedule_delayed_work(&spec->unsol_hp_work, msecs_to_jiffies(500));
        tbl = snd_hda_jack_tbl_get(codec, cb->nid);
        if (tbl)
index b72553710ffbd91eaeaf503fe601eff9d3789258..3c720703ebb8338c4ad9eef13ec5d90de9600866 100644 (file)
@@ -2851,6 +2851,18 @@ static int patch_i915_icl_hdmi(struct hda_codec *codec)
        return intel_hsw_common_init(codec, 0x02, map, ARRAY_SIZE(map));
 }
 
+static int patch_i915_tgl_hdmi(struct hda_codec *codec)
+{
+       /*
+        * pin to port mapping table where the value indicate the pin number and
+        * the index indicate the port number with 1 base.
+        */
+       static const int map[] = {0x4, 0x6, 0x8, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
+
+       return intel_hsw_common_init(codec, 0x02, map, ARRAY_SIZE(map));
+}
+
+
 /* Intel Baytrail and Braswell; with eld notifier */
 static int patch_i915_byt_hdmi(struct hda_codec *codec)
 {
@@ -4153,6 +4165,7 @@ HDA_CODEC_ENTRY(0x8086280b, "Kabylake HDMI",      patch_i915_hsw_hdmi),
 HDA_CODEC_ENTRY(0x8086280c, "Cannonlake HDMI", patch_i915_glk_hdmi),
 HDA_CODEC_ENTRY(0x8086280d, "Geminilake HDMI", patch_i915_glk_hdmi),
 HDA_CODEC_ENTRY(0x8086280f, "Icelake HDMI",    patch_i915_icl_hdmi),
+HDA_CODEC_ENTRY(0x80862812, "Tigerlake HDMI",  patch_i915_tgl_hdmi),
 HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi),
 HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI",        patch_i915_byt_hdmi),
 HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI",   patch_i915_byt_hdmi),
index 91242b6f8ea7adf27e05f2883397f932a2f1688e..4570f662fb48b4090979be99b13087c3c0507a62 100644 (file)
@@ -410,8 +410,8 @@ static void hdac_hda_codec_remove(struct snd_soc_component *component)
                return;
        }
 
-       snd_hdac_ext_bus_link_put(hdev->bus, hlink);
        pm_runtime_disable(&hdev->dev);
+       snd_hdac_ext_bus_link_put(hdev->bus, hlink);
 }
 
 static const struct snd_soc_dapm_route hdac_hda_dapm_routes[] = {
index b5fd8f08726e0a500deaf0b332880ccc5dd83be4..f8b5b960e5970ef3182aaa14b528f09fab6f50be 100644 (file)
@@ -274,7 +274,7 @@ struct hdmi_codec_priv {
        uint8_t eld[MAX_ELD_BYTES];
        struct snd_pcm_chmap *chmap_info;
        unsigned int chmap_idx;
-       struct mutex lock;
+       unsigned long busy;
        struct snd_soc_jack *jack;
        unsigned int jack_status;
 };
@@ -390,8 +390,8 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream,
        struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
        int ret = 0;
 
-       ret = mutex_trylock(&hcp->lock);
-       if (!ret) {
+       ret = test_and_set_bit(0, &hcp->busy);
+       if (ret) {
                dev_err(dai->dev, "Only one simultaneous stream supported!\n");
                return -EINVAL;
        }
@@ -419,7 +419,7 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream,
 
 err:
        /* Release the exclusive lock on error */
-       mutex_unlock(&hcp->lock);
+       clear_bit(0, &hcp->busy);
        return ret;
 }
 
@@ -431,7 +431,7 @@ static void hdmi_codec_shutdown(struct snd_pcm_substream *substream,
        hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
        hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data);
 
-       mutex_unlock(&hcp->lock);
+       clear_bit(0, &hcp->busy);
 }
 
 static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
@@ -811,8 +811,6 @@ static int hdmi_codec_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        hcp->hcd = *hcd;
-       mutex_init(&hcp->lock);
-
        daidrv = devm_kcalloc(dev, dai_count, sizeof(*daidrv), GFP_KERNEL);
        if (!daidrv)
                return -ENOMEM;
index eb709d52825965f3c53aa7432e01191569ab3193..cae1def8902dd73ecc8f51ba28e354f7a8c6bd40 100644 (file)
@@ -960,11 +960,11 @@ static int max98373_i2c_probe(struct i2c_client *i2c,
 
        /* Power on device */
        if (gpio_is_valid(max98373->reset_gpio)) {
-               ret = gpio_request(max98373->reset_gpio, "MAX98373_RESET");
+               ret = devm_gpio_request(&i2c->dev, max98373->reset_gpio,
+                                       "MAX98373_RESET");
                if (ret) {
                        dev_err(&i2c->dev, "%s: Failed to request gpio %d\n",
                                __func__, max98373->reset_gpio);
-                       gpio_free(max98373->reset_gpio);
                        return -EINVAL;
                }
                gpio_direction_output(max98373->reset_gpio, 0);
index 667e9f73aba3850401d2164b9ca143affceb0cf6..e3d311fb510e0a7497fa0e0b7c26aef1204353ef 100644 (file)
@@ -306,7 +306,7 @@ struct pm8916_wcd_analog_priv {
 };
 
 static const char *const adc2_mux_text[] = { "ZERO", "INP2", "INP3" };
-static const char *const rdac2_mux_text[] = { "ZERO", "RX2", "RX1" };
+static const char *const rdac2_mux_text[] = { "RX1", "RX2" };
 static const char *const hph_text[] = { "ZERO", "Switch", };
 
 static const struct soc_enum hph_enum = SOC_ENUM_SINGLE_VIRT(
@@ -321,7 +321,7 @@ static const struct soc_enum adc2_enum = SOC_ENUM_SINGLE_VIRT(
 
 /* RDAC2 MUX */
 static const struct soc_enum rdac2_mux_enum = SOC_ENUM_SINGLE(
-                       CDC_D_CDC_CONN_HPHR_DAC_CTL, 0, 3, rdac2_mux_text);
+                       CDC_D_CDC_CONN_HPHR_DAC_CTL, 0, 2, rdac2_mux_text);
 
 static const struct snd_kcontrol_new spkr_switch[] = {
        SOC_DAPM_SINGLE("Switch", CDC_A_SPKR_DAC_CTL, 7, 1, 0)
index 61226fefe1c4bc13bbb916faf56f5728d65ce0e9..2a4ffe945177ba150f03a066442688bb637a82da 100644 (file)
@@ -555,10 +555,6 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
                return PTR_ERR(priv->clk);
        }
 
-       err = clk_prepare_enable(priv->clk);
-       if (err < 0)
-               return err;
-
        priv->extclk = devm_clk_get(&pdev->dev, "extclk");
        if (IS_ERR(priv->extclk)) {
                if (PTR_ERR(priv->extclk) == -EPROBE_DEFER)
@@ -574,6 +570,10 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
                }
        }
 
+       err = clk_prepare_enable(priv->clk);
+       if (err < 0)
+               return err;
+
        /* Some sensible defaults - this reflects the powerup values */
        priv->ctl_play = KIRKWOOD_PLAYCTL_SIZE_24;
        priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24;
@@ -587,7 +587,7 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
                priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128;
        }
 
-       err = devm_snd_soc_register_component(&pdev->dev, &kirkwood_soc_component,
+       err = snd_soc_register_component(&pdev->dev, &kirkwood_soc_component,
                                         soc_dai, 2);
        if (err) {
                dev_err(&pdev->dev, "snd_soc_register_component failed\n");
@@ -610,6 +610,7 @@ static int kirkwood_i2s_dev_remove(struct platform_device *pdev)
 {
        struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev);
 
+       snd_soc_unregister_component(&pdev->dev);
        if (!IS_ERR(priv->extclk))
                clk_disable_unprepare(priv->extclk);
        clk_disable_unprepare(priv->clk);
index 0097df1fae662f1d5a25af1daf36ddfc5bfb20cc..e80b09143b63edf970e8921366cc074dd6c43ef9 100644 (file)
@@ -66,10 +66,13 @@ static int rk_jack_event(struct notifier_block *nb, unsigned long event,
        struct snd_soc_jack *jack = (struct snd_soc_jack *)data;
        struct snd_soc_dapm_context *dapm = &jack->card->dapm;
 
-       if (event & SND_JACK_MICROPHONE)
+       if (event & SND_JACK_MICROPHONE) {
                snd_soc_dapm_force_enable_pin(dapm, "MICBIAS");
-       else
+               snd_soc_dapm_force_enable_pin(dapm, "SHDN");
+       } else {
                snd_soc_dapm_disable_pin(dapm, "MICBIAS");
+               snd_soc_dapm_disable_pin(dapm, "SHDN");
+       }
 
        snd_soc_dapm_sync(dapm);
 
index 0324a5c3961963b1d9315d1618161c8113891808..28f65eba2bb459fa354c03af97c455e3dd1270d8 100644 (file)
@@ -508,10 +508,10 @@ static struct rsnd_mod_ops rsnd_dmapp_ops = {
 #define RDMA_SSI_I_N(addr, i)  (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8)
 #define RDMA_SSI_O_N(addr, i)  (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc)
 
-#define RDMA_SSIU_I_N(addr, i, j) (addr ##_reg - 0x00441000 + (0x1000 * (i)) + (((j) / 4) * 0xA000) + (((j) % 4) * 0x400))
+#define RDMA_SSIU_I_N(addr, i, j) (addr ##_reg - 0x00441000 + (0x1000 * (i)) + (((j) / 4) * 0xA000) + (((j) % 4) * 0x400) - (0x4000 * ((i) / 9) * ((j) / 4)))
 #define RDMA_SSIU_O_N(addr, i, j) RDMA_SSIU_I_N(addr, i, j)
 
-#define RDMA_SSIU_I_P(addr, i, j) (addr ##_reg - 0x00141000 + (0x1000 * (i)) + (((j) / 4) * 0xA000) + (((j) % 4) * 0x400))
+#define RDMA_SSIU_I_P(addr, i, j) (addr ##_reg - 0x00141000 + (0x1000 * (i)) + (((j) / 4) * 0xA000) + (((j) % 4) * 0x400) - (0x4000 * ((i) / 9) * ((j) / 4)))
 #define RDMA_SSIU_O_P(addr, i, j) RDMA_SSIU_I_P(addr, i, j)
 
 #define RDMA_SRC_I_N(addr, i)  (addr ##_reg - 0x00500000 + (0x400 * i))
index 54cd431faab705dd908ff5cde5a9d9b50ede8e68..5529e8eeca462a9bebf8c5e3494a0bca9c6df8cd 100644 (file)
@@ -152,8 +152,10 @@ static ssize_t sof_dfsentry_write(struct file *file, const char __user *buffer,
         */
        dentry = file->f_path.dentry;
        if (strcmp(dentry->d_name.name, "ipc_flood_count") &&
-           strcmp(dentry->d_name.name, "ipc_flood_duration_ms"))
-               return -EINVAL;
+           strcmp(dentry->d_name.name, "ipc_flood_duration_ms")) {
+               ret = -EINVAL;
+               goto out;
+       }
 
        if (!strcmp(dentry->d_name.name, "ipc_flood_duration_ms"))
                flood_duration_test = true;
index 2c744718840254fc30eec8a12dc39ac45d014a14..0c11fceb28a7a234c1afde9b9c7bc52fe001bd53 100644 (file)
@@ -190,7 +190,7 @@ hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction)
         * Workaround to address a known issue with host DMA that results
         * in xruns during pause/release in capture scenarios.
         */
-       if (!IS_ENABLED(SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1))
+       if (!IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1))
                if (stream && direction == SNDRV_PCM_STREAM_CAPTURE)
                        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
                                                HDA_VS_INTEL_EM2,
@@ -228,7 +228,7 @@ int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag)
        spin_unlock_irq(&bus->reg_lock);
 
        /* Enable DMI L1 entry if there are no capture streams open */
-       if (!IS_ENABLED(SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1))
+       if (!IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1))
                if (!active_capture_stream)
                        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
                                                HDA_VS_INTEL_EM2,
index b2f359d2f7e530b3813ce2b78ae6175272f17e4b..086eeeab8679555b4b5fe87b2bc312fa4b5ef1ef 100644 (file)
@@ -572,8 +572,10 @@ static int sof_set_get_large_ctrl_data(struct snd_sof_dev *sdev,
        else
                err = sof_get_ctrl_copy_params(cdata->type, partdata, cdata,
                                               sparams);
-       if (err < 0)
+       if (err < 0) {
+               kfree(partdata);
                return err;
+       }
 
        msg_bytes = sparams->msg_bytes;
        pl_size = sparams->pl_size;
index 0aabb3190ddc9735aebdbc494805a28f9b97d035..4452594c2e17adfa3f191e26bd4666c160524c20 100644 (file)
@@ -543,15 +543,16 @@ static int sof_control_load_bytes(struct snd_soc_component *scomp,
        struct soc_bytes_ext *sbe = (struct soc_bytes_ext *)kc->private_value;
        int max_size = sbe->max;
 
-       if (le32_to_cpu(control->priv.size) > max_size) {
+       /* init the get/put bytes data */
+       scontrol->size = sizeof(struct sof_ipc_ctrl_data) +
+               le32_to_cpu(control->priv.size);
+
+       if (scontrol->size > max_size) {
                dev_err(sdev->dev, "err: bytes data size %d exceeds max %d.\n",
-                       control->priv.size, max_size);
+                       scontrol->size, max_size);
                return -EINVAL;
        }
 
-       /* init the get/put bytes data */
-       scontrol->size = sizeof(struct sof_ipc_ctrl_data) +
-               le32_to_cpu(control->priv.size);
        scontrol->control_data = kzalloc(max_size, GFP_KERNEL);
        cdata = scontrol->control_data;
        if (!scontrol->control_data)
index a4060813bc74c7b088bdebfa39dc1d624a2b3cc6..48e629ac2d88b630778004f652cd84b4f3b53dbd 100644 (file)
@@ -1218,6 +1218,16 @@ static int stm32_sai_pcm_process_spdif(struct snd_pcm_substream *substream,
        return 0;
 }
 
+/* No support of mmap in S/PDIF mode */
+static const struct snd_pcm_hardware stm32_sai_pcm_hw_spdif = {
+       .info = SNDRV_PCM_INFO_INTERLEAVED,
+       .buffer_bytes_max = 8 * PAGE_SIZE,
+       .period_bytes_min = 1024,
+       .period_bytes_max = PAGE_SIZE,
+       .periods_min = 2,
+       .periods_max = 8,
+};
+
 static const struct snd_pcm_hardware stm32_sai_pcm_hw = {
        .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP,
        .buffer_bytes_max = 8 * PAGE_SIZE,
@@ -1270,7 +1280,7 @@ static const struct snd_dmaengine_pcm_config stm32_sai_pcm_config = {
 };
 
 static const struct snd_dmaengine_pcm_config stm32_sai_pcm_config_spdif = {
-       .pcm_hardware = &stm32_sai_pcm_hw,
+       .pcm_hardware = &stm32_sai_pcm_hw_spdif,
        .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
        .process = stm32_sai_pcm_process_spdif,
 };
index a236350beb102504c6d0f2fbaac3ff40649844a0..2b0bc234e1b69f793b919e464eaa25175c18bd9a 100644 (file)
@@ -62,7 +62,7 @@ int sdma_pcm_platform_register(struct device *dev,
        config->chan_names[0] = txdmachan;
        config->chan_names[1] = rxdmachan;
 
-       return devm_snd_dmaengine_pcm_register(dev, config, 0);
+       return devm_snd_dmaengine_pcm_register(dev, config, flags);
 }
 EXPORT_SYMBOL_GPL(sdma_pcm_platform_register);
 
index 6ecdd10678260f278475787af8d7b1e61e970bae..1178d302757ea71977e95d6880445839434fcf4b 100644 (file)
@@ -3,7 +3,11 @@ include ../scripts/Makefile.include
 
 bindir ?= /usr/bin
 
-ifeq ($(srctree),)
+# This will work when gpio is built in tools env. where srctree
+# isn't set and when invoked from selftests build, where srctree
+# is set to ".". building_out_of_srctree is undefined for in srctree
+# builds
+ifndef building_out_of_srctree
 srctree := $(patsubst %/,%,$(dir $(CURDIR)))
 srctree := $(patsubst %/,%,$(dir $(srctree)))
 endif
index cb3fc09645c482a526e2817250469611a5697010..485cf06ef013f0183d695b35099f4409d9c5f6f4 100644 (file)
@@ -71,7 +71,7 @@ int main(int argc, char **argv)
                        flags |= MAP_SHARED;
                        break;
                case 'H':
-                       flags |= MAP_HUGETLB;
+                       flags |= (MAP_HUGETLB | MAP_ANONYMOUS);
                        break;
                default:
                        return -1;
index 051d7d3f443b4f6663d38b5c190f9293ac51f359..927a151fa9aa9e52c5c721f20c34d1682575b17f 100644 (file)
@@ -69,7 +69,7 @@ int read_usb_vudc_device(struct udev_device *sdev, struct usbip_usb_device *dev)
        FILE *fd = NULL;
        struct udev_device *plat;
        const char *speed;
-       int ret = 0;
+       size_t ret;
 
        plat = udev_device_get_parent(sdev);
        path = udev_device_get_syspath(plat);
@@ -79,8 +79,10 @@ int read_usb_vudc_device(struct udev_device *sdev, struct usbip_usb_device *dev)
        if (!fd)
                return -1;
        ret = fread((char *) &descr, sizeof(descr), 1, fd);
-       if (ret < 0)
+       if (ret != 1) {
+               err("Cannot read vudc device descr file: %s", strerror(errno));
                goto err;
+       }
        fclose(fd);
 
        copy_descr_attr(dev, &descr, bDeviceClass);