1
1
/* SPDX-License-Identifier: GPL-2.0 */
2
2
/* Copyright (c) 2024 Intel Corporation */
3
3
4
+ #include <linux/acpi.h>
5
+ #include <linux/bitfield.h>
4
6
#include <linux/device.h>
5
7
#include <linux/dma-mapping.h>
6
8
#include <linux/err.h>
9
11
#include <linux/pci.h>
10
12
11
13
#include "intel-thc-dev.h"
14
+ #include "intel-thc-hw.h"
12
15
13
16
#include "quickspi-dev.h"
14
17
@@ -24,6 +27,186 @@ struct quickspi_driver_data ptl = {
24
27
.max_packet_size_value = MAX_PACKET_SIZE_VALUE_LNL ,
25
28
};
26
29
30
+ /* THC QuickSPI ACPI method to get device properties */
31
+ /* HIDSPI Method: {6e2ac436-0fcf-41af-a265-b32a220dcfab} */
32
+ static guid_t hidspi_guid =
33
+ GUID_INIT (0x6e2ac436 , 0x0fcf , 0x41af , 0xa2 , 0x65 , 0xb3 , 0x2a ,
34
+ 0x22 , 0x0d , 0xcf , 0xab );
35
+
36
+ /* QuickSpi Method: {300D35b7-ac20-413e-8e9c-92e4dafd0afe} */
37
+ static guid_t thc_quickspi_guid =
38
+ GUID_INIT (0x300d35b7 , 0xac20 , 0x413e , 0x8e , 0x9c , 0x92 , 0xe4 ,
39
+ 0xda , 0xfd , 0x0a , 0xfe );
40
+
41
+ /* Platform Method: {84005682-5b71-41a4-0x8d668130f787a138} */
42
+ static guid_t thc_platform_guid =
43
+ GUID_INIT (0x84005682 , 0x5b71 , 0x41a4 , 0x8d , 0x66 , 0x81 , 0x30 ,
44
+ 0xf7 , 0x87 , 0xa1 , 0x38 );
45
+
46
+ /**
47
+ * thc_acpi_get_property - Query device ACPI parameter
48
+ *
49
+ * @adev: point to ACPI device
50
+ * @guid: ACPI method's guid
51
+ * @rev: ACPI method's revision
52
+ * @func: ACPI method's function number
53
+ * @type: ACPI parameter's data type
54
+ * @prop_buf: point to return buffer
55
+ *
56
+ * This is a helper function for device to query its ACPI parameters.
57
+ *
58
+ * Return: 0 if successful or ENODEV on failed.
59
+ */
60
+ static int thc_acpi_get_property (struct acpi_device * adev , const guid_t * guid ,
61
+ u64 rev , u64 func , acpi_object_type type , void * prop_buf )
62
+ {
63
+ acpi_handle handle = acpi_device_handle (adev );
64
+ union acpi_object * obj ;
65
+
66
+ obj = acpi_evaluate_dsm_typed (handle , guid , rev , func , NULL , type );
67
+ if (!obj ) {
68
+ acpi_handle_err (handle ,
69
+ "Error _DSM call failed, rev: %llu, func: %llu, type: %u\n" ,
70
+ rev , func , type );
71
+ return - ENODEV ;
72
+ }
73
+
74
+ if (type == ACPI_TYPE_INTEGER )
75
+ * (u32 * )prop_buf = (u32 )obj -> integer .value ;
76
+ else if (type == ACPI_TYPE_BUFFER )
77
+ memcpy (prop_buf , obj -> buffer .pointer , obj -> buffer .length );
78
+
79
+ ACPI_FREE (obj );
80
+
81
+ return 0 ;
82
+ }
83
+
84
+ /**
85
+ * quickspi_get_acpi_resources - Query all quickspi devices' ACPI parameters
86
+ *
87
+ * @qsdev: point to quickspi device
88
+ *
89
+ * This function gets all quickspi devices' ACPI resource.
90
+ *
91
+ * Return: 0 if successful or error code on failed.
92
+ */
93
+ static int quickspi_get_acpi_resources (struct quickspi_device * qsdev )
94
+ {
95
+ struct acpi_device * adev = ACPI_COMPANION (qsdev -> dev );
96
+ int ret = - EINVAL ;
97
+
98
+ if (!adev ) {
99
+ dev_err (qsdev -> dev , "no valid ACPI companion\n" );
100
+ return ret ;
101
+ }
102
+
103
+ qsdev -> acpi_dev = adev ;
104
+
105
+ ret = thc_acpi_get_property (adev , & hidspi_guid ,
106
+ ACPI_QUICKSPI_REVISION_NUM ,
107
+ ACPI_QUICKSPI_FUNC_NUM_INPUT_REP_HDR_ADDR ,
108
+ ACPI_TYPE_INTEGER ,
109
+ & qsdev -> input_report_hdr_addr );
110
+ if (ret )
111
+ return ret ;
112
+
113
+ ret = thc_acpi_get_property (adev , & hidspi_guid ,
114
+ ACPI_QUICKSPI_REVISION_NUM ,
115
+ ACPI_QUICKSPI_FUNC_NUM_INPUT_REP_BDY_ADDR ,
116
+ ACPI_TYPE_INTEGER ,
117
+ & qsdev -> input_report_bdy_addr );
118
+ if (ret )
119
+ return ret ;
120
+
121
+ ret = thc_acpi_get_property (adev , & hidspi_guid ,
122
+ ACPI_QUICKSPI_REVISION_NUM ,
123
+ ACPI_QUICKSPI_FUNC_NUM_OUTPUT_REP_ADDR ,
124
+ ACPI_TYPE_INTEGER ,
125
+ & qsdev -> output_report_addr );
126
+ if (ret )
127
+ return ret ;
128
+
129
+ ret = thc_acpi_get_property (adev , & hidspi_guid ,
130
+ ACPI_QUICKSPI_REVISION_NUM ,
131
+ ACPI_QUICKSPI_FUNC_NUM_READ_OPCODE ,
132
+ ACPI_TYPE_BUFFER ,
133
+ & qsdev -> spi_read_opcode );
134
+ if (ret )
135
+ return ret ;
136
+
137
+ ret = thc_acpi_get_property (adev , & hidspi_guid ,
138
+ ACPI_QUICKSPI_REVISION_NUM ,
139
+ ACPI_QUICKSPI_FUNC_NUM_WRITE_OPCODE ,
140
+ ACPI_TYPE_BUFFER ,
141
+ & qsdev -> spi_write_opcode );
142
+ if (ret )
143
+ return ret ;
144
+
145
+ ret = thc_acpi_get_property (adev , & hidspi_guid ,
146
+ ACPI_QUICKSPI_REVISION_NUM ,
147
+ ACPI_QUICKSPI_FUNC_NUM_IO_MODE ,
148
+ ACPI_TYPE_INTEGER ,
149
+ & qsdev -> spi_read_io_mode );
150
+ if (ret )
151
+ return ret ;
152
+
153
+ if (qsdev -> spi_read_io_mode & SPI_WRITE_IO_MODE )
154
+ qsdev -> spi_write_io_mode = FIELD_GET (SPI_IO_MODE_OPCODE , qsdev -> spi_read_io_mode );
155
+ else
156
+ qsdev -> spi_write_io_mode = THC_SINGLE_IO ;
157
+
158
+ qsdev -> spi_read_io_mode = FIELD_GET (SPI_IO_MODE_OPCODE , qsdev -> spi_read_io_mode );
159
+
160
+ ret = thc_acpi_get_property (adev , & thc_quickspi_guid ,
161
+ ACPI_QUICKSPI_REVISION_NUM ,
162
+ ACPI_QUICKSPI_FUNC_NUM_CONNECTION_SPEED ,
163
+ ACPI_TYPE_INTEGER ,
164
+ & qsdev -> spi_freq_val );
165
+ if (ret )
166
+ return ret ;
167
+
168
+ ret = thc_acpi_get_property (adev , & thc_quickspi_guid ,
169
+ ACPI_QUICKSPI_REVISION_NUM ,
170
+ ACPI_QUICKSPI_FUNC_NUM_LIMIT_PACKET_SIZE ,
171
+ ACPI_TYPE_INTEGER ,
172
+ & qsdev -> limit_packet_size );
173
+ if (ret )
174
+ return ret ;
175
+
176
+ if (qsdev -> limit_packet_size || !qsdev -> driver_data )
177
+ qsdev -> spi_packet_size = DEFAULT_MIN_PACKET_SIZE_VALUE ;
178
+ else
179
+ qsdev -> spi_packet_size = qsdev -> driver_data -> max_packet_size_value ;
180
+
181
+ ret = thc_acpi_get_property (adev , & thc_quickspi_guid ,
182
+ ACPI_QUICKSPI_REVISION_NUM ,
183
+ ACPI_QUICKSPI_FUNC_NUM_PERFORMANCE_LIMIT ,
184
+ ACPI_TYPE_INTEGER ,
185
+ & qsdev -> performance_limit );
186
+ if (ret )
187
+ return ret ;
188
+
189
+ qsdev -> performance_limit = FIELD_GET (PERFORMANCE_LIMITATION , qsdev -> performance_limit );
190
+
191
+ ret = thc_acpi_get_property (adev , & thc_platform_guid ,
192
+ ACPI_QUICKSPI_REVISION_NUM ,
193
+ ACPI_QUICKSPI_FUNC_NUM_ACTIVE_LTR ,
194
+ ACPI_TYPE_INTEGER ,
195
+ & qsdev -> active_ltr_val );
196
+ if (ret )
197
+ return ret ;
198
+
199
+ ret = thc_acpi_get_property (adev , & thc_platform_guid ,
200
+ ACPI_QUICKSPI_REVISION_NUM ,
201
+ ACPI_QUICKSPI_FUNC_NUM_LP_LTR ,
202
+ ACPI_TYPE_INTEGER ,
203
+ & qsdev -> low_power_ltr_val );
204
+ if (ret )
205
+ return ret ;
206
+
207
+ return 0 ;
208
+ }
209
+
27
210
/**
28
211
* quickspi_irq_quick_handler - The ISR of the quickspi driver
29
212
*
@@ -113,6 +296,12 @@ static struct quickspi_device *quickspi_dev_init(struct pci_dev *pdev, void __io
113
296
return ERR_PTR (ret );
114
297
}
115
298
299
+ ret = quickspi_get_acpi_resources (qsdev );
300
+ if (ret ) {
301
+ dev_err (dev , "Get ACPI resources failed, ret = %d\n" , ret );
302
+ return ERR_PTR (ret );
303
+ }
304
+
116
305
thc_interrupt_config (qsdev -> thc_hw );
117
306
118
307
thc_interrupt_enable (qsdev -> thc_hw , true);
0 commit comments