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 localu64
variable, but uses a reference to one which is shared by a number ofplatform_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,
- Does anyone know if this shared reference is a possible culprit to the problem?
- Can anyone shed some light on the reasoning why such a drastic change was made to the kernel source?
- 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?