diff options
27 files changed, 787 insertions, 66 deletions
diff --git a/Documentation/device-mapper/boot.txt b/Documentation/device-mapper/boot.txt new file mode 100644 index 000000000000..adcaad5e5e32 --- /dev/null +++ b/Documentation/device-mapper/boot.txt @@ -0,0 +1,42 @@ +Boot time creation of mapped devices +=================================== + +It is possible to configure a device mapper device to act as the root +device for your system in two ways. + +The first is to build an initial ramdisk which boots to a minimal +userspace which configures the device, then pivot_root(8) in to it. + +For simple device mapper configurations, it is possible to boot directly +using the following kernel command line: + +dm="<name> <uuid> <ro>,table line 1,...,table line n" + +name = the name to associate with the device + after boot, udev, if used, will use that name to label + the device node. +uuid = may be 'none' or the UUID desired for the device. +ro = may be "ro" or "rw". If "ro", the device and device table will be + marked read-only. + +Each table line may be as normal when using the dmsetup tool except for +two variations: +1. Any use of commas will be interpreted as a newline +2. Quotation marks cannot be escaped and cannot be used without + terminating the dm= argument. + +Unless renamed by udev, the device node created will be dm-0 as the +first minor number for the device-mapper is used during early creation. + +Example +======= + +- Booting to a linear array made up of user-mode linux block devices: + + dm="lroot none 0, 0 4096 linear 98:16 0, 4096 4096 linear 98:32 0" \ + root=/dev/dm-0 + +Will boot to a rw dm-linear target of 8192 sectors split across two +block devices identified by their major:minor numbers. After boot, udev +will rename this target to /dev/mapper/lroot (depending on the rules). +No uuid was assigned. diff --git a/Documentation/devicetree/bindings/arm/cache.txt b/Documentation/devicetree/bindings/arm/cache.txt new file mode 100644 index 000000000000..a9594f026506 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/cache.txt @@ -0,0 +1,195 @@ +========================================== +ARM processors cache binding description +========================================== + +Device tree bindings for ARM processor caches adhere to the cache bindings +described in [3], in section 3.8 for multi-level and shared caches. +On ARM based systems most of the cache properties related to cache +geometry are probeable in HW, hence, unless otherwise stated, the properties +defined in ePAPR for multi-level and shared caches are to be considered +optional by default. + +On ARM, caches are either architected (directly controlled by the processor +through coprocessor instructions and tightly coupled with the processor +implementation) or unarchitected (controlled through a memory mapped +interface, implemented as a stand-alone IP external to the processor +implementation). + +This document provides the device tree bindings for ARM architected caches. + +- ARM architected cache node + + Description: must be a direct child of the cpu node. A system + can contain multiple architected cache nodes per cpu node, + linked through the next-level-cache phandle. The + next-level-cache property in the cpu node points to + the first level of architected cache for the CPU. + The next-level-cache property in architected cache nodes + points to the respective next level of caching in the + hierarchy. An architected cache node with an empty or + missing next-level-cache property represents the last + architected cache level for the CPU. + On ARM v7 and v8 architectures, the order in which cache + nodes are linked through the next-level-cache phandle must + follow the ordering specified in the processors CLIDR (v7) + and CLIDR_EL1 (v8) registers, as described in [1][2], + implying that a cache node pointed at by a + next-level-cache phandle must correspond to a level + defined in CLIDR (v7) and CLIDR_EL1 (v8) greater than the + one the cache node containing the next-level-cache + phandle corresponds to. + + Since on ARM most of the cache properties are probeable in HW the + properties described in [3] - section 3.8 multi-level and shared + caches - shall be considered optional, with the following properties + updates, specific for the ARM architected cache node. + + - compatible + Usage: Required + Value type: <string> + Definition: value shall be "arm,arch-cache". + + - interrupts + Usage: Optional + Value type: See definition + Definition: standard device tree property [3] that defines + the interrupt line associated with the cache. + The property can be accompanied by an + interrupt-names property, as described in [4]. + + - power-domain + Usage: Optional + Value type: phandle + Definition: A phandle and power domain specifier as defined by + bindings of power controller specified by the + phandle [5]. + + - qcom,dump-size + Usage: Optional + Value type: <integer> + Definition: The memory size needed to contain a copy of the + cache data and associated tag ram. + size = nways * nsets * (bytes per cache line + + bytes tag ram per line) + +Example(dual-cluster big.LITTLE system 32-bit) + + cpus { + #size-cells = <0>; + #address-cells = <1>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x0>; + next-level-cache = <&L1_0>; + + L1_0: l1-cache { + compatible = "arm,arch-cache"; + next-level-cache = <&L2_0>; + }; + + L2_0: l2-cache { + compatible = "arm,arch-cache"; + }; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x1>; + next-level-cache = <&L1_1>; + + L1_1: l1-cache { + compatible = "arm,arch-cache"; + next-level-cache = <&L2_0>; + }; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x2>; + next-level-cache = <&L1_2>; + + L1_2: l1-cache { + compatible = "arm,arch-cache"; + next-level-cache = <&L2_0>; + }; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x3>; + next-level-cache = <&L1_3>; + + L1_3: l1-cache { + compatible = "arm,arch-cache"; + next-level-cache = <&L2_0>; + }; + }; + + cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x100>; + next-level-cache = <&L1_4>; + + L1_4: l1-cache { + compatible = "arm,arch-cache"; + next-level-cache = <&L2_1>; + }; + + L2_1: l2-cache { + compatible = "arm,arch-cache"; + }; + }; + + cpu@101 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x101>; + next-level-cache = <&L1_5>; + + L1_5: l1-cache { + compatible = "arm,arch-cache"; + next-level-cache = <&L2_1>; + }; + }; + + cpu@102 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x102>; + next-level-cache = <&L1_6>; + + L1_6: l1-cache { + compatible = "arm,arch-cache"; + next-level-cache = <&L2_1>; + }; + }; + + cpu@103 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x103>; + next-level-cache = <&L1_7>; + + L1_7: l1-cache { + compatible = "arm,arch-cache"; + next-level-cache = <&L2_1>; + }; + }; + }; + +[1] ARMv7-AR Reference Manual + http://infocenter.arm.com/help/index.jsp +[2] ARMv8-A Reference Manual + http://infocenter.arm.com/help/index.jsp +[3] ePAPR standard + https://www.power.org/documentation/epapr-version-1-1/ +[4] Kernel documentation - resource property bindings + Documentation/devicetree/bindings/resource-names.txt +[5] Kernel documentation - power domain bindings + Documentation/devicetree/bindings/power/power_domain.txt diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 024bdaf9af46..276d3f68e08d 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -56,6 +56,7 @@ parameter is applicable: BLACKFIN Blackfin architecture is enabled. CLK Common clock infrastructure is enabled. CMA Contiguous Memory Area support is enabled. + DM Device mapper support is enabled. DRM Direct Rendering Management support is enabled. DYNAMIC_DEBUG Build in debug messages and enable them at runtime EDD BIOS Enhanced Disk Drive Services (EDD) is enabled @@ -919,6 +920,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. dis_ucode_ldr [X86] Disable the microcode loader. + dm= [DM] Allows early creation of a device-mapper device. + See Documentation/device-mapper/boot.txt. + dma_debug=off If the kernel is compiled with DMA_API_DEBUG support, this option disables the debugging code at boot. diff --git a/arch/arm/boot/dts/qcom/msm8996-ion.dtsi b/arch/arm/boot/dts/qcom/msm8996-ion.dtsi index 6b64e9b8976a..9b287e3f23c5 100644 --- a/arch/arm/boot/dts/qcom/msm8996-ion.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996-ion.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-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 @@ -21,11 +21,6 @@ qcom,ion-heap-type = "SYSTEM"; }; - system_contig_heap: qcom,ion-heap@21 { - reg = <21>; - qcom,ion-heap-type = "SYSTEM_CONTIG"; - }; - qcom,ion-heap@22 { /* ADSP HEAP */ reg = <22>; memory-region = <&adsp_mem>; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-ion.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-ion.dtsi index dfa3dae8e371..7b15fd81c710 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-ion.dtsi +++ b/arch/arm/boot/dts/qcom/msmcobalt-ion.dtsi @@ -21,11 +21,6 @@ qcom,ion-heap-type = "SYSTEM"; }; - system_contig_heap: qcom,ion-heap@21 { - reg = <21>; - qcom,ion-heap-type = "SYSTEM_CONTIG"; - }; - qcom,ion-heap@22 { /* ADSP HEAP */ reg = <22>; memory-region = <&adsp_mem>; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-ion.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-ion.dtsi index f6deef335844..00b9e61d01b8 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-ion.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon-ion.dtsi @@ -21,11 +21,6 @@ qcom,ion-heap-type = "SYSTEM"; }; - system_contig_heap: qcom,ion-heap@21 { - reg = <21>; - qcom,ion-heap-type = "SYSTEM_CONTIG"; - }; - qcom,ion-heap@22 { /* ADSP HEAP */ reg = <22>; memory-region = <&adsp_mem>; diff --git a/arch/arm/boot/dts/qcom/msmtriton-ion.dtsi b/arch/arm/boot/dts/qcom/msmtriton-ion.dtsi index f6deef335844..00b9e61d01b8 100644 --- a/arch/arm/boot/dts/qcom/msmtriton-ion.dtsi +++ b/arch/arm/boot/dts/qcom/msmtriton-ion.dtsi @@ -21,11 +21,6 @@ qcom,ion-heap-type = "SYSTEM"; }; - system_contig_heap: qcom,ion-heap@21 { - reg = <21>; - qcom,ion-heap-type = "SYSTEM_CONTIG"; - }; - qcom,ion-heap@22 { /* ADSP HEAP */ reg = <22>; memory-region = <&adsp_mem>; diff --git a/drivers/clk/msm/clock-debug.c b/drivers/clk/msm/clock-debug.c index d0ff821eb203..00a86ba55171 100644 --- a/drivers/clk/msm/clock-debug.c +++ b/drivers/clk/msm/clock-debug.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2007 Google, Inc. - * Copyright (c) 2007-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2007-2014, 2016, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -355,8 +355,12 @@ static int trace_clocks_show(struct seq_file *m, void *unused) return 1; } list_for_each_entry(c, &clk_list, list) { + int vlevel = 0; + + if (c->num_fmax) + vlevel = find_vdd_level(c, c->rate); trace_clock_state(c->dbg_name, c->prepare_count, c->count, - c->rate); + c->rate, vlevel); total_cnt++; } mutex_unlock(&clk_list_lock); diff --git a/drivers/cpuidle/lpm-levels.c b/drivers/cpuidle/lpm-levels.c index 37e504381313..de033cc37a15 100644 --- a/drivers/cpuidle/lpm-levels.c +++ b/drivers/cpuidle/lpm-levels.c @@ -85,7 +85,9 @@ struct lpm_debug { struct lpm_cluster *lpm_root_node; -static bool lpm_prediction; +#define MAXSAMPLES 5 + +static bool lpm_prediction = true; module_param_named(lpm_prediction, lpm_prediction, bool, S_IRUGO | S_IWUSR | S_IWGRP); diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index 766b052ade1d..294444d5f59e 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -792,11 +792,14 @@ static int tmc_enable(struct tmc_drvdata *drvdata, enum tmc_mode mode) drvdata->out_mode == TMC_ETR_OUT_MODE_USB) { drvdata->usbch = usb_qdss_open("qdss", drvdata, usb_notifier); - if (IS_ERR(drvdata->usbch)) { + if (IS_ERR_OR_NULL(drvdata->usbch)) { dev_err(drvdata->dev, "usb_qdss_open failed\n"); ret = PTR_ERR(drvdata->usbch); pm_runtime_put(drvdata->dev); mutex_unlock(&drvdata->mem_lock); + if (!ret) + ret = -ENODEV; + return ret; } } else if (drvdata->config_type == TMC_CONFIG_TYPE_ETB || @@ -1846,12 +1849,13 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) struct device_node *np = adev->dev.of_node; struct coresight_cti_data *ctidata; - if (np) { - pdata = of_get_coresight_platform_data(dev, np); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - adev->dev.platform_data = pdata; - } + if (!np) + return -ENODEV; + + pdata = of_get_coresight_platform_data(dev, np); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + adev->dev.platform_data = pdata; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 80a439543259..bc5e9a5b1f30 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -1923,6 +1923,45 @@ void dm_interface_exit(void) dm_hash_exit(); } + +/** + * dm_ioctl_export - Permanently export a mapped device via the ioctl interface + * @md: Pointer to mapped_device + * @name: Buffer (size DM_NAME_LEN) for name + * @uuid: Buffer (size DM_UUID_LEN) for uuid or NULL if not desired + */ +int dm_ioctl_export(struct mapped_device *md, const char *name, + const char *uuid) +{ + int r = 0; + struct hash_cell *hc; + + if (!md) { + r = -ENXIO; + goto out; + } + + /* The name and uuid can only be set once. */ + mutex_lock(&dm_hash_cells_mutex); + hc = dm_get_mdptr(md); + mutex_unlock(&dm_hash_cells_mutex); + if (hc) { + DMERR("%s: already exported", dm_device_name(md)); + r = -ENXIO; + goto out; + } + + r = dm_hash_insert(name, uuid, md); + if (r) { + DMERR("%s: could not bind to '%s'", dm_device_name(md), name); + goto out; + } + + /* Let udev know we've changed. */ + dm_kobject_uevent(md, KOBJ_CHANGE, dm_get_event_nr(md)); +out: + return r; +} /** * dm_copy_name_and_uuid - Copy mapped device name & uuid into supplied buffers * @md: Pointer to mapped_device diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index cb5d0daf53bb..b3d78bba3a79 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -11,6 +11,7 @@ #include <linux/vmalloc.h> #include <linux/blkdev.h> #include <linux/namei.h> +#include <linux/mount.h> #include <linux/ctype.h> #include <linux/string.h> #include <linux/slab.h> diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c index e0d6977b24a6..106d76aae3bb 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c +++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c @@ -2344,21 +2344,19 @@ static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev, return -EINVAL; } - if (!new_frame->partial_frame_indicator) { - if (cpp_frame_msg[new_frame->msg_len - 1] != - MSM_CPP_MSG_ID_TRAILER) { - pr_err("Invalid frame message\n"); - return -EINVAL; - } + if (cpp_frame_msg[new_frame->msg_len - 1] != + MSM_CPP_MSG_ID_TRAILER) { + pr_err("Invalid frame message\n"); + return -EINVAL; + } - if ((stripe_base + new_frame->num_strips * stripe_size + 1) != - new_frame->msg_len) { - pr_err("Invalid frame message,len=%d,expected=%d\n", - new_frame->msg_len, - (stripe_base + - new_frame->num_strips * stripe_size + 1)); - return -EINVAL; - } + if ((stripe_base + new_frame->num_strips * stripe_size + 1) != + new_frame->msg_len) { + pr_err("Invalid frame message,len=%d,expected=%d\n", + new_frame->msg_len, + (stripe_base + + new_frame->num_strips * stripe_size + 1)); + return -EINVAL; } if (cpp_dev->iommu_state != CPP_IOMMU_STATE_ATTACHED) { diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c index 3671d5fa6479..e612c6ed11c7 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_common.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c @@ -3705,6 +3705,10 @@ static void log_frame(struct msm_vidc_inst *inst, struct vidc_frame_data *data, if (msm_comm_scale_clocks(inst->core)) dprintk(VIDC_WARN, "Failed to scale clocks. Performance might be impacted\n"); + + if (msm_comm_vote_bus(inst->core)) + dprintk(VIDC_WARN, + "Failed to scale bus. Performance might be impacted\n"); } static int request_seq_header(struct msm_vidc_inst *inst, diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c index efb90c69881f..011941c6d4eb 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_debug.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c @@ -157,7 +157,7 @@ struct dentry *msm_vidc_debugfs_init_drv(void) struct dentry *f = debugfs_create_##__type(__name, S_IRUGO | S_IWUSR, \ dir, __value); \ if (IS_ERR_OR_NULL(f)) { \ - dprintk(VIDC_ERR, "Failed creating debugfs file '%pKd/%s'\n", \ + dprintk(VIDC_ERR, "Failed creating debugfs file '%pd/%s'\n", \ dir, __name); \ f = NULL; \ } \ @@ -349,7 +349,7 @@ struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst, dprintk(VIDC_ERR, "Invalid params, inst: %pK\n", inst); goto failed_create_dir; } - snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%pK", inst); + snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%p", inst); dir = debugfs_create_dir(debugfs_name, parent); if (!dir) { dprintk(VIDC_ERR, "Failed to create debugfs for msm_vidc\n"); diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c index 43188c9d690e..5cb017fdf2d3 100644 --- a/drivers/platform/msm/usb_bam.c +++ b/drivers/platform/msm/usb_bam.c @@ -1323,6 +1323,9 @@ static void usb_bam_finish_suspend(enum usb_ctrl cur_bam) __func__, ret); goto no_lpm; } + } else { + log_event_err("%s: pipe type is not B2B\n", __func__); + cons_empty = true; } spin_lock(&usb_bam_ipa_handshake_info_lock); @@ -1959,8 +1962,8 @@ static void usb_bam_finish_resume(struct work_struct *w) spin_unlock(&usb_bam_ipa_handshake_info_lock); mutex_unlock(&info[cur_bam].suspend_resume_mutex); - log_event_dbg("%s: done..PM Runtime PUT %d, count: %d\n", - __func__, idx, get_pm_runtime_counter(bam_dev)); + log_event_dbg("%s: done..PM Runtime PUT :%d\n", + __func__, get_pm_runtime_counter(bam_dev)); /* Put to match _get at the beginning of this routine */ pm_runtime_put(&ctx->usb_bam_pdev->dev); } @@ -2762,16 +2765,14 @@ static void usb_bam_sps_events(enum sps_callback_case sps_cb_case, void *user) log_event_dbg("%s: received SPS_CALLBACK_BAM_TIMER_IRQ\n", __func__); - spin_lock(&ctx->usb_bam_lock); - bam = get_bam_type_from_core_name((char *)user); if (bam < 0 || bam >= MAX_BAMS) { log_event_err("%s: Invalid bam, type=%d ,name=%s\n", __func__, bam, (char *)user); - spin_unlock(&ctx->usb_bam_lock); return; } ctx = &msm_usb_bam[bam]; + spin_lock(&ctx->usb_bam_lock); ctx->is_bam_inactivity = true; log_event_dbg("%s: Inactivity happened on bam=%s,%d\n", diff --git a/drivers/power/reset/msm-poweroff.c b/drivers/power/reset/msm-poweroff.c index 2f109013f723..d32f293695bb 100644 --- a/drivers/power/reset/msm-poweroff.c +++ b/drivers/power/reset/msm-poweroff.c @@ -380,7 +380,6 @@ static void do_msm_restart(enum reboot_mode reboot_mode, const char *cmd) msm_trigger_wdog_bite(); #endif - scm_disable_sdi(); halt_spmi_pmic_arbiter(); deassert_ps_hold(); diff --git a/drivers/soc/qcom/wcd-dsp-glink.c b/drivers/soc/qcom/wcd-dsp-glink.c index 97d922fa5724..6bc815862541 100644 --- a/drivers/soc/qcom/wcd-dsp-glink.c +++ b/drivers/soc/qcom/wcd-dsp-glink.c @@ -161,8 +161,8 @@ static void wdsp_glink_notify_rx(void *handle, const void *priv, wpriv->rsp_cnt = ++rsp_cnt; mutex_unlock(&wpriv->rsp_mutex); - complete(&wpriv->rsp_complete); glink_rx_done(handle, ptr, true); + complete(&wpriv->rsp_complete); } /* diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c index b8bf80f02f4c..43d3f92cd418 100644 --- a/drivers/staging/android/ion/ion_heap.c +++ b/drivers/staging/android/ion/ion_heap.c @@ -2,7 +2,7 @@ * drivers/staging/android/ion/ion_heap.c * * Copyright (C) 2011 Google, Inc. - * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -325,8 +325,9 @@ struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data) switch (heap_data->type) { case ION_HEAP_TYPE_SYSTEM_CONTIG: - heap = ion_system_contig_heap_create(heap_data); - break; + pr_err("%s: Heap type is disabled: %d\n", __func__, + heap_data->type); + return ERR_PTR(-EINVAL); case ION_HEAP_TYPE_SYSTEM: heap = ion_system_heap_create(heap_data); break; @@ -366,7 +367,8 @@ void ion_heap_destroy(struct ion_heap *heap) switch (heap->type) { case ION_HEAP_TYPE_SYSTEM_CONTIG: - ion_system_contig_heap_destroy(heap); + pr_err("%s: Heap type is disabled: %d\n", __func__, + heap->type); break; case ION_HEAP_TYPE_SYSTEM: ion_system_heap_destroy(heap); diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c index 0316f4e86d39..bcd23d3c19f2 100644 --- a/drivers/video/fbdev/msm/mdss_fb.c +++ b/drivers/video/fbdev/msm/mdss_fb.c @@ -2703,7 +2703,9 @@ static int mdss_fb_release_all(struct fb_info *info, bool release_all) * enabling ahead of unblank. for some special cases like * adb shell stop/start. */ + mutex_lock(&mfd->bl_lock); mdss_fb_set_backlight(mfd, 0); + mutex_unlock(&mfd->bl_lock); ret = mdss_fb_blank_sub(FB_BLANK_POWERDOWN, info, mfd->op_enable); diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 010b5ad2ac5d..5c720864db89 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -383,6 +383,12 @@ void dm_set_mdptr(struct mapped_device *md, void *ptr); void *dm_get_mdptr(struct mapped_device *md); /* + * Export the device via the ioctl interface (uses mdptr). + */ +int dm_ioctl_export(struct mapped_device *md, const char *name, + const char *uuid); + +/* * A device can still be used while suspended, but I/O is deferred. */ int dm_suspend(struct mapped_device *md, unsigned suspend_flags); diff --git a/include/trace/events/power.h b/include/trace/events/power.h index e8bc27f3467e..bc33e91ec5e6 100644 --- a/include/trace/events/power.h +++ b/include/trace/events/power.h @@ -369,15 +369,17 @@ TRACE_EVENT(clock_set_parent, TRACE_EVENT(clock_state, TP_PROTO(const char *name, unsigned long prepare_count, - unsigned long count, unsigned long rate), + unsigned long count, unsigned long rate, + unsigned int vdd_level), - TP_ARGS(name, prepare_count, count, rate), + TP_ARGS(name, prepare_count, count, rate, vdd_level), TP_STRUCT__entry( __string(name, name) __field(unsigned long, prepare_count) __field(unsigned long, count) __field(unsigned long, rate) + __field(unsigned int, vdd_level) ), TP_fast_assign( @@ -385,10 +387,12 @@ TRACE_EVENT(clock_state, __entry->prepare_count = prepare_count; __entry->count = count; __entry->rate = rate; + __entry->vdd_level = vdd_level; ), - TP_printk("%s\t[%lu:%lu]\t%lu", __get_str(name), __entry->prepare_count, - __entry->count, __entry->rate) + TP_printk("%s\tprepare:enable cnt [%lu:%lu]\trate: vdd level [%lu:%u]", + __get_str(name), __entry->prepare_count, + __entry->count, __entry->rate, __entry->vdd_level) ); /* diff --git a/init/Makefile b/init/Makefile index 692b91f1c1d4..243f61de2cba 100644 --- a/init/Makefile +++ b/init/Makefile @@ -15,6 +15,7 @@ mounts-y := do_mounts.o mounts-$(CONFIG_BLK_DEV_RAM) += do_mounts_rd.o mounts-$(CONFIG_BLK_DEV_INITRD) += do_mounts_initrd.o mounts-$(CONFIG_BLK_DEV_MD) += do_mounts_md.o +mounts-$(CONFIG_BLK_DEV_DM) += do_mounts_dm.o # dependencies on generated files need to be listed explicitly $(obj)/version.o: include/generated/compile.h diff --git a/init/do_mounts.c b/init/do_mounts.c index dea5de95c2dd..1902a1c80831 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -566,6 +566,7 @@ void __init prepare_namespace(void) wait_for_device_probe(); md_run_setup(); + dm_run_setup(); if (saved_root_name[0]) { root_device_name = saved_root_name; diff --git a/init/do_mounts.h b/init/do_mounts.h index 375835f1d258..09d22862e8c3 100644 --- a/init/do_mounts.h +++ b/init/do_mounts.h @@ -13,9 +13,6 @@ void mount_block_root(char *name, int flags); void mount_root(void); extern int root_mountflags; -struct dm_table; -static inline void dm_table_put(struct dm_table *t) { } - static inline int create_dev(char *name, dev_t dev) { sys_unlink(name); @@ -77,3 +74,13 @@ void md_run_setup(void); static inline void md_run_setup(void) {} #endif + +#ifdef CONFIG_BLK_DEV_DM + +void dm_run_setup(void); + +#else + +static inline void dm_run_setup(void) {} + +#endif diff --git a/init/do_mounts_dm.c b/init/do_mounts_dm.c new file mode 100644 index 000000000000..f521bc5ae248 --- /dev/null +++ b/init/do_mounts_dm.c @@ -0,0 +1,425 @@ +/* do_mounts_dm.c + * Copyright (C) 2010 The Chromium OS Authors <chromium-os-dev@chromium.org> + * All Rights Reserved. + * Based on do_mounts_md.c + * + * This file is released under the GPL. + */ +#include <linux/device-mapper.h> +#include <linux/fs.h> +#include <linux/string.h> + +#include "do_mounts.h" +#include "../drivers/md/dm.h" + +#define DM_MAX_NAME 32 +#define DM_MAX_UUID 129 +#define DM_NO_UUID "none" + +#define DM_MSG_PREFIX "init" + +/* Separators used for parsing the dm= argument. */ +#define DM_FIELD_SEP ' ' +#define DM_LINE_SEP ',' + +/* + * When the device-mapper and any targets are compiled into the kernel + * (not a module), one target may be created and used as the root device at + * boot time with the parameters given with the boot line dm=... + * The code for that is here. + */ + +struct dm_setup_target { + sector_t begin; + sector_t length; + char *type; + char *params; + /* simple singly linked list */ + struct dm_setup_target *next; +}; + +static struct { + int minor; + int ro; + char name[DM_MAX_NAME]; + char uuid[DM_MAX_UUID]; + char *targets; + struct dm_setup_target *target; + int target_count; +} dm_setup_args __initdata; + +static __initdata int dm_early_setup; + +static size_t __init get_dm_option(char *str, char **next, char sep) +{ + size_t len = 0; + char *endp = NULL; + + if (!str) + return 0; + + endp = strchr(str, sep); + if (!endp) { /* act like strchrnul */ + len = strlen(str); + endp = str + len; + } else { + len = endp - str; + } + + if (endp == str) + return 0; + + if (!next) + return len; + + if (*endp == 0) { + /* Don't advance past the nul. */ + *next = endp; + } else { + *next = endp + 1; + } + return len; +} + +static int __init dm_setup_args_init(void) +{ + dm_setup_args.minor = 0; + dm_setup_args.ro = 0; + dm_setup_args.target = NULL; + dm_setup_args.target_count = 0; + return 0; +} + +static int __init dm_setup_cleanup(void) +{ + struct dm_setup_target *target = dm_setup_args.target; + struct dm_setup_target *old_target = NULL; + while (target) { + kfree(target->type); + kfree(target->params); + old_target = target; + target = target->next; + kfree(old_target); + dm_setup_args.target_count--; + } + BUG_ON(dm_setup_args.target_count); + return 0; +} + +static char * __init dm_setup_parse_device_args(char *str) +{ + char *next = NULL; + size_t len = 0; + + /* Grab the logical name of the device to be exported to udev */ + len = get_dm_option(str, &next, DM_FIELD_SEP); + if (!len) { + DMERR("failed to parse device name"); + goto parse_fail; + } + len = min(len + 1, sizeof(dm_setup_args.name)); + strlcpy(dm_setup_args.name, str, len); /* includes nul */ + str = skip_spaces(next); + + /* Grab the UUID value or "none" */ + len = get_dm_option(str, &next, DM_FIELD_SEP); + if (!len) { + DMERR("failed to parse device uuid"); + goto parse_fail; + } + len = min(len + 1, sizeof(dm_setup_args.uuid)); + strlcpy(dm_setup_args.uuid, str, len); + str = skip_spaces(next); + + /* Determine if the table/device will be read only or read-write */ + if (!strncmp("ro,", str, 3)) { + dm_setup_args.ro = 1; + } else if (!strncmp("rw,", str, 3)) { + dm_setup_args.ro = 0; + } else { + DMERR("failed to parse table mode"); + goto parse_fail; + } + str = skip_spaces(str + 3); + + return str; + +parse_fail: + return NULL; +} + +static void __init dm_substitute_devices(char *str, size_t str_len) +{ + char *candidate = str; + char *candidate_end = str; + char old_char; + size_t len = 0; + dev_t dev; + + if (str_len < 3) + return; + + while (str && *str) { + candidate = strchr(str, '/'); + if (!candidate) + break; + + /* Avoid embedded slashes */ + if (candidate != str && *(candidate - 1) != DM_FIELD_SEP) { + str = strchr(candidate, DM_FIELD_SEP); + continue; + } + + len = get_dm_option(candidate, &candidate_end, DM_FIELD_SEP); + str = skip_spaces(candidate_end); + if (len < 3 || len > 37) /* name_to_dev_t max; maj:mix min */ + continue; + + /* Temporarily terminate with a nul */ + candidate_end--; + old_char = *candidate_end; + *candidate_end = '\0'; + + DMDEBUG("converting candidate device '%s' to dev_t", candidate); + /* Use the boot-time specific device naming */ + dev = name_to_dev_t(candidate); + *candidate_end = old_char; + + DMDEBUG(" -> %u", dev); + /* No suitable replacement found */ + if (!dev) + continue; + + /* Rewrite the /dev/path as a major:minor */ + len = snprintf(candidate, len, "%u:%u", MAJOR(dev), MINOR(dev)); + if (!len) { + DMERR("error substituting device major/minor."); + break; + } + candidate += len; + /* Pad out with spaces (fixing our nul) */ + while (candidate < candidate_end) + *(candidate++) = DM_FIELD_SEP; + } +} + +static int __init dm_setup_parse_targets(char *str) +{ + char *next = NULL; + size_t len = 0; + struct dm_setup_target **target = NULL; + + /* Targets are defined as per the table format but with a + * comma as a newline separator. */ + target = &dm_setup_args.target; + while (str && *str) { + *target = kzalloc(sizeof(struct dm_setup_target), GFP_KERNEL); + if (!*target) { + DMERR("failed to allocate memory for target %d", + dm_setup_args.target_count); + goto parse_fail; + } + dm_setup_args.target_count++; + + (*target)->begin = simple_strtoull(str, &next, 10); + if (!next || *next != DM_FIELD_SEP) { + DMERR("failed to parse starting sector for target %d", + dm_setup_args.target_count - 1); + goto parse_fail; + } + str = skip_spaces(next + 1); + + (*target)->length = simple_strtoull(str, &next, 10); + if (!next || *next != DM_FIELD_SEP) { + DMERR("failed to parse length for target %d", + dm_setup_args.target_count - 1); + goto parse_fail; + } + str = skip_spaces(next + 1); + + len = get_dm_option(str, &next, DM_FIELD_SEP); + if (!len || + !((*target)->type = kstrndup(str, len, GFP_KERNEL))) { + DMERR("failed to parse type for target %d", + dm_setup_args.target_count - 1); + goto parse_fail; + } + str = skip_spaces(next); + + len = get_dm_option(str, &next, DM_LINE_SEP); + if (!len || + !((*target)->params = kstrndup(str, len, GFP_KERNEL))) { + DMERR("failed to parse params for target %d", + dm_setup_args.target_count - 1); + goto parse_fail; + } + str = skip_spaces(next); + + /* Before moving on, walk through the copied target and + * attempt to replace all /dev/xxx with the major:minor number. + * It may not be possible to resolve them traditionally at + * boot-time. */ + dm_substitute_devices((*target)->params, len); + + target = &((*target)->next); + } + DMDEBUG("parsed %d targets", dm_setup_args.target_count); + + return 0; + +parse_fail: + return 1; +} + +/* + * Parse the command-line parameters given our kernel, but do not + * actually try to invoke the DM device now; that is handled by + * dm_setup_drive after the low-level disk drivers have initialised. + * dm format is as follows: + * dm="name uuid fmode,[table line 1],[table line 2],..." + * May be used with root=/dev/dm-0 as it always uses the first dm minor. + */ + +static int __init dm_setup(char *str) +{ + dm_setup_args_init(); + + str = dm_setup_parse_device_args(str); + if (!str) { + DMDEBUG("str is NULL"); + goto parse_fail; + } + + /* Target parsing is delayed until we have dynamic memory */ + dm_setup_args.targets = str; + + printk(KERN_INFO "dm: will configure '%s' on dm-%d\n", + dm_setup_args.name, dm_setup_args.minor); + + dm_early_setup = 1; + return 1; + +parse_fail: + printk(KERN_WARNING "dm: Invalid arguments supplied to dm=.\n"); + return 0; +} + + +static void __init dm_setup_drive(void) +{ + struct mapped_device *md = NULL; + struct dm_table *table = NULL; + struct dm_setup_target *target; + char *uuid = dm_setup_args.uuid; + fmode_t fmode = FMODE_READ; + + /* Finish parsing the targets. */ + if (dm_setup_parse_targets(dm_setup_args.targets)) + goto parse_fail; + + if (dm_create(dm_setup_args.minor, &md)) { + DMDEBUG("failed to create the device"); + goto dm_create_fail; + } + DMDEBUG("created device '%s'", dm_device_name(md)); + + /* In addition to flagging the table below, the disk must be + * set explicitly ro/rw. */ + set_disk_ro(dm_disk(md), dm_setup_args.ro); + + if (!dm_setup_args.ro) + fmode |= FMODE_WRITE; + if (dm_table_create(&table, fmode, dm_setup_args.target_count, md)) { + DMDEBUG("failed to create the table"); + goto dm_table_create_fail; + } + + dm_lock_md_type(md); + target = dm_setup_args.target; + while (target) { + DMINFO("adding target '%llu %llu %s %s'", + (unsigned long long) target->begin, + (unsigned long long) target->length, target->type, + target->params); + if (dm_table_add_target(table, target->type, target->begin, + target->length, target->params)) { + DMDEBUG("failed to add the target to the table"); + goto add_target_fail; + } + target = target->next; + } + + if (dm_table_complete(table)) { + DMDEBUG("failed to complete the table"); + goto table_complete_fail; + } + + if (dm_get_md_type(md) == DM_TYPE_NONE) { + dm_set_md_type(md, dm_table_get_type(table)); + if (dm_setup_md_queue(md)) { + DMWARN("unable to set up device queue for new table."); + goto setup_md_queue_fail; + } + } else if (dm_get_md_type(md) != dm_table_get_type(table)) { + DMWARN("can't change device type after initial table load."); + goto setup_md_queue_fail; + } + + /* Suspend the device so that we can bind it to the table. */ + if (dm_suspend(md, 0)) { + DMDEBUG("failed to suspend the device pre-bind"); + goto suspend_fail; + } + + /* Bind the table to the device. This is the only way to associate + * md->map with the table and set the disk capacity directly. */ + if (dm_swap_table(md, table)) { /* should return NULL. */ + DMDEBUG("failed to bind the device to the table"); + goto table_bind_fail; + } + + /* Finally, resume and the device should be ready. */ + if (dm_resume(md)) { + DMDEBUG("failed to resume the device"); + goto resume_fail; + } + + /* Export the dm device via the ioctl interface */ + if (!strcmp(DM_NO_UUID, dm_setup_args.uuid)) + uuid = NULL; + if (dm_ioctl_export(md, dm_setup_args.name, uuid)) { + DMDEBUG("failed to export device with given name and uuid"); + goto export_fail; + } + printk(KERN_INFO "dm: dm-%d is ready\n", dm_setup_args.minor); + + dm_unlock_md_type(md); + dm_setup_cleanup(); + return; + +export_fail: +resume_fail: +table_bind_fail: +suspend_fail: +setup_md_queue_fail: +table_complete_fail: +add_target_fail: + dm_unlock_md_type(md); +dm_table_create_fail: + dm_put(md); +dm_create_fail: + dm_setup_cleanup(); +parse_fail: + printk(KERN_WARNING "dm: starting dm-%d (%s) failed\n", + dm_setup_args.minor, dm_setup_args.name); +} + +__setup("dm=", dm_setup); + +void __init dm_run_setup(void) +{ + if (!dm_early_setup) + return; + printk(KERN_INFO "dm: attempting early device configuration.\n"); + dm_setup_drive(); +} diff --git a/sound/soc/codecs/wcd934x/wcd934x.c b/sound/soc/codecs/wcd934x/wcd934x.c index 5d6119c6d86a..d77217892f12 100644 --- a/sound/soc/codecs/wcd934x/wcd934x.c +++ b/sound/soc/codecs/wcd934x/wcd934x.c @@ -5136,7 +5136,7 @@ static int tavil_mad_input_put(struct snd_kcontrol *kcontrol, snd_soc_update_bits(codec, WCD934X_SOC_MAD_INP_SEL, 0x0F, tavil_mad_input); snd_soc_update_bits(codec, WCD934X_ANA_MAD_SETUP, - 0x03, mic_bias_found); + 0x07, mic_bias_found); return 0; } |
