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

Configure Feed

Select the types of activity you want to include in your feed.

at v3.1 418 lines 10 kB view raw
1/* 2 * This file is part of wl1271 3 * 4 * Copyright (C) 2009-2010 Nokia Corporation 5 * 6 * Contact: Luciano Coelho <luciano.coelho@nokia.com> 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * version 2 as published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 * 02110-1301 USA 21 * 22 */ 23 24#include <linux/irq.h> 25#include <linux/module.h> 26#include <linux/vmalloc.h> 27#include <linux/mmc/sdio_func.h> 28#include <linux/mmc/sdio_ids.h> 29#include <linux/mmc/card.h> 30#include <linux/mmc/host.h> 31#include <linux/gpio.h> 32#include <linux/wl12xx.h> 33#include <linux/pm_runtime.h> 34 35#include "wl12xx.h" 36#include "wl12xx_80211.h" 37#include "io.h" 38 39#ifndef SDIO_VENDOR_ID_TI 40#define SDIO_VENDOR_ID_TI 0x0097 41#endif 42 43#ifndef SDIO_DEVICE_ID_TI_WL1271 44#define SDIO_DEVICE_ID_TI_WL1271 0x4076 45#endif 46 47static const struct sdio_device_id wl1271_devices[] __devinitconst = { 48 { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) }, 49 {} 50}; 51MODULE_DEVICE_TABLE(sdio, wl1271_devices); 52 53static void wl1271_sdio_set_block_size(struct wl1271 *wl, unsigned int blksz) 54{ 55 sdio_claim_host(wl->if_priv); 56 sdio_set_block_size(wl->if_priv, blksz); 57 sdio_release_host(wl->if_priv); 58} 59 60static inline struct sdio_func *wl_to_func(struct wl1271 *wl) 61{ 62 return wl->if_priv; 63} 64 65static struct device *wl1271_sdio_wl_to_dev(struct wl1271 *wl) 66{ 67 return &(wl_to_func(wl)->dev); 68} 69 70static irqreturn_t wl1271_hardirq(int irq, void *cookie) 71{ 72 struct wl1271 *wl = cookie; 73 unsigned long flags; 74 75 wl1271_debug(DEBUG_IRQ, "IRQ"); 76 77 /* complete the ELP completion */ 78 spin_lock_irqsave(&wl->wl_lock, flags); 79 set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); 80 if (wl->elp_compl) { 81 complete(wl->elp_compl); 82 wl->elp_compl = NULL; 83 } 84 85 if (test_bit(WL1271_FLAG_SUSPENDED, &wl->flags)) { 86 /* don't enqueue a work right now. mark it as pending */ 87 set_bit(WL1271_FLAG_PENDING_WORK, &wl->flags); 88 wl1271_debug(DEBUG_IRQ, "should not enqueue work"); 89 disable_irq_nosync(wl->irq); 90 pm_wakeup_event(wl1271_sdio_wl_to_dev(wl), 0); 91 spin_unlock_irqrestore(&wl->wl_lock, flags); 92 return IRQ_HANDLED; 93 } 94 spin_unlock_irqrestore(&wl->wl_lock, flags); 95 96 return IRQ_WAKE_THREAD; 97} 98 99static void wl1271_sdio_disable_interrupts(struct wl1271 *wl) 100{ 101 disable_irq(wl->irq); 102} 103 104static void wl1271_sdio_enable_interrupts(struct wl1271 *wl) 105{ 106 enable_irq(wl->irq); 107} 108 109static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, 110 size_t len, bool fixed) 111{ 112 int ret; 113 struct sdio_func *func = wl_to_func(wl); 114 115 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { 116 ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); 117 wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x", 118 addr, ((u8 *)buf)[0]); 119 } else { 120 if (fixed) 121 ret = sdio_readsb(func, buf, addr, len); 122 else 123 ret = sdio_memcpy_fromio(func, buf, addr, len); 124 125 wl1271_debug(DEBUG_SDIO, "sdio read 53 addr 0x%x, %zu bytes", 126 addr, len); 127 wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); 128 } 129 130 if (ret) 131 wl1271_error("sdio read failed (%d)", ret); 132} 133 134static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, 135 size_t len, bool fixed) 136{ 137 int ret; 138 struct sdio_func *func = wl_to_func(wl); 139 140 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { 141 sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); 142 wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x", 143 addr, ((u8 *)buf)[0]); 144 } else { 145 wl1271_debug(DEBUG_SDIO, "sdio write 53 addr 0x%x, %zu bytes", 146 addr, len); 147 wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); 148 149 if (fixed) 150 ret = sdio_writesb(func, addr, buf, len); 151 else 152 ret = sdio_memcpy_toio(func, addr, buf, len); 153 } 154 155 if (ret) 156 wl1271_error("sdio write failed (%d)", ret); 157} 158 159static int wl1271_sdio_power_on(struct wl1271 *wl) 160{ 161 struct sdio_func *func = wl_to_func(wl); 162 int ret; 163 164 /* If enabled, tell runtime PM not to power off the card */ 165 if (pm_runtime_enabled(&func->dev)) { 166 ret = pm_runtime_get_sync(&func->dev); 167 if (ret < 0) 168 goto out; 169 } else { 170 /* Runtime PM is disabled: power up the card manually */ 171 ret = mmc_power_restore_host(func->card->host); 172 if (ret < 0) 173 goto out; 174 } 175 176 sdio_claim_host(func); 177 sdio_enable_func(func); 178 179out: 180 return ret; 181} 182 183static int wl1271_sdio_power_off(struct wl1271 *wl) 184{ 185 struct sdio_func *func = wl_to_func(wl); 186 int ret; 187 188 sdio_disable_func(func); 189 sdio_release_host(func); 190 191 /* Power off the card manually, even if runtime PM is enabled. */ 192 ret = mmc_power_save_host(func->card->host); 193 if (ret < 0) 194 return ret; 195 196 /* If enabled, let runtime PM know the card is powered off */ 197 if (pm_runtime_enabled(&func->dev)) 198 ret = pm_runtime_put_sync(&func->dev); 199 200 return ret; 201} 202 203static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable) 204{ 205 if (enable) 206 return wl1271_sdio_power_on(wl); 207 else 208 return wl1271_sdio_power_off(wl); 209} 210 211static struct wl1271_if_operations sdio_ops = { 212 .read = wl1271_sdio_raw_read, 213 .write = wl1271_sdio_raw_write, 214 .power = wl1271_sdio_set_power, 215 .dev = wl1271_sdio_wl_to_dev, 216 .enable_irq = wl1271_sdio_enable_interrupts, 217 .disable_irq = wl1271_sdio_disable_interrupts, 218 .set_block_size = wl1271_sdio_set_block_size, 219}; 220 221static int __devinit wl1271_probe(struct sdio_func *func, 222 const struct sdio_device_id *id) 223{ 224 struct ieee80211_hw *hw; 225 const struct wl12xx_platform_data *wlan_data; 226 struct wl1271 *wl; 227 unsigned long irqflags; 228 mmc_pm_flag_t mmcflags; 229 int ret; 230 231 /* We are only able to handle the wlan function */ 232 if (func->num != 0x02) 233 return -ENODEV; 234 235 hw = wl1271_alloc_hw(); 236 if (IS_ERR(hw)) 237 return PTR_ERR(hw); 238 239 wl = hw->priv; 240 241 wl->if_priv = func; 242 wl->if_ops = &sdio_ops; 243 244 /* Grab access to FN0 for ELP reg. */ 245 func->card->quirks |= MMC_QUIRK_LENIENT_FN0; 246 247 /* Use block mode for transferring over one block size of data */ 248 func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; 249 250 wlan_data = wl12xx_get_platform_data(); 251 if (IS_ERR(wlan_data)) { 252 ret = PTR_ERR(wlan_data); 253 wl1271_error("missing wlan platform data: %d", ret); 254 goto out_free; 255 } 256 257 wl->irq = wlan_data->irq; 258 wl->ref_clock = wlan_data->board_ref_clock; 259 wl->tcxo_clock = wlan_data->board_tcxo_clock; 260 wl->platform_quirks = wlan_data->platform_quirks; 261 262 if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) 263 irqflags = IRQF_TRIGGER_RISING; 264 else 265 irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT; 266 267 ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq, 268 irqflags, 269 DRIVER_NAME, wl); 270 if (ret < 0) { 271 wl1271_error("request_irq() failed: %d", ret); 272 goto out_free; 273 } 274 275 ret = enable_irq_wake(wl->irq); 276 if (!ret) { 277 wl->irq_wake_enabled = true; 278 device_init_wakeup(wl1271_sdio_wl_to_dev(wl), 1); 279 280 /* if sdio can keep power while host is suspended, enable wow */ 281 mmcflags = sdio_get_host_pm_caps(func); 282 wl1271_debug(DEBUG_SDIO, "sdio PM caps = 0x%x", mmcflags); 283 284 if (mmcflags & MMC_PM_KEEP_POWER) 285 hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY; 286 } 287 disable_irq(wl->irq); 288 289 ret = wl1271_init_ieee80211(wl); 290 if (ret) 291 goto out_irq; 292 293 ret = wl1271_register_hw(wl); 294 if (ret) 295 goto out_irq; 296 297 sdio_set_drvdata(func, wl); 298 299 /* Tell PM core that we don't need the card to be powered now */ 300 pm_runtime_put_noidle(&func->dev); 301 302 return 0; 303 304 out_irq: 305 free_irq(wl->irq, wl); 306 307 out_free: 308 wl1271_free_hw(wl); 309 310 return ret; 311} 312 313static void __devexit wl1271_remove(struct sdio_func *func) 314{ 315 struct wl1271 *wl = sdio_get_drvdata(func); 316 317 /* Undo decrement done above in wl1271_probe */ 318 pm_runtime_get_noresume(&func->dev); 319 320 wl1271_unregister_hw(wl); 321 if (wl->irq_wake_enabled) { 322 device_init_wakeup(wl1271_sdio_wl_to_dev(wl), 0); 323 disable_irq_wake(wl->irq); 324 } 325 free_irq(wl->irq, wl); 326 wl1271_free_hw(wl); 327} 328 329#ifdef CONFIG_PM 330static int wl1271_suspend(struct device *dev) 331{ 332 /* Tell MMC/SDIO core it's OK to power down the card 333 * (if it isn't already), but not to remove it completely */ 334 struct sdio_func *func = dev_to_sdio_func(dev); 335 struct wl1271 *wl = sdio_get_drvdata(func); 336 mmc_pm_flag_t sdio_flags; 337 int ret = 0; 338 339 wl1271_debug(DEBUG_MAC80211, "wl1271 suspend. wow_enabled: %d", 340 wl->wow_enabled); 341 342 /* check whether sdio should keep power */ 343 if (wl->wow_enabled) { 344 sdio_flags = sdio_get_host_pm_caps(func); 345 346 if (!(sdio_flags & MMC_PM_KEEP_POWER)) { 347 wl1271_error("can't keep power while host " 348 "is suspended"); 349 ret = -EINVAL; 350 goto out; 351 } 352 353 /* keep power while host suspended */ 354 ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); 355 if (ret) { 356 wl1271_error("error while trying to keep power"); 357 goto out; 358 } 359 360 /* release host */ 361 sdio_release_host(func); 362 } 363out: 364 return ret; 365} 366 367static int wl1271_resume(struct device *dev) 368{ 369 struct sdio_func *func = dev_to_sdio_func(dev); 370 struct wl1271 *wl = sdio_get_drvdata(func); 371 372 wl1271_debug(DEBUG_MAC80211, "wl1271 resume"); 373 if (wl->wow_enabled) { 374 /* claim back host */ 375 sdio_claim_host(func); 376 } 377 378 return 0; 379} 380 381static const struct dev_pm_ops wl1271_sdio_pm_ops = { 382 .suspend = wl1271_suspend, 383 .resume = wl1271_resume, 384}; 385#endif 386 387static struct sdio_driver wl1271_sdio_driver = { 388 .name = "wl1271_sdio", 389 .id_table = wl1271_devices, 390 .probe = wl1271_probe, 391 .remove = __devexit_p(wl1271_remove), 392#ifdef CONFIG_PM 393 .drv = { 394 .pm = &wl1271_sdio_pm_ops, 395 }, 396#endif 397}; 398 399static int __init wl1271_init(void) 400{ 401 return sdio_register_driver(&wl1271_sdio_driver); 402} 403 404static void __exit wl1271_exit(void) 405{ 406 sdio_unregister_driver(&wl1271_sdio_driver); 407} 408 409module_init(wl1271_init); 410module_exit(wl1271_exit); 411 412MODULE_LICENSE("GPL"); 413MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); 414MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); 415MODULE_FIRMWARE(WL1271_FW_NAME); 416MODULE_FIRMWARE(WL128X_FW_NAME); 417MODULE_FIRMWARE(WL127X_AP_FW_NAME); 418MODULE_FIRMWARE(WL128X_AP_FW_NAME);