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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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