diff options
author | Hauke Mehrtens <hauke@hauke-m.de> | 2015-08-02 14:26:52 -0400 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2015-08-10 15:20:46 -0400 |
commit | 53cd2fdb00aab34f91762f6345f83625a30480f0 (patch) | |
tree | fd6d98807ed921b7e2ccdd7d2257bfc9dc7083f9 /drivers/bcma | |
parent | 78623bfb6f4cbdba3183621e8e0e781611217022 (diff) |
bcma: fix access to host_pdev for PCIe devices
bus->host_pdev is part of a union so bus->host_pdev != NULL is probably
also true for PCIe devices, because there it accesses bus->host_pci. If
we access the dev member at the offset defined in struct
platform_device in struct pci_dev instead we probably get something
else.
This patch adds a new function which returns the host dev struct and
NULL if we do not have a host dev. When this gets registered on MIPS
brcm47xx we do not have a host dev in some situations.
This function could also be used in other places.
This problem was introduced in this commit:
commit cae761b5a6bdc597ba476a040fdcd5b4bc559b85
Author: Rafa? Mi?ecki <zajec5@gmail.com>
Date: Sun Jun 28 17:17:13 2015 +0200
bcma: populate bus DT subnodes as platform_device-s
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/bcma')
-rw-r--r-- | drivers/bcma/bcma_private.h | 1 | ||||
-rw-r--r-- | drivers/bcma/main.c | 30 |
2 files changed, 28 insertions, 3 deletions
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h index 15f2b2e242ea..38f156745d53 100644 --- a/drivers/bcma/bcma_private.h +++ b/drivers/bcma/bcma_private.h | |||
@@ -34,6 +34,7 @@ int __init bcma_bus_early_register(struct bcma_bus *bus); | |||
34 | int bcma_bus_suspend(struct bcma_bus *bus); | 34 | int bcma_bus_suspend(struct bcma_bus *bus); |
35 | int bcma_bus_resume(struct bcma_bus *bus); | 35 | int bcma_bus_resume(struct bcma_bus *bus); |
36 | #endif | 36 | #endif |
37 | struct device *bcma_bus_get_host_dev(struct bcma_bus *bus); | ||
37 | 38 | ||
38 | /* scan.c */ | 39 | /* scan.c */ |
39 | void bcma_detect_chip(struct bcma_bus *bus); | 40 | void bcma_detect_chip(struct bcma_bus *bus); |
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 8d973c4fc84e..24882c18fcbe 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c | |||
@@ -7,7 +7,9 @@ | |||
7 | 7 | ||
8 | #include "bcma_private.h" | 8 | #include "bcma_private.h" |
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/mmc/sdio_func.h> | ||
10 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
12 | #include <linux/pci.h> | ||
11 | #include <linux/bcma/bcma.h> | 13 | #include <linux/bcma/bcma.h> |
12 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
13 | #include <linux/of_address.h> | 15 | #include <linux/of_address.h> |
@@ -269,6 +271,28 @@ void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core) | |||
269 | } | 271 | } |
270 | } | 272 | } |
271 | 273 | ||
274 | struct device *bcma_bus_get_host_dev(struct bcma_bus *bus) | ||
275 | { | ||
276 | switch (bus->hosttype) { | ||
277 | case BCMA_HOSTTYPE_PCI: | ||
278 | if (bus->host_pci) | ||
279 | return &bus->host_pci->dev; | ||
280 | else | ||
281 | return NULL; | ||
282 | case BCMA_HOSTTYPE_SOC: | ||
283 | if (bus->host_pdev) | ||
284 | return &bus->host_pdev->dev; | ||
285 | else | ||
286 | return NULL; | ||
287 | case BCMA_HOSTTYPE_SDIO: | ||
288 | if (bus->host_sdio) | ||
289 | return &bus->host_sdio->dev; | ||
290 | else | ||
291 | return NULL; | ||
292 | } | ||
293 | return NULL; | ||
294 | } | ||
295 | |||
272 | void bcma_init_bus(struct bcma_bus *bus) | 296 | void bcma_init_bus(struct bcma_bus *bus) |
273 | { | 297 | { |
274 | mutex_lock(&bcma_buses_mutex); | 298 | mutex_lock(&bcma_buses_mutex); |
@@ -388,6 +412,7 @@ int bcma_bus_register(struct bcma_bus *bus) | |||
388 | { | 412 | { |
389 | int err; | 413 | int err; |
390 | struct bcma_device *core; | 414 | struct bcma_device *core; |
415 | struct device *dev; | ||
391 | 416 | ||
392 | /* Scan for devices (cores) */ | 417 | /* Scan for devices (cores) */ |
393 | err = bcma_bus_scan(bus); | 418 | err = bcma_bus_scan(bus); |
@@ -410,13 +435,12 @@ int bcma_bus_register(struct bcma_bus *bus) | |||
410 | bcma_core_pci_early_init(&bus->drv_pci[0]); | 435 | bcma_core_pci_early_init(&bus->drv_pci[0]); |
411 | } | 436 | } |
412 | 437 | ||
438 | dev = bcma_bus_get_host_dev(bus); | ||
413 | /* TODO: remove check for IS_BUILTIN(CONFIG_BCMA) check when | 439 | /* TODO: remove check for IS_BUILTIN(CONFIG_BCMA) check when |
414 | * of_default_bus_match_table is exported or in some other way | 440 | * of_default_bus_match_table is exported or in some other way |
415 | * accessible. This is just a temporary workaround. | 441 | * accessible. This is just a temporary workaround. |
416 | */ | 442 | */ |
417 | if (IS_BUILTIN(CONFIG_BCMA) && bus->host_pdev) { | 443 | if (IS_BUILTIN(CONFIG_BCMA) && dev) { |
418 | struct device *dev = &bus->host_pdev->dev; | ||
419 | |||
420 | of_platform_populate(dev->of_node, of_default_bus_match_table, | 444 | of_platform_populate(dev->of_node, of_default_bus_match_table, |
421 | NULL, dev); | 445 | NULL, dev); |
422 | } | 446 | } |