Blame view

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