diff options
-rw-r--r-- | drivers/block/xsysace.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index 296d5674a3c1..56c4af3c2edb 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c | |||
@@ -91,6 +91,10 @@ | |||
91 | #include <linux/blkdev.h> | 91 | #include <linux/blkdev.h> |
92 | #include <linux/hdreg.h> | 92 | #include <linux/hdreg.h> |
93 | #include <linux/platform_device.h> | 93 | #include <linux/platform_device.h> |
94 | #if defined(CONFIG_OF) | ||
95 | #include <linux/of_device.h> | ||
96 | #include <linux/of_platform.h> | ||
97 | #endif | ||
94 | 98 | ||
95 | MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>"); | 99 | MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>"); |
96 | MODULE_DESCRIPTION("Xilinx SystemACE device driver"); | 100 | MODULE_DESCRIPTION("Xilinx SystemACE device driver"); |
@@ -1158,6 +1162,85 @@ static struct platform_driver ace_platform_driver = { | |||
1158 | }; | 1162 | }; |
1159 | 1163 | ||
1160 | /* --------------------------------------------------------------------- | 1164 | /* --------------------------------------------------------------------- |
1165 | * OF_Platform Bus Support | ||
1166 | */ | ||
1167 | |||
1168 | #if defined(CONFIG_OF) | ||
1169 | static int __devinit | ||
1170 | ace_of_probe(struct of_device *op, const struct of_device_id *match) | ||
1171 | { | ||
1172 | struct resource res; | ||
1173 | unsigned long physaddr; | ||
1174 | const u32 *id; | ||
1175 | int irq, bus_width, rc; | ||
1176 | |||
1177 | dev_dbg(&op->dev, "ace_of_probe(%p, %p)\n", op, match); | ||
1178 | |||
1179 | /* device id */ | ||
1180 | id = of_get_property(op->node, "port-number", NULL); | ||
1181 | |||
1182 | /* physaddr */ | ||
1183 | rc = of_address_to_resource(op->node, 0, &res); | ||
1184 | if (rc) { | ||
1185 | dev_err(&op->dev, "invalid address\n"); | ||
1186 | return rc; | ||
1187 | } | ||
1188 | physaddr = res.start; | ||
1189 | |||
1190 | /* irq */ | ||
1191 | irq = irq_of_parse_and_map(op->node, 0); | ||
1192 | |||
1193 | /* bus width */ | ||
1194 | bus_width = ACE_BUS_WIDTH_16; | ||
1195 | if (of_find_property(op->node, "8-bit", NULL)) | ||
1196 | bus_width = ACE_BUS_WIDTH_8; | ||
1197 | |||
1198 | /* Call the bus-independant setup code */ | ||
1199 | return ace_alloc(&op->dev, id ? *id : 0, physaddr, irq, bus_width); | ||
1200 | } | ||
1201 | |||
1202 | static int __devexit ace_of_remove(struct of_device *op) | ||
1203 | { | ||
1204 | ace_free(&op->dev); | ||
1205 | return 0; | ||
1206 | } | ||
1207 | |||
1208 | /* Match table for of_platform binding */ | ||
1209 | static struct of_device_id __devinit ace_of_match[] = { | ||
1210 | { .compatible = "xilinx,xsysace", }, | ||
1211 | {}, | ||
1212 | }; | ||
1213 | MODULE_DEVICE_TABLE(of, ace_of_match); | ||
1214 | |||
1215 | static struct of_platform_driver ace_of_driver = { | ||
1216 | .owner = THIS_MODULE, | ||
1217 | .name = "xsysace", | ||
1218 | .match_table = ace_of_match, | ||
1219 | .probe = ace_of_probe, | ||
1220 | .remove = __devexit_p(ace_of_remove), | ||
1221 | .driver = { | ||
1222 | .name = "xsysace", | ||
1223 | }, | ||
1224 | }; | ||
1225 | |||
1226 | /* Registration helpers to keep the number of #ifdefs to a minimum */ | ||
1227 | static inline int __init ace_of_register(void) | ||
1228 | { | ||
1229 | pr_debug("xsysace: registering OF binding\n"); | ||
1230 | return of_register_platform_driver(&ace_of_driver); | ||
1231 | } | ||
1232 | |||
1233 | static inline void __exit ace_of_unregister(void) | ||
1234 | { | ||
1235 | of_unregister_platform_driver(&ace_of_driver); | ||
1236 | } | ||
1237 | #else /* CONFIG_OF */ | ||
1238 | /* CONFIG_OF not enabled; do nothing helpers */ | ||
1239 | static inline int __init ace_of_register(void) { return 0; } | ||
1240 | static inline void __exit ace_of_unregister(void) { } | ||
1241 | #endif /* CONFIG_OF */ | ||
1242 | |||
1243 | /* --------------------------------------------------------------------- | ||
1161 | * Module init/exit routines | 1244 | * Module init/exit routines |
1162 | */ | 1245 | */ |
1163 | static int __init ace_init(void) | 1246 | static int __init ace_init(void) |
@@ -1170,6 +1253,9 @@ static int __init ace_init(void) | |||
1170 | goto err_blk; | 1253 | goto err_blk; |
1171 | } | 1254 | } |
1172 | 1255 | ||
1256 | if ((rc = ace_of_register()) != 0) | ||
1257 | goto err_of; | ||
1258 | |||
1173 | pr_debug("xsysace: registering platform binding\n"); | 1259 | pr_debug("xsysace: registering platform binding\n"); |
1174 | if ((rc = platform_driver_register(&ace_platform_driver)) != 0) | 1260 | if ((rc = platform_driver_register(&ace_platform_driver)) != 0) |
1175 | goto err_plat; | 1261 | goto err_plat; |
@@ -1178,6 +1264,8 @@ static int __init ace_init(void) | |||
1178 | return 0; | 1264 | return 0; |
1179 | 1265 | ||
1180 | err_plat: | 1266 | err_plat: |
1267 | ace_of_unregister(); | ||
1268 | err_of: | ||
1181 | unregister_blkdev(ace_major, "xsysace"); | 1269 | unregister_blkdev(ace_major, "xsysace"); |
1182 | err_blk: | 1270 | err_blk: |
1183 | printk(KERN_ERR "xsysace: registration failed; err=%i\n", rc); | 1271 | printk(KERN_ERR "xsysace: registration failed; err=%i\n", rc); |
@@ -1188,6 +1276,7 @@ static void __exit ace_exit(void) | |||
1188 | { | 1276 | { |
1189 | pr_debug("Unregistering Xilinx SystemACE driver\n"); | 1277 | pr_debug("Unregistering Xilinx SystemACE driver\n"); |
1190 | platform_driver_unregister(&ace_platform_driver); | 1278 | platform_driver_unregister(&ace_platform_driver); |
1279 | ace_of_unregister(); | ||
1191 | unregister_blkdev(ace_major, "xsysace"); | 1280 | unregister_blkdev(ace_major, "xsysace"); |
1192 | } | 1281 | } |
1193 | 1282 | ||