11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
27224adbbSNeelesh Gupta /*
37224adbbSNeelesh Gupta * PowerNV sensor code
47224adbbSNeelesh Gupta *
57224adbbSNeelesh Gupta * Copyright (C) 2013 IBM
67224adbbSNeelesh Gupta */
77224adbbSNeelesh Gupta
87224adbbSNeelesh Gupta #include <linux/delay.h>
9*81d7cac4SRob Herring #include <linux/of.h>
108de303baSNeelesh Gupta #include <linux/of_platform.h>
11*81d7cac4SRob Herring #include <linux/platform_device.h>
127224adbbSNeelesh Gupta #include <asm/opal.h>
138de303baSNeelesh Gupta #include <asm/machdep.h>
147224adbbSNeelesh Gupta
157224adbbSNeelesh Gupta /*
167224adbbSNeelesh Gupta * This will return sensor information to driver based on the requested sensor
177224adbbSNeelesh Gupta * handle. A handle is an opaque id for the powernv, read by the driver from the
187224adbbSNeelesh Gupta * device tree..
197224adbbSNeelesh Gupta */
opal_get_sensor_data(u32 sensor_hndl,u32 * sensor_data)207224adbbSNeelesh Gupta int opal_get_sensor_data(u32 sensor_hndl, u32 *sensor_data)
217224adbbSNeelesh Gupta {
227224adbbSNeelesh Gupta int ret, token;
237224adbbSNeelesh Gupta struct opal_msg msg;
249000c17dSAnton Blanchard __be32 data;
257224adbbSNeelesh Gupta
267224adbbSNeelesh Gupta token = opal_async_get_token_interruptible();
2795e1bc1dSStewart Smith if (token < 0)
2895e1bc1dSStewart Smith return token;
297224adbbSNeelesh Gupta
309000c17dSAnton Blanchard ret = opal_sensor_read(sensor_hndl, token, &data);
316bc08d03SCédric Le Goater switch (ret) {
326bc08d03SCédric Le Goater case OPAL_ASYNC_COMPLETION:
337224adbbSNeelesh Gupta ret = opal_async_wait_response(token, &msg);
347224adbbSNeelesh Gupta if (ret) {
357224adbbSNeelesh Gupta pr_err("%s: Failed to wait for the async response, %d\n",
367224adbbSNeelesh Gupta __func__, ret);
3795e1bc1dSStewart Smith goto out;
387224adbbSNeelesh Gupta }
397224adbbSNeelesh Gupta
40d0226d31SSuraj Jitindar Singh ret = opal_error_code(opal_get_async_rc(msg));
416bc08d03SCédric Le Goater *sensor_data = be32_to_cpu(data);
426bc08d03SCédric Le Goater break;
436bc08d03SCédric Le Goater
446bc08d03SCédric Le Goater case OPAL_SUCCESS:
456bc08d03SCédric Le Goater ret = 0;
466bc08d03SCédric Le Goater *sensor_data = be32_to_cpu(data);
476bc08d03SCédric Le Goater break;
486bc08d03SCédric Le Goater
4917bb6951SVipin K Parashar case OPAL_WRONG_STATE:
5017bb6951SVipin K Parashar ret = -EIO;
5117bb6951SVipin K Parashar break;
5217bb6951SVipin K Parashar
536bc08d03SCédric Le Goater default:
546bc08d03SCédric Le Goater ret = opal_error_code(ret);
556bc08d03SCédric Le Goater break;
566bc08d03SCédric Le Goater }
577224adbbSNeelesh Gupta
587224adbbSNeelesh Gupta out:
5995e1bc1dSStewart Smith opal_async_release_token(token);
607224adbbSNeelesh Gupta return ret;
617224adbbSNeelesh Gupta }
627224adbbSNeelesh Gupta EXPORT_SYMBOL_GPL(opal_get_sensor_data);
638de303baSNeelesh Gupta
opal_get_sensor_data_u64(u32 sensor_hndl,u64 * sensor_data)645cdcb01eSShilpasri G Bhat int opal_get_sensor_data_u64(u32 sensor_hndl, u64 *sensor_data)
655cdcb01eSShilpasri G Bhat {
665cdcb01eSShilpasri G Bhat int ret, token;
675cdcb01eSShilpasri G Bhat struct opal_msg msg;
685cdcb01eSShilpasri G Bhat __be64 data;
695cdcb01eSShilpasri G Bhat
705cdcb01eSShilpasri G Bhat if (!opal_check_token(OPAL_SENSOR_READ_U64)) {
715cdcb01eSShilpasri G Bhat u32 sdata;
725cdcb01eSShilpasri G Bhat
735cdcb01eSShilpasri G Bhat ret = opal_get_sensor_data(sensor_hndl, &sdata);
745cdcb01eSShilpasri G Bhat if (!ret)
755cdcb01eSShilpasri G Bhat *sensor_data = sdata;
765cdcb01eSShilpasri G Bhat return ret;
775cdcb01eSShilpasri G Bhat }
785cdcb01eSShilpasri G Bhat
795cdcb01eSShilpasri G Bhat token = opal_async_get_token_interruptible();
805cdcb01eSShilpasri G Bhat if (token < 0)
815cdcb01eSShilpasri G Bhat return token;
825cdcb01eSShilpasri G Bhat
835cdcb01eSShilpasri G Bhat ret = opal_sensor_read_u64(sensor_hndl, token, &data);
845cdcb01eSShilpasri G Bhat switch (ret) {
855cdcb01eSShilpasri G Bhat case OPAL_ASYNC_COMPLETION:
865cdcb01eSShilpasri G Bhat ret = opal_async_wait_response(token, &msg);
875cdcb01eSShilpasri G Bhat if (ret) {
885cdcb01eSShilpasri G Bhat pr_err("%s: Failed to wait for the async response, %d\n",
895cdcb01eSShilpasri G Bhat __func__, ret);
905cdcb01eSShilpasri G Bhat goto out_token;
915cdcb01eSShilpasri G Bhat }
925cdcb01eSShilpasri G Bhat
935cdcb01eSShilpasri G Bhat ret = opal_error_code(opal_get_async_rc(msg));
945cdcb01eSShilpasri G Bhat *sensor_data = be64_to_cpu(data);
955cdcb01eSShilpasri G Bhat break;
965cdcb01eSShilpasri G Bhat
975cdcb01eSShilpasri G Bhat case OPAL_SUCCESS:
985cdcb01eSShilpasri G Bhat ret = 0;
995cdcb01eSShilpasri G Bhat *sensor_data = be64_to_cpu(data);
1005cdcb01eSShilpasri G Bhat break;
1015cdcb01eSShilpasri G Bhat
1025cdcb01eSShilpasri G Bhat case OPAL_WRONG_STATE:
1035cdcb01eSShilpasri G Bhat ret = -EIO;
1045cdcb01eSShilpasri G Bhat break;
1055cdcb01eSShilpasri G Bhat
1065cdcb01eSShilpasri G Bhat default:
1075cdcb01eSShilpasri G Bhat ret = opal_error_code(ret);
1085cdcb01eSShilpasri G Bhat break;
1095cdcb01eSShilpasri G Bhat }
1105cdcb01eSShilpasri G Bhat
1115cdcb01eSShilpasri G Bhat out_token:
1125cdcb01eSShilpasri G Bhat opal_async_release_token(token);
1135cdcb01eSShilpasri G Bhat return ret;
1145cdcb01eSShilpasri G Bhat }
1155cdcb01eSShilpasri G Bhat EXPORT_SYMBOL_GPL(opal_get_sensor_data_u64);
1165cdcb01eSShilpasri G Bhat
opal_sensor_init(void)11796e023e7SAlistair Popple int __init opal_sensor_init(void)
1188de303baSNeelesh Gupta {
1198de303baSNeelesh Gupta struct platform_device *pdev;
1208de303baSNeelesh Gupta struct device_node *sensor;
1218de303baSNeelesh Gupta
1228de303baSNeelesh Gupta sensor = of_find_node_by_path("/ibm,opal/sensors");
1238de303baSNeelesh Gupta if (!sensor) {
1248de303baSNeelesh Gupta pr_err("Opal node 'sensors' not found\n");
1258de303baSNeelesh Gupta return -ENODEV;
1268de303baSNeelesh Gupta }
1278de303baSNeelesh Gupta
1288de303baSNeelesh Gupta pdev = of_platform_device_create(sensor, "opal-sensor", NULL);
1298de303baSNeelesh Gupta of_node_put(sensor);
1308de303baSNeelesh Gupta
1318de303baSNeelesh Gupta return PTR_ERR_OR_ZERO(pdev);
1328de303baSNeelesh Gupta }
133