0

Presently working on a board support package for an SBC with a S3C6410 CPU. The vendor of the board has only provided support for the 2.6 kernel, and I am trying to migrate up to a newer 3.x kernel. Unfortunately, I keep running into problems with a number of the devices not being properly supported in the latter kernels. For example, USB support is critical for the project. I can get it to work with the 3.0.x series, but 3.2.x and beyond does not come up properly. I have searched for patches/updates to no avail, so I have rolled up my sleeves and gotten down and dirty in the kernel source.

I noticed that there was a substantial change in the kernel tree (arch/arm/plat-samsung), where previously there existed multiple modules, one per supported device, and now there is one monolithic module that contains the support for all of them. For example,

Linux 3.0.80 arch/arm/plat-samsung/dev-usb-hsotg.c

#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>

#include <mach/irqs.h>
#include <mach/map.h>

#include <plat/devs.h>

static struct resource s3c_usb_hsotg_resources[] = {
        [0] = {
                .start  = S3C_PA_USB_HSOTG,
                .end    = S3C_PA_USB_HSOTG + 0x10000 - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
                .start  = IRQ_OTG,
                .end    = IRQ_OTG,
                .flags  = IORESOURCE_IRQ,
        },
};

static u64 s3c_hsotg_dmamask = DMA_BIT_MASK(32);

struct platform_device s3c_device_usb_hsotg = {
        .name           = "s3c-hsotg",
        .id             = -1,
        .num_resources  = ARRAY_SIZE(s3c_usb_hsotg_resources),
        .resource       = s3c_usb_hsotg_resources,
        .dev            = {
                .dma_mask               = &s3c_hsotg_dmamask,
                .coherent_dma_mask      = DMA_BIT_MASK(32),
        },
};

This file has been removed, and the support has been transferred into arch/arm/plat-samsung/devs.c

However, on comparing the original code to that in the newer kernel ...

Linux 3.2.48 arch/arm/plat-samsung/devs.c

/* USB HSOTG */

#ifdef CONFIG_S3C_DEV_USB_HSOTG
static struct resource s3c_usb_hsotg_resources[] = {
        [0] = DEFINE_RES_MEM(S3C_PA_USB_HSOTG, SZ_16K),
        [1] = DEFINE_RES_IRQ(IRQ_OTG),
};

struct platform_device s3c_device_usb_hsotg = {
        .name           = "s3c-hsotg",
        .id             = -1,
        .num_resources  = ARRAY_SIZE(s3c_usb_hsotg_resources),
        .resource       = s3c_usb_hsotg_resources,
        .dev            = {
                .dma_mask               = &samsung_device_dma_mask,
                .coherent_dma_mask      = DMA_BIT_MASK(32),
        },
};
#endif /* CONFIG_S3C_DEV_USB_HSOTG */

... there have been some changes to the driver that, to my naive eyes, look like bugs:

  • The memory size for s3c_usb_hsotg_resources[0] changed from 64K to 16K.
  • The s3c_device_usb_hsotg.dev.dma_mask no longer uses a local u64 variable, but uses a reference to one which is shared by a number of platform_device structs.

Now, in spite of rummaging through kernel code for the better part of two months, I am still very much a noob when it comes to driver development. The memory size change may very well be warranted and part of changes that were made by whomever is presently supporting the module, but I am concerned as to whether using a reference to a single shared u64 variable may be causing some of the problems I have been seeing with this specific device, among others. In the case of the USB driver, I see that it loads when I bring up the board, but it never detects any devices that are connected to it. I have confirmed that this is not a hardware-related issue, as the devices are properly recognized with the 2.6 and 3.0 kernels. So this makes me lean towards it being caused by the newer kernel code.

So,

  1. Does anyone know if this shared reference is a possible culprit to the problem?
  2. Can anyone shed some light on the reasoning why such a drastic change was made to the kernel source?
  3. Are there some concise resources available (links, books, etc) that cover the changes in the kernel device drivers from the 3.0 series to the 3.2+ series?
Will
  • 3,500
  • 4
  • 30
  • 38
  • You could try to run git bisect between v3.0 and v3.2 to find the patch which introduces the problem. – Nico Erfurth Jul 10 '13 at 05:06
  • See: [Cross version modules](http://stackoverflow.com/questions/17138491/how-to-write-cross-version-platform-linux-kernel-modules) for similar concepts. – artless noise Jul 10 '13 at 13:43

1 Answers1

3

I can't answer your first question but I'll attempt to answer your second and third question.

What you're experiencing is actually a very normal part of kernel development. Linux is developed at a very fast pace and has no time to slow down for vendors to catch up. The kernel is constantly being improved and as a result, code may be shuffled around, APIs completely revamped, functions added, renamed or removed etc... If that didn't happen, a lot of effort would be wasted trying to maintain backwards compatibility. In other words, developers for the mainline kernel don't care about your vendor's Linux fork - they only care about the code that is in the mainline kernel.

Unfortunately, the only way you could have avoided this was to have your vendor send your platform support upstream to get it into mainline as soon as the port was finished where it'll be maintained by other coders (instead of you as you're doing now). That way, when things break in your platform because of some change another coder did, it's usually up to that person to fix your code.

Have a read of Stable API Nonsense for more on why Linux development works this way.

To answer your third question, Kernel Newbies maintains a brief changelog of every major release of Linux that you can look up.

http://kernelnewbies.org/Linux_3.2

http://kernelnewbies.org/Linux_3.1

http://kernelnewbies.org/Linux_3.0

For anything more granular, you'd have to go fishing in the git commit logs.

tangrs
  • 9,709
  • 1
  • 38
  • 53
  • Thanks - will definitely give those a read. As for the vendor ... they seem to be more concerned with their more recent products, and not interested in bringing the support forward for my board. Mind you, the board I have is not an old product for them (<2 yrs) ... but they are pushing forward, much like you describe about the kernel. I have a feeling they looked at bringing the support forward, found what I have been dealing with, and decided it wasn't worth their time/effort. Oh well ... learning experience for me, I guess. – Will Jul 10 '13 at 12:46