2019-05-27 14:55:06 +08:00
// SPDX-License-Identifier: GPL-2.0-or-later
2008-04-29 07:24:33 +08:00
/*
* cx18 mailbox functions
*
* Copyright ( C ) 2007 Hans Verkuil < hverkuil @ xs4all . nl >
2010-05-24 05:53:35 +08:00
* Copyright ( C ) 2008 Andy Walls < awalls @ md . metrocast . net >
2008-04-29 07:24:33 +08:00
*/
2019-08-22 21:24:12 +08:00
# include <linux/bitops.h>
2008-04-29 07:24:33 +08:00
# include "cx18-driver.h"
2008-08-31 03:03:44 +08:00
# include "cx18-io.h"
2008-04-29 07:24:33 +08:00
# include "cx18-scb.h"
# include "cx18-irq.h"
# include "cx18-mailbox.h"
2008-11-16 12:38:19 +08:00
# include "cx18-queue.h"
# include "cx18-streams.h"
2010-01-19 08:29:51 +08:00
# include "cx18-alsa-pcm.h" /* FIXME make configurable */
2008-11-16 12:38:19 +08:00
static const char * rpu_str [ ] = { " APU " , " CPU " , " EPU " , " HPU " } ;
2008-04-29 07:24:33 +08:00
# define API_FAST (1 << 2) /* Short timeout */
# define API_SLOW (1 << 3) /* Additional 300ms timeout */
struct cx18_api_info {
u32 cmd ;
u8 flags ; /* Flags, see above */
u8 rpu ; /* Processing unit */
2018-01-05 02:08:56 +08:00
const char * name ; /* The name of the command */
2008-04-29 07:24:33 +08:00
} ;
# define API_ENTRY(rpu, x, f) { (x), (f), (rpu), #x }
static const struct cx18_api_info api_info [ ] = {
/* MPEG encoder API */
API_ENTRY ( CPU , CX18_CPU_SET_CHANNEL_TYPE , 0 ) ,
2018-01-05 02:08:56 +08:00
API_ENTRY ( CPU , CX18_EPU_DEBUG , 0 ) ,
API_ENTRY ( CPU , CX18_CREATE_TASK , 0 ) ,
API_ENTRY ( CPU , CX18_DESTROY_TASK , 0 ) ,
2008-04-29 07:24:33 +08:00
API_ENTRY ( CPU , CX18_CPU_CAPTURE_START , API_SLOW ) ,
API_ENTRY ( CPU , CX18_CPU_CAPTURE_STOP , API_SLOW ) ,
API_ENTRY ( CPU , CX18_CPU_CAPTURE_PAUSE , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_CAPTURE_RESUME , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_CHANNEL_TYPE , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_STREAM_OUTPUT_TYPE , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_VIDEO_IN , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_VIDEO_RATE , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_VIDEO_RESOLUTION , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_FILTER_PARAM , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_SPATIAL_FILTER_TYPE , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_MEDIAN_CORING , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_INDEXTABLE , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_AUDIO_PARAMETERS , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_VIDEO_MUTE , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_AUDIO_MUTE , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_MISC_PARAMETERS , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_RAW_VBI_PARAM , API_SLOW ) ,
API_ENTRY ( CPU , CX18_CPU_SET_CAPTURE_LINE_NO , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_COPYRIGHT , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_AUDIO_PID , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_VIDEO_PID , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_VER_CROP_LINE , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_GOP_STRUCTURE , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_SCENE_CHANGE_DETECTION , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_ASPECT_RATIO , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_SKIP_INPUT_FRAME , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_SLICED_VBI_PARAM , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_SET_USERDATA_PLACE_HOLDER , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_GET_ENC_PTS , 0 ) ,
2011-04-06 19:32:56 +08:00
API_ENTRY ( CPU , CX18_CPU_SET_VFC_PARAM , 0 ) ,
2008-04-29 07:24:33 +08:00
API_ENTRY ( CPU , CX18_CPU_DE_SET_MDL_ACK , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_DE_SET_MDL , API_FAST ) ,
2008-11-01 12:07:36 +08:00
API_ENTRY ( CPU , CX18_CPU_DE_RELEASE_MDL , API_SLOW ) ,
2009-01-05 08:51:17 +08:00
API_ENTRY ( APU , CX18_APU_START , 0 ) ,
API_ENTRY ( APU , CX18_APU_STOP , 0 ) ,
2008-12-15 08:26:25 +08:00
API_ENTRY ( APU , CX18_APU_RESETAI , 0 ) ,
API_ENTRY ( CPU , CX18_CPU_DEBUG_PEEK32 , 0 ) ,
2008-04-29 07:24:33 +08:00
API_ENTRY ( 0 , 0 , 0 ) ,
} ;
static const struct cx18_api_info * find_api_info ( u32 cmd )
{
int i ;
for ( i = 0 ; api_info [ i ] . cmd ; i + + )
if ( api_info [ i ] . cmd = = cmd )
return & api_info [ i ] ;
return NULL ;
}
2009-01-01 23:35:06 +08:00
/* Call with buf of n*11+1 bytes */
static char * u32arr2hex ( u32 data [ ] , int n , char * buf )
2008-11-16 12:38:19 +08:00
{
char * p ;
int i ;
2009-01-01 23:35:06 +08:00
for ( i = 0 , p = buf ; i < n ; i + + , p + = 11 ) {
/* kernel snprintf() appends '\0' always */
snprintf ( p , 12 , " %#010x " , data [ i ] ) ;
}
* p = ' \0 ' ;
return buf ;
}
static void dump_mb ( struct cx18 * cx , struct cx18_mailbox * mb , char * name )
{
char argstr [ MAX_MB_ARGUMENTS * 11 + 1 ] ;
2008-11-16 12:38:19 +08:00
if ( ! ( cx18_debug & CX18_DBGFLG_API ) )
return ;
[media] cx18: don't break long lines
Due to the 80-cols restrictions, and latter due to checkpatch
warnings, several strings were broken into multiple lines. This
is not considered a good practice anymore, as it makes harder
to grep for strings at the source code.
As we're right now fixing other drivers due to KERN_CONT, we need
to be able to identify what printk strings don't end with a "\n".
It is a way easier to detect those if we don't break long lines.
So, join those continuation lines.
The patch was generated via the script below, and manually
adjusted if needed.
</script>
use Text::Tabs;
while (<>) {
if ($next ne "") {
$c=$_;
if ($c =~ /^\s+\"(.*)/) {
$c2=$1;
$next =~ s/\"\n$//;
$n = expand($next);
$funpos = index($n, '(');
$pos = index($c2, '",');
if ($funpos && $pos > 0) {
$s1 = substr $c2, 0, $pos + 2;
$s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2;
$s2 =~ s/^\s+//;
$s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne "");
print unexpand("$next$s1\n");
print unexpand("$s2\n") if ($s2 ne "");
} else {
print "$next$c2\n";
}
$next="";
next;
} else {
print $next;
}
$next="";
} else {
if (m/\"$/) {
if (!m/\\n\"$/) {
$next=$_;
next;
}
}
}
print $_;
}
</script>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-10-19 03:44:03 +08:00
CX18_DEBUG_API ( " %s: req %#010x ack %#010x cmd %#010x err %#010x args%s \n " ,
name , mb - > request , mb - > ack , mb - > cmd , mb - > error ,
2009-01-01 23:35:06 +08:00
u32arr2hex ( mb - > args , MAX_MB_ARGUMENTS , argstr ) ) ;
2008-11-16 12:38:19 +08:00
}
/*
* Functions that run in a work_queue work handling context
*/
2009-11-09 10:45:24 +08:00
static void cx18_mdl_send_to_dvb ( struct cx18_stream * s , struct cx18_mdl * mdl )
{
struct cx18_buffer * buf ;
2010-12-12 07:38:20 +08:00
if ( s - > dvb = = NULL | | ! s - > dvb - > enabled | | mdl - > bytesused = = 0 )
2009-11-09 10:45:24 +08:00
return ;
/* We ignore mdl and buf readpos accounting here - it doesn't matter */
/* The likely case */
if ( list_is_singular ( & mdl - > buf_list ) ) {
buf = list_first_entry ( & mdl - > buf_list , struct cx18_buffer ,
list ) ;
if ( buf - > bytesused )
2010-12-12 07:38:20 +08:00
dvb_dmx_swfilter ( & s - > dvb - > demux ,
2009-11-09 10:45:24 +08:00
buf - > buf , buf - > bytesused ) ;
return ;
}
list_for_each_entry ( buf , & mdl - > buf_list , list ) {
if ( buf - > bytesused = = 0 )
break ;
2010-12-12 07:38:20 +08:00
dvb_dmx_swfilter ( & s - > dvb - > demux , buf - > buf , buf - > bytesused ) ;
2009-11-09 10:45:24 +08:00
}
}
2011-04-06 19:32:56 +08:00
static void cx18_mdl_send_to_videobuf ( struct cx18_stream * s ,
struct cx18_mdl * mdl )
{
struct cx18_videobuf_buffer * vb_buf ;
struct cx18_buffer * buf ;
2011-05-05 20:42:36 +08:00
u8 * p ;
2011-04-06 19:32:56 +08:00
u32 offset = 0 ;
int dispatch = 0 ;
if ( mdl - > bytesused = = 0 )
return ;
/* Acquire a videobuf buffer, clone to and and release it */
spin_lock ( & s - > vb_lock ) ;
if ( list_empty ( & s - > vb_capture ) )
goto out ;
2011-05-03 19:57:40 +08:00
vb_buf = list_first_entry ( & s - > vb_capture , struct cx18_videobuf_buffer ,
2011-04-06 19:32:56 +08:00
vb . queue ) ;
p = videobuf_to_vmalloc ( & vb_buf - > vb ) ;
if ( ! p )
goto out ;
offset = vb_buf - > bytes_used ;
list_for_each_entry ( buf , & mdl - > buf_list , list ) {
if ( buf - > bytesused = = 0 )
break ;
if ( ( offset + buf - > bytesused ) < = vb_buf - > vb . bsize ) {
memcpy ( p + offset , buf - > buf , buf - > bytesused ) ;
offset + = buf - > bytesused ;
vb_buf - > bytes_used + = buf - > bytesused ;
}
}
/* If we've filled the buffer as per the callers res then dispatch it */
2011-09-05 23:23:12 +08:00
if ( vb_buf - > bytes_used > = s - > vb_bytes_per_frame ) {
2011-04-06 19:32:56 +08:00
dispatch = 1 ;
vb_buf - > bytes_used = 0 ;
}
if ( dispatch ) {
2019-01-21 21:32:23 +08:00
vb_buf - > vb . ts = ktime_get_ns ( ) ;
2011-04-06 19:32:56 +08:00
list_del ( & vb_buf - > vb . queue ) ;
vb_buf - > vb . state = VIDEOBUF_DONE ;
wake_up ( & vb_buf - > vb . done ) ;
}
2011-05-03 19:57:40 +08:00
mod_timer ( & s - > vb_timeout , msecs_to_jiffies ( 2000 ) + jiffies ) ;
2011-04-06 19:32:56 +08:00
out :
spin_unlock ( & s - > vb_lock ) ;
}
2010-01-19 08:29:51 +08:00
static void cx18_mdl_send_to_alsa ( struct cx18 * cx , struct cx18_stream * s ,
struct cx18_mdl * mdl )
{
struct cx18_buffer * buf ;
if ( mdl - > bytesused = = 0 )
return ;
/* We ignore mdl and buf readpos accounting here - it doesn't matter */
/* The likely case */
if ( list_is_singular ( & mdl - > buf_list ) ) {
buf = list_first_entry ( & mdl - > buf_list , struct cx18_buffer ,
list ) ;
if ( buf - > bytesused )
cx - > pcm_announce_callback ( cx - > alsa , buf - > buf ,
buf - > bytesused ) ;
return ;
}
list_for_each_entry ( buf , & mdl - > buf_list , list ) {
if ( buf - > bytesused = = 0 )
break ;
cx - > pcm_announce_callback ( cx - > alsa , buf - > buf , buf - > bytesused ) ;
}
}
2009-04-14 09:22:40 +08:00
static void epu_dma_done ( struct cx18 * cx , struct cx18_in_work_order * order )
2008-11-16 12:38:19 +08:00
{
2008-11-19 12:24:33 +08:00
u32 handle , mdl_ack_count , id ;
2008-11-16 12:38:19 +08:00
struct cx18_mailbox * mb ;
struct cx18_mdl_ack * mdl_ack ;
struct cx18_stream * s ;
2009-11-09 10:45:24 +08:00
struct cx18_mdl * mdl ;
2008-11-16 12:38:19 +08:00
int i ;
mb = & order - > mb ;
handle = mb - > args [ 0 ] ;
s = cx18_handle_to_stream ( cx , handle ) ;
if ( s = = NULL ) {
[media] cx18: don't break long lines
Due to the 80-cols restrictions, and latter due to checkpatch
warnings, several strings were broken into multiple lines. This
is not considered a good practice anymore, as it makes harder
to grep for strings at the source code.
As we're right now fixing other drivers due to KERN_CONT, we need
to be able to identify what printk strings don't end with a "\n".
It is a way easier to detect those if we don't break long lines.
So, join those continuation lines.
The patch was generated via the script below, and manually
adjusted if needed.
</script>
use Text::Tabs;
while (<>) {
if ($next ne "") {
$c=$_;
if ($c =~ /^\s+\"(.*)/) {
$c2=$1;
$next =~ s/\"\n$//;
$n = expand($next);
$funpos = index($n, '(');
$pos = index($c2, '",');
if ($funpos && $pos > 0) {
$s1 = substr $c2, 0, $pos + 2;
$s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2;
$s2 =~ s/^\s+//;
$s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne "");
print unexpand("$next$s1\n");
print unexpand("$s2\n") if ($s2 ne "");
} else {
print "$next$c2\n";
}
$next="";
next;
} else {
print $next;
}
$next="";
} else {
if (m/\"$/) {
if (!m/\\n\"$/) {
$next=$_;
next;
}
}
}
print $_;
}
</script>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-10-19 03:44:03 +08:00
CX18_WARN ( " Got DMA done notification for unknown/inactive handle %d, %s mailbox seq no %d \n " ,
handle ,
2008-11-19 12:24:33 +08:00
( order - > flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT ) ?
" stale " : " good " , mb - > request ) ;
2008-11-16 12:38:19 +08:00
return ;
}
mdl_ack_count = mb - > args [ 2 ] ;
mdl_ack = order - > mdl_ack ;
for ( i = 0 ; i < mdl_ack_count ; i + + , mdl_ack + + ) {
2008-11-19 12:24:33 +08:00
id = mdl_ack - > id ;
/*
* Simple integrity check for processing a stale ( and possibly
2009-11-09 10:45:24 +08:00
* inconsistent mailbox ) : make sure the MDL id is in the
2008-11-19 12:24:33 +08:00
* valid range for the stream .
*
* We go through the trouble of dealing with stale mailboxes
* because most of the time , the mailbox data is still valid and
* unchanged ( and in practice the firmware ping - pongs the
* two mdl_ack buffers so mdl_acks are not stale ) .
*
* There are occasions when we get a half changed mailbox ,
* which this check catches for a handle & id mismatch . If the
* handle and id do correspond , the worst case is that we
2009-11-09 10:45:24 +08:00
* completely lost the old MDL , but pick up the new MDL
2008-11-19 12:24:33 +08:00
* early ( but the new mdl_ack is guaranteed to be good in this
* case as the firmware wouldn ' t point us to a new mdl_ack until
* it ' s filled in ) .
*
2009-11-09 10:45:24 +08:00
* cx18_queue_get_mdl ( ) will detect the lost MDLs
2008-12-13 02:50:27 +08:00
* and send them back to q_free for fw rotation eventually .
2008-11-19 12:24:33 +08:00
*/
if ( ( order - > flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT ) & &
2009-11-06 08:51:24 +08:00
! ( id > = s - > mdl_base_idx & &
id < ( s - > mdl_base_idx + s - > buffers ) ) ) {
[media] cx18: don't break long lines
Due to the 80-cols restrictions, and latter due to checkpatch
warnings, several strings were broken into multiple lines. This
is not considered a good practice anymore, as it makes harder
to grep for strings at the source code.
As we're right now fixing other drivers due to KERN_CONT, we need
to be able to identify what printk strings don't end with a "\n".
It is a way easier to detect those if we don't break long lines.
So, join those continuation lines.
The patch was generated via the script below, and manually
adjusted if needed.
</script>
use Text::Tabs;
while (<>) {
if ($next ne "") {
$c=$_;
if ($c =~ /^\s+\"(.*)/) {
$c2=$1;
$next =~ s/\"\n$//;
$n = expand($next);
$funpos = index($n, '(');
$pos = index($c2, '",');
if ($funpos && $pos > 0) {
$s1 = substr $c2, 0, $pos + 2;
$s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2;
$s2 =~ s/^\s+//;
$s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne "");
print unexpand("$next$s1\n");
print unexpand("$s2\n") if ($s2 ne "");
} else {
print "$next$c2\n";
}
$next="";
next;
} else {
print $next;
}
$next="";
} else {
if (m/\"$/) {
if (!m/\\n\"$/) {
$next=$_;
next;
}
}
}
print $_;
}
</script>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-10-19 03:44:03 +08:00
CX18_WARN ( " Fell behind! Ignoring stale mailbox with inconsistent data. Lost MDL for mailbox seq no %d \n " ,
mb - > request ) ;
2008-11-19 12:24:33 +08:00
break ;
}
2009-11-09 10:45:24 +08:00
mdl = cx18_queue_get_mdl ( s , id , mdl_ack - > data_used ) ;
2008-12-13 02:50:27 +08:00
2009-11-09 10:45:24 +08:00
CX18_DEBUG_HI_DMA ( " DMA DONE for %s (MDL %d) \n " , s - > name , id ) ;
if ( mdl = = NULL ) {
CX18_WARN ( " Could not find MDL %d for stream %s \n " ,
2008-11-19 12:24:33 +08:00
id , s - > name ) ;
2008-11-16 12:38:19 +08:00
continue ;
}
2009-04-14 10:08:00 +08:00
CX18_DEBUG_HI_DMA ( " %s recv bytesused = %d \n " ,
2009-11-09 10:45:24 +08:00
s - > name , mdl - > bytesused ) ;
2009-04-14 10:08:00 +08:00
2010-01-19 08:29:51 +08:00
if ( s - > type = = CX18_ENC_STREAM_TYPE_TS ) {
cx18_mdl_send_to_dvb ( s , mdl ) ;
cx18_enqueue ( s , mdl , & s - > q_free ) ;
} else if ( s - > type = = CX18_ENC_STREAM_TYPE_PCM ) {
/* Pass the data to cx18-alsa */
if ( cx - > pcm_announce_callback ! = NULL ) {
cx18_mdl_send_to_alsa ( cx , s , mdl ) ;
cx18_enqueue ( s , mdl , & s - > q_free ) ;
} else {
cx18_enqueue ( s , mdl , & s - > q_full ) ;
}
2011-04-06 19:32:56 +08:00
} else if ( s - > type = = CX18_ENC_STREAM_TYPE_YUV ) {
cx18_mdl_send_to_videobuf ( s , mdl ) ;
cx18_enqueue ( s , mdl , & s - > q_free ) ;
2010-01-19 08:29:51 +08:00
} else {
2009-11-09 10:45:24 +08:00
cx18_enqueue ( s , mdl , & s - > q_full ) ;
2010-01-01 05:27:13 +08:00
if ( s - > type = = CX18_ENC_STREAM_TYPE_IDX )
cx18_stream_rotate_idx_mdls ( cx ) ;
}
2008-11-16 12:38:19 +08:00
}
2009-11-09 10:45:24 +08:00
/* Put as many MDLs as possible back into fw use */
2009-04-14 10:08:00 +08:00
cx18_stream_load_fw_queue ( s ) ;
2008-11-16 12:38:19 +08:00
wake_up ( & cx - > dma_waitq ) ;
if ( s - > id ! = - 1 )
wake_up ( & s - > waitq ) ;
}
2009-04-14 09:22:40 +08:00
static void epu_debug ( struct cx18 * cx , struct cx18_in_work_order * order )
2008-11-16 12:38:19 +08:00
{
char * p ;
char * str = order - > str ;
CX18_DEBUG_INFO ( " %x %s \n " , order - > mb . args [ 0 ] , str ) ;
p = strchr ( str , ' . ' ) ;
if ( ! test_bit ( CX18_F_I_LOADED_FW , & cx - > i_flags ) & & p & & p > str )
CX18_INFO ( " FW version: %s \n " , p - 1 ) ;
}
2009-04-14 09:22:40 +08:00
static void epu_cmd ( struct cx18 * cx , struct cx18_in_work_order * order )
2008-11-16 12:38:19 +08:00
{
switch ( order - > rpu ) {
case CPU :
{
switch ( order - > mb . cmd ) {
case CX18_EPU_DMA_DONE :
epu_dma_done ( cx , order ) ;
break ;
case CX18_EPU_DEBUG :
epu_debug ( cx , order ) ;
break ;
default :
CX18_WARN ( " Unknown CPU to EPU mailbox command %#0x \n " ,
order - > mb . cmd ) ;
break ;
}
break ;
}
case APU :
CX18_WARN ( " Unknown APU to EPU mailbox command %#0x \n " ,
order - > mb . cmd ) ;
break ;
default :
break ;
}
}
static
2009-04-14 09:22:40 +08:00
void free_in_work_order ( struct cx18 * cx , struct cx18_in_work_order * order )
2008-11-16 12:38:19 +08:00
{
atomic_set ( & order - > pending , 0 ) ;
}
2009-04-14 09:22:40 +08:00
void cx18_in_work_handler ( struct work_struct * work )
2008-11-16 12:38:19 +08:00
{
2009-04-14 09:22:40 +08:00
struct cx18_in_work_order * order =
container_of ( work , struct cx18_in_work_order , work ) ;
2008-11-16 12:38:19 +08:00
struct cx18 * cx = order - > cx ;
epu_cmd ( cx , order ) ;
2009-04-14 09:22:40 +08:00
free_in_work_order ( cx , order ) ;
2008-11-16 12:38:19 +08:00
}
/*
* Functions that run in an interrupt handling context
*/
2009-04-14 09:22:40 +08:00
static void mb_ack_irq ( struct cx18 * cx , struct cx18_in_work_order * order )
2008-04-29 07:24:33 +08:00
{
2008-05-21 11:32:01 +08:00
struct cx18_mailbox __iomem * ack_mb ;
2008-11-16 12:38:19 +08:00
u32 ack_irq , req ;
2008-04-29 07:24:33 +08:00
2008-11-16 12:38:19 +08:00
switch ( order - > rpu ) {
2008-04-29 07:24:33 +08:00
case APU :
ack_irq = IRQ_EPU_TO_APU_ACK ;
ack_mb = & cx - > scb - > apu2epu_mb ;
break ;
case CPU :
ack_irq = IRQ_EPU_TO_CPU_ACK ;
ack_mb = & cx - > scb - > cpu2epu_mb ;
break ;
default :
2008-11-06 12:15:41 +08:00
CX18_WARN ( " Unhandled RPU (%d) for command %x ack \n " ,
2008-11-16 12:38:19 +08:00
order - > rpu , order - > mb . cmd ) ;
return ;
2008-04-29 07:24:33 +08:00
}
2008-11-16 12:38:19 +08:00
req = order - > mb . request ;
/* Don't ack if the RPU has gotten impatient and timed us out */
if ( req ! = cx18_readl ( cx , & ack_mb - > request ) | |
2008-11-17 08:18:00 +08:00
req = = cx18_readl ( cx , & ack_mb - > ack ) ) {
[media] cx18: don't break long lines
Due to the 80-cols restrictions, and latter due to checkpatch
warnings, several strings were broken into multiple lines. This
is not considered a good practice anymore, as it makes harder
to grep for strings at the source code.
As we're right now fixing other drivers due to KERN_CONT, we need
to be able to identify what printk strings don't end with a "\n".
It is a way easier to detect those if we don't break long lines.
So, join those continuation lines.
The patch was generated via the script below, and manually
adjusted if needed.
</script>
use Text::Tabs;
while (<>) {
if ($next ne "") {
$c=$_;
if ($c =~ /^\s+\"(.*)/) {
$c2=$1;
$next =~ s/\"\n$//;
$n = expand($next);
$funpos = index($n, '(');
$pos = index($c2, '",');
if ($funpos && $pos > 0) {
$s1 = substr $c2, 0, $pos + 2;
$s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2;
$s2 =~ s/^\s+//;
$s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne "");
print unexpand("$next$s1\n");
print unexpand("$s2\n") if ($s2 ne "");
} else {
print "$next$c2\n";
}
$next="";
next;
} else {
print $next;
}
$next="";
} else {
if (m/\"$/) {
if (!m/\\n\"$/) {
$next=$_;
next;
}
}
}
print $_;
}
</script>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-10-19 03:44:03 +08:00
CX18_DEBUG_WARN ( " Possibly falling behind: %s self-ack'ed our incoming %s to EPU mailbox (sequence no. %u) while processing \n " ,
2008-11-19 12:24:33 +08:00
rpu_str [ order - > rpu ] , rpu_str [ order - > rpu ] , req ) ;
2008-11-17 08:18:00 +08:00
order - > flags | = CX18_F_EWO_MB_STALE_WHILE_PROC ;
2008-11-16 12:38:19 +08:00
return ;
2008-11-17 08:18:00 +08:00
}
2008-11-16 12:38:19 +08:00
cx18_writel ( cx , req , & ack_mb - > ack ) ;
2008-11-01 07:49:12 +08:00
cx18_write_reg_expect ( cx , ack_irq , SW2_INT_SET , ack_irq , ack_irq ) ;
2008-11-16 12:38:19 +08:00
return ;
}
2009-04-14 09:22:40 +08:00
static int epu_dma_done_irq ( struct cx18 * cx , struct cx18_in_work_order * order )
2008-11-16 12:38:19 +08:00
{
u32 handle , mdl_ack_offset , mdl_ack_count ;
struct cx18_mailbox * mb ;
2012-05-26 19:07:03 +08:00
int i ;
2008-11-16 12:38:19 +08:00
mb = & order - > mb ;
handle = mb - > args [ 0 ] ;
mdl_ack_offset = mb - > args [ 1 ] ;
mdl_ack_count = mb - > args [ 2 ] ;
if ( handle = = CX18_INVALID_TASK_HANDLE | |
mdl_ack_count = = 0 | | mdl_ack_count > CX18_MAX_MDL_ACKS ) {
2008-11-17 08:18:00 +08:00
if ( ( order - > flags & CX18_F_EWO_MB_STALE ) = = 0 )
2008-11-16 12:38:19 +08:00
mb_ack_irq ( cx , order ) ;
return - 1 ;
}
2012-05-26 19:07:03 +08:00
for ( i = 0 ; i < sizeof ( struct cx18_mdl_ack ) * mdl_ack_count ; i + = sizeof ( u32 ) )
( ( u32 * ) order - > mdl_ack ) [ i / sizeof ( u32 ) ] =
cx18_readl ( cx , cx - > enc_mem + mdl_ack_offset + i ) ;
2008-11-17 08:18:00 +08:00
if ( ( order - > flags & CX18_F_EWO_MB_STALE ) = = 0 )
2008-11-16 12:38:19 +08:00
mb_ack_irq ( cx , order ) ;
return 1 ;
}
static
2009-04-14 09:22:40 +08:00
int epu_debug_irq ( struct cx18 * cx , struct cx18_in_work_order * order )
2008-11-16 12:38:19 +08:00
{
u32 str_offset ;
char * str = order - > str ;
str [ 0 ] = ' \0 ' ;
str_offset = order - > mb . args [ 1 ] ;
if ( str_offset ) {
cx18_setup_page ( cx , str_offset ) ;
cx18_memcpy_fromio ( cx , str , cx - > enc_mem + str_offset , 252 ) ;
str [ 252 ] = ' \0 ' ;
cx18_setup_page ( cx , SCB_OFFSET ) ;
}
2008-11-17 08:18:00 +08:00
if ( ( order - > flags & CX18_F_EWO_MB_STALE ) = = 0 )
2008-11-16 12:38:19 +08:00
mb_ack_irq ( cx , order ) ;
return str_offset ? 1 : 0 ;
}
static inline
2009-04-14 09:22:40 +08:00
int epu_cmd_irq ( struct cx18 * cx , struct cx18_in_work_order * order )
2008-11-16 12:38:19 +08:00
{
int ret = - 1 ;
switch ( order - > rpu ) {
case CPU :
{
switch ( order - > mb . cmd ) {
case CX18_EPU_DMA_DONE :
2008-11-17 08:18:00 +08:00
ret = epu_dma_done_irq ( cx , order ) ;
2008-11-16 12:38:19 +08:00
break ;
case CX18_EPU_DEBUG :
2008-11-17 08:18:00 +08:00
ret = epu_debug_irq ( cx , order ) ;
2008-11-16 12:38:19 +08:00
break ;
default :
CX18_WARN ( " Unknown CPU to EPU mailbox command %#0x \n " ,
order - > mb . cmd ) ;
break ;
}
break ;
}
case APU :
CX18_WARN ( " Unknown APU to EPU mailbox command %#0x \n " ,
order - > mb . cmd ) ;
break ;
default :
break ;
}
return ret ;
2008-04-29 07:24:33 +08:00
}
2008-11-16 12:38:19 +08:00
static inline
2009-04-14 09:22:40 +08:00
struct cx18_in_work_order * alloc_in_work_order_irq ( struct cx18 * cx )
2008-11-16 12:38:19 +08:00
{
int i ;
2009-04-14 09:22:40 +08:00
struct cx18_in_work_order * order = NULL ;
2008-11-16 12:38:19 +08:00
2009-04-14 09:22:40 +08:00
for ( i = 0 ; i < CX18_MAX_IN_WORK_ORDERS ; i + + ) {
2008-11-16 12:38:19 +08:00
/*
* We only need " pending " atomic to inspect its contents ,
* and need not do a check and set because :
* 1. Any work handler thread only clears " pending " and only
* on one , particular work order at a time , per handler thread .
* 2. " pending " is only set here , and we ' re serialized because
* we ' re called in an IRQ handler context .
*/
2009-04-14 09:22:40 +08:00
if ( atomic_read ( & cx - > in_work_order [ i ] . pending ) = = 0 ) {
order = & cx - > in_work_order [ i ] ;
2008-11-16 12:38:19 +08:00
atomic_set ( & order - > pending , 1 ) ;
break ;
}
}
return order ;
}
void cx18_api_epu_cmd_irq ( struct cx18 * cx , int rpu )
{
struct cx18_mailbox __iomem * mb ;
struct cx18_mailbox * order_mb ;
2009-04-14 09:22:40 +08:00
struct cx18_in_work_order * order ;
2008-11-16 12:38:19 +08:00
int submit ;
2012-05-26 19:07:03 +08:00
int i ;
2008-11-16 12:38:19 +08:00
switch ( rpu ) {
case CPU :
mb = & cx - > scb - > cpu2epu_mb ;
break ;
case APU :
mb = & cx - > scb - > apu2epu_mb ;
break ;
default :
return ;
}
2009-04-14 09:22:40 +08:00
order = alloc_in_work_order_irq ( cx ) ;
2008-11-16 12:38:19 +08:00
if ( order = = NULL ) {
[media] cx18: don't break long lines
Due to the 80-cols restrictions, and latter due to checkpatch
warnings, several strings were broken into multiple lines. This
is not considered a good practice anymore, as it makes harder
to grep for strings at the source code.
As we're right now fixing other drivers due to KERN_CONT, we need
to be able to identify what printk strings don't end with a "\n".
It is a way easier to detect those if we don't break long lines.
So, join those continuation lines.
The patch was generated via the script below, and manually
adjusted if needed.
</script>
use Text::Tabs;
while (<>) {
if ($next ne "") {
$c=$_;
if ($c =~ /^\s+\"(.*)/) {
$c2=$1;
$next =~ s/\"\n$//;
$n = expand($next);
$funpos = index($n, '(');
$pos = index($c2, '",');
if ($funpos && $pos > 0) {
$s1 = substr $c2, 0, $pos + 2;
$s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2;
$s2 =~ s/^\s+//;
$s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne "");
print unexpand("$next$s1\n");
print unexpand("$s2\n") if ($s2 ne "");
} else {
print "$next$c2\n";
}
$next="";
next;
} else {
print $next;
}
$next="";
} else {
if (m/\"$/) {
if (!m/\\n\"$/) {
$next=$_;
next;
}
}
}
print $_;
}
</script>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-10-19 03:44:03 +08:00
CX18_WARN ( " Unable to find blank work order form to schedule incoming mailbox command processing \n " ) ;
2008-11-16 12:38:19 +08:00
return ;
}
2008-11-17 08:18:00 +08:00
order - > flags = 0 ;
2008-11-16 12:38:19 +08:00
order - > rpu = rpu ;
order_mb = & order - > mb ;
2008-11-18 09:48:46 +08:00
/* mb->cmd and mb->args[0] through mb->args[2] */
2012-05-26 19:07:03 +08:00
for ( i = 0 ; i < 4 ; i + + )
( & order_mb - > cmd ) [ i ] = cx18_readl ( cx , & mb - > cmd + i ) ;
2008-11-18 09:48:46 +08:00
/* mb->request and mb->ack. N.B. we want to read mb->ack last */
2012-05-26 19:07:03 +08:00
for ( i = 0 ; i < 2 ; i + + )
( & order_mb - > request ) [ i ] = cx18_readl ( cx , & mb - > request + i ) ;
2008-11-16 12:38:19 +08:00
if ( order_mb - > request = = order_mb - > ack ) {
[media] cx18: don't break long lines
Due to the 80-cols restrictions, and latter due to checkpatch
warnings, several strings were broken into multiple lines. This
is not considered a good practice anymore, as it makes harder
to grep for strings at the source code.
As we're right now fixing other drivers due to KERN_CONT, we need
to be able to identify what printk strings don't end with a "\n".
It is a way easier to detect those if we don't break long lines.
So, join those continuation lines.
The patch was generated via the script below, and manually
adjusted if needed.
</script>
use Text::Tabs;
while (<>) {
if ($next ne "") {
$c=$_;
if ($c =~ /^\s+\"(.*)/) {
$c2=$1;
$next =~ s/\"\n$//;
$n = expand($next);
$funpos = index($n, '(');
$pos = index($c2, '",');
if ($funpos && $pos > 0) {
$s1 = substr $c2, 0, $pos + 2;
$s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2;
$s2 =~ s/^\s+//;
$s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne "");
print unexpand("$next$s1\n");
print unexpand("$s2\n") if ($s2 ne "");
} else {
print "$next$c2\n";
}
$next="";
next;
} else {
print $next;
}
$next="";
} else {
if (m/\"$/) {
if (!m/\\n\"$/) {
$next=$_;
next;
}
}
}
print $_;
}
</script>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-10-19 03:44:03 +08:00
CX18_DEBUG_WARN ( " Possibly falling behind: %s self-ack'ed our incoming %s to EPU mailbox (sequence no. %u) \n " ,
2008-11-19 12:24:33 +08:00
rpu_str [ rpu ] , rpu_str [ rpu ] , order_mb - > request ) ;
2009-01-01 23:35:06 +08:00
if ( cx18_debug & CX18_DBGFLG_WARN )
dump_mb ( cx , order_mb , " incoming " ) ;
2008-11-17 08:18:00 +08:00
order - > flags = CX18_F_EWO_MB_STALE_UPON_RECEIPT ;
2008-11-16 12:38:19 +08:00
}
/*
* Individual EPU command processing is responsible for ack - ing
* a non - stale mailbox as soon as possible
*/
2008-11-17 08:18:00 +08:00
submit = epu_cmd_irq ( cx , order ) ;
2008-11-16 12:38:19 +08:00
if ( submit > 0 ) {
2009-04-14 09:22:40 +08:00
queue_work ( cx - > in_work_queue , & order - > work ) ;
2008-11-16 12:38:19 +08:00
}
}
/*
* Functions called from a non - interrupt , non work_queue context
*/
2008-04-29 07:24:33 +08:00
static int cx18_api_call ( struct cx18 * cx , u32 cmd , int args , u32 data [ ] )
{
const struct cx18_api_info * info = find_api_info ( cmd ) ;
2012-04-23 19:25:20 +08:00
u32 irq , req , ack , err ;
2008-05-21 11:32:01 +08:00
struct cx18_mailbox __iomem * mb ;
2008-04-29 07:24:33 +08:00
wait_queue_head_t * waitq ;
2008-11-06 12:15:41 +08:00
struct mutex * mb_lock ;
2009-04-14 09:53:09 +08:00
unsigned long int t0 , timeout , ret ;
2008-04-29 07:24:33 +08:00
int i ;
2009-01-01 23:35:06 +08:00
char argstr [ MAX_MB_ARGUMENTS * 11 + 1 ] ;
2009-04-14 09:53:09 +08:00
DEFINE_WAIT ( w ) ;
2008-04-29 07:24:33 +08:00
if ( info = = NULL ) {
CX18_WARN ( " unknown cmd %x \n " , cmd ) ;
return - EINVAL ;
}
2009-01-01 23:35:06 +08:00
if ( cx18_debug & CX18_DBGFLG_API ) { /* only call u32arr2hex if needed */
if ( cmd = = CX18_CPU_DE_SET_MDL ) {
if ( cx18_debug & CX18_DBGFLG_HIGHVOL )
CX18_DEBUG_HI_API ( " %s \t cmd %#010x args%s \n " ,
info - > name , cmd ,
u32arr2hex ( data , args , argstr ) ) ;
} else
CX18_DEBUG_API ( " %s \t cmd %#010x args%s \n " ,
info - > name , cmd ,
u32arr2hex ( data , args , argstr ) ) ;
}
2008-11-06 12:15:41 +08:00
switch ( info - > rpu ) {
case APU :
waitq = & cx - > mb_apu_waitq ;
mb_lock = & cx - > epu2apu_mb_lock ;
2008-11-08 10:57:46 +08:00
irq = IRQ_EPU_TO_APU ;
mb = & cx - > scb - > epu2apu_mb ;
2008-11-06 12:15:41 +08:00
break ;
case CPU :
waitq = & cx - > mb_cpu_waitq ;
mb_lock = & cx - > epu2cpu_mb_lock ;
2008-11-08 10:57:46 +08:00
irq = IRQ_EPU_TO_CPU ;
mb = & cx - > scb - > epu2cpu_mb ;
2008-11-06 12:15:41 +08:00
break ;
default :
CX18_WARN ( " Unknown RPU (%d) for API call \n " , info - > rpu ) ;
return - EINVAL ;
}
mutex_lock ( mb_lock ) ;
2008-11-08 10:57:46 +08:00
/*
* Wait for an in - use mailbox to complete
*
* If the XPU is responding with Ack ' s , the mailbox shouldn ' t be in
* a busy state , since we serialize access to it on our end .
*
* If the wait for ack after sending a previous command was interrupted
* by a signal , we may get here and find a busy mailbox . After waiting ,
* mark it " not busy " from our end , if the XPU hasn ' t ack ' ed it still .
*/
req = cx18_readl ( cx , & mb - > request ) ;
2008-11-22 12:23:22 +08:00
timeout = msecs_to_jiffies ( 10 ) ;
2008-11-08 10:57:46 +08:00
ret = wait_event_timeout ( * waitq ,
( ack = cx18_readl ( cx , & mb - > ack ) ) = = req ,
2008-11-09 01:19:37 +08:00
timeout ) ;
2008-11-08 10:57:46 +08:00
if ( req ! = ack ) {
/* waited long enough, make the mbox "not busy" from our end */
cx18_writel ( cx , req , & mb - > ack ) ;
[media] cx18: don't break long lines
Due to the 80-cols restrictions, and latter due to checkpatch
warnings, several strings were broken into multiple lines. This
is not considered a good practice anymore, as it makes harder
to grep for strings at the source code.
As we're right now fixing other drivers due to KERN_CONT, we need
to be able to identify what printk strings don't end with a "\n".
It is a way easier to detect those if we don't break long lines.
So, join those continuation lines.
The patch was generated via the script below, and manually
adjusted if needed.
</script>
use Text::Tabs;
while (<>) {
if ($next ne "") {
$c=$_;
if ($c =~ /^\s+\"(.*)/) {
$c2=$1;
$next =~ s/\"\n$//;
$n = expand($next);
$funpos = index($n, '(');
$pos = index($c2, '",');
if ($funpos && $pos > 0) {
$s1 = substr $c2, 0, $pos + 2;
$s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2;
$s2 =~ s/^\s+//;
$s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne "");
print unexpand("$next$s1\n");
print unexpand("$s2\n") if ($s2 ne "");
} else {
print "$next$c2\n";
}
$next="";
next;
} else {
print $next;
}
$next="";
} else {
if (m/\"$/) {
if (!m/\\n\"$/) {
$next=$_;
next;
}
}
}
print $_;
}
</script>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-10-19 03:44:03 +08:00
CX18_ERR ( " mbox was found stuck busy when setting up for %s; clearing busy and trying to proceed \n " ,
info - > name ) ;
2008-11-09 01:19:37 +08:00
} else if ( ret ! = timeout )
2008-11-22 12:23:22 +08:00
CX18_DEBUG_API ( " waited %u msecs for busy mbox to be acked \n " ,
jiffies_to_msecs ( timeout - ret ) ) ;
2008-11-08 10:57:46 +08:00
/* Build the outgoing mailbox */
req = ( ( req & 0xfffffffe ) = = 0xfffffffe ) ? 1 : req + 1 ;
2008-04-29 07:24:33 +08:00
2008-08-31 03:03:44 +08:00
cx18_writel ( cx , cmd , & mb - > cmd ) ;
2008-04-29 07:24:33 +08:00
for ( i = 0 ; i < args ; i + + )
2008-08-31 03:03:44 +08:00
cx18_writel ( cx , data [ i ] , & mb - > args [ i ] ) ;
cx18_writel ( cx , 0 , & mb - > error ) ;
cx18_writel ( cx , req , & mb - > request ) ;
2008-11-08 10:57:46 +08:00
cx18_writel ( cx , req - 1 , & mb - > ack ) ; /* ensure ack & req are distinct */
2008-04-29 07:24:33 +08:00
2008-11-09 01:19:37 +08:00
/*
* Notify the XPU and wait for it to send an Ack back
*/
2008-11-22 12:23:22 +08:00
timeout = msecs_to_jiffies ( ( info - > flags & API_FAST ) ? 10 : 20 ) ;
2008-11-08 10:57:46 +08:00
CX18_DEBUG_HI_IRQ ( " sending interrupt SW1: %x to send %s \n " ,
irq , info - > name ) ;
2009-04-14 09:53:09 +08:00
/* So we don't miss the wakeup, prepare to wait before notifying fw */
prepare_to_wait ( waitq , & w , TASK_UNINTERRUPTIBLE ) ;
2008-11-01 07:49:12 +08:00
cx18_write_reg_expect ( cx , irq , SW1_INT_SET , irq , irq ) ;
2008-04-29 07:24:33 +08:00
2009-04-14 09:53:09 +08:00
t0 = jiffies ;
ack = cx18_readl ( cx , & mb - > ack ) ;
if ( ack ! = req ) {
schedule_timeout ( timeout ) ;
ret = jiffies - t0 ;
ack = cx18_readl ( cx , & mb - > ack ) ;
} else {
ret = jiffies - t0 ;
}
finish_wait ( waitq , & w ) ;
2008-11-22 12:23:22 +08:00
2009-04-14 09:53:09 +08:00
if ( req ! = ack ) {
2008-11-06 12:15:41 +08:00
mutex_unlock ( mb_lock ) ;
2009-04-14 09:53:09 +08:00
if ( ret > = timeout ) {
/* Timed out */
[media] cx18: don't break long lines
Due to the 80-cols restrictions, and latter due to checkpatch
warnings, several strings were broken into multiple lines. This
is not considered a good practice anymore, as it makes harder
to grep for strings at the source code.
As we're right now fixing other drivers due to KERN_CONT, we need
to be able to identify what printk strings don't end with a "\n".
It is a way easier to detect those if we don't break long lines.
So, join those continuation lines.
The patch was generated via the script below, and manually
adjusted if needed.
</script>
use Text::Tabs;
while (<>) {
if ($next ne "") {
$c=$_;
if ($c =~ /^\s+\"(.*)/) {
$c2=$1;
$next =~ s/\"\n$//;
$n = expand($next);
$funpos = index($n, '(');
$pos = index($c2, '",');
if ($funpos && $pos > 0) {
$s1 = substr $c2, 0, $pos + 2;
$s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2;
$s2 =~ s/^\s+//;
$s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne "");
print unexpand("$next$s1\n");
print unexpand("$s2\n") if ($s2 ne "");
} else {
print "$next$c2\n";
}
$next="";
next;
} else {
print $next;
}
$next="";
} else {
if (m/\"$/) {
if (!m/\\n\"$/) {
$next=$_;
next;
}
}
}
print $_;
}
</script>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-10-19 03:44:03 +08:00
CX18_DEBUG_WARN ( " sending %s timed out waiting %d msecs for RPU acknowledgment \n " ,
2009-04-14 09:53:09 +08:00
info - > name , jiffies_to_msecs ( ret ) ) ;
} else {
[media] cx18: don't break long lines
Due to the 80-cols restrictions, and latter due to checkpatch
warnings, several strings were broken into multiple lines. This
is not considered a good practice anymore, as it makes harder
to grep for strings at the source code.
As we're right now fixing other drivers due to KERN_CONT, we need
to be able to identify what printk strings don't end with a "\n".
It is a way easier to detect those if we don't break long lines.
So, join those continuation lines.
The patch was generated via the script below, and manually
adjusted if needed.
</script>
use Text::Tabs;
while (<>) {
if ($next ne "") {
$c=$_;
if ($c =~ /^\s+\"(.*)/) {
$c2=$1;
$next =~ s/\"\n$//;
$n = expand($next);
$funpos = index($n, '(');
$pos = index($c2, '",');
if ($funpos && $pos > 0) {
$s1 = substr $c2, 0, $pos + 2;
$s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2;
$s2 =~ s/^\s+//;
$s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne "");
print unexpand("$next$s1\n");
print unexpand("$s2\n") if ($s2 ne "");
} else {
print "$next$c2\n";
}
$next="";
next;
} else {
print $next;
}
$next="";
} else {
if (m/\"$/) {
if (!m/\\n\"$/) {
$next=$_;
next;
}
}
}
print $_;
}
</script>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-10-19 03:44:03 +08:00
CX18_DEBUG_WARN ( " woken up before mailbox ack was ready after submitting %s to RPU. only waited %d msecs on req %u but awakened with unmatched ack %u \n " ,
2009-04-14 09:53:09 +08:00
info - > name ,
jiffies_to_msecs ( ret ) ,
req , ack ) ;
}
2008-04-29 07:24:33 +08:00
return - EINVAL ;
2008-11-09 01:19:37 +08:00
}
2009-04-14 09:53:09 +08:00
if ( ret > = timeout )
[media] cx18: don't break long lines
Due to the 80-cols restrictions, and latter due to checkpatch
warnings, several strings were broken into multiple lines. This
is not considered a good practice anymore, as it makes harder
to grep for strings at the source code.
As we're right now fixing other drivers due to KERN_CONT, we need
to be able to identify what printk strings don't end with a "\n".
It is a way easier to detect those if we don't break long lines.
So, join those continuation lines.
The patch was generated via the script below, and manually
adjusted if needed.
</script>
use Text::Tabs;
while (<>) {
if ($next ne "") {
$c=$_;
if ($c =~ /^\s+\"(.*)/) {
$c2=$1;
$next =~ s/\"\n$//;
$n = expand($next);
$funpos = index($n, '(');
$pos = index($c2, '",');
if ($funpos && $pos > 0) {
$s1 = substr $c2, 0, $pos + 2;
$s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2;
$s2 =~ s/^\s+//;
$s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne "");
print unexpand("$next$s1\n");
print unexpand("$s2\n") if ($s2 ne "");
} else {
print "$next$c2\n";
}
$next="";
next;
} else {
print $next;
}
$next="";
} else {
if (m/\"$/) {
if (!m/\\n\"$/) {
$next=$_;
next;
}
}
}
print $_;
}
</script>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-10-19 03:44:03 +08:00
CX18_DEBUG_WARN ( " failed to be awakened upon RPU acknowledgment sending %s; timed out waiting %d msecs \n " ,
2009-04-14 09:53:09 +08:00
info - > name , jiffies_to_msecs ( ret ) ) ;
else
2008-11-09 01:19:37 +08:00
CX18_DEBUG_HI_API ( " waited %u msecs for %s to be acked \n " ,
2009-04-14 09:53:09 +08:00
jiffies_to_msecs ( ret ) , info - > name ) ;
2008-11-06 12:15:41 +08:00
2008-11-08 10:57:46 +08:00
/* Collect data returned by the XPU */
2008-04-29 07:24:33 +08:00
for ( i = 0 ; i < MAX_MB_ARGUMENTS ; i + + )
2008-08-31 03:03:44 +08:00
data [ i ] = cx18_readl ( cx , & mb - > args [ i ] ) ;
err = cx18_readl ( cx , & mb - > error ) ;
2008-11-06 12:15:41 +08:00
mutex_unlock ( mb_lock ) ;
2008-11-08 10:57:46 +08:00
/*
* Wait for XPU to perform extra actions for the caller in some cases .
2009-11-09 10:45:24 +08:00
* e . g . CX18_CPU_DE_RELEASE_MDL will cause the CPU to send all MDLs
2008-11-08 10:57:46 +08:00
* back in a burst shortly thereafter
*/
2008-11-06 12:15:41 +08:00
if ( info - > flags & API_SLOW )
2008-04-29 07:24:33 +08:00
cx18_msleep_timeout ( 300 , 0 ) ;
2008-11-08 10:57:46 +08:00
2008-04-29 07:24:33 +08:00
if ( err )
CX18_DEBUG_API ( " mailbox error %08x for command %s \n " , err ,
info - > name ) ;
return err ? - EIO : 0 ;
}
int cx18_api ( struct cx18 * cx , u32 cmd , int args , u32 data [ ] )
{
2008-11-08 10:57:46 +08:00
return cx18_api_call ( cx , cmd , args , data ) ;
2008-04-29 07:24:33 +08:00
}
static int cx18_set_filter_param ( struct cx18_stream * s )
{
struct cx18 * cx = s - > cx ;
u32 mode ;
int ret ;
mode = ( cx - > filter_mode & 1 ) ? 2 : ( cx - > spatial_strength ? 1 : 0 ) ;
ret = cx18_vapi ( cx , CX18_CPU_SET_FILTER_PARAM , 4 ,
s - > handle , 1 , mode , cx - > spatial_strength ) ;
mode = ( cx - > filter_mode & 2 ) ? 2 : ( cx - > temporal_strength ? 1 : 0 ) ;
ret = ret ? ret : cx18_vapi ( cx , CX18_CPU_SET_FILTER_PARAM , 4 ,
s - > handle , 0 , mode , cx - > temporal_strength ) ;
ret = ret ? ret : cx18_vapi ( cx , CX18_CPU_SET_FILTER_PARAM , 4 ,
s - > handle , 2 , cx - > filter_mode > > 2 , 0 ) ;
return ret ;
}
int cx18_api_func ( void * priv , u32 cmd , int in , int out ,
u32 data [ CX2341X_MBOX_MAX_DATA ] )
{
2010-12-31 21:22:52 +08:00
struct cx18_stream * s = priv ;
struct cx18 * cx = s - > cx ;
2008-04-29 07:24:33 +08:00
switch ( cmd ) {
case CX2341X_ENC_SET_OUTPUT_PORT :
return 0 ;
case CX2341X_ENC_SET_FRAME_RATE :
return cx18_vapi ( cx , CX18_CPU_SET_VIDEO_IN , 6 ,
s - > handle , 0 , 0 , 0 , 0 , data [ 0 ] ) ;
case CX2341X_ENC_SET_FRAME_SIZE :
return cx18_vapi ( cx , CX18_CPU_SET_VIDEO_RESOLUTION , 3 ,
s - > handle , data [ 1 ] , data [ 0 ] ) ;
case CX2341X_ENC_SET_STREAM_TYPE :
return cx18_vapi ( cx , CX18_CPU_SET_STREAM_OUTPUT_TYPE , 2 ,
s - > handle , data [ 0 ] ) ;
case CX2341X_ENC_SET_ASPECT_RATIO :
return cx18_vapi ( cx , CX18_CPU_SET_ASPECT_RATIO , 2 ,
s - > handle , data [ 0 ] ) ;
case CX2341X_ENC_SET_GOP_PROPERTIES :
return cx18_vapi ( cx , CX18_CPU_SET_GOP_STRUCTURE , 3 ,
s - > handle , data [ 0 ] , data [ 1 ] ) ;
case CX2341X_ENC_SET_GOP_CLOSURE :
return 0 ;
case CX2341X_ENC_SET_AUDIO_PROPERTIES :
return cx18_vapi ( cx , CX18_CPU_SET_AUDIO_PARAMETERS , 2 ,
s - > handle , data [ 0 ] ) ;
case CX2341X_ENC_MUTE_AUDIO :
return cx18_vapi ( cx , CX18_CPU_SET_AUDIO_MUTE , 2 ,
s - > handle , data [ 0 ] ) ;
case CX2341X_ENC_SET_BIT_RATE :
return cx18_vapi ( cx , CX18_CPU_SET_VIDEO_RATE , 5 ,
s - > handle , data [ 0 ] , data [ 1 ] , data [ 2 ] , data [ 3 ] ) ;
case CX2341X_ENC_MUTE_VIDEO :
return cx18_vapi ( cx , CX18_CPU_SET_VIDEO_MUTE , 2 ,
s - > handle , data [ 0 ] ) ;
case CX2341X_ENC_SET_FRAME_DROP_RATE :
return cx18_vapi ( cx , CX18_CPU_SET_SKIP_INPUT_FRAME , 2 ,
s - > handle , data [ 0 ] ) ;
case CX2341X_ENC_MISC :
return cx18_vapi ( cx , CX18_CPU_SET_MISC_PARAMETERS , 4 ,
s - > handle , data [ 0 ] , data [ 1 ] , data [ 2 ] ) ;
case CX2341X_ENC_SET_DNR_FILTER_MODE :
cx - > filter_mode = ( data [ 0 ] & 3 ) | ( data [ 1 ] < < 2 ) ;
return cx18_set_filter_param ( s ) ;
case CX2341X_ENC_SET_DNR_FILTER_PROPS :
cx - > spatial_strength = data [ 0 ] ;
cx - > temporal_strength = data [ 1 ] ;
return cx18_set_filter_param ( s ) ;
case CX2341X_ENC_SET_SPATIAL_FILTER_TYPE :
return cx18_vapi ( cx , CX18_CPU_SET_SPATIAL_FILTER_TYPE , 3 ,
s - > handle , data [ 0 ] , data [ 1 ] ) ;
case CX2341X_ENC_SET_CORING_LEVELS :
return cx18_vapi ( cx , CX18_CPU_SET_MEDIAN_CORING , 5 ,
s - > handle , data [ 0 ] , data [ 1 ] , data [ 2 ] , data [ 3 ] ) ;
}
CX18_WARN ( " Unknown cmd %x \n " , cmd ) ;
return 0 ;
}
int cx18_vapi_result ( struct cx18 * cx , u32 data [ MAX_MB_ARGUMENTS ] ,
u32 cmd , int args , . . . )
{
va_list ap ;
int i ;
va_start ( ap , args ) ;
for ( i = 0 ; i < args ; i + + )
data [ i ] = va_arg ( ap , u32 ) ;
va_end ( ap ) ;
return cx18_api ( cx , cmd , args , data ) ;
}
int cx18_vapi ( struct cx18 * cx , u32 cmd , int args , . . . )
{
u32 data [ MAX_MB_ARGUMENTS ] ;
va_list ap ;
int i ;
if ( cx = = NULL ) {
CX18_ERR ( " cx == NULL (cmd=%x) \n " , cmd ) ;
return 0 ;
}
if ( args > MAX_MB_ARGUMENTS ) {
CX18_ERR ( " args too big (cmd=%x) \n " , cmd ) ;
args = MAX_MB_ARGUMENTS ;
}
va_start ( ap , args ) ;
for ( i = 0 ; i < args ; i + + )
data [ i ] = va_arg ( ap , u32 ) ;
va_end ( ap ) ;
return cx18_api ( cx , cmd , args , data ) ;
}