Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion drivers/iio/trx-rf/adrv903x/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ adrv903x_drv-y = \
initdata.o \
adrv903x.o \
adrv903x_conv.o \
adrv903x_debugfs.o
adrv903x_debugfs.o \
adrv903x_ramc.o

ccflags-y += -I$(src)/devices/adrv903x/private/include/ \
-I$(src)/devices/adrv903x/public/include/ \
Expand Down
4 changes: 4 additions & 0 deletions drivers/iio/trx-rf/adrv903x/adrv903x.c
Original file line number Diff line number Diff line change
Expand Up @@ -2121,7 +2121,7 @@
enum jesd204_state_op_reason reason)
{
struct adrv903x_jesd204_priv *priv = jesd204_dev_priv(jdev);
struct device *dev = jesd204_dev_to_device(jdev);

Check warning on line 2124 in drivers/iio/trx-rf/adrv903x/adrv903x.c

View workflow job for this annotation

GitHub Actions / build_llvm_x86_64 / build

clang_analyzer: Value stored to 'dev' during its initialization is never read [deadcode.DeadStores] 2124 | struct device *dev = jesd204_dev_to_device(jdev); | ^~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
struct adrv903x_rf_phy *phy = priv->phy;
u32 deviceClockScaled_kHz = 0;
long dev_clk;
Expand Down Expand Up @@ -2159,7 +2159,7 @@
enum jesd204_state_op_reason reason)
{
struct adrv903x_jesd204_priv *priv = jesd204_dev_priv(jdev);
struct device *dev = jesd204_dev_to_device(jdev);

Check warning on line 2162 in drivers/iio/trx-rf/adrv903x/adrv903x.c

View workflow job for this annotation

GitHub Actions / build_llvm_x86_64 / build

clang_analyzer: Value stored to 'dev' during its initialization is never read [deadcode.DeadStores] 2162 | struct device *dev = jesd204_dev_to_device(jdev); | ^~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
struct adrv903x_rf_phy *phy = priv->phy;
int ret;

Expand Down Expand Up @@ -2189,7 +2189,7 @@
enum jesd204_state_op_reason reason)
{
struct adrv903x_jesd204_priv *priv = jesd204_dev_priv(jdev);
struct device *dev = jesd204_dev_to_device(jdev);

Check warning on line 2192 in drivers/iio/trx-rf/adrv903x/adrv903x.c

View workflow job for this annotation

GitHub Actions / build_llvm_x86_64 / build

clang_analyzer: Value stored to 'dev' during its initialization is never read [deadcode.DeadStores] 2192 | struct device *dev = jesd204_dev_to_device(jdev); | ^~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
struct adrv903x_rf_phy *phy = priv->phy;
int ret, i;
u32 mcsStatus;
Expand Down Expand Up @@ -2228,7 +2228,7 @@
enum jesd204_state_op_reason reason)
{
struct adrv903x_jesd204_priv *priv = jesd204_dev_priv(jdev);
struct device *dev = jesd204_dev_to_device(jdev);

Check warning on line 2231 in drivers/iio/trx-rf/adrv903x/adrv903x.c

View workflow job for this annotation

GitHub Actions / build_llvm_x86_64 / build

clang_analyzer: Value stored to 'dev' during its initialization is never read [deadcode.DeadStores] 2231 | struct device *dev = jesd204_dev_to_device(jdev); | ^~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
struct adrv903x_rf_phy *phy = priv->phy;
int ret;

Expand Down Expand Up @@ -2373,7 +2373,7 @@
struct jesd204_link *lnk)
{
struct adrv903x_jesd204_priv *priv = jesd204_dev_priv(jdev);
struct device *dev = jesd204_dev_to_device(jdev);

Check warning on line 2376 in drivers/iio/trx-rf/adrv903x/adrv903x.c

View workflow job for this annotation

GitHub Actions / build_llvm_x86_64 / build

clang_analyzer: Value stored to 'dev' during its initialization is never read [deadcode.DeadStores] 2376 | struct device *dev = jesd204_dev_to_device(jdev); | ^~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
struct adrv903x_rf_phy *phy = priv->phy;
int ret;

Expand Down Expand Up @@ -2443,7 +2443,7 @@
struct jesd204_link *lnk)
{
struct adrv903x_jesd204_priv *priv = jesd204_dev_priv(jdev);
struct device *dev = jesd204_dev_to_device(jdev);

Check warning on line 2446 in drivers/iio/trx-rf/adrv903x/adrv903x.c

View workflow job for this annotation

GitHub Actions / build_llvm_x86_64 / build

clang_analyzer: Value stored to 'dev' during its initialization is never read [deadcode.DeadStores] 2446 | struct device *dev = jesd204_dev_to_device(jdev); | ^~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
struct adrv903x_rf_phy *phy = priv->phy;
int ret;

Expand Down Expand Up @@ -2734,7 +2734,7 @@
return ret;

priv = jesd204_dev_priv(jdev);
priv->phy = phy;

Check warning on line 2737 in drivers/iio/trx-rf/adrv903x/adrv903x.c

View workflow job for this annotation

GitHub Actions / build_gcc_arm / build

gcc_fanalayzer: dereference of NULL ‘0’ [CWE-476] [-Wanalyzer-null-dereference] 2737 | priv->phy = phy; | ~~~~~~~~~~^~~~~ ‘adrv903x_probe’: events 1-7 | | 2695 | static int adrv903x_probe(struct spi_device *spi) | | ^~~~~~~~~~~~~~ | | | | | (1) entry to ‘adrv903x_probe’ |...... | 2711 | if (!chip_info) | | ~ | | | | | (2) following ‘false’ branch (when ‘chip_info’ is non-NULL)... |...... | 2718 | clk = devm_clk_get_enabled(&spi->dev, "dev_clk"); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (3) ...to here | 2719 | if (IS_ERR(clk)) | | ~ | | | | | (4) following ‘false’ branch... |...... | 2722 | indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*phy)); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (5) ...to here | 2723 | if (!indio_dev) | | ~ | | | | | (6) following ‘false’ branch (when ‘indio_dev’ is non-NULL)... |...... | 2726 | phy = iio_priv(indio_dev); | | ~ | | | | | (7) inlined call to ‘iio_priv’ from ‘adrv903x_probe’ | +--> ‘iio_priv’: event 8 | |/home/runner/_work/linux/linux/include/linux/iio/iio.h:847:25: | 847 | return indio_dev->priv; | | ~~~~~~~~~^~~~~~ | | | | | (8) ...to here | <------+ | ‘adrv903x_probe’: event 9 | |/home/runner/_work/linux/linux/drivers/iio/trx-rf/adrv903x/adrv903x.c:2737:19: | 2737 | priv->phy = phy; | | ~~~~~~~~~~^~~~~ | | | | | (9) dereference of NULL ‘0’ |

phy->palauDevice = &phy->adi_adrv903x_device;
phy->linux_hal.spi = spi;
Expand Down Expand Up @@ -2938,6 +2938,10 @@

adrv903x_register_debugfs(indio_dev);

ret = adrv903x_ramc_probe(phy);
if (ret < 0)
return ret;

return devm_jesd204_fsm_start(&spi->dev, phy->jdev, JESD204_LINKS_ALL);
}

Expand Down
7 changes: 7 additions & 0 deletions drivers/iio/trx-rf/adrv903x/adrv903x.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* ADRV903X
Expand Down Expand Up @@ -74,6 +74,7 @@
DBGFS_RX7_ADC_STATUS,
DBGFS_ORX0_ADC_STATUS,
DBGFS_ORX1_ADC_STATUS,
DBGFS_RX_DATA_CAPTURE,
};

enum adrv903x_rx_ext_info {
Expand Down Expand Up @@ -199,6 +200,10 @@

bool is_initialized;
const struct adrv903x_chip_info *chip_info;

/* RX/ORx data capture storage */
u32 *rx_capture_data;
u32 rx_capture_len;
bool tx_test_tone_en[8];
u32 tx_test_tone_freq_khz[8];
u32 tx_test_tone_phase[8];
Expand Down Expand Up @@ -234,4 +239,6 @@
static inline void adrv903x_register_debugfs(struct iio_dev *indio_dev) { }
#endif

int adrv903x_ramc_probe(struct adrv903x_rf_phy *phy);

#endif
96 changes: 96 additions & 0 deletions drivers/iio/trx-rf/adrv903x/adrv903x_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,33 @@
u8 chan;
int ret;

/* Handle RX data capture read specially */
if (entry->cmd == DBGFS_RX_DATA_CAPTURE) {
char *out_buf;
size_t buf_size, pos = 0;
u32 i;
ssize_t result;

guard(mutex)(&phy->lock);

if (!phy->rx_capture_data || !phy->rx_capture_len)
return -ENODATA;

/* Allocate buffer: up to 12 chars per value (including newline) */
buf_size = phy->rx_capture_len * 12 + 1;
out_buf = kvzalloc(buf_size, GFP_KERNEL);
if (!out_buf)
return -ENOMEM;

for (i = 0; i < phy->rx_capture_len && pos < buf_size - 12; i++)
pos += scnprintf(out_buf + pos, buf_size - pos, "%u\n",
phy->rx_capture_data[i]);

result = simple_read_from_buffer(userbuf, count, ppos, out_buf, pos);
kvfree(out_buf);
return result;
}

if (entry->out_value) {
switch (entry->size) {
case 1:
Expand Down Expand Up @@ -123,7 +150,7 @@
if (chan < ADI_ADRV903X_RX7) {
ret = adrv903x_tr_cal_status_read(phy, ADI_ADRV903X_TC_RX_ADC_MASK, chan, buf);
} else {
chan = ADI_ADRV903X_ORX0 << (entry->cmd - DBGFS_ORX0_ADC_STATUS);

Check warning on line 153 in drivers/iio/trx-rf/adrv903x/adrv903x_debugfs.c

View workflow job for this annotation

GitHub Actions / build_llvm_x86_64 / build

clang_analyzer: Right operand is negative in left shift [core.BitwiseShift] 153 | chan = ADI_ADRV903X_ORX0 << (entry->cmd - DBGFS_ORX0_ADC_STATUS); | ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ret = adrv903x_tr_cal_status_read(phy, ADI_ADRV903X_TC_ORX_ADC_MASK, chan, buf);
}
if (ret < 0)
Expand Down Expand Up @@ -161,6 +188,74 @@
return ret;
buf[ret] = '\0';

/*
* Handle RX_DATA_CAPTURE before taking the lock since it needs
* to allocate memory with GFP_KERNEL which can sleep.
*/
if (entry->cmd == DBGFS_RX_DATA_CAPTURE) {
adi_adrv903x_RxChannels_e chan_sel;
u32 *capture_buf;
u32 length;

if (sscanf(buf, "%lld %u", &val, &length) < 2)
return -EINVAL;

/* Channel: 0-7 for RX0-RX7, 8-9 for ORX0-ORX1 */
if (val < 0 || val > 9)
return -EINVAL;

/* Validate capture length against hardware-supported sizes */
switch (length) {
case ADI_ADRV903X_CAPTURE_SIZE_32:
case ADI_ADRV903X_CAPTURE_SIZE_64:
case ADI_ADRV903X_CAPTURE_SIZE_128:
case ADI_ADRV903X_CAPTURE_SIZE_256:
case ADI_ADRV903X_CAPTURE_SIZE_512:
case ADI_ADRV903X_CAPTURE_SIZE_1K:
case ADI_ADRV903X_CAPTURE_SIZE_2K:
case ADI_ADRV903X_CAPTURE_SIZE_4K:
case ADI_ADRV903X_CAPTURE_SIZE_8K:
case ADI_ADRV903X_CAPTURE_SIZE_12K:
break;
case ADI_ADRV903X_CAPTURE_SIZE_16K:
case ADI_ADRV903X_CAPTURE_SIZE_32K:
/* ORX channels limited to 12K max */
if (val >= 8)
return -EINVAL;
break;
default:
return -EINVAL;
}

if (val < 8)
chan_sel = ADI_ADRV903X_RX0 << val;
else
chan_sel = ADI_ADRV903X_ORX0 << (val - 8);

capture_buf = kvcalloc(length, sizeof(u32), GFP_KERNEL);
if (!capture_buf)
return -ENOMEM;

guard(mutex)(&phy->lock);

ret = adi_adrv903x_RxOrxDataCaptureStart(phy->palauDevice,
chan_sel,
ADI_ADRV903X_CAPTURE_LOC_DDC0,
capture_buf, length,
0, 1000000);
if (ret) {
kvfree(capture_buf);
return __adrv903x_dev_err(phy, __func__, __LINE__);
}

kvfree(phy->rx_capture_data);
phy->rx_capture_data = capture_buf;
phy->rx_capture_len = length;
entry->val = val;

return count;
}

ret = sscanf(buf, "%lli %i %i %i", &val, &val2, &val3, &val4);
if (ret < 1)
return -EINVAL;
Expand Down Expand Up @@ -320,6 +415,7 @@
}
adrv903x_add_debugfs_entry(phy, "orx0_adc_status", DBGFS_ORX0_ADC_STATUS);
adrv903x_add_debugfs_entry(phy, "orx1_adc_status", DBGFS_ORX1_ADC_STATUS);
adrv903x_add_debugfs_entry(phy, "rx_data_capture", DBGFS_RX_DATA_CAPTURE);

for (i = 0; i < phy->adrv903x_debugfs_entry_index; i++) {
if (phy->adrv903x_debugfs_entry_index > DBGFS_BIST_TONE)
Expand Down
Loading
Loading