0

I'm trying^W failing to get a kernel module to respond to a DMA-done interrupt. I've been reading around for help, but most of what I can find is to do with GPIO interrupt management, and I think my problem is trying to figure out how to get the interrupt number. For GPIOs, there's a built-in function for that...

Here's what I have:

I define the driver structure, so I can get the 'probe' function, which I thought I needed to get the platform_device* pointer, which in turn is what I needed to get access to the irq to pass into request_irq()

/****************************************************************************\
|* Driver declaration
\****************************************************************************/
static struct platform_driver xpiDriver = 
    {
    .driver = 
        {
        .name   = XPI_PLATFORM_DEV_NAME,
        .owner  = THIS_MODULE,
        },
    .probe      = deviceProbe,
    .remove     = deviceRemove,
    };

deviceRemove() just returns 0, deviceProbe looks like

/****************************************************************************\
|* Called on module probe
\****************************************************************************/
static int deviceProbe(struct platform_device *pdev)
    {
    _state.irq = platform_get_irq(pdev, 0);
    if (_state.irq < 0) 
        {
        dev_err(&pdev->dev, "could not get IRQ\n");
        return _state.irq;
        }
        
    printk(KERN_INFO "xpi: irq=%d\n",_state.irq);
    
    int ret = request_irq(_state.irq, 
                          dmaIrqHandler, 
                          0,
                          "xpi",
                          NULL);
    printk(KERN_INFO "xpi: ret=%d\n",ret);
    return 0;
    }

I also defined the device, thus

/****************************************************************************\
|* Device declaration
\****************************************************************************/
static struct resource xpi_resources[] = 
    {
        {
        .start  = IRQ_DMA,
        .end    = IRQ_DMA,
        .flags  = IORESOURCE_IRQ,
        .name   = XPI_PLATFORM_DEV_NAME,
        }
    };

static struct platform_device xpi_device = 
    {
    .name           = XPI_PLATFORM_DEV_NAME,
    .resource       = xpi_resources,
    .num_resources  = ARRAY_SIZE(xpi_resources),
    };

... where IRQ_DMA is defined as 21, from looking at the Pi4 data sheet (pg 85, DMA 5)

The module bootstraps by calling

/****************************************************************************\
|* Called on module load
\****************************************************************************/
static int __init xpi_init(void)
    {
    /************************************************************************\
    |* Register the driver
    \************************************************************************/
    int error = platform_driver_register(&xpiDriver);
    
    if (error != 0)
        {
        printk(KERN_ERR "Platform driver error %d\n", error);
        return error;
        }

    /************************************************************************\
    |* Register the device
    \************************************************************************/
    error = platform_device_register(&xpi_device);
    ...

But I'm getting an exception (and a whole bunch of stack trace) which traces back to the call to platform_device_register() which calls into deviceProbe() above and then I get:

[  111.375941] xpi: loading out-of-tree module taints kernel.
[  111.377528] xpi: irq=21
[  111.377545] ------------[ cut here ]------------
[  111.377582] WARNING: CPU: 3 PID: 1406 at kernel/irq/manage.c:2034 request_threaded_irq+0x144/0x160
[  111.377596] Modules linked in: xpi(O+) rfcomm bnep hci_uart btbcm bluetooth ecdh_generic ecc fuse 8021q garp stp llc joydev rpivid_mem vc4 cec v3d drm_kms_helper gpu_sched brcmfmac brcmutil sha256_generic libsha256 drm raspberrypi_hwmon drm_panel_orientation_quirks cfg80211 rfkill bcm2835_codec(C) hid_apple bcm2835_v4l2(C) snd_soc_core bcm2835_isp(C) v4l2_mem2mem snd_bcm2835(C) bcm2835_mmal_vchiq(C) snd_compress videobuf2_dma_contig videobuf2_vmalloc snd_pcm_dmaengine videobuf2_memops videobuf2_v4l2 videobuf2_common snd_pcm snd_timer videodev snd mc syscopyarea sysfillrect vc_sm_cma(C) sysimgblt fb_sys_fops uio_pdrv_genirq uio i2c_dev ip_tables x_tables ipv6
[  111.377861] CPU: 3 PID: 1406 Comm: insmod Tainted: G         C O      5.4.72-v7l+ #1356
[  111.377869] Hardware name: BCM2711
[  111.377879] Backtrace: 
[  111.377903] [<c020e1c8>] (dump_backtrace) from [<c020e544>] (show_stack+0x20/0x24)
[  111.377916]  r7:ffffffff r6:00000000 r5:60000013 r4:c12a1130
[  111.377938] [<c020e524>] (show_stack) from [<c0a84cb0>] (dump_stack+0xd4/0x118)
[  111.377955] [<c0a84bdc>] (dump_stack) from [<c0222424>] (__warn+0xe0/0x108)
[  111.377967]  r10:bf26b498 r9:00000000 r8:00000009 r7:000007f2 r6:c02870d4 r5:00000009
[  111.377976]  r4:c0dc8f14 r3:00000000
[  111.377990] [<c0222344>] (__warn) from [<c02227f0>] (warn_slowpath_fmt+0x74/0xd0)
[  111.378001]  r7:c02870d4 r6:000007f2 r5:c0dc8f14 r4:00000000
[  111.378017] [<c0222780>] (warn_slowpath_fmt) from [<c02870d4>] (request_threaded_irq+0x144/0x160)
[  111.378028]  r8:00000015 r7:c13636bc r6:ef867000 r5:ffffffea r4:bf26d500
[  111.378056] [<c0286f90>] (request_threaded_irq) from [<bf26b118>] (deviceProbe+0x98/0xb0 [xpi])
[  111.378069]  r10:0000002a r9:bf26d014 r8:00000000 r7:c13636bc r6:bf26d014 r5:00000000
[  111.378078]  r4:bf26d500 r3:00000000
[  111.378102] [<bf26b080>] (deviceProbe [xpi]) from [<c07a0964>] (platform_drv_probe+0x58/0xa8)
[  111.378111]  r5:bf26d078 r4:00000000
...
[  111.378626] xpi: ret=-22
[  111.378821] xpi: CPU identified as 3
[  111.379329] xpi: xpi device obtained (234:0)

-22 is EINVAL, so presumably I'm missing something. Anyone want to be nice enough to point out what ?

Cheers :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.