diff options
author | Christian Lamparter <chunkeey@web.de> | 2008-11-16 06:20:32 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-11-25 16:41:38 -0500 |
commit | 40db0b22591f59811feeb7cad26fdde92a190663 (patch) | |
tree | 2e34a63c1a3126b323523f13f7126fd1882f8518 /drivers/net/wireless/p54 | |
parent | ffed785898a6dfd5f80d069bcb607b8cd5613c76 (diff) |
p54pci: cache firmware for suspend/resume
Johannes pointed out that the driver has cache the firmware for
suspend/resume cycles.
Signed-off-by: Christian Lamparter <chunkeey@web.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/p54')
-rw-r--r-- | drivers/net/wireless/p54/p54common.c | 16 | ||||
-rw-r--r-- | drivers/net/wireless/p54/p54pci.c | 42 | ||||
-rw-r--r-- | drivers/net/wireless/p54/p54pci.h | 2 |
3 files changed, 35 insertions, 25 deletions
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 6bf5123c10b2..3373b022d91e 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c | |||
@@ -1524,16 +1524,24 @@ static int p54_start(struct ieee80211_hw *dev) | |||
1524 | 1524 | ||
1525 | mutex_lock(&priv->conf_mutex); | 1525 | mutex_lock(&priv->conf_mutex); |
1526 | err = priv->open(dev); | 1526 | err = priv->open(dev); |
1527 | if (!err) | 1527 | if (err) |
1528 | priv->mode = NL80211_IFTYPE_MONITOR; | 1528 | goto out; |
1529 | P54_SET_QUEUE(priv->qos_params[0], 0x0002, 0x0003, 0x0007, 47); | 1529 | P54_SET_QUEUE(priv->qos_params[0], 0x0002, 0x0003, 0x0007, 47); |
1530 | P54_SET_QUEUE(priv->qos_params[1], 0x0002, 0x0007, 0x000f, 94); | 1530 | P54_SET_QUEUE(priv->qos_params[1], 0x0002, 0x0007, 0x000f, 94); |
1531 | P54_SET_QUEUE(priv->qos_params[2], 0x0003, 0x000f, 0x03ff, 0); | 1531 | P54_SET_QUEUE(priv->qos_params[2], 0x0003, 0x000f, 0x03ff, 0); |
1532 | P54_SET_QUEUE(priv->qos_params[3], 0x0007, 0x000f, 0x03ff, 0); | 1532 | P54_SET_QUEUE(priv->qos_params[3], 0x0007, 0x000f, 0x03ff, 0); |
1533 | err = p54_set_edcf(dev); | 1533 | err = p54_set_edcf(dev); |
1534 | if (!err) | 1534 | if (err) |
1535 | err = p54_init_stats(dev); | 1535 | goto out; |
1536 | err = p54_init_stats(dev); | ||
1537 | if (err) | ||
1538 | goto out; | ||
1539 | err = p54_setup_mac(dev, P54_FILTER_TYPE_NONE, NULL); | ||
1540 | if (err) | ||
1541 | goto out; | ||
1542 | priv->mode = NL80211_IFTYPE_MONITOR; | ||
1536 | 1543 | ||
1544 | out: | ||
1537 | mutex_unlock(&priv->conf_mutex); | 1545 | mutex_unlock(&priv->conf_mutex); |
1538 | return err; | 1546 | return err; |
1539 | } | 1547 | } |
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index c4a868ae6d6b..d21c509325fe 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c | |||
@@ -47,7 +47,6 @@ MODULE_DEVICE_TABLE(pci, p54p_table); | |||
47 | static int p54p_upload_firmware(struct ieee80211_hw *dev) | 47 | static int p54p_upload_firmware(struct ieee80211_hw *dev) |
48 | { | 48 | { |
49 | struct p54p_priv *priv = dev->priv; | 49 | struct p54p_priv *priv = dev->priv; |
50 | const struct firmware *fw_entry = NULL; | ||
51 | __le32 reg; | 50 | __le32 reg; |
52 | int err; | 51 | int err; |
53 | __le32 *data; | 52 | __le32 *data; |
@@ -73,23 +72,15 @@ static int p54p_upload_firmware(struct ieee80211_hw *dev) | |||
73 | P54P_WRITE(ctrl_stat, reg); | 72 | P54P_WRITE(ctrl_stat, reg); |
74 | wmb(); | 73 | wmb(); |
75 | 74 | ||
76 | err = request_firmware(&fw_entry, "isl3886pci", &priv->pdev->dev); | 75 | /* wait for the firmware to reset properly */ |
77 | if (err) { | 76 | mdelay(10); |
78 | printk(KERN_ERR "%s (p54pci): cannot find firmware " | ||
79 | "(isl3886pci)\n", pci_name(priv->pdev)); | ||
80 | err = request_firmware(&fw_entry, "isl3886", &priv->pdev->dev); | ||
81 | if (err) | ||
82 | return err; | ||
83 | } | ||
84 | 77 | ||
85 | err = p54_parse_firmware(dev, fw_entry); | 78 | err = p54_parse_firmware(dev, priv->firmware); |
86 | if (err) { | 79 | if (err) |
87 | release_firmware(fw_entry); | ||
88 | return err; | 80 | return err; |
89 | } | ||
90 | 81 | ||
91 | data = (__le32 *) fw_entry->data; | 82 | data = (__le32 *) priv->firmware->data; |
92 | remains = fw_entry->size; | 83 | remains = priv->firmware->size; |
93 | device_addr = ISL38XX_DEV_FIRMWARE_ADDR; | 84 | device_addr = ISL38XX_DEV_FIRMWARE_ADDR; |
94 | while (remains) { | 85 | while (remains) { |
95 | u32 i = 0; | 86 | u32 i = 0; |
@@ -107,8 +98,6 @@ static int p54p_upload_firmware(struct ieee80211_hw *dev) | |||
107 | P54P_READ(int_enable); | 98 | P54P_READ(int_enable); |
108 | } | 99 | } |
109 | 100 | ||
110 | release_firmware(fw_entry); | ||
111 | |||
112 | reg = P54P_READ(ctrl_stat); | 101 | reg = P54P_READ(ctrl_stat); |
113 | reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN); | 102 | reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN); |
114 | reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET); | 103 | reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET); |
@@ -500,15 +489,14 @@ static int __devinit p54p_probe(struct pci_dev *pdev, | |||
500 | if (mem_len < sizeof(struct p54p_csr)) { | 489 | if (mem_len < sizeof(struct p54p_csr)) { |
501 | printk(KERN_ERR "%s (p54pci): Too short PCI resources\n", | 490 | printk(KERN_ERR "%s (p54pci): Too short PCI resources\n", |
502 | pci_name(pdev)); | 491 | pci_name(pdev)); |
503 | pci_disable_device(pdev); | 492 | goto err_disable_dev; |
504 | return err; | ||
505 | } | 493 | } |
506 | 494 | ||
507 | err = pci_request_regions(pdev, "p54pci"); | 495 | err = pci_request_regions(pdev, "p54pci"); |
508 | if (err) { | 496 | if (err) { |
509 | printk(KERN_ERR "%s (p54pci): Cannot obtain PCI resources\n", | 497 | printk(KERN_ERR "%s (p54pci): Cannot obtain PCI resources\n", |
510 | pci_name(pdev)); | 498 | pci_name(pdev)); |
511 | return err; | 499 | goto err_disable_dev; |
512 | } | 500 | } |
513 | 501 | ||
514 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) || | 502 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) || |
@@ -561,6 +549,17 @@ static int __devinit p54p_probe(struct pci_dev *pdev, | |||
561 | spin_lock_init(&priv->lock); | 549 | spin_lock_init(&priv->lock); |
562 | tasklet_init(&priv->rx_tasklet, p54p_rx_tasklet, (unsigned long)dev); | 550 | tasklet_init(&priv->rx_tasklet, p54p_rx_tasklet, (unsigned long)dev); |
563 | 551 | ||
552 | err = request_firmware(&priv->firmware, "isl3886pci", | ||
553 | &priv->pdev->dev); | ||
554 | if (err) { | ||
555 | printk(KERN_ERR "%s (p54pci): cannot find firmware " | ||
556 | "(isl3886pci)\n", pci_name(priv->pdev)); | ||
557 | err = request_firmware(&priv->firmware, "isl3886", | ||
558 | &priv->pdev->dev); | ||
559 | if (err) | ||
560 | goto err_free_common; | ||
561 | } | ||
562 | |||
564 | err = p54p_open(dev); | 563 | err = p54p_open(dev); |
565 | if (err) | 564 | if (err) |
566 | goto err_free_common; | 565 | goto err_free_common; |
@@ -579,6 +578,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev, | |||
579 | return 0; | 578 | return 0; |
580 | 579 | ||
581 | err_free_common: | 580 | err_free_common: |
581 | release_firmware(priv->firmware); | ||
582 | p54_free_common(dev); | 582 | p54_free_common(dev); |
583 | pci_free_consistent(pdev, sizeof(*priv->ring_control), | 583 | pci_free_consistent(pdev, sizeof(*priv->ring_control), |
584 | priv->ring_control, priv->ring_control_dma); | 584 | priv->ring_control, priv->ring_control_dma); |
@@ -592,6 +592,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev, | |||
592 | 592 | ||
593 | err_free_reg: | 593 | err_free_reg: |
594 | pci_release_regions(pdev); | 594 | pci_release_regions(pdev); |
595 | err_disable_dev: | ||
595 | pci_disable_device(pdev); | 596 | pci_disable_device(pdev); |
596 | return err; | 597 | return err; |
597 | } | 598 | } |
@@ -606,6 +607,7 @@ static void __devexit p54p_remove(struct pci_dev *pdev) | |||
606 | 607 | ||
607 | ieee80211_unregister_hw(dev); | 608 | ieee80211_unregister_hw(dev); |
608 | priv = dev->priv; | 609 | priv = dev->priv; |
610 | release_firmware(priv->firmware); | ||
609 | pci_free_consistent(pdev, sizeof(*priv->ring_control), | 611 | pci_free_consistent(pdev, sizeof(*priv->ring_control), |
610 | priv->ring_control, priv->ring_control_dma); | 612 | priv->ring_control, priv->ring_control_dma); |
611 | p54_free_common(dev); | 613 | p54_free_common(dev); |
diff --git a/drivers/net/wireless/p54/p54pci.h b/drivers/net/wireless/p54/p54pci.h index 4a6778070afc..fbb683953fb2 100644 --- a/drivers/net/wireless/p54/p54pci.h +++ b/drivers/net/wireless/p54/p54pci.h | |||
@@ -93,7 +93,7 @@ struct p54p_priv { | |||
93 | struct pci_dev *pdev; | 93 | struct pci_dev *pdev; |
94 | struct p54p_csr __iomem *map; | 94 | struct p54p_csr __iomem *map; |
95 | struct tasklet_struct rx_tasklet; | 95 | struct tasklet_struct rx_tasklet; |
96 | 96 | const struct firmware *firmware; | |
97 | spinlock_t lock; | 97 | spinlock_t lock; |
98 | struct p54p_ring_control *ring_control; | 98 | struct p54p_ring_control *ring_control; |
99 | dma_addr_t ring_control_dma; | 99 | dma_addr_t ring_control_dma; |