RE: [PATCH v9 3/5] iio: adc: Add Xilinx AMS driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Andy,

Thanks for the review.

> -----Original Message-----
> From: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>
> Sent: Tuesday 16 November 2021 5:39 PM
> To: Anand Ashok Dumbre <ANANDASH@xxxxxxxxxx>
> Cc: linux-kernel@xxxxxxxxxxxxxxx; jic23@xxxxxxxxxx; lars@xxxxxxxxxx; linux-
> iio@xxxxxxxxxxxxxxx; git <git@xxxxxxxxxx>; Michal Simek
> <michals@xxxxxxxxxx>; gregkh@xxxxxxxxxxxxxxxxxxx; rafael@xxxxxxxxxx;
> linux-acpi@xxxxxxxxxxxxxxx; heikki.krogerus@xxxxxxxxxxxxxxx; Manish Narani
> <MNARANI@xxxxxxxxxx>
> Subject: Re: [PATCH v9 3/5] iio: adc: Add Xilinx AMS driver
> 
> On Tue, Nov 16, 2021 at 03:08:40PM +0000, Anand Ashok Dumbre wrote:
> > The AMS includes an ADC as well as on-chip sensors that can be used to
> > sample external voltages and monitor on-die operating conditions, such
> > as temperature and supply voltage levels. The AMS has two SYSMON
> blocks.
> > PL-SYSMON block is capable of monitoring off chip voltage and
> > temperature.
> > PL-SYSMON block has DRP, JTAG and I2C interface to enable monitoring
> > from an external master. Out of these interfaces currently only DRP is
> > supported.
> > Other block PS-SYSMON is memory mapped to PS.
> > The AMS can use internal channels to monitor voltage and temperature
> > as well as one primary and up to 16 auxiliary channels for measuring
> > external voltages.
> > The voltage and temperature monitoring channels also have event
> > capability which allows to generate an interrupt when their value
> > falls below or raises above a set threshold.
> 
> Something with indentation / paragraph splitting went wrong.
> 
> ...
> 
> > +#define AMS_ALARM_THR_MIN		0x0000
> > +#define AMS_ALARM_THR_MAX		0xFFFF
> 
> If this is limited by hardware register, I would rather use (BIT(16) - 1)
> notation. It will give immediately amount of bits used for the value.
> 

So ~(BIT(16) - 1) for AMS_ALARM_THR_MIN
(BIT(16) - 1) for AMS_ALARM_THR_MAX

> ...
> 
> > +#define AMS_REGCFG1_ALARM_MASK
> 	(AMS_CONF1_ALARM_2_TO_0_MASK |	\
> > +
> 	AMS_CONF1_ALARM_6_TO_3_MASK | BIT(0))
> 
> Better to write as
> 
> #define AMS_REGCFG1_ALARM_MASK \
> 	(AMS_CONF1_ALARM_2_TO_0_MASK |
> AMS_CONF1_ALARM_6_TO_3_MASK | BIT(0))
> 

Will do.

> ...
> 
> > +#define AMS_PL_CSTS_ACCESS_MASK		0x00000001U
> 
> BIT()
> 
Will fix.

> ...
> 
> > +	u32 reg;
> > +	int ret;
> 
> 	u32 expect = AMS_PS_CSTS_PS_READY;
> 
> (Use similar approach for other readX_poll_timeout() cases)
> 
> > +		ret = readl_poll_timeout(ams->base + AMS_PS_CSTS, reg,
> > +					 (reg & AMS_PS_CSTS_PS_READY) ==
> > +					 AMS_PS_CSTS_PS_READY, 0,
> > +					 AMS_INIT_TIMEOUT_US);
> 
> 		ret = readl_poll_timeout(ams->base + AMS_PS_CSTS, reg,
> 					 (reg & expect) == expect,
> 					 0, AMS_INIT_TIMEOUT_US);
> 
> 0?!
> 
> 
> > +		if (ret)
> > +			return ret;
> 
> ...
> 
> > +		ret = readl(ams->base + AMS_PL_CSTS);
> > +		if (ret == 0)
> > +			return ret;
> 
> Assigning u32 to int seems wrong.

It's a single bit register.
Even if I use u32 here, the return type is int. 
So, is it ok if I read using u32 and return it by typecasting to int?

> 
> ...
> 
> > +static int ams_enable_single_channel(struct ams *ams, unsigned int
> > +offset) {
> > +	u8 channel_num = 0;
> 
> Assignment does not bring any value.

Agreed. 
> 
> > +	switch (offset) {
> > +	case AMS_VCC_PSPLL0:
> > +		channel_num = AMS_VCC_PSPLL0_CH;
> > +		break;
> > +	case AMS_VCC_PSPLL3:
> > +		channel_num = AMS_VCC_PSPLL3_CH;
> > +		break;
> > +	case AMS_VCCINT:
> > +		channel_num = AMS_VCCINT_CH;
> > +		break;
> > +	case AMS_VCCBRAM:
> > +		channel_num = AMS_VCCBRAM_CH;
> > +		break;
> > +	case AMS_VCCAUX:
> > +		channel_num = AMS_VCCAUX_CH;
> > +		break;
> > +	case AMS_PSDDRPLL:
> > +		channel_num = AMS_PSDDRPLL_CH;
> > +		break;
> > +	case AMS_PSINTFPDDR:
> > +		channel_num = AMS_PSINTFPDDR_CH;
> > +		break;
> > +	default:
> > +		return -EINVAL;
> > +	}
> > +
> > +	/* set single channel, sequencer off mode */
> > +	ams_ps_update_reg(ams, AMS_REG_CONFIG1,
> AMS_CONF1_SEQ_MASK,
> > +			  AMS_CONF1_SEQ_SINGLE_CHANNEL);
> > +
> > +	/* write the channel number */
> > +	ams_ps_update_reg(ams, AMS_REG_CONFIG0,
> AMS_CONF0_CHANNEL_NUM_MASK,
> > +			  channel_num);
> > +
> > +	return 0;
> > +}
> 
> ...
> 
> > +					regval = readl(ams->pl_base +
> > +						       AMS_REG_CONFIG4);
> 
> One line?
> 
> > +					regval = readl(ams->pl_base +
> > +						       AMS_REG_CONFIG4);
> 
> Ditto and so on...
> 
It goes over 80 chars per line.

> ...
> 
> > +static int ams_get_alarm_mask(int scan_index) {
> > +	int bit = 0;
> > +
> > +	if (scan_index >= AMS_PS_SEQ_MAX) {
> > +		bit = AMS_PL_ALARM_START;
> > +		scan_index -= AMS_PS_SEQ_MAX;
> > +	}
> > +
> > +	switch (scan_index) {
> > +	case AMS_SEQ_TEMP:
> > +		return BIT(AMS_ALARM_BIT_TEMP + bit);
> > +	case AMS_SEQ_SUPPLY1:
> > +		return BIT(AMS_ALARM_BIT_SUPPLY1 + bit);
> > +	case AMS_SEQ_SUPPLY2:
> > +		return BIT(AMS_ALARM_BIT_SUPPLY2 + bit);
> > +	case AMS_SEQ_SUPPLY3:
> > +		return BIT(AMS_ALARM_BIT_SUPPLY3 + bit);
> > +	case AMS_SEQ_SUPPLY4:
> > +		return BIT(AMS_ALARM_BIT_SUPPLY4 + bit);
> > +	case AMS_SEQ_SUPPLY5:
> > +		return BIT(AMS_ALARM_BIT_SUPPLY5 + bit);
> > +	case AMS_SEQ_SUPPLY6:
> > +		return BIT(AMS_ALARM_BIT_SUPPLY6 + bit);
> > +	case AMS_SEQ_SUPPLY7:
> > +		return BIT(AMS_ALARM_BIT_SUPPLY7 + bit);
> > +	case AMS_SEQ_SUPPLY8:
> > +		return BIT(AMS_ALARM_BIT_SUPPLY8 + bit);
> > +	case AMS_SEQ_SUPPLY9:
> > +		return BIT(AMS_ALARM_BIT_SUPPLY9 + bit);
> > +	case AMS_SEQ_SUPPLY10:
> > +		return BIT(AMS_ALARM_BIT_SUPPLY10 + bit);
> > +	case AMS_SEQ_VCCAMS:
> > +		return BIT(AMS_ALARM_BIT_VCCAMS + bit);
> > +	case AMS_SEQ_TEMP_REMOTE:
> > +		return BIT(AMS_ALARM_BIT_TEMP_REMOTE + bit);
> > +	default:
> > +		return 0;
> > +	}
> 
> > +	return 0;
> 
> Dead code.

Will remove return statement.

> 
> > +}
> 
> ...
> 
> > +	return (ams->alarm_mask & ams_get_alarm_mask(chan-
> >scan_index)) ? 1
> > +: 0;
> 
> 	return !!(...);
> 
> simply shorter.

Sure.
> 
> ...
> 
> > +	schedule_delayed_work(&ams->ams_unmask_work,
> > +			      msecs_to_jiffies(AMS_UNMASK_TIMEOUT_MS));
> 
> Can be one line.

Over 80 characters. 

Oh! I just saw that upto 100 chars is ok.

> 
> ...
> 
> > +	struct fwnode_handle *child_node = NULL,
> 
> You may drop _node from the name.
> 
> > +			     *fwnode = dev_fwnode(&pdev->dev);
> 
> ...
> 
> > +	if (check_mul_overflow(num_chan, sizeof(struct iio_chan_spec),
> > +			       &ams_chan_size))
> > +		return -EINVAL;
> > +
> > +	/* Initialize buffer for channel specification */
> > +	ams_channels = kzalloc(ams_chan_size, GFP_KERNEL);
> 
> Simply use array_size(). Or why not kcalloc()?
> 
> > +	if (!ams_channels)
> > +		return -ENOMEM;
> 
> ...
> 
> > +	if (check_mul_overflow((size_t)num_channels, sizeof(struct
> iio_chan_spec),
> > +			       &dev_chan_size))
> > +		return -EINVAL;
> > +
> > +	dev_channels = devm_kzalloc(&pdev->dev, dev_chan_size,
> GFP_KERNEL);
> 
> Why not devm_kcalloc()?
> 
> > +	if (!dev_channels) {
> > +		ret = -ENOMEM;
> > +		goto err;
> > +	}
> 
> ...
> 
> > +	ret = 0;
> > +err:
> 
> Use better naming, you should describe what is going to be after goto.
Sure. Will do

> 
> > +	kfree(ams_channels);
> > +
> > +	return ret;
> 
> ...
> 
> > +	ret = devm_add_action_or_reset(&pdev->dev,
> ams_clk_disable_unprepare,
> > +				       ams->clk);
> 
> One line?
> 
> > +	if (ret < 0)
> > +		return ret;
> 
> ...
> 
> > +	ret = ams_init_device(ams);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "failed to initialize AMS\n");
> > +		return ret;
> 
> It's fine to use dev_err_probe() for known error codes.
> 
> > +	}
> 
> ...
> 
> > +	ret = devm_request_irq(&pdev->dev, irq, &ams_irq, 0, "ams-irq",
> > +			       indio_dev);
> > +	if (ret < 0) {
> > +		dev_err(&pdev->dev, "failed to register interrupt\n");
> > +		return ret;
> 
> Ditto.
> 
> > +	}
> 
> --
> With Best Regards,
> Andy Shevchenko
> 

Thanks,
Anand





[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux