aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/tifm_7xx1.c
diff options
context:
space:
mode:
authorAlex Dubov <oakad@yahoo.com>2007-05-01 23:14:55 -0400
committerPierre Ossman <drzeus@drzeus.cx>2007-05-08 16:41:47 -0400
commit055b8224140e7a7515bf8113ce675d58abffedf1 (patch)
tree32528d9920e9819079fce8e0d43f06d75c28da01 /drivers/misc/tifm_7xx1.c
parent36f021b579d195cdc5fa6f3e2bab198b4bf70643 (diff)
disable socket power in adapter driver instead of media one
Socket power must be fully controlled by adapter driver. This also prevents unnecessary power-off of the socket when media driver is unloaded, yet media remains in the socket. Signed-off-by: Alex Dubov <oakad@yahoo.com> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/misc/tifm_7xx1.c')
-rw-r--r--drivers/misc/tifm_7xx1.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c
index 1ba6c085419a..c08ad8f823d2 100644
--- a/drivers/misc/tifm_7xx1.c
+++ b/drivers/misc/tifm_7xx1.c
@@ -105,7 +105,8 @@ static unsigned char tifm_7xx1_toggle_sock_power(char __iomem *sock_addr)
105 == TIFM_TYPE_XD) 105 == TIFM_TYPE_XD)
106 msleep(40); 106 msleep(40);
107 107
108 writel((s_state & 7) | 0x0c00, sock_addr + SOCK_CONTROL); 108 writel((s_state & TIFM_CTRL_POWER_MASK) | 0x0c00,
109 sock_addr + SOCK_CONTROL);
109 /* wait for power to stabilize */ 110 /* wait for power to stabilize */
110 msleep(20); 111 msleep(20);
111 for (cnt = 16; cnt <= 256; cnt <<= 1) { 112 for (cnt = 16; cnt <= 256; cnt <<= 1) {
@@ -122,6 +123,12 @@ static unsigned char tifm_7xx1_toggle_sock_power(char __iomem *sock_addr)
122 return (readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7; 123 return (readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7;
123} 124}
124 125
126inline static void tifm_7xx1_sock_power_off(char __iomem *sock_addr)
127{
128 writel((~TIFM_CTRL_POWER_MASK) & readl(sock_addr + SOCK_CONTROL),
129 sock_addr + SOCK_CONTROL);
130}
131
125inline static char __iomem * 132inline static char __iomem *
126tifm_7xx1_sock_addr(char __iomem *base_addr, unsigned int sock_num) 133tifm_7xx1_sock_addr(char __iomem *base_addr, unsigned int sock_num)
127{ 134{
@@ -133,6 +140,7 @@ static void tifm_7xx1_switch_media(struct work_struct *work)
133 struct tifm_adapter *fm = container_of(work, struct tifm_adapter, 140 struct tifm_adapter *fm = container_of(work, struct tifm_adapter,
134 media_switcher); 141 media_switcher);
135 struct tifm_dev *sock; 142 struct tifm_dev *sock;
143 char __iomem *sock_addr;
136 unsigned long flags; 144 unsigned long flags;
137 unsigned char media_id; 145 unsigned char media_id;
138 unsigned int socket_change_set, cnt; 146 unsigned int socket_change_set, cnt;
@@ -158,11 +166,12 @@ static void tifm_7xx1_switch_media(struct work_struct *work)
158 "%s : demand removing card from socket %u:%u\n", 166 "%s : demand removing card from socket %u:%u\n",
159 fm->cdev.class_id, fm->id, cnt); 167 fm->cdev.class_id, fm->id, cnt);
160 fm->sockets[cnt] = NULL; 168 fm->sockets[cnt] = NULL;
169 sock_addr = sock->addr;
161 spin_unlock_irqrestore(&fm->lock, flags); 170 spin_unlock_irqrestore(&fm->lock, flags);
162 device_unregister(&sock->dev); 171 device_unregister(&sock->dev);
163 spin_lock_irqsave(&fm->lock, flags); 172 spin_lock_irqsave(&fm->lock, flags);
164 writel(0x0e00, tifm_7xx1_sock_addr(fm->addr, cnt) 173 tifm_7xx1_sock_power_off(sock_addr);
165 + SOCK_CONTROL); 174 writel(0x0e00, sock_addr + SOCK_CONTROL);
166 } 175 }
167 176
168 spin_unlock_irqrestore(&fm->lock, flags); 177 spin_unlock_irqrestore(&fm->lock, flags);
@@ -205,8 +214,16 @@ static void tifm_7xx1_switch_media(struct work_struct *work)
205 214
206static int tifm_7xx1_suspend(struct pci_dev *dev, pm_message_t state) 215static int tifm_7xx1_suspend(struct pci_dev *dev, pm_message_t state)
207{ 216{
217 struct tifm_adapter *fm = pci_get_drvdata(dev);
218 int cnt;
219
208 dev_dbg(&dev->dev, "suspending host\n"); 220 dev_dbg(&dev->dev, "suspending host\n");
209 221
222 for (cnt = 0; cnt < fm->num_sockets; cnt++) {
223 if (fm->sockets[cnt])
224 tifm_7xx1_sock_power_off(fm->sockets[cnt]->addr);
225 }
226
210 pci_save_state(dev); 227 pci_save_state(dev);
211 pci_enable_wake(dev, pci_choose_state(dev, state), 0); 228 pci_enable_wake(dev, pci_choose_state(dev, state), 0);
212 pci_disable_device(dev); 229 pci_disable_device(dev);
@@ -357,6 +374,7 @@ err_out:
357static void tifm_7xx1_remove(struct pci_dev *dev) 374static void tifm_7xx1_remove(struct pci_dev *dev)
358{ 375{
359 struct tifm_adapter *fm = pci_get_drvdata(dev); 376 struct tifm_adapter *fm = pci_get_drvdata(dev);
377 int cnt;
360 378
361 fm->eject = tifm_7xx1_dummy_eject; 379 fm->eject = tifm_7xx1_dummy_eject;
362 writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE); 380 writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
@@ -365,6 +383,9 @@ static void tifm_7xx1_remove(struct pci_dev *dev)
365 383
366 tifm_remove_adapter(fm); 384 tifm_remove_adapter(fm);
367 385
386 for (cnt = 0; cnt < fm->num_sockets; cnt++)
387 tifm_7xx1_sock_power_off(tifm_7xx1_sock_addr(fm->addr, cnt));
388
368 pci_set_drvdata(dev, NULL); 389 pci_set_drvdata(dev, NULL);
369 390
370 iounmap(fm->addr); 391 iounmap(fm->addr);