Skip to content

Commit

Permalink
sc1200: remove pointless hwif lookup loop
Browse files Browse the repository at this point in the history
Save PCI regs values for both IDE ports in one buffer, in order to eliminate
a needless and ugly loop across all hwifs, searching for our PCI device.

Partially based on the previous patch by Jeff Garzik.

Cc: Jeff Garzik <jeff@garzik.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
  • Loading branch information
Bartlomiej Zolnierkiewicz committed Jan 25, 2008
1 parent 866e2ec commit 7c0e266
Showing 1 changed file with 38 additions and 70 deletions.
108 changes: 38 additions & 70 deletions drivers/ide/pci/sc1200.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,66 +260,39 @@ static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio)
}

#ifdef CONFIG_PM
static ide_hwif_t *lookup_pci_dev (ide_hwif_t *prev, struct pci_dev *dev)
{
int h;

for (h = 0; h < MAX_HWIFS; h++) {
ide_hwif_t *hwif = &ide_hwifs[h];
if (prev) {
if (hwif == prev)
prev = NULL; // found previous, now look for next match
} else {
if (hwif && hwif->pci_dev == dev)
return hwif; // found next match
}
}
return NULL; // not found
}

typedef struct sc1200_saved_state_s {
__u32 regs[4];
} sc1200_saved_state_t;

struct sc1200_saved_state {
u32 regs[8];
};

static int sc1200_suspend (struct pci_dev *dev, pm_message_t state)
{
ide_hwif_t *hwif = NULL;

printk("SC1200: suspend(%u)\n", state.event);

/*
* we only save state when going from full power to less
*/
if (state.event == PM_EVENT_ON) {
// we only save state when going from full power to less

//
// Loop over all interfaces that are part of this PCI device:
//
while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) {
sc1200_saved_state_t *ss;
unsigned int basereg, r;
//
// allocate a permanent save area, if not already allocated
//
ss = (sc1200_saved_state_t *)hwif->config_data;
if (ss == NULL) {
ss = kmalloc(sizeof(sc1200_saved_state_t), GFP_KERNEL);
if (ss == NULL)
return -ENOMEM;
hwif->config_data = (unsigned long)ss;
}
ss = (sc1200_saved_state_t *)hwif->config_data;
//
// Save timing registers: this may be unnecessary if
// BIOS also does it
//
basereg = hwif->channel ? 0x50 : 0x40;
for (r = 0; r < 4; ++r) {
pci_read_config_dword (hwif->pci_dev, basereg + (r<<2), &ss->regs[r]);
}
struct sc1200_saved_state *ss;
unsigned int r;

/*
* allocate a permanent save area, if not already allocated
*/
ss = (struct sc1200_saved_state *)pci_get_drvdata(dev);
if (ss == NULL) {
ss = kmalloc(sizeof(*ss), GFP_KERNEL);
if (ss == NULL)
return -ENOMEM;
pci_set_drvdata(dev, ss);
}
}

/* You don't need to iterate over disks -- sysfs should have done that for you already */
/*
* save timing registers
* (this may be unnecessary if BIOS also does it)
*/
for (r = 0; r < 8; r++)
pci_read_config_dword(dev, 0x40 + r * 4, &ss->regs[r]);
}

pci_disable_device(dev);
pci_set_power_state(dev, pci_choose_state(dev, state));
Expand All @@ -328,30 +301,25 @@ static int sc1200_suspend (struct pci_dev *dev, pm_message_t state)

static int sc1200_resume (struct pci_dev *dev)
{
ide_hwif_t *hwif = NULL;
int i;
struct sc1200_saved_state *ss;
unsigned int r;
int i;

i = pci_enable_device(dev);
if (i)
return i;

//
// loop over all interfaces that are part of this pci device:
//
while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) {
unsigned int basereg, r;
sc1200_saved_state_t *ss = (sc1200_saved_state_t *)hwif->config_data;

//
// Restore timing registers: this may be unnecessary if BIOS also does it
//
basereg = hwif->channel ? 0x50 : 0x40;
if (ss != NULL) {
for (r = 0; r < 4; ++r) {
pci_write_config_dword(hwif->pci_dev, basereg + (r<<2), ss->regs[r]);
}
}
ss = (struct sc1200_saved_state *)pci_get_drvdata(dev);

/*
* restore timing registers
* (this may be unnecessary if BIOS also does it)
*/
if (ss) {
for (r = 0; r < 8; r++)
pci_write_config_dword(dev, 0x40 + r * 4, ss->regs[r]);
}

return 0;
}
#endif
Expand Down

0 comments on commit 7c0e266

Please sign in to comment.