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 v3.13-rc4 256 lines 6.4 kB view raw
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 * Disclaimer: The codes contained in these modules may be specific to 19 * the Intel Software Development Platform codenamed: Knights Ferry, and 20 * the Intel product codenamed: Knights Corner, and are not backward 21 * compatible with other Intel products. Additionally, Intel will NOT 22 * support the codes or instruction set in future products. 23 * 24 * Intel MIC Card driver. 25 * 26 */ 27#include <linux/module.h> 28#include <linux/pci.h> 29#include <linux/platform_device.h> 30 31#include "../common/mic_dev.h" 32#include "mic_device.h" 33#include "mic_x100.h" 34 35static const char mic_driver_name[] = "mic"; 36 37static struct mic_driver g_drv; 38 39/** 40 * mic_read_spad - read from the scratchpad register 41 * @mdev: pointer to mic_device instance 42 * @idx: index to scratchpad register, 0 based 43 * 44 * This function allows reading of the 32bit scratchpad register. 45 * 46 * RETURNS: An appropriate -ERRNO error value on error, or zero for success. 47 */ 48u32 mic_read_spad(struct mic_device *mdev, unsigned int idx) 49{ 50 return mic_mmio_read(&mdev->mmio, 51 MIC_X100_SBOX_BASE_ADDRESS + 52 MIC_X100_SBOX_SPAD0 + idx * 4); 53} 54 55/** 56 * __mic_send_intr - Send interrupt to Host. 57 * @mdev: pointer to mic_device instance 58 * @doorbell: Doorbell number. 59 */ 60void mic_send_intr(struct mic_device *mdev, int doorbell) 61{ 62 struct mic_mw *mw = &mdev->mmio; 63 64 if (doorbell > MIC_X100_MAX_DOORBELL_IDX) 65 return; 66 /* Ensure that the interrupt is ordered w.r.t previous stores. */ 67 wmb(); 68 mic_mmio_write(mw, MIC_X100_SBOX_SDBIC0_DBREQ_BIT, 69 MIC_X100_SBOX_BASE_ADDRESS + 70 (MIC_X100_SBOX_SDBIC0 + (4 * doorbell))); 71} 72 73/** 74 * mic_ack_interrupt - Device specific interrupt handling. 75 * @mdev: pointer to mic_device instance 76 * 77 * Returns: bitmask of doorbell events triggered. 78 */ 79u32 mic_ack_interrupt(struct mic_device *mdev) 80{ 81 return 0; 82} 83 84static inline int mic_get_sbox_irq(int db) 85{ 86 return MIC_X100_IRQ_BASE + db; 87} 88 89static inline int mic_get_rdmasr_irq(int index) 90{ 91 return MIC_X100_RDMASR_IRQ_BASE + index; 92} 93 94/** 95 * mic_hw_intr_init - Initialize h/w specific interrupt 96 * information. 97 * @mdrv: pointer to mic_driver 98 */ 99void mic_hw_intr_init(struct mic_driver *mdrv) 100{ 101 mdrv->intr_info.num_intr = MIC_X100_NUM_SBOX_IRQ + 102 MIC_X100_NUM_RDMASR_IRQ; 103} 104 105/** 106 * mic_db_to_irq - Retrieve irq number corresponding to a doorbell. 107 * @mdrv: pointer to mic_driver 108 * @db: The doorbell obtained for which the irq is needed. Doorbell 109 * may correspond to an sbox doorbell or an rdmasr index. 110 * 111 * Returns the irq corresponding to the doorbell. 112 */ 113int mic_db_to_irq(struct mic_driver *mdrv, int db) 114{ 115 int rdmasr_index; 116 if (db < MIC_X100_NUM_SBOX_IRQ) { 117 return mic_get_sbox_irq(db); 118 } else { 119 rdmasr_index = db - MIC_X100_NUM_SBOX_IRQ + 120 MIC_X100_RDMASR_IRQ_BASE; 121 return mic_get_rdmasr_irq(rdmasr_index); 122 } 123} 124 125/* 126 * mic_card_map - Allocate virtual address for a remote memory region. 127 * @mdev: pointer to mic_device instance. 128 * @addr: Remote DMA address. 129 * @size: Size of the region. 130 * 131 * Returns: Virtual address backing the remote memory region. 132 */ 133void __iomem * 134mic_card_map(struct mic_device *mdev, dma_addr_t addr, size_t size) 135{ 136 return ioremap(addr, size); 137} 138 139/* 140 * mic_card_unmap - Unmap the virtual address for a remote memory region. 141 * @mdev: pointer to mic_device instance. 142 * @addr: Virtual address for remote memory region. 143 * 144 * Returns: None. 145 */ 146void mic_card_unmap(struct mic_device *mdev, void __iomem *addr) 147{ 148 iounmap(addr); 149} 150 151static int __init mic_probe(struct platform_device *pdev) 152{ 153 struct mic_driver *mdrv = &g_drv; 154 struct mic_device *mdev = &mdrv->mdev; 155 int rc = 0; 156 157 mdrv->dev = &pdev->dev; 158 snprintf(mdrv->name, sizeof(mic_driver_name), mic_driver_name); 159 160 mdev->mmio.pa = MIC_X100_MMIO_BASE; 161 mdev->mmio.len = MIC_X100_MMIO_LEN; 162 mdev->mmio.va = ioremap(MIC_X100_MMIO_BASE, MIC_X100_MMIO_LEN); 163 if (!mdev->mmio.va) { 164 dev_err(&pdev->dev, "Cannot remap MMIO BAR\n"); 165 rc = -EIO; 166 goto done; 167 } 168 mic_hw_intr_init(mdrv); 169 rc = mic_driver_init(mdrv); 170 if (rc) { 171 dev_err(&pdev->dev, "mic_driver_init failed rc %d\n", rc); 172 goto iounmap; 173 } 174done: 175 return rc; 176iounmap: 177 iounmap(mdev->mmio.va); 178 return rc; 179} 180 181static int mic_remove(struct platform_device *pdev) 182{ 183 struct mic_driver *mdrv = &g_drv; 184 struct mic_device *mdev = &mdrv->mdev; 185 186 mic_driver_uninit(mdrv); 187 iounmap(mdev->mmio.va); 188 return 0; 189} 190 191static void mic_platform_shutdown(struct platform_device *pdev) 192{ 193 mic_remove(pdev); 194} 195 196static struct platform_device mic_platform_dev = { 197 .name = mic_driver_name, 198 .id = 0, 199 .num_resources = 0, 200}; 201 202static struct platform_driver __refdata mic_platform_driver = { 203 .probe = mic_probe, 204 .remove = mic_remove, 205 .shutdown = mic_platform_shutdown, 206 .driver = { 207 .name = mic_driver_name, 208 .owner = THIS_MODULE, 209 }, 210}; 211 212static int __init mic_init(void) 213{ 214 int ret; 215 struct cpuinfo_x86 *c = &cpu_data(0); 216 217 if (!(c->x86 == 11 && c->x86_model == 1)) { 218 ret = -ENODEV; 219 pr_err("%s not running on X100 ret %d\n", __func__, ret); 220 goto done; 221 } 222 223 mic_init_card_debugfs(); 224 ret = platform_device_register(&mic_platform_dev); 225 if (ret) { 226 pr_err("platform_device_register ret %d\n", ret); 227 goto cleanup_debugfs; 228 } 229 ret = platform_driver_register(&mic_platform_driver); 230 if (ret) { 231 pr_err("platform_driver_register ret %d\n", ret); 232 goto device_unregister; 233 } 234 return ret; 235 236device_unregister: 237 platform_device_unregister(&mic_platform_dev); 238cleanup_debugfs: 239 mic_exit_card_debugfs(); 240done: 241 return ret; 242} 243 244static void __exit mic_exit(void) 245{ 246 platform_driver_unregister(&mic_platform_driver); 247 platform_device_unregister(&mic_platform_dev); 248 mic_exit_card_debugfs(); 249} 250 251module_init(mic_init); 252module_exit(mic_exit); 253 254MODULE_AUTHOR("Intel Corporation"); 255MODULE_DESCRIPTION("Intel(R) MIC X100 Card driver"); 256MODULE_LICENSE("GPL v2");