diff options
author | Pierre Ossman <drzeus@drzeus.cx> | 2007-06-16 09:54:55 -0400 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2007-09-23 14:51:27 -0400 |
commit | 3b38bea0d976513970f947806b08b9faca418e7a (patch) | |
tree | f542a7e3dfe206be4de9f7ca6ebc23d25a196731 | |
parent | 26074962e8f547b96614dbe248748ba2a1996ca3 (diff) |
sdio: add device id table and matching
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
-rw-r--r-- | drivers/mmc/core/sdio_bus.c | 58 | ||||
-rw-r--r-- | include/linux/mmc/sdio_func.h | 30 | ||||
-rw-r--r-- | include/linux/mod_devicetable.h | 11 |
3 files changed, 92 insertions, 7 deletions
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 461fe4837a9f..a3a89e973d94 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c | |||
@@ -21,14 +21,47 @@ | |||
21 | #include "sdio_bus.h" | 21 | #include "sdio_bus.h" |
22 | 22 | ||
23 | #define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev) | 23 | #define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev) |
24 | #define to_sdio_driver(d) container_of(d, struct sdio_driver, drv) | ||
25 | |||
26 | static const struct sdio_device_id *sdio_match_one(struct sdio_func *func, | ||
27 | const struct sdio_device_id *id) | ||
28 | { | ||
29 | if (id->class != (__u8)SDIO_ANY_ID && id->class != func->class) | ||
30 | return NULL; | ||
31 | if (id->vendor != (__u16)SDIO_ANY_ID && id->vendor != func->vendor) | ||
32 | return NULL; | ||
33 | if (id->device != (__u16)SDIO_ANY_ID && id->device != func->device) | ||
34 | return NULL; | ||
35 | return id; | ||
36 | } | ||
37 | |||
38 | static const struct sdio_device_id *sdio_match_device(struct sdio_func *func, | ||
39 | struct sdio_driver *sdrv) | ||
40 | { | ||
41 | const struct sdio_device_id *ids; | ||
42 | |||
43 | ids = sdrv->id_table; | ||
44 | |||
45 | if (ids) { | ||
46 | while (ids->class || ids->vendor || ids->device) { | ||
47 | if (sdio_match_one(func, ids)) | ||
48 | return ids; | ||
49 | ids++; | ||
50 | } | ||
51 | } | ||
52 | |||
53 | return NULL; | ||
54 | } | ||
24 | 55 | ||
25 | /* | ||
26 | * This currently matches any SDIO function to any driver in order | ||
27 | * to help initial development and testing. | ||
28 | */ | ||
29 | static int sdio_bus_match(struct device *dev, struct device_driver *drv) | 56 | static int sdio_bus_match(struct device *dev, struct device_driver *drv) |
30 | { | 57 | { |
31 | return 1; | 58 | struct sdio_func *func = dev_to_sdio_func(dev); |
59 | struct sdio_driver *sdrv = to_sdio_driver(drv); | ||
60 | |||
61 | if (sdio_match_device(func, sdrv)) | ||
62 | return 1; | ||
63 | |||
64 | return 0; | ||
32 | } | 65 | } |
33 | 66 | ||
34 | static int | 67 | static int |
@@ -42,11 +75,24 @@ sdio_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf, | |||
42 | 75 | ||
43 | static int sdio_bus_probe(struct device *dev) | 76 | static int sdio_bus_probe(struct device *dev) |
44 | { | 77 | { |
45 | return -ENODEV; | 78 | struct sdio_driver *drv = to_sdio_driver(dev->driver); |
79 | struct sdio_func *func = dev_to_sdio_func(dev); | ||
80 | const struct sdio_device_id *id; | ||
81 | |||
82 | id = sdio_match_device(func, drv); | ||
83 | if (!id) | ||
84 | return -ENODEV; | ||
85 | |||
86 | return drv->probe(func, id); | ||
46 | } | 87 | } |
47 | 88 | ||
48 | static int sdio_bus_remove(struct device *dev) | 89 | static int sdio_bus_remove(struct device *dev) |
49 | { | 90 | { |
91 | struct sdio_driver *drv = to_sdio_driver(dev->driver); | ||
92 | struct sdio_func *func = dev_to_sdio_func(dev); | ||
93 | |||
94 | drv->remove(func); | ||
95 | |||
50 | return 0; | 96 | return 0; |
51 | } | 97 | } |
52 | 98 | ||
diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h index 2f2b3c854415..8106d399c414 100644 --- a/include/linux/mmc/sdio_func.h +++ b/include/linux/mmc/sdio_func.h | |||
@@ -12,6 +12,9 @@ | |||
12 | #ifndef MMC_SDIO_FUNC_H | 12 | #ifndef MMC_SDIO_FUNC_H |
13 | #define MMC_SDIO_FUNC_H | 13 | #define MMC_SDIO_FUNC_H |
14 | 14 | ||
15 | #include <linux/device.h> | ||
16 | #include <linux/mod_devicetable.h> | ||
17 | |||
15 | struct mmc_card; | 18 | struct mmc_card; |
16 | 19 | ||
17 | /* | 20 | /* |
@@ -58,13 +61,38 @@ struct sdio_func { | |||
58 | */ | 61 | */ |
59 | struct sdio_driver { | 62 | struct sdio_driver { |
60 | char *name; | 63 | char *name; |
64 | const struct sdio_device_id *id_table; | ||
61 | 65 | ||
62 | int (*probe)(struct sdio_func *); | 66 | int (*probe)(struct sdio_func *, const struct sdio_device_id *); |
63 | void (*remove)(struct sdio_func *); | 67 | void (*remove)(struct sdio_func *); |
64 | 68 | ||
65 | struct device_driver drv; | 69 | struct device_driver drv; |
66 | }; | 70 | }; |
67 | 71 | ||
72 | /** | ||
73 | * SDIO_DEVICE - macro used to describe a specific SDIO device | ||
74 | * @vend: the 16 bit manufacturer code | ||
75 | * @dev: the 16 bit function id | ||
76 | * | ||
77 | * This macro is used to create a struct sdio_device_id that matches a | ||
78 | * specific device. The class field will be set to SDIO_ANY_ID. | ||
79 | */ | ||
80 | #define SDIO_DEVICE(vend,dev) \ | ||
81 | .class = SDIO_ANY_ID, \ | ||
82 | .vendor = (vend), .device = (dev) | ||
83 | |||
84 | /** | ||
85 | * SDIO_DEVICE_CLASS - macro used to describe a specific SDIO device class | ||
86 | * @dev_class: the 8 bit standard interface code | ||
87 | * | ||
88 | * This macro is used to create a struct sdio_device_id that matches a | ||
89 | * specific standard SDIO function type. The vendor and device fields will | ||
90 | * be set to SDIO_ANY_ID. | ||
91 | */ | ||
92 | #define SDIO_DEVICE_CLASS(dev_class) \ | ||
93 | .class = (dev_class), \ | ||
94 | .vendor = SDIO_ANY_ID, .device = SDIO_ANY_ID | ||
95 | |||
68 | extern int sdio_register_driver(struct sdio_driver *); | 96 | extern int sdio_register_driver(struct sdio_driver *); |
69 | extern void sdio_unregister_driver(struct sdio_driver *); | 97 | extern void sdio_unregister_driver(struct sdio_driver *); |
70 | 98 | ||
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 4dc5fa8be781..e47e5951058b 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h | |||
@@ -340,4 +340,15 @@ struct parisc_device_id { | |||
340 | #define PA_HVERSION_ANY_ID 0xffff | 340 | #define PA_HVERSION_ANY_ID 0xffff |
341 | #define PA_SVERSION_ANY_ID 0xffffffff | 341 | #define PA_SVERSION_ANY_ID 0xffffffff |
342 | 342 | ||
343 | /* SDIO */ | ||
344 | |||
345 | #define SDIO_ANY_ID (~0) | ||
346 | |||
347 | struct sdio_device_id { | ||
348 | __u8 class; /* Standard interface or SDIO_ANY_ID */ | ||
349 | __u16 vendor; /* Vendor or SDIO_ANY_ID */ | ||
350 | __u16 device; /* Device ID or SDIO_ANY_ID */ | ||
351 | kernel_ulong_t driver_data; /* Data private to the driver */ | ||
352 | }; | ||
353 | |||
343 | #endif /* LINUX_MOD_DEVICETABLE_H */ | 354 | #endif /* LINUX_MOD_DEVICETABLE_H */ |