diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2020-10-08 04:21:11 -0700 |
---|---|---|
committer | Linux Build Service Account <lnxbuild@localhost> | 2020-10-08 04:21:11 -0700 |
commit | 69c4fe62aaa30faf615733708e40178be50fec48 (patch) | |
tree | d68628a18d5ac90475207e891bba3bf0aa14a748 | |
parent | 0a7732be5c7cbd80c9f9fe45582e1c01d05d3b16 (diff) | |
parent | a0f5b3e5ccde8ab41509e82687aa7898c240d859 (diff) |
Merge a0f5b3e5ccde8ab41509e82687aa7898c240d859 on remote branchLA.UM.8.15.r1-06900-KAMORTA.0
Change-Id: If4da805a96fdb859b6a3b5b85644ada2b4bdc41a
-rw-r--r-- | arch/arm/mm/dma-mapping.c | 18 | ||||
-rw-r--r-- | drivers/gpu/msm/kgsl_pwrctrl.c | 6 | ||||
-rw-r--r-- | drivers/power/supply/qcom/smb5-lib.c | 21 | ||||
-rw-r--r-- | drivers/power/supply/qcom/smblite-lib.c | 67 | ||||
-rw-r--r-- | drivers/power/supply/qcom/smblite-lib.h | 1 | ||||
-rw-r--r-- | drivers/usb/phy/phy-msm-qusb.c | 126 | ||||
-rw-r--r-- | mm/slub.c | 99 |
7 files changed, 294 insertions, 44 deletions
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 98503d534d4e..f4ae01f453df 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -130,6 +130,10 @@ static void *arm_dma_remap(struct device *dev, void *cpu_addr, static void arm_dma_unremap(struct device *dev, void *remapped_addr, size_t size); +static void arm_iommu_sync_sg_for_device(struct device *dev, + struct scatterlist *sg, int nents, enum dma_data_direction dir); +static void arm_iommu_sync_sg_for_cpu(struct device *dev, + struct scatterlist *sg, int nents, enum dma_data_direction dir); static pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot, bool coherent) @@ -1976,6 +1980,9 @@ int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg, current_offset += s->length; } + if ((attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0) + arm_iommu_sync_sg_for_device(dev, sg, nents, dir); + return nents; } @@ -2031,6 +2038,9 @@ void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, unsigned int total_length = sg_dma_len(sg); dma_addr_t iova = sg_dma_address(sg); + if ((attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0) + arm_iommu_sync_sg_for_cpu(dev, sg, nents, dir); + total_length = PAGE_ALIGN((iova & ~PAGE_MASK) + total_length); iova &= PAGE_MASK; @@ -2045,8 +2055,8 @@ void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, * @nents: number of buffers to map (returned from dma_map_sg) * @dir: DMA transfer direction (same as was passed to dma_map_sg) */ -void arm_iommu_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction dir) +static void arm_iommu_sync_sg_for_cpu(struct device *dev, + struct scatterlist *sg, int nents, enum dma_data_direction dir) { struct scatterlist *s; int i; @@ -2069,8 +2079,8 @@ void arm_iommu_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, * @nents: number of buffers to map (returned from dma_map_sg) * @dir: DMA transfer direction (same as was passed to dma_map_sg) */ -void arm_iommu_sync_sg_for_device(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction dir) +static void arm_iommu_sync_sg_for_device(struct device *dev, + struct scatterlist *sg, int nents, enum dma_data_direction dir) { struct scatterlist *s; int i; diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c index 606c8b63b0a4..8db173a049f0 100644 --- a/drivers/gpu/msm/kgsl_pwrctrl.c +++ b/drivers/gpu/msm/kgsl_pwrctrl.c @@ -669,12 +669,12 @@ void kgsl_pwrctrl_pwrlevel_change(struct kgsl_device *device, if (pwr->gpu_bimc_int_clk) { if (pwr->active_pwrlevel == 0 && !pwr->gpu_bimc_interface_enabled) { - kgsl_pwrctrl_clk_set_rate(pwr->gpu_bimc_int_clk, - pwr->gpu_bimc_int_clk_freq, - "bimc_gpu_clk"); _bimc_clk_prepare_enable(device, pwr->gpu_bimc_int_clk, "bimc_gpu_clk"); + kgsl_pwrctrl_clk_set_rate(pwr->gpu_bimc_int_clk, + pwr->gpu_bimc_int_clk_freq, + "bimc_gpu_clk"); pwr->gpu_bimc_interface_enabled = true; } else if (pwr->previous_pwrlevel == 0 && pwr->gpu_bimc_interface_enabled) { diff --git a/drivers/power/supply/qcom/smb5-lib.c b/drivers/power/supply/qcom/smb5-lib.c index 65bbb08936ce..5895445bc6d4 100644 --- a/drivers/power/supply/qcom/smb5-lib.c +++ b/drivers/power/supply/qcom/smb5-lib.c @@ -7176,10 +7176,27 @@ static void smblib_uusb_otg_work(struct work_struct *work) goto out; } otg = !!(stat & U_USB_GROUND_NOVBUS_BIT); - if (chg->otg_present != otg) + if (chg->otg_present != otg) { + if (otg) { + /* otg cable inserted */ + if (chg->typec_port) { + typec_partner_register(chg); + typec_set_data_role(chg->typec_port, + TYPEC_HOST); + typec_set_pwr_role(chg->typec_port, + TYPEC_SOURCE); + } + } else if (chg->typec_port) { + /* otg cable removed */ + typec_set_data_role(chg->typec_port, TYPEC_DEVICE); + typec_set_pwr_role(chg->typec_port, TYPEC_SINK); + typec_partner_unregister(chg); + } + smblib_notify_usb_host(chg, otg); - else + } else { goto out; + } chg->otg_present = otg; if (!otg) diff --git a/drivers/power/supply/qcom/smblite-lib.c b/drivers/power/supply/qcom/smblite-lib.c index d6cd0fed005d..c747f958dce8 100644 --- a/drivers/power/supply/qcom/smblite-lib.c +++ b/drivers/power/supply/qcom/smblite-lib.c @@ -440,7 +440,7 @@ static void smblite_lib_uusb_removal(struct smb_charger *chg) vote(chg->pl_enable_votable_indirect, USBIN_I_VOTER, false, 0); vote(chg->pl_enable_votable_indirect, USBIN_V_VOTER, false, 0); vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, - is_flashlite_active(chg) ? USBIN_500UA : USBIN_100UA); + is_flashlite_active(chg) ? USBIN_200UA : USBIN_100UA); vote(chg->usb_icl_votable, FLASH_ACTIVE_VOTER, false, 0); /* Remove SW thermal regulation votes */ @@ -1627,6 +1627,14 @@ int smblite_lib_set_prop_current_max(struct smb_charger *chg, if (chg->real_charger_type != POWER_SUPPLY_TYPE_USB) return 0; + if (is_flashlite_active(chg) && (val->intval >= USBIN_400UA)) { + /* For Uusb based SDP port */ + vote(chg->usb_icl_votable, FLASH_ACTIVE_VOTER, true, + val->intval - USBIN_300UA); + smblite_lib_dbg(chg, PR_MISC, "flash_active = 1, ICL set to %d\n", + val->intval - USBIN_300UA); + } + rc = vote(chg->usb_icl_votable, USB_PSY_VOTER, true, val->intval); if (rc < 0) { pr_err("Couldn't vote ICL USB_PSY_VOTER rc=%d\n", rc); @@ -1642,12 +1650,6 @@ int smblite_lib_set_prop_current_max(struct smb_charger *chg, /* Update TypeC Rp based current */ if (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC) { update_sw_icl_max(chg, chg->real_charger_type); - } else if (is_flashlite_active(chg) && (val->intval >= USBIN_400UA)) { - /* For Uusb based SDP port */ - vote(chg->usb_icl_votable, FLASH_ACTIVE_VOTER, true, - val->intval - USBIN_300UA); - smblite_lib_dbg(chg, PR_MISC, "flash_active = 1, ICL set to %d\n", - val->intval - USBIN_300UA); } return 0; @@ -2346,43 +2348,28 @@ static void update_sw_icl_max(struct smb_charger *chg, /* rp-std or legacy, USB BC 1.2 */ switch (type) { case POWER_SUPPLY_TYPE_USB: - /* - * USB_PSY will vote to increase the current to 500/900mA once - * enumeration is done. - */ - if (!is_client_vote_enabled(chg->usb_icl_votable, - USB_PSY_VOTER)) { - /* if flash is active force 500mA */ - vote(chg->usb_icl_votable, USB_PSY_VOTER, true, - is_flashlite_active(chg) ? - USBIN_500UA : USBIN_100UA); - } vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, false, 0); break; case POWER_SUPPLY_TYPE_USB_CDP: - vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, - CDP_CURRENT_UA); + icl_ua = CDP_CURRENT_UA; break; case POWER_SUPPLY_TYPE_USB_DCP: - rp_ua = get_rp_based_dcp_current(chg, typec_mode); - vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, rp_ua); + icl_ua = get_rp_based_dcp_current(chg, typec_mode); break; case POWER_SUPPLY_TYPE_UNKNOWN: default: - vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, - USBIN_100UA); + icl_ua = USBIN_100UA; break; } - if (is_flashlite_active(chg)) { - icl_ua = get_effective_result(chg->usb_icl_votable); - if (icl_ua >= USBIN_400UA) { - vote(chg->usb_icl_votable, FLASH_ACTIVE_VOTER, true, + if (is_flashlite_active(chg) && type != POWER_SUPPLY_TYPE_USB) { + vote(chg->usb_icl_votable, FLASH_ACTIVE_VOTER, true, icl_ua - USBIN_300UA); - smblite_lib_dbg(chg, PR_MISC, "flash_active = 1 ICL is set to %d\n", - icl_ua - USBIN_300UA); - } + smblite_lib_dbg(chg, PR_MISC, "flash_active = 1 ICL is set to %d\n", + icl_ua - USBIN_300UA); + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, icl_ua); } + } static void typec_sink_insertion(struct smb_charger *chg) @@ -2595,7 +2582,7 @@ static void typec_src_removal(struct smb_charger *chg) /* reset input current limit voters */ vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, - is_flashlite_active(chg) ? USBIN_500UA : USBIN_100UA); + is_flashlite_active(chg) ? USBIN_200UA : USBIN_100UA); vote(chg->usb_icl_votable, FLASH_ACTIVE_VOTER, false, 0); vote(chg->usb_icl_votable, USB_PSY_VOTER, false, 0); @@ -2907,6 +2894,22 @@ irqreturn_t smblite_usb_id_irq_handler(int irq, void *data) smblite_lib_dbg(chg, PR_INTERRUPT, "IRQ: %s, id_state=%d\n", "usb-id-irq", id_state); + if (id_state) { + /*otg cable removed */ + if (chg->otg_present) { + if (chg->typec_port) { + typec_set_data_role(chg->typec_port, + TYPEC_DEVICE); + typec_set_pwr_role(chg->typec_port, TYPEC_SINK); + typec_partner_unregister(chg); + } + } + } else if (chg->typec_port) { + /*otg cable inserted */ + typec_partner_register(chg); + typec_set_data_role(chg->typec_port, TYPEC_HOST); + typec_set_pwr_role(chg->typec_port, TYPEC_SOURCE); + } smblite_lib_notify_usb_host(chg, !id_state); diff --git a/drivers/power/supply/qcom/smblite-lib.h b/drivers/power/supply/qcom/smblite-lib.h index 9bfb9c97eb8a..374c8ffba8bc 100644 --- a/drivers/power/supply/qcom/smblite-lib.h +++ b/drivers/power/supply/qcom/smblite-lib.h @@ -61,6 +61,7 @@ enum print_reason { #define USBIN_25UA 25000 #define USBIN_100UA 100000 #define USBIN_150UA 150000 +#define USBIN_200UA 200000 #define USBIN_300UA 300000 #define USBIN_400UA 400000 #define USBIN_500UA 500000 diff --git a/drivers/usb/phy/phy-msm-qusb.c b/drivers/usb/phy/phy-msm-qusb.c index c1e978b2fc43..aaab20dfb419 100644 --- a/drivers/usb/phy/phy-msm-qusb.c +++ b/drivers/usb/phy/phy-msm-qusb.c @@ -24,6 +24,7 @@ #include <linux/regulator/machine.h> #include <linux/usb/phy.h> #include <linux/reset.h> +#include <linux/power_supply.h> #define QUSB2PHY_PLL_PWR_CTL 0x18 #define REF_BUF_EN BIT(0) @@ -111,6 +112,7 @@ #define QUSB2PHY_3P3_VOL_MAX 3200000 /* uV */ #define QUSB2PHY_3P3_HPM_LOAD 30000 /* uA */ +#define SOC_THRESHOLD_LEVEL 45 #define QUSB2PHY_REFCLK_ENABLE BIT(0) #define HSTX_TRIMSIZE 4 @@ -153,6 +155,7 @@ struct qusb_phy { struct regulator *vdda33; struct regulator *vdda18; int vdd_levels[3]; /* none, low, high */ + int vdda33_levels[3]; /* low, min, max */ int init_seq_len; int *qusb_phy_init_seq; u32 major_rev; @@ -169,7 +172,10 @@ struct qusb_phy { bool ulpi_mode; bool dpdm_enable; bool is_se_clk; + bool low_soc; + struct notifier_block psy_nb; + struct work_struct soc_eval_work; struct regulator_desc dpdm_rdesc; struct regulator_dev *dpdm_rdev; @@ -180,6 +186,7 @@ struct qusb_phy { bool vbus_active; bool id_state; struct power_supply *usb_psy; + struct power_supply *batt_psy; struct delayed_work port_det_w; enum port_state port_state; unsigned int dcd_timeout; @@ -265,6 +272,34 @@ static int qusb_phy_config_vdd(struct qusb_phy *qphy, int high) return ret; } +static int qusb_read_battery_soc(struct qusb_phy *qphy, int *soc_val) +{ + union power_supply_propval val = {0,}; + int ret = 0; + + if (!qphy->batt_psy) { + qphy->batt_psy = power_supply_get_by_name("battery"); + if (!qphy->batt_psy) { + dev_err(qphy->phy.dev, "Could not get battery psy\n"); + return -ENODEV; + } + } + + if (qphy->batt_psy) { + ret = power_supply_get_property(qphy->batt_psy, + POWER_SUPPLY_PROP_CAPACITY, &val); + if (ret) { + dev_err(qphy->phy.dev, + "battery SoC read error\n"); + return ret; + } + *soc_val = val.intval; + } + + dev_dbg(qphy->phy.dev, "soc:%d\n", *soc_val); + return ret; +} + static int qusb_phy_enable_power(struct qusb_phy *qphy, bool on) { int ret = 0; @@ -314,8 +349,9 @@ static int qusb_phy_enable_power(struct qusb_phy *qphy, bool on) goto disable_vdda18; } - ret = regulator_set_voltage(qphy->vdda33, QUSB2PHY_3P3_VOL_MIN, - QUSB2PHY_3P3_VOL_MAX); + ret = regulator_set_voltage(qphy->vdda33, qphy->vdda33_levels[1], + qphy->vdda33_levels[2]); + if (ret) { dev_err(qphy->phy.dev, "Unable to set voltage for vdda33:%d\n", ret); @@ -628,6 +664,57 @@ static int qusb_phy_init(struct usb_phy *phy) return 0; } +static int qusb_phy_battery_supply_cb(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct qusb_phy *qphy = container_of(nb, struct qusb_phy, psy_nb); + int soc_val = 0; + + if (event != PSY_EVENT_PROP_CHANGED) + return NOTIFY_OK; + + if (qusb_read_battery_soc(qphy, &soc_val) < 0) { + dev_err(qphy->phy.dev, "%s unable to read battery SoC\n", + __func__); + return NOTIFY_OK; + } + + if (soc_val < SOC_THRESHOLD_LEVEL && !qphy->low_soc) { + /* Reduce voltage to be set to 2.9V for low SoC */ + qphy->vdda33_levels[1] = qphy->vdda33_levels[0]; + qphy->vdda33_levels[2] = qphy->vdda33_levels[0]; + qphy->low_soc = true; + queue_work(system_freezable_wq, &qphy->soc_eval_work); + return NOTIFY_OK; + } + + if (soc_val > SOC_THRESHOLD_LEVEL && qphy->low_soc) { + /* Reset voltage to be set to default for normal SoC */ + qphy->vdda33_levels[1] = QUSB2PHY_3P3_VOL_MIN; + qphy->vdda33_levels[2] = QUSB2PHY_3P3_VOL_MAX; + qphy->low_soc = false; + queue_work(system_freezable_wq, &qphy->soc_eval_work); + } + return NOTIFY_OK; +} + +static void qusb_phy_evaluate_soc(struct work_struct *work) +{ + struct qusb_phy *qphy = + container_of(work, struct qusb_phy, soc_eval_work); + int ret = 0; + + dev_dbg(qphy->phy.dev, "%s setting min voltage for vdda33 as %d\n", + __func__, qphy->vdda33_levels[1]); + ret = regulator_set_voltage(qphy->vdda33, qphy->vdda33_levels[1], + qphy->vdda33_levels[2]); + if (ret) { + dev_err(qphy->phy.dev, + "%s unable to set voltage for vdda33, ret = %d\n", + __func__, ret); + } +} + static void qusb_phy_shutdown(struct usb_phy *phy) { struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy); @@ -1796,9 +1883,30 @@ static int qusb_phy_probe(struct platform_device *pdev) if (ret) return ret; + qphy->vdda33_levels[1] = QUSB2PHY_3P3_VOL_MIN; + qphy->vdda33_levels[2] = QUSB2PHY_3P3_VOL_MAX; + ret = of_property_read_u32(dev->of_node, + "qcom,vdda33-voltage-level", + (u32 *)&qphy->vdda33_levels[0]); + if (!ret) { + INIT_WORK(&qphy->soc_eval_work, qusb_phy_evaluate_soc); + /* Register notifier to change gain based on state of charge */ + qphy->psy_nb.notifier_call = qusb_phy_battery_supply_cb; + ret = power_supply_reg_notifier(&qphy->psy_nb); + if (ret) { + dev_dbg(qphy->phy.dev, + "%s: could not register pwr supply notifier\n", + __func__); + goto remove_phy; + } + qphy->low_soc = false; + qusb_phy_battery_supply_cb(&qphy->psy_nb, + PSY_EVENT_PROP_CHANGED, NULL); + } + ret = qusb_phy_regulator_init(qphy); if (ret) - usb_remove_phy(&qphy->phy); + goto unreg_notifier_and_put_batt_psy; /* de-assert clamp dig n to reduce leakage on 1p8 upon boot up */ qusb_phy_clear_tcsr_clamp(qphy, true); @@ -1838,7 +1946,14 @@ static int qusb_phy_probe(struct platform_device *pdev) } qusb_phy_create_debugfs(qphy); + return 0; +unreg_notifier_and_put_batt_psy: + power_supply_unreg_notifier(&qphy->psy_nb); + if (qphy->batt_psy) + power_supply_put(qphy->batt_psy); +remove_phy: + usb_remove_phy(&qphy->phy); return ret; } @@ -1846,6 +1961,11 @@ static int qusb_phy_remove(struct platform_device *pdev) { struct qusb_phy *qphy = platform_get_drvdata(pdev); + power_supply_unreg_notifier(&qphy->psy_nb); + if (qphy->batt_psy) + power_supply_put(qphy->batt_psy); + if (qphy->usb_psy) + power_supply_put(qphy->usb_psy); debugfs_remove_recursive(qphy->root); usb_remove_phy(&qphy->phy); qphy->cable_connected = false; diff --git a/mm/slub.c b/mm/slub.c index d5f745f6dc31..e3f1fc740977 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -37,6 +37,10 @@ #include <trace/events/kmem.h> +#ifdef CONFIG_SLUB_DEBUG +#include <linux/debugfs.h> +#endif + #include "internal.h" /* @@ -5828,6 +5832,85 @@ struct saved_alias { static struct saved_alias *alias_list; +#ifdef CONFIG_SLUB_DEBUG +static struct dentry *slab_debugfs_top; + +static int alloc_trace_locations(struct seq_file *seq, struct kmem_cache *s, + enum track_item alloc) +{ + unsigned long i; + struct loc_track t = { 0, 0, NULL }; + int node; + unsigned long *map = kmalloc(BITS_TO_LONGS(oo_objects(s->max)) * + sizeof(unsigned long), GFP_KERNEL); + struct kmem_cache_node *n; + + if (!map || !alloc_loc_track(&t, PAGE_SIZE / sizeof(struct location), + GFP_KERNEL)) { + kfree(map); + return -ENOMEM; + } + /* Push back cpu slabs */ + flush_all(s); + + for_each_kmem_cache_node(s, node, n) { + unsigned long flags; + struct page *page; + + if (!atomic_long_read(&n->nr_slabs)) + continue; + + spin_lock_irqsave(&n->list_lock, flags); + list_for_each_entry(page, &n->partial, lru) + process_slab(&t, s, page, alloc, map); + list_for_each_entry(page, &n->full, lru) + process_slab(&t, s, page, alloc, map); + spin_unlock_irqrestore(&n->list_lock, flags); + } + + for (i = 0; i < t.count; i++) { + struct location *l = &t.loc[i]; + + seq_printf(seq, + "alloc_list: call_site=%pS count=%zu object_size=%zu slab_size=%zu slab_name=%s\n", + l->addr, l->count, s->object_size, s->size, s->name); + } + + free_loc_track(&t); + kfree(map); + return 0; +} + +static int slab_debug_alloc_trace(struct seq_file *seq, + void *ignored) +{ + + struct kmem_cache *slab; + + list_for_each_entry(slab, &slab_caches, list) { + if (!(slab->flags & SLAB_STORE_USER)) + continue; + alloc_trace_locations(seq, slab, TRACK_ALLOC); + } + + return 0; +} + +static int slab_debug_alloc_trace_open(struct inode *inode, + struct file *file) +{ + return single_open(file, slab_debug_alloc_trace, + inode->i_private); +} + +static const struct file_operations slab_debug_alloc_fops = { + .open = slab_debug_alloc_trace_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +#endif + static int sysfs_slab_alias(struct kmem_cache *s, const char *name) { struct saved_alias *al; @@ -5874,6 +5957,22 @@ static int __init slab_sysfs_init(void) s->name); } +#ifdef CONFIG_SLUB_DEBUG + if (slub_debug) { + slab_debugfs_top = debugfs_create_dir("slab", NULL); + if (!slab_debugfs_top) { + pr_err("Couldn't create slab debugfs directory\n"); + return -ENODEV; + } + + if (!debugfs_create_file("alloc_trace", 0400, slab_debugfs_top, + NULL, &slab_debug_alloc_fops)) { + pr_err("Couldn't create slab/tests debugfs directory\n"); + return -ENODEV; + } + } +#endif + while (alias_list) { struct saved_alias *al = alias_list; |