linux/drivers/mmc/core/sdio_bus.c
<<
>>
Prefs
   1/*
   2 *  linux/drivers/mmc/core/sdio_bus.c
   3 *
   4 *  Copyright 2007 Pierre Ossman
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or (at
   9 * your option) any later version.
  10 *
  11 * SDIO function driver model
  12 */
  13
  14#include <linux/device.h>
  15#include <linux/err.h>
  16#include <linux/export.h>
  17#include <linux/slab.h>
  18#include <linux/pm_runtime.h>
  19#include <linux/acpi.h>
  20
  21#include <linux/mmc/card.h>
  22#include <linux/mmc/host.h>
  23#include <linux/mmc/sdio_func.h>
  24
  25#include "sdio_cis.h"
  26#include "sdio_bus.h"
  27
  28/* show configuration fields */
  29#define sdio_config_attr(field, format_string)                          \
  30static ssize_t                                                          \
  31field##_show(struct device *dev, struct device_attribute *attr, char *buf)                              \
  32{                                                                       \
  33        struct sdio_func *func;                                         \
  34                                                                        \
  35        func = dev_to_sdio_func (dev);                                  \
  36        return sprintf (buf, format_string, func->field);               \
  37}
  38
  39sdio_config_attr(class, "0x%02x\n");
  40sdio_config_attr(vendor, "0x%04x\n");
  41sdio_config_attr(device, "0x%04x\n");
  42
  43static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
  44{
  45        struct sdio_func *func = dev_to_sdio_func (dev);
  46
  47        return sprintf(buf, "sdio:c%02Xv%04Xd%04X\n",
  48                        func->class, func->vendor, func->device);
  49}
  50
  51static struct device_attribute sdio_dev_attrs[] = {
  52        __ATTR_RO(class),
  53        __ATTR_RO(vendor),
  54        __ATTR_RO(device),
  55        __ATTR_RO(modalias),
  56        __ATTR_NULL,
  57};
  58
  59static const struct sdio_device_id *sdio_match_one(struct sdio_func *func,
  60        const struct sdio_device_id *id)
  61{
  62        if (id->class != (__u8)SDIO_ANY_ID && id->class != func->class)
  63                return NULL;
  64        if (id->vendor != (__u16)SDIO_ANY_ID && id->vendor != func->vendor)
  65                return NULL;
  66        if (id->device != (__u16)SDIO_ANY_ID && id->device != func->device)
  67                return NULL;
  68        return id;
  69}
  70
  71static const struct sdio_device_id *sdio_match_device(struct sdio_func *func,
  72        struct sdio_driver *sdrv)
  73{
  74        const struct sdio_device_id *ids;
  75
  76        ids = sdrv->id_table;
  77
  78        if (ids) {
  79                while (ids->class || ids->vendor || ids->device) {
  80                        if (sdio_match_one(func, ids))
  81                                return ids;
  82                        ids++;
  83                }
  84        }
  85
  86        return NULL;
  87}
  88
  89static int sdio_bus_match(struct device *dev, struct device_driver *drv)
  90{
  91        struct sdio_func *func = dev_to_sdio_func(dev);
  92        struct sdio_driver *sdrv = to_sdio_driver(drv);
  93
  94        if (sdio_match_device(func, sdrv))
  95                return 1;
  96
  97        return 0;
  98}
  99
 100static int
 101sdio_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
 102{
 103        struct sdio_func *func = dev_to_sdio_func(dev);
 104
 105        if (add_uevent_var(env,
 106                        "SDIO_CLASS=%02X", func->class))
 107                return -ENOMEM;
 108
 109        if (add_uevent_var(env, 
 110                        "SDIO_ID=%04X:%04X", func->vendor, func->device))
 111                return -ENOMEM;
 112
 113        if (add_uevent_var(env,
 114                        "MODALIAS=sdio:c%02Xv%04Xd%04X",
 115                        func->class, func->vendor, func->device))
 116                return -ENOMEM;
 117
 118        return 0;
 119}
 120
 121static int sdio_bus_probe(struct device *dev)
 122{
 123        struct sdio_driver *drv = to_sdio_driver(dev->driver);
 124        struct sdio_func *func = dev_to_sdio_func(dev);
 125        const struct sdio_device_id *id;
 126        int ret;
 127
 128        id = sdio_match_device(func, drv);
 129        if (!id)
 130                return -ENODEV;
 131
 132        /* Unbound SDIO functions are always suspended.
 133         * During probe, the function is set active and the usage count
 134         * is incremented.  If the driver supports runtime PM,
 135         * it should call pm_runtime_put_noidle() in its probe routine and
 136         * pm_runtime_get_noresume() in its remove routine.
 137         */
 138        if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) {
 139                ret = pm_runtime_get_sync(dev);
 140                if (ret < 0)
 141                        goto disable_runtimepm;
 142        }
 143
 144        /* Set the default block size so the driver is sure it's something
 145         * sensible. */
 146        sdio_claim_host(func);
 147        ret = sdio_set_block_size(func, 0);
 148        sdio_release_host(func);
 149        if (ret)
 150                goto disable_runtimepm;
 151
 152        ret = drv->probe(func, id);
 153        if (ret)
 154                goto disable_runtimepm;
 155
 156        return 0;
 157
 158disable_runtimepm:
 159        if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
 160                pm_runtime_put_noidle(dev);
 161        return ret;
 162}
 163
 164static int sdio_bus_remove(struct device *dev)
 165{
 166        struct sdio_driver *drv = to_sdio_driver(dev->driver);
 167        struct sdio_func *func = dev_to_sdio_func(dev);
 168        int ret = 0;
 169
 170        /* Make sure card is powered before invoking ->remove() */
 171        if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
 172                pm_runtime_get_sync(dev);
 173
 174        drv->remove(func);
 175
 176        if (func->irq_handler) {
 177                pr_warning("WARNING: driver %s did not remove "
 178                        "its interrupt handler!\n", drv->name);
 179                sdio_claim_host(func);
 180                sdio_release_irq(func);
 181                sdio_release_host(func);
 182        }
 183
 184        /* First, undo the increment made directly above */
 185        if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
 186                pm_runtime_put_noidle(dev);
 187
 188        /* Then undo the runtime PM settings in sdio_bus_probe() */
 189        if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
 190                pm_runtime_put_sync(dev);
 191
 192        return ret;
 193}
 194
 195#ifdef CONFIG_PM
 196
 197#ifdef CONFIG_PM_SLEEP
 198static int pm_no_operation(struct device *dev)
 199{
 200        /*
 201         * Prevent the PM core from calling SDIO device drivers' suspend
 202         * callback routines, which it is not supposed to do, by using this
 203         * empty function as the bus type suspend callaback for SDIO.
 204         */
 205        return 0;
 206}
 207#endif
 208
 209static const struct dev_pm_ops sdio_bus_pm_ops = {
 210        SET_SYSTEM_SLEEP_PM_OPS(pm_no_operation, pm_no_operation)
 211        SET_RUNTIME_PM_OPS(
 212                pm_generic_runtime_suspend,
 213                pm_generic_runtime_resume,
 214                NULL
 215        )
 216};
 217
 218#define SDIO_PM_OPS_PTR (&sdio_bus_pm_ops)
 219
 220#else /* !CONFIG_PM */
 221
 222#define SDIO_PM_OPS_PTR NULL
 223
 224#endif /* !CONFIG_PM */
 225
 226static struct bus_type sdio_bus_type = {
 227        .name           = "sdio",
 228        .dev_attrs      = sdio_dev_attrs,
 229        .match          = sdio_bus_match,
 230        .uevent         = sdio_bus_uevent,
 231        .probe          = sdio_bus_probe,
 232        .remove         = sdio_bus_remove,
 233        .pm             = SDIO_PM_OPS_PTR,
 234};
 235
 236int sdio_register_bus(void)
 237{
 238        return bus_register(&sdio_bus_type);
 239}
 240
 241void sdio_unregister_bus(void)
 242{
 243        bus_unregister(&sdio_bus_type);
 244}
 245
 246/**
 247 *      sdio_register_driver - register a function driver
 248 *      @drv: SDIO function driver
 249 */
 250int sdio_register_driver(struct sdio_driver *drv)
 251{
 252        drv->drv.name = drv->name;
 253        drv->drv.bus = &sdio_bus_type;
 254        return driver_register(&drv->drv);
 255}
 256EXPORT_SYMBOL_GPL(sdio_register_driver);
 257
 258/**
 259 *      sdio_unregister_driver - unregister a function driver
 260 *      @drv: SDIO function driver
 261 */
 262void sdio_unregister_driver(struct sdio_driver *drv)
 263{
 264        drv->drv.bus = &sdio_bus_type;
 265        driver_unregister(&drv->drv);
 266}
 267EXPORT_SYMBOL_GPL(sdio_unregister_driver);
 268
 269static void sdio_release_func(struct device *dev)
 270{
 271        struct sdio_func *func = dev_to_sdio_func(dev);
 272
 273        sdio_free_func_cis(func);
 274
 275        kfree(func->info);
 276
 277        kfree(func);
 278}
 279
 280/*
 281 * Allocate and initialise a new SDIO function structure.
 282 */
 283struct sdio_func *sdio_alloc_func(struct mmc_card *card)
 284{
 285        struct sdio_func *func;
 286
 287        func = kzalloc(sizeof(struct sdio_func), GFP_KERNEL);
 288        if (!func)
 289                return ERR_PTR(-ENOMEM);
 290
 291        func->card = card;
 292
 293        device_initialize(&func->dev);
 294
 295        func->dev.parent = &card->dev;
 296        func->dev.bus = &sdio_bus_type;
 297        func->dev.release = sdio_release_func;
 298
 299        return func;
 300}
 301
 302#ifdef CONFIG_ACPI
 303static void sdio_acpi_set_handle(struct sdio_func *func)
 304{
 305        struct mmc_host *host = func->card->host;
 306        u64 addr = (host->slotno << 16) | func->num;
 307
 308        ACPI_HANDLE_SET(&func->dev,
 309                        acpi_get_child(ACPI_HANDLE(host->parent), addr));
 310}
 311#else
 312static inline void sdio_acpi_set_handle(struct sdio_func *func) {}
 313#endif
 314
 315/*
 316 * Register a new SDIO function with the driver model.
 317 */
 318int sdio_add_func(struct sdio_func *func)
 319{
 320        int ret;
 321
 322        dev_set_name(&func->dev, "%s:%d", mmc_card_id(func->card), func->num);
 323
 324        sdio_acpi_set_handle(func);
 325        ret = device_add(&func->dev);
 326        if (ret == 0) {
 327                sdio_func_set_present(func);
 328                acpi_dev_pm_attach(&func->dev, false);
 329        }
 330
 331        return ret;
 332}
 333
 334/*
 335 * Unregister a SDIO function with the driver model, and
 336 * (eventually) free it.
 337 * This function can be called through error paths where sdio_add_func() was
 338 * never executed (because a failure occurred at an earlier point).
 339 */
 340void sdio_remove_func(struct sdio_func *func)
 341{
 342        if (!sdio_func_present(func))
 343                return;
 344
 345        acpi_dev_pm_detach(&func->dev, false);
 346        device_del(&func->dev);
 347        put_device(&func->dev);
 348}
 349
 350