diff options
-rw-r--r-- | Documentation/DocBook/libata.tmpl | 12 | ||||
-rw-r--r-- | drivers/ata/libata-sff.c | 31 | ||||
-rw-r--r-- | drivers/ata/pata_bf54x.c | 40 | ||||
-rw-r--r-- | drivers/ata/pata_scc.c | 38 | ||||
-rw-r--r-- | include/linux/libata.h | 1 |
5 files changed, 63 insertions, 59 deletions
diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl index 70b811e9f2ca..828748c4e78d 100644 --- a/Documentation/DocBook/libata.tmpl +++ b/Documentation/DocBook/libata.tmpl @@ -225,6 +225,18 @@ u8 (*sff_check_altstatus)(struct ata_port *ap); </sect2> + <sect2><title>Write specific ATA shadow register</title> + <programlisting> +void (*sff_set_devctl)(struct ata_port *ap, u8 ctl); + </programlisting> + + <para> + Write the device control ATA shadow register to the hardware. + Most drivers don't need to define this. + </para> + + </sect2> + <sect2><title>Select ATA device on bus</title> <programlisting> void (*sff_dev_select)(struct ata_port *ap, unsigned int device); diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index b31389605bee..31b495fcd969 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -446,6 +446,27 @@ int ata_sff_wait_ready(struct ata_link *link, unsigned long deadline) EXPORT_SYMBOL_GPL(ata_sff_wait_ready); /** + * ata_sff_set_devctl - Write device control reg + * @ap: port where the device is + * @ctl: value to write + * + * Writes ATA taskfile device control register. + * + * Note: may NOT be used as the sff_set_devctl() entry in + * ata_port_operations. + * + * LOCKING: + * Inherited from caller. + */ +static void ata_sff_set_devctl(struct ata_port *ap, u8 ctl) +{ + if (ap->ops->sff_set_devctl) + ap->ops->sff_set_devctl(ap, ctl); + else + iowrite8(ctl, ap->ioaddr.ctl_addr); +} + +/** * ata_sff_dev_select - Select device 0/1 on ATA bus * @ap: ATA channel to manipulate * @device: ATA device (numbered from zero) to select @@ -1895,13 +1916,11 @@ EXPORT_SYMBOL_GPL(ata_sff_lost_interrupt); */ void ata_sff_freeze(struct ata_port *ap) { - struct ata_ioports *ioaddr = &ap->ioaddr; - ap->ctl |= ATA_NIEN; ap->last_ctl = ap->ctl; - if (ioaddr->ctl_addr) - iowrite8(ap->ctl, ioaddr->ctl_addr); + if (ap->ops->sff_set_devctl || ap->ioaddr.ctl_addr) + ata_sff_set_devctl(ap, ap->ctl); /* Under certain circumstances, some controllers raise IRQ on * ATA_NIEN manipulation. Also, many controllers fail to mask @@ -2301,8 +2320,8 @@ void ata_sff_postreset(struct ata_link *link, unsigned int *classes) } /* set up device control */ - if (ap->ioaddr.ctl_addr) { - iowrite8(ap->ctl, ap->ioaddr.ctl_addr); + if (ap->ops->sff_set_devctl || ap->ioaddr.ctl_addr) { + ata_sff_set_devctl(ap, ap->ctl); ap->last_ctl = ap->ctl; } } diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index 02c81f12c702..198307534d90 100644 --- a/drivers/ata/pata_bf54x.c +++ b/drivers/ata/pata_bf54x.c @@ -821,6 +821,18 @@ static void bfin_dev_select(struct ata_port *ap, unsigned int device) } /** + * bfin_set_devctl - Write device control reg + * @ap: port where the device is + * @ctl: value to write + */ + +static u8 bfin_set_devctl(struct ata_port *ap, u8 ctl) +{ + void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; + write_atapi_register(base, ATA_REG_CTRL, ctl); +} + +/** * bfin_bmdma_setup - Set up IDE DMA transaction * @qc: Info associated with this ATA transaction. * @@ -1240,32 +1252,6 @@ static unsigned char bfin_irq_on(struct ata_port *ap) } /** - * bfin_freeze - Freeze DMA controller port - * @ap: port to freeze - * - * Note: Original code is ata_sff_freeze(). - */ - -static void bfin_freeze(struct ata_port *ap) -{ - void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; - - dev_dbg(ap->dev, "in atapi dma freeze\n"); - ap->ctl |= ATA_NIEN; - ap->last_ctl = ap->ctl; - - write_atapi_register(base, ATA_REG_CTRL, ap->ctl); - - /* Under certain circumstances, some controllers raise IRQ on - * ATA_NIEN manipulation. Also, many controllers fail to mask - * previously pending IRQ on ATA_NIEN assertion. Clear it. - */ - ap->ops->sff_check_status(ap); - - bfin_irq_clear(ap); -} - -/** * bfin_thaw - Thaw DMA controller port * @ap: port to thaw * @@ -1476,6 +1462,7 @@ static struct ata_port_operations bfin_pata_ops = { .sff_check_status = bfin_check_status, .sff_check_altstatus = bfin_check_altstatus, .sff_dev_select = bfin_dev_select, + .sff_set_devctl = bfin_set_devctl, .bmdma_setup = bfin_bmdma_setup, .bmdma_start = bfin_bmdma_start, @@ -1485,7 +1472,6 @@ static struct ata_port_operations bfin_pata_ops = { .qc_prep = ata_noop_qc_prep, - .freeze = bfin_freeze, .thaw = bfin_thaw, .softreset = bfin_softreset, .postreset = bfin_postreset, diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index 77ff829af176..86b25fef34a9 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -416,6 +416,17 @@ static void scc_dev_select (struct ata_port *ap, unsigned int device) } /** + * scc_set_devctl - Write device control reg + * @ap: port where the device is + * @ctl: value to write + */ + +static void scc_set_devctl(struct ata_port *ap, u8 ctl) +{ + out_be32(ap->ioaddr.ctl_addr, ctl); +} + +/** * scc_bmdma_setup - Set up PCI IDE BMDMA transaction * @qc: Info associated with this ATA transaction. * @@ -840,31 +851,6 @@ static u8 scc_irq_on (struct ata_port *ap) } /** - * scc_freeze - Freeze BMDMA controller port - * @ap: port to freeze - * - * Note: Original code is ata_sff_freeze(). - */ - -static void scc_freeze (struct ata_port *ap) -{ - struct ata_ioports *ioaddr = &ap->ioaddr; - - ap->ctl |= ATA_NIEN; - ap->last_ctl = ap->ctl; - - out_be32(ioaddr->ctl_addr, ap->ctl); - - /* Under certain circumstances, some controllers raise IRQ on - * ATA_NIEN manipulation. Also, many controllers fail to mask - * previously pending IRQ on ATA_NIEN assertion. Clear it. - */ - ap->ops->sff_check_status(ap); - - ap->ops->sff_irq_clear(ap); -} - -/** * scc_pata_prereset - prepare for reset * @ap: ATA port to be reset * @deadline: deadline jiffies for the operation @@ -977,6 +963,7 @@ static struct ata_port_operations scc_pata_ops = { .sff_check_status = scc_check_status, .sff_check_altstatus = scc_check_altstatus, .sff_dev_select = scc_dev_select, + .sff_set_devctl = scc_set_devctl, .bmdma_setup = scc_bmdma_setup, .bmdma_start = scc_bmdma_start, @@ -984,7 +971,6 @@ static struct ata_port_operations scc_pata_ops = { .bmdma_status = scc_bmdma_status, .sff_data_xfer = scc_data_xfer, - .freeze = scc_freeze, .prereset = scc_pata_prereset, .softreset = scc_softreset, .postreset = scc_postreset, diff --git a/include/linux/libata.h b/include/linux/libata.h index 242eb2646101..6207ec600722 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -850,6 +850,7 @@ struct ata_port_operations { * SFF / taskfile oriented ops */ void (*sff_dev_select)(struct ata_port *ap, unsigned int device); + void (*sff_set_devctl)(struct ata_port *ap, u8 ctl); u8 (*sff_check_status)(struct ata_port *ap); u8 (*sff_check_altstatus)(struct ata_port *ap); void (*sff_tf_load)(struct ata_port *ap, const struct ata_taskfile *tf); |