[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:
parent
7c6efda599
commit
3e9a69275f
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue