0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include "priv.h"
0025
0026 struct nvkm_top_device *
0027 nvkm_top_device_new(struct nvkm_top *top)
0028 {
0029 struct nvkm_top_device *info = kmalloc(sizeof(*info), GFP_KERNEL);
0030 if (info) {
0031 info->type = NVKM_SUBDEV_NR;
0032 info->inst = -1;
0033 info->addr = 0;
0034 info->fault = -1;
0035 info->engine = -1;
0036 info->runlist = -1;
0037 info->reset = -1;
0038 info->intr = -1;
0039 list_add_tail(&info->head, &top->device);
0040 }
0041 return info;
0042 }
0043
0044 u32
0045 nvkm_top_addr(struct nvkm_device *device, enum nvkm_subdev_type type, int inst)
0046 {
0047 struct nvkm_top *top = device->top;
0048 struct nvkm_top_device *info;
0049
0050 if (top) {
0051 list_for_each_entry(info, &top->device, head) {
0052 if (info->type == type && info->inst == inst)
0053 return info->addr;
0054 }
0055 }
0056
0057 return 0;
0058 }
0059
0060 u32
0061 nvkm_top_reset(struct nvkm_device *device, enum nvkm_subdev_type type, int inst)
0062 {
0063 struct nvkm_top *top = device->top;
0064 struct nvkm_top_device *info;
0065
0066 if (top) {
0067 list_for_each_entry(info, &top->device, head) {
0068 if (info->type == type && info->inst == inst && info->reset >= 0)
0069 return BIT(info->reset);
0070 }
0071 }
0072
0073 return 0;
0074 }
0075
0076 u32
0077 nvkm_top_intr_mask(struct nvkm_device *device, enum nvkm_subdev_type type, int inst)
0078 {
0079 struct nvkm_top *top = device->top;
0080 struct nvkm_top_device *info;
0081
0082 if (top) {
0083 list_for_each_entry(info, &top->device, head) {
0084 if (info->type == type && info->inst == inst && info->intr >= 0)
0085 return BIT(info->intr);
0086 }
0087 }
0088
0089 return 0;
0090 }
0091
0092 int
0093 nvkm_top_fault_id(struct nvkm_device *device, enum nvkm_subdev_type type, int inst)
0094 {
0095 struct nvkm_top *top = device->top;
0096 struct nvkm_top_device *info;
0097
0098 list_for_each_entry(info, &top->device, head) {
0099 if (info->type == type && info->inst == inst && info->fault >= 0)
0100 return info->fault;
0101 }
0102
0103 return -ENOENT;
0104 }
0105
0106 struct nvkm_subdev *
0107 nvkm_top_fault(struct nvkm_device *device, int fault)
0108 {
0109 struct nvkm_top *top = device->top;
0110 struct nvkm_top_device *info;
0111
0112 list_for_each_entry(info, &top->device, head) {
0113 if (info->fault == fault)
0114 return nvkm_device_subdev(device, info->type, info->inst);
0115 }
0116
0117 return NULL;
0118 }
0119
0120 static int
0121 nvkm_top_oneinit(struct nvkm_subdev *subdev)
0122 {
0123 struct nvkm_top *top = nvkm_top(subdev);
0124 return top->func->oneinit(top);
0125 }
0126
0127 static void *
0128 nvkm_top_dtor(struct nvkm_subdev *subdev)
0129 {
0130 struct nvkm_top *top = nvkm_top(subdev);
0131 struct nvkm_top_device *info, *temp;
0132
0133 list_for_each_entry_safe(info, temp, &top->device, head) {
0134 list_del(&info->head);
0135 kfree(info);
0136 }
0137
0138 return top;
0139 }
0140
0141 static const struct nvkm_subdev_func
0142 nvkm_top = {
0143 .dtor = nvkm_top_dtor,
0144 .oneinit = nvkm_top_oneinit,
0145 };
0146
0147 int
0148 nvkm_top_new_(const struct nvkm_top_func *func, struct nvkm_device *device,
0149 enum nvkm_subdev_type type, int inst, struct nvkm_top **ptop)
0150 {
0151 struct nvkm_top *top;
0152 if (!(top = *ptop = kzalloc(sizeof(*top), GFP_KERNEL)))
0153 return -ENOMEM;
0154 nvkm_subdev_ctor(&nvkm_top, device, type, inst, &top->subdev);
0155 top->func = func;
0156 INIT_LIST_HEAD(&top->device);
0157 return 0;
0158 }