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