static int vc_mem_proc_read(char *buf, char **start, off_t offset, int count, int *eof, void *data) { char *p = buf; (void) start; (void) count; (void) data; if (offset > 0) { *eof = 1; return 0; } // Get the videocore memory size first vc_mem_get_size(); p += sprintf(p, "Videocore memory:\n"); if (mm_vc_mem_phys_addr != 0) p += sprintf(p, " Physical address: 0x%p\n", (void *) mm_vc_mem_phys_addr); else p += sprintf(p, " Physical address: 0x00000000\n"); p += sprintf(p, " Length (bytes): %u\n", mm_vc_mem_size); *eof = 1; return p - buf; }
static int vc_mem_proc_write(struct file *file, const char __user * buffer, unsigned long count, void *data) { int rc = -EFAULT; char input_str[10]; memset(input_str, 0, sizeof (input_str)); if (count > sizeof (input_str)) { LOG_ERR("%s: input string length too long", __func__); goto out; } if (copy_from_user(input_str, buffer, count - 1)) { LOG_ERR("%s: failed to get input string", __func__); goto out; } if (strncmp(input_str, "connect", strlen("connect")) == 0) { // Get the videocore memory size from the videocore vc_mem_get_size(); } out: return rc; }
static int vc_mem_proc_read(char *buf, char **start, off_t offset, int count, int *eof, void *data) { char *p = buf; (void)start; (void)count; (void)data; if (offset > 0) { *eof = 1; return 0; } /* Get the videocore memory size first */ vc_mem_get_size(); p += sprintf(p, "Videocore memory:\n"); p += sprintf(p, " Physical address: 0x%p\n", (void *)mm_vc_mem_phys_addr); p += sprintf(p, " Base Offset: 0x%08x (%u MiB)\n", mm_vc_mem_base, mm_vc_mem_base >> 20); p += sprintf(p, " Load Offset: 0x%08x (%u MiB)\n", mm_vc_mem_load, mm_vc_mem_load >> 20); p += sprintf(p, " Length (bytes): %u (%u MiB)\n", mm_vc_mem_size, mm_vc_mem_size >> 20); *eof = 1; return p - buf; }
int vc_mem_get_current_load(void) { vc_mem_get_size(); printk(KERN_INFO "vc-mem: current load check = 0x%08x (%u MiB)\n", mm_vc_mem_load, mm_vc_mem_load / (1024 * 1024)); return mm_vc_mem_load; }
int vc_mem_get_current_base(void) { vc_mem_get_size(); printk(KERN_INFO "vc-mem: current base check = 0x%08x (%u MiB)\n", mm_vc_mem_base, mm_vc_mem_base / (1024 * 1024)); return mm_vc_mem_base; }
static long vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int rc = 0; (void) cmd; (void) arg; LOG_DBG("%s: called file = 0x%p", __func__, file); switch (cmd) { case VC_MEM_IOC_MEM_PHYS_ADDR: { LOG_DBG("%s: VC_MEM_IOC_MEM_PHYS_ADDR=0x%p", __func__, (void *) mm_vc_mem_phys_addr); if (copy_to_user((void *) arg, &mm_vc_mem_phys_addr, sizeof (mm_vc_mem_phys_addr)) != 0) { rc = -EFAULT; } break; } case VC_MEM_IOC_MEM_SIZE: { // Get the videocore memory size first vc_mem_get_size(); LOG_DBG("%s: VC_MEM_IOC_MEM_SIZE=%u", __func__, mm_vc_mem_size); if (copy_to_user((void *) arg, &mm_vc_mem_size, sizeof (mm_vc_mem_size)) != 0) { rc = -EFAULT; } break; } case VC_MEM_IOC_MEM_BASE: { // Get the videocore memory base vc_mem_get_base(); LOG_DBG("%s: VC_MEM_IOC_MEM_BASE=%u", __func__, mm_vc_mem_base); if (copy_to_user((void *) arg, &mm_vc_mem_base, sizeof (mm_vc_mem_base)) != 0) { rc = -EFAULT; } break; } default: { return -ENOTTY; } } LOG_DBG("%s: file = 0x%p returning %d", __func__, file, rc); return rc; }
void vc_mem_connected_init(void) { int rc = -EFAULT; struct device *dev; LOG_DBG("%s: called", __func__); vc_mem_get_size(); printk("vc-mem: mm_vc_mem_phys_addr = 0x%08lx\n", mm_vc_mem_phys_addr); printk("vc-mem: mm_vc_mem_size = 0x%08x (%u MiB)\n", mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024)); if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) { LOG_ERR("%s: alloc_chrdev_region failed (rc=%d)", __func__, rc); goto out_err; } cdev_init(&vc_mem_cdev, &vc_mem_fops); if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) { LOG_ERR("%s: cdev_add failed (rc=%d)", __func__, rc); goto out_unregister; } vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME); if (IS_ERR(vc_mem_class)) { rc = PTR_ERR(vc_mem_class); LOG_ERR("%s: class_create failed (rc=%d)", __func__, rc); goto out_cdev_del; } dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL, DRIVER_NAME); if (IS_ERR(dev)) { rc = PTR_ERR(dev); LOG_ERR("%s: device_create failed (rc=%d)", __func__, rc); goto out_class_destroy; } vc_mem_proc_entry = create_proc_entry(DRIVER_NAME, 0444, NULL); if (vc_mem_proc_entry == NULL) { rc = -EFAULT; LOG_ERR("%s: create_proc_entry failed", __func__); goto out_device_destroy; } vc_mem_proc_entry->read_proc = vc_mem_proc_read; vc_mem_proc_entry->write_proc = vc_mem_proc_write; vc_mem_inited = 1; return; out_device_destroy: device_destroy(vc_mem_class, vc_mem_devnum); out_class_destroy: class_destroy(vc_mem_class); vc_mem_class = NULL; out_cdev_del: cdev_del(&vc_mem_cdev); out_unregister: unregister_chrdev_region(vc_mem_devnum, 1); out_err: return; }
int vc_mem_get_current_size(void) { vc_mem_get_size(); return mm_vc_mem_size; }
static int __init vc_mem_init(void) { int rc = -EFAULT; struct device *dev; pr_debug("%s: called\n", __func__); mm_vc_mem_phys_addr = phys_addr; mm_vc_mem_size = mem_size; mm_vc_mem_base = mem_base; vc_mem_get_size(); pr_info("vc-mem: phys_addr:0x%08lx mem_base=0x%08x mem_size:0x%08x(%u MiB)\n", mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024)); if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) { pr_err("%s: alloc_chrdev_region failed (rc=%d)\n", __func__, rc); goto out_err; } cdev_init(&vc_mem_cdev, &vc_mem_fops); if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) { pr_err("%s: cdev_add failed (rc=%d)\n", __func__, rc); goto out_unregister; } vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME); if (IS_ERR(vc_mem_class)) { rc = PTR_ERR(vc_mem_class); pr_err("%s: class_create failed (rc=%d)\n", __func__, rc); goto out_cdev_del; } dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL, DRIVER_NAME); if (IS_ERR(dev)) { rc = PTR_ERR(dev); pr_err("%s: device_create failed (rc=%d)\n", __func__, rc); goto out_class_destroy; } #ifdef CONFIG_DEBUG_FS /* don't fail if the debug entries cannot be created */ vc_mem_debugfs_init(dev); #endif vc_mem_inited = 1; return 0; device_destroy(vc_mem_class, vc_mem_devnum); out_class_destroy: class_destroy(vc_mem_class); vc_mem_class = NULL; out_cdev_del: cdev_del(&vc_mem_cdev); out_unregister: unregister_chrdev_region(vc_mem_devnum, 1); out_err: return -1; }
static int __init vc_mem_init(void) { int rc = -EFAULT; struct device *dev; uint32_t base, load, size; /* * NOTE: vc_mem can't use vchiq_add_connected_callback, * otherwise it will create a module dependancy loop. * * As long as u-boot has initialized the videocore, then this doesn't * cause any problems. The only corner case occurs when the vc_mem * module is statically linked into the kernel and the kernel does the * videocore firmware initialization. In that case we'll report that * the memory size isn't available, and calls to retrieve the memory * size will return zero until the videocore has been initialized. */ printk(KERN_INFO "vc-mem: Videocore memory driver\n"); if (vc_dt_get_mem_config(&base, &load, &size) == 0) { mm_vc_mem_phys_addr = (unsigned long)(base & 0xC0000000); mm_vc_mem_base = (unsigned int)(base & 0x3FFFFFFF); mm_vc_mem_load = (unsigned int)(load & 0x3FFFFFFF); mm_vc_mem_size = size; printk(KERN_INFO "vc-mem: p: 0x%08lx, b: 0x%08x, l: 0x%08x, s: 0x%08x\n", mm_vc_mem_phys_addr, base, load, size); } else { /* fallback to default VC EMI, Capri >= A2 */ mm_vc_mem_phys_addr = 0xC0000000; mm_vc_mem_base = (unsigned int)mm_vc_mem_phys_addr; mm_vc_mem_load = (unsigned int)mm_vc_mem_phys_addr; printk(KERN_WARNING "vc-mem: legacy-base = 0x%08x, update your dt-blob!\n", mm_vc_mem_base); } vc_mem_get_size(); rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME); if (rc < 0) { LOG_ERR("%s: alloc_chrdev_region failed (rc=%d)", __func__, rc); goto out_err; } cdev_init(&vc_mem_cdev, &vc_mem_fops); rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1); if (rc != 0) { LOG_ERR("%s: cdev_add failed (rc=%d)", __func__, rc); goto out_unregister; } vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME); if (IS_ERR(vc_mem_class)) { rc = PTR_ERR(vc_mem_class); LOG_ERR("%s: class_create failed (rc=%d)", __func__, rc); goto out_cdev_del; } dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL, DRIVER_NAME); if (IS_ERR(dev)) { rc = PTR_ERR(dev); LOG_ERR("%s: device_create failed (rc=%d)", __func__, rc); goto out_class_destroy; } vc_mem_proc_entry = create_proc_entry(DRIVER_NAME, 0444, NULL); if (vc_mem_proc_entry == NULL) { rc = -EFAULT; LOG_ERR("%s: create_proc_entry failed", __func__); goto out_device_destroy; } vc_mem_proc_entry->read_proc = vc_mem_proc_read; vc_mem_proc_entry->write_proc = vc_mem_proc_write; vc_mem_inited = 1; return 0; out_device_destroy: device_destroy(vc_mem_class, vc_mem_devnum); out_class_destroy: class_destroy(vc_mem_class); vc_mem_class = NULL; out_cdev_del: cdev_del(&vc_mem_cdev); out_unregister: unregister_chrdev_region(vc_mem_devnum, 1); out_err: return -1; }