1 // SPDX-License-Identifier: GPL-2.0
3 * System Control and Management Interface (SCMI) System Power Protocol
5 * Copyright (C) 2020 ARM Ltd.
8 #define pr_fmt(fmt) "SCMI Notifications SYSTEM - " fmt
10 #include <linux/scmi_protocol.h>
15 #define SCMI_SYSTEM_NUM_SOURCES 1
17 enum scmi_system_protocol_cmd
{
18 SYSTEM_POWER_STATE_NOTIFY
= 0x5,
21 struct scmi_system_power_state_notify
{
25 struct scmi_system_power_state_notifier_payld
{
31 struct scmi_system_info
{
35 static int scmi_system_request_notify(const struct scmi_handle
*handle
,
40 struct scmi_system_power_state_notify
*notify
;
42 ret
= scmi_xfer_get_init(handle
, SYSTEM_POWER_STATE_NOTIFY
,
43 SCMI_PROTOCOL_SYSTEM
, sizeof(*notify
), 0, &t
);
48 notify
->notify_enable
= enable
? cpu_to_le32(BIT(0)) : 0;
50 ret
= scmi_do_xfer(handle
, t
);
52 scmi_xfer_put(handle
, t
);
56 static int scmi_system_set_notify_enabled(const struct scmi_handle
*handle
,
57 u8 evt_id
, u32 src_id
, bool enable
)
61 ret
= scmi_system_request_notify(handle
, enable
);
63 pr_debug("FAIL_ENABLE - evt[%X] - ret:%d\n", evt_id
, ret
);
68 static void *scmi_system_fill_custom_report(const struct scmi_handle
*handle
,
69 u8 evt_id
, ktime_t timestamp
,
70 const void *payld
, size_t payld_sz
,
71 void *report
, u32
*src_id
)
73 const struct scmi_system_power_state_notifier_payld
*p
= payld
;
74 struct scmi_system_power_state_notifier_report
*r
= report
;
76 if (evt_id
!= SCMI_EVENT_SYSTEM_POWER_STATE_NOTIFIER
||
77 sizeof(*p
) != payld_sz
)
80 r
->timestamp
= timestamp
;
81 r
->agent_id
= le32_to_cpu(p
->agent_id
);
82 r
->flags
= le32_to_cpu(p
->flags
);
83 r
->system_state
= le32_to_cpu(p
->system_state
);
89 static const struct scmi_event system_events
[] = {
91 .id
= SCMI_EVENT_SYSTEM_POWER_STATE_NOTIFIER
,
93 sizeof(struct scmi_system_power_state_notifier_payld
),
95 sizeof(struct scmi_system_power_state_notifier_report
),
99 static const struct scmi_event_ops system_event_ops
= {
100 .set_notify_enabled
= scmi_system_set_notify_enabled
,
101 .fill_custom_report
= scmi_system_fill_custom_report
,
104 static int scmi_system_protocol_init(struct scmi_handle
*handle
)
107 struct scmi_system_info
*pinfo
;
109 scmi_version_get(handle
, SCMI_PROTOCOL_SYSTEM
, &version
);
111 dev_dbg(handle
->dev
, "System Power Version %d.%d\n",
112 PROTOCOL_REV_MAJOR(version
), PROTOCOL_REV_MINOR(version
));
114 pinfo
= devm_kzalloc(handle
->dev
, sizeof(*pinfo
), GFP_KERNEL
);
118 scmi_register_protocol_events(handle
,
119 SCMI_PROTOCOL_SYSTEM
, SCMI_PROTO_QUEUE_SZ
,
122 ARRAY_SIZE(system_events
),
123 SCMI_SYSTEM_NUM_SOURCES
);
125 pinfo
->version
= version
;
126 handle
->system_priv
= pinfo
;
131 DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(SCMI_PROTOCOL_SYSTEM
, system
)