FILE
pci-quickspi.c
File preview with syntax highlighting.
linux-6.19.14/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
1/* SPDX-License-Identifier: GPL-2.0 */ 2/* Copyright (c) 2024 Intel Corporation */ 3 4#include <linux/acpi.h> 5#include <linux/bitfield.h> 6#include <linux/device.h> 7#include <linux/dma-mapping.h> 8#include <linux/err.h> 9#include <linux/interrupt.h> 10#include <linux/irqreturn.h> 11#include <linux/pci.h> 12#include <linux/pm_runtime.h> 13 14#include <linux/gpio/consumer.h> 15 16#include "intel-thc-dev.h" 17#include "intel-thc-hw.h" 18#include "intel-thc-wot.h" 19 20#include "quickspi-dev.h" 21#include "quickspi-hid.h" 22#include "quickspi-protocol.h" 23 24struct quickspi_driver_data mtl = { 25 .max_packet_size_value = MAX_PACKET_SIZE_VALUE_MTL, 26}; 27 28struct quickspi_driver_data lnl = { 29 .max_packet_size_value = MAX_PACKET_SIZE_VALUE_LNL, 30}; 31 32struct quickspi_driver_data ptl = { 33 .max_packet_size_value = MAX_PACKET_SIZE_VALUE_LNL, 34}; 35 36struct quickspi_driver_data arl = { 37 .max_packet_size_value = MAX_PACKET_SIZE_VALUE_MTL, 38}; 39 40struct quickspi_driver_data nvl = { 41 .max_packet_size_value = MAX_PACKET_SIZE_VALUE_LNL, 42}; 43 44/* THC QuickSPI ACPI method to get device properties */ 45/* HIDSPI Method: {6e2ac436-0fcf-41af-a265-b32a220dcfab} */ 46static guid_t hidspi_guid = 47 GUID_INIT(0x6e2ac436, 0x0fcf, 0x41af, 0xa2, 0x65, 0xb3, 0x2a, 48 0x22, 0x0d, 0xcf, 0xab); 49 50/* QuickSpi Method: {300D35b7-ac20-413e-8e9c-92e4dafd0afe} */ 51static guid_t thc_quickspi_guid = 52 GUID_INIT(0x300d35b7, 0xac20, 0x413e, 0x8e, 0x9c, 0x92, 0xe4, 53 0xda, 0xfd, 0x0a, 0xfe); 54 55/* Platform Method: {84005682-5b71-41a4-0x8d668130f787a138} */ 56static guid_t thc_platform_guid = 57 GUID_INIT(0x84005682, 0x5b71, 0x41a4, 0x8d, 0x66, 0x81, 0x30, 58 0xf7, 0x87, 0xa1, 0x38); 59 60 61/* QuickSPI Wake-on-Touch GPIO resource */ 62static const struct acpi_gpio_params wake_gpio = { 0, 0, true }; 63 64static const struct acpi_gpio_mapping quickspi_gpios[] = { 65 { "wake-on-touch", &wake_gpio, 1 }, 66 { } 67}; 68 69/** 70 * thc_acpi_get_property - Query device ACPI parameter 71 * 72 * @adev: point to ACPI device 73 * @guid: ACPI method's guid 74 * @rev: ACPI method's revision 75 * @func: ACPI method's function number 76 * @type: ACPI parameter's data type 77 * @prop_buf: point to return buffer 78 * 79 * This is a helper function for device to query its ACPI parameters. 80 * 81 * Return: 0 if successful or ENODEV on failed. 82 */ 83static int thc_acpi_get_property(struct acpi_device *adev, const guid_t *guid, 84 u64 rev, u64 func, acpi_object_type type, void *prop_buf) 85{ 86 acpi_handle handle = acpi_device_handle(adev); 87 union acpi_object *obj; 88 89 obj = acpi_evaluate_dsm_typed(handle, guid, rev, func, NULL, type); 90 if (!obj) { 91 acpi_handle_err(handle, 92 "Error _DSM call failed, rev: %llu, func: %llu, type: %u\n", 93 rev, func, type); 94 return -ENODEV; 95 } 96 97 if (type == ACPI_TYPE_INTEGER) 98 *(u32 *)prop_buf = (u32)obj->integer.value; 99 else if (type == ACPI_TYPE_BUFFER) 100 memcpy(prop_buf, obj->buffer.pointer, obj->buffer.length); 101 102 ACPI_FREE(obj); 103 104 return 0; 105} 106 107/** 108 * quickspi_get_acpi_resources - Query all quickspi devices' ACPI parameters 109 * 110 * @qsdev: point to quickspi device 111 * 112 * This function gets all quickspi devices' ACPI resource. 113 * 114 * Return: 0 if successful or error code on failed. 115 */ 116static int quickspi_get_acpi_resources(struct quickspi_device *qsdev) 117{ 118 struct acpi_device *adev = ACPI_COMPANION(qsdev->dev); 119 int ret = -EINVAL; 120 121 if (!adev) { 122 dev_err(qsdev->dev, "no valid ACPI companion\n"); 123 return ret; 124 } 125 126 qsdev->acpi_dev = adev; 127 128 ret = thc_acpi_get_property(adev, &hidspi_guid, 129 ACPI_QUICKSPI_REVISION_NUM, 130 ACPI_QUICKSPI_FUNC_NUM_INPUT_REP_HDR_ADDR, 131 ACPI_TYPE_INTEGER, 132 &qsdev->input_report_hdr_addr); 133 if (ret) 134 return ret; 135 136 ret = thc_acpi_get_property(adev, &hidspi_guid, 137 ACPI_QUICKSPI_REVISION_NUM, 138 ACPI_QUICKSPI_FUNC_NUM_INPUT_REP_BDY_ADDR, 139 ACPI_TYPE_INTEGER, 140 &qsdev->input_report_bdy_addr); 141 if (ret) 142 return ret; 143 144 ret = thc_acpi_get_property(adev, &hidspi_guid, 145 ACPI_QUICKSPI_REVISION_NUM, 146 ACPI_QUICKSPI_FUNC_NUM_OUTPUT_REP_ADDR, 147 ACPI_TYPE_INTEGER, 148 &qsdev->output_report_addr); 149 if (ret) 150 return ret; 151 152 ret = thc_acpi_get_property(adev, &hidspi_guid, 153 ACPI_QUICKSPI_REVISION_NUM, 154 ACPI_QUICKSPI_FUNC_NUM_READ_OPCODE, 155 ACPI_TYPE_BUFFER, 156 &qsdev->spi_read_opcode); 157 if (ret) 158 return ret; 159 160 ret = thc_acpi_get_property(adev, &hidspi_guid, 161 ACPI_QUICKSPI_REVISION_NUM, 162 ACPI_QUICKSPI_FUNC_NUM_WRITE_OPCODE, 163 ACPI_TYPE_BUFFER, 164 &qsdev->spi_write_opcode); 165 if (ret) 166 return ret; 167 168 ret = thc_acpi_get_property(adev, &hidspi_guid, 169 ACPI_QUICKSPI_REVISION_NUM, 170 ACPI_QUICKSPI_FUNC_NUM_IO_MODE, 171 ACPI_TYPE_INTEGER, 172 &qsdev->spi_read_io_mode); 173 if (ret) 174 return ret; 175 176 if (qsdev->spi_read_io_mode & SPI_WRITE_IO_MODE) 177 qsdev->spi_write_io_mode = FIELD_GET(SPI_IO_MODE_OPCODE, qsdev->spi_read_io_mode); 178 else 179 qsdev->spi_write_io_mode = THC_SINGLE_IO; 180 181 qsdev->spi_read_io_mode = FIELD_GET(SPI_IO_MODE_OPCODE, qsdev->spi_read_io_mode); 182 183 ret = thc_acpi_get_property(adev, &thc_quickspi_guid, 184 ACPI_QUICKSPI_REVISION_NUM, 185 ACPI_QUICKSPI_FUNC_NUM_CONNECTION_SPEED, 186 ACPI_TYPE_INTEGER, 187 &qsdev->spi_freq_val); 188 if (ret) 189 return ret; 190 191 ret = thc_acpi_get_property(adev, &thc_quickspi_guid, 192 ACPI_QUICKSPI_REVISION_NUM, 193 ACPI_QUICKSPI_FUNC_NUM_LIMIT_PACKET_SIZE, 194 ACPI_TYPE_INTEGER, 195 &qsdev->limit_packet_size); 196 if (ret) 197 return ret; 198 199 if (qsdev->limit_packet_size || !qsdev->driver_data) 200 qsdev->spi_packet_size = DEFAULT_MIN_PACKET_SIZE_VALUE; 201 else 202 qsdev->spi_packet_size = qsdev->driver_data->max_packet_size_value; 203 204 ret = thc_acpi_get_property(adev, &thc_quickspi_guid, 205 ACPI_QUICKSPI_REVISION_NUM, 206 ACPI_QUICKSPI_FUNC_NUM_PERFORMANCE_LIMIT, 207 ACPI_TYPE_INTEGER, 208 &qsdev->performance_limit); 209 if (ret) 210 return ret; 211 212 qsdev->performance_limit = FIELD_GET(PERFORMANCE_LIMITATION, qsdev->performance_limit); 213 214 ret = thc_acpi_get_property(adev, &thc_platform_guid, 215 ACPI_QUICKSPI_REVISION_NUM, 216 ACPI_QUICKSPI_FUNC_NUM_ACTIVE_LTR, 217 ACPI_TYPE_INTEGER, 218 &qsdev->active_ltr_val); 219 if (ret) 220 return ret; 221 222 ret = thc_acpi_get_property(adev, &thc_platform_guid, 223 ACPI_QUICKSPI_REVISION_NUM, 224 ACPI_QUICKSPI_FUNC_NUM_LP_LTR, 225 ACPI_TYPE_INTEGER, 226 &qsdev->low_power_ltr_val); 227 if (ret) 228 return ret; 229 230 return 0; 231} 232 233/** 234 * quickspi_irq_quick_handler - The ISR of the quickspi driver 235 * 236 * @irq: The irq number 237 * @dev_id: pointer to the device structure 238 * 239 * Return: IRQ_WAKE_THREAD if further process needed. 240 */ 241static irqreturn_t quickspi_irq_quick_handler(int irq, void *dev_id) 242{ 243 struct quickspi_device *qsdev = dev_id; 244 245 if (qsdev->state == QUICKSPI_DISABLED) 246 return IRQ_HANDLED; 247 248 /* Disable THC interrupt before current interrupt be handled */ 249 thc_interrupt_enable(qsdev->thc_hw, false); 250 251 return IRQ_WAKE_THREAD; 252} 253 254/** 255 * try_recover - Try to recovery THC and Device 256 * @qsdev: pointer to quickspi device 257 * 258 * This function is a error handler, called when fatal error happens. 259 * It try to reset Touch Device and re-configure THC to recovery 260 * transferring between Device and THC. 261 * 262 * Return: 0 if successful or error code on failed. 263 */ 264static int try_recover(struct quickspi_device *qsdev) 265{ 266 int ret; 267 268 ret = reset_tic(qsdev); 269 if (ret) { 270 dev_err(qsdev->dev, "Reset touch device failed, ret = %d\n", ret); 271 return ret; 272 } 273 274 thc_dma_unconfigure(qsdev->thc_hw); 275 276 ret = thc_dma_configure(qsdev->thc_hw); 277 if (ret) { 278 dev_err(qsdev->dev, "Re-configure THC DMA failed, ret = %d\n", ret); 279 return ret; 280 } 281 282 return 0; 283} 284 285/** 286 * quickspi_irq_thread_handler - IRQ thread handler of quickspi driver 287 * 288 * @irq: The IRQ number 289 * @dev_id: pointer to the quickspi device structure 290 * 291 * Return: IRQ_HANDLED to finish this handler. 292 */ 293static irqreturn_t quickspi_irq_thread_handler(int irq, void *dev_id) 294{ 295 struct quickspi_device *qsdev = dev_id; 296 size_t input_len; 297 int read_finished = 0; 298 int err_recover = 0; 299 int int_mask; 300 int ret; 301 302 if (qsdev->state == QUICKSPI_DISABLED) 303 return IRQ_HANDLED; 304 305 ret = pm_runtime_resume_and_get(qsdev->dev); 306 if (ret) 307 return IRQ_HANDLED; 308 309 int_mask = thc_interrupt_handler(qsdev->thc_hw); 310 311 if (int_mask & BIT(THC_FATAL_ERR_INT) || int_mask & BIT(THC_TXN_ERR_INT)) { 312 err_recover = 1; 313 goto end; 314 } 315 316 if (int_mask & BIT(THC_NONDMA_INT)) { 317 if (qsdev->state == QUICKSPI_RESETING) { 318 qsdev->reset_ack = true; 319 wake_up_interruptible(&qsdev->reset_ack_wq); 320 } else { 321 qsdev->nondma_int_received = true; 322 wake_up_interruptible(&qsdev->nondma_int_received_wq); 323 } 324 } 325 326 if (int_mask & BIT(THC_RXDMA2_INT)) { 327 while (!read_finished) { 328 ret = thc_rxdma_read(qsdev->thc_hw, THC_RXDMA2, qsdev->input_buf, 329 &input_len, &read_finished); 330 if (ret) { 331 err_recover = 1; 332 goto end; 333 } 334 335 quickspi_handle_input_data(qsdev, input_len); 336 } 337 } 338 339end: 340 thc_interrupt_enable(qsdev->thc_hw, true); 341 342 if (err_recover) 343 if (try_recover(qsdev)) 344 qsdev->state = QUICKSPI_DISABLED; 345 346 pm_runtime_put_autosuspend(qsdev->dev); 347 348 return IRQ_HANDLED; 349} 350 351/** 352 * quickspi_dev_init - Initialize quickspi device 353 * 354 * @pdev: pointer to the thc pci device 355 * @mem_addr: The pointer of MMIO memory address 356 * @id: point to pci_device_id structure 357 * 358 * Alloc quickspi device structure and initialized THC device, 359 * then configure THC to HIDSPI mode. 360 * 361 * If success, enable THC hardware interrupt. 362 * 363 * Return: pointer to the quickspi device structure if success 364 * or NULL on failed. 365 */ 366static struct quickspi_device *quickspi_dev_init(struct pci_dev *pdev, void __iomem *mem_addr, 367 const struct pci_device_id *id) 368{ 369 struct device *dev = &pdev->dev; 370 struct quickspi_device *qsdev; 371 int ret; 372 373 qsdev = devm_kzalloc(dev, sizeof(struct quickspi_device), GFP_KERNEL); 374 if (!qsdev) 375 return ERR_PTR(-ENOMEM); 376 377 qsdev->pdev = pdev; 378 qsdev->dev = dev; 379 qsdev->mem_addr = mem_addr; 380 qsdev->state = QUICKSPI_DISABLED; 381 qsdev->driver_data = (struct quickspi_driver_data *)id->driver_data; 382 383 init_waitqueue_head(&qsdev->reset_ack_wq); 384 init_waitqueue_head(&qsdev->nondma_int_received_wq); 385 init_waitqueue_head(&qsdev->report_desc_got_wq); 386 init_waitqueue_head(&qsdev->get_report_cmpl_wq); 387 init_waitqueue_head(&qsdev->set_report_cmpl_wq); 388 389 /* thc hw init */ 390 qsdev->thc_hw = thc_dev_init(qsdev->dev, qsdev->mem_addr); 391 if (IS_ERR(qsdev->thc_hw)) { 392 ret = PTR_ERR(qsdev->thc_hw); 393 dev_err(dev, "Failed to initialize THC device context, ret = %d.\n", ret); 394 return ERR_PTR(ret); 395 } 396 397 ret = thc_interrupt_quiesce(qsdev->thc_hw, true); 398 if (ret) 399 return ERR_PTR(ret); 400 401 ret = thc_port_select(qsdev->thc_hw, THC_PORT_TYPE_SPI); 402 if (ret) { 403 dev_err(dev, "Failed to select THC port, ret = %d.\n", ret); 404 return ERR_PTR(ret); 405 } 406 407 ret = quickspi_get_acpi_resources(qsdev); 408 if (ret) { 409 dev_err(dev, "Get ACPI resources failed, ret = %d\n", ret); 410 return ERR_PTR(ret); 411 } 412 413 /* THC config for input/output address */ 414 thc_spi_input_output_address_config(qsdev->thc_hw, 415 qsdev->input_report_hdr_addr, 416 qsdev->input_report_bdy_addr, 417 qsdev->output_report_addr); 418 419 /* THC config for spi read operation */ 420 ret = thc_spi_read_config(qsdev->thc_hw, qsdev->spi_freq_val, 421 qsdev->spi_read_io_mode, 422 qsdev->spi_read_opcode, 423 qsdev->spi_packet_size); 424 if (ret) { 425 dev_err(dev, "thc_spi_read_config failed, ret = %d\n", ret); 426 return ERR_PTR(ret); 427 } 428 429 /* THC config for spi write operation */ 430 ret = thc_spi_write_config(qsdev->thc_hw, qsdev->spi_freq_val, 431 qsdev->spi_write_io_mode, 432 qsdev->spi_write_opcode, 433 qsdev->spi_packet_size, 434 qsdev->performance_limit); 435 if (ret) { 436 dev_err(dev, "thc_spi_write_config failed, ret = %d\n", ret); 437 return ERR_PTR(ret); 438 } 439 440 thc_ltr_config(qsdev->thc_hw, 441 qsdev->active_ltr_val, 442 qsdev->low_power_ltr_val); 443 444 thc_interrupt_config(qsdev->thc_hw); 445 446 thc_interrupt_enable(qsdev->thc_hw, true); 447 448 thc_wot_config(qsdev->thc_hw, &quickspi_gpios[0]); 449 450 qsdev->state = QUICKSPI_INITIATED; 451 452 return qsdev; 453} 454 455/** 456 * quickspi_dev_deinit - De-initialize quickspi device 457 * 458 * @qsdev: pointer to the quickspi device structure 459 * 460 * Disable THC interrupt and deinitilize THC. 461 */ 462static void quickspi_dev_deinit(struct quickspi_device *qsdev) 463{ 464 thc_interrupt_enable(qsdev->thc_hw, false); 465 thc_ltr_unconfig(qsdev->thc_hw); 466 thc_wot_unconfig(qsdev->thc_hw); 467 468 qsdev->state = QUICKSPI_DISABLED; 469} 470 471/** 472 * quickspi_dma_init - Configure THC DMA for quickspi device 473 * @qsdev: pointer to the quickspi device structure 474 * 475 * This function uses TIC's parameters(such as max input length, max output 476 * length) to allocate THC DMA buffers and configure THC DMA engines. 477 * 478 * Return: 0 if successful or error code on failed. 479 */ 480static int quickspi_dma_init(struct quickspi_device *qsdev) 481{ 482 int ret; 483 484 ret = thc_dma_set_max_packet_sizes(qsdev->thc_hw, 0, 485 le16_to_cpu(qsdev->dev_desc.max_input_len), 486 le16_to_cpu(qsdev->dev_desc.max_output_len), 487 0); 488 if (ret) 489 return ret; 490 491 ret = thc_dma_allocate(qsdev->thc_hw); 492 if (ret) { 493 dev_err(qsdev->dev, "Allocate THC DMA buffer failed, ret = %d\n", ret); 494 return ret; 495 } 496 497 /* Enable RxDMA */ 498 ret = thc_dma_configure(qsdev->thc_hw); 499 if (ret) { 500 dev_err(qsdev->dev, "Configure THC DMA failed, ret = %d\n", ret); 501 thc_dma_unconfigure(qsdev->thc_hw); 502 thc_dma_release(qsdev->thc_hw); 503 return ret; 504 } 505 506 return ret; 507} 508 509/** 510 * quickspi_dma_deinit - Release THC DMA for quickspi device 511 * @qsdev: pointer to the quickspi device structure 512 * 513 * Stop THC DMA engines and release all DMA buffers. 514 * 515 */ 516static void quickspi_dma_deinit(struct quickspi_device *qsdev) 517{ 518 thc_dma_unconfigure(qsdev->thc_hw); 519 thc_dma_release(qsdev->thc_hw); 520} 521 522/** 523 * quickspi_alloc_report_buf - Alloc report buffers 524 * @qsdev: pointer to the quickspi device structure 525 * 526 * Allocate report descriptor buffer, it will be used for restore TIC HID 527 * report descriptor. 528 * 529 * Allocate input report buffer, it will be used for receive HID input report 530 * data from TIC. 531 * 532 * Allocate output report buffer, it will be used for store HID output report, 533 * such as set feature. 534 * 535 * Return: 0 if successful or error code on failed. 536 */ 537static int quickspi_alloc_report_buf(struct quickspi_device *qsdev) 538{ 539 size_t max_report_len; 540 size_t max_input_len; 541 542 qsdev->report_descriptor = devm_kzalloc(qsdev->dev, 543 le16_to_cpu(qsdev->dev_desc.rep_desc_len), 544 GFP_KERNEL); 545 if (!qsdev->report_descriptor) 546 return -ENOMEM; 547 548 max_input_len = max(le16_to_cpu(qsdev->dev_desc.rep_desc_len), 549 le16_to_cpu(qsdev->dev_desc.max_input_len)); 550 551 qsdev->input_buf = devm_kzalloc(qsdev->dev, max_input_len, GFP_KERNEL); 552 if (!qsdev->input_buf) 553 return -ENOMEM; 554 555 max_report_len = max(le16_to_cpu(qsdev->dev_desc.max_output_len), 556 le16_to_cpu(qsdev->dev_desc.max_input_len)); 557 558 qsdev->report_buf = devm_kzalloc(qsdev->dev, max_report_len, GFP_KERNEL); 559 if (!qsdev->report_buf) 560 return -ENOMEM; 561 562 return 0; 563} 564 565/* 566 * quickspi_probe: Quickspi driver probe function 567 * 568 * @pdev: point to pci device 569 * @id: point to pci_device_id structure 570 * 571 * This function initializes THC and HIDSPI device, the flow is: 572 * - do THC pci device initialization 573 * - query HIDSPI ACPI parameters 574 * - configure THC to HIDSPI mode 575 * - go through HIDSPI enumeration flow 576 * |- reset HIDSPI device 577 * |- read device descriptor 578 * - enable THC interrupt and DMA 579 * - read report descriptor 580 * - register HID device 581 * - enable runtime power management 582 * 583 * Return 0 if success or error code on failure. 584 */ 585static int quickspi_probe(struct pci_dev *pdev, 586 const struct pci_device_id *id) 587{ 588 struct quickspi_device *qsdev; 589 void __iomem *mem_addr; 590 int ret; 591 592 ret = pcim_enable_device(pdev); 593 if (ret) { 594 dev_err(&pdev->dev, "Failed to enable PCI device, ret = %d.\n", ret); 595 return ret; 596 } 597 598 pci_set_master(pdev); 599 600 mem_addr = pcim_iomap_region(pdev, 0, KBUILD_MODNAME); 601 ret = PTR_ERR_OR_ZERO(mem_addr); 602 if (ret) { 603 dev_err(&pdev->dev, "Failed to get PCI regions, ret = %d.\n", ret); 604 goto disable_pci_device; 605 } 606 607 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); 608 if (ret) { 609 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); 610 if (ret) { 611 dev_err(&pdev->dev, "No usable DMA configuration %d\n", ret); 612 goto disable_pci_device; 613 } 614 } 615 616 ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); 617 if (ret < 0) { 618 dev_err(&pdev->dev, 619 "Failed to allocate IRQ vectors. ret = %d\n", ret); 620 goto disable_pci_device; 621 } 622 623 pdev->irq = pci_irq_vector(pdev, 0); 624 625 qsdev = quickspi_dev_init(pdev, mem_addr, id); 626 if (IS_ERR(qsdev)) { 627 dev_err(&pdev->dev, "QuickSPI device init failed\n"); 628 ret = PTR_ERR(qsdev); 629 goto disable_pci_device; 630 } 631 632 pci_set_drvdata(pdev, qsdev); 633 634 ret = devm_request_threaded_irq(&pdev->dev, pdev->irq, 635 quickspi_irq_quick_handler, 636 quickspi_irq_thread_handler, 637 IRQF_ONESHOT, KBUILD_MODNAME, 638 qsdev); 639 if (ret) { 640 dev_err(&pdev->dev, 641 "Failed to request threaded IRQ, irq = %d.\n", pdev->irq); 642 goto dev_deinit; 643 } 644 645 ret = reset_tic(qsdev); 646 if (ret) { 647 dev_err(&pdev->dev, "Reset Touch Device failed, ret = %d\n", ret); 648 goto dev_deinit; 649 } 650 651 ret = quickspi_alloc_report_buf(qsdev); 652 if (ret) { 653 dev_err(&pdev->dev, "Alloc report buffers failed, ret= %d\n", ret); 654 goto dev_deinit; 655 } 656 657 ret = quickspi_dma_init(qsdev); 658 if (ret) { 659 dev_err(&pdev->dev, "Setup THC DMA failed, ret= %d\n", ret); 660 goto dev_deinit; 661 } 662 663 ret = quickspi_get_report_descriptor(qsdev); 664 if (ret) { 665 dev_err(&pdev->dev, "Get report descriptor failed, ret = %d\n", ret); 666 goto dma_deinit; 667 } 668 669 ret = quickspi_hid_probe(qsdev); 670 if (ret) { 671 dev_err(&pdev->dev, "Failed to register HID device, ret = %d\n", ret); 672 goto dma_deinit; 673 } 674 675 qsdev->state = QUICKSPI_ENABLED; 676 677 /* Enable runtime power management */ 678 pm_runtime_use_autosuspend(qsdev->dev); 679 pm_runtime_set_autosuspend_delay(qsdev->dev, DEFAULT_AUTO_SUSPEND_DELAY_MS); 680 pm_runtime_put_noidle(qsdev->dev); 681 pm_runtime_put_autosuspend(qsdev->dev); 682 683 dev_dbg(&pdev->dev, "QuickSPI probe success\n"); 684 685 return 0; 686 687dma_deinit: 688 quickspi_dma_deinit(qsdev); 689dev_deinit: 690 quickspi_dev_deinit(qsdev); 691disable_pci_device: 692 pci_clear_master(pdev); 693 694 return ret; 695} 696 697/** 698 * quickspi_remove - Device Removal Routine 699 * 700 * @pdev: PCI device structure 701 * 702 * This is called by the PCI subsystem to alert the driver 703 * that it should release a PCI device. 704 */ 705static void quickspi_remove(struct pci_dev *pdev) 706{ 707 struct quickspi_device *qsdev; 708 709 qsdev = pci_get_drvdata(pdev); 710 if (!qsdev) 711 return; 712 713 quickspi_hid_remove(qsdev); 714 quickspi_dma_deinit(qsdev); 715 716 pm_runtime_get_noresume(qsdev->dev); 717 718 quickspi_dev_deinit(qsdev); 719 720 pci_clear_master(pdev); 721} 722 723/** 724 * quickspi_shutdown - Device Shutdown Routine 725 * 726 * @pdev: PCI device structure 727 * 728 * This is called from the reboot notifier 729 * it's a simplified version of remove so we go down 730 * faster. 731 */ 732static void quickspi_shutdown(struct pci_dev *pdev) 733{ 734 struct quickspi_device *qsdev; 735 736 qsdev = pci_get_drvdata(pdev); 737 if (!qsdev) 738 return; 739 740 /* Must stop DMA before reboot to avoid DMA entering into unknown state */ 741 quickspi_dma_deinit(qsdev); 742 743 quickspi_dev_deinit(qsdev); 744} 745 746static int quickspi_suspend(struct device *device) 747{ 748 struct pci_dev *pdev = to_pci_dev(device); 749 struct quickspi_device *qsdev; 750 int ret; 751 752 qsdev = pci_get_drvdata(pdev); 753 if (!qsdev) 754 return -ENODEV; 755 756 ret = quickspi_set_power(qsdev, HIDSPI_SLEEP); 757 if (ret) 758 return ret; 759 760 ret = thc_interrupt_quiesce(qsdev->thc_hw, true); 761 if (ret) 762 return ret; 763 764 thc_interrupt_enable(qsdev->thc_hw, false); 765 766 thc_dma_unconfigure(qsdev->thc_hw); 767 768 return 0; 769} 770 771static int quickspi_resume(struct device *device) 772{ 773 struct pci_dev *pdev = to_pci_dev(device); 774 struct quickspi_device *qsdev; 775 int ret; 776 777 qsdev = pci_get_drvdata(pdev); 778 if (!qsdev) 779 return -ENODEV; 780 781 ret = thc_port_select(qsdev->thc_hw, THC_PORT_TYPE_SPI); 782 if (ret) 783 return ret; 784 785 thc_interrupt_config(qsdev->thc_hw); 786 787 thc_interrupt_enable(qsdev->thc_hw, true); 788 789 ret = thc_dma_configure(qsdev->thc_hw); 790 if (ret) 791 return ret; 792 793 ret = thc_interrupt_quiesce(qsdev->thc_hw, false); 794 if (ret) 795 return ret; 796 797 ret = quickspi_set_power(qsdev, HIDSPI_ON); 798 if (ret) 799 return ret; 800 801 return 0; 802} 803 804static int quickspi_freeze(struct device *device) 805{ 806 struct pci_dev *pdev = to_pci_dev(device); 807 struct quickspi_device *qsdev; 808 int ret; 809 810 qsdev = pci_get_drvdata(pdev); 811 if (!qsdev) 812 return -ENODEV; 813 814 ret = thc_interrupt_quiesce(qsdev->thc_hw, true); 815 if (ret) 816 return ret; 817 818 thc_interrupt_enable(qsdev->thc_hw, false); 819 820 thc_dma_unconfigure(qsdev->thc_hw); 821 822 return 0; 823} 824 825static int quickspi_thaw(struct device *device) 826{ 827 struct pci_dev *pdev = to_pci_dev(device); 828 struct quickspi_device *qsdev; 829 int ret; 830 831 qsdev = pci_get_drvdata(pdev); 832 if (!qsdev) 833 return -ENODEV; 834 835 ret = thc_dma_configure(qsdev->thc_hw); 836 if (ret) 837 return ret; 838 839 thc_interrupt_enable(qsdev->thc_hw, true); 840 841 ret = thc_interrupt_quiesce(qsdev->thc_hw, false); 842 if (ret) 843 return ret; 844 845 return 0; 846} 847 848static int quickspi_poweroff(struct device *device) 849{ 850 struct pci_dev *pdev = to_pci_dev(device); 851 struct quickspi_device *qsdev; 852 int ret; 853 854 qsdev = pci_get_drvdata(pdev); 855 if (!qsdev) 856 return -ENODEV; 857 858 ret = thc_interrupt_quiesce(qsdev->thc_hw, true); 859 if (ret) 860 return ret; 861 862 thc_interrupt_enable(qsdev->thc_hw, false); 863 864 thc_ltr_unconfig(qsdev->thc_hw); 865 866 quickspi_dma_deinit(qsdev); 867 868 return 0; 869} 870 871static int quickspi_restore(struct device *device) 872{ 873 struct pci_dev *pdev = to_pci_dev(device); 874 struct quickspi_device *qsdev; 875 int ret; 876 877 qsdev = pci_get_drvdata(pdev); 878 if (!qsdev) 879 return -ENODEV; 880 881 ret = thc_interrupt_quiesce(qsdev->thc_hw, true); 882 if (ret) 883 return ret; 884 885 /* Reconfig THC HW when back from hibernate */ 886 ret = thc_port_select(qsdev->thc_hw, THC_PORT_TYPE_SPI); 887 if (ret) 888 return ret; 889 890 thc_spi_input_output_address_config(qsdev->thc_hw, 891 qsdev->input_report_hdr_addr, 892 qsdev->input_report_bdy_addr, 893 qsdev->output_report_addr); 894 895 ret = thc_spi_read_config(qsdev->thc_hw, qsdev->spi_freq_val, 896 qsdev->spi_read_io_mode, 897 qsdev->spi_read_opcode, 898 qsdev->spi_packet_size); 899 if (ret) 900 return ret; 901 902 ret = thc_spi_write_config(qsdev->thc_hw, qsdev->spi_freq_val, 903 qsdev->spi_write_io_mode, 904 qsdev->spi_write_opcode, 905 qsdev->spi_packet_size, 906 qsdev->performance_limit); 907 if (ret) 908 return ret; 909 910 thc_interrupt_config(qsdev->thc_hw); 911 912 thc_interrupt_enable(qsdev->thc_hw, true); 913 914 /* TIC may lose power, needs go through reset flow */ 915 ret = reset_tic(qsdev); 916 if (ret) 917 return ret; 918 919 ret = thc_dma_configure(qsdev->thc_hw); 920 if (ret) 921 return ret; 922 923 thc_ltr_config(qsdev->thc_hw, 924 qsdev->active_ltr_val, 925 qsdev->low_power_ltr_val); 926 927 thc_change_ltr_mode(qsdev->thc_hw, THC_LTR_MODE_ACTIVE); 928 929 qsdev->state = QUICKSPI_ENABLED; 930 931 return 0; 932} 933 934static int quickspi_runtime_suspend(struct device *device) 935{ 936 struct pci_dev *pdev = to_pci_dev(device); 937 struct quickspi_device *qsdev; 938 939 qsdev = pci_get_drvdata(pdev); 940 if (!qsdev) 941 return -ENODEV; 942 943 thc_change_ltr_mode(qsdev->thc_hw, THC_LTR_MODE_LP); 944 945 pci_save_state(pdev); 946 947 return 0; 948} 949 950static int quickspi_runtime_resume(struct device *device) 951{ 952 struct pci_dev *pdev = to_pci_dev(device); 953 struct quickspi_device *qsdev; 954 955 qsdev = pci_get_drvdata(pdev); 956 if (!qsdev) 957 return -ENODEV; 958 959 thc_change_ltr_mode(qsdev->thc_hw, THC_LTR_MODE_ACTIVE); 960 961 return 0; 962} 963 964static const struct dev_pm_ops quickspi_pm_ops = { 965 .suspend = quickspi_suspend, 966 .resume = quickspi_resume, 967 .freeze = quickspi_freeze, 968 .thaw = quickspi_thaw, 969 .poweroff = quickspi_poweroff, 970 .restore = quickspi_restore, 971 .runtime_suspend = quickspi_runtime_suspend, 972 .runtime_resume = quickspi_runtime_resume, 973 .runtime_idle = NULL, 974}; 975 976static const struct pci_device_id quickspi_pci_tbl[] = { 977 {PCI_DEVICE_DATA(INTEL, THC_MTL_DEVICE_ID_SPI_PORT1, &mtl), }, 978 {PCI_DEVICE_DATA(INTEL, THC_MTL_DEVICE_ID_SPI_PORT2, &mtl), }, 979 {PCI_DEVICE_DATA(INTEL, THC_LNL_DEVICE_ID_SPI_PORT1, &lnl), }, 980 {PCI_DEVICE_DATA(INTEL, THC_LNL_DEVICE_ID_SPI_PORT2, &lnl), }, 981 {PCI_DEVICE_DATA(INTEL, THC_PTL_H_DEVICE_ID_SPI_PORT1, &ptl), }, 982 {PCI_DEVICE_DATA(INTEL, THC_PTL_H_DEVICE_ID_SPI_PORT2, &ptl), }, 983 {PCI_DEVICE_DATA(INTEL, THC_PTL_U_DEVICE_ID_SPI_PORT1, &ptl), }, 984 {PCI_DEVICE_DATA(INTEL, THC_PTL_U_DEVICE_ID_SPI_PORT2, &ptl), }, 985 {PCI_DEVICE_DATA(INTEL, THC_WCL_DEVICE_ID_SPI_PORT1, &ptl), }, 986 {PCI_DEVICE_DATA(INTEL, THC_WCL_DEVICE_ID_SPI_PORT2, &ptl), }, 987 {PCI_DEVICE_DATA(INTEL, THC_ARL_DEVICE_ID_SPI_PORT1, &arl), }, 988 {PCI_DEVICE_DATA(INTEL, THC_ARL_DEVICE_ID_SPI_PORT2, &arl), }, 989 {PCI_DEVICE_DATA(INTEL, THC_NVL_H_DEVICE_ID_SPI_PORT1, &nvl), }, 990 {PCI_DEVICE_DATA(INTEL, THC_NVL_H_DEVICE_ID_SPI_PORT2, &nvl), }, 991 {} 992}; 993MODULE_DEVICE_TABLE(pci, quickspi_pci_tbl); 994 995static struct pci_driver quickspi_driver = { 996 .name = KBUILD_MODNAME, 997 .id_table = quickspi_pci_tbl, 998 .probe = quickspi_probe, 999 .remove = quickspi_remove, 1000 .shutdown = quickspi_shutdown, 1001 .driver.pm = &quickspi_pm_ops, 1002 .driver.probe_type = PROBE_PREFER_ASYNCHRONOUS, 1003}; 1004 1005module_pci_driver(quickspi_driver); 1006 1007MODULE_AUTHOR("Xinpeng Sun <xinpeng.sun@intel.com>"); 1008MODULE_AUTHOR("Even Xu <even.xu@intel.com>"); 1009 1010MODULE_DESCRIPTION("Intel(R) QuickSPI Driver"); 1011MODULE_LICENSE("GPL"); 1012MODULE_IMPORT_NS("INTEL_THC");
~/
Read-only file preview.