/** * vsp1_dl_fragment_alloc - Allocate a display list fragment * @vsp1: The VSP1 device * @num_entries: The maximum number of entries that the fragment can contain * * Allocate a display list fragment with enough memory to contain the requested * number of entries. * * Return a pointer to a fragment on success or NULL if memory can't be * allocated. */ struct vsp1_dl_body *vsp1_dl_fragment_alloc(struct vsp1_device *vsp1, unsigned int num_entries) { struct vsp1_dl_body *dlb; int ret; dlb = kzalloc(sizeof(*dlb), GFP_KERNEL); if (!dlb) return NULL; ret = vsp1_dl_body_init(vsp1, dlb, num_entries, 0); if (ret < 0) { kfree(dlb); return NULL; } return dlb; }
static struct vsp1_dl_list *vsp1_dl_list_alloc(struct vsp1_dl_manager *dlm) { struct vsp1_dl_list *dl; size_t header_size; int ret; dl = kzalloc(sizeof(*dl), GFP_KERNEL); if (!dl) return NULL; INIT_LIST_HEAD(&dl->fragments); dl->dlm = dlm; /* * Initialize the display list body and allocate DMA memory for the body * and the optional header. Both are allocated together to avoid memory * fragmentation, with the header located right after the body in * memory. */ header_size = dlm->mode == VSP1_DL_MODE_HEADER ? ALIGN(sizeof(struct vsp1_dl_header), 8) : 0; ret = vsp1_dl_body_init(dlm->vsp1, &dl->body0, VSP1_DL_NUM_ENTRIES, header_size); if (ret < 0) { kfree(dl); return NULL; } if (dlm->mode == VSP1_DL_MODE_HEADER) { size_t header_offset = VSP1_DL_NUM_ENTRIES * sizeof(*dl->body0.entries); dl->header = ((void *)dl->body0.entries) + header_offset; dl->dma = dl->body0.dma + header_offset; memset(dl->header, 0, sizeof(*dl->header)); dl->header->lists[0].addr = dl->body0.dma; } return dl; }