aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2018-11-16 08:27:42 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2018-11-16 08:27:42 -0800
commita3068cb89b1cd07e663b32aacc265fc03075bcce (patch)
tree94cbe2b275e8e1908e0ce5dbea44e1e3c93a1045
parentb21b55f9b6443a673524ee7ee429a7abaff7c155 (diff)
parent05faeb588a3d00fb41035a3d79f2abb4d7ac03ba (diff)
Merge "Merge e6cfc273efc14522548c50abd1522baf86abefd4 on remote branch"LA.UM.6.6.2.r1-06400-89xx.0
-rw-r--r--arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/sdm439.dtsi2
-rw-r--r--drivers/clk/msm/clock-gcc-8952.c3
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/gpio-msm-smp2p-test.c763
-rw-r--r--drivers/leds/leds-qpnp-flash-v2.c73
-rw-r--r--drivers/mmc/host/cmdq_hci.c5
7 files changed, 67 insertions, 782 deletions
diff --git a/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi b/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi
index 6c4ea9f2a73e..de0730d36a76 100644
--- a/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi
@@ -134,6 +134,7 @@
1708800 327
1804800 343
1958400 445
+ 2016000 470
>;
idle-cost-data = <
100 80 60 40
@@ -147,6 +148,7 @@
1708800 85
1804800 88
1958400 110
+ 2016000 120
>;
idle-cost-data = <
4 3 2 1
diff --git a/arch/arm64/boot/dts/qcom/sdm439.dtsi b/arch/arm64/boot/dts/qcom/sdm439.dtsi
index d655a999018a..a59b4578135b 100644
--- a/arch/arm64/boot/dts/qcom/sdm439.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439.dtsi
@@ -182,6 +182,7 @@
1708800 327
1804800 343
1958400 445
+ 2016000 470
>;
idle-cost-data = <
100 80 60 40
@@ -207,6 +208,7 @@
1708800 85
1804800 88
1958400 110
+ 2016000 120
>;
idle-cost-data = <
4 3 2 1
diff --git a/drivers/clk/msm/clock-gcc-8952.c b/drivers/clk/msm/clock-gcc-8952.c
index 47619f540b5c..3a17d7cc8b54 100644
--- a/drivers/clk/msm/clock-gcc-8952.c
+++ b/drivers/clk/msm/clock-gcc-8952.c
@@ -274,6 +274,7 @@ static struct pll_freq_tbl apcs_c1_pll_freq[] = {
F_APCS_PLL(1708800000, 89, 0x0, 0x1, 0x0, 0x0, 0x0),
F_APCS_PLL(1804800000, 94, 0x0, 0x1, 0x0, 0x0, 0x0),
F_APCS_PLL(1958400000, 102, 0x0, 0x1, 0x0, 0x0, 0x0),
+ F_APCS_PLL(2016000000, 105, 0x0, 0x1, 0x0, 0x0, 0x0),
};
static struct pll_clk a53ss_c1_pll = {
@@ -304,7 +305,7 @@ static struct pll_clk a53ss_c1_pll = {
.vdd_class = &vdd_hf_pll,
.fmax = (unsigned long [VDD_HF_PLL_NUM]) {
[VDD_HF_PLL_SVS] = 1000000000,
- [VDD_HF_PLL_NOM] = 2000000000,
+ [VDD_HF_PLL_NOM] = 2020000000,
},
.num_fmax = VDD_HF_PLL_NUM,
CLK_INIT(a53ss_c1_pll.c),
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 68418a6536b0..beba6635cd2c 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -143,4 +143,3 @@ obj-$(CONFIG_GPIO_ZYNQ) += gpio-zynq.o
obj-$(CONFIG_GPIO_ZX) += gpio-zx.o
obj-$(CONFIG_GPIO_LOONGSON1) += gpio-loongson1.o
obj-$(CONFIG_MSM_SMP2P) += gpio-msm-smp2p.o
-obj-$(CONFIG_MSM_SMP2P_TEST) += gpio-msm-smp2p-test.o
diff --git a/drivers/gpio/gpio-msm-smp2p-test.c b/drivers/gpio/gpio-msm-smp2p-test.c
deleted file mode 100644
index 1067c4aade39..000000000000
--- a/drivers/gpio/gpio-msm-smp2p-test.c
+++ /dev/null
@@ -1,763 +0,0 @@
-/* drivers/gpio/gpio-msm-smp2p-test.c
- *
- * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/of_gpio.h>
-#include <linux/of_irq.h>
-#include <linux/gpio.h>
-#include <linux/debugfs.h>
-#include <linux/completion.h>
-#include <linux/interrupt.h>
-#include <linux/bitmap.h>
-#include "../soc/qcom/smp2p_private.h"
-#include "../soc/qcom/smp2p_test_common.h"
-
-/* Interrupt callback data */
-struct gpio_info {
- int gpio_base_id;
- int irq_base_id;
-
- bool initialized;
- struct completion cb_completion;
- int cb_count;
- DECLARE_BITMAP(triggered_irqs, SMP2P_BITS_PER_ENTRY);
-};
-
-/* GPIO Inbound/Outbound callback info */
-struct gpio_inout {
- struct gpio_info in;
- struct gpio_info out;
-};
-
-static struct gpio_inout gpio_info[SMP2P_NUM_PROCS];
-
-/**
- * Init/reset the callback data.
- *
- * @info: Pointer to callback data
- */
-static void cb_data_reset(struct gpio_info *info)
-{
- int n;
-
- if (!info)
- return;
-
- if (!info->initialized) {
- init_completion(&info->cb_completion);
- info->initialized = true;
- }
- info->cb_count = 0;
-
- for (n = 0; n < SMP2P_BITS_PER_ENTRY; ++n)
- clear_bit(n, info->triggered_irqs);
-
- reinit_completion(&info->cb_completion);
-}
-
-static int smp2p_gpio_test_probe(struct platform_device *pdev)
-{
- int id;
- int cnt;
- struct device_node *node = pdev->dev.of_node;
- struct gpio_info *gpio_info_ptr = NULL;
-
- /*
- * NOTE: This does a string-lookup of the GPIO pin name and doesn't
- * actually directly link to the SMP2P GPIO driver since all
- * GPIO/Interrupt access must be through standard
- * Linux GPIO / Interrupt APIs.
- */
- if (strcmp("qcom,smp2pgpio_test_smp2p_1_in", node->name) == 0) {
- gpio_info_ptr = &gpio_info[SMP2P_MODEM_PROC].in;
- } else if (strcmp("qcom,smp2pgpio_test_smp2p_1_out", node->name) == 0) {
- gpio_info_ptr = &gpio_info[SMP2P_MODEM_PROC].out;
- } else if (strcmp("qcom,smp2pgpio_test_smp2p_2_in", node->name) == 0) {
- gpio_info_ptr = &gpio_info[SMP2P_AUDIO_PROC].in;
- } else if (strcmp("qcom,smp2pgpio_test_smp2p_2_out", node->name) == 0) {
- gpio_info_ptr = &gpio_info[SMP2P_AUDIO_PROC].out;
- } else if (strcmp("qcom,smp2pgpio_test_smp2p_3_in", node->name) == 0) {
- gpio_info_ptr = &gpio_info[SMP2P_SENSOR_PROC].in;
- } else if (strcmp("qcom,smp2pgpio_test_smp2p_3_out", node->name) == 0) {
- gpio_info_ptr = &gpio_info[SMP2P_SENSOR_PROC].out;
- } else if (strcmp("qcom,smp2pgpio_test_smp2p_4_in", node->name) == 0) {
- gpio_info_ptr = &gpio_info[SMP2P_WIRELESS_PROC].in;
- } else if (strcmp("qcom,smp2pgpio_test_smp2p_4_out", node->name) == 0) {
- gpio_info_ptr = &gpio_info[SMP2P_WIRELESS_PROC].out;
- } else if (strcmp("qcom,smp2pgpio_test_smp2p_5_in", node->name) == 0) {
- gpio_info_ptr = &gpio_info[SMP2P_CDSP_PROC].in;
- } else if (strcmp("qcom,smp2pgpio_test_smp2p_5_out", node->name) == 0) {
- gpio_info_ptr = &gpio_info[SMP2P_CDSP_PROC].out;
- } else if (strcmp("qcom,smp2pgpio_test_smp2p_7_in", node->name) == 0) {
- gpio_info_ptr = &gpio_info[SMP2P_TZ_PROC].in;
- } else if (strcmp("qcom,smp2pgpio_test_smp2p_7_out", node->name) == 0) {
- gpio_info_ptr = &gpio_info[SMP2P_TZ_PROC].out;
- } else if (strcmp("qcom,smp2pgpio_test_smp2p_15_in", node->name) == 0) {
- gpio_info_ptr = &gpio_info[SMP2P_REMOTE_MOCK_PROC].in;
- } else if (
- strcmp("qcom,smp2pgpio_test_smp2p_15_out", node->name) == 0) {
- gpio_info_ptr = &gpio_info[SMP2P_REMOTE_MOCK_PROC].out;
- } else {
- pr_err("%s: unable to match device type '%s'\n",
- __func__, node->name);
- return -ENODEV;
- }
-
- /* retrieve the GPIO and interrupt ID's */
- cnt = of_gpio_count(node);
- if (cnt && gpio_info_ptr) {
- /*
- * Instead of looping through all 32-bits, we can just get the
- * first pin to get the base IDs. This saves on the verbosity
- * of the device tree nodes as well.
- */
- id = of_get_gpio(node, 0);
- if (id == -EPROBE_DEFER)
- return id;
- gpio_info_ptr->gpio_base_id = id;
- gpio_info_ptr->irq_base_id = gpio_to_irq(id);
- }
- return 0;
-}
-
-/*
- * NOTE: Instead of match table and device driver, you may be able to just
- * call of_find_compatible_node() in your init function.
- */
-static const struct of_device_id msm_smp2p_match_table[] = {
- /* modem */
- {.compatible = "qcom,smp2pgpio_test_smp2p_1_out", },
- {.compatible = "qcom,smp2pgpio_test_smp2p_1_in", },
-
- /* audio (adsp) */
- {.compatible = "qcom,smp2pgpio_test_smp2p_2_out", },
- {.compatible = "qcom,smp2pgpio_test_smp2p_2_in", },
-
- /* sensor */
- {.compatible = "qcom,smp2pgpio_test_smp2p_3_out", },
- {.compatible = "qcom,smp2pgpio_test_smp2p_3_in", },
-
- /* wcnss */
- {.compatible = "qcom,smp2pgpio_test_smp2p_4_out", },
- {.compatible = "qcom,smp2pgpio_test_smp2p_4_in", },
-
- /* CDSP */
- {.compatible = "qcom,smp2pgpio_test_smp2p_5_out", },
- {.compatible = "qcom,smp2pgpio_test_smp2p_5_in", },
-
- /* TZ */
- {.compatible = "qcom,smp2pgpio_test_smp2p_7_out", },
- {.compatible = "qcom,smp2pgpio_test_smp2p_7_in", },
-
- /* mock loopback */
- {.compatible = "qcom,smp2pgpio_test_smp2p_15_out", },
- {.compatible = "qcom,smp2pgpio_test_smp2p_15_in", },
- {},
-};
-
-static struct platform_driver smp2p_gpio_driver = {
- .probe = smp2p_gpio_test_probe,
- .driver = {
- .name = "smp2pgpio_test",
- .owner = THIS_MODULE,
- .of_match_table = msm_smp2p_match_table,
- },
-};
-
-/**
- * smp2p_ut_local_gpio_out - Verify outbound functionality.
- *
- * @s: pointer to output file
- */
-static void smp2p_ut_local_gpio_out(struct seq_file *s)
-{
- int failed = 0;
- struct gpio_info *cb_info = &gpio_info[SMP2P_REMOTE_MOCK_PROC].out;
- int ret;
- int id;
- struct msm_smp2p_remote_mock *mock;
-
- seq_printf(s, "Running %s\n", __func__);
- do {
- /* initialize mock edge */
- ret = smp2p_reset_mock_edge();
- UT_ASSERT_INT(ret, ==, 0);
-
- mock = msm_smp2p_get_remote_mock();
- UT_ASSERT_PTR(mock, !=, NULL);
-
- mock->rx_interrupt_count = 0;
- memset(&mock->remote_item, 0,
- sizeof(struct smp2p_smem_item));
- smp2p_init_header((struct smp2p_smem *)&mock->remote_item,
- SMP2P_REMOTE_MOCK_PROC, SMP2P_APPS_PROC,
- 0, 1);
- strlcpy(mock->remote_item.entries[0].name, "smp2p",
- SMP2P_MAX_ENTRY_NAME);
- SMP2P_SET_ENT_VALID(
- mock->remote_item.header.valid_total_ent, 1);
- msm_smp2p_set_remote_mock_exists(true);
- mock->tx_interrupt();
-
- /* open GPIO entry */
- smp2p_gpio_open_test_entry("smp2p",
- SMP2P_REMOTE_MOCK_PROC, true);
-
- /* verify set/get functions */
- UT_ASSERT_INT(0, <, cb_info->gpio_base_id);
- for (id = 0; id < SMP2P_BITS_PER_ENTRY && !failed; ++id) {
- int pin = cb_info->gpio_base_id + id;
-
- mock->rx_interrupt_count = 0;
- gpio_set_value(pin, 1);
- UT_ASSERT_INT(1, ==, mock->rx_interrupt_count);
- UT_ASSERT_INT(1, ==, gpio_get_value(pin));
-
- gpio_set_value(pin, 0);
- UT_ASSERT_INT(2, ==, mock->rx_interrupt_count);
- UT_ASSERT_INT(0, ==, gpio_get_value(pin));
- }
- if (failed)
- break;
-
- seq_puts(s, "\tOK\n");
- } while (0);
-
- if (failed) {
- pr_err("%s: Failed\n", __func__);
- seq_puts(s, "\tFailed\n");
- }
-
- smp2p_gpio_open_test_entry("smp2p",
- SMP2P_REMOTE_MOCK_PROC, false);
-}
-
-/**
- * smp2p_gpio_irq - Interrupt handler for inbound entries.
- *
- * @irq: Virtual IRQ being triggered
- * @data: Cookie data (struct gpio_info * in this case)
- * @returns: Number of bytes written
- */
-static irqreturn_t smp2p_gpio_irq(int irq, void *data)
-{
- struct gpio_info *gpio_ptr = (struct gpio_info *)data;
- int offset;
-
- if (!gpio_ptr) {
- pr_err("%s: gpio_ptr is NULL for irq %d\n", __func__, irq);
- return IRQ_HANDLED;
- }
-
- offset = irq - gpio_ptr->irq_base_id;
- if (offset >= 0 && offset < SMP2P_BITS_PER_ENTRY)
- set_bit(offset, gpio_ptr->triggered_irqs);
- else
- pr_err("%s: invalid irq offset base %d; irq %d\n",
- __func__, gpio_ptr->irq_base_id, irq);
-
- ++gpio_ptr->cb_count;
- complete(&gpio_ptr->cb_completion);
- return IRQ_HANDLED;
-}
-
-/**
- * smp2p_ut_local_gpio_in - Verify inbound functionality.
- *
- * @s: pointer to output file
- */
-static void smp2p_ut_local_gpio_in(struct seq_file *s)
-{
- int failed = 0;
- struct gpio_info *cb_info = &gpio_info[SMP2P_REMOTE_MOCK_PROC].in;
- int id;
- int ret;
- int virq;
- struct msm_smp2p_remote_mock *mock;
-
- seq_printf(s, "Running %s\n", __func__);
-
- cb_data_reset(cb_info);
- do {
- /* initialize mock edge */
- ret = smp2p_reset_mock_edge();
- UT_ASSERT_INT(ret, ==, 0);
-
- mock = msm_smp2p_get_remote_mock();
- UT_ASSERT_PTR(mock, !=, NULL);
-
- mock->rx_interrupt_count = 0;
- memset(&mock->remote_item, 0,
- sizeof(struct smp2p_smem_item));
- smp2p_init_header((struct smp2p_smem *)&mock->remote_item,
- SMP2P_REMOTE_MOCK_PROC, SMP2P_APPS_PROC,
- 0, 1);
- strlcpy(mock->remote_item.entries[0].name, "smp2p",
- SMP2P_MAX_ENTRY_NAME);
- SMP2P_SET_ENT_VALID(
- mock->remote_item.header.valid_total_ent, 1);
- msm_smp2p_set_remote_mock_exists(true);
- mock->tx_interrupt();
-
- smp2p_gpio_open_test_entry("smp2p",
- SMP2P_REMOTE_MOCK_PROC, true);
-
- /* verify set/get functions locally */
- UT_ASSERT_INT(0, <, cb_info->gpio_base_id);
- for (id = 0; id < SMP2P_BITS_PER_ENTRY && !failed; ++id) {
- int pin;
- int current_value;
-
- /* verify pin value cannot be set */
- pin = cb_info->gpio_base_id + id;
- current_value = gpio_get_value(pin);
-
- gpio_set_value(pin, 0);
- UT_ASSERT_INT(current_value, ==, gpio_get_value(pin));
- gpio_set_value(pin, 1);
- UT_ASSERT_INT(current_value, ==, gpio_get_value(pin));
-
- /* verify no interrupts */
- UT_ASSERT_INT(0, ==, cb_info->cb_count);
- }
- if (failed)
- break;
-
- /* register for interrupts */
- UT_ASSERT_INT(0, <, cb_info->irq_base_id);
- for (id = 0; id < SMP2P_BITS_PER_ENTRY && !failed; ++id) {
- virq = cb_info->irq_base_id + id;
- UT_ASSERT_PTR(NULL, !=, irq_to_desc(virq));
- ret = request_irq(virq,
- smp2p_gpio_irq, IRQF_TRIGGER_RISING,
- "smp2p_test", cb_info);
- UT_ASSERT_INT(0, ==, ret);
- }
- if (failed)
- break;
-
- /* verify both rising and falling edge interrupts */
- for (id = 0; id < SMP2P_BITS_PER_ENTRY && !failed; ++id) {
- virq = cb_info->irq_base_id + id;
- irq_set_irq_type(virq, IRQ_TYPE_EDGE_BOTH);
- cb_data_reset(cb_info);
-
- /* verify rising-edge interrupt */
- mock->remote_item.entries[0].entry = 1 << id;
- mock->tx_interrupt();
- UT_ASSERT_INT(cb_info->cb_count, ==, 1);
- UT_ASSERT_INT(0, <,
- test_bit(id, cb_info->triggered_irqs));
- test_bit(id, cb_info->triggered_irqs);
-
- /* verify falling-edge interrupt */
- mock->remote_item.entries[0].entry = 0;
- mock->tx_interrupt();
- UT_ASSERT_INT(cb_info->cb_count, ==, 2);
- UT_ASSERT_INT(0, <,
- test_bit(id, cb_info->triggered_irqs));
- }
- if (failed)
- break;
-
- /* verify rising-edge interrupts */
- for (id = 0; id < SMP2P_BITS_PER_ENTRY && !failed; ++id) {
- virq = cb_info->irq_base_id + id;
- irq_set_irq_type(virq, IRQ_TYPE_EDGE_RISING);
- cb_data_reset(cb_info);
-
- /* verify only rising-edge interrupt is triggered */
- mock->remote_item.entries[0].entry = 1 << id;
- mock->tx_interrupt();
- UT_ASSERT_INT(cb_info->cb_count, ==, 1);
- UT_ASSERT_INT(0, <,
- test_bit(id, cb_info->triggered_irqs));
- test_bit(id, cb_info->triggered_irqs);
-
- mock->remote_item.entries[0].entry = 0;
- mock->tx_interrupt();
- UT_ASSERT_INT(cb_info->cb_count, ==, 1);
- UT_ASSERT_INT(0, <,
- test_bit(id, cb_info->triggered_irqs));
- }
- if (failed)
- break;
-
- /* verify falling-edge interrupts */
- for (id = 0; id < SMP2P_BITS_PER_ENTRY && !failed; ++id) {
- virq = cb_info->irq_base_id + id;
- irq_set_irq_type(virq, IRQ_TYPE_EDGE_FALLING);
- cb_data_reset(cb_info);
-
- /* verify only rising-edge interrupt is triggered */
- mock->remote_item.entries[0].entry = 1 << id;
- mock->tx_interrupt();
- UT_ASSERT_INT(cb_info->cb_count, ==, 0);
- UT_ASSERT_INT(0, ==,
- test_bit(id, cb_info->triggered_irqs));
-
- mock->remote_item.entries[0].entry = 0;
- mock->tx_interrupt();
- UT_ASSERT_INT(cb_info->cb_count, ==, 1);
- UT_ASSERT_INT(0, <,
- test_bit(id, cb_info->triggered_irqs));
- }
- if (failed)
- break;
-
- seq_puts(s, "\tOK\n");
- } while (0);
-
- if (failed) {
- pr_err("%s: Failed\n", __func__);
- seq_puts(s, "\tFailed\n");
- }
-
- /* unregister for interrupts */
- if (cb_info->irq_base_id) {
- for (id = 0; id < SMP2P_BITS_PER_ENTRY; ++id)
- free_irq(cb_info->irq_base_id + id, cb_info);
- }
-
- smp2p_gpio_open_test_entry("smp2p",
- SMP2P_REMOTE_MOCK_PROC, false);
-}
-
-/**
- * smp2p_ut_local_gpio_in_update_open - Verify combined open/update.
- *
- * @s: pointer to output file
- *
- * If the remote side updates the SMP2P bits and sends before negotiation is
- * complete, then the UPDATE event will have to be delayed until negotiation is
- * complete. This should result in both the OPEN and UPDATE events coming in
- * right after each other and the behavior should be transparent to the clients
- * of SMP2P GPIO.
- */
-static void smp2p_ut_local_gpio_in_update_open(struct seq_file *s)
-{
- int failed = 0;
- struct gpio_info *cb_info = &gpio_info[SMP2P_REMOTE_MOCK_PROC].in;
- int id;
- int ret;
- int virq;
- struct msm_smp2p_remote_mock *mock;
-
- seq_printf(s, "Running %s\n", __func__);
-
- cb_data_reset(cb_info);
- do {
- /* initialize mock edge */
- ret = smp2p_reset_mock_edge();
- UT_ASSERT_INT(ret, ==, 0);
-
- mock = msm_smp2p_get_remote_mock();
- UT_ASSERT_PTR(mock, !=, NULL);
-
- mock->rx_interrupt_count = 0;
- memset(&mock->remote_item, 0,
- sizeof(struct smp2p_smem_item));
- smp2p_init_header((struct smp2p_smem *)&mock->remote_item,
- SMP2P_REMOTE_MOCK_PROC, SMP2P_APPS_PROC,
- 0, 1);
- strlcpy(mock->remote_item.entries[0].name, "smp2p",
- SMP2P_MAX_ENTRY_NAME);
- SMP2P_SET_ENT_VALID(
- mock->remote_item.header.valid_total_ent, 1);
-
- /* register for interrupts */
- smp2p_gpio_open_test_entry("smp2p",
- SMP2P_REMOTE_MOCK_PROC, true);
-
- UT_ASSERT_INT(0, <, cb_info->irq_base_id);
- for (id = 0; id < SMP2P_BITS_PER_ENTRY && !failed; ++id) {
- virq = cb_info->irq_base_id + id;
- UT_ASSERT_PTR(NULL, !=, irq_to_desc(virq));
- ret = request_irq(virq,
- smp2p_gpio_irq, IRQ_TYPE_EDGE_BOTH,
- "smp2p_test", cb_info);
- UT_ASSERT_INT(0, ==, ret);
- }
- if (failed)
- break;
-
- /* update the state value and complete negotiation */
- mock->remote_item.entries[0].entry = 0xDEADDEAD;
- msm_smp2p_set_remote_mock_exists(true);
- mock->tx_interrupt();
-
- /* verify delayed state updates were processed */
- for (id = 0; id < SMP2P_BITS_PER_ENTRY && !failed; ++id) {
- virq = cb_info->irq_base_id + id;
-
- UT_ASSERT_INT(cb_info->cb_count, >, 0);
- if (0x1 & (0xDEADDEAD >> id)) {
- /* rising edge should have been triggered */
- if (!test_bit(id, cb_info->triggered_irqs)) {
- seq_printf(s, "%s:%d bit %d clear, ",
- __func__, __LINE__, id);
- seq_puts(s, "expected set\n");
- failed = 1;
- break;
- }
- } else {
- /* edge should not have been triggered */
- if (test_bit(id, cb_info->triggered_irqs)) {
- seq_printf(s, "%s:%d bit %d set, ",
- __func__, __LINE__, id);
- seq_puts(s, "expected clear\n");
- failed = 1;
- break;
- }
- }
- }
- if (failed)
- break;
-
- seq_puts(s, "\tOK\n");
- } while (0);
-
- if (failed) {
- pr_err("%s: Failed\n", __func__);
- seq_puts(s, "\tFailed\n");
- }
-
- /* unregister for interrupts */
- if (cb_info->irq_base_id) {
- for (id = 0; id < SMP2P_BITS_PER_ENTRY; ++id)
- free_irq(cb_info->irq_base_id + id, cb_info);
- }
-
- smp2p_gpio_open_test_entry("smp2p",
- SMP2P_REMOTE_MOCK_PROC, false);
-}
-
-/**
- * smp2p_gpio_write_bits - writes value to each GPIO pin specified in mask.
- *
- * @gpio: gpio test structure
- * @mask: 1 = write gpio_value to this GPIO pin
- * @gpio_value: value to write to GPIO pin
- */
-static void smp2p_gpio_write_bits(struct gpio_info *gpio, uint32_t mask,
- int gpio_value)
-{
- int n;
-
- for (n = 0; n < SMP2P_BITS_PER_ENTRY; ++n) {
- if (mask & 0x1)
- gpio_set_value(gpio->gpio_base_id + n, gpio_value);
- mask >>= 1;
- }
-}
-
-static void smp2p_gpio_set_bits(struct gpio_info *gpio, uint32_t mask)
-{
- smp2p_gpio_write_bits(gpio, mask, 1);
-}
-
-static void smp2p_gpio_clr_bits(struct gpio_info *gpio, uint32_t mask)
-{
- smp2p_gpio_write_bits(gpio, mask, 0);
-}
-
-/**
- * smp2p_gpio_get_value - reads entire 32-bits of GPIO
- *
- * @gpio: gpio structure
- * @returns: 32 bit value of GPIO pins
- */
-static uint32_t smp2p_gpio_get_value(struct gpio_info *gpio)
-{
- int n;
- uint32_t value = 0;
-
- for (n = 0; n < SMP2P_BITS_PER_ENTRY; ++n) {
- if (gpio_get_value(gpio->gpio_base_id + n))
- value |= 1 << n;
- }
- return value;
-}
-
-/**
- * smp2p_ut_remote_inout_core - Verify inbound/outbound functionality.
- *
- * @s: pointer to output file
- * @remote_pid: Remote processor to test
- * @name: Name of the test for reporting
- *
- * This test verifies inbound/outbound functionality for the remote processor.
- */
-static void smp2p_ut_remote_inout_core(struct seq_file *s, int remote_pid,
- const char *name)
-{
- int failed = 0;
- uint32_t request;
- uint32_t response;
- struct gpio_info *cb_in;
- struct gpio_info *cb_out;
- int id;
- int ret;
-
- seq_printf(s, "Running %s for '%s' remote pid %d\n",
- __func__, smp2p_pid_to_name(remote_pid), remote_pid);
-
- cb_in = &gpio_info[remote_pid].in;
- cb_out = &gpio_info[remote_pid].out;
- cb_data_reset(cb_in);
- cb_data_reset(cb_out);
- do {
- /* open test entries */
- msm_smp2p_deinit_rmt_lpb_proc(remote_pid);
- smp2p_gpio_open_test_entry("smp2p", remote_pid, true);
-
- /* register for interrupts */
- UT_ASSERT_INT(0, <, cb_in->gpio_base_id);
- UT_ASSERT_INT(0, <, cb_in->irq_base_id);
- for (id = 0; id < SMP2P_BITS_PER_ENTRY && !failed; ++id) {
- int virq = cb_in->irq_base_id + id;
-
- UT_ASSERT_PTR(NULL, !=, irq_to_desc(virq));
- ret = request_irq(virq,
- smp2p_gpio_irq,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- "smp2p_test", cb_in);
- UT_ASSERT_INT(0, ==, ret);
- }
- if (failed)
- break;
-
- /* write echo of data value 0 */
- UT_ASSERT_INT(0, <, cb_out->gpio_base_id);
- request = 0x0;
- SMP2P_SET_RMT_CMD_TYPE(request, 1);
- SMP2P_SET_RMT_CMD(request, SMP2P_LB_CMD_ECHO);
- SMP2P_SET_RMT_DATA(request, 0x0);
-
- smp2p_gpio_set_bits(cb_out, SMP2P_RMT_IGNORE_MASK);
- smp2p_gpio_clr_bits(cb_out, ~SMP2P_RMT_IGNORE_MASK);
- smp2p_gpio_set_bits(cb_out, request);
-
- UT_ASSERT_INT(cb_in->cb_count, ==, 0);
- smp2p_gpio_clr_bits(cb_out, SMP2P_RMT_IGNORE_MASK);
-
- /* verify response */
- do {
- /* wait for up to 32 changes */
- if (wait_for_completion_timeout(
- &cb_in->cb_completion, HZ / 2) == 0)
- break;
- reinit_completion(&cb_in->cb_completion);
- } while (cb_in->cb_count < 32);
- UT_ASSERT_INT(cb_in->cb_count, >, 0);
- response = smp2p_gpio_get_value(cb_in);
- SMP2P_SET_RMT_CMD_TYPE(request, 0);
- UT_ASSERT_HEX(request, ==, response);
-
- /* write echo of data value of all 1's */
- request = 0x0;
- SMP2P_SET_RMT_CMD_TYPE(request, 1);
- SMP2P_SET_RMT_CMD(request, SMP2P_LB_CMD_ECHO);
- SMP2P_SET_RMT_DATA(request, ~0);
-
- smp2p_gpio_set_bits(cb_out, SMP2P_RMT_IGNORE_MASK);
- cb_data_reset(cb_in);
- smp2p_gpio_clr_bits(cb_out, ~SMP2P_RMT_IGNORE_MASK);
- smp2p_gpio_set_bits(cb_out, request);
-
- UT_ASSERT_INT(cb_in->cb_count, ==, 0);
- smp2p_gpio_clr_bits(cb_out, SMP2P_RMT_IGNORE_MASK);
-
- /* verify response including 24 interrupts */
- do {
- UT_ASSERT_INT(
- (int)wait_for_completion_timeout(
- &cb_in->cb_completion, HZ / 2),
- >, 0);
- reinit_completion(&cb_in->cb_completion);
- } while (cb_in->cb_count < 24);
- response = smp2p_gpio_get_value(cb_in);
- SMP2P_SET_RMT_CMD_TYPE(request, 0);
- UT_ASSERT_HEX(request, ==, response);
- UT_ASSERT_INT(24, ==, cb_in->cb_count);
-
- seq_puts(s, "\tOK\n");
- } while (0);
-
- if (failed) {
- pr_err("%s: Failed\n", name);
- seq_puts(s, "\tFailed\n");
- }
-
- /* unregister for interrupts */
- if (cb_in->irq_base_id) {
- for (id = 0; id < SMP2P_BITS_PER_ENTRY; ++id)
- free_irq(cb_in->irq_base_id + id, cb_in);
- }
-
- smp2p_gpio_open_test_entry("smp2p", remote_pid, false);
- msm_smp2p_init_rmt_lpb_proc(remote_pid);
-}
-
-/**
- * smp2p_ut_remote_inout - Verify inbound/outbound functionality for all.
- *
- * @s: pointer to output file
- *
- * This test verifies inbound and outbound functionality for all
- * configured remote processor.
- */
-static void smp2p_ut_remote_inout(struct seq_file *s)
-{
- struct smp2p_interrupt_config *int_cfg;
- int pid;
-
- int_cfg = smp2p_get_interrupt_config();
- if (!int_cfg) {
- seq_puts(s, "Remote processor config unavailable\n");
- return;
- }
-
- for (pid = 0; pid < SMP2P_NUM_PROCS; ++pid) {
- if (!int_cfg[pid].is_configured)
- continue;
-
- smp2p_ut_remote_inout_core(s, pid, __func__);
- }
-}
-
-static int __init smp2p_debugfs_init(void)
-{
- /* register GPIO pins */
- (void)platform_driver_register(&smp2p_gpio_driver);
-
- /*
- * Add Unit Test entries.
- *
- * The idea with unit tests is that you can run all of them
- * from ADB shell by doing:
- * adb shell
- * cat ut*
- *
- * And if particular tests fail, you can then repeatedly run the
- * failing tests as you debug and resolve the failing test.
- */
- smp2p_debug_create("ut_local_gpio_out", smp2p_ut_local_gpio_out);
- smp2p_debug_create("ut_local_gpio_in", smp2p_ut_local_gpio_in);
- smp2p_debug_create("ut_local_gpio_in_update_open",
- smp2p_ut_local_gpio_in_update_open);
- smp2p_debug_create("ut_remote_gpio_inout", smp2p_ut_remote_inout);
- return 0;
-}
-late_initcall(smp2p_debugfs_init);
diff --git a/drivers/leds/leds-qpnp-flash-v2.c b/drivers/leds/leds-qpnp-flash-v2.c
index 95eec82b85a0..ebf6e11594c3 100644
--- a/drivers/leds/leds-qpnp-flash-v2.c
+++ b/drivers/leds/leds-qpnp-flash-v2.c
@@ -123,6 +123,7 @@
#define FLASH_LED_REG_MULTI_STROBE_CTRL(base) (base + 0x71)
#define LED3_FLASH_ONCE_ONLY_BIT BIT(1)
+#define LED1N2_FLASH_ONCE_ONLY_BIT BIT(0)
#define FLASH_LED_REG_LPG_INPUT_CTRL(base) (base + 0x72)
#define LPG_INPUT_SEL_BIT BIT(0)
@@ -425,7 +426,7 @@ led_brightness qpnp_flash_led_brightness_get(struct led_classdev *led_cdev)
static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led)
{
int rc, i, addr_offset;
- u8 val = 0, mask;
+ u8 val = 0, mask, strobe_mask = 0, strobe_ctrl;
for (i = 0; i < led->num_fnodes; i++) {
addr_offset = led->fnode[i].id;
@@ -436,6 +437,57 @@ static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led)
return rc;
val |= 0x1 << led->fnode[i].id;
+
+ rc = qpnp_flash_led_write(led,
+ FLASH_LED_REG_SAFETY_TMR(led->base + addr_offset),
+ FLASH_LED_SAFETY_TMR_DISABLED);
+ if (rc < 0)
+ return rc;
+
+ if (led->fnode[i].strobe_sel == HW_STROBE) {
+ if (led->fnode[i].id == LED3)
+ strobe_mask |= LED3_FLASH_ONCE_ONLY_BIT;
+ else
+ strobe_mask |= LED1N2_FLASH_ONCE_ONLY_BIT;
+ }
+
+ if (led->fnode[i].id == LED3 &&
+ led->fnode[i].strobe_sel == LPG_STROBE)
+ strobe_mask |= LED3_FLASH_ONCE_ONLY_BIT;
+ /*
+ * As per the hardware recommendation, to use LED2/LED3 in HW
+ * strobe mode, LED1 should be set to HW strobe mode as well.
+ */
+ if (led->fnode[i].strobe_sel == HW_STROBE &&
+ (led->fnode[i].id == LED2 || led->fnode[i].id == LED3)) {
+ mask = FLASH_HW_STROBE_MASK;
+ addr_offset = led->fnode[LED1].id;
+ /*
+ * HW_STROBE: enable, TRIGGER: level,
+ * POLARITY: active high
+ */
+ strobe_ctrl = BIT(2) | BIT(0);
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_STROBE_CTRL(
+ led->base + addr_offset),
+ mask, strobe_ctrl);
+ if (rc < 0)
+ return rc;
+ }
+ }
+
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_MULTI_STROBE_CTRL(led->base),
+ strobe_mask, 0);
+ if (rc < 0)
+ return rc;
+
+ if (led->fnode[LED3].strobe_sel == LPG_STROBE) {
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_LPG_INPUT_CTRL(led->base),
+ LPG_INPUT_SEL_BIT, LPG_INPUT_SEL_BIT);
+ if (rc < 0)
+ return rc;
}
rc = qpnp_flash_led_write(led,
@@ -629,19 +681,6 @@ static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led)
return rc;
}
- if (led->fnode[LED3].strobe_sel == LPG_STROBE) {
- rc = qpnp_flash_led_masked_write(led,
- FLASH_LED_REG_MULTI_STROBE_CTRL(led->base),
- LED3_FLASH_ONCE_ONLY_BIT, 0);
- if (rc < 0)
- return rc;
-
- rc = qpnp_flash_led_masked_write(led,
- FLASH_LED_REG_LPG_INPUT_CTRL(led->base),
- LPG_INPUT_SEL_BIT, LPG_INPUT_SEL_BIT);
- if (rc < 0)
- return rc;
- }
return 0;
}
@@ -1291,6 +1330,12 @@ static int qpnp_flash_led_switch_disable(struct flash_switch_data *snode)
if (rc < 0)
return rc;
+ rc = qpnp_flash_led_write(led,
+ FLASH_LED_REG_SAFETY_TMR(led->base + addr_offset),
+ FLASH_LED_SAFETY_TMR_DISABLED);
+ if (rc < 0)
+ return rc;
+
led->fnode[i].led_on = false;
if (led->fnode[i].strobe_sel == HW_STROBE) {
diff --git a/drivers/mmc/host/cmdq_hci.c b/drivers/mmc/host/cmdq_hci.c
index 01811d94db65..815da18b5fc2 100644
--- a/drivers/mmc/host/cmdq_hci.c
+++ b/drivers/mmc/host/cmdq_hci.c
@@ -1108,7 +1108,7 @@ skip_cqterri:
/* read CQTCN and complete the request */
comp_status = cmdq_readl(cq_host, CQTCN);
if (!comp_status)
- goto out;
+ goto hac;
/*
* The CQTCN must be cleared before notifying req completion
* to upper layers to avoid missing completion notification
@@ -1135,7 +1135,7 @@ skip_cqterri:
}
}
}
-
+hac:
if (status & CQIS_HAC) {
if (cq_host->ops->post_cqe_halt)
cq_host->ops->post_cqe_halt(mmc);
@@ -1146,7 +1146,6 @@ skip_cqterri:
complete(&cq_host->halt_comp);
}
-out:
return IRQ_HANDLED;
}
EXPORT_SYMBOL(cmdq_irq);