1 // SPDX-License-Identifier: GPL-2.0-only OR MIT
2 /*
3 * Apple SMC (System Management Controller) MFD driver
4 *
5 * Copyright The Asahi Linux Contributors
6 */
7
8 #include <linux/bitfield.h>
9 #include <linux/delay.h>
10 #include <linux/device.h>
11 #include <linux/io.h>
12 #include <linux/ioport.h>
13 #include <linux/math.h>
14 #include <linux/mfd/core.h>
15 #include <linux/mfd/macsmc.h>
16 #include <linux/notifier.h>
17 #include <linux/of.h>
18 #include <linux/of_platform.h>
19 #include <linux/overflow.h>
20 #include <linux/platform_device.h>
21 #include <linux/soc/apple/rtkit.h>
22 #include <linux/unaligned.h>
23
24 #define SMC_ENDPOINT 0x20
25
26 /* We don't actually know the true size here but this seem reasonable */
27 #define SMC_SHMEM_SIZE 0x1000
28 #define SMC_MAX_SIZE 255
29
30 #define SMC_MSG_READ_KEY 0x10
31 #define SMC_MSG_WRITE_KEY 0x11
32 #define SMC_MSG_GET_KEY_BY_INDEX 0x12
33 #define SMC_MSG_GET_KEY_INFO 0x13
34 #define SMC_MSG_INITIALIZE 0x17
35 #define SMC_MSG_NOTIFICATION 0x18
36 #define SMC_MSG_RW_KEY 0x20
37
38 #define SMC_DATA GENMASK_ULL(63, 32)
39 #define SMC_WSIZE GENMASK_ULL(31, 24)
40 #define SMC_SIZE GENMASK_ULL(23, 16)
41 #define SMC_ID GENMASK_ULL(15, 12)
42 #define SMC_MSG GENMASK_ULL(7, 0)
43 #define SMC_RESULT SMC_MSG
44
45 #define SMC_TIMEOUT_MS 500
46
47 static const struct mfd_cell apple_smc_devs[] = {
48 MFD_CELL_OF("macsmc-gpio", NULL, NULL, 0, 0, "apple,smc-gpio"),
49 MFD_CELL_OF("macsmc-reboot", NULL, NULL, 0, 0, "apple,smc-reboot"),
50 };
51
apple_smc_cmd_locked(struct apple_smc * smc,u64 cmd,u64 arg,u64 size,u64 wsize,u32 * ret_data)52 static int apple_smc_cmd_locked(struct apple_smc *smc, u64 cmd, u64 arg,
53 u64 size, u64 wsize, u32 *ret_data)
54 {
55 u8 result;
56 int ret;
57 u64 msg;
58
59 lockdep_assert_held(&smc->mutex);
60
61 if (smc->boot_stage != APPLE_SMC_INITIALIZED)
62 return -EIO;
63 if (smc->atomic_mode)
64 return -EIO;
65
66 reinit_completion(&smc->cmd_done);
67
68 smc->msg_id = (smc->msg_id + 1) & 0xf;
69 msg = (FIELD_PREP(SMC_MSG, cmd) |
70 FIELD_PREP(SMC_SIZE, size) |
71 FIELD_PREP(SMC_WSIZE, wsize) |
72 FIELD_PREP(SMC_ID, smc->msg_id) |
73 FIELD_PREP(SMC_DATA, arg));
74
75 ret = apple_rtkit_send_message(smc->rtk, SMC_ENDPOINT, msg, NULL, false);
76 if (ret) {
77 dev_err(smc->dev, "Failed to send command\n");
78 return ret;
79 }
80
81 if (wait_for_completion_timeout(&smc->cmd_done, msecs_to_jiffies(SMC_TIMEOUT_MS)) <= 0) {
82 dev_err(smc->dev, "Command timed out (%llx)", msg);
83 return -ETIMEDOUT;
84 }
85
86 if (FIELD_GET(SMC_ID, smc->cmd_ret) != smc->msg_id) {
87 dev_err(smc->dev, "Command sequence mismatch (expected %d, got %d)\n",
88 smc->msg_id, (unsigned int)FIELD_GET(SMC_ID, smc->cmd_ret));
89 return -EIO;
90 }
91
92 result = FIELD_GET(SMC_RESULT, smc->cmd_ret);
93 if (result)
94 return -EIO;
95
96 if (ret_data)
97 *ret_data = FIELD_GET(SMC_DATA, smc->cmd_ret);
98
99 return FIELD_GET(SMC_SIZE, smc->cmd_ret);
100 }
101
apple_smc_cmd(struct apple_smc * smc,u64 cmd,u64 arg,u64 size,u64 wsize,u32 * ret_data)102 static int apple_smc_cmd(struct apple_smc *smc, u64 cmd, u64 arg,
103 u64 size, u64 wsize, u32 *ret_data)
104 {
105 guard(mutex)(&smc->mutex);
106
107 return apple_smc_cmd_locked(smc, cmd, arg, size, wsize, ret_data);
108 }
109
apple_smc_rw_locked(struct apple_smc * smc,smc_key key,const void * wbuf,size_t wsize,void * rbuf,size_t rsize)110 static int apple_smc_rw_locked(struct apple_smc *smc, smc_key key,
111 const void *wbuf, size_t wsize,
112 void *rbuf, size_t rsize)
113 {
114 u64 smc_size, smc_wsize;
115 u32 rdata;
116 int ret;
117 u64 cmd;
118
119 lockdep_assert_held(&smc->mutex);
120
121 if (rsize > SMC_MAX_SIZE)
122 return -EINVAL;
123 if (wsize > SMC_MAX_SIZE)
124 return -EINVAL;
125
126 if (rsize && wsize) {
127 cmd = SMC_MSG_RW_KEY;
128 memcpy_toio(smc->shmem.iomem, wbuf, wsize);
129 smc_size = rsize;
130 smc_wsize = wsize;
131 } else if (wsize && !rsize) {
132 cmd = SMC_MSG_WRITE_KEY;
133 memcpy_toio(smc->shmem.iomem, wbuf, wsize);
134 /*
135 * Setting size to the length we want to write and wsize to 0
136 * looks silly but that's how the SMC protocol works ¯\_(ツ)_/¯
137 */
138 smc_size = wsize;
139 smc_wsize = 0;
140 } else if (!wsize && rsize) {
141 cmd = SMC_MSG_READ_KEY;
142 smc_size = rsize;
143 smc_wsize = 0;
144 } else {
145 return -EINVAL;
146 }
147
148 ret = apple_smc_cmd_locked(smc, cmd, key, smc_size, smc_wsize, &rdata);
149 if (ret < 0)
150 return ret;
151
152 if (rsize) {
153 /*
154 * Small data <= 4 bytes is returned as part of the reply
155 * message which is sent over the mailbox FIFO. Everything
156 * bigger has to be copied from SRAM which is mapped as
157 * Device memory.
158 */
159 if (rsize <= 4)
160 memcpy(rbuf, &rdata, rsize);
161 else
162 memcpy_fromio(rbuf, smc->shmem.iomem, rsize);
163 }
164
165 return ret;
166 }
167
apple_smc_read(struct apple_smc * smc,smc_key key,void * buf,size_t size)168 int apple_smc_read(struct apple_smc *smc, smc_key key, void *buf, size_t size)
169 {
170 guard(mutex)(&smc->mutex);
171
172 return apple_smc_rw_locked(smc, key, NULL, 0, buf, size);
173 }
174 EXPORT_SYMBOL(apple_smc_read);
175
apple_smc_write(struct apple_smc * smc,smc_key key,void * buf,size_t size)176 int apple_smc_write(struct apple_smc *smc, smc_key key, void *buf, size_t size)
177 {
178 guard(mutex)(&smc->mutex);
179
180 return apple_smc_rw_locked(smc, key, buf, size, NULL, 0);
181 }
182 EXPORT_SYMBOL(apple_smc_write);
183
apple_smc_rw(struct apple_smc * smc,smc_key key,void * wbuf,size_t wsize,void * rbuf,size_t rsize)184 int apple_smc_rw(struct apple_smc *smc, smc_key key, void *wbuf, size_t wsize,
185 void *rbuf, size_t rsize)
186 {
187 guard(mutex)(&smc->mutex);
188
189 return apple_smc_rw_locked(smc, key, wbuf, wsize, rbuf, rsize);
190 }
191 EXPORT_SYMBOL(apple_smc_rw);
192
apple_smc_get_key_by_index(struct apple_smc * smc,int index,smc_key * key)193 int apple_smc_get_key_by_index(struct apple_smc *smc, int index, smc_key *key)
194 {
195 int ret;
196
197 ret = apple_smc_cmd(smc, SMC_MSG_GET_KEY_BY_INDEX, index, 0, 0, key);
198
199 *key = swab32(*key);
200 return ret;
201 }
202 EXPORT_SYMBOL(apple_smc_get_key_by_index);
203
apple_smc_get_key_info(struct apple_smc * smc,smc_key key,struct apple_smc_key_info * info)204 int apple_smc_get_key_info(struct apple_smc *smc, smc_key key, struct apple_smc_key_info *info)
205 {
206 u8 key_info[6];
207 int ret;
208
209 ret = apple_smc_cmd(smc, SMC_MSG_GET_KEY_INFO, key, 0, 0, NULL);
210 if (ret >= 0 && info) {
211 memcpy_fromio(key_info, smc->shmem.iomem, sizeof(key_info));
212 info->size = key_info[0];
213 info->type_code = get_unaligned_be32(&key_info[1]);
214 info->flags = key_info[5];
215 }
216 return ret;
217 }
218 EXPORT_SYMBOL(apple_smc_get_key_info);
219
apple_smc_enter_atomic(struct apple_smc * smc)220 int apple_smc_enter_atomic(struct apple_smc *smc)
221 {
222 guard(mutex)(&smc->mutex);
223
224 /*
225 * Disable notifications since this is called before shutdown and no
226 * notification handler will be able to handle the notification
227 * using atomic operations only. Also ignore any failure here
228 * because we're about to shut down or reboot anyway.
229 * We can't use apple_smc_write_flag here since that would try to lock
230 * smc->mutex again.
231 */
232 const u8 flag = 0;
233
234 apple_smc_rw_locked(smc, SMC_KEY(NTAP), &flag, sizeof(flag), NULL, 0);
235
236 smc->atomic_mode = true;
237
238 return 0;
239 }
240 EXPORT_SYMBOL(apple_smc_enter_atomic);
241
apple_smc_write_atomic(struct apple_smc * smc,smc_key key,void * buf,size_t size)242 int apple_smc_write_atomic(struct apple_smc *smc, smc_key key, void *buf, size_t size)
243 {
244 guard(spinlock_irqsave)(&smc->lock);
245 u8 result;
246 int ret;
247 u64 msg;
248
249 if (size > SMC_MAX_SIZE || size == 0)
250 return -EINVAL;
251
252 if (smc->boot_stage != APPLE_SMC_INITIALIZED)
253 return -EIO;
254 if (!smc->atomic_mode)
255 return -EIO;
256
257 memcpy_toio(smc->shmem.iomem, buf, size);
258 smc->msg_id = (smc->msg_id + 1) & 0xf;
259 msg = (FIELD_PREP(SMC_MSG, SMC_MSG_WRITE_KEY) |
260 FIELD_PREP(SMC_SIZE, size) |
261 FIELD_PREP(SMC_ID, smc->msg_id) |
262 FIELD_PREP(SMC_DATA, key));
263 smc->atomic_pending = true;
264
265 ret = apple_rtkit_send_message(smc->rtk, SMC_ENDPOINT, msg, NULL, true);
266 if (ret < 0) {
267 dev_err(smc->dev, "Failed to send command (%d)\n", ret);
268 return ret;
269 }
270
271 while (smc->atomic_pending) {
272 ret = apple_rtkit_poll(smc->rtk);
273 if (ret < 0) {
274 dev_err(smc->dev, "RTKit poll failed (%llx)", msg);
275 return ret;
276 }
277 udelay(100);
278 }
279
280 if (FIELD_GET(SMC_ID, smc->cmd_ret) != smc->msg_id) {
281 dev_err(smc->dev, "Command sequence mismatch (expected %d, got %d)\n",
282 smc->msg_id, (unsigned int)FIELD_GET(SMC_ID, smc->cmd_ret));
283 return -EIO;
284 }
285
286 result = FIELD_GET(SMC_RESULT, smc->cmd_ret);
287 if (result)
288 return -EIO;
289
290 return FIELD_GET(SMC_SIZE, smc->cmd_ret);
291 }
292 EXPORT_SYMBOL(apple_smc_write_atomic);
293
apple_smc_rtkit_crashed(void * cookie,const void * bfr,size_t bfr_len)294 static void apple_smc_rtkit_crashed(void *cookie, const void *bfr, size_t bfr_len)
295 {
296 struct apple_smc *smc = cookie;
297
298 smc->boot_stage = APPLE_SMC_ERROR_CRASHED;
299 dev_err(smc->dev, "SMC crashed! Your system will reboot in a few seconds...\n");
300 }
301
apple_smc_rtkit_shmem_setup(void * cookie,struct apple_rtkit_shmem * bfr)302 static int apple_smc_rtkit_shmem_setup(void *cookie, struct apple_rtkit_shmem *bfr)
303 {
304 struct apple_smc *smc = cookie;
305 size_t bfr_end;
306
307 if (!bfr->iova) {
308 dev_err(smc->dev, "RTKit wants a RAM buffer\n");
309 return -EIO;
310 }
311
312 if (check_add_overflow(bfr->iova, bfr->size - 1, &bfr_end))
313 return -EFAULT;
314
315 if (bfr->iova < smc->sram->start || bfr->iova > smc->sram->end ||
316 bfr_end > smc->sram->end) {
317 dev_err(smc->dev, "RTKit buffer request outside SRAM region: [0x%llx, 0x%llx]\n",
318 (unsigned long long)bfr->iova,
319 (unsigned long long)bfr_end);
320 return -EFAULT;
321 }
322
323 bfr->iomem = smc->sram_base + (bfr->iova - smc->sram->start);
324 bfr->is_mapped = true;
325
326 return 0;
327 }
328
apple_smc_rtkit_recv_early(void * cookie,u8 endpoint,u64 message)329 static bool apple_smc_rtkit_recv_early(void *cookie, u8 endpoint, u64 message)
330 {
331 struct apple_smc *smc = cookie;
332
333 if (endpoint != SMC_ENDPOINT) {
334 dev_warn(smc->dev, "Received message for unknown endpoint 0x%x\n", endpoint);
335 return false;
336 }
337
338 if (smc->boot_stage == APPLE_SMC_BOOTING) {
339 int ret;
340
341 smc->shmem.iova = message;
342 smc->shmem.size = SMC_SHMEM_SIZE;
343 ret = apple_smc_rtkit_shmem_setup(smc, &smc->shmem);
344 if (ret < 0) {
345 smc->boot_stage = APPLE_SMC_ERROR_NO_SHMEM;
346 dev_err(smc->dev, "Failed to initialize shared memory (%d)\n", ret);
347 } else {
348 smc->boot_stage = APPLE_SMC_INITIALIZED;
349 }
350 complete(&smc->init_done);
351 } else if (FIELD_GET(SMC_MSG, message) == SMC_MSG_NOTIFICATION) {
352 /* Handle these in the RTKit worker thread */
353 return false;
354 } else {
355 smc->cmd_ret = message;
356 if (smc->atomic_pending)
357 smc->atomic_pending = false;
358 else
359 complete(&smc->cmd_done);
360 }
361
362 return true;
363 }
364
apple_smc_rtkit_recv(void * cookie,u8 endpoint,u64 message)365 static void apple_smc_rtkit_recv(void *cookie, u8 endpoint, u64 message)
366 {
367 struct apple_smc *smc = cookie;
368
369 if (endpoint != SMC_ENDPOINT) {
370 dev_warn(smc->dev, "Received message for unknown endpoint 0x%x\n", endpoint);
371 return;
372 }
373
374 if (FIELD_GET(SMC_MSG, message) != SMC_MSG_NOTIFICATION) {
375 dev_warn(smc->dev, "Received unknown message from worker: 0x%llx\n", message);
376 return;
377 }
378
379 blocking_notifier_call_chain(&smc->event_handlers, FIELD_GET(SMC_DATA, message), NULL);
380 }
381
382 static const struct apple_rtkit_ops apple_smc_rtkit_ops = {
383 .crashed = apple_smc_rtkit_crashed,
384 .recv_message = apple_smc_rtkit_recv,
385 .recv_message_early = apple_smc_rtkit_recv_early,
386 .shmem_setup = apple_smc_rtkit_shmem_setup,
387 };
388
apple_smc_rtkit_shutdown(void * data)389 static void apple_smc_rtkit_shutdown(void *data)
390 {
391 struct apple_smc *smc = data;
392
393 /* Shut down SMC firmware, if it's not completely wedged */
394 if (apple_rtkit_is_running(smc->rtk))
395 apple_rtkit_quiesce(smc->rtk);
396 }
397
apple_smc_disable_notifications(void * data)398 static void apple_smc_disable_notifications(void *data)
399 {
400 struct apple_smc *smc = data;
401
402 apple_smc_write_flag(smc, SMC_KEY(NTAP), false);
403 }
404
apple_smc_probe(struct platform_device * pdev)405 static int apple_smc_probe(struct platform_device *pdev)
406 {
407 struct device *dev = &pdev->dev;
408 struct apple_smc *smc;
409 u32 count;
410 int ret;
411
412 smc = devm_kzalloc(dev, sizeof(*smc), GFP_KERNEL);
413 if (!smc)
414 return -ENOMEM;
415
416 smc->dev = &pdev->dev;
417 smc->sram_base = devm_platform_get_and_ioremap_resource(pdev, 1, &smc->sram);
418 if (IS_ERR(smc->sram_base))
419 return dev_err_probe(dev, PTR_ERR(smc->sram_base), "Failed to map SRAM region");
420
421 smc->rtk = devm_apple_rtkit_init(dev, smc, NULL, 0, &apple_smc_rtkit_ops);
422 if (IS_ERR(smc->rtk))
423 return dev_err_probe(dev, PTR_ERR(smc->rtk), "Failed to initialize RTKit");
424
425 smc->boot_stage = APPLE_SMC_BOOTING;
426 ret = apple_rtkit_wake(smc->rtk);
427 if (ret)
428 return dev_err_probe(dev, ret, "Failed to wake up SMC");
429
430 ret = devm_add_action_or_reset(dev, apple_smc_rtkit_shutdown, smc);
431 if (ret)
432 return dev_err_probe(dev, ret, "Failed to register rtkit shutdown action");
433
434 ret = apple_rtkit_start_ep(smc->rtk, SMC_ENDPOINT);
435 if (ret)
436 return dev_err_probe(dev, ret, "Failed to start SMC endpoint");
437
438 init_completion(&smc->init_done);
439 init_completion(&smc->cmd_done);
440
441 ret = apple_rtkit_send_message(smc->rtk, SMC_ENDPOINT,
442 FIELD_PREP(SMC_MSG, SMC_MSG_INITIALIZE), NULL, false);
443 if (ret)
444 return dev_err_probe(dev, ret, "Failed to send init message");
445
446 if (wait_for_completion_timeout(&smc->init_done, msecs_to_jiffies(SMC_TIMEOUT_MS)) == 0) {
447 dev_err(dev, "Timed out initializing SMC");
448 return -ETIMEDOUT;
449 }
450
451 if (smc->boot_stage != APPLE_SMC_INITIALIZED) {
452 dev_err(dev, "SMC failed to boot successfully, boot stage=%d\n", smc->boot_stage);
453 return -EIO;
454 }
455
456 dev_set_drvdata(&pdev->dev, smc);
457 BLOCKING_INIT_NOTIFIER_HEAD(&smc->event_handlers);
458
459 ret = apple_smc_read_u32(smc, SMC_KEY(#KEY), &count);
460 if (ret)
461 return dev_err_probe(smc->dev, ret, "Failed to get key count");
462 smc->key_count = be32_to_cpu(count);
463
464 /* Enable notifications */
465 apple_smc_write_flag(smc, SMC_KEY(NTAP), true);
466 ret = devm_add_action_or_reset(dev, apple_smc_disable_notifications, smc);
467 if (ret)
468 return dev_err_probe(dev, ret, "Failed to register notification disable action");
469
470 ret = devm_mfd_add_devices(smc->dev, PLATFORM_DEVID_NONE,
471 apple_smc_devs, ARRAY_SIZE(apple_smc_devs),
472 NULL, 0, NULL);
473 if (ret)
474 return dev_err_probe(smc->dev, ret, "Failed to register sub-devices");
475
476
477 return 0;
478 }
479
480 static const struct of_device_id apple_smc_of_match[] = {
481 { .compatible = "apple,smc" },
482 {},
483 };
484 MODULE_DEVICE_TABLE(of, apple_smc_of_match);
485
486 static struct platform_driver apple_smc_driver = {
487 .driver = {
488 .name = "macsmc",
489 .of_match_table = apple_smc_of_match,
490 },
491 .probe = apple_smc_probe,
492 };
493 module_platform_driver(apple_smc_driver);
494
495 MODULE_AUTHOR("Hector Martin <marcan@marcan.st>");
496 MODULE_AUTHOR("Sven Peter <sven@kernel.org>");
497 MODULE_LICENSE("Dual MIT/GPL");
498 MODULE_DESCRIPTION("Apple SMC driver");
499