Commit | Line | Data |
---|---|---|
d2912cb1 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
fe602838 MW |
2 | /* |
3 | * Intel PCH/PCU SPI flash PCI driver. | |
4 | * | |
5 | * Copyright (C) 2016, Intel Corporation | |
6 | * Author: Mika Westerberg <mika.westerberg@linux.intel.com> | |
fe602838 MW |
7 | */ |
8 | ||
9 | #include <linux/ioport.h> | |
10 | #include <linux/kernel.h> | |
11 | #include <linux/module.h> | |
12 | #include <linux/pci.h> | |
13 | ||
14 | #include "intel-spi.h" | |
15 | ||
16 | #define BCR 0xdc | |
17 | #define BCR_WPD BIT(0) | |
18 | ||
19 | static const struct intel_spi_boardinfo bxt_info = { | |
20 | .type = INTEL_SPI_BXT, | |
21 | }; | |
22 | ||
4b97ba73 JB |
23 | static const struct intel_spi_boardinfo cnl_info = { |
24 | .type = INTEL_SPI_CNL, | |
25 | }; | |
26 | ||
fe602838 MW |
27 | static int intel_spi_pci_probe(struct pci_dev *pdev, |
28 | const struct pci_device_id *id) | |
29 | { | |
30 | struct intel_spi_boardinfo *info; | |
31 | struct intel_spi *ispi; | |
32 | u32 bcr; | |
33 | int ret; | |
34 | ||
35 | ret = pcim_enable_device(pdev); | |
36 | if (ret) | |
37 | return ret; | |
38 | ||
39 | info = devm_kmemdup(&pdev->dev, (void *)id->driver_data, sizeof(*info), | |
40 | GFP_KERNEL); | |
41 | if (!info) | |
42 | return -ENOMEM; | |
43 | ||
44 | /* Try to make the chip read/write */ | |
45 | pci_read_config_dword(pdev, BCR, &bcr); | |
46 | if (!(bcr & BCR_WPD)) { | |
47 | bcr |= BCR_WPD; | |
48 | pci_write_config_dword(pdev, BCR, bcr); | |
49 | pci_read_config_dword(pdev, BCR, &bcr); | |
50 | } | |
51 | info->writeable = !!(bcr & BCR_WPD); | |
52 | ||
53 | ispi = intel_spi_probe(&pdev->dev, &pdev->resource[0], info); | |
54 | if (IS_ERR(ispi)) | |
55 | return PTR_ERR(ispi); | |
56 | ||
57 | pci_set_drvdata(pdev, ispi); | |
58 | return 0; | |
59 | } | |
60 | ||
61 | static void intel_spi_pci_remove(struct pci_dev *pdev) | |
62 | { | |
63 | intel_spi_remove(pci_get_drvdata(pdev)); | |
64 | } | |
65 | ||
66 | static const struct pci_device_id intel_spi_pci_ids[] = { | |
e43f53c2 | 67 | { PCI_VDEVICE(INTEL, 0x02a4), (unsigned long)&bxt_info }, |
5a0feb62 | 68 | { PCI_VDEVICE(INTEL, 0x06a4), (unsigned long)&bxt_info }, |
824af37e | 69 | { PCI_VDEVICE(INTEL, 0x18e0), (unsigned long)&bxt_info }, |
fe602838 | 70 | { PCI_VDEVICE(INTEL, 0x19e0), (unsigned long)&bxt_info }, |
42460c31 | 71 | { PCI_VDEVICE(INTEL, 0x34a4), (unsigned long)&bxt_info }, |
ba0d4e04 | 72 | { PCI_VDEVICE(INTEL, 0x4b24), (unsigned long)&bxt_info }, |
f13e1804 | 73 | { PCI_VDEVICE(INTEL, 0xa0a4), (unsigned long)&bxt_info }, |
d92b0f18 | 74 | { PCI_VDEVICE(INTEL, 0xa1a4), (unsigned long)&bxt_info }, |
ec0a9f62 | 75 | { PCI_VDEVICE(INTEL, 0xa224), (unsigned long)&bxt_info }, |
4b97ba73 | 76 | { PCI_VDEVICE(INTEL, 0xa324), (unsigned long)&cnl_info }, |
fe602838 MW |
77 | { }, |
78 | }; | |
79 | MODULE_DEVICE_TABLE(pci, intel_spi_pci_ids); | |
80 | ||
81 | static struct pci_driver intel_spi_pci_driver = { | |
82 | .name = "intel-spi", | |
83 | .id_table = intel_spi_pci_ids, | |
84 | .probe = intel_spi_pci_probe, | |
85 | .remove = intel_spi_pci_remove, | |
86 | }; | |
87 | ||
88 | module_pci_driver(intel_spi_pci_driver); | |
89 | ||
90 | MODULE_DESCRIPTION("Intel PCH/PCU SPI flash PCI driver"); | |
91 | MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); | |
92 | MODULE_LICENSE("GPL v2"); |