aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/swim3.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-07-03 03:25:26 -0400
committerPaul Mackerras <paulus@samba.org>2006-07-03 03:25:26 -0400
commit3e9a69275f23baec86b54febc5dad0b2fc7fb200 (patch)
treef499a827aec6f3690ad35bd9427b1a04f6e7db18 /drivers/block/swim3.c
parent7c6efda5996c26c468eaba178af9bac8b70dbdcb (diff)
[POWERPC] Update the SWIM3 (powermac) floppy driver
Port the PowerMac floppy driver (swim3) to use the macio device infrastructure. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'drivers/block/swim3.c')
-rw-r--r--drivers/block/swim3.c230
1 files changed, 130 insertions, 100 deletions
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
index 3721e12135d9..cc42e762396f 100644
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -250,8 +250,6 @@ static int floppy_open(struct inode *inode, struct file *filp);
250static int floppy_release(struct inode *inode, struct file *filp); 250static int floppy_release(struct inode *inode, struct file *filp);
251static int floppy_check_change(struct gendisk *disk); 251static int floppy_check_change(struct gendisk *disk);
252static int floppy_revalidate(struct gendisk *disk); 252static int floppy_revalidate(struct gendisk *disk);
253static int swim3_add_device(struct device_node *swims);
254int swim3_init(void);
255 253
256#ifndef CONFIG_PMAC_MEDIABAY 254#ifndef CONFIG_PMAC_MEDIABAY
257#define check_media_bay(which, what) 1 255#define check_media_bay(which, what) 1
@@ -1011,114 +1009,63 @@ static struct block_device_operations floppy_fops = {
1011 .revalidate_disk= floppy_revalidate, 1009 .revalidate_disk= floppy_revalidate,
1012}; 1010};
1013 1011
1014int swim3_init(void) 1012static int swim3_add_device(struct macio_dev *mdev, int index)
1015{
1016 struct device_node *swim;
1017 int err = -ENOMEM;
1018 int i;
1019
1020 swim = find_devices("floppy");
1021 while (swim && (floppy_count < MAX_FLOPPIES))
1022 {
1023 swim3_add_device(swim);
1024 swim = swim->next;
1025 }
1026
1027 swim = find_devices("swim3");
1028 while (swim && (floppy_count < MAX_FLOPPIES))
1029 {
1030 swim3_add_device(swim);
1031 swim = swim->next;
1032 }
1033
1034 if (!floppy_count)
1035 return -ENODEV;
1036
1037 for (i = 0; i < floppy_count; i++) {
1038 disks[i] = alloc_disk(1);
1039 if (!disks[i])
1040 goto out;
1041 }
1042
1043 if (register_blkdev(FLOPPY_MAJOR, "fd")) {
1044 err = -EBUSY;
1045 goto out;
1046 }
1047
1048 swim3_queue = blk_init_queue(do_fd_request, &swim3_lock);
1049 if (!swim3_queue) {
1050 err = -ENOMEM;
1051 goto out_queue;
1052 }
1053
1054 for (i = 0; i < floppy_count; i++) {
1055 struct gendisk *disk = disks[i];
1056 disk->major = FLOPPY_MAJOR;
1057 disk->first_minor = i;
1058 disk->fops = &floppy_fops;
1059 disk->private_data = &floppy_states[i];
1060 disk->queue = swim3_queue;
1061 disk->flags |= GENHD_FL_REMOVABLE;
1062 sprintf(disk->disk_name, "fd%d", i);
1063 set_capacity(disk, 2880);
1064 add_disk(disk);
1065 }
1066 return 0;
1067
1068out_queue:
1069 unregister_blkdev(FLOPPY_MAJOR, "fd");
1070out:
1071 while (i--)
1072 put_disk(disks[i]);
1073 /* shouldn't we do something with results of swim_add_device()? */
1074 return err;
1075}
1076
1077static int swim3_add_device(struct device_node *swim)
1078{ 1013{
1014 struct device_node *swim = mdev->ofdev.node;
1079 struct device_node *mediabay; 1015 struct device_node *mediabay;
1080 struct floppy_state *fs = &floppy_states[floppy_count]; 1016 struct floppy_state *fs = &floppy_states[index];
1081 struct resource res_reg, res_dma; 1017 int rc = -EBUSY;
1082 1018
1083 if (of_address_to_resource(swim, 0, &res_reg) || 1019 /* Check & Request resources */
1084 of_address_to_resource(swim, 1, &res_dma)) { 1020 if (macio_resource_count(mdev) < 2) {
1085 printk(KERN_ERR "swim3: Can't get addresses\n"); 1021 printk(KERN_WARNING "ifd%d: no address for %s\n",
1086 return -EINVAL; 1022 index, swim->full_name);
1023 return -ENXIO;
1087 } 1024 }
1088 if (request_mem_region(res_reg.start, res_reg.end - res_reg.start + 1, 1025 if (macio_irq_count(mdev) < 2) {
1089 " (reg)") == NULL) { 1026 printk(KERN_WARNING "fd%d: no intrs for device %s\n",
1090 printk(KERN_ERR "swim3: Can't request register space\n"); 1027 index, swim->full_name);
1091 return -EINVAL;
1092 } 1028 }
1093 if (request_mem_region(res_dma.start, res_dma.end - res_dma.start + 1, 1029 if (macio_request_resource(mdev, 0, "swim3 (mmio)")) {
1094 " (dma)") == NULL) { 1030 printk(KERN_ERR "fd%d: can't request mmio resource for %s\n",
1095 release_mem_region(res_reg.start, 1031 index, swim->full_name);
1096 res_reg.end - res_reg.start + 1); 1032 return -EBUSY;
1097 printk(KERN_ERR "swim3: Can't request DMA space\n");
1098 return -EINVAL;
1099 } 1033 }
1100 1034 if (macio_request_resource(mdev, 1, "swim3 (dma)")) {
1101 if (swim->n_intrs < 2) { 1035 printk(KERN_ERR "fd%d: can't request dma resource for %s\n",
1102 printk(KERN_INFO "swim3: expecting 2 intrs (n_intrs:%d)\n", 1036 index, swim->full_name);
1103 swim->n_intrs); 1037 macio_release_resource(mdev, 0);
1104 release_mem_region(res_reg.start, 1038 return -EBUSY;
1105 res_reg.end - res_reg.start + 1);
1106 release_mem_region(res_dma.start,
1107 res_dma.end - res_dma.start + 1);
1108 return -EINVAL;
1109 } 1039 }
1040 dev_set_drvdata(&mdev->ofdev.dev, fs);
1110 1041
1111 mediabay = (strcasecmp(swim->parent->type, "media-bay") == 0) ? swim->parent : NULL; 1042 mediabay = (strcasecmp(swim->parent->type, "media-bay") == 0) ?
1043 swim->parent : NULL;
1112 if (mediabay == NULL) 1044 if (mediabay == NULL)
1113 pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1); 1045 pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1);
1114 1046
1115 memset(fs, 0, sizeof(*fs)); 1047 memset(fs, 0, sizeof(*fs));
1116 spin_lock_init(&fs->lock); 1048 spin_lock_init(&fs->lock);
1117 fs->state = idle; 1049 fs->state = idle;
1118 fs->swim3 = (struct swim3 __iomem *)ioremap(res_reg.start, 0x200); 1050 fs->swim3 = (struct swim3 __iomem *)
1119 fs->dma = (struct dbdma_regs __iomem *)ioremap(res_dma.start, 0x200); 1051 ioremap(macio_resource_start(mdev, 0), 0x200);
1120 fs->swim3_intr = swim->intrs[0].line; 1052 if (fs->swim3 == NULL) {
1121 fs->dma_intr = swim->intrs[1].line; 1053 printk("fd%d: couldn't map registers for %s\n",
1054 index, swim->full_name);
1055 rc = -ENOMEM;
1056 goto out_release;
1057 }
1058 fs->dma = (struct dbdma_regs __iomem *)
1059 ioremap(macio_resource_start(mdev, 1), 0x200);
1060 if (fs->dma == NULL) {
1061 printk("fd%d: couldn't map DMA for %s\n",
1062 index, swim->full_name);
1063 iounmap(fs->swim3);
1064 rc = -ENOMEM;
1065 goto out_release;
1066 }
1067 fs->swim3_intr = macio_irq(mdev, 0);
1068 fs->dma_intr = macio_irq(mdev, 1);;
1122 fs->cur_cyl = -1; 1069 fs->cur_cyl = -1;
1123 fs->cur_sector = -1; 1070 fs->cur_sector = -1;
1124 fs->secpercyl = 36; 1071 fs->secpercyl = 36;
@@ -1132,15 +1079,16 @@ static int swim3_add_device(struct device_node *swim)
1132 st_le16(&fs->dma_cmd[1].command, DBDMA_STOP); 1079 st_le16(&fs->dma_cmd[1].command, DBDMA_STOP);
1133 1080
1134 if (request_irq(fs->swim3_intr, swim3_interrupt, 0, "SWIM3", fs)) { 1081 if (request_irq(fs->swim3_intr, swim3_interrupt, 0, "SWIM3", fs)) {
1135 printk(KERN_ERR "Couldn't get irq %d for SWIM3\n", fs->swim3_intr); 1082 printk(KERN_ERR "fd%d: couldn't request irq %d for %s\n",
1083 index, fs->swim3_intr, swim->full_name);
1136 pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0); 1084 pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0);
1085 goto out_unmap;
1137 return -EBUSY; 1086 return -EBUSY;
1138 } 1087 }
1139/* 1088/*
1140 if (request_irq(fs->dma_intr, fd_dma_interrupt, 0, "SWIM3-dma", fs)) { 1089 if (request_irq(fs->dma_intr, fd_dma_interrupt, 0, "SWIM3-dma", fs)) {
1141 printk(KERN_ERR "Couldn't get irq %d for SWIM3 DMA", 1090 printk(KERN_ERR "Couldn't get irq %d for SWIM3 DMA",
1142 fs->dma_intr); 1091 fs->dma_intr);
1143 pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0);
1144 return -EBUSY; 1092 return -EBUSY;
1145 } 1093 }
1146*/ 1094*/
@@ -1150,8 +1098,90 @@ static int swim3_add_device(struct device_node *swim)
1150 printk(KERN_INFO "fd%d: SWIM3 floppy controller %s\n", floppy_count, 1098 printk(KERN_INFO "fd%d: SWIM3 floppy controller %s\n", floppy_count,
1151 mediabay ? "in media bay" : ""); 1099 mediabay ? "in media bay" : "");
1152 1100
1153 floppy_count++; 1101 return 0;
1154 1102
1103 out_unmap:
1104 iounmap(fs->dma);
1105 iounmap(fs->swim3);
1106
1107 out_release:
1108 macio_release_resource(mdev, 0);
1109 macio_release_resource(mdev, 1);
1110
1111 return rc;
1112}
1113
1114static int __devinit swim3_attach(struct macio_dev *mdev, const struct of_device_id *match)
1115{
1116 int i, rc;
1117 struct gendisk *disk;
1118
1119 /* Add the drive */
1120 rc = swim3_add_device(mdev, floppy_count);
1121 if (rc)
1122 return rc;
1123
1124 /* Now create the queue if not there yet */
1125 if (swim3_queue == NULL) {
1126 /* If we failed, there isn't much we can do as the driver is still
1127 * too dumb to remove the device, just bail out
1128 */
1129 if (register_blkdev(FLOPPY_MAJOR, "fd"))
1130 return 0;
1131 swim3_queue = blk_init_queue(do_fd_request, &swim3_lock);
1132 if (swim3_queue == NULL) {
1133 unregister_blkdev(FLOPPY_MAJOR, "fd");
1134 return 0;
1135 }
1136 }
1137
1138 /* Now register that disk. Same comment about failure handling */
1139 i = floppy_count++;
1140 disk = disks[i] = alloc_disk(1);
1141 if (disk == NULL)
1142 return 0;
1143
1144 disk->major = FLOPPY_MAJOR;
1145 disk->first_minor = i;
1146 disk->fops = &floppy_fops;
1147 disk->private_data = &floppy_states[i];
1148 disk->queue = swim3_queue;
1149 disk->flags |= GENHD_FL_REMOVABLE;
1150 sprintf(disk->disk_name, "fd%d", i);
1151 set_capacity(disk, 2880);
1152 add_disk(disk);
1153
1154 return 0;
1155}
1156
1157static struct of_device_id swim3_match[] =
1158{
1159 {
1160 .name = "swim3",
1161 },
1162 {
1163 .compatible = "ohare-swim3"
1164 },
1165 {
1166 .compatible = "swim3"
1167 },
1168};
1169
1170static struct macio_driver swim3_driver =
1171{
1172 .name = "swim3",
1173 .match_table = swim3_match,
1174 .probe = swim3_attach,
1175#if 0
1176 .suspend = swim3_suspend,
1177 .resume = swim3_resume,
1178#endif
1179};
1180
1181
1182int swim3_init(void)
1183{
1184 macio_register_driver(&swim3_driver);
1155 return 0; 1185 return 0;
1156} 1186}
1157 1187