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()
This commit is contained in:
commit
1e66239e23
7 changed files with 123 additions and 11 deletions
|
@ -91,6 +91,7 @@
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <scsi/scsi_host.h>
|
#include <scsi/scsi_host.h>
|
||||||
#include <linux/libata.h>
|
#include <linux/libata.h>
|
||||||
|
#include <linux/dmi.h>
|
||||||
|
|
||||||
#define DRV_NAME "ata_piix"
|
#define DRV_NAME "ata_piix"
|
||||||
#define DRV_VERSION "2.11"
|
#define DRV_VERSION "2.11"
|
||||||
|
@ -140,6 +141,9 @@ enum {
|
||||||
RV = -3, /* reserved */
|
RV = -3, /* reserved */
|
||||||
|
|
||||||
PIIX_AHCI_DEVICE = 6,
|
PIIX_AHCI_DEVICE = 6,
|
||||||
|
|
||||||
|
/* host->flags bits */
|
||||||
|
PIIX_HOST_BROKEN_SUSPEND = (1 << 24),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct piix_map_db {
|
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 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 void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev);
|
||||||
static int ich_pata_cable_detect(struct ata_port *ap);
|
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;
|
static unsigned int in_module_init = 1;
|
||||||
|
|
||||||
|
@ -255,8 +263,8 @@ static struct pci_driver piix_pci_driver = {
|
||||||
.probe = piix_init_one,
|
.probe = piix_init_one,
|
||||||
.remove = ata_pci_remove_one,
|
.remove = ata_pci_remove_one,
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.suspend = ata_pci_device_suspend,
|
.suspend = piix_pci_device_suspend,
|
||||||
.resume = ata_pci_device_resume,
|
.resume = piix_pci_device_resume,
|
||||||
#endif
|
#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);
|
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_PCI_BAR 5
|
||||||
#define AHCI_GLOBAL_CTL 0x04
|
#define AHCI_GLOBAL_CTL 0x04
|
||||||
#define AHCI_ENABLE (1 << 31)
|
#define AHCI_ENABLE (1 << 31)
|
||||||
|
|
|
@ -45,7 +45,7 @@ static struct dmi_system_id cable_dmi_table[] = {
|
||||||
.ident = "HP Pavilion N5430",
|
.ident = "HP Pavilion N5430",
|
||||||
.matches = {
|
.matches = {
|
||||||
DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
|
DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
|
||||||
DMI_MATCH(DMI_BOARD_NAME, "OmniBook N32N-736"),
|
DMI_MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ }
|
{ }
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include <linux/libata.h>
|
#include <linux/libata.h>
|
||||||
|
|
||||||
#define DRV_NAME "pata_hpt37x"
|
#define DRV_NAME "pata_hpt37x"
|
||||||
#define DRV_VERSION "0.6.6"
|
#define DRV_VERSION "0.6.7"
|
||||||
|
|
||||||
struct hpt_clock {
|
struct hpt_clock {
|
||||||
u8 xfer_speed;
|
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. */
|
/* Select the DPLL clock. */
|
||||||
pci_write_config_byte(dev, 0x5b, 0x21);
|
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++) {
|
for(adjust = 0; adjust < 8; adjust++) {
|
||||||
if (hpt37x_calibrate_dpll(dev))
|
if (hpt37x_calibrate_dpll(dev))
|
||||||
break;
|
break;
|
||||||
/* See if it'll settle at a fractionally different clock */
|
/* See if it'll settle at a fractionally different clock */
|
||||||
if ((adjust & 3) == 3) {
|
if (adjust & 1)
|
||||||
f_low --;
|
f_low -= adjust >> 1;
|
||||||
f_high ++;
|
else
|
||||||
}
|
f_high += adjust >> 1;
|
||||||
pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low);
|
pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100);
|
||||||
}
|
}
|
||||||
if (adjust == 8) {
|
if (adjust == 8) {
|
||||||
printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n");
|
printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n");
|
||||||
|
|
|
@ -1604,6 +1604,7 @@ early_param("pci", pci_setup);
|
||||||
device_initcall(pci_init);
|
device_initcall(pci_init);
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(pci_restore_bars);
|
EXPORT_SYMBOL_GPL(pci_restore_bars);
|
||||||
|
EXPORT_SYMBOL(__pci_reenable_device);
|
||||||
EXPORT_SYMBOL(pci_enable_device_bars);
|
EXPORT_SYMBOL(pci_enable_device_bars);
|
||||||
EXPORT_SYMBOL(pci_enable_device);
|
EXPORT_SYMBOL(pci_enable_device);
|
||||||
EXPORT_SYMBOL(pcim_enable_device);
|
EXPORT_SYMBOL(pcim_enable_device);
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* Functions internal to the PCI core code */
|
/* 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,
|
extern int pci_uevent(struct device *dev, char **envp, int num_envp,
|
||||||
char *buffer, int buffer_size);
|
char *buffer, int buffer_size);
|
||||||
extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
|
extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
|
||||||
|
|
|
@ -216,6 +216,8 @@ enum {
|
||||||
ATA_HOST_SIMPLEX = (1 << 0), /* Host is simplex, one DMA channel per host only */
|
ATA_HOST_SIMPLEX = (1 << 0), /* Host is simplex, one DMA channel per host only */
|
||||||
ATA_HOST_STARTED = (1 << 1), /* Host started */
|
ATA_HOST_STARTED = (1 << 1), /* Host started */
|
||||||
|
|
||||||
|
/* bits 24:31 of host->flags are reserved for LLD specific flags */
|
||||||
|
|
||||||
/* various lengths of time */
|
/* various lengths of time */
|
||||||
ATA_TMOUT_BOOT = 30 * HZ, /* heuristic */
|
ATA_TMOUT_BOOT = 30 * HZ, /* heuristic */
|
||||||
ATA_TMOUT_BOOT_QUICK = 7 * HZ, /* heuristic */
|
ATA_TMOUT_BOOT_QUICK = 7 * HZ, /* heuristic */
|
||||||
|
|
|
@ -534,6 +534,7 @@ static inline int pci_write_config_dword(struct pci_dev *dev, int where, u32 val
|
||||||
|
|
||||||
int __must_check pci_enable_device(struct pci_dev *dev);
|
int __must_check pci_enable_device(struct pci_dev *dev);
|
||||||
int __must_check pci_enable_device_bars(struct pci_dev *dev, int mask);
|
int __must_check pci_enable_device_bars(struct pci_dev *dev, int mask);
|
||||||
|
int __must_check __pci_reenable_device(struct pci_dev *);
|
||||||
int __must_check pcim_enable_device(struct pci_dev *pdev);
|
int __must_check pcim_enable_device(struct pci_dev *pdev);
|
||||||
void pcim_pin_device(struct pci_dev *pdev);
|
void pcim_pin_device(struct pci_dev *pdev);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue