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;
}
示例#3
0
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;
}
示例#4
0
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;
}
示例#5
0
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;
}
示例#9
0
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;
}
示例#10
0
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;
}