1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * APM X-Gene SoC Hardware Monitoring Driver 4 * 5 * Copyright (c) 2016, Applied Micro Circuits Corporation 6 * Author: Loc Ho <lho@apm.com> 7 * Hoan Tran <hotran@apm.com> 8 * 9 * This driver provides the following features: 10 * - Retrieve CPU total power (uW) 11 * - Retrieve IO total power (uW) 12 * - Retrieve SoC temperature (milli-degree C) and alarm 13 */ 14 #include <linux/acpi.h> 15 #include <linux/dma-mapping.h> 16 #include <linux/hwmon.h> 17 #include <linux/hwmon-sysfs.h> 18 #include <linux/io.h> 19 #include <linux/interrupt.h> 20 #include <linux/kfifo.h> 21 #include <linux/mailbox_controller.h> 22 #include <linux/mailbox_client.h> 23 #include <linux/module.h> 24 #include <linux/of.h> 25 #include <linux/platform_device.h> 26 27 #include <acpi/pcc.h> 28 29 /* SLIMpro message defines */ 30 #define MSG_TYPE_DBG 0 31 #define MSG_TYPE_ERR 7 32 #define MSG_TYPE_PWRMGMT 9 33 34 #define MSG_TYPE(v) (((v) & 0xF0000000) >> 28) 35 #define MSG_TYPE_SET(v) (((v) << 28) & 0xF0000000) 36 #define MSG_SUBTYPE(v) (((v) & 0x0F000000) >> 24) 37 #define MSG_SUBTYPE_SET(v) (((v) << 24) & 0x0F000000) 38 39 #define DBG_SUBTYPE_SENSOR_READ 4 40 #define SENSOR_RD_MSG 0x04FFE902 41 #define SENSOR_RD_EN_ADDR(a) ((a) & 0x000FFFFF) 42 #define PMD_PWR_REG 0x20 43 #define PMD_PWR_MW_REG 0x26 44 #define SOC_PWR_REG 0x21 45 #define SOC_PWR_MW_REG 0x27 46 #define SOC_TEMP_REG 0x10 47 48 #define TEMP_NEGATIVE_BIT 8 49 #define SENSOR_INVALID_DATA BIT(15) 50 51 #define PWRMGMT_SUBTYPE_TPC 1 52 #define TPC_ALARM 2 53 #define TPC_GET_ALARM 3 54 #define TPC_CMD(v) (((v) & 0x00FF0000) >> 16) 55 #define TPC_CMD_SET(v) (((v) << 16) & 0x00FF0000) 56 #define TPC_EN_MSG(hndl, cmd, type) \ 57 (MSG_TYPE_SET(MSG_TYPE_PWRMGMT) | \ 58 MSG_SUBTYPE_SET(hndl) | TPC_CMD_SET(cmd) | type) 59 60 /* 61 * Arbitrary retries in case the remote processor is slow to respond 62 * to PCC commands 63 */ 64 #define PCC_NUM_RETRIES 500 65 66 #define ASYNC_MSG_FIFO_SIZE 16 67 #define MBOX_OP_TIMEOUTMS 1000 68 69 #define WATT_TO_mWATT(x) ((x) * 1000) 70 #define mWATT_TO_uWATT(x) ((x) * 1000) 71 #define CELSIUS_TO_mCELSIUS(x) ((x) * 1000) 72 73 #define to_xgene_hwmon_dev(cl) \ 74 container_of(cl, struct xgene_hwmon_dev, mbox_client) 75 76 enum xgene_hwmon_version { 77 XGENE_HWMON_V1 = 0, 78 XGENE_HWMON_V2 = 1, 79 }; 80 81 struct slimpro_resp_msg { 82 u32 msg; 83 u32 param1; 84 u32 param2; 85 } __packed; 86 87 struct xgene_hwmon_dev { 88 struct device *dev; 89 struct mbox_chan *mbox_chan; 90 struct pcc_mbox_chan *pcc_chan; 91 struct mbox_client mbox_client; 92 int mbox_idx; 93 94 spinlock_t kfifo_lock; 95 struct mutex rd_mutex; 96 struct completion rd_complete; 97 int resp_pending; 98 struct slimpro_resp_msg sync_msg; 99 100 struct work_struct workq; 101 struct kfifo_rec_ptr_1 async_msg_fifo; 102 103 struct device *hwmon_dev; 104 bool temp_critical_alarm; 105 106 unsigned int usecs_lat; 107 }; 108 109 /* 110 * This function tests and clears a bitmask then returns its old value 111 */ 112 static u16 xgene_word_tst_and_clr(u16 *addr, u16 mask) 113 { 114 u16 ret, val; 115 116 val = le16_to_cpu(READ_ONCE(*addr)); 117 ret = val & mask; 118 val &= ~mask; 119 WRITE_ONCE(*addr, cpu_to_le16(val)); 120 121 return ret; 122 } 123 124 static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg) 125 { 126 struct acpi_pcct_shared_memory __iomem *generic_comm_base = 127 ctx->pcc_chan->shmem; 128 u32 *ptr = (void *)(generic_comm_base + 1); 129 int rc, i; 130 u16 val; 131 132 mutex_lock(&ctx->rd_mutex); 133 init_completion(&ctx->rd_complete); 134 ctx->resp_pending = true; 135 136 /* Write to the shared command region */ 137 WRITE_ONCE(generic_comm_base->command, 138 cpu_to_le16(MSG_TYPE(msg[0]) | PCC_CMD_GENERATE_DB_INTR)); 139 140 /* Flip CMD COMPLETE bit */ 141 val = le16_to_cpu(READ_ONCE(generic_comm_base->status)); 142 val &= ~PCC_STATUS_CMD_COMPLETE; 143 WRITE_ONCE(generic_comm_base->status, cpu_to_le16(val)); 144 145 /* Copy the message to the PCC comm space */ 146 for (i = 0; i < sizeof(struct slimpro_resp_msg) / 4; i++) 147 WRITE_ONCE(ptr[i], cpu_to_le32(msg[i])); 148 149 /* Ring the doorbell */ 150 rc = mbox_send_message(ctx->mbox_chan, msg); 151 if (rc < 0) { 152 dev_err(ctx->dev, "Mailbox send error %d\n", rc); 153 goto err; 154 } 155 if (!wait_for_completion_timeout(&ctx->rd_complete, 156 usecs_to_jiffies(ctx->usecs_lat))) { 157 dev_err(ctx->dev, "Mailbox operation timed out\n"); 158 rc = -ETIMEDOUT; 159 goto err; 160 } 161 162 /* Check for error message */ 163 if (MSG_TYPE(ctx->sync_msg.msg) == MSG_TYPE_ERR) { 164 rc = -EINVAL; 165 goto err; 166 } 167 168 msg[0] = ctx->sync_msg.msg; 169 msg[1] = ctx->sync_msg.param1; 170 msg[2] = ctx->sync_msg.param2; 171 172 err: 173 mbox_chan_txdone(ctx->mbox_chan, 0); 174 ctx->resp_pending = false; 175 mutex_unlock(&ctx->rd_mutex); 176 return rc; 177 } 178 179 static int xgene_hwmon_rd(struct xgene_hwmon_dev *ctx, u32 *msg) 180 { 181 int rc; 182 183 mutex_lock(&ctx->rd_mutex); 184 init_completion(&ctx->rd_complete); 185 ctx->resp_pending = true; 186 187 rc = mbox_send_message(ctx->mbox_chan, msg); 188 if (rc < 0) { 189 dev_err(ctx->dev, "Mailbox send error %d\n", rc); 190 goto err; 191 } 192 193 if (!wait_for_completion_timeout(&ctx->rd_complete, 194 msecs_to_jiffies(MBOX_OP_TIMEOUTMS))) { 195 dev_err(ctx->dev, "Mailbox operation timed out\n"); 196 rc = -ETIMEDOUT; 197 goto err; 198 } 199 200 /* Check for error message */ 201 if (MSG_TYPE(ctx->sync_msg.msg) == MSG_TYPE_ERR) { 202 rc = -EINVAL; 203 goto err; 204 } 205 206 msg[0] = ctx->sync_msg.msg; 207 msg[1] = ctx->sync_msg.param1; 208 msg[2] = ctx->sync_msg.param2; 209 210 err: 211 ctx->resp_pending = false; 212 mutex_unlock(&ctx->rd_mutex); 213 return rc; 214 } 215 216 static int xgene_hwmon_reg_map_rd(struct xgene_hwmon_dev *ctx, u32 addr, 217 u32 *data) 218 { 219 u32 msg[3]; 220 int rc; 221 222 msg[0] = SENSOR_RD_MSG; 223 msg[1] = SENSOR_RD_EN_ADDR(addr); 224 msg[2] = 0; 225 226 if (acpi_disabled) 227 rc = xgene_hwmon_rd(ctx, msg); 228 else 229 rc = xgene_hwmon_pcc_rd(ctx, msg); 230 231 if (rc < 0) 232 return rc; 233 234 /* 235 * Check if sensor data is valid. 236 */ 237 if (msg[1] & SENSOR_INVALID_DATA) 238 return -ENODATA; 239 240 *data = msg[1]; 241 242 return rc; 243 } 244 245 static int xgene_hwmon_get_notification_msg(struct xgene_hwmon_dev *ctx, 246 u32 *amsg) 247 { 248 u32 msg[3]; 249 int rc; 250 251 msg[0] = TPC_EN_MSG(PWRMGMT_SUBTYPE_TPC, TPC_GET_ALARM, 0); 252 msg[1] = 0; 253 msg[2] = 0; 254 255 rc = xgene_hwmon_pcc_rd(ctx, msg); 256 if (rc < 0) 257 return rc; 258 259 amsg[0] = msg[0]; 260 amsg[1] = msg[1]; 261 amsg[2] = msg[2]; 262 263 return rc; 264 } 265 266 static int xgene_hwmon_get_cpu_pwr(struct xgene_hwmon_dev *ctx, u32 *val) 267 { 268 u32 watt, mwatt; 269 int rc; 270 271 rc = xgene_hwmon_reg_map_rd(ctx, PMD_PWR_REG, &watt); 272 if (rc < 0) 273 return rc; 274 275 rc = xgene_hwmon_reg_map_rd(ctx, PMD_PWR_MW_REG, &mwatt); 276 if (rc < 0) 277 return rc; 278 279 *val = WATT_TO_mWATT(watt) + mwatt; 280 return 0; 281 } 282 283 static int xgene_hwmon_get_io_pwr(struct xgene_hwmon_dev *ctx, u32 *val) 284 { 285 u32 watt, mwatt; 286 int rc; 287 288 rc = xgene_hwmon_reg_map_rd(ctx, SOC_PWR_REG, &watt); 289 if (rc < 0) 290 return rc; 291 292 rc = xgene_hwmon_reg_map_rd(ctx, SOC_PWR_MW_REG, &mwatt); 293 if (rc < 0) 294 return rc; 295 296 *val = WATT_TO_mWATT(watt) + mwatt; 297 return 0; 298 } 299 300 static int xgene_hwmon_get_temp(struct xgene_hwmon_dev *ctx, u32 *val) 301 { 302 return xgene_hwmon_reg_map_rd(ctx, SOC_TEMP_REG, val); 303 } 304 305 /* 306 * Sensor temperature/power functions 307 */ 308 static ssize_t temp1_input_show(struct device *dev, 309 struct device_attribute *attr, 310 char *buf) 311 { 312 struct xgene_hwmon_dev *ctx = dev_get_drvdata(dev); 313 int rc, temp; 314 u32 val; 315 316 rc = xgene_hwmon_get_temp(ctx, &val); 317 if (rc < 0) 318 return rc; 319 320 temp = sign_extend32(val, TEMP_NEGATIVE_BIT); 321 322 return sysfs_emit(buf, "%d\n", CELSIUS_TO_mCELSIUS(temp)); 323 } 324 325 static ssize_t temp1_label_show(struct device *dev, 326 struct device_attribute *attr, 327 char *buf) 328 { 329 return sysfs_emit(buf, "SoC Temperature\n"); 330 } 331 332 static ssize_t temp1_critical_alarm_show(struct device *dev, 333 struct device_attribute *devattr, 334 char *buf) 335 { 336 struct xgene_hwmon_dev *ctx = dev_get_drvdata(dev); 337 338 return sysfs_emit(buf, "%d\n", ctx->temp_critical_alarm); 339 } 340 341 static ssize_t power1_label_show(struct device *dev, 342 struct device_attribute *attr, 343 char *buf) 344 { 345 return sysfs_emit(buf, "CPU power\n"); 346 } 347 348 static ssize_t power2_label_show(struct device *dev, 349 struct device_attribute *attr, 350 char *buf) 351 { 352 return sysfs_emit(buf, "IO power\n"); 353 } 354 355 static ssize_t power1_input_show(struct device *dev, 356 struct device_attribute *attr, 357 char *buf) 358 { 359 struct xgene_hwmon_dev *ctx = dev_get_drvdata(dev); 360 u32 val; 361 int rc; 362 363 rc = xgene_hwmon_get_cpu_pwr(ctx, &val); 364 if (rc < 0) 365 return rc; 366 367 return sysfs_emit(buf, "%u\n", mWATT_TO_uWATT(val)); 368 } 369 370 static ssize_t power2_input_show(struct device *dev, 371 struct device_attribute *attr, 372 char *buf) 373 { 374 struct xgene_hwmon_dev *ctx = dev_get_drvdata(dev); 375 u32 val; 376 int rc; 377 378 rc = xgene_hwmon_get_io_pwr(ctx, &val); 379 if (rc < 0) 380 return rc; 381 382 return sysfs_emit(buf, "%u\n", mWATT_TO_uWATT(val)); 383 } 384 385 static DEVICE_ATTR_RO(temp1_label); 386 static DEVICE_ATTR_RO(temp1_input); 387 static DEVICE_ATTR_RO(temp1_critical_alarm); 388 static DEVICE_ATTR_RO(power1_label); 389 static DEVICE_ATTR_RO(power1_input); 390 static DEVICE_ATTR_RO(power2_label); 391 static DEVICE_ATTR_RO(power2_input); 392 393 static struct attribute *xgene_hwmon_attrs[] = { 394 &dev_attr_temp1_label.attr, 395 &dev_attr_temp1_input.attr, 396 &dev_attr_temp1_critical_alarm.attr, 397 &dev_attr_power1_label.attr, 398 &dev_attr_power1_input.attr, 399 &dev_attr_power2_label.attr, 400 &dev_attr_power2_input.attr, 401 NULL, 402 }; 403 404 ATTRIBUTE_GROUPS(xgene_hwmon); 405 406 static int xgene_hwmon_tpc_alarm(struct xgene_hwmon_dev *ctx, 407 struct slimpro_resp_msg *amsg) 408 { 409 ctx->temp_critical_alarm = !!amsg->param2; 410 sysfs_notify(&ctx->dev->kobj, NULL, "temp1_critical_alarm"); 411 412 return 0; 413 } 414 415 static void xgene_hwmon_process_pwrmsg(struct xgene_hwmon_dev *ctx, 416 struct slimpro_resp_msg *amsg) 417 { 418 if ((MSG_SUBTYPE(amsg->msg) == PWRMGMT_SUBTYPE_TPC) && 419 (TPC_CMD(amsg->msg) == TPC_ALARM)) 420 xgene_hwmon_tpc_alarm(ctx, amsg); 421 } 422 423 /* 424 * This function is called to process async work queue 425 */ 426 static void xgene_hwmon_evt_work(struct work_struct *work) 427 { 428 struct slimpro_resp_msg amsg; 429 struct xgene_hwmon_dev *ctx; 430 int ret; 431 432 ctx = container_of(work, struct xgene_hwmon_dev, workq); 433 while (kfifo_out_spinlocked(&ctx->async_msg_fifo, &amsg, 434 sizeof(struct slimpro_resp_msg), 435 &ctx->kfifo_lock)) { 436 /* 437 * If PCC, send a consumer command to Platform to get info 438 * If Slimpro Mailbox, get message from specific FIFO 439 */ 440 if (!acpi_disabled) { 441 ret = xgene_hwmon_get_notification_msg(ctx, 442 (u32 *)&amsg); 443 if (ret < 0) 444 continue; 445 } 446 447 if (MSG_TYPE(amsg.msg) == MSG_TYPE_PWRMGMT) 448 xgene_hwmon_process_pwrmsg(ctx, &amsg); 449 } 450 } 451 452 static int xgene_hwmon_rx_ready(struct xgene_hwmon_dev *ctx, void *msg) 453 { 454 if (IS_ERR_OR_NULL(ctx->hwmon_dev) && !ctx->resp_pending) { 455 /* Enqueue to the FIFO */ 456 kfifo_in_spinlocked(&ctx->async_msg_fifo, msg, 457 sizeof(struct slimpro_resp_msg), 458 &ctx->kfifo_lock); 459 return -ENODEV; 460 } 461 462 return 0; 463 } 464 465 /* 466 * This function is called when the SLIMpro Mailbox received a message 467 */ 468 static void xgene_hwmon_rx_cb(struct mbox_client *cl, void *msg) 469 { 470 struct xgene_hwmon_dev *ctx = to_xgene_hwmon_dev(cl); 471 472 /* 473 * While the driver registers with the mailbox framework, an interrupt 474 * can be pending before the probe function completes its 475 * initialization. If such condition occurs, just queue up the message 476 * as the driver is not ready for servicing the callback. 477 */ 478 if (xgene_hwmon_rx_ready(ctx, msg) < 0) 479 return; 480 481 /* 482 * Response message format: 483 * msg[0] is the return code of the operation 484 * msg[1] is the first parameter word 485 * msg[2] is the second parameter word 486 * 487 * As message only supports dword size, just assign it. 488 */ 489 490 /* Check for sync query */ 491 if (ctx->resp_pending && 492 ((MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_ERR) || 493 (MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_DBG && 494 MSG_SUBTYPE(((u32 *)msg)[0]) == DBG_SUBTYPE_SENSOR_READ) || 495 (MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_PWRMGMT && 496 MSG_SUBTYPE(((u32 *)msg)[0]) == PWRMGMT_SUBTYPE_TPC && 497 TPC_CMD(((u32 *)msg)[0]) == TPC_ALARM))) { 498 ctx->sync_msg.msg = ((u32 *)msg)[0]; 499 ctx->sync_msg.param1 = ((u32 *)msg)[1]; 500 ctx->sync_msg.param2 = ((u32 *)msg)[2]; 501 502 /* Operation waiting for response */ 503 complete(&ctx->rd_complete); 504 505 return; 506 } 507 508 /* Enqueue to the FIFO */ 509 kfifo_in_spinlocked(&ctx->async_msg_fifo, msg, 510 sizeof(struct slimpro_resp_msg), &ctx->kfifo_lock); 511 /* Schedule the bottom handler */ 512 schedule_work(&ctx->workq); 513 } 514 515 /* 516 * This function is called when the PCC Mailbox received a message 517 */ 518 static void xgene_hwmon_pcc_rx_cb(struct mbox_client *cl, void *msg) 519 { 520 struct xgene_hwmon_dev *ctx = to_xgene_hwmon_dev(cl); 521 struct acpi_pcct_shared_memory __iomem *generic_comm_base = 522 ctx->pcc_chan->shmem; 523 struct slimpro_resp_msg amsg; 524 525 /* 526 * While the driver registers with the mailbox framework, an interrupt 527 * can be pending before the probe function completes its 528 * initialization. If such condition occurs, just queue up the message 529 * as the driver is not ready for servicing the callback. 530 */ 531 if (xgene_hwmon_rx_ready(ctx, &amsg) < 0) 532 return; 533 534 msg = generic_comm_base + 1; 535 /* Check if platform sends interrupt */ 536 if (!xgene_word_tst_and_clr(&generic_comm_base->status, 537 PCC_STATUS_SCI_DOORBELL)) 538 return; 539 540 /* 541 * Response message format: 542 * msg[0] is the return code of the operation 543 * msg[1] is the first parameter word 544 * msg[2] is the second parameter word 545 * 546 * As message only supports dword size, just assign it. 547 */ 548 549 /* Check for sync query */ 550 if (ctx->resp_pending && 551 ((MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_ERR) || 552 (MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_DBG && 553 MSG_SUBTYPE(((u32 *)msg)[0]) == DBG_SUBTYPE_SENSOR_READ) || 554 (MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_PWRMGMT && 555 MSG_SUBTYPE(((u32 *)msg)[0]) == PWRMGMT_SUBTYPE_TPC && 556 TPC_CMD(((u32 *)msg)[0]) == TPC_ALARM))) { 557 /* Check if platform completes command */ 558 if (xgene_word_tst_and_clr(&generic_comm_base->status, 559 PCC_STATUS_CMD_COMPLETE)) { 560 ctx->sync_msg.msg = ((u32 *)msg)[0]; 561 ctx->sync_msg.param1 = ((u32 *)msg)[1]; 562 ctx->sync_msg.param2 = ((u32 *)msg)[2]; 563 564 /* Operation waiting for response */ 565 complete(&ctx->rd_complete); 566 567 return; 568 } 569 } 570 571 /* 572 * Platform notifies interrupt to OSPM. 573 * OPSM schedules a consumer command to get this information 574 * in a workqueue. Platform must wait until OSPM has issued 575 * a consumer command that serves this notification. 576 */ 577 578 /* Enqueue to the FIFO */ 579 kfifo_in_spinlocked(&ctx->async_msg_fifo, &amsg, 580 sizeof(struct slimpro_resp_msg), &ctx->kfifo_lock); 581 /* Schedule the bottom handler */ 582 schedule_work(&ctx->workq); 583 } 584 585 static void xgene_hwmon_tx_done(struct mbox_client *cl, void *msg, int ret) 586 { 587 if (ret) { 588 dev_dbg(cl->dev, "TX did not complete: CMD sent:%x, ret:%d\n", 589 *(u16 *)msg, ret); 590 } else { 591 dev_dbg(cl->dev, "TX completed. CMD sent:%x, ret:%d\n", 592 *(u16 *)msg, ret); 593 } 594 } 595 596 #ifdef CONFIG_ACPI 597 static const struct acpi_device_id xgene_hwmon_acpi_match[] = { 598 {"APMC0D29", XGENE_HWMON_V1}, 599 {"APMC0D8A", XGENE_HWMON_V2}, 600 {}, 601 }; 602 MODULE_DEVICE_TABLE(acpi, xgene_hwmon_acpi_match); 603 #endif 604 605 static int xgene_hwmon_probe(struct platform_device *pdev) 606 { 607 struct xgene_hwmon_dev *ctx; 608 struct mbox_client *cl; 609 int rc; 610 611 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); 612 if (!ctx) 613 return -ENOMEM; 614 615 ctx->dev = &pdev->dev; 616 platform_set_drvdata(pdev, ctx); 617 cl = &ctx->mbox_client; 618 619 spin_lock_init(&ctx->kfifo_lock); 620 mutex_init(&ctx->rd_mutex); 621 622 rc = kfifo_alloc(&ctx->async_msg_fifo, 623 sizeof(struct slimpro_resp_msg) * ASYNC_MSG_FIFO_SIZE, 624 GFP_KERNEL); 625 if (rc) 626 return -ENOMEM; 627 628 INIT_WORK(&ctx->workq, xgene_hwmon_evt_work); 629 630 /* Request mailbox channel */ 631 cl->dev = &pdev->dev; 632 cl->tx_done = xgene_hwmon_tx_done; 633 cl->tx_block = false; 634 cl->tx_tout = MBOX_OP_TIMEOUTMS; 635 cl->knows_txdone = false; 636 if (acpi_disabled) { 637 cl->rx_callback = xgene_hwmon_rx_cb; 638 ctx->mbox_chan = mbox_request_channel(cl, 0); 639 if (IS_ERR(ctx->mbox_chan)) { 640 dev_err(&pdev->dev, 641 "SLIMpro mailbox channel request failed\n"); 642 rc = -ENODEV; 643 goto out_mbox_free; 644 } 645 } else { 646 struct pcc_mbox_chan *pcc_chan; 647 const struct acpi_device_id *acpi_id; 648 649 acpi_id = acpi_match_device(pdev->dev.driver->acpi_match_table, 650 &pdev->dev); 651 if (!acpi_id) { 652 rc = -EINVAL; 653 goto out_mbox_free; 654 } 655 656 if (device_property_read_u32(&pdev->dev, "pcc-channel", 657 &ctx->mbox_idx)) { 658 dev_err(&pdev->dev, "no pcc-channel property\n"); 659 rc = -ENODEV; 660 goto out_mbox_free; 661 } 662 663 cl->rx_callback = xgene_hwmon_pcc_rx_cb; 664 pcc_chan = pcc_mbox_request_channel(cl, ctx->mbox_idx); 665 if (IS_ERR(pcc_chan)) { 666 dev_err(&pdev->dev, 667 "PPC channel request failed\n"); 668 rc = -ENODEV; 669 goto out_mbox_free; 670 } 671 672 ctx->pcc_chan = pcc_chan; 673 ctx->mbox_chan = pcc_chan->mchan; 674 675 if (!ctx->mbox_chan->mbox->txdone_irq) { 676 dev_err(&pdev->dev, "PCC IRQ not supported\n"); 677 rc = -ENODEV; 678 goto out; 679 } 680 681 /* 682 * pcc_chan->latency is just a Nominal value. In reality 683 * the remote processor could be much slower to reply. 684 * So add an arbitrary amount of wait on top of Nominal. 685 */ 686 ctx->usecs_lat = PCC_NUM_RETRIES * pcc_chan->latency; 687 } 688 689 ctx->hwmon_dev = hwmon_device_register_with_groups(ctx->dev, 690 "apm_xgene", 691 ctx, 692 xgene_hwmon_groups); 693 if (IS_ERR(ctx->hwmon_dev)) { 694 dev_err(&pdev->dev, "Failed to register HW monitor device\n"); 695 rc = PTR_ERR(ctx->hwmon_dev); 696 goto out; 697 } 698 699 /* 700 * Schedule the bottom handler if there is a pending message. 701 */ 702 schedule_work(&ctx->workq); 703 704 dev_info(&pdev->dev, "APM X-Gene SoC HW monitor driver registered\n"); 705 706 return 0; 707 708 out: 709 if (acpi_disabled) 710 mbox_free_channel(ctx->mbox_chan); 711 else 712 pcc_mbox_free_channel(ctx->pcc_chan); 713 out_mbox_free: 714 kfifo_free(&ctx->async_msg_fifo); 715 716 return rc; 717 } 718 719 static void xgene_hwmon_remove(struct platform_device *pdev) 720 { 721 struct xgene_hwmon_dev *ctx = platform_get_drvdata(pdev); 722 723 cancel_work_sync(&ctx->workq); 724 hwmon_device_unregister(ctx->hwmon_dev); 725 kfifo_free(&ctx->async_msg_fifo); 726 if (acpi_disabled) 727 mbox_free_channel(ctx->mbox_chan); 728 else 729 pcc_mbox_free_channel(ctx->pcc_chan); 730 } 731 732 static const struct of_device_id xgene_hwmon_of_match[] = { 733 {.compatible = "apm,xgene-slimpro-hwmon"}, 734 {} 735 }; 736 MODULE_DEVICE_TABLE(of, xgene_hwmon_of_match); 737 738 static struct platform_driver xgene_hwmon_driver = { 739 .probe = xgene_hwmon_probe, 740 .remove = xgene_hwmon_remove, 741 .driver = { 742 .name = "xgene-slimpro-hwmon", 743 .of_match_table = xgene_hwmon_of_match, 744 .acpi_match_table = ACPI_PTR(xgene_hwmon_acpi_match), 745 }, 746 }; 747 module_platform_driver(xgene_hwmon_driver); 748 749 MODULE_DESCRIPTION("APM X-Gene SoC hardware monitor"); 750 MODULE_LICENSE("GPL"); 751