scmi_power_control.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  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. #include <linux/math.h>
  46. #include <linux/module.h>
  47. #include <linux/mutex.h>
  48. #include <linux/pm.h>
  49. #include <linux/printk.h>
  50. #include <linux/reboot.h>
  51. #include <linux/scmi_protocol.h>
  52. #include <linux/slab.h>
  53. #include <linux/suspend.h>
  54. #include <linux/time64.h>
  55. #include <linux/timer.h>
  56. #include <linux/types.h>
  57. #include <linux/workqueue.h>
  58. #ifndef MODULE
  59. #include <linux/fs.h>
  60. #endif
  61. enum scmi_syspower_state {
  62. SCMI_SYSPOWER_IDLE,
  63. SCMI_SYSPOWER_IN_PROGRESS,
  64. SCMI_SYSPOWER_REBOOTING
  65. };
  66. /**
  67. * struct scmi_syspower_conf - Common configuration
  68. *
  69. * @dev: A reference device
  70. * @state: Current SystemPower state
  71. * @state_mtx: @state related mutex
  72. * @required_transition: The requested transition as decribed in the received
  73. * SCMI SystemPower notification
  74. * @userspace_nb: The notifier_block registered against the SCMI SystemPower
  75. * notification to start the needed userspace interactions.
  76. * @reboot_nb: A notifier_block optionally used to track reboot progress
  77. * @forceful_work: A worker used to trigger a forceful transition once a
  78. * graceful has timed out.
  79. * @suspend_work: A worker used to trigger system suspend
  80. */
  81. struct scmi_syspower_conf {
  82. struct device *dev;
  83. enum scmi_syspower_state state;
  84. /* Protect access to state */
  85. struct mutex state_mtx;
  86. enum scmi_system_events required_transition;
  87. struct notifier_block userspace_nb;
  88. struct notifier_block reboot_nb;
  89. struct delayed_work forceful_work;
  90. struct work_struct suspend_work;
  91. };
  92. #define userspace_nb_to_sconf(x) \
  93. container_of(x, struct scmi_syspower_conf, userspace_nb)
  94. #define reboot_nb_to_sconf(x) \
  95. container_of(x, struct scmi_syspower_conf, reboot_nb)
  96. #define dwork_to_sconf(x) \
  97. container_of(x, struct scmi_syspower_conf, forceful_work)
  98. /**
  99. * scmi_reboot_notifier - A reboot notifier to catch an ongoing successful
  100. * system transition
  101. * @nb: Reference to the related notifier block
  102. * @reason: The reason for the ongoing reboot
  103. * @__unused: The cmd being executed on a restart request (unused)
  104. *
  105. * When an ongoing system transition is detected, compatible with the one
  106. * requested by SCMI, cancel the delayed work.
  107. *
  108. * Return: NOTIFY_OK in any case
  109. */
  110. static int scmi_reboot_notifier(struct notifier_block *nb,
  111. unsigned long reason, void *__unused)
  112. {
  113. struct scmi_syspower_conf *sc = reboot_nb_to_sconf(nb);
  114. mutex_lock(&sc->state_mtx);
  115. switch (reason) {
  116. case SYS_HALT:
  117. case SYS_POWER_OFF:
  118. if (sc->required_transition == SCMI_SYSTEM_SHUTDOWN)
  119. sc->state = SCMI_SYSPOWER_REBOOTING;
  120. break;
  121. case SYS_RESTART:
  122. if (sc->required_transition == SCMI_SYSTEM_COLDRESET ||
  123. sc->required_transition == SCMI_SYSTEM_WARMRESET)
  124. sc->state = SCMI_SYSPOWER_REBOOTING;
  125. break;
  126. default:
  127. break;
  128. }
  129. if (sc->state == SCMI_SYSPOWER_REBOOTING) {
  130. dev_dbg(sc->dev, "Reboot in progress...cancel delayed work.\n");
  131. cancel_delayed_work_sync(&sc->forceful_work);
  132. }
  133. mutex_unlock(&sc->state_mtx);
  134. return NOTIFY_OK;
  135. }
  136. /**
  137. * scmi_request_forceful_transition - Request forceful SystemPower transition
  138. * @sc: A reference to the configuration data
  139. *
  140. * Initiates the required SystemPower transition without involving userspace:
  141. * just trigger the action at the kernel level after issuing an emergency
  142. * sync. (if possible at all)
  143. */
  144. static inline void
  145. scmi_request_forceful_transition(struct scmi_syspower_conf *sc)
  146. {
  147. dev_dbg(sc->dev, "Serving forceful request:%d\n",
  148. sc->required_transition);
  149. #ifndef MODULE
  150. emergency_sync();
  151. #endif
  152. switch (sc->required_transition) {
  153. case SCMI_SYSTEM_SHUTDOWN:
  154. kernel_power_off();
  155. break;
  156. case SCMI_SYSTEM_COLDRESET:
  157. case SCMI_SYSTEM_WARMRESET:
  158. kernel_restart(NULL);
  159. break;
  160. default:
  161. break;
  162. }
  163. }
  164. static void scmi_forceful_work_func(struct work_struct *work)
  165. {
  166. struct scmi_syspower_conf *sc;
  167. struct delayed_work *dwork;
  168. if (system_state > SYSTEM_RUNNING)
  169. return;
  170. dwork = to_delayed_work(work);
  171. sc = dwork_to_sconf(dwork);
  172. dev_dbg(sc->dev, "Graceful request timed out...forcing !\n");
  173. mutex_lock(&sc->state_mtx);
  174. /* avoid deadlock by unregistering reboot notifier first */
  175. unregister_reboot_notifier(&sc->reboot_nb);
  176. if (sc->state == SCMI_SYSPOWER_IN_PROGRESS)
  177. scmi_request_forceful_transition(sc);
  178. mutex_unlock(&sc->state_mtx);
  179. }
  180. /**
  181. * scmi_request_graceful_transition - Request graceful SystemPower transition
  182. * @sc: A reference to the configuration data
  183. * @timeout_ms: The desired timeout to wait for the shutdown to complete before
  184. * system is forcibly shutdown.
  185. *
  186. * Initiates the required SystemPower transition, requesting userspace
  187. * co-operation: it uses the same orderly_ methods used by ACPI Shutdown event
  188. * processing.
  189. *
  190. * Takes care also to register a reboot notifier and to schedule a delayed work
  191. * in order to detect if userspace actions are taking too long and in such a
  192. * case to trigger a forceful transition.
  193. */
  194. static void scmi_request_graceful_transition(struct scmi_syspower_conf *sc,
  195. unsigned int timeout_ms)
  196. {
  197. unsigned int adj_timeout_ms = 0;
  198. if (timeout_ms) {
  199. int ret;
  200. sc->reboot_nb.notifier_call = &scmi_reboot_notifier;
  201. ret = register_reboot_notifier(&sc->reboot_nb);
  202. if (!ret) {
  203. /* Wait only up to 75% of the advertised timeout */
  204. adj_timeout_ms = mult_frac(timeout_ms, 3, 4);
  205. INIT_DELAYED_WORK(&sc->forceful_work,
  206. scmi_forceful_work_func);
  207. schedule_delayed_work(&sc->forceful_work,
  208. msecs_to_jiffies(adj_timeout_ms));
  209. } else {
  210. /* Carry on best effort even without a reboot notifier */
  211. dev_warn(sc->dev,
  212. "Cannot register reboot notifier !\n");
  213. }
  214. }
  215. dev_dbg(sc->dev,
  216. "Serving graceful req:%d (timeout_ms:%u adj_timeout_ms:%u)\n",
  217. sc->required_transition, timeout_ms, adj_timeout_ms);
  218. switch (sc->required_transition) {
  219. case SCMI_SYSTEM_SHUTDOWN:
  220. /*
  221. * When triggered early at boot-time the 'orderly' call will
  222. * partially fail due to the lack of userspace itself, but
  223. * the force=true argument will start anyway a successful
  224. * forced shutdown.
  225. */
  226. orderly_poweroff(true);
  227. break;
  228. case SCMI_SYSTEM_COLDRESET:
  229. case SCMI_SYSTEM_WARMRESET:
  230. orderly_reboot();
  231. break;
  232. case SCMI_SYSTEM_SUSPEND:
  233. schedule_work(&sc->suspend_work);
  234. break;
  235. default:
  236. break;
  237. }
  238. }
  239. /**
  240. * scmi_userspace_notifier - Notifier callback to act on SystemPower
  241. * Notifications
  242. * @nb: Reference to the related notifier block
  243. * @event: The SystemPower notification event id
  244. * @data: The SystemPower event report
  245. *
  246. * This callback is in charge of decoding the received SystemPower report
  247. * and act accordingly triggering a graceful or forceful system transition.
  248. *
  249. * Note that once a valid SCMI SystemPower event starts being served, any
  250. * other following SystemPower notification received from the same SCMI
  251. * instance (handle) will be ignored.
  252. *
  253. * Return: NOTIFY_OK once a valid SystemPower event has been successfully
  254. * processed.
  255. */
  256. static int scmi_userspace_notifier(struct notifier_block *nb,
  257. unsigned long event, void *data)
  258. {
  259. struct scmi_system_power_state_notifier_report *er = data;
  260. struct scmi_syspower_conf *sc = userspace_nb_to_sconf(nb);
  261. if (er->system_state >= SCMI_SYSTEM_MAX ||
  262. er->system_state == SCMI_SYSTEM_POWERUP) {
  263. dev_err(sc->dev, "Ignoring unsupported system_state: 0x%X\n",
  264. er->system_state);
  265. return NOTIFY_DONE;
  266. }
  267. if (!SCMI_SYSPOWER_IS_REQUEST_GRACEFUL(er->flags)) {
  268. dev_err(sc->dev, "Ignoring forceful notification.\n");
  269. return NOTIFY_DONE;
  270. }
  271. /*
  272. * Bail out if system is already shutting down or an SCMI SystemPower
  273. * requested is already being served.
  274. */
  275. if (system_state > SYSTEM_RUNNING)
  276. return NOTIFY_DONE;
  277. mutex_lock(&sc->state_mtx);
  278. if (sc->state != SCMI_SYSPOWER_IDLE) {
  279. dev_dbg(sc->dev,
  280. "Transition already in progress...ignore.\n");
  281. mutex_unlock(&sc->state_mtx);
  282. return NOTIFY_DONE;
  283. }
  284. sc->state = SCMI_SYSPOWER_IN_PROGRESS;
  285. mutex_unlock(&sc->state_mtx);
  286. sc->required_transition = er->system_state;
  287. /* Leaving a trace in logs of who triggered the shutdown/reboot. */
  288. dev_info(sc->dev, "Serving shutdown/reboot request: %d\n",
  289. sc->required_transition);
  290. scmi_request_graceful_transition(sc, er->timeout);
  291. return NOTIFY_OK;
  292. }
  293. static void scmi_suspend_work_func(struct work_struct *work)
  294. {
  295. pm_suspend(PM_SUSPEND_MEM);
  296. }
  297. static int scmi_syspower_probe(struct scmi_device *sdev)
  298. {
  299. int ret;
  300. struct scmi_syspower_conf *sc;
  301. struct scmi_handle *handle = sdev->handle;
  302. if (!handle)
  303. return -ENODEV;
  304. ret = handle->devm_protocol_acquire(sdev, SCMI_PROTOCOL_SYSTEM);
  305. if (ret)
  306. return ret;
  307. sc = devm_kzalloc(&sdev->dev, sizeof(*sc), GFP_KERNEL);
  308. if (!sc)
  309. return -ENOMEM;
  310. sc->state = SCMI_SYSPOWER_IDLE;
  311. mutex_init(&sc->state_mtx);
  312. sc->required_transition = SCMI_SYSTEM_MAX;
  313. sc->userspace_nb.notifier_call = &scmi_userspace_notifier;
  314. sc->dev = &sdev->dev;
  315. dev_set_drvdata(&sdev->dev, sc);
  316. INIT_WORK(&sc->suspend_work, scmi_suspend_work_func);
  317. return handle->notify_ops->devm_event_notifier_register(sdev,
  318. SCMI_PROTOCOL_SYSTEM,
  319. SCMI_EVENT_SYSTEM_POWER_STATE_NOTIFIER,
  320. NULL, &sc->userspace_nb);
  321. }
  322. static int scmi_system_power_resume(struct device *dev)
  323. {
  324. struct scmi_syspower_conf *sc = dev_get_drvdata(dev);
  325. sc->state = SCMI_SYSPOWER_IDLE;
  326. return 0;
  327. }
  328. static const struct dev_pm_ops scmi_system_power_pmops = {
  329. SYSTEM_SLEEP_PM_OPS(NULL, scmi_system_power_resume)
  330. };
  331. static const struct scmi_device_id scmi_id_table[] = {
  332. { SCMI_PROTOCOL_SYSTEM, "syspower" },
  333. { },
  334. };
  335. MODULE_DEVICE_TABLE(scmi, scmi_id_table);
  336. static struct scmi_driver scmi_system_power_driver = {
  337. .driver = {
  338. .pm = pm_sleep_ptr(&scmi_system_power_pmops),
  339. },
  340. .name = "scmi-system-power",
  341. .probe = scmi_syspower_probe,
  342. .id_table = scmi_id_table,
  343. };
  344. module_scmi_driver(scmi_system_power_driver);
  345. MODULE_AUTHOR("Cristian Marussi <cristian.marussi@arm.com>");
  346. MODULE_DESCRIPTION("ARM SCMI SystemPower Control driver");
  347. MODULE_LICENSE("GPL");