0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include <core/device.h>
0023 #include <core/firmware.h>
0024
0025 int
0026 nvkm_firmware_load_name(const struct nvkm_subdev *subdev, const char *base,
0027 const char *name, int ver, const struct firmware **pfw)
0028 {
0029 char path[64];
0030 int ret;
0031
0032 snprintf(path, sizeof(path), "%s%s", base, name);
0033 ret = nvkm_firmware_get(subdev, path, ver, pfw);
0034 if (ret < 0)
0035 return ret;
0036
0037 return 0;
0038 }
0039
0040 int
0041 nvkm_firmware_load_blob(const struct nvkm_subdev *subdev, const char *base,
0042 const char *name, int ver, struct nvkm_blob *blob)
0043 {
0044 const struct firmware *fw;
0045 int ret;
0046
0047 ret = nvkm_firmware_load_name(subdev, base, name, ver, &fw);
0048 if (ret == 0) {
0049 blob->data = kmemdup(fw->data, fw->size, GFP_KERNEL);
0050 blob->size = fw->size;
0051 nvkm_firmware_put(fw);
0052 if (!blob->data)
0053 return -ENOMEM;
0054 }
0055
0056 return ret;
0057 }
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 int
0070 nvkm_firmware_get(const struct nvkm_subdev *subdev, const char *fwname, int ver,
0071 const struct firmware **fw)
0072 {
0073 struct nvkm_device *device = subdev->device;
0074 char f[64];
0075 char cname[16];
0076 int i;
0077
0078
0079 strncpy(cname, device->chip->name, sizeof(cname));
0080 cname[sizeof(cname) - 1] = '\0';
0081 i = strlen(cname);
0082 while (i) {
0083 --i;
0084 cname[i] = tolower(cname[i]);
0085 }
0086
0087 if (ver != 0)
0088 snprintf(f, sizeof(f), "nvidia/%s/%s-%d.bin", cname, fwname, ver);
0089 else
0090 snprintf(f, sizeof(f), "nvidia/%s/%s.bin", cname, fwname);
0091
0092 if (!firmware_request_nowarn(fw, f, device->dev)) {
0093 nvkm_debug(subdev, "firmware \"%s\" loaded - %zu byte(s)\n",
0094 f, (*fw)->size);
0095 return 0;
0096 }
0097
0098 nvkm_debug(subdev, "firmware \"%s\" unavailable\n", f);
0099 return -ENOENT;
0100 }
0101
0102
0103
0104
0105 void
0106 nvkm_firmware_put(const struct firmware *fw)
0107 {
0108 release_firmware(fw);
0109 }