Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Alex Dubov and committed by
Pierre Ossman
055b8224 36f021b5

+26 -15
+24 -3
drivers/misc/tifm_7xx1.c
··· 105 105 == TIFM_TYPE_XD) 106 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 110 /* wait for power to stabilize */ 110 111 msleep(20); 111 112 for (cnt = 16; cnt <= 256; cnt <<= 1) { ··· 123 122 return (readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7; 124 123 } 125 124 125 + inline static void tifm_7xx1_sock_power_off(char __iomem *sock_addr) 126 + { 127 + writel((~TIFM_CTRL_POWER_MASK) & readl(sock_addr + SOCK_CONTROL), 128 + sock_addr + SOCK_CONTROL); 129 + } 130 + 126 131 inline static char __iomem * 127 132 tifm_7xx1_sock_addr(char __iomem *base_addr, unsigned int sock_num) 128 133 { ··· 140 133 struct tifm_adapter *fm = container_of(work, struct tifm_adapter, 141 134 media_switcher); 142 135 struct tifm_dev *sock; 136 + char __iomem *sock_addr; 143 137 unsigned long flags; 144 138 unsigned char media_id; 145 139 unsigned int socket_change_set, cnt; ··· 166 158 "%s : demand removing card from socket %u:%u\n", 167 159 fm->cdev.class_id, fm->id, cnt); 168 160 fm->sockets[cnt] = NULL; 161 + sock_addr = sock->addr; 169 162 spin_unlock_irqrestore(&fm->lock, flags); 170 163 device_unregister(&sock->dev); 171 164 spin_lock_irqsave(&fm->lock, flags); 172 - writel(0x0e00, tifm_7xx1_sock_addr(fm->addr, cnt) 173 - + SOCK_CONTROL); 165 + tifm_7xx1_sock_power_off(sock_addr); 166 + writel(0x0e00, sock_addr + SOCK_CONTROL); 174 167 } 175 168 176 169 spin_unlock_irqrestore(&fm->lock, flags); ··· 214 205 215 206 static int tifm_7xx1_suspend(struct pci_dev *dev, pm_message_t state) 216 207 { 208 + struct tifm_adapter *fm = pci_get_drvdata(dev); 209 + int cnt; 210 + 217 211 dev_dbg(&dev->dev, "suspending host\n"); 212 + 213 + for (cnt = 0; cnt < fm->num_sockets; cnt++) { 214 + if (fm->sockets[cnt]) 215 + tifm_7xx1_sock_power_off(fm->sockets[cnt]->addr); 216 + } 218 217 219 218 pci_save_state(dev); 220 219 pci_enable_wake(dev, pci_choose_state(dev, state), 0); ··· 374 357 static void tifm_7xx1_remove(struct pci_dev *dev) 375 358 { 376 359 struct tifm_adapter *fm = pci_get_drvdata(dev); 360 + int cnt; 377 361 378 362 fm->eject = tifm_7xx1_dummy_eject; 379 363 writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE); ··· 382 364 free_irq(dev->irq, fm); 383 365 384 366 tifm_remove_adapter(fm); 367 + 368 + for (cnt = 0; cnt < fm->num_sockets; cnt++) 369 + tifm_7xx1_sock_power_off(tifm_7xx1_sock_addr(fm->addr, cnt)); 385 370 386 371 pci_set_drvdata(dev, NULL); 387 372
+1 -12
drivers/mmc/host/tifm_sd.c
··· 1021 1021 mmc_remove_host(mmc); 1022 1022 dev_dbg(&sock->dev, "after remove\n"); 1023 1023 1024 - /* The meaning of the bit majority in this constant is unknown. */ 1025 - writel(0xfff8 & readl(sock->addr + SOCK_CONTROL), 1026 - sock->addr + SOCK_CONTROL); 1027 - 1028 1024 mmc_free_host(mmc); 1029 1025 } 1030 1026 ··· 1028 1032 1029 1033 static int tifm_sd_suspend(struct tifm_dev *sock, pm_message_t state) 1030 1034 { 1031 - struct mmc_host *mmc = tifm_get_drvdata(sock); 1032 - int rc; 1033 - 1034 - rc = mmc_suspend_host(mmc, state); 1035 - /* The meaning of the bit majority in this constant is unknown. */ 1036 - writel(0xfff8 & readl(sock->addr + SOCK_CONTROL), 1037 - sock->addr + SOCK_CONTROL); 1038 - return rc; 1035 + return mmc_suspend_host(tifm_get_drvdata(sock), state); 1039 1036 } 1040 1037 1041 1038 static int tifm_sd_resume(struct tifm_dev *sock)
+1
include/linux/tifm.h
··· 63 63 64 64 #define TIFM_CTRL_LED 0x00000040 65 65 #define TIFM_CTRL_FAST_CLK 0x00000100 66 + #define TIFM_CTRL_POWER_MASK 0x00000007 66 67 67 68 #define TIFM_SOCK_STATE_OCCUPIED 0x00000008 68 69 #define TIFM_SOCK_STATE_POWERED 0x00000080