0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/module.h>
0010 #include <linux/pci.h>
0011
0012 #include "spi-intel.h"
0013
0014 #define BCR 0xdc
0015 #define BCR_WPD BIT(0)
0016
0017 static bool intel_spi_pci_set_writeable(void __iomem *base, void *data)
0018 {
0019 struct pci_dev *pdev = data;
0020 u32 bcr;
0021
0022
0023 pci_read_config_dword(pdev, BCR, &bcr);
0024 if (!(bcr & BCR_WPD)) {
0025 bcr |= BCR_WPD;
0026 pci_write_config_dword(pdev, BCR, bcr);
0027 pci_read_config_dword(pdev, BCR, &bcr);
0028 }
0029
0030 return bcr & BCR_WPD;
0031 }
0032
0033 static const struct intel_spi_boardinfo bxt_info = {
0034 .type = INTEL_SPI_BXT,
0035 .set_writeable = intel_spi_pci_set_writeable,
0036 };
0037
0038 static const struct intel_spi_boardinfo cnl_info = {
0039 .type = INTEL_SPI_CNL,
0040 .set_writeable = intel_spi_pci_set_writeable,
0041 };
0042
0043 static int intel_spi_pci_probe(struct pci_dev *pdev,
0044 const struct pci_device_id *id)
0045 {
0046 struct intel_spi_boardinfo *info;
0047 int ret;
0048
0049 ret = pcim_enable_device(pdev);
0050 if (ret)
0051 return ret;
0052
0053 info = devm_kmemdup(&pdev->dev, (void *)id->driver_data, sizeof(*info),
0054 GFP_KERNEL);
0055 if (!info)
0056 return -ENOMEM;
0057
0058 info->data = pdev;
0059 return intel_spi_probe(&pdev->dev, &pdev->resource[0], info);
0060 }
0061
0062 static const struct pci_device_id intel_spi_pci_ids[] = {
0063 { PCI_VDEVICE(INTEL, 0x02a4), (unsigned long)&bxt_info },
0064 { PCI_VDEVICE(INTEL, 0x06a4), (unsigned long)&bxt_info },
0065 { PCI_VDEVICE(INTEL, 0x18e0), (unsigned long)&bxt_info },
0066 { PCI_VDEVICE(INTEL, 0x19e0), (unsigned long)&bxt_info },
0067 { PCI_VDEVICE(INTEL, 0x1bca), (unsigned long)&bxt_info },
0068 { PCI_VDEVICE(INTEL, 0x34a4), (unsigned long)&bxt_info },
0069 { PCI_VDEVICE(INTEL, 0x38a4), (unsigned long)&bxt_info },
0070 { PCI_VDEVICE(INTEL, 0x43a4), (unsigned long)&cnl_info },
0071 { PCI_VDEVICE(INTEL, 0x4b24), (unsigned long)&bxt_info },
0072 { PCI_VDEVICE(INTEL, 0x4da4), (unsigned long)&bxt_info },
0073 { PCI_VDEVICE(INTEL, 0x51a4), (unsigned long)&cnl_info },
0074 { PCI_VDEVICE(INTEL, 0x54a4), (unsigned long)&cnl_info },
0075 { PCI_VDEVICE(INTEL, 0x7a24), (unsigned long)&cnl_info },
0076 { PCI_VDEVICE(INTEL, 0x7aa4), (unsigned long)&cnl_info },
0077 { PCI_VDEVICE(INTEL, 0x7e23), (unsigned long)&cnl_info },
0078 { PCI_VDEVICE(INTEL, 0xa0a4), (unsigned long)&bxt_info },
0079 { PCI_VDEVICE(INTEL, 0xa1a4), (unsigned long)&bxt_info },
0080 { PCI_VDEVICE(INTEL, 0xa224), (unsigned long)&bxt_info },
0081 { PCI_VDEVICE(INTEL, 0xa324), (unsigned long)&cnl_info },
0082 { PCI_VDEVICE(INTEL, 0xa3a4), (unsigned long)&bxt_info },
0083 { },
0084 };
0085 MODULE_DEVICE_TABLE(pci, intel_spi_pci_ids);
0086
0087 static struct pci_driver intel_spi_pci_driver = {
0088 .name = "intel-spi",
0089 .id_table = intel_spi_pci_ids,
0090 .probe = intel_spi_pci_probe,
0091 };
0092
0093 module_pci_driver(intel_spi_pci_driver);
0094
0095 MODULE_DESCRIPTION("Intel PCH/PCU SPI flash PCI driver");
0096 MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
0097 MODULE_LICENSE("GPL v2");