summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/ec.c6
-rw-r--r--drivers/acpi/executer/exregion.c5
-rw-r--r--drivers/acpi/fan.c30
-rw-r--r--drivers/acpi/processor_core.c39
-rw-r--r--drivers/acpi/utils.c18
-rw-r--r--drivers/acpi/video.c3
-rw-r--r--drivers/ata/libata-core.c380
-rw-r--r--drivers/ata/libata-eh.c8
-rw-r--r--drivers/ata/libata-scsi.c2
-rw-r--r--drivers/ata/libata.h1
-rw-r--r--drivers/ata/pata_legacy.c44
-rw-r--r--drivers/ata/sata_mv.c9
-rw-r--r--drivers/base/power/main.c2
-rw-r--r--drivers/char/agp/amd-k7-agp.c9
-rw-r--r--drivers/char/agp/ati-agp.c16
-rw-r--r--drivers/char/agp/generic.c9
-rw-r--r--drivers/char/agp/sis-agp.c47
-rw-r--r--drivers/char/agp/sworks-agp.c18
-rw-r--r--drivers/char/drm/drmP.h2
-rw-r--r--drivers/char/drm/drm_pciids.h3
-rw-r--r--drivers/char/drm/drm_sysfs.c2
-rw-r--r--drivers/char/drm/drm_vm.c125
-rw-r--r--drivers/char/drm/i915_dma.c5
-rw-r--r--drivers/char/drm/i915_drv.c51
-rw-r--r--drivers/char/drm/i915_drv.h17
-rw-r--r--drivers/char/drm/radeon_cp.c81
-rw-r--r--drivers/char/drm/radeon_drv.h38
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mr.c2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c10
-rw-r--r--drivers/md/dm-raid1.c7
-rw-r--r--drivers/misc/Kconfig17
-rw-r--r--drivers/misc/acer-wmi.c9
-rw-r--r--drivers/misc/intel_menlow.c11
-rw-r--r--drivers/misc/thinkpad_acpi.c123
-rw-r--r--drivers/pci/pci-acpi.c3
-rw-r--r--drivers/thermal/thermal.c39
36 files changed, 960 insertions, 231 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 7222a18..caf873c 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -943,7 +943,11 @@ int __init acpi_ec_ecdt_probe(void)
boot_ec->command_addr = ecdt_ptr->control.address;
boot_ec->data_addr = ecdt_ptr->data.address;
boot_ec->gpe = ecdt_ptr->gpe;
- boot_ec->handle = ACPI_ROOT_OBJECT;
+ if (ACPI_FAILURE(acpi_get_handle(NULL, ecdt_ptr->id,
+ &boot_ec->handle))) {
+ pr_info("Failed to locate handle for boot EC\n");
+ boot_ec->handle = ACPI_ROOT_OBJECT;
+ }
} else {
/* This workaround is needed only on some broken machines,
* which require early EC, but fail to provide ECDT */
diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c
index 2e9ce94..3f51b7e 100644
--- a/drivers/acpi/executer/exregion.c
+++ b/drivers/acpi/executer/exregion.c
@@ -338,6 +338,7 @@ acpi_ex_pci_config_space_handler(u32 function,
acpi_status status = AE_OK;
struct acpi_pci_id *pci_id;
u16 pci_register;
+ u32 value32;
ACPI_FUNCTION_TRACE(ex_pci_config_space_handler);
@@ -364,9 +365,9 @@ acpi_ex_pci_config_space_handler(u32 function,
switch (function) {
case ACPI_READ:
- *value = 0;
status = acpi_os_read_pci_configuration(pci_id, pci_register,
- value, bit_width);
+ &value32, bit_width);
+ *value = value32;
break;
case ACPI_WRITE:
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index 48cb705..c8e3cba 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -256,22 +256,28 @@ static int acpi_fan_add(struct acpi_device *device)
cdev = thermal_cooling_device_register("Fan", device,
&fan_cooling_ops);
- if (cdev)
+ if (IS_ERR(cdev)) {
+ result = PTR_ERR(cdev);
+ goto end;
+ }
+ if (cdev) {
printk(KERN_INFO PREFIX
"%s is registered as cooling_device%d\n",
device->dev.bus_id, cdev->id);
- else
- goto end;
- acpi_driver_data(device) = cdev;
- result = sysfs_create_link(&device->dev.kobj, &cdev->device.kobj,
- "thermal_cooling");
- if (result)
- return result;
- result = sysfs_create_link(&cdev->device.kobj, &device->dev.kobj,
- "device");
- if (result)
- return result;
+ acpi_driver_data(device) = cdev;
+ result = sysfs_create_link(&device->dev.kobj,
+ &cdev->device.kobj,
+ "thermal_cooling");
+ if (result)
+ return result;
+
+ result = sysfs_create_link(&cdev->device.kobj,
+ &device->dev.kobj,
+ "device");
+ if (result)
+ return result;
+ }
result = acpi_fan_add_fs(device);
if (result)
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 75ccf5d..a3cc8a9 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -670,21 +670,26 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
pr->cdev = thermal_cooling_device_register("Processor", device,
&processor_cooling_ops);
- if (pr->cdev)
+ if (IS_ERR(pr->cdev)) {
+ result = PTR_ERR(pr->cdev);
+ goto end;
+ }
+ if (pr->cdev) {
printk(KERN_INFO PREFIX
"%s is registered as cooling_device%d\n",
device->dev.bus_id, pr->cdev->id);
- else
- goto end;
- result = sysfs_create_link(&device->dev.kobj, &pr->cdev->device.kobj,
- "thermal_cooling");
- if (result)
- return result;
- result = sysfs_create_link(&pr->cdev->device.kobj, &device->dev.kobj,
- "device");
- if (result)
- return result;
+ result = sysfs_create_link(&device->dev.kobj,
+ &pr->cdev->device.kobj,
+ "thermal_cooling");
+ if (result)
+ return result;
+ result = sysfs_create_link(&pr->cdev->device.kobj,
+ &device->dev.kobj,
+ "device");
+ if (result)
+ return result;
+ }
if (pr->flags.throttling) {
printk(KERN_INFO PREFIX "%s [%s] (supports",
@@ -809,10 +814,12 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
acpi_processor_remove_fs(device);
- sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
- sysfs_remove_link(&pr->cdev->device.kobj, "device");
- thermal_cooling_device_unregister(pr->cdev);
- pr->cdev = NULL;
+ if (pr->cdev) {
+ sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
+ sysfs_remove_link(&pr->cdev->device.kobj, "device");
+ thermal_cooling_device_unregister(pr->cdev);
+ pr->cdev = NULL;
+ }
processors[pr->id] = NULL;
@@ -826,8 +833,6 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
* Acpi processor hotplug support *
****************************************************************************/
-static int is_processor_present(acpi_handle handle);
-
static int is_processor_present(acpi_handle handle)
{
acpi_status status;
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index 34f1575..eba55b7 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -36,16 +36,20 @@ ACPI_MODULE_NAME("utils");
/* --------------------------------------------------------------------------
Object Evaluation Helpers
-------------------------------------------------------------------------- */
+static void
+acpi_util_eval_error(acpi_handle h, acpi_string p, acpi_status s)
+{
#ifdef ACPI_DEBUG_OUTPUT
-#define acpi_util_eval_error(h,p,s) {\
- char prefix[80] = {'\0'};\
- struct acpi_buffer buffer = {sizeof(prefix), prefix};\
- acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);\
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate [%s.%s]: %s\n",\
- (char *) prefix, p, acpi_format_exception(s))); }
+ char prefix[80] = {'\0'};
+ struct acpi_buffer buffer = {sizeof(prefix), prefix};
+ acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate [%s.%s]: %s\n",
+ (char *) prefix, p, acpi_format_exception(s)));
#else
-#define acpi_util_eval_error(h,p,s)
+ return;
#endif
+}
+
acpi_status
acpi_extract_package(union acpi_object *package,
struct acpi_buffer *format, struct acpi_buffer *buffer)
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 7f714fa..12cce69 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -731,6 +731,9 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
device->cdev = thermal_cooling_device_register("LCD",
device->dev, &video_cooling_ops);
+ if (IS_ERR(device->cdev))
+ return;
+
if (device->cdev) {
printk(KERN_INFO PREFIX
"%s is registered as cooling_device%d\n",
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index def3682..60d1bb5 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -87,6 +87,28 @@ static struct workqueue_struct *ata_wq;
struct workqueue_struct *ata_aux_wq;
+struct ata_force_param {
+ const char *name;
+ unsigned int cbl;
+ int spd_limit;
+ unsigned long xfer_mask;
+ unsigned int horkage_on;
+ unsigned int horkage_off;
+};
+
+struct ata_force_ent {
+ int port;
+ int device;
+ struct ata_force_param param;
+};
+
+static struct ata_force_ent *ata_force_tbl;
+static int ata_force_tbl_size;
+
+static char ata_force_param_buf[PAGE_SIZE] __initdata;
+module_param_string(force, ata_force_param_buf, sizeof(ata_force_param_buf), 0444);
+MODULE_PARM_DESC(force, "Force ATA configurations including cable type, link speed and transfer mode (see Documentation/kernel-parameters.txt for details)");
+
int atapi_enabled = 1;
module_param(atapi_enabled, int, 0444);
MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)");
@@ -130,6 +152,179 @@ MODULE_VERSION(DRV_VERSION);
/**
+ * ata_force_cbl - force cable type according to libata.force
+ * @link: ATA link of interest
+ *
+ * Force cable type according to libata.force and whine about it.
+ * The last entry which has matching port number is used, so it
+ * can be specified as part of device force parameters. For
+ * example, both "a:40c,1.00:udma4" and "1.00:40c,udma4" have the
+ * same effect.
+ *
+ * LOCKING:
+ * EH context.
+ */
+void ata_force_cbl(struct ata_port *ap)
+{
+ int i;
+
+ for (i = ata_force_tbl_size - 1; i >= 0; i--) {
+ const struct ata_force_ent *fe = &ata_force_tbl[i];
+
+ if (fe->port != -1 && fe->port != ap->print_id)
+ continue;
+
+ if (fe->param.cbl == ATA_CBL_NONE)
+ continue;
+
+ ap->cbl = fe->param.cbl;
+ ata_port_printk(ap, KERN_NOTICE,
+ "FORCE: cable set to %s\n", fe->param.name);
+ return;
+ }
+}
+
+/**
+ * ata_force_spd_limit - force SATA spd limit according to libata.force
+ * @link: ATA link of interest
+ *
+ * Force SATA spd limit according to libata.force and whine about
+ * it. When only the port part is specified (e.g. 1:), the limit
+ * applies to all links connected to both the host link and all
+ * fan-out ports connected via PMP. If the device part is
+ * specified as 0 (e.g. 1.00:), it specifies the first fan-out
+ * link not the host link. Device number 15 always points to the
+ * host link whether PMP is attached or not.
+ *
+ * LOCKING:
+ * EH context.
+ */
+static void ata_force_spd_limit(struct ata_link *link)
+{
+ int linkno, i;
+
+ if (ata_is_host_link(link))
+ linkno = 15;
+ else
+ linkno = link->pmp;
+
+ for (i = ata_force_tbl_size - 1; i >= 0; i--) {
+ const struct ata_force_ent *fe = &ata_force_tbl[i];
+
+ if (fe->port != -1 && fe->port != link->ap->print_id)
+ continue;
+
+ if (fe->device != -1 && fe->device != linkno)
+ continue;
+
+ if (!fe->param.spd_limit)
+ continue;
+
+ link->hw_sata_spd_limit = (1 << fe->param.spd_limit) - 1;
+ ata_link_printk(link, KERN_NOTICE,
+ "FORCE: PHY spd limit set to %s\n", fe->param.name);
+ return;
+ }
+}
+
+/**
+ * ata_force_xfermask - force xfermask according to libata.force
+ * @dev: ATA device of interest
+ *
+ * Force xfer_mask according to libata.force and whine about it.
+ * For consistency with link selection, device number 15 selects
+ * the first device connected to the host link.
+ *
+ * LOCKING:
+ * EH context.
+ */
+static void ata_force_xfermask(struct ata_device *dev)
+{
+ int devno = dev->link->pmp + dev->devno;
+ int alt_devno = devno;
+ int i;
+
+ /* allow n.15 for the first device attached to host port */
+ if (ata_is_host_link(dev->link) && devno == 0)
+ alt_devno = 15;
+
+ for (i = ata_force_tbl_size - 1; i >= 0; i--) {
+ const struct ata_force_ent *fe = &ata_force_tbl[i];
+ unsigned long pio_mask, mwdma_mask, udma_mask;
+
+ if (fe->port != -1 && fe->port != dev->link->ap->print_id)
+ continue;
+
+ if (fe->device != -1 && fe->device != devno &&
+ fe->device != alt_devno)
+ continue;
+
+ if (!fe->param.xfer_mask)
+ continue;
+
+ ata_unpack_xfermask(fe->param.xfer_mask,
+ &pio_mask, &mwdma_mask, &udma_mask);
+ if (udma_mask)
+ dev->udma_mask = udma_mask;
+ else if (mwdma_mask) {
+ dev->udma_mask = 0;
+ dev->mwdma_mask = mwdma_mask;
+ } else {
+ dev->udma_mask = 0;
+ dev->mwdma_mask = 0;
+ dev->pio_mask = pio_mask;
+ }
+
+ ata_dev_printk(dev, KERN_NOTICE,
+ "FORCE: xfer_mask set to %s\n", fe->param.name);
+ return;
+ }
+}
+
+/**
+ * ata_force_horkage - force horkage according to libata.force
+ * @dev: ATA device of interest
+ *
+ * Force horkage according to libata.force and whine about it.
+ * For consistency with link selection, device number 15 selects
+ * the first device connected to the host link.
+ *
+ * LOCKING:
+ * EH context.
+ */
+static void ata_force_horkage(struct ata_device *dev)
+{
+ int devno = dev->link->pmp + dev->devno;
+ int alt_devno = devno;
+ int i;
+
+ /* allow n.15 for the first device attached to host port */
+ if (ata_is_host_link(dev->link) && devno == 0)
+ alt_devno = 15;
+
+ for (i = 0; i < ata_force_tbl_size; i++) {
+ const struct ata_force_ent *fe = &ata_force_tbl[i];
+
+ if (fe->port != -1 && fe->port != dev->link->ap->print_id)
+ continue;
+
+ if (fe->device != -1 && fe->device != devno &&
+ fe->device != alt_devno)
+ continue;
+
+ if (!(~dev->horkage & fe->param.horkage_on) &&
+ !(dev->horkage & fe->param.horkage_off))
+ continue;
+
+ dev->horkage |= fe->param.horkage_on;
+ dev->horkage &= ~fe->param.horkage_off;
+
+ ata_dev_printk(dev, KERN_NOTICE,
+ "FORCE: horkage modified (%s)\n", fe->param.name);
+ }
+}
+
+/**
* ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure
* @tf: Taskfile to convert
* @pmp: Port multiplier port
@@ -2067,6 +2262,7 @@ int ata_dev_configure(struct ata_device *dev)
/* set horkage */
dev->horkage |= ata_dev_blacklisted(dev);
+ ata_force_horkage(dev);
/* let ACPI work its magic */
rc = ata_acpi_on_devcfg(dev);
@@ -3150,6 +3346,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
mode_mask = ATA_DMA_MASK_CFA;
ata_dev_xfermask(dev);
+ ata_force_xfermask(dev);
pio_mask = ata_pack_xfermask(dev->pio_mask, 0, 0);
dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask);
@@ -6497,7 +6694,8 @@ void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp)
*/
int sata_link_init_spd(struct ata_link *link)
{
- u32 scontrol, spd;
+ u32 scontrol;
+ u8 spd;
int rc;
rc = sata_scr_read(link, SCR_CONTROL, &scontrol);
@@ -6508,6 +6706,8 @@ int sata_link_init_spd(struct ata_link *link)
if (spd)
link->hw_sata_spd_limit &= (1 << spd) - 1;
+ ata_force_spd_limit(link);
+
link->sata_spd_limit = link->hw_sata_spd_limit;
return 0;
@@ -7218,10 +7418,187 @@ int ata_pci_device_resume(struct pci_dev *pdev)
#endif /* CONFIG_PCI */
+static int __init ata_parse_force_one(char **cur,
+ struct ata_force_ent *force_ent,
+ const char **reason)
+{
+ /* FIXME: Currently, there's no way to tag init const data and
+ * using __initdata causes build failure on some versions of
+ * gcc. Once __initdataconst is implemented, add const to the
+ * following structure.
+ */
+ static struct ata_force_param force_tbl[] __initdata = {
+ { "40c", .cbl = ATA_CBL_PATA40 },
+ { "80c", .cbl = ATA_CBL_PATA80 },
+ { "short40c", .cbl = ATA_CBL_PATA40_SHORT },
+ { "unk", .cbl = ATA_CBL_PATA_UNK },
+ { "ign", .cbl = ATA_CBL_PATA_IGN },
+ { "sata", .cbl = ATA_CBL_SATA },
+ { "1.5Gbps", .spd_limit = 1 },
+ { "3.0Gbps", .spd_limit = 2 },
+ { "noncq", .horkage_on = ATA_HORKAGE_NONCQ },
+ { "ncq", .horkage_off = ATA_HORKAGE_NONCQ },
+ { "pio0", .xfer_mask = 1 << (ATA_SHIFT_PIO + 0) },
+ { "pio1", .xfer_mask = 1 << (ATA_SHIFT_PIO + 1) },
+ { "pio2", .xfer_mask = 1 << (ATA_SHIFT_PIO + 2) },
+ { "pio3", .xfer_mask = 1 << (ATA_SHIFT_PIO + 3) },
+ { "pio4", .xfer_mask = 1 << (ATA_SHIFT_PIO + 4) },
+ { "pio5", .xfer_mask = 1 << (ATA_SHIFT_PIO + 5) },
+ { "pio6", .xfer_mask = 1 << (ATA_SHIFT_PIO + 6) },
+ { "mwdma0", .xfer_mask = 1 << (ATA_SHIFT_MWDMA + 0) },
+ { "mwdma1", .xfer_mask = 1 << (ATA_SHIFT_MWDMA + 1) },
+ { "mwdma2", .xfer_mask = 1 << (ATA_SHIFT_MWDMA + 2) },
+ { "mwdma3", .xfer_mask = 1 << (ATA_SHIFT_MWDMA + 3) },
+ { "mwdma4", .xfer_mask = 1 << (ATA_SHIFT_MWDMA + 4) },
+ { "udma0", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 0) },
+ { "udma16", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 0) },
+ { "udma/16", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 0) },
+ { "udma1", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 1) },
+ { "udma25", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 1) },
+ { "udma/25", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 1) },
+ { "udma2", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 2) },
+ { "udma33", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 2) },
+ { "udma/33", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 2) },
+ { "udma3", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 3) },
+ { "udma44", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 3) },
+ { "udma/44", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 3) },
+ { "udma4", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 4) },
+ { "udma66", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 4) },
+ { "udma/66", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 4) },
+ { "udma5", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 5) },
+ { "udma100", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 5) },
+ { "udma/100", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 5) },
+ { "udma6", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) },
+ { "udma133", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) },
+ { "udma/133", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) },
+ { "udma7", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 7) },
+ };
+ char *start = *cur, *p = *cur;
+ char *id, *val, *endp;
+ const struct ata_force_param *match_fp = NULL;
+ int nr_matches = 0, i;
+
+ /* find where this param ends and update *cur */
+ while (*p != '\0' && *p != ',')
+ p++;
+
+ if (*p == '\0')
+ *cur = p;
+ else
+ *cur = p + 1;
+
+ *p = '\0';
+
+ /* parse */
+ p = strchr(start, ':');
+ if (!p) {
+ val = strstrip(start);
+ goto parse_val;
+ }
+ *p = '\0';
+
+ id = strstrip(start);
+ val = strstrip(p + 1);
+
+ /* parse id */
+ p = strchr(id, '.');
+ if (p) {
+ *p++ = '\0';
+ force_ent->device = simple_strtoul(p, &endp, 10);
+ if (p == endp || *endp != '\0') {
+ *reason = "invalid device";
+ return -EINVAL;
+ }
+ }
+
+ force_ent->port = simple_strtoul(id, &endp, 10);
+ if (p == endp || *endp != '\0') {
+ *reason = "invalid port/link";
+ return -EINVAL;
+ }
+
+ parse_val:
+ /* parse val, allow shortcuts so that both 1.5 and 1.5Gbps work */
+ for (i = 0; i < ARRAY_SIZE(force_tbl); i++) {
+ const struct ata_force_param *fp = &force_tbl[i];
+
+ if (strncasecmp(val, fp->name, strlen(val)))
+ continue;
+
+ nr_matches++;
+ match_fp = fp;
+
+ if (strcasecmp(val, fp->name) == 0) {
+ nr_matches = 1;
+ break;
+ }
+ }
+
+ if (!nr_matches) {
+ *reason = "unknown value";
+ return -EINVAL;
+ }
+ if (nr_matches > 1) {
+ *reason = "ambigious value";
+ return -EINVAL;
+ }
+
+ force_ent->param = *match_fp;
+
+ return 0;
+}
+
+static void __init ata_parse_force_param(void)
+{
+ int idx = 0, size = 1;
+ int last_port = -1, last_device = -1;
+ char *p, *cur, *next;
+
+ /* calculate maximum number of params and allocate force_tbl */
+ for (p = ata_force_param_buf; *p; p++)
+ if (*p == ',')
+ size++;
+
+ ata_force_tbl = kzalloc(sizeof(ata_force_tbl[0]) * size, GFP_KERNEL);
+ if (!ata_force_tbl) {
+ printk(KERN_WARNING "ata: failed to extend force table, "
+ "libata.force ignored\n");
+ return;
+ }
+
+ /* parse and populate the table */
+ for (cur = ata_force_param_buf; *cur != '\0'; cur = next) {
+ const char *reason = "";
+ struct ata_force_ent te = { .port = -1, .device = -1 };
+
+ next = cur;
+ if (ata_parse_force_one(&next, &te, &reason)) {
+ printk(KERN_WARNING "ata: failed to parse force "
+ "parameter \"%s\" (%s)\n",
+ cur, reason);
+ continue;
+ }
+
+ if (te.port == -1) {
+ te.port = last_port;
+ te.device = last_device;
+ }
+
+ ata_force_tbl[idx++] = te;
+
+ last_port = te.port;
+ last_device = te.device;
+ }
+
+ ata_force_tbl_size = idx;
+}
static int __init ata_init(void)
{
ata_probe_timeout *= HZ;
+
+ ata_parse_force_param();
+
ata_wq = create_workqueue("ata");
if (!ata_wq)
return -ENOMEM;
@@ -7238,6 +7615,7 @@ static int __init ata_init(void)
static void __exit ata_exit(void)
{
+ kfree(ata_force_tbl);
destroy_workqueue(ata_wq);
destroy_workqueue(ata_aux_wq);
}
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 4e31071..698ce2c 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2393,9 +2393,11 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
}
/* PDIAG- should have been released, ask cable type if post-reset */
- if (ata_is_host_link(link) && ap->ops->cable_detect &&
- (ehc->i.flags & ATA_EHI_DID_RESET))
- ap->cbl = ap->ops->cable_detect(ap);
+ if ((ehc->i.flags & ATA_EHI_DID_RESET) && ata_is_host_link(link)) {
+ if (ap->ops->cable_detect)
+ ap->cbl = ap->ops->cable_detect(ap);
+ ata_force_cbl(ap);
+ }
/* Configure new devices forward such that user doesn't see
* device detection messages backwards.
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index dd41b1a..f888bab 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -828,7 +828,7 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev)
/**
* atapi_drain_needed - Check whether data transfer may overflow
- * @request: request to be checked
+ * @rq: request to be checked
*
* ATAPI commands which transfer variable length data to host
* might overflow due to application error or hardare bug. This
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 409ffb9..6036ded 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -61,6 +61,7 @@ extern int atapi_passthru16;
extern int libata_fua;
extern int libata_noacpi;
extern int libata_allow_tpm;
+extern void ata_force_cbl(struct ata_port *ap);
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev);
extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
u64 block, u32 n_block, unsigned int tf_flags,
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
index d2177f7..50fe08e 100644
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -774,14 +774,14 @@ static struct ata_port_operations opti82c46x_port_ops = {
static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
struct ata_timing t;
- struct legacy_data *qdi = ap->host->private_data;
+ struct legacy_data *ld_qdi = ap->host->private_data;
int active, recovery;
u8 timing;
/* Get the timing data in cycles */
ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
- if (qdi->fast) {
+ if (ld_qdi->fast) {
active = 8 - FIT(t.active, 1, 8);
recovery = 18 - FIT(t.recover, 3, 18);
} else {
@@ -790,9 +790,9 @@ static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev)
}
timing = (recovery << 4) | active | 0x08;
- qdi->clock[adev->devno] = timing;
+ ld_qdi->clock[adev->devno] = timing;
- outb(timing, qdi->timing);
+ outb(timing, ld_qdi->timing);
}
/**
@@ -808,14 +808,14 @@ static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev)
static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
struct ata_timing t;
- struct legacy_data *qdi = ap->host->private_data;
+ struct legacy_data *ld_qdi = ap->host->private_data;
int active, recovery;
u8 timing;
/* Get the timing data in cycles */
ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
- if (qdi->fast) {
+ if (ld_qdi->fast) {
active = 8 - FIT(t.active, 1, 8);
recovery = 18 - FIT(t.recover, 3, 18);
} else {
@@ -824,12 +824,12 @@ static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev)
}
timing = (recovery << 4) | active | 0x08;
- qdi->clock[adev->devno] = timing;
+ ld_qdi->clock[adev->devno] = timing;
- outb(timing, qdi->timing + 2 * ap->port_no);
+ outb(timing, ld_qdi->timing + 2 * ap->port_no);
/* Clear the FIFO */
if (adev->class != ATA_DEV_ATA)
- outb(0x5F, qdi->timing + 3);
+ outb(0x5F, ld_qdi->timing + 3);
}
/**
@@ -845,14 +845,14 @@ static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev)
static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
struct ata_timing t;
- struct legacy_data *qdi = ap->host->private_data;
+ struct legacy_data *ld_qdi = ap->host->private_data;
int active, recovery;
u8 timing;
/* Get the timing data in cycles */
ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
- if (qdi->fast) {
+ if (ld_qdi->fast) {
active = 8 - FIT(t.active, 1, 8);
recovery = 18 - FIT(t.recover, 3, 18);
} else {
@@ -860,11 +860,11 @@ static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev)
recovery = 15 - FIT(t.recover, 0, 15);
}
timing = (recovery << 4) | active | 0x08;
- qdi->clock[adev->devno] = timing;
- outb(timing, qdi->timing + 2 * adev->devno);
+ ld_qdi->clock[adev->devno] = timing;
+ outb(timing, ld_qdi->timing + 2 * adev->devno);
/* Clear the FIFO */
if (adev->class != ATA_DEV_ATA)
- outb(0x5F, qdi->timing + 3);
+ outb(0x5F, ld_qdi->timing + 3);
}
/**
@@ -879,12 +879,12 @@ static unsigned int qdi_qc_issue_prot(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct ata_device *adev = qc->dev;
- struct legacy_data *qdi = ap->host->private_data;
+ struct legacy_data *ld_qdi = ap->host->private_data;
- if (qdi->clock[adev->devno] != qdi->last) {
+ if (ld_qdi->clock[adev->devno] != ld_qdi->last) {
if (adev->pio_mode) {
- qdi->last = qdi->clock[adev->devno];
- outb(qdi->clock[adev->devno], qdi->timing +
+ ld_qdi->last = ld_qdi->clock[adev->devno];
+ outb(ld_qdi->clock[adev->devno], ld_qdi->timing +
2 * ap->port_no);
}
}
@@ -1037,12 +1037,12 @@ static u8 winbond_readcfg(unsigned long port, u8 reg)
static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
struct ata_timing t;
- struct legacy_data *winbond = ap->host->private_data;
+ struct legacy_data *ld_winbond = ap->host->private_data;
int active, recovery;
u8 reg;
int timing = 0x88 + (ap->port_no * 4) + (adev->devno * 2);
- reg = winbond_readcfg(winbond->timing, 0x81);
+ reg = winbond_readcfg(ld_winbond->timing, 0x81);
/* Get the timing data in cycles */
if (reg & 0x40) /* Fast VLB bus, assume 50MHz */
@@ -1053,7 +1053,7 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
active = (FIT(t.active, 3, 17) - 1) & 0x0F;
recovery = (FIT(t.recover, 1, 15) + 1) & 0x0F;
timing = (active << 4) | recovery;
- winbond_writecfg(winbond->timing, timing, reg);
+ winbond_writecfg(ld_winbond->timing, timing, reg);
/* Load the setup timing */
@@ -1063,7 +1063,7 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
if (!ata_pio_need_iordy(adev))
reg |= 0x02; /* IORDY off */
reg |= (FIT(t.setup, 0, 3) << 6);
- winbond_writecfg(winbond->timing, timing + 1, reg);
+ winbond_writecfg(ld_winbond->timing, timing + 1, reg);
}
static int winbond_port(struct platform_device *dev,
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 1c1fbf3..6ebebde 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -870,7 +870,7 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio,
struct mv_host_priv *hpriv = ap->host->private_data;
int hard_port = mv_hardport_from_port(ap->port_no);
void __iomem *hc_mmio = mv_hc_base_from_port(
- ap->host->iomap[MV_PRIMARY_BAR], hard_port);
+ mv_host_base(ap->host), hard_port);
u32 hc_irq_cause, ipending;
/* clear EDMA event indicators, if any */
@@ -2947,7 +2947,8 @@ static int mv_platform_probe(struct platform_device *pdev)
hpriv->n_ports = n_ports;
host->iomap = NULL;
- hpriv->base = ioremap(res->start, res->end - res->start + 1);
+ hpriv->base = devm_ioremap(&pdev->dev, res->start,
+ res->end - res->start + 1);
hpriv->base -= MV_SATAHC0_REG_BASE;
rc = mv_create_dma_pools(hpriv, &pdev->dev);
@@ -2979,11 +2980,8 @@ static int __devexit mv_platform_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct ata_host *host = dev_get_drvdata(dev);
- struct mv_host_priv *hpriv = host->private_data;
- void __iomem *base = hpriv->base;
ata_host_detach(host);
- iounmap(base);
return 0;
}
@@ -3194,6 +3192,7 @@ MODULE_DESCRIPTION("SCSI low-level driver for Marvell SATA controllers");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, mv_pci_tbl);
MODULE_VERSION(DRV_VERSION);
+MODULE_ALIAS("platform:sata_mv");
#ifdef CONFIG_PCI
module_param(msi, int, 0444);
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index bdc03f7..a96ca86 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -415,7 +415,7 @@ EXPORT_SYMBOL_GPL(device_power_down);
* @dev: Device.
* @state: Power state device is entering.
*/
-int suspend_device(struct device *dev, pm_message_t state)
+static int suspend_device(struct device *dev, pm_message_t state)
{
int error = 0;
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index 87be464..d286699 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -41,6 +41,7 @@ static int amd_create_page_map(struct amd_page_map *page_map)
if (page_map->real == NULL)
return -ENOMEM;
+#ifndef CONFIG_X86
SetPageReserved(virt_to_page(page_map->real));
global_cache_flush();
page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
@@ -52,6 +53,10 @@ static int amd_create_page_map(struct amd_page_map *page_map)
return -ENOMEM;
}
global_cache_flush();
+#else
+ set_memory_uc((unsigned long)page_map->real, 1);
+ page_map->remapped = page_map->real;
+#endif
for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) {
writel(agp_bridge->scratch_page, page_map->remapped+i);
@@ -63,8 +68,12 @@ static int amd_create_page_map(struct amd_page_map *page_map)
static void amd_free_page_map(struct amd_page_map *page_map)
{
+#ifndef CONFIG_X86
iounmap(page_map->remapped);
ClearPageReserved(virt_to_page(page_map->real));
+#else
+ set_memory_wb((unsigned long)page_map->real, 1);
+#endif
free_page((unsigned long) page_map->real);
}
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index 2d46b71..55c97f6 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -60,18 +60,9 @@ static int ati_create_page_map(struct ati_page_map *page_map)
if (page_map->real == NULL)
return -ENOMEM;
- SetPageReserved(virt_to_page(page_map->real));
+ set_memory_uc((unsigned long)page_map->real, 1);
err = map_page_into_agp(virt_to_page(page_map->real));
- page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
- PAGE_SIZE);
- if (page_map->remapped == NULL || err) {
- ClearPageReserved(virt_to_page(page_map->real));
- free_page((unsigned long) page_map->real);
- page_map->real = NULL;
- return -ENOMEM;
- }
- /*CACHE_FLUSH();*/
- global_cache_flush();
+ page_map->remapped = page_map->real;
for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) {
writel(agp_bridge->scratch_page, page_map->remapped+i);
@@ -85,8 +76,7 @@ static int ati_create_page_map(struct ati_page_map *page_map)
static void ati_free_page_map(struct ati_page_map *page_map)
{
unmap_page_from_agp(virt_to_page(page_map->real));
- iounmap(page_map->remapped);
- ClearPageReserved(virt_to_page(page_map->real));
+ set_memory_wb((unsigned long)page_map->real, 1);
free_page((unsigned long) page_map->real);
}
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 7484bc7..7fc0c99 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -932,9 +932,14 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
agp_gatt_table = (void *)table;
bridge->driver->cache_flush();
+#ifdef CONFIG_X86
+ set_memory_uc((unsigned long)table, 1 << page_order);
+ bridge->gatt_table = (void *)table;
+#else
bridge->gatt_table = ioremap_nocache(virt_to_gart(table),
(PAGE_SIZE * (1 << page_order)));
bridge->driver->cache_flush();
+#endif
if (bridge->gatt_table == NULL) {
for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
@@ -991,7 +996,11 @@ int agp_generic_free_gatt_table(struct agp_bridge_data *bridge)
* called, then all agp memory is deallocated and removed
* from the table. */
+#ifdef CONFIG_X86
+ set_memory_wb((unsigned long)bridge->gatt_table, 1 << page_order);
+#else
iounmap(bridge->gatt_table);
+#endif
table = (char *) bridge->gatt_table_real;
table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
index eb1a1c7..b679184 100644
--- a/drivers/char/agp/sis-agp.c
+++ b/drivers/char/agp/sis-agp.c
@@ -14,6 +14,9 @@
#define SIS_TLBCNTRL 0x97
#define SIS_TLBFLUSH 0x98
+#define PCI_DEVICE_ID_SI_662 0x0662
+#define PCI_DEVICE_ID_SI_671 0x0671
+
static int __devinitdata agp_sis_force_delay = 0;
static int __devinitdata agp_sis_agp_spec = -1;
@@ -27,8 +30,8 @@ static int sis_fetch_size(void)
values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if ((temp_size == values[i].size_value) ||
- ((temp_size & ~(0x03)) ==
- (values[i].size_value & ~(0x03)))) {
+ ((temp_size & ~(0x07)) ==
+ (values[i].size_value & ~(0x07)))) {
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i);
@@ -214,6 +217,26 @@ static void __devexit agp_sis_remove(struct pci_dev *pdev)
agp_put_bridge(bridge);
}
+#ifdef CONFIG_PM
+
+static int agp_sis_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ pci_save_state(pdev);
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+ return 0;
+}
+
+static int agp_sis_resume(struct pci_dev *pdev)
+{
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+
+ return sis_driver.configure();
+}
+
+#endif /* CONFIG_PM */
+
static struct pci_device_id agp_sis_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
@@ -331,6 +354,22 @@ static struct pci_device_id agp_sis_pci_table[] = {
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_SI,
+ .device = PCI_DEVICE_ID_SI_662,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ },
+ {
+ .class = (PCI_CLASS_BRIDGE_HOST << 8),
+ .class_mask = ~0,
+ .vendor = PCI_VENDOR_ID_SI,
+ .device = PCI_DEVICE_ID_SI_671,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ },
+ {
+ .class = (PCI_CLASS_BRIDGE_HOST << 8),
+ .class_mask = ~0,
+ .vendor = PCI_VENDOR_ID_SI,
.device = PCI_DEVICE_ID_SI_730,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
@@ -393,6 +432,10 @@ static struct pci_driver agp_sis_pci_driver = {
.id_table = agp_sis_pci_table,
.probe = agp_sis_probe,
.remove = agp_sis_remove,
+#ifdef CONFIG_PM
+ .suspend = agp_sis_suspend,
+ .resume = agp_sis_resume,
+#endif
};
static int __init agp_sis_init(void)
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index 551ef25..e08934e 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -52,28 +52,20 @@ static int serverworks_create_page_map(struct serverworks_page_map *page_map)
if (page_map->real == NULL) {
return -ENOMEM;
}
- SetPageReserved(virt_to_page(page_map->real));
- global_cache_flush();
- page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
- PAGE_SIZE);
- if (page_map->remapped == NULL) {
- ClearPageReserved(virt_to_page(page_map->real));
- free_page((unsigned long) page_map->real);
- page_map->real = NULL;
- return -ENOMEM;
- }
- global_cache_flush();
+
+ set_memory_uc((unsigned long)page_map->real, 1);
+ page_map->remapped = page_map->real;
for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++)
writel(agp_bridge->scratch_page, page_map->remapped+i);
+ /* Red Pen: Everyone else does pci posting flush here */
return 0;
}
static void serverworks_free_page_map(struct serverworks_page_map *page_map)
{
- iounmap(page_map->remapped);
- ClearPageReserved(virt_to_page(page_map->real));
+ set_memory_wb((unsigned long)page_map->real, 1);
free_page((unsigned long) page_map->real);
}
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 19d3be5..a6789f2 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -568,7 +568,7 @@ struct drm_driver {
void (*postclose) (struct drm_device *, struct drm_file *);
void (*lastclose) (struct drm_device *);
int (*unload) (struct drm_device *);
- int (*suspend) (struct drm_device *);
+ int (*suspend) (struct drm_device *, pm_message_t state);
int (*resume) (struct drm_device *);
int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv);
void (*dma_ready) (struct drm_device *);
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
index f524688..715b361 100644
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -83,6 +83,7 @@
{0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
{0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
{0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x5657, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
{0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
@@ -236,6 +237,7 @@
{0x1002, 0x7297, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV560|RADEON_NEW_MEMMAP}, \
{0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP}, \
{0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x791e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
{0, 0, 0}
#define r128_PCI_IDS \
@@ -313,6 +315,7 @@
{0x1039, 0x5300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1039, 0x6300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1039, 0x6330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
+ {0x1039, 0x6351, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x18CA, 0x0040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
{0x18CA, 0x0042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c
index fa36153..05ed504 100644
--- a/drivers/char/drm/drm_sysfs.c
+++ b/drivers/char/drm/drm_sysfs.c
@@ -36,7 +36,7 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state)
printk(KERN_ERR "%s\n", __FUNCTION__);
if (drm_dev->driver->suspend)
- return drm_dev->driver->suspend(drm_dev);
+ return drm_dev->driver->suspend(drm_dev, state);
return 0;
}
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
index cea4105..3d65c4d 100644
--- a/drivers/char/drm/drm_vm.c
+++ b/drivers/char/drm/drm_vm.c
@@ -66,7 +66,7 @@ static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma)
}
/**
- * \c nopage method for AGP virtual memory.
+ * \c fault method for AGP virtual memory.
*
* \param vma virtual memory area.
* \param address access address.
@@ -76,8 +76,7 @@ static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma)
* map, get the page, increment the use count and return it.
*/
#if __OS_HAS_AGP
-static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
- unsigned long address)
+static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct drm_file *priv = vma->vm_file->private_data;
struct drm_device *dev = priv->head->dev;
@@ -89,19 +88,24 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
* Find the right map
*/
if (!drm_core_has_AGP(dev))
- goto vm_nopage_error;
+ goto vm_fault_error;
if (!dev->agp || !dev->agp->cant_use_aperture)
- goto vm_nopage_error;
+ goto vm_fault_error;
if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash))
- goto vm_nopage_error;
+ goto vm_fault_error;
r_list = drm_hash_entry(hash, struct drm_map_list, hash);
map = r_list->map;
if (map && map->type == _DRM_AGP) {
- unsigned long offset = address - vma->vm_start;
+ /*
+ * Using vm_pgoff as a selector forces us to use this unusual
+ * addressing scheme.
+ */
+ unsigned long offset = (unsigned long)vmf->virtual_address -
+ vma->vm_start;
unsigned long baddr = map->offset + offset;
struct drm_agp_mem *agpmem;
struct page *page;
@@ -123,7 +127,7 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
}
if (!agpmem)
- goto vm_nopage_error;
+ goto vm_fault_error;
/*
* Get the page, inc the use count, and return it
@@ -131,22 +135,21 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
offset = (baddr - agpmem->bound) >> PAGE_SHIFT;
page = virt_to_page(__va(agpmem->memory->memory[offset]));
get_page(page);
+ vmf->page = page;
DRM_DEBUG
("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n",
baddr, __va(agpmem->memory->memory[offset]), offset,
page_count(page));
-
- return page;
+ return 0;
}
- vm_nopage_error:
- return NOPAGE_SIGBUS; /* Disallow mremap */
+vm_fault_error:
+ return VM_FAULT_SIGBUS; /* Disallow mremap */
}
#else /* __OS_HAS_AGP */
-static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
- unsigned long address)
+static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
- return NOPAGE_SIGBUS;
+ return VM_FAULT_SIGBUS;
}
#endif /* __OS_HAS_AGP */
@@ -160,28 +163,26 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
* Get the mapping, find the real physical page to map, get the page, and
* return it.
*/
-static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma,
- unsigned long address)
+static int drm_do_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct drm_map *map = (struct drm_map *) vma->vm_private_data;
unsigned long offset;
unsigned long i;
struct page *page;
- if (address > vma->vm_end)
- return NOPAGE_SIGBUS; /* Disallow mremap */
if (!map)
- return NOPAGE_SIGBUS; /* Nothing allocated */
+ return VM_FAULT_SIGBUS; /* Nothing allocated */
- offset = address - vma->vm_start;
+ offset = (unsigned long)vmf->virtual_address - vma->vm_start;
i = (unsigned long)map->handle + offset;
page = vmalloc_to_page((void *)i);
if (!page)
- return NOPAGE_SIGBUS;
+ return VM_FAULT_SIGBUS;
get_page(page);
+ vmf->page = page;
- DRM_DEBUG("0x%lx\n", address);
- return page;
+ DRM_DEBUG("shm_fault 0x%lx\n", offset);
+ return 0;
}
/**
@@ -263,7 +264,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
}
/**
- * \c nopage method for DMA virtual memory.
+ * \c fault method for DMA virtual memory.
*
* \param vma virtual memory area.
* \param address access address.
@@ -271,8 +272,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
*
* Determine the page number from the page offset and get it from drm_device_dma::pagelist.
*/
-static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
- unsigned long address)
+static int drm_do_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct drm_file *priv = vma->vm_file->private_data;
struct drm_device *dev = priv->head->dev;
@@ -282,24 +282,23 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
struct page *page;
if (!dma)
- return NOPAGE_SIGBUS; /* Error */
- if (address > vma->vm_end)
- return NOPAGE_SIGBUS; /* Disallow mremap */
+ return VM_FAULT_SIGBUS; /* Error */
if (!dma->pagelist)
- return NOPAGE_SIGBUS; /* Nothing allocated */
+ return VM_FAULT_SIGBUS; /* Nothing allocated */
- offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
- page_nr = offset >> PAGE_SHIFT;
+ offset = (unsigned long)vmf->virtual_address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
+ page_nr = offset >> PAGE_SHIFT; /* page_nr could just be vmf->pgoff */
page = virt_to_page((dma->pagelist[page_nr] + (offset & (~PAGE_MASK))));
get_page(page);
+ vmf->page = page;
- DRM_DEBUG("0x%lx (page %lu)\n", address, page_nr);
- return page;
+ DRM_DEBUG("dma_fault 0x%lx (page %lu)\n", offset, page_nr);
+ return 0;
}
/**
- * \c nopage method for scatter-gather virtual memory.
+ * \c fault method for scatter-gather virtual memory.
*
* \param vma virtual memory area.
* \param address access address.
@@ -307,8 +306,7 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
*
* Determine the map offset from the page offset and get it from drm_sg_mem::pagelist.
*/
-static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
- unsigned long address)
+static int drm_do_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct drm_map *map = (struct drm_map *) vma->vm_private_data;
struct drm_file *priv = vma->vm_file->private_data;
@@ -320,77 +318,64 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
struct page *page;
if (!entry)
- return NOPAGE_SIGBUS; /* Error */
- if (address > vma->vm_end)
- return NOPAGE_SIGBUS; /* Disallow mremap */
+ return VM_FAULT_SIGBUS; /* Error */
if (!entry->pagelist)
- return NOPAGE_SIGBUS; /* Nothing allocated */
+ return VM_FAULT_SIGBUS; /* Nothing allocated */
- offset = address - vma->vm_start;
+ offset = (unsigned long)vmf->virtual_address - vma->vm_start;
map_offset = map->offset - (unsigned long)dev->sg->virtual;
page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
page = entry->pagelist[page_offset];
get_page(page);
+ vmf->page = page;
- return page;
+ return 0;
}
-static struct page *drm_vm_nopage(struct vm_area_struct *vma,
- unsigned long address, int *type)
+static int drm_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
- if (type)
- *type = VM_FAULT_MINOR;
- return drm_do_vm_nopage(vma, address);
+ return drm_do_vm_fault(vma, vmf);
}
-static struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
- unsigned long address, int *type)
+static int drm_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
- if (type)
- *type = VM_FAULT_MINOR;
- return drm_do_vm_shm_nopage(vma, address);
+ return drm_do_vm_shm_fault(vma, vmf);
}
-static struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
- unsigned long address, int *type)
+static int drm_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
- if (type)
- *type = VM_FAULT_MINOR;
- return drm_do_vm_dma_nopage(vma, address);
+ return drm_do_vm_dma_fault(vma, vmf);
}
-static struct page *drm_vm_sg_nopage(struct vm_area_struct *vma,
- unsigned long address, int *type)
+static int drm_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
- if (type)
- *type = VM_FAULT_MINOR;
- return drm_do_vm_sg_nopage(vma, address);
+ return drm_do_vm_sg_fault(vma, vmf);
}
/** AGP virtual memory operations */
static struct vm_operations_struct drm_vm_ops = {
- .nopage = drm_vm_nopage,
+ .fault = drm_vm_fault,
.open = drm_vm_open,
.close = drm_vm_close,
};
/** Shared virtual memory operations */
static struct vm_operations_struct drm_vm_shm_ops = {
- .nopage = drm_vm_shm_nopage,
+ .fault = drm_vm_shm_fault,
.open = drm_vm_open,
.close = drm_vm_shm_close,
};
/** DMA virtual memory operations */
static struct vm_operations_struct drm_vm_dma_ops = {
- .nopage = drm_vm_dma_nopage,
+ .fault = drm_vm_dma_fault,
.open = drm_vm_open,
.close = drm_vm_close,
};
/** Scatter-gather virtual memory operations */
static struct vm_operations_struct drm_vm_sg_ops = {
- .nopage = drm_vm_sg_nopage,
+ .fault = drm_vm_sg_fault,
.open = drm_vm_open,
.close = drm_vm_close,
};
@@ -604,7 +589,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
/*
* On some platforms we can't talk to bus dma address from the CPU, so for
* memory of type DRM_AGP, we'll deal with sorting out the real physical
- * pages and mappings in nopage()
+ * pages and mappings in fault()
*/
#if defined(__powerpc__)
pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
@@ -634,7 +619,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
break;
case _DRM_CONSISTENT:
/* Consistent memory is really like shared memory. But
- * it's allocated in a different way, so avoid nopage */
+ * it's allocated in a different way, so avoid fault */
if (remap_pfn_range(vma, vma->vm_start,
page_to_pfn(virt_to_page(map->handle)),
vma->vm_end - vma->vm_start, vma->vm_page_prot))
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index 43986d8..e9d6663 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -171,7 +171,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
dev_priv->allow_batchbuffer = 1;
/* Program Hardware Status Page */
- if (!IS_G33(dev)) {
+ if (!I915_NEED_GFX_HWS(dev)) {
dev_priv->status_page_dmah =
drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
@@ -720,6 +720,9 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
drm_i915_private_t *dev_priv = dev->dev_private;
drm_i915_hws_addr_t *hws = data;
+ if (!I915_NEED_GFX_HWS(dev))
+ return -EINVAL;
+
if (!dev_priv) {
DRM_ERROR("called with no initialization\n");
return -EINVAL;
diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c
index 52e5103..4048f39 100644
--- a/drivers/char/drm/i915_drv.c
+++ b/drivers/char/drm/i915_drv.c
@@ -160,6 +160,7 @@ static void i915_save_vga(struct drm_device *dev)
dev_priv->saveAR[i] = i915_read_ar(st01, i, 0);
inb(st01);
outb(dev_priv->saveAR_INDEX, VGA_AR_INDEX);
+ inb(st01);
/* Graphics controller registers */
for (i = 0; i < 9; i++)
@@ -225,6 +226,7 @@ static void i915_restore_vga(struct drm_device *dev)
i915_write_ar(st01, i, dev_priv->saveAR[i], 0);
inb(st01); /* switch back to index mode */
outb(dev_priv->saveAR_INDEX | 0x20, VGA_AR_INDEX);
+ inb(st01);
/* VGA color palette registers */
outb(dev_priv->saveDACMASK, VGA_DACMASK);
@@ -236,7 +238,7 @@ static void i915_restore_vga(struct drm_device *dev)
}
-static int i915_suspend(struct drm_device *dev)
+static int i915_suspend(struct drm_device *dev, pm_message_t state)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int i;
@@ -247,6 +249,9 @@ static int i915_suspend(struct drm_device *dev)
return -ENODEV;
}
+ if (state.event == PM_EVENT_PRETHAW)
+ return 0;
+
pci_save_state(dev->pdev);
pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
@@ -276,6 +281,7 @@ static int i915_suspend(struct drm_device *dev)
dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF);
}
i915_save_palette(dev, PIPE_A);
+ dev_priv->savePIPEASTAT = I915_READ(I915REG_PIPEASTAT);
/* Pipe & plane B info */
dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
@@ -303,6 +309,7 @@ static int i915_suspend(struct drm_device *dev)
dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF);
}
i915_save_palette(dev, PIPE_B);
+ dev_priv->savePIPEBSTAT = I915_READ(I915REG_PIPEBSTAT);
/* CRT state */
dev_priv->saveADPA = I915_READ(ADPA);
@@ -329,12 +336,26 @@ static int i915_suspend(struct drm_device *dev)
dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2);
dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
+ /* Interrupt state */
+ dev_priv->saveIIR = I915_READ(I915REG_INT_IDENTITY_R);
+ dev_priv->saveIER = I915_READ(I915REG_INT_ENABLE_R);
+ dev_priv->saveIMR = I915_READ(I915REG_INT_MASK_R);
+
/* VGA state */
dev_priv->saveVCLK_DIVISOR_VGA0 = I915_READ(VCLK_DIVISOR_VGA0);
dev_priv->saveVCLK_DIVISOR_VGA1 = I915_READ(VCLK_DIVISOR_VGA1);
dev_priv->saveVCLK_POST_DIV = I915_READ(VCLK_POST_DIV);
dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
+ /* Clock gating state */
+ dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D);
+
+ /* Cache mode state */
+ dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
+
+ /* Memory Arbitration state */
+ dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE);
+
/* Scratch space */
for (i = 0; i < 16; i++) {
dev_priv->saveSWF0[i] = I915_READ(SWF0 + (i << 2));
@@ -345,9 +366,11 @@ static int i915_suspend(struct drm_device *dev)
i915_save_vga(dev);
- /* Shut down the device */
- pci_disable_device(dev->pdev);
- pci_set_power_state(dev->pdev, PCI_D3hot);
+ if (state.event == PM_EVENT_SUSPEND) {
+ /* Shut down the device */
+ pci_disable_device(dev->pdev);
+ pci_set_power_state(dev->pdev, PCI_D3hot);
+ }
return 0;
}
@@ -400,9 +423,7 @@ static int i915_resume(struct drm_device *dev)
I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF);
}
- if ((dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) &&
- (dev_priv->saveDPLL_A & DPLL_VGA_MODE_DIS))
- I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF);
+ I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF);
i915_restore_palette(dev, PIPE_A);
/* Enable the plane */
@@ -444,10 +465,9 @@ static int i915_resume(struct drm_device *dev)
I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF);
}
- if ((dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) &&
- (dev_priv->saveDPLL_B & DPLL_VGA_MODE_DIS))
- I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF);
- i915_restore_palette(dev, PIPE_A);
+ I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF);
+
+ i915_restore_palette(dev, PIPE_B);
/* Enable the plane */
I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
I915_WRITE(DSPBBASE, I915_READ(DSPBBASE));
@@ -485,6 +505,15 @@ static int i915_resume(struct drm_device *dev)
I915_WRITE(VCLK_POST_DIV, dev_priv->saveVCLK_POST_DIV);
udelay(150);
+ /* Clock gating state */
+ I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
+
+ /* Cache mode state */
+ I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
+
+ /* Memory arbitration state */
+ I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000);
+
for (i = 0; i < 16; i++) {
I915_WRITE(SWF0 + (i << 2), dev_priv->saveSWF0[i]);
I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]);
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index f8308bf..c10d128 100644
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -134,6 +134,7 @@ typedef struct drm_i915_private {
u32 saveVBLANK_A;
u32 saveVSYNC_A;
u32 saveBCLRPAT_A;
+ u32 savePIPEASTAT;
u32 saveDSPASTRIDE;
u32 saveDSPASIZE;
u32 saveDSPAPOS;
@@ -154,6 +155,7 @@ typedef struct drm_i915_private {
u32 saveVBLANK_B;
u32 saveVSYNC_B;
u32 saveBCLRPAT_B;
+ u32 savePIPEBSTAT;
u32 saveDSPBSTRIDE;
u32 saveDSPBSIZE;
u32 saveDSPBPOS;
@@ -182,6 +184,12 @@ typedef struct drm_i915_private {
u32 saveFBC_LL_BASE;
u32 saveFBC_CONTROL;
u32 saveFBC_CONTROL2;
+ u32 saveIER;
+ u32 saveIIR;
+ u32 saveIMR;
+ u32 saveCACHE_MODE_0;
+ u32 saveDSPCLK_GATE_D;
+ u32 saveMI_ARB_STATE;
u32 saveSWF0[16];
u32 saveSWF1[16];
u32 saveSWF2[3];
@@ -450,6 +458,10 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
*/
#define DMA_FADD_S 0x20d4
+/* Memory Interface Arbitration State
+ */
+#define MI_ARB_STATE 0x20e4
+
/* Cache mode 0 reg.
* - Manipulating render cache behaviour is central
* to the concept of zone rendering, tuning this reg can help avoid
@@ -460,6 +472,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
* bit of interest either set or cleared. EG: (BIT<<16) | BIT to set.
*/
#define Cache_Mode_0 0x2120
+#define CACHE_MODE_0 0x2120
#define CM0_MASK_SHIFT 16
#define CM0_IZ_OPT_DISABLE (1<<6)
#define CM0_ZR_OPT_DISABLE (1<<5)
@@ -655,6 +668,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
/** P1 value is 2 greater than this field */
# define VGA0_PD_P1_MASK (0x1f << 0)
+#define DSPCLK_GATE_D 0x6200
+
/* I830 CRTC registers */
#define HTOTAL_A 0x60000
#define HBLANK_A 0x60004
@@ -1101,6 +1116,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
IS_I945GM(dev) || IS_I965GM(dev) || IS_IGD_GM(dev))
+#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_IGD_GM(dev))
+
#define PRIMARY_RINGBUFFER_SIZE (128*1024)
#endif
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
index 5dc799a..833abc7 100644
--- a/drivers/char/drm/radeon_cp.c
+++ b/drivers/char/drm/radeon_cp.c
@@ -825,11 +825,19 @@ static u32 RADEON_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
return ret;
}
+static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
+{
+ RADEON_WRITE(RS690_MC_INDEX, (addr & RS690_MC_INDEX_MASK));
+ return RADEON_READ(RS690_MC_DATA);
+}
+
u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
{
if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
return RADEON_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
+ return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION);
else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
return RADEON_READ_MCIND(dev_priv, R520_MC_FB_LOCATION);
else
@@ -840,6 +848,8 @@ static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
{
if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
RADEON_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
+ RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc);
else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
RADEON_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc);
else
@@ -850,6 +860,8 @@ static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_lo
{
if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
RADEON_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
+ RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc);
else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
RADEON_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc);
else
@@ -1362,6 +1374,70 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
}
}
+/* Enable or disable RS690 GART on the chip */
+static void radeon_set_rs690gart(drm_radeon_private_t *dev_priv, int on)
+{
+ u32 temp;
+
+ if (on) {
+ DRM_DEBUG("programming rs690 gart %08X %08lX %08X\n",
+ dev_priv->gart_vm_start,
+ (long)dev_priv->gart_info.bus_addr,
+ dev_priv->gart_size);
+
+ temp = RS690_READ_MCIND(dev_priv, RS690_MC_MISC_CNTL);
+ RS690_WRITE_MCIND(RS690_MC_MISC_CNTL, 0x5000);
+
+ RS690_WRITE_MCIND(RS690_MC_AGP_SIZE,
+ RS690_MC_GART_EN | RS690_MC_AGP_SIZE_32MB);
+
+ temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_FEATURE_ID);
+ RS690_WRITE_MCIND(RS690_MC_GART_FEATURE_ID, 0x42040800);
+
+ RS690_WRITE_MCIND(RS690_MC_GART_BASE,
+ dev_priv->gart_info.bus_addr);
+
+ temp = RS690_READ_MCIND(dev_priv, RS690_MC_AGP_MODE_CONTROL);
+ RS690_WRITE_MCIND(RS690_MC_AGP_MODE_CONTROL, 0x01400000);
+
+ RS690_WRITE_MCIND(RS690_MC_AGP_BASE,
+ (unsigned int)dev_priv->gart_vm_start);
+
+ dev_priv->gart_size = 32*1024*1024;
+ temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) &
+ 0xffff0000) | (dev_priv->gart_vm_start >> 16));
+
+ RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, temp);
+
+ temp = RS690_READ_MCIND(dev_priv, RS690_MC_AGP_SIZE);
+ RS690_WRITE_MCIND(RS690_MC_AGP_SIZE,
+ RS690_MC_GART_EN | RS690_MC_AGP_SIZE_32MB);
+
+ do {
+ temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_CACHE_CNTL);
+ if ((temp & RS690_MC_GART_CLEAR_STATUS) ==
+ RS690_MC_GART_CLEAR_DONE)
+ break;
+ DRM_UDELAY(1);
+ } while (1);
+
+ RS690_WRITE_MCIND(RS690_MC_GART_CACHE_CNTL,
+ RS690_MC_GART_CC_CLEAR);
+ do {
+ temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_CACHE_CNTL);
+ if ((temp & RS690_MC_GART_CLEAR_STATUS) ==
+ RS690_MC_GART_CLEAR_DONE)
+ break;
+ DRM_UDELAY(1);
+ } while (1);
+
+ RS690_WRITE_MCIND(RS690_MC_GART_CACHE_CNTL,
+ RS690_MC_GART_CC_NO_CHANGE);
+ } else {
+ RS690_WRITE_MCIND(RS690_MC_AGP_SIZE, RS690_MC_GART_DIS);
+ }
+}
+
static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
{
u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL);
@@ -1396,6 +1472,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
{
u32 tmp;
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) {
+ radeon_set_rs690gart(dev_priv, on);
+ return;
+ }
+
if (dev_priv->flags & RADEON_IS_IGPGART) {
radeon_set_igpgart(dev_priv, on);
return;
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
index 4434332..173ae62 100644
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -123,6 +123,7 @@ enum radeon_family {
CHIP_R420,
CHIP_RV410,
CHIP_RS400,
+ CHIP_RS690,
CHIP_RV515,
CHIP_R520,
CHIP_RV530,
@@ -467,6 +468,36 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
#define RADEON_IGPGART_ENABLE 0x38
#define RADEON_IGPGART_UNK_39 0x39
+#define RS690_MC_INDEX 0x78
+# define RS690_MC_INDEX_MASK 0x1ff
+# define RS690_MC_INDEX_WR_EN (1 << 9)
+# define RS690_MC_INDEX_WR_ACK 0x7f
+#define RS690_MC_DATA 0x7c
+
+#define RS690_MC_MISC_CNTL 0x18
+#define RS690_MC_GART_FEATURE_ID 0x2b
+#define RS690_MC_GART_BASE 0x2c
+#define RS690_MC_GART_CACHE_CNTL 0x2e
+# define RS690_MC_GART_CC_NO_CHANGE 0x0
+# define RS690_MC_GART_CC_CLEAR 0x1
+# define RS690_MC_GART_CLEAR_STATUS (1 << 1)
+# define RS690_MC_GART_CLEAR_DONE (0 << 1)
+# define RS690_MC_GART_CLEAR_PENDING (1 << 1)
+#define RS690_MC_AGP_SIZE 0x38
+# define RS690_MC_GART_DIS 0x0
+# define RS690_MC_GART_EN 0x1
+# define RS690_MC_AGP_SIZE_32MB (0 << 1)
+# define RS690_MC_AGP_SIZE_64MB (1 << 1)
+# define RS690_MC_AGP_SIZE_128MB (2 << 1)
+# define RS690_MC_AGP_SIZE_256MB (3 << 1)
+# define RS690_MC_AGP_SIZE_512MB (4 << 1)
+# define RS690_MC_AGP_SIZE_1GB (5 << 1)
+# define RS690_MC_AGP_SIZE_2GB (6 << 1)
+#define RS690_MC_AGP_MODE_CONTROL 0x39
+#define RS690_MC_FB_LOCATION 0x100
+#define RS690_MC_AGP_LOCATION 0x101
+#define RS690_MC_AGP_BASE 0x102
+
#define R520_MC_IND_INDEX 0x70
#define R520_MC_IND_WR_EN (1<<24)
#define R520_MC_IND_DATA 0x74
@@ -1076,6 +1107,13 @@ do { \
RADEON_WRITE(R520_MC_IND_INDEX, 0); \
} while (0)
+#define RS690_WRITE_MCIND( addr, val ) \
+do { \
+ RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_EN | ((addr) & RS690_MC_INDEX_MASK)); \
+ RADEON_WRITE(RS690_MC_DATA, val); \
+ RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); \
+} while (0)
+
#define CP_PACKET0( reg, n ) \
(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
#define CP_PACKET0_TABLE( reg, n ) \
diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c
index 3b69855..3538da1 100644
--- a/drivers/infiniband/hw/mthca/mthca_mr.c
+++ b/drivers/infiniband/hw/mthca/mthca_mr.c
@@ -686,7 +686,7 @@ err_out_table:
mthca_table_put(dev, dev->mr_table.mpt_table, key);
err_out_mpt_free:
- mthca_free(&dev->mr_table.mpt_alloc, mr->ibmr.lkey);
+ mthca_free(&dev->mr_table.mpt_alloc, key);
return err;
}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 7dd2ec4..52b1beb 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -824,7 +824,6 @@ void ipoib_cm_dev_stop(struct net_device *dev)
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ipoib_cm_rx *p;
unsigned long begin;
- LIST_HEAD(list);
int ret;
if (!IPOIB_CM_SUPPORTED(dev->dev_addr) || !priv->cm.id)
@@ -857,9 +856,12 @@ void ipoib_cm_dev_stop(struct net_device *dev)
/*
* assume the HW is wedged and just free up everything.
*/
- list_splice_init(&priv->cm.rx_flush_list, &list);
- list_splice_init(&priv->cm.rx_error_list, &list);
- list_splice_init(&priv->cm.rx_drain_list, &list);
+ list_splice_init(&priv->cm.rx_flush_list,
+ &priv->cm.rx_reap_list);
+ list_splice_init(&priv->cm.rx_error_list,
+ &priv->cm.rx_reap_list);
+ list_splice_init(&priv->cm.rx_drain_list,
+ &priv->cm.rx_reap_list);
break;
}
spin_unlock_irq(&priv->lock);
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 2928ef2..5160587 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -1695,14 +1695,15 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio,
* information for a retry or there was no other
* mirror in-sync.
*/
- DMERR_LIMIT("Mirror read failed from %s.",
- m->dev->name);
+ DMERR_LIMIT("Mirror read failed.");
return -EIO;
}
+
+ m = read_record->m;
+
DMERR("Mirror read failed from %s. Trying alternative device.",
m->dev->name);
- m = read_record->m;
fail_mirror(m, DM_RAID1_READ_ERROR);
/*
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 1abc95c..982e27b 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -258,6 +258,23 @@ config THINKPAD_ACPI_BAY
If you are not sure, say Y here.
+config THINKPAD_ACPI_VIDEO
+ bool "Video output control support"
+ depends on THINKPAD_ACPI
+ default y
+ ---help---
+ Allows the thinkpad_acpi driver to provide an interface to control
+ the various video output ports.
+
+ This feature often won't work well, depending on ThinkPad model,
+ display state, video output devices in use, whether there is a X
+ server running, phase of the moon, and the current mood of
+ Schroedinger's cat. If you can use X.org's RandR to control
+ your ThinkPad's video output ports instead of this feature,
+ don't think twice: do it and say N here to save some memory.
+
+ If you are not sure, say Y here.
+
config THINKPAD_ACPI_HOTKEY_POLL
bool "Suport NVRAM polling for hot keys"
depends on THINKPAD_ACPI
diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c
index d7aea93..74d12b4 100644
--- a/drivers/misc/acer-wmi.c
+++ b/drivers/misc/acer-wmi.c
@@ -273,6 +273,15 @@ static struct dmi_system_id acer_quirks[] = {
},
{
.callback = dmi_matched,
+ .ident = "Acer TravelMate 4200",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4200"),
+ },
+ .driver_data = &quirk_acer_travelmate_2490,
+ },
+ {
+ .callback = dmi_matched,
.ident = "Medion MD 98300",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
diff --git a/drivers/misc/intel_menlow.c b/drivers/misc/intel_menlow.c
index f70984ab..de16e88 100644
--- a/drivers/misc/intel_menlow.c
+++ b/drivers/misc/intel_menlow.c
@@ -170,10 +170,13 @@ static int intel_menlow_memory_add(struct acpi_device *device)
cdev = thermal_cooling_device_register("Memory controller", device,
&memory_cooling_ops);
- acpi_driver_data(device) = cdev;
- if (!cdev)
- result = -ENODEV;
- else {
+ if (IS_ERR(cdev)) {
+ result = PTR_ERR(cdev);
+ goto end;
+ }
+
+ if (cdev) {
+ acpi_driver_data(device) = cdev;
result = sysfs_create_link(&device->dev.kobj,
&cdev->device.kobj, "thermal_cooling");
if (result)
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index e2c7edd..bb269d0 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -221,6 +221,7 @@ static struct {
u32 hotkey:1;
u32 hotkey_mask:1;
u32 hotkey_wlsw:1;
+ u32 hotkey_tablet:1;
u32 light:1;
u32 light_status:1;
u32 bright_16levels:1;
@@ -301,6 +302,13 @@ TPACPI_HANDLE(hkey, ec, "\\_SB.HKEY", /* 600e/x, 770e, 770x */
"HKEY", /* all others */
); /* 570 */
+TPACPI_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA", /* 570 */
+ "\\_SB.PCI0.AGP0.VID0", /* 600e/x, 770x */
+ "\\_SB.PCI0.VID0", /* 770e */
+ "\\_SB.PCI0.VID", /* A21e, G4x, R50e, X30, X40 */
+ "\\_SB.PCI0.AGP.VID", /* all others */
+ ); /* R30, R31 */
+
/*************************************************************************
* ACPI helpers
@@ -1053,6 +1061,9 @@ static struct attribute_set *hotkey_dev_attributes;
#define HOTKEY_CONFIG_CRITICAL_END
#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
+/* HKEY.MHKG() return bits */
+#define TP_HOTKEY_TABLET_MASK (1 << 3)
+
static int hotkey_get_wlsw(int *status)
{
if (!acpi_evalf(hkey_handle, status, "WLSW", "d"))
@@ -1060,6 +1071,16 @@ static int hotkey_get_wlsw(int *status)
return 0;
}
+static int hotkey_get_tablet_mode(int *status)
+{
+ int s;
+
+ if (!acpi_evalf(hkey_handle, &s, "MHKG", "d"))
+ return -EIO;
+
+ return ((s & TP_HOTKEY_TABLET_MASK) != 0);
+}
+
/*
* Call with hotkey_mutex held
*/
@@ -1154,15 +1175,31 @@ static void tpacpi_input_send_radiosw(void)
{
int wlsw;
- mutex_lock(&tpacpi_inputdev_send_mutex);
-
if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) {
+ mutex_lock(&tpacpi_inputdev_send_mutex);
+
input_report_switch(tpacpi_inputdev,
SW_RADIO, !!wlsw);
input_sync(tpacpi_inputdev);
+
+ mutex_unlock(&tpacpi_inputdev_send_mutex);
}
+}
+
+static void tpacpi_input_send_tabletsw(void)
+{
+ int state;
+
+ if (tp_features.hotkey_tablet &&
+ !hotkey_get_tablet_mode(&state)) {
+ mutex_lock(&tpacpi_inputdev_send_mutex);
- mutex_unlock(&tpacpi_inputdev_send_mutex);
+ input_report_switch(tpacpi_inputdev,
+ SW_TABLET_MODE, !!state);
+ input_sync(tpacpi_inputdev);
+
+ mutex_unlock(&tpacpi_inputdev_send_mutex);
+ }
}
static void tpacpi_input_send_key(unsigned int scancode)
@@ -1417,6 +1454,14 @@ static void hotkey_poll_setup_safe(int may_warn)
mutex_unlock(&hotkey_mutex);
}
+#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
+
+static void hotkey_poll_setup_safe(int __unused)
+{
+}
+
+#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
+
static int hotkey_inputdev_open(struct input_dev *dev)
{
switch (tpacpi_lifecycle) {
@@ -1444,7 +1489,6 @@ static void hotkey_inputdev_close(struct input_dev *dev)
if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING)
hotkey_poll_setup_safe(0);
}
-#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
/* sysfs hotkey enable ------------------------------------------------- */
static ssize_t hotkey_enable_show(struct device *dev,
@@ -1666,6 +1710,29 @@ static void hotkey_radio_sw_notify_change(void)
"hotkey_radio_sw");
}
+/* sysfs hotkey tablet mode (pollable) --------------------------------- */
+static ssize_t hotkey_tablet_mode_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int res, s;
+ res = hotkey_get_tablet_mode(&s);
+ if (res < 0)
+ return res;
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", !!s);
+}
+
+static struct device_attribute dev_attr_hotkey_tablet_mode =
+ __ATTR(hotkey_tablet_mode, S_IRUGO, hotkey_tablet_mode_show, NULL);
+
+static void hotkey_tablet_mode_notify_change(void)
+{
+ if (tp_features.hotkey_tablet)
+ sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
+ "hotkey_tablet_mode");
+}
+
/* sysfs hotkey report_mode -------------------------------------------- */
static ssize_t hotkey_report_mode_show(struct device *dev,
struct device_attribute *attr,
@@ -1878,7 +1945,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
str_supported(tp_features.hotkey));
if (tp_features.hotkey) {
- hotkey_dev_attributes = create_attr_set(12, NULL);
+ hotkey_dev_attributes = create_attr_set(13, NULL);
if (!hotkey_dev_attributes)
return -ENOMEM;
res = add_many_to_attr_set(hotkey_dev_attributes,
@@ -1957,6 +2024,18 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
&dev_attr_hotkey_radio_sw.attr);
}
+ /* For X41t, X60t, X61t Tablets... */
+ if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) {
+ tp_features.hotkey_tablet = 1;
+ printk(TPACPI_INFO
+ "possible tablet mode switch found; "
+ "ThinkPad in %s mode\n",
+ (status & TP_HOTKEY_TABLET_MASK)?
+ "tablet" : "laptop");
+ res = add_to_attr_set(hotkey_dev_attributes,
+ &dev_attr_hotkey_tablet_mode.attr);
+ }
+
if (!res)
res = register_attr_set_with_sysfs(
hotkey_dev_attributes,
@@ -2006,6 +2085,10 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
set_bit(EV_SW, tpacpi_inputdev->evbit);
set_bit(SW_RADIO, tpacpi_inputdev->swbit);
}
+ if (tp_features.hotkey_tablet) {
+ set_bit(EV_SW, tpacpi_inputdev->evbit);
+ set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit);
+ }
dbg_printk(TPACPI_DBG_INIT,
"enabling hot key handling\n");
@@ -2023,12 +2106,12 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
(hotkey_report_mode < 2) ?
"enabled" : "disabled");
-#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
tpacpi_inputdev->open = &hotkey_inputdev_open;
tpacpi_inputdev->close = &hotkey_inputdev_close;
hotkey_poll_setup_safe(1);
-#endif
+ tpacpi_input_send_radiosw();
+ tpacpi_input_send_tabletsw();
}
return (tp_features.hotkey)? 0 : 1;
@@ -2156,11 +2239,15 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
/* 0x5000-0x5FFF: human interface helpers */
switch (hkey) {
case 0x5010: /* Lenovo new BIOS: brightness changed */
- case 0x5009: /* X61t: swivel up (tablet mode) */
- case 0x500a: /* X61t: swivel down (normal mode) */
case 0x500b: /* X61t: tablet pen inserted into bay */
case 0x500c: /* X61t: tablet pen removed from bay */
break;
+ case 0x5009: /* X41t-X61t: swivel up (tablet mode) */
+ case 0x500a: /* X41t-X61t: swivel down (normal mode) */
+ tpacpi_input_send_tabletsw();
+ hotkey_tablet_mode_notify_change();
+ send_acpi_ev = 0;
+ break;
case 0x5001:
case 0x5002:
/* LID switch events. Do not propagate */
@@ -2219,11 +2306,10 @@ static void hotkey_resume(void)
"from firmware\n");
tpacpi_input_send_radiosw();
hotkey_radio_sw_notify_change();
+ hotkey_tablet_mode_notify_change();
hotkey_wakeup_reason_notify_change();
hotkey_wakeup_hotunplug_complete_notify_change();
-#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
hotkey_poll_setup_safe(0);
-#endif
}
/* procfs -------------------------------------------------------------- */
@@ -2676,6 +2762,8 @@ static struct ibm_struct wan_driver_data = {
* Video subdriver
*/
+#ifdef CONFIG_THINKPAD_ACPI_VIDEO
+
enum video_access_mode {
TPACPI_VIDEO_NONE = 0,
TPACPI_VIDEO_570, /* 570 */
@@ -2703,13 +2791,6 @@ static int video_orig_autosw;
static int video_autosw_get(void);
static int video_autosw_set(int enable);
-TPACPI_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA", /* 570 */
- "\\_SB.PCI0.AGP0.VID0", /* 600e/x, 770x */
- "\\_SB.PCI0.VID0", /* 770e */
- "\\_SB.PCI0.VID", /* A21e, G4x, R50e, X30, X40 */
- "\\_SB.PCI0.AGP.VID", /* all others */
- ); /* R30, R31 */
-
TPACPI_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID"); /* G41 */
static int __init video_init(struct ibm_init_struct *iibm)
@@ -3019,6 +3100,8 @@ static struct ibm_struct video_driver_data = {
.exit = video_exit,
};
+#endif /* CONFIG_THINKPAD_ACPI_VIDEO */
+
/*************************************************************************
* Light (thinklight) subdriver
*/
@@ -5803,10 +5886,12 @@ static struct ibm_init_struct ibms_init[] __initdata = {
.init = wan_init,
.data = &wan_driver_data,
},
+#ifdef CONFIG_THINKPAD_ACPI_VIDEO
{
.init = video_init,
.data = &video_driver_data,
},
+#endif
{
.init = light_init,
.data = &light_driver_data,
@@ -5918,7 +6003,7 @@ MODULE_PARM_DESC(hotkey_report_mode,
#define TPACPI_PARAM(feature) \
module_param_call(feature, set_ibm_param, NULL, NULL, 0); \
- MODULE_PARM_DESC(feature, "Simulates thinkpad-aci procfs command " \
+ MODULE_PARM_DESC(feature, "Simulates thinkpad-acpi procfs command " \
"at module load, see documentation")
TPACPI_PARAM(hotkey);
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index e569645..4a23654 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -158,6 +158,7 @@ run_osc_out:
/**
* __pci_osc_support_set - register OS support to Firmware
* @flags: OS support bits
+ * @hid: hardware ID
*
* Update OS support fields and doing a _OSC Query to obtain an update
* from Firmware on supported control bits.
@@ -241,8 +242,6 @@ EXPORT_SYMBOL(pci_osc_control_set);
* choose from highest power _SxD to lowest power _SxW
* else // no _PRW at S-state x
* choose highest power _SxD or any lower power
- *
- * currently we simply return _SxD, if present.
*/
static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev,
diff --git a/drivers/thermal/thermal.c b/drivers/thermal/thermal.c
index e782b3e..8b86e53 100644
--- a/drivers/thermal/thermal.c
+++ b/drivers/thermal/thermal.c
@@ -306,12 +306,23 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
{
struct thermal_cooling_device_instance *dev;
struct thermal_cooling_device_instance *pos;
+ struct thermal_zone_device *pos1;
+ struct thermal_cooling_device *pos2;
int result;
if (trip >= tz->trips || (trip < 0 && trip != THERMAL_TRIPS_NONE))
return -EINVAL;
- if (!tz || !cdev)
+ list_for_each_entry(pos1, &thermal_tz_list, node) {
+ if (pos1 == tz)
+ break;
+ }
+ list_for_each_entry(pos2, &thermal_cdev_list, node) {
+ if (pos2 == cdev)
+ break;
+ }
+
+ if (tz != pos1 || cdev != pos2)
return -EINVAL;
dev =
@@ -437,20 +448,20 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *type,
int result;
if (strlen(type) >= THERMAL_NAME_LENGTH)
- return NULL;
+ return ERR_PTR(-EINVAL);
if (!ops || !ops->get_max_state || !ops->get_cur_state ||
!ops->set_cur_state)
- return NULL;
+ return ERR_PTR(-EINVAL);
cdev = kzalloc(sizeof(struct thermal_cooling_device), GFP_KERNEL);
if (!cdev)
- return NULL;
+ return ERR_PTR(-ENOMEM);
result = get_idr(&thermal_cdev_idr, &thermal_idr_lock, &cdev->id);
if (result) {
kfree(cdev);
- return NULL;
+ return ERR_PTR(result);
}
strcpy(cdev->type, type);
@@ -462,7 +473,7 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *type,
if (result) {
release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id);
kfree(cdev);
- return NULL;
+ return ERR_PTR(result);
}
/* sys I/F */
@@ -498,7 +509,7 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *type,
unregister:
release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id);
device_unregister(&cdev->device);
- return NULL;
+ return ERR_PTR(result);
}
EXPORT_SYMBOL(thermal_cooling_device_register);
@@ -570,17 +581,17 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
int count;
if (strlen(type) >= THERMAL_NAME_LENGTH)
- return NULL;
+ return ERR_PTR(-EINVAL);
if (trips > THERMAL_MAX_TRIPS || trips < 0)
- return NULL;
+ return ERR_PTR(-EINVAL);
if (!ops || !ops->get_temp)
- return NULL;
+ return ERR_PTR(-EINVAL);
tz = kzalloc(sizeof(struct thermal_zone_device), GFP_KERNEL);
if (!tz)
- return NULL;
+ return ERR_PTR(-ENOMEM);
INIT_LIST_HEAD(&tz->cooling_devices);
idr_init(&tz->idr);
@@ -588,7 +599,7 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
result = get_idr(&thermal_tz_idr, &thermal_idr_lock, &tz->id);
if (result) {
kfree(tz);
- return NULL;
+ return ERR_PTR(result);
}
strcpy(tz->type, type);
@@ -601,7 +612,7 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
if (result) {
release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
kfree(tz);
- return NULL;
+ return ERR_PTR(result);
}
/* sys I/F */
@@ -643,7 +654,7 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
unregister:
release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
device_unregister(&tz->device);
- return NULL;
+ return ERR_PTR(result);
}
EXPORT_SYMBOL(thermal_zone_device_register);
OpenPOWER on IntegriCloud