summaryrefslogtreecommitdiffstats
path: root/drivers/hid/intel-ish-hid
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2018-10-23 07:34:28 -0400
committerJiri Kosina <jkosina@suse.cz>2018-10-23 07:34:28 -0400
commit4e7be68e8d0f7bb3c030cdfa442d298457197751 (patch)
treeb5541a91b5f4742d6e2c13d92ffb101fc06f6452 /drivers/hid/intel-ish-hid
parenta600ffe6ec609b0600ec590236f97f8d430e0984 (diff)
parent9ee3e06610fdb8a601cde59c92089fb6c1deb4aa (diff)
Merge branch 'for-4.20/i2c-hid' into for-linus
- general cleanups of hid-i2c driver - SPIODEV device descriptor fixes
Diffstat (limited to 'drivers/hid/intel-ish-hid')
-rw-r--r--drivers/hid/intel-ish-hid/ipc/ipc.c32
-rw-r--r--drivers/hid/intel-ish-hid/ipc/pci-ish.c75
-rw-r--r--drivers/hid/intel-ish-hid/ishtp-hid-client.c41
-rw-r--r--drivers/hid/intel-ish-hid/ishtp/bus.c52
-rw-r--r--drivers/hid/intel-ish-hid/ishtp/bus.h5
-rw-r--r--drivers/hid/intel-ish-hid/ishtp/client-buffers.c49
-rw-r--r--drivers/hid/intel-ish-hid/ishtp/client.c24
-rw-r--r--drivers/hid/intel-ish-hid/ishtp/client.h5
-rw-r--r--drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h2
9 files changed, 188 insertions, 97 deletions
diff --git a/drivers/hid/intel-ish-hid/ipc/ipc.c b/drivers/hid/intel-ish-hid/ipc/ipc.c
index bfbca7ec54ce..742191bb24c6 100644
--- a/drivers/hid/intel-ish-hid/ipc/ipc.c
+++ b/drivers/hid/intel-ish-hid/ipc/ipc.c
@@ -280,14 +280,14 @@ static int write_ipc_from_queue(struct ishtp_device *dev)
280 * if tx send list is empty - return 0; 280 * if tx send list is empty - return 0;
281 * may happen, as RX_COMPLETE handler doesn't check list emptiness. 281 * may happen, as RX_COMPLETE handler doesn't check list emptiness.
282 */ 282 */
283 if (list_empty(&dev->wr_processing_list_head.link)) { 283 if (list_empty(&dev->wr_processing_list)) {
284 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags); 284 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags);
285 out_ipc_locked = 0; 285 out_ipc_locked = 0;
286 return 0; 286 return 0;
287 } 287 }
288 288
289 ipc_link = list_entry(dev->wr_processing_list_head.link.next, 289 ipc_link = list_first_entry(&dev->wr_processing_list,
290 struct wr_msg_ctl_info, link); 290 struct wr_msg_ctl_info, link);
291 /* first 4 bytes of the data is the doorbell value (IPC header) */ 291 /* first 4 bytes of the data is the doorbell value (IPC header) */
292 length = ipc_link->length - sizeof(uint32_t); 292 length = ipc_link->length - sizeof(uint32_t);
293 doorbell_val = *(uint32_t *)ipc_link->inline_data; 293 doorbell_val = *(uint32_t *)ipc_link->inline_data;
@@ -338,7 +338,7 @@ static int write_ipc_from_queue(struct ishtp_device *dev)
338 ipc_send_compl = ipc_link->ipc_send_compl; 338 ipc_send_compl = ipc_link->ipc_send_compl;
339 ipc_send_compl_prm = ipc_link->ipc_send_compl_prm; 339 ipc_send_compl_prm = ipc_link->ipc_send_compl_prm;
340 list_del_init(&ipc_link->link); 340 list_del_init(&ipc_link->link);
341 list_add_tail(&ipc_link->link, &dev->wr_free_list_head.link); 341 list_add(&ipc_link->link, &dev->wr_free_list);
342 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags); 342 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags);
343 343
344 /* 344 /*
@@ -372,18 +372,18 @@ static int write_ipc_to_queue(struct ishtp_device *dev,
372 unsigned char *msg, int length) 372 unsigned char *msg, int length)
373{ 373{
374 struct wr_msg_ctl_info *ipc_link; 374 struct wr_msg_ctl_info *ipc_link;
375 unsigned long flags; 375 unsigned long flags;
376 376
377 if (length > IPC_FULL_MSG_SIZE) 377 if (length > IPC_FULL_MSG_SIZE)
378 return -EMSGSIZE; 378 return -EMSGSIZE;
379 379
380 spin_lock_irqsave(&dev->wr_processing_spinlock, flags); 380 spin_lock_irqsave(&dev->wr_processing_spinlock, flags);
381 if (list_empty(&dev->wr_free_list_head.link)) { 381 if (list_empty(&dev->wr_free_list)) {
382 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags); 382 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags);
383 return -ENOMEM; 383 return -ENOMEM;
384 } 384 }
385 ipc_link = list_entry(dev->wr_free_list_head.link.next, 385 ipc_link = list_first_entry(&dev->wr_free_list,
386 struct wr_msg_ctl_info, link); 386 struct wr_msg_ctl_info, link);
387 list_del_init(&ipc_link->link); 387 list_del_init(&ipc_link->link);
388 388
389 ipc_link->ipc_send_compl = ipc_send_compl; 389 ipc_link->ipc_send_compl = ipc_send_compl;
@@ -391,7 +391,7 @@ static int write_ipc_to_queue(struct ishtp_device *dev,
391 ipc_link->length = length; 391 ipc_link->length = length;
392 memcpy(ipc_link->inline_data, msg, length); 392 memcpy(ipc_link->inline_data, msg, length);
393 393
394 list_add_tail(&ipc_link->link, &dev->wr_processing_list_head.link); 394 list_add_tail(&ipc_link->link, &dev->wr_processing_list);
395 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags); 395 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags);
396 396
397 write_ipc_from_queue(dev); 397 write_ipc_from_queue(dev);
@@ -487,17 +487,13 @@ static int ish_fw_reset_handler(struct ishtp_device *dev)
487{ 487{
488 uint32_t reset_id; 488 uint32_t reset_id;
489 unsigned long flags; 489 unsigned long flags;
490 struct wr_msg_ctl_info *processing, *next;
491 490
492 /* Read reset ID */ 491 /* Read reset ID */
493 reset_id = ish_reg_read(dev, IPC_REG_ISH2HOST_MSG) & 0xFFFF; 492 reset_id = ish_reg_read(dev, IPC_REG_ISH2HOST_MSG) & 0xFFFF;
494 493
495 /* Clear IPC output queue */ 494 /* Clear IPC output queue */
496 spin_lock_irqsave(&dev->wr_processing_spinlock, flags); 495 spin_lock_irqsave(&dev->wr_processing_spinlock, flags);
497 list_for_each_entry_safe(processing, next, 496 list_splice_init(&dev->wr_processing_list, &dev->wr_free_list);
498 &dev->wr_processing_list_head.link, link) {
499 list_move_tail(&processing->link, &dev->wr_free_list_head.link);
500 }
501 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags); 497 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags);
502 498
503 /* ISHTP notification in IPC_RESET */ 499 /* ISHTP notification in IPC_RESET */
@@ -921,9 +917,9 @@ struct ishtp_device *ish_dev_init(struct pci_dev *pdev)
921 spin_lock_init(&dev->out_ipc_spinlock); 917 spin_lock_init(&dev->out_ipc_spinlock);
922 918
923 /* Init IPC processing and free lists */ 919 /* Init IPC processing and free lists */
924 INIT_LIST_HEAD(&dev->wr_processing_list_head.link); 920 INIT_LIST_HEAD(&dev->wr_processing_list);
925 INIT_LIST_HEAD(&dev->wr_free_list_head.link); 921 INIT_LIST_HEAD(&dev->wr_free_list);
926 for (i = 0; i < IPC_TX_FIFO_SIZE; ++i) { 922 for (i = 0; i < IPC_TX_FIFO_SIZE; i++) {
927 struct wr_msg_ctl_info *tx_buf; 923 struct wr_msg_ctl_info *tx_buf;
928 924
929 tx_buf = devm_kzalloc(&pdev->dev, 925 tx_buf = devm_kzalloc(&pdev->dev,
@@ -939,7 +935,7 @@ struct ishtp_device *ish_dev_init(struct pci_dev *pdev)
939 i); 935 i);
940 break; 936 break;
941 } 937 }
942 list_add_tail(&tx_buf->link, &dev->wr_free_list_head.link); 938 list_add_tail(&tx_buf->link, &dev->wr_free_list);
943 } 939 }
944 940
945 dev->ops = &ish_hw_ops; 941 dev->ops = &ish_hw_ops;
diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
index 256b3016116c..8793cc49f855 100644
--- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c
+++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
@@ -115,18 +115,19 @@ static const struct pci_device_id ish_invalid_pci_ids[] = {
115 */ 115 */
116static int ish_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 116static int ish_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
117{ 117{
118 struct ishtp_device *dev; 118 int ret;
119 struct ish_hw *hw; 119 struct ish_hw *hw;
120 int ret; 120 struct ishtp_device *ishtp;
121 struct device *dev = &pdev->dev;
121 122
122 /* Check for invalid platforms for ISH support */ 123 /* Check for invalid platforms for ISH support */
123 if (pci_dev_present(ish_invalid_pci_ids)) 124 if (pci_dev_present(ish_invalid_pci_ids))
124 return -ENODEV; 125 return -ENODEV;
125 126
126 /* enable pci dev */ 127 /* enable pci dev */
127 ret = pci_enable_device(pdev); 128 ret = pcim_enable_device(pdev);
128 if (ret) { 129 if (ret) {
129 dev_err(&pdev->dev, "ISH: Failed to enable PCI device\n"); 130 dev_err(dev, "ISH: Failed to enable PCI device\n");
130 return ret; 131 return ret;
131 } 132 }
132 133
@@ -134,65 +135,44 @@ static int ish_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
134 pci_set_master(pdev); 135 pci_set_master(pdev);
135 136
136 /* pci request regions for ISH driver */ 137 /* pci request regions for ISH driver */
137 ret = pci_request_regions(pdev, KBUILD_MODNAME); 138 ret = pcim_iomap_regions(pdev, 1 << 0, KBUILD_MODNAME);
138 if (ret) { 139 if (ret) {
139 dev_err(&pdev->dev, "ISH: Failed to get PCI regions\n"); 140 dev_err(dev, "ISH: Failed to get PCI regions\n");
140 goto disable_device; 141 return ret;
141 } 142 }
142 143
143 /* allocates and initializes the ISH dev structure */ 144 /* allocates and initializes the ISH dev structure */
144 dev = ish_dev_init(pdev); 145 ishtp = ish_dev_init(pdev);
145 if (!dev) { 146 if (!ishtp) {
146 ret = -ENOMEM; 147 ret = -ENOMEM;
147 goto release_regions; 148 return ret;
148 } 149 }
149 hw = to_ish_hw(dev); 150 hw = to_ish_hw(ishtp);
150 dev->print_log = ish_event_tracer; 151 ishtp->print_log = ish_event_tracer;
151 152
152 /* mapping IO device memory */ 153 /* mapping IO device memory */
153 hw->mem_addr = pci_iomap(pdev, 0, 0); 154 hw->mem_addr = pcim_iomap_table(pdev)[0];
154 if (!hw->mem_addr) { 155 ishtp->pdev = pdev;
155 dev_err(&pdev->dev, "ISH: mapping I/O range failure\n");
156 ret = -ENOMEM;
157 goto free_device;
158 }
159
160 dev->pdev = pdev;
161
162 pdev->dev_flags |= PCI_DEV_FLAGS_NO_D3; 156 pdev->dev_flags |= PCI_DEV_FLAGS_NO_D3;
163 157
164 /* request and enable interrupt */ 158 /* request and enable interrupt */
165 ret = request_irq(pdev->irq, ish_irq_handler, IRQF_SHARED, 159 ret = devm_request_irq(dev, pdev->irq, ish_irq_handler,
166 KBUILD_MODNAME, dev); 160 IRQF_SHARED, KBUILD_MODNAME, ishtp);
167 if (ret) { 161 if (ret) {
168 dev_err(&pdev->dev, "ISH: request IRQ failure (%d)\n", 162 dev_err(dev, "ISH: request IRQ %d failed\n", pdev->irq);
169 pdev->irq); 163 return ret;
170 goto free_device;
171 } 164 }
172 165
173 dev_set_drvdata(dev->devc, dev); 166 dev_set_drvdata(ishtp->devc, ishtp);
174 167
175 init_waitqueue_head(&dev->suspend_wait); 168 init_waitqueue_head(&ishtp->suspend_wait);
176 init_waitqueue_head(&dev->resume_wait); 169 init_waitqueue_head(&ishtp->resume_wait);
177 170
178 ret = ish_init(dev); 171 ret = ish_init(ishtp);
179 if (ret) 172 if (ret)
180 goto free_irq; 173 return ret;
181 174
182 return 0; 175 return 0;
183
184free_irq:
185 free_irq(pdev->irq, dev);
186free_device:
187 pci_iounmap(pdev, hw->mem_addr);
188release_regions:
189 pci_release_regions(pdev);
190disable_device:
191 pci_clear_master(pdev);
192 pci_disable_device(pdev);
193 dev_err(&pdev->dev, "ISH: PCI driver initialization failed.\n");
194
195 return ret;
196} 176}
197 177
198/** 178/**
@@ -204,16 +184,9 @@ disable_device:
204static void ish_remove(struct pci_dev *pdev) 184static void ish_remove(struct pci_dev *pdev)
205{ 185{
206 struct ishtp_device *ishtp_dev = pci_get_drvdata(pdev); 186 struct ishtp_device *ishtp_dev = pci_get_drvdata(pdev);
207 struct ish_hw *hw = to_ish_hw(ishtp_dev);
208 187
209 ishtp_bus_remove_all_clients(ishtp_dev, false); 188 ishtp_bus_remove_all_clients(ishtp_dev, false);
210 ish_device_disable(ishtp_dev); 189 ish_device_disable(ishtp_dev);
211
212 free_irq(pdev->irq, ishtp_dev);
213 pci_iounmap(pdev, hw->mem_addr);
214 pci_release_regions(pdev);
215 pci_clear_master(pdev);
216 pci_disable_device(pdev);
217} 190}
218 191
219static struct device __maybe_unused *ish_resume_device; 192static struct device __maybe_unused *ish_resume_device;
diff --git a/drivers/hid/intel-ish-hid/ishtp-hid-client.c b/drivers/hid/intel-ish-hid/ishtp-hid-client.c
index 2d28cffc1404..e64243bc9c96 100644
--- a/drivers/hid/intel-ish-hid/ishtp-hid-client.c
+++ b/drivers/hid/intel-ish-hid/ishtp-hid-client.c
@@ -320,23 +320,14 @@ do_get_report:
320 */ 320 */
321static void ish_cl_event_cb(struct ishtp_cl_device *device) 321static void ish_cl_event_cb(struct ishtp_cl_device *device)
322{ 322{
323 struct ishtp_cl *hid_ishtp_cl = device->driver_data; 323 struct ishtp_cl *hid_ishtp_cl = ishtp_get_drvdata(device);
324 struct ishtp_cl_rb *rb_in_proc; 324 struct ishtp_cl_rb *rb_in_proc;
325 size_t r_length; 325 size_t r_length;
326 unsigned long flags;
327 326
328 if (!hid_ishtp_cl) 327 if (!hid_ishtp_cl)
329 return; 328 return;
330 329
331 spin_lock_irqsave(&hid_ishtp_cl->in_process_spinlock, flags); 330 while ((rb_in_proc = ishtp_cl_rx_get_rb(hid_ishtp_cl)) != NULL) {
332 while (!list_empty(&hid_ishtp_cl->in_process_list.list)) {
333 rb_in_proc = list_entry(
334 hid_ishtp_cl->in_process_list.list.next,
335 struct ishtp_cl_rb, list);
336 list_del_init(&rb_in_proc->list);
337 spin_unlock_irqrestore(&hid_ishtp_cl->in_process_spinlock,
338 flags);
339
340 if (!rb_in_proc->buffer.data) 331 if (!rb_in_proc->buffer.data)
341 return; 332 return;
342 333
@@ -346,9 +337,7 @@ static void ish_cl_event_cb(struct ishtp_cl_device *device)
346 process_recv(hid_ishtp_cl, rb_in_proc->buffer.data, r_length); 337 process_recv(hid_ishtp_cl, rb_in_proc->buffer.data, r_length);
347 338
348 ishtp_cl_io_rb_recycle(rb_in_proc); 339 ishtp_cl_io_rb_recycle(rb_in_proc);
349 spin_lock_irqsave(&hid_ishtp_cl->in_process_spinlock, flags);
350 } 340 }
351 spin_unlock_irqrestore(&hid_ishtp_cl->in_process_spinlock, flags);
352} 341}
353 342
354/** 343/**
@@ -637,8 +626,8 @@ static int ishtp_get_report_descriptor(struct ishtp_cl *hid_ishtp_cl,
637static int hid_ishtp_cl_init(struct ishtp_cl *hid_ishtp_cl, int reset) 626static int hid_ishtp_cl_init(struct ishtp_cl *hid_ishtp_cl, int reset)
638{ 627{
639 struct ishtp_device *dev; 628 struct ishtp_device *dev;
640 unsigned long flags;
641 struct ishtp_cl_data *client_data = hid_ishtp_cl->client_data; 629 struct ishtp_cl_data *client_data = hid_ishtp_cl->client_data;
630 struct ishtp_fw_client *fw_client;
642 int i; 631 int i;
643 int rv; 632 int rv;
644 633
@@ -660,16 +649,14 @@ static int hid_ishtp_cl_init(struct ishtp_cl *hid_ishtp_cl, int reset)
660 hid_ishtp_cl->rx_ring_size = HID_CL_RX_RING_SIZE; 649 hid_ishtp_cl->rx_ring_size = HID_CL_RX_RING_SIZE;
661 hid_ishtp_cl->tx_ring_size = HID_CL_TX_RING_SIZE; 650 hid_ishtp_cl->tx_ring_size = HID_CL_TX_RING_SIZE;
662 651
663 spin_lock_irqsave(&dev->fw_clients_lock, flags); 652 fw_client = ishtp_fw_cl_get_client(dev, &hid_ishtp_guid);
664 i = ishtp_fw_cl_by_uuid(dev, &hid_ishtp_guid); 653 if (!fw_client) {
665 if (i < 0) {
666 spin_unlock_irqrestore(&dev->fw_clients_lock, flags);
667 dev_err(&client_data->cl_device->dev, 654 dev_err(&client_data->cl_device->dev,
668 "ish client uuid not found\n"); 655 "ish client uuid not found\n");
669 return i; 656 return -ENOENT;
670 } 657 }
671 hid_ishtp_cl->fw_client_id = dev->fw_clients[i].client_id; 658
672 spin_unlock_irqrestore(&dev->fw_clients_lock, flags); 659 hid_ishtp_cl->fw_client_id = fw_client->client_id;
673 hid_ishtp_cl->state = ISHTP_CL_CONNECTING; 660 hid_ishtp_cl->state = ISHTP_CL_CONNECTING;
674 661
675 rv = ishtp_cl_connect(hid_ishtp_cl); 662 rv = ishtp_cl_connect(hid_ishtp_cl);
@@ -765,7 +752,7 @@ static void hid_ishtp_cl_reset_handler(struct work_struct *work)
765 if (!hid_ishtp_cl) 752 if (!hid_ishtp_cl)
766 return; 753 return;
767 754
768 cl_device->driver_data = hid_ishtp_cl; 755 ishtp_set_drvdata(cl_device, hid_ishtp_cl);
769 hid_ishtp_cl->client_data = client_data; 756 hid_ishtp_cl->client_data = client_data;
770 client_data->hid_ishtp_cl = hid_ishtp_cl; 757 client_data->hid_ishtp_cl = hid_ishtp_cl;
771 758
@@ -814,7 +801,7 @@ static int hid_ishtp_cl_probe(struct ishtp_cl_device *cl_device)
814 if (!hid_ishtp_cl) 801 if (!hid_ishtp_cl)
815 return -ENOMEM; 802 return -ENOMEM;
816 803
817 cl_device->driver_data = hid_ishtp_cl; 804 ishtp_set_drvdata(cl_device, hid_ishtp_cl);
818 hid_ishtp_cl->client_data = client_data; 805 hid_ishtp_cl->client_data = client_data;
819 client_data->hid_ishtp_cl = hid_ishtp_cl; 806 client_data->hid_ishtp_cl = hid_ishtp_cl;
820 client_data->cl_device = cl_device; 807 client_data->cl_device = cl_device;
@@ -844,7 +831,7 @@ static int hid_ishtp_cl_probe(struct ishtp_cl_device *cl_device)
844 */ 831 */
845static int hid_ishtp_cl_remove(struct ishtp_cl_device *cl_device) 832static int hid_ishtp_cl_remove(struct ishtp_cl_device *cl_device)
846{ 833{
847 struct ishtp_cl *hid_ishtp_cl = cl_device->driver_data; 834 struct ishtp_cl *hid_ishtp_cl = ishtp_get_drvdata(cl_device);
848 struct ishtp_cl_data *client_data = hid_ishtp_cl->client_data; 835 struct ishtp_cl_data *client_data = hid_ishtp_cl->client_data;
849 836
850 hid_ishtp_trace(client_data, "%s hid_ishtp_cl %p\n", __func__, 837 hid_ishtp_trace(client_data, "%s hid_ishtp_cl %p\n", __func__,
@@ -874,7 +861,7 @@ static int hid_ishtp_cl_remove(struct ishtp_cl_device *cl_device)
874 */ 861 */
875static int hid_ishtp_cl_reset(struct ishtp_cl_device *cl_device) 862static int hid_ishtp_cl_reset(struct ishtp_cl_device *cl_device)
876{ 863{
877 struct ishtp_cl *hid_ishtp_cl = cl_device->driver_data; 864 struct ishtp_cl *hid_ishtp_cl = ishtp_get_drvdata(cl_device);
878 struct ishtp_cl_data *client_data = hid_ishtp_cl->client_data; 865 struct ishtp_cl_data *client_data = hid_ishtp_cl->client_data;
879 866
880 hid_ishtp_trace(client_data, "%s hid_ishtp_cl %p\n", __func__, 867 hid_ishtp_trace(client_data, "%s hid_ishtp_cl %p\n", __func__,
@@ -898,7 +885,7 @@ static int hid_ishtp_cl_reset(struct ishtp_cl_device *cl_device)
898static int hid_ishtp_cl_suspend(struct device *device) 885static int hid_ishtp_cl_suspend(struct device *device)
899{ 886{
900 struct ishtp_cl_device *cl_device = to_ishtp_cl_device(device); 887 struct ishtp_cl_device *cl_device = to_ishtp_cl_device(device);
901 struct ishtp_cl *hid_ishtp_cl = cl_device->driver_data; 888 struct ishtp_cl *hid_ishtp_cl = ishtp_get_drvdata(cl_device);
902 struct ishtp_cl_data *client_data = hid_ishtp_cl->client_data; 889 struct ishtp_cl_data *client_data = hid_ishtp_cl->client_data;
903 890
904 hid_ishtp_trace(client_data, "%s hid_ishtp_cl %p\n", __func__, 891 hid_ishtp_trace(client_data, "%s hid_ishtp_cl %p\n", __func__,
@@ -919,7 +906,7 @@ static int hid_ishtp_cl_suspend(struct device *device)
919static int hid_ishtp_cl_resume(struct device *device) 906static int hid_ishtp_cl_resume(struct device *device)
920{ 907{
921 struct ishtp_cl_device *cl_device = to_ishtp_cl_device(device); 908 struct ishtp_cl_device *cl_device = to_ishtp_cl_device(device);
922 struct ishtp_cl *hid_ishtp_cl = cl_device->driver_data; 909 struct ishtp_cl *hid_ishtp_cl = ishtp_get_drvdata(cl_device);
923 struct ishtp_cl_data *client_data = hid_ishtp_cl->client_data; 910 struct ishtp_cl_data *client_data = hid_ishtp_cl->client_data;
924 911
925 hid_ishtp_trace(client_data, "%s hid_ishtp_cl %p\n", __func__, 912 hid_ishtp_trace(client_data, "%s hid_ishtp_cl %p\n", __func__,
diff --git a/drivers/hid/intel-ish-hid/ishtp/bus.c b/drivers/hid/intel-ish-hid/ishtp/bus.c
index 2623a567ffba..728dc6d4561a 100644
--- a/drivers/hid/intel-ish-hid/ishtp/bus.c
+++ b/drivers/hid/intel-ish-hid/ishtp/bus.c
@@ -149,6 +149,31 @@ int ishtp_fw_cl_by_uuid(struct ishtp_device *dev, const uuid_le *uuid)
149EXPORT_SYMBOL(ishtp_fw_cl_by_uuid); 149EXPORT_SYMBOL(ishtp_fw_cl_by_uuid);
150 150
151/** 151/**
152 * ishtp_fw_cl_get_client() - return client information to client
153 * @dev: the ishtp device structure
154 * @uuid: uuid of the client to search
155 *
156 * Search firmware client using UUID and reture related client information.
157 *
158 * Return: pointer of client information on success, NULL on failure.
159 */
160struct ishtp_fw_client *ishtp_fw_cl_get_client(struct ishtp_device *dev,
161 const uuid_le *uuid)
162{
163 int i;
164 unsigned long flags;
165
166 spin_lock_irqsave(&dev->fw_clients_lock, flags);
167 i = ishtp_fw_cl_by_uuid(dev, uuid);
168 spin_unlock_irqrestore(&dev->fw_clients_lock, flags);
169 if (i < 0 || dev->fw_clients[i].props.fixed_address)
170 return NULL;
171
172 return &dev->fw_clients[i];
173}
174EXPORT_SYMBOL(ishtp_fw_cl_get_client);
175
176/**
152 * ishtp_fw_cl_by_id() - return index to fw_clients for client_id 177 * ishtp_fw_cl_by_id() - return index to fw_clients for client_id
153 * @dev: the ishtp device structure 178 * @dev: the ishtp device structure
154 * @client_id: fw client id to search 179 * @client_id: fw client id to search
@@ -564,6 +589,33 @@ void ishtp_put_device(struct ishtp_cl_device *cl_device)
564EXPORT_SYMBOL(ishtp_put_device); 589EXPORT_SYMBOL(ishtp_put_device);
565 590
566/** 591/**
592 * ishtp_set_drvdata() - set client driver data
593 * @cl_device: client device instance
594 * @data: driver data need to be set
595 *
596 * Set client driver data to cl_device->driver_data.
597 */
598void ishtp_set_drvdata(struct ishtp_cl_device *cl_device, void *data)
599{
600 cl_device->driver_data = data;
601}
602EXPORT_SYMBOL(ishtp_set_drvdata);
603
604/**
605 * ishtp_get_drvdata() - get client driver data
606 * @cl_device: client device instance
607 *
608 * Get client driver data from cl_device->driver_data.
609 *
610 * Return: pointer of driver data
611 */
612void *ishtp_get_drvdata(struct ishtp_cl_device *cl_device)
613{
614 return cl_device->driver_data;
615}
616EXPORT_SYMBOL(ishtp_get_drvdata);
617
618/**
567 * ishtp_bus_new_client() - Create a new client 619 * ishtp_bus_new_client() - Create a new client
568 * @dev: ISHTP device instance 620 * @dev: ISHTP device instance
569 * 621 *
diff --git a/drivers/hid/intel-ish-hid/ishtp/bus.h b/drivers/hid/intel-ish-hid/ishtp/bus.h
index a1ffae7f26ad..b8a5bcc82536 100644
--- a/drivers/hid/intel-ish-hid/ishtp/bus.h
+++ b/drivers/hid/intel-ish-hid/ishtp/bus.h
@@ -101,6 +101,9 @@ void ishtp_reset_compl_handler(struct ishtp_device *dev);
101void ishtp_put_device(struct ishtp_cl_device *); 101void ishtp_put_device(struct ishtp_cl_device *);
102void ishtp_get_device(struct ishtp_cl_device *); 102void ishtp_get_device(struct ishtp_cl_device *);
103 103
104void ishtp_set_drvdata(struct ishtp_cl_device *cl_device, void *data);
105void *ishtp_get_drvdata(struct ishtp_cl_device *cl_device);
106
104int __ishtp_cl_driver_register(struct ishtp_cl_driver *driver, 107int __ishtp_cl_driver_register(struct ishtp_cl_driver *driver,
105 struct module *owner); 108 struct module *owner);
106#define ishtp_cl_driver_register(driver) \ 109#define ishtp_cl_driver_register(driver) \
@@ -110,5 +113,7 @@ void ishtp_cl_driver_unregister(struct ishtp_cl_driver *driver);
110int ishtp_register_event_cb(struct ishtp_cl_device *device, 113int ishtp_register_event_cb(struct ishtp_cl_device *device,
111 void (*read_cb)(struct ishtp_cl_device *)); 114 void (*read_cb)(struct ishtp_cl_device *));
112int ishtp_fw_cl_by_uuid(struct ishtp_device *dev, const uuid_le *cuuid); 115int ishtp_fw_cl_by_uuid(struct ishtp_device *dev, const uuid_le *cuuid);
116struct ishtp_fw_client *ishtp_fw_cl_get_client(struct ishtp_device *dev,
117 const uuid_le *uuid);
113 118
114#endif /* _LINUX_ISHTP_CL_BUS_H */ 119#endif /* _LINUX_ISHTP_CL_BUS_H */
diff --git a/drivers/hid/intel-ish-hid/ishtp/client-buffers.c b/drivers/hid/intel-ish-hid/ishtp/client-buffers.c
index b9b917d2d50d..248651c35497 100644
--- a/drivers/hid/intel-ish-hid/ishtp/client-buffers.c
+++ b/drivers/hid/intel-ish-hid/ishtp/client-buffers.c
@@ -69,6 +69,8 @@ int ishtp_cl_alloc_tx_ring(struct ishtp_cl *cl)
69 int j; 69 int j;
70 unsigned long flags; 70 unsigned long flags;
71 71
72 cl->tx_ring_free_size = 0;
73
72 /* Allocate pool to free Tx bufs */ 74 /* Allocate pool to free Tx bufs */
73 for (j = 0; j < cl->tx_ring_size; ++j) { 75 for (j = 0; j < cl->tx_ring_size; ++j) {
74 struct ishtp_cl_tx_ring *tx_buf; 76 struct ishtp_cl_tx_ring *tx_buf;
@@ -85,6 +87,7 @@ int ishtp_cl_alloc_tx_ring(struct ishtp_cl *cl)
85 87
86 spin_lock_irqsave(&cl->tx_free_list_spinlock, flags); 88 spin_lock_irqsave(&cl->tx_free_list_spinlock, flags);
87 list_add_tail(&tx_buf->list, &cl->tx_free_list.list); 89 list_add_tail(&tx_buf->list, &cl->tx_free_list.list);
90 ++cl->tx_ring_free_size;
88 spin_unlock_irqrestore(&cl->tx_free_list_spinlock, flags); 91 spin_unlock_irqrestore(&cl->tx_free_list_spinlock, flags);
89 } 92 }
90 return 0; 93 return 0;
@@ -144,6 +147,7 @@ void ishtp_cl_free_tx_ring(struct ishtp_cl *cl)
144 tx_buf = list_entry(cl->tx_free_list.list.next, 147 tx_buf = list_entry(cl->tx_free_list.list.next,
145 struct ishtp_cl_tx_ring, list); 148 struct ishtp_cl_tx_ring, list);
146 list_del(&tx_buf->list); 149 list_del(&tx_buf->list);
150 --cl->tx_ring_free_size;
147 kfree(tx_buf->send_buf.data); 151 kfree(tx_buf->send_buf.data);
148 kfree(tx_buf); 152 kfree(tx_buf);
149 } 153 }
@@ -255,3 +259,48 @@ int ishtp_cl_io_rb_recycle(struct ishtp_cl_rb *rb)
255 return rets; 259 return rets;
256} 260}
257EXPORT_SYMBOL(ishtp_cl_io_rb_recycle); 261EXPORT_SYMBOL(ishtp_cl_io_rb_recycle);
262
263/**
264 * ishtp_cl_tx_empty() -test whether client device tx buffer is empty
265 * @cl: Pointer to client device instance
266 *
267 * Look client device tx buffer list, and check whether this list is empty
268 *
269 * Return: true if client tx buffer list is empty else false
270 */
271bool ishtp_cl_tx_empty(struct ishtp_cl *cl)
272{
273 int tx_list_empty;
274 unsigned long tx_flags;
275
276 spin_lock_irqsave(&cl->tx_list_spinlock, tx_flags);
277 tx_list_empty = list_empty(&cl->tx_list.list);
278 spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags);
279
280 return !!tx_list_empty;
281}
282EXPORT_SYMBOL(ishtp_cl_tx_empty);
283
284/**
285 * ishtp_cl_rx_get_rb() -Get a rb from client device rx buffer list
286 * @cl: Pointer to client device instance
287 *
288 * Check client device in-processing buffer list and get a rb from it.
289 *
290 * Return: rb pointer if buffer list isn't empty else NULL
291 */
292struct ishtp_cl_rb *ishtp_cl_rx_get_rb(struct ishtp_cl *cl)
293{
294 unsigned long rx_flags;
295 struct ishtp_cl_rb *rb;
296
297 spin_lock_irqsave(&cl->in_process_spinlock, rx_flags);
298 rb = list_first_entry_or_null(&cl->in_process_list.list,
299 struct ishtp_cl_rb, list);
300 if (rb)
301 list_del_init(&rb->list);
302 spin_unlock_irqrestore(&cl->in_process_spinlock, rx_flags);
303
304 return rb;
305}
306EXPORT_SYMBOL(ishtp_cl_rx_get_rb);
diff --git a/drivers/hid/intel-ish-hid/ishtp/client.c b/drivers/hid/intel-ish-hid/ishtp/client.c
index 007443ef5fca..faeccdb1475b 100644
--- a/drivers/hid/intel-ish-hid/ishtp/client.c
+++ b/drivers/hid/intel-ish-hid/ishtp/client.c
@@ -22,6 +22,25 @@
22#include "hbm.h" 22#include "hbm.h"
23#include "client.h" 23#include "client.h"
24 24
25int ishtp_cl_get_tx_free_buffer_size(struct ishtp_cl *cl)
26{
27 unsigned long tx_free_flags;
28 int size;
29
30 spin_lock_irqsave(&cl->tx_free_list_spinlock, tx_free_flags);
31 size = cl->tx_ring_free_size * cl->device->fw_client->props.max_msg_length;
32 spin_unlock_irqrestore(&cl->tx_free_list_spinlock, tx_free_flags);
33
34 return size;
35}
36EXPORT_SYMBOL(ishtp_cl_get_tx_free_buffer_size);
37
38int ishtp_cl_get_tx_free_rings(struct ishtp_cl *cl)
39{
40 return cl->tx_ring_free_size;
41}
42EXPORT_SYMBOL(ishtp_cl_get_tx_free_rings);
43
25/** 44/**
26 * ishtp_read_list_flush() - Flush read queue 45 * ishtp_read_list_flush() - Flush read queue
27 * @cl: ishtp client instance 46 * @cl: ishtp client instance
@@ -90,6 +109,7 @@ static void ishtp_cl_init(struct ishtp_cl *cl, struct ishtp_device *dev)
90 109
91 cl->rx_ring_size = CL_DEF_RX_RING_SIZE; 110 cl->rx_ring_size = CL_DEF_RX_RING_SIZE;
92 cl->tx_ring_size = CL_DEF_TX_RING_SIZE; 111 cl->tx_ring_size = CL_DEF_TX_RING_SIZE;
112 cl->tx_ring_free_size = cl->tx_ring_size;
93 113
94 /* dma */ 114 /* dma */
95 cl->last_tx_path = CL_TX_PATH_IPC; 115 cl->last_tx_path = CL_TX_PATH_IPC;
@@ -577,6 +597,8 @@ int ishtp_cl_send(struct ishtp_cl *cl, uint8_t *buf, size_t length)
577 * max ISHTP message size per client 597 * max ISHTP message size per client
578 */ 598 */
579 list_del_init(&cl_msg->list); 599 list_del_init(&cl_msg->list);
600 --cl->tx_ring_free_size;
601
580 spin_unlock_irqrestore(&cl->tx_free_list_spinlock, tx_free_flags); 602 spin_unlock_irqrestore(&cl->tx_free_list_spinlock, tx_free_flags);
581 memcpy(cl_msg->send_buf.data, buf, length); 603 memcpy(cl_msg->send_buf.data, buf, length);
582 cl_msg->send_buf.size = length; 604 cl_msg->send_buf.size = length;
@@ -685,6 +707,7 @@ static void ipc_tx_callback(void *prm)
685 ishtp_write_message(dev, &ishtp_hdr, pmsg); 707 ishtp_write_message(dev, &ishtp_hdr, pmsg);
686 spin_lock_irqsave(&cl->tx_free_list_spinlock, tx_free_flags); 708 spin_lock_irqsave(&cl->tx_free_list_spinlock, tx_free_flags);
687 list_add_tail(&cl_msg->list, &cl->tx_free_list.list); 709 list_add_tail(&cl_msg->list, &cl->tx_free_list.list);
710 ++cl->tx_ring_free_size;
688 spin_unlock_irqrestore(&cl->tx_free_list_spinlock, 711 spin_unlock_irqrestore(&cl->tx_free_list_spinlock,
689 tx_free_flags); 712 tx_free_flags);
690 } else { 713 } else {
@@ -778,6 +801,7 @@ static void ishtp_cl_send_msg_dma(struct ishtp_device *dev,
778 ishtp_write_message(dev, &hdr, (unsigned char *)&dma_xfer); 801 ishtp_write_message(dev, &hdr, (unsigned char *)&dma_xfer);
779 spin_lock_irqsave(&cl->tx_free_list_spinlock, tx_free_flags); 802 spin_lock_irqsave(&cl->tx_free_list_spinlock, tx_free_flags);
780 list_add_tail(&cl_msg->list, &cl->tx_free_list.list); 803 list_add_tail(&cl_msg->list, &cl->tx_free_list.list);
804 ++cl->tx_ring_free_size;
781 spin_unlock_irqrestore(&cl->tx_free_list_spinlock, tx_free_flags); 805 spin_unlock_irqrestore(&cl->tx_free_list_spinlock, tx_free_flags);
782 ++cl->send_msg_cnt_dma; 806 ++cl->send_msg_cnt_dma;
783} 807}
diff --git a/drivers/hid/intel-ish-hid/ishtp/client.h b/drivers/hid/intel-ish-hid/ishtp/client.h
index 79eade547f5d..042f4c4853b1 100644
--- a/drivers/hid/intel-ish-hid/ishtp/client.h
+++ b/drivers/hid/intel-ish-hid/ishtp/client.h
@@ -84,6 +84,7 @@ struct ishtp_cl {
84 /* Client Tx buffers list */ 84 /* Client Tx buffers list */
85 unsigned int tx_ring_size; 85 unsigned int tx_ring_size;
86 struct ishtp_cl_tx_ring tx_list, tx_free_list; 86 struct ishtp_cl_tx_ring tx_list, tx_free_list;
87 int tx_ring_free_size;
87 spinlock_t tx_list_spinlock; 88 spinlock_t tx_list_spinlock;
88 spinlock_t tx_free_list_spinlock; 89 spinlock_t tx_free_list_spinlock;
89 size_t tx_offs; /* Offset in buffer at head of 'tx_list' */ 90 size_t tx_offs; /* Offset in buffer at head of 'tx_list' */
@@ -137,6 +138,8 @@ int ishtp_cl_alloc_rx_ring(struct ishtp_cl *cl);
137int ishtp_cl_alloc_tx_ring(struct ishtp_cl *cl); 138int ishtp_cl_alloc_tx_ring(struct ishtp_cl *cl);
138void ishtp_cl_free_rx_ring(struct ishtp_cl *cl); 139void ishtp_cl_free_rx_ring(struct ishtp_cl *cl);
139void ishtp_cl_free_tx_ring(struct ishtp_cl *cl); 140void ishtp_cl_free_tx_ring(struct ishtp_cl *cl);
141int ishtp_cl_get_tx_free_buffer_size(struct ishtp_cl *cl);
142int ishtp_cl_get_tx_free_rings(struct ishtp_cl *cl);
140 143
141/* DMA I/F functions */ 144/* DMA I/F functions */
142void recv_ishtp_cl_msg_dma(struct ishtp_device *dev, void *msg, 145void recv_ishtp_cl_msg_dma(struct ishtp_device *dev, void *msg,
@@ -178,5 +181,7 @@ int ishtp_cl_flush_queues(struct ishtp_cl *cl);
178 181
179/* exported functions from ISHTP client buffer management scope */ 182/* exported functions from ISHTP client buffer management scope */
180int ishtp_cl_io_rb_recycle(struct ishtp_cl_rb *rb); 183int ishtp_cl_io_rb_recycle(struct ishtp_cl_rb *rb);
184bool ishtp_cl_tx_empty(struct ishtp_cl *cl);
185struct ishtp_cl_rb *ishtp_cl_rx_get_rb(struct ishtp_cl *cl);
181 186
182#endif /* _ISHTP_CLIENT_H_ */ 187#endif /* _ISHTP_CLIENT_H_ */
diff --git a/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h b/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h
index 6a6d927b78b0..e7c6bfefaf9e 100644
--- a/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h
+++ b/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h
@@ -207,7 +207,7 @@ struct ishtp_device {
207 struct work_struct bh_hbm_work; 207 struct work_struct bh_hbm_work;
208 208
209 /* IPC write queue */ 209 /* IPC write queue */
210 struct wr_msg_ctl_info wr_processing_list_head, wr_free_list_head; 210 struct list_head wr_processing_list, wr_free_list;
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