.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * ispccdc.c |
---|
3 | 4 | * |
---|
.. | .. |
---|
8 | 9 | * |
---|
9 | 10 | * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com> |
---|
10 | 11 | * Sakari Ailus <sakari.ailus@iki.fi> |
---|
11 | | - * |
---|
12 | | - * This program is free software; you can redistribute it and/or modify |
---|
13 | | - * it under the terms of the GNU General Public License version 2 as |
---|
14 | | - * published by the Free Software Foundation. |
---|
15 | 12 | */ |
---|
16 | 13 | |
---|
17 | 14 | #include <linux/module.h> |
---|
.. | .. |
---|
1315 | 1312 | { |
---|
1316 | 1313 | struct isp_device *isp = to_isp_device(ccdc); |
---|
1317 | 1314 | |
---|
| 1315 | + /* Avoid restarting the CCDC when streaming is stopping. */ |
---|
| 1316 | + if (enable && ccdc->stopping & CCDC_STOP_REQUEST) |
---|
| 1317 | + return; |
---|
| 1318 | + |
---|
1318 | 1319 | isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_PCR, |
---|
1319 | 1320 | ISPCCDC_PCR_EN, enable ? ISPCCDC_PCR_EN : 0); |
---|
1320 | 1321 | |
---|
.. | .. |
---|
1594 | 1595 | return 0; |
---|
1595 | 1596 | |
---|
1596 | 1597 | /* We're in continuous mode, and memory writes were disabled due to a |
---|
1597 | | - * buffer underrun. Reenable them now that we have a buffer. The buffer |
---|
| 1598 | + * buffer underrun. Re-enable them now that we have a buffer. The buffer |
---|
1598 | 1599 | * address has been set in ccdc_video_queue. |
---|
1599 | 1600 | */ |
---|
1600 | 1601 | if (ccdc->state == ISP_PIPELINE_STREAM_CONTINUOUS && ccdc->underrun) { |
---|
.. | .. |
---|
1609 | 1610 | omap3isp_pipeline_cancel_stream(pipe); |
---|
1610 | 1611 | return 0; |
---|
1611 | 1612 | } |
---|
| 1613 | + |
---|
| 1614 | + /* Don't restart CCDC if we're just about to stop streaming. */ |
---|
| 1615 | + if (ccdc->state == ISP_PIPELINE_STREAM_CONTINUOUS && |
---|
| 1616 | + ccdc->stopping & CCDC_STOP_REQUEST) |
---|
| 1617 | + return 0; |
---|
1612 | 1618 | |
---|
1613 | 1619 | if (!ccdc_has_all_fields(ccdc)) |
---|
1614 | 1620 | return 1; |
---|
.. | .. |
---|
1664 | 1670 | spin_unlock_irqrestore(&ccdc->lock, flags); |
---|
1665 | 1671 | } |
---|
1666 | 1672 | |
---|
1667 | | - if (ccdc->output & CCDC_OUTPUT_MEMORY) |
---|
1668 | | - restart = ccdc_isr_buffer(ccdc); |
---|
1669 | | - |
---|
1670 | 1673 | spin_lock_irqsave(&ccdc->lock, flags); |
---|
1671 | | - |
---|
1672 | 1674 | if (ccdc_handle_stopping(ccdc, CCDC_EVENT_VD0)) { |
---|
1673 | 1675 | spin_unlock_irqrestore(&ccdc->lock, flags); |
---|
1674 | 1676 | return; |
---|
1675 | 1677 | } |
---|
| 1678 | + |
---|
| 1679 | + if (ccdc->output & CCDC_OUTPUT_MEMORY) |
---|
| 1680 | + restart = ccdc_isr_buffer(ccdc); |
---|
1676 | 1681 | |
---|
1677 | 1682 | if (!ccdc->shadow_update) |
---|
1678 | 1683 | ccdc_apply_controls(ccdc); |
---|
.. | .. |
---|
1712 | 1717 | * data to memory the CCDC and LSC are stopped immediately but |
---|
1713 | 1718 | * without change the CCDC stopping state machine. The CCDC |
---|
1714 | 1719 | * stopping state machine should be used only when user request |
---|
1715 | | - * for stopping is received (SINGLESHOT is an exeption). |
---|
| 1720 | + * for stopping is received (SINGLESHOT is an exception). |
---|
1716 | 1721 | */ |
---|
1717 | 1722 | switch (ccdc->state) { |
---|
1718 | 1723 | case ISP_PIPELINE_STREAM_SINGLESHOT: |
---|
.. | .. |
---|
2642 | 2647 | |
---|
2643 | 2648 | v4l2_subdev_init(sd, &ccdc_v4l2_ops); |
---|
2644 | 2649 | sd->internal_ops = &ccdc_v4l2_internal_ops; |
---|
2645 | | - strlcpy(sd->name, "OMAP3 ISP CCDC", sizeof(sd->name)); |
---|
| 2650 | + strscpy(sd->name, "OMAP3 ISP CCDC", sizeof(sd->name)); |
---|
2646 | 2651 | sd->grp_id = 1 << 16; /* group ID for isp subdevs */ |
---|
2647 | 2652 | v4l2_set_subdevdata(sd, ccdc); |
---|
2648 | 2653 | sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE; |
---|