1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
31
32
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