Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fe602838 authored by Mika Westerberg's avatar Mika Westerberg Committed by Cyrille Pitchen
Browse files

mtd: spi-nor: intel-spi: Add support for Intel Denverton SPI serial flash controller



Intel Denverton exposes the SPI serial flash controller as a PCI device
instead of being part of the LPC chip as previous generations did.

Signed-off-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: default avatarCyrille Pitchen <cyrille.pitchen@free-electrons.com>
parent f384b352
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -89,6 +89,22 @@ config SPI_NXP_SPIFI
config SPI_INTEL_SPI
	tristate

config SPI_INTEL_SPI_PCI
	tristate "Intel PCH/PCU SPI flash PCI driver" if EXPERT
	depends on X86 && PCI
	select SPI_INTEL_SPI
	help
	  This enables PCI support for the Intel PCH/PCU SPI controller in
	  master mode. This controller is present in modern Intel hardware
	  and is used to hold BIOS and other persistent settings. Using
	  this driver it is possible to upgrade BIOS directly from Linux.

	  Say N here unless you know what you are doing. Overwriting the
	  SPI flash may render the system unbootable.

	  To compile this driver as a module, choose M here: the module
	  will be called intel-spi-pci.

config SPI_INTEL_SPI_PLATFORM
	tristate "Intel PCH/PCU SPI flash platform driver" if EXPERT
	depends on X86
+1 −0
Original line number Diff line number Diff line
@@ -7,5 +7,6 @@ obj-$(CONFIG_SPI_HISI_SFC) += hisi-sfc.o
obj-$(CONFIG_MTD_MT81xx_NOR)    += mtk-quadspi.o
obj-$(CONFIG_SPI_NXP_SPIFI)	+= nxp-spifi.o
obj-$(CONFIG_SPI_INTEL_SPI)	+= intel-spi.o
obj-$(CONFIG_SPI_INTEL_SPI_PCI)	+= intel-spi-pci.o
obj-$(CONFIG_SPI_INTEL_SPI_PLATFORM)	+= intel-spi-platform.o
obj-$(CONFIG_SPI_STM32_QUADSPI)	+= stm32-quadspi.o
 No newline at end of file
+82 −0
Original line number Diff line number Diff line
/*
 * Intel PCH/PCU SPI flash PCI driver.
 *
 * Copyright (C) 2016, Intel Corporation
 * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>

#include "intel-spi.h"

#define BCR		0xdc
#define BCR_WPD		BIT(0)

static const struct intel_spi_boardinfo bxt_info = {
	.type = INTEL_SPI_BXT,
};

static int intel_spi_pci_probe(struct pci_dev *pdev,
			       const struct pci_device_id *id)
{
	struct intel_spi_boardinfo *info;
	struct intel_spi *ispi;
	u32 bcr;
	int ret;

	ret = pcim_enable_device(pdev);
	if (ret)
		return ret;

	info = devm_kmemdup(&pdev->dev, (void *)id->driver_data, sizeof(*info),
			    GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	/* Try to make the chip read/write */
	pci_read_config_dword(pdev, BCR, &bcr);
	if (!(bcr & BCR_WPD)) {
		bcr |= BCR_WPD;
		pci_write_config_dword(pdev, BCR, bcr);
		pci_read_config_dword(pdev, BCR, &bcr);
	}
	info->writeable = !!(bcr & BCR_WPD);

	ispi = intel_spi_probe(&pdev->dev, &pdev->resource[0], info);
	if (IS_ERR(ispi))
		return PTR_ERR(ispi);

	pci_set_drvdata(pdev, ispi);
	return 0;
}

static void intel_spi_pci_remove(struct pci_dev *pdev)
{
	intel_spi_remove(pci_get_drvdata(pdev));
}

static const struct pci_device_id intel_spi_pci_ids[] = {
	{ PCI_VDEVICE(INTEL, 0x19e0), (unsigned long)&bxt_info },
	{ },
};
MODULE_DEVICE_TABLE(pci, intel_spi_pci_ids);

static struct pci_driver intel_spi_pci_driver = {
	.name = "intel-spi",
	.id_table = intel_spi_pci_ids,
	.probe = intel_spi_pci_probe,
	.remove = intel_spi_pci_remove,
};

module_pci_driver(intel_spi_pci_driver);

MODULE_DESCRIPTION("Intel PCH/PCU SPI flash PCI driver");
MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
MODULE_LICENSE("GPL v2");