#include <linux/delay.h>
#include <linux/libata.h>
-#include <asm/io.h>
#include <asm/types.h>
#include <asm/prom.h>
#include <asm/of_platform.h>
#define DRV_NAME "mpc52xx_ata"
-#define DRV_VERSION "0.1.0"
+#define DRV_VERSION "0.1.2"
/* Private structures used by the driver */
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
.error_handler = mpc52xx_ata_error_handler,
+ .cable_detect = ata_cable_40wire,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_mmio_data_xfer,
- .irq_handler = ata_interrupt,
+ .data_xfer = ata_data_xfer,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
-};
-
-static struct ata_probe_ent mpc52xx_ata_probe_ent = {
- .port_ops = &mpc52xx_ata_port_ops,
- .sht = &mpc52xx_ata_sht,
- .n_ports = 1,
- .pio_mask = 0x1f, /* Up to PIO4 */
- .mwdma_mask = 0x00, /* No MWDMA */
- .udma_mask = 0x00, /* No UDMA */
- .port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_MMIO,
- .irq_flags = 0,
};
static int __devinit
mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv)
{
- struct ata_probe_ent *ae = &mpc52xx_ata_probe_ent;
- struct ata_ioports *aio = &ae->port[0];
- int rv;
-
- INIT_LIST_HEAD(&ae->node);
- ae->dev = dev;
- ae->irq = priv->ata_irq;
-
- aio->cmd_addr = 0; /* Don't have a classic reg block */
- aio->altstatus_addr = (unsigned long)&priv->ata_regs->tf_control;
- aio->ctl_addr = (unsigned long)&priv->ata_regs->tf_control;
- aio->data_addr = (unsigned long)&priv->ata_regs->tf_data;
- aio->error_addr = (unsigned long)&priv->ata_regs->tf_features;
- aio->feature_addr = (unsigned long)&priv->ata_regs->tf_features;
- aio->nsect_addr = (unsigned long)&priv->ata_regs->tf_sec_count;
- aio->lbal_addr = (unsigned long)&priv->ata_regs->tf_sec_num;
- aio->lbam_addr = (unsigned long)&priv->ata_regs->tf_cyl_low;
- aio->lbah_addr = (unsigned long)&priv->ata_regs->tf_cyl_high;
- aio->device_addr = (unsigned long)&priv->ata_regs->tf_dev_head;
- aio->status_addr = (unsigned long)&priv->ata_regs->tf_command;
- aio->command_addr = (unsigned long)&priv->ata_regs->tf_command;
-
- ae->private_data = priv;
-
- rv = ata_device_add(ae);
-
- return rv ? 0 : -EINVAL;
+ struct ata_host *host;
+ struct ata_port *ap;
+ struct ata_ioports *aio;
+ int rc;
+
+ host = ata_host_alloc(dev, 1);
+ if (!host)
+ return -ENOMEM;
+
+ ap = host->ports[0];
+ ap->flags |= ATA_FLAG_SLAVE_POSS;
+ ap->pio_mask = 0x1f; /* Up to PIO4 */
+ ap->mwdma_mask = 0x00; /* No MWDMA */
+ ap->udma_mask = 0x00; /* No UDMA */
+ ap->ops = &mpc52xx_ata_port_ops;
+ host->private_data = priv;
+
+ aio = &ap->ioaddr;
+ aio->cmd_addr = NULL; /* Don't have a classic reg block */
+ aio->altstatus_addr = &priv->ata_regs->tf_control;
+ aio->ctl_addr = &priv->ata_regs->tf_control;
+ aio->data_addr = &priv->ata_regs->tf_data;
+ aio->error_addr = &priv->ata_regs->tf_features;
+ aio->feature_addr = &priv->ata_regs->tf_features;
+ aio->nsect_addr = &priv->ata_regs->tf_sec_count;
+ aio->lbal_addr = &priv->ata_regs->tf_sec_num;
+ aio->lbam_addr = &priv->ata_regs->tf_cyl_low;
+ aio->lbah_addr = &priv->ata_regs->tf_cyl_high;
+ aio->device_addr = &priv->ata_regs->tf_dev_head;
+ aio->status_addr = &priv->ata_regs->tf_command;
+ aio->command_addr = &priv->ata_regs->tf_command;
+
+ /* activate host */
+ return ata_host_activate(host, priv->ata_irq, ata_interrupt, 0,
+ &mpc52xx_ata_sht);
}
static struct mpc52xx_ata_priv *
struct ata_host *host = dev_get_drvdata(dev);
struct mpc52xx_ata_priv *priv = host->private_data;
- ata_host_remove(host);
+ ata_host_detach(host);
return priv;
}
unsigned int ipb_freq;
struct resource res_mem;
int ata_irq = NO_IRQ;
- struct mpc52xx_ata __iomem *ata_regs = NULL;
- struct mpc52xx_ata_priv *priv = NULL;
+ struct mpc52xx_ata __iomem *ata_regs;
+ struct mpc52xx_ata_priv *priv;
int rv;
/* Get ipb frequency */
}
/* Request mem region */
- if (!request_mem_region(res_mem.start,
- sizeof(struct mpc52xx_ata), DRV_NAME)) {
+ if (!devm_request_mem_region(&op->dev, res_mem.start,
+ sizeof(struct mpc52xx_ata), DRV_NAME)) {
printk(KERN_ERR DRV_NAME ": "
"Error while requesting mem region\n");
- irq_dispose_mapping(ata_irq);
- return -EBUSY;
+ rv = -EBUSY;
+ goto err;
}
/* Remap registers */
- ata_regs = ioremap(res_mem.start, sizeof(struct mpc52xx_ata));
+ ata_regs = devm_ioremap(&op->dev, res_mem.start,
+ sizeof(struct mpc52xx_ata));
if (!ata_regs) {
printk(KERN_ERR DRV_NAME ": "
"Error while mapping register set\n");
}
/* Prepare our private structure */
- priv = kmalloc(sizeof(struct mpc52xx_ata_priv), GFP_ATOMIC);
+ priv = devm_kzalloc(&op->dev, sizeof(struct mpc52xx_ata_priv),
+ GFP_ATOMIC);
if (!priv) {
printk(KERN_ERR DRV_NAME ": "
"Error while allocating private structure\n");
/* Error path */
err:
- kfree(priv);
-
- if (ata_regs)
- iounmap(ata_regs);
-
- release_mem_region(res_mem.start, sizeof(struct mpc52xx_ata));
-
irq_dispose_mapping(ata_irq);
-
return rv;
}
mpc52xx_ata_remove(struct of_device *op)
{
struct mpc52xx_ata_priv *priv;
- struct resource res_mem;
- int rv;
- /* Unregister */
priv = mpc52xx_ata_remove_one(&op->dev);
-
- /* Free everything */
- iounmap(priv->ata_regs);
-
- rv = of_address_to_resource(op->node, 0, &res_mem);
- if (rv) {
- printk(KERN_ERR DRV_NAME ": "
- "Error while parsing device node resource\n");
- printk(KERN_ERR DRV_NAME ": "
- "Zone may not be properly released\n");
- } else
- release_mem_region(res_mem.start, sizeof(struct mpc52xx_ata));
-
irq_dispose_mapping(priv->ata_irq);
- kfree(priv);
-
return 0;
}
static int
mpc52xx_ata_suspend(struct of_device *op, pm_message_t state)
{
- return 0; /* FIXME : What to do here ? */
+ struct ata_host *host = dev_get_drvdata(&op->dev);
+
+ return ata_host_suspend(host, state);
}
static int
mpc52xx_ata_resume(struct of_device *op)
{
- return 0; /* FIXME : What to do here ? */
+ struct ata_host *host = dev_get_drvdata(&op->dev);
+ struct mpc52xx_ata_priv *priv = host->private_data;
+ int rv;
+
+ rv = mpc52xx_ata_hw_init(priv);
+ if (rv) {
+ printk(KERN_ERR DRV_NAME ": Error during HW init\n");
+ return rv;
+ }
+
+ ata_host_resume(host);
+
+ return 0;
}
#endif
static struct of_device_id mpc52xx_ata_of_match[] = {
{
- .compatible = "mpc5200-ata",
- },
- {
- .compatible = "mpc52xx-ata",
+ .type = "ata",
+ .compatible = "mpc5200-ata",
},
{},
};