Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.6-rc2 153 lines 3.6 kB view raw
1/* 2 * PCI interface driver for DW SPI Core 3 * 4 * Copyright (c) 2009, 2014 Intel Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 */ 15 16#include <linux/interrupt.h> 17#include <linux/pci.h> 18#include <linux/slab.h> 19#include <linux/spi/spi.h> 20#include <linux/module.h> 21 22#include "spi-dw.h" 23 24#define DRIVER_NAME "dw_spi_pci" 25 26struct spi_pci_desc { 27 int (*setup)(struct dw_spi *); 28 u16 num_cs; 29 u16 bus_num; 30}; 31 32static struct spi_pci_desc spi_pci_mid_desc_1 = { 33 .setup = dw_spi_mid_init, 34 .num_cs = 5, 35 .bus_num = 0, 36}; 37 38static struct spi_pci_desc spi_pci_mid_desc_2 = { 39 .setup = dw_spi_mid_init, 40 .num_cs = 2, 41 .bus_num = 1, 42}; 43 44static int spi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 45{ 46 struct dw_spi *dws; 47 struct spi_pci_desc *desc = (struct spi_pci_desc *)ent->driver_data; 48 int pci_bar = 0; 49 int ret; 50 51 ret = pcim_enable_device(pdev); 52 if (ret) 53 return ret; 54 55 dws = devm_kzalloc(&pdev->dev, sizeof(*dws), GFP_KERNEL); 56 if (!dws) 57 return -ENOMEM; 58 59 /* Get basic io resource and map it */ 60 dws->paddr = pci_resource_start(pdev, pci_bar); 61 62 ret = pcim_iomap_regions(pdev, 1 << pci_bar, pci_name(pdev)); 63 if (ret) 64 return ret; 65 66 dws->regs = pcim_iomap_table(pdev)[pci_bar]; 67 dws->irq = pdev->irq; 68 69 /* 70 * Specific handling for paltforms, like dma setup, 71 * clock rate, FIFO depth. 72 */ 73 if (desc) { 74 dws->num_cs = desc->num_cs; 75 dws->bus_num = desc->bus_num; 76 77 if (desc->setup) { 78 ret = desc->setup(dws); 79 if (ret) 80 return ret; 81 } 82 } else { 83 return -ENODEV; 84 } 85 86 ret = dw_spi_add_host(&pdev->dev, dws); 87 if (ret) 88 return ret; 89 90 /* PCI hook and SPI hook use the same drv data */ 91 pci_set_drvdata(pdev, dws); 92 93 dev_info(&pdev->dev, "found PCI SPI controller(ID: %04x:%04x)\n", 94 pdev->vendor, pdev->device); 95 96 return 0; 97} 98 99static void spi_pci_remove(struct pci_dev *pdev) 100{ 101 struct dw_spi *dws = pci_get_drvdata(pdev); 102 103 dw_spi_remove_host(dws); 104} 105 106#ifdef CONFIG_PM_SLEEP 107static int spi_suspend(struct device *dev) 108{ 109 struct pci_dev *pdev = to_pci_dev(dev); 110 struct dw_spi *dws = pci_get_drvdata(pdev); 111 112 return dw_spi_suspend_host(dws); 113} 114 115static int spi_resume(struct device *dev) 116{ 117 struct pci_dev *pdev = to_pci_dev(dev); 118 struct dw_spi *dws = pci_get_drvdata(pdev); 119 120 return dw_spi_resume_host(dws); 121} 122#endif 123 124static SIMPLE_DEV_PM_OPS(dw_spi_pm_ops, spi_suspend, spi_resume); 125 126static const struct pci_device_id pci_ids[] = { 127 /* Intel MID platform SPI controller 0 */ 128 /* 129 * The access to the device 8086:0801 is disabled by HW, since it's 130 * exclusively used by SCU to communicate with MSIC. 131 */ 132 /* Intel MID platform SPI controller 1 */ 133 { PCI_VDEVICE(INTEL, 0x0800), (kernel_ulong_t)&spi_pci_mid_desc_1}, 134 /* Intel MID platform SPI controller 2 */ 135 { PCI_VDEVICE(INTEL, 0x0812), (kernel_ulong_t)&spi_pci_mid_desc_2}, 136 {}, 137}; 138 139static struct pci_driver dw_spi_driver = { 140 .name = DRIVER_NAME, 141 .id_table = pci_ids, 142 .probe = spi_pci_probe, 143 .remove = spi_pci_remove, 144 .driver = { 145 .pm = &dw_spi_pm_ops, 146 }, 147}; 148 149module_pci_driver(dw_spi_driver); 150 151MODULE_AUTHOR("Feng Tang <feng.tang@intel.com>"); 152MODULE_DESCRIPTION("PCI interface driver for DW SPI Core"); 153MODULE_LICENSE("GPL v2");