cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

opal-sensor.c (2592B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * PowerNV sensor code
      4 *
      5 * Copyright (C) 2013 IBM
      6 */
      7
      8#include <linux/delay.h>
      9#include <linux/of_platform.h>
     10#include <asm/opal.h>
     11#include <asm/machdep.h>
     12
     13/*
     14 * This will return sensor information to driver based on the requested sensor
     15 * handle. A handle is an opaque id for the powernv, read by the driver from the
     16 * device tree..
     17 */
     18int opal_get_sensor_data(u32 sensor_hndl, u32 *sensor_data)
     19{
     20	int ret, token;
     21	struct opal_msg msg;
     22	__be32 data;
     23
     24	token = opal_async_get_token_interruptible();
     25	if (token < 0)
     26		return token;
     27
     28	ret = opal_sensor_read(sensor_hndl, token, &data);
     29	switch (ret) {
     30	case OPAL_ASYNC_COMPLETION:
     31		ret = opal_async_wait_response(token, &msg);
     32		if (ret) {
     33			pr_err("%s: Failed to wait for the async response, %d\n",
     34			       __func__, ret);
     35			goto out;
     36		}
     37
     38		ret = opal_error_code(opal_get_async_rc(msg));
     39		*sensor_data = be32_to_cpu(data);
     40		break;
     41
     42	case OPAL_SUCCESS:
     43		ret = 0;
     44		*sensor_data = be32_to_cpu(data);
     45		break;
     46
     47	case OPAL_WRONG_STATE:
     48		ret = -EIO;
     49		break;
     50
     51	default:
     52		ret = opal_error_code(ret);
     53		break;
     54	}
     55
     56out:
     57	opal_async_release_token(token);
     58	return ret;
     59}
     60EXPORT_SYMBOL_GPL(opal_get_sensor_data);
     61
     62int opal_get_sensor_data_u64(u32 sensor_hndl, u64 *sensor_data)
     63{
     64	int ret, token;
     65	struct opal_msg msg;
     66	__be64 data;
     67
     68	if (!opal_check_token(OPAL_SENSOR_READ_U64)) {
     69		u32 sdata;
     70
     71		ret = opal_get_sensor_data(sensor_hndl, &sdata);
     72		if (!ret)
     73			*sensor_data = sdata;
     74		return ret;
     75	}
     76
     77	token = opal_async_get_token_interruptible();
     78	if (token < 0)
     79		return token;
     80
     81	ret = opal_sensor_read_u64(sensor_hndl, token, &data);
     82	switch (ret) {
     83	case OPAL_ASYNC_COMPLETION:
     84		ret = opal_async_wait_response(token, &msg);
     85		if (ret) {
     86			pr_err("%s: Failed to wait for the async response, %d\n",
     87			       __func__, ret);
     88			goto out_token;
     89		}
     90
     91		ret = opal_error_code(opal_get_async_rc(msg));
     92		*sensor_data = be64_to_cpu(data);
     93		break;
     94
     95	case OPAL_SUCCESS:
     96		ret = 0;
     97		*sensor_data = be64_to_cpu(data);
     98		break;
     99
    100	case OPAL_WRONG_STATE:
    101		ret = -EIO;
    102		break;
    103
    104	default:
    105		ret = opal_error_code(ret);
    106		break;
    107	}
    108
    109out_token:
    110	opal_async_release_token(token);
    111	return ret;
    112}
    113EXPORT_SYMBOL_GPL(opal_get_sensor_data_u64);
    114
    115int __init opal_sensor_init(void)
    116{
    117	struct platform_device *pdev;
    118	struct device_node *sensor;
    119
    120	sensor = of_find_node_by_path("/ibm,opal/sensors");
    121	if (!sensor) {
    122		pr_err("Opal node 'sensors' not found\n");
    123		return -ENODEV;
    124	}
    125
    126	pdev = of_platform_device_create(sensor, "opal-sensor", NULL);
    127	of_node_put(sensor);
    128
    129	return PTR_ERR_OR_ZERO(pdev);
    130}