tspp: improve tspp_open_stream/tspp_close_stream behavior
The TSPP driver's kernel API supports opening and closing a TSPP stream using the tspp_open_stream/tspp_close_stream API functions. This commit fixes a few minor issues with the behavior and usage of this API. tspp_open_stream and tspp_close_stream were fixed to connect/disconnect the appropriate TSIF source based on the TSIF reference count. The call to tspp_close_stream from within tspp_close_channel was removed, since a kernel driver that uses the TSPP driver API is expected to call tspp_close_stream explicitly, and not rely on the TSPP driver to close the stream implicitly when the channel is closed. An ioctl was added to allow user-space application to close the stream. Change-Id: If49b440d9d83c8bba54aeabc18e8f06b3cc11b3e Signed-off-by: Liron Kuch <lkuch@codeaurora.org>
This commit is contained in:
parent
4a995e781b
commit
c2392df88a
|
@ -1433,8 +1433,8 @@ static int mpq_tspp_dmx_remove_channel(struct dvb_demux_feed *feed)
|
|||
if (*channel_ref_count == 0) {
|
||||
/* channel is not used any more, release it */
|
||||
tspp_unregister_notification(0, channel_id);
|
||||
tspp_close_channel(0, channel_id);
|
||||
tspp_close_stream(0, channel_id);
|
||||
tspp_close_channel(0, channel_id);
|
||||
atomic_set(data_cnt, 0);
|
||||
|
||||
if (allocation_mode == MPQ_DMX_TSPP_CONTIGUOUS_PHYS_ALLOC)
|
||||
|
|
|
@ -1319,10 +1319,12 @@ int tspp_open_stream(u32 dev, u32 channel_id,
|
|||
pr_err("tspp: error starting tsif0");
|
||||
return -EBUSY;
|
||||
}
|
||||
val = readl_relaxed(pdev->base + TSPP_CONTROL);
|
||||
writel_relaxed(val & ~TSPP_CONTROL_TSP_TSIF0_SRC_DIS,
|
||||
pdev->base + TSPP_CONTROL);
|
||||
wmb();
|
||||
if (pdev->tsif[0].ref_count == 1) {
|
||||
val = readl_relaxed(pdev->base + TSPP_CONTROL);
|
||||
writel_relaxed(val & ~TSPP_CONTROL_TSP_TSIF0_SRC_DIS,
|
||||
pdev->base + TSPP_CONTROL);
|
||||
wmb();
|
||||
}
|
||||
break;
|
||||
case TSPP_SOURCE_TSIF1:
|
||||
if (tspp_config_gpios(pdev, channel->src, 1) != 0) {
|
||||
|
@ -1334,10 +1336,12 @@ int tspp_open_stream(u32 dev, u32 channel_id,
|
|||
pr_err("tspp: error starting tsif1");
|
||||
return -EBUSY;
|
||||
}
|
||||
val = readl_relaxed(pdev->base + TSPP_CONTROL);
|
||||
writel_relaxed(val & ~TSPP_CONTROL_TSP_TSIF1_SRC_DIS,
|
||||
pdev->base + TSPP_CONTROL);
|
||||
wmb();
|
||||
if (pdev->tsif[1].ref_count == 1) {
|
||||
val = readl_relaxed(pdev->base + TSPP_CONTROL);
|
||||
writel_relaxed(val & ~TSPP_CONTROL_TSP_TSIF1_SRC_DIS,
|
||||
pdev->base + TSPP_CONTROL);
|
||||
wmb();
|
||||
}
|
||||
break;
|
||||
case TSPP_SOURCE_MEM:
|
||||
break;
|
||||
|
@ -1363,6 +1367,7 @@ EXPORT_SYMBOL(tspp_open_stream);
|
|||
int tspp_close_stream(u32 dev, u32 channel_id)
|
||||
{
|
||||
u32 val;
|
||||
u32 prev_ref_count;
|
||||
struct tspp_device *pdev;
|
||||
struct tspp_channel *channel;
|
||||
|
||||
|
@ -1379,23 +1384,30 @@ int tspp_close_stream(u32 dev, u32 channel_id)
|
|||
|
||||
switch (channel->src) {
|
||||
case TSPP_SOURCE_TSIF0:
|
||||
prev_ref_count = pdev->tsif[0].ref_count;
|
||||
tspp_stop_tsif(&pdev->tsif[0]);
|
||||
if (tspp_config_gpios(pdev, channel->src, 0) != 0)
|
||||
pr_err("tspp: error disabling tsif0 GPIOs\n");
|
||||
|
||||
val = readl_relaxed(pdev->base + TSPP_CONTROL);
|
||||
writel_relaxed(val | TSPP_CONTROL_TSP_TSIF0_SRC_DIS,
|
||||
pdev->base + TSPP_CONTROL);
|
||||
wmb();
|
||||
if (prev_ref_count == 1) {
|
||||
val = readl_relaxed(pdev->base + TSPP_CONTROL);
|
||||
writel_relaxed(val | TSPP_CONTROL_TSP_TSIF0_SRC_DIS,
|
||||
pdev->base + TSPP_CONTROL);
|
||||
wmb();
|
||||
}
|
||||
break;
|
||||
case TSPP_SOURCE_TSIF1:
|
||||
prev_ref_count = pdev->tsif[1].ref_count;
|
||||
tspp_stop_tsif(&pdev->tsif[1]);
|
||||
if (tspp_config_gpios(pdev, channel->src, 0) != 0)
|
||||
pr_err("tspp: error disabling tsif0 GPIOs\n");
|
||||
|
||||
val = readl_relaxed(pdev->base + TSPP_CONTROL);
|
||||
writel_relaxed(val | TSPP_CONTROL_TSP_TSIF1_SRC_DIS,
|
||||
pdev->base + TSPP_CONTROL);
|
||||
if (prev_ref_count == 1) {
|
||||
val = readl_relaxed(pdev->base + TSPP_CONTROL);
|
||||
writel_relaxed(val | TSPP_CONTROL_TSP_TSIF1_SRC_DIS,
|
||||
pdev->base + TSPP_CONTROL);
|
||||
wmb();
|
||||
}
|
||||
break;
|
||||
case TSPP_SOURCE_MEM:
|
||||
break;
|
||||
|
@ -1595,9 +1607,6 @@ int tspp_close_channel(u32 dev, u32 channel_id)
|
|||
}
|
||||
channel->filter_count = 0;
|
||||
|
||||
/* stop the stream */
|
||||
tspp_close_stream(dev, channel->id);
|
||||
|
||||
/* disconnect the bam */
|
||||
if (sps_disconnect(channel->pipe) != 0)
|
||||
pr_warn("tspp: Error freeing sps endpoint (%i)", channel->id);
|
||||
|
@ -2435,7 +2444,7 @@ static long tspp_ioctl(struct file *filp,
|
|||
channel = filp->private_data;
|
||||
dev = channel->pdev->pdev->id;
|
||||
|
||||
if (!param1)
|
||||
if ((param0 != TSPP_IOCTL_CLOSE_STREAM) && !param1)
|
||||
return -EINVAL;
|
||||
|
||||
switch (param0) {
|
||||
|
@ -2502,6 +2511,9 @@ static long tspp_ioctl(struct file *filp,
|
|||
sizeof(struct tspp_buffer)) == 0)
|
||||
rc = tspp_set_buffer_size(channel, &b);
|
||||
break;
|
||||
case TSPP_IOCTL_CLOSE_STREAM:
|
||||
rc = tspp_close_stream(dev, channel->id);
|
||||
break;
|
||||
default:
|
||||
pr_err("tspp: Unknown ioctl %i", param0);
|
||||
}
|
||||
|
|
|
@ -88,5 +88,7 @@ struct tspp_buffer {
|
|||
_IOW(TSPP_IOCTL_BASE, 5, struct tspp_system_keys)
|
||||
#define TSPP_IOCTL_BUFFER_SIZE \
|
||||
_IOW(TSPP_IOCTL_BASE, 6, struct tspp_buffer)
|
||||
#define TSPP_IOCTL_CLOSE_STREAM \
|
||||
_IO(TSPP_IOCTL_BASE, 7)
|
||||
|
||||
#endif /* _TSPP_H_ */
|
||||
|
|
Loading…
Reference in New Issue