Commit 967ad7f1 authored by Daniel Vetter's avatar Daniel Vetter
Browse files

Merge remote-tracking branch 'airlied/drm-next' into drm-intel-next


The conflict in intel_drv.h tripped me up a bit since a patch in dinq
moves all the functions around, but another one in drm-next removes a
single function. So I'ev figured backing this into a backmerge would
be good.

i915_dma.c is just adjacent lines changed, nothing nefarious there.

Conflicts:
	drivers/gpu/drm/i915/i915_dma.c
	drivers/gpu/drm/i915/intel_drv.h
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parents d7bf63f2 6aba5b6c
...@@ -211,7 +211,6 @@ static struct drm_driver driver = { ...@@ -211,7 +211,6 @@ static struct drm_driver driver = {
.minor = DRIVER_MINOR, .minor = DRIVER_MINOR,
.patchlevel = DRIVER_PATCHLEVEL, .patchlevel = DRIVER_PATCHLEVEL,
.gem_init_object = ast_gem_init_object,
.gem_free_object = ast_gem_free_object, .gem_free_object = ast_gem_free_object,
.dumb_create = ast_dumb_create, .dumb_create = ast_dumb_create,
.dumb_map_offset = ast_dumb_mmap_offset, .dumb_map_offset = ast_dumb_mmap_offset,
......
...@@ -323,7 +323,6 @@ extern int ast_dumb_create(struct drm_file *file, ...@@ -323,7 +323,6 @@ extern int ast_dumb_create(struct drm_file *file,
struct drm_device *dev, struct drm_device *dev,
struct drm_mode_create_dumb *args); struct drm_mode_create_dumb *args);
extern int ast_gem_init_object(struct drm_gem_object *obj);
extern void ast_gem_free_object(struct drm_gem_object *obj); extern void ast_gem_free_object(struct drm_gem_object *obj);
extern int ast_dumb_mmap_offset(struct drm_file *file, extern int ast_dumb_mmap_offset(struct drm_file *file,
struct drm_device *dev, struct drm_device *dev,
......
...@@ -449,12 +449,6 @@ int ast_dumb_create(struct drm_file *file, ...@@ -449,12 +449,6 @@ int ast_dumb_create(struct drm_file *file,
return 0; return 0;
} }
int ast_gem_init_object(struct drm_gem_object *obj)
{
BUG();
return 0;
}
void ast_bo_unref(struct ast_bo **bo) void ast_bo_unref(struct ast_bo **bo)
{ {
struct ttm_buffer_object *tbo; struct ttm_buffer_object *tbo;
......
...@@ -97,7 +97,6 @@ static struct drm_driver driver = { ...@@ -97,7 +97,6 @@ static struct drm_driver driver = {
.major = DRIVER_MAJOR, .major = DRIVER_MAJOR,
.minor = DRIVER_MINOR, .minor = DRIVER_MINOR,
.patchlevel = DRIVER_PATCHLEVEL, .patchlevel = DRIVER_PATCHLEVEL,
.gem_init_object = cirrus_gem_init_object,
.gem_free_object = cirrus_gem_free_object, .gem_free_object = cirrus_gem_free_object,
.dumb_create = cirrus_dumb_create, .dumb_create = cirrus_dumb_create,
.dumb_map_offset = cirrus_dumb_mmap_offset, .dumb_map_offset = cirrus_dumb_mmap_offset,
......
...@@ -191,7 +191,6 @@ int cirrus_device_init(struct cirrus_device *cdev, ...@@ -191,7 +191,6 @@ int cirrus_device_init(struct cirrus_device *cdev,
struct pci_dev *pdev, struct pci_dev *pdev,
uint32_t flags); uint32_t flags);
void cirrus_device_fini(struct cirrus_device *cdev); void cirrus_device_fini(struct cirrus_device *cdev);
int cirrus_gem_init_object(struct drm_gem_object *obj);
void cirrus_gem_free_object(struct drm_gem_object *obj); void cirrus_gem_free_object(struct drm_gem_object *obj);
int cirrus_dumb_mmap_offset(struct drm_file *file, int cirrus_dumb_mmap_offset(struct drm_file *file,
struct drm_device *dev, struct drm_device *dev,
......
...@@ -255,12 +255,6 @@ int cirrus_dumb_create(struct drm_file *file, ...@@ -255,12 +255,6 @@ int cirrus_dumb_create(struct drm_file *file,
return 0; return 0;
} }
int cirrus_gem_init_object(struct drm_gem_object *obj)
{
BUG();
return 0;
}
void cirrus_bo_unref(struct cirrus_bo **bo) void cirrus_bo_unref(struct cirrus_bo **bo)
{ {
struct ttm_buffer_object *tbo; struct ttm_buffer_object *tbo;
......
...@@ -334,7 +334,6 @@ int drm_addctx(struct drm_device *dev, void *data, ...@@ -334,7 +334,6 @@ int drm_addctx(struct drm_device *dev, void *data,
mutex_lock(&dev->ctxlist_mutex); mutex_lock(&dev->ctxlist_mutex);
list_add(&ctx_entry->head, &dev->ctxlist); list_add(&ctx_entry->head, &dev->ctxlist);
++dev->ctx_count;
mutex_unlock(&dev->ctxlist_mutex); mutex_unlock(&dev->ctxlist_mutex);
return 0; return 0;
...@@ -432,7 +431,6 @@ int drm_rmctx(struct drm_device *dev, void *data, ...@@ -432,7 +431,6 @@ int drm_rmctx(struct drm_device *dev, void *data,
if (pos->handle == ctx->handle) { if (pos->handle == ctx->handle) {
list_del(&pos->head); list_del(&pos->head);
kfree(pos); kfree(pos);
--dev->ctx_count;
} }
} }
} }
......
...@@ -109,9 +109,9 @@ static void drm_mode_validate_flag(struct drm_connector *connector, ...@@ -109,9 +109,9 @@ static void drm_mode_validate_flag(struct drm_connector *connector,
* then culled (based on validity and the @maxX, @maxY parameters) and put into * then culled (based on validity and the @maxX, @maxY parameters) and put into
* the normal modes list. * the normal modes list.
* *
* Intended to be use as a generic implementation of the ->probe() @connector * Intended to be use as a generic implementation of the ->fill_modes()
* callback for drivers that use the crtc helpers for output mode filtering and * @connector vfunc for drivers that use the crtc helpers for output mode
* detection. * filtering and detection.
* *
* RETURNS: * RETURNS:
* Number of modes found on @connector. * Number of modes found on @connector.
......
...@@ -228,12 +228,12 @@ i2c_dp_aux_add_bus(struct i2c_adapter *adapter) ...@@ -228,12 +228,12 @@ i2c_dp_aux_add_bus(struct i2c_adapter *adapter)
EXPORT_SYMBOL(i2c_dp_aux_add_bus); EXPORT_SYMBOL(i2c_dp_aux_add_bus);
/* Helpers for DP link training */ /* Helpers for DP link training */
static u8 dp_link_status(u8 link_status[DP_LINK_STATUS_SIZE], int r) static u8 dp_link_status(const u8 link_status[DP_LINK_STATUS_SIZE], int r)
{ {
return link_status[r - DP_LANE0_1_STATUS]; return link_status[r - DP_LANE0_1_STATUS];
} }
static u8 dp_get_lane_status(u8 link_status[DP_LINK_STATUS_SIZE], static u8 dp_get_lane_status(const u8 link_status[DP_LINK_STATUS_SIZE],
int lane) int lane)
{ {
int i = DP_LANE0_1_STATUS + (lane >> 1); int i = DP_LANE0_1_STATUS + (lane >> 1);
...@@ -242,7 +242,7 @@ static u8 dp_get_lane_status(u8 link_status[DP_LINK_STATUS_SIZE], ...@@ -242,7 +242,7 @@ static u8 dp_get_lane_status(u8 link_status[DP_LINK_STATUS_SIZE],
return (l >> s) & 0xf; return (l >> s) & 0xf;
} }
bool drm_dp_channel_eq_ok(u8 link_status[DP_LINK_STATUS_SIZE], bool drm_dp_channel_eq_ok(const u8 link_status[DP_LINK_STATUS_SIZE],
int lane_count) int lane_count)
{ {
u8 lane_align; u8 lane_align;
...@@ -262,7 +262,7 @@ bool drm_dp_channel_eq_ok(u8 link_status[DP_LINK_STATUS_SIZE], ...@@ -262,7 +262,7 @@ bool drm_dp_channel_eq_ok(u8 link_status[DP_LINK_STATUS_SIZE],
} }
EXPORT_SYMBOL(drm_dp_channel_eq_ok); EXPORT_SYMBOL(drm_dp_channel_eq_ok);
bool drm_dp_clock_recovery_ok(u8 link_status[DP_LINK_STATUS_SIZE], bool drm_dp_clock_recovery_ok(const u8 link_status[DP_LINK_STATUS_SIZE],
int lane_count) int lane_count)
{ {
int lane; int lane;
...@@ -277,7 +277,7 @@ bool drm_dp_clock_recovery_ok(u8 link_status[DP_LINK_STATUS_SIZE], ...@@ -277,7 +277,7 @@ bool drm_dp_clock_recovery_ok(u8 link_status[DP_LINK_STATUS_SIZE],
} }
EXPORT_SYMBOL(drm_dp_clock_recovery_ok); EXPORT_SYMBOL(drm_dp_clock_recovery_ok);
u8 drm_dp_get_adjust_request_voltage(u8 link_status[DP_LINK_STATUS_SIZE], u8 drm_dp_get_adjust_request_voltage(const u8 link_status[DP_LINK_STATUS_SIZE],
int lane) int lane)
{ {
int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
...@@ -290,7 +290,7 @@ u8 drm_dp_get_adjust_request_voltage(u8 link_status[DP_LINK_STATUS_SIZE], ...@@ -290,7 +290,7 @@ u8 drm_dp_get_adjust_request_voltage(u8 link_status[DP_LINK_STATUS_SIZE],
} }
EXPORT_SYMBOL(drm_dp_get_adjust_request_voltage); EXPORT_SYMBOL(drm_dp_get_adjust_request_voltage);
u8 drm_dp_get_adjust_request_pre_emphasis(u8 link_status[DP_LINK_STATUS_SIZE], u8 drm_dp_get_adjust_request_pre_emphasis(const u8 link_status[DP_LINK_STATUS_SIZE],
int lane) int lane)
{ {
int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
...@@ -303,7 +303,7 @@ u8 drm_dp_get_adjust_request_pre_emphasis(u8 link_status[DP_LINK_STATUS_SIZE], ...@@ -303,7 +303,7 @@ u8 drm_dp_get_adjust_request_pre_emphasis(u8 link_status[DP_LINK_STATUS_SIZE],
} }
EXPORT_SYMBOL(drm_dp_get_adjust_request_pre_emphasis); EXPORT_SYMBOL(drm_dp_get_adjust_request_pre_emphasis);
void drm_dp_link_train_clock_recovery_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]) { void drm_dp_link_train_clock_recovery_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) {
if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0) if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0)
udelay(100); udelay(100);
else else
...@@ -311,7 +311,7 @@ void drm_dp_link_train_clock_recovery_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]) { ...@@ -311,7 +311,7 @@ void drm_dp_link_train_clock_recovery_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]) {
} }
EXPORT_SYMBOL(drm_dp_link_train_clock_recovery_delay); EXPORT_SYMBOL(drm_dp_link_train_clock_recovery_delay);
void drm_dp_link_train_channel_eq_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]) { void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) {
if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0) if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0)
udelay(400); udelay(400);
else else
......
...@@ -171,76 +171,6 @@ static const struct drm_ioctl_desc drm_ioctls[] = { ...@@ -171,76 +171,6 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
/**
* drm_legacy_dev_reinit
*
* Reinitializes a legacy/ums drm device in it's lastclose function.
*/
static void drm_legacy_dev_reinit(struct drm_device *dev)
{
int i;
if (drm_core_check_feature(dev, DRIVER_MODESET))
return;
atomic_set(&dev->ioctl_count, 0);
atomic_set(&dev->vma_count, 0);
for (i = 0; i < ARRAY_SIZE(dev->counts); i++)
atomic_set(&dev->counts[i], 0);
dev->sigdata.lock = NULL;
dev->context_flag = 0;
dev->last_context = 0;
dev->if_version = 0;
}
/**
* Take down the DRM device.
*
* \param dev DRM device structure.
*
* Frees every resource in \p dev.
*
* \sa drm_device
*/
int drm_lastclose(struct drm_device * dev)
{
struct drm_vma_entry *vma, *vma_temp;
DRM_DEBUG("\n");
if (dev->driver->lastclose)
dev->driver->lastclose(dev);
DRM_DEBUG("driver lastclose completed\n");
if (dev->irq_enabled && !drm_core_check_feature(dev, DRIVER_MODESET))
drm_irq_uninstall(dev);
mutex_lock(&dev->struct_mutex);
drm_agp_clear(dev);
drm_legacy_sg_cleanup(dev);
/* Clear vma list (only built for debugging) */
list_for_each_entry_safe(vma, vma_temp, &dev->vmalist, head) {
list_del(&vma->head);
kfree(vma);
}
drm_legacy_dma_takedown(dev);
dev->dev_mapping = NULL;
mutex_unlock(&dev->struct_mutex);
drm_legacy_dev_reinit(dev);
DRM_DEBUG("lastclose completed\n");
return 0;
}
/** File operations structure */ /** File operations structure */
static const struct file_operations drm_stub_fops = { static const struct file_operations drm_stub_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -386,7 +316,6 @@ long drm_ioctl(struct file *filp, ...@@ -386,7 +316,6 @@ long drm_ioctl(struct file *filp,
return -ENODEV; return -ENODEV;
atomic_inc(&dev->ioctl_count); atomic_inc(&dev->ioctl_count);
atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);
++file_priv->ioctl_count; ++file_priv->ioctl_count;
if ((nr >= DRM_CORE_IOCTL_COUNT) && if ((nr >= DRM_CORE_IOCTL_COUNT) &&
......
...@@ -1264,6 +1264,18 @@ struct edid *drm_get_edid(struct drm_connector *connector, ...@@ -1264,6 +1264,18 @@ struct edid *drm_get_edid(struct drm_connector *connector,
} }
EXPORT_SYMBOL(drm_get_edid); EXPORT_SYMBOL(drm_get_edid);
/**
* drm_edid_duplicate - duplicate an EDID and the extensions
* @edid: EDID to duplicate
*
* Return duplicate edid or NULL on allocation failure.
*/
struct edid *drm_edid_duplicate(const struct edid *edid)
{
return kmemdup(edid, (edid->extensions + 1) * EDID_LENGTH, GFP_KERNEL);
}
EXPORT_SYMBOL(drm_edid_duplicate);
/*** EDID parsing ***/ /*** EDID parsing ***/
/** /**
...@@ -3013,6 +3025,8 @@ int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb) ...@@ -3013,6 +3025,8 @@ int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb)
/* Speaker Allocation Data Block */ /* Speaker Allocation Data Block */
if (dbl == 3) { if (dbl == 3) {
*sadb = kmalloc(dbl, GFP_KERNEL); *sadb = kmalloc(dbl, GFP_KERNEL);
if (!*sadb)
return -ENOMEM;
memcpy(*sadb, &db[1], dbl); memcpy(*sadb, &db[1], dbl);
count = dbl; count = dbl;
break; break;
......
...@@ -32,7 +32,7 @@ MODULE_PARM_DESC(edid_firmware, "Do not probe monitor, use specified EDID blob " ...@@ -32,7 +32,7 @@ MODULE_PARM_DESC(edid_firmware, "Do not probe monitor, use specified EDID blob "
"from built-in data or /lib/firmware instead. "); "from built-in data or /lib/firmware instead. ");
#define GENERIC_EDIDS 5 #define GENERIC_EDIDS 5
static char *generic_edid_name[GENERIC_EDIDS] = { static const char *generic_edid_name[GENERIC_EDIDS] = {
"edid/1024x768.bin", "edid/1024x768.bin",
"edid/1280x1024.bin", "edid/1280x1024.bin",
"edid/1600x1200.bin", "edid/1600x1200.bin",
...@@ -40,7 +40,7 @@ static char *generic_edid_name[GENERIC_EDIDS] = { ...@@ -40,7 +40,7 @@ static char *generic_edid_name[GENERIC_EDIDS] = {
"edid/1920x1080.bin", "edid/1920x1080.bin",
}; };
static u8 generic_edid[GENERIC_EDIDS][128] = { static const u8 generic_edid[GENERIC_EDIDS][128] = {
{ {
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
0x31, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
...@@ -133,63 +133,68 @@ static u8 generic_edid[GENERIC_EDIDS][128] = { ...@@ -133,63 +133,68 @@ static u8 generic_edid[GENERIC_EDIDS][128] = {
}, },
}; };
static int edid_size(const u8 *edid, int data_size)
{
if (data_size < EDID_LENGTH)
return 0;
return (edid[0x7e] + 1) * EDID_LENGTH;
}
static u8 *edid_load(struct drm_connector *connector, const char *name, static u8 *edid_load(struct drm_connector *connector, const char *name,
const char *connector_name) const char *connector_name)
{ {
const struct firmware *fw; const struct firmware *fw = NULL;
struct platform_device *pdev; const u8 *fwdata;
u8 *fwdata = NULL, *edid, *new_edid; u8 *edid;
int fwsize, expected; int fwsize, builtin;
int builtin = 0, err = 0;
int i, valid_extensions = 0; int i, valid_extensions = 0;
bool print_bad_edid = !connector->bad_edid_counter || (drm_debug & DRM_UT_KMS); bool print_bad_edid = !connector->bad_edid_counter || (drm_debug & DRM_UT_KMS);
builtin = 0;
for (i = 0; i < GENERIC_EDIDS; i++) {
if (strcmp(name, generic_edid_name[i]) == 0) {
fwdata = generic_edid[i];
fwsize = sizeof(generic_edid[i]);
builtin = 1;
break;
}
}
if (!builtin) {
struct platform_device *pdev;
int err;
pdev = platform_device_register_simple(connector_name, -1, NULL, 0); pdev = platform_device_register_simple(connector_name, -1, NULL, 0);
if (IS_ERR(pdev)) { if (IS_ERR(pdev)) {
DRM_ERROR("Failed to register EDID firmware platform device " DRM_ERROR("Failed to register EDID firmware platform device "
"for connector \"%s\"\n", connector_name); "for connector \"%s\"\n", connector_name);
err = -EINVAL; return ERR_CAST(pdev);
goto out;
} }
err = request_firmware(&fw, name, &pdev->dev); err = request_firmware(&fw, name, &pdev->dev);
platform_device_unregister(pdev); platform_device_unregister(pdev);
if (err) {
i = 0;
while (i < GENERIC_EDIDS && strcmp(name, generic_edid_name[i]))
i++;
if (i < GENERIC_EDIDS) {
err = 0;
builtin = 1;
fwdata = generic_edid[i];
fwsize = sizeof(generic_edid[i]);
}
}
if (err) { if (err) {
DRM_ERROR("Requesting EDID firmware \"%s\" failed (err=%d)\n", DRM_ERROR("Requesting EDID firmware \"%s\" failed (err=%d)\n",
name, err); name, err);
goto out; return ERR_PTR(err);
} }
if (fwdata == NULL) { fwdata = fw->data;
fwdata = (u8 *) fw->data;
fwsize = fw->size; fwsize = fw->size;
} }
expected = (fwdata[0x7e] + 1) * EDID_LENGTH; if (edid_size(fwdata, fwsize) != fwsize) {
if (expected != fwsize) {
DRM_ERROR("Size of EDID firmware \"%s\" is invalid " DRM_ERROR("Size of EDID firmware \"%s\" is invalid "
"(expected %d, got %d)\n", name, expected, (int) fwsize); "(expected %d, got %d\n", name,
err = -EINVAL; edid_size(fwdata, fwsize), (int)fwsize);
goto relfw_out; edid = ERR_PTR(-EINVAL);
goto out;
} }
edid = kmemdup(fwdata, fwsize, GFP_KERNEL); edid = kmemdup(fwdata, fwsize, GFP_KERNEL);
if (edid == NULL) { if (edid == NULL) {
err = -ENOMEM; edid = ERR_PTR(-ENOMEM);
goto relfw_out; goto out;
} }
if (!drm_edid_block_valid(edid, 0, print_bad_edid)) { if (!drm_edid_block_valid(edid, 0, print_bad_edid)) {
...@@ -197,8 +202,8 @@ static u8 *edid_load(struct drm_connector *connector, const char *name, ...@@ -197,8 +202,8 @@ static u8 *edid_load(struct drm_connector *connector, const char *name,
DRM_ERROR("Base block of EDID firmware \"%s\" is invalid ", DRM_ERROR("Base block of EDID firmware \"%s\" is invalid ",
name); name);
kfree(edid); kfree(edid);
err = -EINVAL; edid = ERR_PTR(-EINVAL);
goto relfw_out; goto out;
} }
for (i = 1; i <= edid[0x7e]; i++) { for (i = 1; i <= edid[0x7e]; i++) {
...@@ -210,18 +215,17 @@ static u8 *edid_load(struct drm_connector *connector, const char *name, ...@@ -210,18 +215,17 @@ static u8 *edid_load(struct drm_connector *connector, const char *name,
} }
if (valid_extensions != edid[0x7e]) { if (valid_extensions != edid[0x7e]) {
u8 *new_edid;
edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions; edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions;
DRM_INFO("Found %d valid extensions instead of %d in EDID data " DRM_INFO("Found %d valid extensions instead of %d in EDID data "
"\"%s\" for connector \"%s\"\n", valid_extensions, "\"%s\" for connector \"%s\"\n", valid_extensions,
edid[0x7e], name, connector_name); edid[0x7e], name, connector_name);
edid[0x7e] = valid_extensions; edid[0x7e] = valid_extensions;
new_edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, new_edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH,
GFP_KERNEL); GFP_KERNEL);
if (new_edid == NULL) { if (new_edid)
err = -ENOMEM;
kfree(edid);
goto relfw_out;
}
edid = new_edid; edid = new_edid;
} }
...@@ -230,13 +234,9 @@ static u8 *edid_load(struct drm_connector *connector, const char *name, ...@@ -230,13 +234,9 @@ static u8 *edid_load(struct drm_connector *connector, const char *name,
"external", valid_extensions, valid_extensions == 1 ? "" : "s", "external", valid_extensions, valid_extensions == 1 ? "" : "s",
name, connector_name); name, connector_name);
relfw_out:
release_firmware(fw);
out: out:
if (err) if (fw)
return ERR_PTR(err); release_firmware(fw);
return edid; return edid;
} }
......
...@@ -852,7 +852,6 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var, ...@@ -852,7 +852,6 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
struct drm_fb_helper *fb_helper = info->par; struct drm_fb_helper *fb_helper = info->par;
struct drm_device *dev = fb_helper->dev; struct drm_device *dev = fb_helper->dev;
struct drm_mode_set *modeset; struct drm_mode_set *modeset;
struct drm_crtc *crtc;
int ret = 0; int ret = 0;
int i; int i;
...@@ -863,8 +862,6 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var, ...@@ -863,8 +862,6 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
} }
for (i = 0; i < fb_helper->crtc_count; i++) { for (i = 0; i < fb_helper->crtc_count; i++) {
crtc = fb_helper->crtc_info[i].mode_set.crtc;
modeset = &fb_helper->crtc_info[i].mode_set; modeset = &fb_helper->crtc_info[i].mode_set;
modeset->x = var->xoffset; modeset->x = var->xoffset;
...@@ -1360,7 +1357,6 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, ...@@ -1360,7 +1357,6 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_helper_funcs *connector_funcs; struct drm_connector_helper_funcs *connector_funcs;
struct drm_encoder *encoder; struct drm_encoder *encoder;
struct drm_fb_helper_crtc *best_crtc;
int my_score, best_score, score; int my_score, best_score, score;
struct drm_fb_helper_crtc **crtcs, *crtc; struct drm_fb_helper_crtc **crtcs, *crtc;
struct drm_fb_helper_connector *fb_helper_conn; struct drm_fb_helper_connector *fb_helper_conn;
...@@ -1372,7 +1368,6 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, ...@@ -1372,7 +1368,6 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
connector = fb_helper_conn->connector; connector = fb_helper_conn->connector;
best_crtcs[n] = NULL; best_crtcs[n] = NULL;
best_crtc = NULL;
best_score = drm_pick_crtcs(fb_helper, best_crtcs, modes, n+1, width, height); best_score = drm_pick_crtcs(fb_helper, best_crtcs, modes, n+1, width, height);
if (modes[n] == NULL) if (modes[n] == NULL)
return best_score; return best_score;
...@@ -1421,7 +1416,6 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, ...@@ -1421,7 +1416,6 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
score = my_score + drm_pick_crtcs(fb_helper, crtcs, modes, n + 1, score = my_score + drm_pick_crtcs(fb_helper, crtcs, modes, n + 1,
width, height); width, height);
if (score > best_score) { if (score > best_score) {
best_crtc = crtc;
best_score = score; best_score = score;
memcpy(best_crtcs, crtcs, memcpy(best_crtcs, crtcs,
dev->mode_config.num_connector * dev->mode_config.num_connector *
...@@ -1588,8 +1582,7 @@ EXPORT_SYMBOL(drm_fb_helper_initial_config); ...@@ -1588,8 +1582,7 @@ 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;
int count = 0; u32 max_width, max_height;
u32 max_width, max_height, bpp_sel;
if (!fb_helper->fb) if (!fb_helper->fb)
return 0; return 0;
...@@ -1604,10 +1597,8 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) ...@@ -1604,10 +1597,8 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
max_width = fb_helper->fb->width; max_width = fb_helper->fb->width;
max_height = fb_helper->fb->height; max_height = fb_helper->fb->height;
bpp_sel = fb_helper->fb->bits_per_pixel;
count = drm_fb_helper_probe_connector_modes(fb_helper, max_width, drm_fb_helper_probe_connector_modes(fb_helper, max_width, max_height);
max_height);
mutex_unlock(&fb_helper->dev->mode_config.mutex); mutex_unlock(&fb_helper->dev->mode_config.mutex);
drm_modeset_lock_all(dev); drm_modeset_lock_all(dev);
......
...@@ -113,7 +113,6 @@ int drm_open(struct inode *inode, struct file *filp) ...@@ -113,7 +113,6 @@ int drm_open(struct inode *inode, struct file *filp)
retcode = drm_open_helper(inode, filp, dev); retcode = drm_open_helper(inode, filp, dev);
if (retcode) if (retcode)
goto err_undo; goto err_undo;
atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
if (need_setup) { if (need_setup) {
retcode = drm_setup(dev); retcode = drm_setup(dev);
if (retcode) if (retcode)
...@@ -385,6 +384,71 @@ static void drm_events_release(struct drm_file *file_priv) ...@@ -385,6 +384,71 @@ static void drm_events_release(struct drm_file *file_priv)
spin_unlock_irqrestore(&dev->event_lock, flags); spin_unlock_irqrestore(&dev->event_lock, flags);
} }
/**
* drm_legacy_dev_reinit
*
* Reinitializes a legacy/ums drm device in it's lastclose function.
*/
static void drm_legacy_dev_reinit(struct drm_device *dev)
{
if (drm_core_check_feature(dev, DRIVER_MODESET))
return;
atomic_set(&dev->ioctl_count, 0);
atomic_set(&dev->vma_count, 0);
dev->sigdata.lock = NULL;
dev->context_flag = 0;
dev->last_context = 0;
dev->if_version = 0;
}
/**
* Take down the DRM device.
*
* \param dev DRM device structure.
*
* Frees every resource in \p dev.
*
* \sa drm_device
*/
int drm_lastclose(struct drm_device * dev)
{
struct drm_vma_entry *vma, *vma_temp;
DRM_DEBUG("\n");
if (dev->driver->lastclose)
dev->driver->lastclose(dev);
DRM_DEBUG("driver lastclose completed\n");
if (dev->irq_enabled && !drm_core_check_feature(dev, DRIVER_MODESET))
drm_irq_uninstall(dev);
mutex_lock(&dev->struct_mutex);
drm_agp_clear(dev);
drm_legacy_sg_cleanup(dev);
/* Clear vma list (only built for debugging) */
list_for_each_entry_safe(vma, vma_temp, &dev->vmalist, head) {
list_del(&vma->head);
kfree(vma);
}
drm_legacy_dma_takedown(dev);
dev->dev_mapping = NULL;
mutex_unlock(&dev->struct_mutex);
drm_legacy_dev_reinit(dev);
DRM_DEBUG("lastclose completed\n");
return 0;
}
/** /**
* Release file. * Release file.
* *
...@@ -454,7 +518,6 @@ int drm_release(struct inode *inode, struct file *filp) ...@@ -454,7 +518,6 @@ int drm_release(struct inode *inode, struct file *filp)
list_del(&pos->head); list_del(&pos->head);
kfree(pos); kfree(pos);
--dev->ctx_count;
} }
} }
} }
...@@ -516,7 +579,6 @@ int drm_release(struct inode *inode, struct file *filp) ...@@ -516,7 +579,6 @@ int drm_release(struct inode *inode, struct file *filp)
* End inline drm_release * End inline drm_release
*/ */
atomic_inc(&dev->counts[_DRM_STAT_CLOSES]);
if (!--dev->open_count) { if (!--dev->open_count) {
if (atomic_read(&dev->ioctl_count)) { if (atomic_read(&dev->ioctl_count)) {
DRM_ERROR("Device busy: %d\n", DRM_ERROR("Device busy: %d\n",
......
...@@ -160,35 +160,6 @@ void drm_gem_private_object_init(struct drm_device *dev, ...@@ -160,35 +160,6 @@ void drm_gem_private_object_init(struct drm_device *dev,
} }
EXPORT_SYMBOL(drm_gem_private_object_init); EXPORT_SYMBOL(drm_gem_private_object_init);
/**
* Allocate a GEM object of the specified size with shmfs backing store
*/
struct drm_gem_object *
drm_gem_object_alloc(struct drm_device *dev, size_t size)
{
struct drm_gem_object *obj;
obj = kzalloc(sizeof(*obj), GFP_KERNEL);
if (!obj)
goto free;
if (drm_gem_object_init(dev, obj, size) != 0)
goto free;
if (dev->driver->gem_init_object != NULL &&
dev->driver->gem_init_object(obj) != 0) {
goto fput;
}
return obj;
fput:
/* Object_init mangles the global counters - readjust them. */
fput(obj->filp);
free:
kfree(obj);
return NULL;
}
EXPORT_SYMBOL(drm_gem_object_alloc);
static void static void
drm_gem_remove_prime_handles(struct drm_gem_object *obj, struct drm_file *filp) drm_gem_remove_prime_handles(struct drm_gem_object *obj, struct drm_file *filp)
{ {
......
...@@ -67,7 +67,6 @@ int drm_global_item_ref(struct drm_global_reference *ref) ...@@ -67,7 +67,6 @@ int drm_global_item_ref(struct drm_global_reference *ref)
{ {
int ret; int ret;
struct drm_global_item *item = &glob[ref->global_type]; struct drm_global_item *item = &glob[ref->global_type];
void *object;
mutex_lock(&item->mutex); mutex_lock(&item->mutex);
if (item->refcount == 0) { if (item->refcount == 0) {
...@@ -85,7 +84,6 @@ int drm_global_item_ref(struct drm_global_reference *ref) ...@@ -85,7 +84,6 @@ int drm_global_item_ref(struct drm_global_reference *ref)
} }
++item->refcount; ++item->refcount;
ref->object = item->object; ref->object = item->object;
object = item->object;
mutex_unlock(&item->mutex); mutex_unlock(&item->mutex);
return 0; return 0;
out_err: out_err:
......
...@@ -163,13 +163,13 @@ int drm_vblank_info(struct seq_file *m, void *data) ...@@ -163,13 +163,13 @@ int drm_vblank_info(struct seq_file *m, void *data)
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
for (crtc = 0; crtc < dev->num_crtcs; crtc++) { for (crtc = 0; crtc < dev->num_crtcs; crtc++) {
seq_printf(m, "CRTC %d enable: %d\n", seq_printf(m, "CRTC %d enable: %d\n",
crtc, atomic_read(&dev->vblank_refcount[crtc])); crtc, atomic_read(&dev->vblank[crtc].refcount));
seq_printf(m, "CRTC %d counter: %d\n", seq_printf(m, "CRTC %d counter: %d\n",
crtc, drm_vblank_count(dev, crtc)); crtc, drm_vblank_count(dev, crtc));
seq_printf(m, "CRTC %d last wait: %d\n", seq_printf(m, "CRTC %d last wait: %d\n",
crtc, dev->last_vblank_wait[crtc]); crtc, dev->vblank[crtc].last_wait);
seq_printf(m, "CRTC %d in modeset: %d\n", seq_printf(m, "CRTC %d in modeset: %d\n",
crtc, dev->vblank_inmodeset[crtc]); crtc, dev->vblank[crtc].inmodeset);
} }
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
return 0; return 0;
......
...@@ -43,9 +43,8 @@ ...@@ -43,9 +43,8 @@
#include <linux/export.h> #include <linux/export.h>
/* Access macro for slots in vblank timestamp ringbuffer. */ /* Access macro for slots in vblank timestamp ringbuffer. */
#define vblanktimestamp(dev, crtc, count) ( \ #define vblanktimestamp(dev, crtc, count) \
(dev)->_vblank_time[(crtc) * DRM_VBLANKTIME_RBSIZE + \ ((dev)->vblank[crtc].time[(count) % DRM_VBLANKTIME_RBSIZE])
((count) % DRM_VBLANKTIME_RBSIZE)])
/* Retry timestamp calculation up to 3 times to satisfy /* Retry timestamp calculation up to 3 times to satisfy
* drm_timestamp_precision before giving up. * drm_timestamp_precision before giving up.
...@@ -89,8 +88,7 @@ int drm_irq_by_busid(struct drm_device *dev, void *data, ...@@ -89,8 +88,7 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
*/ */
static void clear_vblank_timestamps(struct drm_device *dev, int crtc) static void clear_vblank_timestamps(struct drm_device *dev, int crtc)
{ {
memset(&dev->_vblank_time[crtc * DRM_VBLANKTIME_RBSIZE], 0, memset(dev->vblank[crtc].time, 0, sizeof(dev->vblank[crtc].time));
DRM_VBLANKTIME_RBSIZE * sizeof(struct timeval));
} }
/* /*
...@@ -115,7 +113,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) ...@@ -115,7 +113,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
spin_lock_irqsave(&dev->vblank_time_lock, irqflags); spin_lock_irqsave(&dev->vblank_time_lock, irqflags);
dev->driver->disable_vblank(dev, crtc); dev->driver->disable_vblank(dev, crtc);
dev->vblank_enabled[crtc] = 0; dev->vblank[crtc].enabled = false;
/* No further vblank irq's will be processed after /* No further vblank irq's will be processed after
* this point. Get current hardware vblank count and * this point. Get current hardware vblank count and
...@@ -130,9 +128,9 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) ...@@ -130,9 +128,9 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
* delayed gpu counter increment. * delayed gpu counter increment.
*/ */
do { do {
dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc); dev->vblank[crtc].last = dev->driver->get_vblank_counter(dev, crtc);
vblrc = drm_get_last_vbltimestamp(dev, crtc, &tvblank, 0); vblrc = drm_get_last_vbltimestamp(dev, crtc, &tvblank, 0);
} while (dev->last_vblank[crtc] != dev->driver->get_vblank_counter(dev, crtc) && (--count) && vblrc); } while (dev->vblank[crtc].last != dev->driver->get_vblank_counter(dev, crtc) && (--count) && vblrc);
if (!count) if (!count)
vblrc = 0; vblrc = 0;
...@@ -140,7 +138,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) ...@@ -140,7 +138,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
/* Compute time difference to stored timestamp of last vblank /* Compute time difference to stored timestamp of last vblank
* as updated by last invocation of drm_handle_vblank() in vblank irq. * as updated by last invocation of drm_handle_vblank() in vblank irq.
*/ */
vblcount = atomic_read(&dev->_vblank_count[crtc]); vblcount = atomic_read(&dev->vblank[crtc].count);
diff_ns = timeval_to_ns(&tvblank) - diff_ns = timeval_to_ns(&tvblank) -
timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount)); timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount));
...@@ -157,7 +155,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) ...@@ -157,7 +155,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
* hope for the best. * hope for the best.
*/ */
if ((vblrc > 0) && (abs64(diff_ns) > 1000000)) { if ((vblrc > 0) && (abs64(diff_ns) > 1000000)) {
atomic_inc(&dev->_vblank_count[crtc]); atomic_inc(&dev->vblank[crtc].count);
smp_mb__after_atomic_inc(); smp_mb__after_atomic_inc();
} }
...@@ -178,8 +176,8 @@ static void vblank_disable_fn(unsigned long arg) ...@@ -178,8 +176,8 @@ static void vblank_disable_fn(unsigned long arg)
for (i = 0; i < dev->num_crtcs; i++) { for (i = 0; i < dev->num_crtcs; i++) {
spin_lock_irqsave(&dev->vbl_lock, irqflags); spin_lock_irqsave(&dev->vbl_lock, irqflags);
if (atomic_read(&dev->vblank_refcount[i]) == 0 && if (atomic_read(&dev->vblank[i].refcount) == 0 &&
dev->vblank_enabled[i]) { dev->vblank[i].enabled) {
DRM_DEBUG("disabling vblank on crtc %d\n", i); DRM_DEBUG("disabling vblank on crtc %d\n", i);
vblank_disable_and_save(dev, i); vblank_disable_and_save(dev, i);
} }
...@@ -197,14 +195,7 @@ void drm_vblank_cleanup(struct drm_device *dev) ...@@ -197,14 +195,7 @@ void drm_vblank_cleanup(struct drm_device *dev)
vblank_disable_fn((unsigned long)dev); vblank_disable_fn((unsigned long)dev);
kfree(dev->vbl_queue); kfree(dev->vblank);
kfree(dev->_vblank_count);
kfree(dev->vblank_refcount);
kfree(dev->vblank_enabled);
kfree(dev->last_vblank);
kfree(dev->last_vblank_wait);
kfree(dev->vblank_inmodeset);
kfree(dev->_vblank_time);
dev->num_crtcs = 0; dev->num_crtcs = 0;
} }
...@@ -221,40 +212,12 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs) ...@@ -221,40 +212,12 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
dev->num_crtcs = num_crtcs; dev->num_crtcs = num_crtcs;
dev->vbl_queue = kmalloc(sizeof(wait_queue_head_t) * num_crtcs, dev->vblank = kcalloc(num_crtcs, sizeof(*dev->vblank), GFP_KERNEL);
GFP_KERNEL); if (!dev->vblank)
if (!dev->vbl_queue)
goto err; goto err;
dev->_vblank_count = kmalloc(sizeof(atomic_t) * num_crtcs, GFP_KERNEL); for (i = 0; i < num_crtcs; i++)
if (!dev->_vblank_count) init_waitqueue_head(&dev->vblank[i].queue);
goto err;
dev->vblank_refcount = kmalloc(sizeof(atomic_t) * num_crtcs,
GFP_KERNEL);
if (!dev->vblank_refcount)
goto err;
dev->vblank_enabled = kcalloc(num_crtcs, sizeof(int), GFP_KERNEL);
if (!dev->vblank_enabled)
goto err;
dev->last_vblank = kcalloc(num_crtcs, sizeof(u32), GFP_KERNEL);
if (!dev->last_vblank)
goto err;
dev->last_vblank_wait = kcalloc(num_crtcs, sizeof(u32), GFP_KERNEL);
if (!dev->last_vblank_wait)
goto err;
dev->vblank_inmodeset = kcalloc(num_crtcs, sizeof(int), GFP_KERNEL);
if (!dev->vblank_inmodeset)
goto err;
dev->_vblank_time = kcalloc(num_crtcs * DRM_VBLANKTIME_RBSIZE,
sizeof(struct timeval), GFP_KERNEL);
if (!dev->_vblank_time)
goto err;
DRM_INFO("Supports vblank timestamp caching Rev 1 (10.10.2010).\n"); DRM_INFO("Supports vblank timestamp caching Rev 1 (10.10.2010).\n");
...@@ -264,14 +227,8 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs) ...@@ -264,14 +227,8 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
else else
DRM_INFO("No driver support for vblank timestamp query.\n"); DRM_INFO("No driver support for vblank timestamp query.\n");
/* Zero per-crtc vblank stuff */ dev->vblank_disable_allowed = false;
for (i = 0; i < num_crtcs; i++) {
init_waitqueue_head(&dev->vbl_queue[i]);
atomic_set(&dev->_vblank_count[i], 0);
atomic_set(&dev->vblank_refcount[i], 0);
}
dev->vblank_disable_allowed = 0;
return 0; return 0;
err: err:
...@@ -336,7 +293,7 @@ int drm_irq_install(struct drm_device *dev) ...@@ -336,7 +293,7 @@ int drm_irq_install(struct drm_device *dev)
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
return -EBUSY; return -EBUSY;
} }
dev->irq_enabled = 1; dev->irq_enabled = true;
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev)); DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));
...@@ -359,7 +316,7 @@ int drm_irq_install(struct drm_device *dev) ...@@ -359,7 +316,7 @@ int drm_irq_install(struct drm_device *dev)
if (ret < 0) { if (ret < 0) {
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
dev->irq_enabled = 0; dev->irq_enabled = false;
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
return ret; return ret;
} }
...@@ -373,7 +330,7 @@ int drm_irq_install(struct drm_device *dev) ...@@ -373,7 +330,7 @@ int drm_irq_install(struct drm_device *dev)
if (ret < 0) { if (ret < 0) {
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
dev->irq_enabled = 0; dev->irq_enabled = false;
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
if (!drm_core_check_feature(dev, DRIVER_MODESET)) if (!drm_core_check_feature(dev, DRIVER_MODESET))
vga_client_register(dev->pdev, NULL, NULL, NULL); vga_client_register(dev->pdev, NULL, NULL, NULL);
...@@ -394,14 +351,15 @@ EXPORT_SYMBOL(drm_irq_install); ...@@ -394,14 +351,15 @@ EXPORT_SYMBOL(drm_irq_install);
int drm_irq_uninstall(struct drm_device *dev) int drm_irq_uninstall(struct drm_device *dev)
{ {
unsigned long irqflags; unsigned long irqflags;
int irq_enabled, i; bool irq_enabled;
int i;
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return -EINVAL; return -EINVAL;
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
irq_enabled = dev->irq_enabled; irq_enabled = dev->irq_enabled;
dev->irq_enabled = 0; dev->irq_enabled = false;
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
/* /*
...@@ -410,9 +368,9 @@ int drm_irq_uninstall(struct drm_device *dev) ...@@ -410,9 +368,9 @@ int drm_irq_uninstall(struct drm_device *dev)
if (dev->num_crtcs) { if (dev->num_crtcs) {
spin_lock_irqsave(&dev->vbl_lock, irqflags); spin_lock_irqsave(&dev->vbl_lock, irqflags);
for (i = 0; i < dev->num_crtcs; i++) { for (i = 0; i < dev->num_crtcs; i++) {
DRM_WAKEUP(&dev->vbl_queue[i]); DRM_WAKEUP(&dev->vblank[i].queue);
dev->vblank_enabled[i] = 0; dev->vblank[i].enabled = false;
dev->last_vblank[i] = dev->vblank[i].last =
dev->driver->get_vblank_counter(dev, i); dev->driver->get_vblank_counter(dev, i);
} }
spin_unlock_irqrestore(&dev->vbl_lock, irqflags); spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
...@@ -795,7 +753,7 @@ EXPORT_SYMBOL(drm_get_last_vbltimestamp); ...@@ -795,7 +753,7 @@ EXPORT_SYMBOL(drm_get_last_vbltimestamp);
*/ */
u32 drm_vblank_count(struct drm_device *dev, int crtc) u32 drm_vblank_count(struct drm_device *dev, int crtc)
{ {
return atomic_read(&dev->_vblank_count[crtc]); return atomic_read(&dev->vblank[crtc].count);
} }
EXPORT_SYMBOL(drm_vblank_count); EXPORT_SYMBOL(drm_vblank_count);
...@@ -824,10 +782,10 @@ u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, ...@@ -824,10 +782,10 @@ u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc,
* a seqlock. * a seqlock.
*/ */
do { do {
cur_vblank = atomic_read(&dev->_vblank_count[crtc]); cur_vblank = atomic_read(&dev->vblank[crtc].count);
*vblanktime = vblanktimestamp(dev, crtc, cur_vblank); *vblanktime = vblanktimestamp(dev, crtc, cur_vblank);
smp_rmb(); smp_rmb();
} while (cur_vblank != atomic_read(&dev->_vblank_count[crtc])); } while (cur_vblank != atomic_read(&dev->vblank[crtc].count));
return cur_vblank; return cur_vblank;
} }
...@@ -914,12 +872,12 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc) ...@@ -914,12 +872,12 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc)
} while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc)); } while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc));
/* Deal with counter wrap */ /* Deal with counter wrap */
diff = cur_vblank - dev->last_vblank[crtc]; diff = cur_vblank - dev->vblank[crtc].last;
if (cur_vblank < dev->last_vblank[crtc]) { if (cur_vblank < dev->vblank[crtc].last) {
diff += dev->max_vblank_count; diff += dev->max_vblank_count;
DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n", DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
crtc, dev->last_vblank[crtc], cur_vblank, diff); crtc, dev->vblank[crtc].last, cur_vblank, diff);
} }
DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n", DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n",
...@@ -930,12 +888,12 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc) ...@@ -930,12 +888,12 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc)
* reinitialize delayed at next vblank interrupt in that case. * reinitialize delayed at next vblank interrupt in that case.
*/ */
if (rc) { if (rc) {
tslot = atomic_read(&dev->_vblank_count[crtc]) + diff; tslot = atomic_read(&dev->vblank[crtc].count) + diff;
vblanktimestamp(dev, crtc, tslot) = t_vblank; vblanktimestamp(dev, crtc, tslot) = t_vblank;
} }
smp_mb__before_atomic_inc(); smp_mb__before_atomic_inc();
atomic_add(diff, &dev->_vblank_count[crtc]); atomic_add(diff, &dev->vblank[crtc].count);
smp_mb__after_atomic_inc(); smp_mb__after_atomic_inc();
} }
...@@ -957,9 +915,9 @@ int drm_vblank_get(struct drm_device *dev, int crtc) ...@@ -957,9 +915,9 @@ int drm_vblank_get(struct drm_device *dev, int crtc)
spin_lock_irqsave(&dev->vbl_lock, irqflags); spin_lock_irqsave(&dev->vbl_lock, irqflags);
/* Going from 0->1 means we have to enable interrupts again */ /* Going from 0->1 means we have to enable interrupts again */
if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) { if (atomic_add_return(1, &dev->vblank[crtc].refcount) == 1) {
spin_lock_irqsave(&dev->vblank_time_lock, irqflags2); spin_lock_irqsave(&dev->vblank_time_lock, irqflags2);
if (!dev->vblank_enabled[crtc]) { if (!dev->vblank[crtc].enabled) {
/* Enable vblank irqs under vblank_time_lock protection. /* Enable vblank irqs under vblank_time_lock protection.
* All vblank count & timestamp updates are held off * All vblank count & timestamp updates are held off
* until we are done reinitializing master counter and * until we are done reinitializing master counter and
...@@ -970,16 +928,16 @@ int drm_vblank_get(struct drm_device *dev, int crtc) ...@@ -970,16 +928,16 @@ int drm_vblank_get(struct drm_device *dev, int crtc)
DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n",
crtc, ret); crtc, ret);
if (ret) if (ret)
atomic_dec(&dev->vblank_refcount[crtc]); atomic_dec(&dev->vblank[crtc].refcount);
else { else {
dev->vblank_enabled[crtc] = 1; dev->vblank[crtc].enabled = true;
drm_update_vblank_count(dev, crtc); drm_update_vblank_count(dev, crtc);
} }
} }
spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags2); spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags2);
} else { } else {
if (!dev->vblank_enabled[crtc]) { if (!dev->vblank[crtc].enabled) {
atomic_dec(&dev->vblank_refcount[crtc]); atomic_dec(&dev->vblank[crtc].refcount);
ret = -EINVAL; ret = -EINVAL;
} }
} }
...@@ -999,10 +957,10 @@ EXPORT_SYMBOL(drm_vblank_get); ...@@ -999,10 +957,10 @@ EXPORT_SYMBOL(drm_vblank_get);
*/ */
void drm_vblank_put(struct drm_device *dev, int crtc) void drm_vblank_put(struct drm_device *dev, int crtc)
{ {
BUG_ON(atomic_read(&dev->vblank_refcount[crtc]) == 0); BUG_ON(atomic_read(&dev->vblank[crtc].refcount) == 0);
/* Last user schedules interrupt disable */ /* Last user schedules interrupt disable */
if (atomic_dec_and_test(&dev->vblank_refcount[crtc]) && if (atomic_dec_and_test(&dev->vblank[crtc].refcount) &&
(drm_vblank_offdelay > 0)) (drm_vblank_offdelay > 0))
mod_timer(&dev->vblank_disable_timer, mod_timer(&dev->vblank_disable_timer,
jiffies + ((drm_vblank_offdelay * DRM_HZ)/1000)); jiffies + ((drm_vblank_offdelay * DRM_HZ)/1000));
...@@ -1025,7 +983,7 @@ void drm_vblank_off(struct drm_device *dev, int crtc) ...@@ -1025,7 +983,7 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
spin_lock_irqsave(&dev->vbl_lock, irqflags); spin_lock_irqsave(&dev->vbl_lock, irqflags);
vblank_disable_and_save(dev, crtc); vblank_disable_and_save(dev, crtc);
DRM_WAKEUP(&dev->vbl_queue[crtc]); DRM_WAKEUP(&dev->vblank[crtc].queue);
/* Send any queued vblank events, lest the natives grow disquiet */ /* Send any queued vblank events, lest the natives grow disquiet */
seq = drm_vblank_count_and_time(dev, crtc, &now); seq = drm_vblank_count_and_time(dev, crtc, &now);
...@@ -1067,10 +1025,10 @@ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) ...@@ -1067,10 +1025,10 @@ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
* to avoid corrupting the count if multiple, mismatch calls occur), * to avoid corrupting the count if multiple, mismatch calls occur),
* so that interrupts remain enabled in the interim. * so that interrupts remain enabled in the interim.
*/ */
if (!dev->vblank_inmodeset[crtc]) { if (!dev->vblank[crtc].inmodeset) {
dev->vblank_inmodeset[crtc] = 0x1; dev->vblank[crtc].inmodeset = 0x1;
if (drm_vblank_get(dev, crtc) == 0) if (drm_vblank_get(dev, crtc) == 0)
dev->vblank_inmodeset[crtc] |= 0x2; dev->vblank[crtc].inmodeset |= 0x2;
} }
} }
EXPORT_SYMBOL(drm_vblank_pre_modeset); EXPORT_SYMBOL(drm_vblank_pre_modeset);
...@@ -1083,15 +1041,15 @@ void drm_vblank_post_modeset(struct drm_device *dev, int crtc) ...@@ -1083,15 +1041,15 @@ void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
if (!dev->num_crtcs) if (!dev->num_crtcs)
return; return;
if (dev->vblank_inmodeset[crtc]) { if (dev->vblank[crtc].inmodeset) {
spin_lock_irqsave(&dev->vbl_lock, irqflags); spin_lock_irqsave(&dev->vbl_lock, irqflags);
dev->vblank_disable_allowed = 1; dev->vblank_disable_allowed = true;
spin_unlock_irqrestore(&dev->vbl_lock, irqflags); spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
if (dev->vblank_inmodeset[crtc] & 0x2) if (dev->vblank[crtc].inmodeset & 0x2)
drm_vblank_put(dev, crtc); drm_vblank_put(dev, crtc);
dev->vblank_inmodeset[crtc] = 0; dev->vblank[crtc].inmodeset = 0;
} }
} }
EXPORT_SYMBOL(drm_vblank_post_modeset); EXPORT_SYMBOL(drm_vblank_post_modeset);
...@@ -1288,8 +1246,8 @@ int drm_wait_vblank(struct drm_device *dev, void *data, ...@@ -1288,8 +1246,8 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
DRM_DEBUG("waiting on vblank count %d, crtc %d\n", DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
vblwait->request.sequence, crtc); vblwait->request.sequence, crtc);
dev->last_vblank_wait[crtc] = vblwait->request.sequence; dev->vblank[crtc].last_wait = vblwait->request.sequence;
DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ, DRM_WAIT_ON(ret, dev->vblank[crtc].queue, 3 * DRM_HZ,
(((drm_vblank_count(dev, crtc) - (((drm_vblank_count(dev, crtc) -
vblwait->request.sequence) <= (1 << 23)) || vblwait->request.sequence) <= (1 << 23)) ||
!dev->irq_enabled)); !dev->irq_enabled));
...@@ -1367,7 +1325,7 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc) ...@@ -1367,7 +1325,7 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc)
spin_lock_irqsave(&dev->vblank_time_lock, irqflags); spin_lock_irqsave(&dev->vblank_time_lock, irqflags);
/* Vblank irq handling disabled. Nothing to do. */ /* Vblank irq handling disabled. Nothing to do. */
if (!dev->vblank_enabled[crtc]) { if (!dev->vblank[crtc].enabled) {
spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
return false; return false;
} }
...@@ -1377,7 +1335,7 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc) ...@@ -1377,7 +1335,7 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc)
*/ */
/* Get current timestamp and count. */ /* Get current timestamp and count. */
vblcount = atomic_read(&dev->_vblank_count[crtc]); vblcount = atomic_read(&dev->vblank[crtc].count);
drm_get_last_vbltimestamp(dev, crtc, &tvblank, DRM_CALLED_FROM_VBLIRQ); drm_get_last_vbltimestamp(dev, crtc, &tvblank, DRM_CALLED_FROM_VBLIRQ);
/* Compute time difference to timestamp of last vblank */ /* Compute time difference to timestamp of last vblank */
...@@ -1401,14 +1359,14 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc) ...@@ -1401,14 +1359,14 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc)
* the timestamp computed above. * the timestamp computed above.
*/ */
smp_mb__before_atomic_inc(); smp_mb__before_atomic_inc();
atomic_inc(&dev->_vblank_count[crtc]); atomic_inc(&dev->vblank[crtc].count);
smp_mb__after_atomic_inc(); smp_mb__after_atomic_inc();
} else { } else {
DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n", DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n",
crtc, (int) diff_ns); crtc, (int) diff_ns);
} }
DRM_WAKEUP(&dev->vbl_queue[crtc]); DRM_WAKEUP(&dev->vblank[crtc].queue);
drm_handle_vblank_events(dev, crtc); drm_handle_vblank_events(dev, crtc);
spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
......
...@@ -86,7 +86,6 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) ...@@ -86,7 +86,6 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
if (drm_lock_take(&master->lock, lock->context)) { if (drm_lock_take(&master->lock, lock->context)) {
master->lock.file_priv = file_priv; master->lock.file_priv = file_priv;
master->lock.lock_time = jiffies; master->lock.lock_time = jiffies;
atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
break; /* Got lock */ break; /* Got lock */
} }
...@@ -157,8 +156,6 @@ int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv) ...@@ -157,8 +156,6 @@ int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv)
return -EINVAL; return -EINVAL;
} }
atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]);
if (drm_lock_free(&master->lock, lock->context)) { if (drm_lock_free(&master->lock, lock->context)) {
/* FIXME: Should really bail out here. */ /* FIXME: Should really bail out here. */
} }
......
...@@ -322,83 +322,36 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, ...@@ -322,83 +322,36 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
DRM_DEBUG("\n"); DRM_DEBUG("\n");
dev = kzalloc(sizeof(*dev), GFP_KERNEL); dev = drm_dev_alloc(driver, &pdev->dev);
if (!dev) if (!dev)
return -ENOMEM; return -ENOMEM;
ret = pci_enable_device(pdev); ret = pci_enable_device(pdev);
if (ret) if (ret)
goto err_g1; goto err_free;
dev->pdev = pdev; dev->pdev = pdev;
dev->dev = &pdev->dev;
dev->pci_device = pdev->device;
dev->pci_vendor = pdev->vendor;
#ifdef __alpha__ #ifdef __alpha__
dev->hose = pdev->sysdata; dev->hose = pdev->sysdata;
#endif #endif
mutex_lock(&drm_global_mutex); if (drm_core_check_feature(dev, DRIVER_MODESET))
if ((ret = drm_fill_in_dev(dev, ent, driver))) {
printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
goto err_g2;
}
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
pci_set_drvdata(pdev, dev); pci_set_drvdata(pdev, dev);
ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
if (ret)
goto err_g2;
}
if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) {
ret = drm_get_minor(dev, &dev->render, DRM_MINOR_RENDER);
if (ret)
goto err_g21;
}
if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY)))
goto err_g3;
if (dev->driver->load) { ret = drm_dev_register(dev, ent->driver_data);
ret = dev->driver->load(dev, ent->driver_data);
if (ret) if (ret)
goto err_g4; goto err_pci;
}
/* setup the grouping for the legacy output */
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
ret = drm_mode_group_init_legacy_group(dev,
&dev->primary->mode_group);
if (ret)
goto err_g4;
}
list_add_tail(&dev->driver_item, &driver->device_list);
DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
driver->name, driver->major, driver->minor, driver->patchlevel, driver->name, driver->major, driver->minor, driver->patchlevel,
driver->date, pci_name(pdev), dev->primary->index); driver->date, pci_name(pdev), dev->primary->index);
mutex_unlock(&drm_global_mutex);
return 0; return 0;
err_g4: err_pci:
drm_put_minor(&dev->primary);
err_g3:
if (dev->render)
drm_put_minor(&dev->render);
err_g21:
if (drm_core_check_feature(dev, DRIVER_MODESET))
drm_put_minor(&dev->control);
err_g2:
pci_disable_device(pdev); pci_disable_device(pdev);
err_g1: err_free:
kfree(dev); drm_dev_free(dev);
mutex_unlock(&drm_global_mutex);
return ret; return ret;
} }
EXPORT_SYMBOL(drm_get_pci_dev); EXPORT_SYMBOL(drm_get_pci_dev);
......
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