int atomisp_xnr(struct atomisp_device *isp, int flag, int *arg)
{
int xnr_enable = (*arg == 0) ? 0 : 1;
+ unsigned long irq_flag;
if (flag == 0) {
*arg = isp->params.xnr_en;
return 0;
}
+ mutex_lock(&isp->isp_lock);
+ spin_lock_irqsave(&isp->irq_lock, irq_flag);
sh_css_capture_enable_xnr(xnr_enable);
+ spin_unlock_irqrestore(&isp->irq_lock, irq_flag);
+ mutex_unlock(&isp->isp_lock);
return 0;
}
int atomisp_digital_zoom(struct atomisp_device *isp, int flag, __s32 *value)
{
int zoom, zoom_max;
+ unsigned long irq_flag;
if (isp->params.yuv_us_en && isp->main_format) {
/* If upscaling is enabled, we have to ensure minimum zoom */
/* Scale control value in reverse between CSS allowed range */
zoom = 64 - zoom;
zoom = zoom * zoom_max / 64;
+ mutex_lock(&isp->isp_lock);
+ spin_lock_irqsave(&isp->irq_lock, irq_flag);
sh_css_set_zoom_factor(zoom, zoom);
+ spin_unlock_irqrestore(&isp->irq_lock, irq_flag);
+ mutex_unlock(&isp->isp_lock);
}
return 0;
{
struct sh_css_acc_fw *fw;
int ret;
+ unsigned long irq_flag;
mutex_lock(&isp->input_lock);
mutex_lock(&isp->isp_lock);
goto out;
}
+ spin_lock_irqsave(&isp->irq_lock, irq_flag);
ret = sh_css_load_acceleration(fw);
+ spin_unlock_irqrestore(&isp->irq_lock, irq_flag);
if (ret) {
__acc_fw_free(isp, fw);
v4l2_err(&atomisp_dev, "%s: Failed to load acceleration "
enum sh_css_err
sh_css_acc_load(const struct sh_css_acc_fw *firmware)
{
+ /*
+ * moving memory alloc out of spinlock criteria.
+ * placing it in sh_css_acc_set_argument.
+ */
struct sh_css_acc_fw_hdr *header
- = (struct sh_css_acc_fw_hdr *)&firmware->header;
- header->sp_args =
- sh_css_malloc(sizeof(*header->sp_args) *
- header->sp.args_cnt);
- if (!header->sp_args)
- return sh_css_err_cannot_allocate_memory;
- header->loaded = true;
+ = (struct sh_css_acc_fw_hdr *)&firmware->header;
+ if (header->sp.args_cnt == 0)
+ header->loaded = true;
return sh_css_success;
}
header->loaded = false;
}
+static enum sh_css_err
+mem_allocation_for_sp_args(struct sh_css_acc_fw *firmware)
+{
+ struct sh_css_acc_fw_hdr *header
+ = (struct sh_css_acc_fw_hdr *)&firmware->header;
+ if (!header->loaded) {
+ if (!header->sp_args)
+ header->sp_args =
+ sh_css_malloc(sizeof(*header->sp_args) *
+ header->sp.args_cnt);
+ if (!header->sp_args)
+ return sh_css_err_cannot_allocate_memory;
+ header->loaded = true;
+ }
+ return sh_css_success;
+}
/* Set argument <num> of size <size> to value <val> */
enum sh_css_err
sh_css_acc_set_argument(struct sh_css_acc_fw *firmware,
unsigned num, void *val, size_t size)
{
+ enum sh_css_err ret;
+ ret = mem_allocation_for_sp_args(firmware);
+
+ if (ret != sh_css_success)
+ return ret;
+
if (num >= firmware->header.sp.args_cnt)
return sh_css_err_invalid_arguments;
bool is_extension = (header->type != SH_CSS_ACC_STANDALONE);
const struct sh_css_sp_fw *sp_fw = &header->sp.fw;
const unsigned char *sp_program;
+ enum sh_css_err ret;
#if !defined(C_RUN) && !defined(HRT_UNSCHED)
const unsigned char *isp_program;
#endif
*(const void **)&sp_fw->text = SH_CSS_ACC_SP_CODE(firmware);
*(const void **)&sp_fw->data = SH_CSS_ACC_SP_DATA(firmware);
- if (!header->loaded)
- return sh_css_err_invalid_arguments;
+ ret = mem_allocation_for_sp_args(firmware);
+
+ if (ret != sh_css_success)
+ return ret;
+
if (has_extension_args != is_extension)
return sh_css_err_invalid_arguments;