aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/pci/delkin_cb.c
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-10-17 12:09:16 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-10-17 12:09:16 -0400
commit8c061a40c293660793dab83b75223e6eaaa04f8b (patch)
tree0e254768b183c3c043d430c07da82e690d2c19e8 /drivers/ide/pci/delkin_cb.c
parent41d1a3d31d097a31380b83eea0ec10ea1d040376 (diff)
delkin_cb: add PM support
* Factor out chipset initialization code from delkin_cb_probe() to delkin_cb_init_chipset(). * Assign ->init_chipset in struct delkin_cb_port_info. * Add delkin_cb_{suspend,resume}() (->suspend/->resume methods). Fixes kernel bugzilla bug #11735: http://bugzilla.kernel.org/show_bug.cgi?id=11735 Tested-by: bumble.bee@xs4all.nl Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/pci/delkin_cb.c')
-rw-r--r--drivers/ide/pci/delkin_cb.c63
1 files changed, 56 insertions, 7 deletions
diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/pci/delkin_cb.c
index 8689a706f537..8f1b2d9f0513 100644
--- a/drivers/ide/pci/delkin_cb.c
+++ b/drivers/ide/pci/delkin_cb.c
@@ -46,10 +46,27 @@ static const struct ide_port_ops delkin_cb_port_ops = {
46 .quirkproc = ide_undecoded_slave, 46 .quirkproc = ide_undecoded_slave,
47}; 47};
48 48
49static unsigned int delkin_cb_init_chipset(struct pci_dev *dev)
50{
51 unsigned long base = pci_resource_start(dev, 0);
52 int i;
53
54 outb(0x02, base + 0x1e); /* set nIEN to block interrupts */
55 inb(base + 0x17); /* read status to clear interrupts */
56
57 for (i = 0; i < sizeof(setup); ++i) {
58 if (setup[i])
59 outb(setup[i], base + i);
60 }
61
62 return 0;
63}
64
49static const struct ide_port_info delkin_cb_port_info = { 65static const struct ide_port_info delkin_cb_port_info = {
50 .port_ops = &delkin_cb_port_ops, 66 .port_ops = &delkin_cb_port_ops,
51 .host_flags = IDE_HFLAG_IO_32BIT | IDE_HFLAG_UNMASK_IRQS | 67 .host_flags = IDE_HFLAG_IO_32BIT | IDE_HFLAG_UNMASK_IRQS |
52 IDE_HFLAG_NO_DMA, 68 IDE_HFLAG_NO_DMA,
69 .init_chipset = delkin_cb_init_chipset,
53}; 70};
54 71
55static int __devinit 72static int __devinit
@@ -57,7 +74,7 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
57{ 74{
58 struct ide_host *host; 75 struct ide_host *host;
59 unsigned long base; 76 unsigned long base;
60 int i, rc; 77 int rc;
61 hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; 78 hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
62 79
63 rc = pci_enable_device(dev); 80 rc = pci_enable_device(dev);
@@ -72,12 +89,8 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
72 return rc; 89 return rc;
73 } 90 }
74 base = pci_resource_start(dev, 0); 91 base = pci_resource_start(dev, 0);
75 outb(0x02, base + 0x1e); /* set nIEN to block interrupts */ 92
76 inb(base + 0x17); /* read status to clear interrupts */ 93 delkin_cb_init_chipset(dev);
77 for (i = 0; i < sizeof(setup); ++i) {
78 if (setup[i])
79 outb(setup[i], base + i);
80 }
81 94
82 memset(&hw, 0, sizeof(hw)); 95 memset(&hw, 0, sizeof(hw));
83 ide_std_init_ports(&hw, base + 0x10, base + 0x1e); 96 ide_std_init_ports(&hw, base + 0x10, base + 0x1e);
@@ -110,6 +123,40 @@ delkin_cb_remove (struct pci_dev *dev)
110 pci_disable_device(dev); 123 pci_disable_device(dev);
111} 124}
112 125
126#ifdef CONFIG_PM
127static int delkin_cb_suspend(struct pci_dev *dev, pm_message_t state)
128{
129 pci_save_state(dev);
130 pci_disable_device(dev);
131 pci_set_power_state(dev, pci_choose_state(dev, state));
132
133 return 0;
134}
135
136static int delkin_cb_resume(struct pci_dev *dev)
137{
138 struct ide_host *host = pci_get_drvdata(dev);
139 int rc;
140
141 pci_set_power_state(dev, PCI_D0);
142
143 rc = pci_enable_device(dev);
144 if (rc)
145 return rc;
146
147 pci_restore_state(dev);
148 pci_set_master(dev);
149
150 if (host->init_chipset)
151 host->init_chipset(dev);
152
153 return 0;
154}
155#else
156#define delkin_cb_suspend NULL
157#define delkin_cb_resume NULL
158#endif
159
113static struct pci_device_id delkin_cb_pci_tbl[] __devinitdata = { 160static struct pci_device_id delkin_cb_pci_tbl[] __devinitdata = {
114 { 0x1145, 0xf021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 161 { 0x1145, 0xf021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
115 { 0x1145, 0xf024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 162 { 0x1145, 0xf024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
@@ -122,6 +169,8 @@ static struct pci_driver delkin_cb_pci_driver = {
122 .id_table = delkin_cb_pci_tbl, 169 .id_table = delkin_cb_pci_tbl,
123 .probe = delkin_cb_probe, 170 .probe = delkin_cb_probe,
124 .remove = delkin_cb_remove, 171 .remove = delkin_cb_remove,
172 .suspend = delkin_cb_suspend,
173 .resume = delkin_cb_resume,
125}; 174};
126 175
127static int __init delkin_cb_init(void) 176static int __init delkin_cb_init(void)