Merge "arm: defconfig: msm8226: Enable HWMON"
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index a7ea350..741ffbd 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -94,6 +94,14 @@
qcom,hsusb-otg-mode = <1>;
qcom,hsusb-otg-otg-control = <1>;
qcom,hsusb-otg-disable-reset;
+
+ qcom,msm-bus,name = "usb2";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,active-only = <0>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <87 512 0 0>,
+ <87 512 60000 960000>;
};
android_usb@fe8050c8 {
diff --git a/arch/arm/mach-msm/board-8226.c b/arch/arm/mach-msm/board-8226.c
index 2b331d0..79ab428 100644
--- a/arch/arm/mach-msm/board-8226.c
+++ b/arch/arm/mach-msm/board-8226.c
@@ -51,6 +51,7 @@
#include "platsmp.h"
#include "spm.h"
#include "lpm_resources.h"
+#include "modem_notifier.h"
static struct memtype_reserve msm8226_reserve_table[] __initdata = {
[MEMTYPE_SMI] = {
@@ -102,6 +103,8 @@
*/
void __init msm8226_add_drivers(void)
{
+ msm_init_modem_notifier_list();
+ msm_smd_init();
msm_rpm_driver_init();
msm_lpmrs_module_init();
msm_spm_device_init();
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index dfb8d58..2a0cde9 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -514,6 +514,10 @@
((feed->pid != pid) && (feed->pid != 0x2000)))
continue;
+ if (feed->secure_mode.is_secured &&
+ !dvb_dmx_is_rec_feed(feed))
+ return 0;
+
if (feed->type == DMX_TYPE_TS) {
desired_space = 192; /* upper bound */
ts = &feed->feed.ts;
@@ -593,19 +597,23 @@
if (!feed->feed.ts.is_filtering)
break;
if (feed->ts_type & TS_PACKET) {
- if (feed->ts_type & TS_PAYLOAD_ONLY)
- dvb_dmx_swfilter_payload(feed, buf);
- else
+ if (feed->ts_type & TS_PAYLOAD_ONLY) {
+ if (!feed->secure_mode.is_secured)
+ dvb_dmx_swfilter_payload(feed, buf);
+ } else {
dvb_dmx_swfilter_output_packet(feed,
buf, timestamp);
+ }
}
- if (feed->ts_type & TS_DECODER)
+ if ((feed->ts_type & TS_DECODER) &&
+ !feed->secure_mode.is_secured)
if (feed->demux->write_to_decoder)
feed->demux->write_to_decoder(feed, buf, 188);
break;
case DMX_TYPE_SEC:
- if (!feed->feed.sec.is_filtering)
+ if (!feed->feed.sec.is_filtering ||
+ feed->secure_mode.is_secured)
break;
if (dvb_dmx_swfilter_section_packet(feed, buf) < 0)
feed->feed.sec.seclen = feed->feed.sec.secbufp = 0;
@@ -1212,17 +1220,22 @@
{
struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
+ int ret = 0;
mutex_lock(&dvbdmx->mutex);
- dvbdmxfeed->secure_mode = *secure_mode;
-
if ((dvbdmxfeed->state == DMX_STATE_GO) &&
- dvbdmxfeed->demux->set_secure_mode)
- dvbdmxfeed->demux->set_secure_mode(dvbdmxfeed, secure_mode);
+ dvbdmxfeed->demux->set_secure_mode) {
+ ret = dvbdmxfeed->demux->set_secure_mode(dvbdmxfeed,
+ secure_mode);
+ if (!ret)
+ dvbdmxfeed->secure_mode = *secure_mode;
+ } else {
+ dvbdmxfeed->secure_mode = *secure_mode;
+ }
mutex_unlock(&dvbdmx->mutex);
- return 0;
+ return ret;
}
static int dmx_ts_set_indexing_params(
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h
index f5f6039..f3dc4b8 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.h
+++ b/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -203,5 +203,85 @@
void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf,
const u8 timestamp[TIMESTAMP_LEN]);
+/**
+ * dvb_dmx_is_video_feed - Returns whether the PES feed
+ * is video one.
+ *
+ * @feed: The feed to be checked.
+ *
+ * Return 1 if feed is video feed, 0 otherwise.
+ */
+static inline int dvb_dmx_is_video_feed(struct dvb_demux_feed *feed)
+{
+ if (feed->type != DMX_TYPE_TS)
+ return 0;
+
+ if (feed->ts_type & (~TS_DECODER))
+ return 0;
+
+ if ((feed->pes_type == DMX_TS_PES_VIDEO0) ||
+ (feed->pes_type == DMX_TS_PES_VIDEO1) ||
+ (feed->pes_type == DMX_TS_PES_VIDEO2) ||
+ (feed->pes_type == DMX_TS_PES_VIDEO3))
+ return 1;
+
+ return 0;
+}
+
+/**
+ * dvb_dmx_is_pcr_feed - Returns whether the PES feed
+ * is PCR one.
+ *
+ * @feed: The feed to be checked.
+ *
+ * Return 1 if feed is PCR feed, 0 otherwise.
+ */
+static inline int dvb_dmx_is_pcr_feed(struct dvb_demux_feed *feed)
+{
+ if (feed->type != DMX_TYPE_TS)
+ return 0;
+
+ if (feed->ts_type & (~TS_DECODER))
+ return 0;
+
+ if ((feed->pes_type == DMX_TS_PES_PCR0) ||
+ (feed->pes_type == DMX_TS_PES_PCR1) ||
+ (feed->pes_type == DMX_TS_PES_PCR2) ||
+ (feed->pes_type == DMX_TS_PES_PCR3))
+ return 1;
+
+ return 0;
+}
+
+/**
+ * dvb_dmx_is_sec_feed - Returns whether this is a section feed
+ *
+ * @feed: The feed to be checked.
+ *
+ * Return 1 if feed is a section feed, 0 otherwise.
+ */
+static inline int dvb_dmx_is_sec_feed(struct dvb_demux_feed *feed)
+{
+ return (feed->type == DMX_TYPE_SEC);
+}
+
+/**
+ * dvb_dmx_is_rec_feed - Returns whether this is a recording feed
+ *
+ * @feed: The feed to be checked.
+ *
+ * Return 1 if feed is recording feed, 0 otherwise.
+ */
+static inline int dvb_dmx_is_rec_feed(struct dvb_demux_feed *feed)
+{
+ if (feed->type != DMX_TYPE_TS)
+ return 0;
+
+ if (feed->ts_type & (TS_DECODER | TS_PAYLOAD_ONLY))
+ return 0;
+
+ return 1;
+}
+
#endif /* _DVB_DEMUX_H_ */
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
index 9d89a7e..0641162 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
@@ -903,6 +903,8 @@
mutex_init(&mpq_demux->mutex);
+ mpq_demux->num_secure_feeds = 0;
+ mpq_demux->num_active_feeds = 0;
mpq_demux->sdmx_filter_count = 0;
mpq_demux->sdmx_session_handle = SDMX_INVALID_SESSION_HANDLE;
@@ -1230,7 +1232,7 @@
return -EINVAL;
}
- if (mpq_dmx_is_video_feed(feed)) {
+ if (dvb_dmx_is_video_feed(feed)) {
struct mpq_video_feed_info *feed_data;
struct mpq_feed *mpq_feed;
struct mpq_streambuffer *stream_buffer;
@@ -1957,9 +1959,10 @@
}
mpq_sdmx_close_session(mpq_demux);
+ mpq_demux->num_secure_feeds--;
}
- if (mpq_dmx_is_video_feed(feed)) {
+ if (dvb_dmx_is_video_feed(feed)) {
ret = mpq_dmx_terminate_video_feed(mpq_feed);
if (ret)
MPQ_DVB_ERR_PRINT(
@@ -1973,6 +1976,7 @@
}
mpq_sdmx_terminate_metadata_buffer(mpq_feed);
+ mpq_demux->num_active_feeds--;
mutex_unlock(&mpq_demux->mutex);
@@ -1982,7 +1986,7 @@
int mpq_dmx_decoder_fullness_init(struct dvb_demux_feed *feed)
{
- if (mpq_dmx_is_video_feed(feed)) {
+ if (dvb_dmx_is_video_feed(feed)) {
struct mpq_feed *mpq_feed;
struct mpq_video_feed_info *feed_data;
@@ -2056,7 +2060,7 @@
struct mpq_feed *mpq_feed;
int ret = 0;
- if (!mpq_dmx_is_video_feed(feed)) {
+ if (!dvb_dmx_is_video_feed(feed)) {
MPQ_DVB_DBG_PRINT("%s: Invalid feed type %d\n",
__func__,
feed->pes_type);
@@ -2139,7 +2143,7 @@
int mpq_dmx_decoder_fullness_abort(struct dvb_demux_feed *feed)
{
- if (mpq_dmx_is_video_feed(feed)) {
+ if (dvb_dmx_is_video_feed(feed)) {
struct mpq_feed *mpq_feed;
struct mpq_video_feed_info *feed_data;
struct dvb_ringbuffer *video_buff;
@@ -3087,7 +3091,7 @@
struct mpq_streambuffer *video_buff;
struct mpq_feed *mpq_feed;
- if (!mpq_dmx_is_video_feed(feed)) {
+ if (!dvb_dmx_is_video_feed(feed)) {
MPQ_DVB_ERR_PRINT(
"%s: Invalid feed type %d\n",
__func__,
@@ -3230,67 +3234,6 @@
}
EXPORT_SYMBOL(mpq_dmx_process_pcr_packet);
-int mpq_dmx_set_secure_mode(struct dvb_demux_feed *feed,
- struct dmx_secure_mode *sec_mode)
-{
- struct mpq_feed *mpq_feed;
- struct mpq_demux *mpq_demux;
- int ret;
-
- if (!feed || !feed->priv || !sec_mode) {
- MPQ_DVB_ERR_PRINT(
- "%s: invalid parameters\n",
- __func__);
- return -EINVAL;
- }
-
- MPQ_DVB_DBG_PRINT("%s(%d, %d, %d)\n",
- __func__, sec_mode->pid,
- sec_mode->is_secured,
- sec_mode->key_ladder_id);
-
- mpq_feed = feed->priv;
- mpq_demux = mpq_feed->mpq_demux;
-
- mutex_lock(&mpq_demux->mutex);
-
- /*
- * If secure demux is active, set the KL now,
- * otherwise it will be set when secure-demux is started
- * (when filtering starts).
- */
- if (mpq_demux->sdmx_session_handle !=
- SDMX_INVALID_SESSION_HANDLE) {
- if (sec_mode->is_secured) {
- MPQ_DVB_DBG_PRINT(
- "%s: set key-ladder %d to PID %d\n",
- __func__,
- sec_mode->key_ladder_id,
- sec_mode->pid);
- ret = sdmx_set_kl_ind(mpq_demux->sdmx_session_handle,
- sec_mode->pid, sec_mode->key_ladder_id);
- if (ret) {
- MPQ_DVB_ERR_PRINT(
- "%s: FAILED to set keyladder, ret=%d\n",
- __func__, ret);
- ret = -EINVAL;
- }
- } else {
- MPQ_DVB_DBG_PRINT("%s: setting non-secure mode\n",
- __func__);
- ret = 0;
- }
- } else {
- MPQ_DVB_DBG_PRINT("%s: SDMX not started yet\n", __func__);
- ret = 0;
- }
-
- mutex_unlock(&mpq_demux->mutex);
-
- return ret;
-}
-EXPORT_SYMBOL(mpq_dmx_set_secure_mode);
-
int mpq_sdmx_open_session(struct mpq_demux *mpq_demux)
{
enum sdmx_status ret = SDMX_SUCCESS;
@@ -3409,7 +3352,7 @@
*buf_mode = SDMX_RING_BUF;
- if (mpq_dmx_is_video_feed(feed->dvb_demux_feed)) {
+ if (dvb_dmx_is_video_feed(feed->dvb_demux_feed)) {
if (feed_data->buffer_desc.decoder_buffers_num > 1)
*buf_mode = SDMX_LINEAR_GROUP_BUF;
*num_buffers = feed_data->buffer_desc.decoder_buffers_num;
@@ -3429,8 +3372,8 @@
}
} else {
*num_buffers = 1;
- if (mpq_dmx_is_sec_feed(dvbdmx_feed) ||
- mpq_dmx_is_pcr_feed(dvbdmx_feed)) {
+ if (dvb_dmx_is_sec_feed(dvbdmx_feed) ||
+ dvb_dmx_is_pcr_feed(dvbdmx_feed)) {
buffer = &feed->sdmx_buf;
sdmx_buff = feed->sdmx_buf_handle;
} else {
@@ -3481,18 +3424,18 @@
feed = dvbdmx_feed->priv;
- if (mpq_dmx_is_sec_feed(dvbdmx_feed)) {
+ if (dvb_dmx_is_sec_feed(dvbdmx_feed)) {
feed->filter_type = SDMX_SECTION_FILTER;
if (dvbdmx_feed->feed.sec.check_crc)
filter_flags |= SDMX_FILTER_FLAG_VERIFY_SECTION_CRC;
MPQ_DVB_DBG_PRINT("%s: SDMX_SECTION_FILTER\n", __func__);
- } else if (mpq_dmx_is_pcr_feed(dvbdmx_feed)) {
+ } else if (dvb_dmx_is_pcr_feed(dvbdmx_feed)) {
feed->filter_type = SDMX_PCR_FILTER;
MPQ_DVB_DBG_PRINT("%s: SDMX_PCR_FILTER\n", __func__);
- } else if (mpq_dmx_is_video_feed(dvbdmx_feed)) {
+ } else if (dvb_dmx_is_video_feed(dvbdmx_feed)) {
feed->filter_type = SDMX_SEPARATED_PES_FILTER;
MPQ_DVB_DBG_PRINT("%s: SDMX_SEPARATED_PES_FILTER\n", __func__);
- } else if (mpq_dmx_is_rec_feed(dvbdmx_feed)) {
+ } else if (dvb_dmx_is_rec_feed(dvbdmx_feed)) {
feed->filter_type = SDMX_RAW_FILTER;
switch (dvbdmx_feed->tsp_out_format) {
case (DMX_TSP_FORMAT_188):
@@ -3546,7 +3489,7 @@
/* Meta-data initialization,
* Recording filters do no need meta-data buffers.
*/
- if (mpq_dmx_is_rec_feed(dvbdmx_feed)) {
+ if (dvb_dmx_is_rec_feed(dvbdmx_feed)) {
metadata_buff_desc.base_addr = 0;
metadata_buff_desc.size = 0;
} else {
@@ -3640,6 +3583,63 @@
return ret;
}
+/**
+ * mpq_sdmx_init_feed - initialize secure demux related elements of mpq feed
+ *
+ * @mpq_demux: mpq_demux object
+ * @mpq_feed: mpq_feed object
+ *
+ * Note: the function assumes mpq_demux->mutex locking is done by caller.
+ */
+static int mpq_sdmx_init_feed(struct mpq_demux *mpq_demux,
+ struct mpq_feed *mpq_feed)
+{
+ int ret;
+
+ ret = mpq_sdmx_open_session(mpq_demux);
+ if (ret) {
+ MPQ_DVB_ERR_PRINT(
+ "%s: mpq_sdmx_open_session failed, ret=%d\n",
+ __func__, ret);
+
+ ret = -ENODEV;
+ goto init_sdmx_feed_failed;
+ }
+
+ /* PCR and sections have internal buffer for SDMX */
+ if (dvb_dmx_is_pcr_feed(mpq_feed->dvb_demux_feed))
+ ret = mpq_sdmx_alloc_data_buf(mpq_feed, SDMX_PCR_BUFFER_SIZE);
+ else if (dvb_dmx_is_sec_feed(mpq_feed->dvb_demux_feed))
+ ret = mpq_sdmx_alloc_data_buf(mpq_feed,
+ SDMX_SECTION_BUFFER_SIZE);
+ else
+ ret = 0;
+
+ if (ret) {
+ MPQ_DVB_ERR_PRINT("%s: init buffer failed, ret=%d\n",
+ __func__, ret);
+ goto init_sdmx_feed_failed_free_sdmx;
+ }
+
+ ret = mpq_sdmx_filter_setup(mpq_demux, mpq_feed->dvb_demux_feed);
+ if (ret) {
+ MPQ_DVB_ERR_PRINT(
+ "%s: mpq_sdmx_filter_setup failed, ret=%d\n",
+ __func__, ret);
+ goto init_sdmx_feed_failed_free_data_buff;
+ }
+
+ mpq_demux->num_secure_feeds++;
+ return 0;
+
+init_sdmx_feed_failed_free_data_buff:
+ mpq_sdmx_free_data_buf(mpq_feed);
+init_sdmx_feed_failed_free_sdmx:
+ mpq_sdmx_close_session(mpq_demux);
+init_sdmx_feed_failed:
+ return ret;
+}
+
int mpq_dmx_init_mpq_feed(struct dvb_demux_feed *feed)
{
int ret = 0;
@@ -3648,80 +3648,113 @@
mutex_lock(&mpq_demux->mutex);
- if (mpq_dmx_is_video_feed(feed)) {
- ret = mpq_dmx_init_video_feed(mpq_feed);
-
- if (ret) {
- MPQ_DVB_ERR_PRINT(
- "%s: mpq_dmx_init_video_feed failed, ret=%d\n",
- __func__, ret);
- goto init_mpq_feed_failed;
- }
- }
-
mpq_feed->sdmx_buf_handle = NULL;
mpq_feed->metadata_buf_handle = NULL;
mpq_feed->sdmx_filter_handle = SDMX_INVALID_FILTER_HANDLE;
- if (!mpq_sdmx_is_loaded()) {
- /* nothing more to do */
- mpq_demux->sdmx_session_handle = SDMX_INVALID_SESSION_HANDLE;
- mutex_unlock(&mpq_demux->mutex);
- return ret;
+ if (dvb_dmx_is_video_feed(feed)) {
+ ret = mpq_dmx_init_video_feed(mpq_feed);
+ if (ret) {
+ MPQ_DVB_ERR_PRINT(
+ "%s: mpq_dmx_init_video_feed failed, ret=%d\n",
+ __func__, ret);
+ goto init_mpq_feed_end;
+ }
}
- /* Further initializations for secure demux */
- ret = mpq_sdmx_open_session(mpq_demux);
+ /*
+ * sdmx is not relevant for recording filters, which always use
+ * regular filters (non-sdmx)
+ */
+ if (!mpq_sdmx_is_loaded() || !feed->secure_mode.is_secured ||
+ dvb_dmx_is_rec_feed(feed)) {
+ if (!mpq_sdmx_is_loaded())
+ mpq_demux->sdmx_session_handle =
+ SDMX_INVALID_SESSION_HANDLE;
+ goto init_mpq_feed_end;
+ }
+
+ /* Initialization of secure demux filters (PES/PCR/Video/Section) */
+ ret = mpq_sdmx_init_feed(mpq_demux, mpq_feed);
if (ret) {
MPQ_DVB_ERR_PRINT(
- "%s: mpq_sdmx_open_session failed, ret=%d\n",
+ "%s: mpq_sdmx_init_feed failed, ret=%d\n",
__func__, ret);
-
- ret = -ENODEV;
- goto init_mpq_feed_failed_free_video;
+ if (dvb_dmx_is_video_feed(feed))
+ mpq_dmx_terminate_video_feed(mpq_feed);
}
- /* PCR and sections have internal buffer for SDMX */
- if (mpq_dmx_is_pcr_feed(feed))
- ret = mpq_sdmx_alloc_data_buf(mpq_feed,
- SDMX_PCR_BUFFER_SIZE);
- else if (mpq_dmx_is_sec_feed(feed))
- ret = mpq_sdmx_alloc_data_buf(mpq_feed,
- SDMX_SECTION_BUFFER_SIZE);
- else
- ret = 0;
-
- if (ret) {
- MPQ_DVB_ERR_PRINT(
- "%s: init buffer failed, ret=%d\n",
- __func__, ret);
- goto init_mpq_feed_failed_free_sdmx;
- }
-
- ret = mpq_sdmx_filter_setup(mpq_demux, feed);
- if (ret) {
- MPQ_DVB_ERR_PRINT(
- "%s: mpq_sdmx_filter_setup failed, ret=%d\n",
- __func__, ret);
- goto init_mpq_feed_failed_free_data_buff;
- }
-
- mutex_unlock(&mpq_demux->mutex);
- return 0;
-
-init_mpq_feed_failed_free_data_buff:
- mpq_sdmx_free_data_buf(mpq_feed);
-init_mpq_feed_failed_free_sdmx:
- mpq_sdmx_close_session(mpq_demux);
-init_mpq_feed_failed_free_video:
- if (mpq_dmx_is_video_feed(feed))
- mpq_dmx_terminate_video_feed(mpq_feed);
-init_mpq_feed_failed:
+init_mpq_feed_end:
+ if (!ret)
+ mpq_demux->num_active_feeds++;
mutex_unlock(&mpq_demux->mutex);
return ret;
}
EXPORT_SYMBOL(mpq_dmx_init_mpq_feed);
+/**
+ * Note: Called only when filter is in "GO" state - after feed has been started.
+ */
+int mpq_dmx_set_secure_mode(struct dvb_demux_feed *feed,
+ struct dmx_secure_mode *sec_mode)
+{
+ struct mpq_feed *mpq_feed;
+ struct mpq_demux *mpq_demux;
+ int ret = 0;
+
+ if (!feed || !feed->priv || !sec_mode) {
+ MPQ_DVB_ERR_PRINT(
+ "%s: invalid parameters\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ MPQ_DVB_DBG_PRINT("%s(%d, %d, %d)\n",
+ __func__, sec_mode->pid,
+ sec_mode->is_secured,
+ sec_mode->key_ladder_id);
+
+ mpq_feed = feed->priv;
+ mpq_demux = mpq_feed->mpq_demux;
+
+ mutex_lock(&mpq_demux->mutex);
+
+ if (feed->secure_mode.is_secured != sec_mode->is_secured) {
+ /*
+ * Switching between secure & non-secure mode is not allowed
+ * while filter is running
+ */
+ MPQ_DVB_ERR_PRINT(
+ "%s: Cannot switch between secure mode while filter is running\n",
+ __func__);
+ mutex_unlock(&mpq_demux->mutex);
+ return -EPERM;
+ }
+
+ /*
+ * Feed is running in secure mode, this secure mode request is to
+ * update the key ladder id
+ */
+ if (feed->secure_mode.pid == sec_mode->pid && sec_mode->is_secured &&
+ feed->secure_mode.key_ladder_id != sec_mode->key_ladder_id &&
+ mpq_demux->sdmx_session_handle != SDMX_INVALID_SESSION_HANDLE) {
+ ret = sdmx_set_kl_ind(mpq_demux->sdmx_session_handle,
+ sec_mode->pid,
+ sec_mode->key_ladder_id);
+ if (ret) {
+ MPQ_DVB_ERR_PRINT(
+ "%s: FAILED to set key ladder, ret=%d\n",
+ __func__, ret);
+ ret = -ENODEV;
+ }
+ }
+
+ mutex_unlock(&mpq_demux->mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(mpq_dmx_set_secure_mode);
+
static void mpq_sdmx_prepare_filter_status(struct mpq_demux *mpq_demux,
struct sdmx_filter_status *filter_sts,
struct mpq_feed *mpq_feed)
@@ -3742,11 +3775,11 @@
__func__, filter_sts->metadata_fill_count,
filter_sts->metadata_write_offset);
- if (!mpq_dmx_is_video_feed(feed)) {
+ if (!dvb_dmx_is_video_feed(feed)) {
struct dvb_ringbuffer *buffer;
- if (mpq_dmx_is_sec_feed(feed) ||
- mpq_dmx_is_pcr_feed(feed)) {
+ if (dvb_dmx_is_sec_feed(feed) ||
+ dvb_dmx_is_pcr_feed(feed)) {
buffer = (struct dvb_ringbuffer *)
&mpq_feed->sdmx_buf;
} else {
@@ -4521,7 +4554,7 @@
int total_bytes_read = 0;
int limit = mpq_sdmx_proc_limit * mpq_demux->demux.ts_packet_size;
- do {
+ while (fill_count >= mpq_demux->demux.ts_packet_size) {
todo = fill_count > limit ? limit : fill_count;
ret = mpq_sdmx_process_buffer(mpq_demux, input, todo,
read_offset);
@@ -4541,7 +4574,7 @@
__func__, ret);
break;
}
- } while (fill_count > 0);
+ }
return total_bytes_read;
}
@@ -4584,6 +4617,7 @@
{
struct dvb_demux *dvb_demux;
struct mpq_demux *mpq_demux;
+ int ret = count;
if (demux == NULL)
return -EINVAL;
@@ -4591,20 +4625,35 @@
dvb_demux = demux->priv;
mpq_demux = dvb_demux->priv;
- if (mpq_sdmx_is_loaded()) {
- /* route through secure demux */
- return mpq_sdmx_write(mpq_demux,
+ /* Route through secure demux - process secure feeds if any exist */
+ if (mpq_sdmx_is_loaded() && mpq_demux->sdmx_filter_count) {
+ ret = mpq_sdmx_write(mpq_demux,
demux->dvr_input.priv_handle,
buf,
count);
- } else {
- /* route through sw filter */
- dvb_dmx_swfilter_format(dvb_demux, buf, count,
- dvb_demux->tsp_format);
- if (signal_pending(current))
- return -EINTR;
- return count;
+ if (ret < 0) {
+ MPQ_DVB_ERR_PRINT(
+ "%s: mpq_sdmx_write failed. ret = %d\n",
+ __func__, ret);
+ ret = count;
+ }
}
+
+ /*
+ * Route through sw filter - process non-secure feeds if any exist.
+ * For sw filter, should process the same amount of bytes the sdmx
+ * process managed to consume, unless some sdmx error occurred, for
+ * which should process the whole buffer
+ */
+ if (mpq_demux->num_active_feeds > mpq_demux->num_secure_feeds) {
+ dvb_dmx_swfilter_format(dvb_demux, buf, ret,
+ dvb_demux->tsp_format);
+ }
+
+ if (signal_pending(current))
+ return -EINTR;
+
+ return ret;
}
EXPORT_SYMBOL(mpq_dmx_write);
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.h b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.h
index 2c2420b..7affcc6 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.h
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.h
@@ -362,6 +362,9 @@
* @ion_client: ION demux client used to allocate memory from ION.
* @mutex: Lock used to protect against private feed data
* @feeds: mpq common feed object pool
+ * @num_active_feeds: Number of active mpq feeds
+ * @num_secure_feeds: Number of secure feeds (have a sdmx filter associated)
+ * currently allocated.
* @filters_status: Array holding buffers status for each secure demux filter.
* Used before each call to sdmx_process() to build up to date state.
* @sdmx_session_handle: Secure demux open session handle
@@ -406,6 +409,8 @@
struct ion_client *ion_client;
struct mutex mutex;
struct mpq_feed feeds[MPQ_MAX_DMX_FILES];
+ u32 num_active_feeds;
+ u32 num_secure_feeds;
struct sdmx_filter_status filters_status[MPQ_MAX_DMX_FILES];
int sdmx_session_handle;
int sdmx_session_ref_count;
@@ -615,86 +620,6 @@
int mpq_dmx_process_pcr_packet(struct dvb_demux_feed *feed, const u8 *buf);
/**
- * mpq_dmx_is_video_feed - Returns whether the PES feed
- * is video one.
- *
- * @feed: The feed to be checked.
- *
- * Return 1 if feed is video feed, 0 otherwise.
- */
-static inline int mpq_dmx_is_video_feed(struct dvb_demux_feed *feed)
-{
- if (feed->type != DMX_TYPE_TS)
- return 0;
-
- if (feed->ts_type & (~TS_DECODER))
- return 0;
-
- if ((feed->pes_type == DMX_TS_PES_VIDEO0) ||
- (feed->pes_type == DMX_TS_PES_VIDEO1) ||
- (feed->pes_type == DMX_TS_PES_VIDEO2) ||
- (feed->pes_type == DMX_TS_PES_VIDEO3))
- return 1;
-
- return 0;
-}
-
-/**
- * mpq_dmx_is_pcr_feed - Returns whether the PES feed
- * is PCR one.
- *
- * @feed: The feed to be checked.
- *
- * Return 1 if feed is PCR feed, 0 otherwise.
- */
-static inline int mpq_dmx_is_pcr_feed(struct dvb_demux_feed *feed)
-{
- if (feed->type != DMX_TYPE_TS)
- return 0;
-
- if (feed->ts_type & (~TS_DECODER))
- return 0;
-
- if ((feed->pes_type == DMX_TS_PES_PCR0) ||
- (feed->pes_type == DMX_TS_PES_PCR1) ||
- (feed->pes_type == DMX_TS_PES_PCR2) ||
- (feed->pes_type == DMX_TS_PES_PCR3))
- return 1;
-
- return 0;
-}
-
-/**
- * mpq_dmx_is_sec_feed - Returns whether this is a section feed
- *
- * @feed: The feed to be checked.
- *
- * Return 1 if feed is a section feed, 0 otherwise.
- */
-static inline int mpq_dmx_is_sec_feed(struct dvb_demux_feed *feed)
-{
- return (feed->type == DMX_TYPE_SEC);
-}
-
-/**
- * mpq_dmx_is_rec_feed - Returns whether this is a recording feed
- *
- * @feed: The feed to be checked.
- *
- * Return 1 if feed is recording feed, 0 otherwise.
- */
-static inline int mpq_dmx_is_rec_feed(struct dvb_demux_feed *feed)
-{
- if (feed->type != DMX_TYPE_TS)
- return 0;
-
- if (feed->ts_type & (TS_DECODER | TS_PAYLOAD_ONLY))
- return 0;
-
- return 1;
-}
-
-/**
* mpq_dmx_init_hw_statistics -
* Extend dvb-demux debugfs with HW statistics.
*
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tsif.c b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tsif.c
index b29759c..3d48441 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tsif.c
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tsif.c
@@ -518,10 +518,10 @@
"%s: warnning - len larger than one packet\n",
__func__);
- if (mpq_dmx_is_video_feed(feed))
+ if (dvb_dmx_is_video_feed(feed))
return mpq_dmx_process_video_packet(feed, buf);
- if (mpq_dmx_is_pcr_feed(feed))
+ if (dvb_dmx_is_pcr_feed(feed))
return mpq_dmx_process_pcr_packet(feed, buf);
return 0;
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tspp_v1.c b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tspp_v1.c
index 632e864..beb4cce 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tspp_v1.c
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tspp_v1.c
@@ -306,6 +306,30 @@
}
/**
+ * mpq_dmx_tspp_swfilter_desc - helper function
+ *
+ * Takes a tspp buffer descriptor and send it to the SW filter for demuxing,
+ * one TS packet at a time.
+ *
+ * @mpq_demux - mpq demux object
+ * @tspp_data_desc - tspp buffer descriptor
+ */
+static inline void mpq_dmx_tspp_swfilter_desc(struct mpq_demux *mpq_demux,
+ const struct tspp_data_descriptor *tspp_data_desc)
+{
+ u32 notif_size;
+ int i;
+
+ notif_size = tspp_data_desc->size / TSPP_RAW_TTS_SIZE;
+ for (i = 0; i < notif_size; i++)
+ dvb_dmx_swfilter_packet(&mpq_demux->demux,
+ ((u8 *)tspp_data_desc->virt_base) +
+ i * TSPP_RAW_TTS_SIZE,
+ ((u8 *)tspp_data_desc->virt_base) +
+ i * TSPP_RAW_TTS_SIZE + TSPP_RAW_SIZE);
+}
+
+/**
* Demux TS packets from TSPP by secure-demux.
* The fucntion assumes the buffer is physically contiguous
* and that TSPP descriptors are continuous in memory.
@@ -320,37 +344,46 @@
struct sdmx_buff_descr input;
size_t aggregate_len = 0;
size_t aggregate_count = 0;
- phys_addr_t buff_start_addr;
- phys_addr_t buff_current_addr = 0;
+ phys_addr_t buff_start_addr_phys;
+ phys_addr_t buff_current_addr_phys = 0;
+ u32 notif_size;
int i;
while ((tspp_data_desc = tspp_get_buffer(0, channel_id)) != NULL) {
if (0 == aggregate_count)
- buff_current_addr = tspp_data_desc->phys_base;
+ buff_current_addr_phys = tspp_data_desc->phys_base;
+ notif_size = tspp_data_desc->size / TSPP_RAW_TTS_SIZE;
mpq_dmx_tspp_info.tsif[tsif].aggregate_ids[aggregate_count] =
tspp_data_desc->id;
aggregate_len += tspp_data_desc->size;
aggregate_count++;
- mpq_demux->hw_notification_size +=
- tspp_data_desc->size / TSPP_RAW_TTS_SIZE;
+ mpq_demux->hw_notification_size += notif_size;
+
+ /* Let SW filter process only if it might be relevant */
+ if (mpq_demux->num_active_feeds > mpq_demux->num_secure_feeds)
+ mpq_dmx_tspp_swfilter_desc(mpq_demux, tspp_data_desc);
+
}
if (!aggregate_count)
return;
- buff_start_addr = mpq_dmx_tspp_info.tsif[tsif].ch_mem_heap_phys_base;
- input.base_addr = (void *)buff_start_addr;
+ buff_start_addr_phys =
+ mpq_dmx_tspp_info.tsif[tsif].ch_mem_heap_phys_base;
+ input.base_addr = (void *)buff_start_addr_phys;
input.size = mpq_dmx_tspp_info.tsif[tsif].buffer_count *
TSPP_DESCRIPTOR_SIZE;
- MPQ_DVB_DBG_PRINT(
- "%s: Processing %d descriptors: %d bytes at start address 0x%x, read offset %d\n",
- __func__, aggregate_count, aggregate_len,
- (unsigned int)input.base_addr,
- buff_current_addr - buff_start_addr);
+ if (mpq_sdmx_is_loaded() && mpq_demux->sdmx_filter_count) {
+ MPQ_DVB_DBG_PRINT(
+ "%s: SDMX Processing %d descriptors: %d bytes at start address 0x%x, read offset %d\n",
+ __func__, aggregate_count, aggregate_len,
+ (unsigned int)input.base_addr,
+ buff_current_addr_phys - buff_start_addr_phys);
- mpq_sdmx_process(mpq_demux, &input, aggregate_len,
- buff_current_addr - buff_start_addr);
+ mpq_sdmx_process(mpq_demux, &input, aggregate_len,
+ buff_current_addr_phys - buff_start_addr_phys);
+ }
for (i = 0; i < aggregate_count; i++)
tspp_release_buffer(0, channel_id,
@@ -373,7 +406,6 @@
int channel_id;
int ref_count;
int ret;
- int j;
do {
ret = wait_event_interruptible(
@@ -427,13 +459,8 @@
TSPP_RAW_TTS_SIZE;
mpq_demux->hw_notification_size += notif_size;
- for (j = 0; j < notif_size; j++)
- dvb_dmx_swfilter_packet(
- &mpq_demux->demux,
- ((u8 *)tspp_data_desc->virt_base) +
- j * TSPP_RAW_TTS_SIZE,
- ((u8 *)tspp_data_desc->virt_base) +
- j * TSPP_RAW_TTS_SIZE + TSPP_RAW_SIZE);
+ mpq_dmx_tspp_swfilter_desc(mpq_demux,
+ tspp_data_desc);
/*
* Notify TSPP that the buffer
* is no longer needed
@@ -1554,10 +1581,10 @@
"%s: warnning - len larger than one packet\n",
__func__);
- if (mpq_dmx_is_video_feed(feed))
+ if (dvb_dmx_is_video_feed(feed))
return mpq_dmx_process_video_packet(feed, buf);
- if (mpq_dmx_is_pcr_feed(feed))
+ if (dvb_dmx_is_pcr_feed(feed))
return mpq_dmx_process_pcr_packet(feed, buf);
return 0;
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_sdmx.h b/drivers/media/platform/msm/dvb/demux/mpq_sdmx.h
index d292992..5b91436 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_sdmx.h
+++ b/drivers/media/platform/msm/dvb/demux/mpq_sdmx.h
@@ -177,9 +177,7 @@
/* Payload length */
u32 payload_length;
- /* Total metadata length (including this header, plus optional
- * additional metadata.
- */
+ /* Number of meta data bytes immediately following this header */
u32 metadata_length;
};
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index ea0eb7b..1e0de89 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -1069,7 +1069,15 @@
int i, ret = 0;
/* buf sync */
for (i = 0; i < mfd->acq_fen_cnt; i++) {
- ret = sync_fence_wait(mfd->acq_fen[i], WAIT_FENCE_TIMEOUT);
+ ret = sync_fence_wait(mfd->acq_fen[i],
+ WAIT_FENCE_FIRST_TIMEOUT);
+ if (ret == -ETIME) {
+ pr_warn("sync_fence_wait timed out! ");
+ pr_cont("Waiting %ld more seconds\n",
+ WAIT_FENCE_FINAL_TIMEOUT/MSEC_PER_SEC);
+ ret = sync_fence_wait(mfd->acq_fen[i],
+ WAIT_FENCE_FINAL_TIMEOUT);
+ }
if (ret < 0) {
pr_err("%s: sync_fence_wait failed! ret = %x\n",
__func__, ret);
diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h
index c4e837e..db2e305 100644
--- a/drivers/video/msm/mdss/mdss_fb.h
+++ b/drivers/video/msm/mdss/mdss_fb.h
@@ -27,10 +27,11 @@
#define MSM_FB_MAX_DEV_LIST 32
#define MSM_FB_ENABLE_DBGFS
-/* 900 ms for fence time out */
-#define WAIT_FENCE_TIMEOUT 900
-/* 950 ms for display operation time out */
-#define WAIT_DISP_OP_TIMEOUT 950
+#define WAIT_FENCE_FIRST_TIMEOUT MSEC_PER_SEC
+#define WAIT_FENCE_FINAL_TIMEOUT (10 * MSEC_PER_SEC)
+/* Display op timeout should be greater than total timeout */
+#define WAIT_DISP_OP_TIMEOUT ((WAIT_FENCE_FIRST_TIMEOUT + \
+ WAIT_FENCE_FINAL_TIMEOUT) * MDP_MAX_FENCE_FD)
#ifndef MAX
#define MAX(x, y) (((x) > (y)) ? (x) : (y))