| .. | .. |
|---|
| 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; |
|---|