Skip to content

Commit 9f66d83

Browse files
author
Jiri Kosina
committed
Merge branch 'for-5.1/i2c-hid' into for-linus
Fix dmesg flood for Elan touchpanels which are too slow to assert IRQ from Kai-Heng Feng
2 parents edaea3d + 09cc8b3 commit 9f66d83

File tree

6 files changed

+55
-84
lines changed

6 files changed

+55
-84
lines changed

drivers/hid/i2c-hid/i2c-hid-core.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1)
5151
#define I2C_HID_QUIRK_NO_RUNTIME_PM BIT(2)
5252
#define I2C_HID_QUIRK_DELAY_AFTER_SLEEP BIT(3)
53+
#define I2C_HID_QUIRK_BOGUS_IRQ BIT(4)
5354

5455
/* flags */
5556
#define I2C_HID_STARTED 0
@@ -181,6 +182,8 @@ static const struct i2c_hid_quirks {
181182
I2C_HID_QUIRK_NO_RUNTIME_PM },
182183
{ I2C_VENDOR_ID_GOODIX, I2C_DEVICE_ID_GOODIX_01F0,
183184
I2C_HID_QUIRK_NO_RUNTIME_PM },
185+
{ USB_VENDOR_ID_ELAN, HID_ANY_ID,
186+
I2C_HID_QUIRK_BOGUS_IRQ },
184187
{ 0, 0 }
185188
};
186189

@@ -505,6 +508,12 @@ static void i2c_hid_get_input(struct i2c_hid *ihid)
505508
return;
506509
}
507510

511+
if (ihid->quirks & I2C_HID_QUIRK_BOGUS_IRQ && ret_size == 0xffff) {
512+
dev_warn_once(&ihid->client->dev, "%s: IRQ triggered but "
513+
"there's no data\n", __func__);
514+
return;
515+
}
516+
508517
if ((ret_size > size) || (ret_size < 2)) {
509518
dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n",
510519
__func__, size, ret_size);

drivers/hid/intel-ish-hid/ipc/ipc.c

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -259,33 +259,22 @@ static int write_ipc_from_queue(struct ishtp_device *dev)
259259
int i;
260260
void (*ipc_send_compl)(void *);
261261
void *ipc_send_compl_prm;
262-
static int out_ipc_locked;
263-
unsigned long out_ipc_flags;
264262

265263
if (dev->dev_state == ISHTP_DEV_DISABLED)
266-
return -EINVAL;
264+
return -EINVAL;
267265

268-
spin_lock_irqsave(&dev->out_ipc_spinlock, out_ipc_flags);
269-
if (out_ipc_locked) {
270-
spin_unlock_irqrestore(&dev->out_ipc_spinlock, out_ipc_flags);
271-
return -EBUSY;
272-
}
273-
out_ipc_locked = 1;
266+
spin_lock_irqsave(&dev->wr_processing_spinlock, flags);
274267
if (!ish_is_input_ready(dev)) {
275-
out_ipc_locked = 0;
276-
spin_unlock_irqrestore(&dev->out_ipc_spinlock, out_ipc_flags);
268+
spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags);
277269
return -EBUSY;
278270
}
279-
spin_unlock_irqrestore(&dev->out_ipc_spinlock, out_ipc_flags);
280271

281-
spin_lock_irqsave(&dev->wr_processing_spinlock, flags);
282272
/*
283273
* if tx send list is empty - return 0;
284274
* may happen, as RX_COMPLETE handler doesn't check list emptiness.
285275
*/
286276
if (list_empty(&dev->wr_processing_list)) {
287277
spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags);
288-
out_ipc_locked = 0;
289278
return 0;
290279
}
291280

@@ -328,16 +317,15 @@ static int write_ipc_from_queue(struct ishtp_device *dev)
328317
memcpy(&reg, &r_buf[length >> 2], rem);
329318
ish_reg_write(dev, reg_addr, reg);
330319
}
320+
ish_reg_write(dev, IPC_REG_HOST2ISH_DRBL, doorbell_val);
321+
331322
/* Flush writes to msg registers and doorbell */
332323
ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS);
333324

334325
/* Update IPC counters */
335326
++dev->ipc_tx_cnt;
336327
dev->ipc_tx_bytes_cnt += IPC_HEADER_GET_LENGTH(doorbell_val);
337328

338-
ish_reg_write(dev, IPC_REG_HOST2ISH_DRBL, doorbell_val);
339-
out_ipc_locked = 0;
340-
341329
ipc_send_compl = ipc_link->ipc_send_compl;
342330
ipc_send_compl_prm = ipc_link->ipc_send_compl_prm;
343331
list_del_init(&ipc_link->link);
@@ -917,7 +905,6 @@ struct ishtp_device *ish_dev_init(struct pci_dev *pdev)
917905
init_waitqueue_head(&dev->wait_hw_ready);
918906

919907
spin_lock_init(&dev->wr_processing_spinlock);
920-
spin_lock_init(&dev->out_ipc_spinlock);
921908

922909
/* Init IPC processing and free lists */
923910
INIT_LIST_HEAD(&dev->wr_processing_list);

drivers/hid/intel-ish-hid/ishtp/bus.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ int ishtp_send_msg(struct ishtp_device *dev, struct ishtp_msg_hdr *hdr,
119119
* Return: This returns IPC send message status.
120120
*/
121121
int ishtp_write_message(struct ishtp_device *dev, struct ishtp_msg_hdr *hdr,
122-
unsigned char *buf)
122+
void *buf)
123123
{
124124
return ishtp_send_msg(dev, hdr, buf, NULL, NULL);
125125
}
@@ -672,7 +672,8 @@ int ishtp_cl_device_bind(struct ishtp_cl *cl)
672672
spin_lock_irqsave(&cl->dev->device_list_lock, flags);
673673
list_for_each_entry(cl_device, &cl->dev->device_list,
674674
device_link) {
675-
if (cl_device->fw_client->client_id == cl->fw_client_id) {
675+
if (cl_device->fw_client &&
676+
cl_device->fw_client->client_id == cl->fw_client_id) {
676677
cl->device = cl_device;
677678
rv = 0;
678679
break;
@@ -732,6 +733,7 @@ void ishtp_bus_remove_all_clients(struct ishtp_device *ishtp_dev,
732733
spin_lock_irqsave(&ishtp_dev->device_list_lock, flags);
733734
list_for_each_entry_safe(cl_device, n, &ishtp_dev->device_list,
734735
device_link) {
736+
cl_device->fw_client = NULL;
735737
if (warm_reset && cl_device->reference_count)
736738
continue;
737739

drivers/hid/intel-ish-hid/ishtp/bus.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ int ishtp_send_msg(struct ishtp_device *dev,
8585
/* Write a single-fragment message */
8686
int ishtp_write_message(struct ishtp_device *dev,
8787
struct ishtp_msg_hdr *hdr,
88-
unsigned char *buf);
88+
void *buf);
8989

9090
/* Use DMA to send/receive messages */
9191
int ishtp_use_dma_transfer(void);

drivers/hid/intel-ish-hid/ishtp/hbm.c

Lines changed: 36 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -136,27 +136,22 @@ int ishtp_hbm_start_wait(struct ishtp_device *dev)
136136
int ishtp_hbm_start_req(struct ishtp_device *dev)
137137
{
138138
struct ishtp_msg_hdr hdr;
139-
unsigned char data[128];
140-
struct ishtp_msg_hdr *ishtp_hdr = &hdr;
141-
struct hbm_host_version_request *start_req;
142-
const size_t len = sizeof(struct hbm_host_version_request);
139+
struct hbm_host_version_request start_req = { 0 };
143140

144-
ishtp_hbm_hdr(ishtp_hdr, len);
141+
ishtp_hbm_hdr(&hdr, sizeof(start_req));
145142

146143
/* host start message */
147-
start_req = (struct hbm_host_version_request *)data;
148-
memset(start_req, 0, len);
149-
start_req->hbm_cmd = HOST_START_REQ_CMD;
150-
start_req->host_version.major_version = HBM_MAJOR_VERSION;
151-
start_req->host_version.minor_version = HBM_MINOR_VERSION;
144+
start_req.hbm_cmd = HOST_START_REQ_CMD;
145+
start_req.host_version.major_version = HBM_MAJOR_VERSION;
146+
start_req.host_version.minor_version = HBM_MINOR_VERSION;
152147

153148
/*
154149
* (!) Response to HBM start may be so quick that this thread would get
155150
* preempted BEFORE managing to set hbm_state = ISHTP_HBM_START.
156151
* So set it at first, change back to ISHTP_HBM_IDLE upon failure
157152
*/
158153
dev->hbm_state = ISHTP_HBM_START;
159-
if (ishtp_write_message(dev, ishtp_hdr, data)) {
154+
if (ishtp_write_message(dev, &hdr, &start_req)) {
160155
dev_err(dev->devc, "version message send failed\n");
161156
dev->dev_state = ISHTP_DEV_RESETTING;
162157
dev->hbm_state = ISHTP_HBM_IDLE;
@@ -178,19 +173,13 @@ int ishtp_hbm_start_req(struct ishtp_device *dev)
178173
void ishtp_hbm_enum_clients_req(struct ishtp_device *dev)
179174
{
180175
struct ishtp_msg_hdr hdr;
181-
unsigned char data[128];
182-
struct ishtp_msg_hdr *ishtp_hdr = &hdr;
183-
struct hbm_host_enum_request *enum_req;
184-
const size_t len = sizeof(struct hbm_host_enum_request);
176+
struct hbm_host_enum_request enum_req = { 0 };
185177

186178
/* enumerate clients */
187-
ishtp_hbm_hdr(ishtp_hdr, len);
179+
ishtp_hbm_hdr(&hdr, sizeof(enum_req));
180+
enum_req.hbm_cmd = HOST_ENUM_REQ_CMD;
188181

189-
enum_req = (struct hbm_host_enum_request *)data;
190-
memset(enum_req, 0, len);
191-
enum_req->hbm_cmd = HOST_ENUM_REQ_CMD;
192-
193-
if (ishtp_write_message(dev, ishtp_hdr, data)) {
182+
if (ishtp_write_message(dev, &hdr, &enum_req)) {
194183
dev->dev_state = ISHTP_DEV_RESETTING;
195184
dev_err(dev->devc, "enumeration request send failed\n");
196185
ish_hw_reset(dev);
@@ -208,12 +197,8 @@ void ishtp_hbm_enum_clients_req(struct ishtp_device *dev)
208197
*/
209198
static int ishtp_hbm_prop_req(struct ishtp_device *dev)
210199
{
211-
212200
struct ishtp_msg_hdr hdr;
213-
unsigned char data[128];
214-
struct ishtp_msg_hdr *ishtp_hdr = &hdr;
215-
struct hbm_props_request *prop_req;
216-
const size_t len = sizeof(struct hbm_props_request);
201+
struct hbm_props_request prop_req = { 0 };
217202
unsigned long next_client_index;
218203
uint8_t client_num;
219204

@@ -237,15 +222,12 @@ static int ishtp_hbm_prop_req(struct ishtp_device *dev)
237222

238223
dev->fw_clients[client_num].client_id = next_client_index;
239224

240-
ishtp_hbm_hdr(ishtp_hdr, len);
241-
prop_req = (struct hbm_props_request *)data;
225+
ishtp_hbm_hdr(&hdr, sizeof(prop_req));
242226

243-
memset(prop_req, 0, sizeof(struct hbm_props_request));
227+
prop_req.hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
228+
prop_req.address = next_client_index;
244229

245-
prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
246-
prop_req->address = next_client_index;
247-
248-
if (ishtp_write_message(dev, ishtp_hdr, data)) {
230+
if (ishtp_write_message(dev, &hdr, &prop_req)) {
249231
dev->dev_state = ISHTP_DEV_RESETTING;
250232
dev_err(dev->devc, "properties request send failed\n");
251233
ish_hw_reset(dev);
@@ -266,19 +248,14 @@ static int ishtp_hbm_prop_req(struct ishtp_device *dev)
266248
static void ishtp_hbm_stop_req(struct ishtp_device *dev)
267249
{
268250
struct ishtp_msg_hdr hdr;
269-
unsigned char data[128];
270-
struct ishtp_msg_hdr *ishtp_hdr = &hdr;
271-
struct hbm_host_stop_request *req;
272-
const size_t len = sizeof(struct hbm_host_stop_request);
251+
struct hbm_host_stop_request stop_req = { 0 } ;
273252

274-
ishtp_hbm_hdr(ishtp_hdr, len);
275-
req = (struct hbm_host_stop_request *)data;
253+
ishtp_hbm_hdr(&hdr, sizeof(stop_req));
276254

277-
memset(req, 0, sizeof(struct hbm_host_stop_request));
278-
req->hbm_cmd = HOST_STOP_REQ_CMD;
279-
req->reason = DRIVER_STOP_REQUEST;
255+
stop_req.hbm_cmd = HOST_STOP_REQ_CMD;
256+
stop_req.reason = DRIVER_STOP_REQUEST;
280257

281-
ishtp_write_message(dev, ishtp_hdr, data);
258+
ishtp_write_message(dev, &hdr, &stop_req);
282259
}
283260

284261
/**
@@ -294,15 +271,15 @@ int ishtp_hbm_cl_flow_control_req(struct ishtp_device *dev,
294271
struct ishtp_cl *cl)
295272
{
296273
struct ishtp_msg_hdr hdr;
297-
unsigned char data[128];
298-
struct ishtp_msg_hdr *ishtp_hdr = &hdr;
299-
const size_t len = sizeof(struct hbm_flow_control);
274+
struct hbm_flow_control flow_ctrl;
275+
const size_t len = sizeof(flow_ctrl);
300276
int rv;
301277
unsigned long flags;
302278

303279
spin_lock_irqsave(&cl->fc_spinlock, flags);
304-
ishtp_hbm_hdr(ishtp_hdr, len);
305-
ishtp_hbm_cl_hdr(cl, ISHTP_FLOW_CONTROL_CMD, data, len);
280+
281+
ishtp_hbm_hdr(&hdr, len);
282+
ishtp_hbm_cl_hdr(cl, ISHTP_FLOW_CONTROL_CMD, &flow_ctrl, len);
306283

307284
/*
308285
* Sync possible race when RB recycle and packet receive paths
@@ -315,7 +292,7 @@ int ishtp_hbm_cl_flow_control_req(struct ishtp_device *dev,
315292

316293
cl->recv_msg_num_frags = 0;
317294

318-
rv = ishtp_write_message(dev, ishtp_hdr, data);
295+
rv = ishtp_write_message(dev, &hdr, &flow_ctrl);
319296
if (!rv) {
320297
++cl->out_flow_ctrl_creds;
321298
++cl->out_flow_ctrl_cnt;
@@ -345,14 +322,13 @@ int ishtp_hbm_cl_flow_control_req(struct ishtp_device *dev,
345322
int ishtp_hbm_cl_disconnect_req(struct ishtp_device *dev, struct ishtp_cl *cl)
346323
{
347324
struct ishtp_msg_hdr hdr;
348-
unsigned char data[128];
349-
struct ishtp_msg_hdr *ishtp_hdr = &hdr;
350-
const size_t len = sizeof(struct hbm_client_connect_request);
325+
struct hbm_client_connect_request disconn_req;
326+
const size_t len = sizeof(disconn_req);
351327

352-
ishtp_hbm_hdr(ishtp_hdr, len);
353-
ishtp_hbm_cl_hdr(cl, CLIENT_DISCONNECT_REQ_CMD, data, len);
328+
ishtp_hbm_hdr(&hdr, len);
329+
ishtp_hbm_cl_hdr(cl, CLIENT_DISCONNECT_REQ_CMD, &disconn_req, len);
354330

355-
return ishtp_write_message(dev, ishtp_hdr, data);
331+
return ishtp_write_message(dev, &hdr, &disconn_req);
356332
}
357333

358334
/**
@@ -391,14 +367,13 @@ static void ishtp_hbm_cl_disconnect_res(struct ishtp_device *dev,
391367
int ishtp_hbm_cl_connect_req(struct ishtp_device *dev, struct ishtp_cl *cl)
392368
{
393369
struct ishtp_msg_hdr hdr;
394-
unsigned char data[128];
395-
struct ishtp_msg_hdr *ishtp_hdr = &hdr;
396-
const size_t len = sizeof(struct hbm_client_connect_request);
370+
struct hbm_client_connect_request conn_req;
371+
const size_t len = sizeof(conn_req);
397372

398-
ishtp_hbm_hdr(ishtp_hdr, len);
399-
ishtp_hbm_cl_hdr(cl, CLIENT_CONNECT_REQ_CMD, data, len);
373+
ishtp_hbm_hdr(&hdr, len);
374+
ishtp_hbm_cl_hdr(cl, CLIENT_CONNECT_REQ_CMD, &conn_req, len);
400375

401-
return ishtp_write_message(dev, ishtp_hdr, data);
376+
return ishtp_write_message(dev, &hdr, &conn_req);
402377
}
403378

404379
/**

drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,6 @@ struct ishtp_device {
211211
/* For both processing list and free list */
212212
spinlock_t wr_processing_spinlock;
213213

214-
spinlock_t out_ipc_spinlock;
215-
216214
struct ishtp_fw_client *fw_clients; /*Note:memory has to be allocated*/
217215
DECLARE_BITMAP(fw_clients_map, ISHTP_CLIENTS_MAX);
218216
DECLARE_BITMAP(host_clients_map, ISHTP_CLIENTS_MAX);

0 commit comments

Comments
 (0)