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