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