static ssize_t smem_sleep_log_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) { struct smem_sleep_log_data *dev = (struct smem_sleep_log_data *)file->private_data; size_t copy_len =0; SMEM_SLEEP_LOG_DEBUG("%s base = 0x%x, len =%d, offset = %d, buf_size=%d \r\n",__FUNCTION__,dev->smem_buf_base, len,dev->buf_offset,dev->buf_size); if(dev->buf_offset >= dev->buf_size) { /*copy is finished */ return 0; } else { copy_len = ((dev->buf_size - dev->buf_offset) > len) ? len : (dev->buf_size - dev->buf_offset); } if(NULL != dev->smem_buf_base) { /*copy data to user space */ if(copy_to_user((void __user *)buf, dev->smem_buf_base + dev->buf_offset, copy_len)) { SMEM_SLEEP_LOG_DEBUG("smem_sleep_log_read: Fail to copy memory to user space !\n"); return -EFAULT; } dev->buf_offset += copy_len; } else { return -ENOMEM; } return copy_len; }
static int smem_sleep_log_open(struct inode *inode, struct file *file) { SMEM_SLEEP_LOG_DEBUG("%s \r\n",__FUNCTION__); long buf_len = 0; if (down_interruptible(&smem_sleep_log_dev->open_sem)) { SMEM_SLEEP_LOG_DEBUG(KERN_ERR "smem_open: can not get open_sem!\n"); return -ERESTARTSYS; } file->private_data = smem_sleep_log_dev; if(NULL == smem_sleep_log_dev->smem_buf_base) { return -ENOMEM; } /*get the buffer actul length and actul offset*/ memcpy(&buf_len,smem_sleep_log_dev->smem_buf_base,sizeof(long)); smem_sleep_log_dev->buf_size = (buf_len < (smem_buf_size - sizeof(long))) ? buf_len :(smem_buf_size - sizeof(long)); smem_sleep_log_dev->buf_offset = sizeof(long); return 0; }
static int smem_sleep_log_release(struct inode *inode, struct file *file) { SMEM_SLEEP_LOG_DEBUG("%s \r\n",__FUNCTION__); up(&smem_sleep_log_dev->open_sem); return 0; }
static ssize_t smem_sleep_log_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) { struct smem_log_data *dev = (struct smem_log_data *)file->private_data; size_t copy_len =0; if(dev->buf_offset >= dev->buf_size) { /*copy is finished */ return 0; } else { copy_len = ((dev->buf_size - dev->buf_offset) > len) ? len : (dev->buf_size - dev->buf_offset); } if(NULL != psmem_buffer) { /*copy data to user space */ if(copy_to_user((void __user *)buf, psmem_buffer + dev->buf_offset, copy_len)) { SMEM_SLEEP_LOG_DEBUG(KERN_ERR "smem_sleep_log_read: Fail to copy memory to user space !\n"); return -EFAULT; } dev->buf_offset += copy_len; } else { return -ENOMEM; } return copy_len; }
static int smem_sleep_log_open(struct inode *inode, struct file *file) { if (down_interruptible(&smem_log_dev->open_sem)) { SMEM_SLEEP_LOG_DEBUG(KERN_ERR "smem_open: can not get open_sem!\n"); return -ERESTARTSYS; } file->private_data = smem_log_dev; smem_log_dev->buf_size = 0; /*delete 6 lines*/ return 0; }
/*not malloc memory by kmalloc any more, and uste the memory get by smem_alloc directly */ static long smem_sleep_log_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int ret = 0; struct smem_log_data *dev = (struct smem_log_data *)file->private_data; dev->buf_offset = 0; switch(cmd) { /*copy Pwr envent from SMEM to memory*/ case MSM_SMEM_SLEEP_LOG_IOCTL_GET_PWR_EVENT: psmem_buffer = smem_alloc(SMEM_SMEM_LOG_POWER_EVENTS,MAX_SMEM_SLEEP_LOG_EVENT_BUF_SIZE); dev->buf_size = MAX_SMEM_SLEEP_LOG_EVENT_BUF_SIZE; if(NULL == psmem_buffer) { SMEM_SLEEP_LOG_DEBUG(KERN_ERR "smem_sleep_log_ioctl: failed get PWR event\n"); return -ENOMEM; } break; /*copy sleep voters from SMEM to memory*/ case MSM_SMEM_SLEEP_LOG_IOCTL_GET_SLEEP_VOTER: psmem_buffer = smem_alloc(SMEM_SLEEP_STATIC,MAX_SMEM_SLEEP_VOTER_BUF_SIZE); dev->buf_size = MAX_SMEM_SLEEP_VOTER_BUF_SIZE; if(NULL == psmem_buffer) { SMEM_SLEEP_LOG_DEBUG(KERN_ERR "smem_sleep_log_ioctl: failed get Sleep voter\n"); return -ENOMEM; } break; default: break; } return ret; }
static int smem_sleep_log_prob(struct platform_device *pdev) { dev_t dev_id; int retval; int error; unsigned char *mem_base = 0; smem_sleep_log_dev = kzalloc(sizeof(struct smem_sleep_log_data), GFP_KERNEL); if (!smem_sleep_log_dev) { SMEM_SLEEP_LOG_DEBUG(KERN_ERR "smem_sleep_log_prob: Unable to alloc memory for device\n"); return (-ENOMEM); } /* map sleep log memory */ if ((pdev->id == 0) && (pdev->num_resources > 0)) { smem_buf_size = pdev->resource[0].end - pdev->resource[0].start + 1; mem_base = (unsigned char *)(pdev->resource[0].start); SMEM_SLEEP_LOG_DEBUG("%s: phys addr = 0x%x, size = 0x%x\n", __FUNCTION__, mem_base, smem_buf_size); smem_sleep_log_dev->smem_buf_base = ioremap((unsigned long)mem_base, (unsigned long)smem_buf_size); SMEM_SLEEP_LOG_DEBUG("%s: mapped virt address = 0x%x\n", __FUNCTION__, smem_sleep_log_dev->smem_buf_base); if (!smem_sleep_log_dev->smem_buf_base) { printk("smem_sleep_log_prob failed\n"); return -EBUSY; } } /*init mutex*/ init_MUTEX(&smem_sleep_log_dev->open_sem); if (major) { dev_id = MKDEV(major, 0); retval = register_chrdev_region(dev_id, SMEM_SLEEP_LOG_COUNT, NAME); } else { retval = alloc_chrdev_region(&dev_id, 0, SMEM_SLEEP_LOG_COUNT, NAME); major = MAJOR(dev_id); } if (retval) { SMEM_SLEEP_LOG_DEBUG(KERN_ERR "smem_sleep_log cant get major\n"); kfree(smem_sleep_log_dev); return -1; } smem_sleep_log_dev->kt_class = class_create(THIS_MODULE, NAME); if (IS_ERR(smem_sleep_log_dev->kt_class)) { SMEM_SLEEP_LOG_DEBUG(KERN_ERR "failed to class_create\n"); goto can_not_create_class; } smem_sleep_log_dev->pdevice = device_create(smem_sleep_log_dev->kt_class, NULL, dev_id, "%s", NAME); if (IS_ERR(smem_sleep_log_dev->pdevice)) { SMEM_SLEEP_LOG_DEBUG(KERN_ERR "Can't create smem log device\n"); goto can_not_create_class; } cdev_init(&(smem_sleep_log_dev->cdev), &smem_sleep_log_fops); smem_sleep_log_dev->cdev.owner = THIS_MODULE; error = cdev_add(&(smem_sleep_log_dev->cdev), dev_id, SMEM_SLEEP_LOG_COUNT); if (error) { SMEM_SLEEP_LOG_DEBUG(KERN_ERR "smem_sleep_log_prob: Failed cdev_add\n"); error = ENOENT; goto can_not_add_cdev; } return 0; can_not_add_cdev: class_unregister(smem_sleep_log_dev->kt_class); can_not_create_class: unregister_chrdev_region(dev_id, 1); iounmap((void *)(smem_sleep_log_dev->smem_buf_base)); kfree(smem_sleep_log_dev); return error; }
static int __init smem_sleep_log_init(void) { dev_t dev_id; int retval; int error; smem_log_dev = kzalloc(sizeof(struct smem_log_data), GFP_KERNEL); if (!smem_log_dev) { SMEM_SLEEP_LOG_DEBUG(KERN_ERR "smem_sleep_log_init: Unable to alloc memory for device\n"); return (-ENOMEM); } /*init mutex*/ init_MUTEX(&smem_log_dev->open_sem); if (major) { dev_id = MKDEV(major, 0); retval = register_chrdev_region(dev_id, SMEM_SLEEP_LOG_COUNT, NAME); } else { retval = alloc_chrdev_region(&dev_id, 0, SMEM_SLEEP_LOG_COUNT, NAME); major = MAJOR(dev_id); } if (retval) { SMEM_SLEEP_LOG_DEBUG(KERN_ERR "smem_sleep_log cant get major\n"); kfree(smem_log_dev); return -1; } smem_log_dev->kt_class = class_create(THIS_MODULE, NAME); if (IS_ERR(smem_log_dev->kt_class)) { SMEM_SLEEP_LOG_DEBUG(KERN_ERR "failed to class_create\n"); goto can_not_create_class; } smem_log_dev->pdevice = device_create(smem_log_dev->kt_class, NULL, dev_id, "%s", NAME); if (IS_ERR(smem_log_dev->pdevice)) { SMEM_SLEEP_LOG_DEBUG(KERN_ERR "Can't create smem log device\n"); goto can_not_create_class; } cdev_init(&(smem_log_dev->cdev), &smem_sleep_log_fops); smem_log_dev->cdev.owner = THIS_MODULE; error = cdev_add(&(smem_log_dev->cdev), dev_id, SMEM_SLEEP_LOG_COUNT); if (error) { SMEM_SLEEP_LOG_DEBUG(KERN_ERR "init_key_test_cdev: Failed cdev_add\n"); error = ENOENT; goto can_not_add_cdev; } return 0; can_not_add_cdev: class_unregister(smem_log_dev->kt_class); can_not_create_class: unregister_chrdev_region(dev_id, 1); kfree(smem_log_dev); return error; }