diff options
-rw-r--r-- | drivers/mmc/core/sdio.c | 38 | ||||
-rw-r--r-- | include/linux/mmc/sdio_func.h | 5 |
2 files changed, 43 insertions, 0 deletions
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 7ce3e3104d21..be623856f288 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c | |||
@@ -23,8 +23,34 @@ | |||
23 | #include "sd_ops.h" | 23 | #include "sd_ops.h" |
24 | #include "sdio_ops.h" | 24 | #include "sdio_ops.h" |
25 | 25 | ||
26 | static int sdio_read_fbr(struct sdio_func *func) | ||
27 | { | ||
28 | int ret; | ||
29 | unsigned char data; | ||
30 | |||
31 | ret = mmc_io_rw_direct(func->card, 0, 0, | ||
32 | func->num * 0x100 + SDIO_FBR_STD_IF, 0, &data); | ||
33 | if (ret) | ||
34 | goto out; | ||
35 | |||
36 | data &= 0x0f; | ||
37 | |||
38 | if (data == 0x0f) { | ||
39 | ret = mmc_io_rw_direct(func->card, 0, 0, | ||
40 | func->num * 0x100 + SDIO_FBR_STD_IF_EXT, 0, &data); | ||
41 | if (ret) | ||
42 | goto out; | ||
43 | } | ||
44 | |||
45 | func->class = data; | ||
46 | |||
47 | out: | ||
48 | return ret; | ||
49 | } | ||
50 | |||
26 | static int sdio_init_func(struct mmc_card *card, unsigned int fn) | 51 | static int sdio_init_func(struct mmc_card *card, unsigned int fn) |
27 | { | 52 | { |
53 | int ret; | ||
28 | struct sdio_func *func; | 54 | struct sdio_func *func; |
29 | 55 | ||
30 | BUG_ON(fn > SDIO_MAX_FUNCS); | 56 | BUG_ON(fn > SDIO_MAX_FUNCS); |
@@ -35,9 +61,21 @@ static int sdio_init_func(struct mmc_card *card, unsigned int fn) | |||
35 | 61 | ||
36 | func->num = fn; | 62 | func->num = fn; |
37 | 63 | ||
64 | ret = sdio_read_fbr(func); | ||
65 | if (ret) | ||
66 | goto fail; | ||
67 | |||
38 | card->sdio_func[fn - 1] = func; | 68 | card->sdio_func[fn - 1] = func; |
39 | 69 | ||
40 | return 0; | 70 | return 0; |
71 | |||
72 | fail: | ||
73 | /* | ||
74 | * It is okay to remove the function here even though we hold | ||
75 | * the host lock as we haven't registered the device yet. | ||
76 | */ | ||
77 | sdio_remove_func(func); | ||
78 | return ret; | ||
41 | } | 79 | } |
42 | 80 | ||
43 | static int sdio_read_cccr(struct mmc_card *card) | 81 | static int sdio_read_cccr(struct mmc_card *card) |
diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h index 3365fef5f713..4164809a8e63 100644 --- a/include/linux/mmc/sdio_func.h +++ b/include/linux/mmc/sdio_func.h | |||
@@ -21,6 +21,11 @@ struct sdio_func { | |||
21 | struct mmc_card *card; /* the card this device belongs to */ | 21 | struct mmc_card *card; /* the card this device belongs to */ |
22 | struct device dev; /* the device */ | 22 | struct device dev; /* the device */ |
23 | unsigned int num; /* function number */ | 23 | unsigned int num; /* function number */ |
24 | |||
25 | unsigned char class; /* standard interface class */ | ||
26 | unsigned short vendor; /* vendor id */ | ||
27 | unsigned short device; /* device id */ | ||
28 | |||
24 | unsigned int state; /* function state */ | 29 | unsigned int state; /* function state */ |
25 | #define SDIO_STATE_PRESENT (1<<0) /* present in sysfs */ | 30 | #define SDIO_STATE_PRESENT (1<<0) /* present in sysfs */ |
26 | }; | 31 | }; |