diff options
-rw-r--r-- | drivers/ata/Kconfig | 2 | ||||
-rw-r--r-- | drivers/ata/sata_mv.c | 132 |
2 files changed, 75 insertions, 59 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index ae19c9b30d15..ba8f7f4dfa11 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -69,7 +69,7 @@ config ATA_PIIX | |||
69 | 69 | ||
70 | config SATA_MV | 70 | config SATA_MV |
71 | tristate "Marvell SATA support (HIGHLY EXPERIMENTAL)" | 71 | tristate "Marvell SATA support (HIGHLY EXPERIMENTAL)" |
72 | depends on PCI && EXPERIMENTAL | 72 | depends on EXPERIMENTAL |
73 | help | 73 | help |
74 | This option enables support for the Marvell Serial ATA family. | 74 | This option enables support for the Marvell Serial ATA family. |
75 | Currently supports 88SX[56]0[48][01] chips. | 75 | Currently supports 88SX[56]0[48][01] chips. |
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 38d4d08283e2..3c1b5c9027db 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -127,6 +127,9 @@ enum { | |||
127 | /* Host Flags */ | 127 | /* Host Flags */ |
128 | MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */ | 128 | MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */ |
129 | MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */ | 129 | MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */ |
130 | /* SoC integrated controllers, no PCI interface */ | ||
131 | MV_FLAG_SOC = (1 << 28), | ||
132 | |||
130 | MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 133 | MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
131 | ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI | | 134 | ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI | |
132 | ATA_FLAG_PIO_POLLING, | 135 | ATA_FLAG_PIO_POLLING, |
@@ -340,6 +343,7 @@ enum { | |||
340 | #define IS_GEN_I(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_I) | 343 | #define IS_GEN_I(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_I) |
341 | #define IS_GEN_II(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_II) | 344 | #define IS_GEN_II(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_II) |
342 | #define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE) | 345 | #define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE) |
346 | #define HAS_PCI(host) (!((host)->ports[0]->flags & MV_FLAG_SOC)) | ||
343 | 347 | ||
344 | enum { | 348 | enum { |
345 | /* DMA boundary 0xffff is required by the s/g splitting | 349 | /* DMA boundary 0xffff is required by the s/g splitting |
@@ -442,7 +446,7 @@ struct mv_hw_ops { | |||
442 | int (*reset_hc)(struct mv_host_priv *hpriv, void __iomem *mmio, | 446 | int (*reset_hc)(struct mv_host_priv *hpriv, void __iomem *mmio, |
443 | unsigned int n_hc); | 447 | unsigned int n_hc); |
444 | void (*reset_flash)(struct mv_host_priv *hpriv, void __iomem *mmio); | 448 | void (*reset_flash)(struct mv_host_priv *hpriv, void __iomem *mmio); |
445 | void (*reset_bus)(struct pci_dev *pdev, void __iomem *mmio); | 449 | void (*reset_bus)(struct ata_host *host, void __iomem *mmio); |
446 | }; | 450 | }; |
447 | 451 | ||
448 | static void mv_irq_clear(struct ata_port *ap); | 452 | static void mv_irq_clear(struct ata_port *ap); |
@@ -459,7 +463,6 @@ static void mv_error_handler(struct ata_port *ap); | |||
459 | static void mv_eh_freeze(struct ata_port *ap); | 463 | static void mv_eh_freeze(struct ata_port *ap); |
460 | static void mv_eh_thaw(struct ata_port *ap); | 464 | static void mv_eh_thaw(struct ata_port *ap); |
461 | static void mv6_dev_config(struct ata_device *dev); | 465 | static void mv6_dev_config(struct ata_device *dev); |
462 | static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); | ||
463 | 466 | ||
464 | static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, | 467 | static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, |
465 | unsigned int port); | 468 | unsigned int port); |
@@ -469,7 +472,7 @@ static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx, | |||
469 | static int mv5_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, | 472 | static int mv5_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, |
470 | unsigned int n_hc); | 473 | unsigned int n_hc); |
471 | static void mv5_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio); | 474 | static void mv5_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio); |
472 | static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio); | 475 | static void mv5_reset_bus(struct ata_host *host, void __iomem *mmio); |
473 | 476 | ||
474 | static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, | 477 | static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, |
475 | unsigned int port); | 478 | unsigned int port); |
@@ -479,7 +482,7 @@ static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx, | |||
479 | static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, | 482 | static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, |
480 | unsigned int n_hc); | 483 | unsigned int n_hc); |
481 | static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio); | 484 | static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio); |
482 | static void mv_reset_pci_bus(struct pci_dev *pdev, void __iomem *mmio); | 485 | static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio); |
483 | static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio, | 486 | static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio, |
484 | unsigned int port_no); | 487 | unsigned int port_no); |
485 | static void mv_edma_cfg(struct mv_port_priv *pp, struct mv_host_priv *hpriv, | 488 | static void mv_edma_cfg(struct mv_port_priv *pp, struct mv_host_priv *hpriv, |
@@ -690,13 +693,6 @@ static const struct pci_device_id mv_pci_tbl[] = { | |||
690 | { } /* terminate list */ | 693 | { } /* terminate list */ |
691 | }; | 694 | }; |
692 | 695 | ||
693 | static struct pci_driver mv_pci_driver = { | ||
694 | .name = DRV_NAME, | ||
695 | .id_table = mv_pci_tbl, | ||
696 | .probe = mv_init_one, | ||
697 | .remove = ata_pci_remove_one, | ||
698 | }; | ||
699 | |||
700 | static const struct mv_hw_ops mv5xxx_ops = { | 696 | static const struct mv_hw_ops mv5xxx_ops = { |
701 | .phy_errata = mv5_phy_errata, | 697 | .phy_errata = mv5_phy_errata, |
702 | .enable_leds = mv5_enable_leds, | 698 | .enable_leds = mv5_enable_leds, |
@@ -716,45 +712,6 @@ static const struct mv_hw_ops mv6xxx_ops = { | |||
716 | }; | 712 | }; |
717 | 713 | ||
718 | /* | 714 | /* |
719 | * module options | ||
720 | */ | ||
721 | static int msi; /* Use PCI msi; either zero (off, default) or non-zero */ | ||
722 | |||
723 | |||
724 | /* move to PCI layer or libata core? */ | ||
725 | static int pci_go_64(struct pci_dev *pdev) | ||
726 | { | ||
727 | int rc; | ||
728 | |||
729 | if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { | ||
730 | rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); | ||
731 | if (rc) { | ||
732 | rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | ||
733 | if (rc) { | ||
734 | dev_printk(KERN_ERR, &pdev->dev, | ||
735 | "64-bit DMA enable failed\n"); | ||
736 | return rc; | ||
737 | } | ||
738 | } | ||
739 | } else { | ||
740 | rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
741 | if (rc) { | ||
742 | dev_printk(KERN_ERR, &pdev->dev, | ||
743 | "32-bit DMA enable failed\n"); | ||
744 | return rc; | ||
745 | } | ||
746 | rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | ||
747 | if (rc) { | ||
748 | dev_printk(KERN_ERR, &pdev->dev, | ||
749 | "32-bit consistent DMA enable failed\n"); | ||
750 | return rc; | ||
751 | } | ||
752 | } | ||
753 | |||
754 | return rc; | ||
755 | } | ||
756 | |||
757 | /* | ||
758 | * Functions | 715 | * Functions |
759 | */ | 716 | */ |
760 | 717 | ||
@@ -1823,7 +1780,7 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance) | |||
1823 | 1780 | ||
1824 | n_hcs = mv_get_hc_count(host->ports[0]->flags); | 1781 | n_hcs = mv_get_hc_count(host->ports[0]->flags); |
1825 | 1782 | ||
1826 | if (unlikely(irq_stat & PCI_ERR)) { | 1783 | if (unlikely((irq_stat & PCI_ERR) && HAS_PCI(host))) { |
1827 | mv_pci_error(host, mmio); | 1784 | mv_pci_error(host, mmio); |
1828 | handled = 1; | 1785 | handled = 1; |
1829 | goto out_unlock; /* skip all other HC irq handling */ | 1786 | goto out_unlock; /* skip all other HC irq handling */ |
@@ -1894,8 +1851,9 @@ static int mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) | |||
1894 | return -EINVAL; | 1851 | return -EINVAL; |
1895 | } | 1852 | } |
1896 | 1853 | ||
1897 | static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio) | 1854 | static void mv5_reset_bus(struct ata_host *host, void __iomem *mmio) |
1898 | { | 1855 | { |
1856 | struct pci_dev *pdev = to_pci_dev(host->dev); | ||
1899 | int early_5080; | 1857 | int early_5080; |
1900 | 1858 | ||
1901 | early_5080 = (pdev->device == 0x5080) && (pdev->revision == 0); | 1859 | early_5080 = (pdev->device == 0x5080) && (pdev->revision == 0); |
@@ -1906,7 +1864,7 @@ static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio) | |||
1906 | writel(tmp, mmio + MV_PCI_EXP_ROM_BAR_CTL); | 1864 | writel(tmp, mmio + MV_PCI_EXP_ROM_BAR_CTL); |
1907 | } | 1865 | } |
1908 | 1866 | ||
1909 | mv_reset_pci_bus(pdev, mmio); | 1867 | mv_reset_pci_bus(host, mmio); |
1910 | } | 1868 | } |
1911 | 1869 | ||
1912 | static void mv5_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio) | 1870 | static void mv5_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio) |
@@ -2030,9 +1988,8 @@ static int mv5_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, | |||
2030 | 1988 | ||
2031 | #undef ZERO | 1989 | #undef ZERO |
2032 | #define ZERO(reg) writel(0, mmio + (reg)) | 1990 | #define ZERO(reg) writel(0, mmio + (reg)) |
2033 | static void mv_reset_pci_bus(struct pci_dev *pdev, void __iomem *mmio) | 1991 | static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio) |
2034 | { | 1992 | { |
2035 | struct ata_host *host = dev_get_drvdata(&pdev->dev); | ||
2036 | struct mv_host_priv *hpriv = host->private_data; | 1993 | struct mv_host_priv *hpriv = host->private_data; |
2037 | u32 tmp; | 1994 | u32 tmp; |
2038 | 1995 | ||
@@ -2676,7 +2633,6 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) | |||
2676 | static int mv_init_host(struct ata_host *host, unsigned int board_idx) | 2633 | static int mv_init_host(struct ata_host *host, unsigned int board_idx) |
2677 | { | 2634 | { |
2678 | int rc = 0, n_hc, port, hc; | 2635 | int rc = 0, n_hc, port, hc; |
2679 | struct pci_dev *pdev = to_pci_dev(host->dev); | ||
2680 | void __iomem *mmio = host->iomap[MV_PRIMARY_BAR]; | 2636 | void __iomem *mmio = host->iomap[MV_PRIMARY_BAR]; |
2681 | struct mv_host_priv *hpriv = host->private_data; | 2637 | struct mv_host_priv *hpriv = host->private_data; |
2682 | 2638 | ||
@@ -2697,7 +2653,7 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) | |||
2697 | goto done; | 2653 | goto done; |
2698 | 2654 | ||
2699 | hpriv->ops->reset_flash(hpriv, mmio); | 2655 | hpriv->ops->reset_flash(hpriv, mmio); |
2700 | hpriv->ops->reset_bus(pdev, mmio); | 2656 | hpriv->ops->reset_bus(host, mmio); |
2701 | hpriv->ops->enable_leds(hpriv, mmio); | 2657 | hpriv->ops->enable_leds(hpriv, mmio); |
2702 | 2658 | ||
2703 | for (port = 0; port < host->n_ports; port++) { | 2659 | for (port = 0; port < host->n_ports; port++) { |
@@ -2720,8 +2676,10 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) | |||
2720 | 2676 | ||
2721 | mv_port_init(&ap->ioaddr, port_mmio); | 2677 | mv_port_init(&ap->ioaddr, port_mmio); |
2722 | 2678 | ||
2679 | #ifdef CONFIG_PCI | ||
2723 | ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio"); | 2680 | ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio"); |
2724 | ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port"); | 2681 | ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port"); |
2682 | #endif | ||
2725 | } | 2683 | } |
2726 | 2684 | ||
2727 | for (hc = 0; hc < n_hc; hc++) { | 2685 | for (hc = 0; hc < n_hc; hc++) { |
@@ -2758,6 +2716,55 @@ done: | |||
2758 | return rc; | 2716 | return rc; |
2759 | } | 2717 | } |
2760 | 2718 | ||
2719 | #ifdef CONFIG_PCI | ||
2720 | static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); | ||
2721 | |||
2722 | static struct pci_driver mv_pci_driver = { | ||
2723 | .name = DRV_NAME, | ||
2724 | .id_table = mv_pci_tbl, | ||
2725 | .probe = mv_init_one, | ||
2726 | .remove = ata_pci_remove_one, | ||
2727 | }; | ||
2728 | |||
2729 | /* | ||
2730 | * module options | ||
2731 | */ | ||
2732 | static int msi; /* Use PCI msi; either zero (off, default) or non-zero */ | ||
2733 | |||
2734 | |||
2735 | /* move to PCI layer or libata core? */ | ||
2736 | static int pci_go_64(struct pci_dev *pdev) | ||
2737 | { | ||
2738 | int rc; | ||
2739 | |||
2740 | if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { | ||
2741 | rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); | ||
2742 | if (rc) { | ||
2743 | rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | ||
2744 | if (rc) { | ||
2745 | dev_printk(KERN_ERR, &pdev->dev, | ||
2746 | "64-bit DMA enable failed\n"); | ||
2747 | return rc; | ||
2748 | } | ||
2749 | } | ||
2750 | } else { | ||
2751 | rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
2752 | if (rc) { | ||
2753 | dev_printk(KERN_ERR, &pdev->dev, | ||
2754 | "32-bit DMA enable failed\n"); | ||
2755 | return rc; | ||
2756 | } | ||
2757 | rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | ||
2758 | if (rc) { | ||
2759 | dev_printk(KERN_ERR, &pdev->dev, | ||
2760 | "32-bit consistent DMA enable failed\n"); | ||
2761 | return rc; | ||
2762 | } | ||
2763 | } | ||
2764 | |||
2765 | return rc; | ||
2766 | } | ||
2767 | |||
2761 | /** | 2768 | /** |
2762 | * mv_print_info - Dump key info to kernel log for perusal. | 2769 | * mv_print_info - Dump key info to kernel log for perusal. |
2763 | * @host: ATA host to print info about | 2770 | * @host: ATA host to print info about |
@@ -2886,15 +2893,22 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2886 | return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED, | 2893 | return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED, |
2887 | IS_GEN_I(hpriv) ? &mv5_sht : &mv6_sht); | 2894 | IS_GEN_I(hpriv) ? &mv5_sht : &mv6_sht); |
2888 | } | 2895 | } |
2896 | #endif | ||
2889 | 2897 | ||
2890 | static int __init mv_init(void) | 2898 | static int __init mv_init(void) |
2891 | { | 2899 | { |
2892 | return pci_register_driver(&mv_pci_driver); | 2900 | int rc = -ENODEV; |
2901 | #ifdef CONFIG_PCI | ||
2902 | rc = pci_register_driver(&mv_pci_driver); | ||
2903 | #endif | ||
2904 | return rc; | ||
2893 | } | 2905 | } |
2894 | 2906 | ||
2895 | static void __exit mv_exit(void) | 2907 | static void __exit mv_exit(void) |
2896 | { | 2908 | { |
2909 | #ifdef CONFIG_PCI | ||
2897 | pci_unregister_driver(&mv_pci_driver); | 2910 | pci_unregister_driver(&mv_pci_driver); |
2911 | #endif | ||
2898 | } | 2912 | } |
2899 | 2913 | ||
2900 | MODULE_AUTHOR("Brett Russ"); | 2914 | MODULE_AUTHOR("Brett Russ"); |
@@ -2903,8 +2917,10 @@ MODULE_LICENSE("GPL"); | |||
2903 | MODULE_DEVICE_TABLE(pci, mv_pci_tbl); | 2917 | MODULE_DEVICE_TABLE(pci, mv_pci_tbl); |
2904 | MODULE_VERSION(DRV_VERSION); | 2918 | MODULE_VERSION(DRV_VERSION); |
2905 | 2919 | ||
2920 | #ifdef CONFIG_PCI | ||
2906 | module_param(msi, int, 0444); | 2921 | module_param(msi, int, 0444); |
2907 | MODULE_PARM_DESC(msi, "Enable use of PCI MSI (0=off, 1=on)"); | 2922 | MODULE_PARM_DESC(msi, "Enable use of PCI MSI (0=off, 1=on)"); |
2923 | #endif | ||
2908 | 2924 | ||
2909 | module_init(mv_init); | 2925 | module_init(mv_init); |
2910 | module_exit(mv_exit); | 2926 | module_exit(mv_exit); |