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

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

DEFINITIONS

This source file includes following definitions.
  1. mic_dp_init
  2. mic_dp_uninit
  3. mic_request_card_irq
  4. mic_free_card_irq
  5. mic_next_card_db
  6. mic_init_irq
  7. mic_uninit_irq
  8. scdev_to_mdrv
  9. ___mic_request_irq
  10. ___mic_free_irq
  11. ___mic_ack_interrupt
  12. ___mic_next_db
  13. ___mic_send_intr
  14. ___mic_send_p2p_intr
  15. ___mic_ioremap
  16. ___mic_iounmap
  17. vpdev_to_mdrv
  18. __mic_request_irq
  19. __mic_free_irq
  20. __mic_ack_interrupt
  21. __mic_next_db
  22. __mic_get_remote_dp
  23. __mic_send_intr
  24. __mic_ioremap
  25. __mic_iounmap
  26. mic_request_dma_chans
  27. mic_free_dma_chans
  28. mic_driver_init
  29. mic_driver_uninit

   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/interrupt.h>
  18 #include <linux/reboot.h>
  19 #include <linux/dmaengine.h>
  20 #include <linux/kmod.h>
  21 
  22 #include <linux/mic_common.h>
  23 #include "../common/mic_dev.h"
  24 #include "mic_device.h"
  25 
  26 static struct mic_driver *g_drv;
  27 
  28 static int __init mic_dp_init(void)
  29 {
  30         struct mic_driver *mdrv = g_drv;
  31         struct mic_device *mdev = &mdrv->mdev;
  32         struct mic_bootparam __iomem *bootparam;
  33         u64 lo, hi, dp_dma_addr;
  34         u32 magic;
  35 
  36         lo = mic_read_spad(&mdrv->mdev, MIC_DPLO_SPAD);
  37         hi = mic_read_spad(&mdrv->mdev, MIC_DPHI_SPAD);
  38 
  39         dp_dma_addr = lo | (hi << 32);
  40         mdrv->dp = mic_card_map(mdev, dp_dma_addr, MIC_DP_SIZE);
  41         if (!mdrv->dp) {
  42                 dev_err(mdrv->dev, "Cannot remap Aperture BAR\n");
  43                 return -ENOMEM;
  44         }
  45         bootparam = mdrv->dp;
  46         magic = ioread32(&bootparam->magic);
  47         if (MIC_MAGIC != magic) {
  48                 dev_err(mdrv->dev, "bootparam magic mismatch 0x%x\n", magic);
  49                 return -EIO;
  50         }
  51         return 0;
  52 }
  53 
  54 /* Uninitialize the device page */
  55 static void mic_dp_uninit(void)
  56 {
  57         mic_card_unmap(&g_drv->mdev, g_drv->dp);
  58 }
  59 
  60 /**
  61  * mic_request_card_irq - request an irq.
  62  *
  63  * @handler: interrupt handler passed to request_threaded_irq.
  64  * @thread_fn: thread fn. passed to request_threaded_irq.
  65  * @name: The ASCII name of the callee requesting the irq.
  66  * @data: private data that is returned back when calling the
  67  * function handler.
  68  * @index: The doorbell index of the requester.
  69  *
  70  * returns: The cookie that is transparent to the caller. Passed
  71  * back when calling mic_free_irq. An appropriate error code
  72  * is returned on failure. Caller needs to use IS_ERR(return_val)
  73  * to check for failure and PTR_ERR(return_val) to obtained the
  74  * error code.
  75  *
  76  */
  77 struct mic_irq *
  78 mic_request_card_irq(irq_handler_t handler,
  79                      irq_handler_t thread_fn, const char *name,
  80                      void *data, int index)
  81 {
  82         int rc = 0;
  83         unsigned long cookie;
  84         struct mic_driver *mdrv = g_drv;
  85 
  86         rc  = request_threaded_irq(mic_db_to_irq(mdrv, index), handler,
  87                                    thread_fn, 0, name, data);
  88         if (rc) {
  89                 dev_err(mdrv->dev, "request_threaded_irq failed rc = %d\n", rc);
  90                 goto err;
  91         }
  92         mdrv->irq_info.irq_usage_count[index]++;
  93         cookie = index;
  94         return (struct mic_irq *)cookie;
  95 err:
  96         return ERR_PTR(rc);
  97 }
  98 
  99 /**
 100  * mic_free_card_irq - free irq.
 101  *
 102  * @cookie: cookie obtained during a successful call to mic_request_threaded_irq
 103  * @data: private data specified by the calling function during the
 104  * mic_request_threaded_irq
 105  *
 106  * returns: none.
 107  */
 108 void mic_free_card_irq(struct mic_irq *cookie, void *data)
 109 {
 110         int index;
 111         struct mic_driver *mdrv = g_drv;
 112 
 113         index = (unsigned long)cookie & 0xFFFFU;
 114         free_irq(mic_db_to_irq(mdrv, index), data);
 115         mdrv->irq_info.irq_usage_count[index]--;
 116 }
 117 
 118 /**
 119  * mic_next_card_db - Get the doorbell with minimum usage count.
 120  *
 121  * Returns the irq index.
 122  */
 123 int mic_next_card_db(void)
 124 {
 125         int i;
 126         int index = 0;
 127         struct mic_driver *mdrv = g_drv;
 128 
 129         for (i = 0; i < mdrv->intr_info.num_intr; i++) {
 130                 if (mdrv->irq_info.irq_usage_count[i] <
 131                         mdrv->irq_info.irq_usage_count[index])
 132                         index = i;
 133         }
 134 
 135         return index;
 136 }
 137 
 138 /**
 139  * mic_init_irq - Initialize irq information.
 140  *
 141  * Returns 0 in success. Appropriate error code on failure.
 142  */
 143 static int mic_init_irq(void)
 144 {
 145         struct mic_driver *mdrv = g_drv;
 146 
 147         mdrv->irq_info.irq_usage_count = kzalloc((sizeof(u32) *
 148                         mdrv->intr_info.num_intr),
 149                         GFP_KERNEL);
 150         if (!mdrv->irq_info.irq_usage_count)
 151                 return -ENOMEM;
 152         return 0;
 153 }
 154 
 155 /**
 156  * mic_uninit_irq - Uninitialize irq information.
 157  *
 158  * None.
 159  */
 160 static void mic_uninit_irq(void)
 161 {
 162         struct mic_driver *mdrv = g_drv;
 163 
 164         kfree(mdrv->irq_info.irq_usage_count);
 165 }
 166 
 167 static inline struct mic_driver *scdev_to_mdrv(struct scif_hw_dev *scdev)
 168 {
 169         return dev_get_drvdata(scdev->dev.parent);
 170 }
 171 
 172 static struct mic_irq *
 173 ___mic_request_irq(struct scif_hw_dev *scdev,
 174                    irqreturn_t (*func)(int irq, void *data),
 175                                        const char *name, void *data,
 176                                        int db)
 177 {
 178         return mic_request_card_irq(func, NULL, name, data, db);
 179 }
 180 
 181 static void
 182 ___mic_free_irq(struct scif_hw_dev *scdev,
 183                 struct mic_irq *cookie, void *data)
 184 {
 185         return mic_free_card_irq(cookie, data);
 186 }
 187 
 188 static void ___mic_ack_interrupt(struct scif_hw_dev *scdev, int num)
 189 {
 190         struct mic_driver *mdrv = scdev_to_mdrv(scdev);
 191 
 192         mic_ack_interrupt(&mdrv->mdev);
 193 }
 194 
 195 static int ___mic_next_db(struct scif_hw_dev *scdev)
 196 {
 197         return mic_next_card_db();
 198 }
 199 
 200 static void ___mic_send_intr(struct scif_hw_dev *scdev, int db)
 201 {
 202         struct mic_driver *mdrv = scdev_to_mdrv(scdev);
 203 
 204         mic_send_intr(&mdrv->mdev, db);
 205 }
 206 
 207 static void ___mic_send_p2p_intr(struct scif_hw_dev *scdev, int db,
 208                                  struct mic_mw *mw)
 209 {
 210         mic_send_p2p_intr(db, mw);
 211 }
 212 
 213 static void __iomem *
 214 ___mic_ioremap(struct scif_hw_dev *scdev,
 215                phys_addr_t pa, size_t len)
 216 {
 217         struct mic_driver *mdrv = scdev_to_mdrv(scdev);
 218 
 219         return mic_card_map(&mdrv->mdev, pa, len);
 220 }
 221 
 222 static void ___mic_iounmap(struct scif_hw_dev *scdev, void __iomem *va)
 223 {
 224         struct mic_driver *mdrv = scdev_to_mdrv(scdev);
 225 
 226         mic_card_unmap(&mdrv->mdev, va);
 227 }
 228 
 229 static struct scif_hw_ops scif_hw_ops = {
 230         .request_irq = ___mic_request_irq,
 231         .free_irq = ___mic_free_irq,
 232         .ack_interrupt = ___mic_ack_interrupt,
 233         .next_db = ___mic_next_db,
 234         .send_intr = ___mic_send_intr,
 235         .send_p2p_intr = ___mic_send_p2p_intr,
 236         .remap = ___mic_ioremap,
 237         .unmap = ___mic_iounmap,
 238 };
 239 
 240 static inline struct mic_driver *vpdev_to_mdrv(struct vop_device *vpdev)
 241 {
 242         return dev_get_drvdata(vpdev->dev.parent);
 243 }
 244 
 245 static struct mic_irq *
 246 __mic_request_irq(struct vop_device *vpdev,
 247                   irqreturn_t (*func)(int irq, void *data),
 248                    const char *name, void *data, int intr_src)
 249 {
 250         return mic_request_card_irq(func, NULL, name, data, intr_src);
 251 }
 252 
 253 static void __mic_free_irq(struct vop_device *vpdev,
 254                            struct mic_irq *cookie, void *data)
 255 {
 256         return mic_free_card_irq(cookie, data);
 257 }
 258 
 259 static void __mic_ack_interrupt(struct vop_device *vpdev, int num)
 260 {
 261         struct mic_driver *mdrv = vpdev_to_mdrv(vpdev);
 262 
 263         mic_ack_interrupt(&mdrv->mdev);
 264 }
 265 
 266 static int __mic_next_db(struct vop_device *vpdev)
 267 {
 268         return mic_next_card_db();
 269 }
 270 
 271 static void __iomem *__mic_get_remote_dp(struct vop_device *vpdev)
 272 {
 273         struct mic_driver *mdrv = vpdev_to_mdrv(vpdev);
 274 
 275         return mdrv->dp;
 276 }
 277 
 278 static void __mic_send_intr(struct vop_device *vpdev, int db)
 279 {
 280         struct mic_driver *mdrv = vpdev_to_mdrv(vpdev);
 281 
 282         mic_send_intr(&mdrv->mdev, db);
 283 }
 284 
 285 static void __iomem *__mic_ioremap(struct vop_device *vpdev,
 286                                    dma_addr_t pa, size_t len)
 287 {
 288         struct mic_driver *mdrv = vpdev_to_mdrv(vpdev);
 289 
 290         return mic_card_map(&mdrv->mdev, pa, len);
 291 }
 292 
 293 static void __mic_iounmap(struct vop_device *vpdev, void __iomem *va)
 294 {
 295         struct mic_driver *mdrv = vpdev_to_mdrv(vpdev);
 296 
 297         mic_card_unmap(&mdrv->mdev, va);
 298 }
 299 
 300 static struct vop_hw_ops vop_hw_ops = {
 301         .request_irq = __mic_request_irq,
 302         .free_irq = __mic_free_irq,
 303         .ack_interrupt = __mic_ack_interrupt,
 304         .next_db = __mic_next_db,
 305         .get_remote_dp = __mic_get_remote_dp,
 306         .send_intr = __mic_send_intr,
 307         .remap = __mic_ioremap,
 308         .unmap = __mic_iounmap,
 309 };
 310 
 311 static int mic_request_dma_chans(struct mic_driver *mdrv)
 312 {
 313         dma_cap_mask_t mask;
 314         struct dma_chan *chan;
 315 
 316         dma_cap_zero(mask);
 317         dma_cap_set(DMA_MEMCPY, mask);
 318 
 319         do {
 320                 chan = dma_request_channel(mask, NULL, NULL);
 321                 if (chan) {
 322                         mdrv->dma_ch[mdrv->num_dma_ch++] = chan;
 323                         if (mdrv->num_dma_ch >= MIC_MAX_DMA_CHAN)
 324                                 break;
 325                 }
 326         } while (chan);
 327         dev_info(mdrv->dev, "DMA channels # %d\n", mdrv->num_dma_ch);
 328         return mdrv->num_dma_ch;
 329 }
 330 
 331 static void mic_free_dma_chans(struct mic_driver *mdrv)
 332 {
 333         int i = 0;
 334 
 335         for (i = 0; i < mdrv->num_dma_ch; i++) {
 336                 dma_release_channel(mdrv->dma_ch[i]);
 337                 mdrv->dma_ch[i] = NULL;
 338         }
 339         mdrv->num_dma_ch = 0;
 340 }
 341 
 342 /*
 343  * mic_driver_init - MIC driver initialization tasks.
 344  *
 345  * Returns 0 in success. Appropriate error code on failure.
 346  */
 347 int __init mic_driver_init(struct mic_driver *mdrv)
 348 {
 349         int rc;
 350         struct mic_bootparam __iomem *bootparam;
 351         u8 node_id;
 352 
 353         g_drv = mdrv;
 354         /* Unloading the card module is not supported. */
 355         if (!try_module_get(mdrv->dev->driver->owner)) {
 356                 rc = -ENODEV;
 357                 goto done;
 358         }
 359         rc = mic_dp_init();
 360         if (rc)
 361                 goto put;
 362         rc = mic_init_irq();
 363         if (rc)
 364                 goto dp_uninit;
 365         if (!mic_request_dma_chans(mdrv)) {
 366                 rc = -ENODEV;
 367                 goto irq_uninit;
 368         }
 369         mdrv->vpdev = vop_register_device(mdrv->dev, VOP_DEV_TRNSP,
 370                                           NULL, &vop_hw_ops, 0,
 371                                           NULL, mdrv->dma_ch[0]);
 372         if (IS_ERR(mdrv->vpdev)) {
 373                 rc = PTR_ERR(mdrv->vpdev);
 374                 goto dma_free;
 375         }
 376         bootparam = mdrv->dp;
 377         node_id = ioread8(&bootparam->node_id);
 378         mdrv->scdev = scif_register_device(mdrv->dev, MIC_SCIF_DEV,
 379                                            NULL, &scif_hw_ops,
 380                                            0, node_id, &mdrv->mdev.mmio, NULL,
 381                                            NULL, mdrv->dp, mdrv->dma_ch,
 382                                            mdrv->num_dma_ch, true);
 383         if (IS_ERR(mdrv->scdev)) {
 384                 rc = PTR_ERR(mdrv->scdev);
 385                 goto vop_remove;
 386         }
 387         mic_create_card_debug_dir(mdrv);
 388 done:
 389         return rc;
 390 vop_remove:
 391         vop_unregister_device(mdrv->vpdev);
 392 dma_free:
 393         mic_free_dma_chans(mdrv);
 394 irq_uninit:
 395         mic_uninit_irq();
 396 dp_uninit:
 397         mic_dp_uninit();
 398 put:
 399         module_put(mdrv->dev->driver->owner);
 400         return rc;
 401 }
 402 
 403 /*
 404  * mic_driver_uninit - MIC driver uninitialization tasks.
 405  *
 406  * Returns None
 407  */
 408 void mic_driver_uninit(struct mic_driver *mdrv)
 409 {
 410         mic_delete_card_debug_dir(mdrv);
 411         scif_unregister_device(mdrv->scdev);
 412         vop_unregister_device(mdrv->vpdev);
 413         mic_free_dma_chans(mdrv);
 414         mic_uninit_irq();
 415         mic_dp_uninit();
 416         module_put(mdrv->dev->driver->owner);
 417 }

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