Merge "msm: fbdev: add safety check for msm fb data object"
diff --git a/arch/arm64/boot/dts/qcom/apq8009-robot-som-refboard.dts b/arch/arm64/boot/dts/qcom/apq8009-robot-som-refboard.dts
index 103ef7f..f57383c 100644
--- a/arch/arm64/boot/dts/qcom/apq8009-robot-som-refboard.dts
+++ b/arch/arm64/boot/dts/qcom/apq8009-robot-som-refboard.dts
@@ -387,6 +387,10 @@
status = "okay";
};
+&mdss_fb0 {
+ /delete-node/ qcom,cont-splash-memory;
+};
+
&mdss_mdp {
qcom,mdss-pref-prim-intf = "dsi";
status = "okay";
@@ -436,3 +440,5 @@
status = "okay";
};
};
+
+/delete-node/ &cont_splash_mem;
diff --git a/arch/arm64/boot/dts/qcom/msm8953-ext-codec-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/msm8953-ext-codec-mtp-overlay.dts
index 1b09b3c..350d88a 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-ext-codec-mtp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/msm8953-ext-codec-mtp-overlay.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, 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
@@ -46,6 +46,7 @@
qcom,battery-data = <&mtp_batterydata>;
qcom,chg-led-sw-controls;
qcom,chg-led-support;
+ qcom,usbin-vadc = <&pmi8950_vadc>;
};
&int_codec {
diff --git a/arch/arm64/boot/dts/qcom/msm8953-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/msm8953-mtp-overlay.dts
index 00614b2..92cd98d 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-mtp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/msm8953-mtp-overlay.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, 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
@@ -44,4 +44,5 @@
qcom,battery-data = <&mtp_batterydata>;
qcom,chg-led-sw-controls;
qcom,chg-led-support;
+ qcom,usbin-vadc = <&pmi8950_vadc>;
};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-mtp.dts b/arch/arm64/boot/dts/qcom/msm8953-mtp.dts
index 9b20013..e936adf 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/msm8953-mtp.dts
@@ -48,6 +48,7 @@
qcom,battery-data = <&mtp_batterydata>;
qcom,chg-led-sw-controls;
qcom,chg-led-support;
+ qcom,usbin-vadc = <&pmi8950_vadc>;
};
&cci {
qcom,camera@0 {
diff --git a/arch/arm64/boot/dts/qcom/sda429-bg-wtp-overlay.dts b/arch/arm64/boot/dts/qcom/sda429-bg-wtp-overlay.dts
index 9602dd8..d12b346 100644
--- a/arch/arm64/boot/dts/qcom/sda429-bg-wtp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sda429-bg-wtp-overlay.dts
@@ -24,6 +24,115 @@
qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>;
};
+&soc {
+
+ qcom,blackghost {
+ compatible = "qcom,pil-blackghost";
+ qcom,pil-force-shutdown;
+ qcom,firmware-name = "bg-wear";
+ /* GPIO inputs from blackghost */
+ qcom,bg2ap-status-gpio = <&msm_gpio 44 0>;
+ qcom,bg2ap-errfatal-gpio = <&msm_gpio 72 0>;
+ /* GPIO output to blackghost */
+ qcom,ap2bg-status-gpio = <&msm_gpio 61 0>;
+ qcom,ap2bg-errfatal-gpio = <&msm_gpio 62 0>;
+ };
+
+ qcom,msm-ssc-sensors {
+ compatible = "qcom,msm-ssc-sensors";
+ };
+
+ qcom,glink-bgcom-xprt-bg {
+ compatible = "qcom,glink-bgcom-xprt";
+ label = "bg";
+ qcom,qos-config = <&glink_qos_bg>;
+ qcom,ramp-time = <0x10>,
+ <0x20>,
+ <0x30>,
+ <0x40>;
+ };
+
+ glink_qos_bg: qcom,glink-qos-config-bg {
+ compatible = "qcom,glink-qos-config";
+ qcom,flow-info = <0x80 0x0>,
+ <0x70 0x1>,
+ <0x60 0x2>,
+ <0x50 0x3>;
+ qcom,mtu-size = <0x800>;
+ qcom,tput-stats-cycle = <0xa>;
+ };
+
+ qcom,glink_pkt {
+ compatible = "qcom,glinkpkt";
+
+ qcom,glinkpkt-bg-daemon {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "bg-daemon";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_daemon";
+ };
+
+ qcom,glinkpkt-bg-display-ctrl {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "display-ctrl";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_display_ctrl";
+ };
+
+ qcom,glinkpkt-bg-display-data {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "display-data";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_display_data";
+ };
+
+ qcom,glinkpkt-bg-rsb-ctrl {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "RSB_CTRL";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_rsb_ctrl";
+ };
+
+ qcom,glinkpkt-bg-sso-ctrl {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "sso-ctrl";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_sso_ctrl";
+ };
+
+ qcom,glinkpkt-bg-buzzer-ctrl {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "buzzer-ctrl";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_buzzer_ctrl";
+ };
+ };
+
+ spi@78B8000 { /* BLSP1 QUP4 */
+ status = "ok";
+ qcom,bg-spi {
+ compatible = "qcom,bg-spi";
+ reg = <0>;
+ spi-max-frequency = <16000000>;
+ interrupt-parent = <&msm_gpio>;
+ qcom,irq-gpio = <&msm_gpio 43 1>;
+ };
+ };
+
+ qcom,bg-rsb {
+ compatible = "qcom,bg-rsb";
+ vdd-ldo1-supply = <&pm660_l11>;
+ vdd-ldo2-supply = <&pm660_l15>;
+ };
+
+ qcom,bg-daemon {
+ compatible = "qcom,bg-daemon";
+ qcom,bg-reset-gpio = <&pm660_gpios 5 0>;
+ ssr-reg1-supply = <&pm660_l3>;
+ ssr-reg2-supply = <&pm660_l9>;
+ };
+};
+
&usb_otg {
HSUSB_3p3-supply = <&L16A>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm429-bg-wdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm429-bg-wdp-overlay.dts
index a7ce1bd..53229a0 100644
--- a/arch/arm64/boot/dts/qcom/sdm429-bg-wdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm429-bg-wdp-overlay.dts
@@ -24,6 +24,115 @@
qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>;
};
+&soc {
+
+ qcom,blackghost {
+ compatible = "qcom,pil-blackghost";
+ qcom,pil-force-shutdown;
+ qcom,firmware-name = "bg-wear";
+ /* GPIO inputs from blackghost */
+ qcom,bg2ap-status-gpio = <&msm_gpio 44 0>;
+ qcom,bg2ap-errfatal-gpio = <&msm_gpio 72 0>;
+ /* GPIO output to blackghost */
+ qcom,ap2bg-status-gpio = <&msm_gpio 61 0>;
+ qcom,ap2bg-errfatal-gpio = <&msm_gpio 62 0>;
+ };
+
+ qcom,msm-ssc-sensors {
+ compatible = "qcom,msm-ssc-sensors";
+ };
+
+ qcom,glink-bgcom-xprt-bg {
+ compatible = "qcom,glink-bgcom-xprt";
+ label = "bg";
+ qcom,qos-config = <&glink_qos_bg>;
+ qcom,ramp-time = <0x10>,
+ <0x20>,
+ <0x30>,
+ <0x40>;
+ };
+
+ glink_qos_bg: qcom,glink-qos-config-bg {
+ compatible = "qcom,glink-qos-config";
+ qcom,flow-info = <0x80 0x0>,
+ <0x70 0x1>,
+ <0x60 0x2>,
+ <0x50 0x3>;
+ qcom,mtu-size = <0x800>;
+ qcom,tput-stats-cycle = <0xa>;
+ };
+
+ qcom,glink_pkt {
+ compatible = "qcom,glinkpkt";
+
+ qcom,glinkpkt-bg-daemon {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "bg-daemon";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_daemon";
+ };
+
+ qcom,glinkpkt-bg-display-ctrl {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "display-ctrl";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_display_ctrl";
+ };
+
+ qcom,glinkpkt-bg-display-data {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "display-data";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_display_data";
+ };
+
+ qcom,glinkpkt-bg-rsb-ctrl {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "RSB_CTRL";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_rsb_ctrl";
+ };
+
+ qcom,glinkpkt-bg-sso-ctrl {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "sso-ctrl";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_sso_ctrl";
+ };
+
+ qcom,glinkpkt-bg-buzzer-ctrl {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "buzzer-ctrl";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_buzzer_ctrl";
+ };
+ };
+
+ spi@78B8000 { /* BLSP1 QUP4 */
+ status = "ok";
+ qcom,bg-spi {
+ compatible = "qcom,bg-spi";
+ reg = <0>;
+ spi-max-frequency = <16000000>;
+ interrupt-parent = <&msm_gpio>;
+ qcom,irq-gpio = <&msm_gpio 43 1>;
+ };
+ };
+
+ qcom,bg-rsb {
+ compatible = "qcom,bg-rsb";
+ vdd-ldo1-supply = <&pm660_l11>;
+ vdd-ldo2-supply = <&pm660_l15>;
+ };
+
+ qcom,bg-daemon {
+ compatible = "qcom,bg-daemon";
+ qcom,bg-reset-gpio = <&pm660_gpios 5 0>;
+ ssr-reg1-supply = <&pm660_l3>;
+ ssr-reg2-supply = <&pm660_l9>;
+ };
+};
+
&usb_otg {
HSUSB_3p3-supply = <&L16A>;
};
diff --git a/drivers/input/sensors/smi130/smi130_acc.c b/drivers/input/sensors/smi130/smi130_acc.c
index a63e08e..a6416e4 100644
--- a/drivers/input/sensors/smi130/smi130_acc.c
+++ b/drivers/input/sensors/smi130/smi130_acc.c
@@ -133,7 +133,7 @@
#include <linux/delay.h>
#include <asm/irq.h>
#include <linux/math64.h>
-
+#include <linux/cpu.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
@@ -159,7 +159,7 @@
#define SENSOR_NAME "smi130_acc"
#define SMI130_ACC_USE_BASIC_I2C_FUNC 1
-
+#define SMI130_HRTIMER 1
#define MSC_TIME 6
#define ABSMIN -512
#define ABSMAX 512
@@ -1573,7 +1573,6 @@
struct mutex enable_mutex;
struct mutex mode_mutex;
struct delayed_work work;
- struct work_struct irq_work;
#ifdef CONFIG_HAS_EARLYSUSPEND
struct early_suspend early_suspend;
#endif
@@ -1611,8 +1610,57 @@
struct input_dev *accbuf_dev;
int report_evt_cnt;
#endif
+#ifdef SMI130_HRTIMER
+ struct hrtimer smi130_hrtimer;
+#endif
};
+#ifdef SMI130_HRTIMER
+static void smi130_set_cpu_idle_state(bool value)
+{
+ cpu_idle_poll_ctrl(value);
+}
+static enum hrtimer_restart smi130_timer_function(struct hrtimer *timer)
+{
+ smi130_set_cpu_idle_state(true);
+
+ return HRTIMER_NORESTART;
+}
+static void smi130_hrtimer_reset(struct smi130_acc_data *data)
+{
+ hrtimer_cancel(&data->smi130_hrtimer);
+ /*forward HRTIMER just before 1ms of irq arrival*/
+ hrtimer_forward(&data->smi130_hrtimer, ktime_get(),
+ ns_to_ktime(data->time_odr - 1000000));
+ hrtimer_restart(&data->smi130_hrtimer);
+}
+static void smi130_hrtimer_init(struct smi130_acc_data *data)
+{
+ hrtimer_init(&data->smi130_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ data->smi130_hrtimer.function = smi130_timer_function;
+}
+static void smi130_hrtimer_cleanup(struct smi130_acc_data *data)
+{
+ hrtimer_cancel(&data->smi130_hrtimer);
+}
+#else
+static void smi130_set_cpu_idle_state(bool value)
+{
+}
+static void smi130_hrtimer_reset(struct smi130_acc_data *data)
+{
+
+}
+static void smi130_hrtimer_init(struct smi130_acc_data *data)
+{
+
+}
+static void smi130_hrtimer_remove(struct smi130_acc_data *data)
+{
+
+}
+#endif
+
#ifdef CONFIG_HAS_EARLYSUSPEND
static void smi130_acc_early_suspend(struct early_suspend *h);
static void smi130_acc_late_resume(struct early_suspend *h);
@@ -3871,7 +3919,7 @@
signed char sensor_type, short *a_x)
{
int comres = 0;
- unsigned char data[2];
+ unsigned char data[2] = {0};
switch (sensor_type) {
case 0:
@@ -3940,7 +3988,7 @@
signed char sensor_type, short *a_y)
{
int comres = 0;
- unsigned char data[2];
+ unsigned char data[2] = {0};
switch (sensor_type) {
case 0:
@@ -3998,7 +4046,7 @@
signed char sensor_type, short *a_z)
{
int comres = 0;
- unsigned char data[2];
+ unsigned char data[2] = {0};
switch (sensor_type) {
case 0:
@@ -5087,7 +5135,7 @@
signed char sensor_type, struct smi130_accacc *acc)
{
int comres = 0;
- unsigned char data[6];
+ unsigned char data[6] = {0};
struct smi130_acc_data *client_data = i2c_get_clientdata(client);
#ifndef SMI_ACC2X2_SENSOR_IDENTIFICATION_ENABLE
int bitwidth;
@@ -5381,7 +5429,7 @@
struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
size_t count = 0;
- u8 reg[0x40];
+ u8 reg[0x40] = {0};
int i;
for (i = 0; i < 0x40; i++) {
@@ -6962,7 +7010,7 @@
if (!client_data->smi_acc_cachepool) {
PERR("smi_acc_cachepool cache create failed\n");
err = -ENOMEM;
- goto clean_exit1;
+ return 0;
}
for (i = 0; i < SMI_ACC_MAXSAMPLE; i++) {
client_data->smi130_acc_samplist[i] =
@@ -6970,7 +7018,7 @@
GFP_KERNEL);
if (!client_data->smi130_acc_samplist[i]) {
err = -ENOMEM;
- goto clean_exit2;
+ goto clean_exit1;
}
}
@@ -6978,7 +7026,7 @@
if (!client_data->accbuf_dev) {
err = -ENOMEM;
PERR("input device allocation failed\n");
- goto clean_exit3;
+ goto clean_exit1;
}
client_data->accbuf_dev->name = "smi130_accbuf";
client_data->accbuf_dev->id.bustype = BUS_I2C;
@@ -6999,25 +7047,26 @@
if (err) {
PERR("unable to register input device %s\n",
client_data->accbuf_dev->name);
- goto clean_exit3;
+ goto clean_exit2;
}
client_data->acc_buffer_smi130_samples = true;
client_data->acc_enable = false;
+ smi130_set_cpu_idle_state(true);
+
smi130_acc_set_mode(client, SMI_ACC2X2_MODE_NORMAL, 1);
smi130_acc_set_bandwidth(client, SMI_ACC2X2_BW_62_50HZ);
smi130_acc_set_range(client, SMI_ACC2X2_RANGE_2G);
return 1;
-clean_exit3:
- input_free_device(client_data->accbuf_dev);
clean_exit2:
+ input_free_device(client_data->accbuf_dev);
+clean_exit1:
for (i = 0; i < SMI_ACC_MAXSAMPLE; i++)
kmem_cache_free(client_data->smi_acc_cachepool,
client_data->smi130_acc_samplist[i]);
-clean_exit1:
kmem_cache_destroy(client_data->smi_acc_cachepool);
return 0;
}
@@ -7044,10 +7093,9 @@
}
#endif
-static void smi130_acc_irq_work_func(struct work_struct *work)
+static irqreturn_t smi130_acc_irq_work_func(int irq, void *handle)
{
- struct smi130_acc_data *smi130_acc = container_of((struct work_struct *)work,
- struct smi130_acc_data, irq_work);
+ struct smi130_acc_data *smi130_acc = handle;
#ifdef CONFIG_DOUBLE_TAP
struct i2c_client *client = smi130_acc->smi130_acc_client;
#endif
@@ -7092,8 +7140,10 @@
mutex_unlock(&smi130_acc->value_mutex);
}
store_acc_boot_sample(smi130_acc, acc.x, acc.y, acc.z, ts);
-#endif
+ smi130_set_cpu_idle_state(false);
+ return IRQ_HANDLED;
+#endif
smi130_acc_get_interruptstatus1(smi130_acc->smi130_acc_client, &status);
PDEBUG("smi130_acc_irq_work_func, status = 0x%x\n", status);
@@ -7246,10 +7296,9 @@
if (data->smi130_acc_client == NULL)
return IRQ_HANDLED;
data->timestamp = smi130_acc_get_alarm_timestamp();
+ smi130_hrtimer_reset(data);
- schedule_work(&data->irq_work);
-
- return IRQ_HANDLED;
+ return IRQ_WAKE_THREAD;
}
#endif /* defined(SMI_ACC2X2_ENABLE_INT1)||defined(SMI_ACC2X2_ENABLE_INT2) */
@@ -7363,7 +7412,6 @@
if (err)
PERR("could not request irq\n");
- INIT_WORK(&data->irq_work, smi130_acc_irq_work_func);
#endif
#ifndef CONFIG_SMI_ACC_ENABLE_NEWDATA_INT
@@ -7558,9 +7606,11 @@
return -EINVAL;
data->IRQ = client->irq;
PDEBUG("data->IRQ = %d", data->IRQ);
- err = request_irq(data->IRQ, smi130_acc_irq_handler, IRQF_TRIGGER_RISING,
+ err = request_threaded_irq(data->IRQ, smi130_acc_irq_handler,
+ smi130_acc_irq_work_func, IRQF_TRIGGER_RISING,
"smi130_acc", data);
+ smi130_hrtimer_init(data);
err = smi130_acc_early_buff_init(client, data);
if (!err)
goto exit;
@@ -7676,6 +7726,7 @@
if (NULL == data)
return 0;
+ smi130_hrtimer_cleanup(data);
smi130_acc_input_cleanup(data);
smi130_acc_set_enable(&client->dev, 0);
#ifdef CONFIG_HAS_EARLYSUSPEND
diff --git a/drivers/input/sensors/smi130/smi130_driver.c b/drivers/input/sensors/smi130/smi130_driver.c
index 42a0a57..3991ada 100644
--- a/drivers/input/sensors/smi130/smi130_driver.c
+++ b/drivers/input/sensors/smi130/smi130_driver.c
@@ -2879,7 +2879,7 @@
struct smi_client_data *client_data = input_get_drvdata(input);
ssize_t ret;
- u8 reg_data[128], i;
+ u8 reg_data[128] = {0}, i;
int pos;
if (client_data == NULL) {
@@ -2913,7 +2913,8 @@
struct input_dev *input = to_input_dev(dev);
struct smi_client_data *client_data = input_get_drvdata(input);
ssize_t ret;
- u8 reg_data[32];
+ u8 reg_data[32] = {0};
+
int i, j, status, digit;
if (client_data == NULL) {
diff --git a/drivers/input/sensors/smi130/smi130_gyro_driver.c b/drivers/input/sensors/smi130/smi130_gyro_driver.c
index fd9e87d..e497a0a8 100644
--- a/drivers/input/sensors/smi130/smi130_gyro_driver.c
+++ b/drivers/input/sensors/smi130/smi130_gyro_driver.c
@@ -290,7 +290,6 @@
ktime_t work_delay_kt;
uint8_t gpio_pin;
int16_t IRQ;
- struct work_struct irq_work;
#ifdef CONFIG_ENABLE_SMI_ACC_GYRO_BUFFERING
bool read_gyro_boot_sample;
int gyro_bufsample_cnt;
@@ -422,7 +421,7 @@
static void smi_gyro_dump_reg(struct i2c_client *client)
{
int i;
- u8 dbg_buf[64];
+ u8 dbg_buf[64] = {0};
u8 dbg_buf_str[64 * 3 + 1] = "";
for (i = 0; i < BYTES_PER_LINE; i++) {
@@ -1788,7 +1787,7 @@
if (!client_data->smi_gyro_cachepool) {
PERR("smi_gyro_cachepool cache create failed\n");
err = -ENOMEM;
- goto clean_exit1;
+ return 0;
}
for (i = 0; i < SMI_GYRO_MAXSAMPLE; i++) {
@@ -1797,7 +1796,7 @@
GFP_KERNEL);
if (!client_data->smi130_gyro_samplist[i]) {
err = -ENOMEM;
- goto clean_exit2;
+ goto clean_exit1;
}
}
@@ -1806,7 +1805,7 @@
if (!client_data->gyrobuf_dev) {
err = -ENOMEM;
PERR("input device allocation failed\n");
- goto clean_exit3;
+ goto clean_exit1;
}
client_data->gyrobuf_dev->name = "smi130_gyrobuf";
client_data->gyrobuf_dev->id.bustype = BUS_I2C;
@@ -1827,7 +1826,7 @@
if (err) {
PERR("unable to register input device %s\n",
client_data->gyrobuf_dev->name);
- goto clean_exit3;
+ goto clean_exit2;
}
client_data->gyro_buffer_smi130_samples = true;
@@ -1852,13 +1851,12 @@
return 1;
-clean_exit3:
- input_free_device(client_data->gyrobuf_dev);
clean_exit2:
+ input_free_device(client_data->gyrobuf_dev);
+clean_exit1:
for (i = 0; i < SMI_GYRO_MAXSAMPLE; i++)
kmem_cache_free(client_data->smi_gyro_cachepool,
client_data->smi130_gyro_samplist[i]);
-clean_exit1:
kmem_cache_destroy(client_data->smi_gyro_cachepool);
return 0;
}
@@ -1895,10 +1893,9 @@
#if defined(SMI130_GYRO_ENABLE_INT1) || defined(SMI130_GYRO_ENABLE_INT2)
-static void smi130_gyro_irq_work_func(struct work_struct *work)
+static irqreturn_t smi130_gyro_irq_work_func(int irq, void *handle)
{
- struct smi_gyro_client_data *client_data = container_of(work,
- struct smi_gyro_client_data, irq_work);
+ struct smi_gyro_client_data *client_data = handle;
struct smi130_gyro_data_t gyro_data;
struct timespec ts;
ts = ns_to_timespec(client_data->timestamp);
@@ -1919,14 +1916,14 @@
input_sync(client_data->input);
store_gyro_boot_sample(client_data, gyro_data.datax,
gyro_data.datay, gyro_data.dataz, ts);
+ return IRQ_HANDLED;
}
static irqreturn_t smi_gyro_irq_handler(int irq, void *handle)
{
struct smi_gyro_client_data *client_data = handle;
client_data->timestamp= smi130_gyro_get_alarm_timestamp();
- schedule_work(&client_data->irq_work);
- return IRQ_HANDLED;
+ return IRQ_WAKE_THREAD;
}
#endif
static int smi_gyro_probe(struct i2c_client *client, const struct i2c_device_id *id)
@@ -2098,13 +2095,12 @@
PDEBUG("request failed\n");
}
client_data->IRQ = gpio_to_irq(client_data->gpio_pin);
- err = request_irq(client_data->IRQ, smi_gyro_irq_handler,
- IRQF_TRIGGER_RISING,
- SENSOR_NAME, client_data);
+ err = request_threaded_irq(client_data->IRQ,
+ smi_gyro_irq_handler, smi130_gyro_irq_work_func,
+ IRQF_TRIGGER_RISING, SENSOR_NAME, client_data);
if (err < 0)
PDEBUG("request handle failed\n");
}
- INIT_WORK(&client_data->irq_work, smi130_gyro_irq_work_func);
#endif
err = smi130_gyro_early_buff_init(client_data);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index 9d1c5cc..736c594 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -2786,7 +2786,7 @@
/* Set the exception path to AP */
for (client_idx = 0; client_idx < IPA_CLIENT_MAX; client_idx++) {
ep_idx = ipa3_get_ep_mapping(client_idx);
- if (ep_idx == -1)
+ if (ep_idx == -1 || (ep_idx >= IPA3_MAX_NUM_PIPES))
continue;
/* disable statuses for all modem controlled prod pipes */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index f656728..dc9c526 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -67,6 +67,12 @@
/* Indicate backport support for processing user cell base hint */
#define CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED 1
+/* Indicate backport support for external authentication in AP mode */
+#define CFG80211_EXTERNAL_AUTH_AP_SUPPORT 1
+
+/* Indicate backport support for DH IE creation/update*/
+#define CFG80211_EXTERNAL_DH_UPDATE_SUPPORT 1
+
/**
* DOC: Introduction
*
@@ -739,6 +745,17 @@
};
/**
+ * enum cfg80211_ap_settings_flags - AP settings flags
+ *
+ * Used by cfg80211_ap_settings
+ *
+ * @AP_SETTINGS_EXTERNAL_AUTH_SUPPORT: AP supports external authentication
+ */
+enum cfg80211_ap_settings_flags {
+ AP_SETTINGS_EXTERNAL_AUTH_SUPPORT = BIT(0),
+};
+
+/**
* struct cfg80211_ap_settings - AP configuration
*
* Used to configure an AP interface.
@@ -763,6 +780,7 @@
* @pbss: If set, start as a PCP instead of AP. Relevant for DMG
* networks.
* @beacon_rate: bitrate to be used for beacons
+ * @flags: flags, as defined in enum cfg80211_ap_settings_flags
*/
struct cfg80211_ap_settings {
struct cfg80211_chan_def chandef;
@@ -783,6 +801,7 @@
const struct cfg80211_acl_data *acl;
bool pbss;
struct cfg80211_bitrate_mask beacon_rate;
+ u32 flags;
};
/**
@@ -2582,6 +2601,7 @@
* use %WLAN_STATUS_UNSPECIFIED_FAILURE if user space cannot give you
* the real status code for failures. Used only for the authentication
* response command interface (user space to driver).
+ * @pmkid: The identifier to refer a PMKSA.
*/
struct cfg80211_external_auth_params {
enum nl80211_external_auth_action action;
@@ -2589,6 +2609,33 @@
struct cfg80211_ssid ssid;
unsigned int key_mgmt_suite;
u16 status;
+ const u8 *pmkid;
+};
+
+/**
+ * struct cfg80211_update_owe_info - OWE Information
+ *
+ * This structure provides information needed for the drivers to offload OWE
+ * (Opportunistic Wireless Encryption) processing to the user space.
+ *
+ * Commonly used across update_owe_info request and event interfaces.
+ *
+ * @peer: MAC address of the peer device for which the OWE processing
+ * has to be done.
+ * @status: status code, %WLAN_STATUS_SUCCESS for successful OWE info
+ * processing, use %WLAN_STATUS_UNSPECIFIED_FAILURE if user space
+ * cannot give you the real status code for failures. Used only for
+ * OWE update request command interface (user space to driver).
+ * @ie: IEs obtained from the peer or constructed by the user space. These are
+ * the IEs of the remote peer in the event from the host driver and
+ * the constructed IEs by the user space in the request interface.
+ * @ie_len: Length of IEs in octets.
+ */
+struct cfg80211_update_owe_info {
+ u8 peer[ETH_ALEN] __aligned(2);
+ u16 status;
+ const u8 *ie;
+ size_t ie_len;
};
/**
@@ -2903,6 +2950,10 @@
*
* @external_auth: indicates result of offloaded authentication processing from
* user space
+ *
+ * @update_owe_info: Provide updated OWE info to driver. Driver implementing SME
+ * but offloading OWE processing to the user space will get the updated
+ * DH IE through this interface.
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -3189,6 +3240,8 @@
const bool enabled);
int (*external_auth)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_external_auth_params *params);
+ int (*update_owe_info)(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_update_owe_info *owe_info);
};
/*
@@ -6185,4 +6238,14 @@
#define wiphy_WARN(wiphy, format, args...) \
WARN(1, "wiphy: %s\n" format, wiphy_name(wiphy), ##args);
+/**
+ * cfg80211_update_owe_info_event - Notify the peer's OWE info to user space
+ * @netdev: network device
+ * @owe_info: peer's owe info
+ * @gfp: allocation flags
+ */
+void cfg80211_update_owe_info_event(struct net_device *netdev,
+ struct cfg80211_update_owe_info *owe_info,
+ gfp_t gfp);
+
#endif /* __NET_CFG80211_H */
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 39f920c..31817b8 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1018,6 +1018,11 @@
* indicated by %NL80211_ATTR_WIPHY_FREQ and other attributes
* determining the width and type.
*
+ * @NL80211_CMD_UPDATE_OWE_INFO: This interface allows the host driver to
+ * offload OWE processing to user space. This intends to support
+ * OWE AKM by the host drivers that implement SME but rely
+ * on the user space for the cryptographic/DH IE processing in AP mode.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -1238,6 +1243,8 @@
NL80211_CMD_NOTIFY_RADAR,
+ NL80211_CMD_UPDATE_OWE_INFO,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -2179,10 +2186,10 @@
* &enum nl80211_external_auth_action value). This is used with the
* &NL80211_CMD_EXTERNAL_AUTH request event.
* @NL80211_ATTR_EXTERNAL_AUTH_SUPPORT: Flag attribute indicating that the user
- * space supports external authentication. This attribute shall be used
- * only with %NL80211_CMD_CONNECT request. The driver may offload
- * authentication processing to user space if this capability is indicated
- * in NL80211_CMD_CONNECT requests from the user space.
+ * space supports external authentication. This attribute shall be used
+ * with %NL80211_CMD_CONNECT and %NL80211_CMD_START_AP request. The driver
+ * may offload authentication processing to user space if this capability
+ * is indicated in the respective requests from the user space.
*
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
@@ -5264,9 +5271,14 @@
* Used by cfg80211_rx_mgmt()
*
* @NL80211_RXMGMT_FLAG_ANSWERED: frame was answered by device/driver.
+ * @NL80211_RXMGMT_FLAG_EXTERNAL_AUTH: Host driver intends to offload
+ * the authentication. Exclusively defined for host drivers that
+ * advertises the SME functionality but would like the userspace
+ * to handle certain authentication algorithms (e.g. SAE).
*/
enum nl80211_rxmgmt_flags {
NL80211_RXMGMT_FLAG_ANSWERED = 1 << 0,
+ NL80211_RXMGMT_FLAG_EXTERNAL_AUTH = 1 << 1,
};
/*
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d9332d1..71ef07a 100755
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3989,6 +3989,9 @@
return PTR_ERR(params.acl);
}
+ if (info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])
+ params.flags |= AP_SETTINGS_EXTERNAL_AUTH_SUPPORT;
+
wdev_lock(wdev);
err = rdev_start_ap(rdev, dev, ¶ms);
if (!err) {
@@ -12055,7 +12058,9 @@
if (!rdev->ops->external_auth)
return -EOPNOTSUPP;
- if (!info->attrs[NL80211_ATTR_SSID])
+ if (!info->attrs[NL80211_ATTR_SSID] &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
return -EINVAL;
if (!info->attrs[NL80211_ATTR_BSSID])
@@ -12066,21 +12071,52 @@
memset(¶ms, 0, sizeof(params));
- params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
- if (params.ssid.ssid_len == 0 ||
- params.ssid.ssid_len > IEEE80211_MAX_SSID_LEN)
- return -EINVAL;
- memcpy(params.ssid.ssid, nla_data(info->attrs[NL80211_ATTR_SSID]),
- params.ssid.ssid_len);
+ if (info->attrs[NL80211_ATTR_SSID]) {
+ params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
+ if (params.ssid.ssid_len == 0 ||
+ params.ssid.ssid_len > IEEE80211_MAX_SSID_LEN)
+ return -EINVAL;
+ memcpy(params.ssid.ssid,
+ nla_data(info->attrs[NL80211_ATTR_SSID]),
+ params.ssid.ssid_len);
+ }
memcpy(params.bssid, nla_data(info->attrs[NL80211_ATTR_BSSID]),
ETH_ALEN);
params.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
+ if (info->attrs[NL80211_ATTR_PMKID])
+ params.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
+
return rdev_external_auth(rdev, dev, ¶ms);
}
+static int nl80211_update_owe_info(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct cfg80211_update_owe_info owe_info;
+ struct net_device *dev = info->user_ptr[1];
+
+ if (!rdev->ops->update_owe_info)
+ return -EOPNOTSUPP;
+
+ if (!info->attrs[NL80211_ATTR_STATUS_CODE] ||
+ !info->attrs[NL80211_ATTR_MAC])
+ return -EINVAL;
+
+ memset(&owe_info, 0, sizeof(owe_info));
+ owe_info.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
+ nla_memcpy(owe_info.peer, info->attrs[NL80211_ATTR_MAC], ETH_ALEN);
+
+ if (info->attrs[NL80211_ATTR_IE]) {
+ owe_info.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
+ owe_info.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+ }
+
+ return rdev_update_owe_info(rdev, dev, &owe_info);
+}
+
#define NL80211_FLAG_NEED_WIPHY 0x01
#define NL80211_FLAG_NEED_NETDEV 0x02
#define NL80211_FLAG_NEED_RTNL 0x04
@@ -12978,6 +13014,13 @@
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
+ {
+ .cmd = NL80211_CMD_UPDATE_OWE_INFO,
+ .doit = nl80211_update_owe_info,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
+ },
};
/* notification functions */
@@ -15018,6 +15061,46 @@
}
EXPORT_SYMBOL(cfg80211_external_auth_request);
+void cfg80211_update_owe_info_event(struct net_device *netdev,
+ struct cfg80211_update_owe_info *owe_info,
+ gfp_t gfp)
+{
+ struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+ struct sk_buff *msg;
+ void *hdr;
+
+ trace_cfg80211_update_owe_info_event(wiphy, netdev, owe_info);
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+ if (!msg)
+ return;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_UPDATE_OWE_INFO);
+ if (!hdr)
+ goto nla_put_failure;
+
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+ nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, owe_info->peer))
+ goto nla_put_failure;
+
+ if (!owe_info->ie_len ||
+ nla_put(msg, NL80211_ATTR_IE, owe_info->ie_len, owe_info->ie))
+ goto nla_put_failure;
+
+ genlmsg_end(msg, hdr);
+
+ genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
+ NL80211_MCGRP_MLME, gfp);
+ return;
+
+nla_put_failure:
+ genlmsg_cancel(msg, hdr);
+ nlmsg_free(msg);
+}
+EXPORT_SYMBOL(cfg80211_update_owe_info_event);
+
/* initialisation/exit functions */
int nl80211_init(void)
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 091806d..a0ff6b1 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -1168,4 +1168,17 @@
return ret;
}
+static inline int rdev_update_owe_info(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
+ struct cfg80211_update_owe_info *oweinfo)
+{
+ int ret = -EOPNOTSUPP;
+
+ trace_rdev_update_owe_info(&rdev->wiphy, dev, oweinfo);
+ if (rdev->ops->update_owe_info)
+ ret = rdev->ops->update_owe_info(&rdev->wiphy, dev, oweinfo);
+ trace_rdev_return_int(&rdev->wiphy, ret);
+ return ret;
+}
+
#endif /* __CFG80211_RDEV_OPS */
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 80ea75a..ef56df5 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -3090,6 +3090,44 @@
WIPHY_PR_ARG, NETDEV_PR_ARG,
BOOL_TO_STR(__entry->enabled))
);
+
+TRACE_EVENT(rdev_update_owe_info,
+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
+ struct cfg80211_update_owe_info *owe_info),
+ TP_ARGS(wiphy, netdev, owe_info),
+ TP_STRUCT__entry(WIPHY_ENTRY
+ NETDEV_ENTRY
+ MAC_ENTRY(peer)
+ __field(u16, status)
+ __dynamic_array(u8, ie, owe_info->ie_len)),
+ TP_fast_assign(WIPHY_ASSIGN;
+ NETDEV_ASSIGN;
+ MAC_ASSIGN(peer, owe_info->peer);
+ __entry->status = owe_info->status;
+ memcpy(__get_dynamic_array(ie),
+ owe_info->ie, owe_info->ie_len);),
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT
+ " status %d", WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer),
+ __entry->status)
+);
+
+TRACE_EVENT(cfg80211_update_owe_info_event,
+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
+ struct cfg80211_update_owe_info *owe_info),
+ TP_ARGS(wiphy, netdev, owe_info),
+ TP_STRUCT__entry(WIPHY_ENTRY
+ NETDEV_ENTRY
+ MAC_ENTRY(peer)
+ __dynamic_array(u8, ie, owe_info->ie_len)),
+ TP_fast_assign(WIPHY_ASSIGN;
+ NETDEV_ASSIGN;
+ MAC_ASSIGN(peer, owe_info->peer);
+ memcpy(__get_dynamic_array(ie), owe_info->ie,
+ owe_info->ie_len);),
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT,
+ WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer))
+);
+
#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
#undef TRACE_INCLUDE_PATH