Commit 5b3c1832 authored by Hante Meuleman's avatar Hante Meuleman Committed by John W. Linville

brcmfmac: avoid usage of func->card->dev in sdio probe.

brcmf_ops_sdio_probe used the private_date func->card->dev to
store device data of brcmfmac sdio. This is not a good place to
store the data. Use dev of func and use func->card->sdio_func
to group the functions the driver is using.
Reviewed-by: default avatarArend Van Spriel <arend@broadcom.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: default avatarHante Meuleman <meuleman@broadcom.com>
Signed-off-by: default avatarFranky Lin <frankyl@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 2def5c10
...@@ -42,7 +42,8 @@ ...@@ -42,7 +42,8 @@
#ifdef CONFIG_BRCMFMAC_SDIO_OOB #ifdef CONFIG_BRCMFMAC_SDIO_OOB
static irqreturn_t brcmf_sdio_irqhandler(int irq, void *dev_id) static irqreturn_t brcmf_sdio_irqhandler(int irq, void *dev_id)
{ {
struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(dev_id); struct brcmf_bus *bus_if = dev_get_drvdata(dev_id);
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
brcmf_dbg(INTR, "oob intr triggered\n"); brcmf_dbg(INTR, "oob intr triggered\n");
...@@ -71,7 +72,7 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) ...@@ -71,7 +72,7 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
brcmf_dbg(ERROR, "requesting irq %d\n", sdiodev->irq); brcmf_dbg(ERROR, "requesting irq %d\n", sdiodev->irq);
ret = request_irq(sdiodev->irq, brcmf_sdio_irqhandler, ret = request_irq(sdiodev->irq, brcmf_sdio_irqhandler,
sdiodev->irq_flags, "brcmf_oob_intr", sdiodev->irq_flags, "brcmf_oob_intr",
&sdiodev->func[1]->card->dev); &sdiodev->func[1]->dev);
if (ret != 0) if (ret != 0)
return ret; return ret;
spin_lock_init(&sdiodev->irq_en_lock); spin_lock_init(&sdiodev->irq_en_lock);
...@@ -115,7 +116,7 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) ...@@ -115,7 +116,7 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
disable_irq_wake(sdiodev->irq); disable_irq_wake(sdiodev->irq);
sdiodev->irq_wake = false; sdiodev->irq_wake = false;
} }
free_irq(sdiodev->irq, &sdiodev->func[1]->card->dev); free_irq(sdiodev->irq, &sdiodev->func[1]->dev);
sdiodev->irq_en = false; sdiodev->irq_en = false;
return 0; return 0;
...@@ -123,7 +124,8 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) ...@@ -123,7 +124,8 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
#else /* CONFIG_BRCMFMAC_SDIO_OOB */ #else /* CONFIG_BRCMFMAC_SDIO_OOB */
static void brcmf_sdio_irqhandler(struct sdio_func *func) static void brcmf_sdio_irqhandler(struct sdio_func *func)
{ {
struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev); struct brcmf_bus *bus_if = dev_get_drvdata(&func->dev);
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
brcmf_dbg(INTR, "ib intr triggered\n"); brcmf_dbg(INTR, "ib intr triggered\n");
......
...@@ -456,101 +456,107 @@ static inline int brcmf_sdio_getintrcfg(struct brcmf_sdio_dev *sdiodev) ...@@ -456,101 +456,107 @@ static inline int brcmf_sdio_getintrcfg(struct brcmf_sdio_dev *sdiodev)
#endif /* CONFIG_BRCMFMAC_SDIO_OOB */ #endif /* CONFIG_BRCMFMAC_SDIO_OOB */
static int brcmf_ops_sdio_probe(struct sdio_func *func, static int brcmf_ops_sdio_probe(struct sdio_func *func,
const struct sdio_device_id *id) const struct sdio_device_id *id)
{ {
int ret = 0; int err;
struct brcmf_sdio_dev *sdiodev; struct brcmf_sdio_dev *sdiodev;
struct brcmf_bus *bus_if; struct brcmf_bus *bus_if;
brcmf_dbg(TRACE, "Enter\n"); brcmf_dbg(TRACE, "Enter\n");
brcmf_dbg(TRACE, "func->class=%x\n", func->class); brcmf_dbg(TRACE, "Class=%x\n", func->class);
brcmf_dbg(TRACE, "sdio_vendor: 0x%04x\n", func->vendor); brcmf_dbg(TRACE, "sdio vendor ID: 0x%04x\n", func->vendor);
brcmf_dbg(TRACE, "sdio_device: 0x%04x\n", func->device); brcmf_dbg(TRACE, "sdio device ID: 0x%04x\n", func->device);
brcmf_dbg(TRACE, "Function#: 0x%04x\n", func->num); brcmf_dbg(TRACE, "Function#: %d\n", func->num);
if (func->num == 1) { /* Consume func num 1 but dont do anything with it. */
if (dev_get_drvdata(&func->card->dev)) { if (func->num == 1)
brcmf_dbg(ERROR, "card private drvdata occupied\n"); return 0;
return -ENXIO;
} /* Ignore anything but func 2 */
bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL); if (func->num != 2)
if (!bus_if) return -ENODEV;
return -ENOMEM;
sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL); bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL);
if (!sdiodev) { if (!bus_if)
kfree(bus_if); return -ENOMEM;
return -ENOMEM; sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL);
} if (!sdiodev) {
sdiodev->func[0] = func; kfree(bus_if);
sdiodev->func[1] = func; return -ENOMEM;
sdiodev->bus_if = bus_if;
bus_if->bus_priv.sdio = sdiodev;
bus_if->type = SDIO_BUS;
bus_if->align = BRCMF_SDALIGN;
dev_set_drvdata(&func->card->dev, sdiodev);
atomic_set(&sdiodev->suspend, false);
init_waitqueue_head(&sdiodev->request_byte_wait);
init_waitqueue_head(&sdiodev->request_word_wait);
init_waitqueue_head(&sdiodev->request_chain_wait);
init_waitqueue_head(&sdiodev->request_buffer_wait);
} }
if (func->num == 2) { sdiodev->func[0] = func->card->sdio_func[0];
sdiodev = dev_get_drvdata(&func->card->dev); sdiodev->func[1] = func->card->sdio_func[0];
if ((!sdiodev) || (sdiodev->func[1]->card != func->card)) sdiodev->func[2] = func;
return -ENODEV;
ret = brcmf_sdio_getintrcfg(sdiodev);
if (ret)
return ret;
sdiodev->func[2] = func;
bus_if = sdiodev->bus_if; sdiodev->bus_if = bus_if;
sdiodev->dev = &func->dev; bus_if->bus_priv.sdio = sdiodev;
dev_set_drvdata(&func->dev, bus_if); bus_if->type = SDIO_BUS;
bus_if->align = BRCMF_SDALIGN;
dev_set_drvdata(&func->dev, bus_if);
dev_set_drvdata(&sdiodev->func[1]->dev, bus_if);
sdiodev->dev = &sdiodev->func[1]->dev;
brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n"); atomic_set(&sdiodev->suspend, false);
ret = brcmf_sdio_probe(sdiodev); init_waitqueue_head(&sdiodev->request_byte_wait);
if (ret) init_waitqueue_head(&sdiodev->request_word_wait);
dev_set_drvdata(&func->dev, NULL); init_waitqueue_head(&sdiodev->request_chain_wait);
init_waitqueue_head(&sdiodev->request_buffer_wait);
err = brcmf_sdio_getintrcfg(sdiodev);
if (err)
goto fail;
brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n");
err = brcmf_sdio_probe(sdiodev);
if (err) {
brcmf_dbg(ERROR, "F2 error, probe failed %d...\n", err);
goto fail;
} }
brcmf_dbg(TRACE, "F2 init completed...\n");
return 0;
return ret; fail:
dev_set_drvdata(&func->dev, NULL);
dev_set_drvdata(&sdiodev->func[1]->dev, NULL);
kfree(sdiodev);
kfree(bus_if);
return err;
} }
static void brcmf_ops_sdio_remove(struct sdio_func *func) static void brcmf_ops_sdio_remove(struct sdio_func *func)
{ {
struct brcmf_bus *bus_if; struct brcmf_bus *bus_if;
struct brcmf_sdio_dev *sdiodev; struct brcmf_sdio_dev *sdiodev;
brcmf_dbg(TRACE, "Enter\n"); brcmf_dbg(TRACE, "Enter\n");
brcmf_dbg(INFO, "func->class=%x\n", func->class); brcmf_dbg(TRACE, "sdio vendor ID: 0x%04x\n", func->vendor);
brcmf_dbg(INFO, "sdio_vendor: 0x%04x\n", func->vendor); brcmf_dbg(TRACE, "sdio device ID: 0x%04x\n", func->device);
brcmf_dbg(INFO, "sdio_device: 0x%04x\n", func->device); brcmf_dbg(TRACE, "Function: %d\n", func->num);
brcmf_dbg(INFO, "Function#: 0x%04x\n", func->num);
if (func->num == 2) { if (func->num != 1 && func->num != 2)
bus_if = dev_get_drvdata(&func->dev); return;
bus_if = dev_get_drvdata(&func->dev);
if (bus_if) {
sdiodev = bus_if->bus_priv.sdio; sdiodev = bus_if->bus_priv.sdio;
brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_remove...\n");
brcmf_sdio_remove(sdiodev); brcmf_sdio_remove(sdiodev);
dev_set_drvdata(&func->dev, NULL);
} dev_set_drvdata(&sdiodev->func[1]->dev, NULL);
if (func->num == 1) { dev_set_drvdata(&sdiodev->func[2]->dev, NULL);
sdiodev = dev_get_drvdata(&func->card->dev);
bus_if = sdiodev->bus_if;
dev_set_drvdata(&func->card->dev, NULL);
kfree(bus_if); kfree(bus_if);
kfree(sdiodev); kfree(sdiodev);
} }
brcmf_dbg(TRACE, "Exit\n");
} }
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static int brcmf_sdio_suspend(struct device *dev) static int brcmf_sdio_suspend(struct device *dev)
{ {
mmc_pm_flag_t sdio_flags; mmc_pm_flag_t sdio_flags;
struct sdio_func *func = dev_to_sdio_func(dev); struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev); struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
int ret = 0; int ret = 0;
brcmf_dbg(TRACE, "\n"); brcmf_dbg(TRACE, "\n");
...@@ -576,8 +582,8 @@ static int brcmf_sdio_suspend(struct device *dev) ...@@ -576,8 +582,8 @@ static int brcmf_sdio_suspend(struct device *dev)
static int brcmf_sdio_resume(struct device *dev) static int brcmf_sdio_resume(struct device *dev)
{ {
struct sdio_func *func = dev_to_sdio_func(dev); struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev); struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
brcmf_sdio_wdtmr_enable(sdiodev, true); brcmf_sdio_wdtmr_enable(sdiodev, true);
atomic_set(&sdiodev->suspend, false); atomic_set(&sdiodev->suspend, false);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment