124 lines · c
1/*2 * Copyright 2019 Red Hat Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * OTHER DEALINGS IN THE SOFTWARE.21 */22#include "priv.h"23 24int25nvkm_gsp_intr_nonstall(struct nvkm_gsp *gsp, enum nvkm_subdev_type type, int inst)26{27 for (int i = 0; i < gsp->intr_nr; i++) {28 if (gsp->intr[i].type == type && gsp->intr[i].inst == inst)29 return gsp->intr[i].nonstall;30 }31 32 return -ENOENT;33}34 35int36nvkm_gsp_intr_stall(struct nvkm_gsp *gsp, enum nvkm_subdev_type type, int inst)37{38 for (int i = 0; i < gsp->intr_nr; i++) {39 if (gsp->intr[i].type == type && gsp->intr[i].inst == inst) {40 if (gsp->intr[i].stall != ~0)41 return gsp->intr[i].stall;42 43 return -EINVAL;44 }45 }46 47 return -ENOENT;48}49 50static int51nvkm_gsp_fini(struct nvkm_subdev *subdev, bool suspend)52{53 struct nvkm_gsp *gsp = nvkm_gsp(subdev);54 55 if (!gsp->func->fini)56 return 0;57 58 return gsp->func->fini(gsp, suspend);59}60 61static int62nvkm_gsp_init(struct nvkm_subdev *subdev)63{64 struct nvkm_gsp *gsp = nvkm_gsp(subdev);65 66 if (!gsp->func->init)67 return 0;68 69 return gsp->func->init(gsp);70}71 72static int73nvkm_gsp_oneinit(struct nvkm_subdev *subdev)74{75 struct nvkm_gsp *gsp = nvkm_gsp(subdev);76 77 if (!gsp->func->oneinit)78 return 0;79 80 return gsp->func->oneinit(gsp);81}82 83static void *84nvkm_gsp_dtor(struct nvkm_subdev *subdev)85{86 struct nvkm_gsp *gsp = nvkm_gsp(subdev);87 88 if (gsp->func && gsp->func->dtor)89 gsp->func->dtor(gsp);90 91 nvkm_falcon_dtor(&gsp->falcon);92 return gsp;93}94 95static const struct nvkm_subdev_func96nvkm_gsp = {97 .dtor = nvkm_gsp_dtor,98 .oneinit = nvkm_gsp_oneinit,99 .init = nvkm_gsp_init,100 .fini = nvkm_gsp_fini,101};102 103int104nvkm_gsp_new_(const struct nvkm_gsp_fwif *fwif, struct nvkm_device *device,105 enum nvkm_subdev_type type, int inst, struct nvkm_gsp **pgsp)106{107 struct nvkm_gsp *gsp;108 109 if (!(gsp = *pgsp = kzalloc(sizeof(*gsp), GFP_KERNEL)))110 return -ENOMEM;111 112 nvkm_subdev_ctor(&nvkm_gsp, device, type, inst, &gsp->subdev);113 114 fwif = nvkm_firmware_load(&gsp->subdev, fwif, "Gsp", gsp);115 if (IS_ERR(fwif))116 return PTR_ERR(fwif);117 118 gsp->func = fwif->func;119 gsp->rm = gsp->func->rm;120 121 return nvkm_falcon_ctor(gsp->func->flcn, &gsp->subdev, gsp->subdev.name, 0x110000,122 &gsp->falcon);123}124