Lines Matching +full:host +full:- +full:wake

1 // SPDX-License-Identifier: GPL-2.0
6 * Copyright (C) 2011-2016 Google, Inc.
44 * guest user addresses into host ones.
62 #include <linux/dma-mapping.h>
69 * Update this when something changes in the driver's behavior so the host
85 /* A per-pipe command structure, shared with the host */
87 s32 cmd; /* PipeCmdCode, guest -> host */
88 s32 id; /* pipe id, guest -> host */
89 s32 status; /* command execution status, host -> guest */
90 s32 reserved; /* to pad to 64-bit boundary */
94 /* number of buffers, guest -> host */
96 /* number of consumed bytes, host -> guest */
98 /* buffer pointers, guest -> host */
100 /* buffer sizes, guest -> host */
118 /* Device-level set of buffers shared with the host */
127 /* pipe ID - index into goldfish_pipe_dev::pipes array */
130 /* The wake flags pipe is waiting for
132 * and barriers to make it thread-safe.
136 /* wake flags host have signalled,
137 * - protected by goldfish_pipe_dev::lock
152 * - *command_buffer - makes sure a command can safely write its
153 * parameters to the host and read the results back.
157 /* A wake queue for sleeping until host signals an event */
168 * communicate with the emulator, and a wake queue for blocked tasks
177 * - pipes, pipes_capacity
178 * - [*pipes, *pipes + pipes_capacity) - array data
179 * - first_signalled_pipe,
182 * goldfish_pipe::signalled_flags - all singnalled-related fields,
184 * - open_command_params - PIPE_CMD_OPEN-related buffers
201 /* Pointers to the buffers host uses for interaction with this driver */
210 /* Some device-specific data */
224 pipe->command_buffer->cmd = cmd; in goldfish_pipe_cmd_locked()
226 pipe->command_buffer->status = PIPE_ERROR_INVAL; in goldfish_pipe_cmd_locked()
227 writel(pipe->id, pipe->dev->base + PIPE_REG_CMD); in goldfish_pipe_cmd_locked()
228 return pipe->command_buffer->status; in goldfish_pipe_cmd_locked()
235 if (mutex_lock_interruptible(&pipe->lock)) in goldfish_pipe_cmd()
238 mutex_unlock(&pipe->lock); in goldfish_pipe_cmd()
250 return -EAGAIN; in goldfish_pipe_error_convert()
252 return -ENOMEM; in goldfish_pipe_error_convert()
254 return -EIO; in goldfish_pipe_error_convert()
256 return -EINVAL; in goldfish_pipe_error_convert()
268 int requested_pages = ((last_page - first_page) >> PAGE_SHIFT) + 1; in goldfish_pin_pages()
281 return -EFAULT; in goldfish_pin_pages()
300 * Process the first page separately - it's the only page that in populate_rw_params()
308 ? (int)(address_end - address) in populate_rw_params()
309 : (PAGE_SIZE - (address & ~PAGE_MASK)); in populate_rw_params()
310 command->rw_params.ptrs[0] = (u64)(xaddr | (address & ~PAGE_MASK)); in populate_rw_params()
311 command->rw_params.sizes[0] = size_on_page; in populate_rw_params()
314 size_on_page = (i == pages_count - 1) ? in populate_rw_params()
317 command->rw_params.sizes[buffer_idx] += size_on_page; in populate_rw_params()
320 command->rw_params.ptrs[buffer_idx] = (u64)xaddr; in populate_rw_params()
321 command->rw_params.sizes[buffer_idx] = size_on_page; in populate_rw_params()
325 command->rw_params.buffers_count = buffer_idx + 1; in populate_rw_params()
342 if (mutex_lock_interruptible(&pipe->lock)) in transfer_max_buffers()
343 return -ERESTARTSYS; in transfer_max_buffers()
347 pipe->pages, &iter_last_page_size); in transfer_max_buffers()
349 mutex_unlock(&pipe->lock); in transfer_max_buffers()
353 populate_rw_params(pipe->pages, pages_count, address, address_end, in transfer_max_buffers()
355 pipe->command_buffer); in transfer_max_buffers()
361 *consumed_size = pipe->command_buffer->rw_params.consumed_size; in transfer_max_buffers()
363 unpin_user_pages_dirty_lock(pipe->pages, pages_count, in transfer_max_buffers()
366 mutex_unlock(&pipe->lock); in transfer_max_buffers()
374 set_bit(wake_bit, &pipe->flags); in wait_for_host_signal()
376 /* Tell the emulator we're going to wait for a wake event */ in wait_for_host_signal()
380 while (test_bit(wake_bit, &pipe->flags)) { in wait_for_host_signal()
381 if (wait_event_interruptible(pipe->wake_queue, in wait_for_host_signal()
382 !test_bit(wake_bit, &pipe->flags))) in wait_for_host_signal()
383 return -ERESTARTSYS; in wait_for_host_signal()
385 if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags)) in wait_for_host_signal()
386 return -EIO; in wait_for_host_signal()
397 struct goldfish_pipe *pipe = filp->private_data; in goldfish_pipe_read_write()
398 int count = 0, ret = -EINVAL; in goldfish_pipe_read_write()
403 if (unlikely(test_bit(BIT_CLOSED_ON_HOST, &pipe->flags))) in goldfish_pipe_read_write()
404 return -EIO; in goldfish_pipe_read_write()
410 return -EFAULT; in goldfish_pipe_read_write()
414 last_page = (address_end - 1) & PAGE_MASK; in goldfish_pipe_read_write()
415 last_page_size = ((address_end - 1) & ~PAGE_MASK) + 1; in goldfish_pipe_read_write()
449 dev_err_ratelimited(pipe->dev->pdev_dev, in goldfish_pipe_read_write()
457 * non-blocking mode, just return the error code. in goldfish_pipe_read_write()
460 (filp->f_flags & O_NONBLOCK) != 0) { in goldfish_pipe_read_write()
495 struct goldfish_pipe *pipe = filp->private_data; in goldfish_pipe_poll()
499 poll_wait(filp, &pipe->wake_queue, wait); in goldfish_pipe_poll()
503 return -ERESTARTSYS; in goldfish_pipe_poll()
511 if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags)) in goldfish_pipe_poll()
522 if (WARN_ON(id >= dev->pipes_capacity)) in signalled_pipes_add_locked()
525 pipe = dev->pipes[id]; in signalled_pipes_add_locked()
528 pipe->signalled_flags |= flags; in signalled_pipes_add_locked()
530 if (pipe->prev_signalled || pipe->next_signalled || in signalled_pipes_add_locked()
531 dev->first_signalled_pipe == pipe) in signalled_pipes_add_locked()
533 pipe->next_signalled = dev->first_signalled_pipe; in signalled_pipes_add_locked()
534 if (dev->first_signalled_pipe) in signalled_pipes_add_locked()
535 dev->first_signalled_pipe->prev_signalled = pipe; in signalled_pipes_add_locked()
536 dev->first_signalled_pipe = pipe; in signalled_pipes_add_locked()
542 if (pipe->prev_signalled) in signalled_pipes_remove_locked()
543 pipe->prev_signalled->next_signalled = pipe->next_signalled; in signalled_pipes_remove_locked()
544 if (pipe->next_signalled) in signalled_pipes_remove_locked()
545 pipe->next_signalled->prev_signalled = pipe->prev_signalled; in signalled_pipes_remove_locked()
546 if (pipe == dev->first_signalled_pipe) in signalled_pipes_remove_locked()
547 dev->first_signalled_pipe = pipe->next_signalled; in signalled_pipes_remove_locked()
548 pipe->prev_signalled = NULL; in signalled_pipes_remove_locked()
549 pipe->next_signalled = NULL; in signalled_pipes_remove_locked()
558 spin_lock_irqsave(&dev->lock, flags); in signalled_pipes_pop_front()
560 pipe = dev->first_signalled_pipe; in signalled_pipes_pop_front()
562 *wakes = pipe->signalled_flags; in signalled_pipes_pop_front()
563 pipe->signalled_flags = 0; in signalled_pipes_pop_front()
567 * - We want to make it as fast as possible to in signalled_pipes_pop_front()
568 * wake the sleeping pipe operations faster. in signalled_pipes_pop_front()
570 dev->first_signalled_pipe = pipe->next_signalled; in signalled_pipes_pop_front()
571 if (dev->first_signalled_pipe) in signalled_pipes_pop_front()
572 dev->first_signalled_pipe->prev_signalled = NULL; in signalled_pipes_pop_front()
573 pipe->next_signalled = NULL; in signalled_pipes_pop_front()
576 spin_unlock_irqrestore(&dev->lock, flags); in signalled_pipes_pop_front()
582 /* Iterate over the signalled pipes and wake them one by one */ in goldfish_interrupt_task()
589 pipe->flags = 1 << BIT_CLOSED_ON_HOST; in goldfish_interrupt_task()
592 clear_bit(BIT_WAKE_ON_READ, &pipe->flags); in goldfish_interrupt_task()
594 clear_bit(BIT_WAKE_ON_WRITE, &pipe->flags); in goldfish_interrupt_task()
600 wake_up_interruptible(&pipe->wake_queue); in goldfish_interrupt_task()
627 if (dev->magic != &goldfish_pipe_device_deinit) in goldfish_pipe_interrupt()
631 spin_lock_irqsave(&dev->lock, flags); in goldfish_pipe_interrupt()
633 count = readl(dev->base + PIPE_REG_GET_SIGNALLED); in goldfish_pipe_interrupt()
635 spin_unlock_irqrestore(&dev->lock, flags); in goldfish_pipe_interrupt()
643 dev->buffers->signalled_pipe_buffers[i].id, in goldfish_pipe_interrupt()
644 dev->buffers->signalled_pipe_buffers[i].flags); in goldfish_pipe_interrupt()
646 spin_unlock_irqrestore(&dev->lock, flags); in goldfish_pipe_interrupt()
648 tasklet_schedule(&dev->irq_tasklet); in goldfish_pipe_interrupt()
656 for (id = 0; id < dev->pipes_capacity; ++id) in get_free_pipe_id_locked()
657 if (!dev->pipes[id]) in get_free_pipe_id_locked()
665 u32 new_capacity = 2 * dev->pipes_capacity; in get_free_pipe_id_locked()
669 return -ENOMEM; in get_free_pipe_id_locked()
670 memcpy(pipes, dev->pipes, sizeof(*pipes) * dev->pipes_capacity); in get_free_pipe_id_locked()
671 kfree(dev->pipes); in get_free_pipe_id_locked()
672 dev->pipes = pipes; in get_free_pipe_id_locked()
673 id = dev->pipes_capacity; in get_free_pipe_id_locked()
674 dev->pipes_capacity = new_capacity; in get_free_pipe_id_locked()
682 struct miscdevice *miscdev = file->private_data; in to_goldfish_pipe_dev()
688 * goldfish_pipe_open - open a channel to the AVD
709 return -ENOMEM; in goldfish_pipe_open()
711 pipe->dev = dev; in goldfish_pipe_open()
712 mutex_init(&pipe->lock); in goldfish_pipe_open()
713 init_waitqueue_head(&pipe->wake_queue); in goldfish_pipe_open()
717 * it is physically contiguous in host's address space. in goldfish_pipe_open()
720 pipe->command_buffer = in goldfish_pipe_open()
722 if (!pipe->command_buffer) { in goldfish_pipe_open()
723 status = -ENOMEM; in goldfish_pipe_open()
727 spin_lock_irqsave(&dev->lock, flags); in goldfish_pipe_open()
735 dev->pipes[id] = pipe; in goldfish_pipe_open()
736 pipe->id = id; in goldfish_pipe_open()
737 pipe->command_buffer->id = id; in goldfish_pipe_open()
740 dev->buffers->open_command_params.rw_params_max_count = in goldfish_pipe_open()
742 dev->buffers->open_command_params.command_buffer_ptr = in goldfish_pipe_open()
743 (u64)(unsigned long)__pa(pipe->command_buffer); in goldfish_pipe_open()
745 spin_unlock_irqrestore(&dev->lock, flags); in goldfish_pipe_open()
749 file->private_data = pipe; in goldfish_pipe_open()
753 spin_lock_irqsave(&dev->lock, flags); in goldfish_pipe_open()
754 dev->pipes[id] = NULL; in goldfish_pipe_open()
756 spin_unlock_irqrestore(&dev->lock, flags); in goldfish_pipe_open()
757 free_page((unsigned long)pipe->command_buffer); in goldfish_pipe_open()
766 struct goldfish_pipe *pipe = filp->private_data; in goldfish_pipe_release()
767 struct goldfish_pipe_dev *dev = pipe->dev; in goldfish_pipe_release()
772 spin_lock_irqsave(&dev->lock, flags); in goldfish_pipe_release()
773 dev->pipes[pipe->id] = NULL; in goldfish_pipe_release()
775 spin_unlock_irqrestore(&dev->lock, flags); in goldfish_pipe_release()
777 filp->private_data = NULL; in goldfish_pipe_release()
778 free_page((unsigned long)pipe->command_buffer); in goldfish_pipe_release()
796 miscdev->minor = MISC_DYNAMIC_MINOR; in init_miscdevice()
797 miscdev->name = "goldfish_pipe"; in init_miscdevice()
798 miscdev->fops = &goldfish_pipe_fops; in init_miscdevice()
814 tasklet_init(&dev->irq_tasklet, &goldfish_interrupt_task, in goldfish_pipe_device_init()
817 err = devm_request_irq(&pdev->dev, dev->irq, in goldfish_pipe_device_init()
821 dev_err(&pdev->dev, "unable to allocate IRQ for v2\n"); in goldfish_pipe_device_init()
825 init_miscdevice(&dev->miscdev); in goldfish_pipe_device_init()
826 err = misc_register(&dev->miscdev); in goldfish_pipe_device_init()
828 dev_err(&pdev->dev, "unable to register v2 device\n"); in goldfish_pipe_device_init()
832 dev->pdev_dev = &pdev->dev; in goldfish_pipe_device_init()
833 dev->first_signalled_pipe = NULL; in goldfish_pipe_device_init()
834 dev->pipes_capacity = INITIAL_PIPES_CAPACITY; in goldfish_pipe_device_init()
835 dev->pipes = kcalloc(dev->pipes_capacity, sizeof(*dev->pipes), in goldfish_pipe_device_init()
837 if (!dev->pipes) { in goldfish_pipe_device_init()
838 misc_deregister(&dev->miscdev); in goldfish_pipe_device_init()
839 return -ENOMEM; in goldfish_pipe_device_init()
844 * signalled_pipe_buffers, to the host. This means each of those buffers in goldfish_pipe_device_init()
849 dev->buffers = (struct goldfish_pipe_dev_buffers *) in goldfish_pipe_device_init()
851 if (!dev->buffers) { in goldfish_pipe_device_init()
852 kfree(dev->pipes); in goldfish_pipe_device_init()
853 misc_deregister(&dev->miscdev); in goldfish_pipe_device_init()
854 return -ENOMEM; in goldfish_pipe_device_init()
857 /* Send the buffer addresses to the host */ in goldfish_pipe_device_init()
858 write_pa_addr(&dev->buffers->signalled_pipe_buffers, in goldfish_pipe_device_init()
859 dev->base + PIPE_REG_SIGNAL_BUFFER, in goldfish_pipe_device_init()
860 dev->base + PIPE_REG_SIGNAL_BUFFER_HIGH); in goldfish_pipe_device_init()
863 dev->base + PIPE_REG_SIGNAL_BUFFER_COUNT); in goldfish_pipe_device_init()
865 write_pa_addr(&dev->buffers->open_command_params, in goldfish_pipe_device_init()
866 dev->base + PIPE_REG_OPEN_BUFFER, in goldfish_pipe_device_init()
867 dev->base + PIPE_REG_OPEN_BUFFER_HIGH); in goldfish_pipe_device_init()
876 misc_deregister(&dev->miscdev); in goldfish_pipe_device_deinit()
877 tasklet_kill(&dev->irq_tasklet); in goldfish_pipe_device_deinit()
878 kfree(dev->pipes); in goldfish_pipe_device_deinit()
879 free_page((unsigned long)dev->buffers); in goldfish_pipe_device_deinit()
887 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); in goldfish_pipe_probe()
889 return -ENOMEM; in goldfish_pipe_probe()
891 dev->magic = &goldfish_pipe_device_deinit; in goldfish_pipe_probe()
892 spin_lock_init(&dev->lock); in goldfish_pipe_probe()
896 dev_err(&pdev->dev, "can't allocate i/o page\n"); in goldfish_pipe_probe()
897 return -EINVAL; in goldfish_pipe_probe()
899 dev->base = devm_ioremap(&pdev->dev, r->start, PAGE_SIZE); in goldfish_pipe_probe()
900 if (!dev->base) { in goldfish_pipe_probe()
901 dev_err(&pdev->dev, "ioremap failed\n"); in goldfish_pipe_probe()
902 return -EINVAL; in goldfish_pipe_probe()
907 return -EINVAL; in goldfish_pipe_probe()
909 dev->irq = r->start; in goldfish_pipe_probe()
912 * Exchange the versions with the host device in goldfish_pipe_probe()
915 * reading device version back: this allows the host implementation to in goldfish_pipe_probe()
918 writel(PIPE_DRIVER_VERSION, dev->base + PIPE_REG_VERSION); in goldfish_pipe_probe()
919 dev->version = readl(dev->base + PIPE_REG_VERSION); in goldfish_pipe_probe()
920 if (WARN_ON(dev->version < PIPE_CURRENT_DEVICE_VERSION)) in goldfish_pipe_probe()
921 return -EINVAL; in goldfish_pipe_probe()
941 { .compatible = "google,android-pipe", },