From: Paul M. <le...@li...> - 2007-11-07 03:06:44
|
On Wed, Nov 07, 2007 at 11:38:42AM +0900, Magnus Damm wrote: > On Nov 7, 2007 8:49 AM, Paul Mundt <le...@li...> wrote: > > On Tue, Nov 06, 2007 at 08:43:16PM +0900, Magnus Damm wrote: > > > I happen to have two of these R2D-1 boards and I can't get CF working > > > using the latest kernel (latest sh-2.6 git, post 2.6.24-rc1) : > > > > > > ... > > > irq 107: nobody cared (try booting with the "irqpoll" option) > > > [stack dump] > > > [call trace] > > > handlers: > > > [<8c24f660>] (ata_interrupt+0x0/0x240) > > > Disabling IRQ #107 > > > ... > > > > > Did R2D-1 CF work for you with IRQs prior to this change? And does > > reverting it fix get R2D-1 CF working again? The nobody cared thing is > > curious, if you can provide the stack dump/call trace and register state > > it might shed some light on why ata_interrupt isn't handling it. > > The CF for R2D-1 was disabled without this patch - mainly because I > had trouble trying to use it. I thought it had something to do with > the access size and this patch would solve it, but apparently not. I > wonder if CF support in 2.6.24-rc2 works on R2D-1 for other people... > The access size problem causes a bus lock, so that's still a problem, even if IRQs are hosed. > I'm guessing that something is wrong with trigger level. The R2D-1 > documentation does say something about the CF IDE interrupt level to > be H while the rest of the sources are L what ever that means. I don't > think we can control it in the FPGA either. > That suggestions that R2D-1 is using level high. It's possible to set the sense selection on this already at request_irq() time, blackfin ended up having to do this, and so added the ability to pass on IRQ flags via private data. See pata_platform_info->irq_flags in linux/pata_platform.h. I suppose we should be setting the sense selection level high for all of the R2D boards, in that case. > > > I can get things working by hacking in code to enable polling in > > > pata_platform.c though, so I assume that the IO-ports are ok. > > > > > It might be worthwhile making the polling configurable, if you want to > > tidy up a patch for that we can see if it's something work abstracting. > > It's handy for debugging, at least. > > The generic ata code needed an IRQ last time i checked. Otherwise i'd > prefer to not set the interrupt in the platform data to enable > polling. In the end the only thing required is this (mangled patch > hunk): > That's easy enough to fix. How about this? --- drivers/ata/libata-core.c | 7 +++++++ drivers/ata/pata_platform.c | 26 ++++++++++++++++++++------ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index ec3ce12..a0cd6bb 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -7178,6 +7178,9 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) * request IRQ and register it. This helper takes necessasry * arguments and performs the three steps in one go. * + * A NULL @irq_handler or invalid IRQ skips the IRQ registration + * and expects the host to have set polling mode on the port. + * * LOCKING: * Inherited from calling layer (may sleep). * @@ -7194,6 +7197,10 @@ int ata_host_activate(struct ata_host *host, int irq, if (rc) return rc; + /* Special case for polling mode */ + if (!irq_handler || irq < 0) + return ata_host_register(host, sht); + rc = devm_request_irq(host->dev, irq, irq_handler, irq_flags, dev_driver_string(host->dev), host); if (rc) diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c index fc72a96..1d712ec 100644 --- a/drivers/ata/pata_platform.c +++ b/drivers/ata/pata_platform.c @@ -1,7 +1,7 @@ /* * Generic platform device PATA driver * - * Copyright (C) 2006 Paul Mundt + * Copyright (C) 2006 - 2007 Paul Mundt * * Based on pata_pcmcia: * @@ -22,7 +22,7 @@ #include <linux/pata_platform.h> #define DRV_NAME "pata_platform" -#define DRV_VERSION "1.1" +#define DRV_VERSION "1.2" static int pio_mask = 1; @@ -137,11 +137,12 @@ static int __devinit pata_platform_probe(struct platform_device *pdev) struct ata_port *ap; struct pata_platform_info *pp_info; unsigned int mmio; + int irq; /* * Simple resource validation .. */ - if (unlikely(pdev->num_resources != 3)) { + if ((pdev->num_resources != 3) && (pdev->num_resources != 2)) { dev_err(&pdev->dev, "invalid number of resources\n"); return -EINVAL; } @@ -173,6 +174,11 @@ static int __devinit pata_platform_probe(struct platform_device *pdev) (ctl_res->flags == IORESOURCE_MEM)); /* + * And the IRQ + */ + irq = platform_get_irq(pdev, 0); + + /* * Now that that's out of the way, wire up the port.. */ host = ata_host_alloc(&pdev->dev, 1); @@ -185,6 +191,14 @@ static int __devinit pata_platform_probe(struct platform_device *pdev) ap->flags |= ATA_FLAG_SLAVE_POSS; /* + * Use polling mode if there's no IRQ + */ + if (irq < 0) { + ap->flags |= ATA_FLAG_PIO_POLLING; + ata_port_desc(ap, "no IRQ, using PIO polling"); + } + + /* * Handle the MMIO case */ if (mmio) { @@ -213,9 +227,9 @@ static int __devinit pata_platform_probe(struct platform_device *pdev) (unsigned long long)ctl_res->start); /* activate */ - return ata_host_activate(host, platform_get_irq(pdev, 0), - ata_interrupt, pp_info ? pp_info->irq_flags - : 0, &pata_platform_sht); + return ata_host_activate(host, irq, ata_interrupt, + pp_info ? pp_info->irq_flags : 0, + &pata_platform_sht); } /** |