diff options
Diffstat (limited to 'drivers')
188 files changed, 1806 insertions, 984 deletions
| diff --git a/drivers/Makefile b/drivers/Makefile index 67d2334dc41e..527a6da8d539 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -50,7 +50,10 @@ obj-$(CONFIG_RESET_CONTROLLER)	+= reset/  obj-y				+= tty/  obj-y				+= char/ -# gpu/ comes after char for AGP vs DRM startup +# iommu/ comes before gpu as gpu are using iommu controllers +obj-$(CONFIG_IOMMU_SUPPORT)	+= iommu/ + +# gpu/ comes after char for AGP vs DRM startup and after iommu  obj-y				+= gpu/  obj-$(CONFIG_CONNECTOR)		+= connector/ @@ -141,7 +144,6 @@ obj-y				+= clk/  obj-$(CONFIG_MAILBOX)		+= mailbox/  obj-$(CONFIG_HWSPINLOCK)	+= hwspinlock/ -obj-$(CONFIG_IOMMU_SUPPORT)	+= iommu/  obj-$(CONFIG_REMOTEPROC)	+= remoteproc/  obj-$(CONFIG_RPMSG)		+= rpmsg/ diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index 1fdf5e07a1c7..1020b1b53a17 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c @@ -170,7 +170,7 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr)  	acpi_status status;  	int ret; -	if (pr->apic_id == -1) +	if (pr->phys_id == -1)  		return -ENODEV;  	status = acpi_evaluate_integer(pr->handle, "_STA", NULL, &sta); @@ -180,13 +180,13 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr)  	cpu_maps_update_begin();  	cpu_hotplug_begin(); -	ret = acpi_map_lsapic(pr->handle, pr->apic_id, &pr->id); +	ret = acpi_map_cpu(pr->handle, pr->phys_id, &pr->id);  	if (ret)  		goto out;  	ret = arch_register_cpu(pr->id);  	if (ret) { -		acpi_unmap_lsapic(pr->id); +		acpi_unmap_cpu(pr->id);  		goto out;  	} @@ -215,7 +215,7 @@ static int acpi_processor_get_info(struct acpi_device *device)  	union acpi_object object = { 0 };  	struct acpi_buffer buffer = { sizeof(union acpi_object), &object };  	struct acpi_processor *pr = acpi_driver_data(device); -	int apic_id, cpu_index, device_declaration = 0; +	int phys_id, cpu_index, device_declaration = 0;  	acpi_status status = AE_OK;  	static int cpu0_initialized;  	unsigned long long value; @@ -262,15 +262,18 @@ static int acpi_processor_get_info(struct acpi_device *device)  		pr->acpi_id = value;  	} -	apic_id = acpi_get_apicid(pr->handle, device_declaration, pr->acpi_id); -	if (apic_id < 0) -		acpi_handle_debug(pr->handle, "failed to get CPU APIC ID.\n"); -	pr->apic_id = apic_id; +	phys_id = acpi_get_phys_id(pr->handle, device_declaration, pr->acpi_id); +	if (phys_id < 0) +		acpi_handle_debug(pr->handle, "failed to get CPU physical ID.\n"); +	pr->phys_id = phys_id; -	cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id); +	cpu_index = acpi_map_cpuid(pr->phys_id, pr->acpi_id);  	if (!cpu0_initialized && !acpi_has_cpu_in_madt()) {  		cpu0_initialized = 1; -		/* Handle UP system running SMP kernel, with no LAPIC in MADT */ +		/* +		 * Handle UP system running SMP kernel, with no CPU +		 * entry in MADT +		 */  		if ((cpu_index == -1) && (num_online_cpus() == 1))  			cpu_index = 0;  	} @@ -458,7 +461,7 @@ static void acpi_processor_remove(struct acpi_device *device)  	/* Remove the CPU. */  	arch_unregister_cpu(pr->id); -	acpi_unmap_lsapic(pr->id); +	acpi_unmap_cpu(pr->id);  	cpu_hotplug_done();  	cpu_maps_update_done(); diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index c2daa85fc9f7..c0d44d394ca3 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -257,7 +257,7 @@ int acpi_bus_init_power(struct acpi_device *device)  	device->power.state = ACPI_STATE_UNKNOWN;  	if (!acpi_device_is_present(device)) -		return 0; +		return -ENXIO;  	result = acpi_device_get_power(device, &state);  	if (result) diff --git a/drivers/acpi/int340x_thermal.c b/drivers/acpi/int340x_thermal.c index a27d31d1ba24..9dcf83682e36 100644 --- a/drivers/acpi/int340x_thermal.c +++ b/drivers/acpi/int340x_thermal.c @@ -14,10 +14,10 @@  #include "internal.h" -#define DO_ENUMERATION 0x01 +#define INT3401_DEVICE 0X01  static const struct acpi_device_id int340x_thermal_device_ids[] = { -	{"INT3400", DO_ENUMERATION }, -	{"INT3401"}, +	{"INT3400"}, +	{"INT3401", INT3401_DEVICE},  	{"INT3402"},  	{"INT3403"},  	{"INT3404"}, @@ -34,7 +34,10 @@ static int int340x_thermal_handler_attach(struct acpi_device *adev,  					const struct acpi_device_id *id)  {  #if defined(CONFIG_INT340X_THERMAL) || defined(CONFIG_INT340X_THERMAL_MODULE) -	if (id->driver_data == DO_ENUMERATION) +	acpi_create_platform_device(adev); +#elif defined(INTEL_SOC_DTS_THERMAL) || defined(INTEL_SOC_DTS_THERMAL_MODULE) +	/* Intel SoC DTS thermal driver needs INT3401 to set IRQ descriptor */ +	if (id->driver_data == INT3401_DEVICE)  		acpi_create_platform_device(adev);  #endif  	return 1; diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 342942f90a10..02e48394276c 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -69,7 +69,7 @@ static int map_madt_entry(int type, u32 acpi_id)  	unsigned long madt_end, entry;  	static struct acpi_table_madt *madt;  	static int read_madt; -	int apic_id = -1; +	int phys_id = -1;	/* CPU hardware ID */  	if (!read_madt) {  		if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0, @@ -79,7 +79,7 @@ static int map_madt_entry(int type, u32 acpi_id)  	}  	if (!madt) -		return apic_id; +		return phys_id;  	entry = (unsigned long)madt;  	madt_end = entry + madt->header.length; @@ -91,18 +91,18 @@ static int map_madt_entry(int type, u32 acpi_id)  		struct acpi_subtable_header *header =  			(struct acpi_subtable_header *)entry;  		if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { -			if (!map_lapic_id(header, acpi_id, &apic_id)) +			if (!map_lapic_id(header, acpi_id, &phys_id))  				break;  		} else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) { -			if (!map_x2apic_id(header, type, acpi_id, &apic_id)) +			if (!map_x2apic_id(header, type, acpi_id, &phys_id))  				break;  		} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { -			if (!map_lsapic_id(header, type, acpi_id, &apic_id)) +			if (!map_lsapic_id(header, type, acpi_id, &phys_id))  				break;  		}  		entry += header->length;  	} -	return apic_id; +	return phys_id;  }  static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) @@ -110,7 +110,7 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id)  	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };  	union acpi_object *obj;  	struct acpi_subtable_header *header; -	int apic_id = -1; +	int phys_id = -1;  	if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))  		goto exit; @@ -126,38 +126,38 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id)  	header = (struct acpi_subtable_header *)obj->buffer.pointer;  	if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) -		map_lapic_id(header, acpi_id, &apic_id); +		map_lapic_id(header, acpi_id, &phys_id);  	else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) -		map_lsapic_id(header, type, acpi_id, &apic_id); +		map_lsapic_id(header, type, acpi_id, &phys_id);  	else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) -		map_x2apic_id(header, type, acpi_id, &apic_id); +		map_x2apic_id(header, type, acpi_id, &phys_id);  exit:  	kfree(buffer.pointer); -	return apic_id; +	return phys_id;  } -int acpi_get_apicid(acpi_handle handle, int type, u32 acpi_id) +int acpi_get_phys_id(acpi_handle handle, int type, u32 acpi_id)  { -	int apic_id; +	int phys_id; -	apic_id = map_mat_entry(handle, type, acpi_id); -	if (apic_id == -1) -		apic_id = map_madt_entry(type, acpi_id); +	phys_id = map_mat_entry(handle, type, acpi_id); +	if (phys_id == -1) +		phys_id = map_madt_entry(type, acpi_id); -	return apic_id; +	return phys_id;  } -int acpi_map_cpuid(int apic_id, u32 acpi_id) +int acpi_map_cpuid(int phys_id, u32 acpi_id)  {  #ifdef CONFIG_SMP  	int i;  #endif -	if (apic_id == -1) { +	if (phys_id == -1) {  		/*  		 * On UP processor, there is no _MAT or MADT table. -		 * So above apic_id is always set to -1. +		 * So above phys_id is always set to -1.  		 *  		 * BIOS may define multiple CPU handles even for UP processor.  		 * For example, @@ -170,7 +170,7 @@ int acpi_map_cpuid(int apic_id, u32 acpi_id)  		 *     Processor (CPU3, 0x03, 0x00000410, 0x06) {}  		 * }  		 * -		 * Ignores apic_id and always returns 0 for the processor +		 * Ignores phys_id and always returns 0 for the processor  		 * handle with acpi id 0 if nr_cpu_ids is 1.  		 * This should be the case if SMP tables are not found.  		 * Return -1 for other CPU's handle. @@ -178,28 +178,28 @@ int acpi_map_cpuid(int apic_id, u32 acpi_id)  		if (nr_cpu_ids <= 1 && acpi_id == 0)  			return acpi_id;  		else -			return apic_id; +			return phys_id;  	}  #ifdef CONFIG_SMP  	for_each_possible_cpu(i) { -		if (cpu_physical_id(i) == apic_id) +		if (cpu_physical_id(i) == phys_id)  			return i;  	}  #else  	/* In UP kernel, only processor 0 is valid */ -	if (apic_id == 0) -		return apic_id; +	if (phys_id == 0) +		return phys_id;  #endif  	return -1;  }  int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)  { -	int apic_id; +	int phys_id; -	apic_id = acpi_get_apicid(handle, type, acpi_id); +	phys_id = acpi_get_phys_id(handle, type, acpi_id); -	return acpi_map_cpuid(apic_id, acpi_id); +	return acpi_map_cpuid(phys_id, acpi_id);  }  EXPORT_SYMBOL_GPL(acpi_get_cpuid); diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 16914cc30882..dc4d8960684a 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1001,7 +1001,7 @@ static void acpi_free_power_resources_lists(struct acpi_device *device)  	if (device->wakeup.flags.valid)  		acpi_power_resources_list_free(&device->wakeup.resources); -	if (!device->flags.power_manageable) +	if (!device->power.flags.power_resources)  		return;  	for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) { @@ -1744,10 +1744,8 @@ static void acpi_bus_get_power_flags(struct acpi_device *device)  			device->power.flags.power_resources)  		device->power.states[ACPI_STATE_D3_COLD].flags.os_accessible = 1; -	if (acpi_bus_init_power(device)) { -		acpi_free_power_resources_lists(device); +	if (acpi_bus_init_power(device))  		device->flags.power_manageable = 0; -	}  }  static void acpi_bus_get_flags(struct acpi_device *device) @@ -2371,13 +2369,18 @@ static void acpi_bus_attach(struct acpi_device *device)  	/* Skip devices that are not present. */  	if (!acpi_device_is_present(device)) {  		device->flags.visited = false; +		device->flags.power_manageable = 0;  		return;  	}  	if (device->handler)  		goto ok;  	if (!device->flags.initialized) { -		acpi_bus_update_power(device, NULL); +		device->flags.power_manageable = +			device->power.states[ACPI_STATE_D0].flags.valid; +		if (acpi_bus_init_power(device)) +			device->flags.power_manageable = 0; +  		device->flags.initialized = true;  	}  	device->flags.visited = false; diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index c72e79d2c5ad..032db459370f 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -522,6 +522,16 @@ static struct dmi_system_id video_dmi_table[] __initdata = {  		DMI_MATCH(DMI_PRODUCT_NAME, "370R4E/370R4V/370R5E/3570RE/370R5V"),  		},  	}, + +	{ +	 /* https://bugzilla.redhat.com/show_bug.cgi?id=1163574 */ +	 .callback = video_disable_native_backlight, +	 .ident = "Dell XPS15 L521X", +	 .matches = { +		DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), +		DMI_MATCH(DMI_PRODUCT_NAME, "XPS L521X"), +		}, +	},  	{}  }; diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c index ae9f615382f6..aa2224aa7caa 100644 --- a/drivers/block/null_blk.c +++ b/drivers/block/null_blk.c @@ -530,7 +530,7 @@ static int null_add_dev(void)  			goto out_cleanup_queues;  		nullb->q = blk_mq_init_queue(&nullb->tag_set); -		if (!nullb->q) { +		if (IS_ERR(nullb->q)) {  			rv = -ENOMEM;  			goto out_cleanup_tags;  		} diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index b1d5d8797315..cb529e9a82dd 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -215,6 +215,7 @@ static void nvme_set_info(struct nvme_cmd_info *cmd, void *ctx,  	cmd->fn = handler;  	cmd->ctx = ctx;  	cmd->aborted = 0; +	blk_mq_start_request(blk_mq_rq_from_pdu(cmd));  }  /* Special values must be less than 0x1000 */ @@ -431,8 +432,13 @@ static void req_completion(struct nvme_queue *nvmeq, void *ctx,  	if (unlikely(status)) {  		if (!(status & NVME_SC_DNR || blk_noretry_request(req))  		    && (jiffies - req->start_time) < req->timeout) { +			unsigned long flags; +  			blk_mq_requeue_request(req); -			blk_mq_kick_requeue_list(req->q); +			spin_lock_irqsave(req->q->queue_lock, flags); +			if (!blk_queue_stopped(req->q)) +				blk_mq_kick_requeue_list(req->q); +			spin_unlock_irqrestore(req->q->queue_lock, flags);  			return;  		}  		req->errors = nvme_error_status(status); @@ -664,8 +670,6 @@ static int nvme_queue_rq(struct blk_mq_hw_ctx *hctx,  		}  	} -	blk_mq_start_request(req); -  	nvme_set_info(cmd, iod, req_completion);  	spin_lock_irq(&nvmeq->q_lock);  	if (req->cmd_flags & REQ_DISCARD) @@ -835,6 +839,7 @@ static int nvme_submit_async_admin_req(struct nvme_dev *dev)  	if (IS_ERR(req))  		return PTR_ERR(req); +	req->cmd_flags |= REQ_NO_TIMEOUT;  	cmd_info = blk_mq_rq_to_pdu(req);  	nvme_set_info(cmd_info, req, async_req_completion); @@ -1016,14 +1021,19 @@ static void nvme_abort_req(struct request *req)  	struct nvme_command cmd;  	if (!nvmeq->qid || cmd_rq->aborted) { +		unsigned long flags; + +		spin_lock_irqsave(&dev_list_lock, flags);  		if (work_busy(&dev->reset_work)) -			return; +			goto out;  		list_del_init(&dev->node);  		dev_warn(&dev->pci_dev->dev,  			"I/O %d QID %d timeout, reset controller\n",  							req->tag, nvmeq->qid);  		dev->reset_workfn = nvme_reset_failed_dev;  		queue_work(nvme_workq, &dev->reset_work); + out: +		spin_unlock_irqrestore(&dev_list_lock, flags);  		return;  	} @@ -1064,15 +1074,22 @@ static void nvme_cancel_queue_ios(struct blk_mq_hw_ctx *hctx,  	void *ctx;  	nvme_completion_fn fn;  	struct nvme_cmd_info *cmd; -	static struct nvme_completion cqe = { -		.status = cpu_to_le16(NVME_SC_ABORT_REQ << 1), -	}; +	struct nvme_completion cqe; + +	if (!blk_mq_request_started(req)) +		return;  	cmd = blk_mq_rq_to_pdu(req);  	if (cmd->ctx == CMD_CTX_CANCELLED)  		return; +	if (blk_queue_dying(req->q)) +		cqe.status = cpu_to_le16((NVME_SC_ABORT_REQ | NVME_SC_DNR) << 1); +	else +		cqe.status = cpu_to_le16(NVME_SC_ABORT_REQ << 1); + +  	dev_warn(nvmeq->q_dmadev, "Cancelling I/O %d QID %d\n",  						req->tag, nvmeq->qid);  	ctx = cancel_cmd_info(cmd, &fn); @@ -1084,17 +1101,29 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved)  	struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(req);  	struct nvme_queue *nvmeq = cmd->nvmeq; -	dev_warn(nvmeq->q_dmadev, "Timeout I/O %d QID %d\n", req->tag, -							nvmeq->qid); -	if (nvmeq->dev->initialized) -		nvme_abort_req(req); -  	/*  	 * The aborted req will be completed on receiving the abort req.  	 * We enable the timer again. If hit twice, it'll cause a device reset,  	 * as the device then is in a faulty state.  	 */ -	return BLK_EH_RESET_TIMER; +	int ret = BLK_EH_RESET_TIMER; + +	dev_warn(nvmeq->q_dmadev, "Timeout I/O %d QID %d\n", req->tag, +							nvmeq->qid); + +	spin_lock_irq(&nvmeq->q_lock); +	if (!nvmeq->dev->initialized) { +		/* +		 * Force cancelled command frees the request, which requires we +		 * return BLK_EH_NOT_HANDLED. +		 */ +		nvme_cancel_queue_ios(nvmeq->hctx, req, nvmeq, reserved); +		ret = BLK_EH_NOT_HANDLED; +	} else +		nvme_abort_req(req); +	spin_unlock_irq(&nvmeq->q_lock); + +	return ret;  }  static void nvme_free_queue(struct nvme_queue *nvmeq) @@ -1131,10 +1160,16 @@ static void nvme_free_queues(struct nvme_dev *dev, int lowest)   */  static int nvme_suspend_queue(struct nvme_queue *nvmeq)  { -	int vector = nvmeq->dev->entry[nvmeq->cq_vector].vector; +	int vector;  	spin_lock_irq(&nvmeq->q_lock); +	if (nvmeq->cq_vector == -1) { +		spin_unlock_irq(&nvmeq->q_lock); +		return 1; +	} +	vector = nvmeq->dev->entry[nvmeq->cq_vector].vector;  	nvmeq->dev->online_queues--; +	nvmeq->cq_vector = -1;  	spin_unlock_irq(&nvmeq->q_lock);  	irq_set_affinity_hint(vector, NULL); @@ -1169,11 +1204,13 @@ static void nvme_disable_queue(struct nvme_dev *dev, int qid)  		adapter_delete_sq(dev, qid);  		adapter_delete_cq(dev, qid);  	} +	if (!qid && dev->admin_q) +		blk_mq_freeze_queue_start(dev->admin_q);  	nvme_clear_queue(nvmeq);  }  static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, -							int depth, int vector) +							int depth)  {  	struct device *dmadev = &dev->pci_dev->dev;  	struct nvme_queue *nvmeq = kzalloc(sizeof(*nvmeq), GFP_KERNEL); @@ -1199,7 +1236,6 @@ static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid,  	nvmeq->cq_phase = 1;  	nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride];  	nvmeq->q_depth = depth; -	nvmeq->cq_vector = vector;  	nvmeq->qid = qid;  	dev->queue_count++;  	dev->queues[qid] = nvmeq; @@ -1244,6 +1280,7 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid)  	struct nvme_dev *dev = nvmeq->dev;  	int result; +	nvmeq->cq_vector = qid - 1;  	result = adapter_alloc_cq(dev, qid, nvmeq);  	if (result < 0)  		return result; @@ -1355,6 +1392,14 @@ static struct blk_mq_ops nvme_mq_ops = {  	.timeout	= nvme_timeout,  }; +static void nvme_dev_remove_admin(struct nvme_dev *dev) +{ +	if (dev->admin_q && !blk_queue_dying(dev->admin_q)) { +		blk_cleanup_queue(dev->admin_q); +		blk_mq_free_tag_set(&dev->admin_tagset); +	} +} +  static int nvme_alloc_admin_tags(struct nvme_dev *dev)  {  	if (!dev->admin_q) { @@ -1370,21 +1415,20 @@ static int nvme_alloc_admin_tags(struct nvme_dev *dev)  			return -ENOMEM;  		dev->admin_q = blk_mq_init_queue(&dev->admin_tagset); -		if (!dev->admin_q) { +		if (IS_ERR(dev->admin_q)) {  			blk_mq_free_tag_set(&dev->admin_tagset);  			return -ENOMEM;  		} -	} +		if (!blk_get_queue(dev->admin_q)) { +			nvme_dev_remove_admin(dev); +			return -ENODEV; +		} +	} else +		blk_mq_unfreeze_queue(dev->admin_q);  	return 0;  } -static void nvme_free_admin_tags(struct nvme_dev *dev) -{ -	if (dev->admin_q) -		blk_mq_free_tag_set(&dev->admin_tagset); -} -  static int nvme_configure_admin_queue(struct nvme_dev *dev)  {  	int result; @@ -1416,7 +1460,7 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)  	nvmeq = dev->queues[0];  	if (!nvmeq) { -		nvmeq = nvme_alloc_queue(dev, 0, NVME_AQ_DEPTH, 0); +		nvmeq = nvme_alloc_queue(dev, 0, NVME_AQ_DEPTH);  		if (!nvmeq)  			return -ENOMEM;  	} @@ -1439,18 +1483,13 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)  	if (result)  		goto free_nvmeq; -	result = nvme_alloc_admin_tags(dev); -	if (result) -		goto free_nvmeq; - +	nvmeq->cq_vector = 0;  	result = queue_request_irq(dev, nvmeq, nvmeq->irqname);  	if (result) -		goto free_tags; +		goto free_nvmeq;  	return result; - free_tags: -	nvme_free_admin_tags(dev);   free_nvmeq:  	nvme_free_queues(dev, 0);  	return result; @@ -1944,7 +1983,7 @@ static void nvme_create_io_queues(struct nvme_dev *dev)  	unsigned i;  	for (i = dev->queue_count; i <= dev->max_qid; i++) -		if (!nvme_alloc_queue(dev, i, dev->q_depth, i - 1)) +		if (!nvme_alloc_queue(dev, i, dev->q_depth))  			break;  	for (i = dev->online_queues; i <= dev->queue_count - 1; i++) @@ -2235,13 +2274,18 @@ static void nvme_wait_dq(struct nvme_delq_ctx *dq, struct nvme_dev *dev)  			break;  		if (!schedule_timeout(ADMIN_TIMEOUT) ||  					fatal_signal_pending(current)) { +			/* +			 * Disable the controller first since we can't trust it +			 * at this point, but leave the admin queue enabled +			 * until all queue deletion requests are flushed. +			 * FIXME: This may take a while if there are more h/w +			 * queues than admin tags. +			 */  			set_current_state(TASK_RUNNING); -  			nvme_disable_ctrl(dev, readq(&dev->bar->cap)); -			nvme_disable_queue(dev, 0); - -			send_sig(SIGKILL, dq->worker->task, 1); +			nvme_clear_queue(dev->queues[0]);  			flush_kthread_worker(dq->worker); +			nvme_disable_queue(dev, 0);  			return;  		}  	} @@ -2318,7 +2362,6 @@ static void nvme_del_queue_start(struct kthread_work *work)  {  	struct nvme_queue *nvmeq = container_of(work, struct nvme_queue,  							cmdinfo.work); -	allow_signal(SIGKILL);  	if (nvme_delete_sq(nvmeq))  		nvme_del_queue_end(nvmeq);  } @@ -2376,6 +2419,34 @@ static void nvme_dev_list_remove(struct nvme_dev *dev)  		kthread_stop(tmp);  } +static void nvme_freeze_queues(struct nvme_dev *dev) +{ +	struct nvme_ns *ns; + +	list_for_each_entry(ns, &dev->namespaces, list) { +		blk_mq_freeze_queue_start(ns->queue); + +		spin_lock(ns->queue->queue_lock); +		queue_flag_set(QUEUE_FLAG_STOPPED, ns->queue); +		spin_unlock(ns->queue->queue_lock); + +		blk_mq_cancel_requeue_work(ns->queue); +		blk_mq_stop_hw_queues(ns->queue); +	} +} + +static void nvme_unfreeze_queues(struct nvme_dev *dev) +{ +	struct nvme_ns *ns; + +	list_for_each_entry(ns, &dev->namespaces, list) { +		queue_flag_clear_unlocked(QUEUE_FLAG_STOPPED, ns->queue); +		blk_mq_unfreeze_queue(ns->queue); +		blk_mq_start_stopped_hw_queues(ns->queue, true); +		blk_mq_kick_requeue_list(ns->queue); +	} +} +  static void nvme_dev_shutdown(struct nvme_dev *dev)  {  	int i; @@ -2384,8 +2455,10 @@ static void nvme_dev_shutdown(struct nvme_dev *dev)  	dev->initialized = 0;  	nvme_dev_list_remove(dev); -	if (dev->bar) +	if (dev->bar) { +		nvme_freeze_queues(dev);  		csts = readl(&dev->bar->csts); +	}  	if (csts & NVME_CSTS_CFS || !(csts & NVME_CSTS_RDY)) {  		for (i = dev->queue_count - 1; i >= 0; i--) {  			struct nvme_queue *nvmeq = dev->queues[i]; @@ -2400,12 +2473,6 @@ static void nvme_dev_shutdown(struct nvme_dev *dev)  	nvme_dev_unmap(dev);  } -static void nvme_dev_remove_admin(struct nvme_dev *dev) -{ -	if (dev->admin_q && !blk_queue_dying(dev->admin_q)) -		blk_cleanup_queue(dev->admin_q); -} -  static void nvme_dev_remove(struct nvme_dev *dev)  {  	struct nvme_ns *ns; @@ -2413,8 +2480,10 @@ static void nvme_dev_remove(struct nvme_dev *dev)  	list_for_each_entry(ns, &dev->namespaces, list) {  		if (ns->disk->flags & GENHD_FL_UP)  			del_gendisk(ns->disk); -		if (!blk_queue_dying(ns->queue)) +		if (!blk_queue_dying(ns->queue)) { +			blk_mq_abort_requeue_list(ns->queue);  			blk_cleanup_queue(ns->queue); +		}  	}  } @@ -2495,6 +2564,7 @@ static void nvme_free_dev(struct kref *kref)  	nvme_free_namespaces(dev);  	nvme_release_instance(dev);  	blk_mq_free_tag_set(&dev->tagset); +	blk_put_queue(dev->admin_q);  	kfree(dev->queues);  	kfree(dev->entry);  	kfree(dev); @@ -2591,15 +2661,20 @@ static int nvme_dev_start(struct nvme_dev *dev)  	}  	nvme_init_queue(dev->queues[0], 0); +	result = nvme_alloc_admin_tags(dev); +	if (result) +		goto disable;  	result = nvme_setup_io_queues(dev);  	if (result) -		goto disable; +		goto free_tags;  	nvme_set_irq_hints(dev);  	return result; + free_tags: +	nvme_dev_remove_admin(dev);   disable:  	nvme_disable_queue(dev, 0);  	nvme_dev_list_remove(dev); @@ -2639,6 +2714,9 @@ static int nvme_dev_resume(struct nvme_dev *dev)  		dev->reset_workfn = nvme_remove_disks;  		queue_work(nvme_workq, &dev->reset_work);  		spin_unlock(&dev_list_lock); +	} else { +		nvme_unfreeze_queues(dev); +		nvme_set_irq_hints(dev);  	}  	dev->initialized = 1;  	return 0; @@ -2776,11 +2854,10 @@ static void nvme_remove(struct pci_dev *pdev)  	pci_set_drvdata(pdev, NULL);  	flush_work(&dev->reset_work);  	misc_deregister(&dev->miscdev); -	nvme_dev_remove(dev);  	nvme_dev_shutdown(dev); +	nvme_dev_remove(dev);  	nvme_dev_remove_admin(dev);  	nvme_free_queues(dev, 0); -	nvme_free_admin_tags(dev);  	nvme_release_prp_pools(dev);  	kref_put(&dev->kref, nvme_free_dev);  } diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 7ef7c098708f..cdfbd21e3597 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -638,7 +638,7 @@ static int virtblk_probe(struct virtio_device *vdev)  		goto out_put_disk;  	q = vblk->disk->queue = blk_mq_init_queue(&vblk->tag_set); -	if (!q) { +	if (IS_ERR(q)) {  		err = -ENOMEM;  		goto out_free_tags;  	} diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index fd5a5e85d7dc..982b96323f82 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -969,7 +969,8 @@ static void sender(void                *send_info,  		do_gettimeofday(&t);  		pr_info("**Enqueue %02x %02x: %ld.%6.6ld\n", -		       msg->data[0], msg->data[1], t.tv_sec, t.tv_usec); +		       msg->data[0], msg->data[1], +		       (long) t.tv_sec, (long) t.tv_usec);  	}  } diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c index 380478562b7d..5c062548957c 100644 --- a/drivers/dma/dw/core.c +++ b/drivers/dma/dw/core.c @@ -1505,7 +1505,6 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)  	dw->regs = chip->regs;  	chip->dw = dw; -	pm_runtime_enable(chip->dev);  	pm_runtime_get_sync(chip->dev);  	dw_params = dma_read_byaddr(chip->regs, DW_PARAMS); @@ -1703,7 +1702,6 @@ int dw_dma_remove(struct dw_dma_chip *chip)  	}  	pm_runtime_put_sync_suspend(chip->dev); -	pm_runtime_disable(chip->dev);  	return 0;  }  EXPORT_SYMBOL_GPL(dw_dma_remove); diff --git a/drivers/dma/dw/platform.c b/drivers/dma/dw/platform.c index a630161473a4..32ea1aca7a0e 100644 --- a/drivers/dma/dw/platform.c +++ b/drivers/dma/dw/platform.c @@ -15,6 +15,7 @@  #include <linux/module.h>  #include <linux/device.h>  #include <linux/clk.h> +#include <linux/pm_runtime.h>  #include <linux/platform_device.h>  #include <linux/dmaengine.h>  #include <linux/dma-mapping.h> @@ -185,6 +186,8 @@ static int dw_probe(struct platform_device *pdev)  	if (err)  		return err; +	pm_runtime_enable(&pdev->dev); +  	err = dw_dma_probe(chip, pdata);  	if (err)  		goto err_dw_dma_probe; @@ -205,6 +208,7 @@ static int dw_probe(struct platform_device *pdev)  	return 0;  err_dw_dma_probe: +	pm_runtime_disable(&pdev->dev);  	clk_disable_unprepare(chip->clk);  	return err;  } @@ -217,6 +221,7 @@ static int dw_remove(struct platform_device *pdev)  		of_dma_controller_free(pdev->dev.of_node);  	dw_dma_remove(chip); +	pm_runtime_disable(&pdev->dev);  	clk_disable_unprepare(chip->clk);  	return 0; diff --git a/drivers/gpio/gpio-dln2.c b/drivers/gpio/gpio-dln2.c index 978b51eae2ec..ce3c1558cb0a 100644 --- a/drivers/gpio/gpio-dln2.c +++ b/drivers/gpio/gpio-dln2.c @@ -47,13 +47,6 @@  #define DLN2_GPIO_MAX_PINS 32 -struct dln2_irq_work { -	struct work_struct work; -	struct dln2_gpio *dln2; -	int pin; -	int type; -}; -  struct dln2_gpio {  	struct platform_device *pdev;  	struct gpio_chip gpio; @@ -64,10 +57,12 @@ struct dln2_gpio {  	 */  	DECLARE_BITMAP(output_enabled, DLN2_GPIO_MAX_PINS); -	DECLARE_BITMAP(irqs_masked, DLN2_GPIO_MAX_PINS); -	DECLARE_BITMAP(irqs_enabled, DLN2_GPIO_MAX_PINS); -	DECLARE_BITMAP(irqs_pending, DLN2_GPIO_MAX_PINS); -	struct dln2_irq_work *irq_work; +	/* active IRQs - not synced to hardware */ +	DECLARE_BITMAP(unmasked_irqs, DLN2_GPIO_MAX_PINS); +	/* active IRQS - synced to hardware */ +	DECLARE_BITMAP(enabled_irqs, DLN2_GPIO_MAX_PINS); +	int irq_type[DLN2_GPIO_MAX_PINS]; +	struct mutex irq_lock;  };  struct dln2_gpio_pin { @@ -141,16 +136,16 @@ static int dln2_gpio_pin_get_out_val(struct dln2_gpio *dln2, unsigned int pin)  	return !!ret;  } -static void dln2_gpio_pin_set_out_val(struct dln2_gpio *dln2, -				      unsigned int pin, int value) +static int dln2_gpio_pin_set_out_val(struct dln2_gpio *dln2, +				     unsigned int pin, int value)  {  	struct dln2_gpio_pin_val req = {  		.pin = cpu_to_le16(pin),  		.value = value,  	}; -	dln2_transfer_tx(dln2->pdev, DLN2_GPIO_PIN_SET_OUT_VAL, &req, -			 sizeof(req)); +	return dln2_transfer_tx(dln2->pdev, DLN2_GPIO_PIN_SET_OUT_VAL, &req, +				sizeof(req));  }  #define DLN2_GPIO_DIRECTION_IN		0 @@ -267,6 +262,13 @@ static int dln2_gpio_direction_input(struct gpio_chip *chip, unsigned offset)  static int dln2_gpio_direction_output(struct gpio_chip *chip, unsigned offset,  				      int value)  { +	struct dln2_gpio *dln2 = container_of(chip, struct dln2_gpio, gpio); +	int ret; + +	ret = dln2_gpio_pin_set_out_val(dln2, offset, value); +	if (ret < 0) +		return ret; +  	return dln2_gpio_set_direction(chip, offset, DLN2_GPIO_DIRECTION_OUT);  } @@ -297,36 +299,13 @@ static int dln2_gpio_set_event_cfg(struct dln2_gpio *dln2, unsigned pin,  				&req, sizeof(req));  } -static void dln2_irq_work(struct work_struct *w) -{ -	struct dln2_irq_work *iw = container_of(w, struct dln2_irq_work, work); -	struct dln2_gpio *dln2 = iw->dln2; -	u8 type = iw->type & DLN2_GPIO_EVENT_MASK; - -	if (test_bit(iw->pin, dln2->irqs_enabled)) -		dln2_gpio_set_event_cfg(dln2, iw->pin, type, 0); -	else -		dln2_gpio_set_event_cfg(dln2, iw->pin, DLN2_GPIO_EVENT_NONE, 0); -} - -static void dln2_irq_enable(struct irq_data *irqd) -{ -	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); -	struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); -	int pin = irqd_to_hwirq(irqd); - -	set_bit(pin, dln2->irqs_enabled); -	schedule_work(&dln2->irq_work[pin].work); -} - -static void dln2_irq_disable(struct irq_data *irqd) +static void dln2_irq_unmask(struct irq_data *irqd)  {  	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);  	struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio);  	int pin = irqd_to_hwirq(irqd); -	clear_bit(pin, dln2->irqs_enabled); -	schedule_work(&dln2->irq_work[pin].work); +	set_bit(pin, dln2->unmasked_irqs);  }  static void dln2_irq_mask(struct irq_data *irqd) @@ -335,27 +314,7 @@ static void dln2_irq_mask(struct irq_data *irqd)  	struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio);  	int pin = irqd_to_hwirq(irqd); -	set_bit(pin, dln2->irqs_masked); -} - -static void dln2_irq_unmask(struct irq_data *irqd) -{ -	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); -	struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); -	struct device *dev = dln2->gpio.dev; -	int pin = irqd_to_hwirq(irqd); - -	if (test_and_clear_bit(pin, dln2->irqs_pending)) { -		int irq; - -		irq = irq_find_mapping(dln2->gpio.irqdomain, pin); -		if (!irq) { -			dev_err(dev, "pin %d not mapped to IRQ\n", pin); -			return; -		} - -		generic_handle_irq(irq); -	} +	clear_bit(pin, dln2->unmasked_irqs);  }  static int dln2_irq_set_type(struct irq_data *irqd, unsigned type) @@ -366,19 +325,19 @@ static int dln2_irq_set_type(struct irq_data *irqd, unsigned type)  	switch (type) {  	case IRQ_TYPE_LEVEL_HIGH: -		dln2->irq_work[pin].type = DLN2_GPIO_EVENT_LVL_HIGH; +		dln2->irq_type[pin] = DLN2_GPIO_EVENT_LVL_HIGH;  		break;  	case IRQ_TYPE_LEVEL_LOW: -		dln2->irq_work[pin].type = DLN2_GPIO_EVENT_LVL_LOW; +		dln2->irq_type[pin] = DLN2_GPIO_EVENT_LVL_LOW;  		break;  	case IRQ_TYPE_EDGE_BOTH: -		dln2->irq_work[pin].type = DLN2_GPIO_EVENT_CHANGE; +		dln2->irq_type[pin] = DLN2_GPIO_EVENT_CHANGE;  		break;  	case IRQ_TYPE_EDGE_RISING: -		dln2->irq_work[pin].type = DLN2_GPIO_EVENT_CHANGE_RISING; +		dln2->irq_type[pin] = DLN2_GPIO_EVENT_CHANGE_RISING;  		break;  	case IRQ_TYPE_EDGE_FALLING: -		dln2->irq_work[pin].type = DLN2_GPIO_EVENT_CHANGE_FALLING; +		dln2->irq_type[pin] = DLN2_GPIO_EVENT_CHANGE_FALLING;  		break;  	default:  		return -EINVAL; @@ -387,13 +346,50 @@ static int dln2_irq_set_type(struct irq_data *irqd, unsigned type)  	return 0;  } +static void dln2_irq_bus_lock(struct irq_data *irqd) +{ +	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); +	struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); + +	mutex_lock(&dln2->irq_lock); +} + +static void dln2_irq_bus_unlock(struct irq_data *irqd) +{ +	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); +	struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); +	int pin = irqd_to_hwirq(irqd); +	int enabled, unmasked; +	unsigned type; +	int ret; + +	enabled = test_bit(pin, dln2->enabled_irqs); +	unmasked = test_bit(pin, dln2->unmasked_irqs); + +	if (enabled != unmasked) { +		if (unmasked) { +			type = dln2->irq_type[pin] & DLN2_GPIO_EVENT_MASK; +			set_bit(pin, dln2->enabled_irqs); +		} else { +			type = DLN2_GPIO_EVENT_NONE; +			clear_bit(pin, dln2->enabled_irqs); +		} + +		ret = dln2_gpio_set_event_cfg(dln2, pin, type, 0); +		if (ret) +			dev_err(dln2->gpio.dev, "failed to set event\n"); +	} + +	mutex_unlock(&dln2->irq_lock); +} +  static struct irq_chip dln2_gpio_irqchip = {  	.name = "dln2-irq", -	.irq_enable = dln2_irq_enable, -	.irq_disable = dln2_irq_disable,  	.irq_mask = dln2_irq_mask,  	.irq_unmask = dln2_irq_unmask,  	.irq_set_type = dln2_irq_set_type, +	.irq_bus_lock = dln2_irq_bus_lock, +	.irq_bus_sync_unlock = dln2_irq_bus_unlock,  };  static void dln2_gpio_event(struct platform_device *pdev, u16 echo, @@ -425,14 +421,7 @@ static void dln2_gpio_event(struct platform_device *pdev, u16 echo,  		return;  	} -	if (!test_bit(pin, dln2->irqs_enabled)) -		return; -	if (test_bit(pin, dln2->irqs_masked)) { -		set_bit(pin, dln2->irqs_pending); -		return; -	} - -	switch (dln2->irq_work[pin].type) { +	switch (dln2->irq_type[pin]) {  	case DLN2_GPIO_EVENT_CHANGE_RISING:  		if (event->value)  			generic_handle_irq(irq); @@ -451,7 +440,7 @@ static int dln2_gpio_probe(struct platform_device *pdev)  	struct dln2_gpio *dln2;  	struct device *dev = &pdev->dev;  	int pins; -	int i, ret; +	int ret;  	pins = dln2_gpio_get_pin_count(pdev);  	if (pins < 0) { @@ -467,15 +456,7 @@ static int dln2_gpio_probe(struct platform_device *pdev)  	if (!dln2)  		return -ENOMEM; -	dln2->irq_work = devm_kcalloc(&pdev->dev, pins, -				      sizeof(struct dln2_irq_work), GFP_KERNEL); -	if (!dln2->irq_work) -		return -ENOMEM; -	for (i = 0; i < pins; i++) { -		INIT_WORK(&dln2->irq_work[i].work, dln2_irq_work); -		dln2->irq_work[i].pin = i; -		dln2->irq_work[i].dln2 = dln2; -	} +	mutex_init(&dln2->irq_lock);  	dln2->pdev = pdev; @@ -529,11 +510,8 @@ out:  static int dln2_gpio_remove(struct platform_device *pdev)  {  	struct dln2_gpio *dln2 = platform_get_drvdata(pdev); -	int i;  	dln2_unregister_event_cb(pdev, DLN2_GPIO_CONDITION_MET_EV); -	for (i = 0; i < dln2->gpio.ngpio; i++) -		flush_work(&dln2->irq_work[i].work);  	gpiochip_remove(&dln2->gpio);  	return 0; diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c index 09daaf2aeb56..3a5a71050559 100644 --- a/drivers/gpio/gpio-grgpio.c +++ b/drivers/gpio/gpio-grgpio.c @@ -441,7 +441,8 @@ static int grgpio_probe(struct platform_device *ofdev)  	err = gpiochip_add(gc);  	if (err) {  		dev_err(&ofdev->dev, "Could not add gpiochip\n"); -		irq_domain_remove(priv->domain); +		if (priv->domain) +			irq_domain_remove(priv->domain);  		return err;  	} diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 66e40398b3d3..e620807418ea 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o  obj-$(CONFIG_DRM_TTM)	+= ttm/  obj-$(CONFIG_DRM_TDFX)	+= tdfx/  obj-$(CONFIG_DRM_R128)	+= r128/ +obj-$(CONFIG_HSA_AMD) += amd/amdkfd/  obj-$(CONFIG_DRM_RADEON)+= radeon/  obj-$(CONFIG_DRM_MGA)	+= mga/  obj-$(CONFIG_DRM_I810)	+= i810/ @@ -67,4 +68,3 @@ obj-$(CONFIG_DRM_IMX) += imx/  obj-y			+= i2c/  obj-y			+= panel/  obj-y			+= bridge/ -obj-$(CONFIG_HSA_AMD) += amd/amdkfd/ diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 7d4974b83af7..fcfdf23e1913 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -31,7 +31,6 @@  #include <uapi/linux/kfd_ioctl.h>  #include <linux/time.h>  #include <linux/mm.h> -#include <linux/uaccess.h>  #include <uapi/asm-generic/mman-common.h>  #include <asm/processor.h>  #include "kfd_priv.h" @@ -127,17 +126,14 @@ static int kfd_open(struct inode *inode, struct file *filep)  	return 0;  } -static long kfd_ioctl_get_version(struct file *filep, struct kfd_process *p, -					void __user *arg) +static int kfd_ioctl_get_version(struct file *filep, struct kfd_process *p, +					void *data)  { -	struct kfd_ioctl_get_version_args args; +	struct kfd_ioctl_get_version_args *args = data;  	int err = 0; -	args.major_version = KFD_IOCTL_MAJOR_VERSION; -	args.minor_version = KFD_IOCTL_MINOR_VERSION; - -	if (copy_to_user(arg, &args, sizeof(args))) -		err = -EFAULT; +	args->major_version = KFD_IOCTL_MAJOR_VERSION; +	args->minor_version = KFD_IOCTL_MINOR_VERSION;  	return err;  } @@ -221,10 +217,10 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,  	return 0;  } -static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, -					void __user *arg) +static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, +					void *data)  { -	struct kfd_ioctl_create_queue_args args; +	struct kfd_ioctl_create_queue_args *args = data;  	struct kfd_dev *dev;  	int err = 0;  	unsigned int queue_id; @@ -233,16 +229,13 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,  	memset(&q_properties, 0, sizeof(struct queue_properties)); -	if (copy_from_user(&args, arg, sizeof(args))) -		return -EFAULT; -  	pr_debug("kfd: creating queue ioctl\n"); -	err = set_queue_properties_from_user(&q_properties, &args); +	err = set_queue_properties_from_user(&q_properties, args);  	if (err)  		return err; -	dev = kfd_device_by_id(args.gpu_id); +	dev = kfd_device_by_id(args->gpu_id);  	if (dev == NULL)  		return -EINVAL; @@ -250,7 +243,7 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,  	pdd = kfd_bind_process_to_device(dev, p);  	if (IS_ERR(pdd)) { -		err = PTR_ERR(pdd); +		err = -ESRCH;  		goto err_bind_process;  	} @@ -263,33 +256,26 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,  	if (err != 0)  		goto err_create_queue; -	args.queue_id = queue_id; +	args->queue_id = queue_id;  	/* Return gpu_id as doorbell offset for mmap usage */ -	args.doorbell_offset = args.gpu_id << PAGE_SHIFT; - -	if (copy_to_user(arg, &args, sizeof(args))) { -		err = -EFAULT; -		goto err_copy_args_out; -	} +	args->doorbell_offset = args->gpu_id << PAGE_SHIFT;  	mutex_unlock(&p->mutex); -	pr_debug("kfd: queue id %d was created successfully\n", args.queue_id); +	pr_debug("kfd: queue id %d was created successfully\n", args->queue_id);  	pr_debug("ring buffer address == 0x%016llX\n", -			args.ring_base_address); +			args->ring_base_address);  	pr_debug("read ptr address    == 0x%016llX\n", -			args.read_pointer_address); +			args->read_pointer_address);  	pr_debug("write ptr address   == 0x%016llX\n", -			args.write_pointer_address); +			args->write_pointer_address);  	return 0; -err_copy_args_out: -	pqm_destroy_queue(&p->pqm, queue_id);  err_create_queue:  err_bind_process:  	mutex_unlock(&p->mutex); @@ -297,99 +283,90 @@ err_bind_process:  }  static int kfd_ioctl_destroy_queue(struct file *filp, struct kfd_process *p, -					void __user *arg) +					void *data)  {  	int retval; -	struct kfd_ioctl_destroy_queue_args args; - -	if (copy_from_user(&args, arg, sizeof(args))) -		return -EFAULT; +	struct kfd_ioctl_destroy_queue_args *args = data;  	pr_debug("kfd: destroying queue id %d for PASID %d\n", -				args.queue_id, +				args->queue_id,  				p->pasid);  	mutex_lock(&p->mutex); -	retval = pqm_destroy_queue(&p->pqm, args.queue_id); +	retval = pqm_destroy_queue(&p->pqm, args->queue_id);  	mutex_unlock(&p->mutex);  	return retval;  }  static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p, -					void __user *arg) +					void *data)  {  	int retval; -	struct kfd_ioctl_update_queue_args args; +	struct kfd_ioctl_update_queue_args *args = data;  	struct queue_properties properties; -	if (copy_from_user(&args, arg, sizeof(args))) -		return -EFAULT; - -	if (args.queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) { +	if (args->queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) {  		pr_err("kfd: queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n");  		return -EINVAL;  	} -	if (args.queue_priority > KFD_MAX_QUEUE_PRIORITY) { +	if (args->queue_priority > KFD_MAX_QUEUE_PRIORITY) {  		pr_err("kfd: queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n");  		return -EINVAL;  	} -	if ((args.ring_base_address) && +	if ((args->ring_base_address) &&  		(!access_ok(VERIFY_WRITE, -			(const void __user *) args.ring_base_address, +			(const void __user *) args->ring_base_address,  			sizeof(uint64_t)))) {  		pr_err("kfd: can't access ring base address\n");  		return -EFAULT;  	} -	if (!is_power_of_2(args.ring_size) && (args.ring_size != 0)) { +	if (!is_power_of_2(args->ring_size) && (args->ring_size != 0)) {  		pr_err("kfd: ring size must be a power of 2 or 0\n");  		return -EINVAL;  	} -	properties.queue_address = args.ring_base_address; -	properties.queue_size = args.ring_size; -	properties.queue_percent = args.queue_percentage; -	properties.priority = args.queue_priority; +	properties.queue_address = args->ring_base_address; +	properties.queue_size = args->ring_size; +	properties.queue_percent = args->queue_percentage; +	properties.priority = args->queue_priority;  	pr_debug("kfd: updating queue id %d for PASID %d\n", -			args.queue_id, p->pasid); +			args->queue_id, p->pasid);  	mutex_lock(&p->mutex); -	retval = pqm_update_queue(&p->pqm, args.queue_id, &properties); +	retval = pqm_update_queue(&p->pqm, args->queue_id, &properties);  	mutex_unlock(&p->mutex);  	return retval;  } -static long kfd_ioctl_set_memory_policy(struct file *filep, -				struct kfd_process *p, void __user *arg) +static int kfd_ioctl_set_memory_policy(struct file *filep, +					struct kfd_process *p, void *data)  { -	struct kfd_ioctl_set_memory_policy_args args; +	struct kfd_ioctl_set_memory_policy_args *args = data;  	struct kfd_dev *dev;  	int err = 0;  	struct kfd_process_device *pdd;  	enum cache_policy default_policy, alternate_policy; -	if (copy_from_user(&args, arg, sizeof(args))) -		return -EFAULT; - -	if (args.default_policy != KFD_IOC_CACHE_POLICY_COHERENT -	    && args.default_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) { +	if (args->default_policy != KFD_IOC_CACHE_POLICY_COHERENT +	    && args->default_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) {  		return -EINVAL;  	} -	if (args.alternate_policy != KFD_IOC_CACHE_POLICY_COHERENT -	    && args.alternate_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) { +	if (args->alternate_policy != KFD_IOC_CACHE_POLICY_COHERENT +	    && args->alternate_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) {  		return -EINVAL;  	} -	dev = kfd_device_by_id(args.gpu_id); +	dev = kfd_device_by_id(args->gpu_id);  	if (dev == NULL)  		return -EINVAL; @@ -397,23 +374,23 @@ static long kfd_ioctl_set_memory_policy(struct file *filep,  	pdd = kfd_bind_process_to_device(dev, p);  	if (IS_ERR(pdd)) { -		err = PTR_ERR(pdd); +		err = -ESRCH;  		goto out;  	} -	default_policy = (args.default_policy == KFD_IOC_CACHE_POLICY_COHERENT) +	default_policy = (args->default_policy == KFD_IOC_CACHE_POLICY_COHERENT)  			 ? cache_policy_coherent : cache_policy_noncoherent;  	alternate_policy = -		(args.alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT) +		(args->alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT)  		   ? cache_policy_coherent : cache_policy_noncoherent;  	if (!dev->dqm->set_cache_memory_policy(dev->dqm,  				&pdd->qpd,  				default_policy,  				alternate_policy, -				(void __user *)args.alternate_aperture_base, -				args.alternate_aperture_size)) +				(void __user *)args->alternate_aperture_base, +				args->alternate_aperture_size))  		err = -EINVAL;  out: @@ -422,53 +399,44 @@ out:  	return err;  } -static long kfd_ioctl_get_clock_counters(struct file *filep, -				struct kfd_process *p, void __user *arg) +static int kfd_ioctl_get_clock_counters(struct file *filep, +				struct kfd_process *p, void *data)  { -	struct kfd_ioctl_get_clock_counters_args args; +	struct kfd_ioctl_get_clock_counters_args *args = data;  	struct kfd_dev *dev;  	struct timespec time; -	if (copy_from_user(&args, arg, sizeof(args))) -		return -EFAULT; - -	dev = kfd_device_by_id(args.gpu_id); +	dev = kfd_device_by_id(args->gpu_id);  	if (dev == NULL)  		return -EINVAL;  	/* Reading GPU clock counter from KGD */ -	args.gpu_clock_counter = kfd2kgd->get_gpu_clock_counter(dev->kgd); +	args->gpu_clock_counter = kfd2kgd->get_gpu_clock_counter(dev->kgd);  	/* No access to rdtsc. Using raw monotonic time */  	getrawmonotonic(&time); -	args.cpu_clock_counter = (uint64_t)timespec_to_ns(&time); +	args->cpu_clock_counter = (uint64_t)timespec_to_ns(&time);  	get_monotonic_boottime(&time); -	args.system_clock_counter = (uint64_t)timespec_to_ns(&time); +	args->system_clock_counter = (uint64_t)timespec_to_ns(&time);  	/* Since the counter is in nano-seconds we use 1GHz frequency */ -	args.system_clock_freq = 1000000000; - -	if (copy_to_user(arg, &args, sizeof(args))) -		return -EFAULT; +	args->system_clock_freq = 1000000000;  	return 0;  }  static int kfd_ioctl_get_process_apertures(struct file *filp, -				struct kfd_process *p, void __user *arg) +				struct kfd_process *p, void *data)  { -	struct kfd_ioctl_get_process_apertures_args args; +	struct kfd_ioctl_get_process_apertures_args *args = data;  	struct kfd_process_device_apertures *pAperture;  	struct kfd_process_device *pdd;  	dev_dbg(kfd_device, "get apertures for PASID %d", p->pasid); -	if (copy_from_user(&args, arg, sizeof(args))) -		return -EFAULT; - -	args.num_of_nodes = 0; +	args->num_of_nodes = 0;  	mutex_lock(&p->mutex); @@ -477,7 +445,8 @@ static int kfd_ioctl_get_process_apertures(struct file *filp,  		/* Run over all pdd of the process */  		pdd = kfd_get_first_process_device_data(p);  		do { -			pAperture = &args.process_apertures[args.num_of_nodes]; +			pAperture = +				&args->process_apertures[args->num_of_nodes];  			pAperture->gpu_id = pdd->dev->id;  			pAperture->lds_base = pdd->lds_base;  			pAperture->lds_limit = pdd->lds_limit; @@ -487,7 +456,7 @@ static int kfd_ioctl_get_process_apertures(struct file *filp,  			pAperture->scratch_limit = pdd->scratch_limit;  			dev_dbg(kfd_device, -				"node id %u\n", args.num_of_nodes); +				"node id %u\n", args->num_of_nodes);  			dev_dbg(kfd_device,  				"gpu id %u\n", pdd->dev->id);  			dev_dbg(kfd_device, @@ -503,80 +472,131 @@ static int kfd_ioctl_get_process_apertures(struct file *filp,  			dev_dbg(kfd_device,  				"scratch_limit %llX\n", pdd->scratch_limit); -			args.num_of_nodes++; +			args->num_of_nodes++;  		} while ((pdd = kfd_get_next_process_device_data(p, pdd)) != NULL && -				(args.num_of_nodes < NUM_OF_SUPPORTED_GPUS)); +				(args->num_of_nodes < NUM_OF_SUPPORTED_GPUS));  	}  	mutex_unlock(&p->mutex); -	if (copy_to_user(arg, &args, sizeof(args))) -		return -EFAULT; -  	return 0;  } +#define AMDKFD_IOCTL_DEF(ioctl, _func, _flags) \ +	[_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl} + +/** Ioctl table */ +static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = { +	AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_VERSION, +			kfd_ioctl_get_version, 0), + +	AMDKFD_IOCTL_DEF(AMDKFD_IOC_CREATE_QUEUE, +			kfd_ioctl_create_queue, 0), + +	AMDKFD_IOCTL_DEF(AMDKFD_IOC_DESTROY_QUEUE, +			kfd_ioctl_destroy_queue, 0), + +	AMDKFD_IOCTL_DEF(AMDKFD_IOC_SET_MEMORY_POLICY, +			kfd_ioctl_set_memory_policy, 0), + +	AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_CLOCK_COUNTERS, +			kfd_ioctl_get_clock_counters, 0), + +	AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_PROCESS_APERTURES, +			kfd_ioctl_get_process_apertures, 0), + +	AMDKFD_IOCTL_DEF(AMDKFD_IOC_UPDATE_QUEUE, +			kfd_ioctl_update_queue, 0), +}; + +#define AMDKFD_CORE_IOCTL_COUNT	ARRAY_SIZE(amdkfd_ioctls) +  static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)  {  	struct kfd_process *process; -	long err = -EINVAL; +	amdkfd_ioctl_t *func; +	const struct amdkfd_ioctl_desc *ioctl = NULL; +	unsigned int nr = _IOC_NR(cmd); +	char stack_kdata[128]; +	char *kdata = NULL; +	unsigned int usize, asize; +	int retcode = -EINVAL; -	dev_dbg(kfd_device, -		"ioctl cmd 0x%x (#%d), arg 0x%lx\n", -		cmd, _IOC_NR(cmd), arg); +	if (nr >= AMDKFD_CORE_IOCTL_COUNT) +		goto err_i1; + +	if ((nr >= AMDKFD_COMMAND_START) && (nr < AMDKFD_COMMAND_END)) { +		u32 amdkfd_size; + +		ioctl = &amdkfd_ioctls[nr]; + +		amdkfd_size = _IOC_SIZE(ioctl->cmd); +		usize = asize = _IOC_SIZE(cmd); +		if (amdkfd_size > asize) +			asize = amdkfd_size; + +		cmd = ioctl->cmd; +	} else +		goto err_i1; + +	dev_dbg(kfd_device, "ioctl cmd 0x%x (#%d), arg 0x%lx\n", cmd, nr, arg);  	process = kfd_get_process(current); -	if (IS_ERR(process)) -		return PTR_ERR(process); +	if (IS_ERR(process)) { +		dev_dbg(kfd_device, "no process\n"); +		goto err_i1; +	} -	switch (cmd) { -	case KFD_IOC_GET_VERSION: -		err = kfd_ioctl_get_version(filep, process, (void __user *)arg); -		break; -	case KFD_IOC_CREATE_QUEUE: -		err = kfd_ioctl_create_queue(filep, process, -						(void __user *)arg); -		break; - -	case KFD_IOC_DESTROY_QUEUE: -		err = kfd_ioctl_destroy_queue(filep, process, -						(void __user *)arg); -		break; - -	case KFD_IOC_SET_MEMORY_POLICY: -		err = kfd_ioctl_set_memory_policy(filep, process, -						(void __user *)arg); -		break; - -	case KFD_IOC_GET_CLOCK_COUNTERS: -		err = kfd_ioctl_get_clock_counters(filep, process, -						(void __user *)arg); -		break; - -	case KFD_IOC_GET_PROCESS_APERTURES: -		err = kfd_ioctl_get_process_apertures(filep, process, -						(void __user *)arg); -		break; - -	case KFD_IOC_UPDATE_QUEUE: -		err = kfd_ioctl_update_queue(filep, process, -						(void __user *)arg); -		break; - -	default: -		dev_err(kfd_device, -			"unknown ioctl cmd 0x%x, arg 0x%lx)\n", -			cmd, arg); -		err = -EINVAL; -		break; +	/* Do not trust userspace, use our own definition */ +	func = ioctl->func; + +	if (unlikely(!func)) { +		dev_dbg(kfd_device, "no function\n"); +		retcode = -EINVAL; +		goto err_i1;  	} -	if (err < 0) -		dev_err(kfd_device, -			"ioctl error %ld for ioctl cmd 0x%x (#%d)\n", -			err, cmd, _IOC_NR(cmd)); +	if (cmd & (IOC_IN | IOC_OUT)) { +		if (asize <= sizeof(stack_kdata)) { +			kdata = stack_kdata; +		} else { +			kdata = kmalloc(asize, GFP_KERNEL); +			if (!kdata) { +				retcode = -ENOMEM; +				goto err_i1; +			} +		} +		if (asize > usize) +			memset(kdata + usize, 0, asize - usize); +	} -	return err; +	if (cmd & IOC_IN) { +		if (copy_from_user(kdata, (void __user *)arg, usize) != 0) { +			retcode = -EFAULT; +			goto err_i1; +		} +	} else if (cmd & IOC_OUT) { +		memset(kdata, 0, usize); +	} + +	retcode = func(filep, process, kdata); + +	if (cmd & IOC_OUT) +		if (copy_to_user((void __user *)arg, kdata, usize) != 0) +			retcode = -EFAULT; + +err_i1: +	if (!ioctl) +		dev_dbg(kfd_device, "invalid ioctl: pid=%d, cmd=0x%02x, nr=0x%02x\n", +			  task_pid_nr(current), cmd, nr); + +	if (kdata != stack_kdata) +		kfree(kdata); + +	if (retcode) +		dev_dbg(kfd_device, "ret = %d\n", retcode); + +	return retcode;  }  static int kfd_mmap(struct file *filp, struct vm_area_struct *vma) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 924e90c072e5..9c8961d22360 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -161,6 +161,9 @@ static void deallocate_vmid(struct device_queue_manager *dqm,  {  	int bit = qpd->vmid - KFD_VMID_START_OFFSET; +	/* Release the vmid mapping */ +	set_pasid_vmid_mapping(dqm, 0, qpd->vmid); +  	set_bit(bit, (unsigned long *)&dqm->vmid_bitmap);  	qpd->vmid = 0;  	q->properties.vmid = 0; @@ -272,6 +275,18 @@ static int create_compute_queue_nocpsch(struct device_queue_manager *dqm,  		return retval;  	} +	pr_debug("kfd: loading mqd to hqd on pipe (%d) queue (%d)\n", +			q->pipe, +			q->queue); + +	retval = mqd->load_mqd(mqd, q->mqd, q->pipe, +			q->queue, q->properties.write_ptr); +	if (retval != 0) { +		deallocate_hqd(dqm, q); +		mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj); +		return retval; +	} +  	return 0;  } @@ -320,6 +335,7 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)  {  	int retval;  	struct mqd_manager *mqd; +	bool prev_active = false;  	BUG_ON(!dqm || !q || !q->mqd); @@ -330,10 +346,18 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)  		return -ENOMEM;  	} -	retval = mqd->update_mqd(mqd, q->mqd, &q->properties);  	if (q->properties.is_active == true) +		prev_active = true; + +	/* +	 * +	 * check active state vs. the previous state +	 * and modify counter accordingly +	 */ +	retval = mqd->update_mqd(mqd, q->mqd, &q->properties); +	if ((q->properties.is_active == true) && (prev_active == false))  		dqm->queue_count++; -	else +	else if ((q->properties.is_active == false) && (prev_active == true))  		dqm->queue_count--;  	if (sched_policy != KFD_SCHED_POLICY_NO_HWS) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c index adc31474e786..4c3828cf45bf 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c @@ -184,7 +184,7 @@ static bool is_occupied(struct mqd_manager *mm, void *mqd,  			uint32_t queue_id)  { -	return kfd2kgd->hqd_is_occupies(mm->dev->kgd, queue_address, +	return kfd2kgd->hqd_is_occupied(mm->dev->kgd, queue_address,  					pipe_id, queue_id);  } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c index 71699ad97d74..4c25ef504f79 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c @@ -32,7 +32,7 @@ int kfd_pasid_init(void)  {  	pasid_limit = max_num_of_processes; -	pasid_bitmap = kzalloc(BITS_TO_LONGS(pasid_limit), GFP_KERNEL); +	pasid_bitmap = kcalloc(BITS_TO_LONGS(pasid_limit), sizeof(long), GFP_KERNEL);  	if (!pasid_bitmap)  		return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index f9fb81e3bb09..a5edb29507e3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -463,6 +463,24 @@ struct kfd_process {  	bool is_32bit_user_mode;  }; +/** + * Ioctl function type. + * + * \param filep pointer to file structure. + * \param p amdkfd process pointer. + * \param data pointer to arg that was copied from user. + */ +typedef int amdkfd_ioctl_t(struct file *filep, struct kfd_process *p, +				void *data); + +struct amdkfd_ioctl_desc { +	unsigned int cmd; +	int flags; +	amdkfd_ioctl_t *func; +	unsigned int cmd_drv; +	const char *name; +}; +  void kfd_process_create_wq(void);  void kfd_process_destroy_wq(void);  struct kfd_process *kfd_create_process(const struct task_struct *); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index b11792d7e70e..cca1708fd811 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -921,7 +921,7 @@ static int kfd_build_sysfs_node_tree(void)  	uint32_t i = 0;  	list_for_each_entry(dev, &topology_device_list, list) { -		ret = kfd_build_sysfs_node_entry(dev, 0); +		ret = kfd_build_sysfs_node_entry(dev, i);  		if (ret < 0)  			return ret;  		i++; diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h index 47b551970a14..96a512208fad 100644 --- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h @@ -183,7 +183,7 @@ struct kfd2kgd_calls {  	int (*hqd_load)(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,  			uint32_t queue_id, uint32_t __user *wptr); -	bool (*hqd_is_occupies)(struct kgd_dev *kgd, uint64_t queue_address, +	bool (*hqd_is_occupied)(struct kgd_dev *kgd, uint64_t queue_address,  				uint32_t pipe_id, uint32_t queue_id);  	int (*hqd_destroy)(struct kgd_dev *kgd, uint32_t reset_type, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 70d0f0f06f1a..e9f891c432f8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1756,8 +1756,6 @@ struct drm_i915_private {  	 */  	struct workqueue_struct *dp_wq; -	uint32_t bios_vgacntr; -  	/* Abstract the submission mechanism (legacy ringbuffer or execlists) away */  	struct {  		int (*do_execbuf)(struct drm_device *dev, struct drm_file *file, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 52adcb680be3..c11603b4cf1d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1048,6 +1048,7 @@ int  i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,  		      struct drm_file *file)  { +	struct drm_i915_private *dev_priv = dev->dev_private;  	struct drm_i915_gem_pwrite *args = data;  	struct drm_i915_gem_object *obj;  	int ret; @@ -1067,9 +1068,11 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,  			return -EFAULT;  	} +	intel_runtime_pm_get(dev_priv); +  	ret = i915_mutex_lock_interruptible(dev);  	if (ret) -		return ret; +		goto put_rpm;  	obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));  	if (&obj->base == NULL) { @@ -1121,6 +1124,9 @@ out:  	drm_gem_object_unreference(&obj->base);  unlock:  	mutex_unlock(&dev->struct_mutex); +put_rpm: +	intel_runtime_pm_put(dev_priv); +  	return ret;  } diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 996c2931c499..d0d3dfbe6d2a 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3725,8 +3725,6 @@ static bool i8xx_handle_vblank(struct drm_device *dev,  	if ((iir & flip_pending) == 0)  		goto check_page_flip; -	intel_prepare_page_flip(dev, plane); -  	/* We detect FlipDone by looking for the change in PendingFlip from '1'  	 * to '0' on the following vblank, i.e. IIR has the Pendingflip  	 * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence @@ -3736,6 +3734,7 @@ static bool i8xx_handle_vblank(struct drm_device *dev,  	if (I915_READ16(ISR) & flip_pending)  		goto check_page_flip; +	intel_prepare_page_flip(dev, plane);  	intel_finish_page_flip(dev, pipe);  	return true; @@ -3907,8 +3906,6 @@ static bool i915_handle_vblank(struct drm_device *dev,  	if ((iir & flip_pending) == 0)  		goto check_page_flip; -	intel_prepare_page_flip(dev, plane); -  	/* We detect FlipDone by looking for the change in PendingFlip from '1'  	 * to '0' on the following vblank, i.e. IIR has the Pendingflip  	 * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence @@ -3918,6 +3915,7 @@ static bool i915_handle_vblank(struct drm_device *dev,  	if (I915_READ(ISR) & flip_pending)  		goto check_page_flip; +	intel_prepare_page_flip(dev, plane);  	intel_finish_page_flip(dev, pipe);  	return true; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index fb3e3d429191..e2af1383b179 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13057,11 +13057,7 @@ static void i915_disable_vga(struct drm_device *dev)  	vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);  	udelay(300); -	/* -	 * Fujitsu-Siemens Lifebook S6010 (830) has problems resuming -	 * from S3 without preserving (some of?) the other bits. -	 */ -	I915_WRITE(vga_reg, dev_priv->bios_vgacntr | VGA_DISP_DISABLE); +	I915_WRITE(vga_reg, VGA_DISP_DISABLE);  	POSTING_READ(vga_reg);  } @@ -13146,8 +13142,6 @@ void intel_modeset_init(struct drm_device *dev)  	intel_shared_dpll_init(dev); -	/* save the BIOS value before clobbering it */ -	dev_priv->bios_vgacntr = I915_READ(i915_vgacntrl_reg(dev));  	/* Just disable it once at startup */  	i915_disable_vga(dev);  	intel_setup_outputs(dev); diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index f5a78d53e297..ac6da7102fbb 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -615,29 +615,6 @@ static void chv_pipe_power_well_disable(struct drm_i915_private *dev_priv,  		vlv_power_sequencer_reset(dev_priv);  } -static void check_power_well_state(struct drm_i915_private *dev_priv, -				   struct i915_power_well *power_well) -{ -	bool enabled = power_well->ops->is_enabled(dev_priv, power_well); - -	if (power_well->always_on || !i915.disable_power_well) { -		if (!enabled) -			goto mismatch; - -		return; -	} - -	if (enabled != (power_well->count > 0)) -		goto mismatch; - -	return; - -mismatch: -	WARN(1, "state mismatch for '%s' (always_on %d hw state %d use-count %d disable_power_well %d\n", -		  power_well->name, power_well->always_on, enabled, -		  power_well->count, i915.disable_power_well); -} -  /**   * intel_display_power_get - grab a power domain reference   * @dev_priv: i915 device instance @@ -669,8 +646,6 @@ void intel_display_power_get(struct drm_i915_private *dev_priv,  			power_well->ops->enable(dev_priv, power_well);  			power_well->hw_enabled = true;  		} - -		check_power_well_state(dev_priv, power_well);  	}  	power_domains->domain_use_count[domain]++; @@ -709,8 +684,6 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,  			power_well->hw_enabled = false;  			power_well->ops->disable(dev_priv, power_well);  		} - -		check_power_well_state(dev_priv, power_well);  	}  	mutex_unlock(&power_domains->lock); diff --git a/drivers/gpu/drm/nouveau/core/core/event.c b/drivers/gpu/drm/nouveau/core/core/event.c index ff2b434b3db4..760947e380c9 100644 --- a/drivers/gpu/drm/nouveau/core/core/event.c +++ b/drivers/gpu/drm/nouveau/core/core/event.c @@ -26,7 +26,7 @@  void  nvkm_event_put(struct nvkm_event *event, u32 types, int index)  { -	BUG_ON(!spin_is_locked(&event->refs_lock)); +	assert_spin_locked(&event->refs_lock);  	while (types) {  		int type = __ffs(types); types &= ~(1 << type);  		if (--event->refs[index * event->types_nr + type] == 0) { @@ -39,7 +39,7 @@ nvkm_event_put(struct nvkm_event *event, u32 types, int index)  void  nvkm_event_get(struct nvkm_event *event, u32 types, int index)  { -	BUG_ON(!spin_is_locked(&event->refs_lock)); +	assert_spin_locked(&event->refs_lock);  	while (types) {  		int type = __ffs(types); types &= ~(1 << type);  		if (++event->refs[index * event->types_nr + type] == 1) { diff --git a/drivers/gpu/drm/nouveau/core/core/notify.c b/drivers/gpu/drm/nouveau/core/core/notify.c index d1bcde55e9d7..839a32577680 100644 --- a/drivers/gpu/drm/nouveau/core/core/notify.c +++ b/drivers/gpu/drm/nouveau/core/core/notify.c @@ -98,7 +98,7 @@ nvkm_notify_send(struct nvkm_notify *notify, void *data, u32 size)  	struct nvkm_event *event = notify->event;  	unsigned long flags; -	BUG_ON(!spin_is_locked(&event->list_lock)); +	assert_spin_locked(&event->list_lock);  	BUG_ON(size != notify->size);  	spin_lock_irqsave(&event->refs_lock, flags); diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c index 674da1f095b2..732922690653 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c @@ -249,6 +249,39 @@ nve0_identify(struct nouveau_device *device)  		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;  		device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass;  		break; +	case 0x106: +		device->cname = "GK208B"; +		device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass; +		device->oclass[NVDEV_SUBDEV_GPIO   ] =  nve0_gpio_oclass; +		device->oclass[NVDEV_SUBDEV_I2C    ] =  nve0_i2c_oclass; +		device->oclass[NVDEV_SUBDEV_FUSE   ] = &gf100_fuse_oclass; +		device->oclass[NVDEV_SUBDEV_CLOCK  ] = &nve0_clock_oclass; +		device->oclass[NVDEV_SUBDEV_THERM  ] = &nvd0_therm_oclass; +		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass; +		device->oclass[NVDEV_SUBDEV_DEVINIT] =  nvc0_devinit_oclass; +		device->oclass[NVDEV_SUBDEV_MC     ] =  gk20a_mc_oclass; +		device->oclass[NVDEV_SUBDEV_BUS    ] =  nvc0_bus_oclass; +		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass; +		device->oclass[NVDEV_SUBDEV_FB     ] =  nve0_fb_oclass; +		device->oclass[NVDEV_SUBDEV_LTC    ] =  gk104_ltc_oclass; +		device->oclass[NVDEV_SUBDEV_IBUS   ] = &nve0_ibus_oclass; +		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass; +		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass; +		device->oclass[NVDEV_SUBDEV_BAR    ] = &nvc0_bar_oclass; +		device->oclass[NVDEV_SUBDEV_PWR    ] =  nv108_pwr_oclass; +		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass; +		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nvd0_dmaeng_oclass; +		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv108_fifo_oclass; +		device->oclass[NVDEV_ENGINE_SW     ] =  nvc0_software_oclass; +		device->oclass[NVDEV_ENGINE_GR     ] =  nv108_graph_oclass; +		device->oclass[NVDEV_ENGINE_DISP   ] =  nvf0_disp_oclass; +		device->oclass[NVDEV_ENGINE_COPY0  ] = &nve0_copy0_oclass; +		device->oclass[NVDEV_ENGINE_COPY1  ] = &nve0_copy1_oclass; +		device->oclass[NVDEV_ENGINE_COPY2  ] = &nve0_copy2_oclass; +		device->oclass[NVDEV_ENGINE_BSP    ] = &nve0_bsp_oclass; +		device->oclass[NVDEV_ENGINE_VP     ] = &nve0_vp_oclass; +		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass; +		break;  	case 0x108:  		device->cname = "GK208";  		device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass; diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c b/drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c index 5e58bba0dd5c..a7a890fad1e5 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c @@ -44,8 +44,10 @@ static void  pramin_fini(void *data)  {  	struct priv *priv = data; -	nv_wr32(priv->bios, 0x001700, priv->bar0); -	kfree(priv); +	if (priv) { +		nv_wr32(priv->bios, 0x001700, priv->bar0); +		kfree(priv); +	}  }  static void * diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c index 00f2ca7e44a5..033a8e999497 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c @@ -24,34 +24,71 @@  #include "nv50.h" +struct nvaa_ram_priv { +	struct nouveau_ram base; +	u64 poller_base; +}; +  static int  nvaa_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,  	      struct nouveau_oclass *oclass, void *data, u32 datasize,  	      struct nouveau_object **pobject)  { -	const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */ -	const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */ +	u32 rsvd_head = ( 256 * 1024); /* vga memory */ +	u32 rsvd_tail = (1024 * 1024); /* vbios etc */  	struct nouveau_fb *pfb = nouveau_fb(parent); -	struct nouveau_ram *ram; +	struct nvaa_ram_priv *priv;  	int ret; -	ret = nouveau_ram_create(parent, engine, oclass, &ram); -	*pobject = nv_object(ram); +	ret = nouveau_ram_create(parent, engine, oclass, &priv); +	*pobject = nv_object(priv);  	if (ret)  		return ret; -	ram->size = nv_rd32(pfb, 0x10020c); -	ram->size = (ram->size & 0xffffff00) | ((ram->size & 0x000000ff) << 32); +	priv->base.type   = NV_MEM_TYPE_STOLEN; +	priv->base.stolen = (u64)nv_rd32(pfb, 0x100e10) << 12; +	priv->base.size   = (u64)nv_rd32(pfb, 0x100e14) << 12; -	ret = nouveau_mm_init(&pfb->vram, rsvd_head, (ram->size >> 12) - -			      (rsvd_head + rsvd_tail), 1); +	rsvd_tail += 0x1000; +	priv->poller_base = priv->base.size - rsvd_tail; + +	ret = nouveau_mm_init(&pfb->vram, rsvd_head >> 12, +			      (priv->base.size  - (rsvd_head + rsvd_tail)) >> 12, +			      1);  	if (ret)  		return ret; -	ram->type   = NV_MEM_TYPE_STOLEN; -	ram->stolen = (u64)nv_rd32(pfb, 0x100e10) << 12; -	ram->get = nv50_ram_get; -	ram->put = nv50_ram_put; +	priv->base.get = nv50_ram_get; +	priv->base.put = nv50_ram_put; +	return 0; +} + +static int +nvaa_ram_init(struct nouveau_object *object) +{ +	struct nouveau_fb *pfb = nouveau_fb(object); +	struct nvaa_ram_priv *priv = (void *)object; +	int ret; +	u64 dniso, hostnb, flush; + +	ret = nouveau_ram_init(&priv->base); +	if (ret) +		return ret; + +	dniso  = ((priv->base.size - (priv->poller_base + 0x00)) >> 5) - 1; +	hostnb = ((priv->base.size - (priv->poller_base + 0x20)) >> 5) - 1; +	flush  = ((priv->base.size - (priv->poller_base + 0x40)) >> 5) - 1; + +	/* Enable NISO poller for various clients and set their associated +	 * read address, only for MCP77/78 and MCP79/7A. (fd#25701) +	 */ +	nv_wr32(pfb, 0x100c18, dniso); +	nv_mask(pfb, 0x100c14, 0x00000000, 0x00000001); +	nv_wr32(pfb, 0x100c1c, hostnb); +	nv_mask(pfb, 0x100c14, 0x00000000, 0x00000002); +	nv_wr32(pfb, 0x100c24, flush); +	nv_mask(pfb, 0x100c14, 0x00000000, 0x00010000); +  	return 0;  } @@ -60,7 +97,7 @@ nvaa_ram_oclass = {  	.ofuncs = &(struct nouveau_ofuncs) {  		.ctor = nvaa_ram_ctor,  		.dtor = _nouveau_ram_dtor, -		.init = _nouveau_ram_init, +		.init = nvaa_ram_init,  		.fini = _nouveau_ram_fini,  	},  }; diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c index a75c35ccf25c..165401c4045c 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c @@ -24,13 +24,6 @@  #include "nv04.h" -static void -nv4c_mc_msi_rearm(struct nouveau_mc *pmc) -{ -	struct nv04_mc_priv *priv = (void *)pmc; -	nv_wr08(priv, 0x088050, 0xff); -} -  struct nouveau_oclass *  nv4c_mc_oclass = &(struct nouveau_mc_oclass) {  	.base.handle = NV_SUBDEV(MC, 0x4c), @@ -41,5 +34,4 @@ nv4c_mc_oclass = &(struct nouveau_mc_oclass) {  		.fini = _nouveau_mc_fini,  	},  	.intr = nv04_mc_intr, -	.msi_rearm = nv4c_mc_msi_rearm,  }.base; diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 21ec561edc99..bba2960d3dfb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1572,8 +1572,10 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)  	 * so use the DMA API for them.  	 */  	if (!nv_device_is_cpu_coherent(device) && -	    ttm->caching_state == tt_uncached) +	    ttm->caching_state == tt_uncached) {  		ttm_dma_unpopulate(ttm_dma, dev->dev); +		return; +	}  #if __OS_HAS_AGP  	if (drm->agp.stat == ENABLED) { diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 42c34babc2e5..bf0f9e21d714 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -36,7 +36,14 @@ void  nouveau_gem_object_del(struct drm_gem_object *gem)  {  	struct nouveau_bo *nvbo = nouveau_gem_object(gem); +	struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);  	struct ttm_buffer_object *bo = &nvbo->bo; +	struct device *dev = drm->dev->dev; +	int ret; + +	ret = pm_runtime_get_sync(dev); +	if (WARN_ON(ret < 0 && ret != -EACCES)) +		return;  	if (gem->import_attach)  		drm_prime_gem_destroy(gem, nvbo->bo.sg); @@ -46,6 +53,9 @@ nouveau_gem_object_del(struct drm_gem_object *gem)  	/* reset filp so nouveau_bo_del_ttm() can test for it */  	gem->filp = NULL;  	ttm_bo_unref(&bo); + +	pm_runtime_mark_last_busy(dev); +	pm_runtime_put_autosuspend(dev);  }  int @@ -53,7 +63,9 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)  {  	struct nouveau_cli *cli = nouveau_cli(file_priv);  	struct nouveau_bo *nvbo = nouveau_gem_object(gem); +	struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);  	struct nouveau_vma *vma; +	struct device *dev = drm->dev->dev;  	int ret;  	if (!cli->vm) @@ -71,11 +83,16 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)  			goto out;  		} +		ret = pm_runtime_get_sync(dev); +		if (ret < 0 && ret != -EACCES) +			goto out; +  		ret = nouveau_bo_vma_add(nvbo, cli->vm, vma); -		if (ret) { +		if (ret)  			kfree(vma); -			goto out; -		} + +		pm_runtime_mark_last_busy(dev); +		pm_runtime_put_autosuspend(dev);  	} else {  		vma->refcount++;  	} @@ -129,6 +146,8 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)  {  	struct nouveau_cli *cli = nouveau_cli(file_priv);  	struct nouveau_bo *nvbo = nouveau_gem_object(gem); +	struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); +	struct device *dev = drm->dev->dev;  	struct nouveau_vma *vma;  	int ret; @@ -141,8 +160,14 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)  	vma = nouveau_bo_vma_find(nvbo, cli->vm);  	if (vma) { -		if (--vma->refcount == 0) -			nouveau_gem_object_unmap(nvbo, vma); +		if (--vma->refcount == 0) { +			ret = pm_runtime_get_sync(dev); +			if (!WARN_ON(ret < 0 && ret != -EACCES)) { +				nouveau_gem_object_unmap(nvbo, vma); +				pm_runtime_mark_last_busy(dev); +				pm_runtime_put_autosuspend(dev); +			} +		}  	}  	ttm_bo_unreserve(&nvbo->bo);  } diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index d59ec491dbb9..ed644a4f6f57 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1851,10 +1851,9 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)  				return pll;  		}  		/* otherwise, pick one of the plls */ -		if ((rdev->family == CHIP_KAVERI) || -		    (rdev->family == CHIP_KABINI) || +		if ((rdev->family == CHIP_KABINI) ||  		    (rdev->family == CHIP_MULLINS)) { -			/* KB/KV/ML has PPLL1 and PPLL2 */ +			/* KB/ML has PPLL1 and PPLL2 */  			pll_in_use = radeon_get_pll_use_mask(crtc);  			if (!(pll_in_use & (1 << ATOM_PPLL2)))  				return ATOM_PPLL2; @@ -1863,7 +1862,7 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)  			DRM_ERROR("unable to allocate a PPLL\n");  			return ATOM_PPLL_INVALID;  		} else { -			/* CI has PPLL0, PPLL1, and PPLL2 */ +			/* CI/KV has PPLL0, PPLL1, and PPLL2 */  			pll_in_use = radeon_get_pll_use_mask(crtc);  			if (!(pll_in_use & (1 << ATOM_PPLL2)))  				return ATOM_PPLL2; @@ -2155,6 +2154,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)  	case ATOM_PPLL0:  		/* disable the ppll */  		if ((rdev->family == CHIP_ARUBA) || +		    (rdev->family == CHIP_KAVERI) ||  		    (rdev->family == CHIP_BONAIRE) ||  		    (rdev->family == CHIP_HAWAII))  			atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 11ba9d21b89b..db42a670f995 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -492,6 +492,10 @@ int radeon_dp_mode_valid_helper(struct drm_connector *connector,  	struct radeon_connector_atom_dig *dig_connector;  	int dp_clock; +	if ((mode->clock > 340000) && +	    (!radeon_connector_is_dp12_capable(connector))) +		return MODE_CLOCK_HIGH; +  	if (!radeon_connector->con_priv)  		return MODE_CLOCK_HIGH;  	dig_connector = radeon_connector->con_priv; diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index ba85986febea..03003f8a6de6 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h @@ -2156,4 +2156,6 @@  #define ATC_VM_APERTURE1_HIGH_ADDR				0x330Cu  #define ATC_VM_APERTURE1_LOW_ADDR				0x3304u +#define IH_VMID_0_LUT						0x3D40u +  #endif diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index 2fe8cfc966d9..bafdf92a5732 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c @@ -103,7 +103,7 @@ static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder)  	}  	sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); -	if (sad_count < 0) { +	if (sad_count <= 0) {  		DRM_ERROR("Couldn't read SADs: %d\n", sad_count);  		return;  	} diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index 9b42001295ba..e3e9c10cfba9 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c @@ -2745,13 +2745,11 @@ int kv_dpm_init(struct radeon_device *rdev)  	pi->enable_auto_thermal_throttling = true;  	pi->disable_nb_ps3_in_battery = false;  	if (radeon_bapm == -1) { -		/* There are stability issues reported on with -		 * bapm enabled on an asrock system. -		 */ -		if (rdev->pdev->subsystem_vendor == 0x1849) -			pi->bapm_enable = false; -		else +		/* only enable bapm on KB, ML by default */ +		if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS)  			pi->bapm_enable = true; +		else +			pi->bapm_enable = false;  	} else if (radeon_bapm == 0) {  		pi->bapm_enable = false;  	} else { diff --git a/drivers/gpu/drm/radeon/radeon_kfd.c b/drivers/gpu/drm/radeon/radeon_kfd.c index 242fd8b1b221..8bf87f1203cc 100644 --- a/drivers/gpu/drm/radeon/radeon_kfd.c +++ b/drivers/gpu/drm/radeon/radeon_kfd.c @@ -72,7 +72,7 @@ static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id,  static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,  			uint32_t queue_id, uint32_t __user *wptr); -static bool kgd_hqd_is_occupies(struct kgd_dev *kgd, uint64_t queue_address, +static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,  				uint32_t pipe_id, uint32_t queue_id);  static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type, @@ -92,7 +92,7 @@ static const struct kfd2kgd_calls kfd2kgd = {  	.init_memory = kgd_init_memory,  	.init_pipeline = kgd_init_pipeline,  	.hqd_load = kgd_hqd_load, -	.hqd_is_occupies = kgd_hqd_is_occupies, +	.hqd_is_occupied = kgd_hqd_is_occupied,  	.hqd_destroy = kgd_hqd_destroy,  	.get_fw_version = get_fw_version  }; @@ -101,6 +101,7 @@ static const struct kgd2kfd_calls *kgd2kfd;  bool radeon_kfd_init(void)  { +#if defined(CONFIG_HSA_AMD_MODULE)  	bool (*kgd2kfd_init_p)(unsigned, const struct kfd2kgd_calls*,  				const struct kgd2kfd_calls**); @@ -117,6 +118,17 @@ bool radeon_kfd_init(void)  	}  	return true; +#elif defined(CONFIG_HSA_AMD) +	if (!kgd2kfd_init(KFD_INTERFACE_VERSION, &kfd2kgd, &kgd2kfd)) { +		kgd2kfd = NULL; + +		return false; +	} + +	return true; +#else +	return false; +#endif  }  void radeon_kfd_fini(void) @@ -378,6 +390,10 @@ static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid,  		cpu_relax();  	write_register(kgd, ATC_VMID_PASID_MAPPING_UPDATE_STATUS, 1U << vmid); +	/* Mapping vmid to pasid also for IH block */ +	write_register(kgd, IH_VMID_0_LUT + vmid * sizeof(uint32_t), +			pasid_mapping); +  	return 0;  } @@ -517,7 +533,7 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,  	return 0;  } -static bool kgd_hqd_is_occupies(struct kgd_dev *kgd, uint64_t queue_address, +static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,  				uint32_t pipe_id, uint32_t queue_id)  {  	uint32_t act; @@ -556,6 +572,7 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,  		if (timeout == 0) {  			pr_err("kfd: cp queue preemption time out (%dms)\n",  				temp); +			release_queue(kgd);  			return -ETIME;  		}  		msleep(20); diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index 535403e0c8a2..15aee723db77 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c @@ -1703,7 +1703,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,  	u32 format;  	u32 *buffer;  	const u8 __user *data; -	int size, dwords, tex_width, blit_width, spitch; +	unsigned int size, dwords, tex_width, blit_width, spitch;  	u32 height;  	int i;  	u32 texpitch, microtile; diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 230b6f887cd8..dfdc26970022 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -27,7 +27,8 @@ if HID  config HID_BATTERY_STRENGTH  	bool "Battery level reporting for HID devices" -	depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY +	depends on HID +	select POWER_SUPPLY  	default n  	---help---  	This option adds support of reporting battery strength (for HID devices diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index c3d0ac1a0988..8b638792cb43 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1805,6 +1805,7 @@ static const struct hid_device_id hid_have_special_driver[] = {  	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 7460f3402298..9243359c1821 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -526,6 +526,7 @@  #define USB_DEVICE_ID_KYE_GPEN_560	0x5003  #define USB_DEVICE_ID_KYE_EASYPEN_I405X	0x5010  #define USB_DEVICE_ID_KYE_MOUSEPEN_I608X	0x5011 +#define USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2	0x501a  #define USB_DEVICE_ID_KYE_EASYPEN_M610X	0x5013  #define USB_VENDOR_ID_LABTEC		0x1020 diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index e0a0f06ac5ef..9505605b6e22 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -312,6 +312,9 @@ static const struct hid_device_id hid_battery_quirks[] = {  			       USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),  	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, +			       USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO), +	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, +	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,  		USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),  	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },  	{} diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c index b92bf01a1ae8..158fcf577fae 100644 --- a/drivers/hid/hid-kye.c +++ b/drivers/hid/hid-kye.c @@ -323,6 +323,7 @@ static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc,  		}  		break;  	case USB_DEVICE_ID_KYE_MOUSEPEN_I608X: +	case USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2:  		if (*rsize == MOUSEPEN_I608X_RDESC_ORIG_SIZE) {  			rdesc = mousepen_i608x_rdesc_fixed;  			*rsize = sizeof(mousepen_i608x_rdesc_fixed); @@ -415,6 +416,7 @@ static int kye_probe(struct hid_device *hdev, const struct hid_device_id *id)  	switch (id->product) {  	case USB_DEVICE_ID_KYE_EASYPEN_I405X:  	case USB_DEVICE_ID_KYE_MOUSEPEN_I608X: +	case USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2:  	case USB_DEVICE_ID_KYE_EASYPEN_M610X:  		ret = kye_tablet_enable(hdev);  		if (ret) { @@ -446,6 +448,8 @@ static const struct hid_device_id kye_devices[] = {  	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE,  				USB_DEVICE_ID_KYE_MOUSEPEN_I608X) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, +				USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE,  				USB_DEVICE_ID_KYE_EASYPEN_M610X) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE,  				USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE) }, diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index c917ab61aafa..5bc6d80d5be7 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -962,10 +962,24 @@ static int logi_dj_raw_event(struct hid_device *hdev,  	switch (data[0]) {  	case REPORT_ID_DJ_SHORT: +		if (size != DJREPORT_SHORT_LENGTH) { +			dev_err(&hdev->dev, "DJ report of bad size (%d)", size); +			return false; +		}  		return logi_dj_dj_event(hdev, report, data, size);  	case REPORT_ID_HIDPP_SHORT: -		/* intentional fallthrough */ +		if (size != HIDPP_REPORT_SHORT_LENGTH) { +			dev_err(&hdev->dev, +				"Short HID++ report of bad size (%d)", size); +			return false; +		} +		return logi_dj_hidpp_event(hdev, report, data, size);  	case REPORT_ID_HIDPP_LONG: +		if (size != HIDPP_REPORT_LONG_LENGTH) { +			dev_err(&hdev->dev, +				"Long HID++ report of bad size (%d)", size); +			return false; +		}  		return logi_dj_hidpp_event(hdev, report, data, size);  	} diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 2f420c0b6609..a93cefe0e522 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -282,6 +282,33 @@ static inline bool hidpp_report_is_connect_event(struct hidpp_report *report)  		(report->rap.sub_id == 0x41);  } +/** + * hidpp_prefix_name() prefixes the current given name with "Logitech ". + */ +static void hidpp_prefix_name(char **name, int name_length) +{ +#define PREFIX_LENGTH 9 /* "Logitech " */ + +	int new_length; +	char *new_name; + +	if (name_length > PREFIX_LENGTH && +	    strncmp(*name, "Logitech ", PREFIX_LENGTH) == 0) +		/* The prefix has is already in the name */ +		return; + +	new_length = PREFIX_LENGTH + name_length; +	new_name = kzalloc(new_length, GFP_KERNEL); +	if (!new_name) +		return; + +	snprintf(new_name, new_length, "Logitech %s", *name); + +	kfree(*name); + +	*name = new_name; +} +  /* -------------------------------------------------------------------------- */  /* HIDP++ 1.0 commands                                                        */  /* -------------------------------------------------------------------------- */ @@ -321,6 +348,10 @@ static char *hidpp_get_unifying_name(struct hidpp_device *hidpp_dev)  		return NULL;  	memcpy(name, &response.rap.params[2], len); + +	/* include the terminating '\0' */ +	hidpp_prefix_name(&name, len + 1); +  	return name;  } @@ -498,6 +529,9 @@ static char *hidpp_get_device_name(struct hidpp_device *hidpp)  		index += ret;  	} +	/* include the terminating '\0' */ +	hidpp_prefix_name(&name, __name_length + 1); +  	return name;  } @@ -794,18 +828,25 @@ static int wtp_raw_event(struct hid_device *hdev, u8 *data, int size)  	switch (data[0]) {  	case 0x02: +		if (size < 2) { +			hid_err(hdev, "Received HID report of bad size (%d)", +				size); +			return 1; +		}  		if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) {  			input_event(wd->input, EV_KEY, BTN_LEFT,  					!!(data[1] & 0x01));  			input_event(wd->input, EV_KEY, BTN_RIGHT,  					!!(data[1] & 0x02));  			input_sync(wd->input); +			return 0;  		} else {  			if (size < 21)  				return 1;  			return wtp_mouse_raw_xy_event(hidpp, &data[7]);  		}  	case REPORT_ID_HIDPP_LONG: +		/* size is already checked in hidpp_raw_event. */  		if ((report->fap.feature_index != wd->mt_feature_index) ||  		    (report->fap.funcindex_clientid != EVENT_TOUCHPAD_RAW_XY))  			return 1; diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c index 1a07e07d99a0..47d7e74231e5 100644 --- a/drivers/hid/hid-roccat-pyra.c +++ b/drivers/hid/hid-roccat-pyra.c @@ -35,6 +35,8 @@ static struct class *pyra_class;  static void profile_activated(struct pyra_device *pyra,  		unsigned int new_profile)  { +	if (new_profile >= ARRAY_SIZE(pyra->profile_settings)) +		return;  	pyra->actual_profile = new_profile;  	pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi;  } @@ -257,9 +259,11 @@ static ssize_t pyra_sysfs_write_settings(struct file *fp,  	if (off != 0 || count != PYRA_SIZE_SETTINGS)  		return -EINVAL; -	mutex_lock(&pyra->pyra_lock); -  	settings = (struct pyra_settings const *)buf; +	if (settings->startup_profile >= ARRAY_SIZE(pyra->profile_settings)) +		return -EINVAL; + +	mutex_lock(&pyra->pyra_lock);  	retval = pyra_set_settings(usb_dev, settings);  	if (retval) { diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index d32037cbf9db..d43e967e7533 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -706,12 +706,7 @@ static int i2c_hid_start(struct hid_device *hid)  static void i2c_hid_stop(struct hid_device *hid)  { -	struct i2c_client *client = hid->driver_data; -	struct i2c_hid *ihid = i2c_get_clientdata(client); -  	hid->claimed = 0; - -	i2c_hid_free_buffers(ihid);  }  static int i2c_hid_open(struct hid_device *hid) diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index dc89be90b35e..b27b3d33ebab 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -124,6 +124,7 @@ static const struct hid_blacklist {  	{ USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT },  	{ USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS },  	{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT }, +	{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2, HID_QUIRK_MULTI_INPUT },  	{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT },  	{ USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS },  	{ USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD, HID_QUIRK_NO_INIT_REPORTS }, diff --git a/drivers/iio/adc/ad799x.c b/drivers/iio/adc/ad799x.c index e37412da15f5..b99de00e57b8 100644 --- a/drivers/iio/adc/ad799x.c +++ b/drivers/iio/adc/ad799x.c @@ -143,9 +143,15 @@ static int ad799x_write_config(struct ad799x_state *st, u16 val)  	case ad7998:  		return i2c_smbus_write_word_swapped(st->client, AD7998_CONF_REG,  			val); -	default: +	case ad7992: +	case ad7993: +	case ad7994:  		return i2c_smbus_write_byte_data(st->client, AD7998_CONF_REG,  			val); +	default: +		/* Will be written when doing a conversion */ +		st->config = val; +		return 0;  	}  } @@ -155,8 +161,13 @@ static int ad799x_read_config(struct ad799x_state *st)  	case ad7997:  	case ad7998:  		return i2c_smbus_read_word_swapped(st->client, AD7998_CONF_REG); -	default: +	case ad7992: +	case ad7993: +	case ad7994:  		return i2c_smbus_read_byte_data(st->client, AD7998_CONF_REG); +	default: +		/* No readback support */ +		return st->config;  	}  } diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index 866fe904cba2..90c8cb727cc7 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -449,6 +449,9 @@ static int iio_channel_read(struct iio_channel *chan, int *val, int *val2,  	if (val2 == NULL)  		val2 = &unused; +	if(!iio_channel_has_info(chan->channel, info)) +		return -EINVAL; +  	if (chan->indio_dev->info->read_raw_multi) {  		ret = chan->indio_dev->info->read_raw_multi(chan->indio_dev,  					chan->channel, INDIO_MAX_RAW_ELEMENTS, diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 1232336b960e..40dfbc0444c0 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -4029,14 +4029,6 @@ static int device_notifier(struct notifier_block *nb,  	if (action != BUS_NOTIFY_REMOVED_DEVICE)  		return 0; -	/* -	 * If the device is still attached to a device driver we can't -	 * tear down the domain yet as DMA mappings may still be in use. -	 * Wait for the BUS_NOTIFY_UNBOUND_DRIVER event to do that. -	 */ -	if (action == BUS_NOTIFY_DEL_DEVICE && dev->driver != NULL) -		return 0; -  	domain = find_domain(dev);  	if (!domain)  		return 0; @@ -4428,6 +4420,10 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,  				domain_remove_one_dev_info(old_domain, dev);  			else  				domain_remove_dev_info(old_domain); + +			if (!domain_type_is_vm_or_si(old_domain) && +			     list_empty(&old_domain->devices)) +				domain_exit(old_domain);  		}  	} diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index 68dfb0fd5ee9..748693192c20 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c @@ -558,7 +558,7 @@ static pmd_t *ipmmu_alloc_pmd(struct ipmmu_vmsa_device *mmu, pgd_t *pgd,  static u64 ipmmu_page_prot(unsigned int prot, u64 type)  { -	u64 pgprot = ARM_VMSA_PTE_XN | ARM_VMSA_PTE_nG | ARM_VMSA_PTE_AF +	u64 pgprot = ARM_VMSA_PTE_nG | ARM_VMSA_PTE_AF  		   | ARM_VMSA_PTE_SH_IS | ARM_VMSA_PTE_AP_UNPRIV  		   | ARM_VMSA_PTE_NS | type; @@ -568,8 +568,8 @@ static u64 ipmmu_page_prot(unsigned int prot, u64 type)  	if (prot & IOMMU_CACHE)  		pgprot |= IMMAIR_ATTR_IDX_WBRWA << ARM_VMSA_PTE_ATTRINDX_SHIFT; -	if (prot & IOMMU_EXEC) -		pgprot &= ~ARM_VMSA_PTE_XN; +	if (prot & IOMMU_NOEXEC) +		pgprot |= ARM_VMSA_PTE_XN;  	else if (!(prot & (IOMMU_READ | IOMMU_WRITE)))  		/* If no access create a faulting entry to avoid TLB fills. */  		pgprot &= ~ARM_VMSA_PTE_PAGE; diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index b2023af384b9..6a8b1ec4a48a 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c @@ -1009,7 +1009,6 @@ static struct platform_driver rk_iommu_driver = {  	.remove = rk_iommu_remove,  	.driver = {  		   .name = "rk_iommu", -		   .owner = THIS_MODULE,  		   .of_match_table = of_match_ptr(rk_iommu_dt_ids),  	},  }; diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c index a82e542ffc21..0b380603a578 100644 --- a/drivers/isdn/hardware/eicon/message.c +++ b/drivers/isdn/hardware/eicon/message.c @@ -4880,7 +4880,7 @@ static void sig_ind(PLCI *plci)  	byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/  	byte CF_Ind[] = "\x09\x02\x00\x06\x00\x00\x00\x00\x00\x00";  	byte Interr_Err_Ind[] = "\x0a\x02\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; -	byte CONF_Ind[] = "\x09\x16\x00\x06\x00\x00\0x00\0x00\0x00\0x00"; +	byte CONF_Ind[] = "\x09\x16\x00\x06\x00\x00\x00\x00\x00\x00";  	byte force_mt_info = false;  	byte dir;  	dword d; diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c index 26515c27ea8c..25e419752a7b 100644 --- a/drivers/leds/leds-netxbig.c +++ b/drivers/leds/leds-netxbig.c @@ -330,18 +330,18 @@ create_netxbig_led(struct platform_device *pdev,  	led_dat->sata = 0;  	led_dat->cdev.brightness = LED_OFF;  	led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; -	/* -	 * If available, expose the SATA activity blink capability through -	 * a "sata" sysfs attribute. -	 */ -	if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) -		led_dat->cdev.groups = netxbig_led_groups;  	led_dat->mode_addr = template->mode_addr;  	led_dat->mode_val = template->mode_val;  	led_dat->bright_addr = template->bright_addr;  	led_dat->bright_max = (1 << pdata->gpio_ext->num_data) - 1;  	led_dat->timer = pdata->timer;  	led_dat->num_timer = pdata->num_timer; +	/* +	 * If available, expose the SATA activity blink capability through +	 * a "sata" sysfs attribute. +	 */ +	if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) +		led_dat->cdev.groups = netxbig_led_groups;  	return led_classdev_register(&pdev->dev, &led_dat->cdev);  } diff --git a/drivers/mcb/mcb-internal.h b/drivers/mcb/mcb-internal.h index f956ef26c0ce..fb7493dcfb79 100644 --- a/drivers/mcb/mcb-internal.h +++ b/drivers/mcb/mcb-internal.h @@ -7,6 +7,7 @@  #define PCI_DEVICE_ID_MEN_CHAMELEON	0x4d45  #define CHAMELEON_FILENAME_LEN		12  #define CHAMELEONV2_MAGIC		0xabce +#define CHAM_HEADER_SIZE		0x200  enum chameleon_descriptor_type {  	CHAMELEON_DTYPE_GENERAL = 0x0, diff --git a/drivers/mcb/mcb-pci.c b/drivers/mcb/mcb-pci.c index b59181965643..5e1bd5db02c8 100644 --- a/drivers/mcb/mcb-pci.c +++ b/drivers/mcb/mcb-pci.c @@ -17,6 +17,7 @@  struct priv {  	struct mcb_bus *bus; +	phys_addr_t mapbase;  	void __iomem *base;  }; @@ -31,8 +32,8 @@ static int mcb_pci_get_irq(struct mcb_device *mdev)  static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)  { +	struct resource *res;  	struct priv *priv; -	phys_addr_t mapbase;  	int ret;  	int num_cells;  	unsigned long flags; @@ -47,19 +48,21 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)  		return -ENODEV;  	} -	mapbase = pci_resource_start(pdev, 0); -	if (!mapbase) { +	priv->mapbase = pci_resource_start(pdev, 0); +	if (!priv->mapbase) {  		dev_err(&pdev->dev, "No PCI resource\n");  		goto err_start;  	} -	ret = pci_request_region(pdev, 0, KBUILD_MODNAME); -	if (ret) { -		dev_err(&pdev->dev, "Failed to request PCI BARs\n"); +	res = request_mem_region(priv->mapbase, CHAM_HEADER_SIZE, +				 KBUILD_MODNAME); +	if (IS_ERR(res)) { +		dev_err(&pdev->dev, "Failed to request PCI memory\n"); +		ret = PTR_ERR(res);  		goto err_start;  	} -	priv->base = pci_iomap(pdev, 0, 0); +	priv->base = ioremap(priv->mapbase, CHAM_HEADER_SIZE);  	if (!priv->base) {  		dev_err(&pdev->dev, "Cannot ioremap\n");  		ret = -ENOMEM; @@ -84,7 +87,7 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)  	priv->bus->get_irq = mcb_pci_get_irq; -	ret = chameleon_parse_cells(priv->bus, mapbase, priv->base); +	ret = chameleon_parse_cells(priv->bus, priv->mapbase, priv->base);  	if (ret < 0)  		goto err_drvdata;  	num_cells = ret; @@ -93,8 +96,10 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)  	mcb_bus_add_devices(priv->bus); +	return 0; +  err_drvdata: -	pci_iounmap(pdev, priv->base); +	iounmap(priv->base);  err_ioremap:  	pci_release_region(pdev, 0);  err_start: @@ -107,6 +112,10 @@ static void mcb_pci_remove(struct pci_dev *pdev)  	struct priv *priv = pci_get_drvdata(pdev);  	mcb_release_bus(priv->bus); + +	iounmap(priv->base); +	release_region(priv->mapbase, CHAM_HEADER_SIZE); +	pci_disable_device(pdev);  }  static const struct pci_device_id mcb_pci_tbl[] = { diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c index 51fd6b524371..d1b55fe62817 100644 --- a/drivers/misc/cxl/context.c +++ b/drivers/misc/cxl/context.c @@ -100,6 +100,46 @@ int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master,  	return 0;  } +static int cxl_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ +	struct cxl_context *ctx = vma->vm_file->private_data; +	unsigned long address = (unsigned long)vmf->virtual_address; +	u64 area, offset; + +	offset = vmf->pgoff << PAGE_SHIFT; + +	pr_devel("%s: pe: %i address: 0x%lx offset: 0x%llx\n", +			__func__, ctx->pe, address, offset); + +	if (ctx->afu->current_mode == CXL_MODE_DEDICATED) { +		area = ctx->afu->psn_phys; +		if (offset > ctx->afu->adapter->ps_size) +			return VM_FAULT_SIGBUS; +	} else { +		area = ctx->psn_phys; +		if (offset > ctx->psn_size) +			return VM_FAULT_SIGBUS; +	} + +	mutex_lock(&ctx->status_mutex); + +	if (ctx->status != STARTED) { +		mutex_unlock(&ctx->status_mutex); +		pr_devel("%s: Context not started, failing problem state access\n", __func__); +		return VM_FAULT_SIGBUS; +	} + +	vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT); + +	mutex_unlock(&ctx->status_mutex); + +	return VM_FAULT_NOPAGE; +} + +static const struct vm_operations_struct cxl_mmap_vmops = { +	.fault = cxl_mmap_fault, +}; +  /*   * Map a per-context mmio space into the given vma.   */ @@ -108,26 +148,25 @@ int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma)  	u64 len = vma->vm_end - vma->vm_start;  	len = min(len, ctx->psn_size); -	if (ctx->afu->current_mode == CXL_MODE_DEDICATED) { -		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); -		return vm_iomap_memory(vma, ctx->afu->psn_phys, ctx->afu->adapter->ps_size); -	} +	if (ctx->afu->current_mode != CXL_MODE_DEDICATED) { +		/* make sure there is a valid per process space for this AFU */ +		if ((ctx->master && !ctx->afu->psa) || (!ctx->afu->pp_psa)) { +			pr_devel("AFU doesn't support mmio space\n"); +			return -EINVAL; +		} -	/* make sure there is a valid per process space for this AFU */ -	if ((ctx->master && !ctx->afu->psa) || (!ctx->afu->pp_psa)) { -		pr_devel("AFU doesn't support mmio space\n"); -		return -EINVAL; +		/* Can't mmap until the AFU is enabled */ +		if (!ctx->afu->enabled) +			return -EBUSY;  	} -	/* Can't mmap until the AFU is enabled */ -	if (!ctx->afu->enabled) -		return -EBUSY; -  	pr_devel("%s: mmio physical: %llx pe: %i master:%i\n", __func__,  		 ctx->psn_phys, ctx->pe , ctx->master); +	vma->vm_flags |= VM_IO | VM_PFNMAP;  	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); -	return vm_iomap_memory(vma, ctx->psn_phys, len); +	vma->vm_ops = &cxl_mmap_vmops; +	return 0;  }  /* @@ -150,12 +189,6 @@ static void __detach_context(struct cxl_context *ctx)  	afu_release_irqs(ctx);  	flush_work(&ctx->fault_work); /* Only needed for dedicated process */  	wake_up_all(&ctx->wq); - -	/* Release Problem State Area mapping */ -	mutex_lock(&ctx->mapping_lock); -	if (ctx->mapping) -		unmap_mapping_range(ctx->mapping, 0, 0, 1); -	mutex_unlock(&ctx->mapping_lock);  }  /* @@ -184,6 +217,17 @@ void cxl_context_detach_all(struct cxl_afu *afu)  		 * created and torn down after the IDR removed  		 */  		__detach_context(ctx); + +		/* +		 * We are force detaching - remove any active PSA mappings so +		 * userspace cannot interfere with the card if it comes back. +		 * Easiest way to exercise this is to unbind and rebind the +		 * driver via sysfs while it is in use. +		 */ +		mutex_lock(&ctx->mapping_lock); +		if (ctx->mapping) +			unmap_mapping_range(ctx->mapping, 0, 0, 1); +		mutex_unlock(&ctx->mapping_lock);  	}  	mutex_unlock(&afu->contexts_lock);  } diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c index e9f2f10dbb37..b15d8113877c 100644 --- a/drivers/misc/cxl/file.c +++ b/drivers/misc/cxl/file.c @@ -140,18 +140,20 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,  	pr_devel("%s: pe: %i\n", __func__, ctx->pe); -	mutex_lock(&ctx->status_mutex); -	if (ctx->status != OPENED) { -		rc = -EIO; -		goto out; -	} - +	/* 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;  	} +	mutex_lock(&ctx->status_mutex); +	if (ctx->status != OPENED) { +		rc = -EIO; +		goto out; +	} +  	/*  	 * if any of the reserved fields are set or any of the unused  	 * flags are set it's invalid diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index ff2755062b44..06ff0a2ec960 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -234,6 +234,18 @@ static int mei_me_hw_reset(struct mei_device *dev, bool intr_enable)  	struct mei_me_hw *hw = to_me_hw(dev);  	u32 hcsr = mei_hcsr_read(hw); +	/* H_RST may be found lit before reset is started, +	 * for example if preceding reset flow hasn't completed. +	 * In that case asserting H_RST will be ignored, therefore +	 * we need to clean H_RST bit to start a successful reset sequence. +	 */ +	if ((hcsr & H_RST) == H_RST) { +		dev_warn(dev->dev, "H_RST is set = 0x%08X", hcsr); +		hcsr &= ~H_RST; +		mei_me_reg_write(hw, H_CSR, hcsr); +		hcsr = mei_hcsr_read(hw); +	} +  	hcsr |= H_RST | H_IG | H_IS;  	if (intr_enable) diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c index e3e56d35f0ee..970314e0aac8 100644 --- a/drivers/mmc/host/sdhci-acpi.c +++ b/drivers/mmc/host/sdhci-acpi.c @@ -247,6 +247,7 @@ static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = {  	{ "INT33BB"  , "3" , &sdhci_acpi_slot_int_sd },  	{ "INT33C6"  , NULL, &sdhci_acpi_slot_int_sdio },  	{ "INT3436"  , NULL, &sdhci_acpi_slot_int_sdio }, +	{ "INT344D"  , NULL, &sdhci_acpi_slot_int_sdio },  	{ "PNP0D40"  },  	{ },  }; @@ -257,6 +258,7 @@ static const struct acpi_device_id sdhci_acpi_ids[] = {  	{ "INT33BB"  },  	{ "INT33C6"  },  	{ "INT3436"  }, +	{ "INT344D"  },  	{ "PNP0D40"  },  	{ },  }; diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 03427755b902..4f38554ce679 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -993,6 +993,31 @@ static const struct pci_device_id pci_ids[] = {  		.subdevice	= PCI_ANY_ID,  		.driver_data	= (kernel_ulong_t)&sdhci_intel_mrfl_mmc,  	}, + +	{ +		.vendor		= PCI_VENDOR_ID_INTEL, +		.device		= PCI_DEVICE_ID_INTEL_SPT_EMMC, +		.subvendor	= PCI_ANY_ID, +		.subdevice	= PCI_ANY_ID, +		.driver_data	= (kernel_ulong_t)&sdhci_intel_byt_emmc, +	}, + +	{ +		.vendor		= PCI_VENDOR_ID_INTEL, +		.device		= PCI_DEVICE_ID_INTEL_SPT_SDIO, +		.subvendor	= PCI_ANY_ID, +		.subdevice	= PCI_ANY_ID, +		.driver_data	= (kernel_ulong_t)&sdhci_intel_byt_sdio, +	}, + +	{ +		.vendor		= PCI_VENDOR_ID_INTEL, +		.device		= PCI_DEVICE_ID_INTEL_SPT_SD, +		.subvendor	= PCI_ANY_ID, +		.subdevice	= PCI_ANY_ID, +		.driver_data	= (kernel_ulong_t)&sdhci_intel_byt_sd, +	}, +  	{  		.vendor		= PCI_VENDOR_ID_O2,  		.device		= PCI_DEVICE_ID_O2_8120, diff --git a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h index d57c3d169914..1ec684d06d54 100644 --- a/drivers/mmc/host/sdhci-pci.h +++ b/drivers/mmc/host/sdhci-pci.h @@ -21,6 +21,9 @@  #define PCI_DEVICE_ID_INTEL_CLV_EMMC0	0x08e5  #define PCI_DEVICE_ID_INTEL_CLV_EMMC1	0x08e6  #define PCI_DEVICE_ID_INTEL_QRK_SD	0x08A7 +#define PCI_DEVICE_ID_INTEL_SPT_EMMC	0x9d2b +#define PCI_DEVICE_ID_INTEL_SPT_SDIO	0x9d2c +#define PCI_DEVICE_ID_INTEL_SPT_SD	0x9d2d  /*   * PCI registers diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index 45238871192d..ca3424e7ef71 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c @@ -300,13 +300,6 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)  	if (IS_ERR(host))  		return PTR_ERR(host); -	if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) { -		ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info()); -		if (ret < 0) -			goto err_mbus_win; -	} - -  	pltfm_host = sdhci_priv(host);  	pltfm_host->priv = pxa; @@ -325,6 +318,12 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)  	if (!IS_ERR(pxa->clk_core))  		clk_prepare_enable(pxa->clk_core); +	if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) { +		ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info()); +		if (ret < 0) +			goto err_mbus_win; +	} +  	/* enable 1/8V DDR capable */  	host->mmc->caps |= MMC_CAP_1_8V_DDR; @@ -396,11 +395,11 @@ err_add_host:  	pm_runtime_disable(&pdev->dev);  err_of_parse:  err_cd_req: +err_mbus_win:  	clk_disable_unprepare(pxa->clk_io);  	if (!IS_ERR(pxa->clk_core))  		clk_disable_unprepare(pxa->clk_core);  err_clk_get: -err_mbus_win:  	sdhci_pltfm_free(pdev);  	return ret;  } diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index cbb245b58538..f1a488ee432f 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -259,8 +259,6 @@ static void sdhci_reinit(struct sdhci_host *host)  		del_timer_sync(&host->tuning_timer);  		host->flags &= ~SDHCI_NEEDS_RETUNING; -		host->mmc->max_blk_count = -			(host->quirks & SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535;  	}  	sdhci_enable_card_detection(host);  } @@ -1273,6 +1271,12 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned char mode,  		spin_unlock_irq(&host->lock);  		mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);  		spin_lock_irq(&host->lock); + +		if (mode != MMC_POWER_OFF) +			sdhci_writeb(host, SDHCI_POWER_ON, SDHCI_POWER_CONTROL); +		else +			sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); +  		return;  	} @@ -1353,6 +1357,8 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)  	sdhci_runtime_pm_get(host); +	present = mmc_gpio_get_cd(host->mmc); +  	spin_lock_irqsave(&host->lock, flags);  	WARN_ON(host->mrq != NULL); @@ -1381,7 +1387,6 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)  	 *     zero: cd-gpio is used, and card is removed  	 *     one: cd-gpio is used, and card is present  	 */ -	present = mmc_gpio_get_cd(host->mmc);  	if (present < 0) {  		/* If polling, assume that the card is always present. */  		if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) @@ -1880,6 +1885,18 @@ static int sdhci_card_busy(struct mmc_host *mmc)  	return !(present_state & SDHCI_DATA_LVL_MASK);  } +static int sdhci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios) +{ +	struct sdhci_host *host = mmc_priv(mmc); +	unsigned long flags; + +	spin_lock_irqsave(&host->lock, flags); +	host->flags |= SDHCI_HS400_TUNING; +	spin_unlock_irqrestore(&host->lock, flags); + +	return 0; +} +  static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)  {  	struct sdhci_host *host = mmc_priv(mmc); @@ -1887,10 +1904,18 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)  	int tuning_loop_counter = MAX_TUNING_LOOP;  	int err = 0;  	unsigned long flags; +	unsigned int tuning_count = 0; +	bool hs400_tuning;  	sdhci_runtime_pm_get(host);  	spin_lock_irqsave(&host->lock, flags); +	hs400_tuning = host->flags & SDHCI_HS400_TUNING; +	host->flags &= ~SDHCI_HS400_TUNING; + +	if (host->tuning_mode == SDHCI_TUNING_MODE_1) +		tuning_count = host->tuning_count; +  	/*  	 * The Host Controller needs tuning only in case of SDR104 mode  	 * and for SDR50 mode when Use Tuning for SDR50 is set in the @@ -1899,8 +1924,20 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)  	 * tuning function has to be executed.  	 */  	switch (host->timing) { +	/* HS400 tuning is done in HS200 mode */  	case MMC_TIMING_MMC_HS400: +		err = -EINVAL; +		goto out_unlock; +  	case MMC_TIMING_MMC_HS200: +		/* +		 * Periodic re-tuning for HS400 is not expected to be needed, so +		 * disable it here. +		 */ +		if (hs400_tuning) +			tuning_count = 0; +		break; +  	case MMC_TIMING_UHS_SDR104:  		break; @@ -1911,9 +1948,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)  		/* FALLTHROUGH */  	default: -		spin_unlock_irqrestore(&host->lock, flags); -		sdhci_runtime_pm_put(host); -		return 0; +		goto out_unlock;  	}  	if (host->ops->platform_execute_tuning) { @@ -2037,24 +2072,11 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)  	}  out: -	/* -	 * If this is the very first time we are here, we start the retuning -	 * timer. Since only during the first time, SDHCI_NEEDS_RETUNING -	 * flag won't be set, we check this condition before actually starting -	 * the timer. -	 */ -	if (!(host->flags & SDHCI_NEEDS_RETUNING) && host->tuning_count && -	    (host->tuning_mode == SDHCI_TUNING_MODE_1)) { +	host->flags &= ~SDHCI_NEEDS_RETUNING; + +	if (tuning_count) {  		host->flags |= SDHCI_USING_RETUNING_TIMER; -		mod_timer(&host->tuning_timer, jiffies + -			host->tuning_count * HZ); -		/* Tuning mode 1 limits the maximum data length to 4MB */ -		mmc->max_blk_count = (4 * 1024 * 1024) / mmc->max_blk_size; -	} else if (host->flags & SDHCI_USING_RETUNING_TIMER) { -		host->flags &= ~SDHCI_NEEDS_RETUNING; -		/* Reload the new initial value for timer */ -		mod_timer(&host->tuning_timer, jiffies + -			  host->tuning_count * HZ); +		mod_timer(&host->tuning_timer, jiffies + tuning_count * HZ);  	}  	/* @@ -2070,6 +2092,7 @@ out:  	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);  	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); +out_unlock:  	spin_unlock_irqrestore(&host->lock, flags);  	sdhci_runtime_pm_put(host); @@ -2110,15 +2133,18 @@ static void sdhci_card_event(struct mmc_host *mmc)  {  	struct sdhci_host *host = mmc_priv(mmc);  	unsigned long flags; +	int present;  	/* First check if client has provided their own card event */  	if (host->ops->card_event)  		host->ops->card_event(host); +	present = sdhci_do_get_cd(host); +  	spin_lock_irqsave(&host->lock, flags);  	/* Check host->mrq first in case we are runtime suspended */ -	if (host->mrq && !sdhci_do_get_cd(host)) { +	if (host->mrq && !present) {  		pr_err("%s: Card removed during transfer!\n",  			mmc_hostname(host->mmc));  		pr_err("%s: Resetting controller.\n", @@ -2142,6 +2168,7 @@ static const struct mmc_host_ops sdhci_ops = {  	.hw_reset	= sdhci_hw_reset,  	.enable_sdio_irq = sdhci_enable_sdio_irq,  	.start_signal_voltage_switch	= sdhci_start_signal_voltage_switch, +	.prepare_hs400_tuning		= sdhci_prepare_hs400_tuning,  	.execute_tuning			= sdhci_execute_tuning,  	.card_event			= sdhci_card_event,  	.card_busy	= sdhci_card_busy, @@ -3260,8 +3287,9 @@ int sdhci_add_host(struct sdhci_host *host)  		mmc->max_segs = SDHCI_MAX_SEGS;  	/* -	 * Maximum number of sectors in one transfer. Limited by DMA boundary -	 * size (512KiB). +	 * Maximum number of sectors in one transfer. Limited by SDMA boundary +	 * size (512KiB). Note some tuning modes impose a 4MiB limit, but this +	 * is less anyway.  	 */  	mmc->max_req_size = 524288; diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c index 1fcd5568a352..f3470d96837a 100644 --- a/drivers/net/ethernet/allwinner/sun4i-emac.c +++ b/drivers/net/ethernet/allwinner/sun4i-emac.c @@ -850,8 +850,10 @@ static int emac_probe(struct platform_device *pdev)  	}  	db->clk = devm_clk_get(&pdev->dev, NULL); -	if (IS_ERR(db->clk)) +	if (IS_ERR(db->clk)) { +		ret = PTR_ERR(db->clk);  		goto out; +	}  	clk_prepare_enable(db->clk); diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c index 3498760dc22a..760c72c6e2ac 100644 --- a/drivers/net/ethernet/altera/altera_tse_main.c +++ b/drivers/net/ethernet/altera/altera_tse_main.c @@ -1170,10 +1170,6 @@ tx_request_irq_error:  init_error:  	free_skbufs(dev);  alloc_skbuf_error: -	if (priv->phydev) { -		phy_disconnect(priv->phydev); -		priv->phydev = NULL; -	}  phy_error:  	return ret;  } @@ -1186,12 +1182,9 @@ static int tse_shutdown(struct net_device *dev)  	int ret;  	unsigned long int flags; -	/* Stop and disconnect the PHY */ -	if (priv->phydev) { +	/* Stop the PHY */ +	if (priv->phydev)  		phy_stop(priv->phydev); -		phy_disconnect(priv->phydev); -		priv->phydev = NULL; -	}  	netif_stop_queue(dev);  	napi_disable(&priv->napi); @@ -1525,6 +1518,10 @@ err_free_netdev:  static int altera_tse_remove(struct platform_device *pdev)  {  	struct net_device *ndev = platform_get_drvdata(pdev); +	struct altera_tse_private *priv = netdev_priv(ndev); + +	if (priv->phydev) +		phy_disconnect(priv->phydev);  	platform_set_drvdata(pdev, NULL);  	altera_tse_mdio_destroy(ndev); diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c index e398eda07298..c8af3ce3ea38 100644 --- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c @@ -184,15 +184,16 @@ static void alx_schedule_reset(struct alx_priv *alx)  	schedule_work(&alx->reset_wk);  } -static bool alx_clean_rx_irq(struct alx_priv *alx, int budget) +static int alx_clean_rx_irq(struct alx_priv *alx, int budget)  {  	struct alx_rx_queue *rxq = &alx->rxq;  	struct alx_rrd *rrd;  	struct alx_buffer *rxb;  	struct sk_buff *skb;  	u16 length, rfd_cleaned = 0; +	int work = 0; -	while (budget > 0) { +	while (work < budget) {  		rrd = &rxq->rrd[rxq->rrd_read_idx];  		if (!(rrd->word3 & cpu_to_le32(1 << RRD_UPDATED_SHIFT)))  			break; @@ -203,7 +204,7 @@ static bool alx_clean_rx_irq(struct alx_priv *alx, int budget)  		    ALX_GET_FIELD(le32_to_cpu(rrd->word0),  				  RRD_NOR) != 1) {  			alx_schedule_reset(alx); -			return 0; +			return work;  		}  		rxb = &rxq->bufs[rxq->read_idx]; @@ -243,7 +244,7 @@ static bool alx_clean_rx_irq(struct alx_priv *alx, int budget)  		}  		napi_gro_receive(&alx->napi, skb); -		budget--; +		work++;  next_pkt:  		if (++rxq->read_idx == alx->rx_ringsz) @@ -258,21 +259,22 @@ next_pkt:  	if (rfd_cleaned)  		alx_refill_rx_ring(alx, GFP_ATOMIC); -	return budget > 0; +	return work;  }  static int alx_poll(struct napi_struct *napi, int budget)  {  	struct alx_priv *alx = container_of(napi, struct alx_priv, napi);  	struct alx_hw *hw = &alx->hw; -	bool complete = true;  	unsigned long flags; +	bool tx_complete; +	int work; -	complete = alx_clean_tx_irq(alx) && -		   alx_clean_rx_irq(alx, budget); +	tx_complete = alx_clean_tx_irq(alx); +	work = alx_clean_rx_irq(alx, budget); -	if (!complete) -		return 1; +	if (!tx_complete || work == budget) +		return budget;  	napi_complete(&alx->napi); @@ -284,7 +286,7 @@ static int alx_poll(struct napi_struct *napi, int budget)  	alx_post_write(hw); -	return 0; +	return work;  }  static irqreturn_t alx_intr_handle(struct alx_priv *alx, u32 intr) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 553dcd8a9df2..96bf01ba32dd 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -7413,6 +7413,8 @@ static inline void tg3_netif_start(struct tg3 *tp)  }  static void tg3_irq_quiesce(struct tg3 *tp) +	__releases(tp->lock) +	__acquires(tp->lock)  {  	int i; @@ -7421,8 +7423,12 @@ static void tg3_irq_quiesce(struct tg3 *tp)  	tp->irq_sync = 1;  	smp_mb(); +	spin_unlock_bh(&tp->lock); +  	for (i = 0; i < tp->irq_cnt; i++)  		synchronize_irq(tp->napi[i].irq_vec); + +	spin_lock_bh(&tp->lock);  }  /* Fully shutdown all tg3 driver activity elsewhere in the system. @@ -9018,6 +9024,8 @@ static void tg3_restore_clk(struct tg3 *tp)  /* tp->lock is held. */  static int tg3_chip_reset(struct tg3 *tp) +	__releases(tp->lock) +	__acquires(tp->lock)  {  	u32 val;  	void (*write_op)(struct tg3 *, u32, u32); @@ -9073,9 +9081,13 @@ static int tg3_chip_reset(struct tg3 *tp)  	}  	smp_mb(); +	tg3_full_unlock(tp); +  	for (i = 0; i < tp->irq_cnt; i++)  		synchronize_irq(tp->napi[i].irq_vec); +	tg3_full_lock(tp, 0); +  	if (tg3_asic_rev(tp) == ASIC_REV_57780) {  		val = tr32(TG3_PCIE_LNKCTL) & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN;  		tw32(TG3_PCIE_LNKCTL, val | TG3_PCIE_LNKCTL_L1_PLL_PD_DIS); @@ -10903,11 +10915,13 @@ static void tg3_timer(unsigned long __opaque)  {  	struct tg3 *tp = (struct tg3 *) __opaque; -	if (tp->irq_sync || tg3_flag(tp, RESET_TASK_PENDING)) -		goto restart_timer; -  	spin_lock(&tp->lock); +	if (tp->irq_sync || tg3_flag(tp, RESET_TASK_PENDING)) { +		spin_unlock(&tp->lock); +		goto restart_timer; +	} +  	if (tg3_asic_rev(tp) == ASIC_REV_5717 ||  	    tg3_flag(tp, 57765_CLASS))  		tg3_chk_missed_msi(tp); @@ -11101,11 +11115,13 @@ static void tg3_reset_task(struct work_struct *work)  	struct tg3 *tp = container_of(work, struct tg3, reset_task);  	int err; +	rtnl_lock();  	tg3_full_lock(tp, 0);  	if (!netif_running(tp->dev)) {  		tg3_flag_clear(tp, RESET_TASK_PENDING);  		tg3_full_unlock(tp); +		rtnl_unlock();  		return;  	} @@ -11138,6 +11154,7 @@ out:  		tg3_phy_start(tp);  	tg3_flag_clear(tp, RESET_TASK_PENDING); +	rtnl_unlock();  }  static int tg3_request_irq(struct tg3 *tp, int irq_num) diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c index 55eb7f2af2b4..7ef55f5fa664 100644 --- a/drivers/net/ethernet/cadence/at91_ether.c +++ b/drivers/net/ethernet/cadence/at91_ether.c @@ -340,7 +340,7 @@ static int __init at91ether_probe(struct platform_device *pdev)  		res = PTR_ERR(lp->pclk);  		goto err_free_dev;  	} -	clk_enable(lp->pclk); +	clk_prepare_enable(lp->pclk);  	lp->hclk = ERR_PTR(-ENOENT);  	lp->tx_clk = ERR_PTR(-ENOENT); @@ -406,7 +406,7 @@ static int __init at91ether_probe(struct platform_device *pdev)  err_out_unregister_netdev:  	unregister_netdev(dev);  err_disable_clock: -	clk_disable(lp->pclk); +	clk_disable_unprepare(lp->pclk);  err_free_dev:  	free_netdev(dev);  	return res; @@ -424,7 +424,7 @@ static int at91ether_remove(struct platform_device *pdev)  	kfree(lp->mii_bus->irq);  	mdiobus_free(lp->mii_bus);  	unregister_netdev(dev); -	clk_disable(lp->pclk); +	clk_disable_unprepare(lp->pclk);  	free_netdev(dev);  	return 0; @@ -440,7 +440,7 @@ static int at91ether_suspend(struct platform_device *pdev, pm_message_t mesg)  		netif_stop_queue(net_dev);  		netif_device_detach(net_dev); -		clk_disable(lp->pclk); +		clk_disable_unprepare(lp->pclk);  	}  	return 0;  } @@ -451,7 +451,7 @@ static int at91ether_resume(struct platform_device *pdev)  	struct macb *lp = netdev_priv(net_dev);  	if (netif_running(net_dev)) { -		clk_enable(lp->pclk); +		clk_prepare_enable(lp->pclk);  		netif_device_attach(net_dev);  		netif_start_queue(net_dev); diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 2215d432a059..a936ee8958c7 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -2430,7 +2430,7 @@ static void cfg_queues(struct adapter *adapter)  	 */  	n10g = 0;  	for_each_port(adapter, pidx) -		n10g += is_10g_port(&adap2pinfo(adapter, pidx)->link_cfg); +		n10g += is_x_10g_port(&adap2pinfo(adapter, pidx)->link_cfg);  	/*  	 * We default to 1 queue per non-10G port and up to # of cores queues diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c index 21dc9a20308c..60426cf890a7 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c @@ -323,6 +323,8 @@ int t4vf_port_init(struct adapter *adapter, int pidx)  		return v;  	v = be32_to_cpu(port_rpl.u.info.lstatus_to_modtype); +	pi->mdio_addr = (v & FW_PORT_CMD_MDIOCAP_F) ? +			FW_PORT_CMD_MDIOADDR_G(v) : -1;  	pi->port_type = FW_PORT_CMD_PTYPE_G(v);  	pi->mod_type = FW_PORT_MOD_TYPE_NA; diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index 705f334ebb85..b29e027c476e 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -1616,7 +1616,7 @@ static int enic_open(struct net_device *netdev)  		if (vnic_rq_desc_used(&enic->rq[i]) == 0) {  			netdev_err(netdev, "Unable to alloc receive buffers\n");  			err = -ENOMEM; -			goto err_out_notify_unset; +			goto err_out_free_rq;  		}  	} @@ -1649,7 +1649,9 @@ static int enic_open(struct net_device *netdev)  	return 0; -err_out_notify_unset: +err_out_free_rq: +	for (i = 0; i < enic->rq_count; i++) +		vnic_rq_clean(&enic->rq[i], enic_free_rq_buf);  	enic_dev_notify_unset(enic);  err_out_free_intr:  	enic_free_intr(enic); diff --git a/drivers/net/ethernet/dnet.c b/drivers/net/ethernet/dnet.c index a379c3e4b57f..13d00a38a5bd 100644 --- a/drivers/net/ethernet/dnet.c +++ b/drivers/net/ethernet/dnet.c @@ -398,13 +398,8 @@ static int dnet_poll(struct napi_struct *napi, int budget)  		 * break out of while loop if there are no more  		 * packets waiting  		 */ -		if (!(dnet_readl(bp, RX_FIFO_WCNT) >> 16)) { -			napi_complete(napi); -			int_enable = dnet_readl(bp, INTR_ENB); -			int_enable |= DNET_INTR_SRC_RX_CMDFIFOAF; -			dnet_writel(bp, int_enable, INTR_ENB); -			return 0; -		} +		if (!(dnet_readl(bp, RX_FIFO_WCNT) >> 16)) +			break;  		cmd_word = dnet_readl(bp, RX_LEN_FIFO);  		pkt_len = cmd_word & 0xFFFF; @@ -433,20 +428,17 @@ static int dnet_poll(struct napi_struct *napi, int budget)  			       "size %u.\n", dev->name, pkt_len);  	} -	budget -= npackets; -  	if (npackets < budget) {  		/* We processed all packets available.  Tell NAPI it can -		 * stop polling then re-enable rx interrupts */ +		 * stop polling then re-enable rx interrupts. +		 */  		napi_complete(napi);  		int_enable = dnet_readl(bp, INTR_ENB);  		int_enable |= DNET_INTR_SRC_RX_CMDFIFOAF;  		dnet_writel(bp, int_enable, INTR_ENB); -		return 0;  	} -	/* There are still packets waiting */ -	return 1; +	return npackets;  }  static irqreturn_t dnet_interrupt(int irq, void *dev_id) diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index 469691ad4a1e..40132929daf7 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -424,6 +424,8 @@ struct bufdesc_ex {   * (40ns * 6).   */  #define FEC_QUIRK_BUG_CAPTURE		(1 << 10) +/* Controller has only one MDIO bus */ +#define FEC_QUIRK_SINGLE_MDIO		(1 << 11)  struct fec_enet_priv_tx_q {  	int index; diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 5ebdf8dc8a31..bba87775419d 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -91,7 +91,8 @@ static struct platform_device_id fec_devtype[] = {  		.driver_data = 0,  	}, {  		.name = "imx28-fec", -		.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME, +		.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME | +				FEC_QUIRK_SINGLE_MDIO,  	}, {  		.name = "imx6q-fec",  		.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT | @@ -1937,7 +1938,7 @@ static int fec_enet_mii_init(struct platform_device *pdev)  	int err = -ENXIO, i;  	/* -	 * The dual fec interfaces are not equivalent with enet-mac. +	 * The i.MX28 dual fec interfaces are not equal.  	 * Here are the differences:  	 *  	 *  - fec0 supports MII & RMII modes while fec1 only supports RMII @@ -1952,7 +1953,7 @@ static int fec_enet_mii_init(struct platform_device *pdev)  	 * mdio interface in board design, and need to be configured by  	 * fec0 mii_bus.  	 */ -	if ((fep->quirks & FEC_QUIRK_ENET_MAC) && fep->dev_id > 0) { +	if ((fep->quirks & FEC_QUIRK_SINGLE_MDIO) && fep->dev_id > 0) {  		/* fec1 uses fec0 mii_bus */  		if (mii_cnt && fec0_mii_bus) {  			fep->mii_bus = fec0_mii_bus; @@ -2015,7 +2016,7 @@ static int fec_enet_mii_init(struct platform_device *pdev)  	mii_cnt++;  	/* save fec0 mii_bus */ -	if (fep->quirks & FEC_QUIRK_ENET_MAC) +	if (fep->quirks & FEC_QUIRK_SINGLE_MDIO)  		fec0_mii_bus = fep->mii_bus;  	return 0; @@ -3129,6 +3130,7 @@ fec_probe(struct platform_device *pdev)  		pdev->id_entry = of_id->data;  	fep->quirks = pdev->id_entry->driver_data; +	fep->netdev = ndev;  	fep->num_rx_queues = num_rx_qs;  	fep->num_tx_queues = num_tx_qs; diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig index 5b8300a32bf5..4d61ef50b465 100644 --- a/drivers/net/ethernet/intel/Kconfig +++ b/drivers/net/ethernet/intel/Kconfig @@ -281,6 +281,17 @@ config I40E_DCB  	  If unsure, say N. +config I40E_FCOE +	bool "Fibre Channel over Ethernet (FCoE)" +	default n +	depends on I40E && DCB && FCOE +	---help--- +	  Say Y here if you want to use Fibre Channel over Ethernet (FCoE) +	  in the driver. This will create new netdev for exclusive FCoE +	  use with XL710 FCoE offloads enabled. + +	  If unsure, say N. +  config I40EVF  	tristate "Intel(R) XL710 X710 Virtual Function Ethernet support"  	depends on PCI_MSI diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c index 781065eb5431..e9c3a87e5b11 100644 --- a/drivers/net/ethernet/intel/e100.c +++ b/drivers/net/ethernet/intel/e100.c @@ -1543,7 +1543,7 @@ static int e100_phy_init(struct nic *nic)  		mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr);  	} else if ((nic->mac >= mac_82550_D102) || ((nic->flags & ich) &&  	   (mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000) && -		!(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))) { +		(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))) {  		/* enable/disable MDI/MDI-X auto-switching. */  		mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG,  				nic->mii.force_media ? 0 : NCONFIG_AUTO_SWITCH); diff --git a/drivers/net/ethernet/intel/i40e/Makefile b/drivers/net/ethernet/intel/i40e/Makefile index 4b94ddb29c24..c40581999121 100644 --- a/drivers/net/ethernet/intel/i40e/Makefile +++ b/drivers/net/ethernet/intel/i40e/Makefile @@ -44,4 +44,4 @@ i40e-objs := i40e_main.o \  	i40e_virtchnl_pf.o  i40e-$(CONFIG_I40E_DCB) += i40e_dcb.o i40e_dcb_nl.o -i40e-$(CONFIG_FCOE:m=y) += i40e_fcoe.o +i40e-$(CONFIG_I40E_FCOE) += i40e_fcoe.o diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c index 433a55886ad2..cb0de455683e 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c +++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c @@ -829,7 +829,7 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n,  		if (desc_n >= ring->count || desc_n < 0) {  			dev_info(&pf->pdev->dev,  				 "descriptor %d not found\n", desc_n); -			return; +			goto out;  		}  		if (!is_rx_ring) {  			txd = I40E_TX_DESC(ring, desc_n); @@ -855,6 +855,8 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n,  	} else {  		dev_info(&pf->pdev->dev, "dump desc rx/tx <vsi_seid> <ring_id> [<desc_n>]\n");  	} + +out:  	kfree(ring);  } diff --git a/drivers/net/ethernet/intel/i40e/i40e_osdep.h b/drivers/net/ethernet/intel/i40e/i40e_osdep.h index 045b5c4b98b3..ad802dd0f67a 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_osdep.h +++ b/drivers/net/ethernet/intel/i40e/i40e_osdep.h @@ -78,7 +78,7 @@ do {                                                            \  } while (0)  typedef enum i40e_status_code i40e_status; -#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) +#ifdef CONFIG_I40E_FCOE  #define I40E_FCOE -#endif /* CONFIG_FCOE or CONFIG_FCOE_MODULE */ +#endif  #endif /* _I40E_OSDEP_H_ */ diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 04b441460bbd..cecb340898fe 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -658,6 +658,8 @@ static inline u32 i40e_get_head(struct i40e_ring *tx_ring)  	return le32_to_cpu(*(volatile __le32 *)head);  } +#define WB_STRIDE 0x3 +  /**   * i40e_clean_tx_irq - Reclaim resources after transmit completes   * @tx_ring:  tx ring to clean @@ -759,6 +761,18 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget)  	tx_ring->q_vector->tx.total_bytes += total_bytes;  	tx_ring->q_vector->tx.total_packets += total_packets; +	/* check to see if there are any non-cache aligned descriptors +	 * waiting to be written back, and kick the hardware to force +	 * them to be written back in case of napi polling +	 */ +	if (budget && +	    !((i & WB_STRIDE) == WB_STRIDE) && +	    !test_bit(__I40E_DOWN, &tx_ring->vsi->state) && +	    (I40E_DESC_UNUSED(tx_ring) != tx_ring->count)) +		tx_ring->arm_wb = true; +	else +		tx_ring->arm_wb = false; +  	if (check_for_tx_hang(tx_ring) && i40e_check_tx_hang(tx_ring)) {  		/* schedule immediate reset if we believe we hung */  		dev_info(tx_ring->dev, "Detected Tx Unit Hang\n" @@ -777,13 +791,16 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget)  		netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index);  		dev_info(tx_ring->dev, -			 "tx hang detected on queue %d, resetting adapter\n", +			 "tx hang detected on queue %d, reset requested\n",  			 tx_ring->queue_index); -		tx_ring->netdev->netdev_ops->ndo_tx_timeout(tx_ring->netdev); +		/* do not fire the reset immediately, wait for the stack to +		 * decide we are truly stuck, also prevents every queue from +		 * simultaneously requesting a reset +		 */ -		/* the adapter is about to reset, no point in enabling stuff */ -		return true; +		/* the adapter is about to reset, no point in enabling polling */ +		budget = 1;  	}  	netdev_tx_completed_queue(netdev_get_tx_queue(tx_ring->netdev, @@ -806,7 +823,25 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget)  		}  	} -	return budget > 0; +	return !!budget; +} + +/** + * i40e_force_wb - Arm hardware to do a wb on noncache aligned descriptors + * @vsi: the VSI we care about + * @q_vector: the vector  on which to force writeback + * + **/ +static void i40e_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector) +{ +	u32 val = I40E_PFINT_DYN_CTLN_INTENA_MASK | +		  I40E_PFINT_DYN_CTLN_SWINT_TRIG_MASK | +		  I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK +		  /* allow 00 to be written to the index */; + +	wr32(&vsi->back->hw, +	     I40E_PFINT_DYN_CTLN(q_vector->v_idx + vsi->base_vector - 1), +	     val);  }  /** @@ -1290,9 +1325,7 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi,  	 * so the total length of IPv4 header is IHL*4 bytes  	 * The UDP_0 bit *may* bet set if the *inner* header is UDP  	 */ -	if (ipv4_tunnel && -	    (decoded.inner_prot != I40E_RX_PTYPE_INNER_PROT_UDP) && -	    !(rx_status & (1 << I40E_RX_DESC_STATUS_UDP_0_SHIFT))) { +	if (ipv4_tunnel) {  		skb->transport_header = skb->mac_header +  					sizeof(struct ethhdr) +  					(ip_hdr(skb)->ihl * 4); @@ -1302,15 +1335,19 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi,  					  skb->protocol == htons(ETH_P_8021AD))  					  ? VLAN_HLEN : 0; -		rx_udp_csum = udp_csum(skb); -		iph = ip_hdr(skb); -		csum = csum_tcpudp_magic( -				iph->saddr, iph->daddr, -				(skb->len - skb_transport_offset(skb)), -				IPPROTO_UDP, rx_udp_csum); +		if ((ip_hdr(skb)->protocol == IPPROTO_UDP) && +		    (udp_hdr(skb)->check != 0)) { +			rx_udp_csum = udp_csum(skb); +			iph = ip_hdr(skb); +			csum = csum_tcpudp_magic( +					iph->saddr, iph->daddr, +					(skb->len - skb_transport_offset(skb)), +					IPPROTO_UDP, rx_udp_csum); -		if (udp_hdr(skb)->check != csum) -			goto checksum_fail; +			if (udp_hdr(skb)->check != csum) +				goto checksum_fail; + +		} /* else its GRE and so no outer UDP header */  	}  	skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -1581,6 +1618,7 @@ int i40e_napi_poll(struct napi_struct *napi, int budget)  	struct i40e_vsi *vsi = q_vector->vsi;  	struct i40e_ring *ring;  	bool clean_complete = true; +	bool arm_wb = false;  	int budget_per_ring;  	if (test_bit(__I40E_DOWN, &vsi->state)) { @@ -1591,8 +1629,10 @@ int i40e_napi_poll(struct napi_struct *napi, int budget)  	/* Since the actual Tx work is minimal, we can give the Tx a larger  	 * budget and be more aggressive about cleaning up the Tx descriptors.  	 */ -	i40e_for_each_ring(ring, q_vector->tx) +	i40e_for_each_ring(ring, q_vector->tx) {  		clean_complete &= i40e_clean_tx_irq(ring, vsi->work_limit); +		arm_wb |= ring->arm_wb; +	}  	/* We attempt to distribute budget to each Rx queue fairly, but don't  	 * allow the budget to go below 1 because that would exit polling early. @@ -1603,8 +1643,11 @@ int i40e_napi_poll(struct napi_struct *napi, int budget)  		clean_complete &= i40e_clean_rx_irq(ring, budget_per_ring);  	/* If work not completed, return budget and polling will return */ -	if (!clean_complete) +	if (!clean_complete) { +		if (arm_wb) +			i40e_force_wb(vsi, q_vector);  		return budget; +	}  	/* Work is done so exit the polling mode and re-enable the interrupt */  	napi_complete(napi); @@ -1840,17 +1883,16 @@ static int i40e_tso(struct i40e_ring *tx_ring, struct sk_buff *skb,  	if (err < 0)  		return err; -	if (protocol == htons(ETH_P_IP)) { -		iph = skb->encapsulation ? inner_ip_hdr(skb) : ip_hdr(skb); +	iph = skb->encapsulation ? inner_ip_hdr(skb) : ip_hdr(skb); +	ipv6h = skb->encapsulation ? inner_ipv6_hdr(skb) : ipv6_hdr(skb); + +	if (iph->version == 4) {  		tcph = skb->encapsulation ? inner_tcp_hdr(skb) : tcp_hdr(skb);  		iph->tot_len = 0;  		iph->check = 0;  		tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,  						 0, IPPROTO_TCP, 0); -	} else if (skb_is_gso_v6(skb)) { - -		ipv6h = skb->encapsulation ? inner_ipv6_hdr(skb) -					   : ipv6_hdr(skb); +	} else if (ipv6h->version == 6) {  		tcph = skb->encapsulation ? inner_tcp_hdr(skb) : tcp_hdr(skb);  		ipv6h->payload_len = 0;  		tcph->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, @@ -1946,13 +1988,9 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 tx_flags,  					 I40E_TX_CTX_EXT_IP_IPV4_NO_CSUM;  			}  		} else if (tx_flags & I40E_TX_FLAGS_IPV6) { -			if (tx_flags & I40E_TX_FLAGS_TSO) { -				*cd_tunneling |= I40E_TX_CTX_EXT_IP_IPV6; +			*cd_tunneling |= I40E_TX_CTX_EXT_IP_IPV6; +			if (tx_flags & I40E_TX_FLAGS_TSO)  				ip_hdr(skb)->check = 0; -			} else { -				*cd_tunneling |= -					 I40E_TX_CTX_EXT_IP_IPV4_NO_CSUM; -			}  		}  		/* Now set the ctx descriptor fields */ @@ -1962,7 +2000,10 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 tx_flags,  				   ((skb_inner_network_offset(skb) -  					skb_transport_offset(skb)) >> 1) <<  				   I40E_TXD_CTX_QW0_NATLEN_SHIFT; - +		if (this_ip_hdr->version == 6) { +			tx_flags &= ~I40E_TX_FLAGS_IPV4; +			tx_flags |= I40E_TX_FLAGS_IPV6; +		}  	} else {  		network_hdr_len = skb_network_header_len(skb);  		this_ip_hdr = ip_hdr(skb); @@ -2198,7 +2239,6 @@ static void i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,  	/* Place RS bit on last descriptor of any packet that spans across the  	 * 4th descriptor (WB_STRIDE aka 0x3) in a 64B cacheline.  	 */ -#define WB_STRIDE 0x3  	if (((i & WB_STRIDE) != WB_STRIDE) &&  	    (first <= &tx_ring->tx_bi[i]) &&  	    (first >= &tx_ring->tx_bi[i & ~WB_STRIDE])) { diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h index e60d3accb2e2..18b00231d2f1 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h @@ -241,6 +241,7 @@ struct i40e_ring {  	unsigned long last_rx_timestamp;  	bool ring_active;		/* is ring online or not */ +	bool arm_wb;		/* do something to arm write back */  	/* stats structs */  	struct i40e_queue_stats	stats; diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c index 051ea94bdcd3..0f69ef81751a 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/drivers/net/ethernet/intel/igb/e1000_82575.c @@ -1125,7 +1125,7 @@ static s32 igb_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask)  	u32 swmask = mask;  	u32 fwmask = mask << 16;  	s32 ret_val = 0; -	s32 i = 0, timeout = 200; /* FIXME: find real value to use here */ +	s32 i = 0, timeout = 200;  	while (i < timeout) {  		if (igb_get_hw_semaphore(hw)) { diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 943cbd47d832..03e9eb0dc761 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -1829,7 +1829,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)  		err = mlx4_dev_cap(dev, &dev_cap);  		if (err) {  			mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting\n"); -			goto err_stop_fw; +			return err;  		}  		choose_steering_mode(dev, &dev_cap); @@ -1860,7 +1860,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)  					     &init_hca);  		if ((long long) icm_size < 0) {  			err = icm_size; -			goto err_stop_fw; +			return err;  		}  		dev->caps.max_fmr_maps = (1 << (32 - ilog2(dev->caps.num_mpts))) - 1; @@ -1874,7 +1874,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)  		err = mlx4_init_icm(dev, &dev_cap, &init_hca, icm_size);  		if (err) -			goto err_stop_fw; +			return err;  		err = mlx4_INIT_HCA(dev, &init_hca);  		if (err) { @@ -1886,7 +1886,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)  			err = mlx4_query_func(dev, &dev_cap);  			if (err < 0) {  				mlx4_err(dev, "QUERY_FUNC command failed, aborting.\n"); -				goto err_stop_fw; +				goto err_close;  			} else if (err & MLX4_QUERY_FUNC_NUM_SYS_EQS) {  				dev->caps.num_eqs = dev_cap.max_eqs;  				dev->caps.reserved_eqs = dev_cap.reserved_eqs; @@ -2006,11 +2006,6 @@ err_free_icm:  	if (!mlx4_is_slave(dev))  		mlx4_free_icms(dev); -err_stop_fw: -	if (!mlx4_is_slave(dev)) { -		mlx4_UNMAP_FA(dev); -		mlx4_free_icm(dev, priv->fw.fw_icm, 0); -	}  	return err;  } diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c index d6f549685c0f..7094a9c70fd5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/drivers/net/ethernet/mellanox/mlx4/mr.c @@ -584,6 +584,7 @@ EXPORT_SYMBOL_GPL(mlx4_mr_free);  void mlx4_mr_rereg_mem_cleanup(struct mlx4_dev *dev, struct mlx4_mr *mr)  {  	mlx4_mtt_cleanup(dev, &mr->mtt); +	mr->mtt.order = -1;  }  EXPORT_SYMBOL_GPL(mlx4_mr_rereg_mem_cleanup); @@ -593,14 +594,14 @@ int mlx4_mr_rereg_mem_write(struct mlx4_dev *dev, struct mlx4_mr *mr,  {  	int err; -	mpt_entry->start       = cpu_to_be64(iova); -	mpt_entry->length      = cpu_to_be64(size); -	mpt_entry->entity_size = cpu_to_be32(page_shift); -  	err = mlx4_mtt_init(dev, npages, page_shift, &mr->mtt);  	if (err)  		return err; +	mpt_entry->start       = cpu_to_be64(mr->iova); +	mpt_entry->length      = cpu_to_be64(mr->size); +	mpt_entry->entity_size = cpu_to_be32(mr->mtt.page_shift); +  	mpt_entry->pd_flags &= cpu_to_be32(MLX4_MPT_PD_MASK |  					   MLX4_MPT_PD_FLAG_EN_INV);  	mpt_entry->flags    &= cpu_to_be32(MLX4_MPT_FLAG_FREE | diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c index af099057f0e9..71af98bb72cb 100644 --- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c @@ -4033,8 +4033,10 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  	(void)pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));  	mgp->cmd = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->cmd),  				      &mgp->cmd_bus, GFP_KERNEL); -	if (mgp->cmd == NULL) +	if (!mgp->cmd) { +		status = -ENOMEM;  		goto abort_with_enabled; +	}  	mgp->board_span = pci_resource_len(pdev, 0);  	mgp->iomem_base = pci_resource_start(pdev, 0); diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c index c2f09af5c25b..4847713211ca 100644 --- a/drivers/net/ethernet/qlogic/qla3xxx.c +++ b/drivers/net/ethernet/qlogic/qla3xxx.c @@ -146,10 +146,7 @@ static int ql_wait_for_drvr_lock(struct ql3_adapter *qdev)  {  	int i = 0; -	while (i < 10) { -		if (i) -			ssleep(1); - +	do {  		if (ql_sem_lock(qdev,  				QL_DRVR_SEM_MASK,  				(QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) @@ -158,7 +155,8 @@ static int ql_wait_for_drvr_lock(struct ql3_adapter *qdev)  				      "driver lock acquired\n");  			return 1;  		} -	} +		ssleep(1); +	} while (++i < 10);  	netdev_err(qdev->ndev, "Timed out waiting for driver lock...\n");  	return 0; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 9929b97cfb36..2528c3fb6b90 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -2605,6 +2605,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  	} else {  		dev_err(&pdev->dev,  			"%s: failed. Please Reboot\n", __func__); +		err = -ENODEV;  		goto err_out_free_hw;  	} diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index c29ba80ae02b..37583a9d8853 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -473,6 +473,7 @@ static struct sh_eth_cpu_data r8a777x_data = {  	.eesr_err_check	= EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |  			  EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |  			  EESR_ECI, +	.fdr_value	= 0x00000f0f,  	.apr		= 1,  	.mpr		= 1, @@ -495,6 +496,7 @@ static struct sh_eth_cpu_data r8a779x_data = {  	.eesr_err_check	= EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |  			  EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |  			  EESR_ECI, +	.fdr_value	= 0x00000f0f,  	.apr		= 1,  	.mpr		= 1, @@ -536,6 +538,8 @@ static struct sh_eth_cpu_data sh7724_data = {  			  EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |  			  EESR_ECI, +	.trscer_err_mask = DESC_I_RINT8, +  	.apr		= 1,  	.mpr		= 1,  	.tpauser	= 1, @@ -856,6 +860,9 @@ static void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd)  	if (!cd->eesr_err_check)  		cd->eesr_err_check = DEFAULT_EESR_ERR_CHECK; + +	if (!cd->trscer_err_mask) +		cd->trscer_err_mask = DEFAULT_TRSCER_ERR_MASK;  }  static int sh_eth_check_reset(struct net_device *ndev) @@ -1294,7 +1301,7 @@ static int sh_eth_dev_init(struct net_device *ndev, bool start)  	/* Frame recv control (enable multiple-packets per rx irq) */  	sh_eth_write(ndev, RMCR_RNC, RMCR); -	sh_eth_write(ndev, DESC_I_RINT8 | DESC_I_RINT5 | DESC_I_TINT2, TRSCER); +	sh_eth_write(ndev, mdp->cd->trscer_err_mask, TRSCER);  	if (mdp->cd->bculr)  		sh_eth_write(ndev, 0x800, BCULR);	/* Burst sycle set */ diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h index 22301bf9c21d..71f5de1171bd 100644 --- a/drivers/net/ethernet/renesas/sh_eth.h +++ b/drivers/net/ethernet/renesas/sh_eth.h @@ -369,6 +369,8 @@ enum DESC_I_BIT {  	DESC_I_RINT1 = 0x0001,  }; +#define DEFAULT_TRSCER_ERR_MASK (DESC_I_RINT8 | DESC_I_RINT5 | DESC_I_TINT2) +  /* RPADIR */  enum RPADIR_BIT {  	RPADIR_PADS1 = 0x20000, RPADIR_PADS0 = 0x10000, @@ -470,6 +472,9 @@ struct sh_eth_cpu_data {  	unsigned long tx_check;  	unsigned long eesr_err_check; +	/* Error mask */ +	unsigned long trscer_err_mask; +  	/* hardware features */  	unsigned long irq_flags; /* IRQ configuration flags */  	unsigned no_psr:1;	/* EtherC DO NOT have PSR */ diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index c560f9aeb55d..64d1cef4cda1 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -610,7 +610,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable)  			/* Clear all mcast from ALE */  			cpsw_ale_flush_multicast(ale, ALE_ALL_PORTS << -						 priv->host_port); +						 priv->host_port, -1);  			/* Flood All Unicast Packets to Host port */  			cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 1); @@ -634,6 +634,12 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable)  static void cpsw_ndo_set_rx_mode(struct net_device *ndev)  {  	struct cpsw_priv *priv = netdev_priv(ndev); +	int vid; + +	if (priv->data.dual_emac) +		vid = priv->slaves[priv->emac_port].port_vlan; +	else +		vid = priv->data.default_vlan;  	if (ndev->flags & IFF_PROMISC) {  		/* Enable promiscuous mode */ @@ -649,7 +655,8 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev)  	cpsw_ale_set_allmulti(priv->ale, priv->ndev->flags & IFF_ALLMULTI);  	/* Clear all mcast from ALE */ -	cpsw_ale_flush_multicast(priv->ale, ALE_ALL_PORTS << priv->host_port); +	cpsw_ale_flush_multicast(priv->ale, ALE_ALL_PORTS << priv->host_port, +				 vid);  	if (!netdev_mc_empty(ndev)) {  		struct netdev_hw_addr *ha; @@ -757,6 +764,14 @@ requeue:  static irqreturn_t cpsw_interrupt(int irq, void *dev_id)  {  	struct cpsw_priv *priv = dev_id; +	int value = irq - priv->irqs_table[0]; + +	/* NOTICE: Ending IRQ here. The trick with the 'value' variable above +	 * is to make sure we will always write the correct value to the EOI +	 * register. Namely 0 for RX_THRESH Interrupt, 1 for RX Interrupt, 2 +	 * for TX Interrupt and 3 for MISC Interrupt. +	 */ +	cpdma_ctlr_eoi(priv->dma, value);  	cpsw_intr_disable(priv);  	if (priv->irq_enabled == true) { @@ -786,8 +801,6 @@ static int cpsw_poll(struct napi_struct *napi, int budget)  	int			num_tx, num_rx;  	num_tx = cpdma_chan_process(priv->txch, 128); -	if (num_tx) -		cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);  	num_rx = cpdma_chan_process(priv->rxch, budget);  	if (num_rx < budget) { @@ -795,7 +808,6 @@ static int cpsw_poll(struct napi_struct *napi, int budget)  		napi_complete(napi);  		cpsw_intr_enable(priv); -		cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);  		prim_cpsw = cpsw_get_slave_priv(priv, 0);  		if (prim_cpsw->irq_enabled == false) {  			prim_cpsw->irq_enabled = true; @@ -1310,8 +1322,6 @@ static int cpsw_ndo_open(struct net_device *ndev)  	napi_enable(&priv->napi);  	cpdma_ctlr_start(priv->dma);  	cpsw_intr_enable(priv); -	cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); -	cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);  	prim_cpsw = cpsw_get_slave_priv(priv, 0);  	if (prim_cpsw->irq_enabled == false) { @@ -1578,9 +1588,6 @@ static void cpsw_ndo_tx_timeout(struct net_device *ndev)  	cpdma_chan_start(priv->txch);  	cpdma_ctlr_int_ctrl(priv->dma, true);  	cpsw_intr_enable(priv); -	cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); -	cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX); -  }  static int cpsw_ndo_set_mac_address(struct net_device *ndev, void *p) @@ -1620,9 +1627,6 @@ static void cpsw_ndo_poll_controller(struct net_device *ndev)  	cpsw_interrupt(ndev->irq, priv);  	cpdma_ctlr_int_ctrl(priv->dma, true);  	cpsw_intr_enable(priv); -	cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); -	cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX); -  }  #endif diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c index 097ebe7077ac..5246b3a18ff8 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.c +++ b/drivers/net/ethernet/ti/cpsw_ale.c @@ -234,7 +234,7 @@ static void cpsw_ale_flush_mcast(struct cpsw_ale *ale, u32 *ale_entry,  		cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);  } -int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask) +int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid)  {  	u32 ale_entry[ALE_ENTRY_WORDS];  	int ret, idx; @@ -245,6 +245,14 @@ int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask)  		if (ret != ALE_TYPE_ADDR && ret != ALE_TYPE_VLAN_ADDR)  			continue; +		/* if vid passed is -1 then remove all multicast entry from +		 * the table irrespective of vlan id, if a valid vlan id is +		 * passed then remove only multicast added to that vlan id. +		 * if vlan id doesn't match then move on to next entry. +		 */ +		if (vid != -1 && cpsw_ale_get_vlan_id(ale_entry) != vid) +			continue; +  		if (cpsw_ale_get_mcast(ale_entry)) {  			u8 addr[6]; diff --git a/drivers/net/ethernet/ti/cpsw_ale.h b/drivers/net/ethernet/ti/cpsw_ale.h index c0d4127aa549..af1e7ecd87c6 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.h +++ b/drivers/net/ethernet/ti/cpsw_ale.h @@ -92,7 +92,7 @@ void cpsw_ale_stop(struct cpsw_ale *ale);  int cpsw_ale_set_ageout(struct cpsw_ale *ale, int ageout);  int cpsw_ale_flush(struct cpsw_ale *ale, int port_mask); -int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask); +int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid);  int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port,  		       int flags, u16 vid);  int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port, diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index 9c2d91ea0af4..dbcbf0c5bcfa 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c @@ -1043,6 +1043,7 @@ static int temac_of_probe(struct platform_device *op)  	lp->regs = of_iomap(op->dev.of_node, 0);  	if (!lp->regs) {  		dev_err(&op->dev, "could not map temac regs.\n"); +		rc = -ENOMEM;  		goto nodev;  	} @@ -1062,6 +1063,7 @@ static int temac_of_probe(struct platform_device *op)  	np = of_parse_phandle(op->dev.of_node, "llink-connected", 0);  	if (!np) {  		dev_err(&op->dev, "could not find DMA node\n"); +		rc = -ENODEV;  		goto err_iounmap;  	} diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index c18a0c637c44..a6d2860b712c 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -1501,6 +1501,7 @@ static int axienet_of_probe(struct platform_device *op)  	lp->regs = of_iomap(op->dev.of_node, 0);  	if (!lp->regs) {  		dev_err(&op->dev, "could not map Axi Ethernet regs.\n"); +		ret = -ENOMEM;  		goto nodev;  	}  	/* Setup checksum offload, but default to off if not specified */ @@ -1563,6 +1564,7 @@ static int axienet_of_probe(struct platform_device *op)  	np = of_parse_phandle(op->dev.of_node, "axistream-connected", 0);  	if (!np) {  		dev_err(&op->dev, "could not find DMA node\n"); +		ret = -ENODEV;  		goto err_iounmap;  	}  	lp->dma_regs = of_iomap(np, 0); diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c index 24858799c204..9d4ce388510a 100644 --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c @@ -1109,6 +1109,7 @@ static int xemaclite_of_probe(struct platform_device *ofdev)  	res = platform_get_resource(ofdev, IORESOURCE_IRQ, 0);  	if (!res) {  		dev_err(dev, "no IRQ found\n"); +		rc = -ENXIO;  		goto error;  	} diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 93e224217e24..f7ff493f1e73 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -629,6 +629,7 @@ static int team_change_mode(struct team *team, const char *kind)  static void team_notify_peers_work(struct work_struct *work)  {  	struct team *team; +	int val;  	team = container_of(work, struct team, notify_peers.dw.work); @@ -636,9 +637,14 @@ static void team_notify_peers_work(struct work_struct *work)  		schedule_delayed_work(&team->notify_peers.dw, 0);  		return;  	} +	val = atomic_dec_if_positive(&team->notify_peers.count_pending); +	if (val < 0) { +		rtnl_unlock(); +		return; +	}  	call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, team->dev);  	rtnl_unlock(); -	if (!atomic_dec_and_test(&team->notify_peers.count_pending)) +	if (val)  		schedule_delayed_work(&team->notify_peers.dw,  				      msecs_to_jiffies(team->notify_peers.interval));  } @@ -669,6 +675,7 @@ static void team_notify_peers_fini(struct team *team)  static void team_mcast_rejoin_work(struct work_struct *work)  {  	struct team *team; +	int val;  	team = container_of(work, struct team, mcast_rejoin.dw.work); @@ -676,9 +683,14 @@ static void team_mcast_rejoin_work(struct work_struct *work)  		schedule_delayed_work(&team->mcast_rejoin.dw, 0);  		return;  	} +	val = atomic_dec_if_positive(&team->mcast_rejoin.count_pending); +	if (val < 0) { +		rtnl_unlock(); +		return; +	}  	call_netdevice_notifiers(NETDEV_RESEND_IGMP, team->dev);  	rtnl_unlock(); -	if (!atomic_dec_and_test(&team->mcast_rejoin.count_pending)) +	if (val)  		schedule_delayed_work(&team->mcast_rejoin.dw,  				      msecs_to_jiffies(team->mcast_rejoin.interval));  } diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index dcb6d33141e0..1e9cdca37014 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c @@ -1276,7 +1276,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length)          awd.done = 0;          urb->context = &awd; -        status = usb_submit_urb(urb, GFP_NOIO); +        status = usb_submit_urb(urb, GFP_ATOMIC);          if (status) {                  // something went wrong                  usb_free_urb(urb); diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index b8a82b86f909..602dc6668c3a 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -56,6 +56,8 @@ struct qmi_wwan_state {  /* default ethernet address used by the modem */  static const u8 default_modem_addr[ETH_ALEN] = {0x02, 0x50, 0xf3}; +static const u8 buggy_fw_addr[ETH_ALEN] = {0x00, 0xa0, 0xc6, 0x00, 0x00, 0x00}; +  /* Make up an ethernet header if the packet doesn't have one.   *   * A firmware bug common among several devices cause them to send raw @@ -332,10 +334,12 @@ next_desc:  		usb_driver_release_interface(driver, info->data);  	} -	/* Never use the same address on both ends of the link, even -	 * if the buggy firmware told us to. +	/* Never use the same address on both ends of the link, even if the +	 * buggy firmware told us to. Or, if device is assigned the well-known +	 * buggy firmware MAC address, replace it with a random address,  	 */ -	if (ether_addr_equal(dev->net->dev_addr, default_modem_addr)) +	if (ether_addr_equal(dev->net->dev_addr, default_modem_addr) || +	    ether_addr_equal(dev->net->dev_addr, buggy_fw_addr))  		eth_hw_addr_random(dev->net);  	/* make MAC addr easily distinguishable from an IP header */ diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 2d1c77e81836..57ec23e8ccfa 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -1897,6 +1897,22 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev)  	netif_wake_queue(netdev);  } +static netdev_features_t +rtl8152_features_check(struct sk_buff *skb, struct net_device *dev, +		       netdev_features_t features) +{ +	u32 mss = skb_shinfo(skb)->gso_size; +	int max_offset = mss ? GTTCPHO_MAX : TCPHO_MAX; +	int offset = skb_transport_offset(skb); + +	if ((mss || skb->ip_summed == CHECKSUM_PARTIAL) && offset > max_offset) +		features &= ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK); +	else if ((skb->len + sizeof(struct tx_desc)) > agg_buf_sz) +		features &= ~NETIF_F_GSO_MASK; + +	return features; +} +  static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb,  				      struct net_device *netdev)  { @@ -3706,6 +3722,7 @@ static const struct net_device_ops rtl8152_netdev_ops = {  	.ndo_set_mac_address	= rtl8152_set_mac_address,  	.ndo_change_mtu		= rtl8152_change_mtu,  	.ndo_validate_addr	= eth_validate_addr, +	.ndo_features_check	= rtl8152_features_check,  };  static void r8152b_get_version(struct r8152 *tp) diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c index e5be2d21868f..a5f9198d5747 100644 --- a/drivers/net/wireless/iwlwifi/iwl-7000.c +++ b/drivers/net/wireless/iwlwifi/iwl-7000.c @@ -69,8 +69,8 @@  #include "iwl-agn-hw.h"  /* Highest firmware API version supported */ -#define IWL7260_UCODE_API_MAX	10 -#define IWL3160_UCODE_API_MAX	10 +#define IWL7260_UCODE_API_MAX	12 +#define IWL3160_UCODE_API_MAX	12  /* Oldest version we won't warn about */  #define IWL7260_UCODE_API_OK	10 @@ -105,7 +105,7 @@  #define IWL7265_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode"  #define IWL7265D_FW_PRE "iwlwifi-7265D-" -#define IWL7265D_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode" +#define IWL7265D_MODULE_FIRMWARE(api) IWL7265D_FW_PRE __stringify(api) ".ucode"  #define NVM_HW_SECTION_NUM_FAMILY_7000		0 diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c index bf0a95cb7153..3668fc57e770 100644 --- a/drivers/net/wireless/iwlwifi/iwl-8000.c +++ b/drivers/net/wireless/iwlwifi/iwl-8000.c @@ -69,7 +69,7 @@  #include "iwl-agn-hw.h"  /* Highest firmware API version supported */ -#define IWL8000_UCODE_API_MAX	10 +#define IWL8000_UCODE_API_MAX	12  /* Oldest version we won't warn about */  #define IWL8000_UCODE_API_OK	10 diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index f2a047f6bb3e..1bbe4fc47b97 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h @@ -243,6 +243,9 @@ enum iwl_ucode_tlv_flag {   * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif.   * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time   *	longer than the passive one, which is essential for fragmented scan. + * @IWL_UCODE_TLV_API_BASIC_DWELL: use only basic dwell time in scan command, + *	regardless of the band or the number of the probes. FW will calculate + *	the actual dwell time.   */  enum iwl_ucode_tlv_api {  	IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID	= BIT(0), @@ -253,6 +256,7 @@ enum iwl_ucode_tlv_api {  	IWL_UCODE_TLV_API_LMAC_SCAN		= BIT(6),  	IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF	= BIT(7),  	IWL_UCODE_TLV_API_FRAGMENTED_SCAN	= BIT(8), +	IWL_UCODE_TLV_API_BASIC_DWELL		= BIT(13),  };  /** diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index 1f2acf47bfb2..201846de94e7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h @@ -672,6 +672,7 @@ struct iwl_scan_channel_opt {   * @IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED: all passive scans will be fragmented   * @IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED: insert WFA vendor-specific TPC report   *	and DS parameter set IEs into probe requests. + * @IWL_MVM_LMAC_SCAN_FLAG_MATCH: Send match found notification on matches   */  enum iwl_mvm_lmac_scan_flags {  	IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL		= BIT(0), @@ -681,6 +682,7 @@ enum iwl_mvm_lmac_scan_flags {  	IWL_MVM_LMAC_SCAN_FLAG_MULTIPLE_SSIDS	= BIT(4),  	IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED	= BIT(5),  	IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED	= BIT(6), +	IWL_MVM_LMAC_SCAN_FLAG_MATCH		= BIT(9),  };  enum iwl_scan_priority { diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index e5294d01181e..ec9a8e7bae1d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c @@ -171,15 +171,21 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_ssid_ie *cmd_ssid,   * already included in the probe template, so we need to set only   * req->n_ssids - 1 bits in addition to the first bit.   */ -static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) +static u16 iwl_mvm_get_active_dwell(struct iwl_mvm *mvm, +				    enum ieee80211_band band, int n_ssids)  { +	if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BASIC_DWELL) +		return 10;  	if (band == IEEE80211_BAND_2GHZ)  		return 20  + 3 * (n_ssids + 1);  	return 10  + 2 * (n_ssids + 1);  } -static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band) +static u16 iwl_mvm_get_passive_dwell(struct iwl_mvm *mvm, +				     enum ieee80211_band band)  { +	if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BASIC_DWELL) +			return 110;  	return band == IEEE80211_BAND_2GHZ ? 100 + 20 : 100 + 10;  } @@ -331,7 +337,8 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,  		 */  		if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {  			u32 passive_dwell = -				iwl_mvm_get_passive_dwell(IEEE80211_BAND_2GHZ); +				iwl_mvm_get_passive_dwell(mvm, +							  IEEE80211_BAND_2GHZ);  			params->max_out_time = passive_dwell;  		} else {  			params->passive_fragmented = true; @@ -348,8 +355,8 @@ not_bound:  			params->dwell[band].passive = frag_passive_dwell;  		else  			params->dwell[band].passive = -				iwl_mvm_get_passive_dwell(band); -		params->dwell[band].active = iwl_mvm_get_active_dwell(band, +				iwl_mvm_get_passive_dwell(mvm, band); +		params->dwell[band].active = iwl_mvm_get_active_dwell(mvm, band,  								      n_ssids);  	}  } @@ -1448,6 +1455,8 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,  	if (iwl_mvm_scan_pass_all(mvm, req))  		flags |= IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL; +	else +		flags |= IWL_MVM_LMAC_SCAN_FLAG_MATCH;  	if (req->n_ssids == 1 && req->ssids[0].ssid_len != 0)  		flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION; diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 4f15d9decc81..4333306ccdee 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c @@ -108,8 +108,12 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,  			tx_flags &= ~TX_CMD_FLG_SEQ_CTL;  	} -	/* tid_tspec will default to 0 = BE when QOS isn't enabled */ -	ac = tid_to_mac80211_ac[tx_cmd->tid_tspec]; +	/* Default to 0 (BE) when tid_spec is set to IWL_TID_NON_QOS */ +	if (tx_cmd->tid_tspec < IWL_MAX_TID_COUNT) +		ac = tid_to_mac80211_ac[tx_cmd->tid_tspec]; +	else +		ac = tid_to_mac80211_ac[0]; +  	tx_flags |= iwl_mvm_bt_coex_tx_prio(mvm, hdr, info, ac) <<  			TX_CMD_FLG_BT_PRIO_POS; diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index e56e77ef5d2e..917431e30f74 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c @@ -665,7 +665,7 @@ bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm *mvm)  	if (num_of_ant(mvm->fw->valid_rx_ant) == 1)  		return false; -	if (!mvm->cfg->rx_with_siso_diversity) +	if (mvm->cfg->rx_with_siso_diversity)  		return false;  	ieee80211_iterate_active_interfaces_atomic( diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 2f0c4b170344..d5aadb00dd9e 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c @@ -527,8 +527,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  	else if (cfg == &iwl7265_n_cfg)  		cfg_7265d = &iwl7265d_n_cfg;  	if (cfg_7265d && -	    (iwl_trans->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D) +	    (iwl_trans->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D) {  		cfg = cfg_7265d; +		iwl_trans->cfg = cfg_7265d; +	}  #endif  	pci_set_drvdata(pdev, iwl_trans); diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 846a2e6e34d8..c70efb9a6e78 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -666,7 +666,8 @@ tx_status_ok:  }  static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw, -				    u8 *entry, int rxring_idx, int desc_idx) +				    struct sk_buff *new_skb, u8 *entry, +				    int rxring_idx, int desc_idx)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); @@ -674,11 +675,15 @@ static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw,  	u8 tmp_one = 1;  	struct sk_buff *skb; +	if (likely(new_skb)) { +		skb = new_skb; +		goto remap; +	}  	skb = dev_alloc_skb(rtlpci->rxbuffersize);  	if (!skb)  		return 0; -	rtlpci->rx_ring[rxring_idx].rx_buf[desc_idx] = skb; +remap:  	/* just set skb->cb to mapping addr for pci_unmap_single use */  	*((dma_addr_t *)skb->cb) =  		pci_map_single(rtlpci->pdev, skb_tail_pointer(skb), @@ -686,6 +691,7 @@ static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw,  	bufferaddress = *((dma_addr_t *)skb->cb);  	if (pci_dma_mapping_error(rtlpci->pdev, bufferaddress))  		return 0; +	rtlpci->rx_ring[rxring_idx].rx_buf[desc_idx] = skb;  	if (rtlpriv->use_new_trx_flow) {  		rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,  					    HW_DESC_RX_PREPARE, @@ -781,6 +787,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)  		/*rx pkt */  		struct sk_buff *skb = rtlpci->rx_ring[rxring_idx].rx_buf[  				      rtlpci->rx_ring[rxring_idx].idx]; +		struct sk_buff *new_skb;  		if (rtlpriv->use_new_trx_flow) {  			rx_remained_cnt = @@ -807,6 +814,13 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)  		pci_unmap_single(rtlpci->pdev, *((dma_addr_t *)skb->cb),  				 rtlpci->rxbuffersize, PCI_DMA_FROMDEVICE); +		/* get a new skb - if fail, old one will be reused */ +		new_skb = dev_alloc_skb(rtlpci->rxbuffersize); +		if (unlikely(!new_skb)) { +			pr_err("Allocation of new skb failed in %s\n", +			       __func__); +			goto no_new; +		}  		if (rtlpriv->use_new_trx_flow) {  			buffer_desc =  			  &rtlpci->rx_ring[rxring_idx].buffer_desc @@ -911,14 +925,16 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)  			schedule_work(&rtlpriv->works.lps_change_work);  		}  end: +		skb = new_skb; +no_new:  		if (rtlpriv->use_new_trx_flow) { -			_rtl_pci_init_one_rxdesc(hw, (u8 *)buffer_desc, +			_rtl_pci_init_one_rxdesc(hw, skb, (u8 *)buffer_desc,  						 rxring_idx, -					       rtlpci->rx_ring[rxring_idx].idx); +						 rtlpci->rx_ring[rxring_idx].idx);  		} else { -			_rtl_pci_init_one_rxdesc(hw, (u8 *)pdesc, rxring_idx, +			_rtl_pci_init_one_rxdesc(hw, skb, (u8 *)pdesc, +						 rxring_idx,  						 rtlpci->rx_ring[rxring_idx].idx); -  			if (rtlpci->rx_ring[rxring_idx].idx ==  			    rtlpci->rxringcount - 1)  				rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, @@ -1307,7 +1323,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw, int rxring_idx)  		rtlpci->rx_ring[rxring_idx].idx = 0;  		for (i = 0; i < rtlpci->rxringcount; i++) {  			entry = &rtlpci->rx_ring[rxring_idx].buffer_desc[i]; -			if (!_rtl_pci_init_one_rxdesc(hw, (u8 *)entry, +			if (!_rtl_pci_init_one_rxdesc(hw, NULL, (u8 *)entry,  						      rxring_idx, i))  				return -ENOMEM;  		} @@ -1332,7 +1348,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw, int rxring_idx)  		for (i = 0; i < rtlpci->rxringcount; i++) {  			entry = &rtlpci->rx_ring[rxring_idx].desc[i]; -			if (!_rtl_pci_init_one_rxdesc(hw, (u8 *)entry, +			if (!_rtl_pci_init_one_rxdesc(hw, NULL, (u8 *)entry,  						      rxring_idx, i))  				return -ENOMEM;  		} diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c index efbaf2ae1999..794204e34fba 100644 --- a/drivers/net/xen-netback/xenbus.c +++ b/drivers/net/xen-netback/xenbus.c @@ -737,6 +737,7 @@ static void connect(struct backend_info *be)  		}  		queue->remaining_credit = credit_bytes; +		queue->credit_usec = credit_usec;  		err = connect_rings(be, queue);  		if (err) { diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 22bcb4e12e2a..d8c10764f130 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -88,10 +88,8 @@ struct netfront_cb {  #define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3)  struct netfront_stats { -	u64			rx_packets; -	u64			tx_packets; -	u64			rx_bytes; -	u64			tx_bytes; +	u64			packets; +	u64			bytes;  	struct u64_stats_sync	syncp;  }; @@ -160,7 +158,8 @@ struct netfront_info {  	struct netfront_queue *queues;  	/* Statistics */ -	struct netfront_stats __percpu *stats; +	struct netfront_stats __percpu *rx_stats; +	struct netfront_stats __percpu *tx_stats;  	atomic_t rx_gso_checksum_fixup;  }; @@ -565,7 +564,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)  {  	unsigned short id;  	struct netfront_info *np = netdev_priv(dev); -	struct netfront_stats *stats = this_cpu_ptr(np->stats); +	struct netfront_stats *tx_stats = this_cpu_ptr(np->tx_stats);  	struct xen_netif_tx_request *tx;  	char *data = skb->data;  	RING_IDX i; @@ -672,10 +671,10 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)  	if (notify)  		notify_remote_via_irq(queue->tx_irq); -	u64_stats_update_begin(&stats->syncp); -	stats->tx_bytes += skb->len; -	stats->tx_packets++; -	u64_stats_update_end(&stats->syncp); +	u64_stats_update_begin(&tx_stats->syncp); +	tx_stats->bytes += skb->len; +	tx_stats->packets++; +	u64_stats_update_end(&tx_stats->syncp);  	/* Note: It is not safe to access skb after xennet_tx_buf_gc()! */  	xennet_tx_buf_gc(queue); @@ -931,7 +930,7 @@ static int checksum_setup(struct net_device *dev, struct sk_buff *skb)  static int handle_incoming_queue(struct netfront_queue *queue,  				 struct sk_buff_head *rxq)  { -	struct netfront_stats *stats = this_cpu_ptr(queue->info->stats); +	struct netfront_stats *rx_stats = this_cpu_ptr(queue->info->rx_stats);  	int packets_dropped = 0;  	struct sk_buff *skb; @@ -952,10 +951,10 @@ static int handle_incoming_queue(struct netfront_queue *queue,  			continue;  		} -		u64_stats_update_begin(&stats->syncp); -		stats->rx_packets++; -		stats->rx_bytes += skb->len; -		u64_stats_update_end(&stats->syncp); +		u64_stats_update_begin(&rx_stats->syncp); +		rx_stats->packets++; +		rx_stats->bytes += skb->len; +		u64_stats_update_end(&rx_stats->syncp);  		/* Pass it up. */  		napi_gro_receive(&queue->napi, skb); @@ -1079,18 +1078,22 @@ static struct rtnl_link_stats64 *xennet_get_stats64(struct net_device *dev,  	int cpu;  	for_each_possible_cpu(cpu) { -		struct netfront_stats *stats = per_cpu_ptr(np->stats, cpu); +		struct netfront_stats *rx_stats = per_cpu_ptr(np->rx_stats, cpu); +		struct netfront_stats *tx_stats = per_cpu_ptr(np->tx_stats, cpu);  		u64 rx_packets, rx_bytes, tx_packets, tx_bytes;  		unsigned int start;  		do { -			start = u64_stats_fetch_begin_irq(&stats->syncp); +			start = u64_stats_fetch_begin_irq(&tx_stats->syncp); +			tx_packets = tx_stats->packets; +			tx_bytes = tx_stats->bytes; +		} while (u64_stats_fetch_retry_irq(&tx_stats->syncp, start)); -			rx_packets = stats->rx_packets; -			tx_packets = stats->tx_packets; -			rx_bytes = stats->rx_bytes; -			tx_bytes = stats->tx_bytes; -		} while (u64_stats_fetch_retry_irq(&stats->syncp, start)); +		do { +			start = u64_stats_fetch_begin_irq(&rx_stats->syncp); +			rx_packets = rx_stats->packets; +			rx_bytes = rx_stats->bytes; +		} while (u64_stats_fetch_retry_irq(&rx_stats->syncp, start));  		tot->rx_packets += rx_packets;  		tot->tx_packets += tx_packets; @@ -1275,6 +1278,15 @@ static const struct net_device_ops xennet_netdev_ops = {  #endif  }; +static void xennet_free_netdev(struct net_device *netdev) +{ +	struct netfront_info *np = netdev_priv(netdev); + +	free_percpu(np->rx_stats); +	free_percpu(np->tx_stats); +	free_netdev(netdev); +} +  static struct net_device *xennet_create_dev(struct xenbus_device *dev)  {  	int err; @@ -1295,8 +1307,11 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)  	np->queues = NULL;  	err = -ENOMEM; -	np->stats = netdev_alloc_pcpu_stats(struct netfront_stats); -	if (np->stats == NULL) +	np->rx_stats = netdev_alloc_pcpu_stats(struct netfront_stats); +	if (np->rx_stats == NULL) +		goto exit; +	np->tx_stats = netdev_alloc_pcpu_stats(struct netfront_stats); +	if (np->tx_stats == NULL)  		goto exit;  	netdev->netdev_ops	= &xennet_netdev_ops; @@ -1327,7 +1342,7 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)  	return netdev;   exit: -	free_netdev(netdev); +	xennet_free_netdev(netdev);  	return ERR_PTR(err);  } @@ -1369,7 +1384,7 @@ static int netfront_probe(struct xenbus_device *dev,  	return 0;   fail: -	free_netdev(netdev); +	xennet_free_netdev(netdev);  	dev_set_drvdata(&dev->dev, NULL);  	return err;  } @@ -2189,9 +2204,7 @@ static int xennet_remove(struct xenbus_device *dev)  		info->queues = NULL;  	} -	free_percpu(info->stats); - -	free_netdev(info->netdev); +	xennet_free_netdev(info->netdev);  	return 0;  } diff --git a/drivers/phy/phy-miphy28lp.c b/drivers/phy/phy-miphy28lp.c index e34da13885e8..27fa62ce6136 100644 --- a/drivers/phy/phy-miphy28lp.c +++ b/drivers/phy/phy-miphy28lp.c @@ -1050,7 +1050,8 @@ static int miphy28lp_init(struct phy *phy)  		ret = miphy28lp_init_usb3(miphy_phy);  		break;  	default: -		return -EINVAL; +		ret = -EINVAL; +		break;  	}  	mutex_unlock(&miphy_dev->miphy_mutex); diff --git a/drivers/phy/phy-omap-control.c b/drivers/phy/phy-omap-control.c index c96e8183a8ff..efe724f97e02 100644 --- a/drivers/phy/phy-omap-control.c +++ b/drivers/phy/phy-omap-control.c @@ -29,10 +29,9 @@  /**   * omap_control_pcie_pcs - set the PCS delay count   * @dev: the control module device - * @id: index of the pcie PHY (should be 1 or 2)   * @delay: 8 bit delay value   */ -void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay) +void omap_control_pcie_pcs(struct device *dev, u8 delay)  {  	u32 val;  	struct omap_control_phy	*control_phy; @@ -55,8 +54,8 @@ void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay)  	val = readl(control_phy->pcie_pcs);  	val &= ~(OMAP_CTRL_PCIE_PCS_MASK << -		(id * OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT)); -	val |= delay << (id * OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT); +		OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT); +	val |= (delay << OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT);  	writel(val, control_phy->pcie_pcs);  }  EXPORT_SYMBOL_GPL(omap_control_pcie_pcs); diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c index fb02a67c9181..a2b08f3ccb03 100644 --- a/drivers/phy/phy-sun4i-usb.c +++ b/drivers/phy/phy-sun4i-usb.c @@ -244,7 +244,8 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)  	else  		data->num_phys = 3; -	if (of_device_is_compatible(np, "allwinner,sun4i-a10-usb-phy")) +	if (of_device_is_compatible(np, "allwinner,sun4i-a10-usb-phy") || +	    of_device_is_compatible(np, "allwinner,sun6i-a31-usb-phy"))  		data->disc_thresh = 3;  	else  		data->disc_thresh = 2; diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c index 1387b4d4afe3..465de2c800f2 100644 --- a/drivers/phy/phy-ti-pipe3.c +++ b/drivers/phy/phy-ti-pipe3.c @@ -82,7 +82,6 @@ struct ti_pipe3 {  	struct clk		*refclk;  	struct clk		*div_clk;  	struct pipe3_dpll_map	*dpll_map; -	u8			id;  };  static struct pipe3_dpll_map dpll_map_usb[] = { @@ -217,8 +216,13 @@ static int ti_pipe3_init(struct phy *x)  	u32 val;  	int ret = 0; +	/* +	 * Set pcie_pcs register to 0x96 for proper functioning of phy +	 * as recommended in AM572x TRM SPRUHZ6, section 18.5.2.2, table +	 * 18-1804. +	 */  	if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) { -		omap_control_pcie_pcs(phy->control_dev, phy->id, 0xF1); +		omap_control_pcie_pcs(phy->control_dev, 0x96);  		return 0;  	} @@ -347,8 +351,6 @@ static int ti_pipe3_probe(struct platform_device *pdev)  	}  	if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { -		if (of_property_read_u8(node, "id", &phy->id) < 0) -			phy->id = 1;  		clk = devm_clk_get(phy->dev, "dpll_ref");  		if (IS_ERR(clk)) { diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index ba74f0aa60c7..3c22dbebc80f 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -89,6 +89,7 @@ struct rockchip_iomux {   * @reg_pull: optional separate register for additional pull settings   * @clk: clock of the gpio bank   * @irq: interrupt of the gpio bank + * @saved_enables: Saved content of GPIO_INTEN at suspend time.   * @pin_base: first pin number   * @nr_pins: number of pins in this bank   * @name: name of the bank @@ -107,6 +108,7 @@ struct rockchip_pin_bank {  	struct regmap			*regmap_pull;  	struct clk			*clk;  	int				irq; +	u32				saved_enables;  	u32				pin_base;  	u8				nr_pins;  	char				*name; @@ -1543,6 +1545,51 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)  	return 0;  } +static void rockchip_irq_suspend(struct irq_data *d) +{ +	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); +	struct rockchip_pin_bank *bank = gc->private; + +	bank->saved_enables = irq_reg_readl(gc, GPIO_INTEN); +	irq_reg_writel(gc, gc->wake_active, GPIO_INTEN); +} + +static void rockchip_irq_resume(struct irq_data *d) +{ +	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); +	struct rockchip_pin_bank *bank = gc->private; + +	irq_reg_writel(gc, bank->saved_enables, GPIO_INTEN); +} + +static void rockchip_irq_disable(struct irq_data *d) +{ +	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); +	u32 val; + +	irq_gc_lock(gc); + +	val = irq_reg_readl(gc, GPIO_INTEN); +	val &= ~d->mask; +	irq_reg_writel(gc, val, GPIO_INTEN); + +	irq_gc_unlock(gc); +} + +static void rockchip_irq_enable(struct irq_data *d) +{ +	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); +	u32 val; + +	irq_gc_lock(gc); + +	val = irq_reg_readl(gc, GPIO_INTEN); +	val |= d->mask; +	irq_reg_writel(gc, val, GPIO_INTEN); + +	irq_gc_unlock(gc); +} +  static int rockchip_interrupts_register(struct platform_device *pdev,  						struct rockchip_pinctrl *info)  { @@ -1581,12 +1628,16 @@ static int rockchip_interrupts_register(struct platform_device *pdev,  		gc = irq_get_domain_generic_chip(bank->domain, 0);  		gc->reg_base = bank->reg_base;  		gc->private = bank; -		gc->chip_types[0].regs.mask = GPIO_INTEN; +		gc->chip_types[0].regs.mask = GPIO_INTMASK;  		gc->chip_types[0].regs.ack = GPIO_PORTS_EOI;  		gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit; -		gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; -		gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; +		gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit; +		gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit; +		gc->chip_types[0].chip.irq_enable = rockchip_irq_enable; +		gc->chip_types[0].chip.irq_disable = rockchip_irq_disable;  		gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; +		gc->chip_types[0].chip.irq_suspend = rockchip_irq_suspend; +		gc->chip_types[0].chip.irq_resume = rockchip_irq_resume;  		gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type;  		gc->wake_enabled = IRQ_MSK(bank->nr_pins); diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c index 7c9d51382248..9e5ec00084bb 100644 --- a/drivers/pinctrl/pinctrl-st.c +++ b/drivers/pinctrl/pinctrl-st.c @@ -1012,8 +1012,10 @@ static void st_pinconf_dbg_show(struct pinctrl_dev *pctldev,  				   struct seq_file *s, unsigned pin_id)  {  	unsigned long config; -	st_pinconf_get(pctldev, pin_id, &config); +	mutex_unlock(&pctldev->mutex); +	st_pinconf_get(pctldev, pin_id, &config); +	mutex_lock(&pctldev->mutex);  	seq_printf(s, "[OE:%ld,PU:%ld,OD:%ld]\n"  		"\t\t[retime:%ld,invclk:%ld,clknotdat:%ld,"  		"de:%ld,rt-clk:%ld,rt-delay:%ld]", @@ -1443,6 +1445,7 @@ static struct gpio_chip st_gpio_template = {  static struct irq_chip st_gpio_irqchip = {  	.name		= "GPIO", +	.irq_disable	= st_gpio_irq_mask,  	.irq_mask	= st_gpio_irq_mask,  	.irq_unmask	= st_gpio_irq_unmask,  	.irq_set_type	= st_gpio_irq_set_type, diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 91e97ec01418..4d41bf75c233 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -1163,9 +1163,13 @@ static inline int ap_test_config_card_id(unsigned int id)   */  static inline int ap_test_config_domain(unsigned int domain)  { -	if (!ap_configuration) -		return 1; -	return ap_test_config(ap_configuration->aqm, domain); +	if (!ap_configuration)	  /* QCI not supported */ +		if (domain < 16) +			return 1; /* then domains 0...15 are configured */ +		else +			return 0; +	else +		return ap_test_config(ap_configuration->aqm, domain);  }  /** diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index 86c72ba0a0cd..f8c5fc371c4c 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -2177,7 +2177,7 @@ bool BBbVT3253Init(struct vnt_private *priv)  		/* Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted) */  		/*bResult &= BBbWriteEmbedded(dwIoBase,0x0a,0x28);*/  		/* Select VC1/VC2, CR215 = 0x02->0x06 */ -		bResult &= BBbWriteEmbedded(dwIoBase, 0xd7, 0x06); +		bResult &= BBbWriteEmbedded(priv, 0xd7, 0x06);  		/* }} */  		for (ii = 0; ii < CB_VT3253B0_AGC; ii++) diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c index c8f739dd346e..70f870541f92 100644 --- a/drivers/staging/vt6655/channel.c +++ b/drivers/staging/vt6655/channel.c @@ -182,6 +182,14 @@ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel)  	if (pDevice->byCurrentCh == uConnectionChannel)  		return bResult; +	/* Set VGA to max sensitivity */ +	if (pDevice->bUpdateBBVGA && +	    pDevice->byBBVGACurrent != pDevice->abyBBVGA[0]) { +		pDevice->byBBVGACurrent = pDevice->abyBBVGA[0]; + +		BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent); +	} +  	/* clear NAV */  	MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MACCR, MACCR_CLRNAV); diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 83e4162c0094..cd1a277d853b 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -1232,7 +1232,7 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)  	head_td = priv->apCurrTD[dma_idx]; -	head_td->m_td1TD1.byTCR = (TCR_EDP|TCR_STP); +	head_td->m_td1TD1.byTCR = 0;  	head_td->pTDInfo->skb = skb; @@ -1257,6 +1257,11 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)  	priv->bPWBitOn = false; +	/* Set TSR1 & ReqCount in TxDescHead */ +	head_td->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); +	head_td->m_td1TD1.wReqCount = +			cpu_to_le16((u16)head_td->pTDInfo->dwReqCount); +  	head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB;  	if (dma_idx == TYPE_AC0DMA) @@ -1500,9 +1505,11 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw,  		if (conf->enable_beacon) {  			vnt_beacon_enable(priv, vif, conf); -			MACvRegBitsOn(priv, MAC_REG_TCR, TCR_AUTOBCNTX); +			MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, +				      TCR_AUTOBCNTX);  		} else { -			MACvRegBitsOff(priv, MAC_REG_TCR, TCR_AUTOBCNTX); +			MACvRegBitsOff(priv->PortOffset, MAC_REG_TCR, +				       TCR_AUTOBCNTX);  		}  	} diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 61c39dd7ad01..b5b0155961f2 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -1204,13 +1204,10 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,  	ptdCurr = (PSTxDesc)pHeadTD; -	ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; +	ptdCurr->pTDInfo->dwReqCount = cbReqCount;  	ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength;  	ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma;  	ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); -	/* Set TSR1 & ReqCount in TxDescHead */ -	ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); -	ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount));  	return cbHeaderLength;  } diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 55f6774f706f..aebde3289c50 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -2027,10 +2027,10 @@ iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,  		goto reject;  	}  	if (!strncmp("=All", text_ptr, 4)) { -		cmd->cmd_flags |= IFC_SENDTARGETS_ALL; +		cmd->cmd_flags |= ICF_SENDTARGETS_ALL;  	} else if (!strncmp("=iqn.", text_ptr, 5) ||  		   !strncmp("=eui.", text_ptr, 5)) { -		cmd->cmd_flags |= IFC_SENDTARGETS_SINGLE; +		cmd->cmd_flags |= ICF_SENDTARGETS_SINGLE;  	} else {  		pr_err("Unable to locate valid SendTargets=%s value\n", text_ptr);  		goto reject; @@ -3415,10 +3415,10 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd,  		return -ENOMEM;  	}  	/* -	 * Locate pointer to iqn./eui. string for IFC_SENDTARGETS_SINGLE +	 * Locate pointer to iqn./eui. string for ICF_SENDTARGETS_SINGLE  	 * explicit case..  	 */ -	if (cmd->cmd_flags & IFC_SENDTARGETS_SINGLE) { +	if (cmd->cmd_flags & ICF_SENDTARGETS_SINGLE) {  		text_ptr = strchr(text_in, '=');  		if (!text_ptr) {  			pr_err("Unable to locate '=' string in text_in:" @@ -3434,7 +3434,7 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd,  	spin_lock(&tiqn_lock);  	list_for_each_entry(tiqn, &g_tiqn_list, tiqn_list) { -		if ((cmd->cmd_flags & IFC_SENDTARGETS_SINGLE) && +		if ((cmd->cmd_flags & ICF_SENDTARGETS_SINGLE) &&  		     strcmp(tiqn->tiqn, text_ptr)) {  			continue;  		} @@ -3512,7 +3512,7 @@ eob:  		if (end_of_buf)  			break; -		if (cmd->cmd_flags & IFC_SENDTARGETS_SINGLE) +		if (cmd->cmd_flags & ICF_SENDTARGETS_SINGLE)  			break;  	}  	spin_unlock(&tiqn_lock); diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index 09a522bae222..cbcff38ac9b7 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h @@ -135,8 +135,8 @@ enum cmd_flags_table {  	ICF_CONTIG_MEMORY			= 0x00000020,  	ICF_ATTACHED_TO_RQUEUE			= 0x00000040,  	ICF_OOO_CMDSN				= 0x00000080, -	IFC_SENDTARGETS_ALL			= 0x00000100, -	IFC_SENDTARGETS_SINGLE			= 0x00000200, +	ICF_SENDTARGETS_ALL			= 0x00000100, +	ICF_SENDTARGETS_SINGLE			= 0x00000200,  };  /* struct iscsi_cmd->i_state */ diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 7653cfb027a2..58f49ff69b14 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -1103,51 +1103,6 @@ int se_dev_set_queue_depth(struct se_device *dev, u32 queue_depth)  }  EXPORT_SYMBOL(se_dev_set_queue_depth); -int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors) -{ -	int block_size = dev->dev_attrib.block_size; - -	if (dev->export_count) { -		pr_err("dev[%p]: Unable to change SE Device" -			" fabric_max_sectors while export_count is %d\n", -			dev, dev->export_count); -		return -EINVAL; -	} -	if (!fabric_max_sectors) { -		pr_err("dev[%p]: Illegal ZERO value for" -			" fabric_max_sectors\n", dev); -		return -EINVAL; -	} -	if (fabric_max_sectors < DA_STATUS_MAX_SECTORS_MIN) { -		pr_err("dev[%p]: Passed fabric_max_sectors: %u less than" -			" DA_STATUS_MAX_SECTORS_MIN: %u\n", dev, fabric_max_sectors, -				DA_STATUS_MAX_SECTORS_MIN); -		return -EINVAL; -	} -	if (fabric_max_sectors > DA_STATUS_MAX_SECTORS_MAX) { -		pr_err("dev[%p]: Passed fabric_max_sectors: %u" -			" greater than DA_STATUS_MAX_SECTORS_MAX:" -			" %u\n", dev, fabric_max_sectors, -			DA_STATUS_MAX_SECTORS_MAX); -		return -EINVAL; -	} -	/* -	 * Align max_sectors down to PAGE_SIZE to follow transport_allocate_data_tasks() -	 */ -	if (!block_size) { -		block_size = 512; -		pr_warn("Defaulting to 512 for zero block_size\n"); -	} -	fabric_max_sectors = se_dev_align_max_sectors(fabric_max_sectors, -						      block_size); - -	dev->dev_attrib.fabric_max_sectors = fabric_max_sectors; -	pr_debug("dev[%p]: SE Device max_sectors changed to %u\n", -			dev, fabric_max_sectors); -	return 0; -} -EXPORT_SYMBOL(se_dev_set_fabric_max_sectors); -  int se_dev_set_optimal_sectors(struct se_device *dev, u32 optimal_sectors)  {  	if (dev->export_count) { @@ -1156,10 +1111,10 @@ int se_dev_set_optimal_sectors(struct se_device *dev, u32 optimal_sectors)  			dev, dev->export_count);  		return -EINVAL;  	} -	if (optimal_sectors > dev->dev_attrib.fabric_max_sectors) { +	if (optimal_sectors > dev->dev_attrib.hw_max_sectors) {  		pr_err("dev[%p]: Passed optimal_sectors %u cannot be" -			" greater than fabric_max_sectors: %u\n", dev, -			optimal_sectors, dev->dev_attrib.fabric_max_sectors); +			" greater than hw_max_sectors: %u\n", dev, +			optimal_sectors, dev->dev_attrib.hw_max_sectors);  		return -EINVAL;  	} @@ -1553,8 +1508,6 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)  	dev->dev_attrib.unmap_granularity_alignment =  				DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT;  	dev->dev_attrib.max_write_same_len = DA_MAX_WRITE_SAME_LEN; -	dev->dev_attrib.fabric_max_sectors = DA_FABRIC_MAX_SECTORS; -	dev->dev_attrib.optimal_sectors = DA_FABRIC_MAX_SECTORS;  	xcopy_lun = &dev->xcopy_lun;  	xcopy_lun->lun_se_dev = dev; @@ -1595,6 +1548,7 @@ int target_configure_device(struct se_device *dev)  	dev->dev_attrib.hw_max_sectors =  		se_dev_align_max_sectors(dev->dev_attrib.hw_max_sectors,  					 dev->dev_attrib.hw_block_size); +	dev->dev_attrib.optimal_sectors = dev->dev_attrib.hw_max_sectors;  	dev->dev_index = scsi_get_new_index(SCSI_DEVICE_INDEX);  	dev->creation_time = get_jiffies_64(); diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index c2aea099ea4a..d836de200a03 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -621,7 +621,16 @@ fd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,  	struct fd_prot fd_prot;  	sense_reason_t rc;  	int ret = 0; - +	/* +	 * We are currently limited by the number of iovecs (2048) per +	 * single vfs_[writev,readv] call. +	 */ +	if (cmd->data_length > FD_MAX_BYTES) { +		pr_err("FILEIO: Not able to process I/O of %u bytes due to" +		       "FD_MAX_BYTES: %u iovec count limitiation\n", +			cmd->data_length, FD_MAX_BYTES); +		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; +	}  	/*  	 * Call vectorized fileio functions to map struct scatterlist  	 * physical memory addresses to struct iovec virtual memory. @@ -959,7 +968,6 @@ static struct configfs_attribute *fileio_backend_dev_attrs[] = {  	&fileio_dev_attrib_hw_block_size.attr,  	&fileio_dev_attrib_block_size.attr,  	&fileio_dev_attrib_hw_max_sectors.attr, -	&fileio_dev_attrib_fabric_max_sectors.attr,  	&fileio_dev_attrib_optimal_sectors.attr,  	&fileio_dev_attrib_hw_queue_depth.attr,  	&fileio_dev_attrib_queue_depth.attr, diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 3efff94fbd97..78346b850968 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -124,7 +124,7 @@ static int iblock_configure_device(struct se_device *dev)  	q = bdev_get_queue(bd);  	dev->dev_attrib.hw_block_size = bdev_logical_block_size(bd); -	dev->dev_attrib.hw_max_sectors = UINT_MAX; +	dev->dev_attrib.hw_max_sectors = queue_max_hw_sectors(q);  	dev->dev_attrib.hw_queue_depth = q->nr_requests;  	/* @@ -883,7 +883,6 @@ static struct configfs_attribute *iblock_backend_dev_attrs[] = {  	&iblock_dev_attrib_hw_block_size.attr,  	&iblock_dev_attrib_block_size.attr,  	&iblock_dev_attrib_hw_max_sectors.attr, -	&iblock_dev_attrib_fabric_max_sectors.attr,  	&iblock_dev_attrib_optimal_sectors.attr,  	&iblock_dev_attrib_hw_queue_depth.attr,  	&iblock_dev_attrib_queue_depth.attr, diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index d56f2aaba9af..283cf786ef98 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -528,6 +528,18 @@ static int core_scsi3_pr_seq_non_holder(  			return 0;  		} +       } else if (we && registered_nexus) { +               /* +                * Reads are allowed for Write Exclusive locks +                * from all registrants. +                */ +               if (cmd->data_direction == DMA_FROM_DEVICE) { +                       pr_debug("Allowing READ CDB: 0x%02x for %s" +                               " reservation\n", cdb[0], +                               core_scsi3_pr_dump_type(pr_reg_type)); + +                       return 0; +               }  	}  	pr_debug("%s Conflict for %sregistered nexus %s CDB: 0x%2x"  		" for %s reservation\n", transport_dump_cmd_direction(cmd), diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index 60ebd170a561..98e83ac5661b 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c @@ -657,7 +657,6 @@ static struct configfs_attribute *rd_mcp_backend_dev_attrs[] = {  	&rd_mcp_dev_attrib_hw_block_size.attr,  	&rd_mcp_dev_attrib_block_size.attr,  	&rd_mcp_dev_attrib_hw_max_sectors.attr, -	&rd_mcp_dev_attrib_fabric_max_sectors.attr,  	&rd_mcp_dev_attrib_optimal_sectors.attr,  	&rd_mcp_dev_attrib_hw_queue_depth.attr,  	&rd_mcp_dev_attrib_queue_depth.attr, diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 11bea1952435..cd4bed7b2757 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c @@ -953,21 +953,6 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)  	if (cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) {  		unsigned long long end_lba; - -		if (sectors > dev->dev_attrib.fabric_max_sectors) { -			printk_ratelimited(KERN_ERR "SCSI OP %02xh with too" -				" big sectors %u exceeds fabric_max_sectors:" -				" %u\n", cdb[0], sectors, -				dev->dev_attrib.fabric_max_sectors); -			return TCM_INVALID_CDB_FIELD; -		} -		if (sectors > dev->dev_attrib.hw_max_sectors) { -			printk_ratelimited(KERN_ERR "SCSI OP %02xh with too" -				" big sectors %u exceeds backend hw_max_sectors:" -				" %u\n", cdb[0], sectors, -				dev->dev_attrib.hw_max_sectors); -			return TCM_INVALID_CDB_FIELD; -		}  check_lba:  		end_lba = dev->transport->get_blocks(dev) + 1;  		if (cmd->t_task_lba + sectors > end_lba) { diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 1307600fe726..4c71657da56a 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c @@ -505,7 +505,6 @@ static sense_reason_t  spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf)  {  	struct se_device *dev = cmd->se_dev; -	u32 max_sectors;  	int have_tp = 0;  	int opt, min; @@ -539,9 +538,7 @@ spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf)  	/*  	 * Set MAXIMUM TRANSFER LENGTH  	 */ -	max_sectors = min(dev->dev_attrib.fabric_max_sectors, -			  dev->dev_attrib.hw_max_sectors); -	put_unaligned_be32(max_sectors, &buf[8]); +	put_unaligned_be32(dev->dev_attrib.hw_max_sectors, &buf[8]);  	/*  	 * Set OPTIMAL TRANSFER LENGTH diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index 8bfa61c9693d..1157b559683b 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -1118,7 +1118,6 @@ static struct configfs_attribute *tcmu_backend_dev_attrs[] = {  	&tcmu_dev_attrib_hw_block_size.attr,  	&tcmu_dev_attrib_block_size.attr,  	&tcmu_dev_attrib_hw_max_sectors.attr, -	&tcmu_dev_attrib_fabric_max_sectors.attr,  	&tcmu_dev_attrib_optimal_sectors.attr,  	&tcmu_dev_attrib_hw_queue_depth.attr,  	&tcmu_dev_attrib_queue_depth.attr, diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index c1188ac053c9..2ccbc0788353 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c @@ -608,6 +608,7 @@ static int imx_thermal_suspend(struct device *dev)  	regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP);  	regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);  	data->mode = THERMAL_DEVICE_DISABLED; +	clk_disable_unprepare(data->thermal_clk);  	return 0;  } @@ -617,6 +618,7 @@ static int imx_thermal_resume(struct device *dev)  	struct imx_thermal_data *data = dev_get_drvdata(dev);  	struct regmap *map = data->tempmon; +	clk_prepare_enable(data->thermal_clk);  	/* Enabled thermal sensor after resume */  	regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);  	regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP); diff --git a/drivers/thermal/int340x_thermal/acpi_thermal_rel.c b/drivers/thermal/int340x_thermal/acpi_thermal_rel.c index 231cabc16e16..2c2ec7666eb1 100644 --- a/drivers/thermal/int340x_thermal/acpi_thermal_rel.c +++ b/drivers/thermal/int340x_thermal/acpi_thermal_rel.c @@ -119,15 +119,11 @@ int acpi_parse_trt(acpi_handle handle, int *trt_count, struct trt **trtp,  			continue;  		result = acpi_bus_get_device(trt->source, &adev); -		if (!result) -			acpi_create_platform_device(adev); -		else +		if (result)  			pr_warn("Failed to get source ACPI device\n");  		result = acpi_bus_get_device(trt->target, &adev); -		if (!result) -			acpi_create_platform_device(adev); -		else +		if (result)  			pr_warn("Failed to get target ACPI device\n");  	} @@ -206,16 +202,12 @@ int acpi_parse_art(acpi_handle handle, int *art_count, struct art **artp,  		if (art->source) {  			result = acpi_bus_get_device(art->source, &adev); -			if (!result) -				acpi_create_platform_device(adev); -			else +			if (result)  				pr_warn("Failed to get source ACPI device\n");  		}  		if (art->target) {  			result = acpi_bus_get_device(art->target, &adev); -			if (!result) -				acpi_create_platform_device(adev); -			else +			if (result)  				pr_warn("Failed to get source ACPI device\n");  		}  	} diff --git a/drivers/thermal/int340x_thermal/processor_thermal_device.c b/drivers/thermal/int340x_thermal/processor_thermal_device.c index 31bb553aac26..0fe5dbbea968 100644 --- a/drivers/thermal/int340x_thermal/processor_thermal_device.c +++ b/drivers/thermal/int340x_thermal/processor_thermal_device.c @@ -130,6 +130,8 @@ static int proc_thermal_add(struct device *dev,  	int ret;  	adev = ACPI_COMPANION(dev); +	if (!adev) +		return -ENODEV;  	status = acpi_evaluate_object(adev->handle, "PPCC", NULL, &buf);  	if (ACPI_FAILURE(status)) diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c index e145b66df444..d717f3dab6f1 100644 --- a/drivers/thermal/of-thermal.c +++ b/drivers/thermal/of-thermal.c @@ -149,7 +149,7 @@ EXPORT_SYMBOL_GPL(of_thermal_is_trip_valid);   *   * Return: pointer to trip points table, NULL otherwise   */ -const struct thermal_trip * const +const struct thermal_trip *  of_thermal_get_trip_points(struct thermal_zone_device *tz)  {  	struct __thermal_zone *data = tz->devdata; diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c index 8803e693fe68..2580a4872f90 100644 --- a/drivers/thermal/rcar_thermal.c +++ b/drivers/thermal/rcar_thermal.c @@ -63,7 +63,7 @@ struct rcar_thermal_priv {  	struct mutex lock;  	struct list_head list;  	int id; -	int ctemp; +	u32 ctemp;  };  #define rcar_thermal_for_each_priv(pos, common)	\ @@ -145,7 +145,7 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv)  {  	struct device *dev = rcar_priv_to_dev(priv);  	int i; -	int ctemp, old, new; +	u32 ctemp, old, new;  	int ret = -EINVAL;  	mutex_lock(&priv->lock); @@ -372,6 +372,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)  	int i;  	int ret = -ENODEV;  	int idle = IDLE_INTERVAL; +	u32 enr_bits = 0;  	common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL);  	if (!common) @@ -390,7 +391,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)  		/*  		 * platform has IRQ support. -		 * Then, drier use common register +		 * Then, driver uses common registers  		 */  		ret = devm_request_irq(dev, irq->start, rcar_thermal_irq, 0, @@ -408,9 +409,6 @@ static int rcar_thermal_probe(struct platform_device *pdev)  		if (IS_ERR(common->base))  			return PTR_ERR(common->base); -		/* enable temperature comparation */ -		rcar_thermal_common_write(common, ENR, 0x00030303); -  		idle = 0; /* polling delay is not needed */  	} @@ -452,8 +450,15 @@ static int rcar_thermal_probe(struct platform_device *pdev)  			rcar_thermal_irq_enable(priv);  		list_move_tail(&priv->list, &common->head); + +		/* update ENR bits */ +		enr_bits |= 3 << (i * 8);  	} +	/* enable temperature comparation */ +	if (irq) +		rcar_thermal_common_write(common, ENR, enr_bits); +  	platform_set_drvdata(pdev, common);  	dev_info(dev, "%d sensor probed\n", i); diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index 9083e7520623..0531c752fbbb 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -91,7 +91,7 @@ int of_parse_thermal_zones(void);  void of_thermal_destroy_zones(void);  int of_thermal_get_ntrips(struct thermal_zone_device *);  bool of_thermal_is_trip_valid(struct thermal_zone_device *, int); -const struct thermal_trip * const +const struct thermal_trip *  of_thermal_get_trip_points(struct thermal_zone_device *);  #else  static inline int of_parse_thermal_zones(void) { return 0; } @@ -105,7 +105,7 @@ static inline bool of_thermal_is_trip_valid(struct thermal_zone_device *tz,  {  	return 0;  } -static inline const struct thermal_trip * const +static inline const struct thermal_trip *  of_thermal_get_trip_points(struct thermal_zone_device *tz)  {  	return NULL; diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index d2b496750d59..4ddfa60c9222 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -2399,17 +2399,12 @@ static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file,  	poll_wait(file, &tty->read_wait, wait);  	poll_wait(file, &tty->write_wait, wait); -	if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) -		mask |= POLLHUP;  	if (input_available_p(tty, 1))  		mask |= POLLIN | POLLRDNORM; -	else if (mask & POLLHUP) { -		tty_flush_to_ldisc(tty); -		if (input_available_p(tty, 1)) -			mask |= POLLIN | POLLRDNORM; -	}  	if (tty->packet && tty->link->ctrl_status)  		mask |= POLLPRI | POLLIN | POLLRDNORM; +	if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) +		mask |= POLLHUP;  	if (tty_hung_up_p(file))  		mask |= POLLHUP;  	if (!(mask & (POLLHUP | POLLIN | POLLRDNORM))) { diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 31feeb2d0a66..d1f8dc6aabcb 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1815,7 +1815,7 @@ pci_wch_ch353_setup(struct serial_private *priv,  }  static int -pci_wch_ch382_setup(struct serial_private *priv, +pci_wch_ch38x_setup(struct serial_private *priv,                      const struct pciserial_board *board,                      struct uart_8250_port *port, int idx)  { @@ -1880,6 +1880,7 @@ pci_wch_ch382_setup(struct serial_private *priv,  #define PCIE_VENDOR_ID_WCH		0x1c00  #define PCIE_DEVICE_ID_WCH_CH382_2S1P	0x3250 +#define PCIE_DEVICE_ID_WCH_CH384_4S	0x3470  /* Unknown vendors/cards - this should not be in linux/pci_ids.h */  #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584	0x1584 @@ -2571,13 +2572,21 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {  		.subdevice	= PCI_ANY_ID,  		.setup		= pci_wch_ch353_setup,  	}, -	/* WCH CH382 2S1P card (16750 clone) */ +	/* WCH CH382 2S1P card (16850 clone) */  	{  		.vendor         = PCIE_VENDOR_ID_WCH,  		.device         = PCIE_DEVICE_ID_WCH_CH382_2S1P,  		.subvendor      = PCI_ANY_ID,  		.subdevice      = PCI_ANY_ID, -		.setup          = pci_wch_ch382_setup, +		.setup          = pci_wch_ch38x_setup, +	}, +	/* WCH CH384 4S card (16850 clone) */ +	{ +		.vendor         = PCIE_VENDOR_ID_WCH, +		.device         = PCIE_DEVICE_ID_WCH_CH384_4S, +		.subvendor      = PCI_ANY_ID, +		.subdevice      = PCI_ANY_ID, +		.setup          = pci_wch_ch38x_setup,  	},  	/*  	 * ASIX devices with FIFO bug @@ -2876,6 +2885,7 @@ enum pci_board_num_t {  	pbn_fintek_4,  	pbn_fintek_8,  	pbn_fintek_12, +	pbn_wch384_4,  };  /* @@ -3675,6 +3685,14 @@ static struct pciserial_board pci_boards[] = {  		.base_baud	= 115200,  		.first_offset	= 0x40,  	}, + +	[pbn_wch384_4] = { +		.flags		= FL_BASE0, +		.num_ports	= 4, +		.base_baud      = 115200, +		.uart_offset    = 8, +		.first_offset   = 0xC0, +	},  };  static const struct pci_device_id blacklist[] = { @@ -3687,6 +3705,7 @@ static const struct pci_device_id blacklist[] = {  	{ PCI_DEVICE(0x4348, 0x7053), }, /* WCH CH353 2S1P */  	{ PCI_DEVICE(0x4348, 0x5053), }, /* WCH CH353 1S1P */  	{ PCI_DEVICE(0x1c00, 0x3250), }, /* WCH CH382 2S1P */ +	{ PCI_DEVICE(0x1c00, 0x3470), }, /* WCH CH384 4S */  };  /* @@ -5400,6 +5419,10 @@ static struct pci_device_id serial_pci_tbl[] = {  		PCI_ANY_ID, PCI_ANY_ID,  		0, 0, pbn_b0_bt_2_115200 }, +	{	PCIE_VENDOR_ID_WCH, PCIE_DEVICE_ID_WCH_CH384_4S, +		PCI_ANY_ID, PCI_ANY_ID, +		0, 0, pbn_wch384_4 }, +  	/*  	 * Commtech, Inc. Fastcom adapters  	 */ diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 19273e31d224..107e80722575 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -1757,32 +1757,43 @@ static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {  #endif  #if defined(CONFIG_ARCH_EXYNOS) +#define EXYNOS_COMMON_SERIAL_DRV_DATA				\ +	.info = &(struct s3c24xx_uart_info) {			\ +		.name		= "Samsung Exynos UART",	\ +		.type		= PORT_S3C6400,			\ +		.has_divslot	= 1,				\ +		.rx_fifomask	= S5PV210_UFSTAT_RXMASK,	\ +		.rx_fifoshift	= S5PV210_UFSTAT_RXSHIFT,	\ +		.rx_fifofull	= S5PV210_UFSTAT_RXFULL,	\ +		.tx_fifofull	= S5PV210_UFSTAT_TXFULL,	\ +		.tx_fifomask	= S5PV210_UFSTAT_TXMASK,	\ +		.tx_fifoshift	= S5PV210_UFSTAT_TXSHIFT,	\ +		.def_clk_sel	= S3C2410_UCON_CLKSEL0,		\ +		.num_clks	= 1,				\ +		.clksel_mask	= 0,				\ +		.clksel_shift	= 0,				\ +	},							\ +	.def_cfg = &(struct s3c2410_uartcfg) {			\ +		.ucon		= S5PV210_UCON_DEFAULT,		\ +		.ufcon		= S5PV210_UFCON_DEFAULT,	\ +		.has_fracval	= 1,				\ +	}							\ +  static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = { -	.info = &(struct s3c24xx_uart_info) { -		.name		= "Samsung Exynos4 UART", -		.type		= PORT_S3C6400, -		.has_divslot	= 1, -		.rx_fifomask	= S5PV210_UFSTAT_RXMASK, -		.rx_fifoshift	= S5PV210_UFSTAT_RXSHIFT, -		.rx_fifofull	= S5PV210_UFSTAT_RXFULL, -		.tx_fifofull	= S5PV210_UFSTAT_TXFULL, -		.tx_fifomask	= S5PV210_UFSTAT_TXMASK, -		.tx_fifoshift	= S5PV210_UFSTAT_TXSHIFT, -		.def_clk_sel	= S3C2410_UCON_CLKSEL0, -		.num_clks	= 1, -		.clksel_mask	= 0, -		.clksel_shift	= 0, -	}, -	.def_cfg = &(struct s3c2410_uartcfg) { -		.ucon		= S5PV210_UCON_DEFAULT, -		.ufcon		= S5PV210_UFCON_DEFAULT, -		.has_fracval	= 1, -	}, +	EXYNOS_COMMON_SERIAL_DRV_DATA,  	.fifosize = { 256, 64, 16, 16 },  }; + +static struct s3c24xx_serial_drv_data exynos5433_serial_drv_data = { +	EXYNOS_COMMON_SERIAL_DRV_DATA, +	.fifosize = { 64, 256, 16, 256 }, +}; +  #define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos4210_serial_drv_data) +#define EXYNOS5433_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos5433_serial_drv_data)  #else  #define EXYNOS4210_SERIAL_DRV_DATA (kernel_ulong_t)NULL +#define EXYNOS5433_SERIAL_DRV_DATA (kernel_ulong_t)NULL  #endif  static struct platform_device_id s3c24xx_serial_driver_ids[] = { @@ -1804,6 +1815,9 @@ static struct platform_device_id s3c24xx_serial_driver_ids[] = {  	}, {  		.name		= "exynos4210-uart",  		.driver_data	= EXYNOS4210_SERIAL_DRV_DATA, +	}, { +		.name		= "exynos5433-uart", +		.driver_data	= EXYNOS5433_SERIAL_DRV_DATA,  	},  	{ },  }; @@ -1823,6 +1837,8 @@ static const struct of_device_id s3c24xx_uart_dt_match[] = {  		.data = (void *)S5PV210_SERIAL_DRV_DATA },  	{ .compatible = "samsung,exynos4210-uart",  		.data = (void *)EXYNOS4210_SERIAL_DRV_DATA }, +	{ .compatible = "samsung,exynos5433-uart", +		.data = (void *)EXYNOS5433_SERIAL_DRV_DATA },  	{},  };  MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match); diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 57ca61b14670..984605bb5bf1 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2164,7 +2164,9 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port)  		break;  	} -	dev_info(port->dev, "%s%d at %s (irq = %d, base_baud = %d) is a %s\n", +	printk(KERN_INFO "%s%s%s%d at %s (irq = %d, base_baud = %d) is a %s\n", +	       port->dev ? dev_name(port->dev) : "", +	       port->dev ? ": " : "",  	       drv->dev_name,  	       drv->tty_driver->name_base + port->line,  	       address, port->irq, port->uartclk / 16, uart_type(port)); diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 4f35b43e2475..51f066aa375e 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1464,6 +1464,9 @@ static int tty_reopen(struct tty_struct *tty)  	    driver->subtype == PTY_TYPE_MASTER)  		return -EIO; +	if (test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN)) +		return -EBUSY; +  	tty->count++;  	WARN_ON(!tty->ldisc); @@ -2106,10 +2109,6 @@ retry_open:  		retval = -ENODEV;  	filp->f_flags = saved_flags; -	if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && -						!capable(CAP_SYS_ADMIN)) -		retval = -EBUSY; -  	if (retval) {  #ifdef TTY_DEBUG_HANGUP  		printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 5b9825a4538a..a57dc8866fc5 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -669,7 +669,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)  	if (!ci)  		return -ENOMEM; -	platform_set_drvdata(pdev, ci);  	ci->dev = dev;  	ci->platdata = dev_get_platdata(dev);  	ci->imx28_write_fix = !!(ci->platdata->flags & @@ -783,6 +782,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)  		}  	} +	platform_set_drvdata(pdev, ci);  	ret = devm_request_irq(dev, ci->irq, ci_irq, IRQF_SHARED,  			ci->platdata->name, ci);  	if (ret) diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index c1694cff1eaf..48731d0bab35 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -91,6 +91,7 @@ static int host_start(struct ci_hdrc *ci)  	if (!hcd)  		return -ENOMEM; +	dev_set_drvdata(ci->dev, ci);  	hcd->rsrc_start = ci->hw_bank.phys;  	hcd->rsrc_len = ci->hw_bank.size;  	hcd->regs = ci->hw_bank.abs; diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 200168ec2d75..79242008085b 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2567,7 +2567,7 @@ error:   * s3c_hsotg_ep_disable - disable given endpoint   * @ep: The endpoint to disable.   */ -static int s3c_hsotg_ep_disable(struct usb_ep *ep) +static int s3c_hsotg_ep_disable_force(struct usb_ep *ep, bool force)  {  	struct s3c_hsotg_ep *hs_ep = our_ep(ep);  	struct dwc2_hsotg *hsotg = hs_ep->parent; @@ -2588,7 +2588,7 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep)  	spin_lock_irqsave(&hsotg->lock, flags);  	/* terminate all requests with shutdown */ -	kill_all_requests(hsotg, hs_ep, -ESHUTDOWN, false); +	kill_all_requests(hsotg, hs_ep, -ESHUTDOWN, force);  	hsotg->fifo_map &= ~(1<<hs_ep->fifo_index);  	hs_ep->fifo_index = 0; @@ -2609,6 +2609,10 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep)  	return 0;  } +static int s3c_hsotg_ep_disable(struct usb_ep *ep) +{ +	return s3c_hsotg_ep_disable_force(ep, false); +}  /**   * on_list - check request is on the given endpoint   * @ep: The endpoint to check. @@ -2924,7 +2928,7 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget)  	/* all endpoints should be shutdown */  	for (ep = 1; ep < hsotg->num_of_eps; ep++) -		s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); +		s3c_hsotg_ep_disable_force(&hsotg->eps[ep].ep, true);  	spin_lock_irqsave(&hsotg->lock, flags); diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 7c4faf738747..b642a2f998f9 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -33,6 +33,8 @@  #define PCI_DEVICE_ID_INTEL_BYT		0x0f37  #define PCI_DEVICE_ID_INTEL_MRFLD	0x119e  #define PCI_DEVICE_ID_INTEL_BSW		0x22B7 +#define PCI_DEVICE_ID_INTEL_SPTLP	0x9d30 +#define PCI_DEVICE_ID_INTEL_SPTH	0xa130  struct dwc3_pci {  	struct device		*dev; @@ -219,6 +221,8 @@ static const struct pci_device_id dwc3_pci_id_table[] = {  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW), },  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), },  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), }, +	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTLP), }, +	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTH), },  	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), },  	{  }	/* Terminating Entry */  }; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index f03b136ecfce..8f65ab3a3b92 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -882,8 +882,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting)  				if (i == (request->num_mapped_sgs - 1) ||  						sg_is_last(s)) { -					if (list_is_last(&req->list, -							&dep->request_list)) +					if (list_empty(&dep->request_list))  						last_one = true;  					chain = false;  				} @@ -901,6 +900,9 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting)  				if (last_one)  					break;  			} + +			if (last_one) +				break;  		} else {  			dma = req->request.dma;  			length = req->request.length; diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 6e04e302dc3a..a1bc3e3a0b09 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -399,8 +399,9 @@ static int hidg_setup(struct usb_function *f,  	value	= __le16_to_cpu(ctrl->wValue);  	length	= __le16_to_cpu(ctrl->wLength); -	VDBG(cdev, "hid_setup crtl_request : bRequestType:0x%x bRequest:0x%x " -		"Value:0x%x\n", ctrl->bRequestType, ctrl->bRequest, value); +	VDBG(cdev, +	     "%s crtl_request : bRequestType:0x%x bRequest:0x%x Value:0x%x\n", +	     __func__, ctrl->bRequestType, ctrl->bRequest, value);  	switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {  	case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index a90440300735..259b656c0b3e 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -520,7 +520,7 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req)  		req = midi_alloc_ep_req(ep, midi->buflen);  	if (!req) { -		ERROR(midi, "gmidi_transmit: alloc_ep_request failed\n"); +		ERROR(midi, "%s: alloc_ep_request failed\n", __func__);  		return;  	}  	req->length = 0; diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index f7b203293205..e9715845f82e 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -897,7 +897,6 @@ static void f_audio_free_inst(struct usb_function_instance *f)  	struct f_uac1_opts *opts;  	opts = container_of(f, struct f_uac1_opts, func_inst); -	gaudio_cleanup(opts->card);  	if (opts->fn_play_alloc)  		kfree(opts->fn_play);  	if (opts->fn_cap_alloc) @@ -935,6 +934,7 @@ static void f_audio_free(struct usb_function *f)  	struct f_audio *audio = func_to_audio(f);  	struct f_uac1_opts *opts; +	gaudio_cleanup(&audio->card);  	opts = container_of(f->fi, struct f_uac1_opts, func_inst);  	kfree(audio);  	mutex_lock(&opts->lock); diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index c744e4975d74..db49ec4c748e 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -441,6 +441,7 @@ ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)  	kbuf = memdup_user(buf, len);  	if (IS_ERR(kbuf)) {  		value = PTR_ERR(kbuf); +		kbuf = NULL;  		goto free1;  	} @@ -449,6 +450,7 @@ ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)  		data->name, len, (int) value);  free1:  	mutex_unlock(&data->lock); +	kfree (kbuf);  	return value;  } diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index ce882371786b..9f93bed42052 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -716,10 +716,10 @@ static int queue_dma(struct usba_udc *udc, struct usba_ep *ep,  	req->using_dma = 1;  	req->ctrl = USBA_BF(DMA_BUF_LEN, req->req.length)  			| USBA_DMA_CH_EN | USBA_DMA_END_BUF_IE -			| USBA_DMA_END_TR_EN | USBA_DMA_END_TR_IE; +			| USBA_DMA_END_BUF_EN; -	if (ep->is_in) -		req->ctrl |= USBA_DMA_END_BUF_EN; +	if (!ep->is_in) +		req->ctrl |= USBA_DMA_END_TR_EN | USBA_DMA_END_TR_IE;  	/*  	 * Add this request to the queue and submit for DMA if @@ -828,7 +828,7 @@ static int usba_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)  {  	struct usba_ep *ep = to_usba_ep(_ep);  	struct usba_udc *udc = ep->udc; -	struct usba_request *req = to_usba_req(_req); +	struct usba_request *req;  	unsigned long flags;  	u32 status; @@ -837,6 +837,16 @@ static int usba_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)  	spin_lock_irqsave(&udc->lock, flags); +	list_for_each_entry(req, &ep->queue, queue) { +		if (&req->req == _req) +			break; +	} + +	if (&req->req != _req) { +		spin_unlock_irqrestore(&udc->lock, flags); +		return -EINVAL; +	} +  	if (req->using_dma) {  		/*  		 * If this request is currently being transferred, @@ -1563,7 +1573,6 @@ static void usba_ep_irq(struct usba_udc *udc, struct usba_ep *ep)  	if ((epstatus & epctrl) & USBA_RX_BK_RDY) {  		DBG(DBG_BUS, "%s: RX data ready\n", ep->ep.name);  		receive_data(ep); -		usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY);  	}  } diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.c b/drivers/usb/gadget/udc/bdc/bdc_ep.c index ff67ceac77c4..d4fe8d769bd6 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_ep.c +++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c @@ -718,10 +718,11 @@ static int ep_queue(struct bdc_ep *ep, struct bdc_req *req)  	struct bdc *bdc;  	int ret = 0; -	bdc = ep->bdc;  	if (!req || !ep || !ep->usb_ep.desc)  		return -EINVAL; +	bdc = ep->bdc; +  	req->usb_req.actual = 0;  	req->usb_req.status = -EINPROGRESS;  	req->epnum = ep->ep_num; diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index e113fd73aeae..f9a332775c47 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1581,6 +1581,10 @@ iso_stream_schedule (  	else  		next = (now + 2 + 7) & ~0x07;	/* full frame cache */ +	/* If needed, initialize last_iso_frame so that this URB will be seen */ +	if (ehci->isoc_count == 0) +		ehci->last_iso_frame = now >> 3; +  	/*  	 * Use ehci->last_iso_frame as the base.  There can't be any  	 * TDs scheduled for earlier than that. @@ -1600,11 +1604,11 @@ iso_stream_schedule (  	 */  	now2 = (now - base) & (mod - 1); -	/* Is the schedule already full? */ +	/* Is the schedule about to wrap around? */  	if (unlikely(!empty && start < period)) { -		ehci_dbg(ehci, "iso sched full %p (%u-%u < %u mod %u)\n", +		ehci_dbg(ehci, "request %p would overflow (%u-%u < %u mod %u)\n",  				urb, stream->next_uframe, base, period, mod); -		status = -ENOSPC; +		status = -EFBIG;  		goto fail;  	} @@ -1671,10 +1675,6 @@ iso_stream_schedule (  	urb->start_frame = start & (mod - 1);  	if (!stream->highspeed)  		urb->start_frame >>= 3; - -	/* Make sure scan_isoc() sees these */ -	if (ehci->isoc_count == 0) -		ehci->last_iso_frame = now >> 3;  	return status;   fail: diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 19a9af1b4d74..ff9af29b4e9f 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -451,7 +451,7 @@ static int tegra_ehci_probe(struct platform_device *pdev)  	u_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0);  	if (IS_ERR(u_phy)) { -		err = PTR_ERR(u_phy); +		err = -EPROBE_DEFER;  		goto cleanup_clk_en;  	}  	hcd->usb_phy = u_phy; diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index dd483c13565b..ce636466edb7 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -567,7 +567,8 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev)  {  	void __iomem *base;  	u32 control; -	u32 fminterval; +	u32 fminterval = 0; +	bool no_fminterval = false;  	int cnt;  	if (!mmio_resource_enabled(pdev, 0)) @@ -577,6 +578,13 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev)  	if (base == NULL)  		return; +	/* +	 * ULi M5237 OHCI controller locks the whole system when accessing +	 * the OHCI_FMINTERVAL offset. +	 */ +	if (pdev->vendor == PCI_VENDOR_ID_AL && pdev->device == 0x5237) +		no_fminterval = true; +  	control = readl(base + OHCI_CONTROL);  /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ @@ -615,7 +623,9 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev)  	}  	/* software reset of the controller, preserving HcFmInterval */ -	fminterval = readl(base + OHCI_FMINTERVAL); +	if (!no_fminterval) +		fminterval = readl(base + OHCI_FMINTERVAL); +  	writel(OHCI_HCR, base + OHCI_CMDSTATUS);  	/* reset requires max 10 us delay */ @@ -624,7 +634,9 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev)  			break;  		udelay(1);  	} -	writel(fminterval, base + OHCI_FMINTERVAL); + +	if (!no_fminterval) +		writel(fminterval, base + OHCI_FMINTERVAL);  	/* Now the controller is safely in SUSPEND and nothing can wake it up */  	iounmap(base); diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 142b601f9563..7f76c8a12f89 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -82,6 +82,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)  				"must be suspended extra slowly",  				pdev->revision);  		} +		if (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK) +			xhci->quirks |= XHCI_BROKEN_STREAMS;  		/* Fresco Logic confirms: all revisions of this chip do not  		 * support MSI, even though some of them claim to in their PCI  		 * capabilities. diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 01fcbb5eb06e..c50d8d202618 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -3803,6 +3803,15 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev,  		return -EINVAL;  	} +	if (setup == SETUP_CONTEXT_ONLY) { +		slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx); +		if (GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state)) == +		    SLOT_STATE_DEFAULT) { +			xhci_dbg(xhci, "Slot already in default state\n"); +			return 0; +		} +	} +  	command = xhci_alloc_command(xhci, false, false, GFP_KERNEL);  	if (!command)  		return -ENOMEM; diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 9d68372dd9aa..b005010240e5 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -72,6 +72,8 @@ config USB_MUSB_DA8XX  config USB_MUSB_TUSB6010  	tristate "TUSB6010" +	depends on ARCH_OMAP2PLUS || COMPILE_TEST +	depends on NOP_USB_XCEIV = USB_MUSB_HDRC # both built-in or both modules  config USB_MUSB_OMAP2PLUS  	tristate "OMAP2430 and onwards" @@ -85,6 +87,7 @@ config USB_MUSB_AM35X  config USB_MUSB_DSPS  	tristate "TI DSPS platforms"  	select USB_MUSB_AM335X_CHILD +	depends on ARCH_OMAP2PLUS || COMPILE_TEST  	depends on OF_IRQ  config USB_MUSB_BLACKFIN @@ -93,6 +96,7 @@ config USB_MUSB_BLACKFIN  config USB_MUSB_UX500  	tristate "Ux500 platforms" +	depends on ARCH_U8500 || COMPILE_TEST  config USB_MUSB_JZ4740  	tristate "JZ4740" diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index a441a2de8619..178250145613 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -63,7 +63,7 @@ static void bfin_writew(void __iomem *addr, unsigned offset, u16 data)  	bfin_write16(addr + offset, data);  } -static void binf_writel(void __iomem *addr, unsigned offset, u32 data) +static void bfin_writel(void __iomem *addr, unsigned offset, u32 data)  {  	bfin_write16(addr + offset, (u16)data);  } diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index f64fd964dc6d..c39a16ad7832 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c @@ -628,9 +628,9 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller)  		ret = of_property_read_string_index(np, "dma-names", i, &str);  		if (ret)  			goto err; -		if (!strncmp(str, "tx", 2)) +		if (strstarts(str, "tx"))  			is_tx = 1; -		else if (!strncmp(str, "rx", 2)) +		else if (strstarts(str, "rx"))  			is_tx = 0;  		else {  			dev_err(dev, "Wrong dmatype %s\n", str); diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c index ad3701a97389..48131aa8472c 100644 --- a/drivers/usb/musb/musb_debugfs.c +++ b/drivers/usb/musb/musb_debugfs.c @@ -59,20 +59,12 @@ static const struct musb_register_map musb_regmap[] = {  	{ "RxMaxPp",	MUSB_RXMAXP,	16 },  	{ "RxCSR",	MUSB_RXCSR,	16 },  	{ "RxCount",	MUSB_RXCOUNT,	16 }, -	{ "ConfigData",	MUSB_CONFIGDATA,8 },  	{ "IntrRxE",	MUSB_INTRRXE,	16 },  	{ "IntrTxE",	MUSB_INTRTXE,	16 },  	{ "IntrUsbE",	MUSB_INTRUSBE,	8 },  	{ "DevCtl",	MUSB_DEVCTL,	8 }, -	{ "BabbleCtl",	MUSB_BABBLE_CTL,8 }, -	{ "TxFIFOsz",	MUSB_TXFIFOSZ,	8 }, -	{ "RxFIFOsz",	MUSB_RXFIFOSZ,	8 }, -	{ "TxFIFOadd",	MUSB_TXFIFOADD,	16 }, -	{ "RxFIFOadd",	MUSB_RXFIFOADD,	16 },  	{ "VControl",	0x68,		32 },  	{ "HWVers",	0x69,		16 }, -	{ "EPInfo",	MUSB_EPINFO,	8 }, -	{ "RAMInfo",	MUSB_RAMINFO,	8 },  	{ "LinkInfo",	MUSB_LINKINFO,	8 },  	{ "VPLen",	MUSB_VPLEN,	8 },  	{ "HS_EOF1",	MUSB_HS_EOF1,	8 }, @@ -103,6 +95,16 @@ static const struct musb_register_map musb_regmap[] = {  	{ "DMA_CNTLch7",	0x274,	16 },  	{ "DMA_ADDRch7",	0x278,	32 },  	{ "DMA_COUNTch7",	0x27C,	32 }, +#ifndef CONFIG_BLACKFIN +	{ "ConfigData",	MUSB_CONFIGDATA,8 }, +	{ "BabbleCtl",	MUSB_BABBLE_CTL,8 }, +	{ "TxFIFOsz",	MUSB_TXFIFOSZ,	8 }, +	{ "RxFIFOsz",	MUSB_RXFIFOSZ,	8 }, +	{ "TxFIFOadd",	MUSB_TXFIFOADD,	16 }, +	{ "RxFIFOadd",	MUSB_RXFIFOADD,	16 }, +	{ "EPInfo",	MUSB_EPINFO,	8 }, +	{ "RAMInfo",	MUSB_RAMINFO,	8 }, +#endif  	{  }	/* Terminating Entry */  }; @@ -197,30 +199,30 @@ static ssize_t musb_test_mode_write(struct file *file,  	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))  		return -EFAULT; -	if (!strncmp(buf, "force host", 9)) +	if (strstarts(buf, "force host"))  		test = MUSB_TEST_FORCE_HOST; -	if (!strncmp(buf, "fifo access", 11)) +	if (strstarts(buf, "fifo access"))  		test = MUSB_TEST_FIFO_ACCESS; -	if (!strncmp(buf, "force full-speed", 15)) +	if (strstarts(buf, "force full-speed"))  		test = MUSB_TEST_FORCE_FS; -	if (!strncmp(buf, "force high-speed", 15)) +	if (strstarts(buf, "force high-speed"))  		test = MUSB_TEST_FORCE_HS; -	if (!strncmp(buf, "test packet", 10)) { +	if (strstarts(buf, "test packet")) {  		test = MUSB_TEST_PACKET;  		musb_load_testpacket(musb);  	} -	if (!strncmp(buf, "test K", 6)) +	if (strstarts(buf, "test K"))  		test = MUSB_TEST_K; -	if (!strncmp(buf, "test J", 6)) +	if (strstarts(buf, "test J"))  		test = MUSB_TEST_J; -	if (!strncmp(buf, "test SE0 NAK", 12)) +	if (strstarts(buf, "test SE0 NAK"))  		test = MUSB_TEST_SE0_NAK;  	musb_writeb(musb->mregs, MUSB_TESTMODE, test); diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 23d474d3d7f4..883a9adfdfff 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2663,7 +2663,6 @@ void musb_host_cleanup(struct musb *musb)  	if (musb->port_mode == MUSB_PORT_MODE_GADGET)  		return;  	usb_remove_hcd(musb->hcd); -	musb->hcd = NULL;  }  void musb_host_free(struct musb *musb) diff --git a/drivers/usb/phy/phy-mv-usb.c b/drivers/usb/phy/phy-mv-usb.c index 699e38c73d82..697a741a0cb1 100644 --- a/drivers/usb/phy/phy-mv-usb.c +++ b/drivers/usb/phy/phy-mv-usb.c @@ -338,7 +338,6 @@ static void mv_otg_update_inputs(struct mv_otg *mvotg)  static void mv_otg_update_state(struct mv_otg *mvotg)  {  	struct mv_otg_ctrl *otg_ctrl = &mvotg->otg_ctrl; -	struct usb_phy *phy = &mvotg->phy;  	int old_state = mvotg->phy.otg->state;  	switch (old_state) { @@ -858,10 +857,10 @@ static int mv_otg_suspend(struct platform_device *pdev, pm_message_t state)  {  	struct mv_otg *mvotg = platform_get_drvdata(pdev); -	if (mvotg->phy.state != OTG_STATE_B_IDLE) { +	if (mvotg->phy.otg->state != OTG_STATE_B_IDLE) {  		dev_info(&pdev->dev,  			 "OTG state is not B_IDLE, it is %d!\n", -			 mvotg->phy.state); +			 mvotg->phy.otg->state);  		return -EAGAIN;  	} diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index b4066a001ba0..ccfdfb24b240 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c @@ -34,7 +34,7 @@ static struct usb_phy *__usb_find_phy(struct list_head *list,  		return phy;  	} -	return ERR_PTR(-ENODEV); +	return ERR_PTR(-EPROBE_DEFER);  }  static struct usb_phy *__usb_find_phy_dev(struct device *dev, @@ -59,6 +59,9 @@ static struct usb_phy *__of_usb_find_phy(struct device_node *node)  {  	struct usb_phy  *phy; +	if (!of_device_is_available(node)) +		return ERR_PTR(-ENODEV); +  	list_for_each_entry(phy, &phy_list, head) {  		if (node != phy->dev->of_node)  			continue; @@ -66,7 +69,7 @@ static struct usb_phy *__of_usb_find_phy(struct device_node *node)  		return phy;  	} -	return ERR_PTR(-ENODEV); +	return ERR_PTR(-EPROBE_DEFER);  }  static void devm_usb_phy_release(struct device *dev, void *res) @@ -190,10 +193,13 @@ struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev,  	spin_lock_irqsave(&phy_lock, flags);  	phy = __of_usb_find_phy(node); -	if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { -		if (!IS_ERR(phy)) -			phy = ERR_PTR(-EPROBE_DEFER); +	if (IS_ERR(phy)) { +		devres_free(ptr); +		goto err1; +	} +	if (!try_module_get(phy->dev->driver->owner)) { +		phy = ERR_PTR(-ENODEV);  		devres_free(ptr);  		goto err1;  	} diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index 8d7fc48b1f30..29fa1c3d0089 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c @@ -46,6 +46,8 @@ static struct console usbcons;   * ------------------------------------------------------------   */ +static const struct tty_operations usb_console_fake_tty_ops = { +};  /*   * The parsing of the command line works exactly like the @@ -137,13 +139,17 @@ static int usb_console_setup(struct console *co, char *options)  				goto reset_open_count;  			}  			kref_init(&tty->kref); -			tty_port_tty_set(&port->port, tty);  			tty->driver = usb_serial_tty_driver;  			tty->index = co->index; +			init_ldsem(&tty->ldisc_sem); +			INIT_LIST_HEAD(&tty->tty_files); +			kref_get(&tty->driver->kref); +			tty->ops = &usb_console_fake_tty_ops;  			if (tty_init_termios(tty)) {  				retval = -ENOMEM; -				goto free_tty; +				goto put_tty;  			} +			tty_port_tty_set(&port->port, tty);  		}  		/* only call the device specific open if this @@ -161,7 +167,7 @@ static int usb_console_setup(struct console *co, char *options)  			serial->type->set_termios(tty, port, &dummy);  			tty_port_tty_set(&port->port, NULL); -			kfree(tty); +			tty_kref_put(tty);  		}  		set_bit(ASYNCB_INITIALIZED, &port->port.flags);  	} @@ -177,8 +183,8 @@ static int usb_console_setup(struct console *co, char *options)   fail:  	tty_port_tty_set(&port->port, NULL); - free_tty: -	kfree(tty); + put_tty: +	tty_kref_put(tty);   reset_open_count:  	port->port.count = 0;  	usb_autopm_put_interface(serial->interface); diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 6c4eb3cf5efd..f4c56fc1a9f6 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -120,10 +120,12 @@ static const struct usb_device_id id_table[] = {  	{ USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */  	{ USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */  	{ USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */ -	{ USB_DEVICE(0x10C4, 0x8875) }, /* CEL MeshConnect USB Stick */ +	{ USB_DEVICE(0x10C4, 0x8856) },	/* CEL EM357 ZigBee USB Stick - LR */ +	{ USB_DEVICE(0x10C4, 0x8857) },	/* CEL EM357 ZigBee USB Stick */  	{ USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */  	{ USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */  	{ USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */ +	{ USB_DEVICE(0x10C4, 0x8977) },	/* CEL MeshWorks DevKit Device */  	{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */  	{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */  	{ USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 1bd192290b08..ccf1df7c4b80 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -286,7 +286,7 @@ static int usb_serial_generic_submit_read_urb(struct usb_serial_port *port,  	res = usb_submit_urb(port->read_urbs[index], mem_flags);  	if (res) { -		if (res != -EPERM) { +		if (res != -EPERM && res != -ENODEV) {  			dev_err(&port->dev,  					"%s - usb_submit_urb failed: %d\n",  					__func__, res); @@ -373,7 +373,7 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb)  							__func__, urb->status);  		return;  	default: -		dev_err(&port->dev, "%s - nonzero urb status: %d\n", +		dev_dbg(&port->dev, "%s - nonzero urb status: %d\n",  							__func__, urb->status);  		goto resubmit;  	} diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 077c714f1285..e07b15ed5814 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -410,6 +410,8 @@ static void	usa26_instat_callback(struct urb *urb)  	}  	port = serial->port[msg->port];  	p_priv = usb_get_serial_port_data(port); +	if (!p_priv) +		goto resubmit;  	/* Update handshaking pin state information */  	old_dcd_state = p_priv->dcd_state; @@ -420,7 +422,7 @@ static void	usa26_instat_callback(struct urb *urb)  	if (old_dcd_state != p_priv->dcd_state)  		tty_port_tty_hangup(&port->port, true); - +resubmit:  	/* Resubmit urb so we continue receiving */  	err = usb_submit_urb(urb, GFP_ATOMIC);  	if (err != 0) @@ -527,6 +529,8 @@ static void	usa28_instat_callback(struct urb *urb)  	}  	port = serial->port[msg->port];  	p_priv = usb_get_serial_port_data(port); +	if (!p_priv) +		goto resubmit;  	/* Update handshaking pin state information */  	old_dcd_state = p_priv->dcd_state; @@ -537,7 +541,7 @@ static void	usa28_instat_callback(struct urb *urb)  	if (old_dcd_state != p_priv->dcd_state && old_dcd_state)  		tty_port_tty_hangup(&port->port, true); - +resubmit:  		/* Resubmit urb so we continue receiving */  	err = usb_submit_urb(urb, GFP_ATOMIC);  	if (err != 0) @@ -607,6 +611,8 @@ static void	usa49_instat_callback(struct urb *urb)  	}  	port = serial->port[msg->portNumber];  	p_priv = usb_get_serial_port_data(port); +	if (!p_priv) +		goto resubmit;  	/* Update handshaking pin state information */  	old_dcd_state = p_priv->dcd_state; @@ -617,7 +623,7 @@ static void	usa49_instat_callback(struct urb *urb)  	if (old_dcd_state != p_priv->dcd_state && old_dcd_state)  		tty_port_tty_hangup(&port->port, true); - +resubmit:  	/* Resubmit urb so we continue receiving */  	err = usb_submit_urb(urb, GFP_ATOMIC);  	if (err != 0) @@ -855,6 +861,8 @@ static void	usa90_instat_callback(struct urb *urb)  	port = serial->port[0];  	p_priv = usb_get_serial_port_data(port); +	if (!p_priv) +		goto resubmit;  	/* Update handshaking pin state information */  	old_dcd_state = p_priv->dcd_state; @@ -865,7 +873,7 @@ static void	usa90_instat_callback(struct urb *urb)  	if (old_dcd_state != p_priv->dcd_state && old_dcd_state)  		tty_port_tty_hangup(&port->port, true); - +resubmit:  	/* Resubmit urb so we continue receiving */  	err = usb_submit_urb(urb, GFP_ATOMIC);  	if (err != 0) @@ -926,6 +934,8 @@ static void	usa67_instat_callback(struct urb *urb)  	port = serial->port[msg->port];  	p_priv = usb_get_serial_port_data(port); +	if (!p_priv) +		goto resubmit;  	/* Update handshaking pin state information */  	old_dcd_state = p_priv->dcd_state; @@ -934,7 +944,7 @@ static void	usa67_instat_callback(struct urb *urb)  	if (old_dcd_state != p_priv->dcd_state && old_dcd_state)  		tty_port_tty_hangup(&port->port, true); - +resubmit:  	/* Resubmit urb so we continue receiving */  	err = usb_submit_urb(urb, GFP_ATOMIC);  	if (err != 0) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 7a4c21b4f676..efdcee15b520 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -234,6 +234,8 @@ static void option_instat_callback(struct urb *urb);  #define QUALCOMM_VENDOR_ID			0x05C6 +#define SIERRA_VENDOR_ID			0x1199 +  #define CMOTECH_VENDOR_ID			0x16d8  #define CMOTECH_PRODUCT_6001			0x6001  #define CMOTECH_PRODUCT_CMU_300			0x6002 @@ -512,7 +514,7 @@ enum option_blacklist_reason {  		OPTION_BLACKLIST_RESERVED_IF = 2  }; -#define MAX_BL_NUM  8 +#define MAX_BL_NUM  11  struct option_blacklist_info {  	/* bitfield of interface numbers for OPTION_BLACKLIST_SENDSETUP */  	const unsigned long sendsetup; @@ -601,6 +603,11 @@ static const struct option_blacklist_info telit_le920_blacklist = {  	.reserved = BIT(1) | BIT(5),  }; +static const struct option_blacklist_info sierra_mc73xx_blacklist = { +	.sendsetup = BIT(0) | BIT(2), +	.reserved = BIT(8) | BIT(10) | BIT(11), +}; +  static const struct usb_device_id option_ids[] = {  	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },  	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, @@ -1098,6 +1105,8 @@ static const struct usb_device_id option_ids[] = {  	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */  	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */  	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ +	{ USB_DEVICE_INTERFACE_CLASS(SIERRA_VENDOR_ID, 0x68c0, 0xff), +	  .driver_info = (kernel_ulong_t)&sierra_mc73xx_blacklist }, /* MC73xx */  	{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },  	{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },  	{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003), diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index cb3e14780a7e..9c63897b3a56 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -142,7 +142,6 @@ static const struct usb_device_id id_table[] = {  	{DEVICE_SWI(0x0f3d, 0x68a2)},	/* Sierra Wireless MC7700 */  	{DEVICE_SWI(0x114f, 0x68a2)},	/* Sierra Wireless MC7750 */  	{DEVICE_SWI(0x1199, 0x68a2)},	/* Sierra Wireless MC7710 */ -	{DEVICE_SWI(0x1199, 0x68c0)},	/* Sierra Wireless MC73xx */  	{DEVICE_SWI(0x1199, 0x901c)},	/* Sierra Wireless EM7700 */  	{DEVICE_SWI(0x1199, 0x901f)},	/* Sierra Wireless EM7355 */  	{DEVICE_SWI(0x1199, 0x9040)},	/* Sierra Wireless Modem */ diff --git a/drivers/usb/storage/uas-detect.h b/drivers/usb/storage/uas-detect.h index 8a6f371ed6e7..9893d696fc97 100644 --- a/drivers/usb/storage/uas-detect.h +++ b/drivers/usb/storage/uas-detect.h @@ -69,16 +69,39 @@ static int uas_use_uas_driver(struct usb_interface *intf,  		return 0;  	/* -	 * ASM1051 and older ASM1053 devices have the same usb-id, and UAS is -	 * broken on the ASM1051, use the number of streams to differentiate. -	 * New ASM1053-s also support 32 streams, but have a different prod-id. +	 * ASMedia has a number of usb3 to sata bridge chips, at the time of +	 * this writing the following versions exist: +	 * ASM1051 - no uas support version +	 * ASM1051 - with broken (*) uas support +	 * ASM1053 - with working uas support +	 * ASM1153 - with working uas support +	 * +	 * Devices with these chips re-use a number of device-ids over the +	 * entire line, so the device-id is useless to determine if we're +	 * dealing with an ASM1051 (which we want to avoid). +	 * +	 * The ASM1153 can be identified by config.MaxPower == 0, +	 * where as the ASM105x models have config.MaxPower == 36. +	 * +	 * Differentiating between the ASM1053 and ASM1051 is trickier, when +	 * connected over USB-3 we can look at the number of streams supported, +	 * ASM1051 supports 32 streams, where as early ASM1053 versions support +	 * 16 streams, newer ASM1053-s also support 32 streams, but have a +	 * different prod-id. +	 * +	 * (*) ASM1051 chips do work with UAS with some disks (with the +	 *     US_FL_NO_REPORT_OPCODES quirk), but are broken with other disks  	 */  	if (le16_to_cpu(udev->descriptor.idVendor) == 0x174c && -			le16_to_cpu(udev->descriptor.idProduct) == 0x55aa) { -		if (udev->speed < USB_SPEED_SUPER) { +			(le16_to_cpu(udev->descriptor.idProduct) == 0x5106 || +			 le16_to_cpu(udev->descriptor.idProduct) == 0x55aa)) { +		if (udev->actconfig->desc.bMaxPower == 0) { +			/* ASM1153, do nothing */ +		} else if (udev->speed < USB_SPEED_SUPER) {  			/* No streams info, assume ASM1051 */  			flags |= US_FL_IGNORE_UAS;  		} else if (usb_ss_max_streams(&eps[1]->ss_ep_comp) == 32) { +			/* Possibly an ASM1051, disable uas */  			flags |= US_FL_IGNORE_UAS;  		}  	} diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index 18a283d6de1c..6df4357d9ee3 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h @@ -40,6 +40,16 @@   * and don't forget to CC: the USB development list <linux-usb@vger.kernel.org>   */ +/* + * Apricorn USB3 dongle sometimes returns "USBSUSBSUSBS" in response to SCSI + * commands in UAS mode.  Observed with the 1.28 firmware; are there others? + */ +UNUSUAL_DEV(0x0984, 0x0301, 0x0128, 0x0128, +		"Apricorn", +		"", +		USB_SC_DEVICE, USB_PR_DEVICE, NULL, +		US_FL_IGNORE_UAS), +  /* https://bugzilla.kernel.org/show_bug.cgi?id=79511 */  UNUSUAL_DEV(0x0bc2, 0x2312, 0x0000, 0x9999,  		"Seagate", @@ -68,6 +78,20 @@ UNUSUAL_DEV(0x0bc2, 0xa003, 0x0000, 0x9999,  		USB_SC_DEVICE, USB_PR_DEVICE, NULL,  		US_FL_NO_ATA_1X), +/* Reported-by: Marcin ZajÄ…czkowski <mszpak@wp.pl> */ +UNUSUAL_DEV(0x0bc2, 0xa013, 0x0000, 0x9999, +		"Seagate", +		"Backup Plus", +		USB_SC_DEVICE, USB_PR_DEVICE, NULL, +		US_FL_NO_ATA_1X), + +/* Reported-by: Hans de Goede <hdegoede@redhat.com> */ +UNUSUAL_DEV(0x0bc2, 0xa0a4, 0x0000, 0x9999, +		"Seagate", +		"Backup Plus Desk", +		USB_SC_DEVICE, USB_PR_DEVICE, NULL, +		US_FL_NO_ATA_1X), +  /* https://bbs.archlinux.org/viewtopic.php?id=183190 */  UNUSUAL_DEV(0x0bc2, 0xab20, 0x0000, 0x9999,  		"Seagate", @@ -82,6 +106,13 @@ UNUSUAL_DEV(0x0bc2, 0xab21, 0x0000, 0x9999,  		USB_SC_DEVICE, USB_PR_DEVICE, NULL,  		US_FL_NO_ATA_1X), +/* Reported-by: G. Richard Bellamy <rbellamy@pteradigm.com> */ +UNUSUAL_DEV(0x0bc2, 0xab2a, 0x0000, 0x9999, +		"Seagate", +		"BUP Fast HDD", +		USB_SC_DEVICE, USB_PR_DEVICE, NULL, +		US_FL_NO_ATA_1X), +  /* Reported-by: Claudio Bizzarri <claudio.bizzarri@gmail.com> */  UNUSUAL_DEV(0x152d, 0x0567, 0x0000, 0x9999,  		"JMicron", @@ -89,14 +120,6 @@ UNUSUAL_DEV(0x152d, 0x0567, 0x0000, 0x9999,  		USB_SC_DEVICE, USB_PR_DEVICE, NULL,  		US_FL_NO_REPORT_OPCODES), -/* Most ASM1051 based devices have issues with uas, blacklist them all */ -/* Reported-by: Hans de Goede <hdegoede@redhat.com> */ -UNUSUAL_DEV(0x174c, 0x5106, 0x0000, 0x9999, -		"ASMedia", -		"ASM1051", -		USB_SC_DEVICE, USB_PR_DEVICE, NULL, -		US_FL_IGNORE_UAS), -  /* Reported-by: Hans de Goede <hdegoede@redhat.com> */  UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999,  		"VIA", @@ -104,6 +127,13 @@ UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999,  		USB_SC_DEVICE, USB_PR_DEVICE, NULL,  		US_FL_NO_ATA_1X), +/* Reported-by: Takeo Nakayama <javhera@gmx.com> */ +UNUSUAL_DEV(0x357d, 0x7788, 0x0000, 0x9999, +		"JMicron", +		"JMS566", +		USB_SC_DEVICE, USB_PR_DEVICE, NULL, +		US_FL_NO_REPORT_OPCODES), +  /* Reported-by: Hans de Goede <hdegoede@redhat.com> */  UNUSUAL_DEV(0x4971, 0x1012, 0x0000, 0x9999,  		"Hitachi", diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index 255201f22126..7cc0122a18ce 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -840,13 +840,11 @@ static const struct vfio_device_ops vfio_pci_ops = {  static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)  { -	u8 type;  	struct vfio_pci_device *vdev;  	struct iommu_group *group;  	int ret; -	pci_read_config_byte(pdev, PCI_HEADER_TYPE, &type); -	if ((type & PCI_HEADER_TYPE) != PCI_HEADER_TYPE_NORMAL) +	if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL)  		return -EINVAL;  	group = iommu_group_get(&pdev->dev); diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 14419a8ccbb6..d415d69dc237 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -538,7 +538,7 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,  		++headcount;  		seg += in;  	} -	heads[headcount - 1].len = cpu_to_vhost32(vq, len - datalen); +	heads[headcount - 1].len = cpu_to_vhost32(vq, len + datalen);  	*iovcount = seg;  	if (unlikely(log))  		*log_num = nlogs; diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 01c01cb3933f..d695b1673ae5 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -911,6 +911,23 @@ vhost_scsi_map_iov_to_prot(struct tcm_vhost_cmd *cmd,  	return 0;  } +static int vhost_scsi_to_tcm_attr(int attr) +{ +	switch (attr) { +	case VIRTIO_SCSI_S_SIMPLE: +		return TCM_SIMPLE_TAG; +	case VIRTIO_SCSI_S_ORDERED: +		return TCM_ORDERED_TAG; +	case VIRTIO_SCSI_S_HEAD: +		return TCM_HEAD_TAG; +	case VIRTIO_SCSI_S_ACA: +		return TCM_ACA_TAG; +	default: +		break; +	} +	return TCM_SIMPLE_TAG; +} +  static void tcm_vhost_submission_work(struct work_struct *work)  {  	struct tcm_vhost_cmd *cmd = @@ -936,9 +953,10 @@ static void tcm_vhost_submission_work(struct work_struct *work)  	rc = target_submit_cmd_map_sgls(se_cmd, tv_nexus->tvn_se_sess,  			cmd->tvc_cdb, &cmd->tvc_sense_buf[0],  			cmd->tvc_lun, cmd->tvc_exp_data_len, -			cmd->tvc_task_attr, cmd->tvc_data_direction, -			TARGET_SCF_ACK_KREF, sg_ptr, cmd->tvc_sgl_count, -			NULL, 0, sg_prot_ptr, cmd->tvc_prot_sgl_count); +			vhost_scsi_to_tcm_attr(cmd->tvc_task_attr), +			cmd->tvc_data_direction, TARGET_SCF_ACK_KREF, +			sg_ptr, cmd->tvc_sgl_count, NULL, 0, sg_prot_ptr, +			cmd->tvc_prot_sgl_count);  	if (rc < 0) {  		transport_send_check_condition_and_sense(se_cmd,  				TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); diff --git a/drivers/video/fbdev/broadsheetfb.c b/drivers/video/fbdev/broadsheetfb.c index 1c29bd19e3d5..0e5fde1d3ffb 100644 --- a/drivers/video/fbdev/broadsheetfb.c +++ b/drivers/video/fbdev/broadsheetfb.c @@ -636,7 +636,7 @@ static int broadsheet_spiflash_rewrite_sector(struct broadsheetfb_par *par,  		err = broadsheet_spiflash_read_range(par, start_sector_addr,  						data_start_addr, sector_buffer);  		if (err) -			return err; +			goto out;  	}  	/* now we copy our data into the right place in the sector buffer */ @@ -657,7 +657,7 @@ static int broadsheet_spiflash_rewrite_sector(struct broadsheetfb_par *par,  		err = broadsheet_spiflash_read_range(par, tail_start_addr,  			tail_len, sector_buffer + tail_start_addr);  		if (err) -			return err; +			goto out;  	}  	/* if we got here we have the full sector that we want to rewrite. */ @@ -665,11 +665,13 @@ static int broadsheet_spiflash_rewrite_sector(struct broadsheetfb_par *par,  	/* first erase the sector */  	err = broadsheet_spiflash_erase_sector(par, start_sector_addr);  	if (err) -		return err; +		goto out;  	/* now write it */  	err = broadsheet_spiflash_write_sector(par, start_sector_addr,  					sector_buffer, sector_size); +out: +	kfree(sector_buffer);  	return err;  } diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c index 92cac803dee3..1085c0432158 100644 --- a/drivers/video/fbdev/simplefb.c +++ b/drivers/video/fbdev/simplefb.c @@ -402,7 +402,7 @@ static int __init simplefb_init(void)  	if (ret)  		return ret; -	if (IS_ENABLED(CONFIG_OF) && of_chosen) { +	if (IS_ENABLED(CONFIG_OF_ADDRESS) && of_chosen) {  		for_each_child_of_node(of_chosen, np) {  			if (of_device_is_compatible(np, "simple-framebuffer"))  				of_platform_device_create(np, NULL, NULL); diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c index 2ef9529809d8..9756f21b809e 100644 --- a/drivers/virtio/virtio_pci_common.c +++ b/drivers/virtio/virtio_pci_common.c @@ -282,6 +282,7 @@ void vp_del_vqs(struct virtio_device *vdev)  	vp_free_vectors(vdev);  	kfree(vp_dev->vqs); +	vp_dev->vqs = NULL;  }  static int vp_try_to_find_vqs(struct virtio_device *vdev, unsigned nvqs, @@ -421,15 +422,6 @@ int vp_set_vq_affinity(struct virtqueue *vq, int cpu)  	return 0;  } -void virtio_pci_release_dev(struct device *_d) -{ -	/* -	 * No need for a release method as we allocate/free -	 * all devices together with the pci devices. -	 * Provide an empty one to avoid getting a warning from core. -	 */ -} -  #ifdef CONFIG_PM_SLEEP  static int virtio_pci_freeze(struct device *dev)  { diff --git a/drivers/virtio/virtio_pci_common.h b/drivers/virtio/virtio_pci_common.h index adddb647b21d..5a497289b7e9 100644 --- a/drivers/virtio/virtio_pci_common.h +++ b/drivers/virtio/virtio_pci_common.h @@ -126,7 +126,6 @@ const char *vp_bus_name(struct virtio_device *vdev);   * - ignore the affinity request if we're using INTX   */  int vp_set_vq_affinity(struct virtqueue *vq, int cpu); -void virtio_pci_release_dev(struct device *);  int virtio_pci_legacy_probe(struct pci_dev *pci_dev,  			    const struct pci_device_id *id); diff --git a/drivers/virtio/virtio_pci_legacy.c b/drivers/virtio/virtio_pci_legacy.c index 6c76f0f5658c..a5486e65e04b 100644 --- a/drivers/virtio/virtio_pci_legacy.c +++ b/drivers/virtio/virtio_pci_legacy.c @@ -211,6 +211,17 @@ static const struct virtio_config_ops virtio_pci_config_ops = {  	.set_vq_affinity = vp_set_vq_affinity,  }; +static void virtio_pci_release_dev(struct device *_d) +{ +	struct virtio_device *vdev = dev_to_virtio(_d); +	struct virtio_pci_device *vp_dev = to_vp_device(vdev); + +	/* As struct device is a kobject, it's not safe to +	 * free the memory (including the reference counter itself) +	 * until it's release callback. */ +	kfree(vp_dev); +} +  /* the PCI probing function */  int virtio_pci_legacy_probe(struct pci_dev *pci_dev,  			    const struct pci_device_id *id) @@ -302,5 +313,4 @@ void virtio_pci_legacy_remove(struct pci_dev *pci_dev)  	pci_iounmap(pci_dev, vp_dev->ioaddr);  	pci_release_regions(pci_dev);  	pci_disable_device(pci_dev); -	kfree(vp_dev);  } | 
