diff options
| -rw-r--r-- | arch/arm64/Kconfig | 10 | ||||
| -rw-r--r-- | arch/arm64/mm/init.c | 42 | ||||
| -rw-r--r-- | drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c | 16 | ||||
| -rw-r--r-- | drivers/power/supply/qcom/smb-lib.c | 34 | ||||
| -rw-r--r-- | drivers/scsi/ufs/ufs-qcom-debugfs.c | 3 | ||||
| -rw-r--r-- | drivers/soc/qcom/icnss.c | 29 | ||||
| -rw-r--r-- | drivers/usb/dwc3/ep0.c | 2 | ||||
| -rw-r--r-- | drivers/usb/dwc3/gadget.c | 9 | ||||
| -rw-r--r-- | drivers/usb/dwc3/gadget.h | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_hdmi_panel.c | 15 |
10 files changed, 139 insertions, 22 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index d61f3ae80e15..07090b418129 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -652,6 +652,12 @@ config HOTPLUG_CPU Say Y here to experiment with turning CPUs off and on. CPUs can be controlled through /sys/devices/system/cpu. +config ARCH_ENABLE_MEMORY_HOTPLUG + def_bool y + +config ARCH_ENABLE_MEMORY_HOTREMOVE + def_bool y + # The GPIO number here must be sorted by descending number. In case of # a multiplatform kernel, we just want the highest value required by the # selected platforms. @@ -738,6 +744,10 @@ config ARCH_HAS_CACHE_LINE_SIZE source "mm/Kconfig" +config ARCH_MEMORY_PROBE + def_bool y + depends on MEMORY_HOTPLUG + config SECCOMP bool "Enable seccomp to safely compute untrusted bytecode" ---help--- diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index b4ef9ea679a1..1d4dcd57ac85 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -495,3 +495,45 @@ static int __init register_mem_limit_dumper(void) return 0; } __initcall(register_mem_limit_dumper); + +#ifdef CONFIG_MEMORY_HOTPLUG +int arch_add_memory(int nid, u64 start, u64 size, bool for_device) +{ + pg_data_t *pgdat; + struct zone *zone; + unsigned long start_pfn = start >> PAGE_SHIFT; + unsigned long nr_pages = size >> PAGE_SHIFT; + int ret; + + pgdat = NODE_DATA(nid); + + zone = pgdat->node_zones + + zone_for_memory(nid, start, size, ZONE_NORMAL, for_device); + ret = __add_pages(nid, zone, start_pfn, nr_pages); + + if (ret) + pr_warn("%s: Problem encountered in __add_pages() ret=%d\n", + __func__, ret); + + return ret; +} + +#ifdef CONFIG_MEMORY_HOTREMOVE +int arch_remove_memory(u64 start, u64 size) +{ + unsigned long start_pfn = start >> PAGE_SHIFT; + unsigned long nr_pages = size >> PAGE_SHIFT; + struct zone *zone; + int ret; + + zone = page_zone(pfn_to_page(start_pfn)); + ret = __remove_pages(zone, start_pfn, nr_pages); + if (ret) + pr_warn("%s: Problem encountered in __remove_pages() ret=%d\n", + __func__, ret); + + return ret; +} +#endif +#endif + diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c index 08bbed147c86..76e1b60512d0 100644 --- a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c +++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c @@ -2009,6 +2009,18 @@ ioctl32_error: } #endif +static int sde_rotator_ctrl_subscribe_event(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub) +{ + return -EINVAL; +} + +static int sde_rotator_event_unsubscribe(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub) +{ + return -EINVAL; +} + /* V4l2 ioctl handlers */ static const struct v4l2_ioctl_ops sde_rotator_ioctl_ops = { .vidioc_querycap = sde_rotator_querycap, @@ -2033,8 +2045,8 @@ static const struct v4l2_ioctl_ops sde_rotator_ioctl_ops = { .vidioc_s_parm = sde_rotator_s_parm, .vidioc_default = sde_rotator_private_ioctl, .vidioc_log_status = v4l2_ctrl_log_status, - .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, - .vidioc_unsubscribe_event = v4l2_event_unsubscribe, + .vidioc_subscribe_event = sde_rotator_ctrl_subscribe_event, + .vidioc_unsubscribe_event = sde_rotator_event_unsubscribe, }; /* diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index 93512f155c52..7acf5fab573b 100644 --- a/drivers/power/supply/qcom/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -2695,17 +2695,13 @@ int smblib_set_prop_pd_voltage_max(struct smb_charger *chg, return rc; } -int smblib_set_prop_pd_active(struct smb_charger *chg, - const union power_supply_propval *val) +static int __smblib_set_prop_pd_active(struct smb_charger *chg, bool pd_active) { int rc; bool orientation, sink_attached, hvdcp; u8 stat; - if (!get_effective_result(chg->pd_allowed_votable)) - return -EINVAL; - - chg->pd_active = val->intval; + chg->pd_active = pd_active; if (chg->pd_active) { vote(chg->apsd_disable_votable, PD_VOTER, true, 0); vote(chg->pd_allowed_votable, PD_VOTER, true, 0); @@ -2793,6 +2789,15 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, return rc; } +int smblib_set_prop_pd_active(struct smb_charger *chg, + const union power_supply_propval *val) +{ + if (!get_effective_result(chg->pd_allowed_votable)) + return -EINVAL; + + return __smblib_set_prop_pd_active(chg, val->intval); +} + int smblib_set_prop_ship_mode(struct smb_charger *chg, const union power_supply_propval *val) { @@ -3544,6 +3549,13 @@ static void smblib_handle_hvdcp_check_timeout(struct smb_charger *chg, /* enforce DCP ICL if specified */ vote(chg->usb_icl_votable, DCP_VOTER, chg->dcp_icl_ua != -EINVAL, chg->dcp_icl_ua); + + /* + * if pd is not allowed, then set pd_active = false right here, + * so that it starts the hvdcp engine + */ + if (!get_effective_result(chg->pd_allowed_votable)) + __smblib_set_prop_pd_active(chg, 0); } smblib_dbg(chg, PR_INTERRUPT, "IRQ: smblib_handle_hvdcp_check_timeout %s\n", @@ -4188,7 +4200,7 @@ irqreturn_t smblib_handle_usb_typec_change(int irq, void *data) if (chg->cc2_detach_wa_active || chg->typec_en_dis_active || chg->try_sink_active) { - smblib_dbg(chg, PR_INTERRUPT, "Ignoring since %s active\n", + smblib_dbg(chg, PR_MISC | PR_INTERRUPT, "Ignoring since %s active\n", chg->cc2_detach_wa_active ? "cc2_detach_wa" : "typec_en_dis"); return IRQ_HANDLED; @@ -4699,7 +4711,9 @@ static void smblib_legacy_detection_work(struct work_struct *work) smblib_err(chg, "Couldn't disable type-c rc=%d\n", rc); /* wait for the adapter to turn off VBUS */ - msleep(500); + msleep(1000); + + smblib_dbg(chg, PR_MISC, "legacy workaround enabling typec\n"); rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, @@ -4708,7 +4722,7 @@ static void smblib_legacy_detection_work(struct work_struct *work) smblib_err(chg, "Couldn't enable type-c rc=%d\n", rc); /* wait for type-c detection to complete */ - msleep(100); + msleep(400); rc = smblib_read(chg, TYPE_C_STATUS_5_REG, &stat); if (rc < 0) { @@ -4720,6 +4734,8 @@ static void smblib_legacy_detection_work(struct work_struct *work) vote(chg->usb_icl_votable, LEGACY_UNKNOWN_VOTER, false, 0); legacy = stat & TYPEC_LEGACY_CABLE_STATUS_BIT; rp_high = chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_HIGH; + smblib_dbg(chg, PR_MISC, "legacy workaround done legacy = %d rp_high = %d\n", + legacy, rp_high); if (!legacy || !rp_high) vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER, false, 0); diff --git a/drivers/scsi/ufs/ufs-qcom-debugfs.c b/drivers/scsi/ufs/ufs-qcom-debugfs.c index 494ecd1c5f79..db4ecec6cf2f 100644 --- a/drivers/scsi/ufs/ufs-qcom-debugfs.c +++ b/drivers/scsi/ufs/ufs-qcom-debugfs.c @@ -121,7 +121,8 @@ static ssize_t ufs_qcom_dbg_testbus_cfg_write(struct file *file, struct ufs_hba *hba = host->hba; - ret = simple_write_to_buffer(configuration, TESTBUS_CFG_BUFF_LINE_SIZE, + ret = simple_write_to_buffer(configuration, + TESTBUS_CFG_BUFF_LINE_SIZE - 1, &buff_pos, ubuf, cnt); if (ret < 0) { dev_err(host->hba->dev, "%s: failed to read user data\n", diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index 83efbbe25e6b..d9d49e861f03 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -2511,8 +2511,17 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb, if (code != SUBSYS_BEFORE_SHUTDOWN) return NOTIFY_OK; - if (test_bit(ICNSS_PDR_REGISTERED, &priv->state)) + if (test_bit(ICNSS_PDR_REGISTERED, &priv->state)) { + set_bit(ICNSS_FW_DOWN, &priv->state); + icnss_ignore_qmi_timeout(true); + + fw_down_data.crashed = !!notif->crashed; + if (test_bit(ICNSS_FW_READY, &priv->state)) + icnss_call_driver_uevent(priv, + ICNSS_UEVENT_FW_DOWN, + &fw_down_data); return NOTIFY_OK; + } icnss_pr_info("Modem went down, state: 0x%lx, crashed: %d\n", priv->state, notif->crashed); @@ -2646,14 +2655,18 @@ static int icnss_service_notifier_notify(struct notifier_block *nb, icnss_pr_info("PD service down, pd_state: %d, state: 0x%lx: cause: %s\n", *state, priv->state, icnss_pdr_cause[cause]); event_post: - set_bit(ICNSS_FW_DOWN, &priv->state); - icnss_ignore_qmi_timeout(true); - clear_bit(ICNSS_HOST_TRIGGERED_PDR, &priv->state); + if (!test_bit(ICNSS_FW_DOWN, &priv->state)) { + set_bit(ICNSS_FW_DOWN, &priv->state); + icnss_ignore_qmi_timeout(true); - fw_down_data.crashed = event_data->crashed; - if (test_bit(ICNSS_FW_READY, &priv->state)) - icnss_call_driver_uevent(priv, ICNSS_UEVENT_FW_DOWN, - &fw_down_data); + fw_down_data.crashed = event_data->crashed; + if (test_bit(ICNSS_FW_READY, &priv->state)) + icnss_call_driver_uevent(priv, + ICNSS_UEVENT_FW_DOWN, + &fw_down_data); + } + + clear_bit(ICNSS_HOST_TRIGGERED_PDR, &priv->state); icnss_driver_event_post(ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN, ICNSS_EVENT_SYNC, event_data); done: diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index c244d908fa4f..24ecbc469eb6 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -282,7 +282,7 @@ out: return ret; } -static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc) +void dwc3_ep0_stall_and_restart(struct dwc3 *dwc) { struct dwc3_ep *dep; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 94709587f238..f108aecbfe52 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2882,6 +2882,15 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) dwc3_writel(dwc->regs, DWC3_DCTL, reg); dwc->test_mode = false; + /* + * From SNPS databook section 8.1.2 + * the EP0 should be in setup phase. So ensure + * that EP0 is in setup phase by issuing a stall + * and restart if EP0 is not in setup phase. + */ + if (dwc->ep0state != EP0_SETUP_PHASE) + dwc3_ep0_stall_and_restart(dwc); + dwc3_stop_active_transfers(dwc); dwc3_clear_stall_all_ep(dwc); diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h index baa83cf9638b..5b3ffbe3056d 100644 --- a/drivers/usb/dwc3/gadget.h +++ b/drivers/usb/dwc3/gadget.h @@ -98,6 +98,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, void dwc3_ep0_interrupt(struct dwc3 *dwc, const struct dwc3_event_depevt *event); void dwc3_ep0_out_start(struct dwc3 *dwc); +void dwc3_ep0_stall_and_restart(struct dwc3 *dwc); int __dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value); int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value); int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request, diff --git a/drivers/video/fbdev/msm/mdss_hdmi_panel.c b/drivers/video/fbdev/msm/mdss_hdmi_panel.c index a8a56e3a8745..af72973a3988 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_panel.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_panel.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2017, 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 @@ -632,6 +632,19 @@ static int hdmi_panel_setup_dc(struct hdmi_panel *panel) vbi_pkt_reg = DSS_REG_R(panel->io, HDMI_VBI_PKT_CTRL); vbi_pkt_reg |= BIT(5) | BIT(4); DSS_REG_W(panel->io, HDMI_VBI_PKT_CTRL, vbi_pkt_reg); + } else { + hdmi_ctrl_reg = DSS_REG_R(panel->io, HDMI_CTRL); + + /* disable GC CD override */ + hdmi_ctrl_reg &= ~BIT(27); + /* disable deep color for RGB888/YUV444/YUV420 30 bits */ + hdmi_ctrl_reg &= ~BIT(24); + DSS_REG_W(panel->io, HDMI_CTRL, hdmi_ctrl_reg); + + /* disable the GC packet sending */ + vbi_pkt_reg = DSS_REG_R(panel->io, HDMI_VBI_PKT_CTRL); + vbi_pkt_reg &= ~(BIT(5) | BIT(4)); + DSS_REG_W(panel->io, HDMI_VBI_PKT_CTRL, vbi_pkt_reg); } return rc; |
