0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 #define dev_fmt(fmt) "SCMI Notifications - " fmt
0074 #define pr_fmt(fmt) "SCMI Notifications - " fmt
0075
0076 #include <linux/bitfield.h>
0077 #include <linux/bug.h>
0078 #include <linux/compiler.h>
0079 #include <linux/device.h>
0080 #include <linux/err.h>
0081 #include <linux/hashtable.h>
0082 #include <linux/kernel.h>
0083 #include <linux/ktime.h>
0084 #include <linux/kfifo.h>
0085 #include <linux/list.h>
0086 #include <linux/mutex.h>
0087 #include <linux/notifier.h>
0088 #include <linux/refcount.h>
0089 #include <linux/scmi_protocol.h>
0090 #include <linux/slab.h>
0091 #include <linux/types.h>
0092 #include <linux/workqueue.h>
0093
0094 #include "common.h"
0095 #include "notify.h"
0096
0097 #define SCMI_MAX_PROTO 256
0098
0099 #define PROTO_ID_MASK GENMASK(31, 24)
0100 #define EVT_ID_MASK GENMASK(23, 16)
0101 #define SRC_ID_MASK GENMASK(15, 0)
0102
0103
0104
0105
0106
0107 #define MAKE_HASH_KEY(p, e, s) \
0108 (FIELD_PREP(PROTO_ID_MASK, (p)) | \
0109 FIELD_PREP(EVT_ID_MASK, (e)) | \
0110 FIELD_PREP(SRC_ID_MASK, (s)))
0111
0112 #define MAKE_ALL_SRCS_KEY(p, e) MAKE_HASH_KEY((p), (e), SRC_ID_MASK)
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125 #define KEY_FIND(__ht, __obj, __k) \
0126 ({ \
0127 typeof(__k) k_ = __k; \
0128 typeof(__obj) obj_; \
0129 \
0130 hash_for_each_possible((__ht), obj_, hash, k_) \
0131 if (obj_->key == k_) \
0132 break; \
0133 __obj = obj_; \
0134 })
0135
0136 #define KEY_XTRACT_PROTO_ID(key) FIELD_GET(PROTO_ID_MASK, (key))
0137 #define KEY_XTRACT_EVT_ID(key) FIELD_GET(EVT_ID_MASK, (key))
0138 #define KEY_XTRACT_SRC_ID(key) FIELD_GET(SRC_ID_MASK, (key))
0139
0140
0141
0142
0143
0144
0145
0146 #define SCMI_GET_PROTO(__ni, __pid) \
0147 ({ \
0148 typeof(__ni) ni_ = __ni; \
0149 struct scmi_registered_events_desc *__pd = NULL; \
0150 \
0151 if (ni_) \
0152 __pd = READ_ONCE(ni_->registered_protocols[(__pid)]); \
0153 __pd; \
0154 })
0155
0156 #define SCMI_GET_REVT_FROM_PD(__pd, __eid) \
0157 ({ \
0158 typeof(__pd) pd_ = __pd; \
0159 typeof(__eid) eid_ = __eid; \
0160 struct scmi_registered_event *__revt = NULL; \
0161 \
0162 if (pd_ && eid_ < pd_->num_events) \
0163 __revt = READ_ONCE(pd_->registered_events[eid_]); \
0164 __revt; \
0165 })
0166
0167 #define SCMI_GET_REVT(__ni, __pid, __eid) \
0168 ({ \
0169 struct scmi_registered_event *__revt; \
0170 struct scmi_registered_events_desc *__pd; \
0171 \
0172 __pd = SCMI_GET_PROTO((__ni), (__pid)); \
0173 __revt = SCMI_GET_REVT_FROM_PD(__pd, (__eid)); \
0174 __revt; \
0175 })
0176
0177
0178 #define REVT_NOTIFY_SET_STATUS(revt, eid, sid, state) \
0179 ({ \
0180 typeof(revt) r = revt; \
0181 r->proto->ops->set_notify_enabled(r->proto->ph, \
0182 (eid), (sid), (state)); \
0183 })
0184
0185 #define REVT_NOTIFY_ENABLE(revt, eid, sid) \
0186 REVT_NOTIFY_SET_STATUS((revt), (eid), (sid), true)
0187
0188 #define REVT_NOTIFY_DISABLE(revt, eid, sid) \
0189 REVT_NOTIFY_SET_STATUS((revt), (eid), (sid), false)
0190
0191 #define REVT_FILL_REPORT(revt, ...) \
0192 ({ \
0193 typeof(revt) r = revt; \
0194 r->proto->ops->fill_custom_report(r->proto->ph, \
0195 __VA_ARGS__); \
0196 })
0197
0198 #define SCMI_PENDING_HASH_SZ 4
0199 #define SCMI_REGISTERED_HASH_SZ 6
0200
0201 struct scmi_registered_events_desc;
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220 struct scmi_notify_instance {
0221 void *gid;
0222 struct scmi_handle *handle;
0223 struct work_struct init_work;
0224 struct workqueue_struct *notify_wq;
0225
0226 struct mutex pending_mtx;
0227 struct scmi_registered_events_desc **registered_protocols;
0228 DECLARE_HASHTABLE(pending_events_handlers, SCMI_PENDING_HASH_SZ);
0229 };
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240 struct events_queue {
0241 size_t sz;
0242 struct kfifo kfifo;
0243 struct work_struct notify_work;
0244 struct workqueue_struct *wq;
0245 };
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258 struct scmi_event_header {
0259 ktime_t timestamp;
0260 size_t payld_sz;
0261 unsigned char evt_id;
0262 unsigned char payld[];
0263 };
0264
0265 struct scmi_registered_event;
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295 struct scmi_registered_events_desc {
0296 u8 id;
0297 const struct scmi_event_ops *ops;
0298 struct events_queue equeue;
0299 struct scmi_notify_instance *ni;
0300 struct scmi_event_header *eh;
0301 size_t eh_sz;
0302 void *in_flight;
0303 int num_events;
0304 struct scmi_registered_event **registered_events;
0305
0306 struct mutex registered_mtx;
0307 const struct scmi_protocol_handle *ph;
0308 DECLARE_HASHTABLE(registered_events_handlers, SCMI_REGISTERED_HASH_SZ);
0309 };
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331 struct scmi_registered_event {
0332 struct scmi_registered_events_desc *proto;
0333 const struct scmi_event *evt;
0334 void *report;
0335 u32 num_sources;
0336 refcount_t *sources;
0337
0338 struct mutex sources_mtx;
0339 };
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359 struct scmi_event_handler {
0360 u32 key;
0361 refcount_t users;
0362 struct scmi_registered_event *r_evt;
0363 struct blocking_notifier_head chain;
0364 struct hlist_node hash;
0365 bool enabled;
0366 };
0367
0368 #define IS_HNDL_PENDING(hndl) (!(hndl)->r_evt)
0369
0370 static struct scmi_event_handler *
0371 scmi_get_active_handler(struct scmi_notify_instance *ni, u32 evt_key);
0372 static void scmi_put_active_handler(struct scmi_notify_instance *ni,
0373 struct scmi_event_handler *hndl);
0374 static bool scmi_put_handler_unlocked(struct scmi_notify_instance *ni,
0375 struct scmi_event_handler *hndl);
0376
0377
0378
0379
0380
0381
0382
0383
0384 static inline void
0385 scmi_lookup_and_call_event_chain(struct scmi_notify_instance *ni,
0386 u32 evt_key, void *report)
0387 {
0388 int ret;
0389 struct scmi_event_handler *hndl;
0390
0391
0392
0393
0394
0395
0396
0397 hndl = scmi_get_active_handler(ni, evt_key);
0398 if (!hndl)
0399 return;
0400
0401 ret = blocking_notifier_call_chain(&hndl->chain,
0402 KEY_XTRACT_EVT_ID(evt_key),
0403 report);
0404
0405 WARN_ON_ONCE(ret & NOTIFY_STOP_MASK);
0406
0407 scmi_put_active_handler(ni, hndl);
0408 }
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424 static inline struct scmi_registered_event *
0425 scmi_process_event_header(struct events_queue *eq,
0426 struct scmi_registered_events_desc *pd)
0427 {
0428 unsigned int outs;
0429 struct scmi_registered_event *r_evt;
0430
0431 outs = kfifo_out(&eq->kfifo, pd->eh,
0432 sizeof(struct scmi_event_header));
0433 if (!outs)
0434 return NULL;
0435 if (outs != sizeof(struct scmi_event_header)) {
0436 dev_err(pd->ni->handle->dev, "corrupted EVT header. Flush.\n");
0437 kfifo_reset_out(&eq->kfifo);
0438 return NULL;
0439 }
0440
0441 r_evt = SCMI_GET_REVT_FROM_PD(pd, pd->eh->evt_id);
0442 if (!r_evt)
0443 r_evt = ERR_PTR(-EINVAL);
0444
0445 return r_evt;
0446 }
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461 static inline bool
0462 scmi_process_event_payload(struct events_queue *eq,
0463 struct scmi_registered_events_desc *pd,
0464 struct scmi_registered_event *r_evt)
0465 {
0466 u32 src_id, key;
0467 unsigned int outs;
0468 void *report = NULL;
0469
0470 outs = kfifo_out(&eq->kfifo, pd->eh->payld, pd->eh->payld_sz);
0471 if (!outs)
0472 return false;
0473
0474
0475 pd->in_flight = NULL;
0476
0477 if (outs != pd->eh->payld_sz) {
0478 dev_err(pd->ni->handle->dev, "corrupted EVT Payload. Flush.\n");
0479 kfifo_reset_out(&eq->kfifo);
0480 return false;
0481 }
0482
0483 if (IS_ERR(r_evt)) {
0484 dev_warn(pd->ni->handle->dev,
0485 "SKIP UNKNOWN EVT - proto:%X evt:%d\n",
0486 pd->id, pd->eh->evt_id);
0487 return true;
0488 }
0489
0490 report = REVT_FILL_REPORT(r_evt, pd->eh->evt_id, pd->eh->timestamp,
0491 pd->eh->payld, pd->eh->payld_sz,
0492 r_evt->report, &src_id);
0493 if (!report) {
0494 dev_err(pd->ni->handle->dev,
0495 "report not available - proto:%X evt:%d\n",
0496 pd->id, pd->eh->evt_id);
0497 return true;
0498 }
0499
0500
0501 key = MAKE_ALL_SRCS_KEY(pd->id, pd->eh->evt_id);
0502 scmi_lookup_and_call_event_chain(pd->ni, key, report);
0503
0504
0505 key = MAKE_HASH_KEY(pd->id, pd->eh->evt_id, src_id);
0506 scmi_lookup_and_call_event_chain(pd->ni, key, report);
0507
0508 return true;
0509 }
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536 static void scmi_events_dispatcher(struct work_struct *work)
0537 {
0538 struct events_queue *eq;
0539 struct scmi_registered_events_desc *pd;
0540 struct scmi_registered_event *r_evt;
0541
0542 eq = container_of(work, struct events_queue, notify_work);
0543 pd = container_of(eq, struct scmi_registered_events_desc, equeue);
0544
0545
0546
0547
0548
0549
0550
0551 do {
0552 if (!pd->in_flight) {
0553 r_evt = scmi_process_event_header(eq, pd);
0554 if (!r_evt)
0555 break;
0556 pd->in_flight = r_evt;
0557 } else {
0558 r_evt = pd->in_flight;
0559 }
0560 } while (scmi_process_event_payload(eq, pd, r_evt));
0561 }
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578 int scmi_notify(const struct scmi_handle *handle, u8 proto_id, u8 evt_id,
0579 const void *buf, size_t len, ktime_t ts)
0580 {
0581 struct scmi_registered_event *r_evt;
0582 struct scmi_event_header eh;
0583 struct scmi_notify_instance *ni;
0584
0585 ni = scmi_notification_instance_data_get(handle);
0586 if (!ni)
0587 return 0;
0588
0589 r_evt = SCMI_GET_REVT(ni, proto_id, evt_id);
0590 if (!r_evt)
0591 return -EINVAL;
0592
0593 if (len > r_evt->evt->max_payld_sz) {
0594 dev_err(handle->dev, "discard badly sized message\n");
0595 return -EINVAL;
0596 }
0597 if (kfifo_avail(&r_evt->proto->equeue.kfifo) < sizeof(eh) + len) {
0598 dev_warn(handle->dev,
0599 "queue full, dropping proto_id:%d evt_id:%d ts:%lld\n",
0600 proto_id, evt_id, ktime_to_ns(ts));
0601 return -ENOMEM;
0602 }
0603
0604 eh.timestamp = ts;
0605 eh.evt_id = evt_id;
0606 eh.payld_sz = len;
0607
0608
0609
0610
0611
0612 kfifo_in(&r_evt->proto->equeue.kfifo, &eh, sizeof(eh));
0613 kfifo_in(&r_evt->proto->equeue.kfifo, buf, len);
0614
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624
0625
0626 queue_work(r_evt->proto->equeue.wq,
0627 &r_evt->proto->equeue.notify_work);
0628
0629 return 0;
0630 }
0631
0632
0633
0634
0635
0636 static void scmi_kfifo_free(void *kfifo)
0637 {
0638 kfifo_free((struct kfifo *)kfifo);
0639 }
0640
0641
0642
0643
0644
0645
0646
0647
0648
0649
0650
0651 static int scmi_initialize_events_queue(struct scmi_notify_instance *ni,
0652 struct events_queue *equeue, size_t sz)
0653 {
0654 int ret;
0655
0656 if (kfifo_alloc(&equeue->kfifo, sz, GFP_KERNEL))
0657 return -ENOMEM;
0658
0659 equeue->sz = kfifo_size(&equeue->kfifo);
0660
0661 ret = devm_add_action_or_reset(ni->handle->dev, scmi_kfifo_free,
0662 &equeue->kfifo);
0663 if (ret)
0664 return ret;
0665
0666 INIT_WORK(&equeue->notify_work, scmi_events_dispatcher);
0667 equeue->wq = ni->notify_wq;
0668
0669 return ret;
0670 }
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690 static struct scmi_registered_events_desc *
0691 scmi_allocate_registered_events_desc(struct scmi_notify_instance *ni,
0692 u8 proto_id, size_t queue_sz, size_t eh_sz,
0693 int num_events,
0694 const struct scmi_event_ops *ops)
0695 {
0696 int ret;
0697 struct scmi_registered_events_desc *pd;
0698
0699
0700 smp_rmb();
0701 if (WARN_ON(ni->registered_protocols[proto_id]))
0702 return ERR_PTR(-EINVAL);
0703
0704 pd = devm_kzalloc(ni->handle->dev, sizeof(*pd), GFP_KERNEL);
0705 if (!pd)
0706 return ERR_PTR(-ENOMEM);
0707 pd->id = proto_id;
0708 pd->ops = ops;
0709 pd->ni = ni;
0710
0711 ret = scmi_initialize_events_queue(ni, &pd->equeue, queue_sz);
0712 if (ret)
0713 return ERR_PTR(ret);
0714
0715 pd->eh = devm_kzalloc(ni->handle->dev, eh_sz, GFP_KERNEL);
0716 if (!pd->eh)
0717 return ERR_PTR(-ENOMEM);
0718 pd->eh_sz = eh_sz;
0719
0720 pd->registered_events = devm_kcalloc(ni->handle->dev, num_events,
0721 sizeof(char *), GFP_KERNEL);
0722 if (!pd->registered_events)
0723 return ERR_PTR(-ENOMEM);
0724 pd->num_events = num_events;
0725
0726
0727 mutex_init(&pd->registered_mtx);
0728 hash_init(pd->registered_events_handlers);
0729
0730 return pd;
0731 }
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745
0746
0747
0748 int scmi_register_protocol_events(const struct scmi_handle *handle, u8 proto_id,
0749 const struct scmi_protocol_handle *ph,
0750 const struct scmi_protocol_events *ee)
0751 {
0752 int i;
0753 unsigned int num_sources;
0754 size_t payld_sz = 0;
0755 struct scmi_registered_events_desc *pd;
0756 struct scmi_notify_instance *ni;
0757 const struct scmi_event *evt;
0758
0759 if (!ee || !ee->ops || !ee->evts || !ph ||
0760 (!ee->num_sources && !ee->ops->get_num_sources))
0761 return -EINVAL;
0762
0763 ni = scmi_notification_instance_data_get(handle);
0764 if (!ni)
0765 return -ENOMEM;
0766
0767
0768 if (ee->num_sources) {
0769 num_sources = ee->num_sources;
0770 } else {
0771 int nsrc = ee->ops->get_num_sources(ph);
0772
0773 if (nsrc <= 0)
0774 return -EINVAL;
0775 num_sources = nsrc;
0776 }
0777
0778 evt = ee->evts;
0779 for (i = 0; i < ee->num_events; i++)
0780 payld_sz = max_t(size_t, payld_sz, evt[i].max_payld_sz);
0781 payld_sz += sizeof(struct scmi_event_header);
0782
0783 pd = scmi_allocate_registered_events_desc(ni, proto_id, ee->queue_sz,
0784 payld_sz, ee->num_events,
0785 ee->ops);
0786 if (IS_ERR(pd))
0787 return PTR_ERR(pd);
0788
0789 pd->ph = ph;
0790 for (i = 0; i < ee->num_events; i++, evt++) {
0791 struct scmi_registered_event *r_evt;
0792
0793 r_evt = devm_kzalloc(ni->handle->dev, sizeof(*r_evt),
0794 GFP_KERNEL);
0795 if (!r_evt)
0796 return -ENOMEM;
0797 r_evt->proto = pd;
0798 r_evt->evt = evt;
0799
0800 r_evt->sources = devm_kcalloc(ni->handle->dev, num_sources,
0801 sizeof(refcount_t), GFP_KERNEL);
0802 if (!r_evt->sources)
0803 return -ENOMEM;
0804 r_evt->num_sources = num_sources;
0805 mutex_init(&r_evt->sources_mtx);
0806
0807 r_evt->report = devm_kzalloc(ni->handle->dev,
0808 evt->max_report_sz, GFP_KERNEL);
0809 if (!r_evt->report)
0810 return -ENOMEM;
0811
0812 pd->registered_events[i] = r_evt;
0813
0814 smp_wmb();
0815 dev_dbg(handle->dev, "registered event - %lX\n",
0816 MAKE_ALL_SRCS_KEY(r_evt->proto->id, r_evt->evt->id));
0817 }
0818
0819
0820 ni->registered_protocols[proto_id] = pd;
0821
0822 smp_wmb();
0823
0824
0825
0826
0827
0828 schedule_work(&ni->init_work);
0829
0830 return 0;
0831 }
0832
0833
0834
0835
0836
0837
0838
0839 void scmi_deregister_protocol_events(const struct scmi_handle *handle,
0840 u8 proto_id)
0841 {
0842 struct scmi_notify_instance *ni;
0843 struct scmi_registered_events_desc *pd;
0844
0845 ni = scmi_notification_instance_data_get(handle);
0846 if (!ni)
0847 return;
0848
0849 pd = ni->registered_protocols[proto_id];
0850 if (!pd)
0851 return;
0852
0853 ni->registered_protocols[proto_id] = NULL;
0854
0855 smp_wmb();
0856
0857 cancel_work_sync(&pd->equeue.notify_work);
0858 }
0859
0860
0861
0862
0863
0864
0865
0866
0867
0868
0869
0870
0871
0872
0873
0874
0875 static struct scmi_event_handler *
0876 scmi_allocate_event_handler(struct scmi_notify_instance *ni, u32 evt_key)
0877 {
0878 struct scmi_event_handler *hndl;
0879
0880 hndl = kzalloc(sizeof(*hndl), GFP_KERNEL);
0881 if (!hndl)
0882 return NULL;
0883 hndl->key = evt_key;
0884 BLOCKING_INIT_NOTIFIER_HEAD(&hndl->chain);
0885 refcount_set(&hndl->users, 1);
0886
0887 hash_add(ni->pending_events_handlers, &hndl->hash, hndl->key);
0888
0889 return hndl;
0890 }
0891
0892
0893
0894
0895
0896
0897
0898
0899 static void scmi_free_event_handler(struct scmi_event_handler *hndl)
0900 {
0901 hash_del(&hndl->hash);
0902 kfree(hndl);
0903 }
0904
0905
0906
0907
0908
0909
0910
0911
0912
0913
0914
0915
0916
0917 static inline int scmi_bind_event_handler(struct scmi_notify_instance *ni,
0918 struct scmi_event_handler *hndl)
0919 {
0920 struct scmi_registered_event *r_evt;
0921
0922 r_evt = SCMI_GET_REVT(ni, KEY_XTRACT_PROTO_ID(hndl->key),
0923 KEY_XTRACT_EVT_ID(hndl->key));
0924 if (!r_evt)
0925 return -EINVAL;
0926
0927
0928
0929
0930
0931 hash_del(&hndl->hash);
0932
0933
0934
0935
0936
0937
0938
0939 scmi_protocol_acquire(ni->handle, KEY_XTRACT_PROTO_ID(hndl->key));
0940 hndl->r_evt = r_evt;
0941
0942 mutex_lock(&r_evt->proto->registered_mtx);
0943 hash_add(r_evt->proto->registered_events_handlers,
0944 &hndl->hash, hndl->key);
0945 mutex_unlock(&r_evt->proto->registered_mtx);
0946
0947 return 0;
0948 }
0949
0950
0951
0952
0953
0954
0955
0956
0957
0958
0959
0960
0961
0962
0963
0964 static inline int scmi_valid_pending_handler(struct scmi_notify_instance *ni,
0965 struct scmi_event_handler *hndl)
0966 {
0967 struct scmi_registered_events_desc *pd;
0968
0969 if (!IS_HNDL_PENDING(hndl))
0970 return -EINVAL;
0971
0972 pd = SCMI_GET_PROTO(ni, KEY_XTRACT_PROTO_ID(hndl->key));
0973 if (pd)
0974 return -EINVAL;
0975
0976 return 0;
0977 }
0978
0979
0980
0981
0982
0983
0984
0985
0986
0987
0988
0989
0990
0991
0992
0993
0994
0995
0996 static int scmi_register_event_handler(struct scmi_notify_instance *ni,
0997 struct scmi_event_handler *hndl)
0998 {
0999 int ret;
1000
1001 ret = scmi_bind_event_handler(ni, hndl);
1002 if (!ret) {
1003 dev_dbg(ni->handle->dev, "registered NEW handler - key:%X\n",
1004 hndl->key);
1005 } else {
1006 ret = scmi_valid_pending_handler(ni, hndl);
1007 if (!ret)
1008 dev_dbg(ni->handle->dev,
1009 "registered PENDING handler - key:%X\n",
1010 hndl->key);
1011 }
1012
1013 return ret;
1014 }
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046 static inline struct scmi_event_handler *
1047 __scmi_event_handler_get_ops(struct scmi_notify_instance *ni,
1048 u32 evt_key, bool create)
1049 {
1050 struct scmi_registered_event *r_evt;
1051 struct scmi_event_handler *hndl = NULL;
1052
1053 r_evt = SCMI_GET_REVT(ni, KEY_XTRACT_PROTO_ID(evt_key),
1054 KEY_XTRACT_EVT_ID(evt_key));
1055
1056 mutex_lock(&ni->pending_mtx);
1057
1058 if (r_evt) {
1059 mutex_lock(&r_evt->proto->registered_mtx);
1060 hndl = KEY_FIND(r_evt->proto->registered_events_handlers,
1061 hndl, evt_key);
1062 if (hndl)
1063 refcount_inc(&hndl->users);
1064 mutex_unlock(&r_evt->proto->registered_mtx);
1065 }
1066
1067
1068 if (!hndl) {
1069 hndl = KEY_FIND(ni->pending_events_handlers, hndl, evt_key);
1070 if (hndl)
1071 refcount_inc(&hndl->users);
1072 }
1073
1074
1075 if (!hndl && create) {
1076 hndl = scmi_allocate_event_handler(ni, evt_key);
1077 if (hndl && scmi_register_event_handler(ni, hndl)) {
1078 dev_dbg(ni->handle->dev,
1079 "purging UNKNOWN handler - key:%X\n",
1080 hndl->key);
1081
1082 scmi_put_handler_unlocked(ni, hndl);
1083 hndl = NULL;
1084 }
1085 }
1086 mutex_unlock(&ni->pending_mtx);
1087
1088 return hndl;
1089 }
1090
1091 static struct scmi_event_handler *
1092 scmi_get_handler(struct scmi_notify_instance *ni, u32 evt_key)
1093 {
1094 return __scmi_event_handler_get_ops(ni, evt_key, false);
1095 }
1096
1097 static struct scmi_event_handler *
1098 scmi_get_or_create_handler(struct scmi_notify_instance *ni, u32 evt_key)
1099 {
1100 return __scmi_event_handler_get_ops(ni, evt_key, true);
1101 }
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114 static struct scmi_event_handler *
1115 scmi_get_active_handler(struct scmi_notify_instance *ni, u32 evt_key)
1116 {
1117 struct scmi_registered_event *r_evt;
1118 struct scmi_event_handler *hndl = NULL;
1119
1120 r_evt = SCMI_GET_REVT(ni, KEY_XTRACT_PROTO_ID(evt_key),
1121 KEY_XTRACT_EVT_ID(evt_key));
1122 if (r_evt) {
1123 mutex_lock(&r_evt->proto->registered_mtx);
1124 hndl = KEY_FIND(r_evt->proto->registered_events_handlers,
1125 hndl, evt_key);
1126 if (hndl)
1127 refcount_inc(&hndl->users);
1128 mutex_unlock(&r_evt->proto->registered_mtx);
1129 }
1130
1131 return hndl;
1132 }
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147 static inline int __scmi_enable_evt(struct scmi_registered_event *r_evt,
1148 u32 src_id, bool enable)
1149 {
1150 int retvals = 0;
1151 u32 num_sources;
1152 refcount_t *sid;
1153
1154 if (src_id == SRC_ID_MASK) {
1155 src_id = 0;
1156 num_sources = r_evt->num_sources;
1157 } else if (src_id < r_evt->num_sources) {
1158 num_sources = 1;
1159 } else {
1160 return -EINVAL;
1161 }
1162
1163 mutex_lock(&r_evt->sources_mtx);
1164 if (enable) {
1165 for (; num_sources; src_id++, num_sources--) {
1166 int ret = 0;
1167
1168 sid = &r_evt->sources[src_id];
1169 if (refcount_read(sid) == 0) {
1170 ret = REVT_NOTIFY_ENABLE(r_evt, r_evt->evt->id,
1171 src_id);
1172 if (!ret)
1173 refcount_set(sid, 1);
1174 } else {
1175 refcount_inc(sid);
1176 }
1177 retvals += !ret;
1178 }
1179 } else {
1180 for (; num_sources; src_id++, num_sources--) {
1181 sid = &r_evt->sources[src_id];
1182 if (refcount_dec_and_test(sid))
1183 REVT_NOTIFY_DISABLE(r_evt,
1184 r_evt->evt->id, src_id);
1185 }
1186 retvals = 1;
1187 }
1188 mutex_unlock(&r_evt->sources_mtx);
1189
1190 return retvals ? 0 : -EINVAL;
1191 }
1192
1193 static int scmi_enable_events(struct scmi_event_handler *hndl)
1194 {
1195 int ret = 0;
1196
1197 if (!hndl->enabled) {
1198 ret = __scmi_enable_evt(hndl->r_evt,
1199 KEY_XTRACT_SRC_ID(hndl->key), true);
1200 if (!ret)
1201 hndl->enabled = true;
1202 }
1203
1204 return ret;
1205 }
1206
1207 static int scmi_disable_events(struct scmi_event_handler *hndl)
1208 {
1209 int ret = 0;
1210
1211 if (hndl->enabled) {
1212 ret = __scmi_enable_evt(hndl->r_evt,
1213 KEY_XTRACT_SRC_ID(hndl->key), false);
1214 if (!ret)
1215 hndl->enabled = false;
1216 }
1217
1218 return ret;
1219 }
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235 static bool scmi_put_handler_unlocked(struct scmi_notify_instance *ni,
1236 struct scmi_event_handler *hndl)
1237 {
1238 bool freed = false;
1239
1240 if (refcount_dec_and_test(&hndl->users)) {
1241 if (!IS_HNDL_PENDING(hndl))
1242 scmi_disable_events(hndl);
1243 scmi_free_event_handler(hndl);
1244 freed = true;
1245 }
1246
1247 return freed;
1248 }
1249
1250 static void scmi_put_handler(struct scmi_notify_instance *ni,
1251 struct scmi_event_handler *hndl)
1252 {
1253 bool freed;
1254 u8 protocol_id;
1255 struct scmi_registered_event *r_evt = hndl->r_evt;
1256
1257 mutex_lock(&ni->pending_mtx);
1258 if (r_evt) {
1259 protocol_id = r_evt->proto->id;
1260 mutex_lock(&r_evt->proto->registered_mtx);
1261 }
1262
1263 freed = scmi_put_handler_unlocked(ni, hndl);
1264
1265 if (r_evt) {
1266 mutex_unlock(&r_evt->proto->registered_mtx);
1267
1268
1269
1270
1271
1272
1273 if (freed)
1274 scmi_protocol_release(ni->handle, protocol_id);
1275 }
1276 mutex_unlock(&ni->pending_mtx);
1277 }
1278
1279 static void scmi_put_active_handler(struct scmi_notify_instance *ni,
1280 struct scmi_event_handler *hndl)
1281 {
1282 bool freed;
1283 struct scmi_registered_event *r_evt = hndl->r_evt;
1284 u8 protocol_id = r_evt->proto->id;
1285
1286 mutex_lock(&r_evt->proto->registered_mtx);
1287 freed = scmi_put_handler_unlocked(ni, hndl);
1288 mutex_unlock(&r_evt->proto->registered_mtx);
1289 if (freed)
1290 scmi_protocol_release(ni->handle, protocol_id);
1291 }
1292
1293
1294
1295
1296
1297
1298
1299 static int scmi_event_handler_enable_events(struct scmi_event_handler *hndl)
1300 {
1301 if (scmi_enable_events(hndl)) {
1302 pr_err("Failed to ENABLE events for key:%X !\n", hndl->key);
1303 return -EINVAL;
1304 }
1305
1306 return 0;
1307 }
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342 static int scmi_notifier_register(const struct scmi_handle *handle,
1343 u8 proto_id, u8 evt_id, const u32 *src_id,
1344 struct notifier_block *nb)
1345 {
1346 int ret = 0;
1347 u32 evt_key;
1348 struct scmi_event_handler *hndl;
1349 struct scmi_notify_instance *ni;
1350
1351 ni = scmi_notification_instance_data_get(handle);
1352 if (!ni)
1353 return -ENODEV;
1354
1355 evt_key = MAKE_HASH_KEY(proto_id, evt_id,
1356 src_id ? *src_id : SRC_ID_MASK);
1357 hndl = scmi_get_or_create_handler(ni, evt_key);
1358 if (!hndl)
1359 return -EINVAL;
1360
1361 blocking_notifier_chain_register(&hndl->chain, nb);
1362
1363
1364 if (!IS_HNDL_PENDING(hndl)) {
1365 ret = scmi_event_handler_enable_events(hndl);
1366 if (ret)
1367 scmi_put_handler(ni, hndl);
1368 }
1369
1370 return ret;
1371 }
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389 static int scmi_notifier_unregister(const struct scmi_handle *handle,
1390 u8 proto_id, u8 evt_id, const u32 *src_id,
1391 struct notifier_block *nb)
1392 {
1393 u32 evt_key;
1394 struct scmi_event_handler *hndl;
1395 struct scmi_notify_instance *ni;
1396
1397 ni = scmi_notification_instance_data_get(handle);
1398 if (!ni)
1399 return -ENODEV;
1400
1401 evt_key = MAKE_HASH_KEY(proto_id, evt_id,
1402 src_id ? *src_id : SRC_ID_MASK);
1403 hndl = scmi_get_handler(ni, evt_key);
1404 if (!hndl)
1405 return -EINVAL;
1406
1407
1408
1409
1410
1411 blocking_notifier_chain_unregister(&hndl->chain, nb);
1412 scmi_put_handler(ni, hndl);
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425 scmi_put_handler(ni, hndl);
1426
1427 return 0;
1428 }
1429
1430 struct scmi_notifier_devres {
1431 const struct scmi_handle *handle;
1432 u8 proto_id;
1433 u8 evt_id;
1434 u32 __src_id;
1435 u32 *src_id;
1436 struct notifier_block *nb;
1437 };
1438
1439 static void scmi_devm_release_notifier(struct device *dev, void *res)
1440 {
1441 struct scmi_notifier_devres *dres = res;
1442
1443 scmi_notifier_unregister(dres->handle, dres->proto_id, dres->evt_id,
1444 dres->src_id, dres->nb);
1445 }
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463 static int scmi_devm_notifier_register(struct scmi_device *sdev,
1464 u8 proto_id, u8 evt_id,
1465 const u32 *src_id,
1466 struct notifier_block *nb)
1467 {
1468 int ret;
1469 struct scmi_notifier_devres *dres;
1470
1471 dres = devres_alloc(scmi_devm_release_notifier,
1472 sizeof(*dres), GFP_KERNEL);
1473 if (!dres)
1474 return -ENOMEM;
1475
1476 ret = scmi_notifier_register(sdev->handle, proto_id,
1477 evt_id, src_id, nb);
1478 if (ret) {
1479 devres_free(dres);
1480 return ret;
1481 }
1482
1483 dres->handle = sdev->handle;
1484 dres->proto_id = proto_id;
1485 dres->evt_id = evt_id;
1486 dres->nb = nb;
1487 if (src_id) {
1488 dres->__src_id = *src_id;
1489 dres->src_id = &dres->__src_id;
1490 } else {
1491 dres->src_id = NULL;
1492 }
1493 devres_add(&sdev->dev, dres);
1494
1495 return ret;
1496 }
1497
1498 static int scmi_devm_notifier_match(struct device *dev, void *res, void *data)
1499 {
1500 struct scmi_notifier_devres *dres = res;
1501 struct scmi_notifier_devres *xres = data;
1502
1503 if (WARN_ON(!dres || !xres))
1504 return 0;
1505
1506 return dres->proto_id == xres->proto_id &&
1507 dres->evt_id == xres->evt_id &&
1508 dres->nb == xres->nb &&
1509 ((!dres->src_id && !xres->src_id) ||
1510 (dres->src_id && xres->src_id &&
1511 dres->__src_id == xres->__src_id));
1512 }
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531 static int scmi_devm_notifier_unregister(struct scmi_device *sdev,
1532 u8 proto_id, u8 evt_id,
1533 const u32 *src_id,
1534 struct notifier_block *nb)
1535 {
1536 int ret;
1537 struct scmi_notifier_devres dres;
1538
1539 dres.handle = sdev->handle;
1540 dres.proto_id = proto_id;
1541 dres.evt_id = evt_id;
1542 if (src_id) {
1543 dres.__src_id = *src_id;
1544 dres.src_id = &dres.__src_id;
1545 } else {
1546 dres.src_id = NULL;
1547 }
1548
1549 ret = devres_release(&sdev->dev, scmi_devm_release_notifier,
1550 scmi_devm_notifier_match, &dres);
1551
1552 WARN_ON(ret);
1553
1554 return ret;
1555 }
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567 static void scmi_protocols_late_init(struct work_struct *work)
1568 {
1569 int bkt;
1570 struct scmi_event_handler *hndl;
1571 struct scmi_notify_instance *ni;
1572 struct hlist_node *tmp;
1573
1574 ni = container_of(work, struct scmi_notify_instance, init_work);
1575
1576
1577 smp_rmb();
1578
1579 mutex_lock(&ni->pending_mtx);
1580 hash_for_each_safe(ni->pending_events_handlers, bkt, tmp, hndl, hash) {
1581 int ret;
1582
1583 ret = scmi_bind_event_handler(ni, hndl);
1584 if (!ret) {
1585 dev_dbg(ni->handle->dev,
1586 "finalized PENDING handler - key:%X\n",
1587 hndl->key);
1588 ret = scmi_event_handler_enable_events(hndl);
1589 if (ret) {
1590 dev_dbg(ni->handle->dev,
1591 "purging INVALID handler - key:%X\n",
1592 hndl->key);
1593 scmi_put_active_handler(ni, hndl);
1594 }
1595 } else {
1596 ret = scmi_valid_pending_handler(ni, hndl);
1597 if (ret) {
1598 dev_dbg(ni->handle->dev,
1599 "purging PENDING handler - key:%X\n",
1600 hndl->key);
1601
1602 scmi_put_handler_unlocked(ni, hndl);
1603 }
1604 }
1605 }
1606 mutex_unlock(&ni->pending_mtx);
1607 }
1608
1609
1610
1611
1612
1613 static const struct scmi_notify_ops notify_ops = {
1614 .devm_event_notifier_register = scmi_devm_notifier_register,
1615 .devm_event_notifier_unregister = scmi_devm_notifier_unregister,
1616 .event_notifier_register = scmi_notifier_register,
1617 .event_notifier_unregister = scmi_notifier_unregister,
1618 };
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646 int scmi_notification_init(struct scmi_handle *handle)
1647 {
1648 void *gid;
1649 struct scmi_notify_instance *ni;
1650
1651 gid = devres_open_group(handle->dev, NULL, GFP_KERNEL);
1652 if (!gid)
1653 return -ENOMEM;
1654
1655 ni = devm_kzalloc(handle->dev, sizeof(*ni), GFP_KERNEL);
1656 if (!ni)
1657 goto err;
1658
1659 ni->gid = gid;
1660 ni->handle = handle;
1661
1662 ni->registered_protocols = devm_kcalloc(handle->dev, SCMI_MAX_PROTO,
1663 sizeof(char *), GFP_KERNEL);
1664 if (!ni->registered_protocols)
1665 goto err;
1666
1667 ni->notify_wq = alloc_workqueue(dev_name(handle->dev),
1668 WQ_UNBOUND | WQ_FREEZABLE | WQ_SYSFS,
1669 0);
1670 if (!ni->notify_wq)
1671 goto err;
1672
1673 mutex_init(&ni->pending_mtx);
1674 hash_init(ni->pending_events_handlers);
1675
1676 INIT_WORK(&ni->init_work, scmi_protocols_late_init);
1677
1678 scmi_notification_instance_data_set(handle, ni);
1679 handle->notify_ops = ¬ify_ops;
1680
1681 smp_wmb();
1682
1683 dev_info(handle->dev, "Core Enabled.\n");
1684
1685 devres_close_group(handle->dev, ni->gid);
1686
1687 return 0;
1688
1689 err:
1690 dev_warn(handle->dev, "Initialization Failed.\n");
1691 devres_release_group(handle->dev, gid);
1692 return -ENOMEM;
1693 }
1694
1695
1696
1697
1698
1699 void scmi_notification_exit(struct scmi_handle *handle)
1700 {
1701 struct scmi_notify_instance *ni;
1702
1703 ni = scmi_notification_instance_data_get(handle);
1704 if (!ni)
1705 return;
1706 scmi_notification_instance_data_set(handle, NULL);
1707
1708
1709 destroy_workqueue(ni->notify_wq);
1710
1711 devres_release_group(ni->handle->dev, ni->gid);
1712 }