1 /* SPDX-License-Identifier: MIT */ 2 #ifndef __NVKM_FIRMWARE_H__ 3 #define __NVKM_FIRMWARE_H__ 4 #include <core/option.h> 5 #include <core/subdev.h> 6 7 int nvkm_firmware_get(const struct nvkm_subdev *, const char *fwname, int ver, 8 const struct firmware **); 9 void nvkm_firmware_put(const struct firmware *); 10 11 int nvkm_firmware_load_blob(const struct nvkm_subdev *subdev, const char *path, 12 const char *name, int ver, struct nvkm_blob *); 13 int nvkm_firmware_load_name(const struct nvkm_subdev *subdev, const char *path, 14 const char *name, int ver, 15 const struct firmware **); 16 17 #define nvkm_firmware_load(s,l,o,p...) ({ \ 18 struct nvkm_subdev *_s = (s); \ 19 const char *_opts = (o); \ 20 char _option[32]; \ 21 typeof(l[0]) *_list = (l), *_next, *_fwif = NULL; \ 22 int _ver, _fwv, _ret = 0; \ 23 \ 24 snprintf(_option, sizeof(_option), "Nv%sFw", _opts); \ 25 _ver = nvkm_longopt(_s->device->cfgopt, _option, -2); \ 26 if (_ver >= -1) { \ 27 for (_next = _list; !_fwif && _next->load; _next++) { \ 28 if (_next->version == _ver) \ 29 _fwif = _next; \ 30 } \ 31 _ret = _fwif ? 0 : -EINVAL; \ 32 } \ 33 \ 34 if (_ret == 0) { \ 35 snprintf(_option, sizeof(_option), "Nv%sFwVer", _opts); \ 36 _fwv = _fwif ? _fwif->version : -1; \ 37 _ver = nvkm_longopt(_s->device->cfgopt, _option, _fwv); \ 38 for (_next = _fwif ? _fwif : _list; _next->load; _next++) { \ 39 _fwv = (_ver >= 0) ? _ver : _next->version; \ 40 _ret = _next->load(p, _fwv, _next); \ 41 if (_ret == 0 || _ver >= 0) { \ 42 _fwif = _next; \ 43 break; \ 44 } \ 45 } \ 46 } \ 47 \ 48 if (_ret) \ 49 _fwif = ERR_PTR(_ret); \ 50 _fwif; \ 51 }) 52 #endif 53