Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Intel PCH/PCU SPI flash PCI driver.
0004  *
0005  * Copyright (C) 2016 - 2022, Intel Corporation
0006  * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
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     /* Try to make the chip read/write */
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");