108e89f1eSPekka Enberg #include "kvm/framebuffer.h" 208e89f1eSPekka Enberg 308e89f1eSPekka Enberg #include <linux/kernel.h> 408e89f1eSPekka Enberg #include <linux/list.h> 508e89f1eSPekka Enberg #include <stdlib.h> 67fca1897SSasha Levin #include <sys/mman.h> 748d9e01aSSasha Levin #include <errno.h> 808e89f1eSPekka Enberg 908e89f1eSPekka Enberg static LIST_HEAD(framebuffers); 1008e89f1eSPekka Enberg 1108e89f1eSPekka Enberg struct framebuffer *fb__register(struct framebuffer *fb) 1208e89f1eSPekka Enberg { 1308e89f1eSPekka Enberg INIT_LIST_HEAD(&fb->node); 1408e89f1eSPekka Enberg list_add(&fb->node, &framebuffers); 1508e89f1eSPekka Enberg 1608e89f1eSPekka Enberg return fb; 1708e89f1eSPekka Enberg } 1808e89f1eSPekka Enberg 1908e89f1eSPekka Enberg int fb__attach(struct framebuffer *fb, struct fb_target_operations *ops) 2008e89f1eSPekka Enberg { 2108e89f1eSPekka Enberg if (fb->nr_targets >= FB_MAX_TARGETS) 2248d9e01aSSasha Levin return -ENOSPC; 2308e89f1eSPekka Enberg 2408e89f1eSPekka Enberg fb->targets[fb->nr_targets++] = ops; 2508e89f1eSPekka Enberg 2608e89f1eSPekka Enberg return 0; 2708e89f1eSPekka Enberg } 2808e89f1eSPekka Enberg 2908e89f1eSPekka Enberg static int start_targets(struct framebuffer *fb) 3008e89f1eSPekka Enberg { 3108e89f1eSPekka Enberg unsigned long i; 3208e89f1eSPekka Enberg 3308e89f1eSPekka Enberg for (i = 0; i < fb->nr_targets; i++) { 3408e89f1eSPekka Enberg struct fb_target_operations *ops = fb->targets[i]; 3508e89f1eSPekka Enberg int err = 0; 3608e89f1eSPekka Enberg 3708e89f1eSPekka Enberg if (ops->start) 3808e89f1eSPekka Enberg err = ops->start(fb); 3908e89f1eSPekka Enberg 4008e89f1eSPekka Enberg if (err) 4108e89f1eSPekka Enberg return err; 4208e89f1eSPekka Enberg } 4308e89f1eSPekka Enberg 4408e89f1eSPekka Enberg return 0; 4508e89f1eSPekka Enberg } 4608e89f1eSPekka Enberg 47*ba46fe53SSasha Levin int fb__init(struct kvm *kvm) 4808e89f1eSPekka Enberg { 4908e89f1eSPekka Enberg struct framebuffer *fb; 5008e89f1eSPekka Enberg 5108e89f1eSPekka Enberg list_for_each_entry(fb, &framebuffers, node) { 5208e89f1eSPekka Enberg int err; 5308e89f1eSPekka Enberg 5408e89f1eSPekka Enberg err = start_targets(fb); 5508e89f1eSPekka Enberg if (err) 5608e89f1eSPekka Enberg return err; 5708e89f1eSPekka Enberg } 5808e89f1eSPekka Enberg 5908e89f1eSPekka Enberg return 0; 6008e89f1eSPekka Enberg } 6108e89f1eSPekka Enberg 62*ba46fe53SSasha Levin int fb__exit(struct kvm *kvm) 6308e89f1eSPekka Enberg { 6408e89f1eSPekka Enberg struct framebuffer *fb; 6508e89f1eSPekka Enberg 6608e89f1eSPekka Enberg list_for_each_entry(fb, &framebuffers, node) { 6748d9e01aSSasha Levin u32 i; 6848d9e01aSSasha Levin 6948d9e01aSSasha Levin for (i = 0; i < fb->nr_targets; i++) 7048d9e01aSSasha Levin if (fb->targets[i]->stop) 7148d9e01aSSasha Levin fb->targets[i]->stop(fb); 7248d9e01aSSasha Levin 737fca1897SSasha Levin munmap(fb->mem, fb->mem_size); 7408e89f1eSPekka Enberg } 75*ba46fe53SSasha Levin 76*ba46fe53SSasha Levin return 0; 7708e89f1eSPekka Enberg } 78