1*b4734308SPeng Fan // SPDX-License-Identifier: BSD-3-Clause 2*b4734308SPeng Fan /* 3*b4734308SPeng Fan * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. 4*b4734308SPeng Fan * Copyright (c) 2019-2020, Linaro Limited 5*b4734308SPeng Fan */ 6*b4734308SPeng Fan #include <cdefs.h> 7*b4734308SPeng Fan #include <string.h> 8*b4734308SPeng Fan 9*b4734308SPeng Fan #include <drivers/scmi-msg.h> 10*b4734308SPeng Fan #include <drivers/scmi.h> 11*b4734308SPeng Fan #include <lib/utils_def.h> 12*b4734308SPeng Fan 13*b4734308SPeng Fan #include "common.h" 14*b4734308SPeng Fan 15*b4734308SPeng Fan #pragma weak plat_scmi_clock_count 16*b4734308SPeng Fan #pragma weak plat_scmi_clock_get_name 17*b4734308SPeng Fan #pragma weak plat_scmi_clock_rates_array 18*b4734308SPeng Fan #pragma weak plat_scmi_clock_rates_by_step 19*b4734308SPeng Fan #pragma weak plat_scmi_clock_get_rate 20*b4734308SPeng Fan #pragma weak plat_scmi_clock_set_rate 21*b4734308SPeng Fan #pragma weak plat_scmi_clock_get_state 22*b4734308SPeng Fan #pragma weak plat_scmi_clock_set_state 23*b4734308SPeng Fan 24*b4734308SPeng Fan static bool message_id_is_supported(unsigned int message_id); 25*b4734308SPeng Fan 26*b4734308SPeng Fan size_t plat_scmi_clock_count(unsigned int agent_id __unused) 27*b4734308SPeng Fan { 28*b4734308SPeng Fan return 0U; 29*b4734308SPeng Fan } 30*b4734308SPeng Fan 31*b4734308SPeng Fan const char *plat_scmi_clock_get_name(unsigned int agent_id __unused, 32*b4734308SPeng Fan unsigned int scmi_id __unused) 33*b4734308SPeng Fan { 34*b4734308SPeng Fan return NULL; 35*b4734308SPeng Fan } 36*b4734308SPeng Fan 37*b4734308SPeng Fan int32_t plat_scmi_clock_rates_array(unsigned int agent_id __unused, 38*b4734308SPeng Fan unsigned int scmi_id __unused, 39*b4734308SPeng Fan unsigned long *rates __unused, 40*b4734308SPeng Fan size_t *nb_elts __unused) 41*b4734308SPeng Fan { 42*b4734308SPeng Fan return SCMI_NOT_SUPPORTED; 43*b4734308SPeng Fan } 44*b4734308SPeng Fan 45*b4734308SPeng Fan int32_t plat_scmi_clock_rates_by_step(unsigned int agent_id __unused, 46*b4734308SPeng Fan unsigned int scmi_id __unused, 47*b4734308SPeng Fan unsigned long *steps __unused) 48*b4734308SPeng Fan { 49*b4734308SPeng Fan return SCMI_NOT_SUPPORTED; 50*b4734308SPeng Fan } 51*b4734308SPeng Fan 52*b4734308SPeng Fan unsigned long plat_scmi_clock_get_rate(unsigned int agent_id __unused, 53*b4734308SPeng Fan unsigned int scmi_id __unused) 54*b4734308SPeng Fan { 55*b4734308SPeng Fan return 0U; 56*b4734308SPeng Fan } 57*b4734308SPeng Fan 58*b4734308SPeng Fan int32_t plat_scmi_clock_set_rate(unsigned int agent_id __unused, 59*b4734308SPeng Fan unsigned int scmi_id __unused, 60*b4734308SPeng Fan unsigned long rate __unused) 61*b4734308SPeng Fan { 62*b4734308SPeng Fan return SCMI_NOT_SUPPORTED; 63*b4734308SPeng Fan } 64*b4734308SPeng Fan 65*b4734308SPeng Fan int32_t plat_scmi_clock_get_state(unsigned int agent_id __unused, 66*b4734308SPeng Fan unsigned int scmi_id __unused) 67*b4734308SPeng Fan { 68*b4734308SPeng Fan return SCMI_NOT_SUPPORTED; 69*b4734308SPeng Fan } 70*b4734308SPeng Fan 71*b4734308SPeng Fan int32_t plat_scmi_clock_set_state(unsigned int agent_id __unused, 72*b4734308SPeng Fan unsigned int scmi_id __unused, 73*b4734308SPeng Fan bool enable_not_disable __unused) 74*b4734308SPeng Fan { 75*b4734308SPeng Fan return SCMI_NOT_SUPPORTED; 76*b4734308SPeng Fan } 77*b4734308SPeng Fan 78*b4734308SPeng Fan static void report_version(struct scmi_msg *msg) 79*b4734308SPeng Fan { 80*b4734308SPeng Fan struct scmi_protocol_version_p2a return_values = { 81*b4734308SPeng Fan .status = SCMI_SUCCESS, 82*b4734308SPeng Fan .version = SCMI_PROTOCOL_VERSION_CLOCK, 83*b4734308SPeng Fan }; 84*b4734308SPeng Fan 85*b4734308SPeng Fan if (msg->in_size != 0) { 86*b4734308SPeng Fan scmi_status_response(msg, SCMI_PROTOCOL_ERROR); 87*b4734308SPeng Fan return; 88*b4734308SPeng Fan } 89*b4734308SPeng Fan 90*b4734308SPeng Fan scmi_write_response(msg, &return_values, sizeof(return_values)); 91*b4734308SPeng Fan } 92*b4734308SPeng Fan 93*b4734308SPeng Fan static void report_attributes(struct scmi_msg *msg) 94*b4734308SPeng Fan { 95*b4734308SPeng Fan size_t agent_count = plat_scmi_clock_count(msg->agent_id); 96*b4734308SPeng Fan struct scmi_protocol_attributes_p2a return_values = { 97*b4734308SPeng Fan .status = SCMI_SUCCESS, 98*b4734308SPeng Fan .attributes = SCMI_CLOCK_PROTOCOL_ATTRIBUTES(1U, agent_count), 99*b4734308SPeng Fan }; 100*b4734308SPeng Fan 101*b4734308SPeng Fan if (msg->in_size != 0) { 102*b4734308SPeng Fan scmi_status_response(msg, SCMI_PROTOCOL_ERROR); 103*b4734308SPeng Fan return; 104*b4734308SPeng Fan } 105*b4734308SPeng Fan 106*b4734308SPeng Fan scmi_write_response(msg, &return_values, sizeof(return_values)); 107*b4734308SPeng Fan } 108*b4734308SPeng Fan 109*b4734308SPeng Fan static void report_message_attributes(struct scmi_msg *msg) 110*b4734308SPeng Fan { 111*b4734308SPeng Fan struct scmi_protocol_message_attributes_a2p *in_args = (void *)msg->in; 112*b4734308SPeng Fan struct scmi_protocol_message_attributes_p2a return_values = { 113*b4734308SPeng Fan .status = SCMI_SUCCESS, 114*b4734308SPeng Fan /* For this protocol, attributes shall be zero */ 115*b4734308SPeng Fan .attributes = 0U, 116*b4734308SPeng Fan }; 117*b4734308SPeng Fan 118*b4734308SPeng Fan if (msg->in_size != sizeof(*in_args)) { 119*b4734308SPeng Fan scmi_status_response(msg, SCMI_PROTOCOL_ERROR); 120*b4734308SPeng Fan return; 121*b4734308SPeng Fan } 122*b4734308SPeng Fan 123*b4734308SPeng Fan if (!message_id_is_supported(in_args->message_id)) { 124*b4734308SPeng Fan scmi_status_response(msg, SCMI_NOT_FOUND); 125*b4734308SPeng Fan return; 126*b4734308SPeng Fan } 127*b4734308SPeng Fan 128*b4734308SPeng Fan scmi_write_response(msg, &return_values, sizeof(return_values)); 129*b4734308SPeng Fan } 130*b4734308SPeng Fan 131*b4734308SPeng Fan static void scmi_clock_attributes(struct scmi_msg *msg) 132*b4734308SPeng Fan { 133*b4734308SPeng Fan const struct scmi_clock_attributes_a2p *in_args = (void *)msg->in; 134*b4734308SPeng Fan struct scmi_clock_attributes_p2a return_values = { 135*b4734308SPeng Fan .status = SCMI_SUCCESS, 136*b4734308SPeng Fan }; 137*b4734308SPeng Fan const char *name = NULL; 138*b4734308SPeng Fan unsigned int clock_id = 0U; 139*b4734308SPeng Fan 140*b4734308SPeng Fan if (msg->in_size != sizeof(*in_args)) { 141*b4734308SPeng Fan scmi_status_response(msg, SCMI_PROTOCOL_ERROR); 142*b4734308SPeng Fan return; 143*b4734308SPeng Fan } 144*b4734308SPeng Fan 145*b4734308SPeng Fan clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); 146*b4734308SPeng Fan 147*b4734308SPeng Fan if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { 148*b4734308SPeng Fan scmi_status_response(msg, SCMI_INVALID_PARAMETERS); 149*b4734308SPeng Fan return; 150*b4734308SPeng Fan } 151*b4734308SPeng Fan 152*b4734308SPeng Fan 153*b4734308SPeng Fan name = plat_scmi_clock_get_name(msg->agent_id, clock_id); 154*b4734308SPeng Fan if (name == NULL) { 155*b4734308SPeng Fan scmi_status_response(msg, SCMI_NOT_FOUND); 156*b4734308SPeng Fan return; 157*b4734308SPeng Fan } 158*b4734308SPeng Fan 159*b4734308SPeng Fan COPY_NAME_IDENTIFIER(return_values.clock_name, name); 160*b4734308SPeng Fan 161*b4734308SPeng Fan return_values.attributes = plat_scmi_clock_get_state(msg->agent_id, 162*b4734308SPeng Fan clock_id); 163*b4734308SPeng Fan 164*b4734308SPeng Fan scmi_write_response(msg, &return_values, sizeof(return_values)); 165*b4734308SPeng Fan } 166*b4734308SPeng Fan 167*b4734308SPeng Fan static void scmi_clock_rate_get(struct scmi_msg *msg) 168*b4734308SPeng Fan { 169*b4734308SPeng Fan const struct scmi_clock_rate_get_a2p *in_args = (void *)msg->in; 170*b4734308SPeng Fan unsigned long rate = 0U; 171*b4734308SPeng Fan struct scmi_clock_rate_get_p2a return_values = { 172*b4734308SPeng Fan .status = SCMI_SUCCESS, 173*b4734308SPeng Fan }; 174*b4734308SPeng Fan unsigned int clock_id = 0U; 175*b4734308SPeng Fan 176*b4734308SPeng Fan if (msg->in_size != sizeof(*in_args)) { 177*b4734308SPeng Fan scmi_status_response(msg, SCMI_PROTOCOL_ERROR); 178*b4734308SPeng Fan return; 179*b4734308SPeng Fan } 180*b4734308SPeng Fan 181*b4734308SPeng Fan clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); 182*b4734308SPeng Fan 183*b4734308SPeng Fan if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { 184*b4734308SPeng Fan scmi_status_response(msg, SCMI_INVALID_PARAMETERS); 185*b4734308SPeng Fan return; 186*b4734308SPeng Fan } 187*b4734308SPeng Fan 188*b4734308SPeng Fan rate = plat_scmi_clock_get_rate(msg->agent_id, clock_id); 189*b4734308SPeng Fan 190*b4734308SPeng Fan return_values.rate[0] = (uint32_t)rate; 191*b4734308SPeng Fan return_values.rate[1] = (uint32_t)((uint64_t)rate >> 32); 192*b4734308SPeng Fan 193*b4734308SPeng Fan scmi_write_response(msg, &return_values, sizeof(return_values)); 194*b4734308SPeng Fan } 195*b4734308SPeng Fan 196*b4734308SPeng Fan static void scmi_clock_rate_set(struct scmi_msg *msg) 197*b4734308SPeng Fan { 198*b4734308SPeng Fan const struct scmi_clock_rate_set_a2p *in_args = (void *)msg->in; 199*b4734308SPeng Fan unsigned long rate = 0U; 200*b4734308SPeng Fan int32_t status = 0; 201*b4734308SPeng Fan unsigned int clock_id = 0U; 202*b4734308SPeng Fan 203*b4734308SPeng Fan if (msg->in_size != sizeof(*in_args)) { 204*b4734308SPeng Fan scmi_status_response(msg, SCMI_PROTOCOL_ERROR); 205*b4734308SPeng Fan return; 206*b4734308SPeng Fan } 207*b4734308SPeng Fan 208*b4734308SPeng Fan clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); 209*b4734308SPeng Fan 210*b4734308SPeng Fan if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { 211*b4734308SPeng Fan scmi_status_response(msg, SCMI_INVALID_PARAMETERS); 212*b4734308SPeng Fan return; 213*b4734308SPeng Fan } 214*b4734308SPeng Fan 215*b4734308SPeng Fan rate = (unsigned long)(((uint64_t)in_args->rate[1] << 32) | 216*b4734308SPeng Fan in_args->rate[0]); 217*b4734308SPeng Fan 218*b4734308SPeng Fan status = plat_scmi_clock_set_rate(msg->agent_id, clock_id, rate); 219*b4734308SPeng Fan 220*b4734308SPeng Fan scmi_status_response(msg, status); 221*b4734308SPeng Fan } 222*b4734308SPeng Fan 223*b4734308SPeng Fan static void scmi_clock_config_set(struct scmi_msg *msg) 224*b4734308SPeng Fan { 225*b4734308SPeng Fan const struct scmi_clock_config_set_a2p *in_args = (void *)msg->in; 226*b4734308SPeng Fan int32_t status = SCMI_GENERIC_ERROR; 227*b4734308SPeng Fan bool enable = false; 228*b4734308SPeng Fan unsigned int clock_id = 0U; 229*b4734308SPeng Fan 230*b4734308SPeng Fan if (msg->in_size != sizeof(*in_args)) { 231*b4734308SPeng Fan scmi_status_response(msg, SCMI_PROTOCOL_ERROR); 232*b4734308SPeng Fan return; 233*b4734308SPeng Fan } 234*b4734308SPeng Fan 235*b4734308SPeng Fan clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); 236*b4734308SPeng Fan 237*b4734308SPeng Fan if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { 238*b4734308SPeng Fan scmi_status_response(msg, SCMI_INVALID_PARAMETERS); 239*b4734308SPeng Fan return; 240*b4734308SPeng Fan } 241*b4734308SPeng Fan 242*b4734308SPeng Fan enable = in_args->attributes & SCMI_CLOCK_CONFIG_SET_ENABLE_MASK; 243*b4734308SPeng Fan 244*b4734308SPeng Fan status = plat_scmi_clock_set_state(msg->agent_id, clock_id, enable); 245*b4734308SPeng Fan 246*b4734308SPeng Fan scmi_status_response(msg, status); 247*b4734308SPeng Fan } 248*b4734308SPeng Fan 249*b4734308SPeng Fan #define RATES_ARRAY_SIZE_MAX (SCMI_PLAYLOAD_MAX - \ 250*b4734308SPeng Fan sizeof(struct scmi_clock_describe_rates_p2a)) 251*b4734308SPeng Fan 252*b4734308SPeng Fan #define SCMI_RATES_BY_ARRAY(_nb_rates, _rem_rates) \ 253*b4734308SPeng Fan SCMI_CLOCK_DESCRIBE_RATES_NUM_RATES_FLAGS((_nb_rates), \ 254*b4734308SPeng Fan SCMI_CLOCK_RATE_FORMAT_LIST, \ 255*b4734308SPeng Fan (_rem_rates)) 256*b4734308SPeng Fan #define SCMI_RATES_BY_STEP \ 257*b4734308SPeng Fan SCMI_CLOCK_DESCRIBE_RATES_NUM_RATES_FLAGS(3U, \ 258*b4734308SPeng Fan SCMI_CLOCK_RATE_FORMAT_RANGE, \ 259*b4734308SPeng Fan 0U) 260*b4734308SPeng Fan 261*b4734308SPeng Fan #define RATE_DESC_SIZE sizeof(struct scmi_clock_rate) 262*b4734308SPeng Fan 263*b4734308SPeng Fan static void write_rate_desc_array_in_buffer(char *dest, unsigned long *rates, 264*b4734308SPeng Fan size_t nb_elt) 265*b4734308SPeng Fan { 266*b4734308SPeng Fan uint32_t *out = (uint32_t *)(uintptr_t)dest; 267*b4734308SPeng Fan size_t n; 268*b4734308SPeng Fan 269*b4734308SPeng Fan ASSERT_SYM_PTR_ALIGN(out); 270*b4734308SPeng Fan 271*b4734308SPeng Fan for (n = 0U; n < nb_elt; n++) { 272*b4734308SPeng Fan out[2 * n] = (uint32_t)rates[n]; 273*b4734308SPeng Fan out[2 * n + 1] = (uint32_t)((uint64_t)rates[n] >> 32); 274*b4734308SPeng Fan } 275*b4734308SPeng Fan } 276*b4734308SPeng Fan 277*b4734308SPeng Fan static void scmi_clock_describe_rates(struct scmi_msg *msg) 278*b4734308SPeng Fan { 279*b4734308SPeng Fan const struct scmi_clock_describe_rates_a2p *in_args = (void *)msg->in; 280*b4734308SPeng Fan struct scmi_clock_describe_rates_p2a p2a = { 281*b4734308SPeng Fan .status = SCMI_SUCCESS, 282*b4734308SPeng Fan }; 283*b4734308SPeng Fan size_t nb_rates; 284*b4734308SPeng Fan int32_t status; 285*b4734308SPeng Fan unsigned int clock_id; 286*b4734308SPeng Fan 287*b4734308SPeng Fan if (msg->in_size != sizeof(*in_args)) { 288*b4734308SPeng Fan scmi_status_response(msg, SCMI_PROTOCOL_ERROR); 289*b4734308SPeng Fan return; 290*b4734308SPeng Fan } 291*b4734308SPeng Fan 292*b4734308SPeng Fan clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); 293*b4734308SPeng Fan 294*b4734308SPeng Fan if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { 295*b4734308SPeng Fan scmi_status_response(msg, SCMI_INVALID_PARAMETERS); 296*b4734308SPeng Fan return; 297*b4734308SPeng Fan } 298*b4734308SPeng Fan 299*b4734308SPeng Fan /* Platform may support array rate description */ 300*b4734308SPeng Fan status = plat_scmi_clock_rates_array(msg->agent_id, clock_id, NULL, 301*b4734308SPeng Fan &nb_rates); 302*b4734308SPeng Fan if (status == SCMI_SUCCESS) { 303*b4734308SPeng Fan /* Currently 12 cells mex, so it's affordable for the stack */ 304*b4734308SPeng Fan unsigned long plat_rates[RATES_ARRAY_SIZE_MAX / RATE_DESC_SIZE]; 305*b4734308SPeng Fan size_t max_nb = RATES_ARRAY_SIZE_MAX / RATE_DESC_SIZE; 306*b4734308SPeng Fan size_t ret_nb = MIN(nb_rates - in_args->rate_index, max_nb); 307*b4734308SPeng Fan size_t rem_nb = nb_rates - in_args->rate_index - ret_nb; 308*b4734308SPeng Fan 309*b4734308SPeng Fan status = plat_scmi_clock_rates_array(msg->agent_id, clock_id, 310*b4734308SPeng Fan plat_rates, &ret_nb); 311*b4734308SPeng Fan if (status == SCMI_SUCCESS) { 312*b4734308SPeng Fan write_rate_desc_array_in_buffer(msg->out + sizeof(p2a), 313*b4734308SPeng Fan plat_rates, ret_nb); 314*b4734308SPeng Fan 315*b4734308SPeng Fan p2a.num_rates_flags = SCMI_RATES_BY_ARRAY(ret_nb, 316*b4734308SPeng Fan rem_nb); 317*b4734308SPeng Fan p2a.status = SCMI_SUCCESS; 318*b4734308SPeng Fan 319*b4734308SPeng Fan memcpy(msg->out, &p2a, sizeof(p2a)); 320*b4734308SPeng Fan msg->out_size_out = sizeof(p2a) + 321*b4734308SPeng Fan ret_nb * RATE_DESC_SIZE; 322*b4734308SPeng Fan } 323*b4734308SPeng Fan } else if (status == SCMI_NOT_SUPPORTED) { 324*b4734308SPeng Fan unsigned long triplet[3] = { 0U, 0U, 0U }; 325*b4734308SPeng Fan 326*b4734308SPeng Fan /* Platform may support min§max/step triplet description */ 327*b4734308SPeng Fan status = plat_scmi_clock_rates_by_step(msg->agent_id, clock_id, 328*b4734308SPeng Fan triplet); 329*b4734308SPeng Fan if (status == SCMI_SUCCESS) { 330*b4734308SPeng Fan write_rate_desc_array_in_buffer(msg->out + sizeof(p2a), 331*b4734308SPeng Fan triplet, 3U); 332*b4734308SPeng Fan 333*b4734308SPeng Fan p2a.num_rates_flags = SCMI_RATES_BY_STEP; 334*b4734308SPeng Fan p2a.status = SCMI_SUCCESS; 335*b4734308SPeng Fan 336*b4734308SPeng Fan memcpy(msg->out, &p2a, sizeof(p2a)); 337*b4734308SPeng Fan msg->out_size_out = sizeof(p2a) + (3U * RATE_DESC_SIZE); 338*b4734308SPeng Fan } 339*b4734308SPeng Fan } else { 340*b4734308SPeng Fan /* Fallthrough generic exit sequence below with error status */ 341*b4734308SPeng Fan } 342*b4734308SPeng Fan 343*b4734308SPeng Fan if (status != SCMI_SUCCESS) { 344*b4734308SPeng Fan scmi_status_response(msg, status); 345*b4734308SPeng Fan } else { 346*b4734308SPeng Fan /* 347*b4734308SPeng Fan * Message payload is already writen to msg->out, and 348*b4734308SPeng Fan * msg->out_size_out updated. 349*b4734308SPeng Fan */ 350*b4734308SPeng Fan } 351*b4734308SPeng Fan } 352*b4734308SPeng Fan 353*b4734308SPeng Fan static const scmi_msg_handler_t scmi_clock_handler_table[] = { 354*b4734308SPeng Fan [SCMI_PROTOCOL_VERSION] = report_version, 355*b4734308SPeng Fan [SCMI_PROTOCOL_ATTRIBUTES] = report_attributes, 356*b4734308SPeng Fan [SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = report_message_attributes, 357*b4734308SPeng Fan [SCMI_CLOCK_ATTRIBUTES] = scmi_clock_attributes, 358*b4734308SPeng Fan [SCMI_CLOCK_DESCRIBE_RATES] = scmi_clock_describe_rates, 359*b4734308SPeng Fan [SCMI_CLOCK_RATE_SET] = scmi_clock_rate_set, 360*b4734308SPeng Fan [SCMI_CLOCK_RATE_GET] = scmi_clock_rate_get, 361*b4734308SPeng Fan [SCMI_CLOCK_CONFIG_SET] = scmi_clock_config_set, 362*b4734308SPeng Fan }; 363*b4734308SPeng Fan 364*b4734308SPeng Fan static bool message_id_is_supported(size_t message_id) 365*b4734308SPeng Fan { 366*b4734308SPeng Fan return (message_id < ARRAY_SIZE(scmi_clock_handler_table)) && 367*b4734308SPeng Fan (scmi_clock_handler_table[message_id] != NULL); 368*b4734308SPeng Fan } 369*b4734308SPeng Fan 370*b4734308SPeng Fan scmi_msg_handler_t scmi_msg_get_clock_handler(struct scmi_msg *msg) 371*b4734308SPeng Fan { 372*b4734308SPeng Fan const size_t array_size = ARRAY_SIZE(scmi_clock_handler_table); 373*b4734308SPeng Fan unsigned int message_id = SPECULATION_SAFE_VALUE(msg->message_id); 374*b4734308SPeng Fan 375*b4734308SPeng Fan if (message_id >= array_size) { 376*b4734308SPeng Fan VERBOSE("Clock handle not found %u", msg->message_id); 377*b4734308SPeng Fan return NULL; 378*b4734308SPeng Fan } 379*b4734308SPeng Fan 380*b4734308SPeng Fan return scmi_clock_handler_table[message_id]; 381*b4734308SPeng Fan } 382