aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/xsysace.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/xsysace.c')
-rw-r--r--drivers/block/xsysace.c274
1 files changed, 203 insertions, 71 deletions
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 3ede0b63da13..9e7652dcde6c 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
95MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>"); 99MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
96MODULE_DESCRIPTION("Xilinx SystemACE device driver"); 100MODULE_DESCRIPTION("Xilinx SystemACE device driver");
@@ -158,6 +162,9 @@ MODULE_LICENSE("GPL");
158#define ACE_FIFO_SIZE (32) 162#define ACE_FIFO_SIZE (32)
159#define ACE_BUF_PER_SECTOR (ACE_SECTOR_SIZE / ACE_FIFO_SIZE) 163#define ACE_BUF_PER_SECTOR (ACE_SECTOR_SIZE / ACE_FIFO_SIZE)
160 164
165#define ACE_BUS_WIDTH_8 0
166#define ACE_BUS_WIDTH_16 1
167
161struct ace_reg_ops; 168struct ace_reg_ops;
162 169
163struct ace_device { 170struct ace_device {
@@ -188,7 +195,7 @@ struct ace_device {
188 195
189 /* Details of hardware device */ 196 /* Details of hardware device */
190 unsigned long physaddr; 197 unsigned long physaddr;
191 void *baseaddr; 198 void __iomem *baseaddr;
192 int irq; 199 int irq;
193 int bus_width; /* 0 := 8 bit; 1 := 16 bit */ 200 int bus_width; /* 0 := 8 bit; 1 := 16 bit */
194 struct ace_reg_ops *reg_ops; 201 struct ace_reg_ops *reg_ops;
@@ -220,20 +227,20 @@ struct ace_reg_ops {
220/* 8 Bit bus width */ 227/* 8 Bit bus width */
221static u16 ace_in_8(struct ace_device *ace, int reg) 228static u16 ace_in_8(struct ace_device *ace, int reg)
222{ 229{
223 void *r = ace->baseaddr + reg; 230 void __iomem *r = ace->baseaddr + reg;
224 return in_8(r) | (in_8(r + 1) << 8); 231 return in_8(r) | (in_8(r + 1) << 8);
225} 232}
226 233
227static void ace_out_8(struct ace_device *ace, int reg, u16 val) 234static void ace_out_8(struct ace_device *ace, int reg, u16 val)
228{ 235{
229 void *r = ace->baseaddr + reg; 236 void __iomem *r = ace->baseaddr + reg;
230 out_8(r, val); 237 out_8(r, val);
231 out_8(r + 1, val >> 8); 238 out_8(r + 1, val >> 8);
232} 239}
233 240
234static void ace_datain_8(struct ace_device *ace) 241static void ace_datain_8(struct ace_device *ace)
235{ 242{
236 void *r = ace->baseaddr + 0x40; 243 void __iomem *r = ace->baseaddr + 0x40;
237 u8 *dst = ace->data_ptr; 244 u8 *dst = ace->data_ptr;
238 int i = ACE_FIFO_SIZE; 245 int i = ACE_FIFO_SIZE;
239 while (i--) 246 while (i--)
@@ -243,7 +250,7 @@ static void ace_datain_8(struct ace_device *ace)
243 250
244static void ace_dataout_8(struct ace_device *ace) 251static void ace_dataout_8(struct ace_device *ace)
245{ 252{
246 void *r = ace->baseaddr + 0x40; 253 void __iomem *r = ace->baseaddr + 0x40;
247 u8 *src = ace->data_ptr; 254 u8 *src = ace->data_ptr;
248 int i = ACE_FIFO_SIZE; 255 int i = ACE_FIFO_SIZE;
249 while (i--) 256 while (i--)
@@ -931,9 +938,11 @@ static int __devinit ace_setup(struct ace_device *ace)
931{ 938{
932 u16 version; 939 u16 version;
933 u16 val; 940 u16 val;
934
935 int rc; 941 int rc;
936 942
943 dev_dbg(ace->dev, "ace_setup(ace=0x%p)\n", ace);
944 dev_dbg(ace->dev, "physaddr=0x%lx irq=%i\n", ace->physaddr, ace->irq);
945
937 spin_lock_init(&ace->lock); 946 spin_lock_init(&ace->lock);
938 init_completion(&ace->id_completion); 947 init_completion(&ace->id_completion);
939 948
@@ -944,15 +953,6 @@ static int __devinit ace_setup(struct ace_device *ace)
944 if (!ace->baseaddr) 953 if (!ace->baseaddr)
945 goto err_ioremap; 954 goto err_ioremap;
946 955
947 if (ace->irq != NO_IRQ) {
948 rc = request_irq(ace->irq, ace_interrupt, 0, "systemace", ace);
949 if (rc) {
950 /* Failure - fall back to polled mode */
951 dev_err(ace->dev, "request_irq failed\n");
952 ace->irq = NO_IRQ;
953 }
954 }
955
956 /* 956 /*
957 * Initialize the state machine tasklet and stall timer 957 * Initialize the state machine tasklet and stall timer
958 */ 958 */
@@ -982,7 +982,7 @@ static int __devinit ace_setup(struct ace_device *ace)
982 snprintf(ace->gd->disk_name, 32, "xs%c", ace->id + 'a'); 982 snprintf(ace->gd->disk_name, 32, "xs%c", ace->id + 'a');
983 983
984 /* set bus width */ 984 /* set bus width */
985 if (ace->bus_width == 1) { 985 if (ace->bus_width == ACE_BUS_WIDTH_16) {
986 /* 0x0101 should work regardless of endianess */ 986 /* 0x0101 should work regardless of endianess */
987 ace_out_le16(ace, ACE_BUSMODE, 0x0101); 987 ace_out_le16(ace, ACE_BUSMODE, 0x0101);
988 988
@@ -1005,6 +1005,16 @@ static int __devinit ace_setup(struct ace_device *ace)
1005 ace_out(ace, ACE_CTRL, ACE_CTRL_FORCECFGMODE | 1005 ace_out(ace, ACE_CTRL, ACE_CTRL_FORCECFGMODE |
1006 ACE_CTRL_DATABUFRDYIRQ | ACE_CTRL_ERRORIRQ); 1006 ACE_CTRL_DATABUFRDYIRQ | ACE_CTRL_ERRORIRQ);
1007 1007
1008 /* Now we can hook up the irq handler */
1009 if (ace->irq != NO_IRQ) {
1010 rc = request_irq(ace->irq, ace_interrupt, 0, "systemace", ace);
1011 if (rc) {
1012 /* Failure - fall back to polled mode */
1013 dev_err(ace->dev, "request_irq failed\n");
1014 ace->irq = NO_IRQ;
1015 }
1016 }
1017
1008 /* Enable interrupts */ 1018 /* Enable interrupts */
1009 val = ace_in(ace, ACE_CTRL); 1019 val = ace_in(ace, ACE_CTRL);
1010 val |= ACE_CTRL_DATABUFRDYIRQ | ACE_CTRL_ERRORIRQ; 1020 val |= ACE_CTRL_DATABUFRDYIRQ | ACE_CTRL_ERRORIRQ;
@@ -1024,16 +1034,14 @@ static int __devinit ace_setup(struct ace_device *ace)
1024 1034
1025 return 0; 1035 return 0;
1026 1036
1027 err_read: 1037err_read:
1028 put_disk(ace->gd); 1038 put_disk(ace->gd);
1029 err_alloc_disk: 1039err_alloc_disk:
1030 blk_cleanup_queue(ace->queue); 1040 blk_cleanup_queue(ace->queue);
1031 err_blk_initq: 1041err_blk_initq:
1032 iounmap(ace->baseaddr); 1042 iounmap(ace->baseaddr);
1033 if (ace->irq != NO_IRQ) 1043err_ioremap:
1034 free_irq(ace->irq, ace); 1044 dev_info(ace->dev, "xsysace: error initializing device at 0x%lx\n",
1035 err_ioremap:
1036 printk(KERN_INFO "xsysace: error initializing device at 0x%lx\n",
1037 ace->physaddr); 1045 ace->physaddr);
1038 return -ENOMEM; 1046 return -ENOMEM;
1039} 1047}
@@ -1056,98 +1064,222 @@ static void __devexit ace_teardown(struct ace_device *ace)
1056 iounmap(ace->baseaddr); 1064 iounmap(ace->baseaddr);
1057} 1065}
1058 1066
1059/* --------------------------------------------------------------------- 1067static int __devinit
1060 * Platform Bus Support 1068ace_alloc(struct device *dev, int id, unsigned long physaddr,
1061 */ 1069 int irq, int bus_width)
1062
1063static int __devinit ace_probe(struct device *device)
1064{ 1070{
1065 struct platform_device *dev = to_platform_device(device);
1066 struct ace_device *ace; 1071 struct ace_device *ace;
1067 int i; 1072 int rc;
1073 dev_dbg(dev, "ace_alloc(%p)\n", dev);
1068 1074
1069 dev_dbg(device, "ace_probe(%p)\n", device); 1075 if (!physaddr) {
1076 rc = -ENODEV;
1077 goto err_noreg;
1078 }
1070 1079
1071 /* 1080 /* Allocate and initialize the ace device structure */
1072 * Allocate the ace device structure
1073 */
1074 ace = kzalloc(sizeof(struct ace_device), GFP_KERNEL); 1081 ace = kzalloc(sizeof(struct ace_device), GFP_KERNEL);
1075 if (!ace) 1082 if (!ace) {
1083 rc = -ENOMEM;
1076 goto err_alloc; 1084 goto err_alloc;
1077
1078 ace->dev = device;
1079 ace->id = dev->id;
1080 ace->irq = NO_IRQ;
1081
1082 for (i = 0; i < dev->num_resources; i++) {
1083 if (dev->resource[i].flags & IORESOURCE_MEM)
1084 ace->physaddr = dev->resource[i].start;
1085 if (dev->resource[i].flags & IORESOURCE_IRQ)
1086 ace->irq = dev->resource[i].start;
1087 } 1085 }
1088 1086
1089 /* FIXME: Should get bus_width from the platform_device struct */ 1087 ace->dev = dev;
1090 ace->bus_width = 1; 1088 ace->id = id;
1091 1089 ace->physaddr = physaddr;
1092 dev_set_drvdata(&dev->dev, ace); 1090 ace->irq = irq;
1091 ace->bus_width = bus_width;
1093 1092
1094 /* Call the bus-independant setup code */ 1093 /* Call the setup code */
1095 if (ace_setup(ace) != 0) 1094 rc = ace_setup(ace);
1095 if (rc)
1096 goto err_setup; 1096 goto err_setup;
1097 1097
1098 dev_set_drvdata(dev, ace);
1098 return 0; 1099 return 0;
1099 1100
1100 err_setup: 1101err_setup:
1101 dev_set_drvdata(&dev->dev, NULL); 1102 dev_set_drvdata(dev, NULL);
1102 kfree(ace); 1103 kfree(ace);
1103 err_alloc: 1104err_alloc:
1104 printk(KERN_ERR "xsysace: could not initialize device\n"); 1105err_noreg:
1105 return -ENOMEM; 1106 dev_err(dev, "could not initialize device, err=%i\n", rc);
1107 return rc;
1106} 1108}
1107 1109
1108/* 1110static void __devexit ace_free(struct device *dev)
1109 * Platform bus remove() method
1110 */
1111static int __devexit ace_remove(struct device *device)
1112{ 1111{
1113 struct ace_device *ace = dev_get_drvdata(device); 1112 struct ace_device *ace = dev_get_drvdata(dev);
1114 1113 dev_dbg(dev, "ace_free(%p)\n", dev);
1115 dev_dbg(device, "ace_remove(%p)\n", device);
1116 1114
1117 if (ace) { 1115 if (ace) {
1118 ace_teardown(ace); 1116 ace_teardown(ace);
1117 dev_set_drvdata(dev, NULL);
1119 kfree(ace); 1118 kfree(ace);
1120 } 1119 }
1120}
1121
1122/* ---------------------------------------------------------------------
1123 * Platform Bus Support
1124 */
1125
1126static int __devinit ace_probe(struct platform_device *dev)
1127{
1128 unsigned long physaddr = 0;
1129 int bus_width = ACE_BUS_WIDTH_16; /* FIXME: should not be hard coded */
1130 int id = dev->id;
1131 int irq = NO_IRQ;
1132 int i;
1121 1133
1134 dev_dbg(&dev->dev, "ace_probe(%p)\n", dev);
1135
1136 for (i = 0; i < dev->num_resources; i++) {
1137 if (dev->resource[i].flags & IORESOURCE_MEM)
1138 physaddr = dev->resource[i].start;
1139 if (dev->resource[i].flags & IORESOURCE_IRQ)
1140 irq = dev->resource[i].start;
1141 }
1142
1143 /* Call the bus-independant setup code */
1144 return ace_alloc(&dev->dev, id, physaddr, irq, bus_width);
1145}
1146
1147/*
1148 * Platform bus remove() method
1149 */
1150static int __devexit ace_remove(struct platform_device *dev)
1151{
1152 ace_free(&dev->dev);
1122 return 0; 1153 return 0;
1123} 1154}
1124 1155
1125static struct device_driver ace_driver = { 1156static struct platform_driver ace_platform_driver = {
1126 .name = "xsysace",
1127 .bus = &platform_bus_type,
1128 .probe = ace_probe, 1157 .probe = ace_probe,
1129 .remove = __devexit_p(ace_remove), 1158 .remove = __devexit_p(ace_remove),
1159 .driver = {
1160 .owner = THIS_MODULE,
1161 .name = "xsysace",
1162 },
1163};
1164
1165/* ---------------------------------------------------------------------
1166 * OF_Platform Bus Support
1167 */
1168
1169#if defined(CONFIG_OF)
1170static int __devinit
1171ace_of_probe(struct of_device *op, const struct of_device_id *match)
1172{
1173 struct resource res;
1174 unsigned long physaddr;
1175 const u32 *id;
1176 int irq, bus_width, rc;
1177
1178 dev_dbg(&op->dev, "ace_of_probe(%p, %p)\n", op, match);
1179
1180 /* device id */
1181 id = of_get_property(op->node, "port-number", NULL);
1182
1183 /* physaddr */
1184 rc = of_address_to_resource(op->node, 0, &res);
1185 if (rc) {
1186 dev_err(&op->dev, "invalid address\n");
1187 return rc;
1188 }
1189 physaddr = res.start;
1190
1191 /* irq */
1192 irq = irq_of_parse_and_map(op->node, 0);
1193
1194 /* bus width */
1195 bus_width = ACE_BUS_WIDTH_16;
1196 if (of_find_property(op->node, "8-bit", NULL))
1197 bus_width = ACE_BUS_WIDTH_8;
1198
1199 /* Call the bus-independant setup code */
1200 return ace_alloc(&op->dev, id ? *id : 0, physaddr, irq, bus_width);
1201}
1202
1203static int __devexit ace_of_remove(struct of_device *op)
1204{
1205 ace_free(&op->dev);
1206 return 0;
1207}
1208
1209/* Match table for of_platform binding */
1210static struct of_device_id __devinit ace_of_match[] = {
1211 { .compatible = "xilinx,xsysace", },
1212 {},
1213};
1214MODULE_DEVICE_TABLE(of, ace_of_match);
1215
1216static struct of_platform_driver ace_of_driver = {
1217 .owner = THIS_MODULE,
1218 .name = "xsysace",
1219 .match_table = ace_of_match,
1220 .probe = ace_of_probe,
1221 .remove = __devexit_p(ace_of_remove),
1222 .driver = {
1223 .name = "xsysace",
1224 },
1130}; 1225};
1131 1226
1227/* Registration helpers to keep the number of #ifdefs to a minimum */
1228static inline int __init ace_of_register(void)
1229{
1230 pr_debug("xsysace: registering OF binding\n");
1231 return of_register_platform_driver(&ace_of_driver);
1232}
1233
1234static inline void __exit ace_of_unregister(void)
1235{
1236 of_unregister_platform_driver(&ace_of_driver);
1237}
1238#else /* CONFIG_OF */
1239/* CONFIG_OF not enabled; do nothing helpers */
1240static inline int __init ace_of_register(void) { return 0; }
1241static inline void __exit ace_of_unregister(void) { }
1242#endif /* CONFIG_OF */
1243
1132/* --------------------------------------------------------------------- 1244/* ---------------------------------------------------------------------
1133 * Module init/exit routines 1245 * Module init/exit routines
1134 */ 1246 */
1135static int __init ace_init(void) 1247static int __init ace_init(void)
1136{ 1248{
1249 int rc;
1250
1137 ace_major = register_blkdev(ace_major, "xsysace"); 1251 ace_major = register_blkdev(ace_major, "xsysace");
1138 if (ace_major <= 0) { 1252 if (ace_major <= 0) {
1139 printk(KERN_WARNING "xsysace: register_blkdev() failed\n"); 1253 rc = -ENOMEM;
1140 return ace_major; 1254 goto err_blk;
1141 } 1255 }
1142 1256
1143 pr_debug("Registering Xilinx SystemACE driver, major=%i\n", ace_major); 1257 rc = ace_of_register();
1144 return driver_register(&ace_driver); 1258 if (rc)
1259 goto err_of;
1260
1261 pr_debug("xsysace: registering platform binding\n");
1262 rc = platform_driver_register(&ace_platform_driver);
1263 if (rc)
1264 goto err_plat;
1265
1266 pr_info("Xilinx SystemACE device driver, major=%i\n", ace_major);
1267 return 0;
1268
1269err_plat:
1270 ace_of_unregister();
1271err_of:
1272 unregister_blkdev(ace_major, "xsysace");
1273err_blk:
1274 printk(KERN_ERR "xsysace: registration failed; err=%i\n", rc);
1275 return rc;
1145} 1276}
1146 1277
1147static void __exit ace_exit(void) 1278static void __exit ace_exit(void)
1148{ 1279{
1149 pr_debug("Unregistering Xilinx SystemACE driver\n"); 1280 pr_debug("Unregistering Xilinx SystemACE driver\n");
1150 driver_unregister(&ace_driver); 1281 platform_driver_unregister(&ace_platform_driver);
1282 ace_of_unregister();
1151 unregister_blkdev(ace_major, "xsysace"); 1283 unregister_blkdev(ace_major, "xsysace");
1152} 1284}
1153 1285