0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/acpi.h>
0015 #include <linux/dma-mapping.h>
0016 #include <linux/hwmon.h>
0017 #include <linux/hwmon-sysfs.h>
0018 #include <linux/io.h>
0019 #include <linux/interrupt.h>
0020 #include <linux/kfifo.h>
0021 #include <linux/mailbox_controller.h>
0022 #include <linux/mailbox_client.h>
0023 #include <linux/module.h>
0024 #include <linux/of.h>
0025 #include <linux/platform_device.h>
0026
0027 #include <acpi/pcc.h>
0028
0029
0030 #define MSG_TYPE_DBG 0
0031 #define MSG_TYPE_ERR 7
0032 #define MSG_TYPE_PWRMGMT 9
0033
0034 #define MSG_TYPE(v) (((v) & 0xF0000000) >> 28)
0035 #define MSG_TYPE_SET(v) (((v) << 28) & 0xF0000000)
0036 #define MSG_SUBTYPE(v) (((v) & 0x0F000000) >> 24)
0037 #define MSG_SUBTYPE_SET(v) (((v) << 24) & 0x0F000000)
0038
0039 #define DBG_SUBTYPE_SENSOR_READ 4
0040 #define SENSOR_RD_MSG 0x04FFE902
0041 #define SENSOR_RD_EN_ADDR(a) ((a) & 0x000FFFFF)
0042 #define PMD_PWR_REG 0x20
0043 #define PMD_PWR_MW_REG 0x26
0044 #define SOC_PWR_REG 0x21
0045 #define SOC_PWR_MW_REG 0x27
0046 #define SOC_TEMP_REG 0x10
0047
0048 #define TEMP_NEGATIVE_BIT 8
0049 #define SENSOR_INVALID_DATA BIT(15)
0050
0051 #define PWRMGMT_SUBTYPE_TPC 1
0052 #define TPC_ALARM 2
0053 #define TPC_GET_ALARM 3
0054 #define TPC_CMD(v) (((v) & 0x00FF0000) >> 16)
0055 #define TPC_CMD_SET(v) (((v) << 16) & 0x00FF0000)
0056 #define TPC_EN_MSG(hndl, cmd, type) \
0057 (MSG_TYPE_SET(MSG_TYPE_PWRMGMT) | \
0058 MSG_SUBTYPE_SET(hndl) | TPC_CMD_SET(cmd) | type)
0059
0060
0061 #define PCC_SIGNATURE_MASK 0x50424300
0062 #define PCCC_GENERATE_DB_INT BIT(15)
0063 #define PCCS_CMD_COMPLETE BIT(0)
0064 #define PCCS_SCI_DOORBEL BIT(1)
0065 #define PCCS_PLATFORM_NOTIFICATION BIT(3)
0066
0067
0068
0069
0070 #define PCC_NUM_RETRIES 500
0071
0072 #define ASYNC_MSG_FIFO_SIZE 16
0073 #define MBOX_OP_TIMEOUTMS 1000
0074
0075 #define WATT_TO_mWATT(x) ((x) * 1000)
0076 #define mWATT_TO_uWATT(x) ((x) * 1000)
0077 #define CELSIUS_TO_mCELSIUS(x) ((x) * 1000)
0078
0079 #define to_xgene_hwmon_dev(cl) \
0080 container_of(cl, struct xgene_hwmon_dev, mbox_client)
0081
0082 enum xgene_hwmon_version {
0083 XGENE_HWMON_V1 = 0,
0084 XGENE_HWMON_V2 = 1,
0085 };
0086
0087 struct slimpro_resp_msg {
0088 u32 msg;
0089 u32 param1;
0090 u32 param2;
0091 } __packed;
0092
0093 struct xgene_hwmon_dev {
0094 struct device *dev;
0095 struct mbox_chan *mbox_chan;
0096 struct pcc_mbox_chan *pcc_chan;
0097 struct mbox_client mbox_client;
0098 int mbox_idx;
0099
0100 spinlock_t kfifo_lock;
0101 struct mutex rd_mutex;
0102 struct completion rd_complete;
0103 int resp_pending;
0104 struct slimpro_resp_msg sync_msg;
0105
0106 struct work_struct workq;
0107 struct kfifo_rec_ptr_1 async_msg_fifo;
0108
0109 struct device *hwmon_dev;
0110 bool temp_critical_alarm;
0111
0112 phys_addr_t comm_base_addr;
0113 void *pcc_comm_addr;
0114 u64 usecs_lat;
0115 };
0116
0117
0118
0119
0120 static u16 xgene_word_tst_and_clr(u16 *addr, u16 mask)
0121 {
0122 u16 ret, val;
0123
0124 val = le16_to_cpu(READ_ONCE(*addr));
0125 ret = val & mask;
0126 val &= ~mask;
0127 WRITE_ONCE(*addr, cpu_to_le16(val));
0128
0129 return ret;
0130 }
0131
0132 static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg)
0133 {
0134 struct acpi_pcct_shared_memory *generic_comm_base = ctx->pcc_comm_addr;
0135 u32 *ptr = (void *)(generic_comm_base + 1);
0136 int rc, i;
0137 u16 val;
0138
0139 mutex_lock(&ctx->rd_mutex);
0140 init_completion(&ctx->rd_complete);
0141 ctx->resp_pending = true;
0142
0143
0144 WRITE_ONCE(generic_comm_base->signature,
0145 cpu_to_le32(PCC_SIGNATURE_MASK | ctx->mbox_idx));
0146
0147
0148 WRITE_ONCE(generic_comm_base->command,
0149 cpu_to_le16(MSG_TYPE(msg[0]) | PCCC_GENERATE_DB_INT));
0150
0151
0152 val = le16_to_cpu(READ_ONCE(generic_comm_base->status));
0153 val &= ~PCCS_CMD_COMPLETE;
0154 WRITE_ONCE(generic_comm_base->status, cpu_to_le16(val));
0155
0156
0157 for (i = 0; i < sizeof(struct slimpro_resp_msg) / 4; i++)
0158 WRITE_ONCE(ptr[i], cpu_to_le32(msg[i]));
0159
0160
0161 rc = mbox_send_message(ctx->mbox_chan, msg);
0162 if (rc < 0) {
0163 dev_err(ctx->dev, "Mailbox send error %d\n", rc);
0164 goto err;
0165 }
0166 if (!wait_for_completion_timeout(&ctx->rd_complete,
0167 usecs_to_jiffies(ctx->usecs_lat))) {
0168 dev_err(ctx->dev, "Mailbox operation timed out\n");
0169 rc = -ETIMEDOUT;
0170 goto err;
0171 }
0172
0173
0174 if (MSG_TYPE(ctx->sync_msg.msg) == MSG_TYPE_ERR) {
0175 rc = -EINVAL;
0176 goto err;
0177 }
0178
0179 msg[0] = ctx->sync_msg.msg;
0180 msg[1] = ctx->sync_msg.param1;
0181 msg[2] = ctx->sync_msg.param2;
0182
0183 err:
0184 mbox_chan_txdone(ctx->mbox_chan, 0);
0185 ctx->resp_pending = false;
0186 mutex_unlock(&ctx->rd_mutex);
0187 return rc;
0188 }
0189
0190 static int xgene_hwmon_rd(struct xgene_hwmon_dev *ctx, u32 *msg)
0191 {
0192 int rc;
0193
0194 mutex_lock(&ctx->rd_mutex);
0195 init_completion(&ctx->rd_complete);
0196 ctx->resp_pending = true;
0197
0198 rc = mbox_send_message(ctx->mbox_chan, msg);
0199 if (rc < 0) {
0200 dev_err(ctx->dev, "Mailbox send error %d\n", rc);
0201 goto err;
0202 }
0203
0204 if (!wait_for_completion_timeout(&ctx->rd_complete,
0205 msecs_to_jiffies(MBOX_OP_TIMEOUTMS))) {
0206 dev_err(ctx->dev, "Mailbox operation timed out\n");
0207 rc = -ETIMEDOUT;
0208 goto err;
0209 }
0210
0211
0212 if (MSG_TYPE(ctx->sync_msg.msg) == MSG_TYPE_ERR) {
0213 rc = -EINVAL;
0214 goto err;
0215 }
0216
0217 msg[0] = ctx->sync_msg.msg;
0218 msg[1] = ctx->sync_msg.param1;
0219 msg[2] = ctx->sync_msg.param2;
0220
0221 err:
0222 ctx->resp_pending = false;
0223 mutex_unlock(&ctx->rd_mutex);
0224 return rc;
0225 }
0226
0227 static int xgene_hwmon_reg_map_rd(struct xgene_hwmon_dev *ctx, u32 addr,
0228 u32 *data)
0229 {
0230 u32 msg[3];
0231 int rc;
0232
0233 msg[0] = SENSOR_RD_MSG;
0234 msg[1] = SENSOR_RD_EN_ADDR(addr);
0235 msg[2] = 0;
0236
0237 if (acpi_disabled)
0238 rc = xgene_hwmon_rd(ctx, msg);
0239 else
0240 rc = xgene_hwmon_pcc_rd(ctx, msg);
0241
0242 if (rc < 0)
0243 return rc;
0244
0245
0246
0247
0248 if (msg[1] & SENSOR_INVALID_DATA)
0249 return -ENODATA;
0250
0251 *data = msg[1];
0252
0253 return rc;
0254 }
0255
0256 static int xgene_hwmon_get_notification_msg(struct xgene_hwmon_dev *ctx,
0257 u32 *amsg)
0258 {
0259 u32 msg[3];
0260 int rc;
0261
0262 msg[0] = TPC_EN_MSG(PWRMGMT_SUBTYPE_TPC, TPC_GET_ALARM, 0);
0263 msg[1] = 0;
0264 msg[2] = 0;
0265
0266 rc = xgene_hwmon_pcc_rd(ctx, msg);
0267 if (rc < 0)
0268 return rc;
0269
0270 amsg[0] = msg[0];
0271 amsg[1] = msg[1];
0272 amsg[2] = msg[2];
0273
0274 return rc;
0275 }
0276
0277 static int xgene_hwmon_get_cpu_pwr(struct xgene_hwmon_dev *ctx, u32 *val)
0278 {
0279 u32 watt, mwatt;
0280 int rc;
0281
0282 rc = xgene_hwmon_reg_map_rd(ctx, PMD_PWR_REG, &watt);
0283 if (rc < 0)
0284 return rc;
0285
0286 rc = xgene_hwmon_reg_map_rd(ctx, PMD_PWR_MW_REG, &mwatt);
0287 if (rc < 0)
0288 return rc;
0289
0290 *val = WATT_TO_mWATT(watt) + mwatt;
0291 return 0;
0292 }
0293
0294 static int xgene_hwmon_get_io_pwr(struct xgene_hwmon_dev *ctx, u32 *val)
0295 {
0296 u32 watt, mwatt;
0297 int rc;
0298
0299 rc = xgene_hwmon_reg_map_rd(ctx, SOC_PWR_REG, &watt);
0300 if (rc < 0)
0301 return rc;
0302
0303 rc = xgene_hwmon_reg_map_rd(ctx, SOC_PWR_MW_REG, &mwatt);
0304 if (rc < 0)
0305 return rc;
0306
0307 *val = WATT_TO_mWATT(watt) + mwatt;
0308 return 0;
0309 }
0310
0311 static int xgene_hwmon_get_temp(struct xgene_hwmon_dev *ctx, u32 *val)
0312 {
0313 return xgene_hwmon_reg_map_rd(ctx, SOC_TEMP_REG, val);
0314 }
0315
0316
0317
0318
0319 static ssize_t temp1_input_show(struct device *dev,
0320 struct device_attribute *attr,
0321 char *buf)
0322 {
0323 struct xgene_hwmon_dev *ctx = dev_get_drvdata(dev);
0324 int rc, temp;
0325 u32 val;
0326
0327 rc = xgene_hwmon_get_temp(ctx, &val);
0328 if (rc < 0)
0329 return rc;
0330
0331 temp = sign_extend32(val, TEMP_NEGATIVE_BIT);
0332
0333 return sysfs_emit(buf, "%d\n", CELSIUS_TO_mCELSIUS(temp));
0334 }
0335
0336 static ssize_t temp1_label_show(struct device *dev,
0337 struct device_attribute *attr,
0338 char *buf)
0339 {
0340 return sysfs_emit(buf, "SoC Temperature\n");
0341 }
0342
0343 static ssize_t temp1_critical_alarm_show(struct device *dev,
0344 struct device_attribute *devattr,
0345 char *buf)
0346 {
0347 struct xgene_hwmon_dev *ctx = dev_get_drvdata(dev);
0348
0349 return sysfs_emit(buf, "%d\n", ctx->temp_critical_alarm);
0350 }
0351
0352 static ssize_t power1_label_show(struct device *dev,
0353 struct device_attribute *attr,
0354 char *buf)
0355 {
0356 return sysfs_emit(buf, "CPU power\n");
0357 }
0358
0359 static ssize_t power2_label_show(struct device *dev,
0360 struct device_attribute *attr,
0361 char *buf)
0362 {
0363 return sysfs_emit(buf, "IO power\n");
0364 }
0365
0366 static ssize_t power1_input_show(struct device *dev,
0367 struct device_attribute *attr,
0368 char *buf)
0369 {
0370 struct xgene_hwmon_dev *ctx = dev_get_drvdata(dev);
0371 u32 val;
0372 int rc;
0373
0374 rc = xgene_hwmon_get_cpu_pwr(ctx, &val);
0375 if (rc < 0)
0376 return rc;
0377
0378 return sysfs_emit(buf, "%u\n", mWATT_TO_uWATT(val));
0379 }
0380
0381 static ssize_t power2_input_show(struct device *dev,
0382 struct device_attribute *attr,
0383 char *buf)
0384 {
0385 struct xgene_hwmon_dev *ctx = dev_get_drvdata(dev);
0386 u32 val;
0387 int rc;
0388
0389 rc = xgene_hwmon_get_io_pwr(ctx, &val);
0390 if (rc < 0)
0391 return rc;
0392
0393 return sysfs_emit(buf, "%u\n", mWATT_TO_uWATT(val));
0394 }
0395
0396 static DEVICE_ATTR_RO(temp1_label);
0397 static DEVICE_ATTR_RO(temp1_input);
0398 static DEVICE_ATTR_RO(temp1_critical_alarm);
0399 static DEVICE_ATTR_RO(power1_label);
0400 static DEVICE_ATTR_RO(power1_input);
0401 static DEVICE_ATTR_RO(power2_label);
0402 static DEVICE_ATTR_RO(power2_input);
0403
0404 static struct attribute *xgene_hwmon_attrs[] = {
0405 &dev_attr_temp1_label.attr,
0406 &dev_attr_temp1_input.attr,
0407 &dev_attr_temp1_critical_alarm.attr,
0408 &dev_attr_power1_label.attr,
0409 &dev_attr_power1_input.attr,
0410 &dev_attr_power2_label.attr,
0411 &dev_attr_power2_input.attr,
0412 NULL,
0413 };
0414
0415 ATTRIBUTE_GROUPS(xgene_hwmon);
0416
0417 static int xgene_hwmon_tpc_alarm(struct xgene_hwmon_dev *ctx,
0418 struct slimpro_resp_msg *amsg)
0419 {
0420 ctx->temp_critical_alarm = !!amsg->param2;
0421 sysfs_notify(&ctx->dev->kobj, NULL, "temp1_critical_alarm");
0422
0423 return 0;
0424 }
0425
0426 static void xgene_hwmon_process_pwrmsg(struct xgene_hwmon_dev *ctx,
0427 struct slimpro_resp_msg *amsg)
0428 {
0429 if ((MSG_SUBTYPE(amsg->msg) == PWRMGMT_SUBTYPE_TPC) &&
0430 (TPC_CMD(amsg->msg) == TPC_ALARM))
0431 xgene_hwmon_tpc_alarm(ctx, amsg);
0432 }
0433
0434
0435
0436
0437 static void xgene_hwmon_evt_work(struct work_struct *work)
0438 {
0439 struct slimpro_resp_msg amsg;
0440 struct xgene_hwmon_dev *ctx;
0441 int ret;
0442
0443 ctx = container_of(work, struct xgene_hwmon_dev, workq);
0444 while (kfifo_out_spinlocked(&ctx->async_msg_fifo, &amsg,
0445 sizeof(struct slimpro_resp_msg),
0446 &ctx->kfifo_lock)) {
0447
0448
0449
0450
0451 if (!acpi_disabled) {
0452 ret = xgene_hwmon_get_notification_msg(ctx,
0453 (u32 *)&amsg);
0454 if (ret < 0)
0455 continue;
0456 }
0457
0458 if (MSG_TYPE(amsg.msg) == MSG_TYPE_PWRMGMT)
0459 xgene_hwmon_process_pwrmsg(ctx, &amsg);
0460 }
0461 }
0462
0463 static int xgene_hwmon_rx_ready(struct xgene_hwmon_dev *ctx, void *msg)
0464 {
0465 if (IS_ERR_OR_NULL(ctx->hwmon_dev) && !ctx->resp_pending) {
0466
0467 kfifo_in_spinlocked(&ctx->async_msg_fifo, msg,
0468 sizeof(struct slimpro_resp_msg),
0469 &ctx->kfifo_lock);
0470 return -ENODEV;
0471 }
0472
0473 return 0;
0474 }
0475
0476
0477
0478
0479 static void xgene_hwmon_rx_cb(struct mbox_client *cl, void *msg)
0480 {
0481 struct xgene_hwmon_dev *ctx = to_xgene_hwmon_dev(cl);
0482
0483
0484
0485
0486
0487
0488
0489 if (xgene_hwmon_rx_ready(ctx, msg) < 0)
0490 return;
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502 if (ctx->resp_pending &&
0503 ((MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_ERR) ||
0504 (MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_DBG &&
0505 MSG_SUBTYPE(((u32 *)msg)[0]) == DBG_SUBTYPE_SENSOR_READ) ||
0506 (MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_PWRMGMT &&
0507 MSG_SUBTYPE(((u32 *)msg)[0]) == PWRMGMT_SUBTYPE_TPC &&
0508 TPC_CMD(((u32 *)msg)[0]) == TPC_ALARM))) {
0509 ctx->sync_msg.msg = ((u32 *)msg)[0];
0510 ctx->sync_msg.param1 = ((u32 *)msg)[1];
0511 ctx->sync_msg.param2 = ((u32 *)msg)[2];
0512
0513
0514 complete(&ctx->rd_complete);
0515
0516 return;
0517 }
0518
0519
0520 kfifo_in_spinlocked(&ctx->async_msg_fifo, msg,
0521 sizeof(struct slimpro_resp_msg), &ctx->kfifo_lock);
0522
0523 schedule_work(&ctx->workq);
0524 }
0525
0526
0527
0528
0529 static void xgene_hwmon_pcc_rx_cb(struct mbox_client *cl, void *msg)
0530 {
0531 struct xgene_hwmon_dev *ctx = to_xgene_hwmon_dev(cl);
0532 struct acpi_pcct_shared_memory *generic_comm_base = ctx->pcc_comm_addr;
0533 struct slimpro_resp_msg amsg;
0534
0535
0536
0537
0538
0539
0540
0541 if (xgene_hwmon_rx_ready(ctx, &amsg) < 0)
0542 return;
0543
0544 msg = generic_comm_base + 1;
0545
0546 if (!xgene_word_tst_and_clr(&generic_comm_base->status,
0547 PCCS_SCI_DOORBEL))
0548 return;
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560 if (ctx->resp_pending &&
0561 ((MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_ERR) ||
0562 (MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_DBG &&
0563 MSG_SUBTYPE(((u32 *)msg)[0]) == DBG_SUBTYPE_SENSOR_READ) ||
0564 (MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_PWRMGMT &&
0565 MSG_SUBTYPE(((u32 *)msg)[0]) == PWRMGMT_SUBTYPE_TPC &&
0566 TPC_CMD(((u32 *)msg)[0]) == TPC_ALARM))) {
0567
0568 if (xgene_word_tst_and_clr(&generic_comm_base->status,
0569 PCCS_CMD_COMPLETE)) {
0570 ctx->sync_msg.msg = ((u32 *)msg)[0];
0571 ctx->sync_msg.param1 = ((u32 *)msg)[1];
0572 ctx->sync_msg.param2 = ((u32 *)msg)[2];
0573
0574
0575 complete(&ctx->rd_complete);
0576
0577 return;
0578 }
0579 }
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589 kfifo_in_spinlocked(&ctx->async_msg_fifo, &amsg,
0590 sizeof(struct slimpro_resp_msg), &ctx->kfifo_lock);
0591
0592 schedule_work(&ctx->workq);
0593 }
0594
0595 static void xgene_hwmon_tx_done(struct mbox_client *cl, void *msg, int ret)
0596 {
0597 if (ret) {
0598 dev_dbg(cl->dev, "TX did not complete: CMD sent:%x, ret:%d\n",
0599 *(u16 *)msg, ret);
0600 } else {
0601 dev_dbg(cl->dev, "TX completed. CMD sent:%x, ret:%d\n",
0602 *(u16 *)msg, ret);
0603 }
0604 }
0605
0606 #ifdef CONFIG_ACPI
0607 static const struct acpi_device_id xgene_hwmon_acpi_match[] = {
0608 {"APMC0D29", XGENE_HWMON_V1},
0609 {"APMC0D8A", XGENE_HWMON_V2},
0610 {},
0611 };
0612 MODULE_DEVICE_TABLE(acpi, xgene_hwmon_acpi_match);
0613 #endif
0614
0615 static int xgene_hwmon_probe(struct platform_device *pdev)
0616 {
0617 struct xgene_hwmon_dev *ctx;
0618 struct mbox_client *cl;
0619 int rc;
0620
0621 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
0622 if (!ctx)
0623 return -ENOMEM;
0624
0625 ctx->dev = &pdev->dev;
0626 platform_set_drvdata(pdev, ctx);
0627 cl = &ctx->mbox_client;
0628
0629 spin_lock_init(&ctx->kfifo_lock);
0630 mutex_init(&ctx->rd_mutex);
0631
0632 rc = kfifo_alloc(&ctx->async_msg_fifo,
0633 sizeof(struct slimpro_resp_msg) * ASYNC_MSG_FIFO_SIZE,
0634 GFP_KERNEL);
0635 if (rc)
0636 return -ENOMEM;
0637
0638 INIT_WORK(&ctx->workq, xgene_hwmon_evt_work);
0639
0640
0641 cl->dev = &pdev->dev;
0642 cl->tx_done = xgene_hwmon_tx_done;
0643 cl->tx_block = false;
0644 cl->tx_tout = MBOX_OP_TIMEOUTMS;
0645 cl->knows_txdone = false;
0646 if (acpi_disabled) {
0647 cl->rx_callback = xgene_hwmon_rx_cb;
0648 ctx->mbox_chan = mbox_request_channel(cl, 0);
0649 if (IS_ERR(ctx->mbox_chan)) {
0650 dev_err(&pdev->dev,
0651 "SLIMpro mailbox channel request failed\n");
0652 rc = -ENODEV;
0653 goto out_mbox_free;
0654 }
0655 } else {
0656 struct pcc_mbox_chan *pcc_chan;
0657 const struct acpi_device_id *acpi_id;
0658 int version;
0659
0660 acpi_id = acpi_match_device(pdev->dev.driver->acpi_match_table,
0661 &pdev->dev);
0662 if (!acpi_id) {
0663 rc = -EINVAL;
0664 goto out_mbox_free;
0665 }
0666
0667 version = (int)acpi_id->driver_data;
0668
0669 if (device_property_read_u32(&pdev->dev, "pcc-channel",
0670 &ctx->mbox_idx)) {
0671 dev_err(&pdev->dev, "no pcc-channel property\n");
0672 rc = -ENODEV;
0673 goto out_mbox_free;
0674 }
0675
0676 cl->rx_callback = xgene_hwmon_pcc_rx_cb;
0677 pcc_chan = pcc_mbox_request_channel(cl, ctx->mbox_idx);
0678 if (IS_ERR(pcc_chan)) {
0679 dev_err(&pdev->dev,
0680 "PPC channel request failed\n");
0681 rc = -ENODEV;
0682 goto out_mbox_free;
0683 }
0684
0685 ctx->pcc_chan = pcc_chan;
0686 ctx->mbox_chan = pcc_chan->mchan;
0687
0688 if (!ctx->mbox_chan->mbox->txdone_irq) {
0689 dev_err(&pdev->dev, "PCC IRQ not supported\n");
0690 rc = -ENODEV;
0691 goto out;
0692 }
0693
0694
0695
0696
0697
0698 ctx->comm_base_addr = pcc_chan->shmem_base_addr;
0699 if (ctx->comm_base_addr) {
0700 if (version == XGENE_HWMON_V2)
0701 ctx->pcc_comm_addr = (void __force *)ioremap(
0702 ctx->comm_base_addr,
0703 pcc_chan->shmem_size);
0704 else
0705 ctx->pcc_comm_addr = memremap(
0706 ctx->comm_base_addr,
0707 pcc_chan->shmem_size,
0708 MEMREMAP_WB);
0709 } else {
0710 dev_err(&pdev->dev, "Failed to get PCC comm region\n");
0711 rc = -ENODEV;
0712 goto out;
0713 }
0714
0715 if (!ctx->pcc_comm_addr) {
0716 dev_err(&pdev->dev,
0717 "Failed to ioremap PCC comm region\n");
0718 rc = -ENOMEM;
0719 goto out;
0720 }
0721
0722
0723
0724
0725
0726
0727 ctx->usecs_lat = PCC_NUM_RETRIES * pcc_chan->latency;
0728 }
0729
0730 ctx->hwmon_dev = hwmon_device_register_with_groups(ctx->dev,
0731 "apm_xgene",
0732 ctx,
0733 xgene_hwmon_groups);
0734 if (IS_ERR(ctx->hwmon_dev)) {
0735 dev_err(&pdev->dev, "Failed to register HW monitor device\n");
0736 rc = PTR_ERR(ctx->hwmon_dev);
0737 goto out;
0738 }
0739
0740
0741
0742
0743 schedule_work(&ctx->workq);
0744
0745 dev_info(&pdev->dev, "APM X-Gene SoC HW monitor driver registered\n");
0746
0747 return 0;
0748
0749 out:
0750 if (acpi_disabled)
0751 mbox_free_channel(ctx->mbox_chan);
0752 else
0753 pcc_mbox_free_channel(ctx->pcc_chan);
0754 out_mbox_free:
0755 kfifo_free(&ctx->async_msg_fifo);
0756
0757 return rc;
0758 }
0759
0760 static int xgene_hwmon_remove(struct platform_device *pdev)
0761 {
0762 struct xgene_hwmon_dev *ctx = platform_get_drvdata(pdev);
0763
0764 hwmon_device_unregister(ctx->hwmon_dev);
0765 kfifo_free(&ctx->async_msg_fifo);
0766 if (acpi_disabled)
0767 mbox_free_channel(ctx->mbox_chan);
0768 else
0769 pcc_mbox_free_channel(ctx->pcc_chan);
0770
0771 return 0;
0772 }
0773
0774 static const struct of_device_id xgene_hwmon_of_match[] = {
0775 {.compatible = "apm,xgene-slimpro-hwmon"},
0776 {}
0777 };
0778 MODULE_DEVICE_TABLE(of, xgene_hwmon_of_match);
0779
0780 static struct platform_driver xgene_hwmon_driver = {
0781 .probe = xgene_hwmon_probe,
0782 .remove = xgene_hwmon_remove,
0783 .driver = {
0784 .name = "xgene-slimpro-hwmon",
0785 .of_match_table = xgene_hwmon_of_match,
0786 .acpi_match_table = ACPI_PTR(xgene_hwmon_acpi_match),
0787 },
0788 };
0789 module_platform_driver(xgene_hwmon_driver);
0790
0791 MODULE_DESCRIPTION("APM X-Gene SoC hardware monitor");
0792 MODULE_LICENSE("GPL");