diff options
Diffstat (limited to 'drivers')
218 files changed, 1752 insertions, 992 deletions
| diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index 7abe66505739..0d2e98920069 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c @@ -416,9 +416,18 @@ acpi_tb_get_table(struct acpi_table_desc *table_desc,  		}  	} -	table_desc->validation_count++; -	if (table_desc->validation_count == 0) { -		table_desc->validation_count--; +	if (table_desc->validation_count < ACPI_MAX_TABLE_VALIDATIONS) { +		table_desc->validation_count++; + +		/* +		 * Detect validation_count overflows to ensure that the warning +		 * message will only be printed once. +		 */ +		if (table_desc->validation_count >= ACPI_MAX_TABLE_VALIDATIONS) { +			ACPI_WARNING((AE_INFO, +				      "Table %p, Validation count overflows\n", +				      table_desc)); +		}  	}  	*out_table = table_desc->pointer; @@ -445,13 +454,20 @@ void acpi_tb_put_table(struct acpi_table_desc *table_desc)  	ACPI_FUNCTION_TRACE(acpi_tb_put_table); -	if (table_desc->validation_count == 0) { -		ACPI_WARNING((AE_INFO, -			      "Table %p, Validation count is zero before decrement\n", -			      table_desc)); -		return_VOID; +	if (table_desc->validation_count < ACPI_MAX_TABLE_VALIDATIONS) { +		table_desc->validation_count--; + +		/* +		 * Detect validation_count underflows to ensure that the warning +		 * message will only be printed once. +		 */ +		if (table_desc->validation_count >= ACPI_MAX_TABLE_VALIDATIONS) { +			ACPI_WARNING((AE_INFO, +				      "Table %p, Validation count underflows\n", +				      table_desc)); +			return_VOID; +		}  	} -	table_desc->validation_count--;  	if (table_desc->validation_count == 0) { diff --git a/drivers/acpi/acpica/utresrc.c b/drivers/acpi/acpica/utresrc.c index e0587c85bafd..ff096d9755b9 100644 --- a/drivers/acpi/acpica/utresrc.c +++ b/drivers/acpi/acpica/utresrc.c @@ -474,15 +474,6 @@ acpi_ut_walk_aml_resources(struct acpi_walk_state *walk_state,  				return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);  			} -			/* -			 * The end_tag opcode must be followed by a zero byte. -			 * Although this byte is technically defined to be a checksum, -			 * in practice, all ASL compilers set this byte to zero. -			 */ -			if (*(aml + 1) != 0) { -				return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); -			} -  			/* Return the pointer to the end_tag if requested */  			if (!user_function) { diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index c5fecf97ee2f..797b28dc7b34 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -666,14 +666,6 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,  	int ret = -ENODEV;  	struct fwnode_handle *iort_fwnode; -	/* -	 * If we already translated the fwspec there -	 * is nothing left to do, return the iommu_ops. -	 */ -	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec); -	if (ops) -		return ops; -  	if (node) {  		iort_fwnode = iort_get_fwnode(node);  		if (!iort_fwnode) @@ -735,6 +727,14 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)  	u32 streamid = 0;  	int err; +	/* +	 * If we already translated the fwspec there +	 * is nothing left to do, return the iommu_ops. +	 */ +	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec); +	if (ops) +		return ops; +  	if (dev_is_pci(dev)) {  		struct pci_bus *bus = to_pci_dev(dev)->bus;  		u32 rid; @@ -782,6 +782,12 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)  	if (err)  		ops = ERR_PTR(err); +	/* Ignore all other errors apart from EPROBE_DEFER */ +	if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) { +		dev_dbg(dev, "Adding to IOMMU failed: %ld\n", PTR_ERR(ops)); +		ops = NULL; +	} +  	return ops;  } diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index a9a9ab3399d4..d42eeef9d928 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -782,7 +782,7 @@ static int acpi_battery_update(struct acpi_battery *battery, bool resume)  	if ((battery->state & ACPI_BATTERY_STATE_CRITICAL) ||  	    (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) &&              (battery->capacity_now <= battery->alarm))) -		pm_wakeup_hard_event(&battery->device->dev); +		pm_wakeup_event(&battery->device->dev, 0);  	return result;  } diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 9ad8cdb58743..e19f530f1083 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -217,7 +217,7 @@ static int acpi_lid_notify_state(struct acpi_device *device, int state)  	}  	if (state) -		pm_wakeup_hard_event(&device->dev); +		pm_wakeup_event(&device->dev, 0);  	ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device);  	if (ret == NOTIFY_DONE) @@ -402,7 +402,7 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)  		} else {  			int keycode; -			pm_wakeup_hard_event(&device->dev); +			pm_wakeup_event(&device->dev, 0);  			if (button->suspended)  				break; @@ -534,7 +534,6 @@ static int acpi_button_add(struct acpi_device *device)  		lid_device = device;  	} -	device_init_wakeup(&device->dev, true);  	printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device));  	return 0; diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 798d5003a039..993fd31394c8 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -24,7 +24,6 @@  #include <linux/pm_qos.h>  #include <linux/pm_domain.h>  #include <linux/pm_runtime.h> -#include <linux/suspend.h>  #include "internal.h" @@ -400,7 +399,7 @@ static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used)  	mutex_lock(&acpi_pm_notifier_lock);  	if (adev->wakeup.flags.notifier_present) { -		pm_wakeup_ws_event(adev->wakeup.ws, 0, true); +		__pm_wakeup_event(adev->wakeup.ws, 0);  		if (adev->wakeup.context.work.func)  			queue_pm_work(&adev->wakeup.context.work);  	} diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index e39ec7b7cb67..3a10d7573477 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1371,8 +1371,8 @@ int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)  	iort_set_dma_mask(dev);  	iommu = iort_iommu_configure(dev); -	if (IS_ERR(iommu)) -		return PTR_ERR(iommu); +	if (IS_ERR(iommu) && PTR_ERR(iommu) == -EPROBE_DEFER) +		return -EPROBE_DEFER;  	size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);  	/* diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index a6574d626340..097d630ab886 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -663,40 +663,14 @@ static int acpi_freeze_prepare(void)  	acpi_os_wait_events_complete();  	if (acpi_sci_irq_valid())  		enable_irq_wake(acpi_sci_irq); -  	return 0;  } -static void acpi_freeze_wake(void) -{ -	/* -	 * If IRQD_WAKEUP_ARMED is not set for the SCI at this point, it means -	 * that the SCI has triggered while suspended, so cancel the wakeup in -	 * case it has not been a wakeup event (the GPEs will be checked later). -	 */ -	if (acpi_sci_irq_valid() && -	    !irqd_is_wakeup_armed(irq_get_irq_data(acpi_sci_irq))) -		pm_system_cancel_wakeup(); -} - -static void acpi_freeze_sync(void) -{ -	/* -	 * Process all pending events in case there are any wakeup ones. -	 * -	 * The EC driver uses the system workqueue, so that one needs to be -	 * flushed too. -	 */ -	acpi_os_wait_events_complete(); -	flush_scheduled_work(); -} -  static void acpi_freeze_restore(void)  {  	acpi_disable_wakeup_devices(ACPI_STATE_S0);  	if (acpi_sci_irq_valid())  		disable_irq_wake(acpi_sci_irq); -  	acpi_enable_all_runtime_gpes();  } @@ -708,8 +682,6 @@ static void acpi_freeze_end(void)  static const struct platform_freeze_ops acpi_freeze_ops = {  	.begin = acpi_freeze_begin,  	.prepare = acpi_freeze_prepare, -	.wake = acpi_freeze_wake, -	.sync = acpi_freeze_sync,  	.restore = acpi_freeze_restore,  	.end = acpi_freeze_end,  }; diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index e987a6f55d36..9faee1c893e5 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -1091,6 +1091,11 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a  	if (async_error)  		goto Complete; +	if (pm_wakeup_pending()) { +		async_error = -EBUSY; +		goto Complete; +	} +  	if (dev->power.syscore || dev->power.direct_complete)  		goto Complete; diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 9c36b27996fc..c313b600d356 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -28,8 +28,8 @@ bool events_check_enabled __read_mostly;  /* First wakeup IRQ seen by the kernel in the last cycle. */  unsigned int pm_wakeup_irq __read_mostly; -/* If greater than 0 and the system is suspending, terminate the suspend. */ -static atomic_t pm_abort_suspend __read_mostly; +/* If set and the system is suspending, terminate the suspend. */ +static bool pm_abort_suspend __read_mostly;  /*   * Combined counters of registered wakeup events and wakeup events in progress. @@ -855,26 +855,20 @@ bool pm_wakeup_pending(void)  		pm_print_active_wakeup_sources();  	} -	return ret || atomic_read(&pm_abort_suspend) > 0; +	return ret || pm_abort_suspend;  }  void pm_system_wakeup(void)  { -	atomic_inc(&pm_abort_suspend); +	pm_abort_suspend = true;  	freeze_wake();  }  EXPORT_SYMBOL_GPL(pm_system_wakeup); -void pm_system_cancel_wakeup(void) -{ -	atomic_dec(&pm_abort_suspend); -} - -void pm_wakeup_clear(bool reset) +void pm_wakeup_clear(void)  { +	pm_abort_suspend = false;  	pm_wakeup_irq = 0; -	if (reset) -		atomic_set(&pm_abort_suspend, 0);  }  void pm_system_irq_wakeup(unsigned int irq_number) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 28d932906f24..ebbd0c3fe0ed 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -608,6 +608,9 @@ static int loop_switch(struct loop_device *lo, struct file *file)   */  static int loop_flush(struct loop_device *lo)  { +	/* loop not yet configured, no running thread, nothing to flush */ +	if (lo->lo_state != Lo_bound) +		return 0;  	return loop_switch(lo, NULL);  } diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 6e0cbe092220..593a8818aca9 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -343,7 +343,7 @@ static int mmap_mem(struct file *file, struct vm_area_struct *vma)  	phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;  	/* It's illegal to wrap around the end of the physical address space. */ -	if (offset + (phys_addr_t)size < offset) +	if (offset + (phys_addr_t)size - 1 < offset)  		return -EINVAL;  	if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size)) diff --git a/drivers/char/random.c b/drivers/char/random.c index a561f0c2f428..e870f329db88 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1,6 +1,9 @@  /*   * random.c -- A strong random number generator   * + * Copyright (C) 2017 Jason A. Donenfeld <Jason@zx2c4.com>. All + * Rights Reserved. + *   * Copyright Matt Mackall <mpm@selenic.com>, 2003, 2004, 2005   *   * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999.  All @@ -762,6 +765,8 @@ static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait);  static struct crng_state **crng_node_pool __read_mostly;  #endif +static void invalidate_batched_entropy(void); +  static void crng_initialize(struct crng_state *crng)  {  	int		i; @@ -799,6 +804,7 @@ static int crng_fast_load(const char *cp, size_t len)  		cp++; crng_init_cnt++; len--;  	}  	if (crng_init_cnt >= CRNG_INIT_CNT_THRESH) { +		invalidate_batched_entropy();  		crng_init = 1;  		wake_up_interruptible(&crng_init_wait);  		pr_notice("random: fast init done\n"); @@ -836,6 +842,7 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r)  	memzero_explicit(&buf, sizeof(buf));  	crng->init_time = jiffies;  	if (crng == &primary_crng && crng_init < 2) { +		invalidate_batched_entropy();  		crng_init = 2;  		process_random_ready_list();  		wake_up_interruptible(&crng_init_wait); @@ -1097,15 +1104,15 @@ static void add_interrupt_bench(cycles_t start)  static __u32 get_reg(struct fast_pool *f, struct pt_regs *regs)  {  	__u32 *ptr = (__u32 *) regs; -	unsigned long flags; +	unsigned int idx;  	if (regs == NULL)  		return 0; -	local_irq_save(flags); -	if (f->reg_idx >= sizeof(struct pt_regs) / sizeof(__u32)) -		f->reg_idx = 0; -	ptr += f->reg_idx++; -	local_irq_restore(flags); +	idx = READ_ONCE(f->reg_idx); +	if (idx >= sizeof(struct pt_regs) / sizeof(__u32)) +		idx = 0; +	ptr += idx++; +	WRITE_ONCE(f->reg_idx, idx);  	return *ptr;  } @@ -2023,6 +2030,7 @@ struct batched_entropy {  	};  	unsigned int position;  }; +static rwlock_t batched_entropy_reset_lock = __RW_LOCK_UNLOCKED(batched_entropy_reset_lock);  /*   * Get a random word for internal kernel use only. The quality of the random @@ -2033,6 +2041,8 @@ static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64);  u64 get_random_u64(void)  {  	u64 ret; +	bool use_lock = crng_init < 2; +	unsigned long flags;  	struct batched_entropy *batch;  #if BITS_PER_LONG == 64 @@ -2045,11 +2055,15 @@ u64 get_random_u64(void)  #endif  	batch = &get_cpu_var(batched_entropy_u64); +	if (use_lock) +		read_lock_irqsave(&batched_entropy_reset_lock, flags);  	if (batch->position % ARRAY_SIZE(batch->entropy_u64) == 0) {  		extract_crng((u8 *)batch->entropy_u64);  		batch->position = 0;  	}  	ret = batch->entropy_u64[batch->position++]; +	if (use_lock) +		read_unlock_irqrestore(&batched_entropy_reset_lock, flags);  	put_cpu_var(batched_entropy_u64);  	return ret;  } @@ -2059,22 +2073,45 @@ static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u32);  u32 get_random_u32(void)  {  	u32 ret; +	bool use_lock = crng_init < 2; +	unsigned long flags;  	struct batched_entropy *batch;  	if (arch_get_random_int(&ret))  		return ret;  	batch = &get_cpu_var(batched_entropy_u32); +	if (use_lock) +		read_lock_irqsave(&batched_entropy_reset_lock, flags);  	if (batch->position % ARRAY_SIZE(batch->entropy_u32) == 0) {  		extract_crng((u8 *)batch->entropy_u32);  		batch->position = 0;  	}  	ret = batch->entropy_u32[batch->position++]; +	if (use_lock) +		read_unlock_irqrestore(&batched_entropy_reset_lock, flags);  	put_cpu_var(batched_entropy_u32);  	return ret;  }  EXPORT_SYMBOL(get_random_u32); +/* It's important to invalidate all potential batched entropy that might + * be stored before the crng is initialized, which we can do lazily by + * simply resetting the counter to zero so that it's re-extracted on the + * next usage. */ +static void invalidate_batched_entropy(void) +{ +	int cpu; +	unsigned long flags; + +	write_lock_irqsave(&batched_entropy_reset_lock, flags); +	for_each_possible_cpu (cpu) { +		per_cpu_ptr(&batched_entropy_u32, cpu)->position = 0; +		per_cpu_ptr(&batched_entropy_u64, cpu)->position = 0; +	} +	write_unlock_irqrestore(&batched_entropy_reset_lock, flags); +} +  /**   * randomize_page - Generate a random, page aligned address   * @start:	The smallest acceptable address the caller will take. diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 992f7c20760f..88220ff3e1c2 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c @@ -185,8 +185,8 @@ static ssize_t store_down_threshold(struct gov_attr_set *attr_set,  	int ret;  	ret = sscanf(buf, "%u", &input); -	/* cannot be lower than 11 otherwise freq will not fall */ -	if (ret != 1 || input < 11 || input > 100 || +	/* cannot be lower than 1 otherwise freq will not fall */ +	if (ret != 1 || input < 1 || input > 100 ||  			input >= dbs_data->up_threshold)  		return -EINVAL; diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index b7de5bd76a31..eb1158532de3 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -571,9 +571,10 @@ static inline void update_turbo_state(void)  static int min_perf_pct_min(void)  {  	struct cpudata *cpu = all_cpu_data[0]; +	int turbo_pstate = cpu->pstate.turbo_pstate; -	return DIV_ROUND_UP(cpu->pstate.min_pstate * 100, -			    cpu->pstate.turbo_pstate); +	return turbo_pstate ? +		DIV_ROUND_UP(cpu->pstate.min_pstate * 100, turbo_pstate) : 0;  }  static s16 intel_pstate_get_epb(struct cpudata *cpu_data) diff --git a/drivers/cpuidle/dt_idle_states.c b/drivers/cpuidle/dt_idle_states.c index ffca4fc0061d..ae8eb0359889 100644 --- a/drivers/cpuidle/dt_idle_states.c +++ b/drivers/cpuidle/dt_idle_states.c @@ -180,8 +180,10 @@ int dt_init_idle_driver(struct cpuidle_driver *drv,  		if (!state_node)  			break; -		if (!of_device_is_available(state_node)) +		if (!of_device_is_available(state_node)) { +			of_node_put(state_node);  			continue; +		}  		if (!idle_state_valid(state_node, i, cpumask)) {  			pr_warn("%s idle state not valid, bailing out\n", diff --git a/drivers/dax/super.c b/drivers/dax/super.c index 6ed32aac8bbe..922d0823f8ec 100644 --- a/drivers/dax/super.c +++ b/drivers/dax/super.c @@ -210,9 +210,12 @@ EXPORT_SYMBOL_GPL(kill_dax);  static struct inode *dax_alloc_inode(struct super_block *sb)  {  	struct dax_device *dax_dev; +	struct inode *inode;  	dax_dev = kmem_cache_alloc(dax_cache, GFP_KERNEL); -	return &dax_dev->inode; +	inode = &dax_dev->inode; +	inode->i_rdev = 0; +	return inode;  }  static struct dax_device *to_dax_dev(struct inode *inode) @@ -227,7 +230,8 @@ static void dax_i_callback(struct rcu_head *head)  	kfree(dax_dev->host);  	dax_dev->host = NULL; -	ida_simple_remove(&dax_minor_ida, MINOR(inode->i_rdev)); +	if (inode->i_rdev) +		ida_simple_remove(&dax_minor_ida, MINOR(inode->i_rdev));  	kmem_cache_free(dax_cache, dax_dev);  } @@ -423,6 +427,7 @@ static void init_once(void *_dax_dev)  	struct dax_device *dax_dev = _dax_dev;  	struct inode *inode = &dax_dev->inode; +	memset(dax_dev, 0, sizeof(*dax_dev));  	inode_init_once(inode);  } diff --git a/drivers/devfreq/event/exynos-nocp.c b/drivers/devfreq/event/exynos-nocp.c index 5c3e7b11e8a6..f6e7956fc91a 100644 --- a/drivers/devfreq/event/exynos-nocp.c +++ b/drivers/devfreq/event/exynos-nocp.c @@ -267,7 +267,11 @@ static int exynos_nocp_probe(struct platform_device *pdev)  	}  	platform_set_drvdata(pdev, nocp); -	clk_prepare_enable(nocp->clk); +	ret = clk_prepare_enable(nocp->clk); +	if (ret) { +		dev_err(&pdev->dev, "failed to prepare ppmu clock\n"); +		return ret; +	}  	pr_info("exynos-nocp: new NoC Probe device registered: %s\n",  			dev_name(dev)); diff --git a/drivers/devfreq/event/exynos-ppmu.c b/drivers/devfreq/event/exynos-ppmu.c index 9b7350935b73..d96e3dc71cf8 100644 --- a/drivers/devfreq/event/exynos-ppmu.c +++ b/drivers/devfreq/event/exynos-ppmu.c @@ -44,7 +44,7 @@ struct exynos_ppmu {  	{ "ppmu-event2-"#name, PPMU_PMNCNT2 },	\  	{ "ppmu-event3-"#name, PPMU_PMNCNT3 } -struct __exynos_ppmu_events { +static struct __exynos_ppmu_events {  	char *name;  	int id;  } ppmu_events[] = { @@ -648,7 +648,11 @@ static int exynos_ppmu_probe(struct platform_device *pdev)  			dev_name(&pdev->dev), desc[i].name);  	} -	clk_prepare_enable(info->ppmu.clk); +	ret = clk_prepare_enable(info->ppmu.clk); +	if (ret) { +		dev_err(&pdev->dev, "failed to prepare ppmu clock\n"); +		return ret; +	}  	return 0;  } diff --git a/drivers/firmware/efi/efi-bgrt.c b/drivers/firmware/efi/efi-bgrt.c index 8bf27323f7a3..b58233e4ed71 100644 --- a/drivers/firmware/efi/efi-bgrt.c +++ b/drivers/firmware/efi/efi-bgrt.c @@ -27,6 +27,26 @@ struct bmp_header {  	u32 size;  } __packed; +static bool efi_bgrt_addr_valid(u64 addr) +{ +	efi_memory_desc_t *md; + +	for_each_efi_memory_desc(md) { +		u64 size; +		u64 end; + +		if (md->type != EFI_BOOT_SERVICES_DATA) +			continue; + +		size = md->num_pages << EFI_PAGE_SHIFT; +		end = md->phys_addr + size; +		if (addr >= md->phys_addr && addr < end) +			return true; +	} + +	return false; +} +  void __init efi_bgrt_init(struct acpi_table_header *table)  {  	void *image; @@ -36,7 +56,7 @@ void __init efi_bgrt_init(struct acpi_table_header *table)  	if (acpi_disabled)  		return; -	if (!efi_enabled(EFI_BOOT)) +	if (!efi_enabled(EFI_MEMMAP))  		return;  	if (table->length < sizeof(bgrt_tab)) { @@ -65,6 +85,10 @@ void __init efi_bgrt_init(struct acpi_table_header *table)  		goto out;  	} +	if (!efi_bgrt_addr_valid(bgrt->image_address)) { +		pr_notice("Ignoring BGRT: invalid image address\n"); +		goto out; +	}  	image = early_memremap(bgrt->image_address, sizeof(bmp_header));  	if (!image) {  		pr_notice("Ignoring BGRT: failed to map image header memory\n"); diff --git a/drivers/firmware/google/vpd.c b/drivers/firmware/google/vpd.c index 1e7860f02f4f..31058d400bda 100644 --- a/drivers/firmware/google/vpd.c +++ b/drivers/firmware/google/vpd.c @@ -136,12 +136,12 @@ static int vpd_section_attrib_add(const u8 *key, s32 key_len,  	info->value = value;  	INIT_LIST_HEAD(&info->list); -	list_add_tail(&info->list, &sec->attribs);  	ret = sysfs_create_bin_file(sec->kobj, &info->bin_attr);  	if (ret)  		goto free_info_key; +	list_add_tail(&info->list, &sec->attribs);  	return 0;  free_info_key: @@ -158,8 +158,8 @@ static void vpd_section_attrib_destroy(struct vpd_section *sec)  	struct vpd_attrib_info *temp;  	list_for_each_entry_safe(info, temp, &sec->attribs, list) { -		kfree(info->key);  		sysfs_remove_bin_file(sec->kobj, &info->bin_attr); +		kfree(info->key);  		kfree(info);  	}  } @@ -244,7 +244,7 @@ static int vpd_section_destroy(struct vpd_section *sec)  {  	if (sec->enabled) {  		vpd_section_attrib_destroy(sec); -		kobject_del(sec->kobj); +		kobject_put(sec->kobj);  		sysfs_remove_bin_file(vpd_kobj, &sec->bin_attr);  		kfree(sec->raw_name);  		iounmap(sec->baseaddr); @@ -331,7 +331,7 @@ static void __exit vpd_platform_exit(void)  {  	vpd_section_destroy(&ro_vpd);  	vpd_section_destroy(&rw_vpd); -	kobject_del(vpd_kobj); +	kobject_put(vpd_kobj);  }  module_init(vpd_platform_init); diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c index ccea609676ee..4ca436e66bdb 100644 --- a/drivers/gpio/gpio-aspeed.c +++ b/drivers/gpio/gpio-aspeed.c @@ -646,6 +646,9 @@ static int enable_debounce(struct gpio_chip *chip, unsigned int offset,  	int rc;  	int i; +	if (!gpio->clk) +		return -EINVAL; +  	rc = usecs_to_cycles(gpio, usecs, &requested_cycles);  	if (rc < 0) {  		dev_warn(chip->parent, "Failed to convert %luus to cycles at %luHz: %d\n", diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c index 2197368cc899..e60156ec0c18 100644 --- a/drivers/gpio/gpio-crystalcove.c +++ b/drivers/gpio/gpio-crystalcove.c @@ -90,8 +90,18 @@ static inline int to_reg(int gpio, enum ctrl_register reg_type)  {  	int reg; -	if (gpio == 94) -		return GPIOPANELCTL; +	if (gpio >= CRYSTALCOVE_GPIO_NUM) { +		/* +		 * Virtual GPIO called from ACPI, for now we only support +		 * the panel ctl. +		 */ +		switch (gpio) { +		case 0x5e: +			return GPIOPANELCTL; +		default: +			return -EOPNOTSUPP; +		} +	}  	if (reg_type == CTRL_IN) {  		if (gpio < 8) @@ -130,36 +140,36 @@ static void crystalcove_update_irq_ctrl(struct crystalcove_gpio *cg, int gpio)  static int crystalcove_gpio_dir_in(struct gpio_chip *chip, unsigned gpio)  {  	struct crystalcove_gpio *cg = gpiochip_get_data(chip); +	int reg = to_reg(gpio, CTRL_OUT); -	if (gpio > CRYSTALCOVE_VGPIO_NUM) +	if (reg < 0)  		return 0; -	return regmap_write(cg->regmap, to_reg(gpio, CTRL_OUT), -			    CTLO_INPUT_SET); +	return regmap_write(cg->regmap, reg, CTLO_INPUT_SET);  }  static int crystalcove_gpio_dir_out(struct gpio_chip *chip, unsigned gpio,  				    int value)  {  	struct crystalcove_gpio *cg = gpiochip_get_data(chip); +	int reg = to_reg(gpio, CTRL_OUT); -	if (gpio > CRYSTALCOVE_VGPIO_NUM) +	if (reg < 0)  		return 0; -	return regmap_write(cg->regmap, to_reg(gpio, CTRL_OUT), -			    CTLO_OUTPUT_SET | value); +	return regmap_write(cg->regmap, reg, CTLO_OUTPUT_SET | value);  }  static int crystalcove_gpio_get(struct gpio_chip *chip, unsigned gpio)  {  	struct crystalcove_gpio *cg = gpiochip_get_data(chip); -	int ret;  	unsigned int val; +	int ret, reg = to_reg(gpio, CTRL_IN); -	if (gpio > CRYSTALCOVE_VGPIO_NUM) +	if (reg < 0)  		return 0; -	ret = regmap_read(cg->regmap, to_reg(gpio, CTRL_IN), &val); +	ret = regmap_read(cg->regmap, reg, &val);  	if (ret)  		return ret; @@ -170,14 +180,15 @@ static void crystalcove_gpio_set(struct gpio_chip *chip,  				 unsigned gpio, int value)  {  	struct crystalcove_gpio *cg = gpiochip_get_data(chip); +	int reg = to_reg(gpio, CTRL_OUT); -	if (gpio > CRYSTALCOVE_VGPIO_NUM) +	if (reg < 0)  		return;  	if (value) -		regmap_update_bits(cg->regmap, to_reg(gpio, CTRL_OUT), 1, 1); +		regmap_update_bits(cg->regmap, reg, 1, 1);  	else -		regmap_update_bits(cg->regmap, to_reg(gpio, CTRL_OUT), 1, 0); +		regmap_update_bits(cg->regmap, reg, 1, 0);  }  static int crystalcove_irq_type(struct irq_data *data, unsigned type) @@ -185,6 +196,9 @@ static int crystalcove_irq_type(struct irq_data *data, unsigned type)  	struct crystalcove_gpio *cg =  		gpiochip_get_data(irq_data_get_irq_chip_data(data)); +	if (data->hwirq >= CRYSTALCOVE_GPIO_NUM) +		return 0; +  	switch (type) {  	case IRQ_TYPE_NONE:  		cg->intcnt_value = CTLI_INTCNT_DIS; @@ -235,8 +249,10 @@ static void crystalcove_irq_unmask(struct irq_data *data)  	struct crystalcove_gpio *cg =  		gpiochip_get_data(irq_data_get_irq_chip_data(data)); -	cg->set_irq_mask = false; -	cg->update |= UPDATE_IRQ_MASK; +	if (data->hwirq < CRYSTALCOVE_GPIO_NUM) { +		cg->set_irq_mask = false; +		cg->update |= UPDATE_IRQ_MASK; +	}  }  static void crystalcove_irq_mask(struct irq_data *data) @@ -244,8 +260,10 @@ static void crystalcove_irq_mask(struct irq_data *data)  	struct crystalcove_gpio *cg =  		gpiochip_get_data(irq_data_get_irq_chip_data(data)); -	cg->set_irq_mask = true; -	cg->update |= UPDATE_IRQ_MASK; +	if (data->hwirq < CRYSTALCOVE_GPIO_NUM) { +		cg->set_irq_mask = true; +		cg->update |= UPDATE_IRQ_MASK; +	}  }  static struct irq_chip crystalcove_irqchip = { diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index 19a92efabbef..5104b6398139 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -747,7 +747,7 @@ static int mvebu_pwm_probe(struct platform_device *pdev,  		set = U32_MAX;  	else  		return -EINVAL; -	writel_relaxed(0, mvebu_gpioreg_blink_counter_select(mvchip)); +	writel_relaxed(set, mvebu_gpioreg_blink_counter_select(mvchip));  	mvpwm = devm_kzalloc(dev, sizeof(struct mvebu_pwm), GFP_KERNEL);  	if (!mvpwm) @@ -768,6 +768,13 @@ static int mvebu_pwm_probe(struct platform_device *pdev,  	mvpwm->chip.dev = dev;  	mvpwm->chip.ops = &mvebu_pwm_ops;  	mvpwm->chip.npwm = mvchip->chip.ngpio; +	/* +	 * There may already be some PWM allocated, so we can't force +	 * mvpwm->chip.base to a fixed point like mvchip->chip.base. +	 * So, we let pwmchip_add() do the numbering and take the next free +	 * region. +	 */ +	mvpwm->chip.base = -1;  	spin_lock_init(&mvpwm->lock); diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 8be9719284b0..aa885a614e27 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -508,6 +508,8 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,  		bool has_connectors =  			!!new_crtc_state->connector_mask; +		WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); +  		if (!drm_mode_equal(&old_crtc_state->mode, &new_crtc_state->mode)) {  			DRM_DEBUG_ATOMIC("[CRTC:%d:%s] mode changed\n",  					 crtc->base.id, crtc->name); @@ -551,6 +553,8 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,  	for_each_oldnew_connector_in_state(state, connector, old_connector_state, new_connector_state, i) {  		const struct drm_connector_helper_funcs *funcs = connector->helper_private; +		WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); +  		/*  		 * This only sets crtc->connectors_changed for routing changes,  		 * drivers must set crtc->connectors_changed themselves when @@ -650,6 +654,8 @@ drm_atomic_helper_check_planes(struct drm_device *dev,  	for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {  		const struct drm_plane_helper_funcs *funcs; +		WARN_ON(!drm_modeset_is_locked(&plane->mutex)); +  		funcs = plane->helper_private;  		drm_atomic_helper_plane_changed(state, old_plane_state, new_plane_state, plane); @@ -2663,7 +2669,12 @@ int drm_atomic_helper_resume(struct drm_device *dev,  	drm_modeset_acquire_init(&ctx, 0);  	while (1) { +		err = drm_modeset_lock_all_ctx(dev, &ctx); +		if (err) +			goto out; +  		err = drm_atomic_helper_commit_duplicated_state(state, &ctx); +out:  		if (err != -EDEADLK)  			break; diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index b5c6bb46a425..37b8ad3e30d8 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -358,7 +358,12 @@ EXPORT_SYMBOL(drm_put_dev);  void drm_unplug_dev(struct drm_device *dev)  {  	/* for a USB device */ -	drm_dev_unregister(dev); +	if (drm_core_check_feature(dev, DRIVER_MODESET)) +		drm_modeset_unregister_all(dev); + +	drm_minor_unregister(dev, DRM_MINOR_PRIMARY); +	drm_minor_unregister(dev, DRM_MINOR_RENDER); +	drm_minor_unregister(dev, DRM_MINOR_CONTROL);  	mutex_lock(&drm_global_mutex); diff --git a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c index 5abc69c9630f..f77dcfaade6c 100644 --- a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c +++ b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c @@ -760,7 +760,7 @@ static int dsi_parse_dt(struct platform_device *pdev, struct dw_dsi *dsi)  	 * Get the endpoint node. In our case, dsi has one output port1  	 * to which the external HDMI bridge is connected.  	 */ -	ret = drm_of_find_panel_or_bridge(np, 0, 0, NULL, &dsi->bridge); +	ret = drm_of_find_panel_or_bridge(np, 1, 0, NULL, &dsi->bridge);  	if (ret)  		return ret; diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index c994fe6e65b2..48428672fc6e 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1235,6 +1235,15 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent)  		goto out_fini;  	pci_set_drvdata(pdev, &dev_priv->drm); +	/* +	 * Disable the system suspend direct complete optimization, which can +	 * leave the device suspended skipping the driver's suspend handlers +	 * if the device was already runtime suspended. This is needed due to +	 * the difference in our runtime and system suspend sequence and +	 * becaue the HDA driver may require us to enable the audio power +	 * domain during system suspend. +	 */ +	pdev->dev_flags |= PCI_DEV_FLAGS_NEEDS_RESUME;  	ret = i915_driver_init_early(dev_priv, ent);  	if (ret < 0) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 963f6d4481f7..2c453a4e97d5 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2991,6 +2991,16 @@ static inline bool intel_scanout_needs_vtd_wa(struct drm_i915_private *dev_priv)  	return false;  } +static inline bool +intel_ggtt_update_needs_vtd_wa(struct drm_i915_private *dev_priv) +{ +#ifdef CONFIG_INTEL_IOMMU +	if (IS_BROXTON(dev_priv) && intel_iommu_gfx_mapped) +		return true; +#endif +	return false; +} +  int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv,  				int enable_ppgtt); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b6ac3df18b58..462031cbd77f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3298,6 +3298,10 @@ int i915_gem_wait_for_idle(struct drm_i915_private *i915, unsigned int flags)  {  	int ret; +	/* If the device is asleep, we have no requests outstanding */ +	if (!READ_ONCE(i915->gt.awake)) +		return 0; +  	if (flags & I915_WAIT_LOCKED) {  		struct i915_gem_timeline *tl; diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 50b8f1139ff9..f1989b8792dd 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -2191,6 +2191,101 @@ static void gen8_ggtt_clear_range(struct i915_address_space *vm,  		gen8_set_pte(>t_base[i], scratch_pte);  } +static void bxt_vtd_ggtt_wa(struct i915_address_space *vm) +{ +	struct drm_i915_private *dev_priv = vm->i915; + +	/* +	 * Make sure the internal GAM fifo has been cleared of all GTT +	 * writes before exiting stop_machine(). This guarantees that +	 * any aperture accesses waiting to start in another process +	 * cannot back up behind the GTT writes causing a hang. +	 * The register can be any arbitrary GAM register. +	 */ +	POSTING_READ(GFX_FLSH_CNTL_GEN6); +} + +struct insert_page { +	struct i915_address_space *vm; +	dma_addr_t addr; +	u64 offset; +	enum i915_cache_level level; +}; + +static int bxt_vtd_ggtt_insert_page__cb(void *_arg) +{ +	struct insert_page *arg = _arg; + +	gen8_ggtt_insert_page(arg->vm, arg->addr, arg->offset, arg->level, 0); +	bxt_vtd_ggtt_wa(arg->vm); + +	return 0; +} + +static void bxt_vtd_ggtt_insert_page__BKL(struct i915_address_space *vm, +					  dma_addr_t addr, +					  u64 offset, +					  enum i915_cache_level level, +					  u32 unused) +{ +	struct insert_page arg = { vm, addr, offset, level }; + +	stop_machine(bxt_vtd_ggtt_insert_page__cb, &arg, NULL); +} + +struct insert_entries { +	struct i915_address_space *vm; +	struct sg_table *st; +	u64 start; +	enum i915_cache_level level; +}; + +static int bxt_vtd_ggtt_insert_entries__cb(void *_arg) +{ +	struct insert_entries *arg = _arg; + +	gen8_ggtt_insert_entries(arg->vm, arg->st, arg->start, arg->level, 0); +	bxt_vtd_ggtt_wa(arg->vm); + +	return 0; +} + +static void bxt_vtd_ggtt_insert_entries__BKL(struct i915_address_space *vm, +					     struct sg_table *st, +					     u64 start, +					     enum i915_cache_level level, +					     u32 unused) +{ +	struct insert_entries arg = { vm, st, start, level }; + +	stop_machine(bxt_vtd_ggtt_insert_entries__cb, &arg, NULL); +} + +struct clear_range { +	struct i915_address_space *vm; +	u64 start; +	u64 length; +}; + +static int bxt_vtd_ggtt_clear_range__cb(void *_arg) +{ +	struct clear_range *arg = _arg; + +	gen8_ggtt_clear_range(arg->vm, arg->start, arg->length); +	bxt_vtd_ggtt_wa(arg->vm); + +	return 0; +} + +static void bxt_vtd_ggtt_clear_range__BKL(struct i915_address_space *vm, +					  u64 start, +					  u64 length) +{ +	struct clear_range arg = { vm, start, length }; + +	stop_machine(bxt_vtd_ggtt_clear_range__cb, &arg, NULL); +} +  static void gen6_ggtt_clear_range(struct i915_address_space *vm,  				  u64 start, u64 length)  { @@ -2785,6 +2880,14 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)  	ggtt->base.insert_entries = gen8_ggtt_insert_entries; +	/* Serialize GTT updates with aperture access on BXT if VT-d is on. */ +	if (intel_ggtt_update_needs_vtd_wa(dev_priv)) { +		ggtt->base.insert_entries = bxt_vtd_ggtt_insert_entries__BKL; +		ggtt->base.insert_page    = bxt_vtd_ggtt_insert_page__BKL; +		if (ggtt->base.clear_range != nop_clear_range) +			ggtt->base.clear_range = bxt_vtd_ggtt_clear_range__BKL; +	} +  	ggtt->invalidate = gen6_ggtt_invalidate;  	return ggtt_probe_common(ggtt, size); @@ -2997,7 +3100,8 @@ void i915_ggtt_enable_guc(struct drm_i915_private *i915)  void i915_ggtt_disable_guc(struct drm_i915_private *i915)  { -	i915->ggtt.invalidate = gen6_ggtt_invalidate; +	if (i915->ggtt.invalidate == guc_ggtt_invalidate) +		i915->ggtt.invalidate = gen6_ggtt_invalidate;  }  void i915_gem_restore_gtt_mappings(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index a0d6d4317a49..fb5231f98c0d 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -278,7 +278,7 @@ i915_gem_object_set_tiling(struct drm_i915_gem_object *obj,  			obj->mm.quirked = false;  		}  		if (!i915_gem_object_is_tiled(obj)) { -			GEM_BUG_ON(!obj->mm.quirked); +			GEM_BUG_ON(obj->mm.quirked);  			__i915_gem_object_pin_pages(obj);  			obj->mm.quirked = true;  		} diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index f87b0c4e564d..1a78363c7f4a 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -208,7 +208,7 @@ static const struct intel_device_info intel_ironlake_d_info = {  static const struct intel_device_info intel_ironlake_m_info = {  	GEN5_FEATURES,  	.platform = INTEL_IRONLAKE, -	.is_mobile = 1, +	.is_mobile = 1, .has_fbc = 1,  };  #define GEN6_FEATURES \ @@ -390,7 +390,6 @@ static const struct intel_device_info intel_skylake_gt3_info = {  	.has_hw_contexts = 1, \  	.has_logical_ring_contexts = 1, \  	.has_guc = 1, \ -	.has_decoupled_mmio = 1, \  	.has_aliasing_ppgtt = 1, \  	.has_full_ppgtt = 1, \  	.has_full_48bit_ppgtt = 1, \ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3cabe52a4e3b..569717a12723 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12203,6 +12203,15 @@ static void update_scanline_offset(struct intel_crtc *crtc)  	 * type. For DP ports it behaves like most other platforms, but on HDMI  	 * there's an extra 1 line difference. So we need to add two instead of  	 * one to the value. +	 * +	 * On VLV/CHV DSI the scanline counter would appear to increment +	 * approx. 1/3 of a scanline before start of vblank. Unfortunately +	 * that means we can't tell whether we're in vblank or not while +	 * we're on that particular line. We must still set scanline_offset +	 * to 1 so that the vblank timestamps come out correct when we query +	 * the scanline counter from within the vblank interrupt handler. +	 * However if queried just before the start of vblank we'll get an +	 * answer that's slightly in the future.  	 */  	if (IS_GEN2(dev_priv)) {  		const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 854e8e0c836b..f94eacff196c 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -1075,6 +1075,22 @@ int intel_ring_workarounds_emit(struct drm_i915_gem_request *req)  	return 0;  } +static bool ring_is_idle(struct intel_engine_cs *engine) +{ +	struct drm_i915_private *dev_priv = engine->i915; +	bool idle = true; + +	intel_runtime_pm_get(dev_priv); + +	/* No bit for gen2, so assume the CS parser is idle */ +	if (INTEL_GEN(dev_priv) > 2 && !(I915_READ_MODE(engine) & MODE_IDLE)) +		idle = false; + +	intel_runtime_pm_put(dev_priv); + +	return idle; +} +  /**   * intel_engine_is_idle() - Report if the engine has finished process all work   * @engine: the intel_engine_cs @@ -1084,8 +1100,6 @@ int intel_ring_workarounds_emit(struct drm_i915_gem_request *req)   */  bool intel_engine_is_idle(struct intel_engine_cs *engine)  { -	struct drm_i915_private *dev_priv = engine->i915; -  	/* Any inflight/incomplete requests? */  	if (!i915_seqno_passed(intel_engine_get_seqno(engine),  			       intel_engine_last_submit(engine))) @@ -1100,7 +1114,7 @@ bool intel_engine_is_idle(struct intel_engine_cs *engine)  		return false;  	/* Ring stopped? */ -	if (INTEL_GEN(dev_priv) > 2 && !(I915_READ_MODE(engine) & MODE_IDLE)) +	if (!ring_is_idle(engine))  		return false;  	return true; diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index ded2add18b26..d93c58410bff 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -82,20 +82,10 @@ static unsigned int get_crtc_fence_y_offset(struct intel_crtc *crtc)  static void intel_fbc_get_plane_source_size(struct intel_fbc_state_cache *cache,  					    int *width, int *height)  { -	int w, h; - -	if (drm_rotation_90_or_270(cache->plane.rotation)) { -		w = cache->plane.src_h; -		h = cache->plane.src_w; -	} else { -		w = cache->plane.src_w; -		h = cache->plane.src_h; -	} -  	if (width) -		*width = w; +		*width = cache->plane.src_w;  	if (height) -		*height = h; +		*height = cache->plane.src_h;  }  static int intel_fbc_calculate_cfb_size(struct drm_i915_private *dev_priv, @@ -746,6 +736,11 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc,  		cache->crtc.hsw_bdw_pixel_rate = crtc_state->pixel_rate;  	cache->plane.rotation = plane_state->base.rotation; +	/* +	 * Src coordinates are already rotated by 270 degrees for +	 * the 90/270 degree plane rotation cases (to match the +	 * GTT mapping), hence no need to account for rotation here. +	 */  	cache->plane.src_w = drm_rect_width(&plane_state->base.src) >> 16;  	cache->plane.src_h = drm_rect_height(&plane_state->base.src) >> 16;  	cache->plane.visible = plane_state->base.visible; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 570bd603f401..2ca481b5aa69 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4335,11 +4335,19 @@ skl_compute_wm(struct drm_atomic_state *state)  	struct drm_crtc_state *cstate;  	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);  	struct skl_wm_values *results = &intel_state->wm_results; +	struct drm_device *dev = state->dev;  	struct skl_pipe_wm *pipe_wm;  	bool changed = false;  	int ret, i;  	/* +	 * When we distrust bios wm we always need to recompute to set the +	 * expected DDB allocations for each CRTC. +	 */ +	if (to_i915(dev)->wm.distrust_bios_wm) +		changed = true; + +	/*  	 * If this transaction isn't actually touching any CRTC's, don't  	 * bother with watermark calculation.  Note that if we pass this  	 * test, we're guaranteed to hold at least one CRTC state mutex, @@ -4349,6 +4357,7 @@ skl_compute_wm(struct drm_atomic_state *state)  	 */  	for_each_new_crtc_in_state(state, crtc, cstate, i)  		changed = true; +  	if (!changed)  		return 0; diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index c3780d0d2baf..559f1ab42bfc 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -435,8 +435,9 @@ static bool intel_psr_match_conditions(struct intel_dp *intel_dp)  	}  	/* PSR2 is restricted to work with panel resolutions upto 3200x2000 */ -	if (intel_crtc->config->pipe_src_w > 3200 || -				intel_crtc->config->pipe_src_h > 2000) { +	if (dev_priv->psr.psr2_support && +	    (intel_crtc->config->pipe_src_w > 3200 || +	     intel_crtc->config->pipe_src_h > 2000)) {  		dev_priv->psr.psr2_support = false;  		return false;  	} diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 8c87c717c7cd..e6517edcd16b 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -83,10 +83,13 @@ int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,   */  void intel_pipe_update_start(struct intel_crtc *crtc)  { +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);  	const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;  	long timeout = msecs_to_jiffies_timeout(1);  	int scanline, min, max, vblank_start;  	wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base); +	bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && +		intel_crtc_has_type(crtc->config, INTEL_OUTPUT_DSI);  	DEFINE_WAIT(wait);  	vblank_start = adjusted_mode->crtc_vblank_start; @@ -139,6 +142,24 @@ void intel_pipe_update_start(struct intel_crtc *crtc)  	drm_crtc_vblank_put(&crtc->base); +	/* +	 * On VLV/CHV DSI the scanline counter would appear to +	 * increment approx. 1/3 of a scanline before start of vblank. +	 * The registers still get latched at start of vblank however. +	 * This means we must not write any registers on the first +	 * line of vblank (since not the whole line is actually in +	 * vblank). And unfortunately we can't use the interrupt to +	 * wait here since it will fire too soon. We could use the +	 * frame start interrupt instead since it will fire after the +	 * critical scanline, but that would require more changes +	 * in the interrupt code. So for now we'll just do the nasty +	 * thing and poll for the bad scanline to pass us by. +	 * +	 * FIXME figure out if BXT+ DSI suffers from this as well +	 */ +	while (need_vlv_dsi_wa && scanline == vblank_start) +		scanline = intel_get_crtc_scanline(crtc); +  	crtc->debug.scanline_start = scanline;  	crtc->debug.start_vbl_time = ktime_get();  	crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc); diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h index 4b7f73aeddac..f84115261ae7 100644 --- a/drivers/gpu/drm/i915/intel_uc.h +++ b/drivers/gpu/drm/i915/intel_uc.h @@ -59,8 +59,6 @@ struct drm_i915_gem_request;   *                available in the work queue (note, the queue is shared,   *                not per-engine). It is OK for this to be nonzero, but   *                it should not be huge! - *   q_fail: failed to enqueue a work item. This should never happen, - *           because we check for space beforehand.   *   b_fail: failed to ring the doorbell. This should never happen, unless   *           somehow the hardware misbehaves, or maybe if the GuC firmware   *           crashes? We probably need to reset the GPU to recover. diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index 8fb801fab039..8b05ecb8fdef 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c @@ -673,7 +673,7 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)  		ret = drm_of_find_panel_or_bridge(child,  						  imx_ldb->lvds_mux ? 4 : 2, 0,  						  &channel->panel, &channel->bridge); -		if (ret) +		if (ret && ret != -ENODEV)  			return ret;  		/* panel ddc only if there is no bridge */ diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index 808b995a990f..b5cc6e12334c 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -19,6 +19,7 @@  #include <drm/drm_of.h>  #include <linux/clk.h>  #include <linux/component.h> +#include <linux/iopoll.h>  #include <linux/irq.h>  #include <linux/of.h>  #include <linux/of_platform.h> @@ -900,16 +901,12 @@ static int mtk_dsi_host_detach(struct mipi_dsi_host *host,  static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)  { -	u32 timeout_ms = 500000; /* total 1s ~ 2s timeout */ - -	while (timeout_ms--) { -		if (!(readl(dsi->regs + DSI_INTSTA) & DSI_BUSY)) -			break; - -		usleep_range(2, 4); -	} +	int ret; +	u32 val; -	if (timeout_ms == 0) { +	ret = readl_poll_timeout(dsi->regs + DSI_INTSTA, val, !(val & DSI_BUSY), +				 4, 2000000); +	if (ret) {  		DRM_WARN("polling dsi wait not busy timeout!\n");  		mtk_dsi_enable(dsi); diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c index 41a1c03b0347..0a4ffd724146 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c @@ -1062,7 +1062,7 @@ static int mtk_hdmi_setup_vendor_specific_infoframe(struct mtk_hdmi *hdmi,  	}  	err = hdmi_vendor_infoframe_pack(&frame, buffer, sizeof(buffer)); -	if (err) { +	if (err < 0) {  		dev_err(hdmi->dev, "Failed to pack vendor infoframe: %zd\n",  			err);  		return err; diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 75382f5f0fce..10b227d83e9a 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -152,7 +152,7 @@ static struct regmap_config meson_regmap_config = {  	.max_register   = 0x1000,  }; -static int meson_drv_bind(struct device *dev) +static int meson_drv_bind_master(struct device *dev, bool has_components)  {  	struct platform_device *pdev = to_platform_device(dev);  	struct meson_drm *priv; @@ -233,10 +233,12 @@ static int meson_drv_bind(struct device *dev)  	if (ret)  		goto free_drm; -	ret = component_bind_all(drm->dev, drm); -	if (ret) { -		dev_err(drm->dev, "Couldn't bind all components\n"); -		goto free_drm; +	if (has_components) { +		ret = component_bind_all(drm->dev, drm); +		if (ret) { +			dev_err(drm->dev, "Couldn't bind all components\n"); +			goto free_drm; +		}  	}  	ret = meson_plane_create(priv); @@ -276,6 +278,11 @@ free_drm:  	return ret;  } +static int meson_drv_bind(struct device *dev) +{ +	return meson_drv_bind_master(dev, true); +} +  static void meson_drv_unbind(struct device *dev)  {  	struct drm_device *drm = dev_get_drvdata(dev); @@ -357,6 +364,9 @@ static int meson_drv_probe(struct platform_device *pdev)  		count += meson_probe_remote(pdev, &match, np, remote);  	} +	if (count && !match) +		return meson_drv_bind_master(&pdev->dev, false); +  	/* If some endpoints were found, initialize the nodes */  	if (count) {  		dev_info(&pdev->dev, "Queued %d outputs on vpu\n", count); diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/timer.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/timer.h index 6a567fe347b3..820a4805916f 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/timer.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/timer.h @@ -4,6 +4,7 @@  struct nvkm_alarm {  	struct list_head head; +	struct list_head exec;  	u64 timestamp;  	void (*func)(struct nvkm_alarm *);  }; diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 36268e1802b5..15a13d09d431 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -80,7 +80,7 @@ int nouveau_modeset = -1;  module_param_named(modeset, nouveau_modeset, int, 0400);  MODULE_PARM_DESC(runpm, "disable (0), force enable (1), optimus only default (-1)"); -int nouveau_runtime_pm = -1; +static int nouveau_runtime_pm = -1;  module_param_named(runpm, nouveau_runtime_pm, int, 0400);  static struct drm_driver driver_stub; @@ -495,7 +495,7 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)  	nouveau_fbcon_init(dev);  	nouveau_led_init(dev); -	if (nouveau_runtime_pm != 0) { +	if (nouveau_pmops_runtime()) {  		pm_runtime_use_autosuspend(dev->dev);  		pm_runtime_set_autosuspend_delay(dev->dev, 5000);  		pm_runtime_set_active(dev->dev); @@ -527,7 +527,7 @@ nouveau_drm_unload(struct drm_device *dev)  {  	struct nouveau_drm *drm = nouveau_drm(dev); -	if (nouveau_runtime_pm != 0) { +	if (nouveau_pmops_runtime()) {  		pm_runtime_get_sync(dev->dev);  		pm_runtime_forbid(dev->dev);  	} @@ -726,6 +726,14 @@ nouveau_pmops_thaw(struct device *dev)  	return nouveau_do_resume(drm_dev, false);  } +bool +nouveau_pmops_runtime() +{ +	if (nouveau_runtime_pm == -1) +		return nouveau_is_optimus() || nouveau_is_v1_dsm(); +	return nouveau_runtime_pm == 1; +} +  static int  nouveau_pmops_runtime_suspend(struct device *dev)  { @@ -733,14 +741,7 @@ nouveau_pmops_runtime_suspend(struct device *dev)  	struct drm_device *drm_dev = pci_get_drvdata(pdev);  	int ret; -	if (nouveau_runtime_pm == 0) { -		pm_runtime_forbid(dev); -		return -EBUSY; -	} - -	/* are we optimus enabled? */ -	if (nouveau_runtime_pm == -1 && !nouveau_is_optimus() && !nouveau_is_v1_dsm()) { -		DRM_DEBUG_DRIVER("failing to power off - not optimus\n"); +	if (!nouveau_pmops_runtime()) {  		pm_runtime_forbid(dev);  		return -EBUSY;  	} @@ -765,8 +766,10 @@ nouveau_pmops_runtime_resume(struct device *dev)  	struct nvif_device *device = &nouveau_drm(drm_dev)->client.device;  	int ret; -	if (nouveau_runtime_pm == 0) -		return -EINVAL; +	if (!nouveau_pmops_runtime()) { +		pm_runtime_forbid(dev); +		return -EBUSY; +	}  	pci_set_power_state(pdev, PCI_D0);  	pci_restore_state(pdev); @@ -796,14 +799,7 @@ nouveau_pmops_runtime_idle(struct device *dev)  	struct nouveau_drm *drm = nouveau_drm(drm_dev);  	struct drm_crtc *crtc; -	if (nouveau_runtime_pm == 0) { -		pm_runtime_forbid(dev); -		return -EBUSY; -	} - -	/* are we optimus enabled? */ -	if (nouveau_runtime_pm == -1 && !nouveau_is_optimus() && !nouveau_is_v1_dsm()) { -		DRM_DEBUG_DRIVER("failing to power off - not optimus\n"); +	if (!nouveau_pmops_runtime()) {  		pm_runtime_forbid(dev);  		return -EBUSY;  	} diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index eadec2f49ad3..a11b6aaed325 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -108,8 +108,6 @@ nouveau_cli(struct drm_file *fpriv)  #include <nvif/object.h>  #include <nvif/device.h> -extern int nouveau_runtime_pm; -  struct nouveau_drm {  	struct nouveau_cli client;  	struct drm_device *dev; @@ -195,6 +193,7 @@ nouveau_drm(struct drm_device *dev)  int nouveau_pmops_suspend(struct device *);  int nouveau_pmops_resume(struct device *); +bool nouveau_pmops_runtime(void);  #include <nvkm/core/tegra.h> diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c index a4aacbc0cec8..02fe0efb9e16 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vga.c +++ b/drivers/gpu/drm/nouveau/nouveau_vga.c @@ -87,7 +87,7 @@ void  nouveau_vga_init(struct nouveau_drm *drm)  {  	struct drm_device *dev = drm->dev; -	bool runtime = false; +	bool runtime = nouveau_pmops_runtime();  	/* only relevant for PCI devices */  	if (!dev->pdev) @@ -99,10 +99,6 @@ nouveau_vga_init(struct nouveau_drm *drm)  	if (pci_is_thunderbolt_attached(dev->pdev))  		return; -	if (nouveau_runtime_pm == 1) -		runtime = true; -	if ((nouveau_runtime_pm == -1) && (nouveau_is_optimus() || nouveau_is_v1_dsm())) -		runtime = true;  	vga_switcheroo_register_client(dev->pdev, &nouveau_switcheroo_ops, runtime);  	if (runtime && nouveau_is_v1_dsm() && !nouveau_is_optimus()) @@ -113,18 +109,13 @@ void  nouveau_vga_fini(struct nouveau_drm *drm)  {  	struct drm_device *dev = drm->dev; -	bool runtime = false; +	bool runtime = nouveau_pmops_runtime();  	vga_client_register(dev->pdev, NULL, NULL, NULL);  	if (pci_is_thunderbolt_attached(dev->pdev))  		return; -	if (nouveau_runtime_pm == 1) -		runtime = true; -	if ((nouveau_runtime_pm == -1) && (nouveau_is_optimus() || nouveau_is_v1_dsm())) -		runtime = true; -  	vga_switcheroo_unregister_client(dev->pdev);  	if (runtime && nouveau_is_v1_dsm() && !nouveau_is_optimus())  		vga_switcheroo_fini_domain_pm_ops(drm->dev->dev); diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index a7663249b3ba..06e564a9ccb2 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -2107,7 +2107,8 @@ nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state)  					asyc->set.dither = true;  			}  		} else { -			asyc->set.mask = ~0; +			if (asyc) +				asyc->set.mask = ~0;  			asyh->set.mask = ~0;  		} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c index f2a86eae0a0d..2437f7d41ca2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c @@ -50,7 +50,8 @@ nvkm_timer_alarm_trigger(struct nvkm_timer *tmr)  		/* Move to completed list.  We'll drop the lock before  		 * executing the callback so it can reschedule itself.  		 */ -		list_move_tail(&alarm->head, &exec); +		list_del_init(&alarm->head); +		list_add(&alarm->exec, &exec);  	}  	/* Shut down interrupt if no more pending alarms. */ @@ -59,8 +60,8 @@ nvkm_timer_alarm_trigger(struct nvkm_timer *tmr)  	spin_unlock_irqrestore(&tmr->lock, flags);  	/* Execute completed callbacks. */ -	list_for_each_entry_safe(alarm, atemp, &exec, head) { -		list_del_init(&alarm->head); +	list_for_each_entry_safe(alarm, atemp, &exec, exec) { +		list_del(&alarm->exec);  		alarm->func(alarm);  	}  } diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index d8fa7a9c9240..ce5f2d1f9994 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -245,8 +245,6 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder,  				      struct drm_connector_state *conn_state)  {  	struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); -	struct rockchip_dp_device *dp = to_dp(encoder); -	int ret;  	/*  	 * The hardware IC designed that VOP must output the RGB10 video @@ -258,16 +256,6 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder,  	s->output_mode = ROCKCHIP_OUT_MODE_AAAA;  	s->output_type = DRM_MODE_CONNECTOR_eDP; -	if (dp->data->chip_type == RK3399_EDP) { -		/* -		 * For RK3399, VOP Lit must code the out mode to RGB888, -		 * VOP Big must code the out mode to RGB10. -		 */ -		ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, -							encoder); -		if (ret > 0) -			s->output_mode = ROCKCHIP_OUT_MODE_P888; -	}  	return 0;  } diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c index a2169dd3d26b..14fa1f8351e8 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c @@ -615,7 +615,6 @@ static void cdn_dp_encoder_enable(struct drm_encoder *encoder)  {  	struct cdn_dp_device *dp = encoder_to_dp(encoder);  	int ret, val; -	struct rockchip_crtc_state *state;  	ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder);  	if (ret < 0) { @@ -625,14 +624,10 @@ static void cdn_dp_encoder_enable(struct drm_encoder *encoder)  	DRM_DEV_DEBUG_KMS(dp->dev, "vop %s output to cdn-dp\n",  			  (ret) ? "LIT" : "BIG"); -	state = to_rockchip_crtc_state(encoder->crtc->state); -	if (ret) { +	if (ret)  		val = DP_SEL_VOP_LIT | (DP_SEL_VOP_LIT << 16); -		state->output_mode = ROCKCHIP_OUT_MODE_P888; -	} else { +	else  		val = DP_SEL_VOP_LIT << 16; -		state->output_mode = ROCKCHIP_OUT_MODE_AAAA; -	}  	ret = cdn_dp_grf_write(dp, GRF_SOC_CON9, val);  	if (ret) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 3f7a82d1e095..45589d6ce65e 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -875,6 +875,7 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,  static void vop_crtc_enable(struct drm_crtc *crtc)  {  	struct vop *vop = to_vop(crtc); +	const struct vop_data *vop_data = vop->data;  	struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);  	struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;  	u16 hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start; @@ -967,6 +968,13 @@ static void vop_crtc_enable(struct drm_crtc *crtc)  		DRM_DEV_ERROR(vop->dev, "unsupported connector_type [%d]\n",  			      s->output_type);  	} + +	/* +	 * if vop is not support RGB10 output, need force RGB10 to RGB888. +	 */ +	if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA && +	    !(vop_data->feature & VOP_FEATURE_OUTPUT_RGB10)) +		s->output_mode = ROCKCHIP_OUT_MODE_P888;  	VOP_CTRL_SET(vop, out_mode, s->output_mode);  	VOP_CTRL_SET(vop, htotal_pw, (htotal << 16) | hsync_len); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h index 5a4faa85dbd2..9979fd0c2282 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h @@ -142,6 +142,9 @@ struct vop_data {  	const struct vop_intr *intr;  	const struct vop_win_data *win;  	unsigned int win_size; + +#define VOP_FEATURE_OUTPUT_RGB10	BIT(0) +	u64 feature;  };  /* interrupt define */ diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index 0da44442aab0..bafd698a28b1 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -275,6 +275,7 @@ static const struct vop_intr rk3288_vop_intr = {  static const struct vop_data rk3288_vop = {  	.init_table = rk3288_init_reg_table,  	.table_size = ARRAY_SIZE(rk3288_init_reg_table), +	.feature = VOP_FEATURE_OUTPUT_RGB10,  	.intr = &rk3288_vop_intr,  	.ctrl = &rk3288_ctrl_data,  	.win = rk3288_vop_win_data, @@ -343,6 +344,7 @@ static const struct vop_reg_data rk3399_init_reg_table[] = {  static const struct vop_data rk3399_vop_big = {  	.init_table = rk3399_init_reg_table,  	.table_size = ARRAY_SIZE(rk3399_init_reg_table), +	.feature = VOP_FEATURE_OUTPUT_RGB10,  	.intr = &rk3399_vop_intr,  	.ctrl = &rk3399_ctrl_data,  	/* diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 130d51c5ec6a..4b948fba9eec 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -41,9 +41,9 @@  #include <drm/ttm/ttm_module.h>  #include "vmwgfx_fence.h" -#define VMWGFX_DRIVER_DATE "20170221" +#define VMWGFX_DRIVER_DATE "20170607"  #define VMWGFX_DRIVER_MAJOR 2 -#define VMWGFX_DRIVER_MINOR 12 +#define VMWGFX_DRIVER_MINOR 13  #define VMWGFX_DRIVER_PATCHLEVEL 0  #define VMWGFX_FILE_PAGE_OFFSET 0x00100000  #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c index b6a0806b06bf..a1c68e6a689e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c @@ -368,6 +368,8 @@ static void *vmw_local_fifo_reserve(struct vmw_private *dev_priv,  				return fifo_state->static_buffer;  			else {  				fifo_state->dynamic_buffer = vmalloc(bytes); +				if (!fifo_state->dynamic_buffer) +					goto out_err;  				return fifo_state->dynamic_buffer;  			}  		} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index ef9f3a2a4030..1d2db5d912b0 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -274,108 +274,6 @@ void vmw_kms_cursor_post_execbuf(struct vmw_private *dev_priv)  } - -/** - * vmw_du_cursor_plane_update() - Update cursor image and location - * - * @plane: plane object to update - * @crtc: owning CRTC of @plane - * @fb: framebuffer to flip onto plane - * @crtc_x: x offset of plane on crtc - * @crtc_y: y offset of plane on crtc - * @crtc_w: width of plane rectangle on crtc - * @crtc_h: height of plane rectangle on crtc - * @src_x: Not used - * @src_y: Not used - * @src_w: Not used - * @src_h: Not used - * - * - * RETURNS: - * Zero on success, error code on failure - */ -int vmw_du_cursor_plane_update(struct drm_plane *plane, -			       struct drm_crtc *crtc, -			       struct drm_framebuffer *fb, -			       int crtc_x, int crtc_y, -			       unsigned int crtc_w, -			       unsigned int crtc_h, -			       uint32_t src_x, uint32_t src_y, -			       uint32_t src_w, uint32_t src_h) -{ -	struct vmw_private *dev_priv = vmw_priv(crtc->dev); -	struct vmw_display_unit *du = vmw_crtc_to_du(crtc); -	struct vmw_surface *surface = NULL; -	struct vmw_dma_buffer *dmabuf = NULL; -	s32 hotspot_x, hotspot_y; -	int ret; - -	hotspot_x = du->hotspot_x + fb->hot_x; -	hotspot_y = du->hotspot_y + fb->hot_y; - -	/* A lot of the code assumes this */ -	if (crtc_w != 64 || crtc_h != 64) { -		ret = -EINVAL; -		goto out; -	} - -	if (vmw_framebuffer_to_vfb(fb)->dmabuf) -		dmabuf = vmw_framebuffer_to_vfbd(fb)->buffer; -	else -		surface = vmw_framebuffer_to_vfbs(fb)->surface; - -	if (surface && !surface->snooper.image) { -		DRM_ERROR("surface not suitable for cursor\n"); -		ret = -EINVAL; -		goto out; -	} - -	/* setup new image */ -	ret = 0; -	if (surface) { -		/* vmw_user_surface_lookup takes one reference */ -		du->cursor_surface = surface; - -		du->cursor_age = du->cursor_surface->snooper.age; - -		ret = vmw_cursor_update_image(dev_priv, surface->snooper.image, -					      64, 64, hotspot_x, hotspot_y); -	} else if (dmabuf) { -		/* vmw_user_surface_lookup takes one reference */ -		du->cursor_dmabuf = dmabuf; - -		ret = vmw_cursor_update_dmabuf(dev_priv, dmabuf, crtc_w, crtc_h, -					       hotspot_x, hotspot_y); -	} else { -		vmw_cursor_update_position(dev_priv, false, 0, 0); -		goto out; -	} - -	if (!ret) { -		du->cursor_x = crtc_x + du->set_gui_x; -		du->cursor_y = crtc_y + du->set_gui_y; - -		vmw_cursor_update_position(dev_priv, true, -					   du->cursor_x + hotspot_x, -					   du->cursor_y + hotspot_y); -	} - -out: -	return ret; -} - - -int vmw_du_cursor_plane_disable(struct drm_plane *plane) -{ -	if (plane->fb) { -		drm_framebuffer_unreference(plane->fb); -		plane->fb = NULL; -	} - -	return -EINVAL; -} - -  void vmw_du_cursor_plane_destroy(struct drm_plane *plane)  {  	vmw_cursor_update_position(plane->dev->dev_private, false, 0, 0); @@ -473,18 +371,6 @@ vmw_du_cursor_plane_prepare_fb(struct drm_plane *plane,  void -vmw_du_cursor_plane_atomic_disable(struct drm_plane *plane, -				   struct drm_plane_state *old_state) -{ -	struct drm_crtc *crtc = plane->state->crtc ?: old_state->crtc; -	struct vmw_private *dev_priv = vmw_priv(crtc->dev); - -	drm_atomic_set_fb_for_plane(plane->state, NULL); -	vmw_cursor_update_position(dev_priv, false, 0, 0); -} - - -void  vmw_du_cursor_plane_atomic_update(struct drm_plane *plane,  				  struct drm_plane_state *old_state)  { @@ -1498,6 +1384,7 @@ vmw_kms_new_framebuffer(struct vmw_private *dev_priv,  	 */  	if (vmw_kms_srf_ok(dev_priv, mode_cmd->width, mode_cmd->height)  &&  	    dmabuf && only_2d && +	    mode_cmd->width > 64 &&  /* Don't create a proxy for cursor */  	    dev_priv->active_display_unit == vmw_du_screen_target) {  		ret = vmw_create_dmabuf_proxy(dev_priv->dev, mode_cmd,  					      dmabuf, &surface); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index 13f2f1d2818a..5f8d678ae675 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h @@ -256,10 +256,6 @@ int vmw_du_crtc_gamma_set(struct drm_crtc *crtc,  			   u16 *r, u16 *g, u16 *b,  			   uint32_t size,  			   struct drm_modeset_acquire_ctx *ctx); -int vmw_du_crtc_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv, -			    uint32_t handle, uint32_t width, uint32_t height, -			    int32_t hot_x, int32_t hot_y); -int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y);  int vmw_du_connector_set_property(struct drm_connector *connector,  				  struct drm_property *property,  				  uint64_t val); @@ -339,15 +335,6 @@ void vmw_kms_create_implicit_placement_property(struct vmw_private *dev_priv,  /* Universal Plane Helpers */  void vmw_du_primary_plane_destroy(struct drm_plane *plane);  void vmw_du_cursor_plane_destroy(struct drm_plane *plane); -int vmw_du_cursor_plane_disable(struct drm_plane *plane); -int vmw_du_cursor_plane_update(struct drm_plane *plane, -			       struct drm_crtc *crtc, -			       struct drm_framebuffer *fb, -			       int crtc_x, int crtc_y, -			       unsigned int crtc_w, -			       unsigned int crtc_h, -			       uint32_t src_x, uint32_t src_y, -			       uint32_t src_w, uint32_t src_h);  /* Atomic Helpers */  int vmw_du_primary_plane_atomic_check(struct drm_plane *plane, @@ -356,8 +343,6 @@ int vmw_du_cursor_plane_atomic_check(struct drm_plane *plane,  				     struct drm_plane_state *state);  void vmw_du_cursor_plane_atomic_update(struct drm_plane *plane,  				       struct drm_plane_state *old_state); -void vmw_du_cursor_plane_atomic_disable(struct drm_plane *plane, -					struct drm_plane_state *old_state);  int vmw_du_cursor_plane_prepare_fb(struct drm_plane *plane,  				   struct drm_plane_state *new_state);  void vmw_du_plane_cleanup_fb(struct drm_plane *plane, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index bad31bdf09b6..50be1f034f9e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -56,6 +56,8 @@ enum stdu_content_type {   * @right: Right side of bounding box.   * @top: Top side of bounding box.   * @bottom: Bottom side of bounding box. + * @fb_left: Left side of the framebuffer/content bounding box + * @fb_top: Top of the framebuffer/content bounding box   * @buf: DMA buffer when DMA-ing between buffer and screen targets.   * @sid: Surface ID when copying between surface and screen targets.   */ @@ -63,6 +65,7 @@ struct vmw_stdu_dirty {  	struct vmw_kms_dirty base;  	SVGA3dTransferType  transfer;  	s32 left, right, top, bottom; +	s32 fb_left, fb_top;  	u32 pitch;  	union {  		struct vmw_dma_buffer *buf; @@ -647,7 +650,7 @@ static void vmw_stdu_dmabuf_fifo_commit(struct vmw_kms_dirty *dirty)   *   * @dirty: The closure structure.   * - * This function calculates the bounding box for all the incoming clips + * This function calculates the bounding box for all the incoming clips.   */  static void vmw_stdu_dmabuf_cpu_clip(struct vmw_kms_dirty *dirty)  { @@ -656,11 +659,19 @@ static void vmw_stdu_dmabuf_cpu_clip(struct vmw_kms_dirty *dirty)  	dirty->num_hits = 1; -	/* Calculate bounding box */ +	/* Calculate destination bounding box */  	ddirty->left = min_t(s32, ddirty->left, dirty->unit_x1);  	ddirty->top = min_t(s32, ddirty->top, dirty->unit_y1);  	ddirty->right = max_t(s32, ddirty->right, dirty->unit_x2);  	ddirty->bottom = max_t(s32, ddirty->bottom, dirty->unit_y2); + +	/* +	 * Calculate content bounding box.  We only need the top-left +	 * coordinate because width and height will be the same as the +	 * destination bounding box above +	 */ +	ddirty->fb_left = min_t(s32, ddirty->fb_left, dirty->fb_x); +	ddirty->fb_top  = min_t(s32, ddirty->fb_top, dirty->fb_y);  } @@ -697,11 +708,11 @@ static void vmw_stdu_dmabuf_cpu_commit(struct vmw_kms_dirty *dirty)  	/* Assume we are blitting from Host (display_srf) to Guest (dmabuf) */  	src_pitch = stdu->display_srf->base_size.width * stdu->cpp;  	src = ttm_kmap_obj_virtual(&stdu->host_map, ¬_used); -	src += dirty->unit_y1 * src_pitch + dirty->unit_x1 * stdu->cpp; +	src += ddirty->top * src_pitch + ddirty->left * stdu->cpp;  	dst_pitch = ddirty->pitch;  	dst = ttm_kmap_obj_virtual(&stdu->guest_map, ¬_used); -	dst += dirty->fb_y * dst_pitch + dirty->fb_x * stdu->cpp; +	dst += ddirty->fb_top * dst_pitch + ddirty->fb_left * stdu->cpp;  	/* Figure out the real direction */ @@ -760,7 +771,7 @@ static void vmw_stdu_dmabuf_cpu_commit(struct vmw_kms_dirty *dirty)  	}  out_cleanup: -	ddirty->left = ddirty->top = S32_MAX; +	ddirty->left = ddirty->top = ddirty->fb_left = ddirty->fb_top = S32_MAX;  	ddirty->right = ddirty->bottom = S32_MIN;  } @@ -812,6 +823,7 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv,  		SVGA3D_READ_HOST_VRAM;  	ddirty.left = ddirty.top = S32_MAX;  	ddirty.right = ddirty.bottom = S32_MIN; +	ddirty.fb_left = ddirty.fb_top = S32_MAX;  	ddirty.pitch = vfb->base.pitches[0];  	ddirty.buf = buf;  	ddirty.base.fifo_commit = vmw_stdu_dmabuf_fifo_commit; @@ -1355,6 +1367,11 @@ vmw_stdu_primary_plane_atomic_update(struct drm_plane *plane,  		DRM_ERROR("Failed to bind surface to STDU.\n");  	else  		crtc->primary->fb = plane->state->fb; + +	ret = vmw_stdu_update_st(dev_priv, stdu); + +	if (ret) +		DRM_ERROR("Failed to update STDU.\n");  } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index 7681341fe32b..6b70bd259953 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c @@ -1274,11 +1274,14 @@ int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data,  	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;  	int ret;  	uint32_t size; -	uint32_t backup_handle; +	uint32_t backup_handle = 0;  	if (req->multisample_count != 0)  		return -EINVAL; +	if (req->mip_levels > DRM_VMW_MAX_MIP_LEVELS) +		return -EINVAL; +  	if (unlikely(vmw_user_surface_size == 0))  		vmw_user_surface_size = ttm_round_pot(sizeof(*user_srf)) +  			128; @@ -1314,12 +1317,16 @@ int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data,  		ret = vmw_user_dmabuf_lookup(tfile, req->buffer_handle,  					     &res->backup,  					     &user_srf->backup_base); -		if (ret == 0 && res->backup->base.num_pages * PAGE_SIZE < -		    res->backup_size) { -			DRM_ERROR("Surface backup buffer is too small.\n"); -			vmw_dmabuf_unreference(&res->backup); -			ret = -EINVAL; -			goto out_unlock; +		if (ret == 0) { +			if (res->backup->base.num_pages * PAGE_SIZE < +			    res->backup_size) { +				DRM_ERROR("Surface backup buffer is too small.\n"); +				vmw_dmabuf_unreference(&res->backup); +				ret = -EINVAL; +				goto out_unlock; +			} else { +				backup_handle = req->buffer_handle; +			}  		}  	} else if (req->drm_surface_flags & drm_vmw_surface_flag_create_buffer)  		ret = vmw_user_dmabuf_alloc(dev_priv, tfile, @@ -1491,7 +1498,7 @@ int vmw_surface_gb_priv_define(struct drm_device *dev,  				 dev_priv->stdu_max_height);  		if (size.width > max_width || size.height > max_height) { -			DRM_ERROR("%ux%u\n, exeeds max surface size %ux%u", +			DRM_ERROR("%ux%u\n, exceeds max surface size %ux%u",  				  size.width, size.height,  				  max_width, max_height);  			return -EINVAL; diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index 16d556816b5f..2fb5f432a54c 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c @@ -725,15 +725,16 @@ void ipu_set_ic_src_mux(struct ipu_soc *ipu, int csi_id, bool vdi)  	spin_lock_irqsave(&ipu->lock, flags);  	val = ipu_cm_read(ipu, IPU_CONF); -	if (vdi) { +	if (vdi)  		val |= IPU_CONF_IC_INPUT; -	} else { +	else  		val &= ~IPU_CONF_IC_INPUT; -		if (csi_id == 1) -			val |= IPU_CONF_CSI_SEL; -		else -			val &= ~IPU_CONF_CSI_SEL; -	} + +	if (csi_id == 1) +		val |= IPU_CONF_CSI_SEL; +	else +		val &= ~IPU_CONF_CSI_SEL; +  	ipu_cm_write(ipu, val, IPU_CONF);  	spin_unlock_irqrestore(&ipu->lock, flags); diff --git a/drivers/gpu/ipu-v3/ipu-pre.c b/drivers/gpu/ipu-v3/ipu-pre.c index c55563379e2e..c35f74c83065 100644 --- a/drivers/gpu/ipu-v3/ipu-pre.c +++ b/drivers/gpu/ipu-v3/ipu-pre.c @@ -131,8 +131,6 @@ int ipu_pre_get(struct ipu_pre *pre)  	if (pre->in_use)  		return -EBUSY; -	clk_prepare_enable(pre->clk_axi); -  	/* first get the engine out of reset and remove clock gating */  	writel(0, pre->regs + IPU_PRE_CTRL); @@ -149,12 +147,7 @@ int ipu_pre_get(struct ipu_pre *pre)  void ipu_pre_put(struct ipu_pre *pre)  { -	u32 val; - -	val = IPU_PRE_CTRL_SFTRST | IPU_PRE_CTRL_CLKGATE; -	writel(val, pre->regs + IPU_PRE_CTRL); - -	clk_disable_unprepare(pre->clk_axi); +	writel(IPU_PRE_CTRL_SFTRST, pre->regs + IPU_PRE_CTRL);  	pre->in_use = false;  } @@ -249,6 +242,8 @@ static int ipu_pre_probe(struct platform_device *pdev)  	if (!pre->buffer_virt)  		return -ENOMEM; +	clk_prepare_enable(pre->clk_axi); +  	pre->dev = dev;  	platform_set_drvdata(pdev, pre);  	mutex_lock(&ipu_pre_list_mutex); @@ -268,6 +263,8 @@ static int ipu_pre_remove(struct platform_device *pdev)  	available_pres--;  	mutex_unlock(&ipu_pre_list_mutex); +	clk_disable_unprepare(pre->clk_axi); +  	if (pre->buffer_virt)  		gen_pool_free(pre->iram, (unsigned long)pre->buffer_virt,  			      IPU_PRE_MAX_WIDTH * IPU_PRE_NUM_SCANLINES * 4); diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 04cee65531d7..6e040692f1d8 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -826,11 +826,35 @@ static int hid_scan_report(struct hid_device *hid)  				 * hid-rmi should take care of them,  				 * not hid-generic  				 */ -				if (IS_ENABLED(CONFIG_HID_RMI)) -					hid->group = HID_GROUP_RMI; +				hid->group = HID_GROUP_RMI;  		break;  	} +	/* fall back to generic driver in case specific driver doesn't exist */ +	switch (hid->group) { +	case HID_GROUP_MULTITOUCH_WIN_8: +		/* fall-through */ +	case HID_GROUP_MULTITOUCH: +		if (!IS_ENABLED(CONFIG_HID_MULTITOUCH)) +			hid->group = HID_GROUP_GENERIC; +		break; +	case HID_GROUP_SENSOR_HUB: +		if (!IS_ENABLED(CONFIG_HID_SENSOR_HUB)) +			hid->group = HID_GROUP_GENERIC; +		break; +	case HID_GROUP_RMI: +		if (!IS_ENABLED(CONFIG_HID_RMI)) +			hid->group = HID_GROUP_GENERIC; +		break; +	case HID_GROUP_WACOM: +		if (!IS_ENABLED(CONFIG_HID_WACOM)) +			hid->group = HID_GROUP_GENERIC; +		break; +	case HID_GROUP_LOGITECH_DJ_DEVICE: +		if (!IS_ENABLED(CONFIG_HID_LOGITECH_DJ)) +			hid->group = HID_GROUP_GENERIC; +		break; +	}  	vfree(parser);  	return 0;  } @@ -1763,15 +1787,23 @@ EXPORT_SYMBOL_GPL(hid_disconnect);   * used as a driver. See hid_scan_report().   */  static const struct hid_device_id hid_have_special_driver[] = { +#if IS_ENABLED(CONFIG_HID_A4TECH)  	{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) }, +#endif +#if IS_ENABLED(CONFIG_HID_ACCUTOUCH) +	{ HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_ACCUTOUCH_2216) }, +#endif +#if IS_ENABLED(CONFIG_HID_ACRUX)  	{ HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0xf705) }, +#endif +#if IS_ENABLED(CONFIG_HID_ALPS)  	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_DUAL) }, +#endif +#if IS_ENABLED(CONFIG_HID_APPLE)  	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, -	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) }, -	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) }, @@ -1792,11 +1824,6 @@ static const struct hid_device_id hid_have_special_driver[] = {  	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL2) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL3) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL5) },  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI) },  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO) },  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS) }, @@ -1851,62 +1878,100 @@ static const struct hid_device_id hid_have_special_driver[] = {  	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_ANSI) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, +#endif +#if IS_ENABLED(CONFIG_HID_APPLEIR) +	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL2) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL3) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL5) }, +#endif +#if IS_ENABLED(CONFIG_HID_ASUS)  	{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD) },  	{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD2) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T100_KEYBOARD) }, +#endif +#if IS_ENABLED(CONFIG_HID_AUREAL)  	{ HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) }, +#endif +#if IS_ENABLED(CONFIG_HID_BELKIN)  	{ HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, +#endif +#if IS_ENABLED(CONFIG_HID_BETOP_FF)  	{ HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185BFM, 0x2208) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185PC, 0x5506) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185V2PC, 0x1850) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185V2BFM, 0x5500) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) }, +#endif +#if IS_ENABLED(CONFIG_HID_CHERRY)  	{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) }, +#endif +#if IS_ENABLED(CONFIG_HID_CHICONY)  	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_AK1D) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_ACER_SWITCH12) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_JESS_ZEN_AIO_KBD) }, +#endif +#if IS_ENABLED(CONFIG_HID_CMEDIA) +	{ HID_USB_DEVICE(USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM6533) }, +#endif +#if IS_ENABLED(CONFIG_HID_CORSAIR)  	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K90) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, +#endif +#if IS_ENABLED(CONFIG_HID_CP2112)  	{ HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_CP2112) }, +#endif +#if IS_ENABLED(CONFIG_HID_CYPRESS)  	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_4) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_DELCOM, USB_DEVICE_ID_DELCOM_VISUAL_IND) }, +#endif +#if IS_ENABLED(CONFIG_HID_DRAGONRISE)  	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) }, -#if IS_ENABLED(CONFIG_HID_MAYFLASH) -	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE2) },  #endif -	{ HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, USB_DEVICE_ID_DREAM_CHEEKY_WN) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, USB_DEVICE_ID_DREAM_CHEEKY_FA) }, +#if IS_ENABLED(CONFIG_HID_ELECOM)  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRED) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRELESS) }, +#endif +#if IS_ENABLED(CONFIG_HID_ELO)  	{ HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0030) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_ACCUTOUCH_2216) }, +#endif +#if IS_ENABLED(CONFIG_HID_EMS_FF)  	{ HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) }, +#endif +#if IS_ENABLED(CONFIG_HID_EZKEY)  	{ HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, +#endif +#if IS_ENABLED(CONFIG_HID_GEMBIRD)  	{ HID_USB_DEVICE(USB_VENDOR_ID_GEMBIRD, USB_DEVICE_ID_GEMBIRD_JPD_DUALFORCE2) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) }, +#endif +#if IS_ENABLED(CONFIG_HID_GFRM) +        { HID_BLUETOOTH_DEVICE(0x58, 0x2000) }, +        { HID_BLUETOOTH_DEVICE(0x471, 0x2210) }, +#endif +#if IS_ENABLED(CONFIG_HID_GREENASIA)  	{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) }, +#endif +#if IS_ENABLED(CONFIG_HID_GT683R) +	{ HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) }, +#endif +#if IS_ENABLED(CONFIG_HID_GYRATION)  	{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, +#endif +#if IS_ENABLED(CONFIG_HID_HOLTEK)  	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) }, @@ -1915,12 +1980,17 @@ static const struct hid_device_id hid_have_special_driver[] = {  	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A0C2) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_JESS_ZEN_AIO_KBD) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) }, +#endif +#if IS_ENABLED(CONFIG_HID_ICADE)  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) }, +#endif +#if IS_ENABLED(CONFIG_HID_KENSINGTON)  	{ HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, +#endif +#if IS_ENABLED(CONFIG_HID_KEYTOUCH)  	{ HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) }, +#endif +#if IS_ENABLED(CONFIG_HID_KYE)  	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_MANTICORE) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_GX_IMPERATOR) }, @@ -1930,21 +2000,29 @@ static const struct hid_device_id hid_have_special_driver[] = {  	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_V2) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, +#endif +#if IS_ENABLED(CONFIG_HID_LCPOWER)  	{ HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, +#endif +#if IS_ENABLED(CONFIG_HID_LED) +	{ HID_USB_DEVICE(USB_VENDOR_ID_DELCOM, USB_DEVICE_ID_DELCOM_VISUAL_IND) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, USB_DEVICE_ID_DREAM_CHEEKY_WN) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, USB_DEVICE_ID_DREAM_CHEEKY_FA) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_LUXAFOR) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_RISO_KAGAKU, USB_DEVICE_ID_RI_KA_WEBMAIL) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_THINGM, USB_DEVICE_ID_BLINK1) }, +#endif  #if IS_ENABLED(CONFIG_HID_LENOVO)  	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) },  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPPRODOCK) },  #endif -	{ HID_USB_DEVICE(USB_VENDOR_ID_LG, USB_DEVICE_ID_LG_MELFAS_MT) }, +#if IS_ENABLED(CONFIG_HID_LOGITECH)  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) }, -	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) }, -	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_T651) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) }, @@ -1957,7 +2035,6 @@ static const struct hid_device_id hid_have_special_driver[] = {  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G29_WHEEL) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) }, @@ -1969,17 +2046,30 @@ static const struct hid_device_id hid_have_special_driver[] = {  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFGT_WHEEL) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL) }, -#if IS_ENABLED(CONFIG_HID_LOGITECH_DJ) -	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2) }, -#endif  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_LUXAFOR) }, +#endif +#if IS_ENABLED(CONFIG_HID_LOGITECH_HIDPP) +	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_T651) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL) }, +#endif +#if IS_ENABLED(CONFIG_HID_LOGITECH_DJ) +	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2) }, +#endif +#if IS_ENABLED(CONFIG_HID_MAGICMOUSE) +	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) }, +	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) }, +#endif +#if IS_ENABLED(CONFIG_HID_MAYFLASH) +	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE2) }, +#endif +#if IS_ENABLED(CONFIG_HID_MICROSOFT)  	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_KEYBOARD) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, @@ -1995,9 +2085,22 @@ static const struct hid_device_id hid_have_special_driver[] = {  	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_600) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3KV1) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER) }, +	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, +#endif +#if IS_ENABLED(CONFIG_HID_MONTEREY)  	{ HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) }, +#endif +#if IS_ENABLED(CONFIG_HID_MULTITOUCH) +	{ HID_USB_DEVICE(USB_VENDOR_ID_LG, USB_DEVICE_ID_LG_MELFAS_MT) }, +#endif +#if IS_ENABLED(CONFIG_HID_WIIMOTE) +	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) }, +	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE2) }, +#endif +#if IS_ENABLED(CONFIG_HID_NTI)  	{ HID_USB_DEVICE(USB_VENDOR_ID_NTI, USB_DEVICE_ID_USB_SUN) }, +#endif +#if IS_ENABLED(CONFIG_HID_NTRIG)  	{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2) }, @@ -2017,13 +2120,41 @@ static const struct hid_device_id hid_have_special_driver[] = {  	{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) }, +#endif +#if IS_ENABLED(CONFIG_HID_ORTEK)  	{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) }, +#endif +#if IS_ENABLED(CONFIG_HID_PANTHERLORD) +	{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) }, +#endif +#if IS_ENABLED(CONFIG_HID_PENMOUNT)  	{ HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_6000) }, +#endif +#if IS_ENABLED(CONFIG_HID_PETALYNX)  	{ HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, +#endif +#if IS_ENABLED(CONFIG_HID_PICOLCD) +	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) }, +#endif +#if IS_ENABLED(CONFIG_HID_PLANTRONICS)  	{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) }, +#endif +#if IS_ENABLED(CONFIG_HID_PRIMAX)  	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_RISO_KAGAKU, USB_DEVICE_ID_RI_KA_WEBMAIL) }, +#endif +#if IS_ENABLED(CONFIG_HID_PRODIKEYS) +	{ HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, +#endif +#if IS_ENABLED(CONFIG_HID_RMI) +	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_COVER) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_RAZER, USB_DEVICE_ID_RAZER_BLADE_14) }, +#endif  #if IS_ENABLED(CONFIG_HID_ROCCAT)  	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) }, @@ -2051,9 +2182,21 @@ static const struct hid_device_id hid_have_special_driver[] = {  	{ HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT5) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT9) },  #endif +#if IS_ENABLED(CONFIG_HID_SAMSUNG)  	{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) }, +#endif +#if IS_ENABLED(CONFIG_HID_SMARTJOYPLUS) +	{ HID_USB_DEVICE(USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SUPER_JOY_BOX_3) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO) }, +#endif +#if IS_ENABLED(CONFIG_HID_SONY) +	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) },  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_PS3_BDREMOTE) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) }, @@ -2072,9 +2215,17 @@ static const struct hid_device_id hid_have_special_driver[] = {  	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_SINO_LITE, USB_DEVICE_ID_SINO_LITE_CONTROLLER) }, +#endif +#if IS_ENABLED(CONFIG_HID_SPEEDLINK) +	{ HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE) }, +#endif +#if IS_ENABLED(CONFIG_HID_STEELSERIES)  	{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_SRWS1) }, +#endif +#if IS_ENABLED(CONFIG_HID_SUNPLUS)  	{ HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_THINGM, USB_DEVICE_ID_BLINK1) }, +#endif +#if IS_ENABLED(CONFIG_HID_THRUSTMASTER)  	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) }, @@ -2083,12 +2234,25 @@ static const struct hid_device_id hid_have_special_driver[] = {  	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a) }, +#endif +#if IS_ENABLED(CONFIG_HID_TIVO)  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_PRO) }, +#endif +#if IS_ENABLED(CONFIG_HID_TOPSEED) +	{ HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) }, +#endif +#if IS_ENABLED(CONFIG_HID_TWINHAN)  	{ HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) }, +#endif +#if IS_ENABLED(CONFIG_HID_UCLOGIC) +	{ HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_HUION_TABLET) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) }, @@ -2096,20 +2260,17 @@ static const struct hid_device_id hid_have_special_driver[] = {  	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP1062) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_TWHA60) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_THQ, USB_DEVICE_ID_THQ_PS3_UDRAW) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_YIYNOVA_TABLET) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UGEE_TABLET_81) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UGEE_TABLET_45) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_DRAWIMAGE_G3) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER, USB_DEVICE_ID_UGTIZER_TABLET_GP0610) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_TABLET_EX07S) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SUPER_JOY_BOX_3) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER, USB_DEVICE_ID_UGTIZER_TABLET_GP0610) }, +#endif +#if IS_ENABLED(CONFIG_HID_UDRAW_PS3) +	{ HID_USB_DEVICE(USB_VENDOR_ID_THQ, USB_DEVICE_ID_THQ_PS3_UDRAW) }, +#endif +#if IS_ENABLED(CONFIG_HID_WALTOP)  	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_Q_PAD) }, @@ -2117,19 +2278,18 @@ static const struct hid_device_id hid_have_special_driver[] = {  	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE) }, +#endif +#if IS_ENABLED(CONFIG_HID_XINMO)  	{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_THT_2P_ARCADE) }, +#endif +#if IS_ENABLED(CONFIG_HID_ZEROPLUS)  	{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, +#endif +#if IS_ENABLED(CONFIG_HID_ZYDACRON)  	{ HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) }, - -	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, -	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) }, -	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE2) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_RAZER, USB_DEVICE_ID_RAZER_BLADE_14) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM6533) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_COVER) }, +#endif  	{ }  }; diff --git a/drivers/hsi/clients/ssi_protocol.c b/drivers/hsi/clients/ssi_protocol.c index 26b05106f0d3..93d28c0ec8bf 100644 --- a/drivers/hsi/clients/ssi_protocol.c +++ b/drivers/hsi/clients/ssi_protocol.c @@ -1066,7 +1066,7 @@ static void ssip_pn_setup(struct net_device *dev)  	dev->addr_len		= 1;  	dev->tx_queue_len	= SSIP_TXQUEUE_LEN; -	dev->destructor		= free_netdev; +	dev->needs_free_netdev	= true;  	dev->header_ops		= &phonet_header_ops;  } diff --git a/drivers/iio/adc/bcm_iproc_adc.c b/drivers/iio/adc/bcm_iproc_adc.c index 21d38c8af21e..7f4f9c4150e3 100644 --- a/drivers/iio/adc/bcm_iproc_adc.c +++ b/drivers/iio/adc/bcm_iproc_adc.c @@ -143,7 +143,7 @@ static void iproc_adc_reg_dump(struct iio_dev *indio_dev)  	iproc_adc_dbg_reg(dev, adc_priv, IPROC_SOFT_BYPASS_DATA);  } -static irqreturn_t iproc_adc_interrupt_handler(int irq, void *data) +static irqreturn_t iproc_adc_interrupt_thread(int irq, void *data)  {  	u32 channel_intr_status;  	u32 intr_status; @@ -167,7 +167,7 @@ static irqreturn_t iproc_adc_interrupt_handler(int irq, void *data)  	return IRQ_NONE;  } -static irqreturn_t iproc_adc_interrupt_thread(int irq, void *data) +static irqreturn_t iproc_adc_interrupt_handler(int irq, void *data)  {  	irqreturn_t retval = IRQ_NONE;  	struct iproc_adc_priv *adc_priv; @@ -181,7 +181,7 @@ static irqreturn_t iproc_adc_interrupt_thread(int irq, void *data)  	adc_priv = iio_priv(indio_dev);  	regmap_read(adc_priv->regmap, IPROC_INTERRUPT_STATUS, &intr_status); -	dev_dbg(&indio_dev->dev, "iproc_adc_interrupt_thread(),INTRPT_STS:%x\n", +	dev_dbg(&indio_dev->dev, "iproc_adc_interrupt_handler(),INTRPT_STS:%x\n",  			intr_status);  	intr_channels = (intr_status & IPROC_ADC_INTR_MASK) >> IPROC_ADC_INTR; @@ -566,8 +566,8 @@ static int iproc_adc_probe(struct platform_device *pdev)  	}  	ret = devm_request_threaded_irq(&pdev->dev, adc_priv->irqno, -				iproc_adc_interrupt_thread,  				iproc_adc_interrupt_handler, +				iproc_adc_interrupt_thread,  				IRQF_SHARED, "iproc-adc", indio_dev);  	if (ret) {  		dev_err(&pdev->dev, "request_irq error %d\n", ret); diff --git a/drivers/iio/adc/max9611.c b/drivers/iio/adc/max9611.c index ec82106480e1..b0526e4b9530 100644 --- a/drivers/iio/adc/max9611.c +++ b/drivers/iio/adc/max9611.c @@ -438,10 +438,10 @@ static ssize_t max9611_shunt_resistor_show(struct device *dev,  	struct max9611_dev *max9611 = iio_priv(dev_to_iio_dev(dev));  	unsigned int i, r; -	i = max9611->shunt_resistor_uohm / 1000; -	r = max9611->shunt_resistor_uohm % 1000; +	i = max9611->shunt_resistor_uohm / 1000000; +	r = max9611->shunt_resistor_uohm % 1000000; -	return sprintf(buf, "%u.%03u\n", i, r); +	return sprintf(buf, "%u.%06u\n", i, r);  }  static IIO_DEVICE_ATTR(in_power_shunt_resistor, 0444, @@ -536,8 +536,8 @@ static int max9611_probe(struct i2c_client *client,  	int ret;  	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*max9611)); -	if (IS_ERR(indio_dev)) -		return PTR_ERR(indio_dev); +	if (!indio_dev) +		return -ENOMEM;  	i2c_set_clientdata(client, indio_dev); diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c index b23527309088..81d4c39e414a 100644 --- a/drivers/iio/adc/sun4i-gpadc-iio.c +++ b/drivers/iio/adc/sun4i-gpadc-iio.c @@ -105,6 +105,8 @@ struct sun4i_gpadc_iio {  	bool				no_irq;  	/* prevents concurrent reads of temperature and ADC */  	struct mutex			mutex; +	struct thermal_zone_device	*tzd; +	struct device			*sensor_device;  };  #define SUN4I_GPADC_ADC_CHANNEL(_channel, _name) {		\ @@ -502,7 +504,6 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev,  {  	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);  	const struct of_device_id *of_dev; -	struct thermal_zone_device *tzd;  	struct resource *mem;  	void __iomem *base;  	int ret; @@ -532,13 +533,14 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev,  	if (!IS_ENABLED(CONFIG_THERMAL_OF))  		return 0; -	tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, info, -						   &sun4i_ts_tz_ops); -	if (IS_ERR(tzd)) +	info->sensor_device = &pdev->dev; +	info->tzd = thermal_zone_of_sensor_register(info->sensor_device, 0, +						    info, &sun4i_ts_tz_ops); +	if (IS_ERR(info->tzd))  		dev_err(&pdev->dev, "could not register thermal sensor: %ld\n", -			PTR_ERR(tzd)); +			PTR_ERR(info->tzd)); -	return PTR_ERR_OR_ZERO(tzd); +	return PTR_ERR_OR_ZERO(info->tzd);  }  static int sun4i_gpadc_probe_mfd(struct platform_device *pdev, @@ -584,15 +586,15 @@ static int sun4i_gpadc_probe_mfd(struct platform_device *pdev,  		 * of_node, and the device from this driver as third argument to  		 * return the temperature.  		 */ -		struct thermal_zone_device *tzd; -		tzd = devm_thermal_zone_of_sensor_register(pdev->dev.parent, 0, -							   info, -							   &sun4i_ts_tz_ops); -		if (IS_ERR(tzd)) { +		info->sensor_device = pdev->dev.parent; +		info->tzd = thermal_zone_of_sensor_register(info->sensor_device, +							    0, info, +							    &sun4i_ts_tz_ops); +		if (IS_ERR(info->tzd)) {  			dev_err(&pdev->dev,  				"could not register thermal sensor: %ld\n", -				PTR_ERR(tzd)); -			return PTR_ERR(tzd); +				PTR_ERR(info->tzd)); +			return PTR_ERR(info->tzd);  		}  	} else {  		indio_dev->num_channels = @@ -688,7 +690,13 @@ static int sun4i_gpadc_remove(struct platform_device *pdev)  	pm_runtime_put(&pdev->dev);  	pm_runtime_disable(&pdev->dev); -	if (!info->no_irq && IS_ENABLED(CONFIG_THERMAL_OF)) + +	if (!IS_ENABLED(CONFIG_THERMAL_OF)) +		return 0; + +	thermal_zone_of_sensor_unregister(info->sensor_device, info->tzd); + +	if (!info->no_irq)  		iio_map_array_unregister(indio_dev);  	return 0; @@ -700,6 +708,7 @@ static const struct platform_device_id sun4i_gpadc_id[] = {  	{ "sun6i-a31-gpadc-iio", (kernel_ulong_t)&sun6i_gpadc_data },  	{ /* sentinel */ },  }; +MODULE_DEVICE_TABLE(platform, sun4i_gpadc_id);  static struct platform_driver sun4i_gpadc_driver = {  	.driver = { @@ -711,6 +720,7 @@ static struct platform_driver sun4i_gpadc_driver = {  	.probe = sun4i_gpadc_probe,  	.remove = sun4i_gpadc_remove,  }; +MODULE_DEVICE_TABLE(of, sun4i_gpadc_of_id);  module_platform_driver(sun4i_gpadc_driver); diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c index 4282ceca3d8f..6cbed7eb118a 100644 --- a/drivers/iio/adc/ti_am335x_adc.c +++ b/drivers/iio/adc/ti_am335x_adc.c @@ -614,7 +614,7 @@ static int tiadc_probe(struct platform_device *pdev)  		return -EINVAL;  	} -	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*indio_dev)); +	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc_dev));  	if (indio_dev == NULL) {  		dev_err(&pdev->dev, "failed to allocate iio device\n");  		return -ENOMEM; diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index 978e1592c2a3..4061fed93f1f 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -451,7 +451,8 @@ static ssize_t iio_trigger_write_current(struct device *dev,  	return len;  out_trigger_put: -	iio_trigger_put(trig); +	if (trig) +		iio_trigger_put(trig);  	return ret;  } diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c index b30e0c1c6cc4..67838edd8b37 100644 --- a/drivers/iio/light/ltr501.c +++ b/drivers/iio/light/ltr501.c @@ -74,9 +74,9 @@ static const int int_time_mapping[] = {100000, 50000, 200000, 400000};  static const struct reg_field reg_field_it =  				REG_FIELD(LTR501_ALS_MEAS_RATE, 3, 4);  static const struct reg_field reg_field_als_intr = -				REG_FIELD(LTR501_INTR, 0, 0); -static const struct reg_field reg_field_ps_intr =  				REG_FIELD(LTR501_INTR, 1, 1); +static const struct reg_field reg_field_ps_intr = +				REG_FIELD(LTR501_INTR, 0, 0);  static const struct reg_field reg_field_als_rate =  				REG_FIELD(LTR501_ALS_MEAS_RATE, 0, 2);  static const struct reg_field reg_field_ps_rate = diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c index ddf9bee89f77..aa4df0dcc8c9 100644 --- a/drivers/iio/proximity/as3935.c +++ b/drivers/iio/proximity/as3935.c @@ -40,9 +40,9 @@  #define AS3935_AFE_PWR_BIT	BIT(0)  #define AS3935_INT		0x03 -#define AS3935_INT_MASK		0x07 +#define AS3935_INT_MASK		0x0f  #define AS3935_EVENT_INT	BIT(3) -#define AS3935_NOISE_INT	BIT(1) +#define AS3935_NOISE_INT	BIT(0)  #define AS3935_DATA		0x07  #define AS3935_DATA_MASK	0x3F @@ -215,7 +215,7 @@ static irqreturn_t as3935_trigger_handler(int irq, void *private)  	st->buffer[0] = val & AS3935_DATA_MASK;  	iio_push_to_buffers_with_timestamp(indio_dev, &st->buffer, -					   pf->timestamp); +					   iio_get_time_ns(indio_dev));  err_read:  	iio_trigger_notify_done(indio_dev->trig); @@ -244,7 +244,7 @@ static void as3935_event_work(struct work_struct *work)  	switch (val) {  	case AS3935_EVENT_INT: -		iio_trigger_poll(st->trig); +		iio_trigger_poll_chained(st->trig);  		break;  	case AS3935_NOISE_INT:  		dev_warn(&st->spi->dev, "noise level is too high\n"); @@ -269,8 +269,6 @@ static irqreturn_t as3935_interrupt_handler(int irq, void *private)  static void calibrate_as3935(struct as3935_state *st)  { -	mutex_lock(&st->lock); -  	/* mask disturber interrupt bit */  	as3935_write(st, AS3935_INT, BIT(5)); @@ -280,8 +278,6 @@ static void calibrate_as3935(struct as3935_state *st)  	mdelay(2);  	as3935_write(st, AS3935_TUNE_CAP, (st->tune_cap / TUNE_CAP_DIV)); - -	mutex_unlock(&st->lock);  }  #ifdef CONFIG_PM_SLEEP @@ -318,6 +314,8 @@ static int as3935_resume(struct device *dev)  	val &= ~AS3935_AFE_PWR_BIT;  	ret = as3935_write(st, AS3935_AFE_GAIN, val); +	calibrate_as3935(st); +  err_resume:  	mutex_unlock(&st->lock); diff --git a/drivers/infiniband/sw/rxe/rxe.h b/drivers/infiniband/sw/rxe/rxe.h index ecdba2fce083..1ac5b8551a4d 100644 --- a/drivers/infiniband/sw/rxe/rxe.h +++ b/drivers/infiniband/sw/rxe/rxe.h @@ -68,6 +68,7 @@  static inline u32 rxe_crc32(struct rxe_dev *rxe,  			    u32 crc, void *next, size_t len)  { +	u32 retval;  	int err;  	SHASH_DESC_ON_STACK(shash, rxe->tfm); @@ -81,7 +82,9 @@ static inline u32 rxe_crc32(struct rxe_dev *rxe,  		return crc32_le(crc, next, len);  	} -	return *(u32 *)shash_desc_ctx(shash); +	retval = *(u32 *)shash_desc_ctx(shash); +	barrier_data(shash_desc_ctx(shash)); +	return retval;  }  int rxe_set_mtu(struct rxe_dev *rxe, unsigned int dev_mtu); diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index e73d968023f7..f1fa1f172107 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -1118,8 +1118,10 @@ static int elantech_get_resolution_v4(struct psmouse *psmouse,   * Asus UX32VD             0x361f02        00, 15, 0e      clickpad   * Avatar AVIU-145A2       0x361f00        ?               clickpad   * Fujitsu LIFEBOOK E544   0x470f00        d0, 12, 09      2 hw buttons + * Fujitsu LIFEBOOK E546   0x470f00        50, 12, 09      2 hw buttons   * Fujitsu LIFEBOOK E547   0x470f00        50, 12, 09      2 hw buttons   * Fujitsu LIFEBOOK E554   0x570f01        40, 14, 0c      2 hw buttons + * Fujitsu LIFEBOOK E557   0x570f01        40, 14, 0c      2 hw buttons   * Fujitsu T725            0x470f01        05, 12, 09      2 hw buttons   * Fujitsu H730            0x570f00        c0, 14, 0c      3 hw buttons (**)   * Gigabyte U2442          0x450f01        58, 17, 0c      2 hw buttons @@ -1525,6 +1527,13 @@ static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = {  		},  	},  	{ +		/* Fujitsu LIFEBOOK E546  does not work with crc_enabled == 0 */ +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E546"), +		}, +	}, +	{  		/* Fujitsu LIFEBOOK E547 does not work with crc_enabled == 0 */  		.matches = {  			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), @@ -1546,6 +1555,13 @@ static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = {  		},  	},  	{ +		/* Fujitsu LIFEBOOK E557 does not work with crc_enabled == 0 */ +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E557"), +		}, +	}, +	{  		/* Fujitsu LIFEBOOK U745 does not work with crc_enabled == 0 */  		.matches = {  			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), diff --git a/drivers/input/rmi4/rmi_f03.c b/drivers/input/rmi4/rmi_f03.c index 77dad045a468..ad71a5e768dc 100644 --- a/drivers/input/rmi4/rmi_f03.c +++ b/drivers/input/rmi4/rmi_f03.c @@ -146,7 +146,7 @@ static int rmi_f03_register_pt(struct f03_data *f03)  	if (!serio)  		return -ENOMEM; -	serio->id.type = SERIO_8042; +	serio->id.type = SERIO_PS_PSTHRU;  	serio->write = rmi_f03_pt_write;  	serio->port_data = f03; diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index 9f44ee8ea1bc..19779b88a479 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -118,6 +118,7 @@ static const struct iommu_ops  	ops = iommu_ops_from_fwnode(fwnode);  	if ((ops && !ops->of_xlate) || +	    !of_device_is_available(iommu_spec->np) ||  	    (!ops && !of_iommu_driver_present(iommu_spec->np)))  		return NULL; @@ -236,6 +237,12 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,  			ops = ERR_PTR(err);  	} +	/* Ignore all other errors apart from EPROBE_DEFER */ +	if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) { +		dev_dbg(dev, "Adding to IOMMU failed: %ld\n", PTR_ERR(ops)); +		ops = NULL; +	} +  	return ops;  } diff --git a/drivers/irqchip/irq-xtensa-mx.c b/drivers/irqchip/irq-xtensa-mx.c index bb3ac5fe5846..72a391e01011 100644 --- a/drivers/irqchip/irq-xtensa-mx.c +++ b/drivers/irqchip/irq-xtensa-mx.c @@ -142,7 +142,7 @@ static struct irq_chip xtensa_mx_irq_chip = {  int __init xtensa_mx_init_legacy(struct device_node *interrupt_parent)  {  	struct irq_domain *root_domain = -		irq_domain_add_legacy(NULL, NR_IRQS, 0, 0, +		irq_domain_add_legacy(NULL, NR_IRQS - 1, 1, 0,  				&xtensa_mx_irq_domain_ops,  				&xtensa_mx_irq_chip);  	irq_set_default_host(root_domain); diff --git a/drivers/irqchip/irq-xtensa-pic.c b/drivers/irqchip/irq-xtensa-pic.c index 472ae1770964..f728755fa292 100644 --- a/drivers/irqchip/irq-xtensa-pic.c +++ b/drivers/irqchip/irq-xtensa-pic.c @@ -89,7 +89,7 @@ static struct irq_chip xtensa_irq_chip = {  int __init xtensa_pic_init_legacy(struct device_node *interrupt_parent)  {  	struct irq_domain *root_domain = -		irq_domain_add_legacy(NULL, NR_IRQS, 0, 0, +		irq_domain_add_legacy(NULL, NR_IRQS - 1, 1, 0,  				&xtensa_irq_domain_ops, &xtensa_irq_chip);  	irq_set_default_host(root_domain);  	return 0; diff --git a/drivers/md/md.c b/drivers/md/md.c index 212a6777ff31..87edc342ccb3 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -5174,6 +5174,18 @@ static void mddev_delayed_delete(struct work_struct *ws)  static void no_op(struct percpu_ref *r) {} +int mddev_init_writes_pending(struct mddev *mddev) +{ +	if (mddev->writes_pending.percpu_count_ptr) +		return 0; +	if (percpu_ref_init(&mddev->writes_pending, no_op, 0, GFP_KERNEL) < 0) +		return -ENOMEM; +	/* We want to start with the refcount at zero */ +	percpu_ref_put(&mddev->writes_pending); +	return 0; +} +EXPORT_SYMBOL_GPL(mddev_init_writes_pending); +  static int md_alloc(dev_t dev, char *name)  {  	/* @@ -5239,10 +5251,6 @@ static int md_alloc(dev_t dev, char *name)  	blk_queue_make_request(mddev->queue, md_make_request);  	blk_set_stacking_limits(&mddev->queue->limits); -	if (percpu_ref_init(&mddev->writes_pending, no_op, 0, GFP_KERNEL) < 0) -		goto abort; -	/* We want to start with the refcount at zero */ -	percpu_ref_put(&mddev->writes_pending);  	disk = alloc_disk(1 << shift);  	if (!disk) {  		blk_cleanup_queue(mddev->queue); diff --git a/drivers/md/md.h b/drivers/md/md.h index 11f15146ce51..0fa1de42c42b 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -648,6 +648,7 @@ extern void md_unregister_thread(struct md_thread **threadp);  extern void md_wakeup_thread(struct md_thread *thread);  extern void md_check_recovery(struct mddev *mddev);  extern void md_reap_sync_thread(struct mddev *mddev); +extern int mddev_init_writes_pending(struct mddev *mddev);  extern void md_write_start(struct mddev *mddev, struct bio *bi);  extern void md_write_inc(struct mddev *mddev, struct bio *bi);  extern void md_write_end(struct mddev *mddev); diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index af5056d56878..e1a7e3d4c5e4 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -3063,6 +3063,8 @@ static int raid1_run(struct mddev *mddev)  			mdname(mddev));  		return -EIO;  	} +	if (mddev_init_writes_pending(mddev) < 0) +		return -ENOMEM;  	/*  	 * copy the already verified devices into our private RAID1  	 * bookkeeping area. [whatever we allocate in run(), diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 4343d7ff9916..797ed60abd5e 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -3611,6 +3611,9 @@ static int raid10_run(struct mddev *mddev)  	int first = 1;  	bool discard_supported = false; +	if (mddev_init_writes_pending(mddev) < 0) +		return -ENOMEM; +  	if (mddev->private == NULL) {  		conf = setup_conf(mddev);  		if (IS_ERR(conf)) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 722064689e82..ec0f951ae19f 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -7118,6 +7118,9 @@ static int raid5_run(struct mddev *mddev)  	long long min_offset_diff = 0;  	int first = 1; +	if (mddev_init_writes_pending(mddev) < 0) +		return -ENOMEM; +  	if (mddev->recovery_cp != MaxSector)  		pr_notice("md/raid:%s: not clean -- starting background reconstruction\n",  			  mdname(mddev)); diff --git a/drivers/media/cec/Kconfig b/drivers/media/cec/Kconfig index 4e25a950ae6f..43428cec3a01 100644 --- a/drivers/media/cec/Kconfig +++ b/drivers/media/cec/Kconfig @@ -1,5 +1,6 @@  config MEDIA_CEC_RC  	bool "HDMI CEC RC integration"  	depends on CEC_CORE && RC_CORE +	depends on CEC_CORE=m || RC_CORE=y  	---help---  	  Pass on CEC remote control messages to the RC framework. diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c index 0860fb458757..999926f731c8 100644 --- a/drivers/media/cec/cec-api.c +++ b/drivers/media/cec/cec-api.c @@ -271,16 +271,10 @@ static long cec_receive(struct cec_adapter *adap, struct cec_fh *fh,  			bool block, struct cec_msg __user *parg)  {  	struct cec_msg msg = {}; -	long err = 0; +	long err;  	if (copy_from_user(&msg, parg, sizeof(msg)))  		return -EFAULT; -	mutex_lock(&adap->lock); -	if (!adap->is_configured && fh->mode_follower < CEC_MODE_MONITOR) -		err = -ENONET; -	mutex_unlock(&adap->lock); -	if (err) -		return err;  	err = cec_receive_msg(fh, &msg, block);  	if (err) diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index acef4eca269f..3251cba89e8f 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -223,7 +223,7 @@ static void i2c_wr8(struct v4l2_subdev *sd, u16 reg, u8 val)  static void i2c_wr8_and_or(struct v4l2_subdev *sd, u16 reg,  		u8 mask, u8 val)  { -	i2c_wrreg(sd, reg, (i2c_rdreg(sd, reg, 2) & mask) | val, 2); +	i2c_wrreg(sd, reg, (i2c_rdreg(sd, reg, 1) & mask) | val, 1);  }  static u16 i2c_rd16(struct v4l2_subdev *sd, u16 reg) diff --git a/drivers/media/rc/sir_ir.c b/drivers/media/rc/sir_ir.c index e12ec50bf0bf..90a5f8fd5eea 100644 --- a/drivers/media/rc/sir_ir.c +++ b/drivers/media/rc/sir_ir.c @@ -183,9 +183,15 @@ static irqreturn_t sir_interrupt(int irq, void *dev_id)  	static unsigned long delt;  	unsigned long deltintr;  	unsigned long flags; +	int counter = 0;  	int iir, lsr;  	while ((iir = inb(io + UART_IIR) & UART_IIR_ID)) { +		if (++counter > 256) { +			dev_err(&sir_ir_dev->dev, "Trapped in interrupt"); +			break; +		} +  		switch (iir & UART_IIR_ID) { /* FIXME toto treba preriedit */  		case UART_IIR_MSI:  			(void)inb(io + UART_MSR); diff --git a/drivers/media/usb/rainshadow-cec/rainshadow-cec.c b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c index 71bd68548c9c..4126552c9055 100644 --- a/drivers/media/usb/rainshadow-cec/rainshadow-cec.c +++ b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c @@ -336,6 +336,7 @@ static int rain_connect(struct serio *serio, struct serio_driver *drv)  	serio_set_drvdata(serio, rain);  	INIT_WORK(&rain->work, rain_irq_work_handler);  	mutex_init(&rain->write_lock); +	spin_lock_init(&rain->buf_lock);  	err = serio_open(serio, drv);  	if (err) diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 94afbbf92807..c0175ea7e7ad 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -868,7 +868,7 @@ EXPORT_SYMBOL_GPL(vb2_core_create_bufs);  void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no)  { -	if (plane_no > vb->num_planes || !vb->planes[plane_no].mem_priv) +	if (plane_no >= vb->num_planes || !vb->planes[plane_no].mem_priv)  		return NULL;  	return call_ptr_memop(vb, vaddr, vb->planes[plane_no].mem_priv); diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c index 35910f945bfa..99e644cda4d1 100644 --- a/drivers/memory/atmel-ebi.c +++ b/drivers/memory/atmel-ebi.c @@ -581,7 +581,7 @@ static int atmel_ebi_probe(struct platform_device *pdev)  	return of_platform_populate(np, NULL, NULL, dev);  } -static int atmel_ebi_resume(struct device *dev) +static __maybe_unused int atmel_ebi_resume(struct device *dev)  {  	struct atmel_ebi *ebi = dev_get_drvdata(dev);  	struct atmel_ebi_dev *ebid; diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c index 17b433f1ce23..0761271d68c5 100644 --- a/drivers/misc/cxl/file.c +++ b/drivers/misc/cxl/file.c @@ -159,11 +159,8 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,  	/* Do this outside the status_mutex to avoid a circular dependency with  	 * the locking in cxl_mmap_fault() */ -	if (copy_from_user(&work, uwork, -			   sizeof(struct cxl_ioctl_start_work))) { -		rc = -EFAULT; -		goto out; -	} +	if (copy_from_user(&work, uwork, sizeof(work))) +		return -EFAULT;  	mutex_lock(&ctx->status_mutex);  	if (ctx->status != OPENED) { diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c index 871a2f09c718..8d6ea9712dbd 100644 --- a/drivers/misc/cxl/native.c +++ b/drivers/misc/cxl/native.c @@ -1302,13 +1302,16 @@ int cxl_native_register_psl_err_irq(struct cxl *adapter)  void cxl_native_release_psl_err_irq(struct cxl *adapter)  { -	if (adapter->native->err_virq != irq_find_mapping(NULL, adapter->native->err_hwirq)) +	if (adapter->native->err_virq == 0 || +	    adapter->native->err_virq != +	    irq_find_mapping(NULL, adapter->native->err_hwirq))  		return;  	cxl_p1_write(adapter, CXL_PSL_ErrIVTE, 0x0000000000000000);  	cxl_unmap_irq(adapter->native->err_virq, adapter);  	cxl_ops->release_one_irq(adapter, adapter->native->err_hwirq);  	kfree(adapter->irq_name); +	adapter->native->err_virq = 0;  }  int cxl_native_register_serr_irq(struct cxl_afu *afu) @@ -1346,13 +1349,15 @@ int cxl_native_register_serr_irq(struct cxl_afu *afu)  void cxl_native_release_serr_irq(struct cxl_afu *afu)  { -	if (afu->serr_virq != irq_find_mapping(NULL, afu->serr_hwirq)) +	if (afu->serr_virq == 0 || +	    afu->serr_virq != irq_find_mapping(NULL, afu->serr_hwirq))  		return;  	cxl_p1n_write(afu, CXL_PSL_SERR_An, 0x0000000000000000);  	cxl_unmap_irq(afu->serr_virq, afu);  	cxl_ops->release_one_irq(afu->adapter, afu->serr_hwirq);  	kfree(afu->err_irq_name); +	afu->serr_virq = 0;  }  int cxl_native_register_psl_irq(struct cxl_afu *afu) @@ -1375,12 +1380,15 @@ int cxl_native_register_psl_irq(struct cxl_afu *afu)  void cxl_native_release_psl_irq(struct cxl_afu *afu)  { -	if (afu->native->psl_virq != irq_find_mapping(NULL, afu->native->psl_hwirq)) +	if (afu->native->psl_virq == 0 || +	    afu->native->psl_virq != +	    irq_find_mapping(NULL, afu->native->psl_hwirq))  		return;  	cxl_unmap_irq(afu->native->psl_virq, afu);  	cxl_ops->release_one_irq(afu->adapter, afu->native->psl_hwirq);  	kfree(afu->psl_irq_name); +	afu->native->psl_virq = 0;  }  static void recover_psl_err(struct cxl_afu *afu, u64 errstat) diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index d1928fdd0f43..07aad8576334 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -763,8 +763,10 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a,  {  	struct mei_cl_device *cldev = to_mei_cl_device(dev);  	const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl); +	u8 version = mei_me_cl_ver(cldev->me_cl); -	return scnprintf(buf, PAGE_SIZE, "mei:%s:%pUl:", cldev->name, uuid); +	return scnprintf(buf, PAGE_SIZE, "mei:%s:%pUl:%02X:", +			 cldev->name, uuid, version);  }  static DEVICE_ATTR_RO(modalias); diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 165a8009c640..5427032aa05e 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -90,10 +90,13 @@ enum ad_link_speed_type {  	AD_LINK_SPEED_100MBPS,  	AD_LINK_SPEED_1000MBPS,  	AD_LINK_SPEED_2500MBPS, +	AD_LINK_SPEED_5000MBPS,  	AD_LINK_SPEED_10000MBPS, +	AD_LINK_SPEED_14000MBPS,  	AD_LINK_SPEED_20000MBPS,  	AD_LINK_SPEED_25000MBPS,  	AD_LINK_SPEED_40000MBPS, +	AD_LINK_SPEED_50000MBPS,  	AD_LINK_SPEED_56000MBPS,  	AD_LINK_SPEED_100000MBPS,  }; @@ -259,10 +262,13 @@ static inline int __check_agg_selection_timer(struct port *port)   *     %AD_LINK_SPEED_100MBPS,   *     %AD_LINK_SPEED_1000MBPS,   *     %AD_LINK_SPEED_2500MBPS, + *     %AD_LINK_SPEED_5000MBPS,   *     %AD_LINK_SPEED_10000MBPS + *     %AD_LINK_SPEED_14000MBPS,   *     %AD_LINK_SPEED_20000MBPS   *     %AD_LINK_SPEED_25000MBPS   *     %AD_LINK_SPEED_40000MBPS + *     %AD_LINK_SPEED_50000MBPS   *     %AD_LINK_SPEED_56000MBPS   *     %AD_LINK_SPEED_100000MBPS   */ @@ -296,10 +302,18 @@ static u16 __get_link_speed(struct port *port)  			speed = AD_LINK_SPEED_2500MBPS;  			break; +		case SPEED_5000: +			speed = AD_LINK_SPEED_5000MBPS; +			break; +  		case SPEED_10000:  			speed = AD_LINK_SPEED_10000MBPS;  			break; +		case SPEED_14000: +			speed = AD_LINK_SPEED_14000MBPS; +			break; +  		case SPEED_20000:  			speed = AD_LINK_SPEED_20000MBPS;  			break; @@ -312,6 +326,10 @@ static u16 __get_link_speed(struct port *port)  			speed = AD_LINK_SPEED_40000MBPS;  			break; +		case SPEED_50000: +			speed = AD_LINK_SPEED_50000MBPS; +			break; +  		case SPEED_56000:  			speed = AD_LINK_SPEED_56000MBPS;  			break; @@ -712,9 +730,15 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator)  		case AD_LINK_SPEED_2500MBPS:  			bandwidth = nports * 2500;  			break; +		case AD_LINK_SPEED_5000MBPS: +			bandwidth = nports * 5000; +			break;  		case AD_LINK_SPEED_10000MBPS:  			bandwidth = nports * 10000;  			break; +		case AD_LINK_SPEED_14000MBPS: +			bandwidth = nports * 14000; +			break;  		case AD_LINK_SPEED_20000MBPS:  			bandwidth = nports * 20000;  			break; @@ -724,6 +748,9 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator)  		case AD_LINK_SPEED_40000MBPS:  			bandwidth = nports * 40000;  			break; +		case AD_LINK_SPEED_50000MBPS: +			bandwidth = nports * 50000; +			break;  		case AD_LINK_SPEED_56000MBPS:  			bandwidth = nports * 56000;  			break; diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 7d9474352c36..2865f31c6076 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4187,7 +4187,6 @@ static void bond_destructor(struct net_device *bond_dev)  	struct bonding *bond = netdev_priv(bond_dev);  	if (bond->wq)  		destroy_workqueue(bond->wq); -	free_netdev(bond_dev);  }  void bond_setup(struct net_device *bond_dev) @@ -4207,7 +4206,8 @@ void bond_setup(struct net_device *bond_dev)  	bond_dev->netdev_ops = &bond_netdev_ops;  	bond_dev->ethtool_ops = &bond_ethtool_ops; -	bond_dev->destructor = bond_destructor; +	bond_dev->needs_free_netdev = true; +	bond_dev->priv_destructor = bond_destructor;  	SET_NETDEV_DEVTYPE(bond_dev, &bond_type); @@ -4731,7 +4731,7 @@ int bond_create(struct net *net, const char *name)  	rtnl_unlock();  	if (res < 0) -		bond_destructor(bond_dev); +		free_netdev(bond_dev);  	return res;  } diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c index ddabce759456..71a7c3b44fdd 100644 --- a/drivers/net/caif/caif_hsi.c +++ b/drivers/net/caif/caif_hsi.c @@ -1121,7 +1121,7 @@ static void cfhsi_setup(struct net_device *dev)  	dev->flags = IFF_POINTOPOINT | IFF_NOARP;  	dev->mtu = CFHSI_MAX_CAIF_FRAME_SZ;  	dev->priv_flags |= IFF_NO_QUEUE; -	dev->destructor = free_netdev; +	dev->needs_free_netdev = true;  	dev->netdev_ops = &cfhsi_netdevops;  	for (i = 0; i < CFHSI_PRIO_LAST; ++i)  		skb_queue_head_init(&cfhsi->qhead[i]); diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index c2dea4916e5d..76e1d3545105 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c @@ -428,7 +428,7 @@ static void caifdev_setup(struct net_device *dev)  	dev->flags = IFF_POINTOPOINT | IFF_NOARP;  	dev->mtu = CAIF_MAX_MTU;  	dev->priv_flags |= IFF_NO_QUEUE; -	dev->destructor = free_netdev; +	dev->needs_free_netdev = true;  	skb_queue_head_init(&serdev->head);  	serdev->common.link_select = CAIF_LINK_LOW_LATENCY;  	serdev->common.use_frag = true; diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c index 3a529fbe539f..fc21afe852b9 100644 --- a/drivers/net/caif/caif_spi.c +++ b/drivers/net/caif/caif_spi.c @@ -712,7 +712,7 @@ static void cfspi_setup(struct net_device *dev)  	dev->flags = IFF_NOARP | IFF_POINTOPOINT;  	dev->priv_flags |= IFF_NO_QUEUE;  	dev->mtu = SPI_MAX_PAYLOAD_SIZE; -	dev->destructor = free_netdev; +	dev->needs_free_netdev = true;  	skb_queue_head_init(&cfspi->qhead);  	skb_queue_head_init(&cfspi->chead);  	cfspi->cfdev.link_select = CAIF_LINK_HIGH_BANDW; diff --git a/drivers/net/caif/caif_virtio.c b/drivers/net/caif/caif_virtio.c index 6122768c8644..1794ea0420b7 100644 --- a/drivers/net/caif/caif_virtio.c +++ b/drivers/net/caif/caif_virtio.c @@ -617,7 +617,7 @@ static void cfv_netdev_setup(struct net_device *netdev)  	netdev->tx_queue_len = 100;  	netdev->flags = IFF_POINTOPOINT | IFF_NOARP;  	netdev->mtu = CFV_DEF_MTU_SIZE; -	netdev->destructor = free_netdev; +	netdev->needs_free_netdev = true;  }  /* Create debugfs counters for the device */ diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 611d16a7061d..ae4ed03dc642 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -391,6 +391,9 @@ void can_change_state(struct net_device *dev, struct can_frame *cf,  	can_update_state_error_stats(dev, new_state);  	priv->state = new_state; +	if (!cf) +		return; +  	if (unlikely(new_state == CAN_STATE_BUS_OFF)) {  		cf->can_id |= CAN_ERR_BUSOFF;  		return; diff --git a/drivers/net/can/peak_canfd/peak_canfd.c b/drivers/net/can/peak_canfd/peak_canfd.c index 0d57be5ea97b..85268be0c913 100644 --- a/drivers/net/can/peak_canfd/peak_canfd.c +++ b/drivers/net/can/peak_canfd/peak_canfd.c @@ -489,7 +489,7 @@ int peak_canfd_handle_msgs_list(struct peak_canfd_priv *priv,  				struct pucan_rx_msg *msg_list, int msg_count)  {  	void *msg_ptr = msg_list; -	int i, msg_size; +	int i, msg_size = 0;  	for (i = 0; i < msg_count; i++) {  		msg_size = peak_canfd_handle_msg(priv, msg_ptr); diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index eb7173713bbc..6a6e896e52fa 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -417,7 +417,7 @@ static int slc_open(struct net_device *dev)  static void slc_free_netdev(struct net_device *dev)  {  	int i = dev->base_addr; -	free_netdev(dev); +  	slcan_devs[i] = NULL;  } @@ -436,7 +436,8 @@ static const struct net_device_ops slc_netdev_ops = {  static void slc_setup(struct net_device *dev)  {  	dev->netdev_ops		= &slc_netdev_ops; -	dev->destructor		= slc_free_netdev; +	dev->needs_free_netdev	= true; +	dev->priv_destructor	= slc_free_netdev;  	dev->hard_header_len	= 0;  	dev->addr_len		= 0; @@ -761,8 +762,6 @@ static void __exit slcan_exit(void)  		if (sl->tty) {  			printk(KERN_ERR "%s: tty discipline still running\n",  			       dev->name); -			/* Intentionally leak the control block. */ -			dev->destructor = NULL;  		}  		unregister_netdev(dev); diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index eecee7f8dfb7..afcc1312dbaf 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -265,6 +265,8 @@ static int gs_cmd_reset(struct gs_usb *gsusb, struct gs_can *gsdev)  			     sizeof(*dm),  			     1000); +	kfree(dm); +  	return rc;  } diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c index 57913dbbae0a..1ca76e03e965 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c @@ -908,8 +908,6 @@ static int peak_usb_probe(struct usb_interface *intf,  	const struct peak_usb_adapter *peak_usb_adapter = NULL;  	int i, err = -ENOMEM; -	usb_dev = interface_to_usbdev(intf); -  	/* get corresponding PCAN-USB adapter */  	for (i = 0; i < ARRAY_SIZE(peak_usb_adapters_list); i++)  		if (peak_usb_adapters_list[i]->device_id == usb_id_product) { @@ -920,7 +918,7 @@ static int peak_usb_probe(struct usb_interface *intf,  	if (!peak_usb_adapter) {  		/* should never come except device_id bad usage in this file */  		pr_err("%s: didn't find device id. 0x%x in devices list\n", -			PCAN_USB_DRIVER_NAME, usb_dev->descriptor.idProduct); +			PCAN_USB_DRIVER_NAME, usb_id_product);  		return -ENODEV;  	} diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c index facca33d53e9..a8cb33264ff1 100644 --- a/drivers/net/can/vcan.c +++ b/drivers/net/can/vcan.c @@ -152,7 +152,7 @@ static const struct net_device_ops vcan_netdev_ops = {  static void vcan_setup(struct net_device *dev)  {  	dev->type		= ARPHRD_CAN; -	dev->mtu		= CAN_MTU; +	dev->mtu		= CANFD_MTU;  	dev->hard_header_len	= 0;  	dev->addr_len		= 0;  	dev->tx_queue_len	= 0; @@ -163,7 +163,7 @@ static void vcan_setup(struct net_device *dev)  		dev->flags |= IFF_ECHO;  	dev->netdev_ops		= &vcan_netdev_ops; -	dev->destructor		= free_netdev; +	dev->needs_free_netdev	= true;  }  static struct rtnl_link_ops vcan_link_ops __read_mostly = { diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c index 7fbb24795681..cfe889e8f172 100644 --- a/drivers/net/can/vxcan.c +++ b/drivers/net/can/vxcan.c @@ -150,13 +150,13 @@ static const struct net_device_ops vxcan_netdev_ops = {  static void vxcan_setup(struct net_device *dev)  {  	dev->type		= ARPHRD_CAN; -	dev->mtu		= CAN_MTU; +	dev->mtu		= CANFD_MTU;  	dev->hard_header_len	= 0;  	dev->addr_len		= 0;  	dev->tx_queue_len	= 0;  	dev->flags		= (IFF_NOARP|IFF_ECHO);  	dev->netdev_ops		= &vxcan_netdev_ops; -	dev->destructor		= free_netdev; +	dev->needs_free_netdev	= true;  }  /* forward declaration for rtnl_create_link() */ diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index 149244aac20a..9905b52fe293 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -328,7 +328,6 @@ static void dummy_free_netdev(struct net_device *dev)  	struct dummy_priv *priv = netdev_priv(dev);  	kfree(priv->vfinfo); -	free_netdev(dev);  }  static void dummy_setup(struct net_device *dev) @@ -338,7 +337,8 @@ static void dummy_setup(struct net_device *dev)  	/* Initialize the device structure. */  	dev->netdev_ops = &dummy_netdev_ops;  	dev->ethtool_ops = &dummy_ethtool_ops; -	dev->destructor = dummy_free_netdev; +	dev->needs_free_netdev = true; +	dev->priv_destructor = dummy_free_netdev;  	/* Fill in device structure with ethernet-generic values. */  	dev->flags |= IFF_NOARP; diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c index 08d11cede9c9..f5b237e0bd60 100644 --- a/drivers/net/ethernet/amazon/ena/ena_com.c +++ b/drivers/net/ethernet/amazon/ena/ena_com.c @@ -61,6 +61,8 @@  #define ENA_MMIO_READ_TIMEOUT 0xFFFFFFFF +#define ENA_REGS_ADMIN_INTR_MASK 1 +  /*****************************************************************************/  /*****************************************************************************/  /*****************************************************************************/ @@ -232,11 +234,9 @@ static struct ena_comp_ctx *__ena_com_submit_admin_cmd(struct ena_com_admin_queu  	tail_masked = admin_queue->sq.tail & queue_size_mask;  	/* In case of queue FULL */ -	cnt = admin_queue->sq.tail - admin_queue->sq.head; +	cnt = atomic_read(&admin_queue->outstanding_cmds);  	if (cnt >= admin_queue->q_depth) { -		pr_debug("admin queue is FULL (tail %d head %d depth: %d)\n", -			 admin_queue->sq.tail, admin_queue->sq.head, -			 admin_queue->q_depth); +		pr_debug("admin queue is full.\n");  		admin_queue->stats.out_of_space++;  		return ERR_PTR(-ENOSPC);  	} @@ -508,15 +508,20 @@ static int ena_com_comp_status_to_errno(u8 comp_status)  static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_ctx,  						     struct ena_com_admin_queue *admin_queue)  { -	unsigned long flags; -	u32 start_time; +	unsigned long flags, timeout;  	int ret; -	start_time = ((u32)jiffies_to_usecs(jiffies)); +	timeout = jiffies + ADMIN_CMD_TIMEOUT_US; + +	while (1) { +		spin_lock_irqsave(&admin_queue->q_lock, flags); +		ena_com_handle_admin_completion(admin_queue); +		spin_unlock_irqrestore(&admin_queue->q_lock, flags); + +		if (comp_ctx->status != ENA_CMD_SUBMITTED) +			break; -	while (comp_ctx->status == ENA_CMD_SUBMITTED) { -		if ((((u32)jiffies_to_usecs(jiffies)) - start_time) > -		    ADMIN_CMD_TIMEOUT_US) { +		if (time_is_before_jiffies(timeout)) {  			pr_err("Wait for completion (polling) timeout\n");  			/* ENA didn't have any completion */  			spin_lock_irqsave(&admin_queue->q_lock, flags); @@ -528,10 +533,6 @@ static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_c  			goto err;  		} -		spin_lock_irqsave(&admin_queue->q_lock, flags); -		ena_com_handle_admin_completion(admin_queue); -		spin_unlock_irqrestore(&admin_queue->q_lock, flags); -  		msleep(100);  	} @@ -1455,6 +1456,12 @@ void ena_com_admin_destroy(struct ena_com_dev *ena_dev)  void ena_com_set_admin_polling_mode(struct ena_com_dev *ena_dev, bool polling)  { +	u32 mask_value = 0; + +	if (polling) +		mask_value = ENA_REGS_ADMIN_INTR_MASK; + +	writel(mask_value, ena_dev->reg_bar + ENA_REGS_INTR_MASK_OFF);  	ena_dev->admin_queue.polling = polling;  } diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c b/drivers/net/ethernet/amazon/ena/ena_ethtool.c index 67b2338f8fb3..3ee55e2fd694 100644 --- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c +++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c @@ -80,7 +80,6 @@ static const struct ena_stats ena_stats_tx_strings[] = {  	ENA_STAT_TX_ENTRY(tx_poll),  	ENA_STAT_TX_ENTRY(doorbells),  	ENA_STAT_TX_ENTRY(prepare_ctx_err), -	ENA_STAT_TX_ENTRY(missing_tx_comp),  	ENA_STAT_TX_ENTRY(bad_req_id),  }; @@ -94,6 +93,7 @@ static const struct ena_stats ena_stats_rx_strings[] = {  	ENA_STAT_RX_ENTRY(dma_mapping_err),  	ENA_STAT_RX_ENTRY(bad_desc_num),  	ENA_STAT_RX_ENTRY(rx_copybreak_pkt), +	ENA_STAT_RX_ENTRY(empty_rx_ring),  };  static const struct ena_stats ena_stats_ena_com_strings[] = { diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c index 7c1214d78855..4f16ed38bcf3 100644 --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c @@ -190,6 +190,7 @@ static void ena_init_io_rings(struct ena_adapter *adapter)  		rxr->sgl_size = adapter->max_rx_sgl_size;  		rxr->smoothed_interval =  			ena_com_get_nonadaptive_moderation_interval_rx(ena_dev); +		rxr->empty_rx_queue = 0;  	}  } @@ -1078,6 +1079,26 @@ inline void ena_adjust_intr_moderation(struct ena_ring *rx_ring,  	rx_ring->per_napi_bytes = 0;  } +static inline void ena_unmask_interrupt(struct ena_ring *tx_ring, +					struct ena_ring *rx_ring) +{ +	struct ena_eth_io_intr_reg intr_reg; + +	/* Update intr register: rx intr delay, +	 * tx intr delay and interrupt unmask +	 */ +	ena_com_update_intr_reg(&intr_reg, +				rx_ring->smoothed_interval, +				tx_ring->smoothed_interval, +				true); + +	/* It is a shared MSI-X. +	 * Tx and Rx CQ have pointer to it. +	 * So we use one of them to reach the intr reg +	 */ +	ena_com_unmask_intr(rx_ring->ena_com_io_cq, &intr_reg); +} +  static inline void ena_update_ring_numa_node(struct ena_ring *tx_ring,  					     struct ena_ring *rx_ring)  { @@ -1108,7 +1129,6 @@ static int ena_io_poll(struct napi_struct *napi, int budget)  {  	struct ena_napi *ena_napi = container_of(napi, struct ena_napi, napi);  	struct ena_ring *tx_ring, *rx_ring; -	struct ena_eth_io_intr_reg intr_reg;  	u32 tx_work_done;  	u32 rx_work_done; @@ -1149,22 +1169,9 @@ static int ena_io_poll(struct napi_struct *napi, int budget)  			if (ena_com_get_adaptive_moderation_enabled(rx_ring->ena_dev))  				ena_adjust_intr_moderation(rx_ring, tx_ring); -			/* Update intr register: rx intr delay, -			 * tx intr delay and interrupt unmask -			 */ -			ena_com_update_intr_reg(&intr_reg, -						rx_ring->smoothed_interval, -						tx_ring->smoothed_interval, -						true); - -			/* It is a shared MSI-X. -			 * Tx and Rx CQ have pointer to it. -			 * So we use one of them to reach the intr reg -			 */ -			ena_com_unmask_intr(rx_ring->ena_com_io_cq, &intr_reg); +			ena_unmask_interrupt(tx_ring, rx_ring);  		} -  		ena_update_ring_numa_node(tx_ring, rx_ring);  		ret = rx_work_done; @@ -1485,6 +1492,11 @@ static int ena_up_complete(struct ena_adapter *adapter)  	ena_napi_enable_all(adapter); +	/* Enable completion queues interrupt */ +	for (i = 0; i < adapter->num_queues; i++) +		ena_unmask_interrupt(&adapter->tx_ring[i], +				     &adapter->rx_ring[i]); +  	/* schedule napi in case we had pending packets  	 * from the last time we disable napi  	 */ @@ -1532,6 +1544,7 @@ static int ena_create_io_tx_queue(struct ena_adapter *adapter, int qid)  			  "Failed to get TX queue handlers. TX queue num %d rc: %d\n",  			  qid, rc);  		ena_com_destroy_io_queue(ena_dev, ena_qid); +		return rc;  	}  	ena_com_update_numa_node(tx_ring->ena_com_io_cq, ctx.numa_node); @@ -1596,6 +1609,7 @@ static int ena_create_io_rx_queue(struct ena_adapter *adapter, int qid)  			  "Failed to get RX queue handlers. RX queue num %d rc: %d\n",  			  qid, rc);  		ena_com_destroy_io_queue(ena_dev, ena_qid); +		return rc;  	}  	ena_com_update_numa_node(rx_ring->ena_com_io_cq, ctx.numa_node); @@ -1981,6 +1995,7 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev)  	tx_info->tx_descs = nb_hw_desc;  	tx_info->last_jiffies = jiffies; +	tx_info->print_once = 0;  	tx_ring->next_to_use = ENA_TX_RING_IDX_NEXT(next_to_use,  		tx_ring->ring_size); @@ -2550,13 +2565,44 @@ err:  		"Reset attempt failed. Can not reset the device\n");  } -static void check_for_missing_tx_completions(struct ena_adapter *adapter) +static int check_missing_comp_in_queue(struct ena_adapter *adapter, +				       struct ena_ring *tx_ring)  {  	struct ena_tx_buffer *tx_buf;  	unsigned long last_jiffies; +	u32 missed_tx = 0; +	int i; + +	for (i = 0; i < tx_ring->ring_size; i++) { +		tx_buf = &tx_ring->tx_buffer_info[i]; +		last_jiffies = tx_buf->last_jiffies; +		if (unlikely(last_jiffies && +			     time_is_before_jiffies(last_jiffies + TX_TIMEOUT))) { +			if (!tx_buf->print_once) +				netif_notice(adapter, tx_err, adapter->netdev, +					     "Found a Tx that wasn't completed on time, qid %d, index %d.\n", +					     tx_ring->qid, i); + +			tx_buf->print_once = 1; +			missed_tx++; + +			if (unlikely(missed_tx > MAX_NUM_OF_TIMEOUTED_PACKETS)) { +				netif_err(adapter, tx_err, adapter->netdev, +					  "The number of lost tx completions is above the threshold (%d > %d). Reset the device\n", +					  missed_tx, MAX_NUM_OF_TIMEOUTED_PACKETS); +				set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags); +				return -EIO; +			} +		} +	} + +	return 0; +} + +static void check_for_missing_tx_completions(struct ena_adapter *adapter) +{  	struct ena_ring *tx_ring; -	int i, j, budget; -	u32 missed_tx; +	int i, budget, rc;  	/* Make sure the driver doesn't turn the device in other process */  	smp_rmb(); @@ -2572,31 +2618,9 @@ static void check_for_missing_tx_completions(struct ena_adapter *adapter)  	for (i = adapter->last_monitored_tx_qid; i < adapter->num_queues; i++) {  		tx_ring = &adapter->tx_ring[i]; -		for (j = 0; j < tx_ring->ring_size; j++) { -			tx_buf = &tx_ring->tx_buffer_info[j]; -			last_jiffies = tx_buf->last_jiffies; -			if (unlikely(last_jiffies && time_is_before_jiffies(last_jiffies + TX_TIMEOUT))) { -				netif_notice(adapter, tx_err, adapter->netdev, -					     "Found a Tx that wasn't completed on time, qid %d, index %d.\n", -					     tx_ring->qid, j); - -				u64_stats_update_begin(&tx_ring->syncp); -				missed_tx = tx_ring->tx_stats.missing_tx_comp++; -				u64_stats_update_end(&tx_ring->syncp); - -				/* Clear last jiffies so the lost buffer won't -				 * be counted twice. -				 */ -				tx_buf->last_jiffies = 0; - -				if (unlikely(missed_tx > MAX_NUM_OF_TIMEOUTED_PACKETS)) { -					netif_err(adapter, tx_err, adapter->netdev, -						  "The number of lost tx completion is above the threshold (%d > %d). Reset the device\n", -						  missed_tx, MAX_NUM_OF_TIMEOUTED_PACKETS); -					set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags); -				} -			} -		} +		rc = check_missing_comp_in_queue(adapter, tx_ring); +		if (unlikely(rc)) +			return;  		budget--;  		if (!budget) @@ -2606,6 +2630,58 @@ static void check_for_missing_tx_completions(struct ena_adapter *adapter)  	adapter->last_monitored_tx_qid = i % adapter->num_queues;  } +/* trigger napi schedule after 2 consecutive detections */ +#define EMPTY_RX_REFILL 2 +/* For the rare case where the device runs out of Rx descriptors and the + * napi handler failed to refill new Rx descriptors (due to a lack of memory + * for example). + * This case will lead to a deadlock: + * The device won't send interrupts since all the new Rx packets will be dropped + * The napi handler won't allocate new Rx descriptors so the device will be + * able to send new packets. + * + * This scenario can happen when the kernel's vm.min_free_kbytes is too small. + * It is recommended to have at least 512MB, with a minimum of 128MB for + * constrained environment). + * + * When such a situation is detected - Reschedule napi + */ +static void check_for_empty_rx_ring(struct ena_adapter *adapter) +{ +	struct ena_ring *rx_ring; +	int i, refill_required; + +	if (!test_bit(ENA_FLAG_DEV_UP, &adapter->flags)) +		return; + +	if (test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags)) +		return; + +	for (i = 0; i < adapter->num_queues; i++) { +		rx_ring = &adapter->rx_ring[i]; + +		refill_required = +			ena_com_sq_empty_space(rx_ring->ena_com_io_sq); +		if (unlikely(refill_required == (rx_ring->ring_size - 1))) { +			rx_ring->empty_rx_queue++; + +			if (rx_ring->empty_rx_queue >= EMPTY_RX_REFILL) { +				u64_stats_update_begin(&rx_ring->syncp); +				rx_ring->rx_stats.empty_rx_ring++; +				u64_stats_update_end(&rx_ring->syncp); + +				netif_err(adapter, drv, adapter->netdev, +					  "trigger refill for ring %d\n", i); + +				napi_schedule(rx_ring->napi); +				rx_ring->empty_rx_queue = 0; +			} +		} else { +			rx_ring->empty_rx_queue = 0; +		} +	} +} +  /* Check for keep alive expiration */  static void check_for_missing_keep_alive(struct ena_adapter *adapter)  { @@ -2660,6 +2736,8 @@ static void ena_timer_service(unsigned long data)  	check_for_missing_tx_completions(adapter); +	check_for_empty_rx_ring(adapter); +  	if (debug_area)  		ena_dump_stats_to_buf(adapter, debug_area); @@ -2840,6 +2918,11 @@ static void ena_release_bars(struct ena_com_dev *ena_dev, struct pci_dev *pdev)  {  	int release_bars; +	if (ena_dev->mem_bar) +		devm_iounmap(&pdev->dev, ena_dev->mem_bar); + +	devm_iounmap(&pdev->dev, ena_dev->reg_bar); +  	release_bars = pci_select_bars(pdev, IORESOURCE_MEM) & ENA_BAR_MASK;  	pci_release_selected_regions(pdev, release_bars);  } @@ -2927,8 +3010,9 @@ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  		goto err_free_ena_dev;  	} -	ena_dev->reg_bar = ioremap(pci_resource_start(pdev, ENA_REG_BAR), -				   pci_resource_len(pdev, ENA_REG_BAR)); +	ena_dev->reg_bar = devm_ioremap(&pdev->dev, +					pci_resource_start(pdev, ENA_REG_BAR), +					pci_resource_len(pdev, ENA_REG_BAR));  	if (!ena_dev->reg_bar) {  		dev_err(&pdev->dev, "failed to remap regs bar\n");  		rc = -EFAULT; @@ -2948,8 +3032,9 @@ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  	ena_set_push_mode(pdev, ena_dev, &get_feat_ctx);  	if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) { -		ena_dev->mem_bar = ioremap_wc(pci_resource_start(pdev, ENA_MEM_BAR), -					      pci_resource_len(pdev, ENA_MEM_BAR)); +		ena_dev->mem_bar = devm_ioremap_wc(&pdev->dev, +						   pci_resource_start(pdev, ENA_MEM_BAR), +						   pci_resource_len(pdev, ENA_MEM_BAR));  		if (!ena_dev->mem_bar) {  			rc = -EFAULT;  			goto err_device_destroy; diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h b/drivers/net/ethernet/amazon/ena/ena_netdev.h index 0e22bce6239d..a4d3d5e21068 100644 --- a/drivers/net/ethernet/amazon/ena/ena_netdev.h +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h @@ -45,7 +45,7 @@  #define DRV_MODULE_VER_MAJOR	1  #define DRV_MODULE_VER_MINOR	1 -#define DRV_MODULE_VER_SUBMINOR 2 +#define DRV_MODULE_VER_SUBMINOR 7  #define DRV_MODULE_NAME		"ena"  #ifndef DRV_MODULE_VERSION @@ -146,7 +146,18 @@ struct ena_tx_buffer {  	u32 tx_descs;  	/* num of buffers used by this skb */  	u32 num_of_bufs; -	/* Save the last jiffies to detect missing tx packets */ + +	/* Used for detect missing tx packets to limit the number of prints */ +	u32 print_once; +	/* Save the last jiffies to detect missing tx packets +	 * +	 * sets to non zero value on ena_start_xmit and set to zero on +	 * napi and timer_Service_routine. +	 * +	 * while this value is not protected by lock, +	 * a given packet is not expected to be handled by ena_start_xmit +	 * and by napi/timer_service at the same time. +	 */  	unsigned long last_jiffies;  	struct ena_com_buf bufs[ENA_PKT_MAX_BUFS];  } ____cacheline_aligned; @@ -170,7 +181,6 @@ struct ena_stats_tx {  	u64 napi_comp;  	u64 tx_poll;  	u64 doorbells; -	u64 missing_tx_comp;  	u64 bad_req_id;  }; @@ -184,6 +194,7 @@ struct ena_stats_rx {  	u64 dma_mapping_err;  	u64 bad_desc_num;  	u64 rx_copybreak_pkt; +	u64 empty_rx_ring;  };  struct ena_ring { @@ -231,6 +242,7 @@ struct ena_ring {  		struct ena_stats_tx tx_stats;  		struct ena_stats_rx rx_stats;  	}; +	int empty_rx_queue;  } ____cacheline_aligned;  struct ena_stats_dev { diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h index b8e3d88f0879..a66aee51ab5b 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h @@ -193,9 +193,6 @@ int hw_atl_utils_hw_get_regs(struct aq_hw_s *self,  			     struct aq_hw_caps_s *aq_hw_caps,  			     u32 *regs_buff); -int hw_atl_utils_hw_get_settings(struct aq_hw_s *self, -				 struct ethtool_cmd *cmd); -  int hw_atl_utils_hw_set_power(struct aq_hw_s *self,  			      unsigned int power_state); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index ef734675885e..67fe3d826566 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -3883,15 +3883,26 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)  		/* when transmitting in a vf, start bd must hold the ethertype  		 * for fw to enforce it  		 */ +		u16 vlan_tci = 0;  #ifndef BNX2X_STOP_ON_ERROR -		if (IS_VF(bp)) +		if (IS_VF(bp)) {  #endif -			tx_start_bd->vlan_or_ethertype = -				cpu_to_le16(ntohs(eth->h_proto)); +			/* Still need to consider inband vlan for enforced */ +			if (__vlan_get_tag(skb, &vlan_tci)) { +				tx_start_bd->vlan_or_ethertype = +					cpu_to_le16(ntohs(eth->h_proto)); +			} else { +				tx_start_bd->bd_flags.as_bitfield |= +					(X_ETH_INBAND_VLAN << +					 ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT); +				tx_start_bd->vlan_or_ethertype = +					cpu_to_le16(vlan_tci); +			}  #ifndef BNX2X_STOP_ON_ERROR -		else +		} else {  			/* used by FW for packet accounting */  			tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod); +		}  #endif  	} diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index bdfd53b46bc5..9ca994d0bab6 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c @@ -901,6 +901,8 @@ static void bnx2x_vf_flr(struct bnx2x *bp, struct bnx2x_virtf *vf)  	/* release VF resources */  	bnx2x_vf_free_resc(bp, vf); +	vf->malicious = false; +  	/* re-open the mailbox */  	bnx2x_vf_enable_mbx(bp, vf->abs_vfid);  	return; @@ -1822,9 +1824,11 @@ get_vf:  		   vf->abs_vfid, qidx);  		bnx2x_vf_handle_rss_update_eqe(bp, vf);  	case EVENT_RING_OPCODE_VF_FLR: -	case EVENT_RING_OPCODE_MALICIOUS_VF:  		/* Do nothing for now */  		return 0; +	case EVENT_RING_OPCODE_MALICIOUS_VF: +		vf->malicious = true; +		return 0;  	}  	return 0; @@ -1905,6 +1909,13 @@ void bnx2x_iov_adjust_stats_req(struct bnx2x *bp)  			continue;  		} +		if (vf->malicious) { +			DP_AND((BNX2X_MSG_IOV | BNX2X_MSG_STATS), +			       "vf %d malicious so no stats for it\n", +			       vf->abs_vfid); +			continue; +		} +  		DP_AND((BNX2X_MSG_IOV | BNX2X_MSG_STATS),  		       "add addresses for vf %d\n", vf->abs_vfid);  		for_each_vfq(vf, j) { @@ -3042,7 +3053,7 @@ void bnx2x_vf_pci_dealloc(struct bnx2x *bp)  {  	BNX2X_PCI_FREE(bp->vf2pf_mbox, bp->vf2pf_mbox_mapping,  		       sizeof(struct bnx2x_vf_mbx_msg)); -	BNX2X_PCI_FREE(bp->vf2pf_mbox, bp->pf2vf_bulletin_mapping, +	BNX2X_PCI_FREE(bp->pf2vf_bulletin, bp->pf2vf_bulletin_mapping,  		       sizeof(union pf_vf_bulletin));  } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h index 888d0b6632e8..53466f6cebab 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h @@ -141,6 +141,7 @@ struct bnx2x_virtf {  #define VF_RESET	3	/* VF FLR'd, pending cleanup */  	bool flr_clnup_stage;	/* true during flr cleanup */ +	bool malicious;		/* true if FW indicated so, until FLR */  	/* dma */  	dma_addr_t fw_stat_map; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 01c9710fc62e..2c6de769f4e6 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -4668,7 +4668,7 @@ static void dummy_setup(struct net_device *dev)  	/* Initialize the device structure. */  	dev->netdev_ops = &cxgb4_mgmt_netdev_ops;  	dev->ethtool_ops = &cxgb4_mgmt_ethtool_ops; -	dev->destructor = free_netdev; +	dev->needs_free_netdev = true;  }  static int config_mgmt_dev(struct pci_dev *pdev) diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c index 508923f39ccf..259e69a52ec5 100644 --- a/drivers/net/ethernet/ibm/emac/core.c +++ b/drivers/net/ethernet/ibm/emac/core.c @@ -343,6 +343,7 @@ static int emac_reset(struct emac_instance *dev)  {  	struct emac_regs __iomem *p = dev->emacp;  	int n = 20; +	bool __maybe_unused try_internal_clock = false;  	DBG(dev, "reset" NL); @@ -355,6 +356,7 @@ static int emac_reset(struct emac_instance *dev)  	}  #ifdef CONFIG_PPC_DCR_NATIVE +do_retry:  	/*  	 * PPC460EX/GT Embedded Processor Advanced User's Manual  	 * section 28.10.1 Mode Register 0 (EMACx_MR0) states: @@ -362,10 +364,19 @@ static int emac_reset(struct emac_instance *dev)  	 * of the EMAC. If none is present, select the internal clock  	 * (SDR0_ETH_CFG[EMACx_PHY_CLK] = 1).  	 * After a soft reset, select the external clock. +	 * +	 * The AR8035-A PHY Meraki MR24 does not provide a TX Clk if the +	 * ethernet cable is not attached. This causes the reset to timeout +	 * and the PHY detection code in emac_init_phy() is unable to +	 * communicate and detect the AR8035-A PHY. As a result, the emac +	 * driver bails out early and the user has no ethernet. +	 * In order to stay compatible with existing configurations, the +	 * driver will temporarily switch to the internal clock, after +	 * the first reset fails.  	 */  	if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) { -		if (dev->phy_address == 0xffffffff && -		    dev->phy_map == 0xffffffff) { +		if (try_internal_clock || (dev->phy_address == 0xffffffff && +					   dev->phy_map == 0xffffffff)) {  			/* No PHY: select internal loop clock before reset */  			dcri_clrset(SDR0, SDR0_ETH_CFG,  				    0, SDR0_ETH_CFG_ECS << dev->cell_index); @@ -383,8 +394,15 @@ static int emac_reset(struct emac_instance *dev)  #ifdef CONFIG_PPC_DCR_NATIVE  	if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) { -		if (dev->phy_address == 0xffffffff && -		    dev->phy_map == 0xffffffff) { +		if (!n && !try_internal_clock) { +			/* first attempt has timed out. */ +			n = 20; +			try_internal_clock = true; +			goto do_retry; +		} + +		if (try_internal_clock || (dev->phy_address == 0xffffffff && +					   dev->phy_map == 0xffffffff)) {  			/* No PHY: restore external clock source after reset */  			dcri_clrset(SDR0, SDR0_ETH_CFG,  				    SDR0_ETH_CFG_ECS << dev->cell_index, 0); @@ -2460,20 +2478,24 @@ static int emac_mii_bus_reset(struct mii_bus *bus)  	return emac_reset(dev);  } +static int emac_mdio_phy_start_aneg(struct mii_phy *phy, +				    struct phy_device *phy_dev) +{ +	phy_dev->autoneg = phy->autoneg; +	phy_dev->speed = phy->speed; +	phy_dev->duplex = phy->duplex; +	phy_dev->advertising = phy->advertising; +	return phy_start_aneg(phy_dev); +} +  static int emac_mdio_setup_aneg(struct mii_phy *phy, u32 advertise)  {  	struct net_device *ndev = phy->dev;  	struct emac_instance *dev = netdev_priv(ndev); -	dev->phy.autoneg = AUTONEG_ENABLE; -	dev->phy.speed = SPEED_1000; -	dev->phy.duplex = DUPLEX_FULL; -	dev->phy.advertising = advertise;  	phy->autoneg = AUTONEG_ENABLE; -	phy->speed = dev->phy.speed; -	phy->duplex = dev->phy.duplex;  	phy->advertising = advertise; -	return phy_start_aneg(dev->phy_dev); +	return emac_mdio_phy_start_aneg(phy, dev->phy_dev);  }  static int emac_mdio_setup_forced(struct mii_phy *phy, int speed, int fd) @@ -2481,13 +2503,10 @@ static int emac_mdio_setup_forced(struct mii_phy *phy, int speed, int fd)  	struct net_device *ndev = phy->dev;  	struct emac_instance *dev = netdev_priv(ndev); -	dev->phy.autoneg =  AUTONEG_DISABLE; -	dev->phy.speed = speed; -	dev->phy.duplex = fd;  	phy->autoneg = AUTONEG_DISABLE;  	phy->speed = speed;  	phy->duplex = fd; -	return phy_start_aneg(dev->phy_dev); +	return emac_mdio_phy_start_aneg(phy, dev->phy_dev);  }  static int emac_mdio_poll_link(struct mii_phy *phy) @@ -2509,16 +2528,17 @@ static int emac_mdio_read_link(struct mii_phy *phy)  {  	struct net_device *ndev = phy->dev;  	struct emac_instance *dev = netdev_priv(ndev); +	struct phy_device *phy_dev = dev->phy_dev;  	int res; -	res = phy_read_status(dev->phy_dev); +	res = phy_read_status(phy_dev);  	if (res)  		return res; -	dev->phy.speed = phy->speed; -	dev->phy.duplex = phy->duplex; -	dev->phy.pause = phy->pause; -	dev->phy.asym_pause = phy->asym_pause; +	phy->speed = phy_dev->speed; +	phy->duplex = phy_dev->duplex; +	phy->pause = phy_dev->pause; +	phy->asym_pause = phy_dev->asym_pause;  	return 0;  } @@ -2528,13 +2548,6 @@ static int emac_mdio_init_phy(struct mii_phy *phy)  	struct emac_instance *dev = netdev_priv(ndev);  	phy_start(dev->phy_dev); -	dev->phy.autoneg = phy->autoneg; -	dev->phy.speed = phy->speed; -	dev->phy.duplex = phy->duplex; -	dev->phy.advertising = phy->advertising; -	dev->phy.pause = phy->pause; -	dev->phy.asym_pause = phy->asym_pause; -  	return phy_init_hw(dev->phy_dev);  } diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 59ea7a5ae776..78fdd4f0e341 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -1588,6 +1588,11 @@ static void ibmvnic_netpoll_controller(struct net_device *dev)  }  #endif +static int ibmvnic_change_mtu(struct net_device *netdev, int new_mtu) +{ +	return -EOPNOTSUPP; +} +  static const struct net_device_ops ibmvnic_netdev_ops = {  	.ndo_open		= ibmvnic_open,  	.ndo_stop		= ibmvnic_close, @@ -1599,6 +1604,7 @@ static const struct net_device_ops ibmvnic_netdev_ops = {  #ifdef CONFIG_NET_POLL_CONTROLLER  	.ndo_poll_controller	= ibmvnic_netpoll_controller,  #endif +	.ndo_change_mtu		= ibmvnic_change_mtu,  };  /* ethtool functions */ diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 60dc9b2c19ff..395ca94faf80 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -399,6 +399,7 @@ struct i40e_pf {  #define I40E_FLAG_RX_CSUM_ENABLED		BIT_ULL(1)  #define I40E_FLAG_MSI_ENABLED			BIT_ULL(2)  #define I40E_FLAG_MSIX_ENABLED			BIT_ULL(3) +#define I40E_FLAG_HW_ATR_EVICT_ENABLED		BIT_ULL(4)  #define I40E_FLAG_RSS_ENABLED			BIT_ULL(6)  #define I40E_FLAG_VMDQ_ENABLED			BIT_ULL(7)  #define I40E_FLAG_IWARP_ENABLED			BIT_ULL(10) diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 35a246f05520..3d58762efbc0 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -225,7 +225,7 @@ static const struct i40e_priv_flags i40e_gstrings_priv_flags[] = {  	I40E_PRIV_FLAG("LinkPolling", I40E_FLAG_LINK_POLLING_ENABLED, 0),  	I40E_PRIV_FLAG("flow-director-atr", I40E_FLAG_FD_ATR_ENABLED, 0),  	I40E_PRIV_FLAG("veb-stats", I40E_FLAG_VEB_STATS_ENABLED, 0), -	I40E_PRIV_FLAG("hw-atr-eviction", I40E_FLAG_HW_ATR_EVICT_CAPABLE, 0), +	I40E_PRIV_FLAG("hw-atr-eviction", I40E_FLAG_HW_ATR_EVICT_ENABLED, 0),  	I40E_PRIV_FLAG("legacy-rx", I40E_FLAG_LEGACY_RX, 0),  }; @@ -4093,7 +4093,7 @@ flags_complete:  	/* Only allow ATR evict on hardware that is capable of handling it */  	if (pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE) -		pf->flags &= ~I40E_FLAG_HW_ATR_EVICT_CAPABLE; +		pf->flags &= ~I40E_FLAG_HW_ATR_EVICT_ENABLED;  	if (changed_flags & I40E_FLAG_TRUE_PROMISC_SUPPORT) {  		u16 sw_flags = 0, valid_flags = 0; diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index abab7fb7a3fc..98fb644a580e 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -8823,11 +8823,12 @@ static int i40e_sw_init(struct i40e_pf *pf)  		    (pf->hw.aq.api_min_ver > 4))) {  		/* Supported in FW API version higher than 1.4 */  		pf->flags |= I40E_FLAG_GENEVE_OFFLOAD_CAPABLE; -		pf->flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE; -	} else { -		pf->flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE;  	} +	/* Enable HW ATR eviction if possible */ +	if (pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE) +		pf->flags |= I40E_FLAG_HW_ATR_EVICT_ENABLED; +  	pf->eeprom_version = 0xDEAD;  	pf->lan_veb = I40E_NO_VEB;  	pf->lan_vsi = I40E_NO_VSI; diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index ddf885084c77..af554f3cda19 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -2341,7 +2341,7 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb,  	/* Due to lack of space, no more new filters can be programmed */  	if (th->syn && (pf->flags & I40E_FLAG_FD_ATR_AUTO_DISABLED))  		return; -	if (pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE) { +	if (pf->flags & I40E_FLAG_HW_ATR_EVICT_ENABLED) {  		/* HW ATR eviction will take care of removing filters on FIN  		 * and RST packets.  		 */ @@ -2403,7 +2403,7 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb,  			I40E_TXD_FLTR_QW1_CNTINDEX_SHIFT) &  			I40E_TXD_FLTR_QW1_CNTINDEX_MASK; -	if (pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE) +	if (pf->flags & I40E_FLAG_HW_ATR_EVICT_ENABLED)  		dtype_cmd |= I40E_TXD_FLTR_QW1_ATR_MASK;  	fdir_desc->qindex_flex_ptype_vsi = cpu_to_le32(flex_ptype); diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 6bee254d34ee..ecbe40ea8ffe 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -2876,10 +2876,12 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id,  					   VLAN_VID_MASK));  	} +	spin_unlock_bh(&vsi->mac_filter_hash_lock);  	if (vlan_id || qos)  		ret = i40e_vsi_add_pvid(vsi, vlanprio);  	else  		i40e_vsi_remove_pvid(vsi); +	spin_lock_bh(&vsi->mac_filter_hash_lock);  	if (vlan_id) {  		dev_info(&pf->pdev->dev, "Setting VLAN %d, QOS 0x%x on VF %d\n", diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index fe1458450e44..ca4b55c60682 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@ -3725,7 +3725,7 @@ static void mvpp2_bm_bufs_get_addrs(struct device *dev, struct mvpp2 *priv,  				    dma_addr_t *dma_addr,  				    phys_addr_t *phys_addr)  { -	int cpu = smp_processor_id(); +	int cpu = get_cpu();  	*dma_addr = mvpp2_percpu_read(priv, cpu,  				      MVPP2_BM_PHY_ALLOC_REG(bm_pool->id)); @@ -3746,6 +3746,8 @@ static void mvpp2_bm_bufs_get_addrs(struct device *dev, struct mvpp2 *priv,  		if (sizeof(phys_addr_t) == 8)  			*phys_addr |= (u64)phys_addr_highbits << 32;  	} + +	put_cpu();  }  /* Free all buffers from the pool */ @@ -3926,18 +3928,12 @@ static inline u32 mvpp2_bm_cookie_pool_set(u32 cookie, int pool)  	return bm;  } -/* Get pool number from a BM cookie */ -static inline int mvpp2_bm_cookie_pool_get(unsigned long cookie) -{ -	return (cookie >> MVPP2_BM_COOKIE_POOL_OFFS) & 0xFF; -} -  /* Release buffer to BM */  static inline void mvpp2_bm_pool_put(struct mvpp2_port *port, int pool,  				     dma_addr_t buf_dma_addr,  				     phys_addr_t buf_phys_addr)  { -	int cpu = smp_processor_id(); +	int cpu = get_cpu();  	if (port->priv->hw_version == MVPP22) {  		u32 val = 0; @@ -3964,15 +3960,15 @@ static inline void mvpp2_bm_pool_put(struct mvpp2_port *port, int pool,  			   MVPP2_BM_VIRT_RLS_REG, buf_phys_addr);  	mvpp2_percpu_write(port->priv, cpu,  			   MVPP2_BM_PHY_RLS_REG(pool), buf_dma_addr); + +	put_cpu();  }  /* Refill BM pool */ -static void mvpp2_pool_refill(struct mvpp2_port *port, u32 bm, +static void mvpp2_pool_refill(struct mvpp2_port *port, int pool,  			      dma_addr_t dma_addr,  			      phys_addr_t phys_addr)  { -	int pool = mvpp2_bm_cookie_pool_get(bm); -  	mvpp2_bm_pool_put(port, pool, dma_addr, phys_addr);  } @@ -4192,8 +4188,6 @@ static void mvpp22_port_mii_set(struct mvpp2_port *port)  {  	u32 val; -	return; -  	/* Only GOP port 0 has an XLG MAC */  	if (port->gop_id == 0) {  		val = readl(port->base + MVPP22_XLG_CTRL3_REG); @@ -4548,21 +4542,6 @@ static void mvpp2_rxq_offset_set(struct mvpp2_port *port,  	mvpp2_write(port->priv, MVPP2_RXQ_CONFIG_REG(prxq), val);  } -/* Obtain BM cookie information from descriptor */ -static u32 mvpp2_bm_cookie_build(struct mvpp2_port *port, -				 struct mvpp2_rx_desc *rx_desc) -{ -	int cpu = smp_processor_id(); -	int pool; - -	pool = (mvpp2_rxdesc_status_get(port, rx_desc) & -		MVPP2_RXD_BM_POOL_ID_MASK) >> -		MVPP2_RXD_BM_POOL_ID_OFFS; - -	return ((pool & 0xFF) << MVPP2_BM_COOKIE_POOL_OFFS) | -	       ((cpu & 0xFF) << MVPP2_BM_COOKIE_CPU_OFFS); -} -  /* Tx descriptors helper methods */  /* Get pointer to next Tx descriptor to be processed (send) by HW */ @@ -4790,7 +4769,7 @@ static void mvpp2_txp_max_tx_size_set(struct mvpp2_port *port)  static void mvpp2_rx_pkts_coal_set(struct mvpp2_port *port,  				   struct mvpp2_rx_queue *rxq)  { -	int cpu = smp_processor_id(); +	int cpu = get_cpu();  	if (rxq->pkts_coal > MVPP2_OCCUPIED_THRESH_MASK)  		rxq->pkts_coal = MVPP2_OCCUPIED_THRESH_MASK; @@ -4798,6 +4777,8 @@ static void mvpp2_rx_pkts_coal_set(struct mvpp2_port *port,  	mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_NUM_REG, rxq->id);  	mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_THRESH_REG,  			   rxq->pkts_coal); + +	put_cpu();  }  static u32 mvpp2_usec_to_cycles(u32 usec, unsigned long clk_hz) @@ -4978,7 +4959,7 @@ static int mvpp2_rxq_init(struct mvpp2_port *port,  	mvpp2_write(port->priv, MVPP2_RXQ_STATUS_REG(rxq->id), 0);  	/* Set Rx descriptors queue starting address - indirect access */ -	cpu = smp_processor_id(); +	cpu = get_cpu();  	mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_NUM_REG, rxq->id);  	if (port->priv->hw_version == MVPP21)  		rxq_dma = rxq->descs_dma; @@ -4987,6 +4968,7 @@ static int mvpp2_rxq_init(struct mvpp2_port *port,  	mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_DESC_ADDR_REG, rxq_dma);  	mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_DESC_SIZE_REG, rxq->size);  	mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_INDEX_REG, 0); +	put_cpu();  	/* Set Offset */  	mvpp2_rxq_offset_set(port, rxq->id, NET_SKB_PAD); @@ -5013,9 +4995,13 @@ static void mvpp2_rxq_drop_pkts(struct mvpp2_port *port,  	for (i = 0; i < rx_received; i++) {  		struct mvpp2_rx_desc *rx_desc = mvpp2_rxq_next_desc_get(rxq); -		u32 bm = mvpp2_bm_cookie_build(port, rx_desc); +		u32 status = mvpp2_rxdesc_status_get(port, rx_desc); +		int pool; + +		pool = (status & MVPP2_RXD_BM_POOL_ID_MASK) >> +			MVPP2_RXD_BM_POOL_ID_OFFS; -		mvpp2_pool_refill(port, bm, +		mvpp2_pool_refill(port, pool,  				  mvpp2_rxdesc_dma_addr_get(port, rx_desc),  				  mvpp2_rxdesc_cookie_get(port, rx_desc));  	} @@ -5045,10 +5031,11 @@ static void mvpp2_rxq_deinit(struct mvpp2_port *port,  	 * free descriptor number  	 */  	mvpp2_write(port->priv, MVPP2_RXQ_STATUS_REG(rxq->id), 0); -	cpu = smp_processor_id(); +	cpu = get_cpu();  	mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_NUM_REG, rxq->id);  	mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_DESC_ADDR_REG, 0);  	mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_DESC_SIZE_REG, 0); +	put_cpu();  }  /* Create and initialize a Tx queue */ @@ -5071,7 +5058,7 @@ static int mvpp2_txq_init(struct mvpp2_port *port,  	txq->last_desc = txq->size - 1;  	/* Set Tx descriptors queue starting address - indirect access */ -	cpu = smp_processor_id(); +	cpu = get_cpu();  	mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_NUM_REG, txq->id);  	mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_DESC_ADDR_REG,  			   txq->descs_dma); @@ -5096,6 +5083,7 @@ static int mvpp2_txq_init(struct mvpp2_port *port,  	mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_PREF_BUF_REG,  			   MVPP2_PREF_BUF_PTR(desc) | MVPP2_PREF_BUF_SIZE_16 |  			   MVPP2_PREF_BUF_THRESH(desc_per_txq / 2)); +	put_cpu();  	/* WRR / EJP configuration - indirect access */  	tx_port_num = mvpp2_egress_port(port); @@ -5166,10 +5154,11 @@ static void mvpp2_txq_deinit(struct mvpp2_port *port,  	mvpp2_write(port->priv, MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(txq->id), 0);  	/* Set Tx descriptors queue starting address and size */ -	cpu = smp_processor_id(); +	cpu = get_cpu();  	mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_NUM_REG, txq->id);  	mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_DESC_ADDR_REG, 0);  	mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_DESC_SIZE_REG, 0); +	put_cpu();  }  /* Cleanup Tx ports */ @@ -5179,7 +5168,7 @@ static void mvpp2_txq_clean(struct mvpp2_port *port, struct mvpp2_tx_queue *txq)  	int delay, pending, cpu;  	u32 val; -	cpu = smp_processor_id(); +	cpu = get_cpu();  	mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_NUM_REG, txq->id);  	val = mvpp2_percpu_read(port->priv, cpu, MVPP2_TXQ_PREF_BUF_REG);  	val |= MVPP2_TXQ_DRAIN_EN_MASK; @@ -5206,6 +5195,7 @@ static void mvpp2_txq_clean(struct mvpp2_port *port, struct mvpp2_tx_queue *txq)  	val &= ~MVPP2_TXQ_DRAIN_EN_MASK;  	mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_PREF_BUF_REG, val); +	put_cpu();  	for_each_present_cpu(cpu) {  		txq_pcpu = per_cpu_ptr(txq->pcpu, cpu); @@ -5453,7 +5443,7 @@ static void mvpp2_rx_csum(struct mvpp2_port *port, u32 status,  /* Reuse skb if possible, or allocate a new skb and add it to BM pool */  static int mvpp2_rx_refill(struct mvpp2_port *port, -			   struct mvpp2_bm_pool *bm_pool, u32 bm) +			   struct mvpp2_bm_pool *bm_pool, int pool)  {  	dma_addr_t dma_addr;  	phys_addr_t phys_addr; @@ -5465,7 +5455,7 @@ static int mvpp2_rx_refill(struct mvpp2_port *port,  	if (!buf)  		return -ENOMEM; -	mvpp2_pool_refill(port, bm, dma_addr, phys_addr); +	mvpp2_pool_refill(port, pool, dma_addr, phys_addr);  	return 0;  } @@ -5523,7 +5513,7 @@ static int mvpp2_rx(struct mvpp2_port *port, int rx_todo,  		unsigned int frag_size;  		dma_addr_t dma_addr;  		phys_addr_t phys_addr; -		u32 bm, rx_status; +		u32 rx_status;  		int pool, rx_bytes, err;  		void *data; @@ -5535,8 +5525,8 @@ static int mvpp2_rx(struct mvpp2_port *port, int rx_todo,  		phys_addr = mvpp2_rxdesc_cookie_get(port, rx_desc);  		data = (void *)phys_to_virt(phys_addr); -		bm = mvpp2_bm_cookie_build(port, rx_desc); -		pool = mvpp2_bm_cookie_pool_get(bm); +		pool = (rx_status & MVPP2_RXD_BM_POOL_ID_MASK) >> +			MVPP2_RXD_BM_POOL_ID_OFFS;  		bm_pool = &port->priv->bm_pools[pool];  		/* In case of an error, release the requested buffer pointer @@ -5549,7 +5539,7 @@ err_drop_frame:  			dev->stats.rx_errors++;  			mvpp2_rx_error(port, rx_desc);  			/* Return the buffer to the pool */ -			mvpp2_pool_refill(port, bm, dma_addr, phys_addr); +			mvpp2_pool_refill(port, pool, dma_addr, phys_addr);  			continue;  		} @@ -5564,7 +5554,7 @@ err_drop_frame:  			goto err_drop_frame;  		} -		err = mvpp2_rx_refill(port, bm_pool, bm); +		err = mvpp2_rx_refill(port, bm_pool, pool);  		if (err) {  			netdev_err(port->dev, "failed to refill BM pools\n");  			goto err_drop_frame; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h index f4b95dbd1c7f..a0516b0a5273 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h @@ -458,13 +458,15 @@ struct mlx5e_mpw_info {  struct mlx5e_rx_am_stats {  	int ppms; /* packets per msec */ +	int bpms; /* bytes per msec */  	int epms; /* events per msec */  };  struct mlx5e_rx_am_sample { -	ktime_t		time; -	unsigned int	pkt_ctr; -	u16		event_ctr; +	ktime_t	time; +	u32	pkt_ctr; +	u32	byte_ctr; +	u16	event_ctr;  };  struct mlx5e_rx_am { /* Adaptive Moderation */ diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c index 02dd3a95ed8f..acf32fe952cd 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c @@ -183,28 +183,27 @@ static void mlx5e_am_exit_parking(struct mlx5e_rx_am *am)  	mlx5e_am_step(am);  } +#define IS_SIGNIFICANT_DIFF(val, ref) \ +	(((100 * abs((val) - (ref))) / (ref)) > 10) /* more than 10% difference */ +  static int mlx5e_am_stats_compare(struct mlx5e_rx_am_stats *curr,  				  struct mlx5e_rx_am_stats *prev)  { -	int diff; - -	if (!prev->ppms) -		return curr->ppms ? MLX5E_AM_STATS_BETTER : +	if (!prev->bpms) +		return curr->bpms ? MLX5E_AM_STATS_BETTER :  				    MLX5E_AM_STATS_SAME; -	diff = curr->ppms - prev->ppms; -	if (((100 * abs(diff)) / prev->ppms) > 10) /* more than 10% diff */ -		return (diff > 0) ? MLX5E_AM_STATS_BETTER : -				    MLX5E_AM_STATS_WORSE; +	if (IS_SIGNIFICANT_DIFF(curr->bpms, prev->bpms)) +		return (curr->bpms > prev->bpms) ? MLX5E_AM_STATS_BETTER : +						   MLX5E_AM_STATS_WORSE; -	if (!prev->epms) -		return curr->epms ? MLX5E_AM_STATS_WORSE : -				    MLX5E_AM_STATS_SAME; +	if (IS_SIGNIFICANT_DIFF(curr->ppms, prev->ppms)) +		return (curr->ppms > prev->ppms) ? MLX5E_AM_STATS_BETTER : +						   MLX5E_AM_STATS_WORSE; -	diff = curr->epms - prev->epms; -	if (((100 * abs(diff)) / prev->epms) > 10) /* more than 10% diff */ -		return (diff < 0) ? MLX5E_AM_STATS_BETTER : -				    MLX5E_AM_STATS_WORSE; +	if (IS_SIGNIFICANT_DIFF(curr->epms, prev->epms)) +		return (curr->epms < prev->epms) ? MLX5E_AM_STATS_BETTER : +						   MLX5E_AM_STATS_WORSE;  	return MLX5E_AM_STATS_SAME;  } @@ -266,10 +265,13 @@ static void mlx5e_am_sample(struct mlx5e_rq *rq,  {  	s->time	     = ktime_get();  	s->pkt_ctr   = rq->stats.packets; +	s->byte_ctr  = rq->stats.bytes;  	s->event_ctr = rq->cq.event_ctr;  }  #define MLX5E_AM_NEVENTS 64 +#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE) +#define BIT_GAP(bits, end, start) ((((end) - (start)) + BIT_ULL(bits)) & (BIT_ULL(bits) - 1))  static void mlx5e_am_calc_stats(struct mlx5e_rx_am_sample *start,  				struct mlx5e_rx_am_sample *end, @@ -277,13 +279,17 @@ static void mlx5e_am_calc_stats(struct mlx5e_rx_am_sample *start,  {  	/* u32 holds up to 71 minutes, should be enough */  	u32 delta_us = ktime_us_delta(end->time, start->time); -	unsigned int npkts = end->pkt_ctr - start->pkt_ctr; +	u32 npkts = BIT_GAP(BITS_PER_TYPE(u32), end->pkt_ctr, start->pkt_ctr); +	u32 nbytes = BIT_GAP(BITS_PER_TYPE(u32), end->byte_ctr, +			     start->byte_ctr);  	if (!delta_us)  		return; -	curr_stats->ppms =            (npkts * USEC_PER_MSEC) / delta_us; -	curr_stats->epms = (MLX5E_AM_NEVENTS * USEC_PER_MSEC) / delta_us; +	curr_stats->ppms = DIV_ROUND_UP(npkts * USEC_PER_MSEC, delta_us); +	curr_stats->bpms = DIV_ROUND_UP(nbytes * USEC_PER_MSEC, delta_us); +	curr_stats->epms = DIV_ROUND_UP(MLX5E_AM_NEVENTS * USEC_PER_MSEC, +					delta_us);  }  void mlx5e_rx_am_work(struct work_struct *work) @@ -308,7 +314,8 @@ void mlx5e_rx_am(struct mlx5e_rq *rq)  	switch (am->state) {  	case MLX5E_AM_MEASURE_IN_PROGRESS: -		nevents = rq->cq.event_ctr - am->start_sample.event_ctr; +		nevents = BIT_GAP(BITS_PER_TYPE(u16), rq->cq.event_ctr, +				  am->start_sample.event_ctr);  		if (nevents < MLX5E_AM_NEVENTS)  			break;  		mlx5e_am_sample(rq, &end_sample); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h index 53e4992d6511..f81c3aa60b46 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h @@ -417,20 +417,13 @@ struct mlx5e_stats {  };  static const struct counter_desc mlx5e_pme_status_desc[] = { -	{ "module_plug", 0 },  	{ "module_unplug", 8 },  };  static const struct counter_desc mlx5e_pme_error_desc[] = { -	{ "module_pwr_budget_exd", 0 },  /* power budget exceed */ -	{ "module_long_range", 8 },      /* long range for non MLNX cable */ -	{ "module_bus_stuck", 16 },      /* bus stuck (I2C or data shorted) */ -	{ "module_no_eeprom", 24 },      /* no eeprom/retry time out */ -	{ "module_enforce_part", 32 },   /* enforce part number list */ -	{ "module_unknown_id", 40 },     /* unknown identifier */ -	{ "module_high_temp", 48 },      /* high temperature */ +	{ "module_bus_stuck", 16 },       /* bus stuck (I2C or data shorted) */ +	{ "module_high_temp", 48 },       /* high temperature */  	{ "module_bad_shorted", 56 },    /* bad or shorted cable/module */ -	{ "module_unknown_status", 64 },  };  #endif /* __MLX5_EN_STATS_H__ */ diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index 6c636c21d24f..6380c2db355a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@ -860,7 +860,7 @@ struct mlx5_flow_table *mlx5_create_vport_flow_table(struct mlx5_flow_namespace  	ft_attr.level   = level;  	ft_attr.prio    = prio; -	return __mlx5_create_flow_table(ns, &ft_attr, FS_FT_OP_MOD_NORMAL, 0); +	return __mlx5_create_flow_table(ns, &ft_attr, FS_FT_OP_MOD_NORMAL, vport);  }  struct mlx5_flow_table* diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c index 80b23333de7a..c6679b21884e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/health.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c @@ -290,10 +290,8 @@ static void poll_health(unsigned long data)  	struct mlx5_core_health *health = &dev->priv.health;  	u32 count; -	if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) { -		mod_timer(&health->timer, get_next_poll_jiffies()); -		return; -	} +	if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) +		goto out;  	count = ioread32be(health->health_counter);  	if (count == health->prev) @@ -305,8 +303,6 @@ static void poll_health(unsigned long data)  	if (health->miss_counter == MAX_MISSES) {  		dev_err(&dev->pdev->dev, "device's health compromised - reached miss count\n");  		print_health_info(dev); -	} else { -		mod_timer(&health->timer, get_next_poll_jiffies());  	}  	if (in_fatal(dev) && !health->sick) { @@ -314,6 +310,9 @@ static void poll_health(unsigned long data)  		print_health_info(dev);  		mlx5_trigger_health_work(dev);  	} + +out: +	mod_timer(&health->timer, get_next_poll_jiffies());  }  void mlx5_start_health_poll(struct mlx5_core_dev *dev) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 9274d93d3183..dc890944c4ea 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -538,8 +538,10 @@ static int handle_hca_cap(struct mlx5_core_dev *dev)  	/* disable cmdif checksum */  	MLX5_SET(cmd_hca_cap, set_hca_cap, cmdif_checksum, 0); -	/* If the HCA supports 4K UARs use it */ -	if (MLX5_CAP_GEN_MAX(dev, uar_4k)) +	/* Enable 4K UAR only when HCA supports it and page size is bigger +	 * than 4K. +	 */ +	if (MLX5_CAP_GEN_MAX(dev, uar_4k) && PAGE_SIZE > 4096)  		MLX5_SET(cmd_hca_cap, set_hca_cap, uar_4k, 1);  	MLX5_SET(cmd_hca_cap, set_hca_cap, log_uar_page_sz, PAGE_SHIFT - 12); diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c index aa6476439aee..e0ef02f9503b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c @@ -214,13 +214,13 @@ static int dwmac4_wrback_get_tx_timestamp_status(struct dma_desc *p)  {  	/* Context type from W/B descriptor must be zero */  	if (le32_to_cpu(p->des3) & TDES3_CONTEXT_TYPE) -		return -EINVAL; +		return 0;  	/* Tx Timestamp Status is 1 so des0 and des1'll have valid values */  	if (le32_to_cpu(p->des3) & TDES3_TIMESTAMP_STATUS) -		return 0; +		return 1; -	return 1; +	return 0;  }  static inline u64 dwmac4_get_timestamp(void *desc, u32 ats) @@ -282,7 +282,10 @@ static int dwmac4_wrback_get_rx_timestamp_status(void *desc, u32 ats)  		}  	}  exit: -	return ret; +	if (likely(ret == 0)) +		return 1; + +	return 0;  }  static void dwmac4_rd_init_rx_desc(struct dma_desc *p, int disable_rx_ic, diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index f446f368dd20..6a1cb59728fe 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -445,14 +445,14 @@ static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv,  		return;  	/* check tx tstamp status */ -	if (!priv->hw->desc->get_tx_timestamp_status(p)) { +	if (priv->hw->desc->get_tx_timestamp_status(p)) {  		/* get the valid tstamp */  		ns = priv->hw->desc->get_timestamp(p, priv->adv_ts);  		memset(&shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps));  		shhwtstamp.hwtstamp = ns_to_ktime(ns); -		netdev_info(priv->dev, "get valid TX hw timestamp %llu\n", ns); +		netdev_dbg(priv->dev, "get valid TX hw timestamp %llu\n", ns);  		/* pass tstamp to stack */  		skb_tstamp_tx(skb, &shhwtstamp);  	} @@ -479,19 +479,19 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p,  		return;  	/* Check if timestamp is available */ -	if (!priv->hw->desc->get_rx_timestamp_status(p, priv->adv_ts)) { +	if (priv->hw->desc->get_rx_timestamp_status(p, priv->adv_ts)) {  		/* For GMAC4, the valid timestamp is from CTX next desc. */  		if (priv->plat->has_gmac4)  			ns = priv->hw->desc->get_timestamp(np, priv->adv_ts);  		else  			ns = priv->hw->desc->get_timestamp(p, priv->adv_ts); -		netdev_info(priv->dev, "get valid RX hw timestamp %llu\n", ns); +		netdev_dbg(priv->dev, "get valid RX hw timestamp %llu\n", ns);  		shhwtstamp = skb_hwtstamps(skb);  		memset(shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps));  		shhwtstamp->hwtstamp = ns_to_ktime(ns);  	} else  { -		netdev_err(priv->dev, "cannot get RX hw timestamp\n"); +		netdev_dbg(priv->dev, "cannot get RX hw timestamp\n");  	}  } @@ -557,7 +557,10 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)  			/* PTP v1, UDP, any kind of event packet */  			config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;  			/* take time stamp for all event messages */ -			snap_type_sel = PTP_TCR_SNAPTYPSEL_1; +			if (priv->plat->has_gmac4) +				snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1; +			else +				snap_type_sel = PTP_TCR_SNAPTYPSEL_1;  			ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;  			ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; @@ -589,7 +592,10 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)  			config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;  			ptp_v2 = PTP_TCR_TSVER2ENA;  			/* take time stamp for all event messages */ -			snap_type_sel = PTP_TCR_SNAPTYPSEL_1; +			if (priv->plat->has_gmac4) +				snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1; +			else +				snap_type_sel = PTP_TCR_SNAPTYPSEL_1;  			ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;  			ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; @@ -623,7 +629,10 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)  			config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;  			ptp_v2 = PTP_TCR_TSVER2ENA;  			/* take time stamp for all event messages */ -			snap_type_sel = PTP_TCR_SNAPTYPSEL_1; +			if (priv->plat->has_gmac4) +				snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1; +			else +				snap_type_sel = PTP_TCR_SNAPTYPSEL_1;  			ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;  			ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h index 48fb72fc423c..f4b31d69f60e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h @@ -59,7 +59,8 @@  /* Enable Snapshot for Messages Relevant to Master */  #define	PTP_TCR_TSMSTRENA	BIT(15)  /* Select PTP packets for Taking Snapshots */ -#define	PTP_TCR_SNAPTYPSEL_1	GENMASK(17, 16) +#define	PTP_TCR_SNAPTYPSEL_1	BIT(16) +#define	PTP_GMAC4_TCR_SNAPTYPSEL_1	GENMASK(17, 16)  /* Enable MAC address for PTP Frame Filtering */  #define	PTP_TCR_TSENMACADDR	BIT(18) diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index ff626dbde23f..7bcf1b52020e 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -1019,7 +1019,7 @@ static void geneve_setup(struct net_device *dev)  	dev->netdev_ops = &geneve_netdev_ops;  	dev->ethtool_ops = &geneve_ethtool_ops; -	dev->destructor = free_netdev; +	dev->needs_free_netdev = true;  	SET_NETDEV_DEVTYPE(dev, &geneve_type); diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index 7b652bb7ebe4..ca110cd2a4e4 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -611,7 +611,7 @@ static const struct net_device_ops gtp_netdev_ops = {  static void gtp_link_setup(struct net_device *dev)  {  	dev->netdev_ops		= >p_netdev_ops; -	dev->destructor		= free_netdev; +	dev->needs_free_netdev	= true;  	dev->hard_header_len = 0;  	dev->addr_len = 0; diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 922bf440e9f1..021a8ec411ab 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -311,7 +311,7 @@ static void sp_setup(struct net_device *dev)  {  	/* Finish setting up the DEVICE info. */  	dev->netdev_ops		= &sp_netdev_ops; -	dev->destructor		= free_netdev; +	dev->needs_free_netdev	= true;  	dev->mtu		= SIXP_MTU;  	dev->hard_header_len	= AX25_MAX_HEADER_LEN;  	dev->header_ops 	= &ax25_header_ops; diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c index f62e7f325cf9..78a6414c5fd9 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/drivers/net/hamradio/bpqether.c @@ -476,7 +476,7 @@ static const struct net_device_ops bpq_netdev_ops = {  static void bpq_setup(struct net_device *dev)  {  	dev->netdev_ops	     = &bpq_netdev_ops; -	dev->destructor	     = free_netdev; +	dev->needs_free_netdev = true;  	memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);  	memcpy(dev->dev_addr,  &ax25_defaddr, AX25_ADDR_LEN); diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index f82d54e0208c..b30a3c2f772b 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -171,6 +171,8 @@ struct rndis_device {  	spinlock_t request_lock;  	struct list_head req_list; +	struct work_struct mcast_work; +  	u8 hw_mac_adr[ETH_ALEN];  	u8 rss_key[NETVSC_HASH_KEYLEN];  	u16 ind_table[ITAB_NUM]; @@ -201,6 +203,7 @@ int rndis_filter_open(struct netvsc_device *nvdev);  int rndis_filter_close(struct netvsc_device *nvdev);  int rndis_filter_device_add(struct hv_device *dev,  			    struct netvsc_device_info *info); +void rndis_filter_update(struct netvsc_device *nvdev);  void rndis_filter_device_remove(struct hv_device *dev,  				struct netvsc_device *nvdev);  int rndis_filter_set_rss_param(struct rndis_device *rdev, @@ -211,7 +214,6 @@ int rndis_filter_receive(struct net_device *ndev,  			 struct vmbus_channel *channel,  			 void *data, u32 buflen); -int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter);  int rndis_filter_set_device_mac(struct net_device *ndev, char *mac);  void netvsc_switch_datapath(struct net_device *nv_dev, bool vf); @@ -696,7 +698,6 @@ struct net_device_context {  	/* list protection */  	spinlock_t lock; -	struct work_struct work;  	u32 msg_enable; /* debug level */  	u32 tx_checksum_mask; diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 436a3ad55cfd..b65a97ecb78e 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -58,37 +58,12 @@ static int debug = -1;  module_param(debug, int, S_IRUGO);  MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); -static void do_set_multicast(struct work_struct *w) -{ -	struct net_device_context *ndevctx = -		container_of(w, struct net_device_context, work); -	struct hv_device *device_obj = ndevctx->device_ctx; -	struct net_device *ndev = hv_get_drvdata(device_obj); -	struct netvsc_device *nvdev = rcu_dereference(ndevctx->nvdev); -	struct rndis_device *rdev; - -	if (!nvdev) -		return; - -	rdev = nvdev->extension; -	if (rdev == NULL) -		return; - -	if (ndev->flags & IFF_PROMISC) -		rndis_filter_set_packet_filter(rdev, -			NDIS_PACKET_TYPE_PROMISCUOUS); -	else -		rndis_filter_set_packet_filter(rdev, -			NDIS_PACKET_TYPE_BROADCAST | -			NDIS_PACKET_TYPE_ALL_MULTICAST | -			NDIS_PACKET_TYPE_DIRECTED); -} -  static void netvsc_set_multicast_list(struct net_device *net)  {  	struct net_device_context *net_device_ctx = netdev_priv(net); +	struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev); -	schedule_work(&net_device_ctx->work); +	rndis_filter_update(nvdev);  }  static int netvsc_open(struct net_device *net) @@ -125,8 +100,6 @@ static int netvsc_close(struct net_device *net)  	netif_tx_disable(net); -	/* Make sure netvsc_set_multicast_list doesn't re-enable filter! */ -	cancel_work_sync(&net_device_ctx->work);  	ret = rndis_filter_close(nvdev);  	if (ret != 0) {  		netdev_err(net, "unable to close device (ret %d).\n", ret); @@ -1003,7 +976,7 @@ static const struct {  static int netvsc_get_sset_count(struct net_device *dev, int string_set)  {  	struct net_device_context *ndc = netdev_priv(dev); -	struct netvsc_device *nvdev = rcu_dereference(ndc->nvdev); +	struct netvsc_device *nvdev = rtnl_dereference(ndc->nvdev);  	if (!nvdev)  		return -ENODEV; @@ -1133,11 +1106,22 @@ netvsc_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,  }  #ifdef CONFIG_NET_POLL_CONTROLLER -static void netvsc_poll_controller(struct net_device *net) +static void netvsc_poll_controller(struct net_device *dev)  { -	/* As netvsc_start_xmit() works synchronous we don't have to -	 * trigger anything here. -	 */ +	struct net_device_context *ndc = netdev_priv(dev); +	struct netvsc_device *ndev; +	int i; + +	rcu_read_lock(); +	ndev = rcu_dereference(ndc->nvdev); +	if (ndev) { +		for (i = 0; i < ndev->num_chn; i++) { +			struct netvsc_channel *nvchan = &ndev->chan_table[i]; + +			napi_schedule(&nvchan->napi); +		} +	} +	rcu_read_unlock();  }  #endif @@ -1527,7 +1511,6 @@ static int netvsc_probe(struct hv_device *dev,  	hv_set_drvdata(dev, net);  	INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_link_change); -	INIT_WORK(&net_device_ctx->work, do_set_multicast);  	spin_lock_init(&net_device_ctx->lock);  	INIT_LIST_HEAD(&net_device_ctx->reconfig_events); @@ -1597,7 +1580,6 @@ static int netvsc_remove(struct hv_device *dev)  	netif_device_detach(net);  	cancel_delayed_work_sync(&ndev_ctx->dwork); -	cancel_work_sync(&ndev_ctx->work);  	/*  	 * Call to the vsc driver to let it know that the device is being diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index f9d5b0b8209a..cb79cd081f42 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -31,6 +31,7 @@  #include "hyperv_net.h" +static void rndis_set_multicast(struct work_struct *w);  #define RNDIS_EXT_LEN PAGE_SIZE  struct rndis_request { @@ -76,6 +77,7 @@ static struct rndis_device *get_rndis_device(void)  	spin_lock_init(&device->request_lock);  	INIT_LIST_HEAD(&device->req_list); +	INIT_WORK(&device->mcast_work, rndis_set_multicast);  	device->state = RNDIS_DEV_UNINITIALIZED; @@ -815,7 +817,8 @@ static int rndis_filter_query_link_speed(struct rndis_device *dev)  	return ret;  } -int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter) +static int rndis_filter_set_packet_filter(struct rndis_device *dev, +					  u32 new_filter)  {  	struct rndis_request *request;  	struct rndis_set_request *set; @@ -846,6 +849,28 @@ int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter)  	return ret;  } +static void rndis_set_multicast(struct work_struct *w) +{ +	struct rndis_device *rdev +		= container_of(w, struct rndis_device, mcast_work); + +	if (rdev->ndev->flags & IFF_PROMISC) +		rndis_filter_set_packet_filter(rdev, +					       NDIS_PACKET_TYPE_PROMISCUOUS); +	else +		rndis_filter_set_packet_filter(rdev, +					       NDIS_PACKET_TYPE_BROADCAST | +					       NDIS_PACKET_TYPE_ALL_MULTICAST | +					       NDIS_PACKET_TYPE_DIRECTED); +} + +void rndis_filter_update(struct netvsc_device *nvdev) +{ +	struct rndis_device *rdev = nvdev->extension; + +	schedule_work(&rdev->mcast_work); +} +  static int rndis_filter_init_device(struct rndis_device *dev)  {  	struct rndis_request *request; @@ -973,6 +998,9 @@ static int rndis_filter_close_device(struct rndis_device *dev)  	if (dev->state != RNDIS_DEV_DATAINITIALIZED)  		return 0; +	/* Make sure rndis_set_multicast doesn't re-enable filter! */ +	cancel_work_sync(&dev->mcast_work); +  	ret = rndis_filter_set_packet_filter(dev, 0);  	if (ret == -ENODEV)  		ret = 0; diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 312fce7302d3..144ea5ae8ab4 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -207,7 +207,6 @@ static void ifb_dev_free(struct net_device *dev)  		__skb_queue_purge(&txp->tq);  	}  	kfree(dp->tx_private); -	free_netdev(dev);  }  static void ifb_setup(struct net_device *dev) @@ -230,7 +229,8 @@ static void ifb_setup(struct net_device *dev)  	dev->priv_flags &= ~IFF_TX_SKB_SHARING;  	netif_keep_dst(dev);  	eth_hw_addr_random(dev); -	dev->destructor = ifb_dev_free; +	dev->needs_free_netdev = true; +	dev->priv_destructor = ifb_dev_free;  }  static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev) diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c index e4141d62b5c3..dc888dd344eb 100644 --- a/drivers/net/ipvlan/ipvlan_main.c +++ b/drivers/net/ipvlan/ipvlan_main.c @@ -632,7 +632,7 @@ void ipvlan_link_setup(struct net_device *dev)  	dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);  	dev->priv_flags |= IFF_UNICAST_FLT | IFF_NO_QUEUE;  	dev->netdev_ops = &ipvlan_netdev_ops; -	dev->destructor = free_netdev; +	dev->needs_free_netdev = true;  	dev->header_ops = &ipvlan_header_ops;  	dev->ethtool_ops = &ipvlan_ethtool_ops;  } diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 224f65cb576b..30612497643c 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -159,7 +159,6 @@ static void loopback_dev_free(struct net_device *dev)  {  	dev_net(dev)->loopback_dev = NULL;  	free_percpu(dev->lstats); -	free_netdev(dev);  }  static const struct net_device_ops loopback_ops = { @@ -196,7 +195,8 @@ static void loopback_setup(struct net_device *dev)  	dev->ethtool_ops	= &loopback_ethtool_ops;  	dev->header_ops		= ð_header_ops;  	dev->netdev_ops		= &loopback_ops; -	dev->destructor		= loopback_dev_free; +	dev->needs_free_netdev	= true; +	dev->priv_destructor	= loopback_dev_free;  }  /* Setup and register the loopback device. */ diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index b79513b8322f..2067dcc71535 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -2996,7 +2996,6 @@ static void macsec_free_netdev(struct net_device *dev)  	free_percpu(macsec->secy.tx_sc.stats);  	dev_put(real_dev); -	free_netdev(dev);  }  static void macsec_setup(struct net_device *dev) @@ -3006,7 +3005,8 @@ static void macsec_setup(struct net_device *dev)  	dev->max_mtu = ETH_MAX_MTU;  	dev->priv_flags |= IFF_NO_QUEUE;  	dev->netdev_ops = &macsec_netdev_ops; -	dev->destructor = macsec_free_netdev; +	dev->needs_free_netdev = true; +	dev->priv_destructor = macsec_free_netdev;  	SET_NETDEV_DEVTYPE(dev, &macsec_type);  	eth_zero_addr(dev->broadcast); diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index ade1213e8a87..8ca274c6df3d 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -1090,7 +1090,7 @@ void macvlan_common_setup(struct net_device *dev)  	netif_keep_dst(dev);  	dev->priv_flags	       |= IFF_UNICAST_FLT;  	dev->netdev_ops		= &macvlan_netdev_ops; -	dev->destructor		= free_netdev; +	dev->needs_free_netdev	= true;  	dev->header_ops		= &macvlan_hard_header_ops;  	dev->ethtool_ops	= &macvlan_ethtool_ops;  } diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 06ee6395117f..0e27920c2b6b 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -358,7 +358,7 @@ static ssize_t enabled_store(struct config_item *item,  		if (err)  			goto out_unlock; -		pr_info("netconsole: network logging started\n"); +		pr_info("network logging started\n");  	} else {	/* false */  		/* We need to disable the netconsole before cleaning it up  		 * otherwise we might end up in write_msg() with diff --git a/drivers/net/nlmon.c b/drivers/net/nlmon.c index b91603835d26..c4b3362da4a2 100644 --- a/drivers/net/nlmon.c +++ b/drivers/net/nlmon.c @@ -113,7 +113,7 @@ static void nlmon_setup(struct net_device *dev)  	dev->netdev_ops	= &nlmon_ops;  	dev->ethtool_ops = &nlmon_ethtool_ops; -	dev->destructor	= free_netdev; +	dev->needs_free_netdev = true;  	dev->features = NETIF_F_SG | NETIF_F_FRAGLIST |  			NETIF_F_HIGHDMA | NETIF_F_LLTX; diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 65af31f24f01..2dda72004a7d 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -127,6 +127,7 @@ config MDIO_THUNDER  	tristate "ThunderX SOCs MDIO buses"  	depends on 64BIT  	depends on PCI +	depends on !(MDIO_DEVICE=y && PHYLIB=m)  	select MDIO_CAVIUM  	help  	  This driver supports the MDIO interfaces found on Cavium diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index edcdf0d872ed..a9dc366b9b97 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -54,6 +54,8 @@ static const char *phy_speed_to_str(int speed)  		return "5Gbps";  	case SPEED_10000:  		return "10Gbps"; +	case SPEED_14000: +		return "14Gbps";  	case SPEED_20000:  		return "20Gbps";  	case SPEED_25000: diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c index 1da31dc47f86..74b907206aa7 100644 --- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c @@ -629,7 +629,7 @@ static void sl_uninit(struct net_device *dev)  static void sl_free_netdev(struct net_device *dev)  {  	int i = dev->base_addr; -	free_netdev(dev); +  	slip_devs[i] = NULL;  } @@ -651,7 +651,8 @@ static const struct net_device_ops sl_netdev_ops = {  static void sl_setup(struct net_device *dev)  {  	dev->netdev_ops		= &sl_netdev_ops; -	dev->destructor		= sl_free_netdev; +	dev->needs_free_netdev	= true; +	dev->priv_destructor	= sl_free_netdev;  	dev->hard_header_len	= 0;  	dev->addr_len		= 0; @@ -1369,8 +1370,6 @@ static void __exit slip_exit(void)  		if (sl->tty) {  			printk(KERN_ERR "%s: tty discipline still running\n",  			       dev->name); -			/* Intentionally leak the control block. */ -			dev->destructor = NULL;  		}  		unregister_netdev(dev); diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index a3ec1892a286..629a412dc690 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1643,7 +1643,6 @@ static void team_destructor(struct net_device *dev)  	struct team *team = netdev_priv(dev);  	free_percpu(team->pcpu_stats); -	free_netdev(dev);  }  static int team_open(struct net_device *dev) @@ -2073,7 +2072,8 @@ static void team_setup(struct net_device *dev)  	dev->netdev_ops = &team_netdev_ops;  	dev->ethtool_ops = &team_ethtool_ops; -	dev->destructor	= team_destructor; +	dev->needs_free_netdev = true; +	dev->priv_destructor = team_destructor;  	dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);  	dev->priv_flags |= IFF_NO_QUEUE;  	dev->priv_flags |= IFF_TEAM; diff --git a/drivers/net/tun.c b/drivers/net/tun.c index fe660e524af9..ae49f4b99b67 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1561,7 +1561,6 @@ static void tun_free_netdev(struct net_device *dev)  	free_percpu(tun->pcpu_stats);  	tun_flow_uninit(tun);  	security_tun_dev_free_security(tun->security); -	free_netdev(dev);  }  static void tun_setup(struct net_device *dev) @@ -1572,7 +1571,8 @@ static void tun_setup(struct net_device *dev)  	tun->group = INVALID_GID;  	dev->ethtool_ops = &tun_ethtool_ops; -	dev->destructor = tun_free_netdev; +	dev->needs_free_netdev = true; +	dev->priv_destructor = tun_free_netdev;  	/* We prefer our own queue length */  	dev->tx_queue_len = TUN_READQ_SIZE;  } diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c index eb52de8205f0..c7a350bbaaa7 100644 --- a/drivers/net/usb/cdc-phonet.c +++ b/drivers/net/usb/cdc-phonet.c @@ -298,7 +298,7 @@ static void usbpn_setup(struct net_device *dev)  	dev->addr_len		= 1;  	dev->tx_queue_len	= 3; -	dev->destructor		= free_netdev; +	dev->needs_free_netdev	= true;  }  /* diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 8f923a147fa9..32a22f4e8356 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -123,7 +123,7 @@ static void qmimux_setup(struct net_device *dev)  	dev->addr_len        = 0;  	dev->flags           = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;  	dev->netdev_ops      = &qmimux_netdev_ops; -	dev->destructor      = free_netdev; +	dev->needs_free_netdev = true;  }  static struct net_device *qmimux_find_dev(struct usbnet *dev, u8 mux_id) @@ -1192,6 +1192,8 @@ static const struct usb_device_id products[] = {  	{QMI_FIXED_INTF(0x1199, 0x9056, 8)},	/* Sierra Wireless Modem */  	{QMI_FIXED_INTF(0x1199, 0x9057, 8)},  	{QMI_FIXED_INTF(0x1199, 0x9061, 8)},	/* Sierra Wireless Modem */ +	{QMI_FIXED_INTF(0x1199, 0x9063, 8)},	/* Sierra Wireless EM7305 */ +	{QMI_FIXED_INTF(0x1199, 0x9063, 10)},	/* Sierra Wireless EM7305 */  	{QMI_FIXED_INTF(0x1199, 0x9071, 8)},	/* Sierra Wireless MC74xx */  	{QMI_FIXED_INTF(0x1199, 0x9071, 10)},	/* Sierra Wireless MC74xx */  	{QMI_FIXED_INTF(0x1199, 0x9079, 8)},	/* Sierra Wireless EM74xx */ @@ -1206,6 +1208,8 @@ static const struct usb_device_id products[] = {  	{QMI_FIXED_INTF(0x1bc7, 0x1100, 3)},	/* Telit ME910 */  	{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)},	/* Telit LE920 */  	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1201, 2)},	/* Telit LE920, LE920A4 */ +	{QMI_FIXED_INTF(0x1c9e, 0x9801, 3)},	/* Telewell TW-3G HSPA+ */ +	{QMI_FIXED_INTF(0x1c9e, 0x9803, 4)},	/* Telewell TW-3G HSPA+ */  	{QMI_FIXED_INTF(0x1c9e, 0x9b01, 3)},	/* XS Stick W100-2 from 4G Systems */  	{QMI_FIXED_INTF(0x0b3c, 0xc000, 4)},	/* Olivetti Olicard 100 */  	{QMI_FIXED_INTF(0x0b3c, 0xc001, 4)},	/* Olivetti Olicard 120 */ diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 5a02053181d1..8589303b4bf1 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -4454,6 +4454,8 @@ static u8 rtl_get_version(struct usb_interface *intf)  		break;  	} +	dev_dbg(&intf->dev, "Detected version 0x%04x\n", version); +  	return version;  } diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 38f0f03a29c8..0156fe8cac17 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -222,7 +222,6 @@ static int veth_dev_init(struct net_device *dev)  static void veth_dev_free(struct net_device *dev)  {  	free_percpu(dev->vstats); -	free_netdev(dev);  }  #ifdef CONFIG_NET_POLL_CONTROLLER @@ -317,7 +316,8 @@ static void veth_setup(struct net_device *dev)  			       NETIF_F_HW_VLAN_STAG_TX |  			       NETIF_F_HW_VLAN_CTAG_RX |  			       NETIF_F_HW_VLAN_STAG_RX); -	dev->destructor = veth_dev_free; +	dev->needs_free_netdev = true; +	dev->priv_destructor = veth_dev_free;  	dev->max_mtu = ETH_MAX_MTU;  	dev->hw_features = VETH_FEATURES; diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index db882493875c..022c0b5f9844 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c @@ -36,12 +36,14 @@  #include <net/addrconf.h>  #include <net/l3mdev.h>  #include <net/fib_rules.h> +#include <net/netns/generic.h>  #define DRV_NAME	"vrf"  #define DRV_VERSION	"1.0"  #define FIB_RULE_PREF  1000       /* default preference for FIB rules */ -static bool add_fib_rules = true; + +static unsigned int vrf_net_id;  struct net_vrf {  	struct rtable __rcu	*rth; @@ -1348,7 +1350,7 @@ static void vrf_setup(struct net_device *dev)  	dev->netdev_ops = &vrf_netdev_ops;  	dev->l3mdev_ops = &vrf_l3mdev_ops;  	dev->ethtool_ops = &vrf_ethtool_ops; -	dev->destructor = free_netdev; +	dev->needs_free_netdev = true;  	/* Fill in device structure with ethernet-generic values. */  	eth_hw_addr_random(dev); @@ -1394,6 +1396,8 @@ static int vrf_newlink(struct net *src_net, struct net_device *dev,  		       struct nlattr *tb[], struct nlattr *data[])  {  	struct net_vrf *vrf = netdev_priv(dev); +	bool *add_fib_rules; +	struct net *net;  	int err;  	if (!data || !data[IFLA_VRF_TABLE]) @@ -1409,13 +1413,15 @@ static int vrf_newlink(struct net *src_net, struct net_device *dev,  	if (err)  		goto out; -	if (add_fib_rules) { +	net = dev_net(dev); +	add_fib_rules = net_generic(net, vrf_net_id); +	if (*add_fib_rules) {  		err = vrf_add_fib_rules(dev);  		if (err) {  			unregister_netdevice(dev);  			goto out;  		} -		add_fib_rules = false; +		*add_fib_rules = false;  	}  out: @@ -1498,16 +1504,38 @@ static struct notifier_block vrf_notifier_block __read_mostly = {  	.notifier_call = vrf_device_event,  }; +/* Initialize per network namespace state */ +static int __net_init vrf_netns_init(struct net *net) +{ +	bool *add_fib_rules = net_generic(net, vrf_net_id); + +	*add_fib_rules = true; + +	return 0; +} + +static struct pernet_operations vrf_net_ops __net_initdata = { +	.init = vrf_netns_init, +	.id   = &vrf_net_id, +	.size = sizeof(bool), +}; +  static int __init vrf_init_module(void)  {  	int rc;  	register_netdevice_notifier(&vrf_notifier_block); -	rc = rtnl_link_register(&vrf_link_ops); +	rc = register_pernet_subsys(&vrf_net_ops);  	if (rc < 0)  		goto error; +	rc = rtnl_link_register(&vrf_link_ops); +	if (rc < 0) { +		unregister_pernet_subsys(&vrf_net_ops); +		goto error; +	} +  	return 0;  error: diff --git a/drivers/net/vsockmon.c b/drivers/net/vsockmon.c index 7f0136f2dd9d..c28bdce14fd5 100644 --- a/drivers/net/vsockmon.c +++ b/drivers/net/vsockmon.c @@ -135,7 +135,7 @@ static void vsockmon_setup(struct net_device *dev)  	dev->netdev_ops	= &vsockmon_ops;  	dev->ethtool_ops = &vsockmon_ethtool_ops; -	dev->destructor	= free_netdev; +	dev->needs_free_netdev = true;  	dev->features = NETIF_F_SG | NETIF_F_FRAGLIST |  			NETIF_F_HIGHDMA | NETIF_F_LLTX; diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index e045c34ffbeb..25b70cad055c 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -2611,7 +2611,7 @@ static void vxlan_setup(struct net_device *dev)  	eth_hw_addr_random(dev);  	ether_setup(dev); -	dev->destructor = free_netdev; +	dev->needs_free_netdev = true;  	SET_NETDEV_DEVTYPE(dev, &vxlan_type);  	dev->features	|= NETIF_F_LLTX; diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c index 65ee2a6f248c..a0d76f70c428 100644 --- a/drivers/net/wan/dlci.c +++ b/drivers/net/wan/dlci.c @@ -475,7 +475,7 @@ static void dlci_setup(struct net_device *dev)  	dev->flags		= 0;  	dev->header_ops		= &dlci_header_ops;  	dev->netdev_ops		= &dlci_netdev_ops; -	dev->destructor		= free_netdev; +	dev->needs_free_netdev	= true;  	dlp->receive		= dlci_receive; diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c index eb915281197e..78596e42a3f3 100644 --- a/drivers/net/wan/hdlc_fr.c +++ b/drivers/net/wan/hdlc_fr.c @@ -1106,7 +1106,7 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)  		return -EIO;  	} -	dev->destructor = free_netdev; +	dev->needs_free_netdev = true;  	*get_dev_p(pvc, type) = dev;  	if (!used) {  		state(hdlc)->dce_changed = 1; diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c index 9df9ed62beff..63f749078a1f 100644 --- a/drivers/net/wan/lapbether.c +++ b/drivers/net/wan/lapbether.c @@ -306,7 +306,7 @@ static const struct net_device_ops lapbeth_netdev_ops = {  static void lapbeth_setup(struct net_device *dev)  {  	dev->netdev_ops	     = &lapbeth_netdev_ops; -	dev->destructor	     = free_netdev; +	dev->needs_free_netdev = true;  	dev->type            = ARPHRD_X25;  	dev->hard_header_len = 3;  	dev->mtu             = 1000; diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 91ee542de3d7..b90c77ef792e 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -1287,7 +1287,7 @@ void init_netdev(struct net_device *dev)  	struct ath6kl *ar = ath6kl_priv(dev);  	dev->netdev_ops = &ath6kl_netdev_ops; -	dev->destructor = free_netdev; +	dev->needs_free_netdev = true;  	dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;  	dev->needed_headroom = ETH_HLEN; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index a2bf11fc8ecc..b8f042146fc9 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -5222,7 +5222,6 @@ void brcmf_cfg80211_free_netdev(struct net_device *ndev)  	if (vif)  		brcmf_free_vif(vif); -	free_netdev(ndev);  }  static bool brcmf_is_linkup(const struct brcmf_event_msg *e) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index a3d82368f1a9..511d190c6cca 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -624,7 +624,8 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,  		if (!ndev)  			return ERR_PTR(-ENOMEM); -		ndev->destructor = brcmf_cfg80211_free_netdev; +		ndev->needs_free_netdev = true; +		ndev->priv_destructor = brcmf_cfg80211_free_netdev;  		ifp = netdev_priv(ndev);  		ifp->ndev = ndev;  		/* store mapping ifidx to bsscfgidx */ diff --git a/drivers/net/wireless/intersil/hostap/hostap_main.c b/drivers/net/wireless/intersil/hostap/hostap_main.c index 544fc09dcb62..1372b20f931e 100644 --- a/drivers/net/wireless/intersil/hostap/hostap_main.c +++ b/drivers/net/wireless/intersil/hostap/hostap_main.c @@ -73,7 +73,7 @@ struct net_device * hostap_add_interface(struct local_info *local,  	dev->mem_end = mdev->mem_end;  	hostap_setup_dev(dev, local, type); -	dev->destructor = free_netdev; +	dev->needs_free_netdev = true;  	sprintf(dev->name, "%s%s", prefix, name);  	if (!rtnl_locked) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 002b25cff5b6..c854a557998b 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -2861,7 +2861,7 @@ static const struct net_device_ops hwsim_netdev_ops = {  static void hwsim_mon_setup(struct net_device *dev)  {  	dev->netdev_ops = &hwsim_netdev_ops; -	dev->destructor = free_netdev; +	dev->needs_free_netdev = true;  	ether_setup(dev);  	dev->priv_flags |= IFF_NO_QUEUE;  	dev->type = ARPHRD_IEEE80211_RADIOTAP; diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index 2c42191293c3..f2600b827e81 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -1284,7 +1284,7 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv,  			      struct net_device *dev)  {  	dev->netdev_ops = &mwifiex_netdev_ops; -	dev->destructor = free_netdev; +	dev->needs_free_netdev = true;  	/* Initialize private structure */  	priv->current_key_index = 0;  	priv->media_connected = false; diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.c b/drivers/net/wireless/quantenna/qtnfmac/core.c index c5ac252464f4..f053532c0e87 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/core.c +++ b/drivers/net/wireless/quantenna/qtnfmac/core.c @@ -316,7 +316,7 @@ int qtnf_core_net_attach(struct qtnf_wmac *mac, struct qtnf_vif *vif,  	vif->netdev = dev;  	dev->netdev_ops = &qtnf_netdev_ops; -	dev->destructor = free_netdev; +	dev->needs_free_netdev = true;  	dev_net_set(dev, wiphy_net(wiphy));  	dev->ieee80211_ptr = &vif->wdev;  	dev->ieee80211_ptr->iftype = iftype; diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index a60926410438..903d5813023a 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -56,7 +56,7 @@ MODULE_PARM_DESC(max_retries, "max number of retries a command may have");  static int nvme_char_major;  module_param(nvme_char_major, int, 0); -static unsigned long default_ps_max_latency_us = 25000; +static unsigned long default_ps_max_latency_us = 100000;  module_param(default_ps_max_latency_us, ulong, 0644);  MODULE_PARM_DESC(default_ps_max_latency_us,  		 "max power saving latency for new devices; use PM QOS to change per device"); @@ -1342,7 +1342,7 @@ static void nvme_configure_apst(struct nvme_ctrl *ctrl)  	 * transitioning between power states.  Therefore, when running  	 * in any given state, we will enter the next lower-power  	 * non-operational state after waiting 50 * (enlat + exlat) -	 * microseconds, as long as that state's total latency is under +	 * microseconds, as long as that state's exit latency is under  	 * the requested maximum latency.  	 *  	 * We will not autonomously enter any non-operational state for @@ -1387,7 +1387,7 @@ static void nvme_configure_apst(struct nvme_ctrl *ctrl)  		 * lowest-power state, not the number of states.  		 */  		for (state = (int)ctrl->npss; state >= 0; state--) { -			u64 total_latency_us, transition_ms; +			u64 total_latency_us, exit_latency_us, transition_ms;  			if (target)  				table->entries[state] = target; @@ -1408,12 +1408,15 @@ static void nvme_configure_apst(struct nvme_ctrl *ctrl)  			      NVME_PS_FLAGS_NON_OP_STATE))  				continue; -			total_latency_us = -				(u64)le32_to_cpu(ctrl->psd[state].entry_lat) + -				+ le32_to_cpu(ctrl->psd[state].exit_lat); -			if (total_latency_us > ctrl->ps_max_latency_us) +			exit_latency_us = +				(u64)le32_to_cpu(ctrl->psd[state].exit_lat); +			if (exit_latency_us > ctrl->ps_max_latency_us)  				continue; +			total_latency_us = +				exit_latency_us + +				le32_to_cpu(ctrl->psd[state].entry_lat); +  			/*  			 * This state is good.  Use it as the APST idle  			 * target for higher power states. @@ -2438,6 +2441,10 @@ void nvme_kill_queues(struct nvme_ctrl *ctrl)  	struct nvme_ns *ns;  	mutex_lock(&ctrl->namespaces_mutex); + +	/* Forcibly start all queues to avoid having stuck requests */ +	blk_mq_start_hw_queues(ctrl->admin_q); +  	list_for_each_entry(ns, &ctrl->namespaces, list) {  		/*  		 * Revalidating a dead namespace sets capacity to 0. This will diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 5b14cbefb724..92964cef0f4b 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -1139,6 +1139,7 @@ nvme_fc_xmt_disconnect_assoc(struct nvme_fc_ctrl *ctrl)  /* *********************** NVME Ctrl Routines **************************** */  static void __nvme_fc_final_op_cleanup(struct request *rq); +static void nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg);  static int  nvme_fc_reinit_request(void *data, struct request *rq) @@ -1265,7 +1266,7 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req)  	struct nvme_command *sqe = &op->cmd_iu.sqe;  	__le16 status = cpu_to_le16(NVME_SC_SUCCESS << 1);  	union nvme_result result; -	bool complete_rq; +	bool complete_rq, terminate_assoc = true;  	/*  	 * WARNING: @@ -1294,6 +1295,14 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req)  	 * fabricate a CQE, the following fields will not be set as they  	 * are not referenced:  	 *      cqe.sqid,  cqe.sqhd,  cqe.command_id +	 * +	 * Failure or error of an individual i/o, in a transport +	 * detected fashion unrelated to the nvme completion status, +	 * potentially cause the initiator and target sides to get out +	 * of sync on SQ head/tail (aka outstanding io count allowed). +	 * Per FC-NVME spec, failure of an individual command requires +	 * the connection to be terminated, which in turn requires the +	 * association to be terminated.  	 */  	fc_dma_sync_single_for_cpu(ctrl->lport->dev, op->fcp_req.rspdma, @@ -1359,6 +1368,8 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req)  		goto done;  	} +	terminate_assoc = false; +  done:  	if (op->flags & FCOP_FLAGS_AEN) {  		nvme_complete_async_event(&queue->ctrl->ctrl, status, &result); @@ -1366,7 +1377,7 @@ done:  		atomic_set(&op->state, FCPOP_STATE_IDLE);  		op->flags = FCOP_FLAGS_AEN;	/* clear other flags */  		nvme_fc_ctrl_put(ctrl); -		return; +		goto check_error;  	}  	complete_rq = __nvme_fc_fcpop_chk_teardowns(ctrl, op); @@ -1379,6 +1390,10 @@ done:  		nvme_end_request(rq, status, result);  	} else  		__nvme_fc_final_op_cleanup(rq); + +check_error: +	if (terminate_assoc) +		nvme_fc_error_recovery(ctrl, "transport detected io error");  }  static int @@ -2791,6 +2806,7 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,  		ctrl->ctrl.opts = NULL;  		/* initiate nvme ctrl ref counting teardown */  		nvme_uninit_ctrl(&ctrl->ctrl); +		nvme_put_ctrl(&ctrl->ctrl);  		/* as we're past the point where we transition to the ref  		 * counting teardown path, if we return a bad pointer here, diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index d52701df7245..951042a375d6 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -1367,7 +1367,7 @@ static bool nvme_should_reset(struct nvme_dev *dev, u32 csts)  	bool nssro = dev->subsystem && (csts & NVME_CSTS_NSSRO);  	/* If there is a reset ongoing, we shouldn't reset again. */ -	if (work_busy(&dev->reset_work)) +	if (dev->ctrl.state == NVME_CTRL_RESETTING)  		return false;  	/* We shouldn't reset unless the controller is on fatal error state @@ -1903,7 +1903,7 @@ static void nvme_reset_work(struct work_struct *work)  	bool was_suspend = !!(dev->ctrl.ctrl_config & NVME_CC_SHN_NORMAL);  	int result = -ENODEV; -	if (WARN_ON(dev->ctrl.state == NVME_CTRL_RESETTING)) +	if (WARN_ON(dev->ctrl.state != NVME_CTRL_RESETTING))  		goto out;  	/* @@ -1913,9 +1913,6 @@ static void nvme_reset_work(struct work_struct *work)  	if (dev->ctrl.ctrl_config & NVME_CC_ENABLE)  		nvme_dev_disable(dev, false); -	if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_RESETTING)) -		goto out; -  	result = nvme_pci_enable(dev);  	if (result)  		goto out; @@ -2009,8 +2006,8 @@ static int nvme_reset(struct nvme_dev *dev)  {  	if (!dev->ctrl.admin_q || blk_queue_dying(dev->ctrl.admin_q))  		return -ENODEV; -	if (work_busy(&dev->reset_work)) -		return -ENODEV; +	if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_RESETTING)) +		return -EBUSY;  	if (!queue_work(nvme_workq, &dev->reset_work))  		return -EBUSY;  	return 0; @@ -2136,6 +2133,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)  	if (result)  		goto release_pools; +	nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_RESETTING);  	dev_info(dev->ctrl.device, "pci function %s\n", dev_name(&pdev->dev));  	queue_work(nvme_workq, &dev->reset_work); @@ -2179,6 +2177,7 @@ static void nvme_remove(struct pci_dev *pdev)  	nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_DELETING); +	cancel_work_sync(&dev->reset_work);  	pci_set_drvdata(pdev, NULL);  	if (!pci_device_is_present(pdev)) { diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index 28bd255c144d..24397d306d53 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -753,28 +753,26 @@ static void nvme_rdma_reconnect_ctrl_work(struct work_struct *work)  	if (ret)  		goto requeue; -	blk_mq_start_stopped_hw_queues(ctrl->ctrl.admin_q, true); -  	ret = nvmf_connect_admin_queue(&ctrl->ctrl);  	if (ret) -		goto stop_admin_q; +		goto requeue;  	set_bit(NVME_RDMA_Q_LIVE, &ctrl->queues[0].flags);  	ret = nvme_enable_ctrl(&ctrl->ctrl, ctrl->cap);  	if (ret) -		goto stop_admin_q; +		goto requeue;  	nvme_start_keep_alive(&ctrl->ctrl);  	if (ctrl->queue_count > 1) {  		ret = nvme_rdma_init_io_queues(ctrl);  		if (ret) -			goto stop_admin_q; +			goto requeue;  		ret = nvme_rdma_connect_io_queues(ctrl);  		if (ret) -			goto stop_admin_q; +			goto requeue;  	}  	changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE); @@ -782,7 +780,6 @@ static void nvme_rdma_reconnect_ctrl_work(struct work_struct *work)  	ctrl->ctrl.opts->nr_reconnects = 0;  	if (ctrl->queue_count > 1) { -		nvme_start_queues(&ctrl->ctrl);  		nvme_queue_scan(&ctrl->ctrl);  		nvme_queue_async_events(&ctrl->ctrl);  	} @@ -791,8 +788,6 @@ static void nvme_rdma_reconnect_ctrl_work(struct work_struct *work)  	return; -stop_admin_q: -	blk_mq_stop_hw_queues(ctrl->ctrl.admin_q);  requeue:  	dev_info(ctrl->ctrl.device, "Failed reconnect attempt %d\n",  			ctrl->ctrl.opts->nr_reconnects); @@ -823,6 +818,13 @@ static void nvme_rdma_error_recovery_work(struct work_struct *work)  	blk_mq_tagset_busy_iter(&ctrl->admin_tag_set,  				nvme_cancel_request, &ctrl->ctrl); +	/* +	 * queues are not a live anymore, so restart the queues to fail fast +	 * new IO +	 */ +	blk_mq_start_stopped_hw_queues(ctrl->ctrl.admin_q, true); +	nvme_start_queues(&ctrl->ctrl); +  	nvme_rdma_reconnect_or_remove(ctrl);  } @@ -1433,7 +1435,7 @@ nvme_rdma_timeout(struct request *rq, bool reserved)  /*   * We cannot accept any other command until the Connect command has completed.   */ -static inline bool nvme_rdma_queue_is_ready(struct nvme_rdma_queue *queue, +static inline int nvme_rdma_queue_is_ready(struct nvme_rdma_queue *queue,  		struct request *rq)  {  	if (unlikely(!test_bit(NVME_RDMA_Q_LIVE, &queue->flags))) { @@ -1441,11 +1443,22 @@ static inline bool nvme_rdma_queue_is_ready(struct nvme_rdma_queue *queue,  		if (!blk_rq_is_passthrough(rq) ||  		    cmd->common.opcode != nvme_fabrics_command || -		    cmd->fabrics.fctype != nvme_fabrics_type_connect) -			return false; +		    cmd->fabrics.fctype != nvme_fabrics_type_connect) { +			/* +			 * reconnecting state means transport disruption, which +			 * can take a long time and even might fail permanently, +			 * so we can't let incoming I/O be requeued forever. +			 * fail it fast to allow upper layers a chance to +			 * failover. +			 */ +			if (queue->ctrl->ctrl.state == NVME_CTRL_RECONNECTING) +				return -EIO; +			else +				return -EAGAIN; +		}  	} -	return true; +	return 0;  }  static int nvme_rdma_queue_rq(struct blk_mq_hw_ctx *hctx, @@ -1463,8 +1476,9 @@ static int nvme_rdma_queue_rq(struct blk_mq_hw_ctx *hctx,  	WARN_ON_ONCE(rq->tag < 0); -	if (!nvme_rdma_queue_is_ready(queue, rq)) -		return BLK_MQ_RQ_QUEUE_BUSY; +	ret = nvme_rdma_queue_is_ready(queue, rq); +	if (unlikely(ret)) +		goto err;  	dev = queue->device->dev;  	ib_dma_sync_single_for_cpu(dev, sqe->dma, diff --git a/drivers/of/device.c b/drivers/of/device.c index 9416d052cb89..28c38c756f92 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -144,8 +144,8 @@ int of_dma_configure(struct device *dev, struct device_node *np)  		coherent ? " " : " not ");  	iommu = of_iommu_configure(dev, np); -	if (IS_ERR(iommu)) -		return PTR_ERR(iommu); +	if (IS_ERR(iommu) && PTR_ERR(iommu) == -EPROBE_DEFER) +		return -EPROBE_DEFER;  	dev_dbg(dev, "device is%sbehind an iommu\n",  		iommu ? " " : " not "); diff --git a/drivers/phy/phy-qcom-qmp.c b/drivers/phy/phy-qcom-qmp.c index 727e23be7cac..78ca62897784 100644 --- a/drivers/phy/phy-qcom-qmp.c +++ b/drivers/phy/phy-qcom-qmp.c @@ -844,7 +844,7 @@ static int qcom_qmp_phy_vreg_init(struct device *dev)  	int num = qmp->cfg->num_vregs;  	int i; -	qmp->vregs = devm_kcalloc(dev, num, sizeof(qmp->vregs), GFP_KERNEL); +	qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);  	if (!qmp->vregs)  		return -ENOMEM; @@ -983,16 +983,16 @@ int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id)  	 * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.  	 */  	qphy->tx = of_iomap(np, 0); -	if (IS_ERR(qphy->tx)) -		return PTR_ERR(qphy->tx); +	if (!qphy->tx) +		return -ENOMEM;  	qphy->rx = of_iomap(np, 1); -	if (IS_ERR(qphy->rx)) -		return PTR_ERR(qphy->rx); +	if (!qphy->rx) +		return -ENOMEM;  	qphy->pcs = of_iomap(np, 2); -	if (IS_ERR(qphy->pcs)) -		return PTR_ERR(qphy->pcs); +	if (!qphy->pcs) +		return -ENOMEM;  	/*  	 * Get PHY's Pipe clock, if any. USB3 and PCIe are PIPE3 diff --git a/drivers/platform/goldfish/goldfish_pipe.c b/drivers/platform/goldfish/goldfish_pipe.c index 2de1e603bd2b..5f3672153b12 100644 --- a/drivers/platform/goldfish/goldfish_pipe.c +++ b/drivers/platform/goldfish/goldfish_pipe.c @@ -704,7 +704,7 @@ static int get_free_pipe_id_locked(struct goldfish_pipe_dev *dev)  		/* Reallocate the array */  		u32 new_capacity = 2 * dev->pipes_capacity;  		struct goldfish_pipe **pipes = -			kcalloc(new_capacity, sizeof(*pipes), GFP_KERNEL); +			kcalloc(new_capacity, sizeof(*pipes), GFP_ATOMIC);  		if (!pipes)  			return -ENOMEM;  		memcpy(pipes, dev->pipes, sizeof(*pipes) * dev->pipes_capacity); diff --git a/drivers/reset/hisilicon/hi6220_reset.c b/drivers/reset/hisilicon/hi6220_reset.c index 35ce53edabf9..d5e5229308f2 100644 --- a/drivers/reset/hisilicon/hi6220_reset.c +++ b/drivers/reset/hisilicon/hi6220_reset.c @@ -155,3 +155,5 @@ static int __init hi6220_reset_init(void)  }  postcore_initcall(hi6220_reset_init); + +MODULE_LICENSE("GPL v2"); diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c index e72abbc18ee3..a66a317f3e4f 100644 --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -70,14 +70,14 @@ static ssize_t name_show(struct kobject *kobj, struct device *dev, char *buf)  {  	return sprintf(buf, "I/O subchannel (Non-QDIO)\n");  } -MDEV_TYPE_ATTR_RO(name); +static MDEV_TYPE_ATTR_RO(name);  static ssize_t device_api_show(struct kobject *kobj, struct device *dev,  			       char *buf)  {  	return sprintf(buf, "%s\n", VFIO_DEVICE_API_CCW_STRING);  } -MDEV_TYPE_ATTR_RO(device_api); +static MDEV_TYPE_ATTR_RO(device_api);  static ssize_t available_instances_show(struct kobject *kobj,  					struct device *dev, char *buf) @@ -86,7 +86,7 @@ static ssize_t available_instances_show(struct kobject *kobj,  	return sprintf(buf, "%d\n", atomic_read(&private->avail));  } -MDEV_TYPE_ATTR_RO(available_instances); +static MDEV_TYPE_ATTR_RO(available_instances);  static struct attribute *mdev_types_attrs[] = {  	&mdev_type_attr_name.attr, @@ -100,7 +100,7 @@ static struct attribute_group mdev_type_group = {  	.attrs = mdev_types_attrs,  }; -struct attribute_group *mdev_type_groups[] = { +static struct attribute_group *mdev_type_groups[] = {  	&mdev_type_group,  	NULL,  }; @@ -152,7 +152,7 @@ static int vfio_ccw_mdev_open(struct mdev_device *mdev)  				      &events, &private->nb);  } -void vfio_ccw_mdev_release(struct mdev_device *mdev) +static void vfio_ccw_mdev_release(struct mdev_device *mdev)  {  	struct vfio_ccw_private *private =  		dev_get_drvdata(mdev_parent_dev(mdev)); @@ -233,7 +233,7 @@ static int vfio_ccw_mdev_get_region_info(struct vfio_region_info *info,  	}  } -int vfio_ccw_mdev_get_irq_info(struct vfio_irq_info *info) +static int vfio_ccw_mdev_get_irq_info(struct vfio_irq_info *info)  {  	if (info->index != VFIO_CCW_IO_IRQ_INDEX)  		return -EINVAL; diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 9be4596d8a08..ea099910b4e9 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -668,10 +668,28 @@ static int ap_device_probe(struct device *dev)  	struct ap_driver *ap_drv = to_ap_drv(dev->driver);  	int rc; +	/* Add queue/card to list of active queues/cards */ +	spin_lock_bh(&ap_list_lock); +	if (is_card_dev(dev)) +		list_add(&to_ap_card(dev)->list, &ap_card_list); +	else +		list_add(&to_ap_queue(dev)->list, +			 &to_ap_queue(dev)->card->queues); +	spin_unlock_bh(&ap_list_lock); +  	ap_dev->drv = ap_drv;  	rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV; -	if (rc) + +	if (rc) { +		spin_lock_bh(&ap_list_lock); +		if (is_card_dev(dev)) +			list_del_init(&to_ap_card(dev)->list); +		else +			list_del_init(&to_ap_queue(dev)->list); +		spin_unlock_bh(&ap_list_lock);  		ap_dev->drv = NULL; +	} +  	return rc;  } @@ -680,14 +698,17 @@ static int ap_device_remove(struct device *dev)  	struct ap_device *ap_dev = to_ap_dev(dev);  	struct ap_driver *ap_drv = ap_dev->drv; +	if (ap_drv->remove) +		ap_drv->remove(ap_dev); + +	/* Remove queue/card from list of active queues/cards */  	spin_lock_bh(&ap_list_lock);  	if (is_card_dev(dev))  		list_del_init(&to_ap_card(dev)->list);  	else  		list_del_init(&to_ap_queue(dev)->list);  	spin_unlock_bh(&ap_list_lock); -	if (ap_drv->remove) -		ap_drv->remove(ap_dev); +  	return 0;  } @@ -1056,10 +1077,6 @@ static void ap_scan_bus(struct work_struct *unused)  				}  				/* get it and thus adjust reference counter */  				get_device(&ac->ap_dev.device); -				/* Add card device to card list */ -				spin_lock_bh(&ap_list_lock); -				list_add(&ac->list, &ap_card_list); -				spin_unlock_bh(&ap_list_lock);  			}  			/* now create the new queue device */  			aq = ap_queue_create(qid, type); @@ -1070,10 +1087,6 @@ static void ap_scan_bus(struct work_struct *unused)  			aq->ap_dev.device.parent = &ac->ap_dev.device;  			dev_set_name(&aq->ap_dev.device,  				     "%02x.%04x", id, dom); -			/* Add queue device to card queue list */ -			spin_lock_bh(&ap_list_lock); -			list_add(&aq->list, &ac->queues); -			spin_unlock_bh(&ap_list_lock);  			/* Start with a device reset */  			spin_lock_bh(&aq->lock);  			ap_wait(ap_sm_event(aq, AP_EVENT_POLL)); @@ -1081,9 +1094,6 @@ static void ap_scan_bus(struct work_struct *unused)  			/* Register device */  			rc = device_register(&aq->ap_dev.device);  			if (rc) { -				spin_lock_bh(&ap_list_lock); -				list_del_init(&aq->list); -				spin_unlock_bh(&ap_list_lock);  				put_device(&aq->ap_dev.device);  				continue;  			} diff --git a/drivers/s390/crypto/ap_card.c b/drivers/s390/crypto/ap_card.c index cfa161ccc74e..836efac96813 100644 --- a/drivers/s390/crypto/ap_card.c +++ b/drivers/s390/crypto/ap_card.c @@ -160,7 +160,14 @@ static struct device_type ap_card_type = {  static void ap_card_device_release(struct device *dev)  { -	kfree(to_ap_card(dev)); +	struct ap_card *ac = to_ap_card(dev); + +	if (!list_empty(&ac->list)) { +		spin_lock_bh(&ap_list_lock); +		list_del_init(&ac->list); +		spin_unlock_bh(&ap_list_lock); +	} +	kfree(ac);  }  struct ap_card *ap_card_create(int id, int queue_depth, int device_type, diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c index 480c58a63769..0f1a5d02acb0 100644 --- a/drivers/s390/crypto/ap_queue.c +++ b/drivers/s390/crypto/ap_queue.c @@ -584,7 +584,14 @@ static struct device_type ap_queue_type = {  static void ap_queue_device_release(struct device *dev)  { -	kfree(to_ap_queue(dev)); +	struct ap_queue *aq = to_ap_queue(dev); + +	if (!list_empty(&aq->list)) { +		spin_lock_bh(&ap_list_lock); +		list_del_init(&aq->list); +		spin_unlock_bh(&ap_list_lock); +	} +	kfree(aq);  }  struct ap_queue *ap_queue_create(ap_qid_t qid, int device_type) diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index dba94b486f05..fa732bd86729 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c @@ -1954,7 +1954,6 @@ static void netiucv_free_netdevice(struct net_device *dev)  		privptr->conn = NULL; privptr->fsm = NULL;  		/* privptr gets freed by free_netdev() */  	} -	free_netdev(dev);  }  /** @@ -1972,7 +1971,8 @@ static void netiucv_setup_netdevice(struct net_device *dev)  	dev->mtu	         = NETIUCV_MTU_DEFAULT;  	dev->min_mtu		 = 576;  	dev->max_mtu		 = NETIUCV_MTU_MAX; -	dev->destructor          = netiucv_free_netdevice; +	dev->needs_free_netdev   = true; +	dev->priv_destructor     = netiucv_free_netdevice;  	dev->hard_header_len     = NETIUCV_HDRLEN;  	dev->addr_len            = 0;  	dev->type                = ARPHRD_SLIP; diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h index 4fc8ed5fe067..1f424e40afdf 100644 --- a/drivers/scsi/bnx2fc/bnx2fc.h +++ b/drivers/scsi/bnx2fc/bnx2fc.h @@ -191,6 +191,7 @@ struct bnx2fc_hba {  	struct bnx2fc_cmd_mgr *cmd_mgr;  	spinlock_t hba_lock;  	struct mutex hba_mutex; +	struct mutex hba_stats_mutex;  	unsigned long adapter_state;  		#define ADAPTER_STATE_UP		0  		#define ADAPTER_STATE_GOING_DOWN	1 diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index 93b5a0012417..902722dc4ce3 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -663,15 +663,17 @@ static struct fc_host_statistics *bnx2fc_get_host_stats(struct Scsi_Host *shost)  	if (!fw_stats)  		return NULL; +	mutex_lock(&hba->hba_stats_mutex); +  	bnx2fc_stats = fc_get_host_stats(shost);  	init_completion(&hba->stat_req_done);  	if (bnx2fc_send_stat_req(hba)) -		return bnx2fc_stats; +		goto unlock_stats_mutex;  	rc = wait_for_completion_timeout(&hba->stat_req_done, (2 * HZ));  	if (!rc) {  		BNX2FC_HBA_DBG(lport, "FW stat req timed out\n"); -		return bnx2fc_stats; +		goto unlock_stats_mutex;  	}  	BNX2FC_STATS(hba, rx_stat2, fc_crc_cnt);  	bnx2fc_stats->invalid_crc_count += hba->bfw_stats.fc_crc_cnt; @@ -693,6 +695,9 @@ static struct fc_host_statistics *bnx2fc_get_host_stats(struct Scsi_Host *shost)  	memcpy(&hba->prev_stats, hba->stats_buffer,  	       sizeof(struct fcoe_statistics_params)); + +unlock_stats_mutex: +	mutex_unlock(&hba->hba_stats_mutex);  	return bnx2fc_stats;  } @@ -1340,6 +1345,7 @@ static struct bnx2fc_hba *bnx2fc_hba_create(struct cnic_dev *cnic)  	}  	spin_lock_init(&hba->hba_lock);  	mutex_init(&hba->hba_mutex); +	mutex_init(&hba->hba_stats_mutex);  	hba->cnic = cnic; diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c index 9a92b5150218..397094b8bad6 100644 --- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c +++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c @@ -1597,7 +1597,6 @@ static void release_offload_resources(struct cxgbi_sock *csk)  		cxgbi_sock_put(csk);  	}  	csk->dst = NULL; -	csk->cdev = NULL;  }  static int init_act_open(struct cxgbi_sock *csk) diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index fb06974c88c1..e4c83b7c96a8 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c @@ -867,7 +867,8 @@ static void need_active_close(struct cxgbi_sock *csk)  	log_debug(1 << CXGBI_DBG_SOCK, "csk 0x%p,%u,0x%lx,%u.\n",  		csk, (csk)->state, (csk)->flags, (csk)->tid);  	spin_lock_bh(&csk->lock); -	dst_confirm(csk->dst); +	if (csk->dst) +		dst_confirm(csk->dst);  	data_lost = skb_queue_len(&csk->receive_queue);  	__skb_queue_purge(&csk->receive_queue); @@ -882,7 +883,8 @@ static void need_active_close(struct cxgbi_sock *csk)  	}  	if (close_req) { -		if (data_lost) +		if (!cxgbi_sock_flag(csk, CTPF_LOGOUT_RSP_RCVD) || +		    data_lost)  			csk->cdev->csk_send_abort_req(csk);  		else  			csk->cdev->csk_send_close_req(csk); @@ -1186,9 +1188,10 @@ static int cxgbi_sock_send_pdus(struct cxgbi_sock *csk, struct sk_buff *skb)  				cxgbi_ulp_extra_len(cxgbi_skcb_ulp_mode(skb));  		skb = next;  	} -done: +  	if (likely(skb_queue_len(&csk->write_queue)))  		cdev->csk_push_tx_frames(csk, 1); +done:  	spin_unlock_bh(&csk->lock);  	return copied; @@ -1568,9 +1571,12 @@ static inline int read_pdu_skb(struct iscsi_conn *conn,  	}  } -static int skb_read_pdu_bhs(struct iscsi_conn *conn, struct sk_buff *skb) +static int +skb_read_pdu_bhs(struct cxgbi_sock *csk, struct iscsi_conn *conn, +		 struct sk_buff *skb)  {  	struct iscsi_tcp_conn *tcp_conn = conn->dd_data; +	int err;  	log_debug(1 << CXGBI_DBG_PDU_RX,  		"conn 0x%p, skb 0x%p, len %u, flag 0x%lx.\n", @@ -1608,7 +1614,16 @@ static int skb_read_pdu_bhs(struct iscsi_conn *conn, struct sk_buff *skb)  		}  	} -	return read_pdu_skb(conn, skb, 0, 0); +	err = read_pdu_skb(conn, skb, 0, 0); +	if (likely(err >= 0)) { +		struct iscsi_hdr *hdr = (struct iscsi_hdr *)skb->data; +		u8 opcode = hdr->opcode & ISCSI_OPCODE_MASK; + +		if (unlikely(opcode == ISCSI_OP_LOGOUT_RSP)) +			cxgbi_sock_set_flag(csk, CTPF_LOGOUT_RSP_RCVD); +	} + +	return err;  }  static int skb_read_pdu_data(struct iscsi_conn *conn, struct sk_buff *lskb, @@ -1713,7 +1728,7 @@ void cxgbi_conn_pdu_ready(struct cxgbi_sock *csk)  			cxgbi_skcb_rx_pdulen(skb));  		if (cxgbi_skcb_test_flag(skb, SKCBF_RX_COALESCED)) { -			err = skb_read_pdu_bhs(conn, skb); +			err = skb_read_pdu_bhs(csk, conn, skb);  			if (err < 0) {  				pr_err("coalesced bhs, csk 0x%p, skb 0x%p,%u, "  					"f 0x%lx, plen %u.\n", @@ -1731,7 +1746,7 @@ void cxgbi_conn_pdu_ready(struct cxgbi_sock *csk)  					cxgbi_skcb_flags(skb),  					cxgbi_skcb_rx_pdulen(skb));  		} else { -			err = skb_read_pdu_bhs(conn, skb); +			err = skb_read_pdu_bhs(csk, conn, skb);  			if (err < 0) {  				pr_err("bhs, csk 0x%p, skb 0x%p,%u, "  					"f 0x%lx, plen %u.\n", diff --git a/drivers/scsi/cxgbi/libcxgbi.h b/drivers/scsi/cxgbi/libcxgbi.h index 239462a75760..37f07aaab1e4 100644 --- a/drivers/scsi/cxgbi/libcxgbi.h +++ b/drivers/scsi/cxgbi/libcxgbi.h @@ -187,6 +187,7 @@ enum cxgbi_sock_flags {  	CTPF_HAS_ATID,		/* reserved atid */  	CTPF_HAS_TID,		/* reserved hw tid */  	CTPF_OFFLOAD_DOWN,	/* offload function off */ +	CTPF_LOGOUT_RSP_RCVD,   /* received logout response */  };  struct cxgbi_skb_rx_cb { diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 8912767e7bc8..da669dce12fe 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -127,7 +127,7 @@ int lpfc_disc_state_machine(struct lpfc_vport *, struct lpfc_nodelist *, void *,  void lpfc_do_scr_ns_plogi(struct lpfc_hba *, struct lpfc_vport *);  int lpfc_check_sparm(struct lpfc_vport *, struct lpfc_nodelist *,  		     struct serv_parm *, uint32_t, int); -int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist *); +void lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist *);  void lpfc_more_plogi(struct lpfc_vport *);  void lpfc_more_adisc(struct lpfc_vport *);  void lpfc_end_rscn(struct lpfc_vport *); diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index f2cd19c6c2df..24ce96dcc94d 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -978,9 +978,10 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,  					 ndlp, did, ndlp->nlp_fc4_type,  					 FC_TYPE_FCP, FC_TYPE_NVME);  			ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; + +			lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE); +			lpfc_issue_els_prli(vport, ndlp, 0);  		} -		lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE); -		lpfc_issue_els_prli(vport, ndlp, 0);  	} else  		lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,  				 "3065 GFT_ID failed x%08x\n", irsp->ulpStatus); diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index bff3de053df4..f74cb0142fd4 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -206,7 +206,7 @@ lpfc_check_elscmpl_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,   * associated with a LPFC_NODELIST entry. This   * routine effectively results in a "software abort".   */ -int +void  lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)  {  	LIST_HEAD(abort_list); @@ -215,6 +215,10 @@ lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)  	pring = lpfc_phba_elsring(phba); +	/* In case of error recovery path, we might have a NULL pring here */ +	if (!pring) +		return; +  	/* Abort outstanding I/O on NPort <nlp_DID> */  	lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_DISCOVERY,  			 "2819 Abort outstanding I/O on NPort x%x " @@ -273,7 +277,6 @@ lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)  			      IOSTAT_LOCAL_REJECT, IOERR_SLI_ABORTED);  	lpfc_cancel_retry_delay_tmo(phba->pport, ndlp); -	return 0;  }  static int diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index 074a6b5e7763..518b15e6f222 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c @@ -799,8 +799,8 @@ lpfc_nvmet_xmt_fcp_release(struct nvmet_fc_target_port *tgtport,  	}  	spin_unlock_irqrestore(&ctxp->ctxlock, flags); -	lpfc_nvmeio_data(phba, "NVMET FCP FREE: xri x%x ste %d\n", ctxp->oxid, -			 ctxp->state, 0); +	lpfc_nvmeio_data(phba, "NVMET FCP FREE: xri x%x ste %d abt %d\n", ctxp->oxid, +			 ctxp->state, aborting);  	atomic_inc(&lpfc_nvmep->xmt_fcp_release); diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 16d1cd50feed..ca3420de5a01 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -730,6 +730,8 @@ qla2x00_process_loopback(struct bsg_job *bsg_job)  		return -EIO;  	} +	memset(&elreq, 0, sizeof(elreq)); +  	elreq.req_sg_cnt = dma_map_sg(&ha->pdev->dev,  		bsg_job->request_payload.sg_list, bsg_job->request_payload.sg_cnt,  		DMA_TO_DEVICE); @@ -795,10 +797,9 @@ qla2x00_process_loopback(struct bsg_job *bsg_job)  	if (atomic_read(&vha->loop_state) == LOOP_READY &&  	    (ha->current_topology == ISP_CFG_F || -	    ((IS_QLA81XX(ha) || IS_QLA8031(ha) || IS_QLA8044(ha)) && -	    le32_to_cpu(*(uint32_t *)req_data) == ELS_OPCODE_BYTE -	    && req_data_len == MAX_ELS_FRAME_PAYLOAD)) && -		elreq.options == EXTERNAL_LOOPBACK) { +	    (le32_to_cpu(*(uint32_t *)req_data) == ELS_OPCODE_BYTE && +	     req_data_len == MAX_ELS_FRAME_PAYLOAD)) && +	    elreq.options == EXTERNAL_LOOPBACK) {  		type = "FC_BSG_HST_VENDOR_ECHO_DIAG";  		ql_dbg(ql_dbg_user, vha, 0x701e,  		    "BSG request type: %s.\n", type); diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 51b4179469d1..88748a6ab73f 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -1131,7 +1131,7 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)  	/* Mailbox registers. */  	mbx_reg = ®->mailbox0; -	for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++, dmp_reg++) +	for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++, mbx_reg++)  		fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg));  	/* Transfer sequence registers. */ @@ -2090,7 +2090,7 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)  	/* Mailbox registers. */  	mbx_reg = ®->mailbox0; -	for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++, dmp_reg++) +	for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++, mbx_reg++)  		fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg));  	/* Transfer sequence registers. */ diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index ae119018dfaa..eddbc1218a39 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -3425,6 +3425,7 @@ struct qla_hw_data {  	uint8_t 	max_req_queues;  	uint8_t 	max_rsp_queues;  	uint8_t		max_qpairs; +	uint8_t		num_qpairs;  	struct qla_qpair *base_qpair;  	struct qla_npiv_entry *npiv_info;  	uint16_t	nvram_npiv_size; diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 034743309ada..0391fc317003 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -7543,12 +7543,13 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, int v  		/* Assign available que pair id */  		mutex_lock(&ha->mq_lock);  		qpair_id = find_first_zero_bit(ha->qpair_qid_map, ha->max_qpairs); -		if (qpair_id >= ha->max_qpairs) { +		if (ha->num_qpairs >= ha->max_qpairs) {  			mutex_unlock(&ha->mq_lock);  			ql_log(ql_log_warn, vha, 0x0183,  			    "No resources to create additional q pair.\n");  			goto fail_qid_map;  		} +		ha->num_qpairs++;  		set_bit(qpair_id, ha->qpair_qid_map);  		ha->queue_pair_map[qpair_id] = qpair;  		qpair->id = qpair_id; @@ -7635,6 +7636,7 @@ fail_rsp:  fail_msix:  	ha->queue_pair_map[qpair_id] = NULL;  	clear_bit(qpair_id, ha->qpair_qid_map); +	ha->num_qpairs--;  	mutex_unlock(&ha->mq_lock);  fail_qid_map:  	kfree(qpair); @@ -7660,6 +7662,7 @@ int qla2xxx_delete_qpair(struct scsi_qla_host *vha, struct qla_qpair *qpair)  	mutex_lock(&ha->mq_lock);  	ha->queue_pair_map[qpair->id] = NULL;  	clear_bit(qpair->id, ha->qpair_qid_map); +	ha->num_qpairs--;  	list_del(&qpair->qp_list_elem);  	if (list_empty(&vha->qp_list))  		vha->flags.qpairs_available = 0; diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h index 66df6cec59da..c61a6a871c8e 100644 --- a/drivers/scsi/qla2xxx/qla_inline.h +++ b/drivers/scsi/qla2xxx/qla_inline.h @@ -129,28 +129,16 @@ qla2x00_clear_loop_id(fc_port_t *fcport) {  }  static inline void -qla2x00_clean_dsd_pool(struct qla_hw_data *ha, srb_t *sp, -	struct qla_tgt_cmd *tc) +qla2x00_clean_dsd_pool(struct qla_hw_data *ha, struct crc_context *ctx)  { -	struct dsd_dma *dsd_ptr, *tdsd_ptr; -	struct crc_context *ctx; - -	if (sp) -		ctx = (struct crc_context *)GET_CMD_CTX_SP(sp); -	else if (tc) -		ctx = (struct crc_context *)tc->ctx; -	else { -		BUG(); -		return; -	} +	struct dsd_dma *dsd, *tdsd;  	/* clean up allocated prev pool */ -	list_for_each_entry_safe(dsd_ptr, tdsd_ptr, -	    &ctx->dsd_list, list) { -		dma_pool_free(ha->dl_dma_pool, dsd_ptr->dsd_addr, -		    dsd_ptr->dsd_list_dma); -		list_del(&dsd_ptr->list); -		kfree(dsd_ptr); +	list_for_each_entry_safe(dsd, tdsd, &ctx->dsd_list, list) { +		dma_pool_free(ha->dl_dma_pool, dsd->dsd_addr, +		    dsd->dsd_list_dma); +		list_del(&dsd->list); +		kfree(dsd);  	}  	INIT_LIST_HEAD(&ctx->dsd_list);  } diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index aac03504d9a3..2572121b765b 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -3282,7 +3282,7 @@ msix_register_fail:  	}  	/* Enable MSI-X vector for response queue update for queue 0 */ -	if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { +	if (IS_QLA25XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) {  		if (ha->msixbase && ha->mqiobase &&  		    (ha->max_rsp_queues > 1 || ha->max_req_queues > 1 ||  		     ql2xmqsupport)) diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index a113ab3592a7..cba1fc5e8be9 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -3676,15 +3676,6 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,  				qlt_update_host_map(vha, id);  			} -			fc_host_port_name(vha->host) = -			    wwn_to_u64(vha->port_name); - -			if (qla_ini_mode_enabled(vha)) -				ql_dbg(ql_dbg_mbx, vha, 0x1018, -				    "FA-WWN portname %016llx (%x)\n", -				    fc_host_port_name(vha->host), -				    rptid_entry->vp_status); -  			set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);  			set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);  		} else { @@ -4821,9 +4812,9 @@ qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,  	memset(mcp->mb, 0 , sizeof(mcp->mb));  	mcp->mb[0] = MBC_DIAGNOSTIC_ECHO; -	mcp->mb[1] = mreq->options | BIT_6;	/* BIT_6 specifies 64bit address */ +	/* BIT_6 specifies 64bit address */ +	mcp->mb[1] = mreq->options | BIT_15 | BIT_6;  	if (IS_CNA_CAPABLE(ha)) { -		mcp->mb[1] |= BIT_15;  		mcp->mb[2] = vha->fcoe_fcf_idx;  	}  	mcp->mb[16] = LSW(mreq->rcv_dma); diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 1c7957903283..79f050256c55 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -630,29 +630,34 @@ qla2x00_sp_free_dma(void *ptr)  		sp->flags &= ~SRB_CRC_PROT_DMA_VALID;  	} +	if (!ctx) +		goto end; +  	if (sp->flags & SRB_CRC_CTX_DSD_VALID) {  		/* List assured to be having elements */ -		qla2x00_clean_dsd_pool(ha, sp, NULL); +		qla2x00_clean_dsd_pool(ha, ctx);  		sp->flags &= ~SRB_CRC_CTX_DSD_VALID;  	}  	if (sp->flags & SRB_CRC_CTX_DMA_VALID) { -		dma_pool_free(ha->dl_dma_pool, ctx, -		    ((struct crc_context *)ctx)->crc_ctx_dma); +		struct crc_context *ctx0 = ctx; + +		dma_pool_free(ha->dl_dma_pool, ctx0, ctx0->crc_ctx_dma);  		sp->flags &= ~SRB_CRC_CTX_DMA_VALID;  	}  	if (sp->flags & SRB_FCP_CMND_DMA_VALID) { -		struct ct6_dsd *ctx1 = (struct ct6_dsd *)ctx; +		struct ct6_dsd *ctx1 = ctx;  		dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd, -			ctx1->fcp_cmnd_dma); +		    ctx1->fcp_cmnd_dma);  		list_splice(&ctx1->dsd_list, &ha->gbl_dsd_list);  		ha->gbl_dsd_inuse -= ctx1->dsd_use_cnt;  		ha->gbl_dsd_avail += ctx1->dsd_use_cnt;  		mempool_free(ctx1, ha->ctx_mempool);  	} +end:  	CMD_SP(cmd) = NULL;  	qla2x00_rel_sp(sp);  } @@ -699,21 +704,24 @@ qla2xxx_qpair_sp_free_dma(void *ptr)  		sp->flags &= ~SRB_CRC_PROT_DMA_VALID;  	} +	if (!ctx) +		goto end; +  	if (sp->flags & SRB_CRC_CTX_DSD_VALID) {  		/* List assured to be having elements */ -		qla2x00_clean_dsd_pool(ha, sp, NULL); +		qla2x00_clean_dsd_pool(ha, ctx);  		sp->flags &= ~SRB_CRC_CTX_DSD_VALID;  	}  	if (sp->flags & SRB_CRC_CTX_DMA_VALID) { -		dma_pool_free(ha->dl_dma_pool, ctx, -		    ((struct crc_context *)ctx)->crc_ctx_dma); +		struct crc_context *ctx0 = ctx; + +		dma_pool_free(ha->dl_dma_pool, ctx, ctx0->crc_ctx_dma);  		sp->flags &= ~SRB_CRC_CTX_DMA_VALID;  	}  	if (sp->flags & SRB_FCP_CMND_DMA_VALID) { -		struct ct6_dsd *ctx1 = (struct ct6_dsd *)ctx; - +		struct ct6_dsd *ctx1 = ctx;  		dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd,  		    ctx1->fcp_cmnd_dma);  		list_splice(&ctx1->dsd_list, &ha->gbl_dsd_list); @@ -721,7 +729,7 @@ qla2xxx_qpair_sp_free_dma(void *ptr)  		ha->gbl_dsd_avail += ctx1->dsd_use_cnt;  		mempool_free(ctx1, ha->ctx_mempool);  	} - +end:  	CMD_SP(cmd) = NULL;  	qla2xxx_rel_qpair_sp(sp->qpair, sp);  } @@ -1632,7 +1640,7 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)  void  qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)  { -	int que, cnt; +	int que, cnt, status;  	unsigned long flags;  	srb_t *sp;  	struct qla_hw_data *ha = vha->hw; @@ -1662,8 +1670,12 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)  					 */  					sp_get(sp);  					spin_unlock_irqrestore(&ha->hardware_lock, flags); -					qla2xxx_eh_abort(GET_CMD_SP(sp)); +					status = qla2xxx_eh_abort(GET_CMD_SP(sp));  					spin_lock_irqsave(&ha->hardware_lock, flags); +					/* Get rid of extra reference if immediate exit +					 * from ql2xxx_eh_abort */ +					if (status == FAILED && (qla2x00_isp_reg_stat(ha))) +						atomic_dec(&sp->ref_count);  				}  				req->outstanding_cmds[cnt] = NULL;  				sp->done(sp, res); @@ -2623,10 +2635,10 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)  	if (mem_only) {  		if (pci_enable_device_mem(pdev)) -			goto probe_out; +			return ret;  	} else {  		if (pci_enable_device(pdev)) -			goto probe_out; +			return ret;  	}  	/* This may fail but that's ok */ @@ -2636,7 +2648,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)  	if (!ha) {  		ql_log_pci(ql_log_fatal, pdev, 0x0009,  		    "Unable to allocate memory for ha.\n"); -		goto probe_out; +		goto disable_device;  	}  	ql_dbg_pci(ql_dbg_init, pdev, 0x000a,  	    "Memory allocated for ha=%p.\n", ha); @@ -3254,7 +3266,7 @@ iospace_config_failed:  	pci_release_selected_regions(ha->pdev, ha->bars);  	kfree(ha); -probe_out: +disable_device:  	pci_disable_device(pdev);  	return ret;  } diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 0e03ca2ab3e5..e766d8412384 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -2245,11 +2245,13 @@ static void qlt_unmap_sg(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd)  		pci_unmap_sg(ha->pdev, cmd->prot_sg, cmd->prot_sg_cnt,  			cmd->dma_data_direction); +	if (!cmd->ctx) +		return; +  	if (cmd->ctx_dsd_alloced) -		qla2x00_clean_dsd_pool(ha, NULL, cmd); +		qla2x00_clean_dsd_pool(ha, cmd->ctx); -	if (cmd->ctx) -		dma_pool_free(ha->dl_dma_pool, cmd->ctx, cmd->ctx->crc_ctx_dma); +	dma_pool_free(ha->dl_dma_pool, cmd->ctx, cmd->ctx->crc_ctx_dma);  }  static int qlt_check_reserve_free_req(struct scsi_qla_host *vha, diff --git a/drivers/scsi/qla2xxx/qla_tmpl.c b/drivers/scsi/qla2xxx/qla_tmpl.c index 8a58ef3adab4..c197972a3e2d 100644 --- a/drivers/scsi/qla2xxx/qla_tmpl.c +++ b/drivers/scsi/qla2xxx/qla_tmpl.c @@ -371,7 +371,7 @@ qla27xx_fwdt_entry_t262(struct scsi_qla_host *vha,  		goto done;  	} -	if (end <= start || start == 0 || end == 0) { +	if (end < start || start == 0 || end == 0) {  		ql_dbg(ql_dbg_misc, vha, 0xd023,  		    "%s: unusable range (start=%x end=%x)\n", __func__,  		    ent->t262.end_addr, ent->t262.start_addr); diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 17249c3650fe..dc095a292c61 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -1404,7 +1404,7 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)  	arr[4] = SDEBUG_LONG_INQ_SZ - 5;  	arr[5] = (int)have_dif_prot;	/* PROTECT bit */  	if (sdebug_vpd_use_hostno == 0) -		arr[5] = 0x10; /* claim: implicit TGPS */ +		arr[5] |= 0x10; /* claim: implicit TPGS */  	arr[6] = 0x10; /* claim: MultiP */  	/* arr[6] |= 0x40; ... claim: EncServ (enclosure services) */  	arr[7] = 0xa; /* claim: LINKED + CMDQUE */ diff --git a/drivers/staging/ccree/Kconfig b/drivers/staging/ccree/Kconfig index ae627049c499..4be87f503e3b 100644 --- a/drivers/staging/ccree/Kconfig +++ b/drivers/staging/ccree/Kconfig @@ -1,6 +1,6 @@  config CRYPTO_DEV_CCREE  	tristate "Support for ARM TrustZone CryptoCell C7XX family of Crypto accelerators" -	depends on CRYPTO_HW && OF && HAS_DMA +	depends on CRYPTO && CRYPTO_HW && OF && HAS_DMA  	default n  	select CRYPTO_HASH  	select CRYPTO_BLKCIPHER diff --git a/drivers/staging/ccree/ssi_buffer_mgr.c b/drivers/staging/ccree/ssi_buffer_mgr.c index 038e2ff5e545..6471d3d2d375 100644 --- a/drivers/staging/ccree/ssi_buffer_mgr.c +++ b/drivers/staging/ccree/ssi_buffer_mgr.c @@ -216,7 +216,8 @@ void ssi_buffer_mgr_copy_scatterlist_portion(  	uint32_t nents, lbytes;  	nents = ssi_buffer_mgr_get_sgl_nents(sg, end, &lbytes, NULL); -	sg_copy_buffer(sg, nents, (void *)dest, (end - to_skip), 0, (direct == SSI_SG_TO_BUF)); +	sg_copy_buffer(sg, nents, (void *)dest, (end - to_skip + 1), to_skip, +		       (direct == SSI_SG_TO_BUF));  }  static inline int ssi_buffer_mgr_render_buff_to_mlli( diff --git a/drivers/staging/lustre/lustre/lov/lov_pack.c b/drivers/staging/lustre/lustre/lov/lov_pack.c index 2e1bd47337fd..e6727cefde05 100644 --- a/drivers/staging/lustre/lustre/lov/lov_pack.c +++ b/drivers/staging/lustre/lustre/lov/lov_pack.c @@ -293,18 +293,10 @@ int lov_getstripe(struct lov_object *obj, struct lov_stripe_md *lsm,  	size_t lmmk_size;  	size_t lum_size;  	int rc; -	mm_segment_t seg;  	if (!lsm)  		return -ENODATA; -	/* -	 * "Switch to kernel segment" to allow copying from kernel space by -	 * copy_{to,from}_user(). -	 */ -	seg = get_fs(); -	set_fs(KERNEL_DS); -  	if (lsm->lsm_magic != LOV_MAGIC_V1 && lsm->lsm_magic != LOV_MAGIC_V3) {  		CERROR("bad LSM MAGIC: 0x%08X != 0x%08X nor 0x%08X\n",  		       lsm->lsm_magic, LOV_MAGIC_V1, LOV_MAGIC_V3); @@ -406,6 +398,5 @@ int lov_getstripe(struct lov_object *obj, struct lov_stripe_md *lsm,  out_free:  	kvfree(lmmk);  out: -	set_fs(seg);  	return rc;  } diff --git a/drivers/staging/rtl8188eu/os_dep/mon.c b/drivers/staging/rtl8188eu/os_dep/mon.c index cfe37eb026d6..859d0d6051cd 100644 --- a/drivers/staging/rtl8188eu/os_dep/mon.c +++ b/drivers/staging/rtl8188eu/os_dep/mon.c @@ -152,7 +152,7 @@ static const struct net_device_ops mon_netdev_ops = {  static void mon_setup(struct net_device *dev)  {  	dev->netdev_ops = &mon_netdev_ops; -	dev->destructor = free_netdev; +	dev->needs_free_netdev = true;  	ether_setup(dev);  	dev->priv_flags |= IFF_NO_QUEUE;  	dev->type = ARPHRD_IEEE80211; diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c index 36c3189fc4b7..bd4352fe2de3 100644 --- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c @@ -2667,7 +2667,8 @@ static int rtw_cfg80211_add_monitor_if (struct adapter *padapter, char *name, st  	mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;  	strncpy(mon_ndev->name, name, IFNAMSIZ);  	mon_ndev->name[IFNAMSIZ - 1] = 0; -	mon_ndev->destructor = rtw_ndev_destructor; +	mon_ndev->needs_free_netdev = true; +	mon_ndev->priv_destructor = rtw_ndev_destructor;  	mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops; diff --git a/drivers/staging/rtl8723bs/os_dep/os_intfs.c b/drivers/staging/rtl8723bs/os_dep/os_intfs.c index f83cfc76505c..021589913681 100644 --- a/drivers/staging/rtl8723bs/os_dep/os_intfs.c +++ b/drivers/staging/rtl8723bs/os_dep/os_intfs.c @@ -1207,8 +1207,6 @@ void rtw_ndev_destructor(struct net_device *ndev)  	if (ndev->ieee80211_ptr)  		kfree((u8 *)ndev->ieee80211_ptr); - -	free_netdev(ndev);  }  void rtw_dev_unload(struct adapter *padapter) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 9e217b1361ea..fe4fe2440729 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -843,7 +843,10 @@ static ssize_t ci_role_show(struct device *dev, struct device_attribute *attr,  {  	struct ci_hdrc *ci = dev_get_drvdata(dev); -	return sprintf(buf, "%s\n", ci_role(ci)->name); +	if (ci->role != CI_ROLE_END) +		return sprintf(buf, "%s\n", ci_role(ci)->name); + +	return 0;  }  static ssize_t ci_role_store(struct device *dev, diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 6d23eede4d8c..1c31e8a08810 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -294,7 +294,8 @@ static int ci_role_show(struct seq_file *s, void *data)  {  	struct ci_hdrc *ci = s->private; -	seq_printf(s, "%s\n", ci_role(ci)->name); +	if (ci->role != CI_ROLE_END) +		seq_printf(s, "%s\n", ci_role(ci)->name);  	return 0;  } diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 56d2d3213076..d68b125796f9 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1993,6 +1993,7 @@ static void udc_id_switch_for_host(struct ci_hdrc *ci)  int ci_hdrc_gadget_init(struct ci_hdrc *ci)  {  	struct ci_role_driver *rdrv; +	int ret;  	if (!hw_read(ci, CAP_DCCPARAMS, DCCPARAMS_DC))  		return -ENXIO; @@ -2005,7 +2006,10 @@ int ci_hdrc_gadget_init(struct ci_hdrc *ci)  	rdrv->stop	= udc_id_switch_for_host;  	rdrv->irq	= udc_irq;  	rdrv->name	= "gadget"; -	ci->roles[CI_ROLE_GADGET] = rdrv; -	return udc_start(ci); +	ret = udc_start(ci); +	if (!ret) +		ci->roles[CI_ROLE_GADGET] = rdrv; + +	return ret;  } diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index e77a4ed4f021..9f4a0185dd60 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -108,6 +108,8 @@ struct imx_usbmisc {  	const struct usbmisc_ops *ops;  }; +static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data); +  static int usbmisc_imx25_init(struct imx_usbmisc_data *data)  {  	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); @@ -242,10 +244,15 @@ static int usbmisc_imx53_init(struct imx_usbmisc_data *data)  			val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN  				| MX53_USB_UHx_CTRL_ULPI_INT_EN;  			writel(val, reg); -			/* Disable internal 60Mhz clock */ -			reg = usbmisc->base + MX53_USB_CLKONOFF_CTRL_OFFSET; -			val = readl(reg) | MX53_USB_CLKONOFF_CTRL_H2_INT60CKOFF; -			writel(val, reg); +			if (is_imx53_usbmisc(data)) { +				/* Disable internal 60Mhz clock */ +				reg = usbmisc->base + +					MX53_USB_CLKONOFF_CTRL_OFFSET; +				val = readl(reg) | +					MX53_USB_CLKONOFF_CTRL_H2_INT60CKOFF; +				writel(val, reg); +			} +  		}  		if (data->disable_oc) {  			reg = usbmisc->base + MX53_USB_UH2_CTRL_OFFSET; @@ -267,10 +274,15 @@ static int usbmisc_imx53_init(struct imx_usbmisc_data *data)  			val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN  				| MX53_USB_UHx_CTRL_ULPI_INT_EN;  			writel(val, reg); -			/* Disable internal 60Mhz clock */ -			reg = usbmisc->base + MX53_USB_CLKONOFF_CTRL_OFFSET; -			val = readl(reg) | MX53_USB_CLKONOFF_CTRL_H3_INT60CKOFF; -			writel(val, reg); + +			if (is_imx53_usbmisc(data)) { +				/* Disable internal 60Mhz clock */ +				reg = usbmisc->base + +					MX53_USB_CLKONOFF_CTRL_OFFSET; +				val = readl(reg) | +					MX53_USB_CLKONOFF_CTRL_H3_INT60CKOFF; +				writel(val, reg); +			}  		}  		if (data->disable_oc) {  			reg = usbmisc->base + MX53_USB_UH3_CTRL_OFFSET; @@ -456,6 +468,10 @@ static const struct usbmisc_ops imx27_usbmisc_ops = {  	.init = usbmisc_imx27_init,  }; +static const struct usbmisc_ops imx51_usbmisc_ops = { +	.init = usbmisc_imx53_init, +}; +  static const struct usbmisc_ops imx53_usbmisc_ops = {  	.init = usbmisc_imx53_init,  }; @@ -479,6 +495,13 @@ static const struct usbmisc_ops imx7d_usbmisc_ops = {  	.set_wakeup = usbmisc_imx7d_set_wakeup,  }; +static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data) +{ +	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); + +	return usbmisc->ops == &imx53_usbmisc_ops; +} +  int imx_usbmisc_init(struct imx_usbmisc_data *data)  {  	struct imx_usbmisc *usbmisc; @@ -536,7 +559,7 @@ static const struct of_device_id usbmisc_imx_dt_ids[] = {  	},  	{  		.compatible = "fsl,imx51-usbmisc", -		.data = &imx53_usbmisc_ops, +		.data = &imx51_usbmisc_ops,  	},  	{  		.compatible = "fsl,imx53-usbmisc", diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c index 9cd8722f24f6..a3ffe97170ff 100644 --- a/drivers/usb/dwc2/params.c +++ b/drivers/usb/dwc2/params.c @@ -144,6 +144,8 @@ const struct of_device_id dwc2_of_match_table[] = {  	{ .compatible = "lantiq,xrx200-usb", .data = dwc2_set_ltq_params },  	{ .compatible = "snps,dwc2" },  	{ .compatible = "samsung,s3c6400-hsotg" }, +	{ .compatible = "amlogic,meson8-usb", +	  .data = dwc2_set_amlogic_params },  	{ .compatible = "amlogic,meson8b-usb",  	  .data = dwc2_set_amlogic_params },  	{ .compatible = "amlogic,meson-gxbb-usb", diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index 4c8aacc232c0..74d57d6994da 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c @@ -396,7 +396,11 @@ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep)  /* Caller must hold fsg->lock */  static void wakeup_thread(struct fsg_common *common)  { -	smp_wmb();	/* ensure the write of bh->state is complete */ +	/* +	 * Ensure the reading of thread_wakeup_needed +	 * and the writing of bh->state are completed +	 */ +	smp_mb();  	/* Tell the main thread that something has happened */  	common->thread_wakeup_needed = 1;  	if (common->thread_task) @@ -627,7 +631,12 @@ static int sleep_thread(struct fsg_common *common, bool can_freeze)  	}  	__set_current_state(TASK_RUNNING);  	common->thread_wakeup_needed = 0; -	smp_rmb();	/* ensure the latest bh->state is visible */ + +	/* +	 * Ensure the writing of thread_wakeup_needed +	 * and the reading of bh->state are completed +	 */ +	smp_mb();  	return rc;  } diff --git a/drivers/usb/gadget/function/f_phonet.c b/drivers/usb/gadget/function/f_phonet.c index b4058f0000e4..6a1ce6a55158 100644 --- a/drivers/usb/gadget/function/f_phonet.c +++ b/drivers/usb/gadget/function/f_phonet.c @@ -281,7 +281,7 @@ static void pn_net_setup(struct net_device *dev)  	dev->tx_queue_len	= 1;  	dev->netdev_ops		= &pn_netdev_ops; -	dev->destructor		= free_netdev; +	dev->needs_free_netdev	= true;  	dev->header_ops		= &phonet_header_ops;  } diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index 5a2d845fb1a6..cd4c88529721 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -623,7 +623,6 @@ static void renesas_usb3_stop_controller(struct renesas_usb3 *usb3)  {  	usb3_disconnect(usb3);  	usb3_write(usb3, 0, USB3_P0_INT_ENA); -	usb3_write(usb3, 0, USB3_PN_INT_ENA);  	usb3_write(usb3, 0, USB3_USB_OTG_INT_ENA);  	usb3_write(usb3, 0, USB3_USB_INT_ENA_1);  	usb3_write(usb3, 0, USB3_USB_INT_ENA_2); @@ -1475,7 +1474,13 @@ static void usb3_request_done_pipen(struct renesas_usb3 *usb3,  				    struct renesas_usb3_request *usb3_req,  				    int status)  { -	usb3_pn_stop(usb3); +	unsigned long flags; + +	spin_lock_irqsave(&usb3->lock, flags); +	if (usb3_pn_change(usb3, usb3_ep->num)) +		usb3_pn_stop(usb3); +	spin_unlock_irqrestore(&usb3->lock, flags); +  	usb3_disable_pipe_irq(usb3, usb3_ep->num);  	usb3_request_done(usb3_ep, usb3_req, status); @@ -1504,30 +1509,46 @@ static void usb3_irq_epc_pipen_bfrdy(struct renesas_usb3 *usb3, int num)  {  	struct renesas_usb3_ep *usb3_ep = usb3_get_ep(usb3, num);  	struct renesas_usb3_request *usb3_req = usb3_get_request(usb3_ep); +	bool done = false;  	if (!usb3_req)  		return; +	spin_lock(&usb3->lock); +	if (usb3_pn_change(usb3, num)) +		goto out; +  	if (usb3_ep->dir_in) {  		/* Do not stop the IN pipe here to detect LSTTR interrupt */  		if (!usb3_write_pipe(usb3_ep, usb3_req, USB3_PN_WRITE))  			usb3_clear_bit(usb3, PN_INT_BFRDY, USB3_PN_INT_ENA);  	} else {  		if (!usb3_read_pipe(usb3_ep, usb3_req, USB3_PN_READ)) -			usb3_request_done_pipen(usb3, usb3_ep, usb3_req, 0); +			done = true;  	} + +out: +	/* need to unlock because usb3_request_done_pipen() locks it */ +	spin_unlock(&usb3->lock); + +	if (done) +		usb3_request_done_pipen(usb3, usb3_ep, usb3_req, 0);  }  static void usb3_irq_epc_pipen(struct renesas_usb3 *usb3, int num)  {  	u32 pn_int_sta; -	if (usb3_pn_change(usb3, num) < 0) +	spin_lock(&usb3->lock); +	if (usb3_pn_change(usb3, num) < 0) { +		spin_unlock(&usb3->lock);  		return; +	}  	pn_int_sta = usb3_read(usb3, USB3_PN_INT_STA);  	pn_int_sta &= usb3_read(usb3, USB3_PN_INT_ENA);  	usb3_write(usb3, pn_int_sta, USB3_PN_INT_STA); +	spin_unlock(&usb3->lock);  	if (pn_int_sta & PN_INT_LSTTR)  		usb3_irq_epc_pipen_lsttr(usb3, num);  	if (pn_int_sta & PN_INT_BFRDY) @@ -1660,6 +1681,7 @@ static int usb3_disable_pipe_n(struct renesas_usb3_ep *usb3_ep)  	spin_lock_irqsave(&usb3->lock, flags);  	if (!usb3_pn_change(usb3, usb3_ep->num)) { +		usb3_write(usb3, 0, USB3_PN_INT_ENA);  		usb3_write(usb3, 0, USB3_PN_RAMMAP);  		usb3_clear_bit(usb3, PN_CON_EN, USB3_PN_CON);  	} @@ -1799,6 +1821,9 @@ static int renesas_usb3_start(struct usb_gadget *gadget,  	/* hook up the driver */  	usb3->driver = driver; +	pm_runtime_enable(usb3_to_dev(usb3)); +	pm_runtime_get_sync(usb3_to_dev(usb3)); +  	renesas_usb3_init_controller(usb3);  	return 0; @@ -1807,14 +1832,14 @@ static int renesas_usb3_start(struct usb_gadget *gadget,  static int renesas_usb3_stop(struct usb_gadget *gadget)  {  	struct renesas_usb3 *usb3 = gadget_to_renesas_usb3(gadget); -	unsigned long flags; -	spin_lock_irqsave(&usb3->lock, flags);  	usb3->softconnect = false;  	usb3->gadget.speed = USB_SPEED_UNKNOWN;  	usb3->driver = NULL;  	renesas_usb3_stop_controller(usb3); -	spin_unlock_irqrestore(&usb3->lock, flags); + +	pm_runtime_put(usb3_to_dev(usb3)); +	pm_runtime_disable(usb3_to_dev(usb3));  	return 0;  } @@ -1891,9 +1916,6 @@ static int renesas_usb3_remove(struct platform_device *pdev)  	device_remove_file(&pdev->dev, &dev_attr_role); -	pm_runtime_put(&pdev->dev); -	pm_runtime_disable(&pdev->dev); -  	usb_del_gadget_udc(&usb3->gadget);  	__renesas_usb3_ep_free_request(usb3->ep0_req); @@ -2099,9 +2121,6 @@ static int renesas_usb3_probe(struct platform_device *pdev)  	usb3->workaround_for_vbus = priv->workaround_for_vbus; -	pm_runtime_enable(&pdev->dev); -	pm_runtime_get_sync(&pdev->dev); -  	dev_info(&pdev->dev, "probed\n");  	return 0; diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 9c7ee26ef388..bc6a9be2ccc5 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -245,6 +245,11 @@ static int dsps_check_status(struct musb *musb, void *unused)  		dsps_mod_timer_optional(glue);  		break;  	case OTG_STATE_A_WAIT_BCON: +		/* keep VBUS on for host-only mode */ +		if (musb->port_mode == MUSB_PORT_MODE_HOST) { +			dsps_mod_timer_optional(glue); +			break; +		}  		musb_writeb(musb->mregs, MUSB_DEVCTL, 0);  		skip_session = 1;  		/* fall */ diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c index 7a92a5e1d40c..feca75b07fdd 100644 --- a/drivers/xen/privcmd.c +++ b/drivers/xen/privcmd.c @@ -362,8 +362,8 @@ static int mmap_batch_fn(void *data, int nr, void *state)  				st->global_error = 1;  		}  	} -	st->va += PAGE_SIZE * nr; -	st->index += nr; +	st->va += XEN_PAGE_SIZE * nr; +	st->index += nr / XEN_PFN_PER_PAGE;  	return 0;  } | 
