linux/drivers/gpu/drm/amd/amdkfd/kfd_module.c
<<
>>
Prefs
   1/*
   2 * Copyright 2014 Advanced Micro Devices, Inc.
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice shall be included in
  12 * all copies or substantial portions of the Software.
  13 *
  14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20 * OTHER DEALINGS IN THE SOFTWARE.
  21 */
  22
  23#include <linux/module.h>
  24#include <linux/sched.h>
  25#include <linux/moduleparam.h>
  26#include <linux/device.h>
  27#include "kfd_priv.h"
  28
  29#define KFD_DRIVER_AUTHOR       "AMD Inc. and others"
  30
  31#define KFD_DRIVER_DESC         "Standalone HSA driver for AMD's GPUs"
  32#define KFD_DRIVER_DATE         "20150421"
  33#define KFD_DRIVER_MAJOR        0
  34#define KFD_DRIVER_MINOR        7
  35#define KFD_DRIVER_PATCHLEVEL   2
  36
  37static const struct kgd2kfd_calls kgd2kfd = {
  38        .exit           = kgd2kfd_exit,
  39        .probe          = kgd2kfd_probe,
  40        .device_init    = kgd2kfd_device_init,
  41        .device_exit    = kgd2kfd_device_exit,
  42        .interrupt      = kgd2kfd_interrupt,
  43        .suspend        = kgd2kfd_suspend,
  44        .resume         = kgd2kfd_resume,
  45};
  46
  47int sched_policy = KFD_SCHED_POLICY_HWS;
  48module_param(sched_policy, int, 0444);
  49MODULE_PARM_DESC(sched_policy,
  50        "Scheduling policy (0 = HWS (Default), 1 = HWS without over-subscription, 2 = Non-HWS (Used for debugging only)");
  51
  52int max_num_of_queues_per_device = KFD_MAX_NUM_OF_QUEUES_PER_DEVICE_DEFAULT;
  53module_param(max_num_of_queues_per_device, int, 0444);
  54MODULE_PARM_DESC(max_num_of_queues_per_device,
  55        "Maximum number of supported queues per device (1 = Minimum, 4096 = default)");
  56
  57int send_sigterm;
  58module_param(send_sigterm, int, 0444);
  59MODULE_PARM_DESC(send_sigterm,
  60        "Send sigterm to HSA process on unhandled exception (0 = disable, 1 = enable)");
  61
  62static int amdkfd_init_completed;
  63
  64int kgd2kfd_init(unsigned interface_version, const struct kgd2kfd_calls **g2f)
  65{
  66        if (!amdkfd_init_completed)
  67                return -EPROBE_DEFER;
  68
  69        /*
  70         * Only one interface version is supported,
  71         * no kfd/kgd version skew allowed.
  72         */
  73        if (interface_version != KFD_INTERFACE_VERSION)
  74                return -EINVAL;
  75
  76        *g2f = &kgd2kfd;
  77
  78        return 0;
  79}
  80EXPORT_SYMBOL(kgd2kfd_init);
  81
  82void kgd2kfd_exit(void)
  83{
  84}
  85
  86static int __init kfd_module_init(void)
  87{
  88        int err;
  89
  90        /* Verify module parameters */
  91        if ((sched_policy < KFD_SCHED_POLICY_HWS) ||
  92                (sched_policy > KFD_SCHED_POLICY_NO_HWS)) {
  93                pr_err("kfd: sched_policy has invalid value\n");
  94                return -1;
  95        }
  96
  97        /* Verify module parameters */
  98        if ((max_num_of_queues_per_device < 1) ||
  99                (max_num_of_queues_per_device >
 100                        KFD_MAX_NUM_OF_QUEUES_PER_DEVICE)) {
 101                pr_err("kfd: max_num_of_queues_per_device must be between 1 to KFD_MAX_NUM_OF_QUEUES_PER_DEVICE\n");
 102                return -1;
 103        }
 104
 105        err = kfd_pasid_init();
 106        if (err < 0)
 107                goto err_pasid;
 108
 109        err = kfd_chardev_init();
 110        if (err < 0)
 111                goto err_ioctl;
 112
 113        err = kfd_topology_init();
 114        if (err < 0)
 115                goto err_topology;
 116
 117        kfd_process_create_wq();
 118
 119        amdkfd_init_completed = 1;
 120
 121        dev_info(kfd_device, "Initialized module\n");
 122
 123        return 0;
 124
 125err_topology:
 126        kfd_chardev_exit();
 127err_ioctl:
 128        kfd_pasid_exit();
 129err_pasid:
 130        return err;
 131}
 132
 133static void __exit kfd_module_exit(void)
 134{
 135        amdkfd_init_completed = 0;
 136
 137        kfd_process_destroy_wq();
 138        kfd_topology_shutdown();
 139        kfd_chardev_exit();
 140        kfd_pasid_exit();
 141        dev_info(kfd_device, "Removed module\n");
 142}
 143
 144module_init(kfd_module_init);
 145module_exit(kfd_module_exit);
 146
 147MODULE_AUTHOR(KFD_DRIVER_AUTHOR);
 148MODULE_DESCRIPTION(KFD_DRIVER_DESC);
 149MODULE_LICENSE("GPL and additional rights");
 150MODULE_VERSION(__stringify(KFD_DRIVER_MAJOR) "."
 151               __stringify(KFD_DRIVER_MINOR) "."
 152               __stringify(KFD_DRIVER_PATCHLEVEL));
 153