/* * Loopback bridge driver for the Greybus loopback module. * * Copyright 2014 Google Inc. * Copyright 2014 Linaro Ltd. * * Released under the GPLv2 only. */#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt#include<linux/kernel.h>#include<linux/module.h>#include<linux/mutex.h>#include<linux/slab.h>#include<linux/kthread.h>#include<linux/delay.h>#include<linux/random.h>#include<linux/sizes.h>#include<linux/cdev.h>#include<linux/fs.h>#include<linux/kfifo.h>#include<linux/debugfs.h>#include<linux/list_sort.h>#include<linux/spinlock.h>#include<linux/workqueue.h>#include<linux/atomic.h>#include<asm/div64.h>#include"greybus.h"#include"connection.h"#define NSEC_PER_DAY 86400000000000ULLstructgb_loopback_stats{u32min;u32max;u64sum;u32count;};structgb_loopback_device{structdentry*root;u32count;size_tsize_max;/* We need to take a lock in atomic context */spinlock_tlock;structlist_headlist;structlist_headlist_op_async;wait_queue_head_twq;};staticstructgb_loopback_devicegb_dev;structgb_loopback_async_operation{structgb_loopback*gb;structgb_operation*operation;structtimevalts;structtimer_listtimer;structlist_headentry;structwork_structwork;structkrefkref;boolpending;int(*completion)(structgb_loopback_async_operation*op_async);};structgb_loopback{structgb_connection*connection;structdentry*file;structkfifokfifo_lat;structkfifokfifo_ts;structmutexmutex;structtask_struct*task;structlist_headentry;structdevice*dev;wait_queue_head_twq;wait_queue_head_twq_completion;atomic_toutstanding_operations;/* Per connection stats */structgb_loopback_statslatency;structgb_loopback_statsthroughput;structgb_loopback_statsrequests_per_second;structgb_loopback_statsapbridge_unipro_latency;structgb_loopback_statsgpbridge_firmware_latency;inttype;intasync;intid;u32size;u32iteration_max;u32iteration_count;intus_wait;u32error;u32requests_completed;u32requests_timedout;u32timeout;u32jiffy_timeout;u32timeout_min;u32timeout_max;u32outstanding_operations_max;u32lbid;u64elapsed_nsecs;u32apbridge_latency_ts;u32gpbridge_latency_ts;};staticstructclassloopback_class={.name="gb_loopback",.owner=