Revert "net: wireless: bcmdhd: add support for runtime pm"
This reverts commit 357e395483602d2da358f7dee30b583e9d6fa1d2.
diff --git a/drivers/net/wireless/bcmdhd/Makefile b/drivers/net/wireless/bcmdhd/Makefile
index b1cf096..048bb72 100644
--- a/drivers/net/wireless/bcmdhd/Makefile
+++ b/drivers/net/wireless/bcmdhd/Makefile
@@ -171,11 +171,6 @@
ifneq ($(CONFIG_BCMDHD_PCIE),)
DHDCFLAGS += -DPCIE_FULL_DONGLE -DBCMPCIE -DCUSTOM_DPC_PRIO_SETTING=-1
-
-ifneq ($(CONFIG_PM_RUNTIME),)
- DHDCFLAGS += -DAUTO_SUSPEND_TIMEOUT=1
-endif
-
# tput enhancement
DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64
DHDCFLAGS += -DCUSTOM_AMPDU_MPDU=32
diff --git a/drivers/net/wireless/bcmdhd/dhd.h b/drivers/net/wireless/bcmdhd/dhd.h
index 31160e3..7a2334c 100644
--- a/drivers/net/wireless/bcmdhd/dhd.h
+++ b/drivers/net/wireless/bcmdhd/dhd.h
@@ -170,15 +170,6 @@
DUMP_MEMFILE_MAX
};
-#ifdef CONFIG_PM_RUNTIME
-enum pci_power_state {
- PCI_PM_RT_ACTIVE,
- PCI_PM_RT_SUSPENDED,
- PCI_PM_SYS_SUSPENDED,
- PCI_PM_NETIF_SUSPENDED
-};
-#endif /* CONFIG_PM_RUNTIME */
-
/* Packet alignment for most efficient SDIO (can change based on platform) */
#ifndef DHD_SDALIGN
#define DHD_SDALIGN 32
@@ -449,9 +440,6 @@
bool ndo_enable; /* ND offload feature enable */
bool ndo_host_ip_overflow; /* # of host ip addr exceed FW capacity */
#endif /* NDO_CONFIG_SUPPORT */
-#ifdef CONFIG_PM_RUNTIME
- atomic_t runtime_pm_status;
-#endif /* CONFIG_PM_RUNTIME */
} dhd_pub_t;
typedef struct {
diff --git a/drivers/net/wireless/bcmdhd/dhd_bus.h b/drivers/net/wireless/bcmdhd/dhd_bus.h
index 6783a1b..efcbab2 100644
--- a/drivers/net/wireless/bcmdhd/dhd_bus.h
+++ b/drivers/net/wireless/bcmdhd/dhd_bus.h
@@ -186,10 +186,5 @@
extern int dhd_bus_release_dongle(struct dhd_bus *bus);
extern int dhd_bus_request_irq(struct dhd_bus *bus);
-#ifdef CONFIG_PM_RUNTIME
-extern struct device * dhd_bus_to_dev(struct dhd_bus *bus);
-extern void dhdpci_bus_read_frames(struct dhd_bus *bus);
-#endif /* CONFIG_PM_RUNTIME */
-
#endif /* BCMPCIE */
#endif /* _dhd_bus_h_ */
diff --git a/drivers/net/wireless/bcmdhd/dhd_common.c b/drivers/net/wireless/bcmdhd/dhd_common.c
index dd0475f..0d8ba34 100644
--- a/drivers/net/wireless/bcmdhd/dhd_common.c
+++ b/drivers/net/wireless/bcmdhd/dhd_common.c
@@ -86,7 +86,6 @@
#include <wl_iw.h>
-#include <linux/pm_runtime.h>
#ifdef SOFTAP
char fw_path2[MOD_PARAM_PATHLEN];
@@ -349,14 +348,6 @@
{
int ret = BCME_ERROR;
- if (atomic_read(&dhd_pub->runtime_pm_status) >= PCI_PM_SYS_SUSPENDED)
- return -EHOSTDOWN;
-
- if (pm_runtime_get_sync(dhd_bus_to_dev(dhd_pub->bus)) < 0) {
- DHD_RPM(("%s: pm_runtime_get_sync error. \n", __FUNCTION__));
- return BCME_ERROR;
- }
-
if (dhd_os_proto_block(dhd_pub))
{
#if defined(WL_WLC_SHIM)
@@ -390,9 +381,6 @@
}
- pm_runtime_mark_last_busy(dhd_bus_to_dev(dhd_pub->bus));
- pm_runtime_put_autosuspend(dhd_bus_to_dev(dhd_pub->bus));
-
return ret;
}
diff --git a/drivers/net/wireless/bcmdhd/dhd_dbg.h b/drivers/net/wireless/bcmdhd/dhd_dbg.h
index d2f69b6..bb3da6b 100644
--- a/drivers/net/wireless/bcmdhd/dhd_dbg.h
+++ b/drivers/net/wireless/bcmdhd/dhd_dbg.h
@@ -50,7 +50,6 @@
#define DHD_PNO(args) do {if (dhd_msg_level & DHD_PNO_VAL) printf args;} while (0)
#define DHD_RTT(args) do {if (dhd_msg_level & DHD_RTT_VAL) printf args;} while (0)
#define DHD_PKT_MON(args) do {if (dhd_msg_level & DHD_PKT_MON_VAL) printf args;} while (0)
-#define DHD_RPM(args) do {if (dhd_msg_level & DHD_RPM_VAL) printf args;} while (0)
#define DHD_TRACE_HW4 DHD_TRACE
@@ -74,7 +73,6 @@
#define DHD_RTT_ON() (dhd_msg_level & DHD_RTT_VAL)
#define DHD_PKT_MON_ON() (dhd_msg_level & DHD_PKT_MON_VAL)
#define DHD_PKT_MON_DUMP_ON() (dhd_msg_level & DHD_PKT_MON_DUMP_VAL)
-#define DHD_RPM_ON() (dhd_msg_level & DHD_RPM_VAL)
#else /* defined(BCMDBG) || defined(DHD_DEBUG) */
@@ -118,7 +116,6 @@
#define DHD_RTT_ON() 0
#define DHD_PKT_MON_ON() 0
#define DHD_PKT_MON_DUMP_ON() 0
-#define DHD_RPM_ON() 0
#endif
#define DHD_LOG(args)
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c
index 899c4527a..ec49855 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -50,7 +50,6 @@
#include <linux/ip.h>
#include <linux/reboot.h>
#include <linux/notifier.h>
-#include <linux/workqueue.h>
#include <net/addrconf.h>
#ifdef ENABLE_ADAPTIVE_SCHED
#include <linux/cpufreq.h>
@@ -257,7 +256,6 @@
#include <linux/earlysuspend.h>
#endif /* defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) */
-#include <linux/pm_runtime.h>
#ifdef PKT_FILTER_SUPPORT
extern void dhd_pktfilter_offload_set(dhd_pub_t * dhd, char *arg);
@@ -471,8 +469,6 @@
struct notifier_block sar_notifier;
s32 sar_enable;
#endif
- struct workqueue_struct *rx_tx_wq;
-
} dhd_info_t;
#define DHDIF_FWDER(dhdif) FALSE
@@ -2749,95 +2745,6 @@
#endif
}
-struct dhd_rx_tx_work {
- struct work_struct work;
- struct sk_buff *skb;
- struct net_device *net;
- struct dhd_pub *pub;
-};
-
-void dhd_rx_wq_adapter(struct work_struct *ptr)
-{
- struct dhd_rx_tx_work *work;
- struct dhd_pub * pub;
-
- work = container_of(ptr, struct dhd_rx_tx_work, work);
-
- pub = work->pub;
-
- if (pub->busstate == DHD_BUS_DOWN) {
- kfree(work);
- return;
- }
-
- if (atomic_read(&pub->runtime_pm_status) >= PCI_PM_SYS_SUSPENDED) {
- kfree(work);
- return;
- }
-
- if (pm_runtime_get_sync(dhd_bus_to_dev(pub->bus)) >= 0) {
- dhdpci_bus_read_frames(pub->bus);
- pm_runtime_mark_last_busy(dhd_bus_to_dev(pub->bus));
- pm_runtime_put_autosuspend(dhd_bus_to_dev(pub->bus));
- }
- kfree(work);
-}
-
-void dhd_start_xmit_wq_adapter(struct work_struct *ptr)
-{
- struct dhd_rx_tx_work *work;
- int ret;
- dhd_info_t *dhd;
- struct dhd_bus * bus;
-
- work = container_of(ptr, struct dhd_rx_tx_work, work);
-
- dhd = DHD_DEV_INFO(work->net);
-
- bus = dhd->pub.bus;
-
- if (atomic_read(&dhd->pub.runtime_pm_status) >= PCI_PM_SYS_SUSPENDED) {
- kfree_skb(work->skb);
- kfree(work);
- return;
- }
-
- if (pm_runtime_get_sync(dhd_bus_to_dev(bus)) >= 0) {
- ret = dhd_start_xmit(work->skb, work->net);
- pm_runtime_mark_last_busy(dhd_bus_to_dev(bus));
- pm_runtime_put_autosuspend(dhd_bus_to_dev(bus));
- }
- kfree(work);
-
- if (ret)
- netdev_err(work->net,
- "error: dhd_start_xmit():%d\n", ret);
-}
-
-int BCMFASTPATH
-dhd_start_xmit_queue_work(struct sk_buff *skb, struct net_device *net)
-{
- struct dhd_rx_tx_work *start_xmit_work;
- dhd_info_t *dhd = DHD_DEV_INFO(net);
-
- if (atomic_read(&dhd->pub.runtime_pm_status) >= PCI_PM_SYS_SUSPENDED)
- return -ENODEV;
-
- start_xmit_work = (struct dhd_rx_tx_work*)
- kmalloc(sizeof(*start_xmit_work), GFP_ATOMIC);
- if (!start_xmit_work) {
- netdev_err(net,
- "error: failed to alloc start_xmit_work\n");
- return -ENOMEM;
- }
-
- INIT_WORK(&start_xmit_work->work, dhd_start_xmit_wq_adapter);
- start_xmit_work->skb = skb;
- start_xmit_work->net = net;
- queue_work(dhd->rx_tx_wq, &start_xmit_work->work);
-
- return NET_XMIT_SUCCESS;
-}
void
dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool state)
@@ -3664,7 +3571,6 @@
void
dhd_sched_dpc(dhd_pub_t *dhdp)
{
- struct dhd_rx_tx_work *rx_work;
dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
if (dhd->thr_dpc_ctl.thr_pid >= 0) {
@@ -3676,17 +3582,11 @@
DHD_OS_WAKE_UNLOCK(dhdp);
return;
} else {
- rx_work = kmalloc(sizeof(*rx_work), GFP_ATOMIC);
- if (!rx_work) {
- DHD_ERROR(("%s: start_rx_work alloc error. \n", __FUNCTION__));
- return;
+ if (!test_bit(TASKLET_STATE_SCHED, &dhd->tasklet.state) && !isresched) {
+ DHD_OS_WAKE_LOCK(dhdp);
+ tasklet_schedule(&dhd->tasklet);
}
-
- INIT_WORK(&rx_work->work, dhd_rx_wq_adapter);
- rx_work->pub = dhdp;
- queue_work(dhd->rx_tx_wq, &rx_work->work);
}
-
}
static void
@@ -4246,25 +4146,6 @@
return OSL_ERROR(bcmerror);
}
-static int
-dhd_ioctl_entry_wrapper(struct net_device *net, struct ifreq *ifr, int cmd)
-{
- int error;
- dhd_info_t *dhd = DHD_DEV_INFO(net);
-
- if (atomic_read(&dhd->pub.runtime_pm_status) >= PCI_PM_SYS_SUSPENDED)
- return -EHOSTDOWN;
-
- if (pm_runtime_get_sync(dhd_bus_to_dev(dhd->pub.bus)) < 0)
- return BCME_ERROR;
-
- error = dhd_ioctl_entry(net, ifr, cmd);
-
- pm_runtime_mark_last_busy(dhd_bus_to_dev(dhd->pub.bus));
- pm_runtime_put_autosuspend(dhd_bus_to_dev(dhd->pub.bus));
-
- return error;
-}
static int
@@ -4275,7 +4156,6 @@
DHD_OS_WAKE_LOCK(&dhd->pub);
DHD_PERIM_LOCK(&dhd->pub);
DHD_TRACE(("%s: Enter %p\n", __FUNCTION__, net));
-
if (dhd->pub.up == 0) {
goto exit;
}
@@ -4355,7 +4235,6 @@
#endif
DHD_PERIM_UNLOCK(&dhd->pub);
DHD_OS_WAKE_UNLOCK(&dhd->pub);
-
return 0;
}
@@ -4503,6 +4382,7 @@
DHD_PERIM_UNLOCK(&dhd->pub);
DHD_OS_WAKE_UNLOCK(&dhd->pub);
+
return ret;
}
@@ -4748,8 +4628,8 @@
.ndo_open = dhd_open,
.ndo_stop = dhd_stop,
.ndo_get_stats = dhd_get_stats,
- .ndo_do_ioctl = dhd_ioctl_entry_wrapper,
- .ndo_start_xmit = dhd_start_xmit_queue_work,
+ .ndo_do_ioctl = dhd_ioctl_entry,
+ .ndo_start_xmit = dhd_start_xmit,
.ndo_set_mac_address = dhd_set_mac_address,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
.ndo_set_rx_mode = dhd_set_multicast_list,
@@ -4760,8 +4640,8 @@
static struct net_device_ops dhd_ops_virt = {
.ndo_get_stats = dhd_get_stats,
- .ndo_do_ioctl = dhd_ioctl_entry_wrapper,
- .ndo_start_xmit = dhd_start_xmit_queue_work,
+ .ndo_do_ioctl = dhd_ioctl_entry,
+ .ndo_start_xmit = dhd_start_xmit,
.ndo_set_mac_address = dhd_set_mac_address,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
.ndo_set_rx_mode = dhd_set_multicast_list,
@@ -5192,8 +5072,6 @@
}
#endif
dhd->dhd_deferred_wq = dhd_deferred_work_init((void *)dhd);
- dhd->rx_tx_wq = alloc_workqueue("bcmdhd-rx-tx-wq", WQ_HIGHPRI | WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
-
#ifdef DEBUG_CPU_FREQ
dhd->new_freq = alloc_percpu(int);
dhd->freq_trans.notifier_call = dhd_cpufreq_notifier;
@@ -5343,7 +5221,6 @@
DHD_PERIM_LOCK(dhdp);
- atomic_set(&dhd->pub.runtime_pm_status, PCI_PM_RT_SUSPENDED);
/* try to download image and nvram to the dongle */
if (dhd->pub.busstate == DHD_BUS_DOWN && dhd_update_fw_nv_path(dhd)) {
DHD_INFO(("%s download fw %s, nv %s\n", __FUNCTION__, dhd->fw_path, dhd->nv_path));
@@ -5862,10 +5739,6 @@
dhd->dhd_cflags |= WLAN_PLAT_AP_FLAG | WLAN_PLAT_NODFS_FLAG;
} else if ((!op_mode && dhd_get_fw_mode(dhd->info) == DHD_FLAG_MFG_MODE) ||
(op_mode == DHD_FLAG_MFG_MODE)) {
-#ifdef CONFIG_PM_RUNTIME
- pm_runtime_get_sync(dhd_bus_to_dev(dhd->bus));
-#endif /* CONFIG_PM_RUNTIME */
-
#if defined(ARP_OFFLOAD_SUPPORT)
arpoe = 0;
#endif /* ARP_OFFLOAD_SUPPORT */
@@ -6848,8 +6721,8 @@
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31))
ASSERT(!net->open);
net->get_stats = dhd_get_stats;
- net->do_ioctl = dhd_ioctl_entry_wrapper;
- net->hard_start_xmit = dhd_start_xmit_queue_work;
+ net->do_ioctl = dhd_ioctl_entry;
+ net->hard_start_xmit = dhd_start_xmit;
net->set_mac_address = dhd_set_mac_address;
net->set_multicast_list = dhd_set_multicast_list;
net->open = net->stop = NULL;
@@ -7131,8 +7004,6 @@
dhd_monitor_uninit();
}
#endif
- destroy_workqueue(dhd->rx_tx_wq);
-
/* free deferred work queue */
dhd_deferred_work_deinit(dhd->dhd_deferred_wq);
dhd->dhd_deferred_wq = NULL;
@@ -7845,10 +7716,6 @@
int ret = 0;
dhd_info_t *dhd = DHD_DEV_INFO(dev);
-
- if (pm_runtime_get_sync(dhd_bus_to_dev(dhd->pub.bus)) < 0)
- return BCME_ERROR;
-
if (flag == TRUE) {
/* Issue wl down command before resetting the chip */
if (dhd_wl_ioctl_cmd(&dhd->pub, WLC_DOWN, NULL, 0, TRUE, 0) < 0) {
@@ -7882,12 +7749,10 @@
}
#endif /* BCMSDIO */
ret = dhd_bus_devreset(&dhd->pub, flag);
- if (ret)
+ if (ret) {
DHD_ERROR(("%s: dhd_bus_devreset: %d\n", __FUNCTION__, ret));
-
- pm_runtime_mark_last_busy(dhd_bus_to_dev(dhd->pub.bus));
- pm_runtime_put_autosuspend(dhd_bus_to_dev(dhd->pub.bus));
-
+ return ret;
+ }
return ret;
}
diff --git a/drivers/net/wireless/bcmdhd/dhd_pcie.c b/drivers/net/wireless/bcmdhd/dhd_pcie.c
index b19fd01..04cb335 100644
--- a/drivers/net/wireless/bcmdhd/dhd_pcie.c
+++ b/drivers/net/wireless/bcmdhd/dhd_pcie.c
@@ -56,7 +56,7 @@
#include <dhd_ip.h>
#endif /* DHDTCPACK_SUPPRESS */
#include <proto/bcmevent.h>
-#include <linux/pm_runtime.h>
+
#ifdef BCMEMBEDIMAGE
#include BCMEMBEDIMAGE
#endif /* BCMEMBEDIMAGE */
@@ -92,6 +92,7 @@
static int dhdpcie_download_firmware(dhd_bus_t *bus, osl_t *osh);
static int dhdpcie_bus_write_vars(dhd_bus_t *bus);
static void dhdpcie_bus_process_mailbox_intr(dhd_bus_t *bus, uint32 intstatus);
+static void dhdpci_bus_read_frames(dhd_bus_t *bus);
static int dhdpcie_readshared(dhd_bus_t *bus);
static void dhdpcie_init_shared_addr(dhd_bus_t *bus);
static bool dhdpcie_dongle_attach(dhd_bus_t *bus);
@@ -124,8 +125,7 @@
#endif /* BCMEMBEDIMAGE */
extern void dhd_dpc_kill(dhd_pub_t *dhdp);
-static void dhdpcie_handle_mb_data(dhd_bus_t *bus);
-#define MAX_D3_ACK_TIMEOUT 10
+
#define PCI_VENDOR_ID_BROADCOM 0x14e4
@@ -368,8 +368,6 @@
int32
dhdpcie_bus_isr(dhd_bus_t *bus)
{
- uint32 intstatus = 0;
- uint32 newstatus = 0;
do {
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
@@ -400,18 +398,6 @@
dhdpcie_bus_intr_disable(bus); /* Disable interrupt!! */
bus->intdis = TRUE;
- intstatus = bus->intstatus;
-
- newstatus = si_corereg(bus->sih, bus->sih->buscoreidx, PCIMailBoxInt, 0, 0);
- intstatus |= (newstatus & bus->def_intmask);
- si_corereg(bus->sih, bus->sih->buscoreidx, PCIMailBoxInt, intstatus, intstatus);
-
- if (intstatus & bus->def_intmask) {
- if (intstatus & (PCIE_MB_TOPCIE_FN0_0 | PCIE_MB_TOPCIE_FN0_1)) {
- dhdpcie_handle_mb_data(bus);
- }
- }
-
#if defined(PCIE_ISR_THREAD)
DHD_TRACE(("Calling dhd_bus_dpc() from %s\n", __FUNCTION__));
@@ -419,12 +405,8 @@
while (dhd_bus_dpc(bus));
DHD_OS_WAKE_UNLOCK(bus->dhd);
#else
- if (intstatus & PCIE_MB_D2H_MB_MASK) {
- bus->dpc_sched = TRUE;
- dhd_sched_dpc(bus->dhd); /* queue DPC now!! */
- } else {
- dhdpcie_bus_intr_enable(bus);
- }
+ bus->dpc_sched = TRUE;
+ dhd_sched_dpc(bus->dhd); /* queue DPC now!! */
#endif /* defined(SDIO_ISR_THREAD) */
DHD_TRACE(("%s: Exit Success DPC Queued\n", __FUNCTION__));
@@ -779,8 +761,6 @@
goto done;
}
bus->dhd->busstate = DHD_BUS_DOWN;
- atomic_set(&bus->dhd->runtime_pm_status, PCI_PM_NETIF_SUSPENDED);
-
dhdpcie_bus_intr_disable(bus);
status = dhdpcie_bus_cfg_read_dword(bus, PCIIntstatus, 4);
dhdpcie_bus_cfg_write_dword(bus, PCIIntstatus, 4, status);
@@ -841,14 +821,7 @@
DHD_OS_WAKE_LOCK(bus->dhd);
- if (pm_runtime_get_sync(dhd_bus_to_dev(bus)) >= 0) {
-
- ret = _dhdpcie_download_firmware(bus);
-
- pm_runtime_mark_last_busy(dhd_bus_to_dev(bus));
- pm_runtime_put_autosuspend(dhd_bus_to_dev(bus));
-
- }
+ ret = _dhdpcie_download_firmware(bus);
DHD_OS_WAKE_UNLOCK(bus->dhd);
return ret;
@@ -1537,10 +1510,6 @@
DHD_ERROR(("%s : dhd->soc_ram is NULL\n", __FUNCTION__));
return -1;
}
-
- if (pm_runtime_get_sync(dhd_bus_to_dev(bus)) < 0)
- return BCME_ERROR;
-
size = dhd->soc_ram_length = bus->ramsize;
/* Read mem content */
@@ -1563,9 +1532,6 @@
dhd_save_fwdump(bus->dhd, dhd->soc_ram, dhd->soc_ram_length);
dhd_schedule_memdump(bus->dhd, dhd->soc_ram, dhd->soc_ram_length);
- pm_runtime_mark_last_busy(dhd_bus_to_dev(bus));
- pm_runtime_put_autosuspend(dhd_bus_to_dev(bus));
-
return ret;
}
@@ -2770,7 +2736,7 @@
break;
case IOV_SVAL(IOV_PCIE_SUSPEND):
- dhdpcie_bus_suspend(bus, bool_val, TRUE);
+ dhdpcie_bus_suspend(bus, bool_val);
break;
case IOV_GVAL(IOV_MEMSIZE):
@@ -3045,12 +3011,12 @@
{
struct dhd_bus *bus = dhdp->bus;
if (bus) {
- dhdpcie_bus_suspend(bus, state, TRUE);
+ dhdpcie_bus_suspend(bus, state);
}
}
int
-dhdpcie_bus_suspend(struct dhd_bus *bus, bool state, bool byint)
+dhdpcie_bus_suspend(struct dhd_bus *bus, bool state)
{
int timeleft;
@@ -3059,7 +3025,6 @@
struct net_device *netdev = NULL;
dhd_pub_t *pub = (dhd_pub_t *)(bus->dhd);
int idle_retry = 0;
- int d3_read_retry = 0;
int active;
DHD_INFO(("%s Enter with state :%d\n", __FUNCTION__, state));
@@ -3085,43 +3050,52 @@
return BCME_OK;
if (state) {
-
- while ((active = dhd_os_check_wakelock_all(bus->dhd)) &&
- (idle_retry < MAX_WKLK_IDLE_CHECK)) {
- usleep_range(1000, 1500);
- idle_retry++;
- }
-
- if (active)
- return BCME_ERROR;
-
bus->wait_for_d3_ack = 0;
+ bus->suspended = TRUE;
+ bus->dhd->busstate = DHD_BUS_SUSPEND;
- if (byint) {
- DHD_OS_WAKE_LOCK_WAIVE(bus->dhd);
- dhd_os_set_ioctl_resp_timeout(DEFAULT_IOCTL_RESP_TIMEOUT);
- dhdpcie_send_mb_data(bus, H2D_HOST_D3_INFORM);
- timeleft = dhd_os_d3ack_wait(bus->dhd, &bus->wait_for_d3_ack);
- dhd_os_set_ioctl_resp_timeout(IOCTL_RESP_TIMEOUT);
- DHD_OS_WAKE_LOCK_RESTORE(bus->dhd);
- } else {
- dhdpcie_send_mb_data(bus, H2D_HOST_D3_INFORM | H2D_HOST_ACK_NOINT);
- while (!bus->wait_for_d3_ack && d3_read_retry < MAX_D3_ACK_TIMEOUT) {
- dhdpcie_handle_mb_data(bus);
- usleep_range(1000, 1500);
- d3_read_retry++;
- }
- }
+ /* stop all interface network queue. */
+ dhd_bus_stop_queue(bus);
+
+ DHD_OS_WAKE_LOCK_WAIVE(bus->dhd);
+ dhd_os_set_ioctl_resp_timeout(DEFAULT_IOCTL_RESP_TIMEOUT);
+ dhdpcie_send_mb_data(bus, H2D_HOST_D3_INFORM);
+ timeleft = dhd_os_d3ack_wait(bus->dhd, &bus->wait_for_d3_ack);
+ dhd_os_set_ioctl_resp_timeout(IOCTL_RESP_TIMEOUT);
+ DHD_OS_WAKE_LOCK_RESTORE(bus->dhd);
if (bus->wait_for_d3_ack == 1) {
/* Got D3 Ack. Suspend the bus */
/* To allow threads that got pre-empted to complete. */
- dhdpcie_bus_intr_disable(bus);
- rc = dhdpcie_pci_suspend_resume(bus->dev, state);
+
+ while ((active = dhd_os_check_wakelock_all(bus->dhd)) &&
+ (idle_retry < MAX_WKLK_IDLE_CHECK)) {
+ msleep(1);
+ idle_retry++;
+ }
+ if (active) {
+ DHD_ERROR(("Suspend failed because of wakelock\n"));
+ bus->dev->current_state = PCI_D3hot;
+ pci_set_master(bus->dev);
+ rc = pci_set_power_state(bus->dev, PCI_D0);
+ if (rc) {
+ DHD_ERROR(("%s: pci_set_power_state failed:"
+ " current_state[%d], ret[%d]\n",
+ __FUNCTION__, bus->dev->current_state, rc));
+ }
+ bus->suspended = FALSE;
+ bus->dhd->busstate = DHD_BUS_DATA;
+
+ /* resume all interface network queue. */
+ dhd_bus_start_queue(bus);
+
+ rc = BCME_ERROR;
+ } else {
+ dhdpcie_bus_intr_disable(bus);
+ rc = dhdpcie_pci_suspend_resume(bus->dev, state);
+ }
bus->dhd->d3ackcnt_timeout = 0;
- bus->suspended = TRUE;
- bus->dhd->busstate = DHD_BUS_SUSPEND;
- } else {
+ } else if (timeleft == 0) {
bus->dhd->d3ackcnt_timeout++;
DHD_ERROR(("%s: resumed on timeout for D3 ACK d3ackcnt_timeout %d \n",
__FUNCTION__, bus->dhd->d3ackcnt_timeout));
@@ -3153,10 +3127,19 @@
bus->dhd->busstate = DHD_BUS_DATA;
DHD_INFO(("fail to suspend, start net device traffic\n"));
+ /* resume all interface network queue. */
+ dhd_bus_start_queue(bus);
+
DHD_GENERAL_UNLOCK(bus->dhd, flags);
rc = -ETIMEDOUT;
+ } else if (bus->wait_for_d3_ack == DHD_INVALID) {
+ DHD_ERROR(("PCIe link down during suspend"));
+ bus->suspended = FALSE;
+ bus->dhd->busstate = DHD_BUS_DOWN;
+ rc = -ETIMEDOUT;
+ dhdpcie_bus_report_pcie_linkdown(bus);
}
-
+ bus->wait_for_d3_ack = 1;
} else {
/* Resume */
DHD_INFO(("dhdpcie_bus_suspend resume\n"));
@@ -3170,6 +3153,9 @@
} else {
bus->dhd->busstate = DHD_BUS_DATA;
dhdpcie_bus_intr_enable(bus);
+
+ /* resume all interface network queue. */
+ dhd_bus_start_queue(bus);
}
}
return rc;
@@ -3703,7 +3689,7 @@
}
if (d2h_mb_data & D2H_DEV_D3_ACK) {
/* what should we do */
- DHD_RPM(("D2H_MB_DATA: D3 ACK\n"));
+ DHD_ERROR(("D2H_MB_DATA: D3 ACK\n"));
if (!bus->wait_for_d3_ack) {
bus->wait_for_d3_ack = 1;
dhd_os_d3ack_wake(bus->dhd);
@@ -3746,16 +3732,9 @@
}
/* Decode dongle to host message stream */
-void
+static void
dhdpci_bus_read_frames(dhd_bus_t *bus)
{
-
- if (bus->rpm_irq_enable) {
- DHD_RPM(("%s: rpm_irq_enable only.\n", __FUNCTION__));
- bus->rpm_irq_enable = 0;
- return;
- }
-
/* There may be frames in both ctrl buf and data buf; check ctrl buf first */
DHD_PERIM_LOCK(bus->dhd); /* Take the perimeter lock */
@@ -3769,9 +3748,6 @@
dhd_prot_process_msgbuf_rxcpl(bus->dhd);
DHD_PERIM_UNLOCK(bus->dhd); /* Release the perimeter lock */
-
- dhdpcie_bus_intr_enable(bus); /* Enable interrupt!! */
-
}
static int
diff --git a/drivers/net/wireless/bcmdhd/dhd_pcie.h b/drivers/net/wireless/bcmdhd/dhd_pcie.h
index 30db59f..86e868e 100644
--- a/drivers/net/wireless/bcmdhd/dhd_pcie.h
+++ b/drivers/net/wireless/bcmdhd/dhd_pcie.h
@@ -181,9 +181,6 @@
struct msm_pcie_register_event pcie_event;
bool islinkdown;
#endif /* MSM_PCIE_LINKDOWN_RECOVERY */
-#ifdef CONFIG_PM_RUNTIME
- bool rpm_irq_enable;
-#endif /* CONFIG_PM_RUNTIME */
} dhd_bus_t;
/* function declarations */
@@ -200,7 +197,7 @@
extern void dhdpcie_bus_release(struct dhd_bus *bus);
extern int32 dhdpcie_bus_isr(struct dhd_bus *bus);
extern void dhdpcie_free_irq(dhd_bus_t *bus);
-extern int dhdpcie_bus_suspend(struct dhd_bus *bus, bool state, bool byint);
+extern int dhdpcie_bus_suspend(struct dhd_bus *bus, bool state);
extern int dhdpcie_pci_suspend_resume(struct pci_dev *dev, bool state);
extern int dhdpcie_start_host_pcieclock(dhd_bus_t *bus);
extern int dhdpcie_stop_host_pcieclock(dhd_bus_t *bus);
diff --git a/drivers/net/wireless/bcmdhd/dhd_pcie_linux.c b/drivers/net/wireless/bcmdhd/dhd_pcie_linux.c
index c877b7b..14e33f4 100644
--- a/drivers/net/wireless/bcmdhd/dhd_pcie_linux.c
+++ b/drivers/net/wireless/bcmdhd/dhd_pcie_linux.c
@@ -59,8 +59,6 @@
#endif
#endif
-#include <linux/pm_runtime.h>
-
#define PCI_CFG_RETRY 10
#define OS_HANDLE_MAGIC 0x1234abcd /* Magic # to recognize osh */
#define BCM_MEM_FILENAME_LEN 24 /* Mem. filename length */
@@ -121,6 +119,7 @@
struct tasklet_struct tuning_tasklet;
};
+
/* function declarations */
static int __devinit
dhdpcie_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
@@ -130,15 +129,9 @@
static irqreturn_t dhdpcie_isr(int irq, void *arg);
/* OS Routine functions for PCI suspend/resume */
-#ifdef CONFIG_PM_RUNTIME
-static int dhdpcie_pm_runtime_suspend(struct device * dev);
-static int dhdpcie_pm_runtime_resume(struct device * dev);
-#endif /* CONFIG_PM_RUNTIME */
-#ifdef CONFIG_PM
-static int dhdpcie_pm_system_suspend_noirq(struct device * dev);
-static int dhdpcie_pm_system_resume_noirq(struct device * dev);
-#endif /* CONFIG_PM */
-static int dhdpcie_set_suspend_resume(struct pci_dev *dev, bool state, bool byint);
+static int dhdpcie_pci_suspend(struct pci_dev *dev, pm_message_t state);
+static int dhdpcie_set_suspend_resume(struct pci_dev *dev, bool state);
+static int dhdpcie_pci_resume(struct pci_dev *dev);
static int dhdpcie_resume_dev(struct pci_dev *dev);
static int dhdpcie_suspend_dev(struct pci_dev *dev);
static struct pci_device_id dhdpcie_pci_devid[] __devinitdata = {
@@ -154,13 +147,6 @@
};
MODULE_DEVICE_TABLE(pci, dhdpcie_pci_devid);
-
-static const struct dev_pm_ops dhdpcie_pm_ops = {
- SET_RUNTIME_PM_OPS(dhdpcie_pm_runtime_suspend, dhdpcie_pm_runtime_resume, NULL)
- .suspend_noirq = dhdpcie_pm_system_suspend_noirq,
- .resume_noirq = dhdpcie_pm_system_resume_noirq
-};
-
static struct pci_driver dhdpcie_driver = {
node: {},
name: "pcieh",
@@ -170,11 +156,8 @@
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
save_state: NULL,
#endif
-#ifdef CONFIG_PM
- driver: {
- .pm = &dhdpcie_pm_ops,
- },
-#endif
+ suspend: dhdpcie_pci_suspend,
+ resume: dhdpcie_pci_resume,
};
int dhdpcie_init_succeeded = FALSE;
@@ -192,7 +175,7 @@
pci_write_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, pmcsr);
}
-static int dhdpcie_set_suspend_resume(struct pci_dev *pdev, bool state, bool byint)
+static int dhdpcie_set_suspend_resume(struct pci_dev *pdev, bool state)
{
int ret = 0;
dhdpcie_info_t *pch = pci_get_drvdata(pdev);
@@ -214,123 +197,24 @@
(bus->dhd->busstate == DHD_BUS_DATA)) &&
(bus->suspended != state)) {
- ret = dhdpcie_bus_suspend(bus, state, byint);
+ ret = dhdpcie_bus_suspend(bus, state);
}
DHD_INFO(("%s Exit with state :%d\n", __FUNCTION__, ret));
return ret;
}
-#ifdef CONFIG_PM_RUNTIME
-static int dhdpcie_pm_runtime_suspend(struct device * dev)
+
+static int dhdpcie_pci_suspend(struct pci_dev * pdev, pm_message_t state)
{
- struct pci_dev *pdev = to_pci_dev(dev);
- dhdpcie_info_t *pch = pci_get_drvdata(pdev);
- dhd_bus_t *bus = NULL;
- int ret = 0;
-
- if (!pch)
- return -EBUSY;
-
- bus = pch->bus;
-
- DHD_RPM(("%s Enter\n", __FUNCTION__));
-
- if (atomic_read(&bus->dhd->runtime_pm_status) != PCI_PM_RT_ACTIVE)
- return 0;
-
- ret = dhdpcie_set_suspend_resume(pdev, TRUE, TRUE);
-
- if (ret) {
- pm_runtime_mark_last_busy(dev);
- ret = -EAGAIN;
- } else
- atomic_set(&bus->dhd->runtime_pm_status, PCI_PM_RT_SUSPENDED);
-
- return ret;
+ BCM_REFERENCE(state);
+ DHD_INFO(("%s Enter with event %x\n", __FUNCTION__, state.event));
+ return dhdpcie_set_suspend_resume(pdev, TRUE);
}
-static int dhdpcie_pm_runtime_resume(struct device * dev)
+static int dhdpcie_pci_resume(struct pci_dev *pdev)
{
- int ret;
- struct pci_dev *pdev = to_pci_dev(dev);
- dhdpcie_info_t *pch = pci_get_drvdata(pdev);
- dhd_bus_t *bus = NULL;
-
- bus = pch->bus;
-
- DHD_RPM(("%s Enter\n", __FUNCTION__));
-
- if (atomic_read(&bus->dhd->runtime_pm_status) == PCI_PM_RT_ACTIVE)
- return 0;
- else if (atomic_read(&bus->dhd->runtime_pm_status) == PCI_PM_SYS_SUSPENDED)
- return -EHOSTDOWN;
-
- ret = dhdpcie_set_suspend_resume(pdev, FALSE, TRUE);
-
- if (!ret)
- atomic_set(&bus->dhd->runtime_pm_status, PCI_PM_RT_ACTIVE);
- else
- ret = -EAGAIN;
-
- return ret;
-}
-#endif /* CONFIG_PM_RUNTIME */
-
-static int dhdpcie_pm_system_suspend_noirq(struct device * dev)
-{
- struct pci_dev *pdev = to_pci_dev(dev);
- dhdpcie_info_t *pch = pci_get_drvdata(pdev);
- dhd_bus_t *bus = NULL;
- int ret;
-
- DHD_RPM(("%s Enter\n", __FUNCTION__));
-
- if (!pch)
- return -EBUSY;
-
- bus = pch->bus;
-
- ret = dhdpcie_set_suspend_resume(pdev, TRUE, FALSE);
-
- atomic_set(&bus->dhd->runtime_pm_status, PCI_PM_SYS_SUSPENDED);
-
- if (atomic_read(&bus->dhd->runtime_pm_status) == PCI_PM_RT_ACTIVE) {
- pm_runtime_disable(dev);
- pm_runtime_set_suspended(dev);
- pm_runtime_enable(dev);
- }
-
- return ret;
-}
-
-static int dhdpcie_pm_system_resume_noirq(struct device * dev)
-{
- struct pci_dev *pdev = to_pci_dev(dev);
- dhdpcie_info_t *pch = pci_get_drvdata(pdev);
- dhd_bus_t *bus = NULL;
- int ret;
-
- if (!pch)
- return -EBUSY;
-
- bus = pch->bus;
-
- DHD_RPM(("%s Enter\n", __FUNCTION__));
-
- atomic_set(&bus->dhd->runtime_pm_status, PCI_PM_RT_SUSPENDED);
-
- ret = dhdpcie_set_suspend_resume(pdev, FALSE, FALSE);
-
- if (!ret) {
- pm_runtime_get_noresume(dev);
-
- atomic_set(&bus->dhd->runtime_pm_status, PCI_PM_RT_ACTIVE);
-
- pm_runtime_mark_last_busy(dev);
- pm_runtime_put_autosuspend(dev);
- }
-
- return ret;
+ DHD_INFO(("%s Enter\n", __FUNCTION__));
+ return dhdpcie_set_suspend_resume(pdev, FALSE);
}
int dhd_os_get_wake_irq(dhd_pub_t *pub);
@@ -422,15 +306,10 @@
{
int rc;
- if (state) {
+ if (state)
rc = dhdpcie_suspend_dev(dev);
- if(!rc)
- disable_irq(dev->irq);
- }
- else {
- enable_irq(dev->irq);
+ else
rc = dhdpcie_resume_dev(dev);
- }
return rc;
}
@@ -507,11 +386,6 @@
DHD_ERROR(("%s: PCIe Enumeration failed\n", __FUNCTION__));
return -ENODEV;
}
-
- pm_runtime_put_noidle(&pdev->dev);
- pm_runtime_put_noidle(&pdev->dev); //since already +2, even before dhdpcie_pci_probe called.
- pm_runtime_set_suspended(&pdev->dev);
-
/* disable async suspend */
device_disable_async_suspend(&pdev->dev);
DHD_TRACE(("%s: PCIe Enumeration done!!\n", __FUNCTION__));
@@ -545,9 +419,6 @@
bus = pch->bus;
osh = pch->osh;
- pm_runtime_get_noresume(&pdev->dev);
- pm_runtime_get_noresume(&pdev->dev);
-
dhdpcie_bus_release(bus);
pci_disable_device(pdev);
/* pcie info detach */
@@ -694,57 +565,25 @@
return -1; /* FAILURE */
}
-#ifdef CONFIG_ARCH_MSM
-void dhdpcie_event_cb(struct msm_pcie_notify *noti)
+#ifdef MSM_PCIE_LINKDOWN_RECOVERY
+void dhdpcie_linkdown_cb(struct msm_pcie_notify *noti)
{
struct pci_dev *pdev = (struct pci_dev *)noti->user;
dhdpcie_info_t *pch;
dhd_bus_t *bus;
dhd_pub_t *dhd;
-
- if (!pdev)
- return;
-
- pch = pci_get_drvdata(pdev);
-
- if (!pch)
- return;
-
- bus = pch->bus;
-
- if (!bus)
- return;
-
- dhd = bus->dhd;
-
- if (!dhd)
- return;
-
- switch (noti->event) {
-#ifdef MSM_PCIE_LINKDOWN_RECOVERY
- case MSM_PCIE_EVENT_LINKDOWN:
- DHD_ERROR(("%s: Event HANG send up "
- "due to PCIe linkdown\n", __FUNCTION__));
- bus->islinkdown = TRUE;
- dhd->busstate = DHD_BUS_DOWN;
- DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(dhd, DHD_EVENT_TIMEOUT_MS);
- dhd_os_check_hang(dhd, 0, -ETIMEDOUT);
- break;
-#endif /* MSM_PCIE_LINKDOWN_RECOVERY */
-#ifdef CONFIG_PM_RUNTIME
- case MSM_PCIE_EVENT_WAKEUP:
- DHD_RPM(("%s: MSM_PCIE_EVENT_WAKEUP received.\n", __FUNCTION__));
- bus->rpm_irq_enable = 1;
- dhd_sched_dpc(dhd);
- break;
-#endif /* CONFIG_PM_RUNTIME */
- default :
- break;
+ if (pdev && (pch = pci_get_drvdata(pdev))) {
+ if ((bus = pch->bus) && (dhd = bus->dhd)) {
+ DHD_ERROR(("%s: Event HANG send up "
+ "due to PCIe linkdown\n", __FUNCTION__));
+ bus->islinkdown = TRUE;
+ dhd->busstate = DHD_BUS_DOWN;
+ DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(dhd, DHD_EVENT_TIMEOUT_MS);
+ dhd_os_check_hang(dhd, 0, -ETIMEDOUT);
+ }
}
-
}
-#endif /* CONFIG_ARCH_MSM */
-
+#endif /* MSM_PCIE_LINKDOWN_RECOVERY */
int dhdpcie_init(struct pci_dev *pdev)
{
@@ -795,21 +634,15 @@
dhdpcie_info->bus = bus;
dhdpcie_info->bus->dev = pdev;
-#ifdef CONFIG_ARCH_MSM
#ifdef MSM_PCIE_LINKDOWN_RECOVERY
bus->islinkdown = FALSE;
- bus->pcie_event.events |= MSM_PCIE_EVENT_LINKDOWN;
-#endif /* MSM_PCIE_LINKDOWN_RECOVERY */
-#ifdef CONFIG_PM_RUNTIME
- bus->pcie_event.events |= MSM_PCIE_EVENT_WAKEUP;
-#endif /* CONFIG_PM_RUNTIME */
+ bus->pcie_event.events = MSM_PCIE_EVENT_LINKDOWN;
bus->pcie_event.user = pdev;
bus->pcie_event.mode = MSM_PCIE_TRIGGER_CALLBACK;
- bus->pcie_event.callback = dhdpcie_event_cb;
+ bus->pcie_event.callback = dhdpcie_linkdown_cb;
bus->pcie_event.options = MSM_PCIE_CONFIG_NO_RECOVERY;
msm_pcie_register_event(&bus->pcie_event);
-#endif /* CONFIG_ARCH_MSM */
-
+#endif /* MSM_PCIE_LINKDOWN_RECOVERY */
if (bus->intr) {
/* Register interrupt callback, but mask it (not operational yet). */
@@ -849,12 +682,6 @@
#endif
dhdpcie_init_succeeded = TRUE;
-#ifdef CONFIG_PM_RUNTIME
- pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_TIMEOUT * MSEC_PER_SEC);
- pm_runtime_use_autosuspend(&pdev->dev);
- atomic_set(&bus->dhd->runtime_pm_status, PCI_PM_RT_SUSPENDED);
-#endif /* CONFIG_PM_RUNTIME */
-
DHD_ERROR(("%s:Exit - SUCCESS \n", __FUNCTION__));
return 0; /* return SUCCESS */
@@ -1174,16 +1001,3 @@
return ret;
}
-#ifdef CONFIG_PM_RUNTIME
-struct device * dhd_bus_to_dev(dhd_bus_t *bus)
-{
- struct pci_dev *pdev;
- pdev = bus->dev;
-
- if(pdev)
- return &pdev->dev;
- else
- return NULL;
-}
-#endif /* CONFIG_PM_RUNTIME */
-
diff --git a/drivers/net/wireless/bcmdhd/include/bcmpcie.h b/drivers/net/wireless/bcmdhd/include/bcmpcie.h
index fb94adb..5c19f46 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmpcie.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmpcie.h
@@ -177,7 +177,6 @@
/* H2D mail box Data */
#define H2D_HOST_D3_INFORM 0x00000001
#define H2D_HOST_DS_ACK 0x00000002
-#define H2D_HOST_ACK_NOINT 0x10000000 /* d2h ack with no interrupt */
#define H2D_HOST_CONS_INT 0x80000000 /* h2d int for console cmds */
/* D2H mail box Data */
diff --git a/drivers/net/wireless/bcmdhd/include/dhdioctl.h b/drivers/net/wireless/bcmdhd/include/dhdioctl.h
index 0aa4865..a5e5328 100644
--- a/drivers/net/wireless/bcmdhd/include/dhdioctl.h
+++ b/drivers/net/wireless/bcmdhd/include/dhdioctl.h
@@ -96,7 +96,6 @@
#define DHD_RTT_VAL 0x100000
#define DHD_PKT_MON_VAL 0x200000
#define DHD_PKT_MON_DUMP_VAL 0x400000
-#define DHD_RPM_VAL 0x800000
#ifdef SDTEST
/* For pktgen iovar */
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index a423f9e..5548a13 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -1074,10 +1074,7 @@
}
out:
- if (dev->power.use_autosuspend)
- pm_runtime_autosuspend(dev);
- else
- pm_runtime_suspend(dev);
+ pm_runtime_suspend(dev);
return 0;
}