Skip to content

Commit 593ced7

Browse files
committed
Attempt at becoming a ssam device driver.
1 parent 3ab20d1 commit 593ced7

File tree

1 file changed

+28
-54
lines changed

1 file changed

+28
-54
lines changed

drivers/platform/surface/surface_fan.c

Lines changed: 28 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
* Copyright (C) 2023 Ivor Wanders <ivor@iwanders.net>
66
*/
77

8-
#include <linux/acpi.h>
98
#include <linux/hwmon.h>
109
#include <linux/kernel.h>
1110
#include <linux/module.h>
@@ -14,9 +13,7 @@
1413
#include <linux/thermal.h>
1514
#include <linux/types.h>
1615

17-
// This is a non-SSAM client driver as per the surface documentation.
18-
// It registers itself as an ACPI driver for PNP0C0B, which requires removing
19-
// the default fan module.
16+
// This is a SSAM client driver as per the surface documentation.
2017
// It both sets up as a cooling device through the thermal cooling device as
2118
// well as a hwmon fan for monitoring.
2219

@@ -29,10 +26,10 @@
2926

3027
struct fan_data {
3128
struct device *dev;
32-
struct ssam_controller *ctrl;
33-
struct acpi_device *acpi_fan;
34-
3529
struct thermal_cooling_device *cdev;
30+
31+
struct ssam_device *sdev;
32+
3633
struct device *hdev;
3734
};
3835

@@ -51,13 +48,6 @@ SSAM_DEFINE_SYNC_REQUEST_R(__ssam_fan_get, __le16, {
5148
.instance_id = 0x01,
5249
});
5350

54-
// ACPI
55-
static const struct acpi_device_id surface_fan_match[] = {
56-
{ "PNP0C0B" },
57-
{},
58-
};
59-
MODULE_DEVICE_TABLE(acpi, surface_fan_match);
60-
6151

6252
// Thermal cooling device
6353
static int surface_fan_set_cur_state(struct thermal_cooling_device *cdev,
@@ -66,7 +56,7 @@ static int surface_fan_set_cur_state(struct thermal_cooling_device *cdev,
6656
__le16 value;
6757
struct fan_data *d = cdev->devdata;
6858
value = cpu_to_le16(clamp(state, 0lu, (1lu << 16)));
69-
return __ssam_fan_set(d->ctrl, &value);
59+
return __ssam_fan_set(d->sdev->ctrl, &value);
7060
}
7161

7262
static int surface_fan_get_cur_state(struct thermal_cooling_device *cdev,
@@ -75,7 +65,7 @@ static int surface_fan_get_cur_state(struct thermal_cooling_device *cdev,
7565
int res;
7666
struct fan_data *d = cdev->devdata;
7767
__le16 value = 0;
78-
res = __ssam_fan_get(d->ctrl, &value);
68+
res = __ssam_fan_get(d->sdev->ctrl, &value);
7969
*state = le16_to_cpu(value);
8070
return res;
8171
}
@@ -121,15 +111,15 @@ static int surface_fan_hwmon_read(struct device *dev,
121111
enum hwmon_sensor_types type,
122112
u32 attr, int channel, long *val)
123113
{
124-
struct fan_data *data = dev_get_drvdata(dev);
114+
struct fan_data *d = dev_get_drvdata(dev);
125115
__le16 value;
126116
int res;
127117

128118
switch (type) {
129119
case hwmon_fan:
130120
switch (attr) {
131121
case hwmon_fan_input:
132-
res = __ssam_fan_get(data->ctrl, &value);
122+
res = __ssam_fan_get(d->sdev->ctrl, &value);
133123
if (res) {
134124
return -1;
135125
}
@@ -161,14 +151,14 @@ static int surface_fan_hwmon_write(struct device *dev,
161151
u32 attr, int channel, long val)
162152
{
163153
__le16 value;
164-
struct fan_data *data = dev_get_drvdata(dev);
154+
struct fan_data *d = dev_get_drvdata(dev);
165155

166156
switch (type) {
167157
case hwmon_fan:
168158
switch (attr) {
169159
case hwmon_fan_target:
170160
value = cpu_to_le16(clamp(val, 0l, (1l << 16)));
171-
return __ssam_fan_set(data->ctrl, &value);
161+
return __ssam_fan_set(d->sdev->ctrl, &value);
172162
default:
173163
break;
174164
}
@@ -200,29 +190,23 @@ static const struct hwmon_chip_info surface_fan_chip_info = {
200190
.info = surface_fan_info,
201191
};
202192

203-
static int surface_fan_probe(struct platform_device *pdev)
193+
static int surface_fan_probe(struct ssam_device *sdev)
204194
{
205-
struct acpi_device *acpi_fan = ACPI_COMPANION(&pdev->dev);
206-
207-
struct ssam_controller *ctrl;
208195
struct fan_data *data;
209196
struct thermal_cooling_device *cdev;
210197
struct device *hdev;
211198
__le16 value;
212199
int status;
213200

214-
ctrl = ssam_client_bind(&pdev->dev);
215-
if (IS_ERR(ctrl))
216-
return PTR_ERR(ctrl) == -ENODEV ? -EPROBE_DEFER : PTR_ERR(ctrl);
217-
201+
printk(KERN_INFO "In probe!");
218202
// Probe the fan to confirm we actually have it by retrieving the
219203
// speed.
220-
status = __ssam_fan_get(ctrl, &value);
204+
status = __ssam_fan_get(sdev->ctrl, &value);
221205
if (status) {
222206
return -ENODEV;
223207
}
224208

225-
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
209+
data = devm_kzalloc(&sdev->dev, sizeof(*data), GFP_KERNEL);
226210
if (!data)
227211
return -ENOMEM;
228212

@@ -232,55 +216,45 @@ static int surface_fan_probe(struct platform_device *pdev)
232216
return PTR_ERR(cdev);
233217

234218

235-
hdev = devm_hwmon_device_register_with_info(&pdev->dev, "fan", data,
219+
hdev = devm_hwmon_device_register_with_info(&sdev->dev, "fan", data,
236220
&surface_fan_chip_info,
237221
NULL);
238222
if (IS_ERR(hdev)) {
239223
return PTR_ERR(hdev);
240224
}
241225

242-
data->dev = &pdev->dev;
243-
data->ctrl = ctrl;
244-
data->acpi_fan = acpi_fan;
245-
226+
data->sdev = sdev;
246227
data->cdev = cdev;
247228
data->hdev = hdev;
248229

249-
acpi_fan->driver_data = data;
250-
platform_set_drvdata(pdev, data);
230+
ssam_device_set_drvdata(sdev, data);
251231

252232
return 0;
253233
}
254234

255-
static int surface_fan_remove(struct platform_device *pdev)
235+
static void surface_fan_remove(struct ssam_device *sdev)
256236
{
257-
struct fan_data *d = platform_get_drvdata(pdev);
237+
struct fan_data *d = ssam_device_get_drvdata(sdev);
258238
thermal_cooling_device_unregister(d->cdev);
259-
return 0;
260239
}
261240

262241

263-
static struct platform_driver surface_fan = {
242+
static const struct ssam_device_id ssam_fan_match[] = {
243+
{ SSAM_SDEV(FAN, SAM, SSAM_SSH_IID_ANY, SSAM_SSH_FUN_ANY) },
244+
{ },
245+
};
246+
MODULE_DEVICE_TABLE(ssam, ssam_fan_match);
247+
248+
static struct ssam_device_driver surface_fan = {
264249
.probe = surface_fan_probe,
265250
.remove = surface_fan_remove,
251+
.match_table = ssam_fan_match,
266252
.driver = {
267253
.name = "surface_fan",
268-
.acpi_match_table = surface_fan_match,
269254
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
270255
},
271256
};
272-
273-
static int __init surface_fan_init(void)
274-
{
275-
return platform_driver_register(&surface_fan);
276-
}
277-
module_init(surface_fan_init);
278-
279-
static void __exit surface_fan_exit(void)
280-
{
281-
platform_driver_unregister(&surface_fan);
282-
}
283-
module_exit(surface_fan_exit);
257+
module_ssam_device_driver(surface_fan);
284258

285259
MODULE_AUTHOR("Ivor Wanders <ivor@iwanders.net>");
286260
MODULE_DESCRIPTION("Fan Driver for Surface System Aggregator Module");

0 commit comments

Comments
 (0)