1 /* SPDX-License-Identifier: BSD-3-Clause
2 *
3 * Copyright(c) 2016 Intel Corporation. All rights reserved.
4 *
5 * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
6 */
7
8 #ifndef __SOF_LIB_NOTIFIER_H__
9 #define __SOF_LIB_NOTIFIER_H__
10
11 #include <sof/bit.h>
12 #include <sof/list.h>
13 #include <sof/spinlock.h>
14 #include <sof/sof.h>
15 #include <stdint.h>
16
17 /* notifier target core masks */
18 #define NOTIFIER_TARGET_CORE_MASK(x) (1 << (x))
19 #define NOTIFIER_TARGET_CORE_LOCAL NOTIFIER_TARGET_CORE_MASK(cpu_get_id())
20 #define NOTIFIER_TARGET_CORE_ALL_MASK 0xFFFFFFFF
21
22 /** \brief Notifier flags. */
23 #define NOTIFIER_FLAG_AGGREGATE BIT(0)
24
25 enum notify_id {
26 NOTIFIER_ID_CPU_FREQ = 0, /* struct clock_notify_data * */
27 NOTIFIER_ID_SSP_FREQ, /* struct clock_notify_data * */
28 NOTIFIER_ID_KPB_CLIENT_EVT, /* struct kpb_event_data * */
29 NOTIFIER_ID_DMA_DOMAIN_CHANGE, /* struct dma_chan_data * */
30 NOTIFIER_ID_BUFFER_PRODUCE, /* struct buffer_cb_transact* */
31 NOTIFIER_ID_BUFFER_CONSUME, /* struct buffer_cb_transact* */
32 NOTIFIER_ID_BUFFER_FREE, /* struct buffer_cb_free* */
33 NOTIFIER_ID_DMA_COPY, /* struct dma_cb_data* */
34 NOTIFIER_ID_LL_POST_RUN, /* NULL */
35 NOTIFIER_ID_DMA_IRQ, /* struct dma_chan_data * */
36 NOTIFIER_ID_DAI_TRIGGER, /* struct dai_group * */
37 NOTIFIER_ID_COUNT
38 };
39
40 struct notify {
41 struct list_item list[NOTIFIER_ID_COUNT]; /* list of callback handles */
42 spinlock_t lock; /* list lock */
43 };
44
45 struct notify_data {
46 const void *caller;
47 enum notify_id type;
48 uint32_t data_size;
49 void *data;
50 };
51
52 #ifdef CLK_SSP
53 #define NOTIFIER_CLK_CHANGE_ID(clk) \
54 ((clk) == CLK_SSP ? NOTIFIER_ID_SSP_FREQ : NOTIFIER_ID_CPU_FREQ)
55 #else
56 #define NOTIFIER_CLK_CHANGE_ID(clk) NOTIFIER_ID_CPU_FREQ
57 #endif
58
59 struct notify **arch_notify_get(void);
60
61 /** Register a callback to be run when event 'type' happens.
62 *
63 * The identifier for un-registration is the tuple (receiver_data,
64 * caller_id_filter, event_type), the callback argument is not part of
65 * it.
66 *
67 * caller_data argument from notifier_event()
68 *
69 * @param receiver_data private data passed to the callback.
70 * @param caller_id_filter optional, can be used to be notified only by
71 * some specific notifier_event() calls when not NULL.
72 * @param event_type list of callbacks to be added to
73 * @param callback callback function
74 * @param flags see NOTIFIER_FLAG_* above
75 */
76 int notifier_register(void *receiver_data, void *caller_id_filter, enum notify_id event_type,
77 void (*callback)(void *receiver_data, enum notify_id event_type,
78 void *caller_data),
79 uint32_t flags);
80
81 /** Unregister all callbacks matching that arguments tuple. NULL acts
82 * as a wildcard.
83 */
84 void notifier_unregister(void *receiver_data_filter, void *caller_id_filter, enum notify_id type);
85
86 /** Unregister callbacks matching the arguments for every notify_id.
87 * A NULL parameter acts as a wildcard.
88 */
89 void notifier_unregister_all(void *receiver_data_filter, void *caller_id_filter);
90
91 void notifier_notify_remote(void);
92
93 /* data_size is required to manage cache coherency for notifications
94 * across cores.
95 */
96 void notifier_event(const void *caller_id, enum notify_id event_type, uint32_t core_mask,
97 void *caller_data, uint32_t data_size);
98
99 void init_system_notify(struct sof *sof);
100
101 void free_system_notify(void);
102
notify_data_get(void)103 static inline struct notify_data *notify_data_get(void)
104 {
105 return sof_get()->notify_data;
106 }
107
108 #endif /* __SOF_LIB_NOTIFIER_H__ */
109