0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/init.h>
0010 #include <linux/kernel.h>
0011 #include <linux/device.h>
0012 #include <linux/sched.h>
0013 #include <linux/slab.h>
0014 #include "bus.h"
0015 #include "ishtp-dev.h"
0016 #include "client.h"
0017 #include "hbm.h"
0018
0019 static int ishtp_use_dma;
0020 module_param_named(ishtp_use_dma, ishtp_use_dma, int, 0600);
0021 MODULE_PARM_DESC(ishtp_use_dma, "Use DMA to send messages");
0022
0023 #define to_ishtp_cl_driver(d) container_of(d, struct ishtp_cl_driver, driver)
0024 #define to_ishtp_cl_device(d) container_of(d, struct ishtp_cl_device, dev)
0025 static bool ishtp_device_ready;
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 void ishtp_recv(struct ishtp_device *dev)
0037 {
0038 uint32_t msg_hdr;
0039 struct ishtp_msg_hdr *ishtp_hdr;
0040
0041
0042 msg_hdr = dev->ops->ishtp_read_hdr(dev);
0043 if (!msg_hdr)
0044 return;
0045
0046 dev->ops->sync_fw_clock(dev);
0047
0048 ishtp_hdr = (struct ishtp_msg_hdr *)&msg_hdr;
0049 dev->ishtp_msg_hdr = msg_hdr;
0050
0051
0052 if (ishtp_hdr->length > dev->mtu) {
0053 dev_err(dev->devc,
0054 "ISHTP hdr - bad length: %u; dropped [%08X]\n",
0055 (unsigned int)ishtp_hdr->length, msg_hdr);
0056 return;
0057 }
0058
0059
0060 if (!ishtp_hdr->host_addr && !ishtp_hdr->fw_addr)
0061 recv_hbm(dev, ishtp_hdr);
0062
0063 else if (!ishtp_hdr->host_addr)
0064 recv_fixed_cl_msg(dev, ishtp_hdr);
0065 else
0066
0067 recv_ishtp_cl_msg(dev, ishtp_hdr);
0068 }
0069 EXPORT_SYMBOL(ishtp_recv);
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084 int ishtp_send_msg(struct ishtp_device *dev, struct ishtp_msg_hdr *hdr,
0085 void *msg, void(*ipc_send_compl)(void *),
0086 void *ipc_send_compl_prm)
0087 {
0088 unsigned char ipc_msg[IPC_FULL_MSG_SIZE];
0089 uint32_t drbl_val;
0090
0091 drbl_val = dev->ops->ipc_get_header(dev, hdr->length +
0092 sizeof(struct ishtp_msg_hdr),
0093 1);
0094
0095 memcpy(ipc_msg, &drbl_val, sizeof(uint32_t));
0096 memcpy(ipc_msg + sizeof(uint32_t), hdr, sizeof(uint32_t));
0097 memcpy(ipc_msg + 2 * sizeof(uint32_t), msg, hdr->length);
0098 return dev->ops->write(dev, ipc_send_compl, ipc_send_compl_prm,
0099 ipc_msg, 2 * sizeof(uint32_t) + hdr->length);
0100 }
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113 int ishtp_write_message(struct ishtp_device *dev, struct ishtp_msg_hdr *hdr,
0114 void *buf)
0115 {
0116 return ishtp_send_msg(dev, hdr, buf, NULL, NULL);
0117 }
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128 int ishtp_fw_cl_by_uuid(struct ishtp_device *dev, const guid_t *uuid)
0129 {
0130 unsigned int i;
0131
0132 for (i = 0; i < dev->fw_clients_num; ++i) {
0133 if (guid_equal(uuid, &dev->fw_clients[i].props.protocol_name))
0134 return i;
0135 }
0136 return -ENOENT;
0137 }
0138 EXPORT_SYMBOL(ishtp_fw_cl_by_uuid);
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149 struct ishtp_fw_client *ishtp_fw_cl_get_client(struct ishtp_device *dev,
0150 const guid_t *uuid)
0151 {
0152 int i;
0153 unsigned long flags;
0154
0155 spin_lock_irqsave(&dev->fw_clients_lock, flags);
0156 i = ishtp_fw_cl_by_uuid(dev, uuid);
0157 spin_unlock_irqrestore(&dev->fw_clients_lock, flags);
0158 if (i < 0 || dev->fw_clients[i].props.fixed_address)
0159 return NULL;
0160
0161 return &dev->fw_clients[i];
0162 }
0163 EXPORT_SYMBOL(ishtp_fw_cl_get_client);
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173 int ishtp_get_fw_client_id(struct ishtp_fw_client *fw_client)
0174 {
0175 return fw_client->client_id;
0176 }
0177 EXPORT_SYMBOL(ishtp_get_fw_client_id);
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188 int ishtp_fw_cl_by_id(struct ishtp_device *dev, uint8_t client_id)
0189 {
0190 int i, res = -ENOENT;
0191 unsigned long flags;
0192
0193 spin_lock_irqsave(&dev->fw_clients_lock, flags);
0194 for (i = 0; i < dev->fw_clients_num; i++) {
0195 if (dev->fw_clients[i].client_id == client_id) {
0196 res = i;
0197 break;
0198 }
0199 }
0200 spin_unlock_irqrestore(&dev->fw_clients_lock, flags);
0201
0202 return res;
0203 }
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213 static int ishtp_cl_device_probe(struct device *dev)
0214 {
0215 struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
0216 struct ishtp_cl_driver *driver;
0217
0218 if (!device)
0219 return 0;
0220
0221 driver = to_ishtp_cl_driver(dev->driver);
0222 if (!driver || !driver->probe)
0223 return -ENODEV;
0224
0225 return driver->probe(device);
0226 }
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239 static int ishtp_cl_bus_match(struct device *dev, struct device_driver *drv)
0240 {
0241 struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
0242 struct ishtp_cl_driver *driver = to_ishtp_cl_driver(drv);
0243
0244 return guid_equal(&driver->id[0].guid,
0245 &device->fw_client->props.protocol_name);
0246 }
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258 static void ishtp_cl_device_remove(struct device *dev)
0259 {
0260 struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
0261 struct ishtp_cl_driver *driver = to_ishtp_cl_driver(dev->driver);
0262
0263 if (device->event_cb) {
0264 device->event_cb = NULL;
0265 cancel_work_sync(&device->event_work);
0266 }
0267
0268 if (driver->remove)
0269 driver->remove(device);
0270 }
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280 static int ishtp_cl_device_suspend(struct device *dev)
0281 {
0282 struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
0283 struct ishtp_cl_driver *driver;
0284 int ret = 0;
0285
0286 if (!device)
0287 return 0;
0288
0289 driver = to_ishtp_cl_driver(dev->driver);
0290 if (driver && driver->driver.pm) {
0291 if (driver->driver.pm->suspend)
0292 ret = driver->driver.pm->suspend(dev);
0293 }
0294
0295 return ret;
0296 }
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306 static int ishtp_cl_device_resume(struct device *dev)
0307 {
0308 struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
0309 struct ishtp_cl_driver *driver;
0310 int ret = 0;
0311
0312 if (!device)
0313 return 0;
0314
0315 driver = to_ishtp_cl_driver(dev->driver);
0316 if (driver && driver->driver.pm) {
0317 if (driver->driver.pm->resume)
0318 ret = driver->driver.pm->resume(dev);
0319 }
0320
0321 return ret;
0322 }
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333 static int ishtp_cl_device_reset(struct ishtp_cl_device *device)
0334 {
0335 struct ishtp_cl_driver *driver;
0336 int ret = 0;
0337
0338 device->event_cb = NULL;
0339 cancel_work_sync(&device->event_work);
0340
0341 driver = to_ishtp_cl_driver(device->dev.driver);
0342 if (driver && driver->reset)
0343 ret = driver->reset(device);
0344
0345 return ret;
0346 }
0347
0348 static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
0349 char *buf)
0350 {
0351 int len;
0352
0353 len = snprintf(buf, PAGE_SIZE, ISHTP_MODULE_PREFIX "%s\n", dev_name(dev));
0354 return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
0355 }
0356 static DEVICE_ATTR_RO(modalias);
0357
0358 static struct attribute *ishtp_cl_dev_attrs[] = {
0359 &dev_attr_modalias.attr,
0360 NULL,
0361 };
0362 ATTRIBUTE_GROUPS(ishtp_cl_dev);
0363
0364 static int ishtp_cl_uevent(struct device *dev, struct kobj_uevent_env *env)
0365 {
0366 if (add_uevent_var(env, "MODALIAS=" ISHTP_MODULE_PREFIX "%s", dev_name(dev)))
0367 return -ENOMEM;
0368 return 0;
0369 }
0370
0371 static const struct dev_pm_ops ishtp_cl_bus_dev_pm_ops = {
0372
0373 .suspend = ishtp_cl_device_suspend,
0374 .resume = ishtp_cl_device_resume,
0375
0376 .freeze = ishtp_cl_device_suspend,
0377 .thaw = ishtp_cl_device_resume,
0378 .restore = ishtp_cl_device_resume,
0379 };
0380
0381 static struct bus_type ishtp_cl_bus_type = {
0382 .name = "ishtp",
0383 .dev_groups = ishtp_cl_dev_groups,
0384 .probe = ishtp_cl_device_probe,
0385 .match = ishtp_cl_bus_match,
0386 .remove = ishtp_cl_device_remove,
0387 .pm = &ishtp_cl_bus_dev_pm_ops,
0388 .uevent = ishtp_cl_uevent,
0389 };
0390
0391 static void ishtp_cl_dev_release(struct device *dev)
0392 {
0393 kfree(to_ishtp_cl_device(dev));
0394 }
0395
0396 static const struct device_type ishtp_cl_device_type = {
0397 .release = ishtp_cl_dev_release,
0398 };
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411 static struct ishtp_cl_device *ishtp_bus_add_device(struct ishtp_device *dev,
0412 guid_t uuid, char *name)
0413 {
0414 struct ishtp_cl_device *device;
0415 int status;
0416 unsigned long flags;
0417
0418 spin_lock_irqsave(&dev->device_list_lock, flags);
0419 list_for_each_entry(device, &dev->device_list, device_link) {
0420 if (!strcmp(name, dev_name(&device->dev))) {
0421 device->fw_client = &dev->fw_clients[
0422 dev->fw_client_presentation_num - 1];
0423 spin_unlock_irqrestore(&dev->device_list_lock, flags);
0424 ishtp_cl_device_reset(device);
0425 return device;
0426 }
0427 }
0428 spin_unlock_irqrestore(&dev->device_list_lock, flags);
0429
0430 device = kzalloc(sizeof(struct ishtp_cl_device), GFP_KERNEL);
0431 if (!device)
0432 return NULL;
0433
0434 device->dev.parent = dev->devc;
0435 device->dev.bus = &ishtp_cl_bus_type;
0436 device->dev.type = &ishtp_cl_device_type;
0437 device->ishtp_dev = dev;
0438
0439 device->fw_client =
0440 &dev->fw_clients[dev->fw_client_presentation_num - 1];
0441
0442 dev_set_name(&device->dev, "%s", name);
0443
0444 spin_lock_irqsave(&dev->device_list_lock, flags);
0445 list_add_tail(&device->device_link, &dev->device_list);
0446 spin_unlock_irqrestore(&dev->device_list_lock, flags);
0447
0448 status = device_register(&device->dev);
0449 if (status) {
0450 spin_lock_irqsave(&dev->device_list_lock, flags);
0451 list_del(&device->device_link);
0452 spin_unlock_irqrestore(&dev->device_list_lock, flags);
0453 dev_err(dev->devc, "Failed to register ISHTP client device\n");
0454 put_device(&device->dev);
0455 return NULL;
0456 }
0457
0458 ishtp_device_ready = true;
0459
0460 return device;
0461 }
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472 static void ishtp_bus_remove_device(struct ishtp_cl_device *device)
0473 {
0474 device_unregister(&device->dev);
0475 }
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487 int ishtp_cl_driver_register(struct ishtp_cl_driver *driver,
0488 struct module *owner)
0489 {
0490 if (!ishtp_device_ready)
0491 return -ENODEV;
0492
0493 driver->driver.name = driver->name;
0494 driver->driver.owner = owner;
0495 driver->driver.bus = &ishtp_cl_bus_type;
0496
0497 return driver_register(&driver->driver);
0498 }
0499 EXPORT_SYMBOL(ishtp_cl_driver_register);
0500
0501
0502
0503
0504
0505
0506
0507 void ishtp_cl_driver_unregister(struct ishtp_cl_driver *driver)
0508 {
0509 driver_unregister(&driver->driver);
0510 }
0511 EXPORT_SYMBOL(ishtp_cl_driver_unregister);
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521 static void ishtp_bus_event_work(struct work_struct *work)
0522 {
0523 struct ishtp_cl_device *device;
0524
0525 device = container_of(work, struct ishtp_cl_device, event_work);
0526
0527 if (device->event_cb)
0528 device->event_cb(device);
0529 }
0530
0531
0532
0533
0534
0535
0536
0537
0538 void ishtp_cl_bus_rx_event(struct ishtp_cl_device *device)
0539 {
0540 if (!device || !device->event_cb)
0541 return;
0542
0543 if (device->event_cb)
0544 schedule_work(&device->event_work);
0545 }
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556 int ishtp_register_event_cb(struct ishtp_cl_device *device,
0557 void (*event_cb)(struct ishtp_cl_device *))
0558 {
0559 if (device->event_cb)
0560 return -EALREADY;
0561
0562 device->event_cb = event_cb;
0563 INIT_WORK(&device->event_work, ishtp_bus_event_work);
0564
0565 return 0;
0566 }
0567 EXPORT_SYMBOL(ishtp_register_event_cb);
0568
0569
0570
0571
0572
0573
0574
0575 void ishtp_get_device(struct ishtp_cl_device *cl_device)
0576 {
0577 cl_device->reference_count++;
0578 }
0579 EXPORT_SYMBOL(ishtp_get_device);
0580
0581
0582
0583
0584
0585
0586
0587 void ishtp_put_device(struct ishtp_cl_device *cl_device)
0588 {
0589 cl_device->reference_count--;
0590 }
0591 EXPORT_SYMBOL(ishtp_put_device);
0592
0593
0594
0595
0596
0597
0598
0599
0600 void ishtp_set_drvdata(struct ishtp_cl_device *cl_device, void *data)
0601 {
0602 cl_device->driver_data = data;
0603 }
0604 EXPORT_SYMBOL(ishtp_set_drvdata);
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614 void *ishtp_get_drvdata(struct ishtp_cl_device *cl_device)
0615 {
0616 return cl_device->driver_data;
0617 }
0618 EXPORT_SYMBOL(ishtp_get_drvdata);
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628 struct ishtp_cl_device *ishtp_dev_to_cl_device(struct device *device)
0629 {
0630 return to_ishtp_cl_device(device);
0631 }
0632 EXPORT_SYMBOL(ishtp_dev_to_cl_device);
0633
0634
0635
0636
0637
0638
0639
0640
0641
0642
0643 int ishtp_bus_new_client(struct ishtp_device *dev)
0644 {
0645 int i;
0646 char *dev_name;
0647 struct ishtp_cl_device *cl_device;
0648 guid_t device_uuid;
0649
0650
0651
0652
0653
0654
0655
0656 i = dev->fw_client_presentation_num - 1;
0657 device_uuid = dev->fw_clients[i].props.protocol_name;
0658 dev_name = kasprintf(GFP_KERNEL, "{%pUL}", &device_uuid);
0659 if (!dev_name)
0660 return -ENOMEM;
0661
0662 cl_device = ishtp_bus_add_device(dev, device_uuid, dev_name);
0663 if (!cl_device) {
0664 kfree(dev_name);
0665 return -ENOENT;
0666 }
0667
0668 kfree(dev_name);
0669
0670 return 0;
0671 }
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681 int ishtp_cl_device_bind(struct ishtp_cl *cl)
0682 {
0683 struct ishtp_cl_device *cl_device;
0684 unsigned long flags;
0685 int rv;
0686
0687 if (!cl->fw_client_id || cl->state != ISHTP_CL_CONNECTED)
0688 return -EFAULT;
0689
0690 rv = -ENOENT;
0691 spin_lock_irqsave(&cl->dev->device_list_lock, flags);
0692 list_for_each_entry(cl_device, &cl->dev->device_list,
0693 device_link) {
0694 if (cl_device->fw_client &&
0695 cl_device->fw_client->client_id == cl->fw_client_id) {
0696 cl->device = cl_device;
0697 rv = 0;
0698 break;
0699 }
0700 }
0701 spin_unlock_irqrestore(&cl->dev->device_list_lock, flags);
0702 return rv;
0703 }
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714
0715 void ishtp_bus_remove_all_clients(struct ishtp_device *ishtp_dev,
0716 bool warm_reset)
0717 {
0718 struct ishtp_cl_device *cl_device, *n;
0719 struct ishtp_cl *cl;
0720 unsigned long flags;
0721
0722 spin_lock_irqsave(&ishtp_dev->cl_list_lock, flags);
0723 list_for_each_entry(cl, &ishtp_dev->cl_list, link) {
0724 cl->state = ISHTP_CL_DISCONNECTED;
0725
0726
0727
0728
0729
0730
0731 wake_up_interruptible(&cl->wait_ctrl_res);
0732
0733
0734 ishtp_cl_flush_queues(cl);
0735
0736
0737 ishtp_cl_free_rx_ring(cl);
0738 ishtp_cl_free_tx_ring(cl);
0739
0740
0741
0742
0743
0744
0745 }
0746 spin_unlock_irqrestore(&ishtp_dev->cl_list_lock, flags);
0747
0748
0749 ishtp_cl_free_dma_buf(ishtp_dev);
0750
0751
0752 spin_lock_irqsave(&ishtp_dev->device_list_lock, flags);
0753 list_for_each_entry_safe(cl_device, n, &ishtp_dev->device_list,
0754 device_link) {
0755 cl_device->fw_client = NULL;
0756 if (warm_reset && cl_device->reference_count)
0757 continue;
0758
0759 list_del(&cl_device->device_link);
0760 spin_unlock_irqrestore(&ishtp_dev->device_list_lock, flags);
0761 ishtp_bus_remove_device(cl_device);
0762 spin_lock_irqsave(&ishtp_dev->device_list_lock, flags);
0763 }
0764 spin_unlock_irqrestore(&ishtp_dev->device_list_lock, flags);
0765
0766
0767 spin_lock_irqsave(&ishtp_dev->fw_clients_lock, flags);
0768 kfree(ishtp_dev->fw_clients);
0769 ishtp_dev->fw_clients = NULL;
0770 ishtp_dev->fw_clients_num = 0;
0771 ishtp_dev->fw_client_presentation_num = 0;
0772 ishtp_dev->fw_client_index = 0;
0773 bitmap_zero(ishtp_dev->fw_clients_map, ISHTP_CLIENTS_MAX);
0774 spin_unlock_irqrestore(&ishtp_dev->fw_clients_lock, flags);
0775 }
0776 EXPORT_SYMBOL(ishtp_bus_remove_all_clients);
0777
0778
0779
0780
0781
0782
0783
0784 void ishtp_reset_handler(struct ishtp_device *dev)
0785 {
0786 unsigned long flags;
0787
0788
0789 dev->dev_state = ISHTP_DEV_RESETTING;
0790
0791
0792 spin_lock_irqsave(&dev->rd_msg_spinlock, flags);
0793 dev->rd_msg_fifo_head = dev->rd_msg_fifo_tail = 0;
0794 spin_unlock_irqrestore(&dev->rd_msg_spinlock, flags);
0795
0796
0797 ishtp_bus_remove_all_clients(dev, true);
0798 }
0799 EXPORT_SYMBOL(ishtp_reset_handler);
0800
0801
0802
0803
0804
0805
0806
0807
0808 void ishtp_reset_compl_handler(struct ishtp_device *dev)
0809 {
0810 dev->dev_state = ISHTP_DEV_INIT_CLIENTS;
0811 dev->hbm_state = ISHTP_HBM_START;
0812 ishtp_hbm_start_req(dev);
0813 }
0814 EXPORT_SYMBOL(ishtp_reset_compl_handler);
0815
0816
0817
0818
0819
0820
0821
0822
0823 int ishtp_use_dma_transfer(void)
0824 {
0825 return ishtp_use_dma;
0826 }
0827
0828
0829
0830
0831
0832
0833
0834
0835
0836
0837 struct device *ishtp_device(struct ishtp_cl_device *device)
0838 {
0839 return &device->dev;
0840 }
0841 EXPORT_SYMBOL(ishtp_device);
0842
0843
0844
0845
0846
0847
0848
0849
0850 bool ishtp_wait_resume(struct ishtp_device *dev)
0851 {
0852
0853 #define WAIT_FOR_RESUME_ACK_MS 50
0854
0855
0856 if (dev->resume_flag)
0857 wait_event_interruptible_timeout(dev->resume_wait,
0858 !dev->resume_flag,
0859 msecs_to_jiffies(WAIT_FOR_RESUME_ACK_MS));
0860
0861 return (!dev->resume_flag);
0862 }
0863 EXPORT_SYMBOL_GPL(ishtp_wait_resume);
0864
0865
0866
0867
0868
0869
0870
0871
0872
0873 struct device *ishtp_get_pci_device(struct ishtp_cl_device *device)
0874 {
0875 return device->ishtp_dev->devc;
0876 }
0877 EXPORT_SYMBOL(ishtp_get_pci_device);
0878
0879
0880
0881
0882
0883
0884
0885
0886
0887 ishtp_print_log ishtp_trace_callback(struct ishtp_cl_device *cl_device)
0888 {
0889 return cl_device->ishtp_dev->print_log;
0890 }
0891 EXPORT_SYMBOL(ishtp_trace_callback);
0892
0893
0894
0895
0896
0897
0898
0899
0900
0901 int ish_hw_reset(struct ishtp_device *dev)
0902 {
0903 return dev->ops->hw_reset(dev);
0904 }
0905 EXPORT_SYMBOL(ish_hw_reset);
0906
0907
0908
0909
0910
0911
0912
0913
0914 static int __init ishtp_bus_register(void)
0915 {
0916 return bus_register(&ishtp_cl_bus_type);
0917 }
0918
0919
0920
0921
0922
0923
0924 static void __exit ishtp_bus_unregister(void)
0925 {
0926 bus_unregister(&ishtp_cl_bus_type);
0927 }
0928
0929 module_init(ishtp_bus_register);
0930 module_exit(ishtp_bus_unregister);
0931
0932 MODULE_LICENSE("GPL");