402 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * linux/drivers/mmc/core/sdio_bus.c4 *5 * Copyright 2007 Pierre Ossman6 *7 * SDIO function driver model8 */9 10#include <linux/device.h>11#include <linux/err.h>12#include <linux/export.h>13#include <linux/slab.h>14#include <linux/pm_runtime.h>15#include <linux/pm_domain.h>16#include <linux/acpi.h>17#include <linux/sysfs.h>18 19#include <linux/mmc/card.h>20#include <linux/mmc/host.h>21#include <linux/mmc/sdio_func.h>22#include <linux/of.h>23 24#include "core.h"25#include "card.h"26#include "sdio_cis.h"27#include "sdio_bus.h"28 29#define to_sdio_driver(d) container_of_const(d, struct sdio_driver, drv)30 31/* show configuration fields */32#define sdio_config_attr(field, format_string, args...) \33static ssize_t \34field##_show(struct device *dev, struct device_attribute *attr, char *buf) \35{ \36 struct sdio_func *func; \37 \38 func = dev_to_sdio_func (dev); \39 return sysfs_emit(buf, format_string, args); \40} \41static DEVICE_ATTR_RO(field)42 43sdio_config_attr(class, "0x%02x\n", func->class);44sdio_config_attr(vendor, "0x%04x\n", func->vendor);45sdio_config_attr(device, "0x%04x\n", func->device);46sdio_config_attr(revision, "%u.%u\n", func->major_rev, func->minor_rev);47sdio_config_attr(modalias, "sdio:c%02Xv%04Xd%04X\n", func->class, func->vendor, func->device);48 49#define sdio_info_attr(num) \50static ssize_t info##num##_show(struct device *dev, struct device_attribute *attr, char *buf) \51{ \52 struct sdio_func *func = dev_to_sdio_func(dev); \53 \54 if (num > func->num_info) \55 return -ENODATA; \56 if (!func->info[num - 1][0]) \57 return 0; \58 return sysfs_emit(buf, "%s\n", func->info[num - 1]); \59} \60static DEVICE_ATTR_RO(info##num)61 62sdio_info_attr(1);63sdio_info_attr(2);64sdio_info_attr(3);65sdio_info_attr(4);66 67static struct attribute *sdio_dev_attrs[] = {68 &dev_attr_class.attr,69 &dev_attr_vendor.attr,70 &dev_attr_device.attr,71 &dev_attr_revision.attr,72 &dev_attr_info1.attr,73 &dev_attr_info2.attr,74 &dev_attr_info3.attr,75 &dev_attr_info4.attr,76 &dev_attr_modalias.attr,77 NULL,78};79ATTRIBUTE_GROUPS(sdio_dev);80 81static const struct sdio_device_id *sdio_match_one(struct sdio_func *func,82 const struct sdio_device_id *id)83{84 if (id->class != (__u8)SDIO_ANY_ID && id->class != func->class)85 return NULL;86 if (id->vendor != (__u16)SDIO_ANY_ID && id->vendor != func->vendor)87 return NULL;88 if (id->device != (__u16)SDIO_ANY_ID && id->device != func->device)89 return NULL;90 return id;91}92 93static const struct sdio_device_id *sdio_match_device(struct sdio_func *func,94 const struct sdio_driver *sdrv)95{96 const struct sdio_device_id *ids;97 98 ids = sdrv->id_table;99 100 if (ids) {101 while (ids->class || ids->vendor || ids->device) {102 if (sdio_match_one(func, ids))103 return ids;104 ids++;105 }106 }107 108 return NULL;109}110 111static int sdio_bus_match(struct device *dev, const struct device_driver *drv)112{113 struct sdio_func *func = dev_to_sdio_func(dev);114 const struct sdio_driver *sdrv = to_sdio_driver(drv);115 116 if (sdio_match_device(func, sdrv))117 return 1;118 119 return 0;120}121 122static int123sdio_bus_uevent(const struct device *dev, struct kobj_uevent_env *env)124{125 const struct sdio_func *func = dev_to_sdio_func(dev);126 unsigned int i;127 128 if (add_uevent_var(env,129 "SDIO_CLASS=%02X", func->class))130 return -ENOMEM;131 132 if (add_uevent_var(env,133 "SDIO_ID=%04X:%04X", func->vendor, func->device))134 return -ENOMEM;135 136 if (add_uevent_var(env,137 "SDIO_REVISION=%u.%u", func->major_rev, func->minor_rev))138 return -ENOMEM;139 140 for (i = 0; i < func->num_info; i++) {141 if (add_uevent_var(env, "SDIO_INFO%u=%s", i+1, func->info[i]))142 return -ENOMEM;143 }144 145 if (add_uevent_var(env,146 "MODALIAS=sdio:c%02Xv%04Xd%04X",147 func->class, func->vendor, func->device))148 return -ENOMEM;149 150 return 0;151}152 153static int sdio_bus_probe(struct device *dev)154{155 struct sdio_driver *drv = to_sdio_driver(dev->driver);156 struct sdio_func *func = dev_to_sdio_func(dev);157 const struct sdio_device_id *id;158 int ret;159 160 id = sdio_match_device(func, drv);161 if (!id)162 return -ENODEV;163 164 ret = dev_pm_domain_attach(dev, false);165 if (ret)166 return ret;167 168 atomic_inc(&func->card->sdio_funcs_probed);169 170 /* Unbound SDIO functions are always suspended.171 * During probe, the function is set active and the usage count172 * is incremented. If the driver supports runtime PM,173 * it should call pm_runtime_put_noidle() in its probe routine and174 * pm_runtime_get_noresume() in its remove routine.175 */176 if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) {177 ret = pm_runtime_get_sync(dev);178 if (ret < 0)179 goto disable_runtimepm;180 }181 182 /* Set the default block size so the driver is sure it's something183 * sensible. */184 sdio_claim_host(func);185 if (mmc_card_removed(func->card))186 ret = -ENOMEDIUM;187 else188 ret = sdio_set_block_size(func, 0);189 sdio_release_host(func);190 if (ret)191 goto disable_runtimepm;192 193 ret = drv->probe(func, id);194 if (ret)195 goto disable_runtimepm;196 197 return 0;198 199disable_runtimepm:200 atomic_dec(&func->card->sdio_funcs_probed);201 if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)202 pm_runtime_put_noidle(dev);203 dev_pm_domain_detach(dev, false);204 return ret;205}206 207static void sdio_bus_remove(struct device *dev)208{209 struct sdio_driver *drv = to_sdio_driver(dev->driver);210 struct sdio_func *func = dev_to_sdio_func(dev);211 212 /* Make sure card is powered before invoking ->remove() */213 if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)214 pm_runtime_get_sync(dev);215 216 drv->remove(func);217 atomic_dec(&func->card->sdio_funcs_probed);218 219 if (func->irq_handler) {220 pr_warn("WARNING: driver %s did not remove its interrupt handler!\n",221 drv->name);222 sdio_claim_host(func);223 sdio_release_irq(func);224 sdio_release_host(func);225 }226 227 /* First, undo the increment made directly above */228 if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)229 pm_runtime_put_noidle(dev);230 231 /* Then undo the runtime PM settings in sdio_bus_probe() */232 if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)233 pm_runtime_put_sync(dev);234 235 dev_pm_domain_detach(dev, false);236}237 238static const struct dev_pm_ops sdio_bus_pm_ops = {239 SET_SYSTEM_SLEEP_PM_OPS(pm_generic_suspend, pm_generic_resume)240 SET_RUNTIME_PM_OPS(241 pm_generic_runtime_suspend,242 pm_generic_runtime_resume,243 NULL244 )245};246 247static const struct bus_type sdio_bus_type = {248 .name = "sdio",249 .dev_groups = sdio_dev_groups,250 .match = sdio_bus_match,251 .uevent = sdio_bus_uevent,252 .probe = sdio_bus_probe,253 .remove = sdio_bus_remove,254 .pm = &sdio_bus_pm_ops,255};256 257int sdio_register_bus(void)258{259 return bus_register(&sdio_bus_type);260}261 262void sdio_unregister_bus(void)263{264 bus_unregister(&sdio_bus_type);265}266 267/**268 * __sdio_register_driver - register a function driver269 * @drv: SDIO function driver270 * @owner: owning module/driver271 */272int __sdio_register_driver(struct sdio_driver *drv, struct module *owner)273{274 drv->drv.name = drv->name;275 drv->drv.bus = &sdio_bus_type;276 drv->drv.owner = owner;277 278 return driver_register(&drv->drv);279}280EXPORT_SYMBOL_GPL(__sdio_register_driver);281 282/**283 * sdio_unregister_driver - unregister a function driver284 * @drv: SDIO function driver285 */286void sdio_unregister_driver(struct sdio_driver *drv)287{288 drv->drv.bus = &sdio_bus_type;289 driver_unregister(&drv->drv);290}291EXPORT_SYMBOL_GPL(sdio_unregister_driver);292 293static void sdio_release_func(struct device *dev)294{295 struct sdio_func *func = dev_to_sdio_func(dev);296 297 if (!(func->card->quirks & MMC_QUIRK_NONSTD_SDIO))298 sdio_free_func_cis(func);299 300 /*301 * We have now removed the link to the tuples in the302 * card structure, so remove the reference.303 */304 put_device(&func->card->dev);305 306 kfree(func->info);307 kfree(func->tmpbuf);308 kfree(func);309}310 311/*312 * Allocate and initialise a new SDIO function structure.313 */314struct sdio_func *sdio_alloc_func(struct mmc_card *card)315{316 struct sdio_func *func;317 318 func = kzalloc(sizeof(struct sdio_func), GFP_KERNEL);319 if (!func)320 return ERR_PTR(-ENOMEM);321 322 /*323 * allocate buffer separately to make sure it's properly aligned for324 * DMA usage (incl. 64 bit DMA)325 */326 func->tmpbuf = kmalloc(4, GFP_KERNEL);327 if (!func->tmpbuf) {328 kfree(func);329 return ERR_PTR(-ENOMEM);330 }331 332 func->card = card;333 334 device_initialize(&func->dev);335 336 /*337 * We may link to tuples in the card structure,338 * we need make sure we have a reference to it.339 */340 get_device(&func->card->dev);341 342 func->dev.parent = &card->dev;343 func->dev.bus = &sdio_bus_type;344 func->dev.release = sdio_release_func;345 346 return func;347}348 349#ifdef CONFIG_ACPI350static void sdio_acpi_set_handle(struct sdio_func *func)351{352 struct mmc_host *host = func->card->host;353 u64 addr = ((u64)host->slotno << 16) | func->num;354 355 acpi_preset_companion(&func->dev, ACPI_COMPANION(host->parent), addr);356}357#else358static inline void sdio_acpi_set_handle(struct sdio_func *func) {}359#endif360 361static void sdio_set_of_node(struct sdio_func *func)362{363 struct mmc_host *host = func->card->host;364 365 func->dev.of_node = mmc_of_find_child_device(host, func->num);366}367 368/*369 * Register a new SDIO function with the driver model.370 */371int sdio_add_func(struct sdio_func *func)372{373 int ret;374 375 dev_set_name(&func->dev, "%s:%d", mmc_card_id(func->card), func->num);376 377 sdio_set_of_node(func);378 sdio_acpi_set_handle(func);379 device_enable_async_suspend(&func->dev);380 ret = device_add(&func->dev);381 if (ret == 0)382 sdio_func_set_present(func);383 384 return ret;385}386 387/*388 * Unregister a SDIO function with the driver model, and389 * (eventually) free it.390 * This function can be called through error paths where sdio_add_func() was391 * never executed (because a failure occurred at an earlier point).392 */393void sdio_remove_func(struct sdio_func *func)394{395 if (sdio_func_present(func))396 device_del(&func->dev);397 398 of_node_put(func->dev.of_node);399 put_device(&func->dev);400}401 402