Commit acc5ddd9 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-misc-next-2016-12-08' of git://anongit.freedesktop.org/git/drm-misc into drm-next

Another pile of misc stuff, final one for 4.10. If there's some serious
bugfix still I'll send you a pull for drm-misc-next-fixes (like we do with
intel), otherwise this is it and next pull next year for 4.11.

Most interesting bits are probably Chris' fb helper fixes against mst
hotplug oopses.

* tag 'drm-misc-next-2016-12-08' of git://anongit.freedesktop.org/git/drm-misc: (22 commits)
  drm: Take ownership of the dmabuf->obj when exporting
  drm: Allow CAP_PRIME on !MODESET
  drm/fence: add drm_crtc_create_fence()
  drm/bridge: analogix: Don't return -EINVAL when panel doesn't support PSR
  drm/atomic: doc: remove old comment about nonblocking commits
  drm: Don't block the kworker waiting for mode_config.mutex in output_poll()
  drm: Return -ENOTSUPP when called for KMS cap with a non-KMS driver
  drm/amdgpu: don't add files at control minor debugfs directory
  drm: allow changing DPMS mode
  drm/qxl: fix use of uninitialized variable
  drm/qxl: Don't register debugfs for control minors
  drm/radeon: don't add files at control minor debugfs directory
  drm/vmwgfx: Switch to mode_cmd2
  drm/vgem: Use ww_mutex_(un)lock even with a NULL context
  drm: Make the connector .detect() callback optional
  drm/bridge: tc358767: don't warn if display side ASSR enable fails
  drm: Initialise drm_mm.head_node.allocated
  drm: Fix locking cargo-cult in encoder/plane init/cleanup
  drm/doc: Fix indenting in drm_modeset_lock.c comment
  drm: Protect fb_helper list manipulation with a mutex
  ...
parents bfd5be0f 72a93e8d
...@@ -2498,9 +2498,6 @@ int amdgpu_debugfs_add_files(struct amdgpu_device *adev, ...@@ -2498,9 +2498,6 @@ int amdgpu_debugfs_add_files(struct amdgpu_device *adev,
adev->debugfs[adev->debugfs_count].num_files = nfiles; adev->debugfs[adev->debugfs_count].num_files = nfiles;
adev->debugfs_count = i; adev->debugfs_count = i;
#if defined(CONFIG_DEBUG_FS) #if defined(CONFIG_DEBUG_FS)
drm_debugfs_create_files(files, nfiles,
adev->ddev->control->debugfs_root,
adev->ddev->control);
drm_debugfs_create_files(files, nfiles, drm_debugfs_create_files(files, nfiles,
adev->ddev->primary->debugfs_root, adev->ddev->primary->debugfs_root,
adev->ddev->primary); adev->ddev->primary);
...@@ -2514,9 +2511,6 @@ static void amdgpu_debugfs_remove_files(struct amdgpu_device *adev) ...@@ -2514,9 +2511,6 @@ static void amdgpu_debugfs_remove_files(struct amdgpu_device *adev)
unsigned i; unsigned i;
for (i = 0; i < adev->debugfs_count; i++) { for (i = 0; i < adev->debugfs_count; i++) {
drm_debugfs_remove_files(adev->debugfs[i].files,
adev->debugfs[i].num_files,
adev->ddev->control);
drm_debugfs_remove_files(adev->debugfs[i].files, drm_debugfs_remove_files(adev->debugfs[i].files,
adev->debugfs[i].num_files, adev->debugfs[i].num_files,
adev->ddev->primary); adev->ddev->primary);
......
...@@ -424,12 +424,6 @@ dce_virtual_dpms(struct drm_connector *connector, int mode) ...@@ -424,12 +424,6 @@ dce_virtual_dpms(struct drm_connector *connector, int mode)
return 0; return 0;
} }
static enum drm_connector_status
dce_virtual_detect(struct drm_connector *connector, bool force)
{
return connector_status_connected;
}
static int static int
dce_virtual_set_property(struct drm_connector *connector, dce_virtual_set_property(struct drm_connector *connector,
struct drm_property *property, struct drm_property *property,
...@@ -458,7 +452,6 @@ static const struct drm_connector_helper_funcs dce_virtual_connector_helper_func ...@@ -458,7 +452,6 @@ static const struct drm_connector_helper_funcs dce_virtual_connector_helper_func
static const struct drm_connector_funcs dce_virtual_connector_funcs = { static const struct drm_connector_funcs dce_virtual_connector_funcs = {
.dpms = dce_virtual_dpms, .dpms = dce_virtual_dpms,
.detect = dce_virtual_detect,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.set_property = dce_virtual_set_property, .set_property = dce_virtual_set_property,
.destroy = dce_virtual_destroy, .destroy = dce_virtual_destroy,
......
...@@ -41,12 +41,6 @@ static int arcpgu_drm_connector_get_modes(struct drm_connector *connector) ...@@ -41,12 +41,6 @@ static int arcpgu_drm_connector_get_modes(struct drm_connector *connector)
return count; return count;
} }
static enum drm_connector_status
arcpgu_drm_connector_detect(struct drm_connector *connector, bool force)
{
return connector_status_connected;
}
static void arcpgu_drm_connector_destroy(struct drm_connector *connector) static void arcpgu_drm_connector_destroy(struct drm_connector *connector)
{ {
drm_connector_unregister(connector); drm_connector_unregister(connector);
...@@ -61,7 +55,6 @@ arcpgu_drm_connector_helper_funcs = { ...@@ -61,7 +55,6 @@ arcpgu_drm_connector_helper_funcs = {
static const struct drm_connector_funcs arcpgu_drm_connector_funcs = { static const struct drm_connector_funcs arcpgu_drm_connector_funcs = {
.dpms = drm_helper_connector_dpms, .dpms = drm_helper_connector_dpms,
.reset = drm_atomic_helper_connector_reset, .reset = drm_atomic_helper_connector_reset,
.detect = arcpgu_drm_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.destroy = arcpgu_drm_connector_destroy, .destroy = arcpgu_drm_connector_destroy,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
......
...@@ -839,12 +839,6 @@ static void ast_connector_destroy(struct drm_connector *connector) ...@@ -839,12 +839,6 @@ static void ast_connector_destroy(struct drm_connector *connector)
kfree(connector); kfree(connector);
} }
static enum drm_connector_status
ast_connector_detect(struct drm_connector *connector, bool force)
{
return connector_status_connected;
}
static const struct drm_connector_helper_funcs ast_connector_helper_funcs = { static const struct drm_connector_helper_funcs ast_connector_helper_funcs = {
.mode_valid = ast_mode_valid, .mode_valid = ast_mode_valid,
.get_modes = ast_get_modes, .get_modes = ast_get_modes,
...@@ -853,7 +847,6 @@ static const struct drm_connector_helper_funcs ast_connector_helper_funcs = { ...@@ -853,7 +847,6 @@ static const struct drm_connector_helper_funcs ast_connector_helper_funcs = {
static const struct drm_connector_funcs ast_connector_funcs = { static const struct drm_connector_funcs ast_connector_funcs = {
.dpms = drm_helper_connector_dpms, .dpms = drm_helper_connector_dpms,
.detect = ast_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.destroy = ast_connector_destroy, .destroy = ast_connector_destroy,
}; };
......
...@@ -216,12 +216,6 @@ bochs_connector_best_encoder(struct drm_connector *connector) ...@@ -216,12 +216,6 @@ bochs_connector_best_encoder(struct drm_connector *connector)
return NULL; return NULL;
} }
static enum drm_connector_status bochs_connector_detect(struct drm_connector
*connector, bool force)
{
return connector_status_connected;
}
static const struct drm_connector_helper_funcs bochs_connector_connector_helper_funcs = { static const struct drm_connector_helper_funcs bochs_connector_connector_helper_funcs = {
.get_modes = bochs_connector_get_modes, .get_modes = bochs_connector_get_modes,
.mode_valid = bochs_connector_mode_valid, .mode_valid = bochs_connector_mode_valid,
...@@ -230,7 +224,6 @@ static const struct drm_connector_helper_funcs bochs_connector_connector_helper_ ...@@ -230,7 +224,6 @@ static const struct drm_connector_helper_funcs bochs_connector_connector_helper_
static const struct drm_connector_funcs bochs_connector_connector_funcs = { static const struct drm_connector_funcs bochs_connector_connector_funcs = {
.dpms = drm_helper_connector_dpms, .dpms = drm_helper_connector_dpms,
.detect = bochs_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup, .destroy = drm_connector_cleanup,
}; };
......
...@@ -112,7 +112,7 @@ int analogix_dp_enable_psr(struct device *dev) ...@@ -112,7 +112,7 @@ int analogix_dp_enable_psr(struct device *dev)
struct edp_vsc_psr psr_vsc; struct edp_vsc_psr psr_vsc;
if (!dp->psr_support) if (!dp->psr_support)
return -EINVAL; return 0;
/* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
memset(&psr_vsc, 0, sizeof(psr_vsc)); memset(&psr_vsc, 0, sizeof(psr_vsc));
...@@ -135,7 +135,7 @@ int analogix_dp_disable_psr(struct device *dev) ...@@ -135,7 +135,7 @@ int analogix_dp_disable_psr(struct device *dev)
struct edp_vsc_psr psr_vsc; struct edp_vsc_psr psr_vsc;
if (!dp->psr_support) if (!dp->psr_support)
return -EINVAL; return 0;
/* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
memset(&psr_vsc, 0, sizeof(psr_vsc)); memset(&psr_vsc, 0, sizeof(psr_vsc));
......
...@@ -239,16 +239,9 @@ static const struct drm_connector_helper_funcs ptn3460_connector_helper_funcs = ...@@ -239,16 +239,9 @@ static const struct drm_connector_helper_funcs ptn3460_connector_helper_funcs =
.get_modes = ptn3460_get_modes, .get_modes = ptn3460_get_modes,
}; };
static enum drm_connector_status ptn3460_detect(struct drm_connector *connector,
bool force)
{
return connector_status_connected;
}
static const struct drm_connector_funcs ptn3460_connector_funcs = { static const struct drm_connector_funcs ptn3460_connector_funcs = {
.dpms = drm_atomic_helper_connector_dpms, .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.detect = ptn3460_detect,
.destroy = drm_connector_cleanup, .destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset, .reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
......
...@@ -477,16 +477,9 @@ static const struct drm_connector_helper_funcs ps8622_connector_helper_funcs = { ...@@ -477,16 +477,9 @@ static const struct drm_connector_helper_funcs ps8622_connector_helper_funcs = {
.get_modes = ps8622_get_modes, .get_modes = ps8622_get_modes,
}; };
static enum drm_connector_status ps8622_detect(struct drm_connector *connector,
bool force)
{
return connector_status_connected;
}
static const struct drm_connector_funcs ps8622_connector_funcs = { static const struct drm_connector_funcs ps8622_connector_funcs = {
.dpms = drm_atomic_helper_connector_dpms, .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.detect = ps8622_detect,
.destroy = drm_connector_cleanup, .destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset, .reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
......
...@@ -908,7 +908,7 @@ static int tc_main_link_setup(struct tc_data *tc) ...@@ -908,7 +908,7 @@ static int tc_main_link_setup(struct tc_data *tc)
goto err_dpcd_read; goto err_dpcd_read;
if (tmp[0] != tc->assr) { if (tmp[0] != tc->assr) {
dev_warn(dev, "Failed to switch display ASSR to %d, falling back to unscrambled mode\n", dev_dbg(dev, "Failed to switch display ASSR to %d, falling back to unscrambled mode\n",
tc->assr); tc->assr);
/* trying with disabled scrambler */ /* trying with disabled scrambler */
tc->link.scrambler_dis = 1; tc->link.scrambler_dis = 1;
...@@ -1038,12 +1038,6 @@ static int tc_main_link_stream(struct tc_data *tc, int state) ...@@ -1038,12 +1038,6 @@ static int tc_main_link_stream(struct tc_data *tc, int state)
return ret; return ret;
} }
static enum drm_connector_status
tc_connector_detect(struct drm_connector *connector, bool force)
{
return connector_status_connected;
}
static void tc_bridge_pre_enable(struct drm_bridge *bridge) static void tc_bridge_pre_enable(struct drm_bridge *bridge)
{ {
struct tc_data *tc = bridge_to_tc(bridge); struct tc_data *tc = bridge_to_tc(bridge);
...@@ -1168,7 +1162,6 @@ static const struct drm_connector_helper_funcs tc_connector_helper_funcs = { ...@@ -1168,7 +1162,6 @@ static const struct drm_connector_helper_funcs tc_connector_helper_funcs = {
static const struct drm_connector_funcs tc_connector_funcs = { static const struct drm_connector_funcs tc_connector_funcs = {
.dpms = drm_atomic_helper_connector_dpms, .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.detect = tc_connector_detect,
.destroy = drm_connector_cleanup, .destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset, .reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
......
...@@ -498,12 +498,6 @@ static struct drm_encoder *cirrus_connector_best_encoder(struct drm_connector ...@@ -498,12 +498,6 @@ static struct drm_encoder *cirrus_connector_best_encoder(struct drm_connector
return NULL; return NULL;
} }
static enum drm_connector_status cirrus_vga_detect(struct drm_connector
*connector, bool force)
{
return connector_status_connected;
}
static void cirrus_connector_destroy(struct drm_connector *connector) static void cirrus_connector_destroy(struct drm_connector *connector)
{ {
drm_connector_cleanup(connector); drm_connector_cleanup(connector);
...@@ -517,7 +511,6 @@ static const struct drm_connector_helper_funcs cirrus_vga_connector_helper_funcs ...@@ -517,7 +511,6 @@ static const struct drm_connector_helper_funcs cirrus_vga_connector_helper_funcs
static const struct drm_connector_funcs cirrus_vga_connector_funcs = { static const struct drm_connector_funcs cirrus_vga_connector_funcs = {
.dpms = drm_helper_connector_dpms, .dpms = drm_helper_connector_dpms,
.detect = cirrus_vga_detect,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.destroy = cirrus_connector_destroy, .destroy = cirrus_connector_destroy,
}; };
......
...@@ -1864,20 +1864,6 @@ EXPORT_SYMBOL(drm_atomic_clean_old_fb); ...@@ -1864,20 +1864,6 @@ EXPORT_SYMBOL(drm_atomic_clean_old_fb);
* helpers and for the DRM event handling for existing userspace. * helpers and for the DRM event handling for existing userspace.
*/ */
static struct dma_fence *get_crtc_fence(struct drm_crtc *crtc)
{
struct dma_fence *fence;
fence = kzalloc(sizeof(*fence), GFP_KERNEL);
if (!fence)
return NULL;
dma_fence_init(fence, &drm_crtc_fence_ops, &crtc->fence_lock,
crtc->fence_context, ++crtc->fence_seqno);
return fence;
}
struct drm_out_fence_state { struct drm_out_fence_state {
s64 __user *out_fence_ptr; s64 __user *out_fence_ptr;
struct sync_file *sync_file; struct sync_file *sync_file;
...@@ -1959,7 +1945,7 @@ static int prepare_crtc_signaling(struct drm_device *dev, ...@@ -1959,7 +1945,7 @@ static int prepare_crtc_signaling(struct drm_device *dev,
f[*num_fences].out_fence_ptr = fence_ptr; f[*num_fences].out_fence_ptr = fence_ptr;
*fence_state = f; *fence_state = f;
fence = get_crtc_fence(crtc); fence = drm_crtc_create_fence(crtc);
if (!fence) if (!fence)
return -ENOMEM; return -ENOMEM;
......
...@@ -1234,9 +1234,6 @@ static void commit_work(struct work_struct *work) ...@@ -1234,9 +1234,6 @@ static void commit_work(struct work_struct *work)
* function implements nonblocking commits, using * function implements nonblocking commits, using
* drm_atomic_helper_setup_commit() and related functions. * drm_atomic_helper_setup_commit() and related functions.
* *
* Note that right now this function does not support nonblocking commits, hence
* driver writers must implement their own version for now.
*
* Committing the actual hardware state is done through the * Committing the actual hardware state is done through the
* ->atomic_commit_tail() callback of the &drm_mode_config_helper_funcs vtable, * ->atomic_commit_tail() callback of the &drm_mode_config_helper_funcs vtable,
* or it's default implementation drm_atomic_helper_commit_tail(). * or it's default implementation drm_atomic_helper_commit_tail().
...@@ -2885,8 +2882,8 @@ int drm_atomic_helper_connector_dpms(struct drm_connector *connector, ...@@ -2885,8 +2882,8 @@ int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
fail: fail:
if (ret == -EDEADLK) if (ret == -EDEADLK)
goto backoff; goto backoff;
if (ret != 0)
connector->dpms = old_mode; connector->dpms = old_mode;
drm_atomic_state_put(state); drm_atomic_state_put(state);
return ret; return ret;
......
...@@ -152,6 +152,8 @@ static void drm_crtc_crc_fini(struct drm_crtc *crtc) ...@@ -152,6 +152,8 @@ static void drm_crtc_crc_fini(struct drm_crtc *crtc)
#endif #endif
} }
static const struct dma_fence_ops drm_crtc_fence_ops;
static struct drm_crtc *fence_to_crtc(struct dma_fence *fence) static struct drm_crtc *fence_to_crtc(struct dma_fence *fence)
{ {
BUG_ON(fence->ops != &drm_crtc_fence_ops); BUG_ON(fence->ops != &drm_crtc_fence_ops);
...@@ -177,13 +179,27 @@ static bool drm_crtc_fence_enable_signaling(struct dma_fence *fence) ...@@ -177,13 +179,27 @@ static bool drm_crtc_fence_enable_signaling(struct dma_fence *fence)
return true; return true;
} }
const struct dma_fence_ops drm_crtc_fence_ops = { static const struct dma_fence_ops drm_crtc_fence_ops = {
.get_driver_name = drm_crtc_fence_get_driver_name, .get_driver_name = drm_crtc_fence_get_driver_name,
.get_timeline_name = drm_crtc_fence_get_timeline_name, .get_timeline_name = drm_crtc_fence_get_timeline_name,
.enable_signaling = drm_crtc_fence_enable_signaling, .enable_signaling = drm_crtc_fence_enable_signaling,
.wait = dma_fence_default_wait, .wait = dma_fence_default_wait,
}; };
struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc)
{
struct dma_fence *fence;
fence = kzalloc(sizeof(*fence), GFP_KERNEL);
if (!fence)
return NULL;
dma_fence_init(fence, &drm_crtc_fence_ops, &crtc->fence_lock,
crtc->fence_context, ++crtc->fence_seqno);
return fence;
}
/** /**
* drm_crtc_init_with_planes - Initialise a new CRTC object with * drm_crtc_init_with_planes - Initialise a new CRTC object with
* specified primary and cursor planes. * specified primary and cursor planes.
......
...@@ -43,7 +43,7 @@ int drm_crtc_check_viewport(const struct drm_crtc *crtc, ...@@ -43,7 +43,7 @@ int drm_crtc_check_viewport(const struct drm_crtc *crtc,
int drm_crtc_register_all(struct drm_device *dev); int drm_crtc_register_all(struct drm_device *dev);
void drm_crtc_unregister_all(struct drm_device *dev); void drm_crtc_unregister_all(struct drm_device *dev);
extern const struct dma_fence_ops drm_crtc_fence_ops; struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc);
/* IOCTLs */ /* IOCTLs */
int drm_mode_getcrtc(struct drm_device *dev, int drm_mode_getcrtc(struct drm_device *dev,
......
...@@ -110,11 +110,9 @@ int drm_encoder_init(struct drm_device *dev, ...@@ -110,11 +110,9 @@ int drm_encoder_init(struct drm_device *dev,
{ {
int ret; int ret;
drm_modeset_lock_all(dev);
ret = drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER); ret = drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
if (ret) if (ret)
goto out_unlock; return ret;
encoder->dev = dev; encoder->dev = dev;
encoder->encoder_type = encoder_type; encoder->encoder_type = encoder_type;
...@@ -142,9 +140,6 @@ int drm_encoder_init(struct drm_device *dev, ...@@ -142,9 +140,6 @@ int drm_encoder_init(struct drm_device *dev,
if (ret) if (ret)
drm_mode_object_unregister(dev, &encoder->base); drm_mode_object_unregister(dev, &encoder->base);
out_unlock:
drm_modeset_unlock_all(dev);
return ret; return ret;
} }
EXPORT_SYMBOL(drm_encoder_init); EXPORT_SYMBOL(drm_encoder_init);
...@@ -164,12 +159,10 @@ void drm_encoder_cleanup(struct drm_encoder *encoder) ...@@ -164,12 +159,10 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
* the indices on the drm_encoder after us in the encoder_list. * the indices on the drm_encoder after us in the encoder_list.
*/ */
drm_modeset_lock_all(dev);
drm_mode_object_unregister(dev, &encoder->base); drm_mode_object_unregister(dev, &encoder->base);
kfree(encoder->name); kfree(encoder->name);
list_del(&encoder->head); list_del(&encoder->head);
dev->mode_config.num_encoder--; dev->mode_config.num_encoder--;
drm_modeset_unlock_all(dev);
memset(encoder, 0, sizeof(*encoder)); memset(encoder, 0, sizeof(*encoder));
} }
......
...@@ -49,6 +49,7 @@ MODULE_PARM_DESC(fbdev_emulation, ...@@ -49,6 +49,7 @@ MODULE_PARM_DESC(fbdev_emulation,
"Enable legacy fbdev emulation [default=true]"); "Enable legacy fbdev emulation [default=true]");
static LIST_HEAD(kernel_fb_helper_list); static LIST_HEAD(kernel_fb_helper_list);
static DEFINE_MUTEX(kernel_fb_helper_lock);
/** /**
* DOC: fbdev helpers * DOC: fbdev helpers
...@@ -97,6 +98,10 @@ static LIST_HEAD(kernel_fb_helper_list); ...@@ -97,6 +98,10 @@ static LIST_HEAD(kernel_fb_helper_list);
* mmap page writes. * mmap page writes.
*/ */
#define drm_fb_helper_for_each_connector(fbh, i__) \
for (({ lockdep_assert_held(&(fbh)->dev->mode_config.mutex); }), \
i__ = 0; i__ < (fbh)->connector_count; i__++)
/** /**
* drm_fb_helper_single_add_all_connectors() - add all connectors to fbdev * drm_fb_helper_single_add_all_connectors() - add all connectors to fbdev
* emulation helper * emulation helper
...@@ -130,7 +135,7 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper) ...@@ -130,7 +135,7 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
mutex_unlock(&dev->mode_config.mutex); mutex_unlock(&dev->mode_config.mutex);
return 0; return 0;
fail: fail:
for (i = 0; i < fb_helper->connector_count; i++) { drm_fb_helper_for_each_connector(fb_helper, i) {
struct drm_fb_helper_connector *fb_helper_connector = struct drm_fb_helper_connector *fb_helper_connector =
fb_helper->connector_info[i]; fb_helper->connector_info[i];
...@@ -565,7 +570,7 @@ static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode) ...@@ -565,7 +570,7 @@ static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
continue; continue;
/* Walk the connectors & encoders on this fb turning them on/off */ /* Walk the connectors & encoders on this fb turning them on/off */
for (j = 0; j < fb_helper->connector_count; j++) { drm_fb_helper_for_each_connector(fb_helper, j) {
connector = fb_helper->connector_info[j]->connector; connector = fb_helper->connector_info[j]->connector;
connector->funcs->dpms(connector, dpms_mode); connector->funcs->dpms(connector, dpms_mode);
drm_object_property_set_value(&connector->base, drm_object_property_set_value(&connector->base,
...@@ -851,12 +856,14 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) ...@@ -851,12 +856,14 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
if (!drm_fbdev_emulation) if (!drm_fbdev_emulation)
return; return;
mutex_lock(&kernel_fb_helper_lock);
if (!list_empty(&fb_helper->kernel_fb_list)) { if (!list_empty(&fb_helper->kernel_fb_list)) {
list_del(&fb_helper->kernel_fb_list); list_del(&fb_helper->kernel_fb_list);
if (list_empty(&kernel_fb_helper_list)) { if (list_empty(&kernel_fb_helper_list)) {
unregister_sysrq_key('v', &sysrq_drm_fb_helper_restore_op); unregister_sysrq_key('v', &sysrq_drm_fb_helper_restore_op);
} }
} }
mutex_unlock(&kernel_fb_helper_lock);
drm_fb_helper_crtc_free(fb_helper); drm_fb_helper_crtc_free(fb_helper);
...@@ -1469,7 +1476,6 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, ...@@ -1469,7 +1476,6 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
int ret = 0; int ret = 0;
int crtc_count = 0; int crtc_count = 0;
int i; int i;
struct fb_info *info;
struct drm_fb_helper_surface_size sizes; struct drm_fb_helper_surface_size sizes;
int gamma_size = 0; int gamma_size = 0;
...@@ -1485,7 +1491,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, ...@@ -1485,7 +1491,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
sizes.surface_depth = sizes.surface_bpp = preferred_bpp; sizes.surface_depth = sizes.surface_bpp = preferred_bpp;
/* first up get a count of crtcs now in use and new min/maxes width/heights */ /* first up get a count of crtcs now in use and new min/maxes width/heights */
for (i = 0; i < fb_helper->connector_count; i++) { drm_fb_helper_for_each_connector(fb_helper, i) {
struct drm_fb_helper_connector *fb_helper_conn = fb_helper->connector_info[i]; struct drm_fb_helper_connector *fb_helper_conn = fb_helper->connector_info[i];
struct drm_cmdline_mode *cmdline_mode; struct drm_cmdline_mode *cmdline_mode;
...@@ -1572,8 +1578,6 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, ...@@ -1572,8 +1578,6 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
if (ret < 0) if (ret < 0)
return ret; return ret;
info = fb_helper->fbdev;
/* /*
* Set the fb pointer - usually drm_setup_crtcs does this for hotplug * Set the fb pointer - usually drm_setup_crtcs does this for hotplug
* events, but at init time drm_setup_crtcs needs to be called before * events, but at init time drm_setup_crtcs needs to be called before
...@@ -1585,20 +1589,6 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, ...@@ -1585,20 +1589,6 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
if (fb_helper->crtc_info[i].mode_set.num_connectors) if (fb_helper->crtc_info[i].mode_set.num_connectors)
fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb; fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb;
info->var.pixclock = 0;
if (register_framebuffer(info) < 0)
return -EINVAL;
dev_info(fb_helper->dev->dev, "fb%d: %s frame buffer device\n",
info->node, info->fix.id);
if (list_empty(&kernel_fb_helper_list)) {
register_sysrq_key('v', &sysrq_drm_fb_helper_restore_op);
}
list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list);
return 0; return 0;
} }
...@@ -1730,7 +1720,7 @@ static int drm_fb_helper_probe_connector_modes(struct drm_fb_helper *fb_helper, ...@@ -1730,7 +1720,7 @@ static int drm_fb_helper_probe_connector_modes(struct drm_fb_helper *fb_helper,
int count = 0; int count = 0;
int i; int i;
for (i = 0; i < fb_helper->connector_count; i++) { drm_fb_helper_for_each_connector(fb_helper, i) {
connector = fb_helper->connector_info[i]->connector; connector = fb_helper->connector_info[i]->connector;
count += connector->funcs->fill_modes(connector, maxX, maxY); count += connector->funcs->fill_modes(connector, maxX, maxY);
} }
...@@ -1830,7 +1820,7 @@ static void drm_enable_connectors(struct drm_fb_helper *fb_helper, ...@@ -1830,7 +1820,7 @@ static void drm_enable_connectors(struct drm_fb_helper *fb_helper,
struct drm_connector *connector; struct drm_connector *connector;
int i = 0; int i = 0;
for (i = 0; i < fb_helper->connector_count; i++) { drm_fb_helper_for_each_connector(fb_helper, i) {
connector = fb_helper->connector_info[i]->connector; connector = fb_helper->connector_info[i]->connector;
enabled[i] = drm_connector_enabled(connector, true); enabled[i] = drm_connector_enabled(connector, true);
DRM_DEBUG_KMS("connector %d enabled? %s\n", connector->base.id, DRM_DEBUG_KMS("connector %d enabled? %s\n", connector->base.id,
...@@ -1841,7 +1831,7 @@ static void drm_enable_connectors(struct drm_fb_helper *fb_helper, ...@@ -1841,7 +1831,7 @@ static void drm_enable_connectors(struct drm_fb_helper *fb_helper,
if (any_enabled) if (any_enabled)
return; return;
for (i = 0; i < fb_helper->connector_count; i++) { drm_fb_helper_for_each_connector(fb_helper, i) {
connector = fb_helper->connector_info[i]->connector; connector = fb_helper->connector_info[i]->connector;
enabled[i] = drm_connector_enabled(connector, false); enabled[i] = drm_connector_enabled(connector, false);
} }
...@@ -1862,7 +1852,7 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper, ...@@ -1862,7 +1852,7 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper,
return false; return false;
count = 0; count = 0;
for (i = 0; i < fb_helper->connector_count; i++) { drm_fb_helper_for_each_connector(fb_helper, i) {
if (enabled[i]) if (enabled[i])
count++; count++;
} }
...@@ -1873,7 +1863,7 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper, ...@@ -1873,7 +1863,7 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper,
/* check the command line or if nothing common pick 1024x768 */ /* check the command line or if nothing common pick 1024x768 */
can_clone = true; can_clone = true;
for (i = 0; i < fb_helper->connector_count; i++) { drm_fb_helper_for_each_connector(fb_helper, i) {
if (!enabled[i]) if (!enabled[i])
continue; continue;
fb_helper_conn = fb_helper->connector_info[i]; fb_helper_conn = fb_helper->connector_info[i];
...@@ -1899,8 +1889,7 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper, ...@@ -1899,8 +1889,7 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper,
can_clone = true; can_clone = true;
dmt_mode = drm_mode_find_dmt(fb_helper->dev, 1024, 768, 60, false); dmt_mode = drm_mode_find_dmt(fb_helper->dev, 1024, 768, 60, false);
for (i = 0; i < fb_helper->connector_count; i++) { drm_fb_helper_for_each_connector(fb_helper, i) {
if (!enabled[i]) if (!enabled[i])
continue; continue;
...@@ -1931,7 +1920,7 @@ static int drm_get_tile_offsets(struct drm_fb_helper *fb_helper, ...@@ -1931,7 +1920,7 @@ static int drm_get_tile_offsets(struct drm_fb_helper *fb_helper,
int i; int i;
int hoffset = 0, voffset = 0; int hoffset = 0, voffset = 0;
for (i = 0; i < fb_helper->connector_count; i++) { drm_fb_helper_for_each_connector(fb_helper, i) {
fb_helper_conn = fb_helper->connector_info[i]; fb_helper_conn = fb_helper->connector_info[i];
if (!fb_helper_conn->connector->has_tile) if (!fb_helper_conn->connector->has_tile)
continue; continue;
...@@ -1965,7 +1954,7 @@ static bool drm_target_preferred(struct drm_fb_helper *fb_helper, ...@@ -1965,7 +1954,7 @@ static bool drm_target_preferred(struct drm_fb_helper *fb_helper,
int i; int i;
retry: retry:
for (i = 0; i < fb_helper->connector_count; i++) { drm_fb_helper_for_each_connector(fb_helper, i) {
fb_helper_conn = fb_helper->connector_info[i]; fb_helper_conn = fb_helper->connector_info[i];
if (conn_configured & BIT_ULL(i)) if (conn_configured & BIT_ULL(i))
...@@ -2113,20 +2102,22 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, ...@@ -2113,20 +2102,22 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
return best_score; return best_score;
} }
static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
u32 width, u32 height)
{ {
struct drm_device *dev = fb_helper->dev; struct drm_device *dev = fb_helper->dev;
struct drm_fb_helper_crtc **crtcs; struct drm_fb_helper_crtc **crtcs;
struct drm_display_mode **modes; struct drm_display_mode **modes;
struct drm_fb_offset *offsets; struct drm_fb_offset *offsets;
bool *enabled; bool *enabled;
int width, height;
int i; int i;
DRM_DEBUG_KMS("\n"); DRM_DEBUG_KMS("\n");
if (drm_fb_helper_probe_connector_modes(fb_helper, width, height) == 0)
DRM_DEBUG_KMS("No connectors reported connected with modes\n");
width = dev->mode_config.max_width; /* prevent concurrent modification of connector_count by hotplug */
height = dev->mode_config.max_height; lockdep_assert_held(&fb_helper->dev->mode_config.mutex);
crtcs = kcalloc(fb_helper->connector_count, crtcs = kcalloc(fb_helper->connector_count,
sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL); sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);
...@@ -2141,7 +2132,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) ...@@ -2141,7 +2132,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
goto out; goto out;
} }
drm_enable_connectors(fb_helper, enabled); drm_enable_connectors(fb_helper, enabled);
if (!(fb_helper->funcs->initial_config && if (!(fb_helper->funcs->initial_config &&
...@@ -2170,7 +2160,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) ...@@ -2170,7 +2160,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
drm_fb_helper_modeset_release(fb_helper, drm_fb_helper_modeset_release(fb_helper,
&fb_helper->crtc_info[i].mode_set); &fb_helper->crtc_info[i].mode_set);
for (i = 0; i < fb_helper->connector_count; i++) { drm_fb_helper_for_each_connector(fb_helper, i) {
struct drm_display_mode *mode = modes[i]; struct drm_display_mode *mode = modes[i];
struct drm_fb_helper_crtc *fb_crtc = crtcs[i]; struct drm_fb_helper_crtc *fb_crtc = crtcs[i];
struct drm_fb_offset *offset = &offsets[i]; struct drm_fb_offset *offset = &offsets[i];
...@@ -2247,25 +2237,38 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) ...@@ -2247,25 +2237,38 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
int 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; struct drm_device *dev = fb_helper->dev;
int count = 0; struct fb_info *info;
int ret;
if (!drm_fbdev_emulation) if (!drm_fbdev_emulation)
return 0; return 0;
mutex_lock(&dev->mode_config.mutex); mutex_lock(&dev->mode_config.mutex);
count = drm_fb_helper_probe_connector_modes(fb_helper, drm_setup_crtcs(fb_helper,
dev->mode_config.max_width, dev->mode_config.max_width,
dev->mode_config.max_height); dev->mode_config.max_height);
ret = drm_fb_helper_single_fb_probe(fb_helper, bpp_sel);
mutex_unlock(&dev->mode_config.mutex); mutex_unlock(&dev->mode_config.mutex);
/* if (ret)
* we shouldn't end up with no modes here. return ret;
*/
if (count == 0) info = fb_helper->fbdev;
dev_info(fb_helper->dev->dev, "No connectors reported connected with modes\n"); info->var.pixclock = 0;
ret = register_framebuffer(info);
if (ret < 0)
return ret;
dev_info(dev->dev, "fb%d: %s frame buffer device\n",
info->node, info->fix.id);
mutex_lock(&kernel_fb_helper_lock);
if (list_empty(&kernel_fb_helper_list))
register_sysrq_key('v', &sysrq_drm_fb_helper_restore_op);
drm_setup_crtcs(fb_helper); list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list);
mutex_unlock(&kernel_fb_helper_lock);
return drm_fb_helper_single_fb_probe(fb_helper, bpp_sel); return 0;
} }
EXPORT_SYMBOL(drm_fb_helper_initial_config); EXPORT_SYMBOL(drm_fb_helper_initial_config);
...@@ -2293,28 +2296,22 @@ EXPORT_SYMBOL(drm_fb_helper_initial_config); ...@@ -2293,28 +2296,22 @@ EXPORT_SYMBOL(drm_fb_helper_initial_config);
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
{ {
struct drm_device *dev = fb_helper->dev; struct drm_device *dev = fb_helper->dev;
u32 max_width, max_height;
if (!drm_fbdev_emulation) if (!drm_fbdev_emulation)
return 0; return 0;
mutex_lock(&fb_helper->dev->mode_config.mutex); mutex_lock(&dev->mode_config.mutex);
if (!fb_helper->fb || !drm_fb_helper_is_bound(fb_helper)) { if (!fb_helper->fb || !drm_fb_helper_is_bound(fb_helper)) {
fb_helper->delayed_hotplug = true; fb_helper->delayed_hotplug = true;
mutex_unlock(&fb_helper->dev->mode_config.mutex); mutex_unlock(&dev->mode_config.mutex);
return 0; return 0;
} }
DRM_DEBUG_KMS("\n"); DRM_DEBUG_KMS("\n");
max_width = fb_helper->fb->width; drm_setup_crtcs(fb_helper, fb_helper->fb->width, fb_helper->fb->height);
max_height = fb_helper->fb->height;
drm_fb_helper_probe_connector_modes(fb_helper, max_width, max_height); mutex_unlock(&dev->mode_config.mutex);
mutex_unlock(&fb_helper->dev->mode_config.mutex);
drm_modeset_lock_all(dev);
drm_setup_crtcs(fb_helper);
drm_modeset_unlock_all(dev);
drm_fb_helper_set_par(fb_helper->fbdev); drm_fb_helper_set_par(fb_helper->fbdev);
return 0; return 0;
......
...@@ -229,6 +229,22 @@ static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_ ...@@ -229,6 +229,22 @@ static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_
struct drm_crtc *crtc; struct drm_crtc *crtc;
req->value = 0; req->value = 0;
/* Only some caps make sense with UMS/render-only drivers. */
switch (req->capability) {
case DRM_CAP_TIMESTAMP_MONOTONIC:
req->value = drm_timestamp_monotonic;
return 0;
case DRM_CAP_PRIME:
req->value |= dev->driver->prime_fd_to_handle ? DRM_PRIME_CAP_IMPORT : 0;
req->value |= dev->driver->prime_handle_to_fd ? DRM_PRIME_CAP_EXPORT : 0;
return 0;
}
/* Other caps only work with KMS drivers */
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -ENOTSUPP;
switch (req->capability) { switch (req->capability) {
case DRM_CAP_DUMB_BUFFER: case DRM_CAP_DUMB_BUFFER:
if (dev->driver->dumb_create) if (dev->driver->dumb_create)
...@@ -243,23 +259,14 @@ static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_ ...@@ -243,23 +259,14 @@ static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_
case DRM_CAP_DUMB_PREFER_SHADOW: case DRM_CAP_DUMB_PREFER_SHADOW:
req->value = dev->mode_config.prefer_shadow; req->value = dev->mode_config.prefer_shadow;
break; break;
case DRM_CAP_PRIME:
req->value |= dev->driver->prime_fd_to_handle ? DRM_PRIME_CAP_IMPORT : 0;
req->value |= dev->driver->prime_handle_to_fd ? DRM_PRIME_CAP_EXPORT : 0;
break;
case DRM_CAP_TIMESTAMP_MONOTONIC:
req->value = drm_timestamp_monotonic;
break;
case DRM_CAP_ASYNC_PAGE_FLIP: case DRM_CAP_ASYNC_PAGE_FLIP:
req->value = dev->mode_config.async_page_flip; req->value = dev->mode_config.async_page_flip;
break; break;
case DRM_CAP_PAGE_FLIP_TARGET: case DRM_CAP_PAGE_FLIP_TARGET:
if (drm_core_check_feature(dev, DRIVER_MODESET)) { req->value = 1;
req->value = 1; drm_for_each_crtc(crtc, dev) {
drm_for_each_crtc(crtc, dev) { if (!crtc->funcs->page_flip_target)
if (!crtc->funcs->page_flip_target) req->value = 0;
req->value = 0;
}
} }
break; break;
case DRM_CAP_CURSOR_WIDTH: case DRM_CAP_CURSOR_WIDTH:
......
...@@ -905,6 +905,7 @@ void drm_mm_init(struct drm_mm * mm, u64 start, u64 size) ...@@ -905,6 +905,7 @@ void drm_mm_init(struct drm_mm * mm, u64 start, u64 size)
/* Clever trick to avoid a special case in the free hole tracking. */ /* Clever trick to avoid a special case in the free hole tracking. */
INIT_LIST_HEAD(&mm->head_node.node_list); INIT_LIST_HEAD(&mm->head_node.node_list);
mm->head_node.allocated = 0;
mm->head_node.hole_follows = 1; mm->head_node.hole_follows = 1;
mm->head_node.scanned_block = 0; mm->head_node.scanned_block = 0;
mm->head_node.scanned_prev_free = 0; mm->head_node.scanned_prev_free = 0;
......
...@@ -52,12 +52,12 @@ ...@@ -52,12 +52,12 @@
* drm_modeset_drop_locks(&ctx); * drm_modeset_drop_locks(&ctx);
* drm_modeset_acquire_fini(&ctx); * drm_modeset_acquire_fini(&ctx);
* *
* On top of of these per-object locks using &ww_mutex there's also an overall * On top of of these per-object locks using &ww_mutex there's also an overall
* dev->mode_config.lock, for protecting everything else. Mostly this means * dev->mode_config.lock, for protecting everything else. Mostly this means
* probe state of connectors, and preventing hotplug add/removal of connectors. * probe state of connectors, and preventing hotplug add/removal of connectors.
* *
* Finally there's a bunch of dedicated locks to protect drm core internal * Finally there's a bunch of dedicated locks to protect drm core internal
* lists and lookup data structures. * lists and lookup data structures.
*/ */
static DEFINE_WW_CLASS(crtc_ww_class); static DEFINE_WW_CLASS(crtc_ww_class);
......
...@@ -221,7 +221,8 @@ void drm_plane_cleanup(struct drm_plane *plane) ...@@ -221,7 +221,8 @@ void drm_plane_cleanup(struct drm_plane *plane)
{ {
struct drm_device *dev = plane->dev; struct drm_device *dev = plane->dev;
drm_modeset_lock_all(dev); drm_modeset_lock_fini(&plane->mutex);
kfree(plane->format_types); kfree(plane->format_types);
drm_mode_object_unregister(dev, &plane->base); drm_mode_object_unregister(dev, &plane->base);
...@@ -236,7 +237,6 @@ void drm_plane_cleanup(struct drm_plane *plane) ...@@ -236,7 +237,6 @@ void drm_plane_cleanup(struct drm_plane *plane)
dev->mode_config.num_total_plane--; dev->mode_config.num_total_plane--;
if (plane->type == DRM_PLANE_TYPE_OVERLAY) if (plane->type == DRM_PLANE_TYPE_OVERLAY)
dev->mode_config.num_overlay_plane--; dev->mode_config.num_overlay_plane--;
drm_modeset_unlock_all(dev);
WARN_ON(plane->state && !plane->funcs->atomic_destroy_state); WARN_ON(plane->state && !plane->funcs->atomic_destroy_state);
if (plane->state && plane->funcs->atomic_destroy_state) if (plane->state && plane->funcs->atomic_destroy_state)
......
...@@ -290,7 +290,8 @@ static void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach, ...@@ -290,7 +290,8 @@ static void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
* *
* This wraps dma_buf_export() for use by generic GEM drivers that are using * This wraps dma_buf_export() for use by generic GEM drivers that are using
* drm_gem_dmabuf_release(). In addition to calling dma_buf_export(), we take * drm_gem_dmabuf_release(). In addition to calling dma_buf_export(), we take
* a reference to the drm_device which is released by drm_gem_dmabuf_release(). * a reference to the &drm_device and the exported &drm_gem_object (stored in
* exp_info->priv) which is released by drm_gem_dmabuf_release().
* *
* Returns the new dmabuf. * Returns the new dmabuf.
*/ */
...@@ -300,8 +301,11 @@ struct dma_buf *drm_gem_dmabuf_export(struct drm_device *dev, ...@@ -300,8 +301,11 @@ struct dma_buf *drm_gem_dmabuf_export(struct drm_device *dev,
struct dma_buf *dma_buf; struct dma_buf *dma_buf;
dma_buf = dma_buf_export(exp_info); dma_buf = dma_buf_export(exp_info);
if (!IS_ERR(dma_buf)) if (IS_ERR(dma_buf))
drm_dev_ref(dev); return dma_buf;
drm_dev_ref(dev);
drm_gem_object_reference(exp_info->priv);
return dma_buf; return dma_buf;
} }
...@@ -472,8 +476,6 @@ static struct dma_buf *export_and_register_object(struct drm_device *dev, ...@@ -472,8 +476,6 @@ static struct dma_buf *export_and_register_object(struct drm_device *dev,
*/ */
obj->dma_buf = dmabuf; obj->dma_buf = dmabuf;
get_dma_buf(obj->dma_buf); get_dma_buf(obj->dma_buf);
/* Grab a new ref since the callers is now used by the dma-buf */
drm_gem_object_reference(obj);
return dmabuf; return dmabuf;
} }
......
...@@ -152,6 +152,14 @@ void drm_kms_helper_poll_enable_locked(struct drm_device *dev) ...@@ -152,6 +152,14 @@ void drm_kms_helper_poll_enable_locked(struct drm_device *dev)
} }
EXPORT_SYMBOL(drm_kms_helper_poll_enable_locked); EXPORT_SYMBOL(drm_kms_helper_poll_enable_locked);
static enum drm_connector_status
drm_connector_detect(struct drm_connector *connector, bool force)
{
return connector->funcs->detect ?
connector->funcs->detect(connector, force) :
connector_status_connected;
}
/** /**
* drm_helper_probe_single_connector_modes - get complete set of display modes * drm_helper_probe_single_connector_modes - get complete set of display modes
* @connector: connector to probe * @connector: connector to probe
...@@ -239,7 +247,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, ...@@ -239,7 +247,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
if (connector->funcs->force) if (connector->funcs->force)
connector->funcs->force(connector); connector->funcs->force(connector);
} else { } else {
connector->status = connector->funcs->detect(connector, true); connector->status = drm_connector_detect(connector, true);
} }
/* /*
...@@ -384,7 +392,11 @@ static void output_poll_execute(struct work_struct *work) ...@@ -384,7 +392,11 @@ static void output_poll_execute(struct work_struct *work)
if (!drm_kms_helper_poll) if (!drm_kms_helper_poll)
goto out; goto out;
mutex_lock(&dev->mode_config.mutex); if (!mutex_trylock(&dev->mode_config.mutex)) {
repoll = true;
goto out;
}
drm_for_each_connector(connector, dev) { drm_for_each_connector(connector, dev) {
/* Ignore forced connectors. */ /* Ignore forced connectors. */
...@@ -405,7 +417,7 @@ static void output_poll_execute(struct work_struct *work) ...@@ -405,7 +417,7 @@ static void output_poll_execute(struct work_struct *work)
repoll = true; repoll = true;
connector->status = connector->funcs->detect(connector, false); connector->status = drm_connector_detect(connector, false);
if (old_status != connector->status) { if (old_status != connector->status) {
const char *old, *new; const char *old, *new;
...@@ -565,7 +577,7 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev) ...@@ -565,7 +577,7 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev)
old_status = connector->status; old_status = connector->status;
connector->status = connector->funcs->detect(connector, false); connector->status = drm_connector_detect(connector, false);
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n", DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n",
connector->base.id, connector->base.id,
connector->name, connector->name,
......
...@@ -58,17 +58,10 @@ static void fsl_dcu_drm_connector_destroy(struct drm_connector *connector) ...@@ -58,17 +58,10 @@ static void fsl_dcu_drm_connector_destroy(struct drm_connector *connector)
drm_connector_cleanup(connector); drm_connector_cleanup(connector);
} }
static enum drm_connector_status
fsl_dcu_drm_connector_detect(struct drm_connector *connector, bool force)
{
return connector_status_connected;
}
static const struct drm_connector_funcs fsl_dcu_drm_connector_funcs = { static const struct drm_connector_funcs fsl_dcu_drm_connector_funcs = {
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
.destroy = fsl_dcu_drm_connector_destroy, .destroy = fsl_dcu_drm_connector_destroy,
.detect = fsl_dcu_drm_connector_detect,
.dpms = drm_atomic_helper_connector_dpms, .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.reset = drm_atomic_helper_connector_reset, .reset = drm_atomic_helper_connector_reset,
......
...@@ -386,19 +386,6 @@ static void cdv_intel_lvds_mode_set(struct drm_encoder *encoder, ...@@ -386,19 +386,6 @@ static void cdv_intel_lvds_mode_set(struct drm_encoder *encoder,
REG_WRITE(PFIT_CONTROL, pfit_control); REG_WRITE(PFIT_CONTROL, pfit_control);
} }
/**
* Detect the LVDS connection.
*
* This always returns CONNECTOR_STATUS_CONNECTED.
* This connector should only have
* been set up if the LVDS was actually connected anyway.
*/
static enum drm_connector_status cdv_intel_lvds_detect(
struct drm_connector *connector, bool force)
{
return connector_status_connected;
}
/** /**
* Return the list of DDC modes if available, or the BIOS fixed mode otherwise. * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
*/ */
...@@ -521,7 +508,6 @@ static const struct drm_connector_helper_funcs ...@@ -521,7 +508,6 @@ static const struct drm_connector_helper_funcs
static const struct drm_connector_funcs cdv_intel_lvds_connector_funcs = { static const struct drm_connector_funcs cdv_intel_lvds_connector_funcs = {
.dpms = drm_helper_connector_dpms, .dpms = drm_helper_connector_dpms,
.detect = cdv_intel_lvds_detect,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.set_property = cdv_intel_lvds_set_property, .set_property = cdv_intel_lvds_set_property,
.destroy = cdv_intel_lvds_destroy, .destroy = cdv_intel_lvds_destroy,
......
...@@ -499,19 +499,6 @@ static void psb_intel_lvds_mode_set(struct drm_encoder *encoder, ...@@ -499,19 +499,6 @@ static void psb_intel_lvds_mode_set(struct drm_encoder *encoder,
REG_WRITE(PFIT_CONTROL, pfit_control); REG_WRITE(PFIT_CONTROL, pfit_control);
} }
/*
* Detect the LVDS connection.
*
* This always returns CONNECTOR_STATUS_CONNECTED.
* This connector should only have
* been set up if the LVDS was actually connected anyway.
*/
static enum drm_connector_status psb_intel_lvds_detect(struct drm_connector
*connector, bool force)
{
return connector_status_connected;
}
/* /*
* Return the list of DDC modes if available, or the BIOS fixed mode otherwise. * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
*/ */
...@@ -643,7 +630,6 @@ const struct drm_connector_helper_funcs ...@@ -643,7 +630,6 @@ const struct drm_connector_helper_funcs
const struct drm_connector_funcs psb_intel_lvds_connector_funcs = { const struct drm_connector_funcs psb_intel_lvds_connector_funcs = {
.dpms = drm_helper_connector_dpms, .dpms = drm_helper_connector_dpms,
.detect = psb_intel_lvds_detect,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.set_property = psb_intel_lvds_set_property, .set_property = psb_intel_lvds_set_property,
.destroy = psb_intel_lvds_destroy, .destroy = psb_intel_lvds_destroy,
......
...@@ -39,12 +39,6 @@ hibmc_connector_best_encoder(struct drm_connector *connector) ...@@ -39,12 +39,6 @@ hibmc_connector_best_encoder(struct drm_connector *connector)
return drm_encoder_find(connector->dev, connector->encoder_ids[0]); return drm_encoder_find(connector->dev, connector->encoder_ids[0]);
} }
static enum drm_connector_status hibmc_connector_detect(struct drm_connector
*connector, bool force)
{
return connector_status_connected;
}
static const struct drm_connector_helper_funcs static const struct drm_connector_helper_funcs
hibmc_connector_helper_funcs = { hibmc_connector_helper_funcs = {
.get_modes = hibmc_connector_get_modes, .get_modes = hibmc_connector_get_modes,
...@@ -54,7 +48,6 @@ static const struct drm_connector_helper_funcs ...@@ -54,7 +48,6 @@ static const struct drm_connector_helper_funcs
static const struct drm_connector_funcs hibmc_connector_funcs = { static const struct drm_connector_funcs hibmc_connector_funcs = {
.dpms = drm_atomic_helper_connector_dpms, .dpms = drm_atomic_helper_connector_dpms,
.detect = hibmc_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup, .destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset, .reset = drm_atomic_helper_connector_reset,
......
...@@ -1298,12 +1298,6 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder, ...@@ -1298,12 +1298,6 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder,
} }
} }
static enum drm_connector_status
intel_dsi_detect(struct drm_connector *connector, bool force)
{
return connector_status_connected;
}
static int intel_dsi_get_modes(struct drm_connector *connector) static int intel_dsi_get_modes(struct drm_connector *connector)
{ {
struct intel_connector *intel_connector = to_intel_connector(connector); struct intel_connector *intel_connector = to_intel_connector(connector);
...@@ -1407,7 +1401,6 @@ static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs ...@@ -1407,7 +1401,6 @@ static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs
static const struct drm_connector_funcs intel_dsi_connector_funcs = { static const struct drm_connector_funcs intel_dsi_connector_funcs = {
.dpms = drm_atomic_helper_connector_dpms, .dpms = drm_atomic_helper_connector_dpms,
.detect = intel_dsi_detect,
.late_register = intel_connector_register, .late_register = intel_connector_register,
.early_unregister = intel_connector_unregister, .early_unregister = intel_connector_unregister,
.destroy = intel_dsi_connector_destroy, .destroy = intel_dsi_connector_destroy,
......
...@@ -101,12 +101,6 @@ struct imx_ldb { ...@@ -101,12 +101,6 @@ struct imx_ldb {
const struct bus_mux *lvds_mux; const struct bus_mux *lvds_mux;
}; };
static enum drm_connector_status imx_ldb_connector_detect(
struct drm_connector *connector, bool force)
{
return connector_status_connected;
}
static void imx_ldb_ch_set_bus_format(struct imx_ldb_channel *imx_ldb_ch, static void imx_ldb_ch_set_bus_format(struct imx_ldb_channel *imx_ldb_ch,
u32 bus_format) u32 bus_format)
{ {
...@@ -397,7 +391,6 @@ static int imx_ldb_encoder_atomic_check(struct drm_encoder *encoder, ...@@ -397,7 +391,6 @@ static int imx_ldb_encoder_atomic_check(struct drm_encoder *encoder,
static const struct drm_connector_funcs imx_ldb_connector_funcs = { static const struct drm_connector_funcs imx_ldb_connector_funcs = {
.dpms = drm_atomic_helper_connector_dpms, .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.detect = imx_ldb_connector_detect,
.destroy = imx_drm_connector_destroy, .destroy = imx_drm_connector_destroy,
.reset = drm_atomic_helper_connector_reset, .reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
......
...@@ -227,12 +227,6 @@ static int tve_setup_vga(struct imx_tve *tve) ...@@ -227,12 +227,6 @@ static int tve_setup_vga(struct imx_tve *tve)
TVE_TVDAC_TEST_MODE_MASK, 1); TVE_TVDAC_TEST_MODE_MASK, 1);
} }
static enum drm_connector_status imx_tve_connector_detect(
struct drm_connector *connector, bool force)
{
return connector_status_connected;
}
static int imx_tve_connector_get_modes(struct drm_connector *connector) static int imx_tve_connector_get_modes(struct drm_connector *connector)
{ {
struct imx_tve *tve = con_to_tve(connector); struct imx_tve *tve = con_to_tve(connector);
...@@ -352,7 +346,6 @@ static int imx_tve_atomic_check(struct drm_encoder *encoder, ...@@ -352,7 +346,6 @@ static int imx_tve_atomic_check(struct drm_encoder *encoder,
static const struct drm_connector_funcs imx_tve_connector_funcs = { static const struct drm_connector_funcs imx_tve_connector_funcs = {
.dpms = drm_atomic_helper_connector_dpms, .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.detect = imx_tve_connector_detect,
.destroy = imx_drm_connector_destroy, .destroy = imx_drm_connector_destroy,
.reset = drm_atomic_helper_connector_reset, .reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
......
...@@ -49,12 +49,6 @@ static inline struct imx_parallel_display *enc_to_imxpd(struct drm_encoder *e) ...@@ -49,12 +49,6 @@ static inline struct imx_parallel_display *enc_to_imxpd(struct drm_encoder *e)
return container_of(e, struct imx_parallel_display, encoder); return container_of(e, struct imx_parallel_display, encoder);
} }
static enum drm_connector_status imx_pd_connector_detect(
struct drm_connector *connector, bool force)
{
return connector_status_connected;
}
static int imx_pd_connector_get_modes(struct drm_connector *connector) static int imx_pd_connector_get_modes(struct drm_connector *connector)
{ {
struct imx_parallel_display *imxpd = con_to_imxpd(connector); struct imx_parallel_display *imxpd = con_to_imxpd(connector);
...@@ -143,7 +137,6 @@ static int imx_pd_encoder_atomic_check(struct drm_encoder *encoder, ...@@ -143,7 +137,6 @@ static int imx_pd_encoder_atomic_check(struct drm_encoder *encoder,
static const struct drm_connector_funcs imx_pd_connector_funcs = { static const struct drm_connector_funcs imx_pd_connector_funcs = {
.dpms = drm_atomic_helper_connector_dpms, .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.detect = imx_pd_connector_detect,
.destroy = imx_drm_connector_destroy, .destroy = imx_drm_connector_destroy,
.reset = drm_atomic_helper_connector_reset, .reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
......
...@@ -594,12 +594,6 @@ static void mtk_dsi_encoder_enable(struct drm_encoder *encoder) ...@@ -594,12 +594,6 @@ static void mtk_dsi_encoder_enable(struct drm_encoder *encoder)
mtk_output_dsi_enable(dsi); mtk_output_dsi_enable(dsi);
} }
static enum drm_connector_status mtk_dsi_connector_detect(
struct drm_connector *connector, bool force)
{
return connector_status_connected;
}
static int mtk_dsi_connector_get_modes(struct drm_connector *connector) static int mtk_dsi_connector_get_modes(struct drm_connector *connector)
{ {
struct mtk_dsi *dsi = connector_to_dsi(connector); struct mtk_dsi *dsi = connector_to_dsi(connector);
...@@ -616,7 +610,6 @@ static const struct drm_encoder_helper_funcs mtk_dsi_encoder_helper_funcs = { ...@@ -616,7 +610,6 @@ static const struct drm_encoder_helper_funcs mtk_dsi_encoder_helper_funcs = {
static const struct drm_connector_funcs mtk_dsi_connector_funcs = { static const struct drm_connector_funcs mtk_dsi_connector_funcs = {
.dpms = drm_atomic_helper_connector_dpms, .dpms = drm_atomic_helper_connector_dpms,
.detect = mtk_dsi_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup, .destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset, .reset = drm_atomic_helper_connector_reset,
......
...@@ -1658,12 +1658,6 @@ static struct drm_encoder *mga_connector_best_encoder(struct drm_connector ...@@ -1658,12 +1658,6 @@ static struct drm_encoder *mga_connector_best_encoder(struct drm_connector
return NULL; return NULL;
} }
static enum drm_connector_status mga_vga_detect(struct drm_connector
*connector, bool force)
{
return connector_status_connected;
}
static void mga_connector_destroy(struct drm_connector *connector) static void mga_connector_destroy(struct drm_connector *connector)
{ {
struct mga_connector *mga_connector = to_mga_connector(connector); struct mga_connector *mga_connector = to_mga_connector(connector);
...@@ -1680,7 +1674,6 @@ static const struct drm_connector_helper_funcs mga_vga_connector_helper_funcs = ...@@ -1680,7 +1674,6 @@ static const struct drm_connector_helper_funcs mga_vga_connector_helper_funcs =
static const struct drm_connector_funcs mga_vga_connector_funcs = { static const struct drm_connector_funcs mga_vga_connector_funcs = {
.dpms = drm_helper_connector_dpms, .dpms = drm_helper_connector_dpms,
.detect = mga_vga_detect,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.destroy = mga_connector_destroy, .destroy = mga_connector_destroy,
}; };
......
...@@ -122,9 +122,6 @@ int qxl_debugfs_add_files(struct qxl_device *qdev, ...@@ -122,9 +122,6 @@ int qxl_debugfs_add_files(struct qxl_device *qdev,
qdev->debugfs[qdev->debugfs_count].num_files = nfiles; qdev->debugfs[qdev->debugfs_count].num_files = nfiles;
qdev->debugfs_count = i; qdev->debugfs_count = i;
#if defined(CONFIG_DEBUG_FS) #if defined(CONFIG_DEBUG_FS)
drm_debugfs_create_files(files, nfiles,
qdev->ddev->control->debugfs_root,
qdev->ddev->control);
drm_debugfs_create_files(files, nfiles, drm_debugfs_create_files(files, nfiles,
qdev->ddev->primary->debugfs_root, qdev->ddev->primary->debugfs_root,
qdev->ddev->primary); qdev->ddev->primary);
...@@ -138,9 +135,6 @@ void qxl_debugfs_remove_files(struct qxl_device *qdev) ...@@ -138,9 +135,6 @@ void qxl_debugfs_remove_files(struct qxl_device *qdev)
unsigned i; unsigned i;
for (i = 0; i < qdev->debugfs_count; i++) { for (i = 0; i < qdev->debugfs_count; i++) {
drm_debugfs_remove_files(qdev->debugfs[i].files,
qdev->debugfs[i].num_files,
qdev->ddev->control);
drm_debugfs_remove_files(qdev->debugfs[i].files, drm_debugfs_remove_files(qdev->debugfs[i].files,
qdev->debugfs[i].num_files, qdev->debugfs[i].num_files,
qdev->ddev->primary); qdev->ddev->primary);
......
...@@ -134,7 +134,7 @@ qxl_release_alloc(struct qxl_device *qdev, int type, ...@@ -134,7 +134,7 @@ qxl_release_alloc(struct qxl_device *qdev, int type,
release = kmalloc(size, GFP_KERNEL); release = kmalloc(size, GFP_KERNEL);
if (!release) { if (!release) {
DRM_ERROR("Out of memory\n"); DRM_ERROR("Out of memory\n");
return 0; return -ENOMEM;
} }
release->base.ops = NULL; release->base.ops = NULL;
release->type = type; release->type = type;
......
...@@ -1948,9 +1948,6 @@ int radeon_debugfs_add_files(struct radeon_device *rdev, ...@@ -1948,9 +1948,6 @@ int radeon_debugfs_add_files(struct radeon_device *rdev,
rdev->debugfs[rdev->debugfs_count].num_files = nfiles; rdev->debugfs[rdev->debugfs_count].num_files = nfiles;
rdev->debugfs_count = i; rdev->debugfs_count = i;
#if defined(CONFIG_DEBUG_FS) #if defined(CONFIG_DEBUG_FS)
drm_debugfs_create_files(files, nfiles,
rdev->ddev->control->debugfs_root,
rdev->ddev->control);
drm_debugfs_create_files(files, nfiles, drm_debugfs_create_files(files, nfiles,
rdev->ddev->primary->debugfs_root, rdev->ddev->primary->debugfs_root,
rdev->ddev->primary); rdev->ddev->primary);
...@@ -1964,9 +1961,6 @@ static void radeon_debugfs_remove_files(struct radeon_device *rdev) ...@@ -1964,9 +1961,6 @@ static void radeon_debugfs_remove_files(struct radeon_device *rdev)
unsigned i; unsigned i;
for (i = 0; i < rdev->debugfs_count; i++) { for (i = 0; i < rdev->debugfs_count; i++) {
drm_debugfs_remove_files(rdev->debugfs[i].files,
rdev->debugfs[i].num_files,
rdev->ddev->control);
drm_debugfs_remove_files(rdev->debugfs[i].files, drm_debugfs_remove_files(rdev->debugfs[i].files,
rdev->debugfs[i].num_files, rdev->debugfs[i].num_files,
rdev->ddev->primary); rdev->ddev->primary);
......
...@@ -61,16 +61,9 @@ static const struct drm_connector_helper_funcs connector_helper_funcs = { ...@@ -61,16 +61,9 @@ static const struct drm_connector_helper_funcs connector_helper_funcs = {
.get_modes = rcar_du_lvds_connector_get_modes, .get_modes = rcar_du_lvds_connector_get_modes,
}; };
static enum drm_connector_status
rcar_du_lvds_connector_detect(struct drm_connector *connector, bool force)
{
return connector_status_connected;
}
static const struct drm_connector_funcs connector_funcs = { static const struct drm_connector_funcs connector_funcs = {
.dpms = drm_atomic_helper_connector_dpms, .dpms = drm_atomic_helper_connector_dpms,
.reset = drm_atomic_helper_connector_reset, .reset = drm_atomic_helper_connector_reset,
.detect = rcar_du_lvds_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup, .destroy = drm_connector_cleanup,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
......
...@@ -969,12 +969,6 @@ static struct drm_connector_helper_funcs dw_mipi_dsi_connector_helper_funcs = { ...@@ -969,12 +969,6 @@ static struct drm_connector_helper_funcs dw_mipi_dsi_connector_helper_funcs = {
.mode_valid = dw_mipi_dsi_mode_valid, .mode_valid = dw_mipi_dsi_mode_valid,
}; };
static enum drm_connector_status
dw_mipi_dsi_detect(struct drm_connector *connector, bool force)
{
return connector_status_connected;
}
static void dw_mipi_dsi_drm_connector_destroy(struct drm_connector *connector) static void dw_mipi_dsi_drm_connector_destroy(struct drm_connector *connector)
{ {
drm_connector_unregister(connector); drm_connector_unregister(connector);
...@@ -984,7 +978,6 @@ static void dw_mipi_dsi_drm_connector_destroy(struct drm_connector *connector) ...@@ -984,7 +978,6 @@ static void dw_mipi_dsi_drm_connector_destroy(struct drm_connector *connector)
static struct drm_connector_funcs dw_mipi_dsi_atomic_connector_funcs = { static struct drm_connector_funcs dw_mipi_dsi_atomic_connector_funcs = {
.dpms = drm_atomic_helper_connector_dpms, .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.detect = dw_mipi_dsi_detect,
.destroy = dw_mipi_dsi_drm_connector_destroy, .destroy = dw_mipi_dsi_drm_connector_destroy,
.reset = drm_atomic_helper_connector_reset, .reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
......
...@@ -669,15 +669,8 @@ static void shmob_drm_connector_destroy(struct drm_connector *connector) ...@@ -669,15 +669,8 @@ static void shmob_drm_connector_destroy(struct drm_connector *connector)
drm_connector_cleanup(connector); drm_connector_cleanup(connector);
} }
static enum drm_connector_status
shmob_drm_connector_detect(struct drm_connector *connector, bool force)
{
return connector_status_connected;
}
static const struct drm_connector_funcs connector_funcs = { static const struct drm_connector_funcs connector_funcs = {
.dpms = drm_helper_connector_dpms, .dpms = drm_helper_connector_dpms,
.detect = shmob_drm_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.destroy = shmob_drm_connector_destroy, .destroy = shmob_drm_connector_destroy,
}; };
......
...@@ -642,12 +642,6 @@ struct drm_connector_helper_funcs sti_hda_connector_helper_funcs = { ...@@ -642,12 +642,6 @@ struct drm_connector_helper_funcs sti_hda_connector_helper_funcs = {
.mode_valid = sti_hda_connector_mode_valid, .mode_valid = sti_hda_connector_mode_valid,
}; };
static enum drm_connector_status
sti_hda_connector_detect(struct drm_connector *connector, bool force)
{
return connector_status_connected;
}
static int sti_hda_late_register(struct drm_connector *connector) static int sti_hda_late_register(struct drm_connector *connector)
{ {
struct sti_hda_connector *hda_connector struct sti_hda_connector *hda_connector
...@@ -665,7 +659,6 @@ static int sti_hda_late_register(struct drm_connector *connector) ...@@ -665,7 +659,6 @@ static int sti_hda_late_register(struct drm_connector *connector)
static const struct drm_connector_funcs sti_hda_connector_funcs = { static const struct drm_connector_funcs sti_hda_connector_funcs = {
.dpms = drm_atomic_helper_connector_dpms, .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.detect = sti_hda_connector_detect,
.destroy = drm_connector_cleanup, .destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset, .reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
......
...@@ -110,12 +110,6 @@ static struct drm_connector_helper_funcs sun4i_rgb_con_helper_funcs = { ...@@ -110,12 +110,6 @@ static struct drm_connector_helper_funcs sun4i_rgb_con_helper_funcs = {
.mode_valid = sun4i_rgb_mode_valid, .mode_valid = sun4i_rgb_mode_valid,
}; };
static enum drm_connector_status
sun4i_rgb_connector_detect(struct drm_connector *connector, bool force)
{
return connector_status_connected;
}
static void static void
sun4i_rgb_connector_destroy(struct drm_connector *connector) sun4i_rgb_connector_destroy(struct drm_connector *connector)
{ {
...@@ -129,7 +123,6 @@ sun4i_rgb_connector_destroy(struct drm_connector *connector) ...@@ -129,7 +123,6 @@ sun4i_rgb_connector_destroy(struct drm_connector *connector)
static struct drm_connector_funcs sun4i_rgb_con_funcs = { static struct drm_connector_funcs sun4i_rgb_con_funcs = {
.dpms = drm_atomic_helper_connector_dpms, .dpms = drm_atomic_helper_connector_dpms,
.detect = sun4i_rgb_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.destroy = sun4i_rgb_connector_destroy, .destroy = sun4i_rgb_connector_destroy,
.reset = drm_atomic_helper_connector_reset, .reset = drm_atomic_helper_connector_reset,
......
...@@ -537,12 +537,6 @@ static struct drm_connector_helper_funcs sun4i_tv_comp_connector_helper_funcs = ...@@ -537,12 +537,6 @@ static struct drm_connector_helper_funcs sun4i_tv_comp_connector_helper_funcs =
.mode_valid = sun4i_tv_comp_mode_valid, .mode_valid = sun4i_tv_comp_mode_valid,
}; };
static enum drm_connector_status
sun4i_tv_comp_connector_detect(struct drm_connector *connector, bool force)
{
return connector_status_connected;
}
static void static void
sun4i_tv_comp_connector_destroy(struct drm_connector *connector) sun4i_tv_comp_connector_destroy(struct drm_connector *connector)
{ {
...@@ -551,7 +545,6 @@ sun4i_tv_comp_connector_destroy(struct drm_connector *connector) ...@@ -551,7 +545,6 @@ sun4i_tv_comp_connector_destroy(struct drm_connector *connector)
static struct drm_connector_funcs sun4i_tv_comp_connector_funcs = { static struct drm_connector_funcs sun4i_tv_comp_connector_funcs = {
.dpms = drm_atomic_helper_connector_dpms, .dpms = drm_atomic_helper_connector_dpms,
.detect = sun4i_tv_comp_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.destroy = sun4i_tv_comp_connector_destroy, .destroy = sun4i_tv_comp_connector_destroy,
.reset = drm_atomic_helper_connector_reset, .reset = drm_atomic_helper_connector_reset,
......
...@@ -144,13 +144,6 @@ static void panel_connector_destroy(struct drm_connector *connector) ...@@ -144,13 +144,6 @@ static void panel_connector_destroy(struct drm_connector *connector)
drm_connector_cleanup(connector); drm_connector_cleanup(connector);
} }
static enum drm_connector_status panel_connector_detect(
struct drm_connector *connector,
bool force)
{
return connector_status_connected;
}
static int panel_connector_get_modes(struct drm_connector *connector) static int panel_connector_get_modes(struct drm_connector *connector)
{ {
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
...@@ -197,7 +190,6 @@ static struct drm_encoder *panel_connector_best_encoder( ...@@ -197,7 +190,6 @@ static struct drm_encoder *panel_connector_best_encoder(
static const struct drm_connector_funcs panel_connector_funcs = { static const struct drm_connector_funcs panel_connector_funcs = {
.destroy = panel_connector_destroy, .destroy = panel_connector_destroy,
.dpms = drm_atomic_helper_connector_dpms, .dpms = drm_atomic_helper_connector_dpms,
.detect = panel_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.reset = drm_atomic_helper_connector_reset, .reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
......
...@@ -126,7 +126,6 @@ static int attach_dmabuf(struct drm_device *dev, ...@@ -126,7 +126,6 @@ static int attach_dmabuf(struct drm_device *dev,
return PTR_ERR(dmabuf); return PTR_ERR(dmabuf);
obj->dma_buf = dmabuf; obj->dma_buf = dmabuf;
drm_gem_object_reference(obj);
return 0; return 0;
} }
...@@ -191,12 +190,12 @@ int vgem_fence_attach_ioctl(struct drm_device *dev, ...@@ -191,12 +190,12 @@ int vgem_fence_attach_ioctl(struct drm_device *dev,
/* Expose the fence via the dma-buf */ /* Expose the fence via the dma-buf */
ret = 0; ret = 0;
mutex_lock(&resv->lock.base); ww_mutex_lock(&resv->lock, NULL);
if (arg->flags & VGEM_FENCE_WRITE) if (arg->flags & VGEM_FENCE_WRITE)
reservation_object_add_excl_fence(resv, fence); reservation_object_add_excl_fence(resv, fence);
else if ((ret = reservation_object_reserve_shared(resv)) == 0) else if ((ret = reservation_object_reserve_shared(resv)) == 0)
reservation_object_add_shared_fence(resv, fence); reservation_object_add_shared_fence(resv, fence);
mutex_unlock(&resv->lock.base); ww_mutex_unlock(&resv->lock);
/* Record the fence in our idr for later signaling */ /* Record the fence in our idr for later signaling */
if (ret == 0) { if (ret == 0) {
......
...@@ -465,33 +465,34 @@ static int vmw_fb_kms_detach(struct vmw_fb_par *par, ...@@ -465,33 +465,34 @@ static int vmw_fb_kms_detach(struct vmw_fb_par *par,
static int vmw_fb_kms_framebuffer(struct fb_info *info) static int vmw_fb_kms_framebuffer(struct fb_info *info)
{ {
struct drm_mode_fb_cmd mode_cmd; struct drm_mode_fb_cmd2 mode_cmd;
struct vmw_fb_par *par = info->par; struct vmw_fb_par *par = info->par;
struct fb_var_screeninfo *var = &info->var; struct fb_var_screeninfo *var = &info->var;
struct drm_framebuffer *cur_fb; struct drm_framebuffer *cur_fb;
struct vmw_framebuffer *vfb; struct vmw_framebuffer *vfb;
int ret = 0; int ret = 0, depth;
size_t new_bo_size; size_t new_bo_size;
ret = vmw_fb_compute_depth(var, &mode_cmd.depth); ret = vmw_fb_compute_depth(var, &depth);
if (ret) if (ret)
return ret; return ret;
mode_cmd.width = var->xres; mode_cmd.width = var->xres;
mode_cmd.height = var->yres; mode_cmd.height = var->yres;
mode_cmd.bpp = var->bits_per_pixel; mode_cmd.pitches[0] = ((var->bits_per_pixel + 7) / 8) * mode_cmd.width;
mode_cmd.pitch = ((mode_cmd.bpp + 7) / 8) * mode_cmd.width; mode_cmd.pixel_format =
drm_mode_legacy_fb_format(var->bits_per_pixel,
((var->bits_per_pixel + 7) / 8) * mode_cmd.width);
cur_fb = par->set_fb; cur_fb = par->set_fb;
if (cur_fb && cur_fb->width == mode_cmd.width && if (cur_fb && cur_fb->width == mode_cmd.width &&
cur_fb->height == mode_cmd.height && cur_fb->height == mode_cmd.height &&
cur_fb->bits_per_pixel == mode_cmd.bpp && cur_fb->pixel_format == mode_cmd.pixel_format &&
cur_fb->depth == mode_cmd.depth && cur_fb->pitches[0] == mode_cmd.pitches[0])
cur_fb->pitches[0] == mode_cmd.pitch)
return 0; return 0;
/* Need new buffer object ? */ /* Need new buffer object ? */
new_bo_size = (size_t) mode_cmd.pitch * (size_t) mode_cmd.height; new_bo_size = (size_t) mode_cmd.pitches[0] * (size_t) mode_cmd.height;
ret = vmw_fb_kms_detach(par, ret = vmw_fb_kms_detach(par,
par->bo_size < new_bo_size || par->bo_size < new_bo_size ||
par->bo_size > 2*new_bo_size, par->bo_size > 2*new_bo_size,
......
...@@ -516,7 +516,7 @@ static const struct drm_framebuffer_funcs vmw_framebuffer_surface_funcs = { ...@@ -516,7 +516,7 @@ static const struct drm_framebuffer_funcs vmw_framebuffer_surface_funcs = {
static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
struct vmw_surface *surface, struct vmw_surface *surface,
struct vmw_framebuffer **out, struct vmw_framebuffer **out,
const struct drm_mode_fb_cmd const struct drm_mode_fb_cmd2
*mode_cmd, *mode_cmd,
bool is_dmabuf_proxy) bool is_dmabuf_proxy)
...@@ -525,6 +525,7 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, ...@@ -525,6 +525,7 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
struct vmw_framebuffer_surface *vfbs; struct vmw_framebuffer_surface *vfbs;
enum SVGA3dSurfaceFormat format; enum SVGA3dSurfaceFormat format;
int ret; int ret;
struct drm_format_name_buf format_name;
/* 3D is only supported on HWv8 and newer hosts */ /* 3D is only supported on HWv8 and newer hosts */
if (dev_priv->active_display_unit == vmw_du_legacy) if (dev_priv->active_display_unit == vmw_du_legacy)
...@@ -548,21 +549,22 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, ...@@ -548,21 +549,22 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
return -EINVAL; return -EINVAL;
} }
switch (mode_cmd->depth) { switch (mode_cmd->pixel_format) {
case 32: case DRM_FORMAT_ARGB8888:
format = SVGA3D_A8R8G8B8; format = SVGA3D_A8R8G8B8;
break; break;
case 24: case DRM_FORMAT_XRGB8888:
format = SVGA3D_X8R8G8B8; format = SVGA3D_X8R8G8B8;
break; break;
case 16: case DRM_FORMAT_RGB565:
format = SVGA3D_R5G6B5; format = SVGA3D_R5G6B5;
break; break;
case 15: case DRM_FORMAT_XRGB1555:
format = SVGA3D_A1R5G5B5; format = SVGA3D_A1R5G5B5;
break; break;
default: default:
DRM_ERROR("Invalid color depth: %d\n", mode_cmd->depth); DRM_ERROR("Invalid pixel format: %s\n",
drm_get_format_name(mode_cmd->pixel_format, &format_name));
return -EINVAL; return -EINVAL;
} }
...@@ -581,14 +583,9 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, ...@@ -581,14 +583,9 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
goto out_err1; goto out_err1;
} }
/* XXX get the first 3 from the surface info */ drm_helper_mode_fill_fb_struct(&vfbs->base.base, mode_cmd);
vfbs->base.base.bits_per_pixel = mode_cmd->bpp;
vfbs->base.base.pitches[0] = mode_cmd->pitch;
vfbs->base.base.depth = mode_cmd->depth;
vfbs->base.base.width = mode_cmd->width;
vfbs->base.base.height = mode_cmd->height;
vfbs->surface = vmw_surface_reference(surface); vfbs->surface = vmw_surface_reference(surface);
vfbs->base.user_handle = mode_cmd->handle; vfbs->base.user_handle = mode_cmd->handles[0];
vfbs->is_dmabuf_proxy = is_dmabuf_proxy; vfbs->is_dmabuf_proxy = is_dmabuf_proxy;
*out = &vfbs->base; *out = &vfbs->base;
...@@ -755,7 +752,7 @@ static int vmw_framebuffer_unpin(struct vmw_framebuffer *vfb) ...@@ -755,7 +752,7 @@ static int vmw_framebuffer_unpin(struct vmw_framebuffer *vfb)
* 0 on success, error code otherwise * 0 on success, error code otherwise
*/ */
static int vmw_create_dmabuf_proxy(struct drm_device *dev, static int vmw_create_dmabuf_proxy(struct drm_device *dev,
const struct drm_mode_fb_cmd *mode_cmd, const struct drm_mode_fb_cmd2 *mode_cmd,
struct vmw_dma_buffer *dmabuf_mob, struct vmw_dma_buffer *dmabuf_mob,
struct vmw_surface **srf_out) struct vmw_surface **srf_out)
{ {
...@@ -763,17 +760,18 @@ static int vmw_create_dmabuf_proxy(struct drm_device *dev, ...@@ -763,17 +760,18 @@ static int vmw_create_dmabuf_proxy(struct drm_device *dev,
struct drm_vmw_size content_base_size; struct drm_vmw_size content_base_size;
struct vmw_resource *res; struct vmw_resource *res;
unsigned int bytes_pp; unsigned int bytes_pp;
struct drm_format_name_buf format_name;
int ret; int ret;
switch (mode_cmd->depth) { switch (mode_cmd->pixel_format) {
case 32: case DRM_FORMAT_ARGB8888:
case 24: case DRM_FORMAT_XRGB8888:
format = SVGA3D_X8R8G8B8; format = SVGA3D_X8R8G8B8;
bytes_pp = 4; bytes_pp = 4;
break; break;
case 16: case DRM_FORMAT_RGB565:
case 15: case DRM_FORMAT_XRGB1555:
format = SVGA3D_R5G6B5; format = SVGA3D_R5G6B5;
bytes_pp = 2; bytes_pp = 2;
break; break;
...@@ -784,11 +782,12 @@ static int vmw_create_dmabuf_proxy(struct drm_device *dev, ...@@ -784,11 +782,12 @@ static int vmw_create_dmabuf_proxy(struct drm_device *dev,
break; break;
default: default:
DRM_ERROR("Invalid framebuffer format %d\n", mode_cmd->depth); DRM_ERROR("Invalid framebuffer format %s\n",
drm_get_format_name(mode_cmd->pixel_format, &format_name));
return -EINVAL; return -EINVAL;
} }
content_base_size.width = mode_cmd->pitch / bytes_pp; content_base_size.width = mode_cmd->pitches[0] / bytes_pp;
content_base_size.height = mode_cmd->height; content_base_size.height = mode_cmd->height;
content_base_size.depth = 1; content_base_size.depth = 1;
...@@ -826,16 +825,17 @@ static int vmw_create_dmabuf_proxy(struct drm_device *dev, ...@@ -826,16 +825,17 @@ static int vmw_create_dmabuf_proxy(struct drm_device *dev,
static int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv, static int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv,
struct vmw_dma_buffer *dmabuf, struct vmw_dma_buffer *dmabuf,
struct vmw_framebuffer **out, struct vmw_framebuffer **out,
const struct drm_mode_fb_cmd const struct drm_mode_fb_cmd2
*mode_cmd) *mode_cmd)
{ {
struct drm_device *dev = dev_priv->dev; struct drm_device *dev = dev_priv->dev;
struct vmw_framebuffer_dmabuf *vfbd; struct vmw_framebuffer_dmabuf *vfbd;
unsigned int requested_size; unsigned int requested_size;
struct drm_format_name_buf format_name;
int ret; int ret;
requested_size = mode_cmd->height * mode_cmd->pitch; requested_size = mode_cmd->height * mode_cmd->pitches[0];
if (unlikely(requested_size > dmabuf->base.num_pages * PAGE_SIZE)) { if (unlikely(requested_size > dmabuf->base.num_pages * PAGE_SIZE)) {
DRM_ERROR("Screen buffer object size is too small " DRM_ERROR("Screen buffer object size is too small "
"for requested mode.\n"); "for requested mode.\n");
...@@ -844,27 +844,16 @@ static int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv, ...@@ -844,27 +844,16 @@ static int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv,
/* Limited framebuffer color depth support for screen objects */ /* Limited framebuffer color depth support for screen objects */
if (dev_priv->active_display_unit == vmw_du_screen_object) { if (dev_priv->active_display_unit == vmw_du_screen_object) {
switch (mode_cmd->depth) { switch (mode_cmd->pixel_format) {
case 32: case DRM_FORMAT_XRGB8888:
case 24: case DRM_FORMAT_ARGB8888:
/* Only support 32 bpp for 32 and 24 depth fbs */ break;
if (mode_cmd->bpp == 32) case DRM_FORMAT_XRGB1555:
break; case DRM_FORMAT_RGB565:
break;
DRM_ERROR("Invalid color depth/bbp: %d %d\n",
mode_cmd->depth, mode_cmd->bpp);
return -EINVAL;
case 16:
case 15:
/* Only support 16 bpp for 16 and 15 depth fbs */
if (mode_cmd->bpp == 16)
break;
DRM_ERROR("Invalid color depth/bbp: %d %d\n",
mode_cmd->depth, mode_cmd->bpp);
return -EINVAL;
default: default:
DRM_ERROR("Invalid color depth: %d\n", mode_cmd->depth); DRM_ERROR("Invalid pixel format: %s\n",
drm_get_format_name(mode_cmd->pixel_format, &format_name));
return -EINVAL; return -EINVAL;
} }
} }
...@@ -875,14 +864,10 @@ static int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv, ...@@ -875,14 +864,10 @@ static int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv,
goto out_err1; goto out_err1;
} }
vfbd->base.base.bits_per_pixel = mode_cmd->bpp; drm_helper_mode_fill_fb_struct(&vfbd->base.base, mode_cmd);
vfbd->base.base.pitches[0] = mode_cmd->pitch;
vfbd->base.base.depth = mode_cmd->depth;
vfbd->base.base.width = mode_cmd->width;
vfbd->base.base.height = mode_cmd->height;
vfbd->base.dmabuf = true; vfbd->base.dmabuf = true;
vfbd->buffer = vmw_dmabuf_reference(dmabuf); vfbd->buffer = vmw_dmabuf_reference(dmabuf);
vfbd->base.user_handle = mode_cmd->handle; vfbd->base.user_handle = mode_cmd->handles[0];
*out = &vfbd->base; *out = &vfbd->base;
ret = drm_framebuffer_init(dev, &vfbd->base.base, ret = drm_framebuffer_init(dev, &vfbd->base.base,
...@@ -916,7 +901,7 @@ vmw_kms_new_framebuffer(struct vmw_private *dev_priv, ...@@ -916,7 +901,7 @@ vmw_kms_new_framebuffer(struct vmw_private *dev_priv,
struct vmw_dma_buffer *dmabuf, struct vmw_dma_buffer *dmabuf,
struct vmw_surface *surface, struct vmw_surface *surface,
bool only_2d, bool only_2d,
const struct drm_mode_fb_cmd *mode_cmd) const struct drm_mode_fb_cmd2 *mode_cmd)
{ {
struct vmw_framebuffer *vfb = NULL; struct vmw_framebuffer *vfb = NULL;
bool is_dmabuf_proxy = false; bool is_dmabuf_proxy = false;
...@@ -971,7 +956,7 @@ vmw_kms_new_framebuffer(struct vmw_private *dev_priv, ...@@ -971,7 +956,7 @@ vmw_kms_new_framebuffer(struct vmw_private *dev_priv,
static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
struct drm_file *file_priv, struct drm_file *file_priv,
const struct drm_mode_fb_cmd2 *mode_cmd2) const struct drm_mode_fb_cmd2 *mode_cmd)
{ {
struct vmw_private *dev_priv = vmw_priv(dev); struct vmw_private *dev_priv = vmw_priv(dev);
struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
...@@ -979,25 +964,8 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, ...@@ -979,25 +964,8 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
struct vmw_surface *surface = NULL; struct vmw_surface *surface = NULL;
struct vmw_dma_buffer *bo = NULL; struct vmw_dma_buffer *bo = NULL;
struct ttm_base_object *user_obj; struct ttm_base_object *user_obj;
struct drm_mode_fb_cmd mode_cmd;
const struct drm_format_info *info;
int ret; int ret;
info = drm_format_info(mode_cmd2->pixel_format);
if (!info || !info->depth) {
struct drm_format_name_buf format_name;
DRM_ERROR("Unsupported framebuffer format %s\n",
drm_get_format_name(mode_cmd2->pixel_format, &format_name));
return ERR_PTR(-EINVAL);
}
mode_cmd.width = mode_cmd2->width;
mode_cmd.height = mode_cmd2->height;
mode_cmd.pitch = mode_cmd2->pitches[0];
mode_cmd.handle = mode_cmd2->handles[0];
mode_cmd.depth = info->depth;
mode_cmd.bpp = info->cpp[0] * 8;
/** /**
* This code should be conditioned on Screen Objects not being used. * This code should be conditioned on Screen Objects not being used.
* If screen objects are used, we can allocate a GMR to hold the * If screen objects are used, we can allocate a GMR to hold the
...@@ -1005,8 +973,8 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, ...@@ -1005,8 +973,8 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
*/ */
if (!vmw_kms_validate_mode_vram(dev_priv, if (!vmw_kms_validate_mode_vram(dev_priv,
mode_cmd.pitch, mode_cmd->pitches[0],
mode_cmd.height)) { mode_cmd->height)) {
DRM_ERROR("Requested mode exceed bounding box limit.\n"); DRM_ERROR("Requested mode exceed bounding box limit.\n");
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
...@@ -1020,7 +988,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, ...@@ -1020,7 +988,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
* command stream using user-space handles. * command stream using user-space handles.
*/ */
user_obj = ttm_base_object_lookup(tfile, mode_cmd.handle); user_obj = ttm_base_object_lookup(tfile, mode_cmd->handles[0]);
if (unlikely(user_obj == NULL)) { if (unlikely(user_obj == NULL)) {
DRM_ERROR("Could not locate requested kms frame buffer.\n"); DRM_ERROR("Could not locate requested kms frame buffer.\n");
return ERR_PTR(-ENOENT); return ERR_PTR(-ENOENT);
...@@ -1032,14 +1000,14 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, ...@@ -1032,14 +1000,14 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
/* returns either a dmabuf or surface */ /* returns either a dmabuf or surface */
ret = vmw_user_lookup_handle(dev_priv, tfile, ret = vmw_user_lookup_handle(dev_priv, tfile,
mode_cmd.handle, mode_cmd->handles[0],
&surface, &bo); &surface, &bo);
if (ret) if (ret)
goto err_out; goto err_out;
vfb = vmw_kms_new_framebuffer(dev_priv, bo, surface, vfb = vmw_kms_new_framebuffer(dev_priv, bo, surface,
!(dev_priv->capabilities & SVGA_CAP_3D), !(dev_priv->capabilities & SVGA_CAP_3D),
&mode_cmd); mode_cmd);
if (IS_ERR(vfb)) { if (IS_ERR(vfb)) {
ret = PTR_ERR(vfb); ret = PTR_ERR(vfb);
goto err_out; goto err_out;
......
...@@ -248,7 +248,7 @@ vmw_kms_new_framebuffer(struct vmw_private *dev_priv, ...@@ -248,7 +248,7 @@ vmw_kms_new_framebuffer(struct vmw_private *dev_priv,
struct vmw_dma_buffer *dmabuf, struct vmw_dma_buffer *dmabuf,
struct vmw_surface *surface, struct vmw_surface *surface,
bool only_2d, bool only_2d,
const struct drm_mode_fb_cmd *mode_cmd); const struct drm_mode_fb_cmd2 *mode_cmd);
int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv, int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv,
unsigned unit, unsigned unit,
u32 max_width, u32 max_width,
......
...@@ -262,6 +262,9 @@ struct drm_connector_funcs { ...@@ -262,6 +262,9 @@ struct drm_connector_funcs {
* connector due to a user request. force can be used by the driver to * connector due to a user request. force can be used by the driver to
* avoid expensive, destructive operations during automated probing. * avoid expensive, destructive operations during automated probing.
* *
* This callback is optional, if not implemented the connector will be
* considered as always being attached.
*
* FIXME: * FIXME:
* *
* Note that this hook is only called by the probe helper. It's not in * Note that this hook is only called by the probe helper. It's not in
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment