aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2019-09-12 23:28:59 -0700
committerLinux Build Service Account <lnxbuild@localhost>2019-09-12 23:28:59 -0700
commit4e6e0aac86151e6576075542b895a956e227c62c (patch)
treeb9c6c4d8c885ed5598f41d654dbeff789ed03d1b
parentc3c31b96f10bde1341475d9fdcc4907942a42d05 (diff)
parent24a35b53f5bef0b1360b84777f3523505fa83c1d (diff)
Merge 24a35b53f5bef0b1360b84777f3523505fa83c1d on remote branchLA.UM.7.1.r1-16600-sm8150.0
Change-Id: I3aaf70567cf782280a876ee0e549a7cc08c5bf9b
-rw-r--r--drivers/char/diag/diagchar.h2
-rw-r--r--drivers/char/diag/diagchar_core.c2
-rw-r--r--drivers/char/diag/diagfwd_rpmsg.c99
-rw-r--r--drivers/media/platform/msm/camera/cam_core/cam_context.c49
-rw-r--r--drivers/media/platform/msm/camera/cam_core/cam_context.h32
-rw-r--r--drivers/media/platform/msm/camera/cam_core/cam_context_utils.c40
-rw-r--r--drivers/media/platform/msm/camera/cam_core/cam_context_utils.h5
-rw-r--r--drivers/media/platform/msm/camera/cam_core/cam_hw_mgr_intf.h17
-rw-r--r--drivers/media/platform/msm/camera/cam_core/cam_node.c75
-rw-r--r--drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c64
-rw-r--r--drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h8
-rw-r--r--drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c25
-rw-r--r--drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_interface.h26
-rw-r--r--drivers/media/platform/msm/camera/cam_utils/cam_common_util.c21
-rw-r--r--drivers/media/platform/msm/camera/cam_utils/cam_common_util.h24
-rw-r--r--drivers/mmc/core/block.c4
-rw-r--r--drivers/mmc/core/core.c55
-rw-r--r--drivers/mmc/core/sd.c42
-rw-r--r--drivers/mmc/core/slot-gpio.c4
-rw-r--r--drivers/usb/gadget/function/f_fs.c1
-rw-r--r--drivers/usb/phy/phy-msm-snps-hs.c4
-rw-r--r--include/linux/mmc/host.h6
-rw-r--r--include/uapi/media/cam_defs.h25
-rw-r--r--include/uapi/media/cam_req_mgr.h1
24 files changed, 525 insertions, 106 deletions
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index 08e1013cf31e..0478c88757d6 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -617,7 +617,7 @@ struct diagchar_dev {
int dci_tag;
int dci_client_id[MAX_DCI_CLIENTS];
struct mutex dci_mutex;
- spinlock_t rpmsginfo_lock[NUM_PERIPHERALS];
+ struct mutex rpmsginfo_mutex[NUM_PERIPHERALS];
int num_dci_client;
unsigned char *apps_dci_buf;
int dci_state;
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 2e4bb65b26a5..5ae766de94b5 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -4281,7 +4281,7 @@ static int __init diagchar_init(void)
mutex_init(&driver->hdlc_recovery_mutex);
for (i = 0; i < NUM_PERIPHERALS; i++) {
mutex_init(&driver->diagfwd_channel_mutex[i]);
- spin_lock_init(&driver->rpmsginfo_lock[i]);
+ mutex_init(&driver->rpmsginfo_mutex[i]);
driver->diag_id_sent[i] = 0;
}
init_waitqueue_head(&driver->wait_q);
diff --git a/drivers/char/diag/diagfwd_rpmsg.c b/drivers/char/diag/diagfwd_rpmsg.c
index 36ea0b7a2daa..dbad9568e9b7 100644
--- a/drivers/char/diag/diagfwd_rpmsg.c
+++ b/drivers/char/diag/diagfwd_rpmsg.c
@@ -354,17 +354,12 @@ static void diag_state_open_rpmsg(void *ctxt)
static void diag_rpmsg_queue_read(void *ctxt)
{
struct diag_rpmsg_info *rpmsg_info = NULL;
- unsigned long flags;
if (!ctxt)
return;
rpmsg_info = (struct diag_rpmsg_info *)ctxt;
- spin_lock_irqsave(&driver->rpmsginfo_lock[PERI_RPMSG], flags);
- if (rpmsg_info->hdl && rpmsg_info->wq &&
- atomic_read(&rpmsg_info->opened))
- queue_work(rpmsg_info->wq, &(rpmsg_info->read_work));
- spin_unlock_irqrestore(&driver->rpmsginfo_lock[PERI_RPMSG], flags);
+ queue_work(rpmsg_info->wq, &(rpmsg_info->read_work));
}
static void diag_state_close_rpmsg(void *ctxt)
@@ -398,7 +393,6 @@ static int diag_rpmsg_read(void *ctxt, unsigned char *buf, int buf_len)
struct diag_rpmsg_info *rpmsg_info = NULL;
struct diagfwd_info *fwd_info = NULL;
int ret_val = 0;
- unsigned long flags;
if (!ctxt || !buf || buf_len <= 0)
return -EIO;
@@ -409,16 +403,15 @@ static int diag_rpmsg_read(void *ctxt, unsigned char *buf, int buf_len)
return -EIO;
}
- spin_lock_irqsave(&driver->rpmsginfo_lock[PERI_RPMSG], flags);
+ mutex_lock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
if (!atomic_read(&rpmsg_info->opened) ||
!rpmsg_info->hdl || !rpmsg_info->inited) {
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
"diag:RPMSG channel not opened");
- spin_unlock_irqrestore(&driver->rpmsginfo_lock[PERI_RPMSG],
- flags);
+ mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
return -EIO;
}
- spin_unlock_irqrestore(&driver->rpmsginfo_lock[PERI_RPMSG], flags);
+ mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
fwd_info = rpmsg_info->fwd_ctxt;
@@ -442,25 +435,22 @@ static void diag_rpmsg_read_work_fn(struct work_struct *work)
struct diag_rpmsg_info *rpmsg_info = container_of(work,
struct diag_rpmsg_info,
read_work);
- unsigned long flags;
if (!rpmsg_info)
return;
- spin_lock_irqsave(&driver->rpmsginfo_lock[PERI_RPMSG], flags);
+ mutex_lock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
if (!atomic_read(&rpmsg_info->opened)) {
- spin_unlock_irqrestore(&driver->rpmsginfo_lock[PERI_RPMSG],
- flags);
+ mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
return;
}
if (!rpmsg_info->inited) {
- spin_unlock_irqrestore(&driver->rpmsginfo_lock[PERI_RPMSG],
- flags);
+ mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
diag_ws_release();
return;
}
- spin_unlock_irqrestore(&driver->rpmsginfo_lock[PERI_RPMSG], flags);
+ mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
diagfwd_channel_read(rpmsg_info->fwd_ctxt);
}
@@ -470,7 +460,6 @@ static int diag_rpmsg_write(void *ctxt, unsigned char *buf, int len)
struct diag_rpmsg_info *rpmsg_info = NULL;
int err = 0;
struct rpmsg_device *rpdev = NULL;
- unsigned long flags;
if (!ctxt || !buf)
return -EIO;
@@ -482,16 +471,14 @@ static int diag_rpmsg_write(void *ctxt, unsigned char *buf, int len)
return -EINVAL;
}
- spin_lock_irqsave(&driver->rpmsginfo_lock[PERI_RPMSG], flags);
+ mutex_lock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
if (!rpmsg_info->inited || !rpmsg_info->hdl ||
!atomic_read(&rpmsg_info->opened)) {
pr_err_ratelimited("diag: In %s, rpmsg not inited, rpmsg_info: %pK, buf: %pK, len: %d\n",
__func__, rpmsg_info, buf, len);
- spin_unlock_irqrestore(&driver->rpmsginfo_lock[PERI_RPMSG],
- flags);
+ mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
return -ENODEV;
}
- spin_unlock_irqrestore(&driver->rpmsginfo_lock[PERI_RPMSG], flags);
rpdev = (struct rpmsg_device *)rpmsg_info->hdl;
err = rpmsg_send(rpdev->ept, buf, len);
@@ -501,6 +488,7 @@ static int diag_rpmsg_write(void *ctxt, unsigned char *buf, int len)
} else
err = -ENOMEM;
+ mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
return err;
}
@@ -510,18 +498,16 @@ static void diag_rpmsg_late_init_work_fn(struct work_struct *work)
struct diag_rpmsg_info *rpmsg_info = container_of(work,
struct diag_rpmsg_info,
late_init_work);
- unsigned long flags;
if (!rpmsg_info)
return;
- spin_lock_irqsave(&driver->rpmsginfo_lock[PERI_RPMSG], flags);
+ mutex_lock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
if (!rpmsg_info->hdl) {
- spin_unlock_irqrestore(&driver->rpmsginfo_lock[PERI_RPMSG],
- flags);
+ mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
return;
}
- spin_unlock_irqrestore(&driver->rpmsginfo_lock[PERI_RPMSG], flags);
+ mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
diagfwd_channel_open(rpmsg_info->fwd_ctxt);
DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "rpmsg late init p: %d t: %d\n",
@@ -534,18 +520,16 @@ static void diag_rpmsg_open_work_fn(struct work_struct *work)
struct diag_rpmsg_info *rpmsg_info = container_of(work,
struct diag_rpmsg_info,
open_work);
- unsigned long flags;
if (!rpmsg_info)
return;
- spin_lock_irqsave(&driver->rpmsginfo_lock[PERI_RPMSG], flags);
+ mutex_lock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
if (!rpmsg_info->inited) {
- spin_unlock_irqrestore(&driver->rpmsginfo_lock[PERI_RPMSG],
- flags);
+ mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
return;
}
- spin_unlock_irqrestore(&driver->rpmsginfo_lock[PERI_RPMSG], flags);
+ mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
if (rpmsg_info->type != TYPE_CNTL) {
diagfwd_channel_open(rpmsg_info->fwd_ctxt);
@@ -560,19 +544,17 @@ static void diag_rpmsg_close_work_fn(struct work_struct *work)
struct diag_rpmsg_info *rpmsg_info = container_of(work,
struct diag_rpmsg_info,
close_work);
- unsigned long flags;
if (!rpmsg_info)
return;
- spin_lock_irqsave(&driver->rpmsginfo_lock[PERI_RPMSG], flags);
+ mutex_lock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
if (!rpmsg_info->inited || !rpmsg_info->hdl) {
- spin_unlock_irqrestore(&driver->rpmsginfo_lock[PERI_RPMSG],
- flags);
+ mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
return;
}
rpmsg_info->hdl = NULL;
- spin_unlock_irqrestore(&driver->rpmsginfo_lock[PERI_RPMSG], flags);
+ mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
diagfwd_channel_close(rpmsg_info->fwd_ctxt);
}
@@ -685,20 +667,18 @@ static void rpmsg_late_init(struct diag_rpmsg_info *rpmsg_info)
int diag_rpmsg_init_peripheral(uint8_t peripheral)
{
- unsigned long flags;
-
if (peripheral >= NUM_PERIPHERALS) {
pr_err("diag: In %s, invalid peripheral %d\n", __func__,
peripheral);
return -EINVAL;
}
- spin_lock_irqsave(&driver->rpmsginfo_lock[peripheral], flags);
+ mutex_lock(&driver->rpmsginfo_mutex[peripheral]);
rpmsg_late_init(&rpmsg_data[peripheral]);
rpmsg_late_init(&rpmsg_dci[peripheral]);
rpmsg_late_init(&rpmsg_cmd[peripheral]);
rpmsg_late_init(&rpmsg_dci_cmd[peripheral]);
- spin_unlock_irqrestore(&driver->rpmsginfo_lock[peripheral], flags);
+ mutex_unlock(&driver->rpmsginfo_mutex[peripheral]);
return 0;
}
@@ -706,7 +686,6 @@ int diag_rpmsg_init_peripheral(uint8_t peripheral)
static void __diag_rpmsg_init(struct diag_rpmsg_info *rpmsg_info)
{
char wq_name[DIAG_RPMSG_NAME_SZ + 12];
- unsigned long flags;
if (!rpmsg_info)
return;
@@ -726,7 +705,7 @@ static void __diag_rpmsg_init(struct diag_rpmsg_info *rpmsg_info)
INIT_WORK(&(rpmsg_info->close_work), diag_rpmsg_close_work_fn);
INIT_WORK(&(rpmsg_info->read_work), diag_rpmsg_read_work_fn);
INIT_WORK(&(rpmsg_info->late_init_work), diag_rpmsg_late_init_work_fn);
- spin_lock_irqsave(&driver->rpmsginfo_lock[PERI_RPMSG], flags);
+ mutex_lock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
rpmsg_info->hdl = NULL;
rpmsg_info->fwd_ctxt = NULL;
atomic_set(&rpmsg_info->opened, 0);
@@ -735,7 +714,7 @@ static void __diag_rpmsg_init(struct diag_rpmsg_info *rpmsg_info)
"%s initialized fwd_ctxt: %pK hdl: %pK\n",
rpmsg_info->name, rpmsg_info->fwd_ctxt,
rpmsg_info->hdl);
- spin_unlock_irqrestore(&driver->rpmsginfo_lock[PERI_RPMSG], flags);
+ mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
}
void diag_rpmsg_invalidate(void *ctxt, struct diagfwd_info *fwd_ctxt)
@@ -753,7 +732,6 @@ int diag_rpmsg_init(void)
{
uint8_t peripheral;
struct diag_rpmsg_info *rpmsg_info = NULL;
- unsigned long flags;
for (peripheral = 0; peripheral < NUM_PERIPHERALS; peripheral++) {
if (peripheral != PERIPHERAL_WDSP)
@@ -763,10 +741,9 @@ int diag_rpmsg_init(void)
diagfwd_cntl_register(TRANSPORT_RPMSG, rpmsg_info->peripheral,
(void *)rpmsg_info, &rpmsg_ops,
&(rpmsg_info->fwd_ctxt));
- spin_lock_irqsave(&driver->rpmsginfo_lock[peripheral], flags);
+ mutex_lock(&driver->rpmsginfo_mutex[peripheral]);
rpmsg_info->inited = 1;
- spin_unlock_irqrestore(&driver->rpmsginfo_lock[peripheral],
- flags);
+ mutex_unlock(&driver->rpmsginfo_mutex[peripheral]);
diagfwd_channel_open(rpmsg_info->fwd_ctxt);
diagfwd_late_open(rpmsg_info->fwd_ctxt);
__diag_rpmsg_init(&rpmsg_data[peripheral]);
@@ -799,31 +776,27 @@ static void __diag_rpmsg_exit(struct diag_rpmsg_info *rpmsg_info)
void diag_rpmsg_early_exit(void)
{
int peripheral = 0;
- unsigned long flags;
for (peripheral = 0; peripheral < NUM_PERIPHERALS; peripheral++) {
if (peripheral != PERIPHERAL_WDSP)
continue;
- spin_lock_irqsave(&driver->rpmsginfo_lock[peripheral], flags);
+ mutex_lock(&driver->rpmsginfo_mutex[peripheral]);
__diag_rpmsg_exit(&rpmsg_cntl[peripheral]);
- spin_unlock_irqrestore(&driver->rpmsginfo_lock[peripheral],
- flags);
+ mutex_unlock(&driver->rpmsginfo_mutex[peripheral]);
}
}
void diag_rpmsg_exit(void)
{
int peripheral = 0;
- unsigned long flags;
for (peripheral = 0; peripheral < NUM_PERIPHERALS; peripheral++) {
- spin_lock_irqsave(&driver->rpmsginfo_lock[peripheral], flags);
+ mutex_lock(&driver->rpmsginfo_mutex[peripheral]);
__diag_rpmsg_exit(&rpmsg_data[peripheral]);
__diag_rpmsg_exit(&rpmsg_cmd[peripheral]);
__diag_rpmsg_exit(&rpmsg_dci[peripheral]);
__diag_rpmsg_exit(&rpmsg_dci_cmd[peripheral]);
- spin_unlock_irqrestore(&driver->rpmsginfo_lock[peripheral],
- flags);
+ mutex_unlock(&driver->rpmsginfo_mutex[peripheral]);
}
}
@@ -849,7 +822,6 @@ static struct diag_rpmsg_info *diag_get_rpmsg_ptr(char *name)
static int diag_rpmsg_probe(struct rpmsg_device *rpdev)
{
struct diag_rpmsg_info *rpmsg_info = NULL;
- unsigned long flags;
if (!rpdev)
return 0;
@@ -859,11 +831,10 @@ static int diag_rpmsg_probe(struct rpmsg_device *rpdev)
rpmsg_info = diag_get_rpmsg_ptr(rpdev->id.name);
if (rpmsg_info) {
- spin_lock_irqsave(&driver->rpmsginfo_lock[PERI_RPMSG], flags);
+ mutex_lock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
rpmsg_info->hdl = rpdev;
atomic_set(&rpmsg_info->opened, 1);
- spin_unlock_irqrestore(&driver->rpmsginfo_lock[PERI_RPMSG],
- flags);
+ mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
dev_set_drvdata(&rpdev->dev, rpmsg_info);
diagfwd_channel_read(rpmsg_info->fwd_ctxt);
@@ -876,17 +847,15 @@ static int diag_rpmsg_probe(struct rpmsg_device *rpdev)
static void diag_rpmsg_remove(struct rpmsg_device *rpdev)
{
struct diag_rpmsg_info *rpmsg_info = NULL;
- unsigned long flags;
if (!rpdev)
return;
rpmsg_info = diag_get_rpmsg_ptr(rpdev->id.name);
if (rpmsg_info) {
- spin_lock_irqsave(&driver->rpmsginfo_lock[PERI_RPMSG], flags);
+ mutex_lock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
atomic_set(&rpmsg_info->opened, 0);
- spin_unlock_irqrestore(&driver->rpmsginfo_lock[PERI_RPMSG],
- flags);
+ mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
queue_work(rpmsg_info->wq, &rpmsg_info->close_work);
}
}
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context.c b/drivers/media/platform/msm/camera/cam_core/cam_context.c
index e1229f238a12..b6e43f78b65e 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_context.c
+++ b/drivers/media/platform/msm/camera/cam_core/cam_context.c
@@ -234,6 +234,28 @@ int cam_context_handle_crm_process_evt(struct cam_context *ctx,
return rc;
}
+int cam_context_handle_crm_dump_req(struct cam_context *ctx,
+ struct cam_req_mgr_dump_info *dump)
+{
+ int rc = 0;
+
+ if (!ctx->state_machine) {
+ CAM_ERR(CAM_CORE, "Context is not ready");
+ return -EINVAL;
+ }
+ mutex_lock(&ctx->ctx_mutex);
+ if (ctx->state_machine[ctx->state].crm_ops.dump_req) {
+ rc = ctx->state_machine[ctx->state].crm_ops.dump_req(ctx,
+ dump);
+ } else {
+ CAM_ERR(CAM_CORE, "No crm dump req in dev %d, state %d",
+ ctx->dev_hdl, ctx->state);
+ }
+ mutex_unlock(&ctx->ctx_mutex);
+
+ return rc;
+}
+
int cam_context_dump_pf_info(struct cam_context *ctx, unsigned long iova,
uint32_t buf_info)
{
@@ -502,6 +524,33 @@ int cam_context_handle_stop_dev(struct cam_context *ctx,
return rc;
}
+int cam_context_handle_dump_dev(struct cam_context *ctx,
+ struct cam_dump_req_cmd *cmd)
+{
+ int rc = 0;
+
+ if (!ctx || !ctx->state_machine) {
+ CAM_ERR(CAM_CORE, "Context is not ready");
+ return -EINVAL;
+ }
+
+ if (!cmd) {
+ CAM_ERR(CAM_CORE, "Invalid stop device command payload");
+ return -EINVAL;
+ }
+
+ mutex_lock(&ctx->ctx_mutex);
+ if (ctx->state_machine[ctx->state].ioctl_ops.dump_dev)
+ rc = ctx->state_machine[ctx->state].ioctl_ops.dump_dev(
+ ctx, cmd);
+ else
+ CAM_WARN(CAM_CORE, "No dump device in dev %d, name %s state %d",
+ ctx->dev_hdl, ctx->dev_name, ctx->state);
+ mutex_unlock(&ctx->ctx_mutex);
+
+ return rc;
+}
+
int cam_context_init(struct cam_context *ctx,
const char *dev_name,
uint64_t dev_id,
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context.h b/drivers/media/platform/msm/camera/cam_core/cam_context.h
index 2d8c6e0ae819..84a190a4c5a6 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_context.h
+++ b/drivers/media/platform/msm/camera/cam_core/cam_context.h
@@ -92,6 +92,7 @@ struct cam_ctx_request {
* @flush_dev: Function pointer for flush device
* @acquire_hw: Function pointer for acquire hw
* @release_hw: Function pointer for release hw
+ * @dump_dev: Function pointer for dump dev
*
*/
struct cam_ctx_ioctl_ops {
@@ -109,6 +110,9 @@ struct cam_ctx_ioctl_ops {
struct cam_flush_dev_cmd *cmd);
int (*acquire_hw)(struct cam_context *ctx, void *args);
int (*release_hw)(struct cam_context *ctx, void *args);
+ int (*dump_dev)(struct cam_context *ctx,
+ struct cam_dump_req_cmd *cmd);
+
};
/**
@@ -120,6 +124,7 @@ struct cam_ctx_ioctl_ops {
* @apply_req: Apply setting for the context
* @flush_req: Flush request to remove request ids
* @process_evt: Handle event notification from CRM.(optional)
+ * @dump_req: Dump information for the issue request
*
*/
struct cam_ctx_crm_ops {
@@ -135,6 +140,8 @@ struct cam_ctx_crm_ops {
struct cam_req_mgr_flush_request *flush);
int (*process_evt)(struct cam_context *ctx,
struct cam_req_mgr_link_evt_data *evt_data);
+ int (*dump_req)(struct cam_context *ctx,
+ struct cam_req_mgr_dump_info *dump);
};
@@ -305,6 +312,18 @@ int cam_context_handle_crm_process_evt(struct cam_context *ctx,
struct cam_req_mgr_link_evt_data *process_evt);
/**
+ * cam_context_handle_crm_dump_req()
+ *
+ * @brief: Handle CRM dump request
+ *
+ * @ctx: Object pointer for cam_context
+ * @dump: Request to dump
+ *
+ */
+int cam_context_handle_crm_dump_req(struct cam_context *ctx,
+ struct cam_req_mgr_dump_info *dump);
+
+/**
* cam_context_dump_pf_info()
*
* @brief: Handle dump active request request command
@@ -413,6 +432,19 @@ int cam_context_handle_start_dev(struct cam_context *ctx,
int cam_context_handle_stop_dev(struct cam_context *ctx,
struct cam_start_stop_dev_cmd *cmd);
+
+/**
+ * cam_context_handle_dump_dev()
+ *
+ * @brief: Handle dump device command
+ *
+ * @ctx: Object pointer for cam_context
+ * @cmd: Dump device command payload
+ *
+ */
+int cam_context_handle_dump_dev(struct cam_context *ctx,
+ struct cam_dump_req_cmd *cmd);
+
/**
* cam_context_deinit()
*
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c
index 50c2d8d84b24..1705b536bc37 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c
+++ b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c
@@ -1044,3 +1044,43 @@ int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx,
end:
return rc;
}
+
+int32_t cam_context_dump_dev_to_hw(struct cam_context *ctx,
+ struct cam_dump_req_cmd *cmd)
+{
+ int rc = 0;
+ struct cam_hw_dump_args dump_args;
+
+ if (!ctx || !cmd) {
+ CAM_ERR(CAM_CTXT, "Invalid input params %pK %pK", ctx, cmd);
+ return -EINVAL;
+ }
+ if (!ctx->hw_mgr_intf) {
+ CAM_ERR(CAM_CTXT, "[%s][%d] HW interface is not ready",
+ ctx->dev_name, ctx->ctx_id);
+ return -EFAULT;
+ }
+ memset(&dump_args, 0, sizeof(dump_args));
+ if (ctx->hw_mgr_intf->hw_dump) {
+ dump_args.ctxt_to_hw_map = ctx->ctxt_to_hw_map;
+ dump_args.buf_handle = cmd->buf_handle;
+ dump_args.offset = cmd->offset;
+ dump_args.request_id = cmd->issue_req_id;
+ rc = ctx->hw_mgr_intf->hw_dump(
+ ctx->hw_mgr_intf->hw_mgr_priv,
+ &dump_args);
+ if (rc) {
+ CAM_ERR(CAM_CTXT, "[%s][%d] handle[%u] failed",
+ ctx->dev_name, ctx->ctx_id, dump_args.buf_handle);
+ return rc;
+ }
+ CAM_INFO(CAM_CTXT, "[%s] ctx: %d Filled Length %d",
+ ctx->dev_name, ctx->ctx_id,
+ dump_args.offset - cmd->offset);
+ /* Drivers update offest upto which the buffer is written*/
+ cmd->offset = dump_args.offset;
+ } else {
+ CAM_INFO(CAM_CTXT, "%s hw dump not registered", ctx->dev_name);
+ }
+ return rc;
+}
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.h b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.h
index e1809b2fa436..022641f064ea 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.h
+++ b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -36,5 +36,6 @@ int32_t cam_context_flush_req_to_hw(struct cam_context *ctx,
int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx,
struct cam_packet *packet, unsigned long iova, uint32_t buf_info,
bool *mem_found);
-
+int32_t cam_context_dump_dev_to_hw(struct cam_context *ctx,
+ struct cam_dump_req_cmd *cmd);
#endif /* _CAM_CONTEXT_UTILS_H_ */
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_hw_mgr_intf.h b/drivers/media/platform/msm/camera/cam_core/cam_hw_mgr_intf.h
index 2afdafb03184..19e3230d9011 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_hw_mgr_intf.h
+++ b/drivers/media/platform/msm/camera/cam_core/cam_hw_mgr_intf.h
@@ -272,6 +272,21 @@ struct cam_hw_reset_args {
void *ctxt_to_hw_map;
};
+/**
+ * struct cam_hw_dump_args - Dump arguments
+ *
+ * @request_id: request_id
+ * @buf_handle: Buffer handle
+ * @offset: Buffer offset. This is updated by the drivers.
+ * @ctxt_to_hw_map: HW context from the acquire
+ */
+struct cam_hw_dump_args {
+ uint64_t request_id;
+ uint32_t buf_handle;
+ int32_t offset;
+ void *ctxt_to_hw_map;
+};
+
/* enum cam_hw_mgr_command - Hardware manager command type */
enum cam_hw_mgr_command {
CAM_HW_MGR_CMD_INTERNAL,
@@ -324,6 +339,7 @@ struct cam_hw_cmd_args {
* @hw_close: Function pointer for HW deinit
* @hw_flush: Function pointer for HW flush
* @hw_reset: Function pointer for HW reset
+ * @hw_dump: Function pointer for HW dump
*
*/
struct cam_hw_mgr_intf {
@@ -345,6 +361,7 @@ struct cam_hw_mgr_intf {
int (*hw_close)(void *hw_priv, void *hw_close_args);
int (*hw_flush)(void *hw_priv, void *hw_flush_args);
int (*hw_reset)(void *hw_priv, void *hw_reset_args);
+ int (*hw_dump)(void *hw_priv, void *hw_dump_args);
};
#endif /* _CAM_HW_MGR_INTF_H_ */
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_node.c b/drivers/media/platform/msm/camera/cam_core/cam_node.c
index ff6f22956f53..c81bbf937010 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_node.c
+++ b/drivers/media/platform/msm/camera/cam_core/cam_node.c
@@ -330,6 +330,39 @@ static int __cam_node_handle_flush_dev(struct cam_node *node,
return rc;
}
+static int __cam_node_handle_dump_dev(struct cam_node *node,
+ struct cam_dump_req_cmd *dump)
+{
+ struct cam_context *ctx = NULL;
+ int rc;
+
+ if (!dump)
+ return -EINVAL;
+
+ if (dump->dev_handle <= 0) {
+ CAM_ERR(CAM_CORE, "Invalid device handle for context");
+ return -EINVAL;
+ }
+
+ if (dump->session_handle <= 0) {
+ CAM_ERR(CAM_CORE, "Invalid session handle for context");
+ return -EINVAL;
+ }
+
+ ctx = (struct cam_context *)cam_get_device_priv(dump->dev_handle);
+ if (!ctx) {
+ CAM_ERR(CAM_CORE, "Can not get context for handle %d",
+ dump->dev_handle);
+ return -EINVAL;
+ }
+
+ rc = cam_context_handle_dump_dev(ctx, dump);
+ if (rc)
+ CAM_ERR(CAM_CORE, "Flush failure for node %s", node->name);
+
+ return rc;
+}
+
static int __cam_node_handle_release_dev(struct cam_node *node,
struct cam_release_dev_cmd *release)
{
@@ -531,6 +564,25 @@ static int __cam_node_crm_process_evt(
return cam_context_handle_crm_process_evt(ctx, evt_data);
}
+static int __cam_node_crm_dump_req(struct cam_req_mgr_dump_info *dump)
+{
+ struct cam_context *ctx = NULL;
+
+ if (!dump) {
+ CAM_ERR(CAM_CORE, "Invalid dump request payload");
+ return -EINVAL;
+ }
+
+ ctx = (struct cam_context *) cam_get_device_priv(dump->dev_hdl);
+ if (!ctx) {
+ CAM_ERR(CAM_CORE, "Can not get context for handle %d",
+ dump->dev_hdl);
+ return -EINVAL;
+ }
+
+ return cam_context_handle_crm_dump_req(ctx, dump);
+}
+
int cam_node_deinit(struct cam_node *node)
{
if (node)
@@ -586,6 +638,7 @@ int cam_node_init(struct cam_node *node, struct cam_hw_mgr_intf *hw_mgr_intf,
node->crm_node_intf.link_setup = __cam_node_crm_link_setup;
node->crm_node_intf.flush_req = __cam_node_crm_flush_req;
node->crm_node_intf.process_evt = __cam_node_crm_process_evt;
+ node->crm_node_intf.dump_req = __cam_node_crm_dump_req;
mutex_init(&node->list_mutex);
INIT_LIST_HEAD(&node->free_ctx_list);
@@ -827,6 +880,28 @@ release_kfree:
}
break;
}
+ case CAM_DUMP_REQ: {
+ struct cam_dump_req_cmd dump;
+
+ if (copy_from_user(&dump, u64_to_user_ptr(cmd->handle),
+ sizeof(dump))) {
+ rc = -EFAULT;
+ } else {
+ rc = __cam_node_handle_dump_dev(node, &dump);
+ if (rc) {
+ CAM_ERR(CAM_CORE,
+ "Dump device %s failed(rc = %d) ",
+ node->name, rc);
+ } else if (copy_to_user(u64_to_user_ptr(cmd->handle),
+ &dump, sizeof(dump))) {
+ CAM_ERR(CAM_CORE,
+ "Dump device %s copy_to_user fail",
+ node->name);
+ rc = -EFAULT;
+ }
+ }
+ break;
+ }
default:
CAM_ERR(CAM_CORE, "Unknown op code %d", cmd->op_code);
rc = -EINVAL;
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
index d4a76622caec..401bb6a18eab 100644
--- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
+++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
@@ -3454,9 +3454,73 @@ end:
}
+int cam_req_mgr_dump_request(struct cam_dump_req_cmd *dump_req)
+{
+ int rc = 0;
+ struct cam_req_mgr_core_link *link = NULL;
+ struct cam_req_mgr_core_session *session = NULL;
+ struct cam_req_mgr_dump_info info;
+ struct cam_req_mgr_connected_device *device = NULL;
+ int i;
+
+ if (!dump_req) {
+ CAM_ERR(CAM_CRM, "dump req is NULL");
+ rc = -EFAULT;
+ goto end;
+ }
+
+ mutex_lock(&g_crm_core_dev->crm_lock);
+ /* session hdl's priv data is cam session struct */
+ session = (struct cam_req_mgr_core_session *)
+ cam_get_device_priv(dump_req->session_handle);
+ if (!session) {
+ CAM_ERR(CAM_CRM, "Invalid session %x",
+ dump_req->session_handle);
+ rc = -EINVAL;
+ goto end;
+ }
+ if (session->num_links <= 0) {
+ CAM_WARN(CAM_CRM, "No active links in session %x",
+ dump_req->session_handle);
+ goto end;
+ }
+
+ link = (struct cam_req_mgr_core_link *)
+ cam_get_device_priv(dump_req->link_hdl);
+ if (!link) {
+ CAM_DBG(CAM_CRM, "link ptr NULL %x", dump_req->link_hdl);
+ rc = -EINVAL;
+ goto end;
+ }
+ info.offset = dump_req->offset;
+ for (i = 0; i < link->num_devs; i++) {
+ device = &link->l_dev[i];
+ info.link_hdl = dump_req->link_hdl;
+ info.dev_hdl = device->dev_hdl;
+ info.req_id = dump_req->issue_req_id;
+ info.buf_handle = dump_req->buf_handle;
+ if (device->ops && device->ops->dump_req) {
+ rc = device->ops->dump_req(&info);
+ if (rc) {
+ CAM_ERR(CAM_REQ, "Fail dump req %lld dev %d",
+ info.req_id,
+ device->dev_hdl);
+ }
+ }
+ }
+ dump_req->offset = info.offset;
+ CAM_INFO(CAM_REQ, "req %lld, offset %u",
+ dump_req->issue_req_id, dump_req->offset);
+end:
+ mutex_unlock(&g_crm_core_dev->crm_lock);
+ return 0;
+
+}
+
int cam_req_mgr_core_device_init(void)
{
int i;
+
CAM_DBG(CAM_CRM, "Enter g_crm_core_dev %pK", g_crm_core_dev);
if (g_crm_core_dev) {
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h
index bcaf4da387b3..662ab5882a0c 100644
--- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h
+++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h
@@ -56,6 +56,7 @@ enum crm_workq_task_type {
CRM_WORKQ_TASK_NOTIFY_FREEZE,
CRM_WORKQ_TASK_SCHED_REQ,
CRM_WORKQ_TASK_FLUSH_REQ,
+ CRM_WORKQ_TASK_DUMP_REQ,
CRM_WORKQ_TASK_INVALID,
};
@@ -484,5 +485,12 @@ void cam_req_mgr_handle_core_shutdown(void);
*/
int cam_req_mgr_link_control(struct cam_req_mgr_link_control *control);
+/**
+ * cam_req_mgr_dump_request()
+ * @brief: Dumps the request information
+ * @dump_req: Dump request
+ */
+int cam_req_mgr_dump_request(struct cam_dump_req_cmd *dump_req);
+
#endif
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c
index 31607ac6391f..5d4d9fcc47ab 100644
--- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c
+++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c
@@ -473,6 +473,31 @@ static long cam_private_ioctl(struct file *file, void *fh,
rc = -EINVAL;
}
break;
+
+ case CAM_REQ_MGR_REQUEST_DUMP: {
+ struct cam_dump_req_cmd cmd;
+
+ if (k_ioctl->size != sizeof(cmd))
+ return -EINVAL;
+
+ if (copy_from_user(&cmd,
+ u64_to_user_ptr(k_ioctl->handle),
+ sizeof(struct cam_dump_req_cmd))) {
+ rc = -EFAULT;
+ break;
+ }
+
+ rc = cam_req_mgr_dump_request(&cmd);
+ if (!rc)
+ if (copy_to_user(
+ u64_to_user_ptr(k_ioctl->handle),
+ &cmd, sizeof(struct cam_dump_req_cmd))) {
+ rc = -EFAULT;
+ break;
+ }
+ }
+ break;
+
default:
return -ENOIOCTLCMD;
}
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_interface.h b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_interface.h
index 934bc76014a5..33274186fc15 100644
--- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_interface.h
+++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_interface.h
@@ -26,6 +26,7 @@ struct cam_req_mgr_core_dev_link_setup;
struct cam_req_mgr_apply_request;
struct cam_req_mgr_flush_request;
struct cam_req_mgr_link_evt_data;
+struct cam_req_mgr_dump_info;
#define SKIP_NEXT_FRAME 0x100
@@ -52,6 +53,7 @@ typedef int (*cam_req_mgr_add_req)(struct cam_req_mgr_add_request *);
* @cam_req_mgr_apply_req : CRM asks device to apply certain request id.
* @cam_req_mgr_flush_req : Flush or cancel request
* cam_req_mgr_process_evt : generic events
+ * cam_req_mgr_dump_req : dump request
*/
typedef int (*cam_req_mgr_get_dev_info) (struct cam_req_mgr_device_info *);
typedef int (*cam_req_mgr_link_setup)(
@@ -59,6 +61,7 @@ typedef int (*cam_req_mgr_link_setup)(
typedef int (*cam_req_mgr_apply_req)(struct cam_req_mgr_apply_request *);
typedef int (*cam_req_mgr_flush_req)(struct cam_req_mgr_flush_request *);
typedef int (*cam_req_mgr_process_evt)(struct cam_req_mgr_link_evt_data *);
+typedef int (*cam_req_mgr_dump_req)(struct cam_req_mgr_dump_info *);
/**
* @brief : cam_req_mgr_crm_cb - func table
@@ -81,6 +84,7 @@ struct cam_req_mgr_crm_cb {
* @apply_req : payload to apply request id on a device linked
* @flush_req : payload to flush request
* @process_evt : payload to generic event
+ * @dump_req : payload to dump request
*/
struct cam_req_mgr_kmd_ops {
cam_req_mgr_get_dev_info get_dev_info;
@@ -88,6 +92,7 @@ struct cam_req_mgr_kmd_ops {
cam_req_mgr_apply_req apply_req;
cam_req_mgr_flush_req flush_req;
cam_req_mgr_process_evt process_evt;
+ cam_req_mgr_dump_req dump_req;
};
/**
@@ -338,4 +343,25 @@ struct cam_req_mgr_send_request {
int32_t link_hdl;
struct cam_req_mgr_req_queue *in_q;
};
+
+/**
+ * struct cam_req_mgr_dump_info
+ * @req_id : request id to cancel
+ * @link_hdl : link identifier
+ * @dev_hdl : device handle for cross check
+ * @buf_handle : buf handle
+ * @offset : offset of buffere
+ * @error_type : error type
+ *
+ */
+struct cam_req_mgr_dump_info {
+ uint64_t req_id;
+ int32_t link_hdl;
+ int32_t dev_hdl;
+ uint32_t buf_handle;
+ int32_t offset;
+ int32_t error_type;
+};
+
+
#endif
diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_common_util.c b/drivers/media/platform/msm/camera/cam_utils/cam_common_util.c
index bba12cf106df..fd113aeb1dc5 100644
--- a/drivers/media/platform/msm/camera/cam_utils/cam_common_util.c
+++ b/drivers/media/platform/msm/camera/cam_utils/cam_common_util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -55,3 +55,22 @@ uint32_t cam_common_util_remove_duplicate_arr(int32_t *arr, uint32_t num)
return wr_idx;
}
+
+uint64_t cam_common_util_get_time_diff(struct timeval *t1, struct timeval *t2)
+{
+ uint64_t diff = 0;
+
+ diff = (t1->tv_sec - t2->tv_sec) * 1000000 +
+ (t1->tv_usec - t2->tv_usec);
+ return diff;
+}
+
+void cam_common_util_get_curr_timestamp(struct timeval *time_stamp)
+{
+ struct timespec ts;
+
+ get_monotonic_boottime(&ts);
+ time_stamp->tv_sec = ts.tv_sec;
+ time_stamp->tv_usec = ts.tv_nsec/1000;
+}
+
diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_common_util.h b/drivers/media/platform/msm/camera/cam_utils/cam_common_util.h
index 47d441fe3aa1..c06e5372f730 100644
--- a/drivers/media/platform/msm/camera/cam_utils/cam_common_util.h
+++ b/drivers/media/platform/msm/camera/cam_utils/cam_common_util.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -52,4 +52,26 @@ int cam_common_util_get_string_index(const char **strings,
uint32_t cam_common_util_remove_duplicate_arr(int32_t *array,
uint32_t num);
+/**
+ * cam_common_util_get_time_diff()
+ *
+ * @brief Get the time difference between 2 timestamps in usecs
+ *
+ * @t1: Pointer to the later time
+ * @t2: Pointer to the prev
+ *
+ * @return: differnce in usecs
+ */
+uint64_t cam_common_util_get_time_diff(struct timeval *t1, struct timeval *t2);
+
+/**
+ * cam_comomon_util_get_curr_timestamp()
+ *
+ * @brief Get the current timestamp
+ *
+ * @time: Pointer to the time
+ *
+ * @return: void
+ */
+void cam_common_util_get_curr_timestamp(struct timeval *time_stamp);
#endif /* _CAM_COMMON_UTIL_H_ */
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index 80d03edec6d3..29da0b4e9fb8 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -4263,9 +4263,7 @@ static int mmc_blk_probe(struct mmc_card *card)
dev_set_drvdata(&card->dev, md);
-#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
mmc_set_bus_resume_policy(card->host, 1);
-#endif
if (mmc_add_disk(md))
goto out;
@@ -4313,9 +4311,7 @@ static void mmc_blk_remove(struct mmc_card *card)
pm_runtime_put_noidle(&card->dev);
mmc_blk_remove_req(md);
dev_set_drvdata(&card->dev, NULL);
-#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
mmc_set_bus_resume_policy(card->host, 0);
-#endif
}
static int _mmc_blk_suspend(struct mmc_card *card, bool wait)
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 531e34636120..5acb6fe639fd 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1969,10 +1969,9 @@ EXPORT_SYMBOL(mmc_start_areq);
*/
void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
{
-#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
if (mmc_bus_needs_resume(host))
mmc_resume_bus(host);
-#endif
+
__mmc_start_req(host, mrq);
if (!mrq->cap_cmd_during_tfr)
@@ -2284,10 +2283,9 @@ void mmc_get_card(struct mmc_card *card)
{
pm_runtime_get_sync(&card->dev);
mmc_claim_host(card->host);
-#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
+
if (mmc_bus_needs_resume(card->host))
mmc_resume_bus(card->host);
-#endif
}
EXPORT_SYMBOL(mmc_get_card);
@@ -3232,6 +3230,7 @@ int mmc_resume_bus(struct mmc_host *host)
{
unsigned long flags;
int err = 0;
+ int card_present = true;
if (!mmc_bus_needs_resume(host))
return -EINVAL;
@@ -3242,23 +3241,30 @@ int mmc_resume_bus(struct mmc_host *host)
spin_unlock_irqrestore(&host->lock, flags);
mmc_bus_get(host);
- if (host->bus_ops && !host->bus_dead && host->card) {
+ if (host->ops->get_cd) {
+ card_present = host->ops->get_cd(host);
+ if (!card_present) {
+ pr_err("%s: Card removed - card_present:%d\n",
+ mmc_hostname(host), card_present);
+ mmc_card_set_removed(host->card);
+ }
+ }
+
+
+ if (host->bus_ops && !host->bus_dead && host->card && card_present) {
mmc_power_up(host, host->card->ocr);
BUG_ON(!host->bus_ops->resume);
err = host->bus_ops->resume(host);
- if (err) {
- pr_err("%s: %s: resume failed: %d\n",
- mmc_hostname(host), __func__, err);
- /*
- * If we have cd-gpio based detection mechanism and
- * deferred resume is supported, we will not detect
- * card removal event when system is suspended. So if
- * resume fails after a system suspend/resume,
- * schedule the work to detect card presence.
- */
- if (mmc_card_is_removable(host) &&
- !(host->caps & MMC_CAP_NEEDS_POLL)) {
- mmc_detect_change(host, 0);
+ if (err && (err != -ENOMEDIUM)) {
+ pr_err("%s: bus resume: failed: %d\n",
+ mmc_hostname(host), err);
+ err = mmc_hw_reset(host);
+ if (err) {
+ pr_err("%s: reset: failed: %d\n",
+ mmc_hostname(host), err);
+ goto err_reset;
+ } else {
+ mmc_card_clr_suspended(host->card);
}
}
if (mmc_card_cmdq(host->card)) {
@@ -3266,14 +3272,13 @@ int mmc_resume_bus(struct mmc_host *host)
if (err)
pr_err("%s: %s: unhalt failed: %d\n",
mmc_hostname(host), __func__, err);
- else
- mmc_card_clr_suspended(host->card);
}
}
+err_reset:
mmc_bus_put(host);
pr_debug("%s: Deferred resume completed\n", mmc_hostname(host));
- return 0;
+ return err;
}
EXPORT_SYMBOL(mmc_resume_bus);
@@ -4506,7 +4511,7 @@ static int mmc_pm_notify(struct notifier_block *notify_block,
struct mmc_host *host = container_of(
notify_block, struct mmc_host, pm_notify);
unsigned long flags;
- int err = 0;
+ int err = 0, present = 0;
switch (mode) {
case PM_HIBERNATION_PREPARE:
@@ -4549,8 +4554,12 @@ static int mmc_pm_notify(struct notifier_block *notify_block,
spin_lock_irqsave(&host->lock, flags);
host->rescan_disable = 0;
+ if (host->ops->get_cd)
+ present = host->ops->get_cd(host);
+
if (mmc_bus_manual_resume(host) &&
- !host->ignore_bus_resume_flags) {
+ !host->ignore_bus_resume_flags &&
+ present) {
spin_unlock_irqrestore(&host->lock, flags);
break;
}
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index ebbbf8d9a0f3..3fb8c152167a 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -1152,6 +1152,9 @@ static void mmc_sd_remove(struct mmc_host *host)
*/
static int mmc_sd_alive(struct mmc_host *host)
{
+ if (host->ops->get_cd && !host->ops->get_cd(host))
+ return -ENOMEDIUM;
+
return mmc_send_status(host->card, NULL);
}
@@ -1177,6 +1180,16 @@ static void mmc_sd_detect(struct mmc_host *host)
return;
}
+ if (mmc_bus_needs_resume(host))
+ mmc_resume_bus(host);
+
+ if (host->ops->get_cd && !host->ops->get_cd(host)) {
+ err = -ENOMEDIUM;
+ mmc_card_set_removed(host->card);
+ mmc_card_clr_suspended(host->card);
+ goto out;
+ }
+
/*
* Just check if our card has been removed.
*/
@@ -1199,6 +1212,7 @@ static void mmc_sd_detect(struct mmc_host *host)
err = _mmc_detect_card_removed(host);
#endif
+out:
mmc_put_card(host->card);
if (err) {
@@ -1277,6 +1291,11 @@ static int _mmc_sd_resume(struct mmc_host *host)
if (!mmc_card_suspended(host->card))
goto out;
+ if (host->ops->get_cd && !host->ops->get_cd(host)) {
+ mmc_card_clr_suspended(host->card);
+ goto out;
+ }
+
mmc_power_up(host, host->card->ocr);
#ifdef CONFIG_MMC_PARANOID_SD_INIT
retries = 5;
@@ -1303,8 +1322,6 @@ static int _mmc_sd_resume(struct mmc_host *host)
mmc_hostname(host), __func__, err);
mmc_card_set_removed(host->card);
mmc_detect_change(host, msecs_to_jiffies(200));
- } else if (err) {
- goto out;
}
mmc_card_clr_suspended(host->card);
@@ -1329,11 +1346,21 @@ static int mmc_sd_resume(struct mmc_host *host)
MMC_TRACE(host, "%s: Enter\n", __func__);
err = _mmc_sd_resume(host);
- pm_runtime_set_active(&host->card->dev);
- pm_runtime_mark_last_busy(&host->card->dev);
- pm_runtime_enable(&host->card->dev);
- MMC_TRACE(host, "%s: Exit err: %d\n", __func__, err);
+ if (err) {
+ pr_err("%s: sd resume err: %d\n", mmc_hostname(host), err);
+ if (host->ops->get_cd && !host->ops->get_cd(host)) {
+ err = -ENOMEDIUM;
+ mmc_card_set_removed(host->card);
+ }
+ }
+ if (err != -ENOMEDIUM) {
+ pm_runtime_set_active(&host->card->dev);
+ pm_runtime_mark_last_busy(&host->card->dev);
+ pm_runtime_enable(&host->card->dev);
+ }
+
+ MMC_TRACE(host, "%s: Exit err: %d\n", __func__, err);
return err;
}
@@ -1372,6 +1399,9 @@ static int mmc_sd_runtime_resume(struct mmc_host *host)
static int mmc_sd_reset(struct mmc_host *host)
{
+ if (host->ops->get_cd && !host->ops->get_cd(host))
+ return -ENOMEDIUM;
+
mmc_power_cycle(host, host->card->ocr);
return mmc_sd_init_card(host, host->card->ocr, host->card);
}
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index 841e5a2f597d..6989d4061d66 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -35,6 +35,10 @@ static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
{
/* Schedule a card detection after a debounce timeout */
struct mmc_host *host = dev_id;
+ int present = host->ops->get_cd(host);
+
+ pr_debug("%s: cd gpio irq, gpio state %d (CARD_%s)\n",
+ mmc_hostname(host), present, present?"INSERT":"REMOVAL");
host->trigger_card_event = true;
mmc_detect_change(host, msecs_to_jiffies(200));
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index cd88767a0bdc..f4a9b9f75e9f 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -1389,6 +1389,7 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code,
struct usb_endpoint_descriptor desc1, *desc;
switch (epfile->ffs->gadget->speed) {
+ case USB_SPEED_SUPER_PLUS:
case USB_SPEED_SUPER:
desc_idx = 2;
break;
diff --git a/drivers/usb/phy/phy-msm-snps-hs.c b/drivers/usb/phy/phy-msm-snps-hs.c
index d76c143a929f..1bc76ff39a8e 100644
--- a/drivers/usb/phy/phy-msm-snps-hs.c
+++ b/drivers/usb/phy/phy-msm-snps-hs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -578,6 +578,7 @@ static int msm_hsphy_dpdm_regulator_enable(struct regulator_dev *rdev)
UTMI_PHY_DATAPATH_CTRL_OVERRIDE_EN,
UTMI_PHY_DATAPATH_CTRL_OVERRIDE_EN);
+ msm_hsphy_enable_clocks(phy, false);
phy->dpdm_enable = true;
}
mutex_unlock(&phy->phy_lock);
@@ -596,7 +597,6 @@ static int msm_hsphy_dpdm_regulator_disable(struct regulator_dev *rdev)
mutex_lock(&phy->phy_lock);
if (phy->dpdm_enable) {
if (!phy->cable_connected) {
- msm_hsphy_enable_clocks(phy, false);
ret = msm_hsphy_enable_power(phy, false);
if (ret < 0) {
mutex_unlock(&phy->phy_lock);
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 1964564ce34a..7b5a06237408 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -756,6 +756,7 @@ static inline void *mmc_cmdq_private(struct mmc_host *host)
#define mmc_bus_manual_resume(host) ((host)->bus_resume_flags & \
MMC_BUSRESUME_MANUAL_RESUME)
+#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
static inline void mmc_set_bus_resume_policy(struct mmc_host *host, int manual)
{
if (manual)
@@ -763,6 +764,11 @@ static inline void mmc_set_bus_resume_policy(struct mmc_host *host, int manual)
else
host->bus_resume_flags &= ~MMC_BUSRESUME_MANUAL_RESUME;
}
+#else
+static inline void mmc_set_bus_resume_policy(struct mmc_host *host, int manual)
+{
+}
+#endif
extern int mmc_resume_bus(struct mmc_host *host);
diff --git a/include/uapi/media/cam_defs.h b/include/uapi/media/cam_defs.h
index 234b6462fe5b..0fa3777ee7a5 100644
--- a/include/uapi/media/cam_defs.h
+++ b/include/uapi/media/cam_defs.h
@@ -21,6 +21,7 @@
#define CAM_COMMON_OPCODE_BASE_v2 0x150
#define CAM_ACQUIRE_HW (CAM_COMMON_OPCODE_BASE_v2 + 0x1)
#define CAM_RELEASE_HW (CAM_COMMON_OPCODE_BASE_v2 + 0x2)
+#define CAM_DUMP_REQ (CAM_COMMON_OPCODE_BASE_v2 + 0x3)
#define CAM_EXT_OPCODE_BASE 0x200
#define CAM_CONFIG_DEV_EXTERNAL (CAM_EXT_OPCODE_BASE + 0x1)
@@ -626,5 +627,29 @@ struct cam_cmd_mem_regions {
struct cam_cmd_mem_region_info map_info_array[1];
};
+/**
+ * struct cam_dump_req_cmd -
+ * Dump the information of issue req id
+ *
+ * @issue_req_id : Issue Request Id
+ * @session_handle : Session Handle
+ * @link_hdl : link handle
+ * @dev_handle : Device Handle
+ * @error_type : Error Type
+ * @buf_handle : Buffer Handle
+ * @offset : offset for the buffer
+ * @reserved : Reserved
+ */
+struct cam_dump_req_cmd {
+ int64_t issue_req_id;
+ int32_t session_handle;
+ int32_t link_hdl;
+ int32_t dev_handle;
+ int32_t error_type;
+ uint32_t buf_handle;
+ int32_t offset;
+ uint32_t reserved;
+};
+
#endif /* __UAPI_CAM_DEFS_H__ */
diff --git a/include/uapi/media/cam_req_mgr.h b/include/uapi/media/cam_req_mgr.h
index 9b9f97bd50d5..08fe9b547855 100644
--- a/include/uapi/media/cam_req_mgr.h
+++ b/include/uapi/media/cam_req_mgr.h
@@ -246,6 +246,7 @@ struct cam_req_mgr_link_control {
#define CAM_REQ_MGR_CACHE_OPS (CAM_COMMON_OPCODE_MAX + 12)
#define CAM_REQ_MGR_LINK_CONTROL (CAM_COMMON_OPCODE_MAX + 13)
#define CAM_REQ_MGR_LINK_V2 (CAM_COMMON_OPCODE_MAX + 14)
+#define CAM_REQ_MGR_REQUEST_DUMP (CAM_COMMON_OPCODE_MAX + 15)
/* end of cam_req_mgr opcodes */
#define CAM_MEM_FLAG_HW_READ_WRITE (1<<0)