summaryrefslogtreecommitdiffstats
path: root/drivers/hid/intel-ish-hid
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2019-03-05 09:42:51 -0500
committerJiri Kosina <jkosina@suse.cz>2019-03-05 09:42:51 -0500
commit9f66d83ed704bc9ac0f09eb744f8e76a81006eb9 (patch)
treee9a9a84797e440bb14c340d8671159cffe535cc4 /drivers/hid/intel-ish-hid
parentedaea3d904af805545073070307ca5f3afce4e18 (diff)
parent09cc8b361887787a3577aa0b6510af4b11b51b9e (diff)
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
Diffstat (limited to 'drivers/hid/intel-ish-hid')
-rw-r--r--drivers/hid/intel-ish-hid/ipc/ipc.c23
-rw-r--r--drivers/hid/intel-ish-hid/ishtp/bus.c6
-rw-r--r--drivers/hid/intel-ish-hid/ishtp/bus.h2
-rw-r--r--drivers/hid/intel-ish-hid/ishtp/hbm.c97
-rw-r--r--drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h2
5 files changed, 46 insertions, 84 deletions
diff --git a/drivers/hid/intel-ish-hid/ipc/ipc.c b/drivers/hid/intel-ish-hid/ipc/ipc.c
index 45e33c7ba9a6..96e869118db3 100644
--- a/drivers/hid/intel-ish-hid/ipc/ipc.c
+++ b/drivers/hid/intel-ish-hid/ipc/ipc.c
@@ -259,33 +259,22 @@ static int write_ipc_from_queue(struct ishtp_device *dev)
259 int i; 259 int i;
260 void (*ipc_send_compl)(void *); 260 void (*ipc_send_compl)(void *);
261 void *ipc_send_compl_prm; 261 void *ipc_send_compl_prm;
262 static int out_ipc_locked;
263 unsigned long out_ipc_flags;
264 262
265 if (dev->dev_state == ISHTP_DEV_DISABLED) 263 if (dev->dev_state == ISHTP_DEV_DISABLED)
266 return -EINVAL; 264 return -EINVAL;
267 265
268 spin_lock_irqsave(&dev->out_ipc_spinlock, out_ipc_flags); 266 spin_lock_irqsave(&dev->wr_processing_spinlock, 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;
274 if (!ish_is_input_ready(dev)) { 267 if (!ish_is_input_ready(dev)) {
275 out_ipc_locked = 0; 268 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags);
276 spin_unlock_irqrestore(&dev->out_ipc_spinlock, out_ipc_flags);
277 return -EBUSY; 269 return -EBUSY;
278 } 270 }
279 spin_unlock_irqrestore(&dev->out_ipc_spinlock, out_ipc_flags);
280 271
281 spin_lock_irqsave(&dev->wr_processing_spinlock, flags);
282 /* 272 /*
283 * if tx send list is empty - return 0; 273 * if tx send list is empty - return 0;
284 * may happen, as RX_COMPLETE handler doesn't check list emptiness. 274 * may happen, as RX_COMPLETE handler doesn't check list emptiness.
285 */ 275 */
286 if (list_empty(&dev->wr_processing_list)) { 276 if (list_empty(&dev->wr_processing_list)) {
287 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags); 277 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags);
288 out_ipc_locked = 0;
289 return 0; 278 return 0;
290 } 279 }
291 280
@@ -328,6 +317,8 @@ static int write_ipc_from_queue(struct ishtp_device *dev)
328 memcpy(&reg, &r_buf[length >> 2], rem); 317 memcpy(&reg, &r_buf[length >> 2], rem);
329 ish_reg_write(dev, reg_addr, reg); 318 ish_reg_write(dev, reg_addr, reg);
330 } 319 }
320 ish_reg_write(dev, IPC_REG_HOST2ISH_DRBL, doorbell_val);
321
331 /* Flush writes to msg registers and doorbell */ 322 /* Flush writes to msg registers and doorbell */
332 ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS); 323 ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS);
333 324
@@ -335,9 +326,6 @@ static int write_ipc_from_queue(struct ishtp_device *dev)
335 ++dev->ipc_tx_cnt; 326 ++dev->ipc_tx_cnt;
336 dev->ipc_tx_bytes_cnt += IPC_HEADER_GET_LENGTH(doorbell_val); 327 dev->ipc_tx_bytes_cnt += IPC_HEADER_GET_LENGTH(doorbell_val);
337 328
338 ish_reg_write(dev, IPC_REG_HOST2ISH_DRBL, doorbell_val);
339 out_ipc_locked = 0;
340
341 ipc_send_compl = ipc_link->ipc_send_compl; 329 ipc_send_compl = ipc_link->ipc_send_compl;
342 ipc_send_compl_prm = ipc_link->ipc_send_compl_prm; 330 ipc_send_compl_prm = ipc_link->ipc_send_compl_prm;
343 list_del_init(&ipc_link->link); 331 list_del_init(&ipc_link->link);
@@ -917,7 +905,6 @@ struct ishtp_device *ish_dev_init(struct pci_dev *pdev)
917 init_waitqueue_head(&dev->wait_hw_ready); 905 init_waitqueue_head(&dev->wait_hw_ready);
918 906
919 spin_lock_init(&dev->wr_processing_spinlock); 907 spin_lock_init(&dev->wr_processing_spinlock);
920 spin_lock_init(&dev->out_ipc_spinlock);
921 908
922 /* Init IPC processing and free lists */ 909 /* Init IPC processing and free lists */
923 INIT_LIST_HEAD(&dev->wr_processing_list); 910 INIT_LIST_HEAD(&dev->wr_processing_list);
diff --git a/drivers/hid/intel-ish-hid/ishtp/bus.c b/drivers/hid/intel-ish-hid/ishtp/bus.c
index efa21d33ad60..d5f4b6438d86 100644
--- a/drivers/hid/intel-ish-hid/ishtp/bus.c
+++ b/drivers/hid/intel-ish-hid/ishtp/bus.c
@@ -119,7 +119,7 @@ int ishtp_send_msg(struct ishtp_device *dev, struct ishtp_msg_hdr *hdr,
119 * Return: This returns IPC send message status. 119 * Return: This returns IPC send message status.
120 */ 120 */
121int ishtp_write_message(struct ishtp_device *dev, struct ishtp_msg_hdr *hdr, 121int ishtp_write_message(struct ishtp_device *dev, struct ishtp_msg_hdr *hdr,
122 unsigned char *buf) 122 void *buf)
123{ 123{
124 return ishtp_send_msg(dev, hdr, buf, NULL, NULL); 124 return ishtp_send_msg(dev, hdr, buf, NULL, NULL);
125} 125}
@@ -672,7 +672,8 @@ int ishtp_cl_device_bind(struct ishtp_cl *cl)
672 spin_lock_irqsave(&cl->dev->device_list_lock, flags); 672 spin_lock_irqsave(&cl->dev->device_list_lock, flags);
673 list_for_each_entry(cl_device, &cl->dev->device_list, 673 list_for_each_entry(cl_device, &cl->dev->device_list,
674 device_link) { 674 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) {
676 cl->device = cl_device; 677 cl->device = cl_device;
677 rv = 0; 678 rv = 0;
678 break; 679 break;
@@ -732,6 +733,7 @@ void ishtp_bus_remove_all_clients(struct ishtp_device *ishtp_dev,
732 spin_lock_irqsave(&ishtp_dev->device_list_lock, flags); 733 spin_lock_irqsave(&ishtp_dev->device_list_lock, flags);
733 list_for_each_entry_safe(cl_device, n, &ishtp_dev->device_list, 734 list_for_each_entry_safe(cl_device, n, &ishtp_dev->device_list,
734 device_link) { 735 device_link) {
736 cl_device->fw_client = NULL;
735 if (warm_reset && cl_device->reference_count) 737 if (warm_reset && cl_device->reference_count)
736 continue; 738 continue;
737 739
diff --git a/drivers/hid/intel-ish-hid/ishtp/bus.h b/drivers/hid/intel-ish-hid/ishtp/bus.h
index babf19ba3ff6..4cf7ad586c37 100644
--- a/drivers/hid/intel-ish-hid/ishtp/bus.h
+++ b/drivers/hid/intel-ish-hid/ishtp/bus.h
@@ -85,7 +85,7 @@ int ishtp_send_msg(struct ishtp_device *dev,
85/* Write a single-fragment message */ 85/* Write a single-fragment message */
86int ishtp_write_message(struct ishtp_device *dev, 86int ishtp_write_message(struct ishtp_device *dev,
87 struct ishtp_msg_hdr *hdr, 87 struct ishtp_msg_hdr *hdr,
88 unsigned char *buf); 88 void *buf);
89 89
90/* Use DMA to send/receive messages */ 90/* Use DMA to send/receive messages */
91int ishtp_use_dma_transfer(void); 91int ishtp_use_dma_transfer(void);
diff --git a/drivers/hid/intel-ish-hid/ishtp/hbm.c b/drivers/hid/intel-ish-hid/ishtp/hbm.c
index 8b5dd580ceec..d0b847c86935 100644
--- a/drivers/hid/intel-ish-hid/ishtp/hbm.c
+++ b/drivers/hid/intel-ish-hid/ishtp/hbm.c
@@ -136,19 +136,14 @@ int ishtp_hbm_start_wait(struct ishtp_device *dev)
136int ishtp_hbm_start_req(struct ishtp_device *dev) 136int ishtp_hbm_start_req(struct ishtp_device *dev)
137{ 137{
138 struct ishtp_msg_hdr hdr; 138 struct ishtp_msg_hdr hdr;
139 unsigned char data[128]; 139 struct hbm_host_version_request start_req = { 0 };
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);
143 140
144 ishtp_hbm_hdr(ishtp_hdr, len); 141 ishtp_hbm_hdr(&hdr, sizeof(start_req));
145 142
146 /* host start message */ 143 /* host start message */
147 start_req = (struct hbm_host_version_request *)data; 144 start_req.hbm_cmd = HOST_START_REQ_CMD;
148 memset(start_req, 0, len); 145 start_req.host_version.major_version = HBM_MAJOR_VERSION;
149 start_req->hbm_cmd = HOST_START_REQ_CMD; 146 start_req.host_version.minor_version = HBM_MINOR_VERSION;
150 start_req->host_version.major_version = HBM_MAJOR_VERSION;
151 start_req->host_version.minor_version = HBM_MINOR_VERSION;
152 147
153 /* 148 /*
154 * (!) Response to HBM start may be so quick that this thread would get 149 * (!) Response to HBM start may be so quick that this thread would get
@@ -156,7 +151,7 @@ int ishtp_hbm_start_req(struct ishtp_device *dev)
156 * So set it at first, change back to ISHTP_HBM_IDLE upon failure 151 * So set it at first, change back to ISHTP_HBM_IDLE upon failure
157 */ 152 */
158 dev->hbm_state = ISHTP_HBM_START; 153 dev->hbm_state = ISHTP_HBM_START;
159 if (ishtp_write_message(dev, ishtp_hdr, data)) { 154 if (ishtp_write_message(dev, &hdr, &start_req)) {
160 dev_err(dev->devc, "version message send failed\n"); 155 dev_err(dev->devc, "version message send failed\n");
161 dev->dev_state = ISHTP_DEV_RESETTING; 156 dev->dev_state = ISHTP_DEV_RESETTING;
162 dev->hbm_state = ISHTP_HBM_IDLE; 157 dev->hbm_state = ISHTP_HBM_IDLE;
@@ -178,19 +173,13 @@ int ishtp_hbm_start_req(struct ishtp_device *dev)
178void ishtp_hbm_enum_clients_req(struct ishtp_device *dev) 173void ishtp_hbm_enum_clients_req(struct ishtp_device *dev)
179{ 174{
180 struct ishtp_msg_hdr hdr; 175 struct ishtp_msg_hdr hdr;
181 unsigned char data[128]; 176 struct hbm_host_enum_request enum_req = { 0 };
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);
185 177
186 /* enumerate clients */ 178 /* 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;
188 181
189 enum_req = (struct hbm_host_enum_request *)data; 182 if (ishtp_write_message(dev, &hdr, &enum_req)) {
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)) {
194 dev->dev_state = ISHTP_DEV_RESETTING; 183 dev->dev_state = ISHTP_DEV_RESETTING;
195 dev_err(dev->devc, "enumeration request send failed\n"); 184 dev_err(dev->devc, "enumeration request send failed\n");
196 ish_hw_reset(dev); 185 ish_hw_reset(dev);
@@ -208,12 +197,8 @@ void ishtp_hbm_enum_clients_req(struct ishtp_device *dev)
208 */ 197 */
209static int ishtp_hbm_prop_req(struct ishtp_device *dev) 198static int ishtp_hbm_prop_req(struct ishtp_device *dev)
210{ 199{
211
212 struct ishtp_msg_hdr hdr; 200 struct ishtp_msg_hdr hdr;
213 unsigned char data[128]; 201 struct hbm_props_request prop_req = { 0 };
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);
217 unsigned long next_client_index; 202 unsigned long next_client_index;
218 uint8_t client_num; 203 uint8_t client_num;
219 204
@@ -237,15 +222,12 @@ static int ishtp_hbm_prop_req(struct ishtp_device *dev)
237 222
238 dev->fw_clients[client_num].client_id = next_client_index; 223 dev->fw_clients[client_num].client_id = next_client_index;
239 224
240 ishtp_hbm_hdr(ishtp_hdr, len); 225 ishtp_hbm_hdr(&hdr, sizeof(prop_req));
241 prop_req = (struct hbm_props_request *)data;
242 226
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;
244 229
245 prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; 230 if (ishtp_write_message(dev, &hdr, &prop_req)) {
246 prop_req->address = next_client_index;
247
248 if (ishtp_write_message(dev, ishtp_hdr, data)) {
249 dev->dev_state = ISHTP_DEV_RESETTING; 231 dev->dev_state = ISHTP_DEV_RESETTING;
250 dev_err(dev->devc, "properties request send failed\n"); 232 dev_err(dev->devc, "properties request send failed\n");
251 ish_hw_reset(dev); 233 ish_hw_reset(dev);
@@ -266,19 +248,14 @@ static int ishtp_hbm_prop_req(struct ishtp_device *dev)
266static void ishtp_hbm_stop_req(struct ishtp_device *dev) 248static void ishtp_hbm_stop_req(struct ishtp_device *dev)
267{ 249{
268 struct ishtp_msg_hdr hdr; 250 struct ishtp_msg_hdr hdr;
269 unsigned char data[128]; 251 struct hbm_host_stop_request stop_req = { 0 } ;
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);
273 252
274 ishtp_hbm_hdr(ishtp_hdr, len); 253 ishtp_hbm_hdr(&hdr, sizeof(stop_req));
275 req = (struct hbm_host_stop_request *)data;
276 254
277 memset(req, 0, sizeof(struct hbm_host_stop_request)); 255 stop_req.hbm_cmd = HOST_STOP_REQ_CMD;
278 req->hbm_cmd = HOST_STOP_REQ_CMD; 256 stop_req.reason = DRIVER_STOP_REQUEST;
279 req->reason = DRIVER_STOP_REQUEST;
280 257
281 ishtp_write_message(dev, ishtp_hdr, data); 258 ishtp_write_message(dev, &hdr, &stop_req);
282} 259}
283 260
284/** 261/**
@@ -294,15 +271,15 @@ int ishtp_hbm_cl_flow_control_req(struct ishtp_device *dev,
294 struct ishtp_cl *cl) 271 struct ishtp_cl *cl)
295{ 272{
296 struct ishtp_msg_hdr hdr; 273 struct ishtp_msg_hdr hdr;
297 unsigned char data[128]; 274 struct hbm_flow_control flow_ctrl;
298 struct ishtp_msg_hdr *ishtp_hdr = &hdr; 275 const size_t len = sizeof(flow_ctrl);
299 const size_t len = sizeof(struct hbm_flow_control);
300 int rv; 276 int rv;
301 unsigned long flags; 277 unsigned long flags;
302 278
303 spin_lock_irqsave(&cl->fc_spinlock, flags); 279 spin_lock_irqsave(&cl->fc_spinlock, flags);
304 ishtp_hbm_hdr(ishtp_hdr, len); 280
305 ishtp_hbm_cl_hdr(cl, ISHTP_FLOW_CONTROL_CMD, data, len); 281 ishtp_hbm_hdr(&hdr, len);
282 ishtp_hbm_cl_hdr(cl, ISHTP_FLOW_CONTROL_CMD, &flow_ctrl, len);
306 283
307 /* 284 /*
308 * Sync possible race when RB recycle and packet receive paths 285 * 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,
315 292
316 cl->recv_msg_num_frags = 0; 293 cl->recv_msg_num_frags = 0;
317 294
318 rv = ishtp_write_message(dev, ishtp_hdr, data); 295 rv = ishtp_write_message(dev, &hdr, &flow_ctrl);
319 if (!rv) { 296 if (!rv) {
320 ++cl->out_flow_ctrl_creds; 297 ++cl->out_flow_ctrl_creds;
321 ++cl->out_flow_ctrl_cnt; 298 ++cl->out_flow_ctrl_cnt;
@@ -345,14 +322,13 @@ int ishtp_hbm_cl_flow_control_req(struct ishtp_device *dev,
345int ishtp_hbm_cl_disconnect_req(struct ishtp_device *dev, struct ishtp_cl *cl) 322int ishtp_hbm_cl_disconnect_req(struct ishtp_device *dev, struct ishtp_cl *cl)
346{ 323{
347 struct ishtp_msg_hdr hdr; 324 struct ishtp_msg_hdr hdr;
348 unsigned char data[128]; 325 struct hbm_client_connect_request disconn_req;
349 struct ishtp_msg_hdr *ishtp_hdr = &hdr; 326 const size_t len = sizeof(disconn_req);
350 const size_t len = sizeof(struct hbm_client_connect_request);
351 327
352 ishtp_hbm_hdr(ishtp_hdr, len); 328 ishtp_hbm_hdr(&hdr, len);
353 ishtp_hbm_cl_hdr(cl, CLIENT_DISCONNECT_REQ_CMD, data, len); 329 ishtp_hbm_cl_hdr(cl, CLIENT_DISCONNECT_REQ_CMD, &disconn_req, len);
354 330
355 return ishtp_write_message(dev, ishtp_hdr, data); 331 return ishtp_write_message(dev, &hdr, &disconn_req);
356} 332}
357 333
358/** 334/**
@@ -391,14 +367,13 @@ static void ishtp_hbm_cl_disconnect_res(struct ishtp_device *dev,
391int ishtp_hbm_cl_connect_req(struct ishtp_device *dev, struct ishtp_cl *cl) 367int ishtp_hbm_cl_connect_req(struct ishtp_device *dev, struct ishtp_cl *cl)
392{ 368{
393 struct ishtp_msg_hdr hdr; 369 struct ishtp_msg_hdr hdr;
394 unsigned char data[128]; 370 struct hbm_client_connect_request conn_req;
395 struct ishtp_msg_hdr *ishtp_hdr = &hdr; 371 const size_t len = sizeof(conn_req);
396 const size_t len = sizeof(struct hbm_client_connect_request);
397 372
398 ishtp_hbm_hdr(ishtp_hdr, len); 373 ishtp_hbm_hdr(&hdr, len);
399 ishtp_hbm_cl_hdr(cl, CLIENT_CONNECT_REQ_CMD, data, len); 374 ishtp_hbm_cl_hdr(cl, CLIENT_CONNECT_REQ_CMD, &conn_req, len);
400 375
401 return ishtp_write_message(dev, ishtp_hdr, data); 376 return ishtp_write_message(dev, &hdr, &conn_req);
402} 377}
403 378
404/** 379/**
diff --git a/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h b/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h
index e7c6bfefaf9e..e54ce1ef27dd 100644
--- a/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h
+++ b/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h
@@ -211,8 +211,6 @@ struct ishtp_device {
211 /* For both processing list and free list */ 211 /* For both processing list and free list */
212 spinlock_t wr_processing_spinlock; 212 spinlock_t wr_processing_spinlock;
213 213
214 spinlock_t out_ipc_spinlock;
215
216 struct ishtp_fw_client *fw_clients; /*Note:memory has to be allocated*/ 214 struct ishtp_fw_client *fw_clients; /*Note:memory has to be allocated*/
217 DECLARE_BITMAP(fw_clients_map, ISHTP_CLIENTS_MAX); 215 DECLARE_BITMAP(fw_clients_map, ISHTP_CLIENTS_MAX);
218 DECLARE_BITMAP(host_clients_map, ISHTP_CLIENTS_MAX); 216 DECLARE_BITMAP(host_clients_map, ISHTP_CLIENTS_MAX);