aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/Kconfig7
-rw-r--r--drivers/acpi/Makefile2
-rw-r--r--drivers/acpi/battery.c25
-rw-r--r--drivers/acpi/ec.c9
-rw-r--r--drivers/base/base.h2
-rw-r--r--drivers/base/dd.c17
-rw-r--r--drivers/base/power/main.c3
-rw-r--r--drivers/base/sys.c7
-rw-r--r--drivers/block/ataflop.c4
-rw-r--r--drivers/char/scc.h2
-rw-r--r--drivers/char/sx.c5
-rw-r--r--drivers/gpu/drm/drm_crtc.c3
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c21
-rw-r--r--drivers/gpu/drm/drm_fops.c3
-rw-r--r--drivers/gpu/drm/drm_gem.c79
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c2
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c25
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h3
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c182
-rw-r--r--drivers/gpu/drm/i915/i915_gem_tiling.c6
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c8
-rw-r--r--drivers/gpu/drm/i915/intel_display.c161
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c8
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c2
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c2
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_cp.c21
-rw-r--r--drivers/parport/parport_atari.c6
-rw-r--r--drivers/platform/x86/fujitsu-laptop.c25
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c15
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.h2
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c1
-rw-r--r--drivers/scsi/libiscsi.c3
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c1
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c13
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h5
-rw-r--r--drivers/scsi/qla2xxx/qla_devtbl.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h9
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c7
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c58
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c40
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c12
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c16
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h2
-rw-r--r--drivers/scsi/scsi_scan.c1
-rw-r--r--drivers/scsi/sg.c2
-rw-r--r--drivers/serial/8250.c15
-rw-r--r--drivers/serial/8250_pci.c36
-rw-r--r--drivers/video/atafb.c22
-rw-r--r--drivers/video/aty/aty128fb.c1
-rw-r--r--drivers/xen/manage.c8
53 files changed, 617 insertions, 300 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index a7799a99f2d..8a851d0f438 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -254,13 +254,6 @@ config ACPI_PCI_SLOT
help you correlate PCI bus addresses with the physical geography
of your slots. If you are unsure, say N.
-config ACPI_SYSTEM
- bool
- default y
- help
- This driver will enable your system to shut down using ACPI, and
- dump your ACPI DSDT table using /proc/acpi/dsdt.
-
config X86_PM_TIMER
bool "Power Management Timer Support" if EMBEDDED
depends on X86
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 65d90c720b5..b130ea0d075 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -52,7 +52,7 @@ obj-$(CONFIG_ACPI_PROCESSOR) += processor.o
obj-$(CONFIG_ACPI_CONTAINER) += container.o
obj-$(CONFIG_ACPI_THERMAL) += thermal.o
obj-y += power.o
-obj-$(CONFIG_ACPI_SYSTEM) += system.o event.o
+obj-y += system.o event.o
obj-$(CONFIG_ACPI_DEBUG) += debug.o
obj-$(CONFIG_ACPI_NUMA) += numa.o
obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 65132f92045..69cbc57c2d1 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -138,6 +138,29 @@ static int acpi_battery_technology(struct acpi_battery *battery)
static int acpi_battery_get_state(struct acpi_battery *battery);
+static int acpi_battery_is_charged(struct acpi_battery *battery)
+{
+ /* either charging or discharging */
+ if (battery->state != 0)
+ return 0;
+
+ /* battery not reporting charge */
+ if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN ||
+ battery->capacity_now == 0)
+ return 0;
+
+ /* good batteries update full_charge as the batteries degrade */
+ if (battery->full_charge_capacity == battery->capacity_now)
+ return 1;
+
+ /* fallback to using design values for broken batteries */
+ if (battery->design_capacity == battery->capacity_now)
+ return 1;
+
+ /* we don't do any sort of metric based on percentages */
+ return 0;
+}
+
static int acpi_battery_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
@@ -155,7 +178,7 @@ static int acpi_battery_get_property(struct power_supply *psy,
val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
else if (battery->state & 0x02)
val->intval = POWER_SUPPLY_STATUS_CHARGING;
- else if (battery->state == 0)
+ else if (acpi_battery_is_charged(battery))
val->intval = POWER_SUPPLY_STATUS_FULL;
else
val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 5c2f5d343be..2fe15060dcd 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -120,6 +120,8 @@ static struct acpi_ec {
spinlock_t curr_lock;
} *boot_ec, *first_ec;
+static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */
+
/* --------------------------------------------------------------------------
Transaction Management
-------------------------------------------------------------------------- */
@@ -259,6 +261,8 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
acpi_disable_gpe(NULL, ec->gpe);
}
+ if (EC_FLAGS_MSI)
+ udelay(ACPI_EC_DELAY);
/* start transaction */
spin_lock_irqsave(&ec->curr_lock, tmp);
/* following two actions should be kept atomic */
@@ -967,6 +971,11 @@ int __init acpi_ec_ecdt_probe(void)
/*
* Generate a boot ec context
*/
+ if (dmi_name_in_vendors("Micro-Star") ||
+ dmi_name_in_vendors("Notebook")) {
+ pr_info(PREFIX "Enabling special treatment for EC from MSI.\n");
+ EC_FLAGS_MSI = 1;
+ }
status = acpi_get_table(ACPI_SIG_ECDT, 1,
(struct acpi_table_header **)&ecdt_ptr);
if (ACPI_SUCCESS(status)) {
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 0a5f055dffb..9f50f1b545d 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -88,8 +88,6 @@ extern void driver_detach(struct device_driver *drv);
extern int driver_probe_device(struct device_driver *drv, struct device *dev);
extern void sysdev_shutdown(void);
-extern int sysdev_suspend(pm_message_t state);
-extern int sysdev_resume(void);
extern char *make_class_name(const char *name, struct kobject *kobj);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 315bed8d5e7..13523123910 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -18,9 +18,11 @@
*/
#include <linux/device.h>
+#include <linux/delay.h>
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/wait.h>
+#include <linux/async.h>
#include "base.h"
#include "power/power.h"
@@ -168,6 +170,21 @@ int driver_probe_done(void)
}
/**
+ * wait_for_device_probe
+ * Wait for device probing to be completed.
+ *
+ * Note: this function polls at 100 msec intervals.
+ */
+int wait_for_device_probe(void)
+{
+ /* wait for the known devices to complete their probing */
+ while (driver_probe_done() != 0)
+ msleep(100);
+ async_synchronize_full();
+ return 0;
+}
+
+/**
* driver_probe_device - attempt to bind device & driver together
* @drv: driver to bind a device to
* @dev: device to try to bind to the driver
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 670c9d6c140..2d14f4ae6c0 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -333,7 +333,6 @@ static void dpm_power_up(pm_message_t state)
*/
void device_power_up(pm_message_t state)
{
- sysdev_resume();
dpm_power_up(state);
}
EXPORT_SYMBOL_GPL(device_power_up);
@@ -577,8 +576,6 @@ int device_power_down(pm_message_t state)
}
dev->power.status = DPM_OFF_IRQ;
}
- if (!error)
- error = sysdev_suspend(state);
if (error)
dpm_power_up(resume_event(state));
return error;
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index c98c31ec2f7..b428c8c4bc6 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -303,7 +303,6 @@ void sysdev_unregister(struct sys_device * sysdev)
* is guaranteed by virtue of the fact that child devices are registered
* after their parents.
*/
-
void sysdev_shutdown(void)
{
struct sysdev_class * cls;
@@ -363,7 +362,6 @@ static void __sysdev_resume(struct sys_device *dev)
* This is only called by the device PM core, so we let them handle
* all synchronization.
*/
-
int sysdev_suspend(pm_message_t state)
{
struct sysdev_class * cls;
@@ -432,7 +430,7 @@ aux_driver:
}
return ret;
}
-
+EXPORT_SYMBOL_GPL(sysdev_suspend);
/**
* sysdev_resume - Bring system devices back to life.
@@ -442,7 +440,6 @@ aux_driver:
*
* Note: Interrupts are disabled when called.
*/
-
int sysdev_resume(void)
{
struct sysdev_class * cls;
@@ -463,7 +460,7 @@ int sysdev_resume(void)
}
return 0;
}
-
+EXPORT_SYMBOL_GPL(sysdev_resume);
int __init system_bus_init(void)
{
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index 69e1df7dfa1..4234c11c1e4 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -1730,7 +1730,7 @@ static int __init fd_test_drive_present( int drive )
timeout = jiffies + 2*HZ+HZ/2;
while (time_before(jiffies, timeout))
- if (!(mfp.par_dt_reg & 0x20))
+ if (!(st_mfp.par_dt_reg & 0x20))
break;
status = FDC_READ( FDCREG_STATUS );
@@ -1747,7 +1747,7 @@ static int __init fd_test_drive_present( int drive )
/* dummy seek command to make WP bit accessible */
FDC_WRITE( FDCREG_DATA, 0 );
FDC_WRITE( FDCREG_CMD, FDCCMD_SEEK );
- while( mfp.par_dt_reg & 0x20 )
+ while( st_mfp.par_dt_reg & 0x20 )
;
status = FDC_READ( FDCREG_STATUS );
}
diff --git a/drivers/char/scc.h b/drivers/char/scc.h
index 93998f5baff..341b1142bea 100644
--- a/drivers/char/scc.h
+++ b/drivers/char/scc.h
@@ -387,7 +387,7 @@ struct scc_port {
/* The SCC needs 3.5 PCLK cycles recovery time between to register
* accesses. PCLK runs with 8 MHz on an Atari, so this delay is 3.5 *
* 125 ns = 437.5 ns. This is too short for udelay().
- * 10/16/95: A tstb mfp.par_dt_reg takes 600ns (sure?) and thus should be
+ * 10/16/95: A tstb st_mfp.par_dt_reg takes 600ns (sure?) and thus should be
* quite right
*/
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index f146e90404f..518f2a25d91 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -1746,9 +1746,10 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd,
sx_dprintk(SX_DEBUG_FIRMWARE, "returning type= %ld\n", rc);
break;
case SXIO_DO_RAMTEST:
- if (sx_initialized) /* Already initialized: better not ramtest the board. */
+ if (sx_initialized) { /* Already initialized: better not ramtest the board. */
rc = -EPERM;
break;
+ }
if (IS_SX_BOARD(board)) {
rc = do_memtest(board, 0, 0x7000);
if (!rc)
@@ -1788,7 +1789,7 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd,
nbytes - i : SX_CHUNK_SIZE)) {
kfree(tmp);
rc = -EFAULT;
- break;
+ goto out;
}
memcpy_toio(board->base2 + offset + i, tmp,
(i + SX_CHUNK_SIZE > nbytes) ?
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index bfce0992fef..94a76887173 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1741,9 +1741,8 @@ out:
* RETURNS:
* Zero on success, errno on failure.
*/
-void drm_fb_release(struct file *filp)
+void drm_fb_release(struct drm_file *priv)
{
- struct drm_file *priv = filp->private_data;
struct drm_device *dev = priv->minor->dev;
struct drm_framebuffer *fb, *tfb;
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 964c5eb1fad..733028b4d45 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -512,8 +512,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
if (drm_mode_equal(&saved_mode, &crtc->mode)) {
if (saved_x != crtc->x || saved_y != crtc->y ||
depth_changed || bpp_changed) {
- crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y,
- old_fb);
+ ret = !crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y,
+ old_fb);
goto done;
}
}
@@ -552,7 +552,9 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
/* Set up the DPLL and any encoders state that needs to adjust or depend
* on the DPLL.
*/
- crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
+ ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
+ if (!ret)
+ goto done;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
@@ -752,6 +754,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
set->x, set->y,
old_fb)) {
+ DRM_ERROR("failed to set mode on crtc %p\n",
+ set->crtc);
ret = -EINVAL;
goto fail_set_mode;
}
@@ -765,7 +769,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
old_fb = set->crtc->fb;
if (set->crtc->fb != set->fb)
set->crtc->fb = set->fb;
- crtc_funcs->mode_set_base(set->crtc, set->x, set->y, old_fb);
+ ret = crtc_funcs->mode_set_base(set->crtc,
+ set->x, set->y, old_fb);
+ if (ret != 0)
+ goto fail_set_mode;
}
kfree(save_encoders);
@@ -775,8 +782,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
fail_set_mode:
set->crtc->enabled = save_enabled;
count = 0;
- list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ if (!connector->encoder)
+ continue;
+
connector->encoder->crtc = save_crtcs[count++];
+ }
fail_no_encoder:
kfree(save_crtcs);
count = 0;
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index b06a5371585..6c020fe5431 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -457,6 +457,9 @@ int drm_release(struct inode *inode, struct file *filp)
if (dev->driver->driver_features & DRIVER_GEM)
drm_gem_release(dev, file_priv);
+ if (dev->driver->driver_features & DRIVER_MODESET)
+ drm_fb_release(file_priv);
+
mutex_lock(&dev->ctxlist_mutex);
if (!list_empty(&dev->ctxlist)) {
struct drm_ctx_list *pos, *n;
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 6915fb82d0b..88d3368ffdd 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -104,8 +104,8 @@ drm_gem_init(struct drm_device *dev)
if (drm_mm_init(&mm->offset_manager, DRM_FILE_PAGE_OFFSET_START,
DRM_FILE_PAGE_OFFSET_SIZE)) {
- drm_free(mm, sizeof(struct drm_gem_mm), DRM_MEM_MM);
drm_ht_remove(&mm->offset_hash);
+ drm_free(mm, sizeof(struct drm_gem_mm), DRM_MEM_MM);
return -ENOMEM;
}
@@ -295,35 +295,37 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data,
return -EBADF;
again:
- if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0)
- return -ENOMEM;
+ if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0) {
+ ret = -ENOMEM;
+ goto err;
+ }
spin_lock(&dev->object_name_lock);
- if (obj->name) {
- args->name = obj->name;
+ if (!obj->name) {
+ ret = idr_get_new_above(&dev->object_name_idr, obj, 1,
+ &obj->name);
+ args->name = (uint64_t) obj->name;
spin_unlock(&dev->object_name_lock);
- return 0;
- }
- ret = idr_get_new_above(&dev->object_name_idr, obj, 1,
- &obj->name);
- spin_unlock(&dev->object_name_lock);
- if (ret == -EAGAIN)
- goto again;
- if (ret != 0) {
- mutex_lock(&dev->struct_mutex);
- drm_gem_object_unreference(obj);
- mutex_unlock(&dev->struct_mutex);
- return ret;
- }
+ if (ret == -EAGAIN)
+ goto again;
- /*
- * Leave the reference from the lookup around as the
- * name table now holds one
- */
- args->name = (uint64_t) obj->name;
+ if (ret != 0)
+ goto err;
- return 0;
+ /* Allocate a reference for the name table. */
+ drm_gem_object_reference(obj);
+ } else {
+ args->name = (uint64_t) obj->name;
+ spin_unlock(&dev->object_name_lock);
+ ret = 0;
+ }
+
+err:
+ mutex_lock(&dev->struct_mutex);
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
}
/**
@@ -448,6 +450,7 @@ drm_gem_object_handle_free(struct kref *kref)
spin_lock(&dev->object_name_lock);
if (obj->name) {
idr_remove(&dev->object_name_idr, obj->name);
+ obj->name = 0;
spin_unlock(&dev->object_name_lock);
/*
* The object name held a reference to this object, drop
@@ -460,6 +463,26 @@ drm_gem_object_handle_free(struct kref *kref)
}
EXPORT_SYMBOL(drm_gem_object_handle_free);
+void drm_gem_vm_open(struct vm_area_struct *vma)
+{
+ struct drm_gem_object *obj = vma->vm_private_data;
+
+ drm_gem_object_reference(obj);
+}
+EXPORT_SYMBOL(drm_gem_vm_open);
+
+void drm_gem_vm_close(struct vm_area_struct *vma)
+{
+ struct drm_gem_object *obj = vma->vm_private_data;
+ struct drm_device *dev = obj->dev;
+
+ mutex_lock(&dev->struct_mutex);
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+}
+EXPORT_SYMBOL(drm_gem_vm_close);
+
+
/**
* drm_gem_mmap - memory map routine for GEM objects
* @filp: DRM file pointer
@@ -521,6 +544,14 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
#endif
vma->vm_page_prot = __pgprot(prot);
+ /* Take a ref for this mapping of the object, so that the fault
+ * handler can dereference the mmap offset's pointer to the object.
+ * This reference is cleaned up by the corresponding vm_close
+ * (which should happen whether the vma was created by this call, or
+ * by a vm_open due to mremap or partial unmap or whatever).
+ */
+ drm_gem_object_reference(obj);
+
vma->vm_file = filp; /* Needed for drm_vm_open() */
drm_vm_open_locked(vma);
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 81f1cff56fd..2d797ffe813 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -202,7 +202,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
dev_priv->ring.map.flags = 0;
dev_priv->ring.map.mtrr = 0;
- drm_core_ioremap(&dev_priv->ring.map, dev);
+ drm_core_ioremap_wc(&dev_priv->ring.map, dev);
if (dev_priv->ring.map.handle == NULL) {
i915_dma_cleanup(dev);
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index aac12ee31a4..0692622ee2b 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -27,6 +27,7 @@
*
*/
+#include <linux/device.h>
#include "drmP.h"
#include "drm.h"
#include "i915_drm.h"
@@ -66,6 +67,12 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
i915_save_state(dev);
+ /* If KMS is active, we do the leavevt stuff here */
+ if (drm_core_check_feature(dev, DRIVER_MODESET) && i915_gem_idle(dev)) {
+ dev_err(&dev->pdev->dev, "GEM idle failed, aborting suspend\n");
+ return -EBUSY;
+ }
+
intel_opregion_free(dev);
if (state.event == PM_EVENT_SUSPEND) {
@@ -79,6 +86,9 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
static int i915_resume(struct drm_device *dev)
{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int ret = 0;
+
pci_set_power_state(dev->pdev, PCI_D0);
pci_restore_state(dev->pdev);
if (pci_enable_device(dev->pdev))
@@ -89,11 +99,24 @@ static int i915_resume(struct drm_device *dev)
intel_opregion_init(dev);
- return 0;
+ /* KMS EnterVT equivalent */
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ mutex_lock(&dev->struct_mutex);
+ dev_priv->mm.suspended = 0;
+
+ ret = i915_gem_init_ringbuffer(dev);
+ if (ret != 0)
+ ret = -1;
+ mutex_unlock(&dev->struct_mutex);
+ }
+
+ return ret;
}
static struct vm_operations_struct i915_gem_vm_ops = {
.fault = i915_gem_fault,
+ .open = drm_gem_vm_open,
+ .close = drm_gem_vm_close,
};
static struct drm_driver driver = {
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 7325363164f..17fa40858d2 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -184,6 +184,8 @@ typedef struct drm_i915_private {
unsigned int lvds_dither:1;
unsigned int lvds_vbt:1;
unsigned int int_crt_support:1;
+ unsigned int lvds_use_ssc:1;
+ int lvds_ssc_freq;
struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */
int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
@@ -616,6 +618,7 @@ int i915_gem_init_ringbuffer(struct drm_device *dev);
void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
int i915_gem_do_init(struct drm_device *dev, unsigned long start,
unsigned long end);
+int i915_gem_idle(struct drm_device *dev);
int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj,
int write);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 81857665409..25b337438ca 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -34,10 +34,6 @@
#define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT))
-static void
-i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
- uint32_t read_domains,
- uint32_t write_domain);
static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj);
static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj);
@@ -607,8 +603,6 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
case -EAGAIN:
return VM_FAULT_OOM;
case -EFAULT:
- case -EBUSY:
- DRM_ERROR("can't insert pfn?? fault or busy...\n");
return VM_FAULT_SIGBUS;
default:
return VM_FAULT_NOPAGE;
@@ -684,6 +678,30 @@ out_free_list:
return ret;
}
+static void
+i915_gem_free_mmap_offset(struct drm_gem_object *obj)
+{
+ struct drm_device *dev = obj->dev;
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_gem_mm *mm = dev->mm_private;
+ struct drm_map_list *list;
+
+ list = &obj->map_list;
+ drm_ht_remove_item(&mm->offset_hash, &list->hash);
+
+ if (list->file_offset_node) {
+ drm_mm_put_block(list->file_offset_node);
+ list->file_offset_node = NULL;
+ }
+
+ if (list->map) {
+ drm_free(list->map, sizeof(struct drm_map), DRM_MEM_DRIVER);
+ list->map = NULL;
+ }
+
+ obj_priv->mmap_offset = 0;
+}
+
/**
* i915_gem_get_gtt_alignment - return required GTT alignment for an object
* @obj: object to check
@@ -758,8 +776,11 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
if (!obj_priv->mmap_offset) {
ret = i915_gem_create_mmap_offset(obj);
- if (ret)
+ if (ret) {
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
return ret;
+ }
}
args->offset = obj_priv->mmap_offset;
@@ -1996,30 +2017,28 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write)
* drm_agp_chipset_flush
*/
static void
-i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
- uint32_t read_domains,
- uint32_t write_domain)
+i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
struct drm_i915_gem_object *obj_priv = obj->driver_private;
uint32_t invalidate_d