diff options
| author | Sudeep Dutt <sudeep.dutt@intel.com> | 2013-09-05 19:41:31 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-09-26 16:49:23 -0400 |
| commit | b170d8ce3f81bd97e85756e9184779a56a5f55a7 (patch) | |
| tree | aa441b1a6ebd510695b16ee685567409210e3a2a /drivers/misc | |
| parent | 9089e3be60b13a1114e8afdc37c605e75cfc4a26 (diff) | |
Intel MIC Host Driver for X100 family.
This patch enables the following:
a) Initializes the Intel MIC X100 PCIe devices.
b) Provides sysfs entries for family and stepping information.
Co-author: Dasaratharaman Chandramouli <dasaratharaman.chandramouli@intel.com>
Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Signed-off-by: Caz Yokoyama <Caz.Yokoyama@intel.com>
Signed-off-by: Dasaratharaman Chandramouli <dasaratharaman.chandramouli@intel.com>
Signed-off-by: Harshavardhan R Kharche <harshavardhan.r.kharche@intel.com>
Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
Signed-off-by: Sudeep Dutt <sudeep.dutt@intel.com>
Acked-by: Yaozu (Eddie) Dong <eddie.dong@intel.com>
Reviewed-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc')
| -rw-r--r-- | drivers/misc/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/misc/Makefile | 1 | ||||
| -rw-r--r-- | drivers/misc/mic/Kconfig | 19 | ||||
| -rw-r--r-- | drivers/misc/mic/Makefile | 5 | ||||
| -rw-r--r-- | drivers/misc/mic/common/mic_device.h | 37 | ||||
| -rw-r--r-- | drivers/misc/mic/host/Makefile | 8 | ||||
| -rw-r--r-- | drivers/misc/mic/host/mic_device.h | 109 | ||||
| -rw-r--r-- | drivers/misc/mic/host/mic_main.c | 309 | ||||
| -rw-r--r-- | drivers/misc/mic/host/mic_sysfs.c | 97 | ||||
| -rw-r--r-- | drivers/misc/mic/host/mic_x100.c | 75 | ||||
| -rw-r--r-- | drivers/misc/mic/host/mic_x100.h | 47 |
11 files changed, 708 insertions, 0 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 8dacd4c9ee87..e760715bd9cb 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
| @@ -537,4 +537,5 @@ source "drivers/misc/carma/Kconfig" | |||
| 537 | source "drivers/misc/altera-stapl/Kconfig" | 537 | source "drivers/misc/altera-stapl/Kconfig" |
| 538 | source "drivers/misc/mei/Kconfig" | 538 | source "drivers/misc/mei/Kconfig" |
| 539 | source "drivers/misc/vmw_vmci/Kconfig" | 539 | source "drivers/misc/vmw_vmci/Kconfig" |
| 540 | source "drivers/misc/mic/Kconfig" | ||
| 540 | endmenu | 541 | endmenu |
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index c235d5b68311..0b7ea3ea8bb8 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
| @@ -53,3 +53,4 @@ obj-$(CONFIG_INTEL_MEI) += mei/ | |||
| 53 | obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/ | 53 | obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/ |
| 54 | obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o | 54 | obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o |
| 55 | obj-$(CONFIG_SRAM) += sram.o | 55 | obj-$(CONFIG_SRAM) += sram.o |
| 56 | obj-y += mic/ | ||
diff --git a/drivers/misc/mic/Kconfig b/drivers/misc/mic/Kconfig new file mode 100644 index 000000000000..aaefd0cf82a7 --- /dev/null +++ b/drivers/misc/mic/Kconfig | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | comment "Intel MIC Host Driver" | ||
| 2 | |||
| 3 | config INTEL_MIC_HOST | ||
| 4 | tristate "Intel MIC Host Driver" | ||
| 5 | depends on 64BIT && PCI | ||
| 6 | default N | ||
| 7 | help | ||
| 8 | This enables Host Driver support for the Intel Many Integrated | ||
| 9 | Core (MIC) family of PCIe form factor coprocessor devices that | ||
| 10 | run a 64 bit Linux OS. The driver manages card OS state and | ||
| 11 | enables communication between host and card. Intel MIC X100 | ||
| 12 | devices are currently supported. | ||
| 13 | |||
| 14 | If you are building a host kernel with an Intel MIC device then | ||
| 15 | say M (recommended) or Y, else say N. If unsure say N. | ||
| 16 | |||
| 17 | More information about the Intel MIC family as well as the Linux | ||
| 18 | OS and tools for MIC to use with this driver are available from | ||
| 19 | <http://software.intel.com/en-us/mic-developer>. | ||
diff --git a/drivers/misc/mic/Makefile b/drivers/misc/mic/Makefile new file mode 100644 index 000000000000..8e724212d94c --- /dev/null +++ b/drivers/misc/mic/Makefile | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | # | ||
| 2 | # Makefile - Intel MIC Linux driver. | ||
| 3 | # Copyright(c) 2013, Intel Corporation. | ||
| 4 | # | ||
| 5 | obj-$(CONFIG_INTEL_MIC_HOST) += host/ | ||
diff --git a/drivers/misc/mic/common/mic_device.h b/drivers/misc/mic/common/mic_device.h new file mode 100644 index 000000000000..f02262e1c9d3 --- /dev/null +++ b/drivers/misc/mic/common/mic_device.h | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | /* | ||
| 2 | * Intel MIC Platform Software Stack (MPSS) | ||
| 3 | * | ||
| 4 | * Copyright(c) 2013 Intel Corporation. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License, version 2, as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, but | ||
| 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | * General Public License for more details. | ||
| 14 | * | ||
| 15 | * The full GNU General Public License is included in this distribution in | ||
| 16 | * the file called "COPYING". | ||
| 17 | * | ||
| 18 | * Intel MIC driver. | ||
| 19 | * | ||
| 20 | */ | ||
| 21 | #ifndef __MIC_COMMON_DEVICE_H_ | ||
| 22 | #define __MIC_COMMON_DEVICE_H_ | ||
| 23 | |||
| 24 | /** | ||
| 25 | * struct mic_mw - MIC memory window | ||
| 26 | * | ||
| 27 | * @pa: Base physical address. | ||
| 28 | * @va: Base ioremap'd virtual address. | ||
| 29 | * @len: Size of the memory window. | ||
| 30 | */ | ||
| 31 | struct mic_mw { | ||
| 32 | phys_addr_t pa; | ||
| 33 | void __iomem *va; | ||
| 34 | resource_size_t len; | ||
| 35 | }; | ||
| 36 | |||
| 37 | #endif | ||
diff --git a/drivers/misc/mic/host/Makefile b/drivers/misc/mic/host/Makefile new file mode 100644 index 000000000000..93b9d25d2c88 --- /dev/null +++ b/drivers/misc/mic/host/Makefile | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | # | ||
| 2 | # Makefile - Intel MIC Linux driver. | ||
| 3 | # Copyright(c) 2013, Intel Corporation. | ||
| 4 | # | ||
| 5 | obj-$(CONFIG_INTEL_MIC_HOST) += mic_host.o | ||
| 6 | mic_host-objs := mic_main.o | ||
| 7 | mic_host-objs += mic_x100.o | ||
| 8 | mic_host-objs += mic_sysfs.o | ||
diff --git a/drivers/misc/mic/host/mic_device.h b/drivers/misc/mic/host/mic_device.h new file mode 100644 index 000000000000..6cd904cdfdf9 --- /dev/null +++ b/drivers/misc/mic/host/mic_device.h | |||
| @@ -0,0 +1,109 @@ | |||
| 1 | /* | ||
| 2 | * Intel MIC Platform Software Stack (MPSS) | ||
| 3 | * | ||
| 4 | * Copyright(c) 2013 Intel Corporation. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License, version 2, as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, but | ||
| 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | * General Public License for more details. | ||
| 14 | * | ||
| 15 | * The full GNU General Public License is included in this distribution in | ||
| 16 | * the file called "COPYING". | ||
| 17 | * | ||
| 18 | * Intel MIC Host driver. | ||
| 19 | * | ||
| 20 | */ | ||
| 21 | #ifndef _MIC_DEVICE_H_ | ||
| 22 | #define _MIC_DEVICE_H_ | ||
| 23 | |||
| 24 | /* The maximum number of MIC devices supported in a single host system. */ | ||
| 25 | #define MIC_MAX_NUM_DEVS 256 | ||
| 26 | |||
| 27 | /** | ||
| 28 | * enum mic_hw_family - The hardware family to which a device belongs. | ||
| 29 | */ | ||
| 30 | enum mic_hw_family { | ||
| 31 | MIC_FAMILY_X100 = 0, | ||
| 32 | MIC_FAMILY_UNKNOWN | ||
| 33 | }; | ||
| 34 | |||
| 35 | /** | ||
| 36 | * enum mic_stepping - MIC stepping ids. | ||
| 37 | */ | ||
| 38 | enum mic_stepping { | ||
| 39 | MIC_A0_STEP = 0x0, | ||
| 40 | MIC_B0_STEP = 0x10, | ||
| 41 | MIC_B1_STEP = 0x11, | ||
| 42 | MIC_C0_STEP = 0x20, | ||
| 43 | }; | ||
| 44 | |||
| 45 | /** | ||
| 46 | * struct mic_device - MIC device information for each card. | ||
| 47 | * | ||
| 48 | * @mmio: MMIO bar information. | ||
| 49 | * @aper: Aperture bar information. | ||
| 50 | * @family: The MIC family to which this device belongs. | ||
| 51 | * @ops: MIC HW specific operations. | ||
| 52 | * @id: The unique device id for this MIC device. | ||
| 53 | * @stepping: Stepping ID. | ||
| 54 | * @attr_group: Pointer to list of sysfs attribute groups. | ||
| 55 | * @sdev: Device for sysfs entries. | ||
| 56 | */ | ||
| 57 | struct mic_device { | ||
| 58 | struct mic_mw mmio; | ||
| 59 | struct mic_mw aper; | ||
| 60 | enum mic_hw_family family; | ||
| 61 | struct mic_hw_ops *ops; | ||
| 62 | int id; | ||
| 63 | enum mic_stepping stepping; | ||
| 64 | const struct attribute_group **attr_group; | ||
| 65 | struct device *sdev; | ||
| 66 | }; | ||
| 67 | |||
| 68 | /** | ||
| 69 | * struct mic_hw_ops - MIC HW specific operations. | ||
| 70 | * @aper_bar: Aperture bar resource number. | ||
| 71 | * @mmio_bar: MMIO bar resource number. | ||
| 72 | * @read_spad: Read from scratch pad register. | ||
| 73 | * @write_spad: Write to scratch pad register. | ||
| 74 | */ | ||
| 75 | struct mic_hw_ops { | ||
| 76 | u8 aper_bar; | ||
| 77 | u8 mmio_bar; | ||
| 78 | u32 (*read_spad)(struct mic_device *mdev, unsigned int idx); | ||
| 79 | void (*write_spad)(struct mic_device *mdev, unsigned int idx, u32 val); | ||
| 80 | }; | ||
| 81 | |||
| 82 | /** | ||
| 83 | * mic_mmio_read - read from an MMIO register. | ||
| 84 | * @mw: MMIO register base virtual address. | ||
| 85 | * @offset: register offset. | ||
| 86 | * | ||
| 87 | * RETURNS: register value. | ||
| 88 | */ | ||
| 89 | static inline u32 mic_mmio_read(struct mic_mw *mw, u32 offset) | ||
| 90 | { | ||
| 91 | return ioread32(mw->va + offset); | ||
| 92 | } | ||
| 93 | |||
| 94 | /** | ||
| 95 | * mic_mmio_write - write to an MMIO register. | ||
| 96 | * @mw: MMIO register base virtual address. | ||
| 97 | * @val: the data value to put into the register | ||
| 98 | * @offset: register offset. | ||
| 99 | * | ||
| 100 | * RETURNS: none. | ||
| 101 | */ | ||
| 102 | static inline void | ||
| 103 | mic_mmio_write(struct mic_mw *mw, u32 val, u32 offset) | ||
| 104 | { | ||
| 105 | iowrite32(val, mw->va + offset); | ||
| 106 | } | ||
| 107 | |||
| 108 | void mic_sysfs_init(struct mic_device *mdev); | ||
| 109 | #endif | ||
diff --git a/drivers/misc/mic/host/mic_main.c b/drivers/misc/mic/host/mic_main.c new file mode 100644 index 000000000000..228c96c04a03 --- /dev/null +++ b/drivers/misc/mic/host/mic_main.c | |||
| @@ -0,0 +1,309 @@ | |||
| 1 | /* | ||
| 2 | * Intel MIC Platform Software Stack (MPSS) | ||
| 3 | * | ||
| 4 | * Copyright(c) 2013 Intel Corporation. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License, version 2, as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, but | ||
| 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | * General Public License for more details. | ||
| 14 | * | ||
| 15 | * The full GNU General Public License is included in this distribution in | ||
| 16 | * the file called "COPYING". | ||
| 17 | * | ||
| 18 | * Intel MIC Host driver. | ||
| 19 | * | ||
| 20 | * Global TODO's across the driver to be added after initial base | ||
| 21 | * patches are accepted upstream: | ||
| 22 | * 1) Enable DMA support. | ||
| 23 | * 2) Enable per vring interrupt support. | ||
| 24 | */ | ||
| 25 | #include <linux/fs.h> | ||
| 26 | #include <linux/idr.h> | ||
| 27 | #include <linux/module.h> | ||
| 28 | #include <linux/pci.h> | ||
| 29 | |||
| 30 | #include "../common/mic_device.h" | ||
| 31 | #include "mic_device.h" | ||
| 32 | #include "mic_x100.h" | ||
| 33 | |||
| 34 | static const char mic_driver_name[] = "mic"; | ||
| 35 | |||
| 36 | static DEFINE_PCI_DEVICE_TABLE(mic_pci_tbl) = { | ||
| 37 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2250)}, | ||
| 38 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2251)}, | ||
| 39 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2252)}, | ||
| 40 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2253)}, | ||
| 41 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2254)}, | ||
| 42 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2255)}, | ||
| 43 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2256)}, | ||
| 44 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2257)}, | ||
| 45 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2258)}, | ||
| 46 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2259)}, | ||
| 47 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225a)}, | ||
| 48 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225b)}, | ||
| 49 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225c)}, | ||
| 50 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225d)}, | ||
| 51 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225e)}, | ||
| 52 | |||
| 53 | /* required last entry */ | ||
| 54 | { 0, } | ||
| 55 | }; | ||
| 56 | |||
| 57 | MODULE_DEVICE_TABLE(pci, mic_pci_tbl); | ||
| 58 | |||
| 59 | /* ID allocator for MIC devices */ | ||
| 60 | static struct ida g_mic_ida; | ||
| 61 | /* Class of MIC devices for sysfs accessibility. */ | ||
| 62 | static struct class *g_mic_class; | ||
| 63 | /* Base device node number for MIC devices */ | ||
| 64 | static dev_t g_mic_devno; | ||
| 65 | |||
| 66 | /** | ||
| 67 | * mic_ops_init: Initialize HW specific operation tables. | ||
| 68 | * | ||
| 69 | * @mdev: pointer to mic_device instance | ||
| 70 | * | ||
| 71 | * returns none. | ||
| 72 | */ | ||
| 73 | static void mic_ops_init(struct mic_device *mdev) | ||
| 74 | { | ||
| 75 | switch (mdev->family) { | ||
| 76 | case MIC_FAMILY_X100: | ||
| 77 | mdev->ops = &mic_x100_ops; | ||
| 78 | break; | ||
| 79 | default: | ||
| 80 | break; | ||
| 81 | } | ||
| 82 | } | ||
| 83 | |||
| 84 | /** | ||
| 85 | * mic_get_family - Determine hardware family to which this MIC belongs. | ||
| 86 | * | ||
| 87 | * @pdev: The pci device structure | ||
| 88 | * | ||
| 89 | * returns family. | ||
| 90 | */ | ||
| 91 | static enum mic_hw_family mic_get_family(struct pci_dev *pdev) | ||
| 92 | { | ||
| 93 | enum mic_hw_family family; | ||
| 94 | |||
| 95 | switch (pdev->device) { | ||
| 96 | case MIC_X100_PCI_DEVICE_2250: | ||
| 97 | case MIC_X100_PCI_DEVICE_2251: | ||
| 98 | case MIC_X100_PCI_DEVICE_2252: | ||
| 99 | case MIC_X100_PCI_DEVICE_2253: | ||
| 100 | case MIC_X100_PCI_DEVICE_2254: | ||
| 101 | case MIC_X100_PCI_DEVICE_2255: | ||
| 102 | case MIC_X100_PCI_DEVICE_2256: | ||
| 103 | case MIC_X100_PCI_DEVICE_2257: | ||
| 104 | case MIC_X100_PCI_DEVICE_2258: | ||
| 105 | case MIC_X100_PCI_DEVICE_2259: | ||
| 106 | case MIC_X100_PCI_DEVICE_225a: | ||
| 107 | case MIC_X100_PCI_DEVICE_225b: | ||
| 108 | case MIC_X100_PCI_DEVICE_225c: | ||
| 109 | case MIC_X100_PCI_DEVICE_225d: | ||
| 110 | case MIC_X100_PCI_DEVICE_225e: | ||
| 111 | family = MIC_FAMILY_X100; | ||
| 112 | break; | ||
| 113 | default: | ||
| 114 | family = MIC_FAMILY_UNKNOWN; | ||
| 115 | break; | ||
| 116 | } | ||
| 117 | return family; | ||
| 118 | } | ||
| 119 | |||
| 120 | /** | ||
| 121 | * mic_device_init - Allocates and initializes the MIC device structure | ||
| 122 | * | ||
| 123 | * @mdev: pointer to mic_device instance | ||
| 124 | * @pdev: The pci device structure | ||
| 125 | * | ||
| 126 | * returns none. | ||
| 127 | */ | ||
| 128 | static void | ||
| 129 | mic_device_init(struct mic_device *mdev, struct pci_dev *pdev) | ||
| 130 | { | ||
| 131 | mdev->family = mic_get_family(pdev); | ||
| 132 | mdev->stepping = pdev->revision; | ||
| 133 | mic_ops_init(mdev); | ||
| 134 | mic_sysfs_init(mdev); | ||
| 135 | } | ||
| 136 | |||
| 137 | /** | ||
| 138 | * mic_probe - Device Initialization Routine | ||
| 139 | * | ||
| 140 | * @pdev: PCI device structure | ||
| 141 | * @ent: entry in mic_pci_tbl | ||
| 142 | * | ||
| 143 | * returns 0 on success, < 0 on failure. | ||
| 144 | */ | ||
| 145 | static int mic_probe(struct pci_dev *pdev, | ||
| 146 | const struct pci_device_id *ent) | ||
| 147 | { | ||
| 148 | int rc; | ||
| 149 | struct mic_device *mdev; | ||
| 150 | |||
| 151 | mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); | ||
| 152 | if (!mdev) { | ||
| 153 | rc = -ENOMEM; | ||
| 154 | dev_err(&pdev->dev, "mdev kmalloc failed rc %d\n", rc); | ||
| 155 | goto mdev_alloc_fail; | ||
| 156 | } | ||
| 157 | mdev->id = ida_simple_get(&g_mic_ida, 0, MIC_MAX_NUM_DEVS, GFP_KERNEL); | ||
| 158 | if (mdev->id < 0) { | ||
| 159 | rc = mdev->id; | ||
| 160 | dev_err(&pdev->dev, "ida_simple_get failed rc %d\n", rc); | ||
| 161 | goto ida_fail; | ||
| 162 | } | ||
| 163 | |||
| 164 | mic_device_init(mdev, pdev); | ||
| 165 | |||
| 166 | rc = pci_enable_device(pdev); | ||
| 167 | if (rc) { | ||
| 168 | dev_err(&pdev->dev, "failed to enable pci device.\n"); | ||
| 169 | goto ida_remove; | ||
| 170 | } | ||
| 171 | |||
| 172 | pci_set_master(pdev); | ||
| 173 | |||
| 174 | rc = pci_request_regions(pdev, mic_driver_name); | ||
| 175 | if (rc) { | ||
| 176 | dev_err(&pdev->dev, "failed to get pci regions.\n"); | ||
| 177 | goto disable_device; | ||
| 178 | } | ||
| 179 | |||
| 180 | rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); | ||
| 181 | if (rc) { | ||
| 182 | dev_err(&pdev->dev, "Cannot set DMA mask\n"); | ||
| 183 | goto release_regions; | ||
| 184 | } | ||
| 185 | |||
| 186 | mdev->mmio.pa = pci_resource_start(pdev, mdev->ops->mmio_bar); | ||
| 187 | mdev->mmio.len = pci_resource_len(pdev, mdev->ops->mmio_bar); | ||
| 188 | mdev->mmio.va = pci_ioremap_bar(pdev, mdev->ops->mmio_bar); | ||
| 189 | if (!mdev->mmio.va) { | ||
| 190 | dev_err(&pdev->dev, "Cannot remap MMIO BAR\n"); | ||
| 191 | rc = -EIO; | ||
| 192 | goto release_regions; | ||
| 193 | } | ||
| 194 | |||
| 195 | mdev->aper.pa = pci_resource_start(pdev, mdev->ops->aper_bar); | ||
| 196 | mdev->aper.len = pci_resource_len(pdev, mdev->ops->aper_bar); | ||
| 197 | mdev->aper.va = ioremap_wc(mdev->aper.pa, mdev->aper.len); | ||
| 198 | if (!mdev->aper.va) { | ||
| 199 | dev_err(&pdev->dev, "Cannot remap Aperture BAR\n"); | ||
| 200 | rc = -EIO; | ||
| 201 | goto unmap_mmio; | ||
| 202 | } | ||
| 203 | |||
| 204 | pci_set_drvdata(pdev, mdev); | ||
| 205 | |||
| 206 | mdev->sdev = device_create_with_groups(g_mic_class, &pdev->dev, | ||
| 207 | MKDEV(MAJOR(g_mic_devno), mdev->id), NULL, | ||
| 208 | mdev->attr_group, "mic%d", mdev->id); | ||
| 209 | if (IS_ERR(mdev->sdev)) { | ||
| 210 | rc = PTR_ERR(mdev->sdev); | ||
| 211 | dev_err(&pdev->dev, | ||
| 212 | "device_create_with_groups failed rc %d\n", rc); | ||
| 213 | goto unmap_aper; | ||
| 214 | } | ||
| 215 | return 0; | ||
| 216 | unmap_aper: | ||
| 217 | iounmap(mdev->aper.va); | ||
| 218 | unmap_mmio: | ||
| 219 | iounmap(mdev->mmio.va); | ||
| 220 | release_regions: | ||
| 221 | pci_release_regions(pdev); | ||
| 222 | disable_device: | ||
| 223 | pci_disable_device(pdev); | ||
| 224 | ida_remove: | ||
| 225 | ida_simple_remove(&g_mic_ida, mdev->id); | ||
| 226 | ida_fail: | ||
| 227 | kfree(mdev); | ||
| 228 | mdev_alloc_fail: | ||
| 229 | dev_err(&pdev->dev, "Probe failed rc %d\n", rc); | ||
| 230 | return rc; | ||
| 231 | } | ||
| 232 | |||
| 233 | /** | ||
| 234 | * mic_remove - Device Removal Routine | ||
| 235 | * mic_remove is called by the PCI subsystem to alert the driver | ||
| 236 | * that it should release a PCI device. | ||
| 237 | * | ||
| 238 | * @pdev: PCI device structure | ||
| 239 | */ | ||
| 240 | static void mic_remove(struct pci_dev *pdev) | ||
| 241 | { | ||
| 242 | struct mic_device *mdev; | ||
| 243 | |||
| 244 | mdev = pci_get_drvdata(pdev); | ||
| 245 | if (!mdev) | ||
| 246 | return; | ||
| 247 | |||
| 248 | device_destroy(g_mic_class, MKDEV(MAJOR(g_mic_devno), mdev->id)); | ||
| 249 | iounmap(mdev->mmio.va); | ||
| 250 | iounmap(mdev->aper.va); | ||
| 251 | pci_release_regions(pdev); | ||
| 252 | pci_disable_device(pdev); | ||
| 253 | ida_simple_remove(&g_mic_ida, mdev->id); | ||
| 254 | kfree(mdev); | ||
| 255 | } | ||
| 256 | static struct pci_driver mic_driver = { | ||
| 257 | .name = mic_driver_name, | ||
| 258 | .id_table = mic_pci_tbl, | ||
| 259 | .probe = mic_probe, | ||
| 260 | .remove = mic_remove | ||
| 261 | }; | ||
| 262 | |||
| 263 | static int __init mic_init(void) | ||
| 264 | { | ||
| 265 | int ret; | ||
| 266 | |||
| 267 | ret = alloc_chrdev_region(&g_mic_devno, 0, | ||
| 268 | MIC_MAX_NUM_DEVS, mic_driver_name); | ||
| 269 | if (ret) { | ||
| 270 | pr_err("alloc_chrdev_region failed ret %d\n", ret); | ||
| 271 | goto error; | ||
| 272 | } | ||
| 273 | |||
| 274 | g_mic_class = class_create(THIS_MODULE, mic_driver_name); | ||
| 275 | if (IS_ERR(g_mic_class)) { | ||
| 276 | ret = PTR_ERR(g_mic_class); | ||
| 277 | pr_err("class_create failed ret %d\n", ret); | ||
| 278 | goto cleanup_chrdev; | ||
| 279 | } | ||
| 280 | |||
| 281 | ida_init(&g_mic_ida); | ||
| 282 | ret = pci_register_driver(&mic_driver); | ||
| 283 | if (ret) { | ||
| 284 | pr_err("pci_register_driver failed ret %d\n", ret); | ||
| 285 | goto class_destroy; | ||
| 286 | } | ||
| 287 | return ret; | ||
| 288 | class_destroy: | ||
| 289 | class_destroy(g_mic_class); | ||
| 290 | cleanup_chrdev: | ||
| 291 | unregister_chrdev_region(g_mic_devno, MIC_MAX_NUM_DEVS); | ||
| 292 | error: | ||
| 293 | return ret; | ||
| 294 | } | ||
| 295 | |||
| 296 | static void __exit mic_exit(void) | ||
| 297 | { | ||
| 298 | pci_unregister_driver(&mic_driver); | ||
| 299 | ida_destroy(&g_mic_ida); | ||
| 300 | class_destroy(g_mic_class); | ||
| 301 | unregister_chrdev_region(g_mic_devno, MIC_MAX_NUM_DEVS); | ||
| 302 | } | ||
| 303 | |||
| 304 | module_init(mic_init); | ||
| 305 | module_exit(mic_exit); | ||
| 306 | |||
| 307 | MODULE_AUTHOR("Intel Corporation"); | ||
| 308 | MODULE_DESCRIPTION("Intel(R) MIC X100 Host driver"); | ||
| 309 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/misc/mic/host/mic_sysfs.c b/drivers/misc/mic/host/mic_sysfs.c new file mode 100644 index 000000000000..972c18255263 --- /dev/null +++ b/drivers/misc/mic/host/mic_sysfs.c | |||
| @@ -0,0 +1,97 @@ | |||
| 1 | /* | ||
| 2 | * Intel MIC Platform Software Stack (MPSS) | ||
| 3 | * | ||
| 4 | * Copyright(c) 2013 Intel Corporation. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License, version 2, as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, but | ||
| 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | * General Public License for more details. | ||
| 14 | * | ||
| 15 | * The full GNU General Public License is included in this distribution in | ||
| 16 | * the file called "COPYING". | ||
| 17 | * | ||
| 18 | * Intel MIC Host driver. | ||
| 19 | * | ||
| 20 | */ | ||
| 21 | #include <linux/pci.h> | ||
| 22 | |||
| 23 | #include "../common/mic_device.h" | ||
| 24 | #include "mic_device.h" | ||
| 25 | |||
| 26 | static ssize_t | ||
| 27 | mic_show_family(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 28 | { | ||
| 29 | static const char x100[] = "x100"; | ||
| 30 | static const char unknown[] = "Unknown"; | ||
| 31 | const char *card = NULL; | ||
| 32 | struct mic_device *mdev = dev_get_drvdata(dev->parent); | ||
| 33 | |||
| 34 | if (!mdev) | ||
| 35 | return -EINVAL; | ||
| 36 | |||
| 37 | switch (mdev->family) { | ||
| 38 | case MIC_FAMILY_X100: | ||
| 39 | card = x100; | ||
| 40 | break; | ||
| 41 | default: | ||
| 42 | card = unknown; | ||
| 43 | break; | ||
| 44 | } | ||
| 45 | return scnprintf(buf, PAGE_SIZE, "%s\n", card); | ||
| 46 | } | ||
| 47 | static DEVICE_ATTR(family, S_IRUGO, mic_show_family, NULL); | ||
| 48 | |||
| 49 | static ssize_t | ||
| 50 | mic_show_stepping(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 51 | { | ||
| 52 | struct mic_device *mdev = dev_get_drvdata(dev->parent); | ||
| 53 | char *string = "??"; | ||
| 54 | |||
| 55 | if (!mdev) | ||
| 56 | return -EINVAL; | ||
| 57 | |||
| 58 | switch (mdev->stepping) { | ||
| 59 | case MIC_A0_STEP: | ||
| 60 | string = "A0"; | ||
| 61 | break; | ||
| 62 | case MIC_B0_STEP: | ||
| 63 | string = "B0"; | ||
| 64 | break; | ||
| 65 | case MIC_B1_STEP: | ||
| 66 | string = "B1"; | ||
| 67 | break; | ||
| 68 | case MIC_C0_STEP: | ||
| 69 | string = "C0"; | ||
| 70 | break; | ||
| 71 | default: | ||
| 72 | break; | ||
| 73 | } | ||
| 74 | return scnprintf(buf, PAGE_SIZE, "%s\n", string); | ||
| 75 | } | ||
| 76 | static DEVICE_ATTR(stepping, S_IRUGO, mic_show_stepping, NULL); | ||
| 77 | |||
| 78 | static struct attribute *mic_default_attrs[] = { | ||
| 79 | &dev_attr_family.attr, | ||
| 80 | &dev_attr_stepping.attr, | ||
| 81 | |||
| 82 | NULL | ||
| 83 | }; | ||
| 84 | |||
| 85 | static struct attribute_group mic_attr_group = { | ||
| 86 | .attrs = mic_default_attrs, | ||
| 87 | }; | ||
| 88 | |||
| 89 | static const struct attribute_group *__mic_attr_group[] = { | ||
| 90 | &mic_attr_group, | ||
| 91 | NULL | ||
| 92 | }; | ||
| 93 | |||
| 94 | void mic_sysfs_init(struct mic_device *mdev) | ||
| 95 | { | ||
| 96 | mdev->attr_group = __mic_attr_group; | ||
| 97 | } | ||
diff --git a/drivers/misc/mic/host/mic_x100.c b/drivers/misc/mic/host/mic_x100.c new file mode 100644 index 000000000000..da481b173af9 --- /dev/null +++ b/drivers/misc/mic/host/mic_x100.c | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | /* | ||
| 2 | * Intel MIC Platform Software Stack (MPSS) | ||
| 3 | * | ||
| 4 | * Copyright(c) 2013 Intel Corporation. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License, version 2, as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, but | ||
| 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | * General Public License for more details. | ||
| 14 | * | ||
| 15 | * The full GNU General Public License is included in this distribution in | ||
| 16 | * the file called "COPYING". | ||
| 17 | * | ||
| 18 | * Intel MIC Host driver. | ||
| 19 | * | ||
| 20 | */ | ||
| 21 | #include <linux/fs.h> | ||
| 22 | #include <linux/pci.h> | ||
| 23 | |||
| 24 | #include "../common/mic_device.h" | ||
| 25 | #include "mic_device.h" | ||
| 26 | #include "mic_x100.h" | ||
| 27 | |||
| 28 | /** | ||
| 29 | * mic_x100_write_spad - write to the scratchpad register | ||
| 30 | * @mdev: pointer to mic_device instance | ||
| 31 | * @idx: index to the scratchpad register, 0 based | ||
| 32 | * @val: the data value to put into the register | ||
| 33 | * | ||
| 34 | * This function allows writing of a 32bit value to the indexed scratchpad | ||
| 35 | * register. | ||
| 36 | * | ||
| 37 | * RETURNS: none. | ||
| 38 | */ | ||
| 39 | static void | ||
| 40 | mic_x100_write_spad(struct mic_device *mdev, unsigned int idx, u32 val) | ||
| 41 | { | ||
| 42 | dev_dbg(mdev->sdev->parent, "Writing 0x%x to scratch pad index %d\n", | ||
| 43 | val, idx); | ||
| 44 | mic_mmio_write(&mdev->mmio, val, | ||
| 45 | MIC_X100_SBOX_BASE_ADDRESS + | ||
| 46 | MIC_X100_SBOX_SPAD0 + idx * 4); | ||
| 47 | } | ||
| 48 | |||
| 49 | /** | ||
| 50 | * mic_x100_read_spad - read from the scratchpad register | ||
| 51 | * @mdev: pointer to mic_device instance | ||
| 52 | * @idx: index to scratchpad register, 0 based | ||
| 53 | * | ||
| 54 | * This function allows reading of the 32bit scratchpad register. | ||
| 55 | * | ||
| 56 | * RETURNS: An appropriate -ERRNO error value on error, or zero for success. | ||
| 57 | */ | ||
| 58 | static u32 | ||
| 59 | mic_x100_read_spad(struct mic_device *mdev, unsigned int idx) | ||
| 60 | { | ||
| 61 | u32 val = mic_mmio_read(&mdev->mmio, | ||
| 62 | MIC_X100_SBOX_BASE_ADDRESS + | ||
| 63 | MIC_X100_SBOX_SPAD0 + idx * 4); | ||
| 64 | |||
| 65 | dev_dbg(mdev->sdev->parent, | ||
| 66 | "Reading 0x%x from scratch pad index %d\n", val, idx); | ||
| 67 | return val; | ||
| 68 | } | ||
| 69 | |||
| 70 | struct mic_hw_ops mic_x100_ops = { | ||
| 71 | .aper_bar = MIC_X100_APER_BAR, | ||
| 72 | .mmio_bar = MIC_X100_MMIO_BAR, | ||
| 73 | .read_spad = mic_x100_read_spad, | ||
| 74 | .write_spad = mic_x100_write_spad, | ||
| 75 | }; | ||
diff --git a/drivers/misc/mic/host/mic_x100.h b/drivers/misc/mic/host/mic_x100.h new file mode 100644 index 000000000000..1f4e6305dcf5 --- /dev/null +++ b/drivers/misc/mic/host/mic_x100.h | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | /* | ||
| 2 | * Intel MIC Platform Software Stack (MPSS) | ||
| 3 | * | ||
| 4 | * Copyright(c) 2013 Intel Corporation. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License, version 2, as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, but | ||
| 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | * General Public License for more details. | ||
| 14 | * | ||
| 15 | * The full GNU General Public License is included in this distribution in | ||
| 16 | * the file called "COPYING". | ||
| 17 | * | ||
| 18 | * Intel MIC Host driver. | ||
| 19 | * | ||
| 20 | */ | ||
| 21 | #ifndef _MIC_X100_HW_H_ | ||
| 22 | #define _MIC_X100_HW_H_ | ||
| 23 | |||
| 24 | #define MIC_X100_PCI_DEVICE_2250 0x2250 | ||
| 25 | #define MIC_X100_PCI_DEVICE_2251 0x2251 | ||
| 26 | #define MIC_X100_PCI_DEVICE_2252 0x2252 | ||
| 27 | #define MIC_X100_PCI_DEVICE_2253 0x2253 | ||
| 28 | #define MIC_X100_PCI_DEVICE_2254 0x2254 | ||
| 29 | #define MIC_X100_PCI_DEVICE_2255 0x2255 | ||
| 30 | #define MIC_X100_PCI_DEVICE_2256 0x2256 | ||
| 31 | #define MIC_X100_PCI_DEVICE_2257 0x2257 | ||
| 32 | #define MIC_X100_PCI_DEVICE_2258 0x2258 | ||
| 33 | #define MIC_X100_PCI_DEVICE_2259 0x2259 | ||
| 34 | #define MIC_X100_PCI_DEVICE_225a 0x225a | ||
| 35 | #define MIC_X100_PCI_DEVICE_225b 0x225b | ||
| 36 | #define MIC_X100_PCI_DEVICE_225c 0x225c | ||
| 37 | #define MIC_X100_PCI_DEVICE_225d 0x225d | ||
| 38 | #define MIC_X100_PCI_DEVICE_225e 0x225e | ||
| 39 | |||
| 40 | #define MIC_X100_APER_BAR 0 | ||
| 41 | #define MIC_X100_MMIO_BAR 4 | ||
| 42 | |||
| 43 | #define MIC_X100_SBOX_BASE_ADDRESS 0x00010000 | ||
| 44 | #define MIC_X100_SBOX_SPAD0 0x0000AB20 | ||
| 45 | extern struct mic_hw_ops mic_x100_ops; | ||
| 46 | |||
| 47 | #endif | ||
