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

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>

authored by

Christian Lamparter and committed by
John W. Linville
40db0b22 ffed7858

+35 -25
+12 -4
drivers/net/wireless/p54/p54common.c
··· 1524 1524 1525 1525 mutex_lock(&priv->conf_mutex); 1526 1526 err = priv->open(dev); 1527 - if (!err) 1528 - priv->mode = NL80211_IFTYPE_MONITOR; 1527 + if (err) 1528 + goto out; 1529 1529 P54_SET_QUEUE(priv->qos_params[0], 0x0002, 0x0003, 0x0007, 47); 1530 1530 P54_SET_QUEUE(priv->qos_params[1], 0x0002, 0x0007, 0x000f, 94); 1531 1531 P54_SET_QUEUE(priv->qos_params[2], 0x0003, 0x000f, 0x03ff, 0); 1532 1532 P54_SET_QUEUE(priv->qos_params[3], 0x0007, 0x000f, 0x03ff, 0); 1533 1533 err = p54_set_edcf(dev); 1534 - if (!err) 1535 - err = p54_init_stats(dev); 1534 + if (err) 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 1545 mutex_unlock(&priv->conf_mutex); 1538 1546 return err; 1539 1547 }
+22 -20
drivers/net/wireless/p54/p54pci.c
··· 47 47 static int p54p_upload_firmware(struct ieee80211_hw *dev) 48 48 { 49 49 struct p54p_priv *priv = dev->priv; 50 - const struct firmware *fw_entry = NULL; 51 50 __le32 reg; 52 51 int err; 53 52 __le32 *data; ··· 72 73 P54P_WRITE(ctrl_stat, reg); 73 74 wmb(); 74 75 75 - err = request_firmware(&fw_entry, "isl3886pci", &priv->pdev->dev); 76 - if (err) { 77 - printk(KERN_ERR "%s (p54pci): cannot find firmware " 78 - "(isl3886pci)\n", pci_name(priv->pdev)); 79 - err = request_firmware(&fw_entry, "isl3886", &priv->pdev->dev); 80 - if (err) 81 - return err; 82 - } 76 + /* wait for the firmware to reset properly */ 77 + mdelay(10); 83 78 84 - err = p54_parse_firmware(dev, fw_entry); 85 - if (err) { 86 - release_firmware(fw_entry); 79 + err = p54_parse_firmware(dev, priv->firmware); 80 + if (err) 87 81 return err; 88 - } 89 82 90 - data = (__le32 *) fw_entry->data; 91 - remains = fw_entry->size; 83 + data = (__le32 *) priv->firmware->data; 84 + remains = priv->firmware->size; 92 85 device_addr = ISL38XX_DEV_FIRMWARE_ADDR; 93 86 while (remains) { 94 87 u32 i = 0; ··· 97 106 remains -= left; 98 107 P54P_READ(int_enable); 99 108 } 100 - 101 - release_firmware(fw_entry); 102 109 103 110 reg = P54P_READ(ctrl_stat); 104 111 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN); ··· 489 500 if (mem_len < sizeof(struct p54p_csr)) { 490 501 printk(KERN_ERR "%s (p54pci): Too short PCI resources\n", 491 502 pci_name(pdev)); 492 - pci_disable_device(pdev); 493 - return err; 503 + goto err_disable_dev; 494 504 } 495 505 496 506 err = pci_request_regions(pdev, "p54pci"); 497 507 if (err) { 498 508 printk(KERN_ERR "%s (p54pci): Cannot obtain PCI resources\n", 499 509 pci_name(pdev)); 500 - return err; 510 + goto err_disable_dev; 501 511 } 502 512 503 513 if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) || ··· 549 561 spin_lock_init(&priv->lock); 550 562 tasklet_init(&priv->rx_tasklet, p54p_rx_tasklet, (unsigned long)dev); 551 563 564 + err = request_firmware(&priv->firmware, "isl3886pci", 565 + &priv->pdev->dev); 566 + if (err) { 567 + printk(KERN_ERR "%s (p54pci): cannot find firmware " 568 + "(isl3886pci)\n", pci_name(priv->pdev)); 569 + err = request_firmware(&priv->firmware, "isl3886", 570 + &priv->pdev->dev); 571 + if (err) 572 + goto err_free_common; 573 + } 574 + 552 575 err = p54p_open(dev); 553 576 if (err) 554 577 goto err_free_common; ··· 578 579 return 0; 579 580 580 581 err_free_common: 582 + release_firmware(priv->firmware); 581 583 p54_free_common(dev); 582 584 pci_free_consistent(pdev, sizeof(*priv->ring_control), 583 585 priv->ring_control, priv->ring_control_dma); ··· 592 592 593 593 err_free_reg: 594 594 pci_release_regions(pdev); 595 + err_disable_dev: 595 596 pci_disable_device(pdev); 596 597 return err; 597 598 } ··· 607 606 608 607 ieee80211_unregister_hw(dev); 609 608 priv = dev->priv; 609 + release_firmware(priv->firmware); 610 610 pci_free_consistent(pdev, sizeof(*priv->ring_control), 611 611 priv->ring_control, priv->ring_control_dma); 612 612 p54_free_common(dev);
+1 -1
drivers/net/wireless/p54/p54pci.h
··· 93 93 struct pci_dev *pdev; 94 94 struct p54p_csr __iomem *map; 95 95 struct tasklet_struct rx_tasklet; 96 - 96 + const struct firmware *firmware; 97 97 spinlock_t lock; 98 98 struct p54p_ring_control *ring_control; 99 99 dma_addr_t ring_control_dma;