Skip to content

Commit

Permalink
Merge branch 'patchwork' into v4l_for_linus
Browse files Browse the repository at this point in the history
* patchwork:
  [media] s5k4ecgx: select CRC32 helper
  [media] dvb: avoid warning in dvb_net
  [media] v4l: tvp5150: Don't override output pinmuxing at stream on/off time
  [media] v4l: tvp5150: Fix comment regarding output pin muxing
  [media] v4l: tvp5150: Reset device at probe time, not in get/set format handlers
  [media] pctv452e: move buffer to heap, no mutex
  [media] media/cobalt: use pci_irq_allocate_vectors
  [media] cec: fix race between configuring and unconfiguring
  [media] cec: move cec_report_phys_addr into cec_config_thread_func
  [media] cec: replace cec_report_features by cec_fill_msg_report_features
  [media] cec: update log_addr[] before finishing configuration
  [media] cec: CEC_MSG_GIVE_FEATURES should abort for CEC version < 2
  [media] cec: when canceling a message, don't overwrite old status info
  [media] cec: fix report_current_latency
  [media] smiapp: Make suspend and resume functions __maybe_unused
  [media] smiapp: Implement power-on and power-off sequences without runtime PM
  • Loading branch information
Mauro Carvalho Chehab committed Dec 26, 2016
2 parents 65390ea + c739c0a commit 0e0694f
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 175 deletions.
103 changes: 52 additions & 51 deletions drivers/media/cec/cec-adap.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@

#include "cec-priv.h"

static int cec_report_features(struct cec_adapter *adap, unsigned int la_idx);
static int cec_report_phys_addr(struct cec_adapter *adap, unsigned int la_idx);
static void cec_fill_msg_report_features(struct cec_adapter *adap,
struct cec_msg *msg,
unsigned int la_idx);

/*
* 400 ms is the time it takes for one 16 byte message to be
Expand Down Expand Up @@ -288,10 +289,10 @@ static void cec_data_cancel(struct cec_data *data)

/* Mark it as an error */
data->msg.tx_ts = ktime_get_ns();
data->msg.tx_status = CEC_TX_STATUS_ERROR |
CEC_TX_STATUS_MAX_RETRIES;
data->msg.tx_status |= CEC_TX_STATUS_ERROR |
CEC_TX_STATUS_MAX_RETRIES;
data->msg.tx_error_cnt++;
data->attempts = 0;
data->msg.tx_error_cnt = 1;
/* Queue transmitted message for monitoring purposes */
cec_queue_msg_monitor(data->adap, &data->msg, 1);

Expand Down Expand Up @@ -851,7 +852,7 @@ static const u8 cec_msg_size[256] = {
[CEC_MSG_REQUEST_ARC_TERMINATION] = 2 | DIRECTED,
[CEC_MSG_TERMINATE_ARC] = 2 | DIRECTED,
[CEC_MSG_REQUEST_CURRENT_LATENCY] = 4 | BCAST,
[CEC_MSG_REPORT_CURRENT_LATENCY] = 7 | BCAST,
[CEC_MSG_REPORT_CURRENT_LATENCY] = 6 | BCAST,
[CEC_MSG_CDC_MESSAGE] = 2 | BCAST,
};

Expand Down Expand Up @@ -1250,30 +1251,49 @@ static int cec_config_thread_func(void *arg)
for (i = 1; i < las->num_log_addrs; i++)
las->log_addr[i] = CEC_LOG_ADDR_INVALID;
}
for (i = las->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++)
las->log_addr[i] = CEC_LOG_ADDR_INVALID;
adap->is_configured = true;
adap->is_configuring = false;
cec_post_state_event(adap);
mutex_unlock(&adap->lock);

/*
* Now post the Report Features and Report Physical Address broadcast
* messages. Note that these are non-blocking transmits, meaning that
* they are just queued up and once adap->lock is unlocked the main
* thread will kick in and start transmitting these.
*
* If after this function is done (but before one or more of these
* messages are actually transmitted) the CEC adapter is unconfigured,
* then any remaining messages will be dropped by the main thread.
*/
for (i = 0; i < las->num_log_addrs; i++) {
struct cec_msg msg = {};

if (las->log_addr[i] == CEC_LOG_ADDR_INVALID ||
(las->flags & CEC_LOG_ADDRS_FL_CDC_ONLY))
continue;

/*
* Report Features must come first according
* to CEC 2.0
*/
if (las->log_addr[i] != CEC_LOG_ADDR_UNREGISTERED)
cec_report_features(adap, i);
cec_report_phys_addr(adap, i);
msg.msg[0] = (las->log_addr[i] << 4) | 0x0f;

/* Report Features must come first according to CEC 2.0 */
if (las->log_addr[i] != CEC_LOG_ADDR_UNREGISTERED &&
adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0) {
cec_fill_msg_report_features(adap, &msg, i);
cec_transmit_msg_fh(adap, &msg, NULL, false);
}

/* Report Physical Address */
cec_msg_report_physical_addr(&msg, adap->phys_addr,
las->primary_device_type[i]);
dprintk(2, "config: la %d pa %x.%x.%x.%x\n",
las->log_addr[i],
cec_phys_addr_exp(adap->phys_addr));
cec_transmit_msg_fh(adap, &msg, NULL, false);
}
for (i = las->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++)
las->log_addr[i] = CEC_LOG_ADDR_INVALID;
mutex_lock(&adap->lock);
adap->kthread_config = NULL;
mutex_unlock(&adap->lock);
complete(&adap->config_completion);
mutex_unlock(&adap->lock);
return 0;

unconfigure:
Expand Down Expand Up @@ -1526,52 +1546,32 @@ EXPORT_SYMBOL_GPL(cec_s_log_addrs);

/* High-level core CEC message handling */

/* Transmit the Report Features message */
static int cec_report_features(struct cec_adapter *adap, unsigned int la_idx)
/* Fill in the Report Features message */
static void cec_fill_msg_report_features(struct cec_adapter *adap,
struct cec_msg *msg,
unsigned int la_idx)
{
struct cec_msg msg = { };
const struct cec_log_addrs *las = &adap->log_addrs;
const u8 *features = las->features[la_idx];
bool op_is_dev_features = false;
unsigned int idx;

/* This is 2.0 and up only */
if (adap->log_addrs.cec_version < CEC_OP_CEC_VERSION_2_0)
return 0;

/* Report Features */
msg.msg[0] = (las->log_addr[la_idx] << 4) | 0x0f;
msg.len = 4;
msg.msg[1] = CEC_MSG_REPORT_FEATURES;
msg.msg[2] = adap->log_addrs.cec_version;
msg.msg[3] = las->all_device_types[la_idx];
msg->msg[0] = (las->log_addr[la_idx] << 4) | 0x0f;
msg->len = 4;
msg->msg[1] = CEC_MSG_REPORT_FEATURES;
msg->msg[2] = adap->log_addrs.cec_version;
msg->msg[3] = las->all_device_types[la_idx];

/* Write RC Profiles first, then Device Features */
for (idx = 0; idx < ARRAY_SIZE(las->features[0]); idx++) {
msg.msg[msg.len++] = features[idx];
msg->msg[msg->len++] = features[idx];
if ((features[idx] & CEC_OP_FEAT_EXT) == 0) {
if (op_is_dev_features)
break;
op_is_dev_features = true;
}
}
return cec_transmit_msg(adap, &msg, false);
}

/* Transmit the Report Physical Address message */
static int cec_report_phys_addr(struct cec_adapter *adap, unsigned int la_idx)
{
const struct cec_log_addrs *las = &adap->log_addrs;
struct cec_msg msg = { };

/* Report Physical Address */
msg.msg[0] = (las->log_addr[la_idx] << 4) | 0x0f;
cec_msg_report_physical_addr(&msg, adap->phys_addr,
las->primary_device_type[la_idx]);
dprintk(2, "config: la %d pa %x.%x.%x.%x\n",
las->log_addr[la_idx],
cec_phys_addr_exp(adap->phys_addr));
return cec_transmit_msg(adap, &msg, false);
}

/* Transmit the Feature Abort message */
Expand Down Expand Up @@ -1777,9 +1777,10 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
}

case CEC_MSG_GIVE_FEATURES:
if (adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0)
return cec_report_features(adap, la_idx);
return 0;
if (adap->log_addrs.cec_version < CEC_OP_CEC_VERSION_2_0)
return cec_feature_abort(adap, msg);
cec_fill_msg_report_features(adap, &tx_cec_msg, la_idx);
return cec_transmit_msg(adap, &tx_cec_msg, false);

default:
/*
Expand Down
15 changes: 5 additions & 10 deletions drivers/media/dvb-core/dvb_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,9 @@ static void dvb_net_ule_check_crc(struct dvb_net_ule_handle *h,
skb_copy_from_linear_data(h->priv->ule_skb, dest_addr,
ETH_ALEN);
skb_pull(h->priv->ule_skb, ETH_ALEN);
} else {
/* dest_addr buffer is only valid if h->priv->ule_dbit == 0 */
eth_zero_addr(dest_addr);
}

/* Handle ULE Extension Headers. */
Expand Down Expand Up @@ -750,16 +753,8 @@ static void dvb_net_ule_check_crc(struct dvb_net_ule_handle *h,
if (!h->priv->ule_bridged) {
skb_push(h->priv->ule_skb, ETH_HLEN);
h->ethh = (struct ethhdr *)h->priv->ule_skb->data;
if (!h->priv->ule_dbit) {
/*
* dest_addr buffer is only valid if
* h->priv->ule_dbit == 0
*/
memcpy(h->ethh->h_dest, dest_addr, ETH_ALEN);
eth_zero_addr(h->ethh->h_source);
} else /* zeroize source and dest */
memset(h->ethh, 0, ETH_ALEN * 2);

memcpy(h->ethh->h_dest, dest_addr, ETH_ALEN);
eth_zero_addr(h->ethh->h_source);
h->ethh->h_proto = htons(h->priv->ule_sndu_type);
}
/* else: skb is in correct state; nothing to do. */
Expand Down
1 change: 1 addition & 0 deletions drivers/media/i2c/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,7 @@ config VIDEO_S5K6A3
config VIDEO_S5K4ECGX
tristate "Samsung S5K4ECGX sensor support"
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
select CRC32
---help---
This is a V4L2 sensor-level driver for Samsung S5K4ECGX 5M
camera sensor with an embedded SoC image signal processor.
Expand Down
33 changes: 12 additions & 21 deletions drivers/media/i2c/smiapp/smiapp-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2741,9 +2741,7 @@ static const struct v4l2_subdev_internal_ops smiapp_internal_ops = {
* I2C Driver
*/

#ifdef CONFIG_PM

static int smiapp_suspend(struct device *dev)
static int __maybe_unused smiapp_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct v4l2_subdev *subdev = i2c_get_clientdata(client);
Expand All @@ -2768,7 +2766,7 @@ static int smiapp_suspend(struct device *dev)
return 0;
}

static int smiapp_resume(struct device *dev)
static int __maybe_unused smiapp_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct v4l2_subdev *subdev = i2c_get_clientdata(client);
Expand All @@ -2783,13 +2781,6 @@ static int smiapp_resume(struct device *dev)
return rval;
}

#else

#define smiapp_suspend NULL
#define smiapp_resume NULL

#endif /* CONFIG_PM */

static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev)
{
struct smiapp_hwconfig *hwcfg;
Expand Down Expand Up @@ -2913,13 +2904,9 @@ static int smiapp_probe(struct i2c_client *client,
if (IS_ERR(sensor->xshutdown))
return PTR_ERR(sensor->xshutdown);

pm_runtime_enable(&client->dev);

rval = pm_runtime_get_sync(&client->dev);
if (rval < 0) {
rval = -ENODEV;
goto out_power_off;
}
rval = smiapp_power_on(&client->dev);
if (rval < 0)
return rval;

rval = smiapp_identify_module(sensor);
if (rval) {
Expand Down Expand Up @@ -3100,6 +3087,9 @@ static int smiapp_probe(struct i2c_client *client,
if (rval < 0)
goto out_media_entity_cleanup;

pm_runtime_set_active(&client->dev);
pm_runtime_get_noresume(&client->dev);
pm_runtime_enable(&client->dev);
pm_runtime_set_autosuspend_delay(&client->dev, 1000);
pm_runtime_use_autosuspend(&client->dev);
pm_runtime_put_autosuspend(&client->dev);
Expand All @@ -3113,8 +3103,7 @@ static int smiapp_probe(struct i2c_client *client,
smiapp_cleanup(sensor);

out_power_off:
pm_runtime_put(&client->dev);
pm_runtime_disable(&client->dev);
smiapp_power_off(&client->dev);

return rval;
}
Expand All @@ -3127,8 +3116,10 @@ static int smiapp_remove(struct i2c_client *client)

v4l2_async_unregister_subdev(subdev);

pm_runtime_suspend(&client->dev);
pm_runtime_disable(&client->dev);
if (!pm_runtime_status_suspended(&client->dev))
smiapp_power_off(&client->dev);
pm_runtime_set_suspended(&client->dev);

for (i = 0; i < sensor->ssds_used; i++) {
v4l2_device_unregister_subdev(&sensor->ssds[i].sd);
Expand Down
Loading

0 comments on commit 0e0694f

Please sign in to comment.