diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2018-11-16 08:27:42 -0800 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2018-11-16 08:27:42 -0800 |
commit | a3068cb89b1cd07e663b32aacc265fc03075bcce (patch) | |
tree | 94cbe2b275e8e1908e0ce5dbea44e1e3c93a1045 | |
parent | b21b55f9b6443a673524ee7ee429a7abaff7c155 (diff) | |
parent | 05faeb588a3d00fb41035a3d79f2abb4d7ac03ba (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.dtsi | 2 | ||||
-rw-r--r-- | arch/arm64/boot/dts/qcom/sdm439.dtsi | 2 | ||||
-rw-r--r-- | drivers/clk/msm/clock-gcc-8952.c | 3 | ||||
-rw-r--r-- | drivers/gpio/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpio/gpio-msm-smp2p-test.c | 763 | ||||
-rw-r--r-- | drivers/leds/leds-qpnp-flash-v2.c | 73 | ||||
-rw-r--r-- | drivers/mmc/host/cmdq_hci.c | 5 |
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); |