Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * PCI interface driver for DW SPI Core
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (c) 2009, 2014 Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include "spi-dw.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #define DRIVER_NAME "dw_spi_pci"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) /* HW info for MRST Clk Control Unit, 32b reg per controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define MRST_SPI_CLK_BASE	100000000	/* 100m */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define MRST_CLK_SPI_REG	0xff11d86c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define CLK_SPI_BDIV_OFFSET	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define CLK_SPI_BDIV_MASK	0x00000007
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define CLK_SPI_CDIV_OFFSET	9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define CLK_SPI_CDIV_MASK	0x00000e00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define CLK_SPI_DISABLE_OFFSET	8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) struct spi_pci_desc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	int	(*setup)(struct dw_spi *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	u16	num_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	u16	bus_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	u32	max_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) static int spi_mid_init(struct dw_spi *dws)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	void __iomem *clk_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	u32 clk_cdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	clk_reg = ioremap(MRST_CLK_SPI_REG, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	if (!clk_reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	/* Get SPI controller operating freq info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	clk_cdiv = readl(clk_reg + dws->bus_num * sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	clk_cdiv &= CLK_SPI_CDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	clk_cdiv >>= CLK_SPI_CDIV_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	dws->max_freq = MRST_SPI_CLK_BASE / (clk_cdiv + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	iounmap(clk_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	dw_spi_dma_setup_mfld(dws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) static int spi_generic_init(struct dw_spi *dws)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	dw_spi_dma_setup_generic(dws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) static struct spi_pci_desc spi_pci_mid_desc_1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	.setup = spi_mid_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	.num_cs = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	.bus_num = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) static struct spi_pci_desc spi_pci_mid_desc_2 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	.setup = spi_mid_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	.num_cs = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	.bus_num = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) static struct spi_pci_desc spi_pci_ehl_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	.setup = spi_generic_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	.num_cs = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	.bus_num = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	.max_freq = 100000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) static int spi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	struct dw_spi *dws;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	struct spi_pci_desc *desc = (struct spi_pci_desc *)ent->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	int pci_bar = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	ret = pcim_enable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	dws = devm_kzalloc(&pdev->dev, sizeof(*dws), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	if (!dws)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	/* Get basic io resource and map it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	dws->paddr = pci_resource_start(pdev, pci_bar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	pci_set_master(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	ret = pcim_iomap_regions(pdev, 1 << pci_bar, pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	dws->regs = pcim_iomap_table(pdev)[pci_bar];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	dws->irq = pci_irq_vector(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	 * Specific handling for platforms, like dma setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	 * clock rate, FIFO depth.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	if (desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		dws->num_cs = desc->num_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		dws->bus_num = desc->bus_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		dws->max_freq = desc->max_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		if (desc->setup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 			ret = desc->setup(dws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 			if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 				goto err_free_irq_vectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		goto err_free_irq_vectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	ret = dw_spi_add_host(&pdev->dev, dws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		goto err_free_irq_vectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	/* PCI hook and SPI hook use the same drv data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	pci_set_drvdata(pdev, dws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	dev_info(&pdev->dev, "found PCI SPI controller(ID: %04x:%04x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		pdev->vendor, pdev->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	pm_runtime_use_autosuspend(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	pm_runtime_put_autosuspend(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	pm_runtime_allow(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) err_free_irq_vectors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	pci_free_irq_vectors(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static void spi_pci_remove(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	struct dw_spi *dws = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	pm_runtime_forbid(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	pm_runtime_get_noresume(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	dw_spi_remove_host(dws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	pci_free_irq_vectors(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static int spi_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	struct dw_spi *dws = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	return dw_spi_suspend_host(dws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static int spi_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	struct dw_spi *dws = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	return dw_spi_resume_host(dws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static SIMPLE_DEV_PM_OPS(dw_spi_pm_ops, spi_suspend, spi_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static const struct pci_device_id pci_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	/* Intel MID platform SPI controller 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	 * The access to the device 8086:0801 is disabled by HW, since it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	 * exclusively used by SCU to communicate with MSIC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	/* Intel MID platform SPI controller 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	{ PCI_VDEVICE(INTEL, 0x0800), (kernel_ulong_t)&spi_pci_mid_desc_1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	/* Intel MID platform SPI controller 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	{ PCI_VDEVICE(INTEL, 0x0812), (kernel_ulong_t)&spi_pci_mid_desc_2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	/* Intel Elkhart Lake PSE SPI controllers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	{ PCI_VDEVICE(INTEL, 0x4b84), (kernel_ulong_t)&spi_pci_ehl_desc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	{ PCI_VDEVICE(INTEL, 0x4b85), (kernel_ulong_t)&spi_pci_ehl_desc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	{ PCI_VDEVICE(INTEL, 0x4b86), (kernel_ulong_t)&spi_pci_ehl_desc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	{ PCI_VDEVICE(INTEL, 0x4b87), (kernel_ulong_t)&spi_pci_ehl_desc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	{},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) MODULE_DEVICE_TABLE(pci, pci_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static struct pci_driver dw_spi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	.name =		DRIVER_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	.id_table =	pci_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	.probe =	spi_pci_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	.remove =	spi_pci_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	.driver         = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		.pm     = &dw_spi_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) module_pci_driver(dw_spi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) MODULE_AUTHOR("Feng Tang <feng.tang@intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) MODULE_DESCRIPTION("PCI interface driver for DW SPI Core");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) MODULE_LICENSE("GPL v2");