This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

setting DEVCTL[SESSION] in a kernel module not working



Hello!

I'm writing a kernel module for AM335x running TI Arago SDK7 kernel on debian FS. I'm trying to set the USB DEVCTL[session] bit in it as part of a set up I'm doing. Everytime I do ioremap and try to read the existing value of that register it causes a seg fault. I am able to ioremap on other registers no problem. In the same module I have had to ioremap USB0MODE register and change the value inside that, and it worked like a charm, no problem.

Here is what I have:

#define USB_REGISTERS_BASE_ADDRESS 0x01C64000
#define DEVCTL_OFFSET 0x460

struct usb_data {
const char* name; /* Name of the register */
unsigned int base; /* Base address of the register unit */
unsigned int offset; /* Offset of the bit/register */
};


static const struct usb_data devctl_reg = {
.name = "DEVCTL",
.base = USB_REGISTERS_BASE_ADDRESS,
.offset = DEVCTL_OFFSET,
};

static void usbmode_setup(const struct usb_data* reg_data, int host)
{
void __iomem* gpio_base;
unsigned int regval;

gpio_base = ioremap(reg_data->base, 0x1000);
if (!gpio_base) {
printk(KERN_ERR "ioremap of USB0 Control Register failed\n");
return;
} else {
printk(KERN_INFO "Successfully Took over %s Registers area at addres: %02x\n", reg_data->name, gpio_base + reg_data->offset);
}

if (host) {
/* Setting host mode */
regval = readl(gpio_base + reg_data->offset);

printk(KERN_INFO "Read Value of %d\n", regval);
printk(KERN_INFO "Writing value 0x80 into the %s register\n", reg_data->name);
writel(0x80, gpio_base + reg_data->offset);
regval = readl(gpio_base + reg_data->offset);
printk(KERN_INFO "Read Value of %d\n", regval);

} else {
/* Setting Device Mode */
}

iounmap(gpio_base);
}

[  318.240130] Successfully Took over DEVCTL Registers area at addres: e0c6c460
[  318.247597] Unhandled fault: external abort on non-linefetch (0x1008) at 0xe0c6c460
[  318.255669] Internal error: : 1008 [#1] PREEMPT ARM
[  318.260806] Modules linked in: usbmod(+) [last unloaded: usbmod]
[  318.267163] CPU: 0 PID: 1709 Comm: insmod Not tainted 3.12.10-svn13 #4
[  318.274045] task: dd86e040 ti: ddea0000 task.ti: ddea0000
[  318.279749] PC is at usbmode_setup+0x5c/0xe4 [usbmod]
[  318.285080] LR is at wake_up_klogd+0x54/0x7c
[  318.289581] pc : [<bf00405c>]    lr : [<c0073eb0>]    psr: 20000013
[  318.289581] sp : ddea1dc0  ip : ddea1cc0  fp : ddea1ddc
[  318.301670] r10: 00000001  r9 : ddea0000  r8 : bf006000
[  318.307176] r7 : 00000001  r6 : 00000001  r5 : e0c6c000  r4 : bf00410c
[  318.314049] r3 : e0c6c460  r2 : ddea1cc0  r1 : 00000000  r0 : 00000040
[  318.320926] Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
[  318.328446] Control: 10c5387d  Table: 9def0019  DAC: 00000015
[  318.334497] Process insmod (pid: 1709, stack limit = 0xddea0240)
[  318.340822] Stack: (0xddea1dc0 to 0xddea2000)
[  318.345420] 1dc0: 00000000 bf00438c bf004258 bf00424c ddea1df4 ddea1de0 bf006048 bf00400c
[  318.354044] 1de0: 00000000 ddea1f48 ddea1e84 ddea1df8 c0008a1c bf00600c 00000000 00000000
[  318.362663] 1e00: bf00424c 00000000 c008b044 00000001 ddea1e34 ddea1e20 c028db3c c05dc438
[  318.371279] 1e20: c087b3fc 00000000 ddea1e44 ddea1e38 c0066dd4 c028daf4 ddea1e6c ddea1e48
[  318.379904] 1e40: c0067e5c c0066dd0 00000000 ddea1e58 ddea1f48 bf004258 bf00424c ddea1f48
[  318.388521] 1e60: bf004258 bf00424c 00000001 ddf47480 c008b044 00000001 ddea1f44 ddea1e88
[  318.397138] 1e80: c008d868 c0008934 bf004258 00007fff c008b2c0 000085b0 ddea1ec4 e0c5f000
[  318.405756] 1ea0: 00000001 bf00424c ddea1edc bf004258 bf004258 bf004294 bf004378 ddea0000
[  318.414375] 1ec0: ddea1f0c c07a4fbc ddea1fa4 ddea1ed8 c05da520 c00085b4 e0c67000 00000000
[  318.422991] 1ee0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[  318.431608] 1f00: 00000000 00000000 00000000 00000000 00000000 00000000 20000013 000085b0
[  318.440232] 1f20: b6e55000 b6fb1008 00000080 c0014968 ddea0000 00000000 ddea1fa4 ddea1f48
[  318.448850] 1f40: c008df34 c008c074 e0c5f000 000085b0 e0c64f08 e0c64d9b e0c673d8 00000390
[  318.457467] 1f60: 00000410 00000000 00000000 00000000 00000026 00000027 00000010 0000000e
[  318.466086] 1f80: 0000000a 00000000 00000000 b6eb6301 b6fb1dc8 b6fb1d28 00000000 ddea1fa8
[  318.474704] 1fa0: c00147c0 c008de90 b6eb6301 b6fb1dc8 b6e55000 000085b0 b6fb1008 00000002
[  318.483328] 1fc0: b6eb6301 b6fb1dc8 b6fb1d28 00000080 00000000 b6fb1008 000085b0 00000000
[  318.491946] 1fe0: 00000000 bea93bcc b6f68b07 b6ef2fd4 80000010 b6e55000 00000000 00000000
[  318.500561] Backtrace:
[  318.503162] [<bf004000>] (usbmode_setup+0x0/0xe4 [usbmod]) from [<bf006048>] (transition_start+0x48/0x68 [usbmod])
[  318.514059]  r6:bf00424c r5:bf004258 r4:bf00438c r3:00000000
[  318.520059] [<bf006000>] (transition_start+0x0/0x68 [usbmod]) from [<c0008a1c>] (do_one_initcall+0xf4/0x154)
[  318.530415]  r4:ddea1f48 r3:00000000
[  318.534206] [<c0008928>] (do_one_initcall+0x0/0x154) from [<c008d868>] (load_module+0x1800/0x1e1c)
[  318.543658] [<c008c068>] (load_module+0x0/0x1e1c) from [<c008df34>] (SyS_init_module+0xb0/0xf4)
[  318.552838] [<c008de84>] (SyS_init_module+0x0/0xf4) from [<c00147c0>] (ret_fast_syscall+0x0/0x30)
[  318.562187]  r6:b6fb1d28 r5:b6fb1dc8 r4:b6eb6301
[  318.567074] Code: e3560000 0a00001b e5943008 e0853003 (e5931000)
[  318.573502] ---[ end trace bb9e578770f42324 ]---
Segmentation fault

My __init calls that function with the right arguments. Here is what I get when I run it:

Am I doing something wrong?