linux/arch/powerpc/platforms/powernv/opal-sensor.c
<<
>>
Prefs
   1/*
   2 * PowerNV sensor code
   3 *
   4 * Copyright (C) 2013 IBM
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write to the Free Software
  18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19 */
  20
  21#include <linux/delay.h>
  22#include <linux/mutex.h>
  23#include <linux/of_platform.h>
  24#include <asm/opal.h>
  25#include <asm/machdep.h>
  26
  27static DEFINE_MUTEX(opal_sensor_mutex);
  28
  29/*
  30 * This will return sensor information to driver based on the requested sensor
  31 * handle. A handle is an opaque id for the powernv, read by the driver from the
  32 * device tree..
  33 */
  34int opal_get_sensor_data(u32 sensor_hndl, u32 *sensor_data)
  35{
  36        int ret, token;
  37        struct opal_msg msg;
  38        __be32 data;
  39
  40        token = opal_async_get_token_interruptible();
  41        if (token < 0) {
  42                pr_err("%s: Couldn't get the token, returning\n", __func__);
  43                ret = token;
  44                goto out;
  45        }
  46
  47        mutex_lock(&opal_sensor_mutex);
  48        ret = opal_sensor_read(sensor_hndl, token, &data);
  49        switch (ret) {
  50        case OPAL_ASYNC_COMPLETION:
  51                ret = opal_async_wait_response(token, &msg);
  52                if (ret) {
  53                        pr_err("%s: Failed to wait for the async response, %d\n",
  54                               __func__, ret);
  55                        goto out_token;
  56                }
  57
  58                ret = opal_error_code(opal_get_async_rc(msg));
  59                *sensor_data = be32_to_cpu(data);
  60                break;
  61
  62        case OPAL_SUCCESS:
  63                ret = 0;
  64                *sensor_data = be32_to_cpu(data);
  65                break;
  66
  67        case OPAL_WRONG_STATE:
  68                ret = -EIO;
  69                break;
  70
  71        default:
  72                ret = opal_error_code(ret);
  73                break;
  74        }
  75
  76out_token:
  77        mutex_unlock(&opal_sensor_mutex);
  78        opal_async_release_token(token);
  79out:
  80        return ret;
  81}
  82EXPORT_SYMBOL_GPL(opal_get_sensor_data);
  83
  84int __init opal_sensor_init(void)
  85{
  86        struct platform_device *pdev;
  87        struct device_node *sensor;
  88
  89        sensor = of_find_node_by_path("/ibm,opal/sensors");
  90        if (!sensor) {
  91                pr_err("Opal node 'sensors' not found\n");
  92                return -ENODEV;
  93        }
  94
  95        pdev = of_platform_device_create(sensor, "opal-sensor", NULL);
  96        of_node_put(sensor);
  97
  98        return PTR_ERR_OR_ZERO(pdev);
  99}
 100