Code:
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 135df16..c0f71fb 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -455,8 +455,8 @@ static int pci_restore_standard_config(struct pci_dev *pci_dev)
static void pci_pm_default_resume_early(struct pci_dev *pci_dev)
{
+ pci_fixup_device(pci_fixup_resume_early, pci_dev);
pci_restore_standard_config(pci_dev);
- pci_fixup_device(pci_fixup_resume_early, pci_dev);
}
#endif
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 5129ed6..00c6891 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2971,3 +2971,67 @@ int pci_dev_specific_reset(struct pci_dev *dev, int probe)
return -ENOTTY;
}
+
+static bool mbp_force_ahci;
+module_param(mbp_force_ahci, bool, 0444);
+MODULE_PARM_DESC(mbp_force_ahci, "AHCI mode for MacBook Pro");
+
+static bool quirk_mbp_sata_dev(struct pci_dev *pdev)
+{
+ printk(KERN_INFO "Quirking ahci device %04x:%04x\n", pdev->vendor, pdev->device);
+ pci_write_config_word(pdev, 0x90, 0x60); /* AHCI - 6 ports enabled */
+ pdev->class = PCI_CLASS_STORAGE_SATA_AHCI;
+ // pci_write_config_dword(pdev, 0x9c, 0);
+ pci_write_config_byte(pdev, PCI_CLASS_PROG, 0x01);
+ pci_write_config_byte(pdev, PCI_CLASS_DEVICE, 0x06);
+ /* The PCI device ID will have been changed */
+ pci_read_config_word(pdev, PCI_DEVICE_ID, &pdev->device);
+ printk(KERN_DEBUG "ICH AHCI quirk: SATA AHCI controller has device ID %04x:%04x\n", pdev->vendor, pdev->device);
+ return false;
+}
+
+static void quirk_mbp_sata(struct pci_dev *pdev)
+{
+ int ret = 0;
+
+ if (!mbp_force_ahci)
+ return;
+
+ if (quirk_mbp_sata_dev(pdev))
+ return; /* nothing to do */
+
+ /* Try to allocate the resource on BAR 5.
+ * If we have a bad alignment, don't even try,
+ * thus neatly avoiding a scary warning.
+ */
+ if (pci_resource_alignment(pdev, &pdev->resource[5]))
+ ret = pci_assign_resource(pdev, 5);
+ if (!ret) {
+ printk (KERN_INFO "Quirked ICH SATA controller to AHCI mode\n");
+ return;
+ }
+ mbp_force_ahci = 0;
+ printk (KERN_ERR "MBP ICH AHCI quirk: pci_assign_resource returned %d\n", ret);
+}
+
+
+/* On resume, the device will have been reset to IDE mode, so we need to re-quirk */
+static void quirk_mbp_sata_resume(struct pci_dev *pdev)
+{
+ if (mbp_force_ahci && !quirk_mbp_sata_dev(pdev)) {
+ pci_update_resource(pdev, 5);
+ printk (KERN_INFO "Re-quirked ICH SATA controller to AHCI mode\n");
+ }
+}
+
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x3b28, quirk_mbp_sata); /* MacBook Pro (6,1) force AHCI */
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, 0x3b29, quirk_mbp_sata_resume); /* MacBook Pro (6,1) force AHCI on resume. Note that the original quirk will have changed the device ID */
+
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x3b20, quirk_mbp_sata); /* iMac 11,1 force AHCI */
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, 0x3b22, quirk_mbp_sata_resume); /* iMac 11,1 force AHCI on resume. Note that the original quirk will have changed the device ID */
+
+
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1c01, quirk_mbp_sata); /* iMac 8,1 force AHCI */
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, 0x1c03, quirk_mbp_sata_resume); /* iMac 8,1 force AHCI on resume. Note that the original quirk will have changed the device ID */
+
+
diff --git a/drivers/video/backlight/apple_bl.c b/drivers/video/backlight/apple_bl.c
index be98d15..74ef258 100644
--- a/drivers/video/backlight/apple_bl.c
+++ b/drivers/video/backlight/apple_bl.c
@@ -31,6 +31,8 @@ struct hw_data {
/* I/O resource to allocate. */
unsigned long iostart;
unsigned long iolen;
+ unsigned long io_1_start;
+ unsigned long io_1_len;
/* Backlight operations structure. */
const struct backlight_ops backlight_ops;
void (*set_brightness)(int);
@@ -44,6 +46,12 @@ static const struct hw_data *hw_data;
static int debug;
module_param_named(debug, debug, int, 0644);
MODULE_PARM_DESC(debug, "Set to one to enable debugging messages.");
+static int use_gmux;
+module_param_named(use_gmux, use_gmux, int, 0644);
+MODULE_PARM_DESC(use_gmux, "Set to one to use gmux backlight method");
+static int max_brightness = 132000;
+module_param_named(max_brightness, max_brightness, int, 0644);
+MODULE_PARM_DESC(max_brightness, "Set to max allowable brightness");
/*
* Implementation for machines with Intel chipset.
@@ -139,6 +147,53 @@ static const struct hw_data nvidia_chipset_data = {
.set_brightness = nvidia_chipset_set_brightness,
};
+#define PORT_BACKLIGHT_1 0x774
+#define PORT_BACKLIGHT_2 0x10724
+
+static void gmux_set_brightness(int intensity)
+{
+ outw(0x2f, PORT_BACKLIGHT_2);
+ outl(intensity, PORT_BACKLIGHT_1);
+}
+
+static int gmux_send_intensity(struct backlight_device *bd)
+{
+ int intensity = bd->props.brightness;
+
+ if (debug)
+ printk(KERN_DEBUG DRIVER "setting brightness to %d\n",
+ intensity);
+
+ gmux_set_brightness(intensity);
+ return 0;
+}
+
+static int gmux_get_intensity(struct backlight_device *bd)
+{
+ int intensity;
+ intensity = inl(PORT_BACKLIGHT_1);
+
+ if (debug)
+ printk(KERN_DEBUG DRIVER "read brightness of %d\n",
+ intensity);
+
+ return intensity;
+}
+
+static const struct hw_data gmux_data = {
+ .iostart = PORT_BACKLIGHT_1,
+ .iolen = 4,
+ .io_1_start = PORT_BACKLIGHT_2,
+ .io_1_len = 2,
+ .backlight_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .get_brightness = gmux_get_intensity,
+ .update_status = gmux_send_intensity
+ },
+ .set_brightness = gmux_set_brightness,
+};
+
+
static int __devinit apple_bl_add(struct acpi_device *dev)
{
struct backlight_properties props;
@@ -152,10 +207,16 @@ static int __devinit apple_bl_add(struct acpi_device *dev)
return -ENODEV;
}
- if (host->vendor == PCI_VENDOR_ID_INTEL)
- hw_data = &intel_chipset_data;
- else if (host->vendor == PCI_VENDOR_ID_NVIDIA)
- hw_data = &nvidia_chipset_data;
+ if(use_gmux == 0) {
+ if (host->vendor == PCI_VENDOR_ID_INTEL)
+ hw_data = &intel_chipset_data;
+ else if (host->vendor == PCI_VENDOR_ID_NVIDIA)
+ hw_data = &nvidia_chipset_data;
+ }
+ else
+ hw_data = &gmux_data;
+
+ printk(KERN_ERR DRIVER "host->vendor == %x gmux = %d", host->vendor, use_gmux);
pci_dev_put(host);
@@ -170,24 +231,38 @@ static int __devinit apple_bl_add(struct acpi_device *dev)
if (!intensity) {
hw_data->set_brightness(1);
- if (!hw_data->backlight_ops.get_brightness(NULL))
+ if (!hw_data->backlight_ops.get_brightness(NULL)) {
+ printk(KERN_ERR DRIVER "cannot set brightness - no device found\n");
return -ENODEV;
+ }
+
hw_data->set_brightness(0);
}
-
+
if (!request_region(hw_data->iostart, hw_data->iolen,
- "Apple backlight"))
- return -ENXIO;
+ "Apple backlight")) {
+ printk(KERN_ERR DRIVER "cannot request backlight region\n");
+ // return -ENXIO;
+ }
+ if (hw_data->io_1_start != 0 && !request_region(hw_data->io_1_start, hw_data->io_1_len,
+ "Apple backlight1")) {
+ printk(KERN_ERR DRIVER "cannot request backlight region 1\n");
+ // return -ENXIO;
+ }
+
memset(&props, 0, sizeof(struct backlight_properties));
props.type = BACKLIGHT_PLATFORM;
- props.max_brightness = 15;
- apple_backlight_device = backlight_device_register("apple_backlight",
+ props.max_brightness = use_gmux ? max_brightness : 15;
+ apple_backlight_device = backlight_device_register("acpi_video0",
NULL, NULL, &hw_data->backlight_ops, &props);
if (IS_ERR(apple_backlight_device)) {
release_region(hw_data->iostart, hw_data->iolen);
+ if(hw_data->io_1_start)
+ release_region(hw_data->io_1_start, hw_data->io_1_len);
+ printk(KERN_ERR DRIVER "cannot register device\n");
return PTR_ERR(apple_backlight_device);
}
@@ -203,6 +278,8 @@ static int __devexit apple_bl_remove(struct acpi_device *dev, int type)
backlight_device_unregister(apple_backlight_device);
release_region(hw_data->iostart, hw_data->iolen);
+ if(hw_data->io_1_start)
+ release_region(hw_data->io_1_start, hw_data->io_1_len);
hw_data = NULL;
return 0;
}