diff options
Diffstat (limited to 'drivers/misc/sprd_srt')
| -rw-r--r-- | drivers/misc/sprd_srt/Makefile | 1 | ||||
| -rw-r--r-- | drivers/misc/sprd_srt/sprd_srt.c | 151 | ||||
| -rw-r--r-- | drivers/misc/sprd_srt/sprd_srt.h | 29 | ||||
| -rw-r--r-- | drivers/misc/sprd_srt/srt_proc.c | 281 | ||||
| -rw-r--r-- | drivers/misc/sprd_srt/srtpm.c | 119 | ||||
| -rw-r--r-- | drivers/misc/sprd_srt/srtpm.h | 18 |
6 files changed, 599 insertions, 0 deletions
diff --git a/drivers/misc/sprd_srt/Makefile b/drivers/misc/sprd_srt/Makefile new file mode 100644 index 00000000..9f76c8ce --- /dev/null +++ b/drivers/misc/sprd_srt/Makefile @@ -0,0 +1 @@ +obj-m := sprd_srt.o srt_proc.o srtpm.o diff --git a/drivers/misc/sprd_srt/sprd_srt.c b/drivers/misc/sprd_srt/sprd_srt.c new file mode 100644 index 00000000..17727e47 --- /dev/null +++ b/drivers/misc/sprd_srt/sprd_srt.c @@ -0,0 +1,151 @@ +#include <linux/module.h> +#include <linux/types.h> +#include <linux/fs.h> +#include <linux/errno.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/init.h> +#include <linux/cdev.h> +#include <asm/io.h> +#include <asm/system.h> +#include <asm/uaccess.h> +#include <asm/processor.h> +#include <linux/slab.h> +#include <linux/workqueue.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/file.h> +#include <linux/kernel.h> +#include <linux/kmod.h> +#include <linux/ioctl.h> + + +/**********************************************************************************/ +#define SRT_IOCTL_MAGIC 'e' +#define SRT_OPEN _IO(SRT_IOCTL_MAGIC, 1) +#define SRT_RELEASE _IO(SRT_IOCTL_MAGIC, 2) +#define SRT_ENABLE _IO(SRT_IOCTL_MAGIC, 3) +#define SRT_READ1 _IOR(SRT_IOCTL_MAGIC, 4, struct srtinfo_struct) +#define SRT_READ2 _IOR(SRT_IOCTL_MAGIC, 5, struct srtinfo_struct) +#define SRT_WRITE1 _IOW(SRT_IOCTL_MAGIC, 6, struct srtinfo_struct) +#define SRT_WRITE2 _IOW(SRT_IOCTL_MAGIC, 7, struct srtinfo_struct) + +#include "sprd_srt.h" + +/**********************************************************************************/ +static struct srt_dev *g_srt_dev=0; +static int srt_open(struct inode *inode, struct file *filp) +{ + return 0; +} +static int srt_release(struct inode *inode, struct file *filp) +{ + return 0; +} +static ssize_t srt_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos) +{ + return 0; +} +static ssize_t srt_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos) +{ + return 0; +} +static loff_t srt_llseek(struct file *filp, loff_t offset, int orig) +{ + return 0; +} + + +static long srt_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int i,ret=-1; + switch (cmd) + { + case SRT_READ1: + break; + case SRT_READ2: + break; + case SRT_WRITE1: + break; + case SRT_WRITE2: + break; + default: + return - EINVAL; + } + + return 0; +} + +static const struct file_operations srt_fops = { + .owner = THIS_MODULE, + .open = srt_open, + .release = srt_release, + .read = srt_read, + .write = srt_write, + .llseek = srt_llseek, + .unlocked_ioctl = srt_ioctl, +}; +/**********************************************************************************/ +int srt_init(void) +{ + int err; + dev_t devno; + + DEBUG_PRINT(LOG_TAG "%s Start\n", __func__); + + g_srt_dev = kmalloc(sizeof(struct srt_dev), GFP_KERNEL); + if (!g_srt_dev) + { + DEBUG_PRINT(LOG_TAG "mem alloc fail"); + return -1; + } + memset(g_srt_dev, 0, sizeof(struct srt_dev)); + err = alloc_chrdev_region(&devno, 0, 1, "srt"); + g_srt_dev->dev_major = MAJOR(devno); + if (err < 0) + { + DEBUG_PRINT(LOG_TAG "alloc error=%d", err); + return -1; + } + cdev_init(&g_srt_dev->cdev, &srt_fops); + g_srt_dev->cdev.owner = THIS_MODULE; + err = cdev_add(&g_srt_dev->cdev, devno, 1); + if (err) + { + DEBUG_PRINT(LOG_TAG "cdev add=%d, error=%d", devno, err); + return -1; + } + g_srt_dev->pClass = class_create(THIS_MODULE, "srt_class"); + if (IS_ERR(g_srt_dev->pClass)) + { + DEBUG_PRINT(LOG_TAG "create class error\n"); + return -1; + } + g_srt_dev->pClassDev = device_create(g_srt_dev->pClass, NULL, devno, NULL, "srt_dev"); + if (IS_ERR(g_srt_dev->pClassDev)) + { + DEBUG_PRINT(LOG_TAG "create class dev error\n"); + return -1; + } + DEBUG_PRINT(LOG_TAG "%s End\n", __func__); + return 0; +} + +void srt_exit(void) +{ + DEBUG_PRINT(LOG_TAG "%s\n", __func__); + + cdev_del(&g_srt_dev->cdev); + device_destroy(g_srt_dev->pClass, MKDEV(g_srt_dev->dev_major, 0)); + class_destroy(g_srt_dev->pClass); + unregister_chrdev_region(MKDEV(g_srt_dev->dev_major, 0), 1); + kfree(g_srt_dev); + g_srt_dev=0; +} + +module_init(srt_init); +module_exit(srt_exit); + +MODULE_AUTHOR("jie.yang <jie.yang@spreadtrum.com>"); +MODULE_DESCRIPTION("SRT"); +MODULE_LICENSE("GPL"); diff --git a/drivers/misc/sprd_srt/sprd_srt.h b/drivers/misc/sprd_srt/sprd_srt.h new file mode 100644 index 00000000..bd107920 --- /dev/null +++ b/drivers/misc/sprd_srt/sprd_srt.h @@ -0,0 +1,29 @@ +#ifndef __SPRD_SRT_H__ +#define __SPRD_SRT_H__ + + + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "<4>SPRD_SRT " + + +#define SRT_DEBUG (0) /*log switch ,default 0*/ +#if SRT_DEBUG +#define DEBUG_PRINT printk +#else +#define DEBUG_PRINT(...) +#endif + +struct srtinfo_struct +{ + unsigned int value[5]; +}; +struct srt_dev { + struct cdev cdev; + int dev_major; + struct class *pClass; + struct device *pClassDev; +}; +#endif diff --git a/drivers/misc/sprd_srt/srt_proc.c b/drivers/misc/sprd_srt/srt_proc.c new file mode 100644 index 00000000..27de7894 --- /dev/null +++ b/drivers/misc/sprd_srt/srt_proc.c @@ -0,0 +1,281 @@ +#include <linux/module.h> +#include <linux/types.h> +#include <linux/fs.h> +#include <linux/init.h> +#include <linux/uaccess.h> +#include <linux/proc_fs.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/cdev.h> +#include <linux/list.h> +#include <linux/io.h> +#include <linux/input.h> +#include <linux/delay.h> +#include <linux/vmalloc.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/delay.h> +#include <linux/kthread.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/gfp.h> +#include <linux/proc_fs.h> +#include <asm/page.h> +#include <linux/mm.h> +#include <linux/proc_fs.h> + +#define LOG_TAG "AK47Driver: " + +struct slab_obj { + int aa; + int bb; + int cc; + char buff[32]; + char buff2[8]; +}; + +static struct input_dev *ak47_dev; +typedef struct slab_obj *slab_obj_t; +static slab_obj_t memblk; +static struct kmem_cache *myslabobj; +static int pagec; +static char restart_cmd[256] = "/system/bin/start"; +void sprd_srt_sdcard_plug(int plug); +void sprd_srt_emmc_test(int i, int count); +int runcmd(bool force); +static void mm_create(void) +{ + myslabobj = + kmem_cache_create("my_slab_obj", sizeof(struct slab_obj), 0, + SLAB_HWCACHE_ALIGN, NULL); + memblk = kmem_cache_alloc(myslabobj, GFP_KERNEL); + memblk->aa = 0; + memblk->bb = 1; + memblk->cc = 2; + strcpy(memblk->buff2, + "abcdefghtkksfsdllsdfsdksfsdfsdfsjfjsdkfjsdlfjsdl"); +} + +static void mm_destroy(void) +{ + kfree(memblk); + kmem_cache_destroy(myslabobj); +} + +int thread_func(void *arg) +{ + printk("AK47 in kthread :%d\n", (int)arg); + msleep_interruptible((int)arg * 1000); + printk("AK47 in kthread wakup\n"); + runcmd(1); + return 0; +} + +static void argv_cleanup(struct subprocess_info *info) +{ + argv_free(info->argv); +} +int runcmd(bool force) +{ + char **argv; + static char *envp[] = { + "HOME=/", + "PATH=/sbin:/bin:/usr/sbin:/usr/bin", + NULL + }; + int ret; + + argv = argv_split(GFP_KERNEL, restart_cmd, NULL); + if (argv) { + ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC); + argv_free(argv); + } else { + printk(KERN_WARNING "ak47 %s failed to allocate memory for \"%s\"\n", + __func__, restart_cmd); + ret = -ENOMEM; + } + + if (ret && force) { + printk(KERN_WARNING "ak47 Failed to start \n "); + } +printk("AK47 in kthread runcmd exit\n"); + return ret; +} + +static int ak47_write_proc(struct file *file, const char __user * buffer, + unsigned long count, void *data) +{ +#define MAX_INPUT_LEN 128 + unsigned char buf[MAX_INPUT_LEN] = { 0 }; + unsigned char bufCMD[MAX_INPUT_LEN] = { 0 }; + int i; + printk(KERN_ERR "SRT AK47 12.10! \n"); + if (ak47_dev) { + memset(buf, 0, MAX_INPUT_LEN); + if (count > 0 && count < MAX_INPUT_LEN) { + copy_from_user(buf, buffer, count); + printk(KERN_ERR "SRT AK47 buffer: %s \n", buf); + unsigned char *sep = strstr(buf, " "); + if (NULL == sep) { + printk(KERN_ERR "SRT AK47 error 1! \n"); + return; + } + strncpy(bufCMD, buf, sep - buf); + printk(KERN_ERR "SRT AK47 %s! \n", bufCMD); + if (strcmp(bufCMD, "plugin") == 0) { + + /*sprd_srt_sdcard_plug(0);*/ + } + if (strcmp(bufCMD, "plugout") == 0) { + /*sprd_srt_sdcard_plug(1);*/ + } + if (strcmp(bufCMD, "emmcpm") == 0) { + printk(KERN_ERR "SRT do EMMCPM test! \n"); + char cmd[32] = { 0 }; + strcpy(cmd, sep + 1); + /*sprd_srt_emmc_test(1,simple_strtol(sep + 1, NULL,10));*/ + } + if (strcmp(bufCMD, "emmcpmrt") == 0) { + char cmd[32] = { 0 }; + strcpy(cmd, sep + 1); + /*sprd_srt_emmc_test(0,simple_strtol(sep + 1, NULL,10));*/ + } + if (strcmp(bufCMD, "getfreepage") == 0) { + printk(KERN_ERR "AK47 getfreepage \n"); + void *p = __get_free_page(GFP_KERNEL); + if (NULL == p) { + printk(KERN_ERR + "AK47 getfreepage [%d] k failed\n", + 1); + } else { + pagec++; + printk("AK47 getfreepage addr=%x", p); + } + } + if (strcmp(bufCMD, "kmalloc") == 0) { + printk(KERN_ERR "AK47 kmalloc [%d] k\n", + simple_strtol(sep + 1, NULL, 10) * 4); + void *p = + kmalloc(simple_strtol(sep + 1, NULL, 10) * + 1024 * 4, GFP_KERNEL); + if (NULL == p) { + printk(KERN_ERR + "AK47 kmalloc [%d] k failed\n", + simple_strtol(sep + 1, NULL, + 10) * 4); + } else { + char *pc = (char *)p; + memset(pc, 0, 255); + strcpy(pc, "kmallocstring"); + printk("AK47 kmalloc addr=%x,%s", p, + pc); + } + } + if (strcmp(bufCMD, "vmalloc") == 0) { + printk(KERN_ERR "AK47 vmalloc [%d] k\n", + simple_strtol(sep + 1, NULL, 10) * 4); + void *p = + vmalloc(simple_strtol(sep + 1, NULL, 10) * + 1024 * 4); + if (NULL == p) { + printk(KERN_ERR + "AK47 vmalloc [%d] k failed\n", + simple_strtol(sep + 1, NULL, + 10) * 4); + } else { + printk("AK47 vmalloc addr=%x", p); + } + } + if (strcmp(bufCMD, "kstart") == 0) { + printk(KERN_ERR "AK47 ksatrt [%s] \n", sep + 1); + int s = simple_strtol(sep + 1, NULL, 10); + { + struct task_struct *my_thread = NULL; + int rc; + my_thread = + kthread_run(thread_func, s, + "srtkot"); + if (IS_ERR(my_thread)) { + rc = PTR_ERR(my_thread); + printk + ("AK47 error %d create kthread thread\n", + rc); + } else { + printk + ("AK47 create kthread ok\n"); + } + } + } + if (strcmp(bufCMD, "printk") == 0) { + printk(KERN_ERR "AK47 printk [%s] \n", sep + 1); + } + if (strcmp(bufCMD, "inputkey") == 0) { + printk(KERN_ERR "AK47 inputkey [%s] \n", + sep + 1); + int param_size = strlen(sep + 1); + unsigned char *keyBuf = sep + 1; + for (i = 0; i < param_size; i++) { + int key = 0; + if ('u' == keyBuf[i]) { + key = KEY_VOLUMEUP; + } + if ('d' == keyBuf[i]) { + key = KEY_VOLUMEDOWN; + } + input_report_key(ak47_dev, key, 1); + input_report_key(ak47_dev, key, 0); + input_sync(ak47_dev); + printk(KERN_ERR "AK47 inputkey ok"); + } + } + if (strcmp(bufCMD, "slub") == 0) { + mm_create(); + mm_destroy(); + } + } + } + return count; +} +static const struct file_operations proc_srtproc_operations = { + .owner = THIS_MODULE, + .write = ak47_write_proc, +}; +static int __init ak47dev_init(void) +{ + struct proc_dir_entry *ak47_proc = NULL; + int i; + printk(KERN_ERR "AK47 ak47dev_init begin"); + ak47_proc = proc_create("ak47", 0777, NULL, &proc_srtproc_operations); + /*ak47_proc = create_proc_entry("ak47", 0777, NULL);*/ + if (ak47_proc) { + /*ak47_proc->write_proc = ak47_write_proc;*/ + } else { + printk(KERN_ERR "AK47 ak47dev_init error 1 "); + return -EBUSY; + } + ak47_dev = input_allocate_device(); + if (ak47_dev == NULL) { + printk(KERN_ERR "AK47 ak47dev_init error 2"); + return -ENODEV; + } + ak47_dev->name = "ak47"; + set_bit(EV_KEY, ak47_dev->evbit); + set_bit(KEY_VOLUMEUP, ak47_dev->keybit); + set_bit(KEY_VOLUMEDOWN, ak47_dev->keybit); + + input_register_device(ak47_dev); + return 0; +} + +static void __exit ak47dev_exit(void) +{ + if (ak47_dev) + input_unregister_device(ak47_dev); + remove_proc_entry("ak47", NULL); +} + +module_init(ak47dev_init); +module_exit(ak47dev_exit); +MODULE_DESCRIPTION("AK47 utils Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/misc/sprd_srt/srtpm.c b/drivers/misc/sprd_srt/srtpm.c new file mode 100644 index 00000000..b5e1579c --- /dev/null +++ b/drivers/misc/sprd_srt/srtpm.c @@ -0,0 +1,119 @@ +#include <linux/init.h> +#include <linux/module.h> +#include <linux/types.h> +#include <linux/fs.h> +#include <linux/proc_fs.h> +#include <linux/device.h> +#include <linux/kmsg_dump.h> +#include <linux/reboot.h> +#include <linux/uaccess.h> +#include <mach/system.h> +#include <linux/mm.h> +#include <linux/vmalloc.h> +#include <linux/slab.h> + +#include "srtpm.h" + +static void srtpm_poweroff() +{ + printk(KERN_ALERT "Power down.\n"); + if (pm_power_off)pm_power_off(); +} + +static ssize_t __srtpm_get_val(char *buf, int len) +{ + int val = 0; + + return snprintf(buf, len, "%d\n", val); +} + + +static ssize_t __srtpm_set_val(const char *buf, size_t count) +{ + int val = 0; + val = kstrtol(buf, NULL, 10); + if (val == 1)srtpm_poweroff(); + return count; +} + + +static ssize_t srtpm_proc_read(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + if (off > 0) { + *eof = 1; + return 0; + } + + return __srtpm_get_val(page, count); +} + +static ssize_t srtpm_proc_write(struct file *filp, const char __user * buff, + unsigned long len, void *data) +{ + int err = 0; + char *page = NULL; + + if (len > PAGE_SIZE) { + printk(KERN_ALERT "The buff is too large:%lu.\n", len); + return -EFAULT; + } + + page = (char *)kmalloc(len, GFP_KERNEL); + if (!page) { + printk(KERN_ALERT "Failed to alloc page.\n"); + return -ENOMEM; + } + if (copy_from_user(page, buff, len)) { + printk(KERN_ALERT "Failed to copy buff from user.\n"); + err = -EFAULT; + goto out; + } + + err = __srtpm_set_val(page, len); + +out: + kfree(page); + return err; +} +static const struct file_operations proc_srtpm_operations = { + .owner = THIS_MODULE, + .write = srtpm_proc_write, + .read = srtpm_proc_read, +}; + +static void srtpm_create_proc(void) +{ + struct proc_dir_entry *entry; + entry = proc_create(SRTPM_DEVICE_PROC_NAME, 0, NULL, &proc_srtpm_operations); +} + + +static void srtpm_remove_proc(void) +{ + remove_proc_entry(SRTPM_DEVICE_PROC_NAME, NULL); +} + + +static int __init srtpm_init(void) +{ + + srtpm_create_proc(); + + printk(KERN_ALERT "Successed to initialize srtpm device.\n"); + return 0; +} + + +static void __exit srtpm_exit(void) +{ + printk(KERN_ALERT "Destroy srtpm device.\n"); + + srtpm_remove_proc(); +} + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("First Android Device"); + +module_init(srtpm_init); +module_exit(srtpm_exit); diff --git a/drivers/misc/sprd_srt/srtpm.h b/drivers/misc/sprd_srt/srtpm.h new file mode 100644 index 00000000..763d7b9e --- /dev/null +++ b/drivers/misc/sprd_srt/srtpm.h @@ -0,0 +1,18 @@ +#ifndef _SRTPM_ANDROID_H_ +#define _SRTPM_ANDROID_H_ + +#include <linux/cdev.h> +#include <linux/semaphore.h> + +#define SRTPM_DEVICE_NODE_NAME "SrtPM" +#define SRTPM_DEVICE_FILE_NAME "SrtPM" +#define SRTPM_DEVICE_PROC_NAME "SrtPM" +#define SRTPM_DEVICE_CLASS_NAME "SrtPM" + +struct srtpm_android_dev { + int val; + struct semaphore sem; + struct cdev dev; +}; + +#endif |
