1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * SCMI Generic SystemPower Control driver. 4 * 5 * Copyright (C) 2020-2022 ARM Ltd. 6 */ 7 /* 8 * In order to handle platform originated SCMI SystemPower requests (like 9 * shutdowns or cold/warm resets) we register an SCMI Notification notifier 10 * block to react when such SCMI SystemPower events are emitted by platform. 11 * 12 * Once such a notification is received we act accordingly to perform the 13 * required system transition depending on the kind of request. 14 * 15 * Graceful requests are routed to userspace through the same API methods 16 * (orderly_poweroff/reboot()) used by ACPI when handling ACPI Shutdown bus 17 * events. 18 * 19 * Direct forceful requests are not supported since are not meant to be sent 20 * by the SCMI platform to an OSPM like Linux. 21 * 22 * Additionally, graceful request notifications can carry an optional timeout 23 * field stating the maximum amount of time allowed by the platform for 24 * completion after which they are converted to forceful ones: the assumption 25 * here is that even graceful requests can be upper-bound by a maximum final 26 * timeout strictly enforced by the platform itself which can ultimately cut 27 * the power off at will anytime; in order to avoid such extreme scenario, we 28 * track progress of graceful requests through the means of a reboot notifier 29 * converting timed-out graceful requests to forceful ones, so at least we 30 * try to perform a clean sync and shutdown/restart before the power is cut. 31 * 32 * Given the peculiar nature of SCMI SystemPower protocol, that is being in 33 * charge of triggering system wide shutdown/reboot events, there should be 34 * only one SCMI platform actively emitting SystemPower events. 35 * For this reason the SCMI core takes care to enforce the creation of one 36 * single unique device associated to the SCMI System Power protocol; no matter 37 * how many SCMI platforms are defined on the system, only one can be designated 38 * to support System Power: as a consequence this driver will never be probed 39 * more than once. 40 * 41 * For similar reasons as soon as the first valid SystemPower is received by 42 * this driver and the shutdown/reboot is started, any further notification 43 * possibly emitted by the platform will be ignored. 44 */ 45 46 #include <linux/math.h> 47 #include <linux/module.h> 48 #include <linux/mutex.h> 49 #include <linux/pm.h> 50 #include <linux/printk.h> 51 #include <linux/reboot.h> 52 #include <linux/scmi_protocol.h> 53 #include <linux/slab.h> 54 #include <linux/suspend.h> 55 #include <linux/time64.h> 56 #include <linux/timer.h> 57 #include <linux/types.h> 58 #include <linux/workqueue.h> 59 60 #ifndef MODULE 61 #include <linux/fs.h> 62 #endif 63 64 enum scmi_syspower_state { 65 SCMI_SYSPOWER_IDLE, 66 SCMI_SYSPOWER_IN_PROGRESS, 67 SCMI_SYSPOWER_REBOOTING 68 }; 69 70 /** 71 * struct scmi_syspower_conf - Common configuration 72 * 73 * @dev: A reference device 74 * @state: Current SystemPower state 75 * @state_mtx: @state related mutex 76 * @required_transition: The requested transition as decribed in the received 77 * SCMI SystemPower notification 78 * @userspace_nb: The notifier_block registered against the SCMI SystemPower 79 * notification to start the needed userspace interactions. 80 * @reboot_nb: A notifier_block optionally used to track reboot progress 81 * @forceful_work: A worker used to trigger a forceful transition once a 82 * graceful has timed out. 83 * @suspend_work: A worker used to trigger system suspend 84 */ 85 struct scmi_syspower_conf { 86 struct device *dev; 87 enum scmi_syspower_state state; 88 /* Protect access to state */ 89 struct mutex state_mtx; 90 enum scmi_system_events required_transition; 91 92 struct notifier_block userspace_nb; 93 struct notifier_block reboot_nb; 94 95 struct delayed_work forceful_work; 96 struct work_struct suspend_work; 97 }; 98 99 #define userspace_nb_to_sconf(x) \ 100 container_of(x, struct scmi_syspower_conf, userspace_nb) 101 102 #define reboot_nb_to_sconf(x) \ 103 container_of(x, struct scmi_syspower_conf, reboot_nb) 104 105 #define dwork_to_sconf(x) \ 106 container_of(x, struct scmi_syspower_conf, forceful_work) 107 108 /** 109 * scmi_reboot_notifier - A reboot notifier to catch an ongoing successful 110 * system transition 111 * @nb: Reference to the related notifier block 112 * @reason: The reason for the ongoing reboot 113 * @__unused: The cmd being executed on a restart request (unused) 114 * 115 * When an ongoing system transition is detected, compatible with the one 116 * requested by SCMI, cancel the delayed work. 117 * 118 * Return: NOTIFY_OK in any case 119 */ 120 static int scmi_reboot_notifier(struct notifier_block *nb, 121 unsigned long reason, void *__unused) 122 { 123 struct scmi_syspower_conf *sc = reboot_nb_to_sconf(nb); 124 125 mutex_lock(&sc->state_mtx); 126 switch (reason) { 127 case SYS_HALT: 128 case SYS_POWER_OFF: 129 if (sc->required_transition == SCMI_SYSTEM_SHUTDOWN) 130 sc->state = SCMI_SYSPOWER_REBOOTING; 131 break; 132 case SYS_RESTART: 133 if (sc->required_transition == SCMI_SYSTEM_COLDRESET || 134 sc->required_transition == SCMI_SYSTEM_WARMRESET) 135 sc->state = SCMI_SYSPOWER_REBOOTING; 136 break; 137 default: 138 break; 139 } 140 141 if (sc->state == SCMI_SYSPOWER_REBOOTING) { 142 dev_dbg(sc->dev, "Reboot in progress...cancel delayed work.\n"); 143 cancel_delayed_work_sync(&sc->forceful_work); 144 } 145 mutex_unlock(&sc->state_mtx); 146 147 return NOTIFY_OK; 148 } 149 150 /** 151 * scmi_request_forceful_transition - Request forceful SystemPower transition 152 * @sc: A reference to the configuration data 153 * 154 * Initiates the required SystemPower transition without involving userspace: 155 * just trigger the action at the kernel level after issuing an emergency 156 * sync. (if possible at all) 157 */ 158 static inline void 159 scmi_request_forceful_transition(struct scmi_syspower_conf *sc) 160 { 161 dev_dbg(sc->dev, "Serving forceful request:%d\n", 162 sc->required_transition); 163 164 #ifndef MODULE 165 emergency_sync(); 166 #endif 167 switch (sc->required_transition) { 168 case SCMI_SYSTEM_SHUTDOWN: 169 kernel_power_off(); 170 break; 171 case SCMI_SYSTEM_COLDRESET: 172 case SCMI_SYSTEM_WARMRESET: 173 kernel_restart(NULL); 174 break; 175 default: 176 break; 177 } 178 } 179 180 static void scmi_forceful_work_func(struct work_struct *work) 181 { 182 struct scmi_syspower_conf *sc; 183 struct delayed_work *dwork; 184 185 if (system_state > SYSTEM_RUNNING) 186 return; 187 188 dwork = to_delayed_work(work); 189 sc = dwork_to_sconf(dwork); 190 191 dev_dbg(sc->dev, "Graceful request timed out...forcing !\n"); 192 mutex_lock(&sc->state_mtx); 193 /* avoid deadlock by unregistering reboot notifier first */ 194 unregister_reboot_notifier(&sc->reboot_nb); 195 if (sc->state == SCMI_SYSPOWER_IN_PROGRESS) 196 scmi_request_forceful_transition(sc); 197 mutex_unlock(&sc->state_mtx); 198 } 199 200 /** 201 * scmi_request_graceful_transition - Request graceful SystemPower transition 202 * @sc: A reference to the configuration data 203 * @timeout_ms: The desired timeout to wait for the shutdown to complete before 204 * system is forcibly shutdown. 205 * 206 * Initiates the required SystemPower transition, requesting userspace 207 * co-operation: it uses the same orderly_ methods used by ACPI Shutdown event 208 * processing. 209 * 210 * Takes care also to register a reboot notifier and to schedule a delayed work 211 * in order to detect if userspace actions are taking too long and in such a 212 * case to trigger a forceful transition. 213 */ 214 static void scmi_request_graceful_transition(struct scmi_syspower_conf *sc, 215 unsigned int timeout_ms) 216 { 217 unsigned int adj_timeout_ms = 0; 218 219 if (timeout_ms) { 220 int ret; 221 222 sc->reboot_nb.notifier_call = &scmi_reboot_notifier; 223 ret = register_reboot_notifier(&sc->reboot_nb); 224 if (!ret) { 225 /* Wait only up to 75% of the advertised timeout */ 226 adj_timeout_ms = mult_frac(timeout_ms, 3, 4); 227 INIT_DELAYED_WORK(&sc->forceful_work, 228 scmi_forceful_work_func); 229 schedule_delayed_work(&sc->forceful_work, 230 msecs_to_jiffies(adj_timeout_ms)); 231 } else { 232 /* Carry on best effort even without a reboot notifier */ 233 dev_warn(sc->dev, 234 "Cannot register reboot notifier !\n"); 235 } 236 } 237 238 dev_dbg(sc->dev, 239 "Serving graceful req:%d (timeout_ms:%u adj_timeout_ms:%u)\n", 240 sc->required_transition, timeout_ms, adj_timeout_ms); 241 242 switch (sc->required_transition) { 243 case SCMI_SYSTEM_SHUTDOWN: 244 /* 245 * When triggered early at boot-time the 'orderly' call will 246 * partially fail due to the lack of userspace itself, but 247 * the force=true argument will start anyway a successful 248 * forced shutdown. 249 */ 250 orderly_poweroff(true); 251 break; 252 case SCMI_SYSTEM_COLDRESET: 253 case SCMI_SYSTEM_WARMRESET: 254 orderly_reboot(); 255 break; 256 case SCMI_SYSTEM_SUSPEND: 257 schedule_work(&sc->suspend_work); 258 break; 259 default: 260 break; 261 } 262 } 263 264 /** 265 * scmi_userspace_notifier - Notifier callback to act on SystemPower 266 * Notifications 267 * @nb: Reference to the related notifier block 268 * @event: The SystemPower notification event id 269 * @data: The SystemPower event report 270 * 271 * This callback is in charge of decoding the received SystemPower report 272 * and act accordingly triggering a graceful or forceful system transition. 273 * 274 * Note that once a valid SCMI SystemPower event starts being served, any 275 * other following SystemPower notification received from the same SCMI 276 * instance (handle) will be ignored. 277 * 278 * Return: NOTIFY_OK once a valid SystemPower event has been successfully 279 * processed. 280 */ 281 static int scmi_userspace_notifier(struct notifier_block *nb, 282 unsigned long event, void *data) 283 { 284 struct scmi_system_power_state_notifier_report *er = data; 285 struct scmi_syspower_conf *sc = userspace_nb_to_sconf(nb); 286 287 if (er->system_state >= SCMI_SYSTEM_MAX || 288 er->system_state == SCMI_SYSTEM_POWERUP) { 289 dev_err(sc->dev, "Ignoring unsupported system_state: 0x%X\n", 290 er->system_state); 291 return NOTIFY_DONE; 292 } 293 294 if (!SCMI_SYSPOWER_IS_REQUEST_GRACEFUL(er->flags)) { 295 dev_err(sc->dev, "Ignoring forceful notification.\n"); 296 return NOTIFY_DONE; 297 } 298 299 /* 300 * Bail out if system is already shutting down or an SCMI SystemPower 301 * requested is already being served. 302 */ 303 if (system_state > SYSTEM_RUNNING) 304 return NOTIFY_DONE; 305 mutex_lock(&sc->state_mtx); 306 if (sc->state != SCMI_SYSPOWER_IDLE) { 307 dev_dbg(sc->dev, 308 "Transition already in progress...ignore.\n"); 309 mutex_unlock(&sc->state_mtx); 310 return NOTIFY_DONE; 311 } 312 sc->state = SCMI_SYSPOWER_IN_PROGRESS; 313 mutex_unlock(&sc->state_mtx); 314 315 sc->required_transition = er->system_state; 316 317 /* Leaving a trace in logs of who triggered the shutdown/reboot. */ 318 dev_info(sc->dev, "Serving shutdown/reboot request: %d\n", 319 sc->required_transition); 320 321 scmi_request_graceful_transition(sc, er->timeout); 322 323 return NOTIFY_OK; 324 } 325 326 static void scmi_suspend_work_func(struct work_struct *work) 327 { 328 pm_suspend(PM_SUSPEND_MEM); 329 } 330 331 static int scmi_syspower_probe(struct scmi_device *sdev) 332 { 333 int ret; 334 struct scmi_syspower_conf *sc; 335 struct scmi_handle *handle = sdev->handle; 336 337 if (!handle) 338 return -ENODEV; 339 340 ret = handle->devm_protocol_acquire(sdev, SCMI_PROTOCOL_SYSTEM); 341 if (ret) 342 return ret; 343 344 sc = devm_kzalloc(&sdev->dev, sizeof(*sc), GFP_KERNEL); 345 if (!sc) 346 return -ENOMEM; 347 348 sc->state = SCMI_SYSPOWER_IDLE; 349 mutex_init(&sc->state_mtx); 350 sc->required_transition = SCMI_SYSTEM_MAX; 351 sc->userspace_nb.notifier_call = &scmi_userspace_notifier; 352 sc->dev = &sdev->dev; 353 dev_set_drvdata(&sdev->dev, sc); 354 355 INIT_WORK(&sc->suspend_work, scmi_suspend_work_func); 356 357 return handle->notify_ops->devm_event_notifier_register(sdev, 358 SCMI_PROTOCOL_SYSTEM, 359 SCMI_EVENT_SYSTEM_POWER_STATE_NOTIFIER, 360 NULL, &sc->userspace_nb); 361 } 362 363 static int scmi_system_power_resume(struct device *dev) 364 { 365 struct scmi_syspower_conf *sc = dev_get_drvdata(dev); 366 367 sc->state = SCMI_SYSPOWER_IDLE; 368 return 0; 369 } 370 371 static const struct dev_pm_ops scmi_system_power_pmops = { 372 SYSTEM_SLEEP_PM_OPS(NULL, scmi_system_power_resume) 373 }; 374 375 static const struct scmi_device_id scmi_id_table[] = { 376 { SCMI_PROTOCOL_SYSTEM, "syspower" }, 377 { }, 378 }; 379 MODULE_DEVICE_TABLE(scmi, scmi_id_table); 380 381 static struct scmi_driver scmi_system_power_driver = { 382 .driver = { 383 .pm = pm_sleep_ptr(&scmi_system_power_pmops), 384 }, 385 .name = "scmi-system-power", 386 .probe = scmi_syspower_probe, 387 .id_table = scmi_id_table, 388 }; 389 module_scmi_driver(scmi_system_power_driver); 390 391 MODULE_AUTHOR("Cristian Marussi <cristian.marussi@arm.com>"); 392 MODULE_DESCRIPTION("ARM SCMI SystemPower Control driver"); 393 MODULE_LICENSE("GPL"); 394