//pmem device
static struct android_pmem_platform_data android_pmem_kernel_ebi1_pdata = {
.name = PMEM_KERNEL_EBI1_DATA_NAME,
/* if no allocator_type, defaults to PMEM_ALLOCATORTYPE_BITMAP,
* the only valid choice at this time. The board structure is
* set to all zeros by the C runtime initialization and that is now
* the enum value of PMEM_ALLOCATORTYPE_BITMAP, now forced to 0 in
* include/linux/android_pmem.h.
*/
.cached = 0,
};
static struct android_pmem_platform_data android_pmem_adsp_pdata = {
.name = "pmem_adsp",
.allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
.cached = 0,
};
static struct android_pmem_platform_data android_pmem_audio_pdata = {
.name = "pmem_audio",
.allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
.cached = 0,
};
static struct platform_device android_pmem_kernel_ebi1_device = {
.name = "android_pmem",
.id = 1,
.dev = { .platform_data = &android_pmem_kernel_ebi1_pdata },
};
static struct platform_device android_pmem_adsp_device = {
.name = "android_pmem",
.id = 2,
.dev = { .platform_data = &android_pmem_adsp_pdata },
};
static struct platform_device android_pmem_audio_device = {
.name = "android_pmem",
.id = 4,
.dev = { .platform_data = &android_pmem_audio_pdata },
};
static struct platform_device *devices[] __initdata = {
...
&android_pmem_kernel_ebi1_device,
&android_pmem_adsp_device,
&android_pmem_audio_device,
...
}
static void __init msm7x30_init(void)
{
...
platform_add_devices(devices, ARRAY_SIZE(devices));
...
}
MACHINE_START(MSM7X30_FLUID, "QCT MSM7X30 FLUID")
#ifdef CONFIG_MSM_DEBUG_UART
.phys_io = MSM_DEBUG_UART_PHYS,
.io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
#endif
.boot_params = PHYS_OFFSET + 0x100,
.map_io = msm7x30_map_io,
.init_irq = msm7x30_init_irq,
.init_machine = msm7x30_init, //machin
.timer = &msm_timer,
MACHINE_END
static void (*init_machine)(void) __initdata;
static int __init customize_machine(void)
{
/* customizes platform devices, or adds new ones */
=> if (init_machine)
init_machine(); //init_machine() was called during arch init procedure
return 0;
}
arch_initcall(customize_machine);
*** arch/arm/kernel/setup.c:
customize_machine[811] if (init_machine)
customize_machine[812] init_machine();
setup_arch[879] init_machine = mdesc->init_machine; //init_machine was initialized here in setup_arch()
------------------------------------
static void __init msm7x30_allocate_memory_regions(void)
{
void *addr;
unsigned long size;
/*
Request allocation of Hardware accessible PMEM regions
at the beginning to make sure they are allocated in EBI-0.
This will allow 7x30 with two mem banks enter the second
mem bank into Self-Refresh State during Idle Power Collapse.
The current HW accessible PMEM regions are
1. Frame Buffer.
LCDC HW can access msm_fb_resources during Idle-PC.
2. Audio
LPA HW can access android_pmem_audio_pdata during Idle-PC.
*/
size = fb_size ? : MSM_FB_SIZE;
addr = alloc_bootmem(size);
msm_fb_resources[0].start = __pa(addr);
msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1;
pr_info("allocating %lu bytes at %p (%lx physical) for fb\n",
size, addr, __pa(addr));
size = pmem_audio_size;
if (size) {
addr = alloc_bootmem(size);
android_pmem_audio_pdata.start = __pa(addr);
android_pmem_audio_pdata.size = size;
pr_info("allocating %lu bytes at %p (%lx physical) for audio "
"pmem arena\n", size, addr, __pa(addr));
}
size = gpu_phys_size;
if (size) {
addr = alloc_bootmem(size);
kgsl_resources[1].start = __pa(addr);
kgsl_resources[1].end = kgsl_resources[1].start + size - 1;
pr_info("allocating %lu bytes at %p (%lx physical) for "
"KGSL\n", size, addr, __pa(addr));
}
size = pmem_kernel_ebi1_size;
if (size) {
addr = alloc_bootmem_aligned(size, 0x100000);
android_pmem_kernel_ebi1_pdata.start = __pa(addr);
android_pmem_kernel_ebi1_pdata.size = size;
pr_info("allocating %lu bytes at %p (%lx physical) for kernel"
" ebi1 pmem arena\n", size, addr, __pa(addr));
}
size = pmem_sf_size;
if (size) {
addr = alloc_bootmem(size);
android_pmem_pdata.start = __pa(addr);
android_pmem_pdata.size = size;
pr_info("allocating %lu bytes at %p (%lx physical) for sf "
"pmem arena\n", size, addr, __pa(addr));
}
if machine_is_msm7x30_fluid()
size = fluid_pmem_adsp_size;
else
size = pmem_adsp_size;
if (size) {
addr = alloc_bootmem(size);
android_pmem_adsp_pdata.start = __pa(addr);
android_pmem_adsp_pdata.size = size;
pr_info("allocating %lu bytes at %p (%lx physical) for adsp "
"pmem arena\n", size, addr, __pa(addr));
}
}
//pmem driver
static struct platform_driver pmem_driver = {
.probe = pmem_probe,
.remove = pmem_remove,
.driver = { .name = "android_pmem",
.pm = &pmem_dev_pm_ops,
}
};
static int __init pmem_init(void)
{
/* create /sys/kernel/<PMEM_SYSFS_DIR_NAME> directory */
pmem_kset = kset_create_and_add(PMEM_SYSFS_DIR_NAME,
NULL, kernel_kobj);
if (!pmem_kset) {
pr_err("pmem(%s):kset_create_and_add fail\n", __func__);
return -ENOMEM;
}
#ifdef CONFIG_MEMORY_HOTPLUG
hotplug_memory_notifier(pmem_memory_callback, 0);
#endif
return platform_driver_register(&pmem_driver);
}
static int pmem_probe(struct platform_device *pdev)
{
struct android_pmem_platform_data *pdata;
if (!pdev || !pdev->dev.platform_data) {
pr_alert("Unable to probe pmem!\n");
return -1;
}
pdata = pdev->dev.platform_data;
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
return pmem_setup(pdata, NULL, NULL);
}
pmem
最新推荐文章于 2022-04-15 21:08:12 发布