sdio_bus.c revision e29a7d73f4277eb92aa64e17017dea33460828ef
1e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman/* 2e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman * linux/drivers/mmc/core/sdio_bus.c 3e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman * 4e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman * Copyright 2007 Pierre Ossman 5e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman * 6e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman * This program is free software; you can redistribute it and/or modify 7e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman * it under the terms of the GNU General Public License as published by 8e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman * the Free Software Foundation; either version 2 of the License, or (at 9e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman * your option) any later version. 10e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman * 11e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman * SDIO function driver model 12e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman */ 13e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 14e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman#include <linux/device.h> 15e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman#include <linux/err.h> 16e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 17e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman#include <linux/mmc/card.h> 18e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman#include <linux/mmc/sdio_func.h> 19e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 20e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman#include "sdio_bus.h" 21e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 22e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman#define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev) 23e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 24e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman/* 25e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman * This currently matches any SDIO function to any driver in order 26e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman * to help initial development and testing. 27e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman */ 28e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossmanstatic int sdio_bus_match(struct device *dev, struct device_driver *drv) 29e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman{ 30e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman return 1; 31e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman} 32e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 33e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossmanstatic int 34e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossmansdio_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf, 35e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman int buf_size) 36e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman{ 37e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman envp[0] = NULL; 38e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 39e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman return 0; 40e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman} 41e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 42e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossmanstatic int sdio_bus_probe(struct device *dev) 43e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman{ 44e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman return -ENODEV; 45e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman} 46e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 47e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossmanstatic int sdio_bus_remove(struct device *dev) 48e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman{ 49e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman return 0; 50e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman} 51e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 52e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossmanstatic struct bus_type sdio_bus_type = { 53e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman .name = "sdio", 54e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman .match = sdio_bus_match, 55e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman .uevent = sdio_bus_uevent, 56e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman .probe = sdio_bus_probe, 57e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman .remove = sdio_bus_remove, 58e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman}; 59e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 60e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossmanint sdio_register_bus(void) 61e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman{ 62e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman return bus_register(&sdio_bus_type); 63e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman} 64e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 65e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossmanvoid sdio_unregister_bus(void) 66e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman{ 67e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman bus_unregister(&sdio_bus_type); 68e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman} 69e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 70e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossmanstatic void sdio_release_func(struct device *dev) 71e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman{ 72e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman struct sdio_func *func = dev_to_sdio_func(dev); 73e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 74e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman kfree(func); 75e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman} 76e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 77e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman/* 78e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman * Allocate and initialise a new SDIO function structure. 79e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman */ 80e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossmanstruct sdio_func *sdio_alloc_func(struct mmc_card *card) 81e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman{ 82e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman struct sdio_func *func; 83e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 84e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman func = kmalloc(sizeof(struct sdio_func), GFP_KERNEL); 85e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman if (!func) 86e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman return ERR_PTR(-ENOMEM); 87e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 88e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman memset(func, 0, sizeof(struct sdio_func)); 89e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 90e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman func->card = card; 91e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 92e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman device_initialize(&func->dev); 93e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 94e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman func->dev.parent = &card->dev; 95e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman func->dev.bus = &sdio_bus_type; 96e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman func->dev.release = sdio_release_func; 97e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 98e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman return func; 99e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman} 100e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 101e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman/* 102e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman * Register a new SDIO function with the driver model. 103e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman */ 104e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossmanint sdio_add_func(struct sdio_func *func) 105e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman{ 106e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman int ret; 107e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 108e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman snprintf(func->dev.bus_id, sizeof(func->dev.bus_id), 109e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman "%s:%d", mmc_card_id(func->card), func->num); 110e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 111e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman ret = device_add(&func->dev); 112e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman if (ret == 0) 113e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman sdio_func_set_present(func); 114e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 115e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman return ret; 116e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman} 117e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 118e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman/* 119e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman * Unregister a SDIO function with the driver model, and 120e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman * (eventually) free it. 121e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman */ 122e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossmanvoid sdio_remove_func(struct sdio_func *func) 123e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman{ 124e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman if (sdio_func_present(func)) 125e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman device_del(&func->dev); 126e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 127e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman put_device(&func->dev); 128e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman} 129e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 130