linux/drivers/bcma/main.c
<<
>>
Prefs
   1/*
   2 * Broadcom specific AMBA
   3 * Bus subsystem
   4 *
   5 * Licensed under the GNU/GPL. See COPYING for details.
   6 */
   7
   8#include "bcma_private.h"
   9#include <linux/module.h>
  10#include <linux/platform_device.h>
  11#include <linux/bcma/bcma.h>
  12#include <linux/slab.h>
  13
  14MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
  15MODULE_LICENSE("GPL");
  16
  17/* contains the number the next bus should get. */
  18static unsigned int bcma_bus_next_num = 0;
  19
  20/* bcma_buses_mutex locks the bcma_bus_next_num */
  21static DEFINE_MUTEX(bcma_buses_mutex);
  22
  23static int bcma_bus_match(struct device *dev, struct device_driver *drv);
  24static int bcma_device_probe(struct device *dev);
  25static int bcma_device_remove(struct device *dev);
  26static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env);
  27
  28static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf)
  29{
  30        struct bcma_device *core = container_of(dev, struct bcma_device, dev);
  31        return sprintf(buf, "0x%03X\n", core->id.manuf);
  32}
  33static DEVICE_ATTR_RO(manuf);
  34
  35static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf)
  36{
  37        struct bcma_device *core = container_of(dev, struct bcma_device, dev);
  38        return sprintf(buf, "0x%03X\n", core->id.id);
  39}
  40static DEVICE_ATTR_RO(id);
  41
  42static ssize_t rev_show(struct device *dev, struct device_attribute *attr, char *buf)
  43{
  44        struct bcma_device *core = container_of(dev, struct bcma_device, dev);
  45        return sprintf(buf, "0x%02X\n", core->id.rev);
  46}
  47static DEVICE_ATTR_RO(rev);
  48
  49static ssize_t class_show(struct device *dev, struct device_attribute *attr, char *buf)
  50{
  51        struct bcma_device *core = container_of(dev, struct bcma_device, dev);
  52        return sprintf(buf, "0x%X\n", core->id.class);
  53}
  54static DEVICE_ATTR_RO(class);
  55
  56static struct attribute *bcma_device_attrs[] = {
  57        &dev_attr_manuf.attr,
  58        &dev_attr_id.attr,
  59        &dev_attr_rev.attr,
  60        &dev_attr_class.attr,
  61        NULL,
  62};
  63ATTRIBUTE_GROUPS(bcma_device);
  64
  65static struct bus_type bcma_bus_type = {
  66        .name           = "bcma",
  67        .match          = bcma_bus_match,
  68        .probe          = bcma_device_probe,
  69        .remove         = bcma_device_remove,
  70        .uevent         = bcma_device_uevent,
  71        .dev_groups     = bcma_device_groups,
  72};
  73
  74static u16 bcma_cc_core_id(struct bcma_bus *bus)
  75{
  76        if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706)
  77                return BCMA_CORE_4706_CHIPCOMMON;
  78        return BCMA_CORE_CHIPCOMMON;
  79}
  80
  81struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
  82                                        u8 unit)
  83{
  84        struct bcma_device *core;
  85
  86        list_for_each_entry(core, &bus->cores, list) {
  87                if (core->id.id == coreid && core->core_unit == unit)
  88                        return core;
  89        }
  90        return NULL;
  91}
  92EXPORT_SYMBOL_GPL(bcma_find_core_unit);
  93
  94bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value,
  95                     int timeout)
  96{
  97        unsigned long deadline = jiffies + timeout;
  98        u32 val;
  99
 100        do {
 101                val = bcma_read32(core, reg);
 102                if ((val & mask) == value)
 103                        return true;
 104                cpu_relax();
 105                udelay(10);
 106        } while (!time_after_eq(jiffies, deadline));
 107
 108        bcma_warn(core->bus, "Timeout waiting for register 0x%04X!\n", reg);
 109
 110        return false;
 111}
 112
 113static void bcma_release_core_dev(struct device *dev)
 114{
 115        struct bcma_device *core = container_of(dev, struct bcma_device, dev);
 116        if (core->io_addr)
 117                iounmap(core->io_addr);
 118        if (core->io_wrap)
 119                iounmap(core->io_wrap);
 120        kfree(core);
 121}
 122
 123static int bcma_register_cores(struct bcma_bus *bus)
 124{
 125        struct bcma_device *core;
 126        int err, dev_id = 0;
 127
 128        list_for_each_entry(core, &bus->cores, list) {
 129                /* We support that cores ourself */
 130                switch (core->id.id) {
 131                case BCMA_CORE_4706_CHIPCOMMON:
 132                case BCMA_CORE_CHIPCOMMON:
 133                case BCMA_CORE_PCI:
 134                case BCMA_CORE_PCIE:
 135                case BCMA_CORE_MIPS_74K:
 136                case BCMA_CORE_4706_MAC_GBIT_COMMON:
 137                        continue;
 138                }
 139
 140                /* Only first GMAC core on BCM4706 is connected and working */
 141                if (core->id.id == BCMA_CORE_4706_MAC_GBIT &&
 142                    core->core_unit > 0)
 143                        continue;
 144
 145                core->dev.release = bcma_release_core_dev;
 146                core->dev.bus = &bcma_bus_type;
 147                dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id);
 148
 149                switch (bus->hosttype) {
 150                case BCMA_HOSTTYPE_PCI:
 151                        core->dev.parent = &bus->host_pci->dev;
 152                        core->dma_dev = &bus->host_pci->dev;
 153                        core->irq = bus->host_pci->irq;
 154                        break;
 155                case BCMA_HOSTTYPE_SOC:
 156                        core->dev.dma_mask = &core->dev.coherent_dma_mask;
 157                        core->dma_dev = &core->dev;
 158                        break;
 159                case BCMA_HOSTTYPE_SDIO:
 160                        break;
 161                }
 162
 163                err = device_register(&core->dev);
 164                if (err) {
 165                        bcma_err(bus,
 166                                 "Could not register dev for core 0x%03X\n",
 167                                 core->id.id);
 168                        put_device(&core->dev);
 169                        continue;
 170                }
 171                core->dev_registered = true;
 172                dev_id++;
 173        }
 174
 175#ifdef CONFIG_BCMA_DRIVER_MIPS
 176        if (bus->drv_cc.pflash.present) {
 177                err = platform_device_register(&bcma_pflash_dev);
 178                if (err)
 179                        bcma_err(bus, "Error registering parallel flash\n");
 180        }
 181#endif
 182
 183#ifdef CONFIG_BCMA_SFLASH
 184        if (bus->drv_cc.sflash.present) {
 185                err = platform_device_register(&bcma_sflash_dev);
 186                if (err)
 187                        bcma_err(bus, "Error registering serial flash\n");
 188        }
 189#endif
 190
 191#ifdef CONFIG_BCMA_NFLASH
 192        if (bus->drv_cc.nflash.present) {
 193                err = platform_device_register(&bcma_nflash_dev);
 194                if (err)
 195                        bcma_err(bus, "Error registering NAND flash\n");
 196        }
 197#endif
 198        err = bcma_gpio_init(&bus->drv_cc);
 199        if (err == -ENOTSUPP)
 200                bcma_debug(bus, "GPIO driver not activated\n");
 201        else if (err)
 202                bcma_err(bus, "Error registering GPIO driver: %i\n", err);
 203
 204        if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
 205                err = bcma_chipco_watchdog_register(&bus->drv_cc);
 206                if (err)
 207                        bcma_err(bus, "Error registering watchdog driver\n");
 208        }
 209
 210        return 0;
 211}
 212
 213static void bcma_unregister_cores(struct bcma_bus *bus)
 214{
 215        struct bcma_device *core, *tmp;
 216
 217        list_for_each_entry_safe(core, tmp, &bus->cores, list) {
 218                list_del(&core->list);
 219                if (core->dev_registered)
 220                        device_unregister(&core->dev);
 221        }
 222        if (bus->hosttype == BCMA_HOSTTYPE_SOC)
 223                platform_device_unregister(bus->drv_cc.watchdog);
 224}
 225
 226int bcma_bus_register(struct bcma_bus *bus)
 227{
 228        int err;
 229        struct bcma_device *core;
 230
 231        mutex_lock(&bcma_buses_mutex);
 232        bus->num = bcma_bus_next_num++;
 233        mutex_unlock(&bcma_buses_mutex);
 234
 235        /* Scan for devices (cores) */
 236        err = bcma_bus_scan(bus);
 237        if (err) {
 238                bcma_err(bus, "Failed to scan: %d\n", err);
 239                return err;
 240        }
 241
 242        /* Early init CC core */
 243        core = bcma_find_core(bus, bcma_cc_core_id(bus));
 244        if (core) {
 245                bus->drv_cc.core = core;
 246                bcma_core_chipcommon_early_init(&bus->drv_cc);
 247        }
 248
 249        /* Try to get SPROM */
 250        err = bcma_sprom_get(bus);
 251        if (err == -ENOENT) {
 252                bcma_err(bus, "No SPROM available\n");
 253        } else if (err)
 254                bcma_err(bus, "Failed to get SPROM: %d\n", err);
 255
 256        /* Init CC core */
 257        core = bcma_find_core(bus, bcma_cc_core_id(bus));
 258        if (core) {
 259                bus->drv_cc.core = core;
 260                bcma_core_chipcommon_init(&bus->drv_cc);
 261        }
 262
 263        /* Init MIPS core */
 264        core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
 265        if (core) {
 266                bus->drv_mips.core = core;
 267                bcma_core_mips_init(&bus->drv_mips);
 268        }
 269
 270        /* Init PCIE core */
 271        core = bcma_find_core_unit(bus, BCMA_CORE_PCIE, 0);
 272        if (core) {
 273                bus->drv_pci[0].core = core;
 274                bcma_core_pci_init(&bus->drv_pci[0]);
 275        }
 276
 277        /* Init PCIE core */
 278        core = bcma_find_core_unit(bus, BCMA_CORE_PCIE, 1);
 279        if (core) {
 280                bus->drv_pci[1].core = core;
 281                bcma_core_pci_init(&bus->drv_pci[1]);
 282        }
 283
 284        /* Init GBIT MAC COMMON core */
 285        core = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON);
 286        if (core) {
 287                bus->drv_gmac_cmn.core = core;
 288                bcma_core_gmac_cmn_init(&bus->drv_gmac_cmn);
 289        }
 290
 291        /* Register found cores */
 292        bcma_register_cores(bus);
 293
 294        bcma_info(bus, "Bus registered\n");
 295
 296        return 0;
 297}
 298
 299void bcma_bus_unregister(struct bcma_bus *bus)
 300{
 301        struct bcma_device *cores[3];
 302        int err;
 303
 304        err = bcma_gpio_unregister(&bus->drv_cc);
 305        if (err == -EBUSY)
 306                bcma_err(bus, "Some GPIOs are still in use.\n");
 307        else if (err)
 308                bcma_err(bus, "Can not unregister GPIO driver: %i\n", err);
 309
 310        cores[0] = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
 311        cores[1] = bcma_find_core(bus, BCMA_CORE_PCIE);
 312        cores[2] = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON);
 313
 314        bcma_unregister_cores(bus);
 315
 316        kfree(cores[2]);
 317        kfree(cores[1]);
 318        kfree(cores[0]);
 319}
 320
 321int __init bcma_bus_early_register(struct bcma_bus *bus,
 322                                   struct bcma_device *core_cc,
 323                                   struct bcma_device *core_mips)
 324{
 325        int err;
 326        struct bcma_device *core;
 327        struct bcma_device_id match;
 328
 329        bcma_init_bus(bus);
 330
 331        match.manuf = BCMA_MANUF_BCM;
 332        match.id = bcma_cc_core_id(bus);
 333        match.class = BCMA_CL_SIM;
 334        match.rev = BCMA_ANY_REV;
 335
 336        /* Scan for chip common core */
 337        err = bcma_bus_scan_early(bus, &match, core_cc);
 338        if (err) {
 339                bcma_err(bus, "Failed to scan for common core: %d\n", err);
 340                return -1;
 341        }
 342
 343        match.manuf = BCMA_MANUF_MIPS;
 344        match.id = BCMA_CORE_MIPS_74K;
 345        match.class = BCMA_CL_SIM;
 346        match.rev = BCMA_ANY_REV;
 347
 348        /* Scan for mips core */
 349        err = bcma_bus_scan_early(bus, &match, core_mips);
 350        if (err) {
 351                bcma_err(bus, "Failed to scan for mips core: %d\n", err);
 352                return -1;
 353        }
 354
 355        /* Early init CC core */
 356        core = bcma_find_core(bus, bcma_cc_core_id(bus));
 357        if (core) {
 358                bus->drv_cc.core = core;
 359                bcma_core_chipcommon_early_init(&bus->drv_cc);
 360        }
 361
 362        /* Early init MIPS core */
 363        core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
 364        if (core) {
 365                bus->drv_mips.core = core;
 366                bcma_core_mips_early_init(&bus->drv_mips);
 367        }
 368
 369        bcma_info(bus, "Early bus registered\n");
 370
 371        return 0;
 372}
 373
 374#ifdef CONFIG_PM
 375int bcma_bus_suspend(struct bcma_bus *bus)
 376{
 377        struct bcma_device *core;
 378
 379        list_for_each_entry(core, &bus->cores, list) {
 380                struct device_driver *drv = core->dev.driver;
 381                if (drv) {
 382                        struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
 383                        if (adrv->suspend)
 384                                adrv->suspend(core);
 385                }
 386        }
 387        return 0;
 388}
 389
 390int bcma_bus_resume(struct bcma_bus *bus)
 391{
 392        struct bcma_device *core;
 393
 394        /* Init CC core */
 395        if (bus->drv_cc.core) {
 396                bus->drv_cc.setup_done = false;
 397                bcma_core_chipcommon_init(&bus->drv_cc);
 398        }
 399
 400        list_for_each_entry(core, &bus->cores, list) {
 401                struct device_driver *drv = core->dev.driver;
 402                if (drv) {
 403                        struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
 404                        if (adrv->resume)
 405                                adrv->resume(core);
 406                }
 407        }
 408
 409        return 0;
 410}
 411#endif
 412
 413int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
 414{
 415        drv->drv.name = drv->name;
 416        drv->drv.bus = &bcma_bus_type;
 417        drv->drv.owner = owner;
 418
 419        return driver_register(&drv->drv);
 420}
 421EXPORT_SYMBOL_GPL(__bcma_driver_register);
 422
 423void bcma_driver_unregister(struct bcma_driver *drv)
 424{
 425        driver_unregister(&drv->drv);
 426}
 427EXPORT_SYMBOL_GPL(bcma_driver_unregister);
 428
 429static int bcma_bus_match(struct device *dev, struct device_driver *drv)
 430{
 431        struct bcma_device *core = container_of(dev, struct bcma_device, dev);
 432        struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
 433        const struct bcma_device_id *cid = &core->id;
 434        const struct bcma_device_id *did;
 435
 436        for (did = adrv->id_table; did->manuf || did->id || did->rev; did++) {
 437            if ((did->manuf == cid->manuf || did->manuf == BCMA_ANY_MANUF) &&
 438                (did->id == cid->id || did->id == BCMA_ANY_ID) &&
 439                (did->rev == cid->rev || did->rev == BCMA_ANY_REV) &&
 440                (did->class == cid->class || did->class == BCMA_ANY_CLASS))
 441                        return 1;
 442        }
 443        return 0;
 444}
 445
 446static int bcma_device_probe(struct device *dev)
 447{
 448        struct bcma_device *core = container_of(dev, struct bcma_device, dev);
 449        struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
 450                                               drv);
 451        int err = 0;
 452
 453        if (adrv->probe)
 454                err = adrv->probe(core);
 455
 456        return err;
 457}
 458
 459static int bcma_device_remove(struct device *dev)
 460{
 461        struct bcma_device *core = container_of(dev, struct bcma_device, dev);
 462        struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
 463                                               drv);
 464
 465        if (adrv->remove)
 466                adrv->remove(core);
 467
 468        return 0;
 469}
 470
 471static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env)
 472{
 473        struct bcma_device *core = container_of(dev, struct bcma_device, dev);
 474
 475        return add_uevent_var(env,
 476                              "MODALIAS=bcma:m%04Xid%04Xrev%02Xcl%02X",
 477                              core->id.manuf, core->id.id,
 478                              core->id.rev, core->id.class);
 479}
 480
 481static int __init bcma_modinit(void)
 482{
 483        int err;
 484
 485        err = bus_register(&bcma_bus_type);
 486        if (err)
 487                return err;
 488
 489#ifdef CONFIG_BCMA_HOST_PCI
 490        err = bcma_host_pci_init();
 491        if (err) {
 492                pr_err("PCI host initialization failed\n");
 493                err = 0;
 494        }
 495#endif
 496
 497        return err;
 498}
 499fs_initcall(bcma_modinit);
 500
 501static void __exit bcma_modexit(void)
 502{
 503#ifdef CONFIG_BCMA_HOST_PCI
 504        bcma_host_pci_exit();
 505#endif
 506        bus_unregister(&bcma_bus_type);
 507}
 508module_exit(bcma_modexit)
 509