diff options
125 files changed, 3140 insertions, 965 deletions
diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi.txt b/Documentation/devicetree/bindings/fb/mdss-dsi.txt index 31994cf28b27..6c20d22f98b4 100644 --- a/Documentation/devicetree/bindings/fb/mdss-dsi.txt +++ b/Documentation/devicetree/bindings/fb/mdss-dsi.txt @@ -103,6 +103,7 @@ Optional properties: - qcom,platform-reset-gpio: Specifies the panel reset gpio. - qcom,platform-te-gpio: Specifies the gpio used for TE. - qcom,platform-bklight-en-gpio: Specifies the gpio used to enable display back-light +- qcom,platform-bklight-en-gpio-invert: Invert the gpio used to enable display back-light - qcom,panel-mode-gpio: Specifies the GPIO to select video/command/single-port/dual-port mode of panel through gpio when it supports these modes. - pinctrl-names: List of names to assign mdss pin states defined in pinctrl device node @@ -267,6 +268,7 @@ Example: qcom,platform-te-gpio = <&msmgpio 24 0>; qcom,platform-enable-gpio = <&msmgpio 58 1>; qcom,platform-bklight-en-gpio = <&msmgpio 86 0>; + qcom,platform-bklight-en-gpio-invert; qcom,panel-mode-gpio = <&msmgpio 107 0>; qcom,dsi-irq-line; qcom,lane-map = "lane_map_3012"; diff --git a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-smb2.txt b/Documentation/devicetree/bindings/power/qcom-charger/qpnp-smb2.txt index cedb68820d26..eabdc6a75fbe 100644 --- a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-smb2.txt +++ b/Documentation/devicetree/bindings/power/qcom-charger/qpnp-smb2.txt @@ -35,6 +35,11 @@ Charger specific properties: addition battery properties will be faked such that the device assumes normal operation. +- qcom,external-vconn + Usage: optional + Value type: <empty> + Definition: Boolean flag which indicates VCONN is sourced externally. + - qcom,fcc-max-ua Usage: optional Value type: <u32> diff --git a/arch/arm/boot/dts/qcom/sdm660-coresight.dtsi b/arch/arm/boot/dts/qcom/sdm660-coresight.dtsi index be625a15f4ec..d712c04b3e70 100644 --- a/arch/arm/boot/dts/qcom/sdm660-coresight.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-coresight.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-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 @@ -241,10 +241,10 @@ }; port@2 { reg = <5>; - funnel_in1_in_tpda_mss: endpoint { + funnel_in1_in_modem_etm0: endpoint { slave-mode; remote-endpoint = - <&tpda_mss_out_funnel_in1>; + <&modem_etm0_out_funnel_in1>; }; }; port@3 { @@ -1112,17 +1112,19 @@ coresight-name = "coresight-tpda"; qcom,tpda-atid = <65>; - qcom,bc-elem-size = <7 32>, - <9 32>; - qcom,tc-elem-size = <3 32>, - <6 32>, - <9 32>; - qcom,dsb-elem-size = <7 32>, - <9 32>; - qcom,cmb-elem-size = <3 32>, - <4 32>, + qcom,bc-elem-size = <8 32>, + <10 32>; + qcom,tc-elem-size = <4 32>, + <7 32>, + <10 32>; + qcom,dsb-elem-size = <2 32>, + <8 32>, + <10 32>, + <11 32>; + qcom,cmb-elem-size = <4 32>, <5 32>, - <9 64>; + <6 32>, + <10 64>; clocks = <&clock_rpmcc RPM_QDSS_CLK>, <&clock_rpmcc RPM_QDSS_A_CLK>; @@ -1209,7 +1211,7 @@ compatible = "arm,primecell"; arm,primecell-periphid = <0x0003b908>; - reg = <0x71c40000 0x1000>; + reg = <0x7140000 0x1000>; reg-names = "funnel-base"; coresight-name = "coresight-funnel-gpu-dl"; @@ -1409,7 +1411,7 @@ coresight-name = "coresight-tpda-apss"; qcom,tpda-atid = <66>; - qcom,dsb-elem-size = <0 128>; + qcom,dsb-elem-size = <0 32>; clocks = <&clock_rpmcc RPM_QDSS_CLK>, <&clock_rpmcc RPM_QDSS_A_CLK>; @@ -1474,9 +1476,9 @@ #size-cells = <0>; port@0 { reg = <0>; - tpda_mss_out_funnel_in1: endpoint { + tpda_mss_out_funnel_dlct: endpoint { remote-endpoint = - <&funnel_in1_in_tpda_mss>; + <&funnel_dlct_in_tpda_mss>; }; }; port@1 { @@ -1636,10 +1638,10 @@ }; port@5 { reg = <2>; - funnel_dlct_in_modem_etm0: endpoint { + funnel_dlct_in_tpda_mss: endpoint { slave-mode; remote-endpoint = - <&modem_etm0_out_funnel_dlct>; + <&tpda_mss_out_funnel_dlct>; }; }; }; @@ -1712,8 +1714,8 @@ qcom,inst-id = <2>; port{ - modem_etm0_out_funnel_dlct: endpoint { - remote-endpoint = <&funnel_dlct_in_modem_etm0>; + modem_etm0_out_funnel_in1: endpoint { + remote-endpoint = <&funnel_in1_in_modem_etm0>; }; }; }; diff --git a/arch/arm/boot/dts/qcom/sdm660.dtsi b/arch/arm/boot/dts/qcom/sdm660.dtsi index 05822d9d7c4e..6e3cd999ac05 100644 --- a/arch/arm/boot/dts/qcom/sdm660.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660.dtsi @@ -2379,5 +2379,9 @@ }; }; +&blsp2_uart1_hs { + status = "ok"; +}; + #include "sdm660-mdss.dtsi" #include "sdm660-mdss-pll.dtsi" diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig index 77b5390fd384..7761c2360675 100644 --- a/arch/arm64/configs/msmcortex_defconfig +++ b/arch/arm64/configs/msmcortex_defconfig @@ -8,13 +8,11 @@ CONFIG_RCU_EXPERT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_CPU_MAX_BUF_SHIFT=17 -CONFIG_CGROUPS=y CONFIG_CGROUP_DEBUG=y CONFIG_CGROUP_FREEZER=y CONFIG_CPUSETS=y CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_SCHEDTUNE=y -CONFIG_CGROUP_SCHED=y CONFIG_RT_GROUP_SCHED=y CONFIG_SCHED_HMP=y CONFIG_SCHED_HMP_CSTATE_AWARE=y @@ -22,6 +20,7 @@ CONFIG_SCHED_CORE_CTL=y CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set # CONFIG_PID_NS is not set +CONFIG_SCHED_AUTOGROUP=y CONFIG_SCHED_TUNE=y CONFIG_BLK_DEV_INITRD=y # CONFIG_RD_XZ is not set diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index 78319858f734..1ad799523a54 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -60,6 +60,22 @@ static int __get_iommu_pgprot(struct dma_attrs *attrs, int prot, return prot; } +static bool is_dma_coherent(struct device *dev, struct dma_attrs *attrs) +{ + bool is_coherent; + + if (dma_get_attr(DMA_ATTR_FORCE_COHERENT, attrs)) + is_coherent = true; + else if (dma_get_attr(DMA_ATTR_FORCE_NON_COHERENT, attrs)) + is_coherent = false; + else if (is_device_dma_coherent(dev)) + is_coherent = true; + else + is_coherent = false; + + return is_coherent; +} + static struct gen_pool *atomic_pool; #define NO_KERNEL_MAPPING_DUMMY 0x2222 #define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K @@ -214,7 +230,7 @@ static void *__dma_alloc(struct device *dev, size_t size, { struct page *page; void *ptr, *coherent_ptr; - bool coherent = is_device_dma_coherent(dev); + bool coherent = is_dma_coherent(dev, attrs); size = PAGE_ALIGN(size); @@ -269,7 +285,7 @@ static void __dma_free(struct device *dev, size_t size, size = PAGE_ALIGN(size); - if (!is_device_dma_coherent(dev)) { + if (!is_dma_coherent(dev, attrs)) { if (__free_from_pool(vaddr, size)) return; if (!dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) @@ -286,7 +302,7 @@ static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page, dma_addr_t dev_addr; dev_addr = swiotlb_map_page(dev, page, offset, size, dir, attrs); - if (!is_device_dma_coherent(dev)) + if (!is_dma_coherent(dev, attrs)) __dma_map_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir); return dev_addr; @@ -297,7 +313,7 @@ static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr, size_t size, enum dma_data_direction dir, struct dma_attrs *attrs) { - if (!is_device_dma_coherent(dev)) + if (!is_dma_coherent(dev, attrs)) __dma_unmap_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir); swiotlb_unmap_page(dev, dev_addr, size, dir, attrs); } @@ -310,7 +326,7 @@ static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl, int i, ret; ret = swiotlb_map_sg_attrs(dev, sgl, nelems, dir, attrs); - if (!is_device_dma_coherent(dev)) + if (!is_dma_coherent(dev, attrs)) for_each_sg(sgl, sg, ret, i) __dma_map_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)), sg->length, dir); @@ -326,7 +342,7 @@ static void __swiotlb_unmap_sg_attrs(struct device *dev, struct scatterlist *sg; int i; - if (!is_device_dma_coherent(dev)) + if (!is_dma_coherent(dev, attrs)) for_each_sg(sgl, sg, nelems, i) __dma_unmap_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)), sg->length, dir); @@ -392,7 +408,7 @@ static int __swiotlb_mmap(struct device *dev, unsigned long off = vma->vm_pgoff; vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot, - is_device_dma_coherent(dev)); + is_dma_coherent(dev, attrs)); if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret)) return ret; @@ -673,7 +689,7 @@ static void *__iommu_alloc_attrs(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs) { - bool coherent = is_device_dma_coherent(dev); + bool coherent = is_dma_coherent(dev, attrs); int ioprot = dma_direction_to_prot(DMA_BIDIRECTIONAL, coherent); size_t iosize = size; void *addr; @@ -770,7 +786,7 @@ static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma, int ret; vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot, - is_device_dma_coherent(dev)); + is_dma_coherent(dev, attrs)); if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret)) return ret; @@ -827,7 +843,7 @@ static dma_addr_t __iommu_map_page(struct device *dev, struct page *page, enum dma_data_direction dir, struct dma_attrs *attrs) { - bool coherent = is_device_dma_coherent(dev); + bool coherent = is_dma_coherent(dev, attrs); int prot = dma_direction_to_prot(dir, coherent); dma_addr_t dev_addr = iommu_dma_map_page(dev, page, offset, size, prot); @@ -880,7 +896,7 @@ static int __iommu_map_sg_attrs(struct device *dev, struct scatterlist *sgl, int nelems, enum dma_data_direction dir, struct dma_attrs *attrs) { - bool coherent = is_device_dma_coherent(dev); + bool coherent = is_dma_coherent(dev, attrs); if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs)) __iommu_sync_sg_for_device(dev, sgl, nelems, dir); @@ -1225,7 +1241,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, size_t count = size >> PAGE_SHIFT; size_t array_size = count * sizeof(struct page *); int i = 0; - bool is_coherent = is_device_dma_coherent(dev); + bool is_coherent = is_dma_coherent(dev, attrs); if (array_size <= PAGE_SIZE) pages = kzalloc(array_size, gfp); @@ -1338,7 +1354,7 @@ static dma_addr_t __iommu_create_mapping(struct device *dev, if (dma_addr == DMA_ERROR_CODE) return dma_addr; prot = __get_iommu_pgprot(attrs, prot, - is_device_dma_coherent(dev)); + is_dma_coherent(dev, attrs)); iova = dma_addr; for (i = 0; i < count; ) { @@ -1418,7 +1434,7 @@ static void *__iommu_alloc_atomic(struct device *dev, size_t size, size_t array_size = count * sizeof(struct page *); int i; void *addr; - bool coherent = is_device_dma_coherent(dev); + bool coherent = is_dma_coherent(dev, attrs); if (array_size <= PAGE_SIZE) pages = kzalloc(array_size, gfp); @@ -1468,7 +1484,7 @@ static void __iommu_free_atomic(struct device *dev, void *cpu_addr, static void *arm_iommu_alloc_attrs(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs) { - bool coherent = is_device_dma_coherent(dev); + bool coherent = is_dma_coherent(dev, attrs); pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL, coherent); struct page **pages; void *addr = NULL; @@ -1520,7 +1536,7 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma, unsigned long uaddr = vma->vm_start; unsigned long usize = vma->vm_end - vma->vm_start; struct page **pages = __iommu_get_pages(cpu_addr, attrs); - bool coherent = is_device_dma_coherent(dev); + bool coherent = is_dma_coherent(dev, attrs); vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot, coherent); @@ -1635,7 +1651,7 @@ int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg, return 0; } prot = __get_iommu_pgprot(attrs, prot, - is_device_dma_coherent(dev)); + is_dma_coherent(dev, attrs)); ret = iommu_map_sg(mapping->domain, iova, sg, nents, prot); if (ret != total_length) { @@ -1688,8 +1704,11 @@ void arm_iommu_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, { struct scatterlist *s; int i; + struct dma_iommu_mapping *mapping = dev->archdata.mapping; + dma_addr_t iova = sg_dma_address(sg); + bool iova_coherent = iommu_is_iova_coherent(mapping->domain, iova); - if (is_device_dma_coherent(dev)) + if (iova_coherent) return; for_each_sg(sg, s, nents, i) @@ -1709,8 +1728,11 @@ void arm_iommu_sync_sg_for_device(struct device *dev, struct scatterlist *sg, { struct scatterlist *s; int i; + struct dma_iommu_mapping *mapping = dev->archdata.mapping; + dma_addr_t iova = sg_dma_address(sg); + bool iova_coherent = iommu_is_iova_coherent(mapping->domain, iova); - if (is_device_dma_coherent(dev)) + if (iova_coherent) return; for_each_sg(sg, s, nents, i) @@ -1742,7 +1764,7 @@ static dma_addr_t arm_coherent_iommu_map_page(struct device *dev, prot = __dma_direction_to_prot(dir); prot = __get_iommu_pgprot(attrs, prot, - is_device_dma_coherent(dev)); + is_dma_coherent(dev, attrs)); ret = iommu_map(mapping->domain, dma_addr, page_to_phys(page), len, prot); @@ -1769,7 +1791,7 @@ static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page, unsigned long offset, size_t size, enum dma_data_direction dir, struct dma_attrs *attrs) { - if (!is_device_dma_coherent(dev) && + if (!is_dma_coherent(dev, attrs) && !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs)) __dma_page_cpu_to_dev(page, offset, size, dir); @@ -1795,8 +1817,10 @@ static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle, mapping->domain, iova)); int offset = handle & ~PAGE_MASK; int len = PAGE_ALIGN(size + offset); + bool iova_coherent = iommu_is_iova_coherent(mapping->domain, + handle); - if (!(is_device_dma_coherent(dev) || + if (!(iova_coherent || dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))) __dma_page_dev_to_cpu(page, offset, size, dir); @@ -1812,8 +1836,9 @@ static void arm_iommu_sync_single_for_cpu(struct device *dev, struct page *page = phys_to_page(iommu_iova_to_phys( mapping->domain, iova)); unsigned int offset = handle & ~PAGE_MASK; + bool iova_coherent = iommu_is_iova_coherent(mapping->domain, handle); - if (!is_device_dma_coherent(dev)) + if (!iova_coherent) __dma_page_dev_to_cpu(page, offset, size, dir); } @@ -1825,8 +1850,9 @@ static void arm_iommu_sync_single_for_device(struct device *dev, struct page *page = phys_to_page(iommu_iova_to_phys( mapping->domain, iova)); unsigned int offset = handle & ~PAGE_MASK; + bool iova_coherent = iommu_is_iova_coherent(mapping->domain, handle); - if (!is_device_dma_coherent(dev)) + if (!iova_coherent) __dma_page_cpu_to_dev(page, offset, size, dir); } diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index c8bfb6077224..118a4f245ad1 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -306,16 +306,56 @@ static ssize_t __ref store_sched_static_cluster_pwr_cost(struct device *dev, return err; } +static ssize_t show_sched_cluser_wake_idle(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct cpu *cpu = container_of(dev, struct cpu, dev); + ssize_t rc; + int cpuid = cpu->dev.id; + unsigned int wake_up_idle; + + wake_up_idle = sched_get_cluster_wake_idle(cpuid); + + rc = scnprintf(buf, PAGE_SIZE-2, "%d\n", wake_up_idle); + + return rc; +} + +static ssize_t __ref store_sched_cluster_wake_idle(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct cpu *cpu = container_of(dev, struct cpu, dev); + int err; + int cpuid = cpu->dev.id; + unsigned int wake_up_idle; + + err = kstrtouint(strstrip((char *)buf), 0, &wake_up_idle); + if (err) + return err; + + err = sched_set_cluster_wake_idle(cpuid, wake_up_idle); + + if (err >= 0) + err = count; + + return err; +} + static DEVICE_ATTR(sched_static_cpu_pwr_cost, 0644, show_sched_static_cpu_pwr_cost, store_sched_static_cpu_pwr_cost); static DEVICE_ATTR(sched_static_cluster_pwr_cost, 0644, show_sched_static_cluster_pwr_cost, store_sched_static_cluster_pwr_cost); +static DEVICE_ATTR(sched_cluster_wake_up_idle, 0644, + show_sched_cluser_wake_idle, + store_sched_cluster_wake_idle); static struct attribute *hmp_sched_cpu_attrs[] = { &dev_attr_sched_static_cpu_pwr_cost.attr, &dev_attr_sched_static_cluster_pwr_cost.attr, + &dev_attr_sched_cluster_wake_up_idle.attr, NULL }; diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index c056ad9625b1..896bd6ec90f6 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-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 @@ -606,6 +606,13 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, unsigned attr, if (sess->smmu.enabled) { init_dma_attrs(&attrs); dma_set_attr(DMA_ATTR_EXEC_MAPPING, &attrs); + + if (map->attr & FASTRPC_ATTR_NON_COHERENT) + dma_set_attr(DMA_ATTR_FORCE_NON_COHERENT, + &attrs); + else if (map->attr & FASTRPC_ATTR_COHERENT) + dma_set_attr(DMA_ATTR_FORCE_COHERENT, &attrs); + VERIFY(err, map->table->nents == msm_dma_map_sg_attrs(sess->dev, map->table->sgl, map->table->nents, @@ -1143,10 +1150,15 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx) for (oix = 0; oix < inbufs + outbufs; ++oix) { int i = ctx->overps[oix]->raix; struct fastrpc_mmap *map = ctx->maps[i]; - if (ctx->fl->sctx->smmu.coherent) - continue; + if (map && map->uncached) continue; + if (ctx->fl->sctx->smmu.coherent && + !(map && (map->attr & FASTRPC_ATTR_NON_COHERENT))) + continue; + if (map && (map->attr & FASTRPC_ATTR_COHERENT)) + continue; + if (rpra[i].buf.len && ctx->overps[oix]->mstart) dmac_flush_range(uint64_to_ptr(rpra[i].buf.pv), uint64_to_ptr(rpra[i].buf.pv + rpra[i].buf.len)); @@ -1213,6 +1225,12 @@ static void inv_args_pre(struct smq_invoke_ctx *ctx) continue; if (!rpra[i].buf.len) continue; + if (ctx->fl->sctx->smmu.coherent && + !(map && (map->attr & FASTRPC_ATTR_NON_COHERENT))) + continue; + if (map && (map->attr & FASTRPC_ATTR_COHERENT)) + continue; + if (buf_page_start(ptr_to_uint64((void *)rpra)) == buf_page_start(rpra[i].buf.pv)) continue; @@ -1239,10 +1257,17 @@ static void inv_args(struct smq_invoke_ctx *ctx) outbufs = REMOTE_SCALARS_OUTBUFS(sc); for (i = inbufs; i < inbufs + outbufs; ++i) { struct fastrpc_mmap *map = ctx->maps[i]; + if (map && map->uncached) continue; if (!rpra[i].buf.len) continue; + if (ctx->fl->sctx->smmu.coherent && + !(map && (map->attr & FASTRPC_ATTR_NON_COHERENT))) + continue; + if (map && (map->attr & FASTRPC_ATTR_COHERENT)) + continue; + if (buf_page_start(ptr_to_uint64((void *)rpra)) == buf_page_start(rpra[i].buf.pv)) { inv = 1; @@ -1389,15 +1414,13 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, goto bail; } - if (!fl->sctx->smmu.coherent) { - inv_args_pre(ctx); - if (mode == FASTRPC_MODE_SERIAL) - inv_args(ctx); - } + inv_args_pre(ctx); + if (mode == FASTRPC_MODE_SERIAL) + inv_args(ctx); VERIFY(err, 0 == fastrpc_invoke_send(ctx, kernel, invoke->handle)); if (err) goto bail; - if (mode == FASTRPC_MODE_PARALLEL && !fl->sctx->smmu.coherent) + if (mode == FASTRPC_MODE_PARALLEL) inv_args(ctx); wait: if (kernel) diff --git a/drivers/char/adsprpc_shared.h b/drivers/char/adsprpc_shared.h index fe8257ad3db2..4fc9396bfd3a 100644 --- a/drivers/char/adsprpc_shared.h +++ b/drivers/char/adsprpc_shared.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-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 @@ -33,6 +33,12 @@ /* Set for buffers that have no virtual mapping in userspace */ #define FASTRPC_ATTR_NOVA 0x1 +/* Set for buffers that are NOT dma coherent */ +#define FASTRPC_ATTR_NON_COHERENT 0x2 + +/* Set for buffers that are dma coherent */ +#define FASTRPC_ATTR_COHERENT 0x4 + /* Driver should operate in parallel with the co-processor */ #define FASTRPC_MODE_PARALLEL 0 diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 7c73657b399e..05b6ca9b5c55 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -43,6 +43,7 @@ msm-y := \ sde/sde_encoder_phys_vid.o \ sde/sde_encoder_phys_cmd.o \ sde/sde_irq.o \ + sde/sde_kms_utils.o \ sde/sde_kms.o \ sde/sde_plane.o \ msm_atomic.o \ @@ -89,5 +90,6 @@ obj-$(CONFIG_DRM_MSM) += sde/sde_hw_catalog.o \ sde/sde_hw_sspp.o \ sde/sde_hw_wb.o \ sde/sde_hw_pingpong.o \ + sde/sde_hw_mdp_top.o \ sde/sde_hw_interrupts.o \ sde/sde_mdp_formats.o diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c index 3c30267e7283..5fc1664fd9a0 100644 --- a/drivers/gpu/drm/msm/sde/sde_crtc.c +++ b/drivers/gpu/drm/msm/sde/sde_crtc.c @@ -19,40 +19,11 @@ #include "sde_kms.h" #include "sde_hw_lm.h" #include "sde_hw_mdp_ctl.h" +#include "sde_crtc.h" -#define CRTC_DUAL_MIXERS 2 -#define PENDING_FLIP 2 - -#define CRTC_HW_MIXER_MAXSTAGES(c, idx) ((c)->mixer[idx].sblk->maxblendstages) - -struct sde_crtc_mixer { - struct sde_hw_dspp *hw_dspp; - struct sde_hw_mixer *hw_lm; - struct sde_hw_ctl *hw_ctl; - u32 flush_mask; -}; - -struct sde_crtc { - struct drm_crtc base; - char name[8]; - struct drm_plane *plane; - struct drm_plane *planes[8]; - struct drm_encoder *encoder; - int id; - bool enabled; - - spinlock_t lm_lock; /* protect registers */ - - /* HW Resources reserved for the crtc */ - u32 num_ctls; - u32 num_mixers; - struct sde_crtc_mixer mixer[CRTC_DUAL_MIXERS]; - - /*if there is a pending flip, these will be non-null */ - struct drm_pending_vblank_event *event; -}; - -#define to_sde_crtc(x) container_of(x, struct sde_crtc, base) +#define CTL(i) (CTL_0 + (i)) +#define LM(i) (LM_0 + (i)) +#define INTF(i) (INTF_0 + (i)) static struct sde_kms *get_kms(struct drm_crtc *crtc) { @@ -60,89 +31,91 @@ static struct sde_kms *get_kms(struct drm_crtc *crtc) return to_sde_kms(priv->kms); } -static inline struct sde_hw_ctl *sde_crtc_rm_get_ctl_path(enum sde_ctl idx, - void __iomem *addr, - struct sde_mdss_cfg *m) -{ - /* - * This module keeps track of the requested hw resources state, - * if the requested resource is being used it returns NULL, - * otherwise it returns the hw driver struct - */ - return sde_hw_ctl_init(idx, addr, m); -} - -static inline struct sde_hw_mixer *sde_crtc_rm_get_mixer(enum sde_lm idx, - void __iomem *addr, - struct sde_mdss_cfg *m) -{ - /* - * This module keeps track of the requested hw resources state, - * if the requested resource is being used it returns NULL, - * otherwise it returns the hw driver struct - */ - return sde_hw_lm_init(idx, addr, m); -} - static int sde_crtc_reserve_hw_resources(struct drm_crtc *crtc, struct drm_encoder *encoder) { - /* - * Assign CRTC resources - * num_ctls; - * num_mixers; - * sde_lm mixer[CRTC_MAX_PIPES]; - * sde_ctl ctl[CRTC_MAX_PIPES]; - */ struct sde_crtc *sde_crtc = to_sde_crtc(crtc); - struct sde_kms *kms = get_kms(crtc); - enum sde_lm lm_id[CRTC_DUAL_MIXERS]; - enum sde_ctl ctl_id[CRTC_DUAL_MIXERS]; - int i; - - if (!kms) { - DBG("[%s] invalid kms\n", __func__); + struct sde_kms *sde_kms = get_kms(crtc); + struct sde_encoder_hw_resources enc_hw_res; + const struct sde_hw_res_map *plat_hw_res_map; + enum sde_lm unused_lm_id[CRTC_DUAL_MIXERS] = {0}; + enum sde_lm lm_idx; + int i, count = 0; + + if (!sde_kms) { + DBG("[%s] invalid kms", __func__); return -EINVAL; } - if (!kms->mmio) + if (!sde_kms->mmio) return -EINVAL; - /* - * simple check validate against catalog - */ - sde_crtc->num_ctls = 1; - sde_crtc->num_mixers = 1; - ctl_id[0] = CTL_0; - lm_id[0] = LM_0; - - /* - * need to also enable MDP core clock and AHB CLK - * before touching HW driver - */ - DBG("%s Enable clocks\n", __func__); - sde_enable(kms); - for (i = 0; i < sde_crtc->num_ctls; i++) { - sde_crtc->mixer[i].hw_ctl = sde_crtc_rm_get_ctl_path(ctl_id[i], - kms->mmio, kms->catalog); - if (!sde_crtc->mixer[i].hw_ctl) { - DBG("[%s], Invalid ctl_path", __func__); - return -EACCES; + /* Get unused LMs */ + for (i = 0; i < sde_kms->catalog->mixer_count; i++) { + if (!sde_rm_get_mixer(sde_kms, LM(i))) { + unused_lm_id[count++] = LM(i); + if (count == CRTC_DUAL_MIXERS) + break; } } - for (i = 0; i < sde_crtc->num_mixers; i++) { - sde_crtc->mixer[i].hw_lm = sde_crtc_rm_get_mixer(lm_id[i], - kms->mmio, kms->catalog); - if (!sde_crtc->mixer[i].hw_lm) { - DBG("[%s], Invalid ctl_path", __func__); - return -EACCES; + /* query encoder resources */ + sde_encoder_get_hw_resources(sde_crtc->encoder, &enc_hw_res); + + /* parse encoder hw resources, find CTL paths */ + for (i = CTL_0; i <= sde_kms->catalog->ctl_count; i++) { + WARN_ON(sde_crtc->num_ctls > CRTC_DUAL_MIXERS); + if (enc_hw_res.ctls[i]) { + struct sde_crtc_mixer *mixer = + &sde_crtc->mixer[sde_crtc->num_ctls]; + mixer->hw_ctl = sde_rm_get_ctl_path(sde_kms, i); + if (IS_ERR_OR_NULL(mixer->hw_ctl)) { + DBG("[%s], Invalid ctl_path", __func__); + return -EACCES; + } + sde_crtc->num_ctls++; } } + + /* shortcut this process if encoder has no ctl paths */ + if (!sde_crtc->num_ctls) + return 0; + /* - * need to disable MDP core clock and AHB CLK + * Get default LMs if specified in platform config + * other wise acquire the free LMs */ - sde_disable(kms); + for (i = INTF_0; i <= sde_kms->catalog->intf_count; i++) { + if (enc_hw_res.intfs[i]) { + struct sde_crtc_mixer *mixer = + &sde_crtc->mixer[sde_crtc->num_mixers]; + plat_hw_res_map = sde_rm_get_res_map(sde_kms, i); + + lm_idx = plat_hw_res_map->lm; + if (!lm_idx) + lm_idx = unused_lm_id[sde_crtc->num_mixers]; + + DBG("Acquiring LM %d", lm_idx); + mixer->hw_lm = sde_rm_acquire_mixer(sde_kms, lm_idx); + if (IS_ERR_OR_NULL(mixer->hw_lm)) { + DBG("[%s], Invalid mixer", __func__); + return -EACCES; + } + /* interface info */ + mixer->intf_idx = i; + mixer->mode = enc_hw_res.intfs[i]; + sde_crtc->num_mixers++; + } + } + + DBG("control paths %d, num_mixers %d, lm[0] %d, ctl[0] %d ", + sde_crtc->num_ctls, sde_crtc->num_mixers, + sde_crtc->mixer[0].hw_lm->idx, + sde_crtc->mixer[0].hw_ctl->idx); + if (sde_crtc->num_mixers == CRTC_DUAL_MIXERS) + DBG("lm[1] %d, ctl[1], %d", + sde_crtc->mixer[1].hw_lm->idx, + sde_crtc->mixer[1].hw_ctl->idx); return 0; } @@ -278,6 +251,7 @@ static void blend_setup(struct drm_crtc *crtc) unsigned long flags; int i, j, plane_cnt = 0; + DBG(""); spin_lock_irqsave(&sde_crtc->lm_lock, flags); /* ctl could be reserved already */ @@ -353,10 +327,104 @@ out: spin_unlock_irqrestore(&sde_crtc->lm_lock, flags); } +/* if file!=NULL, this is preclose potential cancel-flip path */ +static void complete_flip(struct drm_crtc *crtc, struct drm_file *file) +{ + struct sde_crtc *sde_crtc = to_sde_crtc(crtc); + struct drm_device *dev = crtc->dev; + struct drm_pending_vblank_event *event; + unsigned long flags; + + spin_lock_irqsave(&dev->event_lock, flags); + event = sde_crtc->event; + if (event) { + /* if regular vblank case (!file) or if cancel-flip from + * preclose on file that requested flip, then send the + * event: + */ + if (!file || (event->base.file_priv == file)) { + sde_crtc->event = NULL; + DBG("%s: send event: %pK", sde_crtc->name, event); + drm_send_vblank_event(dev, sde_crtc->id, event); + } + } + spin_unlock_irqrestore(&dev->event_lock, flags); +} + +static void sde_crtc_vblank_cb(void *data) +{ + struct drm_crtc *crtc = (struct drm_crtc *)data; + struct sde_crtc *sde_crtc = to_sde_crtc(crtc); + unsigned pending; + + /* unregister callback */ + sde_encoder_register_vblank_callback(sde_crtc->encoder, NULL, NULL); + + pending = atomic_xchg(&sde_crtc->pending, 0); + + if (pending & PENDING_FLIP) + complete_flip(crtc, NULL); +} + +static int frame_flushed(struct sde_crtc *sde_crtc) +{ + struct vsync_info vsync; + + /* encoder get vsync_info */ + /* if frame_count does not match frame is flushed */ + sde_encoder_get_vsync_info(sde_crtc->encoder, &vsync); + + return (vsync.frame_count & sde_crtc->vsync_count); + +} + +void sde_crtc_wait_for_commit_done(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct sde_crtc *sde_crtc = to_sde_crtc(crtc); + u32 pending; + int i, ret; + + /* ref count the vblank event */ + ret = drm_crtc_vblank_get(crtc); + if (ret) + return; + + /* register callback */ + sde_encoder_register_vblank_callback(sde_crtc->encoder, + sde_crtc_vblank_cb, + (void *)crtc); + + /* wait */ + pending = atomic_read(&sde_crtc->pending); + if (pending & PENDING_FLIP) { + wait_event_timeout(dev->vblank[drm_crtc_index(crtc)].queue, + (frame_flushed(sde_crtc) != 0), + msecs_to_jiffies(CRTC_MAX_WAIT_ONE_FRAME)); + if (ret <= 0) + dev_warn(dev->dev, "vblank time out, crtc=%d\n", + sde_crtc->id); + } + + for (i = 0; i < sde_crtc->num_ctls; i++) + sde_crtc->mixer[i].flush_mask = 0; + + /* release */ + drm_crtc_vblank_put(crtc); +} + static void request_pending(struct drm_crtc *crtc, u32 pending) { - DBG(""); + struct sde_crtc *sde_crtc = to_sde_crtc(crtc); + struct vsync_info vsync; + + /* request vsync info, cache the current frame count */ + sde_encoder_get_vsync_info(sde_crtc->encoder, &vsync); + sde_crtc->vsync_count = vsync.frame_count; + + atomic_or(pending, &sde_crtc->pending); } + /** * Flush the CTL PATH */ @@ -369,14 +437,12 @@ static u32 crtc_flush_all(struct drm_crtc *crtc) DBG(""); for (i = 0; i < sde_crtc->num_ctls; i++) { - /* - * Query flush_mask from encoder - * and append to the ctl_path flush_mask - */ ctl = sde_crtc->mixer[i].hw_ctl; ctl->ops.get_bitmask_intf(ctl, &(sde_crtc->mixer[i].flush_mask), - INTF_1); + sde_crtc->mixer[i].intf_idx); + DBG("Flushing CTL_ID %d, flush_mask %x", ctl->idx, + sde_crtc->mixer[i].flush_mask); ctl->ops.setup_flush(ctl, sde_crtc->mixer[i].flush_mask); } @@ -425,7 +491,7 @@ static void sde_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_device *dev = crtc->dev; unsigned long flags; - DBG(""); + DBG("%s: event: %pK", sde_crtc->name, crtc->state->event); WARN_ON(sde_crtc->event); @@ -605,6 +671,6 @@ struct drm_crtc *sde_crtc_init(struct drm_device *dev, return ERR_PTR(-EINVAL); } - DBG("%s: Successfully initialized crtc\n", __func__); + DBG("%s: Successfully initialized crtc", __func__); return crtc; } diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.h b/drivers/gpu/drm/msm/sde/sde_crtc.h new file mode 100644 index 000000000000..9f14f999913d --- /dev/null +++ b/drivers/gpu/drm/msm/sde/sde_crtc.h @@ -0,0 +1,79 @@ +/* Copyright (c) 2015-2016, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SDE_CRTC_H_ +#define _SDE_CRTC_H_ + +#include "drm_crtc.h" + +#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) + +#define CRTC_DUAL_MIXERS 2 +#define PENDING_FLIP 2 +/* worst case one frame wait time based on 30 FPS : 33.33ms*/ +#define CRTC_MAX_WAIT_ONE_FRAME 34 +#define CRTC_HW_MIXER_MAXSTAGES(c, idx) ((c)->mixer[idx].sblk->maxblendstages) + +/** + * struct sde_crtc_mixer - stores the map for each virtual pipeline in the CRTC + * @hw_dspp : DSPP HW Driver context + * @hw_lm : LM HW Driver context + * @hw_ctl : CTL Path HW driver context + * @intf_idx : Interface idx + * @mode : Interface mode Active/CMD + * @flush_mask : Flush mask value for this commit + */ +struct sde_crtc_mixer { + struct sde_hw_dspp *hw_dspp; + struct sde_hw_mixer *hw_lm; + struct sde_hw_ctl *hw_ctl; + enum sde_intf intf_idx; + enum sde_intf_mode mode; + u32 flush_mask; +}; + +/** + * struct sde_crtc - virtualized CRTC data structure + * @base : Base drm crtc structure + * @name : ASCII description of this crtc + * @encoder : Associated drm encoder object + * @id : Unique crtc identifier + * @lm_lock : LM register access spinlock + * @num_ctls : Number of ctl paths in use + * @num_mixers : Number of mixers in use + * @mixer : List of active mixers + * @event : Pointer to last received drm vblank event + * @pending : Whether or not an update is pending + * @vsync_count : Running count of received vsync events + */ +struct sde_crtc { + struct drm_crtc base; + char name[8]; + struct drm_encoder *encoder; + int id; + + spinlock_t lm_lock; /* protect registers */ + + /* HW Resources reserved for the crtc */ + u32 num_ctls; + u32 num_mixers; + struct sde_crtc_mixer mixer[CRTC_DUAL_MIXERS]; + + /*if there is a pending flip, these will be non-null */ + struct drm_pending_vblank_event *event; + atomic_t pending; + u32 vsync_count; +}; + +#define to_sde_crtc(x) container_of(x, struct sde_crtc, base) + +#endif /* _SDE_CRTC_H_ */ diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c index 2a3bc3004e6c..ad72bca11669 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder.c +++ b/drivers/gpu/drm/msm/sde/sde_encoder.c @@ -148,7 +148,7 @@ static void sde_encoder_destroy(struct drm_encoder *drm_enc) if (sde_enc->num_phys_encs) { DRM_ERROR("Expected num_phys_encs to be 0 not %d\n", - sde_enc->num_phys_encs); + sde_enc->num_phys_encs); } drm_encoder_cleanup(drm_enc); @@ -201,6 +201,7 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, { struct sde_encoder_virt *sde_enc = NULL; int i = 0; + bool splitmode = false; DBG(""); @@ -211,11 +212,23 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, sde_enc = to_sde_encoder_virt(drm_enc); + /* + * Panel is driven by two interfaces ,each interface drives half of + * the horizontal + */ + if (sde_enc->num_phys_encs == 2) + splitmode = true; + for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; - - if (phys && phys->phys_ops.mode_set) - phys->phys_ops.mode_set(phys, mode, adjusted_mode); + if (phys) { + phys->phys_ops.mode_set(phys, + mode, + adjusted_mode, + splitmode); + if (memcmp(mode, adjusted_mode, sizeof(*mode)) != 0) + DRM_ERROR("adjusted modes not supported\n"); + } } } @@ -223,6 +236,7 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) { struct sde_encoder_virt *sde_enc = NULL; int i = 0; + bool splitmode = false; DBG(""); @@ -235,10 +249,19 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) bs_set(sde_enc, 1); + if (sde_enc->num_phys_encs == 2) + splitmode = true; + + for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; if (phys && phys->phys_ops.enable) + + /* enable/disable dual interface top config */ + if (phys->phys_ops.enable_split_config) + phys->phys_ops.enable_split_config(phys, + splitmode); phys->phys_ops.enable(phys); } } @@ -380,13 +403,11 @@ static int sde_encoder_setup_display(struct sde_encoder_virt *sde_enc, * h_tile_instance_ids[2] = {0, 1}; DSI0 = left, DSI1 = right * h_tile_instance_ids[2] = {1, 0}; DSI1 = left, DSI0 = right */ + const struct sde_hw_res_map *hw_res_map = NULL; enum sde_intf intf_idx = INTF_MAX; - enum sde_ctl ctl_idx = CTL_0; + enum sde_ctl ctl_idx = CTL_MAX; u32 controller_id = disp_info->h_tile_instance[i]; - if (intf_type == INTF_HDMI) - ctl_idx = CTL_2; - DBG("h_tile_instance %d = %d", i, controller_id); intf_idx = sde_encoder_get_intf(sde_kms->catalog, @@ -396,6 +417,12 @@ static int sde_encoder_setup_display(struct sde_encoder_virt *sde_enc, ret = -EINVAL; } + hw_res_map = sde_rm_get_res_map(sde_kms, intf_idx); + if (IS_ERR_OR_NULL(hw_res_map)) + ret = -EINVAL; + else + ctl_idx = hw_res_map->ctl; + /* Create both VID and CMD Phys Encoders here */ if (!ret) ret = sde_encoder_virt_add_phys_vid_enc( @@ -461,6 +488,25 @@ void sde_encoder_register_vblank_callback(struct drm_encoder *drm_enc, spin_unlock_irqrestore(&sde_enc->spin_lock, lock_flags); } +void sde_encoder_get_vsync_info(struct drm_encoder *drm_enc, + struct vsync_info *vsync) +{ + struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc); + struct sde_encoder_phys *phys; + + DBG(""); + + if (!vsync) { + DRM_ERROR("Invalid pointer"); + return; + } + + /* we get the vsync info from the intf at index 0: master index */ + phys = sde_enc->phys_encs[0]; + if (phys) + phys->phys_ops.get_vsync_info(phys, vsync); +} + /* encoders init, * initialize encoder based on displays */ diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h index 27fc11175c19..d35e084f9bef 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h +++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h @@ -30,7 +30,8 @@ struct sde_encoder_virt_ops { struct sde_encoder_phys_ops { void (*mode_set)(struct sde_encoder_phys *encoder, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); + struct drm_display_mode *adjusted_mode, + bool splitmode); bool (*mode_fixup)(struct sde_encoder_phys *encoder, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode); @@ -39,6 +40,10 @@ struct sde_encoder_phys_ops { void (*destroy)(struct sde_encoder_phys *encoder); void (*get_hw_resources)(struct sde_encoder_phys *encoder, struct sde_encoder_hw_resources *hw_res); + void (*get_vsync_info)(struct sde_encoder_phys *enc, + struct vsync_info *vsync); + void (*enable_split_config)(struct sde_encoder_phys *enc, + bool enable); }; struct sde_encoder_phys { diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c index 33d1a8eef7a5..aefa11d5cdde 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c +++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c @@ -1,5 +1,4 @@ -/* - * Copyright (c) 2015 The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2016, 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 @@ -9,7 +8,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * */ #include "msm_drv.h" @@ -19,6 +17,7 @@ #include "sde_encoder_phys.h" #include "sde_mdp_formats.h" +#include "sde_hw_mdp_top.h" #define VBLANK_TIMEOUT msecs_to_jiffies(100) @@ -232,14 +231,26 @@ static void sde_encoder_phys_vid_flush_intf(struct sde_encoder_phys *phys_enc) ctl->idx, flush_mask, intf->idx); } -static void sde_encoder_phys_vid_mode_set( - struct sde_encoder_phys *phys_enc, - struct drm_display_mode *mode, - struct drm_display_mode *adj_mode) +static void sde_encoder_phys_vid_mode_set(struct sde_encoder_phys *phys_enc, + struct drm_display_mode *mode, + struct drm_display_mode + *adjusted_mode, + bool splitmode) { - phys_enc->cached_mode = *adj_mode; - DBG("intf %d, caching mode:", phys_enc->hw_intf->idx); - drm_mode_debug_printmodeline(adj_mode); + mode = adjusted_mode; + phys_enc->cached_mode = *adjusted_mode; + if (splitmode) { + phys_enc->cached_mode.hdisplay >>= 1; + phys_enc->cached_mode.htotal >>= 1; + phys_enc->cached_mode.hsync_start >>= 1; + phys_enc->cached_mode.hsync_end >>= 1; + } + + DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", + mode->base.id, mode->name, mode->vrefresh, mode->clock, + mode->hdisplay, mode->hsync_start, mode->hsync_end, mode->htotal, + mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal, + mode->type, mode->flags); } static void sde_encoder_phys_vid_setup_timing_engine( @@ -428,8 +439,57 @@ static void sde_encoder_phys_vid_get_hw_resources( struct sde_encoder_phys *phys_enc, struct sde_encoder_hw_resources *hw_res) { + struct msm_drm_private *priv = phys_enc->parent->dev->dev_private; + struct sde_kms *sde_kms = to_sde_kms(priv->kms); + const struct sde_hw_res_map *hw_res_map; + + DBG("Intf %d\n", phys_enc->hw_intf->idx); + + hw_res->intfs[phys_enc->hw_intf->idx] = INTF_MODE_VIDEO; + /* + * defaults should not be in use, + * otherwise signal/return failure + */ + hw_res_map = sde_rm_get_res_map(sde_kms, phys_enc->hw_intf->idx); + + /* This is video mode panel so PINGPONG will be in by-pass mode + * only assign ctl path.For cmd panel check if pp_split is + * enabled, override default map + */ + hw_res->ctls[hw_res_map->ctl] = true; +} + +/** + * video mode will use the intf (get_status) + * cmd mode will use the pingpong (get_vsync_info) + * to get this information + */ +static void sde_encoder_intf_get_vsync_info(struct sde_encoder_phys *phys_enc, + struct vsync_info *vsync) +{ + struct intf_status status; + DBG(""); - hw_res->intfs[phys_enc->hw_intf->idx] = true; + phys_enc->hw_intf->ops.get_status(phys_enc->hw_intf, &status); + vsync->frame_count = status.frame_count; + vsync->line_count = status.line_count; + DBG(" sde_encoder_intf_get_vsync_info, count %d", vsync->frame_count); +} + +static void sde_encoder_intf_split_config(struct sde_encoder_phys *phys_enc, + bool enable) +{ + struct msm_drm_private *priv = phys_enc->parent->dev->dev_private; + struct sde_kms *sde_kms = to_sde_kms(priv->kms); + struct sde_hw_mdp *mdp = sde_hw_mdptop_init(MDP_TOP, sde_kms->mmio, + sde_kms->catalog); + struct split_pipe_cfg cfg; + + DBG("%p", mdp); + cfg.en = true; + cfg.mode = INTF_MODE_VIDEO; + if (!IS_ERR_OR_NULL(mdp)) + mdp->ops.setup_split_pipe(mdp, &cfg); } static void sde_encoder_phys_vid_init_cbs(struct sde_encoder_phys_ops *ops) @@ -440,6 +500,8 @@ static void sde_encoder_phys_vid_init_cbs(struct sde_encoder_phys_ops *ops) ops->disable = sde_encoder_phys_vid_disable; ops->destroy = sde_encoder_phys_vid_destroy; ops->get_hw_resources = sde_encoder_phys_vid_get_hw_resources; + ops->get_vsync_info = sde_encoder_intf_get_vsync_info; + ops->enable_split_config = sde_encoder_intf_split_config; } struct sde_encoder_phys *sde_encoder_phys_vid_init( @@ -472,8 +534,7 @@ struct sde_encoder_phys *sde_encoder_phys_vid_init( goto fail; } - phys_enc->hw_ctl = sde_hw_ctl_init(ctl_idx, sde_kms->mmio, - sde_kms->catalog); + phys_enc->hw_ctl = sde_rm_acquire_ctl_path(sde_kms, ctl_idx); if (!phys_enc->hw_ctl) { ret = -ENOMEM; goto fail; diff --git a/drivers/gpu/drm/msm/sde/sde_hw_intf.c b/drivers/gpu/drm/msm/sde/sde_hw_intf.c index 072cb6770bc8..8dd306720e90 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_intf.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_intf.c @@ -13,6 +13,7 @@ #include "sde_hwio.h" #include "sde_hw_catalog.h" #include "sde_hw_intf.h" +#include "sde_hw_mdp_top.h" #define INTF_TIMING_ENGINE_EN 0x000 #define INTF_CONFIG 0x004 @@ -205,10 +206,16 @@ static void sde_hw_intf_enable_timing_engine( /* Display interface select */ if (enable) { - intf_sel = SDE_REG_READ(c, DISP_INTF_SEL); + /* top block */ + struct sde_hw_mdp *mdp = sde_hw_mdptop_init(MDP_TOP, + c->base_off, + intf->mdss); + struct sde_hw_blk_reg_map *top = &mdp->hw; - intf_sel |= (intf->cap->type << ((intf->idx) * 8)); - SDE_REG_WRITE(c, DISP_INTF_SEL, intf_sel); + intf_sel = SDE_REG_READ(top, DISP_INTF_SEL); + + intf_sel |= (intf->cap->type << ((intf->idx - INTF_0) * 8)); + SDE_REG_WRITE(top, DISP_INTF_SEL, intf_sel); } SDE_REG_WRITE(c, INTF_TIMING_ENGINE_EN, @@ -366,6 +373,7 @@ struct sde_hw_intf *sde_hw_intf_init(enum sde_intf idx, */ c->idx = idx; c->cap = cfg; + c->mdss = m; _setup_intf_ops(&c->ops, c->cap->features); /* diff --git a/drivers/gpu/drm/msm/sde/sde_hw_intf.h b/drivers/gpu/drm/msm/sde/sde_hw_intf.h index 2dc8c52209f0..2de57868901a 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_intf.h +++ b/drivers/gpu/drm/msm/sde/sde_hw_intf.h @@ -85,6 +85,7 @@ struct sde_hw_intf { /* intf */ enum sde_intf idx; const struct sde_intf_cfg *cap; + const struct sde_mdss_cfg *mdss; /* ops */ struct sde_hw_intf_ops ops; diff --git a/drivers/gpu/drm/msm/sde/sde_hw_lm.c b/drivers/gpu/drm/msm/sde/sde_hw_lm.c index 03704ddf4980..56ebe8fa05b5 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_lm.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_lm.c @@ -76,7 +76,7 @@ static void sde_hw_lm_setup_out(struct sde_hw_mixer *ctx, SDE_REG_WRITE(c, LM_OUT_SIZE, outsize); /* SPLIT_LEFT_RIGHT */ - opmode = (opmode & ~(1 << 31)) | (mixer->right_mixer & 1 << 31); + opmode = (opmode & ~(1 << 31)) | ((mixer->right_mixer) ? (1 << 31) : 0); SDE_REG_WRITE(c, LM_OP_MODE, opmode); } @@ -128,7 +128,7 @@ static void sde_hw_lm_setup_blendcfg(struct sde_hw_mixer *ctx, fg->const_alpha); SDE_REG_WRITE(c, LM_BLEND0_BG_ALPHA + stage_off, bg->const_alpha); - SDE_REG_WRITE(c, LM_OP_MODE, blend_op); + SDE_REG_WRITE(c, LM_BLEND0_OP + stage_off, blend_op); } static void sde_hw_lm_setup_color3(struct sde_hw_mixer *ctx, diff --git a/drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.h b/drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.h index d46064c57ba4..e914abd69906 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.h +++ b/drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.h @@ -14,6 +14,7 @@ #define _SDE_HW_MDP_CTL_H #include "sde_hw_mdss.h" +#include "sde_hw_mdp_util.h" #include "sde_hw_catalog.h" struct sde_hw_ctl; diff --git a/drivers/gpu/drm/msm/sde/sde_hw_mdp_top.c b/drivers/gpu/drm/msm/sde/sde_hw_mdp_top.c new file mode 100644 index 000000000000..92c08fff2031 --- /dev/null +++ b/drivers/gpu/drm/msm/sde/sde_hw_mdp_top.c @@ -0,0 +1,110 @@ +/* Copyright (c) 2015-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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "sde_hwio.h" +#include "sde_hw_catalog.h" +#include "sde_hw_mdp_top.h" + +#define SPLIT_DISPLAY_ENABLE 0x2F4 +#define LOWER_PIPE_CTRL 0x2F8 +#define UPPER_PIPE_CTRL 0x3F0 +#define TE_LINE_INTERVAL 0x3F4 + +static void sde_hw_setup_split_pipe_control(struct sde_hw_mdp *mdp, + struct split_pipe_cfg *cfg) +{ + struct sde_hw_blk_reg_map *c = &mdp->hw; + u32 upper_pipe; + u32 lower_pipe; + + if (cfg->en) { + upper_pipe = BIT(8); + lower_pipe = BIT(8); + + if (cfg->mode == INTF_MODE_CMD) { + upper_pipe |= BIT(0); + lower_pipe |= BIT(0); + } + + SDE_REG_WRITE(c, LOWER_PIPE_CTRL, lower_pipe); + SDE_REG_WRITE(c, UPPER_PIPE_CTRL, upper_pipe); + } + + SDE_REG_WRITE(c, SPLIT_DISPLAY_ENABLE, cfg->en & 0x1); +} + +static void _setup_mdp_ops(struct sde_hw_mdp_ops *ops, + unsigned long cap) +{ + ops->setup_split_pipe = sde_hw_setup_split_pipe_control; +} + +static const struct sde_mdp_cfg *_top_offset(enum sde_mdp mdp, + const struct sde_mdss_cfg *m, + void __iomem *addr, + struct sde_hw_blk_reg_map *b) +{ + int i; + + for (i = 0; i < m->mdp_count; i++) { + if (mdp == m->mdp[i].id) { + b->base_off = addr; + b->blk_off = m->mdp[i].base; + b->hwversion = m->hwversion; + return &m->mdp[i]; + } + } + + return ERR_PTR(-EINVAL); +} + +struct sde_hw_mdp *sde_hw_mdptop_init(enum sde_mdp idx, + void __iomem *addr, + const struct sde_mdss_cfg *m) +{ + static struct sde_hw_mdp *c; + const struct sde_mdp_cfg *cfg; + + /* mdp top is singleton */ + if (c) { + pr_err(" %s returning %pK", __func__, c); + return c; + } + + c = kzalloc(sizeof(*c), GFP_KERNEL); + pr_err(" %s returning %pK", __func__, c); + if (!c) + return ERR_PTR(-ENOMEM); + + cfg = _top_offset(idx, m, addr, &c->hw); + if (IS_ERR_OR_NULL(cfg)) { + kfree(c); + return ERR_PTR(-EINVAL); + } + + /* + * Assign ops + */ + c->idx = idx; + c->cap = cfg; + _setup_mdp_ops(&c->ops, c->cap->features); + + /* + * Perform any default initialization for the intf + */ + return c; +} + +void sde_hw_mdp_destroy(struct sde_hw_mdp *mdp) +{ +} + diff --git a/drivers/gpu/drm/msm/sde/sde_hw_mdp_top.h b/drivers/gpu/drm/msm/sde/sde_hw_mdp_top.h new file mode 100644 index 000000000000..216a27e93d46 --- /dev/null +++ b/drivers/gpu/drm/msm/sde/sde_hw_mdp_top.h @@ -0,0 +1,66 @@ +/* Copyright (c) 2015-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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SDE_HW_MDP_TOP_H +#define _SDE_HW_MDP_TOP_H + +#include "sde_hw_catalog.h" +#include "sde_hw_mdss.h" +#include "sde_hw_mdp_util.h" + +struct sde_hw_mdp; + +/** + * struct split_pipe_cfg - pipe configuration for dual display panels + * @en : Enable/disable dual pipe confguration + * @mode : Panel interface mode + */ +struct split_pipe_cfg { + bool en; + enum sde_intf_mode mode; +}; + +/** + * struct sde_hw_mdp_ops - interface to the MDP TOP Hw driver functions + * Assumption is these functions will be called after clocks are enabled. + * @setup_split_pipe : Programs the pipe control registers + */ +struct sde_hw_mdp_ops { + void (*setup_split_pipe)(struct sde_hw_mdp *mdp, + struct split_pipe_cfg *p); +}; + +struct sde_hw_mdp { + /* base */ + struct sde_hw_blk_reg_map hw; + + /* intf */ + enum sde_mdp idx; + const struct sde_mdp_cfg *cap; + + /* ops */ + struct sde_hw_mdp_ops ops; +}; + +/** + * sde_hw_intf_init - initializes the intf driver for the passed interface idx + * @idx: Interface index for which driver object is required + * @addr: Mapped register io address of MDP + * @m: Pointer to mdss catalog data + */ +struct sde_hw_mdp *sde_hw_mdptop_init(enum sde_mdp idx, + void __iomem *addr, + const struct sde_mdss_cfg *m); + +void sde_hw_mdp_destroy(struct sde_hw_mdp *mdp); + +#endif /*_SDE_HW_MDP_TOP_H */ diff --git a/drivers/gpu/drm/msm/sde/sde_hw_sspp.c b/drivers/gpu/drm/msm/sde/sde_hw_sspp.c index 9a3d25423b8a..8180078ac950 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_sspp.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_sspp.c @@ -414,7 +414,7 @@ static void sde_hw_sspp_setup_sourceaddress(struct sde_hw_pipe *ctx, return; for (i = 0; i < cfg->src.num_planes; i++) - SDE_REG_WRITE(c, SSPP_SRC0_ADDR + idx + i*0x4, + SDE_REG_WRITE(c, SSPP_SRC0_ADDR + idx + i*0x4, cfg->addr.plane[i]); } diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c index 251003e5382c..7fba38b9e60d 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.c +++ b/drivers/gpu/drm/msm/sde/sde_kms.c @@ -21,18 +21,21 @@ static const char * const iommu_ports[] = { "mdp_0", }; +static const struct sde_hw_res_map res_table[INTF_MAX] = { + { SDE_NONE, SDE_NONE, SDE_NONE, SDE_NONE}, + { INTF_0, SDE_NONE, SDE_NONE, SDE_NONE}, + { INTF_1, LM_0, PINGPONG_0, CTL_0}, + { INTF_2, LM_1, PINGPONG_1, CTL_1}, + { INTF_3, SDE_NONE, SDE_NONE, CTL_2}, +}; + + #define DEFAULT_MDP_SRC_CLK 200000000 int sde_disable(struct sde_kms *sde_kms) { DBG(""); - clk_disable_unprepare(sde_kms->ahb_clk); - clk_disable_unprepare(sde_kms->axi_clk); - clk_disable_unprepare(sde_kms->core_clk); - if (sde_kms->lut_clk) - clk_disable_unprepare(sde_kms->lut_clk); - return 0; } @@ -64,8 +67,9 @@ static void sde_complete_commit(struct msm_kms *kms, } static void sde_wait_for_crtc_commit_done(struct msm_kms *kms, - struct drm_crtc *crtc) + struct drm_crtc *crtc) { + sde_crtc_wait_for_commit_done(crtc); } static int modeset_init(struct sde_kms *sde_kms) { @@ -455,6 +459,7 @@ struct msm_kms *sde_kms_init(struct drm_device *dev) clk_set_rate(sde_kms->src_clk, DEFAULT_MDP_SRC_CLK); sde_enable(sde_kms); + sde_kms->hw_res.res_table = res_table; /* * Now we need to read the HW catalog and initialize resources such as @@ -479,9 +484,7 @@ struct msm_kms *sde_kms_init(struct drm_device *dev) dev->mode_config.max_width = catalog->mixer[0].sblk->maxwidth; dev->mode_config.max_height = 4096; - sde_enable(sde_kms); - sde_kms->hw_intr = sde_hw_intr_init(sde_kms->mmio, sde_kms->catalog); - sde_disable(sde_kms); + sde_kms->hw_intr = sde_rm_acquire_intr(sde_kms); if (IS_ERR_OR_NULL(sde_kms->hw_intr)) goto fail; diff --git a/drivers/gpu/drm/msm/sde/sde_kms.h b/drivers/gpu/drm/msm/sde/sde_kms.h index e56fa16423e5..7ac1b6b827bc 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.h +++ b/drivers/gpu/drm/msm/sde/sde_kms.h @@ -17,7 +17,8 @@ #include "msm_kms.h" #include "mdp/mdp_kms.h" #include "sde_hw_catalog.h" -#include "sde_hw_mdss.h" +#include "sde_hw_mdp_ctl.h" +#include "sde_hw_lm.h" #include "sde_hw_interrupts.h" /* @@ -42,6 +43,38 @@ struct sde_irq { spinlock_t cb_lock; }; +/** + * struct sde_hw_res_map : Default resource table identifying default + * hw resource map. Primarily used for forcing DSI to use CTL_0/1 + * and Pingpong 0/1, if the field is set to SDE_NONE means any HW + * intstance for that tpye is allowed as long as it is unused. + */ +struct sde_hw_res_map { + enum sde_intf intf; + enum sde_lm lm; + enum sde_pingpong pp; + enum sde_ctl ctl; +}; + +/* struct sde_hw_resource_manager : Resource mananger maintains the current + * platform configuration and manages shared + * hw resources ex:ctl_path hw driver context + * is needed by CRTCs/PLANEs/ENCODERs + * @ctl : table of control path hw driver contexts allocated + * @mixer : list of mixer hw drivers contexts allocated + * @intr : pointer to hw interrupt context + * @res_table : pointer to default hw_res table for this platform + * @feature_map :BIT map for default enabled features ex:specifies if PP_SPLIT + * is enabled/disabled by defalt for this platform + */ +struct sde_hw_resource_manager { + struct sde_hw_ctl *ctl[CTL_MAX]; + struct sde_hw_mixer *mixer[LM_MAX]; + struct sde_hw_intr *intr; + const struct sde_hw_res_map *res_table; + bool feature_map; +}; + struct sde_kms { struct msm_kms base; struct drm_device *dev; @@ -74,6 +107,7 @@ struct sde_kms { struct sde_hw_intr *hw_intr; struct sde_irq irq_obj; + struct sde_hw_resource_manager hw_res; }; struct vsync_info { @@ -109,6 +143,36 @@ int sde_disable(struct sde_kms *sde_kms); int sde_enable(struct sde_kms *sde_kms); /** + * HW resource manager functions + * @sde_rm_acquire_ctl_path : Allocates control path + * @sde_rm_get_ctl_path : returns control path driver context for already + * acquired ctl path + * @sde_rm_release_ctl_path : Frees control path driver context + * @sde_rm_acquire_mixer : Allocates mixer hw driver context + * @sde_rm_get_mixer : returns mixer context for already + * acquired mixer + * @sde_rm_release_mixer : Frees mixer hw driver context + * @sde_rm_get_hw_res_map : Returns map for the passed INTF + */ +struct sde_hw_ctl *sde_rm_acquire_ctl_path(struct sde_kms *sde_kms, + enum sde_ctl idx); +struct sde_hw_ctl *sde_rm_get_ctl_path(struct sde_kms *sde_kms, + enum sde_ctl idx); +void sde_rm_release_ctl_path(struct sde_kms *sde_kms, + enum sde_ctl idx); +struct sde_hw_mixer *sde_rm_acquire_mixer(struct sde_kms *sde_kms, + enum sde_lm idx); +struct sde_hw_mixer *sde_rm_get_mixer(struct sde_kms *sde_kms, + enum sde_lm idx); +void sde_rm_release_mixer(struct sde_kms *sde_kms, + enum sde_lm idx); +struct sde_hw_intr *sde_rm_acquire_intr(struct sde_kms *sde_kms); +struct sde_hw_intr *sde_rm_get_intr(struct sde_kms *sde_kms); + +const struct sde_hw_res_map *sde_rm_get_res_map(struct sde_kms *sde_kms, + enum sde_intf idx); + +/** * IRQ functions */ int sde_irq_domain_init(struct sde_kms *sde_kms); @@ -200,31 +264,41 @@ void sde_disable_all_irqs(struct sde_kms *sde_kms); int sde_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); void sde_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); +/** + * Plane functions + */ enum sde_sspp sde_plane_pipe(struct drm_plane *plane); struct drm_plane *sde_plane_init(struct drm_device *dev, uint32_t pipe, bool private_plane); +/** + * CRTC functions + */ uint32_t sde_crtc_vblank(struct drm_crtc *crtc); - +void sde_crtc_wait_for_commit_done(struct drm_crtc *crtc); void sde_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file); -void sde_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane); -void sde_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane); struct drm_crtc *sde_crtc_init(struct drm_device *dev, struct drm_encoder *encoder, struct drm_plane *plane, int id); +/** + * Encoder functions and data types + */ struct sde_encoder_hw_resources { - bool intfs[INTF_MAX]; + enum sde_intf_mode intfs[INTF_MAX]; bool pingpongs[PINGPONG_MAX]; + bool ctls[CTL_MAX]; + bool pingpongsplit; }; + void sde_encoder_get_hw_resources(struct drm_encoder *encoder, struct sde_encoder_hw_resources *hw_res); void sde_encoder_register_vblank_callback(struct drm_encoder *drm_enc, void (*cb)(void *), void *data); void sde_encoders_init(struct drm_device *dev); +void sde_encoder_get_vsync_info(struct drm_encoder *encoder, + struct vsync_info *vsync); -int sde_irq_domain_init(struct sde_kms *sde_kms); -int sde_irq_domain_fini(struct sde_kms *sde_kms); #endif /* __sde_kms_H__ */ diff --git a/drivers/gpu/drm/msm/sde/sde_kms_utils.c b/drivers/gpu/drm/msm/sde/sde_kms_utils.c new file mode 100644 index 000000000000..9d6f28cfc06c --- /dev/null +++ b/drivers/gpu/drm/msm/sde/sde_kms_utils.c @@ -0,0 +1,173 @@ +/* Copyright (c) 2015-2016, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "sde_kms.h" +#include "sde_hw_lm.h" +#include "sde_hw_mdp_ctl.h" + +struct sde_hw_intr *sde_rm_acquire_intr(struct sde_kms *sde_kms) +{ + struct sde_hw_intr *hw_intr; + + if (!sde_kms) { + DRM_ERROR("Invalid KMS Driver"); + return ERR_PTR(-EINVAL); + } + + if (sde_kms->hw_res.intr) { + DRM_ERROR("intr already in use "); + return ERR_PTR(-ENODEV); + } + + sde_enable(sde_kms); + hw_intr = sde_hw_intr_init(sde_kms->mmio, + sde_kms->catalog); + sde_disable(sde_kms); + + if (!IS_ERR_OR_NULL(hw_intr)) + sde_kms->hw_res.intr = hw_intr; + + return hw_intr; +} + +struct sde_hw_intr *sde_rm_get_intr(struct sde_kms *sde_kms) +{ + if (!sde_kms) { + DRM_ERROR("Invalid KMS Driver"); + return ERR_PTR(-EINVAL); + } + + return sde_kms->hw_res.intr; +} + +struct sde_hw_ctl *sde_rm_acquire_ctl_path(struct sde_kms *sde_kms, + enum sde_ctl idx) +{ + struct sde_hw_ctl *hw_ctl; + + if (!sde_kms) { + DRM_ERROR("Invalid KMS driver"); + return ERR_PTR(-EINVAL); + } + + if ((idx == SDE_NONE) || (idx > sde_kms->catalog->ctl_count)) { + DRM_ERROR("Invalid Ctl Path Idx %d", idx); + return ERR_PTR(-EINVAL); + } + + if (sde_kms->hw_res.ctl[idx]) { + DRM_ERROR("CTL path %d already in use ", idx); + return ERR_PTR(-ENODEV); + } + + sde_enable(sde_kms); + hw_ctl = sde_hw_ctl_init(idx, sde_kms->mmio, sde_kms->catalog); + sde_disable(sde_kms); + + if (!IS_ERR_OR_NULL(hw_ctl)) + sde_kms->hw_res.ctl[idx] = hw_ctl; + + return hw_ctl; +} + +struct sde_hw_ctl *sde_rm_get_ctl_path(struct sde_kms *sde_kms, + enum sde_ctl idx) +{ + if (!sde_kms) { + DRM_ERROR("Invalid KMS Driver"); + return ERR_PTR(-EINVAL); + } + if ((idx == SDE_NONE) || (idx > sde_kms->catalog->ctl_count)) { + DRM_ERROR("Invalid Ctl path Idx %d", idx); + return ERR_PTR(-EINVAL); + } + + return sde_kms->hw_res.ctl[idx]; +} + +void sde_rm_release_ctl_path(struct sde_kms *sde_kms, enum sde_ctl idx) +{ + if (!sde_kms) { + DRM_ERROR("Invalid pointer\n"); + return; + } + if ((idx == SDE_NONE) || (idx > sde_kms->catalog->ctl_count)) { + DRM_ERROR("Invalid Ctl path Idx %d", idx); + return; + } +} + +struct sde_hw_mixer *sde_rm_acquire_mixer(struct sde_kms *sde_kms, + enum sde_lm idx) +{ + struct sde_hw_mixer *mixer; + + if (!sde_kms) { + DRM_ERROR("Invalid KMS Driver"); + return ERR_PTR(-EINVAL); + } + + if ((idx == SDE_NONE) || (idx > sde_kms->catalog->mixer_count)) { + DBG("Invalid mixer id %d", idx); + return ERR_PTR(-EINVAL); + } + + if (sde_kms->hw_res.mixer[idx]) { + DRM_ERROR("mixer %d already in use ", idx); + return ERR_PTR(-ENODEV); + } + + sde_enable(sde_kms); + mixer = sde_hw_lm_init(idx, sde_kms->mmio, sde_kms->catalog); + sde_disable(sde_kms); + + if (!IS_ERR_OR_NULL(mixer)) + sde_kms->hw_res.mixer[idx] = mixer; + + return mixer; +} + +struct sde_hw_mixer *sde_rm_get_mixer(struct sde_kms *sde_kms, + enum sde_lm idx) +{ + if (!sde_kms) { + DRM_ERROR("Invalid KMS Driver"); + return ERR_PTR(-EINVAL); + } + + if ((idx == SDE_NONE) || (idx > sde_kms->catalog->mixer_count)) { + DRM_ERROR("Invalid mixer id %d", idx); + return ERR_PTR(-EINVAL); + } + + return sde_kms->hw_res.mixer[idx]; +} + +const struct sde_hw_res_map *sde_rm_get_res_map(struct sde_kms *sde_kms, + enum sde_intf idx) +{ + if (!sde_kms) { + DRM_ERROR("Invalid KMS Driver"); + return ERR_PTR(-EINVAL); + } + if ((idx == SDE_NONE) || (idx > sde_kms->catalog->intf_count)) { + DRM_ERROR("Invalid intf id %d", idx); + return ERR_PTR(-EINVAL); + } + + DBG(" Platform Resource map for INTF %d -> lm %d, pp %d ctl %d", + sde_kms->hw_res.res_table[idx].intf, + sde_kms->hw_res.res_table[idx].lm, + sde_kms->hw_res.res_table[idx].pp, + sde_kms->hw_res.res_table[idx].ctl); + return &(sde_kms->hw_res.res_table[idx]); +} diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 582261d5aa17..70766e208217 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1723,6 +1723,17 @@ static int arm_smmu_restore_sec_cfg(struct arm_smmu_device *smmu) return 0; } +static bool is_iommu_pt_coherent(struct arm_smmu_domain *smmu_domain) +{ + if (smmu_domain->attributes & + (1 << DOMAIN_ATTR_PAGE_TABLE_FORCE_COHERENT)) + return true; + else if (smmu_domain->smmu && smmu_domain->smmu->dev) + return smmu_domain->smmu->dev->archdata.dma_coherent; + else + return false; +} + static int arm_smmu_init_domain_context(struct iommu_domain *domain, struct arm_smmu_device *smmu, struct arm_smmu_master_cfg *master_cfg) @@ -1734,6 +1745,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); struct arm_smmu_cfg *cfg = &smmu_domain->cfg; bool is_fast = smmu_domain->attributes & (1 << DOMAIN_ATTR_FAST); + unsigned long quirks = 0; if (smmu_domain->smmu) goto out; @@ -1810,8 +1822,12 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, smmu_domain->smmu = smmu; + if (is_iommu_pt_coherent(smmu_domain)) + quirks |= IO_PGTABLE_QUIRK_PAGE_TABLE_COHERENT; + if (arm_smmu_is_slave_side_secure(smmu_domain)) { smmu_domain->pgtbl_cfg = (struct io_pgtable_cfg) { + .quirks = quirks, .pgsize_bitmap = arm_smmu_ops.pgsize_bitmap, .arm_msm_secure_cfg = { .sec_id = smmu->sec_id, @@ -1822,6 +1838,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, fmt = ARM_MSM_SECURE; } else { smmu_domain->pgtbl_cfg = (struct io_pgtable_cfg) { + .quirks = quirks, .pgsize_bitmap = arm_smmu_ops.pgsize_bitmap, .ias = ias, .oas = oas, @@ -3112,6 +3129,17 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, & (1 << DOMAIN_ATTR_EARLY_MAP)); ret = 0; break; + case DOMAIN_ATTR_PAGE_TABLE_IS_COHERENT: + if (!smmu_domain->smmu) + return -ENODEV; + *((int *)data) = is_iommu_pt_coherent(smmu_domain); + ret = 0; + break; + case DOMAIN_ATTR_PAGE_TABLE_FORCE_COHERENT: + *((int *)data) = !!(smmu_domain->attributes + & (1 << DOMAIN_ATTR_PAGE_TABLE_FORCE_COHERENT)); + ret = 0; + break; default: ret = -ENODEV; break; @@ -3235,6 +3263,26 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain, } break; } + case DOMAIN_ATTR_PAGE_TABLE_FORCE_COHERENT: { + int force_coherent = *((int *)data); + + if (smmu_domain->smmu != NULL) { + dev_err(smmu_domain->smmu->dev, + "cannot change force coherent attribute while attached\n"); + ret = -EBUSY; + break; + } + + if (force_coherent) + smmu_domain->attributes |= + 1 << DOMAIN_ATTR_PAGE_TABLE_FORCE_COHERENT; + else + smmu_domain->attributes &= + ~(1 << DOMAIN_ATTR_PAGE_TABLE_FORCE_COHERENT); + + ret = 0; + break; + } default: ret = -ENODEV; break; diff --git a/drivers/iommu/dma-mapping-fast.c b/drivers/iommu/dma-mapping-fast.c index 411f52c5ae81..004f34ecbff8 100644 --- a/drivers/iommu/dma-mapping-fast.c +++ b/drivers/iommu/dma-mapping-fast.c @@ -25,6 +25,36 @@ #define FAST_PAGE_MASK (~(PAGE_SIZE - 1)) #define FAST_PTE_ADDR_MASK ((av8l_fast_iopte)0xfffffffff000) +static pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot, + bool coherent) +{ + if (dma_get_attr(DMA_ATTR_STRONGLY_ORDERED, attrs)) + return pgprot_noncached(prot); + else if (!coherent || dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs)) + return pgprot_writecombine(prot); + return prot; +} + +static int __get_iommu_pgprot(struct dma_attrs *attrs, int prot, + bool coherent) +{ + if (!dma_get_attr(DMA_ATTR_EXEC_MAPPING, attrs)) + prot |= IOMMU_NOEXEC; + if (dma_get_attr(DMA_ATTR_STRONGLY_ORDERED, attrs)) + prot |= IOMMU_DEVICE; + if (coherent) + prot |= IOMMU_CACHE; + + return prot; +} + +static void fast_dmac_clean_range(struct dma_fast_smmu_mapping *mapping, + void *start, void *end) +{ + if (!mapping->is_smmu_pt_coherent) + dmac_clean_range(start, end); +} + /* * Checks if the allocated range (ending at @end) covered the upcoming * stale bit. We don't need to know exactly where the range starts since @@ -282,11 +312,11 @@ static dma_addr_t fast_smmu_map_page(struct device *dev, struct page *page, int nptes = len >> FAST_PAGE_SHIFT; bool skip_sync = dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs); int prot = __fast_dma_direction_to_prot(dir); + bool is_coherent = is_device_dma_coherent(dev); - if (dma_get_attr(DMA_ATTR_STRONGLY_ORDERED, attrs)) - prot |= IOMMU_DEVICE; + prot = __get_iommu_pgprot(attrs, prot, is_coherent); - if (!skip_sync) + if (!skip_sync && !is_coherent) __fast_dma_page_cpu_to_dev(phys_to_page(phys_to_map), offset_from_phys_to_map, size, dir); @@ -302,8 +332,7 @@ static dma_addr_t fast_smmu_map_page(struct device *dev, struct page *page, if (unlikely(av8l_fast_map_public(pmd, phys_to_map, len, prot))) goto fail_free_iova; - if (!skip_sync) /* TODO: should ask SMMU if coherent */ - dmac_clean_range(pmd, pmd + nptes); + fast_dmac_clean_range(mapping, pmd, pmd + nptes); spin_unlock_irqrestore(&mapping->lock, flags); return iova + offset_from_phys_to_map; @@ -327,14 +356,14 @@ static void fast_smmu_unmap_page(struct device *dev, dma_addr_t iova, int nptes = len >> FAST_PAGE_SHIFT; struct page *page = phys_to_page((*pmd & FAST_PTE_ADDR_MASK)); bool skip_sync = dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs); + bool is_coherent = is_device_dma_coherent(dev); - if (!skip_sync) + if (!skip_sync && !is_coherent) __fast_dma_page_dev_to_cpu(page, offset, size, dir); spin_lock_irqsave(&mapping->lock, flags); av8l_fast_unmap_public(pmd, len); - if (!skip_sync) /* TODO: should ask SMMU if coherent */ - dmac_clean_range(pmd, pmd + nptes); + fast_dmac_clean_range(mapping, pmd, pmd + nptes); __fast_smmu_free_iova(mapping, iova, len); spin_unlock_irqrestore(&mapping->lock, flags); } @@ -437,9 +466,12 @@ static void *fast_smmu_alloc(struct device *dev, size_t size, struct sg_mapping_iter miter; unsigned int count = ALIGN(size, SZ_4K) >> PAGE_SHIFT; int prot = IOMMU_READ | IOMMU_WRITE; /* TODO: extract from attrs */ - pgprot_t remap_prot = pgprot_writecombine(PAGE_KERNEL); + bool is_coherent = is_device_dma_coherent(dev); + pgprot_t remap_prot = __get_dma_pgprot(attrs, PAGE_KERNEL, is_coherent); struct page **pages; + prot = __get_iommu_pgprot(attrs, prot, is_coherent); + *handle = DMA_ERROR_CODE; pages = __fast_smmu_alloc_pages(count, gfp); @@ -454,7 +486,7 @@ static void *fast_smmu_alloc(struct device *dev, size_t size, goto out_free_pages; } - if (!(prot & IOMMU_CACHE)) { + if (!is_coherent) { /* * The CPU-centric flushing implied by SG_MITER_TO_SG isn't * sufficient here, so skip it by using the "wrong" direction. @@ -488,7 +520,7 @@ static void *fast_smmu_alloc(struct device *dev, size_t size, /* TODO: unwind previously successful mappings */ goto out_free_iova; } - dmac_clean_range(ptep, ptep + nptes); + fast_dmac_clean_range(mapping, ptep, ptep + nptes); iova_iter += miter.length; } sg_miter_stop(&miter); @@ -510,7 +542,7 @@ out_unmap: spin_lock_irqsave(&mapping->lock, flags); ptep = iopte_pmd_offset(mapping->pgtbl_pmds, dma_addr); av8l_fast_unmap_public(ptep, size); - dmac_clean_range(ptep, ptep + count); + fast_dmac_clean_range(mapping, ptep, ptep + count); out_free_iova: __fast_smmu_free_iova(mapping, dma_addr, size); spin_unlock_irqrestore(&mapping->lock, flags); @@ -543,7 +575,7 @@ static void fast_smmu_free(struct device *dev, size_t size, ptep = iopte_pmd_offset(mapping->pgtbl_pmds, dma_handle); spin_lock_irqsave(&mapping->lock, flags); av8l_fast_unmap_public(ptep, size); - dmac_clean_range(ptep, ptep + count); + fast_dmac_clean_range(mapping, ptep, ptep + count); __fast_smmu_free_iova(mapping, dma_handle, size); spin_unlock_irqrestore(&mapping->lock, flags); __fast_smmu_free_pages(pages, count); @@ -557,9 +589,10 @@ static int fast_smmu_mmap_attrs(struct device *dev, struct vm_area_struct *vma, unsigned long uaddr = vma->vm_start; struct page **pages; int i, nr_pages, ret = 0; + bool coherent = is_device_dma_coherent(dev); - vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); - + vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot, + coherent); area = find_vm_area(cpu_addr); if (!area) return -EINVAL; @@ -718,6 +751,10 @@ int fast_smmu_attach_device(struct device *dev, } mapping->fast->pgtbl_pmds = info.pmds; + if (iommu_domain_get_attr(domain, DOMAIN_ATTR_PAGE_TABLE_IS_COHERENT, + &mapping->fast->is_smmu_pt_coherent)) + return -EINVAL; + mapping->fast->notifier.notifier_call = fast_smmu_notify; av8l_register_notify(&mapping->fast->notifier); diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index 3f9825a9addb..0d057ca92972 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -290,6 +290,16 @@ static dma_addr_t __arm_lpae_dma_addr(void *pages) return (dma_addr_t)virt_to_phys(pages); } +static inline void pgtable_dma_sync_single_for_device( + struct io_pgtable_cfg *cfg, + dma_addr_t addr, size_t size, + enum dma_data_direction dir) +{ + if (!(cfg->quirks & IO_PGTABLE_QUIRK_PAGE_TABLE_COHERENT)) + dma_sync_single_for_device(cfg->iommu_dev, addr, size, + dir); +} + static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp, struct io_pgtable_cfg *cfg, void *cookie) @@ -340,7 +350,7 @@ static void __arm_lpae_set_pte(arm_lpae_iopte *ptep, arm_lpae_iopte pte, *ptep = pte; if (!selftest_running) - dma_sync_single_for_device(cfg->iommu_dev, + pgtable_dma_sync_single_for_device(cfg, __arm_lpae_dma_addr(ptep), sizeof(pte), DMA_TO_DEVICE); } @@ -415,7 +425,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova, if (lvl == MAP_STATE_LVL) { if (ms->pgtable) - dma_sync_single_for_device(cfg->iommu_dev, + pgtable_dma_sync_single_for_device(cfg, __arm_lpae_dma_addr(ms->pte_start), ms->num_pte * sizeof(*ptep), DMA_TO_DEVICE); @@ -433,7 +443,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova, * mapping. Flush out the previous page mappings. */ if (ms->pgtable) - dma_sync_single_for_device(cfg->iommu_dev, + pgtable_dma_sync_single_for_device(cfg, __arm_lpae_dma_addr(ms->pte_start), ms->num_pte * sizeof(*ptep), DMA_TO_DEVICE); @@ -603,7 +613,7 @@ static int arm_lpae_map_sg(struct io_pgtable_ops *ops, unsigned long iova, } if (ms.pgtable) - dma_sync_single_for_device(cfg->iommu_dev, + pgtable_dma_sync_single_for_device(cfg, __arm_lpae_dma_addr(ms.pte_start), ms.num_pte * sizeof(*ms.pte_start), DMA_TO_DEVICE); @@ -753,7 +763,7 @@ static int __arm_lpae_unmap(struct arm_lpae_io_pgtable *data, table += tl_offset; memset(table, 0, table_len); - dma_sync_single_for_device(cfg->iommu_dev, + pgtable_dma_sync_single_for_device(cfg, __arm_lpae_dma_addr(table), table_len, DMA_TO_DEVICE); @@ -994,7 +1004,7 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie) return NULL; /* TCR */ - if (cfg->iommu_dev && cfg->iommu_dev->archdata.dma_coherent) + if (cfg->quirks & IO_PGTABLE_QUIRK_PAGE_TABLE_COHERENT) reg = (ARM_LPAE_TCR_SH_OS << ARM_LPAE_TCR_SH0_SHIFT) | (ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_IRGN0_SHIFT) | (ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_ORGN0_SHIFT); diff --git a/drivers/iommu/io-pgtable-fast.c b/drivers/iommu/io-pgtable-fast.c index 9a25ebfdc778..a71fcdbb1899 100644 --- a/drivers/iommu/io-pgtable-fast.c +++ b/drivers/iommu/io-pgtable-fast.c @@ -196,7 +196,7 @@ int av8l_fast_map_public(av8l_fast_iopte *ptep, phys_addr_t paddr, size_t size, | AV8L_FAST_PTE_TYPE_PAGE | AV8L_FAST_PTE_AF | AV8L_FAST_PTE_nG - | AV8L_FAST_PTE_SH_IS; + | AV8L_FAST_PTE_SH_OS; if (prot & IOMMU_DEVICE) pte |= (AV8L_FAST_MAIR_ATTR_IDX_DEV @@ -428,9 +428,14 @@ av8l_fast_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie) cfg->pgsize_bitmap = SZ_4K; /* TCR */ - reg = (AV8L_FAST_TCR_SH_IS << AV8L_FAST_TCR_SH0_SHIFT) | - (AV8L_FAST_TCR_RGN_NC << AV8L_FAST_TCR_IRGN0_SHIFT) | - (AV8L_FAST_TCR_RGN_NC << AV8L_FAST_TCR_ORGN0_SHIFT); + if (cfg->quirks & IO_PGTABLE_QUIRK_PAGE_TABLE_COHERENT) + reg = (AV8L_FAST_TCR_SH_OS << AV8L_FAST_TCR_SH0_SHIFT) | + (AV8L_FAST_TCR_RGN_WBWA << AV8L_FAST_TCR_IRGN0_SHIFT) | + (AV8L_FAST_TCR_RGN_WBWA << AV8L_FAST_TCR_ORGN0_SHIFT); + else + reg = (AV8L_FAST_TCR_SH_OS << AV8L_FAST_TCR_SH0_SHIFT) | + (AV8L_FAST_TCR_RGN_NC << AV8L_FAST_TCR_IRGN0_SHIFT) | + (AV8L_FAST_TCR_RGN_NC << AV8L_FAST_TCR_ORGN0_SHIFT); reg |= AV8L_FAST_TCR_TG0_4K; @@ -567,6 +572,7 @@ static int __init av8l_fast_positive_testing(void) av8l_fast_iopte *pmds; cfg = (struct io_pgtable_cfg) { + .quirks = 0, .tlb = &dummy_tlb_ops, .ias = 32, .oas = 32, diff --git a/drivers/iommu/io-pgtable.h b/drivers/iommu/io-pgtable.h index 32ae3c59fe7c..a3f366f559a7 100644 --- a/drivers/iommu/io-pgtable.h +++ b/drivers/iommu/io-pgtable.h @@ -56,7 +56,12 @@ struct iommu_gather_ops { * page table walker. */ struct io_pgtable_cfg { + /* + * IO_PGTABLE_QUIRK_PAGE_TABLE_COHERENT: Set the page table as + * coherent. + */ #define IO_PGTABLE_QUIRK_ARM_NS (1 << 0) /* Set NS bit in PTEs */ + #define IO_PGTABLE_QUIRK_PAGE_TABLE_COHERENT (1 << 1) int quirks; unsigned long pgsize_bitmap; unsigned int ias; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h index 4b881f4fd7b6..39688df93474 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-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 @@ -451,7 +451,7 @@ struct msm_vfe_axi_stream { uint32_t runtime_num_burst_capture; uint32_t runtime_output_format; - enum msm_stream_memory_input_t memory_input; + enum msm_stream_rdi_input_type rdi_input_type; struct msm_isp_sw_framskip sw_skip; uint8_t sw_ping_pong_bit; @@ -820,6 +820,8 @@ struct vfe_device { uint32_t bus_err_ign_mask; uint32_t recovery_irq0_mask; uint32_t recovery_irq1_mask; + /* Store the buf_idx for pd stats RDI stream */ + uint8_t pd_buf_idx; }; struct vfe_parent_device { diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c index 60801ff6be0a..0db901de4562 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-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 @@ -921,6 +921,37 @@ void msm_isp_increment_frame_id(struct vfe_device *vfe_dev, } } +static void msm_isp_update_pd_stats_idx(struct vfe_device *vfe_dev, + enum msm_vfe_input_src frame_src) +{ + struct msm_vfe_axi_stream *pd_stream_info = NULL; + uint32_t pingpong_status = 0, pingpong_bit = 0; + struct msm_isp_buffer *done_buf = NULL; + int vfe_idx = -1; + + if (frame_src < VFE_RAW_0 || frame_src > VFE_RAW_2) + return; + + pd_stream_info = msm_isp_get_stream_common_data(vfe_dev, + RDI_INTF_0 + frame_src - VFE_RAW_0); + + if (pd_stream_info && (pd_stream_info->state == ACTIVE) && + (pd_stream_info->rdi_input_type == + MSM_CAMERA_RDI_PDAF)) { + vfe_idx = msm_isp_get_vfe_idx_for_stream( + vfe_dev, pd_stream_info); + pingpong_status = vfe_dev->hw_info->vfe_ops.axi_ops. + get_pingpong_status(vfe_dev); + pingpong_bit = ((pingpong_status >> + pd_stream_info->wm[vfe_idx][0]) & 0x1); + done_buf = pd_stream_info->buf[pingpong_bit]; + if (done_buf) + vfe_dev->pd_buf_idx = done_buf->buf_idx; + else + vfe_dev->pd_buf_idx = 0xF; + } +} + void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type, enum msm_vfe_input_src frame_src, struct msm_isp_timestamp *ts) { @@ -955,9 +986,8 @@ void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type, vfe_dev->isp_raw2_debug++; } - ISP_DBG("%s: vfe %d frame_src %d frame id: %u\n", __func__, - vfe_dev->pdev->id, frame_src, - vfe_dev->axi_data.src_info[frame_src].frame_id); + ISP_DBG("%s: vfe %d frame_src %d\n", __func__, + vfe_dev->pdev->id, frame_src); /* * Cannot support dual_cam and framedrop same time in union. @@ -1002,6 +1032,12 @@ void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type, if (frame_src == VFE_PIX_0) msm_isp_check_for_output_error(vfe_dev, ts, &event_data.u.sof_info); + /* + * Get and store the buf idx for PD stats + * this is to send the PD stats buffer address + * in BF stats done. + */ + msm_isp_update_pd_stats_idx(vfe_dev, frame_src); break; default: @@ -1174,7 +1210,7 @@ int msm_isp_request_axi_stream(struct vfe_device *vfe_dev, void *arg) return rc; } - stream_info->memory_input = stream_cfg_cmd->memory_input; + stream_info->rdi_input_type = stream_cfg_cmd->rdi_input_type; vfe_dev->reg_update_requested &= ~(BIT(SRC_TO_INTF(stream_info->stream_src))); diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c index 72703c9590ed..f40af6e95272 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-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 @@ -224,6 +224,11 @@ static int32_t msm_isp_stats_buf_divert(struct vfe_device *vfe_dev, stats_event->stats_buf_idxs [stream_info->stats_type] = done_buf->buf_idx; + + stats_event->pd_stats_idx = 0xF; + if (stream_info->stats_type == MSM_ISP_STATS_BF) + stats_event->pd_stats_idx = vfe_dev->pd_buf_idx; + if (comp_stats_type_mask == NULL) { stats_event->stats_mask = 1 << stream_info->stats_type; diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c index 2fc130137c25..920f5a809777 100644 --- a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c +++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-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 @@ -1390,6 +1390,14 @@ static void sde_rotator_commit_handler(struct work_struct *work) entry->item.dst_rect.x, entry->item.dst_rect.y, entry->item.dst_rect.w, entry->item.dst_rect.h); + ATRACE_INT("sde_smmu_ctrl", 0); + ret = sde_smmu_ctrl(1); + if (IS_ERR_VALUE(ret)) { + SDEROT_ERR("IOMMU attach failed\n"); + goto smmu_error; + } + ATRACE_INT("sde_smmu_ctrl", 1); + ret = sde_rotator_map_and_check_data(entry); if (ret) { SDEROT_ERR("fail to prepare input/output data %d\n", ret); @@ -1415,6 +1423,8 @@ static void sde_rotator_commit_handler(struct work_struct *work) sde_rot_mgr_unlock(mgr); return; error: + sde_smmu_ctrl(0); +smmu_error: sde_rotator_put_hw_resource(entry->commitq, entry, hw); get_hw_res_err: sde_rotator_signal_output(entry); @@ -1491,6 +1501,7 @@ static void sde_rotator_done_handler(struct work_struct *work) sde_rot_mgr_lock(mgr); sde_rotator_put_hw_resource(entry->commitq, entry, entry->commitq->hw); sde_rotator_signal_output(entry); + ATRACE_INT("sde_rot_done", 1); sde_rotator_release_entry(mgr, entry); atomic_dec(&request->pending_count); if (request->retireq && request->retire_work) @@ -1498,6 +1509,10 @@ static void sde_rotator_done_handler(struct work_struct *work) if (entry->item.ts) entry->item.ts[SDE_ROTATOR_TS_RETIRE] = ktime_get(); sde_rot_mgr_unlock(mgr); + + ATRACE_INT("sde_smmu_ctrl", 3); + sde_smmu_ctrl(0); + ATRACE_INT("sde_smmu_ctrl", 4); } static bool sde_rotator_verify_format(struct sde_rot_mgr *mgr, diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_wb.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_wb.c index e0f44be222d6..f9dc34167c59 100644 --- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_wb.c +++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_wb.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-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 @@ -317,7 +317,7 @@ static int sde_mdp_wb_wait4comp(struct sde_mdp_ctl *ctl, void *arg) struct sde_mdp_writeback_ctx *ctx; int rc = 0; u64 rot_time = 0; - u32 status, mask, isr; + u32 status, mask, isr = 0; ctx = (struct sde_mdp_writeback_ctx *) ctl->priv_data; if (!ctx) { diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c index f2a9da737453..ddf11b35a1d6 100644 --- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c +++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-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 @@ -36,6 +36,12 @@ #include "sde_rotator_trace.h" #include "sde_rotator_debug.h" +#define RES_UHD (3840*2160) + +/* traffic shaping clock ticks = finish_time x 19.2MHz */ +#define TRAFFIC_SHAPE_CLKTICK_14MS 268800 +#define TRAFFIC_SHAPE_CLKTICK_12MS 230400 + /* XIN mapping */ #define XIN_SSPP 0 #define XIN_WRITEBACK 1 @@ -650,6 +656,20 @@ static void sde_hw_rotator_setup_fetchengine(struct sde_hw_rotator_context *ctx, ctx->is_secure = false; } + /* + * Determine if traffic shaping is required. Only enable traffic + * shaping when content is 4k@30fps. The actual traffic shaping + * bandwidth calculation is done in output setup. + */ + if (((cfg->src_rect->w * cfg->src_rect->h) >= RES_UHD) && + (cfg->fps <= 30)) { + SDEROT_DBG("Enable Traffic Shaper\n"); + ctx->is_traffic_shaping = true; + } else { + SDEROT_DBG("Disable Traffic Shaper\n"); + ctx->is_traffic_shaping = false; + } + /* Update command queue write ptr */ sde_hw_rotator_put_regdma_segment(ctx, wrptr); } @@ -762,6 +782,36 @@ static void sde_hw_rotator_setup_wbengine(struct sde_hw_rotator_context *ctx, else SDE_REGDMA_WRITE(wrptr, ROTTOP_OP_MODE, 0x1); + /* setup traffic shaper for 4k 30fps content */ + if (ctx->is_traffic_shaping) { + u32 bw; + + /* + * Target to finish in 12ms, and we need to set number of bytes + * per clock tick for traffic shaping. + * Each clock tick run @ 19.2MHz, so we need we know total of + * clock ticks in 14ms, i.e. 12ms/(1/19.2MHz) ==> 23040 + * Finally, calcualte the byte count per clock tick based on + * resolution, bpp and compression ratio. + */ + bw = cfg->dst_rect->w * cfg->dst_rect->h; + + if (fmt->chroma_sample == SDE_MDP_CHROMA_420) + bw = (bw * 3) / 2; + else + bw *= fmt->bpp; + + bw /= TRAFFIC_SHAPE_CLKTICK_12MS; + if (bw > 0xFF) + bw = 0xFF; + SDE_REGDMA_WRITE(wrptr, ROT_WB_TRAFFIC_SHAPER_WR_CLIENT, + BIT(31) | bw); + SDEROT_DBG("Enable ROT_WB Traffic Shaper:%d\n", bw); + } else { + SDE_REGDMA_WRITE(wrptr, ROT_WB_TRAFFIC_SHAPER_WR_CLIENT, 0); + SDEROT_DBG("Disable ROT_WB Traffic Shaper\n"); + } + /* Update command queue write ptr */ sde_hw_rotator_put_regdma_segment(ctx, wrptr); } @@ -1039,6 +1089,7 @@ static u32 sde_hw_rotator_wait_done_regdma( !sde_hw_rotator_pending_swts(rot, ctx, &swts), KOFF_TIMEOUT); + ATRACE_INT("sde_rot_done", 0); spin_lock_irqsave(&rot->rotisr_lock, flags); last_isr = ctx->last_regdma_isr_status; @@ -1580,6 +1631,8 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw, sspp_cfg.img_width = item->input.width; sspp_cfg.img_height = item->input.height; + sspp_cfg.fps = entry->perf->config.frame_rate; + sspp_cfg.bw = entry->perf->bw; sspp_cfg.fmt = sde_get_format_params(item->input.format); if (!sspp_cfg.fmt) { SDEROT_ERR("null format\n"); @@ -1599,6 +1652,8 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw, wb_cfg.img_width = item->output.width; wb_cfg.img_height = item->output.height; + wb_cfg.fps = entry->perf->config.frame_rate; + wb_cfg.bw = entry->perf->bw; wb_cfg.fmt = sde_get_format_params(item->output.format); wb_cfg.dst_rect = &item->dst_rect; wb_cfg.data = &entry->dst_buf; @@ -1642,7 +1697,9 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw, MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0; ot_params.bit_off_mdp_clk_ctrl = MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0_XIN0; - ot_params.fmt = entry->perf->config.input.format; + ot_params.fmt = ctx->is_traffic_shaping ? + SDE_PIX_FMT_ABGR_8888 : + entry->perf->config.input.format; sde_mdp_set_ot_limit(&ot_params); } @@ -1660,7 +1717,9 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw, MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0; ot_params.bit_off_mdp_clk_ctrl = MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0_XIN1; - ot_params.fmt = entry->perf->config.input.format; + ot_params.fmt = ctx->is_traffic_shaping ? + SDE_PIX_FMT_ABGR_8888 : + entry->perf->config.input.format; sde_mdp_set_ot_limit(&ot_params); } @@ -1711,7 +1770,6 @@ static int sde_hw_rotator_kickoff(struct sde_rot_hw_resource *hw, struct sde_hw_rotator *rot; struct sde_hw_rotator_resource_info *resinfo; struct sde_hw_rotator_context *ctx; - int ret = 0; if (!hw || !entry) { SDEROT_ERR("null hw resource/entry\n"); @@ -1729,12 +1787,6 @@ static int sde_hw_rotator_kickoff(struct sde_rot_hw_resource *hw, return -EINVAL; } - ret = sde_smmu_ctrl(1); - if (IS_ERR_VALUE(ret)) { - SDEROT_ERR("IOMMU attach failed\n"); - return ret; - } - rot->ops.start_rotator(ctx, ctx->q_id); return 0; @@ -1774,8 +1826,6 @@ static int sde_hw_rotator_wait4done(struct sde_rot_hw_resource *hw, ret = rot->ops.wait_rotator_done(ctx, ctx->q_id, 0); - sde_smmu_ctrl(0); - if (rot->dbgmem) { sde_hw_rotator_unmap_vaddr(&ctx->src_dbgbuf); sde_hw_rotator_unmap_vaddr(&ctx->dst_dbgbuf); diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h index e666f4811c77..5502cc09ae19 100644 --- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h +++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-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 @@ -73,6 +73,8 @@ struct sde_hw_rot_sspp_cfg { struct sde_mdp_data *data; u32 img_width; u32 img_height; + u32 fps; + u64 bw; }; @@ -93,6 +95,8 @@ struct sde_hw_rot_wb_cfg { u32 img_height; u32 v_downscale_factor; u32 h_downscale_factor; + u32 fps; + u64 bw; }; @@ -214,6 +218,7 @@ struct sde_hw_rotator_context { u32 last_regdma_timestamp; dma_addr_t ts_addr; bool is_secure; + bool is_traffic_shaping; }; /** diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index 20949487f859..3d346d85d45a 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -1,6 +1,6 @@ /*Qualcomm Secure Execution Environment Communicator (QSEECOM) driver * - * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-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 @@ -2634,11 +2634,6 @@ int __qseecom_process_rpmb_svc_cmd(struct qseecom_dev_handle *data_ptr, return -EINVAL; } - if ((!req_ptr->cmd_req_buf) || (!req_ptr->resp_buf)) { - pr_err("Invalid req/resp buffer, exiting\n"); - return -EINVAL; - } - /* Clients need to ensure req_buf is at base offset of shared buffer */ if ((uintptr_t)req_ptr->cmd_req_buf != data_ptr->client.user_virt_sb_base) { @@ -2646,15 +2641,11 @@ int __qseecom_process_rpmb_svc_cmd(struct qseecom_dev_handle *data_ptr, return -EINVAL; } - if (((uintptr_t)req_ptr->resp_buf < - data_ptr->client.user_virt_sb_base) || - ((uintptr_t)req_ptr->resp_buf >= - (data_ptr->client.user_virt_sb_base + - data_ptr->client.sb_length))){ - pr_err("response buffer address not within shared bufffer\n"); + if (data_ptr->client.sb_length < + sizeof(struct qseecom_rpmb_provision_key)) { + pr_err("shared buffer is too small to hold key type\n"); return -EINVAL; } - req_buf = data_ptr->client.sb_virt; send_svc_ireq_ptr->qsee_cmd_id = req_ptr->cmd_id; @@ -2681,36 +2672,6 @@ int __qseecom_process_fsm_key_svc_cmd(struct qseecom_dev_handle *data_ptr, return -EINVAL; } - if (((uintptr_t)req_ptr->cmd_req_buf < - data_ptr->client.user_virt_sb_base) || - ((uintptr_t)req_ptr->cmd_req_buf >= - (data_ptr->client.user_virt_sb_base + - data_ptr->client.sb_length))) { - pr_err("cmd buffer address not within shared bufffer\n"); - return -EINVAL; - } - - if (((uintptr_t)req_ptr->resp_buf < - data_ptr->client.user_virt_sb_base) || - ((uintptr_t)req_ptr->resp_buf >= - (data_ptr->client.user_virt_sb_base + - data_ptr->client.sb_length))){ - pr_err("response buffer address not within shared bufffer\n"); - return -EINVAL; - } - - if ((req_ptr->cmd_req_len == 0) || (req_ptr->resp_len == 0) || - req_ptr->cmd_req_len > data_ptr->client.sb_length || - req_ptr->resp_len > data_ptr->client.sb_length) { - pr_err("cmd buffer length or response buffer length not valid\n"); - return -EINVAL; - } - - if (req_ptr->cmd_req_len > UINT_MAX - req_ptr->resp_len) { - pr_err("Integer overflow detected in req_len & rsp_len, exiting now\n"); - return -EINVAL; - } - reqd_len_sb_in = req_ptr->cmd_req_len + req_ptr->resp_len; if (reqd_len_sb_in > data_ptr->client.sb_length) { pr_err("Not enough memory to fit cmd_buf and resp_buf. "); @@ -2732,28 +2693,11 @@ int __qseecom_process_fsm_key_svc_cmd(struct qseecom_dev_handle *data_ptr, return ret; } -static int qseecom_send_service_cmd(struct qseecom_dev_handle *data, - void __user *argp) +static int __validate_send_service_cmd_inputs(struct qseecom_dev_handle *data, + struct qseecom_send_svc_cmd_req *req) { - int ret = 0; - struct qseecom_client_send_service_ireq send_svc_ireq; - struct qseecom_client_send_fsm_key_req send_fsm_key_svc_ireq; - struct qseecom_command_scm_resp resp; - struct qseecom_send_svc_cmd_req req; - void *send_req_ptr; - size_t req_buf_size; - - /*struct qseecom_command_scm_resp resp;*/ - - if (copy_from_user(&req, - (void __user *)argp, - sizeof(req))) { - pr_err("copy_from_user failed\n"); - return -EFAULT; - } - - if ((req.resp_buf == NULL) || (req.cmd_req_buf == NULL)) { - pr_err("cmd buffer or response buffer is null\n"); + if (!req || !req->resp_buf || !req->cmd_req_buf) { + pr_err("req or cmd buffer or response buffer is null\n"); return -EINVAL; } @@ -2777,6 +2721,86 @@ static int qseecom_send_service_cmd(struct qseecom_dev_handle *data, return -EINVAL; } + if (((uintptr_t)req->cmd_req_buf < + data->client.user_virt_sb_base) || + ((uintptr_t)req->cmd_req_buf >= + (data->client.user_virt_sb_base + data->client.sb_length))) { + pr_err("cmd buffer address not within shared bufffer\n"); + return -EINVAL; + } + if (((uintptr_t)req->resp_buf < + data->client.user_virt_sb_base) || + ((uintptr_t)req->resp_buf >= + (data->client.user_virt_sb_base + data->client.sb_length))) { + pr_err("response buffer address not within shared bufffer\n"); + return -EINVAL; + } + if ((req->cmd_req_len == 0) || (req->resp_len == 0) || + (req->cmd_req_len > data->client.sb_length) || + (req->resp_len > data->client.sb_length)) { + pr_err("cmd buf length or response buf length not valid\n"); + return -EINVAL; + } + if (req->cmd_req_len > UINT_MAX - req->resp_len) { + pr_err("Integer overflow detected in req_len & rsp_len\n"); + return -EINVAL; + } + + if ((req->cmd_req_len + req->resp_len) > data->client.sb_length) { + pr_debug("Not enough memory to fit cmd_buf.\n"); + pr_debug("resp_buf. Required: %u, Available: %zu\n", + (req->cmd_req_len + req->resp_len), + data->client.sb_length); + return -ENOMEM; + } + if ((uintptr_t)req->cmd_req_buf > (ULONG_MAX - req->cmd_req_len)) { + pr_err("Integer overflow in req_len & cmd_req_buf\n"); + return -EINVAL; + } + if ((uintptr_t)req->resp_buf > (ULONG_MAX - req->resp_len)) { + pr_err("Integer overflow in resp_len & resp_buf\n"); + return -EINVAL; + } + if (data->client.user_virt_sb_base > + (ULONG_MAX - data->client.sb_length)) { + pr_err("Integer overflow in user_virt_sb_base & sb_length\n"); + return -EINVAL; + } + if ((((uintptr_t)req->cmd_req_buf + req->cmd_req_len) > + ((uintptr_t)data->client.user_virt_sb_base + + data->client.sb_length)) || + (((uintptr_t)req->resp_buf + req->resp_len) > + ((uintptr_t)data->client.user_virt_sb_base + + data->client.sb_length))) { + pr_err("cmd buf or resp buf is out of shared buffer region\n"); + return -EINVAL; + } + return 0; +} + +static int qseecom_send_service_cmd(struct qseecom_dev_handle *data, + void __user *argp) +{ + int ret = 0; + struct qseecom_client_send_service_ireq send_svc_ireq; + struct qseecom_client_send_fsm_key_req send_fsm_key_svc_ireq; + struct qseecom_command_scm_resp resp; + struct qseecom_send_svc_cmd_req req; + void *send_req_ptr; + size_t req_buf_size; + + /*struct qseecom_command_scm_resp resp;*/ + + if (copy_from_user(&req, + (void __user *)argp, + sizeof(req))) { + pr_err("copy_from_user failed\n"); + return -EFAULT; + } + + if (__validate_send_service_cmd_inputs(data, &req)) + return -EINVAL; + data->type = QSEECOM_SECURE_SERVICE; switch (req.cmd_id) { @@ -3625,6 +3649,13 @@ cleanup: } return ret; err: + for (i = 0; i < MAX_ION_FD; i++) + if (data->client.sec_buf_fd[i].is_sec_buf_fd && + data->client.sec_buf_fd[i].vbase) + dma_free_coherent(qseecom.pdev, + data->client.sec_buf_fd[i].size, + data->client.sec_buf_fd[i].vbase, + data->client.sec_buf_fd[i].pbase); if (!IS_ERR_OR_NULL(ihandle)) ion_free(qseecom.ion_clnt, ihandle); return -ENOMEM; diff --git a/drivers/power/qcom-charger/qpnp-smb2.c b/drivers/power/qcom-charger/qpnp-smb2.c index a07325102631..98a917273328 100644 --- a/drivers/power/qcom-charger/qpnp-smb2.c +++ b/drivers/power/qcom-charger/qpnp-smb2.c @@ -288,6 +288,9 @@ static int smb2_parse_dt(struct smb2 *chip) chip->dt.no_battery = of_property_read_bool(node, "qcom,batteryless-platform"); + chg->external_vconn = of_property_read_bool(node, + "qcom,external-vconn"); + rc = of_property_read_u32(node, "qcom,fcc-max-ua", &chip->dt.fcc_ua); if (rc < 0) @@ -1522,7 +1525,7 @@ static struct smb2_irq_info smb2_irqs[] = { }, { .name = "otg-overcurrent", - .handler = smblib_handle_debug, + .handler = smblib_handle_otg_overcurrent, }, { .name = "otg-oc-dis-sw-sts", diff --git a/drivers/power/qcom-charger/smb-lib.c b/drivers/power/qcom-charger/smb-lib.c index 6d010a11d034..eec96d30d4f9 100644 --- a/drivers/power/qcom-charger/smb-lib.c +++ b/drivers/power/qcom-charger/smb-lib.c @@ -1013,12 +1013,119 @@ static int smblib_apsd_disable_vote_callback(struct votable *votable, return 0; } + +/******************* + * VCONN REGULATOR * + * *****************/ + +static int _smblib_vconn_regulator_enable(struct regulator_dev *rdev) +{ + struct smb_charger *chg = rdev_get_drvdata(rdev); + u8 otg_stat, stat4; + int rc = 0; + + if (!chg->external_vconn) { + rc = smblib_read(chg, OTG_STATUS_REG, &otg_stat); + if (rc < 0) { + smblib_err(chg, "Couldn't read OTG status rc=%d\n", rc); + return rc; + } + + if ((otg_stat & OTG_STATE_MASK) != OTG_STATE_ENABLED) { + smblib_err(chg, "Couldn't enable VCONN; OTG is not ready otg_stat=0x%02x\n", + otg_stat); + return -EAGAIN; + } + } + + /* + * VCONN_EN_ORIENTATION is overloaded with overriding the CC pin used + * for Vconn, and it should be set with reverse polarity of CC_OUT. + */ + rc = smblib_read(chg, TYPE_C_STATUS_4_REG, &stat4); + if (rc < 0) { + smblib_err(chg, "Couldn't read TYPE_C_STATUS_4 rc=%d\n", rc); + return rc; + } + + stat4 = stat4 & CC_ORIENTATION_BIT ? 0 : VCONN_EN_ORIENTATION_BIT; + rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, + VCONN_EN_VALUE_BIT | VCONN_EN_ORIENTATION_BIT, + VCONN_EN_VALUE_BIT | stat4); + if (rc < 0) { + smblib_err(chg, "Couldn't enable vconn setting rc=%d\n", rc); + return rc; + } + + return rc; +} + +int smblib_vconn_regulator_enable(struct regulator_dev *rdev) +{ + struct smb_charger *chg = rdev_get_drvdata(rdev); + int rc = 0; + + mutex_lock(&chg->otg_overcurrent_lock); + if (chg->vconn_en) + goto unlock; + + rc = _smblib_vconn_regulator_enable(rdev); + if (rc >= 0) + chg->vconn_en = true; + +unlock: + mutex_unlock(&chg->otg_overcurrent_lock); + return rc; +} + +static int _smblib_vconn_regulator_disable(struct regulator_dev *rdev) +{ + struct smb_charger *chg = rdev_get_drvdata(rdev); + int rc = 0; + + rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, + VCONN_EN_VALUE_BIT, 0); + if (rc < 0) + smblib_err(chg, "Couldn't disable vconn regulator rc=%d\n", rc); + + return rc; +} + +int smblib_vconn_regulator_disable(struct regulator_dev *rdev) +{ + struct smb_charger *chg = rdev_get_drvdata(rdev); + int rc = 0; + + mutex_lock(&chg->otg_overcurrent_lock); + if (!chg->vconn_en) + goto unlock; + + rc = _smblib_vconn_regulator_disable(rdev); + if (rc >= 0) + chg->vconn_en = false; + +unlock: + mutex_unlock(&chg->otg_overcurrent_lock); + return rc; +} + +int smblib_vconn_regulator_is_enabled(struct regulator_dev *rdev) +{ + struct smb_charger *chg = rdev_get_drvdata(rdev); + int ret; + + mutex_lock(&chg->otg_overcurrent_lock); + ret = chg->vconn_en; + mutex_unlock(&chg->otg_overcurrent_lock); + return ret; +} + /***************** * OTG REGULATOR * *****************/ #define MAX_SOFTSTART_TRIES 2 -int smblib_vbus_regulator_enable(struct regulator_dev *rdev) +static int _smblib_vbus_regulator_enable(struct regulator_dev *rdev) { struct smb_charger *chg = rdev_get_drvdata(rdev); u8 stat; @@ -1056,110 +1163,103 @@ int smblib_vbus_regulator_enable(struct regulator_dev *rdev) } } while (--tries); - if (tries == 0) + if (tries == 0) { smblib_err(chg, "Timeout waiting for boost softstart rc=%d\n", rc); + return -ETIMEDOUT; + } return rc; } -int smblib_vbus_regulator_disable(struct regulator_dev *rdev) +int smblib_vbus_regulator_enable(struct regulator_dev *rdev) { struct smb_charger *chg = rdev_get_drvdata(rdev); int rc = 0; - rc = smblib_write(chg, CMD_OTG_REG, 0); - if (rc < 0) { - smblib_err(chg, "Couldn't disable OTG regulator rc=%d\n", rc); - return rc; - } - - smblib_otg_cl_config(chg, MICRO_250MA); - - rc = smblib_masked_write(chg, OTG_ENG_OTG_CFG_REG, - ENG_BUCKBOOST_HALT1_8_MODE_BIT, 0); - if (rc < 0) { - smblib_err(chg, "Couldn't set OTG_ENG_OTG_CFG_REG rc=%d\n", - rc); - return rc; - } + mutex_lock(&chg->otg_overcurrent_lock); + if (chg->otg_en) + goto unlock; + rc = _smblib_vbus_regulator_enable(rdev); + if (rc >= 0) + chg->otg_en = true; +unlock: + mutex_unlock(&chg->otg_overcurrent_lock); return rc; } -int smblib_vbus_regulator_is_enabled(struct regulator_dev *rdev) +static int _smblib_vbus_regulator_disable(struct regulator_dev *rdev) { struct smb_charger *chg = rdev_get_drvdata(rdev); - int rc = 0; - u8 cmd; + int rc; + u8 stat; + + if (!chg->external_vconn) { + rc = smblib_read(chg, RID_CC_CONTROL_7_0_REG, &stat); + if (rc < 0) { + smblib_err(chg, "Couldn't read RID_CC_CONTROL_7_0 rc=%d\n", + rc); + return rc; + } + + /* check if VCONN is enabled on either CC pin */ + if (stat & VCONN_EN_CC_MASK) { + smblib_dbg(chg, PR_MISC, "Killing VCONN before disabling OTG\n"); + rc = _smblib_vconn_regulator_disable(rdev); + if (rc < 0) + smblib_err(chg, "Couldn't disable VCONN rc=%d\n", + rc); + return rc; + } + } - rc = smblib_read(chg, CMD_OTG_REG, &cmd); + rc = smblib_write(chg, CMD_OTG_REG, 0); if (rc < 0) { - smblib_err(chg, "Couldn't read CMD_OTG rc=%d", rc); + smblib_err(chg, "Couldn't disable OTG regulator rc=%d\n", rc); return rc; } - return (cmd & OTG_EN_BIT) ? 1 : 0; -} - -/******************* - * VCONN REGULATOR * - * *****************/ - -int smblib_vconn_regulator_enable(struct regulator_dev *rdev) -{ - struct smb_charger *chg = rdev_get_drvdata(rdev); - u8 stat; - int rc = 0; + smblib_otg_cl_config(chg, MICRO_250MA); - /* - * VCONN_EN_ORIENTATION is overloaded with overriding the CC pin used - * for Vconn, and it should be set with reverse polarity of CC_OUT. - */ - rc = smblib_read(chg, TYPE_C_STATUS_4_REG, &stat); + rc = smblib_masked_write(chg, OTG_ENG_OTG_CFG_REG, + ENG_BUCKBOOST_HALT1_8_MODE_BIT, 0); if (rc < 0) { - smblib_err(chg, "Couldn't read TYPE_C_STATUS_4 rc=%d\n", rc); + smblib_err(chg, "Couldn't set OTG_ENG_OTG_CFG_REG rc=%d\n", rc); return rc; } - stat = stat & CC_ORIENTATION_BIT ? 0 : VCONN_EN_ORIENTATION_BIT; - rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, - VCONN_EN_VALUE_BIT | VCONN_EN_ORIENTATION_BIT, - VCONN_EN_VALUE_BIT | stat); - if (rc < 0) - smblib_err(chg, "Couldn't enable vconn setting rc=%d\n", rc); - return rc; + return 0; } -int smblib_vconn_regulator_disable(struct regulator_dev *rdev) +int smblib_vbus_regulator_disable(struct regulator_dev *rdev) { struct smb_charger *chg = rdev_get_drvdata(rdev); int rc = 0; - rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, - VCONN_EN_VALUE_BIT, 0); - if (rc < 0) - smblib_err(chg, "Couldn't disable vconn regulator rc=%d\n", - rc); + mutex_lock(&chg->otg_overcurrent_lock); + if (!chg->otg_en) + goto unlock; + + rc = _smblib_vbus_regulator_disable(rdev); + if (rc >= 0) + chg->otg_en = false; +unlock: + mutex_unlock(&chg->otg_overcurrent_lock); return rc; } -int smblib_vconn_regulator_is_enabled(struct regulator_dev *rdev) +int smblib_vbus_regulator_is_enabled(struct regulator_dev *rdev) { struct smb_charger *chg = rdev_get_drvdata(rdev); - int rc = 0; - u8 cmd; - - rc = smblib_read(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, &cmd); - if (rc < 0) { - smblib_err(chg, "Couldn't read TYPE_C_INTRPT_ENB_SOFTWARE_CTRL rc=%d\n", - rc); - return rc; - } + int ret; - return (cmd & VCONN_EN_VALUE_BIT) ? 1 : 0; + mutex_lock(&chg->otg_overcurrent_lock); + ret = chg->otg_en; + mutex_unlock(&chg->otg_overcurrent_lock); + return ret; } /******************** @@ -2350,6 +2450,66 @@ irqreturn_t smblib_handle_debug(int irq, void *data) return IRQ_HANDLED; } +irqreturn_t smblib_handle_otg_overcurrent(int irq, void *data) +{ + struct smb_irq_data *irq_data = data; + struct smb_charger *chg = irq_data->parent_data; + int rc; + u8 stat; + + rc = smblib_read(chg, OTG_BASE + INT_RT_STS_OFFSET, &stat); + if (rc < 0) { + dev_err(chg->dev, "Couldn't read OTG_INT_RT_STS rc=%d\n", rc); + return IRQ_HANDLED; + } + + if (!(stat & OTG_OVERCURRENT_RT_STS_BIT)) + return IRQ_HANDLED; + + smblib_err(chg, "over-current detected on VBUS\n"); + if (!chg->vbus_vreg || !chg->vbus_vreg->rdev) + return IRQ_HANDLED; + + mutex_lock(&chg->otg_overcurrent_lock); + if (!chg->external_vconn && chg->vconn_en) { + rc = _smblib_vconn_regulator_disable(chg->vconn_vreg->rdev); + if (rc < 0) + smblib_err(chg, "Couldn't disable VCONN rc=%d\n", rc); + } + + rc = _smblib_vbus_regulator_disable(chg->vbus_vreg->rdev); + if (rc < 0) + smblib_err(chg, "Couldn't disable VBUS rc=%d\n", rc); + + /* + * VBUS must be disabled after OC to be ready for the next insertion. + * If the maximum number of attempts have been reached then don't try + * to re-enable. + */ + if (++chg->otg_attempts > OTG_MAX_ATTEMPTS) { + smblib_err(chg, "OTG failed to enable after %d attempts\n", + chg->otg_attempts - 1); + goto unlock; + } + + /* allow the attached device to discharge */ + msleep(250); + + rc = _smblib_vbus_regulator_enable(chg->vbus_vreg->rdev); + if (rc < 0) + smblib_err(chg, "Couldn't enable VBUS rc=%d\n", rc); + + if (!chg->external_vconn && chg->vconn_en) { + rc = _smblib_vconn_regulator_enable(chg->vconn_vreg->rdev); + if (rc < 0) + smblib_err(chg, "Couldn't enable VCONN rc=%d\n", rc); + } + +unlock: + mutex_unlock(&chg->otg_overcurrent_lock); + return IRQ_HANDLED; +} + static void smblib_pl_handle_chg_state_change(struct smb_charger *chg, u8 stat) { bool pl_enabled; @@ -2864,6 +3024,8 @@ static void smblib_handle_typec_removal(struct smb_charger *chg) */ vote(chg->apsd_disable_votable, PD_HARD_RESET_VOTER, false, 0); + chg->vconn_attempts = 0; + chg->otg_attempts = 0; typec_source_removal(chg); typec_sink_removal(chg); @@ -2968,6 +3130,41 @@ irqreturn_t smblib_handle_usb_typec_change_for_uusb(struct smb_charger *chg) return IRQ_HANDLED; } +static void smblib_handle_vconn_overcurrent(struct smb_charger *chg) +{ + int rc; + + smblib_err(chg, "over-current detected on VCONN\n"); + if (!chg->vconn_vreg || !chg->vconn_vreg->rdev) + return; + + mutex_lock(&chg->otg_overcurrent_lock); + rc = _smblib_vconn_regulator_disable(chg->vconn_vreg->rdev); + if (rc < 0) + smblib_err(chg, "Couldn't disable VCONN rc=%d\n", rc); + + /* + * VCONN must be disabled after OC to be ready for the next insertion. + * If the maximum number of attempts have been reached then don't try + * to re-enable. + */ + if (++chg->vconn_attempts > VCONN_MAX_ATTEMPTS) { + smblib_err(chg, "VCONN failed to enable after %d attempts\n", + chg->vconn_attempts - 1); + goto unlock; + } + + /* allow the attached device to discharge */ + msleep(250); + + rc = _smblib_vconn_regulator_enable(chg->vconn_vreg->rdev); + if (rc < 0) + smblib_err(chg, "Couldn't enable VCONN rc=%d\n", rc); + +unlock: + mutex_unlock(&chg->otg_overcurrent_lock); +} + irqreturn_t smblib_handle_usb_typec_change(int irq, void *data) { struct smb_irq_data *irq_data = data; @@ -3006,6 +3203,9 @@ irqreturn_t smblib_handle_usb_typec_change(int irq, void *data) smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s vbus-error\n", irq_data->name); + if (stat4 & TYPEC_VCONN_OVERCURR_STATUS_BIT) + smblib_handle_vconn_overcurrent(chg); + power_supply_changed(chg->usb_psy); smblib_dbg(chg, PR_REGISTER, "TYPE_C_STATUS_4 = 0x%02x\n", stat4); smblib_dbg(chg, PR_REGISTER, "TYPE_C_STATUS_5 = 0x%02x\n", stat5); @@ -3436,6 +3636,7 @@ int smblib_init(struct smb_charger *chg) int rc = 0; mutex_init(&chg->write_lock); + mutex_init(&chg->otg_overcurrent_lock); INIT_WORK(&chg->bms_update_work, bms_update_work); INIT_WORK(&chg->pl_detect_work, smblib_pl_detect_work); INIT_WORK(&chg->rdstd_cc2_detach_work, rdstd_cc2_detach_work); diff --git a/drivers/power/qcom-charger/smb-lib.h b/drivers/power/qcom-charger/smb-lib.h index b65c0211405a..efce7eb987ab 100644 --- a/drivers/power/qcom-charger/smb-lib.h +++ b/drivers/power/qcom-charger/smb-lib.h @@ -52,6 +52,9 @@ enum print_reason { #define HVDCP_INDIRECT_VOTER "HVDCP_INDIRECT_VOTER" #define MICRO_USB_VOTER "MICRO_USB_VOTER" +#define VCONN_MAX_ATTEMPTS 3 +#define OTG_MAX_ATTEMPTS 3 + enum smb_mode { PARALLEL_MASTER = 0, PARALLEL_SLAVE, @@ -153,10 +156,12 @@ struct smb_charger { struct smb_iio iio; int *debug_mask; enum smb_mode mode; + bool external_vconn; /* locks */ struct mutex write_lock; struct mutex ps_change_lock; + struct mutex otg_overcurrent_lock; /* power supplies */ struct power_supply *batt_psy; @@ -210,21 +215,21 @@ struct smb_charger { int pd_active; bool system_suspend_supported; int boost_threshold_ua; - int system_temp_level; int thermal_levels; int *thermal_mitigation; - int otg_cl_ua; int dcp_icl_ua; - int fake_capacity; - bool step_chg_enabled; bool is_hdc; bool chg_done; bool micro_usb_mode; int input_limited_fcc_ua; + bool otg_en; + bool vconn_en; + int otg_attempts; + int vconn_attempts; /* workaround flag */ u32 wa_flags; @@ -266,6 +271,7 @@ int smblib_vconn_regulator_disable(struct regulator_dev *rdev); int smblib_vconn_regulator_is_enabled(struct regulator_dev *rdev); irqreturn_t smblib_handle_debug(int irq, void *data); +irqreturn_t smblib_handle_otg_overcurrent(int irq, void *data); irqreturn_t smblib_handle_chg_state_change(int irq, void *data); irqreturn_t smblib_handle_step_chg_state_change(int irq, void *data); irqreturn_t smblib_handle_step_chg_soc_update_fail(int irq, void *data); diff --git a/drivers/power/qcom-charger/smb-reg.h b/drivers/power/qcom-charger/smb-reg.h index a9606ab1944b..5f74e27c7978 100644 --- a/drivers/power/qcom-charger/smb-reg.h +++ b/drivers/power/qcom-charger/smb-reg.h @@ -348,6 +348,7 @@ enum { #define OTG_STATUS_REG (OTG_BASE + 0x09) #define BOOST_SOFTSTART_DONE_BIT BIT(3) #define OTG_STATE_MASK GENMASK(2, 0) +#define OTG_STATE_ENABLED 0x2 /* OTG Interrupt Bits */ #define TESTMODE_CHANGE_DETECT_RT_STS_BIT BIT(3) diff --git a/drivers/regulator/cpr3-regulator.c b/drivers/regulator/cpr3-regulator.c index e3e418100eef..6775152f2623 100644 --- a/drivers/regulator/cpr3-regulator.c +++ b/drivers/regulator/cpr3-regulator.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-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 @@ -4442,6 +4442,14 @@ static int cpr3_regulator_disable(struct regulator_dev *rdev) rc); goto done; } + if (ctrl->support_ldo300_vreg) { + rc = regulator_set_voltage(ctrl->system_regulator, 0, + INT_MAX); + if (rc) + cpr3_err(ctrl, "failed to set voltage on system rc=%d\n", + rc); + goto done; + } } cpr3_debug(vreg, "Disabled\n"); diff --git a/drivers/regulator/cpr3-util.c b/drivers/regulator/cpr3-util.c index 60fe825ca013..120ca69e100f 100644 --- a/drivers/regulator/cpr3-util.c +++ b/drivers/regulator/cpr3-util.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-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 @@ -1203,21 +1203,21 @@ int cpr3_parse_common_ctrl_data(struct cpr3_controller *ctrl) if (rc) return rc; - ctrl->vdd_regulator = devm_regulator_get(ctrl->dev, "vdd"); - if (IS_ERR(ctrl->vdd_regulator)) { - rc = PTR_ERR(ctrl->vdd_regulator); - if (rc != -EPROBE_DEFER) { - /* vdd-supply is optional for CPRh controllers. */ - if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPRH) { - cpr3_debug(ctrl, "unable to request vdd regulator, rc=%d\n", - rc); - ctrl->vdd_regulator = NULL; - return 0; - } - cpr3_err(ctrl, "unable to request vdd regulator, rc=%d\n", - rc); + if (of_find_property(ctrl->dev->of_node, "vdd-supply", NULL)) { + ctrl->vdd_regulator = devm_regulator_get(ctrl->dev, "vdd"); + if (IS_ERR(ctrl->vdd_regulator)) { + rc = PTR_ERR(ctrl->vdd_regulator); + if (rc != -EPROBE_DEFER) + cpr3_err(ctrl, "unable to request vdd regulator, rc=%d\n", + rc); + return rc; } - return rc; + } else if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPRH) { + /* vdd-supply is optional for CPRh controllers. */ + ctrl->vdd_regulator = NULL; + } else { + cpr3_err(ctrl, "vdd supply is not defined\n"); + return -ENODEV; } /* diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index ded18adba596..2b097d8ab090 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -143,6 +143,7 @@ enum icnss_debug_quirks { SSR_ONLY, PDR_ONLY, VBATT_DISABLE, + FW_REJUVENATE_ENABLE, }; #define ICNSS_QUIRKS_DEFAULT BIT(VBATT_DISABLE) @@ -150,6 +151,9 @@ enum icnss_debug_quirks { unsigned long quirks = ICNSS_QUIRKS_DEFAULT; module_param(quirks, ulong, 0600); +uint64_t dynamic_feature_mask = QMI_WLFW_FW_REJUVENATE_V01; +module_param(dynamic_feature_mask, ullong, 0600); + void *icnss_ipc_log_context; #ifdef CONFIG_ICNSS_DEBUG @@ -175,6 +179,7 @@ enum icnss_driver_event_type { struct icnss_event_pd_service_down_data { bool crashed; + bool fw_rejuvenate; }; struct icnss_driver_event { @@ -256,6 +261,9 @@ struct icnss_stats { uint32_t vbatt_req; uint32_t vbatt_resp; uint32_t vbatt_req_err; + uint32_t rejuvenate_ack_req; + uint32_t rejuvenate_ack_resp; + uint32_t rejuvenate_ack_err; }; #define MAX_NO_OF_MAC_ADDR 4 @@ -264,6 +272,12 @@ struct icnss_wlan_mac_addr { uint32_t no_of_mac_addr_set; }; +struct service_notifier_context { + void *handle; + uint32_t instance_id; + char name[QMI_SERVREG_LOC_NAME_LENGTH_V01 + 1]; +}; + static struct icnss_priv { uint32_t magic; struct platform_device *pdev; @@ -301,7 +315,7 @@ static struct icnss_priv { spinlock_t on_off_lock; struct icnss_stats stats; struct work_struct service_notifier_work; - void **service_notifier; + struct service_notifier_context *service_notifier; struct notifier_block service_notifier_nb; int total_domains; struct notifier_block get_service_nb; @@ -1001,6 +1015,10 @@ static int wlfw_ind_register_send_sync_msg(void) req.msa_ready_enable = 1; req.pin_connect_result_enable_valid = 1; req.pin_connect_result_enable = 1; + if (test_bit(FW_REJUVENATE_ENABLE, &quirks)) { + req.rejuvenate_enable_valid = 1; + req.rejuvenate_enable = 1; + } req_desc.max_msg_len = WLFW_IND_REGISTER_REQ_MSG_V01_MAX_MSG_LEN; req_desc.msg_id = QMI_WLFW_IND_REGISTER_REQ_V01; @@ -1390,6 +1408,114 @@ out: return ret; } +static int wlfw_rejuvenate_ack_send_sync_msg(struct icnss_priv *priv) +{ + int ret; + struct wlfw_rejuvenate_ack_req_msg_v01 req; + struct wlfw_rejuvenate_ack_resp_msg_v01 resp; + struct msg_desc req_desc, resp_desc; + + icnss_pr_dbg("Sending rejuvenate ack request, state: 0x%lx\n", + priv->state); + + memset(&req, 0, sizeof(req)); + memset(&resp, 0, sizeof(resp)); + + req_desc.max_msg_len = WLFW_REJUVENATE_ACK_REQ_MSG_V01_MAX_MSG_LEN; + req_desc.msg_id = QMI_WLFW_REJUVENATE_ACK_REQ_V01; + req_desc.ei_array = wlfw_rejuvenate_ack_req_msg_v01_ei; + + resp_desc.max_msg_len = WLFW_REJUVENATE_ACK_RESP_MSG_V01_MAX_MSG_LEN; + resp_desc.msg_id = QMI_WLFW_REJUVENATE_ACK_RESP_V01; + resp_desc.ei_array = wlfw_rejuvenate_ack_resp_msg_v01_ei; + + priv->stats.rejuvenate_ack_req++; + ret = qmi_send_req_wait(priv->wlfw_clnt, &req_desc, &req, sizeof(req), + &resp_desc, &resp, sizeof(resp), + WLFW_TIMEOUT_MS); + if (ret < 0) { + icnss_pr_err("Send rejuvenate ack req failed %d\n", ret); + goto out; + } + + if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { + icnss_pr_err("QMI rejuvenate ack request rejected, result:%d error %d\n", + resp.resp.result, resp.resp.error); + ret = resp.resp.result; + goto out; + } + priv->stats.rejuvenate_ack_resp++; + return 0; + +out: + priv->stats.rejuvenate_ack_err++; + ICNSS_ASSERT(false); + return ret; +} + +static int wlfw_dynamic_feature_mask_send_sync_msg(struct icnss_priv *priv, + uint64_t dynamic_feature_mask) +{ + int ret; + struct wlfw_dynamic_feature_mask_req_msg_v01 req; + struct wlfw_dynamic_feature_mask_resp_msg_v01 resp; + struct msg_desc req_desc, resp_desc; + + if (!test_bit(ICNSS_WLFW_QMI_CONNECTED, &priv->state)) { + icnss_pr_err("Invalid state for dynamic feature: 0x%lx\n", + priv->state); + return -EINVAL; + } + + if (!test_bit(FW_REJUVENATE_ENABLE, &quirks)) { + icnss_pr_dbg("FW rejuvenate is disabled from quirks\n"); + dynamic_feature_mask &= ~QMI_WLFW_FW_REJUVENATE_V01; + } + + icnss_pr_dbg("Sending dynamic feature mask request, val 0x%llx, state: 0x%lx\n", + dynamic_feature_mask, priv->state); + + memset(&req, 0, sizeof(req)); + memset(&resp, 0, sizeof(resp)); + + req.mask_valid = 1; + req.mask = dynamic_feature_mask; + + req_desc.max_msg_len = + WLFW_DYNAMIC_FEATURE_MASK_REQ_MSG_V01_MAX_MSG_LEN; + req_desc.msg_id = QMI_WLFW_DYNAMIC_FEATURE_MASK_REQ_V01; + req_desc.ei_array = wlfw_dynamic_feature_mask_req_msg_v01_ei; + + resp_desc.max_msg_len = + WLFW_DYNAMIC_FEATURE_MASK_RESP_MSG_V01_MAX_MSG_LEN; + resp_desc.msg_id = QMI_WLFW_DYNAMIC_FEATURE_MASK_RESP_V01; + resp_desc.ei_array = wlfw_dynamic_feature_mask_resp_msg_v01_ei; + + ret = qmi_send_req_wait(priv->wlfw_clnt, &req_desc, &req, sizeof(req), + &resp_desc, &resp, sizeof(resp), + WLFW_TIMEOUT_MS); + if (ret < 0) { + icnss_pr_err("Send dynamic feature mask req failed %d\n", ret); + goto out; + } + + if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { + icnss_pr_err("QMI dynamic feature mask request rejected, result:%d error %d\n", + resp.resp.result, resp.resp.error); + ret = resp.resp.result; + goto out; + } + + icnss_pr_dbg("prev_mask_valid %u, prev_mask 0x%llx, curr_maks_valid %u, curr_mask 0x%llx\n", + resp.prev_mask_valid, resp.prev_mask, + resp.curr_mask_valid, resp.curr_mask); + + return 0; + +out: + return ret; +} + static void icnss_qmi_wlfw_clnt_notify_work(struct work_struct *work) { int ret; @@ -1430,6 +1556,8 @@ static void icnss_qmi_wlfw_clnt_ind(struct qmi_handle *handle, unsigned int msg_id, void *msg, unsigned int msg_len, void *ind_cb_priv) { + struct icnss_event_pd_service_down_data *event_data; + if (!penv) return; @@ -1450,6 +1578,17 @@ static void icnss_qmi_wlfw_clnt_ind(struct qmi_handle *handle, msg_id); icnss_qmi_pin_connect_result_ind(msg, msg_len); break; + case QMI_WLFW_REJUVENATE_IND_V01: + icnss_pr_dbg("Received Rejuvenate Indication msg_id 0x%x, state: 0x%lx\n", + msg_id, penv->state); + event_data = kzalloc(sizeof(*event_data), GFP_KERNEL); + if (event_data == NULL) + return; + event_data->crashed = true; + event_data->fw_rejuvenate = true; + icnss_driver_event_post(ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN, + 0, event_data); + break; default: icnss_pr_err("Invalid msg_id 0x%x\n", msg_id); break; @@ -1522,6 +1661,11 @@ static int icnss_driver_event_server_arrive(void *data) if (ret < 0) goto err_setup_msa; + ret = wlfw_dynamic_feature_mask_send_sync_msg(penv, + dynamic_feature_mask); + if (ret < 0) + goto err_setup_msa; + icnss_init_vph_monitor(penv); return ret; @@ -1773,6 +1917,9 @@ static int icnss_driver_event_pd_service_down(struct icnss_priv *priv, else icnss_call_driver_remove(priv); + if (event_data->fw_rejuvenate) + wlfw_rejuvenate_ack_send_sync_msg(priv); + out: ret = icnss_hw_power_off(priv); @@ -1973,8 +2120,9 @@ static int icnss_pdr_unregister_notifier(struct icnss_priv *priv) return 0; for (i = 0; i < priv->total_domains; i++) - service_notif_unregister_notifier(priv->service_notifier[i], - &priv->service_notifier_nb); + service_notif_unregister_notifier( + priv->service_notifier[i].handle, + &priv->service_notifier_nb); kfree(priv->service_notifier); @@ -2027,7 +2175,7 @@ static int icnss_get_service_location_notify(struct notifier_block *nb, int curr_state; int ret; int i; - void **handle; + struct service_notifier_context *notifier; icnss_pr_dbg("Get service notify opcode: %lu, state: 0x%lx\n", opcode, priv->state); @@ -2041,9 +2189,10 @@ static int icnss_get_service_location_notify(struct notifier_block *nb, goto out; } - handle = kcalloc(pd->total_domains, sizeof(void *), GFP_KERNEL); - - if (!handle) { + notifier = kcalloc(pd->total_domains, + sizeof(struct service_notifier_context), + GFP_KERNEL); + if (!notifier) { ret = -ENOMEM; goto out; } @@ -2055,21 +2204,24 @@ static int icnss_get_service_location_notify(struct notifier_block *nb, pd->domain_list[i].name, pd->domain_list[i].instance_id); - handle[i] = + notifier[i].handle = service_notif_register_notifier(pd->domain_list[i].name, pd->domain_list[i].instance_id, &priv->service_notifier_nb, &curr_state); + notifier[i].instance_id = pd->domain_list[i].instance_id; + strlcpy(notifier[i].name, pd->domain_list[i].name, + QMI_SERVREG_LOC_NAME_LENGTH_V01 + 1); - if (IS_ERR(handle[i])) { + if (IS_ERR(notifier[i].handle)) { icnss_pr_err("%d: Unable to register notifier for %s(0x%x)\n", i, pd->domain_list->name, pd->domain_list->instance_id); - ret = PTR_ERR(handle[i]); + ret = PTR_ERR(notifier[i].handle); goto free_handle; } } - priv->service_notifier = handle; + priv->service_notifier = notifier; priv->total_domains = pd->total_domains; set_bit(ICNSS_PDR_ENABLED, &priv->state); @@ -2080,11 +2232,11 @@ static int icnss_get_service_location_notify(struct notifier_block *nb, free_handle: for (i = 0; i < pd->total_domains; i++) { - if (handle[i]) - service_notif_unregister_notifier(handle[i], + if (notifier[i].handle) + service_notif_unregister_notifier(notifier[i].handle, &priv->service_notifier_nb); } - kfree(handle); + kfree(notifier); out: icnss_pr_err("PD restart not enabled: %d, state: 0x%lx\n", ret, @@ -2713,6 +2865,42 @@ out: } EXPORT_SYMBOL(icnss_get_wlan_mac_address); +int icnss_trigger_recovery(struct device *dev) +{ + int ret = 0; + struct icnss_priv *priv = dev_get_drvdata(dev); + + if (priv->magic != ICNSS_MAGIC) { + icnss_pr_err("Invalid drvdata: magic 0x%x\n", priv->magic); + ret = -EINVAL; + goto out; + } + + if (test_bit(ICNSS_PD_RESTART, &priv->state)) { + icnss_pr_err("PD recovery already in progress: state: 0x%lx\n", + priv->state); + ret = -EPERM; + goto out; + } + + if (!priv->service_notifier[0].handle) { + icnss_pr_err("Invalid handle during recovery\n"); + ret = -EINVAL; + goto out; + } + + /* + * Initiate PDR, required only for the first instance + */ + ret = service_notif_pd_restart(priv->service_notifier[0].name, + priv->service_notifier[0].instance_id); + +out: + return ret; +} +EXPORT_SYMBOL(icnss_trigger_recovery); + + static int icnss_smmu_init(struct icnss_priv *priv) { struct dma_iommu_mapping *mapping; @@ -2776,33 +2964,35 @@ static void icnss_smmu_deinit(struct icnss_priv *priv) priv->smmu_mapping = NULL; } -static int icnss_test_mode_show(struct seq_file *s, void *data) +static int icnss_fw_debug_show(struct seq_file *s, void *data) { struct icnss_priv *priv = s->private; - seq_puts(s, "0 : Test mode disable\n"); - seq_puts(s, "1 : WLAN Firmware test\n"); - seq_puts(s, "2 : CCPM test\n"); + seq_puts(s, "\nUsage: echo <CMD> <VAL> > <DEBUGFS>/icnss/fw_debug\n"); - seq_puts(s, "\n"); + seq_puts(s, "\nCMD: test_mode\n"); + seq_puts(s, " VAL: 0 (Test mode disable)\n"); + seq_puts(s, " VAL: 1 (WLAN FW test)\n"); + seq_puts(s, " VAL: 2 (CCPM test)\n"); + + seq_puts(s, "\nCMD: dynamic_feature_mask\n"); + seq_puts(s, " VAL: (64 bit feature mask)\n"); if (!test_bit(ICNSS_FW_READY, &priv->state)) { - seq_puts(s, "Firmware is not ready yet!, wait for FW READY\n"); + seq_puts(s, "Firmware is not ready yet, can't run test_mode!\n"); goto out; } if (test_bit(ICNSS_DRIVER_PROBED, &priv->state)) { - seq_puts(s, "Machine mode is running, can't run test mode!\n"); + seq_puts(s, "Machine mode is running, can't run test_mode!\n"); goto out; } if (test_bit(ICNSS_FW_TEST_MODE, &priv->state)) { - seq_puts(s, "Test mode is running!\n"); + seq_puts(s, "test_mode is running, can't run test_mode!\n"); goto out; } - seq_puts(s, "Test can be run, Have fun!\n"); - out: seq_puts(s, "\n"); return 0; @@ -2888,31 +3078,61 @@ out: return ret; } -static ssize_t icnss_test_mode_write(struct file *fp, const char __user *buf, +static ssize_t icnss_fw_debug_write(struct file *fp, + const char __user *user_buf, size_t count, loff_t *off) { struct icnss_priv *priv = ((struct seq_file *)fp->private_data)->private; - int ret; - u32 val; + char buf[64]; + char *sptr, *token; + unsigned int len = 0; + char *cmd; + uint64_t val; + const char *delim = " "; + int ret = 0; - ret = kstrtou32_from_user(buf, count, 0, &val); - if (ret) - return ret; + len = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, len)) + return -EINVAL; - switch (val) { - case 0: - ret = icnss_test_mode_fw_test_off(priv); - break; - case 1: - ret = icnss_test_mode_fw_test(priv, ICNSS_WALTEST); - break; - case 2: - ret = icnss_test_mode_fw_test(priv, ICNSS_CCPM); - break; - default: - ret = -EINVAL; - break; + buf[len] = '\0'; + sptr = buf; + + token = strsep(&sptr, delim); + if (!token) + return -EINVAL; + if (!sptr) + return -EINVAL; + cmd = token; + + token = strsep(&sptr, delim); + if (!token) + return -EINVAL; + if (kstrtou64(token, 0, &val)) + return -EINVAL; + + if (strcmp(cmd, "test_mode") == 0) { + switch (val) { + case 0: + ret = icnss_test_mode_fw_test_off(priv); + break; + case 1: + ret = icnss_test_mode_fw_test(priv, ICNSS_WALTEST); + break; + case 2: + ret = icnss_test_mode_fw_test(priv, ICNSS_CCPM); + break; + case 3: + ret = icnss_trigger_recovery(&priv->pdev->dev); + break; + default: + return -EINVAL; + } + } else if (strcmp(cmd, "dynamic_feature_mask") == 0) { + ret = wlfw_dynamic_feature_mask_send_sync_msg(priv, val); + } else { + return -EINVAL; } if (ret) @@ -2924,16 +3144,16 @@ static ssize_t icnss_test_mode_write(struct file *fp, const char __user *buf, return count; } -static int icnss_test_mode_open(struct inode *inode, struct file *file) +static int icnss_fw_debug_open(struct inode *inode, struct file *file) { - return single_open(file, icnss_test_mode_show, inode->i_private); + return single_open(file, icnss_fw_debug_show, inode->i_private); } -static const struct file_operations icnss_test_mode_fops = { +static const struct file_operations icnss_fw_debug_fops = { .read = seq_read, - .write = icnss_test_mode_write, + .write = icnss_fw_debug_write, .release = single_release, - .open = icnss_test_mode_open, + .open = icnss_fw_debug_open, .owner = THIS_MODULE, .llseek = seq_lseek, }; @@ -3103,6 +3323,9 @@ static int icnss_stats_show(struct seq_file *s, void *data) ICNSS_STATS_DUMP(s, priv, vbatt_req); ICNSS_STATS_DUMP(s, priv, vbatt_resp); ICNSS_STATS_DUMP(s, priv, vbatt_req_err); + ICNSS_STATS_DUMP(s, priv, rejuvenate_ack_req); + ICNSS_STATS_DUMP(s, priv, rejuvenate_ack_resp); + ICNSS_STATS_DUMP(s, priv, rejuvenate_ack_err); seq_puts(s, "\n<------------------ PM stats ------------------->\n"); ICNSS_STATS_DUMP(s, priv, pm_suspend); @@ -3358,8 +3581,8 @@ static int icnss_debugfs_create(struct icnss_priv *priv) priv->root_dentry = root_dentry; - debugfs_create_file("test_mode", 0644, root_dentry, priv, - &icnss_test_mode_fops); + debugfs_create_file("fw_debug", 0644, root_dentry, priv, + &icnss_fw_debug_fops); debugfs_create_file("stats", 0644, root_dentry, priv, &icnss_stats_fops); diff --git a/drivers/soc/qcom/wlan_firmware_service_v01.c b/drivers/soc/qcom/wlan_firmware_service_v01.c index 3e00d6c9d153..e3ebea31c019 100644 --- a/drivers/soc/qcom/wlan_firmware_service_v01.c +++ b/drivers/soc/qcom/wlan_firmware_service_v01.c @@ -1,4 +1,4 @@ - /* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + /* Copyright (c) 2015-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 @@ -130,6 +130,23 @@ static struct elem_info wlfw_shadow_reg_cfg_s_v01_ei[] = { }, }; +static struct elem_info wlfw_shadow_reg_v2_cfg_s_v01_ei[] = { + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint32_t), + .is_array = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct wlfw_shadow_reg_v2_cfg_s_v01, + addr), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .is_array = QMI_COMMON_TLV_TYPE, + }, +}; + static struct elem_info wlfw_memory_region_info_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_8_BYTE, @@ -361,6 +378,78 @@ struct elem_info wlfw_ind_register_req_msg_v01_ei[] = { client_id), }, { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x16, + .offset = offsetof(struct wlfw_ind_register_req_msg_v01, + request_mem_enable_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x16, + .offset = offsetof(struct wlfw_ind_register_req_msg_v01, + request_mem_enable), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x17, + .offset = offsetof(struct wlfw_ind_register_req_msg_v01, + fw_mem_ready_enable_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x17, + .offset = offsetof(struct wlfw_ind_register_req_msg_v01, + fw_mem_ready_enable), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x18, + .offset = offsetof(struct wlfw_ind_register_req_msg_v01, + cold_boot_cal_done_enable_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x18, + .offset = offsetof(struct wlfw_ind_register_req_msg_v01, + cold_boot_cal_done_enable), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x19, + .offset = offsetof(struct wlfw_ind_register_req_msg_v01, + rejuvenate_enable_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint32_t), + .is_array = NO_ARRAY, + .tlv_type = 0x19, + .offset = offsetof(struct wlfw_ind_register_req_msg_v01, + rejuvenate_enable), + }, + { .data_type = QMI_EOTI, .is_array = NO_ARRAY, .is_array = QMI_COMMON_TLV_TYPE, @@ -646,6 +735,34 @@ struct elem_info wlfw_wlan_cfg_req_msg_v01_ei[] = { .ei_array = wlfw_shadow_reg_cfg_s_v01_ei, }, { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x14, + .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, + shadow_reg_v2_valid), + }, + { + .data_type = QMI_DATA_LEN, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x14, + .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, + shadow_reg_v2_len), + }, + { + .data_type = QMI_STRUCT, + .elem_len = QMI_WLFW_MAX_NUM_SHADOW_REG_V2_V01, + .elem_size = sizeof(struct wlfw_shadow_reg_v2_cfg_s_v01), + .is_array = VAR_LEN_ARRAY, + .tlv_type = 0x14, + .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, + shadow_reg_v2), + .ei_array = wlfw_shadow_reg_v2_cfg_s_v01_ei, + }, + { .data_type = QMI_EOTI, .is_array = NO_ARRAY, .is_array = QMI_COMMON_TLV_TYPE, @@ -1650,3 +1767,319 @@ struct elem_info wlfw_mac_addr_resp_msg_v01_ei[] = { .is_array = QMI_COMMON_TLV_TYPE, }, }; + +struct elem_info wlfw_host_cap_req_msg_v01_ei[] = { + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + daemon_support_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + daemon_support), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .is_array = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_host_cap_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .is_array = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof(struct wlfw_host_cap_resp_msg_v01, + resp), + .ei_array = get_qmi_response_type_v01_ei(), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .is_array = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_request_mem_ind_msg_v01_ei[] = { + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint32_t), + .is_array = NO_ARRAY, + .tlv_type = 0x01, + .offset = offsetof(struct wlfw_request_mem_ind_msg_v01, + size), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .is_array = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_respond_mem_req_msg_v01_ei[] = { + { + .data_type = QMI_UNSIGNED_8_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint64_t), + .is_array = NO_ARRAY, + .tlv_type = 0x01, + .offset = offsetof(struct wlfw_respond_mem_req_msg_v01, + addr), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint32_t), + .is_array = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof(struct wlfw_respond_mem_req_msg_v01, + size), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .is_array = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_respond_mem_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .is_array = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof(struct wlfw_respond_mem_resp_msg_v01, + resp), + .ei_array = get_qmi_response_type_v01_ei(), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .is_array = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_fw_mem_ready_ind_msg_v01_ei[] = { + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .is_array = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_cold_boot_cal_done_ind_msg_v01_ei[] = { + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .is_array = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_rejuvenate_ind_msg_v01_ei[] = { + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, + cause_for_rejuvenation_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, + cause_for_rejuvenation), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x11, + .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, + requesting_sub_system_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x11, + .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, + requesting_sub_system), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x12, + .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, + line_number_valid), + }, + { + .data_type = QMI_UNSIGNED_2_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint16_t), + .is_array = NO_ARRAY, + .tlv_type = 0x12, + .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, + line_number), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x13, + .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, + function_name_valid), + }, + { + .data_type = QMI_STRING, + .elem_len = QMI_WLFW_FUNCTION_NAME_LEN_V01 + 1, + .elem_size = sizeof(char), + .is_array = NO_ARRAY, + .tlv_type = 0x13, + .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, + function_name), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .is_array = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_rejuvenate_ack_req_msg_v01_ei[] = { + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .is_array = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_rejuvenate_ack_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .is_array = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof( + struct wlfw_rejuvenate_ack_resp_msg_v01, + resp), + .ei_array = get_qmi_response_type_v01_ei(), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .is_array = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_dynamic_feature_mask_req_msg_v01_ei[] = { + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct + wlfw_dynamic_feature_mask_req_msg_v01, + mask_valid), + }, + { + .data_type = QMI_UNSIGNED_8_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint64_t), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof( + struct wlfw_dynamic_feature_mask_req_msg_v01, + mask), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .is_array = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_dynamic_feature_mask_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .is_array = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof( + struct wlfw_dynamic_feature_mask_resp_msg_v01, + resp), + .ei_array = get_qmi_response_type_v01_ei(), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof( + struct wlfw_dynamic_feature_mask_resp_msg_v01, + prev_mask_valid), + }, + { + .data_type = QMI_UNSIGNED_8_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint64_t), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof( + struct wlfw_dynamic_feature_mask_resp_msg_v01, + prev_mask), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x11, + .offset = offsetof( + struct wlfw_dynamic_feature_mask_resp_msg_v01, + curr_mask_valid), + }, + { + .data_type = QMI_UNSIGNED_8_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint64_t), + .is_array = NO_ARRAY, + .tlv_type = 0x11, + .offset = offsetof( + struct wlfw_dynamic_feature_mask_resp_msg_v01, + curr_mask), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .is_array = QMI_COMMON_TLV_TYPE, + }, +}; + diff --git a/drivers/soc/qcom/wlan_firmware_service_v01.h b/drivers/soc/qcom/wlan_firmware_service_v01.h index 47b315fce94c..751e92338a0f 100644 --- a/drivers/soc/qcom/wlan_firmware_service_v01.h +++ b/drivers/soc/qcom/wlan_firmware_service_v01.h @@ -1,4 +1,4 @@ - /* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + /* Copyright (c) 2015-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 @@ -17,7 +17,10 @@ #define WLFW_SERVICE_VERS_V01 0x01 #define QMI_WLFW_BDF_DOWNLOAD_REQ_V01 0x0025 +#define QMI_WLFW_FW_MEM_READY_IND_V01 0x0037 #define QMI_WLFW_INITIATE_CAL_UPDATE_IND_V01 0x002A +#define QMI_WLFW_HOST_CAP_REQ_V01 0x0034 +#define QMI_WLFW_DYNAMIC_FEATURE_MASK_RESP_V01 0x003B #define QMI_WLFW_CAP_REQ_V01 0x0024 #define QMI_WLFW_CAL_REPORT_REQ_V01 0x0026 #define QMI_WLFW_CAL_UPDATE_RESP_V01 0x0029 @@ -26,25 +29,34 @@ #define QMI_WLFW_CAL_REPORT_RESP_V01 0x0026 #define QMI_WLFW_MAC_ADDR_RESP_V01 0x0033 #define QMI_WLFW_INITIATE_CAL_DOWNLOAD_IND_V01 0x0028 +#define QMI_WLFW_HOST_CAP_RESP_V01 0x0034 #define QMI_WLFW_MSA_READY_IND_V01 0x002B #define QMI_WLFW_ATHDIAG_WRITE_RESP_V01 0x0031 #define QMI_WLFW_WLAN_MODE_REQ_V01 0x0022 #define QMI_WLFW_IND_REGISTER_REQ_V01 0x0020 #define QMI_WLFW_WLAN_CFG_RESP_V01 0x0023 +#define QMI_WLFW_COLD_BOOT_CAL_DONE_IND_V01 0x0038 +#define QMI_WLFW_REQUEST_MEM_IND_V01 0x0035 +#define QMI_WLFW_REJUVENATE_IND_V01 0x0039 +#define QMI_WLFW_DYNAMIC_FEATURE_MASK_REQ_V01 0x003B #define QMI_WLFW_ATHDIAG_WRITE_REQ_V01 0x0031 #define QMI_WLFW_WLAN_MODE_RESP_V01 0x0022 +#define QMI_WLFW_RESPOND_MEM_REQ_V01 0x0036 #define QMI_WLFW_PIN_CONNECT_RESULT_IND_V01 0x002C #define QMI_WLFW_FW_READY_IND_V01 0x0021 #define QMI_WLFW_MSA_READY_RESP_V01 0x002E #define QMI_WLFW_CAL_UPDATE_REQ_V01 0x0029 #define QMI_WLFW_INI_REQ_V01 0x002F #define QMI_WLFW_BDF_DOWNLOAD_RESP_V01 0x0025 +#define QMI_WLFW_REJUVENATE_ACK_RESP_V01 0x003A #define QMI_WLFW_MSA_INFO_RESP_V01 0x002D #define QMI_WLFW_MSA_READY_REQ_V01 0x002E #define QMI_WLFW_CAP_RESP_V01 0x0024 +#define QMI_WLFW_REJUVENATE_ACK_REQ_V01 0x003A #define QMI_WLFW_ATHDIAG_READ_RESP_V01 0x0030 #define QMI_WLFW_VBATT_REQ_V01 0x0032 #define QMI_WLFW_MAC_ADDR_REQ_V01 0x0033 +#define QMI_WLFW_RESPOND_MEM_RESP_V01 0x0036 #define QMI_WLFW_VBATT_RESP_V01 0x0032 #define QMI_WLFW_MSA_INFO_REQ_V01 0x002D #define QMI_WLFW_CAL_DOWNLOAD_REQ_V01 0x0027 @@ -55,12 +67,14 @@ #define QMI_WLFW_MAX_NUM_MEMORY_REGIONS_V01 2 #define QMI_WLFW_MAX_NUM_CAL_V01 5 #define QMI_WLFW_MAX_DATA_SIZE_V01 6144 +#define QMI_WLFW_FUNCTION_NAME_LEN_V01 128 #define QMI_WLFW_MAX_NUM_CE_V01 12 #define QMI_WLFW_MAX_TIMESTAMP_LEN_V01 32 +#define QMI_WLFW_MAX_BUILD_ID_LEN_V01 128 #define QMI_WLFW_MAX_STR_LEN_V01 16 #define QMI_WLFW_MAX_NUM_SHADOW_REG_V01 24 #define QMI_WLFW_MAC_ADDR_SIZE_V01 6 -#define QMI_WLFW_MAX_BUILD_ID_LEN_V01 128 +#define QMI_WLFW_MAX_NUM_SHADOW_REG_V2_V01 36 #define QMI_WLFW_MAX_NUM_SVC_V01 24 enum wlfw_driver_mode_enum_v01 { @@ -72,6 +86,7 @@ enum wlfw_driver_mode_enum_v01 { QMI_WLFW_OFF_V01 = 4, QMI_WLFW_CCPM_V01 = 5, QMI_WLFW_QVIT_V01 = 6, + QMI_WLFW_CALIBRATION_V01 = 7, WLFW_DRIVER_MODE_ENUM_MAX_VAL_V01 = INT_MAX, }; @@ -104,6 +119,9 @@ enum wlfw_pipedir_enum_v01 { #define QMI_WLFW_ALREADY_REGISTERED_V01 ((uint64_t)0x01ULL) #define QMI_WLFW_FW_READY_V01 ((uint64_t)0x02ULL) #define QMI_WLFW_MSA_READY_V01 ((uint64_t)0x04ULL) +#define QMI_WLFW_FW_MEM_READY_V01 ((uint64_t)0x08ULL) + +#define QMI_WLFW_FW_REJUVENATE_V01 ((uint64_t)0x01ULL) struct wlfw_ce_tgt_pipe_cfg_s_v01 { uint32_t pipe_num; @@ -124,6 +142,10 @@ struct wlfw_shadow_reg_cfg_s_v01 { uint16_t offset; }; +struct wlfw_shadow_reg_v2_cfg_s_v01 { + uint32_t addr; +}; + struct wlfw_memory_region_info_s_v01 { uint64_t region_addr; uint32_t size; @@ -161,8 +183,16 @@ struct wlfw_ind_register_req_msg_v01 { uint8_t pin_connect_result_enable; uint8_t client_id_valid; uint32_t client_id; -}; -#define WLFW_IND_REGISTER_REQ_MSG_V01_MAX_MSG_LEN 27 + uint8_t request_mem_enable_valid; + uint8_t request_mem_enable; + uint8_t fw_mem_ready_enable_valid; + uint8_t fw_mem_ready_enable; + uint8_t cold_boot_cal_done_enable_valid; + uint8_t cold_boot_cal_done_enable; + uint8_t rejuvenate_enable_valid; + uint32_t rejuvenate_enable; +}; +#define WLFW_IND_REGISTER_REQ_MSG_V01_MAX_MSG_LEN 46 extern struct elem_info wlfw_ind_register_req_msg_v01_ei[]; struct wlfw_ind_register_resp_msg_v01 { @@ -222,8 +252,12 @@ struct wlfw_wlan_cfg_req_msg_v01 { uint8_t shadow_reg_valid; uint32_t shadow_reg_len; struct wlfw_shadow_reg_cfg_s_v01 shadow_reg[QMI_WLFW_MAX_NUM_SHADOW_REG_V01]; + uint8_t shadow_reg_v2_valid; + uint32_t shadow_reg_v2_len; + struct wlfw_shadow_reg_v2_cfg_s_v01 + shadow_reg_v2[QMI_WLFW_MAX_NUM_SHADOW_REG_V2_V01]; }; -#define WLFW_WLAN_CFG_REQ_MSG_V01_MAX_MSG_LEN 655 +#define WLFW_WLAN_CFG_REQ_MSG_V01_MAX_MSG_LEN 803 extern struct elem_info wlfw_wlan_cfg_req_msg_v01_ei[]; struct wlfw_wlan_cfg_resp_msg_v01 { @@ -448,4 +482,90 @@ struct wlfw_mac_addr_resp_msg_v01 { #define WLFW_MAC_ADDR_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct elem_info wlfw_mac_addr_resp_msg_v01_ei[]; +struct wlfw_host_cap_req_msg_v01 { + uint8_t daemon_support_valid; + uint8_t daemon_support; +}; +#define WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN 4 +extern struct elem_info wlfw_host_cap_req_msg_v01_ei[]; + +struct wlfw_host_cap_resp_msg_v01 { + struct qmi_response_type_v01 resp; +}; +#define WLFW_HOST_CAP_RESP_MSG_V01_MAX_MSG_LEN 7 +extern struct elem_info wlfw_host_cap_resp_msg_v01_ei[]; + +struct wlfw_request_mem_ind_msg_v01 { + uint32_t size; +}; +#define WLFW_REQUEST_MEM_IND_MSG_V01_MAX_MSG_LEN 7 +extern struct elem_info wlfw_request_mem_ind_msg_v01_ei[]; + +struct wlfw_respond_mem_req_msg_v01 { + uint64_t addr; + uint32_t size; +}; +#define WLFW_RESPOND_MEM_REQ_MSG_V01_MAX_MSG_LEN 18 +extern struct elem_info wlfw_respond_mem_req_msg_v01_ei[]; + +struct wlfw_respond_mem_resp_msg_v01 { + struct qmi_response_type_v01 resp; +}; +#define WLFW_RESPOND_MEM_RESP_MSG_V01_MAX_MSG_LEN 7 +extern struct elem_info wlfw_respond_mem_resp_msg_v01_ei[]; + +struct wlfw_fw_mem_ready_ind_msg_v01 { + char placeholder; +}; +#define WLFW_FW_MEM_READY_IND_MSG_V01_MAX_MSG_LEN 0 +extern struct elem_info wlfw_fw_mem_ready_ind_msg_v01_ei[]; + +struct wlfw_cold_boot_cal_done_ind_msg_v01 { + char placeholder; +}; +#define WLFW_COLD_BOOT_CAL_DONE_IND_MSG_V01_MAX_MSG_LEN 0 +extern struct elem_info wlfw_cold_boot_cal_done_ind_msg_v01_ei[]; + +struct wlfw_rejuvenate_ind_msg_v01 { + uint8_t cause_for_rejuvenation_valid; + uint8_t cause_for_rejuvenation; + uint8_t requesting_sub_system_valid; + uint8_t requesting_sub_system; + uint8_t line_number_valid; + uint16_t line_number; + uint8_t function_name_valid; + char function_name[QMI_WLFW_FUNCTION_NAME_LEN_V01 + 1]; +}; +#define WLFW_REJUVENATE_IND_MSG_V01_MAX_MSG_LEN 144 +extern struct elem_info wlfw_rejuvenate_ind_msg_v01_ei[]; + +struct wlfw_rejuvenate_ack_req_msg_v01 { + char placeholder; +}; +#define WLFW_REJUVENATE_ACK_REQ_MSG_V01_MAX_MSG_LEN 0 +extern struct elem_info wlfw_rejuvenate_ack_req_msg_v01_ei[]; + +struct wlfw_rejuvenate_ack_resp_msg_v01 { + struct qmi_response_type_v01 resp; +}; +#define WLFW_REJUVENATE_ACK_RESP_MSG_V01_MAX_MSG_LEN 7 +extern struct elem_info wlfw_rejuvenate_ack_resp_msg_v01_ei[]; + +struct wlfw_dynamic_feature_mask_req_msg_v01 { + uint8_t mask_valid; + uint64_t mask; +}; +#define WLFW_DYNAMIC_FEATURE_MASK_REQ_MSG_V01_MAX_MSG_LEN 11 +extern struct elem_info wlfw_dynamic_feature_mask_req_msg_v01_ei[]; + +struct wlfw_dynamic_feature_mask_resp_msg_v01 { + struct qmi_response_type_v01 resp; + uint8_t prev_mask_valid; + uint64_t prev_mask; + uint8_t curr_mask_valid; + uint64_t curr_mask; +}; +#define WLFW_DYNAMIC_FEATURE_MASK_RESP_MSG_V01_MAX_MSG_LEN 29 +extern struct elem_info wlfw_dynamic_feature_mask_resp_msg_v01_ei[]; + #endif diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index f5c92d904ded..54d2d6b604c0 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -373,11 +373,11 @@ static void snoop_urb(struct usb_device *udev, if (userurb) { /* Async */ if (when == SUBMIT) - dev_info(&udev->dev, "userurb %p, ep%d %s-%s, " + dev_info(&udev->dev, "userurb %pK, ep%d %s-%s, " "length %u\n", userurb, ep, t, d, length); else - dev_info(&udev->dev, "userurb %p, ep%d %s-%s, " + dev_info(&udev->dev, "userurb %pK, ep%d %s-%s, " "actual_length %u status %d\n", userurb, ep, t, d, length, timeout_or_status); diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index a24a8ea9df7c..9a3bf5e2977f 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1693,7 +1693,7 @@ int usb_hcd_unlink_urb (struct urb *urb, int status) if (retval == 0) retval = -EINPROGRESS; else if (retval != -EIDRM && retval != -EBUSY) - dev_dbg(&udev->dev, "hcd_unlink_urb %p fail %d\n", + dev_dbg(&udev->dev, "hcd_unlink_urb %pK fail %d\n", urb, retval); usb_put_dev(udev); } @@ -1860,7 +1860,7 @@ rescan: /* kick hcd */ unlink1(hcd, urb, -ESHUTDOWN); dev_dbg (hcd->self.controller, - "shutdown urb %p ep%d%s%s\n", + "shutdown urb %pK ep%d%s%s\n", urb, usb_endpoint_num(&ep->desc), is_in ? "in" : "out", ({ char *s; diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index c601e25b609f..e43ef7d2d00e 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -335,7 +335,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) if (!urb || !urb->complete) return -EINVAL; if (urb->hcpriv) { - WARN_ONCE(1, "URB %p submitted while active\n", urb); + WARN_ONCE(1, "URB %pK submitted while active\n", urb); return -EBUSY; } diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 85410a2214da..5aae319198fa 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -357,7 +357,7 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc) for (n = 0; n < dwc->num_event_buffers; n++) { evt = dwc->ev_buffs[n]; - dev_dbg(dwc->dev, "Event buf %p dma %08llx length %d\n", + dev_dbg(dwc->dev, "Event buf %pK dma %08llx length %d\n", evt->buf, (unsigned long long) evt->dma, evt->length); diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index 9f67de3cc9e8..4b4978043d50 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -672,7 +672,7 @@ static int dwc3_ep_req_list_show(struct seq_file *s, void *unused) req = list_entry(ptr, struct dwc3_request, list); seq_printf(s, - "req:0x%p len: %d sts: %d dma:0x%pa num_sgs: %d\n", + "req:0x%pK len: %d sts: %d dma:0x%pa num_sgs: %d\n", req, req->request.length, req->request.status, &req->request.dma, req->request.num_sgs); } @@ -711,7 +711,7 @@ static int dwc3_ep_queued_req_show(struct seq_file *s, void *unused) req = list_entry(ptr, struct dwc3_request, list); seq_printf(s, - "req:0x%p len:%d sts:%d dma:%pa nsg:%d trb:0x%p\n", + "req:0x%pK len:%d sts:%d dma:%pa nsg:%d trb:0x%pK\n", req, req->request.length, req->request.status, &req->request.dma, req->request.num_sgs, req->trb); } @@ -751,7 +751,7 @@ static int dwc3_ep_trbs_show(struct seq_file *s, void *unused) dep->name, dep->flags, dep->free_slot, dep->busy_slot); for (j = 0; j < DWC3_TRB_NUM; j++) { trb = &dep->trb_pool[j]; - seq_printf(s, "trb:0x%p bph:0x%x bpl:0x%x size:0x%x ctrl: %x\n", + seq_printf(s, "trb:0x%pK bph:0x%x bpl:0x%x size:0x%x ctrl: %x\n", trb, trb->bph, trb->bpl, trb->size, trb->ctrl); } spin_unlock_irqrestore(&dwc->lock, flags); diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index db74e4f4f4d9..5c451f8a6827 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-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 @@ -723,7 +723,7 @@ static int dwc3_msm_ep_queue(struct usb_ep *ep, list_add_tail(&req_complete->list_item, &mdwc->req_complete_list); request->complete = dwc3_msm_req_complete_func; - dev_vdbg(dwc->dev, "%s: queing request %p to ep %s length %d\n", + dev_vdbg(dwc->dev, "%s: queing request %pK to ep %s length %d\n", __func__, request, ep->name, request->length); size = dwc3_msm_read_reg(mdwc->base, DWC3_GEVNTSIZ(0)); dbm_event_buffer_config(mdwc->dbm, @@ -908,7 +908,7 @@ static void gsi_ring_in_db(struct usb_ep *ep, struct usb_gsi_request *request) dev_dbg(mdwc->dev, "Failed to get GSI DBL address MSB\n"); offset = dwc3_trb_dma_offset(dep, &dep->trb_pool[num_trbs-1]); - dev_dbg(mdwc->dev, "Writing link TRB addr: %pa to %p (%x)\n", + dev_dbg(mdwc->dev, "Writing link TRB addr: %pa to %pK (%x)\n", &offset, gsi_dbl_address_lsb, dbl_lo_addr); writel_relaxed(offset, gsi_dbl_address_lsb); diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 4ee0faa87cff..2b910e09a80a 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -240,7 +240,7 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request, spin_lock_irqsave(&dwc->lock, flags); if (!dep->endpoint.desc) { dwc3_trace(trace_dwc3_ep0, - "trying to queue request %p to disabled %s", + "trying to queue request %pK to disabled %s", request, dep->name); ret = -ESHUTDOWN; goto out; @@ -253,7 +253,7 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request, } dwc3_trace(trace_dwc3_ep0, - "queueing request %p to %s length %d state '%s'", + "queueing request %pK to %s length %d state '%s'", request, dep->name, request->length, dwc3_ep0_state_string(dwc->ep0state)); diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 6852df4f7d1f..e2440b7efc58 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -291,7 +291,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, usb_gadget_unmap_request(&dwc->gadget, &req->request, req->direction); - dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n", + dev_dbg(dwc->dev, "request %pK from %s completed %d/%d ===> %d\n", req, dep->name, req->request.actual, req->request.length, status); trace_dwc3_gadget_giveback(req); @@ -760,7 +760,7 @@ static int dwc3_gadget_ep_enable(struct usb_ep *ep, int ret; if (!ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) { - pr_debug("dwc3: invalid parameters. ep=%p, desc=%p, DT=%d\n", + pr_debug("dwc3: invalid parameters. ep=%pK, desc=%pK, DT=%d\n", ep, desc, desc ? desc->bDescriptorType : 0); return -EINVAL; } @@ -855,7 +855,7 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, { struct dwc3_trb *trb; - dwc3_trace(trace_dwc3_gadget, "%s: req %p dma %08llx length %d%s%s", + dwc3_trace(trace_dwc3_gadget, "%s: req %pK dma %08llx length %d%s%s", dep->name, req, (unsigned long long) dma, length, last ? " last" : "", chain ? " chain" : ""); @@ -1200,7 +1200,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) if (req->request.status == -EINPROGRESS) { ret = -EBUSY; - dev_err(dwc->dev, "%s: %p request already in queue", + dev_err(dwc->dev, "%s: %pK request already in queue", dep->name, req); return ret; } @@ -1344,13 +1344,13 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request, spin_lock_irqsave(&dwc->lock, flags); if (!dep->endpoint.desc) { - dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n", + dev_dbg(dwc->dev, "trying to queue request %pK to disabled %s\n", request, ep->name); ret = -ESHUTDOWN; goto out; } - if (WARN(req->dep != dep, "request %p belongs to '%s'\n", + if (WARN(req->dep != dep, "request %pK belongs to '%s'\n", request, req->dep->name)) { ret = -EINVAL; goto out; @@ -1421,7 +1421,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, dwc3_stop_active_transfer(dwc, dep->number, true); goto out1; } - dev_err(dwc->dev, "request %p was not queued to %s\n", + dev_err(dwc->dev, "request %pK was not queued to %s\n", request, ep->name); ret = -EINVAL; goto out0; @@ -2334,7 +2334,7 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep, * would help. Lets hope that if this occurs, someone * fixes the root cause instead of looking away :) */ - dev_err(dwc->dev, "%s's TRB (%p) still owned by HW\n", + dev_err(dwc->dev, "%s's TRB (%pK) still owned by HW\n", dep->name, trb); count = trb->size & DWC3_TRB_SIZE_MASK; diff --git a/drivers/usb/dwc3/io.h b/drivers/usb/dwc3/io.h index 6a79c8e66bbc..d797eb8728de 100644 --- a/drivers/usb/dwc3/io.h +++ b/drivers/usb/dwc3/io.h @@ -41,7 +41,7 @@ static inline u32 dwc3_readl(void __iomem *base, u32 offset) * documentation, so we revert it back to the proper addresses, the * same way they are described on SNPS documentation */ - dwc3_trace(trace_dwc3_readl, "addr %p value %08x", + dwc3_trace(trace_dwc3_readl, "addr %pK value %08x", base - DWC3_GLOBALS_REGS_START + offset, value); return value; @@ -63,7 +63,7 @@ static inline void dwc3_writel(void __iomem *base, u32 offset, u32 value) * documentation, so we revert it back to the proper addresses, the * same way they are described on SNPS documentation */ - dwc3_trace(trace_dwc3_writel, "addr %p value %08x", + dwc3_trace(trace_dwc3_writel, "addr %pK value %08x", base - DWC3_GLOBALS_REGS_START + offset, value); } diff --git a/drivers/usb/dwc3/trace.h b/drivers/usb/dwc3/trace.h index 9c10669ab91f..225b2d4f9ecd 100644 --- a/drivers/usb/dwc3/trace.h +++ b/drivers/usb/dwc3/trace.h @@ -125,7 +125,7 @@ DECLARE_EVENT_CLASS(dwc3_log_request, __entry->length = req->request.length; __entry->status = req->request.status; ), - TP_printk("%s: req %p length %u/%u ==> %d", + TP_printk("%s: req %pK length %u/%u ==> %d", __get_str(name), __entry->req, __entry->actual, __entry->length, __entry->status ) @@ -228,7 +228,7 @@ DECLARE_EVENT_CLASS(dwc3_log_trb, __entry->size = trb->size; __entry->ctrl = trb->ctrl; ), - TP_printk("%s: trb %p bph %08x bpl %08x size %08x ctrl %08x", + TP_printk("%s: trb %pK bph %08x bpl %08x size %08x ctrl %08x", __get_str(name), __entry->trb, __entry->bph, __entry->bpl, __entry->size, __entry->ctrl ) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 04985ccbbe6d..a53b23789d7a 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -216,7 +216,7 @@ int usb_add_function(struct usb_configuration *config, { int value = -EINVAL; - DBG(config->cdev, "adding '%s'/%p to config '%s'/%p\n", + DBG(config->cdev, "adding '%s'/%pK to config '%s'/%pK\n", function->name, function, config->label, config); @@ -257,7 +257,7 @@ int usb_add_function(struct usb_configuration *config, done: if (value) - DBG(config->cdev, "adding '%s'/%p --> %d\n", + DBG(config->cdev, "adding '%s'/%pK --> %d\n", function->name, function, value); return value; } @@ -854,7 +854,7 @@ static int set_config(struct usb_composite_dev *cdev, result = f->set_alt(f, tmp, 0); if (result < 0) { - DBG(cdev, "interface %d (%s/%p) alt 0 --> %d\n", + DBG(cdev, "interface %d (%s/%pK) alt 0 --> %d\n", tmp, f->name, f, result); reset_config(cdev); @@ -927,7 +927,7 @@ int usb_add_config(struct usb_composite_dev *cdev, if (!bind) goto done; - DBG(cdev, "adding config #%u '%s'/%p\n", + DBG(cdev, "adding config #%u '%s'/%pK\n", config->bConfigurationValue, config->label, config); @@ -944,7 +944,7 @@ int usb_add_config(struct usb_composite_dev *cdev, struct usb_function, list); list_del(&f->list); if (f->unbind) { - DBG(cdev, "unbind function '%s'/%p\n", + DBG(cdev, "unbind function '%s'/%pK\n", f->name, f); f->unbind(config, f); /* may free memory for "f" */ @@ -955,7 +955,7 @@ int usb_add_config(struct usb_composite_dev *cdev, } else { unsigned i; - DBG(cdev, "cfg %d/%p speeds:%s%s%s\n", + DBG(cdev, "cfg %d/%pK speeds:%s%s%s\n", config->bConfigurationValue, config, config->superspeed ? " super" : "", config->highspeed ? " high" : "", @@ -970,7 +970,7 @@ int usb_add_config(struct usb_composite_dev *cdev, if (!f) continue; - DBG(cdev, " interface %d = %s/%p\n", + DBG(cdev, " interface %d = %s/%pK\n", i, f->name, f); } } @@ -996,14 +996,14 @@ static void remove_config(struct usb_composite_dev *cdev, struct usb_function, list); list_del(&f->list); if (f->unbind) { - DBG(cdev, "unbind function '%s'/%p\n", f->name, f); + DBG(cdev, "unbind function '%s'/%pK\n", f->name, f); f->unbind(config, f); /* may free memory for "f" */ } } list_del(&config->list); if (config->unbind) { - DBG(cdev, "unbind config '%s'/%p\n", config->label, config); + DBG(cdev, "unbind config '%s'/%pK\n", config->label, config); config->unbind(config); /* may free memory for "c" */ } @@ -1411,7 +1411,7 @@ static void composite_setup_complete(struct usb_ep *ep, struct usb_request *req) else if (cdev->os_desc_req == req) cdev->os_desc_pending = false; else - WARN(1, "unknown request %p\n", req); + WARN(1, "unknown request %pK\n", req); } static int composite_ep0_queue(struct usb_composite_dev *cdev, @@ -1426,7 +1426,7 @@ static int composite_ep0_queue(struct usb_composite_dev *cdev, else if (cdev->os_desc_req == req) cdev->os_desc_pending = true; else - WARN(1, "unknown request %p\n", req); + WARN(1, "unknown request %pK\n", req); } return ret; diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index be29dc4bef89..4964bb1a24b1 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -1257,7 +1257,7 @@ static void purge_configs_funcs(struct gadget_info *gi) list_move_tail(&f->list, &cfg->func_list); if (f->unbind) { dev_err(&gi->cdev.gadget->dev, "unbind function" - " '%s'/%p\n", f->name, f); + " '%s'/%pK\n", f->name, f); f->unbind(c, f); } } @@ -1458,7 +1458,7 @@ static void android_work(struct work_struct *data) } if (!uevent_sent) { - pr_info("%s: did not send uevent (%d %d %p)\n", __func__, + pr_info("%s: did not send uevent (%d %d %pK)\n", __func__, gi->connected, gi->sw_connected, cdev->config); } } diff --git a/drivers/usb/gadget/function/f_accessory.c b/drivers/usb/gadget/function/f_accessory.c index 013a9d6702db..61057befc136 100644 --- a/drivers/usb/gadget/function/f_accessory.c +++ b/drivers/usb/gadget/function/f_accessory.c @@ -555,7 +555,7 @@ static int create_bulk_endpoints(struct acc_dev *dev, struct usb_ep *ep; int i; - DBG(cdev, "create_bulk_endpoints dev: %p\n", dev); + DBG(cdev, "create_bulk_endpoints dev: %pK\n", dev); ep = usb_ep_autoconfig(cdev->gadget, in_desc); if (!ep) { @@ -646,7 +646,7 @@ requeue_req: r = -EIO; goto done; } else { - pr_debug("rx %p queue\n", req); + pr_debug("rx %pK queue\n", req); } /* wait for a request to complete */ @@ -669,7 +669,7 @@ copy_data: if (req->actual == 0) goto requeue_req; - pr_debug("rx %p %u\n", req, req->actual); + pr_debug("rx %pK %u\n", req, req->actual); xfer = (req->actual < count) ? req->actual : count; r = xfer; if (copy_to_user(buf, req->buf, xfer)) @@ -969,7 +969,7 @@ __acc_function_bind(struct usb_configuration *c, int id; int ret; - DBG(cdev, "acc_function_bind dev: %p\n", dev); + DBG(cdev, "acc_function_bind dev: %pK\n", dev); if (configfs) { if (acc_string_defs[INTERFACE_STRING_INDEX].id == 0) { @@ -1151,7 +1151,7 @@ static void acc_hid_work(struct work_struct *data) list_for_each_safe(entry, temp, &new_list) { hid = list_entry(entry, struct acc_hid_dev, list); if (acc_hid_init(hid)) { - pr_err("can't add HID device %p\n", hid); + pr_err("can't add HID device %pK\n", hid); acc_hid_delete(hid); } else { spin_lock_irqsave(&dev->lock, flags); diff --git a/drivers/usb/gadget/function/f_acm.c b/drivers/usb/gadget/function/f_acm.c index 2fa1e80a3ce7..651e4afe0520 100644 --- a/drivers/usb/gadget/function/f_acm.c +++ b/drivers/usb/gadget/function/f_acm.c @@ -702,7 +702,7 @@ fail: if (acm->notify_req) gs_free_req(acm->notify, acm->notify_req); - ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status); + ERROR(cdev, "%s/%pK: can't bind, err %d\n", f->name, f, status); return status; } diff --git a/drivers/usb/gadget/function/f_cdev.c b/drivers/usb/gadget/function/f_cdev.c index 3b7b23cfde44..d45f4be4a075 100644 --- a/drivers/usb/gadget/function/f_cdev.c +++ b/drivers/usb/gadget/function/f_cdev.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2013-2017, The Linux Foundation. All rights reserved. * Linux Foundation chooses to take subject only to the GPLv2 license terms, * and distributes only under these terms. * @@ -846,7 +846,7 @@ static int usb_cser_alloc_requests(struct usb_ep *ep, struct list_head *head, int i; struct usb_request *req; - pr_debug("ep:%p head:%p num:%d size:%d cb:%p", + pr_debug("ep:%pK head:%pK num:%d size:%d cb:%pK", ep, head, num, size, cb); for (i = 0; i < num; i++) { @@ -896,7 +896,7 @@ static void usb_cser_start_rx(struct f_cdev *port) ret = usb_ep_queue(ep, req, GFP_KERNEL); spin_lock_irqsave(&port->port_lock, flags); if (ret) { - pr_err("port(%d):%p usb ep(%s) queue failed\n", + pr_err("port(%d):%pK usb ep(%s) queue failed\n", port->port_num, port, ep->name); list_add(&req->list, pool); break; @@ -911,7 +911,7 @@ static void usb_cser_read_complete(struct usb_ep *ep, struct usb_request *req) struct f_cdev *port = ep->driver_data; unsigned long flags; - pr_debug("ep:(%p)(%s) port:%p req_status:%d req->actual:%u\n", + pr_debug("ep:(%pK)(%s) port:%pK req_status:%d req->actual:%u\n", ep, ep->name, port, req->status, req->actual); if (!port) { pr_err("port is null\n"); @@ -938,7 +938,7 @@ static void usb_cser_write_complete(struct usb_ep *ep, struct usb_request *req) unsigned long flags; struct f_cdev *port = ep->driver_data; - pr_debug("ep:(%p)(%s) port:%p req_stats:%d\n", + pr_debug("ep:(%pK)(%s) port:%pK req_stats:%d\n", ep, ep->name, port, req->status); if (!port) { @@ -973,7 +973,7 @@ static void usb_cser_start_io(struct f_cdev *port) int ret = -ENODEV; unsigned long flags; - pr_debug("port: %p\n", port); + pr_debug("port: %pK\n", port); spin_lock_irqsave(&port->port_lock, flags); if (!port->is_connected) @@ -1016,7 +1016,7 @@ static void usb_cser_stop_io(struct f_cdev *port) struct usb_ep *out; unsigned long flags; - pr_debug("port:%p\n", port); + pr_debug("port:%pK\n", port); in = port->port_usb.in; out = port->port_usb.out; @@ -1059,7 +1059,7 @@ int f_cdev_open(struct inode *inode, struct file *file) } file->private_data = port; - pr_debug("opening port(%s)(%p)\n", port->name, port); + pr_debug("opening port(%s)(%pK)\n", port->name, port); ret = wait_event_interruptible(port->open_wq, port->is_connected); if (ret) { @@ -1072,7 +1072,7 @@ int f_cdev_open(struct inode *inode, struct file *file) spin_unlock_irqrestore(&port->port_lock, flags); usb_cser_start_rx(port); - pr_debug("port(%s)(%p) open is success\n", port->name, port); + pr_debug("port(%s)(%pK) open is success\n", port->name, port); return 0; } @@ -1092,7 +1092,7 @@ int f_cdev_release(struct inode *inode, struct file *file) port->port_open = false; port->cbits_updated = false; spin_unlock_irqrestore(&port->port_lock, flags); - pr_debug("port(%s)(%p) is closed.\n", port->name, port); + pr_debug("port(%s)(%pK) is closed.\n", port->name, port); return 0; } @@ -1116,7 +1116,7 @@ ssize_t f_cdev_read(struct file *file, return -EINVAL; } - pr_debug("read on port(%s)(%p) count:%zu\n", port->name, port, count); + pr_debug("read on port(%s)(%pK) count:%zu\n", port->name, port, count); spin_lock_irqsave(&port->port_lock, flags); current_rx_req = port->current_rx_req; pending_rx_bytes = port->pending_rx_bytes; @@ -1217,7 +1217,7 @@ ssize_t f_cdev_write(struct file *file, } spin_lock_irqsave(&port->port_lock, flags); - pr_debug("write on port(%s)(%p)\n", port->name, port); + pr_debug("write on port(%s)(%pK)\n", port->name, port); if (!port->is_connected) { spin_unlock_irqrestore(&port->port_lock, flags); @@ -1386,7 +1386,7 @@ static long f_cdev_ioctl(struct file *fp, unsigned cmd, case TIOCMBIC: case TIOCMBIS: case TIOCMSET: - pr_debug("TIOCMSET on port(%s)%p\n", port->name, port); + pr_debug("TIOCMSET on port(%s)%pK\n", port->name, port); i = get_user(val, (uint32_t *)arg); if (i) { pr_err("Error getting TIOCMSET value\n"); @@ -1395,7 +1395,7 @@ static long f_cdev_ioctl(struct file *fp, unsigned cmd, ret = f_cdev_tiocmset(port, val, ~val); break; case TIOCMGET: - pr_debug("TIOCMGET on port(%s)%p\n", port->name, port); + pr_debug("TIOCMGET on port(%s)%pK\n", port->name, port); ret = f_cdev_tiocmget(port); if (ret >= 0) { ret = put_user(ret, (uint32_t *)arg); @@ -1445,14 +1445,14 @@ int usb_cser_connect(struct f_cdev *port) return -ENODEV; } - pr_debug("port(%s) (%p)\n", port->name, port); + pr_debug("port(%s) (%pK)\n", port->name, port); cser = &port->port_usb; cser->notify_modem = usb_cser_notify_modem; ret = usb_ep_enable(cser->in); if (ret) { - pr_err("usb_ep_enable failed eptype:IN ep:%p, err:%d", + pr_err("usb_ep_enable failed eptype:IN ep:%pK, err:%d", cser->in, ret); return ret; } @@ -1460,7 +1460,7 @@ int usb_cser_connect(struct f_cdev *port) ret = usb_ep_enable(cser->out); if (ret) { - pr_err("usb_ep_enable failed eptype:OUT ep:%p, err: %d", + pr_err("usb_ep_enable failed eptype:OUT ep:%pK, err: %d", cser->out, ret); cser->in->driver_data = 0; return ret; @@ -1572,7 +1572,7 @@ static struct f_cdev *f_cdev_alloc(char *func_name, int portno) goto err_create_dev; } - pr_info("port_name:%s (%p) portno:(%d)\n", + pr_info("port_name:%s (%pK) portno:(%d)\n", port->name, port, port->port_num); return port; diff --git a/drivers/usb/gadget/function/f_diag.c b/drivers/usb/gadget/function/f_diag.c index aea1e1d0fa11..fe428e8bb781 100644 --- a/drivers/usb/gadget/function/f_diag.c +++ b/drivers/usb/gadget/function/f_diag.c @@ -2,7 +2,7 @@ * Diag Function Device - Route ARM9 and ARM11 DIAG messages * between HOST and DEVICE. * Copyright (C) 2007 Google, Inc. - * Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2008-2017, The Linux Foundation. All rights reserved. * Author: Brian Swetland <swetland@google.com> * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -244,7 +244,7 @@ static void diag_update_pid_and_serial_num(struct diag_context *ctxt) } update_dload: - pr_debug("%s: dload:%p pid:%x serial_num:%s\n", + pr_debug("%s: dload:%pK pid:%x serial_num:%s\n", __func__, diag_dload, local_diag_dload.pid, local_diag_dload.serial_number); diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 052b6dbc4471..739cf9790cd4 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -699,7 +699,7 @@ static void ffs_epfile_io_complete(struct usb_ep *_ep, struct usb_request *req) ep->status = req->status ? req->status : req->actual; /* Set is_busy false to indicate completion of last request */ ep->is_busy = false; - ffs_log("ep status %d for req %p", ep->status, req); + ffs_log("ep status %d for req %pK", ep->status, req); complete(req->context); } } @@ -1720,12 +1720,12 @@ static void ffs_data_clear(struct ffs_data *ffs) ffs_log("enter: state %d setup_state %d flag %lu", ffs->state, ffs->setup_state, ffs->flags); - pr_debug("%s: ffs->gadget= %p, ffs->flags= %lu\n", + pr_debug("%s: ffs->gadget= %pK, ffs->flags= %lu\n", __func__, ffs->gadget, ffs->flags); ffs_closed(ffs); if (ffs->gadget) - pr_err("%s: ffs:%p ffs->gadget= %p, ffs->flags= %lu\n", + pr_err("%s: ffs:%pK ffs->gadget= %pK, ffs->flags= %lu\n", __func__, ffs, ffs->gadget, ffs->flags); BUG_ON(ffs->gadget); @@ -1814,7 +1814,7 @@ static int functionfs_bind(struct ffs_data *ffs, struct usb_composite_dev *cdev) ffs->gadget = cdev->gadget; - ffs_log("exit: state %d setup_state %d flag %lu gadget %p\n", + ffs_log("exit: state %d setup_state %d flag %lu gadget %pK\n", ffs->state, ffs->setup_state, ffs->flags, ffs->gadget); ffs_data_get(ffs); @@ -1830,7 +1830,7 @@ static void functionfs_unbind(struct ffs_data *ffs) ffs->ep0req = NULL; ffs->gadget = NULL; clear_bit(FFS_FL_BOUND, &ffs->flags); - ffs_log("state %d setup_state %d flag %lu gadget %p\n", + ffs_log("state %d setup_state %d flag %lu gadget %pK\n", ffs->state, ffs->setup_state, ffs->flags, ffs->gadget); ffs_data_put(ffs); } diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c index b3d223a76f07..8c80a8d80ac9 100644 --- a/drivers/usb/gadget/function/f_gsi.c +++ b/drivers/usb/gadget/function/f_gsi.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, 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 @@ -34,14 +34,19 @@ module_param(num_out_bufs, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(num_out_bufs, "Number of OUT buffers"); +static bool qti_packet_debug; +module_param(qti_packet_debug, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(qti_packet_debug, "Print QTI Packet's Raw Data"); + static struct workqueue_struct *ipa_usb_wq; static void gsi_rndis_ipa_reset_trigger(struct f_gsi *rndis); static void ipa_disconnect_handler(struct gsi_data_port *d_port); -static int gsi_ctrl_send_notification(struct f_gsi *gsi, - enum gsi_ctrl_notify_state); +static int gsi_ctrl_send_notification(struct f_gsi *gsi); static int gsi_alloc_trb_buffer(struct f_gsi *gsi); static void gsi_free_trb_buffer(struct f_gsi *gsi); +static struct gsi_ctrl_pkt *gsi_ctrl_pkt_alloc(unsigned len, gfp_t flags); +static void gsi_ctrl_pkt_free(struct gsi_ctrl_pkt *pkt); void post_event(struct gsi_data_port *port, u8 event) { @@ -173,6 +178,7 @@ int ipa_usb_notify_cb(enum ipa_usb_notify_event event, { struct f_gsi *gsi = driver_data; unsigned long flags; + struct gsi_ctrl_pkt *cpkt_notify_connect, *cpkt_notify_speed; if (!gsi) { log_event_err("%s: invalid driver data", __func__); @@ -185,17 +191,43 @@ int ipa_usb_notify_cb(enum ipa_usb_notify_event event, case IPA_USB_DEVICE_READY: if (gsi->d_port.net_ready_trigger) { - log_event_err("%s: Already triggered", __func__); spin_unlock_irqrestore(&gsi->d_port.lock, flags); + log_event_dbg("%s: Already triggered", __func__); return 1; } log_event_err("%s: Set net_ready_trigger", __func__); gsi->d_port.net_ready_trigger = true; - if (gsi->prot_id == IPA_USB_ECM) - gsi_ctrl_send_notification(gsi, - GSI_CTRL_NOTIFY_CONNECT); + if (gsi->prot_id == IPA_USB_ECM) { + cpkt_notify_connect = gsi_ctrl_pkt_alloc(0, GFP_ATOMIC); + if (IS_ERR(cpkt_notify_connect)) { + spin_unlock_irqrestore(&gsi->d_port.lock, + flags); + log_event_dbg("%s: err cpkt_notify_connect\n", + __func__); + return -ENOMEM; + } + cpkt_notify_connect->type = GSI_CTRL_NOTIFY_CONNECT; + + cpkt_notify_speed = gsi_ctrl_pkt_alloc(0, GFP_ATOMIC); + if (IS_ERR(cpkt_notify_speed)) { + spin_unlock_irqrestore(&gsi->d_port.lock, + flags); + gsi_ctrl_pkt_free(cpkt_notify_connect); + log_event_dbg("%s: err cpkt_notify_speed\n", + __func__); + return -ENOMEM; + } + cpkt_notify_speed->type = GSI_CTRL_NOTIFY_SPEED; + spin_lock_irqsave(&gsi->c_port.lock, flags); + list_add_tail(&cpkt_notify_connect->list, + &gsi->c_port.cpkt_resp_q); + list_add_tail(&cpkt_notify_speed->list, + &gsi->c_port.cpkt_resp_q); + spin_unlock_irqrestore(&gsi->c_port.lock, flags); + gsi_ctrl_send_notification(gsi); + } /* Do not post EVT_CONNECTED for RNDIS. Data path for RNDIS is enabled on EVT_HOST_READY. @@ -883,7 +915,7 @@ static int gsi_ctrl_dev_open(struct inode *ip, struct file *fp) ctrl_device); if (!c_port) { - log_event_err("%s: gsi ctrl port %p", __func__, c_port); + log_event_err("%s: gsi ctrl port %pK", __func__, c_port); return -ENODEV; } @@ -906,7 +938,7 @@ static int gsi_ctrl_dev_release(struct inode *ip, struct file *fp) ctrl_device); if (!c_port) { - log_event_err("%s: gsi ctrl port %p", __func__, c_port); + log_event_err("%s: gsi ctrl port %pK", __func__, c_port); return -ENODEV; } @@ -931,7 +963,7 @@ gsi_ctrl_dev_read(struct file *fp, char __user *buf, size_t count, loff_t *pos) log_event_dbg("%s: Enter %zu", __func__, count); if (!c_port) { - log_event_err("%s: gsi ctrl port %p", __func__, c_port); + log_event_err("%s: gsi ctrl port %pK", __func__, c_port); return -ENODEV; } @@ -969,6 +1001,9 @@ gsi_ctrl_dev_read(struct file *fp, char __user *buf, size_t count, loff_t *pos) } log_event_dbg("%s: cpkt size:%d", __func__, cpkt->len); + if (qti_packet_debug) + print_hex_dump(KERN_DEBUG, "READ:", DUMP_PREFIX_OFFSET, 16, 1, + buf, min_t(int, 30, cpkt->len), false); ret = copy_to_user(buf, cpkt->buf, cpkt->len); if (ret) { @@ -1003,7 +1038,7 @@ static ssize_t gsi_ctrl_dev_write(struct file *fp, const char __user *buf, log_event_dbg("Enter %zu", count); if (!c_port || !req || !req->buf) { - log_event_err("%s: c_port %p req %p req->buf %p", + log_event_err("%s: c_port %pK req %pK req->buf %pK", __func__, c_port, req, req ? req->buf : req); return -ENODEV; } @@ -1037,14 +1072,17 @@ static ssize_t gsi_ctrl_dev_write(struct file *fp, const char __user *buf, gsi_ctrl_pkt_free(cpkt); return ret; } + cpkt->type = GSI_CTRL_NOTIFY_RESPONSE_AVAILABLE; c_port->copied_from_modem++; + if (qti_packet_debug) + print_hex_dump(KERN_DEBUG, "WRITE:", DUMP_PREFIX_OFFSET, 16, 1, + buf, min_t(int, 30, count), false); spin_lock_irqsave(&c_port->lock, flags); list_add_tail(&cpkt->list, &c_port->cpkt_resp_q); spin_unlock_irqrestore(&c_port->lock, flags); - ret = gsi_ctrl_send_notification(gsi, - GSI_CTRL_NOTIFY_RESPONSE_AVAILABLE); + ret = gsi_ctrl_send_notification(gsi); c_port->modem_to_host++; log_event_dbg("Exit %zu", count); @@ -1059,11 +1097,13 @@ static long gsi_ctrl_dev_ioctl(struct file *fp, unsigned cmd, struct gsi_ctrl_port, ctrl_device); struct f_gsi *gsi = c_port_to_gsi(c_port); + struct gsi_ctrl_pkt *cpkt; struct ep_info info; int val, ret = 0; + unsigned long flags; if (!c_port) { - log_event_err("%s: gsi ctrl port %p", __func__, c_port); + log_event_err("%s: gsi ctrl port %pK", __func__, c_port); return -ENODEV; } @@ -1074,8 +1114,17 @@ static long gsi_ctrl_dev_ioctl(struct file *fp, unsigned cmd, goto exit_ioctl; } atomic_set(&c_port->ctrl_online, 0); - gsi_ctrl_send_notification(gsi, GSI_CTRL_NOTIFY_OFFLINE); gsi_ctrl_clear_cpkt_queues(gsi, true); + cpkt = gsi_ctrl_pkt_alloc(0, GFP_KERNEL); + if (IS_ERR(cpkt)) { + log_event_err("%s: err allocating cpkt\n", __func__); + return -ENOMEM; + } + cpkt->type = GSI_CTRL_NOTIFY_OFFLINE; + spin_lock_irqsave(&c_port->lock, flags); + list_add_tail(&cpkt->list, &c_port->cpkt_resp_q); + spin_unlock_irqrestore(&c_port->lock, flags); + gsi_ctrl_send_notification(gsi); break; case QTI_CTRL_MODEM_ONLINE: if (gsi->prot_id == IPA_USB_DIAG) { @@ -1180,7 +1229,7 @@ static unsigned int gsi_ctrl_dev_poll(struct file *fp, poll_table *wait) unsigned int mask = 0; if (!c_port) { - log_event_err("%s: gsi ctrl port %p", __func__, c_port); + log_event_err("%s: gsi ctrl port %pK", __func__, c_port); return -ENODEV; } @@ -1297,7 +1346,7 @@ static void gsi_rndis_ipa_reset_trigger(struct f_gsi *rndis) unsigned long flags; if (!rndis) { - log_event_err("%s: gsi prot ctx is %p", __func__, rndis); + log_event_err("%s: gsi prot ctx is %pK", __func__, rndis); return; } @@ -1318,7 +1367,7 @@ void gsi_rndis_flow_ctrl_enable(bool enable, struct rndis_params *param) struct gsi_data_port *d_port; if (!rndis) { - log_event_err("%s: gsi prot ctx is %p", __func__, rndis); + log_event_err("%s: gsi prot ctx is %pK", __func__, rndis); return; } @@ -1346,13 +1395,13 @@ static int queue_notification_request(struct f_gsi *gsi) gsi->c_port.notify_req, GFP_ATOMIC); if (ret == -ENOTSUPP || (ret < 0 && ret != -EAGAIN)) { spin_lock_irqsave(&gsi->c_port.lock, flags); + gsi->c_port.notify_req_queued = false; /* check if device disconnected while we dropped lock */ if (atomic_read(&gsi->connected) && !list_empty(&gsi->c_port.cpkt_resp_q)) { cpkt = list_first_entry(&gsi->c_port.cpkt_resp_q, struct gsi_ctrl_pkt, list); list_del(&cpkt->list); - atomic_dec(&gsi->c_port.notify_count); log_event_err("%s: drop ctrl pkt of len %d error %d", __func__, cpkt->len, ret); gsi_ctrl_pkt_free(cpkt); @@ -1368,36 +1417,53 @@ static int queue_notification_request(struct f_gsi *gsi) return ret; } -static int gsi_ctrl_send_notification(struct f_gsi *gsi, - enum gsi_ctrl_notify_state state) + +static int gsi_ctrl_send_notification(struct f_gsi *gsi) { __le32 *data; struct usb_cdc_notification *event; struct usb_request *req = gsi->c_port.notify_req; struct usb_composite_dev *cdev = gsi->function.config->cdev; + struct gsi_ctrl_pkt *cpkt; + unsigned long flags; + bool del_free_cpkt = false; if (!atomic_read(&gsi->connected)) { log_event_dbg("%s: cable disconnect", __func__); return -ENODEV; } - event = req->buf; + spin_lock_irqsave(&gsi->c_port.lock, flags); + if (list_empty(&gsi->c_port.cpkt_resp_q)) { + spin_unlock_irqrestore(&gsi->c_port.lock, flags); + log_event_dbg("%s: cpkt_resp_q is empty\n", __func__); + return 0; + } - switch (state) { - case GSI_CTRL_NOTIFY_NONE: - if (atomic_read(&gsi->c_port.notify_count) > 0) - log_event_dbg("GSI_CTRL_NOTIFY_NONE %d", - atomic_read(&gsi->c_port.notify_count)); - else - log_event_dbg("No pending notifications"); + log_event_dbg("%s: notify_req_queued:%d\n", + __func__, gsi->c_port.notify_req_queued); + + if (gsi->c_port.notify_req_queued) { + spin_unlock_irqrestore(&gsi->c_port.lock, flags); + log_event_dbg("%s: notify_req is already queued.\n", __func__); return 0; + } + + cpkt = list_first_entry(&gsi->c_port.cpkt_resp_q, + struct gsi_ctrl_pkt, list); + log_event_dbg("%s: cpkt->type:%d\n", __func__, cpkt->type); + + event = req->buf; + + switch (cpkt->type) { case GSI_CTRL_NOTIFY_CONNECT: + del_free_cpkt = true; event->bNotificationType = USB_CDC_NOTIFY_NETWORK_CONNECTION; event->wValue = cpu_to_le16(1); event->wLength = cpu_to_le16(0); - gsi->c_port.notify_state = GSI_CTRL_NOTIFY_SPEED; break; case GSI_CTRL_NOTIFY_SPEED: + del_free_cpkt = true; event->bNotificationType = USB_CDC_NOTIFY_SPEED_CHANGE; event->wValue = cpu_to_le16(0); event->wLength = cpu_to_le16(8); @@ -1409,39 +1475,57 @@ static int gsi_ctrl_send_notification(struct f_gsi *gsi, log_event_dbg("notify speed %d", gsi_xfer_bitrate(cdev->gadget)); - gsi->c_port.notify_state = GSI_CTRL_NOTIFY_NONE; break; case GSI_CTRL_NOTIFY_OFFLINE: + del_free_cpkt = true; event->bNotificationType = USB_CDC_NOTIFY_NETWORK_CONNECTION; event->wValue = cpu_to_le16(0); event->wLength = cpu_to_le16(0); - gsi->c_port.notify_state = GSI_CTRL_NOTIFY_NONE; break; case GSI_CTRL_NOTIFY_RESPONSE_AVAILABLE: event->bNotificationType = USB_CDC_NOTIFY_RESPONSE_AVAILABLE; event->wValue = cpu_to_le16(0); event->wLength = cpu_to_le16(0); - gsi->c_port.notify_state = GSI_CTRL_NOTIFY_RESPONSE_AVAILABLE; if (gsi->prot_id == IPA_USB_RNDIS) { data = req->buf; data[0] = cpu_to_le32(1); data[1] = cpu_to_le32(0); + /* + * we need to free dummy packet for RNDIS as sending + * notification about response available multiple time, + * RNDIS host driver doesn't like. All SEND/GET + * ENCAPSULATED response is one-to-one for RNDIS case + * and host expects to have below sequence: + * ep0: USB_CDC_SEND_ENCAPSULATED_COMMAND + * int_ep: device->host: RESPONSE_AVAILABLE + * ep0: USB_GET_SEND_ENCAPSULATED_COMMAND + * For RMNET case: host ignores multiple notification. + */ + del_free_cpkt = true; } break; default: + spin_unlock_irqrestore(&gsi->c_port.lock, flags); log_event_err("%s:unknown notify state", __func__); + WARN_ON(1); return -EINVAL; } - log_event_dbg("send Notify type %02x", event->bNotificationType); - - if (atomic_inc_return(&gsi->c_port.notify_count) != 1) { - log_event_dbg("delay ep_queue: notify req is busy %d", - atomic_read(&gsi->c_port.notify_count)); - return 0; + /* + * Delete and free cpkt related to non NOTIFY_RESPONSE_AVAILABLE + * notification whereas NOTIFY_RESPONSE_AVAILABLE related cpkt is + * deleted from USB_CDC_GET_ENCAPSULATED_RESPONSE setup request + */ + if (del_free_cpkt) { + list_del(&cpkt->list); + gsi_ctrl_pkt_free(cpkt); } + gsi->c_port.notify_req_queued = true; + spin_unlock_irqrestore(&gsi->c_port.lock, flags); + log_event_dbg("send Notify type %02x", event->bNotificationType); + return queue_notification_request(gsi); } @@ -1451,13 +1535,16 @@ static void gsi_ctrl_notify_resp_complete(struct usb_ep *ep, struct f_gsi *gsi = req->context; struct usb_cdc_notification *event = req->buf; int status = req->status; + unsigned long flags; + + spin_lock_irqsave(&gsi->c_port.lock, flags); + gsi->c_port.notify_req_queued = false; + spin_unlock_irqrestore(&gsi->c_port.lock, flags); switch (status) { case -ECONNRESET: case -ESHUTDOWN: /* connection gone */ - gsi->c_port.notify_state = GSI_CTRL_NOTIFY_NONE; - atomic_set(&gsi->c_port.notify_count, 0); log_event_dbg("ESHUTDOWN/ECONNRESET, connection gone"); gsi_ctrl_clear_cpkt_queues(gsi, false); gsi_ctrl_send_cpkt_tomodem(gsi, NULL, 0); @@ -1467,30 +1554,13 @@ static void gsi_ctrl_notify_resp_complete(struct usb_ep *ep, event->bNotificationType, req->status); /* FALLTHROUGH */ case 0: - /* no need to handle multiple resp available for RNDIS */ - if (gsi->prot_id == IPA_USB_RNDIS) { - atomic_set(&gsi->c_port.notify_count, 0); - log_event_dbg("notify_count = %d", - atomic_read(&gsi->c_port.notify_count)); - break; - } - /* * handle multiple pending resp available * notifications by queuing same until we're done, * rest of the notification require queuing new * request. */ - if (!atomic_dec_and_test(&gsi->c_port.notify_count)) { - log_event_dbg("notify_count = %d", - atomic_read(&gsi->c_port.notify_count)); - queue_notification_request(gsi); - } else if (gsi->c_port.notify_state != GSI_CTRL_NOTIFY_NONE && - gsi->c_port.notify_state != - GSI_CTRL_NOTIFY_RESPONSE_AVAILABLE) { - gsi_ctrl_send_notification(gsi, - gsi->c_port.notify_state); - } + gsi_ctrl_send_notification(gsi); break; } } @@ -1498,8 +1568,20 @@ static void gsi_ctrl_notify_resp_complete(struct usb_ep *ep, static void gsi_rndis_response_available(void *_rndis) { struct f_gsi *gsi = _rndis; + struct gsi_ctrl_pkt *cpkt; + unsigned long flags; - gsi_ctrl_send_notification(gsi, GSI_CTRL_NOTIFY_RESPONSE_AVAILABLE); + cpkt = gsi_ctrl_pkt_alloc(0, GFP_ATOMIC); + if (IS_ERR(cpkt)) { + log_event_err("%s: err allocating cpkt\n", __func__); + return; + } + + cpkt->type = GSI_CTRL_NOTIFY_RESPONSE_AVAILABLE; + spin_lock_irqsave(&gsi->c_port.lock, flags); + list_add_tail(&cpkt->list, &gsi->c_port.cpkt_resp_q); + spin_unlock_irqrestore(&gsi->c_port.lock, flags); + gsi_ctrl_send_notification(gsi); } static void gsi_rndis_command_complete(struct usb_ep *ep, @@ -1522,7 +1604,7 @@ gsi_ctrl_set_ntb_cmd_complete(struct usb_ep *ep, struct usb_request *req) struct f_gsi *gsi = req->context; struct gsi_ntb_info *ntb = NULL; - log_event_dbg("dev:%p", gsi); + log_event_dbg("dev:%pK", gsi); req->context = NULL; if (req->status || req->actual != req->length) { @@ -1652,6 +1734,7 @@ gsi_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) cpkt = list_first_entry(&gsi->c_port.cpkt_resp_q, struct gsi_ctrl_pkt, list); list_del(&cpkt->list); + gsi->c_port.get_encap_cnt++; spin_unlock(&gsi->c_port.lock); value = min_t(unsigned, w_length, cpkt->len); @@ -2019,15 +2102,12 @@ static void gsi_disable(struct usb_function *f) gsi->c_port.notify->driver_data) { usb_ep_disable(gsi->c_port.notify); gsi->c_port.notify->driver_data = NULL; - gsi->c_port.notify_state = GSI_CTRL_NOTIFY_NONE; } - atomic_set(&gsi->c_port.notify_count, 0); - gsi_ctrl_clear_cpkt_queues(gsi, false); /* send 0 len pkt to qti/qbi to notify state change */ gsi_ctrl_send_cpkt_tomodem(gsi, NULL, 0); - + gsi->c_port.notify_req_queued = false; /* Disable Data Path - only if it was initialized already (alt=1) */ if (!gsi->data_interface_up) { log_event_dbg("%s: data intf is closed", __func__); @@ -2114,6 +2194,12 @@ static void gsi_resume(struct usb_function *f) else remote_wakeup_allowed = f->config->cdev->gadget->remote_wakeup; + if (gsi->c_port.notify && !gsi->c_port.notify->desc) + config_ep_by_speed(cdev->gadget, f, gsi->c_port.notify); + + /* Check any pending cpkt, and queue immediately on resume */ + gsi_ctrl_send_notification(gsi); + if (!remote_wakeup_allowed) { /* Configure EPs for GSI */ @@ -2145,10 +2231,7 @@ static void gsi_resume(struct usb_function *f) queue_work(gsi->d_port.ipa_usb_wq, &gsi->d_port.usb_ipa_w); - if (gsi->c_port.notify && !gsi->c_port.notify->desc) - config_ep_by_speed(cdev->gadget, f, gsi->c_port.notify); - atomic_set(&gsi->c_port.notify_count, 0); log_event_dbg("%s: completed", __func__); } @@ -2274,8 +2357,6 @@ skip_string_id_alloc: gsi->c_port.notify = ep; ep->driver_data = cdev; /* claim */ - atomic_set(&gsi->c_port.notify_count, 0); - /* allocate notification request and buffer */ gsi->c_port.notify_req = usb_ep_alloc_request(ep, GFP_KERNEL); if (!gsi->c_port.notify_req) @@ -2300,7 +2381,6 @@ skip_string_id_alloc: event->wIndex = cpu_to_le16(gsi->ctrl_id); event->wLength = cpu_to_le16(0); - gsi->c_port.notify_state = GSI_CTRL_NOTIFY_NONE; } gsi->d_port.in_request.buf_len = info->in_req_buf_len; @@ -2457,7 +2537,7 @@ static int gsi_bind(struct usb_configuration *c, struct usb_function *f) /* export host's Ethernet address in CDC format */ random_ether_addr(gsi->d_port.ipa_init_params.device_ethaddr); random_ether_addr(gsi->d_port.ipa_init_params.host_ethaddr); - log_event_dbg("setting host_ethaddr=%pM, device_ethaddr = %pM", + log_event_dbg("setting host_ethaddr=%pKM, device_ethaddr = %pKM", gsi->d_port.ipa_init_params.host_ethaddr, gsi->d_port.ipa_init_params.device_ethaddr); memcpy(gsi->ethaddr, &gsi->d_port.ipa_init_params.host_ethaddr, @@ -2589,7 +2669,7 @@ static int gsi_bind(struct usb_configuration *c, struct usb_function *f) /* export host's Ethernet address in CDC format */ random_ether_addr(gsi->d_port.ipa_init_params.device_ethaddr); random_ether_addr(gsi->d_port.ipa_init_params.host_ethaddr); - log_event_dbg("setting host_ethaddr=%pM, device_ethaddr = %pM", + log_event_dbg("setting host_ethaddr=%pKM, device_ethaddr = %pKM", gsi->d_port.ipa_init_params.host_ethaddr, gsi->d_port.ipa_init_params.device_ethaddr); @@ -2837,12 +2917,6 @@ static ssize_t gsi_info_show(struct config_item *item, char *page) len += scnprintf(buf + len, PAGE_SIZE - len, "%25s %10s\n", "Ctrl Name: ", gsi->c_port.name); len += scnprintf(buf + len, PAGE_SIZE - len, - "%25s %10u\n", "Notify State: ", - gsi->c_port.notify_state); - len += scnprintf(buf + len, PAGE_SIZE - len, - "%25s %10u\n", "Notify Count: ", - gsi->c_port.notify_count.counter); - len += scnprintf(buf + len, PAGE_SIZE - len, "%25s %10u\n", "Ctrl Online: ", gsi->c_port.ctrl_online.counter); len += scnprintf(buf + len, PAGE_SIZE - len, diff --git a/drivers/usb/gadget/function/f_gsi.h b/drivers/usb/gadget/function/f_gsi.h index f058ab4cedaa..3baf65572afc 100644 --- a/drivers/usb/gadget/function/f_gsi.h +++ b/drivers/usb/gadget/function/f_gsi.h @@ -93,6 +93,14 @@ enum connection_state { STATE_SUSPENDED }; +enum gsi_ctrl_notify_state { + GSI_CTRL_NOTIFY_NONE, + GSI_CTRL_NOTIFY_CONNECT, + GSI_CTRL_NOTIFY_SPEED, + GSI_CTRL_NOTIFY_OFFLINE, + GSI_CTRL_NOTIFY_RESPONSE_AVAILABLE, +}; + #define MAXQUEUELEN 128 struct event_queue { u8 event[MAXQUEUELEN]; @@ -107,9 +115,10 @@ struct gsi_ntb_info { }; struct gsi_ctrl_pkt { - void *buf; - int len; - struct list_head list; + void *buf; + int len; + enum gsi_ctrl_notify_state type; + struct list_head list; }; struct gsi_function_bind_info { @@ -147,22 +156,13 @@ struct gsi_function_bind_info { u32 notify_buf_len; }; -enum gsi_ctrl_notify_state { - GSI_CTRL_NOTIFY_NONE, - GSI_CTRL_NOTIFY_CONNECT, - GSI_CTRL_NOTIFY_SPEED, - GSI_CTRL_NOTIFY_OFFLINE, - GSI_CTRL_NOTIFY_RESPONSE_AVAILABLE, -}; - struct gsi_ctrl_port { char name[GSI_CTRL_NAME_LEN]; struct miscdevice ctrl_device; struct usb_ep *notify; struct usb_request *notify_req; - int notify_state; - atomic_t notify_count; + bool notify_req_queued; atomic_t ctrl_online; @@ -184,6 +184,7 @@ struct gsi_ctrl_port { unsigned copied_from_modem; unsigned modem_to_host; unsigned cpkt_drop_cnt; + unsigned get_encap_cnt; }; struct gsi_data_port { diff --git a/drivers/usb/gadget/function/f_mbim.c b/drivers/usb/gadget/function/f_mbim.c index ad66ec0d1492..cdbac89d8734 100644 --- a/drivers/usb/gadget/function/f_mbim.c +++ b/drivers/usb/gadget/function/f_mbim.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-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 @@ -741,7 +741,7 @@ static void mbim_notify_complete(struct usb_ep *ep, struct usb_request *req) struct f_mbim *mbim = req->context; struct usb_cdc_notification *event = req->buf; - pr_debug("dev:%p\n", mbim); + pr_debug("dev:%pK\n", mbim); spin_lock(&mbim->lock); switch (req->status) { @@ -771,7 +771,7 @@ static void mbim_notify_complete(struct usb_ep *ep, struct usb_request *req) mbim_do_notify(mbim); spin_unlock(&mbim->lock); - pr_debug("dev:%p Exit\n", mbim); + pr_debug("dev:%pK Exit\n", mbim); } static void mbim_ep0out_complete(struct usb_ep *ep, struct usb_request *req) @@ -782,7 +782,7 @@ static void mbim_ep0out_complete(struct usb_ep *ep, struct usb_request *req) struct f_mbim *mbim = func_to_mbim(f); struct mbim_ntb_input_size *ntb = NULL; - pr_debug("dev:%p\n", mbim); + pr_debug("dev:%pK\n", mbim); req->context = NULL; if (req->status || req->actual != req->length) { @@ -820,7 +820,7 @@ static void mbim_ep0out_complete(struct usb_ep *ep, struct usb_request *req) invalid: usb_ep_set_halt(ep); - pr_err("dev:%p Failed\n", mbim); + pr_err("dev:%pK Failed\n", mbim); } static void @@ -853,7 +853,7 @@ fmbim_cmd_complete(struct usb_ep *ep, struct usb_request *req) if (!first_command_sent) first_command_sent = true; - pr_debug("dev:%p port#%d\n", dev, dev->port_num); + pr_debug("dev:%pK port#%d\n", dev, dev->port_num); cpkt = mbim_alloc_ctrl_pkt(len, GFP_ATOMIC); if (!cpkt) { @@ -1192,7 +1192,7 @@ static int mbim_set_alt(struct usb_function *f, unsigned intf, unsigned alt) return ret; } - pr_info("Set mbim port in_desc = 0x%p\n", + pr_info("Set mbim port in_desc = 0x%pK\n", mbim->bam_port.in->desc); ret = config_ep_by_speed(cdev->gadget, f, @@ -1204,7 +1204,7 @@ static int mbim_set_alt(struct usb_function *f, unsigned intf, unsigned alt) return ret; } - pr_info("Set mbim port out_desc = 0x%p\n", + pr_info("Set mbim port out_desc = 0x%pK\n", mbim->bam_port.out->desc); pr_debug("Activate mbim\n"); @@ -1829,7 +1829,7 @@ mbim_write(struct file *fp, const char __user *buf, size_t count, loff_t *pos) pr_debug("Enter(%zu)\n", count); if (!dev || !req || !req->buf) { - pr_err("%s: dev %p req %p req->buf %p\n", + pr_err("%s: dev %pK req %pK req->buf %pK\n", __func__, dev, req, req ? req->buf : req); return -ENODEV; } @@ -1851,7 +1851,7 @@ mbim_write(struct file *fp, const char __user *buf, size_t count, loff_t *pos) } if (dev->not_port.notify_state != MBIM_NOTIFY_RESPONSE_AVAILABLE) { - pr_err("dev:%p state=%d error\n", dev, + pr_err("dev:%pK state=%d error\n", dev, dev->not_port.notify_state); mbim_unlock(&dev->write_excl); return -EINVAL; diff --git a/drivers/usb/gadget/function/f_mtp.c b/drivers/usb/gadget/function/f_mtp.c index 33f7304eac84..972ea68b16e4 100644 --- a/drivers/usb/gadget/function/f_mtp.c +++ b/drivers/usb/gadget/function/f_mtp.c @@ -522,7 +522,7 @@ static int mtp_create_bulk_endpoints(struct mtp_dev *dev, struct usb_ep *ep; int i; - DBG(cdev, "create_bulk_endpoints dev: %p\n", dev); + DBG(cdev, "create_bulk_endpoints dev: %pK\n", dev); ep = usb_ep_autoconfig(cdev->gadget, in_desc); if (!ep) { @@ -650,7 +650,7 @@ requeue_req: r = -EIO; goto done; } else { - DBG(cdev, "rx %p queue\n", req); + DBG(cdev, "rx %pK queue\n", req); } /* wait for a request to complete */ @@ -675,7 +675,7 @@ requeue_req: if (req->actual == 0) goto requeue_req; - DBG(cdev, "rx %p %d\n", req, req->actual); + DBG(cdev, "rx %pK %d\n", req, req->actual); xfer = (req->actual < count) ? req->actual : count; r = xfer; if (copy_to_user(buf, req->buf, xfer)) @@ -955,7 +955,7 @@ static void receive_file_work(struct work_struct *data) } if (write_req) { - DBG(cdev, "rx %p %d\n", write_req, write_req->actual); + DBG(cdev, "rx %pK %d\n", write_req, write_req->actual); start_time = ktime_get(); ret = vfs_write(filp, write_req->buf, write_req->actual, &offset); @@ -1393,7 +1393,7 @@ mtp_function_bind(struct usb_configuration *c, struct usb_function *f) struct mtp_instance *fi_mtp; dev->cdev = cdev; - DBG(cdev, "mtp_function_bind dev: %p\n", dev); + DBG(cdev, "mtp_function_bind dev: %pK\n", dev); /* allocate interface ID(s) */ id = usb_interface_id(c, f); diff --git a/drivers/usb/gadget/function/f_obex.c b/drivers/usb/gadget/function/f_obex.c index d6396e0909ee..98a72b7d6b6a 100644 --- a/drivers/usb/gadget/function/f_obex.c +++ b/drivers/usb/gadget/function/f_obex.c @@ -376,7 +376,7 @@ static int obex_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: - ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status); + ERROR(cdev, "%s/%pK: can't bind, err %d\n", f->name, f, status); return status; } diff --git a/drivers/usb/gadget/function/f_qc_ecm.c b/drivers/usb/gadget/function/f_qc_ecm.c index 2399d8ec7a9d..005a8d1f8747 100644 --- a/drivers/usb/gadget/function/f_qc_ecm.c +++ b/drivers/usb/gadget/function/f_qc_ecm.c @@ -3,7 +3,7 @@ * * Copyright (C) 2003-2005,2008 David Brownell * Copyright (C) 2008 Nokia Corporation - * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-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 @@ -1134,7 +1134,7 @@ ecm_qc_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], if (ecm->xport != USB_GADGET_XPORT_BAM2BAM_IPA) return status; - pr_debug("setting ecm_ipa, host_ethaddr=%pM, device_ethaddr=%pM", + pr_debug("setting ecm_ipa, host_ethaddr=%pKM, device_ethaddr=%pKM", ipa_params.host_ethaddr, ipa_params.device_ethaddr); status = ecm_ipa_init(&ipa_params); if (status) { diff --git a/drivers/usb/gadget/function/f_qc_rndis.c b/drivers/usb/gadget/function/f_qc_rndis.c index 5ebac7ece209..11c73f584594 100644 --- a/drivers/usb/gadget/function/f_qc_rndis.c +++ b/drivers/usb/gadget/function/f_qc_rndis.c @@ -6,7 +6,7 @@ * Copyright (C) 2008 Nokia Corporation * Copyright (C) 2009 Samsung Electronics * Author: Michal Nazarewicz (mina86@mina86.com) - * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-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 @@ -1197,7 +1197,7 @@ usb_function *rndis_qc_bind_config_vendor(struct usb_function_instance *fi, /* export host's Ethernet address in CDC format */ random_ether_addr(rndis_ipa_params.host_ethaddr); random_ether_addr(rndis_ipa_params.device_ethaddr); - pr_debug("setting host_ethaddr=%pM, device_ethaddr=%pM\n", + pr_debug("setting host_ethaddr=%pKM, device_ethaddr=%pKM\n", rndis_ipa_params.host_ethaddr, rndis_ipa_params.device_ethaddr); rndis_ipa_supported = true; diff --git a/drivers/usb/gadget/function/f_qdss.c b/drivers/usb/gadget/function/f_qdss.c index 16bd7d890d3e..29263a84bbea 100644 --- a/drivers/usb/gadget/function/f_qdss.c +++ b/drivers/usb/gadget/function/f_qdss.c @@ -1,7 +1,7 @@ /* * f_qdss.c -- QDSS function Driver * - * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-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 @@ -569,7 +569,7 @@ static int qdss_set_alt(struct usb_function *f, unsigned intf, unsigned alt) struct usb_qdss_ch *ch = &qdss->ch; int ret = 0; - pr_debug("qdss_set_alt qdss pointer = %p\n", qdss); + pr_debug("qdss_set_alt qdss pointer = %pK\n", qdss); qdss->gadget = gadget; if (alt != 0) diff --git a/drivers/usb/gadget/function/f_rmnet.c b/drivers/usb/gadget/function/f_rmnet.c index 3458f42ee06e..6b54e8d4fe8b 100644 --- a/drivers/usb/gadget/function/f_rmnet.c +++ b/drivers/usb/gadget/function/f_rmnet.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-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 @@ -466,8 +466,8 @@ static void frmnet_suspend(struct usb_function *f) else remote_wakeup_allowed = f->config->cdev->gadget->remote_wakeup; - pr_debug("%s: dev: %p remote_wakeup: %d\n", - __func__, dev, remote_wakeup_allowed); + pr_debug("%s: dev: %pK remote_wakeup: %d\n", __func__, dev, + remote_wakeup_allowed); if (dev->notify) { usb_ep_fifo_flush(dev->notify); @@ -486,8 +486,8 @@ static void frmnet_resume(struct usb_function *f) else remote_wakeup_allowed = f->config->cdev->gadget->remote_wakeup; - pr_debug("%s: dev: %p remote_wakeup: %d\n", - __func__, dev, remote_wakeup_allowed); + pr_debug("%s: dev: %pK remote_wakeup: %d\n", __func__, dev, + remote_wakeup_allowed); ipa_data_resume(&dev->ipa_port, dev->func_type, remote_wakeup_allowed); } @@ -514,7 +514,7 @@ frmnet_set_alt(struct usb_function *f, unsigned intf, unsigned alt) struct usb_composite_dev *cdev = f->config->cdev; int ret = 0; - pr_debug("%s: dev: %p\n", __func__, dev); + pr_debug("%s:dev:%pK\n", __func__, dev); dev->cdev = cdev; if (dev->notify) { if (dev->notify->driver_data) { @@ -596,7 +596,7 @@ static void frmnet_ctrl_response_available(struct f_rmnet *dev) int ret; struct rmnet_ctrl_pkt *cpkt; - pr_debug("%s: dev: %p\n", __func__, dev); + pr_debug("%s:dev:%pK\n", __func__, dev); spin_lock_irqsave(&dev->lock, flags); if (!atomic_read(&dev->online) || !req || !req->buf) { spin_unlock_irqrestore(&dev->lock, flags); @@ -644,7 +644,7 @@ static void frmnet_connect(struct grmnet *gr) struct f_rmnet *dev; if (!gr) { - pr_err("%s: Invalid grmnet:%p\n", __func__, gr); + pr_err("%s: Invalid grmnet:%pK\n", __func__, gr); return; } @@ -660,7 +660,7 @@ static void frmnet_disconnect(struct grmnet *gr) int status; if (!gr) { - pr_err("%s: Invalid grmnet:%p\n", __func__, gr); + pr_err("%s: Invalid grmnet:%pK\n", __func__, gr); return; } @@ -702,7 +702,7 @@ frmnet_send_cpkt_response(void *gr, void *buf, size_t len) unsigned long flags; if (!gr || !buf) { - pr_err("%s: Invalid grmnet/buf, grmnet:%p buf:%p\n", + pr_err("%s: Invalid grmnet/buf, grmnet:%pK buf:%pK\n", __func__, gr, buf); return -ENODEV; } @@ -716,7 +716,7 @@ frmnet_send_cpkt_response(void *gr, void *buf, size_t len) dev = port_to_rmnet(gr); - pr_debug("%s: dev: %p\n", __func__, dev); + pr_debug("%s: dev: %pK\n", __func__, dev); if (!atomic_read(&dev->online) || !atomic_read(&dev->ctrl_online)) { rmnet_free_ctrl_pkt(cpkt); return 0; @@ -741,7 +741,7 @@ frmnet_cmd_complete(struct usb_ep *ep, struct usb_request *req) pr_err("%s: rmnet dev is null\n", __func__); return; } - pr_debug("%s: dev: %p\n", __func__, dev); + pr_debug("%s: dev: %pK\n", __func__, dev); cdev = dev->cdev; if (dev->port.send_encap_cmd) { @@ -756,7 +756,7 @@ static void frmnet_notify_complete(struct usb_ep *ep, struct usb_request *req) unsigned long flags; struct rmnet_ctrl_pkt *cpkt; - pr_debug("%s: dev: %p\n", __func__, dev); + pr_debug("%s: dev: %pK\n", __func__, dev); switch (status) { case -ECONNRESET: case -ESHUTDOWN: @@ -823,7 +823,7 @@ frmnet_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) u16 w_length = le16_to_cpu(ctrl->wLength); int ret = -EOPNOTSUPP; - pr_debug("%s: dev: %p\n", __func__, dev); + pr_debug("%s: dev: %pK\n", __func__, dev); if (!atomic_read(&dev->online)) { pr_warn("%s: usb cable is not connected\n", __func__); return -ENOTCONN; diff --git a/drivers/usb/gadget/function/rndis.c b/drivers/usb/gadget/function/rndis.c index 98ac1ff58323..93262f3034d1 100644 --- a/drivers/usb/gadget/function/rndis.c +++ b/drivers/usb/gadget/function/rndis.c @@ -689,13 +689,6 @@ static int rndis_reset_response(struct rndis_params *params, rndis_reset_cmplt_type *resp; rndis_resp_t *r; - u32 length; - u8 *xbuf; - - /* drain the response queue */ - while ((xbuf = rndis_get_next_response(params, &length))) - rndis_free_response(params, xbuf); - r = rndis_add_response(params, sizeof(rndis_reset_cmplt_type)); if (!r) return -ENOMEM; diff --git a/drivers/usb/gadget/function/u_bam.c b/drivers/usb/gadget/function/u_bam.c index bbb744b33c3a..7947bb76f512 100644 --- a/drivers/usb/gadget/function/u_bam.c +++ b/drivers/usb/gadget/function/u_bam.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2016, Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2017, 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 @@ -231,7 +231,7 @@ static int gbam_alloc_requests(struct usb_ep *ep, struct list_head *head, int i; struct usb_request *req; - pr_debug("%s: ep:%p head:%p num:%d cb:%p", __func__, + pr_debug("%s: ep:%pK head:%pK num:%d cb:%pK", __func__, ep, head, num, cb); for (i = 0; i < num; i++) { @@ -491,7 +491,7 @@ void gbam_data_recv_cb(void *p, struct sk_buff *skb) if (!skb) return; - pr_debug("%s: p:%p#%d d:%p skb_len:%d\n", __func__, + pr_debug("%s: p:%pK#%d d:%pK skb_len:%d\n", __func__, port, port->port_num, d, skb->len); spin_lock_irqsave(&port->port_lock_dl, flags); @@ -532,7 +532,8 @@ void gbam_data_write_done(void *p, struct sk_buff *skb) d->pending_bytes_with_bam -= skb->len; gbam_free_skb_to_pool(port, skb); - pr_debug("%s:port:%p d:%p tom:%lu ppkt:%u pbytes:%u pno:%d\n", __func__, + pr_debug("%s:port:%pK d:%pK tom:%lu ppkt:%u pbytes:%u pno:%d\n", + __func__, port, d, d->to_modem, d->pending_pkts_with_bam, d->pending_bytes_with_bam, port->port_num); @@ -608,7 +609,7 @@ static void gbam_data_write_tobam(struct work_struct *w) d->pending_bytes_with_bam += skb->len; d->to_modem++; - pr_debug("%s: port:%p d:%p tom:%lu ppkts:%u pbytes:%u pno:%d\n", + pr_debug("%s: port:%pK d:%pK tom:%lu ppkts:%u pbytes:%u pno:%d\n", __func__, port, d, d->to_modem, d->pending_pkts_with_bam, d->pending_bytes_with_bam, port->port_num); @@ -1097,7 +1098,7 @@ static void gbam_start_io(struct gbam_port *port) { unsigned long flags; - pr_debug("%s: port:%p\n", __func__, port); + pr_debug("%s: port:%pK\n", __func__, port); if (_gbam_start_io(port, true)) return; @@ -1786,7 +1787,7 @@ static int gbam_port_alloc(int portno) pdrv->driver.owner = THIS_MODULE; platform_driver_register(pdrv); - pr_debug("%s: port:%p portno:%d\n", __func__, port, portno); + pr_debug("%s: port:%pK portno:%d\n", __func__, port, portno); return 0; } @@ -1826,7 +1827,7 @@ static int gbam2bam_port_alloc(int portno) INIT_LIST_HEAD(&d->rx_idle); INIT_WORK(&d->write_tobam_w, gbam_data_write_tobam); - pr_debug("%s: port:%p portno:%d\n", __func__, port, portno); + pr_debug("%s: port:%pK portno:%d\n", __func__, port, portno); return 0; } @@ -1858,7 +1859,7 @@ static ssize_t gbam_read_stats(struct file *file, char __user *ubuf, d = &port->data_ch; temp += scnprintf(buf + temp, DEBUG_BUF_SIZE - temp, - "#PORT:%d port:%p data_ch:%p#\n" + "#PORT:%d port:%pK data_ch:%pK#\n" "dpkts_to_usbhost: %lu\n" "dpkts_to_modem: %lu\n" "dpkts_pwith_bam: %u\n" @@ -1981,7 +1982,7 @@ void gbam_disconnect(struct grmnet *gr, u8 port_num, enum transport_type trans) unsigned long flags, flags_ul, flags_dl; struct bam_ch_info *d; - pr_debug("%s: grmnet:%p port#%d\n", __func__, gr, port_num); + pr_debug("%s: grmnet:%pK port#%d\n", __func__, gr, port_num); if (trans == USB_GADGET_XPORT_BAM2BAM) { pr_err("%s: invalid xport#%d\n", __func__, trans); @@ -2109,7 +2110,7 @@ int gbam_connect(struct grmnet *gr, u8 port_num, int ret; unsigned long flags, flags_ul; - pr_debug("%s: grmnet:%p port#%d\n", __func__, gr, port_num); + pr_debug("%s: grmnet:%pK port#%d\n", __func__, gr, port_num); if (!gr) { pr_err("%s: grmnet port is null\n", __func__); @@ -2254,7 +2255,7 @@ int gbam_connect(struct grmnet *gr, u8 port_num, ret = usb_ep_enable(gr->in); if (ret) { - pr_err("%s: usb_ep_enable failed eptype:IN ep:%p", + pr_err("%s: usb_ep_enable failed eptype:IN ep:%pK", __func__, gr->in); usb_ep_free_request(port->port_usb->out, d->rx_req); d->rx_req = NULL; @@ -2277,7 +2278,7 @@ int gbam_connect(struct grmnet *gr, u8 port_num, if (gr->out) { ret = usb_ep_enable(gr->out); if (ret) { - pr_err("%s: usb_ep_enable failed eptype:OUT ep:%p", + pr_err("%s: usb_ep_enable failed eptype:OUT ep:%pK", __func__, gr->out); gr->in->driver_data = 0; usb_ep_disable(gr->in); diff --git a/drivers/usb/gadget/function/u_bam_data.c b/drivers/usb/gadget/function/u_bam_data.c index e479907e93ef..56bb5724ea52 100644 --- a/drivers/usb/gadget/function/u_bam_data.c +++ b/drivers/usb/gadget/function/u_bam_data.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-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 @@ -166,7 +166,7 @@ static int bam_data_alloc_requests(struct usb_ep *ep, struct list_head *head, struct bam_data_ch_info *d = &port->data_ch; struct usb_request *req; - pr_debug("%s: ep:%p head:%p num:%d cb:%p", __func__, + pr_debug("%s: ep:%pK head:%pK num:%d cb:%pK", __func__, ep, head, num, cb); if (d->alloc_rx_reqs) { @@ -292,7 +292,7 @@ static void bam_data_write_done(void *p, struct sk_buff *skb) d->pending_with_bam--; - pr_debug("%s: port:%p d:%p pbam:%u, pno:%d\n", __func__, + pr_debug("%s: port:%pK d:%pK pbam:%u, pno:%d\n", __func__, port, d, d->pending_with_bam, port->port_num); spin_unlock_irqrestore(&port->port_lock, flags); @@ -526,7 +526,7 @@ static void bam_data_write_toipa(struct work_struct *w) d->pending_with_bam++; - pr_debug("%s: port:%p d:%p pbam:%u pno:%d\n", __func__, + pr_debug("%s: port:%pK d:%pK pbam:%u pno:%d\n", __func__, port, d, d->pending_with_bam, port->port_num); spin_unlock_irqrestore(&port->port_lock, flags); @@ -809,7 +809,7 @@ static void bam2bam_data_disconnect_work(struct work_struct *w) usb_gadget_autopm_put_async(port->gadget); spin_unlock_irqrestore(&port->port_lock, flags); - pr_debug("Disconnect workqueue done (port %p)\n", port); + pr_debug("Disconnect workqueue done (port %pK)\n", port); } /* * This function configured data fifo based on index passed to get bam2bam @@ -1144,7 +1144,7 @@ static void bam2bam_data_connect_work(struct work_struct *w) bam_data_start_rx_transfers(d, port); bam_data_start_endless_tx(port); - pr_debug("Connect workqueue done (port %p)", port); + pr_debug("Connect workqueue done (port %pK)", port); return; disconnect_ipa: @@ -1187,7 +1187,7 @@ void bam_data_start_rx_tx(u8 port_num) } if (!d->rx_req || !d->tx_req) { - pr_err("%s: No request d->rx_req=%p, d->tx_req=%p", __func__, + pr_err("%s: No request d->rx_req=%pK, d->tx_req=%pK", __func__, d->rx_req, d->tx_req); goto out; } @@ -1347,7 +1347,7 @@ void bam_data_disconnect(struct data_port *gr, enum function_type func, return; } - pr_debug("dev:%p port number:%d\n", gr, port_num); + pr_debug("dev:%pK port number:%d\n", gr, port_num); if (!gr) { pr_err("data port is null\n"); @@ -1493,7 +1493,7 @@ int bam_data_connect(struct data_port *gr, enum transport_type trans, return -EINVAL; } - pr_debug("dev:%p port#%d\n", gr, port_num); + pr_debug("dev:%pK port#%d\n", gr, port_num); usb_bam_type = usb_bam_get_bam_type(gr->cdev->gadget->name); @@ -1570,7 +1570,7 @@ int bam_data_connect(struct data_port *gr, enum transport_type trans, ret = usb_ep_enable(gr->in); if (ret) { - pr_err("usb_ep_enable failed eptype:IN ep:%p", gr->in); + pr_err("usb_ep_enable failed eptype:IN ep:%pK", gr->in); goto exit; } @@ -1578,7 +1578,7 @@ int bam_data_connect(struct data_port *gr, enum transport_type trans, ret = usb_ep_enable(gr->out); if (ret) { - pr_err("usb_ep_enable failed eptype:OUT ep:%p", gr->out); + pr_err("usb_ep_enable failed eptype:OUT ep:%pK", gr->out); goto disable_in_ep; } @@ -1849,7 +1849,7 @@ void bam_data_suspend(struct data_port *port_usb, u8 dev_port_num, port_usb->in_ep_desc_backup = port_usb->in->desc; port_usb->out_ep_desc_backup = port_usb->out->desc; - pr_debug("in_ep_desc_backup = %p, out_ep_desc_backup = %p", + pr_debug("in_ep_desc_backup = %pK, out_ep_desc_backup = %pK", port_usb->in_ep_desc_backup, port_usb->out_ep_desc_backup); @@ -1890,7 +1890,7 @@ void bam_data_resume(struct data_port *port_usb, u8 dev_port_num, port_usb->in->desc = port_usb->in_ep_desc_backup; port_usb->out->desc = port_usb->out_ep_desc_backup; - pr_debug("in_ep_desc_backup = %p, out_ep_desc_backup = %p", + pr_debug("in_ep_desc_backup = %pK, out_ep_desc_backup = %pK", port_usb->in_ep_desc_backup, port_usb->out_ep_desc_backup); diff --git a/drivers/usb/gadget/function/u_ctrl_qti.c b/drivers/usb/gadget/function/u_ctrl_qti.c index 287bfeb21ea3..8ef223370827 100644 --- a/drivers/usb/gadget/function/u_ctrl_qti.c +++ b/drivers/usb/gadget/function/u_ctrl_qti.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-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 @@ -112,7 +112,7 @@ static void qti_ctrl_queue_notify(struct qti_ctrl_port *port) spin_lock_irqsave(&port->lock, flags); if (!port->is_open) { - pr_err("%s: rmnet ctrl file handler %p is not open", + pr_err("%s: rmnet ctrl file handler %pK is not open", __func__, port); spin_unlock_irqrestore(&port->lock, flags); return; @@ -165,7 +165,7 @@ static int gqti_ctrl_send_cpkt_tomodem(enum qti_port_type qport, /* drop cpkt if port is not open */ if (!port->is_open) { - pr_debug("rmnet file handler %p(index=%d) is not open", + pr_debug("rmnet file handler %pK(index=%d) is not open", port, port->index); port->drp_cpkt_cnt++; spin_unlock_irqrestore(&port->lock, flags); @@ -206,7 +206,7 @@ int gqti_ctrl_connect(void *gr, enum qti_port_type qport, unsigned intf) struct grmnet *g_rmnet = NULL; unsigned long flags; - pr_debug("%s: port type:%d gadget:%p\n", __func__, qport, gr); + pr_debug("%s: port type:%d gadget:%pK\n", __func__, qport, gr); if (qport >= QTI_NUM_PORTS) { pr_err("%s: Invalid QTI port %d\n", __func__, qport); return -ENODEV; @@ -259,7 +259,7 @@ void gqti_ctrl_disconnect(void *gr, enum qti_port_type qport) struct rmnet_ctrl_pkt *cpkt; struct grmnet *g_rmnet = NULL; - pr_debug("%s: gadget:%p\n", __func__, gr); + pr_debug("%s: gadget:%pK\n", __func__, gr); if (qport >= QTI_NUM_PORTS) { pr_err("%s: Invalid QTI port %d\n", __func__, qport); @@ -650,7 +650,7 @@ static int qti_ctrl_read_stats(struct seq_file *s, void *unused) continue; spin_lock_irqsave(&port->lock, flags); - seq_printf(s, "\n#PORT:%d port: %p\n", i, port); + seq_printf(s, "\n#PORT:%d port: %pK\n", i, port); seq_printf(s, "name: %s\n", port->name); seq_printf(s, "host_to_modem: %d\n", port->host_to_modem); diff --git a/drivers/usb/gadget/function/u_data_ipa.c b/drivers/usb/gadget/function/u_data_ipa.c index 2d0cd30c0641..bf9e0fa9950b 100644 --- a/drivers/usb/gadget/function/u_data_ipa.c +++ b/drivers/usb/gadget/function/u_data_ipa.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-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 @@ -183,7 +183,7 @@ void ipa_data_start_rx_tx(enum ipa_func_type func) } if (!port->rx_req || !port->tx_req) { - pr_err("%s: No request d->rx_req=%p, d->tx_req=%p", __func__, + pr_err("%s: No request d->rx_req=%pK, d->tx_req=%pK", __func__, port->rx_req, port->tx_req); spin_unlock_irqrestore(&port->port_lock, flags); return; @@ -290,7 +290,7 @@ void ipa_data_disconnect(struct gadget_ipa_port *gp, enum ipa_func_type func) unsigned long flags; struct usb_gadget *gadget = NULL; - pr_debug("dev:%p port number:%d\n", gp, func); + pr_debug("dev:%pK port number:%d\n", gp, func); if (func >= USB_IPA_NUM_FUNCS) { pr_err("invalid ipa portno#%d\n", func); return; @@ -667,7 +667,7 @@ static void ipa_data_connect_work(struct work_struct *w) if (gport->in) ipa_data_start_endless_xfer(port, true); - pr_debug("Connect workqueue done (port %p)", port); + pr_debug("Connect workqueue done (port %pK)", port); return; disconnect_usb_bam_ipa_out: @@ -717,7 +717,7 @@ int ipa_data_connect(struct gadget_ipa_port *gp, enum ipa_func_type func, unsigned long flags; int ret; - pr_debug("dev:%p port#%d src_connection_idx:%d dst_connection_idx:%d\n", + pr_debug("dev:%pK port#%d src_connection_idx:%d dst_connection_idx:%d\n", gp, func, src_connection_idx, dst_connection_idx); if (func >= USB_IPA_NUM_FUNCS) { @@ -781,7 +781,7 @@ int ipa_data_connect(struct gadget_ipa_port *gp, enum ipa_func_type func, port->port_usb->in->endless = true; ret = usb_ep_enable(port->port_usb->in); if (ret) { - pr_err("usb_ep_enable failed eptype:IN ep:%p", + pr_err("usb_ep_enable failed eptype:IN ep:%pK", port->port_usb->in); usb_ep_free_request(port->port_usb->in, port->tx_req); port->tx_req = NULL; @@ -794,7 +794,7 @@ int ipa_data_connect(struct gadget_ipa_port *gp, enum ipa_func_type func, port->port_usb->out->endless = true; ret = usb_ep_enable(port->port_usb->out); if (ret) { - pr_err("usb_ep_enable failed eptype:OUT ep:%p", + pr_err("usb_ep_enable failed eptype:OUT ep:%pK", port->port_usb->out); usb_ep_free_request(port->port_usb->out, port->rx_req); port->rx_req = NULL; @@ -953,12 +953,12 @@ void ipa_data_suspend(struct gadget_ipa_port *gp, enum ipa_func_type func, */ if (gp->in) { gp->in_ep_desc_backup = gp->in->desc; - pr_debug("in_ep_desc_backup = %p\n", + pr_debug("in_ep_desc_backup = %pK\n", gp->in_ep_desc_backup); } if (gp->out) { gp->out_ep_desc_backup = gp->out->desc; - pr_debug("out_ep_desc_backup = %p\n", + pr_debug("out_ep_desc_backup = %pK\n", gp->out_ep_desc_backup); } ipa_data_disconnect(gp, func); @@ -1040,7 +1040,7 @@ void ipa_data_resume(struct gadget_ipa_port *gp, enum ipa_func_type func, u8 dst_connection_idx = 0; enum usb_ctrl usb_bam_type; - pr_debug("dev:%p port number:%d\n", gp, func); + pr_debug("dev:%pK port number:%d\n", gp, func); if (func >= USB_IPA_NUM_FUNCS) { pr_err("invalid ipa portno#%d\n", func); @@ -1066,7 +1066,7 @@ void ipa_data_resume(struct gadget_ipa_port *gp, enum ipa_func_type func, /* Restore endpoint descriptors info. */ if (gp->in) { gp->in->desc = gp->in_ep_desc_backup; - pr_debug("in_ep_desc_backup = %p\n", + pr_debug("in_ep_desc_backup = %pK\n", gp->in_ep_desc_backup); dst_connection_idx = usb_bam_get_connection_idx( usb_bam_type, IPA_P_BAM, PEER_PERIPHERAL_TO_USB, @@ -1074,7 +1074,7 @@ void ipa_data_resume(struct gadget_ipa_port *gp, enum ipa_func_type func, } if (gp->out) { gp->out->desc = gp->out_ep_desc_backup; - pr_debug("out_ep_desc_backup = %p\n", + pr_debug("out_ep_desc_backup = %pK\n", gp->out_ep_desc_backup); src_connection_idx = usb_bam_get_connection_idx( usb_bam_type, IPA_P_BAM, USB_TO_PEER_PERIPHERAL, @@ -1174,7 +1174,7 @@ static int ipa_data_port_alloc(enum ipa_func_type func) ipa_data_ports[func] = port; - pr_debug("port:%p with portno:%d allocated\n", port, func); + pr_debug("port:%pK with portno:%d allocated\n", port, func); return 0; } diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index 74e9f5b5a45d..70c95d0df581 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -889,7 +889,7 @@ static int get_ether_addr_str(u8 dev_addr[ETH_ALEN], char *str, int len) if (len < 18) return -EINVAL; - snprintf(str, len, "%pM", dev_addr); + snprintf(str, len, "%pKM", dev_addr); return 18; } @@ -971,8 +971,8 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g, free_netdev(net); dev = ERR_PTR(status); } else { - INFO(dev, "MAC %pM\n", net->dev_addr); - INFO(dev, "HOST MAC %pM\n", dev->host_mac); + INFO(dev, "MAC %pKM\n", net->dev_addr); + INFO(dev, "HOST MAC %pKM\n", dev->host_mac); /* * two kinds of host-initiated state changes: @@ -1040,7 +1040,7 @@ int gether_register_netdev(struct net_device *net) dev_dbg(&g->dev, "register_netdev failed, %d\n", status); return status; } else { - INFO(dev, "HOST MAC %pM\n", dev->host_mac); + INFO(dev, "HOST MAC %pKM\n", dev->host_mac); /* two kinds of host-initiated state changes: * - iff DATA transfer is active, carrier is "on" @@ -1056,7 +1056,7 @@ int gether_register_netdev(struct net_device *net) if (status) pr_warn("cannot set self ethernet address: %d\n", status); else - INFO(dev, "MAC %pM\n", dev->dev_mac); + INFO(dev, "MAC %pKM\n", dev->dev_mac); return status; } @@ -1124,7 +1124,7 @@ int gether_get_host_addr_cdc(struct net_device *net, char *host_addr, int len) return -EINVAL; dev = netdev_priv(net); - snprintf(host_addr, len, "%pm", dev->host_mac); + snprintf(host_addr, len, "%pKm", dev->host_mac); return strlen(host_addr); } diff --git a/drivers/usb/gadget/function/u_qc_ether.c b/drivers/usb/gadget/function/u_qc_ether.c index f933cc13bf9e..2fde4850f8cd 100644 --- a/drivers/usb/gadget/function/u_qc_ether.c +++ b/drivers/usb/gadget/function/u_qc_ether.c @@ -4,7 +4,7 @@ * Copyright (C) 2003-2005,2008 David Brownell * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger * Copyright (C) 2008 Nokia Corporation - * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-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 @@ -317,8 +317,8 @@ int gether_qc_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN], dev_dbg(&g->dev, "register_netdev failed, %d\n", status); free_netdev(net); } else { - INFO(dev, "MAC %pM\n", net->dev_addr); - INFO(dev, "HOST MAC %pM\n", dev->host_mac); + INFO(dev, "MAC %pKM\n", net->dev_addr); + INFO(dev, "HOST MAC %pKM\n", dev->host_mac); } diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index e0b77946f013..251ebdcccd60 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -4,7 +4,7 @@ * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com) * Copyright (C) 2008 David Brownell * Copyright (C) 2008 by Nokia Corporation - * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved. * * This code also borrows from usbserial.c, which is * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (greg@kroah.com) @@ -862,7 +862,7 @@ static int gs_open(struct tty_struct *tty, struct file *file) spin_lock_irq(&port->port_lock); if (status) { - pr_debug("gs_open: ttyGS%d (%p,%p) no buffer\n", + pr_debug("gs_open: ttyGS%d (%pK,%pK) no buffer\n", port->port_num, tty, file); port->openclose = false; goto exit_unlock_port; @@ -892,7 +892,7 @@ static int gs_open(struct tty_struct *tty, struct file *file) gser->connect(gser); } - pr_debug("gs_open: ttyGS%d (%p,%p)\n", port->port_num, tty, file); + pr_debug("gs_open: ttyGS%d (%pK,%pK)\n", port->port_num, tty, file); status = 0; @@ -928,7 +928,8 @@ static void gs_close(struct tty_struct *tty, struct file *file) goto exit; } - pr_debug("gs_close: ttyGS%d (%p,%p) ...\n", port->port_num, tty, file); + pr_debug("gs_close: ttyGS%d (%pK,%pK) ...\n", + port->port_num, tty, file); /* mark port as closing but in use; we can drop port lock * and sleep if necessary @@ -965,7 +966,7 @@ static void gs_close(struct tty_struct *tty, struct file *file) port->openclose = false; - pr_debug("gs_close: ttyGS%d (%p,%p) done!\n", + pr_debug("gs_close: ttyGS%d (%pK,%pK) done!\n", port->port_num, tty, file); wake_up(&port->close_wait); @@ -982,7 +983,7 @@ static int gs_write(struct tty_struct *tty, const unsigned char *buf, int count) if (!port) return 0; - pr_vdebug("gs_write: ttyGS%d (%p) writing %d bytes\n", + pr_vdebug("gs_write: ttyGS%d (%pK) writing %d bytes\n", port->port_num, tty, count); spin_lock_irqsave(&port->port_lock, flags); @@ -1004,7 +1005,7 @@ static int gs_put_char(struct tty_struct *tty, unsigned char ch) if (!port) return 0; - pr_vdebug("gs_put_char: (%d,%p) char=0x%x, called from %ps\n", + pr_vdebug("gs_put_char: (%d,%pK) char=0x%x, called from %pKs\n", port->port_num, tty, ch, __builtin_return_address(0)); spin_lock_irqsave(&port->port_lock, flags); @@ -1021,7 +1022,7 @@ static void gs_flush_chars(struct tty_struct *tty) if (!port) return; - pr_vdebug("gs_flush_chars: (%d,%p)\n", port->port_num, tty); + pr_vdebug("gs_flush_chars: (%d,%pK)\n", port->port_num, tty); spin_lock_irqsave(&port->port_lock, flags); if (port->port_usb) @@ -1042,7 +1043,7 @@ static int gs_write_room(struct tty_struct *tty) room = gs_buf_space_avail(&port->port_write_buf); spin_unlock_irqrestore(&port->port_lock, flags); - pr_vdebug("gs_write_room: (%d,%p) room=%d\n", + pr_vdebug("gs_write_room: (%d,%pK) room=%d\n", port->port_num, tty, room); return room; @@ -1058,7 +1059,7 @@ static int gs_chars_in_buffer(struct tty_struct *tty) chars = gs_buf_data_avail(&port->port_write_buf); spin_unlock_irqrestore(&port->port_lock, flags); - pr_vdebug("gs_chars_in_buffer: (%d,%p) chars=%d\n", + pr_vdebug("gs_chars_in_buffer: (%d,%pK) chars=%d\n", port->port_num, tty, chars); return chars; diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index b26b96e25a13..8d22fda48618 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -106,7 +106,7 @@ static inline void dbg_hcc_params (struct ehci_hcd *ehci, char *label) {} static void __maybe_unused dbg_qtd (const char *label, struct ehci_hcd *ehci, struct ehci_qtd *qtd) { - ehci_dbg(ehci, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd, + ehci_dbg(ehci, "%s td %pK n%08x %08x t%08x p0=%08x\n", label, qtd, hc32_to_cpup(ehci, &qtd->hw_next), hc32_to_cpup(ehci, &qtd->hw_alt_next), hc32_to_cpup(ehci, &qtd->hw_token), @@ -124,7 +124,7 @@ dbg_qh (const char *label, struct ehci_hcd *ehci, struct ehci_qh *qh) { struct ehci_qh_hw *hw = qh->hw; - ehci_dbg (ehci, "%s qh %p n%08x info %x %x qtd %x\n", label, + ehci_dbg (ehci, "%s qh %pK n%08x info %x %x qtd %x\n", label, qh, hw->hw_next, hw->hw_info1, hw->hw_info2, hw->hw_current); dbg_qtd("overlay", ehci, (struct ehci_qtd *) &hw->hw_qtd_next); } @@ -132,7 +132,7 @@ dbg_qh (const char *label, struct ehci_hcd *ehci, struct ehci_qh *qh) static void __maybe_unused dbg_itd (const char *label, struct ehci_hcd *ehci, struct ehci_itd *itd) { - ehci_dbg (ehci, "%s [%d] itd %p, next %08x, urb %p\n", + ehci_dbg (ehci, "%s [%d] itd %pK, next %08x, urb %pK\n", label, itd->frame, itd, hc32_to_cpu(ehci, itd->hw_next), itd->urb); ehci_dbg (ehci, @@ -163,7 +163,7 @@ dbg_itd (const char *label, struct ehci_hcd *ehci, struct ehci_itd *itd) static void __maybe_unused dbg_sitd (const char *label, struct ehci_hcd *ehci, struct ehci_sitd *sitd) { - ehci_dbg (ehci, "%s [%d] sitd %p, next %08x, urb %p\n", + ehci_dbg (ehci, "%s [%d] sitd %pK, next %08x, urb %pK\n", label, sitd->frame, sitd, hc32_to_cpu(ehci, sitd->hw_next), sitd->urb); ehci_dbg (ehci, @@ -436,7 +436,7 @@ static void qh_lines ( scratch = hc32_to_cpup(ehci, &hw->hw_info1); hw_curr = (mark == '*') ? hc32_to_cpup(ehci, &hw->hw_current) : 0; temp = scnprintf (next, size, - "qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)", + "qh/%pK dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)", qh, scratch & 0x007f, speed_char (scratch), (scratch >> 8) & 0x000f, @@ -464,7 +464,7 @@ static void qh_lines ( mark = '/'; } temp = snprintf (next, size, - "\n\t%p%c%s len=%d %08x urb %p", + "\n\t%pK%c%s len=%d %08x urb %pK", td, mark, ({ char *tmp; switch ((scratch>>8)&0x03) { case 0: tmp = "out"; break; @@ -662,7 +662,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) switch (hc32_to_cpu(ehci, tag)) { case Q_TYPE_QH: hw = p.qh->hw; - temp = scnprintf (next, size, " qh%d-%04x/%p", + temp = scnprintf (next, size, " qh%d-%04x/%pK", p.qh->ps.period, hc32_to_cpup(ehci, &hw->hw_info2) @@ -724,20 +724,20 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) break; case Q_TYPE_FSTN: temp = scnprintf (next, size, - " fstn-%8x/%p", p.fstn->hw_prev, + " fstn-%8x/%pK", p.fstn->hw_prev, p.fstn); tag = Q_NEXT_TYPE(ehci, p.fstn->hw_next); p = p.fstn->fstn_next; break; case Q_TYPE_ITD: temp = scnprintf (next, size, - " itd/%p", p.itd); + " itd/%pK", p.itd); tag = Q_NEXT_TYPE(ehci, p.itd->hw_next); p = p.itd->itd_next; break; case Q_TYPE_SITD: temp = scnprintf (next, size, - " sitd%d-%04x/%p", + " sitd%d-%04x/%pK", p.sitd->stream->ps.period, hc32_to_cpup(ehci, &p.sitd->hw_uframe) & 0x0000ffff, @@ -909,7 +909,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) } if (!list_empty(&ehci->async_unlink)) { - temp = scnprintf(next, size, "async unlink qh %p\n", + temp = scnprintf(next, size, "async unlink qh %pK\n", list_first_entry(&ehci->async_unlink, struct ehci_qh, unlink_node)); size -= temp; diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index f7661d9750fd..18a05e4b3c5f 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1000,7 +1000,7 @@ idle_timeout: /* caller was supposed to have unlinked any requests; * that's not our job. just leak this memory. */ - ehci_err (ehci, "qh %p (#%02x) state %d%s\n", + ehci_err (ehci, "qh %pK (#%02x) state %d%s\n", qh, ep->desc.bEndpointAddress, qh->qh_state, list_empty (&qh->qtd_list) ? "" : "(has tds)"); break; diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 54f5332f814d..ed4a20a7ca20 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -264,7 +264,7 @@ ehci_urb_done(struct ehci_hcd *ehci, struct urb *urb, int status) #ifdef EHCI_URB_TRACE ehci_dbg (ehci, - "%s %s urb %p ep%d%s status %d len %d/%d\n", + "%s %s urb %pK ep%d%s status %d len %d/%d\n", __func__, urb->dev->devpath, urb, usb_pipeendpoint (urb->pipe), usb_pipein (urb->pipe) ? "in" : "out", @@ -350,7 +350,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) /* Report Data Buffer Error: non-fatal but useful */ if (token & QTD_STS_DBE) ehci_dbg(ehci, - "detected DataBufferErr for urb %p ep%d%s len %d, qtd %p [qh %p]\n", + "detected DataBufferErr for urb %pK ep%d%s len %d, qtd %pK [qh %pK]\n", urb, usb_endpoint_num(&urb->ep->desc), usb_endpoint_dir_in(&urb->ep->desc) ? "in" : "out", @@ -924,7 +924,7 @@ qh_make ( } break; default: - ehci_dbg(ehci, "bogus dev %p speed %d\n", urb->dev, + ehci_dbg(ehci, "bogus dev %pK speed %d\n", urb->dev, urb->dev->speed); done: qh_destroy(ehci, qh); @@ -1112,7 +1112,7 @@ submit_async ( struct ehci_qtd *qtd; qtd = list_entry(qtd_list->next, struct ehci_qtd, qtd_list); ehci_dbg(ehci, - "%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n", + "%s %s urb %pK ep%d%s len %d, qtd %pK [qh %pK]\n", __func__, urb->dev->devpath, urb, epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out", urb->transfer_buffer_length, diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index f9a332775c47..9e69e4567e6a 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -548,7 +548,7 @@ static void qh_link_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh) unsigned period = qh->ps.period; dev_dbg(&qh->ps.udev->dev, - "link qh%d-%04x/%p start %d [%d/%d us]\n", + "link qh%d-%04x/%pK start %d [%d/%d us]\n", period, hc32_to_cpup(ehci, &qh->hw->hw_info2) & (QH_CMASK | QH_SMASK), qh, qh->ps.phase, qh->ps.usecs, qh->ps.c_usecs); @@ -641,7 +641,7 @@ static void qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh) : (qh->ps.usecs * 8); dev_dbg(&qh->ps.udev->dev, - "unlink qh%d-%04x/%p start %d [%d/%d us]\n", + "unlink qh%d-%04x/%pK start %d [%d/%d us]\n", qh->ps.period, hc32_to_cpup(ehci, &qh->hw->hw_info2) & (QH_CMASK | QH_SMASK), qh, qh->ps.phase, qh->ps.usecs, qh->ps.c_usecs); @@ -751,7 +751,7 @@ static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh) * FIXME kill the now-dysfunctional queued urbs */ else { - ehci_err(ehci, "can't reschedule qh %p, err %d\n", + ehci_err(ehci, "can't reschedule qh %pK, err %d\n", qh, rc); } } @@ -869,7 +869,7 @@ static int qh_schedule(struct ehci_hcd *ehci, struct ehci_qh *qh) /* reuse the previous schedule slots, if we can */ if (qh->ps.phase != NO_FRAME) { - ehci_dbg(ehci, "reused qh %p schedule\n", qh); + ehci_dbg(ehci, "reused qh %pK schedule\n", qh); return 0; } @@ -1552,7 +1552,7 @@ iso_stream_schedule ( /* no room in the schedule */ if (!done) { - ehci_dbg(ehci, "iso sched full %p", urb); + ehci_dbg(ehci, "iso sched full %pK", urb); status = -ENOSPC; goto fail; } @@ -1606,7 +1606,7 @@ iso_stream_schedule ( /* Is the schedule about to wrap around? */ if (unlikely(!empty && start < period)) { - ehci_dbg(ehci, "request %p would overflow (%u-%u < %u mod %u)\n", + ehci_dbg(ehci, "request %pK would overflow (%u-%u < %u mod %u)\n", urb, stream->next_uframe, base, period, mod); status = -EFBIG; goto fail; @@ -1635,7 +1635,7 @@ iso_stream_schedule ( /* How many uframes and packets do we need to skip? */ skip = (now2 - start + period - 1) & -period; if (skip >= span) { /* Entirely in the past? */ - ehci_dbg(ehci, "iso underrun %p (%u+%u < %u) [%u]\n", + ehci_dbg(ehci, "iso underrun %pK (%u+%u < %u) [%u]\n", urb, start + base, span - period, now2 + base, base); @@ -1662,7 +1662,7 @@ iso_stream_schedule ( use_start: /* Tried to schedule too far into the future? */ if (unlikely(start + span - period >= mod + wrap)) { - ehci_dbg(ehci, "request %p would overflow (%u+%u >= %u)\n", + ehci_dbg(ehci, "request %pK would overflow (%u+%u >= %u)\n", urb, start, span - period, mod + wrap); status = -EFBIG; goto fail; @@ -1957,7 +1957,7 @@ static int itd_submit (struct ehci_hcd *ehci, struct urb *urb, #ifdef EHCI_URB_TRACE ehci_dbg (ehci, - "%s %s urb %p ep%d%s len %d, %d pkts %d uframes [%p]\n", + "%s %s urb %pK ep%d%s len %d, %d pkts %d uframes [%pK]\n", __func__, urb->dev->devpath, urb, usb_pipeendpoint (urb->pipe), usb_pipein (urb->pipe) ? "in" : "out", @@ -2337,7 +2337,7 @@ static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb, #ifdef EHCI_URB_TRACE ehci_dbg (ehci, - "submit %p dev%s ep%d%s-iso len %d\n", + "submit %pK dev%s ep%d%s-iso len %d\n", urb, urb->dev->devpath, usb_pipeendpoint (urb->pipe), usb_pipein (urb->pipe) ? "in" : "out", @@ -2490,7 +2490,7 @@ restart: q = *q_p; break; default: - ehci_dbg(ehci, "corrupt type %d frame %d shadow %p\n", + ehci_dbg(ehci, "corrupt type %d frame %d shadow %pK\n", type, frame, q.ptr); // BUG (); /* FALL THROUGH */ diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index c3eded317495..56176222b0b6 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c @@ -256,7 +256,7 @@ static void ohci_dump_td (const struct ohci_hcd *ohci, const char *label, { u32 tmp = hc32_to_cpup (ohci, &td->hwINFO); - ohci_dbg (ohci, "%s td %p%s; urb %p index %d; hw next td %08x\n", + ohci_dbg (ohci, "%s td %pK%s; urb %pK index %d; hw next td %08x\n", label, td, (tmp & TD_DONE) ? " (DONE)" : "", td->urb, td->index, @@ -314,7 +314,7 @@ ohci_dump_ed (const struct ohci_hcd *ohci, const char *label, u32 tmp = hc32_to_cpu (ohci, ed->hwINFO); char *type = ""; - ohci_dbg (ohci, "%s, ed %p state 0x%x type %s; next ed %08x\n", + ohci_dbg (ohci, "%s, ed %pK state 0x%x type %s; next ed %08x\n", label, ed, ed->state, edstring (ed->type), hc32_to_cpup (ohci, &ed->hwNextED)); @@ -415,7 +415,7 @@ show_list (struct ohci_hcd *ohci, char *buf, size_t count, struct ed *ed) struct td *td; temp = scnprintf (buf, size, - "ed/%p %cs dev%d ep%d%s max %d %08x%s%s %s", + "ed/%pK %cs dev%d ep%d%s max %d %08x%s%s %s", ed, (info & ED_LOWSPEED) ? 'l' : 'f', info & 0x7f, @@ -437,7 +437,7 @@ show_list (struct ohci_hcd *ohci, char *buf, size_t count, struct ed *ed) cbp = hc32_to_cpup (ohci, &td->hwCBP); be = hc32_to_cpup (ohci, &td->hwBE); temp = scnprintf (buf, size, - "\n\ttd %p %s %d cc=%x urb %p (%08x)", + "\n\ttd %pK %s %d cc=%x urb %pK (%08x)", td, ({ char *pid; switch (info & TD_DP) { @@ -516,7 +516,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) next += temp; do { - temp = scnprintf (next, size, " ed%d/%p", + temp = scnprintf (next, size, " ed%d/%pK", ed->interval, ed); size -= temp; next += temp; diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 760cb57e954e..9094bca1bac6 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -278,7 +278,7 @@ static int ohci_urb_enqueue ( ed->interval); if (urb_priv->td_cnt >= urb_priv->length) { ++urb_priv->td_cnt; /* Mark it */ - ohci_dbg(ohci, "iso underrun %p (%u+%u < %u)\n", + ohci_dbg(ohci, "iso underrun %pK (%u+%u < %u)\n", urb, frame, length, next); } @@ -386,7 +386,7 @@ sanitize: /* caller was supposed to have unlinked any requests; * that's not our job. can't recover; must leak ed. */ - ohci_err (ohci, "leak ed %p (#%02x) state %d%s\n", + ohci_err (ohci, "leak ed %pK (#%02x) state %d%s\n", ed, ep->desc.bEndpointAddress, ed->state, list_empty (&ed->td_list) ? "" : " (has tds)"); td_free (ohci, ed->dummy); @@ -1028,7 +1028,7 @@ int ohci_restart(struct ohci_hcd *ohci) case ED_UNLINK: break; default: - ohci_dbg(ohci, "bogus ed %p state %d\n", + ohci_dbg(ohci, "bogus ed %pK state %d\n", ed, ed->state); } diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c index c9e315c6808a..99576f3a1970 100644 --- a/drivers/usb/host/ohci-mem.c +++ b/drivers/usb/host/ohci-mem.c @@ -109,7 +109,7 @@ td_free (struct ohci_hcd *hc, struct td *td) if (*prev) *prev = td->td_hash; else if ((td->hwINFO & cpu_to_hc32(hc, TD_DONE)) != 0) - ohci_dbg (hc, "no hash for td %p\n", td); + ohci_dbg (hc, "no hash for td %pK\n", td); dma_pool_free (hc->td_cache, td, td->td_dma); } diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 641fed609911..4365dc36be8d 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -143,7 +143,7 @@ static void periodic_link (struct ohci_hcd *ohci, struct ed *ed) { unsigned i; - ohci_dbg(ohci, "link %sed %p branch %d [%dus.], interval %d\n", + ohci_dbg(ohci, "link %sed %pK branch %d [%dus.], interval %d\n", (ed->hwINFO & cpu_to_hc32 (ohci, ED_ISO)) ? "iso " : "", ed, ed->branch, ed->load, ed->interval); @@ -287,7 +287,7 @@ static void periodic_unlink (struct ohci_hcd *ohci, struct ed *ed) } ohci_to_hcd(ohci)->self.bandwidth_allocated -= ed->load / ed->interval; - ohci_dbg(ohci, "unlink %sed %p branch %d [%dus.], interval %d\n", + ohci_dbg(ohci, "unlink %sed %pK branch %d [%dus.], interval %d\n", (ed->hwINFO & cpu_to_hc32 (ohci, ED_ISO)) ? "iso " : "", ed, ed->branch, ed->load, ed->interval); } @@ -787,7 +787,7 @@ static int td_done(struct ohci_hcd *ohci, struct urb *urb, struct td *td) if (cc != TD_CC_NOERROR) ohci_dbg(ohci, - "urb %p iso td %p (%d) len %d cc %d\n", + "urb %pK iso td %pK (%d) len %d cc %d\n", urb, td, 1 + td->index, dlen, cc); /* BULK, INT, CONTROL ... drivers see aggregate length/status, @@ -819,7 +819,7 @@ static int td_done(struct ohci_hcd *ohci, struct urb *urb, struct td *td) if (cc != TD_CC_NOERROR && cc < 0x0E) ohci_dbg(ohci, - "urb %p td %p (%d) cc %d, len=%d/%d\n", + "urb %pK td %pK (%d) cc %d, len=%d/%d\n", urb, td, 1 + td->index, cc, urb->actual_length, urb->transfer_buffer_length); @@ -885,7 +885,7 @@ static void ed_halted(struct ohci_hcd *ohci, struct td *td, int cc) /* fallthrough */ default: ohci_dbg (ohci, - "urb %p path %s ep%d%s %08x cc %d --> status %d\n", + "urb %pK path %s ep%d%s %08x cc %d --> status %d\n", urb, urb->dev->devpath, usb_pipeendpoint (urb->pipe), usb_pipein (urb->pipe) ? "in" : "out", diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 1b28a000d5c6..466ab4fa289e 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c @@ -47,7 +47,7 @@ static int uhci_show_td(struct uhci_hcd *uhci, struct uhci_td *td, char *buf, u32 status, token; status = td_status(uhci, td); - out += sprintf(out, "%*s[%p] link (%08x) ", space, "", td, + out += sprintf(out, "%*s[%pK] link (%08x) ", space, "", td, hc32_to_cpu(uhci, td->link)); out += sprintf(out, "e%d %s%s%s%s%s%s%s%s%s%sLength=%x ", ((status >> 27) & 3), @@ -105,9 +105,9 @@ static int uhci_show_urbp(struct uhci_hcd *uhci, struct urb_priv *urbp, char *ptype; - out += sprintf(out, "urb_priv [%p] ", urbp); - out += sprintf(out, "urb [%p] ", urbp->urb); - out += sprintf(out, "qh [%p] ", urbp->qh); + out += sprintf(out, "urb_priv [%pK] ", urbp); + out += sprintf(out, "urb [%pK] ", urbp->urb); + out += sprintf(out, "qh [%pK] ", urbp->qh); out += sprintf(out, "Dev=%d ", usb_pipedevice(urbp->urb->pipe)); out += sprintf(out, "EP=%x(%s) ", usb_pipeendpoint(urbp->urb->pipe), (usb_pipein(urbp->urb->pipe) ? "IN" : "OUT")); @@ -177,13 +177,13 @@ static int uhci_show_qh(struct uhci_hcd *uhci, default: qtype = "Skel" ; break; } - out += sprintf(out, "%*s[%p] %s QH link (%08x) element (%08x)\n", + out += sprintf(out, "%*s[%pK] %s QH link (%08x) element (%08x)\n", space, "", qh, qtype, hc32_to_cpu(uhci, qh->link), hc32_to_cpu(uhci, element)); if (qh->type == USB_ENDPOINT_XFER_ISOC) out += sprintf(out, - "%*s period %d phase %d load %d us, frame %x desc [%p]\n", + "%*s period %d phase %d load %d us, frame %x desc [%pK]\n", space, "", qh->period, qh->phase, qh->load, qh->iso_frame, qh->iso_packet_desc); else if (qh->type == USB_ENDPOINT_XFER_INT) diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index da6f56d996ce..9ca86cf5c9a9 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -124,9 +124,9 @@ static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci) static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td) { if (!list_empty(&td->list)) - dev_WARN(uhci_dev(uhci), "td %p still in list!\n", td); + dev_WARN(uhci_dev(uhci), "td %pK still in list!\n", td); if (!list_empty(&td->fl_list)) - dev_WARN(uhci_dev(uhci), "td %p still in fl_list!\n", td); + dev_WARN(uhci_dev(uhci), "td %pK still in fl_list!\n", td); dma_pool_free(uhci->td_pool, td, td->dma_handle); } @@ -294,7 +294,7 @@ static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) { WARN_ON(qh->state != QH_STATE_IDLE && qh->udev); if (!list_empty(&qh->queue)) - dev_WARN(uhci_dev(uhci), "qh %p list not empty!\n", qh); + dev_WARN(uhci_dev(uhci), "qh %pK list not empty!\n", qh); list_del(&qh->node); if (qh->udev) { @@ -744,7 +744,7 @@ static void uhci_free_urb_priv(struct uhci_hcd *uhci, struct uhci_td *td, *tmp; if (!list_empty(&urbp->node)) - dev_WARN(uhci_dev(uhci), "urb %p still on QH's list!\n", + dev_WARN(uhci_dev(uhci), "urb %pK still on QH's list!\n", urbp->urb); list_for_each_entry_safe(td, tmp, &urbp->td_list, list) { @@ -1317,7 +1317,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, else if (!uhci_frame_before_eq(next, frame + (urb->number_of_packets - 1) * qh->period)) - dev_dbg(uhci_dev(uhci), "iso underrun %p (%u+%u < %u)\n", + dev_dbg(uhci_dev(uhci), "iso underrun %pK (%u+%u < %u)\n", urb, frame, (urb->number_of_packets - 1) * qh->period, diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c index 74c42f722678..34388950f96b 100644 --- a/drivers/usb/host/xhci-dbg.c +++ b/drivers/usb/host/xhci-dbg.c @@ -30,10 +30,10 @@ void xhci_dbg_regs(struct xhci_hcd *xhci) { u32 temp; - xhci_dbg(xhci, "// xHCI capability registers at %p:\n", + xhci_dbg(xhci, "// xHCI capability registers at %pK:\n", xhci->cap_regs); temp = readl(&xhci->cap_regs->hc_capbase); - xhci_dbg(xhci, "// @%p = 0x%x (CAPLENGTH AND HCIVERSION)\n", + xhci_dbg(xhci, "// @%pK = 0x%x (CAPLENGTH AND HCIVERSION)\n", &xhci->cap_regs->hc_capbase, temp); xhci_dbg(xhci, "// CAPLENGTH: 0x%x\n", (unsigned int) HC_LENGTH(temp)); @@ -42,17 +42,17 @@ void xhci_dbg_regs(struct xhci_hcd *xhci) (unsigned int) HC_VERSION(temp)); #endif - xhci_dbg(xhci, "// xHCI operational registers at %p:\n", xhci->op_regs); + xhci_dbg(xhci, "// xHCI operational registers at %pK:\n", xhci->op_regs); temp = readl(&xhci->cap_regs->run_regs_off); - xhci_dbg(xhci, "// @%p = 0x%x RTSOFF\n", + xhci_dbg(xhci, "// @%pK = 0x%x RTSOFF\n", &xhci->cap_regs->run_regs_off, (unsigned int) temp & RTSOFF_MASK); - xhci_dbg(xhci, "// xHCI runtime registers at %p:\n", xhci->run_regs); + xhci_dbg(xhci, "// xHCI runtime registers at %pK:\n", xhci->run_regs); temp = readl(&xhci->cap_regs->db_off); - xhci_dbg(xhci, "// @%p = 0x%x DBOFF\n", &xhci->cap_regs->db_off, temp); - xhci_dbg(xhci, "// Doorbell array at %p:\n", xhci->dba); + xhci_dbg(xhci, "// @%pK = 0x%x DBOFF\n", &xhci->cap_regs->db_off, temp); + xhci_dbg(xhci, "// Doorbell array at %pK:\n", xhci->dba); } static void xhci_print_cap_regs(struct xhci_hcd *xhci) @@ -60,7 +60,7 @@ static void xhci_print_cap_regs(struct xhci_hcd *xhci) u32 temp; u32 hci_version; - xhci_dbg(xhci, "xHCI capability registers at %p:\n", xhci->cap_regs); + xhci_dbg(xhci, "xHCI capability registers at %pK:\n", xhci->cap_regs); temp = readl(&xhci->cap_regs->hc_capbase); hci_version = HC_VERSION(temp); @@ -157,7 +157,7 @@ static void xhci_print_status(struct xhci_hcd *xhci) static void xhci_print_op_regs(struct xhci_hcd *xhci) { - xhci_dbg(xhci, "xHCI operational registers at %p:\n", xhci->op_regs); + xhci_dbg(xhci, "xHCI operational registers at %pK:\n", xhci->op_regs); xhci_print_command_reg(xhci); xhci_print_status(xhci); } @@ -178,7 +178,7 @@ static void xhci_print_ports(struct xhci_hcd *xhci) addr = &xhci->op_regs->port_status_base; for (i = 0; i < ports; i++) { for (j = 0; j < NUM_PORT_REGS; ++j) { - xhci_dbg(xhci, "%p port %s reg = 0x%x\n", + xhci_dbg(xhci, "%pK port %s reg = 0x%x\n", addr, names[j], (unsigned int) readl(addr)); addr++; @@ -198,35 +198,35 @@ void xhci_print_ir_set(struct xhci_hcd *xhci, int set_num) if (temp == XHCI_INIT_VALUE) return; - xhci_dbg(xhci, " %p: ir_set[%i]\n", ir_set, set_num); + xhci_dbg(xhci, " %pK: ir_set[%i]\n", ir_set, set_num); - xhci_dbg(xhci, " %p: ir_set.pending = 0x%x\n", addr, + xhci_dbg(xhci, " %pK: ir_set.pending = 0x%x\n", addr, (unsigned int)temp); addr = &ir_set->irq_control; temp = readl(addr); - xhci_dbg(xhci, " %p: ir_set.control = 0x%x\n", addr, + xhci_dbg(xhci, " %pK: ir_set.control = 0x%x\n", addr, (unsigned int)temp); addr = &ir_set->erst_size; temp = readl(addr); - xhci_dbg(xhci, " %p: ir_set.erst_size = 0x%x\n", addr, + xhci_dbg(xhci, " %pK: ir_set.erst_size = 0x%x\n", addr, (unsigned int)temp); addr = &ir_set->rsvd; temp = readl(addr); if (temp != XHCI_INIT_VALUE) - xhci_dbg(xhci, " WARN: %p: ir_set.rsvd = 0x%x\n", + xhci_dbg(xhci, " WARN: %pK: ir_set.rsvd = 0x%x\n", addr, (unsigned int)temp); addr = &ir_set->erst_base; temp_64 = xhci_read_64(xhci, addr); - xhci_dbg(xhci, " %p: ir_set.erst_base = @%08llx\n", + xhci_dbg(xhci, " %pK: ir_set.erst_base = @%08llx\n", addr, temp_64); addr = &ir_set->erst_dequeue; temp_64 = xhci_read_64(xhci, addr); - xhci_dbg(xhci, " %p: ir_set.erst_dequeue = @%08llx\n", + xhci_dbg(xhci, " %pK: ir_set.erst_dequeue = @%08llx\n", addr, temp_64); } @@ -235,15 +235,15 @@ void xhci_print_run_regs(struct xhci_hcd *xhci) u32 temp; int i; - xhci_dbg(xhci, "xHCI runtime registers at %p:\n", xhci->run_regs); + xhci_dbg(xhci, "xHCI runtime registers at %pK:\n", xhci->run_regs); temp = readl(&xhci->run_regs->microframe_index); - xhci_dbg(xhci, " %p: Microframe index = 0x%x\n", + xhci_dbg(xhci, " %pK: Microframe index = 0x%x\n", &xhci->run_regs->microframe_index, (unsigned int) temp); for (i = 0; i < 7; ++i) { temp = readl(&xhci->run_regs->rsvd[i]); if (temp != XHCI_INIT_VALUE) - xhci_dbg(xhci, " WARN: %p: Rsvd[%i] = 0x%x\n", + xhci_dbg(xhci, " WARN: %pK: Rsvd[%i] = 0x%x\n", &xhci->run_regs->rsvd[i], i, (unsigned int) temp); } @@ -345,13 +345,13 @@ void xhci_debug_segment(struct xhci_hcd *xhci, struct xhci_segment *seg) void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring) { - xhci_dbg(xhci, "Ring deq = %p (virt), 0x%llx (dma)\n", + xhci_dbg(xhci, "Ring deq = %pK (virt), 0x%llx (dma)\n", ring->dequeue, (unsigned long long)xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue)); xhci_dbg(xhci, "Ring deq updated %u times\n", ring->deq_updates); - xhci_dbg(xhci, "Ring enq = %p (virt), 0x%llx (dma)\n", + xhci_dbg(xhci, "Ring enq = %pK (virt), 0x%llx (dma)\n", ring->enqueue, (unsigned long long)xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue)); @@ -441,7 +441,7 @@ static void dbg_rsvd64(struct xhci_hcd *xhci, u64 *ctx, dma_addr_t dma) { int i; for (i = 0; i < 4; ++i) { - xhci_dbg(xhci, "@%p (virt) @%08llx " + xhci_dbg(xhci, "@%pK (virt) @%08llx " "(dma) %#08llx - rsvd64[%d]\n", &ctx[4 + i], (unsigned long long)dma, ctx[4 + i], i); @@ -480,24 +480,24 @@ static void xhci_dbg_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx * int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params); xhci_dbg(xhci, "Slot Context:\n"); - xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info\n", + xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - dev_info\n", &slot_ctx->dev_info, (unsigned long long)dma, slot_ctx->dev_info); dma += field_size; - xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info2\n", + xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - dev_info2\n", &slot_ctx->dev_info2, (unsigned long long)dma, slot_ctx->dev_info2); dma += field_size; - xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tt_info\n", + xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - tt_info\n", &slot_ctx->tt_info, (unsigned long long)dma, slot_ctx->tt_info); dma += field_size; - xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_state\n", + xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - dev_state\n", &slot_ctx->dev_state, (unsigned long long)dma, slot_ctx->dev_state); dma += field_size; for (i = 0; i < 4; ++i) { - xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n", + xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - rsvd[%d]\n", &slot_ctx->reserved[i], (unsigned long long)dma, slot_ctx->reserved[i], i); dma += field_size; @@ -528,24 +528,24 @@ static void xhci_dbg_ep_ctx(struct xhci_hcd *xhci, xhci_dbg(xhci, "%s Endpoint %02d Context (ep_index %02d):\n", usb_endpoint_out(epaddr) ? "OUT" : "IN", epaddr & USB_ENDPOINT_NUMBER_MASK, i); - xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info\n", + xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - ep_info\n", &ep_ctx->ep_info, (unsigned long long)dma, ep_ctx->ep_info); dma += field_size; - xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info2\n", + xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - ep_info2\n", &ep_ctx->ep_info2, (unsigned long long)dma, ep_ctx->ep_info2); dma += field_size; - xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08llx - deq\n", + xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08llx - deq\n", &ep_ctx->deq, (unsigned long long)dma, ep_ctx->deq); dma += 2*field_size; - xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tx_info\n", + xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - tx_info\n", &ep_ctx->tx_info, (unsigned long long)dma, ep_ctx->tx_info); dma += field_size; for (j = 0; j < 3; ++j) { - xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n", + xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - rsvd[%d]\n", &ep_ctx->reserved[j], (unsigned long long)dma, ep_ctx->reserved[j], j); @@ -575,16 +575,16 @@ void xhci_dbg_ctx(struct xhci_hcd *xhci, return; } - xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - drop flags\n", + xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - drop flags\n", &ctrl_ctx->drop_flags, (unsigned long long)dma, ctrl_ctx->drop_flags); dma += field_size; - xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - add flags\n", + xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - add flags\n", &ctrl_ctx->add_flags, (unsigned long long)dma, ctrl_ctx->add_flags); dma += field_size; for (i = 0; i < 6; ++i) { - xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd2[%d]\n", + xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - rsvd2[%d]\n", &ctrl_ctx->rsvd2[i], (unsigned long long)dma, ctrl_ctx->rsvd2[i], i); dma += field_size; diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 373e9d039457..2b4f3a02f7e8 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1022,7 +1022,7 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, /* Point to output device context in dcbaa. */ xhci->dcbaa->dev_context_ptrs[slot_id] = cpu_to_le64(dev->out_ctx->dma); - xhci_dbg(xhci, "Set slot id %d dcbaa entry %p to 0x%llx\n", + xhci_dbg(xhci, "Set slot id %d dcbaa entry %pK to 0x%llx\n", slot_id, &xhci->dcbaa->dev_context_ptrs[slot_id], le64_to_cpu(xhci->dcbaa->dev_context_ptrs[slot_id])); @@ -1184,7 +1184,7 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud if (udev->tt->multi) slot_ctx->dev_info |= cpu_to_le32(DEV_MTT); } - xhci_dbg(xhci, "udev->tt = %p\n", udev->tt); + xhci_dbg(xhci, "udev->tt = %pK\n", udev->tt); xhci_dbg(xhci, "udev->ttport = 0x%x\n", udev->ttport); /* Step 4 - ring already allocated */ @@ -2035,15 +2035,15 @@ static int xhci_test_trb_in_td(struct xhci_hcd *xhci, if (seg != result_seg) { xhci_warn(xhci, "WARN: %s TRB math test %d failed!\n", test_name, test_number); - xhci_warn(xhci, "Tested TRB math w/ seg %p and " + xhci_warn(xhci, "Tested TRB math w/ seg %pK and " "input DMA 0x%llx\n", input_seg, (unsigned long long) input_dma); - xhci_warn(xhci, "starting TRB %p (0x%llx DMA), " - "ending TRB %p (0x%llx DMA)\n", + xhci_warn(xhci, "starting TRB %pK (0x%llx DMA), " + "ending TRB %pK (0x%llx DMA)\n", start_trb, start_dma, end_trb, end_dma); - xhci_warn(xhci, "Expected seg %p, got seg %p\n", + xhci_warn(xhci, "Expected seg %pK, got seg %pK\n", result_seg, seg); trb_in_td(xhci, input_seg, start_trb, end_trb, input_dma, true); @@ -2189,7 +2189,7 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, rhub = &xhci->usb2_rhub; } else { xhci_warn(xhci, "Ignoring unknown port speed, " - "Ext Cap %p, revision = 0x%x\n", + "Ext Cap %pK, revision = 0x%x\n", addr, major_revision); /* Ignoring port protocol we can't understand. FIXME */ return; @@ -2202,7 +2202,7 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, port_offset = XHCI_EXT_PORT_OFF(temp); port_count = XHCI_EXT_PORT_COUNT(temp); xhci_dbg_trace(xhci, trace_xhci_dbg_init, - "Ext Cap %p, port offset = %u, " + "Ext Cap %pK, port offset = %u, " "count = %u, revision = 0x%x", addr, port_offset, port_count, major_revision); /* Port count includes the current port offset */ @@ -2264,7 +2264,7 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, for (i = port_offset; i < (port_offset + port_count); i++) { /* Duplicate entry. Ignore the port if the revisions differ. */ if (xhci->port_array[i] != 0) { - xhci_warn(xhci, "Duplicate port entry, Ext Cap %p," + xhci_warn(xhci, "Duplicate port entry, Ext Cap %pK," " port %u\n", addr, i); xhci_warn(xhci, "Port was marked as USB %u, " "duplicated as USB %u\n", @@ -2420,7 +2420,7 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) NUM_PORT_REGS*i; xhci_dbg_trace(xhci, trace_xhci_dbg_init, "USB 2.0 port at index %u, " - "addr = %p", i, + "addr = %pK", i, xhci->usb2_ports[port_index]); port_index++; if (port_index == xhci->num_usb2_ports) @@ -2441,7 +2441,7 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) NUM_PORT_REGS*i; xhci_dbg_trace(xhci, trace_xhci_dbg_init, "USB 3.0 port at index %u, " - "addr = %p", i, + "addr = %pK", i, xhci->usb3_ports[port_index]); port_index++; if (port_index == xhci->num_usb3_ports) @@ -2482,7 +2482,7 @@ int xhci_event_ring_setup(struct xhci_hcd *xhci, struct xhci_ring **er, erst->num_entries = ERST_NUM_SEGS; erst->erst_dma_addr = dma; xhci_dbg_trace(xhci, trace_xhci_dbg_init, - "intr# %d: num segs = %i, virt addr = %p, dma addr = 0x%llx", + "intr# %d: num segs = %i, virt addr = %pK, dma addr = 0x%llx", intr_num, erst->num_entries, erst->entries, @@ -2554,7 +2554,7 @@ int xhci_sec_event_ring_setup(struct usb_hcd *hcd, unsigned intr_num) || !xhci->sec_event_ring || !xhci->sec_erst || intr_num > xhci->max_interrupters) { xhci_err(xhci, - "%s:state %x ir_set %p evt_ring %p erst %p intr# %d\n", + "%s:state %x ir_set %pK evt_ring %pK erst %pK intr# %d\n", __func__, xhci->xhc_state, xhci->sec_ir_set, xhci->sec_event_ring, xhci->sec_erst, intr_num); return -EINVAL; @@ -2681,7 +2681,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) memset(xhci->dcbaa, 0, sizeof *(xhci->dcbaa)); xhci->dcbaa->dma = dma; xhci_dbg_trace(xhci, trace_xhci_dbg_init, - "// Device context base array address = 0x%llx (DMA), %p (virt)", + "// Device context base array address = 0x%llx (DMA), %pK (virt)", (unsigned long long)xhci->dcbaa->dma, xhci->dcbaa); xhci_write_64(xhci, dma, &xhci->op_regs->dcbaa_ptr); @@ -2722,7 +2722,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) if (!xhci->cmd_ring) goto fail; xhci_dbg_trace(xhci, trace_xhci_dbg_init, - "Allocated command ring at %p", xhci->cmd_ring); + "Allocated command ring at %pK", xhci->cmd_ring); xhci_dbg_trace(xhci, trace_xhci_dbg_init, "First segment DMA is 0x%llx", (unsigned long long)xhci->cmd_ring->first_seg->dma); diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index a5e600910057..fe529f9f7d28 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -525,7 +525,7 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, "Cycle state = 0x%x", state->new_cycle_state); xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, - "New dequeue segment = %p (virtual)", + "New dequeue segment = %pK (virtual)", state->new_deq_seg); addr = xhci_trb_virt_to_dma(state->new_deq_seg, state->new_deq_ptr); xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, @@ -560,8 +560,8 @@ static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, "Cancel (unchain) link TRB"); xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, - "Address = %p (0x%llx dma); " - "in seg %p (0x%llx dma)", + "Address = %pK (0x%llx dma); " + "in seg %pK (0x%llx dma)", cur_trb, (unsigned long long)xhci_trb_virt_to_dma(cur_seg, cur_trb), cur_seg, @@ -697,7 +697,7 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id, * short, don't muck with the stream ID after * submission. */ - xhci_warn(xhci, "WARN Cancelled URB %p " + xhci_warn(xhci, "WARN Cancelled URB %pK " "has invalid stream ID %u.\n", cur_td->urb, cur_td->urb->stream_id); @@ -1040,7 +1040,7 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id, ep_ring, ep_index); } else { xhci_warn(xhci, "Mismatch between completed Set TR Deq Ptr command & xHCI internal state.\n"); - xhci_warn(xhci, "ep deq seg = %p, deq ptr = %p\n", + xhci_warn(xhci, "ep deq seg = %pK, deq ptr = %pK\n", ep->queued_deq_seg, ep->queued_deq_ptr); } } @@ -1224,7 +1224,7 @@ static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci, i_cmd->status = COMP_CMD_STOP; - xhci_dbg(xhci, "Turn aborted command %p to no-op\n", + xhci_dbg(xhci, "Turn aborted command %pK to no-op\n", i_cmd->command_trb); /* get cycle state from the original cmd trb */ cycle_state = le32_to_cpu( @@ -2595,7 +2595,7 @@ cleanup: URB_SHORT_NOT_OK)) || (status != 0 && !usb_endpoint_xfer_isoc(&urb->ep->desc))) - xhci_dbg(xhci, "Giveback URB %p, len = %d, " + xhci_dbg(xhci, "Giveback URB %pK, len = %d, " "expected = %d, status = %d\n", urb, urb->actual_length, urb->transfer_buffer_length, @@ -4299,7 +4299,7 @@ void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci, int ret; xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, - "Set TR Deq Ptr cmd, new deq seg = %p (0x%llx dma), new deq ptr = %p (0x%llx dma), new cycle = %u", + "Set TR Deq Ptr cmd, new deq seg = %pK (0x%llx dma), new deq ptr = %pK (0x%llx dma), new cycle = %u", deq_state->new_deq_seg, (unsigned long long)deq_state->new_deq_seg->dma, deq_state->new_deq_ptr, @@ -4311,7 +4311,7 @@ void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci, deq_state->new_deq_ptr); if (addr == 0) { xhci_warn(xhci, "WARN Cannot submit Set TR Deq Ptr\n"); - xhci_warn(xhci, "WARN deq seg = %p, deq pt = %p\n", + xhci_warn(xhci, "WARN deq seg = %pK, deq pt = %pK\n", deq_state->new_deq_seg, deq_state->new_deq_ptr); return; } diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h index 59c05653b2ea..4ef95ac3d976 100644 --- a/drivers/usb/host/xhci-trace.h +++ b/drivers/usb/host/xhci-trace.h @@ -103,7 +103,7 @@ DECLARE_EVENT_CLASS(xhci_log_ctx, ((HCC_64BYTE_CONTEXT(xhci->hcc_params) + 1) * 32) * ((ctx->type == XHCI_CTX_TYPE_INPUT) + ep_num + 1)); ), - TP_printk("\nctx_64=%d, ctx_type=%u, ctx_dma=@%llx, ctx_va=@%p", + TP_printk("\nctx_64=%d, ctx_type=%u, ctx_dma=@%llx, ctx_va=@%pK", __entry->ctx_64, __entry->ctx_type, (unsigned long long) __entry->ctx_dma, __entry->ctx_va ) @@ -134,7 +134,7 @@ DECLARE_EVENT_CLASS(xhci_log_event, memcpy(__get_dynamic_array(trb), trb_va, sizeof(struct xhci_generic_trb)); ), - TP_printk("\ntrb_dma=@%llx, trb_va=@%p, status=%08x, flags=%08x", + TP_printk("\ntrb_dma=@%llx, trb_va=@%pK, status=%08x, flags=%08x", (unsigned long long) __entry->dma, __entry->va, __entry->status, __entry->flags ) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 8cfc4ca4c050..6e2c2f2bcce2 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -659,7 +659,7 @@ int xhci_run(struct usb_hcd *hcd) temp = readl(&xhci->ir_set->irq_pending); xhci_dbg_trace(xhci, trace_xhci_dbg_init, - "// Enabling event ring interrupter %p by writing 0x%x to irq_pending", + "// Enabling event ring interrupter %pK by writing 0x%x to irq_pending", xhci->ir_set, (unsigned int) ER_IRQ_ENABLE(temp)); writel(ER_IRQ_ENABLE(temp), &xhci->ir_set->irq_pending); xhci_print_ir_set(xhci, 0); @@ -1458,7 +1458,7 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) exit: return ret; dying: - xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for " + xhci_dbg(xhci, "Ep 0x%x: URB %pK submitted for " "non-responsive xHCI host.\n", urb->ep->desc.bEndpointAddress, urb); ret = -ESHUTDOWN; @@ -1584,7 +1584,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) if ((xhci->xhc_state & XHCI_STATE_DYING) || (xhci->xhc_state & XHCI_STATE_HALTED)) { xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, - "Ep 0x%x: URB %p to be canceled on " + "Ep 0x%x: URB %pK to be canceled on " "non-responsive xHCI host.", urb->ep->desc.bEndpointAddress, urb); /* Let the stop endpoint command watchdog timer (which set this @@ -1607,7 +1607,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) i = urb_priv->td_cnt; if (i < urb_priv->length) xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, - "Cancel URB %p, dev %s, ep 0x%x, " + "Cancel URB %pK, dev %s, ep 0x%x, " "starting at offset 0x%llx", urb, urb->dev->devpath, urb->ep->desc.bEndpointAddress, @@ -1675,7 +1675,7 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, if (xhci->xhc_state & XHCI_STATE_DYING) return -ENODEV; - xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); + xhci_dbg(xhci, "%s called for udev %pK\n", __func__, udev); drop_flag = xhci_get_endpoint_flag(&ep->desc); if (drop_flag == SLOT_FLAG || drop_flag == EP0_FLAG) { xhci_dbg(xhci, "xHCI %s - can't drop slot or ep 0 %#x\n", @@ -1703,7 +1703,7 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, xhci_get_endpoint_flag(&ep->desc)) { /* Do not warn when called after a usb_device_reset */ if (xhci->devs[udev->slot_id]->eps[ep_index].ring != NULL) - xhci_warn(xhci, "xHCI %s called with disabled ep %p\n", + xhci_warn(xhci, "xHCI %s called with disabled ep %pK\n", __func__, ep); return 0; } @@ -1795,7 +1795,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, * ignore this request. */ if (le32_to_cpu(ctrl_ctx->add_flags) & added_ctxs) { - xhci_warn(xhci, "xHCI %s called with enabled ep %p\n", + xhci_warn(xhci, "xHCI %s called with enabled ep %pK\n", __func__, ep); return 0; } @@ -2776,7 +2776,7 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) (xhci->xhc_state & XHCI_STATE_REMOVING)) return -ENODEV; - xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); + xhci_dbg(xhci, "%s called for udev %pK\n", __func__, udev); virt_dev = xhci->devs[udev->slot_id]; command = xhci_alloc_command(xhci, false, true, GFP_KERNEL); @@ -2873,7 +2873,7 @@ void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) return; xhci = hcd_to_xhci(hcd); - xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); + xhci_dbg(xhci, "%s called for udev %pK\n", __func__, udev); virt_dev = xhci->devs[udev->slot_id]; /* Free any rings allocated for added endpoints */ for (i = 0; i < 31; ++i) { @@ -2926,7 +2926,7 @@ static void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci, if (addr == 0) { xhci_warn(xhci, "WARN Cannot submit config ep after " "reset ep command\n"); - xhci_warn(xhci, "WARN deq seg = %p, deq ptr = %p\n", + xhci_warn(xhci, "WARN deq seg = %pK, deq ptr = %pK\n", deq_state->new_deq_seg, deq_state->new_deq_ptr); return; @@ -3948,7 +3948,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, xhci_dbg_trace(xhci, trace_xhci_dbg_address, "Op regs DCBAA ptr = %#016llx", temp_64); xhci_dbg_trace(xhci, trace_xhci_dbg_address, - "Slot ID %d dcbaa entry @%p = %#016llx", + "Slot ID %d dcbaa entry @%pK = %#016llx", udev->slot_id, &xhci->dcbaa->dev_context_ptrs[udev->slot_id], (unsigned long long) diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index ad408251d955..060d78d53118 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c @@ -347,7 +347,7 @@ static int mon_text_open(struct inode *inode, struct file *file) rp->r.rnf_error = mon_text_error; rp->r.rnf_complete = mon_text_complete; - snprintf(rp->slab_name, SLAB_NAME_SZ, "mon_text_%p", rp); + snprintf(rp->slab_name, SLAB_NAME_SZ, "mon_text_%pK", rp); rp->e_slab = kmem_cache_create(rp->slab_name, sizeof(struct mon_event_text), sizeof(long), 0, mon_text_ctor); diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 970a30e155cb..f3e17b84efff 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved. +/* Copyright (c) 2009-2017, Code Aurora Forum. 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 @@ -1727,7 +1727,7 @@ static int msm_otg_probe(struct platform_device *pdev) writel(0x1, phy_select); } - dev_info(&pdev->dev, "OTG regs = %p\n", motg->regs); + dev_info(&pdev->dev, "OTG regs = %pK\n", motg->regs); motg->irq = platform_get_irq(pdev, 0); if (motg->irq < 0) { diff --git a/drivers/video/fbdev/msm/dsi_v2.c b/drivers/video/fbdev/msm/dsi_v2.c index c6e079e26c56..6b6fdbdbd2dd 100644 --- a/drivers/video/fbdev/msm/dsi_v2.c +++ b/drivers/video/fbdev/msm/dsi_v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2015, 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 @@ -232,6 +232,10 @@ static int dsi_parse_gpio(struct platform_device *pdev, pr_err("%s:%d, bklt_en gpio not specified\n", __func__, __LINE__); + ctrl_pdata->bklt_en_gpio_invert = + of_property_read_bool(ctrl_pdev->dev.of_node, + "qcom,platform-bklight-en-gpio-invert"); + return 0; } diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c index f2c2287d7d8c..19e3eadfc1b2 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-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 @@ -4105,6 +4105,10 @@ static int mdss_dsi_parse_gpio_params(struct platform_device *ctrl_pdev, if (!gpio_is_valid(ctrl_pdata->bklt_en_gpio)) pr_info("%s: bklt_en gpio not specified\n", __func__); + ctrl_pdata->bklt_en_gpio_invert = + of_property_read_bool(ctrl_pdev->dev.of_node, + "qcom,platform-bklight-en-gpio-invert"); + ctrl_pdata->rst_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-reset-gpio", 0); if (!gpio_is_valid(ctrl_pdata->rst_gpio)) diff --git a/drivers/video/fbdev/msm/mdss_dsi.h b/drivers/video/fbdev/msm/mdss_dsi.h index 1743a5f23b5d..0574410868bf 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.h +++ b/drivers/video/fbdev/msm/mdss_dsi.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-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 @@ -449,6 +449,7 @@ struct mdss_dsi_ctrl_pdata { int rst_gpio; int disp_en_gpio; int bklt_en_gpio; + bool bklt_en_gpio_invert; int lcd_mode_sel_gpio; int bklt_ctrl; /* backlight ctrl */ bool pwm_pmi; diff --git a/drivers/video/fbdev/msm/mdss_dsi_host.c b/drivers/video/fbdev/msm/mdss_dsi_host.c index 22a424cc15b8..e75e4e187de0 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_host.c +++ b/drivers/video/fbdev/msm/mdss_dsi_host.c @@ -1343,8 +1343,6 @@ static void mdss_dsi_mode_setup(struct mdss_panel_data *pdata) vsync_period = vspw + vbp + height + dummy_yres + vfp; hsync_period = hspw + hbp + width + dummy_xres + hfp; - if (ctrl_pdata->timing_db_mode) - MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x1e8, 0x1); MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x24, ((hspw + hbp + width + dummy_xres) << 16 | (hspw + hbp))); @@ -1358,8 +1356,6 @@ static void mdss_dsi_mode_setup(struct mdss_panel_data *pdata) MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x30, (hspw << 16)); MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x34, 0); MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x38, (vspw << 16)); - if (ctrl_pdata->timing_db_mode) - MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x1e4, 0x1); } else { /* command mode */ if (mipi->dst_format == DSI_CMD_DST_FORMAT_RGB888) bpp = 3; diff --git a/drivers/video/fbdev/msm/mdss_dsi_panel.c b/drivers/video/fbdev/msm/mdss_dsi_panel.c index c3ae4c1f8c17..7f6cad3de18e 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_panel.c +++ b/drivers/video/fbdev/msm/mdss_dsi_panel.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-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 @@ -343,8 +343,14 @@ int mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable) } if (gpio_is_valid(ctrl_pdata->bklt_en_gpio)) { - rc = gpio_direction_output( - ctrl_pdata->bklt_en_gpio, 1); + + if (ctrl_pdata->bklt_en_gpio_invert) + rc = gpio_direction_output( + ctrl_pdata->bklt_en_gpio, 0); + else + rc = gpio_direction_output( + ctrl_pdata->bklt_en_gpio, 1); + if (rc) { pr_err("%s: unable to set dir for bklt gpio\n", __func__); @@ -380,7 +386,12 @@ int mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable) } } else { if (gpio_is_valid(ctrl_pdata->bklt_en_gpio)) { - gpio_set_value((ctrl_pdata->bklt_en_gpio), 0); + + if (ctrl_pdata->bklt_en_gpio_invert) + gpio_set_value((ctrl_pdata->bklt_en_gpio), 1); + else + gpio_set_value((ctrl_pdata->bklt_en_gpio), 0); + gpio_free(ctrl_pdata->bklt_en_gpio); } if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) { diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c index 082986b0ade7..f20248e13cf8 100644 --- a/drivers/video/fbdev/msm/mdss_fb.c +++ b/drivers/video/fbdev/msm/mdss_fb.c @@ -594,7 +594,8 @@ static ssize_t mdss_fb_get_panel_info(struct device *dev, "white_chromaticity_x=%d\nwhite_chromaticity_y=%d\n" "red_chromaticity_x=%d\nred_chromaticity_y=%d\n" "green_chromaticity_x=%d\ngreen_chromaticity_y=%d\n" - "blue_chromaticity_x=%d\nblue_chromaticity_y=%d\n", + "blue_chromaticity_x=%d\nblue_chromaticity_y=%d\n" + "panel_orientation=%d\n", pinfo->partial_update_enabled, pinfo->roi_alignment.xstart_pix_align, pinfo->roi_alignment.width_pix_align, @@ -618,7 +619,8 @@ static ssize_t mdss_fb_get_panel_info(struct device *dev, pinfo->hdr_properties.display_primaries[4], pinfo->hdr_properties.display_primaries[5], pinfo->hdr_properties.display_primaries[6], - pinfo->hdr_properties.display_primaries[7]); + pinfo->hdr_properties.display_primaries[7], + pinfo->panel_orientation); return ret; } diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c index ae6246f2ca27..67813ca9cd37 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c @@ -1773,7 +1773,7 @@ static int hdmi_tx_read_edid(struct hdmi_tx_ctrl *hdmi_ctrl) check_sum += ebuf[ndx]; if (check_sum & 0xFF) { - DEV_ERR("%s: checksome mismatch\n", __func__); + DEV_ERR("%s: checksum mismatch\n", __func__); ret = -EINVAL; goto end; } @@ -2328,6 +2328,8 @@ static void hdmi_tx_update_deep_color(struct hdmi_tx_ctrl *hdmi_ctrl) static void hdmi_tx_hpd_int_work(struct work_struct *work) { struct hdmi_tx_ctrl *hdmi_ctrl = NULL; + int rc = -EINVAL; + int retry = MAX_EDID_READ_RETRY; hdmi_ctrl = container_of(work, struct hdmi_tx_ctrl, hpd_int_work); if (!hdmi_ctrl) { @@ -2346,7 +2348,10 @@ static void hdmi_tx_hpd_int_work(struct work_struct *work) hdmi_ctrl->hpd_state ? "CONNECT" : "DISCONNECT"); if (hdmi_ctrl->hpd_state) { - hdmi_tx_read_sink_info(hdmi_ctrl); + while (rc && retry--) + rc = hdmi_tx_read_sink_info(hdmi_ctrl); + if (!retry && rc) + pr_warn_ratelimited("%s: EDID read failed\n", __func__); hdmi_tx_update_deep_color(hdmi_ctrl); hdmi_tx_send_cable_notification(hdmi_ctrl, true); diff --git a/drivers/video/fbdev/msm/mdss_mdp_layer.c b/drivers/video/fbdev/msm/mdss_mdp_layer.c index c53c8d293539..5a7f8e7e95b4 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_layer.c +++ b/drivers/video/fbdev/msm/mdss_mdp_layer.c @@ -1013,9 +1013,6 @@ static int __configure_pipe_params(struct msm_fb_data_type *mfd, pipe->comp_ratio = layer->buffer.comp_ratio; - if (mfd->panel_orientation) - layer->flags ^= mfd->panel_orientation; - pipe->mixer_left = mixer; pipe->mfd = mfd; pipe->play_cnt = 0; @@ -1161,13 +1158,6 @@ static int __configure_pipe_params(struct msm_fb_data_type *mfd, pipe->multirect.mode = vinfo->multirect.mode; pipe->mixer_stage = layer->z_order; - if (mfd->panel_orientation & MDP_FLIP_LR) - pipe->dst.x = pipe->mixer_left->width - pipe->dst.x - - pipe->dst.w; - if (mfd->panel_orientation & MDP_FLIP_UD) - pipe->dst.y = pipe->mixer_left->height - pipe->dst.y - - pipe->dst.h; - memcpy(&pipe->layer, layer, sizeof(struct mdp_input_layer)); mdss_mdp_overlay_set_chroma_sample(pipe); diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c index 8f48956680fc..c6fc10833d7f 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c +++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c @@ -6157,10 +6157,6 @@ int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd) mfd->panel_orientation = mfd->panel_info->panel_orientation; - if ((mfd->panel_info->panel_orientation & MDP_FLIP_LR) && - (mfd->split_mode == MDP_DUAL_LM_DUAL_DISPLAY)) - mdp5_data->mixer_swap = true; - rc = sysfs_create_group(&dev->kobj, &mdp_overlay_sysfs_group); if (rc) { pr_err("vsync sysfs group creation failed, ret=%d\n", rc); diff --git a/drivers/video/fbdev/msm/msm_mdss_io_8974.c b/drivers/video/fbdev/msm/msm_mdss_io_8974.c index 3dc2e952b5dd..e6151b4c75a1 100644 --- a/drivers/video/fbdev/msm/msm_mdss_io_8974.c +++ b/drivers/video/fbdev/msm/msm_mdss_io_8974.c @@ -947,8 +947,11 @@ static void mdss_dsi_8996_phy_power_off( { int ln; void __iomem *base; + u32 data; - MIPI_OUTP(ctrl->phy_io.base + DSIPHY_CMN_CTRL_0, 0x7f); + /* Turn off PLL power */ + data = MIPI_INP(ctrl->phy_io.base + DSIPHY_CMN_CTRL_0); + MIPI_OUTP(ctrl->phy_io.base + DSIPHY_CMN_CTRL_0, data & ~BIT(7)); /* 4 lanes + clk lane configuration */ for (ln = 0; ln < 5; ln++) { @@ -1004,6 +1007,7 @@ static void mdss_dsi_8996_phy_power_on( void __iomem *base; struct mdss_dsi_phy_ctrl *pd; char *ip; + u32 data; pd = &(((ctrl->panel_data).panel_info.mipi).dsi_phy_db); @@ -1023,6 +1027,10 @@ static void mdss_dsi_8996_phy_power_on( } mdss_dsi_8996_phy_regulator_enable(ctrl); + + /* Turn on PLL power */ + data = MIPI_INP(ctrl->phy_io.base + DSIPHY_CMN_CTRL_0); + MIPI_OUTP(ctrl->phy_io.base + DSIPHY_CMN_CTRL_0, data | BIT(7)); } static void mdss_dsi_phy_power_on( @@ -1126,6 +1134,7 @@ static void mdss_dsi_8996_phy_config(struct mdss_dsi_ctrl_pdata *ctrl) mdss_dsi_8996_pll_source_standalone(ctrl); } + MIPI_OUTP(ctrl->phy_io.base + DSIPHY_CMN_CTRL_0, 0x7f); wmb(); /* make sure registers committed */ } diff --git a/include/linux/dma-mapping-fast.h b/include/linux/dma-mapping-fast.h index ddd126c0fd85..560f04736c1d 100644 --- a/include/linux/dma-mapping-fast.h +++ b/include/linux/dma-mapping-fast.h @@ -36,6 +36,8 @@ struct dma_fast_smmu_mapping { spinlock_t lock; struct notifier_block notifier; + + int is_smmu_pt_coherent; }; #ifdef CONFIG_IOMMU_IO_PGTABLE_FAST diff --git a/include/linux/iommu.h b/include/linux/iommu.h index d7db6b2eeb52..1b3f20e8fb74 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -134,6 +134,8 @@ enum iommu_attr { DOMAIN_ATTR_FAST, DOMAIN_ATTR_PGTBL_INFO, DOMAIN_ATTR_EARLY_MAP, + DOMAIN_ATTR_PAGE_TABLE_IS_COHERENT, + DOMAIN_ATTR_PAGE_TABLE_FORCE_COHERENT, DOMAIN_ATTR_MAX, }; diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 490ff31d1d88..f501b8c0de4e 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -477,6 +477,12 @@ struct perf_event { int nr_siblings; int group_flags; struct perf_event *group_leader; + + /* + * Protect the pmu, attributes and context of a group leader. + * Note: does not protect the pointer to the group_leader. + */ + struct mutex group_leader_mutex; struct pmu *pmu; enum perf_event_active_state state; diff --git a/include/linux/sched.h b/include/linux/sched.h index 36007d90a678..0d1d21e9f081 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2451,6 +2451,8 @@ extern int sched_set_static_cpu_pwr_cost(int cpu, unsigned int cost); extern unsigned int sched_get_static_cpu_pwr_cost(int cpu); extern int sched_set_static_cluster_pwr_cost(int cpu, unsigned int cost); extern unsigned int sched_get_static_cluster_pwr_cost(int cpu); +extern int sched_set_cluster_wake_idle(int cpu, unsigned int wake_idle); +extern unsigned int sched_get_cluster_wake_idle(int cpu); extern int sched_update_freq_max_load(const cpumask_t *cpumask); extern void sched_update_cpu_freq_min_max(const cpumask_t *cpus, u32 fmin, u32 fmax); diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h index 0538de6dfb6f..f7aeb14f4d63 100644 --- a/include/linux/sched/sysctl.h +++ b/include/linux/sched/sysctl.h @@ -39,7 +39,6 @@ extern unsigned int sysctl_sched_latency; extern unsigned int sysctl_sched_min_granularity; extern unsigned int sysctl_sched_wakeup_granularity; extern unsigned int sysctl_sched_child_runs_first; -extern unsigned int sysctl_sched_wake_to_idle; extern unsigned int sysctl_sched_is_big_little; extern unsigned int sysctl_sched_sync_hint_enable; extern unsigned int sysctl_sched_initial_task_util; diff --git a/include/soc/qcom/icnss.h b/include/soc/qcom/icnss.h index 14892a05bd19..7770f06b5e08 100644 --- a/include/soc/qcom/icnss.h +++ b/include/soc/qcom/icnss.h @@ -127,5 +127,6 @@ extern bool icnss_is_qmi_disable(void); extern bool icnss_is_fw_ready(void); extern int icnss_set_wlan_mac_address(const u8 *in, const uint32_t len); extern u8 *icnss_get_wlan_mac_address(struct device *dev, uint32_t *num); +extern int icnss_trigger_recovery(struct device *dev); #endif /* _ICNSS_WLAN_H_ */ diff --git a/include/uapi/media/msmb_isp.h b/include/uapi/media/msmb_isp.h index 44d75aa107d9..fac254c4361b 100644 --- a/include/uapi/media/msmb_isp.h +++ b/include/uapi/media/msmb_isp.h @@ -293,9 +293,10 @@ struct msm_vfe_axi_plane_cfg { uint8_t rdi_cid;/*CID 1-16*/ }; -enum msm_stream_memory_input_t { - MEMORY_INPUT_DISABLED, - MEMORY_INPUT_ENABLED +enum msm_stream_rdi_input_type { + MSM_CAMERA_RDI_MIN, + MSM_CAMERA_RDI_PDAF, + MSM_CAMERA_RDI_MAX, }; struct msm_vfe_axi_stream_request_cmd { @@ -318,7 +319,7 @@ struct msm_vfe_axi_stream_request_cmd { uint32_t controllable_output; uint32_t burst_len; /* Flag indicating memory input stream */ - enum msm_stream_memory_input_t memory_input; + enum msm_stream_rdi_input_type rdi_input_type; }; struct msm_vfe_axi_stream_release_cmd { @@ -726,6 +727,7 @@ struct msm_isp_fetch_eng_event { struct msm_isp_stats_event { uint32_t stats_mask; /* 4 bytes */ uint8_t stats_buf_idxs[MSM_ISP_STATS_MAX]; /* 11 bytes */ + uint8_t pd_stats_idx; }; struct msm_isp_stream_ack { diff --git a/kernel/events/core.c b/kernel/events/core.c index 446dbad75e60..00beacd233fd 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -8066,6 +8066,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, if (!group_leader) group_leader = event; + mutex_init(&event->group_leader_mutex); mutex_init(&event->child_mutex); INIT_LIST_HEAD(&event->child_list); @@ -8505,6 +8506,16 @@ SYSCALL_DEFINE5(perf_event_open, group_leader = NULL; } + /* + * Take the group_leader's group_leader_mutex before observing + * anything in the group leader that leads to changes in ctx, + * many of which may be changing on another thread. + * In particular, we want to take this lock before deciding + * whether we need to move_group. + */ + if (group_leader) + mutex_lock(&group_leader->group_leader_mutex); + if (pid != -1 && !(flags & PERF_FLAG_PID_CGROUP)) { task = find_lively_task_by_vpid(pid); if (IS_ERR(task)) { @@ -8766,6 +8777,8 @@ SYSCALL_DEFINE5(perf_event_open, if (move_group) mutex_unlock(&gctx->mutex); mutex_unlock(&ctx->mutex); + if (group_leader) + mutex_unlock(&group_leader->group_leader_mutex); if (task) { mutex_unlock(&task->signal->cred_guard_mutex); @@ -8815,6 +8828,8 @@ err_task: if (task) put_task_struct(task); err_group_fd: + if (group_leader) + mutex_unlock(&group_leader->group_leader_mutex); fdput(group); err_fd: put_unused_fd(event_fd); diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 87538f7d495a..e1c8ec0458b3 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -86,14 +86,6 @@ static unsigned int sched_nr_latency = 8; unsigned int sysctl_sched_child_runs_first __read_mostly; /* - * Controls whether, when SD_SHARE_PKG_RESOURCES is on, if all - * tasks go to idle CPUs when woken. If this is off, note that the - * per-task flag PF_WAKE_UP_IDLE can still cause a task to go to an - * idle CPU upon being woken. - */ -unsigned int __read_mostly sysctl_sched_wake_to_idle; - -/* * SCHED_OTHER wake-up granularity. * (default: 1 msec * (1 + ilog(ncpus)), units: nanoseconds) * @@ -2649,6 +2641,21 @@ struct cluster_cpu_stats { s64 highest_spare_capacity; }; +/* + * Should task be woken to any available idle cpu? + * + * Waking tasks to idle cpu has mixed implications on both performance and + * power. In many cases, scheduler can't estimate correctly impact of using idle + * cpus on either performance or power. PF_WAKE_UP_IDLE allows external kernel + * module to pass a strong hint to scheduler that the task in question should be + * woken to idle cpu, generally to improve performance. + */ +static inline int wake_to_idle(struct task_struct *p) +{ + return (current->flags & PF_WAKE_UP_IDLE) || + (p->flags & PF_WAKE_UP_IDLE); +} + static int spill_threshold_crossed(struct cpu_select_env *env, struct rq *rq) { u64 total_load; @@ -3009,6 +3016,8 @@ static void find_best_cpu_in_cluster(struct sched_cluster *c, if (env->ignore_prev_cpu) cpumask_clear_cpu(env->prev_cpu, &search_cpus); + env->need_idle = wake_to_idle(env->p) || c->wake_up_idle; + for_each_cpu(i, &search_cpus) { env->cpu_load = cpu_load_sync(i, env->sync); @@ -3052,21 +3061,6 @@ static inline void init_cluster_cpu_stats(struct cluster_cpu_stats *stats) /* No need to initialize stats->best_load */ } -/* - * Should task be woken to any available idle cpu? - * - * Waking tasks to idle cpu has mixed implications on both performance and - * power. In many cases, scheduler can't estimate correctly impact of using idle - * cpus on either performance or power. PF_WAKE_UP_IDLE allows external kernel - * module to pass a strong hint to scheduler that the task in question should be - * woken to idle cpu, generally to improve performance. - */ -static inline int wake_to_idle(struct task_struct *p) -{ - return (current->flags & PF_WAKE_UP_IDLE) || - (p->flags & PF_WAKE_UP_IDLE) || sysctl_sched_wake_to_idle; -} - static inline bool env_has_special_flags(struct cpu_select_env *env) { if (env->need_idle || env->boost_policy != SCHED_BOOST_NONE || @@ -6755,9 +6749,8 @@ static int select_idle_sibling(struct task_struct *p, int target) return i; } - if (!sysctl_sched_wake_to_idle && - !(current->flags & PF_WAKE_UP_IDLE) && - !(p->flags & PF_WAKE_UP_IDLE)) + if (!(current->flags & PF_WAKE_UP_IDLE) && + !(p->flags & PF_WAKE_UP_IDLE)) return target; /* diff --git a/kernel/sched/hmp.c b/kernel/sched/hmp.c index 180e2fcf785b..15b8f2c80e06 100644 --- a/kernel/sched/hmp.c +++ b/kernel/sched/hmp.c @@ -377,6 +377,7 @@ struct sched_cluster init_cluster = { .dstate_wakeup_latency = 0, .exec_scale_factor = 1024, .notifier_sent = 0, + .wake_up_idle = 0, }; static void update_all_clusters_stats(void) @@ -677,6 +678,19 @@ unsigned int sched_get_static_cluster_pwr_cost(int cpu) return cpu_rq(cpu)->cluster->static_cluster_pwr_cost; } +int sched_set_cluster_wake_idle(int cpu, unsigned int wake_idle) +{ + struct sched_cluster *cluster = cpu_rq(cpu)->cluster; + + cluster->wake_up_idle = !!wake_idle; + return 0; +} + +unsigned int sched_get_cluster_wake_idle(int cpu) +{ + return cpu_rq(cpu)->cluster->wake_up_idle; +} + /* * sched_window_stats_policy and sched_ravg_hist_size have a 'sysctl' copy * associated with them. This is required for atomic update of those variables @@ -2227,6 +2241,27 @@ static inline void clear_top_tasks_table(u8 *table) memset(table, 0, NUM_LOAD_INDICES * sizeof(u8)); } +static void rollover_top_tasks(struct rq *rq, bool full_window) +{ + u8 curr_table = rq->curr_table; + u8 prev_table = 1 - curr_table; + int curr_top = rq->curr_top; + + clear_top_tasks_table(rq->top_tasks[prev_table]); + clear_top_tasks_bitmap(rq->top_tasks_bitmap[prev_table]); + + if (full_window) { + curr_top = 0; + clear_top_tasks_table(rq->top_tasks[curr_table]); + clear_top_tasks_bitmap( + rq->top_tasks_bitmap[curr_table]); + } + + rq->curr_table = prev_table; + rq->prev_top = curr_top; + rq->curr_top = 0; +} + static u32 empty_windows[NR_CPUS]; static void rollover_task_window(struct task_struct *p, bool full_window) @@ -2344,29 +2379,18 @@ static void update_cpu_busy_time(struct task_struct *p, struct rq *rq, if (flip_counters) { u64 curr_sum = *curr_runnable_sum; u64 nt_curr_sum = *nt_curr_runnable_sum; - u8 curr_table = rq->curr_table; - u8 prev_table = 1 - curr_table; - int curr_top = rq->curr_top; - - clear_top_tasks_table(rq->top_tasks[prev_table]); - clear_top_tasks_bitmap(rq->top_tasks_bitmap[prev_table]); - if (prev_sum_reset) { + if (prev_sum_reset) curr_sum = nt_curr_sum = 0; - curr_top = 0; - clear_top_tasks_table(rq->top_tasks[curr_table]); - clear_top_tasks_bitmap( - rq->top_tasks_bitmap[curr_table]); - } *prev_runnable_sum = curr_sum; *nt_prev_runnable_sum = nt_curr_sum; *curr_runnable_sum = 0; *nt_curr_runnable_sum = 0; - rq->curr_table = prev_table; - rq->prev_top = curr_top; - rq->curr_top = 0; + + if (p_is_curr_task) + rollover_top_tasks(rq, full_window); } if (!account_busy_for_cpu_time(rq, p, irqtime, event)) diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index a3abdf19ff4c..c110c4aaf2be 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -389,6 +389,7 @@ struct sched_cluster { int dstate, dstate_wakeup_latency, dstate_wakeup_energy; unsigned int static_cluster_pwr_cost; int notifier_sent; + bool wake_up_idle; }; extern unsigned long all_cluster_ids[]; diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 12ea4f09c04b..eced92aa492a 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -289,13 +289,6 @@ static struct ctl_table kern_table[] = { .mode = 0644, .proc_handler = proc_dointvec, }, - { - .procname = "sched_wake_to_idle", - .data = &sysctl_sched_wake_to_idle, - .maxlen = sizeof(unsigned int), - .mode = 0644, - .proc_handler = proc_dointvec, - }, #ifdef CONFIG_SCHED_HMP { .procname = "sched_freq_reporting_policy", diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 86a3c6f0c871..2efe0500bba9 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -237,7 +237,7 @@ EXPORT_SYMBOL_GPL(nf_ct_invert_tuple); static void clean_from_lists(struct nf_conn *ct) { - pr_debug("clean_from_lists(%p)\n", ct); + pr_debug("clean_from_lists(%pK)\n", ct); hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode); hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode); @@ -330,7 +330,7 @@ destroy_conntrack(struct nf_conntrack *nfct) struct net *net = nf_ct_net(ct); struct nf_conntrack_l4proto *l4proto; - pr_debug("destroy_conntrack(%p)\n", ct); + pr_debug("destroy_conntrack(%pK)\n", ct); NF_CT_ASSERT(atomic_read(&nfct->use) == 0); NF_CT_ASSERT(!timer_pending(&ct->timeout)); @@ -361,7 +361,7 @@ destroy_conntrack(struct nf_conntrack *nfct) if (ct->master) nf_ct_put(ct->master); - pr_debug("destroy_conntrack: returning ct=%p to slab\n", ct); + pr_debug("destroy_conntrack: returning ct=%pK to slab\n", ct); nf_conntrack_free(ct); } @@ -629,7 +629,7 @@ __nf_conntrack_confirm(struct sk_buff *skb) * confirmed us. */ NF_CT_ASSERT(!nf_ct_is_confirmed(ct)); - pr_debug("Confirming conntrack %p\n", ct); + pr_debug("Confirming conntrack %pK\n", ct); /* We have to check the DYING flag after unlink to prevent * a race against nf_ct_get_next_corpse() possibly called from * user context, else we insert an already 'dead' hash, blocking @@ -972,7 +972,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl, spin_lock(&nf_conntrack_expect_lock); exp = nf_ct_find_expectation(net, zone, tuple); if (exp) { - pr_debug("conntrack: expectation arrives ct=%p exp=%p\n", + pr_debug("conntrack: expectation arrives ct=%pK exp=%pK\n", ct, exp); /* Welcome, Mr. Bond. We've been expecting you... */ __set_bit(IPS_EXPECTED_BIT, &ct->status); @@ -1063,14 +1063,14 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl, } else { /* Once we've had two way comms, always ESTABLISHED. */ if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) { - pr_debug("nf_conntrack_in: normal packet for %p\n", ct); + pr_debug("nf_conntrack_in: normal packet for %pK\n", ct); *ctinfo = IP_CT_ESTABLISHED; } else if (test_bit(IPS_EXPECTED_BIT, &ct->status)) { - pr_debug("nf_conntrack_in: related packet for %p\n", + pr_debug("nf_conntrack_in: related packet for %pK\n", ct); *ctinfo = IP_CT_RELATED; } else { - pr_debug("nf_conntrack_in: new packet for %p\n", ct); + pr_debug("nf_conntrack_in: new packet for %pK\n", ct); *ctinfo = IP_CT_NEW; } *set_reply = 0; @@ -1212,7 +1212,7 @@ void nf_conntrack_alter_reply(struct nf_conn *ct, /* Should be unconfirmed, so not in hash table yet */ NF_CT_ASSERT(!nf_ct_is_confirmed(ct)); - pr_debug("Altering reply tuple of %p to ", ct); + pr_debug("Altering reply tuple of %pK to ", ct); nf_ct_dump_tuple(newreply); ct->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply; diff --git a/net/wireless/ap.c b/net/wireless/ap.c index cb1cfd34046d..f09f5683cb30 100644 --- a/net/wireless/ap.c +++ b/net/wireless/ap.c @@ -25,8 +25,8 @@ static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, return -ENOENT; err = rdev_stop_ap(rdev, dev); + wdev->beacon_interval = 0; if (!err) { - wdev->beacon_interval = 0; memset(&wdev->chandef, 0, sizeof(wdev->chandef)); wdev->ssid_len = 0; rdev_set_qos_map(rdev, dev, NULL); diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index c07a7eda42a2..252dd6df5ef1 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -357,7 +357,7 @@ static void queue_pending_output_urbs(struct snd_usb_endpoint *ep) err = usb_submit_urb(ctx->urb, GFP_ATOMIC); if (err < 0) usb_audio_err(ep->chip, - "Unable to submit urb #%d: %d (urb %p)\n", + "Unable to submit urb #%d: %d (urb %pK)\n", ctx->index, err, ctx->urb); else set_bit(ctx->index, &ep->active_mask); @@ -459,7 +459,7 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, ep->iface == alts->desc.bInterfaceNumber && ep->altsetting == alts->desc.bAlternateSetting) { usb_audio_dbg(ep->chip, - "Re-using EP %x in iface %d,%d @%p\n", + "Re-using EP %x in iface %d,%d @%pK\n", ep_num, ep->iface, ep->altsetting, ep); goto __exit_unlock; } diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index ae8f8660a18d..a0c0a184d02b 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -228,7 +228,7 @@ static int start_endpoints(struct snd_usb_substream *subs, bool can_sleep) if (!test_and_set_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags)) { struct snd_usb_endpoint *ep = subs->data_endpoint; - dev_dbg(&subs->dev->dev, "Starting data EP @%p\n", ep); + dev_dbg(&subs->dev->dev, "Starting data EP @%pK\n", ep); ep->data_subs = subs; err = snd_usb_endpoint_start(ep, can_sleep); @@ -257,7 +257,7 @@ static int start_endpoints(struct snd_usb_substream *subs, bool can_sleep) } } - dev_dbg(&subs->dev->dev, "Starting sync EP @%p\n", ep); + dev_dbg(&subs->dev->dev, "Starting sync EP @%pK\n", ep); ep->sync_slave = subs->data_endpoint; err = snd_usb_endpoint_start(ep, can_sleep); @@ -629,13 +629,13 @@ static int match_endpoint_audioformats(struct snd_usb_substream *subs, if (fp->channels < 1) { dev_dbg(&subs->dev->dev, - "%s: (fmt @%p) no channels\n", __func__, fp); + "%s: (fmt @%pK) no channels\n", __func__, fp); return 0; } if (!(fp->formats & pcm_format_to_bits(pcm_format))) { dev_dbg(&subs->dev->dev, - "%s: (fmt @%p) no match for format %d\n", __func__, + "%s: (fmt @%pK) no match for format %d\n", __func__, fp, pcm_format); return 0; } @@ -648,7 +648,7 @@ static int match_endpoint_audioformats(struct snd_usb_substream *subs, } if (!score) { dev_dbg(&subs->dev->dev, - "%s: (fmt @%p) no match for rate %d\n", __func__, + "%s: (fmt @%pK) no match for rate %d\n", __func__, fp, rate); return 0; } @@ -657,7 +657,7 @@ static int match_endpoint_audioformats(struct snd_usb_substream *subs, score++; dev_dbg(&subs->dev->dev, - "%s: (fmt @%p) score %d\n", __func__, fp, score); + "%s: (fmt @%pK) score %d\n", __func__, fp, score); return score; } diff --git a/sound/usb/usb_audio_qmi_svc.c b/sound/usb/usb_audio_qmi_svc.c index 2cdf4901b8c7..039519c1d822 100644 --- a/sound/usb/usb_audio_qmi_svc.c +++ b/sound/usb/usb_audio_qmi_svc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-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 @@ -806,7 +806,7 @@ static void uaudio_dev_release(struct kref *kref) { struct uaudio_dev *dev = container_of(kref, struct uaudio_dev, kref); - pr_debug("%s for dev %p\n", __func__, dev); + pr_debug("%s for dev %pK\n", __func__, dev); atomic_set(&dev->in_use, 0); |
