diff options
-rw-r--r-- | .gitignore | 7 | ||||
-rw-r--r-- | ANDROID_3.4.5/arch/arm/kernel/setup.c | 1132 | ||||
-rw-r--r-- | ANDROID_3.4.5/arch/arm/kernel/smp.c | 670 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/cpufreq/cpufreq.c | 1939 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/media/dvb/siano/sms-cards.c | 311 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/media/dvb/siano/sms-cards.h | 123 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/media/dvb/siano/smscoreapi.c | 1644 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/media/dvb/siano/smscoreapi.h | 775 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/media/dvb/siano/smsdvb.c | 1078 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/media/dvb/siano/smsendian.c | 103 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/media/dvb/siano/smsendian.h | 32 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/media/dvb/siano/smsir.c | 114 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/media/dvb/siano/smsir.h | 55 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/media/dvb/siano/smssdio.c | 365 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/media/dvb/siano/smsusb.c | 568 | ||||
-rw-r--r-- | ANDROID_3.4.5/init/calibrate.c | 301 |
16 files changed, 7 insertions, 9210 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..0e840d29 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +obj_tmp/ +ANDROID_3.4.5/ANDROID_3.4.5_Driver_Obj/ +ANDROID_3.4.5/drivers/net/wireless/DPA_MT7601U_ANDROID_JB_3.0.0.6_20130830/PREALLOC/os/linux/Makefile +ANDROID_3.4.5/drivers/net/wireless/DPA_MT7601U_ANDROID_JB_3.0.0.6_20130830/include/ +ANDROID_3.4.5/drivers/net/wireless/DPA_MT7601U_ANDROID_JB_3.0.0.6_20130830/tools/bin2h +ANDROID_3.4.5/security/tomoyo/builtin-policy.h +ANDROID_3.4.5/security/tomoyo/policy/ diff --git a/ANDROID_3.4.5/arch/arm/kernel/setup.c b/ANDROID_3.4.5/arch/arm/kernel/setup.c deleted file mode 100644 index ebfac782..00000000 --- a/ANDROID_3.4.5/arch/arm/kernel/setup.c +++ /dev/null @@ -1,1132 +0,0 @@ -/* - * linux/arch/arm/kernel/setup.c - * - * Copyright (C) 1995-2001 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/export.h> -#include <linux/kernel.h> -#include <linux/stddef.h> -#include <linux/ioport.h> -#include <linux/delay.h> -#include <linux/utsname.h> -#include <linux/initrd.h> -#include <linux/console.h> -#include <linux/bootmem.h> -#include <linux/seq_file.h> -#include <linux/screen_info.h> -#include <linux/init.h> -#include <linux/kexec.h> -#include <linux/of_fdt.h> -#include <linux/root_dev.h> -#include <linux/cpu.h> -#include <linux/interrupt.h> -#include <linux/smp.h> -#include <linux/fs.h> -#include <linux/proc_fs.h> -#include <linux/memblock.h> -#include <linux/bug.h> -#include <linux/compiler.h> -#include <linux/sort.h> - -#include <asm/unified.h> -#include <asm/cp15.h> -#include <asm/cpu.h> -#include <asm/cputype.h> -#include <asm/elf.h> -#include <asm/procinfo.h> -#include <asm/sections.h> -#include <asm/setup.h> -#include <asm/smp_plat.h> -#include <asm/mach-types.h> -#include <asm/cacheflush.h> -#include <asm/cachetype.h> -#include <asm/tlbflush.h> - -#include <asm/prom.h> -#include <asm/mach/arch.h> -#include <asm/mach/irq.h> -#include <asm/mach/time.h> -#include <asm/system_info.h> -#include <asm/system_misc.h> -#include <asm/traps.h> -#include <asm/unwind.h> -#include <asm/memblock.h> - -#if defined(CONFIG_DEPRECATED_PARAM_STRUCT) -#include "compat.h" -#endif -#include "atags.h" -#include "tcm.h" - -#ifndef MEM_SIZE -#define MEM_SIZE (16*1024*1024) -#endif - -#if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE) -char fpe_type[8]; - -static int __init fpe_setup(char *line) -{ - memcpy(fpe_type, line, 8); - return 1; -} - -__setup("fpe=", fpe_setup); -#endif - -extern void paging_init(struct machine_desc *desc); -extern void sanity_check_meminfo(void); -extern void reboot_setup(char *str); - -unsigned int processor_id; -EXPORT_SYMBOL(processor_id); -unsigned int __machine_arch_type __read_mostly; -EXPORT_SYMBOL(__machine_arch_type); -unsigned int cacheid __read_mostly; -EXPORT_SYMBOL(cacheid); - -unsigned int __atags_pointer __initdata; - -unsigned int system_rev; -EXPORT_SYMBOL(system_rev); - -unsigned int system_serial_low; -EXPORT_SYMBOL(system_serial_low); - -unsigned int system_serial_high; -EXPORT_SYMBOL(system_serial_high); - -unsigned int elf_hwcap __read_mostly; -EXPORT_SYMBOL(elf_hwcap); - - -#ifdef MULTI_CPU -struct processor processor __read_mostly; -#endif -#ifdef MULTI_TLB -struct cpu_tlb_fns cpu_tlb __read_mostly; -#endif -#ifdef MULTI_USER -struct cpu_user_fns cpu_user __read_mostly; -#endif -#ifdef MULTI_CACHE -struct cpu_cache_fns cpu_cache __read_mostly; -#endif -#ifdef CONFIG_OUTER_CACHE -struct outer_cache_fns outer_cache __read_mostly; -EXPORT_SYMBOL(outer_cache); -#endif - -/* - * Cached cpu_architecture() result for use by assembler code. - * C code should use the cpu_architecture() function instead of accessing this - * variable directly. - */ -int __cpu_architecture __read_mostly = CPU_ARCH_UNKNOWN; - -struct stack { - u32 irq[3]; - u32 abt[3]; - u32 und[3]; -} ____cacheline_aligned; - -static struct stack stacks[NR_CPUS]; - -char elf_platform[ELF_PLATFORM_SIZE]; -EXPORT_SYMBOL(elf_platform); - -static const char *cpu_name; -static const char *machine_name; -static char __initdata cmd_line[COMMAND_LINE_SIZE]; -struct machine_desc *machine_desc __initdata; - -static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; -static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } }; -#define ENDIANNESS ((char)endian_test.l) - -DEFINE_PER_CPU(struct cpuinfo_arm, cpu_data); - -/* - * Standard memory resources - */ -static struct resource mem_res[] = { - { - .name = "Video RAM", - .start = 0, - .end = 0, - .flags = IORESOURCE_MEM - }, - { - .name = "Kernel code", - .start = 0, - .end = 0, - .flags = IORESOURCE_MEM - }, - { - .name = "Kernel data", - .start = 0, - .end = 0, - .flags = IORESOURCE_MEM - } -}; - -#define video_ram mem_res[0] -#define kernel_code mem_res[1] -#define kernel_data mem_res[2] - -static struct resource io_res[] = { - { - .name = "reserved", - .start = 0x3bc, - .end = 0x3be, - .flags = IORESOURCE_IO | IORESOURCE_BUSY - }, - { - .name = "reserved", - .start = 0x378, - .end = 0x37f, - .flags = IORESOURCE_IO | IORESOURCE_BUSY - }, - { - .name = "reserved", - .start = 0x278, - .end = 0x27f, - .flags = IORESOURCE_IO | IORESOURCE_BUSY - } -}; - -#define lp0 io_res[0] -#define lp1 io_res[1] -#define lp2 io_res[2] - -static const char *proc_arch[] = { - "undefined/unknown", - "3", - "4", - "4T", - "5", - "5T", - "5TE", - "5TEJ", - "6TEJ", - "7", - "?(11)", - "?(12)", - "?(13)", - "?(14)", - "?(15)", - "?(16)", - "?(17)", -}; - -static int __get_cpu_architecture(void) -{ - int cpu_arch; - - if ((read_cpuid_id() & 0x0008f000) == 0) { - cpu_arch = CPU_ARCH_UNKNOWN; - } else if ((read_cpuid_id() & 0x0008f000) == 0x00007000) { - cpu_arch = (read_cpuid_id() & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3; - } else if ((read_cpuid_id() & 0x00080000) == 0x00000000) { - cpu_arch = (read_cpuid_id() >> 16) & 7; - if (cpu_arch) - cpu_arch += CPU_ARCH_ARMv3; - } else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) { - unsigned int mmfr0; - - /* Revised CPUID format. Read the Memory Model Feature - * Register 0 and check for VMSAv7 or PMSAv7 */ - asm("mrc p15, 0, %0, c0, c1, 4" - : "=r" (mmfr0)); - if ((mmfr0 & 0x0000000f) >= 0x00000003 || - (mmfr0 & 0x000000f0) >= 0x00000030) - cpu_arch = CPU_ARCH_ARMv7; - else if ((mmfr0 & 0x0000000f) == 0x00000002 || - (mmfr0 & 0x000000f0) == 0x00000020) - cpu_arch = CPU_ARCH_ARMv6; - else - cpu_arch = CPU_ARCH_UNKNOWN; - } else - cpu_arch = CPU_ARCH_UNKNOWN; - - return cpu_arch; -} - -int __pure cpu_architecture(void) -{ - BUG_ON(__cpu_architecture == CPU_ARCH_UNKNOWN); - - return __cpu_architecture; -} - -static int cpu_has_aliasing_icache(unsigned int arch) -{ - int aliasing_icache; - unsigned int id_reg, num_sets, line_size; - - /* PIPT caches never alias. */ - if (icache_is_pipt()) - return 0; - - /* arch specifies the register format */ - switch (arch) { - case CPU_ARCH_ARMv7: - asm("mcr p15, 2, %0, c0, c0, 0 @ set CSSELR" - : /* No output operands */ - : "r" (1)); - isb(); - asm("mrc p15, 1, %0, c0, c0, 0 @ read CCSIDR" - : "=r" (id_reg)); - line_size = 4 << ((id_reg & 0x7) + 2); - num_sets = ((id_reg >> 13) & 0x7fff) + 1; - aliasing_icache = (line_size * num_sets) > PAGE_SIZE; - break; - case CPU_ARCH_ARMv6: - aliasing_icache = read_cpuid_cachetype() & (1 << 11); - break; - default: - /* I-cache aliases will be handled by D-cache aliasing code */ - aliasing_icache = 0; - } - - return aliasing_icache; -} - -static void __init cacheid_init(void) -{ - unsigned int cachetype = read_cpuid_cachetype(); - unsigned int arch = cpu_architecture(); - - if (arch >= CPU_ARCH_ARMv6) { - if ((cachetype & (7 << 29)) == 4 << 29) { - /* ARMv7 register format */ - arch = CPU_ARCH_ARMv7; - cacheid = CACHEID_VIPT_NONALIASING; - switch (cachetype & (3 << 14)) { - case (1 << 14): - cacheid |= CACHEID_ASID_TAGGED; - break; - case (3 << 14): - cacheid |= CACHEID_PIPT; - break; - } - } else { - arch = CPU_ARCH_ARMv6; - if (cachetype & (1 << 23)) - cacheid = CACHEID_VIPT_ALIASING; - else - cacheid = CACHEID_VIPT_NONALIASING; - } - if (cpu_has_aliasing_icache(arch)) - cacheid |= CACHEID_VIPT_I_ALIASING; - } else { - cacheid = CACHEID_VIVT; - } - - printk("CPU: %s data cache, %s instruction cache\n", - cache_is_vivt() ? "VIVT" : - cache_is_vipt_aliasing() ? "VIPT aliasing" : - cache_is_vipt_nonaliasing() ? "PIPT / VIPT nonaliasing" : "unknown", - cache_is_vivt() ? "VIVT" : - icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" : - icache_is_vipt_aliasing() ? "VIPT aliasing" : - icache_is_pipt() ? "PIPT" : - cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown"); -} - -/* - * These functions re-use the assembly code in head.S, which - * already provide the required functionality. - */ -extern struct proc_info_list *lookup_processor_type(unsigned int); - -void __init early_print(const char *str, ...) -{ - extern void printascii(const char *); - char buf[256]; - va_list ap; - - va_start(ap, str); - vsnprintf(buf, sizeof(buf), str, ap); - va_end(ap); - -#ifdef CONFIG_DEBUG_LL - printascii(buf); -#endif - printk("%s", buf); -} - -static void __init feat_v6_fixup(void) -{ - int id = read_cpuid_id(); - - if ((id & 0xff0f0000) != 0x41070000) - return; - - /* - * HWCAP_TLS is available only on 1136 r1p0 and later, - * see also kuser_get_tls_init. - */ - if ((((id >> 4) & 0xfff) == 0xb36) && (((id >> 20) & 3) == 0)) - elf_hwcap &= ~HWCAP_TLS; -} - -/* - * cpu_init - initialise one CPU. - * - * cpu_init sets up the per-CPU stacks. - */ -void cpu_init(void) -{ - unsigned int cpu = smp_processor_id(); - struct stack *stk = &stacks[cpu]; - - if (cpu >= NR_CPUS) { - printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu); - BUG(); - } - - cpu_proc_init(); - - /* - * Define the placement constraint for the inline asm directive below. - * In Thumb-2, msr with an immediate value is not allowed. - */ -#ifdef CONFIG_THUMB2_KERNEL -#define PLC "r" -#else -#define PLC "I" -#endif - - /* - * setup stacks for re-entrant exception handlers - */ - __asm__ ( - "msr cpsr_c, %1\n\t" - "add r14, %0, %2\n\t" - "mov sp, r14\n\t" - "msr cpsr_c, %3\n\t" - "add r14, %0, %4\n\t" - "mov sp, r14\n\t" - "msr cpsr_c, %5\n\t" - "add r14, %0, %6\n\t" - "mov sp, r14\n\t" - "msr cpsr_c, %7" - : - : "r" (stk), - PLC (PSR_F_BIT | PSR_I_BIT | IRQ_MODE), - "I" (offsetof(struct stack, irq[0])), - PLC (PSR_F_BIT | PSR_I_BIT | ABT_MODE), - "I" (offsetof(struct stack, abt[0])), - PLC (PSR_F_BIT | PSR_I_BIT | UND_MODE), - "I" (offsetof(struct stack, und[0])), - PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE) - : "r14"); -} - -int __cpu_logical_map[NR_CPUS]; - -void __init smp_setup_processor_id(void) -{ - int i; - u32 cpu = is_smp() ? read_cpuid_mpidr() & 0xff : 0; - - cpu_logical_map(0) = cpu; - for (i = 1; i < NR_CPUS; ++i) - cpu_logical_map(i) = i == cpu ? 0 : i; - - printk(KERN_INFO "Booting Linux on physical CPU %d\n", cpu); -} - -static void __init setup_processor(void) -{ - struct proc_info_list *list; - - /* - * locate processor in the list of supported processor - * types. The linker builds this table for us from the - * entries in arch/arm/mm/proc-*.S - */ - list = lookup_processor_type(read_cpuid_id()); - if (!list) { - printk("CPU configuration botched (ID %08x), unable " - "to continue.\n", read_cpuid_id()); - while (1); - } - - cpu_name = list->cpu_name; - __cpu_architecture = __get_cpu_architecture(); - -#ifdef MULTI_CPU - processor = *list->proc; -#endif -#ifdef MULTI_TLB - cpu_tlb = *list->tlb; -#endif -#ifdef MULTI_USER - cpu_user = *list->user; -#endif -#ifdef MULTI_CACHE - cpu_cache = *list->cache; -#endif - - printk("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n", - cpu_name, read_cpuid_id(), read_cpuid_id() & 15, - proc_arch[cpu_architecture()], cr_alignment); - - snprintf(init_utsname()->machine, __NEW_UTS_LEN + 1, "%s%c", - list->arch_name, ENDIANNESS); - snprintf(elf_platform, ELF_PLATFORM_SIZE, "%s%c", - list->elf_name, ENDIANNESS); - elf_hwcap = list->elf_hwcap; -#ifndef CONFIG_ARM_THUMB - elf_hwcap &= ~HWCAP_THUMB; -#endif - - feat_v6_fixup(); - - cacheid_init(); - cpu_init(); -} - -void __init dump_machine_table(void) -{ - struct machine_desc *p; - - early_print("Available machine support:\n\nID (hex)\tNAME\n"); - for_each_machine_desc(p) - early_print("%08x\t%s\n", p->nr, p->name); - - early_print("\nPlease check your kernel config and/or bootloader.\n"); - - while (true) - /* can't use cpu_relax() here as it may require MMU setup */; -} - -int __init arm_add_memory(phys_addr_t start, unsigned long size) -{ - struct membank *bank = &meminfo.bank[meminfo.nr_banks]; - - if (meminfo.nr_banks >= NR_BANKS) { - printk(KERN_CRIT "NR_BANKS too low, " - "ignoring memory at 0x%08llx\n", (long long)start); - return -EINVAL; - } - - /* - * Ensure that start/size are aligned to a page boundary. - * Size is appropriately rounded down, start is rounded up. - */ - size -= start & ~PAGE_MASK; - bank->start = PAGE_ALIGN(start); - -#ifndef CONFIG_LPAE - if (bank->start + size < bank->start) { - printk(KERN_CRIT "Truncating memory at 0x%08llx to fit in " - "32-bit physical address space\n", (long long)start); - /* - * To ensure bank->start + bank->size is representable in - * 32 bits, we use ULONG_MAX as the upper limit rather than 4GB. - * This means we lose a page after masking. - */ - size = ULONG_MAX - bank->start; - } -#endif - - bank->size = size & PAGE_MASK; - - /* - * Check whether this memory region has non-zero size or - * invalid node number. - */ - if (bank->size == 0) - return -EINVAL; - - meminfo.nr_banks++; - return 0; -} - -/* - * Pick out the memory size. We look for mem=size@start, - * where start and size are "size[KkMm]" - */ -static int __init early_mem(char *p) -{ - static int usermem __initdata = 0; - unsigned long size; - phys_addr_t start; - char *endp; - - /* - * If the user specifies memory size, we - * blow away any automatically generated - * size. - */ - if (usermem == 0) { - usermem = 1; - meminfo.nr_banks = 0; - } - - start = PHYS_OFFSET; - size = memparse(p, &endp); - if (*endp == '@') - start = memparse(endp + 1, NULL); - - arm_add_memory(start, size); - - return 0; -} -early_param("mem", early_mem); - -static void __init -setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz) -{ -#ifdef CONFIG_BLK_DEV_RAM - extern int rd_size, rd_image_start, rd_prompt, rd_doload; - - rd_image_start = image_start; - rd_prompt = prompt; - rd_doload = doload; - - if (rd_sz) - rd_size = rd_sz; -#endif -} - -static void __init request_standard_resources(struct machine_desc *mdesc) -{ - struct memblock_region *region; - struct resource *res; - - kernel_code.start = virt_to_phys(_text); - kernel_code.end = virt_to_phys(_etext - 1); - kernel_data.start = virt_to_phys(_sdata); - kernel_data.end = virt_to_phys(_end - 1); - - for_each_memblock(memory, region) { - res = alloc_bootmem_low(sizeof(*res)); - res->name = "System RAM"; - res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region)); - res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; - - request_resource(&iomem_resource, res); - - if (kernel_code.start >= res->start && - kernel_code.end <= res->end) - request_resource(res, &kernel_code); - if (kernel_data.start >= res->start && - kernel_data.end <= res->end) - request_resource(res, &kernel_data); - } - - if (mdesc->video_start) { - video_ram.start = mdesc->video_start; - video_ram.end = mdesc->video_end; - request_resource(&iomem_resource, &video_ram); - } - - /* - * Some machines don't have the possibility of ever - * possessing lp0, lp1 or lp2 - */ - if (mdesc->reserve_lp0) - request_resource(&ioport_resource, &lp0); - if (mdesc->reserve_lp1) - request_resource(&ioport_resource, &lp1); - if (mdesc->reserve_lp2) - request_resource(&ioport_resource, &lp2); -} - -/* - * Tag parsing. - * - * This is the new way of passing data to the kernel at boot time. Rather - * than passing a fixed inflexible structure to the kernel, we pass a list - * of variable-sized tags to the kernel. The first tag must be a ATAG_CORE - * tag for the list to be recognised (to distinguish the tagged list from - * a param_struct). The list is terminated with a zero-length tag (this tag - * is not parsed in any way). - */ -static int __init parse_tag_core(const struct tag *tag) -{ - if (tag->hdr.size > 2) { - if ((tag->u.core.flags & 1) == 0) - root_mountflags &= ~MS_RDONLY; - ROOT_DEV = old_decode_dev(tag->u.core.rootdev); - } - return 0; -} - -__tagtable(ATAG_CORE, parse_tag_core); - -static int __init parse_tag_mem32(const struct tag *tag) -{ - return arm_add_memory(tag->u.mem.start, tag->u.mem.size); -} - -__tagtable(ATAG_MEM, parse_tag_mem32); - -#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) -struct screen_info screen_info = { - .orig_video_lines = 30, - .orig_video_cols = 80, - .orig_video_mode = 0, - .orig_video_ega_bx = 0, - .orig_video_isVGA = 1, - .orig_video_points = 8 -}; - -static int __init parse_tag_videotext(const struct tag *tag) -{ - screen_info.orig_x = tag->u.videotext.x; - screen_info.orig_y = tag->u.videotext.y; - screen_info.orig_video_page = tag->u.videotext.video_page; - screen_info.orig_video_mode = tag->u.videotext.video_mode; - screen_info.orig_video_cols = tag->u.videotext.video_cols; - screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx; - screen_info.orig_video_lines = tag->u.videotext.video_lines; - screen_info.orig_video_isVGA = tag->u.videotext.video_isvga; - screen_info.orig_video_points = tag->u.videotext.video_points; - return 0; -} - -__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext); -#endif - -static int __init parse_tag_ramdisk(const struct tag *tag) -{ - setup_ramdisk((tag->u.ramdisk.flags & 1) == 0, - (tag->u.ramdisk.flags & 2) == 0, - tag->u.ramdisk.start, tag->u.ramdisk.size); - return 0; -} - -__tagtable(ATAG_RAMDISK, parse_tag_ramdisk); - -static int __init parse_tag_serialnr(const struct tag *tag) -{ - system_serial_low = tag->u.serialnr.low; - system_serial_high = tag->u.serialnr.high; - return 0; -} - -__tagtable(ATAG_SERIAL, parse_tag_serialnr); - -static int __init parse_tag_revision(const struct tag *tag) -{ - system_rev = tag->u.revision.rev; - return 0; -} - -__tagtable(ATAG_REVISION, parse_tag_revision); - -static int __init parse_tag_cmdline(const struct tag *tag) -{ -#if defined(CONFIG_CMDLINE_EXTEND) - strlcat(default_command_line, " ", COMMAND_LINE_SIZE); - strlcat(default_command_line, tag->u.cmdline.cmdline, - COMMAND_LINE_SIZE); -#elif defined(CONFIG_CMDLINE_FORCE) - pr_warning("Ignoring tag cmdline (using the default kernel command line)\n"); -#else - strlcpy(default_command_line, tag->u.cmdline.cmdline, - COMMAND_LINE_SIZE); -#endif - return 0; -} - -__tagtable(ATAG_CMDLINE, parse_tag_cmdline); - -/* - * Scan the tag table for this tag, and call its parse function. - * The tag table is built by the linker from all the __tagtable - * declarations. - */ -static int __init parse_tag(const struct tag *tag) -{ - extern struct tagtable __tagtable_begin, __tagtable_end; - struct tagtable *t; - - for (t = &__tagtable_begin; t < &__tagtable_end; t++) - if (tag->hdr.tag == t->tag) { - t->parse(tag); - break; - } - - return t < &__tagtable_end; -} - -/* - * Parse all tags in the list, checking both the global and architecture - * specific tag tables. - */ -static void __init parse_tags(const struct tag *t) -{ - for (; t->hdr.size; t = tag_next(t)) - if (!parse_tag(t)) - printk(KERN_WARNING - "Ignoring unrecognised tag 0x%08x\n", - t->hdr.tag); -} - -/* - * This holds our defaults. - */ -static struct init_tags { - struct tag_header hdr1; - struct tag_core core; - struct tag_header hdr2; - struct tag_mem32 mem; - struct tag_header hdr3; -} init_tags __initdata = { - { tag_size(tag_core), ATAG_CORE }, - { 1, PAGE_SIZE, 0xff }, - { tag_size(tag_mem32), ATAG_MEM }, - { MEM_SIZE }, - { 0, ATAG_NONE } -}; - -static int __init customize_machine(void) -{ - /* customizes platform devices, or adds new ones */ - if (machine_desc->init_machine) - machine_desc->init_machine(); - return 0; -} -arch_initcall(customize_machine); - -#ifdef CONFIG_KEXEC -static inline unsigned long long get_total_mem(void) -{ - unsigned long total; - - total = max_low_pfn - min_low_pfn; - return total << PAGE_SHIFT; -} - -/** - * reserve_crashkernel() - reserves memory are for crash kernel - * - * This function reserves memory area given in "crashkernel=" kernel command - * line parameter. The memory reserved is used by a dump capture kernel when - * primary kernel is crashing. - */ -static void __init reserve_crashkernel(void) -{ - unsigned long long crash_size, crash_base; - unsigned long long total_mem; - int ret; - - total_mem = get_total_mem(); - ret = parse_crashkernel(boot_command_line, total_mem, - &crash_size, &crash_base); - if (ret) - return; - - ret = reserve_bootmem(crash_base, crash_size, BOOTMEM_EXCLUSIVE); - if (ret < 0) { - printk(KERN_WARNING "crashkernel reservation failed - " - "memory is in use (0x%lx)\n", (unsigned long)crash_base); - return; - } - - printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " - "for crashkernel (System RAM: %ldMB)\n", - (unsigned long)(crash_size >> 20), - (unsigned long)(crash_base >> 20), - (unsigned long)(total_mem >> 20)); - - crashk_res.start = crash_base; - crashk_res.end = crash_base + crash_size - 1; - insert_resource(&iomem_resource, &crashk_res); -} -#else -static inline void reserve_crashkernel(void) {} -#endif /* CONFIG_KEXEC */ - -static void __init squash_mem_tags(struct tag *tag) -{ - for (; tag->hdr.size; tag = tag_next(tag)) - if (tag->hdr.tag == ATAG_MEM) - tag->hdr.tag = ATAG_NONE; -} - -static struct machine_desc * __init setup_machine_tags(unsigned int nr) -{ - struct tag *tags = (struct tag *)&init_tags; - struct machine_desc *mdesc = NULL, *p; - char *from = default_command_line; - - init_tags.mem.start = PHYS_OFFSET; - - /* - * locate machine in the list of supported machines. - */ - for_each_machine_desc(p) - if (nr == p->nr) { - printk("Machine: %s\n", p->name); - mdesc = p; - break; - } - - if (!mdesc) { - early_print("\nError: unrecognized/unsupported machine ID" - " (r1 = 0x%08x).\n\n", nr); - dump_machine_table(); /* does not return */ - } - - if (__atags_pointer) - tags = phys_to_virt(__atags_pointer); - else if (mdesc->atag_offset) - tags = (void *)(PAGE_OFFSET + mdesc->atag_offset); - -#if defined(CONFIG_DEPRECATED_PARAM_STRUCT) - /* - * If we have the old style parameters, convert them to - * a tag list. - */ - if (tags->hdr.tag != ATAG_CORE) - convert_to_tag_list(tags); -#endif - - if (tags->hdr.tag != ATAG_CORE) { -#if defined(CONFIG_OF) - /* - * If CONFIG_OF is set, then assume this is a reasonably - * modern system that should pass boot parameters - */ - early_print("Warning: Neither atags nor dtb found\n"); -#endif - tags = (struct tag *)&init_tags; - } - - if (mdesc->fixup) - mdesc->fixup(tags, &from, &meminfo); - - if (tags->hdr.tag == ATAG_CORE) { - if (meminfo.nr_banks != 0) - squash_mem_tags(tags); - save_atags(tags); - parse_tags(tags); - } - - /* parse_early_param needs a boot_command_line */ - strlcpy(boot_command_line, from, COMMAND_LINE_SIZE); - - return mdesc; -} - -static int __init meminfo_cmp(const void *_a, const void *_b) -{ - const struct membank *a = _a, *b = _b; - long cmp = bank_pfn_start(a) - bank_pfn_start(b); - return cmp < 0 ? -1 : cmp > 0 ? 1 : 0; -} - -void __init setup_arch(char **cmdline_p) -{ - struct machine_desc *mdesc; - - setup_processor(); - mdesc = setup_machine_fdt(__atags_pointer); - if (!mdesc) - mdesc = setup_machine_tags(machine_arch_type); - machine_desc = mdesc; - machine_name = mdesc->name; - -#ifdef CONFIG_ZONE_DMA - if (mdesc->dma_zone_size) { - extern unsigned long arm_dma_zone_size; - arm_dma_zone_size = mdesc->dma_zone_size; - } -#endif - if (mdesc->restart_mode) - reboot_setup(&mdesc->restart_mode); - - init_mm.start_code = (unsigned long) _text; - init_mm.end_code = (unsigned long) _etext; - init_mm.end_data = (unsigned long) _edata; - init_mm.brk = (unsigned long) _end; - - /* populate cmd_line too for later use, preserving boot_command_line */ - strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE); - *cmdline_p = cmd_line; - - parse_early_param(); - - sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL); - sanity_check_meminfo(); - arm_memblock_init(&meminfo, mdesc); - - paging_init(mdesc); - request_standard_resources(mdesc); - - if (mdesc->restart) - arm_pm_restart = mdesc->restart; - - unflatten_device_tree(); - -#ifdef CONFIG_SMP - if (is_smp()) - smp_init_cpus(); -#endif - reserve_crashkernel(); - - tcm_init(); - -#ifdef CONFIG_MULTI_IRQ_HANDLER - handle_arch_irq = mdesc->handle_irq; -#endif - -#ifdef CONFIG_VT -#if defined(CONFIG_VGA_CONSOLE) - conswitchp = &vga_con; -#elif defined(CONFIG_DUMMY_CONSOLE) - conswitchp = &dummy_con; -#endif -#endif - - if (mdesc->init_early) - mdesc->init_early(); -} - - -static int __init topology_init(void) -{ - int cpu; - - for_each_possible_cpu(cpu) { - struct cpuinfo_arm *cpuinfo = &per_cpu(cpu_data, cpu); - cpuinfo->cpu.hotpluggable = 1; - register_cpu(&cpuinfo->cpu, cpu); - } - - return 0; -} -subsys_initcall(topology_init); - -#ifdef CONFIG_HAVE_PROC_CPU -static int __init proc_cpu_init(void) -{ - struct proc_dir_entry *res; - - res = proc_mkdir("cpu", NULL); - if (!res) - return -ENOMEM; - return 0; -} -fs_initcall(proc_cpu_init); -#endif - -static const char *hwcap_str[] = { - "swp", - "half", - "thumb", - "26bit", - "fastmult", - "fpa", - "vfp", - "edsp", - "java", - "iwmmxt", - "crunch", - "thumbee", - "neon", - "vfpv3", - "vfpv3d16", - "tls", - "vfpv4", - "idiva", - "idivt", - NULL -}; - -static int c_show(struct seq_file *m, void *v) -{ - int i; - - seq_printf(m, "Processor\t: %s rev %d (%s)\n", - cpu_name, read_cpuid_id() & 15, elf_platform); - -#if defined(CONFIG_SMP) - for_each_online_cpu(i) { - /* - * glibc reads /proc/cpuinfo to determine the number of - * online processors, looking for lines beginning with - * "processor". Give glibc what it expects. - */ - seq_printf(m, "processor\t: %d\n", i); - seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n", - per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ), - (per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100); - } -#else /* CONFIG_SMP */ - seq_printf(m, "BogoMIPS\t: %lu.%02lu\n", - loops_per_jiffy / (500000/HZ), - (loops_per_jiffy / (5000/HZ)) % 100); -#endif - - /* dump out the processor features */ - seq_puts(m, "Features\t: "); - - for (i = 0; hwcap_str[i]; i++) - if (elf_hwcap & (1 << i)) - seq_printf(m, "%s ", hwcap_str[i]); - - seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24); - seq_printf(m, "CPU architecture: %s\n", proc_arch[cpu_architecture()]); - - if ((read_cpuid_id() & 0x0008f000) == 0x00000000) { - /* pre-ARM7 */ - seq_printf(m, "CPU part\t: %07x\n", read_cpuid_id() >> 4); - } else { - if ((read_cpuid_id() & 0x0008f000) == 0x00007000) { - /* ARM7 */ - seq_printf(m, "CPU variant\t: 0x%02x\n", - (read_cpuid_id() >> 16) & 127); - } else { - /* post-ARM7 */ - seq_printf(m, "CPU variant\t: 0x%x\n", - (read_cpuid_id() >> 20) & 15); - } - seq_printf(m, "CPU part\t: 0x%03x\n", - (read_cpuid_id() >> 4) & 0xfff); - } - seq_printf(m, "CPU revision\t: %d\n", read_cpuid_id() & 15); - - seq_puts(m, "\n"); - - seq_printf(m, "Hardware\t: %s\n", machine_name); - seq_printf(m, "Revision\t: %04x\n", system_rev); - seq_printf(m, "Serial\t\t: %08x%08x\n", - system_serial_high, system_serial_low); - - return 0; -} - -static void *c_start(struct seq_file *m, loff_t *pos) -{ - return *pos < 1 ? (void *)1 : NULL; -} - -static void *c_next(struct seq_file *m, void *v, loff_t *pos) -{ - ++*pos; - return NULL; -} - -static void c_stop(struct seq_file *m, void *v) -{ -} - -const struct seq_operations cpuinfo_op = { - .start = c_start, - .next = c_next, - .stop = c_stop, - .show = c_show -}; diff --git a/ANDROID_3.4.5/arch/arm/kernel/smp.c b/ANDROID_3.4.5/arch/arm/kernel/smp.c deleted file mode 100644 index f30d6832..00000000 --- a/ANDROID_3.4.5/arch/arm/kernel/smp.c +++ /dev/null @@ -1,670 +0,0 @@ -/* - * linux/arch/arm/kernel/smp.c - * - * Copyright (C) 2002 ARM Limited, All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/init.h> -#include <linux/spinlock.h> -#include <linux/sched.h> -#include <linux/interrupt.h> -#include <linux/cache.h> -#include <linux/profile.h> -#include <linux/errno.h> -#include <linux/mm.h> -#include <linux/err.h> -#include <linux/cpu.h> -#include <linux/smp.h> -#include <linux/seq_file.h> -#include <linux/irq.h> -#include <linux/percpu.h> -#include <linux/clockchips.h> -#include <linux/completion.h> - -#include <linux/atomic.h> -#include <asm/cacheflush.h> -#include <asm/cpu.h> -#include <asm/cputype.h> -#include <asm/exception.h> -#include <asm/idmap.h> -#include <asm/topology.h> -#include <asm/mmu_context.h> -#include <asm/pgtable.h> -#include <asm/pgalloc.h> -#include <asm/processor.h> -#include <asm/sections.h> -#include <asm/tlbflush.h> -#include <asm/ptrace.h> -#include <asm/localtimer.h> -#include <asm/smp_plat.h> - -/* - * as from 2.5, kernels no longer have an init_tasks structure - * so we need some other way of telling a new secondary core - * where to place its SVC stack - */ -struct secondary_data secondary_data; - -enum ipi_msg_type { - IPI_TIMER = 2, - IPI_RESCHEDULE, - IPI_CALL_FUNC, - IPI_CALL_FUNC_SINGLE, - IPI_CPU_STOP, - IPI_CPU_BACKTRACE, -}; - -static DECLARE_COMPLETION(cpu_running); - -int __cpuinit __cpu_up(unsigned int cpu) -{ - struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu); - struct task_struct *idle = ci->idle; - int ret; - - /* - * Spawn a new process manually, if not already done. - * Grab a pointer to its task struct so we can mess with it - */ - if (!idle) { - idle = fork_idle(cpu); - if (IS_ERR(idle)) { - printk(KERN_ERR "CPU%u: fork() failed\n", cpu); - return PTR_ERR(idle); - } - ci->idle = idle; - } else { - /* - * Since this idle thread is being re-used, call - * init_idle() to reinitialize the thread structure. - */ - init_idle(idle, cpu); - } - - /* - * We need to tell the secondary core where to find - * its stack and the page tables. - */ - secondary_data.stack = task_stack_page(idle) + THREAD_START_SP; - secondary_data.pgdir = virt_to_phys(idmap_pgd); - secondary_data.swapper_pg_dir = virt_to_phys(swapper_pg_dir); - __cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data)); - outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1)); - - /* - * Now bring the CPU into our world. - */ - ret = boot_secondary(cpu, idle); - if (ret == 0) { - /* - * CPU was successfully started, wait for it - * to come online or time out. - */ - wait_for_completion_timeout(&cpu_running, - msecs_to_jiffies(1000)); - - if (!cpu_online(cpu)) { - pr_crit("CPU%u: failed to come online\n", cpu); - ret = -EIO; - } - } else { - pr_err("CPU%u: failed to boot: %d\n", cpu, ret); - } - - secondary_data.stack = NULL; - secondary_data.pgdir = 0; - - return ret; -} - -#ifdef CONFIG_HOTPLUG_CPU -static void percpu_timer_stop(void); - -/* - * __cpu_disable runs on the processor to be shutdown. - */ -int __cpu_disable(void) -{ - unsigned int cpu = smp_processor_id(); - struct task_struct *p; - int ret; - - ret = platform_cpu_disable(cpu); - if (ret) - return ret; - - /* - * Take this CPU offline. Once we clear this, we can't return, - * and we must not schedule until we're ready to give up the cpu. - */ - set_cpu_online(cpu, false); - - /* - * OK - migrate IRQs away from this CPU - */ - migrate_irqs(); - - /* - * Stop the local timer for this CPU. - */ - percpu_timer_stop(); - - /* - * Flush user cache and TLB mappings, and then remove this CPU - * from the vm mask set of all processes. - */ - flush_cache_all(); - local_flush_tlb_all(); - - read_lock(&tasklist_lock); - for_each_process(p) { - if (p->mm) - cpumask_clear_cpu(cpu, mm_cpumask(p->mm)); - } - read_unlock(&tasklist_lock); - - return 0; -} - -static DECLARE_COMPLETION(cpu_died); - -/* - * called on the thread which is asking for a CPU to be shutdown - - * waits until shutdown has completed, or it is timed out. - */ -void __cpu_die(unsigned int cpu) -{ - if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) { - pr_err("CPU%u: cpu didn't die\n", cpu); - return; - } - printk(KERN_NOTICE "CPU%u: shutdown\n", cpu); - - if (!platform_cpu_kill(cpu)) - printk("CPU%u: unable to kill\n", cpu); -} - -/* - * Called from the idle thread for the CPU which has been shutdown. - * - * Note that we disable IRQs here, but do not re-enable them - * before returning to the caller. This is also the behaviour - * of the other hotplug-cpu capable cores, so presumably coming - * out of idle fixes this. - */ -void __ref cpu_die(void) -{ - unsigned int cpu = smp_processor_id(); - - idle_task_exit(); - - local_irq_disable(); - mb(); - - /* Tell __cpu_die() that this CPU is now safe to dispose of */ - complete(&cpu_died); - - /* - * actual CPU shutdown procedure is at least platform (if not - * CPU) specific. - */ - platform_cpu_die(cpu); - - /* - * Do not return to the idle loop - jump back to the secondary - * cpu initialisation. There's some initialisation which needs - * to be repeated to undo the effects of taking the CPU offline. - */ - __asm__("mov sp, %0\n" - " mov fp, #0\n" - " b secondary_start_kernel" - : - : "r" (task_stack_page(current) + THREAD_SIZE - 8)); -} -#endif /* CONFIG_HOTPLUG_CPU */ - -/* - * Called by both boot and secondaries to move global data into - * per-processor storage. - */ -static void __cpuinit smp_store_cpu_info(unsigned int cpuid) -{ - struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid); - - cpu_info->loops_per_jiffy = loops_per_jiffy; - - store_cpu_topology(cpuid); -} - -static void percpu_timer_setup(void); - -/* - * This is the secondary CPU boot entry. We're using this CPUs - * idle thread stack, but a set of temporary page tables. - */ -asmlinkage void __cpuinit secondary_start_kernel(void) -{ - struct mm_struct *mm = &init_mm; - unsigned int cpu = smp_processor_id(); - - /* - * All kernel threads share the same mm context; grab a - * reference and switch to it. - */ - atomic_inc(&mm->mm_count); - current->active_mm = mm; - cpumask_set_cpu(cpu, mm_cpumask(mm)); - cpu_switch_mm(mm->pgd, mm); - enter_lazy_tlb(mm, current); - local_flush_tlb_all(); - - printk("CPU%u: Booted secondary processor\n", cpu); - - cpu_init(); - preempt_disable(); - trace_hardirqs_off(); - - /* - * Give the platform a chance to do its own initialisation. - */ - platform_secondary_init(cpu); - - notify_cpu_starting(cpu); - - calibrate_delay(); - - smp_store_cpu_info(cpu); - - /* - * OK, now it's safe to let the boot CPU continue. Wait for - * the CPU migration code to notice that the CPU is online - * before we continue - which happens after __cpu_up returns. - */ - set_cpu_online(cpu, true); - complete(&cpu_running); - - /* - * Setup the percpu timer for this CPU. - */ - percpu_timer_setup(); - - local_irq_enable(); - local_fiq_enable(); - - /* - * OK, it's off to the idle thread for us - */ - cpu_idle(); -} - -void __init smp_cpus_done(unsigned int max_cpus) -{ - int cpu; - unsigned long bogosum = 0; - - for_each_online_cpu(cpu) - bogosum += per_cpu(cpu_data, cpu).loops_per_jiffy; - - printk(KERN_INFO "SMP: Total of %d processors activated " - "(%lu.%02lu BogoMIPS).\n", - num_online_cpus(), - bogosum / (500000/HZ), - (bogosum / (5000/HZ)) % 100); -} - -void __init smp_prepare_boot_cpu(void) -{ - unsigned int cpu = smp_processor_id(); - - per_cpu(cpu_data, cpu).idle = current; -} - -void __init smp_prepare_cpus(unsigned int max_cpus) -{ - unsigned int ncores = num_possible_cpus(); - - init_cpu_topology(); - - smp_store_cpu_info(smp_processor_id()); - - /* - * are we trying to boot more cores than exist? - */ - if (max_cpus > ncores) - max_cpus = ncores; - if (ncores > 1 && max_cpus) { - /* - * Enable the local timer or broadcast device for the - * boot CPU, but only if we have more than one CPU. - */ - percpu_timer_setup(); - - /* - * Initialise the present map, which describes the set of CPUs - * actually populated at the present time. A platform should - * re-initialize the map in platform_smp_prepare_cpus() if - * present != possible (e.g. physical hotplug). - */ - init_cpu_present(cpu_possible_mask); - - /* - * Initialise the SCU if there are more than one CPU - * and let them know where to start. - */ - platform_smp_prepare_cpus(max_cpus); - } -} - -static void (*smp_cross_call)(const struct cpumask *, unsigned int); - -void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int)) -{ - smp_cross_call = fn; -} - -void arch_send_call_function_ipi_mask(const struct cpumask *mask) -{ - smp_cross_call(mask, IPI_CALL_FUNC); -} - -void arch_send_call_function_single_ipi(int cpu) -{ - smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE); -} - -static const char *ipi_types[NR_IPI] = { -#define S(x,s) [x - IPI_TIMER] = s - S(IPI_TIMER, "Timer broadcast interrupts"), - S(IPI_RESCHEDULE, "Rescheduling interrupts"), - S(IPI_CALL_FUNC, "Function call interrupts"), - S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"), - S(IPI_CPU_STOP, "CPU stop interrupts"), - S(IPI_CPU_BACKTRACE, "CPU backtrace"), -}; - -void show_ipi_list(struct seq_file *p, int prec) -{ - unsigned int cpu, i; - - for (i = 0; i < NR_IPI; i++) { - seq_printf(p, "%*s%u: ", prec - 1, "IPI", i); - - for_each_present_cpu(cpu) - seq_printf(p, "%10u ", - __get_irq_stat(cpu, ipi_irqs[i])); - - seq_printf(p, " %s\n", ipi_types[i]); - } -} - -u64 smp_irq_stat_cpu(unsigned int cpu) -{ - u64 sum = 0; - int i; - - for (i = 0; i < NR_IPI; i++) - sum += __get_irq_stat(cpu, ipi_irqs[i]); - - return sum; -} - -/* - * Timer (local or broadcast) support - */ -static DEFINE_PER_CPU(struct clock_event_device, percpu_clockevent); - -static void ipi_timer(void) -{ - struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent); - evt->event_handler(evt); -} - -#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST -static void smp_timer_broadcast(const struct cpumask *mask) -{ - smp_cross_call(mask, IPI_TIMER); -} -#else -#define smp_timer_broadcast NULL -#endif - -static void broadcast_timer_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ -} - -static void __cpuinit broadcast_timer_setup(struct clock_event_device *evt) -{ - evt->name = "dummy_timer"; - evt->features = CLOCK_EVT_FEAT_ONESHOT | - CLOCK_EVT_FEAT_PERIODIC | - CLOCK_EVT_FEAT_DUMMY; - evt->rating = 400; - evt->mult = 1; - evt->set_mode = broadcast_timer_set_mode; - - clockevents_register_device(evt); -} - -static struct local_timer_ops *lt_ops; - -#ifdef CONFIG_LOCAL_TIMERS -int local_timer_register(struct local_timer_ops *ops) -{ - if (lt_ops) - return -EBUSY; - - lt_ops = ops; - return 0; -} -#endif - -static void __cpuinit percpu_timer_setup(void) -{ - unsigned int cpu = smp_processor_id(); - struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu); - - evt->cpumask = cpumask_of(cpu); - evt->broadcast = smp_timer_broadcast; - - if (!lt_ops || lt_ops->setup(evt)) - broadcast_timer_setup(evt); -} - -#ifdef CONFIG_HOTPLUG_CPU -/* - * The generic clock events code purposely does not stop the local timer - * on CPU_DEAD/CPU_DEAD_FROZEN hotplug events, so we have to do it - * manually here. - */ -static void percpu_timer_stop(void) -{ - unsigned int cpu = smp_processor_id(); - struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu); - - if (lt_ops) - lt_ops->stop(evt); -} -#endif - -static DEFINE_RAW_SPINLOCK(stop_lock); - -/* - * ipi_cpu_stop - handle IPI from smp_send_stop() - */ -static void ipi_cpu_stop(unsigned int cpu) -{ - if (system_state == SYSTEM_BOOTING || - system_state == SYSTEM_RUNNING) { - raw_spin_lock(&stop_lock); - printk(KERN_CRIT "CPU%u: stopping\n", cpu); - dump_stack(); - raw_spin_unlock(&stop_lock); - } - - set_cpu_online(cpu, false); - - local_fiq_disable(); - local_irq_disable(); - - while (1) - cpu_relax(); -} - -static cpumask_t backtrace_mask; -static DEFINE_RAW_SPINLOCK(backtrace_lock); - -/* "in progress" flag of arch_trigger_all_cpu_backtrace */ -static unsigned long backtrace_flag; - -void smp_send_all_cpu_backtrace(void) -{ - unsigned int this_cpu = smp_processor_id(); - int i; - - if (test_and_set_bit(0, &backtrace_flag)) - /* - * If there is already a trigger_all_cpu_backtrace() in progress - * (backtrace_flag == 1), don't output double cpu dump infos. - */ - return; - - cpumask_copy(&backtrace_mask, cpu_online_mask); - cpu_clear(this_cpu, backtrace_mask); - - pr_info("Backtrace for cpu %d (current):\n", this_cpu); - dump_stack(); - - pr_info("\nsending IPI to all other CPUs:\n"); - smp_cross_call(&backtrace_mask, IPI_CPU_BACKTRACE); - - /* Wait for up to 10 seconds for all other CPUs to do the backtrace */ - for (i = 0; i < 10 * 1000; i++) { - if (cpumask_empty(&backtrace_mask)) - break; - mdelay(1); - } - - clear_bit(0, &backtrace_flag); - smp_mb__after_clear_bit(); -} - -/* - * ipi_cpu_backtrace - handle IPI from smp_send_all_cpu_backtrace() - */ -static void ipi_cpu_backtrace(unsigned int cpu, struct pt_regs *regs) -{ - if (cpu_isset(cpu, backtrace_mask)) { - raw_spin_lock(&backtrace_lock); - pr_warning("IPI backtrace for cpu %d\n", cpu); - show_regs(regs); - raw_spin_unlock(&backtrace_lock); - cpu_clear(cpu, backtrace_mask); - } -} - -/* - * Main handler for inter-processor interrupts - */ -asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs) -{ - handle_IPI(ipinr, regs); -} - -void handle_IPI(int ipinr, struct pt_regs *regs) -{ - unsigned int cpu = smp_processor_id(); - struct pt_regs *old_regs = set_irq_regs(regs); - - if (ipinr >= IPI_TIMER && ipinr < IPI_TIMER + NR_IPI) - __inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_TIMER]); - - switch (ipinr) { - case IPI_TIMER: - irq_enter(); - ipi_timer(); - irq_exit(); - break; - - case IPI_RESCHEDULE: - scheduler_ipi(); - break; - - case IPI_CALL_FUNC: - irq_enter(); - generic_smp_call_function_interrupt(); - irq_exit(); - break; - - case IPI_CALL_FUNC_SINGLE: - irq_enter(); - generic_smp_call_function_single_interrupt(); - irq_exit(); - break; - - case IPI_CPU_STOP: - irq_enter(); - ipi_cpu_stop(cpu); - irq_exit(); - break; - - case IPI_CPU_BACKTRACE: - ipi_cpu_backtrace(cpu, regs); - break; - - default: - printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n", - cpu, ipinr); - break; - } - set_irq_regs(old_regs); -} - -void smp_send_reschedule(int cpu) -{ - smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); -} - -#ifdef CONFIG_HOTPLUG_CPU -static void smp_kill_cpus(cpumask_t *mask) -{ - unsigned int cpu; - for_each_cpu(cpu, mask) - platform_cpu_kill(cpu); -} -#else -static void smp_kill_cpus(cpumask_t *mask) { } -#endif - -void smp_send_stop(void) -{ - unsigned long timeout; - struct cpumask mask; - - cpumask_copy(&mask, cpu_online_mask); - cpumask_clear_cpu(smp_processor_id(), &mask); - smp_cross_call(&mask, IPI_CPU_STOP); - - /* Wait up to one second for other CPUs to stop */ - timeout = USEC_PER_SEC; - while (num_online_cpus() > 1 && timeout--) - udelay(1); - - if (num_online_cpus() > 1) - pr_warning("SMP: failed to stop secondary CPUs\n"); - - smp_kill_cpus(&mask); -} - -/* - * not supported here - */ -int setup_profiling_timer(unsigned int multiplier) -{ - return -EINVAL; -} diff --git a/ANDROID_3.4.5/drivers/cpufreq/cpufreq.c b/ANDROID_3.4.5/drivers/cpufreq/cpufreq.c deleted file mode 100644 index 7f2f149a..00000000 --- a/ANDROID_3.4.5/drivers/cpufreq/cpufreq.c +++ /dev/null @@ -1,1939 +0,0 @@ -/* - * linux/drivers/cpufreq/cpufreq.c - * - * Copyright (C) 2001 Russell King - * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de> - * - * Oct 2005 - Ashok Raj <ashok.raj@intel.com> - * Added handling for CPU hotplug - * Feb 2006 - Jacob Shin <jacob.shin@amd.com> - * Fix handling for CPU hotplug -- affected CPUs - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/notifier.h> -#include <linux/cpufreq.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/spinlock.h> -#include <linux/device.h> -#include <linux/slab.h> -#include <linux/cpu.h> -#include <linux/completion.h> -#include <linux/mutex.h> -#include <linux/syscore_ops.h> - -#include <trace/events/power.h> - -/** - * The "cpufreq driver" - the arch- or hardware-dependent low - * level driver of CPUFreq support, and its spinlock. This lock - * also protects the cpufreq_cpu_data array. - */ -static struct cpufreq_driver *cpufreq_driver; -static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); -#ifdef CONFIG_HOTPLUG_CPU -/* This one keeps track of the previously set governor of a removed CPU */ -static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); -#endif -static DEFINE_SPINLOCK(cpufreq_driver_lock); - -/* - * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure - * all cpufreq/hotplug/workqueue/etc related lock issues. - * - * The rules for this semaphore: - * - Any routine that wants to read from the policy structure will - * do a down_read on this semaphore. - * - Any routine that will write to the policy structure and/or may take away - * the policy altogether (eg. CPU hotplug), will hold this lock in write - * mode before doing so. - * - * Additional rules: - * - All holders of the lock should check to make sure that the CPU they - * are concerned with are online after they get the lock. - * - Governor routines that can be called in cpufreq hotplug path should not - * take this sem as top level hotplug notifier handler takes this. - * - Lock should not be held across - * __cpufreq_governor(data, CPUFREQ_GOV_STOP); - */ -static DEFINE_PER_CPU(int, cpufreq_policy_cpu); -static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem); - -#define lock_policy_rwsem(mode, cpu) \ -static int lock_policy_rwsem_##mode \ -(int cpu) \ -{ \ - int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \ - BUG_ON(policy_cpu == -1); \ - down_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \ - if (unlikely(!cpu_online(cpu))) { \ - up_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \ - return -1; \ - } \ - \ - return 0; \ -} - -lock_policy_rwsem(read, cpu); - -lock_policy_rwsem(write, cpu); - -static void unlock_policy_rwsem_read(int cpu) -{ - int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); - BUG_ON(policy_cpu == -1); - up_read(&per_cpu(cpu_policy_rwsem, policy_cpu)); -} - -static void unlock_policy_rwsem_write(int cpu) -{ - int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); - BUG_ON(policy_cpu == -1); - up_write(&per_cpu(cpu_policy_rwsem, policy_cpu)); -} - - -/* internal prototypes */ -static int __cpufreq_governor(struct cpufreq_policy *policy, - unsigned int event); -static unsigned int __cpufreq_get(unsigned int cpu); -static void handle_update(struct work_struct *work); - -/** - * Two notifier lists: the "policy" list is involved in the - * validation process for a new CPU frequency policy; the - * "transition" list for kernel code that needs to handle - * changes to devices when the CPU clock speed changes. - * The mutex locks both lists. - */ -static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list); -static struct srcu_notifier_head cpufreq_transition_notifier_list; - -static bool init_cpufreq_transition_notifier_list_called; -static int __init init_cpufreq_transition_notifier_list(void) -{ - srcu_init_notifier_head(&cpufreq_transition_notifier_list); - init_cpufreq_transition_notifier_list_called = true; - return 0; -} -pure_initcall(init_cpufreq_transition_notifier_list); - -static int off __read_mostly; -int cpufreq_disabled(void) -{ - return off; -} -void disable_cpufreq(void) -{ - off = 1; -} -static LIST_HEAD(cpufreq_governor_list); -static DEFINE_MUTEX(cpufreq_governor_mutex); - -struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) -{ - struct cpufreq_policy *data; - unsigned long flags; - - if (cpu >= nr_cpu_ids) - goto err_out; - - /* get the cpufreq driver */ - spin_lock_irqsave(&cpufreq_driver_lock, flags); - - if (!cpufreq_driver) - goto err_out_unlock; - - if (!try_module_get(cpufreq_driver->owner)) - goto err_out_unlock; - - - /* get the CPU */ - data = per_cpu(cpufreq_cpu_data, cpu); - - if (!data) - goto err_out_put_module; - - if (!kobject_get(&data->kobj)) - goto err_out_put_module; - - spin_unlock_irqrestore(&cpufreq_driver_lock, flags); - return data; - -err_out_put_module: - module_put(cpufreq_driver->owner); -err_out_unlock: - spin_unlock_irqrestore(&cpufreq_driver_lock, flags); -err_out: - return NULL; -} -EXPORT_SYMBOL_GPL(cpufreq_cpu_get); - - -void cpufreq_cpu_put(struct cpufreq_policy *data) -{ - kobject_put(&data->kobj); - module_put(cpufreq_driver->owner); -} -EXPORT_SYMBOL_GPL(cpufreq_cpu_put); - - -/********************************************************************* - * EXTERNALLY AFFECTING FREQUENCY CHANGES * - *********************************************************************/ - -/** - * adjust_jiffies - adjust the system "loops_per_jiffy" - * - * This function alters the system "loops_per_jiffy" for the clock - * speed change. Note that loops_per_jiffy cannot be updated on SMP - * systems as each CPU might be scaled differently. So, use the arch - * per-CPU loops_per_jiffy value wherever possible. - */ -#ifndef CONFIG_SMP -static unsigned long l_p_j_ref; -static unsigned int l_p_j_ref_freq; - -static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) -{ - if (ci->flags & CPUFREQ_CONST_LOOPS) - return; - - if (!l_p_j_ref_freq) { - l_p_j_ref = loops_per_jiffy; - l_p_j_ref_freq = ci->old; - pr_debug("saving %lu as reference value for loops_per_jiffy; " - "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq); - } - if ((val == CPUFREQ_POSTCHANGE && ci->old != ci->new) || - (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) { - loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, - ci->new); - pr_debug("scaling loops_per_jiffy to %lu " - "for frequency %u kHz\n", loops_per_jiffy, ci->new); - } -} -#else -static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) -{ - return; -} -#endif - - -/** - * cpufreq_notify_transition - call notifier chain and adjust_jiffies - * on frequency transition. - * - * This function calls the transition notifiers and the "adjust_jiffies" - * function. It is called twice on all CPU frequency changes that have - * external effects. - */ -void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state) -{ - struct cpufreq_policy *policy; - - BUG_ON(irqs_disabled()); - - freqs->flags = cpufreq_driver->flags; - pr_debug("notification %u of frequency transition to %u kHz\n", - state, freqs->new); - - policy = per_cpu(cpufreq_cpu_data, freqs->cpu); - switch (state) { - - case CPUFREQ_PRECHANGE: - /* detect if the driver reported a value as "old frequency" - * which is not equal to what the cpufreq core thinks is - * "old frequency". - */ - if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { - if ((policy) && (policy->cpu == freqs->cpu) && - (policy->cur) && (policy->cur != freqs->old)) { - pr_debug("Warning: CPU frequency is" - " %u, cpufreq assumed %u kHz.\n", - freqs->old, policy->cur); - freqs->old = policy->cur; - } - } - srcu_notifier_call_chain(&cpufreq_transition_notifier_list, - CPUFREQ_PRECHANGE, freqs); - adjust_jiffies(CPUFREQ_PRECHANGE, freqs); - break; - - case CPUFREQ_POSTCHANGE: - adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); - pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new, - (unsigned long)freqs->cpu); - trace_power_frequency(POWER_PSTATE, freqs->new, freqs->cpu); - trace_cpu_frequency(freqs->new, freqs->cpu); - srcu_notifier_call_chain(&cpufreq_transition_notifier_list, - CPUFREQ_POSTCHANGE, freqs); - if (likely(policy) && likely(policy->cpu == freqs->cpu)) - policy->cur = freqs->new; - break; - } -} -EXPORT_SYMBOL_GPL(cpufreq_notify_transition); - - - -/********************************************************************* - * SYSFS INTERFACE * - *********************************************************************/ - -static struct cpufreq_governor *__find_governor(const char *str_governor) -{ - struct cpufreq_governor *t; - - list_for_each_entry(t, &cpufreq_governor_list, governor_list) - if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN)) - return t; - - return NULL; -} - -/** - * cpufreq_parse_governor - parse a governor string - */ -static int cpufreq_parse_governor(char *str_governor, unsigned int *policy, - struct cpufreq_governor **governor) -{ - int err = -EINVAL; - - if (!cpufreq_driver) - goto out; - - if (cpufreq_driver->setpolicy) { - if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) { - *policy = CPUFREQ_POLICY_PERFORMANCE; - err = 0; - } else if (!strnicmp(str_governor, "powersave", - CPUFREQ_NAME_LEN)) { - *policy = CPUFREQ_POLICY_POWERSAVE; - err = 0; - } - } else if (cpufreq_driver->target) { - struct cpufreq_governor *t; - - mutex_lock(&cpufreq_governor_mutex); - - t = __find_governor(str_governor); - - if (t == NULL) { - int ret; - - mutex_unlock(&cpufreq_governor_mutex); - ret = request_module("cpufreq_%s", str_governor); - mutex_lock(&cpufreq_governor_mutex); - - if (ret == 0) - t = __find_governor(str_governor); - } - - if (t != NULL) { - *governor = t; - err = 0; - } - - mutex_unlock(&cpufreq_governor_mutex); - } -out: - return err; -} - - -/** - * cpufreq_per_cpu_attr_read() / show_##file_name() - - * print out cpufreq information - * - * Write out information from cpufreq_driver->policy[cpu]; object must be - * "unsigned int". - */ - -#define show_one(file_name, object) \ -static ssize_t show_##file_name \ -(struct cpufreq_policy *policy, char *buf) \ -{ \ - return sprintf(buf, "%u\n", policy->object); \ -} - -show_one(cpuinfo_min_freq, cpuinfo.min_freq); -show_one(cpuinfo_max_freq, cpuinfo.max_freq); -show_one(cpuinfo_transition_latency, cpuinfo.transition_latency); -show_one(scaling_min_freq, min); -show_one(scaling_max_freq, max); -show_one(scaling_cur_freq, cur); - -static int __cpufreq_set_policy(struct cpufreq_policy *data, - struct cpufreq_policy *policy); - -/** - * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access - */ -#define store_one(file_name, object) \ -static ssize_t store_##file_name \ -(struct cpufreq_policy *policy, const char *buf, size_t count) \ -{ \ - unsigned int ret = -EINVAL; \ - struct cpufreq_policy new_policy; \ - \ - ret = cpufreq_get_policy(&new_policy, policy->cpu); \ - if (ret) \ - return -EINVAL; \ - \ - ret = sscanf(buf, "%u", &new_policy.object); \ - if (ret != 1) \ - return -EINVAL; \ - \ - ret = __cpufreq_set_policy(policy, &new_policy); \ - policy->user_policy.object = policy->object; \ - \ - return ret ? ret : count; \ -} - -store_one(scaling_min_freq, min); -store_one(scaling_max_freq, max); - -/** - * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware - */ -static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy, - char *buf) -{ - unsigned int cur_freq = __cpufreq_get(policy->cpu); - if (!cur_freq) - return sprintf(buf, "<unknown>"); - return sprintf(buf, "%u\n", cur_freq); -} - - -/** - * show_scaling_governor - show the current policy for the specified CPU - */ -static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf) -{ - if (policy->policy == CPUFREQ_POLICY_POWERSAVE) - return sprintf(buf, "powersave\n"); - else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) - return sprintf(buf, "performance\n"); - else if (policy->governor) - return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", - policy->governor->name); - return -EINVAL; -} - - -/** - * store_scaling_governor - store policy for the specified CPU - */ -static ssize_t store_scaling_governor(struct cpufreq_policy *policy, - const char *buf, size_t count) -{ - unsigned int ret = -EINVAL; - char str_governor[16]; - struct cpufreq_policy new_policy; - - ret = cpufreq_get_policy(&new_policy, policy->cpu); - if (ret) - return ret; - - ret = sscanf(buf, "%15s", str_governor); - if (ret != 1) - return -EINVAL; - - if (cpufreq_parse_governor(str_governor, &new_policy.policy, - &new_policy.governor)) - return -EINVAL; - - /* Do not use cpufreq_set_policy here or the user_policy.max - will be wrongly overridden */ - ret = __cpufreq_set_policy(policy, &new_policy); - - policy->user_policy.policy = policy->policy; - policy->user_policy.governor = policy->governor; - - if (ret) - return ret; - else - return count; -} - -/** - * show_scaling_driver - show the cpufreq driver currently loaded - */ -static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf) -{ - return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", cpufreq_driver->name); -} - -/** - * show_scaling_available_governors - show the available CPUfreq governors - */ -static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy, - char *buf) -{ - ssize_t i = 0; - struct cpufreq_governor *t; - - if (!cpufreq_driver->target) { - i += sprintf(buf, "performance powersave"); - goto out; - } - - list_for_each_entry(t, &cpufreq_governor_list, governor_list) { - if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) - - (CPUFREQ_NAME_LEN + 2))) - goto out; - i += scnprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name); - } -out: - i += sprintf(&buf[i], "\n"); - return i; -} - -static ssize_t show_cpus(const struct cpumask *mask, char *buf) -{ - ssize_t i = 0; - unsigned int cpu; - - for_each_cpu(cpu, mask) { - if (i) - i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " "); - i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu); - if (i >= (PAGE_SIZE - 5)) - break; - } - i += sprintf(&buf[i], "\n"); - return i; -} - -/** - * show_related_cpus - show the CPUs affected by each transition even if - * hw coordination is in use - */ -static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf) -{ - if (cpumask_empty(policy->related_cpus)) - return show_cpus(policy->cpus, buf); - return show_cpus(policy->related_cpus, buf); -} - -/** - * show_affected_cpus - show the CPUs affected by each transition - */ -static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf) -{ - return show_cpus(policy->cpus, buf); -} - -static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy, - const char *buf, size_t count) -{ - unsigned int freq = 0; - unsigned int ret; - - if (!policy->governor || !policy->governor->store_setspeed) - return -EINVAL; - - ret = sscanf(buf, "%u", &freq); - if (ret != 1) - return -EINVAL; - - policy->governor->store_setspeed(policy, freq); - - return count; -} - -static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf) -{ - if (!policy->governor || !policy->governor->show_setspeed) - return sprintf(buf, "<unsupported>\n"); - - return policy->governor->show_setspeed(policy, buf); -} - -/** - * show_scaling_driver - show the current cpufreq HW/BIOS limitation - */ -static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf) -{ - unsigned int limit; - int ret; - if (cpufreq_driver->bios_limit) { - ret = cpufreq_driver->bios_limit(policy->cpu, &limit); - if (!ret) - return sprintf(buf, "%u\n", limit); - } - return sprintf(buf, "%u\n", policy->cpuinfo.max_freq); -} - -cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400); -cpufreq_freq_attr_ro(cpuinfo_min_freq); -cpufreq_freq_attr_ro(cpuinfo_max_freq); -cpufreq_freq_attr_ro(cpuinfo_transition_latency); -cpufreq_freq_attr_ro(scaling_available_governors); -cpufreq_freq_attr_ro(scaling_driver); -cpufreq_freq_attr_ro(scaling_cur_freq); -cpufreq_freq_attr_ro(bios_limit); -cpufreq_freq_attr_ro(related_cpus); -cpufreq_freq_attr_ro(affected_cpus); -cpufreq_freq_attr_rw(scaling_min_freq); -cpufreq_freq_attr_rw(scaling_max_freq); -cpufreq_freq_attr_rw(scaling_governor); -cpufreq_freq_attr_rw(scaling_setspeed); - -static struct attribute *default_attrs[] = { - &cpuinfo_min_freq.attr, - &cpuinfo_max_freq.attr, - &cpuinfo_transition_latency.attr, - &scaling_min_freq.attr, - &scaling_max_freq.attr, - &affected_cpus.attr, - &related_cpus.attr, - &scaling_governor.attr, - &scaling_driver.attr, - &scaling_available_governors.attr, - &scaling_setspeed.attr, - NULL -}; - -struct kobject *cpufreq_global_kobject; -EXPORT_SYMBOL(cpufreq_global_kobject); - -#define to_policy(k) container_of(k, struct cpufreq_policy, kobj) -#define to_attr(a) container_of(a, struct freq_attr, attr) - -static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) -{ - struct cpufreq_policy *policy = to_policy(kobj); - struct freq_attr *fattr = to_attr(attr); - ssize_t ret = -EINVAL; - policy = cpufreq_cpu_get(policy->cpu); - if (!policy) - goto no_policy; - - if (lock_policy_rwsem_read(policy->cpu) < 0) - goto fail; - - if (fattr->show) - ret = fattr->show(policy, buf); - else - ret = -EIO; - - unlock_policy_rwsem_read(policy->cpu); -fail: - cpufreq_cpu_put(policy); -no_policy: - return ret; -} - -static ssize_t store(struct kobject *kobj, struct attribute *attr, - const char *buf, size_t count) -{ - struct cpufreq_policy *policy = to_policy(kobj); - struct freq_attr *fattr = to_attr(attr); - ssize_t ret = -EINVAL; - policy = cpufreq_cpu_get(policy->cpu); - if (!policy) - goto no_policy; - - if (lock_policy_rwsem_write(policy->cpu) < 0) - goto fail; - - if (fattr->store) - ret = fattr->store(policy, buf, count); - else - ret = -EIO; - - unlock_policy_rwsem_write(policy->cpu); -fail: - cpufreq_cpu_put(policy); -no_policy: - return ret; -} - -static void cpufreq_sysfs_release(struct kobject *kobj) -{ - struct cpufreq_policy *policy = to_policy(kobj); - pr_debug("last reference is dropped\n"); - complete(&policy->kobj_unregister); -} - -static const struct sysfs_ops sysfs_ops = { - .show = show, - .store = store, -}; - -static struct kobj_type ktype_cpufreq = { - .sysfs_ops = &sysfs_ops, - .default_attrs = default_attrs, - .release = cpufreq_sysfs_release, -}; - -/* - * Returns: - * Negative: Failure - * 0: Success - * Positive: When we have a managed CPU and the sysfs got symlinked - */ -static int cpufreq_add_dev_policy(unsigned int cpu, - struct cpufreq_policy *policy, - struct device *dev) -{ - int ret = 0; -#ifdef CONFIG_SMP - unsigned long flags; - unsigned int j; -#ifdef CONFIG_HOTPLUG_CPU - struct cpufreq_governor *gov; - - gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu)); - if (gov) { - policy->governor = gov; - pr_debug("Restoring governor %s for cpu %d\n", - policy->governor->name, cpu); - } -#endif - - for_each_cpu(j, policy->cpus) { - struct cpufreq_policy *managed_policy; - - if (cpu == j) - continue; - - /* Check for existing affected CPUs. - * They may not be aware of it due to CPU Hotplug. - * cpufreq_cpu_put is called when the device is removed - * in __cpufreq_remove_dev() - */ - managed_policy = cpufreq_cpu_get(j); - if (unlikely(managed_policy)) { - - /* Set proper policy_cpu */ - unlock_policy_rwsem_write(cpu); - per_cpu(cpufreq_policy_cpu, cpu) = managed_policy->cpu; - - if (lock_policy_rwsem_write(cpu) < 0) { - /* Should not go through policy unlock path */ - if (cpufreq_driver->exit) - cpufreq_driver->exit(policy); - cpufreq_cpu_put(managed_policy); - return -EBUSY; - } - - spin_lock_irqsave(&cpufreq_driver_lock, flags); - cpumask_copy(managed_policy->cpus, policy->cpus); - per_cpu(cpufreq_cpu_data, cpu) = managed_policy; - spin_unlock_irqrestore(&cpufreq_driver_lock, flags); - - pr_debug("CPU already managed, adding link\n"); - ret = sysfs_create_link(&dev->kobj, - &managed_policy->kobj, - "cpufreq"); - if (ret) - cpufreq_cpu_put(managed_policy); - /* - * Success. We only needed to be added to the mask. - * Call driver->exit() because only the cpu parent of - * the kobj needed to call init(). - */ - if (cpufreq_driver->exit) - cpufreq_driver->exit(policy); - - if (!ret) - return 1; - else - return ret; - } - } -#endif - return ret; -} - - -/* symlink affected CPUs */ -static int cpufreq_add_dev_symlink(unsigned int cpu, - struct cpufreq_policy *policy) -{ - unsigned int j; - int ret = 0; - - for_each_cpu(j, policy->cpus) { - struct cpufreq_policy *managed_policy; - struct device *cpu_dev; - - if (j == cpu) - continue; - if (!cpu_online(j)) - continue; - - pr_debug("CPU %u already managed, adding link\n", j); - managed_policy = cpufreq_cpu_get(cpu); - cpu_dev = get_cpu_device(j); - ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj, - "cpufreq"); - if (ret) { - cpufreq_cpu_put(managed_policy); - return ret; - } - } - return ret; -} - -static int cpufreq_add_dev_interface(unsigned int cpu, - struct cpufreq_policy *policy, - struct device *dev) -{ - struct cpufreq_policy new_policy; - struct freq_attr **drv_attr; - unsigned long flags; - int ret = 0; - unsigned int j; - - /* prepare interface data */ - ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, - &dev->kobj, "cpufreq"); - if (ret) - return ret; - - /* set up files for this cpu device */ - drv_attr = cpufreq_driver->attr; - while ((drv_attr) && (*drv_attr)) { - ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); - if (ret) - goto err_out_kobj_put; - drv_attr++; - } - if (cpufreq_driver->get) { - ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr); - if (ret) - goto err_out_kobj_put; - } - if (cpufreq_driver->target) { - ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); - if (ret) - goto err_out_kobj_put; - } - if (cpufreq_driver->bios_limit) { - ret = sysfs_create_file(&policy->kobj, &bios_limit.attr); - if (ret) - goto err_out_kobj_put; - } - - spin_lock_irqsave(&cpufreq_driver_lock, flags); - for_each_cpu(j, policy->cpus) { - if (!cpu_online(j)) - continue; - per_cpu(cpufreq_cpu_data, j) = policy; - per_cpu(cpufreq_policy_cpu, j) = policy->cpu; - } - spin_unlock_irqrestore(&cpufreq_driver_lock, flags); - - ret = cpufreq_add_dev_symlink(cpu, policy); - if (ret) - goto err_out_kobj_put; - - memcpy(&new_policy, policy, sizeof(struct cpufreq_policy)); - /* assure that the starting sequence is run in __cpufreq_set_policy */ - policy->governor = NULL; - - /* set default policy */ - ret = __cpufreq_set_policy(policy, &new_policy); - policy->user_policy.policy = policy->policy; - policy->user_policy.governor = policy->governor; - - if (ret) { - pr_debug("setting policy failed\n"); - if (cpufreq_driver->exit) - cpufreq_driver->exit(policy); - } - return ret; - -err_out_kobj_put: - kobject_put(&policy->kobj); - wait_for_completion(&policy->kobj_unregister); - return ret; -} - - -/** - * cpufreq_add_dev - add a CPU device - * - * Adds the cpufreq interface for a CPU device. - * - * The Oracle says: try running cpufreq registration/unregistration concurrently - * with with cpu hotplugging and all hell will break loose. Tried to clean this - * mess up, but more thorough testing is needed. - Mathieu - */ -static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) -{ - unsigned int cpu = dev->id; - int ret = 0, found = 0; - struct cpufreq_policy *policy; - unsigned long flags; - unsigned int j; -#ifdef CONFIG_HOTPLUG_CPU - int sibling; -#endif - - if (cpu_is_offline(cpu)) - return 0; - - pr_debug("adding CPU %u\n", cpu); - -#ifdef CONFIG_SMP - /* check whether a different CPU already registered this - * CPU because it is in the same boat. */ - policy = cpufreq_cpu_get(cpu); - if (unlikely(policy)) { - cpufreq_cpu_put(policy); - return 0; - } -#endif - - if (!try_module_get(cpufreq_driver->owner)) { - ret = -EINVAL; - goto module_out; - } - - ret = -ENOMEM; - policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL); - if (!policy) - goto nomem_out; - - if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL)) - goto err_free_policy; - - if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL)) - goto err_free_cpumask; - - policy->cpu = cpu; - cpumask_copy(policy->cpus, cpumask_of(cpu)); - - /* Initially set CPU itself as the policy_cpu */ - per_cpu(cpufreq_policy_cpu, cpu) = cpu; - ret = (lock_policy_rwsem_write(cpu) < 0); - WARN_ON(ret); - - init_completion(&policy->kobj_unregister); - INIT_WORK(&policy->update, handle_update); - - /* Set governor before ->init, so that driver could check it */ -#ifdef CONFIG_HOTPLUG_CPU - for_each_online_cpu(sibling) { - struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling); - if (cp && cp->governor && - (cpumask_test_cpu(cpu, cp->related_cpus))) { - policy->governor = cp->governor; - found = 1; - break; - } - } -#endif - if (!found) - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - /* call driver. From then on the cpufreq must be able - * to accept all calls to ->verify and ->setpolicy for this CPU - */ - ret = cpufreq_driver->init(policy); - if (ret) { - pr_debug("initialization failed\n"); - goto err_unlock_policy; - } - policy->user_policy.min = policy->min; - policy->user_policy.max = policy->max; - - blocking_notifier_call_chain(&cpufreq_policy_notifier_list, - CPUFREQ_START, policy); - - ret = cpufreq_add_dev_policy(cpu, policy, dev); - if (ret) { - if (ret > 0) - /* This is a managed cpu, symlink created, - exit with 0 */ - ret = 0; - goto err_unlock_policy; - } - - ret = cpufreq_add_dev_interface(cpu, policy, dev); - if (ret) - goto err_out_unregister; - - unlock_policy_rwsem_write(cpu); - - kobject_uevent(&policy->kobj, KOBJ_ADD); - module_put(cpufreq_driver->owner); - pr_debug("initialization complete\n"); - - return 0; - - -err_out_unregister: - spin_lock_irqsave(&cpufreq_driver_lock, flags); - for_each_cpu(j, policy->cpus) - per_cpu(cpufreq_cpu_data, j) = NULL; - spin_unlock_irqrestore(&cpufreq_driver_lock, flags); - - kobject_put(&policy->kobj); - wait_for_completion(&policy->kobj_unregister); - -err_unlock_policy: - unlock_policy_rwsem_write(cpu); - free_cpumask_var(policy->related_cpus); -err_free_cpumask: - free_cpumask_var(policy->cpus); -err_free_policy: - kfree(policy); -nomem_out: - module_put(cpufreq_driver->owner); -module_out: - return ret; -} - - -/** - * __cpufreq_remove_dev - remove a CPU device - * - * Removes the cpufreq interface for a CPU device. - * Caller should already have policy_rwsem in write mode for this CPU. - * This routine frees the rwsem before returning. - */ -static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) -{ - unsigned int cpu = dev->id; - unsigned long flags; - struct cpufreq_policy *data; - struct kobject *kobj; - struct completion *cmp; -#ifdef CONFIG_SMP - struct device *cpu_dev; - unsigned int j; -#endif - - pr_debug("unregistering CPU %u\n", cpu); - - spin_lock_irqsave(&cpufreq_driver_lock, flags); - data = per_cpu(cpufreq_cpu_data, cpu); - - if (!data) { - spin_unlock_irqrestore(&cpufreq_driver_lock, flags); - unlock_policy_rwsem_write(cpu); - return -EINVAL; - } - per_cpu(cpufreq_cpu_data, cpu) = NULL; - - -#ifdef CONFIG_SMP - /* if this isn't the CPU which is the parent of the kobj, we - * only need to unlink, put and exit - */ - if (unlikely(cpu != data->cpu)) { - pr_debug("removing link\n"); - cpumask_clear_cpu(cpu, data->cpus); - spin_unlock_irqrestore(&cpufreq_driver_lock, flags); - kobj = &dev->kobj; - cpufreq_cpu_put(data); - unlock_policy_rwsem_write(cpu); - sysfs_remove_link(kobj, "cpufreq"); - return 0; - } -#endif - -#ifdef CONFIG_SMP - -#ifdef CONFIG_HOTPLUG_CPU - strncpy(per_cpu(cpufreq_cpu_governor, cpu), data->governor->name, - CPUFREQ_NAME_LEN); -#endif - - /* if we have other CPUs still registered, we need to unlink them, - * or else wait_for_completion below will lock up. Clean the - * per_cpu(cpufreq_cpu_data) while holding the lock, and remove - * the sysfs links afterwards. - */ - if (unlikely(cpumask_weight(data->cpus) > 1)) { - for_each_cpu(j, data->cpus) { - if (j == cpu) - continue; - per_cpu(cpufreq_cpu_data, j) = NULL; - } - } - - spin_unlock_irqrestore(&cpufreq_driver_lock, flags); - - if (unlikely(cpumask_weight(data->cpus) > 1)) { - for_each_cpu(j, data->cpus) { - if (j == cpu) - continue; - pr_debug("removing link for cpu %u\n", j); -#ifdef CONFIG_HOTPLUG_CPU - strncpy(per_cpu(cpufreq_cpu_governor, j), - data->governor->name, CPUFREQ_NAME_LEN); -#endif - cpu_dev = get_cpu_device(j); - kobj = &cpu_dev->kobj; - unlock_policy_rwsem_write(cpu); - sysfs_remove_link(kobj, "cpufreq"); - lock_policy_rwsem_write(cpu); - cpufreq_cpu_put(data); - } - } -#else - spin_unlock_irqrestore(&cpufreq_driver_lock, flags); -#endif - - if (cpufreq_driver->target) - __cpufreq_governor(data, CPUFREQ_GOV_STOP); - - kobj = &data->kobj; - cmp = &data->kobj_unregister; - unlock_policy_rwsem_write(cpu); - kobject_put(kobj); - - /* we need to make sure that the underlying kobj is actually - * not referenced anymore by anybody before we proceed with - * unloading. - */ - pr_debug("waiting for dropping of refcount\n"); - wait_for_completion(cmp); - pr_debug("wait complete\n"); - - lock_policy_rwsem_write(cpu); - if (cpufreq_driver->exit) - cpufreq_driver->exit(data); - unlock_policy_rwsem_write(cpu); - -#ifdef CONFIG_HOTPLUG_CPU - /* when the CPU which is the parent of the kobj is hotplugged - * offline, check for siblings, and create cpufreq sysfs interface - * and symlinks - */ - if (unlikely(cpumask_weight(data->cpus) > 1)) { - /* first sibling now owns the new sysfs dir */ - cpumask_clear_cpu(cpu, data->cpus); - cpufreq_add_dev(get_cpu_device(cpumask_first(data->cpus)), NULL); - - /* finally remove our own symlink */ - lock_policy_rwsem_write(cpu); - __cpufreq_remove_dev(dev, sif); - } -#endif - - free_cpumask_var(data->related_cpus); - free_cpumask_var(data->cpus); - kfree(data); - - return 0; -} - - -static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) -{ - unsigned int cpu = dev->id; - int retval; - - if (cpu_is_offline(cpu)) - return 0; - - if (unlikely(lock_policy_rwsem_write(cpu))) - BUG(); - - retval = __cpufreq_remove_dev(dev, sif); - return retval; -} - - -static void handle_update(struct work_struct *work) -{ - struct cpufreq_policy *policy = - container_of(work, struct cpufreq_policy, update); - unsigned int cpu = policy->cpu; - pr_debug("handle_update for cpu %u called\n", cpu); - cpufreq_update_policy(cpu); -} - -/** - * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble. - * @cpu: cpu number - * @old_freq: CPU frequency the kernel thinks the CPU runs at - * @new_freq: CPU frequency the CPU actually runs at - * - * We adjust to current frequency first, and need to clean up later. - * So either call to cpufreq_update_policy() or schedule handle_update()). - */ -static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, - unsigned int new_freq) -{ - struct cpufreq_freqs freqs; - - pr_debug("Warning: CPU frequency out of sync: cpufreq and timing " - "core thinks of %u, is %u kHz.\n", old_freq, new_freq); - - freqs.cpu = cpu; - freqs.old = old_freq; - freqs.new = new_freq; - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); -} - - -/** - * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur - * @cpu: CPU number - * - * This is the last known freq, without actually getting it from the driver. - * Return value will be same as what is shown in scaling_cur_freq in sysfs. - */ -unsigned int cpufreq_quick_get(unsigned int cpu) -{ - struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); - unsigned int ret_freq = 0; - - if (policy) { - ret_freq = policy->cur; - cpufreq_cpu_put(policy); - } - - return ret_freq; -} -EXPORT_SYMBOL(cpufreq_quick_get); - -/** - * cpufreq_quick_get_max - get the max reported CPU frequency for this CPU - * @cpu: CPU number - * - * Just return the max possible frequency for a given CPU. - */ -unsigned int cpufreq_quick_get_max(unsigned int cpu) -{ - struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); - unsigned int ret_freq = 0; - - if (policy) { - ret_freq = policy->max; - cpufreq_cpu_put(policy); - } - - return ret_freq; -} -EXPORT_SYMBOL(cpufreq_quick_get_max); - - -static unsigned int __cpufreq_get(unsigned int cpu) -{ - struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); - unsigned int ret_freq = 0; - - if (!cpufreq_driver->get) - return ret_freq; - - ret_freq = cpufreq_driver->get(cpu); - - if (ret_freq && policy->cur && - !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { - /* verify no discrepancy between actual and - saved value exists */ - if (unlikely(ret_freq != policy->cur)) { - cpufreq_out_of_sync(cpu, policy->cur, ret_freq); - schedule_work(&policy->update); - } - } - - return ret_freq; -} - -/** - * cpufreq_get - get the current CPU frequency (in kHz) - * @cpu: CPU number - * - * Get the CPU current (static) CPU frequency - */ -unsigned int cpufreq_get(unsigned int cpu) -{ - unsigned int ret_freq = 0; - struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); - - if (!policy) - goto out; - - if (unlikely(lock_policy_rwsem_read(cpu))) - goto out_policy; - - ret_freq = __cpufreq_get(cpu); - - unlock_policy_rwsem_read(cpu); - -out_policy: - cpufreq_cpu_put(policy); -out: - return ret_freq; -} -EXPORT_SYMBOL(cpufreq_get); - -static struct subsys_interface cpufreq_interface = { - .name = "cpufreq", - .subsys = &cpu_subsys, - .add_dev = cpufreq_add_dev, - .remove_dev = cpufreq_remove_dev, -}; - - -/** - * cpufreq_bp_suspend - Prepare the boot CPU for system suspend. - * - * This function is only executed for the boot processor. The other CPUs - * have been put offline by means of CPU hotplug. - */ -static int cpufreq_bp_suspend(void) -{ - int ret = 0; - - int cpu = smp_processor_id(); - struct cpufreq_policy *cpu_policy; - - pr_debug("suspending cpu %u\n", cpu); - - /* If there's no policy for the boot CPU, we have nothing to do. */ - cpu_policy = cpufreq_cpu_get(cpu); - if (!cpu_policy) - return 0; - - if (cpufreq_driver->suspend) { - ret = cpufreq_driver->suspend(cpu_policy); - if (ret) - printk(KERN_ERR "cpufreq: suspend failed in ->suspend " - "step on CPU %u\n", cpu_policy->cpu); - } - - cpufreq_cpu_put(cpu_policy); - return ret; -} - -/** - * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU. - * - * 1.) resume CPUfreq hardware support (cpufreq_driver->resume()) - * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are - * restored. It will verify that the current freq is in sync with - * what we believe it to be. This is a bit later than when it - * should be, but nonethteless it's better than calling - * cpufreq_driver->get() here which might re-enable interrupts... - * - * This function is only executed for the boot CPU. The other CPUs have not - * been turned on yet. - */ -static void cpufreq_bp_resume(void) -{ - int ret = 0; - - int cpu = smp_processor_id(); - struct cpufreq_policy *cpu_policy; - - pr_debug("resuming cpu %u\n", cpu); - - /* If there's no policy for the boot CPU, we have nothing to do. */ - cpu_policy = cpufreq_cpu_get(cpu); - if (!cpu_policy) - return; - - if (cpufreq_driver->resume) { - ret = cpufreq_driver->resume(cpu_policy); - if (ret) { - printk(KERN_ERR "cpufreq: resume failed in ->resume " - "step on CPU %u\n", cpu_policy->cpu); - goto fail; - } - } - - schedule_work(&cpu_policy->update); - -fail: - cpufreq_cpu_put(cpu_policy); -} - -static struct syscore_ops cpufreq_syscore_ops = { - .suspend = cpufreq_bp_suspend, - .resume = cpufreq_bp_resume, -}; - - -/********************************************************************* - * NOTIFIER LISTS INTERFACE * - *********************************************************************/ - -/** - * cpufreq_register_notifier - register a driver with cpufreq - * @nb: notifier function to register - * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER - * - * Add a driver to one of two lists: either a list of drivers that - * are notified about clock rate changes (once before and once after - * the transition), or a list of drivers that are notified about - * changes in cpufreq policy. - * - * This function may sleep, and has the same return conditions as - * blocking_notifier_chain_register. - */ -int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list) -{ - int ret; - - WARN_ON(!init_cpufreq_transition_notifier_list_called); - - switch (list) { - case CPUFREQ_TRANSITION_NOTIFIER: - ret = srcu_notifier_chain_register( - &cpufreq_transition_notifier_list, nb); - break; - case CPUFREQ_POLICY_NOTIFIER: - ret = blocking_notifier_chain_register( - &cpufreq_policy_notifier_list, nb); - break; - default: - ret = -EINVAL; - } - - return ret; -} -EXPORT_SYMBOL(cpufreq_register_notifier); - - -/** - * cpufreq_unregister_notifier - unregister a driver with cpufreq - * @nb: notifier block to be unregistered - * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER - * - * Remove a driver from the CPU frequency notifier list. - * - * This function may sleep, and has the same return conditions as - * blocking_notifier_chain_unregister. - */ -int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list) -{ - int ret; - - switch (list) { - case CPUFREQ_TRANSITION_NOTIFIER: - ret = srcu_notifier_chain_unregister( - &cpufreq_transition_notifier_list, nb); - break; - case CPUFREQ_POLICY_NOTIFIER: - ret = blocking_notifier_chain_unregister( - &cpufreq_policy_notifier_list, nb); - break; - default: - ret = -EINVAL; - } - - return ret; -} -EXPORT_SYMBOL(cpufreq_unregister_notifier); - - -/********************************************************************* - * GOVERNORS * - *********************************************************************/ - - -int __cpufreq_driver_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - int retval = -EINVAL; - - if (cpufreq_disabled()) - return -ENODEV; - - pr_debug("target for CPU %u: %u kHz, relation %u\n", policy->cpu, - target_freq, relation); - if (cpu_online(policy->cpu) && cpufreq_driver->target) - retval = cpufreq_driver->target(policy, target_freq, relation); - - return retval; -} -EXPORT_SYMBOL_GPL(__cpufreq_driver_target); - -int cpufreq_driver_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - int ret = -EINVAL; - - policy = cpufreq_cpu_get(policy->cpu); - if (!policy) - goto no_policy; - - if (unlikely(lock_policy_rwsem_write(policy->cpu))) - goto fail; - - ret = __cpufreq_driver_target(policy, target_freq, relation); - - unlock_policy_rwsem_write(policy->cpu); - -fail: - cpufreq_cpu_put(policy); -no_policy: - return ret; -} -EXPORT_SYMBOL_GPL(cpufreq_driver_target); - -int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu) -{ - int ret = 0; - - policy = cpufreq_cpu_get(policy->cpu); - if (!policy) - return -EINVAL; - - if (cpu_online(cpu) && cpufreq_driver->getavg) - ret = cpufreq_driver->getavg(policy, cpu); - - cpufreq_cpu_put(policy); - return ret; -} -EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg); - -/* - * when "event" is CPUFREQ_GOV_LIMITS - */ - -static int __cpufreq_governor(struct cpufreq_policy *policy, - unsigned int event) -{ - int ret; - - /* Only must be defined when default governor is known to have latency - restrictions, like e.g. conservative or ondemand. - That this is the case is already ensured in Kconfig - */ -#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE - struct cpufreq_governor *gov = &cpufreq_gov_performance; -#else - struct cpufreq_governor *gov = NULL; -#endif - - if (policy->governor->max_transition_latency && - policy->cpuinfo.transition_latency > - policy->governor->max_transition_latency) { - if (!gov) - return -EINVAL; - else { - printk(KERN_WARNING "%s governor failed, too long" - " transition latency of HW, fallback" - " to %s governor\n", - policy->governor->name, - gov->name); - policy->governor = gov; - } - } - - if (!try_module_get(policy->governor->owner)) - return -EINVAL; - - pr_debug("__cpufreq_governor for CPU %u, event %u\n", - policy->cpu, event); - ret = policy->governor->governor(policy, event); - - /* we keep one module reference alive for - each CPU governed by this CPU */ - if ((event != CPUFREQ_GOV_START) || ret) - module_put(policy->governor->owner); - if ((event == CPUFREQ_GOV_STOP) && !ret) - module_put(policy->governor->owner); - - return ret; -} - - -int cpufreq_register_governor(struct cpufreq_governor *governor) -{ - int err; - - if (!governor) - return -EINVAL; - - if (cpufreq_disabled()) - return -ENODEV; - - mutex_lock(&cpufreq_governor_mutex); - - err = -EBUSY; - if (__find_governor(governor->name) == NULL) { - err = 0; - list_add(&governor->governor_list, &cpufreq_governor_list); - } - - mutex_unlock(&cpufreq_governor_mutex); - return err; -} -EXPORT_SYMBOL_GPL(cpufreq_register_governor); - - -void cpufreq_unregister_governor(struct cpufreq_governor *governor) -{ -#ifdef CONFIG_HOTPLUG_CPU - int cpu; -#endif - - if (!governor) - return; - - if (cpufreq_disabled()) - return; - -#ifdef CONFIG_HOTPLUG_CPU - for_each_present_cpu(cpu) { - if (cpu_online(cpu)) - continue; - if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name)) - strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0"); - } -#endif - - mutex_lock(&cpufreq_governor_mutex); - list_del(&governor->governor_list); - mutex_unlock(&cpufreq_governor_mutex); - return; -} -EXPORT_SYMBOL_GPL(cpufreq_unregister_governor); - - - -/********************************************************************* - * POLICY INTERFACE * - *********************************************************************/ - -/** - * cpufreq_get_policy - get the current cpufreq_policy - * @policy: struct cpufreq_policy into which the current cpufreq_policy - * is written - * - * Reads the current cpufreq policy. - */ -int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu) -{ - struct cpufreq_policy *cpu_policy; - if (!policy) - return -EINVAL; - - cpu_policy = cpufreq_cpu_get(cpu); - if (!cpu_policy) - return -EINVAL; - - memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy)); - - cpufreq_cpu_put(cpu_policy); - return 0; -} -EXPORT_SYMBOL(cpufreq_get_policy); - - -/* - * data : current policy. - * policy : policy to be set. - */ -static int __cpufreq_set_policy(struct cpufreq_policy *data, - struct cpufreq_policy *policy) -{ - int ret = 0; - - pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu, - policy->min, policy->max); - - memcpy(&policy->cpuinfo, &data->cpuinfo, - sizeof(struct cpufreq_cpuinfo)); - - if (policy->min > data->max || policy->max < data->min) { - ret = -EINVAL; - goto error_out; - } - - /* verify the cpu speed can be set within this limit */ - ret = cpufreq_driver->verify(policy); - if (ret) - goto error_out; - - /* adjust if necessary - all reasons */ - blocking_notifier_call_chain(&cpufreq_policy_notifier_list, - CPUFREQ_ADJUST, policy); - - /* adjust if necessary - hardware incompatibility*/ - blocking_notifier_call_chain(&cpufreq_policy_notifier_list, - CPUFREQ_INCOMPATIBLE, policy); - - /* verify the cpu speed can be set within this limit, - which might be different to the first one */ - ret = cpufreq_driver->verify(policy); - if (ret) - goto error_out; - - /* notification of the new policy */ - blocking_notifier_call_chain(&cpufreq_policy_notifier_list, - CPUFREQ_NOTIFY, policy); - - data->min = policy->min; - data->max = policy->max; - - pr_debug("new min and max freqs are %u - %u kHz\n", - data->min, data->max); - - if (cpufreq_driver->setpolicy) { - data->policy = policy->policy; - pr_debug("setting range\n"); - ret = cpufreq_driver->setpolicy(policy); - } else { - if (policy->governor != data->governor) { - /* save old, working values */ - struct cpufreq_governor *old_gov = data->governor; - - pr_debug("governor switch\n"); - - /* end old governor */ - if (data->governor) - __cpufreq_governor(data, CPUFREQ_GOV_STOP); - - /* start new governor */ - data->governor = policy->governor; - if (__cpufreq_governor(data, CPUFREQ_GOV_START)) { - /* new governor failed, so re-start old one */ - pr_debug("starting governor %s failed\n", - data->governor->name); - if (old_gov) { - data->governor = old_gov; - __cpufreq_governor(data, - CPUFREQ_GOV_START); - } - ret = -EINVAL; - goto error_out; - } - /* might be a policy change, too, so fall through */ - } - pr_debug("governor: change or update limits\n"); - __cpufreq_governor(data, CPUFREQ_GOV_LIMITS); - } - -error_out: - return ret; -} - -/** - * cpufreq_update_policy - re-evaluate an existing cpufreq policy - * @cpu: CPU which shall be re-evaluated - * - * Useful for policy notifiers which have different necessities - * at different times. - */ -int cpufreq_update_policy(unsigned int cpu) -{ - struct cpufreq_policy *data = cpufreq_cpu_get(cpu); - struct cpufreq_policy policy; - int ret; - - if (!data) { - ret = -ENODEV; - goto no_policy; - } - - if (unlikely(lock_policy_rwsem_write(cpu))) { - ret = -EINVAL; - goto fail; - } - - pr_debug("updating policy for CPU %u\n", cpu); - memcpy(&policy, data, sizeof(struct cpufreq_policy)); - policy.min = data->user_policy.min; - policy.max = data->user_policy.max; - policy.policy = data->user_policy.policy; - policy.governor = data->user_policy.governor; - - /* BIOS might change freq behind our back - -> ask driver for current freq and notify governors about a change */ - if (cpufreq_driver->get) { - policy.cur = cpufreq_driver->get(cpu); - if (!data->cur) { - pr_debug("Driver did not initialize current freq"); - data->cur = policy.cur; - } else { - if (data->cur != policy.cur) - cpufreq_out_of_sync(cpu, data->cur, - policy.cur); - } - } - - ret = __cpufreq_set_policy(data, &policy); - - unlock_policy_rwsem_write(cpu); - -fail: - cpufreq_cpu_put(data); -no_policy: - return ret; -} -EXPORT_SYMBOL(cpufreq_update_policy); - -static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb, - unsigned long action, void *hcpu) -{ - unsigned int cpu = (unsigned long)hcpu; - struct device *dev; - - dev = get_cpu_device(cpu); - if (dev) { - switch (action) { - case CPU_ONLINE: - case CPU_ONLINE_FROZEN: - cpufreq_add_dev(dev, NULL); - break; - case CPU_DOWN_PREPARE: - case CPU_DOWN_PREPARE_FROZEN: - if (unlikely(lock_policy_rwsem_write(cpu))) - BUG(); - - __cpufreq_remove_dev(dev, NULL); - break; - case CPU_DOWN_FAILED: - case CPU_DOWN_FAILED_FROZEN: - cpufreq_add_dev(dev, NULL); - break; - } - } - return NOTIFY_OK; -} - -static struct notifier_block __refdata cpufreq_cpu_notifier = { - .notifier_call = cpufreq_cpu_callback, -}; - -/********************************************************************* - * REGISTER / UNREGISTER CPUFREQ DRIVER * - *********************************************************************/ - -/** - * cpufreq_register_driver - register a CPU Frequency driver - * @driver_data: A struct cpufreq_driver containing the values# - * submitted by the CPU Frequency driver. - * - * Registers a CPU Frequency driver to this core code. This code - * returns zero on success, -EBUSY when another driver got here first - * (and isn't unregistered in the meantime). - * - */ -int cpufreq_register_driver(struct cpufreq_driver *driver_data) -{ - unsigned long flags; - int ret; - - if (cpufreq_disabled()) - return -ENODEV; - - if (!driver_data || !driver_data->verify || !driver_data->init || - ((!driver_data->setpolicy) && (!driver_data->target))) - return -EINVAL; - - pr_debug("trying to register driver %s\n", driver_data->name); - - if (driver_data->setpolicy) - driver_data->flags |= CPUFREQ_CONST_LOOPS; - - spin_lock_irqsave(&cpufreq_driver_lock, flags); - if (cpufreq_driver) { - spin_unlock_irqrestore(&cpufreq_driver_lock, flags); - return -EBUSY; - } - cpufreq_driver = driver_data; - spin_unlock_irqrestore(&cpufreq_driver_lock, flags); - - ret = subsys_interface_register(&cpufreq_interface); - if (ret) - goto err_null_driver; - - if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) { - int i; - ret = -ENODEV; - - /* check for at least one working CPU */ - for (i = 0; i < nr_cpu_ids; i++) - if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) { - ret = 0; - break; - } - - /* if all ->init() calls failed, unregister */ - if (ret) { - pr_debug("no CPU initialized for driver %s\n", - driver_data->name); - goto err_if_unreg; - } - } - - register_hotcpu_notifier(&cpufreq_cpu_notifier); - pr_debug("driver %s up and running\n", driver_data->name); - - return 0; -err_if_unreg: - subsys_interface_unregister(&cpufreq_interface); -err_null_driver: - spin_lock_irqsave(&cpufreq_driver_lock, flags); - cpufreq_driver = NULL; - spin_unlock_irqrestore(&cpufreq_driver_lock, flags); - return ret; -} -EXPORT_SYMBOL_GPL(cpufreq_register_driver); - - -/** - * cpufreq_unregister_driver - unregister the current CPUFreq driver - * - * Unregister the current CPUFreq driver. Only call this if you have - * the right to do so, i.e. if you have succeeded in initialising before! - * Returns zero if successful, and -EINVAL if the cpufreq_driver is - * currently not initialised. - */ -int cpufreq_unregister_driver(struct cpufreq_driver *driver) -{ - unsigned long flags; - - if (!cpufreq_driver || (driver != cpufreq_driver)) - return -EINVAL; - - pr_debug("unregistering driver %s\n", driver->name); - - subsys_interface_unregister(&cpufreq_interface); - unregister_hotcpu_notifier(&cpufreq_cpu_notifier); - - spin_lock_irqsave(&cpufreq_driver_lock, flags); - cpufreq_driver = NULL; - spin_unlock_irqrestore(&cpufreq_driver_lock, flags); - - return 0; -} -EXPORT_SYMBOL_GPL(cpufreq_unregister_driver); - -static int __init cpufreq_core_init(void) -{ - int cpu; - - if (cpufreq_disabled()) - return -ENODEV; - - for_each_possible_cpu(cpu) { - per_cpu(cpufreq_policy_cpu, cpu) = -1; - init_rwsem(&per_cpu(cpu_policy_rwsem, cpu)); - } - - cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj); - BUG_ON(!cpufreq_global_kobject); - register_syscore_ops(&cpufreq_syscore_ops); - - return 0; -} -core_initcall(cpufreq_core_init); diff --git a/ANDROID_3.4.5/drivers/media/dvb/siano/sms-cards.c b/ANDROID_3.4.5/drivers/media/dvb/siano/sms-cards.c deleted file mode 100644 index 680c781c..00000000 --- a/ANDROID_3.4.5/drivers/media/dvb/siano/sms-cards.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Card-specific functions for the Siano SMS1xxx USB dongle - * - * Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. - * - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "sms-cards.h" -#include "smsir.h" -#include <linux/module.h> - -static int sms_dbg; -module_param_named(cards_dbg, sms_dbg, int, 0644); -MODULE_PARM_DESC(cards_dbg, "set debug level (info=1, adv=2 (or-able))"); - -static struct sms_board sms_boards[] = { - [SMS_BOARD_UNKNOWN] = { - .name = "Unknown board", - }, - [SMS1XXX_BOARD_SIANO_STELLAR] = { - .name = "Siano Stellar Digital Receiver", - .type = SMS_STELLAR, - }, - [SMS1XXX_BOARD_SIANO_NOVA_A] = { - .name = "Siano Nova A Digital Receiver", - .type = SMS_NOVA_A0, - }, - [SMS1XXX_BOARD_SIANO_NOVA_B] = { - .name = "Siano Nova B Digital Receiver", - .type = SMS_NOVA_B0, - }, - [SMS1XXX_BOARD_SIANO_VEGA] = { - .name = "Siano Vega Digital Receiver", - .type = SMS_VEGA, - }, - [SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT] = { - .name = "Hauppauge Catamount", - .type = SMS_STELLAR, - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw", - }, - [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A] = { - .name = "Hauppauge Okemo-A", - .type = SMS_NOVA_A0, - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw", - }, - [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B] = { - .name = "Hauppauge Okemo-B", - .type = SMS_NOVA_B0, - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw", - }, - [SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = { - .name = "Hauppauge WinTV MiniStick", - .type = SMS_NOVA_B0, - .fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw", - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", - .rc_codes = RC_MAP_HAUPPAUGE, - .board_cfg.leds_power = 26, - .board_cfg.led0 = 27, - .board_cfg.led1 = 28, - .board_cfg.ir = 9, - .led_power = 26, - .led_lo = 27, - .led_hi = 28, - }, - [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD] = { - .name = "Hauppauge WinTV MiniCard", - .type = SMS_NOVA_B0, - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", - .lna_ctrl = 29, - .board_cfg.foreign_lna0_ctrl = 29, - .rf_switch = 17, - .board_cfg.rf_switch_uhf = 17, - }, - [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = { - .name = "Hauppauge WinTV MiniCard", - .type = SMS_NOVA_B0, - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", - .lna_ctrl = -1, - }, - [SMS1XXX_BOARD_SIANO_NICE] = { - /* 11 */ - .name = "Siano Nice Digital Receiver", - .type = SMS_NOVA_B0, - }, - [SMS1XXX_BOARD_SIANO_VENICE] = { - /* 12 */ - .name = "Siano Venice Digital Receiver", - .type = SMS_VEGA, - }, -}; - -struct sms_board *sms_get_board(unsigned id) -{ - BUG_ON(id >= ARRAY_SIZE(sms_boards)); - - return &sms_boards[id]; -} -EXPORT_SYMBOL_GPL(sms_get_board); -static inline void sms_gpio_assign_11xx_default_led_config( - struct smscore_gpio_config *pGpioConfig) { - pGpioConfig->Direction = SMS_GPIO_DIRECTION_OUTPUT; - pGpioConfig->InputCharacteristics = - SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL; - pGpioConfig->OutputDriving = SMS_GPIO_OUTPUT_DRIVING_4mA; - pGpioConfig->OutputSlewRate = SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS; - pGpioConfig->PullUpDown = SMS_GPIO_PULL_UP_DOWN_NONE; -} - -int sms_board_event(struct smscore_device_t *coredev, - enum SMS_BOARD_EVENTS gevent) { - struct smscore_gpio_config MyGpioConfig; - - sms_gpio_assign_11xx_default_led_config(&MyGpioConfig); - - switch (gevent) { - case BOARD_EVENT_POWER_INIT: /* including hotplug */ - break; /* BOARD_EVENT_BIND */ - - case BOARD_EVENT_POWER_SUSPEND: - break; /* BOARD_EVENT_POWER_SUSPEND */ - - case BOARD_EVENT_POWER_RESUME: - break; /* BOARD_EVENT_POWER_RESUME */ - - case BOARD_EVENT_BIND: - break; /* BOARD_EVENT_BIND */ - - case BOARD_EVENT_SCAN_PROG: - break; /* BOARD_EVENT_SCAN_PROG */ - case BOARD_EVENT_SCAN_COMP: - break; /* BOARD_EVENT_SCAN_COMP */ - case BOARD_EVENT_EMERGENCY_WARNING_SIGNAL: - break; /* BOARD_EVENT_EMERGENCY_WARNING_SIGNAL */ - case BOARD_EVENT_FE_LOCK: - break; /* BOARD_EVENT_FE_LOCK */ - case BOARD_EVENT_FE_UNLOCK: - break; /* BOARD_EVENT_FE_UNLOCK */ - case BOARD_EVENT_DEMOD_LOCK: - break; /* BOARD_EVENT_DEMOD_LOCK */ - case BOARD_EVENT_DEMOD_UNLOCK: - break; /* BOARD_EVENT_DEMOD_UNLOCK */ - case BOARD_EVENT_RECEPTION_MAX_4: - break; /* BOARD_EVENT_RECEPTION_MAX_4 */ - case BOARD_EVENT_RECEPTION_3: - break; /* BOARD_EVENT_RECEPTION_3 */ - case BOARD_EVENT_RECEPTION_2: - break; /* BOARD_EVENT_RECEPTION_2 */ - case BOARD_EVENT_RECEPTION_1: - break; /* BOARD_EVENT_RECEPTION_1 */ - case BOARD_EVENT_RECEPTION_LOST_0: - break; /* BOARD_EVENT_RECEPTION_LOST_0 */ - case BOARD_EVENT_MULTIPLEX_OK: - break; /* BOARD_EVENT_MULTIPLEX_OK */ - case BOARD_EVENT_MULTIPLEX_ERRORS: - break; /* BOARD_EVENT_MULTIPLEX_ERRORS */ - - default: - sms_err("Unknown SMS board event"); - break; - } - return 0; -} -EXPORT_SYMBOL_GPL(sms_board_event); - -static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable) -{ - int lvl, ret; - u32 gpio; - struct smscore_config_gpio gpioconfig = { - .direction = SMS_GPIO_DIRECTION_OUTPUT, - .pullupdown = SMS_GPIO_PULLUPDOWN_NONE, - .inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL, - .outputslewrate = SMS_GPIO_OUTPUTSLEWRATE_FAST, - .outputdriving = SMS_GPIO_OUTPUTDRIVING_4mA, - }; - - if (pin == 0) - return -EINVAL; - - if (pin < 0) { - /* inverted gpio */ - gpio = pin * -1; - lvl = enable ? 0 : 1; - } else { - gpio = pin; - lvl = enable ? 1 : 0; - } - - ret = smscore_configure_gpio(coredev, gpio, &gpioconfig); - if (ret < 0) - return ret; - - return smscore_set_gpio(coredev, gpio, lvl); -} - -int sms_board_setup(struct smscore_device_t *coredev) -{ - int board_id = smscore_get_board_id(coredev); - struct sms_board *board = sms_get_board(board_id); - - switch (board_id) { - case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: - /* turn off all LEDs */ - sms_set_gpio(coredev, board->led_power, 0); - sms_set_gpio(coredev, board->led_hi, 0); - sms_set_gpio(coredev, board->led_lo, 0); - break; - case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: - case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: - /* turn off LNA */ - sms_set_gpio(coredev, board->lna_ctrl, 0); - break; - } - return 0; -} -EXPORT_SYMBOL_GPL(sms_board_setup); - -int sms_board_power(struct smscore_device_t *coredev, int onoff) -{ - int board_id = smscore_get_board_id(coredev); - struct sms_board *board = sms_get_board(board_id); - - switch (board_id) { - case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: - /* power LED */ - sms_set_gpio(coredev, - board->led_power, onoff ? 1 : 0); - break; - case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: - case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: - /* LNA */ - if (!onoff) - sms_set_gpio(coredev, board->lna_ctrl, 0); - break; - } - return 0; -} -EXPORT_SYMBOL_GPL(sms_board_power); - -int sms_board_led_feedback(struct smscore_device_t *coredev, int led) -{ - int board_id = smscore_get_board_id(coredev); - struct sms_board *board = sms_get_board(board_id); - - /* dont touch GPIO if LEDs are already set */ - if (smscore_led_state(coredev, -1) == led) - return 0; - - switch (board_id) { - case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: - sms_set_gpio(coredev, - board->led_lo, (led & SMS_LED_LO) ? 1 : 0); - sms_set_gpio(coredev, - board->led_hi, (led & SMS_LED_HI) ? 1 : 0); - - smscore_led_state(coredev, led); - break; - } - return 0; -} -EXPORT_SYMBOL_GPL(sms_board_led_feedback); - -int sms_board_lna_control(struct smscore_device_t *coredev, int onoff) -{ - int board_id = smscore_get_board_id(coredev); - struct sms_board *board = sms_get_board(board_id); - - sms_debug("%s: LNA %s", __func__, onoff ? "enabled" : "disabled"); - - switch (board_id) { - case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: - case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: - sms_set_gpio(coredev, - board->rf_switch, onoff ? 1 : 0); - return sms_set_gpio(coredev, - board->lna_ctrl, onoff ? 1 : 0); - } - return -EINVAL; -} -EXPORT_SYMBOL_GPL(sms_board_lna_control); - -int sms_board_load_modules(int id) -{ - switch (id) { - case SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT: - case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A: - case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B: - case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: - case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: - case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: - request_module("smsdvb"); - break; - default: - /* do nothing */ - break; - } - return 0; -} -EXPORT_SYMBOL_GPL(sms_board_load_modules); diff --git a/ANDROID_3.4.5/drivers/media/dvb/siano/sms-cards.h b/ANDROID_3.4.5/drivers/media/dvb/siano/sms-cards.h deleted file mode 100644 index d8cdf756..00000000 --- a/ANDROID_3.4.5/drivers/media/dvb/siano/sms-cards.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Card-specific functions for the Siano SMS1xxx USB dongle - * - * Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. - * - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __SMS_CARDS_H__ -#define __SMS_CARDS_H__ - -#include <linux/usb.h> -#include "smscoreapi.h" -#include "smsir.h" - -#define SMS_BOARD_UNKNOWN 0 -#define SMS1XXX_BOARD_SIANO_STELLAR 1 -#define SMS1XXX_BOARD_SIANO_NOVA_A 2 -#define SMS1XXX_BOARD_SIANO_NOVA_B 3 -#define SMS1XXX_BOARD_SIANO_VEGA 4 -#define SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT 5 -#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A 6 -#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B 7 -#define SMS1XXX_BOARD_HAUPPAUGE_WINDHAM 8 -#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD 9 -#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 10 -#define SMS1XXX_BOARD_SIANO_NICE 11 -#define SMS1XXX_BOARD_SIANO_VENICE 12 - -struct sms_board_gpio_cfg { - int lna_vhf_exist; - int lna_vhf_ctrl; - int lna_uhf_exist; - int lna_uhf_ctrl; - int lna_uhf_d_ctrl; - int lna_sband_exist; - int lna_sband_ctrl; - int lna_sband_d_ctrl; - int foreign_lna0_ctrl; - int foreign_lna1_ctrl; - int foreign_lna2_ctrl; - int rf_switch_vhf; - int rf_switch_uhf; - int rf_switch_sband; - int leds_power; - int led0; - int led1; - int led2; - int led3; - int led4; - int ir; - int eeprom_wp; - int mrc_sense; - int mrc_pdn_resetn; - int mrc_gp0; /* mrcs spi int */ - int mrc_gp1; - int mrc_gp2; - int mrc_gp3; - int mrc_gp4; - int host_spi_gsp_ts_int; -}; - -struct sms_board { - enum sms_device_type_st type; - char *name, *fw[DEVICE_MODE_MAX]; - struct sms_board_gpio_cfg board_cfg; - char *rc_codes; /* Name of IR codes table */ - - /* gpios */ - int led_power, led_hi, led_lo, lna_ctrl, rf_switch; -}; - -struct sms_board *sms_get_board(unsigned id); - -extern struct smscore_device_t *coredev; - -enum SMS_BOARD_EVENTS { - BOARD_EVENT_POWER_INIT, - BOARD_EVENT_POWER_SUSPEND, - BOARD_EVENT_POWER_RESUME, - BOARD_EVENT_BIND, - BOARD_EVENT_SCAN_PROG, - BOARD_EVENT_SCAN_COMP, - BOARD_EVENT_EMERGENCY_WARNING_SIGNAL, - BOARD_EVENT_FE_LOCK, - BOARD_EVENT_FE_UNLOCK, - BOARD_EVENT_DEMOD_LOCK, - BOARD_EVENT_DEMOD_UNLOCK, - BOARD_EVENT_RECEPTION_MAX_4, - BOARD_EVENT_RECEPTION_3, - BOARD_EVENT_RECEPTION_2, - BOARD_EVENT_RECEPTION_1, - BOARD_EVENT_RECEPTION_LOST_0, - BOARD_EVENT_MULTIPLEX_OK, - BOARD_EVENT_MULTIPLEX_ERRORS -}; - -int sms_board_event(struct smscore_device_t *coredev, - enum SMS_BOARD_EVENTS gevent); - -int sms_board_setup(struct smscore_device_t *coredev); - -#define SMS_LED_OFF 0 -#define SMS_LED_LO 1 -#define SMS_LED_HI 2 -int sms_board_led_feedback(struct smscore_device_t *coredev, int led); -int sms_board_power(struct smscore_device_t *coredev, int onoff); -int sms_board_lna_control(struct smscore_device_t *coredev, int onoff); - -extern int sms_board_load_modules(int id); - -#endif /* __SMS_CARDS_H__ */ diff --git a/ANDROID_3.4.5/drivers/media/dvb/siano/smscoreapi.c b/ANDROID_3.4.5/drivers/media/dvb/siano/smscoreapi.c deleted file mode 100644 index 7331e845..00000000 --- a/ANDROID_3.4.5/drivers/media/dvb/siano/smscoreapi.c +++ /dev/null @@ -1,1644 +0,0 @@ -/* - * Siano core API module - * - * This file contains implementation for the interface to sms core component - * - * author: Uri Shkolnik - * - * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. - * - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/dma-mapping.h> -#include <linux/delay.h> -#include <linux/io.h> -#include <linux/slab.h> - -#include <linux/firmware.h> -#include <linux/wait.h> -#include <asm/byteorder.h> - -#include "smscoreapi.h" -#include "sms-cards.h" -#include "smsir.h" -#include "smsendian.h" - -static int sms_dbg; -module_param_named(debug, sms_dbg, int, 0644); -MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); - -struct smscore_device_notifyee_t { - struct list_head entry; - hotplug_t hotplug; -}; - -struct smscore_idlist_t { - struct list_head entry; - int id; - int data_type; -}; - -struct smscore_client_t { - struct list_head entry; - struct smscore_device_t *coredev; - void *context; - struct list_head idlist; - onresponse_t onresponse_handler; - onremove_t onremove_handler; -}; - -void smscore_set_board_id(struct smscore_device_t *core, int id) -{ - core->board_id = id; -} - -int smscore_led_state(struct smscore_device_t *core, int led) -{ - if (led >= 0) - core->led_state = led; - return core->led_state; -} -EXPORT_SYMBOL_GPL(smscore_set_board_id); - -int smscore_get_board_id(struct smscore_device_t *core) -{ - return core->board_id; -} -EXPORT_SYMBOL_GPL(smscore_get_board_id); - -struct smscore_registry_entry_t { - struct list_head entry; - char devpath[32]; - int mode; - enum sms_device_type_st type; -}; - -static struct list_head g_smscore_notifyees; -static struct list_head g_smscore_devices; -static struct mutex g_smscore_deviceslock; - -static struct list_head g_smscore_registry; -static struct mutex g_smscore_registrylock; - -static int default_mode = 4; - -module_param(default_mode, int, 0644); -MODULE_PARM_DESC(default_mode, "default firmware id (device mode)"); - -static struct smscore_registry_entry_t *smscore_find_registry(char *devpath) -{ - struct smscore_registry_entry_t *entry; - struct list_head *next; - - kmutex_lock(&g_smscore_registrylock); - for (next = g_smscore_registry.next; - next != &g_smscore_registry; - next = next->next) { - entry = (struct smscore_registry_entry_t *) next; - if (!strcmp(entry->devpath, devpath)) { - kmutex_unlock(&g_smscore_registrylock); - return entry; - } - } - entry = kmalloc(sizeof(struct smscore_registry_entry_t), GFP_KERNEL); - if (entry) { - entry->mode = default_mode; - strcpy(entry->devpath, devpath); - list_add(&entry->entry, &g_smscore_registry); - } else - sms_err("failed to create smscore_registry."); - kmutex_unlock(&g_smscore_registrylock); - return entry; -} - -int smscore_registry_getmode(char *devpath) -{ - struct smscore_registry_entry_t *entry; - - entry = smscore_find_registry(devpath); - if (entry) - return entry->mode; - else - sms_err("No registry found."); - - return default_mode; -} -EXPORT_SYMBOL_GPL(smscore_registry_getmode); - -static enum sms_device_type_st smscore_registry_gettype(char *devpath) -{ - struct smscore_registry_entry_t *entry; - - entry = smscore_find_registry(devpath); - if (entry) - return entry->type; - else - sms_err("No registry found."); - - return -1; -} - -void smscore_registry_setmode(char *devpath, int mode) -{ - struct smscore_registry_entry_t *entry; - - entry = smscore_find_registry(devpath); - if (entry) - entry->mode = mode; - else - sms_err("No registry found."); -} - -static void smscore_registry_settype(char *devpath, - enum sms_device_type_st type) -{ - struct smscore_registry_entry_t *entry; - - entry = smscore_find_registry(devpath); - if (entry) - entry->type = type; - else - sms_err("No registry found."); -} - - -static void list_add_locked(struct list_head *new, struct list_head *head, - spinlock_t *lock) -{ - unsigned long flags; - - spin_lock_irqsave(lock, flags); - - list_add(new, head); - - spin_unlock_irqrestore(lock, flags); -} - -/** - * register a client callback that called when device plugged in/unplugged - * NOTE: if devices exist callback is called immediately for each device - * - * @param hotplug callback - * - * @return 0 on success, <0 on error. - */ -int smscore_register_hotplug(hotplug_t hotplug) -{ - struct smscore_device_notifyee_t *notifyee; - struct list_head *next, *first; - int rc = 0; - - kmutex_lock(&g_smscore_deviceslock); - - notifyee = kmalloc(sizeof(struct smscore_device_notifyee_t), - GFP_KERNEL); - if (notifyee) { - /* now notify callback about existing devices */ - first = &g_smscore_devices; - for (next = first->next; - next != first && !rc; - next = next->next) { - struct smscore_device_t *coredev = - (struct smscore_device_t *) next; - rc = hotplug(coredev, coredev->device, 1); - } - - if (rc >= 0) { - notifyee->hotplug = hotplug; - list_add(¬ifyee->entry, &g_smscore_notifyees); - } else - kfree(notifyee); - } else - rc = -ENOMEM; - - kmutex_unlock(&g_smscore_deviceslock); - - return rc; -} -EXPORT_SYMBOL_GPL(smscore_register_hotplug); - -/** - * unregister a client callback that called when device plugged in/unplugged - * - * @param hotplug callback - * - */ -void smscore_unregister_hotplug(hotplug_t hotplug) -{ - struct list_head *next, *first; - - kmutex_lock(&g_smscore_deviceslock); - - first = &g_smscore_notifyees; - - for (next = first->next; next != first;) { - struct smscore_device_notifyee_t *notifyee = - (struct smscore_device_notifyee_t *) next; - next = next->next; - - if (notifyee->hotplug == hotplug) { - list_del(¬ifyee->entry); - kfree(notifyee); - } - } - - kmutex_unlock(&g_smscore_deviceslock); -} -EXPORT_SYMBOL_GPL(smscore_unregister_hotplug); - -static void smscore_notify_clients(struct smscore_device_t *coredev) -{ - struct smscore_client_t *client; - - /* the client must call smscore_unregister_client from remove handler */ - while (!list_empty(&coredev->clients)) { - client = (struct smscore_client_t *) coredev->clients.next; - client->onremove_handler(client->context); - } -} - -static int smscore_notify_callbacks(struct smscore_device_t *coredev, - struct device *device, int arrival) -{ - struct list_head *next, *first; - int rc = 0; - - /* note: must be called under g_deviceslock */ - - first = &g_smscore_notifyees; - - for (next = first->next; next != first; next = next->next) { - rc = ((struct smscore_device_notifyee_t *) next)-> - hotplug(coredev, device, arrival); - if (rc < 0) - break; - } - - return rc; -} - -static struct -smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, - dma_addr_t common_buffer_phys) -{ - struct smscore_buffer_t *cb = - kmalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL); - if (!cb) { - sms_info("kmalloc(...) failed"); - return NULL; - } - - cb->p = buffer; - cb->offset_in_common = buffer - (u8 *) common_buffer; - cb->phys = common_buffer_phys + cb->offset_in_common; - - return cb; -} - -/** - * creates coredev object for a device, prepares buffers, - * creates buffer mappings, notifies registered hotplugs about new device. - * - * @param params device pointer to struct with device specific parameters - * and handlers - * @param coredev pointer to a value that receives created coredev object - * - * @return 0 on success, <0 on error. - */ -int smscore_register_device(struct smsdevice_params_t *params, - struct smscore_device_t **coredev) -{ - struct smscore_device_t *dev; - u8 *buffer; - - dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL); - if (!dev) { - sms_info("kzalloc(...) failed"); - return -ENOMEM; - } - - /* init list entry so it could be safe in smscore_unregister_device */ - INIT_LIST_HEAD(&dev->entry); - - /* init queues */ - INIT_LIST_HEAD(&dev->clients); - INIT_LIST_HEAD(&dev->buffers); - - /* init locks */ - spin_lock_init(&dev->clientslock); - spin_lock_init(&dev->bufferslock); - - /* init completion events */ - init_completion(&dev->version_ex_done); - init_completion(&dev->data_download_done); - init_completion(&dev->trigger_done); - init_completion(&dev->init_device_done); - init_completion(&dev->reload_start_done); - init_completion(&dev->resume_done); - init_completion(&dev->gpio_configuration_done); - init_completion(&dev->gpio_set_level_done); - init_completion(&dev->gpio_get_level_done); - init_completion(&dev->ir_init_done); - - /* Buffer management */ - init_waitqueue_head(&dev->buffer_mng_waitq); - - /* alloc common buffer */ - dev->common_buffer_size = params->buffer_size * params->num_buffers; - dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size, - &dev->common_buffer_phys, - GFP_KERNEL | GFP_DMA); - if (!dev->common_buffer) { - smscore_unregister_device(dev); - return -ENOMEM; - } - - /* prepare dma buffers */ - for (buffer = dev->common_buffer; - dev->num_buffers < params->num_buffers; - dev->num_buffers++, buffer += params->buffer_size) { - struct smscore_buffer_t *cb = - smscore_createbuffer(buffer, dev->common_buffer, - dev->common_buffer_phys); - if (!cb) { - smscore_unregister_device(dev); - return -ENOMEM; - } - - smscore_putbuffer(dev, cb); - } - - sms_info("allocated %d buffers", dev->num_buffers); - - dev->mode = DEVICE_MODE_NONE; - dev->context = params->context; - dev->device = params->device; - dev->setmode_handler = params->setmode_handler; - dev->detectmode_handler = params->detectmode_handler; - dev->sendrequest_handler = params->sendrequest_handler; - dev->preload_handler = params->preload_handler; - dev->postload_handler = params->postload_handler; - - dev->device_flags = params->flags; - strcpy(dev->devpath, params->devpath); - - smscore_registry_settype(dev->devpath, params->device_type); - - /* add device to devices list */ - kmutex_lock(&g_smscore_deviceslock); - list_add(&dev->entry, &g_smscore_devices); - kmutex_unlock(&g_smscore_deviceslock); - - *coredev = dev; - - sms_info("device %p created", dev); - - return 0; -} -EXPORT_SYMBOL_GPL(smscore_register_device); - - -static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, - void *buffer, size_t size, struct completion *completion) { - int rc = coredev->sendrequest_handler(coredev->context, buffer, size); - if (rc < 0) { - sms_info("sendrequest returned error %d", rc); - return rc; - } - - return wait_for_completion_timeout(completion, - msecs_to_jiffies(SMS_PROTOCOL_MAX_RAOUNDTRIP_MS)) ? - 0 : -ETIME; -} - -/** - * Starts & enables IR operations - * - * @return 0 on success, < 0 on error. - */ -static int smscore_init_ir(struct smscore_device_t *coredev) -{ - int ir_io; - int rc; - void *buffer; - - coredev->ir.dev = NULL; - ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir; - if (ir_io) {/* only if IR port exist we use IR sub-module */ - sms_info("IR loading"); - rc = sms_ir_init(coredev); - - if (rc != 0) - sms_err("Error initialization DTV IR sub-module"); - else { - buffer = kmalloc(sizeof(struct SmsMsgData_ST2) + - SMS_DMA_ALIGNMENT, - GFP_KERNEL | GFP_DMA); - if (buffer) { - struct SmsMsgData_ST2 *msg = - (struct SmsMsgData_ST2 *) - SMS_ALIGN_ADDRESS(buffer); - - SMS_INIT_MSG(&msg->xMsgHeader, - MSG_SMS_START_IR_REQ, - sizeof(struct SmsMsgData_ST2)); - msg->msgData[0] = coredev->ir.controller; - msg->msgData[1] = coredev->ir.timeout; - - smsendian_handle_tx_message( - (struct SmsMsgHdr_ST2 *)msg); - rc = smscore_sendrequest_and_wait(coredev, msg, - msg->xMsgHeader. msgLength, - &coredev->ir_init_done); - - kfree(buffer); - } else - sms_err - ("Sending IR initialization message failed"); - } - } else - sms_info("IR port has not been detected"); - - return 0; -} - -/** - * sets initial device mode and notifies client hotplugs that device is ready - * - * @param coredev pointer to a coredev object returned by - * smscore_register_device - * - * @return 0 on success, <0 on error. - */ -int smscore_start_device(struct smscore_device_t *coredev) -{ - int rc = smscore_set_device_mode( - coredev, smscore_registry_getmode(coredev->devpath)); - if (rc < 0) { - sms_info("set device mode faile , rc %d", rc); - return rc; - } - - kmutex_lock(&g_smscore_deviceslock); - - rc = smscore_notify_callbacks(coredev, coredev->device, 1); - smscore_init_ir(coredev); - - sms_info("device %p started, rc %d", coredev, rc); - - kmutex_unlock(&g_smscore_deviceslock); - - return rc; -} -EXPORT_SYMBOL_GPL(smscore_start_device); - - -static int smscore_load_firmware_family2(struct smscore_device_t *coredev, - void *buffer, size_t size) -{ - struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer; - struct SmsMsgHdr_ST *msg; - u32 mem_address; - u8 *payload = firmware->Payload; - int rc = 0; - firmware->StartAddress = le32_to_cpu(firmware->StartAddress); - firmware->Length = le32_to_cpu(firmware->Length); - - mem_address = firmware->StartAddress; - - sms_info("loading FW to addr 0x%x size %d", - mem_address, firmware->Length); - if (coredev->preload_handler) { - rc = coredev->preload_handler(coredev->context); - if (rc < 0) - return rc; - } - - /* PAGE_SIZE buffer shall be enough and dma aligned */ - msg = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA); - if (!msg) - return -ENOMEM; - - if (coredev->mode != DEVICE_MODE_NONE) { - sms_debug("sending reload command."); - SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ, - sizeof(struct SmsMsgHdr_ST)); - rc = smscore_sendrequest_and_wait(coredev, msg, - msg->msgLength, - &coredev->reload_start_done); - mem_address = *(u32 *) &payload[20]; - } - - while (size && rc >= 0) { - struct SmsDataDownload_ST *DataMsg = - (struct SmsDataDownload_ST *) msg; - int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE); - - SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ, - (u16)(sizeof(struct SmsMsgHdr_ST) + - sizeof(u32) + payload_size)); - - DataMsg->MemAddr = mem_address; - memcpy(DataMsg->Payload, payload, payload_size); - - if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) && - (coredev->mode == DEVICE_MODE_NONE)) - rc = coredev->sendrequest_handler( - coredev->context, DataMsg, - DataMsg->xMsgHeader.msgLength); - else - rc = smscore_sendrequest_and_wait( - coredev, DataMsg, - DataMsg->xMsgHeader.msgLength, - &coredev->data_download_done); - - payload += payload_size; - size -= payload_size; - mem_address += payload_size; - } - - if (rc >= 0) { - if (coredev->mode == DEVICE_MODE_NONE) { - struct SmsMsgData_ST *TriggerMsg = - (struct SmsMsgData_ST *) msg; - - SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, - sizeof(struct SmsMsgHdr_ST) + - sizeof(u32) * 5); - - TriggerMsg->msgData[0] = firmware->StartAddress; - /* Entry point */ - TriggerMsg->msgData[1] = 5; /* Priority */ - TriggerMsg->msgData[2] = 0x200; /* Stack size */ - TriggerMsg->msgData[3] = 0; /* Parameter */ - TriggerMsg->msgData[4] = 4; /* Task ID */ - - if (coredev->device_flags & SMS_ROM_NO_RESPONSE) { - rc = coredev->sendrequest_handler( - coredev->context, TriggerMsg, - TriggerMsg->xMsgHeader.msgLength); - msleep(100); - } else - rc = smscore_sendrequest_and_wait( - coredev, TriggerMsg, - TriggerMsg->xMsgHeader.msgLength, - &coredev->trigger_done); - } else { - SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ, - sizeof(struct SmsMsgHdr_ST)); - - rc = coredev->sendrequest_handler(coredev->context, - msg, msg->msgLength); - } - msleep(500); - } - - sms_debug("rc=%d, postload=%p ", rc, - coredev->postload_handler); - - kfree(msg); - - return ((rc >= 0) && coredev->postload_handler) ? - coredev->postload_handler(coredev->context) : - rc; -} - -/** - * loads specified firmware into a buffer and calls device loadfirmware_handler - * - * @param coredev pointer to a coredev object returned by - * smscore_register_device - * @param filename null-terminated string specifies firmware file name - * @param loadfirmware_handler device handler that loads firmware - * - * @return 0 on success, <0 on error. - */ -static int smscore_load_firmware_from_file(struct smscore_device_t *coredev, - char *filename, - loadfirmware_t loadfirmware_handler) -{ - int rc = -ENOENT; - const struct firmware *fw; - u8 *fw_buffer; - - if (loadfirmware_handler == NULL && !(coredev->device_flags & - SMS_DEVICE_FAMILY2)) - return -EINVAL; - - rc = request_firmware(&fw, filename, coredev->device); - if (rc < 0) { - sms_info("failed to open \"%s\"", filename); - return rc; - } - sms_info("read FW %s, size=%zd", filename, fw->size); - fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), - GFP_KERNEL | GFP_DMA); - if (fw_buffer) { - memcpy(fw_buffer, fw->data, fw->size); - - rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ? - smscore_load_firmware_family2(coredev, - fw_buffer, - fw->size) : - loadfirmware_handler(coredev->context, - fw_buffer, fw->size); - - kfree(fw_buffer); - } else { - sms_info("failed to allocate firmware buffer"); - rc = -ENOMEM; - } - - release_firmware(fw); - - return rc; -} - -/** - * notifies all clients registered with the device, notifies hotplugs, - * frees all buffers and coredev object - * - * @param coredev pointer to a coredev object returned by - * smscore_register_device - * - * @return 0 on success, <0 on error. - */ -void smscore_unregister_device(struct smscore_device_t *coredev) -{ - struct smscore_buffer_t *cb; - int num_buffers = 0; - int retry = 0; - - kmutex_lock(&g_smscore_deviceslock); - - /* Release input device (IR) resources */ - sms_ir_exit(coredev); - - smscore_notify_clients(coredev); - smscore_notify_callbacks(coredev, NULL, 0); - - /* at this point all buffers should be back - * onresponse must no longer be called */ - - while (1) { - while (!list_empty(&coredev->buffers)) { - cb = (struct smscore_buffer_t *) coredev->buffers.next; - list_del(&cb->entry); - kfree(cb); - num_buffers++; - } - if (num_buffers == coredev->num_buffers) - break; - if (++retry > 10) { - sms_info("exiting although " - "not all buffers released."); - break; - } - - sms_info("waiting for %d buffer(s)", - coredev->num_buffers - num_buffers); - msleep(100); - } - - sms_info("freed %d buffers", num_buffers); - - if (coredev->common_buffer) - dma_free_coherent(NULL, coredev->common_buffer_size, - coredev->common_buffer, coredev->common_buffer_phys); - - if (coredev->fw_buf != NULL) - kfree(coredev->fw_buf); - - list_del(&coredev->entry); - kfree(coredev); - - kmutex_unlock(&g_smscore_deviceslock); - - sms_info("device %p destroyed", coredev); -} -EXPORT_SYMBOL_GPL(smscore_unregister_device); - -static int smscore_detect_mode(struct smscore_device_t *coredev) -{ - void *buffer = kmalloc(sizeof(struct SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT, - GFP_KERNEL | GFP_DMA); - struct SmsMsgHdr_ST *msg = - (struct SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer); - int rc; - - if (!buffer) - return -ENOMEM; - - SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ, - sizeof(struct SmsMsgHdr_ST)); - - rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, - &coredev->version_ex_done); - if (rc == -ETIME) { - sms_err("MSG_SMS_GET_VERSION_EX_REQ failed first try"); - - if (wait_for_completion_timeout(&coredev->resume_done, - msecs_to_jiffies(5000))) { - rc = smscore_sendrequest_and_wait( - coredev, msg, msg->msgLength, - &coredev->version_ex_done); - if (rc < 0) - sms_err("MSG_SMS_GET_VERSION_EX_REQ failed " - "second try, rc %d", rc); - } else - rc = -ETIME; - } - - kfree(buffer); - - return rc; -} - -static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { - /*Stellar NOVA A0 Nova B0 VEGA*/ - /*DVBT*/ - {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, - /*DVBH*/ - {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, - /*TDMB*/ - {"none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none"}, - /*DABIP*/ - {"none", "none", "none", "none"}, - /*BDA*/ - {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, - /*ISDBT*/ - {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, - /*ISDBTBDA*/ - {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, - /*CMMB*/ - {"none", "none", "none", "cmmb_vega_12mhz.inp"} -}; - -static inline char *sms_get_fw_name(struct smscore_device_t *coredev, - int mode, enum sms_device_type_st type) -{ - char **fw = sms_get_board(smscore_get_board_id(coredev))->fw; - return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type]; -} - -/** - * calls device handler to change mode of operation - * NOTE: stellar/usb may disconnect when changing mode - * - * @param coredev pointer to a coredev object returned by - * smscore_register_device - * @param mode requested mode of operation - * - * @return 0 on success, <0 on error. - */ -int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) -{ - void *buffer; - int rc = 0; - enum sms_device_type_st type; - - sms_debug("set device mode to %d", mode); - if (coredev->device_flags & SMS_DEVICE_FAMILY2) { - if (mode < DEVICE_MODE_DVBT || mode >= DEVICE_MODE_RAW_TUNER) { - sms_err("invalid mode specified %d", mode); - return -EINVAL; - } - - smscore_registry_setmode(coredev->devpath, mode); - - if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) { - rc = smscore_detect_mode(coredev); - if (rc < 0) { - sms_err("mode detect failed %d", rc); - return rc; - } - } - - if (coredev->mode == mode) { - sms_info("device mode %d already set", mode); - return 0; - } - - if (!(coredev->modes_supported & (1 << mode))) { - char *fw_filename; - - type = smscore_registry_gettype(coredev->devpath); - fw_filename = sms_get_fw_name(coredev, mode, type); - - rc = smscore_load_firmware_from_file(coredev, - fw_filename, NULL); - if (rc < 0) { - sms_warn("error %d loading firmware: %s, " - "trying again with default firmware", - rc, fw_filename); - - /* try again with the default firmware */ - fw_filename = smscore_fw_lkup[mode][type]; - rc = smscore_load_firmware_from_file(coredev, - fw_filename, NULL); - - if (rc < 0) { - sms_warn("error %d loading " - "firmware: %s", rc, - fw_filename); - return rc; - } - } - sms_log("firmware download success: %s", fw_filename); - } else - sms_info("mode %d supported by running " - "firmware", mode); - - buffer = kmalloc(sizeof(struct SmsMsgData_ST) + - SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); - if (buffer) { - struct SmsMsgData_ST *msg = - (struct SmsMsgData_ST *) - SMS_ALIGN_ADDRESS(buffer); - - SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ, - sizeof(struct SmsMsgData_ST)); - msg->msgData[0] = mode; - - rc = smscore_sendrequest_and_wait( - coredev, msg, msg->xMsgHeader.msgLength, - &coredev->init_device_done); - - kfree(buffer); - } else { - sms_err("Could not allocate buffer for " - "init device message."); - rc = -ENOMEM; - } - } else { - if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { - sms_err("invalid mode specified %d", mode); - return -EINVAL; - } - - smscore_registry_setmode(coredev->devpath, mode); - - if (coredev->detectmode_handler) - coredev->detectmode_handler(coredev->context, - &coredev->mode); - - if (coredev->mode != mode && coredev->setmode_handler) - rc = coredev->setmode_handler(coredev->context, mode); - } - - if (rc >= 0) { - coredev->mode = mode; - coredev->device_flags &= ~SMS_DEVICE_NOT_READY; - } - - if (rc < 0) - sms_err("return error code %d.", rc); - return rc; -} - -/** - * calls device handler to get current mode of operation - * - * @param coredev pointer to a coredev object returned by - * smscore_register_device - * - * @return current mode - */ -int smscore_get_device_mode(struct smscore_device_t *coredev) -{ - return coredev->mode; -} -EXPORT_SYMBOL_GPL(smscore_get_device_mode); - -/** - * find client by response id & type within the clients list. - * return client handle or NULL. - * - * @param coredev pointer to a coredev object returned by - * smscore_register_device - * @param data_type client data type (SMS_DONT_CARE for all types) - * @param id client id (SMS_DONT_CARE for all id) - * - */ -static struct -smscore_client_t *smscore_find_client(struct smscore_device_t *coredev, - int data_type, int id) -{ - struct smscore_client_t *client = NULL; - struct list_head *next, *first; - unsigned long flags; - struct list_head *firstid, *nextid; - - - spin_lock_irqsave(&coredev->clientslock, flags); - first = &coredev->clients; - for (next = first->next; - (next != first) && !client; - next = next->next) { - firstid = &((struct smscore_client_t *)next)->idlist; - for (nextid = firstid->next; - nextid != firstid; - nextid = nextid->next) { - if ((((struct smscore_idlist_t *)nextid)->id == id) && - (((struct smscore_idlist_t *)nextid)->data_type == data_type || - (((struct smscore_idlist_t *)nextid)->data_type == 0))) { - client = (struct smscore_client_t *) next; - break; - } - } - } - spin_unlock_irqrestore(&coredev->clientslock, flags); - return client; -} - -/** - * find client by response id/type, call clients onresponse handler - * return buffer to pool on error - * - * @param coredev pointer to a coredev object returned by - * smscore_register_device - * @param cb pointer to response buffer descriptor - * - */ -void smscore_onresponse(struct smscore_device_t *coredev, - struct smscore_buffer_t *cb) { - struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) ((u8 *) cb->p - + cb->offset); - struct smscore_client_t *client; - int rc = -EBUSY; - static unsigned long last_sample_time; /* = 0; */ - static int data_total; /* = 0; */ - unsigned long time_now = jiffies_to_msecs(jiffies); - - if (!last_sample_time) - last_sample_time = time_now; - - if (time_now - last_sample_time > 10000) { - sms_debug("\ndata rate %d bytes/secs", - (int)((data_total * 1000) / - (time_now - last_sample_time))); - - last_sample_time = time_now; - data_total = 0; - } - - data_total += cb->size; - /* Do we need to re-route? */ - if ((phdr->msgType == MSG_SMS_HO_PER_SLICES_IND) || - (phdr->msgType == MSG_SMS_TRANSMISSION_IND)) { - if (coredev->mode == DEVICE_MODE_DVBT_BDA) - phdr->msgDstId = DVBT_BDA_CONTROL_MSG_ID; - } - - - client = smscore_find_client(coredev, phdr->msgType, phdr->msgDstId); - - /* If no client registered for type & id, - * check for control client where type is not registered */ - if (client) - rc = client->onresponse_handler(client->context, cb); - - if (rc < 0) { - switch (phdr->msgType) { - case MSG_SMS_GET_VERSION_EX_RES: - { - struct SmsVersionRes_ST *ver = - (struct SmsVersionRes_ST *) phdr; - sms_debug("MSG_SMS_GET_VERSION_EX_RES " - "id %d prots 0x%x ver %d.%d", - ver->FirmwareId, ver->SupportedProtocols, - ver->RomVersionMajor, ver->RomVersionMinor); - - coredev->mode = ver->FirmwareId == 255 ? - DEVICE_MODE_NONE : ver->FirmwareId; - coredev->modes_supported = ver->SupportedProtocols; - - complete(&coredev->version_ex_done); - break; - } - case MSG_SMS_INIT_DEVICE_RES: - sms_debug("MSG_SMS_INIT_DEVICE_RES"); - complete(&coredev->init_device_done); - break; - case MSG_SW_RELOAD_START_RES: - sms_debug("MSG_SW_RELOAD_START_RES"); - complete(&coredev->reload_start_done); - break; - case MSG_SMS_DATA_DOWNLOAD_RES: - complete(&coredev->data_download_done); - break; - case MSG_SW_RELOAD_EXEC_RES: - sms_debug("MSG_SW_RELOAD_EXEC_RES"); - break; - case MSG_SMS_SWDOWNLOAD_TRIGGER_RES: - sms_debug("MSG_SMS_SWDOWNLOAD_TRIGGER_RES"); - complete(&coredev->trigger_done); - break; - case MSG_SMS_SLEEP_RESUME_COMP_IND: - complete(&coredev->resume_done); - break; - case MSG_SMS_GPIO_CONFIG_EX_RES: - sms_debug("MSG_SMS_GPIO_CONFIG_EX_RES"); - complete(&coredev->gpio_configuration_done); - break; - case MSG_SMS_GPIO_SET_LEVEL_RES: - sms_debug("MSG_SMS_GPIO_SET_LEVEL_RES"); - complete(&coredev->gpio_set_level_done); - break; - case MSG_SMS_GPIO_GET_LEVEL_RES: - { - u32 *msgdata = (u32 *) phdr; - coredev->gpio_get_res = msgdata[1]; - sms_debug("MSG_SMS_GPIO_GET_LEVEL_RES gpio level %d", - coredev->gpio_get_res); - complete(&coredev->gpio_get_level_done); - break; - } - case MSG_SMS_START_IR_RES: - complete(&coredev->ir_init_done); - break; - case MSG_SMS_IR_SAMPLES_IND: - sms_ir_event(coredev, - (const char *) - ((char *)phdr - + sizeof(struct SmsMsgHdr_ST)), - (int)phdr->msgLength - - sizeof(struct SmsMsgHdr_ST)); - break; - - default: - break; - } - smscore_putbuffer(coredev, cb); - } -} -EXPORT_SYMBOL_GPL(smscore_onresponse); - -/** - * return pointer to next free buffer descriptor from core pool - * - * @param coredev pointer to a coredev object returned by - * smscore_register_device - * - * @return pointer to descriptor on success, NULL on error. - */ - -struct smscore_buffer_t *get_entry(struct smscore_device_t *coredev) -{ - struct smscore_buffer_t *cb = NULL; - unsigned long flags; - - spin_lock_irqsave(&coredev->bufferslock, flags); - if (!list_empty(&coredev->buffers)) { - cb = (struct smscore_buffer_t *) coredev->buffers.next; - list_del(&cb->entry); - } - spin_unlock_irqrestore(&coredev->bufferslock, flags); - return cb; -} - -struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev) -{ - struct smscore_buffer_t *cb = NULL; - - wait_event(coredev->buffer_mng_waitq, (cb = get_entry(coredev))); - - return cb; -} -EXPORT_SYMBOL_GPL(smscore_getbuffer); - -/** - * return buffer descriptor to a pool - * - * @param coredev pointer to a coredev object returned by - * smscore_register_device - * @param cb pointer buffer descriptor - * - */ -void smscore_putbuffer(struct smscore_device_t *coredev, - struct smscore_buffer_t *cb) { - wake_up_interruptible(&coredev->buffer_mng_waitq); - list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock); -} -EXPORT_SYMBOL_GPL(smscore_putbuffer); - -static int smscore_validate_client(struct smscore_device_t *coredev, - struct smscore_client_t *client, - int data_type, int id) -{ - struct smscore_idlist_t *listentry; - struct smscore_client_t *registered_client; - - if (!client) { - sms_err("bad parameter."); - return -EINVAL; - } - registered_client = smscore_find_client(coredev, data_type, id); - if (registered_client == client) - return 0; - - if (registered_client) { - sms_err("The msg ID already registered to another client."); - return -EEXIST; - } - listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL); - if (!listentry) { - sms_err("Can't allocate memory for client id."); - return -ENOMEM; - } - listentry->id = id; - listentry->data_type = data_type; - list_add_locked(&listentry->entry, &client->idlist, - &coredev->clientslock); - return 0; -} - -/** - * creates smsclient object, check that id is taken by another client - * - * @param coredev pointer to a coredev object from clients hotplug - * @param initial_id all messages with this id would be sent to this client - * @param data_type all messages of this type would be sent to this client - * @param onresponse_handler client handler that is called to - * process incoming messages - * @param onremove_handler client handler that is called when device is removed - * @param context client-specific context - * @param client pointer to a value that receives created smsclient object - * - * @return 0 on success, <0 on error. - */ -int smscore_register_client(struct smscore_device_t *coredev, - struct smsclient_params_t *params, - struct smscore_client_t **client) -{ - struct smscore_client_t *newclient; - /* check that no other channel with same parameters exists */ - if (smscore_find_client(coredev, params->data_type, - params->initial_id)) { - sms_err("Client already exist."); - return -EEXIST; - } - - newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL); - if (!newclient) { - sms_err("Failed to allocate memory for client."); - return -ENOMEM; - } - - INIT_LIST_HEAD(&newclient->idlist); - newclient->coredev = coredev; - newclient->onresponse_handler = params->onresponse_handler; - newclient->onremove_handler = params->onremove_handler; - newclient->context = params->context; - list_add_locked(&newclient->entry, &coredev->clients, - &coredev->clientslock); - smscore_validate_client(coredev, newclient, params->data_type, - params->initial_id); - *client = newclient; - sms_debug("%p %d %d", params->context, params->data_type, - params->initial_id); - - return 0; -} -EXPORT_SYMBOL_GPL(smscore_register_client); - -/** - * frees smsclient object and all subclients associated with it - * - * @param client pointer to smsclient object returned by - * smscore_register_client - * - */ -void smscore_unregister_client(struct smscore_client_t *client) -{ - struct smscore_device_t *coredev = client->coredev; - unsigned long flags; - - spin_lock_irqsave(&coredev->clientslock, flags); - - - while (!list_empty(&client->idlist)) { - struct smscore_idlist_t *identry = - (struct smscore_idlist_t *) client->idlist.next; - list_del(&identry->entry); - kfree(identry); - } - - sms_info("%p", client->context); - - list_del(&client->entry); - kfree(client); - - spin_unlock_irqrestore(&coredev->clientslock, flags); -} -EXPORT_SYMBOL_GPL(smscore_unregister_client); - -/** - * verifies that source id is not taken by another client, - * calls device handler to send requests to the device - * - * @param client pointer to smsclient object returned by - * smscore_register_client - * @param buffer pointer to a request buffer - * @param size size (in bytes) of request buffer - * - * @return 0 on success, <0 on error. - */ -int smsclient_sendrequest(struct smscore_client_t *client, - void *buffer, size_t size) -{ - struct smscore_device_t *coredev; - struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) buffer; - int rc; - - if (client == NULL) { - sms_err("Got NULL client"); - return -EINVAL; - } - - coredev = client->coredev; - - /* check that no other channel with same id exists */ - if (coredev == NULL) { - sms_err("Got NULL coredev"); - return -EINVAL; - } - - rc = smscore_validate_client(client->coredev, client, 0, - phdr->msgSrcId); - if (rc < 0) - return rc; - - return coredev->sendrequest_handler(coredev->context, buffer, size); -} -EXPORT_SYMBOL_GPL(smsclient_sendrequest); - - -/* old GPIO managements implementation */ -int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, - struct smscore_config_gpio *pinconfig) -{ - struct { - struct SmsMsgHdr_ST hdr; - u32 data[6]; - } msg; - - if (coredev->device_flags & SMS_DEVICE_FAMILY2) { - msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - msg.hdr.msgDstId = HIF_TASK; - msg.hdr.msgFlags = 0; - msg.hdr.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ; - msg.hdr.msgLength = sizeof(msg); - - msg.data[0] = pin; - msg.data[1] = pinconfig->pullupdown; - - /* Convert slew rate for Nova: Fast(0) = 3 / Slow(1) = 0; */ - msg.data[2] = pinconfig->outputslewrate == 0 ? 3 : 0; - - switch (pinconfig->outputdriving) { - case SMS_GPIO_OUTPUTDRIVING_16mA: - msg.data[3] = 7; /* Nova - 16mA */ - break; - case SMS_GPIO_OUTPUTDRIVING_12mA: - msg.data[3] = 5; /* Nova - 11mA */ - break; - case SMS_GPIO_OUTPUTDRIVING_8mA: - msg.data[3] = 3; /* Nova - 7mA */ - break; - case SMS_GPIO_OUTPUTDRIVING_4mA: - default: - msg.data[3] = 2; /* Nova - 4mA */ - break; - } - - msg.data[4] = pinconfig->direction; - msg.data[5] = 0; - } else /* TODO: SMS_DEVICE_FAMILY1 */ - return -EINVAL; - - return coredev->sendrequest_handler(coredev->context, - &msg, sizeof(msg)); -} - -int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level) -{ - struct { - struct SmsMsgHdr_ST hdr; - u32 data[3]; - } msg; - - if (pin > MAX_GPIO_PIN_NUMBER) - return -EINVAL; - - msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - msg.hdr.msgDstId = HIF_TASK; - msg.hdr.msgFlags = 0; - msg.hdr.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ; - msg.hdr.msgLength = sizeof(msg); - - msg.data[0] = pin; - msg.data[1] = level ? 1 : 0; - msg.data[2] = 0; - - return coredev->sendrequest_handler(coredev->context, - &msg, sizeof(msg)); -} - -/* new GPIO management implementation */ -static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum, - u32 *pGroupNum, u32 *pGroupCfg) { - - *pGroupCfg = 1; - - if (PinNum <= 1) { - *pTranslatedPinNum = 0; - *pGroupNum = 9; - *pGroupCfg = 2; - } else if (PinNum >= 2 && PinNum <= 6) { - *pTranslatedPinNum = 2; - *pGroupNum = 0; - *pGroupCfg = 2; - } else if (PinNum >= 7 && PinNum <= 11) { - *pTranslatedPinNum = 7; - *pGroupNum = 1; - } else if (PinNum >= 12 && PinNum <= 15) { - *pTranslatedPinNum = 12; - *pGroupNum = 2; - *pGroupCfg = 3; - } else if (PinNum == 16) { - *pTranslatedPinNum = 16; - *pGroupNum = 23; - } else if (PinNum >= 17 && PinNum <= 24) { - *pTranslatedPinNum = 17; - *pGroupNum = 3; - } else if (PinNum == 25) { - *pTranslatedPinNum = 25; - *pGroupNum = 6; - } else if (PinNum >= 26 && PinNum <= 28) { - *pTranslatedPinNum = 26; - *pGroupNum = 4; - } else if (PinNum == 29) { - *pTranslatedPinNum = 29; - *pGroupNum = 5; - *pGroupCfg = 2; - } else if (PinNum == 30) { - *pTranslatedPinNum = 30; - *pGroupNum = 8; - } else if (PinNum == 31) { - *pTranslatedPinNum = 31; - *pGroupNum = 17; - } else - return -1; - - *pGroupCfg <<= 24; - - return 0; -} - -int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum, - struct smscore_gpio_config *pGpioConfig) { - - u32 totalLen; - u32 TranslatedPinNum = 0; - u32 GroupNum = 0; - u32 ElectricChar; - u32 groupCfg; - void *buffer; - int rc; - - struct SetGpioMsg { - struct SmsMsgHdr_ST xMsgHeader; - u32 msgData[6]; - } *pMsg; - - - if (PinNum > MAX_GPIO_PIN_NUMBER) - return -EINVAL; - - if (pGpioConfig == NULL) - return -EINVAL; - - totalLen = sizeof(struct SmsMsgHdr_ST) + (sizeof(u32) * 6); - - buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT, - GFP_KERNEL | GFP_DMA); - if (!buffer) - return -ENOMEM; - - pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer); - - pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - pMsg->xMsgHeader.msgDstId = HIF_TASK; - pMsg->xMsgHeader.msgFlags = 0; - pMsg->xMsgHeader.msgLength = (u16) totalLen; - pMsg->msgData[0] = PinNum; - - if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) { - pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ; - if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum, - &groupCfg) != 0) { - rc = -EINVAL; - goto free; - } - - pMsg->msgData[1] = TranslatedPinNum; - pMsg->msgData[2] = GroupNum; - ElectricChar = (pGpioConfig->PullUpDown) - | (pGpioConfig->InputCharacteristics << 2) - | (pGpioConfig->OutputSlewRate << 3) - | (pGpioConfig->OutputDriving << 4); - pMsg->msgData[3] = ElectricChar; - pMsg->msgData[4] = pGpioConfig->Direction; - pMsg->msgData[5] = groupCfg; - } else { - pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ; - pMsg->msgData[1] = pGpioConfig->PullUpDown; - pMsg->msgData[2] = pGpioConfig->OutputSlewRate; - pMsg->msgData[3] = pGpioConfig->OutputDriving; - pMsg->msgData[4] = pGpioConfig->Direction; - pMsg->msgData[5] = 0; - } - - smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg); - rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen, - &coredev->gpio_configuration_done); - - if (rc != 0) { - if (rc == -ETIME) - sms_err("smscore_gpio_configure timeout"); - else - sms_err("smscore_gpio_configure error"); - } -free: - kfree(buffer); - - return rc; -} - -int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum, - u8 NewLevel) { - - u32 totalLen; - int rc; - void *buffer; - - struct SetGpioMsg { - struct SmsMsgHdr_ST xMsgHeader; - u32 msgData[3]; /* keep it 3 ! */ - } *pMsg; - - if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER)) - return -EINVAL; - - totalLen = sizeof(struct SmsMsgHdr_ST) + - (3 * sizeof(u32)); /* keep it 3 ! */ - - buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT, - GFP_KERNEL | GFP_DMA); - if (!buffer) - return -ENOMEM; - - pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer); - - pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - pMsg->xMsgHeader.msgDstId = HIF_TASK; - pMsg->xMsgHeader.msgFlags = 0; - pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ; - pMsg->xMsgHeader.msgLength = (u16) totalLen; - pMsg->msgData[0] = PinNum; - pMsg->msgData[1] = NewLevel; - - /* Send message to SMS */ - smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg); - rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen, - &coredev->gpio_set_level_done); - - if (rc != 0) { - if (rc == -ETIME) - sms_err("smscore_gpio_set_level timeout"); - else - sms_err("smscore_gpio_set_level error"); - } - kfree(buffer); - - return rc; -} - -int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum, - u8 *level) { - - u32 totalLen; - int rc; - void *buffer; - - struct SetGpioMsg { - struct SmsMsgHdr_ST xMsgHeader; - u32 msgData[2]; - } *pMsg; - - - if (PinNum > MAX_GPIO_PIN_NUMBER) - return -EINVAL; - - totalLen = sizeof(struct SmsMsgHdr_ST) + (2 * sizeof(u32)); - - buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT, - GFP_KERNEL | GFP_DMA); - if (!buffer) - return -ENOMEM; - - pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer); - - pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - pMsg->xMsgHeader.msgDstId = HIF_TASK; - pMsg->xMsgHeader.msgFlags = 0; - pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_GET_LEVEL_REQ; - pMsg->xMsgHeader.msgLength = (u16) totalLen; - pMsg->msgData[0] = PinNum; - pMsg->msgData[1] = 0; - - /* Send message to SMS */ - smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg); - rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen, - &coredev->gpio_get_level_done); - - if (rc != 0) { - if (rc == -ETIME) - sms_err("smscore_gpio_get_level timeout"); - else - sms_err("smscore_gpio_get_level error"); - } - kfree(buffer); - - /* Its a race between other gpio_get_level() and the copy of the single - * global 'coredev->gpio_get_res' to the function's variable 'level' - */ - *level = coredev->gpio_get_res; - - return rc; -} - -static int __init smscore_module_init(void) -{ - int rc = 0; - - INIT_LIST_HEAD(&g_smscore_notifyees); - INIT_LIST_HEAD(&g_smscore_devices); - kmutex_init(&g_smscore_deviceslock); - - INIT_LIST_HEAD(&g_smscore_registry); - kmutex_init(&g_smscore_registrylock); - - return rc; -} - -static void __exit smscore_module_exit(void) -{ - kmutex_lock(&g_smscore_deviceslock); - while (!list_empty(&g_smscore_notifyees)) { - struct smscore_device_notifyee_t *notifyee = - (struct smscore_device_notifyee_t *) - g_smscore_notifyees.next; - - list_del(¬ifyee->entry); - kfree(notifyee); - } - kmutex_unlock(&g_smscore_deviceslock); - - kmutex_lock(&g_smscore_registrylock); - while (!list_empty(&g_smscore_registry)) { - struct smscore_registry_entry_t *entry = - (struct smscore_registry_entry_t *) - g_smscore_registry.next; - - list_del(&entry->entry); - kfree(entry); - } - kmutex_unlock(&g_smscore_registrylock); - - sms_debug(""); -} - -module_init(smscore_module_init); -module_exit(smscore_module_exit); - -MODULE_DESCRIPTION("Siano MDTV Core module"); -MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/media/dvb/siano/smscoreapi.h b/ANDROID_3.4.5/drivers/media/dvb/siano/smscoreapi.h deleted file mode 100644 index c592ae09..00000000 --- a/ANDROID_3.4.5/drivers/media/dvb/siano/smscoreapi.h +++ /dev/null @@ -1,775 +0,0 @@ -/**************************************************************** - -Siano Mobile Silicon, Inc. -MDTV receiver kernel modules. -Copyright (C) 2006-2008, Uri Shkolnik, Anatoly Greenblat - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - - This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. - -****************************************************************/ - -#ifndef __SMS_CORE_API_H__ -#define __SMS_CORE_API_H__ - -#include <linux/device.h> -#include <linux/list.h> -#include <linux/mm.h> -#include <linux/scatterlist.h> -#include <linux/types.h> -#include <linux/mutex.h> -#include <linux/wait.h> -#include <linux/timer.h> - -#include <asm/page.h> - -#include "smsir.h" - -#define kmutex_init(_p_) mutex_init(_p_) -#define kmutex_lock(_p_) mutex_lock(_p_) -#define kmutex_trylock(_p_) mutex_trylock(_p_) -#define kmutex_unlock(_p_) mutex_unlock(_p_) - -#ifndef min -#define min(a, b) (((a) < (b)) ? (a) : (b)) -#endif - -#define SMS_PROTOCOL_MAX_RAOUNDTRIP_MS (10000) -#define SMS_ALLOC_ALIGNMENT 128 -#define SMS_DMA_ALIGNMENT 16 -#define SMS_ALIGN_ADDRESS(addr) \ - ((((uintptr_t)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1)) - -#define SMS_DEVICE_FAMILY2 1 -#define SMS_ROM_NO_RESPONSE 2 -#define SMS_DEVICE_NOT_READY 0x8000000 - -enum sms_device_type_st { - SMS_STELLAR = 0, - SMS_NOVA_A0, - SMS_NOVA_B0, - SMS_VEGA, - SMS_NUM_OF_DEVICE_TYPES -}; - -struct smscore_device_t; -struct smscore_client_t; -struct smscore_buffer_t; - -typedef int (*hotplug_t)(struct smscore_device_t *coredev, - struct device *device, int arrival); - -typedef int (*setmode_t)(void *context, int mode); -typedef void (*detectmode_t)(void *context, int *mode); -typedef int (*sendrequest_t)(void *context, void *buffer, size_t size); -typedef int (*loadfirmware_t)(void *context, void *buffer, size_t size); -typedef int (*preload_t)(void *context); -typedef int (*postload_t)(void *context); - -typedef int (*onresponse_t)(void *context, struct smscore_buffer_t *cb); -typedef void (*onremove_t)(void *context); - -struct smscore_buffer_t { - /* public members, once passed to clients can be changed freely */ - struct list_head entry; - int size; - int offset; - - /* private members, read-only for clients */ - void *p; - dma_addr_t phys; - unsigned long offset_in_common; -}; - -struct smsdevice_params_t { - struct device *device; - - int buffer_size; - int num_buffers; - - char devpath[32]; - unsigned long flags; - - setmode_t setmode_handler; - detectmode_t detectmode_handler; - sendrequest_t sendrequest_handler; - preload_t preload_handler; - postload_t postload_handler; - - void *context; - enum sms_device_type_st device_type; -}; - -struct smsclient_params_t { - int initial_id; - int data_type; - onresponse_t onresponse_handler; - onremove_t onremove_handler; - void *context; -}; - -struct smscore_device_t { - struct list_head entry; - - struct list_head clients; - struct list_head subclients; - spinlock_t clientslock; - - struct list_head buffers; - spinlock_t bufferslock; - int num_buffers; - - void *common_buffer; - int common_buffer_size; - dma_addr_t common_buffer_phys; - - void *context; - struct device *device; - - char devpath[32]; - unsigned long device_flags; - - setmode_t setmode_handler; - detectmode_t detectmode_handler; - sendrequest_t sendrequest_handler; - preload_t preload_handler; - postload_t postload_handler; - - int mode, modes_supported; - - /* host <--> device messages */ - struct completion version_ex_done, data_download_done, trigger_done; - struct completion init_device_done, reload_start_done, resume_done; - struct completion gpio_configuration_done, gpio_set_level_done; - struct completion gpio_get_level_done, ir_init_done; - - /* Buffer management */ - wait_queue_head_t buffer_mng_waitq; - - /* GPIO */ - int gpio_get_res; - - /* Target hardware board */ - int board_id; - - /* Firmware */ - u8 *fw_buf; - u32 fw_buf_size; - - /* Infrared (IR) */ - struct ir_t ir; - - int led_state; -}; - -/* GPIO definitions for antenna frequency domain control (SMS8021) */ -#define SMS_ANTENNA_GPIO_0 1 -#define SMS_ANTENNA_GPIO_1 0 - -#define BW_8_MHZ 0 -#define BW_7_MHZ 1 -#define BW_6_MHZ 2 -#define BW_5_MHZ 3 -#define BW_ISDBT_1SEG 4 -#define BW_ISDBT_3SEG 5 - -#define MSG_HDR_FLAG_SPLIT_MSG 4 - -#define MAX_GPIO_PIN_NUMBER 31 - -#define HIF_TASK 11 -#define SMS_HOST_LIB 150 -#define DVBT_BDA_CONTROL_MSG_ID 201 - -#define SMS_MAX_PAYLOAD_SIZE 240 -#define SMS_TUNE_TIMEOUT 500 - -#define MSG_SMS_GPIO_CONFIG_REQ 507 -#define MSG_SMS_GPIO_CONFIG_RES 508 -#define MSG_SMS_GPIO_SET_LEVEL_REQ 509 -#define MSG_SMS_GPIO_SET_LEVEL_RES 510 -#define MSG_SMS_GPIO_GET_LEVEL_REQ 511 -#define MSG_SMS_GPIO_GET_LEVEL_RES 512 -#define MSG_SMS_RF_TUNE_REQ 561 -#define MSG_SMS_RF_TUNE_RES 562 -#define MSG_SMS_INIT_DEVICE_REQ 578 -#define MSG_SMS_INIT_DEVICE_RES 579 -#define MSG_SMS_ADD_PID_FILTER_REQ 601 -#define MSG_SMS_ADD_PID_FILTER_RES 602 -#define MSG_SMS_REMOVE_PID_FILTER_REQ 603 -#define MSG_SMS_REMOVE_PID_FILTER_RES 604 -#define MSG_SMS_DAB_CHANNEL 607 -#define MSG_SMS_GET_PID_FILTER_LIST_REQ 608 -#define MSG_SMS_GET_PID_FILTER_LIST_RES 609 -#define MSG_SMS_GET_STATISTICS_RES 616 -#define MSG_SMS_GET_STATISTICS_REQ 615 -#define MSG_SMS_HO_PER_SLICES_IND 630 -#define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651 -#define MSG_SMS_SET_ANTENNA_CONFIG_RES 652 -#define MSG_SMS_SLEEP_RESUME_COMP_IND 655 -#define MSG_SMS_DATA_DOWNLOAD_REQ 660 -#define MSG_SMS_DATA_DOWNLOAD_RES 661 -#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ 664 -#define MSG_SMS_SWDOWNLOAD_TRIGGER_RES 665 -#define MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ 666 -#define MSG_SMS_SWDOWNLOAD_BACKDOOR_RES 667 -#define MSG_SMS_GET_VERSION_EX_REQ 668 -#define MSG_SMS_GET_VERSION_EX_RES 669 -#define MSG_SMS_SET_CLOCK_OUTPUT_REQ 670 -#define MSG_SMS_I2C_SET_FREQ_REQ 685 -#define MSG_SMS_GENERIC_I2C_REQ 687 -#define MSG_SMS_GENERIC_I2C_RES 688 -#define MSG_SMS_DVBT_BDA_DATA 693 -#define MSG_SW_RELOAD_REQ 697 -#define MSG_SMS_DATA_MSG 699 -#define MSG_SW_RELOAD_START_REQ 702 -#define MSG_SW_RELOAD_START_RES 703 -#define MSG_SW_RELOAD_EXEC_REQ 704 -#define MSG_SW_RELOAD_EXEC_RES 705 -#define MSG_SMS_SPI_INT_LINE_SET_REQ 710 -#define MSG_SMS_GPIO_CONFIG_EX_REQ 712 -#define MSG_SMS_GPIO_CONFIG_EX_RES 713 -#define MSG_SMS_ISDBT_TUNE_REQ 776 -#define MSG_SMS_ISDBT_TUNE_RES 777 -#define MSG_SMS_TRANSMISSION_IND 782 -#define MSG_SMS_START_IR_REQ 800 -#define MSG_SMS_START_IR_RES 801 -#define MSG_SMS_IR_SAMPLES_IND 802 -#define MSG_SMS_SIGNAL_DETECTED_IND 827 -#define MSG_SMS_NO_SIGNAL_IND 828 - -#define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \ - (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \ - (ptr)->msgLength = len; (ptr)->msgFlags = 0; \ -} while (0) - -#define SMS_INIT_MSG(ptr, type, len) \ - SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len) - -enum SMS_DVB3_EVENTS { - DVB3_EVENT_INIT = 0, - DVB3_EVENT_SLEEP, - DVB3_EVENT_HOTPLUG, - DVB3_EVENT_FE_LOCK, - DVB3_EVENT_FE_UNLOCK, - DVB3_EVENT_UNC_OK, - DVB3_EVENT_UNC_ERR -}; - -enum SMS_DEVICE_MODE { - DEVICE_MODE_NONE = -1, - DEVICE_MODE_DVBT = 0, - DEVICE_MODE_DVBH, - DEVICE_MODE_DAB_TDMB, - DEVICE_MODE_DAB_TDMB_DABIP, - DEVICE_MODE_DVBT_BDA, - DEVICE_MODE_ISDBT, - DEVICE_MODE_ISDBT_BDA, - DEVICE_MODE_CMMB, - DEVICE_MODE_RAW_TUNER, - DEVICE_MODE_MAX, -}; - -struct SmsMsgHdr_ST { - u16 msgType; - u8 msgSrcId; - u8 msgDstId; - u16 msgLength; /* Length of entire message, including header */ - u16 msgFlags; -}; - -struct SmsMsgData_ST { - struct SmsMsgHdr_ST xMsgHeader; - u32 msgData[1]; -}; - -struct SmsMsgData_ST2 { - struct SmsMsgHdr_ST xMsgHeader; - u32 msgData[2]; -}; - -struct SmsDataDownload_ST { - struct SmsMsgHdr_ST xMsgHeader; - u32 MemAddr; - u8 Payload[SMS_MAX_PAYLOAD_SIZE]; -}; - -struct SmsVersionRes_ST { - struct SmsMsgHdr_ST xMsgHeader; - - u16 ChipModel; /* e.g. 0x1102 for SMS-1102 "Nova" */ - u8 Step; /* 0 - Step A */ - u8 MetalFix; /* 0 - Metal 0 */ - - /* FirmwareId 0xFF if ROM, otherwise the - * value indicated by SMSHOSTLIB_DEVICE_MODES_E */ - u8 FirmwareId; - /* SupportedProtocols Bitwise OR combination of - * supported protocols */ - u8 SupportedProtocols; - - u8 VersionMajor; - u8 VersionMinor; - u8 VersionPatch; - u8 VersionFieldPatch; - - u8 RomVersionMajor; - u8 RomVersionMinor; - u8 RomVersionPatch; - u8 RomVersionFieldPatch; - - u8 TextLabel[34]; -}; - -struct SmsFirmware_ST { - u32 CheckSum; - u32 Length; - u32 StartAddress; - u8 Payload[1]; -}; - -/* Statistics information returned as response for - * SmsHostApiGetStatistics_Req */ -struct SMSHOSTLIB_STATISTICS_ST { - u32 Reserved; /* Reserved */ - - /* Common parameters */ - u32 IsRfLocked; /* 0 - not locked, 1 - locked */ - u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ - u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ - - /* Reception quality */ - s32 SNR; /* dB */ - u32 BER; /* Post Viterbi BER [1E-5] */ - u32 FIB_CRC; /* CRC errors percentage, valid only for DAB */ - u32 TS_PER; /* Transport stream PER, - 0xFFFFFFFF indicate N/A, valid only for DVB-T/H */ - u32 MFER; /* DVB-H frame error rate in percentage, - 0xFFFFFFFF indicate N/A, valid only for DVB-H */ - s32 RSSI; /* dBm */ - s32 InBandPwr; /* In band power in dBM */ - s32 CarrierOffset; /* Carrier Offset in bin/1024 */ - - /* Transmission parameters */ - u32 Frequency; /* Frequency in Hz */ - u32 Bandwidth; /* Bandwidth in MHz, valid only for DVB-T/H */ - u32 TransmissionMode; /* Transmission Mode, for DAB modes 1-4, - for DVB-T/H FFT mode carriers in Kilos */ - u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET, - valid only for DVB-T/H */ - u32 GuardInterval; /* Guard Interval from - SMSHOSTLIB_GUARD_INTERVALS_ET, valid only for DVB-T/H */ - u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET, - valid only for DVB-T/H */ - u32 LPCodeRate; /* Low Priority Code Rate from - SMSHOSTLIB_CODE_RATE_ET, valid only for DVB-T/H */ - u32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET, - valid only for DVB-T/H */ - u32 Constellation; /* Constellation from - SMSHOSTLIB_CONSTELLATION_ET, valid only for DVB-T/H */ - - /* Burst parameters, valid only for DVB-H */ - u32 BurstSize; /* Current burst size in bytes, - valid only for DVB-H */ - u32 BurstDuration; /* Current burst duration in mSec, - valid only for DVB-H */ - u32 BurstCycleTime; /* Current burst cycle time in mSec, - valid only for DVB-H */ - u32 CalculatedBurstCycleTime;/* Current burst cycle time in mSec, - as calculated by demodulator, valid only for DVB-H */ - u32 NumOfRows; /* Number of rows in MPE table, - valid only for DVB-H */ - u32 NumOfPaddCols; /* Number of padding columns in MPE table, - valid only for DVB-H */ - u32 NumOfPunctCols; /* Number of puncturing columns in MPE table, - valid only for DVB-H */ - u32 ErrorTSPackets; /* Number of erroneous - transport-stream packets */ - u32 TotalTSPackets; /* Total number of transport-stream packets */ - u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include - errors after MPE RS decoding */ - u32 NumOfInvalidMpeTlbs;/* Number of MPE tables which include errors - after MPE RS decoding */ - u32 NumOfCorrectedMpeTlbs;/* Number of MPE tables which were - corrected by MPE RS decoding */ - /* Common params */ - u32 BERErrorCount; /* Number of errornous SYNC bits. */ - u32 BERBitCount; /* Total number of SYNC bits. */ - - /* Interface information */ - u32 SmsToHostTxErrors; /* Total number of transmission errors. */ - - /* DAB/T-DMB */ - u32 PreBER; /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */ - - /* DVB-H TPS parameters */ - u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; - if set to 0xFFFFFFFF cell_id not yet recovered */ - u32 DvbhSrvIndHP; /* DVB-H service indication info, bit 1 - - Time Slicing indicator, bit 0 - MPE-FEC indicator */ - u32 DvbhSrvIndLP; /* DVB-H service indication info, bit 1 - - Time Slicing indicator, bit 0 - MPE-FEC indicator */ - - u32 NumMPEReceived; /* DVB-H, Num MPE section received */ - - u32 ReservedFields[10]; /* Reserved */ -}; - -struct SmsMsgStatisticsInfo_ST { - u32 RequestResult; - - struct SMSHOSTLIB_STATISTICS_ST Stat; - - /* Split the calc of the SNR in DAB */ - u32 Signal; /* dB */ - u32 Noise; /* dB */ - -}; - -struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST { - /* Per-layer information */ - u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET, - * 255 means layer does not exist */ - u32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET, - * 255 means layer does not exist */ - u32 BER; /* Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */ - u32 BERErrorCount; /* Post Viterbi Error Bits Count */ - u32 BERBitCount; /* Post Viterbi Total Bits Count */ - u32 PreBER; /* Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */ - u32 TS_PER; /* Transport stream PER [%], 0xFFFFFFFF indicate N/A */ - u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */ - u32 TotalTSPackets; /* Total number of transport-stream packets */ - u32 TILdepthI; /* Time interleaver depth I parameter, - * 255 means layer does not exist */ - u32 NumberOfSegments; /* Number of segments in layer A, - * 255 means layer does not exist */ - u32 TMCCErrors; /* TMCC errors */ -}; - -struct SMSHOSTLIB_STATISTICS_ISDBT_ST { - u32 StatisticsType; /* Enumerator identifying the type of the - * structure. Values are the same as - * SMSHOSTLIB_DEVICE_MODES_E - * - * This field MUST always be first in any - * statistics structure */ - - u32 FullSize; /* Total size of the structure returned by the modem. - * If the size requested by the host is smaller than - * FullSize, the struct will be truncated */ - - /* Common parameters */ - u32 IsRfLocked; /* 0 - not locked, 1 - locked */ - u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ - u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ - - /* Reception quality */ - s32 SNR; /* dB */ - s32 RSSI; /* dBm */ - s32 InBandPwr; /* In band power in dBM */ - s32 CarrierOffset; /* Carrier Offset in Hz */ - - /* Transmission parameters */ - u32 Frequency; /* Frequency in Hz */ - u32 Bandwidth; /* Bandwidth in MHz */ - u32 TransmissionMode; /* ISDB-T transmission mode */ - u32 ModemState; /* 0 - Acquisition, 1 - Locked */ - u32 GuardInterval; /* Guard Interval, 1 divided by value */ - u32 SystemType; /* ISDB-T system type (ISDB-T / ISDB-Tsb) */ - u32 PartialReception; /* TRUE - partial reception, FALSE otherwise */ - u32 NumOfLayers; /* Number of ISDB-T layers in the network */ - - /* Per-layer information */ - /* Layers A, B and C */ - struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST LayerInfo[3]; - /* Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST */ - - /* Interface information */ - u32 SmsToHostTxErrors; /* Total number of transmission errors. */ -}; - -struct PID_STATISTICS_DATA_S { - struct PID_BURST_S { - u32 size; - u32 padding_cols; - u32 punct_cols; - u32 duration; - u32 cycle; - u32 calc_cycle; - } burst; - - u32 tot_tbl_cnt; - u32 invalid_tbl_cnt; - u32 tot_cor_tbl; -}; - -struct PID_DATA_S { - u32 pid; - u32 num_rows; - struct PID_STATISTICS_DATA_S pid_statistics; -}; - -#define CORRECT_STAT_RSSI(_stat) ((_stat).RSSI *= -1) -#define CORRECT_STAT_BANDWIDTH(_stat) (_stat.Bandwidth = 8 - _stat.Bandwidth) -#define CORRECT_STAT_TRANSMISSON_MODE(_stat) \ - if (_stat.TransmissionMode == 0) \ - _stat.TransmissionMode = 2; \ - else if (_stat.TransmissionMode == 1) \ - _stat.TransmissionMode = 8; \ - else \ - _stat.TransmissionMode = 4; - -struct TRANSMISSION_STATISTICS_S { - u32 Frequency; /* Frequency in Hz */ - u32 Bandwidth; /* Bandwidth in MHz */ - u32 TransmissionMode; /* FFT mode carriers in Kilos */ - u32 GuardInterval; /* Guard Interval from - SMSHOSTLIB_GUARD_INTERVALS_ET */ - u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET */ - u32 LPCodeRate; /* Low Priority Code Rate from - SMSHOSTLIB_CODE_RATE_ET */ - u32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET */ - u32 Constellation; /* Constellation from - SMSHOSTLIB_CONSTELLATION_ET */ - - /* DVB-H TPS parameters */ - u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; - if set to 0xFFFFFFFF cell_id not yet recovered */ - u32 DvbhSrvIndHP; /* DVB-H service indication info, bit 1 - - Time Slicing indicator, bit 0 - MPE-FEC indicator */ - u32 DvbhSrvIndLP; /* DVB-H service indication info, bit 1 - - Time Slicing indicator, bit 0 - MPE-FEC indicator */ - u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ -}; - -struct RECEPTION_STATISTICS_S { - u32 IsRfLocked; /* 0 - not locked, 1 - locked */ - u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ - u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ - - u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */ - s32 SNR; /* dB */ - u32 BER; /* Post Viterbi BER [1E-5] */ - u32 BERErrorCount; /* Number of erronous SYNC bits. */ - u32 BERBitCount; /* Total number of SYNC bits. */ - u32 TS_PER; /* Transport stream PER, - 0xFFFFFFFF indicate N/A */ - u32 MFER; /* DVB-H frame error rate in percentage, - 0xFFFFFFFF indicate N/A, valid only for DVB-H */ - s32 RSSI; /* dBm */ - s32 InBandPwr; /* In band power in dBM */ - s32 CarrierOffset; /* Carrier Offset in bin/1024 */ - u32 ErrorTSPackets; /* Number of erroneous - transport-stream packets */ - u32 TotalTSPackets; /* Total number of transport-stream packets */ - - s32 MRC_SNR; /* dB */ - s32 MRC_RSSI; /* dBm */ - s32 MRC_InBandPwr; /* In band power in dBM */ -}; - - -/* Statistics information returned as response for - * SmsHostApiGetStatisticsEx_Req for DVB applications, SMS1100 and up */ -struct SMSHOSTLIB_STATISTICS_DVB_S { - /* Reception */ - struct RECEPTION_STATISTICS_S ReceptionData; - - /* Transmission parameters */ - struct TRANSMISSION_STATISTICS_S TransmissionData; - - /* Burst parameters, valid only for DVB-H */ -#define SRVM_MAX_PID_FILTERS 8 - struct PID_DATA_S PidData[SRVM_MAX_PID_FILTERS]; -}; - -struct SRVM_SIGNAL_STATUS_S { - u32 result; - u32 snr; - u32 tsPackets; - u32 etsPackets; - u32 constellation; - u32 hpCode; - u32 tpsSrvIndLP; - u32 tpsSrvIndHP; - u32 cellId; - u32 reason; - - s32 inBandPower; - u32 requestId; -}; - -struct SMSHOSTLIB_I2C_REQ_ST { - u32 DeviceAddress; /* I2c device address */ - u32 WriteCount; /* number of bytes to write */ - u32 ReadCount; /* number of bytes to read */ - u8 Data[1]; -}; - -struct SMSHOSTLIB_I2C_RES_ST { - u32 Status; /* non-zero value in case of failure */ - u32 ReadCount; /* number of bytes read */ - u8 Data[1]; -}; - - -struct smscore_config_gpio { -#define SMS_GPIO_DIRECTION_INPUT 0 -#define SMS_GPIO_DIRECTION_OUTPUT 1 - u8 direction; - -#define SMS_GPIO_PULLUPDOWN_NONE 0 -#define SMS_GPIO_PULLUPDOWN_PULLDOWN 1 -#define SMS_GPIO_PULLUPDOWN_PULLUP 2 -#define SMS_GPIO_PULLUPDOWN_KEEPER 3 - u8 pullupdown; - -#define SMS_GPIO_INPUTCHARACTERISTICS_NORMAL 0 -#define SMS_GPIO_INPUTCHARACTERISTICS_SCHMITT 1 - u8 inputcharacteristics; - -#define SMS_GPIO_OUTPUTSLEWRATE_FAST 0 -#define SMS_GPIO_OUTPUTSLEWRATE_SLOW 1 - u8 outputslewrate; - -#define SMS_GPIO_OUTPUTDRIVING_4mA 0 -#define SMS_GPIO_OUTPUTDRIVING_8mA 1 -#define SMS_GPIO_OUTPUTDRIVING_12mA 2 -#define SMS_GPIO_OUTPUTDRIVING_16mA 3 - u8 outputdriving; -}; - -struct smscore_gpio_config { -#define SMS_GPIO_DIRECTION_INPUT 0 -#define SMS_GPIO_DIRECTION_OUTPUT 1 - u8 Direction; - -#define SMS_GPIO_PULL_UP_DOWN_NONE 0 -#define SMS_GPIO_PULL_UP_DOWN_PULLDOWN 1 -#define SMS_GPIO_PULL_UP_DOWN_PULLUP 2 -#define SMS_GPIO_PULL_UP_DOWN_KEEPER 3 - u8 PullUpDown; - -#define SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL 0 -#define SMS_GPIO_INPUT_CHARACTERISTICS_SCHMITT 1 - u8 InputCharacteristics; - -#define SMS_GPIO_OUTPUT_SLEW_RATE_SLOW 1 /* 10xx */ -#define SMS_GPIO_OUTPUT_SLEW_RATE_FAST 0 /* 10xx */ - - -#define SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS 0 /* 11xx */ -#define SMS_GPIO_OUTPUT_SLEW_RATE_0_9_V_NS 1 /* 11xx */ -#define SMS_GPIO_OUTPUT_SLEW_RATE_1_7_V_NS 2 /* 11xx */ -#define SMS_GPIO_OUTPUT_SLEW_RATE_3_3_V_NS 3 /* 11xx */ - u8 OutputSlewRate; - -#define SMS_GPIO_OUTPUT_DRIVING_S_4mA 0 /* 10xx */ -#define SMS_GPIO_OUTPUT_DRIVING_S_8mA 1 /* 10xx */ -#define SMS_GPIO_OUTPUT_DRIVING_S_12mA 2 /* 10xx */ -#define SMS_GPIO_OUTPUT_DRIVING_S_16mA 3 /* 10xx */ - -#define SMS_GPIO_OUTPUT_DRIVING_1_5mA 0 /* 11xx */ -#define SMS_GPIO_OUTPUT_DRIVING_2_8mA 1 /* 11xx */ -#define SMS_GPIO_OUTPUT_DRIVING_4mA 2 /* 11xx */ -#define SMS_GPIO_OUTPUT_DRIVING_7mA 3 /* 11xx */ -#define SMS_GPIO_OUTPUT_DRIVING_10mA 4 /* 11xx */ -#define SMS_GPIO_OUTPUT_DRIVING_11mA 5 /* 11xx */ -#define SMS_GPIO_OUTPUT_DRIVING_14mA 6 /* 11xx */ -#define SMS_GPIO_OUTPUT_DRIVING_16mA 7 /* 11xx */ - u8 OutputDriving; -}; - -extern void smscore_registry_setmode(char *devpath, int mode); -extern int smscore_registry_getmode(char *devpath); - -extern int smscore_register_hotplug(hotplug_t hotplug); -extern void smscore_unregister_hotplug(hotplug_t hotplug); - -extern int smscore_register_device(struct smsdevice_params_t *params, - struct smscore_device_t **coredev); -extern void smscore_unregister_device(struct smscore_device_t *coredev); - -extern int smscore_start_device(struct smscore_device_t *coredev); -extern int smscore_load_firmware(struct smscore_device_t *coredev, - char *filename, - loadfirmware_t loadfirmware_handler); - -extern int smscore_set_device_mode(struct smscore_device_t *coredev, int mode); -extern int smscore_get_device_mode(struct smscore_device_t *coredev); - -extern int smscore_register_client(struct smscore_device_t *coredev, - struct smsclient_params_t *params, - struct smscore_client_t **client); -extern void smscore_unregister_client(struct smscore_client_t *client); - -extern int smsclient_sendrequest(struct smscore_client_t *client, - void *buffer, size_t size); -extern void smscore_onresponse(struct smscore_device_t *coredev, - struct smscore_buffer_t *cb); - -extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev); -extern int smscore_map_common_buffer(struct smscore_device_t *coredev, - struct vm_area_struct *vma); -extern int smscore_get_fw_filename(struct smscore_device_t *coredev, - int mode, char *filename); -extern int smscore_send_fw_file(struct smscore_device_t *coredev, - u8 *ufwbuf, int size); - -extern -struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev); -extern void smscore_putbuffer(struct smscore_device_t *coredev, - struct smscore_buffer_t *cb); - -/* old GPIO management */ -int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, - struct smscore_config_gpio *pinconfig); -int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level); - -/* new GPIO management */ -extern int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum, - struct smscore_gpio_config *pGpioConfig); -extern int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum, - u8 NewLevel); -extern int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum, - u8 *level); - -void smscore_set_board_id(struct smscore_device_t *core, int id); -int smscore_get_board_id(struct smscore_device_t *core); - -int smscore_led_state(struct smscore_device_t *core, int led); - - -/* ------------------------------------------------------------------------ */ - -#define DBG_INFO 1 -#define DBG_ADV 2 - -#define sms_printk(kern, fmt, arg...) \ - printk(kern "%s: " fmt "\n", __func__, ##arg) - -#define dprintk(kern, lvl, fmt, arg...) do {\ - if (sms_dbg & lvl) \ - sms_printk(kern, fmt, ##arg); } while (0) - -#define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg) -#define sms_err(fmt, arg...) \ - sms_printk(KERN_ERR, "line: %d: " fmt, __LINE__, ##arg) -#define sms_warn(fmt, arg...) sms_printk(KERN_WARNING, fmt, ##arg) -#define sms_info(fmt, arg...) \ - dprintk(KERN_INFO, DBG_INFO, fmt, ##arg) -#define sms_debug(fmt, arg...) \ - dprintk(KERN_DEBUG, DBG_ADV, fmt, ##arg) - - -#endif /* __SMS_CORE_API_H__ */ diff --git a/ANDROID_3.4.5/drivers/media/dvb/siano/smsdvb.c b/ANDROID_3.4.5/drivers/media/dvb/siano/smsdvb.c deleted file mode 100644 index aa77e54a..00000000 --- a/ANDROID_3.4.5/drivers/media/dvb/siano/smsdvb.c +++ /dev/null @@ -1,1078 +0,0 @@ -/**************************************************************** - -Siano Mobile Silicon, Inc. -MDTV receiver kernel modules. -Copyright (C) 2006-2008, Uri Shkolnik - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - - This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. - -****************************************************************/ - -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/init.h> - -#include "dmxdev.h" -#include "dvbdev.h" -#include "dvb_demux.h" -#include "dvb_frontend.h" - -#include "smscoreapi.h" -#include "smsendian.h" -#include "sms-cards.h" - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -struct smsdvb_client_t { - struct list_head entry; - - struct smscore_device_t *coredev; - struct smscore_client_t *smsclient; - - struct dvb_adapter adapter; - struct dvb_demux demux; - struct dmxdev dmxdev; - struct dvb_frontend frontend; - - fe_status_t fe_status; - - struct completion tune_done; - - struct SMSHOSTLIB_STATISTICS_DVB_S sms_stat_dvb; - int event_fe_state; - int event_unc_state; -}; - -static struct list_head g_smsdvb_clients; -static struct mutex g_smsdvb_clientslock; - -static int sms_dbg; -module_param_named(debug, sms_dbg, int, 0644); -MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); - -/* Events that may come from DVB v3 adapter */ -static void sms_board_dvb3_event(struct smsdvb_client_t *client, - enum SMS_DVB3_EVENTS event) { - - struct smscore_device_t *coredev = client->coredev; - switch (event) { - case DVB3_EVENT_INIT: - sms_debug("DVB3_EVENT_INIT"); - sms_board_event(coredev, BOARD_EVENT_BIND); - break; - case DVB3_EVENT_SLEEP: - sms_debug("DVB3_EVENT_SLEEP"); - sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND); - break; - case DVB3_EVENT_HOTPLUG: - sms_debug("DVB3_EVENT_HOTPLUG"); - sms_board_event(coredev, BOARD_EVENT_POWER_INIT); - break; - case DVB3_EVENT_FE_LOCK: - if (client->event_fe_state != DVB3_EVENT_FE_LOCK) { - client->event_fe_state = DVB3_EVENT_FE_LOCK; - sms_debug("DVB3_EVENT_FE_LOCK"); - sms_board_event(coredev, BOARD_EVENT_FE_LOCK); - } - break; - case DVB3_EVENT_FE_UNLOCK: - if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK) { - client->event_fe_state = DVB3_EVENT_FE_UNLOCK; - sms_debug("DVB3_EVENT_FE_UNLOCK"); - sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK); - } - break; - case DVB3_EVENT_UNC_OK: - if (client->event_unc_state != DVB3_EVENT_UNC_OK) { - client->event_unc_state = DVB3_EVENT_UNC_OK; - sms_debug("DVB3_EVENT_UNC_OK"); - sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK); - } - break; - case DVB3_EVENT_UNC_ERR: - if (client->event_unc_state != DVB3_EVENT_UNC_ERR) { - client->event_unc_state = DVB3_EVENT_UNC_ERR; - sms_debug("DVB3_EVENT_UNC_ERR"); - sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS); - } - break; - - default: - sms_err("Unknown dvb3 api event"); - break; - } -} - - -static void smsdvb_update_dvb_stats(struct RECEPTION_STATISTICS_S *pReceptionData, - struct SMSHOSTLIB_STATISTICS_ST *p) -{ - if (sms_dbg & 2) { - printk(KERN_DEBUG "Reserved = %d", p->Reserved); - printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked); - printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked); - printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn); - printk(KERN_DEBUG "SNR = %d", p->SNR); - printk(KERN_DEBUG "BER = %d", p->BER); - printk(KERN_DEBUG "FIB_CRC = %d", p->FIB_CRC); - printk(KERN_DEBUG "TS_PER = %d", p->TS_PER); - printk(KERN_DEBUG "MFER = %d", p->MFER); - printk(KERN_DEBUG "RSSI = %d", p->RSSI); - printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr); - printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset); - printk(KERN_DEBUG "Frequency = %d", p->Frequency); - printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth); - printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode); - printk(KERN_DEBUG "ModemState = %d", p->ModemState); - printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval); - printk(KERN_DEBUG "CodeRate = %d", p->CodeRate); - printk(KERN_DEBUG "LPCodeRate = %d", p->LPCodeRate); - printk(KERN_DEBUG "Hierarchy = %d", p->Hierarchy); - printk(KERN_DEBUG "Constellation = %d", p->Constellation); - printk(KERN_DEBUG "BurstSize = %d", p->BurstSize); - printk(KERN_DEBUG "BurstDuration = %d", p->BurstDuration); - printk(KERN_DEBUG "BurstCycleTime = %d", p->BurstCycleTime); - printk(KERN_DEBUG "CalculatedBurstCycleTime = %d", p->CalculatedBurstCycleTime); - printk(KERN_DEBUG "NumOfRows = %d", p->NumOfRows); - printk(KERN_DEBUG "NumOfPaddCols = %d", p->NumOfPaddCols); - printk(KERN_DEBUG "NumOfPunctCols = %d", p->NumOfPunctCols); - printk(KERN_DEBUG "ErrorTSPackets = %d", p->ErrorTSPackets); - printk(KERN_DEBUG "TotalTSPackets = %d", p->TotalTSPackets); - printk(KERN_DEBUG "NumOfValidMpeTlbs = %d", p->NumOfValidMpeTlbs); - printk(KERN_DEBUG "NumOfInvalidMpeTlbs = %d", p->NumOfInvalidMpeTlbs); - printk(KERN_DEBUG "NumOfCorrectedMpeTlbs = %d", p->NumOfCorrectedMpeTlbs); - printk(KERN_DEBUG "BERErrorCount = %d", p->BERErrorCount); - printk(KERN_DEBUG "BERBitCount = %d", p->BERBitCount); - printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors); - printk(KERN_DEBUG "PreBER = %d", p->PreBER); - printk(KERN_DEBUG "CellId = %d", p->CellId); - printk(KERN_DEBUG "DvbhSrvIndHP = %d", p->DvbhSrvIndHP); - printk(KERN_DEBUG "DvbhSrvIndLP = %d", p->DvbhSrvIndLP); - printk(KERN_DEBUG "NumMPEReceived = %d", p->NumMPEReceived); - } - - pReceptionData->IsDemodLocked = p->IsDemodLocked; - - pReceptionData->SNR = p->SNR; - pReceptionData->BER = p->BER; - pReceptionData->BERErrorCount = p->BERErrorCount; - pReceptionData->InBandPwr = p->InBandPwr; - pReceptionData->ErrorTSPackets = p->ErrorTSPackets; -}; - - -static void smsdvb_update_isdbt_stats(struct RECEPTION_STATISTICS_S *pReceptionData, - struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p) -{ - int i; - - if (sms_dbg & 2) { - printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked); - printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked); - printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn); - printk(KERN_DEBUG "SNR = %d", p->SNR); - printk(KERN_DEBUG "RSSI = %d", p->RSSI); - printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr); - printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset); - printk(KERN_DEBUG "Frequency = %d", p->Frequency); - printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth); - printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode); - printk(KERN_DEBUG "ModemState = %d", p->ModemState); - printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval); - printk(KERN_DEBUG "SystemType = %d", p->SystemType); - printk(KERN_DEBUG "PartialReception = %d", p->PartialReception); - printk(KERN_DEBUG "NumOfLayers = %d", p->NumOfLayers); - printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors); - - for (i = 0; i < 3; i++) { - printk(KERN_DEBUG "%d: CodeRate = %d", i, p->LayerInfo[i].CodeRate); - printk(KERN_DEBUG "%d: Constellation = %d", i, p->LayerInfo[i].Constellation); - printk(KERN_DEBUG "%d: BER = %d", i, p->LayerInfo[i].BER); - printk(KERN_DEBUG "%d: BERErrorCount = %d", i, p->LayerInfo[i].BERErrorCount); - printk(KERN_DEBUG "%d: BERBitCount = %d", i, p->LayerInfo[i].BERBitCount); - printk(KERN_DEBUG "%d: PreBER = %d", i, p->LayerInfo[i].PreBER); - printk(KERN_DEBUG "%d: TS_PER = %d", i, p->LayerInfo[i].TS_PER); - printk(KERN_DEBUG "%d: ErrorTSPackets = %d", i, p->LayerInfo[i].ErrorTSPackets); - printk(KERN_DEBUG "%d: TotalTSPackets = %d", i, p->LayerInfo[i].TotalTSPackets); - printk(KERN_DEBUG "%d: TILdepthI = %d", i, p->LayerInfo[i].TILdepthI); - printk(KERN_DEBUG "%d: NumberOfSegments = %d", i, p->LayerInfo[i].NumberOfSegments); - printk(KERN_DEBUG "%d: TMCCErrors = %d", i, p->LayerInfo[i].TMCCErrors); - } - } - - pReceptionData->IsDemodLocked = p->IsDemodLocked; - - pReceptionData->SNR = p->SNR; - pReceptionData->InBandPwr = p->InBandPwr; - - pReceptionData->ErrorTSPackets = 0; - pReceptionData->BER = 0; - pReceptionData->BERErrorCount = 0; - for (i = 0; i < 3; i++) { - pReceptionData->BER += p->LayerInfo[i].BER; - pReceptionData->BERErrorCount += p->LayerInfo[i].BERErrorCount; - pReceptionData->ErrorTSPackets += p->LayerInfo[i].ErrorTSPackets; - } -} - -static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) -{ - struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; - struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) (((u8 *) cb->p) - + cb->offset); - u32 *pMsgData = (u32 *) phdr + 1; - /*u32 MsgDataLen = phdr->msgLength - sizeof(struct SmsMsgHdr_ST);*/ - bool is_status_update = false; - - smsendian_handle_rx_message((struct SmsMsgData_ST *) phdr); - - switch (phdr->msgType) { - case MSG_SMS_DVBT_BDA_DATA: - dvb_dmx_swfilter(&client->demux, (u8 *)(phdr + 1), - cb->size - sizeof(struct SmsMsgHdr_ST)); - break; - - case MSG_SMS_RF_TUNE_RES: - case MSG_SMS_ISDBT_TUNE_RES: - complete(&client->tune_done); - break; - - case MSG_SMS_SIGNAL_DETECTED_IND: - sms_info("MSG_SMS_SIGNAL_DETECTED_IND"); - client->sms_stat_dvb.TransmissionData.IsDemodLocked = true; - is_status_update = true; - break; - - case MSG_SMS_NO_SIGNAL_IND: - sms_info("MSG_SMS_NO_SIGNAL_IND"); - client->sms_stat_dvb.TransmissionData.IsDemodLocked = false; - is_status_update = true; - break; - - case MSG_SMS_TRANSMISSION_IND: { - sms_info("MSG_SMS_TRANSMISSION_IND"); - - pMsgData++; - memcpy(&client->sms_stat_dvb.TransmissionData, pMsgData, - sizeof(struct TRANSMISSION_STATISTICS_S)); - - /* Mo need to correct guard interval - * (as opposed to old statistics message). - */ - CORRECT_STAT_BANDWIDTH(client->sms_stat_dvb.TransmissionData); - CORRECT_STAT_TRANSMISSON_MODE( - client->sms_stat_dvb.TransmissionData); - is_status_update = true; - break; - } - case MSG_SMS_HO_PER_SLICES_IND: { - struct RECEPTION_STATISTICS_S *pReceptionData = - &client->sms_stat_dvb.ReceptionData; - struct SRVM_SIGNAL_STATUS_S SignalStatusData; - - /*sms_info("MSG_SMS_HO_PER_SLICES_IND");*/ - pMsgData++; - SignalStatusData.result = pMsgData[0]; - SignalStatusData.snr = pMsgData[1]; - SignalStatusData.inBandPower = (s32) pMsgData[2]; - SignalStatusData.tsPackets = pMsgData[3]; - SignalStatusData.etsPackets = pMsgData[4]; - SignalStatusData.constellation = pMsgData[5]; - SignalStatusData.hpCode = pMsgData[6]; - SignalStatusData.tpsSrvIndLP = pMsgData[7] & 0x03; - SignalStatusData.tpsSrvIndHP = pMsgData[8] & 0x03; - SignalStatusData.cellId = pMsgData[9] & 0xFFFF; - SignalStatusData.reason = pMsgData[10]; - SignalStatusData.requestId = pMsgData[11]; - pReceptionData->IsRfLocked = pMsgData[16]; - pReceptionData->IsDemodLocked = pMsgData[17]; - pReceptionData->ModemState = pMsgData[12]; - pReceptionData->SNR = pMsgData[1]; - pReceptionData->BER = pMsgData[13]; - pReceptionData->RSSI = pMsgData[14]; - CORRECT_STAT_RSSI(client->sms_stat_dvb.ReceptionData); - - pReceptionData->InBandPwr = (s32) pMsgData[2]; - pReceptionData->CarrierOffset = (s32) pMsgData[15]; - pReceptionData->TotalTSPackets = pMsgData[3]; - pReceptionData->ErrorTSPackets = pMsgData[4]; - - /* TS PER */ - if ((SignalStatusData.tsPackets + SignalStatusData.etsPackets) - > 0) { - pReceptionData->TS_PER = (SignalStatusData.etsPackets - * 100) / (SignalStatusData.tsPackets - + SignalStatusData.etsPackets); - } else { - pReceptionData->TS_PER = 0; - } - - pReceptionData->BERBitCount = pMsgData[18]; - pReceptionData->BERErrorCount = pMsgData[19]; - - pReceptionData->MRC_SNR = pMsgData[20]; - pReceptionData->MRC_InBandPwr = pMsgData[21]; - pReceptionData->MRC_RSSI = pMsgData[22]; - - is_status_update = true; - break; - } - case MSG_SMS_GET_STATISTICS_RES: { - union { - struct SMSHOSTLIB_STATISTICS_ISDBT_ST isdbt; - struct SmsMsgStatisticsInfo_ST dvb; - } *p = (void *) (phdr + 1); - struct RECEPTION_STATISTICS_S *pReceptionData = - &client->sms_stat_dvb.ReceptionData; - - sms_info("MSG_SMS_GET_STATISTICS_RES"); - - is_status_update = true; - - switch (smscore_get_device_mode(client->coredev)) { - case DEVICE_MODE_ISDBT: - case DEVICE_MODE_ISDBT_BDA: - smsdvb_update_isdbt_stats(pReceptionData, &p->isdbt); - break; - default: - smsdvb_update_dvb_stats(pReceptionData, &p->dvb.Stat); - } - if (!pReceptionData->IsDemodLocked) { - pReceptionData->SNR = 0; - pReceptionData->BER = 0; - pReceptionData->BERErrorCount = 0; - pReceptionData->InBandPwr = 0; - pReceptionData->ErrorTSPackets = 0; - } - - complete(&client->tune_done); - break; - } - default: - sms_info("Unhandled message %d", phdr->msgType); - - } - smscore_putbuffer(client->coredev, cb); - - if (is_status_update) { - if (client->sms_stat_dvb.ReceptionData.IsDemodLocked) { - client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER - | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; - sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK); - if (client->sms_stat_dvb.ReceptionData.ErrorTSPackets - == 0) - sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK); - else - sms_board_dvb3_event(client, - DVB3_EVENT_UNC_ERR); - - } else { - if (client->sms_stat_dvb.ReceptionData.IsRfLocked) - client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER; - else - client->fe_status = 0; - sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK); - } - } - - return 0; -} - -static void smsdvb_unregister_client(struct smsdvb_client_t *client) -{ - /* must be called under clientslock */ - - list_del(&client->entry); - - smscore_unregister_client(client->smsclient); - dvb_unregister_frontend(&client->frontend); - dvb_dmxdev_release(&client->dmxdev); - dvb_dmx_release(&client->demux); - dvb_unregister_adapter(&client->adapter); - kfree(client); -} - -static void smsdvb_onremove(void *context) -{ - kmutex_lock(&g_smsdvb_clientslock); - - smsdvb_unregister_client((struct smsdvb_client_t *) context); - - kmutex_unlock(&g_smsdvb_clientslock); -} - -static int smsdvb_start_feed(struct dvb_demux_feed *feed) -{ - struct smsdvb_client_t *client = - container_of(feed->demux, struct smsdvb_client_t, demux); - struct SmsMsgData_ST PidMsg; - - sms_debug("add pid %d(%x)", - feed->pid, feed->pid); - - PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - PidMsg.xMsgHeader.msgDstId = HIF_TASK; - PidMsg.xMsgHeader.msgFlags = 0; - PidMsg.xMsgHeader.msgType = MSG_SMS_ADD_PID_FILTER_REQ; - PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); - PidMsg.msgData[0] = feed->pid; - - smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg); - return smsclient_sendrequest(client->smsclient, - &PidMsg, sizeof(PidMsg)); -} - -static int smsdvb_stop_feed(struct dvb_demux_feed *feed) -{ - struct smsdvb_client_t *client = - container_of(feed->demux, struct smsdvb_client_t, demux); - struct SmsMsgData_ST PidMsg; - - sms_debug("remove pid %d(%x)", - feed->pid, feed->pid); - - PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - PidMsg.xMsgHeader.msgDstId = HIF_TASK; - PidMsg.xMsgHeader.msgFlags = 0; - PidMsg.xMsgHeader.msgType = MSG_SMS_REMOVE_PID_FILTER_REQ; - PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); - PidMsg.msgData[0] = feed->pid; - - smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg); - return smsclient_sendrequest(client->smsclient, - &PidMsg, sizeof(PidMsg)); -} - -static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client, - void *buffer, size_t size, - struct completion *completion) -{ - int rc; - - smsendian_handle_tx_message((struct SmsMsgHdr_ST *)buffer); - rc = smsclient_sendrequest(client->smsclient, buffer, size); - if (rc < 0) - return rc; - - return wait_for_completion_timeout(completion, - msecs_to_jiffies(2000)) ? - 0 : -ETIME; -} - -static int smsdvb_send_statistics_request(struct smsdvb_client_t *client) -{ - int rc; - struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ, - DVBT_BDA_CONTROL_MSG_ID, - HIF_TASK, - sizeof(struct SmsMsgHdr_ST), 0 }; - - rc = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), - &client->tune_done); - - return rc; -} - -static inline int led_feedback(struct smsdvb_client_t *client) -{ - if (client->fe_status & FE_HAS_LOCK) - return sms_board_led_feedback(client->coredev, - (client->sms_stat_dvb.ReceptionData.BER - == 0) ? SMS_LED_HI : SMS_LED_LO); - else - return sms_board_led_feedback(client->coredev, SMS_LED_OFF); -} - -static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) -{ - int rc; - struct smsdvb_client_t *client; - client = container_of(fe, struct smsdvb_client_t, frontend); - - rc = smsdvb_send_statistics_request(client); - - *stat = client->fe_status; - - led_feedback(client); - - return rc; -} - -static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - int rc; - struct smsdvb_client_t *client; - client = container_of(fe, struct smsdvb_client_t, frontend); - - rc = smsdvb_send_statistics_request(client); - - *ber = client->sms_stat_dvb.ReceptionData.BER; - - led_feedback(client); - - return rc; -} - -static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - int rc; - - struct smsdvb_client_t *client; - client = container_of(fe, struct smsdvb_client_t, frontend); - - rc = smsdvb_send_statistics_request(client); - - if (client->sms_stat_dvb.ReceptionData.InBandPwr < -95) - *strength = 0; - else if (client->sms_stat_dvb.ReceptionData.InBandPwr > -29) - *strength = 100; - else - *strength = - (client->sms_stat_dvb.ReceptionData.InBandPwr - + 95) * 3 / 2; - - led_feedback(client); - - return rc; -} - -static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - int rc; - struct smsdvb_client_t *client; - client = container_of(fe, struct smsdvb_client_t, frontend); - - rc = smsdvb_send_statistics_request(client); - - *snr = client->sms_stat_dvb.ReceptionData.SNR; - - led_feedback(client); - - return rc; -} - -static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - int rc; - struct smsdvb_client_t *client; - client = container_of(fe, struct smsdvb_client_t, frontend); - - rc = smsdvb_send_statistics_request(client); - - *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets; - - led_feedback(client); - - return rc; -} - -static int smsdvb_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *tune) -{ - sms_debug(""); - - tune->min_delay_ms = 400; - tune->step_size = 250000; - tune->max_drift = 0; - return 0; -} - -static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - - struct { - struct SmsMsgHdr_ST Msg; - u32 Data[3]; - } Msg; - - int ret; - - client->fe_status = FE_HAS_SIGNAL; - client->event_fe_state = -1; - client->event_unc_state = -1; - fe->dtv_property_cache.delivery_system = SYS_DVBT; - - Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - Msg.Msg.msgDstId = HIF_TASK; - Msg.Msg.msgFlags = 0; - Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ; - Msg.Msg.msgLength = sizeof(Msg); - Msg.Data[0] = c->frequency; - Msg.Data[2] = 12000000; - - sms_info("%s: freq %d band %d", __func__, c->frequency, - c->bandwidth_hz); - - switch (c->bandwidth_hz / 1000000) { - case 8: - Msg.Data[1] = BW_8_MHZ; - break; - case 7: - Msg.Data[1] = BW_7_MHZ; - break; - case 6: - Msg.Data[1] = BW_6_MHZ; - break; - case 0: - return -EOPNOTSUPP; - default: - return -EINVAL; - } - /* Disable LNA, if any. An error is returned if no LNA is present */ - ret = sms_board_lna_control(client->coredev, 0); - if (ret == 0) { - fe_status_t status; - - /* tune with LNA off at first */ - ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), - &client->tune_done); - - smsdvb_read_status(fe, &status); - - if (status & FE_HAS_LOCK) - return ret; - - /* previous tune didn't lock - enable LNA and tune again */ - sms_board_lna_control(client->coredev, 1); - } - - return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), - &client->tune_done); -} - -static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - - struct { - struct SmsMsgHdr_ST Msg; - u32 Data[4]; - } Msg; - - fe->dtv_property_cache.delivery_system = SYS_ISDBT; - - Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - Msg.Msg.msgDstId = HIF_TASK; - Msg.Msg.msgFlags = 0; - Msg.Msg.msgType = MSG_SMS_ISDBT_TUNE_REQ; - Msg.Msg.msgLength = sizeof(Msg); - - if (c->isdbt_sb_segment_idx == -1) - c->isdbt_sb_segment_idx = 0; - - switch (c->isdbt_sb_segment_count) { - case 3: - Msg.Data[1] = BW_ISDBT_3SEG; - break; - case 1: - Msg.Data[1] = BW_ISDBT_1SEG; - break; - case 0: /* AUTO */ - switch (c->bandwidth_hz / 1000000) { - case 8: - case 7: - c->isdbt_sb_segment_count = 3; - Msg.Data[1] = BW_ISDBT_3SEG; - break; - case 6: - c->isdbt_sb_segment_count = 1; - Msg.Data[1] = BW_ISDBT_1SEG; - break; - default: /* Assumes 6 MHZ bw */ - c->isdbt_sb_segment_count = 1; - c->bandwidth_hz = 6000; - Msg.Data[1] = BW_ISDBT_1SEG; - break; - } - break; - default: - sms_info("Segment count %d not supported", c->isdbt_sb_segment_count); - return -EINVAL; - } - - Msg.Data[0] = c->frequency; - Msg.Data[2] = 12000000; - Msg.Data[3] = c->isdbt_sb_segment_idx; - - sms_info("%s: freq %d segwidth %d segindex %d\n", __func__, - c->frequency, c->isdbt_sb_segment_count, - c->isdbt_sb_segment_idx); - - return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), - &client->tune_done); -} - -static int smsdvb_set_frontend(struct dvb_frontend *fe) -{ - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - struct smscore_device_t *coredev = client->coredev; - - switch (smscore_get_device_mode(coredev)) { - case DEVICE_MODE_DVBT: - case DEVICE_MODE_DVBT_BDA: - return smsdvb_dvbt_set_frontend(fe); - case DEVICE_MODE_ISDBT: - case DEVICE_MODE_ISDBT_BDA: - return smsdvb_isdbt_set_frontend(fe); - default: - return -EINVAL; - } -} - -static int smsdvb_get_frontend(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *fep = &fe->dtv_property_cache; - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - struct smscore_device_t *coredev = client->coredev; - struct TRANSMISSION_STATISTICS_S *td = - &client->sms_stat_dvb.TransmissionData; - - switch (smscore_get_device_mode(coredev)) { - case DEVICE_MODE_DVBT: - case DEVICE_MODE_DVBT_BDA: - fep->frequency = td->Frequency; - - switch (td->Bandwidth) { - case 6: - fep->bandwidth_hz = 6000000; - break; - case 7: - fep->bandwidth_hz = 7000000; - break; - case 8: - fep->bandwidth_hz = 8000000; - break; - } - - switch (td->TransmissionMode) { - case 2: - fep->transmission_mode = TRANSMISSION_MODE_2K; - break; - case 8: - fep->transmission_mode = TRANSMISSION_MODE_8K; - } - - switch (td->GuardInterval) { - case 0: - fep->guard_interval = GUARD_INTERVAL_1_32; - break; - case 1: - fep->guard_interval = GUARD_INTERVAL_1_16; - break; - case 2: - fep->guard_interval = GUARD_INTERVAL_1_8; - break; - case 3: - fep->guard_interval = GUARD_INTERVAL_1_4; - break; - } - - switch (td->CodeRate) { - case 0: - fep->code_rate_HP = FEC_1_2; - break; - case 1: - fep->code_rate_HP = FEC_2_3; - break; - case 2: - fep->code_rate_HP = FEC_3_4; - break; - case 3: - fep->code_rate_HP = FEC_5_6; - break; - case 4: - fep->code_rate_HP = FEC_7_8; - break; - } - - switch (td->LPCodeRate) { - case 0: - fep->code_rate_LP = FEC_1_2; - break; - case 1: - fep->code_rate_LP = FEC_2_3; - break; - case 2: - fep->code_rate_LP = FEC_3_4; - break; - case 3: - fep->code_rate_LP = FEC_5_6; - break; - case 4: - fep->code_rate_LP = FEC_7_8; - break; - } - - switch (td->Constellation) { - case 0: - fep->modulation = QPSK; - break; - case 1: - fep->modulation = QAM_16; - break; - case 2: - fep->modulation = QAM_64; - break; - } - - switch (td->Hierarchy) { - case 0: - fep->hierarchy = HIERARCHY_NONE; - break; - case 1: - fep->hierarchy = HIERARCHY_1; - break; - case 2: - fep->hierarchy = HIERARCHY_2; - break; - case 3: - fep->hierarchy = HIERARCHY_4; - break; - } - - fep->inversion = INVERSION_AUTO; - break; - case DEVICE_MODE_ISDBT: - case DEVICE_MODE_ISDBT_BDA: - fep->frequency = td->Frequency; - fep->bandwidth_hz = 6000000; - /* todo: retrive the other parameters */ - break; - default: - return -EINVAL; - } - - return 0; -} - -static int smsdvb_init(struct dvb_frontend *fe) -{ - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - - sms_board_power(client->coredev, 1); - - sms_board_dvb3_event(client, DVB3_EVENT_INIT); - return 0; -} - -static int smsdvb_sleep(struct dvb_frontend *fe) -{ - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - - sms_board_led_feedback(client->coredev, SMS_LED_OFF); - sms_board_power(client->coredev, 0); - - sms_board_dvb3_event(client, DVB3_EVENT_SLEEP); - - return 0; -} - -static void smsdvb_release(struct dvb_frontend *fe) -{ - /* do nothing */ -} - -static struct dvb_frontend_ops smsdvb_fe_ops = { - .info = { - .name = "Siano Mobile Digital MDTV Receiver", - .frequency_min = 44250000, - .frequency_max = 867250000, - .frequency_stepsize = 250000, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | - FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_RECOVER | - FE_CAN_HIERARCHY_AUTO, - }, - - .release = smsdvb_release, - - .set_frontend = smsdvb_set_frontend, - .get_frontend = smsdvb_get_frontend, - .get_tune_settings = smsdvb_get_tune_settings, - - .read_status = smsdvb_read_status, - .read_ber = smsdvb_read_ber, - .read_signal_strength = smsdvb_read_signal_strength, - .read_snr = smsdvb_read_snr, - .read_ucblocks = smsdvb_read_ucblocks, - - .init = smsdvb_init, - .sleep = smsdvb_sleep, -}; - -static int smsdvb_hotplug(struct smscore_device_t *coredev, - struct device *device, int arrival) -{ - struct smsclient_params_t params; - struct smsdvb_client_t *client; - int rc; - - /* device removal handled by onremove callback */ - if (!arrival) - return 0; - client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL); - if (!client) { - sms_err("kmalloc() failed"); - return -ENOMEM; - } - - /* register dvb adapter */ - rc = dvb_register_adapter(&client->adapter, - sms_get_board( - smscore_get_board_id(coredev))->name, - THIS_MODULE, device, adapter_nr); - if (rc < 0) { - sms_err("dvb_register_adapter() failed %d", rc); - goto adapter_error; - } - - /* init dvb demux */ - client->demux.dmx.capabilities = DMX_TS_FILTERING; - client->demux.filternum = 32; /* todo: nova ??? */ - client->demux.feednum = 32; - client->demux.start_feed = smsdvb_start_feed; - client->demux.stop_feed = smsdvb_stop_feed; - - rc = dvb_dmx_init(&client->demux); - if (rc < 0) { - sms_err("dvb_dmx_init failed %d", rc); - goto dvbdmx_error; - } - - /* init dmxdev */ - client->dmxdev.filternum = 32; - client->dmxdev.demux = &client->demux.dmx; - client->dmxdev.capabilities = 0; - - rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter); - if (rc < 0) { - sms_err("dvb_dmxdev_init failed %d", rc); - goto dmxdev_error; - } - - /* init and register frontend */ - memcpy(&client->frontend.ops, &smsdvb_fe_ops, - sizeof(struct dvb_frontend_ops)); - - switch (smscore_get_device_mode(coredev)) { - case DEVICE_MODE_DVBT: - case DEVICE_MODE_DVBT_BDA: - client->frontend.ops.delsys[0] = SYS_DVBT; - break; - case DEVICE_MODE_ISDBT: - case DEVICE_MODE_ISDBT_BDA: - client->frontend.ops.delsys[0] = SYS_ISDBT; - break; - } - - rc = dvb_register_frontend(&client->adapter, &client->frontend); - if (rc < 0) { - sms_err("frontend registration failed %d", rc); - goto frontend_error; - } - - params.initial_id = 1; - params.data_type = MSG_SMS_DVBT_BDA_DATA; - params.onresponse_handler = smsdvb_onresponse; - params.onremove_handler = smsdvb_onremove; - params.context = client; - - rc = smscore_register_client(coredev, ¶ms, &client->smsclient); - if (rc < 0) { - sms_err("smscore_register_client() failed %d", rc); - goto client_error; - } - - client->coredev = coredev; - - init_completion(&client->tune_done); - - kmutex_lock(&g_smsdvb_clientslock); - - list_add(&client->entry, &g_smsdvb_clients); - - kmutex_unlock(&g_smsdvb_clientslock); - - client->event_fe_state = -1; - client->event_unc_state = -1; - sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG); - - sms_info("success"); - sms_board_setup(coredev); - - return 0; - -client_error: - dvb_unregister_frontend(&client->frontend); - -frontend_error: - dvb_dmxdev_release(&client->dmxdev); - -dmxdev_error: - dvb_dmx_release(&client->demux); - -dvbdmx_error: - dvb_unregister_adapter(&client->adapter); - -adapter_error: - kfree(client); - return rc; -} - -static int __init smsdvb_module_init(void) -{ - int rc; - - INIT_LIST_HEAD(&g_smsdvb_clients); - kmutex_init(&g_smsdvb_clientslock); - - rc = smscore_register_hotplug(smsdvb_hotplug); - - sms_debug(""); - - return rc; -} - -static void __exit smsdvb_module_exit(void) -{ - smscore_unregister_hotplug(smsdvb_hotplug); - - kmutex_lock(&g_smsdvb_clientslock); - - while (!list_empty(&g_smsdvb_clients)) - smsdvb_unregister_client( - (struct smsdvb_client_t *) g_smsdvb_clients.next); - - kmutex_unlock(&g_smsdvb_clientslock); -} - -module_init(smsdvb_module_init); -module_exit(smsdvb_module_exit); - -MODULE_DESCRIPTION("SMS DVB subsystem adaptation module"); -MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/media/dvb/siano/smsendian.c b/ANDROID_3.4.5/drivers/media/dvb/siano/smsendian.c deleted file mode 100644 index e2657c2f..00000000 --- a/ANDROID_3.4.5/drivers/media/dvb/siano/smsendian.c +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************** - - Siano Mobile Silicon, Inc. - MDTV receiver kernel modules. - Copyright (C) 2006-2009, Uri Shkolnik - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - - ****************************************************************/ - -#include <linux/export.h> -#include <asm/byteorder.h> - -#include "smsendian.h" -#include "smscoreapi.h" - -void smsendian_handle_tx_message(void *buffer) -{ -#ifdef __BIG_ENDIAN - struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer; - int i; - int msgWords; - - switch (msg->xMsgHeader.msgType) { - case MSG_SMS_DATA_DOWNLOAD_REQ: - { - msg->msgData[0] = le32_to_cpu(msg->msgData[0]); - break; - } - - default: - msgWords = (msg->xMsgHeader.msgLength - - sizeof(struct SmsMsgHdr_ST))/4; - - for (i = 0; i < msgWords; i++) - msg->msgData[i] = le32_to_cpu(msg->msgData[i]); - - break; - } -#endif /* __BIG_ENDIAN */ -} -EXPORT_SYMBOL_GPL(smsendian_handle_tx_message); - -void smsendian_handle_rx_message(void *buffer) -{ -#ifdef __BIG_ENDIAN - struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer; - int i; - int msgWords; - - switch (msg->xMsgHeader.msgType) { - case MSG_SMS_GET_VERSION_EX_RES: - { - struct SmsVersionRes_ST *ver = - (struct SmsVersionRes_ST *) msg; - ver->ChipModel = le16_to_cpu(ver->ChipModel); - break; - } - - case MSG_SMS_DVBT_BDA_DATA: - case MSG_SMS_DAB_CHANNEL: - case MSG_SMS_DATA_MSG: - { - break; - } - - default: - { - msgWords = (msg->xMsgHeader.msgLength - - sizeof(struct SmsMsgHdr_ST))/4; - - for (i = 0; i < msgWords; i++) - msg->msgData[i] = le32_to_cpu(msg->msgData[i]); - - break; - } - } -#endif /* __BIG_ENDIAN */ -} -EXPORT_SYMBOL_GPL(smsendian_handle_rx_message); - -void smsendian_handle_message_header(void *msg) -{ -#ifdef __BIG_ENDIAN - struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)msg; - - phdr->msgType = le16_to_cpu(phdr->msgType); - phdr->msgLength = le16_to_cpu(phdr->msgLength); - phdr->msgFlags = le16_to_cpu(phdr->msgFlags); -#endif /* __BIG_ENDIAN */ -} -EXPORT_SYMBOL_GPL(smsendian_handle_message_header); diff --git a/ANDROID_3.4.5/drivers/media/dvb/siano/smsendian.h b/ANDROID_3.4.5/drivers/media/dvb/siano/smsendian.h deleted file mode 100644 index 1624d6fd..00000000 --- a/ANDROID_3.4.5/drivers/media/dvb/siano/smsendian.h +++ /dev/null @@ -1,32 +0,0 @@ -/**************************************************************** - -Siano Mobile Silicon, Inc. -MDTV receiver kernel modules. -Copyright (C) 2006-2009, Uri Shkolnik - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - - This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. - -****************************************************************/ - -#ifndef __SMS_ENDIAN_H__ -#define __SMS_ENDIAN_H__ - -#include <asm/byteorder.h> - -extern void smsendian_handle_tx_message(void *buffer); -extern void smsendian_handle_rx_message(void *buffer); -extern void smsendian_handle_message_header(void *msg); - -#endif /* __SMS_ENDIAN_H__ */ - diff --git a/ANDROID_3.4.5/drivers/media/dvb/siano/smsir.c b/ANDROID_3.4.5/drivers/media/dvb/siano/smsir.c deleted file mode 100644 index 37bc5c4b..00000000 --- a/ANDROID_3.4.5/drivers/media/dvb/siano/smsir.c +++ /dev/null @@ -1,114 +0,0 @@ -/**************************************************************** - - Siano Mobile Silicon, Inc. - MDTV receiver kernel modules. - Copyright (C) 2006-2009, Uri Shkolnik - - Copyright (c) 2010 - Mauro Carvalho Chehab - - Ported the driver to use rc-core - - IR raw event decoding is now done at rc-core - - Code almost re-written - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - - ****************************************************************/ - - -#include <linux/types.h> -#include <linux/input.h> - -#include "smscoreapi.h" -#include "smsir.h" -#include "sms-cards.h" - -#define MODULE_NAME "smsmdtv" - -void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len) -{ - int i; - const s32 *samples = (const void *)buf; - - for (i = 0; i < len >> 2; i++) { - DEFINE_IR_RAW_EVENT(ev); - - ev.duration = abs(samples[i]) * 1000; /* Convert to ns */ - ev.pulse = (samples[i] > 0) ? false : true; - - ir_raw_event_store(coredev->ir.dev, &ev); - } - ir_raw_event_handle(coredev->ir.dev); -} - -int sms_ir_init(struct smscore_device_t *coredev) -{ - int err; - int board_id = smscore_get_board_id(coredev); - struct rc_dev *dev; - - sms_log("Allocating rc device"); - dev = rc_allocate_device(); - if (!dev) { - sms_err("Not enough memory"); - return -ENOMEM; - } - - coredev->ir.controller = 0; /* Todo: vega/nova SPI number */ - coredev->ir.timeout = IR_DEFAULT_TIMEOUT; - sms_log("IR port %d, timeout %d ms", - coredev->ir.controller, coredev->ir.timeout); - - snprintf(coredev->ir.name, sizeof(coredev->ir.name), - "SMS IR (%s)", sms_get_board(board_id)->name); - - strlcpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys)); - strlcat(coredev->ir.phys, "/ir0", sizeof(coredev->ir.phys)); - - dev->input_name = coredev->ir.name; - dev->input_phys = coredev->ir.phys; - dev->dev.parent = coredev->device; - -#if 0 - /* TODO: properly initialize the parameters bellow */ - dev->input_id.bustype = BUS_USB; - dev->input_id.version = 1; - dev->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); - dev->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct); -#endif - - dev->priv = coredev; - dev->driver_type = RC_DRIVER_IR_RAW; - dev->allowed_protos = RC_TYPE_ALL; - dev->map_name = sms_get_board(board_id)->rc_codes; - dev->driver_name = MODULE_NAME; - - sms_log("Input device (IR) %s is set for key events", dev->input_name); - - err = rc_register_device(dev); - if (err < 0) { - sms_err("Failed to register device"); - rc_free_device(dev); - return err; - } - - coredev->ir.dev = dev; - return 0; -} - -void sms_ir_exit(struct smscore_device_t *coredev) -{ - if (coredev->ir.dev) - rc_unregister_device(coredev->ir.dev); - - sms_log(""); -} diff --git a/ANDROID_3.4.5/drivers/media/dvb/siano/smsir.h b/ANDROID_3.4.5/drivers/media/dvb/siano/smsir.h deleted file mode 100644 index ae92b3a8..00000000 --- a/ANDROID_3.4.5/drivers/media/dvb/siano/smsir.h +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************** - -Siano Mobile Silicon, Inc. -MDTV receiver kernel modules. -Copyright (C) 2006-2009, Uri Shkolnik - - Copyright (c) 2010 - Mauro Carvalho Chehab - - Ported the driver to use rc-core - - IR raw event decoding is now done at rc-core - - Code almost re-written - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - - This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. - -****************************************************************/ - -#ifndef __SMS_IR_H__ -#define __SMS_IR_H__ - -#include <linux/input.h> -#include <media/rc-core.h> - -#define IR_DEFAULT_TIMEOUT 100 - -struct smscore_device_t; - -struct ir_t { - struct rc_dev *dev; - char name[40]; - char phys[32]; - - char *rc_codes; - u64 protocol; - - u32 timeout; - u32 controller; -}; - -int sms_ir_init(struct smscore_device_t *coredev); -void sms_ir_exit(struct smscore_device_t *coredev); -void sms_ir_event(struct smscore_device_t *coredev, - const char *buf, int len); - -#endif /* __SMS_IR_H__ */ - diff --git a/ANDROID_3.4.5/drivers/media/dvb/siano/smssdio.c b/ANDROID_3.4.5/drivers/media/dvb/siano/smssdio.c deleted file mode 100644 index 91f8c829..00000000 --- a/ANDROID_3.4.5/drivers/media/dvb/siano/smssdio.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - * smssdio.c - Siano 1xxx SDIO interface driver - * - * Copyright 2008 Pierre Ossman - * - * Based on code by Siano Mobile Silicon, Inc., - * Copyright (C) 2006-2008, Uri Shkolnik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * - * This hardware is a bit odd in that all transfers should be done - * to/from the SMSSDIO_DATA register, yet the "increase address" bit - * always needs to be set. - * - * Also, buffers from the card are always aligned to 128 byte - * boundaries. - */ - -/* - * General cleanup notes: - * - * - only typedefs should be name *_t - * - * - use ERR_PTR and friends for smscore_register_device() - * - * - smscore_getbuffer should zero fields - * - * Fix stop command - */ - -#include <linux/moduleparam.h> -#include <linux/slab.h> -#include <linux/firmware.h> -#include <linux/delay.h> -#include <linux/mmc/card.h> -#include <linux/mmc/sdio_func.h> -#include <linux/mmc/sdio_ids.h> -#include <linux/module.h> - -#include "smscoreapi.h" -#include "sms-cards.h" - -/* Registers */ - -#define SMSSDIO_DATA 0x00 -#define SMSSDIO_INT 0x04 -#define SMSSDIO_BLOCK_SIZE 128 - -static const struct sdio_device_id smssdio_ids[] __devinitconst = { - {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_STELLAR), - .driver_data = SMS1XXX_BOARD_SIANO_STELLAR}, - {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_A0), - .driver_data = SMS1XXX_BOARD_SIANO_NOVA_A}, - {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_B0), - .driver_data = SMS1XXX_BOARD_SIANO_NOVA_B}, - {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VEGA_A0), - .driver_data = SMS1XXX_BOARD_SIANO_VEGA}, - {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VENICE), - .driver_data = SMS1XXX_BOARD_SIANO_VEGA}, - { /* end: all zeroes */ }, -}; - -MODULE_DEVICE_TABLE(sdio, smssdio_ids); - -struct smssdio_device { - struct sdio_func *func; - - struct smscore_device_t *coredev; - - struct smscore_buffer_t *split_cb; -}; - -/*******************************************************************/ -/* Siano core callbacks */ -/*******************************************************************/ - -static int smssdio_sendrequest(void *context, void *buffer, size_t size) -{ - int ret = 0; - struct smssdio_device *smsdev; - - smsdev = context; - - sdio_claim_host(smsdev->func); - - while (size >= smsdev->func->cur_blksize) { - ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA, - buffer, smsdev->func->cur_blksize); - if (ret) - goto out; - - buffer += smsdev->func->cur_blksize; - size -= smsdev->func->cur_blksize; - } - - if (size) { - ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA, - buffer, size); - } - -out: - sdio_release_host(smsdev->func); - - return ret; -} - -/*******************************************************************/ -/* SDIO callbacks */ -/*******************************************************************/ - -static void smssdio_interrupt(struct sdio_func *func) -{ - int ret, isr; - - struct smssdio_device *smsdev; - struct smscore_buffer_t *cb; - struct SmsMsgHdr_ST *hdr; - size_t size; - - smsdev = sdio_get_drvdata(func); - - /* - * The interrupt register has no defined meaning. It is just - * a way of turning of the level triggered interrupt. - */ - isr = sdio_readb(func, SMSSDIO_INT, &ret); - if (ret) { - sms_err("Unable to read interrupt register!\n"); - return; - } - - if (smsdev->split_cb == NULL) { - cb = smscore_getbuffer(smsdev->coredev); - if (!cb) { - sms_err("Unable to allocate data buffer!\n"); - return; - } - - ret = sdio_memcpy_fromio(smsdev->func, - cb->p, - SMSSDIO_DATA, - SMSSDIO_BLOCK_SIZE); - if (ret) { - sms_err("Error %d reading initial block!\n", ret); - return; - } - - hdr = cb->p; - - if (hdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG) { - smsdev->split_cb = cb; - return; - } - - if (hdr->msgLength > smsdev->func->cur_blksize) - size = hdr->msgLength - smsdev->func->cur_blksize; - else - size = 0; - } else { - cb = smsdev->split_cb; - hdr = cb->p; - - size = hdr->msgLength - sizeof(struct SmsMsgHdr_ST); - - smsdev->split_cb = NULL; - } - - if (size) { - void *buffer; - - buffer = cb->p + (hdr->msgLength - size); - size = ALIGN(size, SMSSDIO_BLOCK_SIZE); - - BUG_ON(smsdev->func->cur_blksize != SMSSDIO_BLOCK_SIZE); - - /* - * First attempt to transfer all of it in one go... - */ - ret = sdio_memcpy_fromio(smsdev->func, - buffer, - SMSSDIO_DATA, - size); - if (ret && ret != -EINVAL) { - smscore_putbuffer(smsdev->coredev, cb); - sms_err("Error %d reading data from card!\n", ret); - return; - } - - /* - * ..then fall back to one block at a time if that is - * not possible... - * - * (we have to do this manually because of the - * problem with the "increase address" bit) - */ - if (ret == -EINVAL) { - while (size) { - ret = sdio_memcpy_fromio(smsdev->func, - buffer, SMSSDIO_DATA, - smsdev->func->cur_blksize); - if (ret) { - smscore_putbuffer(smsdev->coredev, cb); - sms_err("Error %d reading " - "data from card!\n", ret); - return; - } - - buffer += smsdev->func->cur_blksize; - if (size > smsdev->func->cur_blksize) - size -= smsdev->func->cur_blksize; - else - size = 0; - } - } - } - - cb->size = hdr->msgLength; - cb->offset = 0; - - smscore_onresponse(smsdev->coredev, cb); -} - -static int __devinit smssdio_probe(struct sdio_func *func, - const struct sdio_device_id *id) -{ - int ret; - - int board_id; - struct smssdio_device *smsdev; - struct smsdevice_params_t params; - - board_id = id->driver_data; - - smsdev = kzalloc(sizeof(struct smssdio_device), GFP_KERNEL); - if (!smsdev) - return -ENOMEM; - - smsdev->func = func; - - memset(¶ms, 0, sizeof(struct smsdevice_params_t)); - - params.device = &func->dev; - params.buffer_size = 0x5000; /* ?? */ - params.num_buffers = 22; /* ?? */ - params.context = smsdev; - - snprintf(params.devpath, sizeof(params.devpath), - "sdio\\%s", sdio_func_id(func)); - - params.sendrequest_handler = smssdio_sendrequest; - - params.device_type = sms_get_board(board_id)->type; - - if (params.device_type != SMS_STELLAR) - params.flags |= SMS_DEVICE_FAMILY2; - else { - /* - * FIXME: Stellar needs special handling... - */ - ret = -ENODEV; - goto free; - } - - ret = smscore_register_device(¶ms, &smsdev->coredev); - if (ret < 0) - goto free; - - smscore_set_board_id(smsdev->coredev, board_id); - - sdio_claim_host(func); - - ret = sdio_enable_func(func); - if (ret) - goto release; - - ret = sdio_set_block_size(func, SMSSDIO_BLOCK_SIZE); - if (ret) - goto disable; - - ret = sdio_claim_irq(func, smssdio_interrupt); - if (ret) - goto disable; - - sdio_set_drvdata(func, smsdev); - - sdio_release_host(func); - - ret = smscore_start_device(smsdev->coredev); - if (ret < 0) - goto reclaim; - - return 0; - -reclaim: - sdio_claim_host(func); - sdio_release_irq(func); -disable: - sdio_disable_func(func); -release: - sdio_release_host(func); - smscore_unregister_device(smsdev->coredev); -free: - kfree(smsdev); - - return ret; -} - -static void smssdio_remove(struct sdio_func *func) -{ - struct smssdio_device *smsdev; - - smsdev = sdio_get_drvdata(func); - - /* FIXME: racy! */ - if (smsdev->split_cb) - smscore_putbuffer(smsdev->coredev, smsdev->split_cb); - - smscore_unregister_device(smsdev->coredev); - - sdio_claim_host(func); - sdio_release_irq(func); - sdio_disable_func(func); - sdio_release_host(func); - - kfree(smsdev); -} - -static struct sdio_driver smssdio_driver = { - .name = "smssdio", - .id_table = smssdio_ids, - .probe = smssdio_probe, - .remove = smssdio_remove, -}; - -/*******************************************************************/ -/* Module functions */ -/*******************************************************************/ - -static int __init smssdio_module_init(void) -{ - int ret = 0; - - printk(KERN_INFO "smssdio: Siano SMS1xxx SDIO driver\n"); - printk(KERN_INFO "smssdio: Copyright Pierre Ossman\n"); - - ret = sdio_register_driver(&smssdio_driver); - - return ret; -} - -static void __exit smssdio_module_exit(void) -{ - sdio_unregister_driver(&smssdio_driver); -} - -module_init(smssdio_module_init); -module_exit(smssdio_module_exit); - -MODULE_DESCRIPTION("Siano SMS1xxx SDIO driver"); -MODULE_AUTHOR("Pierre Ossman"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/media/dvb/siano/smsusb.c b/ANDROID_3.4.5/drivers/media/dvb/siano/smsusb.c deleted file mode 100644 index 664e460f..00000000 --- a/ANDROID_3.4.5/drivers/media/dvb/siano/smsusb.c +++ /dev/null @@ -1,568 +0,0 @@ -/**************************************************************** - -Siano Mobile Silicon, Inc. -MDTV receiver kernel modules. -Copyright (C) 2005-2009, Uri Shkolnik, Anatoly Greenblat - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - - This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. - -****************************************************************/ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/usb.h> -#include <linux/firmware.h> -#include <linux/slab.h> -#include <linux/module.h> - -#include "smscoreapi.h" -#include "sms-cards.h" -#include "smsendian.h" - -static int sms_dbg; -module_param_named(debug, sms_dbg, int, 0644); -MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); - -#define USB1_BUFFER_SIZE 0x1000 -#define USB2_BUFFER_SIZE 0x4000 - -#define MAX_BUFFERS 50 -#define MAX_URBS 10 - -struct smsusb_device_t; - -struct smsusb_urb_t { - struct smscore_buffer_t *cb; - struct smsusb_device_t *dev; - - struct urb urb; -}; - -struct smsusb_device_t { - struct usb_device *udev; - struct smscore_device_t *coredev; - - struct smsusb_urb_t surbs[MAX_URBS]; - - int response_alignment; - int buffer_size; -}; - -static int smsusb_submit_urb(struct smsusb_device_t *dev, - struct smsusb_urb_t *surb); - -static void smsusb_onresponse(struct urb *urb) -{ - struct smsusb_urb_t *surb = (struct smsusb_urb_t *) urb->context; - struct smsusb_device_t *dev = surb->dev; - - if (urb->status == -ESHUTDOWN) { - sms_err("error, urb status %d (-ESHUTDOWN), %d bytes", - urb->status, urb->actual_length); - return; - } - - if ((urb->actual_length > 0) && (urb->status == 0)) { - struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)surb->cb->p; - - smsendian_handle_message_header(phdr); - if (urb->actual_length >= phdr->msgLength) { - surb->cb->size = phdr->msgLength; - - if (dev->response_alignment && - (phdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG)) { - - surb->cb->offset = - dev->response_alignment + - ((phdr->msgFlags >> 8) & 3); - - /* sanity check */ - if (((int) phdr->msgLength + - surb->cb->offset) > urb->actual_length) { - sms_err("invalid response " - "msglen %d offset %d " - "size %d", - phdr->msgLength, - surb->cb->offset, - urb->actual_length); - goto exit_and_resubmit; - } - - /* move buffer pointer and - * copy header to its new location */ - memcpy((char *) phdr + surb->cb->offset, - phdr, sizeof(struct SmsMsgHdr_ST)); - } else - surb->cb->offset = 0; - - smscore_onresponse(dev->coredev, surb->cb); - surb->cb = NULL; - } else { - sms_err("invalid response " - "msglen %d actual %d", - phdr->msgLength, urb->actual_length); - } - } else - sms_err("error, urb status %d, %d bytes", - urb->status, urb->actual_length); - - -exit_and_resubmit: - smsusb_submit_urb(dev, surb); -} - -static int smsusb_submit_urb(struct smsusb_device_t *dev, - struct smsusb_urb_t *surb) -{ - if (!surb->cb) { - surb->cb = smscore_getbuffer(dev->coredev); - if (!surb->cb) { - sms_err("smscore_getbuffer(...) returned NULL"); - return -ENOMEM; - } - } - - usb_fill_bulk_urb( - &surb->urb, - dev->udev, - usb_rcvbulkpipe(dev->udev, 0x81), - surb->cb->p, - dev->buffer_size, - smsusb_onresponse, - surb - ); - surb->urb.transfer_dma = surb->cb->phys; - surb->urb.transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - return usb_submit_urb(&surb->urb, GFP_ATOMIC); -} - -static void smsusb_stop_streaming(struct smsusb_device_t *dev) -{ - int i; - - for (i = 0; i < MAX_URBS; i++) { - usb_kill_urb(&dev->surbs[i].urb); - - if (dev->surbs[i].cb) { - smscore_putbuffer(dev->coredev, dev->surbs[i].cb); - dev->surbs[i].cb = NULL; - } - } -} - -static int smsusb_start_streaming(struct smsusb_device_t *dev) -{ - int i, rc; - - for (i = 0; i < MAX_URBS; i++) { - rc = smsusb_submit_urb(dev, &dev->surbs[i]); - if (rc < 0) { - sms_err("smsusb_submit_urb(...) failed"); - smsusb_stop_streaming(dev); - break; - } - } - - return rc; -} - -static int smsusb_sendrequest(void *context, void *buffer, size_t size) -{ - struct smsusb_device_t *dev = (struct smsusb_device_t *) context; - int dummy; - - smsendian_handle_message_header((struct SmsMsgHdr_ST *)buffer); - return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), - buffer, size, &dummy, 1000); -} - -static char *smsusb1_fw_lkup[] = { - "dvbt_stellar_usb.inp", - "dvbh_stellar_usb.inp", - "tdmb_stellar_usb.inp", - "none", - "dvbt_bda_stellar_usb.inp", -}; - -static inline char *sms_get_fw_name(int mode, int board_id) -{ - char **fw = sms_get_board(board_id)->fw; - return (fw && fw[mode]) ? fw[mode] : smsusb1_fw_lkup[mode]; -} - -static int smsusb1_load_firmware(struct usb_device *udev, int id, int board_id) -{ - const struct firmware *fw; - u8 *fw_buffer; - int rc, dummy; - char *fw_filename; - - if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) { - sms_err("invalid firmware id specified %d", id); - return -EINVAL; - } - - fw_filename = sms_get_fw_name(id, board_id); - - rc = request_firmware(&fw, fw_filename, &udev->dev); - if (rc < 0) { - sms_warn("failed to open \"%s\" mode %d, " - "trying again with default firmware", fw_filename, id); - - fw_filename = smsusb1_fw_lkup[id]; - rc = request_firmware(&fw, fw_filename, &udev->dev); - if (rc < 0) { - sms_warn("failed to open \"%s\" mode %d", - fw_filename, id); - - return rc; - } - } - - fw_buffer = kmalloc(fw->size, GFP_KERNEL); - if (fw_buffer) { - memcpy(fw_buffer, fw->data, fw->size); - - rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2), - fw_buffer, fw->size, &dummy, 1000); - - sms_info("sent %zd(%d) bytes, rc %d", fw->size, dummy, rc); - - kfree(fw_buffer); - } else { - sms_err("failed to allocate firmware buffer"); - rc = -ENOMEM; - } - sms_info("read FW %s, size=%zd", fw_filename, fw->size); - - release_firmware(fw); - - return rc; -} - -static void smsusb1_detectmode(void *context, int *mode) -{ - char *product_string = - ((struct smsusb_device_t *) context)->udev->product; - - *mode = DEVICE_MODE_NONE; - - if (!product_string) { - product_string = "none"; - sms_err("product string not found"); - } else if (strstr(product_string, "DVBH")) - *mode = 1; - else if (strstr(product_string, "BDA")) - *mode = 4; - else if (strstr(product_string, "DVBT")) - *mode = 0; - else if (strstr(product_string, "TDMB")) - *mode = 2; - - sms_info("%d \"%s\"", *mode, product_string); -} - -static int smsusb1_setmode(void *context, int mode) -{ - struct SmsMsgHdr_ST Msg = { MSG_SW_RELOAD_REQ, 0, HIF_TASK, - sizeof(struct SmsMsgHdr_ST), 0 }; - - if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { - sms_err("invalid firmware id specified %d", mode); - return -EINVAL; - } - - return smsusb_sendrequest(context, &Msg, sizeof(Msg)); -} - -static void smsusb_term_device(struct usb_interface *intf) -{ - struct smsusb_device_t *dev = usb_get_intfdata(intf); - - if (dev) { - smsusb_stop_streaming(dev); - - /* unregister from smscore */ - if (dev->coredev) - smscore_unregister_device(dev->coredev); - - sms_info("device %p destroyed", dev); - kfree(dev); - } - - usb_set_intfdata(intf, NULL); -} - -static int smsusb_init_device(struct usb_interface *intf, int board_id) -{ - struct smsdevice_params_t params; - struct smsusb_device_t *dev; - int i, rc; - - /* create device object */ - dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL); - if (!dev) { - sms_err("kzalloc(sizeof(struct smsusb_device_t) failed"); - return -ENOMEM; - } - - memset(¶ms, 0, sizeof(params)); - usb_set_intfdata(intf, dev); - dev->udev = interface_to_usbdev(intf); - - params.device_type = sms_get_board(board_id)->type; - - switch (params.device_type) { - case SMS_STELLAR: - dev->buffer_size = USB1_BUFFER_SIZE; - - params.setmode_handler = smsusb1_setmode; - params.detectmode_handler = smsusb1_detectmode; - break; - default: - sms_err("Unspecified sms device type!"); - /* fall-thru */ - case SMS_NOVA_A0: - case SMS_NOVA_B0: - case SMS_VEGA: - dev->buffer_size = USB2_BUFFER_SIZE; - dev->response_alignment = - le16_to_cpu(dev->udev->ep_in[1]->desc.wMaxPacketSize) - - sizeof(struct SmsMsgHdr_ST); - - params.flags |= SMS_DEVICE_FAMILY2; - break; - } - - params.device = &dev->udev->dev; - params.buffer_size = dev->buffer_size; - params.num_buffers = MAX_BUFFERS; - params.sendrequest_handler = smsusb_sendrequest; - params.context = dev; - usb_make_path(dev->udev, params.devpath, sizeof(params.devpath)); - - /* register in smscore */ - rc = smscore_register_device(¶ms, &dev->coredev); - if (rc < 0) { - sms_err("smscore_register_device(...) failed, rc %d", rc); - smsusb_term_device(intf); - return rc; - } - - smscore_set_board_id(dev->coredev, board_id); - - /* initialize urbs */ - for (i = 0; i < MAX_URBS; i++) { - dev->surbs[i].dev = dev; - usb_init_urb(&dev->surbs[i].urb); - } - - sms_info("smsusb_start_streaming(...)."); - rc = smsusb_start_streaming(dev); - if (rc < 0) { - sms_err("smsusb_start_streaming(...) failed"); - smsusb_term_device(intf); - return rc; - } - - rc = smscore_start_device(dev->coredev); - if (rc < 0) { - sms_err("smscore_start_device(...) failed"); - smsusb_term_device(intf); - return rc; - } - - sms_info("device %p created", dev); - - return rc; -} - -static int __devinit smsusb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct usb_device *udev = interface_to_usbdev(intf); - char devpath[32]; - int i, rc; - - rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81)); - rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02)); - - if (intf->num_altsetting > 0) { - rc = usb_set_interface( - udev, intf->cur_altsetting->desc.bInterfaceNumber, 0); - if (rc < 0) { - sms_err("usb_set_interface failed, rc %d", rc); - return rc; - } - } - - sms_info("smsusb_probe %d", - intf->cur_altsetting->desc.bInterfaceNumber); - for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) - sms_info("endpoint %d %02x %02x %d", i, - intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, - intf->cur_altsetting->endpoint[i].desc.bmAttributes, - intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize); - - if ((udev->actconfig->desc.bNumInterfaces == 2) && - (intf->cur_altsetting->desc.bInterfaceNumber == 0)) { - sms_err("rom interface 0 is not used"); - return -ENODEV; - } - - if (intf->cur_altsetting->desc.bInterfaceNumber == 1) { - snprintf(devpath, sizeof(devpath), "usb\\%d-%s", - udev->bus->busnum, udev->devpath); - sms_info("stellar device was found."); - return smsusb1_load_firmware( - udev, smscore_registry_getmode(devpath), - id->driver_info); - } - - rc = smsusb_init_device(intf, id->driver_info); - sms_info("rc %d", rc); - sms_board_load_modules(id->driver_info); - return rc; -} - -static void smsusb_disconnect(struct usb_interface *intf) -{ - smsusb_term_device(intf); -} - -static int smsusb_suspend(struct usb_interface *intf, pm_message_t msg) -{ - struct smsusb_device_t *dev = usb_get_intfdata(intf); - printk(KERN_INFO "%s: Entering status %d.\n", __func__, msg.event); - smsusb_stop_streaming(dev); - return 0; -} - -static int smsusb_resume(struct usb_interface *intf) -{ - int rc, i; - struct smsusb_device_t *dev = usb_get_intfdata(intf); - struct usb_device *udev = interface_to_usbdev(intf); - - printk(KERN_INFO "%s: Entering.\n", __func__); - usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81)); - usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02)); - - for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) - printk(KERN_INFO "endpoint %d %02x %02x %d\n", i, - intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, - intf->cur_altsetting->endpoint[i].desc.bmAttributes, - intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize); - - if (intf->num_altsetting > 0) { - rc = usb_set_interface(udev, - intf->cur_altsetting->desc. - bInterfaceNumber, 0); - if (rc < 0) { - printk(KERN_INFO "%s usb_set_interface failed, " - "rc %d\n", __func__, rc); - return rc; - } - } - - smsusb_start_streaming(dev); - return 0; -} - -static const struct usb_device_id smsusb_id_table[] __devinitconst = { - { USB_DEVICE(0x187f, 0x0010), - .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, - { USB_DEVICE(0x187f, 0x0100), - .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, - { USB_DEVICE(0x187f, 0x0200), - .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A }, - { USB_DEVICE(0x187f, 0x0201), - .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B }, - { USB_DEVICE(0x187f, 0x0300), - .driver_info = SMS1XXX_BOARD_SIANO_VEGA }, - { USB_DEVICE(0x2040, 0x1700), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT }, - { USB_DEVICE(0x2040, 0x1800), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A }, - { USB_DEVICE(0x2040, 0x1801), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B }, - { USB_DEVICE(0x2040, 0x2000), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x2009), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 }, - { USB_DEVICE(0x2040, 0x200a), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x2010), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x2011), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x2019), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x5500), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5510), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5520), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5530), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5580), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5590), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x187f, 0x0202), - .driver_info = SMS1XXX_BOARD_SIANO_NICE }, - { USB_DEVICE(0x187f, 0x0301), - .driver_info = SMS1XXX_BOARD_SIANO_VENICE }, - { USB_DEVICE(0x2040, 0xb900), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0xb910), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0xb980), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0xb990), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0xc000), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0xc010), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0xc080), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0xc090), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0xc0a0), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0xf5a0), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { } /* Terminating entry */ - }; - -MODULE_DEVICE_TABLE(usb, smsusb_id_table); - -static struct usb_driver smsusb_driver = { - .name = "smsusb", - .probe = smsusb_probe, - .disconnect = smsusb_disconnect, - .id_table = smsusb_id_table, - - .suspend = smsusb_suspend, - .resume = smsusb_resume, -}; - -module_usb_driver(smsusb_driver); - -MODULE_DESCRIPTION("Driver for the Siano SMS1xxx USB dongle"); -MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/init/calibrate.c b/ANDROID_3.4.5/init/calibrate.c deleted file mode 100644 index fda0a7b0..00000000 --- a/ANDROID_3.4.5/init/calibrate.c +++ /dev/null @@ -1,301 +0,0 @@ -/* calibrate.c: default delay calibration - * - * Excised from init/main.c - * Copyright (C) 1991, 1992 Linus Torvalds - */ - -#include <linux/jiffies.h> -#include <linux/delay.h> -#include <linux/init.h> -#include <linux/timex.h> -#include <linux/smp.h> -#include <linux/percpu.h> - -unsigned long lpj_fine; -unsigned long preset_lpj; -static int __init lpj_setup(char *str) -{ - preset_lpj = simple_strtoul(str,NULL,0); - return 1; -} - -__setup("lpj=", lpj_setup); - -#ifdef ARCH_HAS_READ_CURRENT_TIMER - -/* This routine uses the read_current_timer() routine and gets the - * loops per jiffy directly, instead of guessing it using delay(). - * Also, this code tries to handle non-maskable asynchronous events - * (like SMIs) - */ -#define DELAY_CALIBRATION_TICKS ((HZ < 100) ? 1 : (HZ/100)) -#define MAX_DIRECT_CALIBRATION_RETRIES 5 - -static unsigned long __cpuinit calibrate_delay_direct(void) -{ - unsigned long pre_start, start, post_start; - unsigned long pre_end, end, post_end; - unsigned long start_jiffies; - unsigned long timer_rate_min, timer_rate_max; - unsigned long good_timer_sum = 0; - unsigned long good_timer_count = 0; - unsigned long measured_times[MAX_DIRECT_CALIBRATION_RETRIES]; - int max = -1; /* index of measured_times with max/min values or not set */ - int min = -1; - int i; - - if (read_current_timer(&pre_start) < 0 ) - return 0; - - /* - * A simple loop like - * while ( jiffies < start_jiffies+1) - * start = read_current_timer(); - * will not do. As we don't really know whether jiffy switch - * happened first or timer_value was read first. And some asynchronous - * event can happen between these two events introducing errors in lpj. - * - * So, we do - * 1. pre_start <- When we are sure that jiffy switch hasn't happened - * 2. check jiffy switch - * 3. start <- timer value before or after jiffy switch - * 4. post_start <- When we are sure that jiffy switch has happened - * - * Note, we don't know anything about order of 2 and 3. - * Now, by looking at post_start and pre_start difference, we can - * check whether any asynchronous event happened or not - */ - - for (i = 0; i < MAX_DIRECT_CALIBRATION_RETRIES; i++) { - pre_start = 0; - read_current_timer(&start); - start_jiffies = jiffies; - while (time_before_eq(jiffies, start_jiffies + 1)) { - pre_start = start; - read_current_timer(&start); - } - read_current_timer(&post_start); - - pre_end = 0; - end = post_start; - while (time_before_eq(jiffies, start_jiffies + 1 + - DELAY_CALIBRATION_TICKS)) { - pre_end = end; - read_current_timer(&end); - } - read_current_timer(&post_end); - - timer_rate_max = (post_end - pre_start) / - DELAY_CALIBRATION_TICKS; - timer_rate_min = (pre_end - post_start) / - DELAY_CALIBRATION_TICKS; - - /* - * If the upper limit and lower limit of the timer_rate is - * >= 12.5% apart, redo calibration. - */ - if (start >= post_end) - printk(KERN_NOTICE "calibrate_delay_direct() ignoring " - "timer_rate as we had a TSC wrap around" - " start=%lu >=post_end=%lu\n", - start, post_end); - if (start < post_end && pre_start != 0 && pre_end != 0 && - (timer_rate_max - timer_rate_min) < (timer_rate_max >> 3)) { - good_timer_count++; - good_timer_sum += timer_rate_max; - measured_times[i] = timer_rate_max; - if (max < 0 || timer_rate_max > measured_times[max]) - max = i; - if (min < 0 || timer_rate_max < measured_times[min]) - min = i; - } else - measured_times[i] = 0; - - } - - /* - * Find the maximum & minimum - if they differ too much throw out the - * one with the largest difference from the mean and try again... - */ - while (good_timer_count > 1) { - unsigned long estimate; - unsigned long maxdiff; - - /* compute the estimate */ - estimate = (good_timer_sum/good_timer_count); - maxdiff = estimate >> 3; - - /* if range is within 12% let's take it */ - if ((measured_times[max] - measured_times[min]) < maxdiff) - return estimate; - - /* ok - drop the worse value and try again... */ - good_timer_sum = 0; - good_timer_count = 0; - if ((measured_times[max] - estimate) < - (estimate - measured_times[min])) { - printk(KERN_NOTICE "calibrate_delay_direct() dropping " - "min bogoMips estimate %d = %lu\n", - min, measured_times[min]); - measured_times[min] = 0; - min = max; - } else { - printk(KERN_NOTICE "calibrate_delay_direct() dropping " - "max bogoMips estimate %d = %lu\n", - max, measured_times[max]); - measured_times[max] = 0; - max = min; - } - - for (i = 0; i < MAX_DIRECT_CALIBRATION_RETRIES; i++) { - if (measured_times[i] == 0) - continue; - good_timer_count++; - good_timer_sum += measured_times[i]; - if (measured_times[i] < measured_times[min]) - min = i; - if (measured_times[i] > measured_times[max]) - max = i; - } - - } - - printk(KERN_NOTICE "calibrate_delay_direct() failed to get a good " - "estimate for loops_per_jiffy.\nProbably due to long platform " - "interrupts. Consider using \"lpj=\" boot option.\n"); - return 0; -} -#else -static unsigned long __cpuinit calibrate_delay_direct(void) {return 0;} -#endif - -/* - * This is the number of bits of precision for the loops_per_jiffy. Each - * time we refine our estimate after the first takes 1.5/HZ seconds, so try - * to start with a good estimate. - * For the boot cpu we can skip the delay calibration and assign it a value - * calculated based on the timer frequency. - * For the rest of the CPUs we cannot assume that the timer frequency is same as - * the cpu frequency, hence do the calibration for those. - */ -#define LPS_PREC 8 - -static unsigned long __cpuinit calibrate_delay_converge(void) -{ - /* First stage - slowly accelerate to find initial bounds */ - unsigned long lpj, lpj_base, ticks, loopadd, loopadd_base, chop_limit; - int trials = 0, band = 0, trial_in_band = 0; - - lpj = (1<<12); - - /* wait for "start of" clock tick */ - ticks = jiffies; - while (ticks == jiffies) - ; /* nothing */ - /* Go .. */ - ticks = jiffies; - do { - if (++trial_in_band == (1<<band)) { - ++band; - trial_in_band = 0; - } - __delay(lpj * band); - trials += band; - } while (ticks == jiffies); - /* - * We overshot, so retreat to a clear underestimate. Then estimate - * the largest likely undershoot. This defines our chop bounds. - */ - trials -= band; - loopadd_base = lpj * band; - lpj_base = lpj * trials; - -recalibrate: - lpj = lpj_base; - loopadd = loopadd_base; - - /* - * Do a binary approximation to get lpj set to - * equal one clock (up to LPS_PREC bits) - */ - chop_limit = lpj >> LPS_PREC; - while (loopadd > chop_limit) { - lpj += loopadd; - ticks = jiffies; - while (ticks == jiffies) - ; /* nothing */ - ticks = jiffies; - __delay(lpj); - if (jiffies != ticks) /* longer than 1 tick */ - lpj -= loopadd; - loopadd >>= 1; - } - /* - * If we incremented every single time possible, presume we've - * massively underestimated initially, and retry with a higher - * start, and larger range. (Only seen on x86_64, due to SMIs) - */ - if (lpj + loopadd * 2 == lpj_base + loopadd_base * 2) { - lpj_base = lpj; - loopadd_base <<= 2; - goto recalibrate; - } - - return lpj; -} - -static DEFINE_PER_CPU(unsigned long, cpu_loops_per_jiffy) = { 0 }; - -/* - * Check if cpu calibration delay is already known. For example, - * some processors with multi-core sockets may have all cores - * with the same calibration delay. - * - * Architectures should override this function if a faster calibration - * method is available. - */ -unsigned long __attribute__((weak)) __cpuinit calibrate_delay_is_known(void) -{ - return 0; -} - -void __cpuinit calibrate_delay(void) -{ - unsigned long lpj; - static bool printed; - int this_cpu = smp_processor_id(); - - if (per_cpu(cpu_loops_per_jiffy, this_cpu)) { - lpj = per_cpu(cpu_loops_per_jiffy, this_cpu); - if (!printed) - pr_info("Calibrating delay loop (skipped) " - "already calibrated this CPU"); - } else if (preset_lpj) { - lpj = preset_lpj; - if (!printed) - pr_info("Calibrating delay loop (skipped) " - "preset value.. "); - } else if ((!printed) && lpj_fine) { - lpj = lpj_fine; - pr_info("Calibrating delay loop (skipped), " - "value calculated using timer frequency.. "); - } else if ((lpj = calibrate_delay_is_known())) { - ; - } else if ((lpj = calibrate_delay_direct()) != 0) { - if (!printed) - pr_info("Calibrating delay using timer " - "specific routine.. "); - } else { - if (!printed) - pr_info("Calibrating delay loop... "); - lpj = calibrate_delay_converge(); - } - per_cpu(cpu_loops_per_jiffy, this_cpu) = lpj; - if (!printed) - pr_cont("%lu.%02lu BogoMIPS (lpj=%lu)\n", - lpj/(500000/HZ), - (lpj/(5000/HZ)) % 100, lpj); - - loops_per_jiffy = lpj; - printed = true; -} |