Merge tag 'tty-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
[firefly-linux-kernel-4.4.55.git] / drivers / bcma / main.c
index 534e1337766d2d0ba9d7e8d220a30434da23ef5d..38bde6eab8a41867d92de40f7083e411efe67aeb 100644 (file)
@@ -268,6 +268,18 @@ void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core)
        }
 }
 
+void bcma_init_bus(struct bcma_bus *bus)
+{
+       mutex_lock(&bcma_buses_mutex);
+       bus->num = bcma_bus_next_num++;
+       mutex_unlock(&bcma_buses_mutex);
+
+       INIT_LIST_HEAD(&bus->cores);
+       bus->nr_cores = 0;
+
+       bcma_detect_chip(bus);
+}
+
 static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core)
 {
        int err;
@@ -356,12 +368,19 @@ static void bcma_unregister_cores(struct bcma_bus *bus)
        struct bcma_device *core, *tmp;
 
        list_for_each_entry_safe(core, tmp, &bus->cores, list) {
+               if (!core->dev_registered)
+                       continue;
                list_del(&core->list);
-               if (core->dev_registered)
-                       device_unregister(&core->dev);
+               device_unregister(&core->dev);
        }
        if (bus->hosttype == BCMA_HOSTTYPE_SOC)
                platform_device_unregister(bus->drv_cc.watchdog);
+
+       /* Now noone uses internally-handled cores, we can free them */
+       list_for_each_entry_safe(core, tmp, &bus->cores, list) {
+               list_del(&core->list);
+               kfree(core);
+       }
 }
 
 int bcma_bus_register(struct bcma_bus *bus)
@@ -369,10 +388,6 @@ int bcma_bus_register(struct bcma_bus *bus)
        int err;
        struct bcma_device *core;
 
-       mutex_lock(&bcma_buses_mutex);
-       bus->num = bcma_bus_next_num++;
-       mutex_unlock(&bcma_buses_mutex);
-
        /* Scan for devices (cores) */
        err = bcma_bus_scan(bus);
        if (err) {
@@ -387,6 +402,13 @@ int bcma_bus_register(struct bcma_bus *bus)
                bcma_core_chipcommon_early_init(&bus->drv_cc);
        }
 
+       /* Early init PCIE core */
+       core = bcma_find_core(bus, BCMA_CORE_PCIE);
+       if (core) {
+               bus->drv_pci[0].core = core;
+               bcma_core_pci_early_init(&bus->drv_pci[0]);
+       }
+
        /* Cores providing flash access go before SPROM init */
        list_for_each_entry(core, &bus->cores, list) {
                if (bcma_is_core_needed_early(core->id.id))
@@ -459,7 +481,6 @@ int bcma_bus_register(struct bcma_bus *bus)
 
 void bcma_bus_unregister(struct bcma_bus *bus)
 {
-       struct bcma_device *cores[3];
        int err;
 
        err = bcma_gpio_unregister(&bus->drv_cc);
@@ -470,46 +491,23 @@ void bcma_bus_unregister(struct bcma_bus *bus)
 
        bcma_core_chipcommon_b_free(&bus->drv_cc_b);
 
-       cores[0] = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
-       cores[1] = bcma_find_core(bus, BCMA_CORE_PCIE);
-       cores[2] = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON);
-
        bcma_unregister_cores(bus);
-
-       kfree(cores[2]);
-       kfree(cores[1]);
-       kfree(cores[0]);
 }
 
-int __init bcma_bus_early_register(struct bcma_bus *bus,
-                                  struct bcma_device *core_cc,
-                                  struct bcma_device *core_mips)
+/*
+ * This is a special version of bus registration function designed for SoCs.
+ * It scans bus and performs basic initialization of main cores only.
+ * Please note it requires memory allocation, however it won't try to sleep.
+ */
+int __init bcma_bus_early_register(struct bcma_bus *bus)
 {
        int err;
        struct bcma_device *core;
-       struct bcma_device_id match;
 
-       match.manuf = BCMA_MANUF_BCM;
-       match.id = bcma_cc_core_id(bus);
-       match.class = BCMA_CL_SIM;
-       match.rev = BCMA_ANY_REV;
-
-       /* Scan for chip common core */
-       err = bcma_bus_scan_early(bus, &match, core_cc);
-       if (err) {
-               bcma_err(bus, "Failed to scan for common core: %d\n", err);
-               return -1;
-       }
-
-       match.manuf = BCMA_MANUF_MIPS;
-       match.id = BCMA_CORE_MIPS_74K;
-       match.class = BCMA_CL_SIM;
-       match.rev = BCMA_ANY_REV;
-
-       /* Scan for mips core */
-       err = bcma_bus_scan_early(bus, &match, core_mips);
+       /* Scan for devices (cores) */
+       err = bcma_bus_scan(bus);
        if (err) {
-               bcma_err(bus, "Failed to scan for mips core: %d\n", err);
+               bcma_err(bus, "Failed to scan bus: %d\n", err);
                return -1;
        }