Where can I load a GPIO module at the earliest?

0

I wrote a kernel module which works as expected. But I want that to be loaded at the beginning of the boot process. So I moved this code to

OpenWRT/build_dir/target-i386_geode_eglibc-2.19/linux-x86_alix2/linux-3.10.49/arch/x86/platform

and my code is here:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/cs5535.h>

MODULE_AUTHOR("Ramana");
MODULE_DESCRIPTION("POWER LED DRIVER");

#ifdef MODULE_LICENSE
MODULE_LICENSE("Dual BSD/GPL");
#endif

#define HW_VERSION_GPIO 15

#define LATCH_GPIO      6
#define DATA_GPIO       25
#define CLOCK_GPIO      27

#define HIGH            1
#define LOW             0



static void set_power_led(void)
{
    uint8_t i = 0;

    /*
    * Configure Pins Q8 Q7 Q6....Q0 in shift register
    * Set 0 to glow LED
    *
    * shift_reg:
    * indices 0, 1 and 2 are for LED3
    *   0 1 1 -> Blue_ON, GREEN_OFF, RED_OFF
    *
    * indices 3, 4 and 5 are for LED1
    *
    * indices 6, 7 and 8 are for LED2
    *   0 1 1 -> Blue_ON, GREEN_OFF, RED_OFF
    *
    * The pins Q9 Q10 and Q11 are don't care, so we are not using here
    */

    uint8_t shift_reg[9] = {0, 1, 1, 1, 1, 1, 1, 1, 1};

    /*
     * Clear register before set
     */

    for (i = 0; i < 9 ; i ++) {
    gpio_set_value(CLOCK_GPIO, LOW);

    if (shift_reg[i] == 0) {
        gpio_set_value(DATA_GPIO, HIGH);
    } else {
        gpio_set_value(DATA_GPIO, LOW);
    }

    gpio_set_value(CLOCK_GPIO, HIGH);
    }

    gpio_set_value(LATCH_GPIO, HIGH);
    msleep(1);
    gpio_set_value(LATCH_GPIO, LOW);
}


static int __init power_led_init(void)
{
    /*
     * If GPIO 15 is high, it is old hardware
     */
printk(KERN_INFO "LED INIT\n");
    if (!gpio_is_valid(LATCH_GPIO)) {
    printk(KERN_INFO "LEDs: Latch gpio is not valid\n");
    return -ENODEV;
    }

    if (!gpio_is_valid(DATA_GPIO)) {
    printk(KERN_INFO "LEDs: Data gpio is not valid\n");
    return -ENODEV;
    }

    if (!gpio_is_valid(CLOCK_GPIO)) {
    printk(KERN_INFO "LEDs: Clock gpio is not valid\n");
    return -ENODEV;
    }

    gpio_request(LATCH_GPIO, "sysfs");
    gpio_request(DATA_GPIO, "sysfs");
    gpio_request(CLOCK_GPIO, "sysfs");

    gpio_direction_output(LATCH_GPIO, LOW);
    gpio_direction_output(DATA_GPIO, LOW);
    gpio_direction_output(CLOCK_GPIO, LOW);

    set_power_led();

    printk(KERN_INFO "Power LED: registered\n");
    return 0;
}

static void __exit power_led_exit(void)
{
    uint8_t i;


    for (i = 0; i < 9 ; i++) {
    gpio_set_value(CLOCK_GPIO, LOW);
    gpio_set_value(DATA_GPIO, LOW);
    gpio_set_value(CLOCK_GPIO, HIGH);
    }
    gpio_set_value(LATCH_GPIO, HIGH);
    msleep(1);
    gpio_set_value(LATCH_GPIO, LOW);
}

module_init(power_led_init);
module_exit(power_led_exit);

With this there is a kernel panic:

[    0.104709] LED INIT
[    0.105306] BUG: unable to handle kernel NULL pointer dereference at 0000004c
[    0.106284] IP: [<c115acc2>] __gpio_set_value+0x12/0x80
[    0.106284] *pde = 00000000 
[    0.106284] Oops: 0000 [#1] 
[    0.106284] Modules linked in:
[    0.106284] CPU: 0 PID: 1 Comm: swapper Not tainted 3.10.49 #33
[    0.106284] task: cf834000 ti: cf840000 task.ti: cf840000
[    0.106284] EIP: 0060:[<c115acc2>] EFLAGS: 00010286 CPU: 0
[    0.106284] EIP is at __gpio_set_value+0x12/0x80
[    0.106284] EAX: c13a1624 EBX: c13a1624 ECX: ffffffea EDX: 00000000
[    0.106284] ESI: 00000000 EDI: 00000000 EBP: cf841f80 ESP: cf841f24
[    0.106284]  DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
[    0.106284] CR0: 8005003b CR2: 0000004c CR3: 01371000 CR4: 00000090
[    0.106284] DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
[    0.106284] DR6: ffff0ff0 DR7: 00000400
[    0.106284] Stack:
[    0.106284]  cf841f3b cf841f44 0000003e c133b05e c12b0d03 006e6967 01010101 01010101
[    0.106284]  00000000 c133afbb c1000172 cfdff401 00060006 c13019c0 c12ced19 cfdff460
[    0.106284]  00000000 cfdff460 00000200 c114956a c136c480 00000006 0000003e cf840000
[    0.106284] Call Trace:
[    0.106284]  [<c133b05e>] ? power_led_init+0xa3/0x112
[    0.106284]  [<c133afbb>] ? alix_init+0xf6/0xf6
[    0.106284]  [<c1000172>] ? do_one_initcall+0xb2/0x150
[    0.106284]  [<c114956a>] ? strcpy+0xa/0x20
[    0.106284]  [<c132da22>] ? kernel_init_freeable+0xd1/0x173
[    0.106284]  [<c132d4aa>] ? do_early_param+0x77/0x77
[    0.106284]  [<c124ad68>] ? kernel_init+0x8/0x170
[    0.106284]  [<c1251322>] ? ret_from_kernel_thread+0x6/0x28
[    0.106284]  [<c1251337>] ? ret_from_kernel_thread+0x1b/0x28
[    0.106284]  [<c124ad60>] ? rest_init+0x60/0x60
[    0.106284] Code: d6 ab aa aa aa ff d1 5b 5e 5f c3 8d b4 26 00 00 00 00 8d bc 27 00 00 00 00 57 f
[    0.106284] EIP: [<c115acc2>] __gpio_set_value+0x12/0x80 SS:ESP 0068:cf841f24
[    0.106284] CR2: 000000000000004c
[    0.106284] ---[ end trace 23021a4cac17faa2 ]---
[    0.107751] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009
[    0.107751] 

Why this is crashing here and where can I add this to make this module loaded at the earliest.

Full minicom log

PC Engines ALIX.3 v0.99h
640 KB Base Memory
153603174448128645128089697280113664130048146432162816179200195584211968228352244736261120 KB Extended Memory

01F0 Master 045A InnoDisk Corp. - iCF4000 8GB            
Phys C/H/S 16000/16/63 Log C/H/S 1003/255/63 LBA
GRUB loading....


  Booting `OpenWrt'



[    0.000000] Linux version 3.10.49 (savari@Ramana) (gcc version 4.8.3 (OpenWrt/Linaro GCC 4.8-2014.04 unknown) ) #40 Tue Nov 8 13:11:49 IST 2016
[    0.000000] e820: BIOS-provided physical RAM map:
[    0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009ffff] usable
[    0.000000] BIOS-e820: [mem 0x00000000000f0000-0x00000000000fffff] reserved
[    0.000000] BIOS-e820: [mem 0x0000000000100000-0x000000000fffffff] usable
[    0.000000] BIOS-e820: [mem 0x00000000fff00000-0x00000000ffffffff] reserved
[    0.000000] Notice: NX (Execute Disable) protection missing in CPU!
[    0.000000] DMI not present or invalid.
[    0.000000] e820: last_pfn = 0x10000 max_arch_pfn = 0x100000
[    0.000000] init_memory_mapping: [mem 0x00000000-0x000fffff]
[    0.000000] init_memory_mapping: [mem 0x0fc00000-0x0fffffff]
[    0.000000] init_memory_mapping: [mem 0x08000000-0x0fbfffff]
[    0.000000] init_memory_mapping: [mem 0x00100000-0x07ffffff]
[    0.000000] 256MB LOWMEM available.
[    0.000000]   mapped low ram: 0 - 10000000
[    0.000000]   low ram: 0 - 10000000
[    0.000000] Zone ranges:
[    0.000000]   DMA      [mem 0x00001000-0x00ffffff]
[    0.000000]   Normal   [mem 0x01000000-0x0fffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x00001000-0x0009ffff]
[    0.000000]   node   0: [mem 0x00100000-0x0fffffff]
[    0.000000] Using APIC driver default
[    0.000000] No local APIC present or hardware disabled
[    0.000000] APIC: disable apic facility
[    0.000000] APIC: switched to apic NOOP
[    0.000000] e820: [mem 0x10000000-0xffefffff] available for PCI devices
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 64927
[    0.000000] Kernel command line: BOOT_IMAGE=/boot/vmlinuz block2mtd.block2mtd=/dev/hda2,131072,rootfs,5 root=/dev/mtdblock0 rootfstype=jffs2 rootwait console=tty0 console=ttyS0,38400n8 noinitrd
[    0.000000] PID hash table entries: 1024 (order: 0, 4096 bytes)
[    0.000000] Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
[    0.000000] Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
[    0.000000] Initializing CPU#0
[    0.000000] Memory: 255600k/262144k available (2377k kernel code, 6156k reserved, 873k data, 260k init, 0k highmem)
[    0.000000] virtual kernel memory layout:
[    0.000000]     fixmap  : 0xfffa3000 - 0xfffff000   ( 368 kB)
[    0.000000]     vmalloc : 0xd0800000 - 0xfffa1000   ( 759 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xd0000000   ( 256 MB)
[    0.000000]       .init : 0xc132d000 - 0xc136e000   ( 260 kB)
[    0.000000]       .data : 0xc1252630 - 0xc132cd00   ( 873 kB)
[    0.000000]       .text : 0xc1000000 - 0xc1252630   (2377 kB)
[    0.000000] Checking if this processor honours the WP bit even in supervisor mode...Ok.
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] NR_IRQS:2304 nr_irqs:256 16
[    0.000000] console [ttyS0] enabled
[    0.000000] tsc: Fast TSC calibration using PIT
[    0.000000] tsc: Detected 498.062 MHz processor
[    0.003005] Calibrating delay loop (skipped), value calculated using timer frequency.. 996.12 BogoMIPS (lpj=498062)
[    0.005013] pid_max: default: 32768 minimum: 301
[    0.007653] Mount-cache hash table entries: 512
[    0.011056] Last level iTLB entries: 4KB 0, 2MB 0, 4MB 0
[    0.011056] Last level dTLB entries: 4KB 0, 2MB 0, 4MB 0
[    0.011056] tlb_flushall_shift: -1
[    0.012009] CPU: Geode(TM) Integrated Processor by AMD PCS (fam: 05, model: 0a, stepping: 02)
[    0.018327] Performance Events: no PMU driver, software events only.
[    0.026472] NET: Registered protocol family 16
[    0.030862] PCI: PCI BIOS revision 2.10 entry at 0xfced9, last bus=0
[    0.031012] PCI: Using configuration type 1 for base access
[    0.051103] bio: create slab <bio-0> at 0
[    0.057403] SCSI subsystem initialized
[    0.060534] PCI: Probing PCI hardware
[    0.062281] PCI host bridge to bus 0000:00
[    0.063030] pci_bus 0000:00: root bus resource [io  0x0000-0xffff]
[    0.064033] pci_bus 0000:00: root bus resource [mem 0x00000000-0xffffffff]
[    0.065020] pci_bus 0000:00: No busn resource found for root bus, will use [bus 00-ff]
[    0.078410] Switching to clocksource pit
[    0.086307] NET: Registered protocol family 2
[    0.088599] TCP established hash table entries: 2048 (order: 2, 16384 bytes)
[    0.089847] TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
[    0.090949] TCP: Hash tables configured (established 2048 bind 2048)
[    0.092136] TCP: reno registered
[    0.093867] UDP hash table entries: 256 (order: 0, 4096 bytes)
[    0.095398] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[    0.096873] NET: Registered protocol family 1
[    0.100630] platform rtc_cmos: registered platform RTC device (no PNP device found)
[    0.104665] alix: system is recognized as "PC Engines ALIX.3 v0.99h"
[    0.106619] LED INIT
[    0.107229] BUG: unable to handle kernel NULL pointer dereference at 0000004c
[    0.108207] IP: [<c115acc2>] __gpio_set_value+0x12/0x80
[    0.108207] *pde = 00000000 
[    0.108207] Oops: 0000 [#1] 
[    0.108207] Modules linked in:
[    0.108207] CPU: 0 PID: 1 Comm: swapper Not tainted 3.10.49 #40
[    0.108207] task: cf834000 ti: cf840000 task.ti: cf840000
[    0.108207] EIP: 0060:[<c115acc2>] EFLAGS: 00010286 CPU: 0
[    0.108207] EIP is at __gpio_set_value+0x12/0x80
[    0.108207] EAX: c13a1624 EBX: c13a1624 ECX: ffffffea EDX: 00000000
[    0.108207] ESI: 00000000 EDI: 00000000 EBP: cf841f80 ESP: cf841f24
[    0.108207]  DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
[    0.108207] CR0: 8005003b CR2: 0000004c CR3: 01371000 CR4: 00000090
[    0.108207] DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
[    0.108207] DR6: ffff0ff0 DR7: 00000400
[    0.108207] Stack:
[    0.108207]  cf841f3b cf841f44 0000003e c133b031 c12b0deb 006e6967 01010101 01010101
[    0.108207]  00000000 c133afbb c1000172 00000001 00060006 c1301bf0 c12ceeb1 cfdff460
[    0.108207]  00000000 cfdff460 00000200 00000000 c136c480 00000006 0000003e cf840000
[    0.108207] Call Trace:
[    0.108207]  [<c133b031>] ? power_led_init+0x76/0xe5
[    0.108207]  [<c133afbb>] ? alix_init+0xf6/0xf6
[    0.108207]  [<c1000172>] ? do_one_initcall+0xb2/0x150
[    0.108207]  [<c132da22>] ? kernel_init_freeable+0xd1/0x173
[    0.108207]  [<c132d4aa>] ? do_early_param+0x77/0x77
[    0.108207]  [<c124b058>] ? kernel_init+0x8/0x170
[    0.108207]  [<c1251622>] ? ret_from_kernel_thread+0x6/0x28
[    0.108207]  [<c1251637>] ? ret_from_kernel_thread+0x1b/0x28
[    0.108207]  [<c124b050>] ? rest_init+0x60/0x60
[    0.108207] Code: d6 ab aa aa aa ff d1 5b 5e 5f c3 8d b4 26 00 00 00 00 8d bc 27 00 00 00 00 57 89 d7 56 53 e8 46 f4 ff ff 85 c0 89 c3 74 5d 8b 30 <f6> 46 4c 01 74 10 ba 8a 07 00 00 b8 5c da 2c c1 e8 b9 bb ec ff
[    0.108207] EIP: [<c115acc2>] __gpio_set_value+0x12/0x80 SS:ESP 0068:cf841f24
[    0.108207] CR2: 000000000000004c
[    0.108207] ---[ end trace 7b3836317c1bee78 ]---
[    0.108879] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009
[    0.108879] 
linux-kernel
linux-device-driver
openwrt
asked on Stack Overflow Nov 8, 2016 by Ramana Reddy • edited Nov 8, 2016 by Ramana Reddy

1 Answer

1

I think you have put this in kernel source directory. You should place this in drivers/gpio/ in kernel source. Then add the entries in Kconfig and Makefile of drivers/gpio/ directory. In Kconfig, you can specify the dependency. Selecting it with make menuconfig, you will be able to compile this module as a part of kernel, and it will be loaded at boot-time when kernel is loaded. You can decrease the time further in this case using early_initcall() instead of module_init().

If you are not putting this at kernel source (i.e. not building the driver as part of kernel), then you should call this using "insmod my_module.ko" in a shell script, and put it in init.d and call it at your desired runlevel.

answered on Stack Overflow Dec 31, 2016 by Nirav Khatri

User contributions licensed under CC BY-SA 3.0