[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <f7910e810904261606g6f946f87wb45e3c356cf7999d@mail.gmail.com>
Date: Sun, 26 Apr 2009 19:06:45 -0400
From: John Woods <johnrw@...il.com>
To: Krzysztof Halasa <khc@...waw.pl>
Cc: Benoit LIETAER <blietaer@...e.fr>,
lkml <linux-kernel@...r.kernel.org>, netdev@...r.kernel.org
Subject: Re: IXP42x rev. A0 support for network devices
On Sun, Apr 26, 2009 at 5:58 PM, Krzysztof Halasa <khc@...waw.pl> wrote:
> Hi,
>
> well, I finally found that old prototype board with IXP425 rev A0 and
> I was even able to implant some modern RedBoot to it, so I gave it
> a try.
>
> It seems that a list of rev. A0 bugs (or "bugs") isn't that long after
> all (those affecting Ethernet at least). Basically the QMgr IRQ status
> is unreliable, and the undocumented "feature" register is write-only.
>
> This patch is a bit of handcraft but it applies to 2.6.29 and
> probably to older kernels.
> Benoit, John, please let me know if it works or not. Thanks.
> --
> Krzysztof Halasa
>
> --- a/arch/arm/mach-ixp4xx/include/mach/cpu.h
> +++ b/arch/arm/mach-ixp4xx/include/mach/cpu.h
> @@ -26,6 +26,8 @@
> #define IXP46X_PROCESSOR_ID_VALUE 0x69054200
> #define IXP46X_PROCESSOR_ID_MASK 0xfffffff0
>
> +#define cpu_is_ixp42x_rev_a0() ((read_cpuid_id() & (IXP4XX_PROCESSOR_ID_MASK | 0xF)) == \
> + IXP42X_PROCESSOR_ID_VALUE)
> #define cpu_is_ixp42x() ((read_cpuid_id() & IXP4XX_PROCESSOR_ID_MASK) == \
> IXP42X_PROCESSOR_ID_VALUE)
> #define cpu_is_ixp43x() ((read_cpuid_id() & IXP43X_PROCESSOR_ID_MASK) == \
> @@ -35,6 +35,9 @@
> {
> unsigned int val = ~*IXP4XX_EXP_CFG2;
> val &= ~IXP4XX_FEATURE_RESERVED;
> + if (cpu_is_ixp42x_rev_a0())
> + return ~IXP4XX_FEATURE_IXP46X_ONLY & ~(IXP4XX_FEATURE_RCOMP |
> + IXP4XX_FEATURE_AES);
> if (!cpu_is_ixp46x())
> val &= ~IXP4XX_FEATURE_IXP46X_ONLY;
>
> --- a/arch/arm/mach-ixp4xx/ixp4xx_npe.c
> +++ b/arch/arm/mach-ixp4xx/ixp4xx_npe.c
> @@ -386,15 +386,6 @@ static int npe_reset(struct npe *npe)
> /* reset the NPE */
> ixp4xx_write_feature_bits(val &
> ~(IXP4XX_FEATURE_RESET_NPEA << npe->id));
> - for (i = 0; i < MAX_RETRIES; i++) {
> - if (!(ixp4xx_read_feature_bits() &
> - (IXP4XX_FEATURE_RESET_NPEA << npe->id)))
> - break; /* reset completed */
> - udelay(1);
> - }
> - if (i == MAX_RETRIES)
> - return -ETIMEDOUT;
> -
> /* deassert reset */
> ixp4xx_write_feature_bits(val |
> (IXP4XX_FEATURE_RESET_NPEA << npe->id));
> --- a/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
> +++ b/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
> @@ -41,6 +41,31 @@ void qmgr_set_irq(unsigned int queue, int src,
> }
>
>
> +static irqreturn_t qmgr_irq1_a0(int irq, void *pdev)
> +{
> + int i, ret = 0;
> +
> + /* ACK - it may also clear newly requested irqs so don't rely on it */
> + __raw_writel(__raw_readl(&qmgr_regs->irqstat[0]),
> + &qmgr_regs->irqstat[0]);
> +
> + for (i = 0; i < HALF_QUEUES; i++) {
> + u32 src, stat;
> + if (!(qmgr_regs->irqen[0] & BIT(i)))
> + continue;
> + src = qmgr_regs->irqsrc[i >> 3];
> + stat = qmgr_regs->stat1[i >> 3];
> + if (src & 4) /* the IRQ condition is inverted */
> + stat = ~stat;
> + if (stat & BIT(src & 3)) {
> + irq_handlers[i](irq_pdevs[i]);
> + ret = IRQ_HANDLED;
> + }
> + }
> + return ret;
> +}
> +
> +
> static irqreturn_t qmgr_irq1(int irq, void *pdev)
> {
> int i;
> @@ -250,8 +275,8 @@ static int qmgr_init(void)
> for (i = 0; i < QUEUES; i++)
> __raw_writel(0, &qmgr_regs->sram[i]);
>
> - err = request_irq(IRQ_IXP4XX_QM1, qmgr_irq1, 0,
> - "IXP4xx Queue Manager", NULL);
> + err = request_irq(IRQ_IXP4XX_QM1, cpu_is_ixp42x_rev_a0() ? qmgr_irq1_a0
> + : qmgr_irq1, 0, "IXP4xx Queue Manager", NULL);
> if (err) {
> printk(KERN_ERR "qmgr: failed to request IRQ%i\n",
> IRQ_IXP4XX_QM1);
>
Hi Krzysztof,
I should be able to test it, in a day.
Thank You!
John Woods
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists