root/drivers/spi/spi-dw-pci.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. spi_pci_probe
  2. spi_pci_remove
  3. spi_suspend
  4. spi_resume

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * PCI interface driver for DW SPI Core
   4  *
   5  * Copyright (c) 2009, 2014 Intel Corporation.
   6  */
   7 
   8 #include <linux/interrupt.h>
   9 #include <linux/pci.h>
  10 #include <linux/slab.h>
  11 #include <linux/spi/spi.h>
  12 #include <linux/module.h>
  13 
  14 #include "spi-dw.h"
  15 
  16 #define DRIVER_NAME "dw_spi_pci"
  17 
  18 struct spi_pci_desc {
  19         int     (*setup)(struct dw_spi *);
  20         u16     num_cs;
  21         u16     bus_num;
  22         u32     max_freq;
  23 };
  24 
  25 static struct spi_pci_desc spi_pci_mid_desc_1 = {
  26         .setup = dw_spi_mid_init,
  27         .num_cs = 5,
  28         .bus_num = 0,
  29 };
  30 
  31 static struct spi_pci_desc spi_pci_mid_desc_2 = {
  32         .setup = dw_spi_mid_init,
  33         .num_cs = 2,
  34         .bus_num = 1,
  35 };
  36 
  37 static struct spi_pci_desc spi_pci_ehl_desc = {
  38         .num_cs = 1,
  39         .bus_num = -1,
  40         .max_freq = 100000000,
  41 };
  42 
  43 static int spi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
  44 {
  45         struct dw_spi *dws;
  46         struct spi_pci_desc *desc = (struct spi_pci_desc *)ent->driver_data;
  47         int pci_bar = 0;
  48         int ret;
  49 
  50         ret = pcim_enable_device(pdev);
  51         if (ret)
  52                 return ret;
  53 
  54         dws = devm_kzalloc(&pdev->dev, sizeof(*dws), GFP_KERNEL);
  55         if (!dws)
  56                 return -ENOMEM;
  57 
  58         /* Get basic io resource and map it */
  59         dws->paddr = pci_resource_start(pdev, pci_bar);
  60 
  61         ret = pcim_iomap_regions(pdev, 1 << pci_bar, pci_name(pdev));
  62         if (ret)
  63                 return ret;
  64 
  65         dws->regs = pcim_iomap_table(pdev)[pci_bar];
  66         dws->irq = pdev->irq;
  67 
  68         /*
  69          * Specific handling for platforms, like dma setup,
  70          * clock rate, FIFO depth.
  71          */
  72         if (desc) {
  73                 dws->num_cs = desc->num_cs;
  74                 dws->bus_num = desc->bus_num;
  75                 dws->max_freq = desc->max_freq;
  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 
  99 static 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
 107 static int spi_suspend(struct device *dev)
 108 {
 109         struct dw_spi *dws = dev_get_drvdata(dev);
 110 
 111         return dw_spi_suspend_host(dws);
 112 }
 113 
 114 static int spi_resume(struct device *dev)
 115 {
 116         struct dw_spi *dws = dev_get_drvdata(dev);
 117 
 118         return dw_spi_resume_host(dws);
 119 }
 120 #endif
 121 
 122 static SIMPLE_DEV_PM_OPS(dw_spi_pm_ops, spi_suspend, spi_resume);
 123 
 124 static const struct pci_device_id pci_ids[] = {
 125         /* Intel MID platform SPI controller 0 */
 126         /*
 127          * The access to the device 8086:0801 is disabled by HW, since it's
 128          * exclusively used by SCU to communicate with MSIC.
 129          */
 130         /* Intel MID platform SPI controller 1 */
 131         { PCI_VDEVICE(INTEL, 0x0800), (kernel_ulong_t)&spi_pci_mid_desc_1},
 132         /* Intel MID platform SPI controller 2 */
 133         { PCI_VDEVICE(INTEL, 0x0812), (kernel_ulong_t)&spi_pci_mid_desc_2},
 134         /* Intel Elkhart Lake PSE SPI controllers */
 135         { PCI_VDEVICE(INTEL, 0x4b84), (kernel_ulong_t)&spi_pci_ehl_desc},
 136         { PCI_VDEVICE(INTEL, 0x4b85), (kernel_ulong_t)&spi_pci_ehl_desc},
 137         { PCI_VDEVICE(INTEL, 0x4b86), (kernel_ulong_t)&spi_pci_ehl_desc},
 138         { PCI_VDEVICE(INTEL, 0x4b87), (kernel_ulong_t)&spi_pci_ehl_desc},
 139         {},
 140 };
 141 MODULE_DEVICE_TABLE(pci, pci_ids);
 142 
 143 static struct pci_driver dw_spi_driver = {
 144         .name =         DRIVER_NAME,
 145         .id_table =     pci_ids,
 146         .probe =        spi_pci_probe,
 147         .remove =       spi_pci_remove,
 148         .driver         = {
 149                 .pm     = &dw_spi_pm_ops,
 150         },
 151 };
 152 
 153 module_pci_driver(dw_spi_driver);
 154 
 155 MODULE_AUTHOR("Feng Tang <feng.tang@intel.com>");
 156 MODULE_DESCRIPTION("PCI interface driver for DW SPI Core");
 157 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */