Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1e66239e authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev

* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev:
  pata_hpt37x: Fix 2.6.22 clock PLL regression
  pata_ali: Correct HP detect
  ata_piix: fix suspend/resume for some TOSHIBA laptops
  PCI: export __pci_reenable_device()
parents 7742c0bc 64a81709
Loading
Loading
Loading
Loading
+111 −2
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@
#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
#include <linux/dmi.h>

#define DRV_NAME	"ata_piix"
#define DRV_VERSION	"2.11"
@@ -140,6 +141,9 @@ enum {
	RV			= -3, /* reserved */

	PIIX_AHCI_DEVICE	= 6,

	/* host->flags bits */
	PIIX_HOST_BROKEN_SUSPEND = (1 << 24),
};

struct piix_map_db {
@@ -159,6 +163,10 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev);
static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev);
static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev);
static int ich_pata_cable_detect(struct ata_port *ap);
#ifdef CONFIG_PM
static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
static int piix_pci_device_resume(struct pci_dev *pdev);
#endif

static unsigned int in_module_init = 1;

@@ -255,8 +263,8 @@ static struct pci_driver piix_pci_driver = {
	.probe			= piix_init_one,
	.remove			= ata_pci_remove_one,
#ifdef CONFIG_PM
	.suspend		= ata_pci_device_suspend,
	.resume			= ata_pci_device_resume,
	.suspend		= piix_pci_device_suspend,
	.resume			= piix_pci_device_resume,
#endif
};

@@ -881,6 +889,107 @@ static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev)
	do_pata_set_dmamode(ap, adev, 1);
}

#ifdef CONFIG_PM
static struct dmi_system_id piix_broken_suspend_dmi_table[] = {
	{
		.ident = "TECRA M5",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
			DMI_MATCH(DMI_PRODUCT_NAME, "TECRA M5"),
		},
	},
	{
		.ident = "Satellite U200",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
			DMI_MATCH(DMI_PRODUCT_NAME, "Satellite U200"),
		},
	},
	{
		.ident = "Satellite U205",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
			DMI_MATCH(DMI_PRODUCT_NAME, "Satellite U205"),
		},
	},
	{
		.ident = "Portege M500",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
			DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M500"),
		},
	},
	{ }
};

static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
{
	struct ata_host *host = dev_get_drvdata(&pdev->dev);
	unsigned long flags;
	int rc = 0;

	rc = ata_host_suspend(host, mesg);
	if (rc)
		return rc;

	/* Some braindamaged ACPI suspend implementations expect the
	 * controller to be awake on entry; otherwise, it burns cpu
	 * cycles and power trying to do something to the sleeping
	 * beauty.
	 */
	if (dmi_check_system(piix_broken_suspend_dmi_table) &&
	    mesg.event == PM_EVENT_SUSPEND) {
		pci_save_state(pdev);

		/* mark its power state as "unknown", since we don't
		 * know if e.g. the BIOS will change its device state
		 * when we suspend.
		 */
		if (pdev->current_state == PCI_D0)
			pdev->current_state = PCI_UNKNOWN;

		/* tell resume that it's waking up from broken suspend */
		spin_lock_irqsave(&host->lock, flags);
		host->flags |= PIIX_HOST_BROKEN_SUSPEND;
		spin_unlock_irqrestore(&host->lock, flags);
	} else
		ata_pci_device_do_suspend(pdev, mesg);

	return 0;
}

static int piix_pci_device_resume(struct pci_dev *pdev)
{
	struct ata_host *host = dev_get_drvdata(&pdev->dev);
	unsigned long flags;
	int rc;

	if (host->flags & PIIX_HOST_BROKEN_SUSPEND) {
		spin_lock_irqsave(&host->lock, flags);
		host->flags &= ~PIIX_HOST_BROKEN_SUSPEND;
		spin_unlock_irqrestore(&host->lock, flags);

		pci_set_power_state(pdev, PCI_D0);
		pci_restore_state(pdev);

		/* PCI device wasn't disabled during suspend.  Use
		 * __pci_reenable_device() to avoid affecting the
		 * enable count.
		 */
		rc = __pci_reenable_device(pdev);
		if (rc)
			dev_printk(KERN_ERR, &pdev->dev, "failed to enable "
				   "device after resume (%d)\n", rc);
	} else
		rc = ata_pci_device_do_resume(pdev);

	if (rc == 0)
		ata_host_resume(host);

	return rc;
}
#endif

#define AHCI_PCI_BAR 5
#define AHCI_GLOBAL_CTL 0x04
#define AHCI_ENABLE (1 << 31)
+1 −1
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ static struct dmi_system_id cable_dmi_table[] = {
		.ident = "HP Pavilion N5430",
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
			DMI_MATCH(DMI_BOARD_NAME, "OmniBook N32N-736"),
			DMI_MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736"),
		},
	},
	{ }
+7 −7
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@
#include <linux/libata.h>

#define DRV_NAME	"pata_hpt37x"
#define DRV_VERSION	"0.6.6"
#define DRV_VERSION	"0.6.7"

struct hpt_clock {
	u8	xfer_speed;
@@ -1103,17 +1103,17 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)

		/* Select the DPLL clock. */
		pci_write_config_byte(dev, 0x5b, 0x21);
		pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low);
		pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100);

		for(adjust = 0; adjust < 8; adjust++) {
			if (hpt37x_calibrate_dpll(dev))
				break;
			/* See if it'll settle at a fractionally different clock */
			if ((adjust & 3) == 3) {
				f_low --;
				f_high ++;
			}
			pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low);
			if (adjust & 1)
				f_low -= adjust >> 1;
			else
				f_high += adjust >> 1;
			pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100);
		}
		if (adjust == 8) {
			printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n");
+1 −0
Original line number Diff line number Diff line
@@ -1604,6 +1604,7 @@ early_param("pci", pci_setup);
device_initcall(pci_init);

EXPORT_SYMBOL_GPL(pci_restore_bars);
EXPORT_SYMBOL(__pci_reenable_device);
EXPORT_SYMBOL(pci_enable_device_bars);
EXPORT_SYMBOL(pci_enable_device);
EXPORT_SYMBOL(pcim_enable_device);
+0 −1
Original line number Diff line number Diff line
/* Functions internal to the PCI core code */

extern int __must_check __pci_reenable_device(struct pci_dev *);
extern int pci_uevent(struct device *dev, char **envp, int num_envp,
		      char *buffer, int buffer_size);
extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
Loading