/** * adf_fbdev_open - default implementation of fbdev open op */ int adf_fbdev_open(struct fb_info *info, int user) { struct adf_fbdev *fbdev = info->par; int ret; mutex_lock(&fbdev->refcount_lock); if (unlikely(fbdev->refcount == UINT_MAX)) { ret = -EMFILE; goto done; } if (!fbdev->refcount) { struct drm_mode_modeinfo mode; struct fb_videomode fbmode; struct adf_device *dev = adf_interface_parent(fbdev->intf); ret = adf_device_attach(dev, fbdev->eng, fbdev->intf); if (ret < 0 && ret != -EALREADY) goto done; ret = adf_fb_alloc(fbdev); if (ret < 0) goto done; adf_interface_current_mode(fbdev->intf, &mode); adf_modeinfo_to_fb_videomode(&mode, &fbmode); fb_videomode_to_var(&fbdev->info->var, &fbmode); adf_fbdev_set_format(fbdev, fbdev->default_format); adf_fbdev_fill_modelist(fbdev); } if (!fbdev_opened_once) { fbdev_opened_once = true; } else { ret = adf_fbdev_post(fbdev); if (ret < 0) { if (!fbdev->refcount) adf_fb_destroy(fbdev); goto done; } } fbdev->refcount++; done: mutex_unlock(&fbdev->refcount_lock); return ret; }
/** * adf_fbdev_set_par - default implementation of fbdev set_par op */ int adf_fbdev_set_par(struct fb_info *info) { struct adf_fbdev *fbdev = info->par; struct adf_interface *intf = fbdev->intf; struct fb_videomode vmode; struct drm_mode_modeinfo mode; int ret; u32 format = drm_fourcc_from_fb_var(&info->var); fb_var_to_videomode(&vmode, &info->var); adf_modeinfo_from_fb_videomode(&vmode, &mode); ret = adf_interface_set_mode(intf, &mode); if (ret < 0) return ret; ret = adf_fbdev_post(fbdev); if (ret < 0) return ret; if (format != fbdev->format) adf_fbdev_set_format(fbdev, format); return 0; }
/** * adf_fbdev_open - default implementation of fbdev open op */ int adf_fbdev_open(struct fb_info *info, int user) { struct adf_fbdev *fbdev = info->par; int ret; if (!fbdev->open) { struct drm_mode_modeinfo mode; struct fb_videomode fbmode; struct adf_device *dev = adf_interface_parent(fbdev->intf); ret = adf_device_attach(dev, fbdev->eng, fbdev->intf); if (ret < 0 && ret != -EALREADY) return ret; ret = adf_fb_alloc(fbdev); if (ret < 0) return ret; adf_interface_current_mode(fbdev->intf, &mode); adf_modeinfo_to_fb_videomode(&mode, &fbmode); fb_videomode_to_var(&fbdev->info->var, &fbmode); adf_fbdev_set_format(fbdev, fbdev->default_format); adf_fbdev_fill_modelist(fbdev); } ret = adf_fbdev_post(fbdev); if (ret < 0) { if (!fbdev->open) adf_fb_destroy(fbdev); return ret; } fbdev->open = true; return 0; }
/** * adf_fbdev_pan_display - default implementation of fbdev pan_display op */ int adf_fbdev_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { struct adf_fbdev *fbdev = info->par; return adf_fbdev_post(fbdev); }