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>
This commit is contained in:
committed by
John W. Linville
parent
ffed785898
commit
40db0b2259
@@ -1524,16 +1524,24 @@ static int p54_start(struct ieee80211_hw *dev)
|
|||||||
|
|
||||||
mutex_lock(&priv->conf_mutex);
|
mutex_lock(&priv->conf_mutex);
|
||||||
err = priv->open(dev);
|
err = priv->open(dev);
|
||||||
if (!err)
|
if (err)
|
||||||
priv->mode = NL80211_IFTYPE_MONITOR;
|
goto out;
|
||||||
P54_SET_QUEUE(priv->qos_params[0], 0x0002, 0x0003, 0x0007, 47);
|
P54_SET_QUEUE(priv->qos_params[0], 0x0002, 0x0003, 0x0007, 47);
|
||||||
P54_SET_QUEUE(priv->qos_params[1], 0x0002, 0x0007, 0x000f, 94);
|
P54_SET_QUEUE(priv->qos_params[1], 0x0002, 0x0007, 0x000f, 94);
|
||||||
P54_SET_QUEUE(priv->qos_params[2], 0x0003, 0x000f, 0x03ff, 0);
|
P54_SET_QUEUE(priv->qos_params[2], 0x0003, 0x000f, 0x03ff, 0);
|
||||||
P54_SET_QUEUE(priv->qos_params[3], 0x0007, 0x000f, 0x03ff, 0);
|
P54_SET_QUEUE(priv->qos_params[3], 0x0007, 0x000f, 0x03ff, 0);
|
||||||
err = p54_set_edcf(dev);
|
err = p54_set_edcf(dev);
|
||||||
if (!err)
|
if (err)
|
||||||
|
goto out;
|
||||||
err = p54_init_stats(dev);
|
err = p54_init_stats(dev);
|
||||||
|
if (err)
|
||||||
|
goto out;
|
||||||
|
err = p54_setup_mac(dev, P54_FILTER_TYPE_NONE, NULL);
|
||||||
|
if (err)
|
||||||
|
goto out;
|
||||||
|
priv->mode = NL80211_IFTYPE_MONITOR;
|
||||||
|
|
||||||
|
out:
|
||||||
mutex_unlock(&priv->conf_mutex);
|
mutex_unlock(&priv->conf_mutex);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@@ -47,7 +47,6 @@ MODULE_DEVICE_TABLE(pci, p54p_table);
|
|||||||
static int p54p_upload_firmware(struct ieee80211_hw *dev)
|
static int p54p_upload_firmware(struct ieee80211_hw *dev)
|
||||||
{
|
{
|
||||||
struct p54p_priv *priv = dev->priv;
|
struct p54p_priv *priv = dev->priv;
|
||||||
const struct firmware *fw_entry = NULL;
|
|
||||||
__le32 reg;
|
__le32 reg;
|
||||||
int err;
|
int err;
|
||||||
__le32 *data;
|
__le32 *data;
|
||||||
@@ -73,23 +72,15 @@ static int p54p_upload_firmware(struct ieee80211_hw *dev)
|
|||||||
P54P_WRITE(ctrl_stat, reg);
|
P54P_WRITE(ctrl_stat, reg);
|
||||||
wmb();
|
wmb();
|
||||||
|
|
||||||
err = request_firmware(&fw_entry, "isl3886pci", &priv->pdev->dev);
|
/* wait for the firmware to reset properly */
|
||||||
if (err) {
|
mdelay(10);
|
||||||
printk(KERN_ERR "%s (p54pci): cannot find firmware "
|
|
||||||
"(isl3886pci)\n", pci_name(priv->pdev));
|
err = p54_parse_firmware(dev, priv->firmware);
|
||||||
err = request_firmware(&fw_entry, "isl3886", &priv->pdev->dev);
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
|
||||||
|
|
||||||
err = p54_parse_firmware(dev, fw_entry);
|
data = (__le32 *) priv->firmware->data;
|
||||||
if (err) {
|
remains = priv->firmware->size;
|
||||||
release_firmware(fw_entry);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
data = (__le32 *) fw_entry->data;
|
|
||||||
remains = fw_entry->size;
|
|
||||||
device_addr = ISL38XX_DEV_FIRMWARE_ADDR;
|
device_addr = ISL38XX_DEV_FIRMWARE_ADDR;
|
||||||
while (remains) {
|
while (remains) {
|
||||||
u32 i = 0;
|
u32 i = 0;
|
||||||
@@ -107,8 +98,6 @@ static int p54p_upload_firmware(struct ieee80211_hw *dev)
|
|||||||
P54P_READ(int_enable);
|
P54P_READ(int_enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
release_firmware(fw_entry);
|
|
||||||
|
|
||||||
reg = P54P_READ(ctrl_stat);
|
reg = P54P_READ(ctrl_stat);
|
||||||
reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
|
reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
|
||||||
reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
|
reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
|
||||||
@@ -500,15 +489,14 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
|
|||||||
if (mem_len < sizeof(struct p54p_csr)) {
|
if (mem_len < sizeof(struct p54p_csr)) {
|
||||||
printk(KERN_ERR "%s (p54pci): Too short PCI resources\n",
|
printk(KERN_ERR "%s (p54pci): Too short PCI resources\n",
|
||||||
pci_name(pdev));
|
pci_name(pdev));
|
||||||
pci_disable_device(pdev);
|
goto err_disable_dev;
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = pci_request_regions(pdev, "p54pci");
|
err = pci_request_regions(pdev, "p54pci");
|
||||||
if (err) {
|
if (err) {
|
||||||
printk(KERN_ERR "%s (p54pci): Cannot obtain PCI resources\n",
|
printk(KERN_ERR "%s (p54pci): Cannot obtain PCI resources\n",
|
||||||
pci_name(pdev));
|
pci_name(pdev));
|
||||||
return err;
|
goto err_disable_dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) ||
|
if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) ||
|
||||||
@@ -561,6 +549,17 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
|
|||||||
spin_lock_init(&priv->lock);
|
spin_lock_init(&priv->lock);
|
||||||
tasklet_init(&priv->rx_tasklet, p54p_rx_tasklet, (unsigned long)dev);
|
tasklet_init(&priv->rx_tasklet, p54p_rx_tasklet, (unsigned long)dev);
|
||||||
|
|
||||||
|
err = request_firmware(&priv->firmware, "isl3886pci",
|
||||||
|
&priv->pdev->dev);
|
||||||
|
if (err) {
|
||||||
|
printk(KERN_ERR "%s (p54pci): cannot find firmware "
|
||||||
|
"(isl3886pci)\n", pci_name(priv->pdev));
|
||||||
|
err = request_firmware(&priv->firmware, "isl3886",
|
||||||
|
&priv->pdev->dev);
|
||||||
|
if (err)
|
||||||
|
goto err_free_common;
|
||||||
|
}
|
||||||
|
|
||||||
err = p54p_open(dev);
|
err = p54p_open(dev);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_free_common;
|
goto err_free_common;
|
||||||
@@ -579,6 +578,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_free_common:
|
err_free_common:
|
||||||
|
release_firmware(priv->firmware);
|
||||||
p54_free_common(dev);
|
p54_free_common(dev);
|
||||||
pci_free_consistent(pdev, sizeof(*priv->ring_control),
|
pci_free_consistent(pdev, sizeof(*priv->ring_control),
|
||||||
priv->ring_control, priv->ring_control_dma);
|
priv->ring_control, priv->ring_control_dma);
|
||||||
@@ -592,6 +592,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
|
|||||||
|
|
||||||
err_free_reg:
|
err_free_reg:
|
||||||
pci_release_regions(pdev);
|
pci_release_regions(pdev);
|
||||||
|
err_disable_dev:
|
||||||
pci_disable_device(pdev);
|
pci_disable_device(pdev);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -606,6 +607,7 @@ static void __devexit p54p_remove(struct pci_dev *pdev)
|
|||||||
|
|
||||||
ieee80211_unregister_hw(dev);
|
ieee80211_unregister_hw(dev);
|
||||||
priv = dev->priv;
|
priv = dev->priv;
|
||||||
|
release_firmware(priv->firmware);
|
||||||
pci_free_consistent(pdev, sizeof(*priv->ring_control),
|
pci_free_consistent(pdev, sizeof(*priv->ring_control),
|
||||||
priv->ring_control, priv->ring_control_dma);
|
priv->ring_control, priv->ring_control_dma);
|
||||||
p54_free_common(dev);
|
p54_free_common(dev);
|
||||||
|
@@ -93,7 +93,7 @@ struct p54p_priv {
|
|||||||
struct pci_dev *pdev;
|
struct pci_dev *pdev;
|
||||||
struct p54p_csr __iomem *map;
|
struct p54p_csr __iomem *map;
|
||||||
struct tasklet_struct rx_tasklet;
|
struct tasklet_struct rx_tasklet;
|
||||||
|
const struct firmware *firmware;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
struct p54p_ring_control *ring_control;
|
struct p54p_ring_control *ring_control;
|
||||||
dma_addr_t ring_control_dma;
|
dma_addr_t ring_control_dma;
|
||||||
|
Reference in New Issue
Block a user