11/* SPDX-License-Identifier: GPL-2.0 */
22/* Copyright (c) 2024 Intel Corporation */
33
4+ #include <linux/acpi.h>
5+ #include <linux/bitfield.h>
46#include <linux/device.h>
57#include <linux/dma-mapping.h>
68#include <linux/err.h>
911#include <linux/pci.h>
1012
1113#include "intel-thc-dev.h"
14+ #include "intel-thc-hw.h"
1215
1316#include "quickspi-dev.h"
1417
@@ -24,6 +27,186 @@ struct quickspi_driver_data ptl = {
2427 .max_packet_size_value = MAX_PACKET_SIZE_VALUE_LNL ,
2528};
2629
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+
27210/**
28211 * quickspi_irq_quick_handler - The ISR of the quickspi driver
29212 *
@@ -113,6 +296,12 @@ static struct quickspi_device *quickspi_dev_init(struct pci_dev *pdev, void __io
113296 return ERR_PTR (ret );
114297 }
115298
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+
116305 thc_interrupt_config (qsdev -> thc_hw );
117306
118307 thc_interrupt_enable (qsdev -> thc_hw , true);
0 commit comments