root/drivers/misc/mic/card/mic_x100.c

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

DEFINITIONS

This source file includes following definitions.
  1. mic_read_spad
  2. mic_send_intr
  3. mic_x100_send_sbox_intr
  4. mic_x100_send_rdmasr_intr
  5. mic_ack_interrupt
  6. mic_get_sbox_irq
  7. mic_get_rdmasr_irq
  8. mic_send_p2p_intr
  9. mic_hw_intr_init
  10. mic_db_to_irq
  11. mic_card_map
  12. mic_card_unmap
  13. mbdev_to_mdrv
  14. _mic_request_threaded_irq
  15. _mic_free_irq
  16. _mic_ack_interrupt
  17. mic_probe
  18. mic_remove
  19. mic_platform_shutdown
  20. mic_init
  21. mic_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Intel MIC Platform Software Stack (MPSS)
   4  *
   5  * Copyright(c) 2013 Intel Corporation.
   6  *
   7  * Disclaimer: The codes contained in these modules may be specific to
   8  * the Intel Software Development Platform codenamed: Knights Ferry, and
   9  * the Intel product codenamed: Knights Corner, and are not backward
  10  * compatible with other Intel products. Additionally, Intel will NOT
  11  * support the codes or instruction set in future products.
  12  *
  13  * Intel MIC Card driver.
  14  */
  15 #include <linux/module.h>
  16 #include <linux/pci.h>
  17 #include <linux/platform_device.h>
  18 
  19 #include "../common/mic_dev.h"
  20 #include "mic_device.h"
  21 #include "mic_x100.h"
  22 
  23 static const char mic_driver_name[] = "mic";
  24 
  25 static struct mic_driver g_drv;
  26 
  27 /**
  28  * mic_read_spad - read from the scratchpad register
  29  * @mdev: pointer to mic_device instance
  30  * @idx: index to scratchpad register, 0 based
  31  *
  32  * This function allows reading of the 32bit scratchpad register.
  33  *
  34  * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
  35  */
  36 u32 mic_read_spad(struct mic_device *mdev, unsigned int idx)
  37 {
  38         return mic_mmio_read(&mdev->mmio,
  39                 MIC_X100_SBOX_BASE_ADDRESS +
  40                 MIC_X100_SBOX_SPAD0 + idx * 4);
  41 }
  42 
  43 /**
  44  * __mic_send_intr - Send interrupt to Host.
  45  * @mdev: pointer to mic_device instance
  46  * @doorbell: Doorbell number.
  47  */
  48 void mic_send_intr(struct mic_device *mdev, int doorbell)
  49 {
  50         struct mic_mw *mw = &mdev->mmio;
  51 
  52         if (doorbell > MIC_X100_MAX_DOORBELL_IDX)
  53                 return;
  54         /* Ensure that the interrupt is ordered w.r.t previous stores. */
  55         wmb();
  56         mic_mmio_write(mw, MIC_X100_SBOX_SDBIC0_DBREQ_BIT,
  57                        MIC_X100_SBOX_BASE_ADDRESS +
  58                        (MIC_X100_SBOX_SDBIC0 + (4 * doorbell)));
  59 }
  60 
  61 /*
  62  * mic_x100_send_sbox_intr - Send an MIC_X100_SBOX interrupt to MIC.
  63  */
  64 static void mic_x100_send_sbox_intr(struct mic_mw *mw, int doorbell)
  65 {
  66         u64 apic_icr_offset = MIC_X100_SBOX_APICICR0 + doorbell * 8;
  67         u32 apicicr_low = mic_mmio_read(mw, MIC_X100_SBOX_BASE_ADDRESS +
  68                                         apic_icr_offset);
  69 
  70         /* for MIC we need to make sure we "hit" the send_icr bit (13) */
  71         apicicr_low = (apicicr_low | (1 << 13));
  72         /*
  73          * Ensure that the interrupt is ordered w.r.t. previous stores
  74          * to main memory. Fence instructions are not implemented in X100
  75          * since execution is in order but a compiler barrier is still
  76          * required.
  77          */
  78         wmb();
  79         mic_mmio_write(mw, apicicr_low,
  80                        MIC_X100_SBOX_BASE_ADDRESS + apic_icr_offset);
  81 }
  82 
  83 static void mic_x100_send_rdmasr_intr(struct mic_mw *mw, int doorbell)
  84 {
  85         int rdmasr_offset = MIC_X100_SBOX_RDMASR0 + (doorbell << 2);
  86         /*
  87          * Ensure that the interrupt is ordered w.r.t. previous stores
  88          * to main memory. Fence instructions are not implemented in X100
  89          * since execution is in order but a compiler barrier is still
  90          * required.
  91          */
  92         wmb();
  93         mic_mmio_write(mw, 0, MIC_X100_SBOX_BASE_ADDRESS + rdmasr_offset);
  94 }
  95 
  96 /**
  97  * mic_ack_interrupt - Device specific interrupt handling.
  98  * @mdev: pointer to mic_device instance
  99  *
 100  * Returns: bitmask of doorbell events triggered.
 101  */
 102 u32 mic_ack_interrupt(struct mic_device *mdev)
 103 {
 104         return 0;
 105 }
 106 
 107 static inline int mic_get_sbox_irq(int db)
 108 {
 109         return MIC_X100_IRQ_BASE + db;
 110 }
 111 
 112 static inline int mic_get_rdmasr_irq(int index)
 113 {
 114         return  MIC_X100_RDMASR_IRQ_BASE + index;
 115 }
 116 
 117 void mic_send_p2p_intr(int db, struct mic_mw *mw)
 118 {
 119         int rdmasr_index;
 120 
 121         if (db < MIC_X100_NUM_SBOX_IRQ) {
 122                 mic_x100_send_sbox_intr(mw, db);
 123         } else {
 124                 rdmasr_index = db - MIC_X100_NUM_SBOX_IRQ;
 125                 mic_x100_send_rdmasr_intr(mw, rdmasr_index);
 126         }
 127 }
 128 
 129 /**
 130  * mic_hw_intr_init - Initialize h/w specific interrupt
 131  * information.
 132  * @mdrv: pointer to mic_driver
 133  */
 134 void mic_hw_intr_init(struct mic_driver *mdrv)
 135 {
 136         mdrv->intr_info.num_intr = MIC_X100_NUM_SBOX_IRQ +
 137                                 MIC_X100_NUM_RDMASR_IRQ;
 138 }
 139 
 140 /**
 141  * mic_db_to_irq - Retrieve irq number corresponding to a doorbell.
 142  * @mdrv: pointer to mic_driver
 143  * @db: The doorbell obtained for which the irq is needed. Doorbell
 144  * may correspond to an sbox doorbell or an rdmasr index.
 145  *
 146  * Returns the irq corresponding to the doorbell.
 147  */
 148 int mic_db_to_irq(struct mic_driver *mdrv, int db)
 149 {
 150         int rdmasr_index;
 151 
 152         /*
 153          * The total number of doorbell interrupts on the card are 16. Indices
 154          * 0-8 falls in the SBOX category and 8-15 fall in the RDMASR category.
 155          */
 156         if (db < MIC_X100_NUM_SBOX_IRQ) {
 157                 return mic_get_sbox_irq(db);
 158         } else {
 159                 rdmasr_index = db - MIC_X100_NUM_SBOX_IRQ;
 160                 return mic_get_rdmasr_irq(rdmasr_index);
 161         }
 162 }
 163 
 164 /*
 165  * mic_card_map - Allocate virtual address for a remote memory region.
 166  * @mdev: pointer to mic_device instance.
 167  * @addr: Remote DMA address.
 168  * @size: Size of the region.
 169  *
 170  * Returns: Virtual address backing the remote memory region.
 171  */
 172 void __iomem *
 173 mic_card_map(struct mic_device *mdev, dma_addr_t addr, size_t size)
 174 {
 175         return ioremap(addr, size);
 176 }
 177 
 178 /*
 179  * mic_card_unmap - Unmap the virtual address for a remote memory region.
 180  * @mdev: pointer to mic_device instance.
 181  * @addr: Virtual address for remote memory region.
 182  *
 183  * Returns: None.
 184  */
 185 void mic_card_unmap(struct mic_device *mdev, void __iomem *addr)
 186 {
 187         iounmap(addr);
 188 }
 189 
 190 static inline struct mic_driver *mbdev_to_mdrv(struct mbus_device *mbdev)
 191 {
 192         return dev_get_drvdata(mbdev->dev.parent);
 193 }
 194 
 195 static struct mic_irq *
 196 _mic_request_threaded_irq(struct mbus_device *mbdev,
 197                           irq_handler_t handler, irq_handler_t thread_fn,
 198                           const char *name, void *data, int intr_src)
 199 {
 200         int rc = 0;
 201         unsigned int irq = intr_src;
 202         unsigned long cookie = irq;
 203 
 204         rc  = request_threaded_irq(irq, handler, thread_fn, 0, name, data);
 205         if (rc) {
 206                 dev_err(mbdev_to_mdrv(mbdev)->dev,
 207                         "request_threaded_irq failed rc = %d\n", rc);
 208                 return ERR_PTR(rc);
 209         }
 210         return (struct mic_irq *)cookie;
 211 }
 212 
 213 static void _mic_free_irq(struct mbus_device *mbdev,
 214                           struct mic_irq *cookie, void *data)
 215 {
 216         unsigned long irq = (unsigned long)cookie;
 217         free_irq(irq, data);
 218 }
 219 
 220 static void _mic_ack_interrupt(struct mbus_device *mbdev, int num)
 221 {
 222         mic_ack_interrupt(&mbdev_to_mdrv(mbdev)->mdev);
 223 }
 224 
 225 static struct mbus_hw_ops mbus_hw_ops = {
 226         .request_threaded_irq = _mic_request_threaded_irq,
 227         .free_irq = _mic_free_irq,
 228         .ack_interrupt = _mic_ack_interrupt,
 229 };
 230 
 231 static int __init mic_probe(struct platform_device *pdev)
 232 {
 233         struct mic_driver *mdrv = &g_drv;
 234         struct mic_device *mdev = &mdrv->mdev;
 235         int rc = 0;
 236 
 237         mdrv->dev = &pdev->dev;
 238         snprintf(mdrv->name, sizeof(mic_driver_name), mic_driver_name);
 239 
 240         /* FIXME: use dma_set_mask_and_coherent() and check result */
 241         dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
 242 
 243         mdev->mmio.pa = MIC_X100_MMIO_BASE;
 244         mdev->mmio.len = MIC_X100_MMIO_LEN;
 245         mdev->mmio.va = devm_ioremap(&pdev->dev, MIC_X100_MMIO_BASE,
 246                                      MIC_X100_MMIO_LEN);
 247         if (!mdev->mmio.va) {
 248                 dev_err(&pdev->dev, "Cannot remap MMIO BAR\n");
 249                 rc = -EIO;
 250                 goto done;
 251         }
 252         mic_hw_intr_init(mdrv);
 253         platform_set_drvdata(pdev, mdrv);
 254         mdrv->dma_mbdev = mbus_register_device(mdrv->dev, MBUS_DEV_DMA_MIC,
 255                                                NULL, &mbus_hw_ops, 0,
 256                                                mdrv->mdev.mmio.va);
 257         if (IS_ERR(mdrv->dma_mbdev)) {
 258                 rc = PTR_ERR(mdrv->dma_mbdev);
 259                 dev_err(&pdev->dev, "mbus_add_device failed rc %d\n", rc);
 260                 goto done;
 261         }
 262         rc = mic_driver_init(mdrv);
 263         if (rc) {
 264                 dev_err(&pdev->dev, "mic_driver_init failed rc %d\n", rc);
 265                 goto remove_dma;
 266         }
 267 done:
 268         return rc;
 269 remove_dma:
 270         mbus_unregister_device(mdrv->dma_mbdev);
 271         return rc;
 272 }
 273 
 274 static int mic_remove(struct platform_device *pdev)
 275 {
 276         struct mic_driver *mdrv = &g_drv;
 277 
 278         mic_driver_uninit(mdrv);
 279         mbus_unregister_device(mdrv->dma_mbdev);
 280         return 0;
 281 }
 282 
 283 static void mic_platform_shutdown(struct platform_device *pdev)
 284 {
 285         mic_remove(pdev);
 286 }
 287 
 288 static struct platform_driver __refdata mic_platform_driver = {
 289         .probe = mic_probe,
 290         .remove = mic_remove,
 291         .shutdown = mic_platform_shutdown,
 292         .driver         = {
 293                 .name   = mic_driver_name,
 294         },
 295 };
 296 
 297 static struct platform_device *mic_platform_dev;
 298 
 299 static int __init mic_init(void)
 300 {
 301         int ret;
 302         struct cpuinfo_x86 *c = &cpu_data(0);
 303 
 304         if (!(c->x86 == 11 && c->x86_model == 1)) {
 305                 ret = -ENODEV;
 306                 pr_err("%s not running on X100 ret %d\n", __func__, ret);
 307                 goto done;
 308         }
 309 
 310         request_module("mic_x100_dma");
 311         mic_init_card_debugfs();
 312 
 313         mic_platform_dev = platform_device_register_simple(mic_driver_name,
 314                                                            0, NULL, 0);
 315         ret = PTR_ERR_OR_ZERO(mic_platform_dev);
 316         if (ret) {
 317                 pr_err("platform_device_register_full ret %d\n", ret);
 318                 goto cleanup_debugfs;
 319         }
 320         ret = platform_driver_register(&mic_platform_driver);
 321         if (ret) {
 322                 pr_err("platform_driver_register ret %d\n", ret);
 323                 goto device_unregister;
 324         }
 325         return ret;
 326 
 327 device_unregister:
 328         platform_device_unregister(mic_platform_dev);
 329 cleanup_debugfs:
 330         mic_exit_card_debugfs();
 331 done:
 332         return ret;
 333 }
 334 
 335 static void __exit mic_exit(void)
 336 {
 337         platform_driver_unregister(&mic_platform_driver);
 338         platform_device_unregister(mic_platform_dev);
 339         mic_exit_card_debugfs();
 340 }
 341 
 342 module_init(mic_init);
 343 module_exit(mic_exit);
 344 
 345 MODULE_AUTHOR("Intel Corporation");
 346 MODULE_DESCRIPTION("Intel(R) MIC X100 Card driver");
 347 MODULE_LICENSE("GPL v2");

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