Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6083 → Rev 6084

/drivers/video/drm/drm_probe_helper.c
58,40 → 58,84
static bool drm_kms_helper_poll = true;
module_param_named(poll, drm_kms_helper_poll, bool, 0600);
 
static void drm_mode_validate_flag(struct drm_connector *connector,
static enum drm_mode_status
drm_mode_validate_flag(const struct drm_display_mode *mode,
int flags)
{
struct drm_display_mode *mode;
 
if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE |
DRM_MODE_FLAG_3D_MASK))
return;
 
list_for_each_entry(mode, &connector->modes, head) {
if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
!(flags & DRM_MODE_FLAG_INTERLACE))
mode->status = MODE_NO_INTERLACE;
return MODE_NO_INTERLACE;
 
if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
!(flags & DRM_MODE_FLAG_DBLSCAN))
mode->status = MODE_NO_DBLESCAN;
return MODE_NO_DBLESCAN;
 
if ((mode->flags & DRM_MODE_FLAG_3D_MASK) &&
!(flags & DRM_MODE_FLAG_3D_MASK))
mode->status = MODE_NO_STEREO;
return MODE_NO_STEREO;
 
return MODE_OK;
}
 
static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)
{
struct drm_display_mode *mode;
 
if (!connector->cmdline_mode.specified)
return 0;
 
mode = drm_mode_create_from_cmdline_mode(connector->dev,
&connector->cmdline_mode);
if (mode == NULL)
return 0;
 
drm_mode_probed_add(connector, mode);
return 1;
}
 
#define DRM_OUTPUT_POLL_PERIOD (10*HZ)
/**
* drm_kms_helper_poll_enable_locked - re-enable output polling.
* @dev: drm_device
*
* This function re-enables the output polling work without
* locking the mode_config mutex.
*
* This is like drm_kms_helper_poll_enable() however it is to be
* called from a context where the mode_config mutex is locked
* already.
*/
void drm_kms_helper_poll_enable_locked(struct drm_device *dev)
{
bool poll = false;
struct drm_connector *connector;
 
WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
 
if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
return;
 
drm_for_each_connector(connector, dev) {
if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
DRM_CONNECTOR_POLL_DISCONNECT))
poll = true;
}
 
}
EXPORT_SYMBOL(drm_kms_helper_poll_enable_locked);
 
 
static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connector *connector,
uint32_t maxX, uint32_t maxY, bool merge_type_bits)
{
struct drm_device *dev = connector->dev;
struct drm_display_mode *mode;
struct drm_connector_helper_funcs *connector_funcs =
const struct drm_connector_helper_funcs *connector_funcs =
connector->helper_private;
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));
 
110,12 → 154,14
if (connector->funcs->force)
connector->funcs->force(connector);
} else {
old_status = connector->status;
 
connector->status = connector->funcs->detect(connector, true);
}
 
/* Re-enable polling in case the global poll config changed. */
if (drm_kms_helper_poll != dev->mode_config.poll_running)
drm_kms_helper_poll_enable(dev);
drm_kms_helper_poll_enable_locked(dev);
 
dev->mode_config.poll_running = drm_kms_helper_poll;
 
136,6 → 182,7
struct edid *edid = (struct edid *) connector->edid_blob_ptr->data;
 
count = drm_add_edid_modes(connector, edid);
drm_edid_to_eld(connector, edid);
} else
count = (*connector_funcs->get_modes)(connector);
}
147,9 → 194,6
 
drm_mode_connector_list_update(connector, merge_type_bits);
 
if (maxX && maxY)
drm_mode_validate_size(dev, &connector->modes, maxX, maxY);
 
if (connector->interlace_allowed)
mode_flags |= DRM_MODE_FLAG_INTERLACE;
if (connector->doublescan_allowed)
156,9 → 200,17
mode_flags |= DRM_MODE_FLAG_DBLSCAN;
if (connector->stereo_allowed)
mode_flags |= DRM_MODE_FLAG_3D_MASK;
drm_mode_validate_flag(connector, mode_flags);
 
list_for_each_entry(mode, &connector->modes, head) {
if (mode->status == MODE_OK)
mode->status = drm_mode_validate_basic(mode);
 
if (mode->status == MODE_OK)
mode->status = drm_mode_validate_size(mode, maxX, maxY);
 
if (mode->status == MODE_OK)
mode->status = drm_mode_validate_flag(mode, mode_flags);
 
if (mode->status == MODE_OK && connector_funcs->mode_valid)
mode->status = connector_funcs->mode_valid(connector,
mode);
251,7 → 303,6
}
EXPORT_SYMBOL(drm_kms_helper_hotplug_event);
 
#define DRM_OUTPUT_POLL_PERIOD (10*HZ)
static void output_poll_execute(struct work_struct *work)
{
struct delayed_work *delayed_work = to_delayed_work(work);
258,13 → 309,17
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) {
drm_for_each_connector(connector, dev) {
 
/* Ignore forced connectors. */
if (connector->force)
275,8 → 330,6
if (!connector->polled || connector->polled == DRM_CONNECTOR_POLL_HPD)
continue;
 
repoll = true;
 
old_status = connector->status;
/* if we are connected and don't want to poll for disconnect
skip it */
284,10 → 337,30
!(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT))
continue;
 
repoll = true;
 
connector->status = connector->funcs->detect(connector, false);
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);
 
303,6 → 376,8
 
mutex_unlock(&dev->mode_config.mutex);
 
out: ;
 
// if (changed)
// drm_kms_helper_hotplug_event(dev);
 
340,21 → 415,10
*/
void drm_kms_helper_poll_enable(struct drm_device *dev)
{
bool poll = false;
struct drm_connector *connector;
 
if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
return;
 
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
DRM_CONNECTOR_POLL_DISCONNECT))
poll = true;
mutex_lock(&dev->mode_config.mutex);
drm_kms_helper_poll_enable_locked(dev);
mutex_unlock(&dev->mode_config.mutex);
}
 
// if (poll)
// schedule_delayed_work(&dev->mode_config.output_poll_work, DRM_OUTPUT_POLL_PERIOD);
}
EXPORT_SYMBOL(drm_kms_helper_poll_enable);
 
/**
428,7 → 492,7
return false;
 
mutex_lock(&dev->mode_config.mutex);
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
drm_for_each_connector(connector, dev) {
 
/* Only handle HPD capable connectors. */
if (!(connector->polled & DRM_CONNECTOR_POLL_HPD))