[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>
This commit is contained in:
Benjamin Herrenschmidt 2006-07-03 17:25:26 +10:00 committed by Paul Mackerras
parent 7c6efda599
commit 3e9a69275f
1 changed files with 131 additions and 101 deletions

View File

@ -250,8 +250,6 @@ static int floppy_open(struct inode *inode, struct file *filp);
static int floppy_release(struct inode *inode, struct file *filp); static int floppy_release(struct inode *inode, struct file *filp);
static int floppy_check_change(struct gendisk *disk); static int floppy_check_change(struct gendisk *disk);
static int floppy_revalidate(struct gendisk *disk); static int floppy_revalidate(struct gendisk *disk);
static int swim3_add_device(struct device_node *swims);
int swim3_init(void);
#ifndef CONFIG_PMAC_MEDIABAY #ifndef CONFIG_PMAC_MEDIABAY
#define check_media_bay(which, what) 1 #define check_media_bay(which, what) 1
@ -1011,114 +1009,63 @@ static struct block_device_operations floppy_fops = {
.revalidate_disk= floppy_revalidate, .revalidate_disk= floppy_revalidate,
}; };
int swim3_init(void) static int swim3_add_device(struct macio_dev *mdev, int index)
{
struct device_node *swim;
int err = -ENOMEM;
int i;
swim = find_devices("floppy");
while (swim && (floppy_count < MAX_FLOPPIES))
{
swim3_add_device(swim);
swim = swim->next;
}
swim = find_devices("swim3");
while (swim && (floppy_count < MAX_FLOPPIES))
{
swim3_add_device(swim);
swim = swim->next;
}
if (!floppy_count)
return -ENODEV;
for (i = 0; i < floppy_count; i++) {
disks[i] = alloc_disk(1);
if (!disks[i])
goto out;
}
if (register_blkdev(FLOPPY_MAJOR, "fd")) {
err = -EBUSY;
goto out;
}
swim3_queue = blk_init_queue(do_fd_request, &swim3_lock);
if (!swim3_queue) {
err = -ENOMEM;
goto out_queue;
}
for (i = 0; i < floppy_count; i++) {
struct gendisk *disk = disks[i];
disk->major = FLOPPY_MAJOR;
disk->first_minor = i;
disk->fops = &floppy_fops;
disk->private_data = &floppy_states[i];
disk->queue = swim3_queue;
disk->flags |= GENHD_FL_REMOVABLE;
sprintf(disk->disk_name, "fd%d", i);
set_capacity(disk, 2880);
add_disk(disk);
}
return 0;
out_queue:
unregister_blkdev(FLOPPY_MAJOR, "fd");
out:
while (i--)
put_disk(disks[i]);
/* shouldn't we do something with results of swim_add_device()? */
return err;
}
static int swim3_add_device(struct device_node *swim)
{ {
struct device_node *swim = mdev->ofdev.node;
struct device_node *mediabay; struct device_node *mediabay;
struct floppy_state *fs = &floppy_states[floppy_count]; struct floppy_state *fs = &floppy_states[index];
struct resource res_reg, res_dma; int rc = -EBUSY;
if (of_address_to_resource(swim, 0, &res_reg) || /* Check & Request resources */
of_address_to_resource(swim, 1, &res_dma)) { if (macio_resource_count(mdev) < 2) {
printk(KERN_ERR "swim3: Can't get addresses\n"); printk(KERN_WARNING "ifd%d: no address for %s\n",
return -EINVAL; index, swim->full_name);
return -ENXIO;
} }
if (request_mem_region(res_reg.start, res_reg.end - res_reg.start + 1, if (macio_irq_count(mdev) < 2) {
" (reg)") == NULL) { printk(KERN_WARNING "fd%d: no intrs for device %s\n",
printk(KERN_ERR "swim3: Can't request register space\n"); index, swim->full_name);
return -EINVAL;
} }
if (request_mem_region(res_dma.start, res_dma.end - res_dma.start + 1, if (macio_request_resource(mdev, 0, "swim3 (mmio)")) {
" (dma)") == NULL) { printk(KERN_ERR "fd%d: can't request mmio resource for %s\n",
release_mem_region(res_reg.start, index, swim->full_name);
res_reg.end - res_reg.start + 1); return -EBUSY;
printk(KERN_ERR "swim3: Can't request DMA space\n");
return -EINVAL;
} }
if (macio_request_resource(mdev, 1, "swim3 (dma)")) {
printk(KERN_ERR "fd%d: can't request dma resource for %s\n",
index, swim->full_name);
macio_release_resource(mdev, 0);
return -EBUSY;
}
dev_set_drvdata(&mdev->ofdev.dev, fs);
if (swim->n_intrs < 2) { mediabay = (strcasecmp(swim->parent->type, "media-bay") == 0) ?
printk(KERN_INFO "swim3: expecting 2 intrs (n_intrs:%d)\n", swim->parent : NULL;
swim->n_intrs);
release_mem_region(res_reg.start,
res_reg.end - res_reg.start + 1);
release_mem_region(res_dma.start,
res_dma.end - res_dma.start + 1);
return -EINVAL;
}
mediabay = (strcasecmp(swim->parent->type, "media-bay") == 0) ? swim->parent : NULL;
if (mediabay == NULL) if (mediabay == NULL)
pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1); pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1);
memset(fs, 0, sizeof(*fs)); memset(fs, 0, sizeof(*fs));
spin_lock_init(&fs->lock); spin_lock_init(&fs->lock);
fs->state = idle; fs->state = idle;
fs->swim3 = (struct swim3 __iomem *)ioremap(res_reg.start, 0x200); fs->swim3 = (struct swim3 __iomem *)
fs->dma = (struct dbdma_regs __iomem *)ioremap(res_dma.start, 0x200); ioremap(macio_resource_start(mdev, 0), 0x200);
fs->swim3_intr = swim->intrs[0].line; if (fs->swim3 == NULL) {
fs->dma_intr = swim->intrs[1].line; printk("fd%d: couldn't map registers for %s\n",
index, swim->full_name);
rc = -ENOMEM;
goto out_release;
}
fs->dma = (struct dbdma_regs __iomem *)
ioremap(macio_resource_start(mdev, 1), 0x200);
if (fs->dma == NULL) {
printk("fd%d: couldn't map DMA for %s\n",
index, swim->full_name);
iounmap(fs->swim3);
rc = -ENOMEM;
goto out_release;
}
fs->swim3_intr = macio_irq(mdev, 0);
fs->dma_intr = macio_irq(mdev, 1);;
fs->cur_cyl = -1; fs->cur_cyl = -1;
fs->cur_sector = -1; fs->cur_sector = -1;
fs->secpercyl = 36; fs->secpercyl = 36;
@ -1132,15 +1079,16 @@ static int swim3_add_device(struct device_node *swim)
st_le16(&fs->dma_cmd[1].command, DBDMA_STOP); st_le16(&fs->dma_cmd[1].command, DBDMA_STOP);
if (request_irq(fs->swim3_intr, swim3_interrupt, 0, "SWIM3", fs)) { if (request_irq(fs->swim3_intr, swim3_interrupt, 0, "SWIM3", fs)) {
printk(KERN_ERR "Couldn't get irq %d for SWIM3\n", fs->swim3_intr); printk(KERN_ERR "fd%d: couldn't request irq %d for %s\n",
index, fs->swim3_intr, swim->full_name);
pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0); pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0);
goto out_unmap;
return -EBUSY; return -EBUSY;
} }
/* /*
if (request_irq(fs->dma_intr, fd_dma_interrupt, 0, "SWIM3-dma", fs)) { if (request_irq(fs->dma_intr, fd_dma_interrupt, 0, "SWIM3-dma", fs)) {
printk(KERN_ERR "Couldn't get irq %d for SWIM3 DMA", printk(KERN_ERR "Couldn't get irq %d for SWIM3 DMA",
fs->dma_intr); fs->dma_intr);
pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0);
return -EBUSY; return -EBUSY;
} }
*/ */
@ -1150,8 +1098,90 @@ static int swim3_add_device(struct device_node *swim)
printk(KERN_INFO "fd%d: SWIM3 floppy controller %s\n", floppy_count, printk(KERN_INFO "fd%d: SWIM3 floppy controller %s\n", floppy_count,
mediabay ? "in media bay" : ""); mediabay ? "in media bay" : "");
floppy_count++; return 0;
out_unmap:
iounmap(fs->dma);
iounmap(fs->swim3);
out_release:
macio_release_resource(mdev, 0);
macio_release_resource(mdev, 1);
return rc;
}
static int __devinit swim3_attach(struct macio_dev *mdev, const struct of_device_id *match)
{
int i, rc;
struct gendisk *disk;
/* Add the drive */
rc = swim3_add_device(mdev, floppy_count);
if (rc)
return rc;
/* Now create the queue if not there yet */
if (swim3_queue == NULL) {
/* If we failed, there isn't much we can do as the driver is still
* too dumb to remove the device, just bail out
*/
if (register_blkdev(FLOPPY_MAJOR, "fd"))
return 0;
swim3_queue = blk_init_queue(do_fd_request, &swim3_lock);
if (swim3_queue == NULL) {
unregister_blkdev(FLOPPY_MAJOR, "fd");
return 0;
}
}
/* Now register that disk. Same comment about failure handling */
i = floppy_count++;
disk = disks[i] = alloc_disk(1);
if (disk == NULL)
return 0;
disk->major = FLOPPY_MAJOR;
disk->first_minor = i;
disk->fops = &floppy_fops;
disk->private_data = &floppy_states[i];
disk->queue = swim3_queue;
disk->flags |= GENHD_FL_REMOVABLE;
sprintf(disk->disk_name, "fd%d", i);
set_capacity(disk, 2880);
add_disk(disk);
return 0;
}
static struct of_device_id swim3_match[] =
{
{
.name = "swim3",
},
{
.compatible = "ohare-swim3"
},
{
.compatible = "swim3"
},
};
static struct macio_driver swim3_driver =
{
.name = "swim3",
.match_table = swim3_match,
.probe = swim3_attach,
#if 0
.suspend = swim3_suspend,
.resume = swim3_resume,
#endif
};
int swim3_init(void)
{
macio_register_driver(&swim3_driver);
return 0; return 0;
} }