1 /* 2 * Copyright 2019 Red Hat 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 #include "priv.h" 23 24 static int 25 nvkm_gsp_fini(struct nvkm_subdev *subdev, bool suspend) 26 { 27 struct nvkm_gsp *gsp = nvkm_gsp(subdev); 28 29 if (!gsp->func->fini) 30 return 0; 31 32 return gsp->func->fini(gsp, suspend); 33 } 34 35 static int 36 nvkm_gsp_init(struct nvkm_subdev *subdev) 37 { 38 struct nvkm_gsp *gsp = nvkm_gsp(subdev); 39 40 if (!gsp->func->init) 41 return 0; 42 43 return gsp->func->init(gsp); 44 } 45 46 static int 47 nvkm_gsp_oneinit(struct nvkm_subdev *subdev) 48 { 49 struct nvkm_gsp *gsp = nvkm_gsp(subdev); 50 51 if (!gsp->func->oneinit) 52 return 0; 53 54 return gsp->func->oneinit(gsp); 55 } 56 57 static void * 58 nvkm_gsp_dtor(struct nvkm_subdev *subdev) 59 { 60 struct nvkm_gsp *gsp = nvkm_gsp(subdev); 61 62 if (gsp->func && gsp->func->dtor) 63 gsp->func->dtor(gsp); 64 65 nvkm_falcon_dtor(&gsp->falcon); 66 return gsp; 67 } 68 69 static const struct nvkm_subdev_func 70 nvkm_gsp = { 71 .dtor = nvkm_gsp_dtor, 72 .oneinit = nvkm_gsp_oneinit, 73 .init = nvkm_gsp_init, 74 .fini = nvkm_gsp_fini, 75 }; 76 77 int 78 nvkm_gsp_new_(const struct nvkm_gsp_fwif *fwif, struct nvkm_device *device, 79 enum nvkm_subdev_type type, int inst, struct nvkm_gsp **pgsp) 80 { 81 struct nvkm_gsp *gsp; 82 83 if (!(gsp = *pgsp = kzalloc(sizeof(*gsp), GFP_KERNEL))) 84 return -ENOMEM; 85 86 nvkm_subdev_ctor(&nvkm_gsp, device, type, inst, &gsp->subdev); 87 88 fwif = nvkm_firmware_load(&gsp->subdev, fwif, "Gsp", gsp); 89 if (IS_ERR(fwif)) 90 return PTR_ERR(fwif); 91 92 gsp->func = fwif->func; 93 94 return nvkm_falcon_ctor(gsp->func->flcn, &gsp->subdev, gsp->subdev.name, 0x110000, 95 &gsp->falcon); 96 } 97