Skip to content

Commit

Permalink
Merge tag 'char-misc-6.3-rc6' of git://git.kernel.org/pub/scm/linux/k…
Browse files Browse the repository at this point in the history
…ernel/git/gregkh/char-misc

Pull char/misc driver fixes from Greg KH:
 "Here are a small set of various small driver changes for 6.3-rc6.
  Included in here are:

   - iio driver fixes for reported problems

   - coresight hwtracing bugfix for reported problem

   - small counter driver bugfixes

  All have been in linux-next for a while with no reported problems"

* tag 'char-misc-6.3-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
  coresight: etm4x: Do not access TRCIDR1 for identification
  coresight-etm4: Fix for() loop drvdata->nr_addr_cmp range bug
  iio: adc: ti-ads7950: Set `can_sleep` flag for GPIO chip
  iio: adc: palmas_gpadc: fix NULL dereference on rmmod
  counter: 104-quad-8: Fix Synapse action reported for Index signals
  counter: 104-quad-8: Fix race condition between FLAG and CNTR reads
  iio: adc: max11410: fix read_poll_timeout() usage
  iio: dac: cio-dac: Fix max DAC write value check for 12-bit
  iio: light: cm32181: Unregister second I2C client if present
  iio: accel: kionix-kx022a: Get the timestamp from the driver's private data in the trigger_handler
  iio: adc: ad7791: fix IRQ flags
  iio: buffer: make sure O_NONBLOCK is respected
  iio: buffer: correctly return bytes written in output buffers
  iio: light: vcnl4000: Fix WARN_ON on uninitialized lock
  iio: adis16480: select CONFIG_CRC32
  drivers: iio: adc: ltc2497: fix LSB shift
  iio: adc: qcom-spmi-adc5: Fix the channel name
  • Loading branch information
torvalds committed Apr 8, 2023
2 parents aa46fe3 + 4bffd2c commit 68047c4
Show file tree
Hide file tree
Showing 15 changed files with 84 additions and 77 deletions.
31 changes: 9 additions & 22 deletions drivers/counter/104-quad-8.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,6 @@ struct quad8 {
struct quad8_reg __iomem *reg;
};

/* Borrow Toggle flip-flop */
#define QUAD8_FLAG_BT BIT(0)
/* Carry Toggle flip-flop */
#define QUAD8_FLAG_CT BIT(1)
/* Error flag */
#define QUAD8_FLAG_E BIT(4)
/* Up/Down flag */
Expand Down Expand Up @@ -133,6 +129,9 @@ struct quad8 {
#define QUAD8_CMR_QUADRATURE_X2 0x10
#define QUAD8_CMR_QUADRATURE_X4 0x18

/* Each Counter is 24 bits wide */
#define LS7267_CNTR_MAX GENMASK(23, 0)

static int quad8_signal_read(struct counter_device *counter,
struct counter_signal *signal,
enum counter_signal_level *level)
Expand All @@ -156,18 +155,10 @@ static int quad8_count_read(struct counter_device *counter,
{
struct quad8 *const priv = counter_priv(counter);
struct channel_reg __iomem *const chan = priv->reg->channel + count->id;
unsigned int flags;
unsigned int borrow;
unsigned int carry;
unsigned long irqflags;
int i;

flags = ioread8(&chan->control);
borrow = flags & QUAD8_FLAG_BT;
carry = !!(flags & QUAD8_FLAG_CT);

/* Borrow XOR Carry effectively doubles count range */
*val = (unsigned long)(borrow ^ carry) << 24;
*val = 0;

spin_lock_irqsave(&priv->lock, irqflags);

Expand All @@ -191,8 +182,7 @@ static int quad8_count_write(struct counter_device *counter,
unsigned long irqflags;
int i;

/* Only 24-bit values are supported */
if (val > 0xFFFFFF)
if (val > LS7267_CNTR_MAX)
return -ERANGE;

spin_lock_irqsave(&priv->lock, irqflags);
Expand Down Expand Up @@ -378,7 +368,7 @@ static int quad8_action_read(struct counter_device *counter,

/* Handle Index signals */
if (synapse->signal->id >= 16) {
if (priv->preset_enable[count->id])
if (!priv->preset_enable[count->id])
*action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
else
*action = COUNTER_SYNAPSE_ACTION_NONE;
Expand Down Expand Up @@ -806,8 +796,7 @@ static int quad8_count_preset_write(struct counter_device *counter,
struct quad8 *const priv = counter_priv(counter);
unsigned long irqflags;

/* Only 24-bit values are supported */
if (preset > 0xFFFFFF)
if (preset > LS7267_CNTR_MAX)
return -ERANGE;

spin_lock_irqsave(&priv->lock, irqflags);
Expand All @@ -834,8 +823,7 @@ static int quad8_count_ceiling_read(struct counter_device *counter,
*ceiling = priv->preset[count->id];
break;
default:
/* By default 0x1FFFFFF (25 bits unsigned) is maximum count */
*ceiling = 0x1FFFFFF;
*ceiling = LS7267_CNTR_MAX;
break;
}

Expand All @@ -850,8 +838,7 @@ static int quad8_count_ceiling_write(struct counter_device *counter,
struct quad8 *const priv = counter_priv(counter);
unsigned long irqflags;

/* Only 24-bit values are supported */
if (ceiling > 0xFFFFFF)
if (ceiling > LS7267_CNTR_MAX)
return -ERANGE;

spin_lock_irqsave(&priv->lock, irqflags);
Expand Down
24 changes: 10 additions & 14 deletions drivers/hwtracing/coresight/coresight-etm4x-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
if (etm4x_sspcicrn_present(drvdata, i))
etm4x_relaxed_write32(csa, config->ss_pe_cmp[i], TRCSSPCICRn(i));
}
for (i = 0; i < drvdata->nr_addr_cmp; i++) {
for (i = 0; i < drvdata->nr_addr_cmp * 2; i++) {
etm4x_relaxed_write64(csa, config->addr_val[i], TRCACVRn(i));
etm4x_relaxed_write64(csa, config->addr_acc[i], TRCACATRn(i));
}
Expand Down Expand Up @@ -1070,25 +1070,21 @@ static bool etm4_init_iomem_access(struct etmv4_drvdata *drvdata,
struct csdev_access *csa)
{
u32 devarch = readl_relaxed(drvdata->base + TRCDEVARCH);
u32 idr1 = readl_relaxed(drvdata->base + TRCIDR1);

/*
* All ETMs must implement TRCDEVARCH to indicate that
* the component is an ETMv4. To support any broken
* implementations we fall back to TRCIDR1 check, which
* is not really reliable.
* the component is an ETMv4. Even though TRCIDR1 also
* contains the information, it is part of the "Trace"
* register and must be accessed with the OSLK cleared,
* with MMIO. But we cannot touch the OSLK until we are
* sure this is an ETM. So rely only on the TRCDEVARCH.
*/
if ((devarch & ETM_DEVARCH_ID_MASK) == ETM_DEVARCH_ETMv4x_ARCH) {
drvdata->arch = etm_devarch_to_arch(devarch);
} else {
pr_warn("CPU%d: ETM4x incompatible TRCDEVARCH: %x, falling back to TRCIDR1\n",
smp_processor_id(), devarch);

if (ETM_TRCIDR1_ARCH_MAJOR(idr1) != ETM_TRCIDR1_ARCH_ETMv4)
return false;
drvdata->arch = etm_trcidr_to_arch(idr1);
if ((devarch & ETM_DEVARCH_ID_MASK) != ETM_DEVARCH_ETMv4x_ARCH) {
pr_warn_once("TRCDEVARCH doesn't match ETMv4 architecture\n");
return false;
}

drvdata->arch = etm_devarch_to_arch(devarch);
*csa = CSDEV_ACCESS_IOMEM(drvdata->base);
return true;
}
Expand Down
20 changes: 6 additions & 14 deletions drivers/hwtracing/coresight/coresight-etm4x.h
Original file line number Diff line number Diff line change
Expand Up @@ -753,14 +753,12 @@
* TRCDEVARCH - CoreSight architected register
* - Bits[15:12] - Major version
* - Bits[19:16] - Minor version
* TRCIDR1 - ETM architected register
* - Bits[11:8] - Major version
* - Bits[7:4] - Minor version
* We must rely on TRCDEVARCH for the version information,
* however we don't want to break the support for potential
* old implementations which might not implement it. Thus
* we fall back to TRCIDR1 if TRCDEVARCH is not implemented
* for memory mapped components.
*
* We must rely only on TRCDEVARCH for the version information. Even though,
* TRCIDR1 also provides the architecture version, it is a "Trace" register
* and as such must be accessed only with Trace power domain ON. This may
* not be available at probe time.
*
* Now to make certain decisions easier based on the version
* we use an internal representation of the version in the
* driver, as follows :
Expand All @@ -786,12 +784,6 @@ static inline u8 etm_devarch_to_arch(u32 devarch)
ETM_DEVARCH_REVISION(devarch));
}

static inline u8 etm_trcidr_to_arch(u32 trcidr1)
{
return ETM_ARCH_VERSION(ETM_TRCIDR1_ARCH_MAJOR(trcidr1),
ETM_TRCIDR1_ARCH_MINOR(trcidr1));
}

enum etm_impdef_type {
ETM4_IMPDEF_HISI_CORE_COMMIT,
ETM4_IMPDEF_FEATURE_MAX,
Expand Down
2 changes: 1 addition & 1 deletion drivers/iio/accel/kionix-kx022a.c
Original file line number Diff line number Diff line change
Expand Up @@ -864,7 +864,7 @@ static irqreturn_t kx022a_trigger_handler(int irq, void *p)
if (ret < 0)
goto err_read;

iio_push_to_buffers_with_timestamp(idev, data->buffer, pf->timestamp);
iio_push_to_buffers_with_timestamp(idev, data->buffer, data->timestamp);
err_read:
iio_trigger_notify_done(idev->trig);

Expand Down
2 changes: 1 addition & 1 deletion drivers/iio/adc/ad7791.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ static const struct ad_sigma_delta_info ad7791_sigma_delta_info = {
.has_registers = true,
.addr_shift = 4,
.read_mask = BIT(3),
.irq_flags = IRQF_TRIGGER_LOW,
.irq_flags = IRQF_TRIGGER_FALLING,
};

static int ad7791_read_raw(struct iio_dev *indio_dev,
Expand Down
6 changes: 2 additions & 4 deletions drivers/iio/adc/ltc2497.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ struct ltc2497_driverdata {
struct ltc2497core_driverdata common_ddata;
struct i2c_client *client;
u32 recv_size;
u32 sub_lsb;
/*
* DMA (thus cache coherency maintenance) may require the
* transfer buffers to live in their own cache lines.
Expand Down Expand Up @@ -65,10 +64,10 @@ static int ltc2497_result_and_measure(struct ltc2497core_driverdata *ddata,
* equivalent to a sign extension.
*/
if (st->recv_size == 3) {
*val = (get_unaligned_be24(st->data.d8) >> st->sub_lsb)
*val = (get_unaligned_be24(st->data.d8) >> 6)
- BIT(ddata->chip_info->resolution + 1);
} else {
*val = (be32_to_cpu(st->data.d32) >> st->sub_lsb)
*val = (be32_to_cpu(st->data.d32) >> 6)
- BIT(ddata->chip_info->resolution + 1);
}

Expand Down Expand Up @@ -122,7 +121,6 @@ static int ltc2497_probe(struct i2c_client *client)
st->common_ddata.chip_info = chip_info;

resolution = chip_info->resolution;
st->sub_lsb = 31 - (resolution + 1);
st->recv_size = BITS_TO_BYTES(resolution) + 1;

return ltc2497core_probe(dev, indio_dev);
Expand Down
22 changes: 15 additions & 7 deletions drivers/iio/adc/max11410.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,13 +414,17 @@ static int max11410_sample(struct max11410_state *st, int *sample_raw,
if (!ret)
return -ETIMEDOUT;
} else {
int ret2;

/* Wait for status register Conversion Ready flag */
ret = read_poll_timeout(max11410_read_reg, ret,
ret || (val & MAX11410_STATUS_CONV_READY_BIT),
ret = read_poll_timeout(max11410_read_reg, ret2,
ret2 || (val & MAX11410_STATUS_CONV_READY_BIT),
5000, MAX11410_CONVERSION_TIMEOUT_MS * 1000,
true, st, MAX11410_REG_STATUS, &val);
if (ret)
return ret;
if (ret2)
return ret2;
}

/* Read ADC Data */
Expand Down Expand Up @@ -851,17 +855,21 @@ static int max11410_init_vref(struct device *dev,

static int max11410_calibrate(struct max11410_state *st, u32 cal_type)
{
int ret, val;
int ret, ret2, val;

ret = max11410_write_reg(st, MAX11410_REG_CAL_START, cal_type);
if (ret)
return ret;

/* Wait for status register Calibration Ready flag */
return read_poll_timeout(max11410_read_reg, ret,
ret || (val & MAX11410_STATUS_CAL_READY_BIT),
50000, MAX11410_CALIB_TIMEOUT_MS * 1000, true,
st, MAX11410_REG_STATUS, &val);
ret = read_poll_timeout(max11410_read_reg, ret2,
ret2 || (val & MAX11410_STATUS_CAL_READY_BIT),
50000, MAX11410_CALIB_TIMEOUT_MS * 1000, true,
st, MAX11410_REG_STATUS, &val);
if (ret)
return ret;

return ret2;
}

static int max11410_self_calibrate(struct max11410_state *st)
Expand Down
2 changes: 1 addition & 1 deletion drivers/iio/adc/palmas_gpadc.c
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ static int palmas_gpadc_probe(struct platform_device *pdev)

static int palmas_gpadc_remove(struct platform_device *pdev)
{
struct iio_dev *indio_dev = dev_to_iio_dev(&pdev->dev);
struct iio_dev *indio_dev = dev_get_drvdata(&pdev->dev);
struct palmas_gpadc *adc = iio_priv(indio_dev);

if (adc->wakeup1_enable || adc->wakeup2_enable)
Expand Down
10 changes: 9 additions & 1 deletion drivers/iio/adc/qcom-spmi-adc5.c
Original file line number Diff line number Diff line change
Expand Up @@ -628,12 +628,20 @@ static int adc5_get_fw_channel_data(struct adc5_chip *adc,
struct fwnode_handle *fwnode,
const struct adc5_data *data)
{
const char *name = fwnode_get_name(fwnode), *channel_name;
const char *channel_name;
char *name;
u32 chan, value, varr[2];
u32 sid = 0;
int ret;
struct device *dev = adc->dev;

name = devm_kasprintf(dev, GFP_KERNEL, "%pfwP", fwnode);
if (!name)
return -ENOMEM;

/* Cut the address part */
name[strchrnul(name, '@') - name] = '\0';

ret = fwnode_property_read_u32(fwnode, "reg", &chan);
if (ret) {
dev_err(dev, "invalid channel number %s\n", name);
Expand Down
1 change: 1 addition & 0 deletions drivers/iio/adc/ti-ads7950.c
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,7 @@ static int ti_ads7950_probe(struct spi_device *spi)
st->chip.label = dev_name(&st->spi->dev);
st->chip.parent = &st->spi->dev;
st->chip.owner = THIS_MODULE;
st->chip.can_sleep = true;
st->chip.base = -1;
st->chip.ngpio = TI_ADS7950_NUM_GPIOS;
st->chip.get_direction = ti_ads7950_get_direction;
Expand Down
4 changes: 2 additions & 2 deletions drivers/iio/dac/cio-dac.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ static int cio_dac_write_raw(struct iio_dev *indio_dev,
if (mask != IIO_CHAN_INFO_RAW)
return -EINVAL;

/* DAC can only accept up to a 16-bit value */
if ((unsigned int)val > 65535)
/* DAC can only accept up to a 12-bit value */
if ((unsigned int)val > 4095)
return -EINVAL;

priv->chan_out_states[chan->channel] = val;
Expand Down
1 change: 1 addition & 0 deletions drivers/iio/imu/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ config ADIS16480
depends on SPI
select IIO_ADIS_LIB
select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
select CRC32
help
Say yes here to build support for Analog Devices ADIS16375, ADIS16480,
ADIS16485, ADIS16488 inertial sensors.
Expand Down
21 changes: 12 additions & 9 deletions drivers/iio/industrialio-buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,24 +203,27 @@ static ssize_t iio_buffer_write(struct file *filp, const char __user *buf,
break;
}

if (filp->f_flags & O_NONBLOCK) {
if (!written)
ret = -EAGAIN;
break;
}

wait_woken(&wait, TASK_INTERRUPTIBLE,
MAX_SCHEDULE_TIMEOUT);
continue;
}

ret = rb->access->write(rb, n - written, buf + written);
if (ret == 0 && (filp->f_flags & O_NONBLOCK))
ret = -EAGAIN;
if (ret < 0)
break;

if (ret > 0) {
written += ret;
if (written != n && !(filp->f_flags & O_NONBLOCK))
continue;
}
} while (ret == 0);
written += ret;

} while (written != n);
remove_wait_queue(&rb->pollq, &wait);

return ret < 0 ? ret : n;
return ret < 0 ? ret : written;
}

/**
Expand Down
12 changes: 12 additions & 0 deletions drivers/iio/light/cm32181.c
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,14 @@ static const struct iio_info cm32181_info = {
.attrs = &cm32181_attribute_group,
};

static void cm32181_unregister_dummy_client(void *data)
{
struct i2c_client *client = data;

/* Unregister the dummy client */
i2c_unregister_device(client);
}

static int cm32181_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
Expand Down Expand Up @@ -460,6 +468,10 @@ static int cm32181_probe(struct i2c_client *client)
client = i2c_acpi_new_device(dev, 1, &board_info);
if (IS_ERR(client))
return PTR_ERR(client);

ret = devm_add_action_or_reset(dev, cm32181_unregister_dummy_client, client);
if (ret)
return ret;
}

cm32181 = iio_priv(indio_dev);
Expand Down
3 changes: 2 additions & 1 deletion drivers/iio/light/vcnl4000.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,6 @@ static int vcnl4000_init(struct vcnl4000_data *data)

data->rev = ret & 0xf;
data->al_scale = 250000;
mutex_init(&data->vcnl4000_lock);

return data->chip_spec->set_power_state(data, true);
};
Expand Down Expand Up @@ -1367,6 +1366,8 @@ static int vcnl4000_probe(struct i2c_client *client)
data->id = id->driver_data;
data->chip_spec = &vcnl4000_chip_spec_cfg[data->id];

mutex_init(&data->vcnl4000_lock);

ret = data->chip_spec->init(data);
if (ret < 0)
return ret;
Expand Down

0 comments on commit 68047c4

Please sign in to comment.