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
  20#include <linux/mmc/card.h>
  21#include <linux/mmc/host.h>
  22#include <linux/mmc/sdio_func.h>
  23
  24#include "sdio_cis.h"
  25#include "sdio_bus.h"
  26
  27/* show configuration fields */
  28#define sdio_config_attr(field, format_string)                          \
  29static ssize_t                                                          \
  30field##_show(struct device *dev, struct device_attribute *attr, char *buf)                              \
  31{                                                                       \
  32        struct sdio_func *func;                                         \
  33                                                                        \
  34        func = dev_to_sdio_func (dev);                                  \
  35        return sprintf (buf, format_string, func->field);               \
  36}
  37
  38sdio_config_attr(class, "0x%02x\n");
  39sdio_config_attr(vendor, "0x%04x\n");
  40sdio_config_attr(device, "0x%04x\n");
  41
  42static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
  43{
  44        struct sdio_func *func = dev_to_sdio_func (dev);
  45
  46        return sprintf(buf, "sdio:c%02Xv%04Xd%04X\n",
  47                        func->class, func->vendor, func->device);
  48}
  49
  50static struct device_attribute sdio_dev_attrs[] = {
  51        __ATTR_RO(class),
  52        __ATTR_RO(vendor),
  53        __ATTR_RO(device),
  54        __ATTR_RO(modalias),
  55        __ATTR_NULL,
  56};
  57
  58static const struct sdio_device_id *sdio_match_one(struct sdio_func *func,
  59        const struct sdio_device_id *id)
  60{
  61        if (id->class != (__u8)SDIO_ANY_ID && id->class != func->class)
  62                return NULL;
  63        if (id->vendor != (__u16)SDIO_ANY_ID && id->vendor != func->vendor)
  64                return NULL;
  65        if (id->device != (__u16)SDIO_ANY_ID && id->device != func->device)
  66                return NULL;
  67        return id;
  68}
  69
  70static const struct sdio_device_id *sdio_match_device(struct sdio_func *func,
  71        struct sdio_driver *sdrv)
  72{
  73        const struct sdio_device_id *ids;
  74
  75        ids = sdrv->id_table;
  76
  77        if (ids) {
  78                while (ids->class || ids->vendor || ids->device) {
  79                        if (sdio_match_one(func, ids))
  80                                return ids;
  81                        ids++;
  82                }
  83        }
  84
  85        return NULL;
  86}
  87
  88static int sdio_bus_match(struct device *dev, struct device_driver *drv)
  89{
  90        struct sdio_func *func = dev_to_sdio_func(dev);
  91        struct sdio_driver *sdrv = to_sdio_driver(drv);
  92
  93        if (sdio_match_device(func, sdrv))
  94                return 1;
  95
  96        return 0;
  97}
  98
  99static int
 100sdio_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
 101{
 102        struct sdio_func *func = dev_to_sdio_func(dev);
 103
 104        if (add_uevent_var(env,
 105                        "SDIO_CLASS=%02X", func->class))
 106                return -ENOMEM;
 107
 108        if (add_uevent_var(env, 
 109                        "SDIO_ID=%04X:%04X", func->vendor, func->device))
 110                return -ENOMEM;
 111
 112        if (add_uevent_var(env,
 113                        "MODALIAS=sdio:c%02Xv%04Xd%04X",
 114                        func->class, func->vendor, func->device))
 115                return -ENOMEM;
 116
 117        return 0;
 118}
 119
 120static int sdio_bus_probe(struct device *dev)
 121{
 122        struct sdio_driver *drv = to_sdio_driver(dev->driver);
 123        struct sdio_func *func = dev_to_sdio_func(dev);
 124        const struct sdio_device_id *id;
 125        int ret;
 126
 127        id = sdio_match_device(func, drv);
 128        if (!id)
 129                return -ENODEV;
 130
 131        /* Unbound SDIO functions are always suspended.
 132         * During probe, the function is set active and the usage count
 133         * is incremented.  If the driver supports runtime PM,
 134         * it should call pm_runtime_put_noidle() in its probe routine and
 135         * pm_runtime_get_noresume() in its remove routine.
 136         */
 137        if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) {
 138                ret = pm_runtime_get_sync(dev);
 139                if (ret < 0)
 140                        goto out;
 141        }
 142
 143        /* Set the default block size so the driver is sure it's something
 144         * sensible. */
 145        sdio_claim_host(func);
 146        ret = sdio_set_block_size(func, 0);
 147        sdio_release_host(func);
 148        if (ret)
 149                goto disable_runtimepm;
 150
 151        ret = drv->probe(func, id);
 152        if (ret)
 153                goto disable_runtimepm;
 154
 155        return 0;
 156
 157disable_runtimepm:
 158        if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
 159                pm_runtime_put_noidle(dev);
 160out:
 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
 197static int pm_no_operation(struct device *dev)
 198{
 199        return 0;
 200}
 201
 202static const struct dev_pm_ops sdio_bus_pm_ops = {
 203        SET_SYSTEM_SLEEP_PM_OPS(pm_no_operation, pm_no_operation)
 204        SET_RUNTIME_PM_OPS(
 205                pm_generic_runtime_suspend,
 206                pm_generic_runtime_resume,
 207                pm_generic_runtime_idle
 208        )
 209};
 210
 211#define SDIO_PM_OPS_PTR (&sdio_bus_pm_ops)
 212
 213#else /* !CONFIG_PM */
 214
 215#define SDIO_PM_OPS_PTR NULL
 216
 217#endif /* !CONFIG_PM */
 218
 219static struct bus_type sdio_bus_type = {
 220        .name           = "sdio",
 221        .dev_attrs      = sdio_dev_attrs,
 222        .match          = sdio_bus_match,
 223        .uevent         = sdio_bus_uevent,
 224        .probe          = sdio_bus_probe,
 225        .remove         = sdio_bus_remove,
 226        .pm             = SDIO_PM_OPS_PTR,
 227};
 228
 229int sdio_register_bus(void)
 230{
 231        return bus_register(&sdio_bus_type);
 232}
 233
 234void sdio_unregister_bus(void)
 235{
 236        bus_unregister(&sdio_bus_type);
 237}
 238
 239/**
 240 *      sdio_register_driver - register a function driver
 241 *      @drv: SDIO function driver
 242 */
 243int sdio_register_driver(struct sdio_driver *drv)
 244{
 245        drv->drv.name = drv->name;
 246        drv->drv.bus = &sdio_bus_type;
 247        return driver_register(&drv->drv);
 248}
 249EXPORT_SYMBOL_GPL(sdio_register_driver);
 250
 251/**
 252 *      sdio_unregister_driver - unregister a function driver
 253 *      @drv: SDIO function driver
 254 */
 255void sdio_unregister_driver(struct sdio_driver *drv)
 256{
 257        drv->drv.bus = &sdio_bus_type;
 258        driver_unregister(&drv->drv);
 259}
 260EXPORT_SYMBOL_GPL(sdio_unregister_driver);
 261
 262static void sdio_release_func(struct device *dev)
 263{
 264        struct sdio_func *func = dev_to_sdio_func(dev);
 265
 266        sdio_free_func_cis(func);
 267
 268        if (func->info)
 269                kfree(func->info);
 270
 271        kfree(func);
 272}
 273
 274/*
 275 * Allocate and initialise a new SDIO function structure.
 276 */
 277struct sdio_func *sdio_alloc_func(struct mmc_card *card)
 278{
 279        struct sdio_func *func;
 280
 281        func = kzalloc(sizeof(struct sdio_func), GFP_KERNEL);
 282        if (!func)
 283                return ERR_PTR(-ENOMEM);
 284
 285        func->card = card;
 286
 287        device_initialize(&func->dev);
 288
 289        func->dev.parent = &card->dev;
 290        func->dev.bus = &sdio_bus_type;
 291        func->dev.release = sdio_release_func;
 292
 293        return func;
 294}
 295
 296/*
 297 * Register a new SDIO function with the driver model.
 298 */
 299int sdio_add_func(struct sdio_func *func)
 300{
 301        int ret;
 302
 303        dev_set_name(&func->dev, "%s:%d", mmc_card_id(func->card), func->num);
 304
 305        ret = device_add(&func->dev);
 306        if (ret == 0)
 307                sdio_func_set_present(func);
 308
 309        return ret;
 310}
 311
 312/*
 313 * Unregister a SDIO function with the driver model, and
 314 * (eventually) free it.
 315 * This function can be called through error paths where sdio_add_func() was
 316 * never executed (because a failure occurred at an earlier point).
 317 */
 318void sdio_remove_func(struct sdio_func *func)
 319{
 320        if (!sdio_func_present(func))
 321                return;
 322
 323        device_del(&func->dev);
 324        put_device(&func->dev);
 325}
 326
 327