diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2019-09-12 23:28:59 -0700 |
---|---|---|
committer | Linux Build Service Account <lnxbuild@localhost> | 2019-09-12 23:28:59 -0700 |
commit | 4e6e0aac86151e6576075542b895a956e227c62c (patch) | |
tree | b9c6c4d8c885ed5598f41d654dbeff789ed03d1b | |
parent | c3c31b96f10bde1341475d9fdcc4907942a42d05 (diff) | |
parent | 24a35b53f5bef0b1360b84777f3523505fa83c1d (diff) |
Merge 24a35b53f5bef0b1360b84777f3523505fa83c1d on remote branchLA.UM.7.1.r1-16600-sm8150.0
Change-Id: I3aaf70567cf782280a876ee0e549a7cc08c5bf9b
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) |