Commit 073b2435 authored by Oleg Dzhimiev's avatar Oleg Dzhimiev

added spinlock

parent ea1834cd
...@@ -1574,7 +1574,7 @@ int setFramePars(int sensor_port, ///< sensor port number (0 ...@@ -1574,7 +1574,7 @@ int setFramePars(int sensor_port, ///< sensor port number (0
* @param frame_num target frame * @param frame_num target frame
* @return 0 * @return 0
*/ */
int waitFrame(int sensor_port, int frame_num){ int waitFrame(int sensor_port, unsigned long frame_num){
wait_event_interruptible(aframepars_wait_queue[sensor_port], getThisFrameNumber(sensor_port) >= frame_num); wait_event_interruptible(aframepars_wait_queue[sensor_port], getThisFrameNumber(sensor_port) >= frame_num);
return 0; return 0;
} }
......
...@@ -39,7 +39,7 @@ void updateFramePars (int sensor_port, int frame16); ...@@ -39,7 +39,7 @@ void updateFramePars (int sensor_port, int frame16);
int setFrameParStatic (int sensor_port, unsigned long index, unsigned long val); int setFrameParStatic (int sensor_port, unsigned long index, unsigned long val);
int setFrameParsStatic (int sensor_port, int numPars, struct frameparspair_t * pars); int setFrameParsStatic (int sensor_port, int numPars, struct frameparspair_t * pars);
int waitFrame(int sensor_port, int frame_num); int waitFrame(int sensor_port, unsigned long frame_num);
unsigned long getThisFrameNumber (int sensor_port); /// just return current thisFrameNumber unsigned long getThisFrameNumber (int sensor_port); /// just return current thisFrameNumber
/// set parameters for the frame number frameno, knowing that they should be set not less than maxLatency ahead (may be sensor - dependent) /// set parameters for the frame number frameno, knowing that they should be set not less than maxLatency ahead (may be sensor - dependent)
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/fs.h> #include <linux/fs.h>
//#include <linux/spinlock.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -33,6 +34,7 @@ ...@@ -33,6 +34,7 @@
#include "pgm_functions.h" #include "pgm_functions.h"
#include "x393_videomem.h" #include "x393_videomem.h"
#include "x393_fpga_functions.h" #include "x393_fpga_functions.h"
#include "framepars.h"
#include <uapi/elphel/c313a.h> #include <uapi/elphel/c313a.h>
#include <uapi/elphel/x393_devices.h> #include <uapi/elphel/x393_devices.h>
...@@ -63,8 +65,11 @@ ...@@ -63,8 +65,11 @@
static const struct of_device_id elphel393_videomem_of_match[]; static const struct of_device_id elphel393_videomem_of_match[];
static struct device *g_dev_ptr; ///< Global pointer to basic device structure. This pointer is used in debugfs output functions static struct device *g_dev_ptr; ///< Global pointer to basic device structure. This pointer is used in debugfs output functions
wait_queue_head_t videomem_wait_queue; wait_queue_head_t videomem_wait_queue;
static DEFINE_SPINLOCK(lock); // for read-modify-write channel enable
static DEFINE_SPINLOCK(lock); ///< for read-modify-write channel enable
static DEFINE_SPINLOCK(membridge_lock); ///< to lock membridge, unlock on membridge_done interrupt
/** /**
* VIDEOMEM_RAW & IMAGE_RAW are for debug memory access. * VIDEOMEM_RAW & IMAGE_RAW are for debug memory access.
...@@ -688,6 +693,12 @@ int membridge_start(struct file * file){ ...@@ -688,6 +693,12 @@ int membridge_start(struct file * file){
int width_marg, height_marg, width_bursts; int width_marg, height_marg, width_bursts;
int frame_number; int frame_number;
x393_status_membridge_t status = x393_membridge_status();
if (status.busy) {
return -EBUSY;
}
// no need // no need
frame_number = GLOBALPARS(privData->sensor_num,G_THIS_FRAME) & PARS_FRAMES_MASK; frame_number = GLOBALPARS(privData->sensor_num,G_THIS_FRAME) & PARS_FRAMES_MASK;
...@@ -737,6 +748,12 @@ int membridge_start(struct file * file){ ...@@ -737,6 +748,12 @@ int membridge_start(struct file * file){
control_membridge_memory(membridge_sensor_port,1,DIRECT,frame_number); control_membridge_memory(membridge_sensor_port,1,DIRECT,frame_number);
// timeout exit?
while(true){
status = x393_membridge_status();
if (!status.busy) break;
}
//NOTES: //NOTES:
//// get this frame number //// get this frame number
...@@ -816,7 +833,7 @@ ssize_t vm_read(struct file *file, char *buf, size_t count, loff_t *off) ...@@ -816,7 +833,7 @@ ssize_t vm_read(struct file *file, char *buf, size_t count, loff_t *off)
//static int videomem_release (struct inode *inode, struct file *filp) {return 0;} //static int videomem_release (struct inode *inode, struct file *filp) {return 0;}
//static loff_t videomem_lseek (struct file * file, loff_t offset, int orig) {return 0;} //static loff_t videomem_lseek (struct file * file, loff_t offset, int orig) {return 0;}
//static ssize_t videomem_read (struct file * file, char * buf, size_t count, loff_t *off) {return 0;} //static ssize_t videomem_read (struct file * file, char * buf, size_t count, loff_t *off) {return 0;}
static ssize_t videomem_write (struct file * file, const char * buf, size_t count, loff_t *off) {return 0;} ssize_t videomem_write (struct file * file, const char * buf, size_t count, loff_t *off) {return 0;}
/** /**
* @brief Driver LSEEK method (and execute commands) * @brief Driver LSEEK method (and execute commands)
...@@ -831,15 +848,15 @@ static ssize_t videomem_write (struct file * file, const char * buf, size_t co ...@@ -831,15 +848,15 @@ static ssize_t videomem_write (struct file * file, const char * buf, size_t co
* @param orig SEEK_SET, SEEK_CUR or SEEK_SET END * @param orig SEEK_SET, SEEK_CUR or SEEK_SET END
* @return file position (absolute frame number) * @return file position (absolute frame number)
*/ */
static loff_t videomem_lseek(struct file * file, loff_t offset, int orig){ loff_t videomem_lseek(struct file * file, loff_t offset, int orig){
FLAGS_IBH;
unsigned long target_frame; unsigned long target_frame;
struct raw_priv_t * privData = (struct raw_priv_t*) file -> private_data; struct raw_priv_t * privData = (struct raw_priv_t*) file -> private_data;
int sensor_port = privData->sensor_num; int sensor_port = privData->sensor_num;
//sec_usec_t sec_usec; //sec_usec_t sec_usec;
int res; int res;
pr_debug("(videomem_lseek) offset=0x%x, orig=0x%x, sensor_port = %d\n", (int)offset, (int)orig, sensor_port); pr_debug("(videomem_lseek) offset=0x%x, orig=0x%x, sensor_port = %d\n", (int)offset, (int)orig, sensor_port);
switch (orig) { switch (orig) {
case SEEK_SET: case SEEK_SET:
...@@ -850,15 +867,38 @@ static loff_t videomem_lseek(struct file * file, loff_t offset, int orig){ ...@@ -850,15 +867,38 @@ static loff_t videomem_lseek(struct file * file, loff_t offset, int orig){
file->f_pos = getThisFrameNumber(sensor_port) + offset; // modifies frame number, but it is better to use absolute SEEK SET file->f_pos = getThisFrameNumber(sensor_port) + offset; // modifies frame number, but it is better to use absolute SEEK SET
break; break;
case SEEK_END: case SEEK_END:
if (offset <= 0) { if (offset <= 0) {
// ?
file->f_pos = privData->buf_size + offset; file->f_pos = privData->buf_size + offset;
break;
} else { } else {
// wait for a frame here (1 action at a time)
if (offset >= LSEEK_FRAME_WAIT_REL) {
if (offset >= LSEEK_FRAME_WAIT_ABS){
target_frame = offset - LSEEK_FRAME_WAIT_ABS; // Wait for absolute frame number
}else{
target_frame = getThisFrameNumber(sensor_port) + offset - LSEEK_FRAME_WAIT_REL;
}
pr_debug("(videomem_lseek) waiting for frame: %d\n",target_frame);
// wait for frame then continue
waitFrame(sensor_port,target_frame);
return getThisFrameNumber(sensor_port);
}
// setup and run copying through membridge (1 action at a time)
switch (offset) { switch (offset) {
case LSEEK_VIDEOMEM_START: case LSEEK_VIDEOMEM_START:
// Check lock here: // Check lock here:
membridge_start(file); LOCK_IBH(&membridge_lock);
res = membridge_start(file);
UNLOCK_IBH(&membridge_lock);
if (res<0) return res;
break; break;
} }
} }
break; break;
default: default:
...@@ -876,7 +916,7 @@ static loff_t videomem_lseek(struct file * file, loff_t offset, int orig){ ...@@ -876,7 +916,7 @@ static loff_t videomem_lseek(struct file * file, loff_t offset, int orig){
* @param[in] filp * @param[in] filp
* @return Always 0. * @return Always 0.
*/ */
static int videomem_open(struct inode *inode, struct file *filp) int videomem_open(struct inode *inode, struct file *filp)
{ {
struct raw_priv_t *privData; struct raw_priv_t *privData;
...@@ -958,7 +998,7 @@ static int videomem_open(struct inode *inode, struct file *filp) ...@@ -958,7 +998,7 @@ static int videomem_open(struct inode *inode, struct file *filp)
* @param[in] filp * @param[in] filp
* @return 0 * @return 0
*/ */
static int videomem_release(struct inode *inode, struct file *filp) int videomem_release(struct inode *inode, struct file *filp)
{ {
pr_debug("VIDEOMEM_RELEASE\n"); pr_debug("VIDEOMEM_RELEASE\n");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment