Merge tag 'topic/core-stuff-2015-01-23' of git://anongit.freedesktop.org/drm-intel into drm-next
Just flushing out my drm-misc branch, nothing major. Well too old patches I've dug out from years since a patch from Rob look eerily familiar ;-) * tag 'topic/core-stuff-2015-01-23' of git://anongit.freedesktop.org/drm-intel: drm/probe-helper: clamp unknown connector status in the poll work drm/probe-helper: don't lose hotplug event next: drm/atomic: Use copy_from_user to copy 64 bit data from user space drm: Make drm_read() more robust against multithreaded races drm/fb-helper: Propagate errors from initial config failure drm: Drop superfluous "select VT_HW_CONSOLE_BINDING"
This commit is contained in:
commit
e4514003c6
|
@ -335,18 +335,27 @@ int ast_fbdev_init(struct drm_device *dev)
|
|||
|
||||
ret = drm_fb_helper_init(dev, &afbdev->helper,
|
||||
1, 1);
|
||||
if (ret) {
|
||||
kfree(afbdev);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
goto free;
|
||||
|
||||
drm_fb_helper_single_add_all_connectors(&afbdev->helper);
|
||||
ret = drm_fb_helper_single_add_all_connectors(&afbdev->helper);
|
||||
if (ret)
|
||||
goto fini;
|
||||
|
||||
/* disable all the possible outputs/crtcs before entering KMS mode */
|
||||
drm_helper_disable_unused_functions(dev);
|
||||
|
||||
drm_fb_helper_initial_config(&afbdev->helper, 32);
|
||||
ret = drm_fb_helper_initial_config(&afbdev->helper, 32);
|
||||
if (ret)
|
||||
goto fini;
|
||||
|
||||
return 0;
|
||||
|
||||
fini:
|
||||
drm_fb_helper_fini(&afbdev->helper);
|
||||
free:
|
||||
kfree(afbdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ast_fbdev_fini(struct drm_device *dev)
|
||||
|
|
|
@ -207,12 +207,22 @@ int bochs_fbdev_init(struct bochs_device *bochs)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
drm_fb_helper_single_add_all_connectors(&bochs->fb.helper);
|
||||
ret = drm_fb_helper_single_add_all_connectors(&bochs->fb.helper);
|
||||
if (ret)
|
||||
goto fini;
|
||||
|
||||
drm_helper_disable_unused_functions(bochs->dev);
|
||||
drm_fb_helper_initial_config(&bochs->fb.helper, 32);
|
||||
|
||||
ret = drm_fb_helper_initial_config(&bochs->fb.helper, 32);
|
||||
if (ret)
|
||||
goto fini;
|
||||
|
||||
bochs->fb.initialized = true;
|
||||
return 0;
|
||||
|
||||
fini:
|
||||
drm_fb_helper_fini(&bochs->fb.helper);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void bochs_fbdev_fini(struct bochs_device *bochs)
|
||||
|
|
|
@ -317,17 +317,17 @@ int cirrus_fbdev_init(struct cirrus_device *cdev)
|
|||
|
||||
ret = drm_fb_helper_init(cdev->dev, &gfbdev->helper,
|
||||
cdev->num_crtc, CIRRUSFB_CONN_LIMIT);
|
||||
if (ret) {
|
||||
kfree(gfbdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = drm_fb_helper_single_add_all_connectors(&gfbdev->helper);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
drm_fb_helper_single_add_all_connectors(&gfbdev->helper);
|
||||
|
||||
/* disable all the possible outputs/crtcs before entering KMS mode */
|
||||
drm_helper_disable_unused_functions(cdev->dev);
|
||||
drm_fb_helper_initial_config(&gfbdev->helper, bpp_sel);
|
||||
|
||||
return 0;
|
||||
return drm_fb_helper_initial_config(&gfbdev->helper, bpp_sel);
|
||||
}
|
||||
|
||||
void cirrus_fbdev_fini(struct cirrus_device *cdev)
|
||||
|
|
|
@ -1259,7 +1259,9 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if (get_user(prop_value, prop_values_ptr + copied_props)) {
|
||||
if (copy_from_user(&prop_value,
|
||||
prop_values_ptr + copied_props,
|
||||
sizeof(prop_value))) {
|
||||
ret = -EFAULT;
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
@ -1692,7 +1692,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
|
|||
* RETURNS:
|
||||
* Zero if everything went ok, nonzero otherwise.
|
||||
*/
|
||||
bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)
|
||||
int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)
|
||||
{
|
||||
struct drm_device *dev = fb_helper->dev;
|
||||
int count = 0;
|
||||
|
|
|
@ -478,64 +478,59 @@ int drm_release(struct inode *inode, struct file *filp)
|
|||
}
|
||||
EXPORT_SYMBOL(drm_release);
|
||||
|
||||
static bool
|
||||
drm_dequeue_event(struct drm_file *file_priv,
|
||||
size_t total, size_t max, struct drm_pending_event **out)
|
||||
{
|
||||
struct drm_device *dev = file_priv->minor->dev;
|
||||
struct drm_pending_event *e;
|
||||
unsigned long flags;
|
||||
bool ret = false;
|
||||
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
|
||||
*out = NULL;
|
||||
if (list_empty(&file_priv->event_list))
|
||||
goto out;
|
||||
e = list_first_entry(&file_priv->event_list,
|
||||
struct drm_pending_event, link);
|
||||
if (e->event->length + total > max)
|
||||
goto out;
|
||||
|
||||
file_priv->event_space += e->event->length;
|
||||
list_del(&e->link);
|
||||
*out = e;
|
||||
ret = true;
|
||||
|
||||
out:
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t drm_read(struct file *filp, char __user *buffer,
|
||||
size_t count, loff_t *offset)
|
||||
{
|
||||
struct drm_file *file_priv = filp->private_data;
|
||||
struct drm_pending_event *e;
|
||||
size_t total;
|
||||
ssize_t ret;
|
||||
struct drm_device *dev = file_priv->minor->dev;
|
||||
ssize_t ret = 0;
|
||||
|
||||
if ((filp->f_flags & O_NONBLOCK) == 0) {
|
||||
ret = wait_event_interruptible(file_priv->event_wait,
|
||||
!list_empty(&file_priv->event_list));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
if (!access_ok(VERIFY_WRITE, buffer, count))
|
||||
return -EFAULT;
|
||||
|
||||
total = 0;
|
||||
while (drm_dequeue_event(file_priv, total, count, &e)) {
|
||||
if (copy_to_user(buffer + total,
|
||||
e->event, e->event->length)) {
|
||||
total = -EFAULT;
|
||||
spin_lock_irq(&dev->event_lock);
|
||||
for (;;) {
|
||||
if (list_empty(&file_priv->event_list)) {
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
if (filp->f_flags & O_NONBLOCK) {
|
||||
ret = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
spin_unlock_irq(&dev->event_lock);
|
||||
ret = wait_event_interruptible(file_priv->event_wait,
|
||||
!list_empty(&file_priv->event_list));
|
||||
spin_lock_irq(&dev->event_lock);
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
ret = 0;
|
||||
} else {
|
||||
struct drm_pending_event *e;
|
||||
|
||||
e = list_first_entry(&file_priv->event_list,
|
||||
struct drm_pending_event, link);
|
||||
if (e->event->length + ret > count)
|
||||
break;
|
||||
|
||||
if (__copy_to_user_inatomic(buffer + ret,
|
||||
e->event, e->event->length)) {
|
||||
if (ret == 0)
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
file_priv->event_space += e->event->length;
|
||||
ret += e->event->length;
|
||||
list_del(&e->link);
|
||||
e->destroy(e);
|
||||
break;
|
||||
}
|
||||
|
||||
total += e->event->length;
|
||||
e->destroy(e);
|
||||
}
|
||||
spin_unlock_irq(&dev->event_lock);
|
||||
|
||||
return total ?: -EAGAIN;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_read);
|
||||
|
||||
|
|
|
@ -103,6 +103,7 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
|
|||
int count = 0;
|
||||
int mode_flags = 0;
|
||||
bool verbose_prune = true;
|
||||
enum drm_connector_status old_status;
|
||||
|
||||
WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
|
||||
|
||||
|
@ -121,7 +122,33 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
|
|||
if (connector->funcs->force)
|
||||
connector->funcs->force(connector);
|
||||
} else {
|
||||
old_status = connector->status;
|
||||
|
||||
connector->status = connector->funcs->detect(connector, true);
|
||||
|
||||
/*
|
||||
* Normally either the driver's hpd code or the poll loop should
|
||||
* pick up any changes and fire the hotplug event. But if
|
||||
* userspace sneaks in a probe, we might miss a change. Hence
|
||||
* check here, and if anything changed start the hotplug code.
|
||||
*/
|
||||
if (old_status != connector->status) {
|
||||
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
|
||||
connector->base.id,
|
||||
connector->name,
|
||||
old_status, connector->status);
|
||||
|
||||
/*
|
||||
* The hotplug event code might call into the fb
|
||||
* helpers, and so expects that we do not hold any
|
||||
* locks. Fire up the poll struct instead, it will
|
||||
* disable itself again.
|
||||
*/
|
||||
dev->mode_config.delayed_event = true;
|
||||
if (dev->mode_config.poll_enabled)
|
||||
schedule_delayed_work(&dev->mode_config.output_poll_work,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Re-enable polling in case the global poll config changed. */
|
||||
|
@ -274,10 +301,14 @@ static void output_poll_execute(struct work_struct *work)
|
|||
struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
|
||||
struct drm_connector *connector;
|
||||
enum drm_connector_status old_status;
|
||||
bool repoll = false, changed = false;
|
||||
bool repoll = false, changed;
|
||||
|
||||
/* Pick up any changes detected by the probe functions. */
|
||||
changed = dev->mode_config.delayed_event;
|
||||
dev->mode_config.delayed_event = false;
|
||||
|
||||
if (!drm_kms_helper_poll)
|
||||
return;
|
||||
goto out;
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
|
@ -304,6 +335,24 @@ static void output_poll_execute(struct work_struct *work)
|
|||
if (old_status != connector->status) {
|
||||
const char *old, *new;
|
||||
|
||||
/*
|
||||
* The poll work sets force=false when calling detect so
|
||||
* that drivers can avoid to do disruptive tests (e.g.
|
||||
* when load detect cycles could cause flickering on
|
||||
* other, running displays). This bears the risk that we
|
||||
* flip-flop between unknown here in the poll work and
|
||||
* the real state when userspace forces a full detect
|
||||
* call after receiving a hotplug event due to this
|
||||
* change.
|
||||
*
|
||||
* Hence clamp an unknown detect status to the old
|
||||
* value.
|
||||
*/
|
||||
if (connector->status == connector_status_unknown) {
|
||||
connector->status = old_status;
|
||||
continue;
|
||||
}
|
||||
|
||||
old = drm_get_connector_status_name(old_status);
|
||||
new = drm_get_connector_status_name(connector->status);
|
||||
|
||||
|
@ -319,6 +368,7 @@ static void output_poll_execute(struct work_struct *work)
|
|||
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
|
||||
out:
|
||||
if (changed)
|
||||
drm_kms_helper_hotplug_event(dev);
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ config DRM_EXYNOS
|
|||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
|
||||
select VIDEOMODE_HELPERS
|
||||
help
|
||||
Choose this option if you have a Samsung SoC EXYNOS chipset.
|
||||
|
|
|
@ -593,6 +593,7 @@ int psb_fbdev_init(struct drm_device *dev)
|
|||
{
|
||||
struct psb_fbdev *fbdev;
|
||||
struct drm_psb_private *dev_priv = dev->dev_private;
|
||||
int ret;
|
||||
|
||||
fbdev = kzalloc(sizeof(struct psb_fbdev), GFP_KERNEL);
|
||||
if (!fbdev) {
|
||||
|
@ -604,16 +605,29 @@ int psb_fbdev_init(struct drm_device *dev)
|
|||
|
||||
drm_fb_helper_prepare(dev, &fbdev->psb_fb_helper, &psb_fb_helper_funcs);
|
||||
|
||||
drm_fb_helper_init(dev, &fbdev->psb_fb_helper, dev_priv->ops->crtcs,
|
||||
INTELFB_CONN_LIMIT);
|
||||
ret = drm_fb_helper_init(dev, &fbdev->psb_fb_helper,
|
||||
dev_priv->ops->crtcs, INTELFB_CONN_LIMIT);
|
||||
if (ret)
|
||||
goto free;
|
||||
|
||||
drm_fb_helper_single_add_all_connectors(&fbdev->psb_fb_helper);
|
||||
ret = drm_fb_helper_single_add_all_connectors(&fbdev->psb_fb_helper);
|
||||
if (ret)
|
||||
goto fini;
|
||||
|
||||
/* disable all the possible outputs/crtcs before entering KMS mode */
|
||||
drm_helper_disable_unused_functions(dev);
|
||||
|
||||
drm_fb_helper_initial_config(&fbdev->psb_fb_helper, 32);
|
||||
ret = drm_fb_helper_initial_config(&fbdev->psb_fb_helper, 32);
|
||||
if (ret)
|
||||
goto fini;
|
||||
|
||||
return 0;
|
||||
|
||||
fini:
|
||||
drm_fb_helper_fini(&fbdev->psb_fb_helper);
|
||||
free:
|
||||
kfree(fbdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void psb_fbdev_fini(struct drm_device *dev)
|
||||
|
|
|
@ -303,14 +303,22 @@ int mgag200_fbdev_init(struct mga_device *mdev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
drm_fb_helper_single_add_all_connectors(&mfbdev->helper);
|
||||
ret = drm_fb_helper_single_add_all_connectors(&mfbdev->helper);
|
||||
if (ret)
|
||||
goto fini;
|
||||
|
||||
/* disable all the possible outputs/crtcs before entering KMS mode */
|
||||
drm_helper_disable_unused_functions(mdev->dev);
|
||||
|
||||
drm_fb_helper_initial_config(&mfbdev->helper, bpp_sel);
|
||||
ret = drm_fb_helper_initial_config(&mfbdev->helper, bpp_sel);
|
||||
if (ret)
|
||||
goto fini;
|
||||
|
||||
return 0;
|
||||
|
||||
fini:
|
||||
drm_fb_helper_fini(&mfbdev->helper);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void mgag200_fbdev_fini(struct mga_device *mdev)
|
||||
|
|
|
@ -241,17 +241,23 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
drm_fb_helper_single_add_all_connectors(helper);
|
||||
ret = drm_fb_helper_single_add_all_connectors(helper);
|
||||
if (ret)
|
||||
goto fini;
|
||||
|
||||
/* disable all the possible outputs/crtcs before entering KMS mode */
|
||||
drm_helper_disable_unused_functions(dev);
|
||||
|
||||
drm_fb_helper_initial_config(helper, 32);
|
||||
ret = drm_fb_helper_initial_config(helper, 32);
|
||||
if (ret)
|
||||
goto fini;
|
||||
|
||||
priv->fbdev = helper;
|
||||
|
||||
return helper;
|
||||
|
||||
fini:
|
||||
drm_fb_helper_fini(helper);
|
||||
fail:
|
||||
kfree(fbdev);
|
||||
return NULL;
|
||||
|
|
|
@ -526,12 +526,12 @@ nouveau_fbcon_init(struct drm_device *dev)
|
|||
|
||||
ret = drm_fb_helper_init(dev, &fbcon->helper,
|
||||
dev->mode_config.num_crtc, 4);
|
||||
if (ret) {
|
||||
kfree(fbcon);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
goto free;
|
||||
|
||||
drm_fb_helper_single_add_all_connectors(&fbcon->helper);
|
||||
ret = drm_fb_helper_single_add_all_connectors(&fbcon->helper);
|
||||
if (ret)
|
||||
goto fini;
|
||||
|
||||
if (drm->device.info.ram_size <= 32 * 1024 * 1024)
|
||||
preferred_bpp = 8;
|
||||
|
@ -544,8 +544,17 @@ nouveau_fbcon_init(struct drm_device *dev)
|
|||
/* disable all the possible outputs/crtcs before entering KMS mode */
|
||||
drm_helper_disable_unused_functions(dev);
|
||||
|
||||
drm_fb_helper_initial_config(&fbcon->helper, preferred_bpp);
|
||||
ret = drm_fb_helper_initial_config(&fbcon->helper, preferred_bpp);
|
||||
if (ret)
|
||||
goto fini;
|
||||
|
||||
return 0;
|
||||
|
||||
fini:
|
||||
drm_fb_helper_fini(&fbcon->helper);
|
||||
free:
|
||||
kfree(fbcon);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -334,17 +334,23 @@ struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
drm_fb_helper_single_add_all_connectors(helper);
|
||||
ret = drm_fb_helper_single_add_all_connectors(helper);
|
||||
if (ret)
|
||||
goto fini;
|
||||
|
||||
/* disable all the possible outputs/crtcs before entering KMS mode */
|
||||
drm_helper_disable_unused_functions(dev);
|
||||
|
||||
drm_fb_helper_initial_config(helper, 32);
|
||||
ret = drm_fb_helper_initial_config(helper, 32);
|
||||
if (ret)
|
||||
goto fini;
|
||||
|
||||
priv->fbdev = helper;
|
||||
|
||||
return helper;
|
||||
|
||||
fini:
|
||||
drm_fb_helper_fini(helper);
|
||||
fail:
|
||||
kfree(fbdev);
|
||||
return NULL;
|
||||
|
|
|
@ -686,14 +686,24 @@ int qxl_fbdev_init(struct qxl_device *qdev)
|
|||
ret = drm_fb_helper_init(qdev->ddev, &qfbdev->helper,
|
||||
qxl_num_crtc /* num_crtc - QXL supports just 1 */,
|
||||
QXLFB_CONN_LIMIT);
|
||||
if (ret) {
|
||||
kfree(qfbdev);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
goto free;
|
||||
|
||||
ret = drm_fb_helper_single_add_all_connectors(&qfbdev->helper);
|
||||
if (ret)
|
||||
goto fini;
|
||||
|
||||
ret = drm_fb_helper_initial_config(&qfbdev->helper, bpp_sel);
|
||||
if (ret)
|
||||
goto fini;
|
||||
|
||||
drm_fb_helper_single_add_all_connectors(&qfbdev->helper);
|
||||
drm_fb_helper_initial_config(&qfbdev->helper, bpp_sel);
|
||||
return 0;
|
||||
|
||||
fini:
|
||||
drm_fb_helper_fini(&qfbdev->helper);
|
||||
free:
|
||||
kfree(qfbdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void qxl_fbdev_fini(struct qxl_device *qdev)
|
||||
|
|
|
@ -390,18 +390,27 @@ int radeon_fbdev_init(struct radeon_device *rdev)
|
|||
ret = drm_fb_helper_init(rdev->ddev, &rfbdev->helper,
|
||||
rdev->num_crtc,
|
||||
RADEONFB_CONN_LIMIT);
|
||||
if (ret) {
|
||||
kfree(rfbdev);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
goto free;
|
||||
|
||||
drm_fb_helper_single_add_all_connectors(&rfbdev->helper);
|
||||
ret = drm_fb_helper_single_add_all_connectors(&rfbdev->helper);
|
||||
if (ret)
|
||||
goto fini;
|
||||
|
||||
/* disable all the possible outputs/crtcs before entering KMS mode */
|
||||
drm_helper_disable_unused_functions(rdev->ddev);
|
||||
|
||||
drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel);
|
||||
ret = drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel);
|
||||
if (ret)
|
||||
goto fini;
|
||||
|
||||
return 0;
|
||||
|
||||
fini:
|
||||
drm_fb_helper_fini(&rfbdev->helper);
|
||||
free:
|
||||
kfree(rfbdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void radeon_fbdev_fini(struct radeon_device *rdev)
|
||||
|
|
|
@ -7,7 +7,6 @@ config DRM_ROCKCHIP
|
|||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
|
||||
select VIDEOMODE_HELPERS
|
||||
help
|
||||
Choose this option if you have a Rockchip soc chipset.
|
||||
|
|
|
@ -589,19 +589,27 @@ int udl_fbdev_init(struct drm_device *dev)
|
|||
|
||||
ret = drm_fb_helper_init(dev, &ufbdev->helper,
|
||||
1, 1);
|
||||
if (ret) {
|
||||
kfree(ufbdev);
|
||||
return ret;
|
||||
if (ret)
|
||||
goto free;
|
||||
|
||||
}
|
||||
|
||||
drm_fb_helper_single_add_all_connectors(&ufbdev->helper);
|
||||
ret = drm_fb_helper_single_add_all_connectors(&ufbdev->helper);
|
||||
if (ret)
|
||||
goto fini;
|
||||
|
||||
/* disable all the possible outputs/crtcs before entering KMS mode */
|
||||
drm_helper_disable_unused_functions(dev);
|
||||
|
||||
drm_fb_helper_initial_config(&ufbdev->helper, bpp_sel);
|
||||
ret = drm_fb_helper_initial_config(&ufbdev->helper, bpp_sel);
|
||||
if (ret)
|
||||
goto fini;
|
||||
|
||||
return 0;
|
||||
|
||||
fini:
|
||||
drm_fb_helper_fini(&ufbdev->helper);
|
||||
free:
|
||||
kfree(ufbdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void udl_fbdev_cleanup(struct drm_device *dev)
|
||||
|
|
|
@ -1093,6 +1093,7 @@ struct drm_mode_config {
|
|||
/* output poll support */
|
||||
bool poll_enabled;
|
||||
bool poll_running;
|
||||
bool delayed_event;
|
||||
struct delayed_work output_poll_work;
|
||||
|
||||
/* pointers to standard properties */
|
||||
|
|
|
@ -125,7 +125,7 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
|
|||
int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
|
||||
|
||||
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
|
||||
bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel);
|
||||
int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel);
|
||||
int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper);
|
||||
int drm_fb_helper_debug_enter(struct fb_info *info);
|
||||
int drm_fb_helper_debug_leave(struct fb_info *info);
|
||||
|
|
Loading…
Reference in New Issue