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