0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 #include <linux/math.h>
0047 #include <linux/module.h>
0048 #include <linux/mutex.h>
0049 #include <linux/printk.h>
0050 #include <linux/reboot.h>
0051 #include <linux/scmi_protocol.h>
0052 #include <linux/slab.h>
0053 #include <linux/time64.h>
0054 #include <linux/timer.h>
0055 #include <linux/types.h>
0056 #include <linux/workqueue.h>
0057
0058 #ifndef MODULE
0059 #include <linux/fs.h>
0060 #endif
0061
0062 enum scmi_syspower_state {
0063 SCMI_SYSPOWER_IDLE,
0064 SCMI_SYSPOWER_IN_PROGRESS,
0065 SCMI_SYSPOWER_REBOOTING
0066 };
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082 struct scmi_syspower_conf {
0083 struct device *dev;
0084 enum scmi_syspower_state state;
0085
0086 struct mutex state_mtx;
0087 enum scmi_system_events required_transition;
0088
0089 struct notifier_block userspace_nb;
0090 struct notifier_block reboot_nb;
0091
0092 struct delayed_work forceful_work;
0093 };
0094
0095 #define userspace_nb_to_sconf(x) \
0096 container_of(x, struct scmi_syspower_conf, userspace_nb)
0097
0098 #define reboot_nb_to_sconf(x) \
0099 container_of(x, struct scmi_syspower_conf, reboot_nb)
0100
0101 #define dwork_to_sconf(x) \
0102 container_of(x, struct scmi_syspower_conf, forceful_work)
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116 static int scmi_reboot_notifier(struct notifier_block *nb,
0117 unsigned long reason, void *__unused)
0118 {
0119 struct scmi_syspower_conf *sc = reboot_nb_to_sconf(nb);
0120
0121 mutex_lock(&sc->state_mtx);
0122 switch (reason) {
0123 case SYS_HALT:
0124 case SYS_POWER_OFF:
0125 if (sc->required_transition == SCMI_SYSTEM_SHUTDOWN)
0126 sc->state = SCMI_SYSPOWER_REBOOTING;
0127 break;
0128 case SYS_RESTART:
0129 if (sc->required_transition == SCMI_SYSTEM_COLDRESET ||
0130 sc->required_transition == SCMI_SYSTEM_WARMRESET)
0131 sc->state = SCMI_SYSPOWER_REBOOTING;
0132 break;
0133 default:
0134 break;
0135 }
0136
0137 if (sc->state == SCMI_SYSPOWER_REBOOTING) {
0138 dev_dbg(sc->dev, "Reboot in progress...cancel delayed work.\n");
0139 cancel_delayed_work_sync(&sc->forceful_work);
0140 }
0141 mutex_unlock(&sc->state_mtx);
0142
0143 return NOTIFY_OK;
0144 }
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154 static inline void
0155 scmi_request_forceful_transition(struct scmi_syspower_conf *sc)
0156 {
0157 dev_dbg(sc->dev, "Serving forceful request:%d\n",
0158 sc->required_transition);
0159
0160 #ifndef MODULE
0161 emergency_sync();
0162 #endif
0163 switch (sc->required_transition) {
0164 case SCMI_SYSTEM_SHUTDOWN:
0165 kernel_power_off();
0166 break;
0167 case SCMI_SYSTEM_COLDRESET:
0168 case SCMI_SYSTEM_WARMRESET:
0169 kernel_restart(NULL);
0170 break;
0171 default:
0172 break;
0173 }
0174 }
0175
0176 static void scmi_forceful_work_func(struct work_struct *work)
0177 {
0178 struct scmi_syspower_conf *sc;
0179 struct delayed_work *dwork;
0180
0181 if (system_state > SYSTEM_RUNNING)
0182 return;
0183
0184 dwork = to_delayed_work(work);
0185 sc = dwork_to_sconf(dwork);
0186
0187 dev_dbg(sc->dev, "Graceful request timed out...forcing !\n");
0188 mutex_lock(&sc->state_mtx);
0189
0190 unregister_reboot_notifier(&sc->reboot_nb);
0191 if (sc->state == SCMI_SYSPOWER_IN_PROGRESS)
0192 scmi_request_forceful_transition(sc);
0193 mutex_unlock(&sc->state_mtx);
0194 }
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210 static void scmi_request_graceful_transition(struct scmi_syspower_conf *sc,
0211 unsigned int timeout_ms)
0212 {
0213 unsigned int adj_timeout_ms = 0;
0214
0215 if (timeout_ms) {
0216 int ret;
0217
0218 sc->reboot_nb.notifier_call = &scmi_reboot_notifier;
0219 ret = register_reboot_notifier(&sc->reboot_nb);
0220 if (!ret) {
0221
0222 adj_timeout_ms = mult_frac(timeout_ms, 3, 4);
0223 INIT_DELAYED_WORK(&sc->forceful_work,
0224 scmi_forceful_work_func);
0225 schedule_delayed_work(&sc->forceful_work,
0226 msecs_to_jiffies(adj_timeout_ms));
0227 } else {
0228
0229 dev_warn(sc->dev,
0230 "Cannot register reboot notifier !\n");
0231 }
0232 }
0233
0234 dev_dbg(sc->dev,
0235 "Serving graceful req:%d (timeout_ms:%u adj_timeout_ms:%u)\n",
0236 sc->required_transition, timeout_ms, adj_timeout_ms);
0237
0238 switch (sc->required_transition) {
0239 case SCMI_SYSTEM_SHUTDOWN:
0240
0241
0242
0243
0244
0245
0246 orderly_poweroff(true);
0247 break;
0248 case SCMI_SYSTEM_COLDRESET:
0249 case SCMI_SYSTEM_WARMRESET:
0250 orderly_reboot();
0251 break;
0252 default:
0253 break;
0254 }
0255 }
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274 static int scmi_userspace_notifier(struct notifier_block *nb,
0275 unsigned long event, void *data)
0276 {
0277 struct scmi_system_power_state_notifier_report *er = data;
0278 struct scmi_syspower_conf *sc = userspace_nb_to_sconf(nb);
0279
0280 if (er->system_state >= SCMI_SYSTEM_POWERUP) {
0281 dev_err(sc->dev, "Ignoring unsupported system_state: 0x%X\n",
0282 er->system_state);
0283 return NOTIFY_DONE;
0284 }
0285
0286 if (!SCMI_SYSPOWER_IS_REQUEST_GRACEFUL(er->flags)) {
0287 dev_err(sc->dev, "Ignoring forceful notification.\n");
0288 return NOTIFY_DONE;
0289 }
0290
0291
0292
0293
0294
0295 if (system_state > SYSTEM_RUNNING)
0296 return NOTIFY_DONE;
0297 mutex_lock(&sc->state_mtx);
0298 if (sc->state != SCMI_SYSPOWER_IDLE) {
0299 dev_dbg(sc->dev,
0300 "Transition already in progress...ignore.\n");
0301 mutex_unlock(&sc->state_mtx);
0302 return NOTIFY_DONE;
0303 }
0304 sc->state = SCMI_SYSPOWER_IN_PROGRESS;
0305 mutex_unlock(&sc->state_mtx);
0306
0307 sc->required_transition = er->system_state;
0308
0309
0310 dev_info(sc->dev, "Serving shutdown/reboot request: %d\n",
0311 sc->required_transition);
0312
0313 scmi_request_graceful_transition(sc, er->timeout);
0314
0315 return NOTIFY_OK;
0316 }
0317
0318 static int scmi_syspower_probe(struct scmi_device *sdev)
0319 {
0320 int ret;
0321 struct scmi_syspower_conf *sc;
0322 struct scmi_handle *handle = sdev->handle;
0323
0324 if (!handle)
0325 return -ENODEV;
0326
0327 ret = handle->devm_protocol_acquire(sdev, SCMI_PROTOCOL_SYSTEM);
0328 if (ret)
0329 return ret;
0330
0331 sc = devm_kzalloc(&sdev->dev, sizeof(*sc), GFP_KERNEL);
0332 if (!sc)
0333 return -ENOMEM;
0334
0335 sc->state = SCMI_SYSPOWER_IDLE;
0336 mutex_init(&sc->state_mtx);
0337 sc->required_transition = SCMI_SYSTEM_MAX;
0338 sc->userspace_nb.notifier_call = &scmi_userspace_notifier;
0339 sc->dev = &sdev->dev;
0340
0341 return handle->notify_ops->devm_event_notifier_register(sdev,
0342 SCMI_PROTOCOL_SYSTEM,
0343 SCMI_EVENT_SYSTEM_POWER_STATE_NOTIFIER,
0344 NULL, &sc->userspace_nb);
0345 }
0346
0347 static const struct scmi_device_id scmi_id_table[] = {
0348 { SCMI_PROTOCOL_SYSTEM, "syspower" },
0349 { },
0350 };
0351 MODULE_DEVICE_TABLE(scmi, scmi_id_table);
0352
0353 static struct scmi_driver scmi_system_power_driver = {
0354 .name = "scmi-system-power",
0355 .probe = scmi_syspower_probe,
0356 .id_table = scmi_id_table,
0357 };
0358 module_scmi_driver(scmi_system_power_driver);
0359
0360 MODULE_AUTHOR("Cristian Marussi <cristian.marussi@arm.com>");
0361 MODULE_DESCRIPTION("ARM SCMI SystemPower Control driver");
0362 MODULE_LICENSE("GPL");