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