+
+#define MIN_TTYB_SIZE 256
+#define TTYB_ALIGN_MASK 255
+
+/*
+ * Byte threshold to limit memory consumption for flip buffers.
+ * The actual memory limit is > 2x this amount.
+ */
+#define TTYB_MEM_LIMIT 65536
+
+/*
+ * We default to dicing tty buffer allocations to this many characters
+ * in order to avoid multiple page allocations. We know the size of
+ * tty_buffer itself but it must also be taken into account that the
+ * the buffer is 256 byte aligned. See tty_buffer_find for the allocation
+ * logic this must match
+ */
+
+#define TTY_BUFFER_PAGE (((PAGE_SIZE - sizeof(struct tty_buffer)) / 2) & ~0xFF)
+
+
+/**
+ * tty_buffer_lock_exclusive - gain exclusive access to buffer
+ * tty_buffer_unlock_exclusive - release exclusive access
+ *
+ * @port - tty_port owning the flip buffer
+ *
+ * Guarantees safe use of the line discipline's receive_buf() method by
+ * excluding the buffer work and any pending flush from using the flip
+ * buffer. Data can continue to be added concurrently to the flip buffer
+ * from the driver side.
+ *
+ * On release, the buffer work is restarted if there is data in the
+ * flip buffer
+ */
+
+void tty_buffer_lock_exclusive(struct tty_port *port)
+{
+ struct tty_bufhead *buf = &port->buf;
+
+ atomic_inc(&buf->priority);
+ mutex_lock(&buf->lock);
+}
+
+void tty_buffer_unlock_exclusive(struct tty_port *port)
+{
+ struct tty_bufhead *buf = &port->buf;
+ int restart;
+
+ restart = buf->head->commit != buf->head->read;
+
+ atomic_dec(&buf->priority);
+ mutex_unlock(&buf->lock);
+ if (restart)
+ queue_work(system_unbound_wq, &buf->work);
+}
+
+/**
+ * tty_buffer_space_avail - return unused buffer space
+ * @port - tty_port owning the flip buffer
+ *
+ * Returns the # of bytes which can be written by the driver without
+ * reaching the buffer limit.
+ *
+ * Note: this does not guarantee that memory is available to write
+ * the returned # of bytes (use tty_prepare_flip_string_xxx() to
+ * pre-allocate if memory guarantee is required).
+ */
+
+int tty_buffer_space_avail(struct tty_port *port)
+{
+ int space = TTYB_MEM_LIMIT - atomic_read(&port->buf.memory_used);
+ return max(space, 0);
+}
+
+static void tty_buffer_reset(struct tty_buffer *p, size_t size)
+{
+ p->used = 0;
+ p->size = size;
+ p->next = NULL;
+ p->commit = 0;
+ p->read = 0;
+}
+