Skip to content

Commit c48c2ee

Browse files
StollDkitakar5525
authored andcommitted
BACKPORT: ipts: Implement new companion interface
This makes it easier to extend the companion driver, since everything is stored in a single struct. The ipts_companion_t struct is stored in two places, the IPTS main driver, and the driver registering it. It is still passed through to the functions that the companion driver implements to allow for device specific behaviour. Signed-off-by: Dorian Stoll <dorian.stoll@tmsp.io> (cherry-picked from commit a1531a7)
1 parent 7e520ac commit c48c2ee

16 files changed

Lines changed: 216 additions & 204 deletions

File tree

drivers/gpu/drm/i915/intel_ipts.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#include <linux/kernel.h>
2525
#include <linux/types.h>
2626
#include <linux/module.h>
27-
#include <linux/intel_ipts_if.h>
27+
#include <linux/ipts-gfx.h>
2828
#include <drm/drmP.h>
2929

3030
#include "intel_guc_submission.h"

drivers/misc/ipts/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#
55

66
obj-$(CONFIG_INTEL_IPTS)+= intel-ipts.o
7-
intel-ipts-objs += ipts-fw.o
7+
intel-ipts-objs += ipts-companion.o
88
intel-ipts-objs += ipts-mei.o
99
intel-ipts-objs += ipts-hid.o
1010
intel-ipts-objs += ipts-msg-handler.o
Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,38 @@
11
#include <linux/acpi.h>
22
#include <linux/firmware.h>
3-
#include <linux/intel_ipts_fw.h>
4-
#include <linux/intel_ipts_if.h>
3+
#include <linux/ipts.h>
4+
#include <linux/ipts-companion.h>
55
#include <linux/module.h>
66
#include <linux/platform_device.h>
77

88
#define IPTS_SURFACE_FW_PATH_FMT "intel/ipts/%s/%s"
99

10-
#define __IPTS_SURFACE_FIRMWARE(X, Y) \
11-
MODULE_FIRMWARE("intel/ipts/" X "/" Y)
12-
13-
#define IPTS_SURFACE_FIRMWARE(X) \
14-
__IPTS_SURFACE_FIRMWARE(X, "config.bin"); \
15-
__IPTS_SURFACE_FIRMWARE(X, "intel_desc.bin"); \
16-
__IPTS_SURFACE_FIRMWARE(X, "intel_fw_config.bin"); \
17-
__IPTS_SURFACE_FIRMWARE(X, "vendor_desc.bin"); \
18-
__IPTS_SURFACE_FIRMWARE(X, "vendor_kernel.bin")
19-
20-
IPTS_SURFACE_FIRMWARE("MSHW0076");
21-
IPTS_SURFACE_FIRMWARE("MSHW0078");
22-
IPTS_SURFACE_FIRMWARE("MSHW0079");
23-
IPTS_SURFACE_FIRMWARE("MSHW0101");
24-
IPTS_SURFACE_FIRMWARE("MSHW0102");
25-
IPTS_SURFACE_FIRMWARE("MSHW0103");
26-
IPTS_SURFACE_FIRMWARE("MSHW0137");
10+
#define IPTS_SURFACE_FIRMWARE(X) \
11+
MODULE_FIRMWARE("intel/ipts/" X "/config.bin"); \
12+
MODULE_FIRMWARE("intel/ipts/" X "/intel_desc.bin"); \
13+
MODULE_FIRMWARE("intel/ipts/" X "/ipts_fw_config.bin"); \
14+
MODULE_FIRMWARE("intel/ipts/" X "/vendor_desc.bin"); \
15+
MODULE_FIRMWARE("intel/ipts/" X "/vendor_kernel.bin"); \
2716

2817
int ipts_surface_request_firmware(const struct firmware **fw, const char *name,
29-
struct device *device, void *data)
18+
struct device *device, ipts_companion_t *companion)
3019
{
3120
char fw_path[MAX_IOCL_FILE_PATH_LEN];
3221

33-
if (data == NULL) {
22+
if (companion == NULL || companion->data == NULL) {
3423
return -ENOENT;
3524
}
3625

3726
snprintf(fw_path, MAX_IOCL_FILE_PATH_LEN, IPTS_SURFACE_FW_PATH_FMT,
38-
(const char *)data, name);
27+
(const char *)companion->data, name);
3928
return request_firmware(fw, fw_path, device);
4029
}
4130

31+
static ipts_companion_t ipts_surface_companion = {
32+
.firmware_request = &ipts_surface_request_firmware,
33+
.name = "ipts_surface",
34+
};
35+
4236
static int ipts_surface_probe(struct platform_device *pdev)
4337
{
4438
int ret;
@@ -49,11 +43,11 @@ static int ipts_surface_probe(struct platform_device *pdev)
4943
return -ENODEV;
5044
}
5145

52-
ret = intel_ipts_add_fw_handler(&ipts_surface_request_firmware,
53-
(void *)acpi_device_hid(adev));
46+
ipts_surface_companion.data = (void *)acpi_device_hid(adev);
47+
ret = ipts_add_companion(&ipts_surface_companion);
5448
if (ret) {
55-
dev_info(&pdev->dev, "Adding IPTS firmware handler failed, "
56-
"error: %d\n", ret);
49+
dev_info(&pdev->dev, "Adding IPTS companion failed, "
50+
"error: %d\n", ret);
5751
return ret;
5852
}
5953

@@ -62,25 +56,23 @@ static int ipts_surface_probe(struct platform_device *pdev)
6256

6357
static int ipts_surface_remove(struct platform_device *pdev)
6458
{
65-
int ret;
66-
67-
ret = intel_ipts_rm_fw_handler(&ipts_surface_request_firmware);
59+
int ret = ipts_remove_companion(&ipts_surface_companion);
6860
if (ret) {
69-
dev_info(&pdev->dev, "Removing IPTS firmware handler failed, "
70-
"error: %d\n", ret);
61+
dev_info(&pdev->dev, "Removing IPTS companion failed, "
62+
"error: %d\n", ret);
7163
}
7264

7365
return 0;
7466
}
7567

7668
static const struct acpi_device_id ipts_surface_acpi_match[] = {
77-
{ "MSHW0076", 0 }, /* Surface Book 1 / Surface Studio */
78-
{ "MSHW0078", 0 }, /* Surface Pro 4 */
79-
{ "MSHW0079", 0 }, /* Surface Laptop 1 / 2 */
80-
{ "MSHW0101", 0 }, /* Surface Book 2 15" */
81-
{ "MSHW0102", 0 }, /* Surface Pro 2017 / 6 */
82-
{ "MSHW0103", 0 }, /* unknown, but firmware exists */
83-
{ "MSHW0137", 0 }, /* Surface Book 2 */
69+
{ "MSHW0076", 0 }, // Surface Book 1 / Surface Studio
70+
{ "MSHW0078", 0 }, // Surface Pro 4
71+
{ "MSHW0079", 0 }, // Surface Laptop 1 / 2
72+
{ "MSHW0101", 0 }, // Surface Book 2 15"
73+
{ "MSHW0102", 0 }, // Surface Pro 2017 / 6
74+
{ "MSHW0103", 0 }, // unknown, but firmware exists
75+
{ "MSHW0137", 0 }, // Surface Book 2
8476
{ },
8577
};
8678
MODULE_DEVICE_TABLE(acpi, ipts_surface_acpi_match);
@@ -98,3 +90,11 @@ module_platform_driver(ipts_surface_driver);
9890
MODULE_AUTHOR("Dorian Stoll <dorian.stoll@tmsp.io>");
9991
MODULE_DESCRIPTION("IPTS companion driver for Microsoft Surface");
10092
MODULE_LICENSE("GPL v2");
93+
94+
IPTS_SURFACE_FIRMWARE("MSHW0076");
95+
IPTS_SURFACE_FIRMWARE("MSHW0078");
96+
IPTS_SURFACE_FIRMWARE("MSHW0079");
97+
IPTS_SURFACE_FIRMWARE("MSHW0101");
98+
IPTS_SURFACE_FIRMWARE("MSHW0102");
99+
IPTS_SURFACE_FIRMWARE("MSHW0103");
100+
IPTS_SURFACE_FIRMWARE("MSHW0137");

drivers/misc/ipts/ipts-companion.c

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#include <linux/firmware.h>
2+
#include <linux/ipts.h>
3+
#include <linux/ipts-companion.h>
4+
#include <linux/mutex.h>
5+
6+
#include "ipts.h"
7+
#include "ipts-companion.h"
8+
#include "ipts-params.h"
9+
10+
#define IPTS_FW_PATH_FMT "intel/ipts/%s"
11+
12+
ipts_companion_t *ipts_companion;
13+
DEFINE_MUTEX(ipts_companion_lock);
14+
15+
bool ipts_companion_available(void)
16+
{
17+
bool ret;
18+
mutex_lock(&ipts_companion_lock);
19+
20+
ret = ipts_companion != NULL;
21+
22+
mutex_unlock(&ipts_companion_lock);
23+
return ret;
24+
}
25+
26+
/*
27+
* General purpose API for adding or removing a companion driver
28+
* A companion driver is a driver that implements hardware specific
29+
* behaviour into IPTS, so it doesn't have to be hardcoded into the
30+
* main driver. All requests to the companion driver should be wrapped,
31+
* with a fallback in case a companion driver cannot be found.
32+
*/
33+
34+
int ipts_add_companion(ipts_companion_t *companion)
35+
{
36+
int ret = 0;
37+
mutex_lock(&ipts_companion_lock);
38+
39+
if (ipts_companion != NULL) {
40+
ret = -EBUSY;
41+
goto add_companion_return;
42+
}
43+
44+
ipts_companion = companion;
45+
46+
add_companion_return:
47+
48+
mutex_unlock(&ipts_companion_lock);
49+
return ret;
50+
}
51+
EXPORT_SYMBOL_GPL(ipts_add_companion);
52+
53+
int ipts_remove_companion(ipts_companion_t *companion)
54+
{
55+
int ret = 0;
56+
mutex_lock(&ipts_companion_lock);
57+
58+
if (ipts_companion == NULL || companion == NULL) {
59+
ret = 0;
60+
goto remove_companion_return;
61+
}
62+
63+
if (ipts_companion->name != companion->name) {
64+
ret = -EPERM;
65+
goto remove_companion_return;
66+
}
67+
68+
ipts_companion = NULL;
69+
70+
remove_companion_return:
71+
72+
mutex_unlock(&ipts_companion_lock);
73+
return ret;
74+
}
75+
EXPORT_SYMBOL_GPL(ipts_remove_companion);
76+
77+
/*
78+
* Utility functions for IPTS. These functions replace codepaths in the IPTS
79+
* driver, and redirect them to the companion driver, if one was found.
80+
* Otherwise the legacy code gets executed as a fallback.
81+
*/
82+
83+
int ipts_request_firmware(const struct firmware **fw, const char *name,
84+
struct device *device)
85+
{
86+
int ret = 0;
87+
char fw_path[MAX_IOCL_FILE_PATH_LEN];
88+
mutex_lock(&ipts_companion_lock);
89+
90+
// Check if a companion was registered. If not, skip
91+
// forward and try to load the firmware from the legacy path
92+
if (ipts_companion == NULL || ipts_modparams.ignore_companion) {
93+
goto request_firmware_fallback;
94+
}
95+
96+
ret = ipts_companion->firmware_request(fw, name, device, ipts_companion);
97+
if (!ret) {
98+
goto request_firmware_return;
99+
}
100+
101+
request_firmware_fallback:
102+
103+
// If fallback loading for firmware was disabled, abort.
104+
// Return -ENOENT as no firmware file was found.
105+
if (ipts_modparams.ignore_fw_fallback) {
106+
ret = -ENOENT;
107+
goto request_firmware_return;
108+
}
109+
110+
// No firmware was found by the companion driver, try the generic path.
111+
snprintf(fw_path, MAX_IOCL_FILE_PATH_LEN, IPTS_FW_PATH_FMT, name);
112+
ret = request_firmware(fw, fw_path, device);
113+
114+
request_firmware_return:
115+
116+
mutex_unlock(&ipts_companion_lock);
117+
return ret;
118+
}

drivers/misc/ipts/ipts-companion.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef _IPTS_COMPANION_H_
2+
#define _IPTS_COMPANION_H_
3+
4+
#include <linux/firmware.h>
5+
6+
bool ipts_companion_available(void);
7+
int ipts_request_firmware(const struct firmware **fw, const char *name,
8+
struct device *device);
9+
10+
#endif // _IPTS_COMPANION_H_

drivers/misc/ipts/ipts-fw.c

Lines changed: 0 additions & 113 deletions
This file was deleted.

drivers/misc/ipts/ipts-fw.h

Lines changed: 0 additions & 12 deletions
This file was deleted.

0 commit comments

Comments
 (0)