blob: 59c909e1c7c6c8f441ef5c2f48026c3588f577c1 [file] [log] [blame]
Pierre Ossmane29a7d72007-05-26 13:48:18 +02001/*
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
17#include <linux/mmc/card.h>
18#include <linux/mmc/sdio_func.h>
19
20#include "sdio_bus.h"
21
22#define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev)
23
24/*
25 * This currently matches any SDIO function to any driver in order
26 * to help initial development and testing.
27 */
28static int sdio_bus_match(struct device *dev, struct device_driver *drv)
29{
30 return 1;
31}
32
33static int
34sdio_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf,
35 int buf_size)
36{
37 envp[0] = NULL;
38
39 return 0;
40}
41
42static int sdio_bus_probe(struct device *dev)
43{
44 return -ENODEV;
45}
46
47static int sdio_bus_remove(struct device *dev)
48{
49 return 0;
50}
51
52static struct bus_type sdio_bus_type = {
53 .name = "sdio",
54 .match = sdio_bus_match,
55 .uevent = sdio_bus_uevent,
56 .probe = sdio_bus_probe,
57 .remove = sdio_bus_remove,
58};
59
60int sdio_register_bus(void)
61{
62 return bus_register(&sdio_bus_type);
63}
64
65void sdio_unregister_bus(void)
66{
67 bus_unregister(&sdio_bus_type);
68}
69
70static void sdio_release_func(struct device *dev)
71{
72 struct sdio_func *func = dev_to_sdio_func(dev);
73
74 kfree(func);
75}
76
77/*
78 * Allocate and initialise a new SDIO function structure.
79 */
80struct sdio_func *sdio_alloc_func(struct mmc_card *card)
81{
82 struct sdio_func *func;
83
84 func = kmalloc(sizeof(struct sdio_func), GFP_KERNEL);
85 if (!func)
86 return ERR_PTR(-ENOMEM);
87
88 memset(func, 0, sizeof(struct sdio_func));
89
90 func->card = card;
91
92 device_initialize(&func->dev);
93
94 func->dev.parent = &card->dev;
95 func->dev.bus = &sdio_bus_type;
96 func->dev.release = sdio_release_func;
97
98 return func;
99}
100
101/*
102 * Register a new SDIO function with the driver model.
103 */
104int sdio_add_func(struct sdio_func *func)
105{
106 int ret;
107
108 snprintf(func->dev.bus_id, sizeof(func->dev.bus_id),
109 "%s:%d", mmc_card_id(func->card), func->num);
110
111 ret = device_add(&func->dev);
112 if (ret == 0)
113 sdio_func_set_present(func);
114
115 return ret;
116}
117
118/*
119 * Unregister a SDIO function with the driver model, and
120 * (eventually) free it.
121 */
122void sdio_remove_func(struct sdio_func *func)
123{
124 if (sdio_func_present(func))
125 device_del(&func->dev);
126
127 put_device(&func->dev);
128}
129