Merge "coresight-hwevent: Change naming convention for clock" into msm-4.9
diff --git a/Documentation/devicetree/bindings/arm/msm/wil6210.txt b/Documentation/devicetree/bindings/arm/msm/wil6210.txt
index b381bdeb..c467327 100644
--- a/Documentation/devicetree/bindings/arm/msm/wil6210.txt
+++ b/Documentation/devicetree/bindings/arm/msm/wil6210.txt
@@ -10,6 +10,10 @@
- compatible: "qcom,wil6210"
- qcom,smmu-support: Boolean flag indicating whether PCIe has SMMU support
+- qcom,smmu-s1-en: Boolean flag indicating whether SMMU stage1 should be enabled
+- qcom,smmu-fast-map: Boolean flag indicating whether SMMU fast mapping should be enabled
+- qcom,smmu-coherent: Boolean flag indicating SMMU dma and page table coherency
+- qcom,smmu-mapping: specifies the base address and size of SMMU space
- qcom,pcie-parent: phandle for the PCIe root complex to which 11ad card is connected
- Refer to "Documentation/devicetree/bindings/arm/msm/msm_bus.txt" for
the below optional properties:
@@ -33,6 +37,10 @@
wil6210: qcom,wil6210 {
compatible = "qcom,wil6210";
qcom,smmu-support;
+ qcom,smmu-s1-en;
+ qcom,smmu-fast-map;
+ qcom,smmu-coherent;
+ qcom,smmu-mapping = <0x20000000 0xe0000000>;
qcom,pcie-parent = <&pcie1>;
qcom,wigig-en = <&tlmm 94 0>;
qcom,msm-bus,name = "wil6210";
diff --git a/Documentation/devicetree/bindings/power/supply/qcom/smb1355-charger.txt b/Documentation/devicetree/bindings/power/supply/qcom/smb1355-charger.txt
new file mode 100644
index 0000000..ca584e5
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/supply/qcom/smb1355-charger.txt
@@ -0,0 +1,73 @@
+Qualcomm Technologies, Inc. SMB1355 Charger Specific Bindings
+
+SMB1355 slave charger is paired with QTI family of standalone chargers to
+enable a high current, low profile Li+ battery charging system.
+
+The device provides 28V DC withstand, wide operating input range of 3.8 to
+14.2V for standard 5V USB inputs as well as a wide variety of HVDCP Travel
+Adapters and is compatible with QTI's Quick Charge technology.
+
+=======================
+Required Node Structure
+=======================
+
+SMB1355 Charger must be described in two levels of device nodes.
+
+==================================
+First Level Node - SMB1355 Charger
+==================================
+
+Charger specific properties:
+- compatible
+ Usage: required
+ Value type: <string>
+ Definition: "qcom,smb1355".
+
+- qcom,pmic-revid
+ Usage: required
+ Value type: phandle
+ Definition: Should specify the phandle of SMB's revid module. This is used
+ to identify the SMB subtype.
+
+================================================
+Second Level Nodes - SMB1355 Charger Peripherals
+================================================
+
+Peripheral specific properties:
+- reg
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: Address and size of the peripheral's register block.
+
+- interrupts
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: Peripheral interrupt specifier.
+
+- interrupt-names
+ Usage: required
+ Value type: <stringlist>
+ Definition: Interrupt names. This list must match up 1-to-1 with the
+ interrupts specified in the 'interrupts' property.
+
+=======
+Example
+=======
+
+smb1355_charger: qcom,smb1355-charger {
+ compatible = "qcom,smb1355";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ qcom,chgr@1000 {
+ reg = <0x1000 0x100>;
+ interrupts = <0x10 0x1 IRQ_TYPE_EDGE_BOTH>;
+ interrupt-names = "chg-state-change";
+ };
+
+ qcom,chgr-misc@1600 {
+ reg = <0x1600 0x100>;
+ interrupts = <0x16 0x1 IRQ_TYPE_EDGE_BOTH>;
+ interrupt-names = "wdog-bark";
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm845-mtp.dtsi
index 715b566..d316d63 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dtsi
@@ -12,6 +12,7 @@
#include <dt-bindings/gpio/gpio.h>
#include "sdm845-camera-sensor-mtp.dtsi"
+#include "smb1355.dtsi"
/ {
bluetooth: bt_wcn3990 {
@@ -203,6 +204,10 @@
qcom,battery-data = <&mtp_batterydata>;
};
+&smb1355_charger {
+ status = "ok";
+};
+
/ {
aliases {
serial0 = &qupv3_se9_2uart;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-qrd.dtsi b/arch/arm64/boot/dts/qcom/sdm845-qrd.dtsi
index a4dc4753..e21ed36 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-qrd.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-qrd.dtsi
@@ -10,6 +10,8 @@
* GNU General Public License for more details.
*/
+#include "smb1355.dtsi"
+
/{
qrd_batterydata: qcom,battery-data {
qcom,batt-id-range-pct = <15>;
@@ -22,6 +24,10 @@
qcom,battery-data = <&qrd_batterydata>;
};
+&smb1355_charger {
+ status = "ok";
+};
+
&mdss_mdp {
#cooling-cells = <2>;
};
diff --git a/arch/arm64/boot/dts/qcom/smb1355.dtsi b/arch/arm64/boot/dts/qcom/smb1355.dtsi
new file mode 100644
index 0000000..33c5e97
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/smb1355.dtsi
@@ -0,0 +1,55 @@
+/* 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
+ * 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 <dt-bindings/interrupt-controller/irq.h>
+
+&qupv3_se10_i2c {
+ smb1355: qcom,smb1355@8 {
+ compatible = "qcom,i2c-pmic";
+ reg = <0x8>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&spmi_bus>;
+ interrupts = <0x0 0xd1 0x0 IRQ_TYPE_LEVEL_LOW>;
+ interrupt_names = "smb1355";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ qcom,periph-map = <0x10 0x12 0x13 0x16>;
+
+ smb1355_revid: qcom,revid@100 {
+ compatible = "qcom,qpnp-revid";
+ reg = <0x100 0x100>;
+ };
+
+ smb1355_charger: qcom,smb1355-charger@1000 {
+ compatible = "qcom,smb1355";
+ qcom,pmic-revid = <&smb1355_revid>;
+ reg = <0x1000 0x700>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&smb1355>;
+ status = "disabled";
+
+ qcom,chgr@1000 {
+ reg = <0x1000 0x100>;
+ interrupts = <0x10 0x1 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "chg-state-change";
+ };
+
+ qcom,chgr-misc@1600 {
+ reg = <0x1600 0x100>;
+ interrupts = <0x16 0x1 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "wdog-bark";
+ };
+ };
+ };
+};
diff --git a/arch/arm64/configs/sdm845-perf_defconfig b/arch/arm64/configs/sdm845-perf_defconfig
index f989858..531d236 100644
--- a/arch/arm64/configs/sdm845-perf_defconfig
+++ b/arch/arm64/configs/sdm845-perf_defconfig
@@ -300,8 +300,8 @@
CONFIG_POWER_RESET_XGENE=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_QPNP_FG_GEN3=y
+CONFIG_SMB1355_SLAVE_CHARGER=y
CONFIG_QPNP_SMB2=y
-CONFIG_SMB138X_CHARGER=y
CONFIG_QPNP_QNOVO=y
CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
CONFIG_THERMAL=y
diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig
index 7136ca8..cbcf515 100644
--- a/arch/arm64/configs/sdm845_defconfig
+++ b/arch/arm64/configs/sdm845_defconfig
@@ -309,8 +309,8 @@
CONFIG_POWER_RESET_XGENE=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_QPNP_FG_GEN3=y
+CONFIG_SMB1355_SLAVE_CHARGER=y
CONFIG_QPNP_SMB2=y
-CONFIG_SMB138X_CHARGER=y
CONFIG_QPNP_QNOVO=y
CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
CONFIG_THERMAL=y
diff --git a/drivers/gpu/drm/msm/msm_rd.c b/drivers/gpu/drm/msm/msm_rd.c
index 8487f46..3c3f335 100644
--- a/drivers/gpu/drm/msm/msm_rd.c
+++ b/drivers/gpu/drm/msm/msm_rd.c
@@ -105,9 +105,13 @@
static void rd_write(struct msm_rd_state *rd, const void *buf, int sz)
{
- struct circ_buf *fifo = &rd->fifo;
+ struct circ_buf *fifo;
const char *ptr = buf;
+ if (!rd || !buf)
+ return;
+
+ fifo = &rd->fifo;
while (sz > 0) {
char *fptr = &fifo->buf[fifo->head];
int n;
@@ -136,11 +140,18 @@
static ssize_t rd_read(struct file *file, char __user *buf,
size_t sz, loff_t *ppos)
{
- struct msm_rd_state *rd = file->private_data;
- struct circ_buf *fifo = &rd->fifo;
- const char *fptr = &fifo->buf[fifo->tail];
+ struct msm_rd_state *rd;
+ struct circ_buf *fifo;
+ const char *fptr;
int n = 0, ret = 0;
+ if (!file || !file->private_data || !buf || !ppos)
+ return -EINVAL;
+
+ rd = file->private_data;
+ fifo = &rd->fifo;
+ fptr = &fifo->buf[fifo->tail];
+
mutex_lock(&rd->read_lock);
ret = wait_event_interruptible(rd->fifo_event,
@@ -168,19 +179,34 @@
static int rd_open(struct inode *inode, struct file *file)
{
- struct msm_rd_state *rd = inode->i_private;
- struct drm_device *dev = rd->dev;
- struct msm_drm_private *priv = dev->dev_private;
- struct msm_gpu *gpu = priv->gpu;
+ struct msm_rd_state *rd;
+ struct drm_device *dev;
+ struct msm_drm_private *priv;
+ struct msm_gpu *gpu;
uint64_t val;
uint32_t gpu_id;
int ret = 0;
+ if (!file || !inode || !inode->i_private)
+ return -EINVAL;
+
+ rd = inode->i_private;
+ dev = rd->dev;
+
+ if (!dev || !dev->dev_private)
+ return -EINVAL;
+
+ priv = dev->dev_private;
+ gpu = priv->gpu;
+
mutex_lock(&dev->struct_mutex);
if (rd->open || !gpu) {
ret = -EBUSY;
goto out;
+ } else if (!gpu->funcs || !gpu->funcs->get_param) {
+ ret = -EINVAL;
+ goto out;
}
file->private_data = rd;
@@ -201,7 +227,12 @@
static int rd_release(struct inode *inode, struct file *file)
{
- struct msm_rd_state *rd = inode->i_private;
+ struct msm_rd_state *rd;
+
+ if (!inode || !inode->i_private)
+ return -EINVAL;
+
+ rd = inode->i_private;
rd->open = false;
return 0;
}
@@ -217,9 +248,14 @@
int msm_rd_debugfs_init(struct drm_minor *minor)
{
- struct msm_drm_private *priv = minor->dev->dev_private;
+ struct msm_drm_private *priv;
struct msm_rd_state *rd;
+ if (!minor || !minor->dev || !minor->dev->dev_private)
+ return -EINVAL;
+
+ priv = minor->dev->dev_private;
+
/* only create on first minor: */
if (priv->rd)
return 0;
@@ -265,8 +301,14 @@
void msm_rd_debugfs_cleanup(struct drm_minor *minor)
{
- struct msm_drm_private *priv = minor->dev->dev_private;
- struct msm_rd_state *rd = priv->rd;
+ struct msm_drm_private *priv;
+ struct msm_rd_state *rd;
+
+ if (!minor || !minor->dev || !minor->dev->dev_private)
+ return;
+
+ priv = minor->dev->dev_private;
+ rd = priv->rd;
if (!rd)
return;
@@ -315,13 +357,20 @@
/* called under struct_mutex */
void msm_rd_dump_submit(struct msm_gem_submit *submit)
{
- struct drm_device *dev = submit->dev;
- struct msm_drm_private *priv = dev->dev_private;
- struct msm_rd_state *rd = priv->rd;
+ struct drm_device *dev;
+ struct msm_drm_private *priv;
+ struct msm_rd_state *rd;
char msg[128];
int i, n;
- if (!rd->open)
+ if (!submit || !submit->dev || !submit->dev->dev_private)
+ return;
+
+ dev = submit->dev;
+ priv = dev->dev_private;
+ rd = priv->rd;
+
+ if (!rd || !rd->open)
return;
/* writing into fifo is serialized by caller, and
diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c
index 7215fdf..6601c9a 100644
--- a/drivers/media/platform/msm/vidc/hfi_packetization.c
+++ b/drivers/media/platform/msm/vidc/hfi_packetization.c
@@ -1480,22 +1480,22 @@
pkt->size += sizeof(u32) + sizeof(struct hfi_enable);
break;
}
- case HAL_PARAM_VENC_H264_VUI_TIMING_INFO:
+ case HAL_PARAM_VENC_VUI_TIMING_INFO:
{
- struct hfi_h264_vui_timing_info *hfi;
- struct hal_h264_vui_timing_info *timing_info = pdata;
+ struct hfi_vui_timing_info *hfi;
+ struct hal_vui_timing_info *timing_info = pdata;
pkt->rg_property_data[0] =
- HFI_PROPERTY_PARAM_VENC_H264_VUI_TIMING_INFO;
+ HFI_PROPERTY_PARAM_VENC_VUI_TIMING_INFO;
- hfi = (struct hfi_h264_vui_timing_info *)&pkt->
+ hfi = (struct hfi_vui_timing_info *)&pkt->
rg_property_data[1];
hfi->enable = timing_info->enable;
hfi->fixed_frame_rate = timing_info->fixed_frame_rate;
hfi->time_scale = timing_info->time_scale;
pkt->size += sizeof(u32) +
- sizeof(struct hfi_h264_vui_timing_info);
+ sizeof(struct hfi_vui_timing_info);
break;
}
case HAL_CONFIG_VPE_DEINTERLACE:
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index c0b6683..f283b9d 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -988,6 +988,15 @@
(1 << V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_UNLIMITED)),
.qmenu = iframe_sizes,
},
+ {
+ .id = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE,
+ .name = "Frame Rate based Rate Control",
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 0,
+ .step = 1,
+ },
};
@@ -1131,6 +1140,7 @@
int max_hierp_layers;
int baselayerid = 0;
struct hal_video_signal_info signal_info = {0};
+ struct hal_vui_timing_info vui_timing_info = {0};
enum hal_iframesize_type iframesize_type = HAL_IFRAMESIZE_TYPE_DEFAULT;
if (!inst || !inst->core || !inst->core->device) {
@@ -1849,6 +1859,43 @@
ctrl->val);
pdata = &iframesize_type;
break;
+ case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
+ {
+ property_id = HAL_PARAM_VENC_DISABLE_RC_TIMESTAMP;
+ enable.enable = ctrl->val;
+ pdata = &enable;
+ break;
+ }
+ case V4L2_CID_MPEG_VIDC_VIDEO_VUI_TIMING_INFO:
+ {
+ struct v4l2_ctrl *rc_mode;
+ bool cfr = false;
+
+ property_id = HAL_PARAM_VENC_VUI_TIMING_INFO;
+ pdata = &vui_timing_info;
+
+ if (ctrl->val != V4L2_MPEG_VIDC_VIDEO_VUI_TIMING_INFO_ENABLED) {
+ vui_timing_info.enable = 0;
+ break;
+ }
+
+ rc_mode = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL);
+
+ switch (rc_mode->val) {
+ case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR:
+ case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR:
+ case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_CFR:
+ cfr = true;
+ break;
+ default:
+ cfr = false;
+ }
+
+ vui_timing_info.enable = 1;
+ vui_timing_info.fixed_frame_rate = cfr;
+ vui_timing_info.time_scale = NSEC_PER_SEC;
+ break;
+ }
default:
dprintk(VIDC_ERR, "Unsupported index: %x\n", ctrl->id);
rc = -ENOTSUPP;
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
index 8752378..474c2fb6 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
@@ -187,7 +187,7 @@
HAL_PARAM_VDEC_SYNC_FRAME_DECODE,
HAL_PARAM_VENC_H264_ENTROPY_CABAC_MODEL,
HAL_CONFIG_VENC_MAX_BITRATE,
- HAL_PARAM_VENC_H264_VUI_TIMING_INFO,
+ HAL_PARAM_VENC_VUI_TIMING_INFO,
HAL_PARAM_VENC_GENERATE_AUDNAL,
HAL_PARAM_BUFFER_ALLOC_MODE,
HAL_PARAM_VDEC_FRAME_ASSEMBLY,
@@ -813,7 +813,7 @@
};
-struct hal_h264_vui_timing_info {
+struct hal_vui_timing_info {
u32 enable;
u32 fixed_frame_rate;
u32 time_scale;
@@ -1036,7 +1036,7 @@
struct hal_codec_supported codec_supported;
struct hal_multi_view_select multi_view_select;
struct hal_timestamp_scale timestamp_scale;
- struct hal_h264_vui_timing_info h264_vui_timing_info;
+ struct hal_vui_timing_info vui_timing_info;
struct hal_preserve_text_quality preserve_text_quality;
struct hal_buffer_info buffer_info;
struct hal_buffer_alloc_mode buffer_alloc_mode;
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
index 77164be..81b4d91 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
@@ -283,7 +283,7 @@
(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01C)
#define HFI_PROPERTY_PARAM_VENC_VIDEO_SIGNAL_INFO \
(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01D)
-#define HFI_PROPERTY_PARAM_VENC_H264_VUI_TIMING_INFO \
+#define HFI_PROPERTY_PARAM_VENC_VUI_TIMING_INFO \
(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01E)
#define HFI_PROPERTY_PARAM_VENC_LOW_LATENCY_MODE \
(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x022)
@@ -589,7 +589,7 @@
u32 matrix_coeffs;
};
-struct hfi_h264_vui_timing_info {
+struct hfi_vui_timing_info {
u32 enable;
u32 fixed_frame_rate;
u32 time_scale;
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index e3f35bc..4e111cb 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -500,9 +500,9 @@
for (i = 0; i < request->n_ssids; i++) {
wil_dbg_misc(wil, "SSID[%d]", i);
- print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET,
- request->ssids[i].ssid,
- request->ssids[i].ssid_len);
+ wil_hex_dump_misc("SSID ", DUMP_PREFIX_OFFSET, 16, 1,
+ request->ssids[i].ssid,
+ request->ssids[i].ssid_len, true);
}
if (request->n_ssids)
@@ -539,8 +539,8 @@
}
if (request->ie_len)
- print_hex_dump_bytes("Scan IE ", DUMP_PREFIX_OFFSET,
- request->ie, request->ie_len);
+ wil_hex_dump_misc("Scan IE ", DUMP_PREFIX_OFFSET, 16, 1,
+ request->ie, request->ie_len, true);
else
wil_dbg_misc(wil, "Scan has no IE's\n");
@@ -764,6 +764,8 @@
rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn));
if (rc == 0) {
netif_carrier_on(ndev);
+ wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS);
+ wil->bss = bss;
/* Connect can take lots of time */
mod_timer(&wil->connect_timer,
jiffies + msecs_to_jiffies(2000));
@@ -792,6 +794,7 @@
return 0;
}
+ wil->locally_generated_disc = true;
rc = wmi_call(wil, WMI_DISCONNECT_CMDID, NULL, 0,
WMI_DISCONNECT_EVENTID, NULL, 0,
WIL6210_DISCONNECT_TO_MS);
@@ -845,7 +848,8 @@
*/
wil_dbg_misc(wil, "mgmt_tx\n");
- print_hex_dump_bytes("mgmt tx frame ", DUMP_PREFIX_OFFSET, buf, len);
+ wil_hex_dump_misc("mgmt tx frame ", DUMP_PREFIX_OFFSET, 16, 1, buf,
+ len, true);
cmd = kmalloc(sizeof(*cmd) + len, GFP_KERNEL);
if (!cmd) {
@@ -1178,18 +1182,18 @@
static void wil_print_bcon_data(struct cfg80211_beacon_data *b)
{
- print_hex_dump_bytes("head ", DUMP_PREFIX_OFFSET,
- b->head, b->head_len);
- print_hex_dump_bytes("tail ", DUMP_PREFIX_OFFSET,
- b->tail, b->tail_len);
- print_hex_dump_bytes("BCON IE ", DUMP_PREFIX_OFFSET,
- b->beacon_ies, b->beacon_ies_len);
- print_hex_dump_bytes("PROBE ", DUMP_PREFIX_OFFSET,
- b->probe_resp, b->probe_resp_len);
- print_hex_dump_bytes("PROBE IE ", DUMP_PREFIX_OFFSET,
- b->proberesp_ies, b->proberesp_ies_len);
- print_hex_dump_bytes("ASSOC IE ", DUMP_PREFIX_OFFSET,
- b->assocresp_ies, b->assocresp_ies_len);
+ wil_hex_dump_misc("head ", DUMP_PREFIX_OFFSET, 16, 1,
+ b->head, b->head_len, true);
+ wil_hex_dump_misc("tail ", DUMP_PREFIX_OFFSET, 16, 1,
+ b->tail, b->tail_len, true);
+ wil_hex_dump_misc("BCON IE ", DUMP_PREFIX_OFFSET, 16, 1,
+ b->beacon_ies, b->beacon_ies_len, true);
+ wil_hex_dump_misc("PROBE ", DUMP_PREFIX_OFFSET, 16, 1,
+ b->probe_resp, b->probe_resp_len, true);
+ wil_hex_dump_misc("PROBE IE ", DUMP_PREFIX_OFFSET, 16, 1,
+ b->proberesp_ies, b->proberesp_ies_len, true);
+ wil_hex_dump_misc("ASSOC IE ", DUMP_PREFIX_OFFSET, 16, 1,
+ b->assocresp_ies, b->assocresp_ies_len, true);
}
/* internal functions for device reset and starting AP */
@@ -1283,6 +1287,7 @@
wil->pbss = pbss;
netif_carrier_on(ndev);
+ wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS);
rc = wmi_pcp_start(wil, bi, wmi_nettype, chan, hidden_ssid, is_go);
if (rc)
@@ -1298,6 +1303,7 @@
wmi_pcp_stop(wil);
err_pcp_start:
netif_carrier_off(ndev);
+ wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
out:
mutex_unlock(&wil->mutex);
return rc;
@@ -1383,8 +1389,8 @@
wil_dbg_misc(wil, "BI %d DTIM %d\n", info->beacon_interval,
info->dtim_period);
wil_dbg_misc(wil, "PBSS %d\n", info->pbss);
- print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET,
- info->ssid, info->ssid_len);
+ wil_hex_dump_misc("SSID ", DUMP_PREFIX_OFFSET, 16, 1,
+ info->ssid, info->ssid_len, true);
wil_print_bcon_data(bcon);
wil_print_crypto(wil, crypto);
@@ -1404,6 +1410,7 @@
wil_dbg_misc(wil, "stop_ap\n");
netif_carrier_off(ndev);
+ wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
wil_set_recovery_state(wil, fw_recovery_idle);
mutex_lock(&wil->mutex);
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index 3e8cdf1..5648ebb 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -524,9 +524,8 @@
if (!buf)
return -ENOMEM;
- wil_memcpy_fromio_halp_vote(wil_blob->wil, buf,
- (const volatile void __iomem *)
- wil_blob->blob.data + pos, count);
+ wil_memcpy_fromio_32(buf, (const void __iomem *)
+ wil_blob->blob.data + pos, count);
ret = copy_to_user(user_buf, buf, count);
kfree(buf);
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 2c48419..36959a3 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -30,8 +30,8 @@
module_param(debug_fw, bool, 0444);
MODULE_PARM_DESC(debug_fw, " do not perform card reset. For FW debug");
-static bool oob_mode;
-module_param(oob_mode, bool, 0444);
+static u8 oob_mode;
+module_param(oob_mode, byte, 0444);
MODULE_PARM_DESC(oob_mode,
" enable out of the box (OOB) mode in FW, for diagnostics and certification");
@@ -135,14 +135,6 @@
*d++ = __raw_readl(s++);
}
-void wil_memcpy_fromio_halp_vote(struct wil6210_priv *wil, void *dst,
- const volatile void __iomem *src, size_t count)
-{
- wil_halp_vote(wil);
- wil_memcpy_fromio_32(dst, src, count);
- wil_halp_unvote(wil);
-}
-
void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src,
size_t count)
{
@@ -153,15 +145,6 @@
__raw_writel(*s++, d++);
}
-void wil_memcpy_toio_halp_vote(struct wil6210_priv *wil,
- volatile void __iomem *dst,
- const void *src, size_t count)
-{
- wil_halp_vote(wil);
- wil_memcpy_toio_32(dst, src, count);
- wil_halp_unvote(wil);
-}
-
static void wil_disconnect_cid(struct wil6210_priv *wil, int cid,
u16 reason_code, bool from_event)
__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
@@ -274,15 +257,20 @@
wil_bcast_fini(wil);
wil_update_net_queues_bh(wil, NULL, true);
netif_carrier_off(ndev);
+ wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
if (test_bit(wil_status_fwconnected, wil->status)) {
clear_bit(wil_status_fwconnected, wil->status);
cfg80211_disconnected(ndev, reason_code,
- NULL, 0, false, GFP_KERNEL);
+ NULL, 0,
+ wil->locally_generated_disc,
+ GFP_KERNEL);
+ wil->locally_generated_disc = false;
} else if (test_bit(wil_status_fwconnecting, wil->status)) {
cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0,
WLAN_STATUS_UNSPECIFIED_FAILURE,
GFP_KERNEL);
+ wil->bss = NULL;
}
clear_bit(wil_status_fwconnecting, wil->status);
break;
@@ -304,10 +292,34 @@
{
struct wil6210_priv *wil = container_of(work,
struct wil6210_priv, disconnect_worker);
+ struct net_device *ndev = wil_to_ndev(wil);
+ int rc;
+ struct {
+ struct wmi_cmd_hdr wmi;
+ struct wmi_disconnect_event evt;
+ } __packed reply;
- mutex_lock(&wil->mutex);
- _wil6210_disconnect(wil, NULL, WLAN_REASON_UNSPECIFIED, false);
- mutex_unlock(&wil->mutex);
+ if (test_bit(wil_status_fwconnected, wil->status))
+ /* connect succeeded after all */
+ return;
+
+ if (!test_bit(wil_status_fwconnecting, wil->status))
+ /* already disconnected */
+ return;
+
+ rc = wmi_call(wil, WMI_DISCONNECT_CMDID, NULL, 0,
+ WMI_DISCONNECT_EVENTID, &reply, sizeof(reply),
+ WIL6210_DISCONNECT_TO_MS);
+ if (rc) {
+ wil_err(wil, "disconnect error %d\n", rc);
+ return;
+ }
+
+ wil_update_net_queues_bh(wil, NULL, true);
+ netif_carrier_off(ndev);
+ cfg80211_connect_result(ndev, NULL, NULL, 0, NULL, 0,
+ WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL);
+ clear_bit(wil_status_fwconnecting, wil->status);
}
static void wil_connect_timer_fn(ulong x)
@@ -557,6 +569,12 @@
return -EAGAIN;
}
+void wil6210_bus_request(struct wil6210_priv *wil, u32 kbps)
+{
+ if (wil->platform_ops.bus_request)
+ wil->platform_ops.bus_request(wil->platform_handle, kbps);
+}
+
/**
* wil6210_disconnect - disconnect one connection
* @wil: driver context
@@ -610,13 +628,25 @@
wil_w(wil, RGF_USER_USER_CPU_0, 1);
}
-static void wil_set_oob_mode(struct wil6210_priv *wil, bool enable)
+static void wil_set_oob_mode(struct wil6210_priv *wil, u8 mode)
{
- wil_info(wil, "enable=%d\n", enable);
- if (enable)
+ wil_info(wil, "oob_mode to %d\n", mode);
+ switch (mode) {
+ case 0:
+ wil_c(wil, RGF_USER_USAGE_6, BIT_USER_OOB_MODE |
+ BIT_USER_OOB_R2_MODE);
+ break;
+ case 1:
+ wil_c(wil, RGF_USER_USAGE_6, BIT_USER_OOB_R2_MODE);
wil_s(wil, RGF_USER_USAGE_6, BIT_USER_OOB_MODE);
- else
+ break;
+ case 2:
wil_c(wil, RGF_USER_USAGE_6, BIT_USER_OOB_MODE);
+ wil_s(wil, RGF_USER_USAGE_6, BIT_USER_OOB_R2_MODE);
+ break;
+ default:
+ wil_err(wil, "invalid oob_mode: %d\n", mode);
+ }
}
static int wil_target_reset(struct wil6210_priv *wil)
@@ -1073,9 +1103,7 @@
napi_enable(&wil->napi_tx);
set_bit(wil_status_napi_en, wil->status);
- if (wil->platform_ops.bus_request)
- wil->platform_ops.bus_request(wil->platform_handle,
- WIL_MAX_BUS_REQUEST_KBPS);
+ wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
return 0;
}
@@ -1099,8 +1127,7 @@
set_bit(wil_status_resetting, wil->status);
- if (wil->platform_ops.bus_request)
- wil->platform_ops.bus_request(wil->platform_handle, 0);
+ wil6210_bus_request(wil, 0);
wil_disable_irq(wil);
if (test_and_clear_bit(wil_status_napi_en, wil->status)) {
@@ -1163,6 +1190,7 @@
wil->halp.ref_cnt);
if (++wil->halp.ref_cnt == 1) {
+ reinit_completion(&wil->halp.comp);
wil6210_set_halp(wil);
rc = wait_for_completion_timeout(&wil->halp.comp, to_jiffies);
if (!rc) {
diff --git a/drivers/net/wireless/ath/wil6210/pm.c b/drivers/net/wireless/ath/wil6210/pm.c
index 7260bef..2ae4fe8 100644
--- a/drivers/net/wireless/ath/wil6210/pm.c
+++ b/drivers/net/wireless/ath/wil6210/pm.c
@@ -71,6 +71,11 @@
wil_dbg_pm(wil, "suspend: %s\n", is_runtime ? "runtime" : "system");
+ if (test_bit(wil_status_suspended, wil->status)) {
+ wil_dbg_pm(wil, "trying to suspend while suspended\n");
+ return 0;
+ }
+
/* if netif up, hardware is alive, shut it down */
if (ndev->flags & IFF_UP) {
rc = wil_down(wil);
@@ -86,10 +91,14 @@
if (wil->platform_ops.suspend) {
rc = wil->platform_ops.suspend(wil->platform_handle);
- if (rc)
+ if (rc) {
wil_enable_irq(wil);
+ goto out;
+ }
}
+ set_bit(wil_status_suspended, wil->status);
+
out:
wil_dbg_pm(wil, "suspend: %s => %d\n",
is_runtime ? "runtime" : "system", rc);
@@ -117,10 +126,13 @@
/* if netif up, bring hardware up
* During open(), IFF_UP set after actual device method
- * invocation. This prevent recursive call to wil_up()
+ * invocation. This prevent recursive call to wil_up().
+ * wil_status_suspended will be cleared in wil_reset
*/
if (ndev->flags & IFF_UP)
rc = wil_up(wil);
+ else
+ clear_bit(wil_status_suspended, wil->status);
out:
wil_dbg_pm(wil, "resume: %s => %d\n",
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 4bccef3..734449d 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
+ * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -41,6 +41,7 @@
#define WIL_FW_NAME_SPARROW_PLUS "wil6210_sparrow_plus.fw" /* code Sparrow D0 */
#define WIL_BOARD_FILE_NAME "wil6210.brd" /* board & radio parameters */
+#define WIL_DEFAULT_BUS_REQUEST_KBPS 128000 /* ~1Gbps */
#define WIL_MAX_BUS_REQUEST_KBPS 800000 /* ~6.1Gbps */
/**
@@ -140,6 +141,7 @@
#define RGF_USER_USAGE_1 (0x880004)
#define RGF_USER_USAGE_6 (0x880018)
#define BIT_USER_OOB_MODE BIT(31)
+ #define BIT_USER_OOB_R2_MODE BIT(30)
#define RGF_USER_USAGE_8 (0x880020)
#define BIT_USER_PREVENT_DEEP_SLEEP BIT(0)
#define BIT_USER_SUPPORT_T_POWER_ON_0 BIT(1)
@@ -413,6 +415,7 @@
wil_status_irqen, /* FIXME: interrupts enabled - for debug */
wil_status_napi_en, /* NAPI enabled protected by wil->mutex */
wil_status_resetting, /* reset in progress */
+ wil_status_suspended, /* suspend completed, device is suspended */
wil_status_last /* keep last */
};
@@ -616,6 +619,8 @@
u16 channel; /* relevant in AP mode */
int sinfo_gen;
u32 ap_isolate; /* no intra-BSS communication */
+ struct cfg80211_bss *bss; /* connected bss, relevant in STA mode */
+ int locally_generated_disc; /* relevant in STA mode */
/* interrupt moderation */
u32 tx_max_burst_duration;
u32 tx_interframe_timeout;
@@ -771,6 +776,12 @@
print_hex_dump_debug("DBG[ WMI]" prefix_str,\
prefix_type, rowsize, \
groupsize, buf, len, ascii)
+
+#define wil_hex_dump_misc(prefix_str, prefix_type, rowsize, \
+ groupsize, buf, len, ascii) \
+ print_hex_dump_debug("DBG[MISC]" prefix_str,\
+ prefix_type, rowsize, \
+ groupsize, buf, len, ascii)
#else /* defined(CONFIG_DYNAMIC_DEBUG) */
static inline
void wil_hex_dump_txrx(const char *prefix_str, int prefix_type, int rowsize,
@@ -783,18 +794,18 @@
int groupsize, const void *buf, size_t len, bool ascii)
{
}
+
+static inline
+void wil_hex_dump_misc(const char *prefix_str, int prefix_type, int rowsize,
+ int groupsize, const void *buf, size_t len, bool ascii)
+{
+}
#endif /* defined(CONFIG_DYNAMIC_DEBUG) */
void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src,
size_t count);
void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src,
size_t count);
-void wil_memcpy_fromio_halp_vote(struct wil6210_priv *wil, void *dst,
- const volatile void __iomem *src,
- size_t count);
-void wil_memcpy_toio_halp_vote(struct wil6210_priv *wil,
- volatile void __iomem *dst,
- const void *src, size_t count);
void *wil_if_alloc(struct device *dev);
void wil_if_free(struct wil6210_priv *wil);
@@ -910,7 +921,7 @@
u8 type);
int wmi_abort_scan(struct wil6210_priv *wil);
void wil_abort_scan(struct wil6210_priv *wil, bool sync);
-
+void wil6210_bus_request(struct wil6210_priv *wil, u32 kbps);
void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
u16 reason_code, bool from_event);
void wil_probe_client_flush(struct wil6210_priv *wil);
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 0ede7f7..31d6ab9 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -566,6 +566,7 @@
(wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) {
if (rc) {
netif_carrier_off(ndev);
+ wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
wil_err(wil, "cfg80211_connect_result with failure\n");
cfg80211_connect_result(ndev, evt->bssid, NULL, 0,
NULL, 0,
@@ -573,12 +574,16 @@
GFP_KERNEL);
goto out;
} else {
- cfg80211_connect_result(ndev, evt->bssid,
- assoc_req_ie, assoc_req_ielen,
- assoc_resp_ie, assoc_resp_ielen,
- WLAN_STATUS_SUCCESS,
- GFP_KERNEL);
+ struct wiphy *wiphy = wil_to_wiphy(wil);
+
+ cfg80211_ref_bss(wiphy, wil->bss);
+ cfg80211_connect_bss(ndev, evt->bssid, wil->bss,
+ assoc_req_ie, assoc_req_ielen,
+ assoc_resp_ie, assoc_resp_ielen,
+ WLAN_STATUS_SUCCESS, GFP_KERNEL,
+ NL80211_TIMEOUT_UNSPECIFIED);
}
+ wil->bss = NULL;
} else if ((wdev->iftype == NL80211_IFTYPE_AP) ||
(wdev->iftype == NL80211_IFTYPE_P2P_GO)) {
if (rc) {
@@ -1524,6 +1529,7 @@
wil_dbg_wmi(wil, "disconnect_sta: (%pM, reason %d)\n", mac, reason);
+ wil->locally_generated_disc = true;
if (del_sta) {
ether_addr_copy(del_sta_cmd.dst_mac, mac);
rc = wmi_call(wil, WMI_DEL_STA_CMDID, &del_sta_cmd,
@@ -1765,14 +1771,19 @@
void wmi_event_flush(struct wil6210_priv *wil)
{
+ ulong flags;
struct pending_wmi_event *evt, *t;
wil_dbg_wmi(wil, "event_flush\n");
+ spin_lock_irqsave(&wil->wmi_ev_lock, flags);
+
list_for_each_entry_safe(evt, t, &wil->pending_wmi_ev, list) {
list_del(&evt->list);
kfree(evt);
}
+
+ spin_unlock_irqrestore(&wil->wmi_ev_lock, flags);
}
static bool wmi_evt_call_handler(struct wil6210_priv *wil, int id,
diff --git a/drivers/pinctrl/qcom/pinctrl-sdm845.c b/drivers/pinctrl/qcom/pinctrl-sdm845.c
index 67adf58..30c31a8 100644
--- a/drivers/pinctrl/qcom/pinctrl-sdm845.c
+++ b/drivers/pinctrl/qcom/pinctrl-sdm845.c
@@ -526,7 +526,6 @@
msm_mux_reserved30,
msm_mux_qup11,
msm_mux_qup14,
- msm_mux_phase_flag3,
msm_mux_reserved96,
msm_mux_ldo_en,
msm_mux_reserved97,
@@ -543,17 +542,13 @@
msm_mux_phase_flag5,
msm_mux_reserved103,
msm_mux_reserved104,
- msm_mux_pcie1_forceon,
msm_mux_uim2_data,
msm_mux_qup13,
msm_mux_reserved105,
- msm_mux_pcie1_pwren,
msm_mux_uim2_clk,
msm_mux_reserved106,
- msm_mux_pcie1_auxen,
msm_mux_uim2_reset,
msm_mux_reserved107,
- msm_mux_pcie1_button,
msm_mux_uim2_present,
msm_mux_reserved108,
msm_mux_uim1_data,
@@ -564,7 +559,6 @@
msm_mux_reserved111,
msm_mux_uim1_present,
msm_mux_reserved112,
- msm_mux_pcie1_prsnt2,
msm_mux_uim_batt,
msm_mux_edp_hot,
msm_mux_reserved113,
@@ -587,7 +581,6 @@
msm_mux_reserved123,
msm_mux_reserved124,
msm_mux_reserved125,
- msm_mux_sd_card,
msm_mux_reserved126,
msm_mux_reserved127,
msm_mux_reserved128,
@@ -647,7 +640,6 @@
msm_mux_reserved42,
msm_mux_reserved43,
msm_mux_reserved44,
- msm_mux_bt_reset,
msm_mux_qup6,
msm_mux_reserved45,
msm_mux_reserved46,
@@ -672,7 +664,6 @@
msm_mux_gcc_gp1,
msm_mux_phase_flag18,
msm_mux_reserved57,
- msm_mux_ssc_irq,
msm_mux_phase_flag19,
msm_mux_reserved58,
msm_mux_phase_flag20,
@@ -731,10 +722,8 @@
msm_mux_reserved82,
msm_mux_reserved83,
msm_mux_reserved84,
- msm_mux_pcie1_pwrfault,
msm_mux_qup5,
msm_mux_reserved85,
- msm_mux_pcie1_mrl,
msm_mux_reserved86,
msm_mux_reserved87,
msm_mux_reserved88,
@@ -772,6 +761,7 @@
msm_mux_reserved95,
msm_mux_tsif2_sync,
msm_mux_sdc40,
+ msm_mux_phase_flag3,
msm_mux_NA,
};
@@ -781,19 +771,24 @@
"gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
"gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
"gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
- "gpio36", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42", "gpio43",
- "gpio44", "gpio46", "gpio47", "gpio48", "gpio49", "gpio50", "gpio51",
- "gpio52", "gpio53", "gpio54", "gpio55", "gpio56", "gpio57", "gpio64",
- "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70", "gpio71",
- "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77", "gpio81",
- "gpio82", "gpio83", "gpio84", "gpio87", "gpio88", "gpio89", "gpio90",
- "gpio91", "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97",
- "gpio98", "gpio99", "gpio100", "gpio101", "gpio102", "gpio103",
- "gpio109", "gpio110", "gpio111", "gpio112", "gpio114", "gpio115",
- "gpio116", "gpio127", "gpio128", "gpio129", "gpio130", "gpio131",
- "gpio132", "gpio133", "gpio134", "gpio135", "gpio136", "gpio137",
- "gpio138", "gpio139", "gpio140", "gpio141", "gpio142", "gpio143",
- "gpio144", "gpio145", "gpio146", "gpio147", "gpio148", "gpio149",
+ "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
+ "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
+ "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
+ "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
+ "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70",
+ "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77",
+ "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84",
+ "gpio85", "gpio86", "gpio87", "gpio88", "gpio89", "gpio90", "gpio91",
+ "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", "gpio98",
+ "gpio99", "gpio100", "gpio101", "gpio102", "gpio103", "gpio104",
+ "gpio105", "gpio106", "gpio107", "gpio108", "gpio109", "gpio110",
+ "gpio111", "gpio112", "gpio113", "gpio114", "gpio115", "gpio116",
+ "gpio117", "gpio118", "gpio119", "gpio120", "gpio121", "gpio122",
+ "gpio123", "gpio124", "gpio125", "gpio126", "gpio127", "gpio128",
+ "gpio129", "gpio130", "gpio131", "gpio132", "gpio133", "gpio134",
+ "gpio135", "gpio136", "gpio137", "gpio138", "gpio139", "gpio140",
+ "gpio141", "gpio142", "gpio143", "gpio144", "gpio145", "gpio146",
+ "gpio147", "gpio148", "gpio149",
};
static const char * const qup0_groups[] = {
"gpio0", "gpio1", "gpio2", "gpio3",
@@ -1075,9 +1070,6 @@
static const char * const qup14_groups[] = {
"gpio31", "gpio32", "gpio33", "gpio34",
};
-static const char * const phase_flag3_groups[] = {
- "gpio96",
-};
static const char * const reserved96_groups[] = {
"gpio96",
};
@@ -1109,7 +1101,7 @@
"gpio101",
};
static const char * const pci_e1_groups[] = {
- "gpio102", "gpio103", "gpio104",
+ "gpio102", "gpio103",
};
static const char * const prng_rosc_groups[] = {
"gpio102",
@@ -1126,9 +1118,6 @@
static const char * const reserved104_groups[] = {
"gpio104",
};
-static const char * const pcie1_forceon_groups[] = {
- "gpio105",
-};
static const char * const uim2_data_groups[] = {
"gpio105",
};
@@ -1138,27 +1127,18 @@
static const char * const reserved105_groups[] = {
"gpio105",
};
-static const char * const pcie1_pwren_groups[] = {
- "gpio106",
-};
static const char * const uim2_clk_groups[] = {
"gpio106",
};
static const char * const reserved106_groups[] = {
"gpio106",
};
-static const char * const pcie1_auxen_groups[] = {
- "gpio107",
-};
static const char * const uim2_reset_groups[] = {
"gpio107",
};
static const char * const reserved107_groups[] = {
"gpio107",
};
-static const char * const pcie1_button_groups[] = {
- "gpio108",
-};
static const char * const uim2_present_groups[] = {
"gpio108",
};
@@ -1189,9 +1169,6 @@
static const char * const reserved112_groups[] = {
"gpio112",
};
-static const char * const pcie1_prsnt2_groups[] = {
- "gpio113",
-};
static const char * const uim_batt_groups[] = {
"gpio113",
};
@@ -1259,9 +1236,6 @@
static const char * const reserved125_groups[] = {
"gpio125",
};
-static const char * const sd_card_groups[] = {
- "gpio126",
-};
static const char * const reserved126_groups[] = {
"gpio126",
};
@@ -1380,7 +1354,7 @@
"gpio34",
};
static const char * const pci_e0_groups[] = {
- "gpio35", "gpio36", "gpio37",
+ "gpio35", "gpio36",
};
static const char * const jitter_bist_groups[] = {
"gpio35",
@@ -1439,9 +1413,6 @@
static const char * const reserved44_groups[] = {
"gpio44",
};
-static const char * const bt_reset_groups[] = {
- "gpio45",
-};
static const char * const qup6_groups[] = {
"gpio45", "gpio46", "gpio47", "gpio48",
};
@@ -1514,11 +1485,6 @@
static const char * const reserved57_groups[] = {
"gpio57",
};
-static const char * const ssc_irq_groups[] = {
- "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63", "gpio78",
- "gpio79", "gpio80", "gpio117", "gpio118", "gpio119", "gpio120",
- "gpio121", "gpio122", "gpio123", "gpio124", "gpio125",
-};
static const char * const phase_flag19_groups[] = {
"gpio58",
};
@@ -1693,18 +1659,12 @@
static const char * const reserved84_groups[] = {
"gpio84",
};
-static const char * const pcie1_pwrfault_groups[] = {
- "gpio85",
-};
static const char * const qup5_groups[] = {
"gpio85", "gpio86", "gpio87", "gpio88",
};
static const char * const reserved85_groups[] = {
"gpio85",
};
-static const char * const pcie1_mrl_groups[] = {
- "gpio86",
-};
static const char * const reserved86_groups[] = {
"gpio86",
};
@@ -1816,6 +1776,9 @@
static const char * const sdc40_groups[] = {
"gpio96",
};
+static const char * const phase_flag3_groups[] = {
+ "gpio96",
+};
static const struct msm_function sdm845_functions[] = {
FUNCTION(gpio),
@@ -1912,7 +1875,6 @@
FUNCTION(reserved30),
FUNCTION(qup11),
FUNCTION(qup14),
- FUNCTION(phase_flag3),
FUNCTION(reserved96),
FUNCTION(ldo_en),
FUNCTION(reserved97),
@@ -1929,17 +1891,13 @@
FUNCTION(phase_flag5),
FUNCTION(reserved103),
FUNCTION(reserved104),
- FUNCTION(pcie1_forceon),
FUNCTION(uim2_data),
FUNCTION(qup13),
FUNCTION(reserved105),
- FUNCTION(pcie1_pwren),
FUNCTION(uim2_clk),
FUNCTION(reserved106),
- FUNCTION(pcie1_auxen),
FUNCTION(uim2_reset),
FUNCTION(reserved107),
- FUNCTION(pcie1_button),
FUNCTION(uim2_present),
FUNCTION(reserved108),
FUNCTION(uim1_data),
@@ -1950,7 +1908,6 @@
FUNCTION(reserved111),
FUNCTION(uim1_present),
FUNCTION(reserved112),
- FUNCTION(pcie1_prsnt2),
FUNCTION(uim_batt),
FUNCTION(edp_hot),
FUNCTION(reserved113),
@@ -1973,7 +1930,6 @@
FUNCTION(reserved123),
FUNCTION(reserved124),
FUNCTION(reserved125),
- FUNCTION(sd_card),
FUNCTION(reserved126),
FUNCTION(reserved127),
FUNCTION(reserved128),
@@ -2033,7 +1989,6 @@
FUNCTION(reserved42),
FUNCTION(reserved43),
FUNCTION(reserved44),
- FUNCTION(bt_reset),
FUNCTION(qup6),
FUNCTION(reserved45),
FUNCTION(reserved46),
@@ -2058,7 +2013,6 @@
FUNCTION(gcc_gp1),
FUNCTION(phase_flag18),
FUNCTION(reserved57),
- FUNCTION(ssc_irq),
FUNCTION(phase_flag19),
FUNCTION(reserved58),
FUNCTION(phase_flag20),
@@ -2117,10 +2071,8 @@
FUNCTION(reserved82),
FUNCTION(reserved83),
FUNCTION(reserved84),
- FUNCTION(pcie1_pwrfault),
FUNCTION(qup5),
FUNCTION(reserved85),
- FUNCTION(pcie1_mrl),
FUNCTION(reserved86),
FUNCTION(reserved87),
FUNCTION(reserved88),
@@ -2158,6 +2110,7 @@
FUNCTION(reserved95),
FUNCTION(tsif2_sync),
FUNCTION(sdc40),
+ FUNCTION(phase_flag3),
};
static const struct msm_pingroup sdm845_groups[] = {
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c
index 19c3de4a..73738bf 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c
@@ -53,6 +53,8 @@
static bool workqueues_stopped;
static bool ipa3_modem_init_cmplt;
static bool first_time_handshake;
+struct mutex ipa3_qmi_lock;
+
/* QMI A5 service */
static struct msg_desc ipa3_indication_reg_req_desc = {
@@ -610,12 +612,17 @@
req->filter_spec_ex_list_len);
}
- /* cache the qmi_filter_request */
- memcpy(&(ipa3_qmi_ctx->ipa_install_fltr_rule_req_msg_cache[
- ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_msg]),
- req, sizeof(struct ipa_install_fltr_rule_req_msg_v01));
- ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_msg++;
- ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_msg %= 10;
+ mutex_lock(&ipa3_qmi_lock);
+ if (ipa3_qmi_ctx != NULL) {
+ /* cache the qmi_filter_request */
+ memcpy(&(ipa3_qmi_ctx->ipa_install_fltr_rule_req_msg_cache[
+ ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_msg]),
+ req,
+ sizeof(struct ipa_install_fltr_rule_req_msg_v01));
+ ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_msg++;
+ ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_msg %= 10;
+ }
+ mutex_unlock(&ipa3_qmi_lock);
req_desc.max_msg_len = QMI_IPA_INSTALL_FILTER_RULE_REQ_MAX_MSG_LEN_V01;
req_desc.msg_id = QMI_IPA_INSTALL_FILTER_RULE_REQ_V01;
@@ -655,12 +662,17 @@
req->filter_spec_ex_list_len);
}
- /* cache the qmi_filter_request */
- memcpy(&(ipa3_qmi_ctx->ipa_install_fltr_rule_req_ex_msg_cache[
- ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_ex_msg]),
- req, sizeof(struct ipa_install_fltr_rule_req_ex_msg_v01));
- ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_ex_msg++;
- ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_ex_msg %= 10;
+ mutex_lock(&ipa3_qmi_lock);
+ if (ipa3_qmi_ctx != NULL) {
+ /* cache the qmi_filter_request */
+ memcpy(&(ipa3_qmi_ctx->ipa_install_fltr_rule_req_ex_msg_cache[
+ ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_ex_msg]),
+ req,
+ sizeof(struct ipa_install_fltr_rule_req_ex_msg_v01));
+ ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_ex_msg++;
+ ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_ex_msg %= 10;
+ }
+ mutex_unlock(&ipa3_qmi_lock);
req_desc.max_msg_len =
QMI_IPA_INSTALL_FILTER_RULE_EX_REQ_MAX_MSG_LEN_V01;
@@ -796,12 +808,17 @@
return -EINVAL;
}
- /* cache the qmi_filter_request */
- memcpy(&(ipa3_qmi_ctx->ipa_fltr_installed_notif_req_msg_cache[
- ipa3_qmi_ctx->num_ipa_fltr_installed_notif_req_msg]),
- req, sizeof(struct ipa_fltr_installed_notif_req_msg_v01));
- ipa3_qmi_ctx->num_ipa_fltr_installed_notif_req_msg++;
- ipa3_qmi_ctx->num_ipa_fltr_installed_notif_req_msg %= 10;
+ mutex_lock(&ipa3_qmi_lock);
+ if (ipa3_qmi_ctx != NULL) {
+ /* cache the qmi_filter_request */
+ memcpy(&(ipa3_qmi_ctx->ipa_fltr_installed_notif_req_msg_cache[
+ ipa3_qmi_ctx->num_ipa_fltr_installed_notif_req_msg]),
+ req,
+ sizeof(struct ipa_fltr_installed_notif_req_msg_v01));
+ ipa3_qmi_ctx->num_ipa_fltr_installed_notif_req_msg++;
+ ipa3_qmi_ctx->num_ipa_fltr_installed_notif_req_msg %= 10;
+ }
+ mutex_unlock(&ipa3_qmi_lock);
req_desc.max_msg_len =
QMI_IPA_FILTER_INSTALLED_NOTIF_REQ_MAX_MSG_LEN_V01;
@@ -1339,3 +1356,13 @@
resp.resp.error, "ipa_stop_data_usage_quota_req_msg_v01");
}
+void ipa3_qmi_init(void)
+{
+ mutex_init(&ipa3_qmi_lock);
+}
+
+void ipa3_qmi_cleanup(void)
+{
+ mutex_destroy(&ipa3_qmi_lock);
+}
+
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h
index 4fde261..6cd82f8 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h
@@ -204,6 +204,10 @@
void ipa3_q6_handshake_complete(bool ssr_bootup);
+void ipa3_qmi_init(void);
+
+void ipa3_qmi_cleanup(void);
+
#else /* CONFIG_RMNET_IPA3 */
static inline int ipa3_qmi_service_init(uint32_t wan_platform_type)
@@ -316,6 +320,14 @@
static inline void ipa3_q6_handshake_complete(bool ssr_bootup) { }
+static inline void ipa3_qmi_init(void)
+{
+}
+
+static inline void ipa3_qmi_cleanup(void)
+{
+}
+
#endif /* CONFIG_RMNET_IPA3 */
#endif /* IPA_QMI_SERVICE_H */
diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
index 56e7718..a15bd04 100644
--- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
@@ -3206,6 +3206,9 @@
mutex_init(&rmnet_ipa3_ctx->pipe_handle_guard);
rmnet_ipa3_ctx->ipa3_to_apps_hdl = -1;
rmnet_ipa3_ctx->apps_to_ipa3_hdl = -1;
+
+ ipa3_qmi_init();
+
/* Register for Modem SSR */
rmnet_ipa3_ctx->subsys_notify_handle = subsys_notif_register_notifier(
SUBSYS_MODEM,
@@ -3219,7 +3222,7 @@
static void __exit ipa3_wwan_cleanup(void)
{
int ret;
-
+ ipa3_qmi_cleanup();
mutex_destroy(&rmnet_ipa3_ctx->pipe_handle_guard);
ret = subsys_notif_unregister_notifier(
rmnet_ipa3_ctx->subsys_notify_handle, &ipa3_ssr_notifier);
diff --git a/drivers/platform/msm/msm_11ad/msm_11ad.c b/drivers/platform/msm/msm_11ad/msm_11ad.c
index 47da1b3..5595b7b 100644
--- a/drivers/platform/msm/msm_11ad/msm_11ad.c
+++ b/drivers/platform/msm/msm_11ad/msm_11ad.c
@@ -36,7 +36,7 @@
#define WIGIG_VENDOR (0x1ae9)
#define WIGIG_DEVICE (0x0310)
-#define SMMU_BASE 0x10000000 /* Device address range base */
+#define SMMU_BASE 0x20000000 /* Device address range base */
#define SMMU_SIZE ((SZ_1G * 4ULL) - SMMU_BASE)
#define WIGIG_ENABLE_DELAY 50
@@ -93,9 +93,12 @@
/* SMMU */
bool use_smmu; /* have SMMU enabled? */
- int smmu_bypass;
+ int smmu_s1_en;
int smmu_fast_map;
+ int smmu_coherent;
struct dma_iommu_mapping *mapping;
+ u32 smmu_base;
+ u32 smmu_size;
/* bus frequency scaling */
struct msm_bus_scale_pdata *bus_scale;
@@ -638,15 +641,20 @@
{
int atomic_ctx = 1;
int rc;
+ int force_pt_coherent = 1;
+ int smmu_bypass = !ctx->smmu_s1_en;
+ dma_addr_t iova_base = 0;
+ dma_addr_t iova_end = ctx->smmu_base + ctx->smmu_size - 1;
+ struct iommu_domain_geometry geometry;
if (!ctx->use_smmu)
return 0;
- dev_info(ctx->dev, "Initialize SMMU, bypass = %d, fastmap = %d\n",
- ctx->smmu_bypass, ctx->smmu_fast_map);
+ dev_info(ctx->dev, "Initialize SMMU, bypass=%d, fastmap=%d, coherent=%d\n",
+ smmu_bypass, ctx->smmu_fast_map, ctx->smmu_coherent);
ctx->mapping = arm_iommu_create_mapping(&platform_bus_type,
- SMMU_BASE, SMMU_SIZE);
+ ctx->smmu_base, ctx->smmu_size);
if (IS_ERR_OR_NULL(ctx->mapping)) {
rc = PTR_ERR(ctx->mapping) ?: -ENODEV;
dev_err(ctx->dev, "Failed to create IOMMU mapping (%d)\n", rc);
@@ -662,23 +670,50 @@
goto release_mapping;
}
- if (ctx->smmu_bypass) {
+ if (smmu_bypass) {
rc = iommu_domain_set_attr(ctx->mapping->domain,
DOMAIN_ATTR_S1_BYPASS,
- &ctx->smmu_bypass);
+ &smmu_bypass);
if (rc) {
dev_err(ctx->dev, "Set bypass attribute to SMMU failed (%d)\n",
rc);
goto release_mapping;
}
- } else if (ctx->smmu_fast_map) {
- rc = iommu_domain_set_attr(ctx->mapping->domain,
- DOMAIN_ATTR_FAST,
- &ctx->smmu_fast_map);
- if (rc) {
- dev_err(ctx->dev, "Set fast attribute to SMMU failed (%d)\n",
- rc);
- goto release_mapping;
+ } else {
+ /* Set dma-coherent and page table coherency */
+ if (ctx->smmu_coherent) {
+ arch_setup_dma_ops(&ctx->pcidev->dev, 0, 0, NULL, true);
+ rc = iommu_domain_set_attr(ctx->mapping->domain,
+ DOMAIN_ATTR_PAGE_TABLE_FORCE_COHERENT,
+ &force_pt_coherent);
+ if (rc) {
+ dev_err(ctx->dev,
+ "Set SMMU PAGE_TABLE_FORCE_COHERENT attr failed (%d)\n",
+ rc);
+ goto release_mapping;
+ }
+ }
+
+ if (ctx->smmu_fast_map) {
+ rc = iommu_domain_set_attr(ctx->mapping->domain,
+ DOMAIN_ATTR_FAST,
+ &ctx->smmu_fast_map);
+ if (rc) {
+ dev_err(ctx->dev, "Set fast attribute to SMMU failed (%d)\n",
+ rc);
+ goto release_mapping;
+ }
+ memset(&geometry, 0, sizeof(geometry));
+ geometry.aperture_start = iova_base;
+ geometry.aperture_end = iova_end;
+ rc = iommu_domain_set_attr(ctx->mapping->domain,
+ DOMAIN_ATTR_GEOMETRY,
+ &geometry);
+ if (rc) {
+ dev_err(ctx->dev, "Set geometry attribute to SMMU failed (%d)\n",
+ rc);
+ goto release_mapping;
+ }
}
}
@@ -900,6 +935,7 @@
struct device_node *of_node = dev->of_node;
struct device_node *rc_node;
struct pci_dev *pcidev = NULL;
+ u32 smmu_mapping[2];
int rc;
u32 val;
@@ -954,8 +990,27 @@
ctx->use_smmu = of_property_read_bool(of_node, "qcom,smmu-support");
ctx->bus_scale = msm_bus_cl_get_pdata(pdev);
- ctx->smmu_bypass = 1;
- ctx->smmu_fast_map = 0;
+ ctx->smmu_s1_en = of_property_read_bool(of_node, "qcom,smmu-s1-en");
+ if (ctx->smmu_s1_en) {
+ ctx->smmu_fast_map = of_property_read_bool(
+ of_node, "qcom,smmu-fast-map");
+ ctx->smmu_coherent = of_property_read_bool(
+ of_node, "qcom,smmu-coherent");
+ }
+ rc = of_property_read_u32_array(dev->of_node, "qcom,smmu-mapping",
+ smmu_mapping, 2);
+ if (rc) {
+ dev_err(ctx->dev,
+ "Failed to read base/size smmu addresses %d, fallback to default\n",
+ rc);
+ ctx->smmu_base = SMMU_BASE;
+ ctx->smmu_size = SMMU_SIZE;
+ } else {
+ ctx->smmu_base = smmu_mapping[0];
+ ctx->smmu_size = smmu_mapping[1];
+ }
+ dev_dbg(ctx->dev, "smmu_base=0x%x smmu_sise=0x%x\n",
+ ctx->smmu_base, ctx->smmu_size);
/*== execute ==*/
/* turn device on */
diff --git a/drivers/power/supply/qcom/Kconfig b/drivers/power/supply/qcom/Kconfig
index 79ea712..362375f 100644
--- a/drivers/power/supply/qcom/Kconfig
+++ b/drivers/power/supply/qcom/Kconfig
@@ -20,6 +20,16 @@
The driver reports the charger status via the power supply framework.
A charger status change triggers an IRQ via the device STAT pin.
+config SMB1355_SLAVE_CHARGER
+ tristate "SMB1355 Slave Battery Charger"
+ depends on MFD_I2C_PMIC
+ help
+ Say Y to include support for SMB1355 Battery Charger.
+ SMB1355 is a single phase 5A battery charger.
+ The driver supports charger enable/disable.
+ The driver reports the charger status via the power supply framework.
+ A charger status change triggers an IRQ via the device STAT pin.
+
config SMB1351_USB_CHARGER
tristate "smb1351 usb charger (with VBUS detection)"
depends on I2C
diff --git a/drivers/power/supply/qcom/Makefile b/drivers/power/supply/qcom/Makefile
index 171444f..bc19b24 100644
--- a/drivers/power/supply/qcom/Makefile
+++ b/drivers/power/supply/qcom/Makefile
@@ -1,5 +1,6 @@
obj-$(CONFIG_QPNP_FG_GEN3) += qpnp-fg-gen3.o fg-memif.o fg-util.o
obj-$(CONFIG_SMB135X_CHARGER) += smb135x-charger.o pmic-voter.o
+obj-$(CONFIG_SMB1355_SLAVE_CHARGER) += smb1355-charger.o pmic-voter.o
obj-$(CONFIG_SMB1351_USB_CHARGER) += smb1351-charger.o pmic-voter.o battery.o
obj-$(CONFIG_QPNP_SMB2) += qpnp-smb2.o smb-lib.o pmic-voter.o storm-watch.o battery.o
obj-$(CONFIG_SMB138X_CHARGER) += smb138x-charger.o smb-lib.o pmic-voter.o storm-watch.o battery.o
diff --git a/drivers/power/supply/qcom/smb1355-charger.c b/drivers/power/supply/qcom/smb1355-charger.c
new file mode 100644
index 0000000..d5fff74
--- /dev/null
+++ b/drivers/power/supply/qcom/smb1355-charger.c
@@ -0,0 +1,675 @@
+/* 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
+ * 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.
+ */
+
+#define pr_fmt(fmt) "SMB1355: %s: " fmt, __func__
+
+#include <linux/device.h>
+#include <linux/regmap.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/qpnp/qpnp-revid.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/power_supply.h>
+#include <linux/pmic-voter.h>
+
+#define SMB1355_DEFAULT_FCC_UA 1000000
+
+/* SMB1355 registers, different than mentioned in smb-reg.h */
+
+#define CHGR_BASE 0x1000
+#define BATIF_BASE 0x1200
+#define USBIN_BASE 0x1300
+#define MISC_BASE 0x1600
+
+#define BATTERY_STATUS_2_REG (CHGR_BASE + 0x0B)
+#define DISABLE_CHARGING_BIT BIT(3)
+
+#define BATTERY_STATUS_3_REG (CHGR_BASE + 0x0C)
+#define BATT_GT_PRE_TO_FAST_BIT BIT(4)
+#define ENABLE_CHARGING_BIT BIT(3)
+
+#define CHGR_CFG2_REG (CHGR_BASE + 0x51)
+#define CHG_EN_SRC_BIT BIT(7)
+#define CHG_EN_POLARITY_BIT BIT(6)
+
+#define CFG_REG (CHGR_BASE + 0x53)
+#define CHG_OPTION_PIN_TRIM_BIT BIT(7)
+#define BATN_SNS_CFG_BIT BIT(4)
+#define CFG_TAPER_DIS_AFVC_BIT BIT(3)
+#define BATFET_SHUTDOWN_CFG_BIT BIT(2)
+#define VDISCHG_EN_CFG_BIT BIT(1)
+#define VCHG_EN_CFG_BIT BIT(0)
+
+#define FAST_CHARGE_CURRENT_CFG_REG (CHGR_BASE + 0x61)
+#define FAST_CHARGE_CURRENT_SETTING_MASK GENMASK(7, 0)
+
+#define CHGR_BATTOV_CFG_REG (CHGR_BASE + 0x70)
+#define BATTOV_SETTING_MASK GENMASK(7, 0)
+
+#define BARK_BITE_WDOG_PET_REG (MISC_BASE + 0x43)
+#define BARK_BITE_WDOG_PET_BIT BIT(0)
+
+#define WD_CFG_REG (MISC_BASE + 0x51)
+#define WATCHDOG_TRIGGER_AFP_EN_BIT BIT(7)
+#define BARK_WDOG_INT_EN_BIT BIT(6)
+#define BITE_WDOG_INT_EN_BIT BIT(5)
+#define WDOG_IRQ_SFT_BIT BIT(2)
+#define WDOG_TIMER_EN_ON_PLUGIN_BIT BIT(1)
+#define WDOG_TIMER_EN_BIT BIT(0)
+
+#define SNARL_BARK_BITE_WD_CFG_REG (MISC_BASE + 0x53)
+#define BITE_WDOG_DISABLE_CHARGING_CFG_BIT BIT(7)
+#define SNARL_WDOG_TIMEOUT_MASK GENMASK(6, 4)
+#define BARK_WDOG_TIMEOUT_MASK GENMASK(3, 2)
+#define BITE_WDOG_TIMEOUT_MASK GENMASK(1, 0)
+
+struct smb_chg_param {
+ const char *name;
+ u16 reg;
+ int min_u;
+ int max_u;
+ int step_u;
+};
+
+struct smb_params {
+ struct smb_chg_param fcc;
+ struct smb_chg_param ov;
+};
+
+static struct smb_params v1_params = {
+ .fcc = {
+ .name = "fast charge current",
+ .reg = FAST_CHARGE_CURRENT_CFG_REG,
+ .min_u = 0,
+ .max_u = 6000000,
+ .step_u = 25000,
+ },
+ .ov = {
+ .name = "battery over voltage",
+ .reg = CHGR_BATTOV_CFG_REG,
+ .min_u = 2450000,
+ .max_u = 5000000,
+ .step_u = 10000,
+ },
+};
+
+struct smb_irq_info {
+ const char *name;
+ const irq_handler_t handler;
+ const bool wake;
+ int irq;
+};
+
+struct smb1355 {
+ struct device *dev;
+ char *name;
+ struct regmap *regmap;
+
+ struct smb_params param;
+
+ struct mutex write_lock;
+
+ struct power_supply *parallel_psy;
+ struct pmic_revid_data *pmic_rev_id;
+};
+
+static bool is_secure(struct smb1355 *chip, int addr)
+{
+ /* assume everything above 0xA0 is secure */
+ return (addr & 0xFF) >= 0xA0;
+}
+
+static int smb1355_read(struct smb1355 *chip, u16 addr, u8 *val)
+{
+ unsigned int temp;
+ int rc;
+
+ rc = regmap_read(chip->regmap, addr, &temp);
+ if (rc >= 0)
+ *val = (u8)temp;
+
+ return rc;
+}
+
+static int smb1355_masked_write(struct smb1355 *chip, u16 addr, u8 mask, u8 val)
+{
+ int rc;
+
+ mutex_lock(&chip->write_lock);
+ if (is_secure(chip, addr)) {
+ rc = regmap_write(chip->regmap, (addr & 0xFF00) | 0xD0, 0xA5);
+ if (rc < 0)
+ goto unlock;
+ }
+
+ rc = regmap_update_bits(chip->regmap, addr, mask, val);
+
+unlock:
+ mutex_unlock(&chip->write_lock);
+ return rc;
+}
+
+static int smb1355_write(struct smb1355 *chip, u16 addr, u8 val)
+{
+ int rc;
+
+ mutex_lock(&chip->write_lock);
+
+ if (is_secure(chip, addr)) {
+ rc = regmap_write(chip->regmap, (addr & ~(0xFF)) | 0xD0, 0xA5);
+ if (rc < 0)
+ goto unlock;
+ }
+
+ rc = regmap_write(chip->regmap, addr, val);
+
+unlock:
+ mutex_unlock(&chip->write_lock);
+ return rc;
+}
+
+static int smb1355_set_charge_param(struct smb1355 *chip,
+ struct smb_chg_param *param, int val_u)
+{
+ int rc;
+ u8 val_raw;
+
+ if (val_u > param->max_u || val_u < param->min_u) {
+ pr_err("%s: %d is out of range [%d, %d]\n",
+ param->name, val_u, param->min_u, param->max_u);
+ return -EINVAL;
+ }
+
+ val_raw = (val_u - param->min_u) / param->step_u;
+
+ rc = smb1355_write(chip, param->reg, val_raw);
+ if (rc < 0) {
+ pr_err("%s: Couldn't write 0x%02x to 0x%04x rc=%d\n",
+ param->name, val_raw, param->reg, rc);
+ return rc;
+ }
+
+ return rc;
+}
+
+static int smb1355_get_charge_param(struct smb1355 *chip,
+ struct smb_chg_param *param, int *val_u)
+{
+ int rc;
+ u8 val_raw;
+
+ rc = smb1355_read(chip, param->reg, &val_raw);
+ if (rc < 0) {
+ pr_err("%s: Couldn't read from 0x%04x rc=%d\n",
+ param->name, param->reg, rc);
+ return rc;
+ }
+
+ *val_u = val_raw * param->step_u + param->min_u;
+
+ return rc;
+}
+
+static irqreturn_t smb1355_handle_chg_state_change(int irq, void *data)
+{
+ struct smb1355 *chip = data;
+
+ if (chip->parallel_psy)
+ power_supply_changed(chip->parallel_psy);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t smb1355_handle_wdog_bark(int irq, void *data)
+{
+ struct smb1355 *chip = data;
+ int rc;
+
+ rc = smb1355_write(chip, BARK_BITE_WDOG_PET_REG,
+ BARK_BITE_WDOG_PET_BIT);
+ if (rc < 0)
+ pr_err("Couldn't pet the dog rc=%d\n", rc);
+
+ return IRQ_HANDLED;
+}
+
+/*****************************
+ * PARALLEL PSY REGISTRATION *
+ *****************************/
+
+static enum power_supply_property smb1355_parallel_props[] = {
+ POWER_SUPPLY_PROP_CHARGE_TYPE,
+ POWER_SUPPLY_PROP_CHARGING_ENABLED,
+ POWER_SUPPLY_PROP_PIN_ENABLED,
+ POWER_SUPPLY_PROP_INPUT_SUSPEND,
+ POWER_SUPPLY_PROP_VOLTAGE_MAX,
+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
+ POWER_SUPPLY_PROP_MODEL_NAME,
+};
+
+static int smb1355_get_prop_batt_charge_type(struct smb1355 *chip,
+ union power_supply_propval *val)
+{
+ int rc;
+ u8 stat;
+
+ rc = smb1355_read(chip, BATTERY_STATUS_3_REG, &stat);
+ if (rc < 0) {
+ pr_err("Couldn't read SMB1355_BATTERY_STATUS_3 rc=%d\n", rc);
+ return rc;
+ }
+
+ if (stat & ENABLE_CHARGING_BIT) {
+ if (stat & BATT_GT_PRE_TO_FAST_BIT)
+ val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
+ else
+ val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
+ } else {
+ val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
+ }
+
+ return rc;
+}
+
+static int smb1355_get_parallel_charging(struct smb1355 *chip, int *disabled)
+{
+ int rc;
+ u8 cfg2;
+
+ rc = smb1355_read(chip, CHGR_CFG2_REG, &cfg2);
+ if (rc < 0) {
+ pr_err("Couldn't read en_cmg_reg rc=%d\n", rc);
+ return rc;
+ }
+
+ if (cfg2 & CHG_EN_SRC_BIT)
+ *disabled = 0;
+ else
+ *disabled = 1;
+
+ return 0;
+}
+
+static int smb1355_parallel_get_prop(struct power_supply *psy,
+ enum power_supply_property prop,
+ union power_supply_propval *val)
+{
+ struct smb1355 *chip = power_supply_get_drvdata(psy);
+ u8 stat;
+ int rc = 0;
+
+ switch (prop) {
+ case POWER_SUPPLY_PROP_CHARGE_TYPE:
+ rc = smb1355_get_prop_batt_charge_type(chip, val);
+ break;
+ case POWER_SUPPLY_PROP_CHARGING_ENABLED:
+ rc = smb1355_read(chip, BATTERY_STATUS_3_REG, &stat);
+ if (rc >= 0)
+ val->intval = (bool)(stat & ENABLE_CHARGING_BIT);
+ break;
+ case POWER_SUPPLY_PROP_PIN_ENABLED:
+ rc = smb1355_read(chip, BATTERY_STATUS_2_REG, &stat);
+ if (rc >= 0)
+ val->intval = !(stat & DISABLE_CHARGING_BIT);
+ break;
+ case POWER_SUPPLY_PROP_INPUT_SUSPEND:
+ rc = smb1355_get_parallel_charging(chip, &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_MAX:
+ rc = smb1355_get_charge_param(chip, &chip->param.ov,
+ &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
+ rc = smb1355_get_charge_param(chip, &chip->param.fcc,
+ &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_MODEL_NAME:
+ val->strval = chip->name;
+ break;
+ case POWER_SUPPLY_PROP_PARALLEL_MODE:
+ val->intval = POWER_SUPPLY_PL_USBMID_USBMID;
+ break;
+ default:
+ pr_err_ratelimited("parallel psy get prop %d not supported\n",
+ prop);
+ return -EINVAL;
+ }
+
+ if (rc < 0) {
+ pr_debug("Couldn't get prop %d rc = %d\n", prop, rc);
+ return -ENODATA;
+ }
+
+ return rc;
+}
+
+static int smb1355_set_parallel_charging(struct smb1355 *chip, bool disable)
+{
+ int rc;
+
+ rc = smb1355_masked_write(chip, WD_CFG_REG, WDOG_TIMER_EN_BIT,
+ disable ? 0 : WDOG_TIMER_EN_BIT);
+ if (rc < 0) {
+ pr_err("Couldn't %s watchdog rc=%d\n",
+ disable ? "disable" : "enable", rc);
+ disable = true;
+ }
+
+ /*
+ * Configure charge enable for high polarity and
+ * When disabling charging set it to cmd register control(cmd bit=0)
+ * When enabling charging set it to pin control
+ */
+ rc = smb1355_masked_write(chip, CHGR_CFG2_REG,
+ CHG_EN_POLARITY_BIT | CHG_EN_SRC_BIT,
+ disable ? 0 : CHG_EN_SRC_BIT);
+ if (rc < 0) {
+ pr_err("Couldn't configure charge enable source rc=%d\n", rc);
+ return rc;
+ }
+
+ return 0;
+}
+
+static int smb1355_parallel_set_prop(struct power_supply *psy,
+ enum power_supply_property prop,
+ const union power_supply_propval *val)
+{
+ struct smb1355 *chip = power_supply_get_drvdata(psy);
+ int rc = 0;
+
+ switch (prop) {
+ case POWER_SUPPLY_PROP_INPUT_SUSPEND:
+ rc = smb1355_set_parallel_charging(chip, (bool)val->intval);
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_MAX:
+ rc = smb1355_set_charge_param(chip, &chip->param.ov,
+ val->intval);
+ break;
+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
+ rc = smb1355_set_charge_param(chip, &chip->param.fcc,
+ val->intval);
+ break;
+ default:
+ pr_debug("parallel power supply set prop %d not supported\n",
+ prop);
+ return -EINVAL;
+ }
+
+ return rc;
+}
+
+static int smb1355_parallel_prop_is_writeable(struct power_supply *psy,
+ enum power_supply_property prop)
+{
+ return 0;
+}
+
+static struct power_supply_desc parallel_psy_desc = {
+ .name = "parallel",
+ .type = POWER_SUPPLY_TYPE_PARALLEL,
+ .properties = smb1355_parallel_props,
+ .num_properties = ARRAY_SIZE(smb1355_parallel_props),
+ .get_property = smb1355_parallel_get_prop,
+ .set_property = smb1355_parallel_set_prop,
+ .property_is_writeable = smb1355_parallel_prop_is_writeable,
+};
+
+static int smb1355_init_parallel_psy(struct smb1355 *chip)
+{
+ struct power_supply_config parallel_cfg = {};
+
+ parallel_cfg.drv_data = chip;
+ parallel_cfg.of_node = chip->dev->of_node;
+
+ /* change to smb1355's property list */
+ parallel_psy_desc.properties = smb1355_parallel_props;
+ parallel_psy_desc.num_properties = ARRAY_SIZE(smb1355_parallel_props);
+ chip->parallel_psy = devm_power_supply_register(chip->dev,
+ ¶llel_psy_desc,
+ ¶llel_cfg);
+ if (IS_ERR(chip->parallel_psy)) {
+ pr_err("Couldn't register parallel power supply\n");
+ return PTR_ERR(chip->parallel_psy);
+ }
+
+ return 0;
+}
+
+/***************************
+ * HARDWARE INITIALIZATION *
+ ***************************/
+
+static int smb1355_init_hw(struct smb1355 *chip)
+{
+ int rc;
+
+ /* enable watchdog bark and bite interrupts, and disable the watchdog */
+ rc = smb1355_masked_write(chip, WD_CFG_REG, WDOG_TIMER_EN_BIT
+ | WDOG_TIMER_EN_ON_PLUGIN_BIT | BITE_WDOG_INT_EN_BIT
+ | BARK_WDOG_INT_EN_BIT,
+ BITE_WDOG_INT_EN_BIT | BARK_WDOG_INT_EN_BIT);
+ if (rc < 0) {
+ pr_err("Couldn't configure the watchdog rc=%d\n", rc);
+ return rc;
+ }
+
+ /* disable charging when watchdog bites */
+ rc = smb1355_masked_write(chip, SNARL_BARK_BITE_WD_CFG_REG,
+ BITE_WDOG_DISABLE_CHARGING_CFG_BIT,
+ BITE_WDOG_DISABLE_CHARGING_CFG_BIT);
+ if (rc < 0) {
+ pr_err("Couldn't configure the watchdog bite rc=%d\n", rc);
+ return rc;
+ }
+
+ /* disable parallel charging path */
+ rc = smb1355_set_parallel_charging(chip, true);
+ if (rc < 0) {
+ pr_err("Couldn't disable parallel path rc=%d\n", rc);
+ return rc;
+ }
+
+ /* initialize FCC to 0 */
+ rc = smb1355_set_charge_param(chip, &chip->param.fcc, 0);
+ if (rc < 0) {
+ pr_err("Couldn't set 0 FCC rc=%d\n", rc);
+ return rc;
+ }
+
+ /* enable parallel current sensing */
+ rc = smb1355_masked_write(chip, CFG_REG,
+ VCHG_EN_CFG_BIT, VCHG_EN_CFG_BIT);
+ if (rc < 0) {
+ pr_err("Couldn't enable parallel current sensing rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ return 0;
+}
+
+/**************************
+ * INTERRUPT REGISTRATION *
+ **************************/
+static struct smb_irq_info smb1355_irqs[] = {
+ [0] = {
+ .name = "wdog-bark",
+ .handler = smb1355_handle_wdog_bark,
+ },
+ [1] = {
+ .name = "chg-state-change",
+ .handler = smb1355_handle_chg_state_change,
+ .wake = true,
+ },
+};
+
+static int smb1355_get_irq_index_byname(const char *irq_name)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(smb1355_irqs); i++) {
+ if (strcmp(smb1355_irqs[i].name, irq_name) == 0)
+ return i;
+ }
+
+ return -ENOENT;
+}
+
+static int smb1355_request_interrupt(struct smb1355 *chip,
+ struct device_node *node,
+ const char *irq_name)
+{
+ int rc = 0, irq, irq_index;
+
+ irq = of_irq_get_byname(node, irq_name);
+ if (irq < 0) {
+ pr_err("Couldn't get irq %s byname\n", irq_name);
+ return irq;
+ }
+
+ irq_index = smb1355_get_irq_index_byname(irq_name);
+ if (irq_index < 0) {
+ pr_err("%s is not a defined irq\n", irq_name);
+ return irq_index;
+ }
+
+ if (!smb1355_irqs[irq_index].handler)
+ return 0;
+
+ rc = devm_request_threaded_irq(chip->dev, irq, NULL,
+ smb1355_irqs[irq_index].handler,
+ IRQF_ONESHOT, irq_name, chip);
+ if (rc < 0) {
+ pr_err("Couldn't request irq %d rc=%d\n", irq, rc);
+ return rc;
+ }
+
+ if (smb1355_irqs[irq_index].wake)
+ enable_irq_wake(irq);
+
+ return rc;
+}
+
+static int smb1355_request_interrupts(struct smb1355 *chip)
+{
+ struct device_node *node = chip->dev->of_node;
+ struct device_node *child;
+ int rc = 0;
+ const char *name;
+ struct property *prop;
+
+ for_each_available_child_of_node(node, child) {
+ of_property_for_each_string(child, "interrupt-names",
+ prop, name) {
+ rc = smb1355_request_interrupt(chip, child, name);
+ if (rc < 0) {
+ pr_err("Couldn't request interrupt %s rc=%d\n",
+ name, rc);
+ return rc;
+ }
+ }
+ }
+
+ return rc;
+}
+
+/*********
+ * PROBE *
+ *********/
+static const struct of_device_id match_table[] = {
+ {
+ .compatible = "qcom,smb1355",
+ },
+ { },
+};
+
+static int smb1355_probe(struct platform_device *pdev)
+{
+ struct smb1355 *chip;
+ const struct of_device_id *id;
+ int rc = 0;
+
+ chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
+ if (!chip)
+ return -ENOMEM;
+
+ chip->dev = &pdev->dev;
+ chip->param = v1_params;
+ chip->name = "smb1355";
+ mutex_init(&chip->write_lock);
+
+ chip->regmap = dev_get_regmap(chip->dev->parent, NULL);
+ if (!chip->regmap) {
+ pr_err("parent regmap is missing\n");
+ return -EINVAL;
+ }
+
+ id = of_match_device(of_match_ptr(match_table), chip->dev);
+ if (!id) {
+ pr_err("Couldn't find a matching device\n");
+ return -ENODEV;
+ }
+
+ platform_set_drvdata(pdev, chip);
+
+ rc = smb1355_init_hw(chip);
+ if (rc < 0) {
+ pr_err("Couldn't initialize hardware rc=%d\n", rc);
+ goto cleanup;
+ }
+
+ rc = smb1355_init_parallel_psy(chip);
+ if (rc < 0) {
+ pr_err("Couldn't initialize parallel psy rc=%d\n", rc);
+ goto cleanup;
+ }
+
+ rc = smb1355_request_interrupts(chip);
+ if (rc < 0) {
+ pr_err("Couldn't request interrupts rc=%d\n", rc);
+ goto cleanup;
+ }
+
+ pr_info("%s probed successfully\n", chip->name);
+ return rc;
+
+cleanup:
+ platform_set_drvdata(pdev, NULL);
+ return rc;
+}
+
+static int smb1355_remove(struct platform_device *pdev)
+{
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+static struct platform_driver smb1355_driver = {
+ .driver = {
+ .name = "qcom,smb1355-charger",
+ .owner = THIS_MODULE,
+ .of_match_table = match_table,
+ },
+ .probe = smb1355_probe,
+ .remove = smb1355_remove,
+};
+module_platform_driver(smb1355_driver);
+
+MODULE_DESCRIPTION("QPNP SMB1355 Charger Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/qcom/qdsp6v2/Makefile b/drivers/soc/qcom/qdsp6v2/Makefile
index 8c5b0d0..b2cf03c 100644
--- a/drivers/soc/qcom/qdsp6v2/Makefile
+++ b/drivers/soc/qcom/qdsp6v2/Makefile
@@ -1,7 +1,7 @@
-obj-$(CONFIG_MSM_QDSP6_APRV2) += apr.o apr_v2.o apr_tal.o voice_svc.o
-obj-$(CONFIG_MSM_QDSP6_APRV3) += apr.o apr_v3.o apr_tal.o voice_svc.o
-obj-$(CONFIG_MSM_QDSP6_APRV2_GLINK) += apr.o apr_v2.o apr_tal_glink.o voice_svc.o
-obj-$(CONFIG_MSM_QDSP6_APRV3_GLINK) += apr.o apr_v3.o apr_tal_glink.o voice_svc.o
+obj-$(CONFIG_MSM_QDSP6_APRV2) += apr.o apr_v2.o apr_tal.o
+obj-$(CONFIG_MSM_QDSP6_APRV3) += apr.o apr_v3.o apr_tal.o
+obj-$(CONFIG_MSM_QDSP6_APRV2_GLINK) += apr.o apr_v2.o apr_tal_glink.o
+obj-$(CONFIG_MSM_QDSP6_APRV3_GLINK) += apr.o apr_v3.o apr_tal_glink.o
obj-$(CONFIG_SND_SOC_MSM_QDSP6V2_INTF) += msm_audio_ion.o
obj-$(CONFIG_MSM_ADSP_LOADER) += adsp-loader.o
obj-$(CONFIG_MSM_QDSP6_SSR) += audio_ssr.o
diff --git a/drivers/soc/qcom/qdsp6v2/voice_svc.c b/drivers/soc/qcom/qdsp6v2/voice_svc.c
deleted file mode 100644
index f3b1b83..0000000
--- a/drivers/soc/qcom/qdsp6v2/voice_svc.c
+++ /dev/null
@@ -1,837 +0,0 @@
-/* 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
- * 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 <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/uaccess.h>
-#include <linux/slab.h>
-#include <linux/platform_device.h>
-#include <linux/cdev.h>
-#include <linux/qdsp6v2/apr_tal.h>
-#include <linux/qdsp6v2/apr.h>
-#include <sound/voice_svc.h>
-
-#define MINOR_NUMBER 1
-#define APR_MAX_RESPONSE 10
-#define TIMEOUT_MS 1000
-
-#define MAX(a, b) ((a) >= (b) ? (a) : (b))
-
-struct voice_svc_device {
- struct cdev *cdev;
- struct device *dev;
- int major;
-};
-
-struct voice_svc_prvt {
- void *apr_q6_mvm;
- void *apr_q6_cvs;
- uint16_t response_count;
- struct list_head response_queue;
- wait_queue_head_t response_wait;
- spinlock_t response_lock;
- /*
- * This mutex ensures responses are processed in sequential order and
- * that no two threads access and free the same response at the same
- * time.
- */
- struct mutex response_mutex_lock;
-};
-
-struct apr_data {
- struct apr_hdr hdr;
- __u8 payload[0];
-} __packed;
-
-struct apr_response_list {
- struct list_head list;
- struct voice_svc_cmd_response resp;
-};
-
-static struct voice_svc_device *voice_svc_dev;
-static struct class *voice_svc_class;
-static bool reg_dummy_sess;
-static void *dummy_q6_mvm;
-static void *dummy_q6_cvs;
-dev_t device_num;
-
-static int voice_svc_dummy_reg(void);
-static int32_t qdsp_dummy_apr_callback(struct apr_client_data *data,
- void *priv);
-
-static int32_t qdsp_apr_callback(struct apr_client_data *data, void *priv)
-{
- struct voice_svc_prvt *prtd;
- struct apr_response_list *response_list;
- unsigned long spin_flags;
-
- if ((data == NULL) || (priv == NULL)) {
- pr_err("%s: data or priv is NULL\n", __func__);
-
- return -EINVAL;
- }
-
- prtd = (struct voice_svc_prvt *)priv;
- if (prtd == NULL) {
- pr_err("%s: private data is NULL\n", __func__);
-
- return -EINVAL;
- }
-
- pr_debug("%s: data->opcode %x\n", __func__,
- data->opcode);
-
- if (data->opcode == RESET_EVENTS) {
- if (data->reset_proc == APR_DEST_QDSP6) {
- pr_debug("%s: Received ADSP reset event\n", __func__);
-
- if (prtd->apr_q6_mvm != NULL) {
- apr_reset(prtd->apr_q6_mvm);
- prtd->apr_q6_mvm = NULL;
- }
-
- if (prtd->apr_q6_cvs != NULL) {
- apr_reset(prtd->apr_q6_cvs);
- prtd->apr_q6_cvs = NULL;
- }
- } else if (data->reset_proc == APR_DEST_MODEM) {
- pr_debug("%s: Received Modem reset event\n", __func__);
- }
- /* Set the remaining member variables to default values
- * for RESET_EVENTS
- */
- data->payload_size = 0;
- data->payload = NULL;
- data->src_port = 0;
- data->dest_port = 0;
- data->token = 0;
- }
-
- spin_lock_irqsave(&prtd->response_lock, spin_flags);
-
- if (prtd->response_count < APR_MAX_RESPONSE) {
- response_list = kmalloc(sizeof(struct apr_response_list) +
- data->payload_size, GFP_ATOMIC);
- if (response_list == NULL) {
- spin_unlock_irqrestore(&prtd->response_lock,
- spin_flags);
- return -ENOMEM;
- }
-
- response_list->resp.src_port = data->src_port;
-
- /* Reverting the bit manipulation done in voice_svc_update_hdr
- * to the src_port which is returned to us as dest_port.
- */
- response_list->resp.dest_port = ((data->dest_port) >> 8);
- response_list->resp.token = data->token;
- response_list->resp.opcode = data->opcode;
- response_list->resp.payload_size = data->payload_size;
- if (data->payload != NULL && data->payload_size > 0) {
- memcpy(response_list->resp.payload, data->payload,
- data->payload_size);
- }
-
- list_add_tail(&response_list->list, &prtd->response_queue);
- prtd->response_count++;
- spin_unlock_irqrestore(&prtd->response_lock, spin_flags);
-
- wake_up(&prtd->response_wait);
- } else {
- spin_unlock_irqrestore(&prtd->response_lock, spin_flags);
- pr_err("%s: Response dropped since the queue is full\n",
- __func__);
- }
-
- return 0;
-}
-
-static int32_t qdsp_dummy_apr_callback(struct apr_client_data *data, void *priv)
-{
- /* Do Nothing */
- return 0;
-}
-
-static void voice_svc_update_hdr(struct voice_svc_cmd_request *apr_req_data,
- struct apr_data *aprdata)
-{
-
- aprdata->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(sizeof(struct apr_hdr)),
- APR_PKT_VER);
- /* Bit manipulation is done on src_port so that a unique ID is sent.
- * This manipulation can be used in the future where the same service
- * is tried to open multiple times with the same src_port. At that
- * time 0x0001 can be replaced with other values depending on the
- * count.
- */
- aprdata->hdr.src_port = ((apr_req_data->src_port) << 8 | 0x0001);
- aprdata->hdr.dest_port = apr_req_data->dest_port;
- aprdata->hdr.token = apr_req_data->token;
- aprdata->hdr.opcode = apr_req_data->opcode;
- aprdata->hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
- apr_req_data->payload_size);
- memcpy(aprdata->payload, apr_req_data->payload,
- apr_req_data->payload_size);
-}
-
-static int voice_svc_send_req(struct voice_svc_cmd_request *apr_request,
- struct voice_svc_prvt *prtd)
-{
- int ret = 0;
- void *apr_handle = NULL;
- struct apr_data *aprdata = NULL;
- uint32_t user_payload_size;
- uint32_t payload_size;
-
- pr_debug("%s\n", __func__);
-
- if (apr_request == NULL) {
- pr_err("%s: apr_request is NULL\n", __func__);
-
- ret = -EINVAL;
- goto done;
- }
-
- user_payload_size = apr_request->payload_size;
- payload_size = sizeof(struct apr_data) + user_payload_size;
-
- if (payload_size <= user_payload_size) {
- pr_err("%s: invalid payload size ( 0x%x ).\n",
- __func__, user_payload_size);
- ret = -EINVAL;
- goto done;
- } else {
- aprdata = kmalloc(payload_size, GFP_KERNEL);
- if (aprdata == NULL) {
- ret = -ENOMEM;
- goto done;
- }
- }
-
- voice_svc_update_hdr(apr_request, aprdata);
-
- if (!strcmp(apr_request->svc_name, VOICE_SVC_CVS_STR)) {
- apr_handle = prtd->apr_q6_cvs;
- } else if (!strcmp(apr_request->svc_name, VOICE_SVC_MVM_STR)) {
- apr_handle = prtd->apr_q6_mvm;
- } else {
- pr_err("%s: Invalid service %.*s\n", __func__,
- MAX_APR_SERVICE_NAME_LEN, apr_request->svc_name);
-
- ret = -EINVAL;
- goto done;
- }
-
- ret = apr_send_pkt(apr_handle, (uint32_t *)aprdata);
-
- if (ret < 0) {
- pr_err("%s: Fail in sending request %d\n",
- __func__, ret);
- ret = -EINVAL;
- } else {
- pr_debug("%s: apr packet sent successfully %d\n",
- __func__, ret);
- ret = 0;
- }
-
-done:
- kfree(aprdata);
- return ret;
-}
-static int voice_svc_reg(char *svc, uint32_t src_port,
- struct voice_svc_prvt *prtd, void **handle)
-{
- int ret = 0;
-
- pr_debug("%s\n", __func__);
-
- if (handle == NULL) {
- pr_err("%s: handle is NULL\n", __func__);
- ret = -EINVAL;
- goto done;
- }
-
- if (*handle != NULL) {
- pr_err("%s: svc handle not NULL\n", __func__);
- ret = -EINVAL;
- goto done;
- }
-
- if (src_port == (APR_MAX_PORTS - 1)) {
- pr_err("%s: SRC port reserved for dummy session\n", __func__);
- pr_err("%s: Unable to register %s\n", __func__, svc);
- ret = -EINVAL;
- goto done;
- }
-
- *handle = apr_register("ADSP",
- svc, qdsp_apr_callback,
- ((src_port) << 8 | 0x0001),
- prtd);
-
- if (*handle == NULL) {
- pr_err("%s: Unable to register %s\n",
- __func__, svc);
-
- ret = -EFAULT;
- goto done;
- }
- pr_debug("%s: Register %s successful\n",
- __func__, svc);
-done:
- return ret;
-}
-
-static int voice_svc_dereg(char *svc, void **handle)
-{
- int ret = 0;
-
- pr_debug("%s\n", __func__);
-
- if (handle == NULL) {
- pr_err("%s: handle is NULL\n", __func__);
- ret = -EINVAL;
- goto done;
- }
-
- if (*handle == NULL) {
- pr_err("%s: svc handle is NULL\n", __func__);
- ret = -EINVAL;
- goto done;
- }
-
- ret = apr_deregister(*handle);
- if (ret) {
- pr_err("%s: Unable to deregister service %s; error: %d\n",
- __func__, svc, ret);
-
- goto done;
- }
- *handle = NULL;
- pr_debug("%s: deregister %s successful\n", __func__, svc);
-
-done:
- return ret;
-}
-
-static int process_reg_cmd(struct voice_svc_register *apr_reg_svc,
- struct voice_svc_prvt *prtd)
-{
- int ret = 0;
- char *svc = NULL;
- void **handle = NULL;
-
- pr_debug("%s\n", __func__);
-
- if (!strcmp(apr_reg_svc->svc_name, VOICE_SVC_MVM_STR)) {
- svc = VOICE_SVC_MVM_STR;
- handle = &prtd->apr_q6_mvm;
- } else if (!strcmp(apr_reg_svc->svc_name, VOICE_SVC_CVS_STR)) {
- svc = VOICE_SVC_CVS_STR;
- handle = &prtd->apr_q6_cvs;
- } else {
- pr_err("%s: Invalid Service: %.*s\n", __func__,
- MAX_APR_SERVICE_NAME_LEN, apr_reg_svc->svc_name);
- ret = -EINVAL;
- goto done;
- }
-
- if (apr_reg_svc->reg_flag) {
- ret = voice_svc_reg(svc, apr_reg_svc->src_port, prtd,
- handle);
- } else if (!apr_reg_svc->reg_flag) {
- ret = voice_svc_dereg(svc, handle);
- }
-
-done:
- return ret;
-}
-
-static ssize_t voice_svc_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- int ret = 0;
- struct voice_svc_prvt *prtd;
- struct voice_svc_write_msg *data = NULL;
- uint32_t cmd;
- struct voice_svc_register *register_data = NULL;
- struct voice_svc_cmd_request *request_data = NULL;
- uint32_t request_payload_size;
-
- pr_debug("%s\n", __func__);
-
- /*
- * Check if enough memory is allocated to parse the message type.
- * Will check there is enough to hold the payload later.
- */
- if (count >= sizeof(struct voice_svc_write_msg)) {
- data = kmalloc(count, GFP_KERNEL);
- } else {
- pr_debug("%s: invalid data size\n", __func__);
- ret = -EINVAL;
- goto done;
- }
-
- if (data == NULL) {
- pr_err("%s: data kmalloc failed.\n", __func__);
-
- ret = -ENOMEM;
- goto done;
- }
-
- ret = copy_from_user(data, buf, count);
- if (ret) {
- pr_err("%s: copy_from_user failed %d\n", __func__, ret);
-
- ret = -EPERM;
- goto done;
- }
-
- cmd = data->msg_type;
- prtd = (struct voice_svc_prvt *) file->private_data;
- if (prtd == NULL) {
- pr_err("%s: prtd is NULL\n", __func__);
-
- ret = -EINVAL;
- goto done;
- }
-
- switch (cmd) {
- case MSG_REGISTER:
- /*
- * Check that count reflects the expected size to ensure
- * sufficient memory was allocated. Since voice_svc_register
- * has a static size, this should be exact.
- */
- if (count == (sizeof(struct voice_svc_write_msg) +
- sizeof(struct voice_svc_register))) {
- register_data =
- (struct voice_svc_register *)data->payload;
- if (register_data == NULL) {
- pr_err("%s: register data is NULL", __func__);
- ret = -EINVAL;
- goto done;
- }
- ret = process_reg_cmd(register_data, prtd);
- if (!ret)
- ret = count;
- } else {
- pr_err("%s: invalid data payload size for register command\n",
- __func__);
- ret = -EINVAL;
- goto done;
- }
- break;
- case MSG_REQUEST:
- /*
- * Check that count reflects the expected size to ensure
- * sufficient memory was allocated. Since voice_svc_cmd_request
- * has a variable size, check the minimum value count must be to
- * parse the message request then check the minimum size to hold
- * the payload of the message request.
- */
- if (count >= (sizeof(struct voice_svc_write_msg) +
- sizeof(struct voice_svc_cmd_request))) {
- request_data =
- (struct voice_svc_cmd_request *)data->payload;
- if (request_data == NULL) {
- pr_err("%s: request data is NULL", __func__);
- ret = -EINVAL;
- goto done;
- }
-
- request_payload_size = request_data->payload_size;
-
- if (count >= (sizeof(struct voice_svc_write_msg) +
- sizeof(struct voice_svc_cmd_request) +
- request_payload_size)) {
- ret = voice_svc_send_req(request_data, prtd);
- if (!ret)
- ret = count;
- } else {
- pr_err("%s: invalid request payload size\n",
- __func__);
- ret = -EINVAL;
- goto done;
- }
- } else {
- pr_err("%s: invalid data payload size for request command\n",
- __func__);
- ret = -EINVAL;
- goto done;
- }
- break;
- default:
- pr_debug("%s: Invalid command: %u\n", __func__, cmd);
- ret = -EINVAL;
- }
-
-done:
- kfree(data);
- return ret;
-}
-
-static ssize_t voice_svc_read(struct file *file, char __user *arg,
- size_t count, loff_t *ppos)
-{
- int ret = 0;
- struct voice_svc_prvt *prtd;
- struct apr_response_list *resp;
- unsigned long spin_flags;
- int size;
-
- pr_debug("%s\n", __func__);
-
- prtd = (struct voice_svc_prvt *)file->private_data;
- if (prtd == NULL) {
- pr_err("%s: prtd is NULL\n", __func__);
-
- ret = -EINVAL;
- goto done;
- }
-
- mutex_lock(&prtd->response_mutex_lock);
- spin_lock_irqsave(&prtd->response_lock, spin_flags);
-
- if (list_empty(&prtd->response_queue)) {
- spin_unlock_irqrestore(&prtd->response_lock, spin_flags);
- pr_debug("%s: wait for a response\n", __func__);
-
- ret = wait_event_interruptible_timeout(prtd->response_wait,
- !list_empty(&prtd->response_queue),
- msecs_to_jiffies(TIMEOUT_MS));
- if (ret == 0) {
- pr_debug("%s: Read timeout\n", __func__);
-
- ret = -ETIMEDOUT;
- goto unlock;
- } else if (ret > 0 && !list_empty(&prtd->response_queue)) {
- pr_debug("%s: Interrupt received for response\n",
- __func__);
- } else if (ret < 0) {
- pr_debug("%s: Interrupted by SIGNAL %d\n",
- __func__, ret);
-
- goto unlock;
- }
-
- spin_lock_irqsave(&prtd->response_lock, spin_flags);
- }
-
- resp = list_first_entry(&prtd->response_queue,
- struct apr_response_list, list);
-
- spin_unlock_irqrestore(&prtd->response_lock, spin_flags);
-
- size = resp->resp.payload_size +
- sizeof(struct voice_svc_cmd_response);
-
- if (count < size) {
- pr_err("%s: Invalid payload size %zd, %d\n",
- __func__, count, size);
-
- ret = -ENOMEM;
- goto unlock;
- }
-
- if (!access_ok(VERIFY_WRITE, arg, size)) {
- pr_err("%s: Access denied to write\n",
- __func__);
-
- ret = -EPERM;
- goto unlock;
- }
-
- ret = copy_to_user(arg, &resp->resp,
- sizeof(struct voice_svc_cmd_response) +
- resp->resp.payload_size);
- if (ret) {
- pr_err("%s: copy_to_user failed %d\n", __func__, ret);
-
- ret = -EPERM;
- goto unlock;
- }
-
- spin_lock_irqsave(&prtd->response_lock, spin_flags);
-
- list_del(&resp->list);
- prtd->response_count--;
- kfree(resp);
-
- spin_unlock_irqrestore(&prtd->response_lock,
- spin_flags);
-
- ret = count;
-
-unlock:
- mutex_unlock(&prtd->response_mutex_lock);
-done:
- return ret;
-}
-
-static int voice_svc_dummy_reg(void)
-{
- uint32_t src_port = APR_MAX_PORTS - 1;
-
- pr_debug("%s\n", __func__);
- dummy_q6_mvm = apr_register("ADSP", "MVM",
- qdsp_dummy_apr_callback,
- src_port,
- NULL);
- if (dummy_q6_mvm == NULL) {
- pr_err("%s: Unable to register dummy MVM\n", __func__);
- goto err;
- }
-
- dummy_q6_cvs = apr_register("ADSP", "CVS",
- qdsp_dummy_apr_callback,
- src_port,
- NULL);
- if (dummy_q6_cvs == NULL) {
- pr_err("%s: Unable to register dummy CVS\n", __func__);
- goto err;
- }
- return 0;
-err:
- if (dummy_q6_mvm != NULL) {
- apr_deregister(dummy_q6_mvm);
- dummy_q6_mvm = NULL;
- }
- return -EINVAL;
-}
-
-static int voice_svc_open(struct inode *inode, struct file *file)
-{
- struct voice_svc_prvt *prtd = NULL;
-
- pr_debug("%s\n", __func__);
-
- prtd = kmalloc(sizeof(struct voice_svc_prvt), GFP_KERNEL);
-
- if (prtd == NULL)
- return -ENOMEM;
-
- memset(prtd, 0, sizeof(struct voice_svc_prvt));
- prtd->apr_q6_cvs = NULL;
- prtd->apr_q6_mvm = NULL;
- prtd->response_count = 0;
- INIT_LIST_HEAD(&prtd->response_queue);
- init_waitqueue_head(&prtd->response_wait);
- spin_lock_init(&prtd->response_lock);
- mutex_init(&prtd->response_mutex_lock);
- file->private_data = (void *)prtd;
-
- /* Current APR implementation doesn't support session based
- * multiple service registrations. The apr_deregister()
- * function sets the destination and client IDs to zero, if
- * deregister is called for a single service instance.
- * To avoid this, register for additional services.
- */
- if (!reg_dummy_sess) {
- voice_svc_dummy_reg();
- reg_dummy_sess = 1;
- }
- return 0;
-}
-
-static int voice_svc_release(struct inode *inode, struct file *file)
-{
- int ret = 0;
- struct apr_response_list *resp = NULL;
- unsigned long spin_flags;
- struct voice_svc_prvt *prtd = NULL;
- char *svc_name = NULL;
- void **handle = NULL;
-
- pr_debug("%s\n", __func__);
-
- prtd = (struct voice_svc_prvt *)file->private_data;
- if (prtd == NULL) {
- pr_err("%s: prtd is NULL\n", __func__);
-
- ret = -EINVAL;
- goto done;
- }
-
- if (prtd->apr_q6_cvs != NULL) {
- svc_name = VOICE_SVC_MVM_STR;
- handle = &prtd->apr_q6_cvs;
- ret = voice_svc_dereg(svc_name, handle);
- if (ret)
- pr_err("%s: Failed to dereg CVS %d\n", __func__, ret);
- }
-
- if (prtd->apr_q6_mvm != NULL) {
- svc_name = VOICE_SVC_MVM_STR;
- handle = &prtd->apr_q6_mvm;
- ret = voice_svc_dereg(svc_name, handle);
- if (ret)
- pr_err("%s: Failed to dereg MVM %d\n", __func__, ret);
- }
-
- mutex_lock(&prtd->response_mutex_lock);
- spin_lock_irqsave(&prtd->response_lock, spin_flags);
-
- while (!list_empty(&prtd->response_queue)) {
- pr_debug("%s: Remove item from response queue\n", __func__);
-
- resp = list_first_entry(&prtd->response_queue,
- struct apr_response_list, list);
- list_del(&resp->list);
- prtd->response_count--;
- kfree(resp);
- }
-
- spin_unlock_irqrestore(&prtd->response_lock, spin_flags);
- mutex_unlock(&prtd->response_mutex_lock);
-
- mutex_destroy(&prtd->response_mutex_lock);
-
- kfree(file->private_data);
- file->private_data = NULL;
-
-done:
- return ret;
-}
-
-static const struct file_operations voice_svc_fops = {
- .owner = THIS_MODULE,
- .open = voice_svc_open,
- .read = voice_svc_read,
- .write = voice_svc_write,
- .release = voice_svc_release,
-};
-
-
-static int voice_svc_probe(struct platform_device *pdev)
-{
- int ret = 0;
-
- pr_debug("%s\n", __func__);
-
- voice_svc_dev = devm_kzalloc(&pdev->dev,
- sizeof(struct voice_svc_device), GFP_KERNEL);
- if (!voice_svc_dev) {
- ret = -ENOMEM;
- goto done;
- }
-
- ret = alloc_chrdev_region(&device_num, 0, MINOR_NUMBER,
- VOICE_SVC_DRIVER_NAME);
- if (ret) {
- pr_err("%s: Failed to alloc chrdev\n", __func__);
- ret = -ENODEV;
- goto chrdev_err;
- }
-
- voice_svc_dev->major = MAJOR(device_num);
- voice_svc_class = class_create(THIS_MODULE, VOICE_SVC_DRIVER_NAME);
- if (IS_ERR(voice_svc_class)) {
- ret = PTR_ERR(voice_svc_class);
- pr_err("%s: Failed to create class; err = %d\n", __func__,
- ret);
- goto class_err;
- }
-
- voice_svc_dev->dev = device_create(voice_svc_class, NULL, device_num,
- NULL, VOICE_SVC_DRIVER_NAME);
- if (IS_ERR(voice_svc_dev->dev)) {
- ret = PTR_ERR(voice_svc_dev->dev);
- pr_err("%s: Failed to create device; err = %d\n", __func__,
- ret);
- goto dev_err;
- }
-
- voice_svc_dev->cdev = cdev_alloc();
- if (!voice_svc_dev->cdev) {
- pr_err("%s: Failed to alloc cdev\n", __func__);
- ret = -ENOMEM;
- goto cdev_alloc_err;
- }
-
- cdev_init(voice_svc_dev->cdev, &voice_svc_fops);
- ret = cdev_add(voice_svc_dev->cdev, device_num, MINOR_NUMBER);
- if (ret) {
- pr_err("%s: Failed to register chrdev; err = %d\n", __func__,
- ret);
- goto add_err;
- }
- pr_debug("%s: Device created\n", __func__);
- goto done;
-
-add_err:
- cdev_del(voice_svc_dev->cdev);
-cdev_alloc_err:
- device_destroy(voice_svc_class, device_num);
-dev_err:
- class_destroy(voice_svc_class);
-class_err:
- unregister_chrdev_region(0, MINOR_NUMBER);
-chrdev_err:
- kfree(voice_svc_dev);
-done:
- return ret;
-}
-
-static int voice_svc_remove(struct platform_device *pdev)
-{
- pr_debug("%s\n", __func__);
-
- cdev_del(voice_svc_dev->cdev);
- kfree(voice_svc_dev->cdev);
- device_destroy(voice_svc_class, device_num);
- class_destroy(voice_svc_class);
- unregister_chrdev_region(0, MINOR_NUMBER);
- kfree(voice_svc_dev);
-
- return 0;
-}
-
-static const struct of_device_id voice_svc_of_match[] = {
- {.compatible = "qcom,msm-voice-svc"},
- { }
-};
-MODULE_DEVICE_TABLE(of, voice_svc_of_match);
-
-static struct platform_driver voice_svc_driver = {
- .probe = voice_svc_probe,
- .remove = voice_svc_remove,
- .driver = {
- .name = "msm-voice-svc",
- .owner = THIS_MODULE,
- .of_match_table = voice_svc_of_match,
- },
-};
-
-static int __init voice_svc_init(void)
-{
- pr_debug("%s\n", __func__);
-
- return platform_driver_register(&voice_svc_driver);
-}
-
-static void __exit voice_svc_exit(void)
-{
- pr_debug("%s\n", __func__);
-
- platform_driver_unregister(&voice_svc_driver);
-}
-
-module_init(voice_svc_init);
-module_exit(voice_svc_exit);
-
-MODULE_DESCRIPTION("Soc QDSP6v2 Voice Service driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index 37125c0..7da9211 100644
--- a/drivers/thermal/cpu_cooling.c
+++ b/drivers/thermal/cpu_cooling.c
@@ -909,13 +909,11 @@
struct cpufreq_cooling_device *cpufreq_dev;
char dev_name[THERMAL_NAME_LENGTH];
struct cpufreq_frequency_table *pos, *table;
- struct cpumask temp_mask;
unsigned int freq, i, num_cpus;
int ret;
struct thermal_cooling_device_ops *cooling_ops;
- cpumask_and(&temp_mask, clip_cpus, cpu_online_mask);
- policy = cpufreq_cpu_get(cpumask_first(&temp_mask));
+ policy = cpufreq_cpu_get(cpumask_first(clip_cpus));
if (!policy) {
pr_debug("%s: CPUFreq policy not found\n", __func__);
return ERR_PTR(-EPROBE_DEFER);
diff --git a/drivers/tty/serial/msm_geni_serial.c b/drivers/tty/serial/msm_geni_serial.c
index 3fec1d7..6a3f2ac 100644
--- a/drivers/tty/serial/msm_geni_serial.c
+++ b/drivers/tty/serial/msm_geni_serial.c
@@ -379,7 +379,6 @@
ret = pm_runtime_get_sync(uport->dev);
if (ret < 0) {
- dev_err(uport->dev, "%s: Failed (%d)", __func__, ret);
pm_runtime_put_noidle(uport->dev);
pm_runtime_set_suspended(uport->dev);
return ret;
@@ -489,10 +488,8 @@
unsigned int s_irq_status;
if (!(msm_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
- M_SEC_IRQ_EN, true))) {
- dev_err(uport->dev, "%s: Failed waiting for SE\n", __func__);
+ M_SEC_IRQ_EN, true)))
return -ENXIO;
- }
m_irq_status = geni_read_reg_nolog(uport->membase,
SE_GENI_M_IRQ_STATUS);
@@ -504,10 +501,8 @@
SE_GENI_S_IRQ_CLEAR);
if (!(msm_geni_serial_poll_bit(uport, SE_GENI_RX_FIFO_STATUS,
- RX_FIFO_WC_MSK, true))) {
- dev_err(uport->dev, "%s: Failed waiting for Rx\n", __func__);
+ RX_FIFO_WC_MSK, true)))
return -ENXIO;
- }
/*
* Read the Rx FIFO only after clearing the interrupt registers and
@@ -610,10 +605,8 @@
WARN_ON(co->index < 0 || co->index >= GENI_UART_NR_PORTS);
port = get_port_from_line(co->index, true);
- if (IS_ERR_OR_NULL(port)) {
- pr_err("%s:Invalid line %d\n", __func__, co->index);
+ if (IS_ERR_OR_NULL(port))
return;
- }
uport = &port->uport;
spin_lock(&uport->lock);
@@ -982,7 +975,7 @@
port->tx_fifo_width = get_tx_fifo_width(uport->membase);
if (!port->tx_fifo_width) {
dev_err(uport->dev, "%s:Invalid TX FIFO width read\n",
- __func__);
+ __func__);
return -ENXIO;
}
diff --git a/include/sound/voice_svc.h b/include/sound/voice_svc.h
deleted file mode 100644
index 035053f..0000000
--- a/include/sound/voice_svc.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef __VOICE_SVC_H__
-#define __VOICE_SVC_H__
-
-#include <linux/types.h>
-#include <linux/ioctl.h>
-
-#define VOICE_SVC_DRIVER_NAME "voice_svc"
-
-#define VOICE_SVC_MVM_STR "MVM"
-#define VOICE_SVC_CVS_STR "CVS"
-#define MAX_APR_SERVICE_NAME_LEN 64
-
-#define MSG_REGISTER 0x1
-#define MSG_REQUEST 0x2
-#define MSG_RESPONSE 0x3
-
-struct voice_svc_write_msg {
- __u32 msg_type;
- __u8 payload[0];
-};
-
-struct voice_svc_register {
- char svc_name[MAX_APR_SERVICE_NAME_LEN];
- __u32 src_port;
- __u8 reg_flag;
-};
-
-struct voice_svc_cmd_response {
- __u32 src_port;
- __u32 dest_port;
- __u32 token;
- __u32 opcode;
- __u32 payload_size;
- __u8 payload[0];
-};
-
-struct voice_svc_cmd_request {
- char svc_name[MAX_APR_SERVICE_NAME_LEN];
- __u32 src_port;
- __u32 dest_port;
- __u32 token;
- __u32 opcode;
- __u32 payload_size;
- __u8 payload[0];
-};
-
-#endif
diff --git a/include/uapi/sound/Kbuild b/include/uapi/sound/Kbuild
index b0350f0..27e9ef8 100644
--- a/include/uapi/sound/Kbuild
+++ b/include/uapi/sound/Kbuild
@@ -18,7 +18,6 @@
header-y += audio_slimslave.h
header-y += voice_params.h
header-y += audio_effects.h
-header-y += voice_svc.h
header-y += devdep_params.h
header-y += msmcal-hwdep.h
header-y += wcd-dsp-glink.h
diff --git a/init/Kconfig b/init/Kconfig
index 007186d..2c382dc1 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -795,19 +795,6 @@
endchoice
-config RCU_EXPEDITE_BOOT
- bool
- default n
- help
- This option enables expedited grace periods at boot time,
- as if rcu_expedite_gp() had been invoked early in boot.
- The corresponding rcu_unexpedite_gp() is invoked from
- rcu_end_inkernel_boot(), which is intended to be invoked
- at the end of the kernel-only boot sequence, just before
- init is exec'ed.
-
- Accept the default if unsure.
-
endmenu # "RCU Subsystem"
config BUILD_BIN2C
diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c
index 4f6db7e..9e03db9 100644
--- a/kernel/rcu/update.c
+++ b/kernel/rcu/update.c
@@ -132,8 +132,7 @@
}
EXPORT_SYMBOL_GPL(rcu_gp_is_normal);
-static atomic_t rcu_expedited_nesting =
- ATOMIC_INIT(IS_ENABLED(CONFIG_RCU_EXPEDITE_BOOT) ? 1 : 0);
+static atomic_t rcu_expedited_nesting = ATOMIC_INIT(1);
/*
* Should normal grace-period primitives be expedited? Intended for
@@ -182,8 +181,7 @@
*/
void rcu_end_inkernel_boot(void)
{
- if (IS_ENABLED(CONFIG_RCU_EXPEDITE_BOOT))
- rcu_unexpedite_gp();
+ rcu_unexpedite_gp();
if (rcu_normal_after_boot)
WRITE_ONCE(rcu_normal, 1);
}