aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorReinette Chatre <reinette.chatre@intel.com>2009-12-10 17:37:22 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-12-21 11:31:57 -0500
commitf8701fe3aec24fcfb0dfa19aab47904611f96daf (patch)
treec6b415d666c7db75f3606467f3d8fbced1d73e43 /drivers
parent64a76b504b04b5da16d1e7658a95dd126594e02f (diff)
iwlwifi: power up all devices for EEPROM read
Recent commits "iwlwifi: remove power-wasting calls to apm_ops.init()" and "iwlagn: power up device before initializing EEPROM" had the goal of reducing device power consumption from the time the module is loaded until the interface is brought up and the device's power saving mechanisms kick in. The idea is that once the module is loaded there is no need for the device to consume power until the interface is brought up. With the current solution the device is only powered up during EEPROM read, and then so also only if the EEPROM type is OTP. We have found that on certain platforms even non-OTP devices require power to be up during EEPROM read. On these platforms the driver never loads and the system log contains the following: iwlagn 0000:03:00.0: MAC is in deep sleep!. CSR_GP_CNTRL = 0x080403D8 We thus now power up all devices during EEPROM read. Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c14
2 files changed, 6 insertions, 16 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index a7bfae01f19b..1ec8cb4d5eae 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -77,8 +77,7 @@
77 * The MAC (uCode processor, etc.) does not need to be powered up for accessing 77 * The MAC (uCode processor, etc.) does not need to be powered up for accessing
78 * the CSR registers. 78 * the CSR registers.
79 * 79 *
80 * NOTE: Newer devices using one-time-programmable (OTP) memory 80 * NOTE: Device does need to be awake in order to read this memory
81 * require device to be awake in order to read this memory
82 * via CSR_EEPROM and CSR_OTP registers 81 * via CSR_EEPROM and CSR_OTP registers
83 */ 82 */
84#define CSR_BASE (0x000) 83#define CSR_BASE (0x000)
@@ -111,9 +110,8 @@
111/* 110/*
112 * EEPROM and OTP (one-time-programmable) memory reads 111 * EEPROM and OTP (one-time-programmable) memory reads
113 * 112 *
114 * NOTE: For (newer) devices using OTP, device must be awake, initialized via 113 * NOTE: Device must be awake, initialized via apm_ops.init(),
115 * apm_ops.init() in order to read. Older devices (3945/4965/5000) 114 * in order to read.
116 * use EEPROM and do not require this.
117 */ 115 */
118#define CSR_EEPROM_REG (CSR_BASE+0x02c) 116#define CSR_EEPROM_REG (CSR_BASE+0x02c)
119#define CSR_EEPROM_GP (CSR_BASE+0x030) 117#define CSR_EEPROM_GP (CSR_BASE+0x030)
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 3946e5c03f81..72f0d77955cf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -518,10 +518,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
518 } 518 }
519 e = (u16 *)priv->eeprom; 519 e = (u16 *)priv->eeprom;
520 520
521 if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) { 521 priv->cfg->ops->lib->apm_ops.init(priv);
522 /* OTP reads require powered-up chip */
523 priv->cfg->ops->lib->apm_ops.init(priv);
524 }
525 522
526 ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv); 523 ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv);
527 if (ret < 0) { 524 if (ret < 0) {
@@ -570,13 +567,6 @@ int iwl_eeprom_init(struct iwl_priv *priv)
570 e[cache_addr / 2] = eeprom_data; 567 e[cache_addr / 2] = eeprom_data;
571 cache_addr += sizeof(u16); 568 cache_addr += sizeof(u16);
572 } 569 }
573
574 /*
575 * Now that OTP reads are complete, reset chip to save
576 * power until we load uCode during "up".
577 */
578 priv->cfg->ops->lib->apm_ops.stop(priv);
579
580 } else { 570 } else {
581 /* eeprom is an array of 16bit values */ 571 /* eeprom is an array of 16bit values */
582 for (addr = 0; addr < sz; addr += sizeof(u16)) { 572 for (addr = 0; addr < sz; addr += sizeof(u16)) {
@@ -603,6 +593,8 @@ done:
603err: 593err:
604 if (ret) 594 if (ret)
605 iwl_eeprom_free(priv); 595 iwl_eeprom_free(priv);
596 /* Reset chip to save power until we load uCode during "up". */
597 priv->cfg->ops->lib->apm_ops.stop(priv);
606alloc_err: 598alloc_err:
607 return ret; 599 return ret;
608} 600}