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

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>

authored by

Hauke Mehrtens and committed by
Kalle Valo
53cd2fdb 78623bfb

+28 -3
+1
drivers/bcma/bcma_private.h
··· 34 34 int bcma_bus_suspend(struct bcma_bus *bus); 35 35 int bcma_bus_resume(struct bcma_bus *bus); 36 36 #endif 37 + struct device *bcma_bus_get_host_dev(struct bcma_bus *bus); 37 38 38 39 /* scan.c */ 39 40 void bcma_detect_chip(struct bcma_bus *bus);
+27 -3
drivers/bcma/main.c
··· 7 7 8 8 #include "bcma_private.h" 9 9 #include <linux/module.h> 10 + #include <linux/mmc/sdio_func.h> 10 11 #include <linux/platform_device.h> 12 + #include <linux/pci.h> 11 13 #include <linux/bcma/bcma.h> 12 14 #include <linux/slab.h> 13 15 #include <linux/of_address.h> ··· 271 269 } 272 270 } 273 271 272 + struct device *bcma_bus_get_host_dev(struct bcma_bus *bus) 273 + { 274 + switch (bus->hosttype) { 275 + case BCMA_HOSTTYPE_PCI: 276 + if (bus->host_pci) 277 + return &bus->host_pci->dev; 278 + else 279 + return NULL; 280 + case BCMA_HOSTTYPE_SOC: 281 + if (bus->host_pdev) 282 + return &bus->host_pdev->dev; 283 + else 284 + return NULL; 285 + case BCMA_HOSTTYPE_SDIO: 286 + if (bus->host_sdio) 287 + return &bus->host_sdio->dev; 288 + else 289 + return NULL; 290 + } 291 + return NULL; 292 + } 293 + 274 294 void bcma_init_bus(struct bcma_bus *bus) 275 295 { 276 296 mutex_lock(&bcma_buses_mutex); ··· 412 388 { 413 389 int err; 414 390 struct bcma_device *core; 391 + struct device *dev; 415 392 416 393 /* Scan for devices (cores) */ 417 394 err = bcma_bus_scan(bus); ··· 435 410 bcma_core_pci_early_init(&bus->drv_pci[0]); 436 411 } 437 412 413 + dev = bcma_bus_get_host_dev(bus); 438 414 /* TODO: remove check for IS_BUILTIN(CONFIG_BCMA) check when 439 415 * of_default_bus_match_table is exported or in some other way 440 416 * accessible. This is just a temporary workaround. 441 417 */ 442 - if (IS_BUILTIN(CONFIG_BCMA) && bus->host_pdev) { 443 - struct device *dev = &bus->host_pdev->dev; 444 - 418 + if (IS_BUILTIN(CONFIG_BCMA) && dev) { 445 419 of_platform_populate(dev->of_node, of_default_bus_match_table, 446 420 NULL, dev); 447 421 }