aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaeed Bishara <saeed@marvell.com>2008-02-01 18:08:03 -0500
committerJeff Garzik <jeff@garzik.org>2008-02-06 06:54:17 -0500
commitf351b2d638c3cb0b95adde3549b7bfaf3f991dfa (patch)
tree03d2e5b3fb84efcd96b8d32b349350b15469c327
parent0a87e3e92b299e0f1a69b36664ecde2fc296c40a (diff)
sata_mv: Support SoC controllers
Marvell's Orion SoC includes SATA controllers based on Marvell's PCI-to-SATA 88SX controllers. This patch extends the libATA sata_mv driver to support those controllers. [edited to use linux/ata_platform.h -jg] Signed-off-by: Saeed Bishara <saeed@marvell.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
-rw-r--r--drivers/ata/sata_mv.c365
-rw-r--r--include/linux/ata_platform.h13
2 files changed, 330 insertions, 48 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 3c1b5c9027db..1e97a33cd260 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -71,6 +71,8 @@
71#include <linux/interrupt.h> 71#include <linux/interrupt.h>
72#include <linux/dma-mapping.h> 72#include <linux/dma-mapping.h>
73#include <linux/device.h> 73#include <linux/device.h>
74#include <linux/platform_device.h>
75#include <linux/ata_platform.h>
74#include <scsi/scsi_host.h> 76#include <scsi/scsi_host.h>
75#include <scsi/scsi_cmnd.h> 77#include <scsi/scsi_cmnd.h>
76#include <scsi/scsi_device.h> 78#include <scsi/scsi_device.h>
@@ -179,6 +181,8 @@ enum {
179 181
180 HC_MAIN_IRQ_CAUSE_OFS = 0x1d60, 182 HC_MAIN_IRQ_CAUSE_OFS = 0x1d60,
181 HC_MAIN_IRQ_MASK_OFS = 0x1d64, 183 HC_MAIN_IRQ_MASK_OFS = 0x1d64,
184 HC_SOC_MAIN_IRQ_CAUSE_OFS = 0x20020,
185 HC_SOC_MAIN_IRQ_MASK_OFS = 0x20024,
182 PORT0_ERR = (1 << 0), /* shift by port # */ 186 PORT0_ERR = (1 << 0), /* shift by port # */
183 PORT0_DONE = (1 << 1), /* shift by port # */ 187 PORT0_DONE = (1 << 1), /* shift by port # */
184 HC0_IRQ_PEND = 0x1ff, /* bits 0-8 = HC0's ports */ 188 HC0_IRQ_PEND = 0x1ff, /* bits 0-8 = HC0's ports */
@@ -194,11 +198,13 @@ enum {
194 TWSI_INT = (1 << 24), 198 TWSI_INT = (1 << 24),
195 HC_MAIN_RSVD = (0x7f << 25), /* bits 31-25 */ 199 HC_MAIN_RSVD = (0x7f << 25), /* bits 31-25 */
196 HC_MAIN_RSVD_5 = (0x1fff << 19), /* bits 31-19 */ 200 HC_MAIN_RSVD_5 = (0x1fff << 19), /* bits 31-19 */
201 HC_MAIN_RSVD_SOC = (0x3fffffb << 6), /* bits 31-9, 7-6 */
197 HC_MAIN_MASKED_IRQS = (TRAN_LO_DONE | TRAN_HI_DONE | 202 HC_MAIN_MASKED_IRQS = (TRAN_LO_DONE | TRAN_HI_DONE |
198 PORTS_0_7_COAL_DONE | GPIO_INT | TWSI_INT | 203 PORTS_0_7_COAL_DONE | GPIO_INT | TWSI_INT |
199 HC_MAIN_RSVD), 204 HC_MAIN_RSVD),
200 HC_MAIN_MASKED_IRQS_5 = (PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE | 205 HC_MAIN_MASKED_IRQS_5 = (PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE |
201 HC_MAIN_RSVD_5), 206 HC_MAIN_RSVD_5),
207 HC_MAIN_MASKED_IRQS_SOC = (PORTS_0_3_COAL_DONE | HC_MAIN_RSVD_SOC),
202 208
203 /* SATAHC registers */ 209 /* SATAHC registers */
204 HC_CFG_OFS = 0, 210 HC_CFG_OFS = 0,
@@ -368,6 +374,7 @@ enum chip_type {
368 chip_608x, 374 chip_608x,
369 chip_6042, 375 chip_6042,
370 chip_7042, 376 chip_7042,
377 chip_soc,
371}; 378};
372 379
373/* Command ReQuest Block: 32B */ 380/* Command ReQuest Block: 32B */
@@ -424,6 +431,10 @@ struct mv_host_priv {
424 u32 hp_flags; 431 u32 hp_flags;
425 struct mv_port_signal signal[8]; 432 struct mv_port_signal signal[8];
426 const struct mv_hw_ops *ops; 433 const struct mv_hw_ops *ops;
434 int n_ports;
435 void __iomem *base;
436 void __iomem *main_cause_reg_addr;
437 void __iomem *main_mask_reg_addr;
427 u32 irq_cause_ofs; 438 u32 irq_cause_ofs;
428 u32 irq_mask_ofs; 439 u32 irq_mask_ofs;
429 u32 unmask_all_irqs; 440 u32 unmask_all_irqs;
@@ -482,6 +493,15 @@ static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx,
482static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, 493static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio,
483 unsigned int n_hc); 494 unsigned int n_hc);
484static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio); 495static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio);
496static void mv_soc_enable_leds(struct mv_host_priv *hpriv,
497 void __iomem *mmio);
498static void mv_soc_read_preamp(struct mv_host_priv *hpriv, int idx,
499 void __iomem *mmio);
500static int mv_soc_reset_hc(struct mv_host_priv *hpriv,
501 void __iomem *mmio, unsigned int n_hc);
502static void mv_soc_reset_flash(struct mv_host_priv *hpriv,
503 void __iomem *mmio);
504static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio);
485static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio); 505static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio);
486static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio, 506static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio,
487 unsigned int port_no); 507 unsigned int port_no);
@@ -661,6 +681,12 @@ static const struct ata_port_info mv_port_info[] = {
661 .udma_mask = ATA_UDMA6, 681 .udma_mask = ATA_UDMA6,
662 .port_ops = &mv_iie_ops, 682 .port_ops = &mv_iie_ops,
663 }, 683 },
684 { /* chip_soc */
685 .flags = MV_COMMON_FLAGS | MV_FLAG_SOC,
686 .pio_mask = 0x1f, /* pio0-4 */
687 .udma_mask = ATA_UDMA6,
688 .port_ops = &mv_iie_ops,
689 },
664}; 690};
665 691
666static const struct pci_device_id mv_pci_tbl[] = { 692static const struct pci_device_id mv_pci_tbl[] = {
@@ -711,6 +737,15 @@ static const struct mv_hw_ops mv6xxx_ops = {
711 .reset_bus = mv_reset_pci_bus, 737 .reset_bus = mv_reset_pci_bus,
712}; 738};
713 739
740static const struct mv_hw_ops mv_soc_ops = {
741 .phy_errata = mv6_phy_errata,
742 .enable_leds = mv_soc_enable_leds,
743 .read_preamp = mv_soc_read_preamp,
744 .reset_hc = mv_soc_reset_hc,
745 .reset_flash = mv_soc_reset_flash,
746 .reset_bus = mv_soc_reset_bus,
747};
748
714/* 749/*
715 * Functions 750 * Functions
716 */ 751 */
@@ -749,9 +784,15 @@ static inline void __iomem *mv_port_base(void __iomem *base, unsigned int port)
749 (mv_hardport_from_port(port) * MV_PORT_REG_SZ); 784 (mv_hardport_from_port(port) * MV_PORT_REG_SZ);
750} 785}
751 786
787static inline void __iomem *mv_host_base(struct ata_host *host)
788{
789 struct mv_host_priv *hpriv = host->private_data;
790 return hpriv->base;
791}
792
752static inline void __iomem *mv_ap_base(struct ata_port *ap) 793static inline void __iomem *mv_ap_base(struct ata_port *ap)
753{ 794{
754 return mv_port_base(ap->host->iomap[MV_PRIMARY_BAR], ap->port_no); 795 return mv_port_base(mv_host_base(ap->host), ap->port_no);
755} 796}
756 797
757static inline int mv_get_hc_count(unsigned long port_flags) 798static inline int mv_get_hc_count(unsigned long port_flags)
@@ -1649,16 +1690,21 @@ static void mv_intr_edma(struct ata_port *ap)
1649 */ 1690 */
1650static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc) 1691static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc)
1651{ 1692{
1652 void __iomem *mmio = host->iomap[MV_PRIMARY_BAR]; 1693 struct mv_host_priv *hpriv = host->private_data;
1694 void __iomem *mmio = hpriv->base;
1653 void __iomem *hc_mmio = mv_hc_base(mmio, hc); 1695 void __iomem *hc_mmio = mv_hc_base(mmio, hc);
1654 u32 hc_irq_cause; 1696 u32 hc_irq_cause;
1655 int port, port0; 1697 int port, port0, last_port;
1656 1698
1657 if (hc == 0) 1699 if (hc == 0)
1658 port0 = 0; 1700 port0 = 0;
1659 else 1701 else
1660 port0 = MV_PORTS_PER_HC; 1702 port0 = MV_PORTS_PER_HC;
1661 1703
1704 if (HAS_PCI(host))
1705 last_port = port0 + MV_PORTS_PER_HC;
1706 else
1707 last_port = port0 + hpriv->n_ports;
1662 /* we'll need the HC success int register in most cases */ 1708 /* we'll need the HC success int register in most cases */
1663 hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS); 1709 hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS);
1664 if (!hc_irq_cause) 1710 if (!hc_irq_cause)
@@ -1669,7 +1715,7 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc)
1669 VPRINTK("ENTER, hc%u relevant=0x%08x HC IRQ cause=0x%08x\n", 1715 VPRINTK("ENTER, hc%u relevant=0x%08x HC IRQ cause=0x%08x\n",
1670 hc, relevant, hc_irq_cause); 1716 hc, relevant, hc_irq_cause);
1671 1717
1672 for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) { 1718 for (port = port0; port < port0 + last_port; port++) {
1673 struct ata_port *ap = host->ports[port]; 1719 struct ata_port *ap = host->ports[port];
1674 struct mv_port_priv *pp = ap->private_data; 1720 struct mv_port_priv *pp = ap->private_data;
1675 int have_err_bits, hard_port, shift; 1721 int have_err_bits, hard_port, shift;
@@ -1764,13 +1810,15 @@ static void mv_pci_error(struct ata_host *host, void __iomem *mmio)
1764static irqreturn_t mv_interrupt(int irq, void *dev_instance) 1810static irqreturn_t mv_interrupt(int irq, void *dev_instance)
1765{ 1811{
1766 struct ata_host *host = dev_instance; 1812 struct ata_host *host = dev_instance;
1813 struct mv_host_priv *hpriv = host->private_data;
1767 unsigned int hc, handled = 0, n_hcs; 1814 unsigned int hc, handled = 0, n_hcs;
1768 void __iomem *mmio = host->iomap[MV_PRIMARY_BAR]; 1815 void __iomem *mmio = hpriv->base;
1769 u32 irq_stat, irq_mask; 1816 u32 irq_stat, irq_mask;
1770 1817
1771 spin_lock(&host->lock); 1818 spin_lock(&host->lock);
1772 irq_stat = readl(mmio + HC_MAIN_IRQ_CAUSE_OFS); 1819
1773 irq_mask = readl(mmio + HC_MAIN_IRQ_MASK_OFS); 1820 irq_stat = readl(hpriv->main_cause_reg_addr);
1821 irq_mask = readl(hpriv->main_mask_reg_addr);
1774 1822
1775 /* check the cases where we either have nothing pending or have read 1823 /* check the cases where we either have nothing pending or have read
1776 * a bogus register value which can indicate HW removal or PCI fault 1824 * a bogus register value which can indicate HW removal or PCI fault
@@ -1827,7 +1875,8 @@ static unsigned int mv5_scr_offset(unsigned int sc_reg_in)
1827 1875
1828static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val) 1876static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val)
1829{ 1877{
1830 void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR]; 1878 struct mv_host_priv *hpriv = ap->host->private_data;
1879 void __iomem *mmio = hpriv->base;
1831 void __iomem *addr = mv5_phy_base(mmio, ap->port_no); 1880 void __iomem *addr = mv5_phy_base(mmio, ap->port_no);
1832 unsigned int ofs = mv5_scr_offset(sc_reg_in); 1881 unsigned int ofs = mv5_scr_offset(sc_reg_in);
1833 1882
@@ -1840,7 +1889,8 @@ static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val)
1840 1889
1841static int mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) 1890static int mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
1842{ 1891{
1843 void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR]; 1892 struct mv_host_priv *hpriv = ap->host->private_data;
1893 void __iomem *mmio = hpriv->base;
1844 void __iomem *addr = mv5_phy_base(mmio, ap->port_no); 1894 void __iomem *addr = mv5_phy_base(mmio, ap->port_no);
1845 unsigned int ofs = mv5_scr_offset(sc_reg_in); 1895 unsigned int ofs = mv5_scr_offset(sc_reg_in);
1846 1896
@@ -2178,6 +2228,93 @@ static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
2178 writel(m2, port_mmio + PHY_MODE2); 2228 writel(m2, port_mmio + PHY_MODE2);
2179} 2229}
2180 2230
2231/* TODO: use the generic LED interface to configure the SATA Presence */
2232/* & Acitivy LEDs on the board */
2233static void mv_soc_enable_leds(struct mv_host_priv *hpriv,
2234 void __iomem *mmio)
2235{
2236 return;
2237}
2238
2239static void mv_soc_read_preamp(struct mv_host_priv *hpriv, int idx,
2240 void __iomem *mmio)
2241{
2242 void __iomem *port_mmio;
2243 u32 tmp;
2244
2245 port_mmio = mv_port_base(mmio, idx);
2246 tmp = readl(port_mmio + PHY_MODE2);
2247
2248 hpriv->signal[idx].amps = tmp & 0x700; /* bits 10:8 */
2249 hpriv->signal[idx].pre = tmp & 0xe0; /* bits 7:5 */
2250}
2251
2252#undef ZERO
2253#define ZERO(reg) writel(0, port_mmio + (reg))
2254static void mv_soc_reset_hc_port(struct mv_host_priv *hpriv,
2255 void __iomem *mmio, unsigned int port)
2256{
2257 void __iomem *port_mmio = mv_port_base(mmio, port);
2258
2259 writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS);
2260
2261 mv_channel_reset(hpriv, mmio, port);
2262
2263 ZERO(0x028); /* command */
2264 writel(0x101f, port_mmio + EDMA_CFG_OFS);
2265 ZERO(0x004); /* timer */
2266 ZERO(0x008); /* irq err cause */
2267 ZERO(0x00c); /* irq err mask */
2268 ZERO(0x010); /* rq bah */
2269 ZERO(0x014); /* rq inp */
2270 ZERO(0x018); /* rq outp */
2271 ZERO(0x01c); /* respq bah */
2272 ZERO(0x024); /* respq outp */
2273 ZERO(0x020); /* respq inp */
2274 ZERO(0x02c); /* test control */
2275 writel(0xbc, port_mmio + EDMA_IORDY_TMOUT);
2276}
2277
2278#undef ZERO
2279
2280#define ZERO(reg) writel(0, hc_mmio + (reg))
2281static void mv_soc_reset_one_hc(struct mv_host_priv *hpriv,
2282 void __iomem *mmio)
2283{
2284 void __iomem *hc_mmio = mv_hc_base(mmio, 0);
2285
2286 ZERO(0x00c);
2287 ZERO(0x010);
2288 ZERO(0x014);
2289
2290}
2291
2292#undef ZERO
2293
2294static int mv_soc_reset_hc(struct mv_host_priv *hpriv,
2295 void __iomem *mmio, unsigned int n_hc)
2296{
2297 unsigned int port;
2298
2299 for (port = 0; port < hpriv->n_ports; port++)
2300 mv_soc_reset_hc_port(hpriv, mmio, port);
2301
2302 mv_soc_reset_one_hc(hpriv, mmio);
2303
2304 return 0;
2305}
2306
2307static void mv_soc_reset_flash(struct mv_host_priv *hpriv,
2308 void __iomem *mmio)
2309{
2310 return;
2311}
2312
2313static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio)
2314{
2315 return;
2316}
2317
2181static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio, 2318static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio,
2182 unsigned int port_no) 2319 unsigned int port_no)
2183{ 2320{
@@ -2342,7 +2479,7 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class,
2342{ 2479{
2343 struct ata_port *ap = link->ap; 2480 struct ata_port *ap = link->ap;
2344 struct mv_host_priv *hpriv = ap->host->private_data; 2481 struct mv_host_priv *hpriv = ap->host->private_data;
2345 void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR]; 2482 void __iomem *mmio = hpriv->base;
2346 2483
2347 mv_stop_dma(ap); 2484 mv_stop_dma(ap);
2348 2485
@@ -2383,7 +2520,7 @@ static void mv_error_handler(struct ata_port *ap)
2383 2520
2384static void mv_eh_freeze(struct ata_port *ap) 2521static void mv_eh_freeze(struct ata_port *ap)
2385{ 2522{
2386 void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR]; 2523 struct mv_host_priv *hpriv = ap->host->private_data;
2387 unsigned int hc = (ap->port_no > 3) ? 1 : 0; 2524 unsigned int hc = (ap->port_no > 3) ? 1 : 0;
2388 u32 tmp, mask; 2525 u32 tmp, mask;
2389 unsigned int shift; 2526 unsigned int shift;
@@ -2397,13 +2534,14 @@ static void mv_eh_freeze(struct ata_port *ap)
2397 mask = 0x3 << shift; 2534 mask = 0x3 << shift;
2398 2535
2399 /* disable assertion of portN err, done events */ 2536 /* disable assertion of portN err, done events */
2400 tmp = readl(mmio + HC_MAIN_IRQ_MASK_OFS); 2537 tmp = readl(hpriv->main_mask_reg_addr);
2401 writelfl(tmp & ~mask, mmio + HC_MAIN_IRQ_MASK_OFS); 2538 writelfl(tmp & ~mask, hpriv->main_mask_reg_addr);
2402} 2539}
2403 2540
2404static void mv_eh_thaw(struct ata_port *ap) 2541static void mv_eh_thaw(struct ata_port *ap)
2405{ 2542{
2406 void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR]; 2543 struct mv_host_priv *hpriv = ap->host->private_data;
2544 void __iomem *mmio = hpriv->base;
2407 unsigned int hc = (ap->port_no > 3) ? 1 : 0; 2545 unsigned int hc = (ap->port_no > 3) ? 1 : 0;
2408 void __iomem *hc_mmio = mv_hc_base(mmio, hc); 2546 void __iomem *hc_mmio = mv_hc_base(mmio, hc);
2409 void __iomem *port_mmio = mv_ap_base(ap); 2547 void __iomem *port_mmio = mv_ap_base(ap);
@@ -2430,8 +2568,8 @@ static void mv_eh_thaw(struct ata_port *ap)
2430 writel(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); 2568 writel(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
2431 2569
2432 /* enable assertion of portN err, done events */ 2570 /* enable assertion of portN err, done events */
2433 tmp = readl(mmio + HC_MAIN_IRQ_MASK_OFS); 2571 tmp = readl(hpriv->main_mask_reg_addr);
2434 writelfl(tmp | mask, mmio + HC_MAIN_IRQ_MASK_OFS); 2572 writelfl(tmp | mask, hpriv->main_mask_reg_addr);
2435} 2573}
2436 2574
2437/** 2575/**
@@ -2598,9 +2736,13 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
2598 break; 2736 break;
2599 } 2737 }
2600 break; 2738 break;
2739 case chip_soc:
2740 hpriv->ops = &mv_soc_ops;
2741 hp_flags |= MV_HP_ERRATA_60X1C0;
2742 break;
2601 2743
2602 default: 2744 default:
2603 dev_printk(KERN_ERR, &pdev->dev, 2745 dev_printk(KERN_ERR, host->dev,
2604 "BUG: invalid board index %u\n", board_idx); 2746 "BUG: invalid board index %u\n", board_idx);
2605 return 1; 2747 return 1;
2606 } 2748 }
@@ -2633,15 +2775,25 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
2633static int mv_init_host(struct ata_host *host, unsigned int board_idx) 2775static int mv_init_host(struct ata_host *host, unsigned int board_idx)
2634{ 2776{
2635 int rc = 0, n_hc, port, hc; 2777 int rc = 0, n_hc, port, hc;
2636 void __iomem *mmio = host->iomap[MV_PRIMARY_BAR];
2637 struct mv_host_priv *hpriv = host->private_data; 2778 struct mv_host_priv *hpriv = host->private_data;
2638 2779 void __iomem *mmio = hpriv->base;
2639 /* global interrupt mask */
2640 writel(0, mmio + HC_MAIN_IRQ_MASK_OFS);
2641 2780
2642 rc = mv_chip_id(host, board_idx); 2781 rc = mv_chip_id(host, board_idx);
2643 if (rc) 2782 if (rc)
2644 goto done; 2783 goto done;
2784
2785 if (HAS_PCI(host)) {
2786 hpriv->main_cause_reg_addr = hpriv->base +
2787 HC_MAIN_IRQ_CAUSE_OFS;
2788 hpriv->main_mask_reg_addr = hpriv->base + HC_MAIN_IRQ_MASK_OFS;
2789 } else {
2790 hpriv->main_cause_reg_addr = hpriv->base +
2791 HC_SOC_MAIN_IRQ_CAUSE_OFS;
2792 hpriv->main_mask_reg_addr = hpriv->base +
2793 HC_SOC_MAIN_IRQ_MASK_OFS;
2794 }
2795 /* global interrupt mask */
2796 writel(0, hpriv->main_mask_reg_addr);
2645 2797
2646 n_hc = mv_get_hc_count(host->ports[0]->flags); 2798 n_hc = mv_get_hc_count(host->ports[0]->flags);
2647 2799
@@ -2672,13 +2824,15 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
2672 for (port = 0; port < host->n_ports; port++) { 2824 for (port = 0; port < host->n_ports; port++) {
2673 struct ata_port *ap = host->ports[port]; 2825 struct ata_port *ap = host->ports[port];
2674 void __iomem *port_mmio = mv_port_base(mmio, port); 2826 void __iomem *port_mmio = mv_port_base(mmio, port);
2675 unsigned int offset = port_mmio - mmio;
2676 2827
2677 mv_port_init(&ap->ioaddr, port_mmio); 2828 mv_port_init(&ap->ioaddr, port_mmio);
2678 2829
2679#ifdef CONFIG_PCI 2830#ifdef CONFIG_PCI
2680 ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio"); 2831 if (HAS_PCI(host)) {
2681 ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port"); 2832 unsigned int offset = port_mmio - mmio;
2833 ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio");
2834 ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port");
2835 }
2682#endif 2836#endif
2683 } 2837 }
2684 2838
@@ -2694,35 +2848,141 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
2694 writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS); 2848 writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS);
2695 } 2849 }
2696 2850
2697 /* Clear any currently outstanding host interrupt conditions */ 2851 if (HAS_PCI(host)) {
2698 writelfl(0, mmio + hpriv->irq_cause_ofs); 2852 /* Clear any currently outstanding host interrupt conditions */
2853 writelfl(0, mmio + hpriv->irq_cause_ofs);
2699 2854
2700 /* and unmask interrupt generation for host regs */ 2855 /* and unmask interrupt generation for host regs */
2701 writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs); 2856 writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs);
2857 if (IS_GEN_I(hpriv))
2858 writelfl(~HC_MAIN_MASKED_IRQS_5,
2859 hpriv->main_mask_reg_addr);
2860 else
2861 writelfl(~HC_MAIN_MASKED_IRQS,
2862 hpriv->main_mask_reg_addr);
2863
2864 VPRINTK("HC MAIN IRQ cause/mask=0x%08x/0x%08x "
2865 "PCI int cause/mask=0x%08x/0x%08x\n",
2866 readl(hpriv->main_cause_reg_addr),
2867 readl(hpriv->main_mask_reg_addr),
2868 readl(mmio + hpriv->irq_cause_ofs),
2869 readl(mmio + hpriv->irq_mask_ofs));
2870 } else {
2871 writelfl(~HC_MAIN_MASKED_IRQS_SOC,
2872 hpriv->main_mask_reg_addr);
2873 VPRINTK("HC MAIN IRQ cause/mask=0x%08x/0x%08x\n",
2874 readl(hpriv->main_cause_reg_addr),
2875 readl(hpriv->main_mask_reg_addr));
2876 }
2877done:
2878 return rc;
2879}
2702 2880
2703 if (IS_GEN_I(hpriv)) 2881/**
2704 writelfl(~HC_MAIN_MASKED_IRQS_5, mmio + HC_MAIN_IRQ_MASK_OFS); 2882 * mv_platform_probe - handle a positive probe of an soc Marvell
2705 else 2883 * host
2706 writelfl(~HC_MAIN_MASKED_IRQS, mmio + HC_MAIN_IRQ_MASK_OFS); 2884 * @pdev: platform device found
2885 *
2886 * LOCKING:
2887 * Inherited from caller.
2888 */
2889static int mv_platform_probe(struct platform_device *pdev)
2890{
2891 static int printed_version;
2892 const struct mv_sata_platform_data *mv_platform_data;
2893 const struct ata_port_info *ppi[] =
2894 { &mv_port_info[chip_soc], NULL };
2895 struct ata_host *host;
2896 struct mv_host_priv *hpriv;
2897 struct resource *res;
2898 int n_ports, rc;
2707 2899
2708 VPRINTK("HC MAIN IRQ cause/mask=0x%08x/0x%08x " 2900 if (!printed_version++)
2709 "PCI int cause/mask=0x%08x/0x%08x\n", 2901 dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
2710 readl(mmio + HC_MAIN_IRQ_CAUSE_OFS),
2711 readl(mmio + HC_MAIN_IRQ_MASK_OFS),
2712 readl(mmio + hpriv->irq_cause_ofs),
2713 readl(mmio + hpriv->irq_mask_ofs));
2714 2902
2715done: 2903 /*
2716 return rc; 2904 * Simple resource validation ..
2905 */
2906 if (unlikely(pdev->num_resources != 2)) {
2907 dev_err(&pdev->dev, "invalid number of resources\n");
2908 return -EINVAL;
2909 }
2910
2911 /*
2912 * Get the register base first
2913 */
2914 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2915 if (res == NULL)
2916 return -EINVAL;
2917
2918 /* allocate host */
2919 mv_platform_data = pdev->dev.platform_data;
2920 n_ports = mv_platform_data->n_ports;
2921
2922 host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
2923 hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
2924
2925 if (!host || !hpriv)
2926 return -ENOMEM;
2927 host->private_data = hpriv;
2928 hpriv->n_ports = n_ports;
2929
2930 host->iomap = NULL;
2931 hpriv->base = ioremap(res->start, res->end - res->start + 1);
2932 hpriv->base -= MV_SATAHC0_REG_BASE;
2933
2934 /* initialize adapter */
2935 rc = mv_init_host(host, chip_soc);
2936 if (rc)
2937 return rc;
2938
2939 dev_printk(KERN_INFO, &pdev->dev,
2940 "slots %u ports %d\n", (unsigned)MV_MAX_Q_DEPTH,
2941 host->n_ports);
2942
2943 return ata_host_activate(host, platform_get_irq(pdev, 0), mv_interrupt,
2944 IRQF_SHARED, &mv6_sht);
2945}
2946
2947/*
2948 *
2949 * mv_platform_remove - unplug a platform interface
2950 * @pdev: platform device
2951 *
2952 * A platform bus SATA device has been unplugged. Perform the needed
2953 * cleanup. Also called on module unload for any active devices.
2954 */
2955static int __devexit mv_platform_remove(struct platform_device *pdev)
2956{
2957 struct device *dev = &pdev->dev;
2958 struct ata_host *host = dev_get_drvdata(dev);
2959 struct mv_host_priv *hpriv = host->private_data;
2960 void __iomem *base = hpriv->base;
2961
2962 ata_host_detach(host);
2963 iounmap(base);
2964 return 0;
2717} 2965}
2718 2966
2967static struct platform_driver mv_platform_driver = {
2968 .probe = mv_platform_probe,
2969 .remove = __devexit_p(mv_platform_remove),
2970 .driver = {
2971 .name = DRV_NAME,
2972 .owner = THIS_MODULE,
2973 },
2974};
2975
2976
2719#ifdef CONFIG_PCI 2977#ifdef CONFIG_PCI
2720static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); 2978static int mv_pci_init_one(struct pci_dev *pdev,
2979 const struct pci_device_id *ent);
2980
2721 2981
2722static struct pci_driver mv_pci_driver = { 2982static struct pci_driver mv_pci_driver = {
2723 .name = DRV_NAME, 2983 .name = DRV_NAME,
2724 .id_table = mv_pci_tbl, 2984 .id_table = mv_pci_tbl,
2725 .probe = mv_init_one, 2985 .probe = mv_pci_init_one,
2726 .remove = ata_pci_remove_one, 2986 .remove = ata_pci_remove_one,
2727}; 2987};
2728 2988
@@ -2828,14 +3088,15 @@ static int mv_create_dma_pools(struct mv_host_priv *hpriv, struct device *dev)
2828} 3088}
2829 3089
2830/** 3090/**
2831 * mv_init_one - handle a positive probe of a Marvell host 3091 * mv_pci_init_one - handle a positive probe of a PCI Marvell host
2832 * @pdev: PCI device found 3092 * @pdev: PCI device found
2833 * @ent: PCI device ID entry for the matched host 3093 * @ent: PCI device ID entry for the matched host
2834 * 3094 *
2835 * LOCKING: 3095 * LOCKING:
2836 * Inherited from caller. 3096 * Inherited from caller.
2837 */ 3097 */
2838static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) 3098static int mv_pci_init_one(struct pci_dev *pdev,
3099 const struct pci_device_id *ent)
2839{ 3100{
2840 static int printed_version; 3101 static int printed_version;
2841 unsigned int board_idx = (unsigned int)ent->driver_data; 3102 unsigned int board_idx = (unsigned int)ent->driver_data;
@@ -2855,6 +3116,7 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2855 if (!host || !hpriv) 3116 if (!host || !hpriv)
2856 return -ENOMEM; 3117 return -ENOMEM;
2857 host->private_data = hpriv; 3118 host->private_data = hpriv;
3119 hpriv->n_ports = n_ports;
2858 3120
2859 /* acquire resources */ 3121 /* acquire resources */
2860 rc = pcim_enable_device(pdev); 3122 rc = pcim_enable_device(pdev);
@@ -2867,6 +3129,7 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2867 if (rc) 3129 if (rc)
2868 return rc; 3130 return rc;
2869 host->iomap = pcim_iomap_table(pdev); 3131 host->iomap = pcim_iomap_table(pdev);
3132 hpriv->base = host->iomap[MV_PRIMARY_BAR];
2870 3133
2871 rc = pci_go_64(pdev); 3134 rc = pci_go_64(pdev);
2872 if (rc) 3135 if (rc)
@@ -2895,11 +3158,22 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2895} 3158}
2896#endif 3159#endif
2897 3160
3161static int mv_platform_probe(struct platform_device *pdev);
3162static int __devexit mv_platform_remove(struct platform_device *pdev);
3163
2898static int __init mv_init(void) 3164static int __init mv_init(void)
2899{ 3165{
2900 int rc = -ENODEV; 3166 int rc = -ENODEV;
2901#ifdef CONFIG_PCI 3167#ifdef CONFIG_PCI
2902 rc = pci_register_driver(&mv_pci_driver); 3168 rc = pci_register_driver(&mv_pci_driver);
3169 if (rc < 0)
3170 return rc;
3171#endif
3172 rc = platform_driver_register(&mv_platform_driver);
3173
3174#ifdef CONFIG_PCI
3175 if (rc < 0)
3176 pci_unregister_driver(&mv_pci_driver);
2903#endif 3177#endif
2904 return rc; 3178 return rc;
2905} 3179}
@@ -2909,6 +3183,7 @@ static void __exit mv_exit(void)
2909#ifdef CONFIG_PCI 3183#ifdef CONFIG_PCI
2910 pci_unregister_driver(&mv_pci_driver); 3184 pci_unregister_driver(&mv_pci_driver);
2911#endif 3185#endif
3186 platform_driver_unregister(&mv_platform_driver);
2912} 3187}
2913 3188
2914MODULE_AUTHOR("Brett Russ"); 3189MODULE_AUTHOR("Brett Russ");
diff --git a/include/linux/ata_platform.h b/include/linux/ata_platform.h
index 6a7a92db294c..b856a2a590d9 100644
--- a/include/linux/ata_platform.h
+++ b/include/linux/ata_platform.h
@@ -1,5 +1,5 @@
1#ifndef __LINUX_PATA_PLATFORM_H 1#ifndef __LINUX_ATA_PLATFORM_H
2#define __LINUX_PATA_PLATFORM_H 2#define __LINUX_ATA_PLATFORM_H
3 3
4struct pata_platform_info { 4struct pata_platform_info {
5 /* 5 /*
@@ -24,4 +24,11 @@ extern int __devinit __pata_platform_probe(struct device *dev,
24 24
25extern int __devexit __pata_platform_remove(struct device *dev); 25extern int __devexit __pata_platform_remove(struct device *dev);
26 26
27#endif /* __LINUX_PATA_PLATFORM_H */ 27/*
28 * Marvell SATA private data
29 */
30struct mv_sata_platform_data {
31 int n_ports; /* number of sata ports */
32};
33
34#endif /* __LINUX_ATA_PLATFORM_H */