Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c1f4c2b2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull HID fixes from Jiri Kosina:

 - modprobe-after-rmmod load failure bugfix for intel-ish, from Even Xu

 - IRQ probing bugfix for intel-ish, from Srinivas Pandruvada

 - attribute parsing fix in hid-sensor, from Ooi, Joyce

 - other small misc fixes / quirky device additions

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid:
  HID: sensor: fix attributes in HID sensor interface
  HID: intel-ish-hid: request_irq failure
  HID: intel-ish-hid: Fix driver reinit failure
  HID: intel-ish-hid: Move DMA disable code to new function
  HID: intel-ish-hid: consolidate ish wake up operation
  HID: usbhid: add ATEN CS962 to list of quirky devices
  HID: intel-ish-hid: Fix !CONFIG_PM build warning
  HID: sensor-hub: Fix packing of result buffer for feature report
parents bc33b0ca 4c4480aa
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -179,6 +179,7 @@
#define USB_DEVICE_ID_ATEN_4PORTKVM	0x2205
#define USB_DEVICE_ID_ATEN_4PORTKVMC	0x2208
#define USB_DEVICE_ID_ATEN_CS682	0x2213
#define USB_DEVICE_ID_ATEN_CS692	0x8021

#define USB_VENDOR_ID_ATMEL		0x03eb
#define USB_DEVICE_ID_ATMEL_MULTITOUCH	0x211c
+3 −3
Original line number Diff line number Diff line
@@ -292,11 +292,11 @@ static ssize_t show_value(struct device *dev, struct device_attribute *attr,
	bool input = false;
	int value = 0;

	if (sscanf(attr->attr.name, "feature-%d-%x-%s", &index, &usage,
	if (sscanf(attr->attr.name, "feature-%x-%x-%s", &index, &usage,
		   name) == 3) {
		feature = true;
		field_index = index + sensor_inst->input_field_count;
	} else if (sscanf(attr->attr.name, "input-%d-%x-%s", &index, &usage,
	} else if (sscanf(attr->attr.name, "input-%x-%x-%s", &index, &usage,
		   name) == 3) {
		input = true;
		field_index = index;
@@ -398,7 +398,7 @@ static ssize_t store_value(struct device *dev, struct device_attribute *attr,
	char name[HID_CUSTOM_NAME_LENGTH];
	int value;

	if (sscanf(attr->attr.name, "feature-%d-%x-%s", &index, &usage,
	if (sscanf(attr->attr.name, "feature-%x-%x-%s", &index, &usage,
		   name) == 3) {
		field_index = index + sensor_inst->input_field_count;
	} else
+14 −1
Original line number Diff line number Diff line
@@ -251,6 +251,9 @@ int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
	struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
	int report_size;
	int ret = 0;
	u8 *val_ptr;
	int buffer_index = 0;
	int i;

	mutex_lock(&data->mutex);
	report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT);
@@ -271,7 +274,17 @@ int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
		goto done_proc;
	}
	ret = min(report_size, buffer_size);
	memcpy(buffer, report->field[field_index]->value, ret);

	val_ptr = (u8 *)report->field[field_index]->value;
	for (i = 0; i < report->field[field_index]->report_count; ++i) {
		if (buffer_index >= ret)
			break;

		memcpy(&((u8 *)buffer)[buffer_index], val_ptr,
		       report->field[field_index]->report_size / 8);
		val_ptr += sizeof(__s32);
		buffer_index += (report->field[field_index]->report_size / 8);
	}

done_proc:
	mutex_unlock(&data->mutex);
+73 −29
Original line number Diff line number Diff line
@@ -637,6 +637,58 @@ irqreturn_t ish_irq_handler(int irq, void *dev_id)
	return	IRQ_HANDLED;
}

/**
 * ish_disable_dma() - disable dma communication between host and ISHFW
 * @dev: ishtp device pointer
 *
 * Clear the dma enable bit and wait for dma inactive.
 *
 * Return: 0 for success else error code.
 */
static int ish_disable_dma(struct ishtp_device *dev)
{
	unsigned int	dma_delay;

	/* Clear the dma enable bit */
	ish_reg_write(dev, IPC_REG_ISH_RMP2, 0);

	/* wait for dma inactive */
	for (dma_delay = 0; dma_delay < MAX_DMA_DELAY &&
		_ish_read_fw_sts_reg(dev) & (IPC_ISH_IN_DMA);
		dma_delay += 5)
		mdelay(5);

	if (dma_delay >= MAX_DMA_DELAY) {
		dev_err(dev->devc,
			"Wait for DMA inactive timeout\n");
		return	-EBUSY;
	}

	return 0;
}

/**
 * ish_wakeup() - wakeup ishfw from waiting-for-host state
 * @dev: ishtp device pointer
 *
 * Set the dma enable bit and send a void message to FW,
 * it wil wakeup FW from waiting-for-host state.
 */
static void ish_wakeup(struct ishtp_device *dev)
{
	/* Set dma enable bit */
	ish_reg_write(dev, IPC_REG_ISH_RMP2, IPC_RMP2_DMA_ENABLED);

	/*
	 * Send 0 IPC message so that ISH FW wakes up if it was already
	 * asleep.
	 */
	ish_reg_write(dev, IPC_REG_HOST2ISH_DRBL, IPC_DRBL_BUSY_BIT);

	/* Flush writes to doorbell and REMAP2 */
	ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS);
}

/**
 * _ish_hw_reset() - HW reset
 * @dev: ishtp device pointer
@@ -649,7 +701,6 @@ static int _ish_hw_reset(struct ishtp_device *dev)
{
	struct pci_dev *pdev = dev->pdev;
	int	rv;
	unsigned int	dma_delay;
	uint16_t csr;

	if (!pdev)
@@ -664,15 +715,8 @@ static int _ish_hw_reset(struct ishtp_device *dev)
		return	-EINVAL;
	}

	/* Now trigger reset to FW */
	ish_reg_write(dev, IPC_REG_ISH_RMP2, 0);

	for (dma_delay = 0; dma_delay < MAX_DMA_DELAY &&
		_ish_read_fw_sts_reg(dev) & (IPC_ISH_IN_DMA);
		dma_delay += 5)
		mdelay(5);

	if (dma_delay >= MAX_DMA_DELAY) {
	/* Disable dma communication between FW and host */
	if (ish_disable_dma(dev)) {
		dev_err(&pdev->dev,
			"Can't reset - stuck with DMA in-progress\n");
		return	-EBUSY;
@@ -690,16 +734,8 @@ static int _ish_hw_reset(struct ishtp_device *dev)
	csr |= PCI_D0;
	pci_write_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, csr);

	ish_reg_write(dev, IPC_REG_ISH_RMP2, IPC_RMP2_DMA_ENABLED);

	/*
	 * Send 0 IPC message so that ISH FW wakes up if it was already
	 * asleep
	 */
	ish_reg_write(dev, IPC_REG_HOST2ISH_DRBL, IPC_DRBL_BUSY_BIT);

	/* Flush writes to doorbell and REMAP2 */
	ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS);
	/* Now we can enable ISH DMA operation and wakeup ISHFW */
	ish_wakeup(dev);

	return	0;
}
@@ -758,16 +794,9 @@ static int _ish_ipc_reset(struct ishtp_device *dev)
int ish_hw_start(struct ishtp_device *dev)
{
	ish_set_host_rdy(dev);
	/* After that we can enable ISH DMA operation */
	ish_reg_write(dev, IPC_REG_ISH_RMP2, IPC_RMP2_DMA_ENABLED);

	/*
	 * Send 0 IPC message so that ISH FW wakes up if it was already
	 * asleep
	 */
	ish_reg_write(dev, IPC_REG_HOST2ISH_DRBL, IPC_DRBL_BUSY_BIT);
	/* Flush write to doorbell */
	ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS);
	/* After that we can enable ISH DMA operation and wakeup ISHFW */
	ish_wakeup(dev);

	set_host_ready(dev);

@@ -876,6 +905,21 @@ struct ishtp_device *ish_dev_init(struct pci_dev *pdev)
 */
void	ish_device_disable(struct ishtp_device *dev)
{
	struct pci_dev *pdev = dev->pdev;

	if (!pdev)
		return;

	/* Disable dma communication between FW and host */
	if (ish_disable_dma(dev)) {
		dev_err(&pdev->dev,
			"Can't reset - stuck with DMA in-progress\n");
		return;
	}

	/* Put ISH to D3hot state for power saving */
	pci_set_power_state(pdev, PCI_D3hot);

	dev->dev_state = ISHTP_DEV_DISABLED;
	ish_clr_host_rdy(dev);
}
+3 −3
Original line number Diff line number Diff line
@@ -146,7 +146,7 @@ static int ish_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
	pdev->dev_flags |= PCI_DEV_FLAGS_NO_D3;

	/* request and enable interrupt */
	ret = request_irq(pdev->irq, ish_irq_handler, IRQF_NO_SUSPEND,
	ret = request_irq(pdev->irq, ish_irq_handler, IRQF_SHARED,
			  KBUILD_MODNAME, dev);
	if (ret) {
		dev_err(&pdev->dev, "ISH: request IRQ failure (%d)\n",
@@ -202,6 +202,7 @@ static void ish_remove(struct pci_dev *pdev)
	kfree(ishtp_dev);
}

#ifdef CONFIG_PM
static struct device *ish_resume_device;

/**
@@ -293,7 +294,6 @@ static int ish_resume(struct device *device)
	return 0;
}

#ifdef CONFIG_PM
static const struct dev_pm_ops ish_pm_ops = {
	.suspend = ish_suspend,
	.resume = ish_resume,
@@ -301,7 +301,7 @@ static const struct dev_pm_ops ish_pm_ops = {
#define ISHTP_ISH_PM_OPS	(&ish_pm_ops)
#else
#define ISHTP_ISH_PM_OPS	NULL
#endif
#endif /* CONFIG_PM */

static struct pci_driver ish_driver = {
	.name = KBUILD_MODNAME,
Loading