spi: Fix build for Linux v6.8

For Linux v6.8, support for SPI controllers with multiple chip-selects
was added to the SPI core and this updated the 'chip_select' member of
the 'spi_device' structure to be an array. This breaks building the
Tegra124 SPI Slave driver and Tegra210 QUAD SPI driver.

A helper function, spi_get_chipselect(), was added for Linux v6.3 to
retrieve the chip-select for a SPI device and can be used for retrieving
the chip-select for all Linux v6.3+ kernels.

Add a conftest rule to detecting if spi_get_chipselect() is present and
if so use this for getting the chip-select. This fixes the build issues
for Linux v6.8.

Bug 4448428

Change-Id: Ia4f95ed96b9a18cc7da7a4a52305fc64bc31905c
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3050146
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
Jon Hunter
2023-12-11 11:58:22 -08:00
committed by mobile promotions
parent df68c65bab
commit 9e2f7ecdf7
4 changed files with 60 additions and 5 deletions

View File

@@ -1,5 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (C) 2023 NVIDIA CORPORATION. All rights reserved. // SPDX-FileCopyrightText: Copyright (C) 2023-2024 NVIDIA CORPORATION. All rights reserved.
#include <nvidia/conftest.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/reset.h> #include <linux/reset.h>
@@ -1357,7 +1359,11 @@ static int tegra_spi_start_transfer_one(struct spi_device *spi,
command1 |= SPI_TX_EN; command1 |= SPI_TX_EN;
tspi->cur_direction |= DATA_DIR_TX; tspi->cur_direction |= DATA_DIR_TX;
} }
#if defined(NV_SPI_GET_CHIPSELECT_PRESENT)
command1 |= SPI_CS_SEL(spi_get_chipselect(spi, 0));
#else
command1 |= SPI_CS_SEL(spi->chip_select); command1 |= SPI_CS_SEL(spi->chip_select);
#endif
tegra_spi_writel(tspi, command1, SPI_COMMAND1); tegra_spi_writel(tspi, command1, SPI_COMMAND1);
tspi->command1_reg = command1; tspi->command1_reg = command1;
@@ -1398,7 +1404,11 @@ static struct tegra_spi_controller_data
return NULL; return NULL;
} }
#if defined(NV_SPI_GET_CHIPSELECT_PRESENT)
cdata = &tspi->cdata[spi_get_chipselect(spi, 0)];
#else
cdata = &tspi->cdata[spi->chip_select]; cdata = &tspi->cdata[spi->chip_select];
#endif
memset(cdata, 0, sizeof(*cdata)); memset(cdata, 0, sizeof(*cdata));
ret = of_property_read_bool(data_np, "nvidia,variable-length-transfer"); ret = of_property_read_bool(data_np, "nvidia,variable-length-transfer");
@@ -1448,10 +1458,17 @@ static int tegra_spi_setup(struct spi_device *spi)
spin_lock_irqsave(&tspi->lock, flags); spin_lock_irqsave(&tspi->lock, flags);
val = tspi->def_command1_reg; val = tspi->def_command1_reg;
#if defined(NV_SPI_GET_CHIPSELECT_PRESENT)
if (spi->mode & SPI_CS_HIGH)
val &= ~cs_pol_bit[spi_get_chipselect(spi, 0)];
else
val |= cs_pol_bit[spi_get_chipselect(spi, 0)];
#else
if (spi->mode & SPI_CS_HIGH) if (spi->mode & SPI_CS_HIGH)
val &= ~cs_pol_bit[spi->chip_select]; val &= ~cs_pol_bit[spi->chip_select];
else else
val |= cs_pol_bit[spi->chip_select]; val |= cs_pol_bit[spi->chip_select];
#endif
if (tspi->lsbyte_first) if (tspi->lsbyte_first)
val |= SPI_LSBYTE_FE; val |= SPI_LSBYTE_FE;

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
// // SPDX-FileCopyrightText: Copyright (C) 2023-2024 NVIDIA CORPORATION. All rights reserved.
// Copyright (C) 2023 NVIDIA CORPORATION.
#include <nvidia/conftest.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/completion.h> #include <linux/completion.h>
@@ -925,7 +926,11 @@ static u32 tegra_qspi_setup_transfer_one(struct spi_device *spi, struct spi_tran
tegra_qspi_mask_clear_irq(tqspi); tegra_qspi_mask_clear_irq(tqspi);
command1 = tqspi->def_command1_reg; command1 = tqspi->def_command1_reg;
#if defined(NV_SPI_GET_CHIPSELECT_PRESENT)
command1 |= QSPI_CS_SEL(spi_get_chipselect(spi, 0));
#else
command1 |= QSPI_CS_SEL(spi->chip_select); command1 |= QSPI_CS_SEL(spi->chip_select);
#endif
command1 |= QSPI_BIT_LENGTH(bits_per_word - 1); command1 |= QSPI_BIT_LENGTH(bits_per_word - 1);
command1 &= ~QSPI_CONTROL_MODE_MASK; command1 &= ~QSPI_CONTROL_MODE_MASK;
@@ -1109,11 +1114,21 @@ static int tegra_qspi_setup(struct spi_device *spi)
/* keep default cs state to inactive */ /* keep default cs state to inactive */
val = tqspi->def_command1_reg; val = tqspi->def_command1_reg;
#if defined(NV_SPI_GET_CHIPSELECT_PRESENT)
val |= QSPI_CS_SEL(spi_get_chipselect(spi, 0));
if (spi->mode & SPI_CS_HIGH)
val &= ~QSPI_CS_POL_INACTIVE(spi_get_chipselect(spi, 0));
else
val |= QSPI_CS_POL_INACTIVE(spi_get_chipselect(spi, 0));
#else
val |= QSPI_CS_SEL(spi->chip_select); val |= QSPI_CS_SEL(spi->chip_select);
if (spi->mode & SPI_CS_HIGH) if (spi->mode & SPI_CS_HIGH)
val &= ~QSPI_CS_POL_INACTIVE(spi->chip_select); val &= ~QSPI_CS_POL_INACTIVE(spi->chip_select);
else else
val |= QSPI_CS_POL_INACTIVE(spi->chip_select); val |= QSPI_CS_POL_INACTIVE(spi->chip_select);
#endif
tqspi->def_command1_reg = val; tqspi->def_command1_reg = val;
tegra_qspi_writel(tqspi, tqspi->def_command1_reg, QSPI_COMMAND1); tegra_qspi_writel(tqspi, tqspi->def_command1_reg, QSPI_COMMAND1);

View File

@@ -1,6 +1,6 @@
########################################################################### ###########################################################################
# SPDX-License-Identifier: MIT # SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# #
# Makefile file for NVIDIA Linux conftest # Makefile file for NVIDIA Linux conftest
########################################################################### ###########################################################################
@@ -151,6 +151,7 @@ NV_CONFTEST_FUNCTION_COMPILE_TESTS += snd_soc_of_get_dai_name_has_index_arg
NV_CONFTEST_FUNCTION_COMPILE_TESTS += snd_soc_rtd_to_codec NV_CONFTEST_FUNCTION_COMPILE_TESTS += snd_soc_rtd_to_codec
NV_CONFTEST_FUNCTION_COMPILE_TESTS += simple_util_dai_init NV_CONFTEST_FUNCTION_COMPILE_TESTS += simple_util_dai_init
NV_CONFTEST_FUNCTION_COMPILE_TESTS += spi_driver_struct_remove_return_type_int NV_CONFTEST_FUNCTION_COMPILE_TESTS += spi_driver_struct_remove_return_type_int
NV_CONFTEST_FUNCTION_COMPILE_TESTS += spi_get_chipselect
NV_CONFTEST_FUNCTION_COMPILE_TESTS += tc_taprio_qopt_offload_struct_has_cmd NV_CONFTEST_FUNCTION_COMPILE_TESTS += tc_taprio_qopt_offload_struct_has_cmd
NV_CONFTEST_FUNCTION_COMPILE_TESTS += tegra_dev_iommu_get_stream_id NV_CONFTEST_FUNCTION_COMPILE_TESTS += tegra_dev_iommu_get_stream_id
NV_CONFTEST_FUNCTION_COMPILE_TESTS += tegra_ivc_struct_has_iosys_map NV_CONFTEST_FUNCTION_COMPILE_TESTS += tegra_ivc_struct_has_iosys_map

View File

@@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
# SPDX-License-Identifier: MIT # SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
PATH="${PATH}:/bin:/sbin:/usr/bin" PATH="${PATH}:/bin:/sbin:/usr/bin"
@@ -7463,6 +7463,28 @@ compile_test() {
compile_check_conftest "$CODE" "NV_SPI_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT" "" "types" compile_check_conftest "$CODE" "NV_SPI_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT" "" "types"
;; ;;
spi_get_chipselect)
#
# Determine if the function 'spi_get_chip_select()' is present.
#
# In Linux v6.3, commit 303feb3cc06a ("spi: Add APIs in spi core to set/get
# spi->chip_select and spi->cs_gpiod") added a helper function,
# spi_get_chipselect(), so drivers did not need to access the
# 'spi_device->chip_select' directly. This Linux v6.8, commit 4d8ff6b0991d
# ("spi: Add multi-cs memories support in SPI core") updated the
# 'spi_device->chip_select' to be an array and so using spi_get_chipselect
# to retrieve the chipselect is required for Linux v6.8.
#
CODE="
#undef CONFIG_ACPI
#include <linux/spi/spi.h>
void conftest_spi_get_chipselect(void) {
spi_get_chipselect();
}"
compile_check_conftest "$CODE" "NV_SPI_GET_CHIPSELECT_PRESENT" "" "functions"
;;
tc_taprio_qopt_offload_struct_has_cmd) tc_taprio_qopt_offload_struct_has_cmd)
# #
# Determine if struct tc_taprio_qopt_offload has a member named cmd # Determine if struct tc_taprio_qopt_offload has a member named cmd