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: Arend Van Spriel <arend@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Signed-off-by: Hante Meuleman <meuleman@broadcom.com> Signed-off-by: Franky Lin <frankyl@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
2def5c10d2
commit
5b3c183272
|
@ -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)
|
||||||
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)
|
||||||
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)
|
||||||
#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)
|
||||||
#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;
|
|
||||||
}
|
|
||||||
bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL);
|
|
||||||
if (!bus_if)
|
|
||||||
return -ENOMEM;
|
|
||||||
sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL);
|
|
||||||
if (!sdiodev) {
|
|
||||||
kfree(bus_if);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
sdiodev->func[0] = func;
|
|
||||||
sdiodev->func[1] = func;
|
|
||||||
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);
|
/* Ignore anything but func 2 */
|
||||||
init_waitqueue_head(&sdiodev->request_byte_wait);
|
if (func->num != 2)
|
||||||
init_waitqueue_head(&sdiodev->request_word_wait);
|
return -ENODEV;
|
||||||
init_waitqueue_head(&sdiodev->request_chain_wait);
|
|
||||||
init_waitqueue_head(&sdiodev->request_buffer_wait);
|
bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL);
|
||||||
|
if (!bus_if)
|
||||||
|
return -ENOMEM;
|
||||||
|
sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL);
|
||||||
|
if (!sdiodev) {
|
||||||
|
kfree(bus_if);
|
||||||
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
sdiodev->bus_if = bus_if;
|
||||||
if (ret)
|
bus_if->bus_priv.sdio = sdiodev;
|
||||||
return ret;
|
bus_if->type = SDIO_BUS;
|
||||||
sdiodev->func[2] = func;
|
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;
|
||||||
|
|
||||||
bus_if = sdiodev->bus_if;
|
atomic_set(&sdiodev->suspend, false);
|
||||||
sdiodev->dev = &func->dev;
|
init_waitqueue_head(&sdiodev->request_byte_wait);
|
||||||
dev_set_drvdata(&func->dev, bus_if);
|
init_waitqueue_head(&sdiodev->request_word_wait);
|
||||||
|
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");
|
brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n");
|
||||||
ret = brcmf_sdio_probe(sdiodev);
|
err = brcmf_sdio_probe(sdiodev);
|
||||||
if (ret)
|
if (err) {
|
||||||
dev_set_drvdata(&func->dev, NULL);
|
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(INFO, "func->class=%x\n", func->class);
|
|
||||||
brcmf_dbg(INFO, "sdio_vendor: 0x%04x\n", func->vendor);
|
|
||||||
brcmf_dbg(INFO, "sdio_device: 0x%04x\n", func->device);
|
|
||||||
brcmf_dbg(INFO, "Function#: 0x%04x\n", func->num);
|
|
||||||
|
|
||||||
if (func->num == 2) {
|
brcmf_dbg(TRACE, "Enter\n");
|
||||||
bus_if = dev_get_drvdata(&func->dev);
|
brcmf_dbg(TRACE, "sdio vendor ID: 0x%04x\n", func->vendor);
|
||||||
|
brcmf_dbg(TRACE, "sdio device ID: 0x%04x\n", func->device);
|
||||||
|
brcmf_dbg(TRACE, "Function: %d\n", func->num);
|
||||||
|
|
||||||
|
if (func->num != 1 && func->num != 2)
|
||||||
|
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)
|
||||||
|
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue