From: Frans Pop <elendil@planet.nl>
To: linux-arm@vger.kernel.org
Cc: Mark Lord <liml@rtr.ca>,
linux-ide@vger.kernel.org, Saeed Bishara <saeed@marvell.com>,
Nicolas Pitre <nico@cam.org>,
Lennert Buytenhek <buytenh@wantstofly.org>
Subject: [PATCH,v2][1/2] sata-mv: enable HDD led blinking when NCQ is active for GenIIe
Date: Wed, 11 Mar 2009 08:15:51 +0100 [thread overview]
Message-ID: <200903110815.52650.elendil@planet.nl> (raw)
In-Reply-To: <200903110813.25650.elendil@planet.nl>
For some Marvell chips the HDD led does not blink when there is
disk I/O if NCQ is enabled. Add a quirk that enables blink mode for
the led when NCQ is used on any of the ports of a host controller.
The code to enable the blink mode is based on an earlier patch
proposed by Saeed Bishara.
Signed-off-by: Frans Pop <elendil@planet.nl>
Cc: Mark Lord <liml@rtr.ca>
Cc: Saeed Bishara <saeed.bishara@gmail.com>
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 7007edd..4057647 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -205,6 +205,11 @@ enum {
HC_COAL_IRQ = (1 << 4), /* IRQ coalescing */
DEV_IRQ = (1 << 8), /* shift by port # */
+ IIE_LED_CTRL_OFS = 0x2c,
+ IIE_LED_CTRL_BLINK = (1 << 0), /* Active LED blink */
+ IIE_LED_CTRL_ACT_PRESENCE = (1 << 2), /* Multiplex presence with */
+ /* the active LED */
+
/* Shadow block registers */
SHD_BLK_OFS = 0x100,
SHD_CTL_AST_OFS = 0x20, /* ofs from SHD_BLK_OFS */
@@ -359,6 +364,8 @@ enum {
MV_HP_PCIE = (1 << 9), /* PCIe bus/regs: 7042 */
MV_HP_CUT_THROUGH = (1 << 10), /* can use EDMA cut-through */
MV_HP_FLAG_SOC = (1 << 11), /* SystemOnChip, no PCI */
+ MV_HP_NCQ_LED_QUIRK = (1 << 12),
+ MV_HP_LED_BL_EN = (1 << 13), /* is led blinking enabled? */
/* Port private flags (pp_flags) */
MV_PP_FLAG_EDMA_EN = (1 << 0), /* is EDMA engine enabled? */
@@ -480,11 +487,19 @@ struct mv_hw_ops {
unsigned int port);
void (*enable_leds)(struct mv_host_priv *hpriv, void __iomem *mmio);
void (*read_preamp)(struct mv_host_priv *hpriv, int idx,
- void __iomem *mmio);
+ void __iomem *mmio);
int (*reset_hc)(struct mv_host_priv *hpriv, void __iomem *mmio,
unsigned int n_hc);
void (*reset_flash)(struct mv_host_priv *hpriv, void __iomem *mmio);
void (*reset_bus)(struct ata_host *host, void __iomem *mmio);
+ void (*enable_led_blink)(struct mv_host_priv *hpriv,
+ void __iomem *mmio, int enable_blink);
+
+ /*
+ * ->inherits must be the last field and all the preceding
+ * fields must be pointers.
+ */
+ const struct mv_hw_ops *inherits;
};
static int mv_scr_read(struct ata_link *link, unsigned int sc_reg_in, u32 *val);
@@ -530,6 +545,8 @@ static int mv_soc_reset_hc(struct mv_host_priv *hpriv,
static void mv_soc_reset_flash(struct mv_host_priv *hpriv,
void __iomem *mmio);
static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio);
+static void mv_iie_enable_led_blink(struct mv_host_priv *hpriv,
+ void __iomem *mmio, int enable_blink);
static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio);
static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
unsigned int port_no);
@@ -705,6 +722,11 @@ static const struct mv_hw_ops mv6xxx_ops = {
.reset_bus = mv_reset_pci_bus,
};
+static const struct mv_hw_ops mv6xxx_iie_ops = {
+ .inherits = &mv6xxx_ops,
+ .enable_led_blink = mv_iie_enable_led_blink,
+};
+
static const struct mv_hw_ops mv_soc_ops = {
.phy_errata = mv6_phy_errata,
.enable_leds = mv_soc_enable_leds,
@@ -712,6 +734,7 @@ static const struct mv_hw_ops mv_soc_ops = {
.reset_hc = mv_soc_reset_hc,
.reset_flash = mv_soc_reset_flash,
.reset_bus = mv_soc_reset_bus,
+ .enable_led_blink = mv_iie_enable_led_blink,
};
/*
@@ -852,6 +875,55 @@ static void mv_enable_port_irqs(struct ata_port *ap,
mv_set_main_irq_mask(ap->host, disable_bits, enable_bits);
}
+static int mv_has_port_using_ncq(struct ata_host *host)
+{
+ int port;
+ struct mv_host_priv *hpriv = host->private_data;
+
+ for (port = 0; port < hpriv->n_ports; port++) {
+ struct ata_port *ap = host->ports[port];
+ struct mv_port_priv *pp = ap->private_data;
+
+ if ((pp->pp_flags & MV_PP_FLAG_EDMA_EN) &&
+ (pp->pp_flags & MV_PP_FLAG_NCQ_EN))
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * Some chips have an erratum which causes the HDD led not to blink
+ * during I/O when NCQ is enabled. Enabling the blink mode of the
+ * led makes activity visible in that case.
+ */
+static void mv_quirk_blink_led_when_ncq(struct ata_port *ap,
+ int enable)
+{
+ struct mv_host_priv *hpriv = ap->host->private_data;
+ void __iomem *mmio = hpriv->base;
+
+ if (!hpriv->ops->enable_led_blink)
+ return;
+
+ if (enable) {
+ if (!(hpriv->hp_flags & MV_HP_LED_BL_EN)) {
+ hpriv->ops->enable_led_blink(hpriv, mmio, true);
+ hpriv->hp_flags |= MV_HP_LED_BL_EN;
+ }
+ return;
+ } else {
+ if (!(hpriv->hp_flags & MV_HP_LED_BL_EN))
+ return;
+ }
+
+ /* Does any other port still use NCQ? */
+ if (!mv_has_port_using_ncq(ap->host)) {
+ hpriv->ops->enable_led_blink(hpriv, mmio, false);
+ hpriv->hp_flags &= ~MV_HP_LED_BL_EN;
+ }
+}
+
/**
* mv_start_dma - Enable eDMA engine
* @base: port base address
@@ -952,6 +1024,7 @@ static int mv_stop_edma(struct ata_port *ap)
{
void __iomem *port_mmio = mv_ap_base(ap);
struct mv_port_priv *pp = ap->private_data;
+ struct mv_host_priv *hpriv = ap->host->private_data;
if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN))
return 0;
@@ -961,6 +1034,10 @@ static int mv_stop_edma(struct ata_port *ap)
ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n");
return -EIO;
}
+
+ if (hpriv->hp_flags & MV_HP_NCQ_LED_QUIRK)
+ mv_quirk_blink_led_when_ncq(ap, false);
+
return 0;
}
@@ -1222,6 +1299,9 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
}
if (want_ncq) {
+ if (hpriv->hp_flags & MV_HP_NCQ_LED_QUIRK)
+ mv_quirk_blink_led_when_ncq(ap, true);
+
cfg |= EDMA_CFG_NCQ;
pp->pp_flags |= MV_PP_FLAG_NCQ_EN;
} else
@@ -2690,6 +2770,19 @@ static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio)
return;
}
+static void mv_iie_enable_led_blink(struct mv_host_priv *hpriv,
+ void __iomem *mmio, int enable_blink)
+{
+ void __iomem *hc_mmio = mv_hc_base(mmio, 0);
+ u32 tmp = readl(hc_mmio + IIE_LED_CTRL_OFS);
+
+ /* enable/disable blinking mode */
+ if (enable_blink)
+ writel(tmp | IIE_LED_CTRL_BLINK, hc_mmio + IIE_LED_CTRL_OFS);
+ else
+ writel(tmp & ~IIE_LED_CTRL_BLINK, hc_mmio + IIE_LED_CTRL_OFS);
+}
+
static void mv_setup_ifcfg(void __iomem *port_mmio, int want_gen2i)
{
u32 ifcfg = readl(port_mmio + SATA_INTERFACE_CFG_OFS);
@@ -2997,8 +3090,8 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
}
/* drop through */
case chip_6042:
- hpriv->ops = &mv6xxx_ops;
- hp_flags |= MV_HP_GEN_IIE;
+ hpriv->ops = &mv6xxx_iie_ops;
+ hp_flags |= MV_HP_GEN_IIE | MV_HP_NCQ_LED_QUIRK;
if (board_idx == chip_6042 && mv_pci_cut_through_okay(host))
hp_flags |= MV_HP_CUT_THROUGH;
@@ -3016,7 +3109,7 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
case chip_soc:
hpriv->ops = &mv_soc_ops;
hp_flags |= MV_HP_FLAG_SOC | MV_HP_GEN_IIE |
- MV_HP_ERRATA_60X1C0;
+ MV_HP_ERRATA_60X1C0 | MV_HP_NCQ_LED_QUIRK;
break;
default:
next prev parent reply other threads:[~2009-03-11 7:15 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-11 7:13 [PATCH,v2][0/2] sata_mv: harddisk activity led no longer responsive on QNAP TS-109 Frans Pop
2009-03-11 7:15 ` Frans Pop [this message]
2009-03-11 12:47 ` [PATCH,v2][1/2] sata-mv: enable HDD led blinking when NCQ is active for GenIIe Mark Lord
2009-03-11 13:08 ` Frans Pop
2009-03-11 14:15 ` Mark Lord
2009-03-12 11:40 ` Frans Pop
2009-03-12 14:14 ` Mark Lord
2009-03-12 14:15 ` Mark Lord
2009-03-12 14:26 ` Mark Lord
2009-03-13 8:07 ` Frans Pop
2009-03-13 13:04 ` Mark Lord
2009-03-13 18:19 ` Frans Pop
2009-03-13 19:09 ` Mark Lord
2009-03-14 11:57 ` Frans Pop
2009-03-14 14:53 ` Mark Lord
2009-03-15 10:18 ` Frans Pop
2009-03-12 14:27 ` Frans Pop
2009-03-12 14:31 ` Mark Lord
2009-03-11 7:17 ` [PATCH,v2][2/2] sata-mv: add module parameter msq_blink_led to enable quirk " Frans Pop
2009-03-11 12:33 ` [PATCH,v2][0/2] sata_mv: harddisk activity led no longer responsive on QNAP TS-109 Mark Lord
2009-03-11 12:58 ` Mark Lord
2009-03-11 13:01 ` Frans Pop
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200903110815.52650.elendil@planet.nl \
--to=elendil@planet.nl \
--cc=buytenh@wantstofly.org \
--cc=liml@rtr.ca \
--cc=linux-arm@vger.kernel.org \
--cc=linux-ide@vger.kernel.org \
--cc=nico@cam.org \
--cc=saeed@marvell.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).